@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.
Files changed (47) hide show
  1. package/package.json +12 -1
  2. package/src/cli.js +32 -6
  3. package/src/core/adapt/builder.js +26 -5
  4. package/src/core/adapt/index.js +5 -2
  5. package/src/core/config/index.js +7 -5
  6. package/src/core/config/options.js +1 -0
  7. package/src/core/env.js +313 -8
  8. package/src/core/postbuild/analyse.js +2 -1
  9. package/src/core/postbuild/prerender.js +2 -1
  10. package/src/core/sync/sync.js +16 -0
  11. package/src/core/sync/write_ambient.js +12 -6
  12. package/src/core/sync/write_env.js +32 -0
  13. package/src/core/sync/write_root.js +1 -1
  14. package/src/core/sync/write_server.js +3 -2
  15. package/src/core/sync/write_tsconfig.js +1 -0
  16. package/src/exports/hooks/index.js +13 -0
  17. package/src/exports/internal/env.js +71 -0
  18. package/src/exports/internal/types.d.ts +3 -0
  19. package/src/exports/public.d.ts +40 -0
  20. package/src/exports/vite/build/build_service_worker.js +20 -4
  21. package/src/exports/vite/dev/index.js +2 -2
  22. package/src/exports/vite/index.js +127 -29
  23. package/src/exports/vite/module_ids.js +10 -1
  24. package/src/exports/vite/utils.js +6 -0
  25. package/src/runtime/app/env/index.js +2 -0
  26. package/src/runtime/app/env/internal.js +11 -0
  27. package/src/runtime/app/env/private.js +1 -0
  28. package/src/runtime/app/env/public/client.js +7 -0
  29. package/src/runtime/app/env/public/index.js +1 -0
  30. package/src/runtime/app/env/public/server.js +7 -0
  31. package/src/runtime/app/env/standard-schema.d.ts +0 -0
  32. package/src/runtime/app/env/types.d.ts +19 -0
  33. package/src/runtime/app/environment/index.js +10 -2
  34. package/src/runtime/app/server/remote/query.js +1 -1
  35. package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
  36. package/src/runtime/client/utils.js +1 -1
  37. package/src/runtime/server/env_module.js +13 -3
  38. package/src/runtime/server/index.js +2 -0
  39. package/src/runtime/server/page/render.js +11 -3
  40. package/src/runtime/server/respond.js +1 -1
  41. package/src/types/ambient-private.d.ts +25 -9
  42. package/src/types/global-private.d.ts +2 -0
  43. package/src/types/internal.d.ts +1 -0
  44. package/src/utils/import.js +2 -2
  45. package/src/version.js +1 -1
  46. package/types/index.d.ts +70 -1
  47. package/types/index.d.ts.map +7 -1
