@sveltejs/kit 3.0.0-next.6 → 3.0.0-next.8
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 +8 -3
- 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 +86 -1
- package/src/core/generate_manifest/index.js +12 -15
- package/src/core/sync/create_manifest_data/index.js +7 -45
- package/src/core/sync/sync.js +0 -2
- package/src/core/sync/write_client_manifest.js +7 -21
- package/src/core/sync/write_non_ambient.js +12 -9
- package/src/core/sync/write_server.js +0 -4
- package/src/core/sync/write_types/index.js +28 -24
- package/src/core/utils.js +2 -2
- 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 +5 -9
- package/src/exports/params.js +63 -0
- package/src/exports/public.d.ts +103 -46
- package/src/exports/url.js +84 -0
- package/src/exports/vite/dev/index.js +31 -20
- package/src/exports/vite/index.js +280 -199
- package/src/exports/vite/preview/index.js +14 -15
- package/src/exports/vite/utils.js +8 -10
- package/src/runtime/app/env/internal.js +4 -4
- package/src/runtime/app/forms.js +2 -2
- package/src/runtime/app/paths/client.js +3 -7
- package/src/runtime/app/paths/internal/client.js +4 -2
- package/src/runtime/app/paths/internal/server.js +2 -23
- package/src/runtime/app/paths/server.js +3 -3
- 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/bundle.js +1 -1
- package/src/runtime/client/client-entry.js +3 -0
- package/src/runtime/client/client.js +230 -238
- package/src/runtime/client/entry.js +24 -3
- package/src/runtime/client/payload.js +17 -0
- package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
- package/src/runtime/client/remote-functions/form.svelte.js +11 -30
- 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 +3 -7
- package/src/runtime/client/utils.js +0 -96
- package/src/runtime/components/root.svelte +66 -0
- package/src/runtime/form-utils.js +16 -6
- package/src/runtime/server/cookie.js +17 -7
- package/src/runtime/server/index.js +1 -1
- package/src/runtime/server/page/index.js +7 -14
- package/src/runtime/server/page/load_data.js +1 -1
- package/src/runtime/server/page/render.js +72 -88
- package/src/runtime/server/page/server_routing.js +13 -9
- package/src/runtime/server/remote.js +23 -13
- package/src/runtime/server/respond.js +11 -8
- package/src/runtime/server/utils.js +28 -5
- package/src/runtime/telemetry/otel.js +1 -1
- package/src/runtime/types.d.ts +8 -0
- package/src/types/ambient.d.ts +5 -1
- package/src/types/global-private.d.ts +11 -18
- package/src/types/internal.d.ts +25 -30
- package/src/utils/error.js +1 -1
- package/src/utils/import.js +6 -1
- package/src/utils/mime.js +9 -0
- package/src/utils/params.js +66 -0
- package/src/utils/routing.js +90 -44
- 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 +127 -125
- package/types/index.d.ts.map +12 -8
- package/src/core/sync/write_root.js +0 -148
- 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
|
@@ -38,6 +38,7 @@ export async function load_explicit_env(kit, file, root, mode) {
|
|
|
38
38
|
logLevel: 'silent',
|
|
39
39
|
mode,
|
|
40
40
|
define: {
|
|
41
|
+
__SVELTEKIT_PAYLOAD__: 'undefined', // coming in through static import in env/internal.js but will end up unused
|
|
41
42
|
__SVELTEKIT_APP_VERSION__: JSON.stringify(kit.version.name) // needed by $app/env
|
|
42
43
|
},
|
|
43
44
|
resolve: {
|
|
@@ -94,8 +95,9 @@ export async function load_explicit_env(kit, file, root, mode) {
|
|
|
94
95
|
* @param {Record<string, EnvVarConfig<any> | undefined> | null} variables
|
|
95
96
|
* @param {Record<string, string>} env
|
|
96
97
|
* @param {string | null} entry
|
|
98
|
+
* @param {boolean} is_dev
|
|
97
99
|
*/
|
|
98
|
-
export function create_sveltekit_env(variables, env, entry) {
|
|
100
|
+
export function create_sveltekit_env(variables, env, entry, is_dev) {
|
|
99
101
|
const imports = entry
|
|
100
102
|
? [
|
|
101
103
|
`import { variables } from ${JSON.stringify(entry)};`,
|
|
@@ -149,6 +151,19 @@ export function create_sveltekit_env(variables, env, entry) {
|
|
|
149
151
|
}`
|
|
150
152
|
];
|
|
151
153
|
|
|
154
|
+
// In dev, initialise the env immediately. Tools like `vite-node` load modules
|
|
155
|
+
// through the Vite config but don't run the SvelteKit dev server, which is what
|
|
156
|
+
// normally calls `set_env`. Without this, dynamic env vars imported from
|
|
157
|
+
// `$app/env/public` and `$app/env/private` would be `undefined` in such contexts.
|
|
158
|
+
if (is_dev) {
|
|
159
|
+
/** @type {Record<string, string>} */
|
|
160
|
+
const dev_env = {};
|
|
161
|
+
for (const name of Object.keys(variables ?? {})) {
|
|
162
|
+
if (name in env) dev_env[name] = env[name];
|
|
163
|
+
}
|
|
164
|
+
blocks.push(`set_env(${devalue.uneval(dev_env)});`);
|
|
165
|
+
}
|
|
166
|
+
|
|
152
167
|
const module = blocks.join('\n\n');
|
|
153
168
|
|
|
154
169
|
return module;
|
|
@@ -361,3 +376,73 @@ export const reserved = new Set([
|
|
|
361
376
|
]);
|
|
362
377
|
|
|
363
378
|
export const valid_identifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Generates `export const` declarations (and, for reserved-word names that need
|
|
382
|
+
* aliasing, `const` + re-export specifiers) for a set of named exports.
|
|
383
|
+
*
|
|
384
|
+
* For regular names, emits a single efficient `export const name = expr;` statement.
|
|
385
|
+
* For reserved-word names (e.g. `delete`, `class`), emits `const alias = expr;` plus
|
|
386
|
+
* a re-export specifier (`alias as name`), since reserved words can't be `const`
|
|
387
|
+
* binding names but CAN appear in export specifiers.
|
|
388
|
+
*
|
|
389
|
+
* You can do evil things like `export { c as class }`. In order to import/re-export
|
|
390
|
+
* these, you need to alias the binding, then un-alias it when re-exporting:
|
|
391
|
+
*
|
|
392
|
+
* const _0 = ...; // safe binding name
|
|
393
|
+
* export { _0 as class }; // valid — `class` is allowed in export specifiers
|
|
394
|
+
*
|
|
395
|
+
* Aliases are chosen to avoid collisions with any of the supplied names. The
|
|
396
|
+
* namespace binding (used to hold the imported module) is likewise chosen to
|
|
397
|
+
* avoid collisions.
|
|
398
|
+
*
|
|
399
|
+
* @param {Iterable<string>} names — the export names
|
|
400
|
+
* @param {(name: string, namespace: string) => string} build_expression —
|
|
401
|
+
* called for each name to produce the right-hand side of the declaration;
|
|
402
|
+
* receives the chosen namespace binding so it can reference the imported module
|
|
403
|
+
* @param {string} namespace_prefix — the preferred binding name for the namespace
|
|
404
|
+
* (suffixed with a number if it collides with any export name)
|
|
405
|
+
* @returns {{ namespace: string, declarations: string[], reexports: string[] }}
|
|
406
|
+
*/
|
|
407
|
+
export function create_exported_declarations(names, build_expression, namespace_prefix) {
|
|
408
|
+
/** @type {Set<string>} */
|
|
409
|
+
const set = new Set(names);
|
|
410
|
+
|
|
411
|
+
let namespace = namespace_prefix;
|
|
412
|
+
let namespace_index = 0;
|
|
413
|
+
while (set.has(namespace)) {
|
|
414
|
+
namespace = `${namespace_prefix}${namespace_index++}`;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
let alias_index = 0;
|
|
418
|
+
/** @type {Map<string, string>} */
|
|
419
|
+
const aliases = new Map();
|
|
420
|
+
|
|
421
|
+
for (const name of set) {
|
|
422
|
+
if (!reserved.has(name)) continue;
|
|
423
|
+
|
|
424
|
+
let alias = `_${alias_index++}`;
|
|
425
|
+
while (set.has(alias)) {
|
|
426
|
+
alias = `_${alias_index++}`;
|
|
427
|
+
}
|
|
428
|
+
aliases.set(name, alias);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/** @type {string[]} */
|
|
432
|
+
const declarations = [];
|
|
433
|
+
/** @type {string[]} */
|
|
434
|
+
const reexports = [];
|
|
435
|
+
|
|
436
|
+
for (const name of set) {
|
|
437
|
+
const alias = aliases.get(name);
|
|
438
|
+
const expr = build_expression(name, namespace);
|
|
439
|
+
if (alias) {
|
|
440
|
+
declarations.push(`const ${alias} = ${expr};`);
|
|
441
|
+
reexports.push(`${alias} as ${name}`);
|
|
442
|
+
} else {
|
|
443
|
+
declarations.push(`export const ${name} = ${expr};`);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return { namespace, declarations, reexports };
|
|
448
|
+
}
|
|
@@ -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
|
/**
|
|
@@ -180,7 +142,7 @@ function create_routes_and_nodes(cwd, config, fallback) {
|
|
|
180
142
|
throw new Error(`Route ${id} should be renamed to ${id.replace(/#/g, '[x+23]')}`);
|
|
181
143
|
}
|
|
182
144
|
|
|
183
|
-
if (/\[
|
|
145
|
+
if (/\[\.\.\.[\w-]+\]\/\[\[/.test(id)) {
|
|
184
146
|
throw new Error(
|
|
185
147
|
`Invalid route ${id} — an [[optional]] route segment cannot follow a [...rest] route segment`
|
|
186
148
|
);
|
package/src/core/sync/sync.js
CHANGED
|
@@ -2,7 +2,6 @@ import path from 'node:path';
|
|
|
2
2
|
import process from 'node:process';
|
|
3
3
|
import create_manifest_data from './create_manifest_data/index.js';
|
|
4
4
|
import { write_client_manifest } from './write_client_manifest.js';
|
|
5
|
-
import { write_root } from './write_root.js';
|
|
6
5
|
import { write_tsconfig } from './write_tsconfig.js';
|
|
7
6
|
import { write_types, write_all_types } from './write_types/index.js';
|
|
8
7
|
import { write_ambient } from './write_ambient.js';
|
|
@@ -37,7 +36,6 @@ export function create(config, root) {
|
|
|
37
36
|
|
|
38
37
|
write_client_manifest(config.kit, manifest_data, `${output}/client`);
|
|
39
38
|
write_server(config, output, root);
|
|
40
|
-
write_root(manifest_data, config, output);
|
|
41
39
|
write_all_types(config, manifest_data, root);
|
|
42
40
|
write_non_ambient(config.kit, manifest_data);
|
|
43
41
|
|
|
@@ -139,11 +139,6 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
|
|
|
139
139
|
write_if_changed(
|
|
140
140
|
`${output}/app.js`,
|
|
141
141
|
dedent`
|
|
142
|
-
// in dev, this makes Vite inject its client as this module's first dependency,
|
|
143
|
-
// so that global constant replacements are installed before any other module
|
|
144
|
-
// (including user hooks) evaluates. In build it's inert.
|
|
145
|
-
import.meta.hot;
|
|
146
|
-
|
|
147
142
|
${
|
|
148
143
|
client_hooks_file
|
|
149
144
|
? `import * as client_hooks from '${relative_path(output, client_hooks_file)}';`
|
|
@@ -181,28 +176,19 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
|
|
|
181
176
|
|
|
182
177
|
export const decode = (type, value) => decoders[type](value);
|
|
183
178
|
|
|
184
|
-
export { default as root } from '../root.js';
|
|
185
|
-
|
|
186
179
|
export const get_error_template = () => import('../shared/error-template.js').then(m => m.default);
|
|
187
180
|
`
|
|
188
181
|
);
|
|
189
182
|
|
|
190
183
|
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
|
-
}
|
|
184
|
+
const uses_matchers = manifest_data.routes.some((route) =>
|
|
185
|
+
route.params.some((param) => param.matcher)
|
|
186
|
+
);
|
|
202
187
|
|
|
203
|
-
const module =
|
|
204
|
-
|
|
205
|
-
|
|
188
|
+
const module =
|
|
189
|
+
!manifest_data.params || !uses_matchers
|
|
190
|
+
? 'export const matchers = {};'
|
|
191
|
+
: `import { params as matchers } from ${s(relative_path(output, manifest_data.params))};\n\nexport { matchers };`;
|
|
206
192
|
|
|
207
193
|
write_if_changed(`${output}/matchers.js`, module);
|
|
208
194
|
}
|
|
@@ -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
|
|
|
@@ -204,7 +209,7 @@ function generate_app_types(manifest_data, config) {
|
|
|
204
209
|
if (route.params.length > 0) {
|
|
205
210
|
const params = route.params.map((p) => {
|
|
206
211
|
const type = get_matcher_type(p.matcher);
|
|
207
|
-
return `${p.name}${p.optional ? '?:' : ':'} ${type}${p.optional ? ' | undefined' : ''}`;
|
|
212
|
+
return `${/^\w+$/.test(p.name) ? p.name : `'${p.name}'`}${p.optional ? '?:' : ':'} ${type}${p.optional ? ' | undefined' : ''}`;
|
|
208
213
|
});
|
|
209
214
|
const route_type = `${s(route.id)}: { ${params.join('; ')} }`;
|
|
210
215
|
|
|
@@ -225,7 +230,7 @@ function generate_app_types(manifest_data, config) {
|
|
|
225
230
|
const params = Array.from(layout_params)
|
|
226
231
|
.map(([name, { optional, matchers }]) => {
|
|
227
232
|
const type = get_matchers_type(matchers);
|
|
228
|
-
return `${name}${optional ? '?:' : ':'} ${type}${optional ? ' | undefined' : ''}`;
|
|
233
|
+
return `${/^\w+$/.test(name) ? name : `'${name}'`}${optional ? '?:' : ':'} ${type}${optional ? ' | undefined' : ''}`;
|
|
229
234
|
})
|
|
230
235
|
.join('; ');
|
|
231
236
|
|
|
@@ -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};`,
|
|
@@ -24,7 +24,6 @@ const server_template = ({
|
|
|
24
24
|
has_service_worker,
|
|
25
25
|
template
|
|
26
26
|
}) => `
|
|
27
|
-
import root from '../root.js';
|
|
28
27
|
import { set_building, set_prerendering } from '$app/env/internal';
|
|
29
28
|
import { set_assets } from '$app/paths/internal/server';
|
|
30
29
|
import { set_manifest, set_read_implementation } from '__sveltekit/server';
|
|
@@ -32,7 +31,6 @@ import error from '../shared/error-template.js';
|
|
|
32
31
|
|
|
33
32
|
export const options = {
|
|
34
33
|
app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')},
|
|
35
|
-
async: ${s(!!config.compilerOptions?.experimental?.async)},
|
|
36
34
|
csp: ${s(config.kit.csp)},
|
|
37
35
|
csrf_check_origin: ${s(!config.kit.csrf.trustedOrigins.includes('*'))},
|
|
38
36
|
csrf_trusted_origins: ${s(config.kit.csrf.trustedOrigins)},
|
|
@@ -41,10 +39,8 @@ export const options = {
|
|
|
41
39
|
hooks: null, // added lazily, via \`get_hooks\`
|
|
42
40
|
link_header_preload: ${s(config.kit.output.linkHeaderPreload)},
|
|
43
41
|
paths_origin: ${s(config.kit.paths.origin)},
|
|
44
|
-
root,
|
|
45
42
|
service_worker: ${has_service_worker},
|
|
46
43
|
service_worker_options: ${config.kit.serviceWorker.register ? s(config.kit.serviceWorker.options) : 'null'},
|
|
47
|
-
server_error_boundaries: ${s(!!config.kit.experimental.handleRenderingErrors)},
|
|
48
44
|
templates: {
|
|
49
45
|
app: ({ head, body, assets, nonce, env }) => ${s(template)
|
|
50
46
|
.replace('%sveltekit.head%', '" + head + "')
|
|
@@ -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
|
);
|
|
@@ -236,7 +231,9 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
|
|
|
236
231
|
'type OptionalUnion<U extends Record<string, any>, A extends keyof U = U extends U ? keyof U : never> = U extends unknown ? { [P in Exclude<A, keyof U>]?: never } & U : never;',
|
|
237
232
|
|
|
238
233
|
// Re-export `Snapshot` from @sveltejs/kit — in future we could use this to infer <T> from the return type of `snapshot.capture`
|
|
239
|
-
'export type Snapshot<T = any> = Kit.Snapshot<T>;'
|
|
234
|
+
'export type Snapshot<T = any> = Kit.Snapshot<T>;',
|
|
235
|
+
|
|
236
|
+
'export type ErrorProps = { error: App.Error };'
|
|
240
237
|
);
|
|
241
238
|
}
|
|
242
239
|
|
|
@@ -268,15 +265,8 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
|
|
|
268
265
|
|
|
269
266
|
if (route.leaf.server) {
|
|
270
267
|
exports.push(
|
|
271
|
-
'export type Action<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Action<RouteParams, OutputData, RouteId>'
|
|
272
|
-
|
|
273
|
-
exports.push(
|
|
274
|
-
'export type Actions<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Actions<RouteParams, OutputData, RouteId>'
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (route.leaf.server) {
|
|
279
|
-
exports.push(
|
|
268
|
+
'export type Action<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Action<RouteParams, OutputData, RouteId>',
|
|
269
|
+
'export type Actions<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Actions<RouteParams, OutputData, RouteId>',
|
|
280
270
|
'export type PageProps = { params: RouteParams; data: PageData; form: ActionData }'
|
|
281
271
|
);
|
|
282
272
|
} else {
|
|
@@ -604,16 +594,22 @@ function replace_ext_with_js(file_path) {
|
|
|
604
594
|
* @param {import('types').ValidatedConfig} config
|
|
605
595
|
*/
|
|
606
596
|
function generate_params_type(params, outdir, config) {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
597
|
+
const path_to_params = () => {
|
|
598
|
+
const params_file =
|
|
599
|
+
resolve_entry(config.kit.files.params) ??
|
|
600
|
+
config.kit.files.params.replace(/\.(js|ts)$/, '') + '.js';
|
|
601
|
+
|
|
602
|
+
return posixify(path.relative(outdir, params_file));
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
const params_import = path_to_params();
|
|
610
606
|
|
|
611
607
|
return `{ ${params
|
|
612
608
|
.map(
|
|
613
609
|
(param) =>
|
|
614
|
-
`${param.name}${param.optional ? '?' : ''}: ${
|
|
610
|
+
`${/^\w+$/.test(param.name) ? param.name : `'${param.name}'`}${param.optional ? '?' : ''}: ${
|
|
615
611
|
param.matcher
|
|
616
|
-
? `MatcherParam<typeof import('${
|
|
612
|
+
? `import('@sveltejs/kit').MatcherParam<(typeof import('${params_import}').params)[${JSON.stringify(param.matcher)}]>`
|
|
617
613
|
: 'string'
|
|
618
614
|
}${param.optional ? ' | undefined' : ''}`
|
|
619
615
|
)
|
|
@@ -642,6 +638,16 @@ export function tweak_types(content, is_server) {
|
|
|
642
638
|
const code = new MagicString(content);
|
|
643
639
|
|
|
644
640
|
const exports = new Map();
|
|
641
|
+
/** @param {import('typescript').BindingName} name */
|
|
642
|
+
function add_export(name) {
|
|
643
|
+
if (ts.isIdentifier(name)) {
|
|
644
|
+
if (names.has(name.text)) exports.set(name.text, name.text);
|
|
645
|
+
} else {
|
|
646
|
+
for (const element of name.elements) {
|
|
647
|
+
if (ts.isBindingElement(element)) add_export(element.name);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
645
651
|
|
|
646
652
|
ast.forEachChild((node) => {
|
|
647
653
|
if (
|
|
@@ -668,9 +674,7 @@ export function tweak_types(content, is_server) {
|
|
|
668
674
|
|
|
669
675
|
if (ts.isVariableStatement(node)) {
|
|
670
676
|
node.declarationList.declarations.forEach((declaration) => {
|
|
671
|
-
|
|
672
|
-
exports.set(declaration.name.text, declaration.name.text);
|
|
673
|
-
}
|
|
677
|
+
add_export(declaration.name);
|
|
674
678
|
});
|
|
675
679
|
}
|
|
676
680
|
}
|
package/src/core/utils.js
CHANGED
|
@@ -7,7 +7,7 @@ import { noop } from '../utils/functions.js';
|
|
|
7
7
|
import { posixify } from '../utils/os.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Resolved path of the `runtime` directory
|
|
10
|
+
* Resolved path of the `runtime` directory posix-ified
|
|
11
11
|
*
|
|
12
12
|
* TODO Windows issue:
|
|
13
13
|
* Vite or sth else somehow sets the driver letter inconsistently to lower or upper case depending on the run environment.
|
|
@@ -25,7 +25,7 @@ export const runtime_directory = posixify(fileURLToPath(new URL('../runtime', im
|
|
|
25
25
|
*/
|
|
26
26
|
export function get_runtime_base(root) {
|
|
27
27
|
return runtime_directory.startsWith(root)
|
|
28
|
-
? `/${path.relative(root, runtime_directory)}`
|
|
28
|
+
? `/${posixify(path.relative(root, runtime_directory))}`
|
|
29
29
|
: to_fs(runtime_directory);
|
|
30
30
|
}
|
|
31
31
|
|
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;
|