@sveltejs/kit 1.0.0-next.44 → 1.0.0-next.442

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 (153) hide show
  1. package/README.md +12 -9
  2. package/package.json +94 -63
  3. package/src/cli.js +112 -0
  4. package/src/core/adapt/builder.js +223 -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 +5 -0
  10. package/src/core/env.js +97 -0
  11. package/src/core/generate_manifest/index.js +78 -0
  12. package/src/core/prerender/crawl.js +194 -0
  13. package/src/core/prerender/prerender.js +380 -0
  14. package/src/core/prerender/queue.js +80 -0
  15. package/src/core/sync/create_manifest_data/index.js +452 -0
  16. package/src/core/sync/create_manifest_data/types.d.ts +37 -0
  17. package/src/core/sync/sync.js +59 -0
  18. package/src/core/sync/utils.js +33 -0
  19. package/src/core/sync/write_ambient.js +27 -0
  20. package/src/core/sync/write_client_manifest.js +92 -0
  21. package/src/core/sync/write_matchers.js +25 -0
  22. package/src/core/sync/write_root.js +91 -0
  23. package/src/core/sync/write_tsconfig.js +195 -0
  24. package/src/core/sync/write_types/index.js +580 -0
  25. package/src/core/sync/write_types/test/layout/+layout.js +5 -0
  26. package/src/core/sync/write_types/test/layout/+layout.server.js +5 -0
  27. package/src/core/sync/write_types/test/layout/+layout.svelte +0 -0
  28. package/src/core/sync/write_types/test/layout/+page.js +5 -0
  29. package/src/core/sync/write_types/test/layout/+page.server.js +5 -0
  30. package/src/core/sync/write_types/test/layout/+page.svelte +0 -0
  31. package/src/core/sync/write_types/test/layout/_expected/$types.d.ts +67 -0
  32. package/src/core/sync/write_types/test/layout-advanced/(main)/+layout.server.js +5 -0
  33. package/src/core/sync/write_types/test/layout-advanced/(main)/+layout.svelte +0 -0
  34. package/src/core/sync/write_types/test/layout-advanced/(main)/+page.js +5 -0
  35. package/src/core/sync/write_types/test/layout-advanced/(main)/+page@.svelte +0 -0
  36. package/src/core/sync/write_types/test/layout-advanced/(main)/sub/+page.js +5 -0
  37. package/src/core/sync/write_types/test/layout-advanced/(main)/sub/+page.svelte +0 -0
  38. package/src/core/sync/write_types/test/layout-advanced/+layout.js +5 -0
  39. package/src/core/sync/write_types/test/layout-advanced/+layout.svelte +0 -0
  40. package/src/core/sync/write_types/test/layout-advanced/_expected/$types.d.ts +32 -0
  41. package/src/core/sync/write_types/test/layout-advanced/_expected/(main)/$types.d.ts +42 -0
  42. package/src/core/sync/write_types/test/layout-advanced/_expected/(main)/sub/$types.d.ts +33 -0
  43. package/src/core/sync/write_types/test/simple-page-server-and-shared/+page.js +5 -0
  44. package/src/core/sync/write_types/test/simple-page-server-and-shared/+page.server.js +5 -0
  45. package/src/core/sync/write_types/test/simple-page-server-and-shared/+page.svelte +0 -0
  46. package/src/core/sync/write_types/test/simple-page-server-and-shared/_expected/$types.d.ts +44 -0
  47. package/src/core/sync/write_types/test/simple-page-server-only/+page.server.js +5 -0
  48. package/src/core/sync/write_types/test/simple-page-server-only/+page.svelte +0 -0
  49. package/src/core/sync/write_types/test/simple-page-server-only/_expected/$types.d.ts +30 -0
  50. package/src/core/sync/write_types/test/simple-page-shared-only/+page.js +5 -0
  51. package/src/core/sync/write_types/test/simple-page-shared-only/+page.svelte +0 -0
  52. package/src/core/sync/write_types/test/simple-page-shared-only/_expected/$types.d.ts +33 -0
  53. package/src/core/sync/write_types/test/slugs/+layout.js +1 -0
  54. package/src/core/sync/write_types/test/slugs/+layout.svelte +1 -0
  55. package/src/core/sync/write_types/test/slugs/[...rest]/+page.js +3 -0
  56. package/src/core/sync/write_types/test/slugs/[...rest]/+page.svelte +0 -0
  57. package/src/core/sync/write_types/test/slugs/[slug]/+page.js +3 -0
  58. package/src/core/sync/write_types/test/slugs/[slug]/+page.svelte +0 -0
  59. package/src/core/sync/write_types/test/slugs/_expected/$types.d.ts +32 -0
  60. package/src/core/sync/write_types/test/slugs/_expected/[...rest]/$types.d.ts +29 -0
  61. package/src/core/sync/write_types/test/slugs/_expected/[slug]/$types.d.ts +29 -0
  62. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/+layout.js +1 -0
  63. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/+layout.svelte +1 -0
  64. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/_expected/$types.d.ts +30 -0
  65. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/_expected/nested/$types.d.ts +32 -0
  66. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/_expected/nested/[...rest]/$types.d.ts +37 -0
  67. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/_expected/nested/[slug]/$types.d.ts +17 -0
  68. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/nested/+layout.js +1 -0
  69. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/nested/+layout.svelte +1 -0
  70. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/nested/[...rest]/+page.js +3 -0
  71. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/nested/[...rest]/+page.svelte +0 -0
  72. package/src/core/sync/write_types/test/slugs-layout-not-all-pages-have-load/nested/[slug]/+page@.svelte +0 -0
  73. package/src/core/utils.js +70 -0
  74. package/src/hooks.js +26 -0
  75. package/src/index/index.js +45 -0
  76. package/src/index/private.js +33 -0
  77. package/src/node/index.js +145 -0
  78. package/src/node/polyfills.js +40 -0
  79. package/src/runtime/app/env.js +11 -0
  80. package/src/runtime/app/navigation.js +22 -0
  81. package/src/runtime/app/paths.js +1 -0
  82. package/src/runtime/app/stores.js +102 -0
  83. package/src/runtime/client/ambient.d.ts +18 -0
  84. package/src/runtime/client/client.js +1362 -0
  85. package/src/runtime/client/fetcher.js +60 -0
  86. package/src/runtime/client/parse.js +41 -0
  87. package/src/runtime/client/singletons.js +21 -0
  88. package/src/runtime/client/start.js +46 -0
  89. package/src/runtime/client/types.d.ts +86 -0
  90. package/src/runtime/client/utils.js +113 -0
  91. package/src/runtime/components/error.svelte +16 -0
  92. package/{assets → src/runtime}/components/layout.svelte +0 -0
  93. package/src/runtime/env/dynamic/private.js +1 -0
  94. package/src/runtime/env/dynamic/public.js +1 -0
  95. package/src/runtime/env-private.js +7 -0
  96. package/src/runtime/env-public.js +7 -0
  97. package/src/runtime/env.js +6 -0
  98. package/src/runtime/hash.js +16 -0
  99. package/src/runtime/paths.js +11 -0
  100. package/src/runtime/server/endpoint.js +50 -0
  101. package/src/runtime/server/index.js +492 -0
  102. package/src/runtime/server/page/cookie.js +25 -0
  103. package/src/runtime/server/page/crypto.js +239 -0
  104. package/src/runtime/server/page/csp.js +249 -0
  105. package/src/runtime/server/page/fetch.js +266 -0
  106. package/src/runtime/server/page/index.js +408 -0
  107. package/src/runtime/server/page/load_data.js +168 -0
  108. package/src/runtime/server/page/render.js +361 -0
  109. package/src/runtime/server/page/respond_with_error.js +95 -0
  110. package/src/runtime/server/page/types.d.ts +44 -0
  111. package/src/runtime/server/utils.js +116 -0
  112. package/src/utils/array.js +9 -0
  113. package/src/utils/error.js +22 -0
  114. package/src/utils/escape.js +104 -0
  115. package/src/utils/filesystem.js +108 -0
  116. package/src/utils/functions.js +16 -0
  117. package/src/utils/http.js +55 -0
  118. package/src/utils/misc.js +1 -0
  119. package/src/utils/routing.js +146 -0
  120. package/src/utils/url.js +142 -0
  121. package/src/vite/build/build_server.js +348 -0
  122. package/src/vite/build/build_service_worker.js +90 -0
  123. package/src/vite/build/utils.js +160 -0
  124. package/src/vite/dev/index.js +543 -0
  125. package/src/vite/index.js +578 -0
  126. package/src/vite/preview/index.js +186 -0
  127. package/src/vite/types.d.ts +3 -0
  128. package/src/vite/utils.js +345 -0
  129. package/svelte-kit.js +1 -1
  130. package/types/ambient.d.ts +366 -0
  131. package/types/index.d.ts +345 -0
  132. package/types/internal.d.ts +374 -0
  133. package/types/private.d.ts +209 -0
  134. package/CHANGELOG.md +0 -437
  135. package/assets/components/error.svelte +0 -13
  136. package/assets/runtime/app/env.js +0 -5
  137. package/assets/runtime/app/navigation.js +0 -41
  138. package/assets/runtime/app/paths.js +0 -1
  139. package/assets/runtime/app/stores.js +0 -93
  140. package/assets/runtime/chunks/utils.js +0 -19
  141. package/assets/runtime/internal/singletons.js +0 -23
  142. package/assets/runtime/internal/start.js +0 -770
  143. package/assets/runtime/paths.js +0 -12
  144. package/dist/chunks/index.js +0 -3521
  145. package/dist/chunks/index2.js +0 -587
  146. package/dist/chunks/index3.js +0 -246
  147. package/dist/chunks/index4.js +0 -545
  148. package/dist/chunks/index5.js +0 -761
  149. package/dist/chunks/index6.js +0 -322
  150. package/dist/chunks/standard.js +0 -99
  151. package/dist/chunks/utils.js +0 -83
  152. package/dist/cli.js +0 -546
  153. package/dist/ssr.js +0 -2580
