@sveltejs/kit 1.30.2 → 2.0.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 (57) hide show
  1. package/package.json +24 -24
  2. package/src/core/adapt/builder.js +8 -1
  3. package/src/core/config/index.js +9 -1
  4. package/src/core/config/options.js +1 -12
  5. package/src/core/postbuild/analyse.js +98 -80
  6. package/src/core/postbuild/prerender.js +11 -9
  7. package/src/core/sync/sync.js +2 -0
  8. package/src/core/sync/write_non_ambient.js +42 -0
  9. package/src/core/sync/write_server.js +3 -3
  10. package/src/core/sync/write_tsconfig.js +27 -78
  11. package/src/core/sync/write_types/index.js +1 -1
  12. package/src/exports/hooks/sequence.js +1 -1
  13. package/src/exports/index.js +88 -71
  14. package/src/exports/node/index.js +21 -24
  15. package/src/exports/node/polyfills.js +5 -34
  16. package/src/exports/public.d.ts +82 -61
  17. package/src/exports/vite/dev/index.js +11 -19
  18. package/src/exports/vite/graph_analysis/index.js +2 -4
  19. package/src/exports/vite/index.js +73 -14
  20. package/src/exports/vite/module_ids.js +7 -0
  21. package/src/exports/vite/preview/index.js +56 -130
  22. package/src/runtime/app/forms.js +2 -35
  23. package/src/runtime/app/navigation.js +33 -18
  24. package/src/runtime/app/paths.js +2 -29
  25. package/src/runtime/client/client.js +449 -199
  26. package/src/runtime/client/constants.js +5 -1
  27. package/src/runtime/client/session-storage.js +7 -5
  28. package/src/runtime/client/singletons.js +7 -1
  29. package/src/runtime/client/types.d.ts +6 -2
  30. package/src/runtime/client/utils.js +12 -10
  31. package/src/runtime/control.js +16 -8
  32. package/src/runtime/server/cookie.js +38 -61
  33. package/src/runtime/server/data/index.js +6 -4
  34. package/src/runtime/server/env_module.js +29 -0
  35. package/src/runtime/server/fetch.js +7 -6
  36. package/src/runtime/server/index.js +23 -20
  37. package/src/runtime/server/page/actions.js +24 -15
  38. package/src/runtime/server/page/index.js +6 -8
  39. package/src/runtime/server/page/load_data.js +58 -40
  40. package/src/runtime/server/page/render.js +12 -7
  41. package/src/runtime/server/page/respond_with_error.js +4 -4
  42. package/src/runtime/server/page/types.d.ts +1 -1
  43. package/src/runtime/server/respond.js +14 -12
  44. package/src/runtime/server/utils.js +11 -8
  45. package/src/runtime/shared-server.js +19 -2
  46. package/src/types/ambient.d.ts +7 -1
  47. package/src/types/internal.d.ts +4 -1
  48. package/src/types/synthetic/$env+dynamic+private.md +2 -0
  49. package/src/types/synthetic/$env+dynamic+public.md +2 -0
  50. package/src/utils/error.js +17 -1
  51. package/src/utils/routing.js +47 -1
  52. package/src/utils/url.js +45 -27
  53. package/src/version.js +1 -1
  54. package/types/index.d.ts +171 -118
  55. package/types/index.d.ts.map +9 -5
  56. package/src/utils/platform.js +0 -1
  57. package/src/utils/promises.js +0 -61
@@ -2,7 +2,7 @@ import 'svelte'; // pick up `declare module "*.svelte"`
2
2
  import 'vite/client'; // pick up `declare module "*.jpg"`, etc.
3
3
  import '../types/ambient.js';
4
4
 
