@sveltejs/kit 3.0.0-next.1 → 3.0.0-next.11
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 +33 -21
- package/src/constants.js +2 -0
- package/src/core/adapt/builder.js +32 -49
- package/src/core/adapt/index.js +1 -4
- package/src/core/config/index.js +137 -71
- package/src/core/config/options.js +236 -244
- package/src/core/config/types.d.ts +1 -1
- package/src/core/env.js +121 -5
- package/src/core/generate_manifest/index.js +12 -15
- package/src/core/postbuild/analyse.js +7 -19
- package/src/core/postbuild/crawl.js +22 -6
- package/src/core/postbuild/fallback.js +2 -1
- package/src/core/postbuild/prerender.js +114 -48
- package/src/core/postbuild/queue.js +2 -1
- package/src/core/sync/create_manifest_data/index.js +53 -50
- package/src/core/sync/sync.js +0 -2
- package/src/core/sync/write_client_manifest.js +8 -15
- package/src/core/sync/write_env.js +2 -1
- package/src/core/sync/write_non_ambient.js +12 -9
- package/src/core/sync/write_server.js +14 -15
- package/src/core/sync/write_tsconfig.js +16 -8
- package/src/core/sync/write_tsconfig_test/package.json +7 -0
- package/src/core/sync/write_types/index.js +28 -24
- package/src/core/utils.js +30 -5
- package/src/exports/env/index.js +77 -0
- package/src/exports/hooks/index.js +3 -9
- package/src/exports/hooks/sequence.js +3 -2
- package/src/exports/index.js +35 -13
- 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} +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 +62 -15
- package/src/exports/params.js +68 -0
- package/src/exports/public.d.ts +363 -189
- package/src/exports/url.js +86 -0
- package/src/exports/vite/build/build_server.js +53 -59
- package/src/exports/vite/build/remote.js +18 -11
- package/src/exports/vite/build/utils.js +0 -8
- package/src/exports/vite/dev/index.js +92 -50
- package/src/exports/vite/index.js +903 -681
- package/src/exports/vite/module_ids.js +0 -2
- package/src/exports/vite/preview/index.js +32 -24
- package/src/exports/vite/static_analysis/index.js +2 -4
- package/src/exports/vite/static_analysis/types.d.ts +14 -0
- package/src/exports/vite/utils.js +40 -35
- 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 +24 -7
- package/src/runtime/app/paths/client.js +4 -10
- 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/public.d.ts +0 -28
- package/src/runtime/app/paths/server.js +10 -6
- package/src/runtime/app/server/index.js +1 -1
- package/src/runtime/app/server/remote/command.js +0 -3
- package/src/runtime/app/server/remote/form.js +27 -15
- package/src/runtime/app/server/remote/prerender.js +29 -36
- package/src/runtime/app/server/remote/query.js +101 -99
- package/src/runtime/app/server/remote/requested.js +22 -14
- package/src/runtime/app/server/remote/shared.js +30 -26
- 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 +411 -318
- package/src/runtime/client/entry.js +24 -3
- package/src/runtime/client/fetcher.js +3 -2
- package/src/runtime/client/ndjson.js +6 -33
- 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 +7 -32
- package/src/runtime/client/remote-functions/form.svelte.js +183 -112
- package/src/runtime/client/remote-functions/prerender.svelte.js +29 -8
- package/src/runtime/client/remote-functions/query/index.js +7 -14
- package/src/runtime/client/remote-functions/query/instance.svelte.js +63 -18
- package/src/runtime/client/remote-functions/query/proxy.js +3 -3
- package/src/runtime/client/remote-functions/query-batch.svelte.js +60 -68
- package/src/runtime/client/remote-functions/query-live/instance.svelte.js +60 -18
- package/src/runtime/client/remote-functions/query-live/iterator.js +36 -55
- package/src/runtime/client/remote-functions/shared.svelte.js +88 -62
- package/src/runtime/client/sse.js +32 -0
- package/src/runtime/client/state.svelte.js +65 -49
- package/src/runtime/client/stream.js +39 -0
- package/src/runtime/client/types.d.ts +11 -7
- package/src/runtime/client/utils.js +0 -96
- package/src/runtime/components/root.svelte +66 -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 +100 -22
- package/src/runtime/server/cookie.js +69 -52
- package/src/runtime/server/csrf.js +65 -0
- package/src/runtime/server/data/index.js +15 -19
- package/src/runtime/server/env_module.js +0 -5
- package/src/runtime/server/errors.js +135 -0
- package/src/runtime/server/fetch.js +1 -1
- package/src/runtime/server/index.js +22 -12
- package/src/runtime/server/internal.js +25 -0
- package/src/runtime/server/page/actions.js +43 -27
- package/src/runtime/server/page/data_serializer.js +10 -10
- package/src/runtime/server/page/index.js +12 -17
- package/src/runtime/server/page/load_data.js +2 -2
- package/src/runtime/server/page/render.js +114 -193
- package/src/runtime/server/page/respond_with_error.js +11 -11
- package/src/runtime/server/page/server_routing.js +27 -18
- package/src/runtime/server/remote-functions.js +596 -0
- package/src/runtime/server/respond.js +100 -68
- package/src/runtime/server/sourcemaps.js +183 -0
- package/src/runtime/server/utils.js +2 -134
- package/src/runtime/shared.js +83 -13
- package/src/runtime/telemetry/otel.js +1 -1
- package/src/runtime/types.d.ts +8 -0
- package/src/types/ambient-private.d.ts +2 -0
- package/src/types/ambient.d.ts +10 -5
- package/src/types/global-private.d.ts +13 -25
- package/src/types/internal.d.ts +95 -80
- package/src/types/private.d.ts +41 -1
- package/src/utils/error.js +24 -4
- package/src/utils/escape.js +9 -25
- package/src/utils/features.js +1 -1
- package/src/utils/fork.js +7 -2
- package/src/utils/import.js +6 -1
- package/src/utils/imports.js +83 -0
- package/src/utils/mime.js +9 -0
- package/src/utils/page_nodes.js +3 -5
- package/src/utils/params.js +66 -0
- package/src/utils/routing.js +90 -44
- package/src/utils/shared-iterator.js +5 -0
- package/src/utils/streaming.js +14 -4
- package/src/utils/url.js +20 -2
- package/src/version.js +1 -1
- package/types/index.d.ts +537 -557
- package/types/index.d.ts.map +24 -39
- package/src/core/sync/write_root.js +0 -148
- package/src/exports/internal/server.js +0 -22
- package/src/runtime/server/remote.js +0 -457
- package/src/runtime/shared-server.js +0 -7
- package/src/types/synthetic/$lib.md +0 -5
- /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
|
@@ -8,13 +8,9 @@ import { is_endpoint_request, render_endpoint } from './endpoint.js';
|
|
|
8
8
|
import { render_page } from './page/index.js';
|
|
9
9
|
import { render_response } from './page/render.js';
|
|
10
10
|
import { respond_with_error } from './page/respond_with_error.js';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
has_prerendered_path,
|
|
15
|
-
method_not_allowed,
|
|
16
|
-
redirect_response
|
|
17
|
-
} from './utils.js';
|
|
11
|
+
import { get_self_origin, is_csrf_forbidden, is_remote_forbidden } from './csrf.js';
|
|
12
|
+
import { has_prerendered_path, method_not_allowed, redirect_response } from './utils.js';
|
|
13
|
+
import { handle_fatal_error } from './errors.js';
|
|
18
14
|
import { decode_pathname, disable_search, normalize_path } from '../../utils/url.js';
|
|
19
15
|
import { find_route } from '../../utils/routing.js';
|
|
20
16
|
import { redirect_json_response, render_data } from './data/index.js';
|
|
@@ -36,7 +32,7 @@ import {
|
|
|
36
32
|
strip_resolution_suffix
|
|
37
33
|
} from '../pathname.js';
|
|
38
34
|
import { server_data_serializer } from './page/data_serializer.js';
|
|
39
|
-
import { get_remote_id, handle_remote_call } from './remote.js';
|
|
35
|
+
import { get_remote_id, handle_remote_call } from './remote-functions.js';
|
|
40
36
|
import { record_span } from '../telemetry/record_span.js';
|
|
41
37
|
import { otel } from '../telemetry/otel.js';
|
|
42
38
|
|
|
@@ -70,23 +66,28 @@ export async function internal_respond(request, options, manifest, state) {
|
|
|
70
66
|
const is_data_request = has_data_suffix(url.pathname);
|
|
71
67
|
const remote_id = get_remote_id(url);
|
|
72
68
|
|
|
73
|
-
if (!
|
|
69
|
+
if (!__SVELTEKIT_DEV__) {
|
|
74
70
|
const request_origin = request.headers.get('origin');
|
|
71
|
+
const self_origin = get_self_origin(options.paths_origin, url.origin);
|
|
75
72
|
|
|
76
73
|
if (remote_id) {
|
|
77
|
-
if (
|
|
74
|
+
if (
|
|
75
|
+
is_remote_forbidden({
|
|
76
|
+
request,
|
|
77
|
+
request_origin,
|
|
78
|
+
self_origin
|
|
79
|
+
})
|
|
80
|
+
) {
|
|
78
81
|
const message = 'Cross-site remote requests are forbidden';
|
|
79
82
|
return json({ message }, { status: 403 });
|
|
80
83
|
}
|
|
81
84
|
} else if (options.csrf_check_origin) {
|
|
82
|
-
const forbidden =
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
request_origin !== url.origin &&
|
|
89
|
-
(!request_origin || !options.csrf_trusted_origins.includes(request_origin));
|
|
85
|
+
const forbidden = is_csrf_forbidden({
|
|
86
|
+
request,
|
|
87
|
+
request_origin,
|
|
88
|
+
self_origin,
|
|
89
|
+
trusted_origins: options.csrf_trusted_origins
|
|
90
|
+
});
|
|
90
91
|
|
|
91
92
|
if (forbidden) {
|
|
92
93
|
const message = `Cross-site ${request.method} form submissions are forbidden`;
|
|
@@ -147,14 +148,16 @@ export async function internal_respond(request, options, manifest, state) {
|
|
|
147
148
|
},
|
|
148
149
|
remote: {
|
|
149
150
|
data: null,
|
|
151
|
+
explicit: null,
|
|
152
|
+
implicit: null,
|
|
150
153
|
forms: null,
|
|
151
|
-
refreshes: null,
|
|
152
154
|
requested: null,
|
|
153
|
-
reconnects: null,
|
|
154
155
|
batches: null,
|
|
155
156
|
live_iterators: null
|
|
156
157
|
},
|
|
157
158
|
is_in_remote_function: false,
|
|
159
|
+
is_in_remote_form_or_command: false,
|
|
160
|
+
is_in_remote_query: false,
|
|
158
161
|
is_in_render: false,
|
|
159
162
|
is_in_universal_load: false
|
|
160
163
|
};
|
|
@@ -317,7 +320,7 @@ export async function internal_respond(request, options, manifest, state) {
|
|
|
317
320
|
return resolve_route(resolved_path, new URL(request.url), manifest);
|
|
318
321
|
}
|
|
319
322
|
|
|
320
|
-
if (resolved_path === `/${app_dir}/env.js`
|
|
323
|
+
if (resolved_path === `/${app_dir}/env.js`) {
|
|
321
324
|
return get_public_env(request);
|
|
322
325
|
}
|
|
323
326
|
|
|
@@ -329,14 +332,17 @@ export async function internal_respond(request, options, manifest, state) {
|
|
|
329
332
|
}
|
|
330
333
|
|
|
331
334
|
if (!state.prerendering?.fallback) {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
335
|
+
try {
|
|
336
|
+
const matchers = await manifest._.matchers();
|
|
337
|
+
const result = find_route(resolved_path, manifest._.routes, matchers);
|
|
338
|
+
|
|
339
|
+
if (result) {
|
|
340
|
+
route = result.route;
|
|
341
|
+
event.route = { id: route.id };
|
|
342
|
+
event.params = result.params;
|
|
343
|
+
}
|
|
344
|
+
} catch (e) {
|
|
345
|
+
return await handle_fatal_error(event, event_state, options, e);
|
|
340
346
|
}
|
|
341
347
|
}
|
|
342
348
|
|
|
@@ -617,54 +623,80 @@ export async function internal_respond(request, options, manifest, state) {
|
|
|
617
623
|
invalidated_data_nodes,
|
|
618
624
|
trailing_slash
|
|
619
625
|
);
|
|
620
|
-
} else
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
const node = await manifest._.nodes[route.page.leaf]();
|
|
639
|
-
if (node?.server?.actions) {
|
|
640
|
-
allowed_methods.add('POST');
|
|
626
|
+
} else {
|
|
627
|
+
let endpoint;
|
|
628
|
+
if (
|
|
629
|
+
route.endpoint &&
|
|
630
|
+
(!route.page || (!state.prerendering && is_endpoint_request(event)))
|
|
631
|
+
) {
|
|
632
|
+
endpoint = await route.endpoint();
|
|
633
|
+
|
|
634
|
+
// Prefer rendering the page if the endpoint can't handle this GET or HEAD request
|
|
635
|
+
if (route.page && (method === 'GET' || method === 'HEAD')) {
|
|
636
|
+
const endpoint_can_handle = !!(
|
|
637
|
+
endpoint.GET ||
|
|
638
|
+
endpoint.fallback ||
|
|
639
|
+
(method === 'HEAD' && endpoint.HEAD)
|
|
640
|
+
);
|
|
641
|
+
if (!endpoint_can_handle) {
|
|
642
|
+
endpoint = undefined;
|
|
643
|
+
}
|
|
641
644
|
}
|
|
645
|
+
}
|
|
642
646
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
647
|
+
if (endpoint) {
|
|
648
|
+
response = await render_endpoint(event, event_state, endpoint, state);
|
|
649
|
+
} else if (route.page) {
|
|
650
|
+
if (!page_nodes) {
|
|
651
|
+
throw new Error('page_nodes not found. This should never happen');
|
|
652
|
+
} else if (page_methods.has(method)) {
|
|
653
|
+
response = await render_page(
|
|
654
|
+
event,
|
|
655
|
+
event_state,
|
|
656
|
+
route.page,
|
|
657
|
+
options,
|
|
658
|
+
manifest,
|
|
659
|
+
state,
|
|
660
|
+
page_nodes,
|
|
661
|
+
resolve_opts
|
|
662
|
+
);
|
|
652
663
|
} else {
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
664
|
+
const allowed_methods = new Set(allowed_page_methods);
|
|
665
|
+
const node = await manifest._.nodes[route.page.leaf]();
|
|
666
|
+
if (node?.server?.actions) {
|
|
667
|
+
allowed_methods.add('POST');
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
if (method === 'OPTIONS') {
|
|
671
|
+
// This will deny CORS preflight requests implicitly because we don't
|
|
672
|
+
// add the required CORS headers to the response.
|
|
673
|
+
response = new Response(null, {
|
|
674
|
+
status: 204,
|
|
675
|
+
headers: {
|
|
676
|
+
allow: Array.from(allowed_methods.values()).join(', ')
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
} else {
|
|
680
|
+
const mod = [...allowed_methods].reduce((acc, curr) => {
|
|
681
|
+
acc[curr] = true;
|
|
682
|
+
return acc;
|
|
683
|
+
}, /** @type {Record<string, any>} */ ({}));
|
|
684
|
+
response = method_not_allowed(mod, method);
|
|
685
|
+
}
|
|
658
686
|
}
|
|
687
|
+
} else {
|
|
688
|
+
// a route will always have a page or an endpoint, but TypeScript doesn't know that
|
|
689
|
+
throw new Error('Route is neither page nor endpoint. This should never happen');
|
|
659
690
|
}
|
|
660
|
-
} else {
|
|
661
|
-
// a route will always have a page or an endpoint, but TypeScript doesn't know that
|
|
662
|
-
throw new Error('Route is neither page nor endpoint. This should never happen');
|
|
663
691
|
}
|
|
664
692
|
|
|
665
693
|
// If the route contains a page and an endpoint, we need to add a
|
|
666
694
|
// `Vary: Accept` header to the response because of browser caching
|
|
667
|
-
if (
|
|
695
|
+
if (
|
|
696
|
+
(request.method === 'GET' || request.method === 'HEAD') &&
|
|
697
|
+
route.page &&
|
|
698
|
+
route.endpoint
|
|
699
|
+
) {
|
|
668
700
|
const vary = response.headers
|
|
669
701
|
.get('vary')
|
|
670
702
|
?.split(',')
|
|
@@ -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
|
+
}
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
/** @import { ServerHooks } from 'types' */
|
|
2
2
|
import * as devalue from 'devalue';
|
|
3
|
-
import {
|
|
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';
|
|
3
|
+
import { text } from '@sveltejs/kit';
|
|
10
4
|
import { ENDPOINT_METHODS } from '../../constants.js';
|
|
11
|
-
import { escape_html } from '../../utils/escape.js';
|
|
12
|
-
import * as path from '../../utils/path.js';
|
|
13
5
|
|
|
14
6
|
/**
|
|
15
7
|
* @param {Partial<Record<import('types').HttpMethod, any>>} mod
|
|
@@ -46,80 +38,6 @@ export function get_global_name(options) {
|
|
|
46
38
|
return __SVELTEKIT_DEV__ ? '__sveltekit_dev' : `__sveltekit_${options.version_hash}`;
|
|
47
39
|
}
|
|
48
40
|
|
|
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
41
|
/**
|
|
124
42
|
* @param {number} status
|
|
125
43
|
* @param {string} location
|
|
@@ -140,7 +58,7 @@ export function clarify_devalue_error(event, error) {
|
|
|
140
58
|
if (error.path) {
|
|
141
59
|
return (
|
|
142
60
|
`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#
|
|
61
|
+
`If you need to serialize/deserialize custom types, use transport hooks: https://svelte.dev/docs/kit/hooks#transport.`
|
|
144
62
|
);
|
|
145
63
|
}
|
|
146
64
|
|
|
@@ -189,56 +107,6 @@ export function has_prerendered_path(manifest, pathname) {
|
|
|
189
107
|
);
|
|
190
108
|
}
|
|
191
109
|
|
|
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
110
|
/**
|
|
243
111
|
* Returns the filename without the extension. e.g., `+page.server`, `+page`, etc.
|
|
244
112
|
* @param {string | undefined} node_id
|