@sveltejs/kit 2.18.0 → 2.19.0
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/package.json +1 -1
- package/src/core/postbuild/analyse.js +6 -20
- package/src/exports/index.js +1 -0
- package/src/exports/public.d.ts +1 -1
- package/src/runtime/client/client.js +69 -28
- package/src/runtime/server/cookie.js +23 -4
- package/src/runtime/server/page/actions.js +1 -1
- package/src/runtime/server/page/index.js +16 -22
- package/src/runtime/server/page/render.js +9 -6
- package/src/runtime/server/page/respond_with_error.js +4 -3
- package/src/runtime/server/respond.js +125 -134
- package/src/types/internal.d.ts +34 -24
- package/src/utils/page_nodes.js +95 -0
- package/src/version.js +1 -1
- package/types/index.d.ts +33 -26
- package/types/index.d.ts.map +3 -1
- package/src/runtime/server/page/load_page_nodes.js +0 -11
- package/src/utils/options.js +0 -16
- package/src/utils/route_config.js +0 -21
package/package.json
CHANGED
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { pathToFileURL } from 'node:url';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
validate_layout_exports,
|
|
6
|
-
validate_layout_server_exports,
|
|
7
|
-
validate_page_exports,
|
|
8
|
-
validate_page_server_exports,
|
|
9
|
-
validate_server_exports
|
|
10
|
-
} from '../../utils/exports.js';
|
|
3
|
+
import { validate_server_exports } from '../../utils/exports.js';
|
|
11
4
|
import { load_config } from '../config/index.js';
|
|
12
5
|
import { forked } from '../../utils/fork.js';
|
|
13
6
|
import { installPolyfills } from '../../exports/node/polyfills.js';
|
|
14
7
|
import { ENDPOINT_METHODS } from '../../constants.js';
|
|
15
8
|
import { filter_private_env, filter_public_env } from '../../utils/env.js';
|
|
16
9
|
import { has_server_load, resolve_route } from '../../utils/routing.js';
|
|
17
|
-
import { get_page_config } from '../../utils/route_config.js';
|
|
18
10
|
import { check_feature } from '../../utils/features.js';
|
|
19
11
|
import { createReadableStream } from '@sveltejs/kit/node';
|
|
12
|
+
import { PageNodes } from '../../utils/page_nodes.js';
|
|
20
13
|
|
|
21
14
|
export default forked(import.meta.url, analyse);
|
|
22
15
|
|
|
@@ -190,25 +183,18 @@ function analyse_endpoint(route, mod) {
|
|
|
190
183
|
* @param {import('types').SSRNode} leaf
|
|
191
184
|
*/
|
|
192
185
|
function analyse_page(layouts, leaf) {
|
|
193
|
-
for (const layout of layouts) {
|
|
194
|
-
if (layout) {
|
|
195
|
-
validate_layout_server_exports(layout.server, layout.server_id);
|
|
196
|
-
validate_layout_exports(layout.universal, layout.universal_id);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
186
|
/** @type {Array<'GET' | 'POST'>} */
|
|
201
187
|
const methods = ['GET'];
|
|
202
188
|
if (leaf.server?.actions) methods.push('POST');
|
|
203
189
|
|
|
204
|
-
|
|
205
|
-
|
|
190
|
+
const nodes = new PageNodes([...layouts, leaf]);
|
|
191
|
+
nodes.validate();
|
|
206
192
|
|
|
207
193
|
return {
|
|
208
|
-
config:
|
|
194
|
+
config: nodes.get_config(),
|
|
209
195
|
entries: leaf.universal?.entries ?? leaf.server?.entries,
|
|
210
196
|
methods,
|
|
211
|
-
prerender:
|
|
197
|
+
prerender: nodes.prerender()
|
|
212
198
|
};
|
|
213
199
|
}
|
|
214
200
|
|
package/src/exports/index.js
CHANGED
|
@@ -229,6 +229,7 @@ export function isActionFailure(e) {
|
|
|
229
229
|
* ```
|
|
230
230
|
* @param {URL | string} url
|
|
231
231
|
* @returns {{ url: URL, wasNormalized: boolean, denormalize: (url?: string | URL) => URL }}
|
|
232
|
+
* @since 2.18.0
|
|
232
233
|
*/
|
|
233
234
|
export function normalizeUrl(url) {
|
|
234
235
|
url = new URL(url, 'http://internal');
|
package/src/exports/public.d.ts
CHANGED
|
@@ -814,7 +814,7 @@ export type ClientInit = () => MaybePromise<void>;
|
|
|
814
814
|
* The [`reroute`](https://svelte.dev/docs/kit/hooks#Universal-hooks-reroute) hook allows you to modify the URL before it is used to determine which route to render.
|
|
815
815
|
* @since 2.3.0
|
|
816
816
|
*/
|
|
817
|
-
export type Reroute = (event: { url: URL }) => MaybePromise<void | string>;
|
|
817
|
+
export type Reroute = (event: { url: URL; fetch: typeof fetch }) => MaybePromise<void | string>;
|
|
818
818
|
|
|
819
819
|
/**
|
|
820
820
|
* The [`transport`](https://svelte.dev/docs/kit/hooks#Universal-hooks-transport) hook allows you to transport custom types across the server/client boundary.
|
|
@@ -188,6 +188,17 @@ const components = [];
|
|
|
188
188
|
/** @type {{id: string, token: {}, promise: Promise<import('./types.js').NavigationResult>} | null} */
|
|
189
189
|
let load_cache = null;
|
|
190
190
|
|
|
191
|
+
/**
|
|
192
|
+
* @type {Map<string, Promise<URL>>}
|
|
193
|
+
* Cache for client-side rerouting, since it could contain async calls which we want to
|
|
194
|
+
* avoid running multiple times which would slow down navigations (e.g. else preloading
|
|
195
|
+
* wouldn't help because on navigation it would be called again). Since `reroute` should be
|
|
196
|
+
* a pure function (i.e. always return the same) value it's safe to cache across navigations.
|
|
197
|
+
* The server reroute calls don't need to be cached because they are called using `import(...)`
|
|
198
|
+
* which is cached per the JS spec.
|
|
199
|
+
*/
|
|
200
|
+
const reroute_cache = new Map();
|
|
201
|
+
|
|
191
202
|
/**
|
|
192
203
|
* Note on before_navigate_callbacks, on_navigate_callbacks and after_navigate_callbacks:
|
|
193
204
|
* do not re-assign as some closures keep references to these Sets
|
|
@@ -679,12 +690,7 @@ async function load_node({ loader, parent, url, params, route, server_data_node
|
|
|
679
690
|
app.hash
|
|
680
691
|
),
|
|
681
692
|
async fetch(resource, init) {
|
|
682
|
-
/** @type {URL | string} */
|
|
683
|
-
let requested;
|
|
684
|
-
|
|
685
693
|
if (resource instanceof Request) {
|
|
686
|
-
requested = resource.url;
|
|
687
|
-
|
|
688
694
|
// we're not allowed to modify the received `Request` object, so in order
|
|
689
695
|
// to fixup relative urls we create a new equivalent `init` object instead
|
|
690
696
|
init = {
|
|
@@ -709,25 +715,15 @@ async function load_node({ loader, parent, url, params, route, server_data_node
|
|
|
709
715
|
signal: resource.signal,
|
|
710
716
|
...init
|
|
711
717
|
};
|
|
712
|
-
} else {
|
|
713
|
-
requested = resource;
|
|
714
718
|
}
|
|
715
719
|
|
|
716
|
-
|
|
717
|
-
|
|
720
|
+
const { resolved, promise } = resolve_fetch_url(resource, init, url);
|
|
721
|
+
|
|
718
722
|
if (is_tracking) {
|
|
719
723
|
depends(resolved.href);
|
|
720
724
|
}
|
|
721
725
|
|
|
722
|
-
|
|
723
|
-
if (resolved.origin === url.origin) {
|
|
724
|
-
requested = resolved.href.slice(url.origin.length);
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
// prerendered pages may be served from any origin, so `initial_fetch` urls shouldn't be resolved
|
|
728
|
-
return started
|
|
729
|
-
? subsequent_fetch(requested, resolved.href, init)
|
|
730
|
-
: initial_fetch(requested, init);
|
|
726
|
+
return promise;
|
|
731
727
|
},
|
|
732
728
|
setHeaders: () => {}, // noop
|
|
733
729
|
depends,
|
|
@@ -782,6 +778,30 @@ async function load_node({ loader, parent, url, params, route, server_data_node
|
|
|
782
778
|
};
|
|
783
779
|
}
|
|
784
780
|
|
|
781
|
+
/**
|
|
782
|
+
* @param {Request | string | URL} input
|
|
783
|
+
* @param {RequestInit | undefined} init
|
|
784
|
+
* @param {URL} url
|
|
785
|
+
*/
|
|
786
|
+
function resolve_fetch_url(input, init, url) {
|
|
787
|
+
let requested = input instanceof Request ? input.url : input;
|
|
788
|
+
|
|
789
|
+
// we must fixup relative urls so they are resolved from the target page
|
|
790
|
+
const resolved = new URL(requested, url);
|
|
791
|
+
|
|
792
|
+
// match ssr serialized data url, which is important to find cached responses
|
|
793
|
+
if (resolved.origin === url.origin) {
|
|
794
|
+
requested = resolved.href.slice(url.origin.length);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// prerendered pages may be served from any origin, so `initial_fetch` urls shouldn't be resolved
|
|
798
|
+
const promise = started
|
|
799
|
+
? subsequent_fetch(requested, resolved.href, init)
|
|
800
|
+
: initial_fetch(requested, init);
|
|
801
|
+
|
|
802
|
+
return { resolved, promise };
|
|
803
|
+
}
|
|
804
|
+
|
|
785
805
|
/**
|
|
786
806
|
* @param {boolean} parent_changed
|
|
787
807
|
* @param {boolean} route_changed
|
|
@@ -1201,23 +1221,44 @@ async function load_root_error_page({ status, error, url, route }) {
|
|
|
1201
1221
|
* @returns {Promise<URL | undefined>}
|
|
1202
1222
|
*/
|
|
1203
1223
|
async function get_rerouted_url(url) {
|
|
1224
|
+
const href = url.href;
|
|
1225
|
+
|
|
1226
|
+
if (reroute_cache.has(href)) {
|
|
1227
|
+
return reroute_cache.get(href);
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1204
1230
|
let rerouted;
|
|
1231
|
+
|
|
1205
1232
|
try {
|
|
1206
|
-
|
|
1207
|
-
|
|
1233
|
+
const promise = (async () => {
|
|
1234
|
+
// reroute could alter the given URL, so we pass a copy
|
|
1235
|
+
let rerouted =
|
|
1236
|
+
(await app.hooks.reroute({
|
|
1237
|
+
url: new URL(url),
|
|
1238
|
+
fetch: async (input, init) => {
|
|
1239
|
+
return resolve_fetch_url(input, init, url).promise;
|
|
1240
|
+
}
|
|
1241
|
+
})) ?? url;
|
|
1208
1242
|
|
|
1209
|
-
|
|
1210
|
-
|
|
1243
|
+
if (typeof rerouted === 'string') {
|
|
1244
|
+
const tmp = new URL(url); // do not mutate the incoming URL
|
|
1211
1245
|
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1246
|
+
if (app.hash) {
|
|
1247
|
+
tmp.hash = rerouted;
|
|
1248
|
+
} else {
|
|
1249
|
+
tmp.pathname = rerouted;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
rerouted = tmp;
|
|
1216
1253
|
}
|
|
1217
1254
|
|
|
1218
|
-
rerouted
|
|
1219
|
-
}
|
|
1255
|
+
return rerouted;
|
|
1256
|
+
})();
|
|
1257
|
+
|
|
1258
|
+
reroute_cache.set(href, promise);
|
|
1259
|
+
rerouted = await promise;
|
|
1220
1260
|
} catch (e) {
|
|
1261
|
+
reroute_cache.delete(href);
|
|
1221
1262
|
if (DEV) {
|
|
1222
1263
|
// in development, print the error...
|
|
1223
1264
|
console.error(e);
|
|
@@ -29,13 +29,13 @@ function validate_options(options) {
|
|
|
29
29
|
/**
|
|
30
30
|
* @param {Request} request
|
|
31
31
|
* @param {URL} url
|
|
32
|
-
* @param {import('types').TrailingSlash} trailing_slash
|
|
33
32
|
*/
|
|
34
|
-
export function get_cookies(request, url
|
|
33
|
+
export function get_cookies(request, url) {
|
|
35
34
|
const header = request.headers.get('cookie') ?? '';
|
|
36
35
|
const initial_cookies = parse(header, { decode: (value) => value });
|
|
37
36
|
|
|
38
|
-
|
|
37
|
+
/** @type {string | undefined} */
|
|
38
|
+
let normalized_url;
|
|
39
39
|
|
|
40
40
|
/** @type {Record<string, import('./page/types.js').Cookie>} */
|
|
41
41
|
const new_cookies = {};
|
|
@@ -149,6 +149,9 @@ export function get_cookies(request, url, trailing_slash) {
|
|
|
149
149
|
let path = options.path;
|
|
150
150
|
|
|
151
151
|
if (!options.domain || options.domain === url.hostname) {
|
|
152
|
+
if (!normalized_url) {
|
|
153
|
+
throw new Error('Cannot serialize cookies until after the route is determined');
|
|
154
|
+
}
|
|
152
155
|
path = resolve(normalized_url, path);
|
|
153
156
|
}
|
|
154
157
|
|
|
@@ -190,12 +193,20 @@ export function get_cookies(request, url, trailing_slash) {
|
|
|
190
193
|
.join('; ');
|
|
191
194
|
}
|
|
192
195
|
|
|
196
|
+
/** @type {Array<() => void>} */
|
|
197
|
+
const internal_queue = [];
|
|
198
|
+
|
|
193
199
|
/**
|
|
194
200
|
* @param {string} name
|
|
195
201
|
* @param {string} value
|
|
196
202
|
* @param {import('./page/types.js').Cookie['options']} options
|
|
197
203
|
*/
|
|
198
204
|
function set_internal(name, value, options) {
|
|
205
|
+
if (!normalized_url) {
|
|
206
|
+
internal_queue.push(() => set_internal(name, value, options));
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
199
210
|
let path = options.path;
|
|
200
211
|
|
|
201
212
|
if (!options.domain || options.domain === url.hostname) {
|
|
@@ -220,7 +231,15 @@ export function get_cookies(request, url, trailing_slash) {
|
|
|
220
231
|
}
|
|
221
232
|
}
|
|
222
233
|
|
|
223
|
-
|
|
234
|
+
/**
|
|
235
|
+
* @param {import('types').TrailingSlash} trailing_slash
|
|
236
|
+
*/
|
|
237
|
+
function set_trailing_slash(trailing_slash) {
|
|
238
|
+
normalized_url = normalize_path(url.pathname, trailing_slash);
|
|
239
|
+
internal_queue.forEach((fn) => fn());
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return { cookies, new_cookies, get_cookie_header, set_internal, set_trailing_slash };
|
|
224
243
|
}
|
|
225
244
|
|
|
226
245
|
/**
|
|
@@ -214,7 +214,7 @@ function check_named_default_separate(actions) {
|
|
|
214
214
|
|
|
215
215
|
/**
|
|
216
216
|
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
217
|
-
* @param {NonNullable<import('types').
|
|
217
|
+
* @param {NonNullable<import('types').ServerNode['actions']>} actions
|
|
218
218
|
* @throws {Redirect | HttpError | SvelteKitError | Error}
|
|
219
219
|
*/
|
|
220
220
|
async function call_action(event, actions) {
|
|
@@ -13,9 +13,7 @@ import {
|
|
|
13
13
|
import { load_data, load_server_data } from './load_data.js';
|
|
14
14
|
import { render_response } from './render.js';
|
|
15
15
|
import { respond_with_error } from './respond_with_error.js';
|
|
16
|
-
import { get_option } from '../../../utils/options.js';
|
|
17
16
|
import { get_data_json } from '../data/index.js';
|
|
18
|
-
import { load_page_nodes } from './load_page_nodes.js';
|
|
19
17
|
import { DEV } from 'esm-env';
|
|
20
18
|
|
|
21
19
|
/**
|
|
@@ -29,10 +27,11 @@ const MAX_DEPTH = 10;
|
|
|
29
27
|
* @param {import('types').SSROptions} options
|
|
30
28
|
* @param {import('@sveltejs/kit').SSRManifest} manifest
|
|
31
29
|
* @param {import('types').SSRState} state
|
|
30
|
+
* @param {import('../../../utils/page_nodes.js').PageNodes} nodes
|
|
32
31
|
* @param {import('types').RequiredResolveOptions} resolve_opts
|
|
33
32
|
* @returns {Promise<Response>}
|
|
34
33
|
*/
|
|
35
|
-
export async function render_page(event, page, options, manifest, state, resolve_opts) {
|
|
34
|
+
export async function render_page(event, page, options, manifest, state, nodes, resolve_opts) {
|
|
36
35
|
if (state.depth > MAX_DEPTH) {
|
|
37
36
|
// infinite request cycle detected
|
|
38
37
|
return text(`Not found: ${event.url.pathname}`, {
|
|
@@ -46,9 +45,7 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
try {
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const leaf_node = /** @type {import('types').SSRNode} */ (nodes.at(-1));
|
|
48
|
+
const leaf_node = /** @type {import('types').SSRNode} */ (nodes.page());
|
|
52
49
|
|
|
53
50
|
let status = 200;
|
|
54
51
|
|
|
@@ -70,16 +67,10 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
70
67
|
}
|
|
71
68
|
}
|
|
72
69
|
|
|
73
|
-
const should_prerender_data = nodes.some(
|
|
74
|
-
// prerender in case of trailingSlash because the client retrieves that value from the server
|
|
75
|
-
(node) => node?.server?.load || node?.server?.trailingSlash !== undefined
|
|
76
|
-
);
|
|
77
|
-
const data_pathname = add_data_suffix(event.url.pathname);
|
|
78
|
-
|
|
79
70
|
// it's crucial that we do this before returning the non-SSR response, otherwise
|
|
80
71
|
// SvelteKit will erroneously believe that the path has been prerendered,
|
|
81
72
|
// causing functions to be omitted from the manifest generated later
|
|
82
|
-
const should_prerender =
|
|
73
|
+
const should_prerender = nodes.prerender();
|
|
83
74
|
if (should_prerender) {
|
|
84
75
|
const mod = leaf_node.server;
|
|
85
76
|
if (mod?.actions) {
|
|
@@ -96,13 +87,16 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
96
87
|
// inherit the prerender option of the page
|
|
97
88
|
state.prerender_default = should_prerender;
|
|
98
89
|
|
|
90
|
+
const should_prerender_data = nodes.should_prerender_data();
|
|
91
|
+
const data_pathname = add_data_suffix(event.url.pathname);
|
|
92
|
+
|
|
99
93
|
/** @type {import('./types.js').Fetched[]} */
|
|
100
94
|
const fetched = [];
|
|
101
95
|
|
|
102
96
|
// renders an empty 'shell' page if SSR is turned off and if there is
|
|
103
97
|
// no server data to prerender. As a result, the load functions and rendering
|
|
104
98
|
// only occur client-side.
|
|
105
|
-
if (
|
|
99
|
+
if (nodes.ssr() === false && !(state.prerendering && should_prerender_data)) {
|
|
106
100
|
// if the user makes a request through a non-enhanced form, the returned value is lost
|
|
107
101
|
// because there is no SSR or client-side handling of the response
|
|
108
102
|
if (DEV && action_result && !event.request.headers.has('x-sveltekit-action')) {
|
|
@@ -123,7 +117,7 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
123
117
|
fetched,
|
|
124
118
|
page_config: {
|
|
125
119
|
ssr: false,
|
|
126
|
-
csr:
|
|
120
|
+
csr: nodes.csr()
|
|
127
121
|
},
|
|
128
122
|
status,
|
|
129
123
|
error: null,
|
|
@@ -142,7 +136,7 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
142
136
|
let load_error = null;
|
|
143
137
|
|
|
144
138
|
/** @type {Array<Promise<import('types').ServerDataNode | null>>} */
|
|
145
|
-
const server_promises = nodes.map((node, i) => {
|
|
139
|
+
const server_promises = nodes.data.map((node, i) => {
|
|
146
140
|
if (load_error) {
|
|
147
141
|
// if an error happens immediately, don't bother with the rest of the nodes
|
|
148
142
|
throw load_error;
|
|
@@ -177,10 +171,10 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
177
171
|
});
|
|
178
172
|
});
|
|
179
173
|
|
|
180
|
-
const csr =
|
|
174
|
+
const csr = nodes.csr();
|
|
181
175
|
|
|
182
176
|
/** @type {Array<Promise<Record<string, any> | null>>} */
|
|
183
|
-
const load_promises = nodes.map((node, i) => {
|
|
177
|
+
const load_promises = nodes.data.map((node, i) => {
|
|
184
178
|
if (load_error) throw load_error;
|
|
185
179
|
return Promise.resolve().then(async () => {
|
|
186
180
|
try {
|
|
@@ -211,8 +205,8 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
211
205
|
for (const p of server_promises) p.catch(() => {});
|
|
212
206
|
for (const p of load_promises) p.catch(() => {});
|
|
213
207
|
|
|
214
|
-
for (let i = 0; i < nodes.length; i += 1) {
|
|
215
|
-
const node = nodes[i];
|
|
208
|
+
for (let i = 0; i < nodes.data.length; i += 1) {
|
|
209
|
+
const node = nodes.data[i];
|
|
216
210
|
|
|
217
211
|
if (node) {
|
|
218
212
|
try {
|
|
@@ -300,7 +294,7 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
300
294
|
});
|
|
301
295
|
}
|
|
302
296
|
|
|
303
|
-
const ssr =
|
|
297
|
+
const ssr = nodes.ssr();
|
|
304
298
|
|
|
305
299
|
return await render_response({
|
|
306
300
|
event,
|
|
@@ -309,7 +303,7 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
309
303
|
state,
|
|
310
304
|
resolve_opts,
|
|
311
305
|
page_config: {
|
|
312
|
-
csr:
|
|
306
|
+
csr: nodes.csr(),
|
|
313
307
|
ssr
|
|
314
308
|
},
|
|
315
309
|
status,
|
|
@@ -116,11 +116,6 @@ export async function render_response({
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
if (page_config.ssr) {
|
|
119
|
-
if (__SVELTEKIT_DEV__ && !branch.at(-1)?.node.component) {
|
|
120
|
-
// Can only be the leaf, layouts have a fallback component generated
|
|
121
|
-
throw new Error(`Missing +page.svelte component for route ${event.route.id}`);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
119
|
/** @type {Record<string, any>} */
|
|
125
120
|
const props = {
|
|
126
121
|
stores: {
|
|
@@ -128,7 +123,15 @@ export async function render_response({
|
|
|
128
123
|
navigating: writable(null),
|
|
129
124
|
updated
|
|
130
125
|
},
|
|
131
|
-
constructors: await Promise.all(
|
|
126
|
+
constructors: await Promise.all(
|
|
127
|
+
branch.map(({ node }) => {
|
|
128
|
+
if (!node.component) {
|
|
129
|
+
// Can only be the leaf, layouts have a fallback component generated
|
|
130
|
+
throw new Error(`Missing +page.svelte component for route ${event.route.id}`);
|
|
131
|
+
}
|
|
132
|
+
return node.component();
|
|
133
|
+
})
|
|
134
|
+
),
|
|
132
135
|
form: form_value
|
|
133
136
|
};
|
|
134
137
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { render_response } from './render.js';
|
|
2
2
|
import { load_data, load_server_data } from './load_data.js';
|
|
3
3
|
import { handle_error_and_jsonify, static_error_page, redirect_response } from '../utils.js';
|
|
4
|
-
import { get_option } from '../../../utils/options.js';
|
|
5
4
|
import { Redirect } from '../../control.js';
|
|
6
5
|
import { get_status } from '../../../utils/error.js';
|
|
6
|
+
import { PageNodes } from '../../../utils/page_nodes.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @typedef {import('./types.js').Loaded} Loaded
|
|
@@ -40,8 +40,9 @@ export async function respond_with_error({
|
|
|
40
40
|
try {
|
|
41
41
|
const branch = [];
|
|
42
42
|
const default_layout = await manifest._.nodes[0](); // 0 is always the root layout
|
|
43
|
-
const
|
|
44
|
-
const
|
|
43
|
+
const nodes = new PageNodes([default_layout]);
|
|
44
|
+
const ssr = nodes.ssr();
|
|
45
|
+
const csr = nodes.csr();
|
|
45
46
|
|
|
46
47
|
if (ssr) {
|
|
47
48
|
state.error = true;
|
|
@@ -11,21 +11,13 @@ import { exec } from '../../utils/routing.js';
|
|
|
11
11
|
import { redirect_json_response, render_data } from './data/index.js';
|
|
12
12
|
import { add_cookies_to_headers, get_cookies } from './cookie.js';
|
|
13
13
|
import { create_fetch } from './fetch.js';
|
|
14
|
+
import { PageNodes } from '../../utils/page_nodes.js';
|
|
14
15
|
import { HttpError, Redirect, SvelteKitError } from '../control.js';
|
|
15
|
-
import {
|
|
16
|
-
validate_layout_exports,
|
|
17
|
-
validate_layout_server_exports,
|
|
18
|
-
validate_page_exports,
|
|
19
|
-
validate_page_server_exports,
|
|
20
|
-
validate_server_exports
|
|
21
|
-
} from '../../utils/exports.js';
|
|
22
|
-
import { get_option } from '../../utils/options.js';
|
|
16
|
+
import { validate_server_exports } from '../../utils/exports.js';
|
|
23
17
|
import { json, text } from '../../exports/index.js';
|
|
24
18
|
import { action_json_redirect, is_action_json_request } from './page/actions.js';
|
|
25
19
|
import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM } from '../shared.js';
|
|
26
20
|
import { get_public_env } from './env_module.js';
|
|
27
|
-
import { load_page_nodes } from './page/load_page_nodes.js';
|
|
28
|
-
import { get_page_config } from '../../utils/route_config.js';
|
|
29
21
|
import { resolve_route } from './page/server_routing.js';
|
|
30
22
|
import { validateHeaders } from './validate-headers.js';
|
|
31
23
|
import {
|
|
@@ -111,11 +103,82 @@ export async function respond(request, options, manifest, state) {
|
|
|
111
103
|
url.searchParams.delete(INVALIDATED_PARAM);
|
|
112
104
|
}
|
|
113
105
|
|
|
106
|
+
/** @type {Record<string, string>} */
|
|
107
|
+
const headers = {};
|
|
108
|
+
|
|
109
|
+
const { cookies, new_cookies, get_cookie_header, set_internal, set_trailing_slash } = get_cookies(
|
|
110
|
+
request,
|
|
111
|
+
url
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
/** @type {import('@sveltejs/kit').RequestEvent} */
|
|
115
|
+
const event = {
|
|
116
|
+
cookies,
|
|
117
|
+
// @ts-expect-error `fetch` needs to be created after the `event` itself
|
|
118
|
+
fetch: null,
|
|
119
|
+
getClientAddress:
|
|
120
|
+
state.getClientAddress ||
|
|
121
|
+
(() => {
|
|
122
|
+
throw new Error(
|
|
123
|
+
`${__SVELTEKIT_ADAPTER_NAME__} does not specify getClientAddress. Please raise an issue`
|
|
124
|
+
);
|
|
125
|
+
}),
|
|
126
|
+
locals: {},
|
|
127
|
+
params: {},
|
|
128
|
+
platform: state.platform,
|
|
129
|
+
request,
|
|
130
|
+
route: { id: null },
|
|
131
|
+
setHeaders: (new_headers) => {
|
|
132
|
+
if (__SVELTEKIT_DEV__) {
|
|
133
|
+
validateHeaders(new_headers);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
for (const key in new_headers) {
|
|
137
|
+
const lower = key.toLowerCase();
|
|
138
|
+
const value = new_headers[key];
|
|
139
|
+
|
|
140
|
+
if (lower === 'set-cookie') {
|
|
141
|
+
throw new Error(
|
|
142
|
+
'Use `event.cookies.set(name, value, options)` instead of `event.setHeaders` to set cookies'
|
|
143
|
+
);
|
|
144
|
+
} else if (lower in headers) {
|
|
145
|
+
throw new Error(`"${key}" header is already set`);
|
|
146
|
+
} else {
|
|
147
|
+
headers[lower] = value;
|
|
148
|
+
|
|
149
|
+
if (state.prerendering && lower === 'cache-control') {
|
|
150
|
+
state.prerendering.cache = /** @type {string} */ (value);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
url,
|
|
156
|
+
isDataRequest: is_data_request,
|
|
157
|
+
isSubRequest: state.depth > 0
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
event.fetch = create_fetch({
|
|
161
|
+
event,
|
|
162
|
+
options,
|
|
163
|
+
manifest,
|
|
164
|
+
state,
|
|
165
|
+
get_cookie_header,
|
|
166
|
+
set_internal
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
if (state.emulator?.platform) {
|
|
170
|
+
event.platform = await state.emulator.platform({
|
|
171
|
+
config: {},
|
|
172
|
+
prerender: !!state.prerendering?.fallback
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
114
176
|
let resolved_path;
|
|
115
177
|
|
|
116
178
|
try {
|
|
117
179
|
// reroute could alter the given URL, so we pass a copy
|
|
118
|
-
resolved_path =
|
|
180
|
+
resolved_path =
|
|
181
|
+
(await options.hooks.reroute({ url: new URL(url), fetch: event.fetch })) ?? url.pathname;
|
|
119
182
|
} catch {
|
|
120
183
|
return text('Internal Server Error', {
|
|
121
184
|
status: 500
|
|
@@ -131,9 +194,6 @@ export async function respond(request, options, manifest, state) {
|
|
|
131
194
|
/** @type {import('types').SSRRoute | null} */
|
|
132
195
|
let route = null;
|
|
133
196
|
|
|
134
|
-
/** @type {Record<string, string>} */
|
|
135
|
-
let params = {};
|
|
136
|
-
|
|
137
197
|
if (base && !state.prerendering?.fallback) {
|
|
138
198
|
if (!resolved_path.startsWith(base)) {
|
|
139
199
|
return text('Not found', { status: 404 });
|
|
@@ -167,68 +227,13 @@ export async function respond(request, options, manifest, state) {
|
|
|
167
227
|
const matched = exec(match, candidate.params, matchers);
|
|
168
228
|
if (matched) {
|
|
169
229
|
route = candidate;
|
|
170
|
-
|
|
230
|
+
event.route = { id: route.id };
|
|
231
|
+
event.params = decode_params(matched);
|
|
171
232
|
break;
|
|
172
233
|
}
|
|
173
234
|
}
|
|
174
235
|
}
|
|
175
236
|
|
|
176
|
-
/** @type {import('types').TrailingSlash | void} */
|
|
177
|
-
let trailing_slash = undefined;
|
|
178
|
-
|
|
179
|
-
/** @type {Record<string, string>} */
|
|
180
|
-
const headers = {};
|
|
181
|
-
|
|
182
|
-
/** @type {Record<string, import('./page/types.js').Cookie>} */
|
|
183
|
-
let cookies_to_add = {};
|
|
184
|
-
|
|
185
|
-
/** @type {import('@sveltejs/kit').RequestEvent} */
|
|
186
|
-
const event = {
|
|
187
|
-
// @ts-expect-error `cookies` and `fetch` need to be created after the `event` itself
|
|
188
|
-
cookies: null,
|
|
189
|
-
// @ts-expect-error
|
|
190
|
-
fetch: null,
|
|
191
|
-
getClientAddress:
|
|
192
|
-
state.getClientAddress ||
|
|
193
|
-
(() => {
|
|
194
|
-
throw new Error(
|
|
195
|
-
`${__SVELTEKIT_ADAPTER_NAME__} does not specify getClientAddress. Please raise an issue`
|
|
196
|
-
);
|
|
197
|
-
}),
|
|
198
|
-
locals: {},
|
|
199
|
-
params,
|
|
200
|
-
platform: state.platform,
|
|
201
|
-
request,
|
|
202
|
-
route: { id: route?.id ?? null },
|
|
203
|
-
setHeaders: (new_headers) => {
|
|
204
|
-
if (__SVELTEKIT_DEV__) {
|
|
205
|
-
validateHeaders(new_headers);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
for (const key in new_headers) {
|
|
209
|
-
const lower = key.toLowerCase();
|
|
210
|
-
const value = new_headers[key];
|
|
211
|
-
|
|
212
|
-
if (lower === 'set-cookie') {
|
|
213
|
-
throw new Error(
|
|
214
|
-
'Use `event.cookies.set(name, value, options)` instead of `event.setHeaders` to set cookies'
|
|
215
|
-
);
|
|
216
|
-
} else if (lower in headers) {
|
|
217
|
-
throw new Error(`"${key}" header is already set`);
|
|
218
|
-
} else {
|
|
219
|
-
headers[lower] = value;
|
|
220
|
-
|
|
221
|
-
if (state.prerendering && lower === 'cache-control') {
|
|
222
|
-
state.prerendering.cache = /** @type {string} */ (value);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
url,
|
|
228
|
-
isDataRequest: is_data_request,
|
|
229
|
-
isSubRequest: state.depth > 0
|
|
230
|
-
};
|
|
231
|
-
|
|
232
237
|
/** @type {import('types').RequiredResolveOptions} */
|
|
233
238
|
let resolve_opts = {
|
|
234
239
|
transformPageChunk: default_transform,
|
|
@@ -236,51 +241,36 @@ export async function respond(request, options, manifest, state) {
|
|
|
236
241
|
preload: default_preload
|
|
237
242
|
};
|
|
238
243
|
|
|
244
|
+
/** @type {import('types').TrailingSlash} */
|
|
245
|
+
let trailing_slash = 'never';
|
|
246
|
+
|
|
239
247
|
try {
|
|
248
|
+
/** @type {PageNodes|undefined} */
|
|
249
|
+
const page_nodes = route?.page
|
|
250
|
+
? new PageNodes(await load_page_nodes(route.page, manifest))
|
|
251
|
+
: undefined;
|
|
252
|
+
|
|
240
253
|
// determine whether we need to redirect to add/remove a trailing slash
|
|
241
254
|
if (route) {
|
|
242
255
|
// if `paths.base === '/a/b/c`, then the root route is `/a/b/c/`,
|
|
243
256
|
// regardless of the `trailingSlash` route option
|
|
244
257
|
if (url.pathname === base || url.pathname === base + '/') {
|
|
245
258
|
trailing_slash = 'always';
|
|
246
|
-
} else if (
|
|
247
|
-
const nodes = await load_page_nodes(route.page, manifest);
|
|
248
|
-
|
|
259
|
+
} else if (page_nodes) {
|
|
249
260
|
if (DEV) {
|
|
250
|
-
|
|
251
|
-
const page = nodes.at(-1);
|
|
252
|
-
|
|
253
|
-
for (const layout of layouts) {
|
|
254
|
-
if (layout) {
|
|
255
|
-
validate_layout_server_exports(
|
|
256
|
-
layout.server,
|
|
257
|
-
/** @type {string} */ (layout.server_id)
|
|
258
|
-
);
|
|
259
|
-
validate_layout_exports(
|
|
260
|
-
layout.universal,
|
|
261
|
-
/** @type {string} */ (layout.universal_id)
|
|
262
|
-
);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (page) {
|
|
267
|
-
validate_page_server_exports(page.server, /** @type {string} */ (page.server_id));
|
|
268
|
-
validate_page_exports(page.universal, /** @type {string} */ (page.universal_id));
|
|
269
|
-
}
|
|
261
|
+
page_nodes.validate();
|
|
270
262
|
}
|
|
271
|
-
|
|
272
|
-
trailing_slash = get_option(nodes, 'trailingSlash');
|
|
263
|
+
trailing_slash = page_nodes.trailing_slash();
|
|
273
264
|
} else if (route.endpoint) {
|
|
274
265
|
const node = await route.endpoint();
|
|
275
|
-
trailing_slash = node.trailingSlash;
|
|
276
|
-
|
|
266
|
+
trailing_slash = node.trailingSlash ?? 'never';
|
|
277
267
|
if (DEV) {
|
|
278
268
|
validate_server_exports(node, /** @type {string} */ (route.endpoint_id));
|
|
279
269
|
}
|
|
280
270
|
}
|
|
281
271
|
|
|
282
272
|
if (!is_data_request) {
|
|
283
|
-
const normalized = normalize_path(url.pathname, trailing_slash
|
|
273
|
+
const normalized = normalize_path(url.pathname, trailing_slash);
|
|
284
274
|
|
|
285
275
|
if (normalized !== url.pathname && !state.prerendering?.fallback) {
|
|
286
276
|
return new Response(undefined, {
|
|
@@ -306,10 +296,9 @@ export async function respond(request, options, manifest, state) {
|
|
|
306
296
|
const node = await route.endpoint();
|
|
307
297
|
config = node.config ?? config;
|
|
308
298
|
prerender = node.prerender ?? prerender;
|
|
309
|
-
} else if (
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
prerender = get_option(nodes, 'prerender') ?? false;
|
|
299
|
+
} else if (page_nodes) {
|
|
300
|
+
config = page_nodes.get_config() ?? config;
|
|
301
|
+
prerender = page_nodes.prerender();
|
|
313
302
|
}
|
|
314
303
|
|
|
315
304
|
if (state.before_handle) {
|
|
@@ -320,36 +309,16 @@ export async function respond(request, options, manifest, state) {
|
|
|
320
309
|
event.platform = await state.emulator.platform({ config, prerender });
|
|
321
310
|
}
|
|
322
311
|
}
|
|
323
|
-
} else if (state.emulator?.platform) {
|
|
324
|
-
event.platform = await state.emulator.platform({
|
|
325
|
-
config: {},
|
|
326
|
-
prerender: !!state.prerendering?.fallback
|
|
327
|
-
});
|
|
328
312
|
}
|
|
329
313
|
|
|
330
|
-
|
|
331
|
-
request,
|
|
332
|
-
url,
|
|
333
|
-
trailing_slash ?? 'never'
|
|
334
|
-
);
|
|
335
|
-
|
|
336
|
-
cookies_to_add = new_cookies;
|
|
337
|
-
event.cookies = cookies;
|
|
338
|
-
event.fetch = create_fetch({
|
|
339
|
-
event,
|
|
340
|
-
options,
|
|
341
|
-
manifest,
|
|
342
|
-
state,
|
|
343
|
-
get_cookie_header,
|
|
344
|
-
set_internal
|
|
345
|
-
});
|
|
314
|
+
set_trailing_slash(trailing_slash);
|
|
346
315
|
|
|
347
316
|
if (state.prerendering && !state.prerendering.fallback) disable_search(url);
|
|
348
317
|
|
|
349
318
|
const response = await options.hooks.handle({
|
|
350
319
|
event,
|
|
351
320
|
resolve: (event, opts) =>
|
|
352
|
-
resolve(event, opts).then((response) => {
|
|
321
|
+
resolve(event, page_nodes, opts).then((response) => {
|
|
353
322
|
// add headers/cookies here, rather than inside `resolve`, so that we
|
|
354
323
|
// can do it once for all responses instead of once per `return`
|
|
355
324
|
for (const key in headers) {
|
|
@@ -357,7 +326,7 @@ export async function respond(request, options, manifest, state) {
|
|
|
357
326
|
response.headers.set(key, /** @type {string} */ (value));
|
|
358
327
|
}
|
|
359
328
|
|
|
360
|
-
add_cookies_to_headers(response.headers, Object.values(
|
|
329
|
+
add_cookies_to_headers(response.headers, Object.values(new_cookies));
|
|
361
330
|
|
|
362
331
|
if (state.prerendering && event.route.id !== null) {
|
|
363
332
|
response.headers.set('x-sveltekit-routeid', encodeURI(event.route.id));
|
|
@@ -418,7 +387,7 @@ export async function respond(request, options, manifest, state) {
|
|
|
418
387
|
: route?.page && is_action_json_request(event)
|
|
419
388
|
? action_json_redirect(e)
|
|
420
389
|
: redirect_response(e.status, e.location);
|
|
421
|
-
add_cookies_to_headers(response.headers, Object.values(
|
|
390
|
+
add_cookies_to_headers(response.headers, Object.values(new_cookies));
|
|
422
391
|
return response;
|
|
423
392
|
}
|
|
424
393
|
return await handle_fatal_error(event, options, e);
|
|
@@ -426,9 +395,10 @@ export async function respond(request, options, manifest, state) {
|
|
|
426
395
|
|
|
427
396
|
/**
|
|
428
397
|
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
398
|
+
* @param {PageNodes | undefined} page_nodes
|
|
429
399
|
* @param {import('@sveltejs/kit').ResolveOptions} [opts]
|
|
430
400
|
*/
|
|
431
|
-
async function resolve(event, opts) {
|
|
401
|
+
async function resolve(event, page_nodes, opts) {
|
|
432
402
|
try {
|
|
433
403
|
if (opts) {
|
|
434
404
|
resolve_opts = {
|
|
@@ -467,13 +437,23 @@ export async function respond(request, options, manifest, state) {
|
|
|
467
437
|
manifest,
|
|
468
438
|
state,
|
|
469
439
|
invalidated_data_nodes,
|
|
470
|
-
trailing_slash
|
|
440
|
+
trailing_slash
|
|
471
441
|
);
|
|
472
442
|
} else if (route.endpoint && (!route.page || is_endpoint_request(event))) {
|
|
473
443
|
response = await render_endpoint(event, await route.endpoint(), state);
|
|
474
444
|
} else if (route.page) {
|
|
475
|
-
if (
|
|
476
|
-
|
|
445
|
+
if (!page_nodes) {
|
|
446
|
+
throw new Error('page_nodes not found. This should never happen');
|
|
447
|
+
} else if (page_methods.has(method)) {
|
|
448
|
+
response = await render_page(
|
|
449
|
+
event,
|
|
450
|
+
route.page,
|
|
451
|
+
options,
|
|
452
|
+
manifest,
|
|
453
|
+
state,
|
|
454
|
+
page_nodes,
|
|
455
|
+
resolve_opts
|
|
456
|
+
);
|
|
477
457
|
} else {
|
|
478
458
|
const allowed_methods = new Set(allowed_page_methods);
|
|
479
459
|
const node = await manifest._.nodes[route.page.leaf]();
|
|
@@ -499,9 +479,8 @@ export async function respond(request, options, manifest, state) {
|
|
|
499
479
|
}
|
|
500
480
|
}
|
|
501
481
|
} else {
|
|
502
|
-
// a route will always have a page or an endpoint, but TypeScript
|
|
503
|
-
|
|
504
|
-
throw new Error('This should never happen');
|
|
482
|
+
// a route will always have a page or an endpoint, but TypeScript doesn't know that
|
|
483
|
+
throw new Error('Route is neither page nor endpoint. This should never happen');
|
|
505
484
|
}
|
|
506
485
|
|
|
507
486
|
// If the route contains a page and an endpoint, we need to add a
|
|
@@ -578,3 +557,15 @@ export async function respond(request, options, manifest, state) {
|
|
|
578
557
|
}
|
|
579
558
|
}
|
|
580
559
|
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* @param {import('types').PageNodeIndexes} page
|
|
563
|
+
* @param {import('@sveltejs/kit').SSRManifest} manifest
|
|
564
|
+
*/
|
|
565
|
+
export function load_page_nodes(page, manifest) {
|
|
566
|
+
return Promise.all([
|
|
567
|
+
// we use == here rather than === because [undefined] serializes as "[null]"
|
|
568
|
+
...page.layouts.map((n) => (n == undefined ? n : manifest._.nodes[n]())),
|
|
569
|
+
manifest._.nodes[page.leaf]()
|
|
570
|
+
]);
|
|
571
|
+
}
|
package/src/types/internal.d.ts
CHANGED
|
@@ -364,8 +364,28 @@ export interface SSRComponent {
|
|
|
364
364
|
|
|
365
365
|
export type SSRComponentLoader = () => Promise<SSRComponent>;
|
|
366
366
|
|
|
367
|
+
export interface UniversalNode {
|
|
368
|
+
load?: Load;
|
|
369
|
+
prerender?: PrerenderOption;
|
|
370
|
+
ssr?: boolean;
|
|
371
|
+
csr?: boolean;
|
|
372
|
+
trailingSlash?: TrailingSlash;
|
|
373
|
+
config?: any;
|
|
374
|
+
entries?: PrerenderEntryGenerator;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export interface ServerNode {
|
|
378
|
+
load?: ServerLoad;
|
|
379
|
+
prerender?: PrerenderOption;
|
|
380
|
+
ssr?: boolean;
|
|
381
|
+
csr?: boolean;
|
|
382
|
+
trailingSlash?: TrailingSlash;
|
|
383
|
+
actions?: Actions;
|
|
384
|
+
config?: any;
|
|
385
|
+
entries?: PrerenderEntryGenerator;
|
|
386
|
+
}
|
|
387
|
+
|
|
367
388
|
export interface SSRNode {
|
|
368
|
-
component: SSRComponentLoader;
|
|
369
389
|
/** index into the `nodes` array in the generated `client/app.js`. */
|
|
370
390
|
index: number;
|
|
371
391
|
/** external JS files that are loaded on the client. `imports[0]` is the entry point (e.g. `client/nodes/0.js`) */
|
|
@@ -374,32 +394,18 @@ export interface SSRNode {
|
|
|
374
394
|
stylesheets: string[];
|
|
375
395
|
/** external font files that are loaded on the client */
|
|
376
396
|
fonts: string[];
|
|
377
|
-
/** inlined styles. */
|
|
378
|
-
inline_styles?(): MaybePromise<Record<string, string>>;
|
|
379
|
-
|
|
380
|
-
universal: {
|
|
381
|
-
load?: Load;
|
|
382
|
-
prerender?: PrerenderOption;
|
|
383
|
-
ssr?: boolean;
|
|
384
|
-
csr?: boolean;
|
|
385
|
-
trailingSlash?: TrailingSlash;
|
|
386
|
-
config?: any;
|
|
387
|
-
entries?: PrerenderEntryGenerator;
|
|
388
|
-
};
|
|
389
|
-
|
|
390
|
-
server: {
|
|
391
|
-
load?: ServerLoad;
|
|
392
|
-
prerender?: PrerenderOption;
|
|
393
|
-
ssr?: boolean;
|
|
394
|
-
csr?: boolean;
|
|
395
|
-
trailingSlash?: TrailingSlash;
|
|
396
|
-
actions?: Actions;
|
|
397
|
-
config?: any;
|
|
398
|
-
entries?: PrerenderEntryGenerator;
|
|
399
|
-
};
|
|
400
397
|
|
|
401
398
|
universal_id?: string;
|
|
402
399
|
server_id?: string;
|
|
400
|
+
|
|
401
|
+
/** inlined styles. */
|
|
402
|
+
inline_styles?(): MaybePromise<Record<string, string>>;
|
|
403
|
+
/** Svelte component */
|
|
404
|
+
component?: SSRComponentLoader;
|
|
405
|
+
/** +page.js or +layout.js */
|
|
406
|
+
universal?: UniversalNode;
|
|
407
|
+
/** +page.server.js, +layout.server.js, or +server.js */
|
|
408
|
+
server?: ServerNode;
|
|
403
409
|
}
|
|
404
410
|
|
|
405
411
|
export type SSRNodeLoader = () => Promise<SSRNode>;
|
|
@@ -482,6 +488,10 @@ export interface SSRState {
|
|
|
482
488
|
*/
|
|
483
489
|
prerender_default?: PrerenderOption;
|
|
484
490
|
read?: (file: string) => Buffer;
|
|
491
|
+
/**
|
|
492
|
+
* Used to setup `__SVELTEKIT_TRACK__` which checks if a used feature is supported.
|
|
493
|
+
* E.g. if `read` from `$app/server` is used, it checks whether the route's config is compatible.
|
|
494
|
+
*/
|
|
485
495
|
before_handle?: (event: RequestEvent, config: any, prerender: PrerenderOption) => void;
|
|
486
496
|
emulator?: Emulator;
|
|
487
497
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import {
|
|
2
|
+
validate_layout_exports,
|
|
3
|
+
validate_layout_server_exports,
|
|
4
|
+
validate_page_exports,
|
|
5
|
+
validate_page_server_exports
|
|
6
|
+
} from './exports.js';
|
|
7
|
+
|
|
8
|
+
export class PageNodes {
|
|
9
|
+
data;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {Array<import('types').SSRNode | undefined>} nodes
|
|
13
|
+
*/
|
|
14
|
+
constructor(nodes) {
|
|
15
|
+
this.data = nodes;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
layouts() {
|
|
19
|
+
return this.data.slice(0, -1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
page() {
|
|
23
|
+
return this.data.at(-1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
validate() {
|
|
27
|
+
for (const layout of this.layouts()) {
|
|
28
|
+
if (layout) {
|
|
29
|
+
validate_layout_server_exports(layout.server, /** @type {string} */ (layout.server_id));
|
|
30
|
+
validate_layout_exports(layout.universal, /** @type {string} */ (layout.universal_id));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const page = this.page();
|
|
35
|
+
if (page) {
|
|
36
|
+
validate_page_server_exports(page.server, /** @type {string} */ (page.server_id));
|
|
37
|
+
validate_page_exports(page.universal, /** @type {string} */ (page.universal_id));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @template {'prerender' | 'ssr' | 'csr' | 'trailingSlash' | 'entries'} Option
|
|
43
|
+
* @template {(import('types').UniversalNode | import('types').ServerNode)[Option]} Value
|
|
44
|
+
* @param {Option} option
|
|
45
|
+
* @returns {Value | undefined}
|
|
46
|
+
*/
|
|
47
|
+
#get_option(option) {
|
|
48
|
+
return this.data.reduce((value, node) => {
|
|
49
|
+
return /** @type {Value} TypeScript's too dumb to understand this */ (
|
|
50
|
+
node?.universal?.[option] ?? node?.server?.[option] ?? value
|
|
51
|
+
);
|
|
52
|
+
}, /** @type {Value | undefined} */ (undefined));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
csr() {
|
|
56
|
+
return this.#get_option('csr') ?? true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ssr() {
|
|
60
|
+
return this.#get_option('ssr') ?? true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
prerender() {
|
|
64
|
+
return this.#get_option('prerender') ?? false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
trailing_slash() {
|
|
68
|
+
return this.#get_option('trailingSlash') ?? 'never';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
get_config() {
|
|
72
|
+
/** @type {any} */
|
|
73
|
+
let current = {};
|
|
74
|
+
|
|
75
|
+
for (const node of this.data) {
|
|
76
|
+
if (!node?.universal?.config && !node?.server?.config) continue;
|
|
77
|
+
|
|
78
|
+
current = {
|
|
79
|
+
...current,
|
|
80
|
+
...node?.universal?.config,
|
|
81
|
+
...node?.server?.config
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// TODO 3.0 always return `current`? then we can get rid of `?? {}` in other places
|
|
86
|
+
return Object.keys(current).length ? current : undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
should_prerender_data() {
|
|
90
|
+
return this.data.some(
|
|
91
|
+
// prerender in case of trailingSlash because the client retrieves that value from the server
|
|
92
|
+
(node) => node?.server?.load || node?.server?.trailingSlash !== undefined
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
package/src/version.js
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -796,7 +796,7 @@ declare module '@sveltejs/kit' {
|
|
|
796
796
|
* The [`reroute`](https://svelte.dev/docs/kit/hooks#Universal-hooks-reroute) hook allows you to modify the URL before it is used to determine which route to render.
|
|
797
797
|
* @since 2.3.0
|
|
798
798
|
*/
|
|
799
|
-
export type Reroute = (event: { url: URL }) => MaybePromise<void | string>;
|
|
799
|
+
export type Reroute = (event: { url: URL; fetch: typeof fetch }) => MaybePromise<void | string>;
|
|
800
800
|
|
|
801
801
|
/**
|
|
802
802
|
* The [`transport`](https://svelte.dev/docs/kit/hooks#Universal-hooks-transport) hook allows you to transport custom types across the server/client boundary.
|
|
@@ -1842,8 +1842,28 @@ declare module '@sveltejs/kit' {
|
|
|
1842
1842
|
|
|
1843
1843
|
type SSRComponentLoader = () => Promise<SSRComponent>;
|
|
1844
1844
|
|
|
1845
|
+
interface UniversalNode {
|
|
1846
|
+
load?: Load;
|
|
1847
|
+
prerender?: PrerenderOption;
|
|
1848
|
+
ssr?: boolean;
|
|
1849
|
+
csr?: boolean;
|
|
1850
|
+
trailingSlash?: TrailingSlash;
|
|
1851
|
+
config?: any;
|
|
1852
|
+
entries?: PrerenderEntryGenerator;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
interface ServerNode {
|
|
1856
|
+
load?: ServerLoad;
|
|
1857
|
+
prerender?: PrerenderOption;
|
|
1858
|
+
ssr?: boolean;
|
|
1859
|
+
csr?: boolean;
|
|
1860
|
+
trailingSlash?: TrailingSlash;
|
|
1861
|
+
actions?: Actions;
|
|
1862
|
+
config?: any;
|
|
1863
|
+
entries?: PrerenderEntryGenerator;
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1845
1866
|
interface SSRNode {
|
|
1846
|
-
component: SSRComponentLoader;
|
|
1847
1867
|
/** index into the `nodes` array in the generated `client/app.js`. */
|
|
1848
1868
|
index: number;
|
|
1849
1869
|
/** external JS files that are loaded on the client. `imports[0]` is the entry point (e.g. `client/nodes/0.js`) */
|
|
@@ -1852,32 +1872,18 @@ declare module '@sveltejs/kit' {
|
|
|
1852
1872
|
stylesheets: string[];
|
|
1853
1873
|
/** external font files that are loaded on the client */
|
|
1854
1874
|
fonts: string[];
|
|
1855
|
-
/** inlined styles. */
|
|
1856
|
-
inline_styles?(): MaybePromise<Record<string, string>>;
|
|
1857
|
-
|
|
1858
|
-
universal: {
|
|
1859
|
-
load?: Load;
|
|
1860
|
-
prerender?: PrerenderOption;
|
|
1861
|
-
ssr?: boolean;
|
|
1862
|
-
csr?: boolean;
|
|
1863
|
-
trailingSlash?: TrailingSlash;
|
|
1864
|
-
config?: any;
|
|
1865
|
-
entries?: PrerenderEntryGenerator;
|
|
1866
|
-
};
|
|
1867
|
-
|
|
1868
|
-
server: {
|
|
1869
|
-
load?: ServerLoad;
|
|
1870
|
-
prerender?: PrerenderOption;
|
|
1871
|
-
ssr?: boolean;
|
|
1872
|
-
csr?: boolean;
|
|
1873
|
-
trailingSlash?: TrailingSlash;
|
|
1874
|
-
actions?: Actions;
|
|
1875
|
-
config?: any;
|
|
1876
|
-
entries?: PrerenderEntryGenerator;
|
|
1877
|
-
};
|
|
1878
1875
|
|
|
1879
1876
|
universal_id?: string;
|
|
1880
1877
|
server_id?: string;
|
|
1878
|
+
|
|
1879
|
+
/** inlined styles. */
|
|
1880
|
+
inline_styles?(): MaybePromise<Record<string, string>>;
|
|
1881
|
+
/** Svelte component */
|
|
1882
|
+
component?: SSRComponentLoader;
|
|
1883
|
+
/** +page.js or +layout.js */
|
|
1884
|
+
universal?: UniversalNode;
|
|
1885
|
+
/** +page.server.js, +layout.server.js, or +server.js */
|
|
1886
|
+
server?: ServerNode;
|
|
1881
1887
|
}
|
|
1882
1888
|
|
|
1883
1889
|
type SSRNodeLoader = () => Promise<SSRNode>;
|
|
@@ -2016,7 +2022,8 @@ declare module '@sveltejs/kit' {
|
|
|
2016
2022
|
* console.log(url.pathname); // /blog/post
|
|
2017
2023
|
* console.log(denormalize('/blog/post/a')); // /blog/post/a/__data.json
|
|
2018
2024
|
* ```
|
|
2019
|
-
*
|
|
2025
|
+
* @since 2.18.0
|
|
2026
|
+
*/
|
|
2020
2027
|
export function normalizeUrl(url: URL | string): {
|
|
2021
2028
|
url: URL;
|
|
2022
2029
|
wasNormalized: boolean;
|
package/types/index.d.ts.map
CHANGED
|
@@ -73,6 +73,8 @@
|
|
|
73
73
|
"RouteData",
|
|
74
74
|
"SSRComponent",
|
|
75
75
|
"SSRComponentLoader",
|
|
76
|
+
"UniversalNode",
|
|
77
|
+
"ServerNode",
|
|
76
78
|
"SSRNode",
|
|
77
79
|
"SSRNodeLoader",
|
|
78
80
|
"PageNodeIndexes",
|
|
@@ -161,6 +163,6 @@
|
|
|
161
163
|
null,
|
|
162
164
|
null
|
|
163
165
|
],
|
|
164
|
-
"mappings": "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
|
|
166
|
+
"mappings": "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",
|
|
165
167
|
"ignoreList": []
|
|
166
168
|
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {import('types').PageNodeIndexes} page
|
|
3
|
-
* @param {import('@sveltejs/kit').SSRManifest} manifest
|
|
4
|
-
*/
|
|
5
|
-
export function load_page_nodes(page, manifest) {
|
|
6
|
-
return Promise.all([
|
|
7
|
-
// we use == here rather than === because [undefined] serializes as "[null]"
|
|
8
|
-
...page.layouts.map((n) => (n == undefined ? n : manifest._.nodes[n]())),
|
|
9
|
-
manifest._.nodes[page.leaf]()
|
|
10
|
-
]);
|
|
11
|
-
}
|
package/src/utils/options.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @template {'prerender' | 'ssr' | 'csr' | 'trailingSlash' | 'entries'} Option
|
|
3
|
-
* @template {(import('types').SSRNode['universal'] | import('types').SSRNode['server'])[Option]} Value
|
|
4
|
-
*
|
|
5
|
-
* @param {Array<import('types').SSRNode | undefined>} nodes
|
|
6
|
-
* @param {Option} option
|
|
7
|
-
*
|
|
8
|
-
* @returns {Value | undefined}
|
|
9
|
-
*/
|
|
10
|
-
export function get_option(nodes, option) {
|
|
11
|
-
return nodes.reduce((value, node) => {
|
|
12
|
-
return /** @type {Value} TypeScript's too dumb to understand this */ (
|
|
13
|
-
node?.universal?.[option] ?? node?.server?.[option] ?? value
|
|
14
|
-
);
|
|
15
|
-
}, /** @type {Value | undefined} */ (undefined));
|
|
16
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Do a shallow merge (first level) of the config object
|
|
3
|
-
* @param {Array<import('types').SSRNode | undefined>} nodes
|
|
4
|
-
*/
|
|
5
|
-
export function get_page_config(nodes) {
|
|
6
|
-
/** @type {any} */
|
|
7
|
-
let current = {};
|
|
8
|
-
|
|
9
|
-
for (const node of nodes) {
|
|
10
|
-
if (!node?.universal?.config && !node?.server?.config) continue;
|
|
11
|
-
|
|
12
|
-
current = {
|
|
13
|
-
...current,
|
|
14
|
-
...node?.universal?.config,
|
|
15
|
-
...node?.server?.config
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// TODO 3.0 always return `current`? then we can get rid of `?? {}` in other places
|
|
20
|
-
return Object.keys(current).length ? current : undefined;
|
|
21
|
-
}
|