@sveltejs/kit 1.0.0-next.47 → 1.0.0-next.470

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 (115) hide show
  1. package/README.md +12 -9
  2. package/package.json +93 -64
  3. package/scripts/special-types/$env+dynamic+private.md +8 -0
  4. package/scripts/special-types/$env+dynamic+public.md +8 -0
  5. package/scripts/special-types/$env+static+private.md +19 -0
  6. package/scripts/special-types/$env+static+public.md +7 -0
  7. package/scripts/special-types/$lib.md +1 -0
  8. package/src/cli.js +112 -0
  9. package/src/constants.js +7 -0
  10. package/src/core/adapt/builder.js +207 -0
  11. package/src/core/adapt/index.js +31 -0
  12. package/src/core/config/default-error.html +56 -0
  13. package/src/core/config/index.js +105 -0
  14. package/src/core/config/options.js +502 -0
  15. package/src/core/config/types.d.ts +1 -0
  16. package/src/core/env.js +121 -0
  17. package/src/core/generate_manifest/index.js +92 -0
  18. package/src/core/prerender/crawl.js +194 -0
  19. package/src/core/prerender/prerender.js +425 -0
  20. package/src/core/prerender/queue.js +80 -0
  21. package/src/core/sync/create_manifest_data/index.js +472 -0
  22. package/src/core/sync/create_manifest_data/types.d.ts +37 -0
  23. package/src/core/sync/sync.js +59 -0
  24. package/src/core/sync/utils.js +33 -0
  25. package/src/core/sync/write_ambient.js +53 -0
  26. package/src/core/sync/write_client_manifest.js +94 -0
  27. package/src/core/sync/write_matchers.js +25 -0
  28. package/src/core/sync/write_root.js +91 -0
  29. package/src/core/sync/write_tsconfig.js +195 -0
  30. package/src/core/sync/write_types/index.js +595 -0
  31. package/src/core/utils.js +70 -0
  32. package/src/exports/hooks/index.js +1 -0
  33. package/src/exports/hooks/sequence.js +44 -0
  34. package/src/exports/index.js +45 -0
  35. package/src/exports/node/index.js +145 -0
  36. package/src/exports/node/polyfills.js +40 -0
  37. package/src/exports/vite/build/build_server.js +358 -0
  38. package/src/exports/vite/build/build_service_worker.js +90 -0
  39. package/src/exports/vite/build/utils.js +162 -0
  40. package/src/exports/vite/dev/index.js +547 -0
  41. package/src/exports/vite/index.js +601 -0
  42. package/src/exports/vite/preview/index.js +186 -0
  43. package/src/exports/vite/types.d.ts +3 -0
  44. package/src/exports/vite/utils.js +345 -0
  45. package/src/runtime/app/env.js +1 -0
  46. package/src/runtime/app/environment.js +11 -0
  47. package/src/runtime/app/navigation.js +23 -0
  48. package/src/runtime/app/paths.js +1 -0
  49. package/src/runtime/app/stores.js +102 -0
  50. package/src/runtime/client/ambient.d.ts +24 -0
  51. package/src/runtime/client/client.js +1494 -0
  52. package/src/runtime/client/fetcher.js +107 -0
  53. package/src/runtime/client/parse.js +60 -0
  54. package/src/runtime/client/singletons.js +21 -0
  55. package/src/runtime/client/start.js +45 -0
  56. package/src/runtime/client/types.d.ts +91 -0
  57. package/src/runtime/client/utils.js +159 -0
  58. package/src/runtime/components/error.svelte +16 -0
  59. package/{assets → src/runtime}/components/layout.svelte +0 -0
  60. package/src/runtime/control.js +33 -0
  61. package/src/runtime/env/dynamic/private.js +1 -0
  62. package/src/runtime/env/dynamic/public.js +1 -0
  63. package/src/runtime/env-private.js +6 -0
  64. package/src/runtime/env-public.js +6 -0
  65. package/src/runtime/env.js +6 -0
  66. package/src/runtime/hash.js +16 -0
  67. package/src/runtime/paths.js +11 -0
  68. package/src/runtime/server/data/index.js +146 -0
  69. package/src/runtime/server/endpoint.js +63 -0
  70. package/src/runtime/server/index.js +354 -0
  71. package/src/runtime/server/page/cookie.js +25 -0
  72. package/src/runtime/server/page/crypto.js +239 -0
  73. package/src/runtime/server/page/csp.js +249 -0
  74. package/src/runtime/server/page/fetch.js +282 -0
  75. package/src/runtime/server/page/index.js +404 -0
  76. package/src/runtime/server/page/load_data.js +124 -0
  77. package/src/runtime/server/page/render.js +358 -0
  78. package/src/runtime/server/page/respond_with_error.js +92 -0
  79. package/src/runtime/server/page/serialize_data.js +72 -0
  80. package/src/runtime/server/page/types.d.ts +45 -0
  81. package/src/runtime/server/utils.js +209 -0
  82. package/src/utils/array.js +9 -0
  83. package/src/utils/error.js +22 -0
  84. package/src/utils/escape.js +46 -0
  85. package/src/utils/filesystem.js +108 -0
  86. package/src/utils/functions.js +16 -0
  87. package/src/utils/http.js +55 -0
  88. package/src/utils/misc.js +1 -0
  89. package/src/utils/routing.js +117 -0
  90. package/src/utils/url.js +142 -0
  91. package/svelte-kit.js +1 -1
  92. package/types/ambient.d.ts +356 -0
  93. package/types/index.d.ts +356 -0
  94. package/types/internal.d.ts +386 -0
  95. package/types/private.d.ts +213 -0
  96. package/CHANGELOG.md +0 -463
  97. package/assets/components/error.svelte +0 -13
  98. package/assets/runtime/app/env.js +0 -5
  99. package/assets/runtime/app/navigation.js +0 -44
  100. package/assets/runtime/app/paths.js +0 -1
  101. package/assets/runtime/app/stores.js +0 -93
  102. package/assets/runtime/chunks/utils.js +0 -22
  103. package/assets/runtime/internal/singletons.js +0 -23
  104. package/assets/runtime/internal/start.js +0 -773
  105. package/assets/runtime/paths.js +0 -12
  106. package/dist/chunks/index.js +0 -3517
  107. package/dist/chunks/index2.js +0 -587
  108. package/dist/chunks/index3.js +0 -246
  109. package/dist/chunks/index4.js +0 -530
  110. package/dist/chunks/index5.js +0 -763
  111. package/dist/chunks/index6.js +0 -322
  112. package/dist/chunks/standard.js +0 -99
  113. package/dist/chunks/utils.js +0 -83
  114. package/dist/cli.js +0 -553
  115. package/dist/ssr.js +0 -2581
