@sveltejs/kit 1.0.0-next.45 → 1.0.0-next.452

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 (108) hide show
  1. package/README.md +12 -9
  2. package/package.json +92 -63
  3. package/src/cli.js +112 -0
  4. package/src/constants.js +7 -0
  5. package/src/core/adapt/builder.js +223 -0
  6. package/src/core/adapt/index.js +19 -0
  7. package/src/core/config/index.js +86 -0
  8. package/src/core/config/options.js +488 -0
  9. package/src/core/config/types.d.ts +1 -0
  10. package/src/core/env.js +112 -0
  11. package/src/core/generate_manifest/index.js +78 -0
  12. package/src/core/prerender/crawl.js +194 -0
  13. package/src/core/prerender/prerender.js +380 -0
  14. package/src/core/prerender/queue.js +80 -0
  15. package/src/core/sync/create_manifest_data/index.js +452 -0
  16. package/src/core/sync/create_manifest_data/types.d.ts +37 -0
  17. package/src/core/sync/sync.js +59 -0
  18. package/src/core/sync/utils.js +33 -0
  19. package/src/core/sync/write_ambient.js +53 -0
  20. package/src/core/sync/write_client_manifest.js +94 -0
  21. package/src/core/sync/write_matchers.js +25 -0
  22. package/src/core/sync/write_root.js +91 -0
  23. package/src/core/sync/write_tsconfig.js +195 -0
  24. package/src/core/sync/write_types/index.js +596 -0
  25. package/src/core/utils.js +70 -0
  26. package/src/exports/hooks/index.js +1 -0
  27. package/src/exports/hooks/sequence.js +26 -0
  28. package/src/exports/index.js +45 -0
  29. package/src/exports/node/index.js +145 -0
  30. package/src/exports/node/polyfills.js +40 -0
  31. package/src/exports/vite/build/build_server.js +348 -0
  32. package/src/exports/vite/build/build_service_worker.js +90 -0
  33. package/src/exports/vite/build/utils.js +160 -0
  34. package/src/exports/vite/dev/index.js +543 -0
  35. package/src/exports/vite/index.js +588 -0
  36. package/src/exports/vite/preview/index.js +186 -0
  37. package/src/exports/vite/types.d.ts +3 -0
  38. package/src/exports/vite/utils.js +345 -0
  39. package/src/runtime/app/env.js +1 -0
  40. package/src/runtime/app/environment.js +11 -0
  41. package/src/runtime/app/navigation.js +22 -0
  42. package/src/runtime/app/paths.js +1 -0
  43. package/src/runtime/app/stores.js +102 -0
  44. package/src/runtime/client/ambient.d.ts +24 -0
  45. package/src/runtime/client/client.js +1394 -0
  46. package/src/runtime/client/fetcher.js +60 -0
  47. package/src/runtime/client/parse.js +60 -0
  48. package/src/runtime/client/singletons.js +21 -0
  49. package/src/runtime/client/start.js +48 -0
  50. package/src/runtime/client/types.d.ts +88 -0
  51. package/src/runtime/client/utils.js +113 -0
  52. package/src/runtime/components/error.svelte +16 -0
  53. package/{assets → src/runtime}/components/layout.svelte +0 -0
  54. package/src/runtime/control.js +33 -0
  55. package/src/runtime/env/dynamic/private.js +1 -0
  56. package/src/runtime/env/dynamic/public.js +1 -0
  57. package/src/runtime/env-private.js +6 -0
  58. package/src/runtime/env-public.js +6 -0
  59. package/src/runtime/env.js +6 -0
  60. package/src/runtime/hash.js +16 -0
  61. package/src/runtime/paths.js +11 -0
  62. package/src/runtime/server/data/index.js +146 -0
  63. package/src/runtime/server/endpoint.js +50 -0
  64. package/src/runtime/server/index.js +369 -0
  65. package/src/runtime/server/page/cookie.js +25 -0
  66. package/src/runtime/server/page/crypto.js +239 -0
  67. package/src/runtime/server/page/csp.js +249 -0
  68. package/src/runtime/server/page/fetch.js +266 -0
  69. package/src/runtime/server/page/index.js +413 -0
  70. package/src/runtime/server/page/load_data.js +124 -0
  71. package/src/runtime/server/page/render.js +379 -0
  72. package/src/runtime/server/page/respond_with_error.js +94 -0
  73. package/src/runtime/server/page/types.d.ts +44 -0
  74. package/src/runtime/server/utils.js +137 -0
  75. package/src/utils/array.js +9 -0
  76. package/src/utils/error.js +22 -0
  77. package/src/utils/escape.js +104 -0
  78. package/src/utils/filesystem.js +108 -0
  79. package/src/utils/functions.js +16 -0
  80. package/src/utils/http.js +55 -0
  81. package/src/utils/misc.js +1 -0
  82. package/src/utils/routing.js +146 -0
  83. package/src/utils/url.js +142 -0
  84. package/svelte-kit.js +1 -1
  85. package/types/ambient.d.ts +319 -0
  86. package/types/index.d.ts +345 -0
  87. package/types/internal.d.ts +379 -0
  88. package/types/private.d.ts +209 -0
  89. package/CHANGELOG.md +0 -450
  90. package/assets/components/error.svelte +0 -13
  91. package/assets/runtime/app/env.js +0 -5
  92. package/assets/runtime/app/navigation.js +0 -41
  93. package/assets/runtime/app/paths.js +0 -1
  94. package/assets/runtime/app/stores.js +0 -93
  95. package/assets/runtime/chunks/utils.js +0 -19
  96. package/assets/runtime/internal/singletons.js +0 -23
  97. package/assets/runtime/internal/start.js +0 -770
  98. package/assets/runtime/paths.js +0 -12
  99. package/dist/chunks/index.js +0 -3521
  100. package/dist/chunks/index2.js +0 -587
  101. package/dist/chunks/index3.js +0 -246
  102. package/dist/chunks/index4.js +0 -536
  103. package/dist/chunks/index5.js +0 -761
  104. package/dist/chunks/index6.js +0 -322
  105. package/dist/chunks/standard.js +0 -99
  106. package/dist/chunks/utils.js +0 -83
  107. package/dist/cli.js +0 -546
  108. package/dist/ssr.js +0 -2580
