From 78f82833f113d6c1ee4fb7fd66f8ad0378d851d2 Mon Sep 17 00:00:00 2001 From: eleith Date: Fri, 30 Oct 2026 07:26:54 -0700 Subject: [PATCH 1/3] chore(web): apply official SvelteKit 3 migration Preserve exact sv@1.1.1 transformation output and generated task report. This tool-only checkpoint is intentionally non-green: automatic formatting failed during pnpm's non-TTY dependency reconciliation. Required manual integration follows separately. --- apps/web/MIGRATION_TASKS.md | 121 ++++++++++++++++++ apps/web/eslint.config.js | 4 +- apps/web/package.json | 13 +- apps/web/src/app.d.ts | 2 +- apps/web/src/hooks.server.test.ts | 12 +- apps/web/src/hooks.server.ts | 16 +-- apps/web/src/lib/components/AdminNav.svelte | 2 +- apps/web/src/lib/components/AdminPage.svelte | 2 +- .../lib/components/AppointmentActions.svelte | 2 +- .../src/lib/components/AppointmentLog.svelte | 2 +- .../lib/components/AppointmentWizard.svelte | 32 ++--- .../components/AppointmentsBulkDialog.svelte | 2 +- .../lib/components/AppointmentsList.svelte | 6 +- apps/web/src/lib/components/DatePicker.svelte | 2 +- .../web/src/lib/components/DayTimeline.svelte | 4 +- .../lib/components/FormFieldControl.svelte | 2 +- apps/web/src/lib/components/GuestForm.svelte | 26 ++-- apps/web/src/lib/components/LinkNotice.svelte | 4 +- .../lib/components/RescheduleBanner.svelte | 2 +- .../src/lib/components/TimezoneDialog.svelte | 4 +- .../src/lib/components/WizardActions.svelte | 6 +- .../components/WizardPickerControls.svelte | 4 +- .../src/lib/server/appointment/accept.test.ts | 4 +- .../src/lib/server/appointment/cancel.test.ts | 4 +- .../appointment/change-duration.test.ts | 2 +- .../src/lib/server/appointment/create.test.ts | 4 +- .../lib/server/appointment/decline.test.ts | 4 +- .../duration-reschedule-race.test.ts | 2 +- .../lib/server/appointment/duration.test.ts | 2 +- .../src/lib/server/appointment/edit.test.ts | 4 +- .../server/appointment/form.server.test.ts | 2 +- .../src/lib/server/appointment/form.server.ts | 4 +- .../src/lib/server/appointment/purge.test.ts | 4 +- .../appointment/request-video-chat.test.ts | 2 +- .../lib/server/appointment/reschedule.test.ts | 4 +- .../lib/server/appointment/sanitize.test.ts | 2 +- apps/web/src/lib/server/auth/index.test.ts | 11 +- apps/web/src/lib/server/auth/index.ts | 2 +- .../web/src/lib/server/auth/providers.test.ts | 4 +- .../lib/server/availability/booking.test.ts | 4 +- .../src/lib/server/availability/booking.ts | 2 +- .../src/lib/server/availability/calc.test.ts | 4 +- .../lib/server/availability/conflicts.test.ts | 2 +- .../lib/server/availability/intervals.test.ts | 2 +- .../lib/server/availability/settings.test.ts | 2 +- .../lib/server/availability/windows.test.ts | 2 +- .../src/lib/server/calendar/health.test.ts | 2 +- .../src/lib/server/calendar/status.test.ts | 2 +- apps/web/src/lib/server/calendar/status.ts | 2 +- apps/web/src/lib/server/config/boot.test.ts | 2 +- apps/web/src/lib/server/email/status.ts | 4 +- apps/web/src/lib/server/opengraph.ts | 2 +- apps/web/src/lib/server/providers/status.ts | 4 +- apps/web/src/lib/timezones.test.ts | 2 +- apps/web/src/lib/timezones.ts | 2 +- apps/web/src/routes/(app)/+layout.server.ts | 2 +- apps/web/src/routes/(app)/+page.server.ts | 4 +- apps/web/src/routes/(app)/+page.svelte | 2 +- .../(app)/appointment/[id]/+page.server.ts | 22 ++-- .../(app)/appointment/[id]/+page.svelte | 87 +++++++------ .../(app)/appointment/[id]/ics/+server.ts | 8 +- .../(app)/appointment/[id]/ics/server.test.ts | 6 +- .../[id]/reschedule/+page.server.ts | 20 +-- .../appointment/[id]/reschedule/+page.svelte | 2 +- .../[id]/reschedule/server.test.ts | 26 ++-- .../(app)/appointment/[id]/server.test.ts | 14 +- .../(app)/schedule/[slug]/+page.server.ts | 22 ++-- .../routes/(app)/schedule/[slug]/+page.svelte | 2 +- .../(app)/schedule/[slug]/server.test.ts | 26 ++-- apps/web/src/routes/(app)/server.test.ts | 4 +- .../src/routes/(auth)/admin/+page.server.ts | 8 +- apps/web/src/routes/(auth)/admin/+page.svelte | 4 +- .../admin/appointment/[id]/+page.server.ts | 24 ++-- .../[id]/reschedule/+page.server.ts | 12 +- .../[id]/reschedule/server.test.ts | 16 +-- .../admin/appointment/[id]/server.test.ts | 20 +-- .../admin/appointments/+layout.server.ts | 4 +- .../(auth)/admin/appointments/+layout.svelte | 4 +- .../(auth)/admin/appointments/+server.ts | 16 +-- .../admin/appointments/past/+page.server.ts | 6 +- .../admin/appointments/past/+page.svelte | 2 +- .../appointments/pending/+page.server.ts | 6 +- .../admin/appointments/pending/+page.svelte | 2 +- .../admin/appointments/purged/+page.server.ts | 6 +- .../admin/appointments/purged/+page.svelte | 2 +- .../(auth)/admin/appointments/server.test.ts | 12 +- .../appointments/upcoming/+page.server.ts | 6 +- .../admin/appointments/upcoming/+page.svelte | 2 +- .../(auth)/admin/health/+page.server.ts | 10 +- .../routes/(auth)/admin/health/+page.svelte | 4 +- .../routes/(auth)/admin/health/page.test.ts | 2 +- .../routes/(auth)/admin/health/server.test.ts | 18 +-- .../routes/(auth)/admin/page.server.test.ts | 6 +- .../admin/schedule/[slug]/+page.server.ts | 12 +- .../admin/schedule/[slug]/server.test.ts | 16 +-- .../services/google/callback/+page.server.ts | 6 +- .../services/google/callback/+page.svelte | 2 +- .../admin/services/google/connect/+server.ts | 6 +- .../google/disconnect/+page.server.ts | 4 +- .../services/google/disconnect/+page.svelte | 2 +- apps/web/src/routes/+layout.server.ts | 2 +- apps/web/src/routes/+layout.svelte | 18 +-- .../assets/images/avatar.svg/+server.ts | 6 +- .../assets/images/avatar.svg/server.test.ts | 4 +- .../assets/images/opengraph.png/+server.ts | 2 +- apps/web/src/routes/metrics/+server.ts | 6 +- apps/web/src/routes/metrics/server.test.ts | 4 +- .../web/src/routes/schema.json/server.test.ts | 2 +- apps/web/src/routes/signin/+page.server.ts | 4 +- apps/web/src/routes/signin/+page.svelte | 2 +- apps/web/src/routes/signin/server.test.ts | 4 +- apps/web/svelte.config.js | 33 ----- apps/web/tsconfig.json | 22 +--- apps/web/vite.config.ts | 33 ++++- 114 files changed, 558 insertions(+), 442 deletions(-) create mode 100644 apps/web/MIGRATION_TASKS.md delete mode 100644 apps/web/svelte.config.js diff --git a/apps/web/MIGRATION_TASKS.md b/apps/web/MIGRATION_TASKS.md new file mode 100644 index 00000000..7eb75ca6 --- /dev/null +++ b/apps/web/MIGRATION_TASKS.md @@ -0,0 +1,121 @@ + +# SvelteKit 3 migration tasks + +Some migrations are uncommon, context-dependent, or disproportionately difficult to automate safely. This document lists them. + +The findings are intentionally broad and may include files that do not require changes. + +AI agents can work through the migration tasks below one at a time: + +1. Read the linked documentation or pull request before changing code. +2. Inspect every listed file and its surrounding context. +3. Ignore a finding when the file is not actually affected. +4. Make the smallest necessary change. Do not perform unrelated refactors or introduce unnecessary abstractions. +5. Ask the user when application intent cannot be inferred. +6. Run the project's appropriate checks after editing. + +Also search the project for `@migration-task` comments. They may describe additional manual migration work that must be resolved. + +## Migration tasks + +### Review `goto` destinations + +`goto(...)` now rejects destinations that do not resolve to an application route. + +#### What to do + +Confirm each destination is an internal route. Use `window.location.href` for external browser navigation, and handle rejected dynamic destinations where they can fail to resolve. + +#### References + +- [Migrating to SvelteKit v3](https://svelte.dev/docs/kit/migrating-to-sveltekit-3#$app-navigation-goto-rejects-for-URLs-that-don't-resolve-to-a-route) + +#### Files to review + +- [ ] `src/lib/components/AdminNav.svelte` +- [ ] `src/routes/signin/+page.svelte` + +### Replace `invalidateAll` with `refreshAll` + +`invalidateAll` is deprecated in favor of `refreshAll` + +#### What to do + +Replace `invalidateAll()` with `refreshAll()`. Note that `refreshAll()` will keep `page.state` intact. Check if that has unwanted impact on the application; if yes point this out in a comment with steps to take instead of replacing that instance of `invalidateAll()`. Similarly, replace goto(..., { invalidateAll: true }) with goto(..., { refreshAll: true }). + +#### References + +- [Migrating to SvelteKit v3](https://svelte.dev/docs/kit/migrating-to-sveltekit-3#$app-navigation-invalidateAll-is-deprecated-in-favour-of-refreshAll) + +#### Files to review + +- [ ] `src/lib/components/AdminNav.svelte` +- [ ] `src/routes/signin/+page.svelte` + +### Review enhanced forms with explicit actions + +Enhanced forms that submit to another page now navigate to that page. + +#### What to do + +Determine whether each action resolves to another page and confirm navigation is intended. If the form must remain on the current page, implement that behavior explicitly in the enhancement callback. + +#### References + +- [Migrating to SvelteKit v3](https://svelte.dev/docs/kit/migrating-to-sveltekit-3#$app-forms) + +#### Files to review + +- [ ] `src/lib/components/AppointmentActions.svelte` +- [ ] `src/lib/components/GuestForm.svelte` +- [ ] `src/routes/(app)/appointment/[id]/+page.svelte` +- [ ] `src/routes/(auth)/admin/health/+page.svelte` + +### CORS for static assets in development is handled by Vite + +SvelteKit no longer sets `access-control-allow-origin: *` on every static asset request in development. CORS is now delegated to Vite's built-in middleware. + +#### What to do + +If you rely on cross-origin access to static assets in dev, configure it in your Vite config by adding server.cors.origin = "*" to your config. + +#### References + +- [Migrating to SvelteKit v3](https://svelte.dev/docs/kit/migrating-to-sveltekit-3#Security-CORS-for-static-assets-in-development-is-handled-by-Vite) + +### `json` and `text` are deprecated + +The `json(...)` and `text(...)` helpers from `@sveltejs/kit` for generating responses are deprecated. + +#### What to do + +Use `Response.json(...)` and `new Response(text)` instead. + +#### References + +- [Migrating to SvelteKit v3](https://svelte.dev/docs/kit/migrating-to-sveltekit-3#sveltejs-kit-json-and-text-are-deprecated) + +#### Files to review + +- [ ] `src/routes/metrics/+server.ts` +- [ ] `src/routes/schema.json/+server.ts` + +### Move adapter-node `ORIGIN` to `paths.origin` + +The adapter-node `ORIGIN` environment variable is removed. + +#### What to do + +Find where `ORIGIN` is set (`.env` files, scripts, hosting dashboard, ...) and move the public-facing origin to `paths.origin` in `sveltekit(...)`. Do not delete `ORIGIN`: it is ignored by adapter-node now and may have other uses. + +#### References + +- [Migrating to SvelteKit v3](https://svelte.dev/docs/kit/migrating-to-sveltekit-3#Adapters-adapter-node) + +## Final verification + +- [ ] Review every migration task and ignore any irrelevant findings. +- [ ] Resolve remaining `@migration-task` comments. +- [ ] Run the project's type checker and tests. +- [ ] Build the project successfully. +- [ ] Delete this file when all migration work is complete. diff --git a/apps/web/eslint.config.js b/apps/web/eslint.config.js index 46ee86e0..53c6ac3f 100644 --- a/apps/web/eslint.config.js +++ b/apps/web/eslint.config.js @@ -6,7 +6,9 @@ import { defineConfig } from 'eslint/config'; import globals from 'globals'; import prettier from 'eslint-config-prettier'; import ts from 'typescript-eslint'; -import svelteConfig from './svelte.config.js'; +import { loadConfig } from '@sveltejs/load-config'; + +const svelteConfig = (await loadConfig('./', { traverse: false }))?.config; const gitignorePath = path.resolve(import.meta.dirname, '../../.gitignore'); diff --git a/apps/web/package.json b/apps/web/package.json index 71ae5cbb..ff0f101d 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -29,8 +29,9 @@ "@eslint/js": "10.0.1", "@iconify-json/ph": "1.2.2", "@playwright/test": "1.61.1", - "@sveltejs/adapter-node": "5.5.4", - "@sveltejs/kit": "2.70.1", + "@sveltejs/adapter-node": "^6.0.0", + "@sveltejs/kit": "^3.0.0", + "@sveltejs/load-config": "^0.2.2", "@sveltejs/vite-plugin-svelte": "7.1.2", "@types/node": "24.12.4", "@vitest/coverage-v8": "4.1.7", @@ -41,8 +42,8 @@ "pino-pretty": "13.1.3", "prettier": "3.8.3", "prettier-plugin-svelte": "3.5.2", - "svelte": "5.56.0", - "svelte-check": "4.4.8", + "svelte": "^5.57.1", + "svelte-check": "^4.7.5", "typescript": "6.0.3", "typescript-eslint": "8.60.0", "unplugin-icons": "23.0.1", @@ -68,5 +69,9 @@ "temporal-polyfill": "1.0.1", "ts-ics": "2.4.4", "yaml": "2.9.0" + }, + "imports": { + "#lib": "./src/lib/index.js", + "#lib/*": "./src/lib/*" } } diff --git a/apps/web/src/app.d.ts b/apps/web/src/app.d.ts index 5e81e5ca..a9fe704b 100644 --- a/apps/web/src/app.d.ts +++ b/apps/web/src/app.d.ts @@ -1,4 +1,4 @@ -import type { WhenSession } from '$lib/server/auth'; +import type { WhenSession } from '#lib/server/auth/index.js'; // See https://svelte.dev/docs/kit/types#app.d.ts // for information about these interfaces diff --git a/apps/web/src/hooks.server.test.ts b/apps/web/src/hooks.server.test.ts index b643b90a..2f6a923e 100644 --- a/apps/web/src/hooks.server.test.ts +++ b/apps/web/src/hooks.server.test.ts @@ -1,11 +1,11 @@ +import type { Handle } from '@sveltejs/kit/hooks'; import { describe, expect, test, vi } from 'vitest'; -import type { Handle } from '@sveltejs/kit'; -import { validConfig } from '$lib/server/__fixtures__/valid-config'; +import { validConfig } from '#lib/server/__fixtures__/valid-config.js'; -vi.mock('$lib/server/boot', () => ({ bootApp: async () => {} })); -vi.mock('$lib/server/appearance', () => ({ themeStyleTag: () => '' })); -vi.mock('$lib/server/state', () => ({ getConfig: () => validConfig })); -vi.mock('$lib/server/auth', () => ({ +vi.mock('#lib/server/boot.js', () => ({ bootApp: async () => {} })); +vi.mock('#lib/server/appearance', () => ({ themeStyleTag: () => '' })); +vi.mock('#lib/server/state.js', () => ({ getConfig: () => validConfig })); +vi.mock('#lib/server/auth/index.js', () => ({ authHandle: (({ event, resolve }) => resolve(event)) as Handle })); diff --git a/apps/web/src/hooks.server.ts b/apps/web/src/hooks.server.ts index 31bdf535..cf60af71 100644 --- a/apps/web/src/hooks.server.ts +++ b/apps/web/src/hooks.server.ts @@ -1,11 +1,11 @@ -import { sequence } from '@sveltejs/kit/hooks'; -import { redirect, error, type Handle } from '@sveltejs/kit'; -import { authHandle } from '$lib/server/auth'; -import { localRedirect } from '$lib/server/redirect'; -import { bootApp } from '$lib/server/boot'; -import { logger } from '$lib/server/logger'; -import { getConfig } from '$lib/server/state'; -import { themeStyleTag } from '$lib/server/appearance'; +import { redirect, error } from '@sveltejs/kit'; +import { sequence, type Handle } from '@sveltejs/kit/hooks'; +import { authHandle } from '#lib/server/auth/index.js'; +import { localRedirect } from '#lib/server/redirect.js'; +import { bootApp } from '#lib/server/boot.js'; +import { logger } from '#lib/server/logger.js'; +import { getConfig } from '#lib/server/state.js'; +import { themeStyleTag } from '#lib/server/appearance.js'; try { await bootApp(); diff --git a/apps/web/src/lib/components/AdminNav.svelte b/apps/web/src/lib/components/AdminNav.svelte index afd7780b..cdce8496 100644 --- a/apps/web/src/lib/components/AdminNav.svelte +++ b/apps/web/src/lib/components/AdminNav.svelte @@ -2,7 +2,7 @@ import type { Snippet } from 'svelte'; import { page } from '$app/state'; import { goto } from '$app/navigation'; - import { authClient } from '$lib/auth-client'; + import { authClient } from '#lib/auth-client.js'; import IconCalendarBlank from 'virtual:icons/ph/calendar-blank'; import IconArrowUpLeft from 'virtual:icons/ph/arrow-up-left'; import IconSignOut from 'virtual:icons/ph/sign-out'; diff --git a/apps/web/src/lib/components/AdminPage.svelte b/apps/web/src/lib/components/AdminPage.svelte index fc74eb95..1d41cd7a 100644 --- a/apps/web/src/lib/components/AdminPage.svelte +++ b/apps/web/src/lib/components/AdminPage.svelte @@ -1,6 +1,6 @@ + +
{#if form?.error} @@ -123,7 +121,7 @@ {#each formFields as field (field.name)} {#if visibleFields.get(field.name)} diff --git a/apps/web/src/routes/(app)/appointment/[id]/+page.server.ts b/apps/web/src/routes/(app)/appointment/[id]/+page.server.ts index 8b42ab01..7e45ab3c 100644 --- a/apps/web/src/routes/(app)/appointment/[id]/+page.server.ts +++ b/apps/web/src/routes/(app)/appointment/[id]/+page.server.ts @@ -1,14 +1,14 @@ import { error, fail, redirect } from '@sveltejs/kit'; import { shouldAttachVideoChat } from '@when/video-chat'; -import { isEditAllowed, isViewAllowed } from '$lib/server/appointment/access'; +import { isEditAllowed, isViewAllowed } from '#lib/server/appointment/access.js'; import { isActiveStatus, resolveAppointmentActions, type AppointmentRole -} from '$lib/server/appointment/actions'; -import { buildAddToCalendarLinks } from '$lib/server/calendar-links'; -import { systemClock } from '$lib/server/clock'; -import { getConfig, getDb } from '$lib/server/state'; +} from '#lib/server/appointment/actions.js'; +import { buildAddToCalendarLinks } from '#lib/server/calendar-links/index.js'; +import { systemClock } from '#lib/server/clock.js'; +import { getConfig, getDb } from '#lib/server/state.js'; import { findAppointment, findChainTip, @@ -17,13 +17,13 @@ import { parseActionLog, type Appointment } from '@when/db'; -import { toPublicAppointment } from '$lib/server/appointment/sanitize'; -import { readMeetingSnapshot } from '$lib/server/appointment/snapshot'; -import { resolveBookingDurations } from '$lib/server/appointment/duration'; +import { toPublicAppointment } from '#lib/server/appointment/sanitize.js'; +import { readMeetingSnapshot } from '#lib/server/appointment/snapshot.js'; +import { resolveBookingDurations } from '#lib/server/appointment/duration.js'; import type { Actions, PageServerLoad } from './$types'; -import { cancelAppointment } from '$lib/server/appointment/cancel'; -import { validateReason } from '$lib/server/appointment/form.server'; -import { appointmentContext } from '$lib/server/appointment/context'; +import { cancelAppointment } from '#lib/server/appointment/cancel.js'; +import { validateReason } from '#lib/server/appointment/form.server.js'; +import { appointmentContext } from '#lib/server/appointment/context.js'; type ClockStatus = 'upcoming' | 'in_progress' | 'concluded'; diff --git a/apps/web/src/routes/(app)/appointment/[id]/+page.svelte b/apps/web/src/routes/(app)/appointment/[id]/+page.svelte index 30aeebf8..ccda40dd 100644 --- a/apps/web/src/routes/(app)/appointment/[id]/+page.svelte +++ b/apps/web/src/routes/(app)/appointment/[id]/+page.svelte @@ -1,7 +1,6 @@ @@ -360,19 +360,19 @@ appointmentId={data.appointment.id} token={data.token} role={data.role} - onCancel={() => (cancelDialogOpen = true)} + onCancel={() => cancelDialogOpen = true} hasNote={!!data.appointment.note} - onEditNote={() => (editNoteDialogOpen = true)} + onEditNote={() => editNoteDialogOpen = true} hasLocation={!!data.appointment.location} - onEditLocation={() => (editLocationDialogOpen = true)} + onEditLocation={() => editLocationDialogOpen = true} hasVideoChat={!!data.appointment.video_chat} videoChatRequested={data.videoChatRequested} - {changingVideoChat} + changingVideoChat={changingVideoChat} onGenerateVideoChat={handleGenerateVideoChat} onRemoveVideoChat={handleRemoveVideoChat} - onEditVideoChat={() => (editVideoChatDialogOpen = true)} - onEditDuration={data.canEditDuration ? () => (editDurationDialogOpen = true) : undefined} - {isEditable} + onEditVideoChat={() => editVideoChatDialogOpen = true} + onEditDuration={data.canEditDuration ? () => editDurationDialogOpen = true : undefined} + isEditable={isEditable} /> {/if} @@ -422,7 +422,11 @@ {formatDateShort(data.rescheduledFrom.start_time, displayTz)} {/if} - {#if data.rescheduledFrom && data.latestAppointment} · {/if} + + {#if data.rescheduledFrom && data.latestAppointment} + · + {/if} + {#if data.latestAppointment}
- {formatTzShort(displayTz)}{#if zonesDiffer} · you{/if} + {formatTzShort(displayTz)}{#if zonesDiffer} + · you + {/if}
{#if zonesDiffer}
- {formatTimeRange( - data.appointment.start_time, - data.appointment.end_time, - counterpartTz - )} - · {formatTzShort(counterpartTz)} · {counterpartName} + {formatTimeRange(data.appointment.start_time, data.appointment.end_time, counterpartTz)} · {formatTzShort(counterpartTz)} · {counterpartName}
{/if}
@@ -473,7 +474,7 @@ + onclick={() => declineDialogOpen = true} + >Decline {/if} {#if data.actions.accept.allowed} diff --git a/apps/web/src/routes/(app)/appointment/[id]/ics/+server.ts b/apps/web/src/routes/(app)/appointment/[id]/ics/+server.ts index 208736ef..963d6ec8 100644 --- a/apps/web/src/routes/(app)/appointment/[id]/ics/+server.ts +++ b/apps/web/src/routes/(app)/appointment/[id]/ics/+server.ts @@ -1,11 +1,11 @@ import { error, isHttpError } from '@sveltejs/kit'; -import { isViewAllowed } from '$lib/server/appointment/access'; -import { systemClock } from '$lib/server/clock'; +import { isViewAllowed } from '#lib/server/appointment/access.js'; +import { systemClock } from '#lib/server/clock.js'; import { buildIcs } from '@when/calendar'; import { senderEmail } from '@when/config'; import { findAppointment } from '@when/db'; -import { getConfig, getDb } from '$lib/server/state'; -import { icsDownloadsTotal } from '$lib/server/metrics'; +import { getConfig, getDb } from '#lib/server/state.js'; +import { icsDownloadsTotal } from '#lib/server/metrics.js'; import type { RequestHandler } from './$types'; export const GET: RequestHandler = async ({ params, url }) => { diff --git a/apps/web/src/routes/(app)/appointment/[id]/ics/server.test.ts b/apps/web/src/routes/(app)/appointment/[id]/ics/server.test.ts index f2775c6c..e51e208a 100644 --- a/apps/web/src/routes/(app)/appointment/[id]/ics/server.test.ts +++ b/apps/web/src/routes/(app)/appointment/[id]/ics/server.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test, vi, beforeEach } from 'vitest'; -import { validConfig } from '$lib/server/__fixtures__/valid-config'; +import { validConfig } from '#lib/server/__fixtures__/valid-config.js'; import type { Appointment } from '@when/db'; const h = vi.hoisted(() => ({ @@ -8,12 +8,12 @@ const h = vi.hoisted(() => ({ buildIcs: vi.fn(() => 'BEGIN:VCALENDAR') })); -vi.mock('$lib/server/state', () => ({ getConfig: () => validConfig, getDb: () => ({}) })); +vi.mock('#lib/server/state.js', () => ({ getConfig: () => validConfig, getDb: () => ({}) })); vi.mock('@when/db', async (io) => ({ ...(await io()), findAppointment: async () => h.row.current })); -vi.mock('$lib/server/appointment/access', () => ({ +vi.mock('#lib/server/appointment/access.js', () => ({ isViewAllowed: h.viewAllowed })); vi.mock('@when/calendar', async (io) => ({ diff --git a/apps/web/src/routes/(app)/appointment/[id]/reschedule/+page.server.ts b/apps/web/src/routes/(app)/appointment/[id]/reschedule/+page.server.ts index 2e0bb79d..695367ea 100644 --- a/apps/web/src/routes/(app)/appointment/[id]/reschedule/+page.server.ts +++ b/apps/web/src/routes/(app)/appointment/[id]/reschedule/+page.server.ts @@ -1,21 +1,21 @@ import { error, fail, redirect } from '@sveltejs/kit'; import { findAppointment } from '@when/db'; -import { systemClock } from '$lib/server/clock'; -import { getConfig, getDb } from '$lib/server/state'; +import { systemClock } from '#lib/server/clock.js'; +import { getConfig, getDb } from '#lib/server/state.js'; import { resolveFormFields } from '@when/config'; -import { isRescheduleSlotBookable, loadAvailability } from '$lib/server/availability/booking'; -import { resolveDuration } from '$lib/server/appointment/duration'; -import { isViewAllowed } from '$lib/server/appointment/access'; -import type { AppointmentRole } from '$lib/server/appointment/actions'; -import { classifyReschedule, rescheduleAppointment } from '$lib/server/appointment/reschedule'; +import { isRescheduleSlotBookable, loadAvailability } from '#lib/server/availability/booking.js'; +import { resolveDuration } from '#lib/server/appointment/duration.js'; +import { isViewAllowed } from '#lib/server/appointment/access.js'; +import type { AppointmentRole } from '#lib/server/appointment/actions.js'; +import { classifyReschedule, rescheduleAppointment } from '#lib/server/appointment/reschedule.js'; import { parseAndValidateAppointmentForm, parseSlot, resolveTimezone, validateReason -} from '$lib/server/appointment/form.server'; -import { appointmentContext } from '$lib/server/appointment/context'; -import { toPublicAppointment, toPublicEventType } from '$lib/server/appointment/sanitize'; +} from '#lib/server/appointment/form.server.js'; +import { appointmentContext } from '#lib/server/appointment/context.js'; +import { toPublicAppointment, toPublicEventType } from '#lib/server/appointment/sanitize.js'; import type { Actions, PageServerLoad } from './$types'; export const load: PageServerLoad = async ({ params, url, locals }) => { diff --git a/apps/web/src/routes/(app)/appointment/[id]/reschedule/+page.svelte b/apps/web/src/routes/(app)/appointment/[id]/reschedule/+page.svelte index e57260fa..099150d0 100644 --- a/apps/web/src/routes/(app)/appointment/[id]/reschedule/+page.svelte +++ b/apps/web/src/routes/(app)/appointment/[id]/reschedule/+page.svelte @@ -1,6 +1,6 @@ diff --git a/apps/web/src/routes/(app)/appointment/[id]/reschedule/server.test.ts b/apps/web/src/routes/(app)/appointment/[id]/reschedule/server.test.ts index 8bb5ab55..b6671440 100644 --- a/apps/web/src/routes/(app)/appointment/[id]/reschedule/server.test.ts +++ b/apps/web/src/routes/(app)/appointment/[id]/reschedule/server.test.ts @@ -1,9 +1,9 @@ import { describe, expect, test, vi, beforeEach } from 'vitest'; -import { validConfig } from '$lib/server/__fixtures__/valid-config'; +import { validConfig } from '#lib/server/__fixtures__/valid-config.js'; import type { Appointment } from '@when/db'; import type { Meeting } from '@when/config'; -import type { AppointmentRole } from '$lib/server/appointment/actions'; -import { resolveBookingDurations } from '$lib/server/appointment/duration'; +import type { AppointmentRole } from '#lib/server/appointment/actions.js'; +import { resolveBookingDurations } from '#lib/server/appointment/duration.js'; const h = vi.hoisted(() => ({ db: {}, @@ -21,7 +21,7 @@ const h = vi.hoisted(() => ({ toPublicEventType: vi.fn() })); -vi.mock('$lib/server/state', () => ({ getConfig: () => validConfig, getDb: () => h.db })); +vi.mock('#lib/server/state.js', () => ({ getConfig: () => validConfig, getDb: () => h.db })); vi.mock('@when/db', async (io) => { const original = await io(); return { @@ -29,19 +29,19 @@ vi.mock('@when/db', async (io) => { findAppointment: async () => h.row.current }; }); -vi.mock('$lib/server/appointment/access', () => ({ +vi.mock('#lib/server/appointment/access.js', () => ({ isViewAllowed: h.viewAllowed })); -vi.mock('$lib/server/appointment/reschedule', () => ({ +vi.mock('#lib/server/appointment/reschedule.js', () => ({ classifyReschedule: h.classify, rescheduleAppointment: h.reschedule })); -vi.mock('$lib/server/availability/booking', () => ({ +vi.mock('#lib/server/availability/booking.js', () => ({ loadAvailability: h.loadAvailability, isRescheduleSlotBookable: h.isRescheduleSlotBookable })); -vi.mock('$lib/server/appointment/form.server', async (io) => { - const original = await io(); +vi.mock('#lib/server/appointment/form.server.js', async (io) => { + const original = await io(); return { ...original, parseAndValidateAppointmentForm: h.parseForm, @@ -49,12 +49,12 @@ vi.mock('$lib/server/appointment/form.server', async (io) => { validateReason: h.validateReason }; }); -vi.mock('$lib/server/appointment/duration', async (importOriginal) => { - const original = await importOriginal(); +vi.mock('#lib/server/appointment/duration.js', async (importOriginal) => { + const original = await importOriginal(); return { ...original, resolveDuration: h.resolveDuration }; }); -vi.mock('$lib/server/appointment/sanitize', async (importOriginal) => { - const original = await importOriginal(); +vi.mock('#lib/server/appointment/sanitize.js', async (importOriginal) => { + const original = await importOriginal(); return { ...original, toPublicAppointment: h.toPublicAppointment, diff --git a/apps/web/src/routes/(app)/appointment/[id]/server.test.ts b/apps/web/src/routes/(app)/appointment/[id]/server.test.ts index 16edb040..83229c79 100644 --- a/apps/web/src/routes/(app)/appointment/[id]/server.test.ts +++ b/apps/web/src/routes/(app)/appointment/[id]/server.test.ts @@ -1,15 +1,15 @@ import { beforeEach, describe, expect, test, vi } from 'vitest'; import { actions, load } from './+page.server'; -import { validConfig } from '$lib/server/__fixtures__/valid-config'; +import { validConfig } from '#lib/server/__fixtures__/valid-config.js'; import type { Appointment } from '@when/db'; -import type { AppointmentRole } from '$lib/server/appointment/actions'; -import { resolveBookingDurations } from '$lib/server/appointment/duration'; +import type { AppointmentRole } from '#lib/server/appointment/actions.js'; +import { resolveBookingDurations } from '#lib/server/appointment/duration.js'; const h = vi.hoisted(() => ({ cancelAppointment: vi.fn() })); -vi.mock('$lib/server/appointment/cancel', () => ({ cancelAppointment: h.cancelAppointment })); -vi.mock('$lib/server/appointment/duration', async (importOriginal) => { - const original = await importOriginal(); +vi.mock('#lib/server/appointment/cancel.js', () => ({ cancelAppointment: h.cancelAppointment })); +vi.mock('#lib/server/appointment/duration.js', async (importOriginal) => { + const original = await importOriginal(); return { ...original, resolveBookingDurations: vi.fn(original.resolveBookingDurations) }; }); @@ -130,7 +130,7 @@ const automaticVideoAppointment: Appointment = { ]) }; -vi.mock('$lib/server/state', () => ({ +vi.mock('#lib/server/state.js', () => ({ getConfig: () => loadConfig, getDb: () => mockDb })); diff --git a/apps/web/src/routes/(app)/schedule/[slug]/+page.server.ts b/apps/web/src/routes/(app)/schedule/[slug]/+page.server.ts index cff1e65b..819551c7 100644 --- a/apps/web/src/routes/(app)/schedule/[slug]/+page.server.ts +++ b/apps/web/src/routes/(app)/schedule/[slug]/+page.server.ts @@ -1,20 +1,20 @@ import { error, fail, redirect } from '@sveltejs/kit'; -import { isNewSlotBookable, loadAvailability } from '$lib/server/availability/booking'; -import { logger } from '$lib/server/logger'; -import { getConfig, getDb } from '$lib/server/state'; +import { isNewSlotBookable, loadAvailability } from '#lib/server/availability/booking.js'; +import { logger } from '#lib/server/logger.js'; +import { getConfig, getDb } from '#lib/server/state.js'; import { resolveFormFields } from '@when/config'; -import { createAppointment } from '$lib/server/appointment/create'; -import type { AppointmentRole } from '$lib/server/appointment/actions'; -import { resolveBookingDurations, resolveDuration } from '$lib/server/appointment/duration'; +import { createAppointment } from '#lib/server/appointment/create.js'; +import type { AppointmentRole } from '#lib/server/appointment/actions.js'; +import { resolveBookingDurations, resolveDuration } from '#lib/server/appointment/duration.js'; import { parseAndValidateAppointmentForm, parseSlot, resolveTimezone -} from '$lib/server/appointment/form.server'; -import { appointmentContext } from '$lib/server/appointment/context'; -import { normalizeDeepLinkParams } from '$lib/appointment'; -import { toPublicEventType } from '$lib/server/appointment/sanitize'; -import { bookingAttemptsTotal } from '$lib/server/metrics'; +} from '#lib/server/appointment/form.server.js'; +import { appointmentContext } from '#lib/server/appointment/context.js'; +import { normalizeDeepLinkParams } from '#lib/appointment.js'; +import { toPublicEventType } from '#lib/server/appointment/sanitize.js'; +import { bookingAttemptsTotal } from '#lib/server/metrics.js'; import type { Actions, PageServerLoad } from './$types'; export const load: PageServerLoad = async ({ params, url, locals }) => { diff --git a/apps/web/src/routes/(app)/schedule/[slug]/+page.svelte b/apps/web/src/routes/(app)/schedule/[slug]/+page.svelte index 59f63990..e0692578 100644 --- a/apps/web/src/routes/(app)/schedule/[slug]/+page.svelte +++ b/apps/web/src/routes/(app)/schedule/[slug]/+page.svelte @@ -1,5 +1,5 @@ diff --git a/apps/web/src/routes/(app)/schedule/[slug]/server.test.ts b/apps/web/src/routes/(app)/schedule/[slug]/server.test.ts index 7aeb407a..289d93ba 100644 --- a/apps/web/src/routes/(app)/schedule/[slug]/server.test.ts +++ b/apps/web/src/routes/(app)/schedule/[slug]/server.test.ts @@ -1,9 +1,9 @@ import { describe, expect, test, vi, beforeEach } from 'vitest'; -import { validConfig } from '$lib/server/__fixtures__/valid-config'; +import { validConfig } from '#lib/server/__fixtures__/valid-config.js'; import type { Meeting, WhenConfiguration } from '@when/config'; -import type { AppointmentRole } from '$lib/server/appointment/actions'; -import { resolveBookingDurations } from '$lib/server/appointment/duration'; -import { toPublicEventType } from '$lib/server/appointment/sanitize'; +import type { AppointmentRole } from '#lib/server/appointment/actions.js'; +import { resolveBookingDurations } from '#lib/server/appointment/duration.js'; +import { toPublicEventType } from '#lib/server/appointment/sanitize.js'; const h = vi.hoisted(() => ({ cfg: { current: null as unknown as WhenConfiguration }, @@ -17,26 +17,26 @@ const h = vi.hoisted(() => ({ resolveDuration: vi.fn() })); -vi.mock('$lib/server/state', () => ({ getConfig: () => h.cfg.current, getDb: h.getDb })); -vi.mock('$lib/server/availability/booking', () => ({ +vi.mock('#lib/server/state.js', () => ({ getConfig: () => h.cfg.current, getDb: h.getDb })); +vi.mock('#lib/server/availability/booking.js', () => ({ loadAvailability: h.loadAvailability, isNewSlotBookable: h.isNewSlotBookable })); -vi.mock('$lib/server/appointment/create', () => ({ createAppointment: h.createAppointment })); -vi.mock('$lib/server/appointment/form.server', async (io) => { - const original = await io(); +vi.mock('#lib/server/appointment/create.js', () => ({ createAppointment: h.createAppointment })); +vi.mock('#lib/server/appointment/form.server.js', async (io) => { + const original = await io(); return { ...original, parseAndValidateAppointmentForm: h.parseForm, resolveTimezone: h.resolveTimezone }; }); -vi.mock('$lib/server/appointment/duration', async (importOriginal) => { - const original = await importOriginal(); +vi.mock('#lib/server/appointment/duration.js', async (importOriginal) => { + const original = await importOriginal(); return { ...original, resolveDuration: h.resolveDuration }; }); -vi.mock('$lib/server/appointment/sanitize', async (importOriginal) => { - const original = await importOriginal(); +vi.mock('#lib/server/appointment/sanitize.js', async (importOriginal) => { + const original = await importOriginal(); return { ...original, toPublicEventType: vi.fn(original.toPublicEventType) }; }); diff --git a/apps/web/src/routes/(app)/server.test.ts b/apps/web/src/routes/(app)/server.test.ts index e1fece92..b5c05376 100644 --- a/apps/web/src/routes/(app)/server.test.ts +++ b/apps/web/src/routes/(app)/server.test.ts @@ -1,12 +1,12 @@ import { describe, expect, test, vi, beforeEach } from 'vitest'; -import { validConfig } from '$lib/server/__fixtures__/valid-config'; +import { validConfig } from '#lib/server/__fixtures__/valid-config.js'; import type { Meeting, WhenConfiguration } from '@when/config'; const h = vi.hoisted(() => ({ cfg: { current: null as unknown as WhenConfiguration } })); -vi.mock('$lib/server/state', () => ({ getConfig: () => h.cfg.current })); +vi.mock('#lib/server/state.js', () => ({ getConfig: () => h.cfg.current })); import { load } from './+page.server'; diff --git a/apps/web/src/routes/(auth)/admin/+page.server.ts b/apps/web/src/routes/(auth)/admin/+page.server.ts index 3ecc5007..2955e861 100644 --- a/apps/web/src/routes/(auth)/admin/+page.server.ts +++ b/apps/web/src/routes/(auth)/admin/+page.server.ts @@ -1,7 +1,7 @@ -import { systemClock } from '$lib/server/clock'; -import { getConfig, getDb } from '$lib/server/state'; -import { toAppointmentView } from '$lib/server/appointments'; -import { evaluateCalendarStatuses } from '$lib/server/calendar/health'; +import { systemClock } from '#lib/server/clock.js'; +import { getConfig, getDb } from '#lib/server/state.js'; +import { toAppointmentView } from '#lib/server/appointments.js'; +import { evaluateCalendarStatuses } from '#lib/server/calendar/health.js'; import { countAppointments, listAppointmentsPage, listServiceStatus } from '@when/db'; import { allCalendars } from '@when/config'; import { sql } from 'kysely'; diff --git a/apps/web/src/routes/(auth)/admin/+page.svelte b/apps/web/src/routes/(auth)/admin/+page.svelte index 5ba49de9..f33fdb6c 100644 --- a/apps/web/src/routes/(auth)/admin/+page.svelte +++ b/apps/web/src/routes/(auth)/admin/+page.svelte @@ -1,7 +1,7 @@ diff --git a/apps/web/src/routes/(auth)/admin/appointments/pending/+page.server.ts b/apps/web/src/routes/(auth)/admin/appointments/pending/+page.server.ts index b0b4aa9e..3ce24124 100644 --- a/apps/web/src/routes/(auth)/admin/appointments/pending/+page.server.ts +++ b/apps/web/src/routes/(auth)/admin/appointments/pending/+page.server.ts @@ -1,6 +1,6 @@ -import { systemClock } from '$lib/server/clock'; -import { getConfig, getDb } from '$lib/server/state'; -import { toAppointmentView } from '$lib/server/appointments'; +import { systemClock } from '#lib/server/clock.js'; +import { getConfig, getDb } from '#lib/server/state.js'; +import { toAppointmentView } from '#lib/server/appointments.js'; import { countAppointments, listAppointmentsPage } from '@when/db'; import type { PageServerLoad } from './$types'; diff --git a/apps/web/src/routes/(auth)/admin/appointments/pending/+page.svelte b/apps/web/src/routes/(auth)/admin/appointments/pending/+page.svelte index 1c793f93..76a46bcb 100644 --- a/apps/web/src/routes/(auth)/admin/appointments/pending/+page.svelte +++ b/apps/web/src/routes/(auth)/admin/appointments/pending/+page.svelte @@ -1,5 +1,5 @@ diff --git a/apps/web/src/routes/(auth)/admin/appointments/purged/+page.server.ts b/apps/web/src/routes/(auth)/admin/appointments/purged/+page.server.ts index 5758e9a6..1293498f 100644 --- a/apps/web/src/routes/(auth)/admin/appointments/purged/+page.server.ts +++ b/apps/web/src/routes/(auth)/admin/appointments/purged/+page.server.ts @@ -1,6 +1,6 @@ -import { systemClock } from '$lib/server/clock'; -import { getConfig, getDb } from '$lib/server/state'; -import { toAppointmentView } from '$lib/server/appointments'; +import { systemClock } from '#lib/server/clock.js'; +import { getConfig, getDb } from '#lib/server/state.js'; +import { toAppointmentView } from '#lib/server/appointments.js'; import { countAppointments, listAppointmentsPage } from '@when/db'; import type { PageServerLoad } from './$types'; diff --git a/apps/web/src/routes/(auth)/admin/appointments/purged/+page.svelte b/apps/web/src/routes/(auth)/admin/appointments/purged/+page.svelte index d410c996..b1ea1c2d 100644 --- a/apps/web/src/routes/(auth)/admin/appointments/purged/+page.svelte +++ b/apps/web/src/routes/(auth)/admin/appointments/purged/+page.svelte @@ -1,5 +1,5 @@ diff --git a/apps/web/src/routes/(auth)/admin/appointments/server.test.ts b/apps/web/src/routes/(auth)/admin/appointments/server.test.ts index 359f93a6..759ba315 100644 --- a/apps/web/src/routes/(auth)/admin/appointments/server.test.ts +++ b/apps/web/src/routes/(auth)/admin/appointments/server.test.ts @@ -1,7 +1,7 @@ import { describe, expect, test, vi, beforeEach } from 'vitest'; import type { RequestEvent } from './$types'; import { POST } from './+server'; -import { validConfig } from '$lib/server/__fixtures__/valid-config'; +import { validConfig } from '#lib/server/__fixtures__/valid-config.js'; import type { Appointment } from '@when/db'; const mockDb = { @@ -66,7 +66,7 @@ const mockAppts: Record = { } }; -vi.mock('$lib/server/state', () => ({ +vi.mock('#lib/server/state.js', () => ({ getConfig: () => validConfig, getDb: () => mockDb })); @@ -88,7 +88,7 @@ vi.mock('@when/db', async (importOriginal) => { }); const mockPurgeAppointment = vi.fn(); -vi.mock('$lib/server/appointment/purge', () => ({ +vi.mock('#lib/server/appointment/purge.js', () => ({ purgeAppointment: async (_ctx: unknown, input: { appointment: Appointment }) => { mockPurgeAppointment(input.appointment.id); return { ok: true }; @@ -96,7 +96,7 @@ vi.mock('$lib/server/appointment/purge', () => ({ })); const mockCancelAppointment = vi.fn(); -vi.mock('$lib/server/appointment/cancel', () => ({ +vi.mock('#lib/server/appointment/cancel.js', () => ({ cancelAppointment: async ( _ctx: unknown, input: { appointment: Appointment; initiator: string; reason: string } @@ -107,7 +107,7 @@ vi.mock('$lib/server/appointment/cancel', () => ({ })); const mockAcceptAppointment = vi.fn(); -vi.mock('$lib/server/appointment/accept', () => ({ +vi.mock('#lib/server/appointment/accept.js', () => ({ acceptAppointment: async (_ctx: unknown, input: { appointment: Appointment }) => { mockAcceptAppointment(input.appointment.id); return { ok: true }; @@ -115,7 +115,7 @@ vi.mock('$lib/server/appointment/accept', () => ({ })); const mockDeclineAppointment = vi.fn(); -vi.mock('$lib/server/appointment/decline', () => ({ +vi.mock('#lib/server/appointment/decline.js', () => ({ declineAppointment: async (_ctx: unknown, input: { appointment: Appointment }) => { mockDeclineAppointment(input.appointment.id); return { ok: true }; diff --git a/apps/web/src/routes/(auth)/admin/appointments/upcoming/+page.server.ts b/apps/web/src/routes/(auth)/admin/appointments/upcoming/+page.server.ts index 029e0709..e423853f 100644 --- a/apps/web/src/routes/(auth)/admin/appointments/upcoming/+page.server.ts +++ b/apps/web/src/routes/(auth)/admin/appointments/upcoming/+page.server.ts @@ -1,6 +1,6 @@ -import { systemClock } from '$lib/server/clock'; -import { getConfig, getDb } from '$lib/server/state'; -import { toAppointmentView } from '$lib/server/appointments'; +import { systemClock } from '#lib/server/clock.js'; +import { getConfig, getDb } from '#lib/server/state.js'; +import { toAppointmentView } from '#lib/server/appointments.js'; import { countAppointments, listAppointmentsPage } from '@when/db'; import type { PageServerLoad } from './$types'; diff --git a/apps/web/src/routes/(auth)/admin/appointments/upcoming/+page.svelte b/apps/web/src/routes/(auth)/admin/appointments/upcoming/+page.svelte index a94f97d8..5429371a 100644 --- a/apps/web/src/routes/(auth)/admin/appointments/upcoming/+page.svelte +++ b/apps/web/src/routes/(auth)/admin/appointments/upcoming/+page.svelte @@ -1,5 +1,5 @@ diff --git a/apps/web/src/routes/(auth)/admin/health/+page.server.ts b/apps/web/src/routes/(auth)/admin/health/+page.server.ts index 7b5a4d1e..2da12a44 100644 --- a/apps/web/src/routes/(auth)/admin/health/+page.server.ts +++ b/apps/web/src/routes/(auth)/admin/health/+page.server.ts @@ -1,11 +1,11 @@ import { sql, type Kysely } from 'kysely'; import { durationsOf } from '@when/config'; import type { Database } from '@when/db'; -import { getConfig, getDb } from '$lib/server/state'; -import { discoverCalendars, listProviders, probeProvider } from '$lib/server/providers/status'; -import { listCalendars, probeCalendar } from '$lib/server/calendar/status'; -import { sendTestEmail, smtpSummary } from '$lib/server/email/status'; -import { workerReachable } from '$lib/server/worker'; +import { getConfig, getDb } from '#lib/server/state.js'; +import { discoverCalendars, listProviders, probeProvider } from '#lib/server/providers/status.js'; +import { listCalendars, probeCalendar } from '#lib/server/calendar/status.js'; +import { sendTestEmail, smtpSummary } from '#lib/server/email/status.js'; +import { workerReachable } from '#lib/server/worker.js'; import type { Actions, PageServerLoad } from './$types'; async function listBookingCounts(db: Kysely): Promise> { diff --git a/apps/web/src/routes/(auth)/admin/health/+page.svelte b/apps/web/src/routes/(auth)/admin/health/+page.svelte index d7905aff..a004bead 100644 --- a/apps/web/src/routes/(auth)/admin/health/+page.svelte +++ b/apps/web/src/routes/(auth)/admin/health/+page.svelte @@ -3,8 +3,8 @@ import IconWarningCircle from 'virtual:icons/ph/warning-circle'; import IconSpinner from 'virtual:icons/ph/spinner'; import { enhance } from '$app/forms'; - import AdminPage from '$lib/components/AdminPage.svelte'; - import { timeAgo } from '$lib/datetime'; + import AdminPage from '#lib/components/AdminPage.svelte'; + import { timeAgo } from '#lib/datetime.js'; import type { SubmitFunction } from './$types'; let { data, form } = $props(); diff --git a/apps/web/src/routes/(auth)/admin/health/page.test.ts b/apps/web/src/routes/(auth)/admin/health/page.test.ts index 7ed29ed8..6f6e4fb9 100644 --- a/apps/web/src/routes/(auth)/admin/health/page.test.ts +++ b/apps/web/src/routes/(auth)/admin/health/page.test.ts @@ -2,7 +2,7 @@ import { expect, test, vi } from 'vitest'; import { render } from 'svelte/server'; import HealthPage from './+page.svelte'; import type { ActionData, PageData } from './$types'; -import { validConfig } from '$lib/server/__fixtures__/valid-config'; +import { validConfig } from '#lib/server/__fixtures__/valid-config.js'; vi.mock('$app/state', () => ({ page: { url: new URL('https://book.example.com/admin/health') } diff --git a/apps/web/src/routes/(auth)/admin/health/server.test.ts b/apps/web/src/routes/(auth)/admin/health/server.test.ts index 8b4aaa20..e633781e 100644 --- a/apps/web/src/routes/(auth)/admin/health/server.test.ts +++ b/apps/web/src/routes/(auth)/admin/health/server.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test, vi } from 'vitest'; -import { validConfig } from '$lib/server/__fixtures__/valid-config'; +import { validConfig } from '#lib/server/__fixtures__/valid-config.js'; const mockDb = { selectFrom: vi.fn().mockReturnValue({ @@ -13,23 +13,23 @@ const mockDb = { }) }; -vi.mock('$lib/server/state', () => ({ +vi.mock('#lib/server/state.js', () => ({ getDb: () => mockDb, getConfig: () => validConfig })); -vi.mock('$lib/server/providers/status', () => ({ +vi.mock('#lib/server/providers/status.js', () => ({ listProviders: vi.fn().mockResolvedValue([]), discoverCalendars: vi.fn(), probeProvider: vi.fn() })); -vi.mock('$lib/server/calendar/status', () => ({ +vi.mock('#lib/server/calendar/status.js', () => ({ listCalendars: vi.fn().mockResolvedValue([]), probeCalendar: vi.fn() })); -vi.mock('$lib/server/email/status', () => ({ +vi.mock('#lib/server/email/status.js', () => ({ smtpSummary: vi.fn().mockResolvedValue({ host: 'smtp.example.com', port: 587, @@ -41,18 +41,18 @@ vi.mock('$lib/server/email/status', () => ({ sendTestEmail: vi.fn() })); -vi.mock('$lib/server/worker', () => ({ +vi.mock('#lib/server/worker.js', () => ({ workerReachable: vi.fn().mockResolvedValue(true) })); -import { sendTestEmail, type SendResult } from '$lib/server/email/status'; +import { sendTestEmail, type SendResult } from '#lib/server/email/status.js'; import { discoverCalendars, probeProvider, type DiscoveryResult, type ProbeResult -} from '$lib/server/providers/status'; -import { probeCalendar, type CalendarProbeResult } from '$lib/server/calendar/status'; +} from '#lib/server/providers/status.js'; +import { probeCalendar, type CalendarProbeResult } from '#lib/server/calendar/status.js'; import { actions, load } from './+page.server'; type LoadResult = Exclude>, void>; diff --git a/apps/web/src/routes/(auth)/admin/page.server.test.ts b/apps/web/src/routes/(auth)/admin/page.server.test.ts index 182d3d20..8c1944ab 100644 --- a/apps/web/src/routes/(auth)/admin/page.server.test.ts +++ b/apps/web/src/routes/(auth)/admin/page.server.test.ts @@ -1,10 +1,10 @@ import { afterEach, describe, expect, test, vi } from 'vitest'; import { openDb, runMigrations } from '@when/db'; -import { validConfig } from '$lib/server/__fixtures__/valid-config'; -import { systemClock } from '$lib/server/clock'; +import { validConfig } from '#lib/server/__fixtures__/valid-config.js'; +import { systemClock } from '#lib/server/clock.js'; let mockDb: Awaited> | null = null; -vi.mock('$lib/server/state', () => ({ +vi.mock('#lib/server/state.js', () => ({ getDb: () => { if (!mockDb) throw new Error('mockDb not initialized'); return mockDb; diff --git a/apps/web/src/routes/(auth)/admin/schedule/[slug]/+page.server.ts b/apps/web/src/routes/(auth)/admin/schedule/[slug]/+page.server.ts index 71a8de49..aac57db6 100644 --- a/apps/web/src/routes/(auth)/admin/schedule/[slug]/+page.server.ts +++ b/apps/web/src/routes/(auth)/admin/schedule/[slug]/+page.server.ts @@ -1,14 +1,14 @@ import { error, fail, redirect } from '@sveltejs/kit'; -import { isNewSlotBookable } from '$lib/server/availability/booking'; -import { getConfig, getDb } from '$lib/server/state'; -import { createAppointment } from '$lib/server/appointment/create'; -import { resolveDuration } from '$lib/server/appointment/duration'; +import { isNewSlotBookable } from '#lib/server/availability/booking.js'; +import { getConfig, getDb } from '#lib/server/state.js'; +import { createAppointment } from '#lib/server/appointment/create.js'; +import { resolveDuration } from '#lib/server/appointment/duration.js'; import { parseAndValidateAppointmentForm, parseSlot, resolveTimezone -} from '$lib/server/appointment/form.server'; -import { appointmentContext } from '$lib/server/appointment/context'; +} from '#lib/server/appointment/form.server.js'; +import { appointmentContext } from '#lib/server/appointment/context.js'; import type { Actions } from './$types'; export const actions: Actions = { diff --git a/apps/web/src/routes/(auth)/admin/schedule/[slug]/server.test.ts b/apps/web/src/routes/(auth)/admin/schedule/[slug]/server.test.ts index 6d54dcdf..efeb749e 100644 --- a/apps/web/src/routes/(auth)/admin/schedule/[slug]/server.test.ts +++ b/apps/web/src/routes/(auth)/admin/schedule/[slug]/server.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, test, vi } from 'vitest'; -import { validConfig } from '$lib/server/__fixtures__/valid-config'; +import { validConfig } from '#lib/server/__fixtures__/valid-config.js'; const h = vi.hoisted(() => ({ db: {}, @@ -9,15 +9,15 @@ const h = vi.hoisted(() => ({ resolveDuration: vi.fn() })); -vi.mock('$lib/server/state', () => ({ getConfig: () => validConfig, getDb: () => h.db })); -vi.mock('$lib/server/availability/booking', () => ({ isNewSlotBookable: h.isNewSlotBookable })); -vi.mock('$lib/server/appointment/create', () => ({ createAppointment: h.createAppointment })); -vi.mock('$lib/server/appointment/duration', async (importOriginal) => { - const original = await importOriginal(); +vi.mock('#lib/server/state.js', () => ({ getConfig: () => validConfig, getDb: () => h.db })); +vi.mock('#lib/server/availability/booking.js', () => ({ isNewSlotBookable: h.isNewSlotBookable })); +vi.mock('#lib/server/appointment/create.js', () => ({ createAppointment: h.createAppointment })); +vi.mock('#lib/server/appointment/duration.js', async (importOriginal) => { + const original = await importOriginal(); return { ...original, resolveDuration: h.resolveDuration }; }); -vi.mock('$lib/server/appointment/form.server', async (io) => { - const original = await io(); +vi.mock('#lib/server/appointment/form.server.js', async (io) => { + const original = await io(); return { ...original, parseAndValidateAppointmentForm: h.parseForm }; }); diff --git a/apps/web/src/routes/(auth)/admin/services/google/callback/+page.server.ts b/apps/web/src/routes/(auth)/admin/services/google/callback/+page.server.ts index d0351dd3..0a7ccb3e 100644 --- a/apps/web/src/routes/(auth)/admin/services/google/callback/+page.server.ts +++ b/apps/web/src/routes/(auth)/admin/services/google/callback/+page.server.ts @@ -1,15 +1,15 @@ import { dev } from '$app/environment'; -import { getConfig } from '$lib/server/state'; +import { getConfig } from '#lib/server/state.js'; import { exchangeGoogleConnect, findGoogleProvider, refreshTokenEnvVar -} from '$lib/server/providers/google-connect'; +} from '#lib/server/providers/google-connect.js'; import { STATE_COOKIE, parseOAuthState, stateCookieOptions -} from '$lib/server/providers/state-cookie'; +} from '#lib/server/providers/state-cookie.js'; import type { PageServerLoad } from './$types'; function failed(service: string | null, error: string) { diff --git a/apps/web/src/routes/(auth)/admin/services/google/callback/+page.svelte b/apps/web/src/routes/(auth)/admin/services/google/callback/+page.svelte index 3f6ab79f..6759b4ed 100644 --- a/apps/web/src/routes/(auth)/admin/services/google/callback/+page.svelte +++ b/apps/web/src/routes/(auth)/admin/services/google/callback/+page.svelte @@ -1,5 +1,5 @@ diff --git a/apps/web/src/routes/+layout.server.ts b/apps/web/src/routes/+layout.server.ts index ddccf1f4..ddad6844 100644 --- a/apps/web/src/routes/+layout.server.ts +++ b/apps/web/src/routes/+layout.server.ts @@ -1,4 +1,4 @@ -import { getConfig } from '$lib/server/state'; +import { getConfig } from '#lib/server/state.js'; import type { LayoutServerLoad } from './$types'; export const load: LayoutServerLoad = ({ cookies }) => { diff --git a/apps/web/src/routes/+layout.svelte b/apps/web/src/routes/+layout.svelte index 53d2e9d9..607a3b17 100644 --- a/apps/web/src/routes/+layout.svelte +++ b/apps/web/src/routes/+layout.svelte @@ -1,14 +1,14 @@ - -
{#if form?.error} @@ -121,7 +118,7 @@ {#each formFields as field (field.name)} {#if visibleFields.get(field.name)} = { 'x-real-ip': address, ...headers }, - ...body === undefined ? {} : { body: JSON.stringify(body) } + ...(body === undefined ? {} : { body: JSON.stringify(body) }) }), locals: {} } as Parameters[0]['event']; diff --git a/apps/web/src/lib/server/auth/index.ts b/apps/web/src/lib/server/auth/index.ts index ec74fb5d..97246999 100644 --- a/apps/web/src/lib/server/auth/index.ts +++ b/apps/web/src/lib/server/auth/index.ts @@ -1,5 +1,5 @@ import type { Handle } from '@sveltejs/kit/hooks'; -import { building } from '$app/environment'; +import { building } from '$app/env'; import { betterAuth, type BetterAuthOptions } from 'better-auth/minimal'; import { svelteKitHandler } from 'better-auth/svelte-kit'; import type { WhenConfiguration } from '@when/config'; diff --git a/apps/web/src/lib/server/providers/state-cookie.ts b/apps/web/src/lib/server/providers/state-cookie.ts index 10912a93..977646a0 100644 --- a/apps/web/src/lib/server/providers/state-cookie.ts +++ b/apps/web/src/lib/server/providers/state-cookie.ts @@ -1,6 +1,6 @@ import type { Cookies } from '@sveltejs/kit'; -type CookieOptions = Parameters[2]; +type CookieOptions = NonNullable[2]>; export const STATE_COOKIE = 'when_google_oauth'; diff --git a/apps/web/src/routes/(app)/appointment/[id]/+page.svelte b/apps/web/src/routes/(app)/appointment/[id]/+page.svelte index ccda40dd..4b820f91 100644 --- a/apps/web/src/routes/(app)/appointment/[id]/+page.svelte +++ b/apps/web/src/routes/(app)/appointment/[id]/+page.svelte @@ -1,6 +1,6 @@ @@ -360,19 +353,19 @@ appointmentId={data.appointment.id} token={data.token} role={data.role} - onCancel={() => cancelDialogOpen = true} + onCancel={() => (cancelDialogOpen = true)} hasNote={!!data.appointment.note} - onEditNote={() => editNoteDialogOpen = true} + onEditNote={() => (editNoteDialogOpen = true)} hasLocation={!!data.appointment.location} - onEditLocation={() => editLocationDialogOpen = true} + onEditLocation={() => (editLocationDialogOpen = true)} hasVideoChat={!!data.appointment.video_chat} videoChatRequested={data.videoChatRequested} - changingVideoChat={changingVideoChat} + {changingVideoChat} onGenerateVideoChat={handleGenerateVideoChat} onRemoveVideoChat={handleRemoveVideoChat} - onEditVideoChat={() => editVideoChatDialogOpen = true} - onEditDuration={data.canEditDuration ? () => editDurationDialogOpen = true : undefined} - isEditable={isEditable} + onEditVideoChat={() => (editVideoChatDialogOpen = true)} + onEditDuration={data.canEditDuration ? () => (editDurationDialogOpen = true) : undefined} + {isEditable} /> {/if} @@ -424,7 +417,7 @@ {/if} {#if data.rescheduledFrom && data.latestAppointment} - · +  ·  {/if} {#if data.latestAppointment} @@ -459,12 +452,16 @@
{formatTzShort(displayTz)}{#if zonesDiffer} - · you +  · you {/if}
{#if zonesDiffer}
- {formatTimeRange(data.appointment.start_time, data.appointment.end_time, counterpartTz)} · {formatTzShort(counterpartTz)} · {counterpartName} + {formatTimeRange( + data.appointment.start_time, + data.appointment.end_time, + counterpartTz + )} · {formatTzShort(counterpartTz)} · {counterpartName}
{/if} @@ -474,7 +471,7 @@ + onclick={() => (declineDialogOpen = true)}>Decline {/if} {#if data.actions.accept.allowed} diff --git a/apps/web/src/routes/(auth)/admin/appointment/[id]/server.test.ts b/apps/web/src/routes/(auth)/admin/appointment/[id]/server.test.ts index 66895a51..ae7eb07d 100644 --- a/apps/web/src/routes/(auth)/admin/appointment/[id]/server.test.ts +++ b/apps/web/src/routes/(auth)/admin/appointment/[id]/server.test.ts @@ -9,7 +9,8 @@ import type { RequestEvent } from './$types'; vi.mock('#lib/server/appointment/context.js', () => ({ appointmentContext: () => context })); vi.mock('#lib/server/appointment/request-video-chat.js', () => ({ requestVideoChat: vi.fn() })); vi.mock('#lib/server/appointment/change-duration.js', async (importOriginal) => { - const original = await importOriginal(); + const original = + await importOriginal(); return { ...original, changeAppointmentDuration: vi.fn() }; }); diff --git a/apps/web/src/routes/(auth)/admin/services/google/callback/+page.server.ts b/apps/web/src/routes/(auth)/admin/services/google/callback/+page.server.ts index 0a7ccb3e..35c0f377 100644 --- a/apps/web/src/routes/(auth)/admin/services/google/callback/+page.server.ts +++ b/apps/web/src/routes/(auth)/admin/services/google/callback/+page.server.ts @@ -1,4 +1,4 @@ -import { dev } from '$app/environment'; +import { dev } from '$app/env'; import { getConfig } from '#lib/server/state.js'; import { exchangeGoogleConnect, diff --git a/apps/web/src/routes/(auth)/admin/services/google/connect/+server.ts b/apps/web/src/routes/(auth)/admin/services/google/connect/+server.ts index e56e8842..cda40dff 100644 --- a/apps/web/src/routes/(auth)/admin/services/google/connect/+server.ts +++ b/apps/web/src/routes/(auth)/admin/services/google/connect/+server.ts @@ -1,5 +1,5 @@ import { redirect, error } from '@sveltejs/kit'; -import { dev } from '$app/environment'; +import { dev } from '$app/env'; import { getConfig } from '#lib/server/state.js'; import { consentUrl, findGoogleProvider } from '#lib/server/providers/google-connect.js'; import { STATE_COOKIE, stateCookieOptions } from '#lib/server/providers/state-cookie.js'; @@ -16,5 +16,7 @@ export const POST: RequestHandler = async ({ request, cookies }) => { const state = crypto.randomUUID(); cookies.set(STATE_COOKIE, JSON.stringify({ state, service: name }), stateCookieOptions(dev)); - redirect(303, consentUrl(provider, config.url.app, state)); + redirect(303, consentUrl(provider, config.url.app, state), { + external: ['https://accounts.google.com'] + }); }; diff --git a/apps/web/src/routes/signin/+page.svelte b/apps/web/src/routes/signin/+page.svelte index 0ec1e3d3..aec4eea0 100644 --- a/apps/web/src/routes/signin/+page.svelte +++ b/apps/web/src/routes/signin/+page.svelte @@ -47,7 +47,12 @@ pending = false; return; } - await goto(data.callbackUrl, { invalidateAll: true }); + try { + await goto(data.callbackUrl, { invalidateAll: true }); + } catch { + // A same-origin callback may no longer resolve to a Kit route. + window.location.assign(data.callbackUrl); + } } catch { submitError = 'NetworkError'; pending = false; diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index bcebc986..9baba7a8 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -5,23 +5,7 @@ "erasableSyntaxOnly": true, "sourceMap": true, "strict": true, - "types": [ - "$app/types", - "node", - "unplugin-icons/types/svelte" - ] + "types": ["$app/types", "node", "unplugin-icons/types/svelte"] }, - "include": [ - ".svelte-kit/ambient.d.ts", - ".svelte-kit/non-ambient.d.ts", - ".svelte-kit/types/**/$types.d.ts", - "vite.config.js", - "vite.config.ts", - "src/**/*.js", - "src/**/*.ts", - "src/**/*.svelte", - "playwright.config.ts", - "e2e/*.ts", - "e2e/support/**/*.ts" - ] + "include": ["src", "vite.config.ts", "playwright.config.ts", "e2e/*.ts", "e2e/support/**/*.ts"] } diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index c18e643e..9c46d024 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -20,12 +20,9 @@ export default defineConfig(({ command }) => { sveltekit({ compilerOptions: { // Force runes mode for the project, except for libraries. Can be removed in svelte 6. - runes: ({ filename }) => filename.split(/[/\\]/).includes('node_modules') ? undefined : true + runes: ({ filename }) => + filename.split(/[/\\]/).includes('node_modules') ? undefined : true }, - - // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. - // If your environment is not supported, or you settled on a specific environment, switch out the adapter. - // See https://svelte.dev/docs/kit/adapters for more information about adapters. adapter: adapter(), inlineStyleThreshold: 10240, csp: { diff --git a/docs/.env.example b/docs/.env.example index 4ec0d785..7fe2f51e 100644 --- a/docs/.env.example +++ b/docs/.env.example @@ -1,7 +1,11 @@ # Copy to .env beside compose.yaml. Keep it private and out of Git. # Generate AUTH_SECRET with: openssl rand -base64 32 AUTH_SECRET= -ORIGIN=http://localhost:3000 +# When's public URL default for auth and links, not an adapter request-origin override. +ORIGIN=https://when.example.com +# Native adapter setting: the trusted proxy must overwrite X-Forwarded-Proto. +# Preserve the public Host and keep the backend private; see docs/deployment.md. +PROTOCOL_HEADER=x-forwarded-proto # Match the ${...} references in config/when.yaml. WHEN_ADMIN_PASSWORD= diff --git a/docs/config.md b/docs/config.md index 2d982785..7d5bdc7b 100644 --- a/docs/config.md +++ b/docs/config.md @@ -374,8 +374,11 @@ Treat both databases and their backups as sensitive; see | `internal` | `${WHEN_URL_INTERNAL:-}` | Worker → web, including branding images embedded in email. Empty falls back to `app`. | | `worker` | `http://when-worker:9000` | Web → worker telemetry and metrics. | -Usually, set `ORIGIN` and leave `url.app` alone. The web adapter needs `ORIGIN` -behind a reverse proxy anyway. See [deployment](deployment.md#environment-variables). +Usually, set `ORIGIN` and leave `url.app` alone. It supplies When's public URL +for authentication and generated links; an explicit `url.app` takes precedence. +SvelteKit 3's native adapter ignores `ORIGIN` and derives its request origin from +trusted proxy headers and Host instead. These must match the configured public +URL; see the [proxy requirements](deployment.md#reverse-proxy). ## `prometheus` diff --git a/docs/deployment.md b/docs/deployment.md index 74e04d2c..4afab2bd 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -14,7 +14,26 @@ Make `data/` writable by container UID 1000, or SQLite won't start. docker compose up -d ``` -Web listens on 3000. +Web listens on backend port 3000. Open the public proxy URL, not the backend. + +## reverse proxy + +Production browser access requires a trusted reverse proxy. Set +`PROTOCOL_HEADER=x-forwarded-proto`; the proxy must overwrite `X-Forwarded-Proto` +with the public scheme and preserve the public `Host`, including any non-default +port. Reject inappropriate public hosts and keep the backend loopback-only or +private so clients cannot bypass the proxy and supply trusted headers themselves. +The adapter trusts these headers; it does not authenticate the proxy. + +If your proxy forwards the public authority in `X-Forwarded-Host` instead, set the +native `HOST_HEADER=x-forwarded-host` only with a matching proxy overwrite policy. +Do not set `PORT_HEADER` when the authority already includes the port. + +`ORIGIN` supplies When's `url.app` default for authentication and generated links; +SvelteKit 3's native adapter ignores it. The configured public URL and the request +origin derived from proxy headers must agree. An explicit YAML `url.app` overrides +that default, not the adapter's request origin. Internal health and branding GETs +can still use backend HTTP. ## inspect logs @@ -30,10 +49,11 @@ Copy the [environment example](.env.example) to `.env` beside `compose.yaml` and supply real values. After editing `.env`, run `docker compose up -d --force-recreate`. A restart keeps the old environment. -| Variable | Used for | -| ------------- | -------------------------------------------------------------------------------------------------------------------------- | -| `AUTH_SECRET` | Required Auth.js session-signing secret. Generate 32 random bytes with `openssl rand -base64 32`. | -| `ORIGIN` | Public base URL, no trailing slash. Set it behind a proxy or form POSTs can fail with 403. Also the default for `url.app`. | +| Variable | Used for | +| ----------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `AUTH_SECRET` | Required Better Auth secret. Generate 32 random bytes with `openssl rand -base64 32`. | +| `ORIGIN` | Public base URL, no trailing slash. Default for When's `url.app`, used for auth and links; not an adapter override. | +| `PROTOCOL_HEADER` | Set to `x-forwarded-proto` behind the trusted production proxy, which must overwrite it with the public scheme. | Other secret names come from `${ENV_VAR}` references in your config. The example uses: diff --git a/docs/when.example.yaml b/docs/when.example.yaml index f73d9de3..1800d96b 100644 --- a/docs/when.example.yaml +++ b/docs/when.example.yaml @@ -166,8 +166,9 @@ meetings: # --- Public and internal URLs --- # url: -# app defaults to ${ORIGIN}, which you must set anyway to run behind a reverse -# proxy — set ORIGIN in .env and leave this alone rather than repeating it here. +# app defaults to ${ORIGIN:-http://localhost:5173} for auth and generated links. +# Set ORIGIN in .env, or override app here. Neither sets the native adapter's +# request origin: matching trusted proxy headers and Host do (see deployment.md). # app: 'https://when.example.com' # public base URL, used in emails and calendar events # internal: 'http://when-app:3000' # worker → web (defaults to ${WHEN_URL_INTERNAL}) # worker: 'http://when-worker:9000' # web → worker diff --git a/packages/config/src/config.schema.json b/packages/config/src/config.schema.json index 7ecd2522..d966057c 100644 --- a/packages/config/src/config.schema.json +++ b/packages/config/src/config.schema.json @@ -898,7 +898,7 @@ "type": "object", "properties": { "app": { - "description": "Public base URL of the app (include the scheme), used to build links in emails and calendar events. Defaults to the ORIGIN env var, which adapter-node needs anyway to sit behind a reverse proxy — set ORIGIN alone and both agree.", + "description": "Public base URL of the app (include the scheme), used for authentication and links in emails and calendar events. Defaults to the ORIGIN env var, or http://localhost:5173 if unset. The native adapter ignores ORIGIN; trusted proxy headers and Host must produce the same request origin.", "minLength": 1, "default": "${ORIGIN:-http://localhost:5173}", "type": "string" diff --git a/packages/config/src/schema.ts b/packages/config/src/schema.ts index ff8f92cd..aed3bc97 100644 --- a/packages/config/src/schema.ts +++ b/packages/config/src/schema.ts @@ -289,7 +289,7 @@ export const DatabaseSchema = Type.Object({ export const UrlSchema = Type.Object({ app: Type.String({ - description: 'Public base URL of the app (include the scheme), used to build links in emails and calendar events. Defaults to the ORIGIN env var, which adapter-node needs anyway to sit behind a reverse proxy — set ORIGIN alone and both agree.', + description: 'Public base URL of the app (include the scheme), used for authentication and links in emails and calendar events. Defaults to the ORIGIN env var, or http://localhost:5173 if unset. The native adapter ignores ORIGIN; trusted proxy headers and Host must produce the same request origin.', minLength: 1, default: '${ORIGIN:-http://localhost:5173}' }), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e2a0a4c3..ae487984 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,7 +57,7 @@ importers: version: 3.8.3 prettier-plugin-svelte: specifier: 3.5.2 - version: 3.5.2(prettier@3.8.3)(svelte@5.56.0(@typescript-eslint/types@8.60.0)) + version: 3.5.2(prettier@3.8.3)(svelte@5.57.3(@typescript-eslint/types@8.60.0)) typescript: specifier: 6.0.3 version: 6.0.3 @@ -148,10 +148,10 @@ importers: version: link:../../packages/video-chat better-auth: specifier: 1.7.14 - version: 1.7.14(@opentelemetry/api@1.9.1)(@sveltejs/kit@2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vitest@4.1.7) + version: 1.7.14(@opentelemetry/api@1.9.1)(@sveltejs/kit@3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vitest@4.1.7) bits-ui: specifier: 2.18.1 - version: 2.18.1(@internationalized/date@3.12.2)(@sveltejs/kit@2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0)) + version: 2.18.1(@internationalized/date@3.12.2)(@sveltejs/kit@3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0)) kysely: specifier: 0.28.17 version: 0.28.17 @@ -193,14 +193,17 @@ importers: specifier: 1.61.1 version: 1.61.1 '@sveltejs/adapter-node': - specifier: 5.5.4 - version: 5.5.4(@sveltejs/kit@2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0))) + specifier: 6.0.1 + version: 6.0.1(@sveltejs/kit@3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0))) '@sveltejs/kit': - specifier: 2.70.1 - version: 2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) + specifier: 3.1.1 + version: 3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) + '@sveltejs/load-config': + specifier: 0.2.2 + version: 0.2.2 '@sveltejs/vite-plugin-svelte': specifier: 7.1.2 - version: 7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) + version: 7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) '@types/node': specifier: 24.12.4 version: 24.12.4 @@ -215,7 +218,7 @@ importers: version: 10.1.8(eslint@10.4.1) eslint-plugin-svelte: specifier: 3.18.0 - version: 3.18.0(eslint@10.4.1)(svelte@5.56.0(@typescript-eslint/types@8.60.0)) + version: 3.18.0(eslint@10.4.1)(svelte@5.57.3(@typescript-eslint/types@8.60.0)) globals: specifier: 17.6.0 version: 17.6.0 @@ -227,13 +230,13 @@ importers: version: 3.8.3 prettier-plugin-svelte: specifier: 3.5.2 - version: 3.5.2(prettier@3.8.3)(svelte@5.56.0(@typescript-eslint/types@8.60.0)) + version: 3.5.2(prettier@3.8.3)(svelte@5.57.3(@typescript-eslint/types@8.60.0)) svelte: - specifier: 5.56.0 - version: 5.56.0(@typescript-eslint/types@8.60.0) + specifier: 5.57.3 + version: 5.57.3(@typescript-eslint/types@8.60.0) svelte-check: - specifier: 4.4.8 - version: 4.4.8(picomatch@4.0.4)(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3) + specifier: 4.7.7 + version: 4.7.7(picomatch@4.0.4)(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -242,7 +245,7 @@ importers: version: 8.60.0(eslint@10.4.1)(typescript@6.0.3) unplugin-icons: specifier: 23.0.1 - version: 23.0.1(svelte@5.56.0(@typescript-eslint/types@8.60.0)) + version: 23.0.1(svelte@5.57.3(@typescript-eslint/types@8.60.0)) vite: specifier: 8.0.16 version: 8.0.16(@types/node@24.12.4)(esbuild@0.25.0)(yaml@2.9.0) @@ -994,6 +997,9 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} @@ -1147,205 +1153,31 @@ packages: '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - '@rollup/plugin-commonjs@29.0.3': - resolution: {integrity: sha512-ZaOxZceP7SOUW7Lqw5IRVweSQYWaeIPnXIGLiB690EBA3FGJTO40EEr2L5yZplJWsgTCogILRSpcAe7+U0Otdg==} - engines: {node: '>=16.0.0 || 14 >= 14.17'} - peerDependencies: - rollup: ^2.68.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-json@6.1.0': - resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-node-resolve@16.0.3': - resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/pluginutils@5.4.0': - resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/rollup-android-arm-eabi@4.60.4': - resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.60.4': - resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.60.4': - resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.60.4': - resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.60.4': - resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.60.4': - resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} - cpu: [arm] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} - cpu: [arm] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-arm64-gnu@4.60.4': - resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm64-musl@4.60.4': - resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-loong64-gnu@4.60.4': - resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} - cpu: [loong64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-loong64-musl@4.60.4': - resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} - cpu: [loong64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-ppc64-musl@4.60.4': - resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} - cpu: [ppc64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-riscv64-musl@4.60.4': - resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-s390x-gnu@4.60.4': - resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-gnu@4.60.4': - resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-musl@4.60.4': - resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rollup/rollup-openbsd-x64@4.60.4': - resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.60.4': - resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.60.4': - resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.60.4': - resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.60.4': - resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.60.4': - resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} - cpu: [x64] - os: [win32] - '@sinclair/typebox@0.34.49': resolution: {integrity: sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==} '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@sveltejs/acorn-typescript@1.0.10': - resolution: {integrity: sha512-4WfKk68eTih+MiJD4fSbxN7E8kVBmTMPWHUPYjvl2N0rMs53YLTT8/YjKU5Dtnz5LqDjl7LEw4U7lXR2W3J5WA==} + '@sveltejs/acorn-typescript@1.0.13': + resolution: {integrity: sha512-wgKggnhZVL9Bfx1OaKKTrYY9BFRk6C8UAkQNUcIv1+llzYrIqy+RZm5HPKzn0NpEBvTVhTqB4kQyllZywsRBRQ==} peerDependencies: acorn: ^8.9.0 - '@sveltejs/adapter-node@5.5.4': - resolution: {integrity: sha512-45X92CXW+2J8ZUzPv3eLlKWEzINKiiGeFWTjyER4ZN4sGgNoaoeSkCY/QYNxHpPXy71QPsctwccBo9jJs0ySPQ==} + '@sveltejs/adapter-node@6.0.1': + resolution: {integrity: sha512-Pt/YcMakEkTjdQXaAvxrjrDnoGX4zU7pAZICnoLfpI+CawLGigq5upjFW9rVK2QY7yfpR1xeRG/kgI+syzPB3w==} peerDependencies: - '@sveltejs/kit': ^2.4.0 + '@sveltejs/kit': ^3.0.0-next.0 - '@sveltejs/kit@2.70.1': - resolution: {integrity: sha512-nY9SPHGOZro3doud9vZXDBwl9tCZIouuJztjgSHs6PAIrv9M/z5O7eOhPV5xU7CgVHA976Jwu3BA1hIFvXztkA==} - engines: {node: '>=18.13'} + '@sveltejs/kit@3.1.1': + resolution: {integrity: sha512-BiEMvekYXE9Gu/YhWJ/yJ0WDLH1PX/dmjuAeFp5rrtdmgdzkjt7DvimlSP+/U4tgposl7pkE20luHpcnc6BgRw==} + engines: {node: '>=22.17'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.0.0 - '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0 - svelte: ^4.0.0 || ^5.0.0-next.0 - typescript: ^5.3.3 || ^6.0.0 + '@sveltejs/vite-plugin-svelte': ^7.0.0 + svelte: ^5.57.1 + typescript: ^6.0.0 vite: 8.0.16 peerDependenciesMeta: '@opentelemetry/api': @@ -1353,6 +1185,14 @@ packages: typescript: optional: true + '@sveltejs/load-config@0.2.2': + resolution: {integrity: sha512-K7dsJDQxBOF+f+epuhMactcjK2VP4MRkLKtwSykNtEI+cKVEyzrmmhQ1pmoxI800m4JKcyJ05L2M4yPwAGiBNw==} + engines: {node: '>= 18.0.0'} + + '@sveltejs/load-config@0.2.3': + resolution: {integrity: sha512-VT3qmUb8pRV2QrZjd8iAmtg8lf4W0TIjZbvXtz5MKei/q96teWZgGJyyidJzOjzZzvdq616eSRVeMYIQChUTAQ==} + engines: {node: '>= 18.0.0'} + '@sveltejs/vite-plugin-svelte@7.1.2': resolution: {integrity: sha512-DrUBA2UXRfDmUX/ZTiEopd3X40yavsJF1FX2RygcuIScHL7o5YX1fMvoYnDhjeJQC4weCOklirpNWlcb2NiSeA==} engines: {node: ^20.19 || ^22.12 || >=24} @@ -1451,18 +1291,12 @@ packages: '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - '@types/cookie@0.6.0': - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} '@types/esrecurse@4.3.1': resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} @@ -1475,12 +1309,6 @@ packages: '@types/nodemailer@8.0.0': resolution: {integrity: sha512-fyf8jWULsCo0d0BuoQ75i6IeoHs47qcqxWc7yUdUcV0pOZGjUTTOvwdG1PRXUDqN/8A64yQdQdnA2pZgcdi+cA==} - '@types/resolve@1.20.2': - resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - - '@types/trusted-types@2.0.7': - resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - '@typescript-eslint/eslint-plugin@8.60.0': resolution: {integrity: sha512-QYb/sa74/s7OKMbACMjrYnGspj9Hs5YI5aaffSL65UfeBUzVzBJfVo3oWSpbzPurvm7yaCCo2Lk7lVj610HqKw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1588,6 +1416,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.19.0: + resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} + engines: {node: '>=0.4.0'} + hasBin: true + ajv@6.15.0: resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} @@ -1714,9 +1547,6 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -1726,9 +1556,9 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cookie@0.6.0: - resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} - engines: {node: '>= 0.6'} + cookie@2.0.1: + resolution: {integrity: sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==} + engines: {node: '>=22'} cron-parser@5.10.1: resolution: {integrity: sha512-pKRrRagItwk9rGIStcUyMxFX34x56zoX3KDf9HJ4ttwkXIK1qxK63EvXvEDmlxI9AdPJ+Y7TEKRftRlW5eSS7A==} @@ -1773,16 +1603,12 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} - devalue@5.8.1: - resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==} + devalue@5.9.4: + resolution: {integrity: sha512-sPAT4pztbu6586/hrhOnMKS17IJrvg12mXiSPSS3W5qDeN2RGgvZ0diZCm31dBbnevfVmujNO3IM2wrS4Y2Rhg==} end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - es-module-lexer@2.1.0: resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} @@ -1856,8 +1682,8 @@ packages: resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} - esrap@2.2.9: - resolution: {integrity: sha512-4KijP+NxCWthMCUC3qHbE6n4vCjqgJS1uAYKhuT/GWfFTf1Qyive2TgOjep+gzbSzRfnNyaN/UU9YmdOt8Eg0A==} + esrap@2.4.0: + resolution: {integrity: sha512-CQPcneEHw/czj32uwQC52nYnax8H4SXt25FCM+LIwGZ49cMIxpOj3bP8wmzcI+Z0HIy5KkClaPhRLfCySzwHPA==} peerDependencies: '@typescript-eslint/types': ^8.2.0 peerDependenciesMeta: @@ -1872,9 +1698,6 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -1951,9 +1774,6 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} @@ -1974,10 +1794,6 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - hasown@2.0.4: - resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} - engines: {node: '>= 0.4'} - help-me@5.0.0: resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} @@ -2006,10 +1822,6 @@ packages: inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} - is-core-module@2.16.2: - resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} - engines: {node: '>= 0.4'} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -2018,12 +1830,6 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - - is-reference@1.2.1: - resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - is-reference@3.0.3: resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} @@ -2070,10 +1876,6 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - known-css-properties@0.37.0: resolution: {integrity: sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==} @@ -2188,6 +1990,9 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + magic-string@1.4.5: + resolution: {integrity: sha512-oLLC2+YvQUfAa+vxoufE/yc1icb87M9iXIRqAoR/2EhE/8cb3SF/+Gi0c2By1B+5Vz2e2vQtUvHiu1+63Znh+w==} + magicast@0.5.3: resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} @@ -2280,9 +2085,6 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -2404,21 +2206,11 @@ packages: real-require@1.0.0: resolution: {integrity: sha512-P4nbQYQfePJxRSmY+v/KINxVucm4NF3p3s7pJveMTtom52FR4YGltUQLB8idDXwDDWW+eYrWDFbuzUnjoWHF7g==} - resolve@1.22.12: - resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} - engines: {node: '>= 0.4'} - hasBin: true - rolldown@1.0.3: resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - rollup@4.60.4: - resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - rou3@0.9.2: resolution: {integrity: sha512-3SOzvaAg8rkHrXtRjpCvCvbyO5to9oOO27Z/XqHEYXfMRVSw/qMIVdmaOk9W2lcRLtR6dlqTjo9hDeJk70QBYQ==} @@ -2447,9 +2239,6 @@ packages: engines: {node: '>=10'} hasBin: true - set-cookie-parser@3.1.0: - resolution: {integrity: sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==} - set-cookie-parser@3.2.1: resolution: {integrity: sha512-Npd1Pt+4zb3BrSZDPd2qFwRpS6b1EUEasRrO8xS0zMJi0fApXXK5YuzP0minyJnxwnFHoVoJwA55q0A0cu63gQ==} @@ -2503,17 +2292,13 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - svelte-check@4.4.8: - resolution: {integrity: sha512-67adfgBox5eNSNIvIIwgFizKGdcRrGpiMoNO2obHcYuLz7iTa8Xgm/NGU3ntMFnNm8K1grFOIG6HhMLX/vcN8w==} + svelte-check@4.7.7: + resolution: {integrity: sha512-Ge2IMdeTpbJuzNFGRiiMg0RWgbScysKQu7xwcyFJ22+DU9F5nPX51+Q3gHmGqRxYQMx2knreVWt5oCtfe0vf2g==} engines: {node: '>= 18.0.0'} hasBin: true peerDependencies: svelte: ^4.0.0 || ^5.0.0-next.0 - typescript: '>=5.0.0' + typescript: ^5.0.0 || ^6.0.0 svelte-eslint-parser@1.6.1: resolution: {integrity: sha512-hhvSH6kRj46UzrBVO5TaotD+Iuvruj5ccKBcO4wAhVcPTLmIc/c32D8UllBTYO0on4LzYuM0rNzf1lM/gBlkSQ==} @@ -2530,8 +2315,8 @@ packages: peerDependencies: svelte: ^5.30.2 - svelte@5.56.0: - resolution: {integrity: sha512-kTXr26t1bchFp28ROrb957LtbujpBmBDibmqMGziVpUs7awBi96TGgX6SovrA8BNoEUDVRK2Fb9FkeYlGspoVg==} + svelte@5.57.3: + resolution: {integrity: sha512-5mAftM3SoDV9X0zdF386F9p2pv8iKOwi/KfBS1XnBAkVCKFzVOLHUoa8iGWAt4buoicLmyWVRpuuD5wplXOQsg==} engines: {node: '>=18'} tabbable@6.4.0: @@ -3164,6 +2949,8 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/sourcemap-codec@1.6.0': {} + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -3262,160 +3049,45 @@ snapshots: '@rolldown/pluginutils@1.0.1': {} - '@rollup/plugin-commonjs@29.0.3(rollup@4.60.4)': - dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.60.4) - commondir: 1.0.1 - estree-walker: 2.0.2 - fdir: 6.5.0(picomatch@4.0.4) - is-reference: 1.2.1 - magic-string: 0.30.21 - picomatch: 4.0.4 - optionalDependencies: - rollup: 4.60.4 - - '@rollup/plugin-json@6.1.0(rollup@4.60.4)': - dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.60.4) - optionalDependencies: - rollup: 4.60.4 - - '@rollup/plugin-node-resolve@16.0.3(rollup@4.60.4)': - dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.60.4) - '@types/resolve': 1.20.2 - deepmerge: 4.3.1 - is-module: 1.0.0 - resolve: 1.22.12 - optionalDependencies: - rollup: 4.60.4 - - '@rollup/pluginutils@5.4.0(rollup@4.60.4)': - dependencies: - '@types/estree': 1.0.9 - estree-walker: 2.0.2 - picomatch: 4.0.4 - optionalDependencies: - rollup: 4.60.4 - - '@rollup/rollup-android-arm-eabi@4.60.4': - optional: true - - '@rollup/rollup-android-arm64@4.60.4': - optional: true - - '@rollup/rollup-darwin-arm64@4.60.4': - optional: true - - '@rollup/rollup-darwin-x64@4.60.4': - optional: true - - '@rollup/rollup-freebsd-arm64@4.60.4': - optional: true - - '@rollup/rollup-freebsd-x64@4.60.4': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-ppc64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-x64-musl@4.60.4': - optional: true - - '@rollup/rollup-openbsd-x64@4.60.4': - optional: true - - '@rollup/rollup-openharmony-arm64@4.60.4': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.60.4': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.60.4': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.60.4': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.60.4': - optional: true - '@sinclair/typebox@0.34.49': {} '@standard-schema/spec@1.1.0': {} - '@sveltejs/acorn-typescript@1.0.10(acorn@8.16.0)': + '@sveltejs/acorn-typescript@1.0.13(acorn@8.19.0)': dependencies: - acorn: 8.16.0 + acorn: 8.19.0 - '@sveltejs/adapter-node@5.5.4(@sveltejs/kit@2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))': + '@sveltejs/adapter-node@6.0.1(@sveltejs/kit@3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))': dependencies: - '@rollup/plugin-commonjs': 29.0.3(rollup@4.60.4) - '@rollup/plugin-json': 6.1.0(rollup@4.60.4) - '@rollup/plugin-node-resolve': 16.0.3(rollup@4.60.4) - '@sveltejs/kit': 2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) - rollup: 4.60.4 + '@sveltejs/kit': 3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) - '@sveltejs/kit@2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0))': + '@sveltejs/kit@3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0))': dependencies: + '@rolldown/pluginutils': 1.0.1 '@standard-schema/spec': 1.1.0 - '@sveltejs/acorn-typescript': 1.0.10(acorn@8.16.0) - '@sveltejs/vite-plugin-svelte': 7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) - '@types/cookie': 0.6.0 - acorn: 8.16.0 - cookie: 0.6.0 - devalue: 5.8.1 + '@sveltejs/vite-plugin-svelte': 7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) + cookie: 2.0.1 + devalue: 5.9.4 esm-env: 1.2.2 - kleur: 4.1.5 - magic-string: 0.30.21 + magic-string: 1.4.5 mrmime: 2.0.1 - set-cookie-parser: 3.1.0 sirv: 3.0.2 - svelte: 5.56.0(@typescript-eslint/types@8.60.0) + svelte: 5.57.3(@typescript-eslint/types@8.60.0) vite: 8.0.16(@types/node@24.12.4)(esbuild@0.25.0)(yaml@2.9.0) optionalDependencies: '@opentelemetry/api': 1.9.1 typescript: 6.0.3 - '@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0))': + '@sveltejs/load-config@0.2.2': {} + + '@sveltejs/load-config@0.2.3': {} + + '@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0))': dependencies: deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 - svelte: 5.56.0(@typescript-eslint/types@8.60.0) + svelte: 5.57.3(@typescript-eslint/types@8.60.0) vite: 8.0.16(@types/node@24.12.4)(esbuild@0.25.0)(yaml@2.9.0) vitefu: 1.1.3(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) @@ -3484,14 +3156,10 @@ snapshots: '@types/deep-eql': 4.0.2 assertion-error: 2.0.1 - '@types/cookie@0.6.0': {} - '@types/deep-eql@4.0.2': {} '@types/esrecurse@4.3.1': {} - '@types/estree@1.0.8': {} - '@types/estree@1.0.9': {} '@types/json-schema@7.0.15': {} @@ -3504,10 +3172,6 @@ snapshots: dependencies: '@types/node': 24.12.4 - '@types/resolve@1.20.2': {} - - '@types/trusted-types@2.0.7': {} - '@typescript-eslint/eslint-plugin@8.60.0(@typescript-eslint/parser@8.60.0(eslint@10.4.1)(typescript@6.0.3))(eslint@10.4.1)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -3660,6 +3324,8 @@ snapshots: acorn@8.16.0: {} + acorn@8.19.0: {} + ajv@6.15.0: dependencies: fast-deep-equal: 3.1.3 @@ -3683,7 +3349,7 @@ snapshots: balanced-match@4.0.4: {} - better-auth@1.7.14(@opentelemetry/api@1.9.1)(@sveltejs/kit@2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vitest@4.1.7): + better-auth@1.7.14(@opentelemetry/api@1.9.1)(@sveltejs/kit@3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vitest@4.1.7): dependencies: '@better-auth/core': 1.7.14(@better-auth/utils@0.5.1)(@better-fetch/fetch@1.3.3)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.7))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.5.5) '@better-auth/drizzle-adapter': 1.7.14(@better-auth/core@1.7.14(@better-auth/utils@0.5.1)(@better-fetch/fetch@1.3.3)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.7))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.5.5))(@better-auth/utils@0.5.1) @@ -3703,8 +3369,8 @@ snapshots: nanostores: 1.5.5 zod: 4.6.7 optionalDependencies: - '@sveltejs/kit': 2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) - svelte: 5.56.0(@typescript-eslint/types@8.60.0) + '@sveltejs/kit': 3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) + svelte: 5.57.3(@typescript-eslint/types@8.60.0) vitest: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) transitivePeerDependencies: - '@opentelemetry/api' @@ -3720,15 +3386,15 @@ snapshots: bintrees@1.0.2: {} - bits-ui@2.18.1(@internationalized/date@3.12.2)(@sveltejs/kit@2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0)): + bits-ui@2.18.1(@internationalized/date@3.12.2)(@sveltejs/kit@3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0)): dependencies: '@floating-ui/core': 1.7.5 '@floating-ui/dom': 1.7.6 '@internationalized/date': 3.12.2 esm-env: 1.2.2 - runed: 0.35.1(@sveltejs/kit@2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0)) - svelte: 5.56.0(@typescript-eslint/types@8.60.0) - svelte-toolbelt: 0.10.6(@sveltejs/kit@2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0)) + runed: 0.35.1(@sveltejs/kit@3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0)) + svelte: 5.57.3(@typescript-eslint/types@8.60.0) + svelte-toolbelt: 0.10.6(@sveltejs/kit@3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0)) tabbable: 6.4.0 transitivePeerDependencies: - '@sveltejs/kit' @@ -3749,15 +3415,13 @@ snapshots: colorette@2.0.20: {} - commondir@1.0.1: {} - confbox@0.1.8: {} confbox@0.2.4: {} convert-source-map@2.0.0: {} - cookie@0.6.0: {} + cookie@2.0.1: {} cron-parser@5.10.1: dependencies: @@ -3787,14 +3451,12 @@ snapshots: detect-libc@2.1.2: {} - devalue@5.8.1: {} + devalue@5.9.4: {} end-of-stream@1.4.5: dependencies: once: 1.4.0 - es-errors@1.3.0: {} - es-module-lexer@2.1.0: {} esbuild@0.25.0: @@ -3831,7 +3493,7 @@ snapshots: dependencies: eslint: 10.4.1 - eslint-plugin-svelte@3.18.0(eslint@10.4.1)(svelte@5.56.0(@typescript-eslint/types@8.60.0)): + eslint-plugin-svelte@3.18.0(eslint@10.4.1)(svelte@5.57.3(@typescript-eslint/types@8.60.0)): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1) '@jridgewell/sourcemap-codec': 1.5.5 @@ -3843,9 +3505,9 @@ snapshots: postcss-load-config: 3.1.4(postcss@8.5.23) postcss-safe-parser: 7.0.1(postcss@8.5.23) semver: 7.8.1 - svelte-eslint-parser: 1.6.1(svelte@5.56.0(@typescript-eslint/types@8.60.0)) + svelte-eslint-parser: 1.6.1(svelte@5.57.3(@typescript-eslint/types@8.60.0)) optionalDependencies: - svelte: 5.56.0(@typescript-eslint/types@8.60.0) + svelte: 5.57.3(@typescript-eslint/types@8.60.0) transitivePeerDependencies: - ts-node @@ -3920,7 +3582,7 @@ snapshots: dependencies: estraverse: 5.3.0 - esrap@2.2.9(@typescript-eslint/types@8.60.0): + esrap@2.4.0(@typescript-eslint/types@8.60.0): dependencies: '@jridgewell/sourcemap-codec': 1.5.5 optionalDependencies: @@ -3932,8 +3594,6 @@ snapshots: estraverse@5.3.0: {} - estree-walker@2.0.2: {} - estree-walker@3.0.3: dependencies: '@types/estree': 1.0.9 @@ -3992,8 +3652,6 @@ snapshots: fsevents@2.3.3: optional: true - function-bind@1.1.2: {} - glob-parent@6.0.2: dependencies: is-glob: 4.0.3 @@ -4006,10 +3664,6 @@ snapshots: has-flag@4.0.0: {} - hasown@2.0.4: - dependencies: - function-bind: 1.1.2 - help-me@5.0.0: {} html-escaper@2.0.2: {} @@ -4026,22 +3680,12 @@ snapshots: inline-style-parser@0.2.7: {} - is-core-module@2.16.2: - dependencies: - hasown: 2.0.4 - is-extglob@2.1.1: {} is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - is-module@1.0.0: {} - - is-reference@1.2.1: - dependencies: - '@types/estree': 1.0.9 - is-reference@3.0.3: dependencies: '@types/estree': 1.0.9 @@ -4081,8 +3725,6 @@ snapshots: dependencies: json-buffer: 3.0.1 - kleur@4.1.5: {} - known-css-properties@0.37.0: {} kysely@0.28.17: {} @@ -4168,6 +3810,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@1.4.5: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + magicast@0.5.3: dependencies: '@babel/parser': 7.29.7 @@ -4244,8 +3890,6 @@ snapshots: path-key@3.1.1: {} - path-parse@1.0.7: {} - pathe@2.0.3: {} picocolors@1.1.1: {} @@ -4339,10 +3983,10 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-svelte@3.5.2(prettier@3.8.3)(svelte@5.56.0(@typescript-eslint/types@8.60.0)): + prettier-plugin-svelte@3.5.2(prettier@3.8.3)(svelte@5.57.3(@typescript-eslint/types@8.60.0)): dependencies: prettier: 3.8.3 - svelte: 5.56.0(@typescript-eslint/types@8.60.0) + svelte: 5.57.3(@typescript-eslint/types@8.60.0) prettier@3.8.3: {} @@ -4370,13 +4014,6 @@ snapshots: real-require@1.0.0: {} - resolve@1.22.12: - dependencies: - es-errors: 1.3.0 - is-core-module: 2.16.2 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - rolldown@1.0.3: dependencies: '@oxc-project/types': 0.133.0 @@ -4398,47 +4035,16 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.3 '@rolldown/binding-win32-x64-msvc': 1.0.3 - rollup@4.60.4: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.4 - '@rollup/rollup-android-arm64': 4.60.4 - '@rollup/rollup-darwin-arm64': 4.60.4 - '@rollup/rollup-darwin-x64': 4.60.4 - '@rollup/rollup-freebsd-arm64': 4.60.4 - '@rollup/rollup-freebsd-x64': 4.60.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 - '@rollup/rollup-linux-arm-musleabihf': 4.60.4 - '@rollup/rollup-linux-arm64-gnu': 4.60.4 - '@rollup/rollup-linux-arm64-musl': 4.60.4 - '@rollup/rollup-linux-loong64-gnu': 4.60.4 - '@rollup/rollup-linux-loong64-musl': 4.60.4 - '@rollup/rollup-linux-ppc64-gnu': 4.60.4 - '@rollup/rollup-linux-ppc64-musl': 4.60.4 - '@rollup/rollup-linux-riscv64-gnu': 4.60.4 - '@rollup/rollup-linux-riscv64-musl': 4.60.4 - '@rollup/rollup-linux-s390x-gnu': 4.60.4 - '@rollup/rollup-linux-x64-gnu': 4.60.4 - '@rollup/rollup-linux-x64-musl': 4.60.4 - '@rollup/rollup-openbsd-x64': 4.60.4 - '@rollup/rollup-openharmony-arm64': 4.60.4 - '@rollup/rollup-win32-arm64-msvc': 4.60.4 - '@rollup/rollup-win32-ia32-msvc': 4.60.4 - '@rollup/rollup-win32-x64-gnu': 4.60.4 - '@rollup/rollup-win32-x64-msvc': 4.60.4 - fsevents: 2.3.3 - rou3@0.9.2: {} - runed@0.35.1(@sveltejs/kit@2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0)): + runed@0.35.1(@sveltejs/kit@3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0)): dependencies: dequal: 2.0.3 esm-env: 1.2.2 lz-string: 1.5.0 - svelte: 5.56.0(@typescript-eslint/types@8.60.0) + svelte: 5.57.3(@typescript-eslint/types@8.60.0) optionalDependencies: - '@sveltejs/kit': 2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) + '@sveltejs/kit': 3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)) sade@1.8.1: dependencies: @@ -4450,8 +4056,6 @@ snapshots: semver@7.8.1: {} - set-cookie-parser@3.1.0: {} - set-cookie-parser@3.2.1: {} shebang-command@2.0.0: @@ -4494,21 +4098,20 @@ snapshots: dependencies: has-flag: 4.0.0 - supports-preserve-symlinks-flag@1.0.0: {} - - svelte-check@4.4.8(picomatch@4.0.4)(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3): + svelte-check@4.7.7(picomatch@4.0.4)(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3): dependencies: '@jridgewell/trace-mapping': 0.3.31 + '@sveltejs/load-config': 0.2.3 chokidar: 4.0.3 fdir: 6.5.0(picomatch@4.0.4) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.56.0(@typescript-eslint/types@8.60.0) + svelte: 5.57.3(@typescript-eslint/types@8.60.0) typescript: 6.0.3 transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.6.1(svelte@5.56.0(@typescript-eslint/types@8.60.0)): + svelte-eslint-parser@1.6.1(svelte@5.57.3(@typescript-eslint/types@8.60.0)): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -4518,31 +4121,30 @@ snapshots: postcss-selector-parser: 7.1.1 semver: 7.8.1 optionalDependencies: - svelte: 5.56.0(@typescript-eslint/types@8.60.0) + svelte: 5.57.3(@typescript-eslint/types@8.60.0) - svelte-toolbelt@0.10.6(@sveltejs/kit@2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0)): + svelte-toolbelt@0.10.6(@sveltejs/kit@3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0)): dependencies: clsx: 2.1.1 - runed: 0.35.1(@sveltejs/kit@2.70.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.56.0(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.56.0(@typescript-eslint/types@8.60.0)) + runed: 0.35.1(@sveltejs/kit@3.1.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.57.3(@typescript-eslint/types@8.60.0))(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0))(typescript@6.0.3)(vite@8.0.16(@types/node@24.12.4)(yaml@2.9.0)))(svelte@5.57.3(@typescript-eslint/types@8.60.0)) style-to-object: 1.0.14 - svelte: 5.56.0(@typescript-eslint/types@8.60.0) + svelte: 5.57.3(@typescript-eslint/types@8.60.0) transitivePeerDependencies: - '@sveltejs/kit' - svelte@5.56.0(@typescript-eslint/types@8.60.0): + svelte@5.57.3(@typescript-eslint/types@8.60.0): dependencies: '@jridgewell/remapping': 2.3.5 - '@jridgewell/sourcemap-codec': 1.5.5 - '@sveltejs/acorn-typescript': 1.0.10(acorn@8.16.0) + '@jridgewell/sourcemap-codec': 1.6.0 + '@sveltejs/acorn-typescript': 1.0.13(acorn@8.19.0) '@types/estree': 1.0.9 - '@types/trusted-types': 2.0.7 - acorn: 8.16.0 + acorn: 8.19.0 aria-query: 5.3.1 axobject-query: 4.1.0 clsx: 2.1.1 - devalue: 5.8.1 + devalue: 5.9.4 esm-env: 1.2.2 - esrap: 2.2.9(@typescript-eslint/types@8.60.0) + esrap: 2.4.0(@typescript-eslint/types@8.60.0) is-reference: 3.0.3 locate-character: 3.0.0 magic-string: 0.30.21 @@ -4625,7 +4227,7 @@ snapshots: undici-types@7.16.0: {} - unplugin-icons@23.0.1(svelte@5.56.0(@typescript-eslint/types@8.60.0)): + unplugin-icons@23.0.1(svelte@5.57.3(@typescript-eslint/types@8.60.0)): dependencies: '@antfu/install-pkg': 1.1.0 '@iconify/utils': 3.1.3 @@ -4633,7 +4235,7 @@ snapshots: obug: 2.1.1 unplugin: 2.3.11 optionalDependencies: - svelte: 5.56.0(@typescript-eslint/types@8.60.0) + svelte: 5.57.3(@typescript-eslint/types@8.60.0) unplugin@2.3.11: dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 59680c04..30be4da5 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -45,3 +45,5 @@ minimumReleaseAgeExclude: - '@takumi-rs/helpers@2.2.0' - '@takumi-rs/wasm@2.2.0' - takumi-js@2.2.0 + - '@sveltejs/adapter-node@6.0.1' + - '@sveltejs/kit@3.1.1' -- 2.54.0 From 67869f804111f891d466495b23eb2e4776782732 Mon Sep 17 00:00:00 2001 From: eleith Date: Fri, 30 Oct 2026 07:27:34 -0700 Subject: [PATCH 3/3] refactor(web): finish SvelteKit 3 API cleanup Use refreshAll, explicit shallow goto with replacement/state and rejection handling, and native Response.json. Remove the resolved migration task report. --- apps/web/MIGRATION_TASKS.md | 122 ------------------ apps/web/src/lib/appointmentUrlSync.svelte.ts | 8 +- apps/web/src/lib/components/AdminNav.svelte | 2 +- .../(app)/appointment/[id]/+page.svelte | 4 +- apps/web/src/routes/schema.json/+server.ts | 3 +- apps/web/src/routes/signin/+page.svelte | 2 +- 6 files changed, 11 insertions(+), 130 deletions(-) delete mode 100644 apps/web/MIGRATION_TASKS.md diff --git a/apps/web/MIGRATION_TASKS.md b/apps/web/MIGRATION_TASKS.md deleted file mode 100644 index 1795cf46..00000000 --- a/apps/web/MIGRATION_TASKS.md +++ /dev/null @@ -1,122 +0,0 @@ - - -# SvelteKit 3 migration tasks - -Some migrations are uncommon, context-dependent, or disproportionately difficult to automate safely. This document lists them. - -The findings are intentionally broad and may include files that do not require changes. - -AI agents can work through the migration tasks below one at a time: - -1. Read the linked documentation or pull request before changing code. -2. Inspect every listed file and its surrounding context. -3. Ignore a finding when the file is not actually affected. -4. Make the smallest necessary change. Do not perform unrelated refactors or introduce unnecessary abstractions. -5. Ask the user when application intent cannot be inferred. -6. Run the project's appropriate checks after editing. - -Also search the project for `@migration-task` comments. They may describe additional manual migration work that must be resolved. - -## Migration tasks - -### Review `goto` destinations - -`goto(...)` now rejects destinations that do not resolve to an application route. - -#### What to do - -Confirm each destination is an internal route. Use `window.location.href` for external browser navigation, and handle rejected dynamic destinations where they can fail to resolve. - -#### References - -- [Migrating to SvelteKit v3](https://svelte.dev/docs/kit/migrating-to-sveltekit-3#$app-navigation-goto-rejects-for-URLs-that-don't-resolve-to-a-route) - -#### Files to review - -- [ ] `src/lib/components/AdminNav.svelte` -- [ ] `src/routes/signin/+page.svelte` - -### Replace `invalidateAll` with `refreshAll` - -`invalidateAll` is deprecated in favor of `refreshAll` - -#### What to do - -Replace `invalidateAll()` with `refreshAll()`. Note that `refreshAll()` will keep `page.state` intact. Check if that has unwanted impact on the application; if yes point this out in a comment with steps to take instead of replacing that instance of `invalidateAll()`. Similarly, replace goto(..., { invalidateAll: true }) with goto(..., { refreshAll: true }). - -#### References - -- [Migrating to SvelteKit v3](https://svelte.dev/docs/kit/migrating-to-sveltekit-3#$app-navigation-invalidateAll-is-deprecated-in-favour-of-refreshAll) - -#### Files to review - -- [ ] `src/lib/components/AdminNav.svelte` -- [ ] `src/routes/signin/+page.svelte` - -### Review enhanced forms with explicit actions - -Enhanced forms that submit to another page now navigate to that page. - -#### What to do - -Determine whether each action resolves to another page and confirm navigation is intended. If the form must remain on the current page, implement that behavior explicitly in the enhancement callback. - -#### References - -- [Migrating to SvelteKit v3](https://svelte.dev/docs/kit/migrating-to-sveltekit-3#$app-forms) - -#### Files to review - -- [ ] `src/lib/components/AppointmentActions.svelte` -- [ ] `src/lib/components/GuestForm.svelte` -- [ ] `src/routes/(app)/appointment/[id]/+page.svelte` -- [ ] `src/routes/(auth)/admin/health/+page.svelte` - -### CORS for static assets in development is handled by Vite - -SvelteKit no longer sets `access-control-allow-origin: *` on every static asset request in development. CORS is now delegated to Vite's built-in middleware. - -#### What to do - -If you rely on cross-origin access to static assets in dev, configure it in your Vite config by adding server.cors.origin = "\*" to your config. - -#### References - -- [Migrating to SvelteKit v3](https://svelte.dev/docs/kit/migrating-to-sveltekit-3#Security-CORS-for-static-assets-in-development-is-handled-by-Vite) - -### `json` and `text` are deprecated - -The `json(...)` and `text(...)` helpers from `@sveltejs/kit` for generating responses are deprecated. - -#### What to do - -Use `Response.json(...)` and `new Response(text)` instead. - -#### References - -- [Migrating to SvelteKit v3](https://svelte.dev/docs/kit/migrating-to-sveltekit-3#sveltejs-kit-json-and-text-are-deprecated) - -#### Files to review - -- [ ] `src/routes/metrics/+server.ts` -- [ ] `src/routes/schema.json/+server.ts` - -### Move adapter-node `ORIGIN` to `paths.origin` - -The adapter-node `ORIGIN` environment variable is removed. - -#### What to do - -Find where `ORIGIN` is set (`.env` files, scripts, hosting dashboard, ...) and move the public-facing origin to `paths.origin` in `sveltekit(...)`. Do not delete `ORIGIN`: it is ignored by adapter-node now and may have other uses. - -#### References - -- [Migrating to SvelteKit v3](https://svelte.dev/docs/kit/migrating-to-sveltekit-3#Adapters-adapter-node) - -## Final verification - -- [ ] Review every migration task and ignore any irrelevant findings. -- [ ] Resolve remaining `@migration-task` comments. -- [ ] Run the project's type checker and tests. -- [ ] Build the project successfully. -- [ ] Delete this file when all migration work is complete. diff --git a/apps/web/src/lib/appointmentUrlSync.svelte.ts b/apps/web/src/lib/appointmentUrlSync.svelte.ts index 8a0e32b7..54bcfc91 100644 --- a/apps/web/src/lib/appointmentUrlSync.svelte.ts +++ b/apps/web/src/lib/appointmentUrlSync.svelte.ts @@ -1,5 +1,5 @@ import { page } from '$app/state'; -import { replaceState, afterNavigate } from '$app/navigation'; +import { goto, afterNavigate } from '$app/navigation'; import { resolveDeepLink, desiredUrlState, @@ -69,7 +69,11 @@ export function createAppointmentUrlSync( // Shallow navigation changes page.shallow, not the last fully loaded page.url. const url = page.shallow?.url ?? page.url; if (urlStateMatches(url.searchParams, desired)) return; - void replaceState(`${url.pathname}${buildAppointmentSearch(desired)}`, page.state); + void goto(`${url.pathname}${buildAppointmentSearch(desired)}`, { + shallow: true, + replace: true, + state: page.state + }).catch((error) => console.error('Failed to synchronize booking URL', error)); }); return { diff --git a/apps/web/src/lib/components/AdminNav.svelte b/apps/web/src/lib/components/AdminNav.svelte index cdce8496..5e8fb471 100644 --- a/apps/web/src/lib/components/AdminNav.svelte +++ b/apps/web/src/lib/components/AdminNav.svelte @@ -32,7 +32,7 @@ signoutError = error.status === 429 ? 'rate' : 'auth'; return; } - await goto(redirectTo, { invalidateAll: true }); + await goto(redirectTo, { refreshAll: true }); } catch { signoutError = 'network'; } finally { diff --git a/apps/web/src/routes/(app)/appointment/[id]/+page.svelte b/apps/web/src/routes/(app)/appointment/[id]/+page.svelte index 4b820f91..a053ab49 100644 --- a/apps/web/src/routes/(app)/appointment/[id]/+page.svelte +++ b/apps/web/src/routes/(app)/appointment/[id]/+page.svelte @@ -1,7 +1,7 @@