@sveltejs/kit 3.0.0-next.18 → 3.0.0-next.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/package.json +12 -5
  2. package/src/cli.js +1 -1
  3. package/src/constants.js +3 -0
  4. package/src/core/config/index.js +1 -1
  5. package/src/core/env.js +1 -1
  6. package/src/core/postbuild/analyse.js +1 -1
  7. package/src/core/postbuild/prerender.js +1 -1
  8. package/src/core/sync/create_manifest_data/index.js +9 -0
  9. package/src/core/sync/sync.js +22 -9
  10. package/src/core/sync/ts.js +1 -1
  11. package/src/core/sync/write_app_types.js +1 -1
  12. package/src/core/sync/write_client_manifest.js +1 -1
  13. package/src/core/sync/write_server.js +1 -3
  14. package/src/core/sync/write_tsconfig/index.js +1 -1
  15. package/src/core/sync/write_types/index.js +6 -3
  16. package/src/exports/index.js +9 -9
  17. package/src/exports/internal/server/event.js +1 -1
  18. package/src/exports/internal/server/telemetry.js +1 -1
  19. package/src/exports/internal/shared.js +9 -0
  20. package/src/exports/{params.js → params/index.js} +6 -4
  21. package/src/exports/params/public.d.ts +63 -0
  22. package/src/exports/public.d.ts +77 -447
  23. package/src/exports/vite/build/build_server.js +2 -2
  24. package/src/exports/vite/dev/index.js +2 -3
  25. package/src/exports/vite/index.js +14 -3
  26. package/src/pathname.js +55 -0
  27. package/src/runtime/app/{forms.js → forms/index.js} +9 -8
  28. package/src/runtime/app/forms/public.d.ts +2 -0
  29. package/src/runtime/app/forms/types.d.ts +56 -0
  30. package/src/runtime/app/{navigation.js → navigation/index.js} +2 -2
  31. package/src/runtime/app/navigation/public.d.ts +237 -0
  32. package/src/runtime/app/paths/client.js +14 -8
  33. package/src/runtime/app/paths/index.js +1 -1
  34. package/src/runtime/app/paths/internal/client.js +4 -0
  35. package/src/runtime/app/paths/internal/server.js +4 -0
  36. package/src/runtime/app/paths/internal.d.ts +3 -0
  37. package/src/runtime/app/paths/public.d.ts +1 -1
  38. package/src/runtime/app/paths/server.js +6 -4
  39. package/src/runtime/app/server/index.js +1 -1
  40. package/src/runtime/app/server/remote/form.js +3 -4
  41. package/src/runtime/app/server/remote/prerender.js +3 -3
  42. package/src/runtime/app/server/remote/shared.js +3 -10
  43. package/src/runtime/app/state/index.js +4 -2
  44. package/src/runtime/app/state/public.d.ts +72 -0
  45. package/src/runtime/app/stores.js +2 -2
  46. package/src/runtime/client/client.js +65 -54
  47. package/src/runtime/client/entry.js +2 -2
  48. package/src/runtime/client/remote-functions/command.svelte.js +36 -34
  49. package/src/runtime/client/remote-functions/form.svelte.js +76 -78
  50. package/src/runtime/client/remote-functions/prerender.svelte.js +3 -3
  51. package/src/runtime/client/remote-functions/query/index.js +1 -1
  52. package/src/runtime/client/remote-functions/query/instance.svelte.js +4 -3
  53. package/src/runtime/client/remote-functions/query-batch.svelte.js +3 -3
  54. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +5 -5
  55. package/src/runtime/client/remote-functions/query-live/iterator.js +5 -7
  56. package/src/runtime/client/remote-functions/shared.svelte.js +9 -14
  57. package/src/runtime/client/state.svelte.js +5 -3
  58. package/src/runtime/client/types.d.ts +2 -1
  59. package/src/runtime/pathname.js +6 -61
  60. package/src/runtime/props.svelte.js +1 -1
  61. package/src/runtime/server/constants.js +0 -3
  62. package/src/runtime/server/errors.js +53 -28
  63. package/src/runtime/server/fetch.js +1 -1
  64. package/src/runtime/server/index.js +9 -14
  65. package/src/runtime/server/page/actions.js +2 -1
  66. package/src/runtime/server/page/index.js +7 -3
  67. package/src/runtime/server/page/load_data.js +1 -1
  68. package/src/runtime/server/page/render.js +17 -11
  69. package/src/runtime/server/page/server_routing.js +3 -2
  70. package/src/runtime/server/remote-functions.js +3 -2
  71. package/src/runtime/server/respond.js +4 -8
  72. package/src/runtime/server/state.js +3 -6
  73. package/src/types/ambient.d.ts +1 -1
  74. package/src/types/internal.d.ts +8 -10
  75. package/src/types/private.d.ts +12 -3
  76. package/src/utils/error.js +30 -14
  77. package/src/utils/page_nodes.js +3 -2
  78. package/src/utils/params.js +3 -2
  79. package/src/utils/routing.js +5 -4
  80. package/src/version.js +1 -1
  81. package/types/index.d.ts +992 -932
  82. package/types/index.d.ts.map +43 -31
  83. /package/src/{runtime/telemetry/noop.js → telemetry.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "3.0.0-next.18",
3
+ "version": "3.0.0-next.19",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
@@ -33,6 +33,7 @@
33
33
  "@playwright/test": "^1.62.0",
34
34
  "@sveltejs/vite-plugin-svelte": "^7.0.0",
35
35
  "@types/connect": "^3.4.38",
36
+ "@typescript/native": "npm:typescript@^7.0.2",
36
37
  "@types/node": "^22.19.19",
37
38
  "dts-buddy": "^0.8.3",
38
39
  "jsdom": "^30.0.0",
@@ -75,6 +76,7 @@
75
76
  "default": "./src/runtime/app/internal/transport.js"
76
77
  },
