diff --git a/.changeset/verify-svelte-browser-layer.md b/.changeset/verify-svelte-browser-layer.md new file mode 100644 index 0000000..4d6db51 --- /dev/null +++ b/.changeset/verify-svelte-browser-layer.md @@ -0,0 +1,5 @@ +--- +'seamless-cli': minor +--- + +`seamless verify` now drives a SvelteKit app through the same browser specs as the React template. The `svelte` and `svelte-dev` layers run the reference app in `verify/svelte-app` on `@seamless-auth/svelte` (SvelteKit 3 as a single-page app, as a production build and on `vite dev` with `--dev`), or a Svelte web template once the registry has one. `SEAMLESS_SVELTE_DIR` points the run at another Svelte app, and `--local` installs the locally built `@seamless-auth/client` and `@seamless-auth/svelte`. diff --git a/README.md b/README.md index 5e20ab4..95f23eb 100644 --- a/README.md +++ b/README.md @@ -415,14 +415,16 @@ their own Dockerfile's `runtime` target and driven by specs written for their ow Mobile templates are announced and skipped: the harness has no simulator to drive, so a native app is checked by running it against a `--keep-up` stack. -Angular and Vue run the same browser specs as React. `@seamless-auth/angular` and -`@seamless-auth/vue` keep the React screens' accessible names, so the `angular` and `vue` -Playwright projects point at the React specs and drive an app of that framework instead: a web -template whose `template.json` sets `verify.project` (or whose registry `framework` is) `angular` -or `vue`, or, until one exists, the reference app in [verify/angular-app](verify/angular-app) or -[verify/vue-app](verify/vue-app). `SEAMLESS_ANGULAR_DIR` and `SEAMLESS_VUE_DIR` point the run at -another app. With `--local`, the client and each binding are packed into `verify/angular-vendor` -and `verify/vue-vendor` and installed over the published ones. +Angular, Vue and Svelte run the same browser specs as React. `@seamless-auth/angular`, +`@seamless-auth/vue` and `@seamless-auth/svelte` keep the React screens' accessible names, so the +`angular`, `vue` and `svelte` Playwright projects point at the React specs and drive an app of that +framework instead: a web template whose `template.json` sets `verify.project` (or whose registry +`framework` is) `angular`, `vue` or `svelte`, or, until one exists, the reference app in +[verify/angular-app](verify/angular-app), [verify/vue-app](verify/vue-app) or +[verify/svelte-app](verify/svelte-app) (SvelteKit 3, as a single-page app). +`SEAMLESS_ANGULAR_DIR`, `SEAMLESS_VUE_DIR` and `SEAMLESS_SVELTE_DIR` point the run at another app. +With `--local`, the client and each binding are packed into that app's vendor directory and +installed over the published ones. `--adapter-url` holds a server adapter this repository does not build (Go, Rust, Python) to the same contract as the Express and Fastify adapters. It starts only Postgres and the @@ -431,7 +433,7 @@ the reference app must serve, and how it reaches the API, is in [verify/CONFORMANCE.md](verify/CONFORMANCE.md). `--dev` runs every browser template a second time on its development server (`vite`, -`ng serve`, or `next dev`). Production React runs each effect once; Strict Mode in development runs it +`ng serve`, `vite dev` for SvelteKit, or `next dev`). Production React runs each effect once; Strict Mode in development runs it twice, so an effect that is not idempotent (a single-use magic link verified twice, say) passes the production pass and fails this one, the way it fails on a developer's first `npm run dev`. The conformance workflow passes `--dev` on every pull request. diff --git a/src/commands/verify.test.ts b/src/commands/verify.test.ts index e6a3759..9ba8648 100644 --- a/src/commands/verify.test.ts +++ b/src/commands/verify.test.ts @@ -21,6 +21,10 @@ const ALL_PROFILES = [ "--profile", "vue-dev", "--profile", + "svelte", + "--profile", + "svelte-dev", + "--profile", "nextjs", "--profile", "nextjs-dev", @@ -126,7 +130,7 @@ describe("runVerify — published (default) mode", () => { await runVerify([]); // Stale tarballs are removed from every vendor dir; non-tgz files are left. - expect(fs.rmSync).toHaveBeenCalledTimes(5); + expect(fs.rmSync).toHaveBeenCalledTimes(6); const tails = dockerTails(); expect(tails).toContainEqual([...ALL_PROFILES, "down", "-v"]); // initial clean @@ -166,6 +170,8 @@ describe("runVerify — published (default) mode", () => { expect(npmTests).toContainEqual(["test", "--", "--project", "angular"]); expect(tails).toContainEqual(["--profile", "vue", "up", "-d", "--build", "vue"]); expect(npmTests).toContainEqual(["test", "--", "--project", "vue"]); + expect(tails).toContainEqual(["--profile", "svelte", "up", "-d", "--build", "svelte"]); + expect(npmTests).toContainEqual(["test", "--", "--project", "svelte"]); // A successful run does not exit non-zero. expect(exitSpy).not.toHaveBeenCalled(); @@ -329,6 +335,8 @@ describe("runVerify — flag parsing", () => { "angular-dev", "vue", "vue-dev", + "svelte", + "svelte-dev", "nextjs", "nextjs-dev", ]); @@ -338,6 +346,7 @@ describe("runVerify — flag parsing", () => { expect(out).toContain("Web (dev) · web-basic"); expect(out).toContain("Web (dev) · angular-reference"); expect(out).toContain("Web (dev) · vue-reference"); + expect(out).toContain("Web (dev) · svelte-reference"); expect(out).toContain("Full-stack (dev) · nextjs"); }); @@ -498,9 +507,9 @@ describe("runVerify — local mode", () => { }); it("packs the react SDK as a single package when the checkout has no workspaces", async () => { - // A checkout that predates the Angular and Vue packages has neither. + // A checkout that predates the Angular, Vue and Svelte packages has none of them. vi.mocked(fs.existsSync).mockImplementation( - (p: never) => !/packages\/(angular\/dist|vue)/.test(String(p)), + (p: never) => !/packages\/(angular\/dist|vue|svelte)/.test(String(p)), ); await runVerify(["--local"]); @@ -544,9 +553,24 @@ describe("runVerify — local mode", () => { ]); }); + it("packs the Svelte package and its client core for the Svelte app", async () => { + await runVerify(["--local"]); + + const packs = callsFor("npm").filter((a) => a[0] === "pack"); + expect(packs).toContainEqual([ + "pack", + "-w", + "@seamless-auth/client", + "-w", + "@seamless-auth/svelte", + "--pack-destination", + expect.stringContaining("svelte-vendor"), + ]); + }); + it("packs the client core alongside react when the checkout is a workspace", async () => { vi.mocked(fs.existsSync).mockImplementation( - (p: never) => !/packages\/(angular\/dist|vue)/.test(String(p)), + (p: never) => !/packages\/(angular\/dist|vue|svelte)/.test(String(p)), ); vi.mocked(fs.readFileSync).mockImplementation((p: never) => { const s = String(p); diff --git a/src/commands/verify.ts b/src/commands/verify.ts index d3de4c9..6c0c6a2 100644 --- a/src/commands/verify.ts +++ b/src/commands/verify.ts @@ -96,6 +96,7 @@ interface BrowserRuntime { | "SEAMLESS_REACT_DIR" | "SEAMLESS_ANGULAR_DIR" | "SEAMLESS_VUE_DIR" + | "SEAMLESS_SVELTE_DIR" | "SEAMLESS_FULLSTACK_DIR"; } @@ -123,12 +124,20 @@ const VUE_RUNTIME: BrowserRuntime = { dirEnv: "SEAMLESS_VUE_DIR", }; +const SVELTE_RUNTIME: BrowserRuntime = { + project: "svelte", + service: "svelte", + devService: "svelte-dev", + dirEnv: "SEAMLESS_SVELTE_DIR", +}; + // Web templates pick their runtime by verify.project, falling back to the // framework, and then to React, which is what every web template was before. const WEB_RUNTIMES: Record = { react: WEB_RUNTIME, angular: ANGULAR_RUNTIME, vue: VUE_RUNTIME, + svelte: SVELTE_RUNTIME, }; // The reference apps in this repo, one per binding without a web template yet @@ -138,6 +147,7 @@ const WEB_RUNTIMES: Record = { const REFERENCE_APPS: Array<{ id: string; runtime: BrowserRuntime; dir: string }> = [ { id: "angular-reference", runtime: ANGULAR_RUNTIME, dir: path.join(VERIFY_DIR, "angular-app") }, { id: "vue-reference", runtime: VUE_RUNTIME, dir: path.join(VERIFY_DIR, "vue-app") }, + { id: "svelte-reference", runtime: SVELTE_RUNTIME, dir: path.join(VERIFY_DIR, "svelte-app") }, ]; // Full-stack templates render their own screens, so each framework has its own @@ -292,6 +302,7 @@ const FASTIFY_VENDOR_DIR = path.join(VERIFY_DIR, "adapter-fastify-app", "vendor" const REACT_VENDOR_DIR = path.join(VERIFY_DIR, "react-vendor"); const ANGULAR_VENDOR_DIR = path.join(VERIFY_DIR, "angular-vendor"); const VUE_VENDOR_DIR = path.join(VERIFY_DIR, "vue-vendor"); +const SVELTE_VENDOR_DIR = path.join(VERIFY_DIR, "svelte-vendor"); // The React client SDK (@seamless-auth/react). Defaults to a sibling checkout; // override with SEAMLESS_REACT_SDK_DIR. Only needed for --local browser runs. @@ -329,6 +340,7 @@ function cleanVendor(): void { REACT_VENDOR_DIR, ANGULAR_VENDOR_DIR, VUE_VENDOR_DIR, + SVELTE_VENDOR_DIR, ]) { for (const f of fs.readdirSync(dir)) { if (f.endsWith(".tgz")) fs.rmSync(path.join(dir, f)); @@ -352,7 +364,9 @@ function reactSdkWorkspaces(sdkDir: string): string[] { // over the published version (--local browser runs). async function packLocalReactSdk(env: NodeJS.ProcessEnv): Promise { const sdkDir = resolveReactSdkDir(); - console.log(kleur.cyan("→ Building & packing the local client SDKs (react, angular, vue)…")); + console.log( + kleur.cyan("→ Building & packing the local client SDKs (react, angular, vue, svelte)…"), + ); await runCommand("npm", ["run", "build"], sdkDir, env); const workspaceArgs = reactSdkWorkspaces(sdkDir).flatMap((pkg) => ["-w", pkg]); await runCommand( @@ -380,8 +394,12 @@ async function packLocalReactSdk(env: NodeJS.ProcessEnv): Promise { ); } - // @seamless-auth/vue publishes its own directory, like react. - if (fs.existsSync(path.join(sdkDir, "packages", "vue", "package.json"))) { + // @seamless-auth/vue and /svelte publish their own directories, like react. + for (const [binding, vendorDir] of [ + ["vue", VUE_VENDOR_DIR], + ["svelte", SVELTE_VENDOR_DIR], + ] as const) { + if (!fs.existsSync(path.join(sdkDir, "packages", binding, "package.json"))) continue; await runCommand( "npm", [ @@ -389,9 +407,9 @@ async function packLocalReactSdk(env: NodeJS.ProcessEnv): Promise { "-w", "@seamless-auth/client", "-w", - "@seamless-auth/vue", + `@seamless-auth/${binding}`, "--pack-destination", - VUE_VENDOR_DIR, + vendorDir, ], sdkDir, env, @@ -517,7 +535,7 @@ function collectPackageVersions( ? path.join(sdkDir, "packages", "react", "package.json") : path.join(sdkDir, "package.json"); push("@seamless-auth/react", readPkgVersion(reactPkg)); - for (const binding of ["angular", "vue"]) { + for (const binding of ["angular", "vue", "svelte"]) { const pkg = path.join(sdkDir, "packages", binding, "package.json"); if (fs.existsSync(pkg)) push(`@seamless-auth/${binding}`, readPkgVersion(pkg)); } @@ -546,7 +564,7 @@ function collectPackageVersions( for (const pin of reactPins) push("@seamless-auth/react", pin); } - // A full-stack, Angular, or Vue template builds from its own lockfile in both + // A full-stack, Angular, Vue, or Svelte template builds from its own lockfile in both // modes, so its SDK is always the version it pins. A reference app pins // nothing: it installs the published package unless --local packed one. for (const tmpl of webTemplates.filter((t) => t.runtime !== WEB_RUNTIME)) { diff --git a/verify/docker-compose.cache.yml b/verify/docker-compose.cache.yml index 8058dba..8630d47 100644 --- a/verify/docker-compose.cache.yml +++ b/verify/docker-compose.cache.yml @@ -92,3 +92,17 @@ services: - type=gha,scope=verify-vue-dev-${SEAMLESS_VERIFY_TEMPLATE_ID:-default} cache_to: - type=gha,mode=max,scope=verify-vue-dev-${SEAMLESS_VERIFY_TEMPLATE_ID:-default} + + svelte: + build: + cache_from: + - type=gha,scope=verify-svelte-${SEAMLESS_VERIFY_TEMPLATE_ID:-default} + cache_to: + - type=gha,mode=max,scope=verify-svelte-${SEAMLESS_VERIFY_TEMPLATE_ID:-default} + + svelte-dev: + build: + cache_from: + - type=gha,scope=verify-svelte-dev-${SEAMLESS_VERIFY_TEMPLATE_ID:-default} + cache_to: + - type=gha,mode=max,scope=verify-svelte-dev-${SEAMLESS_VERIFY_TEMPLATE_ID:-default} diff --git a/verify/docker-compose.verify.yml b/verify/docker-compose.verify.yml index 358f013..5072bc4 100644 --- a/verify/docker-compose.verify.yml +++ b/verify/docker-compose.verify.yml @@ -15,6 +15,8 @@ # angular-dev profiles); defaults to ./angular-app # SEAMLESS_VUE_DIR absolute path to the Vue app to serve (vue and vue-dev # profiles); defaults to ./vue-app +# SEAMLESS_SVELTE_DIR absolute path to the Svelte app to serve (svelte and +# svelte-dev profiles); defaults to ./svelte-app # API_SERVICE_TOKEN shared secret between the API and both adapters # JWKS_KID key id the adapters expect (must match the API's active kid) # OWNER_EMAIL tenant owner; this email gets the admin role at signup @@ -339,6 +341,49 @@ services: timeout: 3s retries: 40 + # A SvelteKit app on @seamless-auth/svelte, driven by the same browser specs as + # the React template. Built like the Vue app, with the client and Svelte + # tarballs a --local run packs into ./svelte-vendor. + svelte: + profiles: ['svelte'] + build: + context: ${SEAMLESS_SVELTE_DIR:-./svelte-app} + additional_contexts: + sdk: ./svelte-vendor + target: runtime + ports: + - '5173:80' + environment: + API_URL: http://localhost:3000 + depends_on: + adapter: + condition: service_healthy + healthcheck: + test: ['CMD', 'wget', '--no-verbose', '--tries=1', '--spider', 'http://localhost/health'] + interval: 3s + timeout: 3s + retries: 20 + + # The same app on `vite dev` (the Dockerfile's `dev` target). It reads the API + # origin from static/config.js, which already points at localhost:3000. + svelte-dev: + profiles: ['svelte-dev'] + build: + context: ${SEAMLESS_SVELTE_DIR:-./svelte-app} + additional_contexts: + sdk: ./svelte-vendor + target: dev + ports: + - '5173:5173' + depends_on: + adapter: + condition: service_healthy + healthcheck: + test: ['CMD', 'node', '-e', "fetch('http://localhost:5173/').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"] + interval: 3s + timeout: 3s + retries: 40 + # A full-stack template (the Next.js starter) built with its own Dockerfile's # `runtime` target: the standalone production server, on port 80 with /health. # It serves /auth itself, so it talks to the auth API directly and needs no diff --git a/verify/harness/lib/matrixReporter.ts b/verify/harness/lib/matrixReporter.ts index 6b86d75..b515c58 100644 --- a/verify/harness/lib/matrixReporter.ts +++ b/verify/harness/lib/matrixReporter.ts @@ -14,6 +14,8 @@ const LAYERS = [ 'angular-dev', 'vue', 'vue-dev', + 'svelte', + 'svelte-dev', 'nextjs', 'nextjs-dev', ] as const; diff --git a/verify/harness/playwright.config.ts b/verify/harness/playwright.config.ts index 21a8b82..af1ef2b 100644 --- a/verify/harness/playwright.config.ts +++ b/verify/harness/playwright.config.ts @@ -65,6 +65,10 @@ export default defineConfig({ // on `vite`. { name: 'vue', testDir: './react', use: { ...browser, baseURL: REACT_URL } }, { name: 'vue-dev', testDir: './react', use: { ...browser, baseURL: REACT_URL } }, + // And against a SvelteKit app on @seamless-auth/svelte; its dev pass runs on + // `vite dev`. + { name: 'svelte', testDir: './react', use: { ...browser, baseURL: REACT_URL } }, + { name: 'svelte-dev', testDir: './react', use: { ...browser, baseURL: REACT_URL } }, // The Next.js full-stack starter renders its own screens, so it has its own // specs; its dev pass runs them on `next dev`. { name: 'nextjs', testDir: './nextjs', use: { ...browser, baseURL: REACT_URL } }, diff --git a/verify/svelte-app/.dockerignore b/verify/svelte-app/.dockerignore new file mode 100644 index 0000000..e8422de --- /dev/null +++ b/verify/svelte-app/.dockerignore @@ -0,0 +1,3 @@ +node_modules +build +.svelte-kit diff --git a/verify/svelte-app/.gitignore b/verify/svelte-app/.gitignore new file mode 100644 index 0000000..18c6b9e --- /dev/null +++ b/verify/svelte-app/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +build/ +.svelte-kit/ diff --git a/verify/svelte-app/Dockerfile b/verify/svelte-app/Dockerfile new file mode 100644 index 0000000..2e04684 --- /dev/null +++ b/verify/svelte-app/Dockerfile @@ -0,0 +1,30 @@ +# The verify harness builds this image with an `sdk` build context: verify/svelte-vendor, +# which holds local @seamless-auth/client and @seamless-auth/svelte tarballs on a --local +# run and nothing otherwise. Without them, the published @seamless-auth/svelte is used. +FROM node:24-slim AS deps +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm ci +COPY --from=sdk . /tmp/sdk/ +ARG SEAMLESS_SVELTE_VERSION=latest +RUN if ls /tmp/sdk/*.tgz >/dev/null 2>&1; then \ + npm install --no-save /tmp/sdk/*.tgz; \ + else \ + npm install --no-save "@seamless-auth/svelte@${SEAMLESS_SVELTE_VERSION}"; \ + fi +COPY . . + +FROM deps AS dev +EXPOSE 5173 +CMD ["npm", "run", "dev"] + +FROM deps AS builder +RUN npm run build + +FROM nginx:alpine AS runtime +COPY nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=builder /app/build /usr/share/nginx/html +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh +EXPOSE 80 +CMD ["/entrypoint.sh"] diff --git a/verify/svelte-app/entrypoint.sh b/verify/svelte-app/entrypoint.sh new file mode 100755 index 0000000..4adb965 --- /dev/null +++ b/verify/svelte-app/entrypoint.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -e +cat < /usr/share/nginx/html/config.js +window.__SEAMLESS_CONFIG__ = { API_URL: "${API_URL}" }; +CONFIG +exec nginx -g "daemon off;" diff --git a/verify/svelte-app/nginx.conf b/verify/svelte-app/nginx.conf new file mode 100644 index 0000000..b46272f --- /dev/null +++ b/verify/svelte-app/nginx.conf @@ -0,0 +1,17 @@ +server { + listen 80; + root /usr/share/nginx/html; + + location = /health { + access_log off; + return 200 "ok"; + } + + location = /config.js { + add_header Cache-Control "no-store"; + } + + location / { + try_files $uri /index.html; + } +} diff --git a/verify/svelte-app/package-lock.json b/verify/svelte-app/package-lock.json new file mode 100644 index 0000000..5e11088 --- /dev/null +++ b/verify/svelte-app/package-lock.json @@ -0,0 +1,1233 @@ +{ + "name": "seamless-verify-svelte-app", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "seamless-verify-svelte-app", + "devDependencies": { + "@sveltejs/adapter-static": "^4.0.0", + "@sveltejs/kit": "^3.0.0", + "@sveltejs/vite-plugin-svelte": "^7.0.0", + "svelte": "^5.57.0", + "typescript": "~6.0.0", + "vite": "^8.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.153.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.153.0.tgz", + "integrity": "sha512-jSNrRIyvPVLL5E1z/tS5zLAprosGz/FuI1PWwEOz59j3E4TTTzSpqKb/RDGqJhhW0QHYISGXxq582wGx6T11Tw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.13.tgz", + "integrity": "sha512-Vu/NICrgdRvUOeaJZIyB2FP63s6fO/4ud5l8dXmxDx9yDyn+mN0y+gsvsVviSli+T361Aqo0h46EuMoobrwawA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.13.tgz", + "integrity": "sha512-6LEoIrGy5vvCd2boNnv2soPSUZj/PRvhp8R/t9KlX+mIZxThIE/ZqxrGXxmuNX0FuvQFvLdZr7S4HrYpYBVhEQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.13.tgz", + "integrity": "sha512-CaJSRzlQ6Q+zkDMVA9OkVxBjVoPRCDEE3v0FSJ9kIQBgRjFApA3Si4ijhbNVUji7ZJt+PfO0e46qy4nPInHUPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.13.tgz", + "integrity": "sha512-e4r340I5hxSzJkD3YJBxgzq/rJ3wwxwdLLb2FPt1Zpyem20nrQPT11DDEEkazwxaHumH8wpglsp/Ozgj/wT6mw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.13.tgz", + "integrity": "sha512-hoBWDZ4/K/mJKVMbsgUd1jfpA2DiOrJ54mpegObU9TBHBBrtX4FLIXJJQRDPZ/2Dn91GvPob+Z2hwKJzf4E5SQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.13.tgz", + "integrity": "sha512-oF9fZu3vTWnTiVAkDFxU9PJLt1nh20K9RRpuHsR7ZnE2L7XookBbDBVLojCVSLGbvtSlxeUNnjAj6DbNsKyzbg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.13.tgz", + "integrity": "sha512-DTpb/+jMiqWMPgphn4ksW1zW+XLJ6dJJ9FMvnIk9I291LhCctMPhMYJrP5t9p6C9qa3KXadDdUEZHBaPh3kNxQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.13.tgz", + "integrity": "sha512-xU+Kvv9N2A3SY35zFh1FWWNjxbadE/BKeqnkXe7vScU4GZsw757BlVmDLITZEq8DPpk6m7uoDYkK7P+x/uU5Ow==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.13.tgz", + "integrity": "sha512-XMk/hnhh25oQ756Lclb1Q11h4ll0xC0Esa5w4Vzp+mAE2S3AGJgeM0SonrIgY8fHhjarb6hcoTuwoFG0VVP2ig==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.13.tgz", + "integrity": "sha512-U1BoTHYmlywE2n3HUWjzZ+8EQsKr+OwpxYuDWaubx42tUL8QSL7nOqRz/NVHanibbFP3M1Rxuprz/wNcbMKjqw==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.13.tgz", + "integrity": "sha512-J4cm80Pc6wEwV5AZ42o62sIQgDk+Y7R2s646jIwuvO+4V46QB58N4vVuMPWCBaNgursXLpmUWJV//WQAkPvHBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.13.tgz", + "integrity": "sha512-W0euZS40U4V6JkmEnVCIX9mcsL6cbXQ4X8c2w+MMOIjFg68TXUW+u3RT+2e1t1pv9mg/EP3pDtK3POXdQ7Rxyw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.13.tgz", + "integrity": "sha512-do/AF/4n9MRshia3a5aXoy8xM2c6mgfT6D7H/dY6my5z+hfCIR4ab7mk4IRj++nsEQpKy39kd0DQnDq+r692tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.13.tgz", + "integrity": "sha512-6FtUf2cJZobutJdxnGYX8z0vtbgqU0b2v8vfBhkXb9wp2MppMFtkunE+IaOntyi01rkIQoPW2GHABtfzsC0BRQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.13.tgz", + "integrity": "sha512-UKhFaZTeTcbKrb3iU82m17jVcPEAoqDkCN5MBqgPyZSwp/cQmib21crTS0DdH7T1B7wZRWEI89YQAOJMet5yhg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sveltejs/acorn-typescript": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.13.tgz", + "integrity": "sha512-wgKggnhZVL9Bfx1OaKKTrYY9BFRk6C8UAkQNUcIv1+llzYrIqy+RZm5HPKzn0NpEBvTVhTqB4kQyllZywsRBRQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8.9.0" + } + }, + "node_modules/@sveltejs/adapter-static": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-4.0.0.tgz", + "integrity": "sha512-aF1J23R1ebKqUxQ4/qLr/Lxu63NFmLAtg8UZl3HFLxaoA1D/nhTVGcD9lTqx65iUbjNR2iOL0TgOxSX82x6Paw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@sveltejs/kit": "^3.0.0-next.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-3.0.1.tgz", + "integrity": "sha512-8JMCCq7ZUJELi3hbhb0+c9Rs8qnbHW90vhOfM+t1FSF4fhIpG9/FOsH4IYgcITMhbdkSrrn+Kvd9G+q8A+UO6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.1", + "@standard-schema/spec": "^1.1.0", + "cookie": "^2.0.1", + "devalue": "^5.9.4", + "esm-env": "^1.2.2", + "magic-string": "^1.2.3", + "mrmime": "^2.0.1", + "sirv": "^3.0.2" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=22.17" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0", + "@sveltejs/vite-plugin-svelte": "^7.0.0", + "svelte": "^5.57.1", + "typescript": "^6.0.0", + "vite": "^8.0.12" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-7.3.1.tgz", + "integrity": "sha512-ZPsLN8B1e/En+Ak5s4V7srFDT532oS0qieLsQwu63NGKsS+iAjoO2Js1BochlHlglcU+Pt7WAO3C5Ee+4f6gVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "deepmerge": "^4.3.1", + "magic-string": "^1.0.0", + "obug": "^2.1.0", + "vitefu": "^1.1.2" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "peerDependencies": { + "svelte": "^5.46.4", + "vite": "^8.0.0-beta.7 || ^8.0.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", + "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aria-query": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cookie": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-2.0.1.tgz", + "integrity": "sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/devalue": { + "version": "5.9.4", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.4.tgz", + "integrity": "sha512-sPAT4pztbu6586/hrhOnMKS17IJrvg12mXiSPSS3W5qDeN2RGgvZ0diZCm31dBbnevfVmujNO3IM2wrS4Y2Rhg==", + "dev": true, + "license": "MIT" + }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esrap": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.4.0.tgz", + "integrity": "sha512-CQPcneEHw/czj32uwQC52nYnax8H4SXt25FCM+LIwGZ49cMIxpOj3bP8wmzcI+Z0HIy5KkClaPhRLfCySzwHPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "peerDependencies": { + "@typescript-eslint/types": "^8.2.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/types": { + "optional": true + } + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.3.tgz", + "integrity": "sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.6.0" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/nanoid": { + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/obug": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.2.1.tgz", + "integrity": "sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.29.tgz", + "integrity": "sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.19", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rolldown": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.13.tgz", + "integrity": "sha512-/5apOkwWxtACcQtZ5WlrAsKS4JwXVThQPJZ3RqIruRY9UG9M8e0VlXN068xum/JRKA4aIUoJ13ghe/kGCvidiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.153.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.13", + "@rolldown/binding-android-arm64": "1.2.13", + "@rolldown/binding-darwin-arm64": "1.2.13", + "@rolldown/binding-darwin-x64": "1.2.13", + "@rolldown/binding-freebsd-x64": "1.2.13", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.13", + "@rolldown/binding-linux-arm64-gnu": "1.2.13", + "@rolldown/binding-linux-arm64-musl": "1.2.13", + "@rolldown/binding-linux-ppc64-gnu": "1.2.13", + "@rolldown/binding-linux-s390x-gnu": "1.2.13", + "@rolldown/binding-linux-x64-gnu": "1.2.13", + "@rolldown/binding-linux-x64-musl": "1.2.13", + "@rolldown/binding-openharmony-arm64": "1.2.13", + "@rolldown/binding-win32-arm64-msvc": "1.2.13", + "@rolldown/binding-win32-x64-msvc": "1.2.13" + } + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/svelte": { + "version": "5.57.2", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.57.2.tgz", + "integrity": "sha512-1YiPCAXT0Ct6g1vOMmSLa0Nsc3QRMvtDF32ihgglGVrugIuIK38RyDiFNXVDhtQ81TJjSO57NdMw6DyYLqSGDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "@jridgewell/sourcemap-codec": "^1.6.0", + "@sveltejs/acorn-typescript": "^1.0.13", + "@types/estree": "^1.0.9", + "acorn": "^8.18.0", + "aria-query": "5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "devalue": "^5.9.2", + "esm-env": "^1.2.1", + "esrap": "^2.3.6", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/svelte/node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.4.tgz", + "integrity": "sha512-IftLE8phJhdNRIGNEV4JCCvfNScoZQVfcXaN8TQropWGJtOHcu+iAB9pHcuGvmEb/kddw0LBe/jS8ztdC6xdiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.7", + "postcss": "^8.5.29", + "rolldown": "~1.2.12", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.7.1", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz", + "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==", + "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/zimmerframe": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.5.tgz", + "integrity": "sha512-msJxIvYDYcoNL+PJsu+7qmpDWsYmAxTY+2TNYXXF0hzBzBk0BMecOqDOG/EckUoKCuKwObfbugIl8QpqHDXeFA==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/verify/svelte-app/package.json b/verify/svelte-app/package.json new file mode 100644 index 0000000..60be69d --- /dev/null +++ b/verify/svelte-app/package.json @@ -0,0 +1,21 @@ +{ + "name": "seamless-verify-svelte-app", + "private": true, + "description": "Reference SvelteKit app the verify harness drives through @seamless-auth/svelte.", + "type": "module", + "scripts": { + "build": "vite build", + "dev": "vite dev --host 0.0.0.0 --port 5173 --strictPort" + }, + "devDependencies": { + "@sveltejs/adapter-static": "^4.0.0", + "@sveltejs/kit": "^3.0.0", + "@sveltejs/vite-plugin-svelte": "^7.0.0", + "svelte": "^5.57.0", + "typescript": "~6.0.0", + "vite": "^8.0.0" + }, + "imports": { + "#lib/*": "./src/lib/*.ts" + } +} diff --git a/verify/svelte-app/src/app.d.ts b/verify/svelte-app/src/app.d.ts new file mode 100644 index 0000000..de080fd --- /dev/null +++ b/verify/svelte-app/src/app.d.ts @@ -0,0 +1,7 @@ +declare global { + interface Window { + __SEAMLESS_CONFIG__?: { API_URL?: string }; + } +} + +export {}; diff --git a/verify/svelte-app/src/app.html b/verify/svelte-app/src/app.html new file mode 100644 index 0000000..cb82e9b --- /dev/null +++ b/verify/svelte-app/src/app.html @@ -0,0 +1,14 @@ + + + + + + Seamless Auth verify (Svelte) + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/verify/svelte-app/src/lib/auth.ts b/verify/svelte-app/src/lib/auth.ts new file mode 100644 index 0000000..60977d3 --- /dev/null +++ b/verify/svelte-app/src/lib/auth.ts @@ -0,0 +1,10 @@ +import { createSeamlessAuth } from '@seamless-auth/svelte'; + +// The app renders only in the browser (ssr = false in the root layout), so one +// session for the module is one session for the visitor. The adapter origin is +// read at runtime, so one image serves any stack. +export const auth = createSeamlessAuth({ + apiHost: + (typeof window !== 'undefined' && window.__SEAMLESS_CONFIG__?.API_URL) || + 'http://localhost:3000', +}); diff --git a/verify/svelte-app/src/routes/+layout.svelte b/verify/svelte-app/src/routes/+layout.svelte new file mode 100644 index 0000000..f83988d --- /dev/null +++ b/verify/svelte-app/src/routes/+layout.svelte @@ -0,0 +1,13 @@ + + +{@render children()} diff --git a/verify/svelte-app/src/routes/+layout.ts b/verify/svelte-app/src/routes/+layout.ts new file mode 100644 index 0000000..83addb7 --- /dev/null +++ b/verify/svelte-app/src/routes/+layout.ts @@ -0,0 +1,2 @@ +export const ssr = false; +export const prerender = false; diff --git a/verify/svelte-app/src/routes/+page.svelte b/verify/svelte-app/src/routes/+page.svelte new file mode 100644 index 0000000..3dacfd3 --- /dev/null +++ b/verify/svelte-app/src/routes/+page.svelte @@ -0,0 +1,36 @@ + + +
+ + {#if menuOpen} +
+ +
+ {/if} +
+
+

You are signed in

+

Signed in as {identity}.

+
diff --git a/verify/svelte-app/src/routes/+page.ts b/verify/svelte-app/src/routes/+page.ts new file mode 100644 index 0000000..6d40932 --- /dev/null +++ b/verify/svelte-app/src/routes/+page.ts @@ -0,0 +1,5 @@ +import { requireAuth } from '@seamless-auth/svelte/kit'; + +import { auth } from '#lib/auth'; + +export const load = requireAuth(auth); diff --git a/verify/svelte-app/src/routes/health/+server.ts b/verify/svelte-app/src/routes/health/+server.ts new file mode 100644 index 0000000..6c0e4f5 --- /dev/null +++ b/verify/svelte-app/src/routes/health/+server.ts @@ -0,0 +1,7 @@ +// The harness waits on /health before it runs. nginx answers it in the +// production image; this answers it on `vite dev`, which has no fallback page. +export const prerender = true; + +export function GET() { + return new Response('ok'); +} diff --git a/verify/svelte-app/src/routes/login/+page.svelte b/verify/svelte-app/src/routes/login/+page.svelte new file mode 100644 index 0000000..2a0ebe3 --- /dev/null +++ b/verify/svelte-app/src/routes/login/+page.svelte @@ -0,0 +1,5 @@ + + + diff --git a/verify/svelte-app/src/routes/login/+page.ts b/verify/svelte-app/src/routes/login/+page.ts new file mode 100644 index 0000000..07f0f91 --- /dev/null +++ b/verify/svelte-app/src/routes/login/+page.ts @@ -0,0 +1,5 @@ +import { requireGuest } from '@seamless-auth/svelte/kit'; + +import { auth } from '#lib/auth'; + +export const load = requireGuest(auth); diff --git a/verify/svelte-app/src/routes/magic-link-sent/+page.svelte b/verify/svelte-app/src/routes/magic-link-sent/+page.svelte new file mode 100644 index 0000000..09bb905 --- /dev/null +++ b/verify/svelte-app/src/routes/magic-link-sent/+page.svelte @@ -0,0 +1,5 @@ + + + diff --git a/verify/svelte-app/src/routes/magic-link-sent/+page.ts b/verify/svelte-app/src/routes/magic-link-sent/+page.ts new file mode 100644 index 0000000..07f0f91 --- /dev/null +++ b/verify/svelte-app/src/routes/magic-link-sent/+page.ts @@ -0,0 +1,5 @@ +import { requireGuest } from '@seamless-auth/svelte/kit'; + +import { auth } from '#lib/auth'; + +export const load = requireGuest(auth); diff --git a/verify/svelte-app/src/routes/oauth/callback/+page.svelte b/verify/svelte-app/src/routes/oauth/callback/+page.svelte new file mode 100644 index 0000000..9d68af2 --- /dev/null +++ b/verify/svelte-app/src/routes/oauth/callback/+page.svelte @@ -0,0 +1,5 @@ + + + diff --git a/verify/svelte-app/src/routes/passkey-login/+page.svelte b/verify/svelte-app/src/routes/passkey-login/+page.svelte new file mode 100644 index 0000000..743887a --- /dev/null +++ b/verify/svelte-app/src/routes/passkey-login/+page.svelte @@ -0,0 +1,5 @@ + + + diff --git a/verify/svelte-app/src/routes/passkey-login/+page.ts b/verify/svelte-app/src/routes/passkey-login/+page.ts new file mode 100644 index 0000000..07f0f91 --- /dev/null +++ b/verify/svelte-app/src/routes/passkey-login/+page.ts @@ -0,0 +1,5 @@ +import { requireGuest } from '@seamless-auth/svelte/kit'; + +import { auth } from '#lib/auth'; + +export const load = requireGuest(auth); diff --git a/verify/svelte-app/src/routes/register-passkey/+page.svelte b/verify/svelte-app/src/routes/register-passkey/+page.svelte new file mode 100644 index 0000000..8fced0c --- /dev/null +++ b/verify/svelte-app/src/routes/register-passkey/+page.svelte @@ -0,0 +1,5 @@ + + + diff --git a/verify/svelte-app/src/routes/verify-email-otp/+page.svelte b/verify/svelte-app/src/routes/verify-email-otp/+page.svelte new file mode 100644 index 0000000..e70a9f3 --- /dev/null +++ b/verify/svelte-app/src/routes/verify-email-otp/+page.svelte @@ -0,0 +1,5 @@ + + + diff --git a/verify/svelte-app/src/routes/verify-magiclink/+page.svelte b/verify/svelte-app/src/routes/verify-magiclink/+page.svelte new file mode 100644 index 0000000..639b81f --- /dev/null +++ b/verify/svelte-app/src/routes/verify-magiclink/+page.svelte @@ -0,0 +1,5 @@ + + + diff --git a/verify/svelte-app/src/routes/verify-phone-otp/+page.svelte b/verify/svelte-app/src/routes/verify-phone-otp/+page.svelte new file mode 100644 index 0000000..9e65fb1 --- /dev/null +++ b/verify/svelte-app/src/routes/verify-phone-otp/+page.svelte @@ -0,0 +1,5 @@ + + + diff --git a/verify/svelte-app/static/config.js b/verify/svelte-app/static/config.js new file mode 100644 index 0000000..306b771 --- /dev/null +++ b/verify/svelte-app/static/config.js @@ -0,0 +1 @@ +window.__SEAMLESS_CONFIG__ = { API_URL: 'http://localhost:3000' }; diff --git a/verify/svelte-app/tsconfig.json b/verify/svelte-app/tsconfig.json new file mode 100644 index 0000000..079ee0b --- /dev/null +++ b/verify/svelte-app/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "$app/tsconfig", + "compilerOptions": { + "strict": true, + "skipLibCheck": true + }, + "include": ["src", "*"] +} diff --git a/verify/svelte-app/vite.config.ts b/verify/svelte-app/vite.config.ts new file mode 100644 index 0000000..16c70be --- /dev/null +++ b/verify/svelte-app/vite.config.ts @@ -0,0 +1,13 @@ +import adapter from '@sveltejs/adapter-static'; +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [ + sveltekit({ + // A single-page app: the session lives in the browser, and nginx serves + // index.html for every route the build did not write. + adapter: adapter({ fallback: 'index.html' }), + }), + ], +}); diff --git a/verify/svelte-vendor/.gitignore b/verify/svelte-vendor/.gitignore new file mode 100644 index 0000000..aa1ec1e --- /dev/null +++ b/verify/svelte-vendor/.gitignore @@ -0,0 +1 @@ +*.tgz diff --git a/verify/svelte-vendor/.gitkeep b/verify/svelte-vendor/.gitkeep new file mode 100644 index 0000000..e69de29