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

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 +496 -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 +727 -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 +1281 -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 +266 -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 +363 -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 +339 -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 +569 -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 +309 -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,496 @@
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(project_relative, file, config.extensions, config.kit.moduleExtensions);
71
+ const id = segments.join('/');
72
+
73
+ if (/\]\[/.test(id)) {
74
+ throw new Error(`Invalid route ${project_relative} — parameters must be separated`);
75
+ }
76
+
77
+ if (count_occurrences('[', id) !== count_occurrences(']', id)) {
78
+ throw new Error(`Invalid route ${project_relative} — brackets are unbalanced`);
79
+ }
80
+
81
+ // error/layout files should be added to the tree, but don't result
82
+ // in a route being created, so deal with them first. note: we are
83
+ // relying on the fact that the +error and +layout files precede
84
+ // +page files alphabetically, and will therefore be processes
85
+ // before we reach the page
86
+ if (item.kind === 'component' && item.is_error) {
87
+ tree_node(id).error = {
88
+ component: project_relative
89
+ };
90
+
91
+ return;
92
+ }
93
+
94
+ if (item.is_layout) {
95
+ if (item.declares_layout === DEFAULT) {
96
+ throw new Error(`${project_relative} cannot use reserved "${DEFAULT}" name`);
97
+ }
98
+
99
+ const layout_id = item.declares_layout || DEFAULT;
100
+
101
+ const group = tree_node(id);
102
+
103
+ const defined = group.layouts[layout_id] || (group.layouts[layout_id] = {});
104
+
105
+ if (defined[item.kind] && layout_id !== DEFAULT) {
106
+ // edge case
107
+ throw new Error(
108
+ `Duplicate layout ${project_relative} already defined at ${defined[item.kind]}`
109
+ );
110
+ }
111
+
112
+ defined[item.kind] = project_relative;
113
+
114
+ return;
115
+ }
116
+
117
+ const type = item.kind === 'server' && !item.is_layout && !item.is_page ? 'endpoint' : 'page';
118
+
119
+ if (type === 'endpoint' && route_map.has(id)) {
120
+ // note that we are relying on +server being lexically ordered after
121
+ // all other route files — if we added +view or something this is
122
+ // potentially brittle, since the server might be added before
123
+ // another route file. a problem for another day
124
+ throw new Error(
125
+ `${file} cannot share a directory with other route files (${project_relative})`
126
+ );
127
+ }
128
+
129
+ if (!route_map.has(id)) {
130
+ const pattern = parse_route_id(id).pattern;
131
+
132
+ segment_map.set(
133
+ id,
134
+ segments.filter(Boolean).map((segment) => {
135
+ /** @type {import('./types').Part[]} */
136
+ const parts = [];
137
+ segment.split(/\[(.+?)\]/).map((content, i) => {
138
+ const dynamic = !!(i % 2);
139
+
140
+ if (!content) return;
141
+
142
+ parts.push({
143
+ content,
144
+ dynamic,
145
+ rest: dynamic && content.startsWith('...'),
146
+ type: (dynamic && content.split('=')[1]) || null
147
+ });
148
+ });
149
+ return parts;
150
+ })
151
+ );
152
+
153
+ if (type === 'endpoint') {
154
+ route_map.set(id, {
155
+ type,
156
+ id,
157
+ pattern,
158
+ file: project_relative
159
+ });
160
+ } else {
161
+ route_map.set(id, {
162
+ type,
163
+ id,
164
+ pattern,
165
+ errors: [],
166
+ layouts: [],
167
+ leaf: {}
168
+ });
169
+ }
170
+ }
171
+
172
+ if (item.is_page) {
173
+ const route = /** @type {import('types').PageData} */ (route_map.get(id));
174
+
175
+ if (item.kind === 'component') {
176
+ route.leaf.component = project_relative;
177
+
178
+ const { layouts, errors } = trace(tree, id, item.uses_layout, project_relative);
179
+ route.layouts = layouts;
180
+ route.errors = errors;
181
+ } else if (item.kind === 'server') {
182
+ route.leaf.server = project_relative;
183
+ } else {
184
+ route.leaf.shared = project_relative;
185
+ }
186
+ }
187
+ });
188
+
189
+ // TODO remove for 1.0
190
+ if (route_map.size === 0) {
191
+ throw new Error(
192
+ 'The filesystem router API has changed, see https://github.com/sveltejs/kit/discussions/5774 for details'
193
+ );
194
+ }
195
+ }
196
+
197
+ /** @type {import('types').PageNode[]} */
198
+ const nodes = [];
199
+
200
+ tree.forEach(({ layouts, error }) => {
201
+ // we do [default, error, ...other_layouts] so that components[0] and [1]
202
+ // are the root layout/error. kinda janky, there's probably a nicer way
203
+ if (layouts[DEFAULT]) {
204
+ nodes.push(layouts[DEFAULT]);
205
+ }
206
+
207
+ if (error) {
208
+ nodes.push(error);
209
+ }
210
+
211
+ for (const id in layouts) {
212
+ if (id !== DEFAULT) {
213
+ nodes.push(layouts[id]);
214
+ }
215
+ }
216
+ });
217
+
218
+ route_map.forEach((route) => {
219
+ if (route.type === 'page') {
220
+ nodes.push(route.leaf);
221
+ }
222
+ });
223
+
224
+ const routes = Array.from(route_map.values()).sort((a, b) => compare(a, b, segment_map));
225
+
226
+ /** @type {import('types').Asset[]} */
227
+ const assets = fs.existsSync(config.kit.files.assets)
228
+ ? list_files(config.kit.files.assets).map((file) => ({
229
+ file,
230
+ size: fs.statSync(`${config.kit.files.assets}/${file}`).size,
231
+ type: mime.getType(file)
232
+ }))
233
+ : [];
234
+
235
+ const params_base = path.relative(cwd, config.kit.files.params);
236
+
237
+ /** @type {Record<string, string>} */
238
+ const matchers = {};
239
+ if (fs.existsSync(config.kit.files.params)) {
240
+ for (const file of fs.readdirSync(config.kit.files.params)) {
241
+ const ext = path.extname(file);
242
+ if (!config.kit.moduleExtensions.includes(ext)) continue;
243
+ const type = file.slice(0, -ext.length);
244
+
245
+ if (/^\w+$/.test(type)) {
246
+ const matcher_file = path.join(params_base, file);
247
+
248
+ // Disallow same matcher with different extensions
249
+ if (matchers[type]) {
250
+ throw new Error(`Duplicate matchers: ${matcher_file} and ${matchers[type]}`);
251
+ } else {
252
+ matchers[type] = matcher_file;
253
+ }
254
+ } else {
255
+ throw new Error(
256
+ `Matcher names can only have underscores and alphanumeric characters — "${file}" is invalid`
257
+ );
258
+ }
259
+ }
260
+ }
261
+
262
+ return {
263
+ assets,
264
+ nodes,
265
+ routes,
266
+ matchers
267
+ };
268
+ }
269
+
270
+ /**
271
+ * @param {string} project_relative
272
+ * @param {string} file
273
+ * @param {string[]} component_extensions
274
+ * @param {string[]} module_extensions
275
+ * @returns {import('./types').RouteFile}
276
+ */
277
+ function analyze(project_relative, file, component_extensions, module_extensions) {
278
+ const component_extension = component_extensions.find((ext) => file.endsWith(ext));
279
+ if (component_extension) {
280
+ const name = file.slice(0, -component_extension.length);
281
+ const pattern =
282
+ /^\+(?:(page(?:@([a-zA-Z0-9_-]+))?)|(layout(?:-([a-zA-Z0-9_-]+))?(?:@([a-zA-Z0-9_-]+))?)|(error))$/;
283
+ const match = pattern.exec(name);
284
+ if (!match) {
285
+ throw new Error(`Files prefixed with + are reserved (saw ${project_relative})`);
286
+ }
287
+
288
+ return {
289
+ kind: 'component',
290
+ is_page: !!match[1],
291
+ is_layout: !!match[3],
292
+ is_error: !!match[6],
293
+ uses_layout: match[2] || match[5],
294
+ declares_layout: match[4]
295
+ };
296
+ }
297
+
298
+ const module_extension = module_extensions.find((ext) => file.endsWith(ext));
299
+ if (module_extension) {
300
+ const name = file.slice(0, -module_extension.length);
301
+ const pattern =
302
+ /^\+(?:(server)|(page(?:@([a-zA-Z0-9_-]+))?(\.server)?)|(layout(?:-([a-zA-Z0-9_-]+))?(?:@([a-zA-Z0-9_-]+))?(\.server)?))$/;
303
+ const match = pattern.exec(name);
304
+ if (!match) {
305
+ throw new Error(`Files prefixed with + are reserved (saw ${project_relative})`);
306
+ } else if (match[3] || match[7]) {
307
+ throw new Error(
308
+ // prettier-ignore
309
+ `Only Svelte files can reference named layouts. Remove '@${match[3] || match[7]}' from ${file} (at ${project_relative})`
310
+ );
311
+ }
312
+
313
+ const kind = !!(match[1] || match[4] || match[8]) ? 'server' : 'shared';
314
+
315
+ return {
316
+ kind,
317
+ is_page: !!match[2],
318
+ is_layout: !!match[5],
319
+ declares_layout: match[6]
320
+ };
321
+ }
322
+
323
+ throw new Error(`Files and directories prefixed with + are reserved (saw ${project_relative})`);
324
+ }
325
+
326
+ /**
327
+ * @param {import('./types').RouteTree} tree
328
+ * @param {string} id
329
+ * @param {string} layout_id
330
+ * @param {string} project_relative
331
+ */
332
+ function trace(tree, id, layout_id = DEFAULT, project_relative) {
333
+ /** @type {Array<import('types').PageNode | undefined>} */
334
+ const layouts = [];
335
+
336
+ /** @type {Array<import('types').PageNode | undefined>} */
337
+ const errors = [];
338
+
339
+ const parts = id.split('/').filter(Boolean);
340
+
341
+ // walk up the tree, find which +layout and +error components
342
+ // apply to this page
343
+ while (true) {
344
+ const node = tree.get(parts.join('/'));
345
+ const layout = node?.layouts[layout_id];
346
+
347
+ if (layout && layouts.indexOf(layout) > -1) {
348
+ // TODO this needs to be fixed for #5748
349
+ throw new Error(
350
+ `Recursive layout detected: ${layout.component} -> ${layouts
351
+ .map((l) => l?.component)
352
+ .join(' -> ')}`
353
+ );
354
+ }
355
+
356
+ // any segment that has neither a +layout nor an +error can be discarded.
357
+ // in other words these...
358
+ // layouts: [a, , b, c]
359
+ // errors: [d, , e, ]
360
+ //
361
+ // ...can be compacted to these:
362
+ // layouts: [a, b, c]
363
+ // errors: [d, e, ]
364
+ if (node?.error || layout) {
365
+ errors.unshift(node?.error);
366
+ layouts.unshift(layout);
367
+ }
368
+
369
+ const parent_layout_id = layout?.component?.split('/').at(-1)?.split('@')[1]?.split('.')[0];
370
+
371
+ if (parent_layout_id) {
372
+ layout_id = parent_layout_id;
373
+ } else {
374
+ if (layout) layout_id = DEFAULT;
375
+ if (parts.length === 0) break;
376
+ parts.pop();
377
+ }
378
+ }
379
+
380
+ if (layout_id !== DEFAULT) {
381
+ throw new Error(`${project_relative} references missing layout "${layout_id}"`);
382
+ }
383
+
384
+ // trim empty space off the end of the errors array
385
+ let i = errors.length;
386
+ while (i--) if (errors[i]) break;
387
+ errors.length = i + 1;
388
+
389
+ return { layouts, errors };
390
+ }
391
+
392
+ /**
393
+ * @param {import('types').RouteData} a
394
+ * @param {import('types').RouteData} b
395
+ * @param {Map<string, import('./types').Part[][]>} segment_map
396
+ */
397
+ function compare(a, b, segment_map) {
398
+ const a_segments = /** @type {import('./types').Part[][]} */ (segment_map.get(a.id));
399
+ const b_segments = /** @type {import('./types').Part[][]} */ (segment_map.get(b.id));
400
+
401
+ const max_segments = Math.max(a_segments.length, b_segments.length);
402
+ for (let i = 0; i < max_segments; i += 1) {
403
+ const sa = a_segments[i];
404
+ const sb = b_segments[i];
405
+
406
+ // /x < /x/y, but /[...x]/y < /[...x]
407
+ if (!sa) return a.id.includes('[...') ? +1 : -1;
408
+ if (!sb) return b.id.includes('[...') ? -1 : +1;
409
+
410
+ const max_parts = Math.max(sa.length, sb.length);
411
+ for (let i = 0; i < max_parts; i += 1) {
412
+ const pa = sa[i];
413
+ const pb = sb[i];
414
+
415
+ // xy < x[y], but [x].json < [x]
416
+ if (pa === undefined) return pb.dynamic ? -1 : +1;
417
+ if (pb === undefined) return pa.dynamic ? +1 : -1;
418
+
419
+ // x < [x]
420
+ if (pa.dynamic !== pb.dynamic) {
421
+ return pa.dynamic ? +1 : -1;
422
+ }
423
+
424
+ if (pa.dynamic) {
425
+ // [x] < [...x]
426
+ if (pa.rest !== pb.rest) {
427
+ return pa.rest ? +1 : -1;
428
+ }
429
+
430
+ // [x=type] < [x]
431
+ if (!!pa.type !== !!pb.type) {
432
+ return pa.type ? -1 : +1;
433
+ }
434
+ }
435
+ }
436
+ }
437
+
438
+ const a_is_endpoint = a.type === 'endpoint';
439
+ const b_is_endpoint = b.type === 'endpoint';
440
+
441
+ if (a_is_endpoint !== b_is_endpoint) {
442
+ return a_is_endpoint ? -1 : +1;
443
+ }
444
+
445
+ return a < b ? -1 : 1;
446
+ }
447
+
448
+ /**
449
+ * @param {string} needle
450
+ * @param {string} haystack
451
+ */
452
+ function count_occurrences(needle, haystack) {
453
+ let count = 0;
454
+ for (let i = 0; i < haystack.length; i += 1) {
455
+ if (haystack[i] === needle) count += 1;
456
+ }
457
+ return count;
458
+ }
459
+
460
+ /**
461
+ * @param {string} dir
462
+ * @param {string} [path]
463
+ * @param {string[]} [files]
464
+ */
465
+ function list_files(dir, path = '', files = []) {
466
+ fs.readdirSync(dir)
467
+ .sort((a, b) => {
468
+ // sort each directory in (+layout, +error, everything else) order
469
+ // so that we can trace layouts/errors immediately
470
+
471
+ if (a.startsWith('+layout')) {
472
+ if (!b.startsWith('+layout')) return -1;
473
+ } else if (b.startsWith('+layout')) {
474
+ return 1;
475
+ } else if (a.startsWith('__')) {
476
+ if (!b.startsWith('__')) return -1;
477
+ } else if (b.startsWith('__')) {
478
+ return 1;
479
+ }
480
+
481
+ return a < b ? -1 : 1;
482
+ })
483
+ .forEach((file) => {
484
+ const full = `${dir}/${file}`;
485
+ const stats = fs.statSync(full);
486
+ const joined = path ? `${path}/${file}` : file;
487
+
488
+ if (stats.isDirectory()) {
489
+ list_files(full, joined, files);
490
+ } else {
491
+ files.push(joined);
492
+ }
493
+ });
494
+
495
+ return files;
496
+ }
@@ -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_$]*$/;