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

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 (195) hide show
  1. package/package.json +62 -36
  2. package/src/cli.js +15 -12
  3. package/src/constants.js +6 -1
  4. package/src/core/adapt/builder.js +66 -72
  5. package/src/core/adapt/index.js +17 -6
  6. package/src/core/config/index.js +134 -80
  7. package/src/core/config/options.js +295 -273
  8. package/src/core/config/types.d.ts +1 -1
  9. package/src/core/env.js +146 -16
  10. package/src/core/generate_manifest/index.js +18 -15
  11. package/src/core/postbuild/analyse.js +8 -20
  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 +222 -70
  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 +82 -62
  19. package/src/core/sync/sync.js +40 -31
  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} +107 -58
  23. package/src/core/sync/write_client_manifest.js +14 -29
  24. package/src/core/sync/write_env.js +7 -5
  25. package/src/core/sync/write_server.js +37 -45
  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 +127 -123
  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 +195 -0
  36. package/src/exports/hooks/sequence.js +9 -6
  37. package/src/exports/index.js +52 -29
  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} +2 -3
  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 +50 -1733
  49. package/src/exports/remote/index.js +11 -0
  50. package/src/exports/remote/public.d.ts +519 -0
  51. package/src/exports/url.js +86 -0
  52. package/src/exports/vite/build/build_server.js +54 -65
  53. package/src/exports/vite/build/remote.js +24 -19
  54. package/src/exports/vite/build/utils.js +0 -8
  55. package/src/exports/vite/dev/index.js +218 -146
  56. package/src/exports/vite/index.js +1590 -858
  57. package/src/exports/vite/module_ids.js +2 -2
  58. package/src/exports/vite/preview/index.js +40 -32
  59. package/src/exports/vite/public.d.ts +588 -0
  60. package/src/exports/vite/utils.js +84 -46
  61. package/src/pathname.js +55 -0
  62. package/src/runner.js +15 -0
  63. package/src/runtime/app/env/internal.js +4 -4
  64. package/src/runtime/app/env/types.d.ts +1 -1
  65. package/src/runtime/app/environment/index.js +3 -3
  66. package/src/runtime/app/{forms.js → forms/index.js} +73 -42
  67. package/src/runtime/app/forms/public.d.ts +2 -0
  68. package/src/runtime/app/forms/types.d.ts +56 -0
  69. package/src/runtime/app/internal/transport.js +53 -0
  70. package/src/runtime/app/manifest/index.js +1 -0
  71. package/src/runtime/app/{navigation.js → navigation/index.js} +2 -1
  72. package/src/runtime/app/navigation/public.d.ts +237 -0
  73. package/src/runtime/app/paths/client.js +37 -37
  74. package/src/runtime/app/paths/index.js +1 -1
  75. package/src/runtime/app/paths/internal/client.js +34 -2
  76. package/src/runtime/app/paths/internal/server.js +6 -23
  77. package/src/runtime/app/paths/internal.d.ts +3 -0
  78. package/src/runtime/app/paths/public.d.ts +1 -29
  79. package/src/runtime/app/paths/server.js +36 -17
  80. package/src/runtime/app/paths/types.d.ts +11 -19
  81. package/src/runtime/app/server/index.js +2 -2
  82. package/src/runtime/app/server/public.d.ts +201 -0
  83. package/src/runtime/app/server/remote/command.js +13 -11
  84. package/src/runtime/app/server/remote/form.js +61 -39
  85. package/src/runtime/app/server/remote/prerender.js +45 -45
  86. package/src/runtime/app/server/remote/query.js +106 -108
  87. package/src/runtime/app/server/remote/requested.js +27 -19
  88. package/src/runtime/app/server/remote/shared.js +76 -76
  89. package/src/runtime/app/service-worker/index.js +24 -0
  90. package/src/runtime/app/state/client.js +4 -2
  91. package/src/runtime/app/state/index.js +7 -5
  92. package/src/runtime/app/state/public.d.ts +72 -0
  93. package/src/runtime/app/state/server.js +3 -0
  94. package/src/runtime/app/stores.js +15 -78
  95. package/src/runtime/client/bundle.js +1 -1
  96. package/src/runtime/client/client-entry.js +3 -0
  97. package/src/runtime/client/client.js +1336 -648
  98. package/src/runtime/client/constants.js +3 -6
  99. package/src/runtime/client/entry.js +24 -3
  100. package/src/runtime/client/fetcher.js +25 -25
  101. package/src/runtime/client/ndjson.js +1 -1
  102. package/src/runtime/client/parse.js +1 -1
  103. package/src/runtime/client/payload.js +17 -0
  104. package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
  105. package/src/runtime/client/remote-functions/command.svelte.js +37 -61
  106. package/src/runtime/client/remote-functions/form.svelte.js +267 -178
  107. package/src/runtime/client/remote-functions/prerender.svelte.js +32 -11
  108. package/src/runtime/client/remote-functions/query/index.js +10 -17
  109. package/src/runtime/client/remote-functions/query/instance.svelte.js +64 -18
  110. package/src/runtime/client/remote-functions/query/proxy.js +5 -5
  111. package/src/runtime/client/remote-functions/query-batch.svelte.js +61 -70
  112. package/src/runtime/client/remote-functions/query-live/index.js +1 -1
  113. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +63 -21
  114. package/src/runtime/client/remote-functions/query-live/iterator.js +15 -12
  115. package/src/runtime/client/remote-functions/query-live/proxy.js +2 -12
  116. package/src/runtime/client/remote-functions/shared.svelte.js +90 -65
  117. package/src/runtime/client/snapshots.js +147 -0
  118. package/src/runtime/client/state.svelte.js +94 -55
  119. package/src/runtime/client/stream.js +3 -2
  120. package/src/runtime/client/types.d.ts +13 -9
  121. package/src/runtime/client/utils.js +22 -110
  122. package/src/runtime/components/root.svelte +56 -0
  123. package/src/runtime/env/dynamic/private.js +7 -0
  124. package/src/runtime/env/dynamic/public.js +7 -0
  125. package/src/runtime/env/static/private.js +6 -0
  126. package/src/runtime/env/static/public.js +6 -0
  127. package/src/runtime/form-utils.js +172 -61
  128. package/src/runtime/pathname.js +20 -32
  129. package/src/runtime/props.svelte.js +72 -0
  130. package/src/runtime/server/constants.js +0 -3
  131. package/src/runtime/server/cookie.js +72 -55
  132. package/src/runtime/server/csrf.js +65 -0
  133. package/src/runtime/server/data/index.js +49 -53
  134. package/src/runtime/server/dev.js +22 -0
  135. package/src/runtime/server/endpoint.js +6 -7
  136. package/src/runtime/server/env_module.js +0 -5
  137. package/src/runtime/server/errors.js +160 -0
  138. package/src/runtime/server/fetch.js +32 -39
  139. package/src/runtime/server/index.js +90 -64
  140. package/src/runtime/server/internal.js +71 -0
  141. package/src/runtime/server/page/actions.js +85 -64
  142. package/src/runtime/server/page/crypto.js +2 -2
  143. package/src/runtime/server/page/csp.js +88 -104
  144. package/src/runtime/server/page/data_serializer.js +24 -25
  145. package/src/runtime/server/page/index.js +36 -53
  146. package/src/runtime/server/page/load_data.js +50 -57
  147. package/src/runtime/server/page/render.js +173 -239
  148. package/src/runtime/server/page/respond_with_error.js +17 -31
  149. package/src/runtime/server/page/serialize_data.js +2 -13
  150. package/src/runtime/server/page/server_routing.js +85 -26
  151. package/src/runtime/server/remote-functions.js +640 -0
  152. package/src/runtime/server/respond.js +190 -131
  153. package/src/runtime/server/sourcemaps.js +183 -0
  154. package/src/runtime/server/state.js +53 -0
  155. package/src/runtime/server/utils.js +13 -155
  156. package/src/runtime/shared.js +20 -40
  157. package/src/runtime/utils.js +3 -0
  158. package/src/types/ambient-private.d.ts +11 -1
  159. package/src/types/ambient.d.ts +87 -36
  160. package/src/types/global-private.d.ts +25 -25
  161. package/src/types/internal.d.ts +163 -157
  162. package/src/types/private.d.ts +41 -1
  163. package/src/utils/error.js +28 -4
  164. package/src/utils/escape.js +9 -25
  165. package/src/utils/features.js +1 -1
  166. package/src/utils/filesystem.js +1 -23
  167. package/src/utils/fork.js +7 -2
  168. package/src/utils/hash.js +21 -0
  169. package/src/utils/http.js +8 -7
  170. package/src/utils/import.js +9 -2
  171. package/src/utils/imports.js +83 -0
  172. package/src/utils/mime.js +9 -0
  173. package/src/utils/page_nodes.js +6 -7
  174. package/src/utils/params.js +67 -0
  175. package/src/utils/regex.js +9 -0
  176. package/src/utils/routing.js +145 -73
  177. package/src/utils/shared-iterator.js +5 -0
  178. package/src/utils/streaming.js +14 -4
  179. package/src/utils/url.js +33 -2
  180. package/src/version.js +1 -1
  181. package/types/index.d.ts +2616 -2433
  182. package/types/index.d.ts.map +120 -106
  183. package/src/core/sync/write_ambient.js +0 -18
  184. package/src/core/sync/write_root.js +0 -148
  185. package/src/core/sync/write_tsconfig.js +0 -250
  186. package/src/exports/internal/server.js +0 -22
  187. package/src/exports/node/polyfills.js +0 -30
  188. package/src/runtime/server/app.js +0 -9
  189. package/src/runtime/server/remote.js +0 -457
  190. package/src/runtime/shared-server.js +0 -7
  191. package/src/runtime/telemetry/otel.js +0 -21
  192. package/src/runtime/telemetry/record_span.js +0 -65
  193. package/src/types/synthetic/$lib.md +0 -5
  194. /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
  195. /package/src/{runtime/telemetry/noop.js → telemetry.js} +0 -0
