@sveltejs/kit 1.0.11 → 1.0.13

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 (45) hide show
  1. package/package.json +3 -3
  2. package/src/core/adapt/builder.js +1 -1
  3. package/src/core/{prerender → postbuild}/crawl.js +0 -0
  4. package/src/core/{prerender → postbuild}/entities.js +0 -0
  5. package/src/core/{prerender → postbuild}/fallback.js +10 -7
  6. package/src/core/postbuild/index.js +104 -0
  7. package/src/core/{prerender → postbuild}/prerender.js +32 -106
  8. package/src/core/{prerender → postbuild}/queue.js +0 -0
  9. package/src/core/sync/sync.js +10 -0
  10. package/src/core/sync/write_client_manifest.js +1 -1
  11. package/src/core/sync/write_server.js +89 -0
  12. package/src/core/utils.js +0 -9
  13. package/src/exports/vite/build/build_server.js +11 -163
  14. package/src/exports/vite/build/build_service_worker.js +3 -2
  15. package/src/exports/vite/build/utils.js +1 -0
  16. package/src/exports/vite/dev/index.js +72 -114
  17. package/src/exports/vite/index.js +26 -27
  18. package/src/exports/vite/preview/index.js +11 -12
  19. package/src/runtime/app/environment.js +1 -1
  20. package/src/runtime/app/paths.js +1 -1
  21. package/src/runtime/client/client.js +8 -2
  22. package/src/runtime/client/fetcher.js +12 -4
  23. package/src/runtime/client/start.js +1 -2
  24. package/src/runtime/client/types.d.ts +1 -1
  25. package/src/runtime/client/utils.js +1 -2
  26. package/src/runtime/control.js +23 -5
  27. package/src/runtime/server/ambient.d.ts +8 -0
  28. package/src/runtime/server/cookie.js +4 -5
  29. package/src/runtime/server/data/index.js +5 -2
  30. package/src/runtime/server/endpoint.js +5 -5
  31. package/src/runtime/server/fetch.js +11 -9
  32. package/src/runtime/server/index.js +54 -395
  33. package/src/runtime/server/page/csp.js +9 -11
  34. package/src/runtime/server/page/index.js +13 -8
  35. package/src/runtime/server/page/load_data.js +2 -3
  36. package/src/runtime/server/page/render.js +28 -25
  37. package/src/runtime/server/page/respond_with_error.js +20 -13
  38. package/src/runtime/server/page/types.d.ts +0 -1
  39. package/src/runtime/server/respond.js +419 -0
  40. package/src/runtime/server/utils.js +21 -4
  41. package/src/runtime/shared.js +28 -0
  42. package/types/index.d.ts +10 -5
  43. package/types/internal.d.ts +22 -39
  44. package/src/runtime/env.js +0 -12
  45. package/src/runtime/paths.js +0 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -22,7 +22,7 @@
22
22
  "set-cookie-parser": "^2.5.1",
23
23
  "sirv": "^2.0.2",
24
24
  "tiny-glob": "^0.2.9",
25
- "undici": "5.14.0"
25
+ "undici": "5.15.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@playwright/test": "^1.29.2",
@@ -34,7 +34,7 @@
34
34
  "@types/set-cookie-parser": "^2.4.2",
35
35
  "marked": "^4.2.3",
36
36
  "rollup": "^3.7.0",
37
- "svelte": "^3.55.0",
37
+ "svelte": "^3.55.1",
38
38
  "svelte-preprocess": "^5.0.0",
39
39
  "typescript": "^4.9.4",
40
40
  "uvu": "^0.5.6",
@@ -126,7 +126,7 @@ export function create_builder({ config, build_data, routes, prerendered, log })
126
126
 
