@sveltejs/kit 3.0.0-next.24 → 3.0.0-next.25

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 (40) hide show
  1. package/package.json +12 -4
  2. package/src/constants.js +6 -0
  3. package/src/core/adapt/builder.js +1 -2
  4. package/src/core/env.js +3 -6
  5. package/src/core/postbuild/prerender.js +2 -2
  6. package/src/core/sync/write_server.js +3 -17
  7. package/src/core/utils.js +10 -0
  8. package/src/exports/adapter.js +22 -0
  9. package/src/exports/public.d.ts +1 -1
  10. package/src/exports/vite/build/service-worker.js +98 -0
  11. package/src/exports/vite/dev/index.js +17 -3
  12. package/src/exports/vite/index.js +41 -411
  13. package/src/exports/vite/plugins/env-vars.js +42 -0
  14. package/src/exports/vite/plugins/guard.js +205 -0
  15. package/src/exports/vite/utils.js +97 -0
  16. package/src/runtime/app/server/remote/query.js +2 -2
  17. package/src/runtime/client/client.js +4 -4
  18. package/src/runtime/form-utils.js +11 -19
  19. package/src/runtime/server/data/index.js +11 -26
  20. package/src/runtime/server/errors.js +7 -10
  21. package/src/runtime/server/fetch.js +14 -16
  22. package/src/runtime/server/index.js +28 -25
  23. package/src/runtime/server/internal.js +34 -4
  24. package/src/runtime/server/page/actions.js +6 -8
  25. package/src/runtime/server/page/data_serializer.js +6 -10
  26. package/src/runtime/server/page/index.js +9 -14
  27. package/src/runtime/server/page/render.js +16 -29
  28. package/src/runtime/server/page/respond_with_error.js +7 -9
  29. package/src/runtime/server/remote-functions.js +125 -125
  30. package/src/runtime/server/respond.js +53 -28
  31. package/src/runtime/server/state.js +1 -0
  32. package/src/runtime/server/utils.js +0 -7
  33. package/src/runtime/utils.js +41 -0
  34. package/src/types/global-private.d.ts +8 -0
  35. package/src/types/internal.d.ts +7 -11
  36. package/src/utils/filesystem.js +1 -1
  37. package/src/utils/streaming.js +5 -15
  38. package/src/version.js +1 -1
  39. package/types/index.d.ts +20 -1
  40. package/types/index.d.ts.map +4 -1