@@ -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
- * @param {import('types').ValidatedKitConfig} config
104
+ * @param {import('types').ValidatedConfig} 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
258
- * @param {import('types').ValidatedKitConfig} config
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)`
300
+ * @param {import('types').ValidatedConfig} 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,13 +1,11 @@
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
9
7
  * list of routes and corresponding Svelte components (i.e. pages and layouts).
10
- * @param {import('types').ValidatedKitConfig} kit
8
+ * @param {import('types').ValidatedConfig} kit
11
9
  * @param {import('types').ManifestData} manifest_data
12
10
  * @param {string} output
13
11
  * @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
@@ -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'),
@@ -1,11 +1,10 @@
1
1
  import path from 'node:path';
2
- import { styleText } from 'node:util';
3
2
  import { hash } from '../../utils/hash.js';
4
3
  import { resolve_entry } from '../../utils/filesystem.js';
5
4
  import { posixify } from '../../utils/os.js';
6
5
  import { s } from '../../utils/misc.js';
7
6
  import { load_error_page, load_template } from '../config/index.js';
8
- import { write_if_changed } from './utils.js';
7
+ import { check_spelling, write_if_changed } from './utils.js';
9
8
  import { escape_html } from '../../utils/escape.js';
10
9
 
11
10
  /**
@@ -15,7 +14,6 @@ import { escape_html } from '../../utils/escape.js';
15
14
  * config: import('types').ValidatedConfig;
16
15
  * has_service_worker: boolean;
17
16
  * template: string;
18
- * error_page: string;
19
17
  * }} opts
20
18
  */
21
19
  const server_template = ({
@@ -23,54 +21,48 @@ const server_template = ({
23
21
  server_hooks,
24
22
  universal_hooks,
25
23
  has_service_worker,
26
- template,
27
- error_page
24
+ template
28
25
  }) => `
