@sveltejs/kit 1.0.0-next.206 → 1.0.0-next.210

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.
package/dist/ssr.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { g as get_single_valued_header, r as resolve, i as is_root_relative } from './chunks/url.js';
2
2
  import { c as coalesce_to_error } from './chunks/error.js';
3
+ import { s } from './chunks/misc.js';
3
4
 
4
5
  /** @param {Record<string, any>} obj */
5
6
  function lowercase_keys(obj) {
@@ -13,6 +14,28 @@ function lowercase_keys(obj) {
13
14
  return clone;
14
15
  }
15
16
 
17
+ /** @param {Record<string, string>} params */
18
+ function decode_params(params) {
19
+ for (const key in params) {
20
+ // input has already been decoded by decodeURI
21
+ // now handle the rest that decodeURIComponent would do
22
+ params[key] = params[key]
23
+ .replace(/%23/g, '#')
24
+ .replace(/%3[Bb]/g, ';')
25
+ .replace(/%2[Cc]/g, ',')
26
+ .replace(/%2[Ff]/g, '/')
27
+ .replace(/%3[Ff]/g, '?')
28
+ .replace(/%3[Aa]/g, ':')
29
+ .replace(/%40/g, '@')
30
+ .replace(/%26/g, '&')
31
+ .replace(/%3[Dd]/g, '=')
32
+ .replace(/%2[Bb]/g, '+')
33
+ .replace(/%24/g, '$');
34
+ }
35
+
36
+ return params;
37
+ }
38
+
16
39
  /** @param {string} body */
17
40
  function error(body) {
18
41
  return {
@@ -60,10 +83,13 @@ async function render_endpoint(request, route, match) {
60
83
  return;
61
84
  }
62
85
 
63
- const params = route.params(match);
86
+ // we're mutating `request` so that we don't have to do { ...request, params }
87
+ // on the next line, since that breaks the getters that replace path, query and
88
+ // origin. We could revert that once we remove the getters
89
+ request.params = route.params ? decode_params(route.params(match)) : {};
64
90
 
65
- const response = await handler({ ...request, params });
66
- const preface = `Invalid response from route ${request.path}`;
91
+ const response = await handler(request);
92
+ const preface = `Invalid response from route ${request.url.pathname}`;
67
93
 
68
94
  if (!response) {
69
95
  return;
@@ -478,8 +504,6 @@ function escape(str, dict, unicode_encoder) {
478
504
  return result;
479
505
  }
480
506
 
481
- const s$1 = JSON.stringify;
482
-
483
507
  // TODO rename this function/module
484
508
 
485
509
  /**
@@ -490,7 +514,8 @@ const s$1 = JSON.stringify;
490
514
  * page_config: { hydrate: boolean, router: boolean, ssr: boolean };
491
515
  * status: number;
492
516
  * error?: Error,
493
- * page?: import('types/page').Page
517
+ * url: URL;
518
+ * params: Record<string, string>
494
519
  * }} opts
495
520
  */
496
521
  async function render_response({
@@ -500,10 +525,11 @@ async function render_response({
500
525
  page_config,
501
526
  status,
502
527
  error,
503
- page
528
+ url,
529
+ params
504
530
  }) {
505
- const css = new Set(options.entry.css);
506
- const js = new Set(options.entry.js);
531
+ const css = new Set(options.manifest._.entry.css);
532
+ const js = new Set(options.manifest._.entry.js);
507
533
  const styles = new Set();
508
534
 
509
535
  /** @type {Array<{ url: string, body: string, json: string }>} */
@@ -541,10 +567,27 @@ async function render_response({
541
567
  navigating: writable(null),
542
568
  session
543
569
  },
544
- page,
570
+ page: { url, params },
545
571
  components: branch.map(({ node }) => node.module.default)
546
572
  };
547
573
 
574
+ // TODO remove this for 1.0
575
+ /**
576
+ * @param {string} property
577
+ * @param {string} replacement
578
+ */
579
+ const print_error = (property, replacement) => {
580
+ Object.defineProperty(props.page, property, {
581
+ get: () => {
582
+ throw new Error(`$page.${property} has been replaced by $page.url.${replacement}`);
583
+ }
584
+ });
585
+ };
586
+
587
+ print_error('origin', 'origin');
588
+ print_error('path', 'pathname');
589
+ print_error('query', 'searchParams');
590
+
548
591
  // props_n (instead of props[n]) makes it easy to avoid
549
592
  // unnecessary updates for layout components
550
593
  for (let i = 0; i < branch.length; i += 1) {
@@ -575,8 +618,11 @@ async function render_response({
575
618
  ? `<style amp-custom>${Array.from(styles).concat(rendered.css.code).join('\n')}</style>`
576
619
  : ''
577
620
  : [
578
- ...Array.from(js).map((dep) => `<link rel="modulepreload" href="${dep}">`),
579
- ...Array.from(css).map((dep) => `<link rel="stylesheet" href="${dep}">`)
621
+ // From https://web.dev/priority-hints/:
622
+ // Generally, preloads will load in the order the parser gets to them for anything above "Medium" priority
623
+ // Thus, we should list CSS first
624
+ ...Array.from(css).map((dep) => `<link rel="stylesheet" href="${options.prefix}${dep}">`),
625
+ ...Array.from(js).map((dep) => `<link rel="modulepreload" href="${options.prefix}${dep}">`)
580
626
  ].join('\n\t\t');
581
627
 
582
628
  /** @type {string} */
@@ -593,35 +639,26 @@ async function render_response({
593
639
  } else if (include_js) {
594
640
  // prettier-ignore
595
641
  init = `<script type="module">
596
- import { start } from ${s$1(options.entry.file)};
642
+ import { start } from ${s(options.prefix + options.manifest._.entry.file)};
597
643
  start({
598
- target: ${options.target ? `document.querySelector(${s$1(options.target)})` : 'document.body'},
599
- paths: ${s$1(options.paths)},
644
+ target: ${options.target ? `document.querySelector(${s(options.target)})` : 'document.body'},
645
+ paths: ${s(options.paths)},
600
646
  session: ${try_serialize($session, (error) => {
601
647
  throw new Error(`Failed to serialize session data: ${error.message}`);
602
648
  })},
603
- host: ${page && page.host ? s$1(page.host) : 'location.host'},
604
649
  route: ${!!page_config.router},
605
650
  spa: ${!page_config.ssr},
606
- trailing_slash: ${s$1(options.trailing_slash)},
651
+ trailing_slash: ${s(options.trailing_slash)},
607
652
  hydrate: ${page_config.ssr && page_config.hydrate ? `{
608
653
  status: ${status},
609
654
  error: ${serialize_error(error)},
610
655
  nodes: [
611
656
  ${(branch || [])
612
- .map(({ node }) => `import(${s$1(node.entry)})`)
657
+ .map(({ node }) => `import(${s(options.prefix + node.entry)})`)
613
658
  .join(',\n\t\t\t\t\t\t')}
614
659
  ],
615
- page: {
616
- host: ${page && page.host ? s$1(page.host) : 'location.host'}, // TODO this is redundant
617
- path: ${page && page.path ? try_serialize(page.path, error => {
618
- throw new Error(`Failed to serialize page.path: ${error.message}`);
619
- }) : null},
620
- query: new URLSearchParams(${page && page.query ? s$1(page.query.toString()) : ''}),
621
- params: ${page && page.params ? try_serialize(page.params, error => {
622
- throw new Error(`Failed to serialize page.params: ${error.message}`);
623
- }) : null}
624
- }
660
+ url: new URL(${s(url.href)}),
661
+ params: ${devalue(params)}
625
662
  }` : 'null'}
626
663
  });
627
664
  </script>`;
@@ -776,15 +813,14 @@ function normalize(loaded) {
776
813
  return /** @type {import('types/internal').NormalizedLoadOutput} */ (loaded);
777
814
  }
778
815
 
779
- const s = JSON.stringify;
780
-
781
816
  /**
782
817
  * @param {{
783
818
  * request: import('types/hooks').ServerRequest;
784
819
  * options: import('types/internal').SSRRenderOptions;
785
820
  * state: import('types/internal').SSRRenderState;
786
821
  * route: import('types/internal').SSRPage | null;
787
- * page: import('types/page').Page;
822
+ * url: URL;
823
+ * params: Record<string, string>;
788
824
  * node: import('types/internal').SSRNode;
789
825
  * $session: any;
790
826
  * stuff: Record<string, any>;
@@ -801,7 +837,8 @@ async function load_node({
801
837
  options,
802
838
  state,
803
839
  route,
804
- page,
840
+ url,
841
+ params,
805
842
  node,
806
843
  $session,
807
844
  stuff,
@@ -831,9 +868,9 @@ async function load_node({
831
868
 
832
869
  let loaded;
833
870
 
834
- const page_proxy = new Proxy(page, {
871
+ const url_proxy = new Proxy(url, {
835
872
  get: (target, prop, receiver) => {
836
- if (prop === 'query' && prerender_enabled) {
873
+ if (prerender_enabled && (prop === 'search' || prop === 'searchParams')) {
837
874
  throw new Error('Cannot access query on a page with prerendering enabled');
838
875
  }
839
876
  return Reflect.get(target, prop, receiver);
@@ -843,7 +880,8 @@ async function load_node({
843
880
  if (module.load) {
844
881
  /** @type {import('types/page').LoadInput | import('types/page').ErrorLoadInput} */
845
882
  const load_input = {
846
- page: page_proxy,
883
+ url: url_proxy,
884
+ params,
847
885
  get session() {
848
886
  uses_credentials = true;
849
887
  return $session;
@@ -854,12 +892,12 @@ async function load_node({
854
892
  */
855
893
  fetch: async (resource, opts = {}) => {
856
894
  /** @type {string} */
857
- let url;
895
+ let requested;
858
896
 
859
897
  if (typeof resource === 'string') {
860
- url = resource;
898
+ requested = resource;
861
899
  } else {
862
- url = resource.url;
900
+ requested = resource.url;
863
901
 
864
902
  opts = {
865
903
  method: resource.method,
@@ -877,7 +915,7 @@ async function load_node({
877
915
 
878
916
  opts.headers = new Headers(opts.headers);
879
917
 
880
- const resolved = resolve(request.path, url.split('?')[0]);
918
+ const resolved = resolve(request.url.pathname, requested.split('?')[0]);
881
919
 
882
920
  let response;
883
921
 
@@ -888,20 +926,24 @@ async function load_node({
888
926
  resolved.startsWith(prefix) ? resolved.slice(prefix.length) : resolved
889
927
  ).slice(1);
890
928
  const filename_html = `${filename}/index.html`; // path may also match path/index.html
891
- const asset = options.manifest.assets.find(
892
- (d) => d.file === filename || d.file === filename_html
893
- );
894
929
 
895
- if (asset) {
896
- response = options.read
897
- ? new Response(options.read(asset.file), {
898
- headers: asset.type ? { 'content-type': asset.type } : {}
899
- })
900
- : await fetch(
901
- // TODO we need to know what protocol to use
902
- `http://${page.host}/${asset.file}`,
903
- /** @type {RequestInit} */ (opts)
904
- );
930
+ const is_asset = options.manifest.assets.has(filename);
931
+ const is_asset_html = options.manifest.assets.has(filename_html);
932
+
933
+ if (is_asset || is_asset_html) {
934
+ const file = is_asset ? filename : filename_html;
935
+
936
+ if (options.read) {
937
+ const type = is_asset
938
+ ? options.manifest._.mime[filename.slice(filename.lastIndexOf('.'))]
939
+ : 'text/html';
940
+
941
+ response = new Response(options.read(file), {
942
+ headers: type ? { 'content-type': type } : {}
943
+ });
944
+ } else {
945
+ response = await fetch(`${url.origin}/${file}`, /** @type {RequestInit} */ (opts));
946
+ }
905
947
  } else if (is_root_relative(resolved)) {
906
948
  const relative = resolved;
907
949
 
@@ -926,20 +968,16 @@ async function load_node({
926
968
  throw new Error('Request body must be a string');
927
969
  }
928
970
 
929
- const search = url.includes('?') ? url.slice(url.indexOf('?') + 1) : '';
930
-
931
971
  const rendered = await respond(
932
972
  {
933
- host: request.host,
973
+ url: new URL(requested, request.url),
934
974
  method: opts.method || 'GET',
935
975
  headers: Object.fromEntries(opts.headers),
936
- path: relative,
937
- rawBody: opts.body == null ? null : new TextEncoder().encode(opts.body),
938
- query: new URLSearchParams(search)
976
+ rawBody: opts.body == null ? null : new TextEncoder().encode(opts.body)
939
977
  },
940
978
  options,
941
979
  {
942
- fetched: url,
980
+ fetched: requested,
943
981
  initiator: route
944
982
  }
945
983
  );
@@ -956,36 +994,40 @@ async function load_node({
956
994
  status: rendered.status,
957
995
  headers: /** @type {Record<string, string>} */ (rendered.headers)
958
996
  });
997
+ } else {
998
+ // we can't load the endpoint from our own manifest,
999
+ // so we need to make an actual HTTP request
1000
+ return fetch(new URL(requested, request.url).href, {
1001
+ method: opts.method || 'GET',
1002
+ headers: opts.headers
1003
+ });
959
1004
  }
960
1005
  } else {
961
1006
  // external
962
1007
  if (resolved.startsWith('//')) {
963
- throw new Error(`Cannot request protocol-relative URL (${url}) in server-side fetch`);
1008
+ throw new Error(
1009
+ `Cannot request protocol-relative URL (${requested}) in server-side fetch`
1010
+ );
964
1011
  }
965
1012
 
966
1013
  // external fetch
967
- if (typeof request.host !== 'undefined') {
968
- const { hostname: fetch_hostname } = new URL(url);
969
- const [server_hostname] = request.host.split(':');
970
-
971
- // allow cookie passthrough for "same-origin"
972
- // if SvelteKit is serving my.domain.com:
973
- // - domain.com WILL NOT receive cookies
974
- // - my.domain.com WILL receive cookies
975
- // - api.domain.dom WILL NOT receive cookies
976
- // - sub.my.domain.com WILL receive cookies
977
- // ports do not affect the resolution
978
- // leading dot prevents mydomain.com matching domain.com
979
- if (
980
- `.${fetch_hostname}`.endsWith(`.${server_hostname}`) &&
981
- opts.credentials !== 'omit'
982
- ) {
983
- uses_credentials = true;
984
- opts.headers.set('cookie', request.headers.cookie);
985
- }
1014
+ // allow cookie passthrough for "same-origin"
1015
+ // if SvelteKit is serving my.domain.com:
1016
+ // - domain.com WILL NOT receive cookies
1017
+ // - my.domain.com WILL receive cookies
1018
+ // - api.domain.dom WILL NOT receive cookies
1019
+ // - sub.my.domain.com WILL receive cookies
1020
+ // ports do not affect the resolution
1021
+ // leading dot prevents mydomain.com matching domain.com
1022
+ if (
1023
+ `.${new URL(requested).hostname}`.endsWith(`.${request.url.hostname}`) &&
1024
+ opts.credentials !== 'omit'
1025
+ ) {
1026
+ uses_credentials = true;
1027
+ opts.headers.set('cookie', request.headers.cookie);
986
1028
  }
987
1029
 
988
- const external_request = new Request(url, /** @type {RequestInit} */ (opts));
1030
+ const external_request = new Request(requested, /** @type {RequestInit} */ (opts));
989
1031
  response = await options.hooks.externalFetch.call(null, external_request);
990
1032
  }
991
1033
 
@@ -1008,7 +1050,7 @@ async function load_node({
1008
1050
  if (!opts.body || typeof opts.body === 'string') {
1009
1051
  // prettier-ignore
1010
1052
  fetched.push({
1011
- url,
1053
+ url: requested,
1012
1054
  body: /** @type {string} */ (opts.body),
1013
1055
  json: `{"status":${response.status},"statusText":${s(response.statusText)},"headers":${s(headers)},"body":"${escape_json_string_in_html(body)}"}`
1014
1056
  });
@@ -1046,6 +1088,15 @@ async function load_node({
1046
1088
  stuff: { ...stuff }
1047
1089
  };
1048
1090
 
1091
+ if (options.dev) {
1092
+ // TODO remove this for 1.0
1093
+ Object.defineProperty(load_input, 'page', {
1094
+ get: () => {
1095
+ throw new Error('`page` in `load` functions has been replaced by `url` and `params`');
1096
+ }
1097
+ });
1098
+ }
1099
+
1049
1100
  if (is_error) {
1050
1101
  /** @type {import('types/page').ErrorLoadInput} */ (load_input).status = status;
1051
1102
  /** @type {import('types/page').ErrorLoadInput} */ (load_input).error = error;
@@ -1092,15 +1143,11 @@ async function load_node({
1092
1143
  * }} opts
1093
1144
  */
1094
1145
  async function respond_with_error({ request, options, state, $session, status, error }) {
1095
- const default_layout = await options.load_component(options.manifest.layout);
1096
- const default_error = await options.load_component(options.manifest.error);
1097
-
1098
- const page = {
1099
- host: request.host,
1100
- path: request.path,
1101
- query: request.query,
1102
- params: {}
1103
- };
1146
+ const default_layout = await options.manifest._.nodes[0](); // 0 is always the root layout
1147
+ const default_error = await options.manifest._.nodes[1](); // 1 is always the root error
1148
+
1149
+ /** @type {Record<string, string>} */
1150
+ const params = {}; // error page has no params
1104
1151
 
1105
1152
  // error pages don't fall through, so we know it's not undefined
1106
1153
  const loaded = /** @type {Loaded} */ (
@@ -1109,7 +1156,8 @@ async function respond_with_error({ request, options, state, $session, status, e
1109
1156
  options,
1110
1157
  state,
1111
1158
  route: null,
1112
- page,
1159
+ url: request.url, // TODO this is redundant, no?
1160
+ params,
1113
1161
  node: default_layout,
1114
1162
  $session,
1115
1163
  stuff: {},
@@ -1127,7 +1175,8 @@ async function respond_with_error({ request, options, state, $session, status, e
1127
1175
  options,
1128
1176
  state,
1129
1177
  route: null,
1130
- page,
1178
+ url: request.url,
1179
+ params,
1131
1180
  node: default_error,
1132
1181
  $session,
1133
1182
  stuff: loaded ? loaded.stuff : {},
@@ -1152,7 +1201,8 @@ async function respond_with_error({ request, options, state, $session, status, e
1152
1201
  status,
1153
1202
  error,
1154
1203
  branch,
1155
- page
1204
+ url: request.url,
1205
+ params
1156
1206
  });
1157
1207
  } catch (err) {
1158
1208
  const error = coalesce_to_error(err);
@@ -1193,7 +1243,7 @@ function is_prerender_enabled(options, node, state) {
1193
1243
  * state: SSRRenderState;
1194
1244
  * $session: any;
1195
1245
  * route: import('types/internal').SSRPage;
1196
- * page: import('types/page').Page;
1246
+ * params: Record<string, string>;
1197
1247
  * }} opts
1198
1248
  * @returns {Promise<ServerResponse | undefined>}
1199
1249
  */
@@ -1204,7 +1254,9 @@ async function respond$1(opts) {
1204
1254
  let nodes;
1205
1255
 
1206
1256
  try {
1207
- nodes = await Promise.all(route.a.map((id) => (id ? options.load_component(id) : undefined)));
1257
+ nodes = await Promise.all(
1258
+ route.a.map((n) => options.manifest._.nodes[n] && options.manifest._.nodes[n]())
1259
+ );
1208
1260
  } catch (err) {
1209
1261
  const error = coalesce_to_error(err);
1210
1262
 
@@ -1259,6 +1311,7 @@ async function respond$1(opts) {
1259
1311
  try {
1260
1312
  loaded = await load_node({
1261
1313
  ...opts,
1314
+ url: request.url,
1262
1315
  node,
1263
1316
  stuff,
1264
1317
  prerender_enabled: is_prerender_enabled(options, node, state),
@@ -1301,7 +1354,7 @@ async function respond$1(opts) {
1301
1354
  if (error) {
1302
1355
  while (i--) {
1303
1356
  if (route.b[i]) {
1304
- const error_node = await options.load_component(route.b[i]);
1357
+ const error_node = await options.manifest._.nodes[route.b[i]]();
1305
1358
 
1306
1359
  /** @type {Loaded} */
1307
1360
  let node_loaded;
@@ -1315,6 +1368,7 @@ async function respond$1(opts) {
1315
1368
  const error_loaded = /** @type {import('./types').Loaded} */ (
1316
1369
  await load_node({
1317
1370
  ...opts,
1371
+ url: request.url,
1318
1372
  node: error_node,
1319
1373
  stuff: node_loaded.stuff,
1320
1374
  prerender_enabled: is_prerender_enabled(options, error_node, state),
@@ -1372,6 +1426,7 @@ async function respond$1(opts) {
1372
1426
  return with_cookies(
1373
1427
  await render_response({
1374
1428
  ...opts,
1429
+ url: request.url,
1375
1430
  page_config,
1376
1431
  status,
1377
1432
  error,
@@ -1432,18 +1487,11 @@ async function render_page(request, route, match, options, state) {
1432
1487
  return {
1433
1488
  status: 404,
1434
1489
  headers: {},
1435
- body: `Not found: ${request.path}`
1490
+ body: `Not found: ${request.url.pathname}`
1436
1491
  };
1437
1492
  }
1438
1493
 
1439
- const params = route.params(match);
1440
-
1441
- const page = {
1442
- host: request.host,
1443
- path: request.path,
1444
- query: request.query,
1445
- params
1446
- };
1494
+ const params = route.params ? decode_params(route.params(match)) : {};
1447
1495
 
1448
1496
  const $session = await options.hooks.getSession(request);
1449
1497
 
@@ -1453,7 +1501,7 @@ async function render_page(request, route, match, options, state) {
1453
1501
  state,
1454
1502
  $session,
1455
1503
  route,
1456
- page
1504
+ params
1457
1505
  });
1458
1506
 
1459
1507
  if (response) {
@@ -1658,22 +1706,25 @@ function get_multipart(text, boundary) {
1658
1706
 
1659
1707
  /** @type {import('@sveltejs/kit/ssr').Respond} */
1660
1708
  async function respond(incoming, options, state = {}) {
1661
- if (incoming.path !== '/' && options.trailing_slash !== 'ignore') {
1662
- const has_trailing_slash = incoming.path.endsWith('/');
1709
+ if (incoming.url.pathname !== '/' && options.trailing_slash !== 'ignore') {
1710
+ const has_trailing_slash = incoming.url.pathname.endsWith('/');
1663
1711
 
1664
1712
  if (
1665
1713
  (has_trailing_slash && options.trailing_slash === 'never') ||
1666
1714
  (!has_trailing_slash &&
1667
1715
  options.trailing_slash === 'always' &&
1668
- !(incoming.path.split('/').pop() || '').includes('.'))
1716
+ !(incoming.url.pathname.split('/').pop() || '').includes('.'))
1669
1717
  ) {
1670
- const path = has_trailing_slash ? incoming.path.slice(0, -1) : incoming.path + '/';
1671
- const q = incoming.query.toString();
1718
+ incoming.url.pathname = has_trailing_slash
1719
+ ? incoming.url.pathname.slice(0, -1)
1720
+ : incoming.url.pathname + '/';
1721
+
1722
+ if (incoming.url.search === '?') incoming.url.search = '';
1672
1723
 
1673
1724
  return {
1674
1725
  status: 301,
1675
1726
  headers: {
1676
- location: options.paths.base + path + (q ? `?${q}` : '')
1727
+ location: incoming.url.pathname + incoming.url.search
1677
1728
  }
1678
1729
  };
1679
1730
  }
@@ -1688,12 +1739,31 @@ async function respond(incoming, options, state = {}) {
1688
1739
  locals: {}
1689
1740
  };
1690
1741
 
1742
+ // TODO remove this for 1.0
1743
+ /**
1744
+ * @param {string} property
1745
+ * @param {string} replacement
1746
+ */
1747
+ const print_error = (property, replacement) => {
1748
+ Object.defineProperty(request, property, {
1749
+ get: () => {
1750
+ throw new Error(`request.${property} has been replaced by request.url.${replacement}`);
1751
+ }
1752
+ });
1753
+ };
1754
+
1755
+ print_error('origin', 'origin');
1756
+ print_error('path', 'pathname');
1757
+ print_error('query', 'searchParams');
1758
+
1691
1759
  try {
1692
1760
  return await options.hooks.handle({
1693
1761
  request,
1694
1762
  resolve: async (request) => {
1695
1763
  if (state.prerender && state.prerender.fallback) {
1696
1764
  return await render_response({
1765
+ url: request.url,
1766
+ params: request.params,
1697
1767
  options,
1698
1768
  $session: await options.hooks.getSession(request),
1699
1769
  page_config: { ssr: false, router: true, hydrate: true },
@@ -1702,8 +1772,9 @@ async function respond(incoming, options, state = {}) {
1702
1772
  });
1703
1773
  }
1704
1774
 
1705
- const decoded = decodeURI(request.path);
1706
- for (const route of options.manifest.routes) {
1775
+ const decoded = decodeURI(request.url.pathname).replace(options.paths.base, '');
1776
+
1777
+ for (const route of options.manifest._.routes) {
1707
1778
  const match = route.pattern.exec(decoded);
1708
1779
  if (!match) continue;
1709
1780
 
@@ -1740,15 +1811,19 @@ async function respond(incoming, options, state = {}) {
1740
1811
  }
1741
1812
  }
1742
1813
 
1743
- const $session = await options.hooks.getSession(request);
1744
- return await respond_with_error({
1745
- request,
1746
- options,
1747
- state,
1748
- $session,
1749
- status: 404,
1750
- error: new Error(`Not found: ${request.path}`)
1751
- });
1814
+ // if this request came direct from the user, rather than
1815
+ // via a `fetch` in a `load`, render a 404 page
1816
+ if (!state.initiator) {
1817
+ const $session = await options.hooks.getSession(request);
1818
+ return await respond_with_error({
1819
+ request,
1820
+ options,
1821
+ state,
1822
+ $session,
1823
+ status: 404,
1824
+ error: new Error(`Not found: ${request.url.pathname}`)
1825
+ });
1826
+ }
1752
1827
  }
1753
1828
  });
1754
1829
  } catch (/** @type {unknown} */ err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.206",
3
+ "version": "1.0.0-next.210",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -87,6 +87,5 @@
87
87
  "test:unit": "uvu src \"(spec\\.js|test[\\\\/]index\\.js)\" -i packaging",
88
88
  "test:packaging": "uvu src/packaging \"(spec\\.js|test[\\\\/]index\\.js)\"",
89
89
  "test:integration": "uvu test test.js"
90
- },
91
- "readme": "# The fastest way to build Svelte apps\n\nThis is the [SvelteKit](https://kit.svelte.dev) framework and CLI.\n\nThe quickest way to get started is via the [create-svelte](https://github.com/sveltejs/kit/tree/master/packages/create-svelte) package:\n\n```bash\nnpm init svelte@next my-app\ncd my-app\nnpm install\nnpm run dev\n```\n\nSee the [documentation](https://kit.svelte.dev/docs) to learn more.\n\n## Changelog\n\n[The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md).\n"
90
+ }
92
91
  }