@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "3.0.0-next.1",
3
+ "version": "3.0.0-next.11",
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",
33
- "@playwright/test": "^1.60.0",
32
+ "@opentelemetry/api": "^1.9.0",
33
+ "@playwright/test": "^1.61.1",
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.3",
38
38
  "jsdom": "^29.1.1",
39
- "rolldown": "^1.0.0-rc.6",
40
- "svelte": "^5.55.7",
39
+ "rolldown": "^1.2.0",
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.1.5",
45
+ "vitest": "^4.1.10"
45
46
  },
46
47
  "peerDependencies": {
47
- "@sveltejs/vite-plugin-svelte": "^7.0.0",
48
48
  "@opentelemetry/api": "^1.0.0",
49
- "svelte": "^5.48.0",
49
+ "@sveltejs/vite-plugin-svelte": "^7.0.0",
50
+ "svelte": "^5.56.4",
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": {
@@ -71,12 +72,19 @@
71
72
  ],
72
73
  "imports": {
73
74
  "#app/paths": {
75
+ "workerd": "./src/runtime/app/paths/server.js",
74
76
  "browser": "./src/runtime/app/paths/client.js",
75
77
  "default": "./src/runtime/app/paths/server.js"
76
78
  },
77
79
  "#app/env/public": {
80
+ "workerd": "./src/runtime/app/env/public/server.js",
78
81
  "browser": "./src/runtime/app/env/public/client.js",
79
82
  "default": "./src/runtime/app/env/public/server.js"
83
+ },
84
+ "#internal": {
85
+ "workerd": "./src/exports/internal/server/index.js",
86
+ "browser": "./src/exports/internal/client.js",
87
+ "default": "./src/exports/internal/server/index.js"
80
88
  }
81
89
  },
82
90
  "exports": {
@@ -94,11 +102,11 @@
94
102
  "import": "./src/exports/internal/env.js"
95
103
  },
96
104
  "./internal/types": {
97
- "import": "./src/exports/internal/types.js"
105
+ "types": "./src/exports/internal/types.d.ts"
98
106
  },
99
107
  "./internal/server": {
100
108
  "types": "./types/index.d.ts",
101
- "import": "./src/exports/internal/server.js"
109
+ "import": "./src/exports/internal/server/index.js"
102
110
  },
103
111
  "./node": {
104
112
  "types": "./types/index.d.ts",
@@ -108,6 +116,10 @@
108
116
  "types": "./types/index.d.ts",
109
117
  "import": "./src/exports/hooks/index.js"
110
118
  },
119
+ "./env": {
120
+ "types": "./types/index.d.ts",
121
+ "import": "./src/exports/env/index.js"
122
+ },
111
123
  "./vite": {
112
124
  "types": "./types/index.d.ts",
113
125
  "import": "./src/exports/vite/index.js"
@@ -119,7 +131,7 @@
119
131
  },
