@sveltejs/kit 3.0.0-next.23 → 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 (105) hide show
  1. package/package.json +51 -8
  2. package/src/cli.js +3 -3
  3. package/src/constants.js +19 -1
  4. package/src/core/adapt/builder.js +3 -5
  5. package/src/core/env.js +137 -182
  6. package/src/core/postbuild/analyse.js +9 -4
  7. package/src/core/postbuild/prerender.js +5 -6
  8. package/src/core/sync/create_manifest_data/index.js +29 -33
  9. package/src/core/sync/sync.js +23 -40
  10. package/src/core/sync/write_app_manifest.js +83 -0
  11. package/src/core/sync/write_client_manifest.js +6 -4
  12. package/src/core/sync/write_server.js +12 -22
  13. package/src/core/sync/write_types/index.js +2 -2
  14. package/src/core/utils.js +10 -28
  15. package/src/exports/adapter.js +22 -0
  16. package/src/exports/hooks/public.d.ts +9 -1
  17. package/src/exports/node/index.js +77 -5
  18. package/src/exports/public.d.ts +1 -1
  19. package/src/exports/vite/build/build_server.js +3 -3
  20. package/src/exports/vite/build/service-worker.js +98 -0
  21. package/src/exports/vite/build/utils.js +48 -4
  22. package/src/exports/vite/dev/index.js +28 -25
  23. package/src/exports/vite/index.js +94 -747
  24. package/src/exports/vite/module_ids.js +1 -11
  25. package/src/exports/vite/plugins/env-vars.js +159 -0
  26. package/src/exports/vite/plugins/guard.js +205 -0
  27. package/src/exports/vite/preview/index.js +6 -4
  28. package/src/exports/vite/utils.js +99 -4
  29. package/src/runtime/app/env/{types.d.ts → client.js} +9 -4
  30. package/src/runtime/app/env/index.js +1 -2
  31. package/src/runtime/app/env/private/index.js +1 -0
  32. package/src/runtime/app/env/public/client.js +1 -1
  33. package/src/runtime/app/env/public/server.js +1 -1
  34. package/src/runtime/app/env/{internal.js → server.js} +4 -4
  35. package/src/runtime/app/forms/client.js +263 -0
  36. package/src/runtime/app/forms/index.js +1 -263
  37. package/src/runtime/app/forms/public.d.ts +1 -1
  38. package/src/runtime/app/forms/server.js +6 -0
  39. package/src/runtime/app/forms/shared.js +34 -0
  40. package/src/runtime/app/manifest/index.js +1 -1
  41. package/src/runtime/app/navigation/client.js +15 -0
  42. package/src/runtime/app/navigation/index.js +1 -15
  43. package/src/runtime/app/navigation/public.d.ts +1 -1
  44. package/src/runtime/app/navigation/server.js +15 -0
  45. package/src/runtime/app/paths/server.js +1 -1
  46. package/src/runtime/app/server/remote/form.js +11 -1
  47. package/src/runtime/app/server/remote/prerender.js +1 -2
  48. package/src/runtime/app/server/remote/query.js +3 -3
  49. package/src/runtime/app/state/client.svelte.js +207 -0
  50. package/src/runtime/app/state/index.js +1 -66
  51. package/src/runtime/app/state/public.d.ts +1 -1
  52. package/src/runtime/client/bundle.js +1 -1
  53. package/src/runtime/client/client.js +210 -278
  54. package/src/runtime/client/fetcher.js +18 -8
  55. package/src/runtime/client/remote-functions/form.svelte.js +9 -6
  56. package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
  57. package/src/runtime/client/remote-functions/query-live/iterator.js +1 -1
  58. package/src/runtime/client/remote-functions/shared.svelte.js +2 -2
  59. package/src/runtime/client/snapshots.js +1 -3
  60. package/src/runtime/client/stream.js +27 -20
  61. package/src/runtime/client/utils.js +7 -3
  62. package/src/runtime/components/root.svelte +5 -5
  63. package/src/runtime/env/dynamic/private.js +1 -1
  64. package/src/runtime/env/static/private.js +1 -1
  65. package/src/runtime/error-chain.js +54 -0
  66. package/src/runtime/form-utils.js +55 -87
  67. package/src/runtime/invalid-import.js +1 -0
  68. package/src/runtime/props.svelte.js +1 -1
  69. package/src/runtime/server/data/index.js +12 -27
  70. package/src/runtime/server/endpoint.js +8 -3
  71. package/src/runtime/server/env_module.js +1 -1
  72. package/src/runtime/server/errors.js +9 -12
  73. package/src/runtime/server/fetch.js +14 -16
  74. package/src/runtime/server/index.js +30 -27
  75. package/src/runtime/server/internal.js +34 -4
  76. package/src/runtime/server/page/actions.js +77 -124
  77. package/src/runtime/server/page/data_serializer.js +6 -10
  78. package/src/runtime/server/page/index.js +45 -82
  79. package/src/runtime/server/page/render.js +34 -52
  80. package/src/runtime/server/page/respond_with_error.js +7 -9
  81. package/src/runtime/server/remote-functions.js +138 -166
  82. package/src/runtime/server/respond.js +75 -30
  83. package/src/runtime/server/state.js +1 -0
  84. package/src/runtime/server/utils.js +0 -7
  85. package/src/runtime/utils.js +41 -0
  86. package/src/telemetry.js +1 -33
  87. package/src/types/ambient-private.d.ts +9 -17
  88. package/src/types/global-private.d.ts +8 -0
  89. package/src/types/internal.d.ts +27 -15
  90. package/src/types/private.d.ts +1 -1
  91. package/src/utils/exports.js +1 -0
  92. package/src/utils/filesystem.js +10 -22
  93. package/src/utils/functions.js +10 -0
  94. package/src/utils/routing.js +0 -11
  95. package/src/utils/streaming.js +5 -15
  96. package/src/utils/url.js +0 -11
  97. package/src/version.js +1 -1
  98. package/types/index.d.ts +54 -29
  99. package/types/index.d.ts.map +10 -5
  100. package/src/runtime/app/env/private.js +0 -1
  101. package/src/runtime/app/env/standard-schema.d.ts +0 -0
  102. package/src/runtime/app/state/client.js +0 -63
  103. package/src/runtime/client/state.svelte.js +0 -98
  104. package/src/runtime/server/ambient.d.ts +0 -4
  105. package/src/utils/path.js +0 -23
