@sveltejs/kit 3.0.0-next.6 → 3.0.0-next.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -2
- package/src/core/adapt/builder.js +11 -39
- package/src/core/config/index.js +76 -71
- package/src/core/config/options.js +280 -285
- package/src/core/config/types.d.ts +1 -1
- package/src/core/env.js +85 -1
- package/src/core/generate_manifest/index.js +12 -15
- package/src/core/sync/create_manifest_data/index.js +6 -44
- package/src/core/sync/write_client_manifest.js +7 -14
- package/src/core/sync/write_non_ambient.js +10 -7
- package/src/core/sync/write_root.js +9 -30
- package/src/core/sync/write_server.js +0 -1
- package/src/core/sync/write_types/index.js +11 -10
- package/src/exports/index.js +3 -3
- package/src/exports/internal/client.js +5 -0
- package/src/exports/internal/index.js +1 -91
- 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 +1 -1
- package/src/exports/params.js +63 -0
- package/src/exports/public.d.ts +82 -32
- package/src/exports/url.js +84 -0
- package/src/exports/vite/dev/index.js +28 -17
- package/src/exports/vite/index.js +217 -156
- package/src/exports/vite/preview/index.js +1 -1
- package/src/exports/vite/utils.js +3 -5
- package/src/runtime/app/paths/client.js +3 -7
- package/src/runtime/app/paths/server.js +1 -1
- package/src/runtime/app/server/remote/query.js +6 -12
- package/src/runtime/app/state/client.js +1 -2
- package/src/runtime/app/stores.js +13 -76
- package/src/runtime/client/client.js +26 -79
- package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
- package/src/runtime/client/remote-functions/form.svelte.js +5 -24
- package/src/runtime/client/remote-functions/prerender.svelte.js +10 -3
- package/src/runtime/client/remote-functions/query/instance.svelte.js +18 -9
- package/src/runtime/client/remote-functions/query-live/instance.svelte.js +16 -6
- package/src/runtime/client/remote-functions/shared.svelte.js +1 -2
- package/src/runtime/client/state.svelte.js +66 -49
- package/src/runtime/client/types.d.ts +1 -1
- package/src/runtime/client/utils.js +0 -96
- package/src/runtime/form-utils.js +15 -2
- package/src/runtime/server/index.js +1 -1
- package/src/runtime/server/page/load_data.js +1 -1
- package/src/runtime/server/page/render.js +15 -24
- package/src/runtime/server/page/server_routing.js +13 -9
- package/src/runtime/server/remote.js +21 -12
- package/src/runtime/server/respond.js +11 -8
- package/src/runtime/telemetry/otel.js +1 -1
- package/src/types/ambient.d.ts +5 -1
- package/src/types/global-private.d.ts +1 -1
- package/src/types/internal.d.ts +9 -10
- package/src/utils/error.js +1 -1
- package/src/utils/mime.js +9 -0
- package/src/utils/params.js +66 -0
- package/src/utils/routing.js +84 -38
- package/src/utils/streaming.js +14 -4
- package/src/utils/url.js +0 -79
- package/src/version.js +1 -1
- package/types/index.d.ts +98 -87
- package/types/index.d.ts.map +10 -7
- package/src/exports/internal/server.js +0 -22
- /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
package/src/core/env.js
CHANGED
|
@@ -94,8 +94,9 @@ export async function load_explicit_env(kit, file, root, mode) {
|
|
|
94
94
|
* @param {Record<string, EnvVarConfig<any> | undefined> | null} variables
|
|
95
95
|
* @param {Record<string, string>} env
|
|
96
96
|
* @param {string | null} entry
|
|
97
|
+
* @param {boolean} is_dev
|
|
97
98
|
*/
|
|
98
|
-
export function create_sveltekit_env(variables, env, entry) {
|
|
99
|
+
export function create_sveltekit_env(variables, env, entry, is_dev) {
|
|
99
100
|
const imports = entry
|
|
100
101
|
? [
|
|
101
102
|
`import { variables } from ${JSON.stringify(entry)};`,
|
|
@@ -149,6 +150,19 @@ export function create_sveltekit_env(variables, env, entry) {
|
|
|
149
150
|
}`
|
|
150
151
|
];
|
|
151
152
|
|
|
153
|
+
// In dev, initialise the env immediately. Tools like `vite-node` load modules
|
|
154
|
+
// through the Vite config but don't run the SvelteKit dev server, which is what
|
|
155
|
+
// normally calls `set_env`. Without this, dynamic env vars imported from
|
|
156
|
+
// `$app/env/public` and `$app/env/private` would be `undefined` in such contexts.
|
|
157
|
+
if (is_dev) {
|
|
158
|
+
/** @type {Record<string, string>} */
|
|
159
|
+
const dev_env = {};
|
|
160
|
+
for (const name of Object.keys(variables ?? {})) {
|
|
161
|
+
if (name in env) dev_env[name] = env[name];
|
|
162
|
+
}
|
|
163
|
+
blocks.push(`set_env(${devalue.uneval(dev_env)});`);
|
|
164
|
+
}
|
|
165
|
+
|
|
152
166
|
const module = blocks.join('\n\n');
|
|
153
167
|
|
|
154
168
|
return module;
|
|
@@ -361,3 +375,73 @@ export const reserved = new Set([
|
|
|
361
375
|
]);
|
|
362
376
|
|
|
363
377
|
export const valid_identifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Generates `export const` declarations (and, for reserved-word names that need
|
|
381
|
+
* aliasing, `const` + re-export specifiers) for a set of named exports.
|
|
382
|
+
*
|
|
383
|
+
* For regular names, emits a single efficient `export const name = expr;` statement.
|
|
384
|
+
* For reserved-word names (e.g. `delete`, `class`), emits `const alias = expr;` plus
|
|
385
|
+
* a re-export specifier (`alias as name`), since reserved words can't be `const`
|
|
386
|
+
* binding names but CAN appear in export specifiers.
|
|
387
|
+
*
|
|
388
|
+
* You can do evil things like `export { c as class }`. In order to import/re-export
|
|
389
|
+
* these, you need to alias the binding, then un-alias it when re-exporting:
|
|
390
|
+
*
|
|
391
|
+
* const _0 = ...; // safe binding name
|
|
392
|
+
* export { _0 as class }; // valid — `class` is allowed in export specifiers
|
|
393
|
+
*
|
|
394
|
+
* Aliases are chosen to avoid collisions with any of the supplied names. The
|
|
395
|
+
* namespace binding (used to hold the imported module) is likewise chosen to
|
|
396
|
+
* avoid collisions.
|
|
397
|
+
*
|
|
398
|
+
* @param {Iterable<string>} names — the export names
|
|
399
|
+
* @param {(name: string, namespace: string) => string} build_expression —
|
|
400
|
+
* called for each name to produce the right-hand side of the declaration;
|
|
401
|
+
* receives the chosen namespace binding so it can reference the imported module
|
|
402
|
+
* @param {string} namespace_prefix — the preferred binding name for the namespace
|
|
403
|
+
* (suffixed with a number if it collides with any export name)
|
|
404
|
+
* @returns {{ namespace: string, declarations: string[], reexports: string[] }}
|
|
405
|
+
*/
|
|
406
|
+
export function create_exported_declarations(names, build_expression, namespace_prefix) {
|
|
407
|
+
/** @type {Set<string>} */
|
|
408
|
+
const set = new Set(names);
|
|
409
|
+
|
|
410
|
+
let namespace = namespace_prefix;
|
|
411
|
+
let namespace_index = 0;
|
|
412
|
+
while (set.has(namespace)) {
|
|
413
|
+
namespace = `${namespace_prefix}${namespace_index++}`;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
let alias_index = 0;
|
|
417
|
+
/** @type {Map<string, string>} */
|
|
418
|
+
const aliases = new Map();
|
|
419
|
+
|
|
420
|
+
for (const name of set) {
|
|
421
|
+
if (!reserved.has(name)) continue;
|
|
422
|
+
|
|
423
|
+
let alias = `_${alias_index++}`;
|
|
424
|
+
while (set.has(alias)) {
|
|
425
|
+
alias = `_${alias_index++}`;
|
|
426
|
+
}
|
|
427
|
+
aliases.set(name, alias);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/** @type {string[]} */
|
|
431
|
+
const declarations = [];
|
|
432
|
+
/** @type {string[]} */
|
|
433
|
+
const reexports = [];
|
|
434
|
+
|
|
435
|
+
for (const name of set) {
|
|
436
|
+
const alias = aliases.get(name);
|
|
437
|
+
const expr = build_expression(name, namespace);
|
|
438
|
+
if (alias) {
|
|
439
|
+
declarations.push(`const ${alias} = ${expr};`);
|
|
440
|
+
reexports.push(`${alias} as ${name}`);
|
|
441
|
+
} else {
|
|
442
|
+
declarations.push(`export const ${name} = ${expr};`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
return { namespace, declarations, reexports };
|
|
447
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @import { RemoteChunk } from 'types' */
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import
|
|
4
|
+
import { lookup as mime_lookup } from '../../utils/mime.js';
|
|
5
5
|
import { s } from '../../utils/misc.js';
|
|
6
6
|
import { get_mime_lookup } from '../utils.js';
|
|
7
7
|
import { resolve_symlinks } from '../../exports/vite/build/utils.js';
|
|
@@ -69,10 +69,8 @@ export function generate_manifest({
|
|
|
69
69
|
assets.push(build_data.service_worker);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const matchers = new Set(
|
|
75
|
-
build_data.client?.nodes ? Object.keys(build_data.manifest_data.matchers) : undefined
|
|
72
|
+
const uses_matchers = build_data.manifest_data.routes.some((route) =>
|
|
73
|
+
route.params.some((param) => param.matcher)
|
|
76
74
|
);
|
|
77
75
|
|
|
78
76
|
/** @param {Array<number | undefined>} indexes */
|
|
@@ -93,7 +91,7 @@ export function generate_manifest({
|
|
|
93
91
|
files[file] = fs.statSync(path.resolve(build_data.out_dir, 'server', file)).size;
|
|
94
92
|
|
|
95
93
|
const ext = path.extname(file);
|
|
96
|
-
mime_types[ext] ??=
|
|
94
|
+
mime_types[ext] ??= mime_lookup(ext) || '';
|
|
97
95
|
}
|
|
98
96
|
|
|
99
97
|
// prettier-ignore
|
|
@@ -117,10 +115,6 @@ export function generate_manifest({
|
|
|
117
115
|
${routes.map(route => {
|
|
118
116
|
if (!route.page && !route.endpoint) return;
|
|
119
117
|
|
|
120
|
-
route.params.forEach(param => {
|
|
121
|
-
if (param.matcher) matchers.add(param.matcher);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
118
|
return dedent`
|
|
125
119
|
{
|
|
126
120
|
id: ${s(route.id)},
|
|
@@ -134,11 +128,14 @@ export function generate_manifest({
|
|
|
134
128
|
],
|
|
135
129
|
prerendered_routes: new Set(${s(prerendered)}),
|
|
136
130
|
matchers: async () => {
|
|
137
|
-
${
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
131
|
+
${
|
|
132
|
+
uses_matchers && build_data.manifest_data.params
|
|
133
|
+
? dedent`
|
|
134
|
+
const { params } = await import('${join_relative(relative_path, '/entries/params.js')}');
|
|
135
|
+
return params;
|
|
136
|
+
`
|
|
137
|
+
: 'return {};'
|
|
138
|
+
}
|
|
142
139
|
},
|
|
143
140
|
server_assets: ${s(files)}
|
|
144
141
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { lookup } from '
|
|
1
|
+
import { lookup } from '../../../utils/mime.js';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { styleText } from 'node:util';
|
|
@@ -29,22 +29,13 @@ export default function create_manifest_data({
|
|
|
29
29
|
}) {
|
|
30
30
|
const assets = create_assets(config);
|
|
31
31
|
const hooks = create_hooks(config, cwd);
|
|
32
|
-
const
|
|
32
|
+
const params = resolve_params(config, cwd);
|
|
33
33
|
const { nodes, routes } = create_routes_and_nodes(cwd, config, fallback);
|
|
34
34
|
|
|
35
|
-
// validate matcher names used in parameterised routes
|
|
36
|
-
for (const route of routes) {
|
|
37
|
-
for (const param of route.params) {
|
|
38
|
-
if (param.matcher && !matchers[param.matcher]) {
|
|
39
|
-
throw new Error(`No matcher found for parameter '${param.matcher}' in route ${route.id}`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
35
|
return {
|
|
45
36
|
assets,
|
|
46
37
|
hooks,
|
|
47
|
-
|
|
38
|
+
params,
|
|
48
39
|
nodes,
|
|
49
40
|
routes
|
|
50
41
|
};
|
|
@@ -82,38 +73,9 @@ function create_hooks(config, cwd) {
|
|
|
82
73
|
* @param {import('types').ValidatedConfig} config
|
|
83
74
|
* @param {string} cwd
|
|
84
75
|
*/
|
|
85
|
-
function
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
/** @type {Record<string, string>} */
|
|
89
|
-
const matchers = {};
|
|
90
|
-
if (fs.existsSync(config.kit.files.params)) {
|
|
91
|
-
for (const file of fs.readdirSync(config.kit.files.params)) {
|
|
92
|
-
const ext = path.extname(file);
|
|
93
|
-
if (!config.kit.moduleExtensions.includes(ext)) continue;
|
|
94
|
-
const type = file.slice(0, -ext.length);
|
|
95
|
-
|
|
96
|
-
if (/^\w+$/.test(type)) {
|
|
97
|
-
const matcher_file = path.join(params_base, file);
|
|
98
|
-
|
|
99
|
-
// Disallow same matcher with different extensions
|
|
100
|
-
if (matchers[type]) {
|
|
101
|
-
throw new Error(`Duplicate matchers: ${matcher_file} and ${matchers[type]}`);
|
|
102
|
-
} else {
|
|
103
|
-
matchers[type] = matcher_file;
|
|
104
|
-
}
|
|
105
|
-
} else {
|
|
106
|
-
// Allow for matcher test collocation
|
|
107
|
-
if (type.endsWith('.test') || type.endsWith('.spec')) continue;
|
|
108
|
-
|
|
109
|
-
throw new Error(
|
|
110
|
-
`Matcher names can only have underscores and alphanumeric characters — "${file}" is invalid`
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return matchers;
|
|
76
|
+
function resolve_params(config, cwd) {
|
|
77
|
+
const params_file = resolve_entry(config.kit.files.params);
|
|
78
|
+
return params_file ? posixify(path.relative(cwd, params_file)) : null;
|
|
117
79
|
}
|
|
118
80
|
|
|
119
81
|
/**
|
|
@@ -188,21 +188,14 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
|
|
|
188
188
|
);
|
|
189
189
|
|
|
190
190
|
if (client_routing) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const matchers = [];
|
|
195
|
-
|
|
196
|
-
for (const key in manifest_data.matchers) {
|
|
197
|
-
const src = manifest_data.matchers[key];
|
|
198
|
-
|
|
199
|
-
imports.push(`import { match as ${key} } from ${s(relative_path(output, src))};`);
|
|
200
|
-
matchers.push(key);
|
|
201
|
-
}
|
|
191
|
+
const uses_matchers = manifest_data.routes.some((route) =>
|
|
192
|
+
route.params.some((param) => param.matcher)
|
|
193
|
+
);
|
|
202
194
|
|
|
203
|
-
const module =
|
|
204
|
-
|
|
205
|
-
|
|
195
|
+
const module =
|
|
196
|
+
!manifest_data.params || !uses_matchers
|
|
197
|
+
? 'export const matchers = {};'
|
|
198
|
+
: `import { params as matchers } from ${s(relative_path(output, manifest_data.params))};\n\nexport { matchers };`;
|
|
206
199
|
|
|
207
200
|
write_if_changed(`${output}/matchers.js`, module);
|
|
208
201
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { GENERATED_COMMENT } from '../../constants.js';
|
|
3
|
+
import { resolve_entry } from '../../utils/filesystem.js';
|
|
3
4
|
import { posixify } from '../../utils/os.js';
|
|
4
5
|
import { write_if_changed } from './utils.js';
|
|
5
6
|
import { s } from '../../utils/misc.js';
|
|
@@ -85,10 +86,6 @@ export {};
|
|
|
85
86
|
* @param {import('types').ValidatedKitConfig} config
|
|
86
87
|
*/
|
|
87
88
|
function generate_app_types(manifest_data, config) {
|
|
88
|
-
/** @param {string} matcher */
|
|
89
|
-
const path_to_matcher = (matcher) =>
|
|
90
|
-
posixify(path.relative(config.outDir, path.join(config.files.params, matcher + '.js')));
|
|
91
|
-
|
|
92
89
|
/** @type {Map<string, string>} */
|
|
93
90
|
const matcher_types = new Map();
|
|
94
91
|
|
|
@@ -98,7 +95,15 @@ function generate_app_types(manifest_data, config) {
|
|
|
98
95
|
|
|
99
96
|
let type = matcher_types.get(matcher);
|
|
100
97
|
if (!type) {
|
|
101
|
-
|
|
98
|
+
const path_to_params = () => {
|
|
99
|
+
const params_file =
|
|
100
|
+
resolve_entry(config.files.params) ??
|
|
101
|
+
config.files.params.replace(/\.(js|ts)$/, '') + '.js';
|
|
102
|
+
|
|
103
|
+
return posixify(path.relative(config.outDir, params_file));
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
type = `import('@sveltejs/kit').MatcherParam<(typeof import('${path_to_params()}').params)[${JSON.stringify(matcher)}]>`;
|
|
102
107
|
matcher_types.set(matcher, type);
|
|
103
108
|
}
|
|
104
109
|
|
|
@@ -239,8 +244,6 @@ function generate_app_types(manifest_data, config) {
|
|
|
239
244
|
|
|
240
245
|
return [
|
|
241
246
|
'declare module "$app/types" {',
|
|
242
|
-
'\ttype MatcherParam<M> = M extends (param : string) => param is (infer U extends string) ? U : string;',
|
|
243
|
-
'',
|
|
244
247
|
'\texport interface AppTypes {',
|
|
245
248
|
`\t\tRouteId(): ${manifest_data.routes.map((r) => s(r.id)).join(' | ')};`,
|
|
246
249
|
`\t\tRouteParams(): {\n\t\t\t${dynamic_routes.join(';\n\t\t\t')}\n\t\t};`,
|
|
@@ -81,45 +81,24 @@ export function write_root(manifest_data, config, output) {
|
|
|
81
81
|
<!-- This file is generated by @sveltejs/kit — do not edit it! -->
|
|
82
82
|
<svelte:options runes={true} />
|
|
83
83
|
<script>
|
|
84
|
-
import {
|
|
85
|
-
import { browser } from '$app/env';
|
|
84
|
+
import { afterNavigate } from '$app/navigation';
|
|
86
85
|
|
|
87
|
-
|
|
88
|
-
let { stores, page, constructors, components = [], form, ${use_boundaries ? 'errors = [], error, ' : ''}${levels
|
|
86
|
+
let { page, constructors, components = [], form, ${use_boundaries ? 'errors = [], error, ' : ''}${levels
|
|
89
87
|
.map((l) => `data_${l} = null`)
|
|
90
88
|
.join(', ')} } = $props();
|
|
91
89
|
${use_boundaries ? `let data = $derived({${levels.map((l) => `'${l}': data_${l}`).join(', ')}})` : ''}
|
|
92
90
|
|
|
93
|
-
if (browser) {
|
|
94
|
-
$effect.pre(() => stores.page.set(page));
|
|
95
|
-
} else {
|
|
96
|
-
// svelte-ignore state_referenced_locally
|
|
97
|
-
setContext('__svelte__', stores);
|
|
98
|
-
// svelte-ignore state_referenced_locally
|
|
99
|
-
stores.page.set(page);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
$effect(() => {
|
|
103
|
-
stores;page;constructors;components;form;${use_boundaries ? 'errors;error;' : ''}${levels.map((l) => `data_${l}`).join(';')};
|
|
104
|
-
stores.page.notify();
|
|
105
|
-
});
|
|
106
|
-
|
|
107
91
|
let mounted = $state(false);
|
|
108
92
|
let navigated = $state(false);
|
|
109
93
|
let title = $state(null);
|
|
110
94
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
mounted = true;
|
|
122
|
-
return unsubscribe;
|
|
95
|
+
afterNavigate(() => {
|
|
96
|
+
if (mounted) {
|
|
97
|
+
navigated = true;
|
|
98
|
+
title = document.title || 'untitled page';
|
|
99
|
+
} else {
|
|
100
|
+
mounted = true;
|
|
101
|
+
}
|
|
123
102
|
});
|
|
124
103
|
|
|
125
104
|
const Pyramid_${max_depth} = $derived(constructors[${max_depth}]);
|
|
@@ -32,7 +32,6 @@ import error from '../shared/error-template.js';
|
|
|
32
32
|
|
|
33
33
|
export const options = {
|
|
34
34
|
app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')},
|
|
35
|
-
async: ${s(!!config.compilerOptions?.experimental?.async)},
|
|
36
35
|
csp: ${s(config.kit.csp)},
|
|
37
36
|
csrf_check_origin: ${s(!config.kit.csrf.trustedOrigins.includes('*'))},
|
|
38
37
|
csrf_trusted_origins: ${s(config.kit.csrf.trustedOrigins)},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import MagicString from 'magic-string';
|
|
4
|
-
import { rimraf, walk } from '../../../utils/filesystem.js';
|
|
4
|
+
import { rimraf, walk, resolve_entry } from '../../../utils/filesystem.js';
|
|
5
5
|
import { compact } from '../../../utils/array.js';
|
|
6
6
|
import { posixify } from '../../../utils/os.js';
|
|
7
7
|
import { ts } from '../ts.js';
|
|
@@ -198,11 +198,6 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
|
|
|
198
198
|
// Makes sure a type is "repackaged" and therefore more readable
|
|
199
199
|
declarations.push('type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;');
|
|
200
200
|
|
|
201
|
-
// returns the predicate of a matcher's type guard - or string if there is no type guard
|
|
202
|
-
declarations.push(
|
|
203
|
-
'type MatcherParam<M> = M extends (param : string) => param is (infer U extends string) ? U : string;'
|
|
204
|
-
);
|
|
205
|
-
|
|
206
201
|
declarations.push(
|
|
207
202
|
'type RouteParams = ' + generate_params_type(route.params, outdir, config) + ';'
|
|
208
203
|
);
|
|
@@ -604,16 +599,22 @@ function replace_ext_with_js(file_path) {
|
|
|
604
599
|
* @param {import('types').ValidatedConfig} config
|
|
605
600
|
*/
|
|
606
601
|
function generate_params_type(params, outdir, config) {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
602
|
+
const path_to_params = () => {
|
|
603
|
+
const params_file =
|
|
604
|
+
resolve_entry(config.kit.files.params) ??
|
|
605
|
+
config.kit.files.params.replace(/\.(js|ts)$/, '') + '.js';
|
|
606
|
+
|
|
607
|
+
return posixify(path.relative(outdir, params_file));
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
const params_import = path_to_params();
|
|
610
611
|
|
|
611
612
|
return `{ ${params
|
|
612
613
|
.map(
|
|
613
614
|
(param) =>
|
|
614
615
|
`${param.name}${param.optional ? '?' : ''}: ${
|
|
615
616
|
param.matcher
|
|
616
|
-
? `MatcherParam<typeof import('${
|
|
617
|
+
? `import('@sveltejs/kit').MatcherParam<(typeof import('${params_import}').params)[${JSON.stringify(param.matcher)}]>`
|
|
617
618
|
: 'string'
|
|
618
619
|
}${param.optional ? ' | undefined' : ''}`
|
|
619
620
|
)
|
package/src/exports/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/** @import { StandardSchemaV1 } from '@standard-schema/spec' */
|
|
2
|
-
|
|
3
|
-
import { HttpError, Redirect, ActionFailure, ValidationError } from './internal/index.js';
|
|
2
|
+
import { HttpError, Redirect, ActionFailure, ValidationError } from './internal/shared.js';
|
|
4
3
|
import { BROWSER, DEV } from 'esm-env';
|
|
5
4
|
import {
|
|
6
5
|
add_data_suffix,
|
|
@@ -11,9 +10,10 @@ import {
|
|
|
11
10
|
strip_resolution_suffix
|
|
12
11
|
} from '../runtime/pathname.js';
|
|
13
12
|
import { text_encoder } from '../runtime/utils.js';
|
|
14
|
-
import { validate_redirect_location } from '
|
|
13
|
+
import { validate_redirect_location } from './url.js';
|
|
15
14
|
|
|
16
15
|
export { VERSION } from '../version.js';
|
|
16
|
+
export { defineParams } from './params.js';
|
|
17
17
|
|
|
18
18
|
// Keep the status codes as `number` because restricting to certain numbers makes it unnecessarily hard to use compared to the benefits
|
|
19
19
|
// (we have runtime errors already to check for invalid codes). Also see https://github.com/sveltejs/kit/issues/11780
|
|
@@ -1,91 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export class HttpError {
|
|
4
|
-
/**
|
|
5
|
-
* @param {number} status
|
|
6
|
-
* @param {Omit<App.Error, 'status'> | string | undefined} body
|
|
7
|
-
* @param {Omit<App.Error, 'status' | 'message'>} [properties]
|
|
8
|
-
*/
|
|
9
|
-
constructor(status, body, properties) {
|
|
10
|
-
this.status = status;
|
|
11
|
-
if (typeof body === 'string') {
|
|
12
|
-
this.body = { ...properties, message: body, status };
|
|
13
|
-
} else if (body) {
|
|
14
|
-
this.body = { ...body, status };
|
|
15
|
-
} else {
|
|
16
|
-
this.body = { message: `Error: ${status}`, status };
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
toString() {
|
|
21
|
-
return JSON.stringify(this.body);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export class Redirect {
|
|
26
|
-
/**
|
|
27
|
-
* @param {300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308} status
|
|
28
|
-
* @param {string} location
|
|
29
|
-
*/
|
|
30
|
-
constructor(status, location) {
|
|
31
|
-
try {
|
|
32
|
-
new Headers({ location });
|
|
33
|
-
} catch {
|
|
34
|
-
throw new Error(
|
|
35
|
-
`Invalid redirect location ${JSON.stringify(location)}: ` +
|
|
36
|
-
'this string contains characters that cannot be used in HTTP headers'
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
this.status = status;
|
|
41
|
-
this.location = location;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* An error that was thrown from within the SvelteKit runtime that is not fatal and doesn't result in a 500, such as a 404.
|
|
47
|
-
* `SvelteKitError` goes through `handleError`.
|
|
48
|
-
* @extends Error
|
|
49
|
-
*/
|
|
50
|
-
export class SvelteKitError extends Error {
|
|
51
|
-
/**
|
|
52
|
-
* @param {number} status
|
|
53
|
-
* @param {string} text
|
|
54
|
-
* @param {string} message
|
|
55
|
-
*/
|
|
56
|
-
constructor(status, text, message) {
|
|
57
|
-
super(message);
|
|
58
|
-
this.status = status;
|
|
59
|
-
this.text = text;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @template [T=undefined]
|
|
65
|
-
*/
|
|
66
|
-
export class ActionFailure {
|
|
67
|
-
/**
|
|
68
|
-
* @param {number} status
|
|
69
|
-
* @param {T} data
|
|
70
|
-
*/
|
|
71
|
-
constructor(status, data) {
|
|
72
|
-
this.status = status;
|
|
73
|
-
this.data = data;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Error thrown when form validation fails imperatively
|
|
79
|
-
*/
|
|
80
|
-
export class ValidationError extends Error {
|
|
81
|
-
/**
|
|
82
|
-
* @param {StandardSchemaV1.Issue[]} issues
|
|
83
|
-
*/
|
|
84
|
-
constructor(issues) {
|
|
85
|
-
super('Validation failed');
|
|
86
|
-
this.name = 'ValidationError';
|
|
87
|
-
this.issues = issues;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export { init_remote_functions } from './remote-functions.js';
|
|
1
|
+
export * from '#internal';
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/** @import { RequestEvent } from '@sveltejs/kit' */
|
|
2
2
|
/** @import { RequestStore } from 'types' */
|
|
3
3
|
/** @import { AsyncLocalStorage } from 'node:async_hooks' */
|
|
4
|
-
|
|
5
|
-
import { IN_WEBCONTAINER } from '../../runtime/server/constants.js';
|
|
4
|
+
import { IN_WEBCONTAINER } from '../../../runtime/server/constants.js';
|
|
6
5
|
|
|
7
6
|
/** @type {RequestStore | null} */
|
|
8
7
|
let sync_store = null;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** @import { Span } from '@opentelemetry/api' */
|
|
2
|
+
import { try_get_request_store } from './event.js';
|
|
3
|
+
|
|
4
|
+
export function get_origin() {
|
|
5
|
+
return try_get_request_store()?.event.url.origin;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @template {{ tracing: { enabled: boolean, root: Span, current: Span } }} T
|
|
10
|
+
* @param {T} event_like
|
|
11
|
+
* @param {Span} current
|
|
12
|
+
* @returns {T}
|
|
13
|
+
*/
|
|
14
|
+
export function merge_tracing(event_like, current) {
|
|
15
|
+
return {
|
|
16
|
+
...event_like,
|
|
17
|
+
tracing: {
|
|
18
|
+
...event_like.tracing,
|
|
19
|
+
current
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export {
|
|
25
|
+
with_request_store,
|
|
26
|
+
getRequestEvent,
|
|
27
|
+
get_request_store,
|
|
28
|
+
try_get_request_store
|
|
29
|
+
} from './event.js';
|
|
30
|
+
|
|
31
|
+
export { init_remote_functions } from './remote-functions.js';
|
|
32
|
+
|
|
33
|
+
export * from '../shared.js';
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/** @import { StandardSchemaV1 } from '@standard-schema/spec' */
|
|
2
|
+
|
|
3
|
+
export class HttpError {
|
|
4
|
+
/**
|
|
5
|
+
* @param {number} status
|
|
6
|
+
* @param {Omit<App.Error, 'status'> | string | undefined} body
|
|
7
|
+
* @param {Omit<App.Error, 'status' | 'message'>} [properties]
|
|
8
|
+
*/
|
|
9
|
+
constructor(status, body, properties) {
|
|
10
|
+
this.status = status;
|
|
11
|
+
if (typeof body === 'string') {
|
|
12
|
+
this.body = { ...properties, message: body, status };
|
|
13
|
+
} else if (body) {
|
|
14
|
+
this.body = { ...body, status };
|
|
15
|
+
} else {
|
|
16
|
+
this.body = { message: `Error: ${status}`, status };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
toString() {
|
|
21
|
+
return JSON.stringify(this.body);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class Redirect {
|
|
26
|
+
/**
|
|
27
|
+
* @param {300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308} status
|
|
28
|
+
* @param {string} location
|
|
29
|
+
*/
|
|
30
|
+
constructor(status, location) {
|
|
31
|
+
try {
|
|
32
|
+
new Headers({ location });
|
|
33
|
+
} catch {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`Invalid redirect location ${JSON.stringify(location)}: ` +
|
|
36
|
+
'this string contains characters that cannot be used in HTTP headers'
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.status = status;
|
|
41
|
+
this.location = location;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* An error that was thrown from within the SvelteKit runtime that is not fatal and doesn't result in a 500, such as a 404.
|
|
47
|
+
* `SvelteKitError` goes through `handleError`.
|
|
48
|
+
* @extends Error
|
|
49
|
+
*/
|
|
50
|
+
export class SvelteKitError extends Error {
|
|
51
|
+
/**
|
|
52
|
+
* @param {number} status
|
|
53
|
+
* @param {string} text
|
|
54
|
+
* @param {string} message
|
|
55
|
+
*/
|
|
56
|
+
constructor(status, text, message) {
|
|
57
|
+
super(message);
|
|
58
|
+
this.status = status;
|
|
59
|
+
this.text = text;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @template [T=undefined]
|
|
65
|
+
*/
|
|
66
|
+
export class ActionFailure {
|
|
67
|
+
/**
|
|
68
|
+
* @param {number} status
|
|
69
|
+
* @param {T} data
|
|
70
|
+
*/
|
|
71
|
+
constructor(status, data) {
|
|
72
|
+
this.status = status;
|
|
73
|
+
this.data = data;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Error thrown when form validation fails imperatively
|
|
79
|
+
*/
|
|
80
|
+
export class ValidationError extends Error {
|
|
81
|
+
/**
|
|
82
|
+
* @param {StandardSchemaV1.Issue[]} issues
|
|
83
|
+
*/
|
|
84
|
+
constructor(issues) {
|
|
85
|
+
super('Validation failed');
|
|
86
|
+
this.name = 'ValidationError';
|
|
87
|
+
this.issues = issues;
|
|
88
|
+
}
|
|
89
|
+
}
|