@sveltejs/kit 3.0.0-next.1 → 3.0.0-next.11

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 (144) hide show
  1. package/package.json +33 -21
  2. package/src/constants.js +2 -0
  3. package/src/core/adapt/builder.js +32 -49
  4. package/src/core/adapt/index.js +1 -4
  5. package/src/core/config/index.js +137 -71
  6. package/src/core/config/options.js +236 -244
  7. package/src/core/config/types.d.ts +1 -1
  8. package/src/core/env.js +121 -5
  9. package/src/core/generate_manifest/index.js +12 -15
  10. package/src/core/postbuild/analyse.js +7 -19
  11. package/src/core/postbuild/crawl.js +22 -6
  12. package/src/core/postbuild/fallback.js +2 -1
  13. package/src/core/postbuild/prerender.js +114 -48
  14. package/src/core/postbuild/queue.js +2 -1
  15. package/src/core/sync/create_manifest_data/index.js +53 -50
  16. package/src/core/sync/sync.js +0 -2
  17. package/src/core/sync/write_client_manifest.js +8 -15
  18. package/src/core/sync/write_env.js +2 -1
  19. package/src/core/sync/write_non_ambient.js +12 -9
  20. package/src/core/sync/write_server.js +14 -15
  21. package/src/core/sync/write_tsconfig.js +16 -8
  22. package/src/core/sync/write_tsconfig_test/package.json +7 -0
  23. package/src/core/sync/write_types/index.js +28 -24
  24. package/src/core/utils.js +30 -5
  25. package/src/exports/env/index.js +77 -0
  26. package/src/exports/hooks/index.js +3 -9
  27. package/src/exports/hooks/sequence.js +3 -2
  28. package/src/exports/index.js +35 -13
  29. package/src/exports/internal/client.js +5 -0
  30. package/src/exports/internal/env.js +8 -5
  31. package/src/exports/internal/index.js +1 -90
  32. package/src/exports/internal/{event.js → server/event.js} +1 -2
  33. package/src/exports/internal/server/index.js +33 -0
  34. package/src/exports/internal/shared.js +89 -0
  35. package/src/exports/node/index.js +62 -15
  36. package/src/exports/params.js +68 -0
  37. package/src/exports/public.d.ts +363 -189
  38. package/src/exports/url.js +86 -0
  39. package/src/exports/vite/build/build_server.js +53 -59
  40. package/src/exports/vite/build/remote.js +18 -11
  41. package/src/exports/vite/build/utils.js +0 -8
  42. package/src/exports/vite/dev/index.js +92 -50
  43. package/src/exports/vite/index.js +903 -681
  44. package/src/exports/vite/module_ids.js +0 -2
  45. package/src/exports/vite/preview/index.js +32 -24
  46. package/src/exports/vite/static_analysis/index.js +2 -4
  47. package/src/exports/vite/static_analysis/types.d.ts +14 -0
  48. package/src/exports/vite/utils.js +40 -35
  49. package/src/runtime/app/env/internal.js +4 -4
  50. package/src/runtime/app/env/types.d.ts +1 -1
  51. package/src/runtime/app/environment/index.js +3 -3
  52. package/src/runtime/app/forms.js +24 -7
  53. package/src/runtime/app/paths/client.js +4 -10
  54. package/src/runtime/app/paths/internal/client.js +4 -2
  55. package/src/runtime/app/paths/internal/server.js +2 -23
  56. package/src/runtime/app/paths/public.d.ts +0 -28
  57. package/src/runtime/app/paths/server.js +10 -6
  58. package/src/runtime/app/server/index.js +1 -1
  59. package/src/runtime/app/server/remote/command.js +0 -3
  60. package/src/runtime/app/server/remote/form.js +27 -15
  61. package/src/runtime/app/server/remote/prerender.js +29 -36
  62. package/src/runtime/app/server/remote/query.js +101 -99
  63. package/src/runtime/app/server/remote/requested.js +22 -14
  64. package/src/runtime/app/server/remote/shared.js +30 -26
  65. package/src/runtime/app/state/client.js +1 -2
  66. package/src/runtime/app/stores.js +13 -76
  67. package/src/runtime/client/bundle.js +1 -1
  68. package/src/runtime/client/client-entry.js +3 -0
  69. package/src/runtime/client/client.js +411 -318
  70. package/src/runtime/client/entry.js +24 -3
  71. package/src/runtime/client/fetcher.js +3 -2
  72. package/src/runtime/client/ndjson.js +6 -33
  73. package/src/runtime/client/payload.js +17 -0
  74. package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
  75. package/src/runtime/client/remote-functions/command.svelte.js +7 -32
  76. package/src/runtime/client/remote-functions/form.svelte.js +183 -112
  77. package/src/runtime/client/remote-functions/prerender.svelte.js +29 -8
  78. package/src/runtime/client/remote-functions/query/index.js +7 -14
  79. package/src/runtime/client/remote-functions/query/instance.svelte.js +63 -18
  80. package/src/runtime/client/remote-functions/query/proxy.js +3 -3
  81. package/src/runtime/client/remote-functions/query-batch.svelte.js +60 -68
  82. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +60 -18
  83. package/src/runtime/client/remote-functions/query-live/iterator.js +36 -55
  84. package/src/runtime/client/remote-functions/shared.svelte.js +88 -62
  85. package/src/runtime/client/sse.js +32 -0
  86. package/src/runtime/client/state.svelte.js +65 -49
  87. package/src/runtime/client/stream.js +39 -0
  88. package/src/runtime/client/types.d.ts +11 -7
  89. package/src/runtime/client/utils.js +0 -96
  90. package/src/runtime/components/root.svelte +66 -0
  91. package/src/runtime/env/dynamic/private.js +7 -0
  92. package/src/runtime/env/dynamic/public.js +7 -0
  93. package/src/runtime/env/static/private.js +6 -0
  94. package/src/runtime/env/static/public.js +6 -0
  95. package/src/runtime/form-utils.js +100 -22
  96. package/src/runtime/server/cookie.js +69 -52
  97. package/src/runtime/server/csrf.js +65 -0
  98. package/src/runtime/server/data/index.js +15 -19
  99. package/src/runtime/server/env_module.js +0 -5
  100. package/src/runtime/server/errors.js +135 -0
  101. package/src/runtime/server/fetch.js +1 -1
  102. package/src/runtime/server/index.js +22 -12
  103. package/src/runtime/server/internal.js +25 -0
  104. package/src/runtime/server/page/actions.js +43 -27
  105. package/src/runtime/server/page/data_serializer.js +10 -10
  106. package/src/runtime/server/page/index.js +12 -17
  107. package/src/runtime/server/page/load_data.js +2 -2
  108. package/src/runtime/server/page/render.js +114 -193
  109. package/src/runtime/server/page/respond_with_error.js +11 -11
  110. package/src/runtime/server/page/server_routing.js +27 -18
  111. package/src/runtime/server/remote-functions.js +596 -0
  112. package/src/runtime/server/respond.js +100 -68
  113. package/src/runtime/server/sourcemaps.js +183 -0
  114. package/src/runtime/server/utils.js +2 -134
  115. package/src/runtime/shared.js +83 -13
  116. package/src/runtime/telemetry/otel.js +1 -1
  117. package/src/runtime/types.d.ts +8 -0
  118. package/src/types/ambient-private.d.ts +2 -0
  119. package/src/types/ambient.d.ts +10 -5
  120. package/src/types/global-private.d.ts +13 -25
  121. package/src/types/internal.d.ts +95 -80
  122. package/src/types/private.d.ts +41 -1
  123. package/src/utils/error.js +24 -4
  124. package/src/utils/escape.js +9 -25
  125. package/src/utils/features.js +1 -1
  126. package/src/utils/fork.js +7 -2
  127. package/src/utils/import.js +6 -1
  128. package/src/utils/imports.js +83 -0
  129. package/src/utils/mime.js +9 -0
  130. package/src/utils/page_nodes.js +3 -5
  131. package/src/utils/params.js +66 -0
  132. package/src/utils/routing.js +90 -44
  133. package/src/utils/shared-iterator.js +5 -0
  134. package/src/utils/streaming.js +14 -4
  135. package/src/utils/url.js +20 -2
  136. package/src/version.js +1 -1
  137. package/types/index.d.ts +537 -557
  138. package/types/index.d.ts.map +24 -39
  139. package/src/core/sync/write_root.js +0 -148
  140. package/src/exports/internal/server.js +0 -22
  141. package/src/runtime/server/remote.js +0 -457
  142. package/src/runtime/shared-server.js +0 -7
  143. package/src/types/synthetic/$lib.md +0 -5
  144. /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