29
- import root from '../root.js';
30
26
  import { set_building, set_prerendering } from '$app/env/internal';
31
27
  import { set_assets } from '$app/paths/internal/server';
32
- import { set_manifest, set_read_implementation } from '__sveltekit/server';
33
- import { set_env } from '__sveltekit/env';
28
+ import { set_fix_stack_trace, set_manifest, set_read_implementation, log_response } from '__sveltekit/server';
29
+ import error from '../shared/error-template.js';
34
30
 
35
31
  export const options = {
36
32
  app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')},
37
- async: ${s(!!config.compilerOptions?.experimental?.async)},
38
- csp: ${s(config.kit.csp)},
39
- csrf_check_origin: ${s(!config.kit.csrf.trustedOrigins.includes('*'))},
40
- csrf_trusted_origins: ${s(config.kit.csrf.trustedOrigins)},
41
- embedded: ${config.kit.embedded},
42
- hash_routing: ${s(config.kit.router.type === 'hash')},
33
+ csp: ${s(config.csp)},
34
+ csrf_check_origin: ${s(!config.csrf.trustedOrigins.includes('*'))},
35
+ csrf_trusted_origins: ${s(config.csrf.trustedOrigins)},
36
+ embedded: ${config.embedded},
37
+ hash_routing: ${s(config.router.type === 'hash')},
43
38
  hooks: null, // added lazily, via \`get_hooks\`
44
- link_header_preload: ${s(config.kit.output.linkHeaderPreload)},
45
- root,
39
+ link_header_preload: ${s(config.output.linkHeaderPreload)},
40
+ paths_origin: ${s(config.paths.origin)},
46
41
  service_worker: ${has_service_worker},
47
- service_worker_options: ${config.kit.serviceWorker.register ? s(config.kit.serviceWorker.options) : 'null'},
48
- server_error_boundaries: ${s(!!config.kit.experimental.handleRenderingErrors)},
42
+ service_worker_options: ${config.serviceWorker.register ? s(config.serviceWorker.options) : 'null'},
49
43
  templates: {
50
44
  app: ({ head, body, assets, nonce, env }) => ${s(template)
51
45
  .replace('%sveltekit.head%', '" + head + "')
52
46
  .replace('%sveltekit.body%', '" + body + "')
53
47
  .replace(/%sveltekit\.assets%/g, '" + assets + "')
54
48
  .replace(/%sveltekit\.nonce%/g, '" + nonce + "')
55
- .replace(/%sveltekit\.version%/g, escape_html(config.kit.version.name))
49
+ .replace(/%sveltekit\.version%/g, escape_html(config.version.name))
56
50
  .replace(
57
51
  /%sveltekit\.env\.([^%]+)%/g,
58
52
  (_match, capture) => `" + (env[${s(capture)}] ?? "") + "`
59
53
  )},
60
- error: ({ status, message }) => ${s(error_page)
61
- .replace(/%sveltekit\.status%/g, '" + status + "')
62
- .replace(/%sveltekit\.error\.message%/g, '" + message + "')}
54
+ error
63
55
  },
64
- version_hash: ${s(hash(config.kit.version.name))}
56
+ version: ${s(config.version.name)},
57
+ version_hash: ${s(hash(config.version.name))}
65
58
  };
