@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,160 @@
1
+ import * as vite from 'vite';
2
+ import { get_aliases } from '../utils.js';
3
+
4
+ /**
5
+ * @typedef {import('rollup').RollupOutput} RollupOutput
6
+ * @typedef {import('rollup').OutputChunk} OutputChunk
7
+ * @typedef {import('rollup').OutputAsset} OutputAsset
8
+ */
9
+
10
+ /**
11
+ * Invokes Vite.
12
+ * @param {import('vite').UserConfig} config
13
+ */
14
+ export async function create_build(config) {
15
+ const { output } = /** @type {RollupOutput} */ (
16
+ await vite.build({ ...config, configFile: false })
17
+ );
18
+
19
+ const chunks = output.filter(
20
+ /** @returns {output is OutputChunk} */ (output) => output.type === 'chunk'
21
+ );
22
+
23
+ const assets = output.filter(
24
+ /** @returns {output is OutputAsset} */ (output) => output.type === 'asset'
25
+ );
26
+
27
+ return { chunks, assets };
28
+ }
29
+
30
+ /**
31
+ * Adds transitive JS and CSS dependencies to the js and css inputs.
32
+ * @param {import('vite').Manifest} manifest
33
+ * @param {string} entry
34
+ * @param {boolean} add_dynamic_css
35
+ */
36
+ export function find_deps(manifest, entry, add_dynamic_css) {
37
+ /** @type {Set<string>} */
38
+ const seen = new Set();
39
+
40
+ /** @type {Set<string>} */
41
+ const imports = new Set();
42
+
43
+ /** @type {Set<string>} */
44
+ const stylesheets = new Set();
45
+
46
+ /**
47
+ * @param {string} file
48
+ * @param {boolean} add_js
49
+ */
50
+ function traverse(file, add_js) {
51
+ if (seen.has(file)) return;
52
+ seen.add(file);
53
+
54
+ const chunk = manifest[file];
55
+
56
+ if (add_js) imports.add(chunk.file);
57
+
58
+ if (chunk.css) {
59
+ chunk.css.forEach((file) => stylesheets.add(file));
60
+ }
61
+
62
+ if (chunk.imports) {
63
+ chunk.imports.forEach((file) => traverse(file, add_js));
64
+ }
65
+
66
+ if (add_dynamic_css && chunk.dynamicImports) {
67
+ chunk.dynamicImports.forEach((file) => traverse(file, false));
68
+ }
69
+ }
70
+
71
+ traverse(entry, true);
72
+
73
+ return {
74
+ file: manifest[entry].file,
75
+ imports: Array.from(imports),
76
+ stylesheets: Array.from(stylesheets)
77
+ };
78
+ }
79
+
80
+ /**
81
+ * The Vite configuration that we use by default.
82
+ * @param {{
83
+ * config: import('types').ValidatedConfig;
84
+ * input: Record<string, string>;
85
+ * ssr: boolean;
86
+ * outDir: string;
87
+ * }} options
88
+ * @return {import('vite').UserConfig}
89
+ */
90
+ export function get_default_build_config({ config, input, ssr, outDir }) {
91
+ const prefix = `${config.kit.appDir}/immutable`;
92
+
93
+ return {
94
+ appType: 'custom',
95
+ base: ssr ? assets_base(config.kit) : './',
96
+ build: {
97
+ cssCodeSplit: true,
98
+ // don't use the default name to avoid collisions with 'static/manifest.json'
99
+ manifest: 'vite-manifest.json',
100
+ outDir,
101
+ polyfillModulePreload: false,
102
+ rollupOptions: {
103
+ input,
104
+ output: {
105
+ format: 'esm',
106
+ entryFileNames: ssr ? '[name].js' : `${prefix}/[name]-[hash].js`,
107
+ chunkFileNames: ssr ? 'chunks/[name].js' : `${prefix}/chunks/[name]-[hash].js`,
108
+ assetFileNames: `${prefix}/assets/[name]-[hash][extname]`
109
+ },
110
+ preserveEntrySignatures: 'strict'
111
+ },
112
+ ssr,
113
+ target: ssr ? 'node14.8' : undefined
114
+ },
115
+ define: {
116
+ __SVELTEKIT_ADAPTER_NAME__: JSON.stringify(config.kit.adapter?.name),
117
+ __SVELTEKIT_APP_VERSION__: JSON.stringify(config.kit.version.name),
118
+ __SVELTEKIT_APP_VERSION_FILE__: JSON.stringify(`${config.kit.appDir}/version.json`),
119
+ __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: JSON.stringify(config.kit.version.pollInterval),
120
+ __SVELTEKIT_DEV__: 'false'
121
+ },
122
+ publicDir: ssr ? false : config.kit.files.assets,
123
+ resolve: {
124
+ alias: get_aliases(config.kit)
125
+ },
126
+ optimizeDeps: {
127
+ exclude: ['@sveltejs/kit']
128
+ },
129
+ ssr: {
130
+ noExternal: ['@sveltejs/kit']
131
+ },
132
+ worker: {
133
+ rollupOptions: {
134
+ output: {
135
+ entryFileNames: `${prefix}/workers/[name]-[hash].js`,
136
+ chunkFileNames: `${prefix}/workers/chunks/[name]-[hash].js`
137
+ }
138
+ }
139
+ }
140
+ };
141
+ }
142
+
143
+ /**
144
+ * @param {import('types').ValidatedKitConfig} config
145
+ * @returns {string}
146
+ */
147
+ export function assets_base(config) {
148
+ return config.paths.assets || config.paths.base || './';
149
+ }
150
+
151
+ const method_names = new Set(['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']);
152
+
153
+ // If we'd written this in TypeScript, it could be easy...
154
+ /**
155
+ * @param {string} str
156
+ * @returns {str is import('types').HttpMethod}
157
+ */
158
+ export function is_http_method(str) {
159
+ return method_names.has(str);
160
+ }
@@ -0,0 +1,543 @@
1
+ import fs from 'fs';
2
+ import colors from 'kleur';
3
+ import path from 'path';
4
+ import sirv from 'sirv';
5
+ import { URL } from 'url';
6
+ import { getRequest, setResponse } from '../../node/index.js';
7
+ import { installPolyfills } from '../../node/polyfills.js';
8
+ import { coalesce_to_error } from '../../utils/error.js';
9
+ import { posixify } from '../../utils/filesystem.js';
10
+ import { load_template } from '../../core/config/index.js';
11
+ import { SVELTE_KIT_ASSETS } from '../../core/constants.js';
12
+ import * as sync from '../../core/sync/sync.js';
13
+ import { get_mime_lookup, runtime_base, runtime_prefix } from '../../core/utils.js';
14
+ import { get_env, prevent_illegal_vite_imports, resolve_entry } from '../utils.js';
15
+ import { compact } from '../../utils/array.js';
16
+
17
+ // Vite doesn't expose this so we just copy the list for now
18
+ // https://github.com/vitejs/vite/blob/3edd1af56e980aef56641a5a51cf2932bb580d41/packages/vite/src/node/plugins/css.ts#L96
19
+ const style_pattern = /\.(css|less|sass|scss|styl|stylus|pcss|postcss)$/;
20
+
21
+ const cwd = process.cwd();
22
+
23
+ /**
24
+ * @param {import('vite').ViteDevServer} vite
25
+ * @param {import('vite').ResolvedConfig} vite_config
26
+ * @param {import('types').ValidatedConfig} svelte_config
27
+ * @param {Set<string>} illegal_imports
28
+ * @return {Promise<Promise<() => void>>}
29
+ */
30
+ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
31
+ installPolyfills();
32
+
33
+ sync.init(svelte_config, vite_config.mode);
34
+
35
+ /** @type {import('types').Respond} */
36
+ const respond = (await import(`${runtime_prefix}/server/index.js`)).respond;
37
+
38
+ /** @type {import('types').ManifestData} */
39
+ let manifest_data;
40
+ /** @type {import('types').SSRManifest} */
41
+ let manifest;
42
+
43
+ const extensions = [...svelte_config.extensions, ...svelte_config.kit.moduleExtensions];
44
+
45
+ /** @param {string} id */
46
+ async function resolve(id) {
47
+ const url = id.startsWith('..') ? `/@fs${path.posix.resolve(id)}` : `/${id}`;
48
+
49
+ const module = await vite.ssrLoadModule(url);
50
+
51
+ const module_node = await vite.moduleGraph.getModuleByUrl(url);
52
+ if (!module_node) throw new Error(`Could not find node for ${url}`);
53
+
54
+ return { module, module_node, url };
55
+ }
56
+
57
+ async function update_manifest() {
58
+ ({ manifest_data } = await sync.create(svelte_config));
59
+
60
+ manifest = {
61
+ appDir: svelte_config.kit.appDir,
62
+ assets: new Set(manifest_data.assets.map((asset) => asset.file)),
63
+ mimeTypes: get_mime_lookup(manifest_data),
64
+ _: {
65
+ entry: {
66
+ file: `/@fs${runtime_prefix}/client/start.js`,
67
+ imports: [],
68
+ stylesheets: []
69
+ },
70
+ nodes: manifest_data.nodes.map((node, index) => {
71
+ return async () => {
72
+ /** @type {import('types').SSRNode} */
73
+ const result = {};
74
+
75
+ /** @type {import('vite').ModuleNode[]} */
76
+ const module_nodes = [];
77
+
78
+ result.index = index;
79
+
80
+ // these are unused in dev, it's easier to include them
81
+ result.imports = [];
82
+ result.stylesheets = [];
83
+
84
+ if (node.component) {
85
+ result.component = async () => {
86
+ const { module_node, module, url } = await resolve(
87
+ /** @type {string} */ (node.component)
88
+ );
89
+
90
+ module_nodes.push(module_node);
91
+ result.file = url.endsWith('.svelte') ? url : url + '?import'; // TODO what is this for?
92
+
93
+ prevent_illegal_vite_imports(module_node, illegal_imports, extensions);
94
+
95
+ return module.default;
96
+ };
97
+ }
98
+
99
+ if (node.shared) {
100
+ const { module, module_node } = await resolve(node.shared);
101
+
102
+ module_nodes.push(module_node);
103
+
104
+ result.shared = module;
105
+
106
+ prevent_illegal_vite_imports(module_node, illegal_imports, extensions);
107
+ }
108
+
109
+ if (node.server) {
110
+ const { module } = await resolve(node.server);
111
+ result.server = module;
112
+ result.server_id = node.server;
113
+ }
114
+
115
+ // in dev we inline all styles to avoid FOUC. this gets populated lazily so that
116
+ // components/stylesheets loaded via import() during `load` are included
117
+ result.inline_styles = async () => {
118
+ const deps = new Set();
119
+
120
+ for (const module_node of module_nodes) {
121
+ await find_deps(vite, module_node, deps);
122
+ }
123
+
124
+ /** @type {Record<string, string>} */
125
+ const styles = {};
126
+
127
+ for (const dep of deps) {
128
+ const parsed = new URL(dep.url, 'http://localhost/');
129
+ const query = parsed.searchParams;
130
+
131
+ if (
132
+ style_pattern.test(dep.file) ||
133
+ (query.has('svelte') && query.get('type') === 'style')
134
+ ) {
135
+ try {
136
+ const mod = await vite.ssrLoadModule(dep.url);
137
+ styles[dep.url] = mod.default;
138
+ } catch {
139
+ // this can happen with dynamically imported modules, I think
140
+ // because the Vite module graph doesn't distinguish between
141
+ // static and dynamic imports? TODO investigate, submit fix
142
+ }
143
+ }
144
+ }
145
+
146
+ return styles;
147
+ };
148
+
149
+ return result;
150
+ };
151
+ }),
152
+ routes: compact(
153
+ manifest_data.routes.map((route) => {
154
+ if (!route.page && !route.endpoint) return null;
155
+
156
+ const endpoint = route.endpoint;
157
+
158
+ return {
159
+ id: route.id,
160
+ pattern: route.pattern,
161
+ names: route.names,
162
+ types: route.types,
163
+ page: route.page,
164
+ endpoint: endpoint
165
+ ? async () => {
166
+ const url = path.resolve(cwd, endpoint.file);
167
+ return await vite.ssrLoadModule(url);
168
+ }
169
+ : null
170
+ };
171
+ })
172
+ ),
173
+ matchers: async () => {
174
+ /** @type {Record<string, import('types').ParamMatcher>} */
175
+ const matchers = {};
176
+
177
+ for (const key in manifest_data.matchers) {
178
+ const file = manifest_data.matchers[key];
179
+ const url = path.resolve(cwd, file);
180
+ const module = await vite.ssrLoadModule(url);
181
+
182
+ if (module.match) {
183
+ matchers[key] = module.match;
184
+ } else {
185
+ throw new Error(`${file} does not export a \`match\` function`);
186
+ }
187
+ }
188
+
189
+ return matchers;
190
+ }
191
+ }
192
+ };
193
+ }
194
+
195
+ /** @param {Error} error */
196
+ function fix_stack_trace(error) {
197
+ return error.stack ? vite.ssrRewriteStacktrace(error.stack) : error.stack;
198
+ }
199
+
200
+ await update_manifest();
201
+
202
+ /**
203
+ * @param {string} event
204
+ * @param {(file: string) => void} cb
205
+ */
206
+ const watch = (event, cb) => {
207
+ vite.watcher.on(event, (file) => {
208
+ if (file.startsWith(svelte_config.kit.files.routes + path.sep)) {
209
+ cb(file);
210
+ }
211
+ });
212
+ };
213
+ /** @type {NodeJS.Timeout | null } */
214
+ let timeout = null;
215
+ /** @param {() => void} to_run */
216
+ const debounce = (to_run) => {
217
+ timeout && clearTimeout(timeout);
218
+ timeout = setTimeout(() => {
219
+ timeout = null;
220
+ to_run();
221
+ }, 100);
222
+ };
223
+
224
+ // Debounce add/unlink events because in case of folder deletion or moves
225
+ // they fire in rapid succession, causing needless invocations.
226
+ watch('add', () => debounce(update_manifest));
227
+ watch('unlink', () => debounce(update_manifest));
228
+ watch('change', (file) => {
229
+ // Don't run for a single file if the whole manifest is about to get updated
230
+ if (timeout) return;
231
+
232
+ sync.update(svelte_config, manifest_data, file);
233
+ });
234
+
235
+ const assets = svelte_config.kit.paths.assets ? SVELTE_KIT_ASSETS : svelte_config.kit.paths.base;
236
+ const asset_server = sirv(svelte_config.kit.files.assets, {
237
+ dev: true,
238
+ etag: true,
239
+ maxAge: 0,
240
+ extensions: []
241
+ });
242
+
243
+ vite.middlewares.use(async (req, res, next) => {
244
+ try {
245
+ const base = `${vite.config.server.https ? 'https' : 'http'}://${
246
+ req.headers[':authority'] || req.headers.host
247
+ }`;
248
+
249
+ const decoded = decodeURI(new URL(base + req.url).pathname);
250
+
251
+ if (decoded.startsWith(assets)) {
252
+ const pathname = decoded.slice(assets.length);
253
+ const file = svelte_config.kit.files.assets + pathname;
254
+
255
+ if (fs.existsSync(file) && !fs.statSync(file).isDirectory()) {
256
+ if (has_correct_case(file, svelte_config.kit.files.assets)) {
257
+ req.url = encodeURI(pathname); // don't need query/hash
258
+ asset_server(req, res);
259
+ return;
260
+ }
261
+ }
262
+ }
263
+
264
+ next();
265
+ } catch (e) {
266
+ const error = coalesce_to_error(e);
267
+ res.statusCode = 500;
268
+ res.end(fix_stack_trace(error));
269
+ }
270
+ });
271
+
272
+ const { set_private_env } = await vite.ssrLoadModule(`${runtime_base}/env-private.js`);
273
+ const { set_public_env } = await vite.ssrLoadModule(`${runtime_base}/env-public.js`);
274
+
275
+ const env = get_env(svelte_config.kit.env, vite_config.mode);
276
+ set_private_env(env.private);
277
+ set_public_env(env.public);
278
+
279
+ return () => {
280
+ const serve_static_middleware = vite.middlewares.stack.find(
281
+ (middleware) =>
282
+ /** @type {function} */ (middleware.handle).name === 'viteServeStaticMiddleware'
283
+ );
284
+
285
+ remove_static_middlewares(vite.middlewares);
286
+
287
+ vite.middlewares.use(async (req, res) => {
288
+ try {
289
+ const base = `${vite.config.server.https ? 'https' : 'http'}://${
290
+ req.headers[':authority'] || req.headers.host
291
+ }`;
292
+
293
+ const decoded = decodeURI(new URL(base + req.url).pathname);
294
+ const file = posixify(path.resolve(decoded.slice(1)));
295
+ const is_file = fs.existsSync(file) && !fs.statSync(file).isDirectory();
296
+ const allowed =
297
+ !vite_config.server.fs.strict ||
298
+ vite_config.server.fs.allow.some((dir) => file.startsWith(dir));
299
+
300
+ if (is_file && allowed) {
301
+ // @ts-expect-error
302
+ serve_static_middleware.handle(req, res);
303
+ return;
304
+ }
305
+
306
+ if (!decoded.startsWith(svelte_config.kit.paths.base)) {
307
+ return not_found(
308
+ res,
309
+ `Not found (did you mean ${svelte_config.kit.paths.base + req.url}?)`
310
+ );
311
+ }
312
+
313
+ /** @type {Partial<import('types').Hooks>} */
314
+ const user_hooks = resolve_entry(svelte_config.kit.files.hooks)
315
+ ? await vite.ssrLoadModule(`/${svelte_config.kit.files.hooks}`)
316
+ : {};
317
+
318
+ const handle = user_hooks.handle || (({ event, resolve }) => resolve(event));
319
+
320
+ /** @type {import('types').Hooks} */
321
+ const hooks = {
322
+ handle,
323
+ handleError:
324
+ user_hooks.handleError ||
325
+ (({ /** @type {Error & { frame?: string }} */ error }) => {
326
+ console.error(colors.bold().red(error.message));
327
+ if (error.frame) {
328
+ console.error(colors.gray(error.frame));
329
+ }
330
+ if (error.stack) {
331
+ console.error(colors.gray(error.stack));
332
+ }
333
+ }),
334
+ externalFetch: user_hooks.externalFetch || fetch
335
+ };
336
+
337
+ if (/** @type {any} */ (hooks).getContext) {
338
+ // TODO remove this for 1.0
339
+ throw new Error(
340
+ 'The getContext hook has been removed. See https://kit.svelte.dev/docs/hooks'
341
+ );
342
+ }
343
+
344
+ if (/** @type {any} */ (hooks).serverFetch) {
345
+ // TODO remove this for 1.0
346
+ throw new Error('The serverFetch hook has been renamed to externalFetch.');
347
+ }
348
+
349
+ // TODO the / prefix will probably fail if outDir is outside the cwd (which
350
+ // could be the case in a monorepo setup), but without it these modules
351
+ // can get loaded twice via different URLs, which causes failures. Might
352
+ // require changes to Vite to fix
353
+ const { default: root } = await vite.ssrLoadModule(
354
+ `/${posixify(path.relative(cwd, `${svelte_config.kit.outDir}/generated/root.svelte`))}`
355
+ );
356
+
357
+ const paths = await vite.ssrLoadModule(`${runtime_base}/paths.js`);
358
+
359
+ paths.set_paths({
360
+ base: svelte_config.kit.paths.base,
361
+ assets
362
+ });
363
+
364
+ let request;
365
+
366
+ try {
367
+ request = await getRequest(base, req);
368
+ } catch (/** @type {any} */ err) {
369
+ res.statusCode = err.status || 400;
370
+ return res.end(err.reason || 'Invalid request body');
371
+ }
372
+
373
+ const template = load_template(cwd, svelte_config);
374
+
375
+ const rendered = await respond(
376
+ request,
377
+ {
378
+ csp: svelte_config.kit.csp,
379
+ dev: true,
380
+ get_stack: (error) => fix_stack_trace(error),
381
+ handle_error: (error, event) => {
382
+ hooks.handleError({
383
+ error: new Proxy(error, {
384
+ get: (target, property) => {
385
+ if (property === 'stack') {
386
+ return fix_stack_trace(error);
387
+ }
388
+
389
+ return Reflect.get(target, property, target);
390
+ }
391
+ }),
392
+ event,
393
+
394
+ // TODO remove for 1.0
395
+ // @ts-expect-error
396
+ get request() {
397
+ throw new Error(
398
+ 'request in handleError has been replaced with event. See https://github.com/sveltejs/kit/pull/3384 for details'
399
+ );
400
+ }
401
+ });
402
+ },
403
+ hooks,
404
+ hydrate: svelte_config.kit.browser.hydrate,
405
+ manifest,
406
+ method_override: svelte_config.kit.methodOverride,
407
+ paths: {
408
+ base: svelte_config.kit.paths.base,
409
+ assets
410
+ },
411
+ prerender: {
412
+ default: svelte_config.kit.prerender.default,
413
+ enabled: svelte_config.kit.prerender.enabled
414
+ },
415
+ public_env: env.public,
416
+ read: (file) => fs.readFileSync(path.join(svelte_config.kit.files.assets, file)),
417
+ root,
418
+ router: svelte_config.kit.browser.router,
419
+ template: ({ head, body, assets, nonce }) => {
420
+ return (
421
+ template
422
+ .replace(/%sveltekit\.assets%/g, assets)
423
+ .replace(/%sveltekit\.nonce%/g, nonce)
424
+ // head and body must be replaced last, in case someone tries to sneak in %sveltekit.assets% etc
425
+ .replace('%sveltekit.head%', () => head)
426
+ .replace('%sveltekit.body%', () => body)
427
+ );
428
+ },
429
+ template_contains_nonce: template.includes('%sveltekit.nonce%'),
430
+ trailing_slash: svelte_config.kit.trailingSlash
431
+ },
432
+ {
433
+ getClientAddress: () => {
434
+ const { remoteAddress } = req.socket;
435
+ if (remoteAddress) return remoteAddress;
436
+ throw new Error('Could not determine clientAddress');
437
+ }
438
+ }
439
+ );
440
+
441
+ if (rendered.status === 404) {
442
+ // @ts-expect-error
443
+ serve_static_middleware.handle(req, res, () => {
444
+ setResponse(res, rendered);
445
+ });
446
+ } else {
447
+ setResponse(res, rendered);
448
+ }
449
+ } catch (e) {
450
+ const error = coalesce_to_error(e);
451
+ res.statusCode = 500;
452
+ res.end(fix_stack_trace(error));
453
+ }
454
+ });
455
+ };
456
+ }
457
+
458
+ /** @param {import('http').ServerResponse} res */
459
+ function not_found(res, message = 'Not found') {
460
+ res.statusCode = 404;
461
+ res.end(message);
462
+ }
463
+
464
+ /**
465
+ * @param {import('connect').Server} server
466
+ */
467
+ function remove_static_middlewares(server) {
468
+ // We don't use viteServePublicMiddleware because of the following issues:
469
+ // https://github.com/vitejs/vite/issues/9260
470
+ // https://github.com/vitejs/vite/issues/9236
471
+ // https://github.com/vitejs/vite/issues/9234
472
+ const static_middlewares = ['viteServePublicMiddleware', 'viteServeStaticMiddleware'];
473
+ for (let i = server.stack.length - 1; i > 0; i--) {
474
+ // @ts-expect-error using internals
475
+ if (static_middlewares.includes(server.stack[i].handle.name)) {
476
+ server.stack.splice(i, 1);
477
+ }
478
+ }
479
+ }
480
+
481
+ /**
482
+ * @param {import('vite').ViteDevServer} vite
483
+ * @param {import('vite').ModuleNode} node
484
+ * @param {Set<import('vite').ModuleNode>} deps
485
+ */
486
+ async function find_deps(vite, node, deps) {
487
+ // since `ssrTransformResult.deps` contains URLs instead of `ModuleNode`s, this process is asynchronous.
488
+ // instead of using `await`, we resolve all branches in parallel.
489
+ /** @type {Promise<void>[]} */
490
+ const branches = [];
491
+
492
+ /** @param {import('vite').ModuleNode} node */
493
+ async function add(node) {
494
+ if (!deps.has(node)) {
495
+ deps.add(node);
496
+ await find_deps(vite, node, deps);
497
+ }
498
+ }
499
+
500
+ /** @param {string} url */
501
+ async function add_by_url(url) {
502
+ const node = await vite.moduleGraph.getModuleByUrl(url);
503
+
504
+ if (node) {
505
+ await add(node);
506
+ }
507
+ }
508
+
509
+ if (node.ssrTransformResult) {
510
+ if (node.ssrTransformResult.deps) {
511
+ node.ssrTransformResult.deps.forEach((url) => branches.push(add_by_url(url)));
512
+ }
513
+
514
+ if (node.ssrTransformResult.dynamicDeps) {
515
+ node.ssrTransformResult.dynamicDeps.forEach((url) => branches.push(add_by_url(url)));
516
+ }
517
+ } else {
518
+ node.importedModules.forEach((node) => branches.push(add(node)));
519
+ }
520
+
521
+ await Promise.all(branches);
522
+ }
523
+
524
+ /**
525
+ * Determine if a file is being requested with the correct case,
526
+ * to ensure consistent behaviour between dev and prod and across
527
+ * operating systems. Note that we can't use realpath here,
528
+ * because we don't want to follow symlinks
529
+ * @param {string} file
530
+ * @param {string} assets
531
+ * @returns {boolean}
532
+ */
533
+ function has_correct_case(file, assets) {
534
+ if (file === assets) return true;
535
+
536
+ const parent = path.dirname(file);
537
+
538
+ if (fs.readdirSync(parent).includes(path.basename(file))) {
539
+ return has_correct_case(parent, assets);
540
+ }
541
+
542
+ return false;
543
+ }