@sveltejs/kit 3.0.0-next.2 → 3.0.0-next.20

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 (192) hide show
  1. package/package.json +58 -36
  2. package/src/cli.js +14 -11
  3. package/src/constants.js +6 -1
  4. package/src/core/adapt/builder.js +54 -60
  5. package/src/core/adapt/index.js +2 -5
  6. package/src/core/config/index.js +141 -76
  7. package/src/core/config/options.js +260 -260
  8. package/src/core/config/types.d.ts +1 -1
  9. package/src/core/env.js +143 -13
  10. package/src/core/generate_manifest/index.js +18 -15
  11. package/src/core/postbuild/analyse.js +7 -19
  12. package/src/core/postbuild/crawl.js +22 -6
  13. package/src/core/postbuild/entities.js +8 -2
  14. package/src/core/postbuild/fallback.js +4 -2
  15. package/src/core/postbuild/prerender.js +193 -69
  16. package/src/core/postbuild/queue.js +2 -1
  17. package/src/core/sync/create_manifest_data/conflict.js +1 -1
  18. package/src/core/sync/create_manifest_data/index.js +72 -52
  19. package/src/core/sync/sync.js +35 -26
  20. package/src/core/sync/ts.js +1 -1
  21. package/src/core/sync/utils.js +22 -2
  22. package/src/core/sync/{write_non_ambient.js → write_app_types.js} +105 -56
  23. package/src/core/sync/write_client_manifest.js +13 -28
  24. package/src/core/sync/write_env.js +7 -5
  25. package/src/core/sync/write_server.js +25 -33
  26. package/src/core/sync/write_tsconfig/index.js +274 -0
  27. package/src/core/sync/write_tsconfig/test-app/package.json +7 -0
  28. package/src/core/sync/write_tsconfig/utils.js +77 -0
  29. package/src/core/sync/write_tsconfig/validate.js +128 -0
  30. package/src/core/sync/write_types/index.js +119 -116
  31. package/src/core/utils.js +30 -5
  32. package/src/exports/env/index.js +77 -0
  33. package/src/exports/env/public.d.ts +55 -0
  34. package/src/exports/hooks/index.js +3 -9
  35. package/src/exports/hooks/public.d.ts +194 -0
  36. package/src/exports/hooks/sequence.js +9 -6
  37. package/src/exports/index.js +53 -20
  38. package/src/exports/internal/client.js +5 -0
  39. package/src/exports/internal/env.js +8 -5
  40. package/src/exports/internal/index.js +1 -90
  41. package/src/exports/internal/{event.js → server/event.js} +1 -2
  42. package/src/exports/internal/server/index.js +37 -0
  43. package/src/exports/internal/server/telemetry.js +95 -0
  44. package/src/exports/internal/shared.js +90 -0
  45. package/src/exports/node/index.js +64 -22
  46. package/src/exports/params/index.js +70 -0
  47. package/src/exports/params/public.d.ts +63 -0
  48. package/src/exports/public.d.ts +219 -1118
  49. package/src/exports/url.js +86 -0
  50. package/src/exports/vite/build/build_server.js +53 -64
  51. package/src/exports/vite/build/remote.js +24 -19
  52. package/src/exports/vite/build/utils.js +0 -8
  53. package/src/exports/vite/dev/index.js +199 -125
  54. package/src/exports/vite/index.js +1514 -833
  55. package/src/exports/vite/module_ids.js +2 -2
  56. package/src/exports/vite/preview/index.js +32 -24
  57. package/src/exports/vite/utils.js +83 -45
  58. package/src/pathname.js +55 -0
  59. package/src/runner.js +15 -0
  60. package/src/runtime/app/env/internal.js +4 -4
  61. package/src/runtime/app/env/types.d.ts +1 -1
  62. package/src/runtime/app/environment/index.js +3 -3
  63. package/src/runtime/app/{forms.js → forms/index.js} +73 -42
  64. package/src/runtime/app/forms/public.d.ts +2 -0
  65. package/src/runtime/app/forms/types.d.ts +56 -0
  66. package/src/runtime/app/internal/transport.js +53 -0
  67. package/src/runtime/app/manifest/index.js +1 -0
  68. package/src/runtime/app/{navigation.js → navigation/index.js} +2 -1
  69. package/src/runtime/app/navigation/public.d.ts +237 -0
  70. package/src/runtime/app/paths/client.js +37 -37
  71. package/src/runtime/app/paths/index.js +1 -1
  72. package/src/runtime/app/paths/internal/client.js +34 -2
  73. package/src/runtime/app/paths/internal/server.js +6 -23
  74. package/src/runtime/app/paths/internal.d.ts +3 -0
  75. package/src/runtime/app/paths/public.d.ts +1 -29
  76. package/src/runtime/app/paths/server.js +36 -17
  77. package/src/runtime/app/paths/types.d.ts +11 -19
  78. package/src/runtime/app/server/index.js +2 -2
  79. package/src/runtime/app/server/public.d.ts +519 -0
  80. package/src/runtime/app/server/remote/command.js +13 -11
  81. package/src/runtime/app/server/remote/form.js +61 -39
  82. package/src/runtime/app/server/remote/prerender.js +45 -45
  83. package/src/runtime/app/server/remote/query.js +106 -108
  84. package/src/runtime/app/server/remote/requested.js +27 -19
  85. package/src/runtime/app/server/remote/shared.js +75 -75
  86. package/src/runtime/app/service-worker/index.js +24 -0
  87. package/src/runtime/app/state/client.js +4 -2
  88. package/src/runtime/app/state/index.js +7 -5
  89. package/src/runtime/app/state/public.d.ts +72 -0
  90. package/src/runtime/app/state/server.js +3 -0
  91. package/src/runtime/app/stores.js +15 -78
  92. package/src/runtime/client/bundle.js +1 -1
  93. package/src/runtime/client/client-entry.js +3 -0
  94. package/src/runtime/client/client.js +1336 -648
  95. package/src/runtime/client/constants.js +3 -6
  96. package/src/runtime/client/entry.js +24 -3
  97. package/src/runtime/client/fetcher.js +25 -25
  98. package/src/runtime/client/ndjson.js +1 -1
  99. package/src/runtime/client/parse.js +1 -1
  100. package/src/runtime/client/payload.js +17 -0
  101. package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
  102. package/src/runtime/client/remote-functions/command.svelte.js +37 -61
  103. package/src/runtime/client/remote-functions/form.svelte.js +267 -178
  104. package/src/runtime/client/remote-functions/prerender.svelte.js +32 -11
  105. package/src/runtime/client/remote-functions/query/index.js +10 -17
  106. package/src/runtime/client/remote-functions/query/instance.svelte.js +64 -18
  107. package/src/runtime/client/remote-functions/query/proxy.js +5 -5
  108. package/src/runtime/client/remote-functions/query-batch.svelte.js +61 -70
  109. package/src/runtime/client/remote-functions/query-live/index.js +1 -1
  110. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +63 -21
  111. package/src/runtime/client/remote-functions/query-live/iterator.js +15 -12
  112. package/src/runtime/client/remote-functions/query-live/proxy.js +2 -12
  113. package/src/runtime/client/remote-functions/shared.svelte.js +90 -65
  114. package/src/runtime/client/snapshots.js +147 -0
  115. package/src/runtime/client/state.svelte.js +94 -55
  116. package/src/runtime/client/stream.js +3 -2
  117. package/src/runtime/client/types.d.ts +13 -9
  118. package/src/runtime/client/utils.js +22 -110
  119. package/src/runtime/components/root.svelte +56 -0
  120. package/src/runtime/env/dynamic/private.js +7 -0
  121. package/src/runtime/env/dynamic/public.js +7 -0
  122. package/src/runtime/env/static/private.js +6 -0
  123. package/src/runtime/env/static/public.js +6 -0
  124. package/src/runtime/form-utils.js +172 -61
  125. package/src/runtime/pathname.js +20 -32
  126. package/src/runtime/props.svelte.js +72 -0
  127. package/src/runtime/server/constants.js +0 -3
  128. package/src/runtime/server/cookie.js +70 -53
  129. package/src/runtime/server/csrf.js +65 -0
  130. package/src/runtime/server/data/index.js +48 -52
  131. package/src/runtime/server/dev.js +22 -0
  132. package/src/runtime/server/endpoint.js +3 -4
  133. package/src/runtime/server/env_module.js +0 -5
  134. package/src/runtime/server/errors.js +160 -0
  135. package/src/runtime/server/fetch.js +31 -38
  136. package/src/runtime/server/index.js +90 -64
  137. package/src/runtime/server/internal.js +71 -0
  138. package/src/runtime/server/page/actions.js +84 -64
  139. package/src/runtime/server/page/crypto.js +2 -2
  140. package/src/runtime/server/page/csp.js +88 -104
  141. package/src/runtime/server/page/data_serializer.js +22 -23
  142. package/src/runtime/server/page/index.js +35 -53
  143. package/src/runtime/server/page/load_data.js +47 -54
  144. package/src/runtime/server/page/render.js +172 -238
  145. package/src/runtime/server/page/respond_with_error.js +16 -30
  146. package/src/runtime/server/page/serialize_data.js +2 -13
  147. package/src/runtime/server/page/server_routing.js +85 -26
  148. package/src/runtime/server/remote-functions.js +639 -0
  149. package/src/runtime/server/respond.js +188 -129
  150. package/src/runtime/server/sourcemaps.js +183 -0
  151. package/src/runtime/server/state.js +53 -0
  152. package/src/runtime/server/utils.js +12 -154
  153. package/src/runtime/shared.js +20 -40
  154. package/src/runtime/utils.js +3 -0
  155. package/src/types/ambient-private.d.ts +11 -1
  156. package/src/types/ambient.d.ts +87 -36
  157. package/src/types/global-private.d.ts +25 -25
  158. package/src/types/internal.d.ts +160 -150
  159. package/src/types/private.d.ts +41 -1
  160. package/src/utils/error.js +28 -4
  161. package/src/utils/escape.js +9 -25
  162. package/src/utils/features.js +1 -1
  163. package/src/utils/filesystem.js +1 -23
  164. package/src/utils/fork.js +7 -2
  165. package/src/utils/hash.js +21 -0
  166. package/src/utils/http.js +8 -7
  167. package/src/utils/import.js +9 -2
  168. package/src/utils/imports.js +83 -0
  169. package/src/utils/mime.js +9 -0
  170. package/src/utils/page_nodes.js +6 -7
  171. package/src/utils/params.js +67 -0
  172. package/src/utils/regex.js +9 -0
  173. package/src/utils/routing.js +145 -73
  174. package/src/utils/shared-iterator.js +5 -0
  175. package/src/utils/streaming.js +14 -4
  176. package/src/utils/url.js +33 -2
  177. package/src/version.js +1 -1
  178. package/types/index.d.ts +2291 -2135
  179. package/types/index.d.ts.map +116 -108
  180. package/src/core/sync/write_ambient.js +0 -18
  181. package/src/core/sync/write_root.js +0 -148
  182. package/src/core/sync/write_tsconfig.js +0 -250
  183. package/src/exports/internal/server.js +0 -22
  184. package/src/exports/node/polyfills.js +0 -30
  185. package/src/runtime/server/app.js +0 -9
  186. package/src/runtime/server/remote.js +0 -457
  187. package/src/runtime/shared-server.js +0 -7
  188. package/src/runtime/telemetry/otel.js +0 -21
  189. package/src/runtime/telemetry/record_span.js +0 -65
  190. package/src/types/synthetic/$lib.md +0 -5
  191. /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
  192. /package/src/{runtime/telemetry/noop.js → telemetry.js} +0 -0