66
59
 
67
60
  export async function get_hooks() {
68
61
  let handle;
69
62
  let handleFetch;
70
63
  let handleError;
71
- let handleValidationError;
72
64
  let init;
73
- ${server_hooks ? `({ handle, handleFetch, handleError, handleValidationError, init } = await import(${s(server_hooks)}));` : ''}
65
+ ${server_hooks ? `({ handle, handleFetch, handleError, init } = await import(${s(server_hooks)}));` : ''}
74
66
 
75
67
  let reroute;
76
68
  let transport;
@@ -80,20 +72,15 @@ export async function get_hooks() {
80
72
  handle,
81
73
  handleFetch,
82
74
  handleError,
83
- handleValidationError,
84
75
  init,
85
76
  reroute,
86
77
  transport
87
78
  };
88
79
  }
89
80
 
90
- export { set_assets, set_building, set_env, set_manifest, set_prerendering, set_read_implementation };
81
+ export { set_assets, set_building, set_fix_stack_trace, set_manifest, set_prerendering, set_read_implementation, log_response };
91
82
  `;
92
83
 
93
- // TODO need to re-run this whenever src/app.html or src/error.html are
94
- // created or changed, or src/service-worker.js is created or deleted.
95
- // Also, need to check that updating hooks.server.js works
96
-
97
84
  /**
98
85
  * Write server configuration to disk
99
86
  * @param {import('types').ValidatedConfig} config
@@ -101,18 +88,17 @@ export { set_assets, set_building, set_env, set_manifest, set_prerendering, set_
101
88
  * @param {string} root The project root directory
102
89
  */
103
90
  export function write_server(config, output, root) {
104
- const server_hooks_file = resolve_entry(config.kit.files.hooks.server);
105
- const universal_hooks_file = resolve_entry(config.kit.files.hooks.universal);
91
+ const server_hooks_file = resolve_entry(config.files.hooks.server);
92
+ const universal_hooks_file = resolve_entry(config.files.hooks.universal);
93
+
94
+ if (!server_hooks_file) {
95
+ check_spelling('src/hooks.server', 'src/+hooks.server', 'Unexpected + prefix');
96
+ check_spelling('src/hooks.server', 'src/hook.server', 'Missing s suffix');
97
+ }
106
98
 
107
- const typo = resolve_entry('src/+hooks.server');
108
- if (typo) {
109
- console.log(
110
- styleText(
111
- ['bold', 'yellow'],
112
- `Unexpected + prefix. Did you mean ${typo.split('/').at(-1)?.slice(1)}?` +
113
- ` at ${path.resolve(typo)}`
114
- )
115
- );
99
+ if (!universal_hooks_file) {
100
+ check_spelling('src/hooks', 'src/+hooks', 'Unexpected + prefix');
101
+ check_spelling('src/hooks', 'src/hook', 'Missing s suffix');
116
102
  }
117
103
 
118
104
  /** @param {string} file */
@@ -120,6 +106,13 @@ export function write_server(config, output, root) {
120
106
  return posixify(path.relative(`${output}/server`, file));
121
107
  }
122
108
 
109
+ write_if_changed(
110
+ `${output}/shared/error-template.js`,
111
+ `export default ({ status, message }) => ${s(load_error_page(config))
112
+ .replace(/%sveltekit\.status%/g, '" + status + "')
113
+ .replace(/%sveltekit\.error\.message%/g, '" + message + "')};`
114
+ );
115
+
123
116
  // Contains the stringified version of
124
117
  /** @type {import('types').SSROptions} */
125
118
  write_if_changed(
@@ -129,9 +122,8 @@ export function write_server(config, output, root) {
129
122
  server_hooks: server_hooks_file ? relative(server_hooks_file) : null,
130
123
  universal_hooks: universal_hooks_file ? relative(universal_hooks_file) : null,
131
124
  has_service_worker:
132
- config.kit.serviceWorker.register && !!resolve_entry(config.kit.files.serviceWorker),
133
- template: load_template(root, config),
134
- error_page: load_error_page(config)
125
+ config.serviceWorker.register && !!resolve_entry(config.files.serviceWorker),
126
+ template: load_template(root, config)
135
127
  })
136
128
  );
137
129
  }