77
78
  "#app/paths": {
79
+ "types": "./src/runtime/app/paths/internal.d.ts",
78
80
  "workerd": "./src/runtime/app/paths/server.js",
79
81
  "browser": "./src/runtime/app/paths/client.js",
80
82
  "default": "./src/runtime/app/paths/server.js"
@@ -123,6 +125,10 @@
123
125
  "types": "./types/index.d.ts",
124
126
  "import": "./src/exports/env/index.js"
125
127
  },
128
+ "./params": {
129
+ "types": "./types/index.d.ts",
130
+ "import": "./src/exports/params/index.js"
131
+ },
126
132
  "./vite": {
127
133
  "types": "./types/index.d.ts",
128
134
  "import": "./src/exports/vite/index.js"
@@ -133,10 +139,10 @@
133
139
  "node": ">=22.17"
134
140
  },
135
141
  "scripts": {
136
- "lint": "prettier --config ../../.prettierrc --check .",
137
- "check": "tsc && cd ./test/types && tsc && cd ./app-error-enhanced && tsc",
138
- "check:all": "tsc && pnpm -r --filter=\"./**\" check",
139
- "format": "prettier --config ../../.prettierrc --write .",
142
+ "lint": "oxfmt --check .",
143
+ "check": "pnpm tsc-native && pnpm tsc-native --project test/types/tsconfig.json && pnpm tsc-native --project test/types/app-error-enhanced/tsconfig.json",
144
+ "check:all": "pnpm tsc-native && pnpm -r --filter=\"./**\" check",
145
+ "format": "oxfmt --write .",
140
146
  "test": "pnpm test:unit && pnpm test:integration",
141
147
  "test:integration": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test",
142
148
  "test:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:dev",
@@ -148,6 +154,7 @@
148
154
  "test:svelte-async:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:svelte-async:dev",
149
155
  "test:svelte-async:build": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:svelte-async:build",
150
156
  "test:unit": "vitest run ./",
157
+ "tsc-native": "node node_modules/@typescript/native/bin/tsc",
151
158
  "generate:version": "node scripts/generate-version.js",
152
159
  "generate:types": "node scripts/generate-dts.js"
153
160
  }
