@sveltejs/kit 1.0.0-next.41 → 1.0.0-next.410

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 (129) hide show
  1. package/README.md +12 -9
  2. package/package.json +97 -63
  3. package/src/cli.js +119 -0
  4. package/src/core/adapt/builder.js +207 -0
  5. package/src/core/adapt/index.js +19 -0
  6. package/src/core/config/index.js +86 -0
  7. package/src/core/config/options.js +488 -0
  8. package/src/core/config/types.d.ts +1 -0
  9. package/src/core/constants.js +3 -0
  10. package/src/core/generate_manifest/index.js +99 -0
  11. package/src/core/prerender/crawl.js +194 -0
  12. package/src/core/prerender/prerender.js +378 -0
  13. package/src/core/prerender/queue.js +80 -0
  14. package/src/core/sync/create_manifest_data/index.js +492 -0
  15. package/src/core/sync/create_manifest_data/types.d.ts +40 -0
  16. package/src/core/sync/sync.js +59 -0
  17. package/src/core/sync/utils.js +97 -0
  18. package/src/core/sync/write_ambient.js +87 -0
  19. package/src/core/sync/write_client_manifest.js +82 -0
  20. package/src/core/sync/write_matchers.js +25 -0
  21. package/src/core/sync/write_root.js +88 -0
  22. package/src/core/sync/write_tsconfig.js +189 -0
  23. package/src/core/sync/write_types.js +723 -0
  24. package/src/core/utils.js +58 -0
  25. package/src/hooks.js +26 -0
  26. package/src/index/index.js +45 -0
  27. package/src/index/private.js +33 -0
  28. package/src/node/index.js +145 -0
  29. package/src/node/polyfills.js +40 -0
  30. package/src/packaging/index.js +218 -0
  31. package/src/packaging/types.d.ts +8 -0
  32. package/src/packaging/typescript.js +150 -0
  33. package/src/packaging/utils.js +143 -0
  34. package/src/runtime/app/env.js +11 -0
  35. package/src/runtime/app/navigation.js +22 -0
  36. package/src/runtime/app/paths.js +1 -0
  37. package/src/runtime/app/stores.js +94 -0
  38. package/src/runtime/client/ambient.d.ts +17 -0
  39. package/src/runtime/client/client.js +1269 -0
  40. package/src/runtime/client/fetcher.js +60 -0
  41. package/src/runtime/client/parse.js +36 -0
  42. package/src/runtime/client/singletons.js +11 -0
  43. package/src/runtime/client/start.js +48 -0
  44. package/src/runtime/client/types.d.ts +106 -0
  45. package/src/runtime/client/utils.js +113 -0
  46. package/src/runtime/components/error.svelte +16 -0
  47. package/{assets → src/runtime}/components/layout.svelte +0 -0
  48. package/src/runtime/env/dynamic/private.js +1 -0
  49. package/src/runtime/env/dynamic/public.js +1 -0
  50. package/src/runtime/env-private.js +7 -0
  51. package/src/runtime/env-public.js +7 -0
  52. package/src/runtime/env.js +6 -0
  53. package/src/runtime/hash.js +16 -0
  54. package/src/runtime/paths.js +11 -0
  55. package/src/runtime/server/endpoint.js +42 -0
  56. package/src/runtime/server/index.js +434 -0
  57. package/src/runtime/server/page/cookie.js +25 -0
  58. package/src/runtime/server/page/crypto.js +239 -0
  59. package/src/runtime/server/page/csp.js +249 -0
  60. package/src/runtime/server/page/fetch.js +265 -0
  61. package/src/runtime/server/page/index.js +418 -0
  62. package/src/runtime/server/page/load_data.js +94 -0
  63. package/src/runtime/server/page/render.js +357 -0
  64. package/src/runtime/server/page/respond_with_error.js +105 -0
  65. package/src/runtime/server/page/types.d.ts +44 -0
  66. package/src/runtime/server/utils.js +116 -0
  67. package/src/utils/error.js +22 -0
  68. package/src/utils/escape.js +104 -0
  69. package/src/utils/filesystem.js +108 -0
  70. package/src/utils/http.js +55 -0
  71. package/src/utils/misc.js +1 -0
  72. package/src/utils/routing.js +107 -0
  73. package/src/utils/url.js +97 -0
  74. package/src/vite/build/build_server.js +335 -0
  75. package/src/vite/build/build_service_worker.js +90 -0
  76. package/src/vite/build/utils.js +153 -0
  77. package/src/vite/dev/index.js +565 -0
  78. package/src/vite/index.js +540 -0
  79. package/src/vite/preview/index.js +186 -0
  80. package/src/vite/types.d.ts +3 -0
  81. package/src/vite/utils.js +335 -0
  82. package/svelte-kit.js +1 -1
  83. package/types/ambient.d.ts +368 -0
  84. package/types/index.d.ts +345 -0
  85. package/types/internal.d.ts +313 -0
  86. package/types/private.d.ts +236 -0
  87. package/CHANGELOG.md +0 -419
  88. package/assets/components/error.svelte +0 -13
  89. package/assets/runtime/app/env.js +0 -5
  90. package/assets/runtime/app/navigation.js +0 -41
  91. package/assets/runtime/app/paths.js +0 -1
  92. package/assets/runtime/app/stores.js +0 -93
  93. package/assets/runtime/chunks/utils.js +0 -19
  94. package/assets/runtime/internal/singletons.js +0 -23
  95. package/assets/runtime/internal/start.js +0 -770
  96. package/assets/runtime/paths.js +0 -12
  97. package/dist/api.js +0 -28
  98. package/dist/api.js.map +0 -1
  99. package/dist/chunks/index.js +0 -3519
  100. package/dist/chunks/index2.js +0 -587
  101. package/dist/chunks/index3.js +0 -246
  102. package/dist/chunks/index4.js +0 -524
  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/cli.js.map +0 -1
  109. package/dist/create_app.js +0 -592
  110. package/dist/create_app.js.map +0 -1
  111. package/dist/index.js +0 -392
  112. package/dist/index.js.map +0 -1
  113. package/dist/index2.js +0 -3519
  114. package/dist/index2.js.map +0 -1
  115. package/dist/index3.js +0 -320
  116. package/dist/index3.js.map +0 -1
  117. package/dist/index4.js +0 -323
  118. package/dist/index4.js.map +0 -1
  119. package/dist/index5.js +0 -247
  120. package/dist/index5.js.map +0 -1
  121. package/dist/index6.js +0 -761
  122. package/dist/index6.js.map +0 -1
  123. package/dist/renderer.js +0 -2499
  124. package/dist/renderer.js.map +0 -1
  125. package/dist/ssr.js +0 -2581
  126. package/dist/standard.js +0 -100
  127. package/dist/standard.js.map +0 -1
  128. package/dist/utils.js +0 -84
  129. package/dist/utils.js.map +0 -1