@@ -15,7 +15,6 @@ import { escape_html } from '../../utils/escape.js';
15
15
  * config: import('types').ValidatedConfig;
16
16
  * has_service_worker: boolean;
17
17
  * template: string;
18
- * error_page: string;
19
18
  * }} opts
20
19
  */
21
20
  const server_template = ({
@@ -23,18 +22,15 @@ const server_template = ({
23
22
  server_hooks,
24
23
  universal_hooks,
25
24
  has_service_worker,
26
- template,
27
- error_page
25
+ template
28
26
  }) => `
29
- import root from '../root.js';
30
27
  import { set_building, set_prerendering } from '$app/env/internal';
31
28
  import { set_assets } from '$app/paths/internal/server';
32
- import { set_manifest, set_read_implementation } from '__sveltekit/server';
33
- import { set_env } from '__sveltekit/env';
29
+ import { set_fix_stack_trace, set_manifest, set_read_implementation } from '__sveltekit/server';
30
+ import error from '../shared/error-template.js';
34
31
 
35
32
  export const options = {
36
33
  app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')},
37
- async: ${s(!!config.compilerOptions?.experimental?.async)},
38
34
  csp: ${s(config.kit.csp)},
39
35
  csrf_check_origin: ${s(!config.kit.csrf.trustedOrigins.includes('*'))},
40
36
  csrf_trusted_origins: ${s(config.kit.csrf.trustedOrigins)},
@@ -42,10 +38,9 @@ export const options = {
42
38
  hash_routing: ${s(config.kit.router.type === 'hash')},
43
39
  hooks: null, // added lazily, via \`get_hooks\`
44
40
  link_header_preload: ${s(config.kit.output.linkHeaderPreload)},
45
- root,
41
+ paths_origin: ${s(config.kit.paths.origin)},
46
42
  service_worker: ${has_service_worker},
47
43
  service_worker_options: ${config.kit.serviceWorker.register ? s(config.kit.serviceWorker.options) : 'null'},
48
- server_error_boundaries: ${s(!!config.kit.experimental.handleRenderingErrors)},
49
44
  templates: {
50
45
  app: ({ head, body, assets, nonce, env }) => ${s(template)
51
46
  .replace('%sveltekit.head%', '" + head + "')
@@ -57,9 +52,7 @@ export const options = {
57
52
  /%sveltekit\.env\.([^%]+)%/g,
58
53
  (_match, capture) => `" + (env[${s(capture)}] ?? "") + "`
59
54
  )},
60
- error: ({ status, message }) => ${s(error_page)
61
- .replace(/%sveltekit\.status%/g, '" + status + "')
62
- .replace(/%sveltekit\.error\.message%/g, '" + message + "')}
55
+ error
63
56
  },
64
57
  version_hash: ${s(hash(config.kit.version.name))}
65
58
  };
@@ -87,7 +80,7 @@ export async function get_hooks() {
87
80
  };
88
81
  }
89
82
 
90
- export { set_assets, set_building, set_env, set_manifest, set_prerendering, set_read_implementation };
83
+ export { set_assets, set_building, set_fix_stack_trace, set_manifest, set_prerendering, set_read_implementation };
91
84
  `;
92
85
 
93
86
  // TODO need to re-run this whenever src/app.html or src/error.html are
@@ -120,6 +113,13 @@ export function write_server(config, output, root) {
120
113
  return posixify(path.relative(`${output}/server`, file));
121
114
  }
122
115
 
116
+ write_if_changed(
117
+ `${output}/shared/error-template.js`,
118
+ `export default ({ status, message }) => ${s(load_error_page(config))
119
+ .replace(/%sveltekit\.status%/g, '" + status + "')
120
+ .replace(/%sveltekit\.error\.message%/g, '" + message + "')};`
121
+ );
122
+
123
123
  // Contains the stringified version of
124
124
  /** @type {import('types').SSROptions} */
125
125
  write_if_changed(
@@ -130,8 +130,7 @@ export function write_server(config, output, root) {
130
130
  universal_hooks: universal_hooks_file ? relative(universal_hooks_file) : null,
131
131
  has_service_worker:
132
132
  config.kit.serviceWorker.register && !!resolve_entry(config.kit.files.serviceWorker),
133
- template: load_template(root, config),
134
- error_page: load_error_page(config)
133
+ template: load_template(root, config)
135
134
  })
136
135
  );
137
136
  }
