@sveltejs/kit 2.62.0 → 2.63.0
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.
- package/package.json +12 -1
- package/src/cli.js +32 -6
- package/src/core/adapt/builder.js +26 -5
- package/src/core/adapt/index.js +5 -2
- package/src/core/config/index.js +7 -5
- package/src/core/config/options.js +1 -0
- package/src/core/env.js +313 -8
- package/src/core/postbuild/analyse.js +2 -1
- package/src/core/postbuild/prerender.js +2 -1
- package/src/core/sync/sync.js +16 -0
- package/src/core/sync/write_ambient.js +12 -6
- package/src/core/sync/write_env.js +32 -0
- package/src/core/sync/write_root.js +1 -1
- package/src/core/sync/write_server.js +3 -2
- package/src/core/sync/write_tsconfig.js +1 -0
- package/src/exports/hooks/index.js +13 -0
- package/src/exports/internal/env.js +71 -0
- package/src/exports/internal/types.d.ts +3 -0
- package/src/exports/public.d.ts +40 -0
- package/src/exports/vite/build/build_service_worker.js +20 -4
- package/src/exports/vite/dev/index.js +2 -2
- package/src/exports/vite/index.js +127 -29
- package/src/exports/vite/module_ids.js +10 -1
- package/src/exports/vite/utils.js +6 -0
- package/src/runtime/app/env/index.js +2 -0
- package/src/runtime/app/env/internal.js +11 -0
- package/src/runtime/app/env/private.js +1 -0
- package/src/runtime/app/env/public/client.js +7 -0
- package/src/runtime/app/env/public/index.js +1 -0
- package/src/runtime/app/env/public/server.js +7 -0
- package/src/runtime/app/env/standard-schema.d.ts +0 -0
- package/src/runtime/app/env/types.d.ts +19 -0
- package/src/runtime/app/environment/index.js +10 -2
- package/src/runtime/app/server/remote/query.js +1 -1
- package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
- package/src/runtime/client/utils.js +1 -1
- package/src/runtime/server/env_module.js +13 -3
- package/src/runtime/server/index.js +2 -0
- package/src/runtime/server/page/render.js +11 -3
- package/src/runtime/server/respond.js +1 -1
- package/src/types/ambient-private.d.ts +25 -9
- package/src/types/global-private.d.ts +2 -0
- package/src/types/internal.d.ts +1 -0
- package/src/utils/import.js +2 -2
- package/src/version.js +1 -1
- package/types/index.d.ts +70 -1
- package/types/index.d.ts.map +7 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/kit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.63.0",
|
|
4
4
|
"description": "SvelteKit is the fastest way to build Svelte apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -76,6 +76,10 @@
|
|
|
76
76
|
"#app/paths": {
|
|
77
77
|
"browser": "./src/runtime/app/paths/client.js",
|
|
78
78
|
"default": "./src/runtime/app/paths/server.js"
|
|
79
|
+
},
|
|
80
|
+
"#app/env/public": {
|
|
81
|
+
"browser": "./src/runtime/app/env/public/client.js",
|
|
82
|
+
"default": "./src/runtime/app/env/public/server.js"
|
|
79
83
|
}
|
|
80
84
|
},
|
|
81
85
|
"exports": {
|
|
@@ -88,6 +92,13 @@
|
|
|
88
92
|
"types": "./types/index.d.ts",
|
|
89
93
|
"import": "./src/exports/internal/index.js"
|
|
90
94
|
},
|
|
95
|
+
"./internal/env": {
|
|
96
|
+
"types": "./types/index.d.ts",
|
|
97
|
+
"import": "./src/exports/internal/env.js"
|
|
98
|
+
},
|
|
99
|
+
"./internal/types": {
|
|
100
|
+
"import": "./src/exports/internal/types.js"
|
|
101
|
+
},
|
|
91
102
|
"./internal/server": {
|
|
92
103
|
"types": "./types/index.d.ts",
|
|
93
104
|
"import": "./src/exports/internal/server.js"
|
package/src/cli.js
CHANGED
|
@@ -4,6 +4,7 @@ import { parseArgs } from 'node:util';
|
|
|
4
4
|
import colors from 'kleur';
|
|
5
5
|
import { load_config } from './core/config/index.js';
|
|
6
6
|
import { coalesce_to_error } from './utils/error.js';
|
|
7
|
+
import { resolve_explicit_env_entry } from './core/env.js';
|
|
7
8
|
|
|
8
9
|
/** @param {unknown} e */
|
|
9
10
|
function handle_error(e) {
|
|
@@ -73,20 +74,45 @@ if (!command) {
|
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
if (command === 'sync') {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
// create placeholder .svelte-kit/tsconfig.json if necessary, to squelch warnings.
|
|
78
|
+
// this isn't bulletproof — if someone has some esoteric config, it will continue
|
|
79
|
+
// to harmlessly warn — but we handle the 90% case and clean up after ourselves
|
|
80
|
+
const sveltekit_dir = '.svelte-kit';
|
|
81
|
+
const base_tsconfig = `${sveltekit_dir}/tsconfig.json`;
|
|
82
|
+
const base_tsconfig_json = '{}';
|
|
83
|
+
|
|
84
|
+
const sveltekit_dir_exists = fs.existsSync(sveltekit_dir);
|
|
85
|
+
const base_tsconfig_exists = fs.existsSync(base_tsconfig);
|
|
86
|
+
|
|
87
|
+
if (!base_tsconfig_exists) {
|
|
88
|
+
try {
|
|
89
|
+
fs.mkdirSync('.svelte-kit');
|
|
90
|
+
} catch {
|
|
91
|
+
// ignore
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
fs.writeFileSync(base_tsconfig, base_tsconfig_json);
|
|
82
95
|
}
|
|
83
96
|
|
|
84
97
|
try {
|
|
85
98
|
const config = await load_config();
|
|
86
99
|
const sync = await import('./core/sync/sync.js');
|
|
87
100
|
sync.all_types(config, values.mode);
|
|
101
|
+
|
|
102
|
+
const explicit_env_entry = resolve_explicit_env_entry(config.kit);
|
|
103
|
+
await sync.env(config.kit, explicit_env_entry, values.mode);
|
|
88
104
|
} catch (error) {
|
|
89
105
|
handle_error(error);
|
|
106
|
+
} finally {
|
|
107
|
+
// if we errored, or accidentally created the wrong file
|
|
108
|
+
// (could happen!) then clean up after ourselves
|
|
109
|
+
if (fs.readFileSync(base_tsconfig, 'utf-8') === base_tsconfig_json) {
|
|
110
|
+
fs.unlinkSync(base_tsconfig);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (!sveltekit_dir_exists && fs.readdirSync(sveltekit_dir).length === 0) {
|
|
114
|
+
fs.rmSync(sveltekit_dir, { recursive: true });
|
|
115
|
+
}
|
|
90
116
|
}
|
|
91
117
|
} else {
|
|
92
118
|
console.error(colors.bold().red(`> Unknown command: ${command}`));
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
/** @import { StandardSchemaV1 } from '@standard-schema/spec' */
|
|
1
2
|
/** @import { Builder } from '@sveltejs/kit' */
|
|
2
3
|
/** @import { ResolvedConfig } from 'vite' */
|
|
3
|
-
/** @import { RouteDefinition } from '@sveltejs/kit' */
|
|
4
|
+
/** @import { RouteDefinition, EnvVarConfig } from '@sveltejs/kit' */
|
|
4
5
|
/** @import { RouteData, ValidatedConfig, BuildData, ServerMetadata, ServerMetadataRoute, Prerendered, PrerenderMap, Logger, RemoteChunk } from 'types' */
|
|
5
6
|
import colors from 'kleur';
|
|
7
|
+
import * as devalue from 'devalue';
|
|
6
8
|
import { createReadStream, createWriteStream, existsSync, statSync } from 'node:fs';
|
|
7
9
|
import { extname, resolve, join, dirname, relative } from 'node:path';
|
|
8
10
|
import { pipeline } from 'node:stream';
|
|
@@ -17,6 +19,7 @@ import { write } from '../sync/utils.js';
|
|
|
17
19
|
import { list_files } from '../utils.js';
|
|
18
20
|
import { find_server_assets } from '../generate_manifest/find_server_assets.js';
|
|
19
21
|
import { reserved } from '../env.js';
|
|
22
|
+
import { handle_issues, validate } from '../../exports/internal/env.js';
|
|
20
23
|
|
|
21
24
|
const pipe = promisify(pipeline);
|
|
22
25
|
const extensions = ['.html', '.js', '.mjs', '.json', '.css', '.svg', '.xml', '.wasm', '.txt'];
|
|
@@ -32,7 +35,8 @@ const extensions = ['.html', '.js', '.mjs', '.json', '.css', '.svg', '.xml', '.w
|
|
|
32
35
|
* prerender_map: PrerenderMap;
|
|
33
36
|
* log: Logger;
|
|
34
37
|
* vite_config: ResolvedConfig;
|
|
35
|
-
* remotes: RemoteChunk[]
|
|
38
|
+
* remotes: RemoteChunk[];
|
|
39
|
+
* explicit_env_config: Record<string, EnvVarConfig<any>> | null;
|
|
36
40
|
* }} opts
|
|
37
41
|
* @returns {Builder}
|
|
38
42
|
*/
|
|
@@ -45,7 +49,8 @@ export function create_builder({
|
|
|
45
49
|
prerender_map,
|
|
46
50
|
log,
|
|
47
51
|
vite_config,
|
|
48
|
-
remotes
|
|
52
|
+
remotes,
|
|
53
|
+
explicit_env_config
|
|
49
54
|
}) {
|
|
50
55
|
/** @type {Map<RouteDefinition, RouteData>} */
|
|
51
56
|
const lookup = new Map();
|
|
@@ -168,7 +173,7 @@ export function create_builder({
|
|
|
168
173
|
|
|
169
174
|
const fallback = await generate_fallback({
|
|
170
175
|
manifest_path,
|
|
171
|
-
env:
|
|
176
|
+
env: env.all,
|
|
172
177
|
out_dir: config.kit.outDir,
|
|
173
178
|
origin: config.kit.prerender.origin,
|
|
174
179
|
assets: config.kit.files.assets
|
|
@@ -193,7 +198,23 @@ export function create_builder({
|
|
|
193
198
|
const dest = `${config.kit.outDir}/output/prerendered/dependencies/${config.kit.appDir}/env.js`;
|
|
194
199
|
const env = get_env(config.kit.env, vite_config.mode);
|
|
195
200
|
|
|
196
|
-
|
|
201
|
+
const values = config.kit.experimental.explicitEnvironmentVariables ? {} : env.public;
|
|
202
|
+
|
|
203
|
+
if (config.kit.experimental.explicitEnvironmentVariables) {
|
|
204
|
+
const variables = explicit_env_config ?? {};
|
|
205
|
+
|
|
206
|
+
/** @type {Record<string, StandardSchemaV1.Issue[]>} */
|
|
207
|
+
const issues = {};
|
|
208
|
+
|
|
209
|
+
for (const [name, config] of Object.entries(variables)) {
|
|
210
|
+
if (config.static || !config.public) continue;
|
|
211
|
+
values[name] = validate(variables, env.all[name], name, issues);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
handle_issues(issues);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
write(dest, `export const env=${devalue.uneval(values)}`);
|
|
197
218
|
},
|
|
198
219
|
|
|
199
220
|
generateManifest({ relativePath, routes: subset }) {
|
package/src/core/adapt/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { create_builder } from './builder.js';
|
|
|
10
10
|
* @param {import('types').Logger} log
|
|
11
11
|
* @param {import('types').RemoteChunk[]} remotes
|
|
12
12
|
* @param {import('vite').ResolvedConfig} vite_config
|
|
13
|
+
* @param {Record<string, import('@sveltejs/kit').EnvVarConfig<any>> | null} explicit_env_config
|
|
13
14
|
*/
|
|
14
15
|
export async function adapt(
|
|
15
16
|
config,
|
|
@@ -19,7 +20,8 @@ export async function adapt(
|
|
|
19
20
|
prerender_map,
|
|
20
21
|
log,
|
|
21
22
|
remotes,
|
|
22
|
-
vite_config
|
|
23
|
+
vite_config,
|
|
24
|
+
explicit_env_config
|
|
23
25
|
) {
|
|
24
26
|
// This is only called when adapter is truthy, so the cast is safe
|
|
25
27
|
const { name, adapt } = /** @type {import('@sveltejs/kit').Adapter} */ (config.kit.adapter);
|
|
@@ -35,7 +37,8 @@ export async function adapt(
|
|
|
35
37
|
prerender_map,
|
|
36
38
|
log,
|
|
37
39
|
remotes,
|
|
38
|
-
vite_config
|
|
40
|
+
vite_config,
|
|
41
|
+
explicit_env_config
|
|
39
42
|
});
|
|
40
43
|
|
|
41
44
|
await adapt(builder);
|
package/src/core/config/index.js
CHANGED
|
@@ -33,11 +33,13 @@ export function load_template(cwd, { kit }) {
|
|
|
33
33
|
}
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
if (!kit.experimental.explicitEnvironmentVariables) {
|
|
37
|
+
for (const match of contents.matchAll(/%sveltekit\.env\.([^%]+)%/g)) {
|
|
38
|
+
if (!match[1].startsWith(env.publicPrefix)) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Environment variables in ${relative} must start with ${env.publicPrefix} (saw %sveltekit.env.${match[1]}%)`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
|
package/src/core/env.js
CHANGED
|
@@ -1,19 +1,126 @@
|
|
|
1
|
+
/** @import { StandardSchemaV1 } from '@standard-schema/spec' */
|
|
2
|
+
/** @import { EnvVarConfig } from '@sveltejs/kit' */
|
|
3
|
+
/** @import { ValidatedKitConfig } from 'types' */
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import process from 'node:process';
|
|
6
|
+
import * as vite from 'vite';
|
|
7
|
+
import * as devalue from 'devalue';
|
|
1
8
|
import { GENERATED_COMMENT } from '../constants.js';
|
|
2
9
|
import { dedent } from './sync/utils.js';
|
|
3
|
-
import { runtime_base } from './utils.js';
|
|
10
|
+
import { runtime_base, runtime_directory } from './utils.js';
|
|
11
|
+
import { resolve_entry } from '../utils/filesystem.js';
|
|
12
|
+
import { handle_issues, validate } from '../exports/internal/env.js';
|
|
13
|
+
import { get_config_aliases } from '../exports/vite/utils.js';
|
|
4
14
|
|
|
5
15
|
/**
|
|
6
16
|
* @typedef {'public' | 'private'} EnvType
|
|
7
17
|
*/
|
|
8
18
|
|
|
19
|
+
let warned = false;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {import('types').ValidatedKitConfig} config
|
|
23
|
+
* @returns {string | null}
|
|
24
|
+
*/
|
|
25
|
+
export function resolve_explicit_env_entry(config) {
|
|
26
|
+
const resolved = resolve_entry(path.join(config.files.src, 'env'));
|
|
27
|
+
|
|
28
|
+
if (resolved) {
|
|
29
|
+
if (config.experimental.explicitEnvironmentVariables) {
|
|
30
|
+
return resolved;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!warned) {
|
|
34
|
+
console.warn(
|
|
35
|
+
`${path.relative(process.cwd(), resolved)} requires the \`experimental.explicitEnvironmentVariables\` flag to be set`
|
|
36
|
+
);
|
|
37
|
+
warned = true;
|
|
38
|
+
}
|
|
39
|
+
} else if (config.experimental.explicitEnvironmentVariables) {
|
|
40
|
+
console.warn(
|
|
41
|
+
'experimental.explicitEnvironmentVariables was set, but no src/env.ts or src/env.js file could be found'
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {ValidatedKitConfig} kit
|
|
50
|
+
* @param {string | null} file
|
|
51
|
+
* @param {string} mode
|
|
52
|
+
* @returns {Promise<Record<string, EnvVarConfig<any>> | null>}
|
|
53
|
+
*/
|
|
54
|
+
export async function load_explicit_env(kit, file, mode) {
|
|
55
|
+
if (!file) return null;
|
|
56
|
+
|
|
57
|
+
const server = await vite.createServer({
|
|
58
|
+
configFile: false,
|
|
59
|
+
logLevel: 'silent',
|
|
60
|
+
mode,
|
|
61
|
+
define: {
|
|
62
|
+
__SVELTEKIT_APP_VERSION__: JSON.stringify(kit.version.name) // needed by $app/env
|
|
63
|
+
},
|
|
64
|
+
resolve: {
|
|
65
|
+
alias: [
|
|
66
|
+
{ find: '$app/env', replacement: `${runtime_directory}/app/env` },
|
|
67
|
+
...get_config_aliases(kit)
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
/** @type {Record<string, EnvVarConfig<any>>} */
|
|
73
|
+
let variables;
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
({ variables } = await server.ssrLoadModule(file));
|
|
77
|
+
|
|
78
|
+
if (!variables || typeof variables !== 'object') {
|
|
79
|
+
throw new Error(`${file} must export a variables object`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// validate
|
|
83
|
+
for (const name of Object.keys(variables)) {
|
|
84
|
+
if (!valid_identifier.test(name) || reserved.has(name)) {
|
|
85
|
+
throw new Error(`Invalid environment variable name ${JSON.stringify(name)}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
} catch (e) {
|
|
89
|
+
const error = /** @type {any} */ (e || {});
|
|
90
|
+
|
|
91
|
+
if (
|
|
92
|
+
error.code === 'ERR_MODULE_NOT_FOUND' &&
|
|
93
|
+
error.message?.includes(`Cannot find module '$app`)
|
|
94
|
+
) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Cannot import \`$app/*\` modules other than \`$app/env\` inside \`src/env\``,
|
|
97
|
+
{ cause: e }
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
throw error;
|
|
102
|
+
} finally {
|
|
103
|
+
await server.close();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return variables;
|
|
107
|
+
}
|
|
108
|
+
|
|
9
109
|
/**
|
|
10
110
|
* @param {string} id
|
|
11
111
|
* @param {Record<string, string>} env
|
|
112
|
+
* @param {boolean} disabled
|
|
12
113
|
* @returns {string}
|
|
13
114
|
*/
|
|
14
|
-
export function create_static_module(id, env) {
|
|
115
|
+
export function create_static_module(id, env, disabled) {
|
|
15
116
|
/** @type {string[]} */
|
|
16
|
-
const
|
|
117
|
+
const statements = [];
|
|
118
|
+
|
|
119
|
+
if (disabled) {
|
|
120
|
+
statements.push(
|
|
121
|
+
`throw new Error('Cannot import \`${id}\` when \`experimental.explicitEnvironmentVariables\` is enabled. Use \`${id.replace('$env/static', '$app/env')}\` instead.');`
|
|
122
|
+
);
|
|
123
|
+
}
|
|
17
124
|
|
|
18
125
|
for (const key in env) {
|
|
19
126
|
if (!valid_identifier.test(key) || reserved.has(key)) {
|
|
@@ -23,24 +130,199 @@ export function create_static_module(id, env) {
|
|
|
23
130
|
const comment = `/** @type {import('${id}').${key}} */`;
|
|
24
131
|
const declaration = `export const ${key} = ${JSON.stringify(env[key])};`;
|
|
25
132
|
|
|
26
|
-
|
|
133
|
+
statements.push(`${comment}\n${declaration}`);
|
|
27
134
|
}
|
|
28
135
|
|
|
29
|
-
return GENERATED_COMMENT +
|
|
136
|
+
return GENERATED_COMMENT + statements.join('\n\n');
|
|
30
137
|
}
|
|
31
138
|
|
|
32
139
|
/**
|
|
33
140
|
* @param {EnvType} type
|
|
34
141
|
* @param {Record<string, string> | undefined} dev_values If in a development mode, values to pre-populate the module with.
|
|
142
|
+
* @param {boolean} disabled
|
|
35
143
|
*/
|
|
36
|
-
export function create_dynamic_module(type, dev_values) {
|
|
144
|
+
export function create_dynamic_module(type, dev_values, disabled) {
|
|
145
|
+
const prelude = disabled
|
|
146
|
+
? `throw new Error('Cannot import \`$env/dynamic/${type}\` when \`experimental.explicitEnvironmentVariables\` is enabled. Use \`$app/env/${type}\` instead.');\n\n`
|
|
147
|
+
: '';
|
|
148
|
+
|
|
37
149
|
if (dev_values) {
|
|
38
150
|
const keys = Object.entries(dev_values).map(
|
|
39
151
|
([k, v]) => `${JSON.stringify(k)}: ${JSON.stringify(v)}`
|
|
40
152
|
);
|
|
41
|
-
return
|
|
153
|
+
return `${prelude}export const env = {\n${keys.join(',\n')}\n}`;
|
|
154
|
+
}
|
|
155
|
+
return `${prelude}export { ${type}_env as env } from '${runtime_base}/shared-server.js';`;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Creates the `__sveltekit/env` module
|
|
160
|
+
* @param {Record<string, EnvVarConfig<any>> | null} variables
|
|
161
|
+
* @param {Record<string, string>} env
|
|
162
|
+
* @param {string | null} entry
|
|
163
|
+
*/
|
|
164
|
+
export function create_sveltekit_env(variables, env, entry) {
|
|
165
|
+
const imports = entry
|
|
166
|
+
? [
|
|
167
|
+
`import { variables } from ${JSON.stringify(entry)};`,
|
|
168
|
+
`import { validate, handle_issues } from '@sveltejs/kit/internal/env';`
|
|
169
|
+
]
|
|
170
|
+
: [`const variables = {};`, `const handle_issues = () => {};`];
|
|
171
|
+
|
|
172
|
+
const declarations = [];
|
|
173
|
+
const setters = [];
|
|
174
|
+
|
|
175
|
+
/** @type {Record<string, StandardSchemaV1.Issue[]>} */
|
|
176
|
+
const issues = {};
|
|
177
|
+
|
|
178
|
+
for (const [name, config] of Object.entries(variables ?? {})) {
|
|
179
|
+
if (config.static) {
|
|
180
|
+
if (config.public) {
|
|
181
|
+
const value = validate(variables ?? {}, env[name], name, issues);
|
|
182
|
+
declarations.push(`explicit_public_env.${name} = ${devalue.uneval(value)};`);
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
setters.push(
|
|
186
|
+
`const ${name} = validate(variables, env.${name}, ${JSON.stringify(name)}, issues);`
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
if (config.public) {
|
|
190
|
+
setters.push(`explicit_public_env.${name} = ${name};`);
|
|
191
|
+
setters.push(`rendered_env.${name} = ${name};`);
|
|
192
|
+
} else {
|
|
193
|
+
setters.push(`dynamic_private_env.${name} = ${name};`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
handle_issues(issues);
|
|
199
|
+
|
|
200
|
+
const blocks = [
|
|
201
|
+
GENERATED_COMMENT,
|
|
202
|
+
imports.join('\n'),
|
|
203
|
+
`const issues = {};`,
|
|
204
|
+
'export { variables }',
|
|
205
|
+
'export const dynamic_private_env = {};',
|
|
206
|
+
'export const explicit_public_env = {};',
|
|
207
|
+
'export const rendered_env = {};',
|
|
208
|
+
...declarations,
|
|
209
|
+
`handle_issues(issues);`,
|
|
210
|
+
dedent`
|
|
211
|
+
export function set_env(env) {
|
|
212
|
+
const issues = {};
|
|
213
|
+
${setters.join('\n')}
|
|
214
|
+
handle_issues(issues);
|
|
215
|
+
}`
|
|
216
|
+
];
|
|
217
|
+
|
|
218
|
+
const module = blocks.join('\n\n');
|
|
219
|
+
|
|
220
|
+
return module;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Creates the `__sveltekit/env/private` module
|
|
225
|
+
* @param {Record<string, EnvVarConfig<any>> | null} variables
|
|
226
|
+
* @param {Record<string, string>} env
|
|
227
|
+
*/
|
|
228
|
+
export function create_sveltekit_env_private(variables, env) {
|
|
229
|
+
if (!variables) {
|
|
230
|
+
return '';
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** @type {Record<string, StandardSchemaV1.Issue[]>} */
|
|
234
|
+
const issues = {};
|
|
235
|
+
|
|
236
|
+
/** @type {string[]} */
|
|
237
|
+
const exports = [];
|
|
238
|
+
|
|
239
|
+
for (const [name, config] of Object.entries(variables)) {
|
|
240
|
+
if (config.public) continue;
|
|
241
|
+
|
|
242
|
+
const value = config.static
|
|
243
|
+
? devalue.uneval(validate(variables, env[name], name, issues))
|
|
244
|
+
: `env.${name}`;
|
|
245
|
+
|
|
246
|
+
exports.push(`export const ${name} = ${value};\n`);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
handle_issues(issues);
|
|
250
|
+
|
|
251
|
+
return `import { dynamic_private_env as env } from '__sveltekit/env';\n\n${exports.join('')}`;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Creates the `__sveltekit/env/public/*` modules
|
|
256
|
+
* @param {Record<string, EnvVarConfig<any>> | null} variables
|
|
257
|
+
* @param {Record<string, string>} env
|
|
258
|
+
* @param {string} prelude
|
|
259
|
+
*/
|
|
260
|
+
export function create_sveltekit_env_public(variables, env, prelude) {
|
|
261
|
+
if (!variables) {
|
|
262
|
+
return '';
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** @type {Record<string, StandardSchemaV1.Issue[]>} */
|
|
266
|
+
const issues = {};
|
|
267
|
+
|
|
268
|
+
/** @type {string[]} */
|
|
269
|
+
const exports = [];
|
|
270
|
+
|
|
271
|
+
for (const [name, config] of Object.entries(variables)) {
|
|
272
|
+
if (!config.public) continue;
|
|
273
|
+
|
|
274
|
+
const value = config.static
|
|
275
|
+
? devalue.uneval(validate(variables, env[name], name, issues))
|
|
276
|
+
: `env.${name}`;
|
|
277
|
+
|
|
278
|
+
exports.push(`export const ${name} = ${value};\n`);
|
|
42
279
|
}
|
|
43
|
-
|
|
280
|
+
|
|
281
|
+
handle_issues(issues);
|
|
282
|
+
|
|
283
|
+
return `${prelude}\n\n${exports.join('')}`;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Creates the `__sveltekit/env/service-worker` module used in development
|
|
288
|
+
* (but not in prod, which goes through build_service_worker instead)
|
|
289
|
+
* @param {Record<string, EnvVarConfig<any>> | null} variables
|
|
290
|
+
* @param {Record<string, string>} env
|
|
291
|
+
* @param {string} global
|
|
292
|
+
*/
|
|
293
|
+
export function create_sveltekit_env_service_worker_dev(variables, env, global) {
|
|
294
|
+
/** @type {string[]} */
|
|
295
|
+
const properties = [];
|
|
296
|
+
|
|
297
|
+
/** @type {Record<string, StandardSchemaV1.Issue[]>} */
|
|
298
|
+
const issues = {};
|
|
299
|
+
|
|
300
|
+
for (const [name, config] of Object.entries(variables ?? {})) {
|
|
301
|
+
if (!config.public) continue;
|
|
302
|
+
|
|
303
|
+
const value = validate(variables ?? {}, env[name], name, issues);
|
|
304
|
+
properties.push(`${name}: ${devalue.uneval(value)}`);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
handle_issues(issues);
|
|
308
|
+
|
|
309
|
+
return dedent`
|
|
310
|
+
globalThis.__SVELTEKIT_EXPERIMENTAL_EXPLICIT_ENVIRONMENT_VARIABLES__ = true;
|
|
311
|
+
|
|
312
|
+
${global} = {
|
|
313
|
+
env: {
|
|
314
|
+
${properties.join(',\n\t\t') || '// empty'}
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
`;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** @param {string} description */
|
|
321
|
+
function create_jsdoc(description) {
|
|
322
|
+
return `/**\n${description
|
|
323
|
+
.split('\n')
|
|
324
|
+
.map((line) => ` * ${line.replaceAll('*/', '*\\/')}`)
|
|
325
|
+
.join('\n')}\n */`;
|
|
44
326
|
}
|
|
45
327
|
|
|
46
328
|
/**
|
|
@@ -98,6 +380,29 @@ export function create_dynamic_types(id, env, { public_prefix, private_prefix })
|
|
|
98
380
|
`;
|
|
99
381
|
}
|
|
100
382
|
|
|
383
|
+
/**
|
|
384
|
+
* @param {Record<string, EnvVarConfig<any>>} variables
|
|
385
|
+
* @param {string} relative
|
|
386
|
+
* @param {EnvType} type
|
|
387
|
+
*/
|
|
388
|
+
export function create_explicit_env_types(variables, relative, type) {
|
|
389
|
+
const declarations = Object.entries(variables)
|
|
390
|
+
.filter(([_, config]) => !!config.public === (type === 'public'))
|
|
391
|
+
.map(([name, config]) => {
|
|
392
|
+
const comment = config.description ? `${create_jsdoc(config.description)}\n` : '';
|
|
393
|
+
const type = config.schema
|
|
394
|
+
? `import('@sveltejs/kit/internal/types').StandardSchemaV1.InferOutput<typeof import('${relative}').variables.${name}.schema>`
|
|
395
|
+
: 'string';
|
|
396
|
+
return `${comment}export const ${name}: ${type};`;
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
return dedent`
|
|
400
|
+
declare module '$app/env/${type}' {
|
|
401
|
+
${declarations.join('\n') || `// no ${type} environment variables were defined`}
|
|
402
|
+
}
|
|
403
|
+
`;
|
|
404
|
+
}
|
|
405
|
+
|
|
101
406
|
export const reserved = new Set([
|
|
102
407
|
'do',
|
|
103
408
|
'if',
|
|
@@ -50,7 +50,7 @@ async function analyse({
|
|
|
50
50
|
|
|
51
51
|
installPolyfills();
|
|
52
52
|
|
|
53
|
-
// configure `import { building } from '$app/environment'` —
|
|
53
|
+
// configure `import { building } from '$app/environment'` and `$app/env` —
|
|
54
54
|
// essential we do this before analysing the code
|
|
55
55
|
internal.set_building();
|
|
56
56
|
|
|
@@ -60,6 +60,7 @@ async function analyse({
|
|
|
60
60
|
const public_env = filter_env(env, public_prefix, private_prefix);
|
|
61
61
|
internal.set_private_env(private_env);
|
|
62
62
|
internal.set_public_env(public_env);
|
|
63
|
+
internal.set_env(env);
|
|
63
64
|
internal.set_manifest(manifest);
|
|
64
65
|
internal.set_read_implementation((file) => createReadableStream(`${server_root}/server/${file}`));
|
|
65
66
|
|
|
@@ -46,7 +46,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
|
|
|
46
46
|
/** @type {import('types').ServerModule} */
|
|
47
47
|
const { Server } = await import(pathToFileURL(`${out}/server/index.js`).href);
|
|
48
48
|
|
|
49
|
-
// configure `import { building } from '$app/environment'` —
|
|
49
|
+
// configure `import { building } from '$app/environment'` and `$app/env` —
|
|
50
50
|
// essential we do this before analysing the code
|
|
51
51
|
internal.set_building();
|
|
52
52
|
internal.set_prerendering();
|
|
@@ -497,6 +497,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
|
|
|
497
497
|
const public_env = filter_env(env, public_prefix, private_prefix);
|
|
498
498
|
internal.set_private_env(private_env);
|
|
499
499
|
internal.set_public_env(public_env);
|
|
500
|
+
internal.set_env(env);
|
|
500
501
|
internal.set_manifest(manifest);
|
|
501
502
|
internal.set_read_implementation((file) => createReadableStream(`${out}/server/${file}`));
|
|
502
503
|
|
package/src/core/sync/sync.js
CHANGED
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
create_node_analyser,
|
|
12
12
|
get_page_options
|
|
13
13
|
} from '../../exports/vite/static_analysis/index.js';
|
|
14
|
+
import { load_explicit_env } from '../env.js';
|
|
15
|
+
import { write_env } from './write_env.js';
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Initialize SvelteKit's generated files that only depend on the config and mode.
|
|
@@ -87,6 +89,20 @@ export function all_types(config, mode) {
|
|
|
87
89
|
write_non_ambient(config.kit, manifest_data);
|
|
88
90
|
}
|
|
89
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Generate modules and types for explicit env vars
|
|
94
|
+
* @param {import('types').ValidatedKitConfig} kit
|
|
95
|
+
* @param {string | null} entry
|
|
96
|
+
* @param {string} mode The Vite mode
|
|
97
|
+
*/
|
|
98
|
+
export async function env(kit, entry, mode) {
|
|
99
|
+
const env_config = await load_explicit_env(kit, entry, mode);
|
|
100
|
+
|
|
101
|
+
write_env(kit, entry, env_config);
|
|
102
|
+
|
|
103
|
+
return env_config;
|
|
104
|
+
}
|
|
105
|
+
|
|
90
106
|
/**
|
|
91
107
|
* Regenerate __SERVER__/internal.js in response to src/{app.html,error.html,service-worker.js} changing
|
|
92
108
|
* @param {import('types').ValidatedConfig} config
|
|
@@ -53,11 +53,17 @@ ${create_dynamic_types('public', env, prefixes)}
|
|
|
53
53
|
* @param {string} mode The Vite mode
|
|
54
54
|
*/
|
|
55
55
|
export function write_ambient(config, mode) {
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
/** @type {string} */
|
|
57
|
+
let content;
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
if (config.experimental.explicitEnvironmentVariables) {
|
|
60
|
+
content = `${GENERATED_COMMENT}\n/// <reference types="@sveltejs/kit" />`;
|
|
61
|
+
} else {
|
|
62
|
+
const env = get_env(config.env, mode);
|
|
63
|
+
const { publicPrefix: public_prefix, privatePrefix: private_prefix } = config.env;
|
|
64
|
+
|
|
65
|
+
content = template(env, { public_prefix, private_prefix });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
write_if_changed(path.join(config.outDir, 'ambient.d.ts'), content);
|
|
63
69
|
}
|