127
127
  generateFallback(dest) {
128
128
  // do prerendering in a subprocess so any dangling stuff gets killed upon completion
129
- const script = fileURLToPath(new URL('../prerender/fallback.js', import.meta.url));
129
+ const script = fileURLToPath(new URL('../postbuild/fallback.js', import.meta.url));
130
130
 
131
131
  const manifest_path = `${config.kit.outDir}/output/server/manifest-full.js`;
132
132
 
File without changes
File without changes
@@ -14,17 +14,19 @@ installPolyfills();
14
14
 
15
15
  const server_root = join(config.outDir, 'output');
16
16
 
17
+ /** @type {import('types').ServerInternalModule} */
18
+ const { set_building, set_paths } = await import(
19
+ pathToFileURL(`${server_root}/server/internal.js`).href
20
+ );
21
+
17
22
  /** @type {import('types').ServerModule} */
18
- const { Server, override } = await import(pathToFileURL(`${server_root}/server/index.js`).href);
23
+ const { Server } = await import(pathToFileURL(`${server_root}/server/index.js`).href);
19
24
 
20
25
  /** @type {import('types').SSRManifest} */
21
26
  const manifest = (await import(pathToFileURL(manifest_path).href)).manifest;
22
27
 
23
- override({
24
- building: true,
25
- paths: config.paths,
26
- read: (file) => readFileSync(join(config.files.assets, file))
27
- });
28
+ set_building(true);
29
+ set_paths(config.paths);
28
30
 
29
31
  const server = new Server(manifest);
30
32
  await server.init({ env: JSON.parse(env) });
@@ -36,7 +38,8 @@ const rendered = await server.respond(new Request(config.prerender.origin + '/[f
36
38
  prerendering: {
37
39
  fallback: true,
38
40
  dependencies: new Map()
39
- }
41
+ },
42
+ read: (file) => readFileSync(join(config.files.assets, file))
40
43
  });
41
44
 
42
45
  mkdirp(dirname(dest));
