@sveltejs/kit 2.20.7 → 2.21.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.
- package/package.json +7 -6
- package/src/core/sync/utils.js +2 -2
- package/src/exports/public.d.ts +7 -7
- package/src/exports/vite/build/build_server.js +22 -10
- package/src/exports/vite/dev/index.js +20 -3
- package/src/exports/vite/index.js +5 -5
- package/src/exports/vite/preview/index.js +1 -1
- package/src/exports/vite/static_analysis/index.js +259 -0
- package/src/runtime/server/endpoint.js +1 -1
- package/src/runtime/server/page/index.js +15 -9
- package/src/runtime/server/page/load_data.js +1 -0
- package/src/runtime/server/respond.js +1 -1
- package/src/types/internal.d.ts +1 -1
- package/src/utils/import.js +41 -14
- package/src/utils/page_nodes.js +5 -5
- package/src/version.js +1 -1
- package/types/index.d.ts +8 -8
- package/types/index.d.ts.map +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/kit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.21.0",
|
|
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",
|
|
@@ -31,18 +32,18 @@
|
|
|
31
32
|
"sirv": "^3.0.0"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
|
-
"@playwright/test": "^1.
|
|
35
|
+
"@playwright/test": "^1.51.1",
|
|
35
36
|
"@sveltejs/vite-plugin-svelte": "^5.0.1",
|
|
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.
|
|
40
|
+
"dts-buddy": "^0.6.0",
|
|
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.
|
|
45
|
-
"vitest": "^3.
|
|
45
|
+
"vite": "^6.2.7",
|
|
46
|
+
"vitest": "^3.1.1"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|
|
48
49
|
"@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0",
|
package/src/core/sync/utils.js
CHANGED
|
@@ -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 {
|
|
4
|
+
import { import_peer } from '../../utils/import.js';
|
|
5
5
|
|
|
6
6
|
/** @type {{ VERSION: string }} */
|
|
7
|
-
const { VERSION } = await
|
|
7
|
+
const { VERSION } = await import_peer('svelte/compiler');
|
|
8
8
|
|
|
9
9
|
/** @type {Map<string, string>} */
|
|
10
10
|
const previous_contents = new Map();
|
package/src/exports/public.d.ts
CHANGED
|
@@ -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
|
|
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 prerendering).
|
|
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 = {
|
|
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 = {
|
|
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,8 @@ 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_static_analyser } from '../static_analysis/index.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* @param {string} out
|
|
@@ -14,7 +15,7 @@ import { basename } from 'node:path';
|
|
|
14
15
|
* @param {import('vite').Rollup.OutputAsset[] | null} css
|
|
15
16
|
* @param {import('types').RecursiveRequired<import('types').ValidatedConfig['kit']['output']>} output_config
|
|
16
17
|
*/
|
|
17
|
-
export function build_server_nodes(out, kit, manifest_data, server_manifest, client_manifest, css, output_config) {
|
|
18
|
+
export async function build_server_nodes(out, kit, manifest_data, server_manifest, client_manifest, css, output_config) {
|
|
18
19
|
mkdirp(`${out}/server/nodes`);
|
|
19
20
|
mkdirp(`${out}/server/stylesheets`);
|
|
20
21
|
|
|
@@ -73,7 +74,14 @@ export function build_server_nodes(out, kit, manifest_data, server_manifest, cli
|
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
|
|
77
|
+
const { get_page_options } = create_static_analyser(async (server_node) => {
|
|
78
|
+
// Windows needs the file:// protocol for absolute path dynamic imports
|
|
79
|
+
return import(`file://${join(out, 'server', resolve_symlinks(server_manifest, server_node).chunk.file)}`);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
for (let i = 0; i < manifest_data.nodes.length; i++) {
|
|
83
|
+
const node = manifest_data.nodes[i];
|
|
84
|
+
|
|
77
85
|
/** @type {string[]} */
|
|
78
86
|
const imports = [];
|
|
79
87
|
|
|
@@ -101,12 +109,16 @@ export function build_server_nodes(out, kit, manifest_data, server_manifest, cli
|
|
|
101
109
|
}
|
|
102
110
|
|
|
103
111
|
if (node.universal) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
const page_options = await get_page_options(node);
|
|
113
|
+
if (!!page_options && page_options.ssr === false) {
|
|
114
|
+
exports.push(`export const universal = ${s(page_options, null, 2)};`)
|
|
115
|
+
} else {
|
|
116
|
+
imports.push(
|
|
117
|
+
`import * as universal from '../${resolve_symlinks(server_manifest, node.universal).chunk.file}';`
|
|
118
|
+
);
|
|
119
|
+
// TODO: when building for analysis, explain why the file was loaded on the server if we fail to load it
|
|
120
|
+
exports.push('export { universal };');
|
|
121
|
+
}
|
|
110
122
|
exports.push(`export const universal_id = ${s(node.universal)};`);
|
|
111
123
|
}
|
|
112
124
|
|
|
@@ -186,5 +198,5 @@ export function build_server_nodes(out, kit, manifest_data, server_manifest, cli
|
|
|
186
198
|
`${out}/server/nodes/${i}.js`,
|
|
187
199
|
`${imports.join('\n')}\n\n${exports.join('\n')}\n`
|
|
188
200
|
);
|
|
189
|
-
}
|
|
201
|
+
}
|
|
190
202
|
}
|
|
@@ -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_static_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,12 @@ export async function dev(vite, vite_config, svelte_config) {
|
|
|
124
128
|
return;
|
|
125
129
|
}
|
|
126
130
|
|
|
131
|
+
const static_analyser = create_static_analyser(async (server_node) => {
|
|
132
|
+
const { module } = await resolve(server_node);
|
|
133
|
+
return module;
|
|
134
|
+
});
|
|
135
|
+
invalidate_page_options = static_analyser.invalidate_page_options;
|
|
136
|
+
|
|
127
137
|
manifest = {
|
|
128
138
|
appDir: svelte_config.kit.appDir,
|
|
129
139
|
appPath: svelte_config.kit.appDir,
|
|
@@ -202,9 +212,15 @@ export async function dev(vite, vite_config, svelte_config) {
|
|
|
202
212
|
}
|
|
203
213
|
|
|
204
214
|
if (node.universal) {
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
215
|
+
const page_options = await static_analyser.get_page_options(node);
|
|
216
|
+
if (page_options?.ssr === false) {
|
|
217
|
+
result.universal = page_options;
|
|
218
|
+
} else {
|
|
219
|
+
// TODO: explain why the file was loaded on the server if we fail to load it
|
|
220
|
+
const { module, module_node } = await resolve(node.universal);
|
|
221
|
+
module_nodes.push(module_node);
|
|
222
|
+
result.universal = module;
|
|
223
|
+
}
|
|
208
224
|
}
|
|
209
225
|
|
|
210
226
|
if (node.server) {
|
|
@@ -344,6 +360,7 @@ export async function dev(vite, vite_config, svelte_config) {
|
|
|
344
360
|
if (timeout || restarting) return;
|
|
345
361
|
|
|
346
362
|
sync.update(svelte_config, manifest_data, file);
|
|
363
|
+
invalidate_page_options(path.relative(cwd, file));
|
|
347
364
|
});
|
|
348
365
|
|
|
349
366
|
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 {
|
|
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
|
|
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
|
|
184
|
+
const vite = await import_peer('vite');
|
|
185
185
|
|
|
186
186
|
const { kit } = svelte_config;
|
|
187
187
|
const out = `${kit.outDir}/output`;
|
|
@@ -821,7 +821,7 @@ Tips:
|
|
|
821
821
|
// first, build server nodes without the client manifest so we can analyse it
|
|
822
822
|
log.info('Analysing routes');
|
|
823
823
|
|
|
824
|
-
build_server_nodes(
|
|
824
|
+
await build_server_nodes(
|
|
825
825
|
out,
|
|
826
826
|
kit,
|
|
827
827
|
manifest_data,
|
|
@@ -983,7 +983,7 @@ Tips:
|
|
|
983
983
|
);
|
|
984
984
|
|
|
985
985
|
// regenerate nodes with the client manifest...
|
|
986
|
-
build_server_nodes(
|
|
986
|
+
await build_server_nodes(
|
|
987
987
|
out,
|
|
988
988
|
kit,
|
|
989
989
|
manifest_data,
|
|
@@ -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 {
|
|
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 {(server_node: string) => Promise<Record<string, any>>} resolve
|
|
185
|
+
*/
|
|
186
|
+
export function create_static_analyser(resolve) {
|
|
187
|
+
/** @type {Map<string, Record<string, any> | null>} */
|
|
188
|
+
const static_exports = new Map();
|
|
189
|
+
|
|
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,6 +15,7 @@ import { render_response } from './render.js';
|
|
|
15
15
|
import { respond_with_error } from './respond_with_error.js';
|
|
16
16
|
import { get_data_json } from '../data/index.js';
|
|
17
17
|
import { DEV } from 'esm-env';
|
|
18
|
+
import { PageNodes } from '../../../utils/page_nodes.js';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* The maximum request depth permitted before assuming we're stuck in an infinite loop
|
|
@@ -93,10 +94,13 @@ export async function render_page(event, page, options, manifest, state, nodes,
|
|
|
93
94
|
/** @type {import('./types.js').Fetched[]} */
|
|
94
95
|
const fetched = [];
|
|
95
96
|
|
|
97
|
+
const ssr = nodes.ssr();
|
|
98
|
+
const csr = nodes.csr();
|
|
99
|
+
|
|
96
100
|
// renders an empty 'shell' page if SSR is turned off and if there is
|
|
97
101
|
// no server data to prerender. As a result, the load functions and rendering
|
|
98
102
|
// only occur client-side.
|
|
99
|
-
if (
|
|
103
|
+
if (ssr === false && !(state.prerendering && should_prerender_data)) {
|
|
100
104
|
// if the user makes a request through a non-enhanced form, the returned value is lost
|
|
101
105
|
// because there is no SSR or client-side handling of the response
|
|
102
106
|
if (DEV && action_result && !event.request.headers.has('x-sveltekit-action')) {
|
|
@@ -117,7 +121,7 @@ export async function render_page(event, page, options, manifest, state, nodes,
|
|
|
117
121
|
fetched,
|
|
118
122
|
page_config: {
|
|
119
123
|
ssr: false,
|
|
120
|
-
csr
|
|
124
|
+
csr
|
|
121
125
|
},
|
|
122
126
|
status,
|
|
123
127
|
error: null,
|
|
@@ -171,8 +175,6 @@ export async function render_page(event, page, options, manifest, state, nodes,
|
|
|
171
175
|
});
|
|
172
176
|
});
|
|
173
177
|
|
|
174
|
-
const csr = nodes.csr();
|
|
175
|
-
|
|
176
178
|
/** @type {Array<Promise<Record<string, any> | null>>} */
|
|
177
179
|
const load_promises = nodes.data.map((node, i) => {
|
|
178
180
|
if (load_error) throw load_error;
|
|
@@ -244,16 +246,22 @@ export async function render_page(event, page, options, manifest, state, nodes,
|
|
|
244
246
|
let j = i;
|
|
245
247
|
while (!branch[j]) j -= 1;
|
|
246
248
|
|
|
249
|
+
const layouts = compact(branch.slice(0, j + 1));
|
|
250
|
+
const nodes = new PageNodes(layouts.map((layout) => layout.node));
|
|
251
|
+
|
|
247
252
|
return await render_response({
|
|
248
253
|
event,
|
|
249
254
|
options,
|
|
250
255
|
manifest,
|
|
251
256
|
state,
|
|
252
257
|
resolve_opts,
|
|
253
|
-
page_config: {
|
|
258
|
+
page_config: {
|
|
259
|
+
ssr: nodes.ssr(),
|
|
260
|
+
csr: nodes.csr()
|
|
261
|
+
},
|
|
254
262
|
status,
|
|
255
263
|
error,
|
|
256
|
-
branch:
|
|
264
|
+
branch: layouts.concat({
|
|
257
265
|
node,
|
|
258
266
|
data: null,
|
|
259
267
|
server_data: null
|
|
@@ -294,8 +302,6 @@ export async function render_page(event, page, options, manifest, state, nodes,
|
|
|
294
302
|
});
|
|
295
303
|
}
|
|
296
304
|
|
|
297
|
-
const ssr = nodes.ssr();
|
|
298
|
-
|
|
299
305
|
return await render_response({
|
|
300
306
|
event,
|
|
301
307
|
options,
|
|
@@ -303,7 +309,7 @@ export async function render_page(event, page, options, manifest, state, nodes,
|
|
|
303
309
|
state,
|
|
304
310
|
resolve_opts,
|
|
305
311
|
page_config: {
|
|
306
|
-
csr
|
|
312
|
+
csr,
|
|
307
313
|
ssr
|
|
308
314
|
},
|
|
309
315
|
status,
|
|
@@ -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;
|
package/src/types/internal.d.ts
CHANGED
|
@@ -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;
|
package/src/utils/import.js
CHANGED
|
@@ -1,25 +1,52 @@
|
|
|
1
|
-
import * as imr from 'import-meta-resolve';
|
|
2
1
|
import process from 'node:process';
|
|
3
|
-
import
|
|
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
|
|
46
|
+
export async function import_peer(dependency) {
|
|
11
47
|
try {
|
|
12
|
-
|
|
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
|
-
|
|
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
|
}
|
package/src/utils/page_nodes.js
CHANGED
|
@@ -39,16 +39,15 @@ export class PageNodes {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
|
-
* @template {'prerender' | 'ssr' | 'csr' | 'trailingSlash'
|
|
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
|
|
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
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
|
|
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 prerendering).
|
|
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 = {
|
|
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 = {
|
|
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;
|
package/types/index.d.ts.map
CHANGED
|
@@ -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": ";;;;;;;;;kBA2BiBA,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;aA2BZC,cAAcA;;;;;;aAMdC,cAAcA
|
|
172
|
+
"mappings": "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",
|
|
170
173
|
"ignoreList": []
|
|
171
174
|
}
|