@sveltejs/kit 1.0.0-next.50 → 1.0.0-next.500

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