@sveltejs/kit 1.0.0-next.371 → 1.0.0-next.374

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) {
@@ -1030,24 +1034,17 @@ function create_client({ target, session, base, trailing_slash }) {
1030
1034
  });
1031
1035
  }
1032
1036
 
1033
- let loaded;
1034
-
1035
1037
  if (import.meta.env.DEV) {
1036
1038
  try {
1037
1039
  lock_fetch();
1038
- loaded = await module.load.call(null, load_input);
1040
+ node.loaded = normalize(await module.load.call(null, load_input));
1039
1041
  } finally {
1040
1042
  unlock_fetch();
1041
1043
  }
1042
1044
  } 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');
1045
+ node.loaded = normalize(await module.load.call(null, load_input));
1048
1046
  }
1049
1047
 
1050
- node.loaded = normalize(loaded);
1051
1048
  if (node.loaded.stuff) node.stuff = node.loaded.stuff;
1052
1049
  if (node.loaded.dependencies) {
1053
1050
  node.loaded.dependencies.forEach(add_dependency);
@@ -1088,7 +1085,7 @@ function create_client({ target, session, base, trailing_slash }) {
1088
1085
  let stuff = root_stuff;
1089
1086
  let stuff_changed = false;
1090
1087
 
1091
- /** @type {number | undefined} */
1088
+ /** @type {number} */
1092
1089
  let status = 200;
1093
1090
 
1094
1091
  /** @type {Error | null} */
@@ -1174,7 +1171,7 @@ function create_client({ target, session, base, trailing_slash }) {
1174
1171
 
1175
1172
  if (node.loaded) {
1176
1173
  if (node.loaded.error) {
1177
- status = node.loaded.status;
1174
+ status = node.loaded.status ?? 500;
1178
1175
  error = node.loaded.error;
1179
1176
  }
1180
1177
 
@@ -1703,7 +1700,7 @@ function create_client({ target, session, base, trailing_slash }) {
1703
1700
  if (node.loaded.error) {
1704
1701
  if (error) throw node.loaded.error;
1705
1702
  error_args = {
1706
- status: node.loaded.status,
1703
+ status: node.loaded.status ?? 500,
1707
1704
  error: node.loaded.error,
1708
1705
  url,
1709
1706
  routeId
@@ -27,32 +27,34 @@ function to_headers(object) {
27
27
  * @param {string[]} types
28
28
  */
29
29
  function negotiate(accept, types) {
30
- const parts = accept
31
- .split(',')
32
- .map((str, i) => {
33
- const match = /([^/]+)\/([^;]+)(?:;q=([0-9.]+))?/.exec(str);
34
- if (match) {
35
- const [, type, subtype, q = '1'] = match;
36
- return { type, subtype, q: +q, i };
37
- }
30
+ /** @type {Array<{ type: string, subtype: string, q: number, i: number }>} */
31
+ const parts = [];
38
32
 
39
- throw new Error(`Invalid Accept header: ${accept}`);
40
- })
41
- .sort((a, b) => {
42
- if (a.q !== b.q) {
43
- return b.q - a.q;
44
- }
33
+ accept.split(',').forEach((str, i) => {
34
+ const match = /([^/]+)\/([^;]+)(?:;q=([0-9.]+))?/.exec(str);
45
35
 
46
- if ((a.subtype === '*') !== (b.subtype === '*')) {
47
- return a.subtype === '*' ? 1 : -1;
48
- }
36
+ // no match equals invalid header ignore
37
+ if (match) {
38
+ const [, type, subtype, q = '1'] = match;
39
+ parts.push({ type, subtype, q: +q, i });
40
+ }
41
+ });
49
42
 
50
- if ((a.type === '*') !== (b.type === '*')) {
51
- return a.type === '*' ? 1 : -1;
52
- }
43
+ parts.sort((a, b) => {
44
+ if (a.q !== b.q) {
45
+ return b.q - a.q;
46
+ }
53
47
 
54
- return a.i - b.i;
55
- });
48
+ if ((a.subtype === '*') !== (b.subtype === '*')) {
49
+ return a.subtype === '*' ? 1 : -1;
50
+ }
51
+
52
+ if ((a.type === '*') !== (b.type === '*')) {
53
+ return a.type === '*' ? 1 : -1;
54
+ }
55
+
56
+ return a.i - b.i;
57
+ });
56
58
 
57
59
  let accepted;
58
60
  let min_priority = Infinity;
@@ -975,9 +977,6 @@ function base64(bytes) {
975
977
  return result;
976
978
  }
977
979
 
978
- /** @type {Promise<void>} */
979
- let csp_ready;
980
-
981
980
  const array = new Uint8Array(16);
982
981
 
983
982
  function generate_nonce() {
@@ -997,13 +996,12 @@ const quoted = new Set([
997
996
 
998
997
  const crypto_pattern = /^(nonce|sha\d\d\d)-/;
999
998
 
1000
- class Csp {
999
+ // CSP and CSP Report Only are extremely similar with a few caveats
1000
+ // the easiest/DRYest way to express this is with some private encapsulation
1001
+ class BaseProvider {
1001
1002
  /** @type {boolean} */
1002
1003
  #use_hashes;
1003
1004
 
1004
- /** @type {boolean} */
1005
- #dev;
1006
-
1007
1005
  /** @type {boolean} */
1008
1006
  #script_needs_csp;
1009
1007
 
@@ -1019,21 +1017,18 @@ class Csp {
1019
1017
  /** @type {import('types').Csp.Source[]} */
1020
1018
  #style_src;
1021
1019
 
1020
+ /** @type {string} */
1021
+ #nonce;
1022
+
1022
1023
  /**
1023
- * @param {{
1024
- * mode: string,
1025
- * directives: import('types').CspDirectives
1026
- * }} config
1027
- * @param {{
1028
- * dev: boolean;
1029
- * prerender: boolean;
1030
- * needs_nonce: boolean;
1031
- * }} opts
1024
+ * @param {boolean} use_hashes
1025
+ * @param {import('types').CspDirectives} directives
1026
+ * @param {string} nonce
1027
+ * @param {boolean} dev
1032
1028
  */
1033
- constructor({ mode, directives }, { dev, prerender, needs_nonce }) {
1034
- this.#use_hashes = mode === 'hash' || (mode === 'auto' && prerender);
1029
+ constructor(use_hashes, directives, nonce, dev) {
1030
+ this.#use_hashes = use_hashes;
1035
1031
  this.#directives = dev ? { ...directives } : directives; // clone in dev so we can safely mutate
1036
- this.#dev = dev;
1037
1032
 
1038
1033
  const d = this.#directives;
1039
1034
 
@@ -1075,10 +1070,7 @@ class Csp {
1075
1070
 
1076
1071
  this.script_needs_nonce = this.#script_needs_csp && !this.#use_hashes;
1077
1072
  this.style_needs_nonce = this.#style_needs_csp && !this.#use_hashes;
1078
-
1079
- if (this.script_needs_nonce || this.style_needs_nonce || needs_nonce) {
1080
- this.nonce = generate_nonce();
1081
- }
1073
+ this.#nonce = nonce;
1082
1074
  }
1083
1075
 
1084
1076
  /** @param {string} content */
@@ -1087,7 +1079,7 @@ class Csp {
1087
1079
  if (this.#use_hashes) {
1088
1080
  this.#script_src.push(`sha256-${sha256(content)}`);
1089
1081
  } else if (this.#script_src.length === 0) {
1090
- this.#script_src.push(`nonce-${this.nonce}`);
1082
+ this.#script_src.push(`nonce-${this.#nonce}`);
1091
1083
  }
1092
1084
  }
1093
1085
  }
@@ -1098,12 +1090,14 @@ class Csp {
1098
1090
  if (this.#use_hashes) {
1099
1091
  this.#style_src.push(`sha256-${sha256(content)}`);
1100
1092
  } else if (this.#style_src.length === 0) {
1101
- this.#style_src.push(`nonce-${this.nonce}`);
1093
+ this.#style_src.push(`nonce-${this.#nonce}`);
1102
1094
  }
1103
1095
  }
1104
1096
  }
1105
1097
 
1106
- /** @param {boolean} [is_meta] */
1098
+ /**
1099
+ * @param {boolean} [is_meta]
1100
+ */
1107
1101
  get_header(is_meta = false) {
1108
1102
  const header = [];
1109
1103
 
@@ -1134,7 +1128,7 @@ class Csp {
1134
1128
  continue;
1135
1129
  }
1136
1130
 
1137
- // @ts-expect-error gimme a break typescript, `key` is obviously a member of directives
1131
+ // @ts-expect-error gimme a break typescript, `key` is obviously a member of internal_directives
1138
1132
  const value = /** @type {string[] | true} */ (directives[key]);
1139
1133
 
1140
1134
  if (!value) continue;
@@ -1155,13 +1149,81 @@ class Csp {
1155
1149
 
1156
1150
  return header.join('; ');
1157
1151
  }
1152
+ }
1158
1153
 
1154
+ class CspProvider extends BaseProvider {
1159
1155
  get_meta() {
1160
1156
  const content = escape_html_attr(this.get_header(true));
1161
1157
  return `<meta http-equiv="content-security-policy" content=${content}>`;
1162
1158
  }
1163
1159
  }
1164
1160
 
1161
+ class CspReportOnlyProvider extends BaseProvider {
1162
+ /**
1163
+ * @param {boolean} use_hashes
1164
+ * @param {import('types').CspDirectives} directives
1165
+ * @param {string} nonce
1166
+ * @param {boolean} dev
1167
+ */
1168
+ constructor(use_hashes, directives, nonce, dev) {
1169
+ super(use_hashes, directives, nonce, dev);
1170
+
1171
+ if (Object.values(directives).filter((v) => !!v).length > 0) {
1172
+ // If we're generating content-security-policy-report-only,
1173
+ // if there are any directives, we need a report-uri or report-to (or both)
1174
+ // else it's just an expensive noop.
1175
+ const has_report_to = directives['report-to']?.length ?? 0 > 0;
1176
+ const has_report_uri = directives['report-uri']?.length ?? 0 > 0;
1177
+ if (!has_report_to && !has_report_uri) {
1178
+ throw Error(
1179
+ '`content-security-policy-report-only` must be specified with either the `report-to` or `report-uri` directives, or both'
1180
+ );
1181
+ }
1182
+ }
1183
+ }
1184
+ }
1185
+
1186
+ class Csp {
1187
+ /** @readonly */
1188
+ nonce = generate_nonce();
1189
+
1190
+ /** @type {CspProvider} */
1191
+ csp_provider;
1192
+
1193
+ /** @type {CspReportOnlyProvider} */
1194
+ report_only_provider;
1195
+
1196
+ /**
1197
+ * @param {import('./types').CspConfig} config
1198
+ * @param {import('./types').CspOpts} opts
1199
+ */
1200
+ constructor({ mode, directives, reportOnly }, { prerender, dev }) {
1201
+ const use_hashes = mode === 'hash' || (mode === 'auto' && prerender);
1202
+ this.csp_provider = new CspProvider(use_hashes, directives, this.nonce, dev);
1203
+ this.report_only_provider = new CspReportOnlyProvider(use_hashes, reportOnly, this.nonce, dev);
1204
+ }
1205
+
1206
+ get script_needs_nonce() {
1207
+ return this.csp_provider.script_needs_nonce || this.report_only_provider.script_needs_nonce;
1208
+ }
1209
+
1210
+ get style_needs_nonce() {
1211
+ return this.csp_provider.style_needs_nonce || this.report_only_provider.style_needs_nonce;
1212
+ }
1213
+
1214
+ /** @param {string} content */
1215
+ add_script(content) {
1216
+ this.csp_provider.add_script(content);
1217
+ this.report_only_provider.add_script(content);
1218
+ }
1219
+
1220
+ /** @param {string} content */
1221
+ add_style(content) {
1222
+ this.csp_provider.add_style(content);
1223
+ this.report_only_provider.add_style(content);
1224
+ }
1225
+ }
1226
+
1165
1227
  const absolute = /^([a-z]+:)?\/?\//;
1166
1228
  const scheme = /^[a-z]+:/;
1167
1229
 
@@ -1307,6 +1369,14 @@ async function render_response({
1307
1369
  }
1308
1370
 
1309
1371
  if (resolve_opts.ssr) {
1372
+ const leaf = /** @type {import('./types.js').Loaded} */ (branch.at(-1));
1373
+
1374
+ if (leaf.loaded.status) {
1375
+ // explicit status returned from `load` or a page endpoint trumps
1376
+ // initial status
1377
+ status = leaf.loaded.status;
1378
+ }
1379
+
1310
1380
  for (const { node, props, loaded, fetched, uses_credentials } of branch) {
1311
1381
  if (node.imports) {
1312
1382
  node.imports.forEach((url) => modulepreloads.add(url));
@@ -1387,11 +1457,9 @@ async function render_response({
1387
1457
 
1388
1458
  let { head, html: body } = rendered;
1389
1459
 
1390
- await csp_ready;
1391
1460
  const csp = new Csp(options.csp, {
1392
1461
  dev: options.dev,
1393
- prerender: !!state.prerendering,
1394
- needs_nonce: options.template_contains_nonce
1462
+ prerender: !!state.prerendering
1395
1463
  });
1396
1464
 
1397
1465
  const target = hash(body);
@@ -1502,7 +1570,7 @@ async function render_response({
1502
1570
  if (state.prerendering) {
1503
1571
  const http_equiv = [];
1504
1572
 
1505
- const csp_headers = csp.get_meta();
1573
+ const csp_headers = csp.csp_provider.get_meta();
1506
1574
  if (csp_headers) {
1507
1575
  http_equiv.push(csp_headers);
1508
1576
  }
@@ -1534,10 +1602,14 @@ async function render_response({
1534
1602
  }
1535
1603
 
1536
1604
  if (!state.prerendering) {
1537
- const csp_header = csp.get_header();
1605
+ const csp_header = csp.csp_provider.get_header();
1538
1606
  if (csp_header) {
1539
1607
  headers.set('content-security-policy', csp_header);
1540
1608
  }
1609
+ const report_only_header = csp.report_only_provider.get_header();
1610
+ if (report_only_header) {
1611
+ headers.set('content-security-policy-report-only', report_only_header);
1612
+ }
1541
1613
  }
1542
1614
 
1543
1615
  return new Response(html, {
@@ -2032,10 +2104,14 @@ var parseString_1 = setCookie.exports.parseString = parseString;
2032
2104
  var splitCookiesString_1 = setCookie.exports.splitCookiesString = splitCookiesString;
2033
2105
 
2034
2106
  /**
2035
- * @param {import('types').LoadOutput} loaded
2107
+ * @param {import('types').LoadOutput | void} loaded
2036
2108
  * @returns {import('types').NormalizedLoadOutput}
2037
2109
  */
2038
2110
  function normalize(loaded) {
2111
+ if (!loaded) {
2112
+ return {};
2113
+ }
2114
+
2039
2115
  // TODO remove for 1.0
2040
2116
  // @ts-expect-error
2041
2117
  if (loaded.fallthrough) {
@@ -2177,7 +2253,7 @@ async function load_node({
2177
2253
  /** @type {import('set-cookie-parser').Cookie[]} */
2178
2254
  const new_cookies = [];
2179
2255
 
2180
- /** @type {import('types').LoadOutput} */
2256
+ /** @type {import('types').NormalizedLoadOutput} */
2181
2257
  let loaded;
2182
2258
 
2183
2259
  const should_prerender = node.module.prerender ?? options.prerender.default;
@@ -2200,12 +2276,10 @@ async function load_node({
2200
2276
 
2201
2277
  if (shadow.error) {
2202
2278
  loaded = {
2203
- status: shadow.status,
2204
2279
  error: shadow.error
2205
2280
  };
2206
2281
  } else if (shadow.redirect) {
2207
2282
  loaded = {
2208
- status: shadow.status,
2209
2283
  redirect: shadow.redirect
2210
2284
  };
2211
2285
  } else if (module.load) {
@@ -2473,7 +2547,7 @@ async function load_node({
2473
2547
  return proxy;
2474
2548
  },
2475
2549
  stuff: { ...stuff },
2476
- status: is_error ? status ?? null : null,
2550
+ status: (is_error ? status : shadow.status) ?? null,
2477
2551
  error: is_error ? error ?? null : null
2478
2552
  };
2479
2553
 
@@ -2486,12 +2560,7 @@ async function load_node({
2486
2560
  });
2487
2561
  }
2488
2562
 
2489
- loaded = await module.load.call(null, load_input);
2490
-
2491
- if (!loaded) {
2492
- // TODO do we still want to enforce this now that there's no fallthrough?
2493
- throw new Error(`load function must return a value${options.dev ? ` (${node.file})` : ''}`);
2494
- }
2563
+ loaded = normalize(await module.load.call(null, load_input));
2495
2564
  } else if (shadow.body) {
2496
2565
  loaded = {
2497
2566
  props: shadow.body
@@ -2500,6 +2569,8 @@ async function load_node({
2500
2569
  loaded = {};
2501
2570
  }
2502
2571
 
2572
+ loaded.status = loaded.status ?? shadow.status;
2573
+
2503
2574
  // generate __data.json files when prerendering
2504
2575
  if (shadow.body && state.prerendering) {
2505
2576
  const pathname = `${event.url.pathname.replace(/\/$/, '')}/__data.json`;
@@ -2515,7 +2586,7 @@ async function load_node({
2515
2586
  return {
2516
2587
  node,
2517
2588
  props: shadow.body,
2518
- loaded: normalize(loaded),
2589
+ loaded,
2519
2590
  stuff: loaded.stuff || stuff,
2520
2591
  fetched,
2521
2592
  set_cookie_headers: new_cookies.map((new_cookie) => {
@@ -2558,7 +2629,7 @@ async function load_shadow_data(route, event, options, prerender) {
2558
2629
 
2559
2630
  /** @type {import('types').ShadowData} */
2560
2631
  const data = {
2561
- status: 200,
2632
+ status: undefined,
2562
2633
  cookies: [],
2563
2634
  body: {}
2564
2635
  };
@@ -2598,13 +2669,13 @@ async function load_shadow_data(route, event, options, prerender) {
2598
2669
  if (get) {
2599
2670
  const { status, headers, body } = validate_shadow_output(await get(event));
2600
2671
  add_cookies(/** @type {string[]} */ (data.cookies), headers);
2601
- data.status = status;
2602
2672
 
2603
2673
  if (body instanceof Error) {
2604
2674
  if (status < 400) {
2605
2675
  data.status = 500;
2606
2676
  data.error = new Error('A non-error status code was returned with an error body');
2607
2677
  } else {
2678
+ data.status = status;
2608
2679
  data.error = body;
2609
2680
  }
2610
2681
 
@@ -2612,11 +2683,13 @@ async function load_shadow_data(route, event, options, prerender) {
2612
2683
  }
2613
2684
 
2614
2685
  if (status >= 400) {
2686
+ data.status = status;
2615
2687
  data.error = new Error('Failed to load data');
2616
2688
  return data;
2617
2689
  }
2618
2690
 
2619
2691
  if (status >= 300) {
2692
+ data.status = status;
2620
2693
  data.redirect = /** @type {string} */ (
2621
2694
  headers instanceof Headers ? headers.get('location') : headers.location
2622
2695
  );
@@ -2905,7 +2978,8 @@ async function respond$1(opts) {
2905
2978
  }
2906
2979
 
2907
2980
  if (loaded.loaded.error) {
2908
- ({ status, error } = loaded.loaded);
2981
+ error = loaded.loaded.error;
2982
+ status = loaded.loaded.status ?? 500;
2909
2983
  }
2910
2984
  } catch (err) {
2911
2985
  const e = coalesce_to_error(err);
@@ -111,6 +111,40 @@ function init(open, close) {
111
111
 
112
112
  /** @typedef {import('./types').Validator} Validator */
113
113
 
114
+ const directives = object({
115
+ 'child-src': string_array(),
116
+ 'default-src': string_array(),
117
+ 'frame-src': string_array(),
118
+ 'worker-src': string_array(),
119
+ 'connect-src': string_array(),
120
+ 'font-src': string_array(),
121
+ 'img-src': string_array(),
122
+ 'manifest-src': string_array(),
123
+ 'media-src': string_array(),
124
+ 'object-src': string_array(),
125
+ 'prefetch-src': string_array(),
126
+ 'script-src': string_array(),
127
+ 'script-src-elem': string_array(),
128
+ 'script-src-attr': string_array(),
129
+ 'style-src': string_array(),
130
+ 'style-src-elem': string_array(),
131
+ 'style-src-attr': string_array(),
132
+ 'base-uri': string_array(),
133
+ sandbox: string_array(),
134
+ 'form-action': string_array(),
135
+ 'frame-ancestors': string_array(),
136
+ 'navigate-to': string_array(),
137
+ 'report-uri': string_array(),
138
+ 'report-to': string_array(),
139
+ 'require-trusted-types-for': string_array(),
140
+ 'trusted-types': string_array(),
141
+ 'upgrade-insecure-requests': boolean(false),
142
+ 'require-sri-for': string_array(),
143
+ 'block-all-mixed-content': boolean(false),
144
+ 'plugin-types': string_array(),
145
+ referrer: string_array()
146
+ });
147
+
114
148
  /** @type {Validator} */
115
149
  const options = object(
116
150
  {
@@ -189,39 +223,8 @@ const options = object(
189
223
 
190
224
  csp: object({
191
225
  mode: list(['auto', 'hash', 'nonce']),
192
- directives: object({
193
- 'child-src': string_array(),
194
- 'default-src': string_array(),
195
- 'frame-src': string_array(),
196
- 'worker-src': string_array(),
197
- 'connect-src': string_array(),
198
- 'font-src': string_array(),
199
- 'img-src': string_array(),
200
- 'manifest-src': string_array(),
201
- 'media-src': string_array(),
202
- 'object-src': string_array(),
203
- 'prefetch-src': string_array(),
204
- 'script-src': string_array(),
205
- 'script-src-elem': string_array(),
206
- 'script-src-attr': string_array(),
207
- 'style-src': string_array(),
208
- 'style-src-elem': string_array(),
209
- 'style-src-attr': string_array(),
210
- 'base-uri': string_array(),
211
- sandbox: string_array(),
212
- 'form-action': string_array(),
213
- 'frame-ancestors': string_array(),
214
- 'navigate-to': string_array(),
215
- 'report-uri': string_array(),
216
- 'report-to': string_array(),
217
- 'require-trusted-types-for': string_array(),
218
- 'trusted-types': string_array(),
219
- 'upgrade-insecure-requests': boolean(false),
220
- 'require-sri-for': string_array(),
221
- 'block-all-mixed-content': boolean(false),
222
- 'plugin-types': string_array(),
223
- referrer: string_array()
224
- })
226
+ directives,
227
+ reportOnly: directives
225
228
  }),
226
229
 
227
230
  // TODO: remove this for the 1.0 release
@@ -410,7 +413,7 @@ const options = object(
410
413
  * @param {boolean} [allow_unknown]
411
414
  * @returns {Validator}
412
415
  */
413
- function object(children, allow_unknown) {
416
+ function object(children, allow_unknown = false) {
414
417
  return (input, keypath) => {
415
418
  /** @type {Record<string, any>} */
416
419
  const output = {};
@@ -620,7 +623,7 @@ async function load_config({ cwd = process.cwd() } = {}) {
620
623
  * @param {import('types').Config} config
621
624
  * @returns {import('types').ValidatedConfig}
622
625
  */
623
- function process_config(config, { cwd = process.cwd() }) {
626
+ function process_config(config, { cwd = process.cwd() } = {}) {
624
627
  const validated = validate_config(config);
625
628
 
626
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.371');
21
+ const prog = sade('svelte-kit').version('1.0.0-next.374');
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,12 @@ function kit() {
2870
2874
  */
2871
2875
  let paths;
2872
2876
 
2873
- function create_client_config() {
2877
+ function vite_client_config() {
2874
2878
  /** @type {Record<string, string>} */
2875
2879
  const input = {
2876
2880
  // Put unchanging assets in immutable directory. We don't set that in the
2877
2881
  // outDir so that other plugins can add mutable assets to the bundle
2878
- start: `${get_runtime_path(svelte_config.kit)}/client/start.js`
2882
+ start: `${get_runtime_directory(svelte_config.kit)}/client/start.js`
2879
2883
  };
2880
2884
 
2881
2885
  // This step is optional — Vite/Rollup will create the necessary chunks
@@ -2899,9 +2903,38 @@ function kit() {
2899
2903
  });
2900
2904
  }
2901
2905
 
2906
+ /**
2907
+ * @param {import('rollup').OutputAsset[]} assets
2908
+ * @param {import('rollup').OutputChunk[]} chunks
2909
+ */
2910
+ function client_build_info(assets, chunks) {
2911
+ /** @type {import('vite').Manifest} */
2912
+ const vite_manifest = JSON.parse(
2913
+ fs__default.readFileSync(`${paths.client_out_dir}/manifest.json`, 'utf-8')
2914
+ );
2915
+
2916
+ const entry_id = posixify(
2917
+ path__default.relative(cwd, `${get_runtime_directory(svelte_config.kit)}/client/start.js`)
2918
+ );
2919
+
2920
+ return {
2921
+ assets,
2922
+ chunks,
2923
+ entry: find_deps$1(vite_manifest, entry_id, false),
2924
+ vite_manifest
2925
+ };
2926
+ }
2927
+
2928
+ // TODO remove this for 1.0
2929
+ check_vite_version();
2930
+
2902
2931
  return {
2903
2932
  name: 'vite-plugin-svelte-kit',
2904
2933
 
2934
+ /**
2935
+ * Build the SvelteKit-provided Vite config to be merged with the user's vite.config.js file.
2936
+ * @see https://vitejs.dev/guide/api-plugin.html#config
2937
+ */
2905
2938
  async config(config, config_env) {
2906
2939
  vite_config_env = config_env;
2907
2940
  svelte_config = await load_config();
@@ -2920,7 +2953,7 @@ function kit() {
2920
2953
 
2921
2954
  manifest_data = all(svelte_config).manifest_data;
2922
2955
 
2923
- const new_config = create_client_config();
2956
+ const new_config = vite_client_config();
2924
2957
 
2925
2958
  warn_overridden_config(config, new_config);
2926
2959
 
@@ -2928,13 +2961,15 @@ function kit() {
2928
2961
  }
2929
2962
 
2930
2963
  // dev and preview config can be shared
2964
+ /** @type {import('vite').UserConfig} */
2931
2965
  const result = {
2966
+ appType: 'custom',
2932
2967
  base: '/',
2933
2968
  build: {
2934
2969
  rollupOptions: {
2935
2970
  // Vite dependency crawler needs an explicit JS entry point
2936
2971
  // eventhough server otherwise works without it
2937
- input: `${get_runtime_path(svelte_config.kit)}/client/start.js`
2972
+ input: `${get_runtime_directory(svelte_config.kit)}/client/start.js`
2938
2973
  }
2939
2974
  },
2940
2975
  resolve: {
@@ -2966,10 +3001,16 @@ function kit() {
2966
3001
  return result;
2967
3002
  },
2968
3003
 
3004
+ /**
3005
+ * Stores the final config.
3006
+ */
2969
3007
  configResolved(config) {
2970
3008
  vite_config = config;
2971
3009
  },
2972
3010
 
3011
+ /**
3012
+ * Clears the output directories.
3013
+ */
2973
3014
  buildStart() {
2974
3015
  if (is_build) {
2975
3016
  rimraf(paths.build_dir);
@@ -2980,6 +3021,11 @@ function kit() {
2980
3021
  }
2981
3022
  },
2982
3023
 
3024
+ /**
3025
+ * Vite builds a single bundle. We need three bundles: client, server, and service worker.
3026
+ * The user's package.json scripts will invoke the Vite CLI to execute the client build. We
3027
+ * then use this hook to kick off builds for the server and service worker.
3028
+ */
2983
3029
  async writeBundle(_options, bundle) {
2984
3030
  log = logger({
2985
3031
  verbose: vite_config.logLevel === 'info'
@@ -2990,36 +3036,10 @@ function kit() {
2990
3036
  JSON.stringify({ version: process.env.VITE_SVELTEKIT_APP_VERSION })
2991
3037
  );
2992
3038
 
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
- };
3039
+ const { assets, chunks } = collect_output(bundle);
3021
3040
  log.info(`Client build completed. Wrote ${chunks.length} chunks and ${assets.length} assets`);
3022
3041
 
3042
+ log.info('Building server');
3023
3043
  const options = {
3024
3044
  cwd,
3025
3045
  config: svelte_config,
@@ -3029,13 +3049,9 @@ function kit() {
3029
3049
  output_dir: paths.output_dir,
3030
3050
  service_worker_entry_file: resolve_entry(svelte_config.kit.files.serviceWorker)
3031
3051
  };
3032
-
3033
- log.info('Building server');
3034
-
3052
+ const client = client_build_info(assets, chunks);
3035
3053
  const server = await build_server(options, client);
3036
3054
 
3037
- process.env.SVELTEKIT_SERVER_BUILD_COMPLETED = 'true';
3038
-
3039
3055
  /** @type {import('types').BuildData} */
3040
3056
  build_data = {
3041
3057
  app_dir: svelte_config.kit.appDir,
@@ -3054,6 +3070,9 @@ function kit() {
3054
3070
  })};\n`
3055
3071
  );
3056
3072
 
3073
+ process.env.SVELTEKIT_SERVER_BUILD_COMPLETED = 'true';
3074
+ log.info('Prerendering');
3075
+
3057
3076
  const static_files = manifest_data.assets.map((asset) => posixify(asset.file));
3058
3077
 
3059
3078
  const files = new Set([
@@ -3069,8 +3088,6 @@ function kit() {
3069
3088
  }
3070
3089
  });
3071
3090
 
3072
- log.info('Prerendering');
3073
-
3074
3091
  prerendered = await prerender({
3075
3092
  config: svelte_config.kit,
3076
3093
  entries: manifest_data.routes
@@ -3095,6 +3112,9 @@ function kit() {
3095
3112
  );
3096
3113
  },
3097
3114
 
3115
+ /**
3116
+ * Runs the adapter.
3117
+ */
3098
3118
  async closeBundle() {
3099
3119
  if (!is_build) {
3100
3120
  return; // vite calls closeBundle when dev-server restarts, ignore that
@@ -3112,30 +3132,70 @@ function kit() {
3112
3132
 
3113
3133
  if (svelte_config.kit.prerender.enabled) {
3114
3134
  // this is necessary to close any open db connections, etc.
3115
- // TODO: prerender in a subprocess so we can exit in isolation
3135
+ // TODO: prerender in a subprocess so we can exit in isolation and then remove this
3116
3136
  // https://github.com/sveltejs/kit/issues/5306
3117
3137
  process.exit(0);
3118
3138
  }
3119
3139
  },
3120
3140
 
3141
+ /**
3142
+ * Adds the SvelteKit middleware to do SSR in dev mode.
3143
+ * @see https://vitejs.dev/guide/api-plugin.html#configureserver
3144
+ */
3121
3145
  async configureServer(vite) {
3122
3146
  return await dev(vite, vite_config, svelte_config);
3123
3147
  },
3124
3148
 
3149
+ /**
3150
+ * Adds the SvelteKit middleware to do SSR in preview mode.
3151
+ * @see https://vitejs.dev/guide/api-plugin.html#configurepreviewserver
3152
+ */
3125
3153
  configurePreviewServer(vite) {
3126
3154
  return preview(vite, svelte_config, vite_config.preview.https ? 'https' : 'http');
3127
3155
  }
3128
3156
  };
3129
3157
  }
3130
3158
 
3159
+ function check_vite_version() {
3160
+ let vite_major = 3;
3161
+
3162
+ try {
3163
+ const pkg = JSON.parse(fs__default.readFileSync('package.json', 'utf-8'));
3164
+ vite_major = +pkg.devDependencies['vite'].replace(/^[~^]/, '')[0];
3165
+ } catch {
3166
+ // do nothing
3167
+ }
3168
+
3169
+ if (vite_major < 3) {
3170
+ throw new Error(
3171
+ `Vite version ${vite_major} is no longer supported. Please upgrade to version 3`
3172
+ );
3173
+ }
3174
+ }
3175
+
3176
+ /** @param {import('rollup').OutputBundle} bundle */
3177
+ function collect_output(bundle) {
3178
+ /** @type {import('rollup').OutputChunk[]} */
3179
+ const chunks = [];
3180
+ /** @type {import('rollup').OutputAsset[]} */
3181
+ const assets = [];
3182
+ for (const value of Object.values(bundle)) {
3183
+ // collect asset and output chunks
3184
+ if (value.type === 'asset') {
3185
+ assets.push(value);
3186
+ } else {
3187
+ chunks.push(value);
3188
+ }
3189
+ }
3190
+ return { assets, chunks };
3191
+ }
3192
+
3131
3193
  /**
3132
3194
  * @param {Record<string, any>} config
3133
3195
  * @param {Record<string, any>} resolved_config
3134
- * @param {string} [path]
3135
- * @param {string[]} [out] used locally to compute the return value
3136
3196
  */
3137
- function warn_overridden_config(config, resolved_config, path = '', out = []) {
3138
- const overridden = find_overridden_config(config, resolved_config, path, out);
3197
+ function warn_overridden_config(config, resolved_config) {
3198
+ const overridden = find_overridden_config(config, resolved_config, enforced_config, '', []);
3139
3199
  if (overridden.length > 0) {
3140
3200
  console.log(
3141
3201
  $.bold().red('The following Vite config options will be overridden by SvelteKit:')
@@ -3147,16 +3207,21 @@ function warn_overridden_config(config, resolved_config, path = '', out = []) {
3147
3207
  /**
3148
3208
  * @param {Record<string, any>} config
3149
3209
  * @param {Record<string, any>} resolved_config
3210
+ * @param {import('./types').EnforcedConfig} enforced_config
3150
3211
  * @param {string} path
3151
3212
  * @param {string[]} out used locally to compute the return value
3152
3213
  */
3153
- function find_overridden_config(config, resolved_config, path, out) {
3214
+ function find_overridden_config(config, resolved_config, enforced_config, path, out) {
3154
3215
  for (const key in enforced_config) {
3155
3216
  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);
3217
+ const enforced = enforced_config[key];
3218
+
3219
+ if (enforced === true) {
3220
+ if (config[key] !== resolved_config[key]) {
3221
+ out.push(path + key);
3222
+ }
3158
3223
  } else {
3159
- find_overridden_config(config[key], resolved_config[key], path + key + '.', out);
3224
+ find_overridden_config(config[key], resolved_config[key], enforced, path + key + '.', out);
3160
3225
  }
3161
3226
  }
3162
3227
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.371",
3
+ "version": "1.0.0-next.374",
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
@@ -105,6 +105,7 @@ export interface KitConfig {
105
105
  csp?: {
106
106
  mode?: 'hash' | 'nonce' | 'auto';
107
107
  directives?: CspDirectives;
108
+ reportOnly?: CspDirectives;
108
109
  };
109
110
  moduleExtensions?: string[];
110
111
  files?: {
@@ -150,7 +151,6 @@ export interface KitConfig {
150
151
  name?: string;
151
152
  pollInterval?: number;
152
153
  };
153
- vite?: import('vite').UserConfig | (() => MaybePromise<import('vite').UserConfig>);
154
154
  }
155
155
 
156
156
  export interface ExternalFetch {
@@ -182,7 +182,7 @@ export interface Load<
182
182
  InputProps extends Record<string, any> = Record<string, any>,
183
183
  OutputProps extends Record<string, any> = InputProps
184
184
  > {
185
- (event: LoadEvent<Params, InputProps>): MaybePromise<LoadOutput<OutputProps>>;
185
+ (event: LoadEvent<Params, InputProps>): MaybePromise<LoadOutput<OutputProps> | void>;
186
186
  }
187
187
 
188
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