From 5d81c957d6b46279b98dc4e71a0a29cff419020a Mon Sep 17 00:00:00 2001 From: Stanislav Khromov Date: Sat, 19 Jul 2025 15:24:15 +0200 Subject: [PATCH 1/9] Add allowedOrigins option to CSRF config Introduces a new `allowedOrigins` array to the CSRF configuration, allowing trusted third-party origins to bypass CSRF origin checks for form submissions. Updates server logic to permit requests from these origins, extends type definitions and documentation, and adds comprehensive tests to verify correct behavior for allowed, blocked, and edge-case origins. --- packages/kit/src/core/config/index.spec.js | 3 +- packages/kit/src/core/config/options.js | 3 +- packages/kit/src/core/sync/write_server.js | 1 + packages/kit/src/exports/public.d.ts | 11 ++ packages/kit/src/runtime/server/respond.js | 4 +- packages/kit/src/types/internal.d.ts | 1 + .../apps/basics/src/routes/csrf/+server.js | 22 +++- .../kit/test/apps/basics/svelte.config.js | 5 + .../kit/test/apps/basics/test/server.test.js | 122 ++++++++++++++++++ 9 files changed, 168 insertions(+), 4 deletions(-) diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js index 419f30416d9c..d77890510285 100644 --- a/packages/kit/src/core/config/index.spec.js +++ b/packages/kit/src/core/config/index.spec.js @@ -68,7 +68,8 @@ const get_defaults = (prefix = '') => ({ reportOnly: directive_defaults }, csrf: { - checkOrigin: true + checkOrigin: true, + allowedOrigins: [] }, embedded: false, env: { diff --git a/packages/kit/src/core/config/options.js b/packages/kit/src/core/config/options.js index a2b9bb81759d..797ef00d5ddc 100644 --- a/packages/kit/src/core/config/options.js +++ b/packages/kit/src/core/config/options.js @@ -109,7 +109,8 @@ const options = object( }), csrf: object({ - checkOrigin: boolean(true) + checkOrigin: boolean(true), + allowedOrigins: string_array([]) }), embedded: boolean(false), diff --git a/packages/kit/src/core/sync/write_server.js b/packages/kit/src/core/sync/write_server.js index 5e93d5c1cd25..f1b51d426efe 100644 --- a/packages/kit/src/core/sync/write_server.js +++ b/packages/kit/src/core/sync/write_server.js @@ -38,6 +38,7 @@ export const options = { app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')}, csp: ${s(config.kit.csp)}, csrf_check_origin: ${s(config.kit.csrf.checkOrigin)}, + csrf_allowed_origins: ${s(config.kit.csrf.allowedOrigins)}, embedded: ${config.kit.embedded}, env_public_prefix: '${config.kit.env.publicPrefix}', env_private_prefix: '${config.kit.env.privatePrefix}', diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index afc5f1d6d450..7359ac61425d 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -373,6 +373,17 @@ export interface KitConfig { * @default true */ checkOrigin?: boolean; + /** + * An array of origins that are allowed to make cross-origin form submissions to your app, even when `checkOrigin` is `true`. + * + * Each origin should be a complete origin including protocol (e.g., `https://payment-gateway.com`). + * This is useful for allowing trusted third-party services like payment gateways or authentication providers to submit forms to your app. + * + * **Warning**: Only add origins you completely trust, as this bypasses CSRF protection for those origins. + * @default [] + * @example ['https://checkout.stripe.com', 'https://accounts.google.com'] + */ + allowedOrigins?: string[]; }; /** * Whether or not the app is embedded inside a larger app. If `true`, SvelteKit will add its event listeners related to navigation etc on the parent of `%sveltekit.body%` instead of `window`, and will pass `params` from the server rather than inferring them from `location.pathname`. diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index d37659cf899b..92929a0bc2fc 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -65,13 +65,15 @@ export async function respond(request, options, manifest, state) { const url = new URL(request.url); if (options.csrf_check_origin) { + const request_origin = request.headers.get('origin'); const forbidden = is_form_content_type(request) && (request.method === 'POST' || request.method === 'PUT' || request.method === 'PATCH' || request.method === 'DELETE') && - request.headers.get('origin') !== url.origin; + request_origin !== url.origin && + (!request_origin || !options.csrf_allowed_origins.includes(request_origin)); if (forbidden) { const csrf_error = new HttpError( diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index 17e2425e3c17..06f447ad439e 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -417,6 +417,7 @@ export interface SSROptions { app_template_contains_nonce: boolean; csp: ValidatedConfig['kit']['csp']; csrf_check_origin: boolean; + csrf_allowed_origins: string[]; embedded: boolean; env_public_prefix: string; env_private_prefix: string; diff --git a/packages/kit/test/apps/basics/src/routes/csrf/+server.js b/packages/kit/test/apps/basics/src/routes/csrf/+server.js index cfbef14241d6..a6e0c58d0b7a 100644 --- a/packages/kit/test/apps/basics/src/routes/csrf/+server.js +++ b/packages/kit/test/apps/basics/src/routes/csrf/+server.js @@ -1,4 +1,24 @@ +/** @type {import('./$types').RequestHandler} */ +export function GET() { + return new Response('ok', { status: 200 }); +} + /** @type {import('./$types').RequestHandler} */ export function POST() { - return new Response(undefined, { status: 201 }); + return new Response('ok', { status: 200 }); +} + +/** @type {import('./$types').RequestHandler} */ +export function PUT() { + return new Response('ok', { status: 200 }); +} + +/** @type {import('./$types').RequestHandler} */ +export function PATCH() { + return new Response('ok', { status: 200 }); +} + +/** @type {import('./$types').RequestHandler} */ +export function DELETE() { + return new Response('ok', { status: 200 }); } diff --git a/packages/kit/test/apps/basics/svelte.config.js b/packages/kit/test/apps/basics/svelte.config.js index d2193940f0ab..defc1c5afea0 100644 --- a/packages/kit/test/apps/basics/svelte.config.js +++ b/packages/kit/test/apps/basics/svelte.config.js @@ -18,6 +18,11 @@ const config = { } }, + csrf: { + checkOrigin: true, + allowedOrigins: ['https://trusted.example.com', 'https://payment-gateway.test'] + }, + prerender: { entries: [ '*', diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index e265115c53c2..e616b92af031 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -84,6 +84,128 @@ test.describe('CSRF', () => { } } }); + + test('Allows requests from same origin', async ({ baseURL }) => { + const url = new URL(baseURL); + const res = await fetch(`${baseURL}/csrf`, { + method: 'POST', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + origin: url.origin + } + }); + expect(res.status).toBe(200); + expect(await res.text()).toBe('ok'); + }); + + test('Allows requests from allowed origins', async ({ baseURL }) => { + // Test with trusted.example.com which is in allowedOrigins + const res1 = await fetch(`${baseURL}/csrf`, { + method: 'POST', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + origin: 'https://trusted.example.com' + } + }); + expect(res1.status).toBe(200); + expect(await res1.text()).toBe('ok'); + + // Test with payment-gateway.test which is also in allowedOrigins + const res2 = await fetch(`${baseURL}/csrf`, { + method: 'POST', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + origin: 'https://payment-gateway.test' + } + }); + expect(res2.status).toBe(200); + expect(await res2.text()).toBe('ok'); + }); + + test('Blocks requests from non-allowed origins', async ({ baseURL }) => { + // Test with origin not in allowedOrigins list + const res1 = await fetch(`${baseURL}/csrf`, { + method: 'POST', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + origin: 'https://malicious-site.com' + } + }); + expect(res1.status).toBe(403); + expect(await res1.text()).toBe('Cross-site POST form submissions are forbidden'); + + // Test with similar but not exact origin + const res2 = await fetch(`${baseURL}/csrf`, { + method: 'POST', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + origin: 'https://trusted.example.com.evil.com' + } + }); + expect(res2.status).toBe(403); + expect(await res2.text()).toBe('Cross-site POST form submissions are forbidden'); + + // Test subdomain attack (should be blocked) + const res3 = await fetch(`${baseURL}/csrf`, { + method: 'POST', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + origin: 'https://evil.trusted.example.com' + } + }); + expect(res3.status).toBe(403); + expect(await res3.text()).toBe('Cross-site POST form submissions are forbidden'); + }); + + test('Allows GET requests regardless of origin', async ({ baseURL }) => { + const res = await fetch(`${baseURL}/csrf`, { + method: 'GET', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + origin: 'https://any-origin.com' + } + }); + expect(res.status).toBe(200); + }); + + test('Allows non-form content types regardless of origin', async ({ baseURL }) => { + const res = await fetch(`${baseURL}/csrf`, { + method: 'POST', + headers: { + 'content-type': 'application/json', + origin: 'https://any-origin.com' + } + }); + expect(res.status).toBe(200); + }); + + test('Allows all protected HTTP methods from allowed origins', async ({ baseURL }) => { + const methods = ['POST', 'PUT', 'PATCH', 'DELETE']; + for (const method of methods) { + const res = await fetch(`${baseURL}/csrf`, { + method, + headers: { + 'content-type': 'application/x-www-form-urlencoded', + origin: 'https://trusted.example.com' + } + }); + expect(res.status, `Method ${method} should be allowed from trusted origin`).toBe(200); + expect(await res.text(), `Method ${method} should return ok`).toBe('ok'); + } + }); + + test('Handles null origin correctly', async ({ baseURL }) => { + // Some requests may have null origin (e.g., from certain mobile apps) + const res = await fetch(`${baseURL}/csrf`, { + method: 'POST', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + origin: 'null' + } + }); + expect(res.status).toBe(403); + expect(await res.text()).toBe('Cross-site POST form submissions are forbidden'); + }); }); test.describe('Endpoints', () => { From b7d5924e5d7dc2f09da54f189429d62b391dbd51 Mon Sep 17 00:00:00 2001 From: Stanislav Khromov Date: Sat, 19 Jul 2025 22:17:10 +0200 Subject: [PATCH 2/9] Update CSRF test for undefined origin handling Renames the test to clarify it checks for undefined origin and removes the 'origin: null' header from the request. This ensures the test accurately reflects scenarios where the origin header is not set. --- packages/kit/test/apps/basics/test/server.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index e616b92af031..03c8f29f017e 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -194,13 +194,12 @@ test.describe('CSRF', () => { } }); - test('Handles null origin correctly', async ({ baseURL }) => { + test('Handles undefined origin correctly', async ({ baseURL }) => { // Some requests may have null origin (e.g., from certain mobile apps) const res = await fetch(`${baseURL}/csrf`, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded', - origin: 'null' } }); expect(res.status).toBe(403); From 2bacd26988e6253fb7c481344636ce79cc095d26 Mon Sep 17 00:00:00 2001 From: Stanislav Khromov Date: Sat, 19 Jul 2025 22:27:25 +0200 Subject: [PATCH 3/9] format --- packages/kit/test/apps/basics/test/server.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index 03c8f29f017e..2e976bc429a6 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -199,7 +199,7 @@ test.describe('CSRF', () => { const res = await fetch(`${baseURL}/csrf`, { method: 'POST', headers: { - 'content-type': 'application/x-www-form-urlencoded', + 'content-type': 'application/x-www-form-urlencoded' } }); expect(res.status).toBe(403); From b9015f9b306369208bd83537e718142e1614e9a0 Mon Sep 17 00:00:00 2001 From: Stanislav Khromov Date: Sat, 19 Jul 2025 23:30:52 +0200 Subject: [PATCH 4/9] Add allowedOrigins option to form CSRF config Introduces an allowedOrigins array to the form configuration, enabling trusted third-party origins to bypass CSRF protection for cross-origin form submissions. This is useful for integrating with services like payment gateways or authentication providers. --- packages/kit/types/index.d.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 28a0b6c4a56a..6e078054a3f6 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -355,6 +355,17 @@ declare module '@sveltejs/kit' { * @default true */ checkOrigin?: boolean; + /** + * An array of origins that are allowed to make cross-origin form submissions to your app, even when `checkOrigin` is `true`. + * + * Each origin should be a complete origin including protocol (e.g., `https://payment-gateway.com`). + * This is useful for allowing trusted third-party services like payment gateways or authentication providers to submit forms to your app. + * + * **Warning**: Only add origins you completely trust, as this bypasses CSRF protection for those origins. + * @default [] + * @example ['https://checkout.stripe.com', 'https://accounts.google.com'] + */ + allowedOrigins?: string[]; }; /** * Whether or not the app is embedded inside a larger app. If `true`, SvelteKit will add its event listeners related to navigation etc on the parent of `%sveltekit.body%` instead of `window`, and will pass `params` from the server rather than inferring them from `location.pathname`. From 2cddffd4128e95909cdebaf8e0d35508d9478d3e Mon Sep 17 00:00:00 2001 From: Stanislav Khromov Date: Sun, 20 Jul 2025 00:38:23 +0200 Subject: [PATCH 5/9] Add changeset --- .changeset/plain-games-roll.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/plain-games-roll.md diff --git a/.changeset/plain-games-roll.md b/.changeset/plain-games-roll.md new file mode 100644 index 000000000000..287f950f3868 --- /dev/null +++ b/.changeset/plain-games-roll.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +feat: add CSRF allowedOrigins bypass list From f08ca73d4abb7fd15dcc5c37aa05775c5420b479 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 20 Aug 2025 18:42:35 -0400 Subject: [PATCH 6/9] separate remote calls from form submissions --- packages/kit/src/runtime/server/respond.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index b10b90b93830..dddcdf1cca69 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -74,19 +74,14 @@ export async function internal_respond(request, options, manifest, state) { const is_data_request = has_data_suffix(url.pathname); const remote_id = get_remote_id(url); - if (options.csrf_check_origin) { - const request_origin = request.headers.get('origin'); - const opts = { status: 403 }; - - if (remote_id && request.method !== 'GET') { - return json( - { - message: 'Cross-site remote requests are forbidden' - }, - opts - ); - } + const request_origin = request.headers.get('origin'); + if (remote_id) { + if (request.method !== 'GET' && request_origin !== url.origin) { + const message = 'Cross-site remote requests are forbidden'; + return json({ message }, { status: 403 }); + } + } else if (options.csrf_check_origin) { const forbidden = is_form_content_type(request) && (request.method === 'POST' || @@ -98,9 +93,12 @@ export async function internal_respond(request, options, manifest, state) { if (forbidden) { const message = `Cross-site ${request.method} form submissions are forbidden`; + const opts = { status: 403 }; + if (request.headers.get('accept') === 'application/json') { return json({ message }, opts); } + return text(message, opts); } } From fda6875d00cd4ee180b260fabead714bb8490e82 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 20 Aug 2025 18:45:28 -0400 Subject: [PATCH 7/9] allowedOrigins -> trustedOrigins --- packages/kit/src/core/config/index.spec.js | 2 +- packages/kit/src/core/config/options.js | 2 +- packages/kit/src/core/sync/write_server.js | 2 +- packages/kit/src/exports/public.d.ts | 2 +- packages/kit/src/runtime/server/respond.js | 2 +- packages/kit/src/types/internal.d.ts | 2 +- .../kit/test/apps/basics/svelte.config.js | 2 +- .../kit/test/apps/basics/test/server.test.js | 6 +- packages/kit/types/index.d.ts | 263 ++++++++++++------ 9 files changed, 194 insertions(+), 89 deletions(-) diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js index 5f501d99af32..3e923935059e 100644 --- a/packages/kit/src/core/config/index.spec.js +++ b/packages/kit/src/core/config/index.spec.js @@ -69,7 +69,7 @@ const get_defaults = (prefix = '') => ({ }, csrf: { checkOrigin: true, - allowedOrigins: [] + trustedOrigins: [] }, embedded: false, env: { diff --git a/packages/kit/src/core/config/options.js b/packages/kit/src/core/config/options.js index ec29b314d25a..2210130b148b 100644 --- a/packages/kit/src/core/config/options.js +++ b/packages/kit/src/core/config/options.js @@ -109,7 +109,7 @@ const options = object( csrf: object({ checkOrigin: boolean(true), - allowedOrigins: string_array([]) + trustedOrigins: string_array([]) }), embedded: boolean(false), diff --git a/packages/kit/src/core/sync/write_server.js b/packages/kit/src/core/sync/write_server.js index e6a78c5b05be..f23f23b268be 100644 --- a/packages/kit/src/core/sync/write_server.js +++ b/packages/kit/src/core/sync/write_server.js @@ -38,7 +38,7 @@ export const options = { app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')}, csp: ${s(config.kit.csp)}, csrf_check_origin: ${s(config.kit.csrf.checkOrigin)}, - csrf_allowed_origins: ${s(config.kit.csrf.allowedOrigins)}, + csrf_trusted_origins: ${s(config.kit.csrf.trustedOrigins)}, embedded: ${config.kit.embedded}, env_public_prefix: '${config.kit.env.publicPrefix}', env_private_prefix: '${config.kit.env.privatePrefix}', diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 136bc9c8e099..22df7f3c91e5 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -438,7 +438,7 @@ export interface KitConfig { * @default [] * @example ['https://checkout.stripe.com', 'https://accounts.google.com'] */ - allowedOrigins?: string[]; + trustedOrigins?: string[]; }; /** * Whether or not the app is embedded inside a larger app. If `true`, SvelteKit will add its event listeners related to navigation etc on the parent of `%sveltekit.body%` instead of `window`, and will pass `params` from the server rather than inferring them from `location.pathname`. diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index dddcdf1cca69..fe2ed1c6f86a 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -89,7 +89,7 @@ export async function internal_respond(request, options, manifest, state) { request.method === 'PATCH' || request.method === 'DELETE') && request_origin !== url.origin && - (!request_origin || !options.csrf_allowed_origins.includes(request_origin)); + (!request_origin || !options.csrf_trusted_origins.includes(request_origin)); if (forbidden) { const message = `Cross-site ${request.method} form submissions are forbidden`; diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index 333752cd1bc2..9e215926ce1a 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -442,7 +442,7 @@ export interface SSROptions { app_template_contains_nonce: boolean; csp: ValidatedConfig['kit']['csp']; csrf_check_origin: boolean; - csrf_allowed_origins: string[]; + csrf_trusted_origins: string[]; embedded: boolean; env_public_prefix: string; env_private_prefix: string; diff --git a/packages/kit/test/apps/basics/svelte.config.js b/packages/kit/test/apps/basics/svelte.config.js index 42ebc71bf574..fc40386676f9 100644 --- a/packages/kit/test/apps/basics/svelte.config.js +++ b/packages/kit/test/apps/basics/svelte.config.js @@ -39,7 +39,7 @@ const config = { csrf: { checkOrigin: true, - allowedOrigins: ['https://trusted.example.com', 'https://payment-gateway.test'] + trustedOrigins: ['https://trusted.example.com', 'https://payment-gateway.test'] }, prerender: { diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index db2f7f23feba..5b14edb642a1 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -100,7 +100,7 @@ test.describe('CSRF', () => { }); test('Allows requests from allowed origins', async ({ baseURL }) => { - // Test with trusted.example.com which is in allowedOrigins + // Test with trusted.example.com which is in trustedOrigins const res1 = await fetch(`${baseURL}/csrf`, { method: 'POST', headers: { @@ -111,7 +111,7 @@ test.describe('CSRF', () => { expect(res1.status).toBe(200); expect(await res1.text()).toBe('ok'); - // Test with payment-gateway.test which is also in allowedOrigins + // Test with payment-gateway.test which is also in trustedOrigins const res2 = await fetch(`${baseURL}/csrf`, { method: 'POST', headers: { @@ -124,7 +124,7 @@ test.describe('CSRF', () => { }); test('Blocks requests from non-allowed origins', async ({ baseURL }) => { - // Test with origin not in allowedOrigins list + // Test with origin not in trustedOrigins list const res1 = await fetch(`${baseURL}/csrf`, { method: 'POST', headers: { diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 056a214d4633..11e4f557c7ab 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -4,7 +4,11 @@ declare module '@sveltejs/kit' { import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; import type { StandardSchemaV1 } from '@standard-schema/spec'; - import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams, ResolvedPathname } from '$app/types'; + import type { + RouteId as AppRouteId, + LayoutParams as AppLayoutParams, + ResolvedPathname + } from '$app/types'; import type { Span } from '@opentelemetry/api'; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. @@ -269,7 +273,10 @@ declare module '@sveltejs/kit' { * @param name the name of the cookie * @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) */ - delete: (name: string, opts: import('cookie').CookieSerializeOptions & { path: string }) => void; + delete: ( + name: string, + opts: import('cookie').CookieSerializeOptions & { path: string } + ) => void; /** * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response. @@ -414,7 +421,7 @@ declare module '@sveltejs/kit' { * @default [] * @example ['https://checkout.stripe.com', 'https://accounts.google.com'] */ - allowedOrigins?: string[]; + trustedOrigins?: string[]; }; /** * Whether or not the app is embedded inside a larger app. If `true`, SvelteKit will add its event listeners related to navigation etc on the parent of `%sveltekit.body%` instead of `window`, and will pass `params` from the server rather than inferring them from `location.pathname`. @@ -1430,7 +1437,10 @@ declare module '@sveltejs/kit' { * but they will always be split at sensible boundaries such as `%sveltekit.head%` or layout/page components. * @param input the html chunk and the info if this is the last chunk */ - transformPageChunk?: (input: { html: string; done: boolean }) => MaybePromise; + transformPageChunk?: (input: { + html: string; + done: boolean; + }) => MaybePromise; /** * Determines which headers should be included in serialized responses when a `load` function loads a resource with `fetch`. * By default, none will be included. @@ -1840,7 +1850,9 @@ declare module '@sveltejs/kit' { * A function that is invoked once the entry has been created. This is where you * should write the function to the filesystem and generate redirect manifests. */ - complete(entry: { generateManifest(opts: { relativePath: string }): string }): MaybePromise; + complete(entry: { + generateManifest(opts: { relativePath: string }): string; + }): MaybePromise; } // Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts @@ -2305,16 +2317,24 @@ declare module '@sveltejs/kit' { * @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling. * @throws {Error} If the provided status is invalid (not between 400 and 599). */ - export function error(status: number, body?: { - message: string; - } extends App.Error ? App.Error | string | undefined : never): never; + export function error( + status: number, + body?: { + message: string; + } extends App.Error + ? App.Error | string | undefined + : never + ): never; /** * Checks whether this is an error thrown by {@link error}. * @param status The status to filter for. * */ - export function isHttpError(e: unknown, status?: T): e is (HttpError_1 & { + export function isHttpError( + e: unknown, + status?: T + ): e is HttpError_1 & { status: T extends undefined ? never : T; - }); + }; /** * Redirect a request. When called during request handling, SvelteKit will return a redirect response. * Make sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it. @@ -2331,7 +2351,10 @@ declare module '@sveltejs/kit' { * @throws {Redirect} This error instructs SvelteKit to redirect to the specified location. * @throws {Error} If the provided status is invalid. * */ - export function redirect(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), location: string | URL): never; + export function redirect( + status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), + location: string | URL + ): never; /** * Checks whether this is a redirect thrown by {@link redirect}. * @param e The object to check. @@ -2383,20 +2406,31 @@ declare module '@sveltejs/kit' { wasNormalized: boolean; denormalize: (url?: string | URL) => URL; }; - export type LessThan = TNumber extends TArray["length"] ? TArray[number] : LessThan; - export type NumericRange = Exclude, LessThan>; + export type LessThan< + TNumber extends number, + TArray extends any[] = [] + > = TNumber extends TArray['length'] + ? TArray[number] + : LessThan; + export type NumericRange = Exclude< + TEnd | LessThan, + LessThan + >; export const VERSION: string; class HttpError_1 { - - constructor(status: number, body: { - message: string; - } extends App.Error ? (App.Error | string | undefined) : App.Error); + constructor( + status: number, + body: { + message: string; + } extends App.Error + ? App.Error | string | undefined + : App.Error + ); status: number; body: App.Error; toString(): string; } class Redirect_1 { - constructor(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308, location: string); status: 301 | 302 | 303 | 307 | 308 | 300 | 304 | 305 | 306; location: string; @@ -2483,13 +2517,20 @@ declare module '@sveltejs/kit/hooks' { } declare module '@sveltejs/kit/node' { - export function getRequest({ request, base, bodySizeLimit }: { - request: import("http").IncomingMessage; + export function getRequest({ + request, + base, + bodySizeLimit + }: { + request: import('http').IncomingMessage; base: string; bodySizeLimit?: number; }): Promise; - export function setResponse(res: import("http").ServerResponse, response: Response): Promise; + export function setResponse( + res: import('http').ServerResponse, + response: Response + ): Promise; /** * Converts a file on disk to a readable stream * @since 2.4.0 @@ -2514,7 +2555,7 @@ declare module '@sveltejs/kit/vite' { /** * Returns the SvelteKit Vite plugins. * */ - export function sveltekit(): Promise; + export function sveltekit(): Promise; export {}; } @@ -2562,7 +2603,10 @@ declare module '$app/forms' { * } * ``` * */ - export function deserialize | undefined, Failure extends Record | undefined>(result: string): import("@sveltejs/kit").ActionResult; + export function deserialize< + Success extends Record | undefined, + Failure extends Record | undefined + >(result: string): import('@sveltejs/kit').ActionResult; /** * This action enhances a `
` element that otherwise would work without JavaScript. * @@ -2586,14 +2630,23 @@ declare module '$app/forms' { * @param form_element The form element * @param submit Submit callback */ - export function enhance | undefined, Failure extends Record | undefined>(form_element: HTMLFormElement, submit?: import("@sveltejs/kit").SubmitFunction): { + export function enhance< + Success extends Record | undefined, + Failure extends Record | undefined + >( + form_element: HTMLFormElement, + submit?: import('@sveltejs/kit').SubmitFunction + ): { destroy(): void; }; /** * This action updates the `form` property of the current page with the given data and updates `page.status`. * In case of an error, it redirects to the nearest error page. * */ - export function applyAction | undefined, Failure extends Record | undefined>(result: import("@sveltejs/kit").ActionResult): Promise; + export function applyAction< + Success extends Record | undefined, + Failure extends Record | undefined + >(result: import('@sveltejs/kit').ActionResult): Promise; export {}; } @@ -2604,7 +2657,9 @@ declare module '$app/navigation' { * * `afterNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function afterNavigate(callback: (navigation: import("@sveltejs/kit").AfterNavigate) => void): void; + export function afterNavigate( + callback: (navigation: import('@sveltejs/kit').AfterNavigate) => void + ): void; /** * A navigation interceptor that triggers before we navigate to a URL, whether by clicking a link, calling `goto(...)`, or using the browser back/forward controls. * @@ -2616,7 +2671,9 @@ declare module '$app/navigation' { * * `beforeNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function beforeNavigate(callback: (navigation: import("@sveltejs/kit").BeforeNavigate) => void): void; + export function beforeNavigate( + callback: (navigation: import('@sveltejs/kit').BeforeNavigate) => void + ): void; /** * A lifecycle function that runs the supplied `callback` immediately before we navigate to a new URL except during full-page navigations. * @@ -2626,7 +2683,9 @@ declare module '$app/navigation' { * * `onNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function onNavigate(callback: (navigation: import("@sveltejs/kit").OnNavigate) => MaybePromise<(() => void) | void>): void; + export function onNavigate( + callback: (navigation: import('@sveltejs/kit').OnNavigate) => MaybePromise<(() => void) | void> + ): void; /** * If called when the page is being updated following a navigation (in `onMount` or `afterNavigate` or an action, for example), this disables SvelteKit's built-in scroll handling. * This is generally discouraged, since it breaks user expectations. @@ -2641,14 +2700,17 @@ declare module '$app/navigation' { * @param url Where to navigate to. Note that if you've set [`config.kit.paths.base`](https://svelte.dev/docs/kit/configuration#paths) and the URL is root-relative, you need to prepend the base path if you want to navigate within the app. * @param {Object} opts Options related to the navigation * */ - export function goto(url: string | URL, opts?: { - replaceState?: boolean | undefined; - noScroll?: boolean | undefined; - keepFocus?: boolean | undefined; - invalidateAll?: boolean | undefined; - invalidate?: (string | URL | ((url: URL) => boolean))[] | undefined; - state?: App.PageState | undefined; - }): Promise; + export function goto( + url: string | URL, + opts?: { + replaceState?: boolean | undefined; + noScroll?: boolean | undefined; + keepFocus?: boolean | undefined; + invalidateAll?: boolean | undefined; + invalidate?: (string | URL | ((url: URL) => boolean))[] | undefined; + state?: App.PageState | undefined; + } + ): Promise; /** * Causes any `load` functions belonging to the currently active page to re-run if they depend on the `url` in question, via `fetch` or `depends`. Returns a `Promise` that resolves when the page is subsequently updated. * @@ -2675,7 +2737,9 @@ declare module '$app/navigation' { * Causes all currently active remote functions to refresh, and all `load` functions belonging to the currently active page to re-run (unless disabled via the option argument). * Returns a `Promise` that resolves when the page is subsequently updated. * */ - export function refreshAll({ includeLoadFunctions }?: { + export function refreshAll({ + includeLoadFunctions + }?: { includeLoadFunctions?: boolean; }): Promise; /** @@ -2689,14 +2753,17 @@ declare module '$app/navigation' { * * @param href Page to preload * */ - export function preloadData(href: string): Promise<{ - type: "loaded"; - status: number; - data: Record; - } | { - type: "redirect"; - location: string; - }>; + export function preloadData(href: string): Promise< + | { + type: 'loaded'; + status: number; + data: Record; + } + | { + type: 'redirect'; + location: string; + } + >; /** * Programmatically imports the code for routes that haven't yet been fetched. * Typically, you might call this to speed up subsequent navigation. @@ -2798,7 +2865,13 @@ declare module '$app/paths' { } declare module '$app/server' { - import type { RequestEvent, RemoteCommand, RemoteForm, RemotePrerenderFunction, RemoteQueryFunction } from '@sveltejs/kit'; + import type { + RequestEvent, + RemoteCommand, + RemoteForm, + RemotePrerenderFunction, + RemoteQueryFunction + } from '@sveltejs/kit'; import type { StandardSchemaV1 } from '@standard-schema/spec'; /** * Read the contents of an imported asset from the filesystem @@ -2836,7 +2909,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function command(validate: "unchecked", fn: (arg: Input) => Output): RemoteCommand; + export function command( + validate: 'unchecked', + fn: (arg: Input) => Output + ): RemoteCommand; /** * Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2844,7 +2920,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function command(validate: Schema, fn: (arg: StandardSchemaV1.InferOutput) => Output): RemoteCommand, Output>; + export function command( + validate: Schema, + fn: (arg: StandardSchemaV1.InferOutput) => Output + ): RemoteCommand, Output>; /** * Creates a form object that can be spread onto a `` element. * @@ -2860,10 +2939,15 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender(fn: () => MaybePromise, options?: { - inputs?: RemotePrerenderInputsGenerator; - dynamic?: boolean; - } | undefined): RemotePrerenderFunction; + export function prerender( + fn: () => MaybePromise, + options?: + | { + inputs?: RemotePrerenderInputsGenerator; + dynamic?: boolean; + } + | undefined + ): RemotePrerenderFunction; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2871,10 +2955,16 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender(validate: "unchecked", fn: (arg: Input) => MaybePromise, options?: { - inputs?: RemotePrerenderInputsGenerator; - dynamic?: boolean; - } | undefined): RemotePrerenderFunction; + export function prerender( + validate: 'unchecked', + fn: (arg: Input) => MaybePromise, + options?: + | { + inputs?: RemotePrerenderInputsGenerator; + dynamic?: boolean; + } + | undefined + ): RemotePrerenderFunction; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2882,10 +2972,16 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise, options?: { - inputs?: RemotePrerenderInputsGenerator>; - dynamic?: boolean; - } | undefined): RemotePrerenderFunction, Output>; + export function prerender( + schema: Schema, + fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise, + options?: + | { + inputs?: RemotePrerenderInputsGenerator>; + dynamic?: boolean; + } + | undefined + ): RemotePrerenderFunction, Output>; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2901,7 +2997,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function query(validate: "unchecked", fn: (arg: Input) => MaybePromise): RemoteQueryFunction; + export function query( + validate: 'unchecked', + fn: (arg: Input) => MaybePromise + ): RemoteQueryFunction; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2909,7 +3008,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function query(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise): RemoteQueryFunction, Output>; + export function query( + schema: Schema, + fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise + ): RemoteQueryFunction, Output>; type RemotePrerenderInputsGenerator = () => MaybePromise; type MaybePromise = T | Promise; @@ -2953,19 +3055,21 @@ declare module '$app/state' { * On the server, values can only be read during rendering (in other words _not_ in e.g. `load` functions). In the browser, the values can be read at any time. * * */ - export const page: import("@sveltejs/kit").Page; + export const page: import('@sveltejs/kit').Page; /** * A read-only object representing an in-progress navigation, with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties. * Values are `null` when no navigation is occurring, or during server rendering. * */ - export const navigating: import("@sveltejs/kit").Navigation | { - from: null; - to: null; - type: null; - willUnload: null; - delta: null; - complete: null; - }; + export const navigating: + | import('@sveltejs/kit').Navigation + | { + from: null; + to: null; + type: null; + willUnload: null; + delta: null; + complete: null; + }; /** * A read-only reactive value that's initially `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update `current` to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling. * */ @@ -2979,11 +3083,10 @@ declare module '$app/state' { declare module '$app/stores' { export function getStores(): { - page: typeof page; - + navigating: typeof navigating; - + updated: typeof updated; }; /** @@ -2993,7 +3096,7 @@ declare module '$app/stores' { * * @deprecated Use `page` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const page: import("svelte/store").Readable; + export const page: import('svelte/store').Readable; /** * A readable store. * When navigating starts, its value is a `Navigation` object with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties. @@ -3003,7 +3106,9 @@ declare module '$app/stores' { * * @deprecated Use `navigating` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const navigating: import("svelte/store").Readable; + export const navigating: import('svelte/store').Readable< + import('@sveltejs/kit').Navigation | null + >; /** * A readable store whose initial value is `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update the store value to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling. * @@ -3011,12 +3116,12 @@ declare module '$app/stores' { * * @deprecated Use `updated` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const updated: import("svelte/store").Readable & { + export const updated: import('svelte/store').Readable & { check(): Promise; }; export {}; -}/** +} /** * It's possible to tell SvelteKit how to type objects inside your app by declaring the `App` namespace. By default, a new project will have a file called `src/app.d.ts` containing the following: * * ```ts @@ -3152,4 +3257,4 @@ declare module '$app/types' { export type Asset = ReturnType; } -//# sourceMappingURL=index.d.ts.map \ No newline at end of file +//# sourceMappingURL=index.d.ts.map From 51880bca52d2e96a5bbb01e0cc601362dbc1ce8e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 20 Aug 2025 18:50:34 -0400 Subject: [PATCH 8/9] regenerate --- packages/kit/types/index.d.ts | 261 ++++++++++------------------------ 1 file changed, 78 insertions(+), 183 deletions(-) diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 11e4f557c7ab..07e62b12c88b 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -4,11 +4,7 @@ declare module '@sveltejs/kit' { import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; import type { StandardSchemaV1 } from '@standard-schema/spec'; - import type { - RouteId as AppRouteId, - LayoutParams as AppLayoutParams, - ResolvedPathname - } from '$app/types'; + import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams, ResolvedPathname } from '$app/types'; import type { Span } from '@opentelemetry/api'; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. @@ -273,10 +269,7 @@ declare module '@sveltejs/kit' { * @param name the name of the cookie * @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) */ - delete: ( - name: string, - opts: import('cookie').CookieSerializeOptions & { path: string } - ) => void; + delete: (name: string, opts: import('cookie').CookieSerializeOptions & { path: string }) => void; /** * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response. @@ -1437,10 +1430,7 @@ declare module '@sveltejs/kit' { * but they will always be split at sensible boundaries such as `%sveltekit.head%` or layout/page components. * @param input the html chunk and the info if this is the last chunk */ - transformPageChunk?: (input: { - html: string; - done: boolean; - }) => MaybePromise; + transformPageChunk?: (input: { html: string; done: boolean }) => MaybePromise; /** * Determines which headers should be included in serialized responses when a `load` function loads a resource with `fetch`. * By default, none will be included. @@ -1850,9 +1840,7 @@ declare module '@sveltejs/kit' { * A function that is invoked once the entry has been created. This is where you * should write the function to the filesystem and generate redirect manifests. */ - complete(entry: { - generateManifest(opts: { relativePath: string }): string; - }): MaybePromise; + complete(entry: { generateManifest(opts: { relativePath: string }): string }): MaybePromise; } // Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts @@ -2317,24 +2305,16 @@ declare module '@sveltejs/kit' { * @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling. * @throws {Error} If the provided status is invalid (not between 400 and 599). */ - export function error( - status: number, - body?: { - message: string; - } extends App.Error - ? App.Error | string | undefined - : never - ): never; + export function error(status: number, body?: { + message: string; + } extends App.Error ? App.Error | string | undefined : never): never; /** * Checks whether this is an error thrown by {@link error}. * @param status The status to filter for. * */ - export function isHttpError( - e: unknown, - status?: T - ): e is HttpError_1 & { + export function isHttpError(e: unknown, status?: T): e is (HttpError_1 & { status: T extends undefined ? never : T; - }; + }); /** * Redirect a request. When called during request handling, SvelteKit will return a redirect response. * Make sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it. @@ -2351,10 +2331,7 @@ declare module '@sveltejs/kit' { * @throws {Redirect} This error instructs SvelteKit to redirect to the specified location. * @throws {Error} If the provided status is invalid. * */ - export function redirect( - status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), - location: string | URL - ): never; + export function redirect(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), location: string | URL): never; /** * Checks whether this is a redirect thrown by {@link redirect}. * @param e The object to check. @@ -2406,31 +2383,20 @@ declare module '@sveltejs/kit' { wasNormalized: boolean; denormalize: (url?: string | URL) => URL; }; - export type LessThan< - TNumber extends number, - TArray extends any[] = [] - > = TNumber extends TArray['length'] - ? TArray[number] - : LessThan; - export type NumericRange = Exclude< - TEnd | LessThan, - LessThan - >; + export type LessThan = TNumber extends TArray["length"] ? TArray[number] : LessThan; + export type NumericRange = Exclude, LessThan>; export const VERSION: string; class HttpError_1 { - constructor( - status: number, - body: { - message: string; - } extends App.Error - ? App.Error | string | undefined - : App.Error - ); + + constructor(status: number, body: { + message: string; + } extends App.Error ? (App.Error | string | undefined) : App.Error); status: number; body: App.Error; toString(): string; } class Redirect_1 { + constructor(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308, location: string); status: 301 | 302 | 303 | 307 | 308 | 300 | 304 | 305 | 306; location: string; @@ -2517,20 +2483,13 @@ declare module '@sveltejs/kit/hooks' { } declare module '@sveltejs/kit/node' { - export function getRequest({ - request, - base, - bodySizeLimit - }: { - request: import('http').IncomingMessage; + export function getRequest({ request, base, bodySizeLimit }: { + request: import("http").IncomingMessage; base: string; bodySizeLimit?: number; }): Promise; - export function setResponse( - res: import('http').ServerResponse, - response: Response - ): Promise; + export function setResponse(res: import("http").ServerResponse, response: Response): Promise; /** * Converts a file on disk to a readable stream * @since 2.4.0 @@ -2555,7 +2514,7 @@ declare module '@sveltejs/kit/vite' { /** * Returns the SvelteKit Vite plugins. * */ - export function sveltekit(): Promise; + export function sveltekit(): Promise; export {}; } @@ -2603,10 +2562,7 @@ declare module '$app/forms' { * } * ``` * */ - export function deserialize< - Success extends Record | undefined, - Failure extends Record | undefined - >(result: string): import('@sveltejs/kit').ActionResult; + export function deserialize | undefined, Failure extends Record | undefined>(result: string): import("@sveltejs/kit").ActionResult; /** * This action enhances a `` element that otherwise would work without JavaScript. * @@ -2630,23 +2586,14 @@ declare module '$app/forms' { * @param form_element The form element * @param submit Submit callback */ - export function enhance< - Success extends Record | undefined, - Failure extends Record | undefined - >( - form_element: HTMLFormElement, - submit?: import('@sveltejs/kit').SubmitFunction - ): { + export function enhance | undefined, Failure extends Record | undefined>(form_element: HTMLFormElement, submit?: import("@sveltejs/kit").SubmitFunction): { destroy(): void; }; /** * This action updates the `form` property of the current page with the given data and updates `page.status`. * In case of an error, it redirects to the nearest error page. * */ - export function applyAction< - Success extends Record | undefined, - Failure extends Record | undefined - >(result: import('@sveltejs/kit').ActionResult): Promise; + export function applyAction | undefined, Failure extends Record | undefined>(result: import("@sveltejs/kit").ActionResult): Promise; export {}; } @@ -2657,9 +2604,7 @@ declare module '$app/navigation' { * * `afterNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function afterNavigate( - callback: (navigation: import('@sveltejs/kit').AfterNavigate) => void - ): void; + export function afterNavigate(callback: (navigation: import("@sveltejs/kit").AfterNavigate) => void): void; /** * A navigation interceptor that triggers before we navigate to a URL, whether by clicking a link, calling `goto(...)`, or using the browser back/forward controls. * @@ -2671,9 +2616,7 @@ declare module '$app/navigation' { * * `beforeNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function beforeNavigate( - callback: (navigation: import('@sveltejs/kit').BeforeNavigate) => void - ): void; + export function beforeNavigate(callback: (navigation: import("@sveltejs/kit").BeforeNavigate) => void): void; /** * A lifecycle function that runs the supplied `callback` immediately before we navigate to a new URL except during full-page navigations. * @@ -2683,9 +2626,7 @@ declare module '$app/navigation' { * * `onNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function onNavigate( - callback: (navigation: import('@sveltejs/kit').OnNavigate) => MaybePromise<(() => void) | void> - ): void; + export function onNavigate(callback: (navigation: import("@sveltejs/kit").OnNavigate) => MaybePromise<(() => void) | void>): void; /** * If called when the page is being updated following a navigation (in `onMount` or `afterNavigate` or an action, for example), this disables SvelteKit's built-in scroll handling. * This is generally discouraged, since it breaks user expectations. @@ -2700,17 +2641,14 @@ declare module '$app/navigation' { * @param url Where to navigate to. Note that if you've set [`config.kit.paths.base`](https://svelte.dev/docs/kit/configuration#paths) and the URL is root-relative, you need to prepend the base path if you want to navigate within the app. * @param {Object} opts Options related to the navigation * */ - export function goto( - url: string | URL, - opts?: { - replaceState?: boolean | undefined; - noScroll?: boolean | undefined; - keepFocus?: boolean | undefined; - invalidateAll?: boolean | undefined; - invalidate?: (string | URL | ((url: URL) => boolean))[] | undefined; - state?: App.PageState | undefined; - } - ): Promise; + export function goto(url: string | URL, opts?: { + replaceState?: boolean | undefined; + noScroll?: boolean | undefined; + keepFocus?: boolean | undefined; + invalidateAll?: boolean | undefined; + invalidate?: (string | URL | ((url: URL) => boolean))[] | undefined; + state?: App.PageState | undefined; + }): Promise; /** * Causes any `load` functions belonging to the currently active page to re-run if they depend on the `url` in question, via `fetch` or `depends`. Returns a `Promise` that resolves when the page is subsequently updated. * @@ -2737,9 +2675,7 @@ declare module '$app/navigation' { * Causes all currently active remote functions to refresh, and all `load` functions belonging to the currently active page to re-run (unless disabled via the option argument). * Returns a `Promise` that resolves when the page is subsequently updated. * */ - export function refreshAll({ - includeLoadFunctions - }?: { + export function refreshAll({ includeLoadFunctions }?: { includeLoadFunctions?: boolean; }): Promise; /** @@ -2753,17 +2689,14 @@ declare module '$app/navigation' { * * @param href Page to preload * */ - export function preloadData(href: string): Promise< - | { - type: 'loaded'; - status: number; - data: Record; - } - | { - type: 'redirect'; - location: string; - } - >; + export function preloadData(href: string): Promise<{ + type: "loaded"; + status: number; + data: Record; + } | { + type: "redirect"; + location: string; + }>; /** * Programmatically imports the code for routes that haven't yet been fetched. * Typically, you might call this to speed up subsequent navigation. @@ -2865,13 +2798,7 @@ declare module '$app/paths' { } declare module '$app/server' { - import type { - RequestEvent, - RemoteCommand, - RemoteForm, - RemotePrerenderFunction, - RemoteQueryFunction - } from '@sveltejs/kit'; + import type { RequestEvent, RemoteCommand, RemoteForm, RemotePrerenderFunction, RemoteQueryFunction } from '@sveltejs/kit'; import type { StandardSchemaV1 } from '@standard-schema/spec'; /** * Read the contents of an imported asset from the filesystem @@ -2909,10 +2836,7 @@ declare module '$app/server' { * * @since 2.27 */ - export function command( - validate: 'unchecked', - fn: (arg: Input) => Output - ): RemoteCommand; + export function command(validate: "unchecked", fn: (arg: Input) => Output): RemoteCommand; /** * Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2920,10 +2844,7 @@ declare module '$app/server' { * * @since 2.27 */ - export function command( - validate: Schema, - fn: (arg: StandardSchemaV1.InferOutput) => Output - ): RemoteCommand, Output>; + export function command(validate: Schema, fn: (arg: StandardSchemaV1.InferOutput) => Output): RemoteCommand, Output>; /** * Creates a form object that can be spread onto a `` element. * @@ -2939,15 +2860,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender( - fn: () => MaybePromise, - options?: - | { - inputs?: RemotePrerenderInputsGenerator; - dynamic?: boolean; - } - | undefined - ): RemotePrerenderFunction; + export function prerender(fn: () => MaybePromise, options?: { + inputs?: RemotePrerenderInputsGenerator; + dynamic?: boolean; + } | undefined): RemotePrerenderFunction; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2955,16 +2871,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender( - validate: 'unchecked', - fn: (arg: Input) => MaybePromise, - options?: - | { - inputs?: RemotePrerenderInputsGenerator; - dynamic?: boolean; - } - | undefined - ): RemotePrerenderFunction; + export function prerender(validate: "unchecked", fn: (arg: Input) => MaybePromise, options?: { + inputs?: RemotePrerenderInputsGenerator; + dynamic?: boolean; + } | undefined): RemotePrerenderFunction; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2972,16 +2882,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender( - schema: Schema, - fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise, - options?: - | { - inputs?: RemotePrerenderInputsGenerator>; - dynamic?: boolean; - } - | undefined - ): RemotePrerenderFunction, Output>; + export function prerender(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise, options?: { + inputs?: RemotePrerenderInputsGenerator>; + dynamic?: boolean; + } | undefined): RemotePrerenderFunction, Output>; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2997,10 +2901,7 @@ declare module '$app/server' { * * @since 2.27 */ - export function query( - validate: 'unchecked', - fn: (arg: Input) => MaybePromise - ): RemoteQueryFunction; + export function query(validate: "unchecked", fn: (arg: Input) => MaybePromise): RemoteQueryFunction; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -3008,10 +2909,7 @@ declare module '$app/server' { * * @since 2.27 */ - export function query( - schema: Schema, - fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise - ): RemoteQueryFunction, Output>; + export function query(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise): RemoteQueryFunction, Output>; type RemotePrerenderInputsGenerator = () => MaybePromise; type MaybePromise = T | Promise; @@ -3055,21 +2953,19 @@ declare module '$app/state' { * On the server, values can only be read during rendering (in other words _not_ in e.g. `load` functions). In the browser, the values can be read at any time. * * */ - export const page: import('@sveltejs/kit').Page; + export const page: import("@sveltejs/kit").Page; /** * A read-only object representing an in-progress navigation, with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties. * Values are `null` when no navigation is occurring, or during server rendering. * */ - export const navigating: - | import('@sveltejs/kit').Navigation - | { - from: null; - to: null; - type: null; - willUnload: null; - delta: null; - complete: null; - }; + export const navigating: import("@sveltejs/kit").Navigation | { + from: null; + to: null; + type: null; + willUnload: null; + delta: null; + complete: null; + }; /** * A read-only reactive value that's initially `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update `current` to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling. * */ @@ -3083,10 +2979,11 @@ declare module '$app/state' { declare module '$app/stores' { export function getStores(): { + page: typeof page; - + navigating: typeof navigating; - + updated: typeof updated; }; /** @@ -3096,7 +2993,7 @@ declare module '$app/stores' { * * @deprecated Use `page` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const page: import('svelte/store').Readable; + export const page: import("svelte/store").Readable; /** * A readable store. * When navigating starts, its value is a `Navigation` object with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties. @@ -3106,9 +3003,7 @@ declare module '$app/stores' { * * @deprecated Use `navigating` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const navigating: import('svelte/store').Readable< - import('@sveltejs/kit').Navigation | null - >; + export const navigating: import("svelte/store").Readable; /** * A readable store whose initial value is `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update the store value to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling. * @@ -3116,12 +3011,12 @@ declare module '$app/stores' { * * @deprecated Use `updated` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const updated: import('svelte/store').Readable & { + export const updated: import("svelte/store").Readable & { check(): Promise; }; export {}; -} /** +}/** * It's possible to tell SvelteKit how to type objects inside your app by declaring the `App` namespace. By default, a new project will have a file called `src/app.d.ts` containing the following: * * ```ts @@ -3257,4 +3152,4 @@ declare module '$app/types' { export type Asset = ReturnType; } -//# sourceMappingURL=index.d.ts.map +//# sourceMappingURL=index.d.ts.map \ No newline at end of file From 22f6b147b1ab84b68455f0a9dc313a9f14f5918f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 20 Aug 2025 19:03:25 -0400 Subject: [PATCH 9/9] Apply suggestions from code review --- .changeset/plain-games-roll.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/plain-games-roll.md b/.changeset/plain-games-roll.md index 287f950f3868..489d19746e2d 100644 --- a/.changeset/plain-games-roll.md +++ b/.changeset/plain-games-roll.md @@ -1,5 +1,5 @@ --- -'@sveltejs/kit': patch +'@sveltejs/kit': minor --- -feat: add CSRF allowedOrigins bypass list +feat: add `csrf.trustedOrigins` configuration