@sveltejs/kit 2.65.1 → 2.66.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 +3 -3
- package/src/core/adapt/builder.js +33 -6
- package/src/core/config/index.js +60 -2
- package/src/core/config/options.js +12 -3
- package/src/core/env.js +7 -3
- package/src/core/postbuild/analyse.js +4 -1
- package/src/core/postbuild/prerender.js +13 -4
- package/src/core/sync/create_manifest_data/index.js +13 -2
- package/src/core/sync/write_client_manifest.js +2 -0
- package/src/core/sync/write_server.js +12 -10
- package/src/core/sync/write_tsconfig.js +1 -2
- package/src/exports/internal/env.js +1 -1
- package/src/exports/public.d.ts +13 -1
- package/src/exports/vite/build/build_server.js +6 -1
- package/src/exports/vite/build/build_service_worker.js +8 -2
- package/src/exports/vite/index.js +44 -16
- package/src/exports/vite/preview/index.js +13 -4
- package/src/exports/vite/static_analysis/index.js +8 -3
- package/src/runtime/app/paths/server.js +7 -1
- package/src/runtime/app/server/remote/form.js +2 -2
- package/src/runtime/client/client.js +30 -8
- package/src/runtime/client/fetcher.js +3 -2
- package/src/runtime/client/remote-functions/form.svelte.js +16 -6
- package/src/runtime/client/remote-functions/prerender.svelte.js +5 -0
- package/src/runtime/client/remote-functions/query/instance.svelte.js +8 -1
- package/src/runtime/client/remote-functions/query-live/instance.svelte.js +25 -8
- package/src/runtime/client/remote-functions/shared.svelte.js +7 -1
- package/src/runtime/client/types.d.ts +6 -0
- package/src/runtime/form-utils.js +1 -0
- package/src/runtime/server/page/render.js +15 -13
- package/src/runtime/server/remote.js +9 -3
- package/src/runtime/server/respond.js +4 -1
- package/src/types/internal.d.ts +3 -1
- package/src/types/private.d.ts +24 -1
- package/src/utils/shared-iterator.js +5 -0
- package/src/utils/url.js +1 -1
- package/src/version.js +1 -1
- package/types/index.d.ts +54 -11
- package/types/index.d.ts.map +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/kit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.66.0",
|
|
4
4
|
"description": "SvelteKit is the fastest way to build Svelte apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"@types/connect": "^3.4.38",
|
|
39
39
|
"@types/node": "^18.19.130",
|
|
40
40
|
"@types/set-cookie-parser": "^2.4.7",
|
|
41
|
-
"dts-buddy": "^0.8.
|
|
41
|
+
"dts-buddy": "^0.8.1",
|
|
42
42
|
"jsdom": "^26.1.0",
|
|
43
43
|
"rollup": "^4.59.0",
|
|
44
44
|
"svelte": "^5.56.3",
|
|
45
45
|
"typescript": "^5.3.3",
|
|
46
|
-
"vite": "^6.4.
|
|
46
|
+
"vite": "^6.4.3",
|
|
47
47
|
"vitest": "^4.1.7"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
@@ -22,7 +22,19 @@ import { reserved } from '../env.js';
|
|
|
22
22
|
import { handle_issues, validate } from '../../exports/internal/env.js';
|
|
23
23
|
|
|
24
24
|
const pipe = promisify(pipeline);
|
|
25
|
-
const extensions = [
|
|
25
|
+
const extensions = [
|
|
26
|
+
'.html',
|
|
27
|
+
'.js',
|
|
28
|
+
'.mjs',
|
|
29
|
+
'.json',
|
|
30
|
+
'.css',
|
|
31
|
+
'.svg',
|
|
32
|
+
'.xml',
|
|
33
|
+
'.wasm',
|
|
34
|
+
'.txt',
|
|
35
|
+
'.md',
|
|
36
|
+
'.mdx'
|
|
37
|
+
];
|
|
26
38
|
|
|
27
39
|
/**
|
|
28
40
|
* Creates the Builder which is passed to adapters for building the application.
|
|
@@ -193,12 +205,12 @@ export function create_builder({
|
|
|
193
205
|
},
|
|
194
206
|
|
|
195
207
|
generateEnvModule() {
|
|
196
|
-
if (!build_data.client?.uses_env_dynamic_public) return;
|
|
197
|
-
|
|
198
|
-
const dest = `${config.kit.outDir}/output/prerendered/dependencies/${config.kit.appDir}/env.js`;
|
|
199
208
|
const env = get_env(config.kit.env, vite_config.mode);
|
|
200
209
|
|
|
201
|
-
const
|
|
210
|
+
const dest = `${config.kit.outDir}/output/prerendered/dependencies/${config.kit.appDir}`;
|
|
211
|
+
|
|
212
|
+
/** @type {string} */
|
|
213
|
+
let payload;
|
|
202
214
|
|
|
203
215
|
if (config.kit.experimental.explicitEnvironmentVariables) {
|
|
204
216
|
const variables = explicit_env_config ?? {};
|
|
@@ -206,15 +218,30 @@ export function create_builder({
|
|
|
206
218
|
/** @type {Record<string, StandardSchemaV1.Issue[]>} */
|
|
207
219
|
const issues = {};
|
|
208
220
|
|
|
221
|
+
/** @type {Record<string, any>} */
|
|
222
|
+
const values = {};
|
|
223
|
+
|
|
209
224
|
for (const [name, config] of Object.entries(variables)) {
|
|
210
225
|
if (config.static || !config.public) continue;
|
|
211
226
|
values[name] = validate(variables, env.all[name], name, issues);
|
|
212
227
|
}
|
|
213
228
|
|
|
214
229
|
handle_issues(issues);
|
|
230
|
+
|
|
231
|
+
if (Object.keys(values).length === 0) return;
|
|
232
|
+
|
|
233
|
+
payload = devalue.uneval(values);
|
|
234
|
+
|
|
235
|
+
if (build_data.service_worker) {
|
|
236
|
+
write(`${dest}/env.script.js`, `globalThis.__sveltekit_sw={env:${payload}}`);
|
|
237
|
+
}
|
|
238
|
+
} else {
|
|
239
|
+
payload = devalue.uneval(env.public);
|
|
215
240
|
}
|
|
216
241
|
|
|
217
|
-
|
|
242
|
+
if (build_data.client?.uses_env_dynamic_public) {
|
|
243
|
+
write(`${dest}/env.js`, `export const env=${payload}`);
|
|
244
|
+
}
|
|
218
245
|
},
|
|
219
246
|
|
|
220
247
|
generateManifest({ relativePath, routes: subset }) {
|
package/src/core/config/index.js
CHANGED
|
@@ -1,14 +1,72 @@
|
|
|
1
|
-
/** @import { Config } from '@sveltejs/kit' */
|
|
1
|
+
/** @import { Config, KitConfig } from '@sveltejs/kit' */
|
|
2
|
+
/** @import { Options, SvelteConfig } from '@sveltejs/vite-plugin-svelte' */
|
|
2
3
|
/** @import { ValidatedConfig } from 'types' */
|
|
3
4
|
/** @import { ResolvedConfig } from 'vite' */
|
|
4
5
|
import fs from 'node:fs';
|
|
5
6
|
import path from 'node:path';
|
|
6
7
|
import process from 'node:process';
|
|
7
8
|
import * as url from 'node:url';
|
|
8
|
-
import options from './options.js';
|
|
9
|
+
import { options, kit_options, kit_experimental_options } from './options.js';
|
|
9
10
|
import { resolve_entry } from '../../utils/filesystem.js';
|
|
10
11
|
import { import_peer } from '../../utils/import.js';
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Splits the config passed to the `sveltekit` Vite plugin into the options that
|
|
15
|
+
* SvelteKit processes itself and the options that are forwarded to
|
|
16
|
+
* `vite-plugin-svelte`. SvelteKit makes no assumptions about which options
|
|
17
|
+
* `vite-plugin-svelte` accepts — it plucks out its own options and passes
|
|
18
|
+
* everything else along (`vite-plugin-svelte` does its own validation).
|
|
19
|
+
* @param {KitConfig & Omit<Options, 'onwarn'> & Pick<SvelteConfig, 'vitePlugin'>} config
|
|
20
|
+
* @returns {{ svelte_config: Config, vite_plugin_svelte_config: Record<string, any> }}
|
|
21
|
+
*/
|
|
22
|
+
export function split_config(config) {
|
|
23
|
+
const { extensions, compilerOptions, vitePlugin, preprocess, ...rest } = config;
|
|
24
|
+
|
|
25
|
+
/** @type {KitConfig} */
|
|
26
|
+
const kit = {};
|
|
27
|
+
|
|
28
|
+
/** @type {Record<string, any>} */
|
|
29
|
+
const vite_plugin_svelte_config = {};
|
|
30
|
+
|
|
31
|
+
for (const key in rest) {
|
|
32
|
+
if (key === 'experimental') {
|
|
33
|
+
// `experimental` is a namespace that both SvelteKit and vite-plugin-svelte
|
|
34
|
+
// use, so pluck out the flags SvelteKit recognises and pass the rest along
|
|
35
|
+
const experimental = /** @type {Record<string, any>} */ (rest[key]) ?? {};
|
|
36
|
+
|
|
37
|
+
/** @type {Record<string, any>} */
|
|
38
|
+
const kit_experimental = {};
|
|
39
|
+
/** @type {Record<string, any>} */
|
|
40
|
+
const vps_experimental = {};
|
|
41
|
+
|
|
42
|
+
for (const flag in experimental) {
|
|
43
|
+
if (kit_experimental_options.includes(flag)) {
|
|
44
|
+
kit_experimental[flag] = experimental[flag];
|
|
45
|
+
} else {
|
|
46
|
+
vps_experimental[flag] = experimental[flag];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (Object.keys(kit_experimental).length > 0) {
|
|
51
|
+
kit.experimental = kit_experimental;
|
|
52
|
+
}
|
|
53
|
+
if (Object.keys(vps_experimental).length > 0) {
|
|
54
|
+
vite_plugin_svelte_config.experimental = vps_experimental;
|
|
55
|
+
}
|
|
56
|
+
} else if (kit_options.includes(key)) {
|
|
57
|
+
// @ts-expect-error - we've verified this is one of SvelteKit's own options
|
|
58
|
+
kit[key] = rest[key];
|
|
59
|
+
} else {
|
|
60
|
+
vite_plugin_svelte_config[key] = /** @type {Record<string, any>} */ (rest)[key];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
svelte_config: { extensions, compilerOptions, vitePlugin, preprocess, kit },
|
|
66
|
+
vite_plugin_svelte_config
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
12
70
|
/**
|
|
13
71
|
* Loads the template (src/app.html by default) and validates that it has the
|
|
14
72
|
* required content.
|
|
@@ -45,7 +45,7 @@ const directives = object({
|
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
/** @type {Validator} */
|
|
48
|
-
const options = object(
|
|
48
|
+
export const options = object(
|
|
49
49
|
{
|
|
50
50
|
extensions: validate(['.svelte'], (input, keypath) => {
|
|
51
51
|
if (!Array.isArray(input) || !input.every((page) => typeof page === 'string')) {
|
|
@@ -326,6 +326,17 @@ const options = object(
|
|
|
326
326
|
true
|
|
327
327
|
);
|
|
328
328
|
|
|
329
|
+
// Derive the names of SvelteKit's own config options from the schema, so they
|
|
330
|
+
// stay in sync automatically. These are used to separate Kit's options from
|
|
331
|
+
// `vite-plugin-svelte`'s options when config is passed via the Vite plugin.
|
|
332
|
+
const defaults = /** @type {Record<string, any>} */ (options({}, 'config'));
|
|
333
|
+
|
|
334
|
+
/** The names of the options that live under the `kit` namespace */
|
|
335
|
+
export const kit_options = Object.keys(defaults.kit);
|
|
336
|
+
|
|
337
|
+
/** The names of the options that live under the `kit.experimental` namespace */
|
|
338
|
+
export const kit_experimental_options = Object.keys(defaults.kit.experimental);
|
|
339
|
+
|
|
329
340
|
/**
|
|
330
341
|
* @param {Validator} fn
|
|
331
342
|
* @param {(keypath: string) => string} get_message
|
|
@@ -502,5 +513,3 @@ function assert_trusted_types_supported(keypath) {
|
|
|
502
513
|
);
|
|
503
514
|
}
|
|
504
515
|
}
|
|
505
|
-
|
|
506
|
-
export default options;
|
package/src/core/env.js
CHANGED
|
@@ -72,6 +72,10 @@ export async function load_explicit_env(kit, file, mode) {
|
|
|
72
72
|
/** @type {Record<string, EnvVarConfig<any>>} */
|
|
73
73
|
let variables;
|
|
74
74
|
|
|
75
|
+
/** @type {import('../runtime/app/env/internal.js')} */ (
|
|
76
|
+
await server.ssrLoadModule(`${runtime_directory}/app/env/internal.js`)
|
|
77
|
+
).set_building();
|
|
78
|
+
|
|
75
79
|
try {
|
|
76
80
|
({ variables } = await server.ssrLoadModule(file));
|
|
77
81
|
|
|
@@ -157,7 +161,7 @@ export function create_dynamic_module(type, dev_values, disabled) {
|
|
|
157
161
|
|
|
158
162
|
/**
|
|
159
163
|
* Creates the `__sveltekit/env` module
|
|
160
|
-
* @param {Record<string, EnvVarConfig<any
|
|
164
|
+
* @param {Record<string, EnvVarConfig<any> | undefined> | null} variables
|
|
161
165
|
* @param {Record<string, string>} env
|
|
162
166
|
* @param {string | null} entry
|
|
163
167
|
*/
|
|
@@ -176,7 +180,7 @@ export function create_sveltekit_env(variables, env, entry) {
|
|
|
176
180
|
const issues = {};
|
|
177
181
|
|
|
178
182
|
for (const [name, config] of Object.entries(variables ?? {})) {
|
|
179
|
-
if (config
|
|
183
|
+
if (config?.static) {
|
|
180
184
|
if (config.public) {
|
|
181
185
|
const value = validate(variables ?? {}, env[name], name, issues);
|
|
182
186
|
declarations.push(`explicit_public_env.${name} = ${devalue.uneval(value)};`);
|
|
@@ -186,7 +190,7 @@ export function create_sveltekit_env(variables, env, entry) {
|
|
|
186
190
|
`const ${name} = validate(variables, env.${name}, ${JSON.stringify(name)}, issues);`
|
|
187
191
|
);
|
|
188
192
|
|
|
189
|
-
if (config
|
|
193
|
+
if (config?.public) {
|
|
190
194
|
setters.push(`explicit_public_env.${name} = ${name};`);
|
|
191
195
|
setters.push(`rendered_env.${name} = ${name};`);
|
|
192
196
|
} else {
|
|
@@ -58,10 +58,13 @@ async function analyse({
|
|
|
58
58
|
const public_env = filter_env(env, public_prefix, private_prefix);
|
|
59
59
|
internal.set_private_env(private_env);
|
|
60
60
|
internal.set_public_env(public_env);
|
|
61
|
-
internal.set_env(env);
|
|
62
61
|
internal.set_manifest(manifest);
|
|
63
62
|
internal.set_read_implementation((file) => createReadableStream(`${server_root}/server/${file}`));
|
|
64
63
|
|
|
64
|
+
/** @type {import('__sveltekit/env')} */
|
|
65
|
+
const { set_env } = await import(pathToFileURL(`${server_root}/server/env.js`).href);
|
|
66
|
+
set_env(env);
|
|
67
|
+
|
|
65
68
|
/** @type {import('types').ServerMetadata} */
|
|
66
69
|
const metadata = {
|
|
67
70
|
nodes: [],
|
|
@@ -43,14 +43,18 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
|
|
|
43
43
|
/** @type {import('types').ServerInternalModule} */
|
|
44
44
|
const internal = await import(pathToFileURL(`${out}/server/internal.js`).href);
|
|
45
45
|
|
|
46
|
-
/** @type {import('types').ServerModule} */
|
|
47
|
-
const { Server } = await import(pathToFileURL(`${out}/server/index.js`).href);
|
|
48
|
-
|
|
49
46
|
// configure `import { building } from '$app/environment'` and `$app/env` —
|
|
50
47
|
// essential we do this before analysing the code
|
|
51
48
|
internal.set_building();
|
|
52
49
|
internal.set_prerendering();
|
|
53
50
|
|
|
51
|
+
/** @type {import('__sveltekit/env')} */
|
|
52
|
+
const { set_env } = await import(pathToFileURL(`${out}/server/env.js`).href);
|
|
53
|
+
set_env(env);
|
|
54
|
+
|
|
55
|
+
/** @type {import('types').ServerModule} */
|
|
56
|
+
const { Server } = await import(pathToFileURL(`${out}/server/index.js`).href);
|
|
57
|
+
|
|
54
58
|
/**
|
|
55
59
|
* @template {{message: string}} T
|
|
56
60
|
* @template {Omit<T, 'message'>} K
|
|
@@ -382,6 +386,12 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
|
|
|
382
386
|
const type = headers['content-type'];
|
|
383
387
|
const is_html = response_type === REDIRECT || type === 'text/html';
|
|
384
388
|
|
|
389
|
+
if (!is_html && response.status === 200 && decoded.slice(config.paths.base.length + 1) === '') {
|
|
390
|
+
throw new Error(
|
|
391
|
+
`Cannot prerender a root +server.js that returns a non-HTML response - static hosts always serve an HTML file for \`${config.paths.base || '/'}\``
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
|
|
385
395
|
const file = output_filename(decoded, is_html);
|
|
386
396
|
const dest = `${config.outDir}/output/prerendered/${category}/${file}`;
|
|
387
397
|
|
|
@@ -499,7 +509,6 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
|
|
|
499
509
|
const public_env = filter_env(env, public_prefix, private_prefix);
|
|
500
510
|
internal.set_private_env(private_env);
|
|
501
511
|
internal.set_public_env(public_env);
|
|
502
|
-
internal.set_env(env);
|
|
503
512
|
internal.set_manifest(manifest);
|
|
504
513
|
internal.set_read_implementation((file) => createReadableStream(`${out}/server/${file}`));
|
|
505
514
|
|
|
@@ -426,7 +426,7 @@ function create_routes_and_nodes(cwd, config, fallback) {
|
|
|
426
426
|
|
|
427
427
|
const indexes = new Map(nodes.map((node, i) => [node, i]));
|
|
428
428
|
|
|
429
|
-
const node_analyser = create_node_analyser();
|
|
429
|
+
const node_analyser = create_node_analyser(cwd);
|
|
430
430
|
|
|
431
431
|
// add the related layout, page, and error nodes for a route
|
|
432
432
|
for (const route of routes) {
|
|
@@ -495,7 +495,18 @@ function create_routes_and_nodes(cwd, config, fallback) {
|
|
|
495
495
|
|
|
496
496
|
for (const route of routes) {
|
|
497
497
|
if (route.endpoint) {
|
|
498
|
-
route.endpoint.page_options = get_page_options(route.endpoint.file);
|
|
498
|
+
route.endpoint.page_options = get_page_options(path.join(cwd, route.endpoint.file));
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
if (route.page && route.endpoint) {
|
|
502
|
+
const page = nodes[route.page.leaf];
|
|
503
|
+
if (page.page_options?.prerender || route.endpoint.page_options?.prerender) {
|
|
504
|
+
const endpoint_file = route.endpoint.file.split('/').pop();
|
|
505
|
+
|
|
506
|
+
throw new Error(
|
|
507
|
+
`Cannot prerender a route (${route.id}) with both a \`+page.svelte\` and a \`${endpoint_file}\``
|
|
508
|
+
);
|
|
509
|
+
}
|
|
499
510
|
}
|
|
500
511
|
}
|
|
501
512
|
|
|
@@ -183,6 +183,8 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
|
|
|
183
183
|
export const decode = (type, value) => decoders[type](value);
|
|
184
184
|
|
|
185
185
|
export { default as root } from '../root.${isSvelte5Plus() ? 'js' : 'svelte'}';
|
|
186
|
+
|
|
187
|
+
export const get_error_template = () => import('../shared/error-template.js').then(m => m.default);
|
|
186
188
|
`
|
|
187
189
|
);
|
|
188
190
|
|
|
@@ -17,7 +17,6 @@ import { escape_html } from '../../utils/escape.js';
|
|
|
17
17
|
* has_service_worker: boolean;
|
|
18
18
|
* runtime_directory: string;
|
|
19
19
|
* template: string;
|
|
20
|
-
* error_page: string;
|
|
21
20
|
* }} opts
|
|
22
21
|
*/
|
|
23
22
|
const server_template = ({
|
|
@@ -26,15 +25,14 @@ const server_template = ({
|
|
|
26
25
|
universal_hooks,
|
|
27
26
|
has_service_worker,
|
|
28
27
|
runtime_directory,
|
|
29
|
-
template
|
|
30
|
-
error_page
|
|
28
|
+
template
|
|
31
29
|
}) => `
|
|
32
30
|
import root from '../root.${isSvelte5Plus() ? 'js' : 'svelte'}';
|
|
33
31
|
import { set_building, set_prerendering } from '$app/env/internal';
|
|
34
32
|
import { set_assets } from '$app/paths/internal/server';
|
|
35
33
|
import { set_manifest, set_read_implementation } from '__sveltekit/server';
|
|
36
|
-
import { set_env } from '__sveltekit/env';
|
|
37
34
|
import { set_private_env, set_public_env } from '${runtime_directory}/shared-server.js';
|
|
35
|
+
import error from '../shared/error-template.js';
|
|
38
36
|
|
|
39
37
|
export const options = {
|
|
40
38
|
app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')},
|
|
@@ -63,9 +61,7 @@ export const options = {
|
|
|
63
61
|
/%sveltekit\.env\.([^%]+)%/g,
|
|
64
62
|
(_match, capture) => `" + (env[${s(capture)}] ?? "") + "`
|
|
65
63
|
)},
|
|
66
|
-
error
|
|
67
|
-
.replace(/%sveltekit\.status%/g, '" + status + "')
|
|
68
|
-
.replace(/%sveltekit\.error\.message%/g, '" + message + "')}
|
|
64
|
+
error
|
|
69
65
|
},
|
|
70
66
|
version_hash: ${s(hash(config.kit.version.name))}
|
|
71
67
|
};
|
|
@@ -93,7 +89,7 @@ export async function get_hooks() {
|
|
|
93
89
|
};
|
|
94
90
|
}
|
|
95
91
|
|
|
96
|
-
export { set_assets, set_building,
|
|
92
|
+
export { set_assets, set_building, set_manifest, set_prerendering, set_private_env, set_public_env, set_read_implementation };
|
|
97
93
|
`;
|
|
98
94
|
|
|
99
95
|
// TODO need to re-run this whenever src/app.html or src/error.html are
|
|
@@ -126,6 +122,13 @@ export function write_server(config, output) {
|
|
|
126
122
|
return posixify(path.relative(`${output}/server`, file));
|
|
127
123
|
}
|
|
128
124
|
|
|
125
|
+
write_if_changed(
|
|
126
|
+
`${output}/shared/error-template.js`,
|
|
127
|
+
`export default ({ status, message }) => ${s(load_error_page(config))
|
|
128
|
+
.replace(/%sveltekit\.status%/g, '" + status + "')
|
|
129
|
+
.replace(/%sveltekit\.error\.message%/g, '" + message + "')};`
|
|
130
|
+
);
|
|
131
|
+
|
|
129
132
|
// Contains the stringified version of
|
|
130
133
|
/** @type {import('types').SSROptions} */
|
|
131
134
|
write_if_changed(
|
|
@@ -137,8 +140,7 @@ export function write_server(config, output) {
|
|
|
137
140
|
has_service_worker:
|
|
138
141
|
config.kit.serviceWorker.register && !!resolve_entry(config.kit.files.serviceWorker),
|
|
139
142
|
runtime_directory: relative(runtime_directory),
|
|
140
|
-
template: load_template(process.cwd(), config)
|
|
141
|
-
error_page: load_error_page(config)
|
|
143
|
+
template: load_template(process.cwd(), config)
|
|
142
144
|
})
|
|
143
145
|
);
|
|
144
146
|
}
|
|
@@ -122,8 +122,7 @@ export function get_tsconfig(kit) {
|
|
|
122
122
|
moduleResolution: 'bundler',
|
|
123
123
|
module: 'esnext',
|
|
124
124
|
noEmit: true, // prevent tsconfig error "overwriting input files" - Vite handles the build and ignores this
|
|
125
|
-
target: 'esnext'
|
|
126
|
-
types: ['node']
|
|
125
|
+
target: 'esnext'
|
|
127
126
|
},
|
|
128
127
|
include: [...include],
|
|
129
128
|
exclude
|
|
@@ -16,7 +16,7 @@ const ASYNC_VALIDATOR = {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* @param {Record<string, EnvVarConfig<any
|
|
19
|
+
* @param {Record<string, EnvVarConfig<any> | undefined>} variables
|
|
20
20
|
* @param {string | undefined} value
|
|
21
21
|
* @param {string} name
|
|
22
22
|
* @param {Record<string, StandardSchemaV1.Issue[]>} issues
|
package/src/exports/public.d.ts
CHANGED
|
@@ -141,7 +141,7 @@ export interface Builder {
|
|
|
141
141
|
generateFallback: (dest: string) => Promise<void>;
|
|
142
142
|
|
|
143
143
|
/**
|
|
144
|
-
* Generate a module exposing build-time environment variables as `$env/dynamic/public` if the app uses it.
|
|
144
|
+
* Generate a module exposing build-time environment variables as `$env/dynamic/public` or `$app/env/public` if the app uses it.
|
|
145
145
|
*/
|
|
146
146
|
generateEnvModule: () => void;
|
|
147
147
|
|
|
@@ -1550,6 +1550,10 @@ export interface RequestEvent<
|
|
|
1550
1550
|
locals: App.Locals;
|
|
1551
1551
|
/**
|
|
1552
1552
|
* The parameters of the current route - e.g. for a route like `/blog/[slug]`, a `{ slug: string }` object.
|
|
1553
|
+
*
|
|
1554
|
+
* In the context of a remote function request initiated by the client, this relates to the page the remote function
|
|
1555
|
+
* was called from, _not_ the URL of the endpoint SvelteKit creates for the remote function. Never use this to determine
|
|
1556
|
+
* whether or not a user is authorized to access certain data, as these values are part of the request which could be manipulated.
|
|
1553
1557
|
*/
|
|
1554
1558
|
params: Params;
|
|
1555
1559
|
/**
|
|
@@ -1566,6 +1570,10 @@ export interface RequestEvent<
|
|
|
1566
1570
|
route: {
|
|
1567
1571
|
/**
|
|
1568
1572
|
* The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `/blog/[slug]`. It is `null` when no route is matched.
|
|
1573
|
+
*
|
|
1574
|
+
* In the context of a remote function request initiated by the client, this relates to the page the remote function
|
|
1575
|
+
* was called from, _not_ the URL of the endpoint SvelteKit creates for the remote function. Never use this to determine
|
|
1576
|
+
* whether or not a user is authorized to access certain data, as these values are part of the request which could be manipulated.
|
|
1569
1577
|
*/
|
|
1570
1578
|
id: RouteId;
|
|
1571
1579
|
};
|
|
@@ -1594,6 +1602,10 @@ export interface RequestEvent<
|
|
|
1594
1602
|
setHeaders: (headers: Record<string, string>) => void;
|
|
1595
1603
|
/**
|
|
1596
1604
|
* The requested URL.
|
|
1605
|
+
*
|
|
1606
|
+
* In the context of a remote function request initiated by the client, this relates to the page the remote function
|
|
1607
|
+
* was called from, _not_ the URL of the endpoint SvelteKit creates for the remote function. Never use this to determine
|
|
1608
|
+
* whether or not a user is authorized to access certain data, as these values are part of the request which could be manipulated.
|
|
1597
1609
|
*/
|
|
1598
1610
|
url: URL;
|
|
1599
1611
|
/**
|
|
@@ -147,7 +147,12 @@ export function build_server_nodes(
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
if (node.universal) {
|
|
150
|
-
if (
|
|
150
|
+
if (
|
|
151
|
+
(kit.router.type === 'hash' &&
|
|
152
|
+
node.page_options !== null &&
|
|
153
|
+
node.page_options?.ssr === undefined) ||
|
|
154
|
+
(node.page_options && node.page_options.ssr === false)
|
|
155
|
+
) {
|
|
151
156
|
exports.push(`export const universal = ${s(node.page_options, null, 2)};`);
|
|
152
157
|
} else {
|
|
153
158
|
imports.push(
|
|
@@ -106,11 +106,17 @@ export async function build_service_worker(
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
if (id === '\0virtual:app/env/public') {
|
|
109
|
-
|
|
109
|
+
const has_dynamic_public_env = Object.values(env_config ?? {}).some(
|
|
110
|
+
(variable) => variable.public && !variable.static
|
|
111
|
+
);
|
|
112
|
+
|
|
110
113
|
return create_sveltekit_env_public(
|
|
111
114
|
env_config,
|
|
112
115
|
env.all,
|
|
113
|
-
|
|
116
|
+
has_dynamic_public_env
|
|
117
|
+
? // the service worker isn't registered as ESM yet, so we need to use `importScripts`
|
|
118
|
+
`importScripts('${kit.paths.base}/${kit.appDir}/env.script.js'); const env = globalThis.__sveltekit_sw.env;`
|
|
119
|
+
: ''
|
|
114
120
|
);
|
|
115
121
|
}
|
|
116
122
|
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
import * as sync from '../../core/sync/sync.js';
|
|
23
23
|
import { create_assets } from '../../core/sync/create_manifest_data/index.js';
|
|
24
24
|
import { runtime_directory, logger } from '../../core/utils.js';
|
|
25
|
-
import { load_svelte_config, process_config } from '../../core/config/index.js';
|
|
25
|
+
import { load_svelte_config, process_config, split_config } from '../../core/config/index.js';
|
|
26
26
|
import { generate_manifest } from '../../core/generate_manifest/index.js';
|
|
27
27
|
import { build_server_nodes } from './build/build_server.js';
|
|
28
28
|
import { build_service_worker } from './build/build_service_worker.js';
|
|
@@ -143,19 +143,27 @@ const warning_preprocessor = {
|
|
|
143
143
|
/**
|
|
144
144
|
* Returns the SvelteKit Vite plugins.
|
|
145
145
|
* Since version 2.62.0 you can pass [configuration](configuration) directly, in which case `svelte.config.js` is ignored.
|
|
146
|
-
*
|
|
146
|
+
* Any options that don't belong to SvelteKit are passed through to `vite-plugin-svelte`.
|
|
147
|
+
* @param {KitConfig & Omit<Options, 'onwarn'> & Pick<SvelteConfig, 'vitePlugin'>} [config]
|
|
147
148
|
* @returns {Promise<Plugin[]>}
|
|
148
149
|
*/
|
|
149
150
|
export async function sveltekit(config) {
|
|
150
151
|
/** @type {ValidatedConfig} */
|
|
151
152
|
let svelte_config;
|
|
152
153
|
|
|
154
|
+
// any options passed to the plugin that SvelteKit doesn't use itself are
|
|
155
|
+
// forwarded to vite-plugin-svelte, which does its own validation
|
|
156
|
+
/** @type {Record<string, any>} */
|
|
157
|
+
let vite_plugin_svelte_config = {};
|
|
158
|
+
|
|
153
159
|
if (config !== undefined) {
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
const split = split_config(config);
|
|
161
|
+
vite_plugin_svelte_config = split.vite_plugin_svelte_config;
|
|
162
|
+
|
|
163
|
+
svelte_config = process_config(split.svelte_config, {
|
|
164
|
+
cwd,
|
|
165
|
+
source: 'SvelteKit options from Vite config'
|
|
166
|
+
});
|
|
159
167
|
|
|
160
168
|
const config_file = ['svelte.config.js', 'svelte.config.ts'].find((file) =>
|
|
161
169
|
fs.existsSync(file)
|
|
@@ -180,6 +188,9 @@ export async function sveltekit(config) {
|
|
|
180
188
|
|
|
181
189
|
/** @type {Options} */
|
|
182
190
|
const vite_plugin_svelte_options = {
|
|
191
|
+
// pass through any options that SvelteKit doesn't use itself first, so
|
|
192
|
+
// that the options SvelteKit manages below always take precedence
|
|
193
|
+
...vite_plugin_svelte_config,
|
|
183
194
|
configFile: false,
|
|
184
195
|
extensions: svelte_config.extensions,
|
|
185
196
|
preprocess,
|
|
@@ -293,8 +304,11 @@ async function kit({ svelte_config }) {
|
|
|
293
304
|
const allow = new Set([
|
|
294
305
|
kit.files.lib,
|
|
295
306
|
kit.files.routes,
|
|
307
|
+
kit.files.src,
|
|
296
308
|
kit.outDir,
|
|
297
|
-
|
|
309
|
+
// ensures that the client entry is served even if it's located outside
|
|
310
|
+
// the local node_modules, such as the pnpm global virtual store
|
|
311
|
+
runtime_directory,
|
|
298
312
|
path.resolve('node_modules'),
|
|
299
313
|
path.resolve(vite.searchForWorkspaceRoot(cwd), 'node_modules')
|
|
300
314
|
]);
|
|
@@ -958,6 +972,7 @@ async function kit({ svelte_config }) {
|
|
|
958
972
|
if (ssr) {
|
|
959
973
|
input.index = `${runtime_directory}/server/index.js`;
|
|
960
974
|
input.internal = `${out_dir}/generated/server/internal.js`;
|
|
975
|
+
input.env = `__sveltekit/env`;
|
|
961
976
|
input['remote-entry'] = `${runtime_directory}/app/server/remote/index.js`;
|
|
962
977
|
|
|
963
978
|
// add entry points for every endpoint...
|
|
@@ -1375,6 +1390,17 @@ async function kit({ svelte_config }) {
|
|
|
1375
1390
|
const deps_of = (entry, add_dynamic_css = false) =>
|
|
1376
1391
|
find_deps(manifest, posixify(path.relative('.', entry)), add_dynamic_css);
|
|
1377
1392
|
|
|
1393
|
+
const has_explicit_dynamic_public_env = Object.values(explicit_env_config ?? {}).some(
|
|
1394
|
+
(variable) => variable.public && !variable.static
|
|
1395
|
+
);
|
|
1396
|
+
|
|
1397
|
+
const uses_env_dynamic_public = client_chunks.some(
|
|
1398
|
+
(chunk) =>
|
|
1399
|
+
chunk.type === 'chunk' &&
|
|
1400
|
+
(chunk.modules[env_dynamic_public] ||
|
|
1401
|
+
(has_explicit_dynamic_public_env && chunk.modules[sveltekit_env_public_client]))
|
|
1402
|
+
);
|
|
1403
|
+
|
|
1378
1404
|
if (svelte_config.kit.output.bundleStrategy === 'split') {
|
|
1379
1405
|
const start = deps_of(`${runtime_directory}/client/entry.js`);
|
|
1380
1406
|
const app = deps_of(`${out_dir}/generated/client-optimized/app.js`);
|
|
@@ -1385,9 +1411,7 @@ async function kit({ svelte_config }) {
|
|
|
1385
1411
|
imports: [...start.imports, ...app.imports],
|
|
1386
1412
|
stylesheets: [...start.stylesheets, ...app.stylesheets],
|
|
1387
1413
|
fonts: [...start.fonts, ...app.fonts],
|
|
1388
|
-
uses_env_dynamic_public
|
|
1389
|
-
(chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public]
|
|
1390
|
-
)
|
|
1414
|
+
uses_env_dynamic_public
|
|
1391
1415
|
};
|
|
1392
1416
|
|
|
1393
1417
|
// In case of server-side route resolution, we create a purpose-built route manifest that is
|
|
@@ -1434,9 +1458,7 @@ async function kit({ svelte_config }) {
|
|
|
1434
1458
|
imports: start.imports,
|
|
1435
1459
|
stylesheets: start.stylesheets,
|
|
1436
1460
|
fonts: start.fonts,
|
|
1437
|
-
uses_env_dynamic_public
|
|
1438
|
-
(chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public]
|
|
1439
|
-
)
|
|
1461
|
+
uses_env_dynamic_public
|
|
1440
1462
|
};
|
|
1441
1463
|
|
|
1442
1464
|
if (svelte_config.kit.output.bundleStrategy === 'inline') {
|
|
@@ -1633,13 +1655,18 @@ function find_overridden_config(config, resolved_config, enforced_config, path,
|
|
|
1633
1655
|
for (const key in enforced_config) {
|
|
1634
1656
|
if (typeof config === 'object' && key in config && key in resolved_config) {
|
|
1635
1657
|
const enforced = enforced_config[key];
|
|
1658
|
+
const resolved = resolved_config[key];
|
|
1636
1659
|
|
|
1637
1660
|
if (enforced === true) {
|
|
1638
|
-
|
|
1661
|
+
// Normalize path separators before comparing to avoid false positives on Windows,
|
|
1662
|
+
// where config values like `root` may use backslashes while SvelteKit uses forward slashes.
|
|
1663
|
+
const a = typeof config[key] === 'string' ? posixify(config[key]) : config[key];
|
|
1664
|
+
const b = typeof resolved === 'string' ? posixify(resolved) : resolved;
|
|
1665
|
+
if (a !== b) {
|
|
1639
1666
|
out.push(path + key);
|
|
1640
1667
|
}
|
|
1641
1668
|
} else {
|
|
1642
|
-
find_overridden_config(config[key],
|
|
1669
|
+
find_overridden_config(config[key], resolved, enforced, path + key + '.', out);
|
|
1643
1670
|
}
|
|
1644
1671
|
}
|
|
1645
1672
|
}
|
|
@@ -1654,6 +1681,7 @@ const create_service_worker_module = (config) => dedent`
|
|
|
1654
1681
|
throw new Error('This module can only be imported inside a service worker');
|
|
1655
1682
|
}
|
|
1656
1683
|
|
|
1684
|
+
export const base = location.pathname.split('/').slice(0, -1).join('/');
|
|
1657
1685
|
export const build = [];
|
|
1658
1686
|
export const files = [
|
|
1659
1687
|
${create_assets(config)
|