@sveltejs/kit 2.62.0 → 3.0.0-next.0

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 (104) hide show
  1. package/package.json +28 -22
  2. package/src/cli.js +49 -20
  3. package/src/core/adapt/builder.js +38 -69
  4. package/src/core/adapt/index.js +11 -6
  5. package/src/core/config/index.js +12 -82
  6. package/src/core/config/options.js +36 -45
  7. package/src/core/env.js +240 -60
  8. package/src/core/generate_manifest/find_server_assets.js +3 -2
  9. package/src/core/generate_manifest/index.js +11 -3
  10. package/src/core/postbuild/analyse.js +20 -16
  11. package/src/core/postbuild/fallback.js +0 -3
  12. package/src/core/postbuild/prerender.js +19 -17
  13. package/src/core/postbuild/queue.js +3 -4
  14. package/src/core/sync/create_manifest_data/index.js +16 -18
  15. package/src/core/sync/sync.js +44 -23
  16. package/src/core/sync/utils.js +0 -15
  17. package/src/core/sync/write_ambient.js +5 -50
  18. package/src/core/sync/write_client_manifest.js +8 -9
  19. package/src/core/sync/write_env.js +36 -0
  20. package/src/core/sync/write_non_ambient.js +7 -7
  21. package/src/core/sync/write_root.js +41 -89
  22. package/src/core/sync/write_server.js +18 -24
  23. package/src/core/sync/write_tsconfig.js +29 -24
  24. package/src/core/sync/write_types/index.js +31 -25
  25. package/src/core/utils.js +14 -11
  26. package/src/exports/hooks/index.js +13 -0
  27. package/src/exports/index.js +8 -21
  28. package/src/exports/internal/env.js +71 -0
  29. package/src/exports/internal/types.d.ts +3 -0
  30. package/src/exports/node/index.js +8 -13
  31. package/src/exports/public.d.ts +68 -69
  32. package/src/exports/vite/build/build_server.js +14 -11
  33. package/src/exports/vite/build/remote.js +6 -7
  34. package/src/exports/vite/build/utils.js +7 -5
  35. package/src/exports/vite/dev/index.js +32 -33
  36. package/src/exports/vite/index.js +1015 -711
  37. package/src/exports/vite/module_ids.js +10 -6
  38. package/src/exports/vite/options.js +17 -0
  39. package/src/exports/vite/preview/index.js +3 -5
  40. package/src/exports/vite/static_analysis/index.js +11 -5
  41. package/src/exports/vite/utils.js +11 -41
  42. package/src/runtime/app/env/index.js +2 -0
  43. package/src/runtime/app/env/internal.js +14 -0
  44. package/src/runtime/app/env/private.js +1 -0
  45. package/src/runtime/app/env/public/client.js +1 -0
  46. package/src/runtime/app/env/public/index.js +1 -0
  47. package/src/runtime/app/env/public/server.js +1 -0
  48. package/src/runtime/app/env/standard-schema.d.ts +0 -0
  49. package/src/runtime/app/server/index.js +4 -2
  50. package/src/runtime/app/server/remote/form.js +0 -51
  51. package/src/runtime/app/server/remote/query.js +1 -8
  52. package/src/runtime/app/server/remote/shared.js +4 -3
  53. package/src/runtime/app/state/client.js +1 -12
  54. package/src/runtime/client/client.js +1 -1
  55. package/src/runtime/client/constants.js +0 -1
  56. package/src/runtime/client/remote-functions/form.svelte.js +0 -31
  57. package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
  58. package/src/runtime/client/remote-functions/query/index.js +2 -2
  59. package/src/runtime/client/remote-functions/query/instance.svelte.js +1 -2
  60. package/src/runtime/client/remote-functions/query-batch.svelte.js +2 -2
  61. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +5 -8
  62. package/src/runtime/client/utils.js +9 -11
  63. package/src/runtime/components/{svelte-5/layout.svelte → layout.svelte} +1 -1
  64. package/src/runtime/form-utils.js +4 -41
  65. package/src/runtime/server/cookie.js +21 -37
  66. package/src/runtime/server/env_module.js +12 -4
  67. package/src/runtime/server/fetch.js +6 -10
  68. package/src/runtime/server/index.js +5 -9
  69. package/src/runtime/server/page/render.js +33 -37
  70. package/src/runtime/server/page/types.d.ts +4 -2
  71. package/src/runtime/server/respond.js +3 -3
  72. package/src/runtime/server/utils.js +2 -4
  73. package/src/runtime/shared-server.js +0 -22
  74. package/src/runtime/shared.js +0 -15
  75. package/src/types/ambient-private.d.ts +25 -9
  76. package/src/types/global-private.d.ts +6 -0
  77. package/src/types/internal.d.ts +4 -8
  78. package/src/utils/css.js +3 -19
  79. package/src/utils/filesystem.js +1 -30
  80. package/src/utils/http.js +0 -21
  81. package/src/utils/import.js +8 -7
  82. package/src/utils/os.js +7 -0
  83. package/src/utils/path.js +23 -0
  84. package/src/utils/shared-iterator.js +3 -0
  85. package/src/utils/streaming.js +2 -4
  86. package/src/utils/url.js +1 -1
  87. package/src/utils/vite.js +28 -0
  88. package/src/version.js +1 -1
  89. package/types/index.d.ts +85 -109
  90. package/types/index.d.ts.map +5 -6
  91. package/src/exports/vite/build/build_service_worker.js +0 -149
  92. package/src/runtime/app/environment/index.js +0 -2
  93. package/src/runtime/components/svelte-4/error.svelte +0 -6
  94. package/src/runtime/components/svelte-4/layout.svelte +0 -1
  95. package/src/runtime/env/dynamic/private.js +0 -1
  96. package/src/runtime/env/dynamic/public.js +0 -1
  97. package/src/types/synthetic/$env+dynamic+private.md +0 -43
  98. package/src/types/synthetic/$env+dynamic+public.md +0 -46
  99. package/src/types/synthetic/$env+static+private.md +0 -31
  100. package/src/types/synthetic/$env+static+public.md +0 -31
  101. package/src/utils/env.js +0 -13
  102. package/src/utils/promise.js +0 -29
  103. /package/src/runtime/app/{environment → env}/types.d.ts +0 -0
  104. /package/src/runtime/components/{svelte-5/error.svelte → error.svelte} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "2.62.0",
