@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.470",
3
+ "version": "1.0.0-next.473",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -171,20 +171,10 @@ const options = object(
171
171
 
172
172
  inlineStyleThreshold: number(0),
173
173
 
174
- methodOverride: object({
175
- parameter: string('_method'),
176
- allowed: validate([], (input, keypath) => {
177
- if (!Array.isArray(input) || !input.every((method) => typeof method === 'string')) {
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 prerender = result.response.headers.get('x-sveltekit-prerender');
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 = /** @type {string} */ (result.response.headers.get('x-sveltekit-routeid'));
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
- if (config.prerender.crawl && response.headers.get('content-type') === 'text/html') {
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 type = /** @type {string} */ (response.headers.get('content-type'));
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 = response.headers.get('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 (!response.headers.get('x-sveltekit-normalize')) {
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}} {errors}/>`;
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}} {errors}>
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}} {errors} />
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, server_names);
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 errors = 'unknown';
299
+ let type = 'unknown';
299
300
  if (proxy) {
300
- const types = [];
301
- for (const method of ['POST', 'PUT', 'PATCH', 'DELETE']) {
302
- if (proxy.exports.includes(method)) {
303
- // If the file wasn't tweaked, we can use the return type of the original file.
304
- // The advantage is that type updates are reflected without saving.
305
- const from = proxy.modified
306
- ? `./proxy${replace_ext_with_js(basename)}`
307
- : path_to_original(outdir, node.server);
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 Errors = ${errors};`);
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, shared_names);
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 {Set<string>} names
426
+ * @param {boolean} is_server
430
427
  * @returns {Proxy}
431
428
  */
432
- export function tweak_types(content, names) {
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, ' event');
501
+ code.appendLeft(tag.typeExpression.end, ` ${name}`);
499
502
  } else {
500
503
  code.overwrite(tag.pos, tag.end, '');
501
504
  }
502
- modified = true;
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 && names.has(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
- names.has(declaration.name.text) &&
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
  }
@@ -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
@@ -74,7 +74,6 @@ export class Server {
74
74
  },
75
75
  hooks: null,
76
76
  manifest,
77
- method_override: ${s(config.kit.methodOverride)},
78
77
  paths: { base, assets },
79
78
  public_env: {},
80
79
  read,
@@ -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, illegal_imports) {
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(module_node, illegal_imports, extensions);
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(module_node, illegal_imports, extensions);
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
- illegal_imports
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, illegal_imports);
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 {Set<string>} illegal_imports Illegal module IDs -- be sure to call vite.normalizePath!
257
+ * @param {string} lib_dir
232
258
  */
233
- export function prevent_illegal_rollup_imports(node_getter, node, illegal_imports) {
234
- const chain = find_illegal_rollup_imports(node_getter, node, false, illegal_imports);
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 (illegal_imports.has(name)) {
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 {Set<string>} illegal_imports Illegal module IDs -- be sure to call vite.normalizePath!
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, illegal_imports, module_types) {
315
- const chain = find_illegal_vite_imports(node, illegal_imports, get_module_types(module_types));
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, illegal_imports, module_types, seen = new Set()) {
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 (name && illegal_imports.has(name)) {
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, illegal_imports, module_types, seen);
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