@sveltejs/kit 2.61.1 → 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 (53) hide show
  1. package/package.json +14 -3
  2. package/src/cli.js +32 -6
  3. package/src/core/adapt/builder.js +31 -5
  4. package/src/core/adapt/index.js +5 -2
  5. package/src/core/config/index.js +100 -36
  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/fallback.js +7 -8
  10. package/src/core/postbuild/prerender.js +6 -2
  11. package/src/core/sync/sync.js +16 -0
  12. package/src/core/sync/write_ambient.js +12 -6
  13. package/src/core/sync/write_env.js +32 -0
  14. package/src/core/sync/write_root.js +1 -1
  15. package/src/core/sync/write_server.js +3 -2
  16. package/src/core/sync/write_tsconfig.js +1 -0
  17. package/src/exports/hooks/index.js +13 -0
  18. package/src/exports/internal/env.js +71 -0
  19. package/src/exports/internal/types.d.ts +3 -0
  20. package/src/exports/node/index.js +2 -10
  21. package/src/exports/public.d.ts +41 -1
  22. package/src/exports/vite/build/build_service_worker.js +20 -4
  23. package/src/exports/vite/dev/index.js +2 -2
  24. package/src/exports/vite/index.js +157 -33
  25. package/src/exports/vite/module_ids.js +10 -1
  26. package/src/exports/vite/utils.js +6 -0
  27. package/src/runtime/app/env/index.js +2 -0
  28. package/src/runtime/app/env/internal.js +11 -0
  29. package/src/runtime/app/env/private.js +1 -0
  30. package/src/runtime/app/env/public/client.js +7 -0
  31. package/src/runtime/app/env/public/index.js +1 -0
  32. package/src/runtime/app/env/public/server.js +7 -0
  33. package/src/runtime/app/env/standard-schema.d.ts +0 -0
  34. package/src/runtime/app/env/types.d.ts +19 -0
  35. package/src/runtime/app/environment/index.js +10 -2
  36. package/src/runtime/app/server/remote/query.js +1 -1
  37. package/src/runtime/app/state/client.js +10 -6
  38. package/src/runtime/client/client.js +68 -51
  39. package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
  40. package/src/runtime/client/utils.js +1 -1
  41. package/src/runtime/server/env_module.js +13 -3
  42. package/src/runtime/server/fetch.js +12 -14
  43. package/src/runtime/server/index.js +2 -0
  44. package/src/runtime/server/page/render.js +11 -3
  45. package/src/runtime/server/respond.js +8 -11
  46. package/src/types/ambient-private.d.ts +25 -9
  47. package/src/types/global-private.d.ts +2 -0
  48. package/src/types/internal.d.ts +1 -0
  49. package/src/utils/http.js +21 -0
  50. package/src/utils/import.js +2 -2
  51. package/src/version.js +1 -1
  52. package/types/index.d.ts +76 -4
  53. package/types/index.d.ts.map +7 -1
@@ -1,3 +1,4 @@
1
+ import { DEV } from 'esm-env';
1
2
  import {
2
3
  page as _page,
3
4
  navigating as _navigating,
@@ -53,12 +54,15 @@ export const navigating = {
53
54
  }
54
55
  };
55
56
 
56
- Object.defineProperty(navigating, 'current', {
57
- get() {
58
- // between 2.12.0 and 2.12.1 `navigating.current` existed
59
- throw new Error('Replace navigating.current.<prop> with navigating.<prop>');
60
- }
61
- });
57
+ // TODO: remove in 3.0
58
+ if (DEV) {
59
+ Object.defineProperty(navigating, 'current', {
60
+ get() {
61
+ // between 2.12.0 and 2.12.1 `navigating.current` existed
62
+ throw new Error('Replace navigating.current.<prop> with navigating.<prop>');
63
+ }
64
+ });
65
+ }
62
66
 