3
+ "version": "3.0.0-next.0",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
@@ -20,38 +20,35 @@
20
20
  "dependencies": {
21
21
  "@standard-schema/spec": "^1.0.0",
22
22
  "@sveltejs/acorn-typescript": "^1.0.9",
23
- "@types/cookie": "^0.6.0",
24
23
  "acorn": "^8.16.0",
25
- "cookie": "^0.6.0",
24
+ "cookie": "^1.1.1",
26
25
  "devalue": "^5.8.1",
27
26
  "esm-env": "^1.2.2",
28
- "kleur": "^4.1.5",
29
27
  "magic-string": "^0.30.5",
30
28
  "mrmime": "^2.0.0",
31
- "set-cookie-parser": "^3.0.0",
32
29
  "sirv": "^3.0.0"
33
30
  },
34
31
  "devDependencies": {
35
32
  "@opentelemetry/api": "^1.0.0",
36
33
  "@playwright/test": "^1.60.0",
37
- "@sveltejs/vite-plugin-svelte": "^6.0.0-next.3",
34
+ "@sveltejs/vite-plugin-svelte": "^7.0.0",
38
35
  "@types/connect": "^3.4.38",
39
- "@types/node": "^18.19.130",
40
- "@types/set-cookie-parser": "^2.4.7",
36
+ "@types/node": "^22.19.19",
41
37
  "dts-buddy": "^0.8.0",
42
- "jsdom": "^26.1.0",
43
- "rollup": "^4.59.0",
38
+ "jsdom": "^29.1.1",
39
+ "rolldown": "^1.0.0-rc.6",
44
40
  "svelte": "^5.55.7",
45
- "typescript": "^5.3.3",
46
- "vite": "^6.4.2",
41
+ "svelte-preprocess": "^6.0.5",
42
+ "typescript": "~6.0.0",
43
+ "vite": "^8.0.10",
47
44
  "vitest": "^4.1.7"
48
45
  },
