@sveltejs/kit 1.0.0-next.44 → 1.0.0-next.442

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 (153) hide show
  1. package/README.md +12 -9
  2. package/package.json +94 -63
  3. package/src/cli.js +112 -0
  4. package/src/core/adapt/builder.js +223 -0
  5. package/src/core/adapt/index.js +19 -0
  6. package/src/core/config/index.js +86 -0
  7. package/src/core/config/options.js +488 -0
  8. package/src/core/config/types.d.ts +1 -0
  9. package/src/core/constants.js +5 -0
  10. package/src/core/env.js +97 -0
  11. package/src/core/generate_manifest/index.js +78 -0
  12. package/src/core/prerender/crawl.js +194 -0
  13. package/src/core/prerender/prerender.js +380 -0
  14. package/src/core/prerender/queue.js +80 -0
  15. package/src/core/sync/create_manifest_data/index.js +452 -0
  16. package/src/core/sync/create_manifest_data/types.d.ts +37 -0
  17. package/src/core/sync/sync.js +59 -0
  18. package/src/core/sync/utils.js +33 -0
  19. package/src/core/sync/write_ambient.js +27 -0
  20. package/src/core/sync/write_client_manifest.js +92 -0
  21. package/src/core/sync/write_matchers.js +25 -0
  22. package/src/core/sync/write_root.js +91 -0
  23. package/src/core/sync/write_tsconfig.js +195 -0
  24. package/src/core/sync/write_types/index.js +580 -0
  25. package/src/core/sync/write_types/test/layout/+layout.js +5 -0
  26. package/src/core/sync/write_types/test/layout/+layout.server.js +5 -0
  27. package/src/core/sync/write_types/test/layout/+layout.svelte +0 -0
  28. package/src/core/sync/write_types/test/layout/+page.js +5 -0
  29. package/src/core/sync/write_types/test/layout/+page.server.js +5 -0
  30. package/src/core/sync/write_types/test/layout/+page.svelte +0 -0
  31. package/src/core/sync/write_types/test/layout/_expected/$types.d.ts +67 -0
  32. package/src/core/sync/write_types/test/layout-advanced/(main)/+layout.server.js +5 -0
  33. package/src/core/sync/write_types/test/layout-advanced/(main)/+layout.svelte +0 -0
  34. package/src/core/sync/write_types/test/layout-advanced/(main)/+page.js +5 -0
  35. package/src/core/sync/write_types/test/layout-advanced/(main)/+page@.svelte +0 -0
  36. package/src/core/sync/write_types/test/layout-advanced/(main)/sub/+page.js +5 -0
  37. package/src/core/sync/write_types/test/layout-advanced/(main)/sub/+page.svelte +0 -0
  38. package/src/core/sync/write_types/test/layout-advanced/+layout.js +5 -0
  39. package/src/core/sync/write_types/test/layout-advanced/+layout.svelte +0 -0
  40. package/src/core/sync/write_types/test/layout-advanced/_expected/$types.d.ts +32 -0
  41. package/src/core/sync/write_types/test/layout-advanced/_expected/(main)/$types.d.ts +42 -0
  42. package/src/core/sync/write_types/test/layout-advanced/_expected/(main)/sub/$types.d.ts +33 -0
  43. package/src/core/sync/write_types/test/simple-page-server-and-shared/+page.js +5 -0
  44. package/src/core/sync/write_types/test/simple-page-server-and-shared/+page.server.js +5 -0
  45. package/src/core/sync/write_types/test/simple-page-server-and-shared/+page.svelte +0 -0
  46. package/src/core/sync/write_types/test/simple-page-server-and-shared/_expected/$types.d.ts +44 -0
  47. package/src/core/sync/write_types/test/simple-page-server-only/+page.server.js +5 -0
  48. package/src/core/sync/write_types/test/simple-page-server-only/+page.svelte +0 -0
  49. package/src/core/sync/write_types/test/simple-page-server-only/_expected/$types.d.ts +30 -0
  50. package/src/core/sync/write_types/test/simple-page-shared-only/+page.js +5 -0
  51. package/src/core/sync/write_types/test/simple-page-shared-only/+page.svelte +0 -0
  52. package/src/core/sync/write_types/test/simple-page-shared-only/_expected/$types.d.ts +33 -0
  53. package/src/core/sync/write_types/test/slugs/+layout.js +1 -0
  54. package/src/core/sync/write_types/test/slugs/+layout.svelte +1 -0
  55. package/src/core/sync/write_types/test/slugs/[...rest]/+page.js +3 -0
  56. package/src/core/sync/write_types/test/slugs/[...rest]/+page.svelte +0 -0
  57. package/src/core/sync/write_types/test/slugs/[slug]/+page.js +3 -0
  58. package/src/core/sync/write_types/test/slugs/[slug]/+page.svelte +0 -0
  59. package/src/core/sync/write_types/test/slugs/_expected/$types.d.ts +32 -0
  60. package/src/core/sync/write_types/test/slugs/_expected/[...rest]/$types.d.ts +29 -0
  61. package/src/core/sync/write_types/test/slugs/_expected/[slug]/$types.d.ts +29 -0
  62. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/+layout.js +1 -0
  63. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/+layout.svelte +1 -0
  64. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/_expected/$types.d.ts +30 -0
  65. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/_expected/nested/$types.d.ts +32 -0
  66. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/_expected/nested/[...rest]/$types.d.ts +37 -0
  67. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/_expected/nested/[slug]/$types.d.ts +17 -0
  68. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/nested/+layout.js +1 -0
  69. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/nested/+layout.svelte +1 -0
  70. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/nested/[...rest]/+page.js +3 -0
  71. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/nested/[...rest]/+page.svelte +0 -0
  72. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/nested/[slug]/+page@.svelte +0 -0
  73. package/src/core/utils.js +70 -0
  74. package/src/hooks.js +26 -0
  75. package/src/index/index.js +45 -0
  76. package/src/index/private.js +33 -0
  77. package/src/node/index.js +145 -0
  78. package/src/node/polyfills.js +40 -0
  79. package/src/runtime/app/env.js +11 -0
  80. package/src/runtime/app/navigation.js +22 -0
  81. package/src/runtime/app/paths.js +1 -0
  82. package/src/runtime/app/stores.js +102 -0
  83. package/src/runtime/client/ambient.d.ts +18 -0
  84. package/src/runtime/client/client.js +1362 -0
  85. package/src/runtime/client/fetcher.js +60 -0
  86. package/src/runtime/client/parse.js +41 -0
  87. package/src/runtime/client/singletons.js +21 -0
  88. package/src/runtime/client/start.js +46 -0
  89. package/src/runtime/client/types.d.ts +86 -0
  90. package/src/runtime/client/utils.js +113 -0
  91. package/src/runtime/components/error.svelte +16 -0
  92. package/{assets → src/runtime}/components/layout.svelte +0 -0
  93. package/src/runtime/env/dynamic/private.js +1 -0
  94. package/src/runtime/env/dynamic/public.js +1 -0
  95. package/src/runtime/env-private.js +7 -0
  96. package/src/runtime/env-public.js +7 -0
  97. package/src/runtime/env.js +6 -0
  98. package/src/runtime/hash.js +16 -0
  99. package/src/runtime/paths.js +11 -0
  100. package/src/runtime/server/endpoint.js +50 -0
  101. package/src/runtime/server/index.js +492 -0
  102. package/src/runtime/server/page/cookie.js +25 -0
  103. package/src/runtime/server/page/crypto.js +239 -0
  104. package/src/runtime/server/page/csp.js +249 -0
  105. package/src/runtime/server/page/fetch.js +266 -0
  106. package/src/runtime/server/page/index.js +408 -0
  107. package/src/runtime/server/page/load_data.js +168 -0
  108. package/src/runtime/server/page/render.js +361 -0
  109. package/src/runtime/server/page/respond_with_error.js +95 -0
  110. package/src/runtime/server/page/types.d.ts +44 -0
  111. package/src/runtime/server/utils.js +116 -0
  112. package/src/utils/array.js +9 -0
  113. package/src/utils/error.js +22 -0
  114. package/src/utils/escape.js +104 -0
  115. package/src/utils/filesystem.js +108 -0
  116. package/src/utils/functions.js +16 -0
  117. package/src/utils/http.js +55 -0
  118. package/src/utils/misc.js +1 -0
  119. package/src/utils/routing.js +146 -0
  120. package/src/utils/url.js +142 -0
  121. package/src/vite/build/build_server.js +348 -0
  122. package/src/vite/build/build_service_worker.js +90 -0
  123. package/src/vite/build/utils.js +160 -0
  124. package/src/vite/dev/index.js +543 -0
  125. package/src/vite/index.js +578 -0
  126. package/src/vite/preview/index.js +186 -0
  127. package/src/vite/types.d.ts +3 -0
  128. package/src/vite/utils.js +345 -0
  129. package/svelte-kit.js +1 -1
  130. package/types/ambient.d.ts +366 -0
  131. package/types/index.d.ts +345 -0
  132. package/types/internal.d.ts +374 -0
  133. package/types/private.d.ts +209 -0
  134. package/CHANGELOG.md +0 -437
  135. package/assets/components/error.svelte +0 -13
  136. package/assets/runtime/app/env.js +0 -5
  137. package/assets/runtime/app/navigation.js +0 -41
  138. package/assets/runtime/app/paths.js +0 -1
  139. package/assets/runtime/app/stores.js +0 -93
  140. package/assets/runtime/chunks/utils.js +0 -19
  141. package/assets/runtime/internal/singletons.js +0 -23
  142. package/assets/runtime/internal/start.js +0 -770
  143. package/assets/runtime/paths.js +0 -12
  144. package/dist/chunks/index.js +0 -3521
  145. package/dist/chunks/index2.js +0 -587
  146. package/dist/chunks/index3.js +0 -246
  147. package/dist/chunks/index4.js +0 -545
  148. package/dist/chunks/index5.js +0 -761
  149. package/dist/chunks/index6.js +0 -322
  150. package/dist/chunks/standard.js +0 -99
  151. package/dist/chunks/utils.js +0 -83
  152. package/dist/cli.js +0 -546
  153. package/dist/ssr.js +0 -2580