@@ -2,6 +2,7 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { styleText } from 'node:util';
4
4
  import { posixify } from '../../utils/os.js';
5
+ import { read_package_imports, normalize_import_value } from '../../utils/imports.js';
5
6
  import { write_if_changed } from './utils.js';
6
7
 
7
8
  /**
@@ -62,11 +63,10 @@ export function get_tsconfig(kit, cwd) {
62
63
  'env.d.ts',
63
64
  'non-ambient.d.ts',
64
65
  './types/**/$types.d.ts',
65
- config_relative('svelte.config.js'),
66
66
  config_relative('vite.config.js'),
67
67
  config_relative('vite.config.ts')
68
68
  ]);
69
- const src_includes = [kit.files.routes, kit.files.lib, kit.files.src].filter((dir) => {
69
+ const src_includes = [kit.files.routes, kit.files.src].filter((dir) => {
70
70
  const relative = path.relative(kit.files.src, dir);
71
71
  return !relative || relative.startsWith('..');
72
72
  });
@@ -125,8 +125,7 @@ export function get_tsconfig(kit, cwd) {
125
125
  moduleResolution: 'bundler',
126
126
  module: 'esnext',
127
127
  noEmit: true, // prevent tsconfig error "overwriting input files" - Vite handles the build and ignores this
128
- target: 'esnext',
129
- types: ['node']
128
+ target: 'esnext'
130
129
  },
131
130
  include: [...include],
132
131
  exclude
@@ -176,7 +175,7 @@ function validate_user_config(cwd, out, config) {
176
175
  styleText(
177
176
  ['bold', 'yellow'],
178
177
  `You have specified a baseUrl and/or paths in your ${config.kind} which interferes with SvelteKit's auto-generated tsconfig.json. ` +
179
- 'Remove it to avoid problems with intellisense. For path aliases, use `kit.alias` instead: https://svelte.dev/docs/kit/configuration#alias'
178
+ 'Remove it to avoid problems with intellisense. For path aliases, use `config.alias` instead: https://svelte.dev/docs/kit/configuration#alias'
180
179
  )
181
180
  );
182
181
  }
@@ -200,7 +199,7 @@ const alias_regex = /^(.+?)(\/\*)?$/;
200
199
  const value_regex = /^(.*?)((\/\*)|(\.\w+))?$/;
201
200
 
202
201
  /**
203
- * Generates tsconfig path aliases from kit's aliases.
202
+ * Generates tsconfig path aliases from kit's aliases and the package.json `imports` field.
204
203
  * Related to vite alias creation.
205
204
  *
206
205
  * @param {import('types').ValidatedKitConfig} config
@@ -217,8 +216,17 @@ function get_tsconfig_paths(config, cwd) {
217
216
  };
218
217
 
219
218
  const alias = { ...config.alias };
220
- if (fs.existsSync(project_relative(cwd, config.files.lib))) {
221
- alias['$lib'] = project_relative(cwd, config.files.lib);
219
+
220
+ // Add all `#`-prefixed imports from package.json as path aliases
221
+ const imports = read_package_imports(cwd);
222
+ if (imports) {
223
+ for (const [key, raw_value] of Object.entries(imports)) {
224
+ if (!key.startsWith('#')) continue;
225
+ const value = normalize_import_value(raw_value);
226
+ if (value) {
227
+ alias[key] = value;
228
+ }
229
+ }
222
230
  }
223
231
 
224
232
  /** @type {Record<string, string[]>} */
@@ -0,0 +1,7 @@
1
+ {
2
+ "private": true,
3
+ "imports": {
4
+ "#lib": "./src/lib",
5
+ "#lib/*": "./src/lib/*"
6
+ }
7
+ }
@@ -1,7 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import MagicString from 'magic-string';
4
- import { rimraf, walk } from '../../../utils/filesystem.js';
4
+ import { rimraf, walk, resolve_entry } from '../../../utils/filesystem.js';
5
5
  import { compact } from '../../../utils/array.js';
6
6
  import { posixify } from '../../../utils/os.js';
7
7
  import { ts } from '../ts.js';
@@ -198,11 +198,6 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
198
198
  // Makes sure a type is "repackaged" and therefore more readable
199
199
  declarations.push('type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;');
200
200
 
201
- // returns the predicate of a matcher's type guard - or string if there is no type guard
202
- declarations.push(
203
- 'type MatcherParam<M> = M extends (param : string) => param is (infer U extends string) ? U : string;'
204
- );
205
-
206
201
  declarations.push(
207
202
  'type RouteParams = ' + generate_params_type(route.params, outdir, config) + ';'
208
203
  );
@@ -236,7 +231,9 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
236
231
  'type OptionalUnion<U extends Record<string, any>, A extends keyof U = U extends U ? keyof U : never> = U extends unknown ? { [P in Exclude<A, keyof U>]?: never } & U : never;',
237
232
 
238
233
  // Re-export `Snapshot` from @sveltejs/kit — in future we could use this to infer <T> from the return type of `snapshot.capture`
239
- 'export type Snapshot<T = any> = Kit.Snapshot<T>;'
234
+ 'export type Snapshot<T = any> = Kit.Snapshot<T>;',
235
+
236
+ 'export type ErrorProps = { error: App.Error };'
240
237
  );
