@sveltejs/kit 3.0.0-next.23 → 3.0.0-next.25

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 (105) hide show
  1. package/package.json +51 -8
  2. package/src/cli.js +3 -3
  3. package/src/constants.js +19 -1
  4. package/src/core/adapt/builder.js +3 -5
  5. package/src/core/env.js +137 -182
  6. package/src/core/postbuild/analyse.js +9 -4
  7. package/src/core/postbuild/prerender.js +5 -6
  8. package/src/core/sync/create_manifest_data/index.js +29 -33
  9. package/src/core/sync/sync.js +23 -40
  10. package/src/core/sync/write_app_manifest.js +83 -0
  11. package/src/core/sync/write_client_manifest.js +6 -4
  12. package/src/core/sync/write_server.js +12 -22
  13. package/src/core/sync/write_types/index.js +2 -2
  14. package/src/core/utils.js +10 -28
  15. package/src/exports/adapter.js +22 -0
  16. package/src/exports/hooks/public.d.ts +9 -1
  17. package/src/exports/node/index.js +77 -5
  18. package/src/exports/public.d.ts +1 -1
  19. package/src/exports/vite/build/build_server.js +3 -3
  20. package/src/exports/vite/build/service-worker.js +98 -0
  21. package/src/exports/vite/build/utils.js +48 -4
  22. package/src/exports/vite/dev/index.js +28 -25
  23. package/src/exports/vite/index.js +94 -747
  24. package/src/exports/vite/module_ids.js +1 -11
  25. package/src/exports/vite/plugins/env-vars.js +159 -0
  26. package/src/exports/vite/plugins/guard.js +205 -0
  27. package/src/exports/vite/preview/index.js +6 -4
  28. package/src/exports/vite/utils.js +99 -4
  29. package/src/runtime/app/env/{types.d.ts → client.js} +9 -4
  30. package/src/runtime/app/env/index.js +1 -2
  31. package/src/runtime/app/env/private/index.js +1 -0
  32. package/src/runtime/app/env/public/client.js +1 -1
  33. package/src/runtime/app/env/public/server.js +1 -1
  34. package/src/runtime/app/env/{internal.js → server.js} +4 -4
  35. package/src/runtime/app/forms/client.js +263 -0
  36. package/src/runtime/app/forms/index.js +1 -263
  37. package/src/runtime/app/forms/public.d.ts +1 -1
  38. package/src/runtime/app/forms/server.js +6 -0
  39. package/src/runtime/app/forms/shared.js +34 -0
  40. package/src/runtime/app/manifest/index.js +1 -1
  41. package/src/runtime/app/navigation/client.js +15 -0
  42. package/src/runtime/app/navigation/index.js +1 -15
  43. package/src/runtime/app/navigation/public.d.ts +1 -1
  44. package/src/runtime/app/navigation/server.js +15 -0
  45. package/src/runtime/app/paths/server.js +1 -1
  46. package/src/runtime/app/server/remote/form.js +11 -1
  47. package/src/runtime/app/server/remote/prerender.js +1 -2
  48. package/src/runtime/app/server/remote/query.js +3 -3
  49. package/src/runtime/app/state/client.svelte.js +207 -0
  50. package/src/runtime/app/state/index.js +1 -66
  51. package/src/runtime/app/state/public.d.ts +1 -1
  52. package/src/runtime/client/bundle.js +1 -1
  53. package/src/runtime/client/client.js +210 -278
  54. package/src/runtime/client/fetcher.js +18 -8
  55. package/src/runtime/client/remote-functions/form.svelte.js +9 -6
  56. package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
  57. package/src/runtime/client/remote-functions/query-live/iterator.js +1 -1
  58. package/src/runtime/client/remote-functions/shared.svelte.js +2 -2
  59. package/src/runtime/client/snapshots.js +1 -3
  60. package/src/runtime/client/stream.js +27 -20
  61. package/src/runtime/client/utils.js +7 -3
  62. package/src/runtime/components/root.svelte +5 -5
  63. package/src/runtime/env/dynamic/private.js +1 -1
  64. package/src/runtime/env/static/private.js +1 -1
  65. package/src/runtime/error-chain.js +54 -0
  66. package/src/runtime/form-utils.js +55 -87
  67. package/src/runtime/invalid-import.js +1 -0
  68. package/src/runtime/props.svelte.js +1 -1
  69. package/src/runtime/server/data/index.js +12 -27
  70. package/src/runtime/server/endpoint.js +8 -3
  71. package/src/runtime/server/env_module.js +1 -1
  72. package/src/runtime/server/errors.js +9 -12
  73. package/src/runtime/server/fetch.js +14 -16
  74. package/src/runtime/server/index.js +30 -27
  75. package/src/runtime/server/internal.js +34 -4
  76. package/src/runtime/server/page/actions.js +77 -124
  77. package/src/runtime/server/page/data_serializer.js +6 -10
  78. package/src/runtime/server/page/index.js +45 -82
  79. package/src/runtime/server/page/render.js +34 -52
  80. package/src/runtime/server/page/respond_with_error.js +7 -9
  81. package/src/runtime/server/remote-functions.js +138 -166
  82. package/src/runtime/server/respond.js +75 -30
  83. package/src/runtime/server/state.js +1 -0
  84. package/src/runtime/server/utils.js +0 -7
  85. package/src/runtime/utils.js +41 -0
  86. package/src/telemetry.js +1 -33
  87. package/src/types/ambient-private.d.ts +9 -17
  88. package/src/types/global-private.d.ts +8 -0
  89. package/src/types/internal.d.ts +27 -15
  90. package/src/types/private.d.ts +1 -1
  91. package/src/utils/exports.js +1 -0
  92. package/src/utils/filesystem.js +10 -22
  93. package/src/utils/functions.js +10 -0
  94. package/src/utils/routing.js +0 -11
  95. package/src/utils/streaming.js +5 -15
  96. package/src/utils/url.js +0 -11
  97. package/src/version.js +1 -1
  98. package/types/index.d.ts +54 -29
  99. package/types/index.d.ts.map +10 -5
  100. package/src/runtime/app/env/private.js +0 -1
  101. package/src/runtime/app/env/standard-schema.d.ts +0 -0
  102. package/src/runtime/app/state/client.js +0 -63
  103. package/src/runtime/client/state.svelte.js +0 -98
  104. package/src/runtime/server/ambient.d.ts +0 -4
  105. package/src/utils/path.js +0 -23
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "3.0.0-next.23",
3
+ "version": "3.0.0-next.25",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
@@ -72,19 +72,54 @@
72
72
  "svelte-kit.js"
