@sveltejs/kit 3.0.0-next.4 → 3.0.0-next.7

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 (91) hide show
  1. package/package.json +23 -18
  2. package/src/core/adapt/builder.js +29 -43
  3. package/src/core/adapt/index.js +1 -4
  4. package/src/core/config/index.js +135 -71
  5. package/src/core/config/options.js +291 -244
  6. package/src/core/config/types.d.ts +1 -1
  7. package/src/core/env.js +120 -5
  8. package/src/core/generate_manifest/index.js +12 -15
  9. package/src/core/postbuild/analyse.js +8 -12
  10. package/src/core/postbuild/crawl.js +22 -6
  11. package/src/core/postbuild/prerender.js +40 -23
  12. package/src/core/sync/create_manifest_data/index.js +29 -49
  13. package/src/core/sync/write_client_manifest.js +14 -14
  14. package/src/core/sync/write_non_ambient.js +10 -7
  15. package/src/core/sync/write_root.js +9 -30
  16. package/src/core/sync/write_server.js +13 -11
  17. package/src/core/sync/write_tsconfig.js +2 -4
  18. package/src/core/sync/write_types/index.js +11 -10
  19. package/src/exports/index.js +34 -12
  20. package/src/exports/internal/client.js +5 -0
  21. package/src/exports/internal/env.js +1 -1
  22. package/src/exports/internal/index.js +1 -90
  23. package/src/exports/internal/{event.js → server/event.js} +1 -2
  24. package/src/exports/internal/server/index.js +33 -0
  25. package/src/exports/internal/shared.js +89 -0
  26. package/src/exports/node/index.js +58 -7
  27. package/src/exports/params.js +63 -0
  28. package/src/exports/public.d.ts +299 -145
  29. package/src/exports/url.js +84 -0
  30. package/src/exports/vite/build/build_server.js +6 -1
  31. package/src/exports/vite/dev/index.js +38 -37
  32. package/src/exports/vite/index.js +498 -353
  33. package/src/exports/vite/preview/index.js +16 -8
  34. package/src/exports/vite/utils.js +7 -11
  35. package/src/runtime/app/env/types.d.ts +1 -1
  36. package/src/runtime/app/forms.js +22 -5
  37. package/src/runtime/app/paths/client.js +4 -10
  38. package/src/runtime/app/paths/public.d.ts +0 -28
  39. package/src/runtime/app/paths/server.js +8 -4
  40. package/src/runtime/app/server/remote/form.js +10 -3
  41. package/src/runtime/app/server/remote/query.js +9 -18
  42. package/src/runtime/app/server/remote/requested.js +8 -4
  43. package/src/runtime/app/server/remote/shared.js +5 -7
  44. package/src/runtime/app/state/client.js +1 -2
  45. package/src/runtime/app/stores.js +13 -76
  46. package/src/runtime/client/client.js +205 -167
  47. package/src/runtime/client/fetcher.js +3 -2
  48. package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
  49. package/src/runtime/client/remote-functions/form.svelte.js +122 -31
  50. package/src/runtime/client/remote-functions/prerender.svelte.js +17 -4
  51. package/src/runtime/client/remote-functions/query/index.js +3 -2
  52. package/src/runtime/client/remote-functions/query/instance.svelte.js +27 -11
  53. package/src/runtime/client/remote-functions/query-batch.svelte.js +4 -3
  54. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +42 -15
  55. package/src/runtime/client/remote-functions/shared.svelte.js +18 -9
  56. package/src/runtime/client/state.svelte.js +66 -49
  57. package/src/runtime/client/types.d.ts +10 -2
  58. package/src/runtime/client/utils.js +0 -96
  59. package/src/runtime/form-utils.js +99 -18
  60. package/src/runtime/server/cookie.js +22 -33
  61. package/src/runtime/server/csrf.js +65 -0
  62. package/src/runtime/server/data/index.js +7 -7
  63. package/src/runtime/server/env_module.js +0 -5
  64. package/src/runtime/server/index.js +2 -2
  65. package/src/runtime/server/page/actions.js +41 -26
  66. package/src/runtime/server/page/index.js +2 -1
  67. package/src/runtime/server/page/load_data.js +1 -1
  68. package/src/runtime/server/page/render.js +36 -47
  69. package/src/runtime/server/page/respond_with_error.js +7 -8
  70. package/src/runtime/server/page/server_routing.js +13 -9
  71. package/src/runtime/server/remote.js +85 -39
  72. package/src/runtime/server/respond.js +92 -58
  73. package/src/runtime/server/utils.js +7 -7
  74. package/src/runtime/telemetry/otel.js +1 -1
  75. package/src/types/ambient.d.ts +10 -5
  76. package/src/types/global-private.d.ts +4 -4
  77. package/src/types/internal.d.ts +17 -20
  78. package/src/types/private.d.ts +33 -1
  79. package/src/types/synthetic/$lib.md +1 -1
  80. package/src/utils/error.js +12 -4
  81. package/src/utils/mime.js +9 -0
  82. package/src/utils/params.js +66 -0
  83. package/src/utils/routing.js +84 -38
  84. package/src/utils/shared-iterator.js +5 -0
  85. package/src/utils/streaming.js +14 -4
  86. package/src/utils/url.js +20 -2
  87. package/src/version.js +1 -1
  88. package/types/index.d.ts +434 -269
  89. package/types/index.d.ts.map +19 -15
  90. package/src/exports/internal/server.js +0 -22
  91. /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "3.0.0-next.4",
