@sveltejs/kit 1.0.0-next.468 → 1.0.0-next.470
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 +4 -4
- package/src/core/env.js +11 -2
- package/src/core/sync/create_manifest_data/index.js +20 -0
- package/src/exports/vite/build/build_server.js +7 -1
- package/src/exports/vite/build/utils.js +4 -2
- package/src/exports/vite/dev/index.js +11 -10
- package/src/exports/vite/index.js +8 -2
- package/src/runtime/server/page/fetch.js +147 -153
- package/src/utils/routing.js +0 -20
- package/types/index.d.ts +4 -4
- package/types/internal.d.ts +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/kit",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.470",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/sveltejs/kit",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"homepage": "https://kit.svelte.dev",
|
|
11
11
|
"type": "module",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@sveltejs/vite-plugin-svelte": "^1.0.
|
|
13
|
+
"@sveltejs/vite-plugin-svelte": "^1.0.5",
|
|
14
14
|
"cookie": "^0.5.0",
|
|
15
15
|
"devalue": "^3.1.2",
|
|
16
16
|
"kleur": "^4.1.4",
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"svelte-preprocess": "^4.10.6",
|
|
39
39
|
"typescript": "^4.8.2",
|
|
40
40
|
"uvu": "^0.5.3",
|
|
41
|
-
"vite": "^3.1.0
|
|
41
|
+
"vite": "^3.1.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"svelte": "^3.44.0",
|
|
45
|
-
"vite": "^3.1.0
|
|
45
|
+
"vite": "^3.1.0"
|
|
46
46
|
},
|
|
47
47
|
"bin": {
|
|
48
48
|
"svelte-kit": "svelte-kit.js"
|
package/src/core/env.js
CHANGED
|
@@ -24,8 +24,17 @@ export function create_static_module(id, env) {
|
|
|
24
24
|
return GENERATED_COMMENT + declarations.join('\n\n');
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/**
|
|
28
|
-
|
|
27
|
+
/**
|
|
28
|
+
* @param {'public' | 'private'} type
|
|
29
|
+
* @param {Record<string, string> | undefined} dev_values If in a development mode, values to pre-populate the module with.
|
|
30
|
+
*/
|
|
31
|
+
export function create_dynamic_module(type, dev_values) {
|
|
32
|
+
if (dev_values) {
|
|
33
|
+
const objectKeys = Object.entries(dev_values).map(
|
|
34
|
+
([k, v]) => `${JSON.stringify(k)}: ${JSON.stringify(v)}`
|
|
35
|
+
);
|
|
36
|
+
return `const env = {\n${objectKeys.join(',\n')}\n}\n\nexport { env }`;
|
|
37
|
+
}
|
|
29
38
|
return `export { env } from '${runtime_base}/env-${type}.js';`;
|
|
30
39
|
}
|
|
31
40
|
|
|
@@ -103,6 +103,14 @@ function create_routes_and_nodes(cwd, config, fallback) {
|
|
|
103
103
|
* @param {import('types').RouteData | null} parent
|
|
104
104
|
*/
|
|
105
105
|
const walk = (depth, id, segment, parent) => {
|
|
106
|
+
if (/\]\[/.test(id)) {
|
|
107
|
+
throw new Error(`Invalid route ${id} — parameters must be separated`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (count_occurrences('[', id) !== count_occurrences(']', id)) {
|
|
111
|
+
throw new Error(`Invalid route ${id} — brackets are unbalanced`);
|
|
112
|
+
}
|
|
113
|
+
|
|
106
114
|
const { pattern, names, types } = parse_route_id(id);
|
|
107
115
|
|
|
108
116
|
const segments = id.split('/');
|
|
@@ -450,3 +458,15 @@ function list_files(dir) {
|
|
|
450
458
|
|
|
451
459
|
return files;
|
|
452
460
|
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* @param {string} needle
|
|
464
|
+
* @param {string} haystack
|
|
465
|
+
*/
|
|
466
|
+
function count_occurrences(needle, haystack) {
|
|
467
|
+
let count = 0;
|
|
468
|
+
for (let i = 0; i < haystack.length; i += 1) {
|
|
469
|
+
if (haystack[i] === needle) count += 1;
|
|
470
|
+
}
|
|
471
|
+
return count;
|
|
472
|
+
}
|
|
@@ -110,10 +110,16 @@ export class Server {
|
|
|
110
110
|
|
|
111
111
|
if (!this.options.hooks) {
|
|
112
112
|
const module = await import(${s(hooks)});
|
|
113
|
+
|
|
114
|
+
// TODO remove this for 1.0
|
|
115
|
+
if (module.externalFetch) {
|
|
116
|
+
throw new Error('externalFetch has been removed — use handleFetch instead. See https://github.com/sveltejs/kit/pull/6565 for details');
|
|
117
|
+
}
|
|
118
|
+
|
|
113
119
|
this.options.hooks = {
|
|
114
120
|
handle: module.handle || (({ event, resolve }) => resolve(event)),
|
|
115
121
|
handleError: module.handleError || (({ error }) => console.error(error.stack)),
|
|
116
|
-
|
|
122
|
+
handleFetch: module.handleFetch || (({ request, fetch }) => fetch(request))
|
|
117
123
|
};
|
|
118
124
|
}
|
|
119
125
|
}
|
|
@@ -105,7 +105,8 @@ export function get_default_build_config({ config, input, ssr, outDir }) {
|
|
|
105
105
|
format: 'esm',
|
|
106
106
|
entryFileNames: ssr ? '[name].js' : `${prefix}/[name]-[hash].js`,
|
|
107
107
|
chunkFileNames: ssr ? 'chunks/[name].js' : `${prefix}/chunks/[name]-[hash].js`,
|
|
108
|
-
assetFileNames: `${prefix}/assets/[name]-[hash][extname]
|
|
108
|
+
assetFileNames: `${prefix}/assets/[name]-[hash][extname]`,
|
|
109
|
+
hoistTransitiveImports: false
|
|
109
110
|
},
|
|
110
111
|
preserveEntrySignatures: 'strict'
|
|
111
112
|
},
|
|
@@ -133,7 +134,8 @@ export function get_default_build_config({ config, input, ssr, outDir }) {
|
|
|
133
134
|
rollupOptions: {
|
|
134
135
|
output: {
|
|
135
136
|
entryFileNames: `${prefix}/workers/[name]-[hash].js`,
|
|
136
|
-
chunkFileNames: `${prefix}/workers/chunks/[name]-[hash].js
|
|
137
|
+
chunkFileNames: `${prefix}/workers/chunks/[name]-[hash].js`,
|
|
138
|
+
hoistTransitiveImports: false
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
141
|
}
|
|
@@ -11,7 +11,7 @@ import { load_error_page, load_template } from '../../../core/config/index.js';
|
|
|
11
11
|
import { SVELTE_KIT_ASSETS } from '../../../constants.js';
|
|
12
12
|
import * as sync from '../../../core/sync/sync.js';
|
|
13
13
|
import { get_mime_lookup, runtime_base, runtime_prefix } from '../../../core/utils.js';
|
|
14
|
-
import {
|
|
14
|
+
import { prevent_illegal_vite_imports, resolve_entry } from '../utils.js';
|
|
15
15
|
import { compact } from '../../../utils/array.js';
|
|
16
16
|
|
|
17
17
|
// Vite doesn't expose this so we just copy the list for now
|
|
@@ -269,13 +269,6 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
|
|
|
269
269
|
}
|
|
270
270
|
});
|
|
271
271
|
|
|
272
|
-
const { set_private_env } = await vite.ssrLoadModule(`${runtime_base}/env-private.js`);
|
|
273
|
-
const { set_public_env } = await vite.ssrLoadModule(`${runtime_base}/env-public.js`);
|
|
274
|
-
|
|
275
|
-
const env = get_env(svelte_config.kit.env, vite_config.mode);
|
|
276
|
-
set_private_env(env.private);
|
|
277
|
-
set_public_env(env.public);
|
|
278
|
-
|
|
279
272
|
return () => {
|
|
280
273
|
const serve_static_middleware = vite.middlewares.stack.find(
|
|
281
274
|
(middleware) =>
|
|
@@ -317,6 +310,14 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
|
|
|
317
310
|
|
|
318
311
|
const handle = user_hooks.handle || (({ event, resolve }) => resolve(event));
|
|
319
312
|
|
|
313
|
+
// TODO remove for 1.0
|
|
314
|
+
// @ts-expect-error
|
|
315
|
+
if (user_hooks.externalFetch) {
|
|
316
|
+
throw new Error(
|
|
317
|
+
'externalFetch has been removed — use handleFetch instead. See https://github.com/sveltejs/kit/pull/6565 for details'
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
320
321
|
/** @type {import('types').Hooks} */
|
|
321
322
|
const hooks = {
|
|
322
323
|
handle,
|
|
@@ -331,7 +332,7 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
|
|
|
331
332
|
console.error(colors.gray(error.stack));
|
|
332
333
|
}
|
|
333
334
|
}),
|
|
334
|
-
|
|
335
|
+
handleFetch: user_hooks.handleFetch || (({ request, fetch }) => fetch(request))
|
|
335
336
|
};
|
|
336
337
|
|
|
337
338
|
if (/** @type {any} */ (hooks).getContext) {
|
|
@@ -411,7 +412,7 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
|
|
|
411
412
|
base: svelte_config.kit.paths.base,
|
|
412
413
|
assets
|
|
413
414
|
},
|
|
414
|
-
public_env:
|
|
415
|
+
public_env: {},
|
|
415
416
|
read: (file) => fs.readFileSync(path.join(svelte_config.kit.files.assets, file)),
|
|
416
417
|
root,
|
|
417
418
|
app_template: ({ head, body, assets, nonce }) => {
|
|
@@ -299,9 +299,15 @@ function kit() {
|
|
|
299
299
|
case '\0$env/static/public':
|
|
300
300
|
return create_static_module('$env/static/public', env.public);
|
|
301
301
|
case '\0$env/dynamic/private':
|
|
302
|
-
return create_dynamic_module(
|
|
302
|
+
return create_dynamic_module(
|
|
303
|
+
'private',
|
|
304
|
+
vite_config_env.command === 'serve' ? env.private : undefined
|
|
305
|
+
);
|
|
303
306
|
case '\0$env/dynamic/public':
|
|
304
|
-
return create_dynamic_module(
|
|
307
|
+
return create_dynamic_module(
|
|
308
|
+
'public',
|
|
309
|
+
vite_config_env.command === 'serve' ? env.public : undefined
|
|
310
|
+
);
|
|
305
311
|
}
|
|
306
312
|
},
|
|
307
313
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as cookie from 'cookie';
|
|
2
2
|
import * as set_cookie_parser from 'set-cookie-parser';
|
|
3
3
|
import { respond } from '../index.js';
|
|
4
|
-
import { is_root_relative, resolve } from '../../../utils/url.js';
|
|
5
4
|
import { domain_matches, path_matches } from './cookie.js';
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -20,185 +19,165 @@ export function create_fetch({ event, options, state, route, prerender_default }
|
|
|
20
19
|
const initial_cookies = cookie.parse(event.request.headers.get('cookie') || '');
|
|
21
20
|
|
|
22
21
|
/** @type {import('set-cookie-parser').Cookie[]} */
|
|
23
|
-
const
|
|
22
|
+
const set_cookies = [];
|
|
24
23
|
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
} else {
|
|
33
|
-
requested = resource.url;
|
|
34
|
-
|
|
35
|
-
opts = {
|
|
36
|
-
method: resource.method,
|
|
37
|
-
headers: resource.headers,
|
|
38
|
-
body: resource.body,
|
|
39
|
-
mode: resource.mode,
|
|
40
|
-
credentials: resource.credentials,
|
|
41
|
-
cache: resource.cache,
|
|
42
|
-
redirect: resource.redirect,
|
|
43
|
-
referrer: resource.referrer,
|
|
44
|
-
integrity: resource.integrity,
|
|
45
|
-
...opts
|
|
46
|
-
};
|
|
47
|
-
}
|
|
24
|
+
/**
|
|
25
|
+
* @param {URL} url
|
|
26
|
+
* @param {string | null} header
|
|
27
|
+
*/
|
|
28
|
+
function get_cookie_header(url, header) {
|
|
29
|
+
/** @type {Record<string, string>} */
|
|
30
|
+
const new_cookies = {};
|
|
48
31
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
key !== 'authorization' &&
|
|
55
|
-
key !== 'connection' &&
|
|
56
|
-
key !== 'content-length' &&
|
|
57
|
-
key !== 'cookie' &&
|
|
58
|
-
key !== 'host' &&
|
|
59
|
-
key !== 'if-none-match' &&
|
|
60
|
-
!opts.headers.has(key)
|
|
61
|
-
) {
|
|
62
|
-
opts.headers.set(key, value);
|
|
63
|
-
}
|
|
32
|
+
for (const cookie of set_cookies) {
|
|
33
|
+
if (!domain_matches(url.hostname, cookie.domain)) continue;
|
|
34
|
+
if (!path_matches(url.pathname, cookie.path)) continue;
|
|
35
|
+
|
|
36
|
+
new_cookies[cookie.name] = cookie.value;
|
|
64
37
|
}
|
|
65
38
|
|
|
66
|
-
|
|
39
|
+
// cookies from explicit `cookie` header take precedence over cookies previously set
|
|
40
|
+
// during this load with `set-cookie`, which take precedence over the cookies
|
|
41
|
+
// sent by the user agent
|
|
42
|
+
const combined_cookies = {
|
|
43
|
+
...initial_cookies,
|
|
44
|
+
...new_cookies,
|
|
45
|
+
...cookie.parse(header ?? '')
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return Object.entries(combined_cookies)
|
|
49
|
+
.map(([name, value]) => `${name}=${value}`)
|
|
50
|
+
.join('; ');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** @type {typeof fetch} */
|
|
54
|
+
const fetcher = async (info, init) => {
|
|
55
|
+
const request = normalize_fetch_input(info, init, event.url);
|
|
67
56
|
|
|
68
|
-
|
|
69
|
-
let response;
|
|
57
|
+
const request_body = init?.body;
|
|
70
58
|
|
|
71
59
|
/** @type {import('types').PrerenderDependency} */
|
|
72
60
|
let dependency;
|
|
73
61
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
).slice(1);
|
|
80
|
-
const filename_html = `${filename}/index.html`; // path may also match path/index.html
|
|
62
|
+
const response = await options.hooks.handleFetch({
|
|
63
|
+
event,
|
|
64
|
+
request,
|
|
65
|
+
fetch: async (info, init) => {
|
|
66
|
+
const request = normalize_fetch_input(info, init, event.url);
|
|
81
67
|
|
|
82
|
-
|
|
83
|
-
const is_asset_html = options.manifest.assets.has(filename_html);
|
|
68
|
+
const url = new URL(request.url);
|
|
84
69
|
|
|
85
|
-
|
|
86
|
-
|
|
70
|
+
if (url.origin !== event.url.origin) {
|
|
71
|
+
// allow cookie passthrough for "same-origin"
|
|
72
|
+
// if SvelteKit is serving my.domain.com:
|
|
73
|
+
// - domain.com WILL NOT receive cookies
|
|
74
|
+
// - my.domain.com WILL receive cookies
|
|
75
|
+
// - api.domain.dom WILL NOT receive cookies
|
|
76
|
+
// - sub.my.domain.com WILL receive cookies
|
|
77
|
+
// ports do not affect the resolution
|
|
78
|
+
// leading dot prevents mydomain.com matching domain.com
|
|
79
|
+
if (
|
|
80
|
+
`.${url.hostname}`.endsWith(`.${event.url.hostname}`) &&
|
|
81
|
+
request.credentials !== 'omit'
|
|
82
|
+
) {
|
|
83
|
+
const cookie = get_cookie_header(url, request.headers.get('cookie'));
|
|
84
|
+
if (cookie) request.headers.set('cookie', cookie);
|
|
85
|
+
}
|
|
87
86
|
|
|
88
|
-
|
|
89
|
-
const type = is_asset
|
|
90
|
-
? options.manifest.mimeTypes[filename.slice(filename.lastIndexOf('.'))]
|
|
91
|
-
: 'text/html';
|
|
87
|
+
let response = await fetch(request);
|
|
92
88
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
89
|
+
if (request.mode === 'no-cors') {
|
|
90
|
+
response = new Response('', {
|
|
91
|
+
status: response.status,
|
|
92
|
+
statusText: response.statusText,
|
|
93
|
+
headers: response.headers
|
|
94
|
+
});
|
|
95
|
+
} else {
|
|
96
|
+
if (url.origin !== event.url.origin) {
|
|
97
|
+
const acao = response.headers.get('access-control-allow-origin');
|
|
98
|
+
if (!acao || (acao !== event.url.origin && acao !== '*')) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`CORS error: ${
|
|
101
|
+
acao ? 'Incorrect' : 'No'
|
|
102
|
+
} 'Access-Control-Allow-Origin' header is present on the requested resource`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
102
107
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const combined_cookies = { ...initial_cookies };
|
|
108
|
+
return response;
|
|
109
|
+
}
|
|
106
110
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (!path_matches(resolved, cookie.path)) continue;
|
|
111
|
+
/** @type {Response} */
|
|
112
|
+
let response;
|
|
110
113
|
|
|
111
|
-
|
|
112
|
-
|
|
114
|
+
// handle fetch requests for static assets. e.g. prebaked data, etc.
|
|
115
|
+
// we need to support everything the browser's fetch supports
|
|
116
|
+
const prefix = options.paths.assets || options.paths.base;
|
|
117
|
+
const decoded = decodeURIComponent(url.pathname);
|
|
118
|
+
const filename = (
|
|
119
|
+
decoded.startsWith(prefix) ? decoded.slice(prefix.length) : decoded
|
|
120
|
+
).slice(1);
|
|
121
|
+
const filename_html = `${filename}/index.html`; // path may also match path/index.html
|
|
113
122
|
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
.join('; ');
|
|
123
|
+
const is_asset = options.manifest.assets.has(filename);
|
|
124
|
+
const is_asset_html = options.manifest.assets.has(filename_html);
|
|
117
125
|
|
|
118
|
-
if (
|
|
119
|
-
|
|
120
|
-
}
|
|
126
|
+
if (is_asset || is_asset_html) {
|
|
127
|
+
const file = is_asset ? filename : filename_html;
|
|
121
128
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
129
|
+
if (options.read) {
|
|
130
|
+
const type = is_asset
|
|
131
|
+
? options.manifest.mimeTypes[filename.slice(filename.lastIndexOf('.'))]
|
|
132
|
+
: 'text/html';
|
|
126
133
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
// in this context anyway, so we take the easy route and ban them
|
|
132
|
-
throw new Error('Request body must be a string');
|
|
133
|
-
}
|
|
134
|
+
return new Response(options.read(file), {
|
|
135
|
+
headers: type ? { 'content-type': type } : {}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
134
138
|
|
|
135
|
-
|
|
136
|
-
new Request(new URL(requested, event.url).href, { ...opts }),
|
|
137
|
-
options,
|
|
138
|
-
{
|
|
139
|
-
prerender_default,
|
|
140
|
-
...state,
|
|
141
|
-
initiator: route
|
|
139
|
+
return await fetch(request);
|
|
142
140
|
}
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
if (state.prerendering) {
|
|
146
|
-
dependency = { response, body: null };
|
|
147
|
-
state.prerendering.dependencies.set(resolved, dependency);
|
|
148
|
-
}
|
|
149
|
-
} else {
|
|
150
|
-
// external
|
|
151
|
-
if (resolved.startsWith('//')) {
|
|
152
|
-
requested = event.url.protocol + requested;
|
|
153
|
-
}
|
|
154
141
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
// - domain.com WILL NOT receive cookies
|
|
161
|
-
// - my.domain.com WILL receive cookies
|
|
162
|
-
// - api.domain.dom WILL NOT receive cookies
|
|
163
|
-
// - sub.my.domain.com WILL receive cookies
|
|
164
|
-
// ports do not affect the resolution
|
|
165
|
-
// leading dot prevents mydomain.com matching domain.com
|
|
166
|
-
if (`.${url.hostname}`.endsWith(`.${event.url.hostname}`) && opts.credentials !== 'omit') {
|
|
167
|
-
const cookie = event.request.headers.get('cookie');
|
|
168
|
-
if (cookie) opts.headers.set('cookie', cookie);
|
|
169
|
-
}
|
|
142
|
+
if (request.credentials !== 'omit') {
|
|
143
|
+
const cookie = get_cookie_header(url, request.headers.get('cookie'));
|
|
144
|
+
if (cookie) {
|
|
145
|
+
request.headers.set('cookie', cookie);
|
|
146
|
+
}
|
|
170
147
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
148
|
+
const authorization = event.request.headers.get('authorization');
|
|
149
|
+
if (authorization && !request.headers.has('authorization')) {
|
|
150
|
+
request.headers.set('authorization', authorization);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
175
153
|
|
|
176
|
-
|
|
177
|
-
|
|
154
|
+
if (request_body && typeof request_body !== 'string') {
|
|
155
|
+
// TODO is this still necessary? we just bail out below
|
|
156
|
+
// per https://developer.mozilla.org/en-US/docs/Web/API/Request/Request, this can be a
|
|
157
|
+
// Blob, BufferSource, FormData, URLSearchParams, USVString, or ReadableStream object.
|
|
158
|
+
// non-string bodies are irksome to deal with, but luckily aren't particularly useful
|
|
159
|
+
// in this context anyway, so we take the easy route and ban them
|
|
160
|
+
throw new Error('Request body must be a string');
|
|
161
|
+
}
|
|
178
162
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
headers: response.headers
|
|
163
|
+
response = await respond(request, options, {
|
|
164
|
+
prerender_default,
|
|
165
|
+
...state,
|
|
166
|
+
initiator: route
|
|
184
167
|
});
|
|
185
|
-
|
|
186
|
-
if (
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
throw new Error(
|
|
190
|
-
`CORS error: ${
|
|
191
|
-
acao ? 'Incorrect' : 'No'
|
|
192
|
-
} 'Access-Control-Allow-Origin' header is present on the requested resource`
|
|
193
|
-
);
|
|
194
|
-
}
|
|
168
|
+
|
|
169
|
+
if (state.prerendering) {
|
|
170
|
+
dependency = { response, body: null };
|
|
171
|
+
state.prerendering.dependencies.set(url.pathname, dependency);
|
|
195
172
|
}
|
|
173
|
+
|
|
174
|
+
return response;
|
|
196
175
|
}
|
|
197
|
-
}
|
|
176
|
+
});
|
|
198
177
|
|
|
199
178
|
const set_cookie = response.headers.get('set-cookie');
|
|
200
179
|
if (set_cookie) {
|
|
201
|
-
|
|
180
|
+
set_cookies.push(
|
|
202
181
|
...set_cookie_parser
|
|
203
182
|
.splitCookiesString(set_cookie)
|
|
204
183
|
.map((str) => set_cookie_parser.parseString(str))
|
|
@@ -220,7 +199,7 @@ export function create_fetch({ event, options, state, route, prerender_default }
|
|
|
220
199
|
}
|
|
221
200
|
}
|
|
222
201
|
|
|
223
|
-
if (!
|
|
202
|
+
if (!body || typeof body === 'string') {
|
|
224
203
|
const status_number = Number(response.status);
|
|
225
204
|
if (isNaN(status_number)) {
|
|
226
205
|
throw new Error(
|
|
@@ -231,9 +210,11 @@ export function create_fetch({ event, options, state, route, prerender_default }
|
|
|
231
210
|
}
|
|
232
211
|
|
|
233
212
|
fetched.push({
|
|
234
|
-
url:
|
|
235
|
-
|
|
236
|
-
|
|
213
|
+
url: request.url.startsWith(event.url.origin)
|
|
214
|
+
? request.url.slice(event.url.origin.length)
|
|
215
|
+
: request.url,
|
|
216
|
+
method: request.method,
|
|
217
|
+
body: /** @type {string | undefined} */ (request_body),
|
|
237
218
|
response: {
|
|
238
219
|
status: status_number,
|
|
239
220
|
statusText: response.statusText,
|
|
@@ -284,5 +265,18 @@ export function create_fetch({ event, options, state, route, prerender_default }
|
|
|
284
265
|
return proxy;
|
|
285
266
|
};
|
|
286
267
|
|
|
287
|
-
return { fetcher, fetched, cookies };
|
|
268
|
+
return { fetcher, fetched, cookies: set_cookies };
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* @param {RequestInfo | URL} info
|
|
273
|
+
* @param {RequestInit | undefined} init
|
|
274
|
+
* @param {URL} url
|
|
275
|
+
*/
|
|
276
|
+
function normalize_fetch_input(info, init, url) {
|
|
277
|
+
if (info instanceof Request) {
|
|
278
|
+
return info;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return new Request(typeof info === 'string' ? new URL(info, url) : info, init);
|
|
288
282
|
}
|
package/src/utils/routing.js
CHANGED
|
@@ -12,14 +12,6 @@ export function parse_route_id(id) {
|
|
|
12
12
|
// const add_trailing_slash = !/\.[a-z]+$/.test(key);
|
|
13
13
|
let add_trailing_slash = true;
|
|
14
14
|
|
|
15
|
-
if (/\]\[/.test(id)) {
|
|
16
|
-
throw new Error(`Invalid route ${id} — parameters must be separated`);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (count_occurrences('[', id) !== count_occurrences(']', id)) {
|
|
20
|
-
throw new Error(`Invalid route ${id} — brackets are unbalanced`);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
15
|
const pattern =
|
|
24
16
|
id === ''
|
|
25
17
|
? /^\/$/
|
|
@@ -123,15 +115,3 @@ export function exec(match, names, types, matchers) {
|
|
|
123
115
|
|
|
124
116
|
return params;
|
|
125
117
|
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* @param {string} needle
|
|
129
|
-
* @param {string} haystack
|
|
130
|
-
*/
|
|
131
|
-
function count_occurrences(needle, haystack) {
|
|
132
|
-
let count = 0;
|
|
133
|
-
for (let i = 0; i < haystack.length; i += 1) {
|
|
134
|
-
if (haystack[i] === needle) count += 1;
|
|
135
|
-
}
|
|
136
|
-
return count;
|
|
137
|
-
}
|
package/types/index.d.ts
CHANGED
|
@@ -176,10 +176,6 @@ export interface KitConfig {
|
|
|
176
176
|
};
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
export interface ExternalFetch {
|
|
180
|
-
(req: Request): Promise<Response>;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
179
|
export interface Handle {
|
|
184
180
|
(input: {
|
|
185
181
|
event: RequestEvent;
|
|
@@ -191,6 +187,10 @@ export interface HandleError {
|
|
|
191
187
|
(input: { error: Error & { frame?: string }; event: RequestEvent }): void;
|
|
192
188
|
}
|
|
193
189
|
|
|
190
|
+
export interface HandleFetch {
|
|
191
|
+
(input: { event: RequestEvent; request: Request; fetch: typeof fetch }): MaybePromise<Response>;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
194
|
/**
|
|
195
195
|
* The generic form of `PageLoad` and `LayoutLoad`. You should import those from `./$types` (see [generated types](https://kit.svelte.dev/docs/types#generated-types))
|
|
196
196
|
* rather than using `Load` directly.
|
package/types/internal.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { SvelteComponent } from 'svelte/internal';
|
|
|
3
3
|
import {
|
|
4
4
|
Action,
|
|
5
5
|
Config,
|
|
6
|
-
ExternalFetch,
|
|
7
6
|
ServerLoad,
|
|
8
7
|
Handle,
|
|
9
8
|
HandleError,
|
|
@@ -14,7 +13,8 @@ import {
|
|
|
14
13
|
ResolveOptions,
|
|
15
14
|
Server,
|
|
16
15
|
ServerInitOptions,
|
|
17
|
-
SSRManifest
|
|
16
|
+
SSRManifest,
|
|
17
|
+
HandleFetch
|
|
18
18
|
} from './index.js';
|
|
19
19
|
import {
|
|
20
20
|
HttpMethod,
|
|
@@ -90,9 +90,9 @@ export type CSRRoute = {
|
|
|
90
90
|
export type GetParams = (match: RegExpExecArray) => Record<string, string>;
|
|
91
91
|
|
|
92
92
|
export interface Hooks {
|
|
93
|
-
externalFetch: ExternalFetch;
|
|
94
93
|
handle: Handle;
|
|
95
94
|
handleError: HandleError;
|
|
95
|
+
handleFetch: HandleFetch;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
export interface ImportNode {
|