@sveltejs/kit 2.5.0 → 2.5.2
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 +3 -3
- package/src/core/sync/write_tsconfig.js +1 -0
- package/src/exports/index.js +15 -7
- package/src/exports/public.d.ts +6 -5
- package/src/runtime/client/client.js +22 -13
- package/src/version.js +1 -1
- package/types/index.d.ts +9 -8
- package/types/index.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/kit",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.2",
|
|
4
4
|
"description": "The fastest way to build Svelte apps",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"@types/set-cookie-parser": "^2.4.7",
|
|
34
34
|
"dts-buddy": "^0.4.3",
|
|
35
35
|
"rollup": "^4.9.5",
|
|
36
|
-
"svelte": "^4.2.
|
|
36
|
+
"svelte": "^4.2.10",
|
|
37
37
|
"svelte-preprocess": "^5.1.3",
|
|
38
38
|
"typescript": "^5.3.3",
|
|
39
|
-
"vite": "^5.0
|
|
39
|
+
"vite": "^5.1.0",
|
|
40
40
|
"vitest": "^1.2.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
package/src/exports/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { BROWSER, DEV } from 'esm-env';
|
|
|
3
3
|
|
|
4
4
|
export { VERSION } from '../version.js';
|
|
5
5
|
|
|
6
|
+
// TODO 3.0: remove these types as they are not used anymore (we can't remove them yet because that would be a breaking change)
|
|
6
7
|
/**
|
|
7
8
|
* @template {number} TNumber
|
|
8
9
|
* @template {any[]} [TArray=[]]
|
|
@@ -15,6 +16,9 @@ export { VERSION } from '../version.js';
|
|
|
15
16
|
* @typedef {Exclude<TEnd | LessThan<TEnd>, LessThan<TStart>>} NumericRange
|
|
16
17
|
*/
|
|
17
18
|
|
|
19
|
+
// Keep the status codes as `number` because restricting to certain numbers makes it unnecessarily hard to use compared to the benefits
|
|
20
|
+
// (we have runtime errors already to check for invalid codes). Also see https://github.com/sveltejs/kit/issues/11780
|
|
21
|
+
|
|
18
22
|
// we have to repeat the JSDoc because the display for function overloads is broken
|
|
19
23
|
// see https://github.com/microsoft/TypeScript/issues/55056
|
|
20
24
|
|
|
@@ -23,10 +27,10 @@ export { VERSION } from '../version.js';
|
|
|
23
27
|
* When called during request handling, this will cause SvelteKit to
|
|
24
28
|
* return an error response without invoking `handleError`.
|
|
25
29
|
* Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
|
|
26
|
-
* @param {
|
|
30
|
+
* @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
|
|
27
31
|
* @param {App.Error} body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
|
|
28
32
|
* @overload
|
|
29
|
-
* @param {
|
|
33
|
+
* @param {number} status
|
|
30
34
|
* @param {App.Error} body
|
|
31
35
|
* @return {never}
|
|
32
36
|
* @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling.
|
|
@@ -37,10 +41,10 @@ export { VERSION } from '../version.js';
|
|
|
37
41
|
* When called during request handling, this will cause SvelteKit to
|
|
38
42
|
* return an error response without invoking `handleError`.
|
|
39
43
|
* Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
|
|
40
|
-
* @param {
|
|
44
|
+
* @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
|
|
41
45
|
* @param {{ message: string } extends App.Error ? App.Error | string | undefined : never} [body] An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
|
|
42
46
|
* @overload
|
|
43
|
-
* @param {
|
|
47
|
+
* @param {number} status
|
|
44
48
|
* @param {{ message: string } extends App.Error ? App.Error | string | undefined : never} [body]
|
|
45
49
|
* @return {never}
|
|
46
50
|
* @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling.
|
|
@@ -51,7 +55,7 @@ export { VERSION } from '../version.js';
|
|
|
51
55
|
* When called during request handling, this will cause SvelteKit to
|
|
52
56
|
* return an error response without invoking `handleError`.
|
|
53
57
|
* Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
|
|
54
|
-
* @param {
|
|
58
|
+
* @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
|
|
55
59
|
* @param {{ message: string } extends App.Error ? App.Error | string | undefined : never} body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
|
|
56
60
|
* @return {never}
|
|
57
61
|
* @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling.
|
|
@@ -80,7 +84,7 @@ export function isHttpError(e, status) {
|
|
|
80
84
|
/**
|
|
81
85
|
* Redirect a request. When called during request handling, SvelteKit will return a redirect response.
|
|
82
86
|
* Make sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it.
|
|
83
|
-
* @param {
|
|
87
|
+
* @param {300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number)} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages). Must be in the range 300-308.
|
|
84
88
|
* @param {string | URL} location The location to redirect to.
|
|
85
89
|
* @throws {Redirect} This error instructs SvelteKit to redirect to the specified location.
|
|
86
90
|
* @throws {Error} If the provided status is invalid.
|
|
@@ -91,7 +95,11 @@ export function redirect(status, location) {
|
|
|
91
95
|
throw new Error('Invalid status code');
|
|
92
96
|
}
|
|
93
97
|
|
|
94
|
-
throw new Redirect(
|
|
98
|
+
throw new Redirect(
|
|
99
|
+
// @ts-ignore
|
|
100
|
+
status,
|
|
101
|
+
location.toString()
|
|
102
|
+
);
|
|
95
103
|
}
|
|
96
104
|
|
|
97
105
|
/**
|
package/src/exports/public.d.ts
CHANGED
|
@@ -79,11 +79,12 @@ export interface ActionFailure<T extends Record<string, unknown> | undefined = u
|
|
|
79
79
|
[uniqueSymbol]: true; // necessary or else UnpackValidationError could wrongly unpack objects with the same shape as ActionFailure
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
type UnpackValidationError<T> =
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
type UnpackValidationError<T> =
|
|
83
|
+
T extends ActionFailure<infer X>
|
|
84
|
+
? X
|
|
85
|
+
: T extends void
|
|
86
|
+
? undefined // needs to be undefined, because void will corrupt union type
|
|
87
|
+
: T;
|
|
87
88
|
|
|
88
89
|
/**
|
|
89
90
|
* This object is passed to the `adapt` function of adapters.
|
|
@@ -67,6 +67,8 @@ const snapshots = storage.get(SNAPSHOT_KEY) ?? {};
|
|
|
67
67
|
if (DEV && BROWSER) {
|
|
68
68
|
let warned = false;
|
|
69
69
|
|
|
70
|
+
const current_module_url = import.meta.url.split('?')[0]; // remove query params that vite adds to the URL when it is loaded from node_modules
|
|
71
|
+
|
|
70
72
|
const warn = () => {
|
|
71
73
|
if (warned) return;
|
|
72
74
|
|
|
@@ -76,7 +78,8 @@ if (DEV && BROWSER) {
|
|
|
76
78
|
if (!stack) return;
|
|
77
79
|
if (!stack[0].includes('https:') && !stack[0].includes('http:')) stack = stack.slice(1); // Chrome includes the error message in the stack
|
|
78
80
|
stack = stack.slice(2); // remove `warn` and the place where `warn` was called
|
|
79
|
-
if
|
|
81
|
+
// Can be falsy if was called directly from an anonymous function
|
|
82
|
+
if (stack[0]?.includes(current_module_url)) return;
|
|
80
83
|
|
|
81
84
|
warned = true;
|
|
82
85
|
|
|
@@ -305,20 +308,23 @@ async function _invalidate() {
|
|
|
305
308
|
|
|
306
309
|
const nav_token = (token = {});
|
|
307
310
|
const navigation_result = intent && (await load_route(intent));
|
|
308
|
-
if (nav_token !== token) return;
|
|
311
|
+
if (!navigation_result || nav_token !== token) return;
|
|
309
312
|
|
|
310
|
-
if (navigation_result) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
root.$set(navigation_result.props);
|
|
318
|
-
}
|
|
313
|
+
if (navigation_result.type === 'redirect') {
|
|
314
|
+
return _goto(new URL(navigation_result.location, current.url).href, {}, 1, nav_token);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (navigation_result.props.page) {
|
|
318
|
+
page = navigation_result.props.page;
|
|
319
319
|
}
|
|
320
|
+
current = navigation_result.state;
|
|
321
|
+
reset_invalidation();
|
|
322
|
+
root.$set(navigation_result.props);
|
|
323
|
+
}
|
|
320
324
|
|
|
325
|
+
function reset_invalidation() {
|
|
321
326
|
invalidated.length = 0;
|
|
327
|
+
force_invalidation = false;
|
|
322
328
|
}
|
|
323
329
|
|
|
324
330
|
/** @param {number} index */
|
|
@@ -1089,6 +1095,9 @@ async function load_root_error_page({ status, error, url, route }) {
|
|
|
1089
1095
|
}
|
|
1090
1096
|
|
|
1091
1097
|
/**
|
|
1098
|
+
* Resolve the full info (which route, params, etc.) for a client-side navigation from the URL,
|
|
1099
|
+
* taking the reroute hook into account. If this isn't a client-side-navigation (or the URL is undefined),
|
|
1100
|
+
* returns undefined.
|
|
1092
1101
|
* @param {URL | undefined} url
|
|
1093
1102
|
* @param {boolean} invalidating
|
|
1094
1103
|
*/
|
|
@@ -1278,8 +1287,7 @@ async function navigate({
|
|
|
1278
1287
|
|
|
1279
1288
|
// reset invalidation only after a finished navigation. If there are redirects or
|
|
1280
1289
|
// additional invalidations, they should get the same invalidation treatment
|
|
1281
|
-
|
|
1282
|
-
force_invalidation = false;
|
|
1290
|
+
reset_invalidation();
|
|
1283
1291
|
|
|
1284
1292
|
updating = true;
|
|
1285
1293
|
|
|
@@ -1818,6 +1826,7 @@ export function pushState(url, state) {
|
|
|
1818
1826
|
};
|
|
1819
1827
|
|
|
1820
1828
|
history.pushState(opts, '', resolve_url(url));
|
|
1829
|
+
has_navigated = true;
|
|
1821
1830
|
|
|
1822
1831
|
page = { ...page, state };
|
|
1823
1832
|
root.$set({ page });
|
package/src/version.js
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -61,11 +61,12 @@ declare module '@sveltejs/kit' {
|
|
|
61
61
|
[uniqueSymbol]: true; // necessary or else UnpackValidationError could wrongly unpack objects with the same shape as ActionFailure
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
type UnpackValidationError<T> =
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
type UnpackValidationError<T> =
|
|
65
|
+
T extends ActionFailure<infer X>
|
|
66
|
+
? X
|
|
67
|
+
: T extends void
|
|
68
|
+
? undefined // needs to be undefined, because void will corrupt union type
|
|
69
|
+
: T;
|
|
69
70
|
|
|
70
71
|
/**
|
|
71
72
|
* This object is passed to the `adapt` function of adapters.
|
|
@@ -1766,7 +1767,7 @@ declare module '@sveltejs/kit' {
|
|
|
1766
1767
|
* @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling.
|
|
1767
1768
|
* @throws {Error} If the provided status is invalid (not between 400 and 599).
|
|
1768
1769
|
*/
|
|
1769
|
-
export function error(status:
|
|
1770
|
+
export function error(status: number, body: App.Error): never;
|
|
1770
1771
|
/**
|
|
1771
1772
|
* Throws an error with a HTTP status code and an optional message.
|
|
1772
1773
|
* When called during request handling, this will cause SvelteKit to
|
|
@@ -1777,7 +1778,7 @@ declare module '@sveltejs/kit' {
|
|
|
1777
1778
|
* @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling.
|
|
1778
1779
|
* @throws {Error} If the provided status is invalid (not between 400 and 599).
|
|
1779
1780
|
*/
|
|
1780
|
-
export function error(status:
|
|
1781
|
+
export function error(status: number, body?: {
|
|
1781
1782
|
message: string;
|
|
1782
1783
|
} extends App.Error ? App.Error | string | undefined : never): never;
|
|
1783
1784
|
/**
|
|
@@ -1795,7 +1796,7 @@ declare module '@sveltejs/kit' {
|
|
|
1795
1796
|
* @throws {Redirect} This error instructs SvelteKit to redirect to the specified location.
|
|
1796
1797
|
* @throws {Error} If the provided status is invalid.
|
|
1797
1798
|
* */
|
|
1798
|
-
export function redirect(status:
|
|
1799
|
+
export function redirect(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), location: string | URL): never;
|
|
1799
1800
|
/**
|
|
1800
1801
|
* Checks whether this is a redirect thrown by {@link redirect}.
|
|
1801
1802
|
* @param e The object to check.
|
package/types/index.d.ts.map
CHANGED
|
@@ -154,5 +154,5 @@
|
|
|
154
154
|
null,
|
|
155
155
|
null
|
|
156
156
|
],
|
|
157
|
-
"mappings": ";;;;;;;;;kBA2BiBA,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;aA2BZC,cAAcA;;;;;;aAMdC,cAAcA;;;;;;;;;;;;;;;kBAeTC,aAAaA
|
|
157
|
+
"mappings": "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"
|
|
158
158
|
}
|