@sveltejs/kit 3.0.0-next.11 → 3.0.0-next.12

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 (61) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +8 -8
  3. package/src/constants.js +1 -1
  4. package/src/core/config/options.js +43 -35
  5. package/src/core/env.js +25 -11
  6. package/src/core/sync/sync.js +11 -14
  7. package/src/core/sync/utils.js +21 -1
  8. package/src/core/sync/{write_non_ambient.js → write_app_types.js} +23 -21
  9. package/src/core/sync/write_client_manifest.js +4 -12
  10. package/src/core/sync/write_env.js +6 -4
  11. package/src/core/sync/write_server.js +10 -15
  12. package/src/core/sync/write_tsconfig/index.js +245 -0
  13. package/src/core/sync/write_tsconfig/utils.js +162 -0
  14. package/src/core/sync/write_types/index.js +80 -88
  15. package/src/exports/internal/server/index.js +3 -1
  16. package/src/exports/public.d.ts +28 -51
  17. package/src/exports/vite/dev/index.js +88 -76
  18. package/src/exports/vite/index.js +364 -144
  19. package/src/exports/vite/module_ids.js +3 -1
  20. package/src/exports/vite/utils.js +1 -10
  21. package/src/runner.js +13 -0
  22. package/src/runtime/app/forms.js +4 -0
  23. package/src/runtime/app/manifest/index.js +1 -0
  24. package/src/runtime/app/paths/client.js +30 -30
  25. package/src/runtime/app/paths/internal/client.js +26 -0
  26. package/src/runtime/app/paths/server.js +22 -9
  27. package/src/runtime/app/paths/types.d.ts +11 -19
  28. package/src/runtime/app/server/remote/command.js +12 -7
  29. package/src/runtime/app/server/remote/form.js +29 -26
  30. package/src/runtime/app/server/remote/prerender.js +9 -2
  31. package/src/runtime/app/server/remote/query.js +5 -4
  32. package/src/runtime/app/server/remote/shared.js +48 -30
  33. package/src/runtime/app/service-worker/index.js +24 -0
  34. package/src/runtime/app/state/index.js +1 -1
  35. package/src/runtime/client/client.js +46 -9
  36. package/src/runtime/client/remote-functions/form.svelte.js +43 -51
  37. package/src/runtime/client/remote-functions/query/index.js +2 -2
  38. package/src/runtime/client/remote-functions/query-batch.svelte.js +2 -3
  39. package/src/runtime/client/remote-functions/query-live/iterator.js +5 -2
  40. package/src/runtime/client/remote-functions/shared.svelte.js +4 -1
  41. package/src/runtime/client/state.svelte.js +54 -21
  42. package/src/runtime/form-utils.js +89 -54
  43. package/src/runtime/server/cookie.js +1 -1
  44. package/src/runtime/server/data/index.js +31 -28
  45. package/src/runtime/server/errors.js +1 -1
  46. package/src/runtime/server/page/actions.js +3 -3
  47. package/src/runtime/server/page/render.js +19 -28
  48. package/src/runtime/server/remote-functions.js +66 -35
  49. package/src/runtime/server/respond.js +56 -14
  50. package/src/runtime/server/utils.js +10 -0
  51. package/src/types/ambient-private.d.ts +8 -0
  52. package/src/types/ambient.d.ts +22 -27
  53. package/src/types/global-private.d.ts +12 -0
  54. package/src/types/internal.d.ts +13 -3
  55. package/src/utils/url.js +12 -0
  56. package/src/version.js +1 -1
  57. package/types/index.d.ts +80 -98
  58. package/types/index.d.ts.map +4 -1
  59. package/src/core/sync/write_ambient.js +0 -18
  60. package/src/core/sync/write_tsconfig.js +0 -258
  61. /package/src/core/sync/{write_tsconfig_test → write_tsconfig/test-app}/package.json +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "3.0.0-next.11",
3
+ "version": "3.0.0-next.12",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
package/src/cli.js CHANGED
@@ -75,19 +75,19 @@ if (!command) {
75
75
  }
76
76
 