241
238
  }
242
239
 
@@ -268,15 +265,8 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
268
265
 
269
266
  if (route.leaf.server) {
270
267
  exports.push(
271
- 'export type Action<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Action<RouteParams, OutputData, RouteId>'
272
- );
273
- exports.push(
274
- 'export type Actions<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Actions<RouteParams, OutputData, RouteId>'
275
- );
276
- }
277
-
278
- if (route.leaf.server) {
279
- exports.push(
268
+ 'export type Action<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Action<RouteParams, OutputData, RouteId>',
269
+ 'export type Actions<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Actions<RouteParams, OutputData, RouteId>',
280
270
  'export type PageProps = { params: RouteParams; data: PageData; form: ActionData }'
281
271
  );
282
272
  } else {
@@ -604,16 +594,22 @@ function replace_ext_with_js(file_path) {
604
594
  * @param {import('types').ValidatedConfig} config
605
595
  */
606
596
  function generate_params_type(params, outdir, config) {
607
- /** @param {string} matcher */
608
- const path_to_matcher = (matcher) =>
609
- posixify(path.relative(outdir, path.join(config.kit.files.params, matcher + '.js')));
597
+ const path_to_params = () => {
598
+ const params_file =
599
+ resolve_entry(config.kit.files.params) ??
600
+ config.kit.files.params.replace(/\.(js|ts)$/, '') + '.js';
601
+
602
+ return posixify(path.relative(outdir, params_file));
603
+ };
604
+
605
+ const params_import = path_to_params();
610
606
 
611
607
  return `{ ${params
612
608
  .map(
613
609
  (param) =>
614
- `${param.name}${param.optional ? '?' : ''}: ${
610
+ `${/^\w+$/.test(param.name) ? param.name : `'${param.name}'`}${param.optional ? '?' : ''}: ${
615
611
  param.matcher
616
- ? `MatcherParam<typeof import('${path_to_matcher(param.matcher)}').match>`
612
+ ? `import('@sveltejs/kit').MatcherParam<(typeof import('${params_import}').params)[${JSON.stringify(param.matcher)}]>`
617
613
  : 'string'
618
614
  }${param.optional ? ' | undefined' : ''}`
619
615
  )
@@ -642,6 +638,16 @@ export function tweak_types(content, is_server) {
642
638
  const code = new MagicString(content);
643
639
 
644
640
  const exports = new Map();
641
+ /** @param {import('typescript').BindingName} name */
642
+ function add_export(name) {
643
+ if (ts.isIdentifier(name)) {
644
+ if (names.has(name.text)) exports.set(name.text, name.text);
645
+ } else {
646
+ for (const element of name.elements) {
647
+ if (ts.isBindingElement(element)) add_export(element.name);
648
+ }
649
+ }
650
+ }
645
651
 
646
652
  ast.forEachChild((node) => {
647
653
  if (
@@ -668,9 +674,7 @@ export function tweak_types(content, is_server) {
668
674
 
669
675
  if (ts.isVariableStatement(node)) {
670
676
  node.declarationList.declarations.forEach((declaration) => {
671
- if (ts.isIdentifier(declaration.name) && names.has(declaration.name.text)) {
672
- exports.set(declaration.name.text, declaration.name.text);
673
- }
677
+ add_export(declaration.name);
674
678
  });
675
679
  }
676
680
  }
package/src/core/utils.js CHANGED
@@ -7,7 +7,7 @@ import { noop } from '../utils/functions.js';
7
7
  import { posixify } from '../utils/os.js';
8
8
 
9
9
  /**
10
- * Resolved path of the `runtime` directory
10
+ * Resolved path of the `runtime` directory posix-ified
11
11
  *
12
12
  * TODO Windows issue:
13
13
  * Vite or sth else somehow sets the driver letter inconsistently to lower or upper case depending on the run environment.
@@ -25,23 +25,48 @@ export const runtime_directory = posixify(fileURLToPath(new URL('../runtime', im
25
25
  */
26
26
  export function get_runtime_base(root) {
27
27
  return runtime_directory.startsWith(root)
28
- ? `/${path.relative(root, runtime_directory)}`
28
+ ? `/${posixify(path.relative(root, runtime_directory))}`
29
29
  : to_fs(runtime_directory);
30
30
  }
31
31
 
32
32
  /** @param {{ verbose: boolean }} opts */
33
- export function logger({ verbose }) {
33
+ export function logger({ verbose } = { verbose: true }) {
34
34
  /** @type {import('types').Logger} */
35
- const log = (msg) => console.log(msg.replace(/^/gm, ' '));
35
+ const log = (msg) => console.log(msg);
36
36
 
37
37
  /** @param {string} msg */
38
- const err = (msg) => console.error(msg.replace(/^/gm, ' '));
38
+ const err = (msg) => console.error(msg);
39
39
 
40
40
  log.success = (msg) => log(styleText('green', `✔ ${msg}`));
41
41
  log.error = (msg) => err(styleText(['bold', 'red'], msg));
42
42
  log.warn = (msg) => log(styleText(['bold', 'yellow'], msg));
43
43
  log.minor = verbose ? (msg) => log(styleText('grey', msg)) : noop;
44
44
  log.info = verbose ? log : noop;
45
+ log.err = err;
46
+
47
+ log.prettyError = (error, caller) => {
48
+ /** @type {unknown} */
49
+ let e = error;
50
+
51
+ while (e instanceof Error) {
52
+ let stack = e.stack;
53
+ if (stack) {
54
+ if (caller) {
55
+ const i = stack.indexOf(caller);
56
+ // Cut the stack trace off at the point when our internal one starts
57
+ stack = stack.slice(0, stack.lastIndexOf('\n', i));
58
+ }
59
+
60
+ err(stack);
61
+ }
62
+
63
+ e = e.cause;
64
+ }
65
+
66
+ if (e) {
67
+ err(String(e));
68
+ }
69
+ };
45
70
 
46
71
  return log;
47
72
  }
@@ -0,0 +1,77 @@
1
+ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */
2
+ /** @import { DefinedEnvVars, EnvVarConfig } from '@sveltejs/kit' */
3
+
4
+ /**
5
+ * Utility for defining [environment variables](https://svelte.dev/docs/kit/environment-variables),
6
+ * which are made available via `$app/env/public` and `$app/env/private`.
7
+ *
8
+ * @example
9
+ * ```js
10
+ * import { defineEnvVars } from '@sveltejs/kit/env';
11
+ * import * as v from 'valibot';
12
+ *
13
+ * export const variables = defineEnvVars({
14
+ * API_URL: {
15
+ * schema: v.pipe(v.string(), v.url())
16
+ * },
17
+ * PORT: {
18
+ * schema: (value) => {
19
+ * if (value === undefined) return 3000;
20
+ * const port = Number(value);
21
+ * if (!Number.isInteger(port)) throw new Error('PORT must be an integer');
22
+ * return port;
23
+ * }
24
+ * }
25
+ * });
26
+ * ```
27
+ *
28
+ * @template {Record<string, EnvVarConfig<any>>} T
29
+ * @param {T} variables
30
+ * @returns {DefinedEnvVars<T>}
31
+ */
32
+ export function defineEnvVars(variables) {
33
+ /** @type {Record<string, EnvVarConfig<any>>} */
34
+ const normalized = {};
35
+
36
+ for (const [name, config] of Object.entries(variables)) {
37
+ // standard schemas can be callable (e.g. ArkType), so a function is only a validator if it isn't one
38
+ normalized[name] =
39
+ typeof config.schema === 'function' && !('~standard' in config.schema)
40
+ ? { ...config, schema: normalize_env_schema(config.schema) }
41
+ : config;
42
+ }
43
+
44
+ return /** @type {DefinedEnvVars<T>} */ (normalized);
45
+ }
46
+
47
+ /**
48
+ * @param {(value: string | undefined) => any} fn
49
+ * @returns {StandardSchemaV1<string | undefined, any>}
50
+ */
51
+ function normalize_env_schema(fn) {
52
+ return /** @type {StandardSchemaV1<string | undefined, any>} */ (
53
+ /** @type {unknown} */ ({
54
+ '~standard': {
55
+ validate(/** @type {unknown} */ value) {
56
+ let result;
57
+
58
+ try {
59
+ result = fn(/** @type {string | undefined} */ (value));
60
+ } catch (error) {
61
+ return {
62
+ issues: [
63
+ {
64
+ message: error instanceof Error ? error.message || 'Invalid value' : String(error)
65
+ }
66
+ ]
67
+ };
68
+ }
69
+
70
+ if (result instanceof Promise) return result; // will be rejected upstream
71
+
72
+ return { value: result };
73
+ }
74
+ }
75
+ })
76
+ );
77
+ }
@@ -1,14 +1,8 @@
1
- /** @import { EnvVarConfig } from '@sveltejs/kit' */
2
-
3
1
  export { sequence } from './sequence.js';
4
2
 
5
3
  /**
6
- * Utility for defining [environment variables](https://svelte.dev/docs/kit/environment-variables),
7
- * which are made available via `$app/env/public` and `$app/env/private`.
8
- * @template {Record<string, EnvVarConfig<any>>} T
9
- * @param {T} variables
10
- * @returns {T}
4
+ * @internal
11
5
  */
12
- export function defineEnvVars(variables) {
13
- return variables;
6
+ export function defineEnvVars() {
7
+ throw new Error(`\`defineEnvVars\` has moved — import it from \`@sveltejs/kit/env\` instead`);
14
8
  }
@@ -1,5 +1,4 @@
1
1
  /** @import { Handle, RequestEvent, ResolveOptions } from '@sveltejs/kit' */
2
- /** @import { MaybePromise } from 'types' */
3
2
  import {
4
3
  merge_tracing,
5
4
  get_request_store,
@@ -74,6 +73,8 @@ import {
74
73
  * first post-processing
75
74
  * ```
76
75
  *
76
+ * Calling `resolve` invokes the next handler in the sequence (or SvelteKit itself, if it is the last one). To pass data between handlers, use `event.locals`.
77
+ *
77
78
  * @param {...Handle} handlers The chain of `handle` functions
78
79
  * @returns {Handle}
79
80
  */
@@ -89,7 +90,7 @@ export function sequence(...handlers) {
89
90
  * @param {number} i
90
91
  * @param {RequestEvent} event
91
92
  * @param {ResolveOptions | undefined} parent_options
92
- * @returns {MaybePromise<Response>}
93
+ * @returns {Promise<Response>}
93
94
  */
94
95
  function apply_handle(i, event, parent_options) {
95
96
  const handle = handlers[i];
@@ -1,6 +1,5 @@
1
1
  /** @import { StandardSchemaV1 } from '@standard-schema/spec' */
2
-
3
- import { HttpError, Redirect, ActionFailure, ValidationError } from './internal/index.js';
2
+ import { HttpError, Redirect, ActionFailure, ValidationError } from './internal/shared.js';
4
3
  import { BROWSER, DEV } from 'esm-env';
5
4
  import {
6
5
  add_data_suffix,
@@ -11,8 +10,10 @@ import {
11
10
  strip_resolution_suffix
12
11
  } from '../runtime/pathname.js';
13
12
  import { text_encoder } from '../runtime/utils.js';
13
+ import { validate_redirect_location } from './url.js';
14
14
 
15
15
  export { VERSION } from '../version.js';
16
+ export { defineParams } from './params.js';
16
17
 
17
18
  // Keep the status codes as `number` because restricting to certain numbers makes it unnecessarily hard to use compared to the benefits
18
19
  // (we have runtime errors already to check for invalid codes). Also see https://github.com/sveltejs/kit/issues/11780
@@ -26,10 +27,10 @@ export { VERSION } from '../version.js';
26
27
  * return an error response without invoking `handleError`.
27
28
  * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
28
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.
29
- * @param {App.Error} body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
30
+ * @param {Omit<App.Error, 'status'> & { status?: App.Error['status'] }} body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
30
31
  * @overload
31
32
  * @param {number} status
32
- * @param {App.Error} body
33
+ * @param {Omit<App.Error, 'status'> & { status?: App.Error['status'] }} body
33
34
  * @return {never}
34
35
  * @throws {import('./public.js').HttpError} This error instructs SvelteKit to initiate HTTP error handling.
35
36
  * @throws {Error} If the provided status is invalid (not between 400 and 599).
@@ -40,10 +41,10 @@ export { VERSION } from '../version.js';
40
41
  * return an error response without invoking `handleError`.
41
42
  * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
42
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.
43
- * @param {{ message: string } extends App.Error ? App.Error | string | undefined : never} [body] An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
44
+ * @param {{ status: number; message: string } extends App.Error ? string | void | undefined : never} body The error message.
44
45
  * @overload
45
46
  * @param {number} status
46
- * @param {{ message: string } extends App.Error ? App.Error | string | undefined : never} [body]
47
+ * @param {{ status: number; message: string } extends App.Error ? string | void | undefined : never} body
47
48
  * @return {never}
48
49
  * @throws {import('./public.js').HttpError} This error instructs SvelteKit to initiate HTTP error handling.
49
50
  * @throws {Error} If the provided status is invalid (not between 400 and 599).
@@ -54,17 +55,34 @@ export { VERSION } from '../version.js';
54
55
  * return an error response without invoking `handleError`.
55
56
  * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
56
57
  * @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.
57
- * @param {{ message: string } extends App.Error ? App.Error | string | undefined : never} body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
58
+ * @param {string} body The error message.
59
+ * @param {{ status: number; message: string } extends App.Error ? never : Omit<App.Error, 'status' | 'message'>} properties Additional properties of the App.Error type.
60
+ * @overload
61
+ * @param {number} status
62
+ * @param {string} body
63
+ * @param {{ status: number; message: string } extends App.Error ? never : Omit<App.Error, 'status' | 'message'>} properties
58
64
  * @return {never}
59
65
  * @throws {import('./public.js').HttpError} This error instructs SvelteKit to initiate HTTP error handling.
60
66
  * @throws {Error} If the provided status is invalid (not between 400 and 599).
61
67
  */
62
- export function error(status, body) {
68
+ /**
69
+ * Throws an error with a HTTP status code and an optional message.
70
+ * When called during request handling, this will cause SvelteKit to
71
+ * return an error response without invoking `handleError`.
72
+ * Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
73
+ * @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.
74
+ * @param {any} [body] An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
75
+ * @param {any} [properties] Additional properties of the App.Error type when passing a string message.
76
+ * @return {never}
77
+ * @throws {import('./public.js').HttpError} This error instructs SvelteKit to initiate HTTP error handling.
78
+ * @throws {Error} If the provided status is invalid (not between 400 and 599).
79
+ */
80
+ export function error(status, body, properties) {
63
81
  if ((!BROWSER || DEV) && (isNaN(status) || status < 400 || status > 599)) {
64
82
  throw new Error(`HTTP error status codes must be between 400 and 599 — ${status} is invalid`);
65
83
  }
66
84
 
67
- throw new HttpError(status, body);
85
+ throw new HttpError(status, body, properties);
68
86
  }
69
87
 
70
88
  /**
@@ -92,19 +110,23 @@ export function isHttpError(e, status) {
92
110
  *
93
111
  * @param {300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number)} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages). Must be in the range 300-308.
94
112
  * @param {string | URL} location The location to redirect to.
113
+ * @param {{ external?: boolean | string[] }} [options] To redirect to an external URL, you must pass `{ external: true }` to allow any external URL except `javascript:` URLs, or `{ external: [...] }` with an allowlist of permitted origins.
95
114
  * @throws {import('./public.js').Redirect} This error instructs SvelteKit to redirect to the specified location.
96
- * @throws {Error} If the provided status is invalid or the location cannot be used as a header value.
115
+ * @throws {Error} If the provided status is invalid, the location cannot be used as a header value, or the location is an external URL without permission.
97
116
  * @return {never}
98
117
  */
99
- export function redirect(status, location) {
118
+ export function redirect(status, location, options) {
100
119
  if ((!BROWSER || DEV) && (isNaN(status) || status < 300 || status > 308)) {
101
120
  throw new Error('Invalid status code');
102
121
  }
103
122
 
123
+ const href = location.toString();
124
+ validate_redirect_location(href, options);
125
+
104
126
  throw new Redirect(
105
127
  // @ts-ignore
106
128
  status,
107
- location.toString()
129
+ href
108
130
  );
109
131
  }
110
132
 
@@ -212,7 +234,7 @@ export function isActionFailure(e) {
212
234
  * ```ts
213
235
  * import { invalid } from '@sveltejs/kit';
214
236
  * import { form } from '$app/server';
215
- * import { tryLogin } from '$lib/server/auth';
237
+ * import { tryLogin } from '#lib/server/auth';
216
238
  * import * as v from 'valibot';
217
239
  *
218
240
  * export const login = form(
@@ -0,0 +1,5 @@
1
+ export function get_origin() {
2
+ return window.location.origin;
3
+ }
4
+
5
+ export * from './shared.js';
@@ -1,10 +1,10 @@
1
1
  /** @import { StandardSchemaV1 } from '@standard-schema/spec' */
2
2
  /** @import { EnvVarConfig } from '@sveltejs/kit' */
3
3
 
4
- import { stackless } from '../vite/utils.js';
4
+ import { stackless } from '../../utils/error.js';
5
5
 
6
6
  const MISSING = {
7
- message: `Value is missing. If it is optional, add a Standard Schema validator declaring it as such.`
7
+ message: `Value is missing. If it is optional, add a validator declaring it as such.`
8
8
  };
9
9
 
10
10
  const BAD_VALIDATOR = {
@@ -16,7 +16,7 @@ const ASYNC_VALIDATOR = {
16
16
  };
17
17
 
18
18
  /**
19
- * @param {Record<string, EnvVarConfig<any>>} variables
19
+ * @param {Record<string, EnvVarConfig<any> | undefined>} variables
20
20
  * @param {string | undefined} value
21
21
  * @param {string} name
22
22
  * @param {Record<string, StandardSchemaV1.Issue[]>} issues
@@ -24,10 +24,13 @@ const ASYNC_VALIDATOR = {
24
24
  */
25
25
  export function validate(variables, value, name, issues) {
26
26
  const config = variables[name] ?? {};
27
- const validator = config.schema;
27
+ // `defineEnvVars` normalizes function validators to standard schemas
28
+ const validator = /** @type {StandardSchemaV1<string | undefined, any> | undefined} */ (
29
+ config.schema
30
+ );
28
31
 
29
32
  if (!validator) {
30
- if (!value) issues[name] = [MISSING];
33
+ if (value === undefined) issues[name] = [MISSING];
31
34
  return value;
32
35
  }
33
36