@sveltejs/kit 3.0.0-next.22 → 3.0.0-next.24

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 (106) hide show
  1. package/package.json +40 -9
  2. package/src/cli.js +3 -3
  3. package/src/constants.js +13 -1
  4. package/src/core/adapt/builder.js +2 -3
  5. package/src/core/env.js +139 -181
  6. package/src/core/postbuild/analyse.js +9 -4
  7. package/src/core/postbuild/prerender.js +22 -23
  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 +10 -6
  13. package/src/core/sync/write_types/index.js +2 -2
  14. package/src/core/utils.js +0 -28
  15. package/src/exports/hooks/public.d.ts +9 -1
  16. package/src/exports/index.js +10 -0
  17. package/src/exports/node/index.js +77 -5
  18. package/src/exports/public.d.ts +9 -0
  19. package/src/exports/vite/build/build_server.js +3 -3
  20. package/src/exports/vite/build/utils.js +48 -4
  21. package/src/exports/vite/dev/index.js +11 -22
  22. package/src/exports/vite/index.js +62 -345
  23. package/src/exports/vite/module_ids.js +1 -11
  24. package/src/exports/vite/plugins/env-vars.js +117 -0
  25. package/src/exports/vite/preview/index.js +6 -4
  26. package/src/exports/vite/utils.js +2 -4
  27. package/src/runtime/app/env/{types.d.ts → client.js} +9 -4
  28. package/src/runtime/app/env/index.js +1 -2
  29. package/src/runtime/app/env/private/index.js +1 -0
  30. package/src/runtime/app/env/public/client.js +1 -1
  31. package/src/runtime/app/env/public/server.js +1 -1
  32. package/src/runtime/app/env/{internal.js → server.js} +4 -4
  33. package/src/runtime/app/forms/client.js +263 -0
  34. package/src/runtime/app/forms/index.js +1 -263
  35. package/src/runtime/app/forms/public.d.ts +1 -1
  36. package/src/runtime/app/forms/server.js +6 -0
  37. package/src/runtime/app/forms/shared.js +34 -0
  38. package/src/runtime/app/manifest/index.js +1 -1
  39. package/src/runtime/app/navigation/client.js +15 -0
  40. package/src/runtime/app/navigation/index.js +1 -15
  41. package/src/runtime/app/navigation/public.d.ts +1 -1
  42. package/src/runtime/app/navigation/server.js +15 -0
  43. package/src/runtime/app/paths/server.js +1 -1
  44. package/src/runtime/app/server/public.d.ts +512 -0
  45. package/src/runtime/app/server/remote/command.js +1 -1
  46. package/src/runtime/app/server/remote/form.js +16 -6
  47. package/src/runtime/app/server/remote/prerender.js +2 -3
  48. package/src/runtime/app/server/remote/query.js +2 -2
  49. package/src/runtime/app/server/remote/requested.js +3 -3
  50. package/src/runtime/app/state/client.svelte.js +207 -0
  51. package/src/runtime/app/state/index.js +1 -66
  52. package/src/runtime/app/state/public.d.ts +1 -1
  53. package/src/runtime/client/bundle.js +1 -1
  54. package/src/runtime/client/client.js +206 -274
  55. package/src/runtime/client/fetcher.js +18 -8
  56. package/src/runtime/client/remote-functions/command.svelte.js +1 -1
  57. package/src/runtime/client/remote-functions/form.svelte.js +10 -7
  58. package/src/runtime/client/remote-functions/prerender.svelte.js +2 -2
  59. package/src/runtime/client/remote-functions/query/index.js +1 -1
  60. package/src/runtime/client/remote-functions/query/instance.svelte.js +2 -1
  61. package/src/runtime/client/remote-functions/query-batch.svelte.js +1 -1
  62. package/src/runtime/client/remote-functions/query-live/index.js +1 -1
  63. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +4 -3
  64. package/src/runtime/client/remote-functions/query-live/iterator.js +1 -1
  65. package/src/runtime/client/remote-functions/shared.svelte.js +3 -3
  66. package/src/runtime/client/snapshots.js +1 -3
  67. package/src/runtime/client/stream.js +27 -20
  68. package/src/runtime/client/utils.js +7 -3
  69. package/src/runtime/components/root.svelte +5 -5
  70. package/src/runtime/env/dynamic/private.js +1 -1
  71. package/src/runtime/env/static/private.js +1 -1
  72. package/src/runtime/error-chain.js +54 -0
  73. package/src/runtime/form-utils.js +53 -77
  74. package/src/runtime/invalid-import.js +1 -0
  75. package/src/runtime/props.svelte.js +1 -1
  76. package/src/runtime/server/data/index.js +1 -1
  77. package/src/runtime/server/endpoint.js +8 -3
  78. package/src/runtime/server/env_module.js +1 -1
  79. package/src/runtime/server/errors.js +2 -2
  80. package/src/runtime/server/index.js +2 -2
  81. package/src/runtime/server/page/actions.js +77 -122
  82. package/src/runtime/server/page/index.js +37 -69
  83. package/src/runtime/server/page/render.js +18 -23
  84. package/src/runtime/server/remote-functions.js +15 -43
  85. package/src/runtime/server/respond.js +23 -3
  86. package/src/telemetry.js +1 -33
  87. package/src/types/ambient-private.d.ts +9 -17
  88. package/src/types/internal.d.ts +21 -5
  89. package/src/types/private.d.ts +1 -1
  90. package/src/utils/exports.js +1 -0
  91. package/src/utils/filesystem.js +9 -21
  92. package/src/utils/functions.js +10 -0
  93. package/src/utils/promise.js +25 -0
  94. package/src/utils/routing.js +0 -11
  95. package/src/utils/url.js +0 -11
  96. package/src/version.js +1 -1
  97. package/types/index.d.ts +1134 -1136
  98. package/types/index.d.ts.map +50 -50
  99. package/src/exports/remote/index.js +0 -11
  100. package/src/exports/remote/public.d.ts +0 -519
  101. package/src/runtime/app/env/private.js +0 -1
  102. package/src/runtime/app/env/standard-schema.d.ts +0 -0
  103. package/src/runtime/app/state/client.js +0 -63
  104. package/src/runtime/client/state.svelte.js +0 -98
  105. package/src/runtime/server/ambient.d.ts +0 -4
  106. 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.22",