@@ -0,0 +1,205 @@
1
+ /** @import { TopLevelFilterExpression } from '@rolldown/pluginutils' */
2
+ /** @import { ManifestData, ValidatedConfig } from 'types' */
3
+ /** @import { Plugin } from 'vite' */
4
+ import path from 'node:path';
5
+ import { and, exactRegex, importerId, include, not } from '@rolldown/pluginutils';
6
+ import { app_env_private, app_server } from '../module_ids.js';
7
+ import {
8
+ error_for_missing_config,
9
+ normalize_id,
10
+ remote_module_pattern,
11
+ server_only_directory_pattern,
12
+ server_only_module_pattern
13
+ } from '../utils.js';
14
+ import { stackless } from '../../../utils/error.js';
15
+ import { posixify } from '../../../utils/os.js';
16
+
17
+ /**
18
+ * Ensures that client-side code can't accidentally import server-side code,
19
+ * whether in `*.server.js` files, `$app/server`, any `/server/` directory, or `$app/env/private`
20
+ * @param {ValidatedConfig} kit
21
+ * @param {() => { vite: typeof import('vite'); root: string; normalized_aliases: Array<{ alias: string, path: string }>; service_worker_entry_file: string | null; }} get_config
22
+ * @param {() => ManifestData} get_manifest_data
23
+ * @returns {Plugin}
24
+ */
25
+ export function plugin_guard(kit, get_config, get_manifest_data) {
26
+ /** @type {string} */
27
+ let root;
28
+
29
+ /** @type {string} */
30
+ let normalized_cwd;
31
+ /** @type {Array<{ alias: string, path: string }>} */
32
+ let normalized_aliases;
33
+ /** @type {string} */
34
+ let normalized_node_modules;
35
+ /** @type {string} */
36
+ let normalized_routes;
37
+ /** @type {string} */
38
+ let normalized_assets;
39
+
40
+ /** @type {string | null} */
41
+ let service_worker_entry_file;
42
+
43
+ /** @type {Map<string, Set<string>>} */
44
+ const import_map = new Map();
45
+
46
+ return {
47
+ name: 'vite-plugin-sveltekit-guard',
48
+
49
+ // Run this plugin before built-in resolution, so that relative imports
50
+ // are added to the module graph
51
+ enforce: 'pre',
52
+
53
+ configResolved() {
54
+ /** @type {typeof import('vite')} */
55
+ let vite;
56
+ ({ vite, root, normalized_aliases, service_worker_entry_file } = get_config());
57
+
58
+ normalized_cwd = vite.normalizePath(root);
59
+ normalized_node_modules = vite.normalizePath(path.resolve(root, 'node_modules'));
60
+ normalized_routes = vite.normalizePath(path.resolve(root, kit.files.routes));
61
+ normalized_assets = vite.normalizePath(path.resolve(root, kit.files.assets));
62
+ },
63
+
64
+ applyToEnvironment(environment) {
65
+ // the import map is only read for client-side violations in `load`, so skip other environments
66
+ return environment.config.consumer === 'client';
67
+ },
68
+
69
+ resolveId: {
70
+ // composable filters are not accepted type-wise but still work during build
71
+ // see https://github.com/vitejs/rolldown-vite/issues/605
72
+ filter: /** @type {any} */ (
73
+ /** @satisfies {TopLevelFilterExpression[]} */ ([
74
+ include(and(importerId(/.+/), not(importerId(/index\.html$/))))
75
+ ])
76
+ ),
77
+ async handler(id, importer, options) {
78
+ // composable filters only work during build so we still need this guard for dev
79
+ // see https://github.com/vitejs/rolldown-vite/issues/605
80
+ if (importer && !importer.endsWith('index.html')) {
81
+ const resolved = await this.resolve(id, importer, { ...options, skipSelf: true });
82
+
83
+ if (resolved) {
84
+ const normalized = normalize_id(resolved.id, normalized_aliases, normalized_cwd);
85
+
86
+ let importers = import_map.get(normalized);
87
+
88
+ if (!importers) {
89
+ importers = new Set();
90
+ import_map.set(normalized, importers);
91
+ }
92
+
93
+ importers.add(normalize_id(importer, normalized_aliases, normalized_cwd));
94
+ }
95
+ }
96
+ }
97
+ },
98
+
99
+ load: {
100
+ filter: {
101
+ id: [
102
+ exactRegex(app_server),
103
+ exactRegex(app_env_private),
104
+ server_only_module_pattern,
105
+ server_only_directory_pattern
106
+ ]
107
+ },
108
+ handler(id) {
109
+ const normalized = normalize_id(id, normalized_aliases, normalized_cwd);
110
+
111
+ let is_server_only = normalized === '$app/env/private' || normalized === '$app/server';
112
+
113
+ // skip .server.js files outside the cwd or in node_modules, as the filename might not mean 'server-only module' in this context
114
+ if (id.startsWith(normalized_cwd) && !id.startsWith(normalized_node_modules)) {
115
+ // e.g. `server.ts` or `foo.server.ts`
116
+ is_server_only ||= server_only_module_pattern.test(id);
117
+
118
+ // e.g. `server/foo.ts`, unless in `src/routes` or `static`
119
+ is_server_only ||=
120
+ server_only_directory_pattern.test(id) &&
121
+ !id.startsWith(normalized_routes + '/') &&
122
+ !id.startsWith(normalized_assets + '/');
123
+ }
124
+
125
+ if (!is_server_only) return;
126
+
127
+ const manifest_data = get_manifest_data();
128
+
129
+ /** @type {Set<string>} */
130
+ const entrypoints = new Set();
131
+ for (const node of manifest_data.nodes) {
132
+ if (node.component) entrypoints.add(node.component);
133
+ if (node.universal) entrypoints.add(node.universal);
134
+ }
135
+
136
+ if (manifest_data.hooks.client) entrypoints.add(manifest_data.hooks.client);
137
+ if (manifest_data.hooks.universal) entrypoints.add(manifest_data.hooks.universal);
138
+
139
+ if (service_worker_entry_file) {
140
+ entrypoints.add(posixify(path.relative(root, service_worker_entry_file)));
141
+ }
142
+
143
+ // Walk up the import graph from the server-only module, looking for a chain
144
+ // that leads back to a client entrypoint. We search all candidates (not just
145
+ // the first) because a module can be imported by both server and client code,
146
+ // and a greedy first-match could follow a server-only branch that never
147
+ // reaches an entrypoint — see https://github.com/sveltejs/kit/issues/16232
148
+ /** @type {Set<string>} */
149
+ const visited = new Set([normalized]);
150
+
151
+ /**
152
+ * @param {string} current
153
+ * @param {string[]} chain
154
+ * @returns {string[] | null}
155
+ */
156
+ function find_chain(current, chain) {
157
+ const importers = import_map.get(current);
158
+ if (!importers) return null;
159
+
160
+ for (const importer of importers) {
161
+ if (visited.has(importer)) continue;
162
+ visited.add(importer);
163
+
164
+ const next_chain = [...chain, importer];
165
+ if (entrypoints.has(importer)) {
166
+ return next_chain;
167
+ }
168
+ const result = find_chain(importer, next_chain);
169
+ if (result) return result;
170
+ }
171
+ return null;
172
+ }
173
+
174
+ const chain = find_chain(normalized, [normalized]);
175
+
176
+ if (chain) {
177
+ if (chain.some((id) => remote_module_pattern.test(id))) {
178
+ error_for_missing_config('remote functions', 'experimental.remoteFunctions', 'true');
179
+ }
180
+
181
+ const pyramid = chain
182
+ .reverse()
183
+ .map((id, i) => {
184
+ return `${' '.repeat(i + 1)}${id}`;
185
+ })
186
+ .join(' imports\n');
187
+
188
+ let message = `Cannot import ${normalized} into code that runs in the browser, as this could leak sensitive information.`;
189
+ message += `\n\n${pyramid}`;
190
+ message += `\n\nIf you're only using the import as a type, change it to \`import type\`.`;
191
+
192
+ throw stackless(message);
193
+ }
194
+
195
+ // No chain from this server-only module to a client entrypoint was found —
196
+ // the module is only imported from server code, which is valid.
197
+ }
198
+ },
199
+
200
+ // avoid watch mode rebuilds using stale import map data
201
+ buildEnd() {
202
+ import_map.clear();
203
+ }
204
+ };
205
+ }
@@ -1,5 +1,9 @@
1
+ /** @import { UserConfig } from 'vite' */
2
+ /** @import { EnforcedConfig } from './types.js' */
1
3
  import fs from 'node:fs';