49
46
  "peerDependencies": {
47
+ "@sveltejs/vite-plugin-svelte": "^7.0.0",
50
48
  "@opentelemetry/api": "^1.0.0",
51
- "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0",
52
- "svelte": "^4.0.0 || ^5.0.0-next.0",
53
- "typescript": "^5.3.3 || ^6.0.0",
54
- "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0"
49
+ "svelte": "^5.48.0",
50
+ "typescript": "^6.0.0",
51
+ "vite": "^8.0.0"
55
52
  },
56
53
  "peerDependenciesMeta": {
57
54
  "@opentelemetry/api": {
@@ -76,6 +73,10 @@
76
73
  "#app/paths": {
77
74
  "browser": "./src/runtime/app/paths/client.js",
78
75
  "default": "./src/runtime/app/paths/server.js"
76
+ },
77
+ "#app/env/public": {
78
+ "browser": "./src/runtime/app/env/public/client.js",
79
+ "default": "./src/runtime/app/env/public/server.js"
79
80
  }
80
81
  },
81
82
  "exports": {
@@ -88,6 +89,13 @@
88
89
  "types": "./types/index.d.ts",
89
90
  "import": "./src/exports/internal/index.js"
90
91
  },
92
+ "./internal/env": {
93
+ "types": "./types/index.d.ts",
94
+ "import": "./src/exports/internal/env.js"
95
+ },
96
+ "./internal/types": {
97
+ "import": "./src/exports/internal/types.js"
98
+ },
91
99
  "./internal/server": {
92
100
  "types": "./types/index.d.ts",
93
101
  "import": "./src/exports/internal/server.js"
@@ -96,10 +104,6 @@
96
104
  "types": "./types/index.d.ts",
97
105
  "import": "./src/exports/node/index.js"
98
106
  },
99
- "./node/polyfills": {
100
- "types": "./types/index.d.ts",
101
- "import": "./src/exports/node/polyfills.js"
102
- },
103
107
  "./hooks": {
104
108
  "types": "./types/index.d.ts",
105
109
  "import": "./src/exports/hooks/index.js"
@@ -111,7 +115,7 @@
111
115
  },
112
116
  "types": "types/index.d.ts",
113
117
  "engines": {
114
- "node": ">=18.13"
118
+ "node": ">=22"
115
119
  },
116
120
  "scripts": {
117
121
  "lint": "prettier --config ../../.prettierrc --check .",
@@ -126,7 +130,9 @@
126
130
  "test:server-side-route-resolution:build": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:server-side-route-resolution:build",
127
131
  "test:svelte-async:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:svelte-async:dev",
128
132
  "test:svelte-async:build": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:svelte-async:build",
129
- "test:unit": "vitest --config kit.vitest.config.js run",
133
+ "test:unit:dev": "vitest --config kit.vitest.config.js run",
134
+ "test:unit:prod": "NODE_ENV=production vitest --config kit.vitest.config.js run csp.spec.js cookie.spec.js",
135
+ "test:unit": "pnpm test:unit:dev && pnpm test:unit:prod",
130
136
  "generate:version": "node scripts/generate-version.js",
131
137
  "generate:types": "node scripts/generate-dts.js"
132
138
  }
package/src/cli.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import fs from 'node:fs';
2
2
  import process from 'node:process';
3
- import { parseArgs } from 'node:util';
4
- import colors from 'kleur';
5
- import { load_config } from './core/config/index.js';
3
+ import { parseArgs, styleText } from 'node:util';
4
+ import { extract_svelte_config, load_vite_config } from './core/config/index.js';
6
5
  import { coalesce_to_error } from './utils/error.js';
6
+ import { resolve_explicit_env_entry } from './core/env.js';
7
7
 
8
8
  /** @param {unknown} e */
9
9
  function handle_error(e) {
@@ -11,9 +11,9 @@ function handle_error(e) {
11
11
 
12
12
  if (error.name === 'SyntaxError') throw error;
13
13
 
14
- console.error(colors.bold().red(`> ${error.message}`));
14
+ console.error(styleText(['bold', 'red'], `> ${error.message}`));
15
15
  if (error.stack) {
16
- console.error(colors.gray(error.stack.split('\n').slice(1).join('\n')));
16
+ console.error(styleText('grey', error.stack.split('\n').slice(1).join('\n')));
17
17
  }
18
18
 
19
19
  process.exit(1);
@@ -25,14 +25,15 @@ const help = `
25
25
  Usage: svelte-kit <command> [options]
26
26
 
27
27
  Commands:
28
- sync Synchronise generated type definitions
28
+ sync Synchronise generated type definitions
29
29
 
30
30
  Options:
31
- --version, -v Show version number
32
- --help, -h Show this help message
31
+ --version, -v Show version number
32
+ --help, -h Show this help message
33
33
 
34
34
  Sync Options:
35
- --mode <mode> Specify a mode for loading environment variables (default: development)
35
+ --config, -c <config> Specify a custom Vite config file
36
+ --mode <mode> Specify a mode for loading environment variables (default: development)
36
37
  `;
37
38
 
38
39
  let parsed;
@@ -41,14 +42,15 @@ try {
41
42
  options: {
42
43
  version: { type: 'boolean', short: 'v' },
43
44
  help: { type: 'boolean', short: 'h' },
44
- mode: { type: 'string', default: 'development' }
45
+ mode: { type: 'string', default: 'development' },
46
+ config: { type: 'string', short: 'c', default: undefined }
45
47
  },
46
48
  allowPositionals: true,
47
49
  strict: true
48
50
  });
49
51
  } catch (err) {
50
52
  const error = /** @type {Error} */ (err);
51
- console.error(colors.bold().red(`> ${error.message}`));
53
+ console.error(styleText(['bold', 'red'], `> ${error.message}`));
52
54
  console.log(help);
53
55
  process.exit(1);
54
56
  }
@@ -73,23 +75,50 @@ if (!command) {
73
75
  }
74
76
 
75
77
  if (command === 'sync') {
76
- const config_files = ['js', 'ts']
77
- .map((ext) => `svelte.config.${ext}`)
78
- .filter((f) => fs.existsSync(f));
79
- if (config_files.length === 0) {
80
- console.warn(`Missing Svelte config file in ${process.cwd()} — skipping`);
81
- process.exit(0);
78
+ // create placeholder .svelte-kit/tsconfig.json if necessary, to squelch warnings.
79
+ // this isn't bulletproof — if someone has some esoteric config, it will continue
80
+ // to harmlessly warn — but we handle the 90% case and clean up after ourselves
81
+ const sveltekit_dir = '.svelte-kit';
82
+ const base_tsconfig = `${sveltekit_dir}/tsconfig.json`;
83
+ const base_tsconfig_json = '{}';
84
+
85
+ const sveltekit_dir_exists = fs.existsSync(sveltekit_dir);
86
+ const base_tsconfig_exists = fs.existsSync(base_tsconfig);
87
+
88
+ if (!base_tsconfig_exists) {
89
+ try {
90
+ fs.mkdirSync('.svelte-kit');
91
+ } catch {
92
+ // ignore
93
+ }
94
+
95
+ fs.writeFileSync(base_tsconfig, base_tsconfig_json);
82
96
  }
83
97
 
84
98
  try {
85
- const config = await load_config();
99
+ const vite_config = await load_vite_config(values.config);
100
+ const sveltekit_config = extract_svelte_config(vite_config);
101
+
86
102
  const sync = await import('./core/sync/sync.js');
87
- sync.all_types(config, values.mode);
103
+ sync.all_types(sveltekit_config);
104
+
105
+ const explicit_env_entry = resolve_explicit_env_entry(sveltekit_config.kit);
106
+ await sync.env(sveltekit_config.kit, explicit_env_entry, vite_config.root, values.mode);
88
107
  } catch (error) {
89
108
  handle_error(error);
109
+ } finally {
110
+ // if we errored, or accidentally created the wrong file
111
+ // (could happen!) then clean up after ourselves
112
+ if (fs.readFileSync(base_tsconfig, 'utf-8') === base_tsconfig_json) {
113
+ fs.unlinkSync(base_tsconfig);
114
+ }
115
+
116
+ if (!sveltekit_dir_exists && fs.readdirSync(sveltekit_dir).length === 0) {
117
+ fs.rmSync(sveltekit_dir, { recursive: true });
118
+ }
90
119
  }
91
120
  } else {
92
- console.error(colors.bold().red(`> Unknown command: ${command}`));
121
+ console.error(styleText(['bold', 'red'], `> Unknown command: ${command}`));
93
122
  console.log(help);
94
123
  process.exit(1);
95
124
  }
@@ -1,22 +1,25 @@
1
+ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */
1
2
  /** @import { Builder } from '@sveltejs/kit' */
2
3
  /** @import { ResolvedConfig } from 'vite' */
3
- /** @import { RouteDefinition } from '@sveltejs/kit' */
4
+ /** @import { RouteDefinition, EnvVarConfig } from '@sveltejs/kit' */
4
5
  /** @import { RouteData, ValidatedConfig, BuildData, ServerMetadata, ServerMetadataRoute, Prerendered, PrerenderMap, Logger, RemoteChunk } from 'types' */
5
- import colors from 'kleur';
6
+ import { loadEnv } from 'vite';
7
+ import * as devalue from 'devalue';
6
8
  import { createReadStream, createWriteStream, existsSync, statSync } from 'node:fs';
7
9
  import { extname, resolve, join, dirname, relative } from 'node:path';
8
10
  import { pipeline } from 'node:stream';
9
- import { promisify } from 'node:util';
11
+ import { promisify, styleText } from 'node:util';
10
12
  import zlib from 'node:zlib';
11
- import { copy, rimraf, mkdirp, posixify } from '../../utils/filesystem.js';
13
+ import { copy, rimraf, mkdirp } from '../../utils/filesystem.js';
14
+ import { posixify } from '../../utils/os.js';
12
15
  import { generate_manifest } from '../generate_manifest/index.js';
13
16
  import { get_route_segments } from '../../utils/routing.js';
14
- import { get_env } from '../../exports/vite/utils.js';
15
17
  import generate_fallback from '../postbuild/fallback.js';
16
18
  import { write } from '../sync/utils.js';
17
19
  import { list_files } from '../utils.js';
18
20
  import { find_server_assets } from '../generate_manifest/find_server_assets.js';
19
21
  import { reserved } from '../env.js';
22
+ import { handle_issues, validate } from '../../exports/internal/env.js';
20
23
 
21
24
  const pipe = promisify(pipeline);
22
25
  const extensions = ['.html', '.js', '.mjs', '.json', '.css', '.svg', '.xml', '.wasm', '.txt'];
@@ -32,7 +35,8 @@ const extensions = ['.html', '.js', '.mjs', '.json', '.css', '.svg', '.xml', '.w
32
35
  * prerender_map: PrerenderMap;
33
36
  * log: Logger;
34
37
  * vite_config: ResolvedConfig;
35
- * remotes: RemoteChunk[]
38
+ * remotes: RemoteChunk[];
39
+ * explicit_env_config: Record<string, EnvVarConfig<any>> | null;
36
40
  * }} opts
37
41
  * @returns {Builder}
38
42
  */
@@ -45,7 +49,8 @@ export function create_builder({
45
49
  prerender_map,
46
50
  log,
47
51
  vite_config,
48
- remotes
52
+ remotes,
53
+ explicit_env_config
49
54
  }) {
50
55
  /** @type {Map<RouteDefinition, RouteData>} */
51
56
  const lookup = new Map();
@@ -104,71 +109,21 @@ export function create_builder({
104
109
  );
105
110
  },
106
111
 
107
- async createEntries(fn) {
108
- const seen = new Set();
109
-
110
- for (let i = 0; i < route_data.length; i += 1) {
111
- const route = route_data[i];
112
- if (prerender_map.get(route.id) === true) continue;
113
- const { id, filter, complete } = fn(routes[i]);
114
-
115
- if (seen.has(id)) continue;
116
- seen.add(id);
117
-
118
- const group = [route];
119
-
120
- // figure out which lower priority routes should be considered fallbacks
121
- for (let j = i + 1; j < route_data.length; j += 1) {
122
- if (prerender_map.get(routes[j].id) === true) continue;
123
- if (filter(routes[j])) {
124
- group.push(route_data[j]);
125
- }
126
- }
127
-
128
- const filtered = new Set(group);
129
-
130
- // heuristic: if /foo/[bar] is included, /foo/[bar].json should
131
- // also be included, since the page likely needs the endpoint
132
- // TODO is this still necessary, given the new way of doing things?
133
- filtered.forEach((route) => {
134
- if (route.page) {
135
- const endpoint = route_data.find((candidate) => candidate.id === route.id + '.json');
136
-
137
- if (endpoint) {
138
- filtered.add(endpoint);
139
- }
140
- }
141
- });
142
-
143
- if (filtered.size > 0) {
144
- await complete({
145
- generateManifest: ({ relativePath }) =>
146
- generate_manifest({
147
- build_data,
148
- prerendered: [],
149
- relative_path: relativePath,
150
- routes: Array.from(filtered),
151
- remotes
152
- })
153
- });
154
- }
155
- }
156
- },
157
-
158
112
  findServerAssets(route_data) {
159
113
  return find_server_assets(
160
114
  build_data,
161
- route_data.map((route) => /** @type {import('types').RouteData} */ (lookup.get(route)))
115
+ route_data.map((route) => /** @type {import('types').RouteData} */ (lookup.get(route))),
116
+ vite_config.root
162
117
  );
163
118
  },
164
119
 
165
120
  async generateFallback(dest) {
166
121
  const manifest_path = `${config.kit.outDir}/output/server/manifest-full.js`;
167
- const env = get_env(config.kit.env, vite_config.mode);
122
+ const env = loadEnv(vite_config.mode, config.kit.env.dir, '');
168
123
 
169
124
  const fallback = await generate_fallback({
170
125
  manifest_path,
171
- env: { ...env.private, ...env.public },
126
+ env,
172
127
  out_dir: config.kit.outDir,
173
128
  origin: config.kit.prerender.origin,
174
129
  assets: config.kit.files.assets
@@ -176,11 +131,10 @@ export function create_builder({
176
131
 
177
132
  if (existsSync(dest)) {
178
133
  console.log(
179
- colors
180
- .bold()
181
- .yellow(
182
- `Overwriting ${dest} with fallback page. Consider using a different name for the fallback.`
183
- )
134
+ styleText(
135
+ ['bold', 'yellow'],
136
+ `Overwriting ${dest} with fallback page. Consider using a different name for the fallback.`
137
+ )
184
138
  );
185
139
  }
186
140
 
@@ -191,9 +145,23 @@ export function create_builder({
191
145
  if (!build_data.client?.uses_env_dynamic_public) return;
192
146
 
193
147
  const dest = `${config.kit.outDir}/output/prerendered/dependencies/${config.kit.appDir}/env.js`;
194
- const env = get_env(config.kit.env, vite_config.mode);
148
+ const env = loadEnv(vite_config.mode, config.kit.env.dir, '');
149
+
150
+ /** @type {Record<string, any>} */
151
+ const values = {};
152
+ const variables = explicit_env_config ?? {};
153
+
154
+ /** @type {Record<string, StandardSchemaV1.Issue[]>} */
155
+ const issues = {};
156
+
157
+ for (const [name, config] of Object.entries(variables)) {
158
+ if (config.static || !config.public) continue;
159
+ values[name] = validate(variables, env[name], name, issues);
160
+ }
161
+
162
+ handle_issues(issues);
195
163
 
196
- write(dest, `export const env=${JSON.stringify(env.public)}`);
164
+ write(dest, `export const env=${devalue.uneval(values)}`);
197
165
  },
198
166
 
199
167
  generateManifest({ relativePath, routes: subset }) {
@@ -204,7 +172,8 @@ export function create_builder({
204
172
  routes: subset
205
173
  ? subset.map((route) => /** @type {import('types').RouteData} */ (lookup.get(route)))
206
174
  : route_data.filter((route) => prerender_map.get(route.id) !== true),
207
- remotes
175
+ remotes,
176
+ root: vite_config.root
208
177
  });
209
178
  },
210
179
 
@@ -1,7 +1,9 @@
1
- import colors from 'kleur';
1
+ /** @import { Adapter } from '@sveltejs/kit' */
2
+ import { styleText } from 'node:util';
2
3
  import { create_builder } from './builder.js';
3
4
 
4
5
  /**
6
+ * @param {Adapter} adapter
5
7
  * @param {import('types').ValidatedConfig} config
6
8
  * @param {import('types').BuildData} build_data
7
9
  * @param {import('types').ServerMetadata} server_metadata
@@ -10,8 +12,10 @@ import { create_builder } from './builder.js';
10
12
  * @param {import('types').Logger} log
11
13
  * @param {import('types').RemoteChunk[]} remotes
12
14
  * @param {import('vite').ResolvedConfig} vite_config
15
+ * @param {Record<string, import('@sveltejs/kit').EnvVarConfig<any>> | null} explicit_env_config
13
16
  */
14
17
  export async function adapt(
18
+ adapter,
15
19
  config,
16
20
  build_data,
17
21
  server_metadata,
@@ -19,12 +23,12 @@ export async function adapt(
19
23
  prerender_map,
20
24
  log,
21
25
  remotes,
22
- vite_config
26
+ vite_config,
27
+ explicit_env_config
23
28
  ) {
24
- // This is only called when adapter is truthy, so the cast is safe
25
- const { name, adapt } = /** @type {import('@sveltejs/kit').Adapter} */ (config.kit.adapter);
29
+ const { name, adapt } = adapter;
26
30
 
27
- console.log(colors.bold().cyan(`\n> Using ${name}`));
31
+ console.log(styleText(['bold', 'cyan'], `\n> Using ${name}`));
28
32
 
29
33
  const builder = create_builder({
30
34
  config,
@@ -35,7 +39,8 @@ export async function adapt(
35
39
  prerender_map,
36
40
  log,
37
41
  remotes,
38
- vite_config
42
+ vite_config,
43
+ explicit_env_config
39
44
  });
40
45
 
41
46
  await adapt(builder);
@@ -16,7 +16,7 @@ import { import_peer } from '../../utils/import.js';
16
16
  * @param {ValidatedConfig} config
17
17
  */
18
18
  export function load_template(cwd, { kit }) {
19
- const { env, files } = kit;
19
+ const { files } = kit;
20
20
 
21
21
  const relative = path.relative(cwd, files.appTemplate);
22
22
 
@@ -33,14 +33,6 @@ export function load_template(cwd, { kit }) {
33
33
  }
34
34
  });
35
35
 
36
- for (const match of contents.matchAll(/%sveltekit\.env\.([^%]+)%/g)) {
37
- if (!match[1].startsWith(env.publicPrefix)) {
38
- throw new Error(
39
- `Environment variables in ${relative} must start with ${env.publicPrefix} (saw %sveltekit.env.${match[1]}%)`
40
- );
41
- }
42
- }
43
-
44
36
  return contents;
45
37
  }
46
38
 
@@ -62,85 +54,23 @@ export function load_error_page(config) {
62
54
  }
63
55
 
64
56
  /**
65
- * Loads and validates Svelte config file. Tries Vite config first, falls back to svelte.config.js
66
- * @param {{ cwd?: string }} options
67
- * @returns {Promise<ValidatedConfig>}
57
+ * @param {string} [config]
68
58
  */
69
- export async function load_config({ cwd = process.cwd() } = {}) {
70
- try {
71
- const vite_config = await load_config_from_vite({ cwd });
72
- if (vite_config) {
73
- return vite_config;
74
- }
75
- } catch (e) {
76
- // TODO SvelteKit 3: fail completely instead
77
- console.error(
78
- 'Loading Svelte config from Vite config failed:',
79
- e,
80
- '\n\nFalling back to loading svelte.config.js'
81
- );
82
- }
83
-
84
- return load_svelte_config(cwd);
85
- }
86
-
87
- /**
88
- * Loads and validates Svelte config file
89
- * @param {string} [cwd]
90
- * @returns {Promise<ValidatedConfig>}
91
- */
92
- export async function load_svelte_config(cwd = process.cwd()) {
93
- const config_files = ['js', 'ts']
94
- .map((ext) => path.join(cwd, `svelte.config.${ext}`))
95
- .filter((f) => fs.existsSync(f));
96
-
97
- if (config_files.length === 0) {
98
- console.log(
99
- `No Svelte config file found in ${cwd} - using SvelteKit's default configuration without an adapter.`
100
- );
101
- return process_config({}, { cwd });
102
- }
103
-
104
- const config_file = config_files[0];
105
- if (config_files.length > 1) {
106
- console.log(
107
- `Found multiple Svelte config files in ${cwd}: ${config_files.map((f) => path.basename(f)).join(', ')}. Using ${path.basename(config_file)}`
108
- );
109
- }
59
+ export async function load_vite_config(config) {
60
+ const { resolveConfig } = /** @type {import('vite')} */ (
61
+ await import_peer('vite', process.cwd())
62
+ );
110
63
 
111
- const config = await import(`${url.pathToFileURL(config_file).href}?ts=${Date.now()}`);
112
- return process_config(config.default, { cwd, source: path.relative(cwd, config_file) });
64
+ return resolveConfig({ configFile: config }, 'build', process.env.MODE ?? 'production');
113
65
  }
114
66
 
115
67
  /**
116
- * Loads and validates Svelte config via Vite config resolution (if set that way).
117
- * @param {{ cwd?: string; mode?: string }} options
118
- * @returns {Promise<ValidatedConfig | undefined>}
68
+ * @param {ResolvedConfig} vite_config
69
+ * @returns {ValidatedConfig}
119
70
  */
120
- async function load_config_from_vite({ cwd = process.cwd(), mode } = {}) {
121
- const { resolveConfig } = await import_peer('vite');
122
- const current_cwd = process.cwd();
123
-
124
- if (cwd !== current_cwd) {
125
- process.chdir(cwd);
126
- }
127
-
128
- /** @type {ResolvedConfig} */
129
- let resolved;
130
-
131
- try {
132
- resolved = await resolveConfig({}, 'build', mode ?? process.env.MODE ?? 'production');
133
- } finally {
134
- if (cwd !== current_cwd) {
135
- process.chdir(current_cwd);
136
- }
137
- }
138
-
139
- const plugin = resolved.plugins.find(
140
- (plugin) => plugin.name === 'vite-plugin-sveltekit-setup' && plugin.api?.options
141
- );
142
-
143
- return plugin?.api.options;
71
+ export function extract_svelte_config(vite_config) {
72
+ const plugin = vite_config.plugins.find((p) => p.name === 'vite-plugin-sveltekit-setup');
73
+ return plugin?.api.options ?? process_config({});
144
74
  }
145
75
 
146
76
  /**