@depup/nuxt__kit 4.4.2-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 ADDED
@@ -0,0 +1,1981 @@
1
+ import { performance } from "node:perf_hooks";
2
+ import { createDefu, defu } from "defu";
3
+ import { applyDefaults } from "untyped";
4
+ import { consola } from "consola";
5
+ import { AsyncLocalStorage } from "node:async_hooks";
6
+ import { getContext } from "unctx";
7
+ import satisfies from "semver/functions/satisfies.js";
8
+ import { readPackageJSON, resolvePackageJSON } from "pkg-types";
9
+ import { existsSync, lstatSync, promises, readFileSync } from "node:fs";
10
+ import { fileURLToPath, pathToFileURL } from "node:url";
11
+ import { basename, dirname, isAbsolute, join, normalize, parse, relative, resolve } from "pathe";
12
+ import { createJiti } from "jiti";
13
+ import { interopDefault, lookupNodeModuleSubpath, parseNodeModulePath, resolveModuleExportNames } from "mlly";
14
+ import { resolveModulePath, resolveModuleURL } from "exsolve";
15
+ import { isRelative, withTrailingSlash, withoutTrailingSlash } from "ufo";
16
+ import { read, update } from "rc9";
17
+ import semver, { gte } from "semver";
18
+ import { captureStackTrace } from "errx";
19
+ import process from "node:process";
20
+ import { glob } from "tinyglobby";
21
+ import { resolveAlias as resolveAlias$1, reverseResolveAlias } from "pathe/utils";
22
+ import ignore from "ignore";
23
+ import { loadConfig } from "c12";
24
+ import destr from "destr";
25
+ import { kebabCase, pascalCase, snakeCase } from "scule";
26
+ import { klona } from "klona";
27
+ import { hash } from "ohash";
28
+ import { isAbsolute as isAbsolute$1 } from "node:path";
29
+ //#region src/logger.ts
30
+ const logger = consola;
31
+ function useLogger(tag, options = {}) {
32
+ return tag ? logger.create(options).withTag(tag) : logger;
33
+ }
34
+ //#endregion
35
+ //#region src/context.ts
36
+ /**
37
+ * Direct access to the Nuxt global context - see https://github.com/unjs/unctx.
38
+ * @deprecated Use `getNuxtCtx` instead
39
+ */
40
+ const nuxtCtx = getContext("nuxt");
41
+ /** async local storage for the name of the current nuxt instance */
42
+ const asyncNuxtStorage = getContext("asyncNuxtStorage", {
43
+ asyncContext: true,
44
+ AsyncLocalStorage
45
+ });
46
+ /** Direct access to the Nuxt context with asyncLocalStorage - see https://github.com/unjs/unctx. */
47
+ const getNuxtCtx = () => asyncNuxtStorage.tryUse();
48
+ /**
49
+ * Get access to Nuxt instance.
50
+ *
51
+ * Throws an error if Nuxt instance is unavailable.
52
+ * @example
53
+ * ```js
54
+ * const nuxt = useNuxt()
55
+ * ```
56
+ */
57
+ function useNuxt() {
58
+ const instance = asyncNuxtStorage.tryUse() || nuxtCtx.tryUse();
59
+ if (!instance) throw new Error("Nuxt instance is unavailable!");
60
+ return instance;
61
+ }
62
+ /**
63
+ * Get access to Nuxt instance.
64
+ *
65
+ * Returns null if Nuxt instance is unavailable.
66
+ * @example
67
+ * ```js
68
+ * const nuxt = tryUseNuxt()
69
+ * if (nuxt) {
70
+ * // Do something
71
+ * }
72
+ * ```
73
+ */
74
+ function tryUseNuxt() {
75
+ return asyncNuxtStorage.tryUse() || nuxtCtx.tryUse();
76
+ }
77
+ function runWithNuxtContext(nuxt, fn) {
78
+ return asyncNuxtStorage.call(nuxt, fn);
79
+ }
80
+ //#endregion
81
+ //#region src/compatibility.ts
82
+ const SEMANTIC_VERSION_RE = /-\d+\.[0-9a-f]+/;
83
+ function normalizeSemanticVersion(version) {
84
+ return version.replace(SEMANTIC_VERSION_RE, "");
85
+ }
86
+ const builderMap = {
87
+ "@nuxt/rspack-builder": "rspack",
88
+ "@nuxt/vite-builder": "vite",
89
+ "@nuxt/webpack-builder": "webpack"
90
+ };
91
+ function checkNuxtVersion(version, nuxt = useNuxt()) {
92
+ return satisfies(normalizeSemanticVersion(getNuxtVersion(nuxt)), version, { includePrerelease: true });
93
+ }
94
+ /**
95
+ * Check version constraints and return incompatibility issues as an array
96
+ */
97
+ async function checkNuxtCompatibility(constraints, nuxt = useNuxt()) {
98
+ const issues = [];
99
+ if (constraints.nuxt) {
100
+ const nuxtVersion = getNuxtVersion(nuxt);
101
+ if (!checkNuxtVersion(constraints.nuxt, nuxt)) issues.push({
102
+ name: "nuxt",
103
+ message: `Nuxt version \`${constraints.nuxt}\` is required but currently using \`${nuxtVersion}\``
104
+ });
105
+ }
106
+ if (constraints.builder && typeof nuxt.options.builder === "string") {
107
+ const currentBuilder = builderMap[nuxt.options.builder] || nuxt.options.builder;
108
+ if (currentBuilder in constraints.builder) {
109
+ const constraint = constraints.builder[currentBuilder];
110
+ if (constraint === false) issues.push({
111
+ name: "builder",
112
+ message: `Not compatible with \`${nuxt.options.builder}\`.`
113
+ });
114
+ else for (const parent of [
115
+ nuxt.options.rootDir,
116
+ nuxt.options.workspaceDir,
117
+ import.meta.url
118
+ ]) {
119
+ const builderVersion = await readPackageJSON(nuxt.options.builder, { parent }).then((r) => r.version).catch(() => void 0);
120
+ if (builderVersion) {
121
+ if (!satisfies(normalizeSemanticVersion(builderVersion), constraint, { includePrerelease: true })) issues.push({
122
+ name: "builder",
123
+ message: `Not compatible with \`${builderVersion}\` of \`${currentBuilder}\`. This module requires \`${constraint}\`.`
124
+ });
125
+ break;
126
+ }
127
+ }
128
+ }
129
+ }
130
+ await nuxt.callHook("kit:compatibility", constraints, issues);
131
+ issues.toString = () => issues.map((issue) => ` - [${issue.name}] ${issue.message}`).join("\n");
132
+ return issues;
133
+ }
134
+ /**
135
+ * Check version constraints and throw a detailed error if has any, otherwise returns true
136
+ */
137
+ async function assertNuxtCompatibility(constraints, nuxt = useNuxt()) {
138
+ const issues = await checkNuxtCompatibility(constraints, nuxt);
139
+ if (issues.length) throw new Error("Nuxt compatibility issues found:\n" + issues.toString());
140
+ return true;
141
+ }
142
+ /**
143
+ * Check version constraints and return true if passed, otherwise returns false
144
+ */
145
+ async function hasNuxtCompatibility(constraints, nuxt = useNuxt()) {
146
+ return !(await checkNuxtCompatibility(constraints, nuxt)).length;
147
+ }
148
+ /**
149
+ * Check if current Nuxt instance is of specified major version
150
+ */
151
+ function isNuxtMajorVersion(majorVersion, nuxt = useNuxt()) {
152
+ const version = getNuxtVersion(nuxt);
153
+ return version[0] === majorVersion.toString() && version[1] === ".";
154
+ }
155
+ /**
156
+ * @deprecated Use `isNuxtMajorVersion(2, nuxt)` instead. This may be removed in \@nuxt/kit v5 or a future major version.
157
+ */
158
+ function isNuxt2(nuxt = useNuxt()) {
159
+ return isNuxtMajorVersion(2, nuxt);
160
+ }
161
+ /**
162
+ * @deprecated Use `isNuxtMajorVersion(3, nuxt)` instead. This may be removed in \@nuxt/kit v5 or a future major version.
163
+ */
164
+ function isNuxt3(nuxt = useNuxt()) {
165
+ return isNuxtMajorVersion(3, nuxt);
166
+ }
167
+ const NUXT_VERSION_RE = /^v/g;
168
+ /**
169
+ * Get nuxt version
170
+ */
171
+ function getNuxtVersion(nuxt = useNuxt()) {
172
+ 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?");
174
+ return rawVersion.replace(NUXT_VERSION_RE, "");
175
+ }
176
+ //#endregion
177
+ //#region src/module/define.ts
178
+ function defineNuxtModule(definition) {
179
+ if (definition) return _defineNuxtModule(definition);
180
+ return { with: (definition) => _defineNuxtModule(definition) };
181
+ }
182
+ function _defineNuxtModule(definition) {
183
+ if (typeof definition === "function") return _defineNuxtModule({ setup: definition });
184
+ const module = defu(definition, { meta: {} });
185
+ module.meta.configKey ||= module.meta.name;
186
+ async function getOptions(inlineOptions, nuxt = useNuxt()) {
187
+ const nuxtConfigOptionsKey = module.meta.configKey || module.meta.name;
188
+ let options = defu(inlineOptions, nuxtConfigOptionsKey && nuxtConfigOptionsKey in nuxt.options ? nuxt.options[nuxtConfigOptionsKey] : {}, module.defaults instanceof Function ? await module.defaults(nuxt) : module.defaults ?? {});
189
+ if (module.schema) options = await applyDefaults(module.schema, options);
190
+ return Promise.resolve(options);
191
+ }
192
+ function getModuleDependencies(nuxt = useNuxt()) {
193
+ if (typeof module.moduleDependencies === "function") return module.moduleDependencies(nuxt);
194
+ return module.moduleDependencies;
195
+ }
196
+ async function normalizedModule(inlineOptions, nuxt = tryUseNuxt()) {
197
+ if (!nuxt) throw new TypeError(`Cannot use ${module.meta.name || "module"} outside of Nuxt context`);
198
+ const uniqueKey = module.meta.name || module.meta.configKey;
199
+ if (uniqueKey) {
200
+ nuxt.options._requiredModules ||= {};
201
+ if (nuxt.options._requiredModules[uniqueKey]) return false;
202
+ nuxt.options._requiredModules[uniqueKey] = true;
203
+ }
204
+ if (module.meta.compatibility) {
205
+ const issues = await checkNuxtCompatibility(module.meta.compatibility, nuxt);
206
+ if (issues.length) {
207
+ const errorMessage = `Module \`${module.meta.name}\` is disabled due to incompatibility issues:\n${issues.toString()}`;
208
+ if (nuxt.options.experimental.enforceModuleCompatibility) {
209
+ const error = new Error(errorMessage);
210
+ error.name = "ModuleCompatibilityError";
211
+ throw error;
212
+ }
213
+ logger.warn(errorMessage);
214
+ return;
215
+ }
216
+ }
217
+ const _options = await getOptions(inlineOptions, nuxt);
218
+ if (module.hooks) nuxt.hooks.addHooks(module.hooks);
219
+ const moduleName = uniqueKey || module.meta.name || "<no name>";
220
+ nuxt._perf?.startPhase(`module:${moduleName}`);
221
+ const start = performance.now();
222
+ let res = {};
223
+ try {
224
+ res = await module.setup?.call(null, _options, nuxt) ?? {};
225
+ } finally {
226
+ nuxt._perf?.endPhase(`module:${moduleName}`);
227
+ }
228
+ const perf = performance.now() - start;
229
+ const setupTime = Math.round(perf * 100) / 100;
230
+ if (setupTime > 5e3 && uniqueKey !== "@nuxt/telemetry") logger.warn(`Slow module \`${moduleName}\` took \`${setupTime}ms\` to setup.`);
231
+ else if (nuxt.options.debug && nuxt.options.debug.modules) logger.info(`Module \`${moduleName}\` took \`${setupTime}ms\` to setup.`);
232
+ if (res === false) return false;
233
+ return defu(res, { timings: { setup: setupTime } });
234
+ }
235
+ normalizedModule.getMeta = () => Promise.resolve(module.meta);
236
+ normalizedModule.getOptions = getOptions;
237
+ normalizedModule.getModuleDependencies = getModuleDependencies;
238
+ normalizedModule.onInstall = module.onInstall;
239
+ normalizedModule.onUpgrade = module.onUpgrade;
240
+ return normalizedModule;
241
+ }
242
+ //#endregion
243
+ //#region src/internal/trace.ts
244
+ const distURL = import.meta.url.replace(/\/dist\/.*$/, "/");
245
+ function getUserCaller() {
246
+ if (!import.meta.dev) return null;
247
+ const { source, line, column } = captureStackTrace().find((entry) => !entry.source.startsWith(distURL)) ?? {};
248
+ if (!source) return null;
249
+ return {
250
+ source: source.replace(/^file:\/\//, ""),
251
+ line,
252
+ column
253
+ };
254
+ }
255
+ const warnings = /* @__PURE__ */ new Set();
256
+ function warn(warning) {
257
+ if (!warnings.has(warning)) {
258
+ console.warn(warning);
259
+ warnings.add(warning);
260
+ }
261
+ }
262
+ //#endregion
263
+ //#region src/layers.ts
264
+ const layerMap = /* @__PURE__ */ new WeakMap();
265
+ /**
266
+ * Get the resolved directory paths for all layers in a Nuxt application.
267
+ *
268
+ * Returns an array of LayerDirectories objects, ordered by layer priority:
269
+ * - The first layer is the user/project layer (highest priority)
270
+ * - Earlier layers override later layers in the array
271
+ * - Base layers appear last in the array (lowest priority)
272
+ *
273
+ * @param nuxt - The Nuxt instance to get layers from. Defaults to the current Nuxt context.
274
+ * @returns Array of LayerDirectories objects, ordered by priority (user layer first)
275
+ */
276
+ function getLayerDirectories(nuxt = useNuxt()) {
277
+ return nuxt.options._layers.map((layer) => {
278
+ if (layerMap.has(layer)) return layerMap.get(layer);
279
+ const config = withTrailingSlash$2(layer.config.rootDir) === withTrailingSlash$2(nuxt.options.rootDir) ? nuxt.options : layer.config;
280
+ const src = withTrailingSlash$2(config.srcDir || layer.cwd);
281
+ const root = withTrailingSlash$2(config.rootDir || layer.cwd);
282
+ const directories = {
283
+ root,
284
+ shared: withTrailingSlash$2(resolve(root, resolveAlias(config.dir?.shared || "shared", nuxt.options.alias))),
285
+ server: withTrailingSlash$2(resolve(src, resolveAlias(config.serverDir || "server", nuxt.options.alias))),
286
+ modules: withTrailingSlash$2(resolve(src, resolveAlias(config.dir?.modules || "modules", nuxt.options.alias))),
287
+ public: withTrailingSlash$2(resolve(src, resolveAlias(config.dir?.public || "public", nuxt.options.alias))),
288
+ app: src,
289
+ appLayouts: withTrailingSlash$2(resolve(src, resolveAlias(config.dir?.layouts || "layouts", nuxt.options.alias))),
290
+ appMiddleware: withTrailingSlash$2(resolve(src, resolveAlias(config.dir?.middleware || "middleware", nuxt.options.alias))),
291
+ appPages: withTrailingSlash$2(resolve(src, resolveAlias(config.dir?.pages || "pages", nuxt.options.alias))),
292
+ appPlugins: withTrailingSlash$2(resolve(src, resolveAlias(config.dir?.plugins || "plugins", nuxt.options.alias)))
293
+ };
294
+ layerMap.set(layer, directories);
295
+ return directories;
296
+ });
297
+ }
298
+ function withTrailingSlash$2(dir) {
299
+ return dir.replace(/[^/]$/, "$&/");
300
+ }
301
+ //#endregion
302
+ //#region src/ignore.ts
303
+ function createIsIgnored(nuxt = tryUseNuxt()) {
304
+ return (pathname, stats) => isIgnored(pathname, stats, nuxt);
305
+ }
306
+ /**
307
+ * Return a filter function to filter an array of paths
308
+ */
309
+ function isIgnored(pathname, _stats, nuxt = tryUseNuxt()) {
310
+ if (!nuxt) return false;
311
+ if (!nuxt._ignore) {
312
+ nuxt._ignore = ignore(nuxt.options.ignoreOptions);
313
+ nuxt._ignore.add(resolveIgnorePatterns());
314
+ }
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);
316
+ if (relativePath[0] === "." && relativePath[1] === ".") return false;
317
+ return !!(relativePath && nuxt._ignore.ignores(relativePath));
318
+ }
319
+ const NEGATION_RE = /^(!?)(.*)$/;
320
+ function resolveIgnorePatterns(relativePath) {
321
+ const nuxt = tryUseNuxt();
322
+ if (!nuxt) return [];
323
+ const ignorePatterns = nuxt.options.ignore.flatMap((s) => resolveGroupSyntax(s));
324
+ const nuxtignoreFile = join(nuxt.options.rootDir, ".nuxtignore");
325
+ if (existsSync(nuxtignoreFile)) {
326
+ const contents = readFileSync(nuxtignoreFile, "utf-8");
327
+ ignorePatterns.push(...contents.trim().split(/\r?\n/));
328
+ }
329
+ if (relativePath) return ignorePatterns.map((p) => {
330
+ const [_, negation = "", pattern] = p.match(NEGATION_RE) || [];
331
+ if (pattern && pattern[0] === "*") return p;
332
+ return negation + relative(relativePath, resolve(nuxt.options.rootDir, pattern || p));
333
+ });
334
+ return ignorePatterns;
335
+ }
336
+ /**
337
+ * This function turns string containing groups '**\/*.{spec,test}.{js,ts}' into an array of strings.
338
+ * For example will '**\/*.{spec,test}.{js,ts}' be resolved to:
339
+ * ['**\/*.spec.js', '**\/*.spec.ts', '**\/*.test.js', '**\/*.test.ts']
340
+ * @param group string containing the group syntax
341
+ * @returns {string[]} array of strings without the group syntax
342
+ */
343
+ function resolveGroupSyntax(group) {
344
+ let groups = [group];
345
+ while (groups.some((group) => group.includes("{"))) groups = groups.flatMap((group) => {
346
+ const [head, ...tail] = group.split("{");
347
+ if (tail.length) {
348
+ const [body = "", ...rest] = tail.join("{").split("}");
349
+ return body.split(",").map((part) => `${head}${part}${rest.join("")}`);
350
+ }
351
+ return group;
352
+ });
353
+ return groups;
354
+ }
355
+ //#endregion
356
+ //#region src/utils.ts
357
+ /** @since 3.9.0 */
358
+ function toArray(value) {
359
+ return Array.isArray(value) ? value : [value];
360
+ }
361
+ /**
362
+ * Filter out items from an array in place. This function mutates the array.
363
+ * `predicate` get through the array from the end to the start for performance.
364
+ *
365
+ * This function should be faster than `Array.prototype.filter` on large arrays.
366
+ */
367
+ function filterInPlace(array, predicate) {
368
+ for (let i = array.length; i--;) if (!predicate(array[i], i, array)) array.splice(i, 1);
369
+ return array;
370
+ }
371
+ const MODE_RE = /\.(server|client)(\.\w+)*$/;
372
+ const distDirURL = new URL(".", import.meta.url);
373
+ //#endregion
374
+ //#region src/resolve.ts
375
+ /**
376
+ * Resolve the full path to a file or a directory (based on the provided type), respecting Nuxt alias and extensions options.
377
+ *
378
+ * If a path cannot be resolved, normalized input will be returned unless the `fallbackToOriginal` option is set to `true`,
379
+ * in which case the original input path will be returned.
380
+ */
381
+ async function resolvePath(path, opts = {}) {
382
+ const { type = "file" } = opts;
383
+ const res = await _resolvePathGranularly(path, {
384
+ ...opts,
385
+ type
386
+ });
387
+ if (res.type === type) return res.path;
388
+ return opts.fallbackToOriginal ? path : res.path;
389
+ }
390
+ /**
391
+ * Try to resolve first existing file in paths
392
+ */
393
+ async function findPath(paths, opts, pathType = "file") {
394
+ for (const path of toArray(paths)) {
395
+ const res = await _resolvePathGranularly(path, {
396
+ ...opts,
397
+ type: opts?.type || pathType
398
+ });
399
+ if (!res.type || pathType && res.type !== pathType) continue;
400
+ if (res.virtual || await existsSensitive(res.path)) return res.path;
401
+ }
402
+ return null;
403
+ }
404
+ /**
405
+ * Resolve path aliases respecting Nuxt alias options
406
+ */
407
+ function resolveAlias(path, alias) {
408
+ alias ||= tryUseNuxt()?.options.alias || {};
409
+ return resolveAlias$1(path, alias);
410
+ }
411
+ /**
412
+ * Create a relative resolver
413
+ */
414
+ function createResolver(base) {
415
+ if (!base) throw new Error("`base` argument is missing for createResolver(base)!");
416
+ base = base.toString();
417
+ if (base.startsWith("file://")) base = dirname(fileURLToPath(base));
418
+ return {
419
+ resolve: (...path) => resolve(base, ...path),
420
+ resolvePath: (path, opts) => resolvePath(path, {
421
+ cwd: base,
422
+ ...opts
423
+ })
424
+ };
425
+ }
426
+ async function resolveNuxtModule(base, paths) {
427
+ const resolved = [];
428
+ const resolver = createResolver(base);
429
+ for (const path of paths) {
430
+ if (path.startsWith(base)) {
431
+ resolved.push(path.split("/index.ts")[0]);
432
+ continue;
433
+ }
434
+ const resolvedPath = await resolver.resolvePath(path);
435
+ const dir = parseNodeModulePath(resolvedPath).dir;
436
+ if (dir) {
437
+ resolved.push(dir);
438
+ continue;
439
+ }
440
+ const index = resolvedPath.lastIndexOf(path);
441
+ resolved.push(index === -1 ? dirname(resolvedPath) : resolvedPath.slice(0, index + path.length));
442
+ }
443
+ return resolved;
444
+ }
445
+ async function _resolvePathType(path, opts = {}, skipFs = false) {
446
+ if (opts?.virtual && existsInVFS(path)) return {
447
+ path,
448
+ type: "file",
449
+ virtual: true
450
+ };
451
+ 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
+ }
463
+ }
464
+ function normalizeExtension(ext) {
465
+ return ext.startsWith(".") ? ext : `.${ext}`;
466
+ }
467
+ async function _resolvePathGranularly(path, opts = { type: "file" }) {
468
+ const _path = path;
469
+ path = normalize(path);
470
+ if (isAbsolute(path)) {
471
+ const res = await _resolvePathType(path, opts);
472
+ if (res && res.type === opts.type) return res;
473
+ }
474
+ const nuxt = tryUseNuxt();
475
+ 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
+ ]);
482
+ const modulesDir = nuxt ? nuxt.options.modulesDir : [];
483
+ path = resolveAlias$1(path, opts.alias ?? nuxt?.options.alias ?? {});
484
+ if (!isAbsolute(path)) path = resolve(cwd, path);
485
+ const res = await _resolvePathType(path, opts);
486
+ if (res && res.type === opts.type) return res;
487
+ if (opts.type === "file") {
488
+ for (const ext of extensions) {
489
+ const normalizedExt = normalizeExtension(ext);
490
+ const extPath = await _resolvePathType(path + normalizedExt, opts);
491
+ if (extPath && extPath.type === "file") return extPath;
492
+ const indexPath = await _resolvePathType(join(path, "index" + normalizedExt), opts, res?.type !== "dir");
493
+ if (indexPath && indexPath.type === "file") return indexPath;
494
+ }
495
+ const resolvedModulePath = resolveModulePath(_path, {
496
+ try: true,
497
+ suffixes: ["", "index"],
498
+ from: [cwd, ...modulesDir].map((d) => directoryToURL(d))
499
+ });
500
+ if (resolvedModulePath) return {
501
+ path: resolvedModulePath,
502
+ type: "file",
503
+ virtual: false
504
+ };
505
+ }
506
+ return { path };
507
+ }
508
+ async function existsSensitive(path) {
509
+ return new Set(await promises.readdir(dirname(path)).catch(() => [])).has(basename(path));
510
+ }
511
+ function existsInVFS(path, nuxt = tryUseNuxt()) {
512
+ if (!nuxt) return false;
513
+ if (path in nuxt.vfs) return true;
514
+ return (nuxt.apps.default?.templates ?? nuxt.options.build.templates).some((template) => template.dst === path);
515
+ }
516
+ /**
517
+ * Resolve absolute file paths in the provided directory with respect to `.nuxtignore` and return them sorted.
518
+ * @param path path to the directory to resolve files in
519
+ * @param pattern glob pattern or an array of glob patterns to match files
520
+ * @param opts options for globbing
521
+ * @param opts.followSymbolicLinks whether to follow symbolic links, default is `true`
522
+ * @param opts.ignore additional glob patterns to ignore
523
+ * @returns sorted array of absolute file paths
524
+ */
525
+ async function resolveFiles(path, pattern, opts = {}) {
526
+ const files = [];
527
+ for (const p of await glob(pattern, {
528
+ cwd: path,
529
+ followSymbolicLinks: opts.followSymbolicLinks ?? true,
530
+ absolute: true,
531
+ ignore: opts.ignore
532
+ })) if (!isIgnored(p)) files.push(p);
533
+ return files.sort();
534
+ }
535
+ //#endregion
536
+ //#region src/internal/esm.ts
537
+ function directoryToURL(dir) {
538
+ return pathToFileURL(dir + "/");
539
+ }
540
+ function tryResolveModule(id, url = import.meta.url) {
541
+ return Promise.resolve(resolveModulePath(id, {
542
+ from: url,
543
+ suffixes: ["", "index"],
544
+ try: true
545
+ }));
546
+ }
547
+ function resolveModule(id, options) {
548
+ return resolveModulePath(id, {
549
+ 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
+ ]
558
+ });
559
+ }
560
+ async function importModule(id, opts) {
561
+ return await import(pathToFileURL(resolveModule(id, opts)).href).then((r) => opts?.interopDefault !== false ? interopDefault(r) : r);
562
+ }
563
+ function tryImportModule(id, opts) {
564
+ try {
565
+ return importModule(id, opts).catch(() => void 0);
566
+ } catch {}
567
+ }
568
+ /**
569
+ * @deprecated Please use `importModule` instead.
570
+ */
571
+ function requireModule(id, opts) {
572
+ const caller = getUserCaller();
573
+ warn(`[@nuxt/kit] \`requireModule\` is deprecated${caller ? ` (used at \`${resolveAlias(caller.source)}:${caller.line}:${caller.column}\`)` : ""}. Please use \`importModule\` instead.`);
574
+ const resolvedPath = resolveModule(id, opts);
575
+ return createJiti(import.meta.url, { interopDefault: opts?.interopDefault !== false })(pathToFileURL(resolvedPath).href);
576
+ }
577
+ /**
578
+ * @deprecated Please use `tryImportModule` instead.
579
+ */
580
+ function tryRequireModule(id, opts) {
581
+ try {
582
+ return requireModule(id, opts);
583
+ } catch {}
584
+ }
585
+ //#endregion
586
+ //#region src/module/install.ts
587
+ const NODE_MODULES_RE = /[/\\]node_modules[/\\]/;
588
+ const ignoredConfigKeys = new Set([
589
+ "components",
590
+ "imports",
591
+ "pages",
592
+ "devtools",
593
+ "telemetry"
594
+ ]);
595
+ /**
596
+ * Installs a set of modules on a Nuxt instance.
597
+ * @internal
598
+ */
599
+ async function installModules(modulesToInstall, resolvedModulePaths, nuxt = useNuxt()) {
600
+ const localLayerModuleDirs = [];
601
+ for (const l of nuxt.options._layers) {
602
+ const srcDir = l.config.srcDir || l.cwd;
603
+ if (!NODE_MODULES_RE.test(srcDir)) localLayerModuleDirs.push(resolve(srcDir, l.config?.dir?.modules || "modules").replace(/\/?$/, "/"));
604
+ }
605
+ nuxt._moduleOptionsFunctions ||= /* @__PURE__ */ new Map();
606
+ const resolvedModules = [];
607
+ const modulesByMetaName = /* @__PURE__ */ new Map();
608
+ const inlineConfigKeys = new Set(await Promise.all([...modulesToInstall].map(async ([mod]) => {
609
+ if (typeof mod === "string") return;
610
+ const meta = await Promise.resolve(mod.getMeta?.());
611
+ if (meta?.name) modulesByMetaName.set(meta.name, mod);
612
+ if (meta?.configKey) {
613
+ if (meta.configKey !== meta.name) modulesByMetaName.set(meta.configKey, mod);
614
+ return meta.configKey;
615
+ }
616
+ })));
617
+ let error;
618
+ const dependencyMap = /* @__PURE__ */ new Map();
619
+ for (const [key, options] of modulesToInstall) {
620
+ const res = await loadNuxtModuleInstance(key, nuxt).catch((err) => {
621
+ if (dependencyMap.has(key) && typeof key === "string") err.cause = `Could not resolve \`${key}\` (specified as a dependency of ${dependencyMap.get(key)}).`;
622
+ throw err;
623
+ });
624
+ const dependencyMeta = await res.nuxtModule.getModuleDependencies?.(nuxt) || {};
625
+ for (const [name, value] of Object.entries(dependencyMeta)) {
626
+ if (!value.overrides && !value.defaults && !value.version && value.optional) continue;
627
+ const resolvedModule = modulesByMetaName.has(name) ? resolveModuleWithOptions(modulesByMetaName.get(name), nuxt) : resolveModuleWithOptions(name, nuxt);
628
+ const moduleToAttribute = typeof key === "string" ? `\`${key}\`` : "a module in `nuxt.options`";
629
+ if (!resolvedModule?.module) {
630
+ const message = `Could not resolve \`${name}\` (specified as a dependency of ${moduleToAttribute}).`;
631
+ error = new TypeError(message);
632
+ continue;
633
+ }
634
+ if (value.version) {
635
+ 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 })) {
637
+ const message = `Module \`${name}\` version (\`${pkg.version}\`) does not satisfy \`${value.version}\` (requested by ${moduleToAttribute}).`;
638
+ error = new TypeError(message);
639
+ }
640
+ }
641
+ if (value.overrides || value.defaults) {
642
+ const currentFns = nuxt._moduleOptionsFunctions.get(resolvedModule.module) || [];
643
+ nuxt._moduleOptionsFunctions.set(resolvedModule.module, [...currentFns, () => ({
644
+ defaults: value.defaults,
645
+ overrides: value.overrides
646
+ })]);
647
+ }
648
+ if (value.optional === true) continue;
649
+ nuxt.options.typescript.hoist.push(name);
650
+ if (resolvedModule && !modulesToInstall.has(resolvedModule.module) && (!resolvedModule.resolvedPath || !resolvedModulePaths.has(resolvedModule.resolvedPath))) {
651
+ if (typeof resolvedModule.module === "string" && inlineConfigKeys.has(resolvedModule.module)) continue;
652
+ modulesToInstall.set(resolvedModule.module, resolvedModule.options);
653
+ dependencyMap.set(resolvedModule.module, moduleToAttribute);
654
+ const path = resolvedModule.resolvedPath || resolvedModule.module;
655
+ if (typeof path === "string") resolvedModulePaths.add(path);
656
+ }
657
+ }
658
+ resolvedModules.push({
659
+ moduleToInstall: key,
660
+ meta: await res.nuxtModule.getMeta?.(),
661
+ nuxtModule: res.nuxtModule,
662
+ buildTimeModuleMeta: res.buildTimeModuleMeta,
663
+ resolvedModulePath: res.resolvedModulePath,
664
+ inlineOptions: options
665
+ });
666
+ }
667
+ if (error) throw error;
668
+ for (const { nuxtModule, meta = {}, moduleToInstall, buildTimeModuleMeta, resolvedModulePath, inlineOptions } of resolvedModules) {
669
+ const configKey = meta.configKey;
670
+ const optionsFns = new Set([
671
+ ...nuxt._moduleOptionsFunctions.get(moduleToInstall) || [],
672
+ ...meta?.name ? nuxt._moduleOptionsFunctions.get(meta.name) || [] : [],
673
+ ...configKey ? nuxt._moduleOptionsFunctions.get(configKey) || [] : []
674
+ ]);
675
+ if (optionsFns.size > 0) {
676
+ const overrides = [];
677
+ const defaults = [];
678
+ for (const fn of optionsFns) {
679
+ const options = fn();
680
+ overrides.push(options.overrides);
681
+ defaults.push(options.defaults);
682
+ }
683
+ if (configKey) nuxt.options[configKey] = defu(...overrides, nuxt.options[configKey], ...defaults);
684
+ }
685
+ const isDisabled = configKey && !ignoredConfigKeys.has(configKey) && nuxt.options[configKey] === false;
686
+ if (!isDisabled) await callLifecycleHooks(nuxtModule, meta, inlineOptions, nuxt);
687
+ const path = typeof moduleToInstall === "string" ? moduleToInstall : void 0;
688
+ await callModule(nuxt, nuxtModule, inlineOptions, {
689
+ meta: defu({ disabled: isDisabled }, meta, buildTimeModuleMeta),
690
+ nameOrPath: path,
691
+ modulePath: resolvedModulePath || path,
692
+ localLayerModuleDirs
693
+ });
694
+ }
695
+ delete nuxt._moduleOptionsFunctions;
696
+ }
697
+ /**
698
+ * Installs a module on a Nuxt instance.
699
+ * @deprecated Use module dependencies.
700
+ */
701
+ async function installModule(moduleToInstall, inlineOptions, nuxt = useNuxt()) {
702
+ const { nuxtModule, buildTimeModuleMeta, resolvedModulePath } = await loadNuxtModuleInstance(moduleToInstall, nuxt);
703
+ const localLayerModuleDirs = [];
704
+ for (const dirs of getLayerDirectories(nuxt)) if (!NODE_MODULES_RE.test(dirs.app)) localLayerModuleDirs.push(dirs.modules);
705
+ const meta = await nuxtModule.getMeta?.();
706
+ let mergedOptions = inlineOptions;
707
+ const configKey = meta?.configKey;
708
+ if (configKey && nuxt._moduleOptionsFunctions) {
709
+ const optionsFns = [...nuxt._moduleOptionsFunctions.get(moduleToInstall) || [], ...nuxt._moduleOptionsFunctions.get(configKey) || []];
710
+ if (optionsFns.length > 0) {
711
+ const overrides = [];
712
+ const defaults = [];
713
+ for (const fn of optionsFns) {
714
+ const options = fn();
715
+ overrides.push(options.overrides);
716
+ defaults.push(options.defaults);
717
+ }
718
+ mergedOptions = defu(inlineOptions, ...overrides, nuxt.options[configKey], ...defaults);
719
+ nuxt.options[configKey] = mergedOptions;
720
+ }
721
+ }
722
+ const isDisabled = configKey && !ignoredConfigKeys.has(configKey) && nuxt.options[configKey] === false;
723
+ if (!isDisabled) await callLifecycleHooks(nuxtModule, meta, mergedOptions, nuxt);
724
+ const path = typeof moduleToInstall === "string" ? moduleToInstall : void 0;
725
+ await callModule(nuxt, nuxtModule, mergedOptions, {
726
+ meta: defu({ disabled: isDisabled }, meta, buildTimeModuleMeta),
727
+ nameOrPath: path,
728
+ modulePath: resolvedModulePath || path,
729
+ localLayerModuleDirs
730
+ });
731
+ }
732
+ function resolveModuleWithOptions(definition, nuxt) {
733
+ const [module, options = {}] = Array.isArray(definition) ? definition : [definition, {}];
734
+ if (!module) return;
735
+ if (typeof module !== "string") return {
736
+ module,
737
+ options
738
+ };
739
+ const modAlias = resolveAlias(module, nuxt.options.alias);
740
+ return {
741
+ module,
742
+ resolvedPath: resolveModulePath(modAlias, {
743
+ try: true,
744
+ from: nuxt.options.modulesDir.map((m) => directoryToURL(m.replace(/\/node_modules\/?$/, "/"))),
745
+ suffixes: [
746
+ "nuxt",
747
+ "nuxt/index",
748
+ "module",
749
+ "module/index",
750
+ "",
751
+ "index"
752
+ ],
753
+ extensions: [
754
+ ".js",
755
+ ".mjs",
756
+ ".cjs",
757
+ ".ts",
758
+ ".mts",
759
+ ".cts"
760
+ ]
761
+ }) || modAlias,
762
+ options
763
+ };
764
+ }
765
+ async function loadNuxtModuleInstance(nuxtModule, nuxt = useNuxt()) {
766
+ let buildTimeModuleMeta = {};
767
+ if (typeof nuxtModule === "function") return {
768
+ nuxtModule,
769
+ buildTimeModuleMeta
770
+ };
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 });
773
+ nuxtModule = resolveAlias(nuxtModule, nuxt.options.alias);
774
+ if (isRelative(nuxtModule)) nuxtModule = resolve(nuxt.options.rootDir, nuxtModule);
775
+ try {
776
+ const src = resolveModuleURL(nuxtModule, {
777
+ from: nuxt.options.modulesDir.map((m) => directoryToURL(m.replace(/\/node_modules\/?$/, "/"))),
778
+ suffixes: [
779
+ "nuxt",
780
+ "nuxt/index",
781
+ "module",
782
+ "module/index",
783
+ "",
784
+ "index"
785
+ ],
786
+ extensions: [
787
+ ".js",
788
+ ".mjs",
789
+ ".cjs",
790
+ ".ts",
791
+ ".mts",
792
+ ".cts"
793
+ ]
794
+ });
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
+ } 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
+ }
812
+ }
813
+ throw new TypeError(`Could not load \`${nuxtModule}\`. Is it installed?`);
814
+ }
815
+ function getDirectory(p) {
816
+ try {
817
+ return isAbsolute(p) && lstatSync(p).isFile() ? dirname(p) : p;
818
+ } catch {}
819
+ return p;
820
+ }
821
+ const normalizeModuleTranspilePath = (p) => {
822
+ return getDirectory(p).split("node_modules/").pop();
823
+ };
824
+ const MissingModuleMatcher = /Cannot find module\s+['"]?([^'")\s]+)['"]?/i;
825
+ async function callLifecycleHooks(nuxtModule, meta = {}, inlineOptions, nuxt = useNuxt()) {
826
+ if (!meta.name || !meta.version) return;
827
+ if (!nuxtModule.onInstall && !nuxtModule.onUpgrade) return;
828
+ const previousVersion = read({
829
+ dir: nuxt.options.rootDir,
830
+ name: ".nuxtrc"
831
+ })?.setups?.[meta.name];
832
+ try {
833
+ if (!previousVersion) await nuxtModule.onInstall?.(nuxt);
834
+ else if (semver.gt(meta.version, previousVersion)) await nuxtModule.onUpgrade?.(nuxt, inlineOptions, previousVersion);
835
+ if (previousVersion !== meta.version) update({ setups: { [meta.name]: meta?.version } }, {
836
+ dir: nuxt.options.rootDir,
837
+ name: ".nuxtrc"
838
+ });
839
+ } catch (e) {
840
+ logger.error(`Error while executing ${!previousVersion ? "install" : "upgrade"} hook for module \`${meta.name}\`: ${e}`);
841
+ }
842
+ }
843
+ async function callModule(nuxt, nuxtModule, moduleOptions = {}, options) {
844
+ const modulePath = options.modulePath;
845
+ const nameOrPath = options.nameOrPath;
846
+ const localLayerModuleDirs = options.localLayerModuleDirs;
847
+ const fn = () => nuxt.options.experimental?.debugModuleMutation && nuxt._asyncLocalStorageModule ? nuxt._asyncLocalStorageModule.run(nuxtModule, () => nuxtModule(moduleOptions, nuxt)) : nuxtModule(moduleOptions, nuxt);
848
+ const res = options.meta.disabled ? false : await fn();
849
+ let entryPath;
850
+ if (typeof modulePath === "string") {
851
+ const parsed = parseNodeModulePath(modulePath);
852
+ if (parsed.name) {
853
+ const subpath = await lookupNodeModuleSubpath(modulePath) || ".";
854
+ entryPath = join(parsed.name, subpath === "./" ? "." : subpath);
855
+ }
856
+ if (res !== false) {
857
+ const moduleRoot = parsed.dir ? parsed.dir + parsed.name : await resolvePackageJSON(modulePath, { try: true }).then((r) => r ? dirname(r) : modulePath);
858
+ nuxt.options.build.transpile.push(normalizeModuleTranspilePath(moduleRoot));
859
+ const directory = moduleRoot.replace(/\/?$/, "/");
860
+ if (moduleRoot !== nameOrPath && !localLayerModuleDirs.some((dir) => directory.startsWith(dir))) nuxt.options.modulesDir.push(join(moduleRoot, "node_modules"));
861
+ }
862
+ }
863
+ if (nameOrPath) {
864
+ entryPath ||= resolveAlias(nameOrPath, nuxt.options.alias);
865
+ if (entryPath !== nameOrPath) options.meta.rawPath = nameOrPath;
866
+ }
867
+ nuxt.options._installedModules ||= [];
868
+ nuxt.options._installedModules.push({
869
+ meta: options.meta,
870
+ module: nuxtModule,
871
+ timings: (res || {}).timings,
872
+ entryPath
873
+ });
874
+ }
875
+ //#endregion
876
+ //#region src/module/compatibility.ts
877
+ function resolveNuxtModuleEntryName(m) {
878
+ if (typeof m === "object" && !Array.isArray(m)) return m.name;
879
+ if (Array.isArray(m)) return resolveNuxtModuleEntryName(m[0]);
880
+ return m || false;
881
+ }
882
+ /**
883
+ * Check if a Nuxt module is installed by name.
884
+ *
885
+ * This will check both the installed modules and the modules to be installed. Note
886
+ * that it cannot detect if a module is _going to be_ installed programmatically by another module.
887
+ */
888
+ function hasNuxtModule(moduleName, nuxt = useNuxt()) {
889
+ return nuxt.options._installedModules.some(({ meta }) => meta.name === moduleName) || nuxt.options.modules.some((m) => moduleName === resolveNuxtModuleEntryName(m));
890
+ }
891
+ /**
892
+ * Checks if a Nuxt module is compatible with a given semver version.
893
+ */
894
+ async function hasNuxtModuleCompatibility(module, semverVersion, nuxt = useNuxt()) {
895
+ const version = await getNuxtModuleVersion(module, nuxt);
896
+ if (!version) return false;
897
+ return satisfies(normalizeSemanticVersion(version), semverVersion, { includePrerelease: true });
898
+ }
899
+ /**
900
+ * Get the version of a Nuxt module.
901
+ *
902
+ * Scans installed modules for the version, if it's not found it will attempt to load the module instance and get the version from there.
903
+ */
904
+ async function getNuxtModuleVersion(module, nuxt = useNuxt()) {
905
+ const moduleMeta = (typeof module === "string" ? { name: module } : await module.getMeta?.()) || {};
906
+ if (moduleMeta.version) return moduleMeta.version;
907
+ if (!moduleMeta.name) return false;
908
+ for (const m of nuxt.options._installedModules) if (m.meta.name === moduleMeta.name && m.meta.version) return m.meta.version;
909
+ if (hasNuxtModule(moduleMeta.name)) {
910
+ const { nuxtModule, buildTimeModuleMeta } = await loadNuxtModuleInstance(moduleMeta.name, nuxt);
911
+ return buildTimeModuleMeta.version || await nuxtModule.getMeta?.().then((r) => r.version) || false;
912
+ }
913
+ return false;
914
+ }
915
+ //#endregion
916
+ //#region src/loader/config.ts
917
+ const merger = createDefu((obj, key, value) => {
918
+ if (Array.isArray(obj[key]) && Array.isArray(value)) {
919
+ obj[key] = obj[key].concat(value);
920
+ return true;
921
+ }
922
+ });
923
+ async function loadNuxtConfig(opts) {
924
+ const localLayers = (await glob("layers/*", {
925
+ onlyDirectories: true,
926
+ cwd: opts.cwd || process.cwd()
927
+ })).map((d) => withTrailingSlash(d)).sort((a, b) => b.localeCompare(a));
928
+ opts.overrides = defu(opts.overrides, { _extends: localLayers });
929
+ const { configFile, layers = [], cwd, config: nuxtConfig, meta } = await withDefineNuxtConfig(() => loadConfig({
930
+ name: "nuxt",
931
+ configFile: "nuxt.config",
932
+ rcFile: ".nuxtrc",
933
+ extend: { extendKey: [
934
+ "theme",
935
+ "_extends",
936
+ "extends"
937
+ ] },
938
+ dotenv: true,
939
+ globalRc: true,
940
+ merger,
941
+ ...opts
942
+ }));
943
+ nuxtConfig.rootDir ||= cwd;
944
+ nuxtConfig._nuxtConfigFile = configFile;
945
+ nuxtConfig._nuxtConfigFiles = [configFile];
946
+ nuxtConfig._loadOptions = opts;
947
+ nuxtConfig.alias ||= {};
948
+ if (meta?.name) {
949
+ const alias = `#layers/${meta.name}`;
950
+ nuxtConfig.alias[alias] ||= withTrailingSlash(nuxtConfig.rootDir);
951
+ }
952
+ const defaultBuildDir = join(nuxtConfig.rootDir, ".nuxt");
953
+ 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());
955
+ const layerSchemaKeys = [
956
+ "future",
957
+ "srcDir",
958
+ "rootDir",
959
+ "serverDir",
960
+ "dir"
961
+ ];
962
+ const layerSchema = Object.create(null);
963
+ for (const key of layerSchemaKeys) if (key in NuxtConfigSchema) layerSchema[key] = NuxtConfigSchema[key];
964
+ const _layers = [];
965
+ const processedLayers = /* @__PURE__ */ new Set();
966
+ const localRelativePaths = new Set(localLayers.map((layer) => withoutTrailingSlash(layer)));
967
+ for (const layer of layers) {
968
+ const resolvedRootDir = layer.config?.rootDir ?? layer.cwd;
969
+ layer.config = {
970
+ ...layer.config || {},
971
+ rootDir: resolvedRootDir
972
+ };
973
+ if (processedLayers.has(resolvedRootDir)) continue;
974
+ processedLayers.add(resolvedRootDir);
975
+ layer.config = await applyDefaults(layerSchema, layer.config);
976
+ if (!layer.configFile || layer.configFile.endsWith(".nuxtrc")) continue;
977
+ if (layer.cwd && cwd && localRelativePaths.has(relative(cwd, layer.cwd))) {
978
+ layer.meta ||= {};
979
+ layer.meta.name ||= basename(layer.cwd);
980
+ }
981
+ if (layer.meta?.name) {
982
+ const alias = `#layers/${layer.meta.name}`;
983
+ nuxtConfig.alias[alias] ||= withTrailingSlash(layer.config.rootDir || layer.cwd);
984
+ }
985
+ _layers.push(layer);
986
+ }
987
+ nuxtConfig._layers = _layers;
988
+ if (!_layers.length) _layers.push({
989
+ cwd,
990
+ config: {
991
+ rootDir: cwd,
992
+ srcDir: cwd
993
+ }
994
+ });
995
+ return await applyDefaults(NuxtConfigSchema, nuxtConfig);
996
+ }
997
+ function loadNuxtSchema(cwd) {
998
+ const url = directoryToURL(cwd);
999
+ const urls = [url];
1000
+ const nuxtPath = resolveModuleURL("nuxt", {
1001
+ try: true,
1002
+ from: url
1003
+ }) ?? resolveModuleURL("nuxt-nightly", {
1004
+ try: true,
1005
+ from: url
1006
+ });
1007
+ if (nuxtPath) urls.unshift(nuxtPath);
1008
+ return import(resolveModuleURL("@nuxt/schema", {
1009
+ try: true,
1010
+ from: urls
1011
+ }) ?? "@nuxt/schema").then((r) => r.NuxtConfigSchema);
1012
+ }
1013
+ async function withDefineNuxtConfig(fn) {
1014
+ const key = "defineNuxtConfig";
1015
+ const globalSelf = globalThis;
1016
+ if (!globalSelf[key]) {
1017
+ globalSelf[key] = (c) => c;
1018
+ globalSelf[key].count = 0;
1019
+ }
1020
+ globalSelf[key].count++;
1021
+ try {
1022
+ return await fn();
1023
+ } finally {
1024
+ globalSelf[key].count--;
1025
+ if (!globalSelf[key].count) delete globalSelf[key];
1026
+ }
1027
+ }
1028
+ //#endregion
1029
+ //#region src/loader/schema.ts
1030
+ function extendNuxtSchema(def) {
1031
+ useNuxt().hook("schema:extend", (schemas) => {
1032
+ schemas.push(typeof def === "function" ? def() : def);
1033
+ });
1034
+ }
1035
+ //#endregion
1036
+ //#region src/loader/nuxt.ts
1037
+ async function loadNuxt(opts) {
1038
+ opts.cwd = resolve(opts.cwd || opts.rootDir || ".");
1039
+ opts.overrides ||= opts.config || {};
1040
+ opts.overrides.dev = !!opts.dev;
1041
+ const resolvedPath = ["nuxt-nightly", "nuxt"].reduce((resolvedPath, pkg) => {
1042
+ const path = resolveModulePath(pkg, {
1043
+ try: true,
1044
+ from: [directoryToURL(opts.cwd)]
1045
+ });
1046
+ return path && path.length > resolvedPath.length ? path : resolvedPath;
1047
+ }, "");
1048
+ if (!resolvedPath) throw new Error(`Cannot find any nuxt version from ${opts.cwd}`);
1049
+ const { loadNuxt } = await import(pathToFileURL(resolvedPath).href).then((r) => interopDefault(r));
1050
+ return await loadNuxt(opts);
1051
+ }
1052
+ async function buildNuxt(nuxt) {
1053
+ const rootURL = directoryToURL(nuxt.options.rootDir);
1054
+ const { build } = await tryImportModule("nuxt-nightly", { url: rootURL }) || await importModule("nuxt", { url: rootURL });
1055
+ return runWithNuxtContext(nuxt, () => build(nuxt));
1056
+ }
1057
+ //#endregion
1058
+ //#region src/head.ts
1059
+ function setGlobalHead(head) {
1060
+ const nuxt = useNuxt();
1061
+ nuxt.options.app.head = defu(head, nuxt.options.app.head);
1062
+ }
1063
+ //#endregion
1064
+ //#region src/imports.ts
1065
+ function addImports(imports) {
1066
+ useNuxt().hook("imports:extend", (_imports) => {
1067
+ _imports.push(...toArray(imports));
1068
+ });
1069
+ }
1070
+ function addImportsDir(dirs, opts = {}) {
1071
+ useNuxt().hook("imports:dirs", (_dirs) => {
1072
+ for (const dir of toArray(dirs)) _dirs[opts.prepend ? "unshift" : "push"](dir);
1073
+ });
1074
+ }
1075
+ function addImportsSources(presets) {
1076
+ useNuxt().hook("imports:sources", (_presets) => {
1077
+ for (const preset of toArray(presets)) _presets.push(preset);
1078
+ });
1079
+ }
1080
+ //#endregion
1081
+ //#region src/nitro.ts
1082
+ const HANDLER_METHOD_RE = /\.(get|head|patch|post|put|delete|connect|options|trace)(\.\w+)*$/;
1083
+ /**
1084
+ * normalize handler object
1085
+ *
1086
+ */
1087
+ function normalizeHandlerMethod(handler) {
1088
+ const [, method = void 0] = handler.handler.match(HANDLER_METHOD_RE) || [];
1089
+ return {
1090
+ method: method?.toUpperCase(),
1091
+ ...handler,
1092
+ handler: normalize(handler.handler)
1093
+ };
1094
+ }
1095
+ /**
1096
+ * Adds a nitro server handler
1097
+ *
1098
+ */
1099
+ function addServerHandler(handler) {
1100
+ useNuxt().options.serverHandlers.push(normalizeHandlerMethod(handler));
1101
+ }
1102
+ /**
1103
+ * Adds a nitro server handler for development-only
1104
+ *
1105
+ */
1106
+ function addDevServerHandler(handler) {
1107
+ useNuxt().options.devServerHandlers.push(handler);
1108
+ }
1109
+ /**
1110
+ * Adds a Nitro plugin
1111
+ */
1112
+ function addServerPlugin(plugin) {
1113
+ const nuxt = useNuxt();
1114
+ nuxt.options.nitro.plugins ||= [];
1115
+ nuxt.options.nitro.plugins.push(normalize(plugin));
1116
+ }
1117
+ /**
1118
+ * Adds routes to be prerendered
1119
+ */
1120
+ function addPrerenderRoutes(routes) {
1121
+ const nuxt = useNuxt();
1122
+ routes = toArray(routes).filter(Boolean);
1123
+ if (!routes.length) return;
1124
+ nuxt.hook("prerender:routes", (ctx) => {
1125
+ for (const route of routes) ctx.routes.add(route);
1126
+ });
1127
+ }
1128
+ /**
1129
+ * Access to the Nitro instance
1130
+ *
1131
+ * **Note:** You can call `useNitro()` only after `ready` hook.
1132
+ *
1133
+ * **Note:** Changes to the Nitro instance configuration are not applied.
1134
+ * @example
1135
+ *
1136
+ * ```ts
1137
+ * nuxt.hook('ready', () => {
1138
+ * console.log(useNitro())
1139
+ * })
1140
+ * ```
1141
+ */
1142
+ function useNitro() {
1143
+ const nuxt = useNuxt();
1144
+ if (!nuxt._nitro) throw new Error("Nitro is not initialized yet. You can call `useNitro()` only after `ready` hook.");
1145
+ return nuxt._nitro;
1146
+ }
1147
+ /**
1148
+ * Add server imports to be auto-imported by Nitro
1149
+ */
1150
+ function addServerImports(imports) {
1151
+ const nuxt = useNuxt();
1152
+ const _imports = toArray(imports);
1153
+ nuxt.hook("nitro:config", (config) => {
1154
+ config.imports ||= {};
1155
+ config.imports.imports ||= [];
1156
+ config.imports.imports.push(..._imports);
1157
+ });
1158
+ }
1159
+ /**
1160
+ * Add directories to be scanned for auto-imports by Nitro
1161
+ */
1162
+ function addServerImportsDir(dirs, opts = {}) {
1163
+ const nuxt = useNuxt();
1164
+ const _dirs = toArray(dirs);
1165
+ nuxt.hook("nitro:config", (config) => {
1166
+ config.imports ||= {};
1167
+ config.imports.dirs ||= [];
1168
+ config.imports.dirs[opts.prepend ? "unshift" : "push"](..._dirs);
1169
+ });
1170
+ }
1171
+ /**
1172
+ * Add directories to be scanned by Nitro. It will check for subdirectories,
1173
+ * which will be registered just like the `~~/server` folder is.
1174
+ */
1175
+ function addServerScanDir(dirs, opts = {}) {
1176
+ useNuxt().hook("nitro:config", (config) => {
1177
+ config.scanDirs ||= [];
1178
+ for (const dir of toArray(dirs)) config.scanDirs[opts.prepend ? "unshift" : "push"](dir);
1179
+ });
1180
+ }
1181
+ //#endregion
1182
+ //#region src/runtime-config.ts
1183
+ /**
1184
+ * Access 'resolved' Nuxt runtime configuration, with values updated from environment.
1185
+ *
1186
+ * This mirrors the runtime behavior of Nitro.
1187
+ */
1188
+ function useRuntimeConfig() {
1189
+ const nuxt = useNuxt();
1190
+ return applyEnv(klona(nuxt.options.nitro.runtimeConfig), {
1191
+ prefix: "NITRO_",
1192
+ altPrefix: "NUXT_",
1193
+ envExpansion: nuxt.options.nitro.experimental?.envExpansion ?? !!process.env.NITRO_ENV_EXPANSION
1194
+ });
1195
+ }
1196
+ /**
1197
+ * Update Nuxt runtime configuration.
1198
+ */
1199
+ function updateRuntimeConfig(runtimeConfig) {
1200
+ const nuxt = useNuxt();
1201
+ Object.assign(nuxt.options.nitro.runtimeConfig, defu(runtimeConfig, nuxt.options.nitro.runtimeConfig));
1202
+ try {
1203
+ return useNitro().updateConfig({ runtimeConfig });
1204
+ } catch {}
1205
+ }
1206
+ function getEnv(key, opts, env = process.env) {
1207
+ const envKey = snakeCase(key).toUpperCase();
1208
+ return destr(env[opts.prefix + envKey] ?? env[opts.altPrefix + envKey]);
1209
+ }
1210
+ function _isObject(input) {
1211
+ return typeof input === "object" && !Array.isArray(input);
1212
+ }
1213
+ function applyEnv(obj, opts, parentKey = "") {
1214
+ for (const key in obj) {
1215
+ const subKey = parentKey ? `${parentKey}_${key}` : key;
1216
+ const envValue = getEnv(subKey, opts);
1217
+ if (_isObject(obj[key])) if (_isObject(envValue)) {
1218
+ obj[key] = {
1219
+ ...obj[key],
1220
+ ...envValue
1221
+ };
1222
+ applyEnv(obj[key], opts, subKey);
1223
+ } else if (envValue === void 0) applyEnv(obj[key], opts, subKey);
1224
+ else obj[key] = envValue ?? obj[key];
1225
+ else obj[key] = envValue ?? obj[key];
1226
+ if (opts.envExpansion && typeof obj[key] === "string") obj[key] = _expandFromEnv(obj[key]);
1227
+ }
1228
+ return obj;
1229
+ }
1230
+ const envExpandRx = /\{\{([^{}]*)\}\}/g;
1231
+ function _expandFromEnv(value, env = process.env) {
1232
+ return value.replace(envExpandRx, (match, key) => {
1233
+ return env[key] || match;
1234
+ });
1235
+ }
1236
+ //#endregion
1237
+ //#region src/build.ts
1238
+ const extendWebpackCompatibleConfig = (builder) => (fn, options = {}) => {
1239
+ const nuxt = useNuxt();
1240
+ if (options.dev === false && nuxt.options.dev) return;
1241
+ if (options.build === false && nuxt.options.build) return;
1242
+ nuxt.hook(`${builder}:config`, async (configs) => {
1243
+ if (options.server !== false) {
1244
+ const config = configs.find((i) => i.name === "server");
1245
+ if (config) await fn(config);
1246
+ }
1247
+ if (options.client !== false) {
1248
+ const config = configs.find((i) => i.name === "client");
1249
+ if (config) await fn(config);
1250
+ }
1251
+ });
1252
+ };
1253
+ /**
1254
+ * Extend webpack config
1255
+ *
1256
+ * The fallback function might be called multiple times
1257
+ * when applying to both client and server builds.
1258
+ */
1259
+ const extendWebpackConfig = extendWebpackCompatibleConfig("webpack");
1260
+ /**
1261
+ * Extend rspack config
1262
+ *
1263
+ * The fallback function might be called multiple times
1264
+ * when applying to both client and server builds.
1265
+ */
1266
+ const extendRspackConfig = extendWebpackCompatibleConfig("rspack");
1267
+ /**
1268
+ * Extend Vite config
1269
+ */
1270
+ function extendViteConfig(fn, options = {}) {
1271
+ const nuxt = useNuxt();
1272
+ if (options.dev === false && nuxt.options.dev) return;
1273
+ if (options.build === false && nuxt.options.build) return;
1274
+ if (options.server === false || options.client === false) {
1275
+ const caller = getUserCaller();
1276
+ warn(`[@nuxt/kit] calling \`extendViteConfig\` with only server/client environment is deprecated${caller ? ` (used at \`${resolveAlias(caller.source)}:${caller.line}:${caller.column}\`)` : ""}. Nuxt 5+ will use the Vite Environment API which shares a configuration between environments. You can likely use a Vite plugin to achieve the same result.`);
1277
+ }
1278
+ return nuxt.hook("vite:extend", ({ config }) => fn(config));
1279
+ }
1280
+ /**
1281
+ * Append webpack plugin to the config.
1282
+ */
1283
+ function addWebpackPlugin(pluginOrGetter, options) {
1284
+ extendWebpackConfig(async (config) => {
1285
+ const method = options?.prepend ? "unshift" : "push";
1286
+ const plugin = typeof pluginOrGetter === "function" ? await pluginOrGetter() : pluginOrGetter;
1287
+ config.plugins ||= [];
1288
+ config.plugins[method](...toArray(plugin));
1289
+ }, options);
1290
+ }
1291
+ /**
1292
+ * Append rspack plugin to the config.
1293
+ */
1294
+ function addRspackPlugin(pluginOrGetter, options) {
1295
+ extendRspackConfig(async (config) => {
1296
+ const method = options?.prepend ? "unshift" : "push";
1297
+ const plugin = typeof pluginOrGetter === "function" ? await pluginOrGetter() : pluginOrGetter;
1298
+ config.plugins ||= [];
1299
+ config.plugins[method](...toArray(plugin));
1300
+ }, options);
1301
+ }
1302
+ /**
1303
+ * Append Vite plugin to the config.
1304
+ */
1305
+ function addVitePlugin(pluginOrGetter, options = {}) {
1306
+ const nuxt = useNuxt();
1307
+ if (options.dev === false && nuxt.options.dev) return;
1308
+ if (options.build === false && nuxt.options.build) return;
1309
+ let needsEnvInjection = false;
1310
+ nuxt.hook("vite:extend", async ({ config }) => {
1311
+ config.plugins ||= [];
1312
+ const plugin = toArray(typeof pluginOrGetter === "function" ? await pluginOrGetter() : pluginOrGetter);
1313
+ if (options.server !== false && options.client !== false) {
1314
+ const method = options?.prepend ? "unshift" : "push";
1315
+ config.plugins[method](...plugin);
1316
+ return;
1317
+ }
1318
+ if (!config.environments?.ssr || !config.environments.client) {
1319
+ needsEnvInjection = true;
1320
+ return;
1321
+ }
1322
+ const environmentName = options.server === false ? "client" : "ssr";
1323
+ const pluginName = plugin.map((p) => p.name).join("|");
1324
+ config.plugins.push({
1325
+ name: `${pluginName}:wrapper`,
1326
+ enforce: options?.prepend ? "pre" : "post",
1327
+ applyToEnvironment(environment) {
1328
+ if (environment.name === environmentName) return plugin;
1329
+ }
1330
+ });
1331
+ });
1332
+ nuxt.hook("vite:extendConfig", async (config, env) => {
1333
+ if (!needsEnvInjection) return;
1334
+ const plugin = toArray(typeof pluginOrGetter === "function" ? await pluginOrGetter() : pluginOrGetter);
1335
+ const method = options?.prepend ? "unshift" : "push";
1336
+ if (env.isClient && options.server === false) config.plugins[method](...plugin);
1337
+ if (env.isServer && options.client === false) config.plugins[method](...plugin);
1338
+ });
1339
+ }
1340
+ function addBuildPlugin(pluginFactory, options) {
1341
+ if (pluginFactory.vite) addVitePlugin(pluginFactory.vite, options);
1342
+ if (pluginFactory.webpack) addWebpackPlugin(pluginFactory.webpack, options);
1343
+ if (pluginFactory.rspack) addRspackPlugin(pluginFactory.rspack, options);
1344
+ }
1345
+ //#endregion
1346
+ //#region src/components.ts
1347
+ /**
1348
+ * Register a directory to be scanned for components and imported only when used.
1349
+ */
1350
+ function addComponentsDir(dir, opts = {}) {
1351
+ const nuxt = useNuxt();
1352
+ nuxt.options.components ||= [];
1353
+ dir.priority ||= 0;
1354
+ nuxt.hook("components:dirs", (dirs) => {
1355
+ dirs[opts.prepend ? "unshift" : "push"](dir);
1356
+ });
1357
+ }
1358
+ /**
1359
+ * This utility takes a file path or npm package that is scanned for named exports, which are get added automatically
1360
+ */
1361
+ function addComponentExports(opts) {
1362
+ const nuxt = useNuxt();
1363
+ const components = [];
1364
+ nuxt.hook("components:dirs", async () => {
1365
+ const names = await resolveModuleExportNames(await resolvePath(opts.filePath), { extensions: nuxt.options.extensions });
1366
+ components.length = 0;
1367
+ for (const name of names) components.push(normalizeComponent({
1368
+ name: pascalCase([opts.prefix || "", name === "default" ? "" : name]),
1369
+ export: name,
1370
+ ...opts
1371
+ }));
1372
+ });
1373
+ addComponents(components);
1374
+ }
1375
+ /**
1376
+ * Register a component by its name and filePath.
1377
+ */
1378
+ function addComponent(opts) {
1379
+ addComponents([normalizeComponent(opts)]);
1380
+ }
1381
+ function addComponents(addedComponents) {
1382
+ const nuxt = useNuxt();
1383
+ nuxt.options.components ||= [];
1384
+ nuxt.hook("components:extend", (components) => {
1385
+ for (const component of addedComponents) {
1386
+ const existingComponentIndex = components.findIndex((c) => (c.pascalName === component.pascalName || c.kebabName === component.kebabName) && c.mode === component.mode);
1387
+ if (existingComponentIndex !== -1) {
1388
+ const existingComponent = components[existingComponentIndex];
1389
+ const existingPriority = existingComponent.priority ?? 0;
1390
+ const newPriority = component.priority ?? 0;
1391
+ if (newPriority < existingPriority) continue;
1392
+ if (newPriority === existingPriority) {
1393
+ 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.`);
1395
+ }
1396
+ components.splice(existingComponentIndex, 1, component);
1397
+ } else components.push(component);
1398
+ }
1399
+ });
1400
+ }
1401
+ function normalizeComponent(opts) {
1402
+ if (!opts.mode) {
1403
+ const [, mode = "all"] = opts.filePath.match(MODE_RE) || [];
1404
+ opts.mode = mode;
1405
+ }
1406
+ return {
1407
+ export: opts.export || "default",
1408
+ chunkName: "components/" + kebabCase(opts.name),
1409
+ global: opts.global ?? false,
1410
+ kebabName: kebabCase(opts.name || ""),
1411
+ pascalName: pascalCase(opts.name || ""),
1412
+ prefetch: false,
1413
+ preload: false,
1414
+ mode: "all",
1415
+ shortPath: opts.filePath,
1416
+ priority: 0,
1417
+ meta: {},
1418
+ ...opts
1419
+ };
1420
+ }
1421
+ //#endregion
1422
+ //#region src/template.ts
1423
+ /**
1424
+ * Renders given template during build into the virtual file system (and optionally to disk in the project `buildDir`)
1425
+ */
1426
+ function addTemplate(_template) {
1427
+ const nuxt = useNuxt();
1428
+ const template = normalizeTemplate(_template);
1429
+ filterInPlace(nuxt.options.build.templates, (p) => (p.dst || normalizeTemplate(p).dst) !== template.dst);
1430
+ try {
1431
+ const distDir = distDirURL.toString();
1432
+ const { source } = captureStackTrace().find((e) => e.source && !e.source.startsWith(distDir)) ?? {};
1433
+ if (source) {
1434
+ const path = normalize(fileURLToPath(source));
1435
+ if (existsSync(path)) template._path = path;
1436
+ }
1437
+ } catch {}
1438
+ nuxt.options.build.templates.push(template);
1439
+ return template;
1440
+ }
1441
+ /**
1442
+ * Adds a virtual file that can be used within the Nuxt Nitro server build.
1443
+ */
1444
+ function addServerTemplate(template) {
1445
+ const nuxt = useNuxt();
1446
+ nuxt.options.nitro.virtual ||= {};
1447
+ nuxt.options.nitro.virtual[template.filename] = template.getContents;
1448
+ return template;
1449
+ }
1450
+ /**
1451
+ * Renders given types during build to disk in the project `buildDir`
1452
+ * and register them as types.
1453
+ *
1454
+ * You can pass a second context object to specify in which context the type should be added.
1455
+ *
1456
+ * If no context object is passed, then it will only be added to the nuxt context.
1457
+ */
1458
+ function addTypeTemplate(_template, context) {
1459
+ const nuxt = useNuxt();
1460
+ 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}"`);
1462
+ if (!context || context.nuxt) nuxt.hook("prepare:types", (payload) => {
1463
+ payload.references ||= [];
1464
+ payload.references.push({ path: template.dst });
1465
+ });
1466
+ if (context?.node) nuxt.hook("prepare:types", (payload) => {
1467
+ payload.nodeReferences ||= [];
1468
+ payload.nodeReferences.push({ path: template.dst });
1469
+ });
1470
+ if (context?.shared) nuxt.hook("prepare:types", (payload) => {
1471
+ payload.sharedReferences ||= [];
1472
+ payload.sharedReferences.push({ path: template.dst });
1473
+ });
1474
+ if (!context || context.nuxt || context.shared) nuxt.options.vite.vue = defu(nuxt.options.vite.vue, { script: { globalTypeFiles: [template.dst] } });
1475
+ if (context?.nitro) nuxt.hook("nitro:prepare:types", (payload) => {
1476
+ payload.references ||= [];
1477
+ payload.references.push({ path: template.dst });
1478
+ });
1479
+ return template;
1480
+ }
1481
+ /**
1482
+ * Normalize a nuxt template object
1483
+ */
1484
+ function normalizeTemplate(template, buildDir) {
1485
+ if (!template) throw new Error("Invalid template: " + JSON.stringify(template));
1486
+ if (typeof template === "string") template = { src: template };
1487
+ else template = { ...template };
1488
+ if (template.src) {
1489
+ if (!existsSync(template.src)) throw new Error("Template not found: " + template.src);
1490
+ if (!template.filename) {
1491
+ const srcPath = parse(template.src);
1492
+ template.filename = template.fileName || `${basename(srcPath.dir)}.${srcPath.name}.${hash(template.src).replace(/-/g, "_")}${srcPath.ext}`;
1493
+ }
1494
+ }
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;
1498
+ template.dst ||= resolve(buildDir ?? useNuxt().options.buildDir, template.filename);
1499
+ return template;
1500
+ }
1501
+ /**
1502
+ * Trigger rebuilding Nuxt templates
1503
+ *
1504
+ * You can pass a filter within the options to selectively regenerate a subset of templates.
1505
+ */
1506
+ async function updateTemplates(options) {
1507
+ await tryUseNuxt()?.hooks.callHook("builder:generateApp", options);
1508
+ }
1509
+ function resolveLayerPaths(dirs, projectBuildDir) {
1510
+ const relativeRootDir = relativeWithDot(projectBuildDir, dirs.root);
1511
+ const relativeSrcDir = relativeWithDot(projectBuildDir, dirs.app);
1512
+ const relativeModulesDir = relativeWithDot(projectBuildDir, dirs.modules);
1513
+ const relativeSharedDir = relativeWithDot(projectBuildDir, dirs.shared);
1514
+ return {
1515
+ nuxt: [
1516
+ join(relativeSrcDir, "**/*"),
1517
+ join(relativeModulesDir, `*/runtime/**/*`),
1518
+ join(relativeRootDir, `test/nuxt/**/*`),
1519
+ join(relativeRootDir, `tests/nuxt/**/*`),
1520
+ join(relativeRootDir, `layers/*/app/**/*`),
1521
+ join(relativeRootDir, `layers/*/modules/*/runtime/**/*`)
1522
+ ],
1523
+ nitro: [
1524
+ join(relativeModulesDir, `*/runtime/server/**/*`),
1525
+ join(relativeRootDir, `layers/*/server/**/*`),
1526
+ join(relativeRootDir, `layers/*/modules/*/runtime/server/**/*`)
1527
+ ],
1528
+ node: [
1529
+ join(relativeModulesDir, `*.*`),
1530
+ join(relativeRootDir, `nuxt.config.*`),
1531
+ join(relativeRootDir, `.config/nuxt.*`),
1532
+ join(relativeRootDir, `layers/*/nuxt.config.*`),
1533
+ join(relativeRootDir, `layers/*/.config/nuxt.*`),
1534
+ join(relativeRootDir, `layers/*/modules/**/*`)
1535
+ ],
1536
+ shared: [
1537
+ join(relativeSharedDir, `**/*`),
1538
+ join(relativeModulesDir, `*/shared/**/*`),
1539
+ join(relativeRootDir, `layers/*/shared/**/*`)
1540
+ ],
1541
+ sharedDeclarations: [
1542
+ join(relativeSharedDir, `**/*.d.ts`),
1543
+ join(relativeModulesDir, `*/shared/**/*.d.ts`),
1544
+ join(relativeRootDir, `layers/*/shared/**/*.d.ts`)
1545
+ ],
1546
+ globalDeclarations: [join(relativeRootDir, `*.d.ts`), join(relativeRootDir, `layers/*/*.d.ts`)]
1547
+ };
1548
+ }
1549
+ const EXTENSION_RE = /\b(?:\.d\.[cm]?ts|\.\w+)$/g;
1550
+ const excludedAlias = [/^@vue\/.*$/, /^#internal\/nuxt/];
1551
+ 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]);
1556
+ const exclude = /* @__PURE__ */ new Set();
1557
+ const nodeExclude = /* @__PURE__ */ new Set();
1558
+ const sharedExclude = /* @__PURE__ */ new Set();
1559
+ const legacyExclude = /* @__PURE__ */ new Set();
1560
+ if (nuxt.options.typescript.includeWorkspace && nuxt.options.workspaceDir !== nuxt.options.srcDir) {
1561
+ include.add(join(relative(nuxt.options.buildDir, nuxt.options.workspaceDir), "**/*"));
1562
+ legacyInclude.add(join(relative(nuxt.options.buildDir, nuxt.options.workspaceDir), "**/*"));
1563
+ }
1564
+ const layerDirs = getLayerDirectories(nuxt);
1565
+ const sourceDirs = layerDirs.map((layer) => layer.app);
1566
+ for (const dir of nuxt.options.modulesDir) {
1567
+ if (!sourceDirs.some((srcDir) => dir.startsWith(srcDir))) exclude.add(relativeWithDot(nuxt.options.buildDir, dir));
1568
+ nodeExclude.add(relativeWithDot(nuxt.options.buildDir, dir));
1569
+ legacyExclude.add(relativeWithDot(nuxt.options.buildDir, dir));
1570
+ }
1571
+ for (const dir of ["dist", ".data"]) {
1572
+ exclude.add(relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, dir)));
1573
+ nodeExclude.add(relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, dir)));
1574
+ legacyExclude.add(relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, dir)));
1575
+ }
1576
+ const rootDirWithSlash = withTrailingSlash$1(nuxt.options.rootDir);
1577
+ for (const dirs of layerDirs) if (!dirs.app.startsWith(rootDirWithSlash) || dirs.root === rootDirWithSlash || dirs.app.includes("node_modules")) {
1578
+ const rootGlob = join(relativeWithDot(nuxt.options.buildDir, dirs.root), "**/*");
1579
+ const paths = resolveLayerPaths(dirs, nuxt.options.buildDir);
1580
+ for (const path of paths.nuxt) {
1581
+ include.add(path);
1582
+ legacyInclude.add(path);
1583
+ if (path !== rootGlob) nodeExclude.add(path);
1584
+ }
1585
+ for (const path of paths.nitro) {
1586
+ exclude.add(path);
1587
+ nodeExclude.add(path);
1588
+ legacyExclude.add(path);
1589
+ }
1590
+ for (const path of paths.node) {
1591
+ nodeInclude.add(path);
1592
+ legacyInclude.add(path);
1593
+ exclude.add(path);
1594
+ }
1595
+ for (const path of paths.shared) {
1596
+ legacyInclude.add(path);
1597
+ sharedInclude.add(path);
1598
+ }
1599
+ for (const path of paths.sharedDeclarations) include.add(path);
1600
+ for (const path of paths.globalDeclarations) {
1601
+ include.add(path);
1602
+ legacyInclude.add(path);
1603
+ sharedInclude.add(path);
1604
+ }
1605
+ }
1606
+ const moduleEntryPaths = [];
1607
+ for (const m of nuxt.options._installedModules) {
1608
+ const path = m.meta?.rawPath || m.entryPath;
1609
+ if (path) moduleEntryPaths.push(getDirectory(path));
1610
+ }
1611
+ const modulePaths = await resolveNuxtModule(rootDirWithSlash, moduleEntryPaths);
1612
+ for (const path of modulePaths) {
1613
+ const relative = relativeWithDot(nuxt.options.buildDir, path);
1614
+ if (!path.includes("node_modules") && path.startsWith(rootDirWithSlash)) {
1615
+ include.add(join(relative, "runtime"));
1616
+ include.add(join(relative, "dist/runtime"));
1617
+ nodeInclude.add(join(relative, "*.*"));
1618
+ }
1619
+ legacyInclude.add(join(relative, "runtime"));
1620
+ legacyInclude.add(join(relative, "dist/runtime"));
1621
+ nodeExclude.add(join(relative, "runtime"));
1622
+ nodeExclude.add(join(relative, "dist/runtime"));
1623
+ exclude.add(join(relative, "runtime/server"));
1624
+ exclude.add(join(relative, "dist/runtime/server"));
1625
+ exclude.add(join(relative, "*.*"));
1626
+ exclude.add(join(relative, "dist/*.*"));
1627
+ legacyExclude.add(join(relative, "runtime/server"));
1628
+ legacyExclude.add(join(relative, "dist/runtime/server"));
1629
+ }
1630
+ const nestedModulesDirs = [];
1631
+ for (const dir of [...nuxt.options.modulesDir].sort()) {
1632
+ const withSlash = withTrailingSlash$1(dir);
1633
+ if (nestedModulesDirs.every((d) => !d.startsWith(withSlash))) nestedModulesDirs.push(withSlash);
1634
+ }
1635
+ 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);
1637
+ hasTypescriptVersionWithModulePreserve ??= true;
1638
+ const useDecorators = Boolean(nuxt.options.experimental?.decorators);
1639
+ const tsConfig = defu(nuxt.options.typescript?.tsConfig, {
1640
+ compilerOptions: {
1641
+ esModuleInterop: true,
1642
+ skipLibCheck: true,
1643
+ target: "ESNext",
1644
+ allowJs: true,
1645
+ resolveJsonModule: true,
1646
+ moduleDetection: "force",
1647
+ isolatedModules: true,
1648
+ verbatimModuleSyntax: true,
1649
+ allowArbitraryExtensions: true,
1650
+ strict: nuxt.options.typescript?.strict ?? true,
1651
+ noUncheckedIndexedAccess: true,
1652
+ forceConsistentCasingInFileNames: true,
1653
+ noImplicitOverride: true,
1654
+ ...useDecorators ? { experimentalDecorators: false } : {},
1655
+ module: hasTypescriptVersionWithModulePreserve ? "preserve" : "ESNext",
1656
+ noEmit: true,
1657
+ lib: [
1658
+ "ESNext",
1659
+ ...useDecorators ? ["esnext.decorators"] : [],
1660
+ "dom",
1661
+ "dom.iterable",
1662
+ "webworker"
1663
+ ],
1664
+ jsx: "preserve",
1665
+ jsxImportSource: "vue",
1666
+ types: [],
1667
+ paths: {},
1668
+ moduleResolution: nuxt.options.future?.typescriptBundlerResolution || nuxt.options.experimental?.typescriptBundlerResolution ? "Bundler" : "Node",
1669
+ useDefineForClassFields: true,
1670
+ noImplicitThis: true,
1671
+ allowSyntheticDefaultImports: true
1672
+ },
1673
+ include: [...include],
1674
+ exclude: [...exclude]
1675
+ });
1676
+ const nodeTsConfig = defu(nuxt.options.typescript?.nodeTsConfig, {
1677
+ compilerOptions: {
1678
+ esModuleInterop: tsConfig.compilerOptions?.esModuleInterop,
1679
+ skipLibCheck: tsConfig.compilerOptions?.skipLibCheck,
1680
+ target: tsConfig.compilerOptions?.target,
1681
+ allowJs: tsConfig.compilerOptions?.allowJs,
1682
+ resolveJsonModule: tsConfig.compilerOptions?.resolveJsonModule,
1683
+ moduleDetection: tsConfig.compilerOptions?.moduleDetection,
1684
+ isolatedModules: tsConfig.compilerOptions?.isolatedModules,
1685
+ verbatimModuleSyntax: tsConfig.compilerOptions?.verbatimModuleSyntax,
1686
+ allowArbitraryExtensions: tsConfig.compilerOptions?.allowArbitraryExtensions,
1687
+ strict: tsConfig.compilerOptions?.strict,
1688
+ noUncheckedIndexedAccess: tsConfig.compilerOptions?.noUncheckedIndexedAccess,
1689
+ forceConsistentCasingInFileNames: tsConfig.compilerOptions?.forceConsistentCasingInFileNames,
1690
+ noImplicitOverride: tsConfig.compilerOptions?.noImplicitOverride,
1691
+ module: tsConfig.compilerOptions?.module,
1692
+ noEmit: true,
1693
+ types: [],
1694
+ paths: {},
1695
+ moduleResolution: tsConfig.compilerOptions?.moduleResolution,
1696
+ useDefineForClassFields: tsConfig.compilerOptions?.useDefineForClassFields,
1697
+ noImplicitThis: tsConfig.compilerOptions?.noImplicitThis,
1698
+ allowSyntheticDefaultImports: tsConfig.compilerOptions?.allowSyntheticDefaultImports
1699
+ },
1700
+ include: [...nodeInclude],
1701
+ exclude: [...nodeExclude]
1702
+ });
1703
+ const sharedTsConfig = defu(nuxt.options.typescript?.sharedTsConfig, {
1704
+ compilerOptions: {
1705
+ esModuleInterop: tsConfig.compilerOptions?.esModuleInterop,
1706
+ skipLibCheck: tsConfig.compilerOptions?.skipLibCheck,
1707
+ target: tsConfig.compilerOptions?.target,
1708
+ allowJs: tsConfig.compilerOptions?.allowJs,
1709
+ resolveJsonModule: tsConfig.compilerOptions?.resolveJsonModule,
1710
+ moduleDetection: tsConfig.compilerOptions?.moduleDetection,
1711
+ isolatedModules: tsConfig.compilerOptions?.isolatedModules,
1712
+ verbatimModuleSyntax: tsConfig.compilerOptions?.verbatimModuleSyntax,
1713
+ allowArbitraryExtensions: tsConfig.compilerOptions?.allowArbitraryExtensions,
1714
+ strict: tsConfig.compilerOptions?.strict,
1715
+ noUncheckedIndexedAccess: tsConfig.compilerOptions?.noUncheckedIndexedAccess,
1716
+ forceConsistentCasingInFileNames: tsConfig.compilerOptions?.forceConsistentCasingInFileNames,
1717
+ noImplicitOverride: tsConfig.compilerOptions?.noImplicitOverride,
1718
+ module: tsConfig.compilerOptions?.module,
1719
+ noEmit: true,
1720
+ types: [],
1721
+ paths: {},
1722
+ moduleResolution: tsConfig.compilerOptions?.moduleResolution,
1723
+ useDefineForClassFields: tsConfig.compilerOptions?.useDefineForClassFields,
1724
+ noImplicitThis: tsConfig.compilerOptions?.noImplicitThis,
1725
+ allowSyntheticDefaultImports: tsConfig.compilerOptions?.allowSyntheticDefaultImports
1726
+ },
1727
+ include: [...sharedInclude],
1728
+ exclude: [...sharedExclude]
1729
+ });
1730
+ const aliases = nuxt.options.alias;
1731
+ const basePath = tsConfig.compilerOptions.baseUrl ? resolve(nuxt.options.buildDir, tsConfig.compilerOptions.baseUrl) : nuxt.options.buildDir;
1732
+ tsConfig.compilerOptions ||= {};
1733
+ tsConfig.compilerOptions.paths ||= {};
1734
+ tsConfig.include ||= [];
1735
+ const importPaths = nuxt.options.modulesDir.map((d) => directoryToURL(d));
1736
+ for (const alias in aliases) {
1737
+ if (excludedAlias.some((re) => re.test(alias))) continue;
1738
+ let absolutePath = resolve(basePath, aliases[alias]);
1739
+ let stats = await promises.stat(absolutePath).catch(() => null);
1740
+ if (!stats) {
1741
+ const resolvedModule = resolveModulePath(aliases[alias], {
1742
+ try: true,
1743
+ from: importPaths,
1744
+ extensions: [
1745
+ ...nuxt.options.extensions,
1746
+ ".d.ts",
1747
+ ".d.mts",
1748
+ ".d.cts"
1749
+ ]
1750
+ });
1751
+ if (resolvedModule) {
1752
+ absolutePath = resolvedModule;
1753
+ stats = await promises.stat(resolvedModule).catch(() => null);
1754
+ }
1755
+ }
1756
+ const relativePath = relativeWithDot(nuxt.options.buildDir, absolutePath);
1757
+ if (stats?.isDirectory() || aliases[alias].endsWith("/")) {
1758
+ tsConfig.compilerOptions.paths[alias] = [relativePath];
1759
+ tsConfig.compilerOptions.paths[`${alias}/*`] = [`${relativePath}/*`];
1760
+ } else {
1761
+ const path = stats?.isFile() ? relativePath.replace(EXTENSION_RE, "") : aliases[alias];
1762
+ tsConfig.compilerOptions.paths[alias] = [path];
1763
+ }
1764
+ }
1765
+ const references = [];
1766
+ const nodeReferences = [];
1767
+ const sharedReferences = [];
1768
+ await Promise.all([...nuxt.options.modules, ...nuxt.options._modules].map(async (id) => {
1769
+ if (typeof id !== "string") return;
1770
+ for (const parent of nestedModulesDirs) {
1771
+ const pkg = await readPackageJSON(id, { parent }).catch(() => null);
1772
+ if (pkg) {
1773
+ nodeReferences.push({ types: pkg.name ?? id });
1774
+ references.push({ types: pkg.name ?? id });
1775
+ return;
1776
+ }
1777
+ }
1778
+ nodeReferences.push({ types: id });
1779
+ references.push({ types: id });
1780
+ }));
1781
+ const declarations = [];
1782
+ await nuxt.callHook("prepare:types", {
1783
+ references,
1784
+ declarations,
1785
+ tsConfig,
1786
+ nodeTsConfig,
1787
+ nodeReferences,
1788
+ sharedTsConfig,
1789
+ sharedReferences
1790
+ });
1791
+ const legacyTsConfig = defu({}, {
1792
+ ...tsConfig,
1793
+ include: [...tsConfig.include, ...legacyInclude],
1794
+ exclude: [...legacyExclude]
1795
+ });
1796
+ async function resolveConfig(tsConfig) {
1797
+ for (const alias in tsConfig.compilerOptions.paths) {
1798
+ const paths = tsConfig.compilerOptions.paths[alias];
1799
+ tsConfig.compilerOptions.paths[alias] = [...new Set(await Promise.all(paths.map(async (path) => {
1800
+ 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);
1803
+ })))];
1804
+ }
1805
+ sortTsPaths(tsConfig.compilerOptions.paths);
1806
+ tsConfig.include = [...new Set(tsConfig.include.map((p) => isAbsolute(p) ? relativeWithDot(nuxt.options.buildDir, p) : p))];
1807
+ tsConfig.exclude = [...new Set(tsConfig.exclude.map((p) => isAbsolute(p) ? relativeWithDot(nuxt.options.buildDir, p) : p))];
1808
+ }
1809
+ await Promise.all([
1810
+ resolveConfig(tsConfig),
1811
+ resolveConfig(nodeTsConfig),
1812
+ resolveConfig(sharedTsConfig),
1813
+ resolveConfig(legacyTsConfig)
1814
+ ]);
1815
+ const declaration = [
1816
+ ...references.map((ref) => renderReference(ref, nuxt.options.buildDir)),
1817
+ ...declarations,
1818
+ "",
1819
+ "export {}",
1820
+ ""
1821
+ ].join("\n");
1822
+ const nodeDeclaration = [
1823
+ ...nodeReferences.map((ref) => renderReference(ref, nuxt.options.buildDir)),
1824
+ "",
1825
+ "export {}",
1826
+ ""
1827
+ ].join("\n");
1828
+ return {
1829
+ declaration,
1830
+ sharedTsConfig,
1831
+ sharedDeclaration: [
1832
+ ...sharedReferences.map((ref) => renderReference(ref, nuxt.options.buildDir)),
1833
+ "",
1834
+ "export {}",
1835
+ ""
1836
+ ].join("\n"),
1837
+ nodeTsConfig,
1838
+ nodeDeclaration,
1839
+ tsConfig,
1840
+ legacyTsConfig
1841
+ };
1842
+ }
1843
+ async function writeTypes(nuxt) {
1844
+ const { tsConfig, nodeTsConfig, nodeDeclaration, declaration, legacyTsConfig, sharedDeclaration, sharedTsConfig } = await _generateTypes(nuxt);
1845
+ const appTsConfigPath = resolve(nuxt.options.buildDir, "tsconfig.app.json");
1846
+ const legacyTsConfigPath = resolve(nuxt.options.buildDir, "tsconfig.json");
1847
+ const nodeTsConfigPath = resolve(nuxt.options.buildDir, "tsconfig.node.json");
1848
+ const sharedTsConfigPath = resolve(nuxt.options.buildDir, "tsconfig.shared.json");
1849
+ const declarationPath = resolve(nuxt.options.buildDir, "nuxt.d.ts");
1850
+ const nodeDeclarationPath = resolve(nuxt.options.buildDir, "nuxt.node.d.ts");
1851
+ const sharedDeclarationPath = resolve(nuxt.options.buildDir, "nuxt.shared.d.ts");
1852
+ await promises.mkdir(nuxt.options.buildDir, { recursive: true });
1853
+ await Promise.all([
1854
+ promises.writeFile(appTsConfigPath, JSON.stringify(tsConfig, null, 2)),
1855
+ promises.writeFile(legacyTsConfigPath, JSON.stringify(legacyTsConfig, null, 2)),
1856
+ promises.writeFile(nodeTsConfigPath, JSON.stringify(nodeTsConfig, null, 2)),
1857
+ promises.writeFile(sharedTsConfigPath, JSON.stringify(sharedTsConfig, null, 2)),
1858
+ promises.writeFile(declarationPath, declaration),
1859
+ promises.writeFile(nodeDeclarationPath, nodeDeclaration),
1860
+ promises.writeFile(sharedDeclarationPath, sharedDeclaration)
1861
+ ]);
1862
+ }
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;
1868
+ }
1869
+ }
1870
+ function renderReference(ref, baseDir) {
1871
+ return `/// <reference ${"path" in ref ? `path="${isAbsolute(ref.path) ? relative(baseDir, ref.path) : ref.path}"` : `types="${ref.types}"`} />`;
1872
+ }
1873
+ const RELATIVE_WITH_DOT_RE = /^([^.])/;
1874
+ function relativeWithDot(from, to) {
1875
+ return relative(from, to).replace(RELATIVE_WITH_DOT_RE, "./$1") || ".";
1876
+ }
1877
+ function withTrailingSlash$1(dir) {
1878
+ return dir.replace(/[^/]$/, "$&/");
1879
+ }
1880
+ //#endregion
1881
+ //#region src/layout.ts
1882
+ const LAYOUT_RE = /["']/g;
1883
+ function addLayout(template, name) {
1884
+ const nuxt = useNuxt();
1885
+ const { filename, src } = addTemplate(template);
1886
+ const layoutName = kebabCase(name || parse(filename).name).replace(LAYOUT_RE, "");
1887
+ nuxt.hook("app:templates", (app) => {
1888
+ if (layoutName in app.layouts) {
1889
+ const relativePath = reverseResolveAlias(app.layouts[layoutName].file, {
1890
+ ...nuxt?.options.alias || {},
1891
+ ...strippedAtAliases
1892
+ }).pop() || app.layouts[layoutName].file;
1893
+ return logger.warn(`Not overriding \`${layoutName}\` (provided by \`${relativePath}\`) with \`${src || filename}\`.`);
1894
+ }
1895
+ app.layouts[layoutName] = {
1896
+ file: join("#build", filename),
1897
+ name: layoutName
1898
+ };
1899
+ });
1900
+ }
1901
+ const strippedAtAliases = {
1902
+ "@": "",
1903
+ "@@": ""
1904
+ };
1905
+ //#endregion
1906
+ //#region src/pages.ts
1907
+ function extendPages(cb) {
1908
+ useNuxt().hook("pages:extend", cb);
1909
+ }
1910
+ function extendRouteRules(route, rule, options = {}) {
1911
+ const nuxt = useNuxt();
1912
+ for (const opts of [nuxt.options, nuxt.options.nitro]) {
1913
+ opts.routeRules ||= {};
1914
+ opts.routeRules[route] = options.override ? defu(rule, opts.routeRules[route]) : defu(opts.routeRules[route], rule);
1915
+ }
1916
+ }
1917
+ function addRouteMiddleware(input, options = {}) {
1918
+ const nuxt = useNuxt();
1919
+ const middlewares = toArray(input);
1920
+ nuxt.hook("app:resolve", (app) => {
1921
+ for (const middleware of middlewares) {
1922
+ const find = app.middleware.findIndex((item) => item.name === middleware.name);
1923
+ if (find >= 0) {
1924
+ const foundPath = app.middleware[find].path;
1925
+ if (foundPath === middleware.path) continue;
1926
+ 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.`);
1928
+ } else if (options.prepend === true) app.middleware.unshift({ ...middleware });
1929
+ else app.middleware.push({ ...middleware });
1930
+ }
1931
+ });
1932
+ }
1933
+ //#endregion
1934
+ //#region src/plugin.ts
1935
+ /**
1936
+ * Normalize a nuxt plugin object
1937
+ */
1938
+ const pluginSymbol = Symbol.for("nuxt plugin");
1939
+ function normalizePlugin(plugin) {
1940
+ if (typeof plugin === "string") plugin = { src: plugin };
1941
+ else plugin = { ...plugin };
1942
+ if (pluginSymbol in plugin) return plugin;
1943
+ if (!plugin.src) throw new Error("Invalid plugin. src option is required: " + JSON.stringify(plugin));
1944
+ plugin.src = normalize(resolveAlias(plugin.src));
1945
+ 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
+ ] });
1955
+ } catch {}
1956
+ if (plugin.ssr) plugin.mode = "server";
1957
+ if (!plugin.mode) {
1958
+ const [, mode = "all"] = plugin.src.match(MODE_RE) || [];
1959
+ plugin.mode = mode;
1960
+ }
1961
+ plugin[pluginSymbol] = true;
1962
+ return plugin;
1963
+ }
1964
+ function addPlugin(_plugin, opts = {}) {
1965
+ const nuxt = useNuxt();
1966
+ const plugin = normalizePlugin(_plugin);
1967
+ filterInPlace(nuxt.options.plugins, (p) => normalizePlugin(p).src !== plugin.src);
1968
+ nuxt.options.plugins[opts.append ? "push" : "unshift"](plugin);
1969
+ return plugin;
1970
+ }
1971
+ /**
1972
+ * Adds a template and registers as a nuxt plugin.
1973
+ */
1974
+ function addPluginTemplate(plugin, opts = {}) {
1975
+ return addPlugin(typeof plugin === "string" ? { src: plugin } : {
1976
+ ...plugin,
1977
+ src: addTemplate(plugin).dst
1978
+ }, opts);
1979
+ }
1980
+ //#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 };