@sveltejs/kit 1.0.0-next.470 → 1.0.0-next.473
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 -1
- package/src/core/config/options.js +4 -14
- package/src/core/prerender/prerender.js +12 -6
- package/src/core/sync/write_root.js +4 -4
- package/src/core/sync/write_types/index.js +104 -26
- package/src/exports/index.js +10 -1
- package/src/exports/node/polyfills.js +3 -2
- package/src/exports/vite/build/build_server.js +0 -1
- package/src/exports/vite/dev/index.js +12 -5
- package/src/exports/vite/index.js +2 -12
- package/src/exports/vite/utils.js +42 -26
- package/src/runtime/app/forms.js +65 -0
- package/src/runtime/client/client.js +122 -58
- package/src/runtime/client/start.js +1 -9
- package/src/runtime/client/types.d.ts +9 -13
- package/src/runtime/control.js +67 -0
- package/src/runtime/server/cookie.js +76 -0
- package/src/runtime/server/endpoint.js +4 -1
- package/src/runtime/server/index.js +27 -42
- package/src/runtime/server/page/actions.js +225 -0
- package/src/runtime/server/page/fetch.js +23 -19
- package/src/runtime/server/page/index.js +37 -133
- package/src/runtime/server/page/render.js +20 -19
- package/src/runtime/server/page/respond_with_error.js +3 -3
- package/src/runtime/server/page/serialize_data.js +32 -17
- package/src/runtime/server/page/types.d.ts +4 -8
- package/src/runtime/server/utils.js +11 -0
- package/types/ambient.d.ts +48 -0
- package/types/index.d.ts +59 -19
- package/types/internal.d.ts +3 -12
- package/types/private.d.ts +0 -3
- package/src/runtime/server/page/cookie.js +0 -25
package/package.json
CHANGED
|
@@ -171,20 +171,10 @@ const options = object(
|
|
|
171
171
|
|
|
172
172
|
inlineStyleThreshold: number(0),
|
|
173
173
|
|
|
174
|
-
methodOverride:
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
throw new Error(`${keypath} must be an array of strings`);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (input.map((i) => i.toUpperCase()).includes('GET')) {
|
|
182
|
-
throw new Error(`${keypath} cannot contain "GET"`);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return input;
|
|
186
|
-
})
|
|
187
|
-
}),
|
|
174
|
+
methodOverride: error(
|
|
175
|
+
() =>
|
|
176
|
+
'Method overrides have been removed in favor of actions. See the PR for more information: https://github.com/sveltejs/kit/pull/6469'
|
|
177
|
+
),
|
|
188
178
|
|
|
189
179
|
moduleExtensions: string_array(['.js', '.ts']),
|
|
190
180
|
|
|
@@ -237,10 +237,11 @@ export async function prerender() {
|
|
|
237
237
|
const encoded_dependency_path = new URL(dependency_path, 'http://localhost').pathname;
|
|
238
238
|
const decoded_dependency_path = decodeURI(encoded_dependency_path);
|
|
239
239
|
|
|
240
|
-
const
|
|
240
|
+
const headers = Object.fromEntries(result.response.headers);
|
|
241
241
|
|
|
242
|
+
const prerender = headers['x-sveltekit-prerender'];
|
|
242
243
|
if (prerender) {
|
|
243
|
-
const route_id =
|
|
244
|
+
const route_id = headers['x-sveltekit-routeid'];
|
|
244
245
|
const existing_value = prerender_map.get(route_id);
|
|
245
246
|
if (existing_value !== 'auto') {
|
|
246
247
|
prerender_map.set(route_id, prerender === 'true' ? true : 'auto');
|
|
@@ -259,7 +260,10 @@ export async function prerender() {
|
|
|
259
260
|
);
|
|
260
261
|
}
|
|
261
262
|
|
|
262
|
-
|
|
263
|
+
// avoid triggering `filterSerializeResponseHeaders` guard
|
|
264
|
+
const headers = Object.fromEntries(response.headers);
|
|
265
|
+
|
|
266
|
+
if (config.prerender.crawl && headers['content-type'] === 'text/html') {
|
|
263
267
|
for (const href of crawl(body.toString())) {
|
|
264
268
|
if (href.startsWith('data:') || href.startsWith('#')) continue;
|
|
265
269
|
|
|
@@ -288,7 +292,9 @@ export async function prerender() {
|
|
|
288
292
|
*/
|
|
289
293
|
function save(category, response, body, decoded, encoded, referrer, referenceType) {
|
|
290
294
|
const response_type = Math.floor(response.status / 100);
|
|
291
|
-
const
|
|
295
|
+
const headers = Object.fromEntries(response.headers);
|
|
296
|
+
|
|
297
|
+
const type = headers['content-type'];
|
|
292
298
|
const is_html = response_type === REDIRECT || type === 'text/html';
|
|
293
299
|
|
|
294
300
|
const file = output_filename(decoded, is_html);
|
|
@@ -297,7 +303,7 @@ export async function prerender() {
|
|
|
297
303
|
if (written.has(file)) return;
|
|
298
304
|
|
|
299
305
|
if (response_type === REDIRECT) {
|
|
300
|
-
const location =
|
|
306
|
+
const location = headers['location'];
|
|
301
307
|
|
|
302
308
|
if (location) {
|
|
303
309
|
const resolved = resolve(encoded, location);
|
|
@@ -305,7 +311,7 @@ export async function prerender() {
|
|
|
305
311
|
enqueue(decoded, decodeURI(resolved), resolved);
|
|
306
312
|
}
|
|
307
313
|
|
|
308
|
-
if (!
|
|
314
|
+
if (!headers['x-sveltekit-normalize']) {
|
|
309
315
|
mkdirp(dirname(dest));
|
|
310
316
|
|
|
311
317
|
log.warn(`${response.status} ${decoded} -> ${location}`);
|
|
@@ -21,16 +21,16 @@ export function write_root(manifest_data, output) {
|
|
|
21
21
|
|
|
22
22
|
let l = max_depth;
|
|
23
23
|
|
|
24
|
-
let pyramid = `<svelte:component this={components[${l}]} data={data_${l}} {
|
|
24
|
+
let pyramid = `<svelte:component this={components[${l}]} data={data_${l}} {form} />`;
|
|
25
25
|
|
|
26
26
|
while (l--) {
|
|
27
27
|
pyramid = `
|
|
28
28
|
{#if components[${l + 1}]}
|
|
29
|
-
<svelte:component this={components[${l}]} data={data_${l}}
|
|
29
|
+
<svelte:component this={components[${l}]} data={data_${l}}>
|
|
30
30
|
${pyramid.replace(/\n/g, '\n\t\t\t\t\t')}
|
|
31
31
|
</svelte:component>
|
|
32
32
|
{:else}
|
|
33
|
-
<svelte:component this={components[${l}]} data={data_${l}} {
|
|
33
|
+
<svelte:component this={components[${l}]} data={data_${l}} {form} />
|
|
34
34
|
{/if}
|
|
35
35
|
`
|
|
36
36
|
.replace(/^\t\t\t/gm, '')
|
|
@@ -50,8 +50,8 @@ export function write_root(manifest_data, output) {
|
|
|
50
50
|
export let page;
|
|
51
51
|
|
|
52
52
|
export let components;
|
|
53
|
+
export let form;
|
|
53
54
|
${levels.map((l) => `export let data_${l} = null;`).join('\n\t\t\t\t')}
|
|
54
|
-
export let errors;
|
|
55
55
|
|
|
56
56
|
if (!browser) {
|
|
57
57
|
setContext('__svelte__', stores);
|
|
@@ -21,9 +21,6 @@ try {
|
|
|
21
21
|
|
|
22
22
|
const cwd = process.cwd();
|
|
23
23
|
|
|
24
|
-
const shared_names = new Set(['load']);
|
|
25
|
-
const server_names = new Set(['load', 'POST', 'PUT', 'PATCH', 'DELETE']); // TODO replace with a single `action`
|
|
26
|
-
|
|
27
24
|
/**
|
|
28
25
|
* Creates types for the whole manifest
|
|
29
26
|
* @param {import('types').ValidatedConfig} config
|
|
@@ -193,6 +190,7 @@ function update_types(config, routes, route) {
|
|
|
193
190
|
|
|
194
191
|
if (route.leaf.server) {
|
|
195
192
|
exports.push(`export type Action = Kit.Action<RouteParams>`);
|
|
193
|
+
exports.push(`export type Actions = Kit.Actions<RouteParams>`);
|
|
196
194
|
}
|
|
197
195
|
}
|
|
198
196
|
|
|
@@ -231,6 +229,9 @@ function update_types(config, routes, route) {
|
|
|
231
229
|
|
|
232
230
|
if (route.endpoint) {
|
|
233
231
|
exports.push(`export type RequestHandler = Kit.RequestHandler<RouteParams>;`);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (route.leaf?.server || route.endpoint) {
|
|
234
235
|
exports.push(`export type RequestEvent = Kit.RequestEvent<RouteParams>;`);
|
|
235
236
|
}
|
|
236
237
|
|
|
@@ -270,7 +271,7 @@ function process_node(node, outdir, is_page, all_pages_have_load = true) {
|
|
|
270
271
|
|
|
271
272
|
if (node.server) {
|
|
272
273
|
const content = fs.readFileSync(node.server, 'utf8');
|
|
273
|
-
const proxy = tweak_types(content,
|
|
274
|
+
const proxy = tweak_types(content, true);
|
|
274
275
|
const basename = path.basename(node.server);
|
|
275
276
|
if (proxy?.modified) {
|
|
276
277
|
fs.writeFileSync(`${outdir}/proxy${basename}`, proxy.code);
|
|
@@ -295,23 +296,19 @@ function process_node(node, outdir, is_page, all_pages_have_load = true) {
|
|
|
295
296
|
exports.push(`export type ${prefix}ServerLoadEvent = Parameters<${prefix}ServerLoad>[0];`);
|
|
296
297
|
|
|
297
298
|
if (is_page) {
|
|
298
|
-
let
|
|
299
|
+
let type = 'unknown';
|
|
299
300
|
if (proxy) {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
types.push(`Kit.AwaitedErrors<typeof import('${from}').${method}>`);
|
|
310
|
-
}
|
|
301
|
+
if (proxy.exports.includes('actions')) {
|
|
302
|
+
// If the file wasn't tweaked, we can use the return type of the original file.
|
|
303
|
+
// The advantage is that type updates are reflected without saving.
|
|
304
|
+
const from = proxy.modified
|
|
305
|
+
? `./proxy${replace_ext_with_js(basename)}`
|
|
306
|
+
: path_to_original(outdir, node.server);
|
|
307
|
+
|
|
308
|
+
type = `Kit.AwaitedActions<typeof import('${from}').actions>`;
|
|
311
309
|
}
|
|
312
|
-
errors = types.length ? types.join(' | ') : 'null';
|
|
313
310
|
}
|
|
314
|
-
exports.push(`export type
|
|
311
|
+
exports.push(`export type ActionData = ${type};`);
|
|
315
312
|
}
|
|
316
313
|
} else {
|
|
317
314
|
server_data = 'null';
|
|
@@ -323,7 +320,7 @@ function process_node(node, outdir, is_page, all_pages_have_load = true) {
|
|
|
323
320
|
|
|
324
321
|
if (node.shared) {
|
|
325
322
|
const content = fs.readFileSync(node.shared, 'utf8');
|
|
326
|
-
const proxy = tweak_types(content,
|
|
323
|
+
const proxy = tweak_types(content, false);
|
|
327
324
|
if (proxy?.modified) {
|
|
328
325
|
fs.writeFileSync(`${outdir}/proxy${path.basename(node.shared)}`, proxy.code);
|
|
329
326
|
written_proxies.push(`proxy${path.basename(node.shared)}`);
|
|
@@ -426,10 +423,12 @@ function replace_ext_with_js(file_path) {
|
|
|
426
423
|
|
|
427
424
|
/**
|
|
428
425
|
* @param {string} content
|
|
429
|
-
* @param {
|
|
426
|
+
* @param {boolean} is_server
|
|
430
427
|
* @returns {Proxy}
|
|
431
428
|
*/
|
|
432
|
-
export function tweak_types(content,
|
|
429
|
+
export function tweak_types(content, is_server) {
|
|
430
|
+
const names = new Set(is_server ? ['load', 'actions'] : ['load']);
|
|
431
|
+
|
|
433
432
|
try {
|
|
434
433
|
let modified = false;
|
|
435
434
|
|
|
@@ -480,6 +479,7 @@ export function tweak_types(content, names) {
|
|
|
480
479
|
* @param {import('typescript').Node} value
|
|
481
480
|
*/
|
|
482
481
|
function replace_jsdoc_type_tags(node, value) {
|
|
482
|
+
let _modified = false;
|
|
483
483
|
// @ts-ignore
|
|
484
484
|
if (node.jsDoc) {
|
|
485
485
|
// @ts-ignore
|
|
@@ -492,22 +492,27 @@ export function tweak_types(content, names) {
|
|
|
492
492
|
ts.isArrowFunction(value);
|
|
493
493
|
|
|
494
494
|
if (is_fn && value.parameters?.length > 0) {
|
|
495
|
+
const name = ts.isIdentifier(value.parameters[0].name)
|
|
496
|
+
? value.parameters[0].name.text
|
|
497
|
+
: 'event';
|
|
495
498
|
code.overwrite(tag.tagName.pos, tag.tagName.end, 'param');
|
|
496
499
|
code.prependRight(tag.typeExpression.pos + 1, 'Parameters<');
|
|
497
500
|
code.appendLeft(tag.typeExpression.end - 1, '>[0]');
|
|
498
|
-
code.appendLeft(tag.typeExpression.end,
|
|
501
|
+
code.appendLeft(tag.typeExpression.end, ` ${name}`);
|
|
499
502
|
} else {
|
|
500
503
|
code.overwrite(tag.pos, tag.end, '');
|
|
501
504
|
}
|
|
502
|
-
|
|
505
|
+
_modified = true;
|
|
503
506
|
}
|
|
504
507
|
}
|
|
505
508
|
}
|
|
506
509
|
}
|
|
510
|
+
modified ||= _modified;
|
|
511
|
+
return _modified;
|
|
507
512
|
}
|
|
508
513
|
|
|
509
514
|
ast.forEachChild((node) => {
|
|
510
|
-
if (ts.isFunctionDeclaration(node) && node.name?.text &&
|
|
515
|
+
if (ts.isFunctionDeclaration(node) && node.name?.text && node.name?.text === 'load') {
|
|
511
516
|
// remove JSDoc comment above `export function load ...`
|
|
512
517
|
replace_jsdoc_type_tags(node, node);
|
|
513
518
|
}
|
|
@@ -525,7 +530,7 @@ export function tweak_types(content, names) {
|
|
|
525
530
|
for (const declaration of node.declarationList.declarations) {
|
|
526
531
|
if (
|
|
527
532
|
ts.isIdentifier(declaration.name) &&
|
|
528
|
-
|
|
533
|
+
declaration.name.text === 'load' &&
|
|
529
534
|
declaration.initializer
|
|
530
535
|
) {
|
|
531
536
|
// edge case — remove JSDoc comment above individual export
|
|
@@ -548,7 +553,6 @@ export function tweak_types(content, names) {
|
|
|
548
553
|
rhs.parameters.length
|
|
549
554
|
) {
|
|
550
555
|
const arg = rhs.parameters[0];
|
|
551
|
-
|
|
552
556
|
const add_parens = content[arg.pos - 1] !== '(';
|
|
553
557
|
|
|
554
558
|
if (add_parens) code.prependRight(arg.pos, '(');
|
|
@@ -569,6 +573,80 @@ export function tweak_types(content, names) {
|
|
|
569
573
|
|
|
570
574
|
modified = true;
|
|
571
575
|
}
|
|
576
|
+
} else if (
|
|
577
|
+
is_server &&
|
|
578
|
+
ts.isIdentifier(declaration.name) &&
|
|
579
|
+
declaration.name?.text === 'actions' &&
|
|
580
|
+
declaration.initializer
|
|
581
|
+
) {
|
|
582
|
+
// remove JSDoc comment from `export const actions = ..`
|
|
583
|
+
const removed = replace_jsdoc_type_tags(node, declaration.initializer);
|
|
584
|
+
// ... and move type to each individual action
|
|
585
|
+
if (removed) {
|
|
586
|
+
const rhs = declaration.initializer;
|
|
587
|
+
if (ts.isObjectLiteralExpression(rhs)) {
|
|
588
|
+
for (const prop of rhs.properties) {
|
|
589
|
+
if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
|
|
590
|
+
const rhs = prop.initializer;
|
|
591
|
+
const replaced = replace_jsdoc_type_tags(prop, rhs);
|
|
592
|
+
if (
|
|
593
|
+
!replaced &&
|
|
594
|
+
rhs &&
|
|
595
|
+
(ts.isArrowFunction(rhs) || ts.isFunctionExpression(rhs)) &&
|
|
596
|
+
rhs.parameters?.[0]
|
|
597
|
+
) {
|
|
598
|
+
const name = ts.isIdentifier(rhs.parameters[0].name)
|
|
599
|
+
? rhs.parameters[0].name.text
|
|
600
|
+
: 'event';
|
|
601
|
+
code.prependRight(
|
|
602
|
+
rhs.pos,
|
|
603
|
+
`/** @param {import('./$types').RequestEvent} ${name} */ `
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// remove type from `export const actions: Actions ...`
|
|
612
|
+
if (declaration.type) {
|
|
613
|
+
let a = declaration.type.pos;
|
|
614
|
+
let b = declaration.type.end;
|
|
615
|
+
while (/\s/.test(content[a])) a += 1;
|
|
616
|
+
|
|
617
|
+
const type = content.slice(a, b);
|
|
618
|
+
code.remove(declaration.name.end, declaration.type.end);
|
|
619
|
+
code.append(`;null as any as ${type};`);
|
|
620
|
+
modified = true;
|
|
621
|
+
|
|
622
|
+
// ... and move type to each individual action
|
|
623
|
+
const rhs = declaration.initializer;
|
|
624
|
+
if (ts.isObjectLiteralExpression(rhs)) {
|
|
625
|
+
for (const prop of rhs.properties) {
|
|
626
|
+
if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
|
|
627
|
+
const rhs = prop.initializer;
|
|
628
|
+
|
|
629
|
+
if (
|
|
630
|
+
rhs &&
|
|
631
|
+
(ts.isArrowFunction(rhs) || ts.isFunctionExpression(rhs)) &&
|
|
632
|
+
rhs.parameters.length
|
|
633
|
+
) {
|
|
634
|
+
const arg = rhs.parameters[0];
|
|
635
|
+
const add_parens = content[arg.pos - 1] !== '(';
|
|
636
|
+
|
|
637
|
+
if (add_parens) code.prependRight(arg.pos, '(');
|
|
638
|
+
|
|
639
|
+
if (arg && !arg.type) {
|
|
640
|
+
code.appendLeft(
|
|
641
|
+
arg.name.end,
|
|
642
|
+
`: import('./$types').RequestEvent` + (add_parens ? ')' : '')
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
572
650
|
}
|
|
573
651
|
}
|
|
574
652
|
}
|
package/src/exports/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HttpError, Redirect } from '../runtime/control.js';
|
|
1
|
+
import { HttpError, Redirect, ValidationError } from '../runtime/control.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Creates an `HttpError` object with an HTTP status code and an optional message.
|
|
@@ -43,3 +43,12 @@ export function json(data, init) {
|
|
|
43
43
|
headers
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Generates a `ValidationError` object.
|
|
49
|
+
* @param {number} status
|
|
50
|
+
* @param {Record<string, any> | undefined} [data]
|
|
51
|
+
*/
|
|
52
|
+
export function invalid(status, data) {
|
|
53
|
+
return new ValidationError(status, data);
|
|
54
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fetch, Response, Request, Headers } from 'undici';
|
|
2
2
|
import { ReadableStream, TransformStream, WritableStream } from 'stream/web';
|
|
3
3
|
import { Readable } from 'stream';
|
|
4
|
-
import { Request as NodeFetchRequest } from 'node-fetch';
|
|
4
|
+
import { Request as NodeFetchRequest, FormData } from 'node-fetch';
|
|
5
5
|
import { webcrypto as crypto } from 'crypto';
|
|
6
6
|
|
|
7
7
|
/** @type {Record<string, any>} */
|
|
@@ -24,7 +24,8 @@ const globals = {
|
|
|
24
24
|
Headers,
|
|
25
25
|
ReadableStream,
|
|
26
26
|
TransformStream,
|
|
27
|
-
WritableStream
|
|
27
|
+
WritableStream,
|
|
28
|
+
FormData
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
// exported for dev/preview and node environments
|
|
@@ -13,6 +13,7 @@ import * as sync from '../../../core/sync/sync.js';
|
|
|
13
13
|
import { get_mime_lookup, runtime_base, runtime_prefix } from '../../../core/utils.js';
|
|
14
14
|
import { prevent_illegal_vite_imports, resolve_entry } from '../utils.js';
|
|
15
15
|
import { compact } from '../../../utils/array.js';
|
|
16
|
+
import { normalizePath } from 'vite';
|
|
16
17
|
|
|
17
18
|
// Vite doesn't expose this so we just copy the list for now
|
|
18
19
|
// https://github.com/vitejs/vite/blob/3edd1af56e980aef56641a5a51cf2932bb580d41/packages/vite/src/node/plugins/css.ts#L96
|
|
@@ -24,10 +25,9 @@ const cwd = process.cwd();
|
|
|
24
25
|
* @param {import('vite').ViteDevServer} vite
|
|
25
26
|
* @param {import('vite').ResolvedConfig} vite_config
|
|
26
27
|
* @param {import('types').ValidatedConfig} svelte_config
|
|
27
|
-
* @param {Set<string>} illegal_imports
|
|
28
28
|
* @return {Promise<Promise<() => void>>}
|
|
29
29
|
*/
|
|
30
|
-
export async function dev(vite, vite_config, svelte_config
|
|
30
|
+
export async function dev(vite, vite_config, svelte_config) {
|
|
31
31
|
installPolyfills();
|
|
32
32
|
|
|
33
33
|
sync.init(svelte_config, vite_config.mode);
|
|
@@ -90,7 +90,11 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
|
|
|
90
90
|
module_nodes.push(module_node);
|
|
91
91
|
result.file = url.endsWith('.svelte') ? url : url + '?import'; // TODO what is this for?
|
|
92
92
|
|
|
93
|
-
prevent_illegal_vite_imports(
|
|
93
|
+
prevent_illegal_vite_imports(
|
|
94
|
+
module_node,
|
|
95
|
+
normalizePath(svelte_config.kit.files.lib),
|
|
96
|
+
extensions
|
|
97
|
+
);
|
|
94
98
|
|
|
95
99
|
return module.default;
|
|
96
100
|
};
|
|
@@ -103,7 +107,11 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
|
|
|
103
107
|
|
|
104
108
|
result.shared = module;
|
|
105
109
|
|
|
106
|
-
prevent_illegal_vite_imports(
|
|
110
|
+
prevent_illegal_vite_imports(
|
|
111
|
+
module_node,
|
|
112
|
+
normalizePath(svelte_config.kit.files.lib),
|
|
113
|
+
extensions
|
|
114
|
+
);
|
|
107
115
|
}
|
|
108
116
|
|
|
109
117
|
if (node.server) {
|
|
@@ -407,7 +415,6 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
|
|
|
407
415
|
},
|
|
408
416
|
hooks,
|
|
409
417
|
manifest,
|
|
410
|
-
method_override: svelte_config.kit.methodOverride,
|
|
411
418
|
paths: {
|
|
412
419
|
base: svelte_config.kit.paths.base,
|
|
413
420
|
assets
|
|
@@ -103,9 +103,6 @@ function kit() {
|
|
|
103
103
|
/** @type {import('types').BuildData} */
|
|
104
104
|
let build_data;
|
|
105
105
|
|
|
106
|
-
/** @type {Set<string>} */
|
|
107
|
-
let illegal_imports;
|
|
108
|
-
|
|
109
106
|
/** @type {string | undefined} */
|
|
110
107
|
let deferred_warning;
|
|
111
108
|
|
|
@@ -212,13 +209,6 @@ function kit() {
|
|
|
212
209
|
client_out_dir: `${svelte_config.kit.outDir}/output/client`
|
|
213
210
|
};
|
|
214
211
|
|
|
215
|
-
illegal_imports = new Set([
|
|
216
|
-
'/@id/__x00__$env/dynamic/private', //dev
|
|
217
|
-
'\0$env/dynamic/private', // prod
|
|
218
|
-
'/@id/__x00__$env/static/private', // dev
|
|
219
|
-
'\0$env/static/private' // prod
|
|
220
|
-
]);
|
|
221
|
-
|
|
222
212
|
if (is_build) {
|
|
223
213
|
manifest_data = (await sync.all(svelte_config, config_env.mode)).manifest_data;
|
|
224
214
|
|
|
@@ -361,7 +351,7 @@ function kit() {
|
|
|
361
351
|
prevent_illegal_rollup_imports(
|
|
362
352
|
this.getModuleInfo.bind(this),
|
|
363
353
|
module_node,
|
|
364
|
-
|
|
354
|
+
vite.normalizePath(svelte_config.kit.files.lib)
|
|
365
355
|
);
|
|
366
356
|
}
|
|
367
357
|
});
|
|
@@ -517,7 +507,7 @@ function kit() {
|
|
|
517
507
|
if (deferred_warning) console.error('\n' + deferred_warning);
|
|
518
508
|
};
|
|
519
509
|
|
|
520
|
-
return await dev(vite, vite_config, svelte_config
|
|
510
|
+
return await dev(vite, vite_config, svelte_config);
|
|
521
511
|
},
|
|
522
512
|
|
|
523
513
|
/**
|
|
@@ -4,6 +4,26 @@ import { loadConfigFromFile, loadEnv, normalizePath } from 'vite';
|
|
|
4
4
|
import { runtime_directory } from '../../core/utils.js';
|
|
5
5
|
import { posixify } from '../../utils/filesystem.js';
|
|
6
6
|
|
|
7
|
+
const illegal_imports = new Set([
|
|
8
|
+
'/@id/__x00__$env/dynamic/private', //dev
|
|
9
|
+
'\0$env/dynamic/private', // prod
|
|
10
|
+
'/@id/__x00__$env/static/private', // dev
|
|
11
|
+
'\0$env/static/private' // prod
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
/** @param {string} id */
|
|
15
|
+
function is_illegal(id) {
|
|
16
|
+
if (illegal_imports.has(id)) return true;
|
|
17
|
+
|
|
18
|
+
// files outside the project root are ignored
|
|
19
|
+
if (!id.startsWith(normalizePath(process.cwd()))) return false;
|
|
20
|
+
|
|
21
|
+
// so are files inside node_modules
|
|
22
|
+
if (id.startsWith(normalizePath(node_modules_dir))) return false;
|
|
23
|
+
|
|
24
|
+
return /.*\.server\..+/.test(path.basename(id));
|
|
25
|
+
}
|
|
26
|
+
|
|
7
27
|
/**
|
|
8
28
|
* @param {import('vite').ResolvedConfig} config
|
|
9
29
|
* @param {import('vite').ConfigEnv} config_env
|
|
@@ -183,8 +203,9 @@ function repeat(str, times) {
|
|
|
183
203
|
/**
|
|
184
204
|
* Create a formatted error for an illegal import.
|
|
185
205
|
* @param {Array<{name: string, dynamic: boolean}>} stack
|
|
206
|
+
* @param {string} lib_dir
|
|
186
207
|
*/
|
|
187
|
-
function format_illegal_import_chain(stack) {
|
|
208
|
+
function format_illegal_import_chain(stack, lib_dir) {
|
|
188
209
|
const dev_virtual_prefix = '/@id/__x00__';
|
|
189
210
|
const prod_virtual_prefix = '\0';
|
|
190
211
|
|
|
@@ -195,6 +216,9 @@ function format_illegal_import_chain(stack) {
|
|
|
195
216
|
if (file.name.startsWith(prod_virtual_prefix)) {
|
|
196
217
|
return { ...file, name: file.name.replace(prod_virtual_prefix, '') };
|
|
197
218
|
}
|
|
219
|
+
if (file.name.startsWith(lib_dir)) {
|
|
220
|
+
return { ...file, name: file.name.replace(lib_dir, '$lib') };
|
|
221
|
+
}
|
|
198
222
|
|
|
199
223
|
return { ...file, name: path.relative(process.cwd(), file.name) };
|
|
200
224
|
});
|
|
@@ -211,6 +235,8 @@ function format_illegal_import_chain(stack) {
|
|
|
211
235
|
return `Cannot import ${stack.at(-1)?.name} into client-side code:\n${pyramid}`;
|
|
212
236
|
}
|
|
213
237
|
|
|
238
|
+
const node_modules_dir = path.resolve(process.cwd(), 'node_modules');
|
|
239
|
+
|
|
214
240
|
/**
|
|
215
241
|
* Load environment variables from process.env and .env files
|
|
216
242
|
* @param {import('types').ValidatedKitConfig['env']} env_config
|
|
@@ -228,11 +254,11 @@ export function get_env(env_config, mode) {
|
|
|
228
254
|
/**
|
|
229
255
|
* @param {(id: string) => import('rollup').ModuleInfo | null} node_getter
|
|
230
256
|
* @param {import('rollup').ModuleInfo} node
|
|
231
|
-
* @param {
|
|
257
|
+
* @param {string} lib_dir
|
|
232
258
|
*/
|
|
233
|
-
export function prevent_illegal_rollup_imports(node_getter, node,
|
|
234
|
-
const chain = find_illegal_rollup_imports(node_getter, node, false
|
|
235
|
-
if (chain) throw new Error(format_illegal_import_chain(chain));
|
|
259
|
+
export function prevent_illegal_rollup_imports(node_getter, node, lib_dir) {
|
|
260
|
+
const chain = find_illegal_rollup_imports(node_getter, node, false);
|
|
261
|
+
if (chain) throw new Error(format_illegal_import_chain(chain, lib_dir));
|
|
236
262
|
}
|
|
237
263
|
|
|
238
264
|
const query_pattern = /\?.*$/s;
|
|
@@ -246,36 +272,27 @@ function remove_query_from_path(path) {
|
|
|
246
272
|
* @param {(id: string) => import('rollup').ModuleInfo | null} node_getter
|
|
247
273
|
* @param {import('rollup').ModuleInfo} node
|
|
248
274
|
* @param {boolean} dynamic
|
|
249
|
-
* @param {Set<string>} illegal_imports Illegal module IDs -- be sure to call vite.normalizePath!
|
|
250
275
|
* @param {Set<string>} seen
|
|
251
276
|
* @returns {Array<import('types').ImportNode> | null}
|
|
252
277
|
*/
|
|
253
|
-
const find_illegal_rollup_imports = (
|
|
254
|
-
node_getter,
|
|
255
|
-
node,
|
|
256
|
-
dynamic,
|
|
257
|
-
illegal_imports,
|
|
258
|
-
seen = new Set()
|
|
259
|
-
) => {
|
|
278
|
+
const find_illegal_rollup_imports = (node_getter, node, dynamic, seen = new Set()) => {
|
|
260
279
|
const name = remove_query_from_path(normalizePath(node.id));
|
|
261
280
|
if (seen.has(name)) return null;
|
|
262
281
|
seen.add(name);
|
|
263
282
|
|
|
264
|
-
if (
|
|
283
|
+
if (is_illegal(name)) {
|
|
265
284
|
return [{ name, dynamic }];
|
|
266
285
|
}
|
|
267
286
|
|
|
268
287
|
for (const id of node.importedIds) {
|
|
269
288
|
const child = node_getter(id);
|
|
270
|
-
const chain =
|
|
271
|
-
child && find_illegal_rollup_imports(node_getter, child, false, illegal_imports, seen);
|
|
289
|
+
const chain = child && find_illegal_rollup_imports(node_getter, child, false, seen);
|
|
272
290
|
if (chain) return [{ name, dynamic }, ...chain];
|
|
273
291
|
}
|
|
274
292
|
|
|
275
293
|
for (const id of node.dynamicallyImportedIds) {
|
|
276
294
|
const child = node_getter(id);
|
|
277
|
-
const chain =
|
|
278
|
-
child && find_illegal_rollup_imports(node_getter, child, true, illegal_imports, seen);
|
|
295
|
+
const chain = child && find_illegal_rollup_imports(node_getter, child, true, seen);
|
|
279
296
|
if (chain) return [{ name, dynamic }, ...chain];
|
|
280
297
|
}
|
|
281
298
|
|
|
@@ -308,22 +325,21 @@ const get_module_types = (config_module_types) => {
|
|
|
308
325
|
/**
|
|
309
326
|
* Throw an error if a private module is imported from a client-side node.
|
|
310
327
|
* @param {import('vite').ModuleNode} node
|
|
311
|
-
* @param {
|
|
328
|
+
* @param {string} lib_dir
|
|
312
329
|
* @param {Iterable<string>} module_types File extensions to analyze in addition to the defaults: `.ts`, `.js`, etc.
|
|
313
330
|
*/
|
|
314
|
-
export function prevent_illegal_vite_imports(node,
|
|
315
|
-
const chain = find_illegal_vite_imports(node,
|
|
316
|
-
if (chain) throw new Error(format_illegal_import_chain(chain));
|
|
331
|
+
export function prevent_illegal_vite_imports(node, lib_dir, module_types) {
|
|
332
|
+
const chain = find_illegal_vite_imports(node, get_module_types(module_types));
|
|
333
|
+
if (chain) throw new Error(format_illegal_import_chain(chain, lib_dir));
|
|
317
334
|
}
|
|
318
335
|
|
|
319
336
|
/**
|
|
320
337
|
* @param {import('vite').ModuleNode} node
|
|
321
|
-
* @param {Set<string>} illegal_imports Illegal module IDs -- be sure to call vite.normalizePath!
|
|
322
338
|
* @param {Set<string>} module_types File extensions to analyze: `.ts`, `.js`, etc.
|
|
323
339
|
* @param {Set<string>} seen
|
|
324
340
|
* @returns {Array<import('types').ImportNode> | null}
|
|
325
341
|
*/
|
|
326
|
-
function find_illegal_vite_imports(node,
|
|
342
|
+
function find_illegal_vite_imports(node, module_types, seen = new Set()) {
|
|
327
343
|
if (!node.id) return null; // TODO when does this happen?
|
|
328
344
|
const name = remove_query_from_path(normalizePath(node.id));
|
|
329
345
|
|
|
@@ -332,12 +348,12 @@ function find_illegal_vite_imports(node, illegal_imports, module_types, seen = n
|
|
|
332
348
|
}
|
|
333
349
|
seen.add(name);
|
|
334
350
|
|
|
335
|
-
if (
|
|
351
|
+
if (is_illegal(name)) {
|
|
336
352
|
return [{ name, dynamic: false }];
|
|
337
353
|
}
|
|
338
354
|
|
|
339
355
|
for (const child of node.importedModules) {
|
|
340
|
-
const chain = child && find_illegal_vite_imports(child,
|
|
356
|
+
const chain = child && find_illegal_vite_imports(child, module_types, seen);
|
|
341
357
|
if (chain) return [{ name, dynamic: false }, ...chain];
|
|
342
358
|
}
|
|
343
359
|
|