@@ -3,7 +3,6 @@ import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'no
3
3
  import { dirname, join } from 'node:path';
4
4
  import { pathToFileURL } from 'node:url';
5
5
  import { walk } from '../../utils/filesystem.js';
6
- import { posixify } from '../../utils/os.js';
7
6
  import { noop } from '../../utils/functions.js';
8
7
  import { decode_uri, is_root_relative, resolve } from '../../utils/url.js';
9
8
  import { escape_html } from '../../utils/escape.js';
@@ -53,7 +52,7 @@ async function prerender({
53
52
  const manifest = (await import(pathToFileURL(manifest_path).href)).manifest;
54
53
 
55
54
  /** @type {import('types').ServerInternalModule} */
56
- const { set_building, set_prerendering, set_manifest, set_read_implementation, log_response } =
55
+ const { set_building, set_prerendering, set_manifest, set_read_implementation, format_response } =
57
56
  await import(pathToFileURL(`${out}/server/internal.js`).href);
58
57
 
59
58
  // configure `import { building } from `$app/env` —
@@ -63,7 +62,7 @@ async function prerender({
63
62
 
64
63
  // `set_env` and `Server` live in modules that import the user's `src/env` config. We import them
65
64
  // *after* `set_building()` so that `building`-dependent expressions resolve correctly
66
- /** @type {typeof import('__sveltekit/env')} */
65
+ /** @type {typeof import('<sveltekit:generated>/env/config.js')} */
67
66
  const { set_env } = await import(pathToFileURL(`${out}/server/env.js`).href);
68
67
  set_env(env);
69
68
 
@@ -256,13 +255,13 @@ async function prerender({
256
255
  return file;
257
256
  }
258
257
 
259
- const files = new Set(walk(`${out}/client`).map(posixify));
258
+ const files = new Set(walk(`${out}/client`));
260
259
  files.add(`${config.appDir}/env.js`);
261
260
 
262
261
  const immutable = `${config.appDir}/immutable`;
263
262
  if (existsSync(`${out}/server/${immutable}`)) {
264
263
  for (const file of walk(`${out}/server/${immutable}`)) {
265
- files.add(posixify(`${config.appDir}/immutable/${file}`));
264
+ files.add(`${config.appDir}/immutable/${file}`);
266
265
  }
267
266
  }
268
267
 
@@ -425,7 +424,7 @@ async function prerender({
425
424
  }
426
425
 
427
426
  if (response.status >= 400) {
428
- log_response(response.status, request);
427
+ console.log(format_response(response.status, request));
429
428
  }
430
429
 
431
430
  const body = Buffer.from(await response.arrayBuffer());
@@ -1,11 +1,12 @@
1
+ /** @import { ValidatedConfig } from 'types' */
1
2
  import { lookup } from '../../../utils/mime.js';
2
3
  import fs from 'node:fs';
3
4
  import path from 'node:path';
4
5
  import { styleText } from 'node:util';
5
- import { resolve_entry } from '../../../utils/filesystem.js';
6
+ import { resolve_entry, walk } from '../../../utils/filesystem.js';
6
7
  import { posixify } from '../../../utils/os.js';
7
8
  import { parse_route_id } from '../../../utils/routing.js';
8
- import { list_files, runtime_directory } from '../../utils.js';
9
+ import { runtime_directory } from '../../utils.js';
9
10
  import { prevent_conflicts } from './conflict.js';
10
11
  import { sort_routes } from './sort.js';
11
12
  import {
@@ -13,24 +14,27 @@ import {
13
14
  get_page_options
14
15
  } from '../../../exports/vite/static_analysis/index.js';
15
16
 
17
+ const component_name_pattern = /^\+(?:(page(?:@(.*))?)|(layout(?:@(.*))?)|(error))$/;
18
+
19
+ const module_name_pattern =
20
+ /^\+(?:(server)|(page(?:(@[a-zA-Z0-9_-]*))?(\.server)?)|(layout(?:(@[a-zA-Z0-9_-]*))?(\.server)?))$/;
21
+
16
22
  /**
17
23
  * Generates the manifest data used for the client-side manifest and types generation.
18
- * @param {{
19
- * config: import('types').ValidatedConfig;
20
- * fallback?: string;
21
- * cwd: string;
22
- * }} opts
24
+ * @param {ValidatedConfig} config
25
+ * @param {string} root
26
+ * @param {string} [fallback] Where to look for fallback components
23
27
  * @returns {import('types').ManifestData}
24
28
  */
25
- export default function create_manifest_data({
29
+ export default function create_manifest_data(
26
30
  config,
27
- fallback = `${runtime_directory}/components`,
28
- cwd
29
- }) {
31
+ root,
32
+ fallback = `${runtime_directory}/components`
33
+ ) {
30
34
  const assets = create_assets(config);
31
- const hooks = create_hooks(config, cwd);
32
- const params = resolve_params(config, cwd);
33
- const { nodes, routes } = create_routes_and_nodes(cwd, config, fallback);
35
+ const hooks = create_hooks(config, root);
36
+ const params = resolve_params(config, root);
37
+ const { nodes, routes } = create_routes_and_nodes(root, config, fallback);
34
38
 
35
39
  return {
36
40
  assets,
@@ -74,7 +78,9 @@ export function is_app_route(route) {
74
78
  * @param {import('types').ValidatedConfig} config
75
79
  */
76
80
  export function create_assets(config) {
77
- return list_files(config.files.assets).map((file) => ({
81
+ if (!fs.existsSync(config.files.assets)) return [];
82
+
83
+ return [...walk(config.files.assets)].map((file) => ({
78
84
  file,
79
85
  size: fs.statSync(path.resolve(config.files.assets, file)).size,
80
86
  type: lookup(file) || null
@@ -232,13 +238,12 @@ function create_routes_and_nodes(cwd, config, fallback) {
232
238
 
233
239
  if (!file.name.startsWith('+')) {
234
240
  const name = file.name.slice(0, -ext.length);
241
+ const pattern = config.extensions.includes(ext)
242
+ ? component_name_pattern
243
+ : module_name_pattern;
244
+
235
245
  // check if it is a valid route filename but missing the + prefix
236
- const typo =
237
- /^(?:(page(?:@(.*))?)|(layout(?:@(.*))?)|(error))$/.test(name) ||
238
- /^(?:(server)|(page(?:(@[a-zA-Z0-9_-]*))?(\.server)?)|(layout(?:(@[a-zA-Z0-9_-]*))?(\.server)?))$/.test(
239
- name
240
- );
241
- if (typo) {
246
+ if (pattern.test(`+${name}`)) {
242
247
  console.log(
243
248
  styleText(
244
249
  ['bold', 'yellow'],
@@ -265,13 +270,7 @@ function create_routes_and_nodes(cwd, config, fallback) {
265
270
  const ext = valid_extensions.find((ext) => name.endsWith(ext));
266
271
  if (ext) name = name.slice(0, -ext.length);
267
272
 
268
- const valid =
269
- /^\+(?:(page(?:@(.*))?)|(layout(?:@(.*))?)|(error))$/.test(name) ||
270
- /^\+(?:(server)|(page(?:(@[a-zA-Z0-9_-]*))?(\.server)?)|(layout(?:(@[a-zA-Z0-9_-]*))?(\.server)?))$/.test(
271
- name
272
- );
273
-
274
- if (valid) continue;
273
+ if (component_name_pattern.test(name) || module_name_pattern.test(name)) continue;
275
274
  }
276
275
 
277
276
  const project_relative = posixify(path.relative(cwd, path.join(dir, file.name)));
@@ -535,8 +534,7 @@ function analyze(project_relative, file, component_extensions, module_extensions
535
534
  const component_extension = component_extensions.find((ext) => file.endsWith(ext));
536
535
  if (component_extension) {
537
536
  const name = file.slice(0, -component_extension.length);
538
- const pattern = /^\+(?:(page(?:@(.*))?)|(layout(?:@(.*))?)|(error))$/;
539
- const match = pattern.exec(name);
537
+ const match = component_name_pattern.exec(name);
540
538
  if (!match) {
541
539
  throw new Error(`Files prefixed with + are reserved (saw ${project_relative})`);
542
540
  }
@@ -553,9 +551,7 @@ function analyze(project_relative, file, component_extensions, module_extensions
553
551
  const module_extension = module_extensions.find((ext) => file.endsWith(ext));
554
552
  if (module_extension) {
555
553
  const name = file.slice(0, -module_extension.length);
556
- const pattern =
557
- /^\+(?:(server)|(page(?:(@[a-zA-Z0-9_-]*))?(\.server)?)|(layout(?:(@[a-zA-Z0-9_-]*))?(\.server)?))$/;
558
- const match = pattern.exec(name);
554
+ const match = module_name_pattern.exec(name);
559
555
  if (!match) {
560
556
  throw new Error(`Files prefixed with + are reserved (saw ${project_relative})`);
561
557
  } else if (match[3] || match[6]) {
@@ -1,3 +1,4 @@
1
+ /** @import { ValidatedConfig, ManifestData } from 'types' */
1
2
  import path from 'node:path';
2
3
  import create_manifest_data from './create_manifest_data/index.js';
3
4
  import { write_client_manifest } from './write_client_manifest.js';
@@ -11,39 +12,30 @@ import {
11
12
  } from '../../exports/vite/static_analysis/index.js';
12
13
  import { load_explicit_env } from '../env.js';
13
14
  import { write_env } from './write_env.js';
14
-
15
- /**
16
- * Initialize SvelteKit's generated files that only depend on the config and mode.
17
- * @param {import('types').ValidatedConfig} config
18
- * @param {string} root The project root directory
19
- */
20
- export function init(config, root) {
21
- write_tsconfig(config, root);
22
- }
15
+ import { write_app_manifest } from './write_app_manifest.js';
23
16
 
24
17
  /**
25
18
  * Update SvelteKit's generated files
26
- * @param {import('types').ValidatedConfig} config
19
+ * @param {ValidatedConfig} config
27
20
  * @param {string} root The project root directory
21
+ * @param {ManifestData} manifest_data
22
+ * @param {boolean} is_build
28
23
  */
29
- export function create(config, root) {
30
- const manifest_data = create_manifest_data({ config, cwd: root });
24
+ export function create(config, root, manifest_data, is_build) {
25
+ const output = path.join(config.outDir, `generated/${is_build ? 'build' : 'dev'}`);
31
26
 
32
- const output = path.join(config.outDir, 'generated');
33
-
34
- write_client_manifest(config, manifest_data, `${output}/client`);
27
+ write_app_manifest(output, manifest_data, is_build);
28
+ write_client_manifest(config, manifest_data, `${output}/client`, root);
35
29
  write_server(config, output, root);
36
30
  write_all_types(config, manifest_data, root);
37
31
  write_app_types(config, manifest_data, root);
38
-
39
- return { manifest_data };
40
32
  }
41
33
 
42
34
  /**
43
35
  * Update SvelteKit's generated files in response to a single file content update.
44
36
  * Do not call this when the file in question was created/deleted.
45
37
  *
46
- * @param {import('types').ValidatedConfig} config
38
+ * @param {ValidatedConfig} config
47
39
  * @param {import('types').ManifestData} manifest_data
48
40
  * @param {string} file
49
41
  * @param {string} root The project root directory
@@ -79,48 +71,39 @@ export function update(config, manifest_data, file, root) {
79
71
  }
80
72
 
81
73
  /**
82
- * Run sync.init and sync.create in series, returning the result from sync.create.
83
- * @param {import('types').ValidatedConfig} config
74
+ * Run write_tsconfig and sync.create in series during build
75
+ * @param {ValidatedConfig} config
84
76
  * @param {string} root The project root directory
77
+ * @param {ManifestData} manifest_data
85
78
  */
86
- export function all(config, root) {
87
- init(config, root);
88
- return create(config, root);
79
+ export function all(config, root, manifest_data) {
80
+ write_tsconfig(config, root);
81
+ create(config, root, manifest_data, true);
89
82
  }
90
83
 
91
84
  /**
92
85
  * Run sync.init and then generate all type files.
93
- * @param {import('types').ValidatedConfig} config
86
+ * @param {ValidatedConfig} config
94
87
  * @param {string} root
95
88
  */
96
89
  export function all_types(config, root) {
97
- init(config, root);
98
- const manifest_data = create_manifest_data({ config, cwd: root });
90
+ write_tsconfig(config, root);
91
+ const manifest_data = create_manifest_data(config, root);
99
92
  write_all_types(config, manifest_data, root);
100
93
  write_app_types(config, manifest_data, root);
101
94
  }
102
95
 
103
96
  /**
104
97
  * Generate modules and types for explicit env vars
105
- * @param {typeof import('vite')} vite
106
- * @param {import('types').ValidatedConfig} kit
98
+ * @param {ValidatedConfig} kit
107
99
  * @param {string | null} entry
108
100
  * @param {string} root The Vite root
109
101
  * @param {string} mode The Vite mode
110
102
  */
111
- export async function env(vite, kit, entry, root, mode) {
112
- const env_config = await load_explicit_env(vite, kit, entry, root, mode);
103
+ export async function env(kit, entry, root, mode) {
104
+ const env_config = await load_explicit_env(kit, entry, root, mode);
113
105
 
114
- write_env(entry, env_config, root);
106
+ write_env(entry, env_config.variables, root);
115
107
 
116
108
  return env_config;
117
109
  }
118
-
119
- /**
120
- * Regenerate __SERVER__/internal.js in response to src/{app.html,error.html,service-worker.js} changing
121
- * @param {import('types').ValidatedConfig} config
122
- * @param {string} root The project root directory
123
- */
124
- export function server(config, root) {
125
- write_server(config, path.join(config.outDir, 'generated'), root);
126
- }
@@ -0,0 +1,83 @@
1
+ /** @import { Asset, ManifestData, RouteData } from 'types' */
2
+
3
+ import { s } from '../../utils/misc.js';
4
+ import { is_app_route, is_endpoint_route, is_page_route } from './create_manifest_data/index.js';
5
+ import { dedent, write_if_changed } from './utils.js';
6
+
7
+ /**
8
+ * Creates the `$app/manifest` data module. During development, real values
9
+ * are emitted for `assets` and `routes` (the only data known at that point).
10
+ *
11
+ * During build, bare identifier placeholders (fake globals) are emitted.
12
+ * The bundler leaves these as unresolved global references in the output,
13
+ * which are then replaced with real values by scanning the output chunks
14
+ * after each build completes. This avoids the content-hash feedback loop:
15
+ * the manifest data lives in its own chunk with a fixed filename, so
16
+ * importers' hashes are stable regardless of the manifest content.
17
+ *
18
+ * @param {string} out
19
+ * @param {ManifestData | undefined} manifest_data
20
+ * @param {boolean} is_build
21
+ */
22
+ export function write_app_manifest(out, manifest_data, is_build) {
23
+ const code = is_build
24
+ ? // Bare identifiers (fake globals) — the bundler leaves these as
25
+ // unresolved global references in the output. They are replaced
26
+ // with real values by `replace_manifest_placeholder_variables`
27
+ // after each build completes.
28
+ dedent`
29
+ export const immutable = __SVELTEKIT_MANIFEST_IMMUTABLE__;
30
+ export const assets = __SVELTEKIT_MANIFEST_ASSETS__;
31
+ export const prerendered = __SVELTEKIT_MANIFEST_PRERENDERED__;
32
+ export const routes = __SVELTEKIT_MANIFEST_ROUTES__;
33
+ `
34
+ : // In dev, an empty manifest is written before dependency scanning starts.
35
+ // `configureServer` replaces it with the full manifest before modules are served.
36
+ dedent`
37
+ // empty during dev
38
+ export const immutable = [];
39
+ export const prerendered = [];
40
+
41
+ export const assets = [
42
+ ${stringify_assets(manifest_data?.assets)}
43
+ ];
44
+
45
+ export const routes = [
46
+ ${stringify_routes(manifest_data?.routes)}
47
+ ];
48
+ `;
49
+
50
+ write_if_changed(`${out}/app-manifest.js`, code);
51
+ }
52
+
53
+ /**
54
+ * @param {Asset[] | undefined} assets
55
+ * @returns {string}
56
+ */
57
+ function stringify_assets(assets) {
58
+ return assets?.map((asset) => s({ path: asset.file })).join(',\n') ?? '';
59
+ }
60
+
61
+ /**
62
+ * @param {RouteData[] | undefined} routes
63
+ * @returns {Array<{ id: string; page: boolean; endpoint: boolean }>}
64
+ */
65
+ export function get_manifest_routes(routes) {
66
+ return (
67
+ routes?.filter(is_app_route).map((route) => ({
68
+ id: route.id,
69
+ page: is_page_route(route),
70
+ endpoint: is_endpoint_route(route)
71
+ })) ?? []
72
+ );
73
+ }
74
+
75
+ /**
76
+ * @param {RouteData[] | undefined} routes
77
+ * @returns {string}
78
+ */
79
+ function stringify_routes(routes) {
80
+ return get_manifest_routes(routes)
81
+ .map((route) => s(route))
82
+ .join(',\n');
83
+ }
@@ -1,3 +1,4 @@
1
+ import path from 'node:path';
1
2
  import { check_spelling, dedent, write_if_changed } from './utils.js';
2
3
  import { relative_path, resolve_entry } from '../../utils/filesystem.js';
3
4
  import { s } from '../../utils/misc.js';
@@ -8,9 +9,10 @@ import { s } from '../../utils/misc.js';
8
9
  * @param {import('types').ValidatedConfig} kit
9
10
  * @param {import('types').ManifestData} manifest_data
10
11
  * @param {string} output
12
+ * @param {string} root The project root directory
11
13
  * @param {import('types').ServerMetadata['nodes']} [metadata] If this is omitted, we have to assume that all routes with a `+layout/page.server.js` file have a server load function
12
14
  */
13
- export function write_client_manifest(kit, manifest_data, output, metadata) {
15
+ export function write_client_manifest(kit, manifest_data, output, root, metadata) {
14
16
  const client_routing = kit.router.resolution === 'client';
15
17
 
16
18
  /**
@@ -22,7 +24,7 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
22
24
 
23
25
  if (node.universal) {
24
26
  declarations.push(
25
- `import * as universal from ${s(relative_path(`${output}/nodes`, node.universal))};`,
27
+ `import * as universal from ${s(relative_path(`${output}/nodes`, path.resolve(root, node.universal)))};`,
26
28
  'export { universal };'
27
29
  );
28
30
  }
@@ -30,7 +32,7 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
30
32
  if (node.component) {
31
33
  declarations.push(
32
34
  `export { default as component } from ${s(
33
- relative_path(`${output}/nodes`, node.component)
35
+ relative_path(`${output}/nodes`, path.resolve(root, node.component))
34
36
  )};`
35
37
  );
36
38
  }
@@ -180,7 +182,7 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
180
182
  const module =
181
183
  !manifest_data.params || !uses_matchers
182
184
  ? 'export const matchers = {};'
183
- : `import { params as matchers } from ${s(relative_path(output, manifest_data.params))};\n\nexport { matchers };`;
185
+ : `import { params as matchers } from ${s(relative_path(output, path.resolve(root, manifest_data.params)))};\n\nexport { matchers };`;
184
186
 
185
187
  write_if_changed(`${output}/matchers.js`, module);
186
188
  }
@@ -1,44 +1,37 @@
1
1
  import path from 'node:path';
2
- import { hash } from '../../utils/hash.js';
3
2
  import { resolve_entry } from '../../utils/filesystem.js';
4
3
  import { posixify } from '../../utils/os.js';
5
4
  import { s } from '../../utils/misc.js';
6
5
  import { load_error_page, load_template } from '../config/index.js';
7
6
  import { check_spelling, write_if_changed } from './utils.js';
8
7
  import { escape_html } from '../../utils/escape.js';
8
+ import { runtime_directory } from '../utils.js';
9
9
 
10
10
  /**
11
11
  * @param {{
12
12
  * server_hooks: string | null;
13
13
  * universal_hooks: string | null;
14
14
  * config: import('types').ValidatedConfig;
15
- * has_service_worker: boolean;
16
15
  * template: string;
16
+ * runtime_directory: string;
17
17
  * }} opts
18
18
  */
19
19
  const server_template = ({
20
20
  config,
21
21
  server_hooks,
22
22
  universal_hooks,
23
- has_service_worker,
24
- template
23
+ template,
24
+ runtime_directory
25
25
  }) => `
26
- import { set_building, set_prerendering } from '$app/env/internal';
26
+ import { set_building, set_prerendering } from '$app/env/server';
27
27
  import { set_assets } from '$app/paths/internal/server';
28
- import { set_fix_stack_trace, set_manifest, set_read_implementation, log_response } from '__sveltekit/server';
29
- import error from '../shared/error-template.js';
28
+ import { set_fix_stack_trace, set_manifest, set_read_implementation, format_response } from '${runtime_directory}/server/internal.js';
29
+ import error from './shared/error-template.js';
30
30
 
31
31
  export const options = {
32
32
  app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')},
33
33
  csp: ${s(config.csp)},
34
- csrf_check_origin: ${s(!config.csrf.trustedOrigins.includes('*'))},
35
34
  csrf_trusted_origins: ${s(config.csrf.trustedOrigins)},
36
- embedded: ${config.embedded},
37
- hash_routing: ${s(config.router.type === 'hash')},
38
- hooks: null, // added lazily, via \`get_hooks\`
39
- link_header_preload: ${s(config.output.linkHeaderPreload)},
40
- paths_origin: ${s(config.paths.origin)},
41
- service_worker: ${has_service_worker},
42
35
  service_worker_options: ${config.serviceWorker.register ? s(config.serviceWorker.options) : 'null'},
43
36
  templates: {
44
37
  app: ({ head, body, assets, nonce, env }) => ${s(template)
@@ -52,9 +45,7 @@ export const options = {
52
45
  (_match, capture) => `" + (env[${s(capture)}] ?? "") + "`
53
46
  )},
54
47
  error
55
- },
56
- version: ${s(config.version.name)},
57
- version_hash: ${s(hash(config.version.name))}
48
+ }
58
49
  };
59
50
 
60
51
  export async function get_hooks() {
@@ -78,7 +69,7 @@ export async function get_hooks() {
78
69
  };
79
70
  }
80
71
 
81
- export { set_assets, set_building, set_fix_stack_trace, set_manifest, set_prerendering, set_read_implementation, log_response };
72
+ export { set_assets, set_building, set_fix_stack_trace, set_manifest, set_prerendering, set_read_implementation, format_response };
82
73
  `;
83
74
 
84
75
  /**
@@ -103,7 +94,7 @@ export function write_server(config, output, root) {
103
94
 
104
95
  /** @param {string} file */
105
96
  function relative(file) {
106
- return posixify(path.relative(`${output}/server`, file));
97
+ return posixify(path.relative(output, file));
107
98
  }
108
99
 
109
100
  write_if_changed(
@@ -116,13 +107,12 @@ export function write_server(config, output, root) {
116
107
  // Contains the stringified version of
117
108
  /** @type {import('types').SSROptions} */
118
109
  write_if_changed(
119
- `${output}/server/internal.js`,
110
+ `${output}/server.js`,
120
111
  server_template({
121
112
  config,
113
+ runtime_directory: relative(runtime_directory),
122
114
  server_hooks: server_hooks_file ? relative(server_hooks_file) : null,
123
115
  universal_hooks: universal_hooks_file ? relative(universal_hooks_file) : null,
124
- has_service_worker:
125
- config.serviceWorker.register && !!resolve_entry(config.files.serviceWorker),
126
116
  template: load_template(root, config)
127
117
  })
128
118
  );
@@ -42,12 +42,12 @@ export function write_all_types(config, manifest_data, root) {
42
42
  posixify(path.relative(root, config.files.routes))
43
43
  );
44
44
  const expected_directories = new Set(
45
- manifest_data.routes.map((route) => path.join(routes_dir, route.id))
45
+ manifest_data.routes.map((route) => path.posix.join(routes_dir, route.id))
46
46
  );
47
47
 
48
48
  if (fs.existsSync(types_dir)) {
49
49
  for (const file of walk(types_dir)) {
50
- const dir = path.dirname(file);
50
+ const dir = path.posix.dirname(file);
51
51
  if (!expected_directories.has(dir)) {
52
52
  fs.rmSync(path.join(types_dir, file), { force: true, recursive: true });
53
53
  }
package/src/core/utils.js CHANGED
@@ -1,10 +1,10 @@
1
- import fs from 'node:fs';
2
1
  import path from 'node:path';
3
2
  import { fileURLToPath } from 'node:url';
4
3
  import { styleText } from 'node:util';
5
4
  import { to_fs } from '../utils/vite.js';
6
5
  import { noop } from '../utils/functions.js';
7
6
  import { posixify } from '../utils/os.js';
7
+ import { hash } from '../utils/hash.js';
8
8
 
9
9
  /**
10
10
  * Resolved path of the `runtime` directory posix-ified
@@ -16,6 +16,15 @@ import { posixify } from '../utils/os.js';
16
16
  */
17
17
  export const runtime_directory = posixify(fileURLToPath(new URL('../runtime', import.meta.url)));
18
18
 
19
+ /**
20
+ * The name of the `globalThis.__sveltekit_xxx` object the app's payload is attached to
21
+ * @param {string} version_name
22
+ * @param {boolean} dev
23
+ */
24
+ export function get_global_name(version_name, dev) {
25
+ return dev ? '__sveltekit_dev' : `__sveltekit_${hash(version_name)}`;
26
+ }
27
+
19
28
  /**
20
29
  * This allows us to import SvelteKit internals that aren't exposed via `pkg.exports` in a
21
30
  * way that works whether `@sveltejs/kit` is installed inside the project's `node_modules`
@@ -85,30 +94,3 @@ export function get_mime_lookup(manifest_data) {
85
94
 
86
95
  return mime;
87
96
  }
88
-
89
- /**
90
- * @param {string} dir
91
- * @param {(file: string) => boolean} [filter]
92
- */
93
- export function list_files(dir, filter) {
94
- /** @type {string[]} */
95
- const files = [];
96
-
97
- /** @param {string} current */
98
- function walk(current) {
99
- for (const file of fs.readdirSync(path.resolve(dir, current))) {
100
- const child = path.posix.join(current, file);
101
- if (fs.statSync(path.resolve(dir, child)).isDirectory()) {
102
- walk(child);
103
- } else {
104
- if (!filter || filter(child)) {
105
- files.push(child);
106
- }
107
- }
108
- }
109
- }
110
-
111
- if (fs.existsSync(dir)) walk('');
112
-
113
- return files;
114
- }
@@ -0,0 +1,22 @@
1
+ import { REROUTED_URL_HEADER } from '../constants.js';
2
+
3
+ /**
4
+ * Helps a catch-all request handler pass the request to a different handler if
5
+ * the `reroute` hook has returned a URL pathname that's different from the
6
+ * incoming request.
7
+ *
8
+ * If your adapter is capable of deploying multiple serverless functions, it's a
9
+ * good idea to also deploy a "catch-all" one to handle uncaught requests.
10
+ * Running this in that function allows the app's `reroute` hook to rewrite
11
+ * the request URL and invoke the next appropriate serverless function, if any.
12
+ * @param {Response} response The response returned from the SvelteKit `server.respond` function
13
+ * @param {(url: URL) => Response | Promise<Response>} next Your platform-specific implementation for invoking the next handler with a different request URL
14
+ * @returns {Response | Promise<Response>}
15
+ * @since 3.0.0
16
+ */
17
+ export function applyReroute(response, next) {
18
+ const rerouted_url = response.headers.get(REROUTED_URL_HEADER);
19
+ if (!rerouted_url) return response;
20
+
21
+ return next(new URL(rerouted_url));
22
+ }
@@ -170,9 +170,17 @@ export interface ResolveOptions {
170
170
  * `<head>` tag; if `output.linkHeaderPreload` is enabled, dynamically rendered pages use the
171
171
  * [`Link` response header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link) instead.
172
172
  * By default, `js` and `css` files will be preloaded.
173
+ *
174
+ * For `font` files, `input` also has a `filename` property, the source file's pathname relative
175
+ * to the project root, so that a filter can match on it instead of the hashed path. `js` and
176
+ * `css` files are bundled and have no single source file name.
173
177
  * @param input the type of the file and its path
174
178
  */
175
- preload?: (input: { type: 'font' | 'css' | 'js' | 'asset'; path: string }) => boolean;
179
+ preload?: (
180
+ input:
181
+ | { type: 'css' | 'js' | 'asset'; path: string }
182
+ | { type: 'font'; path: string; filename: string }
183
+ ) => boolean;
176
184
  }
177
185
 
178
186
  type AppErrorWithOptionalDefaults = Omit<App.Error, 'status' | 'message'> & {