@@ -0,0 +1,32 @@
1
+ /** @import { EnvVarConfig } from '@sveltejs/kit' */
2
+ import path from 'node:path';
3
+ import { create_explicit_env_types } from '../env.js';
4
+ import { write_if_changed } from './utils.js';
5
+
6
+ const DOCS = '// See https://svelte.dev/docs/kit/environment-variables for more information';
7
+
8
+ /**
9
+ * Writes ambient declarations including types reference to @sveltejs/kit,
10
+ * and the existing environment variables in process.env to
11
+ * $env/static/private and $env/static/public
12
+ * @param {import('types').ValidatedKitConfig} kit
13
+ * @param {string | null} entry
14
+ * @param {Record<string, EnvVarConfig<any>> | null} env_config
15
+ */
16
+ export function write_env(kit, entry, env_config) {
17
+ const content = [];
18
+ const out = path.join(kit.outDir, 'env.d.ts');
19
+
20
+ if (entry && env_config) {
21
+ const relative = path.relative(kit.outDir, entry);
22
+ content.push(
23
+ `// This file is generated from ${relative}.\n${DOCS}`,
24
+ create_explicit_env_types(env_config, relative, 'private'),
25
+ create_explicit_env_types(env_config, relative, 'public')
26
+ );
27
+ } else {
28
+ content.push(DOCS);
29
+ }
30
+
31
+ write_if_changed(out, content.join('\n\n'));
32
+ }
@@ -100,7 +100,7 @@ export function write_root(manifest_data, config, output) {
100
100
  ${isSvelte5Plus() ? '<svelte:options runes={true} />' : ''}
101
101
  <script>
102
102
  import { setContext, ${isSvelte5Plus() ? '' : 'afterUpdate, '}onMount, tick } from 'svelte';
103
- import { browser } from '$app/environment';
103
+ import { browser } from '$app/env';
104
104
 
105
105
  // stores
106
106
  ${
@@ -30,9 +30,10 @@ const server_template = ({
30
30
  error_page
31
31
  }) => `
32
32
  import root from '../root.${isSvelte5Plus() ? 'js' : 'svelte'}';
33
- import { set_building, set_prerendering } from '__sveltekit/environment';
33
+ import { set_building, set_prerendering } from '$app/env/internal';
34
34
  import { set_assets } from '$app/paths/internal/server';
35
35
  import { set_manifest, set_read_implementation } from '__sveltekit/server';
36
+ import { set_env } from '__sveltekit/env';
36
37
  import { set_private_env, set_public_env } from '${runtime_directory}/shared-server.js';
37
38
 
38
39
  export const options = {
@@ -92,7 +93,7 @@ export async function get_hooks() {
92
93
  };
93
94
  }
94
95
 
95
- export { set_assets, set_building, set_manifest, set_prerendering, set_private_env, set_public_env, set_read_implementation };
96
+ export { set_assets, set_building, set_env, set_manifest, set_prerendering, set_private_env, set_public_env, set_read_implementation };
96
97
  `;
97
98
 
98
99
  // TODO need to re-run this whenever src/app.html or src/error.html are
@@ -57,6 +57,7 @@ export function get_tsconfig(kit) {
57
57
 
58
58
  const include = new Set([
59
59
  'ambient.d.ts', // careful: changing this name would be a breaking change, because it's referenced in the service-workers documentation
60
+ 'env.d.ts',
60
61
  'non-ambient.d.ts',
61
62
  './types/**/$types.d.ts',
62
63
  config_relative('vite.config.js'),
@@ -1 +1,14 @@
1
+ /** @import { EnvVarConfig } from '@sveltejs/kit' */
2
+
1
3
  export { sequence } from './sequence.js';
4
+
5
+ /**
6
+ * Utility for defining [environment variables](https://svelte.dev/docs/kit/environment-variables),
7
+ * which are made available via `$app/env/public` and `$app/env/private`.
8
+ * @template {Record<string, EnvVarConfig<any>>} T
9
+ * @param {T} variables
10
+ * @returns {T}
11
+ */
12
+ export function defineEnvVars(variables) {
13
+ return variables;
14
+ }
@@ -0,0 +1,71 @@
1
+ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */
2
+ /** @import { EnvVarConfig } from '@sveltejs/kit' */
3
+
4
+ import { stackless } from '../vite/utils.js';
5
+
6
+ const MISSING = {
7
+ message: `Value is missing. If it is optional, add a Standard Schema validator declaring it as such.`
8
+ };
9
+
10
+ const BAD_VALIDATOR = {
11
+ message: 'Variable was configured with a validator that does not implement Standard Schema'
12
+ };
13
+
14
+ const ASYNC_VALIDATOR = {
15
+ message: 'Variable uses an async validator, which is not supported'
16
+ };
17
+
18
+ /**
19
+ * @param {Record<string, EnvVarConfig<any>>} variables
20
+ * @param {string | undefined} value
21
+ * @param {string} name
22
+ * @param {Record<string, StandardSchemaV1.Issue[]>} issues
23
+ * @returns
24
+ */
25
+ export function validate(variables, value, name, issues) {
26
+ const config = variables[name] ?? {};
27
+ const validator = config.schema;
28
+
29
+ if (!validator) {
30
+ if (!value) issues[name] = [MISSING];
31
+ return value;
32
+ }
33
+
34
+ if (!validator['~standard']) {
35
+ issues[name] = [BAD_VALIDATOR];
36
+ return;
37
+ }
38
+
39
+ const result = validator['~standard'].validate(value);
40
+
41
+ if (result instanceof Promise) {
42
+ issues[name] = [ASYNC_VALIDATOR];
43
+ return;
44
+ }
45
+
46
+ if (result.issues) {
47
+ issues[name] = [...result.issues];
48
+ return;
49
+ }
50
+
51
+ return result.value;
52
+ }
53
+
54
+ /**
55
+ * @param {Record<string, StandardSchemaV1.Issue[]>} issues
56
+ */
57
+ export function handle_issues(issues) {
58
+ const entries = Object.entries(issues);
59
+
60
+ if (entries.length === 0) {
61
+ return;
62
+ }
63
+
64
+ let message = 'Invalid environment variables\n';
65
+
66
+ for (const [name, issues] of entries) {
67
+ message += `\n${name}\n${issues.map((issue) => ` - ${issue.message}`).join('\n')}\n`;
68
+ }
69
+
70
+ throw stackless(message);
71
+ }
@@ -0,0 +1,3 @@
1
+ // We re-export this so we can use it in the `$app/env/*` module declarations
2
+ // without the app needing to depend on this package
3
+ export { StandardSchemaV1 } from '@standard-schema/spec';
@@ -476,6 +476,13 @@ export interface KitConfig {
476
476
  };
477
477
  /** Experimental features. Here be dragons. These are not subject to semantic versioning, so breaking changes or removal can happen in any release. */
478
478
  experimental?: {
479
+ /**
480
+ * Whether to enable explicit environment variables using `src/env.js` or `src/env.ts`.
481
+ * @since 2.62.0
482
+ * @default false
483
+ */
484
+ explicitEnvironmentVariables?: boolean;
485
+
479
486
  /**
480
487
  * Options for enabling server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions).
481
488
  * @default { server: false, serverFile: false }
@@ -2314,4 +2321,37 @@ export type RemoteLiveQueryFunction<Input, Output, _Validated = Input> = (
2314
2321
  arg: undefined extends Input ? Input | void : Input
2315
2322
  ) => RemoteLiveQuery<Output>;
2316
2323
 
2324
+ /**
2325
+ * [Environment variables](https://svelte.dev/docs/kit/environment-variables) can be configured by exporting
2326
+ * a `variables` object from `src/env.ts`, using [`defineEnvVars`](https://svelte.dev/docs/kit/@sveltejs-kit-hooks#defineEnvVars).
2327
+ */
2328
+ export interface EnvVarConfig<T> {
2329
+ /**
2330
+ * Whether the environment variable can be accessed by client-side code.
2331
+ * - if `true`, it can be imported from `$app/env/public`
2332
+ * - if `false`, it can be imported from `$app/env/private`, which is a [server-only module](https://svelte.dev/docs/kit/server-only-modules)
2333
+ * @default false
2334
+ */
2335
+ public?: boolean;
2336
+ /**
2337
+ * Whether the value is determined at build time or when the app runs.
2338
+ * - if `true`, the build time value is inlined into the bundle. This enables optimisations like dead-code elimination
2339
+ * - if `false`, the value is read from the environment when the app starts
2340
+ * @default false
2341
+ */
2342
+ static?: boolean;
2343
+ /**
2344
+ * A [Standard Schema](https://standardschema.dev/) validator that is applied to the value when the app starts.
2345
+ * The validator can output any value — not necessarily a string — but public, non-static values must be
2346
+ * serializable by [devalue](https://github.com/sveltejs/devalue) so that they can be sent to the browser.
2347
+ *
2348
+ * If omitted, the value must be a non-empty string.
2349
+ */
2350
+ schema?: StandardSchemaV1<string | undefined, T>;
2351
+ /**
2352
+ * A description of the variable that will be used for inline documentation on hover.
2353
+ */
2354
+ description?: string;
2355
+ }
2356
+
2317
2357
  export * from './index.js';
@@ -1,10 +1,11 @@
1
+ /** @import { EnvVarConfig } from '@sveltejs/kit' */
1
2
  import fs from 'node:fs';
2
3
  import process from 'node:process';
3
4
  import * as vite from 'vite';
4
5
  import { dedent } from '../../../core/sync/utils.js';
5
6
  import { s } from '../../../utils/misc.js';
6
7
  import { get_config_aliases, strip_virtual_prefix, get_env, normalize_id } from '../utils.js';
7
- import { create_static_module } from '../../../core/env.js';
8
+ import { create_static_module, create_sveltekit_env_public } from '../../../core/env.js';
8
9
  import { env_static_public, service_worker } from '../module_ids.js';
9
10
 
10
11
  // @ts-ignore `vite.rolldownVersion` only exists in `rolldown-vite`
@@ -18,6 +19,7 @@ const is_rolldown = !!vite.rolldownVersion;
18
19
  * @param {string} service_worker_entry_file
19
20
  * @param {import('types').Prerendered} prerendered
20
21
  * @param {import('vite').Manifest} client_manifest
22
+ * @param {Record<string, EnvVarConfig<any>> | null} env_config
21
23
  */
22
24
  export async function build_service_worker(
23
25
  out,
@@ -26,7 +28,8 @@ export async function build_service_worker(
26
28
  manifest_data,
27
29
  service_worker_entry_file,
28
30
  prerendered,
29
- client_manifest
31
+ client_manifest,
32
+ env_config
30
33
  ) {
31
34
  const build = new Set();
32
35
  for (const key in client_manifest) {
@@ -85,7 +88,20 @@ export async function build_service_worker(
85
88
  }
86
89
 
87
90
  if (id === env_static_public) {
88
- return create_static_module('$env/static/public', env.public);
91
+ return create_static_module(
92
+ '$env/static/public',
93
+ env.public,
94
+ kit.experimental.explicitEnvironmentVariables
95
+ );
96
+ }
97
+
98
+ if (id === '\0virtual:app/env/public') {
99
+ // TODO ideally we would only add the `importScripts` if there are dynamic vars that are known to be used
100
+ return create_sveltekit_env_public(
101
+ env_config,
102
+ env.all,
103
+ `importScripts('${kit.paths.base}/${kit.appDir}/env.script.js'); const env = globalThis.__sveltekit_sw.env;`
104
+ );
89
105
  }
90
106
 
91
107
  const normalized_cwd = vite.normalizePath(process.cwd());
@@ -93,7 +109,7 @@ export async function build_service_worker(
93
109
  const relative = normalize_id(id, normalized_lib, normalized_cwd);
94
110
  const stripped = strip_virtual_prefix(relative);
95
111
  throw new Error(
96
- `Cannot import ${stripped} into service-worker code. Only the modules $service-worker and $env/static/public are available in service workers.`
112
+ `Cannot import ${stripped} into service-worker code. Only the modules $service-worker, $env/static/public and $app/env/public are available in service workers.`
97
113
  );
98
114
  }
99
115
  };
@@ -322,7 +322,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes) {
322
322
  // ssrFixStacktrace can fail on StackBlitz web containers and we don't know why
323
323
  // by ignoring it the line numbers are wrong, but at least we can show the error
324
324
  }
325
- return error.stack;
325
+ return error.stack?.replaceAll('\0', ''); // remove null bytes from e.g. virtual module IDs, or the response will fail
326
326
  }
327
327
 
328
328
  update_manifest();
@@ -587,7 +587,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes) {
587
587
  } catch (e) {
588
588
  const error = coalesce_to_error(e);
589
589
  res.statusCode = 500;
590
- res.end(fix_stack_trace(error));
590
+ res.end(fix_stack_trace(error) || error.message); // handle `stackless` errors
591
591
  }
592
592
  });
593
593
  };
@@ -1,3 +1,4 @@
1
+ /** @import { EnvVarConfig } from '@sveltejs/kit' */
1
2
  /** @import { Options, SvelteConfig } from '@sveltejs/vite-plugin-svelte' */
2
3
  /** @import { PreprocessorGroup } from 'svelte/compiler' */
3
4
  /** @import { KitConfig } from '@sveltejs/kit' */
@@ -6,11 +7,18 @@
6
7
  import fs from 'node:fs';
7
8
  import path from 'node:path';
8
9
  import process from 'node:process';
9
-
10
10
  import colors from 'kleur';
11
11
 
12
12
  import { copy, mkdirp, posixify, read, resolve_entry, rimraf } from '../../utils/filesystem.js';
13
- import { create_static_module, create_dynamic_module } from '../../core/env.js';
13
+ import {
14
+ create_dynamic_module,
15
+ create_sveltekit_env,
16
+ create_sveltekit_env_public,
17
+ create_static_module,
18
+ resolve_explicit_env_entry,
19
+ create_sveltekit_env_service_worker_dev,
20
+ create_sveltekit_env_private
21
+ } from '../../core/env.js';
14
22
  import * as sync from '../../core/sync/sync.js';
15
23
  import { create_assets } from '../../core/sync/create_manifest_data/index.js';
16
24
  import { runtime_directory, logger } from '../../core/utils.js';
@@ -40,8 +48,12 @@ import {
40
48
  env_static_private,
41
49
  env_static_public,
42
50
  service_worker,
43
- sveltekit_environment,
44
- sveltekit_server
51
+ sveltekit_env,
52
+ sveltekit_env_private,
53
+ sveltekit_env_service_worker,
54
+ sveltekit_server,
55
+ sveltekit_env_public_client,
56
+ sveltekit_env_public_server
45
57
  } from './module_ids.js';
46
58
  import { import_peer } from '../../utils/import.js';
47
59
  import { compact } from '../../utils/array.js';
@@ -237,7 +249,7 @@ async function kit({ svelte_config }) {
237
249
  /** @type {boolean} */
238
250
  let is_build;
239
251
 
240
- /** @type {{ public: Record<string, string>; private: Record<string, string> }} */
252
+ /** @type {{ all: Record<string, string>; public: Record<string, string>; private: Record<string, string> }} */
241
253
  let env;
242
254
 
243
255
  /** @type {() => Promise<void>} */
@@ -350,7 +362,7 @@ async function kit({ svelte_config }) {
350
362
  // because they for example use esbuild.build with `platform: 'browser'`
351
363
  'esm-env',
352
364
  // This forces `$app/*` modules to be bundled, since they depend on
353
- // virtual modules like `__sveltekit/environment` (this isn't a valid bare
365
+ // virtual modules like `__sveltekit/env` (this isn't a valid bare
354
366
  // import, but it works with vite-node's externalization logic, which
355
367
  // uses basic concatenation)
356
368
  '@sveltejs/kit/src/runtime'
@@ -394,6 +406,7 @@ async function kit({ svelte_config }) {
394
406
 
395
407
  const define = {
396
408
  __SVELTEKIT_APP_DIR__: s(kit.appDir),
409
+ __SVELTEKIT_APP_VERSION__: s(kit.version.name),
397
410
  __SVELTEKIT_EMBEDDED__: s(kit.embedded),
398
411
  __SVELTEKIT_FORK_PRELOADS__: s(kit.experimental.forkPreloads),
399
412
  __SVELTEKIT_PATHS_ASSETS__: s(kit.paths.assets),
@@ -403,6 +416,9 @@ async function kit({ svelte_config }) {
403
416
  __SVELTEKIT_HASH_ROUTING__: s(kit.router.type === 'hash'),
404
417
  __SVELTEKIT_SERVER_TRACING_ENABLED__: s(kit.experimental.tracing.server),
405
418
  __SVELTEKIT_EXPERIMENTAL_USE_TRANSFORM_ERROR__: s(kit.experimental.handleRenderingErrors),
419
+ __SVELTEKIT_EXPERIMENTAL_EXPLICIT_ENVIRONMENT_VARIABLES__: s(
420
+ kit.experimental.explicitEnvironmentVariables
421
+ ),
406
422
  __SVELTEKIT_DEV__: s(!is_build)
407
423
  };
408
424
 
@@ -471,10 +487,50 @@ async function kit({ svelte_config }) {
471
487
  }
472
488
  };
473
489
 
490
+ /** @type {string | null} */
491
+ let explicit_env_entry = null;
492
+
493
+ /** @type {Record<string, EnvVarConfig<any>> | null} */
494
+ let explicit_env_config = null;
495
+
474
496
  /** @type {Plugin} */
475
497
  const plugin_virtual_modules = {
476
498
  name: 'vite-plugin-sveltekit-virtual-modules',
477
499
 
500
+ async configResolved(config) {
501
+ explicit_env_entry = resolve_explicit_env_entry(kit);
502
+ explicit_env_config = await sync.env(kit, explicit_env_entry, config.mode);
503
+ },
504
+
505
+ configureServer(server) {
506
+ if (!kit.experimental.explicitEnvironmentVariables) {
507
+ return;
508
+ }
509
+
510
+ server.watcher.on('all', async (_, file) => {
511
+ if (!file.includes('env')) {
512
+ return;
513
+ }
514
+
515
+ const resolved = resolve_explicit_env_entry(kit);
516
+
517
+ if (file === explicit_env_entry || file === resolved) {
518
+ explicit_env_entry = resolved;
519
+ explicit_env_config = await sync.env(kit, explicit_env_entry, vite_config_env.mode);
520
+
521
+ for (const id of [sveltekit_env, sveltekit_env_public_client]) {
522
+ const module = server.moduleGraph.getModuleById(id);
523
+
524
+ if (module) {
525
+ server.moduleGraph.invalidateModule(module);
526
+ }
527
+ }
528
+
529
+ server.ws.send({ type: 'full-reload' });
530
+ }
531
+ });
532
+ },
533
+
478
534
  resolveId(id, importer) {
479
535
  if (id === '__sveltekit/manifest') {
480
536
  return `${out_dir}/generated/client-optimized/app.js`;
@@ -484,6 +540,7 @@ async function kit({ svelte_config }) {
484
540
  // This check won't catch transitive imports, but it will warn when the import comes from a service-worker directly.
485
541
  // Transitive imports will be caught during the build.
486
542
  // TODO move this logic to plugin_guard
543
+ // TODO allow $app/env/public
487
544
  if (importer) {
488
545
  const parsed_importer = path.parse(importer);
489
546
 
@@ -491,13 +548,19 @@ async function kit({ svelte_config }) {
491
548
  parsed_importer.dir === parsed_service_worker.dir &&
492
549
  parsed_importer.name === parsed_service_worker.name;
493
550
 
494
- if (importer_is_service_worker && id !== '$service-worker' && id !== '$env/static/public') {
551
+ if (
552
+ importer_is_service_worker &&
553
+ id !== '$service-worker' &&
554
+ id !== '$env/static/public' &&
555
+ id !== 'virtual:$app/env/public' &&
556
+ id !== '__sveltekit/env/service-worker'
557
+ ) {
495
558
  throw new Error(
496
559
  `Cannot import ${normalize_id(
497
560
  id,
498
561
  normalized_lib,
499
562
  normalized_cwd
500
- )} into service-worker code. Only the modules $service-worker and $env/static/public are available in service workers.`
563
+ )} into service-worker code. Only the modules $service-worker, $env/static/public and $app/env/public are available in service workers.`
501
564
  );
502
565
  }
503
566
  }
@@ -524,17 +587,20 @@ async function kit({ svelte_config }) {
524
587
  ? `globalThis.__sveltekit_${version_hash}`
525
588
  : 'globalThis.__sveltekit_dev';
526
589
 
590
+ const explicit_env_flag = kit.experimental.explicitEnvironmentVariables;
591
+
527
592
  switch (id) {
528
593
  case env_static_private:
529
- return create_static_module('$env/static/private', env.private);
594
+ return create_static_module('$env/static/private', env.private, explicit_env_flag);
530
595
 
531
596
  case env_static_public:
532
- return create_static_module('$env/static/public', env.public);
597
+ return create_static_module('$env/static/public', env.public, explicit_env_flag);
533
598
 
534
599
  case env_dynamic_private:
535
600
  return create_dynamic_module(
536
601
  'private',
537
- vite_config_env.command === 'serve' ? env.private : undefined
602
+ vite_config_env.command === 'serve' ? env.private : undefined,
603
+ explicit_env_flag
538
604
  );
539
605
 
540
606
  case env_dynamic_public:
@@ -545,29 +611,35 @@ async function kit({ svelte_config }) {
545
611
 
546
612
  return create_dynamic_module(
547
613
  'public',
548
- vite_config_env.command === 'serve' ? env.public : undefined
614
+ vite_config_env.command === 'serve' ? env.public : undefined,
615
+ explicit_env_flag
549
616
  );
550
617
 
551
618
  case service_worker:
552
619
  return create_service_worker_module(svelte_config);
553
620
 
554
- case sveltekit_environment: {
555
- const { version } = svelte_config.kit;
621
+ case sveltekit_env:
622
+ return create_sveltekit_env(explicit_env_config, env.all, explicit_env_entry);
556
623
 
557
- return dedent`
558
- export const version = ${s(version.name)};
559
- export let building = false;
560
- export let prerendering = false;
624
+ case sveltekit_env_public_client:
625
+ return create_sveltekit_env_public(
626
+ explicit_env_config,
627
+ env.all,
628
+ `const env = ${global}.env;`
629
+ );
561
630
 
562
- export function set_building() {
563
- building = true;
564
- }
631
+ case sveltekit_env_public_server:
632
+ return create_sveltekit_env_public(
633
+ explicit_env_config,
634
+ env.all,
635
+ `import { rendered_env as env } from '__sveltekit/env';`
636
+ );
565
637
 
566
- export function set_prerendering() {
567
- prerendering = true;
568
- }
569
- `;
570
- }
638
+ case sveltekit_env_private:
639
+ return create_sveltekit_env_private(explicit_env_config, env.all);
640
+
641
+ case sveltekit_env_service_worker:
642
+ return create_sveltekit_env_service_worker_dev(explicit_env_config, env.all, global);
571
643
 
572
644
  case sveltekit_server: {
573
645
  return dedent`
@@ -594,7 +666,7 @@ async function kit({ svelte_config }) {
594
666
 
595
667
  /**
596
668
  * Ensures that client-side code can't accidentally import server-side code,
597
- * whether in `*.server.js` files, `$app/server`, `$lib/server`, or `$env/[static|dynamic]/private`
669
+ * whether in `*.server.js` files, `$app/server`, `$lib/server`, `$app/env/private`, or `$env/[static|dynamic]/private`
598
670
  * @type {Plugin}
599
671
  */
600
672
  const plugin_guard = {
@@ -636,6 +708,7 @@ async function kit({ svelte_config }) {
636
708
  const is_server_only =
637
709
  normalized === '$env/static/private' ||
638
710
  normalized === '$env/dynamic/private' ||
711
+ normalized === '$app/env/private' ||
639
712
  normalized === '$app/server' ||
640
713
  normalized.startsWith('$lib/server/') ||
641
714
  (is_internal && server_only_pattern.test(path.basename(id)));
@@ -843,6 +916,26 @@ async function kit({ svelte_config }) {
843
916
  }
844
917
  };
845
918
 
919
+ /** @type {Plugin} */
920
+ const plugin_service_worker_env = {
921
+ name: 'vite-plugin-sveltekit-service-worker-env',
922
+
923
+ transform: {
924
+ filter: {
925
+ id: service_worker_entry_file || '<skip>'
926
+ },
927
+ handler(code) {
928
+ // in dev, we prepend the service worker with an import that
929
+ // configures `env`, in case `$app/env/public` is imported,
930
+ // in prod, where we currently use non-module service
931
+ // workers, we have to use `importScripts` instead
932
+ return {
933
+ code: `import '__sveltekit/env/service-worker';\n${code}`
934
+ };
935
+ }
936
+ }
937
+ };
938
+
846
939
  /** @type {Plugin} */
847
940
  const plugin_compile = {
848
941
  name: 'vite-plugin-sveltekit-compile',
@@ -1391,7 +1484,8 @@ async function kit({ svelte_config }) {
1391
1484
  manifest_data,
1392
1485
  service_worker_entry_file,
1393
1486
  prerendered,
1394
- client_manifest
1487
+ client_manifest,
1488
+ explicit_env_config
1395
1489
  );
1396
1490
  }
1397
1491
 
@@ -1414,7 +1508,8 @@ async function kit({ svelte_config }) {
1414
1508
  prerender_map,
1415
1509
  log,
1416
1510
  remotes,
1417
- vite_config
1511
+ vite_config,
1512
+ explicit_env_config
1418
1513
  );
1419
1514
  } else {
1420
1515
  console.log(colors.bold().yellow('\nNo adapter specified'));
@@ -1447,6 +1542,9 @@ async function kit({ svelte_config }) {
1447
1542
  kit.experimental.remoteFunctions && plugin_remote,
1448
1543
  plugin_virtual_modules,
1449
1544
  plugin_guard,
1545
+ kit.experimental.explicitEnvironmentVariables &&
1546
+ service_worker_entry_file &&
1547
+ plugin_service_worker_env,
1450
1548
  plugin_compile
1451
1549
  ].filter((p) => !!p);
1452
1550
  }
@@ -6,11 +6,20 @@ export const env_static_public = '\0virtual:env/static/public';
6
6
  export const env_dynamic_private = '\0virtual:env/dynamic/private';
7
7
  export const env_dynamic_public = '\0virtual:env/dynamic/public';
8
8
 
9
+ export const sveltekit_env = '\0virtual:__sveltekit/env';
10
+ export const sveltekit_env_public_client = '\0virtual:__sveltekit/env/public/client';
11
+ export const sveltekit_env_public_server = '\0virtual:__sveltekit/env/public/server';
12
+ export const sveltekit_env_private = '\0virtual:__sveltekit/env/private';
13
+ export const sveltekit_env_service_worker = '\0virtual:__sveltekit/env/service-worker';
14
+
9
15
  export const service_worker = '\0virtual:service-worker';
10
16
 
11
- export const sveltekit_environment = '\0virtual:__sveltekit/environment';
12
17
  export const sveltekit_server = '\0virtual:__sveltekit/server';
13
18
 
14
19
  export const app_server = posixify(
15
20
  fileURLToPath(new URL('../../runtime/app/server/index.js', import.meta.url))
16
21
  );
22
+
23
+ export const app_env_private = posixify(
24
+ fileURLToPath(new URL('../../runtime/app/env/private.js', import.meta.url))
25
+ );
@@ -7,6 +7,7 @@ import { escape_html } from '../../utils/escape.js';
7
7
  import { dedent } from '../../core/sync/utils.js';
8
8
  import {
9
9
  app_server,
10
+ app_env_private,
10
11
  env_dynamic_private,
11
12
  env_dynamic_public,
12
13
  env_static_private,
@@ -71,6 +72,7 @@ export function get_env(env_config, mode) {
71
72
  const env = loadEnv(mode, env_config.dir, '');
72
73
 
73
74
  return {
75
+ all: env,
74
76
  public: filter_env(env, public_prefix, private_prefix),
75
77
  private: filter_env(env, private_prefix, public_prefix)
76
78
  };
@@ -155,6 +157,10 @@ export function normalize_id(id, lib, cwd) {
155
157
  return '$app/server';
156
158
  }
157
159
 
160
+ if (id === app_env_private) {
161
+ return '$app/env/private';
162
+ }
163
+
158
164
  if (id === env_static_private) {
159
165
  return '$env/static/private';
160
166
  }
@@ -0,0 +1,2 @@
1
+ export { BROWSER as browser, DEV as dev } from 'esm-env';
2
+ export { building, version } from './internal.js';
@@ -0,0 +1,11 @@
1
+ export const version = __SVELTEKIT_APP_VERSION__;
2
+ export let building = false;
3
+ export let prerendering = false;
4
+
5
+ export function set_building() {
6
+ building = true;
7
+ }
8
+
9
+ export function set_prerendering() {
10
+ prerendering = true;
11
+ }
@@ -0,0 +1 @@
1
+ export * from '__sveltekit/env/private';
@@ -0,0 +1,7 @@
1
+ export * from '__sveltekit/env/public/client';
2
+
3
+ if (!__SVELTEKIT_EXPERIMENTAL_EXPLICIT_ENVIRONMENT_VARIABLES__) {
4
+ throw new Error(
5
+ 'Cannot import `$app/env/public` unless `experimental.explicitEnvironmentVariables` is enabled'
6
+ );
7
+ }