@sveltejs/kit 3.0.0-next.13 → 3.0.0-next.16
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 +7 -4
- package/src/cli.js +8 -5
- package/src/core/adapt/builder.js +20 -10
- package/src/core/config/index.js +4 -5
- package/src/core/env.js +3 -3
- package/src/core/generate_manifest/index.js +6 -0
- package/src/core/postbuild/entities.js +8 -2
- package/src/core/postbuild/fallback.js +2 -1
- package/src/core/postbuild/prerender.js +18 -13
- package/src/core/sync/create_manifest_data/conflict.js +1 -1
- package/src/core/sync/create_manifest_data/index.js +33 -2
- package/src/core/sync/sync.js +3 -2
- package/src/core/sync/utils.js +2 -2
- package/src/core/sync/write_app_types.js +72 -27
- package/src/core/sync/write_tsconfig/index.js +73 -54
- package/src/core/sync/write_tsconfig/utils.js +0 -61
- package/src/core/sync/write_tsconfig/validate.js +128 -0
- package/src/core/sync/write_types/index.js +7 -4
- package/src/exports/node/index.js +2 -7
- package/src/exports/public.d.ts +25 -18
- package/src/exports/vite/build/build_server.js +2 -3
- package/src/exports/vite/dev/index.js +44 -36
- package/src/exports/vite/index.js +91 -16
- package/src/exports/vite/utils.js +62 -15
- package/src/runner.js +4 -2
- package/src/runtime/app/forms.js +4 -7
- package/src/runtime/app/internal/transport.js +53 -0
- package/src/runtime/app/paths/client.js +2 -2
- package/src/runtime/app/paths/internal/client.js +2 -2
- package/src/runtime/app/server/remote/prerender.js +6 -10
- package/src/runtime/app/server/remote/query.js +3 -9
- package/src/runtime/app/server/remote/requested.js +2 -2
- package/src/runtime/app/server/remote/shared.js +1 -16
- package/src/runtime/client/client.js +177 -63
- package/src/runtime/client/fetcher.js +2 -13
- package/src/runtime/client/parse.js +1 -1
- package/src/runtime/client/remote-functions/command.svelte.js +1 -2
- package/src/runtime/client/remote-functions/form.svelte.js +3 -7
- package/src/runtime/client/remote-functions/prerender.svelte.js +2 -2
- package/src/runtime/client/remote-functions/query/index.js +1 -1
- package/src/runtime/client/remote-functions/query/proxy.js +2 -2
- package/src/runtime/client/remote-functions/query-batch.svelte.js +1 -1
- package/src/runtime/client/remote-functions/query-live/proxy.js +2 -12
- package/src/runtime/client/remote-functions/shared.svelte.js +1 -1
- package/src/runtime/client/utils.js +1 -0
- package/src/runtime/form-utils.js +4 -6
- package/src/runtime/pathname.js +44 -1
- package/src/runtime/server/data/index.js +5 -8
- package/src/runtime/server/dev.js +22 -0
- package/src/runtime/server/endpoint.js +3 -4
- package/src/runtime/server/fetch.js +25 -30
- package/src/runtime/server/index.js +64 -46
- package/src/runtime/server/internal.js +12 -5
- package/src/runtime/server/page/actions.js +18 -43
- package/src/runtime/server/page/crypto.js +2 -2
- package/src/runtime/server/page/csp.js +2 -1
- package/src/runtime/server/page/data_serializer.js +12 -13
- package/src/runtime/server/page/index.js +16 -32
- package/src/runtime/server/page/load_data.js +28 -44
- package/src/runtime/server/page/render.js +28 -12
- package/src/runtime/server/page/respond_with_error.js +8 -20
- package/src/runtime/server/page/serialize_data.js +2 -13
- package/src/runtime/server/page/server_routing.js +58 -9
- package/src/runtime/server/remote-functions.js +11 -15
- package/src/runtime/server/respond.js +44 -56
- package/src/runtime/server/state.js +60 -0
- package/src/runtime/server/utils.js +0 -20
- package/src/runtime/shared.js +20 -40
- package/src/runtime/utils.js +3 -0
- package/src/types/ambient-private.d.ts +1 -1
- package/src/types/ambient.d.ts +58 -7
- package/src/types/global-private.d.ts +1 -1
- package/src/types/internal.d.ts +47 -53
- package/src/utils/filesystem.js +1 -23
- package/src/utils/hash.js +21 -0
- package/src/utils/http.js +8 -7
- package/src/utils/import.js +2 -1
- package/src/utils/params.js +1 -1
- package/src/utils/regex.js +9 -0
- package/src/utils/routing.js +52 -27
- package/src/utils/url.js +1 -0
- package/src/version.js +1 -1
- package/types/index.d.ts +98 -28
- package/types/index.d.ts.map +1 -1
- package/src/exports/node/polyfills.js +0 -30
- package/src/runtime/server/app.js +0 -9
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/** @import { RequestEvent, ActionResult, Actions } from '@sveltejs/kit' */
|
|
2
|
-
/** @import { SSROptions, SSRNode, ServerNode
|
|
3
|
-
import * as devalue from 'devalue';
|
|
2
|
+
/** @import { SSROptions, SSRNode, ServerNode } from 'types' */
|
|
4
3
|
import { DEV } from 'esm-env';
|
|
5
4
|
import { json } from '@sveltejs/kit';
|
|
6
5
|
import { HttpError, Redirect, ActionFailure, SvelteKitError } from '@sveltejs/kit/internal';
|
|
7
6
|
import { with_request_store, merge_tracing } from '@sveltejs/kit/internal/server';
|
|
8
7
|
import { normalize_error } from '../../../utils/error.js';
|
|
9
8
|
import { is_form_content_type, negotiate } from '../../../utils/http.js';
|
|
10
|
-
import {
|
|
9
|
+
import { with_version_header } from '../utils.js';
|
|
11
10
|
import { handle_error_and_jsonify } from '../errors.js';
|
|
12
11
|
import { record_span } from '../../telemetry/record_span.js';
|
|
12
|
+
import { stringify, uneval } from '#app/internal/transport';
|
|
13
13
|
|
|
14
14
|
/** @param {RequestEvent} event */
|
|
15
15
|
export function is_action_json_request(event) {
|
|
@@ -23,11 +23,11 @@ export function is_action_json_request(event) {
|
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* @param {RequestEvent} event
|
|
26
|
-
* @param {import('types').RequestState}
|
|
26
|
+
* @param {import('types').RequestState} state
|
|
27
27
|
* @param {SSROptions} options
|
|
28
28
|
* @param {SSRNode['server'] | undefined} server
|
|
29
29
|
*/
|
|
30
|
-
export async function handle_action_json_request(event,
|
|
30
|
+
export async function handle_action_json_request(event, state, options, server) {
|
|
31
31
|
const actions = server?.actions;
|
|
32
32
|
|
|
33
33
|
if (!actions) {
|
|
@@ -37,7 +37,7 @@ export async function handle_action_json_request(event, event_state, options, se
|
|
|
37
37
|
`POST method not allowed. No form actions exist for ${DEV ? `the page at ${event.route.id}` : 'this page'}`
|
|
38
38
|
);
|
|
39
39
|
|
|
40
|
-
const error = await handle_error_and_jsonify(event,
|
|
40
|
+
const error = await handle_error_and_jsonify(event, state, options, no_actions_error);
|
|
41
41
|
|
|
42
42
|
return action_json(
|
|
43
43
|
{
|
|
@@ -58,7 +58,7 @@ export async function handle_action_json_request(event, event_state, options, se
|
|
|
58
58
|
check_named_default_separate(actions);
|
|
59
59
|
|
|
60
60
|
try {
|
|
61
|
-
const data = await call_action(event,
|
|
61
|
+
const data = await call_action(event, state, actions);
|
|
62
62
|
|
|
63
63
|
if (DEV) {
|
|
64
64
|
validate_action_return(data);
|
|
@@ -72,11 +72,7 @@ export async function handle_action_json_request(event, event_state, options, se
|
|
|
72
72
|
// @ts-expect-error we assign a string to what is supposed to be an object. That's ok
|
|
73
73
|
// because we don't use the object outside, and this way we have better code navigation
|
|
74
74
|
// through knowing where the related interface is used.
|
|
75
|
-
data:
|
|
76
|
-
data.data,
|
|
77
|
-
/** @type {string} */ (event.route.id),
|
|
78
|
-
options.hooks.transport
|
|
79
|
-
)
|
|
75
|
+
data: try_serialize(data.data, stringify, /** @type {string} */ (event.route.id))
|
|
80
76
|
},
|
|
81
77
|
{
|
|
82
78
|
status: data.status
|
|
@@ -87,11 +83,7 @@ export async function handle_action_json_request(event, event_state, options, se
|
|
|
87
83
|
type: 'success',
|
|
88
84
|
status: 200,
|
|
89
85
|
// @ts-expect-error see comment above
|
|
90
|
-
data:
|
|
91
|
-
data,
|
|
92
|
-
/** @type {string} */ (event.route.id),
|
|
93
|
-
options.hooks.transport
|
|
94
|
-
)
|
|
86
|
+
data: try_serialize(data, stringify, /** @type {string} */ (event.route.id))
|
|
95
87
|
});
|
|
96
88
|
} else {
|
|
97
89
|
// no data returned — use 204 No Content (without a body, per the spec)
|
|
@@ -106,7 +98,7 @@ export async function handle_action_json_request(event, event_state, options, se
|
|
|
106
98
|
|
|
107
99
|
const transformed = await handle_error_and_jsonify(
|
|
108
100
|
event,
|
|
109
|
-
|
|
101
|
+
state,
|
|
110
102
|
options,
|
|
111
103
|
check_incorrect_fail_use(err)
|
|
112
104
|
);
|
|
@@ -160,11 +152,11 @@ export function is_action_request(event) {
|
|
|
160
152
|
|
|
161
153
|
/**
|
|
162
154
|
* @param {RequestEvent} event
|
|
163
|
-
* @param {import('types').RequestState}
|
|
155
|
+
* @param {import('types').RequestState} state
|
|
164
156
|
* @param {SSRNode['server'] | undefined} server
|
|
165
157
|
* @returns {Promise<ActionResult>}
|
|
166
158
|
*/
|
|
167
|
-
export async function handle_action_request(event,
|
|
159
|
+
export async function handle_action_request(event, state, server) {
|
|
168
160
|
const actions = server?.actions;
|
|
169
161
|
|
|
170
162
|
if (!actions) {
|
|
@@ -188,7 +180,7 @@ export async function handle_action_request(event, event_state, server) {
|
|
|
188
180
|
check_named_default_separate(actions);
|
|
189
181
|
|
|
190
182
|
try {
|
|
191
|
-
const data = await call_action(event,
|
|
183
|
+
const data = await call_action(event, state, actions);
|
|
192
184
|
|
|
193
185
|
if (DEV) {
|
|
194
186
|
validate_action_return(data);
|
|
@@ -240,11 +232,11 @@ function check_named_default_separate(actions) {
|
|
|
240
232
|
|
|
241
233
|
/**
|
|
242
234
|
* @param {RequestEvent} event
|
|
243
|
-
* @param {import('types').RequestState}
|
|
235
|
+
* @param {import('types').RequestState} state
|
|
244
236
|
* @param {NonNullable<ServerNode['actions']>} actions
|
|
245
237
|
* @throws {Redirect | HttpError | SvelteKitError | Error}
|
|
246
238
|
*/
|
|
247
|
-
async function call_action(event,
|
|
239
|
+
async function call_action(event, state, actions) {
|
|
248
240
|
const url = new URL(event.request.url);
|
|
249
241
|
|
|
250
242
|
let name = 'default';
|
|
@@ -283,7 +275,7 @@ async function call_action(event, event_state, actions) {
|
|
|
283
275
|
fn: async (current) => {
|
|
284
276
|
const traced_event = merge_tracing(event, current);
|
|
285
277
|
|
|
286
|
-
const result = await with_request_store({ event: traced_event, state
|
|
278
|
+
const result = await with_request_store({ event: traced_event, state }, () =>
|
|
287
279
|
action(traced_event)
|
|
288
280
|
);
|
|
289
281
|
|
|
@@ -314,26 +306,9 @@ function validate_action_return(data) {
|
|
|
314
306
|
* Try to `devalue.uneval` the data object, and if it fails, return a proper Error with context
|
|
315
307
|
* @param {any} data
|
|
316
308
|
* @param {string} route_id
|
|
317
|
-
* @param {ServerHooks['transport']} transport
|
|
318
309
|
*/
|
|
319
|
-
export function uneval_action_response(data, route_id
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
return try_serialize(data, (value) => devalue.uneval(value, replacer), route_id);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Try to `devalue.stringify` the data object, and if it fails, return a proper Error with context
|
|
327
|
-
* @param {any} data
|
|
328
|
-
* @param {string} route_id
|
|
329
|
-
* @param {ServerHooks['transport']} transport
|
|
330
|
-
*/
|
|
331
|
-
function stringify_action_response(data, route_id, transport) {
|
|
332
|
-
const encoders = Object.fromEntries(
|
|
333
|
-
Object.entries(transport).map(([key, value]) => [key, value.encode])
|
|
334
|
-
);
|
|
335
|
-
|
|
336
|
-
return try_serialize(data, (value) => devalue.stringify(value, encoders), route_id);
|
|
310
|
+
export function uneval_action_response(data, route_id) {
|
|
311
|
+
return try_serialize(data, uneval, route_id);
|
|
337
312
|
}
|
|
338
313
|
|
|
339
314
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { text_encoder } from '../../utils.js';
|
|
1
|
+
import { base64_encode, text_encoder } from '../../utils.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* SHA-256 hashing function adapted from https://bitwiseshiftleft.github.io/sjcl
|
|
@@ -102,7 +102,7 @@ export function sha256(data) {
|
|
|
102
102
|
const bytes = new Uint8Array(out.buffer);
|
|
103
103
|
reverse_endianness(bytes);
|
|
104
104
|
|
|
105
|
-
return
|
|
105
|
+
return base64_encode(bytes);
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
/** The SHA-256 initialization vector */
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { escape_html } from '../../../utils/escape.js';
|
|
2
|
+
import { base64_encode } from '../../utils.js';
|
|
2
3
|
import { sha256 } from './crypto.js';
|
|
3
4
|
|
|
4
5
|
const array = new Uint8Array(16);
|
|
5
6
|
|
|
6
7
|
function generate_nonce() {
|
|
7
8
|
crypto.getRandomValues(array);
|
|
8
|
-
return
|
|
9
|
+
return base64_encode(array);
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
const quoted = new Set([
|
|
@@ -3,16 +3,17 @@ import { compact } from '../../../utils/array.js';
|
|
|
3
3
|
import { create_async_iterator } from '../../../utils/streaming.js';
|
|
4
4
|
import { clarify_devalue_error, get_global_name, serialize_uses } from '../utils.js';
|
|
5
5
|
import { handle_error_and_jsonify } from '../errors.js';
|
|
6
|
+
import { encoders } from '#app/internal/transport';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* If the serialized data contains promises, `chunks` will be an
|
|
9
10
|
* async iterable containing their resolutions
|
|
10
11
|
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
11
|
-
* @param {import('types').RequestState}
|
|
12
|
+
* @param {import('types').RequestState} state
|
|
12
13
|
* @param {import('types').SSROptions} options
|
|
13
14
|
* @returns {import('./types.js').ServerDataSerializer}
|
|
14
15
|
*/
|
|
15
|
-
export function server_data_serializer(event,
|
|
16
|
+
export function server_data_serializer(event, state, options) {
|
|
16
17
|
let promise_id = 1;
|
|
17
18
|
let max_nodes = -1;
|
|
18
19
|
|
|
@@ -30,7 +31,7 @@ export function server_data_serializer(event, event_state, options) {
|
|
|
30
31
|
.then(/** @param {any} data */ (data) => ({ data }))
|
|
31
32
|
.catch(
|
|
32
33
|
/** @param {any} error */ async (error) => ({
|
|
33
|
-
error: await handle_error_and_jsonify(event,
|
|
34
|
+
error: await handle_error_and_jsonify(event, state, options, error)
|
|
34
35
|
})
|
|
35
36
|
)
|
|
36
37
|
.then(
|
|
@@ -44,7 +45,7 @@ export function server_data_serializer(event, event_state, options) {
|
|
|
44
45
|
} catch (e) {
|
|
45
46
|
error = await handle_error_and_jsonify(
|
|
46
47
|
event,
|
|
47
|
-
|
|
48
|
+
state,
|
|
48
49
|
options,
|
|
49
50
|
new Error(`Failed to serialize promise while rendering ${event.route.id}`, {
|
|
50
51
|
cause: e
|
|
@@ -64,8 +65,8 @@ export function server_data_serializer(event, event_state, options) {
|
|
|
64
65
|
|
|
65
66
|
return `${global}.defer(${id})`;
|
|
66
67
|
} else {
|
|
67
|
-
for (const key in
|
|
68
|
-
const encoded =
|
|
68
|
+
for (const key in encoders) {
|
|
69
|
+
const encoded = encoders[key](thing);
|
|
69
70
|
if (encoded) {
|
|
70
71
|
return `app.decode('${key}', ${devalue.uneval(encoded, replacer)})`;
|
|
71
72
|
}
|
|
@@ -125,19 +126,17 @@ export function server_data_serializer(event, event_state, options) {
|
|
|
125
126
|
* If the serialized data contains promises, `chunks` will be an
|
|
126
127
|
* async iterable containing their resolutions
|
|
127
128
|
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
128
|
-
* @param {import('types').RequestState}
|
|
129
|
+
* @param {import('types').RequestState} state
|
|
129
130
|
* @param {import('types').SSROptions} options
|
|
130
131
|
* @returns {import('./types.js').ServerDataSerializerJson}
|
|
131
132
|
*/
|
|
132
|
-
export function server_data_serializer_json(event,
|
|
133
|
+
export function server_data_serializer_json(event, state, options) {
|
|
133
134
|
let promise_id = 1;
|
|
134
135
|
|
|
135
136
|
const iterator = create_async_iterator();
|
|
136
137
|
|
|
137
138
|
const reducers = {
|
|
138
|
-
...
|
|
139
|
-
Object.entries(options.hooks.transport).map(([key, value]) => [key, value.encode])
|
|
140
|
-
),
|
|
139
|
+
...encoders,
|
|
141
140
|
/** @param {any} thing */
|
|
142
141
|
Promise: (thing) => {
|
|
143
142
|
if (typeof thing?.then !== 'function') {
|
|
@@ -153,7 +152,7 @@ export function server_data_serializer_json(event, event_state, options) {
|
|
|
153
152
|
.catch(
|
|
154
153
|
/** @param {any} e */ async (e) => {
|
|
155
154
|
key = 'error';
|
|
156
|
-
return handle_error_and_jsonify(event,
|
|
155
|
+
return handle_error_and_jsonify(event, state, options, /** @type {any} */ (e));
|
|
157
156
|
}
|
|
158
157
|
)
|
|
159
158
|
.then(
|
|
@@ -165,7 +164,7 @@ export function server_data_serializer_json(event, event_state, options) {
|
|
|
165
164
|
} catch (e) {
|
|
166
165
|
const error = await handle_error_and_jsonify(
|
|
167
166
|
event,
|
|
168
|
-
|
|
167
|
+
state,
|
|
169
168
|
options,
|
|
170
169
|
new Error(`Failed to serialize promise while rendering ${event.route.id}`, {
|
|
171
170
|
cause: e
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @import { Component } from 'svelte' */
|
|
2
2
|
/** @import { ActionResult, RequestEvent, SSRManifest } from '@sveltejs/kit' */
|
|
3
|
-
/** @import { PageNodeIndexes, RequestState, RequiredResolveOptions, ServerDataNode, SSRNode, SSROptions
|
|
3
|
+
/** @import { PageNodeIndexes, RequestState, RequiredResolveOptions, ServerDataNode, SSRNode, SSROptions } from 'types' */
|
|
4
4
|
import { text } from '@sveltejs/kit';
|
|
5
5
|
import { Redirect } from '@sveltejs/kit/internal';
|
|
6
6
|
import { compact } from '../../../utils/array.js';
|
|
@@ -30,25 +30,15 @@ const MAX_DEPTH = 10;
|
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* @param {RequestEvent} event
|
|
33
|
-
* @param {RequestState}
|
|
33
|
+
* @param {RequestState} state
|
|
34
34
|
* @param {PageNodeIndexes} page
|
|
35
35
|
* @param {SSROptions} options
|
|
36
36
|
* @param {SSRManifest} manifest
|
|
37
|
-
* @param {SSRState} state
|
|
38
37
|
* @param {import('../../../utils/page_nodes.js').PageNodes} nodes
|
|
39
38
|
* @param {RequiredResolveOptions} resolve_opts
|
|
40
39
|
* @returns {Promise<Response>}
|
|
41
40
|
*/
|
|
42
|
-
export async function render_page(
|
|
43
|
-
event,
|
|
44
|
-
event_state,
|
|
45
|
-
page,
|
|
46
|
-
options,
|
|
47
|
-
manifest,
|
|
48
|
-
state,
|
|
49
|
-
nodes,
|
|
50
|
-
resolve_opts
|
|
51
|
-
) {
|
|
41
|
+
export async function render_page(event, state, page, options, manifest, nodes, resolve_opts) {
|
|
52
42
|
if (state.depth > MAX_DEPTH) {
|
|
53
43
|
// infinite request cycle detected
|
|
54
44
|
return text(`Not found: ${event.url.pathname}`, {
|
|
@@ -58,7 +48,7 @@ export async function render_page(
|
|
|
58
48
|
|
|
59
49
|
if (is_action_json_request(event)) {
|
|
60
50
|
const node = await manifest._.nodes[page.leaf]();
|
|
61
|
-
return handle_action_json_request(event,
|
|
51
|
+
return handle_action_json_request(event, state, options, node?.server);
|
|
62
52
|
}
|
|
63
53
|
|
|
64
54
|
try {
|
|
@@ -72,11 +62,11 @@ export async function render_page(
|
|
|
72
62
|
if (is_action_request(event)) {
|
|
73
63
|
const remote_id = get_remote_action(event.url);
|
|
74
64
|
if (remote_id) {
|
|
75
|
-
action_result = await handle_remote_form_post(event,
|
|
65
|
+
action_result = await handle_remote_form_post(event, state, manifest, remote_id);
|
|
76
66
|
} else {
|
|
77
67
|
// for action requests, first call handler in +page.server.js
|
|
78
68
|
// (this also determines status code)
|
|
79
|
-
action_result = await handle_action_request(event,
|
|
69
|
+
action_result = await handle_action_request(event, state, leaf_node.server);
|
|
80
70
|
}
|
|
81
71
|
|
|
82
72
|
if (action_result?.type === 'redirect') {
|
|
@@ -156,12 +146,11 @@ export async function render_page(
|
|
|
156
146
|
status,
|
|
157
147
|
error: null,
|
|
158
148
|
event,
|
|
159
|
-
|
|
149
|
+
state,
|
|
160
150
|
options,
|
|
161
151
|
manifest,
|
|
162
|
-
state,
|
|
163
152
|
resolve_opts,
|
|
164
|
-
data_serializer: server_data_serializer(event,
|
|
153
|
+
data_serializer: server_data_serializer(event, state, options)
|
|
165
154
|
});
|
|
166
155
|
}
|
|
167
156
|
|
|
@@ -171,10 +160,10 @@ export async function render_page(
|
|
|
171
160
|
/** @type {Error | null} */
|
|
172
161
|
let load_error = null;
|
|
173
162
|
|
|
174
|
-
const data_serializer = server_data_serializer(event,
|
|
163
|
+
const data_serializer = server_data_serializer(event, state, options);
|
|
175
164
|
const data_serializer_json =
|
|
176
165
|
state.prerendering && should_prerender_data
|
|
177
|
-
? server_data_serializer_json(event,
|
|
166
|
+
? server_data_serializer_json(event, state, options)
|
|
178
167
|
: null;
|
|
179
168
|
|
|
180
169
|
/** @type {Array<Promise<ServerDataNode | null>>} */
|
|
@@ -194,7 +183,6 @@ export async function render_page(
|
|
|
194
183
|
|
|
195
184
|
const server_data = await load_server_data({
|
|
196
185
|
event,
|
|
197
|
-
event_state,
|
|
198
186
|
state,
|
|
199
187
|
node,
|
|
200
188
|
parent: async () => {
|
|
@@ -229,7 +217,7 @@ export async function render_page(
|
|
|
229
217
|
try {
|
|
230
218
|
return await load_data({
|
|
231
219
|
event,
|
|
232
|
-
|
|
220
|
+
state,
|
|
233
221
|
fetched,
|
|
234
222
|
node,
|
|
235
223
|
parent: async () => {
|
|
@@ -241,7 +229,6 @@ export async function render_page(
|
|
|
241
229
|
},
|
|
242
230
|
resolve_opts,
|
|
243
231
|
server_data_promise: server_promises[i],
|
|
244
|
-
state,
|
|
245
232
|
csr
|
|
246
233
|
});
|
|
247
234
|
} catch (e) {
|
|
@@ -284,7 +271,7 @@ export async function render_page(
|
|
|
284
271
|
return redirect_response(err.status, err.location);
|
|
285
272
|
}
|
|
286
273
|
|
|
287
|
-
const error = await handle_error_and_jsonify(event,
|
|
274
|
+
const error = await handle_error_and_jsonify(event, state, options, err);
|
|
288
275
|
const status = error.status;
|
|
289
276
|
|
|
290
277
|
while (i--) {
|
|
@@ -307,10 +294,9 @@ export async function render_page(
|
|
|
307
294
|
|
|
308
295
|
return await render_response({
|
|
309
296
|
event,
|
|
310
|
-
|
|
297
|
+
state,
|
|
311
298
|
options,
|
|
312
299
|
manifest,
|
|
313
|
-
state,
|
|
314
300
|
resolve_opts,
|
|
315
301
|
page_config: {
|
|
316
302
|
ssr: nodes.ssr(),
|
|
@@ -355,10 +341,9 @@ export async function render_page(
|
|
|
355
341
|
|
|
356
342
|
return await render_response({
|
|
357
343
|
event,
|
|
358
|
-
|
|
344
|
+
state,
|
|
359
345
|
options,
|
|
360
346
|
manifest,
|
|
361
|
-
state,
|
|
362
347
|
resolve_opts,
|
|
363
348
|
page_config: {
|
|
364
349
|
csr,
|
|
@@ -369,7 +354,7 @@ export async function render_page(
|
|
|
369
354
|
branch: compact(branch),
|
|
370
355
|
action_result,
|
|
371
356
|
fetched,
|
|
372
|
-
data_serializer: !ssr ? server_data_serializer(event,
|
|
357
|
+
data_serializer: !ssr ? server_data_serializer(event, state, options) : data_serializer,
|
|
373
358
|
error_components: await load_error_components(ssr, branch, page, manifest)
|
|
374
359
|
});
|
|
375
360
|
} catch (e) {
|
|
@@ -382,10 +367,9 @@ export async function render_page(
|
|
|
382
367
|
// but the page failed to render, or that a prerendering error occurred
|
|
383
368
|
return await respond_with_error({
|
|
384
369
|
event,
|
|
385
|
-
|
|
370
|
+
state,
|
|
386
371
|
options,
|
|
387
372
|
manifest,
|
|
388
|
-
state,
|
|
389
373
|
error: e,
|
|
390
374
|
resolve_opts
|
|
391
375
|
});
|
|
@@ -12,14 +12,13 @@ import { get_node_type } from '../utils.js';
|
|
|
12
12
|
* Calls the user's server `load` function.
|
|
13
13
|
* @param {{
|
|
14
14
|
* event: import('@sveltejs/kit').RequestEvent;
|
|
15
|
-
*
|
|
16
|
-
* state: import('types').SSRState;
|
|
15
|
+
* state: import('types').RequestState;
|
|
17
16
|
* node: import('types').SSRNode | undefined;
|
|
18
17
|
* parent: () => Promise<Record<string, any>>;
|
|
19
18
|
* }} opts
|
|
20
19
|
* @returns {Promise<import('types').ServerDataNode | null>}
|
|
21
20
|
*/
|
|
22
|
-
export async function load_server_data({ event,
|
|
21
|
+
export async function load_server_data({ event, state, node, parent }) {
|
|
23
22
|
if (!node?.server) return null;
|
|
24
23
|
|
|
25
24
|
let is_tracking = true;
|
|
@@ -83,7 +82,7 @@ export async function load_server_data({ event, event_state, state, node, parent
|
|
|
83
82
|
},
|
|
84
83
|
fn: async (current) => {
|
|
85
84
|
const traced_event = merge_tracing(event, current);
|
|
86
|
-
const result = await with_request_store({ event: traced_event, state
|
|
85
|
+
const result = await with_request_store({ event: traced_event, state }, () =>
|
|
87
86
|
load.call(null, {
|
|
88
87
|
...traced_event,
|
|
89
88
|
fetch: (info, init) => {
|
|
@@ -194,25 +193,23 @@ export async function load_server_data({ event, event_state, state, node, parent
|
|
|
194
193
|
* Calls the user's `load` function.
|
|
195
194
|
* @param {{
|
|
196
195
|
* event: import('@sveltejs/kit').RequestEvent;
|
|
197
|
-
*
|
|
196
|
+
* state: import('types').RequestState;
|
|
198
197
|
* fetched: import('./types.js').Fetched[];
|
|
199
198
|
* node: import('types').SSRNode | undefined;
|
|
200
199
|
* parent: () => Promise<Record<string, any>>;
|
|
201
200
|
* resolve_opts: import('types').RequiredResolveOptions;
|
|
202
201
|
* server_data_promise: Promise<import('types').ServerDataNode | null>;
|
|
203
|
-
* state: import('types').SSRState;
|
|
204
202
|
* csr: boolean;
|
|
205
203
|
* }} opts
|
|
206
204
|
* @returns {Promise<Record<string, any | Promise<any>> | null>}
|
|
207
205
|
*/
|
|
208
206
|
export async function load_data({
|
|
209
207
|
event,
|
|
210
|
-
|
|
208
|
+
state,
|
|
211
209
|
fetched,
|
|
212
210
|
node,
|
|
213
211
|
parent,
|
|
214
212
|
server_data_promise,
|
|
215
|
-
state,
|
|
216
213
|
resolve_opts,
|
|
217
214
|
csr
|
|
218
215
|
}) {
|
|
@@ -234,15 +231,14 @@ export async function load_data({
|
|
|
234
231
|
},
|
|
235
232
|
fn: async (current) => {
|
|
236
233
|
const traced_event = merge_tracing(event, current);
|
|
237
|
-
const child_state = { ...event_state, is_in_universal_load: true };
|
|
238
234
|
|
|
239
|
-
return await with_request_store({ event: traced_event, state
|
|
235
|
+
return await with_request_store({ event: traced_event, state }, () =>
|
|
240
236
|
load.call(null, {
|
|
241
237
|
url: event.url,
|
|
242
238
|
params: event.params,
|
|
243
239
|
data: server_data_node?.data ?? null,
|
|
244
240
|
route: event.route,
|
|
245
|
-
fetch: create_universal_fetch(event, state, fetched, csr, resolve_opts),
|
|
241
|
+
fetch: create_universal_fetch(event, state.prerendering, fetched, csr, resolve_opts),
|
|
246
242
|
setHeaders: event.setHeaders,
|
|
247
243
|
depends: noop,
|
|
248
244
|
parent,
|
|
@@ -262,13 +258,13 @@ export async function load_data({
|
|
|
262
258
|
|
|
263
259
|
/**
|
|
264
260
|
* @param {Pick<import('@sveltejs/kit').RequestEvent, 'fetch' | 'url' | 'request' | 'route'>} event
|
|
265
|
-
* @param {import('types').
|
|
261
|
+
* @param {import('types').PrerenderOptions | undefined} prerendering
|
|
266
262
|
* @param {import('./types.js').Fetched[]} fetched
|
|
267
263
|
* @param {boolean} csr
|
|
268
264
|
* @param {Pick<Required<import('@sveltejs/kit').ResolveOptions>, 'filterSerializedResponseHeaders'>} resolve_opts
|
|
269
265
|
* @returns {typeof fetch}
|
|
270
266
|
*/
|
|
271
|
-
export function create_universal_fetch(event,
|
|
267
|
+
export function create_universal_fetch(event, prerendering, fetched, csr, resolve_opts) {
|
|
272
268
|
/**
|
|
273
269
|
* @param {URL | RequestInfo} input
|
|
274
270
|
* @param {RequestInit} [init]
|
|
@@ -290,9 +286,9 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts)
|
|
|
290
286
|
let dependency;
|
|
291
287
|
|
|
292
288
|
if (same_origin) {
|
|
293
|
-
if (
|
|
289
|
+
if (prerendering) {
|
|
294
290
|
dependency = { response, body: null };
|
|
295
|
-
|
|
291
|
+
prerendering.dependencies.set(url.pathname, dependency);
|
|
296
292
|
}
|
|
297
293
|
} else if (url.protocol === 'https:' || url.protocol === 'http:') {
|
|
298
294
|
// simulate CORS errors and "no access to body in no-cors mode" server-side for consistency with client-side behaviour
|
|
@@ -336,7 +332,7 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts)
|
|
|
336
332
|
|
|
337
333
|
const request_body =
|
|
338
334
|
input instanceof Request && cloned_body
|
|
339
|
-
? await
|
|
335
|
+
? await new Response(cloned_body).text()
|
|
340
336
|
: init?.body;
|
|
341
337
|
|
|
342
338
|
if (
|
|
@@ -371,16 +367,7 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts)
|
|
|
371
367
|
const [a, b] = response.body.tee();
|
|
372
368
|
|
|
373
369
|
void (async () => {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
for await (const chunk of a) {
|
|
377
|
-
const combined = new Uint8Array(result.length + chunk.length);
|
|
378
|
-
|
|
379
|
-
combined.set(result, 0);
|
|
380
|
-
combined.set(chunk, result.length);
|
|
381
|
-
|
|
382
|
-
result = combined;
|
|
383
|
-
}
|
|
370
|
+
const result = new Uint8Array(await new Response(a).arrayBuffer());
|
|
384
371
|
|
|
385
372
|
if (dependency) {
|
|
386
373
|
dependency.body = new Uint8Array(result);
|
|
@@ -482,6 +469,21 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts)
|
|
|
482
469
|
|
|
483
470
|
return value;
|
|
484
471
|
};
|
|
472
|
+
|
|
473
|
+
const get_set_cookie = response.headers.getSetCookie;
|
|
474
|
+
response.headers.getSetCookie = () => {
|
|
475
|
+
const values = get_set_cookie.call(response.headers);
|
|
476
|
+
for (const value of values) {
|
|
477
|
+
const included = resolve_opts.filterSerializedResponseHeaders('set-cookie', value);
|
|
478
|
+
if (!included) {
|
|
479
|
+
throw new Error(
|
|
480
|
+
`Failed to get response header "set-cookie" — it must be included by the \`filterSerializedResponseHeaders\` option: https://svelte.dev/docs/kit/hooks#handle (at ${event.route.id})`
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
return values;
|
|
486
|
+
};
|
|
485
487
|
}
|
|
486
488
|
|
|
487
489
|
return proxy;
|
|
@@ -496,21 +498,3 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts)
|
|
|
496
498
|
return response;
|
|
497
499
|
};
|
|
498
500
|
}
|
|
499
|
-
|
|
500
|
-
/**
|
|
501
|
-
* @param {ReadableStream<Uint8Array>} stream
|
|
502
|
-
*/
|
|
503
|
-
async function stream_to_string(stream) {
|
|
504
|
-
let result = '';
|
|
505
|
-
const reader = stream.getReader();
|
|
506
|
-
const decoder = new TextDecoder();
|
|
507
|
-
while (true) {
|
|
508
|
-
const { done, value } = await reader.read();
|
|
509
|
-
if (done) {
|
|
510
|
-
result += decoder.decode();
|
|
511
|
-
break;
|
|
512
|
-
}
|
|
513
|
-
result += decoder.decode(value, { stream: true });
|
|
514
|
-
}
|
|
515
|
-
return result;
|
|
516
|
-
}
|