style(app): apply eslint --fix to Tier 2 (TypeScript plumbing)

WS-3 session 1b-i Tier 2.

Scope: composables, lib, stores, plugins, types, utils, navigation,
main.ts. Mechanical fixes only — predominantly newline-before-return,
arrow-parens, antfu/if-newline, padding-line-between-statements, plus
one unicorn/prefer-includes (.some(p => x === p) → .includes(x))
in router guards.

Excludes (per session prompt):
- apps/app/vite.config.ts (Tier 3)
- apps/app/themeConfig.ts (Tier 3)
- apps/app/vitest.config.ts (Tier 3)
- All .vue files (already in Tier 1)

Hand-reviewed diffs for the three auth/router-critical files before
committing:
- src/lib/axios.ts: reviewed clean. Pure mechanical (quote-props on
  Accept header, curly-strip on single-statement ifs, one blank line
  before impersonationStore.clearState()). No type-import changes,
  no logic touched.
- src/stores/useAuthStore.ts: reviewed clean. curly-strip + padding
  before returns. The initialize()/doInitialize() race-condition guard
  on isInitialized is preserved verbatim.
- src/plugins/1.router/guards.ts: reviewed clean. if-newline reformat
  + one .some() → .includes() rewrite that's behaviorally identical
  for primitive equality on the guestOnlyPaths string array.

Tests + typecheck verified green post-fix:
- apps/app vitest: 49 passed (unchanged)
- apps/app vue-tsc: clean (unchanged)

Lint baseline progression:
- Pre-Tier-2: 422 problems (post-Tier-1)
- Post-Tier-2: 246 problems

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-29 11:06:46 +02:00
parent 47bd533179
commit a7eaf0f948
28 changed files with 189 additions and 97 deletions

View File

@@ -4,10 +4,12 @@ import { isAxiosError } from 'axios'
* Human-readable message from Laravel API validation / exception responses.
*/
export function getApiErrorMessage(error: unknown, fallback: string): string {
if (!isAxiosError(error)) return fallback
if (!isAxiosError(error))
return fallback
const data = error.response?.data as Record<string, unknown> | undefined
if (!data) return fallback
if (!data)
return fallback
const errors = data.errors
if (errors && typeof errors === 'object' && errors !== null && !Array.isArray(errors)) {
@@ -15,12 +17,14 @@ export function getApiErrorMessage(error: unknown, fallback: string): string {
if (Array.isArray(value) && value.length > 0 && typeof value[0] === 'string')
return value[0]
if (typeof value === 'string') return value
if (typeof value === 'string')
return value
}
}
const message = data.message
if (typeof message === 'string' && message.trim() !== '') return message
if (typeof message === 'string' && message.trim() !== '')
return message
return fallback
}

View File

@@ -7,7 +7,7 @@ const apiClient: AxiosInstance = axios.create({
baseURL: import.meta.env.VITE_API_URL,
withCredentials: true,
headers: {
Accept: 'application/json',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
timeout: 30000,
@@ -17,9 +17,8 @@ apiClient.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
const orgStore = useOrganisationStore()
if (orgStore.activeOrganisationId) {
if (orgStore.activeOrganisationId)
config.headers['X-Organisation-Id'] = orgStore.activeOrganisationId
}
// Add impersonation header when active
// Lazy import to avoid circular dependency with store
@@ -27,18 +26,16 @@ apiClient.interceptors.request.use(
if (impersonationData) {
try {
const parsed = JSON.parse(impersonationData) as { targetUserId?: string }
if (parsed.targetUserId) {
if (parsed.targetUserId)
config.headers['X-Impersonate-User'] = parsed.targetUserId
}
}
catch {
// Invalid data — ignore
}
}
if (import.meta.env.DEV) {
if (import.meta.env.DEV)
console.log(`🚀 ${config.method?.toUpperCase()} ${config.url}`, config.data)
}
return config
},
@@ -47,16 +44,14 @@ apiClient.interceptors.request.use(
apiClient.interceptors.response.use(
response => {
if (import.meta.env.DEV) {
if (import.meta.env.DEV)
console.log(`${response.status} ${response.config.url}`, response.data)
}
return response
},
error => {
if (import.meta.env.DEV) {
if (import.meta.env.DEV)
console.error(`${error.response?.status} ${error.config?.url}`, error.response?.data)
}
const status = error.response?.status
const notificationStore = useNotificationStore()
@@ -65,6 +60,7 @@ apiClient.interceptors.response.use(
if (status === 403 && error.response?.data?.impersonation_ended) {
import('@/stores/useImpersonationStore').then(({ useImpersonationStore }) => {
const impersonationStore = useImpersonationStore()
impersonationStore.clearState()
window.location.href = '/platform'
})
@@ -76,9 +72,8 @@ apiClient.interceptors.response.use(
// Lazy import to avoid circular dependency
import('@/stores/useAuthStore').then(({ useAuthStore }) => {
const authStore = useAuthStore()
if (authStore.isInitialized) {
if (authStore.isInitialized)
authStore.handleUnauthorized()
}
})
}
else if (status === 403) {
@@ -90,9 +85,8 @@ apiClient.interceptors.response.use(
else if (status === 422) {
// Show validation message to user; still reject so component onError handlers can react
const message = error.response?.data?.message
if (message && typeof message === 'string') {
if (message && typeof message === 'string')
notificationStore.show(message, 'error')
}
}
else if (status === 503) {
notificationStore.show('Service temporarily unavailable. Please try again later.', 'error')

View File

@@ -4,12 +4,18 @@
*/
export function dutchPlural(word: string): string {
// Words ending in -ie: add -s (editie → edities, locatie → locaties)
if (word.endsWith('ie')) return `${word}s`
if (word.endsWith('ie'))
return `${word}s`
// Words ending in -e: add -s (ronde → rondes)
if (word.endsWith('e')) return `${word}s`
if (word.endsWith('e'))
return `${word}s`
// Double vowel before final consonant(s): single vowel + en (onderdeel → onderdelen)
const match = word.match(/^(.*)([aeiou])\2([^aeiou]+)$/i)
if (match) return `${match[1]}${match[2]}${match[3]}en`
if (match)
return `${match[1]}${match[2]}${match[3]}en`
// Default: add -en (dag → dagen)
return `${word}en`
}