@@ -0,0 +1,142 @@
1
+ const absolute = /^([a-z]+:)?\/?\//;
2
+ const scheme = /^[a-z]+:/;
3
+
4
+ /**
5
+ * @param {string} base
6
+ * @param {string} path
7
+ */
8
+ export function resolve(base, path) {
9
+ if (scheme.test(path)) return path;
10
+
11
+ const base_match = absolute.exec(base);
12
+ const path_match = absolute.exec(path);
13
+
14
+ if (!base_match) {
15
+ throw new Error(`bad base path: "${base}"`);
16
+ }
17
+
18
+ const baseparts = path_match ? [] : base.slice(base_match[0].length).split('/');
19
+ const pathparts = path_match ? path.slice(path_match[0].length).split('/') : path.split('/');
20
+
21
+ baseparts.pop();
22
+
23
+ for (let i = 0; i < pathparts.length; i += 1) {
24
+ const part = pathparts[i];
25
+ if (part === '.') continue;
26
+ else if (part === '..') baseparts.pop();
27
+ else baseparts.push(part);
28
+ }
29
+
30
+ const prefix = (path_match && path_match[0]) || (base_match && base_match[0]) || '';
31
+
32
+ return `${prefix}${baseparts.join('/')}`;
33
+ }
34
+
35
+ /** @param {string} path */
36
+ export function is_root_relative(path) {
37
+ return path[0] === '/' && path[1] !== '/';
38
+ }
39
+
40
+ /**
41
+ * @param {string} path
42
+ * @param {import('types').TrailingSlash} trailing_slash
43
+ */
44
+ export function normalize_path(path, trailing_slash) {
45
+ if (path === '/' || trailing_slash === 'ignore') return path;
46
+
47
+ if (trailing_slash === 'never') {
48
+ return path.endsWith('/') ? path.slice(0, -1) : path;
49
+ } else if (trailing_slash === 'always' && !path.endsWith('/')) {
50
+ return path + '/';
51
+ }
52
+
53
+ return path;
54
+ }
55
+
56
+ /** @param {Record<string, string>} params */
57
+ export function decode_params(params) {
58
+ for (const key in params) {
59
+ // input has already been decoded by decodeURI
60
+ // now handle the rest that decodeURIComponent would do
61
+ params[key] = params[key]
62
+ .replace(/%23/g, '#')
63
+ .replace(/%3[Bb]/g, ';')
64
+ .replace(/%2[Cc]/g, ',')
65
+ .replace(/%2[Ff]/g, '/')
66
+ .replace(/%3[Ff]/g, '?')
67
+ .replace(/%3[Aa]/g, ':')
68
+ .replace(/%40/g, '@')
69
+ .replace(/%26/g, '&')
70
+ .replace(/%3[Dd]/g, '=')
71
+ .replace(/%2[Bb]/g, '+')
72
+ .replace(/%24/g, '$');
73
+ }
74
+
75
+ return params;
76
+ }
77
+
78
+ /**
79
+ * URL properties that could change during the lifetime of the page,
80
+ * which excludes things like `origin`
81
+ * @type {Array<keyof URL>}
82
+ */
83
+ const tracked_url_properties = ['href', 'pathname', 'search', 'searchParams', 'toString', 'toJSON'];
84
+
85
+ /**
86
+ * @param {URL} url
87
+ * @param {() => void} callback
88
+ */
89
+ export function make_trackable(url, callback) {
90
+ const tracked = new URL(url);
91
+
92
+ for (const property of tracked_url_properties) {
93
+ let value = tracked[property];
94
+
95
+ Object.defineProperty(tracked, property, {
96
+ get() {
97
+ callback();
98
+ return value;
99
+ },
100
+
101
+ enumerable: true,
102
+ configurable: true
103
+ });
104
+ }
105
+
106
+ // @ts-ignore
107
+ tracked[Symbol.for('nodejs.util.inspect.custom')] = (depth, opts, inspect) => {
108
+ return inspect(url, opts);
109
+ };
110
+
111
+ disable_hash(tracked);
112
+
113
+ return tracked;
114
+ }
115
+
116
+ /**
117
+ * Disallow access to `url.hash` on the server and in `load`
118
+ * @param {URL} url
119
+ */
120
+ export function disable_hash(url) {
121
+ Object.defineProperty(url, 'hash', {
122
+ get() {
123
+ throw new Error(
124
+ 'Cannot access event.url.hash. Consider using `$page.url.hash` inside a component instead'
125
+ );
126
+ }
127
+ });
128
+ }
129
+
130
+ /**
131
+ * Disallow access to `url.search` and `url.searchParams` during prerendering
132
+ * @param {URL} url
133
+ */
134
+ export function disable_search(url) {
135
+ for (const property of ['search', 'searchParams']) {
136
+ Object.defineProperty(url, property, {
137
+ get() {
138
+ throw new Error(`Cannot access url.${property} on a page with prerendering enabled`);
139
+ }
140
+ });
141
+ }
142
+ }
@@ -0,0 +1,348 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { mkdirp, posixify } from '../../utils/filesystem.js';
4
+ import { get_vite_config, merge_vite_configs, resolve_entry } from '../utils.js';
5
+ import { load_template } from '../../core/config/index.js';
6
+ import { runtime_directory } from '../../core/utils.js';
7
+ import { create_build, find_deps, get_default_build_config, is_http_method } from './utils.js';
8
+ import { s } from '../../utils/misc.js';
9
+
10
+ /**
11
+ * @param {{
12
+ * hooks: string;
13
+ * config: import('types').ValidatedConfig;
14
+ * has_service_worker: boolean;
15
+ * runtime: string;
16
+ * template: string;
17
+ * }} opts
18
+ */
19
+ const server_template = ({ config, hooks, has_service_worker, runtime, template }) => `
20
+ import root from '__GENERATED__/root.svelte';
21
+ import { respond } from '${runtime}/server/index.js';
22
+ import { set_paths, assets, base } from '${runtime}/paths.js';
23
+ import { set_prerendering } from '${runtime}/env.js';
24
+ import { set_private_env } from '${runtime}/env-private.js';
25
+ import { set_public_env } from '${runtime}/env-public.js';
26
+
27
+ const template = ({ head, body, assets, nonce }) => ${s(template)
28
+ .replace('%sveltekit.head%', '" + head + "')
29
+ .replace('%sveltekit.body%', '" + body + "')
30
+ .replace(/%sveltekit\.assets%/g, '" + assets + "')
31
+ .replace(/%sveltekit\.nonce%/g, '" + nonce + "')};
32
+
33
+ let read = null;
34
+
35
+ set_paths(${s(config.kit.paths)});
36
+
37
+ let default_protocol = 'https';
38
+
39
+ // allow paths to be globally overridden
40
+ // in svelte-kit preview and in prerendering
41
+ export function override(settings) {
42
+ default_protocol = settings.protocol || default_protocol;
43
+ set_paths(settings.paths);
44
+ set_prerendering(settings.prerendering);
45
+ read = settings.read;
46
+ }
47
+
48
+ export class Server {
49
+ constructor(manifest) {
50
+ this.options = {
51
+ csp: ${s(config.kit.csp)},
52
+ dev: false,
53
+ get_stack: error => String(error), // for security
54
+ handle_error: (error, event) => {
55
+ this.options.hooks.handleError({
56
+ error,
57
+ event,
58
+
59
+ // TODO remove for 1.0
60
+ // @ts-expect-error
61
+ get request() {
62
+ throw new Error('request in handleError has been replaced with event. See https://github.com/sveltejs/kit/pull/3384 for details');
63
+ }
64
+ });
65
+ error.stack = this.options.get_stack(error);
66
+ },
67
+ hooks: null,
68
+ hydrate: ${s(config.kit.browser.hydrate)},
69
+ manifest,
70
+ method_override: ${s(config.kit.methodOverride)},
71
+ paths: { base, assets },
72
+ prerender: {
73
+ default: ${config.kit.prerender.default},
74
+ enabled: ${config.kit.prerender.enabled}
75
+ },
76
+ public_env: {},
77
+ read,
78
+ root,
79
+ service_worker: ${has_service_worker ? "base + '/service-worker.js'" : 'null'},
80
+ router: ${s(config.kit.browser.router)},
81
+ template,
82
+ template_contains_nonce: ${template.includes('%sveltekit.nonce%')},
83
+ trailing_slash: ${s(config.kit.trailingSlash)}
84
+ };
85
+ }
86
+
87
+ /**
88
+ * Take care: Some adapters may have to call \`Server.init\` per-request to set env vars,
89
+ * so anything that shouldn't be rerun should be wrapped in an \`if\` block to make sure it hasn't
90
+ * been done already.
91
+ */
92
+ async init({ env }) {
93
+ const entries = Object.entries(env);
94
+
95
+ const prv = Object.fromEntries(entries.filter(([k]) => !k.startsWith('${
96
+ config.kit.env.publicPrefix
97
+ }')));
98
+
99
+ const pub = Object.fromEntries(entries.filter(([k]) => k.startsWith('${
100
+ config.kit.env.publicPrefix
101
+ }')));
102
+
103
+ set_private_env(prv);
104
+ set_public_env(pub);
105
+
106
+ this.options.public_env = pub;
107
+
108
+ if (!this.options.hooks) {
109
+ const module = await import(${s(hooks)});
110
+ this.options.hooks = {
111
+ handle: module.handle || (({ event, resolve }) => resolve(event)),
112
+ handleError: module.handleError || (({ error }) => console.error(error.stack)),
113
+ externalFetch: module.externalFetch || fetch
114
+ };
115
+ }
116
+ }
117
+
118
+ async respond(request, options = {}) {
119
+ if (!(request instanceof Request)) {
120
+ throw new Error('The first argument to server.respond must be a Request object. See https://github.com/sveltejs/kit/pull/3384 for details');
121
+ }
122
+
123
+ return respond(request, this.options, options);
124
+ }
125
+ }
126
+ `;
127
+
128
+ /**
129
+ * @param {{
130
+ * cwd: string;
131
+ * config: import('types').ValidatedConfig;
132
+ * vite_config: import('vite').ResolvedConfig;
133
+ * vite_config_env: import('vite').ConfigEnv;
134
+ * manifest_data: import('types').ManifestData;
135
+ * build_dir: string;
136
+ * output_dir: string;
137
+ * service_worker_entry_file: string | null;
138
+ * }} options
139
+ * @param {{ vite_manifest: import('vite').Manifest, assets: import('rollup').OutputAsset[] }} client
140
+ */
141
+ export async function build_server(options, client) {
142
+ const {
143
+ cwd,
144
+ config,
145
+ vite_config,
146
+ vite_config_env,
147
+ manifest_data,
148
+ build_dir,
149
+ output_dir,
150
+ service_worker_entry_file
151
+ } = options;
152
+
153
+ let hooks_file = resolve_entry(config.kit.files.hooks);
154
+ if (!hooks_file || !fs.existsSync(hooks_file)) {
155
+ hooks_file = path.join(config.kit.outDir, 'build/hooks.js');
156
+ fs.writeFileSync(hooks_file, '');
157
+ }
158
+
159
+ /** @type {Record<string, string>} */
160
+ const input = {
161
+ index: `${build_dir}/index.js`
162
+ };
163
+
164
+ // add entry points for every endpoint...
165
+ manifest_data.routes.forEach((route) => {
166
+ if (route.endpoint) {
167
+ const resolved = path.resolve(cwd, route.endpoint.file);
168
+ const relative = decodeURIComponent(path.relative(config.kit.files.routes, resolved));
169
+ const name = posixify(path.join('entries/endpoints', relative.replace(/\.js$/, '')));
170
+ input[name] = resolved;
171
+ }
172
+ });
173
+
174
+ // ...and every component used by pages...
175
+ manifest_data.nodes.forEach((node) => {
176
+ for (const file of [node.component, node.shared, node.server]) {
177
+ if (file) {
178
+ const resolved = path.resolve(cwd, file);
179
+ const relative = decodeURIComponent(path.relative(config.kit.files.routes, resolved));
180
+
181
+ const name = relative.startsWith('..')
182
+ ? posixify(path.join('entries/fallbacks', path.basename(file)))
183
+ : posixify(path.join('entries/pages', relative.replace(/\.js$/, '')));
184
+ input[name] = resolved;
185
+ }
186
+ }
187
+ });
188
+
189
+ // ...and every matcher
190
+ Object.entries(manifest_data.matchers).forEach(([key, file]) => {
191
+ const name = posixify(path.join('entries/matchers', key));
192
+ input[name] = path.resolve(cwd, file);
193
+ });
194
+
195
+ /** @type {(file: string) => string} */
196
+ const app_relative = (file) => {
197
+ const relative_file = path.relative(build_dir, path.resolve(cwd, file));
198
+ return relative_file[0] === '.' ? relative_file : `./${relative_file}`;
199
+ };
200
+
201
+ fs.writeFileSync(
202
+ input.index,
203
+ server_template({
204
+ config,
205
+ hooks: app_relative(hooks_file),
206
+ has_service_worker: config.kit.serviceWorker.register && !!service_worker_entry_file,
207
+ runtime: posixify(path.relative(build_dir, runtime_directory)),
208
+ template: load_template(cwd, config)
209
+ })
210
+ );
211
+
212
+ const merged_config = merge_vite_configs(
213
+ get_default_build_config({ config, input, ssr: true, outDir: `${output_dir}/server` }),
214
+ await get_vite_config(vite_config, vite_config_env)
215
+ );
216
+
217
+ const { chunks } = await create_build(merged_config);
218
+
219
+ /** @type {import('vite').Manifest} */
220
+ const vite_manifest = JSON.parse(
221
+ fs.readFileSync(`${output_dir}/server/${vite_config.build.manifest}`, 'utf-8')
222
+ );
223
+
224
+ mkdirp(`${output_dir}/server/nodes`);
225
+ mkdirp(`${output_dir}/server/stylesheets`);
226
+
227
+ const stylesheet_lookup = new Map();
228
+
229
+ client.assets.forEach((asset) => {
230
+ if (asset.fileName.endsWith('.css')) {
231
+ if (asset.source.length < config.kit.inlineStyleThreshold) {
232
+ const index = stylesheet_lookup.size;
233
+ const file = `${output_dir}/server/stylesheets/${index}.js`;
234
+
235
+ fs.writeFileSync(file, `// ${asset.fileName}\nexport default ${s(asset.source)};`);
236
+ stylesheet_lookup.set(asset.fileName, index);
237
+ }
238
+ }
239
+ });
240
+
241
+ manifest_data.nodes.forEach((node, i) => {
242
+ /** @type {string[]} */
243
+ const imports = [];
244
+
245
+ // String representation of
246
+ /** @type {import('types').SSRNode} */
247
+ /** @type {string[]} */
248
+ const exports = [`export const index = ${i};`];
249
+
250
+ /** @type {string[]} */
251
+ const imported = [];
252
+
253
+ /** @type {string[]} */
254
+ const stylesheets = [];
255
+
256
+ if (node.component) {
257
+ const entry = find_deps(client.vite_manifest, node.component, true);
258
+
259
+ imported.push(...entry.imports);
260
+ stylesheets.push(...entry.stylesheets);
261
+
262
+ exports.push(
263
+ `export const component = async () => (await import('../${
264
+ vite_manifest[node.component].file
265
+ }')).default;`,
266
+ `export const file = '${entry.file}';` // TODO what is this?
267
+ );
268
+ }
269
+
270
+ if (node.shared) {
271
+ const entry = find_deps(client.vite_manifest, node.shared, true);
272
+
273
+ imported.push(...entry.imports);
274
+ stylesheets.push(...entry.stylesheets);
275
+
276
+ imports.push(`import * as shared from '../${vite_manifest[node.shared].file}';`);
277
+ exports.push(`export { shared };`);
278
+ }
279
+
280
+ if (node.server) {
281
+ imports.push(`import * as server from '../${vite_manifest[node.server].file}';`);
282
+ exports.push(`export { server };`);
283
+ }
284
+
285
+ exports.push(
286
+ `export const imports = ${s(imported)};`,
287
+ `export const stylesheets = ${s(stylesheets)};`
288
+ );
289
+
290
+ /** @type {string[]} */
291
+ const styles = [];
292
+
293
+ stylesheets.forEach((file) => {
294
+ if (stylesheet_lookup.has(file)) {
295
+ const index = stylesheet_lookup.get(file);
296
+ const name = `stylesheet_${index}`;
297
+ imports.push(`import ${name} from '../stylesheets/${index}.js';`);
298
+ styles.push(`\t${s(file)}: ${name}`);
299
+ }
300
+ });
301
+
302
+ if (styles.length > 0) {
303
+ exports.push(`export const inline_styles = () => ({\n${styles.join(',\n')}\n});`);
304
+ }
305
+
306
+ const out = `${output_dir}/server/nodes/${i}.js`;
307
+ fs.writeFileSync(out, `${imports.join('\n')}\n\n${exports.join('\n')}\n`);
308
+ });
309
+
310
+ return {
311
+ chunks,
312
+ vite_manifest,
313
+ methods: get_methods(cwd, chunks, manifest_data)
314
+ };
315
+ }
316
+
317
+ /**
318
+ * @param {string} cwd
319
+ * @param {import('rollup').OutputChunk[]} output
320
+ * @param {import('types').ManifestData} manifest_data
321
+ */
322
+ function get_methods(cwd, output, manifest_data) {
323
+ /** @type {Record<string, string[]>} */
324
+ const lookup = {};
325
+ output.forEach((chunk) => {
326
+ if (!chunk.facadeModuleId) return;
327
+ const id = chunk.facadeModuleId.slice(cwd.length + 1);
328
+ lookup[id] = chunk.exports;
329
+ });
330
+
331
+ /** @type {Record<string, import('types').HttpMethod[]>} */
332
+ const methods = {};
333
+ manifest_data.routes.forEach((route) => {
334
+ if (route.endpoint) {
335
+ if (lookup[route.endpoint.file]) {
336
+ methods[route.endpoint.file] = lookup[route.endpoint.file].filter(is_http_method);
337
+ }
338
+ }
339
+
340
+ if (route.leaf?.server) {
341
+ if (lookup[route.leaf.server]) {
342
+ methods[route.leaf.server] = lookup[route.leaf.server].filter(is_http_method);
343
+ }
344
+ }
345
+ });
346
+
347
+ return methods;
348
+ }
@@ -0,0 +1,90 @@
1
+ import fs from 'fs';
2
+ import * as vite from 'vite';
3
+ import { s } from '../../utils/misc.js';
4
+ import { assets_base } from './utils.js';
5
+
6
+ /**
7
+ * @param {{
8
+ * config: import('types').ValidatedConfig;
9
+ * vite_config: import('vite').ResolvedConfig;
10
+ * vite_config_env: import('vite').ConfigEnv;
11
+ * manifest_data: import('types').ManifestData;
12
+ * output_dir: string;
13
+ * service_worker_entry_file: string | null;
14
+ * }} options
15
+ * @param {import('types').Prerendered} prerendered
16
+ * @param {import('vite').Manifest} client_manifest
17
+ */
18
+ export async function build_service_worker(
19
+ { config, manifest_data, output_dir, service_worker_entry_file },
20
+ prerendered,
21
+ client_manifest
22
+ ) {
23
+ const build = new Set();
24
+ for (const key in client_manifest) {
25
+ const { file, css = [], assets = [] } = client_manifest[key];
26
+ build.add(file);
27
+ css.forEach((file) => build.add(file));
28
+ assets.forEach((file) => build.add(file));
29
+ }
30
+
31
+ const service_worker = `${config.kit.outDir}/generated/service-worker.js`;
32
+
33
+ fs.writeFileSync(
34
+ service_worker,
35
+ `
36
+ // TODO remove for 1.0
37
+ export const timestamp = {
38
+ toString: () => {
39
+ throw new Error('\`timestamp\` has been removed from $service-worker. Use \`version\` instead');
40
+ }
41
+ };
42
+
43
+ export const build = [
44
+ ${Array.from(build)
45
+ .map((file) => `${s(`${config.kit.paths.base}/${file}`)}`)
46
+ .join(',\n\t\t\t\t')}
47
+ ];
48
+
49
+ export const files = [
50
+ ${manifest_data.assets
51
+ .filter((asset) => config.kit.serviceWorker.files(asset.file))
52
+ .map((asset) => `${s(`${config.kit.paths.base}/${asset.file}`)}`)
53
+ .join(',\n\t\t\t\t')}
54
+ ];
55
+
56
+ export const prerendered = [
57
+ ${prerendered.paths.map((path) => s(path)).join(',\n\t\t\t\t')}
58
+ ];
59
+
60
+ export const version = ${s(config.kit.version.name)};
61
+ `
62
+ .replace(/^\t{3}/gm, '')
63
+ .trim()
64
+ );
65
+
66
+ await vite.build({
67
+ base: assets_base(config.kit),
68
+ build: {
69
+ lib: {
70
+ entry: /** @type {string} */ (service_worker_entry_file),
71
+ name: 'app',
72
+ formats: ['es']
73
+ },
74
+ rollupOptions: {
75
+ output: {
76
+ entryFileNames: 'service-worker.js'
77
+ }
78
+ },
79
+ outDir: `${output_dir}/client`,
80
+ emptyOutDir: false
81
+ },
82
+ configFile: false,
83
+ resolve: {
84
+ alias: {
85
+ '$service-worker': service_worker,
86
+ $lib: config.kit.files.lib
87
+ }
88
+ }
89
+ });
90
+ }