@sveltejs/kit 3.0.0-next.1 → 3.0.0-next.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +33 -21
- package/src/constants.js +2 -0
- package/src/core/adapt/builder.js +32 -49
- package/src/core/adapt/index.js +1 -4
- package/src/core/config/index.js +137 -71
- package/src/core/config/options.js +236 -244
- package/src/core/config/types.d.ts +1 -1
- package/src/core/env.js +121 -5
- package/src/core/generate_manifest/index.js +12 -15
- package/src/core/postbuild/analyse.js +7 -19
- package/src/core/postbuild/crawl.js +22 -6
- package/src/core/postbuild/fallback.js +2 -1
- package/src/core/postbuild/prerender.js +114 -48
- package/src/core/postbuild/queue.js +2 -1
- package/src/core/sync/create_manifest_data/index.js +53 -50
- package/src/core/sync/sync.js +0 -2
- package/src/core/sync/write_client_manifest.js +8 -15
- package/src/core/sync/write_env.js +2 -1
- package/src/core/sync/write_non_ambient.js +12 -9
- package/src/core/sync/write_server.js +14 -15
- package/src/core/sync/write_tsconfig.js +16 -8
- package/src/core/sync/write_tsconfig_test/package.json +7 -0
- package/src/core/sync/write_types/index.js +28 -24
- package/src/core/utils.js +30 -5
- package/src/exports/env/index.js +77 -0
- package/src/exports/hooks/index.js +3 -9
- package/src/exports/hooks/sequence.js +3 -2
- package/src/exports/index.js +35 -13
- package/src/exports/internal/client.js +5 -0
- package/src/exports/internal/env.js +8 -5
- package/src/exports/internal/index.js +1 -90
- package/src/exports/internal/{event.js → server/event.js} +1 -2
- package/src/exports/internal/server/index.js +33 -0
- package/src/exports/internal/shared.js +89 -0
- package/src/exports/node/index.js +62 -15
- package/src/exports/params.js +68 -0
- package/src/exports/public.d.ts +363 -189
- package/src/exports/url.js +86 -0
- package/src/exports/vite/build/build_server.js +53 -59
- package/src/exports/vite/build/remote.js +18 -11
- package/src/exports/vite/build/utils.js +0 -8
- package/src/exports/vite/dev/index.js +92 -50
- package/src/exports/vite/index.js +903 -681
- package/src/exports/vite/module_ids.js +0 -2
- package/src/exports/vite/preview/index.js +32 -24
- package/src/exports/vite/static_analysis/index.js +2 -4
- package/src/exports/vite/static_analysis/types.d.ts +14 -0
- package/src/exports/vite/utils.js +40 -35
- package/src/runtime/app/env/internal.js +4 -4
- package/src/runtime/app/env/types.d.ts +1 -1
- package/src/runtime/app/environment/index.js +3 -3
- package/src/runtime/app/forms.js +24 -7
- package/src/runtime/app/paths/client.js +4 -10
- package/src/runtime/app/paths/internal/client.js +4 -2
- package/src/runtime/app/paths/internal/server.js +2 -23
- package/src/runtime/app/paths/public.d.ts +0 -28
- package/src/runtime/app/paths/server.js +10 -6
- package/src/runtime/app/server/index.js +1 -1
- package/src/runtime/app/server/remote/command.js +0 -3
- package/src/runtime/app/server/remote/form.js +27 -15
- package/src/runtime/app/server/remote/prerender.js +29 -36
- package/src/runtime/app/server/remote/query.js +101 -99
- package/src/runtime/app/server/remote/requested.js +22 -14
- package/src/runtime/app/server/remote/shared.js +30 -26
- package/src/runtime/app/state/client.js +1 -2
- package/src/runtime/app/stores.js +13 -76
- package/src/runtime/client/bundle.js +1 -1
- package/src/runtime/client/client-entry.js +3 -0
- package/src/runtime/client/client.js +411 -318
- package/src/runtime/client/entry.js +24 -3
- package/src/runtime/client/fetcher.js +3 -2
- package/src/runtime/client/ndjson.js +6 -33
- package/src/runtime/client/payload.js +17 -0
- package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
- package/src/runtime/client/remote-functions/command.svelte.js +7 -32
- package/src/runtime/client/remote-functions/form.svelte.js +183 -112
- package/src/runtime/client/remote-functions/prerender.svelte.js +29 -8
- package/src/runtime/client/remote-functions/query/index.js +7 -14
- package/src/runtime/client/remote-functions/query/instance.svelte.js +63 -18
- package/src/runtime/client/remote-functions/query/proxy.js +3 -3
- package/src/runtime/client/remote-functions/query-batch.svelte.js +60 -68
- package/src/runtime/client/remote-functions/query-live/instance.svelte.js +60 -18
- package/src/runtime/client/remote-functions/query-live/iterator.js +36 -55
- package/src/runtime/client/remote-functions/shared.svelte.js +88 -62
- package/src/runtime/client/sse.js +32 -0
- package/src/runtime/client/state.svelte.js +65 -49
- package/src/runtime/client/stream.js +39 -0
- package/src/runtime/client/types.d.ts +11 -7
- package/src/runtime/client/utils.js +0 -96
- package/src/runtime/components/root.svelte +66 -0
- package/src/runtime/env/dynamic/private.js +7 -0
- package/src/runtime/env/dynamic/public.js +7 -0
- package/src/runtime/env/static/private.js +6 -0
- package/src/runtime/env/static/public.js +6 -0
- package/src/runtime/form-utils.js +100 -22
- package/src/runtime/server/cookie.js +69 -52
- package/src/runtime/server/csrf.js +65 -0
- package/src/runtime/server/data/index.js +15 -19
- package/src/runtime/server/env_module.js +0 -5
- package/src/runtime/server/errors.js +135 -0
- package/src/runtime/server/fetch.js +1 -1
- package/src/runtime/server/index.js +22 -12
- package/src/runtime/server/internal.js +25 -0
- package/src/runtime/server/page/actions.js +43 -27
- package/src/runtime/server/page/data_serializer.js +10 -10
- package/src/runtime/server/page/index.js +12 -17
- package/src/runtime/server/page/load_data.js +2 -2
- package/src/runtime/server/page/render.js +114 -193
- package/src/runtime/server/page/respond_with_error.js +11 -11
- package/src/runtime/server/page/server_routing.js +27 -18
- package/src/runtime/server/remote-functions.js +596 -0
- package/src/runtime/server/respond.js +100 -68
- package/src/runtime/server/sourcemaps.js +183 -0
- package/src/runtime/server/utils.js +2 -134
- package/src/runtime/shared.js +83 -13
- package/src/runtime/telemetry/otel.js +1 -1
- package/src/runtime/types.d.ts +8 -0
- package/src/types/ambient-private.d.ts +2 -0
- package/src/types/ambient.d.ts +10 -5
- package/src/types/global-private.d.ts +13 -25
- package/src/types/internal.d.ts +95 -80
- package/src/types/private.d.ts +41 -1
- package/src/utils/error.js +24 -4
- package/src/utils/escape.js +9 -25
- package/src/utils/features.js +1 -1
- package/src/utils/fork.js +7 -2
- package/src/utils/import.js +6 -1
- package/src/utils/imports.js +83 -0
- package/src/utils/mime.js +9 -0
- package/src/utils/page_nodes.js +3 -5
- package/src/utils/params.js +66 -0
- package/src/utils/routing.js +90 -44
- package/src/utils/shared-iterator.js +5 -0
- package/src/utils/streaming.js +14 -4
- package/src/utils/url.js +20 -2
- package/src/version.js +1 -1
- package/types/index.d.ts +537 -557
- package/types/index.d.ts.map +24 -39
- package/src/core/sync/write_root.js +0 -148
- package/src/exports/internal/server.js +0 -22
- package/src/runtime/server/remote.js +0 -457
- package/src/runtime/shared-server.js +0 -7
- package/src/types/synthetic/$lib.md +0 -5
- /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { DEV } from 'esm-env';
|
|
2
|
+
// we use the export subpath to conditionally import the client/server `get_origin`
|
|
3
|
+
// so that `node:async_hooks` isn't pulled into the client build
|
|
4
|
+
import { get_origin } from '#internal';
|
|
5
|
+
import { matches_external_allowlist_entry } from '../utils/url.js';
|
|
6
|
+
|
|
7
|
+
// See https://datatracker.ietf.org/doc/html/rfc2606 - no domains under the .invalid TLD can be registered
|
|
8
|
+
const REDIRECT_BASE = 'https://sveltekit-redirect.invalid';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Whether a redirect location is absolute, i.e. not a root-relative or path-relative URL,
|
|
12
|
+
* and not pointing to the same origin as we're currently on (if determineable).
|
|
13
|
+
* @param {string} location
|
|
14
|
+
*/
|
|
15
|
+
export function is_external_location(location) {
|
|
16
|
+
const origin = get_origin();
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
return !matches_external_allowlist_entry(location, origin ?? REDIRECT_BASE);
|
|
20
|
+
} catch {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const javascript_protocols = new Set(['javascript:', 'data:']);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {string} location
|
|
29
|
+
*/
|
|
30
|
+
function is_javascript_location(location) {
|
|
31
|
+
try {
|
|
32
|
+
return javascript_protocols.has(new URL(location, REDIRECT_BASE).protocol);
|
|
33
|
+
} catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param {string} location
|
|
40
|
+
* @param {{ external?: boolean | string[] }} [options]
|
|
41
|
+
*/
|
|
42
|
+
export function validate_redirect_location(location, options) {
|
|
43
|
+
if (!is_external_location(location)) return;
|
|
44
|
+
|
|
45
|
+
const external = options?.external;
|
|
46
|
+
|
|
47
|
+
if (!external) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
DEV
|
|
50
|
+
? `Cannot redirect to external URL ${JSON.stringify(location)}. ` +
|
|
51
|
+
'To redirect to an external URL, pass `{ external: true }` or an allowlist of permitted origins as the third argument to `redirect`'
|
|
52
|
+
: 'Cannot redirect to external URL unless explicitly allowed'
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (external === true) {
|
|
57
|
+
if (is_javascript_location(location)) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
DEV
|
|
60
|
+
? `Cannot redirect to ${JSON.stringify(location)} with \`{ external: true }\`. ` +
|
|
61
|
+
'The `javascript:` and `data:` protocols must be explicitly listed in the `external` allowlist'
|
|
62
|
+
: 'Cannot redirect to external URL unless explicitly allowed'
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (Array.isArray(external)) {
|
|
70
|
+
if (!external.some((allowed) => matches_external_allowlist_entry(location, allowed))) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
DEV
|
|
73
|
+
? `Cannot redirect to ${JSON.stringify(location)}: URL origin is not included in the \`external\` allowlist`
|
|
74
|
+
: 'Cannot redirect to external URL unless explicitly allowed'
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
throw new Error(
|
|
82
|
+
DEV
|
|
83
|
+
? '`redirect` options.external must be `true` or an array of allowed origins'
|
|
84
|
+
: 'Invalid redirect options.external value'
|
|
85
|
+
);
|
|
86
|
+
}
|
|
@@ -16,39 +16,16 @@ import { fix_css_urls } from '../../../utils/css.js';
|
|
|
16
16
|
import { escape_for_interpolation } from '../../../utils/escape.js';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* @overload Build without the client manifest so we can analyse the nodes.
|
|
20
19
|
* @param {string} out
|
|
21
20
|
* @param {ValidatedKitConfig} kit
|
|
22
21
|
* @param {ManifestData} manifest_data
|
|
23
22
|
* @param {Manifest} server_manifest
|
|
24
|
-
* @param {null} client_manifest
|
|
25
|
-
* @param {null} assets_path
|
|
26
|
-
* @param {null} client_chunks
|
|
27
|
-
* @param {string} root
|
|
28
|
-
* @returns {void}
|
|
29
|
-
*/
|
|
30
|
-
/**
|
|
31
|
-
* @overload Or build with the client manifest
|
|
32
|
-
* @param {string} out
|
|
33
|
-
* @param {ValidatedKitConfig} kit
|
|
34
|
-
* @param {ManifestData} manifest_data
|
|
35
|
-
* @param {Manifest} server_manifest
|
|
36
|
-
* @param {Manifest} client_manifest
|
|
23
|
+
* @param {Manifest | null} client_manifest
|
|
37
24
|
* @param {string} assets_path
|
|
38
|
-
* @param {Rolldown.
|
|
25
|
+
* @param {(Rolldown.OutputAsset | Rolldown.OutputChunk)[]} chunks
|
|
39
26
|
* @param {string} root
|
|
40
27
|
* @returns {void}
|
|
41
28
|
*/
|
|
42
|
-
/**
|
|
43
|
-
* @param {string} out
|
|
44
|
-
* @param {ValidatedKitConfig} kit
|
|
45
|
-
* @param {ManifestData} manifest_data
|
|
46
|
-
* @param {Manifest} server_manifest
|
|
47
|
-
* @param {Manifest | null} client_manifest
|
|
48
|
-
* @param {string | null} assets_path
|
|
49
|
-
* @param {Rolldown.RolldownOutput['output'] | null} client_chunks
|
|
50
|
-
* @param {string} root
|
|
51
|
-
*/
|
|
52
29
|
export function build_server_nodes(
|
|
53
30
|
out,
|
|
54
31
|
kit,
|
|
@@ -56,7 +33,7 @@ export function build_server_nodes(
|
|
|
56
33
|
server_manifest,
|
|
57
34
|
client_manifest,
|
|
58
35
|
assets_path,
|
|
59
|
-
|
|
36
|
+
chunks,
|
|
60
37
|
root
|
|
61
38
|
) {
|
|
62
39
|
mkdirp(`${out}/server/nodes`);
|
|
@@ -75,8 +52,8 @@ export function build_server_nodes(
|
|
|
75
52
|
*/
|
|
76
53
|
let prepare_css_for_inlining = (css) => s(css);
|
|
77
54
|
|
|
78
|
-
if (
|
|
79
|
-
for (const chunk of
|
|
55
|
+
if (chunks && kit.inlineStyleThreshold > 0 && kit.output.bundleStrategy === 'split') {
|
|
56
|
+
for (const chunk of chunks) {
|
|
80
57
|
if (chunk.type !== 'asset' || !chunk.fileName.endsWith('.css')) {
|
|
81
58
|
continue;
|
|
82
59
|
}
|
|
@@ -132,6 +109,9 @@ export function build_server_nodes(
|
|
|
132
109
|
}
|
|
133
110
|
}
|
|
134
111
|
|
|
112
|
+
/** path to the `.svelte-kit` directory */
|
|
113
|
+
const out_dir = normalizePath(kit.outDir);
|
|
114
|
+
|
|
135
115
|
for (let i = 0; i < manifest_data.nodes.length; i++) {
|
|
136
116
|
const node = manifest_data.nodes[i];
|
|
137
117
|
|
|
@@ -155,7 +135,11 @@ export function build_server_nodes(
|
|
|
155
135
|
/** @type {Set<string>} */
|
|
156
136
|
const eager_assets = new Set();
|
|
157
137
|
|
|
158
|
-
|
|
138
|
+
const uses_server_component = node.child_pages
|
|
139
|
+
? node.child_pages.some((child) => child.page_options?.ssr !== false)
|
|
140
|
+
: node.page_options?.ssr !== false;
|
|
141
|
+
|
|
142
|
+
if (node.component && uses_server_component) {
|
|
159
143
|
exports.push(
|
|
160
144
|
'let component_cache;',
|
|
161
145
|
`export const component = async () => component_cache ??= (await import('../${
|
|
@@ -165,7 +149,12 @@ export function build_server_nodes(
|
|
|
165
149
|
}
|
|
166
150
|
|
|
167
151
|
if (node.universal) {
|
|
168
|
-
if (
|
|
152
|
+
if (
|
|
153
|
+
(kit.router.type === 'hash' &&
|
|
154
|
+
node.page_options !== null &&
|
|
155
|
+
node.page_options?.ssr === undefined) ||
|
|
156
|
+
(node.page_options && node.page_options.ssr === false)
|
|
157
|
+
) {
|
|
169
158
|
exports.push(`export const universal = ${s(node.page_options, null, 2)};`);
|
|
170
159
|
} else {
|
|
171
160
|
imports.push(
|
|
@@ -185,18 +174,7 @@ export function build_server_nodes(
|
|
|
185
174
|
exports.push(`export const server_id = ${s(node.server)};`);
|
|
186
175
|
}
|
|
187
176
|
|
|
188
|
-
if (
|
|
189
|
-
client_manifest &&
|
|
190
|
-
(node.universal || node.component) &&
|
|
191
|
-
kit.output.bundleStrategy === 'split'
|
|
192
|
-
) {
|
|
193
|
-
const entry_path = `${normalizePath(kit.outDir)}/generated/client-optimized/nodes/${i}.js`;
|
|
194
|
-
const entry = find_deps(client_manifest, entry_path, true, root);
|
|
195
|
-
|
|
196
|
-
// Eagerly load client stylesheets and fonts imported by the SSR-ed page to avoid FOUC.
|
|
197
|
-
// However, if it is not used during SSR (not present in the server manifest),
|
|
198
|
-
// then it can be lazily loaded in the browser.
|
|
199
|
-
|
|
177
|
+
if ((node.universal || node.component) && kit.output.bundleStrategy === 'split') {
|
|
200
178
|
/** @type {AssetDependencies | undefined} */
|
|
201
179
|
let component;
|
|
202
180
|
if (node.component) {
|
|
@@ -209,25 +187,41 @@ export function build_server_nodes(
|
|
|
209
187
|
universal = find_deps(server_manifest, node.universal, true, root);
|
|
210
188
|
}
|
|
211
189
|
|
|
212
|
-
|
|
213
|
-
|
|
190
|
+
if (client_manifest) {
|
|
191
|
+
const entry_path = `${out_dir}/generated/client-optimized/nodes/${i}.js`;
|
|
192
|
+
const entry = find_deps(client_manifest, entry_path, true, root);
|
|
214
193
|
|
|
215
|
-
|
|
216
|
-
//
|
|
217
|
-
//
|
|
218
|
-
if (filepath === entry_path) {
|
|
219
|
-
filepath = node.component ?? filepath;
|
|
220
|
-
}
|
|
194
|
+
// Eagerly load client stylesheets and fonts imported by the SSR-ed page to avoid FOUC.
|
|
195
|
+
// However, if it is not used during SSR (not present in the server manifest),
|
|
196
|
+
// then it can be lazily loaded in the browser.
|
|
221
197
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
198
|
+
/** @type {Set<string>} */
|
|
199
|
+
const eager_css = new Set();
|
|
200
|
+
|
|
201
|
+
entry.stylesheet_map.forEach((value, filepath) => {
|
|
202
|
+
// pages and layouts are renamed to node indexes when optimised for the client
|
|
203
|
+
// so we use the original filename instead to check against the server manifest
|
|
204
|
+
if (filepath === entry_path) {
|
|
205
|
+
filepath = node.component ?? filepath;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (component?.stylesheet_map.has(filepath) || universal?.stylesheet_map.has(filepath)) {
|
|
209
|
+
value.css.forEach((file) => eager_css.add(file));
|
|
210
|
+
value.assets.forEach((file) => eager_assets.add(file));
|
|
211
|
+
}
|
|
212
|
+
});
|
|
227
213
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
214
|
+
imported = entry.imports;
|
|
215
|
+
stylesheets = Array.from(eager_css);
|
|
216
|
+
fonts = filter_fonts(Array.from(eager_assets));
|
|
217
|
+
} else {
|
|
218
|
+
for (const entry of [component, universal]) {
|
|
219
|
+
if (!entry) continue;
|
|
220
|
+
imported.push(...entry.imports);
|
|
221
|
+
stylesheets.push(...entry.stylesheets);
|
|
222
|
+
fonts.push(...entry.fonts);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
231
225
|
}
|
|
232
226
|
|
|
233
227
|
exports.push(
|
|
@@ -244,7 +238,7 @@ export function build_server_nodes(
|
|
|
244
238
|
|
|
245
239
|
// Keep track of Vite asset filenames so that we avoid touching unrelated ones
|
|
246
240
|
// when adjusting the inlined CSS
|
|
247
|
-
if (stylesheets_to_inline.size &&
|
|
241
|
+
if (stylesheets_to_inline.size && eager_assets.size) {
|
|
248
242
|
vite_assets = new Set(
|
|
249
243
|
Array.from(eager_assets).map((asset) => {
|
|
250
244
|
return decodeURIComponent(asset.replace(`${assets_path}/`, ''));
|
|
@@ -13,7 +13,7 @@ import { posixify } from '../../../utils/os.js';
|
|
|
13
13
|
* @param {Array<{ hash: string, file: string }>} remotes
|
|
14
14
|
* @param {ServerMetadata} metadata
|
|
15
15
|
* @param {string} cwd
|
|
16
|
-
* @param {Rolldown.
|
|
16
|
+
* @param {(Rolldown.OutputAsset | Rolldown.OutputChunk)[]} server_chunks
|
|
17
17
|
* @param {NonNullable<import('vitest/config').ViteUserConfig['build']>['sourcemap']} sourcemap
|
|
18
18
|
*/
|
|
19
19
|
export async function treeshake_prerendered_remotes(
|
|
@@ -22,11 +22,14 @@ export async function treeshake_prerendered_remotes(
|
|
|
22
22
|
remotes,
|
|
23
23
|
metadata,
|
|
24
24
|
cwd,
|
|
25
|
-
|
|
25
|
+
server_chunks,
|
|
26
26
|
sourcemap
|
|
27
27
|
) {
|
|
28
28
|
if (remotes.length === 0) return;
|
|
29
29
|
|
|
30
|
+
/** @type {string[]} */
|
|
31
|
+
const chunk_paths = [];
|
|
32
|
+
|
|
30
33
|
for (const remote of remotes) {
|
|
31
34
|
const exports_map = metadata.remotes.get(remote.hash);
|
|
32
35
|
if (!exports_map) continue;
|
|
@@ -45,7 +48,7 @@ export async function treeshake_prerendered_remotes(
|
|
|
45
48
|
// remove file extension
|
|
46
49
|
const remote_filename = path.basename(remote.file).split('.').slice(0, -1).join('.');
|
|
47
50
|
|
|
48
|
-
const remote_chunk =
|
|
51
|
+
const remote_chunk = server_chunks.find((chunk) => {
|
|
49
52
|
return chunk.name === remote_filename;
|
|
50
53
|
});
|
|
51
54
|
|
|
@@ -88,8 +91,13 @@ export async function treeshake_prerendered_remotes(
|
|
|
88
91
|
|
|
89
92
|
const stubbed = modified_code.toString();
|
|
90
93
|
fs.writeFileSync(chunk_path, stubbed);
|
|
94
|
+
chunk_paths.push(chunk_path);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (!chunk_paths.length) return;
|
|
91
98
|
|
|
92
|
-
|
|
99
|
+
for (const chunk_path of chunk_paths) {
|
|
100
|
+
const bundle = /** @type {Rolldown.RolldownOutput} */ (
|
|
93
101
|
await vite.build({
|
|
94
102
|
configFile: false,
|
|
95
103
|
build: {
|
|
@@ -97,7 +105,7 @@ export async function treeshake_prerendered_remotes(
|
|
|
97
105
|
ssr: true,
|
|
98
106
|
target: 'esnext',
|
|
99
107
|
sourcemap,
|
|
100
|
-
|
|
108
|
+
rolldownOptions: {
|
|
101
109
|
// avoid resolving imports
|
|
102
110
|
external: (id) => !id.endsWith(chunk_path),
|
|
103
111
|
input: {
|
|
@@ -108,14 +116,13 @@ export async function treeshake_prerendered_remotes(
|
|
|
108
116
|
})
|
|
109
117
|
);
|
|
110
118
|
|
|
111
|
-
const
|
|
112
|
-
(output
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
fs.writeFileSync(chunk_path, chunk.code);
|
|
119
|
+
for (const output of bundle.output) {
|
|
120
|
+
if (output.type !== 'chunk' || output.name !== 'treeshaken') return;
|
|
121
|
+
|
|
122
|
+
fs.writeFileSync(chunk_path, output.code);
|
|
116
123
|
|
|
117
124
|
const chunk_sourcemap = bundle.output.find(
|
|
118
|
-
(
|
|
125
|
+
(o) => o.type === 'asset' && o.fileName === output.fileName + '.map'
|
|
119
126
|
);
|
|
120
127
|
if (chunk_sourcemap && chunk_sourcemap.type === 'asset') {
|
|
121
128
|
fs.writeFileSync(chunk_path + '.map', chunk_sourcemap.source);
|
|
@@ -124,14 +124,6 @@ export function filter_fonts(assets) {
|
|
|
124
124
|
return assets.filter((asset) => /\.(woff2?|ttf|otf)$/.test(asset));
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
/**
|
|
128
|
-
* @param {import('types').ValidatedKitConfig} config
|
|
129
|
-
* @returns {string}
|
|
130
|
-
*/
|
|
131
|
-
export function assets_base(config) {
|
|
132
|
-
return (config.paths.assets || config.paths.base || '.') + '/';
|
|
133
|
-
}
|
|
134
|
-
|
|
135
127
|
/**
|
|
136
128
|
* Writes a function with arguments used by a template literal.
|
|
137
129
|
* This helps us store strings in a module and inject values at runtime.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** @import { RequestEvent } from '@sveltejs/kit' */
|
|
2
2
|
/** @import { PrerenderOption, UniversalNode } from 'types' */
|
|
3
|
+
import process from 'node:process';
|
|
3
4
|
import fs from 'node:fs';
|
|
4
5
|
import path from 'node:path';
|
|
5
6
|
import { URL } from 'node:url';
|
|
@@ -10,14 +11,21 @@ import { isCSSRequest, loadEnv, buildErrorMessage } from 'vite';
|
|
|
10
11
|
import { createReadableStream, getRequest, setResponse } from '../../../exports/node/index.js';
|
|
11
12
|
import { coalesce_to_error } from '../../../utils/error.js';
|
|
12
13
|
import { resolve_entry } from '../../../utils/filesystem.js';
|
|
14
|
+
import { load_and_validate_params } from '../../../utils/params.js';
|
|
13
15
|
import { from_fs, to_fs } from '../../../utils/vite.js';
|
|
14
16
|
import { posixify } from '../../../utils/os.js';
|
|
15
17
|
import { load_error_page } from '../../../core/config/index.js';
|
|
16
|
-
import { SVELTE_KIT_ASSETS } from '../../../constants.js';
|
|
18
|
+
import { SRC_ROOT, SVELTE_KIT_ASSETS } from '../../../constants.js';
|
|
17
19
|
import * as sync from '../../../core/sync/sync.js';
|
|
18
20
|
import { get_mime_lookup, get_runtime_base } from '../../../core/utils.js';
|
|
21
|
+
import '../../../utils/mime.js'; // extend mrmime with additional types (affects sirv too)
|
|
19
22
|
import { compact } from '../../../utils/array.js';
|
|
20
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
is_chrome_devtools_request,
|
|
25
|
+
log_response,
|
|
26
|
+
not_found,
|
|
27
|
+
remote_module_pattern
|
|
28
|
+
} from '../utils.js';
|
|
21
29
|
import { SCHEME } from '../../../utils/url.js';
|
|
22
30
|
import { check_feature } from '../../../utils/features.js';
|
|
23
31
|
import { escape_html } from '../../../utils/escape.js';
|
|
@@ -31,10 +39,9 @@ const vite_css_query_regex = /(?:\?|&)(?:raw|url|inline)(?:&|$)/;
|
|
|
31
39
|
* @param {import('types').ValidatedConfig} svelte_config
|
|
32
40
|
* @param {() => Array<{ hash: string, file: string }>} get_remotes
|
|
33
41
|
* @param {string} root The project root directory
|
|
34
|
-
* @param {import('@sveltejs/kit').Adapter | undefined} adapter
|
|
35
42
|
* @return {Promise<Promise<() => void>>}
|
|
36
43
|
*/
|
|
37
|
-
export async function dev(vite, vite_config, svelte_config, get_remotes, root
|
|
44
|
+
export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
38
45
|
/** @type {AsyncLocalStorage<{ event: RequestEvent, config: any, prerender: PrerenderOption }>} */
|
|
39
46
|
const async_local_storage = new AsyncLocalStorage();
|
|
40
47
|
|
|
@@ -42,7 +49,12 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
42
49
|
const context = async_local_storage.getStore();
|
|
43
50
|
if (!context || context.prerender === true) return;
|
|
44
51
|
|
|
45
|
-
check_feature(
|
|
52
|
+
check_feature(
|
|
53
|
+
/** @type {string} */ (context.event.route.id),
|
|
54
|
+
context.config,
|
|
55
|
+
label,
|
|
56
|
+
svelte_config.kit.adapter
|
|
57
|
+
);
|
|
46
58
|
};
|
|
47
59
|
|
|
48
60
|
const fetch = globalThis.fetch;
|
|
@@ -79,6 +91,10 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
79
91
|
vite.config.logger.error(msg, { error: err });
|
|
80
92
|
}
|
|
81
93
|
|
|
94
|
+
// TODO this is inadequate — it doesn't reliably show the overlay on every page load,
|
|
95
|
+
// and when it does appear it may immediately vanish. `vite.ws.send` broadcasts
|
|
96
|
+
// to all connected clients, even ones that are unaffected by the error.
|
|
97
|
+
// we need a more considered approach
|
|
82
98
|
vite.ws.send({
|
|
83
99
|
type: 'error',
|
|
84
100
|
err: /** @type {import('vite').ErrorPayload['err']} */ ({
|
|
@@ -106,10 +122,17 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
106
122
|
return { module, module_node, url };
|
|
107
123
|
}
|
|
108
124
|
|
|
109
|
-
function update_manifest() {
|
|
125
|
+
async function update_manifest() {
|
|
110
126
|
try {
|
|
111
127
|
({ manifest_data } = sync.create(svelte_config, root));
|
|
112
128
|
|
|
129
|
+
await load_and_validate_params({
|
|
130
|
+
routes: manifest_data.routes,
|
|
131
|
+
params_path: manifest_data.params,
|
|
132
|
+
root,
|
|
133
|
+
load: (file) => loud_ssr_load_module(file)
|
|
134
|
+
});
|
|
135
|
+
|
|
113
136
|
if (manifest_error) {
|
|
114
137
|
manifest_error = null;
|
|
115
138
|
vite.ws.send({ type: 'full-reload' });
|
|
@@ -288,22 +311,18 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
288
311
|
})
|
|
289
312
|
),
|
|
290
313
|
matchers: async () => {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
matchers[key] = module.match;
|
|
301
|
-
} else {
|
|
302
|
-
throw new Error(`${file} does not export a \`match\` function`);
|
|
303
|
-
}
|
|
314
|
+
if (!manifest_data.params) return {};
|
|
315
|
+
|
|
316
|
+
const url = path.resolve(root, manifest_data.params);
|
|
317
|
+
const module = await vite.ssrLoadModule(url, { fixStacktrace: true });
|
|
318
|
+
|
|
319
|
+
if (!module.params) {
|
|
320
|
+
throw new Error(
|
|
321
|
+
`${manifest_data.params} does not export \`params\` from \`defineParams\``
|
|
322
|
+
);
|
|
304
323
|
}
|
|
305
324
|
|
|
306
|
-
return
|
|
325
|
+
return module.params;
|
|
307
326
|
}
|
|
308
327
|
}
|
|
309
328
|
};
|
|
@@ -311,16 +330,53 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
311
330
|
|
|
312
331
|
/** @param {Error} error */
|
|
313
332
|
function fix_stack_trace(error) {
|
|
333
|
+
if (!error.stack) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
|
|
314
337
|
try {
|
|
315
338
|
vite.ssrFixStacktrace(error);
|
|
316
339
|
} catch {
|
|
317
340
|
// ssrFixStacktrace can fail on StackBlitz web containers and we don't know why
|
|
318
341
|
// by ignoring it the line numbers are wrong, but at least we can show the error
|
|
319
342
|
}
|
|
320
|
-
|
|
343
|
+
|
|
344
|
+
if (error.stack) {
|
|
345
|
+
let end = 0;
|
|
346
|
+
|
|
347
|
+
error.stack = error.stack
|
|
348
|
+
.replaceAll('\0', '') // remove null bytes from e.g. virtual module IDs, or the response will fail
|
|
349
|
+
.split('\n')
|
|
350
|
+
.map((line, i) => {
|
|
351
|
+
const match = /^ {4}at (?:[^ ]+ \((.+)\)|(.+))$/.exec(line);
|
|
352
|
+
if (!match) {
|
|
353
|
+
end = i + 1;
|
|
354
|
+
return line;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const loc = match[1] ?? match[2];
|
|
358
|
+
const file = loc.replace(/:\d+:\d+$/, '');
|
|
359
|
+
|
|
360
|
+
if (fs.existsSync(file)) {
|
|
361
|
+
if (!file.includes('node_modules') && !file.includes(SRC_ROOT)) {
|
|
362
|
+
end = i + 1;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return line.replace(file, path.posix.relative(process.cwd(), file));
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return line;
|
|
369
|
+
})
|
|
370
|
+
.slice(0, end)
|
|
371
|
+
.join('\n');
|
|
372
|
+
|
|
373
|
+
return error.stack;
|
|
374
|
+
}
|
|
321
375
|
}
|
|
322
376
|
|
|
323
|
-
update_manifest();
|
|
377
|
+
await update_manifest();
|
|
378
|
+
|
|
379
|
+
const params_file = resolve_entry(svelte_config.kit.files.params);
|
|
324
380
|
|
|
325
381
|
/**
|
|
326
382
|
* @param {string} event
|
|
@@ -330,8 +386,8 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
330
386
|
vite.watcher.on(event, (file) => {
|
|
331
387
|
if (
|
|
332
388
|
file.startsWith(svelte_config.kit.files.routes + path.sep) ||
|
|
333
|
-
|
|
334
|
-
|
|
389
|
+
(params_file && file === params_file) ||
|
|
390
|
+
remote_module_pattern.test(file) ||
|
|
335
391
|
// in contrast to server hooks, client hooks are written to the client manifest
|
|
336
392
|
// and therefore need rebuilding when they are added/removed
|
|
337
393
|
file.startsWith(svelte_config.kit.files.hooks.client)
|
|
@@ -351,9 +407,6 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
351
407
|
}, 100);
|
|
352
408
|
};
|
|
353
409
|
|
|
354
|
-
// flag to skip watchers if server is already restarting
|
|
355
|
-
let restarting = false;
|
|
356
|
-
|
|
357
410
|
// Debounce add/unlink events because in case of folder deletion or moves
|
|
358
411
|
// they fire in rapid succession, causing needless invocations.
|
|
359
412
|
// These watchers only run for routes, param matchers, and client hooks.
|
|
@@ -362,7 +415,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
362
415
|
watch('change', (file) => {
|
|
363
416
|
// Don't run for a single file if the whole manifest is about to get updated
|
|
364
417
|
// Unless it's a file where the trailing slash page option might have changed
|
|
365
|
-
if (timeout ||
|
|
418
|
+
if (timeout || !/\+(page|layout|server).*$/.test(file)) return;
|
|
366
419
|
sync.update(svelte_config, manifest_data, file, root);
|
|
367
420
|
});
|
|
368
421
|
|
|
@@ -373,7 +426,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
373
426
|
// send the vite client a full-reload event without path being set
|
|
374
427
|
if (appTemplate !== 'index.html') {
|
|
375
428
|
vite.watcher.on('change', (file) => {
|
|
376
|
-
if (file === appTemplate
|
|
429
|
+
if (file === appTemplate) {
|
|
377
430
|
vite.ws.send({ type: 'full-reload' });
|
|
378
431
|
}
|
|
379
432
|
});
|
|
@@ -390,26 +443,12 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
390
443
|
}
|
|
391
444
|
});
|
|
392
445
|
|
|
393
|
-
vite.watcher.on('change', async (file) => {
|
|
394
|
-
// changing the svelte config requires restarting the dev server
|
|
395
|
-
// the config is only read on start and passed on to vite-plugin-svelte
|
|
396
|
-
// which needs up-to-date values to operate correctly
|
|
397
|
-
if (file.match(/[/\\]svelte\.config\.[jt]s$/)) {
|
|
398
|
-
console.log(`svelte config changed, restarting vite dev-server. changed file: ${file}`);
|
|
399
|
-
restarting = true;
|
|
400
|
-
await vite.restart();
|
|
401
|
-
}
|
|
402
|
-
});
|
|
403
|
-
|
|
404
446
|
const assets = svelte_config.kit.paths.assets ? SVELTE_KIT_ASSETS : svelte_config.kit.paths.base;
|
|
405
447
|
const asset_server = sirv(svelte_config.kit.files.assets, {
|
|
406
448
|
dev: true,
|
|
407
449
|
etag: true,
|
|
408
450
|
maxAge: 0,
|
|
409
|
-
extensions: []
|
|
410
|
-
setHeaders: (res) => {
|
|
411
|
-
res.setHeader('access-control-allow-origin', '*');
|
|
412
|
-
}
|
|
451
|
+
extensions: []
|
|
413
452
|
});
|
|
414
453
|
|
|
415
454
|
vite.middlewares.use((req, res, next) => {
|
|
@@ -436,7 +475,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
436
475
|
});
|
|
437
476
|
|
|
438
477
|
const env = loadEnv(vite_config.mode, svelte_config.kit.env.dir, '');
|
|
439
|
-
const emulator = await adapter?.emulate?.();
|
|
478
|
+
const emulator = await svelte_config.kit.adapter?.emulate?.();
|
|
440
479
|
|
|
441
480
|
return () => {
|
|
442
481
|
const serve_static_middleware = vite.middlewares.stack.find(
|
|
@@ -513,7 +552,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
513
552
|
);
|
|
514
553
|
|
|
515
554
|
const { set_fix_stack_trace } = await vite.ssrLoadModule(
|
|
516
|
-
`${get_runtime_base(root)}/
|
|
555
|
+
`${get_runtime_base(root)}/server/internal.js`
|
|
517
556
|
);
|
|
518
557
|
set_fix_stack_trace(fix_stack_trace);
|
|
519
558
|
|
|
@@ -527,7 +566,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
527
566
|
read: (file) => createReadableStream(from_fs(file))
|
|
528
567
|
});
|
|
529
568
|
|
|
530
|
-
const request =
|
|
569
|
+
const request = getRequest({
|
|
531
570
|
base,
|
|
532
571
|
request: req
|
|
533
572
|
});
|
|
@@ -578,15 +617,18 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root, a
|
|
|
578
617
|
if (rendered.status === 404) {
|
|
579
618
|
// @ts-expect-error
|
|
580
619
|
serve_static_middleware.handle(req, res, () => {
|
|
581
|
-
|
|
620
|
+
log_response(rendered.status, request);
|
|
621
|
+
setResponse(res, rendered);
|
|
582
622
|
});
|
|
583
623
|
} else {
|
|
584
|
-
|
|
624
|
+
log_response(rendered.status, request);
|
|
625
|
+
setResponse(res, rendered);
|
|
585
626
|
}
|
|
586
627
|
} catch (e) {
|
|
587
628
|
const error = coalesce_to_error(e);
|
|
588
629
|
res.statusCode = 500;
|
|
589
|
-
|
|
630
|
+
fix_stack_trace(error);
|
|
631
|
+
res.end(error.stack || error.message); // handle `stackless` errors
|
|
590
632
|
}
|
|
591
633
|
});
|
|
592
634
|
};
|