@sveltejs/kit 1.9.3 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.9.3",
3
+ "version": "1.10.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
package/src/core/env.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { GENERATED_COMMENT } from '../constants.js';
2
+ import { dedent } from './sync/utils.js';
2
3
  import { runtime_base } from './utils.js';
3
4
 
4
5
  /**
@@ -50,10 +51,13 @@ export function create_dynamic_module(type, dev_values) {
50
51
  export function create_static_types(id, env) {
51
52
  const declarations = Object.keys(env[id])
52
53
  .filter((k) => valid_identifier.test(k))
53
- .map((k) => `\texport const ${k}: string;`)
54
- .join('\n');
54
+ .map((k) => `export const ${k}: string;`);
55
55
 
56
- return `declare module '$env/static/${id}' {\n${declarations}\n}`;
56
+ return dedent`
57
+ declare module '$env/static/${id}' {
58
+ ${declarations.join('\n')}
59
+ }
60
+ `;
57
61
  }
58
62
 
59
63
  /**
@@ -65,19 +69,24 @@ export function create_static_types(id, env) {
65
69
  export function create_dynamic_types(id, env, prefix) {
66
70
  const properties = Object.keys(env[id])
67
71
  .filter((k) => valid_identifier.test(k))
68
- .map((k) => `\t\t${k}: string;`);
72
+ .map((k) => `${k}: string;`);
69
73
 
70
74
  const prefixed = `[key: \`${prefix}\${string}\`]`;
71
75
 
72
76
  if (id === 'private') {
73
- properties.push(`\t\t${prefixed}: undefined;`);
74
- properties.push(`\t\t[key: string]: string | undefined;`);
77
+ properties.push(`${prefixed}: undefined;`);
78
+ properties.push(`[key: string]: string | undefined;`);
75
79
  } else {
76
- properties.push(`\t\t${prefixed}: string | undefined;`);
80
+ properties.push(`${prefixed}: string | undefined;`);
77
81
  }
78
82
 
79
- const declaration = `export const env: {\n${properties.join('\n')}\n\t}`;
80
- return `declare module '$env/dynamic/${id}' {\n\t${declaration}\n}`;
83
+ return dedent`
84
+ declare module '$env/dynamic/${id}' {
85
+ export const env: {
86
+ ${properties.join('\n')}
87
+ }
88
+ }
89
+ `;
81
90
  }
82
91
 
83
92
  export const reserved = new Set([
@@ -3,6 +3,7 @@ import { get_mime_lookup } from '../utils.js';
3
3
  import { resolve_symlinks } from '../../exports/vite/build/utils.js';
4
4
  import { compact } from '../../utils/array.js';
5
5
  import { join_relative } from '../../utils/filesystem.js';
6
+ import { dedent } from '../sync/utils.js';
6
7
 
7
8
  /**
8
9
  * Generates the data used to write the server-side manifest.js file. This data is used in the Vite
@@ -80,37 +81,41 @@ export function generate_manifest({ build_data, relative_path, routes }) {
80
81
  // prettier-ignore
81
82
  // String representation of
82
83
  /** @type {import('types').SSRManifest} */
