@sveltejs/kit 1.0.0-next.561 → 1.0.0-next.563
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/adapt/builder.js +4 -10
- package/src/core/generate_manifest/index.js +3 -10
- package/src/exports/vite/dev/index.js +21 -20
- package/src/runtime/client/client.js +14 -10
- package/src/runtime/server/data/index.js +16 -9
- package/src/runtime/server/index.js +17 -4
- package/src/runtime/server/page/actions.js +1 -1
- package/src/runtime/server/page/index.js +1 -1
- package/src/runtime/server/page/respond_with_error.js +2 -2
- package/src/runtime/server/utils.js +3 -3
- package/types/index.d.ts +11 -4
- package/types/internal.d.ts +1 -1
- package/types/private.d.ts +1 -3
package/package.json
CHANGED
|
@@ -93,24 +93,22 @@ export function create_builder({ config, build_data, routes, prerendered, log })
|
|
|
93
93
|
|
|
94
94
|
if (filtered.size > 0) {
|
|
95
95
|
await complete({
|
|
96
|
-
generateManifest: ({ relativePath
|
|
96
|
+
generateManifest: ({ relativePath }) =>
|
|
97
97
|
generate_manifest({
|
|
98
98
|
build_data,
|
|
99
99
|
relative_path: relativePath,
|
|
100
|
-
routes: Array.from(filtered)
|
|
101
|
-
format
|
|
100
|
+
routes: Array.from(filtered)
|
|
102
101
|
})
|
|
103
102
|
});
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
105
|
},
|
|
107
106
|
|
|
108
|
-
generateManifest: ({ relativePath
|
|
107
|
+
generateManifest: ({ relativePath }) => {
|
|
109
108
|
return generate_manifest({
|
|
110
109
|
build_data,
|
|
111
110
|
relative_path: relativePath,
|
|
112
|
-
routes
|
|
113
|
-
format
|
|
111
|
+
routes
|
|
114
112
|
});
|
|
115
113
|
},
|
|
116
114
|
|
|
@@ -126,10 +124,6 @@ export function create_builder({ config, build_data, routes, prerendered, log })
|
|
|
126
124
|
return `${config.kit.outDir}/output/server`;
|
|
127
125
|
},
|
|
128
126
|
|
|
129
|
-
getStaticDirectory() {
|
|
130
|
-
return config.kit.files.assets;
|
|
131
|
-
},
|
|
132
|
-
|
|
133
127
|
getAppPath() {
|
|
134
128
|
return build_data.app_path;
|
|
135
129
|
},
|
|
@@ -11,10 +11,9 @@ import { join_relative } from '../../utils/filesystem.js';
|
|
|
11
11
|
* build_data: import('types').BuildData;
|
|
12
12
|
* relative_path: string;
|
|
13
13
|
* routes: import('types').RouteData[];
|
|
14
|
-
* format?: 'esm' | 'cjs'
|
|
15
14
|
* }} opts
|
|
16
15
|
*/
|
|
17
|
-
export function generate_manifest({ build_data, relative_path, routes
|
|
16
|
+
export function generate_manifest({ build_data, relative_path, routes }) {
|
|
18
17
|
/**
|
|
19
18
|
* @type {Map<any, number>} The new index of each node in the filtered nodes array
|
|
20
19
|
*/
|
|
@@ -55,13 +54,7 @@ export function generate_manifest({ build_data, relative_path, routes, format =
|
|
|
55
54
|
});
|
|
56
55
|
|
|
57
56
|
/** @type {(path: string) => string} */
|
|
58
|
-
const
|
|
59
|
-
format === 'esm'
|
|
60
|
-
? (path) => `import('${path}')`
|
|
61
|
-
: (path) => `Promise.resolve().then(() => require('${path}'))`;
|
|
62
|
-
|
|
63
|
-
/** @type {(path: string) => string} */
|
|
64
|
-
const loader = (path) => `() => ${load(path)}`;
|
|
57
|
+
const loader = (path) => `() => import('${path}')`;
|
|
65
58
|
|
|
66
59
|
const assets = build_data.manifest_data.assets.map((asset) => asset.file);
|
|
67
60
|
if (build_data.service_worker) {
|
|
@@ -115,7 +108,7 @@ export function generate_manifest({ build_data, relative_path, routes, format =
|
|
|
115
108
|
}).filter(Boolean).join(',\n\t\t\t\t')}
|
|
116
109
|
],
|
|
117
110
|
matchers: async () => {
|
|
118
|
-
${Array.from(matchers).map(type => `const { match: ${type} } = await ${
|
|
111
|
+
${Array.from(matchers).map(type => `const { match: ${type} } = await import ('${(join_relative(relative_path, `/entries/matchers/${type}.js`))}')`).join('\n\t\t\t\t')}
|
|
119
112
|
return { ${Array.from(matchers).join(', ')} };
|
|
120
113
|
}
|
|
121
114
|
}
|
|
@@ -426,28 +426,29 @@ export async function dev(vite, vite_config, svelte_config) {
|
|
|
426
426
|
check_origin: svelte_config.kit.csrf.checkOrigin
|
|
427
427
|
},
|
|
428
428
|
dev: true,
|
|
429
|
-
handle_error: (error, event) => {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
return fix_stack_trace(error);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
return Reflect.get(target, property, target);
|
|
429
|
+
handle_error: async (error, event) => {
|
|
430
|
+
const error_object = await hooks.handleError({
|
|
431
|
+
error: new Proxy(error, {
|
|
432
|
+
get: (target, property) => {
|
|
433
|
+
if (property === 'stack') {
|
|
434
|
+
return fix_stack_trace(error);
|
|
439
435
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
// TODO remove for 1.0
|
|
444
|
-
// @ts-expect-error
|
|
445
|
-
get request() {
|
|
446
|
-
throw new Error(
|
|
447
|
-
'request in handleError has been replaced with event. See https://github.com/sveltejs/kit/pull/3384 for details'
|
|
448
|
-
);
|
|
436
|
+
|
|
437
|
+
return Reflect.get(target, property, target);
|
|
449
438
|
}
|
|
450
|
-
})
|
|
439
|
+
}),
|
|
440
|
+
event,
|
|
441
|
+
|
|
442
|
+
// TODO remove for 1.0
|
|
443
|
+
// @ts-expect-error
|
|
444
|
+
get request() {
|
|
445
|
+
throw new Error(
|
|
446
|
+
'request in handleError has been replaced with event. See https://github.com/sveltejs/kit/pull/3384 for details'
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
return (
|
|
451
|
+
error_object ?? { message: event.route.id != null ? 'Internal Error' : 'Not Found' }
|
|
451
452
|
);
|
|
452
453
|
},
|
|
453
454
|
hooks,
|
|
@@ -248,7 +248,7 @@ export function create_client({ target, base }) {
|
|
|
248
248
|
navigation_result = await server_fallback(
|
|
249
249
|
url,
|
|
250
250
|
{ id: null },
|
|
251
|
-
handle_error(new Error(`Not found: ${url.pathname}`), {
|
|
251
|
+
await handle_error(new Error(`Not found: ${url.pathname}`), {
|
|
252
252
|
url,
|
|
253
253
|
params: {},
|
|
254
254
|
route: { id: null }
|
|
@@ -268,7 +268,11 @@ export function create_client({ target, base }) {
|
|
|
268
268
|
if (redirect_chain.length > 10 || redirect_chain.includes(url.pathname)) {
|
|
269
269
|
navigation_result = await load_root_error_page({
|
|
270
270
|
status: 500,
|
|
271
|
-
error: handle_error(new Error('Redirect loop'), {
|
|
271
|
+
error: await handle_error(new Error('Redirect loop'), {
|
|
272
|
+
url,
|
|
273
|
+
params: {},
|
|
274
|
+
route: { id: null }
|
|
275
|
+
}),
|
|
272
276
|
url,
|
|
273
277
|
route: { id: null }
|
|
274
278
|
});
|
|
@@ -770,7 +774,7 @@ export function create_client({ target, base }) {
|
|
|
770
774
|
} catch (error) {
|
|
771
775
|
return load_root_error_page({
|
|
772
776
|
status: 500,
|
|
773
|
-
error: handle_error(error, { url, params, route: { id: route.id } }),
|
|
777
|
+
error: await handle_error(error, { url, params, route: { id: route.id } }),
|
|
774
778
|
url,
|
|
775
779
|
route
|
|
776
780
|
});
|
|
@@ -859,7 +863,7 @@ export function create_client({ target, base }) {
|
|
|
859
863
|
status = err.status;
|
|
860
864
|
error = err.body;
|
|
861
865
|
} else {
|
|
862
|
-
error = handle_error(err, { params, url, route: { id: route.id } });
|
|
866
|
+
error = await handle_error(err, { params, url, route: { id: route.id } });
|
|
863
867
|
}
|
|
864
868
|
|
|
865
869
|
const error_load = await load_nearest_error_page(i, branch, errors);
|
|
@@ -1385,7 +1389,7 @@ export function create_client({ target, base }) {
|
|
|
1385
1389
|
}, 20);
|
|
1386
1390
|
};
|
|
1387
1391
|
|
|
1388
|
-
target.addEventListener('touchstart', trigger_prefetch);
|
|
1392
|
+
target.addEventListener('touchstart', trigger_prefetch, { passive: true });
|
|
1389
1393
|
target.addEventListener('mousemove', handle_mousemove);
|
|
1390
1394
|
target.addEventListener('sveltekit:trigger_prefetch', trigger_prefetch);
|
|
1391
1395
|
|
|
@@ -1567,7 +1571,7 @@ export function create_client({ target, base }) {
|
|
|
1567
1571
|
|
|
1568
1572
|
result = await load_root_error_page({
|
|
1569
1573
|
status: error instanceof HttpError ? error.status : 500,
|
|
1570
|
-
error: handle_error(error, { url, params, route }),
|
|
1574
|
+
error: await handle_error(error, { url, params, route }),
|
|
1571
1575
|
url,
|
|
1572
1576
|
route
|
|
1573
1577
|
});
|
|
@@ -1619,7 +1623,7 @@ async function load_data(url, invalid) {
|
|
|
1619
1623
|
/**
|
|
1620
1624
|
* @param {unknown} error
|
|
1621
1625
|
* @param {import('types').NavigationEvent} event
|
|
1622
|
-
* @returns {App.Error}
|
|
1626
|
+
* @returns {import('../../../types/private.js').MaybePromise<App.Error>}
|
|
1623
1627
|
*/
|
|
1624
1628
|
function handle_error(error, event) {
|
|
1625
1629
|
if (error instanceof HttpError) {
|
|
@@ -1717,8 +1721,8 @@ function reset_focus() {
|
|
|
1717
1721
|
|
|
1718
1722
|
if (__SVELTEKIT_DEV__) {
|
|
1719
1723
|
// Nasty hack to silence harmless warnings the user can do nothing about
|
|
1720
|
-
const
|
|
1721
|
-
console.warn = (...args)
|
|
1724
|
+
const console_warn = console.warn;
|
|
1725
|
+
console.warn = function warn(...args) {
|
|
1722
1726
|
if (
|
|
1723
1727
|
args.length === 1 &&
|
|
1724
1728
|
/<(Layout|Page)(_[\w$]+)?> was created (with unknown|without expected) prop '(data|form)'/.test(
|
|
@@ -1727,6 +1731,6 @@ if (__SVELTEKIT_DEV__) {
|
|
|
1727
1731
|
) {
|
|
1728
1732
|
return;
|
|
1729
1733
|
}
|
|
1730
|
-
|
|
1734
|
+
console_warn(...args);
|
|
1731
1735
|
};
|
|
1732
1736
|
}
|
|
@@ -87,7 +87,7 @@ export async function render_data(event, route, options, state, trailing_slash)
|
|
|
87
87
|
let length = promises.length;
|
|
88
88
|
const nodes = await Promise.all(
|
|
89
89
|
promises.map((p, i) =>
|
|
90
|
-
p.catch((error) => {
|
|
90
|
+
p.catch(async (error) => {
|
|
91
91
|
if (error instanceof Redirect) {
|
|
92
92
|
throw error;
|
|
93
93
|
}
|
|
@@ -97,7 +97,7 @@ export async function render_data(event, route, options, state, trailing_slash)
|
|
|
97
97
|
|
|
98
98
|
return /** @type {import('types').ServerErrorNode} */ ({
|
|
99
99
|
type: 'error',
|
|
100
|
-
error: handle_error_and_jsonify(event, options, error),
|
|
100
|
+
error: await handle_error_and_jsonify(event, options, error),
|
|
101
101
|
status: error instanceof HttpError ? error.status : undefined
|
|
102
102
|
});
|
|
103
103
|
})
|
|
@@ -117,15 +117,10 @@ export async function render_data(event, route, options, state, trailing_slash)
|
|
|
117
117
|
const error = normalize_error(e);
|
|
118
118
|
|
|
119
119
|
if (error instanceof Redirect) {
|
|
120
|
-
return
|
|
121
|
-
JSON.stringify({
|
|
122
|
-
type: 'redirect',
|
|
123
|
-
location: error.location
|
|
124
|
-
})
|
|
125
|
-
);
|
|
120
|
+
return redirect_json_response(error);
|
|
126
121
|
} else {
|
|
127
122
|
// TODO make it clearer that this was an unexpected error
|
|
128
|
-
return json_response(JSON.stringify(handle_error_and_jsonify(event, options, error)));
|
|
123
|
+
return json_response(JSON.stringify(await handle_error_and_jsonify(event, options, error)));
|
|
129
124
|
}
|
|
130
125
|
}
|
|
131
126
|
}
|
|
@@ -143,3 +138,15 @@ function json_response(json, status = 200) {
|
|
|
143
138
|
}
|
|
144
139
|
});
|
|
145
140
|
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @param {Redirect} redirect
|
|
144
|
+
*/
|
|
145
|
+
export function redirect_json_response(redirect) {
|
|
146
|
+
return json_response(
|
|
147
|
+
JSON.stringify({
|
|
148
|
+
type: 'redirect',
|
|
149
|
+
location: redirect.location
|
|
150
|
+
})
|
|
151
|
+
);
|
|
152
|
+
}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
strip_data_suffix
|
|
14
14
|
} from '../../utils/url.js';
|
|
15
15
|
import { exec } from '../../utils/routing.js';
|
|
16
|
-
import { INVALIDATED_HEADER, render_data } from './data/index.js';
|
|
16
|
+
import { INVALIDATED_HEADER, redirect_json_response, render_data } from './data/index.js';
|
|
17
17
|
import { add_cookies_to_headers, get_cookies } from './cookie.js';
|
|
18
18
|
import { create_fetch } from './fetch.js';
|
|
19
19
|
import { Redirect } from '../control.js';
|
|
@@ -289,12 +289,25 @@ export async function respond(request, options, state) {
|
|
|
289
289
|
}
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
+
// Edge case: If user does `return Response(30x)` in handle hook while processing a data request,
|
|
293
|
+
// we need to transform the redirect response to a corresponding JSON response.
|
|
294
|
+
if (is_data_request && response.status >= 300 && response.status <= 308) {
|
|
295
|
+
const location = response.headers.get('location');
|
|
296
|
+
if (location) {
|
|
297
|
+
return redirect_json_response(new Redirect(/** @type {any} */ (response.status), location));
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
292
301
|
return response;
|
|
293
302
|
} catch (error) {
|
|
294
303
|
if (error instanceof Redirect) {
|
|
295
|
-
|
|
304
|
+
if (is_data_request) {
|
|
305
|
+
return redirect_json_response(error);
|
|
306
|
+
} else {
|
|
307
|
+
return redirect_response(error.status, error.location);
|
|
308
|
+
}
|
|
296
309
|
}
|
|
297
|
-
return handle_fatal_error(event, options, error);
|
|
310
|
+
return await handle_fatal_error(event, options, error);
|
|
298
311
|
}
|
|
299
312
|
|
|
300
313
|
/**
|
|
@@ -386,7 +399,7 @@ export async function respond(request, options, state) {
|
|
|
386
399
|
return await fetch(request);
|
|
387
400
|
} catch (error) {
|
|
388
401
|
// HttpError from endpoint can end up here - TODO should it be handled there instead?
|
|
389
|
-
return handle_fatal_error(event, options, error);
|
|
402
|
+
return await handle_fatal_error(event, options, error);
|
|
390
403
|
} finally {
|
|
391
404
|
event.cookies.set = () => {
|
|
392
405
|
throw new Error('Cannot use `cookies.set(...)` after the response has been generated');
|
|
@@ -72,7 +72,7 @@ export async function handle_action_json_request(event, options, server) {
|
|
|
72
72
|
return action_json(
|
|
73
73
|
{
|
|
74
74
|
type: 'error',
|
|
75
|
-
error: handle_error_and_jsonify(event, options, check_incorrect_invalid_use(error))
|
|
75
|
+
error: await handle_error_and_jsonify(event, options, check_incorrect_invalid_use(error))
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
status: error instanceof HttpError ? error.status : 500
|
|
@@ -223,7 +223,7 @@ export async function render_page(event, route, page, options, state, resolve_op
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
const status = err instanceof HttpError ? err.status : 500;
|
|
226
|
-
const error = handle_error_and_jsonify(event, options, err);
|
|
226
|
+
const error = await handle_error_and_jsonify(event, options, err);
|
|
227
227
|
|
|
228
228
|
while (i--) {
|
|
229
229
|
if (page.errors[i]) {
|
|
@@ -80,7 +80,7 @@ export async function respond_with_error({ event, options, state, status, error,
|
|
|
80
80
|
csr: get_option([default_layout], 'csr') ?? true
|
|
81
81
|
},
|
|
82
82
|
status,
|
|
83
|
-
error: handle_error_and_jsonify(event, options, error),
|
|
83
|
+
error: await handle_error_and_jsonify(event, options, error),
|
|
84
84
|
branch,
|
|
85
85
|
fetched,
|
|
86
86
|
event,
|
|
@@ -96,7 +96,7 @@ export async function respond_with_error({ event, options, state, status, error,
|
|
|
96
96
|
return static_error_page(
|
|
97
97
|
options,
|
|
98
98
|
error instanceof HttpError ? error.status : 500,
|
|
99
|
-
handle_error_and_jsonify(event, options, error).message
|
|
99
|
+
(await handle_error_and_jsonify(event, options, error)).message
|
|
100
100
|
);
|
|
101
101
|
}
|
|
102
102
|
}
|
|
@@ -113,10 +113,10 @@ export function static_error_page(options, status, message) {
|
|
|
113
113
|
* @param {import('types').SSROptions} options
|
|
114
114
|
* @param {unknown} error
|
|
115
115
|
*/
|
|
116
|
-
export function handle_fatal_error(event, options, error) {
|
|
116
|
+
export async function handle_fatal_error(event, options, error) {
|
|
117
117
|
error = error instanceof HttpError ? error : coalesce_to_error(error);
|
|
118
118
|
const status = error instanceof HttpError ? error.status : 500;
|
|
119
|
-
const body = handle_error_and_jsonify(event, options, error);
|
|
119
|
+
const body = await handle_error_and_jsonify(event, options, error);
|
|
120
120
|
|
|
121
121
|
// ideally we'd use sec-fetch-dest instead, but Safari — quelle surprise — doesn't support it
|
|
122
122
|
const type = negotiate(event.request.headers.get('accept') || 'text/html', [
|
|
@@ -138,7 +138,7 @@ export function handle_fatal_error(event, options, error) {
|
|
|
138
138
|
* @param {import('types').RequestEvent} event
|
|
139
139
|
* @param {import('types').SSROptions} options
|
|
140
140
|
* @param {any} error
|
|
141
|
-
* @returns {App.Error}
|
|
141
|
+
* @returns {import('types').MaybePromise<App.Error>}
|
|
142
142
|
*/
|
|
143
143
|
export function handle_error_and_jsonify(event, options, error) {
|
|
144
144
|
if (error instanceof HttpError) {
|
package/types/index.d.ts
CHANGED
|
@@ -72,12 +72,11 @@ export interface Builder {
|
|
|
72
72
|
*/
|
|
73
73
|
createEntries(fn: (route: RouteDefinition) => AdapterEntry): Promise<void>;
|
|
74
74
|
|
|
75
|
-
generateManifest(opts: { relativePath: string
|
|
75
|
+
generateManifest(opts: { relativePath: string }): string;
|
|
76
76
|
|
|
77
77
|
getBuildDirectory(name: string): string;
|
|
78
78
|
getClientDirectory(): string;
|
|
79
79
|
getServerDirectory(): string;
|
|
80
|
-
getStaticDirectory(): string;
|
|
81
80
|
/** The application path including any configured base path */
|
|
82
81
|
getAppPath(): string;
|
|
83
82
|
|
|
@@ -242,12 +241,20 @@ export interface Handle {
|
|
|
242
241
|
}): MaybePromise<Response>;
|
|
243
242
|
}
|
|
244
243
|
|
|
244
|
+
/**
|
|
245
|
+
* If an unexpected error is thrown during loading or rendering, this function will be called with the error and the event.
|
|
246
|
+
* Make sure that this function _never_ throws an error.
|
|
247
|
+
*/
|
|
245
248
|
export interface HandleServerError {
|
|
246
|
-
(input: { error: unknown; event: RequestEvent }): void | App.Error
|
|
249
|
+
(input: { error: unknown; event: RequestEvent }): MaybePromise<void | App.Error>;
|
|
247
250
|
}
|
|
248
251
|
|
|
252
|
+
/**
|
|
253
|
+
* If an unexpected error is thrown during loading or the following render, this function will be called with the error and the event.
|
|
254
|
+
* Make sure that this function _never_ throws an error.
|
|
255
|
+
*/
|
|
249
256
|
export interface HandleClientError {
|
|
250
|
-
(input: { error: unknown; event: NavigationEvent }): void | App.Error
|
|
257
|
+
(input: { error: unknown; event: NavigationEvent }): MaybePromise<void | App.Error>;
|
|
251
258
|
}
|
|
252
259
|
|
|
253
260
|
export interface HandleFetch {
|
package/types/internal.d.ts
CHANGED
|
@@ -298,7 +298,7 @@ export interface SSROptions {
|
|
|
298
298
|
check_origin: boolean;
|
|
299
299
|
};
|
|
300
300
|
dev: boolean;
|
|
301
|
-
handle_error(error: Error & { frame?: string }, event: RequestEvent): App.Error
|
|
301
|
+
handle_error(error: Error & { frame?: string }, event: RequestEvent): MaybePromise<App.Error>;
|
|
302
302
|
hooks: ServerHooks;
|
|
303
303
|
manifest: SSRManifest;
|
|
304
304
|
paths: {
|
package/types/private.d.ts
CHANGED
|
@@ -21,9 +21,7 @@ export interface AdapterEntry {
|
|
|
21
21
|
* A function that is invoked once the entry has been created. This is where you
|
|
22
22
|
* should write the function to the filesystem and generate redirect manifests.
|
|
23
23
|
*/
|
|
24
|
-
complete(entry: {
|
|
25
|
-
generateManifest(opts: { relativePath: string; format?: 'esm' | 'cjs' }): string;
|
|
26
|
-
}): MaybePromise<void>;
|
|
24
|
+
complete(entry: { generateManifest(opts: { relativePath: string }): string }): MaybePromise<void>;
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
// Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts
|