@@ -0,0 +1,452 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import mime from 'mime';
4
+ import { runtime_directory } from '../../utils.js';
5
+ import { posixify } from '../../../utils/filesystem.js';
6
+ import { parse_route_id, affects_path } from '../../../utils/routing.js';
7
+
8
+ /**
9
+ * @param {{
10
+ * config: import('types').ValidatedConfig;
11
+ * fallback?: string;
12
+ * cwd?: string;
13
+ * }} opts
14
+ * @returns {import('types').ManifestData}
15
+ */
16
+ export default function create_manifest_data({
17
+ config,
18
+ fallback = `${runtime_directory}/components`,
19
+ cwd = process.cwd()
20
+ }) {
21
+ const assets = create_assets(config);
22
+ const matchers = create_matchers(config, cwd);
23
+ const { nodes, routes } = create_routes_and_nodes(cwd, config, fallback);
24
+
25
+ return {
26
+ assets,
27
+ matchers,
28
+ nodes,
29
+ routes
30
+ };
31
+ }
32
+
33
+ /**
34
+ * @param {import('types').ValidatedConfig} config
35
+ */
36
+ function create_assets(config) {
37
+ return list_files(config.kit.files.assets).map((file) => ({
38
+ file,
39
+ size: fs.statSync(path.resolve(config.kit.files.assets, file)).size,
40
+ type: mime.getType(file)
41
+ }));
42
+ }
43
+
44
+ /**
45
+ * @param {import('types').ValidatedConfig} config
46
+ * @param {string} cwd
47
+ */
48
+ function create_matchers(config, cwd) {
49
+ const params_base = path.relative(cwd, config.kit.files.params);
50
+
51
+ /** @type {Record<string, string>} */
52
+ const matchers = {};
53
+ if (fs.existsSync(config.kit.files.params)) {
54
+ for (const file of fs.readdirSync(config.kit.files.params)) {
55
+ const ext = path.extname(file);
56
+ if (!config.kit.moduleExtensions.includes(ext)) continue;
57
+ const type = file.slice(0, -ext.length);
58
+
59
+ if (/^\w+$/.test(type)) {
60
+ const matcher_file = path.join(params_base, file);
61
+
62
+ // Disallow same matcher with different extensions
63
+ if (matchers[type]) {
64
+ throw new Error(`Duplicate matchers: ${matcher_file} and ${matchers[type]}`);
65
+ } else {
66
+ matchers[type] = matcher_file;
67
+ }
68
+ } else {
69
+ throw new Error(
70
+ `Matcher names can only have underscores and alphanumeric characters — "${file}" is invalid`
71
+ );
72
+ }
73
+ }
74
+ }
75
+
76
+ return matchers;
77
+ }
78
+
79
+ /**
80
+ * @param {import('types').ValidatedConfig} config
81
+ * @param {string} cwd
82
+ * @param {string} fallback
83
+ */
84
+ function create_routes_and_nodes(cwd, config, fallback) {
85
+ /** @type {Map<string, import('types').RouteData>} */
86
+ const route_map = new Map();
87
+
88
+ /** @type {Map<string, import('./types').Part[][]>} */
89
+ const segment_map = new Map();
90
+
91
+ const routes_base = posixify(path.relative(cwd, config.kit.files.routes));
92
+
93
+ const valid_extensions = [...config.extensions, ...config.kit.moduleExtensions];
94
+
95
+ /** @type {import('types').PageNode[]} */
96
+ const nodes = [];
97
+
98
+ if (fs.existsSync(config.kit.files.routes)) {
99
+ /**
100
+ * @param {number} depth
101
+ * @param {string} id
102
+ * @param {string} segment
103
+ * @param {import('types').RouteData | null} parent
104
+ */
105
+ const walk = (depth, id, segment, parent) => {
106
+ const { pattern, names, types } = parse_route_id(id);
107
+
108
+ const segments = id.split('/');
109
+
110
+ segment_map.set(
111
+ id,
112
+ segments
113
+ .filter((segment) => segment !== '' && affects_path(segment))
114
+ .map((segment) => {
115
+ /** @type {import('./types').Part[]} */
116
+ const parts = [];
117
+ segment.split(/\[(.+?)\]/).map((content, i) => {
118
+ const dynamic = !!(i % 2);
119
+
120
+ if (!content) return;
121
+
122
+ parts.push({
123
+ content,
124
+ dynamic,
125
+ rest: dynamic && content.startsWith('...'),
126
+ type: (dynamic && content.split('=')[1]) || null
127
+ });
128
+ });
129
+ return parts;
130
+ })
131
+ );
132
+
133
+ /** @type {import('types').RouteData} */
134
+ const route = {
135
+ id,
136
+ parent,
137
+
138
+ segment,
139
+ pattern,
140
+ names,
141
+ types,
142
+
143
+ layout: null,
144
+ error: null,
145
+ leaf: null,
146
+ page: null,
147
+ endpoint: null
148
+ };
149
+
150
+ // important to do this before walking children, so that child
151
+ // routes appear later
152
+ route_map.set(id, route);
153
+
154
+ // if we don't do this, the route map becomes unwieldy to console.log
155
+ Object.defineProperty(route, 'parent', { enumerable: false });
156
+
157
+ const dir = path.join(cwd, routes_base, id);
158
+
159
+ const files = fs.readdirSync(dir, {
160
+ withFileTypes: true
161
+ });
162
+
163
+ // process files first
164
+ for (const file of files) {
165
+ if (file.isDirectory()) continue;
166
+ if (!file.name.startsWith('+')) continue;
167
+ if (!valid_extensions.find((ext) => file.name.endsWith(ext))) continue;
168
+
169
+ const project_relative = posixify(path.relative(cwd, path.join(dir, file.name)));
170
+
171
+ const item = analyze(
172
+ project_relative,
173
+ file.name,
174
+ config.extensions,
175
+ config.kit.moduleExtensions
176
+ );
177
+
178
+ if (item.kind === 'component') {
179
+ if (item.is_error) {
180
+ route.error = {
181
+ depth,
182
+ component: project_relative
183
+ };
184
+ } else if (item.is_layout) {
185
+ if (!route.layout) route.layout = { depth, child_pages: [] };
186
+ route.layout.component = project_relative;
187
+ if (item.uses_layout !== undefined) route.layout.parent_id = item.uses_layout;
188
+ } else {
189
+ if (!route.leaf) route.leaf = { depth };
190
+ route.leaf.component = project_relative;
191
+ if (item.uses_layout !== undefined) route.leaf.parent_id = item.uses_layout;
192
+ }
193
+ } else if (item.is_layout) {
194
+ if (!route.layout) route.layout = { depth, child_pages: [] };
195
+ route.layout[item.kind] = project_relative;
196
+ } else if (item.is_page) {
197
+ if (!route.leaf) route.leaf = { depth };
198
+ route.leaf[item.kind] = project_relative;
199
+ } else {
200
+ route.endpoint = {
201
+ file: project_relative
202
+ };
203
+ }
204
+ }
205
+
206
+ // then handle children
207
+ for (const file of files) {
208
+ if (file.isDirectory()) {
209
+ walk(depth + 1, path.posix.join(id, file.name), file.name, route);
210
+ }
211
+ }
212
+ };
213
+
214
+ walk(0, '', '', null);
215
+
216
+ const root = /** @type {import('types').RouteData} */ (route_map.get(''));
217
+
218
+ // TODO remove for 1.0
219
+ if (route_map.size === 1) {
220
+ if (!root.leaf && !root.error && !root.layout && !root.endpoint) {
221
+ throw new Error(
222
+ 'The filesystem router API has changed, see https://github.com/sveltejs/kit/discussions/5774 for details'
223
+ );
224
+ }
225
+ }
226
+
227
+ if (!root.layout?.component) {
228
+ if (!root.layout) root.layout = { depth: 0, child_pages: [] };
229
+ root.layout.component = posixify(path.relative(cwd, `${fallback}/layout.svelte`));
230
+ }
231
+
232
+ if (!root.error?.component) {
233
+ if (!root.error) root.error = { depth: 0 };
234
+ root.error.component = posixify(path.relative(cwd, `${fallback}/error.svelte`));
235
+ }
236
+
237
+ // we do layouts/errors first as they are more likely to be reused,
238
+ // and smaller indexes take fewer bytes. also, this guarantees that
239
+ // the default error/layout are 0/1
240
+ route_map.forEach((route) => {
241
+ if (route.layout) nodes.push(route.layout);
242
+ if (route.error) nodes.push(route.error);
243
+ });
244
+
245
+ /** @type {Map<string, string>} */
246
+ const conflicts = new Map();
247
+
248
+ route_map.forEach((route) => {
249
+ if (!route.leaf) return;
250
+
251
+ nodes.push(route.leaf);
252
+
253
+ const normalized = route.id.split('/').filter(affects_path).join('/');
254
+
255
+ if (conflicts.has(normalized)) {
256
+ throw new Error(`${conflicts.get(normalized)} and ${route.id} occupy the same route`);
257
+ }
258
+
259
+ conflicts.set(normalized, route.id);
260
+ });
261
+
262
+ const indexes = new Map(nodes.map((node, i) => [node, i]));
263
+
264
+ route_map.forEach((route) => {
265
+ if (!route.leaf) return;
266
+
267
+ if (route.leaf && route.endpoint) {
268
+ // TODO possibly relax this https://github.com/sveltejs/kit/issues/5896
269
+ throw new Error(`${route.endpoint.file} cannot share a directory with other route files`);
270
+ }
271
+
272
+ route.page = {
273
+ layouts: [],
274
+ errors: [],
275
+ leaf: /** @type {number} */ (indexes.get(route.leaf))
276
+ };
277
+
278
+ /** @type {import('types').RouteData | null} */
279
+ let current_route = route;
280
+ let current_node = route.leaf;
281
+ let parent_id = route.leaf.parent_id;
282
+
283
+ while (current_route) {
284
+ if (parent_id === undefined || current_route.segment === parent_id) {
285
+ if (current_route.layout || current_route.error) {
286
+ route.page.layouts.unshift(
287
+ current_route.layout ? indexes.get(current_route.layout) : undefined
288
+ );
289
+ route.page.errors.unshift(
290
+ current_route.error ? indexes.get(current_route.error) : undefined
291
+ );
292
+ }
293
+
294
+ if (current_route.layout) {
295
+ /** @type {import('types').PageNode[]} */ (current_route.layout.child_pages).push(
296
+ route.leaf
297
+ );
298
+ current_node.parent = current_node = current_route.layout;
299
+ parent_id = current_node.parent_id;
300
+ } else {
301
+ parent_id = undefined;
302
+ }
303
+ }
304
+
305
+ current_route = current_route.parent;
306
+ }
307
+
308
+ if (parent_id !== undefined) {
309
+ throw new Error(`${current_node.component} references missing segment "${parent_id}"`);
310
+ }
311
+ });
312
+ }
313
+
314
+ const routes = Array.from(route_map.values()).sort((a, b) => compare(a, b, segment_map));
315
+
316
+ return { nodes, routes };
317
+ }
318
+
319
+ /**
320
+ * @param {string} project_relative
321
+ * @param {string} file
322
+ * @param {string[]} component_extensions
323
+ * @param {string[]} module_extensions
324
+ * @returns {import('./types').RouteFile}
325
+ */
326
+ function analyze(project_relative, file, component_extensions, module_extensions) {
327
+ const component_extension = component_extensions.find((ext) => file.endsWith(ext));
328
+ if (component_extension) {
329
+ const name = file.slice(0, -component_extension.length);
330
+ const pattern = /^\+(?:(page(?:@(.*))?)|(layout(?:@(.*))?)|(error))$/;
331
+ const match = pattern.exec(name);
332
+ if (!match) {
333
+ // TODO remove for 1.0
334
+ if (/^\+layout-/.test(name)) {
335
+ throw new Error(
336
+ `${project_relative} should be reimplemented with layout groups: https://kit.svelte.dev/docs/advanced-routing#advanced-layouts`
337
+ );
338
+ }
339
+
340
+ throw new Error(`Files prefixed with + are reserved (saw ${project_relative})`);
341
+ }
342
+
343
+ return {
344
+ kind: 'component',
345
+ is_page: !!match[1],
346
+ is_layout: !!match[3],
347
+ is_error: !!match[5],
348
+ uses_layout: match[2] ?? match[4]
349
+ };
350
+ }
351
+
352
+ const module_extension = module_extensions.find((ext) => file.endsWith(ext));
353
+ if (module_extension) {
354
+ const name = file.slice(0, -module_extension.length);
355
+ const pattern =
356
+ /^\+(?:(server)|(page(?:(@[a-zA-Z0-9_-]*))?(\.server)?)|(layout(?:(@[a-zA-Z0-9_-]*))?(\.server)?))$/;
357
+ const match = pattern.exec(name);
358
+ if (!match) {
359
+ throw new Error(`Files prefixed with + are reserved (saw ${project_relative})`);
360
+ } else if (match[3] || match[6]) {
361
+ throw new Error(
362
+ // prettier-ignore
363
+ `Only Svelte files can reference named layouts. Remove '${match[3] || match[6]}' from ${file} (at ${project_relative})`
364
+ );
365
+ }
366
+
367
+ const kind = !!(match[1] || match[4] || match[7]) ? 'server' : 'shared';
368
+
369
+ return {
370
+ kind,
371
+ is_page: !!match[2],
372
+ is_layout: !!match[5]
373
+ };
374
+ }
375
+
376
+ throw new Error(`Files and directories prefixed with + are reserved (saw ${project_relative})`);
377
+ }
378
+
379
+ /**
380
+ * @param {import('types').RouteData} a
381
+ * @param {import('types').RouteData} b
382
+ * @param {Map<string, import('./types').Part[][]>} segment_map
383
+ */
384
+ function compare(a, b, segment_map) {
385
+ const a_segments = /** @type {import('./types').Part[][]} */ (segment_map.get(a.id));
386
+ const b_segments = /** @type {import('./types').Part[][]} */ (segment_map.get(b.id));
387
+
388
+ const max_segments = Math.max(a_segments.length, b_segments.length);
389
+ for (let i = 0; i < max_segments; i += 1) {
390
+ const sa = a_segments[i];
391
+ const sb = b_segments[i];
392
+
393
+ // /x < /x/y, but /[...x]/y < /[...x]
394
+ if (!sa) return a.id.includes('[...') ? +1 : -1;
395
+ if (!sb) return b.id.includes('[...') ? -1 : +1;
396
+
397
+ const max_parts = Math.max(sa.length, sb.length);
398
+ for (let i = 0; i < max_parts; i += 1) {
399
+ const pa = sa[i];
400
+ const pb = sb[i];
401
+
402
+ // xy < x[y], but [x].json < [x]
403
+ if (pa === undefined) return pb.dynamic ? -1 : +1;
404
+ if (pb === undefined) return pa.dynamic ? +1 : -1;
405
+
406
+ // x < [x]
407
+ if (pa.dynamic !== pb.dynamic) {
408
+ return pa.dynamic ? +1 : -1;
409
+ }
410
+
411
+ if (pa.dynamic) {
412
+ // [x] < [...x]
413
+ if (pa.rest !== pb.rest) {
414
+ return pa.rest ? +1 : -1;
415
+ }
416
+
417
+ // [x=type] < [x]
418
+ if (!!pa.type !== !!pb.type) {
419
+ return pa.type ? -1 : +1;
420
+ }
421
+ }
422
+ }
423
+ }
424
+
425
+ if (!!a.endpoint !== !!b.endpoint) {
426
+ return a.endpoint ? -1 : +1;
427
+ }
428
+
429
+ return a < b ? -1 : 1;
430
+ }
431
+
432
+ /** @param {string} dir */
433
+ function list_files(dir) {
434
+ /** @type {string[]} */
435
+ const files = [];
436
+
437
+ /** @param {string} current */
438
+ function walk(current) {
439
+ for (const file of fs.readdirSync(path.resolve(dir, current))) {
440
+ const child = path.posix.join(current, file);
441
+ if (fs.statSync(path.resolve(dir, child)).isDirectory()) {
442
+ walk(child);
443
+ } else {
444
+ files.push(child);
445
+ }
446
+ }
447
+ }
448
+
449
+ if (fs.existsSync(dir)) walk('');
450
+
451
+ return files;
452
+ }
@@ -0,0 +1,37 @@
1
+ import { PageNode } from 'types';
2
+
3
+ interface Part {
4
+ content: string;
5
+ dynamic: boolean;
6
+ rest: boolean;
7
+ type: string | null;
8
+ }
9
+
10
+ interface RouteTreeNode {
11
+ error: PageNode | undefined;
12
+ layout: PageNode | undefined;
13
+ }
14
+
15
+ export type RouteTree = Map<string, RouteTreeNode>;
16
+
17
+ interface RouteComponent {
18
+ kind: 'component';
19
+ is_page: boolean;
20
+ is_layout: boolean;
21
+ is_error: boolean;
22
+ uses_layout: string | undefined;
23
+ }
24
+
25
+ interface RouteSharedModule {
26
+ kind: 'shared';
27
+ is_page: boolean;
28
+ is_layout: boolean;
29
+ }
30
+
31
+ interface RouteServerModule {
32
+ kind: 'server';
33
+ is_page: boolean;
34
+ is_layout: boolean;
35
+ }
36
+
37
+ export type RouteFile = RouteComponent | RouteSharedModule | RouteServerModule;
@@ -0,0 +1,59 @@
1
+ import path from 'path';
2
+ import create_manifest_data from './create_manifest_data/index.js';
3
+ import { write_client_manifest } from './write_client_manifest.js';
4
+ import { write_matchers } from './write_matchers.js';
5
+ import { write_root } from './write_root.js';
6
+ import { write_tsconfig } from './write_tsconfig.js';
7
+ import { write_types, write_all_types } from './write_types/index.js';
8
+ import { write_ambient } from './write_ambient.js';
9
+
10
+ /**
11
+ * Initialize SvelteKit's generated files.
12
+ * @param {import('types').ValidatedConfig} config
13
+ * @param {string} mode
14
+ */
15
+ export function init(config, mode) {
16
+ write_tsconfig(config.kit);
17
+ write_ambient(config.kit, mode);
18
+ }
19
+
20
+ /**
21
+ * Update SvelteKit's generated files
22
+ * @param {import('types').ValidatedConfig} config
23
+ */
24
+ export async function create(config) {
25
+ const manifest_data = create_manifest_data({ config });
26
+
27
+ const output = path.join(config.kit.outDir, 'generated');
28
+
29
+ write_client_manifest(manifest_data, output);
30
+ write_root(manifest_data, output);
31
+ write_matchers(manifest_data, output);
32
+ await write_all_types(config, manifest_data);
33
+
34
+ return { manifest_data };
35
+ }
36
+
37
+ /**
38
+ * Update SvelteKit's generated files in response to a single file content update.
39
+ * Do not call this when the file in question was created/deleted.
40
+ *
41
+ * @param {import('types').ValidatedConfig} config
42
+ * @param {import('types').ManifestData} manifest_data
43
+ * @param {string} file
44
+ */
45
+ export async function update(config, manifest_data, file) {
46
+ await write_types(config, manifest_data, file);
47
+
48
+ return { manifest_data };
49
+ }
50
+
51
+ /**
52
+ * Run sync.init and sync.update in series, returning the result from sync.update.
53
+ * @param {import('types').ValidatedConfig} config
54
+ * @param {string} mode The Vite mode
55
+ */
56
+ export async function all(config, mode) {
57
+ init(config, mode);
58
+ return await create(config);
59
+ }
@@ -0,0 +1,33 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { mkdirp } from '../../utils/filesystem.js';
4
+
5
+ /** @type {Map<string, string>} */
6
+ const previous_contents = new Map();
7
+
8
+ /**
9
+ * @param {string} file
10
+ * @param {string} code
11
+ */
12
+ export function write_if_changed(file, code) {
13
+ if (code !== previous_contents.get(file)) {
14
+ write(file, code);
15
+ }
16
+ }
17
+
18
+ /**
19
+ * @param {string} file
20
+ * @param {string} code
21
+ */
22
+ export function write(file, code) {
23
+ previous_contents.set(file, code);
24
+ mkdirp(path.dirname(file));
25
+ fs.writeFileSync(file, code);
26
+ }
27
+
28
+ /** @param {string} str */
29
+ export function trim(str) {
30
+ const indentation = /** @type {RegExpExecArray} */ (/\n?(\s*)/.exec(str))[1];
31
+ const pattern = new RegExp(`^${indentation}`, 'gm');
32
+ return str.replace(pattern, '').trim();
33
+ }
@@ -0,0 +1,53 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { get_env } from '../../exports/vite/utils.js';
4
+ import { GENERATED_COMMENT } from '../../constants.js';
5
+ import { create_dynamic_types, create_static_types } from '../env.js';
6
+ import { write_if_changed } from './utils.js';
7
+ import { fileURLToPath } from 'url';
8
+
9
+ const descriptions_dir = fileURLToPath(new URL('../../../scripts/special-types', import.meta.url));
10
+
11
+ /** @param {string} filename */
12
+ function read_description(filename) {
13
+ const content = fs.readFileSync(`${descriptions_dir}/${filename}`, 'utf8');
14
+ return `/**\n${content
15
+ .trim()
16
+ .split('\n')
17
+ .map((line) => ` * ${line}`)
18
+ .join('\n')}\n */`;
19
+ }
20
+
21
+ /**
22
+ * @param {{ public: Record<string, string>, private: Record<string, string> }} env
23
+ */
24
+ const template = (env) => `
25
+ ${GENERATED_COMMENT}
26
+
27
+ /// <reference types="@sveltejs/kit" />
28
+
29
+ ${read_description('$env+static+private.md')}
30
+ ${create_static_types('$env/static/private', env.private)}
31
+
32
+ ${read_description('$env+static+public.md')}
33
+ ${create_static_types('$env/static/public', env.public)}
34
+
35
+ ${read_description('$env+dynamic+private.md')}
36
+ ${create_dynamic_types('$env/dynamic/private', env.private)}
37
+
38
+ ${read_description('$env+dynamic+public.md')}
39
+ ${create_dynamic_types('$env/dynamic/public', env.public)}
40
+ `;
41
+
42
+ /**
43
+ * Writes ambient declarations including types reference to @sveltejs/kit,
44
+ * and the existing environment variables in process.env to
45
+ * $env/static/private and $env/static/public
46
+ * @param {import('types').ValidatedKitConfig} config
47
+ * @param {string} mode The Vite mode
48
+ */
49
+ export function write_ambient(config, mode) {
50
+ const env = get_env(config.env, mode);
51
+
52
+ write_if_changed(path.join(config.outDir, 'ambient.d.ts'), template(env));
53
+ }