5
- import { CompileOptions } from 'svelte/types/compiler/interfaces';
5
+ import { CompileOptions } from 'svelte/compiler';
6
6
  import {
7
7
  AdapterEntry,
8
8
  CspDirectives,
@@ -17,12 +17,10 @@ import {
17
17
  RequestOptions,
18
18
  RouteSegment
19
19
  } from '../types/private.js';
20
- import { ActionFailure } from '../runtime/control.js';
21
20
  import { BuildData, SSRNodeLoader, SSRRoute, ValidatedConfig } from 'types';
22
21
  import type { PluginOptions } from '@sveltejs/vite-plugin-svelte';
23
22
 
24
23
  export { PrerenderOption } from '../types/private.js';
25
- export { ActionFailure };
26
24
 
27
25
  /**
28
26
  * [Adapters](https://kit.svelte.dev/docs/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing.
@@ -39,20 +37,11 @@ export interface Adapter {
39
37
  adapt(builder: Builder): MaybePromise<void>;
40
38
  }
41
39
 
42
- type AwaitedPropertiesUnion<input extends Record<string, any> | void> = input extends void
40
+ export type LoadProperties<input extends Record<string, any> | void> = input extends void
43
41
  ? undefined // needs to be undefined, because void will break intellisense
44
42
  : input extends Record<string, any>
45
- ? {
46
- [key in keyof input]: Awaited<input[key]>;
47
- }
48
- : {} extends input // handles the any case
49
- ? input
50
- : unknown;
51
-
52
- export type AwaitedProperties<input extends Record<string, any> | void> =
53
- AwaitedPropertiesUnion<input> extends Record<string, any>
54
- ? OptionalUnion<AwaitedPropertiesUnion<input>>
55
- : AwaitedPropertiesUnion<input>;
43
+ ? input
44
+ : unknown;
56
45
 
57
46
  export type AwaitedActions<T extends Record<string, (...args: any) => any>> = OptionalUnion<
58
47
  {
@@ -67,11 +56,19 @@ type OptionalUnion<
67
56
  A extends keyof U = U extends U ? keyof U : never
68
57
  > = U extends unknown ? { [P in Exclude<A, keyof U>]?: never } & U : never;
69
58
 
59
+ declare const uniqueSymbol: unique symbol;
60
+
61
+ export interface ActionFailure<T extends Record<string, unknown> | undefined = undefined> {
62
+ status: number;
63
+ data: T;
64
+ [uniqueSymbol]: true; // necessary or else UnpackValidationError could wrongly unpack objects with the same shape as ActionFailure
65
+ }
66
+
70
67
  type UnpackValidationError<T> = T extends ActionFailure<infer X>
71
68
  ? X
72
69
  : T extends void
73
- ? undefined // needs to be undefined, because void will corrupt union type
74
- : T;
70
+ ? undefined // needs to be undefined, because void will corrupt union type
71
+ : T;
75
72
 
76
73
  /**
77
74
  * This object is passed to the `adapt` function of adapters.
@@ -104,6 +101,11 @@ export interface Builder {
104
101
  */
105
102
  generateFallback(dest: string): Promise<void>;
106
103
 
104
+ /**
105
+ * Generate a module exposing build-time environment variables as `$env/dynamic/public`.
106
+ */
107
+ generateEnvModule(): void;
108
+
107
109
  /**
108
110
  * Generate a server-side manifest to initialise the SvelteKit [server](https://kit.svelte.dev/docs/types#public-types-server) with.
109
111
  * @param opts a relative path to the base directory of the app and optionally in which format (esm or cjs) the manifest should be generated
@@ -212,34 +214,42 @@ export interface Cookies {
212
214
  *
213
215
  * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`.
214
216
  *
215
- * By default, the `path` of a cookie is the 'directory' of the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app.
217
+ * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children
216
218
  * @param name the name of the cookie
217
219
  * @param value the cookie value
218
220
  * @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options)
219
221
  */
220
- set(name: string, value: string, opts?: import('cookie').CookieSerializeOptions): void;
222
+ set(
223
+ name: string,
224
+ value: string,
225
+ opts: import('cookie').CookieSerializeOptions & { path: string }
226
+ ): void;
221
227
 
222
228
  /**
223
229
  * Deletes a cookie by setting its value to an empty string and setting the expiry date in the past.
224
230
  *
225
- * By default, the `path` of a cookie is the 'directory' of the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app.
231
+ * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children
226
232
  * @param name the name of the cookie
227
233
  * @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options)
228
234
  */
229
- delete(name: string, opts?: import('cookie').CookieSerializeOptions): void;
235
+ delete(name: string, opts: import('cookie').CookieSerializeOptions & { path: string }): void;
230
236
 
231
237
  /**
232
238
  * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response.
233
239
  *
234
240
  * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`.
235
241
  *
236
- * By default, the `path` of a cookie is the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app.
242
+ * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children
237
243
  *
238
244
  * @param name the name of the cookie
239
245
  * @param value the cookie value
240
246
  * @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options)
241
247
  */
242
- serialize(name: string, value: string, opts?: import('cookie').CookieSerializeOptions): string;
248
+ serialize(
249
+ name: string,
250
+ value: string,
251
+ opts: import('cookie').CookieSerializeOptions & { path: string }
252
+ ): string;
243
253
  }
