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