@@ -1,12 +1,9 @@
1
1
  import path from 'node:path';
2
- import process from 'node:process';
3
2
  import create_manifest_data from './create_manifest_data/index.js';
4
3
  import { write_client_manifest } from './write_client_manifest.js';
5
- import { write_root } from './write_root.js';
6
- import { write_tsconfig } from './write_tsconfig.js';
4
+ import { write_tsconfig } from './write_tsconfig/index.js';
7
5
  import { write_types, write_all_types } from './write_types/index.js';
8
- import { write_ambient } from './write_ambient.js';
9
- import { write_non_ambient } from './write_non_ambient.js';
6
+ import { write_app_types } from './write_app_types.js';
10
7
  import { write_server } from './write_server.js';
11
8
  import {
12
9
  create_node_analyser,
@@ -22,7 +19,6 @@ import { write_env } from './write_env.js';
22
19
  */
23
20
  export function init(config, root) {
24
21
  write_tsconfig(config.kit, root);
25
- write_ambient(config.kit);
26
22
  }
27
23
 
28
24
  /**
@@ -37,9 +33,8 @@ export function create(config, root) {
37
33
 
38
34
  write_client_manifest(config.kit, manifest_data, `${output}/client`);
39
35
  write_server(config, output, root);
40
- write_root(manifest_data, config, output);
41
36
  write_all_types(config, manifest_data, root);
42
- write_non_ambient(config.kit, manifest_data);
37
+ write_app_types(config.kit, manifest_data, root);
43
38
 
44
39
  return { manifest_data };
45
40
  }
@@ -52,22 +47,35 @@ export function create(config, root) {
52
47
  * @param {import('types').ManifestData} manifest_data
53
48
  * @param {string} file
54
49
  * @param {string} root The project root directory
50
+ * @returns {boolean} Whether the update completed, or a full manifest rebuild is needed
55
51
  */
56
52
  export function update(config, manifest_data, file, root) {
57
- const node_analyser = create_node_analyser(root);
53
+ try {
54
+ const node_analyser = create_node_analyser(root);
58
55
 
59
- for (const node of manifest_data.nodes) {
60
- node.page_options = node_analyser.get_page_options(node);
61
- }
56
+ for (const node of manifest_data.nodes) {
57
+ node.page_options = node_analyser.get_page_options(node);
58
+ }
59
+
60
+ for (const route of manifest_data.routes) {
61
+ if (route.endpoint) {
62
+ route.endpoint.page_options = get_page_options(route.endpoint.file, root);
63
+ }
64
+ }
62
65
 
63
- for (const route of manifest_data.routes) {
64
- if (route.endpoint) {
65
- route.endpoint.page_options = get_page_options(route.endpoint.file, root);
66
+ write_types(config, manifest_data, file, root);
67
+ write_app_types(config.kit, manifest_data, root);
68
+ } catch (error) {
69
+ // A route file can disappear before the watcher delivers its unlink event. In that case,
70
+ // the manifest is stale and must be rebuilt instead of incrementally updated.
71
+ if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {
72
+ return false;
66
73
  }
74
+
75
+ throw error;
67
76
  }
68
77
 
69
- write_types(config, manifest_data, file, root);
70
- write_non_ambient(config.kit, manifest_data);
78
+ return true;
71
79
  }
72
80
 
73
81
  /**
@@ -83,26 +91,27 @@ export function all(config, root) {
83
91
  /**
84
92
  * Run sync.init and then generate all type files.
85
93
  * @param {import('types').ValidatedConfig} config
94
+ * @param {string} root
86
95
  */
87
- export function all_types(config) {
88
- const cwd = process.cwd();
89
- init(config, cwd);
90
- const manifest_data = create_manifest_data({ config, cwd });
91
- write_all_types(config, manifest_data, cwd);
92
- write_non_ambient(config.kit, manifest_data);
96
+ export function all_types(config, root) {
97
+ init(config, root);
98
+ const manifest_data = create_manifest_data({ config, cwd: root });
99
+ write_all_types(config, manifest_data, root);
100
+ write_app_types(config.kit, manifest_data, root);
93
101
  }
94
102
 
95
103
  /**
96
104
  * Generate modules and types for explicit env vars
105
+ * @param {typeof import('vite')} vite
97
106
  * @param {import('types').ValidatedKitConfig} kit
98
107
  * @param {string | null} entry
99
108
  * @param {string} root The Vite root
100
109
  * @param {string} mode The Vite mode
101
110
  */
102
- export async function env(kit, entry, root, mode) {
103
- const env_config = await load_explicit_env(kit, entry, root, mode);
111
+ export async function env(vite, kit, entry, root, mode) {
112
+ const env_config = await load_explicit_env(vite, kit, entry, root, mode);
104
113
 
105
- write_env(kit, entry, env_config);
114
+ write_env(entry, env_config, root);
106
115
 
107
116
  return env_config;
108
117
  }
@@ -1,4 +1,4 @@
1
- /** @type {import('typescript')} */
1
+ /** @type {typeof import('typescript')} */
2
2
  // @ts-ignore
3
3
  export let ts = undefined;
4
4
  try {
@@ -1,6 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { mkdirp } from '../../utils/filesystem.js';
3
+ import { styleText } from 'node:util';
4
+ import { resolve_entry } from '../../utils/filesystem.js';
4
5
 
5
6
  /** @type {Map<string, string>} */
6
7
  const previous_contents = new Map();
@@ -21,7 +22,7 @@ export function write_if_changed(file, code) {
21
22
  */
22
23
  export function write(file, code) {
23
24
  previous_contents.set(file, code);
24
- mkdirp(path.dirname(file));
25
+ fs.mkdirSync(path.dirname(file), { recursive: true });
25
26
  fs.writeFileSync(file, code);
26
27
  }
27
28
 
@@ -68,3 +69,22 @@ export function dedent(strings, ...values) {
68
69
 
69
70
  return str;
70
71
  }
72
+
73
+ /**
74
+ * @param {string} original
75
+ * @param {string} typo The common misspelling to check for
76
+ * @param {string} description What was wrong with the filename
77
+ */
78
+ export function check_spelling(original, typo, description) {
79
+ const misspelled = resolve_entry(typo);
80
+ if (!misspelled) return;
81
+
82
+ const corrected = path.basename(misspelled).replace(path.basename(typo), path.basename(original));
83
+
84
+ console.warn(
85
+ styleText(
86
+ ['bold', 'yellow'],
87
+ `${description}. Did you mean ${corrected}?` + ` at ${path.resolve(misspelled)}`
88
+ )
89
+ );
90
+ }
@@ -1,17 +1,45 @@
1
1
  import path from 'node:path';
2
2
  import { GENERATED_COMMENT } from '../../constants.js';
3
+ import { resolve_entry } from '../../utils/filesystem.js';
3
4
  import { posixify } from '../../utils/os.js';
4
5
  import { write_if_changed } from './utils.js';
5
6
  import { s } from '../../utils/misc.js';
6
- import { get_route_segments } from '../../utils/routing.js';
7
-
8
- const replace_optional_params = (/** @type {string} */ id) =>
9
- id.replace(/\/\[\[[^\]]+\]\]/g, '${string}');
10
- const replace_required_params = (/** @type {string} */ id) =>
11
- id.replace(/\/\[[^\]]+\]/g, '/${string}');
12
- /** Convert route ID to pathname by removing layout groups */
13
- const remove_group_segments = (/** @type {string} */ id) => {
14
- return '/' + get_route_segments(id).join('/');
7
+ import {
8
+ decode_escape_sequence,
9
+ encode_pathname_chars,
10
+ get_route_segments,
11
+ segment_pattern
12
+ } from '../../utils/routing.js';
13
+ import { is_app_route, is_endpoint_route, is_page_route } from './create_manifest_data/index.js';
14
+
15
+ const optional_param_pattern = /^\[\[[\w-]+(?:=[\w-]+)?\]\]$/;
16
+ const rest_param_pattern = /^\[\.\.\.[\w-]+(?:=[\w-]+)?\]$/;
17
+
18
+ /**
19
+ * Convert a route ID to the pathnames it can match (relative to the base path), in which each
20
+ * param is replaced with `${string}` and each escape sequence is expanded. A param that fills an
21
+ * entire segment can be absent, so it contributes a pathname with the segment and one without,
22
+ * rather than one that absorbs the `/`
23
+ * @param {string} id
24
+ */
25
+ const get_pathname_patterns = (id) => {
26
+ let pathnames = [''];
27
+
28
+ for (const segment of get_route_segments(id)) {
29
+ const omittable = optional_param_pattern.test(segment) || rest_param_pattern.test(segment);
30
+ const content = omittable
31
+ ? '${string}'
32
+ : segment.replace(segment_pattern, (_, escape_type, escape_code) =>
33
+ escape_type ? encode_pathname_chars(decode_escape_sequence(escape_code)) : '${string}'
34
+ );
35
+
36
+ pathnames = pathnames.flatMap((pathname) => {
37
+ const joined = pathname === '' ? content : `${pathname}/${content}`;
38
+ return omittable ? [joined, pathname] : [joined];
39
+ });
40
+ }
41
+
42
+ return [...new Set(pathnames)];
15
43
  };
16
44
 
17
45
  /**
@@ -21,10 +49,6 @@ const remove_group_segments = (/** @type {string} */ id) => {
21
49
  * @returns {string[]}
22
50
  */
23
51
  function get_pathnames_for_trailing_slash(pathname, route) {
24
- if (pathname === '/') {
25
- return [pathname];
26
- }
27
-
28
52
  /** @type {Set<string>} */
29
53
  const pathnames = new Set();
30
54
 
@@ -54,12 +78,8 @@ function get_pathnames_for_trailing_slash(pathname, route) {
54
78
  // people could use to type their own components.
55
79
  // The T generic is needed or else there's a "all declarations must have identical type parameters" error.
56
80
  const template = `
57
- ${GENERATED_COMMENT}
58
-
59
81
  declare module "svelte/elements" {
60
82
  export interface HTMLAttributes<T> {
61
- 'data-sveltekit-keepfocus'?: true | false | '' | undefined | null;
62
- 'data-sveltekit-noscroll'?: true | false | '' | undefined | null;
63
83
  'data-sveltekit-preload-code'?:
64
84
  | true
65
85
  | false
@@ -73,22 +93,18 @@ declare module "svelte/elements" {
73
93
  'data-sveltekit-preload-data'?: true | false | '' | 'hover' | 'tap' | undefined | null;
74
94
  'data-sveltekit-reload'?: true | false | '' | undefined | null;
75
95
  'data-sveltekit-replacestate'?: true | false | '' | undefined | null;
96
+ 'data-sveltekit-reset'?: true | false | '' | undefined | null;
76
97
  }
77
98
  }
78
-
79
- export {};
80
99
  `;
81
100
 
82
101
  /**
83
102
  * Generate app types interface extension
84
103
  * @param {import('types').ManifestData} manifest_data
85
104
  * @param {import('types').ValidatedKitConfig} config
105
+ * @param {string} dir
86
106
  */
87
- function generate_app_types(manifest_data, config) {
88
- /** @param {string} matcher */
89
- const path_to_matcher = (matcher) =>
90
- posixify(path.relative(config.outDir, path.join(config.files.params, matcher + '.js')));
91
-
107
+ function generate_app_types(manifest_data, config, dir) {
92
108
  /** @type {Map<string, string>} */
93
109
  const matcher_types = new Map();
94
110
 
@@ -98,7 +114,15 @@ function generate_app_types(manifest_data, config) {
98
114
 
99
115
  let type = matcher_types.get(matcher);
100
116
  if (!type) {
101
- type = `MatcherParam<typeof import('${path_to_matcher(matcher)}').match>`;
117
+ const path_to_params = () => {
118
+ const params_file =
119
+ resolve_entry(config.files.params) ??
120
+ config.files.params.replace(/\.(js|ts)$/, '') + '.js';
121
+
122
+ return posixify(path.relative(dir, params_file));
123
+ };
124
+
125
+ type = `import('@sveltejs/kit/params').MatcherParam<(typeof import('${path_to_params()}').params)[${JSON.stringify(matcher)}]>`;
102
126
  matcher_types.set(matcher, type);
103
127
  }
104
128
 
@@ -145,6 +169,15 @@ function generate_app_types(manifest_data, config) {
145
169
  /** @type {Set<string>} */
146
170
  const pathnames = new Set();
147
171
 
172
+ /** @type {string[]} */
173
+ const page_route_ids = [];
174
+
175
+ /** @type {string[]} */
176
+ const endpoint_route_ids = [];
177
+
178
+ /** @type {string[]} */
179
+ const app_route_ids = [];
180
+
148
181
  /** @type {string[]} */
149
182
  const dynamic_routes = [];
150
183
 
@@ -153,15 +186,17 @@ function generate_app_types(manifest_data, config) {
153
186
 
154
187
  /** @type {Map<string, Map<string, { optional: boolean, matchers: Set<string> | null }>>} */
155
188
  const layout_params_by_route = new Map(
156
- manifest_data.routes.map((route) => [
157
- route.id,
158
- new Map(
159
- route.params.map((p) => [
160
- p.name,
161
- { optional: p.optional, matchers: p.matcher ? new Set([p.matcher]) : null }
162
- ])
163
- )
164
- ])
189
+ manifest_data.routes
190
+ .filter((route) => route.layout)
191
+ .map((route) => [
192
+ route.id,
193
+ new Map(
194
+ route.params.map((p) => [
195
+ p.name,
196
+ { optional: p.optional, matchers: p.matcher ? new Set([p.matcher]) : null }
197
+ ])
198
+ )
199
+ ])
165
200
  );
166
201
 
167
202
  for (const route of manifest_data.routes) {
@@ -195,8 +230,11 @@ function generate_app_types(manifest_data, config) {
195
230
  }
196
231
 
197
232
  for (const route of manifest_data.routes) {
198
- const pathname = remove_group_segments(route.id);
199
- let normalized_pathname = pathname;
233
+ const id = s(route.id);
234
+
235
+ if (is_page_route(route)) page_route_ids.push(id);
236
+ if (is_endpoint_route(route)) endpoint_route_ids.push(id);
237
+ if (is_app_route(route)) app_route_ids.push(id);
200
238
 
201
239
  /** @type {(path: string) => string} */
202
240
  let serialise = s;
@@ -204,18 +242,20 @@ function generate_app_types(manifest_data, config) {
204
242
  if (route.params.length > 0) {
205
243
  const params = route.params.map((p) => {
206
244
  const type = get_matcher_type(p.matcher);
207
- return `${p.name}${p.optional ? '?:' : ':'} ${type}${p.optional ? ' | undefined' : ''}`;
245
+ return `${/^\w+$/.test(p.name) ? p.name : `'${p.name}'`}${p.optional ? '?:' : ':'} ${type}${p.optional ? ' | undefined' : ''}`;
208
246
  });
209
- const route_type = `${s(route.id)}: { ${params.join('; ')} }`;
210
247
 
211
- dynamic_routes.push(route_type);
248
+ if (is_app_route(route)) {
249
+ dynamic_routes.push(`${s(route.id)}: { ${params.join('; ')} }`);
250
+ }
212
251
 
213
- normalized_pathname = replace_required_params(replace_optional_params(pathname));
214
252
  serialise = (p) => `\`${p}\` & {}`;
215
253
  }
216
254
 
217
- for (const p of get_pathnames_for_trailing_slash(normalized_pathname, route)) {
218
- pathnames.add(serialise(p));
255
+ for (const pathname of get_pathname_patterns(route.id)) {
256
+ for (const p of get_pathnames_for_trailing_slash(pathname, route)) {
257
+ pathnames.add(serialise(p));
258
+ }
219
259
  }
220
260
 
221
261
  let layout_type = 'Record<string, never>';
@@ -225,42 +265,51 @@ function generate_app_types(manifest_data, config) {
225
265
  const params = Array.from(layout_params)
226
266
  .map(([name, { optional, matchers }]) => {
227
267
  const type = get_matchers_type(matchers);
228
- return `${name}${optional ? '?:' : ':'} ${type}${optional ? ' | undefined' : ''}`;
268
+ return `${/^\w+$/.test(name) ? name : `'${name}'`}${optional ? '?:' : ':'} ${type}${optional ? ' | undefined' : ''}`;
229
269
  })
230
270
  .join('; ');
231
271
 
232
272
  if (params.length > 0) layout_type = `{ ${params} }`;
233
273
  }
234
274
 
235
- layouts.push(`${s(route.id)}: ${layout_type}`);
275
+ if (route.layout) layouts.push(`${s(route.id)}: ${layout_type}`);
236
276
  }
237
277
 
238
- const assets = manifest_data.assets.map((asset) => s('/' + asset.file));
278
+ const assets = manifest_data.assets.map((asset) => s(asset.file));
239
279
 
240
280
  return [
241
281
  'declare module "$app/types" {',
242
- '\ttype MatcherParam<M> = M extends (param : string) => param is (infer U extends string) ? U : string;',
243
- '',
244
282
  '\texport interface AppTypes {',
245
- `\t\tRouteId(): ${manifest_data.routes.map((r) => s(r.id)).join(' | ')};`,
283
+ `\t\tPageRouteId(): ${page_route_ids.join(' | ') || 'never'};`,
284
+ `\t\tEndpointRouteId(): ${endpoint_route_ids.join(' | ') || 'never'};`,
285
+ `\t\tRouteId(): ${app_route_ids.join(' | ') || 'never'};`,
246
286
  `\t\tRouteParams(): {\n\t\t\t${dynamic_routes.join(';\n\t\t\t')}\n\t\t};`,
247
287
  `\t\tLayoutParams(): {\n\t\t\t${layouts.join(';\n\t\t\t')}\n\t\t};`,
248
- `\t\tPathname(): ${Array.from(pathnames).join(' | ')};`,
249
- '\t\tResolvedPathname(): `${"" | `/${string}`}${ReturnType<AppTypes[\'Pathname\']>}`;',
250
- `\t\tAsset(): ${assets.concat('string & {}').join(' | ')};`,
288
+ `\t\tPath(): ${Array.from(pathnames).join(' | ')};`,
289
+ '\t\tResolvedPathname(): `${"/" | `/${string}/`}${ReturnType<AppTypes[\'Path\']>}`;',
290
+ `\t\tAssetPath(): ${assets.join(' | ') || 'never'};`,
251
291
  '\t}',
252
292
  '}'
253
293
  ].join('\n');
254
294
  }
255
295
 
256
296
  /**
257
- * Writes non-ambient declarations to the output directory
297
+ * Writes `node_modules/$app/types/index.d.ts`. This file contains
298
+ * declarations for `$app/types` and `svelte/elements`, and
299
+ * imports `env.ts` which declares `$app/env/(public|private)`
258
300
  * @param {import('types').ValidatedKitConfig} config
259
301
  * @param {import('types').ManifestData} manifest_data
302
+ * @param {string} root
260
303
  */
261
- export function write_non_ambient(config, manifest_data) {
262
- const app_types = generate_app_types(manifest_data, config);
263
- const content = [template, app_types].join('\n\n');
304
+ export function write_app_types(config, manifest_data, root) {
305
+ const dir = path.join(root, 'node_modules/$app/types');
306
+
307
+ const content = [
308
+ GENERATED_COMMENT,
309
+ `import '@sveltejs/kit';\nimport './env';`,
310
+ generate_app_types(manifest_data, config, dir),
311
+ template.trim()
312
+ ].join('\n\n');
264
313
 
265
- write_if_changed(path.join(config.outDir, 'non-ambient.d.ts'), content);
314
+ write_if_changed(path.join(dir, 'index.d.ts'), content);
266
315
  }
@@ -1,8 +1,6 @@
1
- import path from 'node:path';
2
- import { styleText } from 'node:util';
1
+ import { check_spelling, dedent, write_if_changed } from './utils.js';
3
2
  import { relative_path, resolve_entry } from '../../utils/filesystem.js';
4
3
  import { s } from '../../utils/misc.js';
5
- import { dedent, write_if_changed } from './utils.js';
6
4
 
7
5
  /**
8
6
  * Writes the client manifest to disk. The manifest is used to power the router. It contains the
@@ -123,15 +121,9 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
123
121
  const client_hooks_file = resolve_entry(kit.files.hooks.client);
124
122
  const universal_hooks_file = resolve_entry(kit.files.hooks.universal);
125
123
 
126
- const typo = resolve_entry('src/+hooks.client');
127
- if (typo) {
128
- console.log(
129
- styleText(
130
- ['bold', 'yellow'],
131
- `Unexpected + prefix. Did you mean ${typo.split('/').at(-1)?.slice(1)}?` +
132
- ` at ${path.resolve(typo)}`
133
- )
134
- );
124
+ if (!client_hooks_file) {
125
+ check_spelling('src/hooks.client', 'src/+hooks.client', 'Unexpected + prefix');
126
+ check_spelling('src/hooks.client', 'src/hook.client', 'Missing s suffix');
135
127
  }
136
128
 
137
129
  // Stringified version of
@@ -163,7 +155,7 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
163
155
  export const hooks = {
164
156
  handleError: ${
165
157
  client_hooks_file ? 'client_hooks.handleError || ' : ''
166
- }(({ error }) => { console.error(error) }),
158
+ }(({ kind, error }) => { if (kind === 'unknown') { console.error(error); } }),
167
159
  ${client_hooks_file ? 'init: client_hooks.init,' : ''}
168
160
  reroute: ${universal_hooks_file ? 'universal_hooks.reroute || ' : ''}(() => {}),
169
161
  transport: ${universal_hooks_file ? 'universal_hooks.transport || ' : ''}{}
@@ -176,26 +168,19 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
176
168
 
177
169
  export const decode = (type, value) => decoders[type](value);
178
170
 
179
- export { default as root } from '../root.js';
171
+ export const get_error_template = () => import('../shared/error-template.js').then(m => m.default);
180
172
  `
181
173
  );
182
174
 
183
175
  if (client_routing) {
184
- // write matchers to a separate module so that we don't
185
- // need to worry about name conflicts
186
- const imports = [];
187
- const matchers = [];
188
-
189
- for (const key in manifest_data.matchers) {
190
- const src = manifest_data.matchers[key];
191
-
192
- imports.push(`import { match as ${key} } from ${s(relative_path(output, src))};`);
193
- matchers.push(key);
194
- }
176
+ const uses_matchers = manifest_data.routes.some((route) =>
177
+ route.params.some((param) => param.matcher)
178
+ );
195
179
 
196
- const module = imports.length
197
- ? `${imports.join('\n')}\n\nexport const matchers = { ${matchers.join(', ')} };`
198
- : 'export const matchers = {};';
180
+ const module =
181
+ !manifest_data.params || !uses_matchers
182
+ ? 'export const matchers = {};'
183
+ : `import { params as matchers } from ${s(relative_path(output, manifest_data.params))};\n\nexport { matchers };`;
199
184
 
200
185
  write_if_changed(`${output}/matchers.js`, module);
201
186
  }
@@ -1,4 +1,4 @@
1
- /** @import { EnvVarConfig } from '@sveltejs/kit' */
1
+ /** @import { EnvVarConfig } from '@sveltejs/kit/env' */
2
2
  import path from 'node:path';
3
3
  import { create_explicit_env_types } from '../env.js';
4
4
  import { write_if_changed } from './utils.js';
@@ -10,16 +10,18 @@ const DOCS = '// See https://svelte.dev/docs/kit/environment-variables for more
10
10
  * Writes ambient declarations including types reference to @sveltejs/kit,
11
11
  * and the existing environment variables in process.env to
12
12
  * $env/static/private and $env/static/public
13
- * @param {import('types').ValidatedKitConfig} kit
14
13
  * @param {string | null} entry
15
14
  * @param {Record<string, EnvVarConfig<any>> | null} env_config
15
+ * @param {string} root
16
16
  */
17
- export function write_env(kit, entry, env_config) {
17
+ export function write_env(entry, env_config, root) {
18
18
  const content = [];
19
- const out = path.join(kit.outDir, 'env.d.ts');
19
+
20
+ const dir = path.join(root, 'node_modules/$app/types');
21
+ const out = path.join(dir, 'env.d.ts');
20
22
 
21
23
  if (entry && env_config) {
22
- const relative = posixify(path.relative(kit.outDir, entry));
24
+ const relative = posixify(path.relative(dir, entry));
23
25
  content.push(
24
26
  `// This file is generated from ${relative}.\n${DOCS}`,
25
27
  create_explicit_env_types(env_config, relative, 'private'),