83
- return `{
84
- appDir: ${s(build_data.app_dir)},
85
- appPath: ${s(build_data.app_path)},
86
- assets: new Set(${s(assets)}),
87
- mimeTypes: ${s(get_mime_lookup(build_data.manifest_data))},
88
- _: {
89
- client: ${s(build_data.client)},
90
- nodes: [
91
- ${(node_paths).map(loader).join(',\n\t\t\t\t')}
92
- ],
93
- routes: [
94
- ${routes.map(route => {
95
- route.params.forEach(param => {
96
- if (param.matcher) matchers.add(param.matcher);
97
- });
84
+ return dedent`
85
+ {
86
+ appDir: ${s(build_data.app_dir)},
87
+ appPath: ${s(build_data.app_path)},
88
+ assets: new Set(${s(assets)}),
89
+ mimeTypes: ${s(get_mime_lookup(build_data.manifest_data))},
90
+ _: {
91
+ client: ${s(build_data.client)},
92
+ nodes: [
93
+ ${(node_paths).map(loader).join(',\n')}
94
+ ],
95
+ routes: [
96
+ ${routes.map(route => {
97
+ route.params.forEach(param => {
98
+ if (param.matcher) matchers.add(param.matcher);
99
+ });
98
100
 
99
- if (!route.page && !route.endpoint) return;
101
+ if (!route.page && !route.endpoint) return;
100
102
 
101
- return `{
102
- id: ${s(route.id)},
103
- pattern: ${route.pattern},
104
- params: ${s(route.params)},
105
- page: ${route.page ? `{ layouts: ${get_nodes(route.page.layouts)}, errors: ${get_nodes(route.page.errors)}, leaf: ${reindexed.get(route.page.leaf)} }` : 'null'},
106
- endpoint: ${route.endpoint ? loader(join_relative(relative_path, resolve_symlinks(build_data.server_manifest, route.endpoint.file).chunk.file)) : 'null'}
107
- }`;
108
- }).filter(Boolean).join(',\n\t\t\t\t')}
109
- ],
110
- matchers: async () => {
111
- ${Array.from(matchers).map(type => `const { match: ${type} } = await import ('${(join_relative(relative_path, `/entries/matchers/${type}.js`))}')`).join('\n\t\t\t\t')}
112
- return { ${Array.from(matchers).join(', ')} };
103
+ return dedent`
104
+ {
105
+ id: ${s(route.id)},
106
+ pattern: ${route.pattern},
107
+ params: ${s(route.params)},
108
+ page: ${route.page ? `{ layouts: ${get_nodes(route.page.layouts)}, errors: ${get_nodes(route.page.errors)}, leaf: ${reindexed.get(route.page.leaf)} }` : 'null'},
109
+ endpoint: ${route.endpoint ? loader(join_relative(relative_path, resolve_symlinks(build_data.server_manifest, route.endpoint.file).chunk.file)) : 'null'}
110
+ }
111
+ `;
112
+ }).filter(Boolean).join(',\n')}
113
+ ],
114
+ matchers: async () => {
115
+ ${Array.from(matchers).map(type => `const { match: ${type} } = await import ('${(join_relative(relative_path, `/entries/matchers/${type}.js`))}')`).join('\n')}
116
+ return { ${Array.from(matchers).join(', ')} };
117
+ }
113
118
  }
114
119
  }
115
- }`.replace(/^\t/gm, '');
120
+ `;
116
121
  }
@@ -25,9 +25,46 @@ export function write(file, code) {
25
25
  fs.writeFileSync(file, code);
26
26
  }
27
27
 
