@sveltejs/kit 1.0.0-next.430 → 1.0.0-next.433
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 -2
- package/src/core/adapt/builder.js +28 -13
- package/src/core/generate_manifest/index.js +12 -33
- package/src/core/prerender/prerender.js +3 -2
- package/src/core/sync/create_manifest_data/index.js +273 -333
- package/src/core/sync/create_manifest_data/types.d.ts +1 -4
- package/src/core/sync/sync.js +3 -3
- package/src/core/sync/utils.js +0 -11
- package/src/core/sync/write_client_manifest.js +27 -13
- package/src/core/sync/write_root.js +1 -1
- package/src/core/sync/write_types.js +156 -384
- package/src/runtime/client/ambient.d.ts +4 -3
- package/src/runtime/client/client.js +208 -132
- package/src/runtime/client/parse.js +10 -5
- package/src/runtime/client/types.d.ts +10 -29
- package/src/runtime/server/endpoint.js +2 -10
- package/src/runtime/server/index.js +87 -44
- package/src/runtime/server/page/fetch.js +1 -1
- package/src/runtime/server/page/index.js +13 -25
- package/src/runtime/server/page/load_data.js +47 -10
- package/src/utils/array.js +9 -0
- package/src/utils/functions.js +16 -0
- package/src/utils/routing.js +30 -1
- package/src/vite/build/build_server.js +23 -12
- package/src/vite/dev/index.js +22 -30
- package/src/vite/index.js +7 -1
- package/src/vite/preview/index.js +1 -1
- package/types/index.d.ts +1 -1
- package/types/internal.d.ts +103 -41
|
@@ -10,6 +10,7 @@ import { negotiate } from '../../utils/http.js';
|
|
|
10
10
|
import { HttpError, Redirect } from '../../index/private.js';
|
|
11
11
|
import { load_server_data } from './page/load_data.js';
|
|
12
12
|
import { json } from '../../index/index.js';
|
|
13
|
+
import { once } from '../../utils/functions.js';
|
|
13
14
|
|
|
14
15
|
/* global __SVELTEKIT_ADAPTER_NAME__ */
|
|
15
16
|
|
|
@@ -92,7 +93,7 @@ export async function respond(request, options, state) {
|
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
if (route) {
|
|
95
|
-
if (route.
|
|
96
|
+
if (route.page) {
|
|
96
97
|
const normalized = normalize_path(url.pathname, options.trailing_slash);
|
|
97
98
|
|
|
98
99
|
if (normalized !== url.pathname && !state.prerendering?.fallback) {
|
|
@@ -252,21 +253,28 @@ export async function respond(request, options, state) {
|
|
|
252
253
|
if (route) {
|
|
253
254
|
/** @type {Response} */
|
|
254
255
|
let response;
|
|
255
|
-
if (is_data_request && route.
|
|
256
|
+
if (is_data_request && route.page) {
|
|
256
257
|
try {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
258
|
+
const node_ids = [...route.page.layouts, route.page.leaf];
|
|
259
|
+
|
|
260
|
+
const invalidated =
|
|
261
|
+
request.headers.get('x-sveltekit-invalidated')?.split(',').map(Boolean) ??
|
|
262
|
+
node_ids.map(() => true);
|
|
263
|
+
|
|
264
|
+
let aborted = false;
|
|
265
|
+
|
|
266
|
+
const functions = node_ids.map((n, i) => {
|
|
267
|
+
return once(async () => {
|
|
268
|
+
try {
|
|
269
|
+
if (aborted) {
|
|
270
|
+
return /** @type {import('types').ServerDataSkippedNode} */ ({
|
|
271
|
+
type: 'skip'
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// == because it could be undefined (in dev) or null (in build, because of JSON.stringify)
|
|
276
|
+
const node = n == undefined ? n : await options.manifest._.nodes[n]();
|
|
277
|
+
return load_server_data({
|
|
270
278
|
dev: options.dev,
|
|
271
279
|
event,
|
|
272
280
|
node,
|
|
@@ -274,56 +282,91 @@ export async function respond(request, options, state) {
|
|
|
274
282
|
/** @type {Record<string, any>} */
|
|
275
283
|
const data = {};
|
|
276
284
|
for (let j = 0; j < i; j += 1) {
|
|
277
|
-
const parent =
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
285
|
+
const parent = /** @type {import('types').ServerDataNode} */ (
|
|
286
|
+
await functions[j]()
|
|
287
|
+
);
|
|
281
288
|
Object.assign(data, parent.data);
|
|
282
289
|
}
|
|
283
290
|
return data;
|
|
284
291
|
}
|
|
285
|
-
})
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
if (error instanceof Redirect) {
|
|
291
|
-
throw error;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (error instanceof HttpError) {
|
|
295
|
-
return error; // { status, message }
|
|
292
|
+
});
|
|
293
|
+
} catch (e) {
|
|
294
|
+
aborted = true;
|
|
295
|
+
throw e;
|
|
296
296
|
}
|
|
297
|
+
});
|
|
298
|
+
});
|
|
297
299
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
return {
|
|
301
|
-
|
|
302
|
-
};
|
|
300
|
+
const promises = functions.map(async (fn, i) => {
|
|
301
|
+
if (!invalidated[i]) {
|
|
302
|
+
return /** @type {import('types').ServerDataSkippedNode} */ ({
|
|
303
|
+
type: 'skip'
|
|
304
|
+
});
|
|
303
305
|
}
|
|
306
|
+
|
|
307
|
+
return fn();
|
|
304
308
|
});
|
|
305
309
|
|
|
306
|
-
|
|
310
|
+
let length = promises.length;
|
|
311
|
+
const nodes = await Promise.all(
|
|
312
|
+
promises.map((p, i) =>
|
|
313
|
+
p.catch((e) => {
|
|
314
|
+
const error = normalize_error(e);
|
|
315
|
+
|
|
316
|
+
if (error instanceof Redirect) {
|
|
317
|
+
throw error;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Math.min because array isn't guaranteed to resolve in order
|
|
321
|
+
length = Math.min(length, i + 1);
|
|
322
|
+
|
|
323
|
+
if (error instanceof HttpError) {
|
|
324
|
+
return /** @type {import('types').ServerErrorNode} */ ({
|
|
325
|
+
type: 'error',
|
|
326
|
+
httperror: { ...error }
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
options.handle_error(error, event);
|
|
331
|
+
|
|
332
|
+
return /** @type {import('types').ServerErrorNode} */ ({
|
|
333
|
+
type: 'error',
|
|
334
|
+
error: error_to_pojo(error, options.get_stack)
|
|
335
|
+
});
|
|
336
|
+
})
|
|
337
|
+
)
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
/** @type {import('types').ServerData} */
|
|
341
|
+
const server_data = {
|
|
307
342
|
type: 'data',
|
|
308
|
-
nodes:
|
|
309
|
-
}
|
|
343
|
+
nodes: nodes.slice(0, length)
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
response = json(server_data);
|
|
310
347
|
} catch (e) {
|
|
311
348
|
const error = normalize_error(e);
|
|
312
349
|
|
|
313
350
|
if (error instanceof Redirect) {
|
|
314
|
-
|
|
351
|
+
/** @type {import('types').ServerData} */
|
|
352
|
+
const server_data = {
|
|
315
353
|
type: 'redirect',
|
|
316
354
|
location: error.location
|
|
317
|
-
}
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
response = json(server_data);
|
|
318
358
|
} else {
|
|
319
359
|
response = json(error_to_pojo(error, options.get_stack), { status: 500 });
|
|
320
360
|
}
|
|
321
361
|
}
|
|
362
|
+
} else if (route.page) {
|
|
363
|
+
response = await render_page(event, route, route.page, options, state, resolve_opts);
|
|
364
|
+
} else if (route.endpoint) {
|
|
365
|
+
response = await render_endpoint(event, await route.endpoint());
|
|
322
366
|
} else {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
: await render_page(event, route, options, state, resolve_opts);
|
|
367
|
+
// a route will always have a page or an endpoint, but TypeScript
|
|
368
|
+
// doesn't know that
|
|
369
|
+
throw new Error('This should never happen');
|
|
327
370
|
}
|
|
328
371
|
|
|
329
372
|
if (!is_data_request) {
|
|
@@ -9,7 +9,7 @@ import { domain_matches, path_matches } from './cookie.js';
|
|
|
9
9
|
* event: import('types').RequestEvent;
|
|
10
10
|
* options: import('types').SSROptions;
|
|
11
11
|
* state: import('types').SSRState;
|
|
12
|
-
* route: import('types').
|
|
12
|
+
* route: import('types').SSRRoute | import('types').SSRErrorPage;
|
|
13
13
|
* }} opts
|
|
14
14
|
*/
|
|
15
15
|
export function create_fetch({ event, options, state, route }) {
|
|
@@ -5,6 +5,7 @@ import { method_not_allowed, error_to_pojo, allowed_methods } from '../utils.js'
|
|
|
5
5
|
import { create_fetch } from './fetch.js';
|
|
6
6
|
import { HttpError, Redirect } from '../../../index/private.js';
|
|
7
7
|
import { error, json } from '../../../index/index.js';
|
|
8
|
+
import { compact } from '../../../utils/array.js';
|
|
8
9
|
import { normalize_error } from '../../../utils/error.js';
|
|
9
10
|
import { load_data, load_server_data } from './load_data.js';
|
|
10
11
|
|
|
@@ -17,13 +18,14 @@ import { load_data, load_server_data } from './load_data.js';
|
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* @param {import('types').RequestEvent} event
|
|
20
|
-
* @param {import('types').
|
|
21
|
+
* @param {import('types').SSRRoute} route
|
|
22
|
+
* @param {import('types').PageNodeIndexes} page
|
|
21
23
|
* @param {import('types').SSROptions} options
|
|
22
24
|
* @param {import('types').SSRState} state
|
|
23
25
|
* @param {import('types').RequiredResolveOptions} resolve_opts
|
|
24
26
|
* @returns {Promise<Response>}
|
|
25
27
|
*/
|
|
26
|
-
export async function render_page(event, route, options, state, resolve_opts) {
|
|
28
|
+
export async function render_page(event, route, page, options, state, resolve_opts) {
|
|
27
29
|
if (state.initiator === route) {
|
|
28
30
|
// infinite request cycle detected
|
|
29
31
|
return new Response(`Not found: ${event.url.pathname}`, {
|
|
@@ -41,7 +43,7 @@ export async function render_page(event, route, options, state, resolve_opts) {
|
|
|
41
43
|
event.request.method !== 'GET' &&
|
|
42
44
|
event.request.method !== 'HEAD'
|
|
43
45
|
) {
|
|
44
|
-
const node = await options.manifest._.nodes[
|
|
46
|
+
const node = await options.manifest._.nodes[page.leaf]();
|
|
45
47
|
if (node.server) {
|
|
46
48
|
return handle_json_request(event, options, node.server);
|
|
47
49
|
}
|
|
@@ -52,8 +54,8 @@ export async function render_page(event, route, options, state, resolve_opts) {
|
|
|
52
54
|
try {
|
|
53
55
|
const nodes = await Promise.all([
|
|
54
56
|
// we use == here rather than === because [undefined] serializes as "[null]"
|
|
55
|
-
...
|
|
56
|
-
options.manifest._.nodes[
|
|
57
|
+
...page.layouts.map((n) => (n == undefined ? n : options.manifest._.nodes[n]())),
|
|
58
|
+
options.manifest._.nodes[page.leaf]()
|
|
57
59
|
]);
|
|
58
60
|
|
|
59
61
|
const leaf_node = /** @type {import('types').SSRNode} */ (nodes.at(-1));
|
|
@@ -145,7 +147,7 @@ export async function render_page(event, route, options, state, resolve_opts) {
|
|
|
145
147
|
/** @type {Error | null} */
|
|
146
148
|
let load_error = null;
|
|
147
149
|
|
|
148
|
-
/** @type {Array<Promise<
|
|
150
|
+
/** @type {Array<Promise<import('types').ServerDataNode | null>>} */
|
|
149
151
|
const server_promises = nodes.map((node, i) => {
|
|
150
152
|
if (load_error) {
|
|
151
153
|
// if an error happens immediately, don't bother with the rest of the nodes
|
|
@@ -168,7 +170,8 @@ export async function render_page(event, route, options, state, resolve_opts) {
|
|
|
168
170
|
/** @type {Record<string, any>} */
|
|
169
171
|
const data = {};
|
|
170
172
|
for (let j = 0; j < i; j += 1) {
|
|
171
|
-
|
|
173
|
+
const parent = await server_promises[j];
|
|
174
|
+
if (parent) Object.assign(data, await parent.data);
|
|
172
175
|
}
|
|
173
176
|
return data;
|
|
174
177
|
}
|
|
@@ -243,8 +246,8 @@ export async function render_page(event, route, options, state, resolve_opts) {
|
|
|
243
246
|
const status = error instanceof HttpError ? error.status : 500;
|
|
244
247
|
|
|
245
248
|
while (i--) {
|
|
246
|
-
if (
|
|
247
|
-
const index = /** @type {number} */ (
|
|
249
|
+
if (page.errors[i]) {
|
|
250
|
+
const index = /** @type {number} */ (page.errors[i]);
|
|
248
251
|
const node = await options.manifest._.nodes[index]();
|
|
249
252
|
|
|
250
253
|
let j = i;
|
|
@@ -291,7 +294,7 @@ export async function render_page(event, route, options, state, resolve_opts) {
|
|
|
291
294
|
response: new Response(undefined),
|
|
292
295
|
body: JSON.stringify({
|
|
293
296
|
type: 'data',
|
|
294
|
-
nodes: branch.map((branch_node) =>
|
|
297
|
+
nodes: branch.map((branch_node) => branch_node?.server_data)
|
|
295
298
|
})
|
|
296
299
|
});
|
|
297
300
|
}
|
|
@@ -399,18 +402,3 @@ function redirect_response(status, location) {
|
|
|
399
402
|
headers: { location }
|
|
400
403
|
});
|
|
401
404
|
}
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* @template T
|
|
405
|
-
* @param {Array<T | null>} array
|
|
406
|
-
* @returns {T[]}
|
|
407
|
-
*/
|
|
408
|
-
function compact(array) {
|
|
409
|
-
const compacted = [];
|
|
410
|
-
for (const item of array) {
|
|
411
|
-
if (item) {
|
|
412
|
-
compacted.push(item);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
return compacted;
|
|
416
|
-
}
|
|
@@ -8,19 +8,46 @@ import { LoadURL, PrerenderingURL } from '../../../utils/url.js';
|
|
|
8
8
|
* node: import('types').SSRNode | undefined;
|
|
9
9
|
* parent: () => Promise<Record<string, any>>;
|
|
10
10
|
* }} opts
|
|
11
|
+
* @returns {Promise<import('types').ServerDataNode | null>}
|
|
11
12
|
*/
|
|
12
13
|
export async function load_server_data({ dev, event, node, parent }) {
|
|
13
14
|
if (!node?.server) return null;
|
|
14
15
|
|
|
15
|
-
const
|
|
16
|
+
const uses = {
|
|
17
|
+
dependencies: new Set(),
|
|
18
|
+
params: new Set(),
|
|
19
|
+
parent: false,
|
|
20
|
+
url: false
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/** @param {string[]} deps */
|
|
24
|
+
function depends(...deps) {
|
|
25
|
+
for (const dep of deps) {
|
|
26
|
+
const { href } = new URL(dep, event.url);
|
|
27
|
+
uses.dependencies.add(href);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const params = new Proxy(event.params, {
|
|
32
|
+
get: (target, key) => {
|
|
33
|
+
uses.params.add(key);
|
|
34
|
+
return target[/** @type {string} */ (key)];
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const result = await node.server.load?.call(null, {
|
|
16
39
|
// can't use destructuring here because it will always
|
|
17
40
|
// invoke event.clientAddress, which breaks prerendering
|
|
18
41
|
get clientAddress() {
|
|
19
42
|
return event.clientAddress;
|
|
20
43
|
},
|
|
44
|
+
depends,
|
|
21
45
|
locals: event.locals,
|
|
22
|
-
params
|
|
23
|
-
parent
|
|
46
|
+
params,
|
|
47
|
+
parent: async () => {
|
|
48
|
+
uses.parent = true;
|
|
49
|
+
return parent();
|
|
50
|
+
},
|
|
24
51
|
platform: event.platform,
|
|
25
52
|
request: event.request,
|
|
26
53
|
routeId: event.routeId,
|
|
@@ -28,13 +55,22 @@ export async function load_server_data({ dev, event, node, parent }) {
|
|
|
28
55
|
url: event.url
|
|
29
56
|
});
|
|
30
57
|
|
|
31
|
-
const
|
|
58
|
+
const data = result ? await unwrap_promises(result) : null;
|
|
32
59
|
|
|
33
60
|
if (dev) {
|
|
34
|
-
check_serializability(
|
|
61
|
+
check_serializability(data, /** @type {string} */ (node.server_id), 'data');
|
|
35
62
|
}
|
|
36
63
|
|
|
37
|
-
return
|
|
64
|
+
return {
|
|
65
|
+
type: 'data',
|
|
66
|
+
data,
|
|
67
|
+
uses: {
|
|
68
|
+
dependencies: uses.dependencies.size > 0 ? Array.from(uses.dependencies) : undefined,
|
|
69
|
+
params: uses.params.size > 0 ? Array.from(uses.params) : undefined,
|
|
70
|
+
parent: uses.parent ? 1 : undefined,
|
|
71
|
+
url: uses.url ? 1 : undefined
|
|
72
|
+
}
|
|
73
|
+
};
|
|
38
74
|
}
|
|
39
75
|
|
|
40
76
|
/**
|
|
@@ -44,21 +80,22 @@ export async function load_server_data({ dev, event, node, parent }) {
|
|
|
44
80
|
* fetcher: typeof fetch;
|
|
45
81
|
* node: import('types').SSRNode | undefined;
|
|
46
82
|
* parent: () => Promise<Record<string, any>>;
|
|
47
|
-
* server_data_promise: Promise<
|
|
83
|
+
* server_data_promise: Promise<import('types').ServerDataNode | null>;
|
|
48
84
|
* state: import('types').SSRState;
|
|
49
85
|
* }} opts
|
|
86
|
+
* @returns {Promise<Record<string, any> | null>}
|
|
50
87
|
*/
|
|
51
88
|
export async function load_data({ event, fetcher, node, parent, server_data_promise, state }) {
|
|
52
|
-
const
|
|
89
|
+
const server_data_node = await server_data_promise;
|
|
53
90
|
|
|
54
91
|
if (!node?.shared?.load) {
|
|
55
|
-
return
|
|
92
|
+
return server_data_node?.data ?? null;
|
|
56
93
|
}
|
|
57
94
|
|
|
58
95
|
const load_input = {
|
|
59
96
|
url: state.prerendering ? new PrerenderingURL(event.url) : new LoadURL(event.url),
|
|
60
97
|
params: event.params,
|
|
61
|
-
data:
|
|
98
|
+
data: server_data_node?.data ?? null,
|
|
62
99
|
routeId: event.routeId,
|
|
63
100
|
fetch: fetcher,
|
|
64
101
|
setHeaders: event.setHeaders,
|
package/src/utils/routing.js
CHANGED
|
@@ -12,12 +12,21 @@ 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
|
+
|
|
15
23
|
const pattern =
|
|
16
24
|
id === ''
|
|
17
25
|
? /^\/$/
|
|
18
26
|
: new RegExp(
|
|
19
27
|
`^${id
|
|
20
|
-
.split(/(
|
|
28
|
+
.split(/(?:\/|$)/)
|
|
29
|
+
.filter(affects_path)
|
|
21
30
|
.map((segment, i, segments) => {
|
|
22
31
|
const decoded_segment = decodeURIComponent(segment);
|
|
23
32
|
// special case — /[...rest]/ could contain zero segments
|
|
@@ -79,6 +88,14 @@ export function parse_route_id(id) {
|
|
|
79
88
|
return { pattern, names, types };
|
|
80
89
|
}
|
|
81
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Returns `false` for `(group)` segments
|
|
93
|
+
* @param {string} segment
|
|
94
|
+
*/
|
|
95
|
+
export function affects_path(segment) {
|
|
96
|
+
return !/^\([^)]+\)$/.test(segment);
|
|
97
|
+
}
|
|
98
|
+
|
|
82
99
|
/**
|
|
83
100
|
* @param {RegExpMatchArray} match
|
|
84
101
|
* @param {string[]} names
|
|
@@ -106,3 +123,15 @@ export function exec(match, names, types, matchers) {
|
|
|
106
123
|
|
|
107
124
|
return params;
|
|
108
125
|
}
|
|
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
|
+
}
|
|
@@ -84,7 +84,12 @@ export class Server {
|
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Take care: Some adapters may have to call \`Server.init\` per-request to set env vars,
|
|
89
|
+
* so anything that shouldn't be rerun should be wrapped in an \`if\` block to make sure it hasn't
|
|
90
|
+
* been done already.
|
|
91
|
+
*/
|
|
92
|
+
async init({ env }) {
|
|
88
93
|
const entries = Object.entries(env);
|
|
89
94
|
|
|
90
95
|
const prv = Object.fromEntries(entries.filter(([k]) => !k.startsWith('${
|
|
@@ -99,12 +104,6 @@ export class Server {
|
|
|
99
104
|
set_public_env(pub);
|
|
100
105
|
|
|
101
106
|
this.options.public_env = pub;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async respond(request, options = {}) {
|
|
105
|
-
if (!(request instanceof Request)) {
|
|
106
|
-
throw new Error('The first argument to server.respond must be a Request object. See https://github.com/sveltejs/kit/pull/3384 for details');
|
|
107
|
-
}
|
|
108
107
|
|
|
109
108
|
if (!this.options.hooks) {
|
|
110
109
|
const module = await import(${s(hooks)});
|
|
@@ -114,6 +113,12 @@ export class Server {
|
|
|
114
113
|
externalFetch: module.externalFetch || fetch
|
|
115
114
|
};
|
|
116
115
|
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async respond(request, options = {}) {
|
|
119
|
+
if (!(request instanceof Request)) {
|
|
120
|
+
throw new Error('The first argument to server.respond must be a Request object. See https://github.com/sveltejs/kit/pull/3384 for details');
|
|
121
|
+
}
|
|
117
122
|
|
|
118
123
|
return respond(request, this.options, options);
|
|
119
124
|
}
|
|
@@ -158,8 +163,8 @@ export async function build_server(options, client) {
|
|
|
158
163
|
|
|
159
164
|
// add entry points for every endpoint...
|
|
160
165
|
manifest_data.routes.forEach((route) => {
|
|
161
|
-
if (route.
|
|
162
|
-
const resolved = path.resolve(cwd, route.file);
|
|
166
|
+
if (route.endpoint) {
|
|
167
|
+
const resolved = path.resolve(cwd, route.endpoint.file);
|
|
163
168
|
const relative = decodeURIComponent(path.relative(config.kit.files.routes, resolved));
|
|
164
169
|
const name = posixify(path.join('entries/endpoints', relative.replace(/\.js$/, '')));
|
|
165
170
|
input[name] = resolved;
|
|
@@ -326,10 +331,16 @@ function get_methods(cwd, output, manifest_data) {
|
|
|
326
331
|
/** @type {Record<string, import('types').HttpMethod[]>} */
|
|
327
332
|
const methods = {};
|
|
328
333
|
manifest_data.routes.forEach((route) => {
|
|
329
|
-
|
|
334
|
+
if (route.endpoint) {
|
|
335
|
+
if (lookup[route.endpoint.file]) {
|
|
336
|
+
methods[route.endpoint.file] = lookup[route.endpoint.file].filter(is_http_method);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
330
339
|
|
|
331
|
-
if (
|
|
332
|
-
|
|
340
|
+
if (route.leaf?.server) {
|
|
341
|
+
if (lookup[route.leaf.server]) {
|
|
342
|
+
methods[route.leaf.server] = lookup[route.leaf.server].filter(is_http_method);
|
|
343
|
+
}
|
|
333
344
|
}
|
|
334
345
|
});
|
|
335
346
|
|
package/src/vite/dev/index.js
CHANGED
|
@@ -7,12 +7,12 @@ import { getRequest, setResponse } from '../../node/index.js';
|
|
|
7
7
|
import { installPolyfills } from '../../node/polyfills.js';
|
|
8
8
|
import { coalesce_to_error } from '../../utils/error.js';
|
|
9
9
|
import { posixify } from '../../utils/filesystem.js';
|
|
10
|
-
import { parse_route_id } from '../../utils/routing.js';
|
|
11
10
|
import { load_template } from '../../core/config/index.js';
|
|
12
11
|
import { SVELTE_KIT_ASSETS } from '../../core/constants.js';
|
|
13
12
|
import * as sync from '../../core/sync/sync.js';
|
|
14
13
|
import { get_mime_lookup, runtime_base, runtime_prefix } from '../../core/utils.js';
|
|
15
14
|
import { get_env, prevent_illegal_vite_imports, resolve_entry } from '../utils.js';
|
|
15
|
+
import { compact } from '../../utils/array.js';
|
|
16
16
|
|
|
17
17
|
// Vite doesn't expose this so we just copy the list for now
|
|
18
18
|
// https://github.com/vitejs/vite/blob/3edd1af56e980aef56641a5a51cf2932bb580d41/packages/vite/src/node/plugins/css.ts#L96
|
|
@@ -149,36 +149,27 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
|
|
|
149
149
|
return result;
|
|
150
150
|
};
|
|
151
151
|
}),
|
|
152
|
-
routes:
|
|
153
|
-
|
|
152
|
+
routes: compact(
|
|
153
|
+
manifest_data.routes.map((route) => {
|
|
154
|
+
if (!route.page && !route.endpoint) return null;
|
|
155
|
+
|
|
156
|
+
const endpoint = route.endpoint;
|
|
154
157
|
|
|
155
|
-
if (route.type === 'page') {
|
|
156
158
|
return {
|
|
157
|
-
type: 'page',
|
|
158
159
|
id: route.id,
|
|
159
|
-
pattern,
|
|
160
|
-
names,
|
|
161
|
-
types,
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
160
|
+
pattern: route.pattern,
|
|
161
|
+
names: route.names,
|
|
162
|
+
types: route.types,
|
|
163
|
+
page: route.page,
|
|
164
|
+
endpoint: endpoint
|
|
165
|
+
? async () => {
|
|
166
|
+
const url = path.resolve(cwd, endpoint.file);
|
|
167
|
+
return await vite.ssrLoadModule(url);
|
|
168
|
+
}
|
|
169
|
+
: null
|
|
167
170
|
};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return {
|
|
171
|
-
type: 'endpoint',
|
|
172
|
-
id: route.id,
|
|
173
|
-
pattern,
|
|
174
|
-
names,
|
|
175
|
-
types,
|
|
176
|
-
load: async () => {
|
|
177
|
-
const url = path.resolve(cwd, route.file);
|
|
178
|
-
return await vite.ssrLoadModule(url);
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
}),
|
|
171
|
+
})
|
|
172
|
+
),
|
|
182
173
|
matchers: async () => {
|
|
183
174
|
/** @type {Record<string, import('types').ParamMatcher>} */
|
|
184
175
|
const matchers = {};
|
|
@@ -229,15 +220,16 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
|
|
|
229
220
|
to_run();
|
|
230
221
|
}, 100);
|
|
231
222
|
};
|
|
223
|
+
|
|
232
224
|
// Debounce add/unlink events because in case of folder deletion or moves
|
|
233
225
|
// they fire in rapid succession, causing needless invocations.
|
|
234
226
|
watch('add', () => debounce(update_manifest));
|
|
235
227
|
watch('unlink', () => debounce(update_manifest));
|
|
236
228
|
watch('change', (file) => {
|
|
237
229
|
// Don't run for a single file if the whole manifest is about to get updated
|
|
238
|
-
if (
|
|
239
|
-
|
|
240
|
-
|
|
230
|
+
if (timeout) return;
|
|
231
|
+
|
|
232
|
+
sync.update(svelte_config, manifest_data, file);
|
|
241
233
|
});
|
|
242
234
|
|
|
243
235
|
const assets = svelte_config.kit.paths.assets ? SVELTE_KIT_ASSETS : svelte_config.kit.paths.base;
|
package/src/vite/index.js
CHANGED
|
@@ -411,7 +411,13 @@ function kit() {
|
|
|
411
411
|
|
|
412
412
|
const child = fork(
|
|
413
413
|
script,
|
|
414
|
-
[
|
|
414
|
+
[
|
|
415
|
+
vite_config.build.outDir,
|
|
416
|
+
results_path,
|
|
417
|
+
manifest_path,
|
|
418
|
+
'' + verbose,
|
|
419
|
+
JSON.stringify({ ...env.private, ...env.public })
|
|
420
|
+
],
|
|
415
421
|
{
|
|
416
422
|
stdio: 'inherit'
|
|
417
423
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -264,7 +264,7 @@ export interface ResolveOptions {
|
|
|
264
264
|
|
|
265
265
|
export class Server {
|
|
266
266
|
constructor(manifest: SSRManifest);
|
|
267
|
-
init(options: ServerInitOptions): void
|
|
267
|
+
init(options: ServerInitOptions): Promise<void>;
|
|
268
268
|
respond(request: Request, options: RequestOptions): Promise<Response>;
|
|
269
269
|
}
|
|
270
270
|
|