@depup/nuxt__kit 4.4.2-depup.0 → 4.5.1-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -4,9 +4,13 @@ import { applyDefaults } from "untyped";
4
4
  import { consola } from "consola";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { getContext } from "unctx";
7
- import satisfies from "semver/functions/satisfies.js";
7
+ import { createConsoleReporter, defineDiagnostics } from "nostics";
8
+ import process from "node:process";
9
+ import { ansiFormatter } from "nostics/formatters/ansi";
10
+ import { colors } from "consola/utils";
11
+ import { isGreater, isGreaterOrEqual, satisfies } from "verkit";
8
12
  import { readPackageJSON, resolvePackageJSON } from "pkg-types";
9
- import { existsSync, lstatSync, promises, readFileSync } from "node:fs";
13
+ import { existsSync, lstatSync, promises, readFileSync, realpathSync, statSync } from "node:fs";
10
14
  import { fileURLToPath, pathToFileURL } from "node:url";
11
15
  import { basename, dirname, isAbsolute, join, normalize, parse, relative, resolve } from "pathe";
12
16
  import { createJiti } from "jiti";
@@ -14,16 +18,15 @@ import { interopDefault, lookupNodeModuleSubpath, parseNodeModulePath, resolveMo
14
18
  import { resolveModulePath, resolveModuleURL } from "exsolve";
15
19
  import { isRelative, withTrailingSlash, withoutTrailingSlash } from "ufo";
16
20
  import { read, update } from "rc9";
17
- import semver, { gte } from "semver";
18
21
  import { captureStackTrace } from "errx";
19
- import process from "node:process";
20
22
  import { glob } from "tinyglobby";
21
23
  import { resolveAlias as resolveAlias$1, reverseResolveAlias } from "pathe/utils";
22
24
  import ignore from "ignore";
23
- import { loadConfig } from "c12";
25
+ import { loadConfig, setupDotenv } from "c12";
26
+ import { klona } from "klona/full";
24
27
  import destr from "destr";
25
28
  import { kebabCase, pascalCase, snakeCase } from "scule";
26
- import { klona } from "klona";
29
+ import { klona as klona$1 } from "klona";
27
30
  import { hash } from "ohash";
28
31
  import { isAbsolute as isAbsolute$1 } from "node:path";
29
32
  //#region src/logger.ts
@@ -32,6 +35,123 @@ function useLogger(tag, options = {}) {
32
35
  return tag ? logger.create(options).withTag(tag) : logger;
33
36
  }
34
37
  //#endregion
38
+ //#region src/diagnostics/_shared.ts
39
+ /**
40
+ * Resolve the docs URL for a stable `NUXT_B<NNNN>` code.
41
+ *
42
+ * Codes with a dedicated docs page pass this as their `see:` URL; codes whose
43
+ * inline why+fix is self-sufficient opt out with `docs: false`.
44
+ */
45
+ const docsBase = (code) => `https://nuxt.com/docs/4.x/errors/${code.replace("NUXT_", "").toLowerCase()}`;
46
+ const reporters = [/* @__PURE__ */ createConsoleReporter(process.env.NODE_ENV === "test" ? void 0 : { formatter: ansiFormatter(colors) })];
47
+ //#endregion
48
+ //#region src/diagnostics/kit-api.ts
49
+ /**
50
+ * B8xxx
51
+ * Kit API diagnostics.
52
+ */
53
+ const kitDiagnostics = /* #__PURE__ */ defineDiagnostics({
54
+ docsBase,
55
+ reporters,
56
+ codes: {
57
+ NUXT_B8001: {
58
+ why: "The active Nuxt instance is unavailable in the current context.",
59
+ fix: "Call this within a Nuxt module `setup()` function, or inside a `nuxt.hook()` callback.",
60
+ docs: false
61
+ },
62
+ NUXT_B8002: {
63
+ why: "The `base` argument to `createResolver(base)` is missing.",
64
+ fix: "Pass `import.meta.url` or a directory path as the `base` argument to `createResolver()`.",
65
+ docs: false
66
+ },
67
+ NUXT_B8003: {
68
+ why: "Nitro is not initialized yet: `useNitro()` was called before the `ready` hook ran.",
69
+ fix: "Move the `useNitro()` call inside a hook that runs after initialization, such as `nuxt.hook('ready', () => { ... })`.",
70
+ docs: false
71
+ },
72
+ NUXT_B8004: {
73
+ why: (p) => `Nuxt compatibility issues were found:\n${p.issues}`,
74
+ fix: "Update the module to support the current Nuxt version, or check if a newer version of the module is available.",
75
+ docs: false
76
+ },
77
+ NUXT_B8005: {
78
+ why: "The Nuxt version cannot be determined: no current instance was passed.",
79
+ fix: "Pass a valid Nuxt instance to `getNuxtVersion()`, or ensure `useNuxt()` is available in the current context.",
80
+ docs: false
81
+ },
82
+ NUXT_B8006: {
83
+ why: (p) => `No Nuxt version could be found from \`${p.cwd}\`.`,
84
+ fix: "Run `npm install nuxt` in your project directory to install Nuxt.",
85
+ docs: false
86
+ },
87
+ NUXT_B8007: {
88
+ why: (p) => `The type template filename \`${p.template}\` is invalid.`,
89
+ fix: "Rename the template filename to end with `.d.ts`.",
90
+ docs: false
91
+ },
92
+ NUXT_B8008: {
93
+ why: (p) => `The template value is invalid: ${p.template}.`,
94
+ fix: "Pass a valid template object or a string path to `addTemplate()`.",
95
+ docs: false
96
+ },
97
+ NUXT_B8009: {
98
+ why: (p) => `The template was not found at \`${p.template}\`.`,
99
+ fix: "Check that the `src` path exists and is an absolute path or resolvable from the module directory.",
100
+ docs: false
101
+ },
102
+ NUXT_B8010: {
103
+ why: (p) => `The template \`${p.template}\` provides neither \`getContents\` nor \`src\`.`,
104
+ fix: "Add a `getContents` function or a `src` path to the template object.",
105
+ docs: false
106
+ },
107
+ NUXT_B8011: {
108
+ why: (p) => `The template is missing a \`filename\`: ${p.template}.`,
109
+ fix: "Add a `filename` property to the template object, or provide a `src` path so the filename can be derived from it.",
110
+ docs: false
111
+ },
112
+ NUXT_B8012: {
113
+ why: (p) => `\`${p.name}\` was used outside of a Nuxt context.`,
114
+ fix: "Register this module in the `modules` array of `nuxt.config` rather than calling it directly.",
115
+ docs: false
116
+ },
117
+ NUXT_B8013: {
118
+ why: (p) => p.message,
119
+ fix: "Update the module to a version that supports the current Nuxt version, or set `experimental.enforceModuleCompatibility` to `true` to make this a fatal error.",
120
+ docs: false
121
+ },
122
+ NUXT_B8014: {
123
+ why: (p) => `Module \`${p.name}\` was slow to set up, taking \`${p.time}ms\`.`,
124
+ fix: "Defer expensive operations to a later hook (e.g. `build:before`) to reduce startup time.",
125
+ docs: false
126
+ },
127
+ NUXT_B8015: {
128
+ why: (p) => `A Nuxt module must be a function or a string to import. Received: \`${p.received}\`.`,
129
+ fix: "Pass a module function or a string package name to the `modules` array in `nuxt.config`.",
130
+ docs: false
131
+ },
132
+ NUXT_B8016: {
133
+ why: (p) => `The Nuxt module \`${p.module}\` is not a function.`,
134
+ fix: "Ensure the module has a default export that is a function, using `defineNuxtModule()` to create a valid module.",
135
+ docs: false
136
+ },
137
+ NUXT_B8017: {
138
+ why: (p) => `The module \`${p.module}\` could not be loaded. It may not be installed.`,
139
+ fix: (p) => `Run \`npm install ${p.module}\` to install it.`,
140
+ docs: false
141
+ },
142
+ NUXT_B8018: {
143
+ why: (p) => `An error occurred while importing the module \`${p.module}\`: ${p.error}.`,
144
+ fix: "A sub-dependency of this module is missing. Install it, or check that the module is compatible with the current environment.",
145
+ docs: false
146
+ },
147
+ NUXT_B8019: {
148
+ why: (p) => `An error occurred while executing the ${p.phase} hook for module \`${p.name}\`: ${p.error}.`,
149
+ fix: "Check the module's install/upgrade hook implementation, or report this issue to the module author.",
150
+ docs: false
151
+ }
152
+ }
153
+ });
154
+ //#endregion
35
155
  //#region src/context.ts
36
156
  /**
37
157
  * Direct access to the Nuxt global context - see https://github.com/unjs/unctx.
@@ -56,7 +176,7 @@ const getNuxtCtx = () => asyncNuxtStorage.tryUse();
56
176
  */
57
177
  function useNuxt() {
58
178
  const instance = asyncNuxtStorage.tryUse() || nuxtCtx.tryUse();
59
- if (!instance) throw new Error("Nuxt instance is unavailable!");
179
+ if (!instance) throw kitDiagnostics.NUXT_B8001();
60
180
  return instance;
61
181
  }
62
182
  /**
@@ -136,7 +256,7 @@ async function checkNuxtCompatibility(constraints, nuxt = useNuxt()) {
136
256
  */
137
257
  async function assertNuxtCompatibility(constraints, nuxt = useNuxt()) {
138
258
  const issues = await checkNuxtCompatibility(constraints, nuxt);
139
- if (issues.length) throw new Error("Nuxt compatibility issues found:\n" + issues.toString());
259
+ if (issues.length) throw kitDiagnostics.NUXT_B8004({ issues: issues.toString() });
140
260
  return true;
141
261
  }
142
262
  /**
@@ -170,7 +290,7 @@ const NUXT_VERSION_RE = /^v/g;
170
290
  */
171
291
  function getNuxtVersion(nuxt = useNuxt()) {
172
292
  const rawVersion = nuxt?._version || nuxt?.version || nuxt?.constructor?.version;
173
- if (typeof rawVersion !== "string") throw new TypeError("Cannot determine nuxt version! Is current instance passed?");
293
+ if (typeof rawVersion !== "string") throw kitDiagnostics.NUXT_B8005();
174
294
  return rawVersion.replace(NUXT_VERSION_RE, "");
175
295
  }
176
296
  //#endregion
@@ -194,7 +314,7 @@ function _defineNuxtModule(definition) {
194
314
  return module.moduleDependencies;
195
315
  }
196
316
  async function normalizedModule(inlineOptions, nuxt = tryUseNuxt()) {
197
- if (!nuxt) throw new TypeError(`Cannot use ${module.meta.name || "module"} outside of Nuxt context`);
317
+ if (!nuxt) throw kitDiagnostics.NUXT_B8012({ name: module.meta.name || "module" });
198
318
  const uniqueKey = module.meta.name || module.meta.configKey;
199
319
  if (uniqueKey) {
200
320
  nuxt.options._requiredModules ||= {};
@@ -210,7 +330,7 @@ function _defineNuxtModule(definition) {
210
330
  error.name = "ModuleCompatibilityError";
211
331
  throw error;
212
332
  }
213
- logger.warn(errorMessage);
333
+ kitDiagnostics.NUXT_B8013({ message: errorMessage });
214
334
  return;
215
335
  }
216
336
  }
@@ -219,7 +339,7 @@ function _defineNuxtModule(definition) {
219
339
  const moduleName = uniqueKey || module.meta.name || "<no name>";
220
340
  nuxt._perf?.startPhase(`module:${moduleName}`);
221
341
  const start = performance.now();
222
- let res = {};
342
+ let res;
223
343
  try {
224
344
  res = await module.setup?.call(null, _options, nuxt) ?? {};
225
345
  } finally {
@@ -227,7 +347,10 @@ function _defineNuxtModule(definition) {
227
347
  }
228
348
  const perf = performance.now() - start;
229
349
  const setupTime = Math.round(perf * 100) / 100;
230
- if (setupTime > 5e3 && uniqueKey !== "@nuxt/telemetry") logger.warn(`Slow module \`${moduleName}\` took \`${setupTime}ms\` to setup.`);
350
+ if (setupTime > 5e3 && uniqueKey !== "@nuxt/telemetry") kitDiagnostics.NUXT_B8014({
351
+ name: moduleName,
352
+ time: setupTime
353
+ });
231
354
  else if (nuxt.options.debug && nuxt.options.debug.modules) logger.info(`Module \`${moduleName}\` took \`${setupTime}ms\` to setup.`);
232
355
  if (res === false) return false;
233
356
  return defu(res, { timings: { setup: setupTime } });
@@ -303,6 +426,7 @@ function withTrailingSlash$2(dir) {
303
426
  function createIsIgnored(nuxt = tryUseNuxt()) {
304
427
  return (pathname, stats) => isIgnored(pathname, stats, nuxt);
305
428
  }
429
+ const layerRootsCache = /* @__PURE__ */ new WeakMap();
306
430
  /**
307
431
  * Return a filter function to filter an array of paths
308
432
  */
@@ -312,7 +436,16 @@ function isIgnored(pathname, _stats, nuxt = tryUseNuxt()) {
312
436
  nuxt._ignore = ignore(nuxt.options.ignoreOptions);
313
437
  nuxt._ignore.add(resolveIgnorePatterns());
314
438
  }
315
- const relativePath = relative(getLayerDirectories(nuxt).map((dirs) => dirs.root).sort((a, b) => b.length - a.length).find((cwd) => pathname.startsWith(cwd)) ?? nuxt.options.rootDir, pathname);
439
+ let cwds = layerRootsCache.get(nuxt);
440
+ if (!cwds) {
441
+ cwds = getLayerDirectories(nuxt).map((dirs) => dirs.root).sort((a, b) => b.length - a.length);
442
+ layerRootsCache.set(nuxt, cwds);
443
+ }
444
+ for (const cwd of cwds) if (pathname.startsWith(cwd)) {
445
+ const relativePath = pathname.slice(cwd.length);
446
+ return !!(relativePath && nuxt._ignore.ignores(relativePath));
447
+ }
448
+ const relativePath = relative(nuxt.options.rootDir, pathname);
316
449
  if (relativePath[0] === "." && relativePath[1] === ".") return false;
317
450
  return !!(relativePath && nuxt._ignore.ignores(relativePath));
318
451
  }
@@ -371,6 +504,23 @@ function filterInPlace(array, predicate) {
371
504
  const MODE_RE = /\.(server|client)(\.\w+)*$/;
372
505
  const distDirURL = new URL(".", import.meta.url);
373
506
  //#endregion
507
+ //#region src/constants.ts
508
+ /**
509
+ * Default extensions for files that may contain JSX.
510
+ * @internal
511
+ */
512
+ const DEFAULT_JSX_FILE_EXTENSIONS = [".tsx", ".jsx"];
513
+ /** Default extensions for JavaScript/TypeScript files, in order of resolution priority. */
514
+ const DEFAULT_JS_FILE_EXTENSIONS = [
515
+ ".mjs",
516
+ ".js",
517
+ ".cjs",
518
+ ".mts",
519
+ ".ts",
520
+ ".cts",
521
+ ...DEFAULT_JSX_FILE_EXTENSIONS
522
+ ];
523
+ //#endregion
374
524
  //#region src/resolve.ts
375
525
  /**
376
526
  * Resolve the full path to a file or a directory (based on the provided type), respecting Nuxt alias and extensions options.
@@ -392,11 +542,12 @@ async function resolvePath(path, opts = {}) {
392
542
  */
393
543
  async function findPath(paths, opts, pathType = "file") {
394
544
  for (const path of toArray(paths)) {
545
+ const type = opts?.type || pathType;
395
546
  const res = await _resolvePathGranularly(path, {
396
547
  ...opts,
397
- type: opts?.type || pathType
548
+ type
398
549
  });
399
- if (!res.type || pathType && res.type !== pathType) continue;
550
+ if (!res.type || res.type !== type) continue;
400
551
  if (res.virtual || await existsSensitive(res.path)) return res.path;
401
552
  }
402
553
  return null;
@@ -412,7 +563,7 @@ function resolveAlias(path, alias) {
412
563
  * Create a relative resolver
413
564
  */
414
565
  function createResolver(base) {
415
- if (!base) throw new Error("`base` argument is missing for createResolver(base)!");
566
+ if (!base) throw kitDiagnostics.NUXT_B8002();
416
567
  base = base.toString();
417
568
  if (base.startsWith("file://")) base = dirname(fileURLToPath(base));
418
569
  return {
@@ -449,17 +600,12 @@ async function _resolvePathType(path, opts = {}, skipFs = false) {
449
600
  virtual: true
450
601
  };
451
602
  if (skipFs) return;
452
- const fd = await promises.open(path, "r").catch(() => null);
453
- try {
454
- const stats = await fd?.stat();
455
- if (stats) return {
456
- path,
457
- type: stats.isFile() ? "file" : "dir",
458
- virtual: false
459
- };
460
- } finally {
461
- fd?.close();
462
- }
603
+ const stats = await promises.stat(path).catch(() => null);
604
+ if (stats) return {
605
+ path,
606
+ type: stats.isFile() ? "file" : "dir",
607
+ virtual: false
608
+ };
463
609
  }
464
610
  function normalizeExtension(ext) {
465
611
  return ext.startsWith(".") ? ext : `.${ext}`;
@@ -473,12 +619,7 @@ async function _resolvePathGranularly(path, opts = { type: "file" }) {
473
619
  }
474
620
  const nuxt = tryUseNuxt();
475
621
  const cwd = opts.cwd || (nuxt ? nuxt.options.rootDir : process.cwd());
476
- const extensions = opts.extensions || (nuxt ? nuxt.options.extensions : [
477
- ".ts",
478
- ".mjs",
479
- ".cjs",
480
- ".json"
481
- ]);
622
+ const extensions = opts.extensions || (nuxt ? nuxt.options.extensions : [...DEFAULT_JS_FILE_EXTENSIONS, ".json"]);
482
623
  const modulesDir = nuxt ? nuxt.options.modulesDir : [];
483
624
  path = resolveAlias$1(path, opts.alias ?? nuxt?.options.alias ?? {});
484
625
  if (!isAbsolute(path)) path = resolve(cwd, path);
@@ -547,14 +688,7 @@ function tryResolveModule(id, url = import.meta.url) {
547
688
  function resolveModule(id, options) {
548
689
  return resolveModulePath(id, {
549
690
  from: options?.url ?? options?.paths ?? [import.meta.url],
550
- extensions: options?.extensions ?? [
551
- ".js",
552
- ".mjs",
553
- ".cjs",
554
- ".ts",
555
- ".mts",
556
- ".cts"
557
- ]
691
+ extensions: options?.extensions ?? DEFAULT_JS_FILE_EXTENSIONS
558
692
  });
559
693
  }
560
694
  async function importModule(id, opts) {
@@ -585,7 +719,7 @@ function tryRequireModule(id, opts) {
585
719
  //#endregion
586
720
  //#region src/module/install.ts
587
721
  const NODE_MODULES_RE = /[/\\]node_modules[/\\]/;
588
- const ignoredConfigKeys = new Set([
722
+ const ignoredConfigKeys = /* @__PURE__ */ new Set([
589
723
  "components",
590
724
  "imports",
591
725
  "pages",
@@ -605,6 +739,8 @@ async function installModules(modulesToInstall, resolvedModulePaths, nuxt = useN
605
739
  nuxt._moduleOptionsFunctions ||= /* @__PURE__ */ new Map();
606
740
  const resolvedModules = [];
607
741
  const modulesByMetaName = /* @__PURE__ */ new Map();
742
+ const moduleLoadCache = /* @__PURE__ */ new Map();
743
+ for (const [key] of modulesToInstall) moduleLoadCache.set(key, loadNuxtModuleInstance(key, nuxt));
608
744
  const inlineConfigKeys = new Set(await Promise.all([...modulesToInstall].map(async ([mod]) => {
609
745
  if (typeof mod === "string") return;
610
746
  const meta = await Promise.resolve(mod.getMeta?.());
@@ -617,7 +753,7 @@ async function installModules(modulesToInstall, resolvedModulePaths, nuxt = useN
617
753
  let error;
618
754
  const dependencyMap = /* @__PURE__ */ new Map();
619
755
  for (const [key, options] of modulesToInstall) {
620
- const res = await loadNuxtModuleInstance(key, nuxt).catch((err) => {
756
+ const res = await (moduleLoadCache.get(key) || loadNuxtModuleInstance(key, nuxt)).catch((err) => {
621
757
  if (dependencyMap.has(key) && typeof key === "string") err.cause = `Could not resolve \`${key}\` (specified as a dependency of ${dependencyMap.get(key)}).`;
622
758
  throw err;
623
759
  });
@@ -633,7 +769,7 @@ async function installModules(modulesToInstall, resolvedModulePaths, nuxt = useN
633
769
  }
634
770
  if (value.version) {
635
771
  const pkg = await readPackageJSON(name, { from: [res.resolvedModulePath, ...nuxt.options.modulesDir].filter(Boolean) }).catch(() => null);
636
- if (pkg?.version && !semver.satisfies(pkg.version, value.version, { includePrerelease: true })) {
772
+ if (pkg?.version && !satisfies(pkg.version, value.version, { includePrerelease: true })) {
637
773
  const message = `Module \`${name}\` version (\`${pkg.version}\`) does not satisfy \`${value.version}\` (requested by ${moduleToAttribute}).`;
638
774
  error = new TypeError(message);
639
775
  }
@@ -667,7 +803,7 @@ async function installModules(modulesToInstall, resolvedModulePaths, nuxt = useN
667
803
  if (error) throw error;
668
804
  for (const { nuxtModule, meta = {}, moduleToInstall, buildTimeModuleMeta, resolvedModulePath, inlineOptions } of resolvedModules) {
669
805
  const configKey = meta.configKey;
670
- const optionsFns = new Set([
806
+ const optionsFns = /* @__PURE__ */ new Set([
671
807
  ...nuxt._moduleOptionsFunctions.get(moduleToInstall) || [],
672
808
  ...meta?.name ? nuxt._moduleOptionsFunctions.get(meta.name) || [] : [],
673
809
  ...configKey ? nuxt._moduleOptionsFunctions.get(configKey) || [] : []
@@ -750,30 +886,34 @@ function resolveModuleWithOptions(definition, nuxt) {
750
886
  "",
751
887
  "index"
752
888
  ],
753
- extensions: [
754
- ".js",
755
- ".mjs",
756
- ".cjs",
757
- ".ts",
758
- ".mts",
759
- ".cts"
760
- ]
889
+ extensions: DEFAULT_JS_FILE_EXTENSIONS
761
890
  }) || modAlias,
762
891
  options
763
892
  };
764
893
  }
894
+ let _jitiCache;
895
+ function getSharedJiti(nuxt) {
896
+ _jitiCache ||= /* @__PURE__ */ new WeakMap();
897
+ let jiti = _jitiCache.get(nuxt);
898
+ if (!jiti) {
899
+ jiti = createJiti(nuxt.options.rootDir, { alias: nuxt.options.alias });
900
+ _jitiCache.set(nuxt, jiti);
901
+ }
902
+ return jiti;
903
+ }
765
904
  async function loadNuxtModuleInstance(nuxtModule, nuxt = useNuxt()) {
766
905
  let buildTimeModuleMeta = {};
767
906
  if (typeof nuxtModule === "function") return {
768
907
  nuxtModule,
769
908
  buildTimeModuleMeta
770
909
  };
771
- if (typeof nuxtModule !== "string") throw new TypeError(`Nuxt module should be a function or a string to import. Received: ${nuxtModule}.`);
772
- const jiti = createJiti(nuxt.options.rootDir, { alias: nuxt.options.alias });
910
+ if (typeof nuxtModule !== "string") throw kitDiagnostics.NUXT_B8015({ received: `${typeof nuxtModule} (${JSON.stringify(nuxtModule)})` });
911
+ const jiti = getSharedJiti(nuxt);
773
912
  nuxtModule = resolveAlias(nuxtModule, nuxt.options.alias);
774
913
  if (isRelative(nuxtModule)) nuxtModule = resolve(nuxt.options.rootDir, nuxtModule);
914
+ let src;
775
915
  try {
776
- const src = resolveModuleURL(nuxtModule, {
916
+ src = resolveModuleURL(nuxtModule, {
777
917
  from: nuxt.options.modulesDir.map((m) => directoryToURL(m.replace(/\/node_modules\/?$/, "/"))),
778
918
  suffixes: [
779
919
  "nuxt",
@@ -783,34 +923,33 @@ async function loadNuxtModuleInstance(nuxtModule, nuxt = useNuxt()) {
783
923
  "",
784
924
  "index"
785
925
  ],
786
- extensions: [
787
- ".js",
788
- ".mjs",
789
- ".cjs",
790
- ".ts",
791
- ".mts",
792
- ".cts"
793
- ]
926
+ extensions: DEFAULT_JS_FILE_EXTENSIONS
794
927
  });
795
- const resolvedModulePath = fileURLToPath(src);
796
- const resolvedNuxtModule = await jiti.import(src, { default: true });
797
- if (typeof resolvedNuxtModule !== "function") throw new TypeError(`Nuxt module should be a function: ${nuxtModule}.`);
798
- const moduleMetadataPath = new URL("module.json", src);
799
- if (existsSync(moduleMetadataPath)) buildTimeModuleMeta = JSON.parse(await promises.readFile(moduleMetadataPath, "utf-8"));
800
- return {
801
- nuxtModule: resolvedNuxtModule,
802
- buildTimeModuleMeta,
803
- resolvedModulePath
804
- };
805
928
  } catch (error) {
806
- const code = error.code;
807
- if (code === "ERR_PACKAGE_PATH_NOT_EXPORTED" || code === "ERR_UNSUPPORTED_DIR_IMPORT" || code === "ENOTDIR") throw new TypeError(`Could not load \`${nuxtModule}\`. Is it installed?`);
808
- if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
809
- const module = MissingModuleMatcher.exec(error.message)?.[1];
810
- if (module && !module.includes(nuxtModule)) throw new TypeError(`Error while importing module \`${nuxtModule}\`: ${error}`);
811
- }
929
+ throw kitDiagnostics.NUXT_B8017({
930
+ module: nuxtModule,
931
+ cause: error
932
+ });
933
+ }
934
+ const resolvedModulePath = fileURLToPath(src);
935
+ let resolvedNuxtModule;
936
+ try {
937
+ resolvedNuxtModule = await jiti.import(src, { default: true });
938
+ } catch (error) {
939
+ throw kitDiagnostics.NUXT_B8018({
940
+ module: nuxtModule,
941
+ error: String(error),
942
+ cause: error
943
+ });
812
944
  }
813
- throw new TypeError(`Could not load \`${nuxtModule}\`. Is it installed?`);
945
+ if (typeof resolvedNuxtModule !== "function") throw kitDiagnostics.NUXT_B8016({ module: nuxtModule });
946
+ const moduleMetadataPath = new URL("module.json", src);
947
+ if (existsSync(moduleMetadataPath)) buildTimeModuleMeta = JSON.parse(await promises.readFile(moduleMetadataPath, "utf-8"));
948
+ return {
949
+ nuxtModule: resolvedNuxtModule,
950
+ buildTimeModuleMeta,
951
+ resolvedModulePath
952
+ };
814
953
  }
815
954
  function getDirectory(p) {
816
955
  try {
@@ -821,7 +960,6 @@ function getDirectory(p) {
821
960
  const normalizeModuleTranspilePath = (p) => {
822
961
  return getDirectory(p).split("node_modules/").pop();
823
962
  };
824
- const MissingModuleMatcher = /Cannot find module\s+['"]?([^'")\s]+)['"]?/i;
825
963
  async function callLifecycleHooks(nuxtModule, meta = {}, inlineOptions, nuxt = useNuxt()) {
826
964
  if (!meta.name || !meta.version) return;
827
965
  if (!nuxtModule.onInstall && !nuxtModule.onUpgrade) return;
@@ -831,13 +969,17 @@ async function callLifecycleHooks(nuxtModule, meta = {}, inlineOptions, nuxt = u
831
969
  })?.setups?.[meta.name];
832
970
  try {
833
971
  if (!previousVersion) await nuxtModule.onInstall?.(nuxt);
834
- else if (semver.gt(meta.version, previousVersion)) await nuxtModule.onUpgrade?.(nuxt, inlineOptions, previousVersion);
972
+ else if (isGreater(meta.version, previousVersion)) await nuxtModule.onUpgrade?.(nuxt, inlineOptions, previousVersion);
835
973
  if (previousVersion !== meta.version) update({ setups: { [meta.name]: meta?.version } }, {
836
974
  dir: nuxt.options.rootDir,
837
975
  name: ".nuxtrc"
838
976
  });
839
977
  } catch (e) {
840
- logger.error(`Error while executing ${!previousVersion ? "install" : "upgrade"} hook for module \`${meta.name}\`: ${e}`);
978
+ kitDiagnostics.NUXT_B8019({
979
+ phase: !previousVersion ? "install" : "upgrade",
980
+ name: meta.name,
981
+ error: String(e)
982
+ });
841
983
  }
842
984
  }
843
985
  async function callModule(nuxt, nuxtModule, moduleOptions = {}, options) {
@@ -921,12 +1063,22 @@ const merger = createDefu((obj, key, value) => {
921
1063
  }
922
1064
  });
923
1065
  async function loadNuxtConfig(opts) {
1066
+ const rootCwd = resolve(opts.cwd || process.cwd());
924
1067
  const localLayers = (await glob("layers/*", {
925
1068
  onlyDirectories: true,
926
- cwd: opts.cwd || process.cwd()
1069
+ cwd: rootCwd
927
1070
  })).map((d) => withTrailingSlash(d)).sort((a, b) => b.localeCompare(a));
928
1071
  opts.overrides = defu(opts.overrides, { _extends: localLayers });
929
- const { configFile, layers = [], cwd, config: nuxtConfig, meta } = await withDefineNuxtConfig(() => loadConfig({
1072
+ const autoScanSources = new Set(localLayers);
1073
+ const localLayerDirs = new Set(localLayers.map((dir) => canonicalLayerDir(resolve(rootCwd, withoutTrailingSlash(dir)))));
1074
+ const extendsLocalLayerOrder = [];
1075
+ if (opts.dotenv !== false) await setupDotenv({
1076
+ cwd: opts.cwd || process.cwd(),
1077
+ ...typeof opts.dotenv === "object" ? opts.dotenv : {}
1078
+ });
1079
+ const schemaPromise = loadNuxtSchema(opts.cwd || process.cwd());
1080
+ const seenLayerDirs = /* @__PURE__ */ new Set();
1081
+ const resolved = await withDefineNuxtConfig(() => loadConfig({
930
1082
  name: "nuxt",
931
1083
  configFile: "nuxt.config",
932
1084
  rcFile: ".nuxtrc",
@@ -935,15 +1087,56 @@ async function loadNuxtConfig(opts) {
935
1087
  "_extends",
936
1088
  "extends"
937
1089
  ] },
938
- dotenv: true,
939
1090
  globalRc: true,
940
1091
  merger,
941
- ...opts
1092
+ ...opts,
1093
+ dotenv: false,
1094
+ async resolve(source, resolveOptions) {
1095
+ const custom = await opts.resolve?.(source, resolveOptions);
1096
+ if (custom) return custom;
1097
+ if (typeof source !== "string") return;
1098
+ const base = resolveOptions.cwd ? resolve(resolveOptions.cwd) : rootCwd;
1099
+ const aliased = resolveLayerExtendsAlias(source, rootCwd);
1100
+ const path = aliased ?? resolve(base, source);
1101
+ if (!existsSync(path)) return;
1102
+ const layerDir = canonicalLayerDir(path);
1103
+ if (base === rootCwd && !autoScanSources.has(source) && localLayerDirs.has(layerDir)) extendsLocalLayerOrder.push(layerDir);
1104
+ if (seenLayerDirs.has(layerDir)) return {
1105
+ config: {},
1106
+ cwd: layerDir,
1107
+ source
1108
+ };
1109
+ seenLayerDirs.add(layerDir);
1110
+ if (aliased) {
1111
+ const layer = await loadConfig({
1112
+ cwd: aliased,
1113
+ name: "nuxt",
1114
+ configFile: "nuxt.config",
1115
+ rcFile: false,
1116
+ extend: false,
1117
+ jiti: resolveOptions.jiti
1118
+ });
1119
+ return layer.configFile ? {
1120
+ config: layer.config,
1121
+ configFile: layer.configFile,
1122
+ cwd: aliased,
1123
+ source: aliased,
1124
+ meta: layer.meta
1125
+ } : {
1126
+ config: {},
1127
+ cwd: aliased,
1128
+ source
1129
+ };
1130
+ }
1131
+ }
942
1132
  }));
1133
+ const { configFile, layers = [], cwd, meta } = resolved;
1134
+ const nuxtConfig = klona(resolved.config);
943
1135
  nuxtConfig.rootDir ||= cwd;
944
1136
  nuxtConfig._nuxtConfigFile = configFile;
945
1137
  nuxtConfig._nuxtConfigFiles = [configFile];
946
1138
  nuxtConfig._loadOptions = opts;
1139
+ if (typeof opts.envName === "string") nuxtConfig.envName = opts.envName;
947
1140
  nuxtConfig.alias ||= {};
948
1141
  if (meta?.name) {
949
1142
  const alias = `#layers/${meta.name}`;
@@ -951,7 +1144,7 @@ async function loadNuxtConfig(opts) {
951
1144
  }
952
1145
  const defaultBuildDir = join(nuxtConfig.rootDir, ".nuxt");
953
1146
  if (!opts.overrides?._prepare && !nuxtConfig.dev && !nuxtConfig.buildDir && existsSync(defaultBuildDir)) nuxtConfig.buildDir = join(nuxtConfig.rootDir, "node_modules/.cache/nuxt/.nuxt");
954
- const NuxtConfigSchema = await loadNuxtSchema(nuxtConfig.rootDir || cwd || process.cwd());
1147
+ const NuxtConfigSchema = await schemaPromise;
955
1148
  const layerSchemaKeys = [
956
1149
  "future",
957
1150
  "srcDir",
@@ -984,6 +1177,7 @@ async function loadNuxtConfig(opts) {
984
1177
  }
985
1178
  _layers.push(layer);
986
1179
  }
1180
+ if (extendsLocalLayerOrder.length) reorderLocalLayersByExtends(_layers, extendsLocalLayerOrder, localLayerDirs);
987
1181
  nuxtConfig._layers = _layers;
988
1182
  if (!_layers.length) _layers.push({
989
1183
  cwd,
@@ -994,6 +1188,63 @@ async function loadNuxtConfig(opts) {
994
1188
  });
995
1189
  return await applyDefaults(NuxtConfigSchema, nuxtConfig);
996
1190
  }
1191
+ /**
1192
+ * Canonicalise a filesystem path to a layer directory: config-file paths collapse to their
1193
+ * directory and symlinks resolve to their target, so different spellings of the same layer
1194
+ * share one identity. The path must exist.
1195
+ */
1196
+ function canonicalLayerDir(path) {
1197
+ return normalize(realpathSync(statSync(path).isDirectory() ? path : dirname(path)));
1198
+ }
1199
+ const LAYER_EXTENDS_ALIASES = [
1200
+ "~~",
1201
+ "@@",
1202
+ "~",
1203
+ "@"
1204
+ ];
1205
+ /**
1206
+ * Resolve a leading `~`, `~~`, `@` or `@@` alias in an `extends` source to an absolute path.
1207
+ * Local layers live at the project root, so every alias resolves against `rootDir`. Returns
1208
+ * `undefined` when the source is not alias-prefixed.
1209
+ */
1210
+ function resolveLayerExtendsAlias(source, rootDir) {
1211
+ for (const alias of LAYER_EXTENDS_ALIASES) {
1212
+ if (source === alias) return rootDir;
1213
+ if (source.startsWith(`${alias}/`)) return join(rootDir, source.slice(alias.length + 1));
1214
+ }
1215
+ }
1216
+ /**
1217
+ * Reorder local layers (from the `~~/layers/` directory) in place to match the order they are
1218
+ * listed in `extends` (first entry = highest priority). Listed layers come first in that order;
1219
+ * unlisted local layers keep their existing alphabetical order after them. Non-local layers keep
1220
+ * their positions.
1221
+ */
1222
+ function reorderLocalLayersByExtends(layers, extendsOrder, localLayerDirs) {
1223
+ const layerDir = (layer) => {
1224
+ const dir = withoutTrailingSlash(layer.config?.rootDir ?? layer.cwd ?? "");
1225
+ try {
1226
+ return normalize(realpathSync(dir));
1227
+ } catch {
1228
+ return normalize(dir);
1229
+ }
1230
+ };
1231
+ const priorityByDir = new Map(extendsOrder.map((dir, index) => [dir, index]));
1232
+ const localSlots = [];
1233
+ const localLayers = [];
1234
+ for (let index = 0; index < layers.length; index++) if (localLayerDirs.has(layerDir(layers[index]))) {
1235
+ localSlots.push(index);
1236
+ localLayers.push(layers[index]);
1237
+ }
1238
+ const orderedLocalLayers = localLayers.map((layer, index) => ({
1239
+ layer,
1240
+ index
1241
+ })).sort((a, b) => {
1242
+ return (priorityByDir.get(layerDir(a.layer)) ?? Number.POSITIVE_INFINITY) - (priorityByDir.get(layerDir(b.layer)) ?? Number.POSITIVE_INFINITY) || a.index - b.index;
1243
+ }).map((entry) => entry.layer);
1244
+ localSlots.forEach((slot, index) => {
1245
+ layers[slot] = orderedLocalLayers[index];
1246
+ });
1247
+ }
997
1248
  function loadNuxtSchema(cwd) {
998
1249
  const url = directoryToURL(cwd);
999
1250
  const urls = [url];
@@ -1045,7 +1296,7 @@ async function loadNuxt(opts) {
1045
1296
  });
1046
1297
  return path && path.length > resolvedPath.length ? path : resolvedPath;
1047
1298
  }, "");
1048
- if (!resolvedPath) throw new Error(`Cannot find any nuxt version from ${opts.cwd}`);
1299
+ if (!resolvedPath) throw kitDiagnostics.NUXT_B8006({ cwd: opts.cwd });
1049
1300
  const { loadNuxt } = await import(pathToFileURL(resolvedPath).href).then((r) => interopDefault(r));
1050
1301
  return await loadNuxt(opts);
1051
1302
  }
@@ -1078,6 +1329,16 @@ function addImportsSources(presets) {
1078
1329
  });
1079
1330
  }
1080
1331
  //#endregion
1332
+ //#region src/app-config.ts
1333
+ /**
1334
+ * Update Nuxt app configuration.
1335
+ * @since 4.5.0
1336
+ */
1337
+ function updateAppConfig(appConfig) {
1338
+ const nuxt = useNuxt();
1339
+ Object.assign(nuxt.options.appConfig, defu(appConfig, nuxt.options.appConfig));
1340
+ }
1341
+ //#endregion
1081
1342
  //#region src/nitro.ts
1082
1343
  const HANDLER_METHOD_RE = /\.(get|head|patch|post|put|delete|connect|options|trace)(\.\w+)*$/;
1083
1344
  /**
@@ -1141,7 +1402,7 @@ function addPrerenderRoutes(routes) {
1141
1402
  */
1142
1403
  function useNitro() {
1143
1404
  const nuxt = useNuxt();
1144
- if (!nuxt._nitro) throw new Error("Nitro is not initialized yet. You can call `useNitro()` only after `ready` hook.");
1405
+ if (!nuxt._nitro) throw kitDiagnostics.NUXT_B8003();
1145
1406
  return nuxt._nitro;
1146
1407
  }
1147
1408
  /**
@@ -1187,7 +1448,7 @@ function addServerScanDir(dirs, opts = {}) {
1187
1448
  */
1188
1449
  function useRuntimeConfig() {
1189
1450
  const nuxt = useNuxt();
1190
- return applyEnv(klona(nuxt.options.nitro.runtimeConfig), {
1451
+ return applyEnv(klona$1(nuxt.options.nitro.runtimeConfig), {
1191
1452
  prefix: "NITRO_",
1192
1453
  altPrefix: "NUXT_",
1193
1454
  envExpansion: nuxt.options.nitro.experimental?.envExpansion ?? !!process.env.NITRO_ENV_EXPANSION
@@ -1342,6 +1603,91 @@ function addBuildPlugin(pluginFactory, options) {
1342
1603
  if (pluginFactory.webpack) addWebpackPlugin(pluginFactory.webpack, options);
1343
1604
  if (pluginFactory.rspack) addRspackPlugin(pluginFactory.rspack, options);
1344
1605
  }
1606
+ /**
1607
+ * Set the build output for the given key. See {@link NuxtBuildOutputs}.
1608
+ */
1609
+ function setBuildOutput(key, provider, nuxt = useNuxt()) {
1610
+ nuxt.buildOutputs[key] = provider;
1611
+ }
1612
+ //#endregion
1613
+ //#region src/diagnostics/components.ts
1614
+ /**
1615
+ * B3xxx
1616
+ * Component diagnostics.
1617
+ *
1618
+ * @internal
1619
+ */
1620
+ const componentDiagnostics = /* #__PURE__ */ defineDiagnostics({
1621
+ docsBase,
1622
+ reporters,
1623
+ codes: {
1624
+ NUXT_B3001: {
1625
+ why: (p) => `Components directory not found: \`${p.dirPath}\`.`,
1626
+ fix: "If this is intentional, remove it from `components.dirs` in your `nuxt.config`.",
1627
+ docs: false
1628
+ },
1629
+ NUXT_B3002: {
1630
+ why: (p) => `Using server component \`${p.component}\` with \`ssr: false\` is not supported with auto-detected component islands.`,
1631
+ fix: "Set `experimental.componentIslands` to `true` in your `nuxt.config`, or convert the component to a client component.",
1632
+ docs: false
1633
+ },
1634
+ NUXT_B3003: {
1635
+ why: (p) => `Standalone server components (\`${p.component}\`) are not yet supported without enabling \`experimental.componentIslands\`.`,
1636
+ fix: "Set `experimental.componentIslands` to `true` in your `nuxt.config`.",
1637
+ docs: false
1638
+ },
1639
+ NUXT_B3004: {
1640
+ why: (p) => `\`${p.file}\` is using \`${p.component}\` which requires \`${p.requiredModule}\`.`,
1641
+ fix: (p) => `Run \`npx nuxt add ${p.requiredModule}\` to install it.`,
1642
+ docs: false
1643
+ },
1644
+ NUXT_B3005: {
1645
+ why: (p) => `Multiple hydration strategies are not supported in the same component \`<${p.component}>\` in \`${p.file}\`.`,
1646
+ fix: "Use only one hydration strategy attribute (e.g. `hydrate-on-visible` or `hydrate-on-idle`) per component.",
1647
+ docs: false
1648
+ },
1649
+ NUXT_B3006: {
1650
+ why: (p) => `Component \`<${p.component}>\` (used in \`${p.file}\`) has lazy-hydration props but is not declared as a lazy component.`,
1651
+ fix: (p) => `Rename it to \`<${p.lazyName} />\` or remove the lazy-hydration props.`,
1652
+ docs: false
1653
+ },
1654
+ NUXT_B3007: {
1655
+ why: (p) => `Using the \`nuxt-client\` attribute (in \`${p.file}\`) to render client components within islands requires \`experimental.componentIslands.selectiveClient\` to be enabled.`,
1656
+ fix: "Set `experimental.componentIslands.selectiveClient` to `true` in your `nuxt.config`.",
1657
+ docs: false
1658
+ },
1659
+ NUXT_B3008: {
1660
+ why: (p) => `Components not scanned from \`${p.scannedPath}\`, likely due to a directory casing mismatch.`,
1661
+ fix: (p) => `Rename the directory from \`${p.scannedPath}\` to \`${p.expectedPath}\` to match the expected casing.`,
1662
+ docs: false
1663
+ },
1664
+ NUXT_B3009: {
1665
+ why: (p) => `The component \`${p.component}\` (in \`${p.filePath}\`) is using the reserved "Lazy" prefix used for dynamic imports, which may cause it to break at runtime.`,
1666
+ fix: "Rename the component to avoid the `Lazy` prefix.",
1667
+ docs: false
1668
+ },
1669
+ NUXT_B3010: {
1670
+ why: (p) => `Component did not resolve to a file name in \`${p.filePath}\`.`,
1671
+ fix: "Rename the component file to something other than `index` (e.g. `MyComponent.vue`).",
1672
+ docs: false
1673
+ },
1674
+ NUXT_B3011: {
1675
+ why: (p) => `Two component files resolving to the same name \`${p.component}\`:\n\n - ${p.filePath}\n - ${p.duplicatePath}`,
1676
+ fix: "Rename one of the files or adjust the `components.dirs` prefix settings in your `nuxt.config`.",
1677
+ docs: false
1678
+ },
1679
+ NUXT_B3012: {
1680
+ why: (p) => `Overriding ${p.name} component.`,
1681
+ fix: "Specify a `priority` option when calling `addComponent` to avoid this warning.",
1682
+ docs: false
1683
+ },
1684
+ NUXT_B3013: {
1685
+ why: (p) => `Rendering client components within islands via the \`nuxt-client\` attribute (in \`${p.file}\`) is only supported with the Vite builder.`,
1686
+ fix: "Switch to the Vite builder with `builder: 'vite'` in your `nuxt.config`.",
1687
+ docs: false
1688
+ }
1689
+ }
1690
+ });
1345
1691
  //#endregion
1346
1692
  //#region src/components.ts
1347
1693
  /**
@@ -1391,7 +1737,7 @@ function addComponents(addedComponents) {
1391
1737
  if (newPriority < existingPriority) continue;
1392
1738
  if (newPriority === existingPriority) {
1393
1739
  const name = existingComponent.pascalName || existingComponent.kebabName;
1394
- logger.warn(`Overriding ${name} component. You can specify a \`priority\` option when calling \`addComponent\` to avoid this warning.`);
1740
+ componentDiagnostics.NUXT_B3012({ name });
1395
1741
  }
1396
1742
  components.splice(existingComponentIndex, 1, component);
1397
1743
  } else components.push(component);
@@ -1419,6 +1765,184 @@ function normalizeComponent(opts) {
1419
1765
  };
1420
1766
  }
1421
1767
  //#endregion
1768
+ //#region src/diagnostics/pages.ts
1769
+ /**
1770
+ * B4xxx
1771
+ * Pages / routing diagnostics.
1772
+ *
1773
+ * @internal
1774
+ */
1775
+ const pageDiagnostics = /* #__PURE__ */ defineDiagnostics({
1776
+ docsBase,
1777
+ reporters,
1778
+ codes: {
1779
+ NUXT_B4001: {
1780
+ why: (p) => `The file \`${p.pathname}\` is empty, so it cannot be a valid page.`,
1781
+ fix: "Add a `<template>` block to the page file, or remove the empty file from the `pages/` directory.",
1782
+ docs: false
1783
+ },
1784
+ NUXT_B4002: {
1785
+ why: "An `await` expression is used in a variable referenced by `definePageMeta`, which runs synchronously.",
1786
+ fix: (p) => `Move the \`await\` outside of variables referenced in \`definePageMeta\`, or use a static value instead (near offset ${p.offset}): ${p.codeSnippet}`,
1787
+ docs: false
1788
+ },
1789
+ NUXT_B4003: {
1790
+ why: (p) => `\`definePageMeta()\` is called ${p.callCount} times in \`${p.file}\`, but only one call is allowed.`,
1791
+ fix: "Merge all `definePageMeta()` calls into a single call.",
1792
+ docs: false
1793
+ },
1794
+ NUXT_B4004: {
1795
+ why: (p) => `The route name generated for \`${p.file}\` collides with the one already generated for \`${p.existingFile}\`.`,
1796
+ fix: "Set a custom name using `definePageMeta` within one of the page files.",
1797
+ docs: false
1798
+ },
1799
+ NUXT_B4005: {
1800
+ why: (p) => `\`${p.fnName}\` was called with a \`${p.receivedType}\` instead of an object literal (reading \`${p.file}\`).`,
1801
+ fix: (p) => `Pass a plain object literal to \`${p.fnName}()\`, e.g. \`${p.fnName}({ ... })\`. Variables and function calls are not supported.`,
1802
+ docs: false
1803
+ },
1804
+ NUXT_B4006: {
1805
+ why: (p) => `\`${p.fnName}\` was called with a non-serializable object literal (reading \`${p.file}\`).`,
1806
+ fix: "Use only JSON-serializable values (strings, numbers, booleans, arrays, plain objects) in `defineRouteRules()`.",
1807
+ docs: false
1808
+ },
1809
+ NUXT_B4008: {
1810
+ why: "Server pages with `ssr: false` are not supported while component islands are auto-detected.",
1811
+ fix: "Set `experimental.componentIslands` to `true`.",
1812
+ docs: false
1813
+ },
1814
+ NUXT_B4009: {
1815
+ why: (p) => `No layout name could be resolved for \`${p.file}\` (\`index\` is ignored for the purpose of creating a layout name).`,
1816
+ fix: "Rename the layout file to something other than `index` (e.g. `layouts/default.vue`).",
1817
+ docs: false
1818
+ },
1819
+ NUXT_B4010: {
1820
+ why: (p) => `No middleware name could be resolved for \`${p.file}\` (\`index\` is ignored for the purpose of creating a middleware name).`,
1821
+ fix: "Rename the middleware file to something other than `index` (e.g. `middleware/auth.ts`).",
1822
+ docs: false
1823
+ },
1824
+ NUXT_B4011: {
1825
+ why: (p) => `While building the page tree: ${p.message}`,
1826
+ fix: "Check the page file naming and directory structure for issues.",
1827
+ docs: false
1828
+ },
1829
+ NUXT_B4012: {
1830
+ why: (p) => `The incremental route update for \`${p.event}\` on \`${p.path}\` failed, so a full rebuild was performed.`,
1831
+ fix: "This is usually harmless: the full rebuild will recover. If it happens repeatedly, check for unusual file naming in `pages/`.",
1832
+ docs: false
1833
+ },
1834
+ NUXT_B4013: {
1835
+ why: (p) => `A \`${p.name}\` middleware already exists at \`${p.foundPath}\`.`,
1836
+ fix: "Set `override: true` to replace it.",
1837
+ docs: false
1838
+ },
1839
+ NUXT_B4014: {
1840
+ why: (p) => `Layout \`${p.layoutName}\` is already provided by \`${p.existingPath}\` and was not overridden with \`${p.newPath}\`.`,
1841
+ fix: "Rename one of the layouts, or remove the duplicate layout registration.",
1842
+ docs: false
1843
+ },
1844
+ NUXT_B4016: {
1845
+ why: (p) => `Inline route rules for \`${p.path}\` cannot be represented exactly by Nitro route rules, so they were not applied: ${p.detail}.`,
1846
+ fix: "Define the affected route rules explicitly in `nitro.routeRules`.",
1847
+ docs: false
1848
+ },
1849
+ NUXT_B4017: {
1850
+ why: (p) => `Inline route rules for \`${p.path}\` generated \`${p.pattern}\`, which is already used by another page.`,
1851
+ fix: "The later inline route rules override the earlier ones. Use distinct routes, or define the rules explicitly in `nitro.routeRules`.",
1852
+ docs: false
1853
+ }
1854
+ }
1855
+ });
1856
+ //#endregion
1857
+ //#region src/types.ts
1858
+ const TYPE_RESOLVE_OPTIONS = {
1859
+ conditions: [
1860
+ "types",
1861
+ "import",
1862
+ "require"
1863
+ ],
1864
+ extensions: [
1865
+ ".js",
1866
+ ".mjs",
1867
+ ".cjs",
1868
+ ".ts",
1869
+ ".mts",
1870
+ ".cts"
1871
+ ]
1872
+ };
1873
+ const STRIPPABLE_EXT_RE = /\b\.(?:d\.ts|tsx?|jsx?)$/;
1874
+ const RUNTIME_EXT_RE = /(?<!\.d)\.([cm])(?:ts|js)$/;
1875
+ function isFile(path) {
1876
+ return promises.stat(path).then((s) => s.isFile(), () => false);
1877
+ }
1878
+ /**
1879
+ * Rewrite a resolved module path to the declaration file TypeScript will load for it.
1880
+ *
1881
+ * A `.d.ts` / `.d.mts` / `.d.cts` or `.ts` / `.tsx` path is returned unchanged (or with
1882
+ * the extension stripped, where TypeScript's extensionless `paths` retry will find it).
1883
+ * A `.mjs` / `.cjs` / `.mts` / `.cts` runtime path is rewritten to an adjacent declaration
1884
+ * sibling when one exists; otherwise it is returned as-is for the caller to handle.
1885
+ */
1886
+ async function resolveDeclarationPath(absolutePath) {
1887
+ const stripped = absolutePath.replace(STRIPPABLE_EXT_RE, "");
1888
+ if (stripped !== absolutePath) return stripped;
1889
+ const runtimeMatch = absolutePath.match(RUNTIME_EXT_RE);
1890
+ if (runtimeMatch) {
1891
+ const base = absolutePath.slice(0, -runtimeMatch[0].length);
1892
+ if (await isFile(`${base}.d.ts`)) return base;
1893
+ const declaration = `${base}.d.${runtimeMatch[1]}ts`;
1894
+ if (await isFile(declaration)) return declaration;
1895
+ }
1896
+ return absolutePath;
1897
+ }
1898
+ /** Extract the package name (including scope) from a (possibly subpath) module specifier. */
1899
+ function packageName(specifier) {
1900
+ const segments = specifier.split("/");
1901
+ return specifier[0] === "@" ? segments.slice(0, 2).join("/") : segments[0];
1902
+ }
1903
+ const rootCache = /* @__PURE__ */ new Map();
1904
+ function resolveRoot(basePkg, from) {
1905
+ const cacheKey = `${basePkg}\0${from.map(String).join("\0")}`;
1906
+ if (rootCache.has(cacheKey)) return rootCache.get(cacheKey);
1907
+ const promise = (async () => {
1908
+ try {
1909
+ return dirname(await resolvePackageJSON(resolveModulePath(basePkg, {
1910
+ from,
1911
+ ...TYPE_RESOLVE_OPTIONS
1912
+ })));
1913
+ } catch {
1914
+ return;
1915
+ }
1916
+ })();
1917
+ rootCache.set(cacheKey, promise);
1918
+ return promise;
1919
+ }
1920
+ /**
1921
+ * Resolve auto-import / `tsConfig.paths` entries to the path TypeScript should load types from.
1922
+ *
1923
+ * A bare package resolves to its package root, so TypeScript follows the package's own
1924
+ * `exports` / `types` (which may differ from the file its `.` export condition points at).
1925
+ * A subpath export resolves to its entry's declaration sibling when one exists, otherwise to
1926
+ * the resolved file itself.
1927
+ *
1928
+ * Returns `[specifier, absolutePath]` pairs, omitting any specifier that cannot be resolved.
1929
+ */
1930
+ async function resolveTypePaths(packages, searchPaths) {
1931
+ const from = searchPaths.map((d) => directoryToURL(d));
1932
+ return (await Promise.allSettled(packages.map(async (pkg) => {
1933
+ if (pkg === packageName(pkg)) {
1934
+ const root = await resolveRoot(pkg, from);
1935
+ return root ? [pkg, root] : void 0;
1936
+ }
1937
+ const resolved = resolveModulePath(pkg, {
1938
+ from,
1939
+ try: true,
1940
+ ...TYPE_RESOLVE_OPTIONS
1941
+ });
1942
+ return resolved ? [pkg, await resolveDeclarationPath(resolved)] : void 0;
1943
+ }))).flatMap((result) => result.status === "fulfilled" && result.value ? [result.value] : []);
1944
+ }
1945
+ //#endregion
1422
1946
  //#region src/template.ts
1423
1947
  /**
1424
1948
  * Renders given template during build into the virtual file system (and optionally to disk in the project `buildDir`)
@@ -1458,7 +1982,7 @@ function addServerTemplate(template) {
1458
1982
  function addTypeTemplate(_template, context) {
1459
1983
  const nuxt = useNuxt();
1460
1984
  const template = addTemplate(_template);
1461
- if (!template.filename.endsWith(".d.ts")) throw new Error(`Invalid type template. Filename must end with .d.ts : "${template.filename}"`);
1985
+ if (!template.filename.endsWith(".d.ts")) throw kitDiagnostics.NUXT_B8007({ template: template.filename });
1462
1986
  if (!context || context.nuxt) nuxt.hook("prepare:types", (payload) => {
1463
1987
  payload.references ||= [];
1464
1988
  payload.references.push({ path: template.dst });
@@ -1482,19 +2006,19 @@ function addTypeTemplate(_template, context) {
1482
2006
  * Normalize a nuxt template object
1483
2007
  */
1484
2008
  function normalizeTemplate(template, buildDir) {
1485
- if (!template) throw new Error("Invalid template: " + JSON.stringify(template));
2009
+ if (!template) throw kitDiagnostics.NUXT_B8008({ template: JSON.stringify(template) });
1486
2010
  if (typeof template === "string") template = { src: template };
1487
2011
  else template = { ...template };
1488
2012
  if (template.src) {
1489
- if (!existsSync(template.src)) throw new Error("Template not found: " + template.src);
2013
+ if (!existsSync(template.src)) throw kitDiagnostics.NUXT_B8009({ template: template.src });
1490
2014
  if (!template.filename) {
1491
2015
  const srcPath = parse(template.src);
1492
2016
  template.filename = template.fileName || `${basename(srcPath.dir)}.${srcPath.name}.${hash(template.src).replace(/-/g, "_")}${srcPath.ext}`;
1493
2017
  }
1494
2018
  }
1495
- if (!template.src && !template.getContents) throw new Error("Invalid template. Either `getContents` or `src` should be provided: " + JSON.stringify(template));
1496
- if (!template.filename) throw new Error("Invalid template. `filename` must be provided: " + JSON.stringify(template));
1497
- if (template.filename.endsWith(".d.ts")) template.write = true;
2019
+ if (!template.src && !template.getContents) throw kitDiagnostics.NUXT_B8010({ template: template.filename || template.src || JSON.stringify(template) });
2020
+ if (!template.filename) throw kitDiagnostics.NUXT_B8011({ template: JSON.stringify(template) });
2021
+ if (template.filename.endsWith(".d.ts") || template.filename.endsWith(".d.mts") || template.filename.endsWith(".d.cts")) template.write = true;
1498
2022
  template.dst ||= resolve(buildDir ?? useNuxt().options.buildDir, template.filename);
1499
2023
  return template;
1500
2024
  }
@@ -1531,7 +2055,8 @@ function resolveLayerPaths(dirs, projectBuildDir) {
1531
2055
  join(relativeRootDir, `.config/nuxt.*`),
1532
2056
  join(relativeRootDir, `layers/*/nuxt.config.*`),
1533
2057
  join(relativeRootDir, `layers/*/.config/nuxt.*`),
1534
- join(relativeRootDir, `layers/*/modules/**/*`)
2058
+ join(relativeRootDir, `layers/*/modules/*.*`),
2059
+ join(relativeRootDir, `layers/*/modules/*/*.*`)
1535
2060
  ],
1536
2061
  shared: [
1537
2062
  join(relativeSharedDir, `**/*`),
@@ -1546,13 +2071,15 @@ function resolveLayerPaths(dirs, projectBuildDir) {
1546
2071
  globalDeclarations: [join(relativeRootDir, `*.d.ts`), join(relativeRootDir, `layers/*/*.d.ts`)]
1547
2072
  };
1548
2073
  }
1549
- const EXTENSION_RE = /\b(?:\.d\.[cm]?ts|\.\w+)$/g;
2074
+ async function getPathSubstitution(absolutePath, buildDir) {
2075
+ return relativeWithDot(buildDir, await resolveDeclarationPath(absolutePath));
2076
+ }
1550
2077
  const excludedAlias = [/^@vue\/.*$/, /^#internal\/nuxt/];
1551
2078
  async function _generateTypes(nuxt) {
1552
- const include = new Set(["./nuxt.d.ts"]);
1553
- const nodeInclude = new Set(["./nuxt.node.d.ts"]);
1554
- const sharedInclude = new Set(["./nuxt.shared.d.ts"]);
1555
- const legacyInclude = new Set([...include, ...nodeInclude]);
2079
+ const include = /* @__PURE__ */ new Set(["./nuxt.d.ts"]);
2080
+ const nodeInclude = /* @__PURE__ */ new Set(["./nuxt.node.d.ts"]);
2081
+ const sharedInclude = /* @__PURE__ */ new Set(["./nuxt.shared.d.ts"]);
2082
+ const legacyInclude = /* @__PURE__ */ new Set([...include, ...nodeInclude]);
1556
2083
  const exclude = /* @__PURE__ */ new Set();
1557
2084
  const nodeExclude = /* @__PURE__ */ new Set();
1558
2085
  const sharedExclude = /* @__PURE__ */ new Set();
@@ -1628,20 +2155,23 @@ async function _generateTypes(nuxt) {
1628
2155
  legacyExclude.add(join(relative, "dist/runtime/server"));
1629
2156
  }
1630
2157
  const nestedModulesDirs = [];
1631
- for (const dir of [...nuxt.options.modulesDir].sort()) {
2158
+ for (const dir of nuxt.options.modulesDir.toSorted()) {
1632
2159
  const withSlash = withTrailingSlash$1(dir);
1633
2160
  if (nestedModulesDirs.every((d) => !d.startsWith(withSlash))) nestedModulesDirs.push(withSlash);
1634
2161
  }
1635
2162
  let hasTypescriptVersionWithModulePreserve;
1636
- for (const parent of nestedModulesDirs) hasTypescriptVersionWithModulePreserve ??= await readPackageJSON("typescript", { parent }).then((r) => r?.version && gte(r.version, "5.4.0")).catch(() => void 0);
2163
+ for (const parent of nestedModulesDirs) hasTypescriptVersionWithModulePreserve ??= await readPackageJSON("typescript", { parent }).then((r) => r?.version && isGreaterOrEqual(r.version, "5.4.0")).catch(() => void 0);
1637
2164
  hasTypescriptVersionWithModulePreserve ??= true;
1638
2165
  const useDecorators = Boolean(nuxt.options.experimental?.decorators);
2166
+ const isV5OrHigher = (nuxt.options.future?.compatibilityVersion ?? 4) >= 5;
2167
+ const userExclude = nuxt.options.typescript?.tsConfig?.exclude ?? [];
1639
2168
  const tsConfig = defu(nuxt.options.typescript?.tsConfig, {
1640
2169
  compilerOptions: {
1641
2170
  esModuleInterop: true,
1642
2171
  skipLibCheck: true,
1643
2172
  target: "ESNext",
1644
2173
  allowJs: true,
2174
+ allowImportingTsExtensions: true,
1645
2175
  resolveJsonModule: true,
1646
2176
  moduleDetection: "force",
1647
2177
  isolatedModules: true,
@@ -1651,6 +2181,7 @@ async function _generateTypes(nuxt) {
1651
2181
  noUncheckedIndexedAccess: true,
1652
2182
  forceConsistentCasingInFileNames: true,
1653
2183
  noImplicitOverride: true,
2184
+ ...isV5OrHigher ? { noUncheckedSideEffectImports: true } : {},
1654
2185
  ...useDecorators ? { experimentalDecorators: false } : {},
1655
2186
  module: hasTypescriptVersionWithModulePreserve ? "preserve" : "ESNext",
1656
2187
  noEmit: true,
@@ -1661,6 +2192,7 @@ async function _generateTypes(nuxt) {
1661
2192
  "dom.iterable",
1662
2193
  "webworker"
1663
2194
  ],
2195
+ libReplacement: false,
1664
2196
  jsx: "preserve",
1665
2197
  jsxImportSource: "vue",
1666
2198
  types: [],
@@ -1679,6 +2211,7 @@ async function _generateTypes(nuxt) {
1679
2211
  skipLibCheck: tsConfig.compilerOptions?.skipLibCheck,
1680
2212
  target: tsConfig.compilerOptions?.target,
1681
2213
  allowJs: tsConfig.compilerOptions?.allowJs,
2214
+ allowImportingTsExtensions: tsConfig.compilerOptions?.allowImportingTsExtensions,
1682
2215
  resolveJsonModule: tsConfig.compilerOptions?.resolveJsonModule,
1683
2216
  moduleDetection: tsConfig.compilerOptions?.moduleDetection,
1684
2217
  isolatedModules: tsConfig.compilerOptions?.isolatedModules,
@@ -1706,6 +2239,7 @@ async function _generateTypes(nuxt) {
1706
2239
  skipLibCheck: tsConfig.compilerOptions?.skipLibCheck,
1707
2240
  target: tsConfig.compilerOptions?.target,
1708
2241
  allowJs: tsConfig.compilerOptions?.allowJs,
2242
+ allowImportingTsExtensions: tsConfig.compilerOptions?.allowImportingTsExtensions,
1709
2243
  resolveJsonModule: tsConfig.compilerOptions?.resolveJsonModule,
1710
2244
  moduleDetection: tsConfig.compilerOptions?.moduleDetection,
1711
2245
  isolatedModules: tsConfig.compilerOptions?.isolatedModules,
@@ -1732,6 +2266,7 @@ async function _generateTypes(nuxt) {
1732
2266
  tsConfig.compilerOptions ||= {};
1733
2267
  tsConfig.compilerOptions.paths ||= {};
1734
2268
  tsConfig.include ||= [];
2269
+ tsConfig.exclude ||= [];
1735
2270
  const importPaths = nuxt.options.modulesDir.map((d) => directoryToURL(d));
1736
2271
  for (const alias in aliases) {
1737
2272
  if (excludedAlias.some((re) => re.test(alias))) continue;
@@ -1758,7 +2293,7 @@ async function _generateTypes(nuxt) {
1758
2293
  tsConfig.compilerOptions.paths[alias] = [relativePath];
1759
2294
  tsConfig.compilerOptions.paths[`${alias}/*`] = [`${relativePath}/*`];
1760
2295
  } else {
1761
- const path = stats?.isFile() ? relativePath.replace(EXTENSION_RE, "") : aliases[alias];
2296
+ const path = stats?.isFile() ? await getPathSubstitution(absolutePath, nuxt.options.buildDir) : aliases[alias];
1762
2297
  tsConfig.compilerOptions.paths[alias] = [path];
1763
2298
  }
1764
2299
  }
@@ -1791,18 +2326,18 @@ async function _generateTypes(nuxt) {
1791
2326
  const legacyTsConfig = defu({}, {
1792
2327
  ...tsConfig,
1793
2328
  include: [...tsConfig.include, ...legacyInclude],
1794
- exclude: [...legacyExclude]
2329
+ exclude: [...userExclude, ...legacyExclude]
1795
2330
  });
2331
+ const nonRootLayerDirs = layerDirs.map((dirs) => dirs.root).filter((root) => !rootDirWithSlash.startsWith(root));
1796
2332
  async function resolveConfig(tsConfig) {
1797
2333
  for (const alias in tsConfig.compilerOptions.paths) {
1798
2334
  const paths = tsConfig.compilerOptions.paths[alias];
1799
2335
  tsConfig.compilerOptions.paths[alias] = [...new Set(await Promise.all(paths.map(async (path) => {
1800
2336
  if (!isAbsolute(path)) return path;
1801
- const stats = await promises.stat(path).catch(() => null);
1802
- return relativeWithDot(nuxt.options.buildDir, stats?.isFile() ? path.replace(EXTENSION_RE, "") : path);
2337
+ return (await promises.stat(path).catch(() => null))?.isFile() ? getPathSubstitution(path, nuxt.options.buildDir) : relativeWithDot(nuxt.options.buildDir, path);
1803
2338
  })))];
1804
2339
  }
1805
- sortTsPaths(tsConfig.compilerOptions.paths);
2340
+ tsConfig.compilerOptions.paths = sortTsPaths(tsConfig.compilerOptions.paths, nonRootLayerDirs, nuxt.options.buildDir, nuxt.options.typescript?.hoist ?? []);
1806
2341
  tsConfig.include = [...new Set(tsConfig.include.map((p) => isAbsolute(p) ? relativeWithDot(nuxt.options.buildDir, p) : p))];
1807
2342
  tsConfig.exclude = [...new Set(tsConfig.exclude.map((p) => isAbsolute(p) ? relativeWithDot(nuxt.options.buildDir, p) : p))];
1808
2343
  }
@@ -1860,12 +2395,48 @@ async function writeTypes(nuxt) {
1860
2395
  promises.writeFile(sharedDeclarationPath, sharedDeclaration)
1861
2396
  ]);
1862
2397
  }
1863
- function sortTsPaths(paths) {
1864
- for (const pathKey in paths) if (pathKey.startsWith("#build")) {
1865
- const pathValue = paths[pathKey];
1866
- delete paths[pathKey];
1867
- paths[pathKey] = pathValue;
2398
+ /**
2399
+ * Sort the paths in the tsconfig.json file, so
2400
+ * - Hoisted package paths stay at the top (`typescript.hoist`)
2401
+ * - Custom layer aliases follow, then generic `#layers/*` aliases
2402
+ * - Generic `~`/`@` aliases come after layer aliases
2403
+ * - `#build` alias is at the bottom (https://github.com/nuxt/nuxt/issues/30325)
2404
+ */
2405
+ function sortTsPaths(paths, layerDirs, buildDir, hoist) {
2406
+ const hoistKeys = new Set(hoist);
2407
+ const hoistPaths = {};
2408
+ const customLayerPaths = {};
2409
+ const genericLayerPaths = {};
2410
+ const otherPaths = {};
2411
+ const buildPaths = {};
2412
+ for (const pathKey in paths) {
2413
+ if (pathKey.startsWith("#build")) {
2414
+ buildPaths[pathKey] = paths[pathKey];
2415
+ continue;
2416
+ }
2417
+ if (isHoistPathKey(pathKey, hoistKeys)) {
2418
+ hoistPaths[pathKey] = paths[pathKey];
2419
+ continue;
2420
+ }
2421
+ if (layerDirs.length && paths[pathKey].some((target) => isPathUnderLayerDirs(target, buildDir, layerDirs))) if (pathKey.startsWith("#layers")) genericLayerPaths[pathKey] = paths[pathKey];
2422
+ else customLayerPaths[pathKey] = paths[pathKey];
2423
+ else otherPaths[pathKey] = paths[pathKey];
1868
2424
  }
2425
+ return {
2426
+ ...hoistPaths,
2427
+ ...customLayerPaths,
2428
+ ...genericLayerPaths,
2429
+ ...otherPaths,
2430
+ ...buildPaths
2431
+ };
2432
+ }
2433
+ const PATH_WILDCARD_RE = /\/?\*$/;
2434
+ function isHoistPathKey(pathKey, hoistKeys) {
2435
+ return hoistKeys.has(pathKey.replace(PATH_WILDCARD_RE, ""));
2436
+ }
2437
+ function isPathUnderLayerDirs(target, buildDir, layerDirs) {
2438
+ const absolute = withTrailingSlash$1(resolve(buildDir, target.replace(PATH_WILDCARD_RE, "")));
2439
+ return layerDirs.some((dir) => absolute.startsWith(dir));
1869
2440
  }
1870
2441
  function renderReference(ref, baseDir) {
1871
2442
  return `/// <reference ${"path" in ref ? `path="${isAbsolute(ref.path) ? relative(baseDir, ref.path) : ref.path}"` : `types="${ref.types}"`} />`;
@@ -1890,7 +2461,12 @@ function addLayout(template, name) {
1890
2461
  ...nuxt?.options.alias || {},
1891
2462
  ...strippedAtAliases
1892
2463
  }).pop() || app.layouts[layoutName].file;
1893
- return logger.warn(`Not overriding \`${layoutName}\` (provided by \`${relativePath}\`) with \`${src || filename}\`.`);
2464
+ pageDiagnostics.NUXT_B4014({
2465
+ layoutName,
2466
+ existingPath: relativePath,
2467
+ newPath: src || filename
2468
+ });
2469
+ return;
1894
2470
  }
1895
2471
  app.layouts[layoutName] = {
1896
2472
  file: join("#build", filename),
@@ -1924,13 +2500,94 @@ function addRouteMiddleware(input, options = {}) {
1924
2500
  const foundPath = app.middleware[find].path;
1925
2501
  if (foundPath === middleware.path) continue;
1926
2502
  if (options.override === true) app.middleware[find] = { ...middleware };
1927
- else logger.warn(`'${middleware.name}' middleware already exists at '${foundPath}'. You can set \`override: true\` to replace it.`);
2503
+ else pageDiagnostics.NUXT_B4013({
2504
+ name: middleware.name,
2505
+ foundPath
2506
+ });
1928
2507
  } else if (options.prepend === true) app.middleware.unshift({ ...middleware });
1929
2508
  else app.middleware.push({ ...middleware });
1930
2509
  }
1931
2510
  });
1932
2511
  }
1933
2512
  //#endregion
2513
+ //#region src/diagnostics/plugins.ts
2514
+ /**
2515
+ * B2xxx
2516
+ * Plugin diagnostics (`addPlugin`, plugin metadata, plugin ordering).
2517
+ *
2518
+ * @internal
2519
+ */
2520
+ const pluginDiagnostics = /* #__PURE__ */ defineDiagnostics({
2521
+ docsBase,
2522
+ reporters,
2523
+ codes: {
2524
+ NUXT_B2001: {
2525
+ why: (p) => `The second argument to \`${p.name}\` is a \`${p.type}\`, not an object literal.`,
2526
+ fix: "Pass an object literal as the second argument, e.g. `defineNuxtPlugin(() => {}, { name: 'my-plugin' })`.",
2527
+ docs: false
2528
+ },
2529
+ NUXT_B2002: {
2530
+ why: "Plugin options contain spread elements or computed keys, which are not supported.",
2531
+ fix: "Use static properties instead.",
2532
+ docs: false
2533
+ },
2534
+ NUXT_B2003: {
2535
+ why: "`dependsOn` is not an array of string literals.",
2536
+ fix: "Use string literals in the `dependsOn` array, e.g. `dependsOn: ['my-plugin']`.",
2537
+ docs: false
2538
+ },
2539
+ NUXT_B2004: {
2540
+ why: (p) => `Plugin \`${p.src}\` has no content.`,
2541
+ fix: "Add content to the plugin file, or remove it from the `plugins/` directory.",
2542
+ docs: false
2543
+ },
2544
+ NUXT_B2005: {
2545
+ why: (p) => `Plugin \`${p.src}\` has no default export and will be ignored at build time.`,
2546
+ fix: "Add `export default defineNuxtPlugin(() => {})` to your plugin.",
2547
+ docs: false
2548
+ },
2549
+ NUXT_B2006: {
2550
+ why: (p) => `Error parsing plugin \`${p.src}\`.`,
2551
+ fix: "Check the plugin file for syntax errors.",
2552
+ docs: false
2553
+ },
2554
+ NUXT_B2007: {
2555
+ why: (p) => `Plugin \`${p.src}\` is not wrapped in \`defineNuxtPlugin\`.`,
2556
+ fix: "Wrap your plugin with `defineNuxtPlugin`. This may enable enhancements in future.",
2557
+ docs: false
2558
+ },
2559
+ NUXT_B2008: {
2560
+ why: (p) => `Plugin \`${p.name}\` depends on \`${p.missing}\` but they are not registered.`,
2561
+ fix: "Register the missing dependency plugins, or remove them from the `dependsOn` array.",
2562
+ docs: false
2563
+ },
2564
+ NUXT_B2009: {
2565
+ why: (p) => `Circular dependency detected in plugins: ${p.cycle}.`,
2566
+ fix: "Restructure the plugin `dependsOn` declarations to break the cycle.",
2567
+ docs: false
2568
+ },
2569
+ NUXT_B2010: {
2570
+ why: (p) => `Failed to parse static properties from plugin \`${p.src}\`, falling back to non-optimized runtime meta.`,
2571
+ fix: "Use an object literal with static values as the second argument to `defineNuxtPlugin()`, and check the plugin file for syntax errors or unsupported constructs in the metadata.",
2572
+ docs: false
2573
+ },
2574
+ NUXT_B2011: {
2575
+ why: (p) => `Invalid plugin \`${p.src}\`. The \`src\` option is required.`,
2576
+ fix: "Pass a string path, or an object with a `src` property, to `addPlugin()`.",
2577
+ docs: false
2578
+ },
2579
+ NUXT_B2012: {
2580
+ why: (p) => {
2581
+ const dependencies = p.dependencies.map((name) => `\`${name}\``).join(", ");
2582
+ const plural = p.dependencies.length > 1;
2583
+ return `Plugin \`${p.name}\` depends on ${dependencies}, but ${plural ? "these dependencies are" : "this dependency is"} unavailable in the ${p.mode} build and will be ignored.`;
2584
+ },
2585
+ fix: "Do not depend on plugins that are unavailable in the same build environment; remove them from the `dependsOn` array.",
2586
+ docs: false
2587
+ }
2588
+ }
2589
+ });
2590
+ //#endregion
1934
2591
  //#region src/plugin.ts
1935
2592
  /**
1936
2593
  * Normalize a nuxt plugin object
@@ -1940,18 +2597,10 @@ function normalizePlugin(plugin) {
1940
2597
  if (typeof plugin === "string") plugin = { src: plugin };
1941
2598
  else plugin = { ...plugin };
1942
2599
  if (pluginSymbol in plugin) return plugin;
1943
- if (!plugin.src) throw new Error("Invalid plugin. src option is required: " + JSON.stringify(plugin));
2600
+ if (!plugin.src) throw pluginDiagnostics.NUXT_B2011({ src: JSON.stringify(plugin) });
1944
2601
  plugin.src = normalize(resolveAlias(plugin.src));
1945
2602
  if (!existsSync(plugin.src) && isAbsolute$1(plugin.src)) try {
1946
- plugin.src = resolveModulePath(plugin.src, { extensions: tryUseNuxt()?.options.extensions ?? [
1947
- ".js",
1948
- ".mjs",
1949
- ".cjs",
1950
- ".ts",
1951
- ".tsx",
1952
- ".mts",
1953
- ".cts"
1954
- ] });
2603
+ plugin.src = resolveModulePath(plugin.src, { extensions: tryUseNuxt()?.options.extensions ?? DEFAULT_JS_FILE_EXTENSIONS });
1955
2604
  } catch {}
1956
2605
  if (plugin.ssr) plugin.mode = "server";
1957
2606
  if (!plugin.mode) {
@@ -1978,4 +2627,322 @@ function addPluginTemplate(plugin, opts = {}) {
1978
2627
  }, opts);
1979
2628
  }
1980
2629
  //#endregion
1981
- export { addBuildPlugin, addComponent, addComponentExports, addComponentsDir, addDevServerHandler, addImports, addImportsDir, addImportsSources, addLayout, addPlugin, addPluginTemplate, addPrerenderRoutes, addRouteMiddleware, addRspackPlugin, addServerHandler, addServerImports, addServerImportsDir, addServerPlugin, addServerScanDir, addServerTemplate, addTemplate, addTypeTemplate, addVitePlugin, addWebpackPlugin, assertNuxtCompatibility, buildNuxt, checkNuxtCompatibility, createIsIgnored, createResolver, defineNuxtModule, directoryToURL, extendNuxtSchema, extendPages, extendRouteRules, extendRspackConfig, extendViteConfig, extendWebpackConfig, findPath, getDirectory, getLayerDirectories, getNuxtCtx, getNuxtModuleVersion, getNuxtVersion, hasNuxtCompatibility, hasNuxtModule, hasNuxtModuleCompatibility, importModule, installModule, installModules, isIgnored, isNuxt2, isNuxt3, isNuxtMajorVersion, loadNuxt, loadNuxtConfig, loadNuxtModuleInstance, logger, normalizeModuleTranspilePath, normalizePlugin, normalizeSemanticVersion, normalizeTemplate, nuxtCtx, requireModule, resolveAlias, resolveFiles, resolveIgnorePatterns, resolveModule, resolveModuleWithOptions, resolveNuxtModule, resolvePath, runWithNuxtContext, setGlobalHead, tryImportModule, tryRequireModule, tryResolveModule, tryUseNuxt, updateRuntimeConfig, updateTemplates, useLogger, useNitro, useNuxt, useRuntimeConfig, writeTypes };
2630
+ //#region src/diagnostics/build.ts
2631
+ /**
2632
+ * B1xxx
2633
+ * Build / compilation diagnostics.
2634
+ *
2635
+ * @internal
2636
+ */
2637
+ const buildDiagnostics = /* #__PURE__ */ defineDiagnostics({
2638
+ docsBase,
2639
+ reporters,
2640
+ codes: {
2641
+ NUXT_B1001: {
2642
+ why: (p) => `Could not compile template \`${p.filename}\`.`,
2643
+ fix: (p) => p.src ? `Check the template source file at \`${p.src}\` for syntax errors.` : "Check the `getContents` function of this template for errors.",
2644
+ docs: false
2645
+ },
2646
+ NUXT_B1002: {
2647
+ why: (p) => `Error reading template from \`${p.src}\`.`,
2648
+ fix: "Check that the template `src` path exists and is readable.",
2649
+ docs: false
2650
+ },
2651
+ NUXT_B1003: {
2652
+ why: "Invalid template. Templates must have either `src` or `getContents`.",
2653
+ fix: "Add a `getContents` function or a `src` path to the `addTemplate()` call.",
2654
+ docs: false
2655
+ },
2656
+ NUXT_B1004: {
2657
+ why: "Failed to install dependencies.",
2658
+ fix: (p) => `Try installing manually with \`npm install ${p.packages}\`.`,
2659
+ docs: false
2660
+ },
2661
+ NUXT_B1005: {
2662
+ why: (p) => `Plugin \`${p.plugin}\` failed to scan file \`${p.file}\`.`,
2663
+ fix: "Check the file for syntax errors, or report this issue to the plugin author.",
2664
+ docs: false
2665
+ },
2666
+ NUXT_B1006: {
2667
+ why: (p) => `Cannot read file \`${p.file}\`.`,
2668
+ fix: "Check that the file exists and has correct permissions.",
2669
+ docs: false
2670
+ },
2671
+ NUXT_B1007: {
2672
+ why: (p) => `Error in \`afterScan\` hook of plugin \`${p.plugin}\`.`,
2673
+ fix: "Check the plugin implementation or report this issue to the plugin author.",
2674
+ docs: false
2675
+ },
2676
+ NUXT_B1008: {
2677
+ why: (p) => `No factory function found for \`${p.function}\` in file \`${p.file}\`. This is a Nuxt bug.`,
2678
+ fix: "Please report this issue at https://github.com/nuxt/nuxt/issues with the file contents.",
2679
+ docs: false
2680
+ },
2681
+ NUXT_B1009: {
2682
+ why: (p) => `Duplicate keyed function name \`${p.functionName}\`${p.name && p.functionName !== p.name ? ` defined as \`${p.name}\`` : ""} with ${p.source ? `the same source \`${p.source}\`` : "no source"} found. Overwriting the existing entry.`,
2683
+ fix: "Ensure each keyed function has a unique name, or use a different source to distinguish them.",
2684
+ docs: false
2685
+ },
2686
+ NUXT_B1010: {
2687
+ why: (p) => `Failed to read file \`${p.file}\` as it changed during read.`,
2688
+ fix: "The file was modified while being read, usually by a concurrent process writing to it. Try restarting the build.",
2689
+ docs: false
2690
+ },
2691
+ NUXT_B1011: {
2692
+ why: (p) => `Failed to read file \`${p.file}\`.`,
2693
+ fix: "Check that the file exists and is readable, or try clearing the build cache with `nuxt clean`.",
2694
+ docs: false
2695
+ },
2696
+ NUXT_B1012: {
2697
+ why: (p) => `Skipping unsafe cache path: ${p.path}. This cache file has a path that escapes the project directory (possible path traversal).`,
2698
+ fix: "Delete the cache with `nuxt clean` and rebuild.",
2699
+ docs: false
2700
+ },
2701
+ NUXT_B1013: {
2702
+ why: (p) => `Failed to restore cached file \`${p.file}\`.`,
2703
+ fix: "Try clearing the build cache with `nuxt clean` and rebuilding from scratch.",
2704
+ docs: false
2705
+ },
2706
+ NUXT_B1014: {
2707
+ why: "Problem checking for external configuration files.",
2708
+ fix: "This is likely a transient file system error. If it persists, check file permissions in your project root.",
2709
+ docs: false
2710
+ },
2711
+ NUXT_B1015: {
2712
+ why: "Falling back to `chokidar-granular` as `@parcel/watcher` cannot be resolved in your project.",
2713
+ fix: "Install `@parcel/watcher` for better performance: `npm install -D @parcel/watcher`.",
2714
+ docs: false
2715
+ },
2716
+ NUXT_B1016: {
2717
+ why: "Failed to set up the `@parcel/watcher` file watcher.",
2718
+ fix: "This is likely an environment or file system issue. Watching for file changes may not work; restart the dev server and, if the problem persists, report it.",
2719
+ docs: false
2720
+ },
2721
+ NUXT_B1017: {
2722
+ why: (p) => `Loading \`${p.builder}\` builder failed.`,
2723
+ fix: (p) => `Run \`npm install ${p.builder}\` to install it.`,
2724
+ docs: false
2725
+ },
2726
+ NUXT_B1018: {
2727
+ why: (p) => `Loading \`${p.builder}\` server builder failed.`,
2728
+ fix: (p) => `Run \`npm install ${p.builder}\` to install it.`,
2729
+ docs: false
2730
+ },
2731
+ NUXT_B1019: {
2732
+ why: (p) => `Unknown component mode \`${p.mode}\`. This might be an internal Nuxt bug.`,
2733
+ fix: "If you are a module author, ensure the component `mode` is set to `client`, `server`, or `all`. Otherwise, please report this issue.",
2734
+ docs: false
2735
+ },
2736
+ NUXT_B1020: {
2737
+ why: "`experimental.watcher: \"builder\"` is set but the active builder does not implement `setupWatcher`. Falling back to the default file watcher.",
2738
+ fix: "Remove `experimental.watcher` from your `nuxt.config`, or use a builder that supports its own watcher.",
2739
+ docs: false
2740
+ }
2741
+ }
2742
+ });
2743
+ //#endregion
2744
+ //#region src/diagnostics/config.ts
2745
+ /**
2746
+ * B5xxx
2747
+ * Configuration diagnostics.
2748
+ *
2749
+ * @internal
2750
+ */
2751
+ const configDiagnostics = /* #__PURE__ */ defineDiagnostics({
2752
+ docsBase,
2753
+ reporters,
2754
+ codes: {
2755
+ NUXT_B5001: {
2756
+ why: (p) => `No \`compatibilityDate\` is set in \`nuxt.config\`, so the \`${p.fallback}\` fallback is being used.`,
2757
+ fix: (p) => `Add \`compatibilityDate: '${p.latest}'\` to your \`nuxt.config.ts\`.`
2758
+ },
2759
+ NUXT_B5002: {
2760
+ why: (p) => `\`@nuxt/webpack-builder\` could not be installed in \`${p.rootDir}\`.`,
2761
+ fix: "Install it manually with `npm install -D @nuxt/webpack-builder`, or change the `builder` option to `vite` in `nuxt.config`.",
2762
+ docs: false
2763
+ },
2764
+ NUXT_B5003: {
2765
+ why: (p) => `The \`app\` namespace is reserved for Nuxt and exposed to the browser, but \`runtimeConfig.app.${p.key}\` is set.`,
2766
+ fix: "Move the key to `runtimeConfig.public` or a custom namespace."
2767
+ },
2768
+ NUXT_B5004: {
2769
+ why: (p) => `External configuration files are not supported: ${p.files}.`,
2770
+ fix: "Move these configurations into `nuxt.config.ts` and delete the external config files."
2771
+ },
2772
+ NUXT_B5005: {
2773
+ why: (p) => `Nuxt schema could not be loaded from \`${p.filePath}\`.`,
2774
+ fix: "Ensure the file exports a valid object with `defineNuxtSchema()` or as a plain object.",
2775
+ docs: false
2776
+ },
2777
+ NUXT_B5006: {
2778
+ why: (p) => `\`${p.option}\` is used in dev mode, which causes a memory leak.`,
2779
+ fix: "Remove the hash option from your webpack config.",
2780
+ docs: false
2781
+ },
2782
+ NUXT_B5007: {
2783
+ why: "The webpack server config `target` is not set to \"node\".",
2784
+ fix: "Set `target: \"node\"` in your webpack server configuration.",
2785
+ docs: false
2786
+ },
2787
+ NUXT_B5009: {
2788
+ why: "`@parcel/watcher` cannot be resolved in your project, so `chokidar` is being used instead.",
2789
+ fix: "Install `@parcel/watcher` for better file watching: `npm install -D @parcel/watcher`.",
2790
+ docs: false
2791
+ },
2792
+ NUXT_B5010: {
2793
+ why: (p) => `Required packages are not installed: ${p.names}.`,
2794
+ fix: (p) => `Run \`npm install ${p.install}\` to install them.`,
2795
+ docs: false
2796
+ },
2797
+ NUXT_B5011: {
2798
+ why: (p) => `Package \`${p.name}\` is missing.`,
2799
+ fix: (p) => `Run \`npx nuxt add ${p.name}\` to install it.`,
2800
+ docs: false
2801
+ }
2802
+ }
2803
+ });
2804
+ //#endregion
2805
+ //#region src/diagnostics/head.ts
2806
+ /**
2807
+ * B6xxx
2808
+ * Head / auto-import diagnostics.
2809
+ *
2810
+ * @internal
2811
+ */
2812
+ const headDiagnostics = /* #__PURE__ */ defineDiagnostics({
2813
+ docsBase,
2814
+ reporters,
2815
+ codes: {
2816
+ NUXT_B6001: {
2817
+ why: (p) => `\`${p.file}\` imports head composables directly from \`${p.module}\`, which loses Nuxt's type safety.`,
2818
+ fix: "Import from `#imports` instead.",
2819
+ docs: false
2820
+ },
2821
+ NUXT_B6002: {
2822
+ why: (p) => `\`${p.name}\` is already auto-imported by Nuxt as a built-in, and overriding it will likely cause issues.`,
2823
+ fix: (p) => `Rename \`${p.name}\` in \`${p.file}\` so it no longer collides with the built-in auto-import.`,
2824
+ docs: false
2825
+ },
2826
+ NUXT_B6003: {
2827
+ why: "`unhead.legacy` is deprecated and will be removed.",
2828
+ fix: "Remove deprecated head patterns (`hid`, `vmid`, `children`, `body: true`) and resolve promise values before passing them to `useHead`.",
2829
+ docs: false
2830
+ },
2831
+ NUXT_B6004: {
2832
+ why: "`experimental.headNext` is deprecated. CAPO sorting is now the default.",
2833
+ fix: "Remove `experimental.headNext` from your `nuxt.config`, or set `unhead.legacy: true` to opt out temporarily.",
2834
+ docs: false
2835
+ },
2836
+ NUXT_B6005: {
2837
+ why: (p) => `Could not resolve \`${p.from}\` used by the auto-import \`${p.name}\`.`,
2838
+ fix: "Check the `from` path in `imports.presets` (or the module that registered this import). Auto-imports from an unresolvable module are silently skipped and can surface as unrelated type errors elsewhere.",
2839
+ docs: false
2840
+ }
2841
+ }
2842
+ });
2843
+ //#endregion
2844
+ //#region src/diagnostics/bundler.ts
2845
+ /**
2846
+ * B7xxx
2847
+ * Bundler (Vite / webpack / Nitro) diagnostics.
2848
+ *
2849
+ * @internal
2850
+ */
2851
+ const bundlerDiagnostics = /* #__PURE__ */ defineDiagnostics({
2852
+ docsBase,
2853
+ reporters,
2854
+ codes: {
2855
+ NUXT_B7001: {
2856
+ why: "`rollup-plugin-visualizer` is not installed, so bundle analysis cannot run.",
2857
+ fix: "Run `npm install -D rollup-plugin-visualizer` to enable bundle analysis.",
2858
+ docs: false
2859
+ },
2860
+ NUXT_B7002: {
2861
+ why: (p) => `Some \`vite.optimizeDeps.include\` entries could not be resolved: ${p.deps}.`,
2862
+ fix: "Remove or correct these entries in the `vite.optimizeDeps.include` array of your `nuxt.config.ts`. Report entries added by a Nuxt module to the module author.",
2863
+ docs: false
2864
+ },
2865
+ NUXT_B7003: {
2866
+ why: "The server-side bundle produced more than one JS entry file.",
2867
+ fix: "Avoid using `optimization.splitChunks` in the server config.",
2868
+ docs: false
2869
+ },
2870
+ NUXT_B7004: {
2871
+ why: (p) => `Webpack entry \`${p.entryName}\` was not found.`,
2872
+ fix: (p) => `Check that the \`entry\` option in your webpack configuration points to an existing file. Expected entry name: \`${p.entryName}\`.`,
2873
+ docs: false
2874
+ },
2875
+ NUXT_B7005: {
2876
+ why: (p) => `No client entry was found in \`rollupOptions.input\`; expected an \`entry\` key or a string input but received ${p.input}.`,
2877
+ fix: "Set `vite.build.rollupOptions.input` to a string or an object with an `entry` key in your `nuxt.config`.",
2878
+ docs: false
2879
+ },
2880
+ NUXT_B7006: {
2881
+ why: (p) => `No server entry was found in \`rollupOptions.input\`; expected a \`server\` key or a string input but received ${p.input}.`,
2882
+ fix: "Set `vite.build.rollupOptions.input` to a string or an object with a `server` key in your `nuxt.config`.",
2883
+ docs: false
2884
+ },
2885
+ NUXT_B7007: {
2886
+ why: (p) => `The PostCSS plugin \`${p.pluginName}\` could not be loaded.`,
2887
+ fix: (p) => `Run \`npm install -D ${p.pluginName}\` to install the PostCSS plugin.`,
2888
+ docs: false
2889
+ },
2890
+ NUXT_B7008: {
2891
+ why: "`@vitejs/plugin-vue-jsx` is not installed, so JSX support is unavailable.",
2892
+ fix: "Run `npm install -D @vitejs/plugin-vue-jsx` to install it.",
2893
+ docs: false
2894
+ },
2895
+ NUXT_B7009: {
2896
+ why: (p) => `The Babel dependencies required for decorator support are missing: ${p.deps}.`,
2897
+ fix: (p) => `Run \`npm install -D ${p.install}\` to install the required Babel decorator dependencies.`,
2898
+ docs: false
2899
+ },
2900
+ NUXT_B7011: {
2901
+ why: (p) => `The PostCSS plugin \`${p.pluginName}\` could not be imported, which is unexpected.`,
2902
+ fix: (p) => `Run \`npm install -D ${p.pluginName}\` to install it, or report this issue at https://github.com/nuxt/nuxt/issues.`,
2903
+ docs: false
2904
+ },
2905
+ NUXT_B7012: {
2906
+ why: (p) => `A ViteNode socket payload of ${p.requiredSize} bytes exceeds the internal buffer limit of ${p.maxSize} bytes.`,
2907
+ fix: "Reduce the payload size sent through the ViteNode socket.",
2908
+ docs: false
2909
+ },
2910
+ NUXT_B7013: {
2911
+ why: "The ViteNode socket server was started without a configured socket path.",
2912
+ fix: "This is likely an internal Nuxt bug. Please report it at https://github.com/nuxt/nuxt/issues.",
2913
+ docs: false
2914
+ },
2915
+ NUXT_B7014: {
2916
+ why: (p) => `The webpack \`${p.name}\` build failed with errors.`,
2917
+ fix: "Fix the build errors listed above. If the errors are unclear, try running `nuxt cleanup` and rebuilding.",
2918
+ docs: false
2919
+ },
2920
+ NUXT_B7015: {
2921
+ why: "Payload extraction is disabled, which is suboptimal for full-static output.",
2922
+ fix: "Set `experimental.payloadExtraction` to `true` or `'client'`.",
2923
+ docs: false
2924
+ },
2925
+ NUXT_B7016: {
2926
+ why: (p) => `The configured \`spaLoadingTemplate\` path does not exist: \`${p.path}\`.`,
2927
+ fix: "Point `spaLoadingTemplate` in `nuxt.config` at an existing HTML file, or set it to `true` to use the default template.",
2928
+ docs: false
2929
+ },
2930
+ NUXT_B7017: {
2931
+ why: "Could not find the Nuxt dev server to attach Rspack HMR to; hot module replacement will be disabled.",
2932
+ fix: "This is likely an internal Nuxt bug. Please report it with a reproduction.",
2933
+ docs: false
2934
+ },
2935
+ NUXT_B7018: {
2936
+ why: "Failed to restrict vite-node socket permissions; closing the socket.",
2937
+ fix: "Check that the temporary directory used for the vite-node socket is writable and supports `chmod`.",
2938
+ docs: false
2939
+ },
2940
+ NUXT_B7019: {
2941
+ why: "The server webpack build does not externalize dependencies.",
2942
+ fix: "Externalize dependencies in the server build (`externals`) for better build performance.",
2943
+ docs: false
2944
+ }
2945
+ }
2946
+ });
2947
+ //#endregion
2948
+ export { DEFAULT_JSX_FILE_EXTENSIONS, DEFAULT_JS_FILE_EXTENSIONS, addBuildPlugin, addComponent, addComponentExports, addComponentsDir, addDevServerHandler, addImports, addImportsDir, addImportsSources, addLayout, addPlugin, addPluginTemplate, addPrerenderRoutes, addRouteMiddleware, addRspackPlugin, addServerHandler, addServerImports, addServerImportsDir, addServerPlugin, addServerScanDir, addServerTemplate, addTemplate, addTypeTemplate, addVitePlugin, addWebpackPlugin, assertNuxtCompatibility, buildDiagnostics, buildNuxt, bundlerDiagnostics, checkNuxtCompatibility, componentDiagnostics, configDiagnostics, createIsIgnored, createResolver, defineNuxtModule, directoryToURL, extendNuxtSchema, extendPages, extendRouteRules, extendRspackConfig, extendViteConfig, extendWebpackConfig, findPath, getDirectory, getLayerDirectories, getNuxtCtx, getNuxtModuleVersion, getNuxtVersion, hasNuxtCompatibility, hasNuxtModule, hasNuxtModuleCompatibility, headDiagnostics, importModule, installModule, installModules, isIgnored, isNuxt2, isNuxt3, isNuxtMajorVersion, loadNuxt, loadNuxtConfig, loadNuxtModuleInstance, logger, normalizeModuleTranspilePath, normalizePlugin, normalizeSemanticVersion, normalizeTemplate, nuxtCtx, packageName, pageDiagnostics, pluginDiagnostics, requireModule, resolveAlias, resolveDeclarationPath, resolveFiles, resolveIgnorePatterns, resolveModule, resolveModuleWithOptions, resolveNuxtModule, resolvePath, resolveTypePaths, runWithNuxtContext, setBuildOutput, setGlobalHead, tryImportModule, tryRequireModule, tryResolveModule, tryUseNuxt, updateAppConfig, updateRuntimeConfig, updateTemplates, useLogger, useNitro, useNuxt, useRuntimeConfig, writeTypes };