@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.
Files changed (144) hide show
  1. package/package.json +33 -21
  2. package/src/constants.js +2 -0
  3. package/src/core/adapt/builder.js +32 -49
  4. package/src/core/adapt/index.js +1 -4
  5. package/src/core/config/index.js +137 -71
  6. package/src/core/config/options.js +236 -244
  7. package/src/core/config/types.d.ts +1 -1
  8. package/src/core/env.js +121 -5
  9. package/src/core/generate_manifest/index.js +12 -15
  10. package/src/core/postbuild/analyse.js +7 -19
  11. package/src/core/postbuild/crawl.js +22 -6
  12. package/src/core/postbuild/fallback.js +2 -1
  13. package/src/core/postbuild/prerender.js +114 -48
  14. package/src/core/postbuild/queue.js +2 -1
  15. package/src/core/sync/create_manifest_data/index.js +53 -50
  16. package/src/core/sync/sync.js +0 -2
  17. package/src/core/sync/write_client_manifest.js +8 -15
  18. package/src/core/sync/write_env.js +2 -1
  19. package/src/core/sync/write_non_ambient.js +12 -9
  20. package/src/core/sync/write_server.js +14 -15
  21. package/src/core/sync/write_tsconfig.js +16 -8
  22. package/src/core/sync/write_tsconfig_test/package.json +7 -0
  23. package/src/core/sync/write_types/index.js +28 -24
  24. package/src/core/utils.js +30 -5
  25. package/src/exports/env/index.js +77 -0
  26. package/src/exports/hooks/index.js +3 -9
  27. package/src/exports/hooks/sequence.js +3 -2
  28. package/src/exports/index.js +35 -13
  29. package/src/exports/internal/client.js +5 -0
  30. package/src/exports/internal/env.js +8 -5
  31. package/src/exports/internal/index.js +1 -90
  32. package/src/exports/internal/{event.js → server/event.js} +1 -2
  33. package/src/exports/internal/server/index.js +33 -0
  34. package/src/exports/internal/shared.js +89 -0
  35. package/src/exports/node/index.js +62 -15
  36. package/src/exports/params.js +68 -0
  37. package/src/exports/public.d.ts +363 -189
  38. package/src/exports/url.js +86 -0
  39. package/src/exports/vite/build/build_server.js +53 -59
  40. package/src/exports/vite/build/remote.js +18 -11
  41. package/src/exports/vite/build/utils.js +0 -8
  42. package/src/exports/vite/dev/index.js +92 -50
  43. package/src/exports/vite/index.js +903 -681
  44. package/src/exports/vite/module_ids.js +0 -2
  45. package/src/exports/vite/preview/index.js +32 -24
  46. package/src/exports/vite/static_analysis/index.js +2 -4
  47. package/src/exports/vite/static_analysis/types.d.ts +14 -0
  48. package/src/exports/vite/utils.js +40 -35
  49. package/src/runtime/app/env/internal.js +4 -4
  50. package/src/runtime/app/env/types.d.ts +1 -1
  51. package/src/runtime/app/environment/index.js +3 -3
  52. package/src/runtime/app/forms.js +24 -7
  53. package/src/runtime/app/paths/client.js +4 -10
  54. package/src/runtime/app/paths/internal/client.js +4 -2
  55. package/src/runtime/app/paths/internal/server.js +2 -23
  56. package/src/runtime/app/paths/public.d.ts +0 -28
  57. package/src/runtime/app/paths/server.js +10 -6
  58. package/src/runtime/app/server/index.js +1 -1
  59. package/src/runtime/app/server/remote/command.js +0 -3
  60. package/src/runtime/app/server/remote/form.js +27 -15
  61. package/src/runtime/app/server/remote/prerender.js +29 -36
  62. package/src/runtime/app/server/remote/query.js +101 -99
  63. package/src/runtime/app/server/remote/requested.js +22 -14
  64. package/src/runtime/app/server/remote/shared.js +30 -26
  65. package/src/runtime/app/state/client.js +1 -2
  66. package/src/runtime/app/stores.js +13 -76
  67. package/src/runtime/client/bundle.js +1 -1
  68. package/src/runtime/client/client-entry.js +3 -0
  69. package/src/runtime/client/client.js +411 -318
  70. package/src/runtime/client/entry.js +24 -3
  71. package/src/runtime/client/fetcher.js +3 -2
  72. package/src/runtime/client/ndjson.js +6 -33
  73. package/src/runtime/client/payload.js +17 -0
  74. package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
  75. package/src/runtime/client/remote-functions/command.svelte.js +7 -32
  76. package/src/runtime/client/remote-functions/form.svelte.js +183 -112
  77. package/src/runtime/client/remote-functions/prerender.svelte.js +29 -8
  78. package/src/runtime/client/remote-functions/query/index.js +7 -14
  79. package/src/runtime/client/remote-functions/query/instance.svelte.js +63 -18
  80. package/src/runtime/client/remote-functions/query/proxy.js +3 -3
  81. package/src/runtime/client/remote-functions/query-batch.svelte.js +60 -68
  82. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +60 -18
  83. package/src/runtime/client/remote-functions/query-live/iterator.js +36 -55
  84. package/src/runtime/client/remote-functions/shared.svelte.js +88 -62
  85. package/src/runtime/client/sse.js +32 -0
  86. package/src/runtime/client/state.svelte.js +65 -49
  87. package/src/runtime/client/stream.js +39 -0
  88. package/src/runtime/client/types.d.ts +11 -7
  89. package/src/runtime/client/utils.js +0 -96
  90. package/src/runtime/components/root.svelte +66 -0
  91. package/src/runtime/env/dynamic/private.js +7 -0
  92. package/src/runtime/env/dynamic/public.js +7 -0
  93. package/src/runtime/env/static/private.js +6 -0
  94. package/src/runtime/env/static/public.js +6 -0
  95. package/src/runtime/form-utils.js +100 -22
  96. package/src/runtime/server/cookie.js +69 -52
  97. package/src/runtime/server/csrf.js +65 -0
  98. package/src/runtime/server/data/index.js +15 -19
  99. package/src/runtime/server/env_module.js +0 -5
  100. package/src/runtime/server/errors.js +135 -0
  101. package/src/runtime/server/fetch.js +1 -1
  102. package/src/runtime/server/index.js +22 -12
  103. package/src/runtime/server/internal.js +25 -0
  104. package/src/runtime/server/page/actions.js +43 -27
  105. package/src/runtime/server/page/data_serializer.js +10 -10
  106. package/src/runtime/server/page/index.js +12 -17
  107. package/src/runtime/server/page/load_data.js +2 -2
  108. package/src/runtime/server/page/render.js +114 -193
  109. package/src/runtime/server/page/respond_with_error.js +11 -11
  110. package/src/runtime/server/page/server_routing.js +27 -18
  111. package/src/runtime/server/remote-functions.js +596 -0
  112. package/src/runtime/server/respond.js +100 -68
  113. package/src/runtime/server/sourcemaps.js +183 -0
  114. package/src/runtime/server/utils.js +2 -134
  115. package/src/runtime/shared.js +83 -13
  116. package/src/runtime/telemetry/otel.js +1 -1
  117. package/src/runtime/types.d.ts +8 -0
  118. package/src/types/ambient-private.d.ts +2 -0
  119. package/src/types/ambient.d.ts +10 -5
  120. package/src/types/global-private.d.ts +13 -25
  121. package/src/types/internal.d.ts +95 -80
  122. package/src/types/private.d.ts +41 -1
  123. package/src/utils/error.js +24 -4
  124. package/src/utils/escape.js +9 -25
  125. package/src/utils/features.js +1 -1
  126. package/src/utils/fork.js +7 -2
  127. package/src/utils/import.js +6 -1
  128. package/src/utils/imports.js +83 -0
  129. package/src/utils/mime.js +9 -0
  130. package/src/utils/page_nodes.js +3 -5
  131. package/src/utils/params.js +66 -0
  132. package/src/utils/routing.js +90 -44
  133. package/src/utils/shared-iterator.js +5 -0
  134. package/src/utils/streaming.js +14 -4
  135. package/src/utils/url.js +20 -2
  136. package/src/version.js +1 -1
  137. package/types/index.d.ts +537 -557
  138. package/types/index.d.ts.map +24 -39
  139. package/src/core/sync/write_root.js +0 -148
  140. package/src/exports/internal/server.js +0 -22
  141. package/src/runtime/server/remote.js +0 -457
  142. package/src/runtime/shared-server.js +0 -7
  143. package/src/types/synthetic/$lib.md +0 -5
  144. /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 { is_form_content_type } from '../../utils/http.js';