3
+ "version": "3.0.0-next.7",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
@@ -18,37 +18,38 @@
18
18
  "homepage": "https://svelte.dev",
19
19
  "type": "module",
20
20
  "dependencies": {
21
- "@standard-schema/spec": "^1.0.0",
22
- "@sveltejs/acorn-typescript": "^1.0.9",
23
- "acorn": "^8.16.0",
24
- "cookie": "^1.1.1",
21
+ "@standard-schema/spec": "^1.1.0",
22
+ "@sveltejs/acorn-typescript": "^1.0.10",
23
+ "acorn": "^8.17.0",
24
+ "cookie": "^2.0.0",
25
25
  "devalue": "^5.8.1",
26
26
  "esm-env": "^1.2.2",
27
- "magic-string": "^0.30.5",
27
+ "magic-string": "^0.30.21",
28
28
  "mrmime": "^2.0.0",
29
- "sirv": "^3.0.0"
29
+ "sirv": "^3.0.2"
30
30
  },
31
31
  "devDependencies": {
32
- "@opentelemetry/api": "^1.0.0",
32
+ "@opentelemetry/api": "^1.9.0",
33
33
  "@playwright/test": "^1.60.0",
34
34
  "@sveltejs/vite-plugin-svelte": "^7.0.0",
35
35
  "@types/connect": "^3.4.38",
36
36
  "@types/node": "^22.19.19",
37
- "dts-buddy": "^0.8.0",
37
+ "dts-buddy": "^0.8.1",
38
38
  "jsdom": "^29.1.1",
39
- "rolldown": "^1.0.0-rc.6",
39
+ "rolldown": "^1.1.2",
40
40
  "svelte": "^5.56.3",
41
41
  "svelte-preprocess": "^6.0.5",
42
- "typescript": "~6.0.0",
43
- "vite": "^8.0.10",
44
- "vitest": "^4.1.7"
42
+ "typescript": "~6.0.3",
43
+ "valibot": "^1.2.0",
44
+ "vite": "^8.0.16",
45
+ "vitest": "^4.1.9"
45
46
  },
46
47
  "peerDependencies": {
47
- "@sveltejs/vite-plugin-svelte": "^7.0.0",
48
48
  "@opentelemetry/api": "^1.0.0",
49
+ "@sveltejs/vite-plugin-svelte": "^7.0.0",
49
50
  "svelte": "^5.48.0",
50
51
  "typescript": "^6.0.0",
51
- "vite": "^8.0.0"
52
+ "vite": "^8.0.12"
52
53
  },