77
77
  if (command === 'sync') {
78
- // create placeholder .svelte-kit/tsconfig.json if necessary, to squelch warnings.
78
+ // create placeholder node_modules/$app/tsconfig/tsconfig.json if necessary, to squelch warnings.
79
79
  // this isn't bulletproof — if someone has some esoteric config, it will continue
80
80
  // to harmlessly warn — but we handle the 90% case and clean up after ourselves
81
- const sveltekit_dir = '.svelte-kit';
82
- const base_tsconfig = `${sveltekit_dir}/tsconfig.json`;
81
+ const dir = 'node_modules/$app/tsconfig';
82
+ const base_tsconfig = `${dir}/tsconfig.json`;
83
83
  const base_tsconfig_json = '{}';
84
84
 
85
- const sveltekit_dir_exists = fs.existsSync(sveltekit_dir);
85
+ const sveltekit_dir_exists = fs.existsSync(dir);
86
86
  const base_tsconfig_exists = fs.existsSync(base_tsconfig);
87
87
 
88
88
  if (!base_tsconfig_exists) {
89
89
  try {
90
- fs.mkdirSync('.svelte-kit');
90
+ fs.mkdirSync(dir, { recursive: true });
91
91
  } catch {
92
92
  // ignore
93
93
  }
@@ -100,7 +100,7 @@ if (command === 'sync') {
100
100
  const sveltekit_config = extract_svelte_config(vite_config);
101
101
 
102
102
  const sync = await import('./core/sync/sync.js');
103
- sync.all_types(sveltekit_config);
103
+ sync.all_types(sveltekit_config, vite_config.root);
104
104
 
105
105
  const explicit_env_entry = resolve_explicit_env_entry(sveltekit_config.kit);
106
106
  await sync.env(sveltekit_config.kit, explicit_env_entry, vite_config.root, values.mode);
@@ -113,8 +113,8 @@ if (command === 'sync') {
113
113
  fs.unlinkSync(base_tsconfig);
114
114
  }
115
115
 
116
- if (!sveltekit_dir_exists && fs.readdirSync(sveltekit_dir).length === 0) {
117
- fs.rmSync(sveltekit_dir, { recursive: true });
116
+ if (!sveltekit_dir_exists && fs.readdirSync(dir).length === 0) {
117
+ fs.rmSync(dir, { recursive: true });
118
118
  }
119
119
  }
120
120
  } else {
package/src/constants.js CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  export const SVELTE_KIT_ASSETS = '/_svelte_kit_assets';
6
6
 
7
- export const GENERATED_COMMENT = '// this file is generated — do not edit it\n';
7
+ export const GENERATED_COMMENT = '// this file is generated — do not edit it';
8
8
 
9
9
  export const ENDPOINT_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'];
10
10
 
@@ -1,6 +1,7 @@
1
1
  /** @import { SvelteConfig } from '@sveltejs/vite-plugin-svelte' */
2
2
  /** @import { ValidatedKitConfig } from 'types' */
3
3
  /** @import { Validator } from './types.js' */
4
+ import { styleText } from 'node:util';
4
5
 
5
6
  const directives = object({
6
7
  'child-src': string_array(),
@@ -77,17 +78,21 @@ export const validate_kit_options = object({
77
78
  return input;
78
79
  }),
79
80
 
80
- alias: validate({}, (input, keypath) => {
81
- if (typeof input !== 'object') {
82
- throw new Error(`${keypath} should be an object`);
83
- }
81
+ alias: deprecate(
82
+ validate({}, (input, keypath) => {
83
+ if (typeof input !== 'object') {
84
+ throw new Error(`${keypath} should be an object`);
85
+ }
84
86
 
85
- for (const key in input) {
86
- assert_string(input[key], `${keypath}.${key}`);
87
- }
87
+ for (const key in input) {
88
+ assert_string(input[key], `${keypath}.${key}`);
89
+ }
88
90
 
89
- return input;
90
- }),
91
+ return input;
92
+ }),
93
+ (keypath) =>
94
+ `The \`${keypath}\` option is deprecated, and will be removed in a future version of SvelteKit. Use subpath imports instead: https://svelte.dev/docs/kit/$lib`
95
+ ),
91
96
 
92
97
  appDir: validate('_app', (input, keypath) => {
93
98
  assert_string(input, keypath);
@@ -270,47 +275,50 @@ export const validate_kit_options = object({
270
275
  }),
271
276
 
272
277
  serviceWorker: object({
278
+ files: removed(),
273
279
  register: boolean(true),
274
280
  // options could be undefined but if it is defined we only validate that
275
281
  // it's an object since the type comes from the browser itself
276
- options: validate(undefined, object({}, true)),
277
- files: fun((filename) => !/\.DS_Store/.test(filename))
282
+ options: validate(undefined, object({}, true))
278
283
  }),
279
284
 
280
285
  tracing: object({
281
286
  server: boolean(false)
282
287
  }),
283
288
 
284
- typescript: object({
285
- config: fun((config) => config)
286
- }),
289
+ typescript: deprecate(
290
+ object({
291
+ config: fun((config) => config)
292
+ }),
293
+ (keypath) => {
294
+ return `The \`${keypath}\` option is deprecated, and will be removed in a future version. Add configuration to tsconfig.json directly`;
295
+ }
296
+ ),
287
297
 
288
298
  version: object({
289
299
  name: string(Date.now().toString()),
290
- pollInterval: number(0)
300
+ pollInterval: number(3_600_000)
291
301
  })
292
302
  });
293
303
 
294
- // /**
295
- // * @param {Validator} fn
296
- // * @param {(keypath: string) => string} get_message
297
- // * @returns {Validator}
298
- // */
299
- // function deprecate(
300
- // fn,
301
- // get_message = (keypath) =>
302
- // `The \`${keypath}\` option is deprecated, and will be removed in a future version`
303
- // ) {
304
- // return (input, keypath) => {
305
- // keypath = remove_kit_prefix(keypath);
306
- //
307
- // if (input !== undefined) {
308
- // console.warn(styleText(['bold', 'yellow'], get_message(keypath)));
309
- // }
310
-
311
- // return fn(input, keypath);
312
- // };
313
- // }
304
+ /**
305
+ * @param {Validator} fn
306
+ * @param {(keypath: string) => string} get_message
307
+ * @returns {Validator}
308
+ */
309
+ function deprecate(
310
+ fn,
311
+ get_message = (keypath) =>
312
+ `The \`${keypath}\` option is deprecated, and will be removed in a future version`
313
+ ) {
314
+ return (input, keypath) => {
315
+ if (input !== undefined) {
316
+ console.warn(styleText(['bold', 'yellow'], get_message(keypath)));
317
+ }
318
+
319
+ return fn(input, keypath);
320
+ };
321
+ }
314
322
 
315
323
  // Derive the names of SvelteKit's own config options from the schema, so they
316
324
  // stay in sync automatically. These are used to separate Kit's options from
package/src/core/env.js CHANGED
@@ -10,6 +10,7 @@ import { runtime_directory } from './utils.js';
10
10
  import { resolve_entry } from '../utils/filesystem.js';
11
11
  import { handle_issues, validate } from '../exports/internal/env.js';
12
12
  import { get_config_aliases } from '../exports/vite/utils.js';
13
+ import { get_runner } from '../runner.js';
13
14
 
14
15
  /**
15
16
  * @typedef {'public' | 'private'} EnvType
@@ -52,12 +53,14 @@ export async function load_explicit_env(kit, file, root, mode) {
52
53
  /** @type {Record<string, EnvVarConfig<any>>} */
53
54
  let variables;
54
55
 
56
+ const runner = get_runner(server);
57
+
55
58
  /** @type {import('../runtime/app/env/internal.js')} */ (
56
- await server.ssrLoadModule(`${runtime_directory}/app/env/internal.js`)
59
+ await runner.import(`${runtime_directory}/app/env/internal.js`)
57
60
  ).set_building();
58
61
 
59
62
  try {
60
- ({ variables } = await server.ssrLoadModule(file));
63
+ ({ variables } = await runner.import(file));
61
64
 
62
65
  if (!variables || typeof variables !== 'object') {
63
66
  throw new Error(`${file} must export a variables object`);
@@ -238,25 +241,35 @@ export function create_sveltekit_env_public(variables, env, prelude) {
238
241
  * `env.js`. If there are none, values are inlined.
239
242
  * @param {Record<string, EnvVarConfig<any>> | null} variables
240
243
  * @param {Record<string, string>} env
244
+ * @param {string} version
241
245
  * @param {string} global
242
246
  * @param {string} base
243
247
  * @param {string} app_dir
244
248
  */
245
- export function create_sveltekit_env_service_worker(variables, env, global, base, app_dir) {
249
+ export function create_sveltekit_env_service_worker(
250
+ variables,
251
+ env,
252
+ version,
253
+ global,
254
+ base,
255
+ app_dir
256
+ ) {
246
257
  const has_dynamic_public_env = Object.values(variables ?? {}).some(
247
258
  (config) => config.public && !config.static
248
259
  );
249
260
 
250
261
  if (!has_dynamic_public_env) {
251
- return create_sveltekit_env_service_worker_dev(variables, env, global);
262
+ return create_sveltekit_env_service_worker_dev(variables, env, version, global);
252
263
  }
253
264
 
254
265
  return dedent`
255
266
  import { env } from '${base}/${app_dir}/env.js';
256
267
 
257
- globalThis.__SVELTEKIT_EXPERIMENTAL_EXPLICIT_ENVIRONMENT_VARIABLES__ = true;
258
-
259
- ${global} = { env };
268
+ ${global} = {
269
+ base: location.pathname.split('/').slice(0, -1).join('/'),
270
+ env,
271
+ version: ${JSON.stringify(version)}
272
+ };
260
273
  `;
261
274
  }
262
275
 
@@ -264,9 +277,10 @@ export function create_sveltekit_env_service_worker(variables, env, global, base
264
277
  * Creates the `__sveltekit/env/service-worker` module used in development
265
278
  * @param {Record<string, EnvVarConfig<any>> | null} variables
266
279
  * @param {Record<string, string>} env
280
+ * @param {string} version
267
281
  * @param {string} global
268
282
  */
269
- export function create_sveltekit_env_service_worker_dev(variables, env, global) {
283
+ export function create_sveltekit_env_service_worker_dev(variables, env, version, global) {
270
284
  /** @type {string[]} */
271
285
  const properties = [];
272
286
 
@@ -283,12 +297,12 @@ export function create_sveltekit_env_service_worker_dev(variables, env, global)
283
297
  handle_issues(issues);
284
298
 
285
299
  return dedent`
286
- globalThis.__SVELTEKIT_EXPERIMENTAL_EXPLICIT_ENVIRONMENT_VARIABLES__ = true;
287
-
288
300
  ${global} = {
301
+ base: location.pathname.split('/').slice(0, -1).join('/'),
289
302
  env: {
290
303
  ${properties.join(',\n\t\t') || '// empty'}
291
- }
304
+ },
305
+ version: ${JSON.stringify(version)}
292
306
  };
293
307
  `;
294
308
  }
@@ -1,11 +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_tsconfig } from './write_tsconfig.js';
4
+ import { write_tsconfig } from './write_tsconfig/index.js';
6
5
  import { write_types, write_all_types } from './write_types/index.js';
7
- import { write_ambient } from './write_ambient.js';
8
- import { write_non_ambient } from './write_non_ambient.js';
6
+ import { write_app_types } from './write_app_types.js';
9
7
  import { write_server } from './write_server.js';
10
8
  import {
11
9
  create_node_analyser,
@@ -21,7 +19,6 @@ import { write_env } from './write_env.js';
21
19
  */
22
20
  export function init(config, root) {
23
21
  write_tsconfig(config.kit, root);
24
- write_ambient(config.kit);
25
22
  }
26
23
 
27
24
  /**
@@ -37,7 +34,7 @@ export function create(config, root) {
37
34
  write_client_manifest(config.kit, manifest_data, `${output}/client`);
38
35
  write_server(config, output, root);
39
36
  write_all_types(config, manifest_data, root);
40
- write_non_ambient(config.kit, manifest_data);
37
+ write_app_types(config.kit, manifest_data, root);
41
38
 
42
39
  return { manifest_data };
43
40
  }
@@ -65,7 +62,7 @@ export function update(config, manifest_data, file, root) {
65
62
  }
66
63
 
67
64
  write_types(config, manifest_data, file, root);
68
- write_non_ambient(config.kit, manifest_data);
65
+ write_app_types(config.kit, manifest_data, root);
69
66
  }
70
67
 
71
68
  /**
@@ -81,13 +78,13 @@ export function all(config, root) {
81
78
  /**
82
79
  * Run sync.init and then generate all type files.
83
80
  * @param {import('types').ValidatedConfig} config
81
+ * @param {string} root
84
82
  */
85
- export function all_types(config) {
86
- const cwd = process.cwd();
87
- init(config, cwd);
88
- const manifest_data = create_manifest_data({ config, cwd });
89
- write_all_types(config, manifest_data, cwd);
90
- write_non_ambient(config.kit, manifest_data);
83
+ export function all_types(config, root) {
84
+ init(config, root);
85
+ const manifest_data = create_manifest_data({ config, cwd: root });
86
+ write_all_types(config, manifest_data, root);
87
+ write_app_types(config.kit, manifest_data, root);
91
88
  }
92
89
 
93
90
  /**
@@ -100,7 +97,7 @@ export function all_types(config) {
100
97
  export async function env(kit, entry, root, mode) {
101
98
  const env_config = await load_explicit_env(kit, entry, root, mode);
102
99
 
103
- write_env(kit, entry, env_config);
100
+ write_env(entry, env_config, root);
104
101
 
105
102
  return env_config;
106
103
  }
@@ -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 { mkdirp, resolve_entry } from '../../utils/filesystem.js';
4
5
 
5
6
  /** @type {Map<string, string>} */
6
7
  const previous_contents = new Map();
@@ -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
+ }
@@ -22,10 +22,6 @@ const remove_group_segments = (/** @type {string} */ id) => {
22
22
  * @returns {string[]}
23
23
  */
24
24
  function get_pathnames_for_trailing_slash(pathname, route) {
25
- if (pathname === '/') {
26
- return [pathname];
27
- }
28
-
29
25
  /** @type {Set<string>} */
30
26
  const pathnames = new Set();
31
27
 
@@ -55,8 +51,6 @@ function get_pathnames_for_trailing_slash(pathname, route) {
55
51
  // people could use to type their own components.
56
52
  // The T generic is needed or else there's a "all declarations must have identical type parameters" error.
57
53
  const template = `
58
- ${GENERATED_COMMENT}
59
-
60
54
  declare module "svelte/elements" {
61
55
  export interface HTMLAttributes<T> {
62
56
  'data-sveltekit-keepfocus'?: true | false | '' | undefined | null;
@@ -76,16 +70,15 @@ declare module "svelte/elements" {
76
70
  'data-sveltekit-replacestate'?: true | false | '' | undefined | null;
77
71
  }
78
72
  }
79
-
80
- export {};
81
73
  `;
82
74
 
83
75
  /**
84
76
  * Generate app types interface extension
85
77
  * @param {import('types').ManifestData} manifest_data
86
78
  * @param {import('types').ValidatedKitConfig} config
79
+ * @param {string} dir
87
80
  */
88
- function generate_app_types(manifest_data, config) {
81
+ function generate_app_types(manifest_data, config, dir) {
89
82
  /** @type {Map<string, string>} */
90
83
  const matcher_types = new Map();
91
84
 
@@ -100,7 +93,7 @@ function generate_app_types(manifest_data, config) {
100
93
  resolve_entry(config.files.params) ??
101
94
  config.files.params.replace(/\.(js|ts)$/, '') + '.js';
102
95
 
103
- return posixify(path.relative(config.outDir, params_file));
96
+ return posixify(path.relative(dir, params_file));
104
97
  };
105
98
 
106
99
  type = `import('@sveltejs/kit').MatcherParam<(typeof import('${path_to_params()}').params)[${JSON.stringify(matcher)}]>`;
@@ -201,7 +194,7 @@ function generate_app_types(manifest_data, config) {
201
194
 
202
195
  for (const route of manifest_data.routes) {
203
196
  const pathname = remove_group_segments(route.id);
204
- let normalized_pathname = pathname;
197
+ let normalized_pathname = pathname.slice(1);
205
198
 
206
199
  /** @type {(path: string) => string} */
207
200
  let serialise = s;
@@ -215,7 +208,7 @@ function generate_app_types(manifest_data, config) {
215
208
 
216
209
  dynamic_routes.push(route_type);
217
210
 
218
- normalized_pathname = replace_required_params(replace_optional_params(pathname));
211
+ normalized_pathname = replace_required_params(replace_optional_params(pathname)).slice(1);
219
212
  serialise = (p) => `\`${p}\` & {}`;
220
213
  }
221
214
 
@@ -240,7 +233,7 @@ function generate_app_types(manifest_data, config) {
240
233
  layouts.push(`${s(route.id)}: ${layout_type}`);
241
234
  }
242
235
 
243
- const assets = manifest_data.assets.map((asset) => s('/' + asset.file));
236
+ const assets = manifest_data.assets.map((asset) => s(asset.file));
244
237
 
245
238
  return [
246
239
  'declare module "$app/types" {',
@@ -248,22 +241,31 @@ function generate_app_types(manifest_data, config) {
248
241
  `\t\tRouteId(): ${manifest_data.routes.map((r) => s(r.id)).join(' | ')};`,
249
242
  `\t\tRouteParams(): {\n\t\t\t${dynamic_routes.join(';\n\t\t\t')}\n\t\t};`,
250
243
  `\t\tLayoutParams(): {\n\t\t\t${layouts.join(';\n\t\t\t')}\n\t\t};`,
251
- `\t\tPathname(): ${Array.from(pathnames).join(' | ')};`,
252
- '\t\tResolvedPathname(): `${"" | `/${string}`}${ReturnType<AppTypes[\'Pathname\']>}`;',
253
- `\t\tAsset(): ${assets.concat('string & {}').join(' | ')};`,
244
+ `\t\tPath(): ${Array.from(pathnames).join(' | ')};`,
245
+ '\t\tResolvedPathname(): `${"/" | `/${string}/`}${ReturnType<AppTypes[\'Path\']>}`;',
246
+ `\t\tAssetPath(): ${assets.join(' | ') || 'never'};`,
254
247
  '\t}',
255
248
  '}'
256
249
  ].join('\n');
257
250
  }
258
251
 
259
252
  /**
260
- * Writes non-ambient declarations to the output directory
253
+ * Writes `node_modules/$app/types/index.d.ts`. This file contains
254
+ * declarations for `$app/types` and `svelte/elements`, and
255
+ * imports `env.ts` which declares `$app/env/(public|private)`
261
256
  * @param {import('types').ValidatedKitConfig} config
262
257
  * @param {import('types').ManifestData} manifest_data
258
+ * @param {string} root
263
259
  */
264
- export function write_non_ambient(config, manifest_data) {
265
- const app_types = generate_app_types(manifest_data, config);
266
- const content = [template, app_types].join('\n\n');
260
+ export function write_app_types(config, manifest_data, root) {
261
+ const dir = path.join(root, 'node_modules/$app/types');
262
+
263
+ const content = [
264
+ GENERATED_COMMENT,
265
+ `import '@sveltejs/kit';\nimport './env';`,
266
+ generate_app_types(manifest_data, config, dir),
267
+ template.trim()
268
+ ].join('\n\n');
267
269
 
268
- write_if_changed(path.join(config.outDir, 'non-ambient.d.ts'), content);
270
+ write_if_changed(path.join(dir, 'index.d.ts'), content);
269
271
  }
@@ -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
@@ -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
  /**
@@ -54,6 +53,7 @@ export const options = {
54
53
  )},
55
54
  error
56
55
  },
56
+ version: ${s(config.kit.version.name)},
57
57
  version_hash: ${s(hash(config.kit.version.name))}
58
58
  };
59
59
 
@@ -83,10 +83,6 @@ export async function get_hooks() {
83
83
  export { set_assets, set_building, set_fix_stack_trace, set_manifest, set_prerendering, set_read_implementation };
84
84
  `;
85
85
 
86
- // TODO need to re-run this whenever src/app.html or src/error.html are
87
- // created or changed, or src/service-worker.js is created or deleted.
88
- // Also, need to check that updating hooks.server.js works
89
-
90
86
  /**
91
87
  * Write server configuration to disk
92
88
  * @param {import('types').ValidatedConfig} config
@@ -97,15 +93,14 @@ export function write_server(config, output, root) {
97
93
  const server_hooks_file = resolve_entry(config.kit.files.hooks.server);
98
94
  const universal_hooks_file = resolve_entry(config.kit.files.hooks.universal);
99
95
 
100
- const typo = resolve_entry('src/+hooks.server');
101
- if (typo) {
102
- console.log(
103
- styleText(
104
- ['bold', 'yellow'],
105
- `Unexpected + prefix. Did you mean ${typo.split('/').at(-1)?.slice(1)}?` +
106
- ` at ${path.resolve(typo)}`
107
- )
108
- );
96
+ if (!server_hooks_file) {
97
+ check_spelling('src/hooks.server', 'src/+hooks.server', 'Unexpected + prefix');
98
+ check_spelling('src/hooks.server', 'src/hook.server', 'Missing s suffix');
99
+ }
100
+
101
+ if (!universal_hooks_file) {
102
+ check_spelling('src/hooks', 'src/+hooks', 'Unexpected + prefix');
103
+ check_spelling('src/hooks', 'src/hook', 'Missing s suffix');
109
104
  }
110
105
 
111
106
  /** @param {string} file */