@@ -0,0 +1,492 @@
1
+ import { render_endpoint } from './endpoint.js';
2
+ import { render_page } from './page/index.js';
3
+ import { render_response } from './page/render.js';
4
+ import { respond_with_error } from './page/respond_with_error.js';
5
+ import { coalesce_to_error, normalize_error } from '../../utils/error.js';
6
+ import { serialize_error, GENERIC_ERROR, error_to_pojo } from './utils.js';
7
+ import { decode_params, disable_search, normalize_path } from '../../utils/url.js';
8
+ import { exec } from '../../utils/routing.js';
9
+ import { negotiate } from '../../utils/http.js';
10
+ import { HttpError, Redirect } from '../../index/private.js';
11
+ import { load_server_data } from './page/load_data.js';
12
+ import { json } from '../../index/index.js';
13
+ import { once } from '../../utils/functions.js';
14
+
15
+ /* global __SVELTEKIT_ADAPTER_NAME__ */
16
+
17
+ const DATA_SUFFIX = '/__data.json';
18
+
19
+ /** @param {{ html: string }} opts */
20
+ const default_transform = ({ html }) => html;
21
+
22
+ /** @type {import('types').Respond} */
23
+ export async function respond(request, options, state) {
24
+ let url = new URL(request.url);
25
+
26
+ const { parameter, allowed } = options.method_override;
27
+ const method_override = url.searchParams.get(parameter)?.toUpperCase();
28
+
29
+ if (method_override) {
30
+ if (request.method === 'POST') {
31
+ if (allowed.includes(method_override)) {
32
+ request = new Proxy(request, {
33
+ get: (target, property, _receiver) => {
34
+ if (property === 'method') return method_override;
35
+ return Reflect.get(target, property, target);
36
+ }
37
+ });
38
+ } else {
39
+ const verb = allowed.length === 0 ? 'enabled' : 'allowed';
40
+ const body = `${parameter}=${method_override} is not ${verb}. See https://kit.svelte.dev/docs/configuration#methodoverride`;
41
+
42
+ return new Response(body, {
43
+ status: 400
44
+ });
45
+ }
46
+ } else {
47
+ throw new Error(`${parameter}=${method_override} is only allowed with POST requests`);
48
+ }
49
+ }
50
+
51
+ let decoded;
52
+ try {
53
+ decoded = decodeURI(url.pathname);
54
+ } catch {
55
+ return new Response('Malformed URI', { status: 400 });
56
+ }
57
+
58
+ /** @type {import('types').SSRRoute | null} */
59
+ let route = null;
60
+
61
+ /** @type {Record<string, string>} */
62
+ let params = {};
63
+
64
+ if (options.paths.base && !state.prerendering?.fallback) {
65
+ if (!decoded.startsWith(options.paths.base)) {
66
+ return new Response('Not found', { status: 404 });
67
+ }
68
+ decoded = decoded.slice(options.paths.base.length) || '/';
69
+ }
70
+
71
+ const is_data_request = decoded.endsWith(DATA_SUFFIX);
72
+
73
+ if (is_data_request) {
74
+ const data_suffix_length = DATA_SUFFIX.length - (options.trailing_slash === 'always' ? 1 : 0);
75
+ decoded = decoded.slice(0, -data_suffix_length) || '/';
76
+ url = new URL(url.origin + url.pathname.slice(0, -data_suffix_length) + url.search);
77
+ }
78
+
79
+ if (!state.prerendering?.fallback) {
80
+ const matchers = await options.manifest._.matchers();
81
+
82
+ for (const candidate of options.manifest._.routes) {
83
+ const match = candidate.pattern.exec(decoded);
84
+ if (!match) continue;
85
+
86
+ const matched = exec(match, candidate.names, candidate.types, matchers);
87
+ if (matched) {
88
+ route = candidate;
89
+ params = decode_params(matched);
90
+ break;
91
+ }
92
+ }
93
+ }
94
+
95
+ if (route) {
96
+ if (route.page) {
97
+ const normalized = normalize_path(url.pathname, options.trailing_slash);
98
+
99
+ if (normalized !== url.pathname && !state.prerendering?.fallback) {
100
+ return new Response(undefined, {
101
+ status: 301,
102
+ headers: {
103
+ 'x-sveltekit-normalize': '1',
104
+ location:
105
+ // ensure paths starting with '//' are not treated as protocol-relative
106
+ (normalized.startsWith('//') ? url.origin + normalized : normalized) +
107
+ (url.search === '?' ? '' : url.search)
108
+ }
109
+ });
110
+ }
111
+ } else if (is_data_request) {
112
+ // requesting /__data.json should fail for a standalone endpoint
113
+ return new Response(undefined, {
114
+ status: 404
115
+ });
116
+ }
117
+ }
118
+
119
+ /** @type {import('types').ResponseHeaders} */
120
+ const headers = {};
121
+
122
+ /** @type {string[]} */
123
+ const cookies = [];
124
+
125
+ if (state.prerendering) disable_search(url);
126
+
127
+ /** @type {import('types').RequestEvent} */
128
+ const event = {
129
+ getClientAddress:
130
+ state.getClientAddress ||
131
+ (() => {
132
+ throw new Error(
133
+ `${__SVELTEKIT_ADAPTER_NAME__} does not specify getClientAddress. Please raise an issue`
134
+ );
135
+ }),
136
+ locals: {},
137
+ params,
138
+ platform: state.platform,
139
+ request,
140
+ routeId: route && route.id,
141
+ setHeaders: (new_headers) => {
142
+ for (const key in new_headers) {
143
+ const lower = key.toLowerCase();
144
+ const value = new_headers[key];
145
+
146
+ if (lower === 'set-cookie') {
147
+ const new_cookies = /** @type {string[]} */ (Array.isArray(value) ? value : [value]);
148
+
149
+ for (const cookie of new_cookies) {
150
+ if (cookies.includes(cookie)) {
151
+ throw new Error(`"${key}" header already has cookie with same value`);
152
+ }
153
+
154
+ cookies.push(cookie);
155
+ }
156
+ } else if (lower in headers) {
157
+ throw new Error(`"${key}" header is already set`);
158
+ } else {
159
+ headers[lower] = value;
160
+
161
+ if (state.prerendering && lower === 'cache-control') {
162
+ state.prerendering.cache = /** @type {string} */ (value);
163
+ }
164
+ }
165
+ }
166
+ },
167
+ url
168
+ };
169
+
170
+ // TODO remove this for 1.0
171
+ /**
172
+ * @param {string} property
173
+ * @param {string} replacement
174
+ * @param {string} suffix
175
+ */
176
+ const removed = (property, replacement, suffix = '') => ({
177
+ get: () => {
178
+ throw new Error(`event.${property} has been replaced by event.${replacement}` + suffix);
179
+ }
180
+ });
181
+
182
+ const details = '. See https://github.com/sveltejs/kit/pull/3384 for details';
183
+
184
+ const body_getter = {
185
+ get: () => {
186
+ throw new Error(
187
+ 'To access the request body use the text/json/arrayBuffer/formData methods, e.g. `body = await request.json()`' +
188
+ details
189
+ );
190
+ }
191
+ };
192
+
193
+ Object.defineProperties(event, {
194
+ clientAddress: removed('clientAddress', 'getClientAddress'),
195
+ method: removed('method', 'request.method', details),
196
+ headers: removed('headers', 'request.headers', details),
197
+ origin: removed('origin', 'url.origin'),
198
+ path: removed('path', 'url.pathname'),
199
+ query: removed('query', 'url.searchParams'),
200
+ body: body_getter,
201
+ rawBody: body_getter
202
+ });
203
+
204
+ /** @type {import('types').RequiredResolveOptions} */
205
+ let resolve_opts = {
206
+ ssr: true,
207
+ transformPageChunk: default_transform
208
+ };
209
+
210
+ // TODO match route before calling handle?
211
+
212
+ try {
213
+ const response = await options.hooks.handle({
214
+ event,
215
+ resolve: async (event, opts) => {
216
+ if (opts) {
217
+ // TODO remove for 1.0
218
+ // @ts-expect-error
219
+ if (opts.transformPage) {
220
+ throw new Error(
221
+ 'transformPage has been replaced by transformPageChunk — see https://github.com/sveltejs/kit/pull/5657 for more information'
222
+ );
223
+ }
224
+
225
+ resolve_opts = {
226
+ ssr: opts.ssr !== false,
227
+ transformPageChunk: opts.transformPageChunk || default_transform
228
+ };
229
+ }
230
+
231
+ if (state.prerendering?.fallback) {
232
+ return await render_response({
233
+ event,
234
+ options,
235
+ state,
236
+ page_config: { router: true, hydrate: true },
237
+ status: 200,
238
+ error: null,
239
+ branch: [],
240
+ fetched: [],
241
+ validation_errors: undefined,
242
+ cookies: [],
243
+ resolve_opts: {
244
+ ...resolve_opts,
245
+ ssr: false
246
+ }
247
+ });
248
+ }
249
+
250
+ if (route) {
251
+ /** @type {Response} */
252
+ let response;
253
+ if (is_data_request && route.page) {
254
+ try {
255
+ const node_ids = [...route.page.layouts, route.page.leaf];
256
+
257
+ const invalidated =
258
+ request.headers.get('x-sveltekit-invalidated')?.split(',').map(Boolean) ??
259
+ node_ids.map(() => true);
260
+
261
+ let aborted = false;
262
+
263
+ const functions = node_ids.map((n, i) => {
264
+ return once(async () => {
265
+ try {
266
+ if (aborted) {
267
+ return /** @type {import('types').ServerDataSkippedNode} */ ({
268
+ type: 'skip'
269
+ });
270
+ }
271
+
272
+ // == because it could be undefined (in dev) or null (in build, because of JSON.stringify)
273
+ const node = n == undefined ? n : await options.manifest._.nodes[n]();
274
+ return load_server_data({
275
+ dev: options.dev,
276
+ event,
277
+ state,
278
+ node,
279
+ parent: async () => {
280
+ /** @type {Record<string, any>} */
281
+ const data = {};
282
+ for (let j = 0; j < i; j += 1) {
283
+ const parent = /** @type {import('types').ServerDataNode | null} */ (
284
+ await functions[j]()
285
+ );
286
+
287
+ if (parent) {
288
+ Object.assign(data, parent.data);
289
+ }
290
+ }
291
+ return data;
292
+ }
293
+ });
294
+ } catch (e) {
295
+ aborted = true;
296
+ throw e;
297
+ }
298
+ });
299
+ });
300
+
301
+ const promises = functions.map(async (fn, i) => {
302
+ if (!invalidated[i]) {
303
+ return /** @type {import('types').ServerDataSkippedNode} */ ({
304
+ type: 'skip'
305
+ });
306
+ }
307
+
308
+ return fn();
309
+ });
310
+
311
+ let length = promises.length;
312
+ const nodes = await Promise.all(
313
+ promises.map((p, i) =>
314
+ p.catch((e) => {
315
+ const error = normalize_error(e);
316
+
317
+ if (error instanceof Redirect) {
318
+ throw error;
319
+ }
320
+
321
+ // Math.min because array isn't guaranteed to resolve in order
322
+ length = Math.min(length, i + 1);
323
+
324
+ if (error instanceof HttpError) {
325
+ return /** @type {import('types').ServerErrorNode} */ ({
326
+ type: 'error',
327
+ httperror: { ...error }
328
+ });
329
+ }
330
+
331
+ options.handle_error(error, event);
332
+
333
+ return /** @type {import('types').ServerErrorNode} */ ({
334
+ type: 'error',
335
+ error: error_to_pojo(error, options.get_stack)
336
+ });
337
+ })
338
+ )
339
+ );
340
+
341
+ /** @type {import('types').ServerData} */
342
+ const server_data = {
343
+ type: 'data',
344
+ nodes: nodes.slice(0, length)
345
+ };
346
+
347
+ response = json(server_data);
348
+ } catch (e) {
349
+ const error = normalize_error(e);
350
+
351
+ if (error instanceof Redirect) {
352
+ /** @type {import('types').ServerData} */
353
+ const server_data = {
354
+ type: 'redirect',
355
+ location: error.location
356
+ };
357
+
358
+ response = json(server_data);
359
+ } else {
360
+ response = json(error_to_pojo(error, options.get_stack), { status: 500 });
361
+ }
362
+ }
363
+ } else if (route.page) {
364
+ response = await render_page(event, route, route.page, options, state, resolve_opts);
365
+ } else if (route.endpoint) {
366
+ response = await render_endpoint(event, await route.endpoint());
367
+ } else {
368
+ // a route will always have a page or an endpoint, but TypeScript
369
+ // doesn't know that
370
+ throw new Error('This should never happen');
371
+ }
372
+
373
+ if (!is_data_request) {
374
+ // we only want to set cookies on __data.json requests, we don't
375
+ // want to cache stuff erroneously etc
376
+ for (const key in headers) {
377
+ const value = headers[key];
378
+ response.headers.set(key, /** @type {string} */ (value));
379
+ }
380
+ }
381
+
382
+ for (const cookie of cookies) {
383
+ response.headers.append('set-cookie', cookie);
384
+ }
385
+
386
+ // respond with 304 if etag matches
387
+ if (response.status === 200 && response.headers.has('etag')) {
388
+ let if_none_match_value = request.headers.get('if-none-match');
389
+
390
+ // ignore W/ prefix https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match#directives
391
+ if (if_none_match_value?.startsWith('W/"')) {
392
+ if_none_match_value = if_none_match_value.substring(2);
393
+ }
394
+
395
+ const etag = /** @type {string} */ (response.headers.get('etag'));
396
+
397
+ if (if_none_match_value === etag) {
398
+ const headers = new Headers({ etag });
399
+
400
+ // https://datatracker.ietf.org/doc/html/rfc7232#section-4.1
401
+ for (const key of ['cache-control', 'content-location', 'date', 'expires', 'vary']) {
402
+ const value = response.headers.get(key);
403
+ if (value) headers.set(key, value);
404
+ }
405
+
406
+ return new Response(undefined, {
407
+ status: 304,
408
+ headers
409
+ });
410
+ }
411
+ }
412
+
413
+ return response;
414
+ }
415
+
416
+ if (state.initiator === GENERIC_ERROR) {
417
+ return new Response('Internal Server Error', {
418
+ status: 500
419
+ });
420
+ }
421
+
422
+ // if this request came direct from the user, rather than
423
+ // via a `fetch` in a `load`, render a 404 page
424
+ if (!state.initiator) {
425
+ return await respond_with_error({
426
+ event,
427
+ options,
428
+ state,
429
+ status: 404,
430
+ error: new Error(`Not found: ${event.url.pathname}`),
431
+ resolve_opts
432
+ });
433
+ }
434
+
435
+ if (state.prerendering) {
436
+ return new Response('not found', { status: 404 });
437
+ }
438
+
439
+ // we can't load the endpoint from our own manifest,
440
+ // so we need to make an actual HTTP request
441
+ return await fetch(request);
442
+ },
443
+
444
+ // TODO remove for 1.0
445
+ // @ts-expect-error
446
+ get request() {
447
+ throw new Error('request in handle has been replaced with event' + details);
448
+ }
449
+ });
450
+
451
+ // TODO for 1.0, change the error message to point to docs rather than PR
452
+ if (response && !(response instanceof Response)) {
453
+ throw new Error('handle must return a Response object' + details);
454
+ }
455
+
456
+ return response;
457
+ } catch (/** @type {unknown} */ e) {
458
+ const error = coalesce_to_error(e);
459
+
460
+ options.handle_error(error, event);
461
+
462
+ const type = negotiate(event.request.headers.get('accept') || 'text/html', [
463
+ 'text/html',
464
+ 'application/json'
465
+ ]);
466
+
467
+ if (is_data_request || type === 'application/json') {
468
+ return new Response(serialize_error(error, options.get_stack), {
469
+ status: 500,
470
+ headers: { 'content-type': 'application/json; charset=utf-8' }
471
+ });
472
+ }
473
+
474
+ // TODO is this necessary? should we just return a plain 500 at this point?
475
+ try {
476
+ return await respond_with_error({
477
+ event,
478
+ options,
479
+ state,
480
+ status: 500,
481
+ error,
482
+ resolve_opts
483
+ });
484
+ } catch (/** @type {unknown} */ e) {
485
+ const error = coalesce_to_error(e);
486
+
487
+ return new Response(options.dev ? error.stack : error.message, {
488
+ status: 500
489
+ });
490
+ }
491
+ }
492
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @param {string} hostname
3
+ * @param {string} [constraint]
4
+ */
5
+ export function domain_matches(hostname, constraint) {
6
+ if (!constraint) return true;
7
+
8
+ const normalized = constraint[0] === '.' ? constraint.slice(1) : constraint;
9
+
10
+ if (hostname === normalized) return true;
11
+ return hostname.endsWith('.' + normalized);
12
+ }
13
+
14
+ /**
15
+ * @param {string} path
16
+ * @param {string} [constraint]
17
+ */
18
+ export function path_matches(path, constraint) {
19
+ if (!constraint) return true;
20
+
21
+ const normalized = constraint.endsWith('/') ? constraint.slice(0, -1) : constraint;
22
+
23
+ if (path === normalized) return true;
24
+ return path.startsWith(normalized + '/');
25
+ }