@sveltejs/kit 2.20.8 → 2.21.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "2.20.8",
3
+ "version": "2.21.1",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
@@ -18,11 +18,12 @@
18
18
  "homepage": "https://svelte.dev",
19
19
  "type": "module",
20
20
  "dependencies": {
21
+ "@sveltejs/acorn-typescript": "^1.0.5",
21
22
  "@types/cookie": "^0.6.0",
23
+ "acorn": "^8.14.1",
22
24
  "cookie": "^0.6.0",
23
25
  "devalue": "^5.1.0",
24
26
  "esm-env": "^1.2.2",
25
- "import-meta-resolve": "^4.1.0",
26
27
  "kleur": "^4.1.5",
27
28
  "magic-string": "^0.30.5",
28
29
  "mrmime": "^2.0.0",
@@ -36,12 +37,12 @@
36
37
  "@types/connect": "^3.4.38",
37
38
  "@types/node": "^18.19.48",
38
39
  "@types/set-cookie-parser": "^2.4.7",
39
- "dts-buddy": "^0.5.5",
40
+ "dts-buddy": "^0.6.1",
40
41
  "rollup": "^4.14.2",
41
42
  "svelte": "^5.23.1",
42
43
  "svelte-preprocess": "^6.0.0",
43
44
  "typescript": "^5.3.3",
44
- "vite": "^6.2.6",
45
+ "vite": "^6.2.7",
45
46
  "vitest": "^3.1.1"
46
47
  },
47
48
  "peerDependencies": {
@@ -10,6 +10,7 @@ import { has_server_load, resolve_route } from '../../utils/routing.js';
10
10
  import { check_feature } from '../../utils/features.js';
11
11
  import { createReadableStream } from '@sveltejs/kit/node';
12
12
  import { PageNodes } from '../../utils/page_nodes.js';
13
+ import { build_server_nodes } from '../../exports/vite/build/build_server.js';
13
14
 
14
15
  export default forked(import.meta.url, analyse);
15
16
 
@@ -20,7 +21,9 @@ export default forked(import.meta.url, analyse);
20
21
  * manifest_data: import('types').ManifestData;
21
22
  * server_manifest: import('vite').Manifest;
22
23
  * tracked_features: Record<string, string[]>;
23
- * env: Record<string, string>
24
+ * env: Record<string, string>;
25
+ * out: string;
26
+ * output_config: import('types').RecursiveRequired<import('types').ValidatedConfig['kit']['output']>;
24
27
  * }} opts
25
28
  */
