@sveltejs/kit 1.0.0-next.42 → 1.0.0-next.422

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 (126) hide show
  1. package/README.md +12 -9
  2. package/package.json +95 -63
  3. package/src/cli.js +112 -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 +482 -0
  8. package/src/core/config/types.d.ts +1 -0
  9. package/src/core/constants.js +5 -0
  10. package/src/core/env.js +91 -0
  11. package/src/core/generate_manifest/index.js +99 -0
  12. package/src/core/prerender/crawl.js +194 -0
  13. package/src/core/prerender/prerender.js +378 -0
  14. package/src/core/prerender/queue.js +80 -0
  15. package/src/core/sync/create_manifest_data/index.js +506 -0
  16. package/src/core/sync/create_manifest_data/types.d.ts +40 -0
  17. package/src/core/sync/sync.js +59 -0
  18. package/src/core/sync/utils.js +44 -0
  19. package/src/core/sync/write_ambient.js +27 -0
  20. package/src/core/sync/write_client_manifest.js +82 -0
  21. package/src/core/sync/write_matchers.js +25 -0
  22. package/src/core/sync/write_root.js +88 -0
  23. package/src/core/sync/write_tsconfig.js +189 -0
  24. package/src/core/sync/write_types.js +769 -0
  25. package/src/core/utils.js +58 -0
  26. package/src/hooks.js +26 -0
  27. package/src/index/index.js +45 -0
  28. package/src/index/private.js +33 -0
  29. package/src/node/index.js +145 -0
  30. package/src/node/polyfills.js +40 -0
  31. package/src/runtime/app/env.js +11 -0
  32. package/src/runtime/app/navigation.js +22 -0
  33. package/src/runtime/app/paths.js +1 -0
  34. package/src/runtime/app/stores.js +91 -0
  35. package/src/runtime/client/ambient.d.ts +17 -0
  36. package/src/runtime/client/client.js +1258 -0
  37. package/src/runtime/client/fetcher.js +60 -0
  38. package/src/runtime/client/parse.js +36 -0
  39. package/src/runtime/client/singletons.js +11 -0
  40. package/src/runtime/client/start.js +46 -0
  41. package/src/runtime/client/types.d.ts +105 -0
  42. package/src/runtime/client/utils.js +113 -0
  43. package/src/runtime/components/error.svelte +16 -0
  44. package/{assets → src/runtime}/components/layout.svelte +0 -0
  45. package/src/runtime/env/dynamic/private.js +1 -0
  46. package/src/runtime/env/dynamic/public.js +1 -0
  47. package/src/runtime/env-private.js +7 -0
  48. package/src/runtime/env-public.js +7 -0
  49. package/src/runtime/env.js +6 -0
  50. package/src/runtime/hash.js +16 -0
  51. package/src/runtime/paths.js +11 -0
  52. package/src/runtime/server/endpoint.js +58 -0
  53. package/src/runtime/server/index.js +448 -0
  54. package/src/runtime/server/page/cookie.js +25 -0
  55. package/src/runtime/server/page/crypto.js +239 -0
  56. package/src/runtime/server/page/csp.js +249 -0
  57. package/src/runtime/server/page/fetch.js +266 -0
  58. package/src/runtime/server/page/index.js +416 -0
  59. package/src/runtime/server/page/load_data.js +127 -0
  60. package/src/runtime/server/page/render.js +359 -0
  61. package/src/runtime/server/page/respond_with_error.js +94 -0
  62. package/src/runtime/server/page/types.d.ts +44 -0
  63. package/src/runtime/server/utils.js +116 -0
  64. package/src/utils/error.js +22 -0
  65. package/src/utils/escape.js +104 -0
  66. package/src/utils/filesystem.js +108 -0
  67. package/src/utils/http.js +55 -0
  68. package/src/utils/misc.js +1 -0
  69. package/src/utils/routing.js +107 -0
  70. package/src/utils/url.js +97 -0
  71. package/src/vite/build/build_server.js +337 -0
  72. package/src/vite/build/build_service_worker.js +90 -0
  73. package/src/vite/build/utils.js +157 -0
  74. package/src/vite/dev/index.js +568 -0
  75. package/src/vite/index.js +566 -0
  76. package/src/vite/preview/index.js +186 -0
  77. package/src/vite/types.d.ts +3 -0
  78. package/src/vite/utils.js +334 -0
  79. package/svelte-kit.js +1 -1
  80. package/types/ambient.d.ts +355 -0
  81. package/types/index.d.ts +342 -0
  82. package/types/internal.d.ts +308 -0
  83. package/types/private.d.ts +209 -0
  84. package/CHANGELOG.md +0 -425
  85. package/assets/components/error.svelte +0 -13
  86. package/assets/runtime/app/env.js +0 -5
  87. package/assets/runtime/app/navigation.js +0 -41
  88. package/assets/runtime/app/paths.js +0 -1
  89. package/assets/runtime/app/stores.js +0 -93
  90. package/assets/runtime/chunks/utils.js +0 -19
  91. package/assets/runtime/internal/singletons.js +0 -23
  92. package/assets/runtime/internal/start.js +0 -770
  93. package/assets/runtime/paths.js +0 -12
  94. package/dist/api.js +0 -28
  95. package/dist/api.js.map +0 -1
  96. package/dist/chunks/index.js +0 -3521
  97. package/dist/chunks/index2.js +0 -587
  98. package/dist/chunks/index3.js +0 -246
  99. package/dist/chunks/index4.js +0 -530
  100. package/dist/chunks/index5.js +0 -761
  101. package/dist/chunks/index6.js +0 -322
  102. package/dist/chunks/standard.js +0 -99
  103. package/dist/chunks/utils.js +0 -83
  104. package/dist/cli.js +0 -546
  105. package/dist/cli.js.map +0 -1
  106. package/dist/create_app.js +0 -592
  107. package/dist/create_app.js.map +0 -1
  108. package/dist/index.js +0 -392
  109. package/dist/index.js.map +0 -1
  110. package/dist/index2.js +0 -3519
  111. package/dist/index2.js.map +0 -1
  112. package/dist/index3.js +0 -320
  113. package/dist/index3.js.map +0 -1
  114. package/dist/index4.js +0 -323
  115. package/dist/index4.js.map +0 -1
  116. package/dist/index5.js +0 -247
  117. package/dist/index5.js.map +0 -1
  118. package/dist/index6.js +0 -761
  119. package/dist/index6.js.map +0 -1
  120. package/dist/renderer.js +0 -2499
  121. package/dist/renderer.js.map +0 -1
  122. package/dist/ssr.js +0 -2581
  123. package/dist/standard.js +0 -100
  124. package/dist/standard.js.map +0 -1
  125. package/dist/utils.js +0 -84
  126. package/dist/utils.js.map +0 -1
