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

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,29 @@ 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
+ if (options.dev) {
575
+ // TODO remove this for 1.0
576
+ /**
577
+ * @param {string} property
578
+ * @param {string} replacement
579
+ */
580
+ const print_error = (property, replacement) => {
581
+ Object.defineProperty(props.page, property, {
582
+ get: () => {
583
+ throw new Error(`$page.${property} has been replaced by $page.url.${replacement}`);
584
+ }
585
+ });
586
+ };
587
+
588
+ print_error('origin', 'origin');
589
+ print_error('path', 'pathname');
590
+ print_error('query', 'searchParams');
591
+ }
592
+
548
593
  // props_n (instead of props[n]) makes it easy to avoid
549
594
  // unnecessary updates for layout components
550
595
  for (let i = 0; i < branch.length; i += 1) {
@@ -575,8 +620,11 @@ async function render_response({
575
620
  ? `<style amp-custom>${Array.from(styles).concat(rendered.css.code).join('\n')}</style>`
576
621
  : ''
577
622
  : [
578
- ...Array.from(js).map((dep) => `<link rel="modulepreload" href="${dep}">`),
579
- ...Array.from(css).map((dep) => `<link rel="stylesheet" href="${dep}">`)
623
+ // From https://web.dev/priority-hints/:
624
+ // Generally, preloads will load in the order the parser gets to them for anything above "Medium" priority
625
+ // Thus, we should list CSS first
626
+ ...Array.from(css).map((dep) => `<link rel="stylesheet" href="${options.prefix}${dep}">`),
627
+ ...Array.from(js).map((dep) => `<link rel="modulepreload" href="${options.prefix}${dep}">`)
580
628
  ].join('\n\t\t');
581
629
 
582
630
  /** @type {string} */
@@ -593,35 +641,26 @@ async function render_response({
593
641
  } else if (include_js) {
594
642
  // prettier-ignore
595
643
  init = `<script type="module">
596
- import { start } from ${s$1(options.entry.file)};
644
+ import { start } from ${s(options.prefix + options.manifest._.entry.file)};
597
645
  start({
598
- target: ${options.target ? `document.querySelector(${s$1(options.target)})` : 'document.body'},
599
- paths: ${s$1(options.paths)},
646
+ target: ${options.target ? `document.querySelector(${s(options.target)})` : 'document.body'},
647
+ paths: ${s(options.paths)},
600
648
  session: ${try_serialize($session, (error) => {
601
649
  throw new Error(`Failed to serialize session data: ${error.message}`);
602
650
  })},
603
- host: ${page && page.host ? s$1(page.host) : 'location.host'},
604
651
  route: ${!!page_config.router},
605
652
  spa: ${!page_config.ssr},
606
- trailing_slash: ${s$1(options.trailing_slash)},
653
+ trailing_slash: ${s(options.trailing_slash)},
607
654
  hydrate: ${page_config.ssr && page_config.hydrate ? `{
608
655
  status: ${status},
609
656
  error: ${serialize_error(error)},
610
657
  nodes: [
611
658
  ${(branch || [])
612
- .map(({ node }) => `import(${s$1(node.entry)})`)
659
+ .map(({ node }) => `import(${s(options.prefix + node.entry)})`)
613
660
  .join(',\n\t\t\t\t\t\t')}
614
661
  ],
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
- }
662
+ url: new URL(${s(url.href)}),
663
+ params: ${devalue(params)}
625
664
  }` : 'null'}
626
665
  });
627
666
  </script>`;
@@ -776,15 +815,14 @@ function normalize(loaded) {
776
815
  return /** @type {import('types/internal').NormalizedLoadOutput} */ (loaded);
777
816
  }
778
817
 
779
- const s = JSON.stringify;
780
-
781
818
  /**
782
819
  * @param {{
783
820
  * request: import('types/hooks').ServerRequest;
784
821
  * options: import('types/internal').SSRRenderOptions;
785
822
  * state: import('types/internal').SSRRenderState;
786
823
  * route: import('types/internal').SSRPage | null;
787
- * page: import('types/page').Page;
824
+ * url: URL;
825
+ * params: Record<string, string>;
788
826
  * node: import('types/internal').SSRNode;
789
827
  * $session: any;
790
828
  * stuff: Record<string, any>;
@@ -801,7 +839,8 @@ async function load_node({
801
839
  options,
802
840
  state,
803
841
  route,
804
- page,
842
+ url,
843
+ params,
805
844
  node,
806
845
  $session,
807
846
  stuff,
@@ -831,9 +870,9 @@ async function load_node({
831
870
 
832
871
  let loaded;
833
872
 
834
- const page_proxy = new Proxy(page, {
873
+ const url_proxy = new Proxy(url, {
835
874
  get: (target, prop, receiver) => {
836
- if (prop === 'query' && prerender_enabled) {
875
+ if (prerender_enabled && (prop === 'search' || prop === 'searchParams')) {
837
876
  throw new Error('Cannot access query on a page with prerendering enabled');
838
877
  }
839
878
  return Reflect.get(target, prop, receiver);
@@ -843,7 +882,8 @@ async function load_node({
843
882
  if (module.load) {
844
883
  /** @type {import('types/page').LoadInput | import('types/page').ErrorLoadInput} */
845
884
  const load_input = {
846
- page: page_proxy,
885
+ url: url_proxy,
886
+ params,
847
887
  get session() {
848
888
  uses_credentials = true;
849
889
  return $session;
@@ -854,12 +894,12 @@ async function load_node({
854
894
  */
855
895
  fetch: async (resource, opts = {}) => {
856
896
  /** @type {string} */
857
- let url;
897
+ let requested;
858
898
 
859
899
  if (typeof resource === 'string') {
860
- url = resource;
900
+ requested = resource;
861
901
  } else {
862
- url = resource.url;
902
+ requested = resource.url;
863
903
 
864
904
  opts = {
865
905
  method: resource.method,
@@ -877,7 +917,7 @@ async function load_node({
877
917
 
878
918
  opts.headers = new Headers(opts.headers);
879
919
 
880
- const resolved = resolve(request.path, url.split('?')[0]);
920
+ const resolved = resolve(request.url.pathname, requested.split('?')[0]);
881
921
 
882
922
  let response;
883
923
 
@@ -888,20 +928,24 @@ async function load_node({
888
928
  resolved.startsWith(prefix) ? resolved.slice(prefix.length) : resolved
889
929
  ).slice(1);
890
930
  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
931
 
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
- );
932
+ const is_asset = options.manifest.assets.has(filename);
933
+ const is_asset_html = options.manifest.assets.has(filename_html);
934
+
935
+ if (is_asset || is_asset_html) {
936
+ const file = is_asset ? filename : filename_html;
937
+
938
+ if (options.read) {
939
+ const type = is_asset
940
+ ? options.manifest._.mime[filename.slice(filename.lastIndexOf('.'))]
941
+ : 'text/html';
942
+
943
+ response = new Response(options.read(file), {
944
+ headers: type ? { 'content-type': type } : {}
945
+ });
946
+ } else {
947
+ response = await fetch(`${url.origin}/${file}`, /** @type {RequestInit} */ (opts));
948
+ }
905
949
  } else if (is_root_relative(resolved)) {
906
950
  const relative = resolved;
907
951
 
@@ -926,20 +970,16 @@ async function load_node({
926
970
  throw new Error('Request body must be a string');
927
971
  }
928
972
 
929
- const search = url.includes('?') ? url.slice(url.indexOf('?') + 1) : '';
930
-
931
973
  const rendered = await respond(
932
974
  {
933
- host: request.host,
975
+ url: new URL(requested, request.url),
934
976
  method: opts.method || 'GET',
935
977
  headers: Object.fromEntries(opts.headers),
936
- path: relative,
937
- rawBody: opts.body == null ? null : new TextEncoder().encode(opts.body),
938
- query: new URLSearchParams(search)
978
+ rawBody: opts.body == null ? null : new TextEncoder().encode(opts.body)
939
979
  },
940
980
  options,
941
981
  {
942
- fetched: url,
982
+ fetched: requested,
943
983
  initiator: route
944
984
  }
945
985
  );
@@ -956,36 +996,40 @@ async function load_node({
956
996
  status: rendered.status,
957
997
  headers: /** @type {Record<string, string>} */ (rendered.headers)
958
998
  });
999
+ } else {
1000
+ // we can't load the endpoint from our own manifest,
1001
+ // so we need to make an actual HTTP request
1002
+ return fetch(new URL(requested, request.url).href, {
1003
+ method: opts.method || 'GET',
1004
+ headers: opts.headers
1005
+ });
959
1006
  }
960
1007
  } else {
961
1008
  // external
962
1009
  if (resolved.startsWith('//')) {
963
- throw new Error(`Cannot request protocol-relative URL (${url}) in server-side fetch`);
1010
+ throw new Error(
1011
+ `Cannot request protocol-relative URL (${requested}) in server-side fetch`
1012
+ );
964
1013
  }
965
1014
 
966
1015
  // 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
- }
1016
+ // allow cookie passthrough for "same-origin"
1017
+ // if SvelteKit is serving my.domain.com:
1018
+ // - domain.com WILL NOT receive cookies
1019
+ // - my.domain.com WILL receive cookies
1020
+ // - api.domain.dom WILL NOT receive cookies
1021
+ // - sub.my.domain.com WILL receive cookies
1022
+ // ports do not affect the resolution
1023
+ // leading dot prevents mydomain.com matching domain.com
1024
+ if (
1025
+ `.${new URL(requested).hostname}`.endsWith(`.${request.url.hostname}`) &&
1026
+ opts.credentials !== 'omit'
1027
+ ) {
1028
+ uses_credentials = true;
1029
+ opts.headers.set('cookie', request.headers.cookie);
986
1030
  }
987
1031
 
988
- const external_request = new Request(url, /** @type {RequestInit} */ (opts));
1032
+ const external_request = new Request(requested, /** @type {RequestInit} */ (opts));
989
1033
  response = await options.hooks.externalFetch.call(null, external_request);
990
1034
  }
991
1035
 
@@ -1008,7 +1052,7 @@ async function load_node({
1008
1052
  if (!opts.body || typeof opts.body === 'string') {
1009
1053
  // prettier-ignore
1010
1054
  fetched.push({
1011
- url,
1055
+ url: requested,
1012
1056
  body: /** @type {string} */ (opts.body),
1013
1057
  json: `{"status":${response.status},"statusText":${s(response.statusText)},"headers":${s(headers)},"body":"${escape_json_string_in_html(body)}"}`
1014
1058
  });
@@ -1046,6 +1090,15 @@ async function load_node({
1046
1090
  stuff: { ...stuff }
1047
1091
  };
1048
1092
 
1093
+ if (options.dev) {
1094
+ // TODO remove this for 1.0
1095
+ Object.defineProperty(load_input, 'page', {
1096
+ get: () => {
1097
+ throw new Error('`page` in `load` functions has been replaced by `url` and `params`');
1098
+ }
1099
+ });
1100
+ }
1101
+
1049
1102
  if (is_error) {
1050
1103
  /** @type {import('types/page').ErrorLoadInput} */ (load_input).status = status;
1051
1104
  /** @type {import('types/page').ErrorLoadInput} */ (load_input).error = error;
@@ -1092,15 +1145,11 @@ async function load_node({
1092
1145
  * }} opts
1093
1146
  */
1094
1147
  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
- };
1148
+ const default_layout = await options.manifest._.nodes[0](); // 0 is always the root layout
1149
+ const default_error = await options.manifest._.nodes[1](); // 1 is always the root error
1150
+
1151
+ /** @type {Record<string, string>} */
1152
+ const params = {}; // error page has no params
1104
1153
 
1105
1154
  // error pages don't fall through, so we know it's not undefined
1106
1155
  const loaded = /** @type {Loaded} */ (
@@ -1109,7 +1158,8 @@ async function respond_with_error({ request, options, state, $session, status, e
1109
1158
  options,
1110
1159
  state,
1111
1160
  route: null,
1112
- page,
1161
+ url: request.url, // TODO this is redundant, no?
1162
+ params,
1113
1163
  node: default_layout,
1114
1164
  $session,
1115
1165
  stuff: {},
@@ -1127,7 +1177,8 @@ async function respond_with_error({ request, options, state, $session, status, e
1127
1177
  options,
1128
1178
  state,
1129
1179
  route: null,
1130
- page,
1180
+ url: request.url,
1181
+ params,
1131
1182
  node: default_error,
1132
1183
  $session,
1133
1184
  stuff: loaded ? loaded.stuff : {},
@@ -1152,7 +1203,8 @@ async function respond_with_error({ request, options, state, $session, status, e
1152
1203
  status,
1153
1204
  error,
1154
1205
  branch,
1155
- page
1206
+ url: request.url,
1207
+ params
1156
1208
  });
1157
1209
  } catch (err) {
1158
1210
  const error = coalesce_to_error(err);
@@ -1193,7 +1245,7 @@ function is_prerender_enabled(options, node, state) {
1193
1245
  * state: SSRRenderState;
1194
1246
  * $session: any;
1195
1247
  * route: import('types/internal').SSRPage;
1196
- * page: import('types/page').Page;
1248
+ * params: Record<string, string>;
1197
1249
  * }} opts
1198
1250
  * @returns {Promise<ServerResponse | undefined>}
1199
1251
  */
@@ -1204,7 +1256,9 @@ async function respond$1(opts) {
1204
1256
  let nodes;
1205
1257
 
1206
1258
  try {
1207
- nodes = await Promise.all(route.a.map((id) => (id ? options.load_component(id) : undefined)));
1259
+ nodes = await Promise.all(
1260
+ route.a.map((n) => options.manifest._.nodes[n] && options.manifest._.nodes[n]())
1261
+ );
1208
1262
  } catch (err) {
1209
1263
  const error = coalesce_to_error(err);
1210
1264
 
@@ -1259,6 +1313,7 @@ async function respond$1(opts) {
1259
1313
  try {
1260
1314
  loaded = await load_node({
1261
1315
  ...opts,
1316
+ url: request.url,
1262
1317
  node,
1263
1318
  stuff,
1264
1319
  prerender_enabled: is_prerender_enabled(options, node, state),
@@ -1301,7 +1356,7 @@ async function respond$1(opts) {
1301
1356
  if (error) {
1302
1357
  while (i--) {
1303
1358
  if (route.b[i]) {
1304
- const error_node = await options.load_component(route.b[i]);
1359
+ const error_node = await options.manifest._.nodes[route.b[i]]();
1305
1360
 
1306
1361
  /** @type {Loaded} */
1307
1362
  let node_loaded;
@@ -1315,6 +1370,7 @@ async function respond$1(opts) {
1315
1370
  const error_loaded = /** @type {import('./types').Loaded} */ (
1316
1371
  await load_node({
1317
1372
  ...opts,
1373
+ url: request.url,
1318
1374
  node: error_node,
1319
1375
  stuff: node_loaded.stuff,
1320
1376
  prerender_enabled: is_prerender_enabled(options, error_node, state),
@@ -1372,6 +1428,7 @@ async function respond$1(opts) {
1372
1428
  return with_cookies(
1373
1429
  await render_response({
1374
1430
  ...opts,
1431
+ url: request.url,
1375
1432
  page_config,
1376
1433
  status,
1377
1434
  error,
@@ -1432,18 +1489,11 @@ async function render_page(request, route, match, options, state) {
1432
1489
  return {
1433
1490
  status: 404,
1434
1491
  headers: {},
1435
- body: `Not found: ${request.path}`
1492
+ body: `Not found: ${request.url.pathname}`
1436
1493
  };
1437
1494
  }
1438
1495
 
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
- };
1496
+ const params = route.params ? decode_params(route.params(match)) : {};
1447
1497
 
1448
1498
  const $session = await options.hooks.getSession(request);
1449
1499
 
@@ -1453,7 +1503,7 @@ async function render_page(request, route, match, options, state) {
1453
1503
  state,
1454
1504
  $session,
1455
1505
  route,
1456
- page
1506
+ params
1457
1507
  });
1458
1508
 
1459
1509
  if (response) {
@@ -1658,22 +1708,25 @@ function get_multipart(text, boundary) {
1658
1708
 
1659
1709
  /** @type {import('@sveltejs/kit/ssr').Respond} */
1660
1710
  async function respond(incoming, options, state = {}) {
1661
- if (incoming.path !== '/' && options.trailing_slash !== 'ignore') {
1662
- const has_trailing_slash = incoming.path.endsWith('/');
1711
+ if (incoming.url.pathname !== '/' && options.trailing_slash !== 'ignore') {
1712
+ const has_trailing_slash = incoming.url.pathname.endsWith('/');
1663
1713
 
1664
1714
  if (
1665
1715
  (has_trailing_slash && options.trailing_slash === 'never') ||
1666
1716
  (!has_trailing_slash &&
1667
1717
  options.trailing_slash === 'always' &&
1668
- !(incoming.path.split('/').pop() || '').includes('.'))
1718
+ !(incoming.url.pathname.split('/').pop() || '').includes('.'))
1669
1719
  ) {
1670
- const path = has_trailing_slash ? incoming.path.slice(0, -1) : incoming.path + '/';
1671
- const q = incoming.query.toString();
1720
+ incoming.url.pathname = has_trailing_slash
1721
+ ? incoming.url.pathname.slice(0, -1)
1722
+ : incoming.url.pathname + '/';
1723
+
1724
+ if (incoming.url.search === '?') incoming.url.search = '';
1672
1725
 
1673
1726
  return {
1674
1727
  status: 301,
1675
1728
  headers: {
1676
- location: options.paths.base + path + (q ? `?${q}` : '')
1729
+ location: incoming.url.pathname + incoming.url.search
1677
1730
  }
1678
1731
  };
1679
1732
  }
@@ -1688,12 +1741,33 @@ async function respond(incoming, options, state = {}) {
1688
1741
  locals: {}
1689
1742
  };
1690
1743
 
1744
+ if (options.dev) {
1745
+ // TODO remove this for 1.0
1746
+ /**
1747
+ * @param {string} property
1748
+ * @param {string} replacement
1749
+ */
1750
+ const print_error = (property, replacement) => {
1751
+ Object.defineProperty(request, property, {
1752
+ get: () => {
1753
+ throw new Error(`request.${property} has been replaced by request.url.${replacement}`);
1754
+ }
1755
+ });
1756
+ };
1757
+
1758
+ print_error('origin', 'origin');
1759
+ print_error('path', 'pathname');
1760
+ print_error('query', 'searchParams');
1761
+ }
1762
+
1691
1763
  try {
1692
1764
  return await options.hooks.handle({
1693
1765
  request,
1694
1766
  resolve: async (request) => {
1695
1767
  if (state.prerender && state.prerender.fallback) {
1696
1768
  return await render_response({
1769
+ url: request.url,
1770
+ params: request.params,
1697
1771
  options,
1698
1772
  $session: await options.hooks.getSession(request),
1699
1773
  page_config: { ssr: false, router: true, hydrate: true },
@@ -1702,8 +1776,9 @@ async function respond(incoming, options, state = {}) {
1702
1776
  });
1703
1777
  }
1704
1778
 
1705
- const decoded = decodeURI(request.path);
1706
- for (const route of options.manifest.routes) {
1779
+ const decoded = decodeURI(request.url.pathname).replace(options.paths.base, '');
1780
+
1781
+ for (const route of options.manifest._.routes) {
1707
1782
  const match = route.pattern.exec(decoded);
1708
1783
  if (!match) continue;
1709
1784
 
@@ -1740,15 +1815,19 @@ async function respond(incoming, options, state = {}) {
1740
1815
  }
1741
1816
  }
1742
1817
 
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
- });
1818
+ // if this request came direct from the user, rather than
1819
+ // via a `fetch` in a `load`, render a 404 page
1820
+ if (!state.initiator) {
1821
+ const $session = await options.hooks.getSession(request);
1822
+ return await respond_with_error({
1823
+ request,
1824
+ options,
1825
+ state,
1826
+ $session,
1827
+ status: 404,
1828
+ error: new Error(`Not found: ${request.url.pathname}`)
1829
+ });
1830
+ }
1752
1831
  }
1753
1832
  });
1754
1833
  } 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.208",
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
  }