style: align oxfmt to trailing-comma 'all' and normalize code
All checks were successful
Build and Push Docker Image / build (push) Successful in 28s

The repo was authored prettier-style (trailing-comma 'all') but .oxfmtrc.json
was set to 'es5', so every formatted file diverged. Switch the config to 'all'
to match the existing code, ignore docs/** and **/drizzle/** (prose + generated
snapshots the formatter should not own), and reformat the source tree once for
consistency. No behavioural change; all suites green (api 60, worker 28, admin 21).
This commit is contained in:
Bas van Rossem
2026-06-17 21:36:18 +02:00
parent 1807f2b6d6
commit 70ac27ec8e
27 changed files with 48 additions and 51 deletions

View File

@@ -6,10 +6,10 @@
"semi": true, "semi": true,
"singleQuote": true, "singleQuote": true,
"jsxSingleQuote": false, "jsxSingleQuote": false,
"trailingComma": "es5", "trailingComma": "all",
"bracketSpacing": true, "bracketSpacing": true,
"bracketSameLine": false, "bracketSameLine": false,
"arrowParens": "always", "arrowParens": "always",
"endOfLine": "lf", "endOfLine": "lf",
"ignorePatterns": ["examples/**/*"] "ignorePatterns": ["examples/**/*", "docs/**", "**/drizzle/**"]
} }

View File

@@ -22,7 +22,7 @@ function renderApp() {
return render( return render(
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<App /> <App />
</QueryClientProvider> </QueryClientProvider>,
); );
} }

View File

@@ -46,7 +46,7 @@ function renderHarness() {
return render( return render(
<AuthProvider> <AuthProvider>
<Harness /> <Harness />
</AuthProvider> </AuthProvider>,
); );
} }

View File

@@ -5,7 +5,7 @@ export const API_URL = import.meta.env.VITE_API_URL ?? 'http://localhost:3000';
export class ApiError extends Error { export class ApiError extends Error {
constructor( constructor(
public status: number, public status: number,
message: string message: string,
) { ) {
super(message); super(message);
this.name = 'ApiError'; this.name = 'ApiError';

View File

@@ -11,5 +11,5 @@ createRoot(document.getElementById('root')!).render(
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<App /> <App />
</QueryClientProvider> </QueryClientProvider>
</React.StrictMode> </React.StrictMode>,
); );

View File

@@ -41,7 +41,7 @@ function renderActivities() {
return render( return render(
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<Activities /> <Activities />
</QueryClientProvider> </QueryClientProvider>,
); );
} }

View File

@@ -100,7 +100,7 @@ export default function Activities() {
setNewName(''); setNewName('');
setNewTypes([...ALL_TYPES]); setNewTypes([...ALL_TYPES]);
}, },
} },
); );
} }
@@ -118,13 +118,13 @@ export default function Activities() {
if (editName.trim().length === 0 || editTypes.length === 0) return; if (editName.trim().length === 0 || editTypes.length === 0) return;
updateActivity.mutate( updateActivity.mutate(
{ id, input: { name: editName.trim(), insole_types: editTypes } }, { id, input: { name: editName.trim(), insole_types: editTypes } },
{ onSuccess: () => setEditingId(null) } { onSuccess: () => setEditingId(null) },
); );
} }
function handleDelete(id: number, name: string) { function handleDelete(id: number, name: string) {
const ok = window.confirm( const ok = window.confirm(
`"${name}" verwijderen? Alle tijdsregistraties voor deze taak worden ook verwijderd.` `"${name}" verwijderen? Alle tijdsregistraties voor deze taak worden ook verwijderd.`,
); );
if (ok) deleteActivity.mutate(id); if (ok) deleteActivity.mutate(id);
} }

View File

@@ -38,7 +38,7 @@ function renderLive() {
return render( return render(
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<Live /> <Live />
</QueryClientProvider> </QueryClientProvider>,
); );
} }

View File

@@ -54,7 +54,7 @@ function LiveCard({ session, now }: { session: WorkSession; now: number }) {
const base = session.paused_at ? Date.parse(session.paused_at) : now; const base = session.paused_at ? Date.parse(session.paused_at) : now;
const worked = Math.max( const worked = Math.max(
0, 0,
Math.floor((base - Date.parse(session.start_time)) / 1000) - session.paused_seconds Math.floor((base - Date.parse(session.start_time)) / 1000) - session.paused_seconds,
); );
return ( return (
<article className="live-card"> <article className="live-card">

View File

@@ -16,7 +16,7 @@ export default function Login() {
await signIn(email, password); await signIn(email, password);
} catch (err) { } catch (err) {
setError( setError(
err instanceof NotAdminError ? 'Geen toegang — alleen beheerders.' : 'Inloggen mislukt' err instanceof NotAdminError ? 'Geen toegang — alleen beheerders.' : 'Inloggen mislukt',
); );
} finally { } finally {
setBusy(false); setBusy(false);

View File

@@ -18,7 +18,7 @@ export function createApp(): Hono {
allowHeaders: ['Content-Type', 'Authorization'], allowHeaders: ['Content-Type', 'Authorization'],
exposeHeaders: ['set-auth-token'], // so the SPA can read the bearer token on sign-in exposeHeaders: ['set-auth-token'], // so the SPA can read the bearer token on sign-in
credentials: true, credentials: true,
}) }),
); );
app.route('/', health); app.route('/', health);
app.on(['POST', 'GET'], '/api/auth/*', (c) => auth.handler(c.req.raw)); app.on(['POST', 'GET'], '/api/auth/*', (c) => auth.handler(c.req.raw));

View File

@@ -45,7 +45,7 @@ export const session = sqliteTable(
}, },
(table) => ({ (table) => ({
sessionUserIdIdx: index('session_userId_idx').on(table.userId), sessionUserIdIdx: index('session_userId_idx').on(table.userId),
}) }),
); );
export const account = sqliteTable( export const account = sqliteTable(
@@ -73,7 +73,7 @@ export const account = sqliteTable(
}, },
(table) => ({ (table) => ({
accountUserIdIdx: index('account_userId_idx').on(table.userId), accountUserIdIdx: index('account_userId_idx').on(table.userId),
}) }),
); );
export const verification = sqliteTable( export const verification = sqliteTable(
@@ -93,7 +93,7 @@ export const verification = sqliteTable(
}, },
(table) => ({ (table) => ({
verificationIdentifierIdx: index('verification_identifier_idx').on(table.identifier), verificationIdentifierIdx: index('verification_identifier_idx').on(table.identifier),
}) }),
); );
export const userRelations = relations(user, ({ many }) => ({ export const userRelations = relations(user, ({ many }) => ({
@@ -157,5 +157,5 @@ export const workSessions = sqliteTable(
(table) => ({ (table) => ({
workSessionsUserIdIdx: index('work_sessions_userId_idx').on(table.userId), workSessionsUserIdIdx: index('work_sessions_userId_idx').on(table.userId),
workSessionsStartTimeIdx: index('work_sessions_startTime_idx').on(table.startTime), workSessionsStartTimeIdx: index('work_sessions_startTime_idx').on(table.startTime),
}) }),
); );

View File

@@ -5,7 +5,7 @@ type WorkSessionRow = typeof workSessions.$inferSelect;
export function toWorkSession( export function toWorkSession(
row: WorkSessionRow, row: WorkSessionRow,
opts: { activityName?: string | null; userName?: string | null; userEmail?: string | null } = {} opts: { activityName?: string | null; userName?: string | null; userEmail?: string | null } = {},
): WorkSession { ): WorkSession {
return { return {
id: row.id, id: row.id,

View File

@@ -35,8 +35,8 @@ adminRoutes.get('/api/admin/sessions', async (c) => {
activityName: r.activityName, activityName: r.activityName,
userName: r.userName, userName: r.userName,
userEmail: r.userEmail, userEmail: r.userEmail,
}) }),
) ),
); );
}); });
@@ -54,7 +54,7 @@ adminRoutes.get('/api/admin/sessions/active', async (c) => {
activityName: r.activityName, activityName: r.activityName,
userName: r.userName, userName: r.userName,
userEmail: r.userEmail, userEmail: r.userEmail,
}) }),
) ),
); );
}); });

View File

@@ -236,7 +236,7 @@ describe('activities routes', () => {
expect(after.map((r) => r.id)).toEqual(ids); expect(after.map((r) => r.id)).toEqual(ids);
// In particular, b now precedes a. // In particular, b now precedes a.
expect(after.findIndex((r) => r.id === b.id)).toBeLessThan( expect(after.findIndex((r) => r.id === b.id)).toBeLessThan(
after.findIndex((r) => r.id === a.id) after.findIndex((r) => r.id === a.id),
); );
}); });

View File

@@ -14,7 +14,7 @@ async function completedSession(
token: string, token: string,
activityId: number, activityId: number,
insoleType: string, insoleType: string,
durationSeconds: number durationSeconds: number,
): Promise<number> { ): Promise<number> {
const startRes = await app.request('/api/sessions/start', { const startRes = await app.request('/api/sessions/start', {
method: 'POST', method: 'POST',
@@ -47,13 +47,13 @@ describe('csv export', () => {
expect(res.status).toBe(200); expect(res.status).toBe(200);
expect(res.headers.get('content-type')).toContain('text/csv'); expect(res.headers.get('content-type')).toContain('text/csv');
expect(res.headers.get('content-disposition')).toBe( expect(res.headers.get('content-disposition')).toBe(
'attachment; filename="insole-production-report.csv"' 'attachment; filename="insole-production-report.csv"',
); );
const text = await res.text(); const text = await res.text();
const lines = text.split('\n'); const lines = text.split('\n');
expect(lines[0]).toBe( expect(lines[0]).toBe(
'"ID","Task","Insole Type","No. of Insoles","Date","Total Duration","Paused Duration","Start Time","End Time"' '"ID","Task","Insole Type","No. of Insoles","Date","Total Duration","Paused Duration","Start Time","End Time"',
); );
expect(lines).toHaveLength(2); expect(lines).toHaveLength(2);
expect(lines[1]).toContain('"Frezen"'); expect(lines[1]).toContain('"Frezen"');

View File

@@ -27,7 +27,7 @@ export async function createTestUser(email: string, role: 'worker' | 'admin' = '
export async function authToken( export async function authToken(
app: Hono, app: Hono,
email: string, email: string,
role: 'worker' | 'admin' = 'worker' role: 'worker' | 'admin' = 'worker',
): Promise<string> { ): Promise<string> {
await createTestUser(email, role); await createTestUser(email, role);
const signin = await app.request('/api/auth/sign-in/email', { const signin = await app.request('/api/auth/sign-in/email', {
@@ -47,7 +47,7 @@ export function bearer(token: string): Record<string, string> {
// Insert an activity straight into the DB (test setup that should not depend on authz). // Insert an activity straight into the DB (test setup that should not depend on authz).
export async function seedActivity( export async function seedActivity(
name: string, name: string,
insoleTypes: string[] = ['Kurk', 'Berk', '3D'] insoleTypes: string[] = ['Kurk', 'Berk', '3D'],
): Promise<number> { ): Promise<number> {
const [row] = await db.insert(activities).values({ name, insoleTypes }).returning(); const [row] = await db.insert(activities).values({ name, insoleTypes }).returning();
return row.id; return row.id;

View File

@@ -33,7 +33,7 @@ describe('seed', () => {
await seed(); await seed();
expect(await db.select().from(user).where(eq(user.email, 'admin@solelog.local'))).toHaveLength( expect(await db.select().from(user).where(eq(user.email, 'admin@solelog.local'))).toHaveLength(
1 1,
); );
}); });
}); });

View File

@@ -378,7 +378,7 @@ describe('session reads', () => {
const body = await res.json(); const body = await res.json();
expect(body).toHaveLength(2); expect(body).toHaveLength(2);
expect(new Date(body[0].start_time).getTime()).toBeGreaterThan( expect(new Date(body[0].start_time).getTime()).toBeGreaterThan(
new Date(body[1].start_time).getTime() new Date(body[1].start_time).getTime(),
); );
expect(body[0].activity_name).toBe('Slijpen'); expect(body[0].activity_name).toBe('Slijpen');
expect(body[1].activity_name).toBe('Frezen'); expect(body[1].activity_name).toBe('Frezen');

View File

@@ -18,7 +18,7 @@ function renderApp() {
return render( return render(
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<App /> <App />
</QueryClientProvider> </QueryClientProvider>,
); );
} }

View File

@@ -39,7 +39,7 @@ describe('AuthContext signOut', () => {
render( render(
<AuthProvider> <AuthProvider>
<SignOutButton /> <SignOutButton />
</AuthProvider> </AuthProvider>,
); );
await user.click(screen.getByRole('button', { name: 'Uitloggen' })); await user.click(screen.getByRole('button', { name: 'Uitloggen' }));

View File

@@ -28,10 +28,7 @@ describe('api client', () => {
}); });
it('throws ApiError on a non-2xx response', async () => { it('throws ApiError on a non-2xx response', async () => {
vi.stubGlobal( vi.stubGlobal('fetch', vi.fn().mockResolvedValue(new Response(null, { status: 401 })));
'fetch',
vi.fn().mockResolvedValue(new Response(null, { status: 401 })),
);
await expect(apiFetch('/api/me')).rejects.toMatchObject({ status: 401 }); await expect(apiFetch('/api/me')).rejects.toMatchObject({ status: 401 });
await expect(apiFetch('/api/me')).rejects.toBeInstanceOf(ApiError); await expect(apiFetch('/api/me')).rejects.toBeInstanceOf(ApiError);

View File

@@ -5,7 +5,7 @@ export const API_URL = import.meta.env.VITE_API_URL ?? 'http://localhost:3000';
export class ApiError extends Error { export class ApiError extends Error {
constructor( constructor(
public status: number, public status: number,
message: string message: string,
) { ) {
super(message); super(message);
this.name = 'ApiError'; this.name = 'ApiError';

View File

@@ -21,7 +21,7 @@ function renderAccount() {
<AuthProvider> <AuthProvider>
<Account /> <Account />
</AuthProvider> </AuthProvider>
</QueryClientProvider> </QueryClientProvider>,
); );
} }

View File

@@ -46,7 +46,7 @@ function renderHistory() {
return render( return render(
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<History /> <History />
</QueryClientProvider> </QueryClientProvider>,
); );
} }

View File

@@ -91,7 +91,7 @@ function renderStopwatch() {
return render( return render(
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<Stopwatch /> <Stopwatch />
</QueryClientProvider> </QueryClientProvider>,
); );
} }
@@ -105,17 +105,17 @@ describe('Stopwatch', () => {
mockedUseActivities.mockReturnValue(query<ReturnType<typeof useActivities>>([FREZEN, PRINTEN])); mockedUseActivities.mockReturnValue(query<ReturnType<typeof useActivities>>([FREZEN, PRINTEN]));
mockedUseActiveSessions.mockReturnValue(query<ReturnType<typeof useActiveSessions>>([])); mockedUseActiveSessions.mockReturnValue(query<ReturnType<typeof useActiveSessions>>([]));
mockedUseStartSession.mockReturnValue( mockedUseStartSession.mockReturnValue(
mutation<ReturnType<typeof useStartSession>>(startMutate) mutation<ReturnType<typeof useStartSession>>(startMutate),
); );
mockedUseStopSession.mockReturnValue(mutation<ReturnType<typeof useStopSession>>(stopMutate)); mockedUseStopSession.mockReturnValue(mutation<ReturnType<typeof useStopSession>>(stopMutate));
mockedUseDiscardSession.mockReturnValue( mockedUseDiscardSession.mockReturnValue(
mutation<ReturnType<typeof useDiscardSession>>(discardMutate) mutation<ReturnType<typeof useDiscardSession>>(discardMutate),
); );
mockedUsePauseSession.mockReturnValue( mockedUsePauseSession.mockReturnValue(
mutation<ReturnType<typeof usePauseSession>>(pauseMutate) mutation<ReturnType<typeof usePauseSession>>(pauseMutate),
); );
mockedUseResumeSession.mockReturnValue( mockedUseResumeSession.mockReturnValue(
mutation<ReturnType<typeof useResumeSession>>(resumeMutate) mutation<ReturnType<typeof useResumeSession>>(resumeMutate),
); );
}); });
@@ -189,7 +189,7 @@ describe('Stopwatch', () => {
const user = userEvent.setup(); const user = userEvent.setup();
// Recover an active session so the screen renders the running UI. // Recover an active session so the screen renders the running UI.
mockedUseActiveSessions.mockReturnValue( mockedUseActiveSessions.mockReturnValue(
query<ReturnType<typeof useActiveSessions>>([activeSession()]) query<ReturnType<typeof useActiveSessions>>([activeSession()]),
); );
renderStopwatch(); renderStopwatch();
@@ -197,7 +197,7 @@ describe('Stopwatch', () => {
await user.click(cancel); await user.click(cancel);
expect( expect(
screen.getByRole('button', { name: 'Nogmaals tikken ter bevestiging' }) screen.getByRole('button', { name: 'Nogmaals tikken ter bevestiging' }),
).toBeInTheDocument(); ).toBeInTheDocument();
await user.click(screen.getByRole('button', { name: 'Nogmaals tikken ter bevestiging' })); await user.click(screen.getByRole('button', { name: 'Nogmaals tikken ter bevestiging' }));
@@ -208,7 +208,7 @@ describe('Stopwatch', () => {
it('pauses via the server when the display is tapped while running', async () => { it('pauses via the server when the display is tapped while running', async () => {
const user = userEvent.setup(); const user = userEvent.setup();
mockedUseActiveSessions.mockReturnValue( mockedUseActiveSessions.mockReturnValue(
query<ReturnType<typeof useActiveSessions>>([activeSession()]) query<ReturnType<typeof useActiveSessions>>([activeSession()]),
); );
renderStopwatch(); renderStopwatch();
@@ -225,7 +225,7 @@ describe('Stopwatch', () => {
mockedUseActiveSessions.mockReturnValue( mockedUseActiveSessions.mockReturnValue(
query<ReturnType<typeof useActiveSessions>>([ query<ReturnType<typeof useActiveSessions>>([
activeSession({ paused_at: new Date().toISOString(), paused_seconds: 30 }), activeSession({ paused_at: new Date().toISOString(), paused_seconds: 30 }),
]) ]),
); );
renderStopwatch(); renderStopwatch();
@@ -241,7 +241,7 @@ describe('Stopwatch', () => {
mockedUseActiveSessions.mockReturnValue( mockedUseActiveSessions.mockReturnValue(
query<ReturnType<typeof useActiveSessions>>([ query<ReturnType<typeof useActiveSessions>>([
activeSession({ paused_at: new Date().toISOString(), paused_seconds: 30 }), activeSession({ paused_at: new Date().toISOString(), paused_seconds: 30 }),
]) ]),
); );
renderStopwatch(); renderStopwatch();

View File

@@ -118,7 +118,7 @@ export default function Stopwatch() {
setPauseStartedMs(null); setPauseStartedMs(null);
setNowMs(Date.now()); setNowMs(Date.now());
}, },
} },
); );
} }