26
29
  async function analyse({
@@ -29,7 +32,9 @@ async function analyse({
29
32
  manifest_data,
30
33
  server_manifest,
31
34
  tracked_features,
32
- env
35
+ env,
36
+ out,
37
+ output_config
33
38
  }) {
34
39
  /** @type {import('@sveltejs/kit').SSRManifest} */
35
40
  const manifest = (await import(pathToFileURL(manifest_path).href)).manifest;
@@ -58,6 +63,20 @@ async function analyse({
58
63
  internal.set_manifest(manifest);
59
64
  internal.set_read_implementation((file) => createReadableStream(`${server_root}/server/${file}`));
60
65
 
66
+ const static_exports = new Map();
67
+
68
+ // first, build server nodes without the client manifest so we can analyse it
69
+ await build_server_nodes(
70
+ out,
71
+ config,
72
+ manifest_data,
73
+ server_manifest,
74
+ null,
75
+ null,
76
+ output_config,
77
+ static_exports
78
+ );
79
+
61
80
  /** @type {import('types').ServerMetadata} */
62
81
  const metadata = {
63
82
  nodes: [],
@@ -143,7 +162,7 @@ async function analyse({
143
162
  });
144
163
  }
145
164
 
146
- return metadata;
165
+ return { metadata, static_exports };
147
166
  }
148
167
 
149
168
  /**
@@ -1,10 +1,10 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { mkdirp } from '../../utils/filesystem.js';
4
- import { resolve_peer_dependency } from '../../utils/import.js';
4
+ import { import_peer } from '../../utils/import.js';
5
5
 
6
6
  /** @type {{ VERSION: string }} */
7
- const { VERSION } = await resolve_peer_dependency('svelte/compiler');
7
+ const { VERSION } = await import_peer('svelte/compiler');
8
8
 
9
9
  /** @type {Map<string, string>} */
10
10
  const previous_contents = new Map();
@@ -180,14 +180,14 @@ export function text(body, init) {
180
180
  }
181
181
 
182
182
  /**
183
- * Create an `ActionFailure` object.
183
+ * Create an `ActionFailure` object. Call when form submission fails.
184
184
  * @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.
185
185
  * @overload
186
186
  * @param {number} status
187
187
  * @returns {import('./public.js').ActionFailure<undefined>}
188
188
  */
189
189
  /**
190
- * Create an `ActionFailure` object.
190
+ * Create an `ActionFailure` object. Call when form submission fails.
191
191
  * @template {Record<string, unknown> | undefined} [T=undefined]
192
192
  * @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.
193
193
  * @param {T} data Data associated with the failure (e.g. validation errors)
@@ -197,7 +197,7 @@ export function text(body, init) {
197
197
  * @returns {import('./public.js').ActionFailure<T>}
198
198
  */
199
199
  /**
200
- * Create an `ActionFailure` object.
200
+ * Create an `ActionFailure` object. Call when form submission fails.
201
201
  * @param {number} status
202
202
  * @param {any} [data]
203
203
  * @returns {import('./public.js').ActionFailure<any>}
@@ -36,18 +36,18 @@ export interface Adapter {
36
36
  */
37
37
  adapt: (builder: Builder) => MaybePromise<void>;
38
38
  /**
39
- * Checks called during dev and build to determine whether specific features will work in production with this adapter
39
+ * Checks called during dev and build to determine whether specific features will work in production with this adapter.
40
40
  */
41
41
  supports?: {
42
42
  /**
43
- * Test support for `read` from `$app/server`
44
- * @param config The merged route config
43
+ * Test support for `read` from `$app/server`.
44
+ * @param details.config The merged route config
45
45
  */
46
46
  read?: (details: { config: any; route: { id: string } }) => boolean;
47
47
  };
48
48
  /**
49
49
  * Creates an `Emulator`, which allows the adapter to influence the environment
50
- * during dev, build and prerendering
50
+ * during dev, build and prerendering.
51
51
  */
52
52
  emulate?: () => MaybePromise<Emulator>;
53
53
  }
@@ -790,7 +790,7 @@ export type HandleClientError = (input: {
790
790
  }) => MaybePromise<void | App.Error>;
791
791
 
792
792
  /**
793
- * The [`handleFetch`](https://svelte.dev/docs/kit/hooks#Server-hooks-handleFetch) hook allows you to modify (or replace) a `fetch` request that happens inside a `load` function that runs on the server (or during pre-rendering)
793
+ * The [`handleFetch`](https://svelte.dev/docs/kit/hooks#Server-hooks-handleFetch) hook allows you to modify (or replace) the result of an [`event.fetch`](https://svelte.dev/docs/kit/load#Making-fetch-requests) call that runs on the server (or during prerendering) inside an endpoint, `load`, `action`, `handle`, `handleError` or `reroute`.
794
794
  */
795
795
  export type HandleFetch = (input: {
796
796
  event: RequestEvent;
@@ -1409,7 +1409,7 @@ export interface ServerLoadEvent<
1409
1409
  }
1410
1410
 
1411
1411
  /**
1412
- * Shape of a form action method that is part of `export const actions = {..}` in `+page.server.js`.
1412
+ * Shape of a form action method that is part of `export const actions = {...}` in `+page.server.js`.
1413
1413
  * See [form actions](https://svelte.dev/docs/kit/form-actions) for more information.
1414
1414
  */
1415
1415
  export type Action<
@@ -1419,7 +1419,7 @@ export type Action<
1419
1419
  > = (event: RequestEvent<Params, RouteId>) => MaybePromise<OutputData>;
1420
1420
 
1421
1421
  /**
1422
- * Shape of the `export const actions = {..}` object in `+page.server.js`.
1422
+ * Shape of the `export const actions = {...}` object in `+page.server.js`.
1423
1423
  * See [form actions](https://svelte.dev/docs/kit/form-actions) for more information.
1424
1424
  */
1425
1425
  export type Actions<
@@ -3,7 +3,9 @@ import { mkdirp } from '../../../utils/filesystem.js';
3
3
  import { filter_fonts, find_deps, resolve_symlinks } from './utils.js';
4
4
  import { s } from '../../../utils/misc.js';
5
5
  import { normalizePath } from 'vite';
6
- import { basename } from 'node:path';
6
+ import { basename, join } from 'node:path';
7
+ import { create_node_analyser } from '../static_analysis/index.js';
8
+
7
9
 
8
10
  /**
9
11
  * @param {string} out
@@ -13,8 +15,9 @@ import { basename } from 'node:path';
13
15
  * @param {import('vite').Manifest | null} client_manifest
14
16
  * @param {import('vite').Rollup.OutputAsset[] | null} css
15
17
  * @param {import('types').RecursiveRequired<import('types').ValidatedConfig['kit']['output']>} output_config
18
+ * @param {Map<string, Record<string, any> | null>} static_exports
16
19
  */
17
- export function build_server_nodes(out, kit, manifest_data, server_manifest, client_manifest, css, output_config) {
20
+ export async function build_server_nodes(out, kit, manifest_data, server_manifest, client_manifest, css, output_config, static_exports) {
18
21
  mkdirp(`${out}/server/nodes`);
19
22
  mkdirp(`${out}/server/stylesheets`);
20
23
 
@@ -73,7 +76,17 @@ export function build_server_nodes(out, kit, manifest_data, server_manifest, cli
73
76
  }
74
77
  }
75
78
 
76
- manifest_data.nodes.forEach((node, i) => {
79
+ const { get_page_options } = create_node_analyser({
80
+ resolve: (server_node) => {
81
+ // Windows needs the file:// protocol for absolute path dynamic imports
82
+ return import(`file://${join(out, 'server', resolve_symlinks(server_manifest, server_node).chunk.file)}`);
83
+ },
84
+ static_exports
85
+ });
86
+
87
+ for (let i = 0; i < manifest_data.nodes.length; i++) {
88
+ const node = manifest_data.nodes[i];
89
+
77
90
  /** @type {string[]} */
78
91
  const imports = [];
79
92
 
@@ -101,12 +114,16 @@ export function build_server_nodes(out, kit, manifest_data, server_manifest, cli
101
114
  }
102
115
 
103
116
  if (node.universal) {
104
- imports.push(
105
- `import * as universal from '../${
106
- resolve_symlinks(server_manifest, node.universal).chunk.file
107
- }';`
108
- );
109
- exports.push('export { universal };');
117
+ const page_options = await get_page_options(node);
118
+ if (!!page_options && page_options.ssr === false) {
119
+ exports.push(`export const universal = ${s(page_options, null, 2)};`)
120
+ } else {
121
+ imports.push(
122
+ `import * as universal from '../${resolve_symlinks(server_manifest, node.universal).chunk.file}';`
123
+ );
124
+ // TODO: when building for analysis, explain why the file was loaded on the server if we fail to load it
125
+ exports.push('export { universal };');
126
+ }
110
127
  exports.push(`export const universal_id = ${s(node.universal)};`);
111
128
  }
112
129
 
@@ -186,5 +203,5 @@ export function build_server_nodes(out, kit, manifest_data, server_manifest, cli
186
203
  `${out}/server/nodes/${i}.js`,
187
204
  `${imports.join('\n')}\n\n${exports.join('\n')}\n`
188
205
  );
189
- });
206
+ }
190
207
  }
@@ -19,6 +19,7 @@ import { not_found } from '../utils.js';
19
19
  import { SCHEME } from '../../../utils/url.js';
20
20
  import { check_feature } from '../../../utils/features.js';
21
21
  import { escape_html } from '../../../utils/escape.js';
22
+ import { create_node_analyser } from '../static_analysis/index.js';
22
23
 
23
24
  const cwd = process.cwd();
24
25
  // vite-specifc queries that we should skip handling for css urls
@@ -101,6 +102,9 @@ export async function dev(vite, vite_config, svelte_config) {
101
102
  return { module, module_node, url };
102
103
  }
103
104
 
105
+ /** @type {(file: string) => void} */
106
+ let invalidate_page_options;
107
+
104
108
  function update_manifest() {
105
109
  try {
106
110
  ({ manifest_data } = sync.create(svelte_config));
@@ -124,6 +128,14 @@ export async function dev(vite, vite_config, svelte_config) {
124
128
  return;
125
129
  }
126
130
 
131
+ const node_analyser = create_node_analyser({
132
+ resolve: async (server_node) => {
133
+ const { module } = await resolve(server_node);
134
+ return module;
135
+ }
136
+ });
137
+ invalidate_page_options = node_analyser.invalidate_page_options;
138
+
127
139
  manifest = {
128
140
  appDir: svelte_config.kit.appDir,
129
141
  appPath: svelte_config.kit.appDir,
@@ -202,9 +214,15 @@ export async function dev(vite, vite_config, svelte_config) {
202
214
  }
203
215
 
204
216
  if (node.universal) {
205
- const { module, module_node } = await resolve(node.universal);
206
- module_nodes.push(module_node);
207
- result.universal = module;
217
+ const page_options = await node_analyser.get_page_options(node);
218
+ if (page_options?.ssr === false) {
219
+ result.universal = page_options;
220
+ } else {
221
+ // TODO: explain why the file was loaded on the server if we fail to load it
222
+ const { module, module_node } = await resolve(node.universal);
223
+ module_nodes.push(module_node);
224
+ result.universal = module;
225
+ }
208
226
  }
209
227
 
210
228
  if (node.server) {
@@ -344,6 +362,7 @@ export async function dev(vite, vite_config, svelte_config) {
344
362
  if (timeout || restarting) return;
345
363
 
346
364
  sync.update(svelte_config, manifest_data, file);
365
+ invalidate_page_options(path.relative(cwd, file));
347
366
  });
348
367
 
349
368
  const { appTemplate, errorTemplate, serviceWorker, hooks } = svelte_config.kit.files;
@@ -34,7 +34,7 @@ import {
34
34
  sveltekit_paths,
35
35
  sveltekit_server
36
36
  } from './module_ids.js';
37
- import { resolve_peer_dependency } from '../../utils/import.js';
37
+ import { import_peer } from '../../utils/import.js';
38
38
  import { compact } from '../../utils/array.js';
39
39
 
40
40
  const cwd = process.cwd();
@@ -155,7 +155,7 @@ export async function sveltekit() {
155
155
  ...svelte_config.vitePlugin
156
156
  };
157
157
 
158
- const { svelte } = await resolve_peer_dependency('@sveltejs/vite-plugin-svelte');
158
+ const { svelte } = await import_peer('@sveltejs/vite-plugin-svelte');
159
159
 
160
160
  return [...svelte(vite_plugin_svelte_options), ...(await kit({ svelte_config }))];
161
161
  }
@@ -181,7 +181,7 @@ let manifest_data;
181
181
  * @return {Promise<import('vite').Plugin[]>}
182
182
  */
183
183
  async function kit({ svelte_config }) {
184
- const vite = await resolve_peer_dependency('vite');
184
+ const vite = await import_peer('vite');
185
185
 
186
186
  const { kit } = svelte_config;
187
187
  const out = `${kit.outDir}/output`;
@@ -818,26 +818,17 @@ Tips:
818
818
  })};\n`
819
819
  );
820
820
 
821
- // first, build server nodes without the client manifest so we can analyse it
822
821
  log.info('Analysing routes');
823
822
 
824
- build_server_nodes(
825
- out,
826
- kit,
827
- manifest_data,
828
- server_manifest,
829
- null,
830
- null,
831
- svelte_config.output
832
- );
833
-
834
- const metadata = await analyse({
823
+ const { metadata, static_exports } = await analyse({
835
824
  hash: kit.router.type === 'hash',
836
825
  manifest_path,
837
826
  manifest_data,
838
827
  server_manifest,
839
828
  tracked_features,
840
- env: { ...env.private, ...env.public }
829
+ env: { ...env.private, ...env.public },
830
+ out,
831
+ output_config: svelte_config.output
841
832
  });
842
833
 
843
834
  log.info('Building app');
@@ -983,14 +974,15 @@ Tips:
983
974
  );
984
975
 
985
976
  // regenerate nodes with the client manifest...
986
- build_server_nodes(
977
+ await build_server_nodes(
987
978
  out,
988
979
  kit,
989
980
  manifest_data,
990
981
  server_manifest,
991
982
  client_manifest,
992
983
  css,
993
- svelte_config.kit.output
984
+ svelte_config.kit.output,
985
+ static_exports
994
986
  );
995
987
 
996
988
  // ...and prerender
@@ -14,7 +14,7 @@ import { not_found } from '../utils.js';
14
14
  /** @typedef {(req: Req, res: Res, next: () => void) => void} Handler */
15
15
 
16
16
  /**
17
- * @param {{ middlewares: import('connect').Server }} vite
17
+ * @param {import('vite').PreviewServer} vite
18
18
  * @param {import('vite').ResolvedConfig} vite_config
19
19
  * @param {import('types').ValidatedConfig} svelte_config
20
20
  */
@@ -0,0 +1,259 @@
1
+ import { tsPlugin } from '@sveltejs/acorn-typescript';
2
+ import { Parser } from 'acorn';
3
+ import { read } from '../../../utils/filesystem.js';
4
+
5
+ const inheritable_page_options = new Set(['ssr', 'prerender', 'csr', 'trailingSlash', 'config']);
6
+
7
+ const page_options = new Set([...inheritable_page_options, 'entries']);
8
+
9
+ const skip_parsing_regex = new RegExp(
10
+ `${Array.from(page_options).join('|')}|(?:export[\\s\\n]+\\*[\\s\\n]+from)`
11
+ );
12
+
13
+ const parser = Parser.extend(tsPlugin());
14
+
15
+ /**
16
+ * Collects exported page options from a +page.js/+layout.js file.
17
+ * We ignore reassignments and use the declared value.
18
+ * Returns `null` if any export is too difficult to analyse.
19
+ * @param {string} filename
20
+ * @param {string} input
21
+ * @returns {Record<string, any> | null}
22
+ */
23
+ export function statically_analyse_exports(filename, input) {
24
+ // if there's a chance there are no page exports or export all declaration,
25
+ // then we can skip the AST parsing which is expensive
26
+ if (!skip_parsing_regex.test(input)) {
27
+ return {};
28
+ }
29
+
30
+ try {
31
+ const source = parser.parse(input, {
32
+ sourceType: 'module',
33
+ ecmaVersion: 'latest'
34
+ });
35
+
36
+ /** @type {Map<string, import('acorn').Literal['value']>} */
37
+ const static_exports = new Map();
38
+
39
+ for (const statement of source.body) {
40
+ // ignore export all declarations with aliases that are not page options
41
+ if (
42
+ statement.type === 'ExportAllDeclaration' &&
43
+ statement.exported &&
44
+ !page_options.has(get_name(statement.exported))
45
+ ) {
46
+ continue;
47
+ }
48
+
49
+ if (
50
+ statement.type === 'ExportDefaultDeclaration' ||
51
+ statement.type === 'ExportAllDeclaration'
52
+ ) {
53
+ return null;
54
+ } else if (statement.type !== 'ExportNamedDeclaration') {
55
+ continue;
56
+ }
57
+
58
+ if (statement.specifiers.length) {
59
+ /** @type {Map<string, string>} */
60
+ const export_specifiers = new Map();
61
+ for (const specifier of statement.specifiers) {
62
+ const exported_name = get_name(specifier.exported);
63
+ if (!page_options.has(exported_name)) {
64
+ continue;
65
+ }
66
+
67
+ if (statement.source) {
68
+ return null;
69
+ }
70
+
71
+ export_specifiers.set(get_name(specifier.local), exported_name);
72
+ }
73
+
74
+ for (const statement of source.body) {
75
+ switch (statement.type) {
76
+ case 'ImportDeclaration': {
77
+ for (const import_specifier of statement.specifiers) {
78
+ if (export_specifiers.has(import_specifier.local.name)) {
79
+ return null;
80
+ }
81
+ }
82
+ break;
83
+ }
84
+ case 'ExportNamedDeclaration':
85
+ case 'VariableDeclaration':
86
+ case 'FunctionDeclaration':
87
+ case 'ClassDeclaration': {
88
+ const declaration =
89
+ statement.type === 'ExportNamedDeclaration' ? statement.declaration : statement;
90
+
91
+ if (!declaration) {
92
+ break;
93
+ }
94
+
95
+ // class and function declarations
96
+ if (declaration.type !== 'VariableDeclaration') {
97
+ if (export_specifiers.has(declaration.id.name)) {
98
+ return null;
99
+ }
100
+ break;
101
+ }
102
+
103
+ for (const variable_declarator of declaration.declarations) {
104
+ if (
105
+ variable_declarator.id.type !== 'Identifier' ||
106
+ !export_specifiers.has(variable_declarator.id.name)
107
+ ) {
108
+ continue;
109
+ }
110
+
111
+ if (variable_declarator.init?.type === 'Literal') {
112
+ static_exports.set(
113
+ /** @type {string} */ (export_specifiers.get(variable_declarator.id.name)),
114
+ variable_declarator.init.value
115
+ );
116
+ export_specifiers.delete(variable_declarator.id.name);
117
+ continue;
118
+ }
119
+
120
+ // references a declaration we can't easily evaluate statically
121
+ return null;
122
+ }
123
+ break;
124
+ }
125
+ }
126
+ }
127
+
128
+ // there were some export specifiers that we couldn't resolve
129
+ if (export_specifiers.size) {
130
+ return null;
131
+ }
132
+ continue;
133
+ }
134
+
135
+ if (!statement.declaration) {
136
+ continue;
137
+ }
138
+
139
+ // class and function declarations
140
+ if (statement.declaration.type !== 'VariableDeclaration') {
141
+ if (page_options.has(statement.declaration.id.name)) {
142
+ return null;
143
+ }
144
+ continue;
145
+ }
146
+
147
+ for (const declaration of statement.declaration.declarations) {
148
+ if (declaration.id.type !== 'Identifier') {
149
+ return null;
150
+ }
151
+
152
+ if (!page_options.has(declaration.id.name)) {
153
+ continue;
154
+ }
155
+
156
+ if (declaration.init?.type === 'Literal') {
157
+ static_exports.set(declaration.id.name, declaration.init.value);
158
+ continue;
159
+ }
160
+
161
+ // references a declaration we can't easily evaluate statically
162
+ return null;
163
+ }
164
+ }
165
+
166
+ return Object.fromEntries(static_exports);
167
+ } catch (error) {
168
+ if (error instanceof Error) {
169
+ error.message = `Failed to statically analyse ${filename}. ${error.message}`;
170
+ }
171
+ throw error;
172
+ }
173
+ }
174
+
175
+ /**
176
+ * @param {import('acorn').Identifier | import('acorn').Literal} node
177
+ * @returns {string}
178
+ */
179
+ export function get_name(node) {
180
+ return node.type === 'Identifier' ? node.name : /** @type {string} */ (node.value);
181
+ }
182
+
183
+ /**
184
+ * @param {{
185
+ * resolve: (file: string) => Promise<Record<string, any>>;
186
+ * static_exports?: Map<string, Record<string, any> | null>;
187
+ * }} opts
188
+ */
189
+ export function create_node_analyser({ resolve, static_exports = new Map() }) {
190
+ /**
191
+ * Computes the final page options for a node (if possible). Otherwise, returns `null`.
192
+ * @param {import('types').PageNode} node
193
+ * @returns {Promise<import('types').UniversalNode | null>}
194
+ */
195
+ const get_page_options = async (node) => {
196
+ if (node.universal && static_exports.has(node.universal)) {
197
+ return /** @type {import('types').UniversalNode | null} */ (
198
+ static_exports.get(node.universal)
199
+ );
200
+ }
201
+
202
+ /** @type {Record<string, any> | null} */
203
+ let page_options = {};
204
+
205
+ if (node.server) {
206
+ const module = await resolve(node.server);
207
+ for (const key in inheritable_page_options) {
208
+ if (key in module) {
209
+ page_options[key] = module[key];
210
+ }
211
+ }
212
+ }
213
+
214
+ if (node.universal) {
215
+ let universal_exports = static_exports.get(node.universal);
216
+ if (universal_exports === undefined) {
217
+ const input = read(node.universal);
218
+ universal_exports = statically_analyse_exports(node.universal, input);
219
+ }
220
+
221
+ if (universal_exports === null) {
222
+ static_exports.set(node.universal, null);
223
+ return null;
224
+ }
225
+
226
+ page_options = { ...page_options, ...universal_exports };
227
+ }
228
+
229
+ if (node.parent) {
230
+ const parent_options = await get_page_options(node.parent);
231
+ if (parent_options === null) {
232
+ // if the parent cannot be statically analysed, we can't know what
233
+ // page options the current node inherits, so we invalidate it too
234
+ if (node.universal) {
235
+ static_exports.set(node.universal, null);
236
+ }
237
+ return null;
238
+ }
239
+
240
+ page_options = { ...parent_options, ...page_options };
241
+ }
242
+
243
+ if (node.universal) {
244
+ static_exports.set(node.universal, page_options);
245
+ }
246
+
247
+ return page_options;
248
+ };
249
+
250
+ /**
251
+ * @param {string} file
252
+ * @returns {void}
253
+ */
254
+ const invalidate_page_options = (file) => {
255
+ static_exports.delete(file);
256
+ };
257
+
258
+ return { get_page_options, invalidate_page_options };
259
+ }
@@ -15,7 +15,7 @@ export async function render_endpoint(event, mod, state) {
15
15
 
16
16
  let handler = mod[method] || mod.fallback;
17
17
 
18
- if (method === 'HEAD' && mod.GET && !mod.HEAD) {
18
+ if (method === 'HEAD' && !mod.HEAD && mod.GET) {
19
19
  handler = mod.GET;
20
20
  }
21
21
 
@@ -29,6 +29,7 @@ export async function load_server_data({ event, state, node, parent }) {
29
29
  };
30
30
 
31
31
  const load = node.server.load;
32
+ // TODO: shouldn't this be calculated using PageNodes? there could be a trailingSlash option on a layout
32
33
  const slash = node.server.trailingSlash;
33
34
 
34
35
  if (!load) {
@@ -288,7 +288,7 @@ export async function respond(request, options, manifest, state) {
288
288
  let trailing_slash = 'never';
289
289
 
290
290
  try {
291
- /** @type {PageNodes|undefined} */
291
+ /** @type {PageNodes | undefined} */
292
292
  const page_nodes = route?.page
293
293
  ? new PageNodes(await load_page_nodes(route.page, manifest))
294
294
  : undefined;
@@ -401,7 +401,7 @@ export interface SSRNode {
401
401
  universal_id?: string;
402
402
  server_id?: string;
403
403
 
404
- /** inlined styles. */
404
+ /** inlined styles */
405
405
  inline_styles?(): MaybePromise<Record<string, string>>;
406
406
  /** Svelte component */
407
407
  component?: SSRComponentLoader;
@@ -1,25 +1,52 @@
1
- import * as imr from 'import-meta-resolve';
2
1
  import process from 'node:process';
3
- import { pathToFileURL } from 'node:url';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+
5
+ /**
6
+ * Resolves a peer dependency relative to the current CWD. Duplicated with `packages/adapter-auto`
7
+ * @param {string} dependency
8
+ */
9
+ function resolve_peer(dependency) {
10
+ let [name, ...parts] = dependency.split('/');
11
+ if (name[0] === '@') name += `/${parts.shift()}`;
12
+
13
+ let dir = process.cwd();
14
+
15
+ while (!fs.existsSync(`${dir}/node_modules/${name}/package.json`)) {
16
+ if (dir === (dir = path.dirname(dir))) {
17
+ throw new Error(
18
+ `Could not resolve peer dependency "${name}" relative to your project — please install it and try again.`
19
+ );
20
+ }
21
+ }
22
+
23
+ const pkg_dir = `${dir}/node_modules/${name}`;
24
+ const pkg = JSON.parse(fs.readFileSync(`${pkg_dir}/package.json`, 'utf-8'));
25
+
26
+ const subpackage = ['.', ...parts].join('/');
27
+
28
+ let exported = pkg.exports[subpackage];
29
+
30
+ while (typeof exported !== 'string') {
31
+ if (!exported) {
32
+ throw new Error(`Could not find valid "${subpackage}" export in ${name}/package.json`);
33
+ }
34
+
35
+ exported = exported['import'] ?? exported['default'];
36
+ }
37
+
38
+ return path.resolve(pkg_dir, exported);
39
+ }
4
40
 
5
41
  /**
6
42
  * Resolve a dependency relative to the current working directory,
7
43
  * rather than relative to this package (but falls back to trying that, if necessary)
8
44
  * @param {string} dependency
9
45
  */
10
- export async function resolve_peer_dependency(dependency) {
46
+ export async function import_peer(dependency) {
11
47
  try {
12
- // @ts-expect-error the types are wrong
13
- const resolved = imr.resolve(dependency, pathToFileURL(process.cwd() + '/dummy.js'));
14
- return await import(resolved);
48
+ return await import(resolve_peer(dependency));
15
49
  } catch {
16
- try {
17
- // both imr.resolve and await import above can throw, which is why we can't just do import(resolved).catch(...) above
18
- return await import(dependency);
19
- } catch {
20
- throw new Error(
21
- `Could not resolve peer dependency "${dependency}" relative to your project — please install it and try again.`
22
- );
23
- }
50
+ return await import(dependency);
24
51
  }
25
52
  }
@@ -39,16 +39,15 @@ export class PageNodes {
39
39
  }
40
40
 
41
41
  /**
42
- * @template {'prerender' | 'ssr' | 'csr' | 'trailingSlash' | 'entries'} Option
43
- * @template {(import('types').UniversalNode | import('types').ServerNode)[Option]} Value
42
+ * @template {'prerender' | 'ssr' | 'csr' | 'trailingSlash'} Option
44
43
  * @param {Option} option
45
44
  * @returns {Value | undefined}
46
45
  */
47
46
  #get_option(option) {
47
+ /** @typedef {(import('types').UniversalNode | import('types').ServerNode)[Option]} Value */
48
+
48
49
  return this.data.reduce((value, node) => {
49
- return /** @type {Value} TypeScript's too dumb to understand this */ (
50
- node?.universal?.[option] ?? node?.server?.[option] ?? value
51
- );
50
+ return node?.universal?.[option] ?? node?.server?.[option] ?? value;
52
51
  }, /** @type {Value | undefined} */ (undefined));
53
52
  }
54
53
 
@@ -77,6 +76,7 @@ export class PageNodes {
77
76
 
78
77
  current = {
79
78
  ...current,
79
+ // TODO: should we override the server config value with the universal value similar to other page options?
80
80
  ...node?.universal?.config,
81
81
  ...node?.server?.config
82
82
  };
package/src/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // generated during release, do not modify
2
2
 
3
3
  /** @type {string} */
4
- export const VERSION = '2.20.8';
4
+ export const VERSION = '2.21.1';
package/types/index.d.ts CHANGED
@@ -18,18 +18,18 @@ declare module '@sveltejs/kit' {
18
18
  */
19
19
  adapt: (builder: Builder) => MaybePromise<void>;
20
20
  /**
21
- * Checks called during dev and build to determine whether specific features will work in production with this adapter
21
+ * Checks called during dev and build to determine whether specific features will work in production with this adapter.
22
22
  */
23
23
  supports?: {
24
24
  /**
25
- * Test support for `read` from `$app/server`
26
- * @param config The merged route config
25
+ * Test support for `read` from `$app/server`.
26
+ * @param details.config The merged route config
27
27
  */
28
28
  read?: (details: { config: any; route: { id: string } }) => boolean;
29
29
  };
30
30
  /**
31
31
  * Creates an `Emulator`, which allows the adapter to influence the environment
32
- * during dev, build and prerendering
32
+ * during dev, build and prerendering.
33
33
  */
34
34
  emulate?: () => MaybePromise<Emulator>;
35
35
  }
@@ -772,7 +772,7 @@ declare module '@sveltejs/kit' {
772
772
  }) => MaybePromise<void | App.Error>;
773
773
 
774
774
  /**
775
- * The [`handleFetch`](https://svelte.dev/docs/kit/hooks#Server-hooks-handleFetch) hook allows you to modify (or replace) a `fetch` request that happens inside a `load` function that runs on the server (or during pre-rendering)
775
+ * The [`handleFetch`](https://svelte.dev/docs/kit/hooks#Server-hooks-handleFetch) hook allows you to modify (or replace) the result of an [`event.fetch`](https://svelte.dev/docs/kit/load#Making-fetch-requests) call that runs on the server (or during prerendering) inside an endpoint, `load`, `action`, `handle`, `handleError` or `reroute`.
776
776
  */
777
777
  export type HandleFetch = (input: {
778
778
  event: RequestEvent;
@@ -1391,7 +1391,7 @@ declare module '@sveltejs/kit' {
1391
1391
  }
1392
1392
 
1393
1393
  /**
1394
- * Shape of a form action method that is part of `export const actions = {..}` in `+page.server.js`.
1394
+ * Shape of a form action method that is part of `export const actions = {...}` in `+page.server.js`.
1395
1395
  * See [form actions](https://svelte.dev/docs/kit/form-actions) for more information.
1396
1396
  */
1397
1397
  export type Action<
@@ -1401,7 +1401,7 @@ declare module '@sveltejs/kit' {
1401
1401
  > = (event: RequestEvent<Params, RouteId>) => MaybePromise<OutputData>;
1402
1402
 
1403
1403
  /**
1404
- * Shape of the `export const actions = {..}` object in `+page.server.js`.
1404
+ * Shape of the `export const actions = {...}` object in `+page.server.js`.
1405
1405
  * See [form actions](https://svelte.dev/docs/kit/form-actions) for more information.
1406
1406
  */
1407
1407
  export type Actions<
@@ -1881,7 +1881,7 @@ declare module '@sveltejs/kit' {
1881
1881
  universal_id?: string;
1882
1882
  server_id?: string;
1883
1883
 
1884
- /** inlined styles. */
1884
+ /** inlined styles */
1885
1885
  inline_styles?(): MaybePromise<Record<string, string>>;
1886
1886
  /** Svelte component */
1887
1887
  component?: SSRComponentLoader;
@@ -2001,12 +2001,12 @@ declare module '@sveltejs/kit' {
2001
2001
  */
2002
2002
  export function text(body: string, init?: ResponseInit | undefined): Response;
2003
2003
  /**
2004
- * Create an `ActionFailure` object.
2004
+ * Create an `ActionFailure` object. Call when form submission fails.
2005
2005
  * @param 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.
2006
2006
  * */
2007
2007
  export function fail(status: number): ActionFailure<undefined>;
2008
2008
  /**
2009
- * Create an `ActionFailure` object.
2009
+ * Create an `ActionFailure` object. Call when form submission fails.
2010
2010
  * @param 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.
2011
2011
  * @param data Data associated with the failure (e.g. validation errors)
2012
2012
  * */
@@ -5,7 +5,10 @@
5
5
  "Adapter",
6
6
  "LoadProperties",
7
7
  "AwaitedActions",
8
+ "OptionalUnion",
9
+ "uniqueSymbol",
8
10
  "ActionFailure",
11
+ "UnpackValidationError",
9
12
  "Builder",
10
13
  "Config",
11
14
  "Cookies",
@@ -166,6 +169,6 @@
166
169
  null,
167
170
  null
168
171
  ],
169
- "mappings": "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",
172
+ "mappings": "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",
170
173
  "ignoreList": []
171
174
  }