3
+ "version": "3.0.0-next.24",
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",
@@ -129,10 +164,6 @@
129
164
  "types": "./types/index.d.ts",
130
165
  "import": "./src/exports/params/index.js"
131
166
  },
132
- "./remote": {
133
- "types": "./types/index.d.ts",
134
- "import": "./src/exports/remote/index.js"
135
- },
136
167
  "./vite": {
137
168
  "types": "./types/index.d.ts",
138
169
  "import": "./src/exports/vite/index.js"
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,10 +6,22 @@ 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;
@@ -18,13 +18,12 @@ import { extname, resolve, join, dirname, relative } from 'node:path';
18
18
  import { pipeline } from 'node:stream';
19
19
  import { promisify } from 'node:util';
20
20
  import zlib from 'node:zlib';
21
- import { copy } from '../../utils/filesystem.js';
21
+ import { copy, walk } from '../../utils/filesystem.js';
22
22
  import { posixify } from '../../utils/os.js';
23
23
  import { generate_manifest } from '../generate_manifest/index.js';
24
24
  import { get_route_segments } from '../../utils/routing.js';
25
25
  import generate_fallback from '../postbuild/fallback.js';
26
26
  import { write } from '../sync/utils.js';
27
- import { list_files } from '../utils.js';
28
27
  import { find_server_assets } from '../generate_manifest/find_server_assets.js';
29
28
  import { create_exported_declarations } from '../env.js';
30
29
  import { handle_issues, validate } from '../../exports/internal/env.js';
@@ -120,7 +119,7 @@ export function create_builder({
120
119
  return [];
121
120
  }
122
121
 
123
- const files = list_files(directory, (file) => extensions.includes(extname(file)));
122
+ const files = [...walk(directory)].filter((file) => extensions.includes(extname(file)));
124
123
 
125
124
  await Promise.all(
126
125
  files.flatMap((file) => {
package/src/core/env.js CHANGED
@@ -3,13 +3,15 @@
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
7
  import { 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 { hash } from '../utils/hash.js';
14
+ import { posixify } from '../utils/os.js';
13
15
 
14
16
  /**
15
17
  * @typedef {'public' | 'private'} EnvType
@@ -17,37 +19,55 @@ import { get_runner } from '../runner.js';
17
19
 
18
20
  /**
19
21
  * @param {ValidatedConfig} config
22
+ * @param {string} root
20
23
  * @returns {string | null}
21
24
  */
22
- export function resolve_explicit_env_entry(config) {
23
- return resolve_entry(path.join(config.files.src, 'env')) ?? null;
25
+ export function resolve_env_entry(config, root) {
26
+ return resolve_entry(path.resolve(root, config.files.src, 'env'));
24
27
  }
25
28
 
26
29
  /**
27
- * @param {typeof import('vite')} vite
28
30
  * @param {ValidatedConfig} kit
29
31
  * @param {string | null} file
30
32
  * @param {string} root
31
33
  * @param {string} mode
32
- * @returns {Promise<Record<string, EnvVarConfig<any>> | null>}
34
+ * @returns {Promise<{ variables: Record<string, EnvVarConfig<any>> | null, deps: Set<string> }>}
33
35
  */
34
- export async function load_explicit_env(vite, kit, file, root, mode) {
35
- if (!file) return null;
36
+ export async function load_explicit_env(kit, file, root, mode) {
37
+ /** @type {Set<string>} */
38
+ const deps = new Set();
39
+
40
+ if (!file) {
41
+ return { variables: null, deps };
42
+ }
43
+
44
+ /** @type {typeof import('vite')} */
45
+ const vite = await import_peer('vite', root);
36
46
 
37
47
  const server = await vite.createServer({
38
48
  configFile: false,
39
49
  logLevel: 'silent',
40
50
  mode,
41
51
  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
52
+ // these are needed by $app/env
53
+ __SVELTEKIT_APP_VERSION__: JSON.stringify(kit.version.name),
54
+ __SVELTEKIT_DEV__: mode === 'development',
55
+ __SVELTEKIT_PAYLOAD__: 'undefined' // coming in through static import in env/internal.js but will end up unused
44
56
  },
45
57
  resolve: {
46
58
  alias: [
47
59
  { find: '$app/env', replacement: `${runtime_directory}/app/env` },
48
60
  ...get_config_aliases(kit, root)
49
61
  ]
50
- }
62
+ },
63
+ plugins: [
64
+ {
65
+ name: 'dependency-scanner',
66
+ load(id) {
67
+ deps.add(id);
68
+ }
69
+ }
70
+ ]
51
71
  });
52
72
 
53
73
  /** @type {Record<string, EnvVarConfig<any>>} */
@@ -55,8 +75,8 @@ export async function load_explicit_env(vite, kit, file, root, mode) {
55
75
 
56
76
  const runner = get_runner(vite, server);
57
77
 
58
- /** @type {typeof import('../runtime/app/env/internal.js')} */ (
59
- await runner.import(`${runtime_directory}/app/env/internal.js`)
78
+ /** @type {typeof import('../runtime/app/env/server.js')} */ (
79
+ await runner.import(`${runtime_directory}/app/env/server.js`)
60
80
  ).set_building();
61
81
 
62
82
  try {
@@ -90,44 +110,68 @@ export async function load_explicit_env(vite, kit, file, root, mode) {
90
110
  await server.close();
91
111
  }
92
112
 
93
- return variables;
113
+ return { variables, deps };
94
114
  }
95
115
 
96
116
  /**
97
- * Creates the `__sveltekit/env` module
98
- * @param {Record<string, EnvVarConfig<any> | undefined> | null} variables
117
+ * Creates the `<sveltekit:generated>/env/*` modules, keyed by path relative to `dir`. Every module
118
+ * derives from one pass over `variables`, so an inlined value is validated once per build.
119
+ * @param {ValidatedConfig} config
120
+ * @param {Record<string, EnvVarConfig<any>> | null} variables
99
121
  * @param {Record<string, string>} env
122
+ * @param {string} dir
100
123
  * @param {string | null} entry
101
124
  * @param {boolean} is_dev
125
+ * @returns {Record<string, string>}
102
126
  */
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 = () => {};`];
127
+ export function create_env_modules(config, variables, env, dir, entry, is_dev) {
128
+ /** @type {Record<string, StandardSchemaV1.Issue[]>} */
129
+ const issues = {};
130
+
131
+ /** @type {Record<string, string>} */
132
+ const dev_env = {};
110
133
 
134
+ /** @type {string[]} */
111
135
  const declarations = [];
136
+ /** @type {string[]} */
112
137
  const setters = [];
138
+ /** @type {string[]} */
139
+ const public_exports = [];
140
+ /** @type {string[]} */
141
+ const private_exports = [];
142
+ /** @type {string[]} */
143
+ const sw_properties = [];
113
144
 
114
- /** @type {Record<string, StandardSchemaV1.Issue[]>} */
115
- const issues = {};
145
+ let sw_dynamic = false;
146
+
147
+ for (const [name, { public: is_public, static: is_static }] of Object.entries(variables ?? {})) {
148
+ if (is_dev && name in env) dev_env[name] = env[name];
149
+
150
+ const exports = is_public ? public_exports : private_exports;
151
+
152
+ if (is_static) {
153
+ const value = devalue.uneval(validate(variables ?? {}, env[name], name, issues));
154
+ exports.push(`export const ${name} = ${value};\n`);
116
155
 
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)};`);
156
+ if (is_public) {
157
+ declarations.push(`explicit_public_env.${name} = ${value};`);
158
+ sw_properties.push(`${name}: ${value}`);
122
159
  }
123
160
  } else {
161
+ exports.push(`export const ${name} = env.${name};\n`);
124
162
  setters.push(
125
163
  `const ${name} = validate(variables, env.${name}, ${JSON.stringify(name)}, issues);`
126
164
  );
127
165
 
128
- if (config?.public) {
166
+ if (is_public) {
129
167
  setters.push(`explicit_public_env.${name} = ${name};`);
130
168
  setters.push(`rendered_env.${name} = ${name};`);
169
+ sw_dynamic = true;
170
+ // in dev there is no prerendered env module, so the service worker inlines the value
171
+ if (is_dev) {
172
+ const value = devalue.uneval(validate(variables ?? {}, env[name], name, issues));
173
+ sw_properties.push(`${name}: ${value}`);
174
+ }
131
175
  } else {
132
176
  setters.push(`dynamic_private_env.${name} = ${name};`);
133
177
  }
@@ -136,9 +180,13 @@ export function create_sveltekit_env(variables, env, entry, is_dev) {
136
180
 
137
181
  handle_issues(issues);
138
182
 
139
- const blocks = [
140
- GENERATED_COMMENT,
141
- imports.join('\n'),
183
+ const config_blocks = [
184
+ entry
185
+ ? [
186
+ `import { variables } from ${JSON.stringify(entry)};`,
187
+ `import { validate, handle_issues } from '@sveltejs/kit/internal/env';`
188
+ ].join('\n')
189
+ : [`const variables = {};`, `const handle_issues = () => {};`].join('\n'),
142
190
  `const issues = {};`,
143
191
  'export { variables }',
144
192
  'export const dynamic_private_env = {};',
@@ -154,157 +202,67 @@ export function create_sveltekit_env(variables, env, entry, is_dev) {
154
202
  }`
155
203
  ];
156
204
 
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
205
  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 '';
206
+ // In dev, initialise the env immediately. Tools like `vite-node` load modules
207
+ // through the Vite config but don't run the SvelteKit dev server, which is what
208
+ // normally calls `set_env`. Without this, dynamic env vars imported from
209
+ // `$app/env/public` and `$app/env/private` would be `undefined` in such contexts.
210
+ config_blocks.push(`set_env(${devalue.uneval(dev_env)});`);
183
211
  }
184
212
 
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
- `;
213
+ /**
214
+ * @param {string} prelude
215
+ * @param {string[]} exports
216
+ */
217
+ const module = (prelude, exports) => (variables ? `${prelude}\n\n${exports.join('')}` : '');
218
+
219
+ const global = is_dev
220
+ ? 'globalThis.__sveltekit_dev'
221
+ : `globalThis.__sveltekit_${hash(config.version.name)}`;
222
+
223
+ const version = JSON.stringify(config.version.name);
224
+
225
+ // a production build with dynamic public env vars loads them at runtime via an import of
226
+ // the prerendered `env.js`; otherwise the values are inlined
227
+ const service_worker =
228
+ !is_dev && sw_dynamic
229
+ ? dedent`
230
+ import { env } from '${config.paths.base}/${config.appDir}/env.js';
231
+
232
+ ${global} = {
233
+ base: location.pathname.split('/').slice(0, -1).join('/'),
234
+ env,
235
+ version: ${version}
236
+ };
237
+ `
238
+ : dedent`
239
+ ${global} = {
240
+ base: location.pathname.split('/').slice(0, -1).join('/'),
241
+ env: {
242
+ ${sw_properties.join(',\n\t\t') || '// empty'}
243
+ },
244
+ version: ${version}
245
+ };
246
+ `;
247
+
248
+ return {
249
+ 'config.js': config_blocks.join('\n\n'),
250
+ 'public/server.js': module(
251
+ `import { rendered_env as env } from '../config.js';`,
252
+ public_exports
253
+ ),
254
+ 'private/server.js': module(
255
+ `import { dynamic_private_env as env } from '../config.js';`,
256
+ private_exports
257
+ ),
258
+ 'public/client.js': module(
259
+ is_dev
260
+ ? `const { env } = globalThis.__sveltekit_dev;`
261
+ : `import { payload } from ${JSON.stringify(posixify(path.relative(`${dir}/public`, `${runtime_directory}/client/payload.js`)))};\nconst env = payload.env;`,
262
+ public_exports
263
+ ),
264
+ 'service-worker.js': service_worker
265
+ };
308
266
  }
309
267
 
310
268
  /** @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