@sveltejs/kit 1.30.2 → 2.0.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 +24 -24
- package/src/core/adapt/builder.js +8 -1
- package/src/core/config/index.js +9 -1
- package/src/core/config/options.js +1 -12
- package/src/core/postbuild/analyse.js +98 -80
- package/src/core/postbuild/prerender.js +11 -9
- package/src/core/sync/sync.js +2 -0
- package/src/core/sync/write_non_ambient.js +42 -0
- package/src/core/sync/write_server.js +3 -3
- package/src/core/sync/write_tsconfig.js +27 -78
- package/src/core/sync/write_types/index.js +1 -1
- package/src/exports/hooks/sequence.js +1 -1
- package/src/exports/index.js +88 -71
- package/src/exports/node/index.js +21 -24
- package/src/exports/node/polyfills.js +5 -34
- package/src/exports/public.d.ts +82 -61
- package/src/exports/vite/dev/index.js +11 -19
- package/src/exports/vite/graph_analysis/index.js +2 -4
- package/src/exports/vite/index.js +73 -14
- package/src/exports/vite/module_ids.js +7 -0
- package/src/exports/vite/preview/index.js +56 -130
- package/src/runtime/app/forms.js +2 -35
- package/src/runtime/app/navigation.js +33 -18
- package/src/runtime/app/paths.js +2 -29
- package/src/runtime/client/client.js +449 -199
- package/src/runtime/client/constants.js +5 -1
- package/src/runtime/client/session-storage.js +7 -5
- package/src/runtime/client/singletons.js +7 -1
- package/src/runtime/client/types.d.ts +6 -2
- package/src/runtime/client/utils.js +12 -10
- package/src/runtime/control.js +16 -8
- package/src/runtime/server/cookie.js +38 -61
- package/src/runtime/server/data/index.js +6 -4
- package/src/runtime/server/env_module.js +29 -0
- package/src/runtime/server/fetch.js +7 -6
- package/src/runtime/server/index.js +23 -20
- package/src/runtime/server/page/actions.js +24 -15
- package/src/runtime/server/page/index.js +6 -8
- package/src/runtime/server/page/load_data.js +58 -40
- package/src/runtime/server/page/render.js +12 -7
- package/src/runtime/server/page/respond_with_error.js +4 -4
- package/src/runtime/server/page/types.d.ts +1 -1
- package/src/runtime/server/respond.js +14 -12
- package/src/runtime/server/utils.js +11 -8
- package/src/runtime/shared-server.js +19 -2
- package/src/types/ambient.d.ts +7 -1
- package/src/types/internal.d.ts +4 -1
- package/src/types/synthetic/$env+dynamic+private.md +2 -0
- package/src/types/synthetic/$env+dynamic+public.md +2 -0
- package/src/utils/error.js +17 -1
- package/src/utils/routing.js +47 -1
- package/src/utils/url.js +45 -27
- package/src/version.js +1 -1
- package/types/index.d.ts +171 -118
- package/types/index.d.ts.map +9 -5
- package/src/utils/platform.js +0 -1
- package/src/utils/promises.js +0 -61
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export const SNAPSHOT_KEY = 'sveltekit:snapshot';
|
|
2
2
|
export const SCROLL_KEY = 'sveltekit:scroll';
|
|
3
|
-
export const
|
|
3
|
+
export const STATES_KEY = 'sveltekit:states';
|
|
4
|
+
export const PAGE_URL_KEY = 'sveltekit:pageurl';
|
|
5
|
+
|
|
6
|
+
export const HISTORY_INDEX = 'sveltekit:history';
|
|
7
|
+
export const NAVIGATION_INDEX = 'sveltekit:navigation';
|
|
4
8
|
|
|
5
9
|
export const PRELOAD_PRIORITIES = /** @type {const} */ ({
|
|
6
10
|
tap: 1,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Read a value from `sessionStorage`
|
|
3
3
|
* @param {string} key
|
|
4
|
+
* @param {(value: string) => any} parse
|
|
4
5
|
*/
|
|
5
|
-
export function get(key) {
|
|
6
|
+
export function get(key, parse = JSON.parse) {
|
|
6
7
|
try {
|
|
7
|
-
return
|
|
8
|
+
return parse(sessionStorage[key]);
|
|
8
9
|
} catch {
|
|
9
10
|
// do nothing
|
|
10
11
|
}
|
|
@@ -14,11 +15,12 @@ export function get(key) {
|
|
|
14
15
|
* Write a value to `sessionStorage`
|
|
15
16
|
* @param {string} key
|
|
16
17
|
* @param {any} value
|
|
18
|
+
* @param {(value: any) => string} stringify
|
|
17
19
|
*/
|
|
18
|
-
export function set(key, value) {
|
|
19
|
-
const
|
|
20
|
+
export function set(key, value, stringify = JSON.stringify) {
|
|
21
|
+
const data = stringify(value);
|
|
20
22
|
try {
|
|
21
|
-
sessionStorage[key] =
|
|
23
|
+
sessionStorage[key] = data;
|
|
22
24
|
} catch {
|
|
23
25
|
// do nothing
|
|
24
26
|
}
|
|
@@ -21,7 +21,13 @@ export function init(opts) {
|
|
|
21
21
|
*/
|
|
22
22
|
export function client_method(key) {
|
|
23
23
|
if (!BROWSER) {
|
|
24
|
-
if (
|
|
24
|
+
if (
|
|
25
|
+
key === 'before_navigate' ||
|
|
26
|
+
key === 'after_navigate' ||
|
|
27
|
+
key === 'on_navigate' ||
|
|
28
|
+
key === 'push_state' ||
|
|
29
|
+
key === 'replace_state'
|
|
30
|
+
) {
|
|
25
31
|
// @ts-expect-error doesn't recognize that both keys here return void so expects a async function
|
|
26
32
|
return () => {};
|
|
27
33
|
} else {
|
|
@@ -7,7 +7,9 @@ import {
|
|
|
7
7
|
invalidate,
|
|
8
8
|
invalidateAll,
|
|
9
9
|
preloadCode,
|
|
10
|
-
preloadData
|
|
10
|
+
preloadData,
|
|
11
|
+
pushState,
|
|
12
|
+
replaceState
|
|
11
13
|
} from '../app/navigation.js';
|
|
12
14
|
import { SvelteComponent } from 'svelte';
|
|
13
15
|
import { ClientHooks, CSRPageNode, CSRPageNodeLoader, CSRRoute, TrailingSlash, Uses } from 'types';
|
|
@@ -51,6 +53,8 @@ export interface Client {
|
|
|
51
53
|
invalidate_all: typeof invalidateAll;
|
|
52
54
|
preload_code: typeof preloadCode;
|
|
53
55
|
preload_data: typeof preloadData;
|
|
56
|
+
push_state: typeof pushState;
|
|
57
|
+
replace_state: typeof replaceState;
|
|
54
58
|
apply_action: typeof applyAction;
|
|
55
59
|
|
|
56
60
|
// private API
|
|
@@ -92,7 +96,7 @@ export type NavigationFinished = {
|
|
|
92
96
|
props: {
|
|
93
97
|
constructors: Array<typeof SvelteComponent>;
|
|
94
98
|
components?: Array<SvelteComponent>;
|
|
95
|
-
page
|
|
99
|
+
page: Page;
|
|
96
100
|
form?: Record<string, any> | null;
|
|
97
101
|
[key: `data_${number}`]: Record<string, any>;
|
|
98
102
|
};
|
|
@@ -8,16 +8,18 @@ import { PRELOAD_PRIORITIES } from './constants.js';
|
|
|
8
8
|
|
|
9
9
|
export const origin = BROWSER ? location.origin : '';
|
|
10
10
|
|
|
11
|
-
/** @param {
|
|
12
|
-
export function
|
|
13
|
-
|
|
11
|
+
/** @param {string | URL} url */
|
|
12
|
+
export function resolve_url(url) {
|
|
13
|
+
if (url instanceof URL) return url;
|
|
14
|
+
|
|
15
|
+
let baseURI = document.baseURI;
|
|
14
16
|
|
|
15
17
|
if (!baseURI) {
|
|
16
|
-
const baseTags =
|
|
17
|
-
baseURI = baseTags.length ? baseTags[0].href :
|
|
18
|
+
const baseTags = document.getElementsByTagName('base');
|
|
19
|
+
baseURI = baseTags.length ? baseTags[0].href : document.URL;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
return baseURI;
|
|
22
|
+
return new URL(url, baseURI);
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
export function scroll_state() {
|
|
@@ -147,7 +149,7 @@ export function get_link_info(a, base) {
|
|
|
147
149
|
*/
|
|
148
150
|
export function get_router_options(element) {
|
|
149
151
|
/** @type {ValidLinkOptions<'keepfocus'> | null} */
|
|
150
|
-
let
|
|
152
|
+
let keepfocus = null;
|
|
151
153
|
|
|
152
154
|
/** @type {ValidLinkOptions<'noscroll'> | null} */
|
|
153
155
|
let noscroll = null;
|
|
@@ -170,7 +172,7 @@ export function get_router_options(element) {
|
|
|
170
172
|
while (el && el !== document.documentElement) {
|
|
171
173
|
if (preload_code === null) preload_code = link_option(el, 'preload-code');
|
|
172
174
|
if (preload_data === null) preload_data = link_option(el, 'preload-data');
|
|
173
|
-
if (
|
|
175
|
+
if (keepfocus === null) keepfocus = link_option(el, 'keepfocus');
|
|
174
176
|
if (noscroll === null) noscroll = link_option(el, 'noscroll');
|
|
175
177
|
if (reload === null) reload = link_option(el, 'reload');
|
|
176
178
|
if (replace_state === null) replace_state = link_option(el, 'replacestate');
|
|
@@ -188,14 +190,14 @@ export function get_router_options(element) {
|
|
|
188
190
|
case 'false':
|
|
189
191
|
return false;
|
|
190
192
|
default:
|
|
191
|
-
return
|
|
193
|
+
return undefined;
|
|
192
194
|
}
|
|
193
195
|
}
|
|
194
196
|
|
|
195
197
|
return {
|
|
196
198
|
preload_code: levels[preload_code ?? 'off'],
|
|
197
199
|
preload_data: levels[preload_data ?? 'off'],
|
|
198
|
-
|
|
200
|
+
keepfocus: get_option_state(keepfocus),
|
|
199
201
|
noscroll: get_option_state(noscroll),
|
|
200
202
|
reload: get_option_state(reload),
|
|
201
203
|
replace_state: get_option_state(replace_state)
|
package/src/runtime/control.js
CHANGED
|
@@ -30,15 +30,20 @@ export class Redirect {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
/**
|
|
34
|
+
* An error that was thrown from within the SvelteKit runtime that is not fatal and doesn't result in a 500, such as a 404.
|
|
35
|
+
* `SvelteKitError` goes through `handleError`.
|
|
36
|
+
*/
|
|
37
|
+
export class SvelteKitError extends Error {
|
|
34
38
|
/**
|
|
35
|
-
* @param {
|
|
39
|
+
* @param {number} status
|
|
40
|
+
* @param {string} text
|
|
41
|
+
* @param {string} message
|
|
36
42
|
*/
|
|
37
|
-
constructor(
|
|
38
|
-
super();
|
|
39
|
-
|
|
40
|
-
this.
|
|
41
|
-
this.message = `Not found: ${pathname}`;
|
|
43
|
+
constructor(status, text, message) {
|
|
44
|
+
super(message);
|
|
45
|
+
this.status = status;
|
|
46
|
+
this.text = text;
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
|
|
@@ -48,7 +53,7 @@ export class NotFound extends Error {
|
|
|
48
53
|
export class ActionFailure {
|
|
49
54
|
/**
|
|
50
55
|
* @param {number} status
|
|
51
|
-
* @param {T}
|
|
56
|
+
* @param {T} data
|
|
52
57
|
*/
|
|
53
58
|
constructor(status, data) {
|
|
54
59
|
this.status = status;
|
|
@@ -66,6 +71,7 @@ export class ActionFailure {
|
|
|
66
71
|
* ActionFailure: typeof ActionFailure;
|
|
67
72
|
* HttpError: typeof HttpError;
|
|
68
73
|
* Redirect: typeof Redirect;
|
|
74
|
+
* SvelteKitError: typeof SvelteKitError;
|
|
69
75
|
* }} implementations
|
|
70
76
|
*/
|
|
71
77
|
export function replace_implementations(implementations) {
|
|
@@ -75,4 +81,6 @@ export function replace_implementations(implementations) {
|
|
|
75
81
|
HttpError = implementations.HttpError; // eslint-disable-line no-class-assign
|
|
76
82
|
// @ts-expect-error
|
|
77
83
|
Redirect = implementations.Redirect; // eslint-disable-line no-class-assign
|
|
84
|
+
// @ts-expect-error
|
|
85
|
+
SvelteKitError = implementations.SvelteKitError; // eslint-disable-line no-class-assign
|
|
78
86
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { parse, serialize } from 'cookie';
|
|
2
|
-
import { normalize_path, resolve } from '../../utils/url.js';
|
|
3
|
-
import { warn_with_callsite } from './utils.js';
|
|
2
|
+
import { add_data_suffix, normalize_path, resolve } from '../../utils/url.js';
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Tracks all cookies set during dev mode so we can emit warnings
|
|
@@ -15,24 +14,11 @@ const cookie_paths = {};
|
|
|
15
14
|
*/
|
|
16
15
|
const MAX_COOKIE_SIZE = 4129;
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
function deprecate_missing_path(opts, method) {
|
|
24
|
-
if (opts.path === undefined) {
|
|
25
|
-
warn_with_callsite(
|
|
26
|
-
`Calling \`cookies.${method}(...)\` without specifying a \`path\` is deprecated, and will be disallowed in SvelteKit 2.0. Relative paths can be used`,
|
|
27
|
-
1
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (opts.path === '') {
|
|
32
|
-
warn_with_callsite(
|
|
33
|
-
`Calling \`cookies.${method}(...)\` with \`path: ''\` will behave differently in SvelteKit 2.0. Instead of using the browser default behaviour, it will set the cookie path to the current pathname`,
|
|
34
|
-
1
|
|
35
|
-
);
|
|
17
|
+
// TODO 3.0 remove this check
|
|
18
|
+
/** @param {import('./page/types.js').Cookie['options']} options */
|
|
19
|
+
function validate_options(options) {
|
|
20
|
+
if (options?.path === undefined) {
|
|
21
|
+
throw new Error('You must specify a `path` when setting, deleting or serializing cookies');
|
|
36
22
|
}
|
|
37
23
|
}
|
|
38
24
|
|
|
@@ -46,8 +32,6 @@ export function get_cookies(request, url, trailing_slash) {
|
|
|
46
32
|
const initial_cookies = parse(header, { decode: (value) => value });
|
|
47
33
|
|
|
48
34
|
const normalized_url = normalize_path(url.pathname, trailing_slash);
|
|
49
|
-
// Emulate browser-behavior: if the cookie is set at '/foo/bar', its path is '/foo'
|
|
50
|
-
const default_path = normalized_url.split('/').slice(0, -1).join('/') || '/';
|
|
51
35
|
|
|
52
36
|
/** @type {Record<string, import('./page/types.js').Cookie>} */
|
|
53
37
|
const new_cookies = {};
|
|
@@ -126,39 +110,37 @@ export function get_cookies(request, url, trailing_slash) {
|
|
|
126
110
|
/**
|
|
127
111
|
* @param {string} name
|
|
128
112
|
* @param {string} value
|
|
129
|
-
* @param {import('
|
|
113
|
+
* @param {import('./page/types.js').Cookie['options']} options
|
|
130
114
|
*/
|
|
131
|
-
set(name, value,
|
|
132
|
-
|
|
133
|
-
set_internal(name, value, { ...defaults, ...
|
|
115
|
+
set(name, value, options) {
|
|
116
|
+
validate_options(options);
|
|
117
|
+
set_internal(name, value, { ...defaults, ...options });
|
|
134
118
|
},
|
|
135
119
|
|
|
136
120
|
/**
|
|
137
121
|
* @param {string} name
|
|
138
|
-
*
|
|
122
|
+
* @param {import('./page/types.js').Cookie['options']} options
|
|
139
123
|
*/
|
|
140
|
-
delete(name,
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
cookies.set(name, '', {
|
|
144
|
-
path: default_path, // TODO 2.0 remove this
|
|
145
|
-
...opts,
|
|
146
|
-
maxAge: 0
|
|
147
|
-
});
|
|
124
|
+
delete(name, options) {
|
|
125
|
+
validate_options(options);
|
|
126
|
+
cookies.set(name, '', { ...options, maxAge: 0 });
|
|
148
127
|
},
|
|
149
128
|
|
|
150
129
|
/**
|
|
151
130
|
* @param {string} name
|
|
152
131
|
* @param {string} value
|
|
153
|
-
*
|
|
132
|
+
* @param {import('./page/types.js').Cookie['options']} options
|
|
154
133
|
*/
|
|
155
|
-
serialize(name, value,
|
|
156
|
-
|
|
134
|
+
serialize(name, value, options) {
|
|
135
|
+
validate_options(options);
|
|
136
|
+
|
|
137
|
+
let path = options.path;
|
|
138
|
+
|
|
139
|
+
if (!options.domain || options.domain === url.hostname) {
|
|
140
|
+
path = resolve(normalized_url, path);
|
|
141
|
+
}
|
|
157
142
|
|
|
158
|
-
return serialize(name, value, {
|
|
159
|
-
...defaults,
|
|
160
|
-
...opts
|
|
161
|
-
});
|
|
143
|
+
return serialize(name, value, { ...defaults, ...options, path });
|
|
162
144
|
}
|
|
163
145
|
};
|
|
164
146
|
|
|
@@ -199,27 +181,16 @@ export function get_cookies(request, url, trailing_slash) {
|
|
|
199
181
|
/**
|
|
200
182
|
* @param {string} name
|
|
201
183
|
* @param {string} value
|
|
202
|
-
* @param {import('
|
|
184
|
+
* @param {import('./page/types.js').Cookie['options']} options
|
|
203
185
|
*/
|
|
204
|
-
function set_internal(name, value,
|
|
205
|
-
let path =
|
|
186
|
+
function set_internal(name, value, options) {
|
|
187
|
+
let path = options.path;
|
|
206
188
|
|
|
207
|
-
if (!
|
|
208
|
-
|
|
209
|
-
if (path[0] === '.') path = resolve(url.pathname, path);
|
|
210
|
-
} else {
|
|
211
|
-
path = default_path;
|
|
212
|
-
}
|
|
189
|
+
if (!options.domain || options.domain === url.hostname) {
|
|
190
|
+
path = resolve(normalized_url, path);
|
|
213
191
|
}
|
|
214
192
|
|
|
215
|
-
new_cookies[name] = {
|
|
216
|
-
name,
|
|
217
|
-
value,
|
|
218
|
-
options: {
|
|
219
|
-
...opts,
|
|
220
|
-
path
|
|
221
|
-
}
|
|
222
|
-
};
|
|
193
|
+
new_cookies[name] = { name, value, options: { ...options, path } };
|
|
223
194
|
|
|
224
195
|
if (__SVELTEKIT_DEV__) {
|
|
225
196
|
const serialized = serialize(name, value, new_cookies[name].options);
|
|
@@ -230,10 +201,8 @@ export function get_cookies(request, url, trailing_slash) {
|
|
|
230
201
|
cookie_paths[name] ??= new Set();
|
|
231
202
|
|
|
232
203
|
if (!value) {
|
|
233
|
-
// @ts-expect-error temporary
|
|
234
204
|
cookie_paths[name].delete(path);
|
|
235
205
|
} else {
|
|
236
|
-
// @ts-expect-error temporary
|
|
237
206
|
cookie_paths[name].add(path);
|
|
238
207
|
}
|
|
239
208
|
}
|
|
@@ -276,6 +245,14 @@ export function add_cookies_to_headers(headers, cookies) {
|
|
|
276
245
|
for (const new_cookie of cookies) {
|
|
277
246
|
const { name, value, options } = new_cookie;
|
|
278
247
|
headers.append('set-cookie', serialize(name, value, options));
|
|
248
|
+
|
|
249
|
+
// special case — for routes ending with .html, the route data lives in a sibling
|
|
250
|
+
// `.html__data.json` file rather than a child `/__data.json` file, which means
|
|
251
|
+
// we need to duplicate the cookie
|
|
252
|
+
if (options.path.endsWith('.html')) {
|
|
253
|
+
const path = add_data_suffix(options.path);
|
|
254
|
+
headers.append('set-cookie', serialize(name, value, { ...options, path }));
|
|
255
|
+
}
|
|
279
256
|
}
|
|
280
257
|
}
|
|
281
258
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HttpError, Redirect } from '../../control.js';
|
|
1
|
+
import { HttpError, SvelteKitError, Redirect } from '../../control.js';
|
|
2
2
|
import { normalize_error } from '../../../utils/error.js';
|
|
3
3
|
import { once } from '../../../utils/functions.js';
|
|
4
4
|
import { load_server_data } from '../page/load_data.js';
|
|
@@ -76,8 +76,7 @@ export async function render_data(
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
return data;
|
|
79
|
-
}
|
|
80
|
-
track_server_fetches: options.track_server_fetches
|
|
79
|
+
}
|
|
81
80
|
});
|
|
82
81
|
} catch (e) {
|
|
83
82
|
aborted = true;
|
|
@@ -110,7 +109,10 @@ export async function render_data(
|
|
|
110
109
|
return /** @type {import('types').ServerErrorNode} */ ({
|
|
111
110
|
type: 'error',
|
|
112
111
|
error: await handle_error_and_jsonify(event, options, error),
|
|
113
|
-
status:
|
|
112
|
+
status:
|
|
113
|
+
error instanceof HttpError || error instanceof SvelteKitError
|
|
114
|
+
? error.status
|
|
115
|
+
: undefined
|
|
114
116
|
});
|
|
115
117
|
})
|
|
116
118
|
)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { public_env } from '../shared-server.js';
|
|
2
|
+
|
|
3
|
+
/** @type {string} */
|
|
4
|
+
let body;
|
|
5
|
+
|
|
6
|
+
/** @type {string} */
|
|
7
|
+
let etag;
|
|
8
|
+
|
|
9
|
+
/** @type {Headers} */
|
|
10
|
+
let headers;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {Request} request
|
|
14
|
+
* @returns {Response}
|
|
15
|
+
*/
|
|
16
|
+
export function get_public_env(request) {
|
|
17
|
+
body ??= `export const env=${JSON.stringify(public_env)}`;
|
|
18
|
+
etag ??= `W/${Date.now()}`;
|
|
19
|
+
headers ??= new Headers({
|
|
20
|
+
'content-type': 'application/javascript; charset=utf-8',
|
|
21
|
+
etag
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (request.headers.get('if-none-match') === etag) {
|
|
25
|
+
return new Response(undefined, { status: 304, headers });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return new Response(body, { headers });
|
|
29
|
+
}
|
|
@@ -9,7 +9,7 @@ import * as paths from '__sveltekit/paths';
|
|
|
9
9
|
* manifest: import('@sveltejs/kit').SSRManifest;
|
|
10
10
|
* state: import('types').SSRState;
|
|
11
11
|
* get_cookie_header: (url: URL, header: string | null) => string;
|
|
12
|
-
* set_internal: (name: string, value: string, opts: import('
|
|
12
|
+
* set_internal: (name: string, value: string, opts: import('./page/types.js').Cookie['options']) => void;
|
|
13
13
|
* }} opts
|
|
14
14
|
* @returns {typeof fetch}
|
|
15
15
|
*/
|
|
@@ -134,12 +134,13 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
|
|
|
134
134
|
for (const str of set_cookie_parser.splitCookiesString(set_cookie)) {
|
|
135
135
|
const { name, value, ...options } = set_cookie_parser.parseString(str);
|
|
136
136
|
|
|
137
|
+
const path = options.path ?? (url.pathname.split('/').slice(0, -1).join('/') || '/');
|
|
138
|
+
|
|
137
139
|
// options.sameSite is string, something more specific is required - type cast is safe
|
|
138
|
-
set_internal(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
);
|
|
140
|
+
set_internal(name, value, {
|
|
141
|
+
path,
|
|
142
|
+
.../** @type {import('cookie').CookieSerializeOptions} */ (options)
|
|
143
|
+
});
|
|
143
144
|
}
|
|
144
145
|
}
|
|
145
146
|
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { respond } from './respond.js';
|
|
2
|
-
import { set_private_env, set_public_env } from '../shared-server.js';
|
|
2
|
+
import { set_private_env, set_public_env, set_safe_public_env } from '../shared-server.js';
|
|
3
3
|
import { options, get_hooks } from '__SERVER__/internal.js';
|
|
4
4
|
import { DEV } from 'esm-env';
|
|
5
5
|
import { filter_private_env, filter_public_env } from '../../utils/env.js';
|
|
6
|
+
import { building } from '../app/environment.js';
|
|
7
|
+
|
|
8
|
+
/** @type {ProxyHandler<{ type: 'public' | 'private' }>} */
|
|
9
|
+
const prerender_env_handler = {
|
|
10
|
+
get({ type }, prop) {
|
|
11
|
+
throw new Error(
|
|
12
|
+
`Cannot read values from $env/dynamic/${type} while prerendering (attempted to read env.${prop.toString()}). Use $env/static/${type} instead`
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
6
16
|
|
|
7
17
|
export class Server {
|
|
8
18
|
/** @type {import('types').SSROptions} */
|
|
@@ -27,19 +37,19 @@ export class Server {
|
|
|
27
37
|
// Take care: Some adapters may have to call `Server.init` per-request to set env vars,
|
|
28
38
|
// so anything that shouldn't be rerun should be wrapped in an `if` block to make sure it hasn't
|
|
29
39
|
// been done already.
|
|
40
|
+
|
|
30
41
|
// set env, in case it's used in initialisation
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
);
|
|
42
|
+
const prefixes = {
|
|
43
|
+
public_prefix: this.#options.env_public_prefix,
|
|
44
|
+
private_prefix: this.#options.env_private_prefix
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const private_env = filter_private_env(env, prefixes);
|
|
48
|
+
const public_env = filter_public_env(env, prefixes);
|
|
49
|
+
|
|
50
|
+
set_private_env(building ? new Proxy({ type: 'private' }, prerender_env_handler) : private_env);
|
|
51
|
+
set_public_env(building ? new Proxy({ type: 'public' }, prerender_env_handler) : public_env);
|
|
52
|
+
set_safe_public_env(public_env);
|
|
43
53
|
|
|
44
54
|
if (!this.#options.hooks) {
|
|
45
55
|
try {
|
|
@@ -71,13 +81,6 @@ export class Server {
|
|
|
71
81
|
* @param {import('types').RequestOptions} options
|
|
72
82
|
*/
|
|
73
83
|
async respond(request, options) {
|
|
74
|
-
// TODO this should probably have been removed for 1.0 — i think we can get rid of it?
|
|
75
|
-
if (!(request instanceof Request)) {
|
|
76
|
-
throw new Error(
|
|
77
|
-
'The first argument to server.respond must be a Request object. See https://github.com/sveltejs/kit/pull/3384 for details'
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
84
|
return respond(request, this.#options, this.#manifest, {
|
|
82
85
|
...options,
|
|
83
86
|
error: false,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as devalue from 'devalue';
|
|
2
|
-
import {
|
|
3
|
-
import { normalize_error } from '../../../utils/error.js';
|
|
2
|
+
import { json } from '../../../exports/index.js';
|
|
3
|
+
import { get_status, normalize_error } from '../../../utils/error.js';
|
|
4
4
|
import { is_form_content_type, negotiate } from '../../../utils/http.js';
|
|
5
|
-
import { HttpError, Redirect, ActionFailure } from '../../control.js';
|
|
5
|
+
import { HttpError, Redirect, ActionFailure, SvelteKitError } from '../../control.js';
|
|
6
6
|
import { handle_error_and_jsonify } from '../utils.js';
|
|
7
7
|
|
|
8
8
|
/** @param {import('@sveltejs/kit').RequestEvent} event */
|
|
@@ -24,8 +24,11 @@ export async function handle_action_json_request(event, options, server) {
|
|
|
24
24
|
const actions = server?.actions;
|
|
25
25
|
|
|
26
26
|
if (!actions) {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
const no_actions_error = new SvelteKitError(
|
|
28
|
+
405,
|
|
29
|
+
'Method Not Allowed',
|
|
30
|
+
'POST method not allowed. No actions exist for this page'
|
|
31
|
+
);
|
|
29
32
|
return action_json(
|
|
30
33
|
{
|
|
31
34
|
type: 'error',
|
|
@@ -81,7 +84,7 @@ export async function handle_action_json_request(event, options, server) {
|
|
|
81
84
|
error: await handle_error_and_jsonify(event, options, check_incorrect_fail_use(err))
|
|
82
85
|
},
|
|
83
86
|
{
|
|
84
|
-
status: err
|
|
87
|
+
status: get_status(err)
|
|
85
88
|
}
|
|
86
89
|
);
|
|
87
90
|
}
|
|
@@ -139,7 +142,11 @@ export async function handle_action_request(event, server) {
|
|
|
139
142
|
});
|
|
140
143
|
return {
|
|
141
144
|
type: 'error',
|
|
142
|
-
error:
|
|
145
|
+
error: new SvelteKitError(
|
|
146
|
+
405,
|
|
147
|
+
'Method Not Allowed',
|
|
148
|
+
'POST method not allowed. No actions exist for this page'
|
|
149
|
+
)
|
|
143
150
|
};
|
|
144
151
|
}
|
|
145
152
|
|
|
@@ -198,7 +205,7 @@ function check_named_default_separate(actions) {
|
|
|
198
205
|
/**
|
|
199
206
|
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
200
207
|
* @param {NonNullable<import('types').SSRNode['server']['actions']>} actions
|
|
201
|
-
* @throws {Redirect |
|
|
208
|
+
* @throws {Redirect | HttpError | SvelteKitError | Error}
|
|
202
209
|
*/
|
|
203
210
|
async function call_action(event, actions) {
|
|
204
211
|
const url = new URL(event.request.url);
|
|
@@ -216,12 +223,16 @@ async function call_action(event, actions) {
|
|
|
216
223
|
|
|
217
224
|
const action = actions[name];
|
|
218
225
|
if (!action) {
|
|
219
|
-
throw new
|
|
226
|
+
throw new SvelteKitError(404, 'Not Found', `No action with name '${name}' found`);
|
|
220
227
|
}
|
|
221
228
|
|
|
222
229
|
if (!is_form_content_type(event.request)) {
|
|
223
|
-
throw new
|
|
224
|
-
|
|
230
|
+
throw new SvelteKitError(
|
|
231
|
+
415,
|
|
232
|
+
'Unsupported Media Type',
|
|
233
|
+
`Form actions expect form-encoded data — received ${event.request.headers.get(
|
|
234
|
+
'content-type'
|
|
235
|
+
)}`
|
|
225
236
|
);
|
|
226
237
|
}
|
|
227
238
|
|
|
@@ -231,13 +242,11 @@ async function call_action(event, actions) {
|
|
|
231
242
|
/** @param {any} data */
|
|
232
243
|
function validate_action_return(data) {
|
|
233
244
|
if (data instanceof Redirect) {
|
|
234
|
-
throw new Error('Cannot `return redirect(...)` — use `
|
|
245
|
+
throw new Error('Cannot `return redirect(...)` — use `redirect(...)` instead');
|
|
235
246
|
}
|
|
236
247
|
|
|
237
248
|
if (data instanceof HttpError) {
|
|
238
|
-
throw new Error(
|
|
239
|
-
'Cannot `return error(...)` — use `throw error(...)` or `return fail(...)` instead'
|
|
240
|
-
);
|
|
249
|
+
throw new Error('Cannot `return error(...)` — use `error(...)` or `return fail(...)` instead');
|
|
241
250
|
}
|
|
242
251
|
}
|
|
243
252
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { text } from '../../../exports/index.js';
|
|
2
2
|
import { compact } from '../../../utils/array.js';
|
|
3
|
-
import { normalize_error } from '../../../utils/error.js';
|
|
3
|
+
import { get_status, normalize_error } from '../../../utils/error.js';
|
|
4
4
|
import { add_data_suffix } from '../../../utils/url.js';
|
|
5
|
-
import {
|
|
5
|
+
import { Redirect } from '../../control.js';
|
|
6
6
|
import { redirect_response, static_error_page, handle_error_and_jsonify } from '../utils.js';
|
|
7
7
|
import {
|
|
8
8
|
handle_action_json_request,
|
|
@@ -65,8 +65,7 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
65
65
|
return redirect_response(action_result.status, action_result.location);
|
|
66
66
|
}
|
|
67
67
|
if (action_result?.type === 'error') {
|
|
68
|
-
|
|
69
|
-
status = error instanceof HttpError ? error.status : 500;
|
|
68
|
+
status = get_status(action_result.error);
|
|
70
69
|
}
|
|
71
70
|
if (action_result?.type === 'failure') {
|
|
72
71
|
status = action_result.status;
|
|
@@ -78,7 +77,7 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
78
77
|
|
|
79
78
|
// it's crucial that we do this before returning the non-SSR response, otherwise
|
|
80
79
|
// SvelteKit will erroneously believe that the path has been prerendered,
|
|
81
|
-
// causing functions to be omitted from the
|
|
80
|
+
// causing functions to be omitted from the manifest generated later
|
|
82
81
|
const should_prerender = get_option(nodes, 'prerender') ?? false;
|
|
83
82
|
if (should_prerender) {
|
|
84
83
|
const mod = leaf_node.server;
|
|
@@ -150,8 +149,7 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
150
149
|
if (parent) Object.assign(data, await parent.data);
|
|
151
150
|
}
|
|
152
151
|
return data;
|
|
153
|
-
}
|
|
154
|
-
track_server_fetches: options.track_server_fetches
|
|
152
|
+
}
|
|
155
153
|
});
|
|
156
154
|
} catch (e) {
|
|
157
155
|
load_error = /** @type {Error} */ (e);
|
|
@@ -222,7 +220,7 @@ export async function render_page(event, page, options, manifest, state, resolve
|
|
|
222
220
|
return redirect_response(err.status, err.location);
|
|
223
221
|
}
|
|
224
222
|
|
|
225
|
-
const status = err
|
|
223
|
+
const status = get_status(err);
|
|
226
224
|
const error = await handle_error_and_jsonify(event, options, err);
|
|
227
225
|
|
|
228
226
|
while (i--) {
|