@sveltejs/kit 3.0.0-next.10 → 3.0.0-next.12
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 +1 -1
- package/src/cli.js +8 -8
- package/src/constants.js +3 -1
- package/src/core/adapt/builder.js +3 -6
- package/src/core/config/index.js +6 -1
- package/src/core/config/options.js +54 -104
- package/src/core/env.js +25 -11
- package/src/core/postbuild/fallback.js +2 -1
- package/src/core/postbuild/prerender.js +75 -28
- package/src/core/postbuild/queue.js +2 -1
- package/src/core/sync/sync.js +11 -14
- package/src/core/sync/utils.js +21 -1
- package/src/core/sync/{write_non_ambient.js → write_app_types.js} +23 -21
- package/src/core/sync/write_client_manifest.js +4 -12
- package/src/core/sync/write_env.js +6 -4
- package/src/core/sync/write_server.js +12 -17
- package/src/core/sync/write_tsconfig/index.js +245 -0
- package/src/core/sync/write_tsconfig/utils.js +162 -0
- package/src/core/sync/write_types/index.js +80 -88
- package/src/core/utils.js +28 -3
- package/src/exports/env/index.js +68 -3
- package/src/exports/internal/env.js +6 -3
- package/src/exports/internal/server/index.js +3 -1
- package/src/exports/params.js +9 -4
- package/src/exports/public.d.ts +69 -71
- package/src/exports/vite/dev/index.js +112 -56
- package/src/exports/vite/index.js +483 -258
- package/src/exports/vite/module_ids.js +2 -2
- package/src/exports/vite/preview/index.js +3 -2
- package/src/exports/vite/utils.js +21 -10
- package/src/runner.js +13 -0
- package/src/runtime/app/forms.js +4 -0
- package/src/runtime/app/manifest/index.js +1 -0
- package/src/runtime/app/paths/client.js +30 -30
- package/src/runtime/app/paths/internal/client.js +26 -0
- package/src/runtime/app/paths/server.js +23 -10
- package/src/runtime/app/paths/types.d.ts +11 -19
- package/src/runtime/app/server/index.js +1 -1
- package/src/runtime/app/server/remote/command.js +12 -7
- package/src/runtime/app/server/remote/form.js +29 -26
- package/src/runtime/app/server/remote/prerender.js +9 -2
- package/src/runtime/app/server/remote/query.js +6 -5
- package/src/runtime/app/server/remote/shared.js +48 -30
- package/src/runtime/app/service-worker/index.js +24 -0
- package/src/runtime/app/state/index.js +1 -1
- package/src/runtime/client/client.js +46 -9
- package/src/runtime/client/ndjson.js +1 -1
- package/src/runtime/client/remote-functions/form.svelte.js +43 -51
- package/src/runtime/client/remote-functions/query/index.js +2 -2
- package/src/runtime/client/remote-functions/query-batch.svelte.js +2 -3
- package/src/runtime/client/remote-functions/query-live/iterator.js +5 -2
- package/src/runtime/client/remote-functions/shared.svelte.js +4 -1
- package/src/runtime/client/state.svelte.js +54 -21
- package/src/runtime/client/stream.js +3 -2
- package/src/runtime/form-utils.js +89 -54
- package/src/runtime/server/cookie.js +1 -1
- package/src/runtime/server/data/index.js +32 -29
- package/src/runtime/server/errors.js +135 -0
- package/src/runtime/server/fetch.js +1 -1
- package/src/runtime/server/index.js +20 -10
- package/src/runtime/server/internal.js +25 -0
- package/src/runtime/server/page/actions.js +4 -3
- package/src/runtime/server/page/data_serializer.js +10 -10
- package/src/runtime/server/page/index.js +3 -2
- package/src/runtime/server/page/load_data.js +1 -1
- package/src/runtime/server/page/render.js +22 -35
- package/src/runtime/server/page/respond_with_error.js +6 -5
- package/src/runtime/server/{remote.js → remote-functions.js} +67 -36
- package/src/runtime/server/respond.js +58 -20
- package/src/runtime/server/sourcemaps.js +183 -0
- package/src/runtime/server/utils.js +12 -157
- package/src/types/ambient-private.d.ts +10 -0
- package/src/types/ambient.d.ts +22 -27
- package/src/types/global-private.d.ts +12 -5
- package/src/types/internal.d.ts +19 -9
- package/src/types/private.d.ts +8 -0
- package/src/utils/escape.js +9 -25
- package/src/utils/features.js +1 -1
- package/src/utils/fork.js +7 -2
- package/src/utils/page_nodes.js +3 -5
- package/src/utils/url.js +12 -0
- package/src/version.js +1 -1
- package/types/index.d.ts +152 -120
- package/types/index.d.ts.map +6 -1
- package/src/core/sync/write_ambient.js +0 -18
- package/src/core/sync/write_tsconfig.js +0 -258
- package/src/runtime/shared-server.js +0 -7
- /package/src/core/sync/{write_tsconfig_test → write_tsconfig/test-app}/package.json +0 -0
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -75,19 +75,19 @@ if (!command) {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
if (command === 'sync') {
|
|
78
|
-
// create placeholder
|
|
78
|
+
// create placeholder node_modules/$app/tsconfig/tsconfig.json if necessary, to squelch warnings.
|
|
79
79
|
// this isn't bulletproof — if someone has some esoteric config, it will continue
|
|
80
80
|
// to harmlessly warn — but we handle the 90% case and clean up after ourselves
|
|
81
|
-
const
|
|
82
|
-
const base_tsconfig = `${
|
|
81
|
+
const dir = 'node_modules/$app/tsconfig';
|
|
82
|
+
const base_tsconfig = `${dir}/tsconfig.json`;
|
|
83
83
|
const base_tsconfig_json = '{}';
|
|
84
84
|
|
|
85
|
-
const sveltekit_dir_exists = fs.existsSync(
|
|
85
|
+
const sveltekit_dir_exists = fs.existsSync(dir);
|
|
86
86
|
const base_tsconfig_exists = fs.existsSync(base_tsconfig);
|
|
87
87
|
|
|
88
88
|
if (!base_tsconfig_exists) {
|
|
89
89
|
try {
|
|
90
|
-
fs.mkdirSync(
|
|
90
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
91
91
|
} catch {
|
|
92
92
|
// ignore
|
|
93
93
|
}
|
|
@@ -100,7 +100,7 @@ if (command === 'sync') {
|
|
|
100
100
|
const sveltekit_config = extract_svelte_config(vite_config);
|
|
101
101
|
|
|
102
102
|
const sync = await import('./core/sync/sync.js');
|
|
103
|
-
sync.all_types(sveltekit_config);
|
|
103
|
+
sync.all_types(sveltekit_config, vite_config.root);
|
|
104
104
|
|
|
105
105
|
const explicit_env_entry = resolve_explicit_env_entry(sveltekit_config.kit);
|
|
106
106
|
await sync.env(sveltekit_config.kit, explicit_env_entry, vite_config.root, values.mode);
|
|
@@ -113,8 +113,8 @@ if (command === 'sync') {
|
|
|
113
113
|
fs.unlinkSync(base_tsconfig);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
if (!sveltekit_dir_exists && fs.readdirSync(
|
|
117
|
-
fs.rmSync(
|
|
116
|
+
if (!sveltekit_dir_exists && fs.readdirSync(dir).length === 0) {
|
|
117
|
+
fs.rmSync(dir, { recursive: true });
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
} else {
|
package/src/constants.js
CHANGED
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export const SVELTE_KIT_ASSETS = '/_svelte_kit_assets';
|
|
6
6
|
|
|
7
|
-
export const GENERATED_COMMENT = '// this file is generated — do not edit it
|
|
7
|
+
export const GENERATED_COMMENT = '// this file is generated — do not edit it';
|
|
8
8
|
|
|
9
9
|
export const ENDPOINT_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'];
|
|
10
10
|
|
|
11
11
|
export const MUTATIVE_METHODS = ['POST', 'PUT', 'PATCH', 'DELETE'];
|
|
12
12
|
|
|
13
13
|
export const PAGE_METHODS = ['GET', 'POST', 'HEAD'];
|
|
14
|
+
|
|
15
|
+
export const SRC_ROOT = import.meta.dirname;
|
|
@@ -8,7 +8,7 @@ import * as devalue from 'devalue';
|
|
|
8
8
|
import { createReadStream, createWriteStream, existsSync, statSync } from 'node:fs';
|
|
9
9
|
import { extname, resolve, join, dirname, relative } from 'node:path';
|
|
10
10
|
import { pipeline } from 'node:stream';
|
|
11
|
-
import { promisify
|
|
11
|
+
import { promisify } from 'node:util';
|
|
12
12
|
import zlib from 'node:zlib';
|
|
13
13
|
import { copy, rimraf, mkdirp } from '../../utils/filesystem.js';
|
|
14
14
|
import { posixify } from '../../utils/os.js';
|
|
@@ -142,11 +142,8 @@ export function create_builder({
|
|
|
142
142
|
});
|
|
143
143
|
|
|
144
144
|
if (existsSync(dest)) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
['bold', 'yellow'],
|
|
148
|
-
`Overwriting ${dest} with fallback page. Consider using a different name for the fallback.`
|
|
149
|
-
)
|
|
145
|
+
log.warn(
|
|
146
|
+
`\nOverwriting ${dest} with fallback page. Consider using a different name for the fallback.\n`
|
|
150
147
|
);
|
|
151
148
|
}
|
|
152
149
|
|
package/src/core/config/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import fs from 'node:fs';
|
|
|
6
6
|
import path from 'node:path';
|
|
7
7
|
import process from 'node:process';
|
|
8
8
|
import * as url from 'node:url';
|
|
9
|
+
import { styleText } from 'node:util';
|
|
9
10
|
import {
|
|
10
11
|
validate_kit_options,
|
|
11
12
|
kit_options,
|
|
@@ -223,6 +224,10 @@ export function validate_config(config) {
|
|
|
223
224
|
return validated;
|
|
224
225
|
} catch (e) {
|
|
225
226
|
const error = /** @type {Error} */ (e);
|
|
226
|
-
|
|
227
|
+
|
|
228
|
+
// Print a nicer version of the error to the console
|
|
229
|
+
console.log(styleText(['bold', 'red'], `\n${error.message}\n`));
|
|
230
|
+
|
|
231
|
+
throw stackless('Failed to load SvelteKit options from Vite config');
|
|
227
232
|
}
|
|
228
233
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** @import { SvelteConfig } from '@sveltejs/vite-plugin-svelte' */
|
|
2
2
|
/** @import { ValidatedKitConfig } from 'types' */
|
|
3
3
|
/** @import { Validator } from './types.js' */
|
|
4
|
+
import { styleText } from 'node:util';
|
|
4
5
|
|
|
5
6
|
const directives = object({
|
|
6
7
|
'child-src': string_array(),
|
|
@@ -60,6 +61,12 @@ export const validate_svelte_options = object(
|
|
|
60
61
|
true
|
|
61
62
|
);
|
|
62
63
|
|
|
64
|
+
const prerender_handler = validate(undefined, (input, keypath) => {
|
|
65
|
+
if (typeof input === 'function') return input;
|
|
66
|
+
if (['fail', 'warn', 'ignore'].includes(input)) return input;
|
|
67
|
+
throw new Error(`${keypath} should be "fail", "warn", "ignore" or a custom function`);
|
|
68
|
+
});
|
|
69
|
+
|
|
63
70
|
/** @type {Validator<ValidatedKitConfig>} */
|
|
64
71
|
export const validate_kit_options = object({
|
|
65
72
|
adapter: validate(undefined, (input, keypath) => {
|
|
@@ -71,17 +78,21 @@ export const validate_kit_options = object({
|
|
|
71
78
|
return input;
|
|
72
79
|
}),
|
|
73
80
|
|
|
74
|
-
alias:
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
alias: deprecate(
|
|
82
|
+
validate({}, (input, keypath) => {
|
|
83
|
+
if (typeof input !== 'object') {
|
|
84
|
+
throw new Error(`${keypath} should be an object`);
|
|
85
|
+
}
|
|
78
86
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
for (const key in input) {
|
|
88
|
+
assert_string(input[key], `${keypath}.${key}`);
|
|
89
|
+
}
|
|
82
90
|
|
|
83
|
-
|
|
84
|
-
|
|
91
|
+
return input;
|
|
92
|
+
}),
|
|
93
|
+
(keypath) =>
|
|
94
|
+
`The \`${keypath}\` option is deprecated, and will be removed in a future version of SvelteKit. Use subpath imports instead: https://svelte.dev/docs/kit/$lib`
|
|
95
|
+
),
|
|
85
96
|
|
|
86
97
|
appDir: validate('_app', (input, keypath) => {
|
|
87
98
|
assert_string(input, keypath);
|
|
@@ -247,75 +258,11 @@ export const validate_kit_options = object({
|
|
|
247
258
|
return input;
|
|
248
259
|
}),
|
|
249
260
|
|
|
250
|
-
handleHttpError:
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
);
|
|
256
|
-
},
|
|
257
|
-
(input, keypath) => {
|
|
258
|
-
if (typeof input === 'function') return input;
|
|
259
|
-
if (['fail', 'warn', 'ignore'].includes(input)) return input;
|
|
260
|
-
throw new Error(`${keypath} should be "fail", "warn", "ignore" or a custom function`);
|
|
261
|
-
}
|
|
262
|
-
),
|
|
263
|
-
|
|
264
|
-
handleMissingId: validate(
|
|
265
|
-
(/** @type {any} */ { message }) => {
|
|
266
|
-
throw new Error(
|
|
267
|
-
message +
|
|
268
|
-
'\nTo suppress or handle this error, implement `handleMissingId` in https://svelte.dev/docs/kit/configuration#prerender'
|
|
269
|
-
);
|
|
270
|
-
},
|
|
271
|
-
(input, keypath) => {
|
|
272
|
-
if (typeof input === 'function') return input;
|
|
273
|
-
if (['fail', 'warn', 'ignore'].includes(input)) return input;
|
|
274
|
-
throw new Error(`${keypath} should be "fail", "warn", "ignore" or a custom function`);
|
|
275
|
-
}
|
|
276
|
-
),
|
|
277
|
-
|
|
278
|
-
handleEntryGeneratorMismatch: validate(
|
|
279
|
-
(/** @type {any} */ { message }) => {
|
|
280
|
-
throw new Error(
|
|
281
|
-
message +
|
|
282
|
-
'\nTo suppress or handle this error, implement `handleEntryGeneratorMismatch` in https://svelte.dev/docs/kit/configuration#prerender'
|
|
283
|
-
);
|
|
284
|
-
},
|
|
285
|
-
(input, keypath) => {
|
|
286
|
-
if (typeof input === 'function') return input;
|
|
287
|
-
if (['fail', 'warn', 'ignore'].includes(input)) return input;
|
|
288
|
-
throw new Error(`${keypath} should be "fail", "warn", "ignore" or a custom function`);
|
|
289
|
-
}
|
|
290
|
-
),
|
|
291
|
-
|
|
292
|
-
handleUnseenRoutes: validate(
|
|
293
|
-
(/** @type {any} */ { message }) => {
|
|
294
|
-
throw new Error(
|
|
295
|
-
message +
|
|
296
|
-
'\nTo suppress or handle this error, implement `handleUnseenRoutes` in https://svelte.dev/docs/kit/configuration#prerender'
|
|
297
|
-
);
|
|
298
|
-
},
|
|
299
|
-
(input, keypath) => {
|
|
300
|
-
if (typeof input === 'function') return input;
|
|
301
|
-
if (['fail', 'warn', 'ignore'].includes(input)) return input;
|
|
302
|
-
throw new Error(`${keypath} should be "fail", "warn", "ignore" or a custom function`);
|
|
303
|
-
}
|
|
304
|
-
),
|
|
305
|
-
|
|
306
|
-
handleInvalidUrl: validate(
|
|
307
|
-
(/** @type {any} */ { message }) => {
|
|
308
|
-
throw new Error(
|
|
309
|
-
message +
|
|
310
|
-
'\nTo suppress or handle this error, implement `handleInvalidUrl` in https://svelte.dev/docs/kit/configuration#prerender'
|
|
311
|
-
);
|
|
312
|
-
},
|
|
313
|
-
(input, keypath) => {
|
|
314
|
-
if (typeof input === 'function') return input;
|
|
315
|
-
if (['fail', 'warn', 'ignore'].includes(input)) return input;
|
|
316
|
-
throw new Error(`${keypath} should be "fail", "warn", "ignore" or a custom function`);
|
|
317
|
-
}
|
|
318
|
-
),
|
|
261
|
+
handleHttpError: prerender_handler,
|
|
262
|
+
handleMissingId: prerender_handler,
|
|
263
|
+
handleEntryGeneratorMismatch: prerender_handler,
|
|
264
|
+
handleUnseenRoutes: prerender_handler,
|
|
265
|
+
handleInvalidUrl: prerender_handler,
|
|
319
266
|
|
|
320
267
|
origin: removed(
|
|
321
268
|
(keypath) => `\`${keypath}\` has been removed in favour of \`config.paths.origin\``
|
|
@@ -328,47 +275,50 @@ export const validate_kit_options = object({
|
|
|
328
275
|
}),
|
|
329
276
|
|
|
330
277
|
serviceWorker: object({
|
|
278
|
+
files: removed(),
|
|
331
279
|
register: boolean(true),
|
|
332
280
|
// options could be undefined but if it is defined we only validate that
|
|
333
281
|
// it's an object since the type comes from the browser itself
|
|
334
|
-
options: validate(undefined, object({}, true))
|
|
335
|
-
files: fun((filename) => !/\.DS_Store/.test(filename))
|
|
282
|
+
options: validate(undefined, object({}, true))
|
|
336
283
|
}),
|
|
337
284
|
|
|
338
285
|
tracing: object({
|
|
339
286
|
server: boolean(false)
|
|
340
287
|
}),
|
|
341
288
|
|
|
342
|
-
typescript:
|
|
343
|
-
|
|
344
|
-
|
|
289
|
+
typescript: deprecate(
|
|
290
|
+
object({
|
|
291
|
+
config: fun((config) => config)
|
|
292
|
+
}),
|
|
293
|
+
(keypath) => {
|
|
294
|
+
return `The \`${keypath}\` option is deprecated, and will be removed in a future version. Add configuration to tsconfig.json directly`;
|
|
295
|
+
}
|
|
296
|
+
),
|
|
345
297
|
|
|
346
298
|
version: object({
|
|
347
299
|
name: string(Date.now().toString()),
|
|
348
|
-
pollInterval: number(
|
|
300
|
+
pollInterval: number(3_600_000)
|
|
349
301
|
})
|
|
350
302
|
});
|
|
351
303
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
// };
|
|
371
|
-
// }
|
|
304
|
+
/**
|
|
305
|
+
* @param {Validator} fn
|
|
306
|
+
* @param {(keypath: string) => string} get_message
|
|
307
|
+
* @returns {Validator}
|
|
308
|
+
*/
|
|
309
|
+
function deprecate(
|
|
310
|
+
fn,
|
|
311
|
+
get_message = (keypath) =>
|
|
312
|
+
`The \`${keypath}\` option is deprecated, and will be removed in a future version`
|
|
313
|
+
) {
|
|
314
|
+
return (input, keypath) => {
|
|
315
|
+
if (input !== undefined) {
|
|
316
|
+
console.warn(styleText(['bold', 'yellow'], get_message(keypath)));
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return fn(input, keypath);
|
|
320
|
+
};
|
|
321
|
+
}
|
|
372
322
|
|
|
373
323
|
// Derive the names of SvelteKit's own config options from the schema, so they
|
|
374
324
|
// stay in sync automatically. These are used to separate Kit's options from
|
package/src/core/env.js
CHANGED
|
@@ -10,6 +10,7 @@ import { runtime_directory } from './utils.js';
|
|
|
10
10
|
import { resolve_entry } from '../utils/filesystem.js';
|
|
11
11
|
import { handle_issues, validate } from '../exports/internal/env.js';
|
|
12
12
|
import { get_config_aliases } from '../exports/vite/utils.js';
|
|
13
|
+
import { get_runner } from '../runner.js';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* @typedef {'public' | 'private'} EnvType
|
|
@@ -52,12 +53,14 @@ export async function load_explicit_env(kit, file, root, mode) {
|
|
|
52
53
|
/** @type {Record<string, EnvVarConfig<any>>} */
|
|
53
54
|
let variables;
|
|
54
55
|
|
|
56
|
+
const runner = get_runner(server);
|
|
57
|
+
|
|
55
58
|
/** @type {import('../runtime/app/env/internal.js')} */ (
|
|
56
|
-
await
|
|
59
|
+
await runner.import(`${runtime_directory}/app/env/internal.js`)
|
|
57
60
|
).set_building();
|
|
58
61
|
|
|
59
62
|
try {
|
|
60
|
-
({ variables } = await
|
|
63
|
+
({ variables } = await runner.import(file));
|
|
61
64
|
|
|
62
65
|
if (!variables || typeof variables !== 'object') {
|
|
63
66
|
throw new Error(`${file} must export a variables object`);
|
|
@@ -238,25 +241,35 @@ export function create_sveltekit_env_public(variables, env, prelude) {
|
|
|
238
241
|
* `env.js`. If there are none, values are inlined.
|
|
239
242
|
* @param {Record<string, EnvVarConfig<any>> | null} variables
|
|
240
243
|
* @param {Record<string, string>} env
|
|
244
|
+
* @param {string} version
|
|
241
245
|
* @param {string} global
|
|
242
246
|
* @param {string} base
|
|
243
247
|
* @param {string} app_dir
|
|
244
248
|
*/
|
|
245
|
-
export function create_sveltekit_env_service_worker(
|
|
249
|
+
export function create_sveltekit_env_service_worker(
|
|
250
|
+
variables,
|
|
251
|
+
env,
|
|
252
|
+
version,
|
|
253
|
+
global,
|
|
254
|
+
base,
|
|
255
|
+
app_dir
|
|
256
|
+
) {
|
|
246
257
|
const has_dynamic_public_env = Object.values(variables ?? {}).some(
|
|
247
258
|
(config) => config.public && !config.static
|
|
248
259
|
);
|
|
249
260
|
|
|
250
261
|
if (!has_dynamic_public_env) {
|
|
251
|
-
return create_sveltekit_env_service_worker_dev(variables, env, global);
|
|
262
|
+
return create_sveltekit_env_service_worker_dev(variables, env, version, global);
|
|
252
263
|
}
|
|
253
264
|
|
|
254
265
|
return dedent`
|
|
255
266
|
import { env } from '${base}/${app_dir}/env.js';
|
|
256
267
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
268
|
+
${global} = {
|
|
269
|
+
base: location.pathname.split('/').slice(0, -1).join('/'),
|
|
270
|
+
env,
|
|
271
|
+
version: ${JSON.stringify(version)}
|
|
272
|
+
};
|
|
260
273
|
`;
|
|
261
274
|
}
|
|
262
275
|
|
|
@@ -264,9 +277,10 @@ export function create_sveltekit_env_service_worker(variables, env, global, base
|
|
|
264
277
|
* Creates the `__sveltekit/env/service-worker` module used in development
|
|
265
278
|
* @param {Record<string, EnvVarConfig<any>> | null} variables
|
|
266
279
|
* @param {Record<string, string>} env
|
|
280
|
+
* @param {string} version
|
|
267
281
|
* @param {string} global
|
|
268
282
|
*/
|
|
269
|
-
export function create_sveltekit_env_service_worker_dev(variables, env, global) {
|
|
283
|
+
export function create_sveltekit_env_service_worker_dev(variables, env, version, global) {
|
|
270
284
|
/** @type {string[]} */
|
|
271
285
|
const properties = [];
|
|
272
286
|
|
|
@@ -283,12 +297,12 @@ export function create_sveltekit_env_service_worker_dev(variables, env, global)
|
|
|
283
297
|
handle_issues(issues);
|
|
284
298
|
|
|
285
299
|
return dedent`
|
|
286
|
-
globalThis.__SVELTEKIT_EXPERIMENTAL_EXPLICIT_ENVIRONMENT_VARIABLES__ = true;
|
|
287
|
-
|
|
288
300
|
${global} = {
|
|
301
|
+
base: location.pathname.split('/').slice(0, -1).join('/'),
|
|
289
302
|
env: {
|
|
290
303
|
${properties.join(',\n\t\t') || '// empty'}
|
|
291
|
-
}
|
|
304
|
+
},
|
|
305
|
+
version: ${JSON.stringify(version)}
|
|
292
306
|
};
|
|
293
307
|
`;
|
|
294
308
|
}
|
|
@@ -2,6 +2,7 @@ import { readFileSync } from 'node:fs';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
4
|
import { forked } from '../../utils/fork.js';
|
|
5
|
+
import { stackless } from '../../utils/error.js';
|
|
5
6
|
|
|
6
7
|
export default forked(import.meta.url, generate_fallback);
|
|
7
8
|
|
|
@@ -47,5 +48,5 @@ async function generate_fallback({ manifest_path, env, out_dir, origin, assets }
|
|
|
47
48
|
return await response.text();
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
throw
|
|
51
|
+
throw stackless('Could not create a fallback page');
|
|
51
52
|
}
|
|
@@ -16,6 +16,7 @@ import * as devalue from 'devalue';
|
|
|
16
16
|
import { createReadableStream } from '@sveltejs/kit/node';
|
|
17
17
|
import generate_fallback from './fallback.js';
|
|
18
18
|
import { stringify_remote_arg } from '../../runtime/shared.js';
|
|
19
|
+
import { log_response } from '../../exports/vite/utils.js';
|
|
19
20
|
|
|
20
21
|
export default forked(import.meta.url, prerender);
|
|
21
22
|
|
|
@@ -57,29 +58,60 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
|
|
|
57
58
|
/** @type {import('types').ServerModule} */
|
|
58
59
|
const { Server } = await import(pathToFileURL(`${out}/server/index.js`).href);
|
|
59
60
|
|
|
61
|
+
const throw_handled = () => {
|
|
62
|
+
throw new Error('__handled__');
|
|
63
|
+
};
|
|
64
|
+
|
|
60
65
|
/**
|
|
61
66
|
* @template {{message: string}} T
|
|
62
67
|
* @template {Omit<T, 'message'>} K
|
|
63
|
-
* @param {
|
|
64
|
-
* @param {'fail' | 'warn' | 'ignore' | ((details: T) => void)} input
|
|
68
|
+
* @param {string} name
|
|
69
|
+
* @param {'fail' | 'warn' | 'ignore' | undefined | ((details: T) => void)} input
|
|
65
70
|
* @param {(details: K) => string} format
|
|
66
|
-
* @returns {(details: K) => void}
|
|
71
|
+
* @returns {(details: K & { error?: unknown }) => void}
|
|
67
72
|
*/
|
|
68
|
-
function normalise_error_handler(
|
|
73
|
+
function normalise_error_handler(name, input, format) {
|
|
74
|
+
/**
|
|
75
|
+
* @param {any} details
|
|
76
|
+
*/
|
|
77
|
+
function log_failure(details) {
|
|
78
|
+
const message = format(details);
|
|
79
|
+
log.error(`\n${message}\n`);
|
|
80
|
+
}
|
|
81
|
+
|
|
69
82
|
switch (input) {
|
|
70
83
|
case 'fail':
|
|
71
84
|
return (details) => {
|
|
72
|
-
|
|
85
|
+
log_failure(details);
|
|
86
|
+
throw_handled();
|
|
73
87
|
};
|
|
74
88
|
case 'warn':
|
|
75
|
-
return
|
|
76
|
-
log.error(format(details));
|
|
77
|
-
};
|
|
89
|
+
return log_failure;
|
|
78
90
|
case 'ignore':
|
|
79
91
|
return noop;
|
|
92
|
+
case undefined: {
|
|
93
|
+
return (details) => {
|
|
94
|
+
log_failure(details);
|
|
95
|
+
|
|
96
|
+
log.err(
|
|
97
|
+
`To suppress or handle this error, implement \`${name}\` in https://svelte.dev/docs/kit/configuration#prerender\n`
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
throw_handled();
|
|
101
|
+
};
|
|
102
|
+
}
|
|
80
103
|
default:
|
|
81
|
-
|
|
82
|
-
|
|
104
|
+
return (details) => {
|
|
105
|
+
const message = format(details);
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
// @ts-expect-error TS thinks T might be of a different kind, but it's not
|
|
109
|
+
input({ ...details, message });
|
|
110
|
+
} catch (error) {
|
|
111
|
+
log.prettyError(error, import.meta.dirname);
|
|
112
|
+
throw_handled();
|
|
113
|
+
}
|
|
114
|
+
};
|
|
83
115
|
}
|
|
84
116
|
}
|
|
85
117
|
|
|
@@ -141,48 +173,55 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
|
|
|
141
173
|
const saved = new Map();
|
|
142
174
|
|
|
143
175
|
const handle_http_error = normalise_error_handler(
|
|
144
|
-
|
|
176
|
+
'handleHttpError',
|
|
145
177
|
config.prerender.handleHttpError,
|
|
146
178
|
({ status, path, referrer, referenceType }) => {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
179
|
+
let message = `Failed to prerender ${path}`;
|
|
180
|
+
|
|
181
|
+
if (status === 404) {
|
|
182
|
+
if (!path.startsWith(config.paths.base)) {
|
|
183
|
+
message = referrer ? `${path} (${referenceType} from ${referrer})` : path;
|
|
184
|
+
|
|
185
|
+
message += ` does not begin with \`base\`. You can fix this by using \`resolve('${path}')\` from \`$app/paths\`. The base path is configurable from \`paths.base\``;
|
|
186
|
+
} else if (referrer) {
|
|
187
|
+
message = `${path} was ${referenceType} from ${referrer}`;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
151
190
|
|
|
152
|
-
return
|
|
191
|
+
return message;
|
|
153
192
|
}
|
|
154
193
|
);
|
|
155
194
|
|
|
156
195
|
const handle_missing_id = normalise_error_handler(
|
|
157
|
-
|
|
196
|
+
'handleMissingId',
|
|
158
197
|
config.prerender.handleMissingId,
|
|
159
198
|
({ path, id, referrers }) => {
|
|
160
199
|
return (
|
|
161
|
-
`The following pages contain links to ${path}#${id}, but no element with id="${id}" exists on ${path}
|
|
200
|
+
`The following pages contain links to ${path}#${id}, but no element with id="${id}" exists on ${path}:` +
|
|
162
201
|
referrers.map((l) => `\n - ${l}`).join('')
|
|
163
202
|
);
|
|
164
203
|
}
|
|
165
204
|
);
|
|
166
205
|
|
|
167
206
|
const handle_entry_generator_mismatch = normalise_error_handler(
|
|
168
|
-
|
|
207
|
+
'handleEntryGeneratorMismatch',
|
|
169
208
|
config.prerender.handleEntryGeneratorMismatch,
|
|
170
209
|
({ generatedFromId, entry, matchedId }) => {
|
|
171
|
-
return `The entries export from ${generatedFromId} generated entry ${entry}, which was matched by ${matchedId
|
|
210
|
+
return `The entries export from ${generatedFromId} generated entry ${entry}, which was matched by ${matchedId === entry ? 'a static route' : matchedId}`;
|
|
172
211
|
}
|
|
173
212
|
);
|
|
174
213
|
|
|
175
214
|
const handle_not_prerendered_route = normalise_error_handler(
|
|
176
|
-
|
|
215
|
+
'handleUnseenRoutes',
|
|
177
216
|
config.prerender.handleUnseenRoutes,
|
|
178
217
|
({ routes }) => {
|
|
179
218
|
const list = routes.map((id) => ` - ${id}`).join('\n');
|
|
180
|
-
return `The following routes were marked as prerenderable, but were not prerendered because they were not found while crawling your app:\n${list}
|
|
219
|
+
return `The following routes were marked as prerenderable, but were not prerendered because they were not found while crawling your app:\n${list}`;
|
|
181
220
|
}
|
|
182
221
|
);
|
|
183
222
|
|
|
184
223
|
const handle_invalid_url = normalise_error_handler(
|
|
185
|
-
|
|
224
|
+
'handleInvalidUrl',
|
|
186
225
|
config.prerender.handleInvalidUrl,
|
|
187
226
|
({ href, referrer }) => {
|
|
188
227
|
return `Invalid URL ${href}${referrer ? ` (linked from ${referrer})` : ''}`;
|
|
@@ -260,7 +299,9 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
|
|
|
260
299
|
/** @type {Map<string, import('types').PrerenderDependency>} */
|
|
261
300
|
const dependencies = new Map();
|
|
262
301
|
|
|
263
|
-
const
|
|
302
|
+
const request = new Request(prerender_origin + encoded);
|
|
303
|
+
|
|
304
|
+
const response = await server.respond(request, {
|
|
264
305
|
getClientAddress() {
|
|
265
306
|
throw new Error('Cannot read clientAddress during prerendering');
|
|
266
307
|
},
|
|
@@ -298,6 +339,10 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
|
|
|
298
339
|
});
|
|
299
340
|
}
|
|
300
341
|
|
|
342
|
+
if (response.status !== 204) {
|
|
343
|
+
log_response(response.status, request);
|
|
344
|
+
}
|
|
345
|
+
|
|
301
346
|
const body = Buffer.from(await response.arrayBuffer());
|
|
302
347
|
|
|
303
348
|
const category = decoded.startsWith(remote_prefix) ? 'data' : 'pages';
|
|
@@ -428,8 +473,6 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
|
|
|
428
473
|
if (!headers['x-sveltekit-normalize']) {
|
|
429
474
|
mkdirp(dirname(dest));
|
|
430
475
|
|
|
431
|
-
log.warn(`${response.status} ${decoded} -> ${location}`);
|
|
432
|
-
|
|
433
476
|
writeFileSync(
|
|
434
477
|
dest,
|
|
435
478
|
`<script>location.href=${devalue.uneval(
|
|
@@ -476,7 +519,6 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
|
|
|
476
519
|
|
|
477
520
|
mkdirp(dir);
|
|
478
521
|
|
|
479
|
-
log.info(`${response.status} ${decoded}`);
|
|
480
522
|
writeFileSync(dest, body);
|
|
481
523
|
written.add(file);
|
|
482
524
|
|
|
@@ -492,7 +534,12 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env, vit
|
|
|
492
534
|
|
|
493
535
|
prerendered.paths.push(decoded);
|
|
494
536
|
} else if (response_type !== OK) {
|
|
495
|
-
handle_http_error({
|
|
537
|
+
handle_http_error({
|
|
538
|
+
status: response.status,
|
|
539
|
+
path: decoded,
|
|
540
|
+
referrer,
|
|
541
|
+
referenceType
|
|
542
|
+
});
|
|
496
543
|
}
|
|
497
544
|
|
|
498
545
|
manifest.assets.add(file);
|
|
@@ -28,7 +28,7 @@ export function queue(concurrency) {
|
|
|
28
28
|
|
|
29
29
|
if (task) {
|
|
30
30
|
current += 1;
|
|
31
|
-
const promise =
|
|
31
|
+
const promise = (async () => task.fn())(); // could throw synchronously
|
|
32
32
|
|
|
33
33
|
void promise
|
|
34
34
|
.then(task.fulfil, (err) => {
|
|
@@ -54,6 +54,7 @@ export function queue(concurrency) {
|
|
|
54
54
|
const promise = new Promise((fulfil, reject) => {
|
|
55
55
|
tasks.push({ fn, fulfil, reject });
|
|
56
56
|
});
|
|
57
|
+
promise.catch(() => {});
|
|
57
58
|
|
|
58
59
|
dequeue();
|
|
59
60
|
return promise;
|