@sveltejs/kit 1.27.6 → 1.28.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 +3 -3
- package/src/core/sync/write_root.js +1 -0
- package/src/exports/vite/preview/index.js +3 -1
- package/src/runtime/client/client.js +1 -1
- package/src/runtime/server/cookie.js +41 -3
- package/src/runtime/server/fetch.js +14 -2
- package/src/runtime/server/page/load_data.js +18 -8
- package/src/runtime/server/utils.js +14 -0
- package/src/utils/promises.js +45 -1
- package/src/version.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.28.0",
|
|
4
4
|
"description": "The fastest way to build Svelte apps",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"@types/set-cookie-parser": "^2.4.2",
|
|
34
34
|
"dts-buddy": "^0.2.4",
|
|
35
35
|
"rollup": "^3.29.4",
|
|
36
|
-
"svelte": "^4.2.
|
|
37
|
-
"svelte-preprocess": "^5.
|
|
36
|
+
"svelte": "^4.2.7",
|
|
37
|
+
"svelte-preprocess": "^5.1.1",
|
|
38
38
|
"typescript": "^4.9.4",
|
|
39
39
|
"vite": "^4.4.9",
|
|
40
40
|
"vitest": "^0.34.5"
|
|
@@ -39,6 +39,7 @@ export function write_root(manifest_data, output) {
|
|
|
39
39
|
`${output}/root.svelte`,
|
|
40
40
|
dedent`
|
|
41
41
|
<!-- This file is generated by @sveltejs/kit — do not edit it! -->
|
|
42
|
+
${isSvelte5Plus() ? '<svelte:options runes={true} />' : ''}
|
|
42
43
|
<script>
|
|
43
44
|
import { setContext, ${isSvelte5Plus() ? '' : 'afterUpdate, '}onMount, tick } from 'svelte';
|
|
44
45
|
import { browser } from '$app/environment';
|
|
@@ -102,7 +102,7 @@ export async function preview(vite, vite_config, svelte_config) {
|
|
|
102
102
|
return;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
const { pathname } = new URL(/** @type {string} */ (req.url), 'http://dummy');
|
|
105
|
+
const { pathname, search } = new URL(/** @type {string} */ (req.url), 'http://dummy');
|
|
106
106
|
|
|
107
107
|
let filename = normalizePath(
|
|
108
108
|
join(svelte_config.kit.outDir, 'output/prerendered/pages' + pathname)
|
|
@@ -113,6 +113,7 @@ export async function preview(vite, vite_config, svelte_config) {
|
|
|
113
113
|
const has_trailing_slash = pathname.endsWith('/');
|
|
114
114
|
const html_filename = `${filename}${has_trailing_slash ? 'index.html' : '.html'}`;
|
|
115
115
|
|
|
116
|
+
/** @type {string | undefined} */
|
|
116
117
|
let redirect;
|
|
117
118
|
|
|
118
119
|
if (is_file(html_filename)) {
|
|
@@ -127,6 +128,7 @@ export async function preview(vite, vite_config, svelte_config) {
|
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
if (redirect) {
|
|
131
|
+
if (search) redirect += search;
|
|
130
132
|
res.writeHead(307, {
|
|
131
133
|
location: redirect
|
|
132
134
|
});
|
|
@@ -559,7 +559,7 @@ export function create_client(app, target) {
|
|
|
559
559
|
} else {
|
|
560
560
|
data = (await node.universal.load.call(null, load_input)) ?? null;
|
|
561
561
|
}
|
|
562
|
-
data = data ? await unwrap_promises(data) : null;
|
|
562
|
+
data = data ? await unwrap_promises(data, route.id) : null;
|
|
563
563
|
}
|
|
564
564
|
|
|
565
565
|
return {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { parse, serialize } from 'cookie';
|
|
2
|
-
import { normalize_path } from '../../utils/url.js';
|
|
2
|
+
import { normalize_path, resolve } from '../../utils/url.js';
|
|
3
|
+
import { warn_with_callsite } from './utils.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Tracks all cookies set during dev mode so we can emit warnings
|
|
@@ -14,6 +15,27 @@ const cookie_paths = {};
|
|
|
14
15
|
*/
|
|
15
16
|
const MAX_COOKIE_SIZE = 4129;
|
|
16
17
|
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param {import('cookie').CookieSerializeOptions} opts
|
|
21
|
+
* @param {'set' | 'delete' | 'serialize'} method
|
|
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
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
17
39
|
/**
|
|
18
40
|
* @param {Request} request
|
|
19
41
|
* @param {URL} url
|
|
@@ -107,6 +129,7 @@ export function get_cookies(request, url, trailing_slash) {
|
|
|
107
129
|
* @param {import('cookie').CookieSerializeOptions} opts
|
|
108
130
|
*/
|
|
109
131
|
set(name, value, opts = {}) {
|
|
132
|
+
deprecate_missing_path(opts, 'set');
|
|
110
133
|
set_internal(name, value, { ...defaults, ...opts });
|
|
111
134
|
},
|
|
112
135
|
|
|
@@ -115,7 +138,10 @@ export function get_cookies(request, url, trailing_slash) {
|
|
|
115
138
|
* @param {import('cookie').CookieSerializeOptions} opts
|
|
116
139
|
*/
|
|
117
140
|
delete(name, opts = {}) {
|
|
141
|
+
deprecate_missing_path(opts, 'delete');
|
|
142
|
+
|
|
118
143
|
cookies.set(name, '', {
|
|
144
|
+
path: default_path, // TODO 2.0 remove this
|
|
119
145
|
...opts,
|
|
120
146
|
maxAge: 0
|
|
121
147
|
});
|
|
@@ -126,7 +152,9 @@ export function get_cookies(request, url, trailing_slash) {
|
|
|
126
152
|
* @param {string} value
|
|
127
153
|
* @param {import('cookie').CookieSerializeOptions} opts
|
|
128
154
|
*/
|
|
129
|
-
serialize(name, value, opts) {
|
|
155
|
+
serialize(name, value, opts = {}) {
|
|
156
|
+
deprecate_missing_path(opts, 'serialize');
|
|
157
|
+
|
|
130
158
|
return serialize(name, value, {
|
|
131
159
|
...defaults,
|
|
132
160
|
...opts
|
|
@@ -174,7 +202,15 @@ export function get_cookies(request, url, trailing_slash) {
|
|
|
174
202
|
* @param {import('cookie').CookieSerializeOptions} opts
|
|
175
203
|
*/
|
|
176
204
|
function set_internal(name, value, opts) {
|
|
177
|
-
|
|
205
|
+
let path = opts.path;
|
|
206
|
+
|
|
207
|
+
if (!opts.domain || opts.domain === url.hostname) {
|
|
208
|
+
if (path) {
|
|
209
|
+
if (path[0] === '.') path = resolve(url.pathname, path);
|
|
210
|
+
} else {
|
|
211
|
+
path = default_path;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
178
214
|
|
|
179
215
|
new_cookies[name] = {
|
|
180
216
|
name,
|
|
@@ -194,8 +230,10 @@ export function get_cookies(request, url, trailing_slash) {
|
|
|
194
230
|
cookie_paths[name] ??= new Set();
|
|
195
231
|
|
|
196
232
|
if (!value) {
|
|
233
|
+
// @ts-expect-error temporary
|
|
197
234
|
cookie_paths[name].delete(path);
|
|
198
235
|
} else {
|
|
236
|
+
// @ts-expect-error temporary
|
|
199
237
|
cookie_paths[name].add(path);
|
|
200
238
|
}
|
|
201
239
|
}
|
|
@@ -14,7 +14,10 @@ import * as paths from '__sveltekit/paths';
|
|
|
14
14
|
* @returns {typeof fetch}
|
|
15
15
|
*/
|
|
16
16
|
export function create_fetch({ event, options, manifest, state, get_cookie_header, set_internal }) {
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* @type {typeof fetch}
|
|
19
|
+
*/
|
|
20
|
+
const server_fetch = async (info, init) => {
|
|
18
21
|
const original_request = normalize_fetch_input(info, init, event.url);
|
|
19
22
|
|
|
20
23
|
// some runtimes (e.g. Cloudflare) error if you access `request.mode`,
|
|
@@ -23,7 +26,7 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
|
|
|
23
26
|
let credentials =
|
|
24
27
|
(info instanceof Request ? info.credentials : init?.credentials) ?? 'same-origin';
|
|
25
28
|
|
|
26
|
-
return
|
|
29
|
+
return options.hooks.handleFetch({
|
|
27
30
|
event,
|
|
28
31
|
request: original_request,
|
|
29
32
|
fetch: async (info, init) => {
|
|
@@ -144,6 +147,15 @@ export function create_fetch({ event, options, manifest, state, get_cookie_heade
|
|
|
144
147
|
}
|
|
145
148
|
});
|
|
146
149
|
};
|
|
150
|
+
|
|
151
|
+
// Don't make this function `async`! Otherwise, the user has to `catch` promises they use for streaming responses or else
|
|
152
|
+
// it will be an unhandled rejection. Instead, we add a `.catch(() => {})` ourselves below to this from happening.
|
|
153
|
+
return (input, init) => {
|
|
154
|
+
// See docs in fetch.js for why we need to do this
|
|
155
|
+
const response = server_fetch(input, init);
|
|
156
|
+
response.catch(() => {});
|
|
157
|
+
return response;
|
|
158
|
+
};
|
|
147
159
|
}
|
|
148
160
|
|
|
149
161
|
/**
|
|
@@ -125,9 +125,9 @@ export async function load_server_data({
|
|
|
125
125
|
url
|
|
126
126
|
});
|
|
127
127
|
|
|
128
|
-
const data = result ? await unwrap_promises(result) : null;
|
|
128
|
+
const data = result ? await unwrap_promises(result, node.server_id) : null;
|
|
129
129
|
if (__SVELTEKIT_DEV__) {
|
|
130
|
-
validate_load_response(data,
|
|
130
|
+
validate_load_response(data, node.server_id);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
done = true;
|
|
@@ -181,9 +181,9 @@ export async function load_data({
|
|
|
181
181
|
parent
|
|
182
182
|
});
|
|
183
183
|
|
|
184
|
-
const data = result ? await unwrap_promises(result) : null;
|
|
184
|
+
const data = result ? await unwrap_promises(result, node.universal_id) : null;
|
|
185
185
|
if (__SVELTEKIT_DEV__) {
|
|
186
|
-
validate_load_response(data,
|
|
186
|
+
validate_load_response(data, node.universal_id);
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
return data;
|
|
@@ -195,13 +195,14 @@ export async function load_data({
|
|
|
195
195
|
* @param {import('./types.js').Fetched[]} fetched
|
|
196
196
|
* @param {boolean} csr
|
|
197
197
|
* @param {Pick<Required<import('@sveltejs/kit').ResolveOptions>, 'filterSerializedResponseHeaders'>} resolve_opts
|
|
198
|
+
* @returns {typeof fetch}
|
|
198
199
|
*/
|
|
199
200
|
export function create_universal_fetch(event, state, fetched, csr, resolve_opts) {
|
|
200
201
|
/**
|
|
201
202
|
* @param {URL | RequestInfo} input
|
|
202
203
|
* @param {RequestInit} [init]
|
|
203
204
|
*/
|
|
204
|
-
|
|
205
|
+
const universal_fetch = async (input, init) => {
|
|
205
206
|
const cloned_body = input instanceof Request && input.body ? input.clone().body : null;
|
|
206
207
|
|
|
207
208
|
const cloned_headers =
|
|
@@ -329,6 +330,15 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts)
|
|
|
329
330
|
|
|
330
331
|
return proxy;
|
|
331
332
|
};
|
|
333
|
+
|
|
334
|
+
// Don't make this function `async`! Otherwise, the user has to `catch` promises they use for streaming responses or else
|
|
335
|
+
// it will be an unhandled rejection. Instead, we add a `.catch(() => {})` ourselves below to this from happening.
|
|
336
|
+
return (input, init) => {
|
|
337
|
+
// See docs in fetch.js for why we need to do this
|
|
338
|
+
const response = universal_fetch(input, init);
|
|
339
|
+
response.catch(() => {});
|
|
340
|
+
return response;
|
|
341
|
+
};
|
|
332
342
|
}
|
|
333
343
|
|
|
334
344
|
/**
|
|
@@ -350,12 +360,12 @@ async function stream_to_string(stream) {
|
|
|
350
360
|
|
|
351
361
|
/**
|
|
352
362
|
* @param {any} data
|
|
353
|
-
* @param {string} [
|
|
363
|
+
* @param {string} [id]
|
|
354
364
|
*/
|
|
355
|
-
function validate_load_response(data,
|
|
365
|
+
function validate_load_response(data, id) {
|
|
356
366
|
if (data != null && Object.getPrototypeOf(data) !== Object.prototype) {
|
|
357
367
|
throw new Error(
|
|
358
|
-
`a load function
|
|
368
|
+
`a load function in ${id} returned ${
|
|
359
369
|
typeof data !== 'object'
|
|
360
370
|
? `a ${typeof data}`
|
|
361
371
|
: data instanceof Response
|
|
@@ -159,3 +159,17 @@ export function stringify_uses(node) {
|
|
|
159
159
|
|
|
160
160
|
return `"uses":{${uses.join(',')}}`;
|
|
161
161
|
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* @param {string} message
|
|
165
|
+
* @param {number} offset
|
|
166
|
+
*/
|
|
167
|
+
export function warn_with_callsite(message, offset = 0) {
|
|
168
|
+
if (DEV) {
|
|
169
|
+
const stack = fix_stack_trace(new Error()).split('\n');
|
|
170
|
+
const line = stack.at(3 + offset);
|
|
171
|
+
message += `\n${line}`;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
console.warn(message);
|
|
175
|
+
}
|
package/src/utils/promises.js
CHANGED
|
@@ -1,10 +1,54 @@
|
|
|
1
|
+
import { DEV } from 'esm-env';
|
|
2
|
+
|
|
3
|
+
/** @type {Set<string> | null} */
|
|
4
|
+
let warned = null;
|
|
5
|
+
|
|
6
|
+
// TODO v2: remove all references to unwrap_promises
|
|
7
|
+
|
|
1
8
|
/**
|
|
2
9
|
* Given an object, return a new object where all top level values are awaited
|
|
3
10
|
*
|
|
4
11
|
* @param {Record<string, any>} object
|
|
12
|
+
* @param {string | null} [id]
|
|
5
13
|
* @returns {Promise<Record<string, any>>}
|
|
6
14
|
*/
|
|
7
|
-
export async function unwrap_promises(object) {
|
|
15
|
+
export async function unwrap_promises(object, id) {
|
|
16
|
+
if (DEV) {
|
|
17
|
+
/** @type {string[]} */
|
|
18
|
+
const promises = [];
|
|
19
|
+
|
|
20
|
+
for (const key in object) {
|
|
21
|
+
if (typeof object[key]?.then === 'function') {
|
|
22
|
+
promises.push(key);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (promises.length > 0) {
|
|
27
|
+
if (!warned) warned = new Set();
|
|
28
|
+
|
|
29
|
+
const last = promises.pop();
|
|
30
|
+
|
|
31
|
+
const properties =
|
|
32
|
+
promises.length > 0
|
|
33
|
+
? `${promises.map((p) => `"${p}"`).join(', ')} and "${last}" properties`
|
|
34
|
+
: `"${last}" property`;
|
|
35
|
+
|
|
36
|
+
const location = id ? `the \`load\` function in ${id}` : 'a `load` function';
|
|
37
|
+
|
|
38
|
+
const description = promises.length > 0 ? 'are promises' : 'is a promise';
|
|
39
|
+
|
|
40
|
+
const message = `The top-level ${properties} returned from ${location} ${description}.`;
|
|
41
|
+
|
|
42
|
+
if (!warned.has(message)) {
|
|
43
|
+
console.warn(
|
|
44
|
+
`\n${message}\n\nIn SvelteKit 2.0, these will longer be awaited automatically. To get rid of this warning, await all promises included as top-level properties in \`load\` return values.\n`
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
warned.add(message);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
8
52
|
for (const key in object) {
|
|
9
53
|
if (typeof object[key]?.then === 'function') {
|
|
10
54
|
return Object.fromEntries(
|
package/src/version.js
CHANGED