2
4
  import path from 'node:path';
5
+ import process from 'node:process';
6
+ import { styleText } from 'node:util';
3
7
  import { posixify } from '../../utils/os.js';
4
8
  import { negotiate } from '../../utils/http.js';
5
9
  import { escape_html } from '../../utils/escape.js';
@@ -227,3 +231,96 @@ export function error_for_missing_config(feature_name, path, value) {
227
231
  `
228
232
  );
229
233
  }
234
+
235
+ /** @type {EnforcedConfig} */
236
+ export const enforced_config = {
237
+ appType: true,
238
+ base: true,
239
+ build: {
240
+ cssCodeSplit: true,
241
+ emptyOutDir: true,
242
+ lib: {
243
+ entry: true,
244
+ name: true,
245
+ formats: true
246
+ },
247
+ manifest: true,
248
+ outDir: true,
249
+ rolldownOptions: {
250
+ input: true,
251
+ output: {
252
+ format: true,
253
+ entryFileNames: true,
254
+ chunkFileNames: true,
255
+ assetFileNames: true
256
+ },
257
+ preserveEntrySignatures: true
258
+ },
259
+ ssr: true
260
+ },
261
+ publicDir: true,
262
+ resolve: {
263
+ alias: {
264
+ $app: true,
265
+ $env: true,
266
+ '<sveltekit:generated>': true
267
+ }
268
+ }
269
+ };
270
+
271
+ /**
272
+ * @param {UserConfig} config
273
+ * @param {UserConfig} resolved_config
274
+ */
275
+ export function warn_overridden_config(config, resolved_config) {
276
+ const overridden = find_overridden_config(config, resolved_config, enforced_config, '', []);
277
+
278
+ if (overridden.length > 0) {
279
+ console.error(
280
+ styleText(
281
+ ['bold', 'red'],
282
+ 'The following Vite config options will be overridden by SvelteKit:'
283
+ ) + overridden.map((key) => `\n - ${key}`).join('')
284
+ );
285
+ }
286
+ }
287
+
288
+ /**
289
+ * @param {Record<string, any>} config
290
+ * @param {Record<string, any>} resolved_config
291
+ * @param {EnforcedConfig} enforced_config
292
+ * @param {string} path
293
+ * @param {string[]} out used locally to compute the return value
294
+ */
295
+ export function find_overridden_config(config, resolved_config, enforced_config, path, out) {
296
+ if (config == null || resolved_config == null) {
297
+ return out;
298
+ }
299
+
300
+ for (const key in enforced_config) {
301
+ if (typeof config === 'object' && key in config && key in resolved_config) {
302
+ const enforced = enforced_config[key];
303
+ const resolved = resolved_config[key];
304
+
305
+ if (enforced === true) {
306
+ if (comparable(config[key]) !== comparable(resolved)) {
307
+ out.push(path + key);
308
+ }
309
+ } else {
310
+ find_overridden_config(config[key], resolved, enforced, path + key + '.', out);
311
+ }
312
+ }
313
+ }
314
+ return out;
315
+ }
316
+
317
+ /**
318
+ * Normalizes a config value for comparison, since Windows paths may use backslashes
319
+ * and differ in casing (e.g. the drive letter) depending on where they came from.
320
+ * @param {any} value
321
+ */
322
+ export function comparable(value) {
323
+ if (typeof value !== 'string') return value;
324
+ const normalized = posixify(value);
325
+ return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
326
+ }
@@ -330,7 +330,7 @@ function batch(validate_or_fn, maybe_fn) {
330
330
  id: '',
331
331
  name: '',
332
332
  validate,
333
- run: async (args, options) => {
333
+ run: async (args) => {
334
334
  const { event, state } = get_request_store();
335
335
 
336
336
  return run_remote_function(
@@ -347,7 +347,7 @@ function batch(validate_or_fn, maybe_fn) {
347
347
  const data = get_result(arg, i);
348
348
  return { type: 'result', data };
349
349
  } catch (error) {
350
- const transformed = await handle_error_and_jsonify(event, state, options, error);
350
+ const transformed = await handle_error_and_jsonify(event, state, error);
351
351
 
352
352
  return {
353
353
  type: 'error',
@@ -615,7 +615,7 @@ async function _invalidate(reset_page_state = true) {
615
615
 
616
616
  const token = (invalidation_token = {});
617
617
  const nav_token = navigation_token;
618
- const navigating = is_navigating;
618
+ const prev_current = current;
619
619
  const intent = await get_navigation_intent(current.url, true);
620
620
 
621
621
  // Clear preload, it might be affected by the invalidation.
@@ -655,9 +655,9 @@ async function _invalidate(reset_page_state = true) {
655
655
  );
656
656
  }
657
657
 
658
- // A navigation started before the invalidation and ended before it finished. The invalidation did not redirect,
659
- // hence it likely contains outdated data now, so we ignore it.
660
- if (navigating && !is_navigating) {
658
+ // a navigation applied its result while the invalidation was loading,
659
+ // so the invalidation contains outdated data for a page we are no longer on
660
+ if (current !== prev_current) {
661
661
  return;
662
662
  }
663
663
 
@@ -3,7 +3,7 @@
3
3
 
4
4
  import { DEV } from 'esm-env';
5
5
  import * as devalue from 'devalue';
6
- import { text_decoder, text_encoder } from './utils.js';
6
+ import { stream_from_iterable, text_decoder, text_encoder } from './utils.js';
7
7
  import { noop } from '../utils/functions.js';
8
8
  import { SvelteKitError } from '@sveltejs/kit/internal';
9
9
 
@@ -441,25 +441,17 @@ class LazyFile {
441
441
  }
442
442
  stream() {
443
443
  const range = read_range(this.#get_chunk, this.#offset, this.size);
444
- let cursor = 0;
445
- return new ReadableStream({
446
- pull: async (controller) => {
447
- const { value, done } = await range.next();
448
- if (done) {
449
- if (cursor < this.size) {
450
- controller.error('incomplete file data');
451
- } else {
452
- controller.close();
453
- }
454
- return;
455
- }
456
- cursor += value.byteLength;
457
- controller.enqueue(value);
458
- if (cursor >= this.size) {
459
- controller.close();
444
+ const size = this.size;
445
+ return stream_from_iterable(
446
+ (async function* () {
447
+ let cursor = 0;
448
+ for await (const chunk of range) {
449
+ cursor += chunk.byteLength;
450
+ yield chunk;
460
451
  }
461
- }
462
- });
452
+ if (cursor < size) throw new Error('incomplete file data');
453
+ })()
454
+ );
463
455
  }
464
456
  async text() {
465
457
  return text_decoder.decode(await this.arrayBuffer());
@@ -6,14 +6,13 @@ import { server_data_serializer_json } from '../page/data_serializer.js';
6
6
  import { load_server_data } from '../page/load_data.js';
7
7
  import { handle_error_and_jsonify } from '../errors.js';
8
8
  import { normalize_path } from '../../../utils/url.js';
9
- import { text_encoder } from '../../utils.js';
9
+ import { stream_text } from '../../utils.js';
10
10
  import { with_version_header } from '../utils.js';
11
11
 
12
12
  /**
13
13
  * @param {import('@sveltejs/kit').RequestEvent} event
14
14
  * @param {import('types').RequestState} state
15
15
  * @param {{ page: Pick<import('types').PageNodeIndexes, 'layouts' | 'leaf'> | null }} route
16
- * @param {import('types').SSROptions} options
17
16
  * @param {import('@sveltejs/kit').SSRManifest} manifest
18
17
  * @param {boolean[] | undefined} invalidated_data_nodes
19
18
  * @param {import('types').TrailingSlash} trailing_slash
@@ -23,7 +22,6 @@ export async function render_data(
23
22
  event,
24
23
  state,
25
24
  route,
26
- options,
27
25
  manifest,
28
26
  invalidated_data_nodes,
29
27
  trailing_slash
@@ -92,7 +90,7 @@ export async function render_data(
92
90
  return fn();
93
91
  });
94
92
 
95
- const data_serializer = server_data_serializer_json(event, state, options);
93
+ const data_serializer = server_data_serializer_json(event, state);
96
94
  await Promise.all(
97
95
  promises.map(async (p, i) => {
98
96
  const node = await p.catch(async (error) => {
@@ -100,7 +98,7 @@ export async function render_data(
100
98
  throw error;
101
99
  }
102
100
 
103
- const transformed = await handle_error_and_jsonify(event, state, options, error);
101
+ const transformed = await handle_error_and_jsonify(event, state, error);
104
102
 
105
103
  return /** @type {import('types').ServerErrorNode} */ ({
106
104
  type: 'error',
@@ -120,27 +118,14 @@ export async function render_data(
120
118
  }
121
119
 
122
120
  return with_version_header(
123
- new Response(
124
- new ReadableStream({
125
- async start(controller) {
126
- controller.enqueue(text_encoder.encode(data));
127
- for await (const chunk of chunks) {
128
- controller.enqueue(text_encoder.encode(chunk));
129
- }
130
- controller.close();
131
- },
132
-
133
- type: 'bytes'
134
- }),
135
- {
136
- headers: {
137
- // we use a proprietary content type to prevent buffering.
138
- // the `text` prefix makes it inspectable
139
- 'content-type': 'text/sveltekit-data',
140
- 'cache-control': 'private, no-store'
141
- }
121
+ new Response(stream_text(data, chunks), {
122
+ headers: {
123
+ // we use a proprietary content type to prevent buffering.
124
+ // the `text` prefix makes it inspectable
125
+ 'content-type': 'text/sveltekit-data',
126
+ 'cache-control': 'private, no-store'
142
127
  }
143
- )
128
+ })
144
129
  );
145
130
  } catch (e) {
146
131
  const error = normalize_error(e);
@@ -148,7 +133,7 @@ export async function render_data(
148
133
  if (error instanceof Redirect) {
149
134
  return redirect_json_response(error);
150
135
  } else {
151
- const transformed = await handle_error_and_jsonify(event, state, options, error);
136
+ const transformed = await handle_error_and_jsonify(event, state, error);
152
137
  return json_response(transformed, transformed.status);
153
138
  }
154
139
  }
@@ -8,17 +8,16 @@ import {
8
8
  import { with_request_store } from '@sveltejs/kit/internal/server';
9
9
  import { add_deprecated_handle_error_properties, coalesce_to_error } from '../../utils/error.js';
10
10
  import { negotiate } from '../../utils/http.js';
11
- import { fix_stack_trace } from './internal.js';
11
+ import { fix_stack_trace, hooks, options } from './internal.js';
12
12
  import { escape_html } from '../../utils/escape.js';
13
13
 
14
14
  /**
15
15
  * @param {import('@sveltejs/kit').RequestEvent} event
16
16
  * @param {import('types').RequestState} state
17
- * @param {import('types').SSROptions} options
18
17
  * @param {unknown} error
19
18
  */
20
- export async function handle_fatal_error(event, state, options, error) {
21
- const body = await handle_error_and_jsonify(event, state, options, error);
19
+ export async function handle_fatal_error(event, state, error) {
20
+ const body = await handle_error_and_jsonify(event, state, error);
22
21
  const status = body.status;
23
22
 
24
23
  // sec-fetch-dest would be nicer, but non-browser clients and plain HTTP hosts don't send it
@@ -33,17 +32,16 @@ export async function handle_fatal_error(event, state, options, error) {
33
32
  });
34
33
  }
35
34
 
36
- return static_error_page(options, status, body.message);
35
+ return static_error_page(status, body.message);
37
36
  }
38
37
 
39
38
  /**
40
39
  * @param {import('@sveltejs/kit').RequestEvent} event
41
40
  * @param {import('types').RequestState} state
42
- * @param {import('types').SSROptions} options
43
41
  * @param {any} error
44
42
  * @returns {App.Error | Promise<App.Error>}
45
43
  */
46
- export function handle_error_and_jsonify(event, state, options, error) {
44
+ export function handle_error_and_jsonify(event, state, error) {
47
45
  if (error instanceof HandledHttpError) {
48
46
  return error.body;
49
47
  }
@@ -90,7 +88,7 @@ export function handle_error_and_jsonify(event, state, options, error) {
90
88
  const input = { ...caught, event };
91
89
  if (__SVELTEKIT_DEV__) add_deprecated_handle_error_properties(input, fallback);
92
90
 
93
- result = with_request_store({ event, state }, () => options.hooks.handleError(input));
91
+ result = with_request_store({ event, state }, () => hooks.handleError(input));
94
92
  } catch (hook_error) {
95
93
  log_handle_error_hook_failure(error, hook_error);
96
94
  return { status: fallback.status, message: 'Internal Error' };
@@ -141,11 +139,10 @@ function log_handle_error_hook_failure(error, hook_error) {
141
139
  /**
142
140
  * Return as a response that renders the error.html
143
141
  *
144
- * @param {import('types').SSROptions} options
145
142
  * @param {number} status
146
143
  * @param {string} message
147
144
  */
148
- export function static_error_page(options, status, message) {
145
+ export function static_error_page(status, message) {
149
146
  let page = options.templates.error({ status, message: escape_html(message) });
150
147
 
151
148
  if (__SVELTEKIT_DEV__) {
@@ -2,14 +2,13 @@ import { parseSetCookie } from 'cookie';
2
2
  import { noop } from '../../utils/functions.js';
3
3
  import { respond } from './respond.js';
4
4
  import * as paths from '#app/paths';
5
- import { read_implementation } from './internal.js';
5
+ import { hooks, read_implementation } from './internal.js';
6
6
  import { has_prerendered_path } from './utils.js';
7
7
  import { fork_state_for_subrequest } from './state.js';
8
8
 
9
9
  /**
10
10
  * @param {{
11
11
  * event: import('@sveltejs/kit').RequestEvent;
12
- * options: import('types').SSROptions;
13
12
  * manifest: import('@sveltejs/kit').SSRManifest;
14
13
  * state: import('types').RequestState;
15
14
  * get_cookie_header: (url: URL, header: string | null) => string;
@@ -17,7 +16,7 @@ import { fork_state_for_subrequest } from './state.js';
17
16
  * }} opts
18
17
  * @returns {typeof fetch}
19
18
  */
20
- export function create_fetch({ event, options, manifest, state, get_cookie_header, set_internal }) {
19
+ export function create_fetch({ event, manifest, state, get_cookie_header, set_internal }) {
21
20
  /**
22
21
  * @type {typeof fetch}
23
22
  */
@@ -30,7 +29,7 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
30
29
  let credentials =
31
30
  (info instanceof Request ? info.credentials : init?.credentials) ?? 'same-origin';
32
31
 
33
- return options.hooks.handleFetch({
32
+ return hooks.handleFetch({
34
33
  event,
35
34
  request: original_request,
36
35
  fetch: async (info, init) => {
@@ -148,18 +147,19 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
148
147
  request.headers.set('accept-language', accept_language);
149
148
  }
150
149
 
151
- const response = await internal_fetch(request, options, manifest, state);
150
+ const response = await internal_fetch(request, manifest, state);
152
151
 
153
152
  for (const str of response.headers.getSetCookie()) {
154
- const { name, value, ...options } = parseSetCookie(str, { decode: (v) => v });
153
+ const { name, value, ...cookie_options } = parseSetCookie(str, { decode: (v) => v });
155
154
 
156
- const path = options.path ?? (url.pathname.split('/').slice(0, -1).join('/') || '/');
155
+ const path =
156
+ cookie_options.path ?? (url.pathname.split('/').slice(0, -1).join('/') || '/');
157
157
 
158
- // options.sameSite is string, something more specific is required - type cast is safe
158
+ // sameSite is string, something more specific is required - type cast is safe
159
159
  set_internal(name, /** @type {string} */ (value), {
160
160
  path,
161
161
  encode: (value) => value,
162
- .../** @type {import('cookie').SerializeOptions} */ (options)
162
+ .../** @type {import('cookie').SerializeOptions} */ (cookie_options)
163
163
  });
164
164
  }
165
165
 
@@ -193,12 +193,11 @@ function normalize_fetch_input(info, init, url) {
193
193
 
194
194
  /**
195
195
  * @param {Request} request
196
- * @param {import('types').SSROptions} options
197
196
  * @param {import('@sveltejs/kit').SSRManifest} manifest
198
197
  * @param {import('types').RequestState} state
199
198
  * @returns {Promise<Response>}
200
199
  */
201
- async function internal_fetch(request, options, manifest, state) {
200
+ async function internal_fetch(request, manifest, state) {
202
201
  if (request.signal?.aborted) {
203
202
  throw new DOMException('The operation was aborted.', 'AbortError');
204
203
  }
@@ -206,7 +205,7 @@ async function internal_fetch(request, options, manifest, state) {
206
205
  const subrequest_state = fork_state_for_subrequest(state);
207
206
 
208
207
  if (!request.signal) {
209
- return await respond(request, options, manifest, subrequest_state);
208
+ return await respond(request, manifest, subrequest_state);
210
209
  }
211
210
 
212
211
  let remove_abort_listener = noop;
@@ -219,8 +218,7 @@ async function internal_fetch(request, options, manifest, state) {
219
218
  remove_abort_listener = () => request.signal.removeEventListener('abort', on_abort);
220
219
  });
221
220
 
222
- return Promise.race([
223
- respond(request, options, manifest, subrequest_state),
224
- abort_promise
225
- ]).finally(remove_abort_listener);
221
+ return Promise.race([respond(request, manifest, subrequest_state), abort_promise]).finally(
222
+ remove_abort_listener
223
+ );
226
224
  }