28
- /** @param {string} str */
29
- export function trim(str) {
30
- const indentation = /** @type {RegExpExecArray} */ (/\n?([ \t]*)/.exec(str))[1];
31
- const pattern = new RegExp(`^${indentation}`, 'gm');
32
- return str.replace(pattern, '').trim();
28
+ /** @type {WeakMap<TemplateStringsArray, { strings: string[], indents: string[] }>} */
29
+ const dedent_map = new WeakMap();
30
+
31
+ /**
32
+ * Allows indenting template strings without the extra indentation ending up in the result.
33
+ * Still allows indentation of lines relative to one another in the template string.
34
+ * @param {TemplateStringsArray} strings
35
+ * @param {any[]} values
36
+ */
37
+ export function dedent(strings, ...values) {
38
+ let dedented = dedent_map.get(strings);
39
+
40
+ if (!dedented) {
41
+ const indentation = /** @type {RegExpExecArray} */ (/\n?([ \t]*)/.exec(strings[0]))[1];
42
+ const pattern = new RegExp(`^${indentation}`, 'gm');
43
+
44
+ dedented = {
45
+ strings: strings.map((str) => str.replace(pattern, '')),
46
+ indents: []
47
+ };
48
+
49
+ let current = '\n';
50
+
51
+ for (let i = 0; i < values.length; i += 1) {
52
+ const string = dedented.strings[i];
53
+ const match = /\n([ \t]*)$/.exec(string);
54
+
55
+ if (match) current = match[0];
56
+ dedented.indents[i] = current;
57
+ }
58
+
59
+ dedent_map.set(strings, dedented);
60
+ }
61
+
62
+ let str = dedented.strings[0];
63
+ for (let i = 0; i < values.length; i += 1) {
64
+ str += String(values[i]).replace(/\n/g, dedented.indents[i]) + dedented.strings[i + 1];
65
+ }
66
+
67
+ str = str.trim();
68
+
69
+ return str;
33
70
  }
@@ -1,6 +1,6 @@
1
1
  import { relative_path, resolve_entry } from '../../utils/filesystem.js';
2
2
  import { s } from '../../utils/misc.js';
3
- import { trim, write_if_changed } from './utils.js';
3
+ import { dedent, write_if_changed } from './utils.js';
4
4
 
5
5
  /**
6
6
  * Writes the client manifest to disk. The manifest is used to power the router. It contains the
@@ -45,75 +45,79 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
45
45
  write_if_changed(`${output}/nodes/${i}.js`, generate_node(node));
46
46
  return `() => import('./nodes/${i}')`;
47
47
  })
48
- .join(',\n\t');
48
+ .join(',\n');
49
49
 
50
50
  const layouts_with_server_load = new Set();
51
51
 
52
- const dictionary = `{
53
- ${manifest_data.routes
54
- .map((route) => {
55
- if (route.page) {
56
- const errors = route.page.errors.slice(1).map((n) => n ?? '');
57
- const layouts = route.page.layouts.slice(1).map((n) => n ?? '');
58
-
59
- while (layouts.at(-1) === '') layouts.pop();
60
- while (errors.at(-1) === '') errors.pop();
61
-
62
- let leaf_has_server_load = false;
63
- if (route.leaf) {
64
- if (metadata) {
65
- const i = /** @type {number} */ (indices.get(route.leaf));
66
-
67
- leaf_has_server_load = metadata[i].has_server_load;
68
- } else if (route.leaf.server) {
69
- leaf_has_server_load = true;
52
+ const dictionary = dedent`
53
+ {
54
+ ${manifest_data.routes
55
+ .map((route) => {
56
+ if (route.page) {
57
+ const errors = route.page.errors.slice(1).map((n) => n ?? '');
58
+ const layouts = route.page.layouts.slice(1).map((n) => n ?? '');
59
+
60
+ while (layouts.at(-1) === '') layouts.pop();
61
+ while (errors.at(-1) === '') errors.pop();
62
+
63
+ let leaf_has_server_load = false;
64
+ if (route.leaf) {
65
+ if (metadata) {
66
+ const i = /** @type {number} */ (indices.get(route.leaf));
67
+
68
+ leaf_has_server_load = metadata[i].has_server_load;
69
+ } else if (route.leaf.server) {
70
+ leaf_has_server_load = true;
71
+ }
70
72
  }
71
- }
72
73
 
73
- // Encode whether or not the route uses server data
74
- // using the ones' complement, to save space
75
- const array = [`${leaf_has_server_load ? '~' : ''}${route.page.leaf}`];
74
+ // Encode whether or not the route uses server data
75
+ // using the ones' complement, to save space
76
+ const array = [`${leaf_has_server_load ? '~' : ''}${route.page.leaf}`];
76
77
 
77
- // Encode whether or not the layout uses server data.
78
- // It's a different method compared to pages because layouts
79
- // are reused across pages, so we save space by doing it this way.
80
- route.page.layouts.forEach((layout) => {
81
- if (layout == undefined) return;
78
+ // Encode whether or not the layout uses server data.
79
+ // It's a different method compared to pages because layouts
80
+ // are reused across pages, so we save space by doing it this way.
81
+ route.page.layouts.forEach((layout) => {
82
+ if (layout == undefined) return;
82
83
 
83
- let layout_has_server_load = false;
84
+ let layout_has_server_load = false;
84
85
 
85
- if (metadata) {
86
- layout_has_server_load = metadata[layout].has_server_load;
87
- } else if (manifest_data.nodes[layout].server) {
88
- layout_has_server_load = true;
89
- }
86
+ if (metadata) {
87
+ layout_has_server_load = metadata[layout].has_server_load;
88
+ } else if (manifest_data.nodes[layout].server) {
89
+ layout_has_server_load = true;
90
+ }
90
91
 
91
- if (layout_has_server_load) {
92
- layouts_with_server_load.add(layout);
93
- }
94
- });
92
+ if (layout_has_server_load) {
93
+ layouts_with_server_load.add(layout);
94
+ }
95
+ });
95
96
 
96
- // only include non-root layout/error nodes if they exist
97
- if (layouts.length > 0 || errors.length > 0) array.push(`[${layouts.join(',')}]`);
98
- if (errors.length > 0) array.push(`[${errors.join(',')}]`);
97
+ // only include non-root layout/error nodes if they exist
98
+ if (layouts.length > 0 || errors.length > 0) array.push(`[${layouts.join(',')}]`);
99
+ if (errors.length > 0) array.push(`[${errors.join(',')}]`);
99
100
 
100
- return `${s(route.id)}: [${array.join(',')}]`;
101
- }
102
- })
103
- .filter(Boolean)
104
- .join(',\n\t\t')}
105
- }`.replace(/^\t/gm, '');
101
+ return `${s(route.id)}: [${array.join(',')}]`;
102
+ }
103
+ })
104
+ .filter(Boolean)
105
+ .join(',\n')}
106
+ }
107
+ `;
106
108
 
107
109
  const hooks_file = resolve_entry(kit.files.hooks.client);
108
110
 
109
111
  write_if_changed(
110
112
  `${output}/app.js`,
111
- trim(`
113
+ dedent`
112
114
  ${hooks_file ? `import * as client_hooks from '${relative_path(output, hooks_file)}';` : ''}
113
115
 
114
116
  export { matchers } from './matchers.js';
115
117
 
116
- export const nodes = [${nodes}];
118
+ export const nodes = [
119
+ ${nodes}
120
+ ];
117
121
 
118
122
  export const server_loads = [${[...layouts_with_server_load].join(',')}];
119
123
 
@@ -126,7 +130,7 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
126
130
  };
127
131
 
128
132
  export { default as root } from '../root.svelte';
129
- `)
133
+ `
130
134
  );
131
135
 
132
136
  // write matchers to a separate module so that we don't
@@ -1,4 +1,4 @@
1
- import { trim, write_if_changed } from './utils.js';
1
+ import { dedent, write_if_changed } from './utils.js';
2
2
 
3
3
  /**
4
4
  * @param {import('types').ManifestData} manifest_data
@@ -24,22 +24,20 @@ export function write_root(manifest_data, output) {
24
24
  let pyramid = `<svelte:component this={constructors[${l}]} bind:this={components[${l}]} data={data_${l}} {form} />`;
25
25
 
26
26
  while (l--) {
27
- pyramid = `
27
+ pyramid = dedent`
28
28
  {#if constructors[${l + 1}]}
29
29
  <svelte:component this={constructors[${l}]} bind:this={components[${l}]} data={data_${l}}>
30
- ${pyramid.replace(/\n/g, '\n\t\t\t\t\t')}
30
+ ${pyramid}
31
31
  </svelte:component>
32
32
  {:else}
33
33
  <svelte:component this={constructors[${l}]} bind:this={components[${l}]} data={data_${l}} {form} />
34
34
  {/if}
35
- `
36
- .replace(/^\t\t\t/gm, '')
37
- .trim();
35
+ `;
38
36
  }
39
37
 
40
38
  write_if_changed(
41
39
  `${output}/root.svelte`,
42
- trim(`
40
+ dedent`
43
41
  <!-- This file is generated by @sveltejs/kit — do not edit it! -->
44
42
  <script>
45
43
  import { setContext, afterUpdate, onMount } from 'svelte';
@@ -52,7 +50,7 @@ export function write_root(manifest_data, output) {
52
50
  export let constructors;
53
51
  export let components = [];
54
52
  export let form;
55
- ${levels.map((l) => `export let data_${l} = null;`).join('\n\t\t\t\t')}
53
+ ${levels.map((l) => `export let data_${l} = null;`).join('\n')}
56
54
 
57
55
  if (!browser) {
58
56
  setContext('__svelte__', stores);
@@ -78,7 +76,7 @@ export function write_root(manifest_data, output) {
78
76
  });
79
77
  </script>
80
78
 
81
- ${pyramid.replace(/\n/g, '\n\t\t\t')}
79
+ ${pyramid}
82
80
 
83
81
  {#if mounted}
84
82
  <div id="svelte-announcer" aria-live="assertive" aria-atomic="true" style="position: absolute; left: 0; top: 0; clip: rect(0 0 0 0); clip-path: inset(50%); overflow: hidden; white-space: nowrap; width: 1px; height: 1px">
@@ -87,6 +85,6 @@ export function write_root(manifest_data, output) {
87
85
  {/if}
88
86
  </div>
89
87
  {/if}
90
- `)
88
+ `
91
89
  );
92
90
  }
@@ -1,5 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import * as vite from 'vite';
3
+ import { dedent } from '../../../core/sync/utils.js';
3
4
  import { s } from '../../../utils/misc.js';
4
5
  import { get_config_aliases } from '../utils.js';
5
6
  import { assets_base } from './utils.js';
@@ -34,28 +35,26 @@ export async function build_service_worker(
34
35
 
35
36
  fs.writeFileSync(
36
37
  service_worker,
37
- `
38
+ dedent`
38
39
  export const build = [
39
40
  ${Array.from(build)
40
41
  .map((file) => `${s(`${kit.paths.base}/${file}`)}`)
41
- .join(',\n\t\t\t\t')}
42
+ .join(',\n')}
42
43
  ];
43
44
 
44
45
  export const files = [
45
46
  ${manifest_data.assets
46
47
  .filter((asset) => kit.serviceWorker.files(asset.file))
47
48
  .map((asset) => `${s(`${kit.paths.base}/${asset.file}`)}`)
48
- .join(',\n\t\t\t\t')}
49
+ .join(',\n')}
49
50
  ];
50
51
 
51
52
  export const prerendered = [
52
- ${prerendered.paths.map((path) => s(path)).join(',\n\t\t\t\t')}
53
+ ${prerendered.paths.map((path) => s(path)).join(',\n')}
53
54
  ];
54
55
 
55
56
  export const version = ${s(kit.version.name)};
56
57
  `