53
54
  "peerDependenciesMeta": {
54
55
  "@opentelemetry/api": {
@@ -77,6 +78,10 @@
77
78
  "#app/env/public": {
78
79
  "browser": "./src/runtime/app/env/public/client.js",
79
80
  "default": "./src/runtime/app/env/public/server.js"
81
+ },
82
+ "#internal": {
83
+ "browser": "./src/exports/internal/client.js",
84
+ "default": "./src/exports/internal/server/index.js"
80
85
  }
81
86
  },
82
87
  "exports": {
@@ -94,11 +99,11 @@
94
99
  "import": "./src/exports/internal/env.js"
95
100
  },
96
101
  "./internal/types": {
97
- "import": "./src/exports/internal/types.js"
102
+ "types": "./src/exports/internal/types.d.ts"
98
103
  },
99
104
  "./internal/server": {
100
105
  "types": "./types/index.d.ts",
101
- "import": "./src/exports/internal/server.js"
106
+ "import": "./src/exports/internal/server/index.js"
102
107
  },
103
108
  "./node": {
104
109
  "types": "./types/index.d.ts",
@@ -119,7 +124,7 @@
119
124
  },
120
125
  "scripts": {
121
126
  "lint": "prettier --config ../../.prettierrc --check .",
122
- "check": "tsc && cd ./test/types && tsc",
127
+ "check": "tsc && cd ./test/types && tsc && cd ./app-error-enhanced && tsc",
123
128
  "check:all": "tsc && pnpm -r --filter=\"./**\" check",
124
129
  "format": "prettier --config ../../.prettierrc --write .",
125
130
  "test": "pnpm test:unit && pnpm test:integration",
@@ -18,11 +18,23 @@ import generate_fallback from '../postbuild/fallback.js';
18
18
  import { write } from '../sync/utils.js';
19
19
  import { list_files } from '../utils.js';
20
20
  import { find_server_assets } from '../generate_manifest/find_server_assets.js';
21
- import { reserved } from '../env.js';
21
+ import { create_exported_declarations } from '../env.js';
22
22
  import { handle_issues, validate } from '../../exports/internal/env.js';
23
23
 
24
24
  const pipe = promisify(pipeline);
25
- const extensions = ['.html', '.js', '.mjs', '.json', '.css', '.svg', '.xml', '.wasm', '.txt'];
25
+ const extensions = [
26
+ '.html',
27
+ '.js',
28
+ '.mjs',
29
+ '.json',
30
+ '.css',
31
+ '.svg',
32
+ '.xml',
33
+ '.wasm',
34
+ '.txt',
35
+ '.md',
36
+ '.mdx'
37
+ ];
26
38
 
27
39
  /**
28
40
  * Creates the Builder which is passed to adapters for building the application.
@@ -125,7 +137,7 @@ export function create_builder({
125
137
  manifest_path,
126
138
  env,
127
139
  out_dir: config.kit.outDir,
128
- origin: config.kit.prerender.origin,
140
+ origin: config.kit.paths.origin || 'http://sveltekit-prerender',
129
141
  assets: config.kit.files.assets
130
142
  });
131
143
 
@@ -144,7 +156,7 @@ export function create_builder({
144
156
  generateEnvModule() {
145
157
  if (!build_data.client?.uses_env_dynamic_public) return;
146
158
 
147
- const dest = `${config.kit.outDir}/output/prerendered/dependencies/${config.kit.appDir}/env.js`;
159
+ const dest = `${config.kit.outDir}/output/prerendered/dependencies/${config.kit.appDir}`;
148
160
  const env = loadEnv(vite_config.mode, config.kit.env.dir, '');
149
161
 
150
162
  /** @type {Record<string, any>} */
@@ -161,7 +173,9 @@ export function create_builder({
161
173
 
162
174
  handle_issues(issues);
163
175
 
164
- write(dest, `export const env=${devalue.uneval(values)}`);
176
+ const payload = devalue.uneval(values);
177
+
178
+ write(`${dest}/env.js`, `export const env=${payload}`);
165
179
  },
166
180
 
167
181
  generateManifest({ relativePath, routes: subset }) {
@@ -291,53 +305,25 @@ async function compress_file(file, format = 'gz') {
291
305
  * - Imports `exports` from the entrypoint (dynamically, if `tla` is true)
292
306
  * - Re-exports `exports` from the entrypoint
293
307
  *
294
- * `default` receives special treatment: It will be imported as `default` and exported with `export default`.
295
- *
296
308
  * @param {{ instrumentation: string; start: string; exports: string[] }} opts
297
309
  * @returns {string}
298
310
  */
299
311
  function create_instrumentation_facade({ instrumentation, start, exports }) {
300
312
  const import_instrumentation = `import './${instrumentation}';`;
301
313
 
302
- let alias_index = 0;
303
- const aliases = new Map();
304
-
305
- for (const name of exports.filter((name) => reserved.has(name))) {
306
- /*
307
- * you can do evil things like `export { c as class }`.
308
- * in order to import these, you need to alias them, and then un-alias them when re-exporting
309
- * this map will allow us to generate the following:
310
- * import { class as _1 } from 'entrypoint';
311
- * export { _1 as class };
312
- */
313
- let alias = `_${alias_index++}`;
314
- while (exports.includes(alias)) {
315
- alias = `_${alias_index++}`;
316
- }
317
-
318
- aliases.set(name, alias);
319
- }
320
-
321
- const import_statements = [];
322
- const export_statements = [];
323
-
324
- for (const name of exports) {
325
- const alias = aliases.get(name);
326
- if (alias) {
327
- import_statements.push(`${name}: ${alias}`);
328
- export_statements.push(`${alias} as ${name}`);
329
- } else {
330
- import_statements.push(`${name}`);
331
- export_statements.push(`${name}`);
332
- }
333
- }
314
+ const { namespace, declarations, reexports } = create_exported_declarations(
315
+ exports,
316
+ (name, ns) => `${ns}.${name}`,
317
+ '__mod'
318
+ );
334
319
 
335
- const entrypoint_facade = [
336
- `const { ${import_statements.join(', ')} } = await import('./${start}');`,
337
- export_statements.length > 0 ? `export { ${export_statements.join(', ')} };` : ''
320
+ const parts = [
321
+ `const ${namespace} = await import('./${start}');`,
322
+ declarations.join('\n'),
323
+ reexports.length > 0 ? `export { ${reexports.join(', ')} };` : ''
338
324
  ]
339
325
  .filter(Boolean)
340
326
  .join('\n');
341
327
 
342
- return `${import_instrumentation}\n${entrypoint_facade}`;
328
+ return `${import_instrumentation}\n${parts}`;
343
329
  }
@@ -1,9 +1,7 @@
1
- /** @import { Adapter } from '@sveltejs/kit' */
2
1
  import { styleText } from 'node:util';
3
2
  import { create_builder } from './builder.js';
4
3
 
5
4
  /**
6
- * @param {Adapter} adapter
7
5
  * @param {import('types').ValidatedConfig} config
8
6
  * @param {import('types').BuildData} build_data
9
7
  * @param {import('types').ServerMetadata} server_metadata
@@ -15,7 +13,6 @@ import { create_builder } from './builder.js';
15
13
  * @param {Record<string, import('@sveltejs/kit').EnvVarConfig<any>> | null} explicit_env_config
16
14
  */
17
15
  export async function adapt(
18
- adapter,
19
16
  config,
20
17
  build_data,
21
18
  server_metadata,
@@ -26,7 +23,7 @@ export async function adapt(
26
23
  vite_config,
27
24
  explicit_env_config
28
25
  ) {
29
- const { name, adapt } = adapter;
26
+ const { name, adapt } = config.kit.adapter;
30
27
 
31
28
  console.log(styleText(['bold', 'cyan'], `\n> Using ${name}`));
32
29
 
@@ -1,14 +1,77 @@
1
- /** @import { Config } from '@sveltejs/kit' */
1
+ /** @import { Config, KitConfig } from '@sveltejs/kit' */
2
+ /** @import { Options, SvelteConfig } from '@sveltejs/vite-plugin-svelte' */
2
3
  /** @import { ValidatedConfig } from 'types' */
3
4
  /** @import { ResolvedConfig } from 'vite' */
4
5
  import fs from 'node:fs';
5
6
  import path from 'node:path';
6
7
  import process from 'node:process';
7
8
  import * as url from 'node:url';
8
- import options from './options.js';
9
+ import {
10
+ validate_kit_options,
11
+ kit_options,
12
+ kit_experimental_options,
13
+ validate_svelte_options
14
+ } from './options.js';
9
15
  import { resolve_entry } from '../../utils/filesystem.js';
10
16
  import { import_peer } from '../../utils/import.js';
11
17
 
18
+ /**
19
+ * Splits the config passed to the `sveltekit` Vite plugin into the options that
20
+ * SvelteKit processes itself and the options that are forwarded to
21
+ * `vite-plugin-svelte`. SvelteKit makes no assumptions about which options
22
+ * `vite-plugin-svelte` accepts — it plucks out its own options and passes
23
+ * everything else along (`vite-plugin-svelte` does its own validation).
24
+ * @param {KitConfig & Omit<Options, 'onwarn'> & Pick<SvelteConfig, 'vitePlugin'>} config
25
+ * @returns {{ svelte_config: Config, vite_plugin_svelte_config: Record<string, any> }}
26
+ */
27
+ export function split_config(config) {
28
+ const { extensions, compilerOptions, vitePlugin, preprocess, ...rest } = config;
29
+
30
+ /** @type {KitConfig} */
31
+ const kit = {};
32
+
33
+ /** @type {Record<string, any>} */
34
+ const vite_plugin_svelte_config = {};
35
+
36
+ for (const key in rest) {
37
+ if (key === 'experimental') {
38
+ // `experimental` is a namespace that both SvelteKit and vite-plugin-svelte
39
+ // use, so pluck out the flags SvelteKit recognises and pass the rest along
40
+ const experimental = /** @type {Record<string, any>} */ (rest[key]) ?? {};
41
+
42
+ /** @type {Record<string, any>} */
43
+ const kit_experimental = {};
44
+ /** @type {Record<string, any>} */
45
+ const vps_experimental = {};
46
+
47
+ for (const flag in experimental) {
48
+ if (kit_experimental_options.includes(flag)) {
49
+ kit_experimental[flag] = experimental[flag];
50
+ } else {
51
+ vps_experimental[flag] = experimental[flag];
52
+ }
53
+ }
54
+
55
+ if (Object.keys(kit_experimental).length > 0) {
56
+ kit.experimental = kit_experimental;
57
+ }
58
+ if (Object.keys(vps_experimental).length > 0) {
59
+ vite_plugin_svelte_config.experimental = vps_experimental;
60
+ }
61
+ } else if (kit_options.includes(key)) {
62
+ // @ts-expect-error - we've verified this is one of SvelteKit's own options
63
+ kit[key] = rest[key];
64
+ } else {
65
+ vite_plugin_svelte_config[key] = /** @type {Record<string, any>} */ (rest)[key];
66
+ }
67
+ }
68
+
69
+ return {
70
+ svelte_config: { extensions, compilerOptions, vitePlugin, preprocess, kit },
71
+ vite_plugin_svelte_config
72
+ };
73
+ }
74
+
12
75
  /**
13
76
  * Loads the template (src/app.html by default) and validates that it has the
14
77
  * required content.
@@ -70,98 +133,99 @@ export async function load_vite_config(config) {
70
133
  */
71
134
  export function extract_svelte_config(vite_config) {
72
135
  const plugin = vite_config.plugins.find((p) => p.name === 'vite-plugin-sveltekit-setup');
73
- return plugin?.api.options ?? process_config({});
136
+ return plugin?.api.options ?? process_config(validate_config({}), vite_config.root);
74
137
  }
75
138
 
76
139
  /**
77
- * @param {Config} config
140
+ * @param {ValidatedConfig} config
141
+ * @param {string} cwd
78
142
  * @returns {ValidatedConfig}
79
143
  */
80
- export function process_config(config, { cwd = process.cwd(), source = 'svelte.config.js' } = {}) {
81
- try {
82
- const validated = validate_config(config, cwd);
83
-
84
- validated.kit.outDir = path.resolve(cwd, validated.kit.outDir);
144
+ export function process_config(config, cwd) {
145
+ if (
146
+ config.kit.csp?.directives?.['require-trusted-types-for']?.includes('script') &&
147
+ config.kit.serviceWorker.register &&
148
+ resolve_entry(path.resolve(cwd, config.kit.files.serviceWorker)) &&
149
+ !config.kit.csp?.directives?.['trusted-types']?.includes('sveltekit-trusted-url')
150
+ ) {
151
+ throw new Error(
152
+ "The `csp.directives['trusted-types']` option must include 'sveltekit-trusted-url' when `serviceWorker.register` is true"
153
+ );
154
+ }
85
155
 
86
- for (const key in validated.kit.files) {
87
- if (key === 'hooks') {
88
- validated.kit.files.hooks.client = path.resolve(cwd, validated.kit.files.hooks.client);
89
- validated.kit.files.hooks.server = path.resolve(cwd, validated.kit.files.hooks.server);
90
- validated.kit.files.hooks.universal = path.resolve(
91
- cwd,
92
- validated.kit.files.hooks.universal
93
- );
94
- } else {
95
- // @ts-expect-error
96
- validated.kit.files[key] = path.resolve(cwd, validated.kit.files[key]);
97
- }
156
+ config.kit.outDir = path.resolve(cwd, config.kit.outDir);
157
+ config.kit.env.dir = path.resolve(cwd, config.kit.env.dir);
158
+
159
+ for (const key in config.kit.files) {
160
+ if (key === 'hooks') {
161
+ config.kit.files.hooks.client = path.resolve(cwd, config.kit.files.hooks.client);
162
+ config.kit.files.hooks.server = path.resolve(cwd, config.kit.files.hooks.server);
163
+ config.kit.files.hooks.universal = path.resolve(cwd, config.kit.files.hooks.universal);
164
+ } else {
165
+ // @ts-expect-error
166
+ config.kit.files[key] = path.resolve(cwd, config.kit.files[key]);
98
167
  }
99
-
100
- return validated;
101
- } catch (e) {
102
- const error = /** @type {Error} */ (e);
103
-
104
- // redact the stack trace — it's not helpful to users
105
- error.stack = `Error loading ${source}: ${error.message}\n`;
106
- throw error;
107
168
  }
169
+
170
+ return config;
108
171
  }
109
172
 
110
173
  /**
111
174
  * @param {Config} config
112
- * @param {string} [cwd]
113
175
  * @returns {ValidatedConfig}
114
176
  */
115
- export function validate_config(config, cwd = process.cwd()) {
116
- if (typeof config !== 'object') {
117
- throw new Error(
118
- 'The Svelte config file must have a configuration object as its default export. See https://svelte.dev/docs/kit/configuration'
119
- );
120
- }
121
-
122
- /** @type {ValidatedConfig} */
123
- const validated = options(config, 'config');
124
- const files = validated.kit.files;
125
-
126
- files.hooks.client ??= path.join(files.src, 'hooks.client');
127
- files.hooks.server ??= path.join(files.src, 'hooks.server');
128
- files.hooks.universal ??= path.join(files.src, 'hooks');
129
- files.lib ??= path.join(files.src, 'lib');
130
- files.params ??= path.join(files.src, 'params');
131
- files.routes ??= path.join(files.src, 'routes');
132
- files.serviceWorker ??= path.join(files.src, 'service-worker');
133
- files.appTemplate ??= path.join(files.src, 'app.html');
134
- files.errorTemplate ??= path.join(files.src, 'error.html');
135
-
136
- if (validated.kit.router.resolution === 'server') {
137
- if (validated.kit.router.type === 'hash') {
138
- throw new Error(
139
- "The `router.resolution` option cannot be 'server' if `router.type` is 'hash'"
140
- );
141
- }
142
- if (validated.kit.output.bundleStrategy !== 'split') {
177
+ export function validate_config(config) {
178
+ try {
179
+ if (typeof config !== 'object') {
143
180
  throw new Error(
144
- "The `router.resolution` option cannot be 'server' if `output.bundleStrategy` is 'inline' or 'single'"
181
+ 'The SvelteKit options from the Vite config must be an object. See https://svelte.dev/docs/kit/configuration'
145
182
  );
146
183
  }
147
- }
148
184
 
149
- if (validated.kit.csp?.directives?.['require-trusted-types-for']?.includes('script')) {
150
- if (!validated.kit.csp?.directives?.['trusted-types']?.includes('svelte-trusted-html')) {
151
- throw new Error(
152
- "The `csp.directives['trusted-types']` option must include 'svelte-trusted-html'"
153
- );
185
+ const validated = /** @type {ValidatedConfig} */ ({
186
+ ...validate_svelte_options(config, 'config'),
187
+ kit: validate_kit_options(config.kit, 'config')
188
+ });
189
+ const files = validated.kit.files;
190
+
191
+ files.hooks.client ??= path.join(files.src, 'hooks.client');
192
+ files.hooks.server ??= path.join(files.src, 'hooks.server');
193
+ files.hooks.universal ??= path.join(files.src, 'hooks');
194
+ files.lib ??= path.join(files.src, 'lib');
195
+ files.params ??= path.join(files.src, 'params');
196
+ files.routes ??= path.join(files.src, 'routes');
197
+ files.serviceWorker ??= path.join(files.src, 'service-worker');
198
+ files.appTemplate ??= path.join(files.src, 'app.html');
199
+ files.errorTemplate ??= path.join(files.src, 'error.html');
200
+
201
+ if (validated.kit.router.resolution === 'server') {
202
+ if (validated.kit.router.type === 'hash') {
203
+ throw new Error(
204
+ "The `router.resolution` option cannot be 'server' if `router.type` is 'hash'"
205
+ );
206
+ }
207
+ if (validated.kit.output.bundleStrategy !== 'split') {
208
+ throw new Error(
209
+ "The `router.resolution` option cannot be 'server' if `output.bundleStrategy` is 'inline' or 'single'"
210
+ );
211
+ }
154
212
  }
213
+
155
214
  if (
156
- validated.kit.serviceWorker?.register &&
157
- resolve_entry(path.resolve(cwd, validated.kit.files.serviceWorker)) &&
158
- !validated.kit.csp?.directives?.['trusted-types']?.includes('sveltekit-trusted-url')
215
+ validated.kit.csp?.directives?.['require-trusted-types-for']?.includes('script') &&
216
+ !validated.kit.csp?.directives?.['trusted-types']?.includes('svelte-trusted-html')
159
217
  ) {
160
218
  throw new Error(
161
- "The `csp.directives['trusted-types']` option must include 'sveltekit-trusted-url' when `serviceWorker.register` is true"
219
+ "The `csp.directives['trusted-types']` option must include 'svelte-trusted-html'"
162
220
  );
163
221
  }
164
- }
165
222
 
166
- return validated;
223
+ return validated;
224
+ } catch (e) {
225
+ const error = /** @type {Error} */ (e);
226
+
227
+ // redact the stack trace — it's not helpful to users
228
+ error.stack = `Error loading SvelteKit options from Vite config: ${error.message}\n`;
229
+ throw error;
230
+ }
167
231
  }