package/src/cli.js CHANGED
@@ -97,7 +97,7 @@ if (command === 'sync') {
97
97
  }
98
98
 
99
99
  try {
100
- const vite = /** @type {import('vite')} */ (await import_peer('vite', process.cwd()));
100
+ const vite = /** @type {typeof import('vite')} */ (await import_peer('vite', process.cwd()));
101
101
 
102
102
  const vite_config = await load_vite_config(values.config, vite);
103
103
  const sveltekit_config = extract_svelte_config(vite_config);
package/src/constants.js CHANGED
@@ -13,3 +13,6 @@ export const MUTATIVE_METHODS = ['POST', 'PUT', 'PATCH', 'DELETE'];
13
13
  export const PAGE_METHODS = ['GET', 'POST', 'HEAD'];
14
14
 
15
15
  export const SRC_ROOT = import.meta.dirname;
16
+
17
+ // eslint-disable-next-line n/prefer-global/process
18
+ export const IN_WEBCONTAINER = !!globalThis.process?.versions?.webcontainer;
@@ -123,7 +123,7 @@ export function load_error_page(config) {
123
123
  * @param {typeof import('vite')} [vite]
124
124
  */
125
125
  export async function load_vite_config(config, vite) {
126
- vite ??= /** @type {import('vite')} */ (await import_peer('vite', process.cwd()));
126
+ vite ??= /** @type {typeof import('vite')} */ (await import_peer('vite', process.cwd()));
127
127
 
128
128
  return vite.resolveConfig({ configFile: config }, 'build', process.env.MODE ?? 'production');
129
129
  }
package/src/core/env.js CHANGED
@@ -55,7 +55,7 @@ export async function load_explicit_env(vite, kit, file, root, mode) {
55
55
 
56
56
  const runner = get_runner(vite, server);
57
57
 
58
- /** @type {import('../runtime/app/env/internal.js')} */ (
58
+ /** @type {typeof import('../runtime/app/env/internal.js')} */ (
59
59
  await runner.import(`${runtime_directory}/app/env/internal.js`)
60
60
  ).set_building();
61
61
 
@@ -54,7 +54,7 @@ async function analyse({
54
54
 
55
55
  // `set_env` lives in a separate module that imports the user's `src/env` config. We import it
56
56
  // *after* `set_building()` so that `building`-dependent expressions resolve correctly
57
- /** @type {import('__sveltekit/env')} */
57
+ /** @type {typeof import('__sveltekit/env')} */
58
58
  const { set_env } = await import(pathToFileURL(`${server_root}/server/env.js`).href);
59
59
  set_env(env);
60
60
 
@@ -52,7 +52,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
52
52
 
53
53
  // `set_env` and `Server` live in modules that import the user's `src/env` config. We import them
54
54
  // *after* `set_building()` so that `building`-dependent expressions resolve correctly
55
- /** @type {import('__sveltekit/env')} */
55
+ /** @type {typeof import('__sveltekit/env')} */
56
56
  const { set_env } = await import(pathToFileURL(`${out}/server/env.js`).href);
57
57
  set_env(env);
58
58
 
@@ -251,6 +251,15 @@ function create_routes_and_nodes(cwd, config, fallback) {
251
251
  continue;
252
252
  }
253
253
 
254
+ // allow e.g. `+page.stories.svelte` or `+server.test.ts`
255
+ if (
256
+ file.name.includes('.test.') ||
257
+ file.name.includes('.spec.') ||
258
+ file.name.includes('.stories.')
259
+ ) {
260
+ continue;
261
+ }
262
+
254
263
  if (file.name.endsWith('.d.ts')) {
255
264
  let name = file.name.slice(0, -5);
256
265
  const ext = valid_extensions.find((ext) => name.endsWith(ext));
@@ -47,22 +47,35 @@ export function create(config, root) {
47
47
  * @param {import('types').ManifestData} manifest_data
48
48
  * @param {string} file
49
49
  * @param {string} root The project root directory
50
+ * @returns {boolean} Whether the update completed, or a full manifest rebuild is needed
50
51
  */
51
52
  export function update(config, manifest_data, file, root) {
52
- const node_analyser = create_node_analyser(root);
53
+ try {
54
+ const node_analyser = create_node_analyser(root);
53
55
 
54
- for (const node of manifest_data.nodes) {
55
- node.page_options = node_analyser.get_page_options(node);
56
- }
56
+ for (const node of manifest_data.nodes) {
57
+ node.page_options = node_analyser.get_page_options(node);
58
+ }
59
+
60
+ for (const route of manifest_data.routes) {
61
+ if (route.endpoint) {
62
+ route.endpoint.page_options = get_page_options(route.endpoint.file, root);
63
+ }
64
+ }
57
65
 
58
- for (const route of manifest_data.routes) {
59
- if (route.endpoint) {
60
- route.endpoint.page_options = get_page_options(route.endpoint.file, root);
66
+ write_types(config, manifest_data, file, root);
67
+ write_app_types(config.kit, manifest_data, root);
68
+ } catch (error) {
69
+ // A route file can disappear before the watcher delivers its unlink event. In that case,
70
+ // the manifest is stale and must be rebuilt instead of incrementally updated.
71
+ if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {
72
+ return false;
61
73
  }
74
+
75
+ throw error;
62
76
  }
63
77
 
64
- write_types(config, manifest_data, file, root);
65
- write_app_types(config.kit, manifest_data, root);
78
+ return true;
66
79
  }
67
80
 
68
81
  /**
@@ -1,4 +1,4 @@
1
- /** @type {import('typescript')} */
1
+ /** @type {typeof import('typescript')} */
2
2
  // @ts-ignore
3
3
  export let ts = undefined;
4
4
  try {
@@ -122,7 +122,7 @@ function generate_app_types(manifest_data, config, dir) {
122
122
  return posixify(path.relative(dir, params_file));
123
123
  };
124
124
 
125
- type = `import('@sveltejs/kit').MatcherParam<(typeof import('${path_to_params()}').params)[${JSON.stringify(matcher)}]>`;
125
+ type = `import('@sveltejs/kit/params').MatcherParam<(typeof import('${path_to_params()}').params)[${JSON.stringify(matcher)}]>`;
126
126
  matcher_types.set(matcher, type);
127
127
  }
128
128
 
@@ -155,7 +155,7 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
155
155
  export const hooks = {
156
156
  handleError: ${
157
157
  client_hooks_file ? 'client_hooks.handleError || ' : ''
158
- }(({ error }) => { console.error(error) }),
158
+ }(({ kind, error }) => { if (kind === 'unknown') { console.error(error); } }),
159
159
  ${client_hooks_file ? 'init: client_hooks.init,' : ''}
160
160
  reroute: ${universal_hooks_file ? 'universal_hooks.reroute || ' : ''}(() => {}),
161
161
  transport: ${universal_hooks_file ? 'universal_hooks.transport || ' : ''}{}
@@ -61,9 +61,8 @@ export async function get_hooks() {
61
61
  let handle;
62
62
  let handleFetch;
63
63
  let handleError;
64
- let handleValidationError;
65
64
  let init;
66
- ${server_hooks ? `({ handle, handleFetch, handleError, handleValidationError, init } = await import(${s(server_hooks)}));` : ''}
65
+ ${server_hooks ? `({ handle, handleFetch, handleError, init } = await import(${s(server_hooks)}));` : ''}
67
66
 
68
67
  let reroute;
69
68
  let transport;
@@ -73,7 +72,6 @@ export async function get_hooks() {
73
72
  handle,
74
73
  handleFetch,
75
74
  handleError,
76
- handleValidationError,
77
75
  init,
78
76
  reroute,
79
77
  transport
@@ -13,7 +13,7 @@ import {
13
13
  } from './utils.js';
14
14
  import { extends_id, validate_resolved_config } from './validate.js';
15
15
 
16
- /** @type {import('typescript')} */
16
+ /** @type {typeof import('typescript')} */
17
17
  let ts;
18
18
  try {
19
19
  ts = await import('typescript');
@@ -187,7 +187,10 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
187
187
  const outdir = path.join(config.kit.outDir, 'types', routes_dir, route.id);
188
188
 
189
189
  // now generate new types
190
- const imports = ["import type * as Kit from '@sveltejs/kit';"];
190
+ const imports = [
191
+ "import type * as Kit from '@sveltejs/kit';",
192
+ "import { MatcherParam } from '@sveltejs/kit/params';"
193
+ ];
191
194
 
192
195
  /** @type {string[]} */
193
196
  const declarations = [];
@@ -431,7 +434,7 @@ function process_node(node, outdir, is_page, proxies, root, all_pages_have_load
431
434
  'type ExtractActionFailure<T> = T extends Kit.ActionFailure<infer X> ? X extends void ? never : X : never;',
432
435
  'type ActionsFailure<T extends Record<string, (...args: any) => any>> = { [Key in keyof T]: Exclude<ExtractActionFailure<Awaited<ReturnType<T[Key]>>>, void>; }[keyof T];',
433
436
  `type ActionsExport = typeof import('${from}').actions`,
434
- 'export type SubmitFunction = Kit.SubmitFunction<Expand<ActionsSuccess<ActionsExport>>, Expand<ActionsFailure<ActionsExport>>>'
437
+ "export type SubmitFunction = import('$app/forms').SubmitFunction<Expand<ActionsSuccess<ActionsExport>>, Expand<ActionsFailure<ActionsExport>>>"
435
438
  );
436
439
 
437
440
  type = 'Expand<Kit.AwaitedActions<ActionsExport>> | null';
@@ -613,7 +616,7 @@ function generate_params_type(params, outdir, config) {
613
616
  (param) =>
614
617
  `${/^\w+$/.test(param.name) ? param.name : `'${param.name}'`}${param.optional ? '?' : ''}: ${
615
618
  param.matcher
616
- ? `Kit.MatcherParam<(typeof import('${params_import}').params)[${JSON.stringify(param.matcher)}]>`
619
+ ? `MatcherParam<(typeof import('${params_import}').params)[${JSON.stringify(param.matcher)}]>`
617
620
  : 'string'
618
621
  }${param.optional ? ' | undefined' : ''}`
619
622
  )
@@ -8,12 +8,12 @@ import {
8
8
  has_resolution_suffix,
9
9
  strip_data_suffix,
10
10
  strip_resolution_suffix
11
- } from '../runtime/pathname.js';
12
- import { text_encoder } from '../runtime/utils.js';
11
+ } from '../pathname.js';
13
12
  import { validate_redirect_location } from './url.js';
14
13
 
14
+ const text_encoder = new TextEncoder();
15
+
15
16
  export { VERSION } from '../version.js';
16
- export { defineParams } from './params.js';
17
17
 
18
18
  // Keep the status codes as `number` because restricting to certain numbers makes it unnecessarily hard to use compared to the benefits
19
19
  // (we have runtime errors already to check for invalid codes). Also see https://github.com/sveltejs/kit/issues/11780
@@ -24,7 +24,7 @@ export { defineParams } from './params.js';
24
24
  /**
25
25
  * Throws an error with a HTTP status code and an optional message.
26
26
  * When called during request handling, this will cause SvelteKit to
27
- * return an error response without invoking `handleError`.
27
+ * return an error response; the error will be passed to `handleError` as an _expected_ error.
28
28
  * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
29
29
  * @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
30
30
  * @param {string} [message] The error message.
@@ -38,15 +38,15 @@ export { defineParams } from './params.js';
38
38
  /**
39
39
  * Throws an error with a HTTP status code and an optional message.
40
40
  * When called during request handling, this will cause SvelteKit to
41
- * return an error response without invoking `handleError`.
41
+ * return an error response; the error will be passed to `handleError` as an _expected_ error.
42
42
  * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
43
43
  * @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
44
44
  * @param {string} message The error message.
45
- * @param {{ status: number; message: string } extends App.Error ? never : Omit<App.Error, 'status' | 'message'>} properties Additional properties of the App.Error type.
45
+ * @param {keyof Omit<App.Error, 'status' | 'message'> extends never ? never : Omit<App.Error, 'status' | 'message'>} properties Additional properties of the App.Error type.
46
46
  * @overload
47
47
  * @param {number} status
48
48
  * @param {string} message
49
- * @param {{ status: number; message: string } extends App.Error ? never : Omit<App.Error, 'status' | 'message'>} properties
49
+ * @param {keyof Omit<App.Error, 'status' | 'message'> extends never ? never : Omit<App.Error, 'status' | 'message'>} properties
50
50
  * @return {never}
51
51
  * @throws {import('./public.js').HttpError} This error instructs SvelteKit to initiate HTTP error handling.
52
52
  * @throws {Error} If the provided status is invalid (not between 400 and 599).
@@ -54,7 +54,7 @@ export { defineParams } from './params.js';
54
54
  /**
55
55
  * Throws an error with a HTTP status code and an optional message.
56
56
  * When called during request handling, this will cause SvelteKit to
57
- * return an error response without invoking `handleError`.
57
+ * return an error response; the error will be passed to `handleError` as an _expected_ error.
58
58
  * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
59
59
  * @deprecated Passing an `App.Error` body as the second argument is deprecated — pass the `message` as the second argument, and any additional properties as the third
60
60
  * @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
@@ -69,7 +69,7 @@ export { defineParams } from './params.js';
69
69
  /**
70
70
  * Throws an error with a HTTP status code and an optional message.
71
71
  * When called during request handling, this will cause SvelteKit to
72
- * return an error response without invoking `handleError`.
72
+ * return an error response; the error will be passed to `handleError` as an _expected_ error.
73
73
  * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
74
74
  * @param {any} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
75
75
  * @param {any} [message] A string, or (deprecated) a partial App.Error object
@@ -1,7 +1,7 @@
1
1
  /** @import { RequestEvent } from '@sveltejs/kit' */
2
2
  /** @import { RequestStore } from 'types' */
3
3
  /** @import { AsyncLocalStorage } from 'node:async_hooks' */
4
- import { IN_WEBCONTAINER } from '../../../runtime/server/constants.js';
4
+ import { IN_WEBCONTAINER } from '../../../constants.js';
5
5
 
6
6
  /** @type {RequestStore | null} */
7
7
  let sync_store = null;
@@ -1,7 +1,7 @@
1
1
  /** @import { Tracer, SpanStatusCode, PropagationAPI, ContextAPI } from '@opentelemetry/api' */
2
2
  /** @import { RecordSpan } from 'types' */
3
3
  import { HttpError, Redirect } from '../shared.js';
4
- import { noop_span } from '../../../runtime/telemetry/noop.js';
4
+ import { noop_span } from '../../../telemetry.js';
5
5
 
6
6
  // Import this module by its bare specifier so bundled and external code share its state.
7
7
 
@@ -14,6 +14,15 @@ export class HttpError {
14
14
  }
15
15
  }
16
16
 
17
+ /**
18
+ * An `HttpError` whose body is already in its final, user-facing form — either produced by the
19
+ * `handleError` hook on the server and reconstructed here from the response, or authored directly
20
+ * by the client runtime. Unlike a plain `HttpError` (which represents a fresh `error(...)` call
21
+ * that the hook has yet to see), `handleError` must not run on it.
22
+ * @extends HttpError
23
+ */
24
+ export class HandledHttpError extends HttpError {}
25
+
17
26
  export class Redirect {
18
27
  /**
19
28
  * @param {300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308} status
@@ -1,9 +1,11 @@
1
+ /** @import { ParamDefinition, ParamMatcher } from '@sveltejs/kit/params' */
2
+
1
3
  /**
2
4
  * Define [parameter matchers](https://svelte.dev/docs/kit/advanced-routing#Matching) for your app.
3
5
  *
4
6
  * @example
5
7
  * ```js
6
- * import { defineParams } from '@sveltejs/kit';
8
+ * import { defineParams } from '@sveltejs/kit/params';
7
9
  * import * as v from 'valibot';
8
10
  *
9
11
  * export const params = defineParams({
@@ -31,8 +33,8 @@ export function defineParams(definitions) {
31
33
  }
32
34
 
33
35
  /**
34
- * @param {import('@sveltejs/kit').ParamDefinition} definition
35
- * @returns {import('@sveltejs/kit').ParamMatcher}
36
+ * @param {ParamDefinition} definition
37
+ * @returns {ParamMatcher}
36
38
  */
37
39
  export function normalize_param_definition(definition) {
38
40
  // standard schemas can be callable (e.g. ArkType), so this must be checked before the function case
@@ -45,7 +47,7 @@ export function normalize_param_definition(definition) {
45
47
  }
46
48
 
47
49
  if (typeof definition === 'function') {
48
- return /** @type {import('@sveltejs/kit').ParamMatcher} */ (
50
+ return /** @type {ParamMatcher} */ (
49
51
  /** @type {unknown} */ ({
50
52
  '~standard': {
51
53
  validate(/** @type {unknown} */ value) {
@@ -0,0 +1,63 @@
1
+ import { StandardSchemaV1 } from '@standard-schema/spec';
2
+
3
+ /**
4
+ * The shape of a param matcher. See [matching](https://svelte.dev/docs/kit/advanced-routing#Matching) for more info.
5
+ */
6
+ export type ParamMatcher<Output = any> = StandardSchemaV1<string, Output>;
7
+
8
+ /**
9
+ * A value that can be parsed from a URL param and losslessly encoded with `String(...)`.
10
+ */
11
+ export type ParamValue = string | number | boolean | bigint;
12
+
13
+ /**
14
+ * A param matcher definition passed to [`defineParams`](https://svelte.dev/docs/kit/@sveltejs-kit#defineParams).
15
+ */
16
+ export type ParamDefinition =
17
+ | ((param: string) => ParamValue | undefined)
18
+ | StandardSchemaV1<string, ParamValue>;
19
+
20
+ /**
21
+ * The return type of [`defineParams`](https://svelte.dev/docs/kit/@sveltejs-kit#defineParams).
22
+ */
23
+ export type DefinedParams<T extends Record<string, ParamDefinition>> = {
24
+ readonly [K in keyof T]: ParamEntry<T[K]>;
25
+ };
26
+
27
+ /**
28
+ * Normalizes a property of defineParams (schema or function) to standard schema.
29
+ */
30
+ type ParamEntry<M> =
31
+ M extends StandardSchemaV1<any, any>
32
+ ? StandardSchemaV1.InferOutput<M> extends ParamValue
33
+ ? StandardSchemaV1<any, M>
34
+ : StandardSchemaV1<any, never>
35
+ : M extends (param: string) => infer R
36
+ ? Exclude<R, undefined> extends ParamValue
37
+ ? StandardSchemaV1<any, Exclude<R, undefined>>
38
+ : StandardSchemaV1<any, never>
39
+ : never;
40
+
41
+ /**
42
+ * Extracts the param type from a matcher.
43
+ */
44
+ export type MatcherParam<M extends StandardSchemaV1<any, any>> =
45
+ M extends StandardSchemaV1<any, infer Inner>
46
+ ? Inner extends ParamValue
47
+ ? Inner
48
+ : Inner extends StandardSchemaV1<any, any>
49
+ ? StandardSchemaV1.InferOutput<Inner> extends ParamValue
50
+ ? StandardSchemaV1.InferOutput<Inner>
51
+ : never
52
+ : never
53
+ : never;
54
+
55
+ /**
56
+ * Define [parameter matchers](https://svelte.dev/docs/kit/advanced-routing#Matching) for your app.
57
+ *
58
+ * @template T
59
+ * @param definitions
60
+ */
61
+ export function defineParams<T extends Record<string, ParamDefinition>>(
62
+ definitions: T
63
+ ): DefinedParams<T>;