@@ -0,0 +1,104 @@
1
+ import { writeFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { pathToFileURL } from 'url';
4
+ import { get_option } from '../../runtime/server/utils.js';
5
+ import {
6
+ validate_common_exports,
7
+ validate_page_server_exports,
8
+ validate_server_exports
9
+ } from '../../utils/exports.js';
10
+ import { load_config } from '../config/index.js';
11
+ import { prerender } from './prerender.js';
12
+
13
+ const [, , client_out_dir, manifest_path, results_path, verbose, env] = process.argv;
14
+
15
+ /** @type {import('types').SSRManifest} */
16
+ const manifest = (await import(pathToFileURL(manifest_path).href)).manifest;
17
+
18
+ /** @type {import('types').PrerenderMap} */
19
+ const prerender_map = new Map();
20
+
21
+ /** @type {import('types').ValidatedKitConfig} */
22
+ const config = (await load_config()).kit;
23
+
24
+ const server_root = join(config.outDir, 'output');
25
+
26
+ /** @type {import('types').ServerInternalModule} */
27
+ const internal = await import(pathToFileURL(`${server_root}/server/internal.js`).href);
28
+
29
+ /** @type {import('types').ServerModule} */
30
+ const { Server } = await import(pathToFileURL(`${server_root}/server/index.js`).href);
31
+
32
+ // configure `import { building } from '$app/environment'` —
33
+ // essential we do this before analysing the code
34
+ internal.set_building(true);
35
+
36
+ // analyse routes
37
+ for (const route of manifest._.routes) {
38
+ if (route.endpoint) {
39
+ const mod = await route.endpoint();
40
+ if (mod.prerender !== undefined) {
41
+ validate_server_exports(mod, route.id);
42
+
43
+ if (mod.prerender && (mod.POST || mod.PATCH || mod.PUT || mod.DELETE)) {
44
+ throw new Error(
45
+ `Cannot prerender a +server file with POST, PATCH, PUT, or DELETE (${route.id})`
46
+ );
47
+ }
48
+
49
+ prerender_map.set(route.id, mod.prerender);
50
+ }
51
+ }
52
+
53
+ if (route.page) {
54
+ const nodes = await Promise.all(
55
+ [...route.page.layouts, route.page.leaf].map((n) => {
56
+ if (n !== undefined) return manifest._.nodes[n]();
57
+ })
58
+ );
59
+
60
+ const layouts = nodes.slice(0, -1);
61
+ const page = nodes.at(-1);
62
+
63
+ for (const layout of layouts) {
64
+ if (layout) {
65
+ validate_common_exports(layout.server, route.id);
66
+ validate_common_exports(layout.universal, route.id);
67
+ }
68
+ }
69
+
70
+ if (page) {
71
+ validate_page_server_exports(page.server, route.id);
72
+ validate_common_exports(page.universal, route.id);
73
+ }
74
+
75
+ const should_prerender = get_option(nodes, 'prerender');
76
+ const prerender =
77
+ should_prerender === true ||
78
+ // Try prerendering if ssr is false and no server needed. Set it to 'auto' so that
79
+ // the route is not removed from the manifest, there could be a server load function.
80
+ // People can opt out of this behavior by explicitly setting prerender to false
81
+ (should_prerender !== false && get_option(nodes, 'ssr') === false && !page?.server?.actions
82
+ ? 'auto'
83
+ : should_prerender ?? false);
84
+
85
+ prerender_map.set(route.id, prerender);
86
+ }
87
+ }
88
+
89
+ const { prerendered } = await prerender({
90
+ Server,
91
+ internal,
92
+ manifest,
93
+ prerender_map,
94
+ client_out_dir,
95
+ verbose,
96
+ env
97
+ });
98
+
99
+ writeFileSync(
100
+ results_path,
101
+ JSON.stringify({ prerendered, prerender_map }, (_key, value) =>
102
+ value instanceof Map ? Array.from(value.entries()) : value
103
+ )
104
+ );
@@ -1,6 +1,6 @@
1
1
  import { readFileSync, writeFileSync } from 'fs';
2
2
  import { dirname, join } from 'path';
3
- import { pathToFileURL, URL } from 'url';
3
+ import { URL } from 'url';
4
4
  import { installPolyfills } from '../../exports/node/polyfills.js';
5
5
  import { mkdirp, posixify, walk } from '../../utils/filesystem.js';
6
6
  import { should_polyfill } from '../../utils/platform.js';
@@ -11,16 +11,6 @@ import { escape_html_attr } from '../../utils/escape.js';
11
11
  import { logger } from '../utils.js';
12
12
  import { load_config } from '../config/index.js';
13
13
  import { get_route_segments } from '../../utils/routing.js';
14
- import { get_option } from '../../runtime/server/utils.js';
15
- import {
16
- validate_common_exports,
17
- validate_page_server_exports,
18
- validate_server_exports
19
- } from '../../utils/exports.js';
20
-
21
- const [, , client_out_dir, manifest_path, results_path, verbose, env] = process.argv;
22
-
23
- prerender();
24
14
 
25
15
  /**
26
16
  * @template {{message: string}} T
@@ -52,22 +42,27 @@ const OK = 2;
52
42
  const REDIRECT = 3;
53
43
 
54
44
  /**
45
+ *
55
46
  * @param {{
56
- * prerendered: import('types').Prerendered;
47
+ * Server: typeof import('types').InternalServer;
48
+ * internal: import('types').ServerInternalModule;
49
+ * manifest: import('types').SSRManifest;
57
50
  * prerender_map: import('types').PrerenderMap;
58
- * }} data
51
+ * client_out_dir: string;
52
+ * verbose: string;
53
+ * env: string;
54
+ * }} opts
55
+ * @returns
59
56
  */
60
- const output_and_exit = (data) => {
61
- writeFileSync(
62
- results_path,
63
- JSON.stringify(data, (_key, value) =>
64
- value instanceof Map ? Array.from(value.entries()) : value
65
- )
66
- );
67
- process.exit(0);
68
- };
69
-
70
- export async function prerender() {
57
+ export async function prerender({
58
+ Server,
59
+ internal,
60
+ manifest,
61
+ prerender_map,
62
+ client_out_dir,
63
+ verbose,
64
+ env
65
+ }) {
71
66
  /** @type {import('types').Prerendered} */
72
67
  const prerendered = {
73
68
  pages: new Map(),
@@ -76,9 +71,6 @@ export async function prerender() {
76
71
  paths: []
77
72
  };
78
73
 
79
- /** @type {import('types').PrerenderMap} */
80
- const prerender_map = new Map();
81
-
82
74
  /** @type {Set<string>} */
83
75
  const prerendered_routes = new Set();
84
76
 
@@ -94,29 +86,10 @@ export async function prerender() {
94
86
  installPolyfills();
95
87
  }
96
88
 
97
- const server_root = join(config.outDir, 'output');
98
-
99
- /** @type {import('types').ServerModule} */
100
- const { Server, override } = await import(pathToFileURL(`${server_root}/server/index.js`).href);
101
-
102
- /** @type {import('types').SSRManifest} */
103
- const manifest = (await import(pathToFileURL(manifest_path).href)).manifest;
104
-
105
89
  /** @type {Map<string, string>} */
106
90
  const saved = new Map();
107
91
 
108
- override({
109
- building: true,
110
- paths: config.paths,
111
- read: (file) => {
112
- // stuff we just wrote
113
- const filepath = saved.get(file);
114
- if (filepath) return readFileSync(filepath);
115
-
116
- // stuff in `static`
117
- return readFileSync(join(config.files.assets, file));
118
- }
119
- });
92
+ internal.set_paths(config.paths);
120
93
 
121
94
  const server = new Server(manifest);
122
95
  await server.init({ env: JSON.parse(env) });
@@ -201,9 +174,19 @@ export async function prerender() {
201
174
  const dependencies = new Map();
202
175
 
203
176
  const response = await server.respond(new Request(config.prerender.origin + encoded), {
204
- getClientAddress,
177
+ getClientAddress() {
178
+ throw new Error('Cannot read clientAddress during prerendering');
179
+ },
205
180
  prerendering: {
206
181
  dependencies
182
+ },
183
+ read: (file) => {
184
+ // stuff we just wrote
185
+ const filepath = saved.get(file);
186
+ if (filepath) return readFileSync(filepath);
187
+
188
+ // stuff in `static`
189
+ return readFileSync(join(config.files.assets, file));
207
190
  }
208
191
  });
209
192
 
@@ -367,58 +350,6 @@ export async function prerender() {
367
350
  saved.set(file, dest);
368
351
  }
369
352
 
370
- for (const route of manifest._.routes) {
371
- if (route.endpoint) {
372
- const mod = await route.endpoint();
373
- if (mod.prerender !== undefined) {
374
- validate_server_exports(mod, route.id);
375
-
376
- if (mod.prerender && (mod.POST || mod.PATCH || mod.PUT || mod.DELETE)) {
377
- throw new Error(
378
- `Cannot prerender a +server file with POST, PATCH, PUT, or DELETE (${route.id})`
379
- );
380
- }
381
-
382
- prerender_map.set(route.id, mod.prerender);
383
- }
384
- }
385
-
386
- if (route.page) {
387
- const nodes = await Promise.all(
388
- [...route.page.layouts, route.page.leaf].map((n) => {
389
- if (n !== undefined) return manifest._.nodes[n]();
390
- })
391
- );
392
-
393
- const layouts = nodes.slice(0, -1);
394
- const page = nodes.at(-1);
395
-
396
- for (const layout of layouts) {
397
- if (layout) {
398
- validate_common_exports(layout.server, route.id);
399
- validate_common_exports(layout.universal, route.id);
400
- }
401
- }
402
-
403
- if (page) {
404
- validate_page_server_exports(page.server, route.id);
405
- validate_common_exports(page.universal, route.id);
406
- }
407
-
408
- const should_prerender = get_option(nodes, 'prerender');
409
- const prerender =
410
- should_prerender === true ||
411
- // Try prerendering if ssr is false and no server needed. Set it to 'auto' so that
412
- // the route is not removed from the manifest, there could be a server load function.
413
- // People can opt out of this behavior by explicitly setting prerender to false
414
- (should_prerender !== false && get_option(nodes, 'ssr') === false && !page?.server?.actions
415
- ? 'auto'
416
- : false);
417
-
418
- prerender_map.set(route.id, prerender);
419
- }
420
- }
421
-
422
353
  for (const entry of config.prerender.entries) {
423
354
  if (entry === '*') {
424
355
  for (const [id, prerender] of prerender_map) {
@@ -467,10 +398,5 @@ export async function prerender() {
467
398
  );
468
399
  }
469
400
 
470
- output_and_exit({ prerendered, prerender_map });
471
- }
472
-
473
- /** @return {string} */
474
- function getClientAddress() {
475
- throw new Error('Cannot read clientAddress during prerendering');
401
+ return { prerendered, prerender_map };
476
402
  }
File without changes
@@ -6,6 +6,7 @@ import { write_root } from './write_root.js';
6
6
  import { write_tsconfig } from './write_tsconfig.js';
7
7
  import { write_types, write_all_types } from './write_types/index.js';
8
8
  import { write_ambient } from './write_ambient.js';
9
+ import { write_server } from './write_server.js';
9
10
 
10
11
  /**
11
12
  * Initialize SvelteKit's generated files.
@@ -27,6 +28,7 @@ export async function create(config) {
27
28
  const output = path.join(config.kit.outDir, 'generated');
28
29
 
29
30
  write_client_manifest(config, manifest_data, output);
31
+ write_server(config, output);
30
32
  write_root(manifest_data, output);
31
33
  write_matchers(manifest_data, output);
32
34
  await write_all_types(config, manifest_data);
@@ -57,3 +59,11 @@ export async function all(config, mode) {
57
59
  init(config, mode);
58
60
  return await create(config);
59
61
  }
62
+
63
+ /**
64
+ * Regenerate server-internal.js in response to src/{app.html,error.html,service-worker.js} changing
65
+ * @param {import('types').ValidatedConfig} config
66
+ */
67
+ export function server(config) {
68
+ write_server(config, path.join(config.kit.outDir, 'generated'));
69
+ }
@@ -33,7 +33,7 @@ export function write_client_manifest(config, manifest_data, output) {
33
33
  }
34
34
 
35
35
  if (node.server) {
36
- declarations.push(`export const server = true;`);
36
+ declarations.push(`export const has_server_load = true;`);
37
37
  }
38
38
 
39
39
  return declarations.join('\n');
@@ -0,0 +1,89 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { posixify, resolve_entry } from '../../utils/filesystem.js';
4
+ import { s } from '../../utils/misc.js';
5
+ import { load_error_page, load_template } from '../config/index.js';
6
+ import { runtime_directory } from '../utils.js';
7
+
8
+ /**
9
+ * @param {{
10
+ * hooks: string | null;
11
+ * config: import('types').ValidatedConfig;
12
+ * has_service_worker: boolean;
13
+ * runtime_directory: string;
14
+ * template: string;
15
+ * error_page: string;
16
+ * }} opts
17
+ */
18
+ const server_template = ({
19
+ config,
20
+ hooks,
21
+ has_service_worker,
22
+ runtime_directory,
23
+ template,
24
+ error_page
25
+ }) => `
26
+ import root from './root.svelte';
27
+ import { set_building, set_paths, set_version } from '${runtime_directory}/shared.js';
28
+
29
+ set_paths(${s(config.kit.paths)});
30
+ set_version(${s(config.kit.version.name)});
31
+
32
+ export const options = {
33
+ csp: ${s(config.kit.csp)},
34
+ csrf_check_origin: ${s(config.kit.csrf.checkOrigin)},
35
+ embedded: ${config.kit.embedded},
36
+ env_public_prefix: '${config.kit.env.publicPrefix}',
37
+ hooks: null, // added lazily, via \`get_hooks\`
38
+ root,
39
+ service_worker: ${has_service_worker},
40
+ templates: {
41
+ app: ({ head, body, assets, nonce }) => ${s(template)
42
+ .replace('%sveltekit.head%', '" + head + "')
43
+ .replace('%sveltekit.body%', '" + body + "')
44
+ .replace(/%sveltekit\.assets%/g, '" + assets + "')
45
+ .replace(/%sveltekit\.nonce%/g, '" + nonce + "')},
46
+ error: ({ status, message }) => ${s(error_page)
47
+ .replace(/%sveltekit\.status%/g, '" + status + "')
48
+ .replace(/%sveltekit\.error\.message%/g, '" + message + "')}
49
+ }
50
+ };
51
+
52
+ export function get_hooks() {
53
+ return ${hooks ? `import(${s(hooks)})` : '{}'};
54
+ }
55
+
56
+ export { set_building, set_paths };
57
+ `;
58
+
59
+ // TODO need to re-run this whenever src/app.html or src/error.html are
60
+ // created or changed, or src/service-worker.js is created or deleted.
61
+ // Also, need to check that updating hooks.server.js works
62
+
63
+ /**
64
+ * Write server configuration to disk
65
+ * @param {import('types').ValidatedConfig} config
66
+ * @param {string} output
67
+ */
68
+ export function write_server(config, output) {
69
+ // TODO the casting shouldn't be necessary — investigate
70
+ const hooks_file = /** @type {string} */ (resolve_entry(config.kit.files.hooks.server));
71
+
72
+ /** @param {string} file */
73
+ function relative(file) {
74
+ return posixify(path.relative(output, file));
75
+ }
76
+
77
+ fs.writeFileSync(
78
+ `${output}/server-internal.js`,
79
+ server_template({
80
+ config,
81
+ hooks: fs.existsSync(hooks_file) ? relative(hooks_file) : null,
82
+ has_service_worker:
83
+ config.kit.serviceWorker.register && !!resolve_entry(config.kit.files.serviceWorker),
84
+ runtime_directory: relative(runtime_directory),
85
+ template: load_template(process.cwd(), config),
86
+ error_page: load_error_page(config)
87
+ })
88
+ );
89
+ }
package/src/core/utils.js CHANGED
@@ -13,9 +13,6 @@ import { posixify, to_fs } from '../utils/filesystem.js';
13
13
  */
14
14
  export const runtime_directory = posixify(fileURLToPath(new URL('../runtime', import.meta.url)));
15
15
 
16
- /** Prefix for the `runtime` directory, for use with import declarations */
17
- export const runtime_prefix = posixify_path(runtime_directory);
18
-
19
16
  /**
20
17
  * This allows us to import SvelteKit internals that aren't exposed via `pkg.exports` in a
21
18
  * way that works whether `@sveltejs/kit` is installed inside the project's `node_modules`
@@ -25,12 +22,6 @@ export const runtime_base = runtime_directory.startsWith(process.cwd())
25
22
  ? `/${path.relative('.', runtime_directory)}`
26
23
  : to_fs(runtime_directory);
27
24
 
28
- /** @param {string} str */
29
- function posixify_path(str) {
30
- const parsed = path.parse(str);
31
- return `/${parsed.dir.slice(parsed.root.length).split(path.sep).join('/')}/${parsed.base}`;
32
- }
33
-
34
25
  function noop() {}
35
26
 
36
27
  /** @param {{ verbose: boolean }} opts */