120
132
  "scripts": {
121
133
  "lint": "prettier --config ../../.prettierrc --check .",
122
- "check": "tsc && cd ./test/types && tsc",
134
+ "check": "tsc && cd ./test/types && tsc && cd ./app-error-enhanced && tsc",
123
135
  "check:all": "tsc && pnpm -r --filter=\"./**\" check",
124
136
  "format": "prettier --config ../../.prettierrc --write .",
125
137
  "test": "pnpm test:unit && pnpm test:integration",
package/src/constants.js CHANGED
@@ -11,3 +11,5 @@ export const ENDPOINT_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIO
11
11
  export const MUTATIVE_METHODS = ['POST', 'PUT', 'PATCH', 'DELETE'];
12
12
 
13
13
  export const PAGE_METHODS = ['GET', 'POST', 'HEAD'];
14
+
15
+ export const SRC_ROOT = import.meta.dirname;
@@ -8,7 +8,7 @@ import * as devalue from 'devalue';
8
8
  import { createReadStream, createWriteStream, existsSync, statSync } from 'node:fs';
9
9
  import { extname, resolve, join, dirname, relative } from 'node:path';
10
10
  import { pipeline } from 'node:stream';
11
- import { promisify, styleText } from 'node:util';
11
+ import { promisify } from 'node:util';
12
12
  import zlib from 'node:zlib';
13
13
  import { copy, rimraf, mkdirp } from '../../utils/filesystem.js';
14
14
  import { posixify } from '../../utils/os.js';
@@ -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,16 +137,13 @@ 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
 
132
144
  if (existsSync(dest)) {
133
- console.log(
134
- styleText(
135
- ['bold', 'yellow'],
136
- `Overwriting ${dest} with fallback page. Consider using a different name for the fallback.`
137
- )
145
+ log.warn(
146
+ `\nOverwriting ${dest} with fallback page. Consider using a different name for the fallback.\n`
138
147
  );
139
148
  }
140
149
 
@@ -144,7 +153,7 @@ export function create_builder({
144
153
  generateEnvModule() {
145
154
  if (!build_data.client?.uses_env_dynamic_public) return;
146
155
 
147
- const dest = `${config.kit.outDir}/output/prerendered/dependencies/${config.kit.appDir}/env.js`;
156
+ const dest = `${config.kit.outDir}/output/prerendered/dependencies/${config.kit.appDir}`;
148
157
  const env = loadEnv(vite_config.mode, config.kit.env.dir, '');
149
158
 
150
159
  /** @type {Record<string, any>} */
@@ -161,7 +170,9 @@ export function create_builder({
161
170
 
162
171
  handle_issues(issues);
163
172
 
164
- write(dest, `export const env=${devalue.uneval(values)}`);
173
+ const payload = devalue.uneval(values);
174
+
175
+ write(`${dest}/env.js`, `export const env=${payload}`);
165
176
  },
166
177
 
167
178
  generateManifest({ relativePath, routes: subset }) {
@@ -291,53 +302,25 @@ async function compress_file(file, format = 'gz') {
291
302
  * - Imports `exports` from the entrypoint (dynamically, if `tla` is true)
292
303
  * - Re-exports `exports` from the entrypoint
293
304
  *
294
- * `default` receives special treatment: It will be imported as `default` and exported with `export default`.
295
- *
296
305
  * @param {{ instrumentation: string; start: string; exports: string[] }} opts
297
306
  * @returns {string}
298
307
  */
299
308
  function create_instrumentation_facade({ instrumentation, start, exports }) {
300
309
  const import_instrumentation = `import './${instrumentation}';`;
301
310
 
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
- }
311
+ const { namespace, declarations, reexports } = create_exported_declarations(
312
+ exports,
313
+ (name, ns) => `${ns}.${name}`,
314
+ '__mod'
315
+ );
334
316
 
335
- const entrypoint_facade = [
336
- `const { ${import_statements.join(', ')} } = await import('./${start}');`,
337
- export_statements.length > 0 ? `export { ${export_statements.join(', ')} };` : ''
317
+ const parts = [
318
+ `const ${namespace} = await import('./${start}');`,
319
+ declarations.join('\n'),
320
+ reexports.length > 0 ? `export { ${reexports.join(', ')} };` : ''
338
321
  ]
339
322
  .filter(Boolean)
340
323
  .join('\n');
341
324
 
342
- return `${import_instrumentation}\n${entrypoint_facade}`;
325
+ return `${import_instrumentation}\n${parts}`;
343
326
  }
@@ -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,13 +1,78 @@
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 { styleText } from 'node:util';
10
+ import {
11
+ validate_kit_options,
12
+ kit_options,
13
+ kit_experimental_options,
14
+ validate_svelte_options
15
+ } from './options.js';
9
16
  import { resolve_entry } from '../../utils/filesystem.js';
10
17
  import { import_peer } from '../../utils/import.js';
18
+ import { stackless } from '../../utils/error.js';
19
+
20
+ /**
21
+ * Splits the config passed to the `sveltekit` Vite plugin into the options that
22
+ * SvelteKit processes itself and the options that are forwarded to
23
+ * `vite-plugin-svelte`. SvelteKit makes no assumptions about which options
24
+ * `vite-plugin-svelte` accepts — it plucks out its own options and passes
25
+ * everything else along (`vite-plugin-svelte` does its own validation).
26
+ * @param {KitConfig & Omit<Options, 'onwarn'> & Pick<SvelteConfig, 'vitePlugin'>} config
27
+ * @returns {{ svelte_config: Config, vite_plugin_svelte_config: Record<string, any> }}
28
+ */
29
+ export function split_config(config) {
30
+ const { extensions, compilerOptions, vitePlugin, preprocess, ...rest } = config;
31
+
32
+ /** @type {KitConfig} */
33
+ const kit = {};
34
+
35
+ /** @type {Record<string, any>} */
36
+ const vite_plugin_svelte_config = {};
37
+
38
+ for (const key in rest) {
39
+ if (key === 'experimental') {
40
+ // `experimental` is a namespace that both SvelteKit and vite-plugin-svelte
41
+ // use, so pluck out the flags SvelteKit recognises and pass the rest along
42
+ const experimental = /** @type {Record<string, any>} */ (rest[key]) ?? {};
43
+
44
+ /** @type {Record<string, any>} */
45
+ const kit_experimental = {};
46
+ /** @type {Record<string, any>} */
47
+ const vps_experimental = {};
48
+
49
+ for (const flag in experimental) {
50
+ if (kit_experimental_options.includes(flag)) {
51
+ kit_experimental[flag] = experimental[flag];
52
+ } else {
53
+ vps_experimental[flag] = experimental[flag];
54
+ }
55
+ }
56
+
57
+ if (Object.keys(kit_experimental).length > 0) {
58
+ kit.experimental = kit_experimental;
59
+ }
60
+ if (Object.keys(vps_experimental).length > 0) {
61
+ vite_plugin_svelte_config.experimental = vps_experimental;
62
+ }
63
+ } else if (kit_options.includes(key)) {
64
+ // @ts-expect-error - we've verified this is one of SvelteKit's own options
65
+ kit[key] = rest[key];
66
+ } else {
67
+ vite_plugin_svelte_config[key] = /** @type {Record<string, any>} */ (rest)[key];
68
+ }
69
+ }
70
+
71
+ return {
72
+ svelte_config: { extensions, compilerOptions, vitePlugin, preprocess, kit },
73
+ vite_plugin_svelte_config
74
+ };
75
+ }
11
76
 
12
77
  /**
13
78
  * Loads the template (src/app.html by default) and validates that it has the
@@ -70,98 +135,99 @@ export async function load_vite_config(config) {
70
135
  */
71
136
  export function extract_svelte_config(vite_config) {
72
137
  const plugin = vite_config.plugins.find((p) => p.name === 'vite-plugin-sveltekit-setup');
73
- return plugin?.api.options ?? process_config({});
138
+ return plugin?.api.options ?? process_config(validate_config({}), vite_config.root);
74
139
  }
75
140
 
76
141
  /**
77
- * @param {Config} config
142
+ * @param {ValidatedConfig} config
143
+ * @param {string} cwd
78
144
  * @returns {ValidatedConfig}
79
145
  */
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);
146
+ export function process_config(config, cwd) {
147
+ if (
148
+ config.kit.csp?.directives?.['require-trusted-types-for']?.includes('script') &&
149
+ config.kit.serviceWorker.register &&
150
+ resolve_entry(path.resolve(cwd, config.kit.files.serviceWorker)) &&
151
+ !config.kit.csp?.directives?.['trusted-types']?.includes('sveltekit-trusted-url')
152
+ ) {
153
+ throw new Error(
154
+ "The `csp.directives['trusted-types']` option must include 'sveltekit-trusted-url' when `serviceWorker.register` is true"
155
+ );
156
+ }
85
157
 
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
- }
158
+ config.kit.outDir = path.resolve(cwd, config.kit.outDir);
159
+ config.kit.env.dir = path.resolve(cwd, config.kit.env.dir);
160
+
161
+ for (const key in config.kit.files) {
162
+ if (key === 'hooks') {
163
+ config.kit.files.hooks.client = path.resolve(cwd, config.kit.files.hooks.client);
164
+ config.kit.files.hooks.server = path.resolve(cwd, config.kit.files.hooks.server);
165
+ config.kit.files.hooks.universal = path.resolve(cwd, config.kit.files.hooks.universal);
166
+ } else if (key !== 'lib' /* TODO remove when we remove the `lib` option altogether */) {
167
+ // @ts-expect-error
168
+ config.kit.files[key] = path.resolve(cwd, config.kit.files[key]);
98
169
  }
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
170
  }
171
+
172
+ return config;
108
173
  }
109
174
 
110
175
  /**
111
176
  * @param {Config} config
112
- * @param {string} [cwd]
113
177
  * @returns {ValidatedConfig}
114
178
  */
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') {
179
+ export function validate_config(config) {
180
+ try {
181
+ if (typeof config !== 'object') {
143
182
  throw new Error(
144
- "The `router.resolution` option cannot be 'server' if `output.bundleStrategy` is 'inline' or 'single'"
183
+ 'The SvelteKit options from the Vite config must be an object. See https://svelte.dev/docs/kit/configuration'
145
184
  );
146
185
  }
147
- }
148
186
 
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
- );
187
+ const validated = /** @type {ValidatedConfig} */ ({
188
+ ...validate_svelte_options(config, 'config'),
189
+ kit: validate_kit_options(config.kit, 'config')
190
+ });
191
+ const files = validated.kit.files;
192
+
193
+ files.hooks.client ??= path.join(files.src, 'hooks.client');
194
+ files.hooks.server ??= path.join(files.src, 'hooks.server');
195
+ files.hooks.universal ??= path.join(files.src, 'hooks');
196
+ files.params ??= path.join(files.src, 'params');
197
+ files.routes ??= path.join(files.src, 'routes');
198
+ files.serviceWorker ??= path.join(files.src, 'service-worker');
199
+ files.appTemplate ??= path.join(files.src, 'app.html');
200
+ files.errorTemplate ??= path.join(files.src, 'error.html');
201
+
202
+ if (validated.kit.router.resolution === 'server') {
203
+ if (validated.kit.router.type === 'hash') {
204
+ throw new Error(
205
+ "The `router.resolution` option cannot be 'server' if `router.type` is 'hash'"
206
+ );
207
+ }
208
+ if (validated.kit.output.bundleStrategy !== 'split') {
209
+ throw new Error(
210
+ "The `router.resolution` option cannot be 'server' if `output.bundleStrategy` is 'inline' or 'single'"
211
+ );
212
+ }
154
213
  }
214
+
155
215
  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')
216
+ validated.kit.csp?.directives?.['require-trusted-types-for']?.includes('script') &&
217
+ !validated.kit.csp?.directives?.['trusted-types']?.includes('svelte-trusted-html')
159
218
  ) {
160
219
  throw new Error(
161
- "The `csp.directives['trusted-types']` option must include 'sveltekit-trusted-url' when `serviceWorker.register` is true"
220
+ "The `csp.directives['trusted-types']` option must include 'svelte-trusted-html'"
162
221
  );
163
222
  }
164
- }
165
223
 
166
- return validated;
224
+ return validated;
225
+ } catch (e) {
226
+ const error = /** @type {Error} */ (e);
227
+
228
+ // Print a nicer version of the error to the console
229
+ console.log(styleText(['bold', 'red'], `\n${error.message}\n`));
230
+
231
+ throw stackless('Failed to load SvelteKit options from Vite config');
232
+ }
167
233
  }