244
254
 
245
255
  export interface KitConfig {
@@ -279,7 +289,9 @@ export interface KitConfig {
279
289
  */
280
290
  alias?: Record<string, string>;
281
291
  /**
282
- * The directory relative to `paths.assets` where the built JS and CSS (and imported assets) are served from. (The filenames therein contain content-based hashes, meaning they can be cached indefinitely). Must not start or end with `/`.
292
+ * The directory where SvelteKit keeps its stuff, including static assets (such as JS and CSS) and internally-used routes.
293
+ *
294
+ * If `paths.assets` is specified, there will be two app directories — `${paths.assets}/${appDir}` and `${paths.base}/${appDir}`.
283
295
  * @default "_app"
284
296
  */
285
297
  appDir?: string;
@@ -343,16 +355,6 @@ export interface KitConfig {
343
355
  */
344
356
  checkOrigin?: boolean;
345
357
  };
346
- /**
347
- * Here be dragons. Enable at your peril.
348
- */
349
- dangerZone?: {
350
- /**
351
- * Automatically add server-side `fetch`ed URLs to the `dependencies` map of `load` functions. This will expose secrets
352
- * to the client if your URL contains them.
353
- */
354
- trackServerFetches?: boolean;
355
- };
356
358
  /**
357
359
  * Whether or not the app is embedded inside a larger app. If `true`, SvelteKit will add its event listeners related to navigation etc on the parent of `%sveltekit.body%` instead of `window`, and will pass `params` from the server rather than inferring them from `location.pathname`.
358
360
  * @default false
@@ -473,17 +475,20 @@ export interface KitConfig {
473
475
  */
474
476
  base?: '' | `/${string}`;
475
477
  /**
476
- * Whether to use relative asset paths. By default, if `paths.assets` is not external, SvelteKit will replace `%sveltekit.assets%` with a relative path and use relative paths to reference build artifacts, but `base` and `assets` imported from `$app/paths` will be as specified in your config.
478
+ * Whether to use relative asset paths.
477
479
  *
478
- * If `true`, `base` and `assets` imported from `$app/paths` will be replaced with relative asset paths during server-side rendering, resulting in portable HTML.
480
+ * If `true`, `base` and `assets` imported from `$app/paths` will be replaced with relative asset paths during server-side rendering, resulting in more portable HTML.
479
481
  * If `false`, `%sveltekit.assets%` and references to build artifacts will always be root-relative paths, unless `paths.assets` is an external URL
480
482
  *
481
483
  * [Single-page app](https://kit.svelte.dev/docs/single-page-apps) fallback pages will always use absolute paths, regardless of this setting.
482
484
  *
483
485
  * If your app uses a `<base>` element, you should set this to `false`, otherwise asset URLs will incorrectly be resolved against the `<base>` URL rather than the current page.
484
- * @default undefined
486
+ *
487
+ * In 1.0, `undefined` was a valid value, which was set by default. In that case, if `paths.assets` was not external, SvelteKit would replace `%sveltekit.assets%` with a relative path and use relative paths to reference build artifacts, but `base` and `assets` imported from `$app/paths` would be as specified in your config.
488
+ *
489
+ * @default true
485
490
  */
486
- relative?: boolean | undefined;
491
+ relative?: boolean;
487
492
  };
488
493
  /**
489
494
  * See [Prerendering](https://kit.svelte.dev/docs/page-options#prerender).
@@ -500,7 +505,7 @@ export interface KitConfig {
500
505
  */
501
506
  crawl?: boolean;
502
507
  /**
503
- * An array of pages to prerender, or start crawling from (if `crawl: true`). The `*` string includes all non-dynamic routes (i.e. pages with no `[parameters]`, because SvelteKit doesn't know what value the parameters should have).
508
+ * An array of pages to prerender, or start crawling from (if `crawl: true`). The `*` string includes all routes containing no required `[parameters]` with optional parameters included as being empty (since SvelteKit doesn't know what value any parameters should have).
504
509
  * @default ["*"]
505
510
  */
506
511
  entries?: Array<'*' | `/${string}`>;
@@ -652,6 +657,8 @@ export type Handle = (input: {
652
657
  export type HandleServerError = (input: {
653
658
  error: unknown;
654
659
  event: RequestEvent;
660
+ status: number;
661
+ message: string;
655
662
  }) => MaybePromise<void | App.Error>;
656
663
 
657
664
  /**
@@ -663,6 +670,8 @@ export type HandleServerError = (input: {
663
670
  export type HandleClientError = (input: {
664
671
  error: unknown;
665
672
  event: NavigationEvent;
673
+ status: number;
674
+ message: string;
666
675
  }) => MaybePromise<void | App.Error>;
667
676
 
668
677
  /**
@@ -781,7 +790,21 @@ export interface LoadEvent<
781
790
  * <button on:click={increase}>Increase Count</button>
782
791
  * ```
783
792
  */
784
- depends(...deps: string[]): void;
793
+ depends(...deps: Array<`${string}:${string}`>): void;
794
+ /**
795
+ * Use this function to opt out of dependency tracking for everything that is synchronously called within the callback. Example:
796
+ *
797
+ * ```js
798
+ * /// file: src/routes/+page.server.js
799
+ * export async function load({ untrack, url }) {
800
+ * // Untrack url.pathname so that path changes don't trigger a rerun
801
+ * if (untrack(() => url.pathname === '/')) {
802
+ * return { message: 'Welcome!' };
803
+ * }
804
+ * }
805
+ * ```
806
+ */
807
+ untrack<T>(fn: () => T): T;
785
808
  }
786
809
 
787
810
  export interface NavigationEvent<
@@ -848,7 +871,7 @@ export interface Navigation {
848
871
  /**
849
872
  * The type of navigation:
850
873
  * - `form`: The user submitted a `<form>`
851
- * - `leave`: The user is leaving the app by closing the tab or using the back/forward buttons to go to a different document
874
+ * - `leave`: The app is being left either because the tab is being closed or a navigation to a different document is occurring
852
875
  * - `link`: Navigation was triggered by a link click
853
876
  * - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
854
877
  * - `popstate`: Navigation was triggered by back/forward navigation
@@ -952,6 +975,10 @@ export interface Page<
952
975
  * The merged result of all data from all `load` functions on the current page. You can type a common denominator through `App.PageData`.
953
976
  */
954
977
  data: App.PageData & Record<string, any>;
978
+ /**
979
+ * The page state, which can be manipulated using the [`pushState`](https://kit.svelte.dev/docs/modules#$app-navigation-pushstate) and [`replaceState`](https://kit.svelte.dev/docs/modules#$app-navigation-replacestate) functions from `$app/navigation`.
980
+ */
981
+ state: App.PageState;
955
982
  /**
956
983
  * Filled only after a form submission. See [form actions](https://kit.svelte.dev/docs/form-actions) for more info.
957
984
  */
@@ -1183,6 +1210,20 @@ export interface ServerLoadEvent<
1183
1210
  * ```
1184
1211
  */
1185
1212
  depends(...deps: string[]): void;
1213
+ /**
1214
+ * Use this function to opt out of dependency tracking for everything that is synchronously called within the callback. Example:
1215
+ *
1216
+ * ```js
1217
+ * /// file: src/routes/+page.js
1218
+ * export async function load({ untrack, url }) {
1219
+ * // Untrack url.pathname so that path changes don't trigger a rerun
1220
+ * if (untrack(() => url.pathname === '/')) {
1221
+ * return { message: 'Welcome!' };
1222
+ * }
1223
+ * }
1224
+ * ```
1225
+ */
1226
+ untrack<T>(fn: () => T): T;
1186
1227
  }
1187
1228
 
1188
1229
  /**
@@ -1249,17 +1290,7 @@ export type SubmitFunction<
1249
1290
  Failure extends Record<string, unknown> | undefined = Record<string, any>
1250
1291
  > = (input: {
1251
1292
  action: URL;
1252
- /**
1253
- * use `formData` instead of `data`
1254
- * @deprecated
1255
- */
1256
- data: FormData;
1257
1293
  formData: FormData;
1258
- /**
1259
- * use `formElement` instead of `form`
1260
- * @deprecated
1261
- */
1262
- form: HTMLFormElement;
1263
1294
  formElement: HTMLFormElement;
1264
1295
  controller: AbortController;
1265
1296
  submitter: HTMLElement | null;
@@ -1267,17 +1298,7 @@ export type SubmitFunction<
1267
1298
  }) => MaybePromise<
1268
1299
  | void
1269
1300
  | ((opts: {
1270
- /**
1271
- * use `formData` instead of `data`
1272
- * @deprecated
1273
- */
1274
- data: FormData;
1275
1301
  formData: FormData;
1276
- /**
1277
- * use `formElement` instead of `form`
1278
- * @deprecated
1279
- */
1280
- form: HTMLFormElement;
1281
1302
  formElement: HTMLFormElement;
1282
1303
  action: URL;
1283
1304
  result: ActionResult<Success, Failure>;
@@ -8,7 +8,6 @@ import { getRequest, setResponse } from '../../../exports/node/index.js';
8
8
  import { installPolyfills } from '../../../exports/node/polyfills.js';
9
9
  import { coalesce_to_error } from '../../../utils/error.js';
10
10
  import { posixify, resolve_entry, to_fs } from '../../../utils/filesystem.js';
11
- import { should_polyfill } from '../../../utils/platform.js';
12
11
  import { load_error_page } from '../../../core/config/index.js';
13
12
  import { SVELTE_KIT_ASSETS } from '../../../constants.js';
14
13
  import * as sync from '../../../core/sync/sync.js';
@@ -26,9 +25,7 @@ const cwd = process.cwd();
26
25
  * @return {Promise<Promise<() => void>>}
27
26
  */
28
27
  export async function dev(vite, vite_config, svelte_config) {
29
- if (should_polyfill) {
30
- installPolyfills();
31
- }
28
+ installPolyfills();
32
29
 
33
30
  const fetch = globalThis.fetch;
34
31
  globalThis.fetch = (info, init) => {
@@ -123,7 +120,8 @@ export async function dev(vite, vite_config, svelte_config) {
123
120
  app: `${to_fs(svelte_config.kit.outDir)}/generated/client/app.js`,
124
121
  imports: [],
125
122
  stylesheets: [],
126
- fonts: []
123
+ fonts: [],
124
+ uses_env_dynamic_public: true
127
125
  },
128
126
  nodes: manifest_data.nodes.map((node, index) => {
129
127
  return async () => {
@@ -223,7 +221,7 @@ export async function dev(vite, vite_config, svelte_config) {
223
221
  ? async () => {
224
222
  const url = path.resolve(cwd, endpoint.file);
225
223
  return await loud_ssr_load_module(url);
226
- }
224
+ }
227
225
  : null,
228
226
  endpoint_id: endpoint?.file
229
227
  };
@@ -357,7 +355,8 @@ export async function dev(vite, vite_config, svelte_config) {
357
355
  control_module_node.replace_implementations({
358
356
  ActionFailure: control_module_vite.ActionFailure,
359
357
  HttpError: control_module_vite.HttpError,
360
- Redirect: control_module_vite.Redirect
358
+ Redirect: control_module_vite.Redirect,
359
+ SvelteKitError: control_module_vite.SvelteKitError
361
360
  });
362
361
  }
363
362
  align_exports();
@@ -473,17 +472,10 @@ export async function dev(vite, vite_config, svelte_config) {
473
472
 
474
473
  await server.init({ env });
475
474
 
476
- let request;
477
-
478
- try {
479
- request = await getRequest({
480
- base,
481
- request: req
482
- });
483
- } catch (/** @type {any} */ err) {
484
- res.statusCode = err.status || 400;
485
- return res.end('Invalid request body');
486
- }
475
+ const request = await getRequest({
476
+ base,
477
+ request: req
478
+ });
487
479
 
488
480
  if (manifest_error) {
489
481
  console.error(colors.bold().red(manifest_error.message));
@@ -537,7 +529,7 @@ export async function dev(vite, vite_config, svelte_config) {
537
529
  * @param {import('connect').Server} server
538
530
  */
539
531
  function remove_static_middlewares(server) {
540
- const static_middlewares = ['viteServeStaticMiddleware'];
532
+ const static_middlewares = ['viteServeStaticMiddleware', 'viteServePublicMiddleware'];
541
533
  for (let i = server.stack.length - 1; i > 0; i--) {
542
534
  // @ts-expect-error using internals
543
535
  if (static_middlewares.includes(server.stack[i].handle.name)) {
@@ -1,11 +1,9 @@
1
1
  import path from 'node:path';
2
2
  import { posixify } from '../../../utils/filesystem.js';
3
3
  import { strip_virtual_prefix } from '../utils.js';
4
+ import { env_dynamic_private, env_static_private } from '../module_ids.js';
4
5
 
5
- const ILLEGAL_IMPORTS = new Set([
6
- '\0virtual:$env/dynamic/private',
7
- '\0virtual:$env/static/private'
8
- ]);
6
+ const ILLEGAL_IMPORTS = new Set([env_dynamic_private, env_static_private]);
9
7
  const ILLEGAL_MODULE_NAME_PATTERN = /.*\.server\..+/;
10
8
 
11
9
  /**
@@ -1,5 +1,5 @@
1
1
  import fs from 'node:fs';
2
- import path from 'node:path';
2
+ import path, { join } from 'node:path';
3
3
 
4
4
  import { svelte } from '@sveltejs/vite-plugin-svelte';
5
5
  import colors from 'kleur';
@@ -19,14 +19,23 @@ import { dev } from './dev/index.js';
19
19
  import { is_illegal, module_guard, normalize_id } from './graph_analysis/index.js';
20
20
  import { preview } from './preview/index.js';
21
21
  import { get_config_aliases, get_env, strip_virtual_prefix } from './utils.js';
22
+ import { SVELTE_KIT_ASSETS } from '../../constants.js';
22
23
  import { write_client_manifest } from '../../core/sync/write_client_manifest.js';
23
24
  import prerender from '../../core/postbuild/prerender.js';
24
25
  import analyse from '../../core/postbuild/analyse.js';
25
26
  import { s } from '../../utils/misc.js';
26
27
  import { hash } from '../../runtime/hash.js';
27
28
  import { dedent, isSvelte5Plus } from '../../core/sync/utils.js';
28
-
29
- export { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
29
+ import sirv from 'sirv';
30
+ import {
31
+ env_dynamic_private,
32
+ env_dynamic_public,
33
+ env_static_private,
34
+ env_static_public,
35
+ service_worker,
36
+ sveltekit_environment,
37
+ sveltekit_paths
38
+ } from './module_ids.js';
30
39
 
31
40
  const cwd = process.cwd();
32
41
 
@@ -72,7 +81,7 @@ const options_regex = /(export\s+const\s+(prerender|csr|ssr|trailingSlash))\s*=/
72
81
  /** @type {Set<string>} */
73
82
  const warned = new Set();
74
83
 
75
- /** @type {import('@sveltejs/vite-plugin-svelte').PreprocessorGroup} */
84
+ /** @type {import('svelte/compiler').PreprocessorGroup} */
76
85
  const warning_preprocessor = {
77
86
  script: ({ content, filename }) => {
78
87
  if (!filename) return;
@@ -363,22 +372,22 @@ function kit({ svelte_config }) {
363
372
  }
364
373
 
365
374
  switch (id) {
366
- case '\0virtual:$env/static/private':
375
+ case env_static_private:
367
376
  return create_static_module('$env/static/private', env.private);
368
377
 
369
- case '\0virtual:$env/static/public':
378
+ case env_static_public:
370
379
  return create_static_module('$env/static/public', env.public);
371
380
 
372
- case '\0virtual:$env/dynamic/private':
381
+ case env_dynamic_private:
373
382
  return create_dynamic_module(
374
383
  'private',
375
384
  vite_config_env.command === 'serve' ? env.private : undefined
376
385
  );
377
386
 
378
- case '\0virtual:$env/dynamic/public':
387
+ case env_dynamic_public:
379
388
  // populate `$env/dynamic/public` from `window`
380
389
  if (browser) {
381
- return `export const env = ${global}.env;`;
390
+ return `export const env = ${global}.env ?? (await import(/* @vite-ignore */ ${global}.base + '/' + '${kit.appDir}/env.js')).env;`;
382
391
  }
383
392
 
384
393
  return create_dynamic_module(
@@ -386,12 +395,12 @@ function kit({ svelte_config }) {
386
395
  vite_config_env.command === 'serve' ? env.public : undefined
387
396
  );
388
397
 
389
- case '\0virtual:$service-worker':
398
+ case service_worker:
390
399
  return create_service_worker_module(svelte_config);
391
400
 
392
401
  // for internal use only. it's published as $app/paths externally
393
402
  // we use this alias so that we won't collide with user aliases
394
- case '\0virtual:__sveltekit/paths': {
403
+ case sveltekit_paths: {
395
404
  const { assets, base } = svelte_config.kit.paths;
396
405
 
397
406
  // use the values defined in `global`, but fall back to hard-coded values
@@ -429,7 +438,7 @@ function kit({ svelte_config }) {
429
438
  `;
430
439
  }
431
440
 
432
- case '\0virtual:__sveltekit/environment': {
441
+ case sveltekit_environment: {
433
442
  const { version } = svelte_config.kit;
434
443
 
435
444
  return dedent`
@@ -570,7 +579,7 @@ function kit({ svelte_config }) {
570
579
  preserveEntrySignatures: 'strict'
571
580
  },
572
581
  ssrEmitAssets: true,
573
- target: ssr ? 'node16.14' : undefined
582
+ target: ssr ? 'node18.13' : 'es2022'
574
583
  },
575
584
  publicDir: kit.files.assets,
576
585
  worker: {
@@ -617,6 +626,31 @@ function kit({ svelte_config }) {
617
626
  * @see https://vitejs.dev/guide/api-plugin.html#configurepreviewserver
618
627
  */
619
628
  configurePreviewServer(vite) {
629
+ // generated client assets and the contents of `static`
630
+ // should we use Vite's built-in asset server for this?
631
+ // we would need to set the outDir to do so
632
+ const { paths } = svelte_config.kit;
633
+ const assets = paths.assets ? SVELTE_KIT_ASSETS : paths.base;
634
+ vite.middlewares.use(
635
+ scoped(
636
+ assets,
637
+ sirv(join(svelte_config.kit.outDir, 'output/client'), {
638
+ setHeaders: (res, pathname) => {
639
+ if (pathname.startsWith(`/${svelte_config.kit.appDir}/immutable`)) {
640
+ res.setHeader('cache-control', 'public,max-age=31536000,immutable');
641
+ }
642
+ if (vite_config.preview.cors) {
643
+ res.setHeader('Access-Control-Allow-Origin', '*');
644
+ res.setHeader(
645
+ 'Access-Control-Allow-Headers',
646
+ 'Origin, Content-Type, Accept, Range'
647
+ );
648
+ }
649
+ }
650
+ })
651
+ )
652
+ );
653
+
620
654
  return preview(vite, vite_config, svelte_config);
621
655
  },
622
656
 
@@ -738,7 +772,10 @@ function kit({ svelte_config }) {
738
772
  app: app.file,
739
773
  imports: [...start.imports, ...app.imports],
740
774
  stylesheets: [...start.stylesheets, ...app.stylesheets],
741
- fonts: [...start.fonts, ...app.fonts]
775
+ fonts: [...start.fonts, ...app.fonts],
776
+ uses_env_dynamic_public: output.some(
777
+ (chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public]
778
+ )
742
779
  };
743
780
 
744
781
  const css = output.filter(
@@ -906,3 +943,25 @@ const create_service_worker_module = (config) => dedent`
906
943
  export const prerendered = [];
907
944
  export const version = ${s(config.kit.version.name)};
908
945
  `;
946
+
947
+ /**
948
+ * @param {string} scope
949
+ * @param {(req: import('http').IncomingMessage, res: import('http').ServerResponse, next: () => void) => void} handler
950
+ * @returns {(req: import('http').IncomingMessage, res: import('http').ServerResponse, next: () => void) => void}
951
+ */
952
+ function scoped(scope, handler) {
953
+ if (scope === '') return handler;
954
+
955
+ return (req, res, next) => {
956
+ if (req.url?.startsWith(scope)) {
957
+ const original_url = req.url;
958
+ req.url = req.url.slice(scope.length);
959
+ handler(req, res, () => {
960
+ req.url = original_url;
961
+ next();
962
+ });
963
+ } else {
964
+ next();
965
+ }
966
+ };
967
+ }
@@ -0,0 +1,7 @@
1
+ export const env_static_private = '\0virtual:$env/static/private';
2
+ export const env_static_public = '\0virtual:$env/static/public';
3
+ export const env_dynamic_private = '\0virtual:$env/dynamic/private';
4
+ export const env_dynamic_public = '\0virtual:$env/dynamic/public';
5
+ export const service_worker = '\0virtual:$service-worker';
6
+ export const sveltekit_paths = '\0virtual:__sveltekit/paths';
7
+ export const sveltekit_environment = '\0virtual:__sveltekit/environment';