@sveltejs/kit 3.0.0-next.2 → 3.0.0-next.21
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 +62 -36
- package/src/cli.js +15 -12
- package/src/constants.js +6 -1
- package/src/core/adapt/builder.js +66 -72
- package/src/core/adapt/index.js +17 -6
- package/src/core/config/index.js +134 -80
- package/src/core/config/options.js +295 -273
- package/src/core/config/types.d.ts +1 -1
- package/src/core/env.js +146 -16
- package/src/core/generate_manifest/index.js +18 -15
- package/src/core/postbuild/analyse.js +8 -20
- package/src/core/postbuild/crawl.js +22 -6
- package/src/core/postbuild/entities.js +8 -2
- package/src/core/postbuild/fallback.js +4 -2
- package/src/core/postbuild/prerender.js +222 -70
- package/src/core/postbuild/queue.js +2 -1
- package/src/core/sync/create_manifest_data/conflict.js +1 -1
- package/src/core/sync/create_manifest_data/index.js +82 -62
- package/src/core/sync/sync.js +40 -31
- package/src/core/sync/ts.js +1 -1
- package/src/core/sync/utils.js +22 -2
- package/src/core/sync/{write_non_ambient.js → write_app_types.js} +107 -58
- package/src/core/sync/write_client_manifest.js +14 -29
- package/src/core/sync/write_env.js +7 -5
- package/src/core/sync/write_server.js +37 -45
- package/src/core/sync/write_tsconfig/index.js +274 -0
- package/src/core/sync/write_tsconfig/test-app/package.json +7 -0
- package/src/core/sync/write_tsconfig/utils.js +77 -0
- package/src/core/sync/write_tsconfig/validate.js +128 -0
- package/src/core/sync/write_types/index.js +127 -123
- package/src/core/utils.js +30 -5
- package/src/exports/env/index.js +77 -0
- package/src/exports/env/public.d.ts +55 -0
- package/src/exports/hooks/index.js +3 -9
- package/src/exports/hooks/public.d.ts +195 -0
- package/src/exports/hooks/sequence.js +9 -6
- package/src/exports/index.js +52 -29
- package/src/exports/internal/client.js +5 -0
- package/src/exports/internal/env.js +8 -5
- package/src/exports/internal/index.js +1 -90
- package/src/exports/internal/{event.js → server/event.js} +2 -3
- package/src/exports/internal/server/index.js +37 -0
- package/src/exports/internal/server/telemetry.js +95 -0
- package/src/exports/internal/shared.js +90 -0
- package/src/exports/node/index.js +64 -22
- package/src/exports/params/index.js +70 -0
- package/src/exports/params/public.d.ts +63 -0
- package/src/exports/public.d.ts +50 -1733
- package/src/exports/remote/index.js +11 -0
- package/src/exports/remote/public.d.ts +519 -0
- package/src/exports/url.js +86 -0
- package/src/exports/vite/build/build_server.js +54 -65
- package/src/exports/vite/build/remote.js +24 -19
- package/src/exports/vite/build/utils.js +0 -8
- package/src/exports/vite/dev/index.js +218 -146
- package/src/exports/vite/index.js +1590 -858
- package/src/exports/vite/module_ids.js +2 -2
- package/src/exports/vite/preview/index.js +40 -32
- package/src/exports/vite/public.d.ts +588 -0
- package/src/exports/vite/utils.js +84 -46
- package/src/pathname.js +55 -0
- package/src/runner.js +15 -0
- package/src/runtime/app/env/internal.js +4 -4
- package/src/runtime/app/env/types.d.ts +1 -1
- package/src/runtime/app/environment/index.js +3 -3
- package/src/runtime/app/{forms.js → forms/index.js} +73 -42
- package/src/runtime/app/forms/public.d.ts +2 -0
- package/src/runtime/app/forms/types.d.ts +56 -0
- package/src/runtime/app/internal/transport.js +53 -0
- package/src/runtime/app/manifest/index.js +1 -0
- package/src/runtime/app/{navigation.js → navigation/index.js} +2 -1
- package/src/runtime/app/navigation/public.d.ts +237 -0
- package/src/runtime/app/paths/client.js +37 -37
- package/src/runtime/app/paths/index.js +1 -1
- package/src/runtime/app/paths/internal/client.js +34 -2
- package/src/runtime/app/paths/internal/server.js +6 -23
- package/src/runtime/app/paths/internal.d.ts +3 -0
- package/src/runtime/app/paths/public.d.ts +1 -29
- package/src/runtime/app/paths/server.js +36 -17
- package/src/runtime/app/paths/types.d.ts +11 -19
- package/src/runtime/app/server/index.js +2 -2
- package/src/runtime/app/server/public.d.ts +201 -0
- package/src/runtime/app/server/remote/command.js +13 -11
- package/src/runtime/app/server/remote/form.js +61 -39
- package/src/runtime/app/server/remote/prerender.js +45 -45
- package/src/runtime/app/server/remote/query.js +106 -108
- package/src/runtime/app/server/remote/requested.js +27 -19
- package/src/runtime/app/server/remote/shared.js +76 -76
- package/src/runtime/app/service-worker/index.js +24 -0
- package/src/runtime/app/state/client.js +4 -2
- package/src/runtime/app/state/index.js +7 -5
- package/src/runtime/app/state/public.d.ts +72 -0
- package/src/runtime/app/state/server.js +3 -0
- package/src/runtime/app/stores.js +15 -78
- package/src/runtime/client/bundle.js +1 -1
- package/src/runtime/client/client-entry.js +3 -0
- package/src/runtime/client/client.js +1336 -648
- package/src/runtime/client/constants.js +3 -6
- package/src/runtime/client/entry.js +24 -3
- package/src/runtime/client/fetcher.js +25 -25
- package/src/runtime/client/ndjson.js +1 -1
- package/src/runtime/client/parse.js +1 -1
- package/src/runtime/client/payload.js +17 -0
- package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
- package/src/runtime/client/remote-functions/command.svelte.js +37 -61
- package/src/runtime/client/remote-functions/form.svelte.js +267 -178
- package/src/runtime/client/remote-functions/prerender.svelte.js +32 -11
- package/src/runtime/client/remote-functions/query/index.js +10 -17
- package/src/runtime/client/remote-functions/query/instance.svelte.js +64 -18
- package/src/runtime/client/remote-functions/query/proxy.js +5 -5
- package/src/runtime/client/remote-functions/query-batch.svelte.js +61 -70
- package/src/runtime/client/remote-functions/query-live/index.js +1 -1
- package/src/runtime/client/remote-functions/query-live/instance.svelte.js +63 -21
- package/src/runtime/client/remote-functions/query-live/iterator.js +15 -12
- package/src/runtime/client/remote-functions/query-live/proxy.js +2 -12
- package/src/runtime/client/remote-functions/shared.svelte.js +90 -65
- package/src/runtime/client/snapshots.js +147 -0
- package/src/runtime/client/state.svelte.js +94 -55
- package/src/runtime/client/stream.js +3 -2
- package/src/runtime/client/types.d.ts +13 -9
- package/src/runtime/client/utils.js +22 -110
- package/src/runtime/components/root.svelte +56 -0
- package/src/runtime/env/dynamic/private.js +7 -0
- package/src/runtime/env/dynamic/public.js +7 -0
- package/src/runtime/env/static/private.js +6 -0
- package/src/runtime/env/static/public.js +6 -0
- package/src/runtime/form-utils.js +172 -61
- package/src/runtime/pathname.js +20 -32
- package/src/runtime/props.svelte.js +72 -0
- package/src/runtime/server/constants.js +0 -3
- package/src/runtime/server/cookie.js +72 -55
- package/src/runtime/server/csrf.js +65 -0
- package/src/runtime/server/data/index.js +49 -53
- package/src/runtime/server/dev.js +22 -0
- package/src/runtime/server/endpoint.js +6 -7
- package/src/runtime/server/env_module.js +0 -5
- package/src/runtime/server/errors.js +160 -0
- package/src/runtime/server/fetch.js +32 -39
- package/src/runtime/server/index.js +90 -64
- package/src/runtime/server/internal.js +71 -0
- package/src/runtime/server/page/actions.js +85 -64
- package/src/runtime/server/page/crypto.js +2 -2
- package/src/runtime/server/page/csp.js +88 -104
- package/src/runtime/server/page/data_serializer.js +24 -25
- package/src/runtime/server/page/index.js +36 -53
- package/src/runtime/server/page/load_data.js +50 -57
- package/src/runtime/server/page/render.js +173 -239
- package/src/runtime/server/page/respond_with_error.js +17 -31
- package/src/runtime/server/page/serialize_data.js +2 -13
- package/src/runtime/server/page/server_routing.js +85 -26
- package/src/runtime/server/remote-functions.js +640 -0
- package/src/runtime/server/respond.js +190 -131
- package/src/runtime/server/sourcemaps.js +183 -0
- package/src/runtime/server/state.js +53 -0
- package/src/runtime/server/utils.js +13 -155
- package/src/runtime/shared.js +20 -40
- package/src/runtime/utils.js +3 -0
- package/src/types/ambient-private.d.ts +11 -1
- package/src/types/ambient.d.ts +87 -36
- package/src/types/global-private.d.ts +25 -25
- package/src/types/internal.d.ts +163 -157
- package/src/types/private.d.ts +41 -1
- package/src/utils/error.js +28 -4
- package/src/utils/escape.js +9 -25
- package/src/utils/features.js +1 -1
- package/src/utils/filesystem.js +1 -23
- package/src/utils/fork.js +7 -2
- package/src/utils/hash.js +21 -0
- package/src/utils/http.js +8 -7
- package/src/utils/import.js +9 -2
- package/src/utils/imports.js +83 -0
- package/src/utils/mime.js +9 -0
- package/src/utils/page_nodes.js +6 -7
- package/src/utils/params.js +67 -0
- package/src/utils/regex.js +9 -0
- package/src/utils/routing.js +145 -73
- package/src/utils/shared-iterator.js +5 -0
- package/src/utils/streaming.js +14 -4
- package/src/utils/url.js +33 -2
- package/src/version.js +1 -1
- package/types/index.d.ts +2616 -2433
- package/types/index.d.ts.map +120 -106
- package/src/core/sync/write_ambient.js +0 -18
- package/src/core/sync/write_root.js +0 -148
- package/src/core/sync/write_tsconfig.js +0 -250
- package/src/exports/internal/server.js +0 -22
- package/src/exports/node/polyfills.js +0 -30
- package/src/runtime/server/app.js +0 -9
- package/src/runtime/server/remote.js +0 -457
- package/src/runtime/shared-server.js +0 -7
- package/src/runtime/telemetry/otel.js +0 -21
- package/src/runtime/telemetry/record_span.js +0 -65
- package/src/types/synthetic/$lib.md +0 -5
- /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
- /package/src/{runtime/telemetry/noop.js → telemetry.js} +0 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/* eslint-disable n/prefer-global/process */
|
|
2
|
+
|
|
3
|
+
// using `getBuiltinModule` rather than `import` makes this safe to run in non-Node-compatible environments
|
|
4
|
+
const fs = globalThis.process?.getBuiltinModule?.('node:fs');
|
|
5
|
+
const url = globalThis.process?.getBuiltinModule?.('node:url');
|
|
6
|
+
const path = globalThis.process?.getBuiltinModule?.('node:path');
|
|
7
|
+
const module = globalThis.process?.getBuiltinModule?.('node:module');
|
|
8
|
+
|
|
9
|
+
const cwd = globalThis.process?.cwd?.();
|
|
10
|
+
|
|
11
|
+
/** @type {(file: string) => string} */
|
|
12
|
+
const relative = cwd ? (file) => path.relative(cwd, file) : (file) => file;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Applies sourcemaps, makes paths relative to the cwd, and truncates
|
|
16
|
+
* non-user code from the bottom of the stack
|
|
17
|
+
* @param {Error} error
|
|
18
|
+
* @returns void
|
|
19
|
+
*/
|
|
20
|
+
export let fix_stack_trace = (error) => {
|
|
21
|
+
if (!error.stack || !fs) return;
|
|
22
|
+
|
|
23
|
+
let end = 0;
|
|
24
|
+
|
|
25
|
+
error.stack = error.stack
|
|
26
|
+
.split('\n')
|
|
27
|
+
.map((line, i) => {
|
|
28
|
+
const match = line.match(/^ {4}at.+(file:\/\/\/.*):(\d+):(\d+)(\)?)$/);
|
|
29
|
+
|
|
30
|
+
if (!match) {
|
|
31
|
+
if (!line.includes('node:internal/')) {
|
|
32
|
+
end = i + 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return line;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const file = url.fileURLToPath(match[1]);
|
|
39
|
+
const traced = trace(file, Number(match[2]) - 1, Number(match[3]) - 1);
|
|
40
|
+
|
|
41
|
+
// truncate non-user code from the bottom of the stack (but leave it in otherwise)
|
|
42
|
+
if (!/[\\/]node_modules[\\/]/.test(traced?.file ?? file)) {
|
|
43
|
+
end = i + 1;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (traced?.line) {
|
|
47
|
+
const location = `${match[1]}:${match[2]}:${match[3]}`;
|
|
48
|
+
const original = `${relative(traced.file)}:${traced.line}:${traced.column}`;
|
|
49
|
+
|
|
50
|
+
return line.replace(location, original);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (traced) {
|
|
54
|
+
return `${line.replace(match[1], relative(file))} [${traced.file}]`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return line;
|
|
58
|
+
})
|
|
59
|
+
.slice(0, end)
|
|
60
|
+
.join('\n');
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Override the implementation of fix_stack_trace (for using during dev)
|
|
65
|
+
* @param {(error: Error) => void} fn
|
|
66
|
+
*/
|
|
67
|
+
export function set_fix_stack_trace(fn) {
|
|
68
|
+
fix_stack_trace = fn;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** @type {Map<string, { map: import('node:module').SourceMap; directory: string } | null>} */
|
|
72
|
+
const source_maps = new Map();
|
|
73
|
+
|
|
74
|
+
/** @type {Map<string, Array<string | undefined>>} */
|
|
75
|
+
const source_regions = new Map();
|
|
76
|
+
|
|
77
|
+
/** @param {string} file */
|
|
78
|
+
function get_source_map(file) {
|
|
79
|
+
if (source_maps.has(file)) {
|
|
80
|
+
return source_maps.get(file);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
let source;
|
|
85
|
+
let directory = path.dirname(file);
|
|
86
|
+
|
|
87
|
+
const code = fs.readFileSync(file, 'utf8');
|
|
88
|
+
const matches = Array.from(code.matchAll(/\/\/[#@]\s*sourceMappingURL=(\S+)/g));
|
|
89
|
+
const url = matches.at(-1)?.[1];
|
|
90
|
+
|
|
91
|
+
if (url?.startsWith('data:')) {
|
|
92
|
+
const comma = url.indexOf(',');
|
|
93
|
+
const metadata = url.slice(5, comma);
|
|
94
|
+
const data = url.slice(comma + 1);
|
|
95
|
+
source = metadata.endsWith(';base64')
|
|
96
|
+
? Buffer.from(data, 'base64').toString()
|
|
97
|
+
: decodeURIComponent(data);
|
|
98
|
+
} else {
|
|
99
|
+
const map_file = url
|
|
100
|
+
? path.resolve(path.dirname(file), decodeURIComponent(url))
|
|
101
|
+
: `${file}.map`;
|
|
102
|
+
if (fs.existsSync(map_file)) {
|
|
103
|
+
directory = path.dirname(map_file);
|
|
104
|
+
source = fs.readFileSync(map_file, 'utf8');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (source) {
|
|
109
|
+
const source_map = { map: new module.SourceMap(JSON.parse(source)), directory };
|
|
110
|
+
source_maps.set(file, source_map);
|
|
111
|
+
|
|
112
|
+
return source_map;
|
|
113
|
+
}
|
|
114
|
+
} catch {
|
|
115
|
+
// failure could be for any reason and this is best-effort, ignore
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
source_maps.set(file, null);
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
*
|
|
124
|
+
* @param {string} file
|
|
125
|
+
* @param {number} line
|
|
126
|
+
* @param {number} column
|
|
127
|
+
* @returns {null | { file: string, line?: number, column?: number }}
|
|
128
|
+
*/
|
|
129
|
+
function trace(file, line, column) {
|
|
130
|
+
const source_map = get_source_map(file);
|
|
131
|
+
if (!source_map) return null;
|
|
132
|
+
|
|
133
|
+
const entry = source_map.map.findEntry(line, column);
|
|
134
|
+
|
|
135
|
+
if (
|
|
136
|
+
entry &&
|
|
137
|
+
'originalSource' in entry &&
|
|
138
|
+
entry.originalSource &&
|
|
139
|
+
typeof entry.originalLine === 'number' &&
|
|
140
|
+
typeof entry.originalColumn === 'number'
|
|
141
|
+
) {
|
|
142
|
+
const source = entry.originalSource.startsWith('file:')
|
|
143
|
+
? url.fileURLToPath(entry.originalSource)
|
|
144
|
+
: path.resolve(source_map.directory, entry.originalSource);
|
|
145
|
+
|
|
146
|
+
const traced = {
|
|
147
|
+
file: source,
|
|
148
|
+
line: entry.originalLine + 1,
|
|
149
|
+
column: entry.originalColumn + 1
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// keep going, in case we are running code that was bundled a second time by an adapter
|
|
153
|
+
return trace(traced.file, traced.line - 1, traced.column - 1) ?? traced;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
let regions = source_regions.get(file);
|
|
157
|
+
if (!regions) {
|
|
158
|
+
/** @type {string | undefined} */
|
|
159
|
+
let source;
|
|
160
|
+
regions = fs
|
|
161
|
+
.readFileSync(file, 'utf8')
|
|
162
|
+
.split('\n')
|
|
163
|
+
.map((line) => {
|
|
164
|
+
// Vite will merge multiple files into one but add region markers
|
|
165
|
+
// with the original file names, which we try to extract here.
|
|
166
|
+
const start = line.match(/^\/\/#region (.+)$/);
|
|
167
|
+
if (start) source = start[1];
|
|
168
|
+
if (line === '//#endregion') source = undefined;
|
|
169
|
+
return source;
|
|
170
|
+
});
|
|
171
|
+
source_regions.set(file, regions);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const source = regions[line];
|
|
175
|
+
|
|
176
|
+
if (source) {
|
|
177
|
+
return {
|
|
178
|
+
file: source
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** @import { InternalRequestOptions, RequestState } from 'types' */
|
|
2
|
+
|
|
3
|
+
/** Per-request caches and context flags — never carried into a fork. */
|
|
4
|
+
function transient_fields() {
|
|
5
|
+
return {
|
|
6
|
+
remote: {
|
|
7
|
+
data: null,
|
|
8
|
+
explicit: null,
|
|
9
|
+
implicit: null,
|
|
10
|
+
forms: null,
|
|
11
|
+
requested: null,
|
|
12
|
+
batches: null,
|
|
13
|
+
live_iterators: null
|
|
14
|
+
},
|
|
15
|
+
is_in_remote_function: false,
|
|
16
|
+
is_in_remote_form_or_command: false,
|
|
17
|
+
is_in_remote_query: false,
|
|
18
|
+
is_in_remote_prerender: false,
|
|
19
|
+
is_in_render: false
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {InternalRequestOptions} options
|
|
25
|
+
* @returns {RequestState}
|
|
26
|
+
*/
|
|
27
|
+
export function create_request_state(options) {
|
|
28
|
+
// every field is initialized up front so the object shape stays stable
|
|
29
|
+
return {
|
|
30
|
+
getClientAddress: options.getClientAddress,
|
|
31
|
+
platform: options.platform,
|
|
32
|
+
read: options.read,
|
|
33
|
+
before_handle: options.before_handle,
|
|
34
|
+
emulator: options.emulator,
|
|
35
|
+
prerendering: options.prerendering,
|
|
36
|
+
prerender_default: undefined,
|
|
37
|
+
error: false,
|
|
38
|
+
depth: 0,
|
|
39
|
+
...transient_fields()
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param {RequestState} state
|
|
45
|
+
* @returns {RequestState}
|
|
46
|
+
*/
|
|
47
|
+
export function fork_state_for_subrequest(state) {
|
|
48
|
+
return {
|
|
49
|
+
...state,
|
|
50
|
+
...transient_fields(),
|
|
51
|
+
depth: state.depth + 1
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import * as devalue from 'devalue';
|
|
3
|
-
import { DEV } from 'esm-env';
|
|
4
|
-
import { json, text } from '@sveltejs/kit';
|
|
5
|
-
import { HttpError } from '@sveltejs/kit/internal';
|
|
6
|
-
import { with_request_store } from '@sveltejs/kit/internal/server';
|
|
7
|
-
import { coalesce_to_error, get_message, get_status } from '../../utils/error.js';
|
|
8
|
-
import { negotiate } from '../../utils/http.js';
|
|
9
|
-
import { fix_stack_trace } from '../shared-server.js';
|
|
1
|
+
import { text } from '@sveltejs/kit';
|
|
10
2
|
import { ENDPOINT_METHODS } from '../../constants.js';
|
|
11
|
-
import { escape_html } from '../../utils/escape.js';
|
|
12
|
-
import * as path from '../../utils/path.js';
|
|
13
3
|
|
|
14
4
|
/**
|
|
15
5
|
* @param {Partial<Record<import('types').HttpMethod, any>>} mod
|
|
@@ -46,80 +36,6 @@ export function get_global_name(options) {
|
|
|
46
36
|
return __SVELTEKIT_DEV__ ? '__sveltekit_dev' : `__sveltekit_${options.version_hash}`;
|
|
47
37
|
}
|
|
48
38
|
|
|
49
|
-
/**
|
|
50
|
-
* Return as a response that renders the error.html
|
|
51
|
-
*
|
|
52
|
-
* @param {import('types').SSROptions} options
|
|
53
|
-
* @param {number} status
|
|
54
|
-
* @param {string} message
|
|
55
|
-
*/
|
|
56
|
-
export function static_error_page(options, status, message) {
|
|
57
|
-
let page = options.templates.error({ status, message: escape_html(message) });
|
|
58
|
-
|
|
59
|
-
if (__SVELTEKIT_DEV__) {
|
|
60
|
-
// inject Vite HMR client, for easier debugging
|
|
61
|
-
page = page.replace('</head>', '<script type="module" src="/@vite/client"></script></head>');
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return text(page, {
|
|
65
|
-
headers: { 'content-type': 'text/html; charset=utf-8' },
|
|
66
|
-
status
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
72
|
-
* @param {import('types').RequestState} state
|
|
73
|
-
* @param {import('types').SSROptions} options
|
|
74
|
-
* @param {unknown} error
|
|
75
|
-
*/
|
|
76
|
-
export async function handle_fatal_error(event, state, options, error) {
|
|
77
|
-
error = error instanceof HttpError ? error : coalesce_to_error(error);
|
|
78
|
-
const status = get_status(error);
|
|
79
|
-
const body = await handle_error_and_jsonify(event, state, options, error);
|
|
80
|
-
|
|
81
|
-
// ideally we'd use sec-fetch-dest instead, but Safari — quelle surprise — doesn't support it
|
|
82
|
-
const type = negotiate(event.request.headers.get('accept') || 'text/html', [
|
|
83
|
-
'application/json',
|
|
84
|
-
'text/html'
|
|
85
|
-
]);
|
|
86
|
-
|
|
87
|
-
if (event.isDataRequest || type === 'application/json') {
|
|
88
|
-
return json(body, {
|
|
89
|
-
status
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return static_error_page(options, status, body.message);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
98
|
-
* @param {import('types').RequestState} state
|
|
99
|
-
* @param {import('types').SSROptions} options
|
|
100
|
-
* @param {any} error
|
|
101
|
-
* @returns {Promise<App.Error>}
|
|
102
|
-
*/
|
|
103
|
-
export async function handle_error_and_jsonify(event, state, options, error) {
|
|
104
|
-
if (error instanceof HttpError) {
|
|
105
|
-
// @ts-expect-error custom user errors may not have a message field if App.Error is overwritten
|
|
106
|
-
return { message: 'Unknown Error', ...error.body };
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (__SVELTEKIT_DEV__ && typeof error == 'object') {
|
|
110
|
-
fix_stack_trace(error);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const status = get_status(error);
|
|
114
|
-
const message = get_message(error);
|
|
115
|
-
|
|
116
|
-
return (
|
|
117
|
-
(await with_request_store({ event, state }, () =>
|
|
118
|
-
options.hooks.handleError({ error, event, status, message })
|
|
119
|
-
)) ?? { message }
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
39
|
/**
|
|
124
40
|
* @param {number} status
|
|
125
41
|
* @param {string} location
|
|
@@ -133,14 +49,24 @@ export function redirect_response(status, location) {
|
|
|
133
49
|
}
|
|
134
50
|
|
|
135
51
|
/**
|
|
136
|
-
* @param {
|
|
52
|
+
* @param {Response} response
|
|
53
|
+
*/
|
|
54
|
+
export function with_version_header(response) {
|
|
55
|
+
if (__SVELTEKIT_APP_VERSION_CHECKS_ENABLED__) {
|
|
56
|
+
response.headers.set('x-sveltekit-version', __SVELTEKIT_APP_VERSION__);
|
|
57
|
+
}
|
|
58
|
+
return response;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {import('$app/server').RequestEvent} event
|
|
137
63
|
* @param {Error & { path: string }} error
|
|
138
64
|
*/
|
|
139
65
|
export function clarify_devalue_error(event, error) {
|
|
140
66
|
if (error.path) {
|
|
141
67
|
return (
|
|
142
68
|
`Data returned from \`load\` while rendering ${event.route.id} is not serializable: ${error.message} (${error.path}). ` +
|
|
143
|
-
`If you need to serialize/deserialize custom types, use transport hooks: https://svelte.dev/docs/kit/hooks#
|
|
69
|
+
`If you need to serialize/deserialize custom types, use transport hooks: https://svelte.dev/docs/kit/hooks#transport.`
|
|
144
70
|
);
|
|
145
71
|
}
|
|
146
72
|
|
|
@@ -189,56 +115,6 @@ export function has_prerendered_path(manifest, pathname) {
|
|
|
189
115
|
);
|
|
190
116
|
}
|
|
191
117
|
|
|
192
|
-
/**
|
|
193
|
-
* Formats the error into a nice message with sanitized stack trace
|
|
194
|
-
* @param {number} status
|
|
195
|
-
* @param {Error} error
|
|
196
|
-
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
197
|
-
*/
|
|
198
|
-
export function format_server_error(status, error, event) {
|
|
199
|
-
const formatted_text = `\n\x1b[1;31m[${status}] ${event.request.method} ${event.url.pathname}\x1b[0m`;
|
|
200
|
-
|
|
201
|
-
if (status === 404) {
|
|
202
|
-
return formatted_text;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return `${formatted_text}\n${DEV ? clean_up_stack_trace(error) : error.stack}`;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* In dev, tidy up stack traces by making paths relative to the current project directory
|
|
210
|
-
* @param {string} file
|
|
211
|
-
*/
|
|
212
|
-
let relative = (file) => file;
|
|
213
|
-
|
|
214
|
-
if (DEV) {
|
|
215
|
-
try {
|
|
216
|
-
relative = (file) => path.relative(__SVELTEKIT_ROOT__, file);
|
|
217
|
-
} catch {
|
|
218
|
-
// do nothing
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Provides a refined stack trace by excluding lines following the last occurrence of a line containing +page. +layout. or +server.
|
|
224
|
-
* @param {Error} error
|
|
225
|
-
*/
|
|
226
|
-
export function clean_up_stack_trace(error) {
|
|
227
|
-
const stack_trace = (error.stack?.split('\n') ?? []).map((line) => {
|
|
228
|
-
return line.replace(/\((.+)(:\d+:\d+)\)$/, (_, file, loc) => `(${relative(file)}${loc})`);
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
// progressive enhancement for people who haven't configured kit.files.src to something else
|
|
232
|
-
const last_line_from_src_code = stack_trace.findLastIndex((line) => /\(src[\\/]/.test(line));
|
|
233
|
-
|
|
234
|
-
if (last_line_from_src_code === -1) {
|
|
235
|
-
// default to the whole stack trace
|
|
236
|
-
return error.stack;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return stack_trace.slice(0, last_line_from_src_code + 1).join('\n');
|
|
240
|
-
}
|
|
241
|
-
|
|
242
118
|
/**
|
|
243
119
|
* Returns the filename without the extension. e.g., `+page.server`, `+page`, etc.
|
|
244
120
|
* @param {string | undefined} node_id
|
|
@@ -261,21 +137,3 @@ export function get_node_type(node_id) {
|
|
|
261
137
|
export function count_non_ssi_comments(str) {
|
|
262
138
|
return (str.match(/<!--(?!#)/g) ?? []).length;
|
|
263
139
|
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Creates a serialiser for non-arbitrary POJOs using the app's transport hook
|
|
267
|
-
* @param {ServerHooks['transport']} transport
|
|
268
|
-
* @returns {(thing: unknown) => string | undefined}
|
|
269
|
-
*/
|
|
270
|
-
export function create_replacer(transport) {
|
|
271
|
-
/** @param {unknown} thing */
|
|
272
|
-
const replacer = (thing) => {
|
|
273
|
-
for (const key in transport) {
|
|
274
|
-
const encoded = transport[key].encode(thing);
|
|
275
|
-
if (encoded) {
|
|
276
|
-
return `app.decode('${key}', ${devalue.uneval(encoded, replacer)})`;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
return replacer;
|
|
281
|
-
}
|
package/src/runtime/shared.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/** @import { Transport } from '@sveltejs/kit' */
|
|
2
1
|
import * as devalue from 'devalue';
|
|
3
|
-
import { base64_decode, base64_encode, text_encoder } from './utils.js';
|
|
2
|
+
import { base64_decode, base64_encode, text_decoder, text_encoder } from './utils.js';
|
|
3
|
+
import { decoders, encoders } from '#app/internal/transport';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @param {string} route_id
|
|
@@ -39,17 +39,6 @@ export function validate_load_response(data, location_description) {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
/**
|
|
43
|
-
* Try to `devalue.stringify` the data object using the provided transport encoders.
|
|
44
|
-
* @param {any} data
|
|
45
|
-
* @param {Transport} transport
|
|
46
|
-
*/
|
|
47
|
-
export function stringify(data, transport) {
|
|
48
|
-
const encoders = Object.fromEntries(Object.entries(transport).map(([k, v]) => [k, v.encode]));
|
|
49
|
-
|
|
50
|
-
return devalue.stringify(data, encoders);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
42
|
const object_proto_names = /* @__PURE__ */ Object.getOwnPropertyNames(Object.prototype)
|
|
54
43
|
.sort()
|
|
55
44
|
.join('\0');
|
|
@@ -102,11 +91,9 @@ const remote_regex_guard = '__skrag';
|
|
|
102
91
|
const remote_arg_marker = Symbol(remote_object);
|
|
103
92
|
|
|
104
93
|
/**
|
|
105
|
-
* @param {Transport} transport
|
|
106
94
|
* @param {boolean} sort
|
|
107
|
-
* @param {Map<any, any>} remote_arg_clones
|
|
108
95
|
*/
|
|
109
|
-
function create_remote_arg_reducers(
|
|
96
|
+
function create_remote_arg_reducers(sort) {
|
|
110
97
|
/** @type {Record<string, (value: unknown) => unknown>} */
|
|
111
98
|
const remote_fns_reducers = {
|
|
112
99
|
/** @param {unknown} value */
|
|
@@ -118,6 +105,8 @@ function create_remote_arg_reducers(transport, sort, remote_arg_clones) {
|
|
|
118
105
|
};
|
|
119
106
|
|
|
120
107
|
if (sort) {
|
|
108
|
+
const clones = new Map();
|
|
109
|
+
|
|
121
110
|
/** @type {(value: unknown) => Array<[unknown, unknown]> | undefined} */
|
|
122
111
|
remote_fns_reducers[remote_map] = (value) => {
|
|
123
112
|
if (!(value instanceof Map)) {
|
|
@@ -167,18 +156,15 @@ function create_remote_arg_reducers(transport, sort, remote_arg_clones) {
|
|
|
167
156
|
return;
|
|
168
157
|
}
|
|
169
158
|
|
|
170
|
-
if (
|
|
171
|
-
return
|
|
159
|
+
if (clones.has(value)) {
|
|
160
|
+
return clones.get(value);
|
|
172
161
|
}
|
|
173
162
|
|
|
174
|
-
return to_sorted(value,
|
|
163
|
+
return to_sorted(value, clones);
|
|
175
164
|
};
|
|
176
165
|
}
|
|
177
166
|
|
|
178
|
-
const
|
|
179
|
-
Object.entries(transport).map(([k, v]) => [k, v.encode])
|
|
180
|
-
);
|
|
181
|
-
const all_reducers = { ...user_reducers, ...remote_fns_reducers };
|
|
167
|
+
const all_reducers = { ...encoders, ...remote_fns_reducers };
|
|
182
168
|
|
|
183
169
|
/** @type {(value: unknown) => string} */
|
|
184
170
|
const stringify = (value) => devalue.stringify(value, all_reducers);
|
|
@@ -186,8 +172,7 @@ function create_remote_arg_reducers(transport, sort, remote_arg_clones) {
|
|
|
186
172
|
return all_reducers;
|
|
187
173
|
}
|
|
188
174
|
|
|
189
|
-
|
|
190
|
-
function create_remote_arg_revivers(transport) {
|
|
175
|
+
function create_remote_arg_revivers() {
|
|
191
176
|
const remote_fns_revivers = {
|
|
192
177
|
/** @type {(value: unknown) => unknown} */
|
|
193
178
|
[remote_object]: (value) => value,
|
|
@@ -251,11 +236,7 @@ function create_remote_arg_revivers(transport) {
|
|
|
251
236
|
}
|
|
252
237
|
};
|
|
253
238
|
|
|
254
|
-
const
|
|
255
|
-
Object.entries(transport).map(([k, v]) => [k, v.decode])
|
|
256
|
-
);
|
|
257
|
-
|
|
258
|
-
const all_revivers = { ...user_revivers, ...remote_fns_revivers };
|
|
239
|
+
const all_revivers = { ...decoders, ...remote_fns_revivers };
|
|
259
240
|
|
|
260
241
|
/** @type {(data: string) => unknown} */
|
|
261
242
|
const parse = (data) => devalue.parse(data, all_revivers);
|
|
@@ -267,13 +248,12 @@ function create_remote_arg_revivers(transport) {
|
|
|
267
248
|
* Stringifies the argument (if any) for a remote function in such a way that
|
|
268
249
|
* it is both a valid URL and a valid file name (necessary for prerendering).
|
|
269
250
|
* @param {any} value
|
|
270
|
-
* @param {Transport} transport
|
|
271
251
|
*/
|
|
272
|
-
export function stringify_remote_arg(value
|
|
252
|
+
export function stringify_remote_arg(value) {
|
|
273
253
|
if (value === undefined) return '';
|
|
274
254
|
|
|
275
255
|
// If people hit file/url size limits, we can look into using something like compress_and_encode_text from svelte.dev beyond a certain size
|
|
276
|
-
const json = devalue.stringify(value, create_remote_arg_reducers(
|
|
256
|
+
const json = devalue.stringify(value, create_remote_arg_reducers(true));
|
|
277
257
|
|
|
278
258
|
return url_friendly_base64_encode(json);
|
|
279
259
|
}
|
|
@@ -281,12 +261,11 @@ export function stringify_remote_arg(value, transport) {
|
|
|
281
261
|
/**
|
|
282
262
|
* Stringifies command arguments, including `File` objects.
|
|
283
263
|
* @param {any} value
|
|
284
|
-
* @param {Transport} transport
|
|
285
264
|
*/
|
|
286
|
-
export async function stringify_command_arg(value
|
|
265
|
+
export async function stringify_command_arg(value) {
|
|
287
266
|
if (value === undefined) return '';
|
|
288
267
|
|
|
289
|
-
const reducers = create_remote_arg_reducers(
|
|
268
|
+
const reducers = create_remote_arg_reducers(false);
|
|
290
269
|
|
|
291
270
|
/** @type {Set<Promise<any>>} */
|
|
292
271
|
const allowed_promises = new Set();
|
|
@@ -331,23 +310,24 @@ export async function stringify_command_arg(value, transport) {
|
|
|
331
310
|
*/
|
|
332
311
|
function url_friendly_base64_encode(string) {
|
|
333
312
|
const bytes = text_encoder.encode(string);
|
|
313
|
+
// TODO replace with `bytes.toBase64({ alphabet: 'base64url', omitPadding: true })` when we require Node >= 25
|
|
334
314
|
return base64_encode(bytes).replaceAll('=', '').replaceAll('+', '-').replaceAll('/', '_');
|
|
335
315
|
}
|
|
336
316
|
|
|
337
317
|
/**
|
|
338
318
|
* Parses the argument (if any) for a remote function
|
|
339
319
|
* @param {string} string
|
|
340
|
-
* @param {Transport} transport
|
|
341
320
|
*/
|
|
342
|
-
export function parse_remote_arg(string
|
|
321
|
+
export function parse_remote_arg(string) {
|
|
343
322
|
if (!string) return undefined;
|
|
344
323
|
|
|
345
|
-
const json_string =
|
|
324
|
+
const json_string = text_decoder.decode(
|
|
325
|
+
// TODO replace with `Uint8Array.fromBase64(string, { alphabet: 'base64url' })` when we require Node >= 25
|
|
346
326
|
// no need to add back `=` characters, atob can handle it
|
|
347
327
|
base64_decode(string.replaceAll('-', '+').replaceAll('_', '/'))
|
|
348
328
|
);
|
|
349
329
|
|
|
350
|
-
return devalue.parse(json_string, create_remote_arg_revivers(
|
|
330
|
+
return devalue.parse(json_string, create_remote_arg_revivers());
|
|
351
331
|
}
|
|
352
332
|
|
|
353
333
|
/**
|
package/src/runtime/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BROWSER } from 'esm-env';
|
|
2
2
|
|
|
3
3
|
export const text_encoder = new TextEncoder();
|
|
4
|
+
export const text_decoder = new TextDecoder();
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Like node's path.relative, but without using node
|
|
@@ -28,6 +29,7 @@ export function get_relative_path(from, to) {
|
|
|
28
29
|
* @returns {string}
|
|
29
30
|
*/
|
|
30
31
|
export function base64_encode(bytes) {
|
|
32
|
+
// TODO replace with `bytes.toBase64()` when we require Node >= 25
|
|
31
33
|
// Using `Buffer` is faster than iterating
|
|
32
34
|
if (!BROWSER && globalThis.Buffer) {
|
|
33
35
|
return globalThis.Buffer.from(bytes).toString('base64');
|
|
@@ -47,6 +49,7 @@ export function base64_encode(bytes) {
|
|
|
47
49
|
* @returns {Uint8Array}
|
|
48
50
|
*/
|
|
49
51
|
export function base64_decode(encoded) {
|
|
52
|
+
// TODO replace with `Uint8Array.fromBase64(encoded)` when we require Node >= 25
|
|
50
53
|
// Using `Buffer` is faster than iterating
|
|
51
54
|
if (!BROWSER && globalThis.Buffer) {
|
|
52
55
|
const buffer = globalThis.Buffer.from(encoded, 'base64');
|
|
@@ -13,8 +13,10 @@ declare module '__sveltekit/paths' {
|
|
|
13
13
|
declare module '__sveltekit/server' {
|
|
14
14
|
import { SSRManifest } from '@sveltejs/kit';
|
|
15
15
|
|
|
16
|
+
export let fix_stack_trace: (error: Error) => string;
|
|
16
17
|
export let manifest: SSRManifest;
|
|
17
18
|
export function read_implementation(path: string): ReadableStream;
|
|
19
|
+
export function set_fix_stack_trace(fn: (error: Error) => string): void;
|
|
18
20
|
export function set_manifest(manifest: SSRManifest): void;
|
|
19
21
|
export function set_read_implementation(fn: (path: string) => ReadableStream): void;
|
|
20
22
|
}
|
|
@@ -23,7 +25,7 @@ declare module '__sveltekit/env' {
|
|
|
23
25
|
// exported environment variables are defined in env.d.ts
|
|
24
26
|
|
|
25
27
|
/** Populate exported environment variables */
|
|
26
|
-
export function set_env(environment: Record<string, string>): void;
|
|
28
|
+
export function set_env(environment: Record<string, string | undefined>): void;
|
|
27
29
|
|
|
28
30
|
/** public env vars */
|
|
29
31
|
export const explicit_public_env: Record<string, any>;
|
|
@@ -43,3 +45,11 @@ declare module '__sveltekit/env/public/client' {
|
|
|
43
45
|
declare module '__sveltekit/env/public/server' {
|
|
44
46
|
// exported environment variables are defined in env.d.ts
|
|
45
47
|
}
|
|
48
|
+
|
|
49
|
+
/** Internal version of $app/manifest */
|
|
50
|
+
declare module '__sveltekit/manifest-data' {
|
|
51
|
+
export const immutable: Array<{ path: string }>;
|
|
52
|
+
export const assets: Array<{ path: string }>;
|
|
53
|
+
export const prerendered: Array<{ path: string }>;
|
|
54
|
+
export const routes: Array<{ id: string; page: boolean; endpoint: boolean }>;
|
|
55
|
+
}
|