@@ -0,0 +1,492 @@
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 } from '../../../utils/routing.js';
7
+
8
+ const DEFAULT = 'default';
9
+
10
+ /**
11
+ * @param {{
12
+ * config: import('types').ValidatedConfig;
13
+ * fallback?: string;
14
+ * cwd?: string;
15
+ * }} opts
16
+ * @returns {import('types').ManifestData}
17
+ */
18
+ export default function create_manifest_data({
19
+ config,
20
+ fallback = `${runtime_directory}/components`,
21
+ cwd = process.cwd()
22
+ }) {
23
+ /** @type {Map<string, import('types').RouteData>} */
24
+ const route_map = new Map();
25
+
26
+ /** @type {Map<string, import('./types').Part[][]>} */
27
+ const segment_map = new Map();
28
+
29
+ /** @type {import('./types').RouteTree} */
30
+ const tree = new Map();
31
+
32
+ const default_layout = {
33
+ component: posixify(path.relative(cwd, `${fallback}/layout.svelte`))
34
+ };
35
+
36
+ // set default root layout/error
37
+ tree.set('', {
38
+ error: {
39
+ component: posixify(path.relative(cwd, `${fallback}/error.svelte`))
40
+ },
41
+ layouts: { [DEFAULT]: default_layout }
42
+ });
43
+
44
+ /** @param {string} id */
45
+ function tree_node(id) {
46
+ if (!tree.has(id)) {
47
+ tree.set(id, {
48
+ error: undefined,
49
+ layouts: {}
50
+ });
51
+ }
52
+
53
+ return /** @type {import('./types').RouteTreeNode} */ (tree.get(id));
54
+ }
55
+
56
+ const routes_base = posixify(path.relative(cwd, config.kit.files.routes));
57
+ const valid_extensions = [...config.extensions, ...config.kit.moduleExtensions];
58
+
59
+ if (fs.existsSync(config.kit.files.routes)) {
60
+ list_files(config.kit.files.routes).forEach((filepath) => {
61
+ const extension = valid_extensions.find((ext) => filepath.endsWith(ext));
62
+ if (!extension) return;
63
+
64
+ const project_relative = `${routes_base}/${filepath}`;
65
+ const segments = filepath.split('/');
66
+ const file = /** @type {string} */ (segments.pop());
67
+
68
+ if (file[0] !== '+') return; // not a route file
69
+
70
+ const item = analyze(file, config.extensions, config.kit.moduleExtensions);
71
+
72
+ if (!item) {
73
+ throw new Error(
74
+ `Files and directories prefixed with + are reserved (saw ${project_relative})`
75
+ );
76
+ }
77
+
78
+ const id = segments.join('/');
79
+
80
+ if (/\]\[/.test(id)) {
81
+ throw new Error(`Invalid route ${project_relative} — parameters must be separated`);
82
+ }
83
+
84
+ if (count_occurrences('[', id) !== count_occurrences(']', id)) {
85
+ throw new Error(`Invalid route ${project_relative} — brackets are unbalanced`);
86
+ }
87
+
88
+ // error/layout files should be added to the tree, but don't result
89
+ // in a route being created, so deal with them first. note: we are
90
+ // relying on the fact that the +error and +layout files precede
91
+ // +page files alphabetically, and will therefore be processes
92
+ // before we reach the page
93
+ if (item.kind === 'component' && item.is_error) {
94
+ tree_node(id).error = {
95
+ component: project_relative
96
+ };
97
+
98
+ return;
99
+ }
100
+
101
+ if (item.is_layout) {
102
+ if (item.declares_layout === DEFAULT) {
103
+ throw new Error(`${project_relative} cannot use reserved "${DEFAULT}" name`);
104
+ }
105
+
106
+ const layout_id = item.declares_layout || DEFAULT;
107
+
108
+ const group = tree_node(id);
109
+
110
+ const defined = group.layouts[layout_id] || (group.layouts[layout_id] = {});
111
+
112
+ if (defined[item.kind] && layout_id !== DEFAULT) {
113
+ // edge case
114
+ throw new Error(
115
+ `Duplicate layout ${project_relative} already defined at ${defined[item.kind]}`
116
+ );
117
+ }
118
+
119
+ defined[item.kind] = project_relative;
120
+
121
+ return;
122
+ }
123
+
124
+ const type = item.kind === 'server' && !item.is_layout && !item.is_page ? 'endpoint' : 'page';
125
+
126
+ if (type === 'endpoint' && route_map.has(id)) {
127
+ // note that we are relying on +server being lexically ordered after
128
+ // all other route files — if we added +view or something this is
129
+ // potentially brittle, since the server might be added before
130
+ // another route file. a problem for another day
131
+ throw new Error(
132
+ `${file} cannot share a directory with other route files (${project_relative})`
133
+ );
134
+ }
135
+
136
+ if (!route_map.has(id)) {
137
+ const pattern = parse_route_id(id).pattern;
138
+
139
+ segment_map.set(
140
+ id,
141
+ segments.filter(Boolean).map((segment) => {
142
+ /** @type {import('./types').Part[]} */
143
+ const parts = [];
144
+ segment.split(/\[(.+?)\]/).map((content, i) => {
145
+ const dynamic = !!(i % 2);
146
+
147
+ if (!content) return;
148
+
149
+ parts.push({
150
+ content,
151
+ dynamic,
152
+ rest: dynamic && content.startsWith('...'),
153
+ type: (dynamic && content.split('=')[1]) || null
154
+ });
155
+ });
156
+ return parts;
157
+ })
158
+ );
159
+
160
+ if (type === 'endpoint') {
161
+ route_map.set(id, {
162
+ type,
163
+ id,
164
+ pattern,
165
+ file: project_relative
166
+ });
167
+ } else {
168
+ route_map.set(id, {
169
+ type,
170
+ id,
171
+ pattern,
172
+ errors: [],
173
+ layouts: [],
174
+ leaf: {}
175
+ });
176
+ }
177
+ }
178
+
179
+ if (item.is_page) {
180
+ const route = /** @type {import('types').PageData} */ (route_map.get(id));
181
+
182
+ if (item.kind === 'component') {
183
+ route.leaf.component = project_relative;
184
+
185
+ const { layouts, errors } = trace(tree, id, item.uses_layout, project_relative);
186
+ route.layouts = layouts;
187
+ route.errors = errors;
188
+ } else if (item.kind === 'server') {
189
+ route.leaf.server = project_relative;
190
+ } else {
191
+ route.leaf.shared = project_relative;
192
+ }
193
+ }
194
+ });
195
+
196
+ // TODO remove for 1.0
197
+ if (route_map.size === 0) {
198
+ throw new Error(
199
+ 'The filesystem router API has changed, see https://github.com/sveltejs/kit/discussions/5774 for details'
200
+ );
201
+ }
202
+ }
203
+
204
+ /** @type {import('types').PageNode[]} */
205
+ const nodes = [];
206
+
207
+ tree.forEach(({ layouts, error }) => {
208
+ // we do [default, error, ...other_layouts] so that components[0] and [1]
209
+ // are the root layout/error. kinda janky, there's probably a nicer way
210
+ if (layouts[DEFAULT]) {
211
+ nodes.push(layouts[DEFAULT]);
212
+ }
213
+
214
+ if (error) {
215
+ nodes.push(error);
216
+ }
217
+
218
+ for (const id in layouts) {
219
+ if (id !== DEFAULT) {
220
+ nodes.push(layouts[id]);
221
+ }
222
+ }
223
+ });
224
+
225
+ route_map.forEach((route) => {
226
+ if (route.type === 'page') {
227
+ nodes.push(route.leaf);
228
+ }
229
+ });
230
+
231
+ const routes = Array.from(route_map.values()).sort((a, b) => compare(a, b, segment_map));
232
+
233
+ /** @type {import('types').Asset[]} */
234
+ const assets = fs.existsSync(config.kit.files.assets)
235
+ ? list_files(config.kit.files.assets).map((file) => ({
236
+ file,
237
+ size: fs.statSync(`${config.kit.files.assets}/${file}`).size,
238
+ type: mime.getType(file)
239
+ }))
240
+ : [];
241
+
242
+ const params_base = path.relative(cwd, config.kit.files.params);
243
+
244
+ /** @type {Record<string, string>} */
245
+ const matchers = {};
246
+ if (fs.existsSync(config.kit.files.params)) {
247
+ for (const file of fs.readdirSync(config.kit.files.params)) {
248
+ const ext = path.extname(file);
249
+ if (!config.kit.moduleExtensions.includes(ext)) continue;
250
+ const type = file.slice(0, -ext.length);
251
+
252
+ if (/^\w+$/.test(type)) {
253
+ const matcher_file = path.join(params_base, file);
254
+
255
+ // Disallow same matcher with different extensions
256
+ if (matchers[type]) {
257
+ throw new Error(`Duplicate matchers: ${matcher_file} and ${matchers[type]}`);
258
+ } else {
259
+ matchers[type] = matcher_file;
260
+ }
261
+ } else {
262
+ throw new Error(
263
+ `Matcher names can only have underscores and alphanumeric characters — "${file}" is invalid`
264
+ );
265
+ }
266
+ }
267
+ }
268
+
269
+ return {
270
+ assets,
271
+ nodes,
272
+ routes,
273
+ matchers
274
+ };
275
+ }
276
+
277
+ /**
278
+ * @param {string} file
279
+ * @param {string[]} component_extensions
280
+ * @param {string[]} module_extensions
281
+ * @returns {import('./types').RouteFile | null}
282
+ */
283
+ function analyze(file, component_extensions, module_extensions) {
284
+ const component_extension = component_extensions.find((ext) => file.endsWith(ext));
285
+ if (component_extension) {
286
+ const name = file.slice(0, -component_extension.length);
287
+ const pattern =
288
+ /^\+(?:(page(?:@([a-zA-Z0-9_-]+))?)|(layout(?:-([a-zA-Z0-9_-]+))?(?:@([a-zA-Z0-9_-]+))?)|(error))$/;
289
+ const match = pattern.exec(name);
290
+ if (!match) return null;
291
+
292
+ return {
293
+ kind: 'component',
294
+ is_page: !!match[1],
295
+ is_layout: !!match[3],
296
+ is_error: !!match[6],
297
+ uses_layout: match[2] || match[5],
298
+ declares_layout: match[4]
299
+ };
300
+ }
301
+
302
+ const module_extension = module_extensions.find((ext) => file.endsWith(ext));
303
+ if (module_extension) {
304
+ const name = file.slice(0, -module_extension.length);
305
+ const pattern = /^\+(?:(server)|(page(\.server)?)|(layout(?:-([a-zA-Z0-9_-]+))?(\.server)?))$/;
306
+ const match = pattern.exec(name);
307
+ if (!match) return null;
308
+
309
+ const kind = !!(match[1] || match[3] || match[6]) ? 'server' : 'shared';
310
+
311
+ return {
312
+ kind,
313
+ is_page: !!match[2],
314
+ is_layout: !!match[4],
315
+ declares_layout: match[5]
316
+ };
317
+ }
318
+
319
+ return null;
320
+ }
321
+
322
+ /**
323
+ * @param {import('./types').RouteTree} tree
324
+ * @param {string} id
325
+ * @param {string} layout_id
326
+ * @param {string} project_relative
327
+ */
328
+ function trace(tree, id, layout_id = DEFAULT, project_relative) {
329
+ /** @type {Array<import('types').PageNode | undefined>} */
330
+ const layouts = [];
331
+
332
+ /** @type {Array<import('types').PageNode | undefined>} */
333
+ const errors = [];
334
+
335
+ const parts = id.split('/').filter(Boolean);
336
+
337
+ // walk up the tree, find which +layout and +error components
338
+ // apply to this page
339
+ while (true) {
340
+ const node = tree.get(parts.join('/'));
341
+ const layout = node?.layouts[layout_id];
342
+
343
+ if (layout && layouts.indexOf(layout) > -1) {
344
+ // TODO this needs to be fixed for #5748
345
+ throw new Error(
346
+ `Recursive layout detected: ${layout.component} -> ${layouts
347
+ .map((l) => l?.component)
348
+ .join(' -> ')}`
349
+ );
350
+ }
351
+
352
+ // any segment that has neither a +layout nor an +error can be discarded.
353
+ // in other words these...
354
+ // layouts: [a, , b, c]
355
+ // errors: [d, , e, ]
356
+ //
357
+ // ...can be compacted to these:
358
+ // layouts: [a, b, c]
359
+ // errors: [d, e, ]
360
+ if (node?.error || layout) {
361
+ errors.unshift(node?.error);
362
+ layouts.unshift(layout);
363
+ }
364
+
365
+ const parent_layout_id = layout?.component?.split('/').at(-1)?.split('@')[1]?.split('.')[0];
366
+
367
+ if (parent_layout_id) {
368
+ layout_id = parent_layout_id;
369
+ } else {
370
+ if (layout) layout_id = DEFAULT;
371
+ if (parts.length === 0) break;
372
+ parts.pop();
373
+ }
374
+ }
375
+
376
+ if (layout_id !== DEFAULT) {
377
+ throw new Error(`${project_relative} references missing layout "${layout_id}"`);
378
+ }
379
+
380
+ // trim empty space off the end of the errors array
381
+ let i = errors.length;
382
+ while (i--) if (errors[i]) break;
383
+ errors.length = i + 1;
384
+
385
+ return { layouts, errors };
386
+ }
387
+
388
+ /**
389
+ * @param {import('types').RouteData} a
390
+ * @param {import('types').RouteData} b
391
+ * @param {Map<string, import('./types').Part[][]>} segment_map
392
+ */
393
+ function compare(a, b, segment_map) {
394
+ const a_segments = /** @type {import('./types').Part[][]} */ (segment_map.get(a.id));
395
+ const b_segments = /** @type {import('./types').Part[][]} */ (segment_map.get(b.id));
396
+
397
+ const max_segments = Math.max(a_segments.length, b_segments.length);
398
+ for (let i = 0; i < max_segments; i += 1) {
399
+ const sa = a_segments[i];
400
+ const sb = b_segments[i];
401
+
402
+ // /x < /x/y, but /[...x]/y < /[...x]
403
+ if (!sa) return a.id.includes('[...') ? +1 : -1;
404
+ if (!sb) return b.id.includes('[...') ? -1 : +1;
405
+
406
+ const max_parts = Math.max(sa.length, sb.length);
407
+ for (let i = 0; i < max_parts; i += 1) {
408
+ const pa = sa[i];
409
+ const pb = sb[i];
410
+
411
+ // xy < x[y], but [x].json < [x]
412
+ if (pa === undefined) return pb.dynamic ? -1 : +1;
413
+ if (pb === undefined) return pa.dynamic ? +1 : -1;
414
+
415
+ // x < [x]
416
+ if (pa.dynamic !== pb.dynamic) {
417
+ return pa.dynamic ? +1 : -1;
418
+ }
419
+
420
+ if (pa.dynamic) {
421
+ // [x] < [...x]
422
+ if (pa.rest !== pb.rest) {
423
+ return pa.rest ? +1 : -1;
424
+ }
425
+
426
+ // [x=type] < [x]
427
+ if (!!pa.type !== !!pb.type) {
428
+ return pa.type ? -1 : +1;
429
+ }
430
+ }
431
+ }
432
+ }
433
+
434
+ const a_is_endpoint = a.type === 'endpoint';
435
+ const b_is_endpoint = b.type === 'endpoint';
436
+
437
+ if (a_is_endpoint !== b_is_endpoint) {
438
+ return a_is_endpoint ? -1 : +1;
439
+ }
440
+
441
+ return a < b ? -1 : 1;
442
+ }
443
+
444
+ /**
445
+ * @param {string} needle
446
+ * @param {string} haystack
447
+ */
448
+ function count_occurrences(needle, haystack) {
449
+ let count = 0;
450
+ for (let i = 0; i < haystack.length; i += 1) {
451
+ if (haystack[i] === needle) count += 1;
452
+ }
453
+ return count;
454
+ }
455
+
456
+ /**
457
+ * @param {string} dir
458
+ * @param {string} [path]
459
+ * @param {string[]} [files]
460
+ */
461
+ function list_files(dir, path = '', files = []) {
462
+ fs.readdirSync(dir)
463
+ .sort((a, b) => {
464
+ // sort each directory in (+layout, +error, everything else) order
465
+ // so that we can trace layouts/errors immediately
466
+
467
+ if (a.startsWith('+layout')) {
468
+ if (!b.startsWith('+layout')) return -1;
469
+ } else if (b.startsWith('+layout')) {
470
+ return 1;
471
+ } else if (a.startsWith('__')) {
472
+ if (!b.startsWith('__')) return -1;
473
+ } else if (b.startsWith('__')) {
474
+ return 1;
475
+ }
476
+
477
+ return a < b ? -1 : 1;
478
+ })
479
+ .forEach((file) => {
480
+ const full = `${dir}/${file}`;
481
+ const stats = fs.statSync(full);
482
+ const joined = path ? `${path}/${file}` : file;
483
+
484
+ if (stats.isDirectory()) {
485
+ list_files(full, joined, files);
486
+ } else {
487
+ files.push(joined);
488
+ }
489
+ });
490
+
491
+ return files;
492
+ }
@@ -0,0 +1,40 @@
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
+ layouts: Record<string, PageNode>;
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
+ declares_layout: string | undefined;
24
+ }
25
+
26
+ interface RouteSharedModule {
27
+ kind: 'shared';
28
+ is_page: boolean;
29
+ is_layout: boolean;
30
+ declares_layout: string | undefined;
31
+ }
32
+
33
+ interface RouteServerModule {
34
+ kind: 'server';
35
+ is_page: boolean;
36
+ is_layout: boolean;
37
+ declares_layout: string | undefined;
38
+ }
39
+
40
+ 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_type, write_types } from './write_types.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_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_type(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,97 @@
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
+ /**
29
+ * @param {(file: string) => boolean} should_remove
30
+ */
31
+ export function remove_from_previous(should_remove) {
32
+ for (const key of previous_contents.keys()) {
33
+ if (should_remove(key)) {
34
+ previous_contents.delete(key);
35
+ }
36
+ }
37
+ }
38
+
39
+ /** @param {string} str */
40
+ export function trim(str) {
41
+ const indentation = /** @type {RegExpExecArray} */ (/\n?(\s*)/.exec(str))[1];
42
+ const pattern = new RegExp(`^${indentation}`, 'gm');
43
+ return str.replace(pattern, '').trim();
44
+ }
45
+
46
+ export const reserved = new Set([
47
+ 'do',
48
+ 'if',
49
+ 'in',
50
+ 'for',
51
+ 'let',
52
+ 'new',
53
+ 'try',
54
+ 'var',
55
+ 'case',
56
+ 'else',
57
+ 'enum',
58
+ 'eval',
59
+ 'null',
60
+ 'this',
61
+ 'true',
62
+ 'void',
63
+ 'with',
64
+ 'await',
65
+ 'break',
66
+ 'catch',
67
+ 'class',
68
+ 'const',
69
+ 'false',
70
+ 'super',
71
+ 'throw',
72
+ 'while',
73
+ 'yield',
74
+ 'delete',
75
+ 'export',
76
+ 'import',
77
+ 'public',
78
+ 'return',
79
+ 'static',
80
+ 'switch',
81
+ 'typeof',
82
+ 'default',
83
+ 'extends',
84
+ 'finally',
85
+ 'package',
86
+ 'private',
87
+ 'continue',
88
+ 'debugger',
89
+ 'function',
90
+ 'arguments',
91
+ 'interface',
92
+ 'protected',
93
+ 'implements',
94
+ 'instanceof'
95
+ ]);
96
+
97
+ export const valid_identifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;