63
67
  export const updated = {
64
68
  get current() {
@@ -1,3 +1,4 @@
1
+ /** @import { ServerNodesResponse, ServerRedirectNode } from 'types' */
1
2
  /** @import { CacheEntry } from './remote-functions/cache.svelte.js' */
2
3
  /** @import { Query } from './remote-functions/query/instance.svelte.js' */
3
4
  /** @import { LiveQuery } from './remote-functions/query-live/instance.svelte.js' */
@@ -231,6 +232,7 @@ let load_cache = null;
231
232
  function discard_load_cache() {
232
233
  void load_cache?.fork?.then((f) => f?.discard());
233
234
  load_cache = null;
235
+ current_a = { element: undefined, href: undefined };
234
236
  }
235
237
 
236
238
  /**
@@ -1842,8 +1844,10 @@ async function navigate({
1842
1844
  if (load_cache?.fork && !load_cache_fork) {
1843
1845
  // discard fork of different route
1844
1846
  discard_load_cache();
1847
+ } else {
1848
+ load_cache = null;
1849
+ current_a = { element: undefined, href: undefined };
1845
1850
  }
1846
- load_cache = null;
1847
1851
 
1848
1852
  navigation_result.props.page.state = state;
1849
1853
 
@@ -2029,11 +2033,16 @@ if (import.meta.hot) {
2029
2033
 
2030
2034
  /** @typedef {(typeof PRELOAD_PRIORITIES)['hover'] | (typeof PRELOAD_PRIORITIES)['tap']} PreloadDataPriority */
2031
2035
 
2036
+ /**
2037
+ * The anchor element whose href is being preloaded. It is reset after navigation
2038
+ * or changes when a different anchor element is being preloaded.
2039
+ * @type {{ element: Element | SVGAElement | undefined; href: string | SVGAnimatedString | undefined }}
2040
+ */
2041
+ let current_a = { element: undefined, href: undefined };
2042
+
2032
2043
  function setup_preload() {
2033
2044
  /** @type {NodeJS.Timeout} */
2034
2045
  let mousemove_timeout;
2035
- /** @type {{ element: Element | SVGAElement | undefined; href: string | SVGAnimatedString | undefined }} */
2036
- let current_a = { element: undefined, href: undefined };
2037
2046
  /** @type {PreloadDataPriority} */
2038
2047
  let current_priority;
2039
2048
 
@@ -2626,7 +2635,7 @@ function _start_router() {
2626
2635
  });
2627
2636
 
2628
2637
  // @ts-expect-error this isn't supported everywhere yet
2629
- if (!navigator.connection?.saveData && !/2g/.test(navigator.connection?.effectiveType)) {
2638
+ if (!navigator.connection?.saveData) {
2630
2639
  setup_preload();
2631
2640
  }
2632
2641
 
@@ -3067,61 +3076,69 @@ async function load_data(url, invalid) {
3067
3076
  throw new HttpError(res.status, message);
3068
3077
  }
3069
3078
 
3070
- // TODO: fix eslint error / figure out if it actually applies to our situation
3071
- // eslint-disable-next-line
3072
- return new Promise(async (resolve) => {
3073
- /**
3074
- * Map of deferred promises that will be resolved by a subsequent chunk of data
3075
- * @type {Map<string, import('types').Deferred>}
3076
- */
3077
- const deferreds = new Map();
3078
- const reader = /** @type {ReadableStream<Uint8Array>} */ (res.body).getReader();
3079
-
3080
- /**
3081
- * @param {any} data
3082
- */
3083
- function deserialize(data) {
3084
- return devalue.unflatten(data, {
3085
- ...app.decoders,
3086
- Promise: (id) => {
3087
- return new Promise((fulfil, reject) => {
3088
- deferreds.set(id, { fulfil, reject });
3089
- });
3090
- }
3091
- });
3092
- }
3079
+ return new Promise((resolve, reject) => {
3080
+ process_stream(resolve, res).catch(reject);
3081
+ });
3093
3082
 
3094
- for await (const node of read_ndjson(reader)) {
3095
- if (node.type === 'redirect') {
3096
- return resolve(node);
3097
- }
3083
+ // TODO edge case handling necessary? stream() read fails?
3084
+ }
3098
3085
 
3099
- if (node.type === 'data') {
3100
- // This is the first (and possibly only, if no pending promises) chunk
3101
- node.nodes?.forEach((/** @type {any} */ node) => {
3102
- if (node?.type === 'data') {
3103
- node.uses = deserialize_uses(node.uses);
3104
- node.data = deserialize(node.data);
3105
- }
3086
+ /**
3087
+ * @param {(value: ServerNodesResponse | ServerRedirectNode) => void} resolve
3088
+ * @param {Response} res
3089
+ * @returns {Promise<void>}
3090
+ */
3091
+ async function process_stream(resolve, res) {
3092
+ const reader = /** @type {ReadableStream<Uint8Array>} */ (res.body).getReader();
3093
+
3094
+ /**
3095
+ * Map of deferred promises that will be resolved by a subsequent chunk of data
3096
+ * @type {Map<string, import('types').Deferred>}
3097
+ */
3098
+ const deferreds = new Map();
3099
+
3100
+ /**
3101
+ * @param {any} data
3102
+ */
3103
+ function deserialize(data) {
3104
+ return devalue.unflatten(data, {
3105
+ ...app.decoders,
3106
+ Promise: (id) => {
3107
+ return new Promise((fulfil, reject) => {
3108
+ deferreds.set(id, { fulfil, reject });
3106
3109
  });
3110
+ }
3111
+ });
3112
+ }
3107
3113
 
3108
- resolve(node);
3109
- } else if (node.type === 'chunk') {
3110
- // This is a subsequent chunk containing deferred data
3111
- const { id, data, error } = node;
3112
- const deferred = /** @type {import('types').Deferred} */ (deferreds.get(id));
3113
- deferreds.delete(id);
3114
+ for await (const node of read_ndjson(reader)) {
3115
+ if (node.type === 'redirect') {
3116
+ return resolve(node);
3117
+ }
3114
3118
 
3115
- if (error) {
3116
- deferred.reject(deserialize(error));
3117
- } else {
3118
- deferred.fulfil(deserialize(data));
3119
+ if (node.type === 'data') {
3120
+ // This is the first (and possibly only, if no pending promises) chunk
3121
+ node.nodes?.forEach((/** @type {any} */ node) => {
3122
+ if (node?.type === 'data') {
3123
+ node.uses = deserialize_uses(node.uses);
3124
+ node.data = deserialize(node.data);
3119
3125
  }
3126
+ });
3127
+
3128
+ resolve(node);
3129
+ } else if (node.type === 'chunk') {
3130
+ // This is a subsequent chunk containing deferred data
3131
+ const { id, data, error } = node;
3132
+ const deferred = /** @type {import('types').Deferred} */ (deferreds.get(id));
3133
+ deferreds.delete(id);
3134
+
3135
+ if (error) {
3136
+ deferred.reject(deserialize(error));
3137
+ } else {
3138
+ deferred.fulfil(deserialize(data));
3120
3139
  }
3121
3140
  }
3122
- });
3123
-
3124
- // TODO edge case handling necessary? stream() read fails?
3141
+ }
3125
3142
  }
3126
3143
 
3127
3144
  /**
@@ -1,6 +1,6 @@
1
1
  /** @import { RemotePrerenderFunction } from '@sveltejs/kit' */
2
2
  import { app_dir, base } from '$app/paths/internal/client';
3
- import { version } from '__sveltekit/environment';
3
+ import { version } from '$app/env';
4
4
  import * as devalue from 'devalue';
5
5
  import { app, prerender_responses } from '../client.js';
6
6
  import { get_remote_request_headers, remote_request } from './shared.svelte.js';
@@ -1,7 +1,7 @@
1
1
  import { BROWSER, DEV } from 'esm-env';
2
2
  import { writable } from 'svelte/store';
3
3
  import { assets } from '$app/paths';
4
- import { version } from '__sveltekit/environment';
4
+ import { version } from '$app/env';
5
5
  import { noop } from '../../utils/functions.js';
6
6
  import { PRELOAD_PRIORITIES } from './constants.js';
7
7
 
@@ -1,7 +1,9 @@
1
+ import * as devalue from 'devalue';
1
2
  import { public_env } from '../shared-server.js';
3
+ import { rendered_env } from '__sveltekit/env';
2
4
 
3
5
  /** @type {string} */
4
- let body;
6
+ let payload;
5
7
 
6
8
  /** @type {string} */
7
9
  let etag;
@@ -14,7 +16,11 @@ let headers;
14
16
  * @returns {Response}
15
17
  */
16
18
  export function get_public_env(request) {
17
- body ??= `export const env=${JSON.stringify(public_env)}`;
19
+ const script = request.url.endsWith('.script.js');
20
+
21
+ const env = __SVELTEKIT_EXPERIMENTAL_EXPLICIT_ENVIRONMENT_VARIABLES__ ? rendered_env : public_env;
22
+
23
+ payload ??= devalue.uneval(env);
18
24
  etag ??= `W/${Date.now()}`;
19
25
  headers ??= new Headers({
20
26
  'content-type': 'application/javascript; charset=utf-8',
@@ -25,5 +31,9 @@ export function get_public_env(request) {
25
31
  return new Response(undefined, { status: 304, headers });
26
32
  }
27
33
 
28
- return new Response(body, { headers });
34
+ if (script) {
35
+ return new Response(`globalThis.__sveltekit_sw={env:${payload}}`, { headers });
36
+ }
37
+
38
+ return new Response(`export const env=${payload}`, { headers });
29
39
  }
@@ -1,5 +1,6 @@
1
1
  import * as set_cookie_parser from 'set-cookie-parser';
2
2
  import { noop } from '../../utils/functions.js';
3
+ import { get_set_cookies } from '../../utils/http.js';
3
4
  import { respond } from './respond.js';
4
5
  import * as paths from '$app/paths/internal/server';
5
6
  import { read_implementation } from '__sveltekit/server';
@@ -152,22 +153,19 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
152
153
 
153
154
  const response = await internal_fetch(request, options, manifest, state);
154
155
 
155
- const set_cookie = response.headers.get('set-cookie');
156
- if (set_cookie) {
157
- for (const str of set_cookie_parser.splitCookiesString(set_cookie)) {
158
- const { name, value, ...options } = set_cookie_parser.parseString(str, {
159
- decodeValues: false
160
- });
156
+ for (const str of get_set_cookies(response.headers)) {
157
+ const { name, value, ...options } = set_cookie_parser.parseString(str, {
158
+ decodeValues: false
159
+ });
161
160
 
162
- const path = options.path ?? (url.pathname.split('/').slice(0, -1).join('/') || '/');
161
+ const path = options.path ?? (url.pathname.split('/').slice(0, -1).join('/') || '/');
163
162
 
164
- // options.sameSite is string, something more specific is required - type cast is safe
165
- set_internal(name, value, {
166
- path,
167
- encode: (value) => value,
168
- .../** @type {import('cookie').CookieSerializeOptions} */ (options)
169
- });
170
- }
163
+ // options.sameSite is string, something more specific is required - type cast is safe
164
+ set_internal(name, value, {
165
+ path,
166
+ encode: (value) => value,
167
+ .../** @type {import('cookie').CookieSerializeOptions} */ (options)
168
+ });
171
169
  }
172
170
 
173
171
  return response;
@@ -8,6 +8,7 @@ import { options, get_hooks } from '__SERVER__/internal.js';
8
8
  import { filter_env } from '../../utils/env.js';
9
9
  import { format_server_error } from './utils.js';
10
10
  import { set_read_implementation, set_manifest } from '__sveltekit/server';
11
+ import { set_env } from '__sveltekit/env';
11
12
  import { set_app } from './app.js';
12
13
 
13
14
  /** @type {Promise<any>} */
@@ -62,6 +63,7 @@ export class Server {
62
63
 
63
64
  set_private_env(filter_env(env, env_private_prefix, env_public_prefix));
64
65
  set_public_env(filter_env(env, env_public_prefix, env_private_prefix));
66
+ set_env(env);
65
67
 
66
68
  if (read) {
67
69
  // Wrap the read function to handle MaybePromise<ReadableStream>
@@ -23,6 +23,7 @@ import {
23
23
  } from '../utils.js';
24
24
  import { create_remote_key } from '../../shared.js';
25
25
  import { get_status } from '../../../utils/error.js';
26
+ import * as env from '__sveltekit/env';
26
27
 
27
28
  // TODO rename this function/module
28
29
 
@@ -404,7 +405,10 @@ export async function render_response({
404
405
  // import the env.js module so that it evaluates before any user code can evaluate.
405
406
  // TODO revert to using top-level await once https://bugs.webkit.org/show_bug.cgi?id=242740 is fixed
406
407
  // https://github.com/sveltejs/kit/pull/11601
407
- const load_env_eagerly = client.uses_env_dynamic_public && state.prerendering;
408
+ const load_env_eagerly =
409
+ (__SVELTEKIT_EXPERIMENTAL_EXPLICIT_ENVIRONMENT_VARIABLES__ ||
410
+ client.uses_env_dynamic_public) &&
411
+ state.prerendering;
408
412
 
409
413
  const properties = [`base: ${base_expression}`];
410
414
 
@@ -412,7 +416,9 @@ export async function render_response({
412
416
  properties.push(`assets: ${s(paths.assets)}`);
413
417
  }
414
418
 
415
- if (client.uses_env_dynamic_public) {
419
+ if (__SVELTEKIT_EXPERIMENTAL_EXPLICIT_ENVIRONMENT_VARIABLES__) {
420
+ properties.push(`env: ${load_env_eagerly ? 'null' : devalue.uneval(env.rendered_env)}`);
421
+ } else if (client.uses_env_dynamic_public) {
416
422
  properties.push(`env: ${load_env_eagerly ? 'null' : s(public_env)}`);
417
423
  }
418
424
 
@@ -677,7 +683,9 @@ export async function render_response({
677
683
  body,
678
684
  assets,
679
685
  nonce: /** @type {string} */ (csp.nonce),
680
- env: public_env
686
+ env: __SVELTEKIT_EXPERIMENTAL_EXPLICIT_ENVIRONMENT_VARIABLES__
687
+ ? env.explicit_public_env
688
+ : public_env
681
689
  });
682
690
 
683
691
  // TODO flush chunks as early as we can
@@ -8,7 +8,7 @@ import { is_endpoint_request, render_endpoint } from './endpoint.js';
8
8
  import { render_page } from './page/index.js';
9
9
  import { render_response } from './page/render.js';
10
10
  import { respond_with_error } from './page/respond_with_error.js';
11
- import { is_form_content_type } from '../../utils/http.js';
11
+ import { get_set_cookies, is_form_content_type } from '../../utils/http.js';
12
12
  import {
13
13
  handle_fatal_error,
14
14
  has_prerendered_path,
@@ -317,7 +317,7 @@ export async function internal_respond(request, options, manifest, state) {
317
317
  return resolve_route(resolved_path, new URL(request.url), manifest);
318
318
  }
319
319
 
320
- if (resolved_path === `/${app_dir}/env.js`) {
320
+ if (resolved_path === `/${app_dir}/env.js` || resolved_path === `/${app_dir}/env.script.js`) {
321
321
  return get_public_env(request);
322
322
  }
323
323
 
@@ -511,19 +511,16 @@ export async function internal_respond(request, options, manifest, state) {
511
511
  if (if_none_match_value === etag) {
512
512
  const headers = new Headers({ etag });
513
513
 
514
- // https://datatracker.ietf.org/doc/html/rfc7232#section-4.1 + set-cookie
515
- for (const key of [
516
- 'cache-control',
517
- 'content-location',
518
- 'date',
519
- 'expires',
520
- 'vary',
521
- 'set-cookie'
522
- ]) {
514
+ // https://datatracker.ietf.org/doc/html/rfc7232#section-4.1
515
+ for (const key of ['cache-control', 'content-location', 'date', 'expires', 'vary']) {
523
516
  const value = response.headers.get(key);
524
517
  if (value) headers.set(key, value);
525
518
  }
526
519
 
520
+ for (const cookie of get_set_cookies(response.headers)) {
521
+ headers.append('set-cookie', cookie);
522
+ }
523
+
527
524
  return new Response(undefined, {
528
525
  status: 304,
529
526
  headers
@@ -1,12 +1,3 @@
1
- /** Internal version of $app/environment */
2
- declare module '__sveltekit/environment' {
3
- export const building: boolean;
4
- export const prerendering: boolean;
5
- export const version: string;
6
- export function set_building(): void;
7
- export function set_prerendering(): void;
8
- }
9
-
10
1
  /** Internal version of $app/paths */
11
2
  declare module '__sveltekit/paths' {
12
3
  export let base: '' | `/${string}`;
@@ -27,3 +18,28 @@ declare module '__sveltekit/server' {
27
18
  export function set_manifest(manifest: SSRManifest): void;
28
19
  export function set_read_implementation(fn: (path: string) => ReadableStream): void;
29
20
  }
21
+
22
+ declare module '__sveltekit/env' {
23
+ // exported environment variables are defined in env.d.ts
24
+
25
+ /** Populate exported environment variables */
26
+ export function set_env(environment: Record<string, string>): void;
27
+
28
+ /** public env vars */
29
+ export const explicit_public_env: Record<string, any>;
30
+
31
+ /** public env vars that should be inlined when a page is rendered */
32
+ export const rendered_env: Record<string, any>;
33
+ }
34
+
35
+ declare module '__sveltekit/env/private' {
36
+ // exported environment variables are defined in env.d.ts
37
+ }
38
+
39
+ declare module '__sveltekit/env/public/client' {
40
+ // exported environment variables are defined in env.d.ts
41
+ }
42
+
43
+ declare module '__sveltekit/env/public/server' {
44
+ // exported environment variables are defined in env.d.ts
45
+ }
@@ -1,6 +1,7 @@
1
1
  declare global {
2
2
  const __SVELTEKIT_ADAPTER_NAME__: string;
3
3
  const __SVELTEKIT_APP_DIR__: string;
4
+ const __SVELTEKIT_APP_VERSION__: string;
4
5
  const __SVELTEKIT_APP_VERSION_FILE__: string;
5
6
  const __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: number;
6
7
  /**
@@ -63,6 +64,7 @@ declare global {
63
64
  */
64
65
  var __SVELTEKIT_TRACK__: (label: string) => void;
65
66
  var __SVELTEKIT_EXPERIMENTAL_USE_TRANSFORM_ERROR__: boolean;
67
+ var __SVELTEKIT_EXPERIMENTAL_EXPLICIT_ENVIRONMENT_VARIABLES__: boolean;
66
68
  var Bun: object;
67
69
  var Deno: object;
68
70
  }
@@ -44,6 +44,7 @@ export interface ServerModule {
44
44
  export interface ServerInternalModule {
45
45
  set_assets(path: string): void;
46
46
  set_building(): void;
47
+ set_env(environment: Record<string, string>): void;
47
48
  set_manifest(manifest: SSRManifest): void;
48
49
  set_prerendering(): void;
49
50
  set_private_env(environment: Record<string, string>): void;
package/src/utils/http.js CHANGED
@@ -1,3 +1,4 @@
1
+ import * as set_cookie_parser from 'set-cookie-parser';
1
2
  import { BINARY_FORM_CONTENT_TYPE } from '../runtime/form-utils.js';
2
3
 
3
4
  /**
@@ -56,6 +57,26 @@ export function negotiate(accept, types) {
56
57
  return accepted;
57
58
  }
58
59
 
60
+ /**
61
+ * Reads all `Set-Cookie` headers as separate values. `Headers.get('set-cookie')`
62
+ * collapses them into a single comma-joined string that browsers cannot parse, so
63
+ * we use `Headers.getSetCookie()` where available and fall back to splitting the
64
+ * joined string otherwise.
65
+ *
66
+ * TODO 3.0 `getSetCookie` is available in Node 19.7+; once we drop support for
67
+ * older versions we can use it directly and remove the `splitCookiesString` fallback
68
+ * @param {Headers} headers
69
+ * @returns {string[]}
70
+ */
71
+ export function get_set_cookies(headers) {
72
+ if (typeof headers.getSetCookie === 'function') {
73
+ return headers.getSetCookie();
74
+ }
75
+
76
+ const set_cookie = headers.get('set-cookie');
77
+ return set_cookie ? set_cookie_parser.splitCookiesString(set_cookie) : [];
78
+ }
79
+
59
80
  /**
60
81
  * Returns `true` if the request contains a `content-type` header with the given type
61
82
  * @param {Request} request
@@ -45,8 +45,8 @@ function resolve_peer(dependency) {
45
45
  */
46
46
  export async function import_peer(dependency) {
47
47
  try {
48
- return await import(resolve_peer(dependency));
48
+ return await import(/* @vite-ignore */ resolve_peer(dependency));
49
49
  } catch {
50
- return await import(dependency);
50
+ return await import(/* @vite-ignore */ dependency);
51
51
  }
52
52
  }
package/src/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // generated during release, do not modify
2
2
 
3
3
  /** @type {string} */
4
- export const VERSION = '2.61.1';
4
+ export const VERSION = '2.63.0';
package/types/index.d.ts CHANGED
@@ -116,7 +116,7 @@ declare module '@sveltejs/kit' {
116
116
  generateFallback: (dest: string) => Promise<void>;
117
117
 
118
118
  /**
119
- * Generate a module exposing build-time environment variables as `$env/dynamic/public`.
119
+ * Generate a module exposing build-time environment variables as `$env/dynamic/public` if the app uses it.
120
120
  */
121
121
  generateEnvModule: () => void;
122
122
 
@@ -450,6 +450,13 @@ declare module '@sveltejs/kit' {
450
450
  };
451
451
  /** Experimental features. Here be dragons. These are not subject to semantic versioning, so breaking changes or removal can happen in any release. */
452
452
  experimental?: {
453
+ /**
454
+ * Whether to enable explicit environment variables using `src/env.js` or `src/env.ts`.
455
+ * @since 2.62.0
456
+ * @default false
457
+ */
458
+ explicitEnvironmentVariables?: boolean;
459
+
453
460
  /**
454
461
  * 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).
455
462
  * @default { server: false, serverFile: false }
@@ -2287,6 +2294,39 @@ declare module '@sveltejs/kit' {
2287
2294
  export type RemoteLiveQueryFunction<Input, Output, _Validated = Input> = (
2288
2295
  arg: undefined extends Input ? Input | void : Input
2289
2296
  ) => RemoteLiveQuery<Output>;
2297
+
2298
+ /**
2299
+ * [Environment variables](https://svelte.dev/docs/kit/environment-variables) can be configured by exporting
2300
+ * a `variables` object from `src/env.ts`, using [`defineEnvVars`](https://svelte.dev/docs/kit/@sveltejs-kit-hooks#defineEnvVars).
2301
+ */
2302
+ export interface EnvVarConfig<T> {
2303
+ /**
2304
+ * Whether the environment variable can be accessed by client-side code.
2305
+ * - if `true`, it can be imported from `$app/env/public`
2306
+ * - if `false`, it can be imported from `$app/env/private`, which is a [server-only module](https://svelte.dev/docs/kit/server-only-modules)
2307
+ * @default false
2308
+ */
2309
+ public?: boolean;
2310
+ /**
2311
+ * Whether the value is determined at build time or when the app runs.
2312
+ * - if `true`, the build time value is inlined into the bundle. This enables optimisations like dead-code elimination
2313
+ * - if `false`, the value is read from the environment when the app starts
2314
+ * @default false
2315
+ */
2316
+ static?: boolean;
2317
+ /**
2318
+ * A [Standard Schema](https://standardschema.dev/) validator that is applied to the value when the app starts.
2319
+ * The validator can output any value — not necessarily a string — but public, non-static values must be
2320
+ * serializable by [devalue](https://github.com/sveltejs/devalue) so that they can be sent to the browser.
2321
+ *
2322
+ * If omitted, the value must be a non-empty string.
2323
+ */
2324
+ schema?: StandardSchemaV1<string | undefined, T>;
2325
+ /**
2326
+ * A description of the variable that will be used for inline documentation on hover.
2327
+ */
2328
+ description?: string;
2329
+ }
2290
2330
  interface AdapterEntry {
2291
2331
  /**
2292
2332
  * A string that uniquely identifies an HTTP service (e.g. serverless function) and is used for deduplication.
@@ -2923,7 +2963,7 @@ declare module '@sveltejs/kit' {
2923
2963
  class Redirect_1 {
2924
2964
 
2925
2965
  constructor(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308, location: string);
2926
- status: 301 | 302 | 303 | 307 | 308 | 300 | 304 | 305 | 306;
2966
+ status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308;
2927
2967
  location: string;
2928
2968
  }
2929
2969
 
@@ -2931,7 +2971,12 @@ declare module '@sveltejs/kit' {
2931
2971
  }
2932
2972
 
2933
2973
  declare module '@sveltejs/kit/hooks' {
2934
- import type { Handle } from '@sveltejs/kit';
2974
+ import type { EnvVarConfig, Handle } from '@sveltejs/kit';
2975
+ /**
2976
+ * Utility for defining [environment variables](https://svelte.dev/docs/kit/environment-variables),
2977
+ * which are made available via `$app/env/public` and `$app/env/private`.
2978
+ * */
2979
+ export function defineEnvVars<T extends Record<string, EnvVarConfig<any>>>(variables: T): T;
2935
2980
  /**
2936
2981
  * A helper function for sequencing multiple `handle` calls in a middleware-like manner.
2937
2982
  * The behavior for the `handle` options is as follows:
@@ -3036,11 +3081,38 @@ declare module '@sveltejs/kit/node/polyfills' {
3036
3081
  }
3037
3082
 
3038
3083
  declare module '@sveltejs/kit/vite' {
3084
+ import type { KitConfig } from '@sveltejs/kit';
3085
+ import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte';
3039
3086
  import type { Plugin } from 'vite';
3040
3087
  /**
3041
3088
  * Returns the SvelteKit Vite plugins.
3089
+ * Since version 2.62.0 you can pass [configuration](configuration) directly, in which case `svelte.config.js` is ignored.
3042
3090
  * */
3043
- export function sveltekit(): Promise<Plugin[]>;
3091
+ export function sveltekit(config?: KitConfig & Omit<SvelteConfig, "onwarn">): Promise<Plugin[]>;
3092
+
3093
+ export {};
3094
+ }
3095
+
3096
+ declare module '$app/env' {
3097
+ /**
3098
+ * `true` if the app is running in the browser.
3099
+ */
3100
+ export const browser: boolean;
3101
+
3102
+ /**
3103
+ * Whether the dev server is running. This is not guaranteed to correspond to `NODE_ENV` or `MODE`.
3104
+ */
3105
+ export const dev: boolean;
3106
+
3107
+ /**
3108
+ * SvelteKit analyses your app during the `build` step by running it. During this process, `building` is `true`. This also applies during prerendering.
3109
+ */
3110
+ export const building: boolean;
3111
+
3112
+ /**
3113
+ * The value of `config.kit.version.name`.
3114
+ */
3115
+ export const version: string;
3044
3116
 
3045
3117
  export {};
3046
3118
  }