@@ -0,0 +1,482 @@
1
+ import { join } from 'path';
2
+
3
+ /** @typedef {import('./types').Validator} Validator */
4
+
5
+ const directives = object({
6
+ 'child-src': string_array(),
7
+ 'default-src': string_array(),
8
+ 'frame-src': string_array(),
9
+ 'worker-src': string_array(),
10
+ 'connect-src': string_array(),
11
+ 'font-src': string_array(),
12
+ 'img-src': string_array(),
13
+ 'manifest-src': string_array(),
14
+ 'media-src': string_array(),
15
+ 'object-src': string_array(),
16
+ 'prefetch-src': string_array(),
17
+ 'script-src': string_array(),
18
+ 'script-src-elem': string_array(),
19
+ 'script-src-attr': string_array(),
20
+ 'style-src': string_array(),
21
+ 'style-src-elem': string_array(),
22
+ 'style-src-attr': string_array(),
23
+ 'base-uri': string_array(),
24
+ sandbox: string_array(),
25
+ 'form-action': string_array(),
26
+ 'frame-ancestors': string_array(),
27
+ 'navigate-to': string_array(),
28
+ 'report-uri': string_array(),
29
+ 'report-to': string_array(),
30
+ 'require-trusted-types-for': string_array(),
31
+ 'trusted-types': string_array(),
32
+ 'upgrade-insecure-requests': boolean(false),
33
+ 'require-sri-for': string_array(),
34
+ 'block-all-mixed-content': boolean(false),
35
+ 'plugin-types': string_array(),
36
+ referrer: string_array()
37
+ });
38
+
39
+ /** @type {Validator} */
40
+ const options = object(
41
+ {
42
+ extensions: validate(['.svelte'], (input, keypath) => {
43
+ if (!Array.isArray(input) || !input.every((page) => typeof page === 'string')) {
44
+ throw new Error(`${keypath} must be an array of strings`);
45
+ }
46
+
47
+ input.forEach((extension) => {
48
+ if (extension[0] !== '.') {
49
+ throw new Error(`Each member of ${keypath} must start with '.' — saw '${extension}'`);
50
+ }
51
+
52
+ if (!/^(\.[a-z0-9]+)+$/i.test(extension)) {
53
+ throw new Error(`File extensions must be alphanumeric — saw '${extension}'`);
54
+ }
55
+ });
56
+
57
+ return input;
58
+ }),
59
+
60
+ kit: object({
61
+ adapter: validate(null, (input, keypath) => {
62
+ if (typeof input !== 'object' || !input.adapt) {
63
+ let message = `${keypath} should be an object with an "adapt" method`;
64
+
65
+ if (Array.isArray(input) || typeof input === 'string') {
66
+ // for the early adapter adopters
67
+ message += ', rather than the name of an adapter';
68
+ }
69
+
70
+ throw new Error(`${message}. See https://kit.svelte.dev/docs/adapters`);
71
+ }
72
+
73
+ return input;
74
+ }),
75
+
76
+ alias: validate({}, (input, keypath) => {
77
+ if (typeof input !== 'object') {
78
+ throw new Error(`${keypath} should be an object`);
79
+ }
80
+
81
+ for (const key in input) {
82
+ assert_string(input[key], `${keypath}.${key}`);
83
+ }
84
+
85
+ return input;
86
+ }),
87
+
88
+ // TODO: remove this for the 1.0 release
89
+ amp: error(
90
+ (keypath) =>
91
+ `${keypath} has been removed. See https://kit.svelte.dev/docs/seo#amp for details on how to support AMP`
92
+ ),
93
+
94
+ appDir: validate('_app', (input, keypath) => {
95
+ assert_string(input, keypath);
96
+
97
+ if (input) {
98
+ if (input.startsWith('/') || input.endsWith('/')) {
99
+ throw new Error(
100
+ "config.kit.appDir cannot start or end with '/'. See https://kit.svelte.dev/docs/configuration"
101
+ );
102
+ }
103
+ } else {
104
+ throw new Error(`${keypath} cannot be empty`);
105
+ }
106
+
107
+ return input;
108
+ }),
109
+
110
+ browser: object({
111
+ hydrate: boolean(true),
112
+ router: boolean(true)
113
+ }),
114
+
115
+ csp: object({
116
+ mode: list(['auto', 'hash', 'nonce']),
117
+ directives,
118
+ reportOnly: directives
119
+ }),
120
+
121
+ // TODO: remove this for the 1.0 release
122
+ endpointExtensions: error(
123
+ (keypath) => `${keypath} has been renamed to config.kit.moduleExtensions`
124
+ ),
125
+
126
+ env: object({
127
+ publicPrefix: string('PUBLIC_')
128
+ }),
129
+
130
+ files: object({
131
+ assets: string('static'),
132
+ hooks: string(join('src', 'hooks')),
133
+ lib: string(join('src', 'lib')),
134
+ params: string(join('src', 'params')),
135
+ routes: string(join('src', 'routes')),
136
+ serviceWorker: string(join('src', 'service-worker')),
137
+ template: string(join('src', 'app.html'))
138
+ }),
139
+
140
+ // TODO: remove this for the 1.0 release
141
+ headers: error(
142
+ (keypath) =>
143
+ `${keypath} has been removed. See https://github.com/sveltejs/kit/pull/3384 for details`
144
+ ),
145
+
146
+ // TODO: remove this for the 1.0 release
147
+ host: error(
148
+ (keypath) =>
149
+ `${keypath} has been removed. See https://github.com/sveltejs/kit/pull/3384 for details`
150
+ ),
151
+
152
+ // TODO remove for 1.0
153
+ hydrate: error((keypath) => `${keypath} has been moved to config.kit.browser.hydrate`),
154
+
155
+ inlineStyleThreshold: number(0),
156
+
157
+ methodOverride: object({
158
+ parameter: string('_method'),
159
+ allowed: validate([], (input, keypath) => {
160
+ if (!Array.isArray(input) || !input.every((method) => typeof method === 'string')) {
161
+ throw new Error(`${keypath} must be an array of strings`);
162
+ }
163
+
164
+ if (input.map((i) => i.toUpperCase()).includes('GET')) {
165
+ throw new Error(`${keypath} cannot contain "GET"`);
166
+ }
167
+
168
+ return input;
169
+ })
170
+ }),
171
+
172
+ moduleExtensions: string_array(['.js', '.ts']),
173
+
174
+ outDir: string('.svelte-kit'),
175
+
176
+ package: error((keypath) => `${keypath} has been removed — use @sveltejs/package instead`),
177
+
178
+ paths: object({
179
+ base: validate('', (input, keypath) => {
180
+ assert_string(input, keypath);
181
+
182
+ if (input !== '' && (input.endsWith('/') || !input.startsWith('/'))) {
183
+ throw new Error(
184
+ `${keypath} option must either be the empty string or a root-relative path that starts but doesn't end with '/'. See https://kit.svelte.dev/docs/configuration#paths`
185
+ );
186
+ }
187
+
188
+ return input;
189
+ }),
190
+ assets: validate('', (input, keypath) => {
191
+ assert_string(input, keypath);
192
+
193
+ if (input) {
194
+ if (!/^[a-z]+:\/\//.test(input)) {
195
+ throw new Error(
196
+ `${keypath} option must be an absolute path, if specified. See https://kit.svelte.dev/docs/configuration#paths`
197
+ );
198
+ }
199
+
200
+ if (input.endsWith('/')) {
201
+ throw new Error(
202
+ `${keypath} option must not end with '/'. See https://kit.svelte.dev/docs/configuration#paths`
203
+ );
204
+ }
205
+ }
206
+
207
+ return input;
208
+ })
209
+ }),
210
+
211
+ prerender: object({
212
+ concurrency: number(1),
213
+ crawl: boolean(true),
214
+ createIndexFiles: error(
215
+ (keypath) =>
216
+ `${keypath} has been removed — it is now controlled by the trailingSlash option. See https://kit.svelte.dev/docs/configuration#trailingslash`
217
+ ),
218
+ default: boolean(false),
219
+ enabled: boolean(true),
220
+ entries: validate(['*'], (input, keypath) => {
221
+ if (!Array.isArray(input) || !input.every((page) => typeof page === 'string')) {
222
+ throw new Error(`${keypath} must be an array of strings`);
223
+ }
224
+
225
+ input.forEach((page) => {
226
+ if (page !== '*' && page[0] !== '/') {
227
+ throw new Error(
228
+ `Each member of ${keypath} must be either '*' or an absolute path beginning with '/' — saw '${page}'`
229
+ );
230
+ }
231
+ });
232
+
233
+ return input;
234
+ }),
235
+
236
+ // TODO: remove this for the 1.0 release
237
+ force: validate(undefined, (input, keypath) => {
238
+ if (typeof input !== 'undefined') {
239
+ const newSetting = input ? 'continue' : 'fail';
240
+ const needsSetting = newSetting === 'continue';
241
+ throw new Error(
242
+ `${keypath} has been removed in favor of \`onError\`. In your case, set \`onError\` to "${newSetting}"${
243
+ needsSetting ? '' : ' (or leave it undefined)'
244
+ } to get the same behavior as you would with \`force: ${JSON.stringify(input)}\``
245
+ );
246
+ }
247
+ }),
248
+
249
+ onError: validate('fail', (input, keypath) => {
250
+ if (typeof input === 'function') return input;
251
+ if (['continue', 'fail'].includes(input)) return input;
252
+ throw new Error(
253
+ `${keypath} should be either a custom function or one of "continue" or "fail"`
254
+ );
255
+ }),
256
+
257
+ origin: validate('http://sveltekit-prerender', (input, keypath) => {
258
+ assert_string(input, keypath);
259
+
260
+ let origin;
261
+
262
+ try {
263
+ origin = new URL(input).origin;
264
+ } catch (e) {
265
+ throw new Error(`${keypath} must be a valid origin`);
266
+ }
267
+
268
+ if (input !== origin) {
269
+ throw new Error(`${keypath} must be a valid origin (${origin} rather than ${input})`);
270
+ }
271
+
272
+ return origin;
273
+ }),
274
+
275
+ // TODO: remove this for the 1.0 release
276
+ pages: error((keypath) => `${keypath} has been renamed to \`entries\`.`)
277
+ }),
278
+
279
+ // TODO: remove this for the 1.0 release
280
+ protocol: error(
281
+ (keypath) =>
282
+ `${keypath} has been removed. See https://github.com/sveltejs/kit/pull/3384 for details`
283
+ ),
284
+
285
+ // TODO remove for 1.0
286
+ router: error((keypath) => `${keypath} has been moved to config.kit.browser.router`),
287
+
288
+ // TODO remove for 1.0
289
+ routes: error(
290
+ (keypath) =>
291
+ `${keypath} has been removed. See https://github.com/sveltejs/kit/discussions/5774 for details`
292
+ ),
293
+
294
+ serviceWorker: object({
295
+ register: boolean(true),
296
+ files: fun((filename) => !/\.DS_Store/.test(filename))
297
+ }),
298
+
299
+ // TODO remove this for 1.0
300
+ ssr: error(
301
+ (keypath) =>
302
+ `${keypath} has been removed — use the handle hook instead: https://kit.svelte.dev/docs/hooks#handle`
303
+ ),
304
+
305
+ // TODO remove this for 1.0
306
+ target: error((keypath) => `${keypath} is no longer required, and should be removed`),
307
+
308
+ trailingSlash: list(['never', 'always', 'ignore']),
309
+
310
+ version: object({
311
+ name: string(Date.now().toString()),
312
+ pollInterval: number(0)
313
+ }),
314
+
315
+ // TODO remove this for 1.0
316
+ vite: error((keypath) => `${keypath} has been removed — use vite.config.js instead`)
317
+ })
318
+ },
319
+ true
320
+ );
321
+
322
+ /**
323
+ * @param {Record<string, Validator>} children
324
+ * @param {boolean} [allow_unknown]
325
+ * @returns {Validator}
326
+ */
327
+ function object(children, allow_unknown = false) {
328
+ return (input, keypath) => {
329
+ /** @type {Record<string, any>} */
330
+ const output = {};
331
+
332
+ if ((input && typeof input !== 'object') || Array.isArray(input)) {
333
+ throw new Error(`${keypath} should be an object`);
334
+ }
335
+
336
+ for (const key in input) {
337
+ if (!(key in children)) {
338
+ if (allow_unknown) {
339
+ output[key] = input[key];
340
+ } else {
341
+ let message = `Unexpected option ${keypath}.${key}`;
342
+
343
+ // special case
344
+ if (keypath === 'config.kit' && key in options) {
345
+ message += ` (did you mean config.${key}?)`;
346
+ }
347
+
348
+ throw new Error(message);
349
+ }
350
+ }
351
+ }
352
+
353
+ for (const key in children) {
354
+ const validator = children[key];
355
+ output[key] = validator(input && input[key], `${keypath}.${key}`);
356
+ }
357
+
358
+ return output;
359
+ };
360
+ }
361
+
362
+ /**
363
+ * @param {any} fallback
364
+ * @param {(value: any, keypath: string) => any} fn
365
+ * @returns {Validator}
366
+ */
367
+ function validate(fallback, fn) {
368
+ return (input, keypath) => {
369
+ return input === undefined ? fallback : fn(input, keypath);
370
+ };
371
+ }
372
+
373
+ /**
374
+ * @param {string | null} fallback
375
+ * @param {boolean} allow_empty
376
+ * @returns {Validator}
377
+ */
378
+ function string(fallback, allow_empty = true) {
379
+ return validate(fallback, (input, keypath) => {
380
+ assert_string(input, keypath);
381
+
382
+ if (!allow_empty && input === '') {
383
+ throw new Error(`${keypath} cannot be empty`);
384
+ }
385
+
386
+ return input;
387
+ });
388
+ }
389
+
390
+ /**
391
+ * @param {string[] | undefined} [fallback]
392
+ * @returns {Validator}
393
+ */
394
+ function string_array(fallback) {
395
+ return validate(fallback, (input, keypath) => {
396
+ if (input === undefined) return input;
397
+
398
+ if (!Array.isArray(input) || input.some((value) => typeof value !== 'string')) {
399
+ throw new Error(`${keypath} must be an array of strings, if specified`);
400
+ }
401
+
402
+ return input;
403
+ });
404
+ }
405
+
406
+ /**
407
+ * @param {number} fallback
408
+ * @returns {Validator}
409
+ */
410
+ function number(fallback) {
411
+ return validate(fallback, (input, keypath) => {
412
+ if (typeof input !== 'number') {
413
+ throw new Error(`${keypath} should be a number, if specified`);
414
+ }
415
+ return input;
416
+ });
417
+ }
418
+
419
+ /**
420
+ * @param {boolean} fallback
421
+ * @returns {Validator}
422
+ */
423
+ function boolean(fallback) {
424
+ return validate(fallback, (input, keypath) => {
425
+ if (typeof input !== 'boolean') {
426
+ throw new Error(`${keypath} should be true or false, if specified`);
427
+ }
428
+ return input;
429
+ });
430
+ }
431
+
432
+ /**
433
+ * @param {string[]} options
434
+ * @returns {Validator}
435
+ */
436
+ function list(options, fallback = options[0]) {
437
+ return validate(fallback, (input, keypath) => {
438
+ if (!options.includes(input)) {
439
+ // prettier-ignore
440
+ const msg = options.length > 2
441
+ ? `${keypath} should be one of ${options.slice(0, -1).map(input => `"${input}"`).join(', ')} or "${options[options.length - 1]}"`
442
+ : `${keypath} should be either "${options[0]}" or "${options[1]}"`;
443
+
444
+ throw new Error(msg);
445
+ }
446
+ return input;
447
+ });
448
+ }
449
+
450
+ /**
451
+ * @param {(filename: string) => boolean} fallback
452
+ * @returns {Validator}
453
+ */
454
+ function fun(fallback) {
455
+ return validate(fallback, (input, keypath) => {
456
+ if (typeof input !== 'function') {
457
+ throw new Error(`${keypath} should be a function, if specified`);
458
+ }
459
+ return input;
460
+ });
461
+ }
462
+
463
+ /**
464
+ * @param {string} input
465
+ * @param {string} keypath
466
+ */
467
+ function assert_string(input, keypath) {
468
+ if (typeof input !== 'string') {
469
+ throw new Error(`${keypath} should be a string, if specified`);
470
+ }
471
+ }
472
+
473
+ /** @param {(keypath?: string) => string} fn */
474
+ function error(fn) {
475
+ return validate(undefined, (input, keypath) => {
476
+ if (input !== undefined) {
477
+ throw new Error(fn(keypath));
478
+ }
479
+ });
480
+ }
481
+
482
+ export default options;
@@ -0,0 +1 @@
1
+ export type Validator<T = any> = (input: T, keypath: string) => T;
@@ -0,0 +1,5 @@
1
+ // in `vite dev` and `vite preview`, we use a fake asset path so that we can
2
+ // serve local assets while verifying that requests are correctly prefixed
3
+ export const SVELTE_KIT_ASSETS = '/_svelte_kit_assets';
4
+
5
+ export const GENERATED_COMMENT = '// this file is generated — do not edit it\n';
@@ -0,0 +1,91 @@
1
+ import { GENERATED_COMMENT } from './constants.js';
2
+
3
+ /**
4
+ * @param {string} id
5
+ * @param {Record<string, string>} env
6
+ * @returns {string}
7
+ */
8
+ export function create_module(id, env) {
9
+ /** @type {string[]} */
10
+ const declarations = [];
11
+
12
+ for (const key in env) {
13
+ if (!valid_identifier.test(key) || reserved.has(key)) {
14
+ continue;
15
+ }
16
+
17
+ const comment = `/** @type {import('${id}').${key}} */`;
18
+ const declaration = `export const ${key} = ${JSON.stringify(env[key])};`;
19
+
20
+ declarations.push(`${comment}\n${declaration}`);
21
+ }
22
+
23
+ return GENERATED_COMMENT + declarations.join('\n\n');
24
+ }
25
+
26
+ /**
27
+ * @param {string} id
28
+ * @param {Record<string, string>} env
29
+ * @returns {string}
30
+ */
31
+ export function create_types(id, env) {
32
+ const declarations = Object.keys(env)
33
+ .filter((k) => valid_identifier.test(k))
34
+ .map((k) => `\texport const ${k}: string;`)
35
+ .join('\n');
36
+
37
+ return `declare module '${id}' {\n${declarations}\n}`;
38
+ }
39
+
40
+ export const reserved = new Set([
41
+ 'do',
42
+ 'if',
43
+ 'in',
44
+ 'for',
45
+ 'let',
46
+ 'new',
47
+ 'try',
48
+ 'var',
49
+ 'case',
50
+ 'else',
51
+ 'enum',
52
+ 'eval',
53
+ 'null',
54
+ 'this',
55
+ 'true',
56
+ 'void',
57
+ 'with',
58
+ 'await',
59
+ 'break',
60
+ 'catch',
61
+ 'class',
62
+ 'const',
63
+ 'false',
64
+ 'super',
65
+ 'throw',
66
+ 'while',
67
+ 'yield',
68
+ 'delete',
69
+ 'export',
70
+ 'import',
71
+ 'public',
72
+ 'return',
73
+ 'static',
74
+ 'switch',
75
+ 'typeof',
76
+ 'default',
77
+ 'extends',
78
+ 'finally',
79
+ 'package',
80
+ 'private',
81
+ 'continue',
82
+ 'debugger',
83
+ 'function',
84
+ 'arguments',
85
+ 'interface',
86
+ 'protected',
87
+ 'implements',
88
+ 'instanceof'
89
+ ]);
90
+
91
+ export const valid_identifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
@@ -0,0 +1,99 @@
1
+ import { s } from '../../utils/misc.js';
2
+ import { parse_route_id } from '../../utils/routing.js';
3
+ import { get_mime_lookup } from '../utils.js';
4
+
5
+ /**
6
+ * Generates the data used to write the server-side manifest.js file. This data is used in the Vite
7
+ * build process, to power routing, etc.
8
+ * @param {{
9
+ * build_data: import('types').BuildData;
10
+ * relative_path: string;
11
+ * routes: import('types').RouteData[];
12
+ * format?: 'esm' | 'cjs'
13
+ * }} opts
14
+ */
15
+ export function generate_manifest({ build_data, relative_path, routes, format = 'esm' }) {
16
+ /** @typedef {{ index: number, path: string }} LookupEntry */
17
+ /** @type {Map<import('types').PageNode, LookupEntry>} */
18
+ const bundled_nodes = new Map();
19
+
20
+ build_data.manifest_data.nodes.forEach((node, i) => {
21
+ bundled_nodes.set(node, {
22
+ path: `${relative_path}/nodes/${i}.js`,
23
+ index: i
24
+ });
25
+ });
26
+
27
+ /** @type {(path: string) => string} */
28
+ const load =
29
+ format === 'esm'
30
+ ? (path) => `import('${path}')`
31
+ : (path) => `Promise.resolve().then(() => require('${path}'))`;
32
+
33
+ /** @type {(path: string) => string} */
34
+ const loader = (path) => `() => ${load(path)}`;
35
+
36
+ const assets = build_data.manifest_data.assets.map((asset) => asset.file);
37
+ if (build_data.service_worker) {
38
+ assets.push(build_data.service_worker);
39
+ }
40
+
41
+ /** @param {import('types').PageNode | undefined} id */
42
+ const get_index = (id) => id && /** @type {LookupEntry} */ (bundled_nodes.get(id)).index;
43
+
44
+ const matchers = new Set();
45
+
46
+ // prettier-ignore
47
+ return `{
48
+ appDir: ${s(build_data.app_dir)},
49
+ assets: new Set(${s(assets)}),
50
+ mimeTypes: ${s(get_mime_lookup(build_data.manifest_data))},
51
+ _: {
52
+ entry: ${s(build_data.client.entry)},
53
+ nodes: [
54
+ ${Array.from(bundled_nodes.values()).map(node => loader(node.path)).join(',\n\t\t\t\t')}
55
+ ],
56
+ routes: [
57
+ ${routes.map(route => {
58
+ const { pattern, names, types } = parse_route_id(route.id);
59
+
60
+ types.forEach(type => {
61
+ if (type) matchers.add(type);
62
+ });
63
+
64
+ if (route.type === 'page') {
65
+ return `{
66
+ type: 'page',
67
+ id: ${s(route.id)},
68
+ pattern: ${pattern},
69
+ names: ${s(names)},
70
+ types: ${s(types)},
71
+ errors: ${s(route.errors.map(get_index))},
72
+ layouts: ${s(route.layouts.map(get_index))},
73
+ leaf: ${s(get_index(route.leaf))}
74
+ }`.replace(/^\t\t/gm, '');
75
+ } else {
76
+ if (!build_data.server.vite_manifest[route.file]) {
77
+ // this is necessary in cases where a .css file snuck in —
78
+ // perhaps it would be better to disallow these (and others?)
79
+ return null;
80
+ }
81
+
82
+ return `{
83
+ type: 'endpoint',
84
+ id: ${s(route.id)},
85
+ pattern: ${pattern},
86
+ names: ${s(names)},
87
+ types: ${s(types)},
88
+ load: ${loader(`${relative_path}/${build_data.server.vite_manifest[route.file].file}`)}
89
+ }`.replace(/^\t\t/gm, '');
90
+ }
91
+ }).filter(Boolean).join(',\n\t\t\t\t')}
92
+ ],
93
+ matchers: async () => {
94
+ ${Array.from(matchers).map(type => `const { match: ${type} } = await ${load(`${relative_path}/entries/matchers/${type}.js`)}`).join('\n\t\t\t\t')}
95
+ return { ${Array.from(matchers).join(', ')} };
96
+ }
97
+ }
98
+ }`.replace(/^\t/gm, '');
99
+ }