57
- .replace(/^\t{3}/gm, '')
58
- .trim()
59
58
  );
60
59
 
61
60
  await vite.build({
@@ -24,6 +24,7 @@ import prerender from '../../core/postbuild/prerender.js';
24
24
  import analyse from '../../core/postbuild/analyse.js';
25
25
  import { s } from '../../utils/misc.js';
26
26
  import { hash } from '../../runtime/hash.js';
27
+ import { dedent } from '../../core/sync/utils.js';
27
28
 
28
29
  export { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
29
30
 
@@ -354,13 +355,16 @@ function kit({ svelte_config }) {
354
355
  switch (id) {
355
356
  case '\0$env/static/private':
356
357
  return create_static_module('$env/static/private', env.private);
358
+
357
359
  case '\0$env/static/public':
358
360
  return create_static_module('$env/static/public', env.public);
361
+
359
362
  case '\0$env/dynamic/private':
360
363
  return create_dynamic_module(
361
364
  'private',
362
365
  vite_config_env.command === 'serve' ? env.private : undefined
363
366
  );
367
+
364
368
  case '\0$env/dynamic/public':
365
369
  // populate `$env/dynamic/public` from `window`
366
370
  if (browser) {
@@ -371,6 +375,7 @@ function kit({ svelte_config }) {
371
375
  'public',
372
376
  vite_config_env.command === 'serve' ? env.public : undefined
373
377
  );
378
+
374
379
  case '\0$service-worker':
375
380
  return create_service_worker_module(svelte_config);
376
381
 
@@ -383,40 +388,47 @@ function kit({ svelte_config }) {
383
388
  // for the sake of things like Vitest which may import this module
384
389
  // outside the context of a page
385
390
  if (browser) {
386
- return `export const base = ${global}?.base ?? ${s(base)};
387
- export const assets = ${global}?.assets ?? ${assets ? s(assets) : 'base'};`;
391
+ return dedent`
392
+ export const base = ${global}?.base ?? ${s(base)};
393
+ export const assets = ${global}?.assets ?? ${assets ? s(assets) : 'base'};
394
+ `;
388
395
  }
389
396
 
390
- return `export let base = ${s(base)};
391
- export let assets = ${assets ? s(assets) : 'base'};
397
+ return dedent`
398
+ export let base = ${s(base)};
399
+ export let assets = ${assets ? s(assets) : 'base'};
392
400
 
393
- export const relative = ${svelte_config.kit.paths.relative};
401
+ export const relative = ${svelte_config.kit.paths.relative};
394
402
 
395
- const initial = { base, assets };
403
+ const initial = { base, assets };
396
404
 
397
- export function override(paths) {
398
- base = paths.base;
399
- assets = paths.assets;
400
- }
405
+ export function override(paths) {
406
+ base = paths.base;
407
+ assets = paths.assets;
408
+ }
401
409
 
402
- export function reset() {
403
- base = initial.base;
404
- assets = initial.assets;
405
- }
410
+ export function reset() {
411
+ base = initial.base;
412
+ assets = initial.assets;
413
+ }
406
414
 
407
- /** @param {string} path */
408
- export function set_assets(path) {
409
- assets = initial.assets = path;
410
- }`;
415
+ /** @param {string} path */
416
+ export function set_assets(path) {
417
+ assets = initial.assets = path;
418
+ }
419
+ `;
411
420
 
412
421
  case '\0__sveltekit/environment':
413
422
  const { version } = svelte_config.kit;
414
- return `export const version = ${s(version.name)};
415
- export let building = false;
416
423
 
417
- export function set_building() {
418
- building = true;
419
- }`;
424
+ return dedent`
425
+ export const version = ${s(version.name)};
426
+ export let building = false;
427
+
428
+ export function set_building() {
429
+ building = true;
430
+ }
431
+ `;
420
432
  }
421
433
  }
422
434
  };
@@ -863,18 +875,18 @@ function find_overridden_config(config, resolved_config, enforced_config, path,
863
875
  /**
864
876
  * @param {import('types').ValidatedConfig} config
865
877
  */
866
- const create_service_worker_module = (config) => `
867
- if (typeof self === 'undefined' || self instanceof ServiceWorkerGlobalScope === false) {
868
- throw new Error('This module can only be imported inside a service worker');
869
- }
878
+ const create_service_worker_module = (config) => dedent`
879
+ if (typeof self === 'undefined' || self instanceof ServiceWorkerGlobalScope === false) {
880
+ throw new Error('This module can only be imported inside a service worker');
881
+ }
870
882
 
871
- export const build = [];
872
- export const files = [
873
- ${create_assets(config)
874
- .filter((asset) => config.kit.serviceWorker.files(asset.file))
875
- .map((asset) => `${s(`${config.kit.paths.base}/${asset.file}`)}`)
876
- .join(',\n\t\t\t\t')}
877
- ];
878
- export const prerendered = [];
879
- export const version = ${s(config.kit.version.name)};
883
+ export const build = [];
884
+ export const files = [
885
+ ${create_assets(config)
886
+ .filter((asset) => config.kit.serviceWorker.files(asset.file))
887
+ .map((asset) => `${s(`${config.kit.paths.base}/${asset.file}`)}`)
888
+ .join(',\n')}
889
+ ];
890
+ export const prerendered = [];
891
+ export const version = ${s(config.kit.version.name)};
880
892
  `;
@@ -1410,14 +1410,19 @@ export function create_client(app, target) {
1410
1410
  goto(result.location, { invalidateAll: true }, []);
1411
1411
  } else {
1412
1412
  /** @type {Record<string, any>} */
1413
- const props = {
1414
- form: result.data,
1413
+ root.$set({
1414
+ // this brings Svelte's view of the world in line with SvelteKit's
1415
+ // after use:enhance reset the form....
1416
+ form: null,
1415
1417
  page: { ...page, form: result.data, status: result.status }
1416
- };
1417
- root.$set(props);
1418
+ });
1419
+
1420
+ // ...so that setting the `form` prop takes effect and isn't ignored
1421
+ await tick();
1422
+ root.$set({ form: result.data });
1418
1423
 
1419
1424
  if (result.type === 'success') {
1420
- tick().then(reset_focus);
1425
+ reset_focus();
1421
1426
  }
1422
1427
  }
1423
1428
  },
@@ -98,6 +98,25 @@ export function get_cookies(request, url, trailing_slash) {
98
98
  }
99
99
  },
100
100
 
101
+ /**
102
+ * @param {import('cookie').CookieParseOptions} opts
103
+ */
104
+ getAll(opts) {
105
+ const decoder = opts?.decode || decodeURIComponent;
106
+ const cookies = parse(header, { decode: decoder });
107
+
108
+ for (const c of Object.values(new_cookies)) {
109
+ if (
110
+ domain_matches(url.hostname, c.options.domain) &&
111
+ path_matches(url.pathname, c.options.path)
112
+ ) {
113
+ cookies[c.name] = c.value;
114
+ }
115
+ }
116
+
117
+ return Object.entries(cookies).map(([name, value]) => ({ name, value }));
118
+ },
119
+
101
120
  /**
102
121
  * @param {string} name
103
122
  * @param {string} value
@@ -235,20 +235,20 @@ export async function render_response({
235
235
  for (const dep of stylesheets) {
236
236
  const path = prefixed(dep);
237
237
 
238
- if (resolve_opts.preload({ type: 'css', path })) {
239
- const attributes = ['rel="stylesheet"'];
240
-
241
- if (inline_styles.has(dep)) {
242
- // don't load stylesheets that are already inlined
243
- // include them in disabled state so that Vite can detect them and doesn't try to add them
244
- attributes.push('disabled', 'media="(max-width: 0)"');
245
- } else {
238
+ const attributes = ['rel="stylesheet"'];
239
+
240
+ if (inline_styles.has(dep)) {
241
+ // don't load stylesheets that are already inlined
242
+ // include them in disabled state so that Vite can detect them and doesn't try to add them
243
+ attributes.push('disabled', 'media="(max-width: 0)"');
244
+ } else {
245
+ if (resolve_opts.preload({ type: 'css', path })) {
246
246
  const preload_atts = ['rel="preload"', 'as="style"'];
247
247
  link_header_preloads.add(`<${encodeURI(path)}>; ${preload_atts.join(';')}; nopush`);
248
248
  }
249
-
250
- head += `\n\t\t<link href="${path}" ${attributes.join(' ')}>`;
251
249
  }
250
+
251
+ head += `\n\t\t<link href="${path}" ${attributes.join(' ')}>`;
252
252
  }
253
253
 
254
254
  for (const dep of fonts) {
package/types/index.d.ts CHANGED
@@ -198,7 +198,13 @@ export interface Cookies {
198
198
  get(name: string, opts?: import('cookie').CookieParseOptions): string | undefined;
199
199
 
200
200
  /**
201
- * Sets a cookie. This will add a `set-cookie` header to the response, but also make the cookie available via `cookies.get` during the current request.
201
+ * Gets all cookies that were previously set with `cookies.set`, or from the request headers.
202
+ * @param opts the options, passed directily to `cookie.parse`. See documentation [here](https://github.com/jshttp/cookie#cookieparsestr-options)
203
+ */
204
+ getAll(opts?: import('cookie').CookieParseOptions): Array<{ name: string; value: string }>;
205
+
206
+ /**
207
+ * Sets a cookie. This will add a `set-cookie` header to the response, but also make the cookie available via `cookies.get` or `cookies.getAll` during the current request.
202
208
  *
203
209
  * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`.
204
210
  *