@sveltejs/kit 1.0.0-next.203 → 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/assets/runtime/internal/start.js +114 -119
- package/dist/chunks/index.js +100 -114
- package/dist/chunks/index2.js +29 -15
- package/dist/chunks/index3.js +403 -821
- package/dist/chunks/index4.js +89 -378
- package/dist/chunks/index5.js +524 -723
- package/dist/chunks/index6.js +737 -15485
- package/dist/chunks/index7.js +15575 -0
- package/dist/chunks/misc.js +3 -0
- package/dist/cli.js +91 -26
- package/dist/ssr.js +210 -135
- package/package.json +2 -3
- package/types/ambient-modules.d.ts +15 -7
- package/types/app.d.ts +29 -5
- package/types/config.d.ts +79 -12
- package/types/hooks.d.ts +16 -4
- package/types/index.d.ts +3 -3
- package/types/internal.d.ts +40 -28
- package/types/page.d.ts +2 -8
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
|
-
|
|
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(
|
|
66
|
-
const preface = `Invalid response from route ${request.
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
579
|
-
|
|
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
|
|
644
|
+
import { start } from ${s(options.prefix + options.manifest._.entry.file)};
|
|
597
645
|
start({
|
|
598
|
-
target: ${options.target ? `document.querySelector(${s
|
|
599
|
-
paths: ${s
|
|
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
|
|
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
|
|
659
|
+
.map(({ node }) => `import(${s(options.prefix + node.entry)})`)
|
|
613
660
|
.join(',\n\t\t\t\t\t\t')}
|
|
614
661
|
],
|
|
615
|
-
|
|
616
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
|
873
|
+
const url_proxy = new Proxy(url, {
|
|
835
874
|
get: (target, prop, receiver) => {
|
|
836
|
-
if (prop === '
|
|
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
|
-
|
|
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
|
|
897
|
+
let requested;
|
|
858
898
|
|
|
859
899
|
if (typeof resource === 'string') {
|
|
860
|
-
|
|
900
|
+
requested = resource;
|
|
861
901
|
} else {
|
|
862
|
-
|
|
902
|
+
requested = resource.url;
|
|
863
903
|
|
|
864
904
|
opts = {
|
|
865
905
|
method: resource.method,
|
|
@@ -875,7 +915,9 @@ async function load_node({
|
|
|
875
915
|
};
|
|
876
916
|
}
|
|
877
917
|
|
|
878
|
-
|
|
918
|
+
opts.headers = new Headers(opts.headers);
|
|
919
|
+
|
|
920
|
+
const resolved = resolve(request.url.pathname, requested.split('?')[0]);
|
|
879
921
|
|
|
880
922
|
let response;
|
|
881
923
|
|
|
@@ -886,35 +928,37 @@ async function load_node({
|
|
|
886
928
|
resolved.startsWith(prefix) ? resolved.slice(prefix.length) : resolved
|
|
887
929
|
).slice(1);
|
|
888
930
|
const filename_html = `${filename}/index.html`; // path may also match path/index.html
|
|
889
|
-
const asset = options.manifest.assets.find(
|
|
890
|
-
(d) => d.file === filename || d.file === filename_html
|
|
891
|
-
);
|
|
892
931
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
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
|
+
}
|
|
903
949
|
} else if (is_root_relative(resolved)) {
|
|
904
950
|
const relative = resolved;
|
|
905
951
|
|
|
906
|
-
const headers = /** @type {import('types/helper').RequestHeaders} */ ({
|
|
907
|
-
...opts.headers
|
|
908
|
-
});
|
|
909
|
-
|
|
910
952
|
// TODO: fix type https://github.com/node-fetch/node-fetch/issues/1113
|
|
911
953
|
if (opts.credentials !== 'omit') {
|
|
912
954
|
uses_credentials = true;
|
|
913
955
|
|
|
914
|
-
|
|
956
|
+
if (request.headers.cookie) {
|
|
957
|
+
opts.headers.set('cookie', request.headers.cookie);
|
|
958
|
+
}
|
|
915
959
|
|
|
916
|
-
if (!headers.authorization) {
|
|
917
|
-
headers.authorization
|
|
960
|
+
if (request.headers.authorization && !opts.headers.has('authorization')) {
|
|
961
|
+
opts.headers.set('authorization', request.headers.authorization);
|
|
918
962
|
}
|
|
919
963
|
}
|
|
920
964
|
|
|
@@ -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
|
-
|
|
975
|
+
url: new URL(requested, request.url),
|
|
934
976
|
method: opts.method || 'GET',
|
|
935
|
-
headers,
|
|
936
|
-
|
|
937
|
-
rawBody: opts.body == null ? null : new TextEncoder().encode(opts.body),
|
|
938
|
-
query: new URLSearchParams(search)
|
|
977
|
+
headers: Object.fromEntries(opts.headers),
|
|
978
|
+
rawBody: opts.body == null ? null : new TextEncoder().encode(opts.body)
|
|
939
979
|
},
|
|
940
980
|
options,
|
|
941
981
|
{
|
|
942
|
-
fetched:
|
|
982
|
+
fetched: requested,
|
|
943
983
|
initiator: route
|
|
944
984
|
}
|
|
945
985
|
);
|
|
@@ -956,40 +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(
|
|
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
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
opts.credentials !== 'omit'
|
|
982
|
-
) {
|
|
983
|
-
uses_credentials = true;
|
|
984
|
-
|
|
985
|
-
opts.headers = {
|
|
986
|
-
...opts.headers,
|
|
987
|
-
cookie: request.headers.cookie
|
|
988
|
-
};
|
|
989
|
-
}
|
|
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);
|
|
990
1030
|
}
|
|
991
1031
|
|
|
992
|
-
const external_request = new Request(
|
|
1032
|
+
const external_request = new Request(requested, /** @type {RequestInit} */ (opts));
|
|
993
1033
|
response = await options.hooks.externalFetch.call(null, external_request);
|
|
994
1034
|
}
|
|
995
1035
|
|
|
@@ -1012,7 +1052,7 @@ async function load_node({
|
|
|
1012
1052
|
if (!opts.body || typeof opts.body === 'string') {
|
|
1013
1053
|
// prettier-ignore
|
|
1014
1054
|
fetched.push({
|
|
1015
|
-
url,
|
|
1055
|
+
url: requested,
|
|
1016
1056
|
body: /** @type {string} */ (opts.body),
|
|
1017
1057
|
json: `{"status":${response.status},"statusText":${s(response.statusText)},"headers":${s(headers)},"body":"${escape_json_string_in_html(body)}"}`
|
|
1018
1058
|
});
|
|
@@ -1050,6 +1090,15 @@ async function load_node({
|
|
|
1050
1090
|
stuff: { ...stuff }
|
|
1051
1091
|
};
|
|
1052
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
|
+
|
|
1053
1102
|
if (is_error) {
|
|
1054
1103
|
/** @type {import('types/page').ErrorLoadInput} */ (load_input).status = status;
|
|
1055
1104
|
/** @type {import('types/page').ErrorLoadInput} */ (load_input).error = error;
|
|
@@ -1096,15 +1145,11 @@ async function load_node({
|
|
|
1096
1145
|
* }} opts
|
|
1097
1146
|
*/
|
|
1098
1147
|
async function respond_with_error({ request, options, state, $session, status, error }) {
|
|
1099
|
-
const default_layout = await options.
|
|
1100
|
-
const default_error = await options.
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
path: request.path,
|
|
1105
|
-
query: request.query,
|
|
1106
|
-
params: {}
|
|
1107
|
-
};
|
|
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
|
|
1108
1153
|
|
|
1109
1154
|
// error pages don't fall through, so we know it's not undefined
|
|
1110
1155
|
const loaded = /** @type {Loaded} */ (
|
|
@@ -1113,7 +1158,8 @@ async function respond_with_error({ request, options, state, $session, status, e
|
|
|
1113
1158
|
options,
|
|
1114
1159
|
state,
|
|
1115
1160
|
route: null,
|
|
1116
|
-
|
|
1161
|
+
url: request.url, // TODO this is redundant, no?
|
|
1162
|
+
params,
|
|
1117
1163
|
node: default_layout,
|
|
1118
1164
|
$session,
|
|
1119
1165
|
stuff: {},
|
|
@@ -1131,7 +1177,8 @@ async function respond_with_error({ request, options, state, $session, status, e
|
|
|
1131
1177
|
options,
|
|
1132
1178
|
state,
|
|
1133
1179
|
route: null,
|
|
1134
|
-
|
|
1180
|
+
url: request.url,
|
|
1181
|
+
params,
|
|
1135
1182
|
node: default_error,
|
|
1136
1183
|
$session,
|
|
1137
1184
|
stuff: loaded ? loaded.stuff : {},
|
|
@@ -1156,7 +1203,8 @@ async function respond_with_error({ request, options, state, $session, status, e
|
|
|
1156
1203
|
status,
|
|
1157
1204
|
error,
|
|
1158
1205
|
branch,
|
|
1159
|
-
|
|
1206
|
+
url: request.url,
|
|
1207
|
+
params
|
|
1160
1208
|
});
|
|
1161
1209
|
} catch (err) {
|
|
1162
1210
|
const error = coalesce_to_error(err);
|
|
@@ -1197,7 +1245,7 @@ function is_prerender_enabled(options, node, state) {
|
|
|
1197
1245
|
* state: SSRRenderState;
|
|
1198
1246
|
* $session: any;
|
|
1199
1247
|
* route: import('types/internal').SSRPage;
|
|
1200
|
-
*
|
|
1248
|
+
* params: Record<string, string>;
|
|
1201
1249
|
* }} opts
|
|
1202
1250
|
* @returns {Promise<ServerResponse | undefined>}
|
|
1203
1251
|
*/
|
|
@@ -1208,7 +1256,9 @@ async function respond$1(opts) {
|
|
|
1208
1256
|
let nodes;
|
|
1209
1257
|
|
|
1210
1258
|
try {
|
|
1211
|
-
nodes = await Promise.all(
|
|
1259
|
+
nodes = await Promise.all(
|
|
1260
|
+
route.a.map((n) => options.manifest._.nodes[n] && options.manifest._.nodes[n]())
|
|
1261
|
+
);
|
|
1212
1262
|
} catch (err) {
|
|
1213
1263
|
const error = coalesce_to_error(err);
|
|
1214
1264
|
|
|
@@ -1263,6 +1313,7 @@ async function respond$1(opts) {
|
|
|
1263
1313
|
try {
|
|
1264
1314
|
loaded = await load_node({
|
|
1265
1315
|
...opts,
|
|
1316
|
+
url: request.url,
|
|
1266
1317
|
node,
|
|
1267
1318
|
stuff,
|
|
1268
1319
|
prerender_enabled: is_prerender_enabled(options, node, state),
|
|
@@ -1305,7 +1356,7 @@ async function respond$1(opts) {
|
|
|
1305
1356
|
if (error) {
|
|
1306
1357
|
while (i--) {
|
|
1307
1358
|
if (route.b[i]) {
|
|
1308
|
-
const error_node = await options.
|
|
1359
|
+
const error_node = await options.manifest._.nodes[route.b[i]]();
|
|
1309
1360
|
|
|
1310
1361
|
/** @type {Loaded} */
|
|
1311
1362
|
let node_loaded;
|
|
@@ -1319,6 +1370,7 @@ async function respond$1(opts) {
|
|
|
1319
1370
|
const error_loaded = /** @type {import('./types').Loaded} */ (
|
|
1320
1371
|
await load_node({
|
|
1321
1372
|
...opts,
|
|
1373
|
+
url: request.url,
|
|
1322
1374
|
node: error_node,
|
|
1323
1375
|
stuff: node_loaded.stuff,
|
|
1324
1376
|
prerender_enabled: is_prerender_enabled(options, error_node, state),
|
|
@@ -1376,6 +1428,7 @@ async function respond$1(opts) {
|
|
|
1376
1428
|
return with_cookies(
|
|
1377
1429
|
await render_response({
|
|
1378
1430
|
...opts,
|
|
1431
|
+
url: request.url,
|
|
1379
1432
|
page_config,
|
|
1380
1433
|
status,
|
|
1381
1434
|
error,
|
|
@@ -1436,18 +1489,11 @@ async function render_page(request, route, match, options, state) {
|
|
|
1436
1489
|
return {
|
|
1437
1490
|
status: 404,
|
|
1438
1491
|
headers: {},
|
|
1439
|
-
body: `Not found: ${request.
|
|
1492
|
+
body: `Not found: ${request.url.pathname}`
|
|
1440
1493
|
};
|
|
1441
1494
|
}
|
|
1442
1495
|
|
|
1443
|
-
const params = route.params(match);
|
|
1444
|
-
|
|
1445
|
-
const page = {
|
|
1446
|
-
host: request.host,
|
|
1447
|
-
path: request.path,
|
|
1448
|
-
query: request.query,
|
|
1449
|
-
params
|
|
1450
|
-
};
|
|
1496
|
+
const params = route.params ? decode_params(route.params(match)) : {};
|
|
1451
1497
|
|
|
1452
1498
|
const $session = await options.hooks.getSession(request);
|
|
1453
1499
|
|
|
@@ -1457,7 +1503,7 @@ async function render_page(request, route, match, options, state) {
|
|
|
1457
1503
|
state,
|
|
1458
1504
|
$session,
|
|
1459
1505
|
route,
|
|
1460
|
-
|
|
1506
|
+
params
|
|
1461
1507
|
});
|
|
1462
1508
|
|
|
1463
1509
|
if (response) {
|
|
@@ -1662,22 +1708,25 @@ function get_multipart(text, boundary) {
|
|
|
1662
1708
|
|
|
1663
1709
|
/** @type {import('@sveltejs/kit/ssr').Respond} */
|
|
1664
1710
|
async function respond(incoming, options, state = {}) {
|
|
1665
|
-
if (incoming.
|
|
1666
|
-
const has_trailing_slash = incoming.
|
|
1711
|
+
if (incoming.url.pathname !== '/' && options.trailing_slash !== 'ignore') {
|
|
1712
|
+
const has_trailing_slash = incoming.url.pathname.endsWith('/');
|
|
1667
1713
|
|
|
1668
1714
|
if (
|
|
1669
1715
|
(has_trailing_slash && options.trailing_slash === 'never') ||
|
|
1670
1716
|
(!has_trailing_slash &&
|
|
1671
1717
|
options.trailing_slash === 'always' &&
|
|
1672
|
-
!(incoming.
|
|
1718
|
+
!(incoming.url.pathname.split('/').pop() || '').includes('.'))
|
|
1673
1719
|
) {
|
|
1674
|
-
|
|
1675
|
-
|
|
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 = '';
|
|
1676
1725
|
|
|
1677
1726
|
return {
|
|
1678
1727
|
status: 301,
|
|
1679
1728
|
headers: {
|
|
1680
|
-
location:
|
|
1729
|
+
location: incoming.url.pathname + incoming.url.search
|
|
1681
1730
|
}
|
|
1682
1731
|
};
|
|
1683
1732
|
}
|
|
@@ -1692,12 +1741,33 @@ async function respond(incoming, options, state = {}) {
|
|
|
1692
1741
|
locals: {}
|
|
1693
1742
|
};
|
|
1694
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
|
+
|
|
1695
1763
|
try {
|
|
1696
1764
|
return await options.hooks.handle({
|
|
1697
1765
|
request,
|
|
1698
1766
|
resolve: async (request) => {
|
|
1699
1767
|
if (state.prerender && state.prerender.fallback) {
|
|
1700
1768
|
return await render_response({
|
|
1769
|
+
url: request.url,
|
|
1770
|
+
params: request.params,
|
|
1701
1771
|
options,
|
|
1702
1772
|
$session: await options.hooks.getSession(request),
|
|
1703
1773
|
page_config: { ssr: false, router: true, hydrate: true },
|
|
@@ -1706,8 +1776,9 @@ async function respond(incoming, options, state = {}) {
|
|
|
1706
1776
|
});
|
|
1707
1777
|
}
|
|
1708
1778
|
|
|
1709
|
-
const decoded = decodeURI(request.
|
|
1710
|
-
|
|
1779
|
+
const decoded = decodeURI(request.url.pathname).replace(options.paths.base, '');
|
|
1780
|
+
|
|
1781
|
+
for (const route of options.manifest._.routes) {
|
|
1711
1782
|
const match = route.pattern.exec(decoded);
|
|
1712
1783
|
if (!match) continue;
|
|
1713
1784
|
|
|
@@ -1744,15 +1815,19 @@ async function respond(incoming, options, state = {}) {
|
|
|
1744
1815
|
}
|
|
1745
1816
|
}
|
|
1746
1817
|
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
options
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
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
|
+
}
|
|
1756
1831
|
}
|
|
1757
1832
|
});
|
|
1758
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.
|
|
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
|
}
|