12
- import {
13
- handle_fatal_error,
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 (!DEV) {
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 (request.method !== 'GET' && request_origin !== url.origin) {
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
- is_form_content_type(request) &&
84
- (request.method === 'POST' ||
85
- request.method === 'PUT' ||
86
- request.method === 'PATCH' ||
87
- request.method === 'DELETE') &&
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` || resolved_path === `/${app_dir}/env.script.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
- // TODO this could theoretically break — should probably be inside a try-catch
333
- const matchers = await manifest._.matchers();
334
- const result = find_route(resolved_path, manifest._.routes, matchers);
335
-
336
- if (result) {
337
- route = result.route;
338
- event.route = { id: route.id };
339
- event.params = result.params;
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 if (route.endpoint && (!route.page || is_endpoint_request(event))) {
621
- response = await render_endpoint(event, event_state, await route.endpoint(), state);
622
- } else if (route.page) {
623
- if (!page_nodes) {
624
- throw new Error('page_nodes not found. This should never happen');
625
- } else if (page_methods.has(method)) {
626
- response = await render_page(
627
- event,
628
- event_state,
629
- route.page,
630
- options,
631
- manifest,
632
- state,
633
- page_nodes,
634
- resolve_opts
635
- );
636
- } else {
637
- const allowed_methods = new Set(allowed_page_methods);
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
- if (method === 'OPTIONS') {
644
- // This will deny CORS preflight requests implicitly because we don't
645
- // add the required CORS headers to the response.
646
- response = new Response(null, {
647
- status: 204,
648
- headers: {
649
- allow: Array.from(allowed_methods.values()).join(', ')
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 mod = [...allowed_methods].reduce((acc, curr) => {
654
- acc[curr] = true;
655
- return acc;
656
- }, /** @type {Record<string, any>} */ ({}));
657
- response = method_not_allowed(mod, method);
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 (request.method === 'GET' && route.page && route.endpoint) {
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 { 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';
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#Universal-hooks-transport.`
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