@@ -0,0 +1,146 @@
1
+ import { HttpError, Redirect } from '../../control.js';
2
+ import { normalize_error } from '../../../utils/error.js';
3
+ import { once } from '../../../utils/functions.js';
4
+ import { load_server_data } from '../page/load_data.js';
5
+ import { data_response, error_to_pojo } from '../utils.js';
6
+ import { normalize_path } from '../../../utils/url.js';
7
+ import { DATA_SUFFIX } from '../../../constants.js';
8
+
9
+ /**
10
+ * @param {import('types').RequestEvent} event
11
+ * @param {import('types').SSRRoute} route
12
+ * @param {import('types').SSROptions} options
13
+ * @param {import('types').SSRState} state
14
+ * @returns {Promise<Response>}
15
+ */
16
+ export async function render_data(event, route, options, state) {
17
+ if (!route.page) {
18
+ // requesting /__data.js should fail for a +server.js
19
+ return new Response(undefined, {
20
+ status: 404
21
+ });
22
+ }
23
+
24
+ try {
25
+ const node_ids = [...route.page.layouts, route.page.leaf];
26
+
27
+ const invalidated =
28
+ event.url.searchParams
29
+ .get('__invalid')
30
+ ?.split('')
31
+ .map((x) => x === 'y') ?? node_ids.map(() => true);
32
+
33
+ let aborted = false;
34
+
35
+ const url = new URL(event.url);
36
+ url.pathname = normalize_path(
37
+ url.pathname.slice(0, -DATA_SUFFIX.length),
38
+ options.trailing_slash
39
+ );
40
+
41
+ url.searchParams.delete('__invalid');
42
+ url.searchParams.delete('__id');
43
+
44
+ const new_event = { ...event, url };
45
+
46
+ const functions = node_ids.map((n, i) => {
47
+ return once(async () => {
48
+ try {
49
+ if (aborted) {
50
+ return /** @type {import('types').ServerDataSkippedNode} */ ({
51
+ type: 'skip'
52
+ });
53
+ }
54
+
55
+ // == because it could be undefined (in dev) or null (in build, because of JSON.stringify)
56
+ const node = n == undefined ? n : await options.manifest._.nodes[n]();
57
+ return load_server_data({
58
+ event: new_event,
59
+ state,
60
+ node,
61
+ parent: async () => {
62
+ /** @type {Record<string, any>} */
63
+ const data = {};
64
+ for (let j = 0; j < i; j += 1) {
65
+ const parent = /** @type {import('types').ServerDataNode | null} */ (
66
+ await functions[j]()
67
+ );
68
+
69
+ if (parent) {
70
+ Object.assign(data, parent.data);
71
+ }
72
+ }
73
+ return data;
74
+ }
75
+ });
76
+ } catch (e) {
77
+ aborted = true;
78
+ throw e;
79
+ }
80
+ });
81
+ });
82
+
83
+ const promises = functions.map(async (fn, i) => {
84
+ if (!invalidated[i]) {
85
+ return /** @type {import('types').ServerDataSkippedNode} */ ({
86
+ type: 'skip'
87
+ });
88
+ }
89
+
90
+ return fn();
91
+ });
92
+
93
+ let length = promises.length;
94
+ const nodes = await Promise.all(
95
+ promises.map((p, i) =>
96
+ p.catch((e) => {
97
+ const error = normalize_error(e);
98
+
99
+ if (error instanceof Redirect) {
100
+ throw error;
101
+ }
102
+
103
+ // Math.min because array isn't guaranteed to resolve in order
104
+ length = Math.min(length, i + 1);
105
+
106
+ if (error instanceof HttpError) {
107
+ return /** @type {import('types').ServerErrorNode} */ ({
108
+ type: 'error',
109
+ httperror: { ...error }
110
+ });
111
+ }
112
+
113
+ options.handle_error(error, event);
114
+
115
+ return /** @type {import('types').ServerErrorNode} */ ({
116
+ type: 'error',
117
+ error: error_to_pojo(error, options.get_stack)
118
+ });
119
+ })
120
+ )
121
+ );
122
+
123
+ /** @type {import('types').ServerData} */
124
+ const server_data = {
125
+ type: 'data',
126
+ nodes: nodes.slice(0, length)
127
+ };
128
+
129
+ return data_response(server_data);
130
+ } catch (e) {
131
+ const error = normalize_error(e);
132
+
133
+ if (error instanceof Redirect) {
134
+ /** @type {import('types').ServerData} */
135
+ const server_data = {
136
+ type: 'redirect',
137
+ location: error.location
138
+ };
139
+
140
+ return data_response(server_data);
141
+ } else {
142
+ // TODO make it clearer that this was an unexpected error
143
+ return data_response(error_to_pojo(error, options.get_stack));
144
+ }
145
+ }
146
+ }
@@ -0,0 +1,63 @@
1
+ import { Redirect } from '../control.js';
2
+ import { check_method_names, method_not_allowed } from './utils.js';
3
+
4
+ /**
5
+ * @param {import('types').RequestEvent} event
6
+ * @param {import('types').SSREndpoint} mod
7
+ * @param {import('types').SSRState} state
8
+ * @returns {Promise<Response>}
9
+ */
10
+ export async function render_endpoint(event, mod, state) {
11
+ const method = /** @type {import('types').HttpMethod} */ (event.request.method);
12
+
13
+ // TODO: Remove for 1.0
14
+ check_method_names(mod);
15
+
16
+ let handler = mod[method];
17
+
18
+ if (!handler && method === 'HEAD') {
19
+ handler = mod.GET;
20
+ }
21
+
22
+ if (!handler) {
23
+ return method_not_allowed(mod, method);
24
+ }
25
+
26
+ const prerender = mod.prerender ?? state.prerender_default;
27
+
28
+ if (prerender && (mod.POST || mod.PATCH || mod.PUT || mod.DELETE)) {
29
+ throw new Error('Cannot prerender endpoints that have mutative methods');
30
+ }
31
+
32
+ if (state.prerendering && !prerender) {
33
+ throw new Error(`${event.routeId} is not prerenderable`);
34
+ }
35
+
36
+ try {
37
+ const response = await handler(
38
+ /** @type {import('types').RequestEvent<Record<string, any>>} */ (event)
39
+ );
40
+
41
+ if (!(response instanceof Response)) {
42
+ throw new Error(
43
+ `Invalid response from route ${event.url.pathname}: handler should return a Response object`
44
+ );
45
+ }
46
+
47
+ if (state.prerendering) {
48
+ response.headers.set('x-sveltekit-routeid', /** @type {string} */ (event.routeId));
49
+ response.headers.set('x-sveltekit-prerender', String(prerender));
50
+ }
51
+
52
+ return response;
53
+ } catch (error) {
54
+ if (error instanceof Redirect) {
55
+ return new Response(undefined, {
56
+ status: error.status,
57
+ headers: { location: error.location }
58
+ });
59
+ }
60
+
61
+ throw error;
62
+ }
63
+ }
@@ -0,0 +1,354 @@
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 } from '../../utils/error.js';
6
+ import { GENERIC_ERROR, handle_fatal_error } from './utils.js';
7
+ import { decode_params, disable_search, normalize_path } from '../../utils/url.js';
8
+ import { exec } from '../../utils/routing.js';
9
+ import { render_data } from './data/index.js';
10
+ import { DATA_SUFFIX } from '../../constants.js';
11
+
12
+ /* global __SVELTEKIT_ADAPTER_NAME__ */
13
+
14
+ /** @param {{ html: string }} opts */
15
+ const default_transform = ({ html }) => html;
16
+
17
+ /** @type {import('types').Respond} */
18
+ export async function respond(request, options, state) {
19
+ let url = new URL(request.url);
20
+
21
+ if (options.csrf.check_origin) {
22
+ const type = request.headers.get('content-type')?.split(';')[0];
23
+
24
+ const forbidden =
25
+ request.method === 'POST' &&
26
+ request.headers.get('origin') !== url.origin &&
27
+ (type === 'application/x-www-form-urlencoded' || type === 'multipart/form-data');
28
+
29
+ if (forbidden) {
30
+ return new Response(`Cross-site ${request.method} form submissions are forbidden`, {
31
+ status: 403
32
+ });
33
+ }
34
+ }
35
+
36
+ const { parameter, allowed } = options.method_override;
37
+ const method_override = url.searchParams.get(parameter)?.toUpperCase();
38
+
39
+ if (method_override) {
40
+ if (request.method === 'POST') {
41
+ if (allowed.includes(method_override)) {
42
+ request = new Proxy(request, {
43
+ get: (target, property, _receiver) => {
44
+ if (property === 'method') return method_override;
45
+ return Reflect.get(target, property, target);
46
+ }
47
+ });
48
+ } else {
49
+ const verb = allowed.length === 0 ? 'enabled' : 'allowed';
50
+ const body = `${parameter}=${method_override} is not ${verb}. See https://kit.svelte.dev/docs/configuration#methodoverride`;
51
+
52
+ return new Response(body, {
53
+ status: 400
54
+ });
55
+ }
56
+ } else {
57
+ throw new Error(`${parameter}=${method_override} is only allowed with POST requests`);
58
+ }
59
+ }
60
+
61
+ let decoded;
62
+ try {
63
+ decoded = decodeURI(url.pathname);
64
+ } catch {
65
+ return new Response('Malformed URI', { status: 400 });
66
+ }
67
+
68
+ /** @type {import('types').SSRRoute | null} */
69
+ let route = null;
70
+
71
+ /** @type {Record<string, string>} */
72
+ let params = {};
73
+
74
+ if (options.paths.base && !state.prerendering?.fallback) {
75
+ if (!decoded.startsWith(options.paths.base)) {
76
+ return new Response('Not found', { status: 404 });
77
+ }
78
+ decoded = decoded.slice(options.paths.base.length) || '/';
79
+ }
80
+
81
+ const is_data_request = decoded.endsWith(DATA_SUFFIX);
82
+ if (is_data_request) decoded = decoded.slice(0, -DATA_SUFFIX.length) || '/';
83
+
84
+ if (!state.prerendering?.fallback) {
85
+ const matchers = await options.manifest._.matchers();
86
+
87
+ for (const candidate of options.manifest._.routes) {
88
+ const match = candidate.pattern.exec(decoded);
89
+ if (!match) continue;
90
+
91
+ const matched = exec(match, candidate.names, candidate.types, matchers);
92
+ if (matched) {
93
+ route = candidate;
94
+ params = decode_params(matched);
95
+ break;
96
+ }
97
+ }
98
+ }
99
+
100
+ if (route?.page && !is_data_request) {
101
+ const normalized = normalize_path(url.pathname, options.trailing_slash);
102
+
103
+ if (normalized !== url.pathname && !state.prerendering?.fallback) {
104
+ return new Response(undefined, {
105
+ status: 301,
106
+ headers: {
107
+ 'x-sveltekit-normalize': '1',
108
+ location:
109
+ // ensure paths starting with '//' are not treated as protocol-relative
110
+ (normalized.startsWith('//') ? url.origin + normalized : normalized) +
111
+ (url.search === '?' ? '' : url.search)
112
+ }
113
+ });
114
+ }
115
+ }
116
+
117
+ /** @type {import('types').ResponseHeaders} */
118
+ const headers = {};
119
+
120
+ /** @type {string[]} */
121
+ const cookies = [];
122
+
123
+ if (state.prerendering) disable_search(url);
124
+
125
+ /** @type {import('types').RequestEvent} */
126
+ const event = {
127
+ getClientAddress:
128
+ state.getClientAddress ||
129
+ (() => {
130
+ throw new Error(
131
+ `${__SVELTEKIT_ADAPTER_NAME__} does not specify getClientAddress. Please raise an issue`
132
+ );
133
+ }),
134
+ locals: {},
135
+ params,
136
+ platform: state.platform,
137
+ request,
138
+ routeId: route && route.id,
139
+ setHeaders: (new_headers) => {
140
+ for (const key in new_headers) {
141
+ const lower = key.toLowerCase();
142
+ const value = new_headers[key];
143
+
144
+ if (lower === 'set-cookie') {
145
+ const new_cookies = /** @type {string[]} */ (Array.isArray(value) ? value : [value]);
146
+
147
+ for (const cookie of new_cookies) {
148
+ if (cookies.includes(cookie)) {
149
+ throw new Error(`"${key}" header already has cookie with same value`);
150
+ }
151
+
152
+ cookies.push(cookie);
153
+ }
154
+ } else if (lower in headers) {
155
+ throw new Error(`"${key}" header is already set`);
156
+ } else {
157
+ headers[lower] = value;
158
+
159
+ if (state.prerendering && lower === 'cache-control') {
160
+ state.prerendering.cache = /** @type {string} */ (value);
161
+ }
162
+ }
163
+ }
164
+ },
165
+ url
166
+ };
167
+
168
+ // TODO remove this for 1.0
169
+ /**
170
+ * @param {string} property
171
+ * @param {string} replacement
172
+ * @param {string} suffix
173
+ */
174
+ const removed = (property, replacement, suffix = '') => ({
175
+ get: () => {
176
+ throw new Error(`event.${property} has been replaced by event.${replacement}` + suffix);
177
+ }
178
+ });
179
+
180
+ const details = '. See https://github.com/sveltejs/kit/pull/3384 for details';
181
+
182
+ const body_getter = {
183
+ get: () => {
184
+ throw new Error(
185
+ 'To access the request body use the text/json/arrayBuffer/formData methods, e.g. `body = await request.json()`' +
186
+ details
187
+ );
188
+ }
189
+ };
190
+
191
+ Object.defineProperties(event, {
192
+ clientAddress: removed('clientAddress', 'getClientAddress'),
193
+ method: removed('method', 'request.method', details),
194
+ headers: removed('headers', 'request.headers', details),
195
+ origin: removed('origin', 'url.origin'),
196
+ path: removed('path', 'url.pathname'),
197
+ query: removed('query', 'url.searchParams'),
198
+ body: body_getter,
199
+ rawBody: body_getter
200
+ });
201
+
202
+ /** @type {import('types').RequiredResolveOptions} */
203
+ let resolve_opts = {
204
+ transformPageChunk: default_transform
205
+ };
206
+
207
+ /**
208
+ *
209
+ * @param {import('types').RequestEvent} event
210
+ * @param {import('types').ResolveOptions} [opts]
211
+ */
212
+ async function resolve(event, opts) {
213
+ try {
214
+ if (opts) {
215
+ // TODO remove for 1.0
216
+ if ('transformPage' in opts) {
217
+ throw new Error(
218
+ 'transformPage has been replaced by transformPageChunk — see https://github.com/sveltejs/kit/pull/5657 for more information'
219
+ );
220
+ }
221
+
222
+ if ('ssr' in opts) {
223
+ throw new Error(
224
+ 'ssr has been removed, set it in the appropriate +layout.js instead. See the PR for more information: https://github.com/sveltejs/kit/pull/6197'
225
+ );
226
+ }
227
+
228
+ resolve_opts = {
229
+ transformPageChunk: opts.transformPageChunk || default_transform
230
+ };
231
+ }
232
+
233
+ if (state.prerendering?.fallback) {
234
+ return await render_response({
235
+ event,
236
+ options,
237
+ state,
238
+ page_config: { ssr: false, csr: true },
239
+ status: 200,
240
+ error: null,
241
+ branch: [],
242
+ fetched: [],
243
+ validation_errors: undefined,
244
+ cookies: [],
245
+ resolve_opts
246
+ });
247
+ }
248
+
249
+ if (route) {
250
+ /** @type {Response} */
251
+ let response;
252
+
253
+ if (is_data_request) {
254
+ response = await render_data(event, route, options, state);
255
+ } else if (route.page) {
256
+ response = await render_page(event, route, route.page, options, state, resolve_opts);
257
+ } else if (route.endpoint) {
258
+ response = await render_endpoint(event, await route.endpoint(), state);
259
+ } else {
260
+ // a route will always have a page or an endpoint, but TypeScript
261
+ // doesn't know that
262
+ throw new Error('This should never happen');
263
+ }
264
+
265
+ if (!is_data_request) {
266
+ // we only want to set cookies on __data.js requests, we don't
267
+ // want to cache stuff erroneously etc
268
+ for (const key in headers) {
269
+ const value = headers[key];
270
+ response.headers.set(key, /** @type {string} */ (value));
271
+ }
272
+ }
273
+
274
+ for (const cookie of cookies) {
275
+ response.headers.append('set-cookie', cookie);
276
+ }
277
+
278
+ // respond with 304 if etag matches
279
+ if (response.status === 200 && response.headers.has('etag')) {
280
+ let if_none_match_value = request.headers.get('if-none-match');
281
+
282
+ // ignore W/ prefix https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match#directives
283
+ if (if_none_match_value?.startsWith('W/"')) {
284
+ if_none_match_value = if_none_match_value.substring(2);
285
+ }
286
+
287
+ const etag = /** @type {string} */ (response.headers.get('etag'));
288
+
289
+ if (if_none_match_value === etag) {
290
+ const headers = new Headers({ etag });
291
+
292
+ // https://datatracker.ietf.org/doc/html/rfc7232#section-4.1
293
+ for (const key of ['cache-control', 'content-location', 'date', 'expires', 'vary']) {
294
+ const value = response.headers.get(key);
295
+ if (value) headers.set(key, value);
296
+ }
297
+
298
+ return new Response(undefined, {
299
+ status: 304,
300
+ headers
301
+ });
302
+ }
303
+ }
304
+
305
+ return response;
306
+ }
307
+
308
+ if (state.initiator === GENERIC_ERROR) {
309
+ return new Response('Internal Server Error', {
310
+ status: 500
311
+ });
312
+ }
313
+
314
+ // if this request came direct from the user, rather than
315
+ // via a `fetch` in a `load`, render a 404 page
316
+ if (!state.initiator) {
317
+ return await respond_with_error({
318
+ event,
319
+ options,
320
+ state,
321
+ status: 404,
322
+ error: new Error(`Not found: ${event.url.pathname}`),
323
+ resolve_opts
324
+ });
325
+ }
326
+
327
+ if (state.prerendering) {
328
+ return new Response('not found', { status: 404 });
329
+ }
330
+
331
+ // we can't load the endpoint from our own manifest,
332
+ // so we need to make an actual HTTP request
333
+ return await fetch(request);
334
+ } catch (e) {
335
+ const error = coalesce_to_error(e);
336
+ return handle_fatal_error(event, options, error);
337
+ }
338
+ }
339
+
340
+ try {
341
+ return await options.hooks.handle({
342
+ event,
343
+ resolve,
344
+ // TODO remove for 1.0
345
+ // @ts-expect-error
346
+ get request() {
347
+ throw new Error('request in handle has been replaced with event' + details);
348
+ }
349
+ });
350
+ } catch (/** @type {unknown} */ e) {
351
+ const error = coalesce_to_error(e);
352
+ return handle_fatal_error(event, options, error);
353
+ }
354
+ }
@@ -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
+ }