@sveltejs/kit 1.0.0-next.372 → 1.0.0-next.375

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.
@@ -17,10 +17,14 @@ function coalesce_to_error(err) {
17
17
  }
18
18
 
19
19
  /**
20
- * @param {import('types').LoadOutput} loaded
20
+ * @param {import('types').LoadOutput | void} loaded
21
21
  * @returns {import('types').NormalizedLoadOutput}
22
22
  */
23
23
  function normalize(loaded) {
24
+ if (!loaded) {
25
+ return {};
26
+ }
27
+
24
28
  // TODO remove for 1.0
25
29
  // @ts-expect-error
26
30
  if (loaded.fallthrough) {
@@ -40,7 +44,10 @@ function normalize(loaded) {
40
44
  const status = loaded.status;
41
45
 
42
46
  if (!loaded.error && has_error_status) {
43
- return { status: status || 500, error: new Error() };
47
+ return {
48
+ status: status || 500,
49
+ error: new Error(`${status}`)
50
+ };
44
51
  }
45
52
 
46
53
  const error = typeof loaded.error === 'string' ? new Error(loaded.error) : loaded.error;
@@ -1030,24 +1037,17 @@ function create_client({ target, session, base, trailing_slash }) {
1030
1037
  });
1031
1038
  }
1032
1039
 
1033
- let loaded;
1034
-
1035
1040
  if (import.meta.env.DEV) {
1036
1041
  try {
1037
1042
  lock_fetch();
1038
- loaded = await module.load.call(null, load_input);
1043
+ node.loaded = normalize(await module.load.call(null, load_input));
1039
1044
  } finally {
1040
1045
  unlock_fetch();
1041
1046
  }
1042
1047
  } else {
1043
- loaded = await module.load.call(null, load_input);
1044
- }
1045
-
1046
- if (!loaded) {
1047
- throw new Error('load function must return a value');
1048
+ node.loaded = normalize(await module.load.call(null, load_input));
1048
1049
  }
1049
1050
 
1050
- node.loaded = normalize(loaded);
1051
1051
  if (node.loaded.stuff) node.stuff = node.loaded.stuff;
1052
1052
  if (node.loaded.dependencies) {
1053
1053
  node.loaded.dependencies.forEach(add_dependency);
@@ -1088,7 +1088,7 @@ function create_client({ target, session, base, trailing_slash }) {
1088
1088
  let stuff = root_stuff;
1089
1089
  let stuff_changed = false;
1090
1090
 
1091
- /** @type {number | undefined} */
1091
+ /** @type {number} */
1092
1092
  let status = 200;
1093
1093
 
1094
1094
  /** @type {Error | null} */
@@ -1174,7 +1174,7 @@ function create_client({ target, session, base, trailing_slash }) {
1174
1174
 
1175
1175
  if (node.loaded) {
1176
1176
  if (node.loaded.error) {
1177
- status = node.loaded.status;
1177
+ status = node.loaded.status ?? 500;
1178
1178
  error = node.loaded.error;
1179
1179
  }
1180
1180
 
@@ -1703,7 +1703,7 @@ function create_client({ target, session, base, trailing_slash }) {
1703
1703
  if (node.loaded.error) {
1704
1704
  if (error) throw node.loaded.error;
1705
1705
  error_args = {
1706
- status: node.loaded.status,
1706
+ status: node.loaded.status ?? 500,
1707
1707
  error: node.loaded.error,
1708
1708
  url,
1709
1709
  routeId
@@ -192,6 +192,11 @@ function clone_error(error, get_stack) {
192
192
  return object;
193
193
  }
194
194
 
195
+ /** @type {import('types').SSRErrorPage} */
196
+ const GENERIC_ERROR = {
197
+ id: '__error'
198
+ };
199
+
195
200
  /** @param {string} body */
196
201
  function error(body) {
197
202
  return new Response(body, {
@@ -1369,6 +1374,14 @@ async function render_response({
1369
1374
  }
1370
1375
 
1371
1376
  if (resolve_opts.ssr) {
1377
+ const leaf = /** @type {import('./types.js').Loaded} */ (branch.at(-1));
1378
+
1379
+ if (leaf.loaded.status) {
1380
+ // explicit status returned from `load` or a page endpoint trumps
1381
+ // initial status
1382
+ status = leaf.loaded.status;
1383
+ }
1384
+
1372
1385
  for (const { node, props, loaded, fetched, uses_credentials } of branch) {
1373
1386
  if (node.imports) {
1374
1387
  node.imports.forEach((url) => modulepreloads.add(url));
@@ -2096,10 +2109,14 @@ var parseString_1 = setCookie.exports.parseString = parseString;
2096
2109
  var splitCookiesString_1 = setCookie.exports.splitCookiesString = splitCookiesString;
2097
2110
 
2098
2111
  /**
2099
- * @param {import('types').LoadOutput} loaded
2112
+ * @param {import('types').LoadOutput | void} loaded
2100
2113
  * @returns {import('types').NormalizedLoadOutput}
2101
2114
  */
2102
2115
  function normalize(loaded) {
2116
+ if (!loaded) {
2117
+ return {};
2118
+ }
2119
+
2103
2120
  // TODO remove for 1.0
2104
2121
  // @ts-expect-error
2105
2122
  if (loaded.fallthrough) {
@@ -2119,7 +2136,10 @@ function normalize(loaded) {
2119
2136
  const status = loaded.status;
2120
2137
 
2121
2138
  if (!loaded.error && has_error_status) {
2122
- return { status: status || 500, error: new Error() };
2139
+ return {
2140
+ status: status || 500,
2141
+ error: new Error(`${status}`)
2142
+ };
2123
2143
  }
2124
2144
 
2125
2145
  const error = typeof loaded.error === 'string' ? new Error(loaded.error) : loaded.error;
@@ -2205,7 +2225,7 @@ function path_matches(path, constraint) {
2205
2225
  * event: import('types').RequestEvent;
2206
2226
  * options: import('types').SSROptions;
2207
2227
  * state: import('types').SSRState;
2208
- * route: import('types').SSRPage | null;
2228
+ * route: import('types').SSRPage | import('types').SSRErrorPage;
2209
2229
  * node: import('types').SSRNode;
2210
2230
  * $session: any;
2211
2231
  * stuff: Record<string, any>;
@@ -2241,7 +2261,7 @@ async function load_node({
2241
2261
  /** @type {import('set-cookie-parser').Cookie[]} */
2242
2262
  const new_cookies = [];
2243
2263
 
2244
- /** @type {import('types').LoadOutput} */
2264
+ /** @type {import('types').NormalizedLoadOutput} */
2245
2265
  let loaded;
2246
2266
 
2247
2267
  const should_prerender = node.module.prerender ?? options.prerender.default;
@@ -2264,12 +2284,10 @@ async function load_node({
2264
2284
 
2265
2285
  if (shadow.error) {
2266
2286
  loaded = {
2267
- status: shadow.status,
2268
2287
  error: shadow.error
2269
2288
  };
2270
2289
  } else if (shadow.redirect) {
2271
2290
  loaded = {
2272
- status: shadow.status,
2273
2291
  redirect: shadow.redirect
2274
2292
  };
2275
2293
  } else if (module.load) {
@@ -2537,7 +2555,7 @@ async function load_node({
2537
2555
  return proxy;
2538
2556
  },
2539
2557
  stuff: { ...stuff },
2540
- status: is_error ? status ?? null : null,
2558
+ status: (is_error ? status : shadow.status) ?? null,
2541
2559
  error: is_error ? error ?? null : null
2542
2560
  };
2543
2561
 
@@ -2550,12 +2568,7 @@ async function load_node({
2550
2568
  });
2551
2569
  }
2552
2570
 
2553
- loaded = await module.load.call(null, load_input);
2554
-
2555
- if (!loaded) {
2556
- // TODO do we still want to enforce this now that there's no fallthrough?
2557
- throw new Error(`load function must return a value${options.dev ? ` (${node.file})` : ''}`);
2558
- }
2571
+ loaded = normalize(await module.load.call(null, load_input));
2559
2572
  } else if (shadow.body) {
2560
2573
  loaded = {
2561
2574
  props: shadow.body
@@ -2564,6 +2577,8 @@ async function load_node({
2564
2577
  loaded = {};
2565
2578
  }
2566
2579
 
2580
+ loaded.status = loaded.status ?? shadow.status;
2581
+
2567
2582
  // generate __data.json files when prerendering
2568
2583
  if (shadow.body && state.prerendering) {
2569
2584
  const pathname = `${event.url.pathname.replace(/\/$/, '')}/__data.json`;
@@ -2579,7 +2594,7 @@ async function load_node({
2579
2594
  return {
2580
2595
  node,
2581
2596
  props: shadow.body,
2582
- loaded: normalize(loaded),
2597
+ loaded,
2583
2598
  stuff: loaded.stuff || stuff,
2584
2599
  fetched,
2585
2600
  set_cookie_headers: new_cookies.map((new_cookie) => {
@@ -2622,7 +2637,7 @@ async function load_shadow_data(route, event, options, prerender) {
2622
2637
 
2623
2638
  /** @type {import('types').ShadowData} */
2624
2639
  const data = {
2625
- status: 200,
2640
+ status: undefined,
2626
2641
  cookies: [],
2627
2642
  body: {}
2628
2643
  };
@@ -2662,13 +2677,13 @@ async function load_shadow_data(route, event, options, prerender) {
2662
2677
  if (get) {
2663
2678
  const { status, headers, body } = validate_shadow_output(await get(event));
2664
2679
  add_cookies(/** @type {string[]} */ (data.cookies), headers);
2665
- data.status = status;
2666
2680
 
2667
2681
  if (body instanceof Error) {
2668
2682
  if (status < 400) {
2669
2683
  data.status = 500;
2670
2684
  data.error = new Error('A non-error status code was returned with an error body');
2671
2685
  } else {
2686
+ data.status = status;
2672
2687
  data.error = body;
2673
2688
  }
2674
2689
 
@@ -2676,11 +2691,13 @@ async function load_shadow_data(route, event, options, prerender) {
2676
2691
  }
2677
2692
 
2678
2693
  if (status >= 400) {
2694
+ data.status = status;
2679
2695
  data.error = new Error('Failed to load data');
2680
2696
  return data;
2681
2697
  }
2682
2698
 
2683
2699
  if (status >= 300) {
2700
+ data.status = status;
2684
2701
  data.redirect = /** @type {string} */ (
2685
2702
  headers instanceof Headers ? headers.get('location') : headers.location
2686
2703
  );
@@ -2790,7 +2807,7 @@ async function respond_with_error({
2790
2807
  event,
2791
2808
  options,
2792
2809
  state,
2793
- route: null,
2810
+ route: GENERIC_ERROR,
2794
2811
  node: default_layout,
2795
2812
  $session,
2796
2813
  stuff: {},
@@ -2799,12 +2816,16 @@ async function respond_with_error({
2799
2816
  })
2800
2817
  );
2801
2818
 
2819
+ if (layout_loaded.loaded.error) {
2820
+ throw layout_loaded.loaded.error;
2821
+ }
2822
+
2802
2823
  const error_loaded = /** @type {Loaded} */ (
2803
2824
  await load_node({
2804
2825
  event,
2805
2826
  options,
2806
2827
  state,
2807
- route: null,
2828
+ route: GENERIC_ERROR,
2808
2829
  node: default_error,
2809
2830
  $session,
2810
2831
  stuff: layout_loaded ? layout_loaded.stuff : {},
@@ -2969,7 +2990,8 @@ async function respond$1(opts) {
2969
2990
  }
2970
2991
 
2971
2992
  if (loaded.loaded.error) {
2972
- ({ status, error } = loaded.loaded);
2993
+ error = loaded.loaded.error;
2994
+ status = loaded.loaded.status ?? 500;
2973
2995
  }
2974
2996
  } catch (err) {
2975
2997
  const e = coalesce_to_error(err);
@@ -3448,6 +3470,12 @@ async function respond(request, options, state) {
3448
3470
  }
3449
3471
  }
3450
3472
 
3473
+ if (state.initiator === GENERIC_ERROR) {
3474
+ return new Response('Internal Server Error', {
3475
+ status: 500
3476
+ });
3477
+ }
3478
+
3451
3479
  // if this request came direct from the user, rather than
3452
3480
  // via a `fetch` in a `load`, render a 404 page
3453
3481
  if (!state.initiator) {
@@ -3502,6 +3530,7 @@ async function respond(request, options, state) {
3502
3530
  });
3503
3531
  }
3504
3532
 
3533
+ // TODO is this necessary? should we just return a plain 500 at this point?
3505
3534
  try {
3506
3535
  const $session = await options.hooks.getSession(event);
3507
3536
  return await respond_with_error({
@@ -623,7 +623,7 @@ async function load_config({ cwd = process.cwd() } = {}) {
623
623
  * @param {import('types').Config} config
624
624
  * @returns {import('types').ValidatedConfig}
625
625
  */
626
- function process_config(config, { cwd = process.cwd() }) {
626
+ function process_config(config, { cwd = process.cwd() } = {}) {
627
627
  const validated = validate_config(config);
628
628
 
629
629
  validated.kit.outDir = path__default.resolve(cwd, validated.kit.outDir);
@@ -107,9 +107,25 @@ var other = {"application/prs.cww":["cww"],"application/vnd.1000minds.decision-m
107
107
  let Mime = Mime_1;
108
108
  var mime = new Mime(standard, other);
109
109
 
110
- const get_runtime_path = /** @param {import('types').ValidatedKitConfig} config */ (config) =>
111
- posixify_path(path__default.join(config.outDir, 'runtime'))
112
- ;
110
+ /**
111
+ * Get the prefix for the `runtime` directory, for use with import declarations
112
+ * @param {import('types').ValidatedKitConfig} config
113
+ */
114
+ function get_runtime_prefix(config) {
115
+ {
116
+ return posixify_path(path__default.join(config.outDir, 'runtime'));
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Get the resolved path of the `runtime` directory
122
+ * @param {import('types').ValidatedKitConfig} config
123
+ */
124
+ function get_runtime_directory(config) {
125
+ {
126
+ return path__default.join(config.outDir, 'runtime');
127
+ }
128
+ }
113
129
 
114
130
  /** @param {string} str */
115
131
  function posixify_path(str) {
@@ -285,7 +301,7 @@ const DEFAULT = 'default';
285
301
  */
286
302
  function create_manifest_data({
287
303
  config,
288
- fallback = `${get_runtime_path(config.kit)}/components`,
304
+ fallback = `${get_runtime_directory(config.kit)}/components`,
289
305
  cwd = process.cwd()
290
306
  }) {
291
307
  /** @type {import('types').RouteData[]} */
@@ -989,4 +1005,4 @@ var sync = /*#__PURE__*/Object.freeze({
989
1005
  all: all
990
1006
  });
991
1007
 
992
- export { get_mime_lookup as a, all as b, sync as c, get_runtime_path as g, init as i, logger as l, parse_route_id as p, s, update as u };
1008
+ export { get_runtime_prefix as a, get_mime_lookup as b, all as c, sync as d, get_runtime_directory as g, init as i, logger as l, parse_route_id as p, s, update as u };
package/dist/cli.js CHANGED
@@ -18,7 +18,7 @@ function handle_error(e) {
18
18
  process.exit(1);
19
19
  }
20
20
 
21
- const prog = sade('svelte-kit').version('1.0.0-next.372');
21
+ const prog = sade('svelte-kit').version('1.0.0-next.375');
22
22
 
23
23
  prog
24
24
  .command('package')
@@ -46,7 +46,7 @@ prog
46
46
 
47
47
  try {
48
48
  const config = await load_config();
49
- const sync = await import('./chunks/sync.js').then(function (n) { return n.c; });
49
+ const sync = await import('./chunks/sync.js').then(function (n) { return n.d; });
50
50
  sync.all(config);
51
51
  } catch (error) {
52
52
  handle_error(error);
@@ -10389,7 +10389,7 @@ function requireFetch () {
10389
10389
  }
10390
10390
 
10391
10391
  // https://fetch.spec.whatwg.org/#finalize-and-report-timing
10392
- function finalizeAndReportTiming (response, initiatorType) {
10392
+ function finalizeAndReportTiming (response, initiatorType = 'other') {
10393
10393
  // 1. If response is an aborted network error, then return.
10394
10394
  if (response.type === 'error' && response.aborted) {
10395
10395
  return
@@ -11553,7 +11553,10 @@ function requireFetch () {
11553
11553
  // 2. Let forwardResponse be the result of running HTTP-network fetch
11554
11554
  // given httpFetchParams, includeCredentials, and isNewConnectionFetch.
11555
11555
  const forwardResponse = await httpNetworkFetch(
11556
- httpFetchParams);
11556
+ httpFetchParams,
11557
+ includeCredentials,
11558
+ isNewConnectionFetch
11559
+ );
11557
11560
 
11558
11561
  // 3. If httpRequest’s method is unsafe and forwardResponse’s status is
11559
11562
  // in the range 200 to 399, inclusive, invalidate appropriate stored
@@ -11655,8 +11658,8 @@ function requireFetch () {
11655
11658
  // https://fetch.spec.whatwg.org/#http-network-fetch
11656
11659
  async function httpNetworkFetch (
11657
11660
  fetchParams,
11658
- includeCredentials,
11659
- forceNewConnection
11661
+ includeCredentials = false,
11662
+ forceNewConnection = false
11660
11663
  ) {
11661
11664
  assert(!fetchParams.controller.connection || fetchParams.controller.connection.destroyed);
11662
11665
 
package/dist/node.js CHANGED
@@ -4495,7 +4495,7 @@ try {
4495
4495
  const POOL_SIZE = 65536;
4496
4496
 
4497
4497
  /** @param {(Blob | Uint8Array)[]} parts */
4498
- async function * toIterator (parts, clone) {
4498
+ async function * toIterator (parts, clone = true) {
4499
4499
  for (const part of parts) {
4500
4500
  if ('stream' in part) {
4501
4501
  yield * (/** @type {AsyncIterableIterator<Uint8Array>} */ (part.stream()));
package/dist/vite.js CHANGED
@@ -6,7 +6,7 @@ import { svelte } from '@sveltejs/vite-plugin-svelte';
6
6
  import * as vite from 'vite';
7
7
  import { loadConfigFromFile, searchForWorkspaceRoot } from 'vite';
8
8
  import { p as posixify, m as mkdirp, r as rimraf } from './chunks/write_tsconfig.js';
9
- import { g as get_runtime_path, s, i as init, u as update, a as get_mime_lookup, p as parse_route_id, b as all, l as logger } from './chunks/sync.js';
9
+ import { g as get_runtime_directory, s, i as init, a as get_runtime_prefix, u as update, b as get_mime_lookup, p as parse_route_id, c as all, l as logger } from './chunks/sync.js';
10
10
  import { pathToFileURL, URL as URL$1 } from 'url';
11
11
  import { installPolyfills } from './node/polyfills.js';
12
12
  import * as qs from 'querystring';
@@ -127,7 +127,7 @@ function get_aliases(config) {
127
127
  /** @type {Record<string, string>} */
128
128
  const alias = {
129
129
  __GENERATED__: path__default.posix.join(config.outDir, 'generated'),
130
- $app: `${get_runtime_path(config)}/app`,
130
+ $app: `${get_runtime_directory(config)}/app`,
131
131
 
132
132
  // For now, we handle `$lib` specially here rather than make it a default value for
133
133
  // `config.kit.alias` since it has special meaning for packaging, etc.
@@ -253,12 +253,13 @@ function find_deps$1(manifest, entry, add_dynamic_css) {
253
253
  */
254
254
  const get_default_config = function ({ config, input, ssr, outDir }) {
255
255
  return {
256
+ appType: 'custom',
256
257
  base: assets_base(config.kit),
257
258
  build: {
258
259
  cssCodeSplit: true,
259
260
  manifest: true,
260
261
  outDir,
261
- polyfillDynamicImport: false,
262
+ polyfillModulePreload: false,
262
263
  rollupOptions: {
263
264
  input,
264
265
  output: {
@@ -278,7 +279,6 @@ const get_default_config = function ({ config, input, ssr, outDir }) {
278
279
  resolve: {
279
280
  alias: get_aliases(config.kit)
280
281
  },
281
- // @ts-expect-error
282
282
  ssr: {
283
283
  // when developing against the Kit src code, we want to ensure that
284
284
  // our dependencies are bundled so that apps don't need to install
@@ -302,6 +302,9 @@ function assets_base(config) {
302
302
  }
303
303
 
304
304
  /**
305
+ * vite.config.js will contain vite-plugin-svelte-kit, which kicks off the server and service
306
+ * worker builds in a hook. When running the server and service worker builds we must remove
307
+ * the SvelteKit plugin so that we do not kick off additional instances of these builds.
305
308
  * @param {import('vite').UserConfig} config
306
309
  */
307
310
  function remove_svelte_kit(config) {
@@ -482,7 +485,7 @@ async function build_server(options, client) {
482
485
  config,
483
486
  hooks: app_relative(hooks_file),
484
487
  has_service_worker: config.kit.serviceWorker.register && !!service_worker_entry_file,
485
- runtime: get_runtime_path(config.kit),
488
+ runtime: posixify(path__default.relative(build_dir, get_runtime_directory(config.kit))),
486
489
  template: load_template(cwd, config)
487
490
  })
488
491
  );
@@ -1950,7 +1953,7 @@ function toHeaders(name, stats, isEtag) {
1950
1953
  return headers;
1951
1954
  }
1952
1955
 
1953
- function sirv (dir, opts) {
1956
+ function sirv (dir, opts={}) {
1954
1957
  dir = resolve$1(dir || '.');
1955
1958
 
1956
1959
  let isNotFound = opts.onNoMatch || is404;
@@ -2049,7 +2052,7 @@ async function dev(vite, vite_config, svelte_config) {
2049
2052
 
2050
2053
  init(svelte_config);
2051
2054
 
2052
- const runtime = get_runtime_path(svelte_config.kit);
2055
+ const runtime = get_runtime_prefix(svelte_config.kit);
2053
2056
 
2054
2057
  process.env.VITE_SVELTEKIT_APP_VERSION_POLL_INTERVAL = '0';
2055
2058
 
@@ -2077,7 +2080,7 @@ async function dev(vite, vite_config, svelte_config) {
2077
2080
  const url = id.startsWith('..') ? `/@fs${path__default.posix.resolve(id)}` : `/${id}`;
2078
2081
 
2079
2082
  const module = /** @type {import('types').SSRComponent} */ (
2080
- await vite.ssrLoadModule(url, { fixStacktrace: false })
2083
+ await vite.ssrLoadModule(url)
2081
2084
  );
2082
2085
 
2083
2086
  return {
@@ -2107,7 +2110,7 @@ async function dev(vite, vite_config, svelte_config) {
2107
2110
  (query.has('svelte') && query.get('type') === 'style')
2108
2111
  ) {
2109
2112
  try {
2110
- const mod = await vite.ssrLoadModule(dep.url, { fixStacktrace: false });
2113
+ const mod = await vite.ssrLoadModule(dep.url);
2111
2114
  styles[dep.url] = mod.default;
2112
2115
  } catch {
2113
2116
  // this can happen with dynamically imported modules, I think
@@ -2135,7 +2138,7 @@ async function dev(vite, vite_config, svelte_config) {
2135
2138
  shadow: route.shadow
2136
2139
  ? async () => {
2137
2140
  const url = path__default.resolve(cwd$1, /** @type {string} */ (route.shadow));
2138
- return await vite.ssrLoadModule(url, { fixStacktrace: false });
2141
+ return await vite.ssrLoadModule(url);
2139
2142
  }
2140
2143
  : null,
2141
2144
  a: route.a.map((id) => (id ? manifest_data.components.indexOf(id) : undefined)),
@@ -2151,7 +2154,7 @@ async function dev(vite, vite_config, svelte_config) {
2151
2154
  types,
2152
2155
  load: async () => {
2153
2156
  const url = path__default.resolve(cwd$1, route.file);
2154
- return await vite.ssrLoadModule(url, { fixStacktrace: false });
2157
+ return await vite.ssrLoadModule(url);
2155
2158
  }
2156
2159
  };
2157
2160
  }),
@@ -2162,7 +2165,7 @@ async function dev(vite, vite_config, svelte_config) {
2162
2165
  for (const key in manifest_data.matchers) {
2163
2166
  const file = manifest_data.matchers[key];
2164
2167
  const url = path__default.resolve(cwd$1, file);
2165
- const module = await vite.ssrLoadModule(url, { fixStacktrace: false });
2168
+ const module = await vite.ssrLoadModule(url);
2166
2169
 
2167
2170
  if (module.match) {
2168
2171
  matchers[key] = module.match;
@@ -2252,9 +2255,7 @@ async function dev(vite, vite_config, svelte_config) {
2252
2255
 
2253
2256
  /** @type {Partial<import('types').Hooks>} */
2254
2257
  const user_hooks = resolve_entry(svelte_config.kit.files.hooks)
2255
- ? await vite.ssrLoadModule(`/${svelte_config.kit.files.hooks}`, {
2256
- fixStacktrace: false
2257
- })
2258
+ ? await vite.ssrLoadModule(`/${svelte_config.kit.files.hooks}`)
2258
2259
  : {};
2259
2260
 
2260
2261
  const handle = user_hooks.handle || (({ event, resolve }) => resolve(event));
@@ -2294,15 +2295,13 @@ async function dev(vite, vite_config, svelte_config) {
2294
2295
  // can get loaded twice via different URLs, which causes failures. Might
2295
2296
  // require changes to Vite to fix
2296
2297
  const { default: root } = await vite.ssrLoadModule(
2297
- `/${posixify(path__default.relative(cwd$1, `${svelte_config.kit.outDir}/generated/root.svelte`))}`,
2298
- { fixStacktrace: false }
2298
+ `/${posixify(path__default.relative(cwd$1, `${svelte_config.kit.outDir}/generated/root.svelte`))}`
2299
2299
  );
2300
2300
 
2301
2301
  const paths = await vite.ssrLoadModule(
2302
2302
  true
2303
2303
  ? `/${posixify(path__default.relative(cwd$1, `${svelte_config.kit.outDir}/runtime/paths.js`))}`
2304
- : `/@fs${runtime}/paths.js`,
2305
- { fixStacktrace: false }
2304
+ : `/@fs${runtime}/paths.js`
2306
2305
  );
2307
2306
 
2308
2307
  paths.set_paths({
@@ -2408,7 +2407,7 @@ async function dev(vite, vite_config, svelte_config) {
2408
2407
  }
2409
2408
 
2410
2409
  /** @param {import('http').ServerResponse} res */
2411
- function not_found(res, message) {
2410
+ function not_found(res, message = 'Not found') {
2412
2411
  res.statusCode = 404;
2413
2412
  res.end(message);
2414
2413
  }
@@ -2417,12 +2416,7 @@ function not_found(res, message) {
2417
2416
  * @param {import('connect').Server} server
2418
2417
  */
2419
2418
  function remove_html_middlewares(server) {
2420
- const html_middlewares = [
2421
- 'viteIndexHtmlMiddleware',
2422
- 'vite404Middleware',
2423
- 'viteSpaFallbackMiddleware',
2424
- 'viteServeStaticMiddleware'
2425
- ];
2419
+ const html_middlewares = ['viteServeStaticMiddleware'];
2426
2420
  for (let i = server.stack.length - 1; i > 0; i--) {
2427
2421
  // @ts-expect-error using internals until https://github.com/vitejs/vite/pull/4640 is merged
2428
2422
  if (html_middlewares.includes(server.stack[i].handle.name)) {
@@ -2789,8 +2783,9 @@ function scoped(scope, handler) {
2789
2783
 
2790
2784
  const cwd = process.cwd();
2791
2785
 
2792
- /** @type {Record<string, any>} */
2786
+ /** @type {import('./types').EnforcedConfig} */
2793
2787
  const enforced_config = {
2788
+ appType: true,
2794
2789
  base: true,
2795
2790
  build: {
2796
2791
  cssCodeSplit: true,
@@ -2802,7 +2797,7 @@ const enforced_config = {
2802
2797
  },
2803
2798
  manifest: true,
2804
2799
  outDir: true,
2805
- polyfillDynamicImport: true,
2800
+ polyfillModulePreload: true,
2806
2801
  rollupOptions: {
2807
2802
  input: true,
2808
2803
  output: {
@@ -2834,6 +2829,15 @@ function sveltekit() {
2834
2829
  }
2835
2830
 
2836
2831
  /**
2832
+ * Returns the SvelteKit Vite plugin. Vite executes Rollup hooks as well as some of its own.
2833
+ * Background reading is available at:
2834
+ * - https://vitejs.dev/guide/api-plugin.html
2835
+ * - https://rollupjs.org/guide/en/#plugin-development
2836
+ *
2837
+ * You can get an idea of the lifecycle by looking at the flow charts here:
2838
+ * - https://rollupjs.org/guide/en/#build-hooks
2839
+ * - https://rollupjs.org/guide/en/#output-generation-hooks
2840
+ *
2837
2841
  * @return {import('vite').Plugin}
2838
2842
  */
2839
2843
  function kit() {
@@ -2870,12 +2874,14 @@ function kit() {
2870
2874
  */
2871
2875
  let paths;
2872
2876
 
2873
- function create_client_config() {
2877
+ let completed_build = false;
2878
+
2879
+ function vite_client_config() {
2874
2880
  /** @type {Record<string, string>} */
2875
2881
  const input = {
2876
2882
  // Put unchanging assets in immutable directory. We don't set that in the
2877
2883
  // outDir so that other plugins can add mutable assets to the bundle
2878
- start: `${get_runtime_path(svelte_config.kit)}/client/start.js`
2884
+ start: `${get_runtime_directory(svelte_config.kit)}/client/start.js`
2879
2885
  };
2880
2886
 
2881
2887
  // This step is optional — Vite/Rollup will create the necessary chunks
@@ -2899,9 +2905,38 @@ function kit() {
2899
2905
  });
2900
2906
  }
2901
2907
 
2908
+ /**
2909
+ * @param {import('rollup').OutputAsset[]} assets
2910
+ * @param {import('rollup').OutputChunk[]} chunks
2911
+ */
2912
+ function client_build_info(assets, chunks) {
2913
+ /** @type {import('vite').Manifest} */
2914
+ const vite_manifest = JSON.parse(
2915
+ fs__default.readFileSync(`${paths.client_out_dir}/manifest.json`, 'utf-8')
2916
+ );
2917
+
2918
+ const entry_id = posixify(
2919
+ path__default.relative(cwd, `${get_runtime_directory(svelte_config.kit)}/client/start.js`)
2920
+ );
2921
+
2922
+ return {
2923
+ assets,
2924
+ chunks,
2925
+ entry: find_deps$1(vite_manifest, entry_id, false),
2926
+ vite_manifest
2927
+ };
2928
+ }
2929
+
2930
+ // TODO remove this for 1.0
2931
+ check_vite_version();
2932
+
2902
2933
  return {
2903
2934
  name: 'vite-plugin-svelte-kit',
2904
2935
 
2936
+ /**
2937
+ * Build the SvelteKit-provided Vite config to be merged with the user's vite.config.js file.
2938
+ * @see https://vitejs.dev/guide/api-plugin.html#config
2939
+ */
2905
2940
  async config(config, config_env) {
2906
2941
  vite_config_env = config_env;
2907
2942
  svelte_config = await load_config();
@@ -2920,7 +2955,7 @@ function kit() {
2920
2955
 
2921
2956
  manifest_data = all(svelte_config).manifest_data;
2922
2957
 
2923
- const new_config = create_client_config();
2958
+ const new_config = vite_client_config();
2924
2959
 
2925
2960
  warn_overridden_config(config, new_config);
2926
2961
 
@@ -2928,13 +2963,15 @@ function kit() {
2928
2963
  }
2929
2964
 
2930
2965
  // dev and preview config can be shared
2966
+ /** @type {import('vite').UserConfig} */
2931
2967
  const result = {
2968
+ appType: 'custom',
2932
2969
  base: '/',
2933
2970
  build: {
2934
2971
  rollupOptions: {
2935
2972
  // Vite dependency crawler needs an explicit JS entry point
2936
2973
  // eventhough server otherwise works without it
2937
- input: `${get_runtime_path(svelte_config.kit)}/client/start.js`
2974
+ input: `${get_runtime_directory(svelte_config.kit)}/client/start.js`
2938
2975
  }
2939
2976
  },
2940
2977
  resolve: {
@@ -2966,10 +3003,16 @@ function kit() {
2966
3003
  return result;
2967
3004
  },
2968
3005
 
3006
+ /**
3007
+ * Stores the final config.
3008
+ */
2969
3009
  configResolved(config) {
2970
3010
  vite_config = config;
2971
3011
  },
2972
3012
 
3013
+ /**
3014
+ * Clears the output directories.
3015
+ */
2973
3016
  buildStart() {
2974
3017
  if (is_build) {
2975
3018
  rimraf(paths.build_dir);
@@ -2980,6 +3023,11 @@ function kit() {
2980
3023
  }
2981
3024
  },
2982
3025
 
3026
+ /**
3027
+ * Vite builds a single bundle. We need three bundles: client, server, and service worker.
3028
+ * The user's package.json scripts will invoke the Vite CLI to execute the client build. We
3029
+ * then use this hook to kick off builds for the server and service worker.
3030
+ */
2983
3031
  async writeBundle(_options, bundle) {
2984
3032
  log = logger({
2985
3033
  verbose: vite_config.logLevel === 'info'
@@ -2990,36 +3038,10 @@ function kit() {
2990
3038
  JSON.stringify({ version: process.env.VITE_SVELTEKIT_APP_VERSION })
2991
3039
  );
2992
3040
 
2993
- /** @type {import('rollup').OutputChunk[]} */
2994
- const chunks = [];
2995
- /** @type {import('rollup').OutputAsset[]} */
2996
- const assets = [];
2997
- for (const key of Object.keys(bundle)) {
2998
- // collect asset and output chunks
2999
- if (bundle[key].type === 'asset') {
3000
- assets.push(/** @type {import('rollup').OutputAsset} */ (bundle[key]));
3001
- } else {
3002
- chunks.push(/** @type {import('rollup').OutputChunk} */ (bundle[key]));
3003
- }
3004
- }
3005
-
3006
- /** @type {import('vite').Manifest} */
3007
- const vite_manifest = JSON.parse(
3008
- fs__default.readFileSync(`${paths.client_out_dir}/manifest.json`, 'utf-8')
3009
- );
3010
-
3011
- const entry_id = posixify(
3012
- path__default.relative(cwd, `${get_runtime_path(svelte_config.kit)}/client/start.js`)
3013
- );
3014
-
3015
- const client = {
3016
- assets,
3017
- chunks,
3018
- entry: find_deps$1(vite_manifest, entry_id, false),
3019
- vite_manifest
3020
- };
3041
+ const { assets, chunks } = collect_output(bundle);
3021
3042
  log.info(`Client build completed. Wrote ${chunks.length} chunks and ${assets.length} assets`);
3022
3043
 
3044
+ log.info('Building server');
3023
3045
  const options = {
3024
3046
  cwd,
3025
3047
  config: svelte_config,
@@ -3029,13 +3051,9 @@ function kit() {
3029
3051
  output_dir: paths.output_dir,
3030
3052
  service_worker_entry_file: resolve_entry(svelte_config.kit.files.serviceWorker)
3031
3053
  };
3032
-
3033
- log.info('Building server');
3034
-
3054
+ const client = client_build_info(assets, chunks);
3035
3055
  const server = await build_server(options, client);
3036
3056
 
3037
- process.env.SVELTEKIT_SERVER_BUILD_COMPLETED = 'true';
3038
-
3039
3057
  /** @type {import('types').BuildData} */
3040
3058
  build_data = {
3041
3059
  app_dir: svelte_config.kit.appDir,
@@ -3054,6 +3072,9 @@ function kit() {
3054
3072
  })};\n`
3055
3073
  );
3056
3074
 
3075
+ process.env.SVELTEKIT_SERVER_BUILD_COMPLETED = 'true';
3076
+ log.info('Prerendering');
3077
+
3057
3078
  const static_files = manifest_data.assets.map((asset) => posixify(asset.file));
3058
3079
 
3059
3080
  const files = new Set([
@@ -3069,8 +3090,6 @@ function kit() {
3069
3090
  }
3070
3091
  });
3071
3092
 
3072
- log.info('Prerendering');
3073
-
3074
3093
  prerendered = await prerender({
3075
3094
  config: svelte_config.kit,
3076
3095
  entries: manifest_data.routes
@@ -3093,12 +3112,20 @@ function kit() {
3093
3112
  console.log(
3094
3113
  `\nRun ${$.bold().cyan('npm run preview')} to preview your production build locally.`
3095
3114
  );
3115
+
3116
+ completed_build = true;
3096
3117
  },
3097
3118
 
3119
+ /**
3120
+ * Runs the adapter.
3121
+ */
3098
3122
  async closeBundle() {
3099
- if (!is_build) {
3100
- return; // vite calls closeBundle when dev-server restarts, ignore that
3123
+ if (!completed_build) {
3124
+ // vite calls closeBundle when dev-server restarts, ignore that,
3125
+ // and only adapt when build successfully completes.
3126
+ return;
3101
3127
  }
3128
+
3102
3129
  if (svelte_config.kit.adapter) {
3103
3130
  const { adapt } = await import('./chunks/index2.js');
3104
3131
  await adapt(svelte_config, build_data, prerendered, { log });
@@ -3112,30 +3139,70 @@ function kit() {
3112
3139
 
3113
3140
  if (svelte_config.kit.prerender.enabled) {
3114
3141
  // this is necessary to close any open db connections, etc.
3115
- // TODO: prerender in a subprocess so we can exit in isolation
3142
+ // TODO: prerender in a subprocess so we can exit in isolation and then remove this
3116
3143
  // https://github.com/sveltejs/kit/issues/5306
3117
3144
  process.exit(0);
3118
3145
  }
3119
3146
  },
3120
3147
 
3148
+ /**
3149
+ * Adds the SvelteKit middleware to do SSR in dev mode.
3150
+ * @see https://vitejs.dev/guide/api-plugin.html#configureserver
3151
+ */
3121
3152
  async configureServer(vite) {
3122
3153
  return await dev(vite, vite_config, svelte_config);
3123
3154
  },
3124
3155
 
3156
+ /**
3157
+ * Adds the SvelteKit middleware to do SSR in preview mode.
3158
+ * @see https://vitejs.dev/guide/api-plugin.html#configurepreviewserver
3159
+ */
3125
3160
  configurePreviewServer(vite) {
3126
3161
  return preview(vite, svelte_config, vite_config.preview.https ? 'https' : 'http');
3127
3162
  }
3128
3163
  };
3129
3164
  }
3130
3165
 
3166
+ function check_vite_version() {
3167
+ let vite_major = 3;
3168
+
3169
+ try {
3170
+ const pkg = JSON.parse(fs__default.readFileSync('package.json', 'utf-8'));
3171
+ vite_major = +pkg.devDependencies['vite'].replace(/^[~^]/, '')[0];
3172
+ } catch {
3173
+ // do nothing
3174
+ }
3175
+
3176
+ if (vite_major < 3) {
3177
+ throw new Error(
3178
+ `Vite version ${vite_major} is no longer supported. Please upgrade to version 3`
3179
+ );
3180
+ }
3181
+ }
3182
+
3183
+ /** @param {import('rollup').OutputBundle} bundle */
3184
+ function collect_output(bundle) {
3185
+ /** @type {import('rollup').OutputChunk[]} */
3186
+ const chunks = [];
3187
+ /** @type {import('rollup').OutputAsset[]} */
3188
+ const assets = [];
3189
+ for (const value of Object.values(bundle)) {
3190
+ // collect asset and output chunks
3191
+ if (value.type === 'asset') {
3192
+ assets.push(value);
3193
+ } else {
3194
+ chunks.push(value);
3195
+ }
3196
+ }
3197
+ return { assets, chunks };
3198
+ }
3199
+
3131
3200
  /**
3132
3201
  * @param {Record<string, any>} config
3133
3202
  * @param {Record<string, any>} resolved_config
3134
- * @param {string} [path]
3135
- * @param {string[]} [out] used locally to compute the return value
3136
3203
  */
3137
- function warn_overridden_config(config, resolved_config, path = '', out = []) {
3138
- const overridden = find_overridden_config(config, resolved_config, path, out);
3204
+ function warn_overridden_config(config, resolved_config) {
3205
+ const overridden = find_overridden_config(config, resolved_config, enforced_config, '', []);
3139
3206
  if (overridden.length > 0) {
3140
3207
  console.log(
3141
3208
  $.bold().red('The following Vite config options will be overridden by SvelteKit:')
@@ -3147,16 +3214,21 @@ function warn_overridden_config(config, resolved_config, path = '', out = []) {
3147
3214
  /**
3148
3215
  * @param {Record<string, any>} config
3149
3216
  * @param {Record<string, any>} resolved_config
3217
+ * @param {import('./types').EnforcedConfig} enforced_config
3150
3218
  * @param {string} path
3151
3219
  * @param {string[]} out used locally to compute the return value
3152
3220
  */
3153
- function find_overridden_config(config, resolved_config, path, out) {
3221
+ function find_overridden_config(config, resolved_config, enforced_config, path, out) {
3154
3222
  for (const key in enforced_config) {
3155
3223
  if (typeof config === 'object' && config !== null && key in config) {
3156
- if (enforced_config[key] === true && config[key] !== resolved_config[key]) {
3157
- out.push(path + key);
3224
+ const enforced = enforced_config[key];
3225
+
3226
+ if (enforced === true) {
3227
+ if (config[key] !== resolved_config[key]) {
3228
+ out.push(path + key);
3229
+ }
3158
3230
  } else {
3159
- find_overridden_config(config[key], resolved_config[key], path + key + '.', out);
3231
+ find_overridden_config(config[key], resolved_config[key], enforced, path + key + '.', out);
3160
3232
  }
3161
3233
  }
3162
3234
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.372",
3
+ "version": "1.0.0-next.375",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -10,12 +10,12 @@
10
10
  "homepage": "https://kit.svelte.dev",
11
11
  "type": "module",
12
12
  "dependencies": {
13
- "@sveltejs/vite-plugin-svelte": "1.0.0-next.49",
13
+ "@sveltejs/vite-plugin-svelte": "^1.0.1",
14
14
  "chokidar": "^3.5.3",
15
15
  "sade": "^1.8.1"
16
16
  },
17
17
  "devDependencies": {
18
- "@playwright/test": "^1.22.2",
18
+ "@playwright/test": "^1.23.3",
19
19
  "@rollup/plugin-replace": "^4.0.0",
20
20
  "@types/connect": "^3.4.35",
21
21
  "@types/cookie": "^0.5.1",
@@ -33,7 +33,7 @@
33
33
  "marked": "^4.0.16",
34
34
  "mime": "^3.0.0",
35
35
  "node-fetch": "^3.2.4",
36
- "rollup": "^2.75.3",
36
+ "rollup": "^2.75.7",
37
37
  "selfsigned": "^2.0.1",
38
38
  "set-cookie-parser": "^2.4.8",
39
39
  "sirv": "^2.0.2",
@@ -45,11 +45,11 @@
45
45
  "typescript": "^4.7.4",
46
46
  "undici": "^5.6.1",
47
47
  "uvu": "^0.5.3",
48
- "vite": "^2.9.13"
48
+ "vite": "^3.0.0"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "svelte": "^3.44.0",
52
- "vite": "^2.9.10"
52
+ "vite": "^3.0.0"
53
53
  },
54
54
  "bin": {
55
55
  "svelte-kit": "svelte-kit.js"
@@ -80,7 +80,7 @@ declare module '$app/env' {
80
80
  export const dev: boolean;
81
81
 
82
82
  /**
83
- * The Vite.js mode the app is running in. Configure in `config.kit.vite.mode`.
83
+ * The Vite.js mode the app is running in. Configure in [`vite.config.js`](https://vitejs.dev/config/shared-options.html#mode).
84
84
  * Vite.js loads the dotenv file associated with the provided mode, `.env.[mode]` or `.env.[mode].local`.
85
85
  * By default, `vite dev` runs with `mode=development` and `vite build` runs with `mode=production`.
86
86
  */
package/types/index.d.ts CHANGED
@@ -151,7 +151,6 @@ export interface KitConfig {
151
151
  name?: string;
152
152
  pollInterval?: number;
153
153
  };
154
- vite?: import('vite').UserConfig | (() => MaybePromise<import('vite').UserConfig>);
155
154
  }
156
155
 
157
156
  export interface ExternalFetch {
@@ -183,7 +182,7 @@ export interface Load<
183
182
  InputProps extends Record<string, any> = Record<string, any>,
184
183
  OutputProps extends Record<string, any> = InputProps
185
184
  > {
186
- (event: LoadEvent<Params, InputProps>): MaybePromise<LoadOutput<OutputProps>>;
185
+ (event: LoadEvent<Params, InputProps>): MaybePromise<LoadOutput<OutputProps> | void>;
187
186
  }
188
187
 
189
188
  export interface LoadEvent<
@@ -113,7 +113,7 @@ export interface MethodOverride {
113
113
  }
114
114
 
115
115
  export type NormalizedLoadOutput = {
116
- status: number;
116
+ status?: number;
117
117
  error?: Error;
118
118
  redirect?: string;
119
119
  props?: Record<string, any> | Promise<Record<string, any>>;
@@ -153,12 +153,9 @@ export interface PrerenderOptions {
153
153
 
154
154
  export type RecursiveRequired<T> = {
155
155
  // Recursive implementation of TypeScript's Required utility type.
156
- // Will recursively continue until it reaches primitive or union
157
- // with a Function in it, except those commented below
156
+ // Will recursively continue until it reaches a primitive or Function
158
157
  [K in keyof T]-?: Extract<T[K], Function> extends never // If it does not have a Function type
159
158
  ? RecursiveRequired<T[K]> // recursively continue through.
160
- : K extends 'vite' // If it reaches the 'vite' key
161
- ? Extract<T[K], Function> // only take the Function type.
162
159
  : T[K]; // Use the exact type for everything else
163
160
  };
164
161
 
@@ -293,6 +290,10 @@ export interface SSRPage {
293
290
  b: Array<number | undefined>;
294
291
  }
295
292
 
293
+ export interface SSRErrorPage {
294
+ id: '__error';
295
+ }
296
+
296
297
  export interface SSRPagePart {
297
298
  id: string;
298
299
  load: SSRComponentLoader;
@@ -303,7 +304,7 @@ export type SSRRoute = SSREndpoint | SSRPage;
303
304
  export interface SSRState {
304
305
  fallback?: string;
305
306
  getClientAddress: () => string;
306
- initiator?: SSRPage | null;
307
+ initiator?: SSRPage | SSRErrorPage;
307
308
  platform?: any;
308
309
  prerendering?: PrerenderOptions;
309
310
  }