73
73
  ],
74
74
  "imports": {
75
+ "#app/env": {
76
+ "types": "./src/runtime/app/env/client.js",
77
+ "workerd": "./src/runtime/app/env/server.js",
78
+ "browser": "./src/runtime/app/env/client.js",
79
+ "default": "./src/runtime/app/env/server.js"
80
+ },
81
+ "#app/env/public": {
82
+ "workerd": "./src/runtime/app/env/public/server.js",
83
+ "browser": "./src/runtime/app/env/public/client.js",
84
+ "default": "./src/runtime/app/env/public/server.js"
85
+ },
86
+ "#app/env/server": {
87
+ "workerd": "./src/runtime/app/env/server.js",
88
+ "browser": "./src/runtime/invalid-import.js",
89
+ "default": "./src/runtime/app/env/server.js"
90
+ },
91
+ "#app/forms": {
92
+ "types": "./src/runtime/app/forms/client.js",
93
+ "workerd": "./src/runtime/app/forms/server.js",
94
+ "browser": "./src/runtime/app/forms/client.js",
95
+ "default": "./src/runtime/app/forms/server.js"
96
+ },
75
97
  "#app/internal/transport": {
76
98
  "default": "./src/runtime/app/internal/transport.js"
77
99
  },
100
+ "#app/navigation": {
101
+ "types": "./src/runtime/app/navigation/client.js",
102
+ "workerd": "./src/runtime/app/navigation/server.js",
103
+ "browser": "./src/runtime/app/navigation/client.js",
104
+ "default": "./src/runtime/app/navigation/server.js"
105
+ },
78
106
  "#app/paths": {
79
107
  "types": "./src/runtime/app/paths/internal.d.ts",
80
108
  "workerd": "./src/runtime/app/paths/server.js",
81
109
  "browser": "./src/runtime/app/paths/client.js",
82
110
  "default": "./src/runtime/app/paths/server.js"
83
111
  },
84
- "#app/env/public": {
85
- "workerd": "./src/runtime/app/env/public/server.js",
86
- "browser": "./src/runtime/app/env/public/client.js",
87
- "default": "./src/runtime/app/env/public/server.js"
112
+ "#app/state": {
113
+ "types": "./src/runtime/app/state/client.svelte.js",
114
+ "workerd": "./src/runtime/app/state/server.js",
115
+ "browser": "./src/runtime/app/state/client.svelte.js",
116
+ "default": "./src/runtime/app/state/server.js"
117
+ },
118
+ "#app/state/client": {
119
+ "types": "./src/runtime/app/state/client.svelte.js",
120
+ "workerd": "./src/runtime/invalid-import.js",
121
+ "browser": "./src/runtime/app/state/client.svelte.js",
122
+ "default": "./src/runtime/invalid-import.js"
88
123
  },
89
124
  "#internal": {
90
125
  "workerd": "./src/exports/internal/server/index.js",
@@ -113,6 +148,10 @@
113
148
  "types": "./types/index.d.ts",
114
149
  "import": "./src/exports/internal/server/index.js"
115
150
  },
151
+ "./adapter": {
152
+ "types": "./types/index.d.ts",
153
+ "import": "./src/exports/adapter.js"
154
+ },
116
155
  "./node": {
117
156
  "types": "./types/index.d.ts",
118
157
  "import": "./src/exports/node/index.js"
@@ -145,9 +184,13 @@
145
184
  "format": "oxfmt --write .",
146
185
  "test": "pnpm test:unit && pnpm test:integration",
147
186
  "test:integration": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test",
148
- "test:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:dev",
149
- "test:build": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:build",
150
- "test:cross-platform:dev": "pnpm test:unit && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:cross-platform:dev",
187
+ "test:dev": "pnpm -r --workspace-concurrency 2 --filter=\"./test/**\" test:dev",
188
+ "test:build": "pnpm -r --workspace-concurrency 2 --filter=\"./test/**\" test:build",
189
+ "test:dev:basics": "pnpm --filter=test-basics test:dev",
190
+ "test:dev:rest": "pnpm -r --workspace-concurrency 2 --filter=\"./test/**\" --filter=\"!test-basics\" test:dev",
191
+ "test:build:basics": "pnpm --filter=test-basics test:build",
192
+ "test:build:rest": "pnpm -r --workspace-concurrency 2 --filter=\"./test/**\" --filter=\"!test-basics\" test:build",
193
+ "test:cross-platform:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:cross-platform:dev",
151
194
  "test:cross-platform:build": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:cross-platform:build",
152
195
  "test:server-side-route-resolution:dev": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:server-side-route-resolution:dev",
153
196
  "test:server-side-route-resolution:build": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test:server-side-route-resolution:build",
package/src/cli.js CHANGED
@@ -2,9 +2,9 @@ import fs from 'node:fs';
2
2
  import process from 'node:process';
3
3
  import { parseArgs, styleText } from 'node:util';
4
4
  import { extract_svelte_config, load_vite_config } from './core/config/index.js';
5
- import { resolve_explicit_env_entry } from './core/env.js';
6
5
  import { coalesce_to_error } from './utils/error.js';
7
6
  import { import_peer } from './utils/import.js';
7
+ import { resolve_env_entry } from './core/env.js';
8
8
 
9
9
  /** @param {unknown} e */
10
10
  function handle_error(e) {
@@ -105,8 +105,8 @@ if (command === 'sync') {
105
105
  const sync = await import('./core/sync/sync.js');
106
106
  sync.all_types(sveltekit_config, vite_config.root);
107
107
 
108
- const explicit_env_entry = resolve_explicit_env_entry(sveltekit_config);
109
- await sync.env(vite, sveltekit_config, explicit_env_entry, vite_config.root, values.mode);
108
+ const entry = resolve_env_entry(sveltekit_config, vite_config.root);
109
+ await sync.env(sveltekit_config, entry, vite_config.root, values.mode);
110
110
  } catch (error) {
111
111
  handle_error(error);
112
112
  } finally {
package/src/constants.js CHANGED
@@ -6,13 +6,31 @@ export const SVELTE_KIT_ASSETS = '/_svelte_kit_assets';
6
6
 
7
7
  export const GENERATED_COMMENT = '// this file is generated — do not edit it';
8
8
 
9
- export const ENDPOINT_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'];
9
+ export const ENDPOINT_METHODS = [
10
+ 'GET',
11
+ 'POST',
12
+ 'PUT',
13
+ 'PATCH',
14
+ 'DELETE',
15
+ 'OPTIONS',
16
+ 'HEAD',
17
+ 'QUERY'
18
+ ];
10
19
 
11
20
  export const MUTATIVE_METHODS = ['POST', 'PUT', 'PATCH', 'DELETE'];
12
21
 
22
+ /** methods whose responses depend on the request body, so they can never be prerendered */
23
+ export const BODY_DEPENDENT_METHODS = [...MUTATIVE_METHODS, 'QUERY'];
24
+
13
25
  export const PAGE_METHODS = ['GET', 'POST', 'HEAD'];
14
26
 
15
27
  export const SRC_ROOT = import.meta.dirname;
16
28
 
17
29
  // eslint-disable-next-line n/prefer-global/process
18
30
  export const IN_WEBCONTAINER = !!globalThis.process?.versions?.webcontainer;
31
+
32
+ /**
33
+ * If an an adapter deploys a catch-all serverless function, the rerouted URL
34
+ * is stored in this header.
35
+ */
36
+ export const REROUTED_URL_HEADER = 'x-sveltekit-rerouted-url';
@@ -1,7 +1,6 @@
1
1
  /** @import { StandardSchemaV1 } from '@standard-schema/spec' */
2
- /** @import { Builder } from '@sveltejs/kit' */
3
2
  /** @import { ResolvedConfig } from 'vite' */
4
- /** @import { RouteDefinition } from '@sveltejs/kit' */
3
+ /** @import { Builder, RouteDefinition } from '@sveltejs/kit' */
5
4
  /** @import { EnvVarConfig } from '@sveltejs/kit/env' */
6
5
  /** @import { RouteData, ValidatedConfig, BuildData, ServerMetadata, ServerMetadataRoute, Prerendered, PrerenderMap, Logger, RemoteChunk } from 'types' */
7
6
  import { loadEnv } from 'vite';
@@ -18,13 +17,12 @@ import { extname, resolve, join, dirname, relative } from 'node:path';
18
17
  import { pipeline } from 'node:stream';
19
18
  import { promisify } from 'node:util';
20
19
  import zlib from 'node:zlib';
21
- import { copy } from '../../utils/filesystem.js';
20
+ import { copy, walk } from '../../utils/filesystem.js';
22
21
  import { posixify } from '../../utils/os.js';
23
22
  import { generate_manifest } from '../generate_manifest/index.js';
24
23
  import { get_route_segments } from '../../utils/routing.js';
25
24
  import generate_fallback from '../postbuild/fallback.js';
26
25
  import { write } from '../sync/utils.js';
27
- import { list_files } from '../utils.js';
28
26
  import { find_server_assets } from '../generate_manifest/find_server_assets.js';
29
27
  import { create_exported_declarations } from '../env.js';
30
28
  import { handle_issues, validate } from '../../exports/internal/env.js';
@@ -120,7 +118,7 @@ export function create_builder({
120
118
  return [];
121
119
  }
122
120
 
123
- const files = list_files(directory, (file) => extensions.includes(extname(file)));
121
+ const files = [...walk(directory)].filter((file) => extensions.includes(extname(file)));
124
122
 
125
123
  await Promise.all(
126
124
  files.flatMap((file) => {
package/src/core/env.js CHANGED
@@ -3,13 +3,14 @@
3
3
  /** @import { ValidatedConfig } from 'types' */
4
4
  import path from 'node:path';
5
5
  import * as devalue from 'devalue';
6
- import { GENERATED_COMMENT } from '../constants.js';
7
6
  import { dedent } from './sync/utils.js';
8
- import { runtime_directory } from './utils.js';
7
+ import { get_global_name, runtime_directory } from './utils.js';
9
8
  import { resolve_entry } from '../utils/filesystem.js';
10
9
  import { handle_issues, validate } from '../exports/internal/env.js';
11
10
  import { get_config_aliases } from '../exports/vite/utils.js';
12
11
  import { get_runner } from '../runner.js';
12
+ import { import_peer } from '../utils/import.js';
13
+ import { posixify } from '../utils/os.js';
13
14
 
14
15
  /**
15
16
  * @typedef {'public' | 'private'} EnvType
@@ -17,37 +18,55 @@ import { get_runner } from '../runner.js';
17
18
 
18
19
  /**
19
20
  * @param {ValidatedConfig} config
21
+ * @param {string} root
20
22
  * @returns {string | null}
21
23
  */
22
- export function resolve_explicit_env_entry(config) {
23
- return resolve_entry(path.join(config.files.src, 'env')) ?? null;
24
+ export function resolve_env_entry(config, root) {
25
+ return resolve_entry(path.resolve(root, config.files.src, 'env'));
24
26
  }
25
27
 
26
28
  /**
27
- * @param {typeof import('vite')} vite
28
29
  * @param {ValidatedConfig} kit
29
30
  * @param {string | null} file
30
31
  * @param {string} root
31
32
  * @param {string} mode
32
- * @returns {Promise<Record<string, EnvVarConfig<any>> | null>}
33
+ * @returns {Promise<{ variables: Record<string, EnvVarConfig<any>> | null, deps: Set<string> }>}
33
34
  */
34
- export async function load_explicit_env(vite, kit, file, root, mode) {
35
- if (!file) return null;
35
+ export async function load_explicit_env(kit, file, root, mode) {
36
+ /** @type {Set<string>} */
37
+ const deps = new Set();
38
+
39
+ if (!file) {
40
+ return { variables: null, deps };
41
+ }
42
+
43
+ /** @type {typeof import('vite')} */
44
+ const vite = await import_peer('vite', root);
36
45
 
37
46
  const server = await vite.createServer({
38
47
  configFile: false,
39
48
  logLevel: 'silent',
40
49
  mode,
41
50
  define: {
42
- __SVELTEKIT_PAYLOAD__: 'undefined', // coming in through static import in env/internal.js but will end up unused
43
- __SVELTEKIT_APP_VERSION__: JSON.stringify(kit.version.name) // needed by $app/env
51
+ // these are needed by $app/env
52
+ __SVELTEKIT_APP_VERSION__: JSON.stringify(kit.version.name),
53
+ __SVELTEKIT_DEV__: mode === 'development',
54
+ __SVELTEKIT_PAYLOAD__: 'undefined' // coming in through static import in env/internal.js but will end up unused
44
55
  },
45
56
  resolve: {
46
57
  alias: [
47
58
  { find: '$app/env', replacement: `${runtime_directory}/app/env` },
48
59
  ...get_config_aliases(kit, root)
49
60
  ]
50
- }
61
+ },
62
+ plugins: [
63
+ {
64
+ name: 'dependency-scanner',
65
+ load(id) {
66
+ deps.add(id);
67
+ }
68
+ }
69
+ ]
51
70
  });
52
71
 
53
72
  /** @type {Record<string, EnvVarConfig<any>>} */
@@ -55,8 +74,8 @@ export async function load_explicit_env(vite, kit, file, root, mode) {
55
74
 
56
75
  const runner = get_runner(vite, server);
57
76
 
58
- /** @type {typeof import('../runtime/app/env/internal.js')} */ (
59
- await runner.import(`${runtime_directory}/app/env/internal.js`)
77
+ /** @type {typeof import('../runtime/app/env/server.js')} */ (
78
+ await runner.import(`${runtime_directory}/app/env/server.js`)
60
79
  ).set_building();
61
80
 
62
81
  try {
@@ -90,44 +109,68 @@ export async function load_explicit_env(vite, kit, file, root, mode) {
90
109
  await server.close();
91
110
  }
92
111
 
93
- return variables;
112
+ return { variables, deps };
94
113
  }
95
114
 
96
115
  /**
97
- * Creates the `__sveltekit/env` module
98
- * @param {Record<string, EnvVarConfig<any> | undefined> | null} variables
116
+ * Creates the `<sveltekit:generated>/env/*` modules, keyed by path relative to `dir`. Every module
117
+ * derives from one pass over `variables`, so an inlined value is validated once per build.
118
+ * @param {ValidatedConfig} config
119
+ * @param {Record<string, EnvVarConfig<any>> | null} variables
99
120
  * @param {Record<string, string>} env
121
+ * @param {string} dir
100
122
  * @param {string | null} entry
101
123
  * @param {boolean} is_dev
124
+ * @returns {Record<string, string>}
102
125
  */
103
- export function create_sveltekit_env(variables, env, entry, is_dev) {
104
- const imports = entry
105
- ? [
106
- `import { variables } from ${JSON.stringify(entry)};`,
107
- `import { validate, handle_issues } from '@sveltejs/kit/internal/env';`
108
- ]
109
- : [`const variables = {};`, `const handle_issues = () => {};`];
126
+ export function create_env_modules(config, variables, env, dir, entry, is_dev) {
127
+ /** @type {Record<string, StandardSchemaV1.Issue[]>} */
128
+ const issues = {};
129
+
130
+ /** @type {Record<string, string>} */
131
+ const dev_env = {};
110
132
 
133
+ /** @type {string[]} */
111
134
  const declarations = [];
135
+ /** @type {string[]} */
112
136
  const setters = [];
137
+ /** @type {string[]} */
138
+ const public_exports = [];
139
+ /** @type {string[]} */
140
+ const private_exports = [];
141
+ /** @type {string[]} */
142
+ const sw_properties = [];
113
143
 
114
- /** @type {Record<string, StandardSchemaV1.Issue[]>} */
115
- const issues = {};
144
+ let sw_dynamic = false;
145
+
146
+ for (const [name, { public: is_public, static: is_static }] of Object.entries(variables ?? {})) {
147
+ if (is_dev && name in env) dev_env[name] = env[name];
148
+
149
+ const exports = is_public ? public_exports : private_exports;
150
+
151
+ if (is_static) {
152
+ const value = devalue.uneval(validate(variables ?? {}, env[name], name, issues));
153
+ exports.push(`export const ${name} = ${value};\n`);
116
154
 
117
- for (const [name, config] of Object.entries(variables ?? {})) {
118
- if (config?.static) {
119
- if (config.public) {
120
- const value = validate(variables ?? {}, env[name], name, issues);
121
- declarations.push(`explicit_public_env.${name} = ${devalue.uneval(value)};`);
155
+ if (is_public) {
156
+ declarations.push(`explicit_public_env.${name} = ${value};`);
157
+ sw_properties.push(`${name}: ${value}`);
122
158
  }
123
159
  } else {
160
+ exports.push(`export const ${name} = env.${name};\n`);
124
161
  setters.push(
125
162
  `const ${name} = validate(variables, env.${name}, ${JSON.stringify(name)}, issues);`
126
163
  );
127
164
 
128
- if (config?.public) {
165
+ if (is_public) {
129
166
  setters.push(`explicit_public_env.${name} = ${name};`);
130
167
  setters.push(`rendered_env.${name} = ${name};`);
168
+ sw_dynamic = true;
169
+ // in dev there is no prerendered env module, so the service worker inlines the value
170
+ if (is_dev) {
171
+ const value = devalue.uneval(validate(variables ?? {}, env[name], name, issues));
172
+ sw_properties.push(`${name}: ${value}`);
173
+ }
131
174
  } else {
132
175
  setters.push(`dynamic_private_env.${name} = ${name};`);
133
176
  }
@@ -136,9 +179,13 @@ export function create_sveltekit_env(variables, env, entry, is_dev) {
136
179
 
137
180
  handle_issues(issues);
138
181
 
139
- const blocks = [
140
- GENERATED_COMMENT,
141
- imports.join('\n'),
182
+ const config_blocks = [
183
+ entry
184
+ ? [
185
+ `import { variables } from ${JSON.stringify(entry)};`,
186
+ `import { validate, handle_issues } from '@sveltejs/kit/internal/env';`
187
+ ].join('\n')
188
+ : [`const variables = {};`, `const handle_issues = () => {};`].join('\n'),
142
189
  `const issues = {};`,
143
190
  'export { variables }',
144
191
  'export const dynamic_private_env = {};',
@@ -154,157 +201,65 @@ export function create_sveltekit_env(variables, env, entry, is_dev) {
154
201
  }`
155
202
  ];
156
203
 
157
- // In dev, initialise the env immediately. Tools like `vite-node` load modules
158
- // through the Vite config but don't run the SvelteKit dev server, which is what
159
- // normally calls `set_env`. Without this, dynamic env vars imported from
160
- // `$app/env/public` and `$app/env/private` would be `undefined` in such contexts.
161
204
  if (is_dev) {
162
- /** @type {Record<string, string>} */
163
- const dev_env = {};
164
- for (const name of Object.keys(variables ?? {})) {
165
- if (name in env) dev_env[name] = env[name];
166
- }
167
- blocks.push(`set_env(${devalue.uneval(dev_env)});`);
168
- }
169
-
170
- const module = blocks.join('\n\n');
171
-
172
- return module;
173
- }
174
-
175
- /**
176
- * Creates the `__sveltekit/env/private` module
177
- * @param {Record<string, EnvVarConfig<any>> | null} variables
178
- * @param {Record<string, string>} env
179
- */
180
- export function create_sveltekit_env_private(variables, env) {
181
- if (!variables) {
182
- return '';
205
+ // In dev, initialise the env immediately. Tools like `vite-node` load modules
206
+ // through the Vite config but don't run the SvelteKit dev server, which is what
207
+ // normally calls `set_env`. Without this, dynamic env vars imported from
208
+ // `$app/env/public` and `$app/env/private` would be `undefined` in such contexts.
209
+ config_blocks.push(`set_env(${devalue.uneval(dev_env)});`);
183
210
  }
184
211
 
185
- /** @type {Record<string, StandardSchemaV1.Issue[]>} */
186
- const issues = {};
187
-
188
- /** @type {string[]} */
189
- const exports = [];
190
-
191
- for (const [name, config] of Object.entries(variables)) {
192
- if (config.public) continue;
193
-
194
- const value = config.static
195
- ? devalue.uneval(validate(variables, env[name], name, issues))
196
- : `env.${name}`;
197
-
198
- exports.push(`export const ${name} = ${value};\n`);
199
- }
200
-
201
- handle_issues(issues);
202
-
203
- return `import { dynamic_private_env as env } from '__sveltekit/env';\n\n${exports.join('')}`;
204
- }
205
-
206
- /**
207
- * Creates the `__sveltekit/env/public/*` modules
208
- * @param {Record<string, EnvVarConfig<any>> | null} variables
209
- * @param {Record<string, string>} env
210
- * @param {string} prelude
211
- */
212
- export function create_sveltekit_env_public(variables, env, prelude) {
213
- if (!variables) {
214
- return '';
215
- }
216
-
217
- /** @type {Record<string, StandardSchemaV1.Issue[]>} */
218
- const issues = {};
219
-
220
- /** @type {string[]} */
221
- const exports = [];
222
-
223
- for (const [name, config] of Object.entries(variables)) {
224
- if (!config.public) continue;
225
-
226
- const value = config.static
227
- ? devalue.uneval(validate(variables, env[name], name, issues))
228
- : `env.${name}`;
229
-
230
- exports.push(`export const ${name} = ${value};\n`);
231
- }
232
-
233
- handle_issues(issues);
234
-
235
- return `${prelude}\n\n${exports.join('')}`;
236
- }
237
-
238
- /**
239
- * Creates the `__sveltekit/env/service-worker` module used in production. When an app uses
240
- * dynamic public env vars, they're loaded at runtime via an import of the prerendered
241
- * `env.js`. If there are none, values are inlined.
242
- * @param {Record<string, EnvVarConfig<any>> | null} variables
243
- * @param {Record<string, string>} env
244
- * @param {string} version
245
- * @param {string} global
246
- * @param {string} base
247
- * @param {string} app_dir
248
- */
249
- export function create_sveltekit_env_service_worker(
250
- variables,
251
- env,
252
- version,
253
- global,
254
- base,
255
- app_dir
256
- ) {
257
- const has_dynamic_public_env = Object.values(variables ?? {}).some(
258
- (config) => config.public && !config.static
259
- );
260
-
261
- if (!has_dynamic_public_env) {
262
- return create_sveltekit_env_service_worker_dev(variables, env, version, global);
263
- }
264
-
265
- return dedent`
266
- import { env } from '${base}/${app_dir}/env.js';
267
-
268
- ${global} = {
269
- base: location.pathname.split('/').slice(0, -1).join('/'),
270
- env,
271
- version: ${JSON.stringify(version)}
272
- };
273
- `;
274
- }
275
-
276
- /**
277
- * Creates the `__sveltekit/env/service-worker` module used in development
278
- * @param {Record<string, EnvVarConfig<any>> | null} variables
279
- * @param {Record<string, string>} env
280
- * @param {string} version
281
- * @param {string} global
282
- */
283
- export function create_sveltekit_env_service_worker_dev(variables, env, version, global) {
284
- /** @type {string[]} */
285
- const properties = [];
286
-
287
- /** @type {Record<string, StandardSchemaV1.Issue[]>} */
288
- const issues = {};
289
-
290
- for (const [name, config] of Object.entries(variables ?? {})) {
291
- if (!config.public) continue;
292
-
293
- const value = validate(variables ?? {}, env[name], name, issues);
294
- properties.push(`${name}: ${devalue.uneval(value)}`);
295
- }
296
-
297
- handle_issues(issues);
298
-
299
- return dedent`
300
- ${global} = {
301
- base: location.pathname.split('/').slice(0, -1).join('/'),
302
- env: {
303
- ${properties.join(',\n\t\t') || '// empty'}
304
- },
305
- version: ${JSON.stringify(version)}
306
- };
307
- `;
212
+ /**
213
+ * @param {string} prelude
214
+ * @param {string[]} exports
215
+ */
216
+ const module = (prelude, exports) => (variables ? `${prelude}\n\n${exports.join('')}` : '');
217
+
218
+ const global = `globalThis.${get_global_name(config.version.name, is_dev)}`;
219
+
220
+ const version = JSON.stringify(config.version.name);
221
+
222
+ // a production build with dynamic public env vars loads them at runtime via an import of
223
+ // the prerendered `env.js`; otherwise the values are inlined
224
+ const service_worker =
225
+ !is_dev && sw_dynamic
226
+ ? dedent`
227
+ import { env } from '${config.paths.base}/${config.appDir}/env.js';
228
+
229
+ ${global} = {
230
+ base: location.pathname.split('/').slice(0, -1).join('/'),
231
+ env,
232
+ version: ${version}
233
+ };
234
+ `
235
+ : dedent`
236
+ ${global} = {
237
+ base: location.pathname.split('/').slice(0, -1).join('/'),
238
+ env: {
239
+ ${sw_properties.join(',\n\t\t') || '// empty'}
240
+ },
241
+ version: ${version}
242
+ };
243
+ `;
244
+
245
+ return {
246
+ 'config.js': config_blocks.join('\n\n'),
247
+ 'public/server.js': module(
248
+ `import { rendered_env as env } from '../config.js';`,
249
+ public_exports
250
+ ),
251
+ 'private/server.js': module(
252
+ `import { dynamic_private_env as env } from '../config.js';`,
253
+ private_exports
254
+ ),
255
+ 'public/client.js': module(
256
+ is_dev
257
+ ? `const { env } = ${global};`
258
+ : `import { payload } from ${JSON.stringify(posixify(path.relative(`${dir}/public`, `${runtime_directory}/client/payload.js`)))};\nconst env = payload.env;`,
259
+ public_exports
260
+ ),
261
+ 'service-worker.js': service_worker
262
+ };
308
263
  }
309
264
 
310
265
  /** @param {string} description */
@@ -4,7 +4,7 @@ import { pathToFileURL } from 'node:url';
4
4
  import { validate_server_exports } from '../../utils/exports.js';
5
5
  import { extract_svelte_config, load_vite_config } from '../config/index.js';
6
6
  import { forked } from '../../utils/fork.js';
7
- import { ENDPOINT_METHODS } from '../../constants.js';
7
+ import { BODY_DEPENDENT_METHODS, ENDPOINT_METHODS } from '../../constants.js';
8
8
  import { has_server_load, resolve_route } from '../../utils/routing.js';
9
9
  import { check_feature } from '../../utils/features.js';
10
10
  import { createReadableStream } from '@sveltejs/kit/node';
@@ -54,7 +54,7 @@ async function analyse({
54
54
 
55
55
  // `set_env` lives in a separate module that imports the user's `src/env` config. We import it
56
56
  // *after* `set_building()` so that `building`-dependent expressions resolve correctly
57
- /** @type {typeof import('__sveltekit/env')} */
57
+ /** @type {typeof import('<sveltekit:generated>/env/config.js')} */
58
58
  const { set_env } = await import(pathToFileURL(`${server_root}/server/env.js`).href);
59
59
  set_env(env);
60
60
 
@@ -175,9 +175,14 @@ async function analyse({
175
175
  function analyse_endpoint(route, mod) {
176
176
  validate_server_exports(mod, route.id);
177
177
 
178
- if (mod.prerender && (mod.POST || mod.PATCH || mod.PUT || mod.DELETE)) {
178
+ if (
179
+ mod.prerender &&
180
+ /** @type {import('types').HttpMethod[]} */ (BODY_DEPENDENT_METHODS).some(
181
+ (method) => mod[method]
182
+ )
183
+ ) {
179
184
  throw new Error(
180
- `Cannot prerender a +server file with POST, PATCH, PUT, or DELETE (${route.id})`
185
+ `Cannot prerender a +server file with ${BODY_DEPENDENT_METHODS.join(', ')} handlers (${route.id})`
181
186
  );
182
187
  }
183
188