@nuxt/kit-nightly 4.3.0-29461891.8f4fbecd → 4.3.0-29466366.fa21bb17

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,2011 +1,2002 @@
1
- import { performance } from 'node:perf_hooks';
2
- import { 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, lookupNodeModuleSubpath, resolveModuleExportNames } from 'mlly';
14
- import { resolveModulePath, resolveModuleURL } from 'exsolve';
15
- import { isRelative, withTrailingSlash as withTrailingSlash$2, 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 { 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[/\\]/;
564
- const ignoredConfigKeys = /* @__PURE__ */ new Set(["components", "imports", "pages", "devtools", "telemetry"]);
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
+ */
565
603
  async function installModules(modulesToInstall, resolvedModulePaths, nuxt = useNuxt()) {
566
- const localLayerModuleDirs = [];
567
- for (const l of nuxt.options._layers) {
568
- const srcDir = l.config.srcDir || l.cwd;
569
- if (!NODE_MODULES_RE.test(srcDir)) {
570
- localLayerModuleDirs.push(resolve(srcDir, l.config?.dir?.modules || "modules").replace(/\/?$/, "/"));
571
- }
572
- }
573
- nuxt._moduleOptionsFunctions ||= /* @__PURE__ */ new Map();
574
- const resolvedModules = [];
575
- const inlineConfigKeys = new Set(
576
- await Promise.all([...modulesToInstall].map(([mod]) => typeof mod !== "string" && Promise.resolve(mod.getMeta?.())?.then((r) => r?.configKey)))
577
- );
578
- let error;
579
- const dependencyMap = /* @__PURE__ */ new Map();
580
- for (const [key, options] of modulesToInstall) {
581
- const res = await loadNuxtModuleInstance(key, nuxt).catch((err) => {
582
- if (dependencyMap.has(key) && typeof key === "string") {
583
- err.cause = `Could not resolve \`${key}\` (specified as a dependency of ${dependencyMap.get(key)}).`;
584
- }
585
- throw err;
586
- });
587
- const dependencyMeta = await res.nuxtModule.getModuleDependencies?.(nuxt) || {};
588
- for (const [name, value] of Object.entries(dependencyMeta)) {
589
- if (!value.overrides && !value.defaults && !value.version && value.optional) {
590
- continue;
591
- }
592
- const resolvedModule = resolveModuleWithOptions(name, nuxt);
593
- const moduleToAttribute = typeof key === "string" ? `\`${key}\`` : "a module in `nuxt.options`";
594
- if (!resolvedModule?.module) {
595
- const message = `Could not resolve \`${name}\` (specified as a dependency of ${moduleToAttribute}).`;
596
- error = new TypeError(message);
597
- continue;
598
- }
599
- if (value.version) {
600
- const resolvePaths = [res.resolvedModulePath, ...nuxt.options.modulesDir].filter(Boolean);
601
- const pkg = await readPackageJSON(name, { from: resolvePaths }).catch(() => null);
602
- if (pkg?.version && !semver.satisfies(pkg.version, value.version)) {
603
- const message = `Module \`${name}\` version (\`${pkg.version}\`) does not satisfy \`${value.version}\` (requested by ${moduleToAttribute}).`;
604
- error = new TypeError(message);
605
- }
606
- }
607
- if (value.overrides || value.defaults) {
608
- const currentFns = nuxt._moduleOptionsFunctions.get(resolvedModule.module) || [];
609
- nuxt._moduleOptionsFunctions.set(resolvedModule.module, [
610
- ...currentFns,
611
- () => ({ defaults: value.defaults, overrides: value.overrides })
612
- ]);
613
- }
614
- if (value.optional === true) {
615
- continue;
616
- }
617
- nuxt.options.typescript.hoist.push(name);
618
- if (resolvedModule && !modulesToInstall.has(resolvedModule.module) && (!resolvedModule.resolvedPath || !resolvedModulePaths.has(resolvedModule.resolvedPath))) {
619
- if (typeof resolvedModule.module === "string" && inlineConfigKeys.has(resolvedModule.module)) {
620
- continue;
621
- }
622
- modulesToInstall.set(resolvedModule.module, resolvedModule.options);
623
- dependencyMap.set(resolvedModule.module, moduleToAttribute);
624
- const path = resolvedModule.resolvedPath || resolvedModule.module;
625
- if (typeof path === "string") {
626
- resolvedModulePaths.add(path);
627
- }
628
- }
629
- }
630
- resolvedModules.push({
631
- moduleToInstall: key,
632
- meta: await res.nuxtModule.getMeta?.(),
633
- nuxtModule: res.nuxtModule,
634
- buildTimeModuleMeta: res.buildTimeModuleMeta,
635
- resolvedModulePath: res.resolvedModulePath,
636
- inlineOptions: options
637
- });
638
- }
639
- if (error) {
640
- throw error;
641
- }
642
- for (const { nuxtModule, meta = {}, moduleToInstall, buildTimeModuleMeta, resolvedModulePath, inlineOptions } of resolvedModules) {
643
- const configKey = meta.configKey;
644
- const optionsFns = [
645
- ...nuxt._moduleOptionsFunctions.get(moduleToInstall) || [],
646
- ...meta?.name ? nuxt._moduleOptionsFunctions.get(meta.name) || [] : [],
647
- // TODO: consider dropping options functions keyed by config key
648
- ...configKey ? nuxt._moduleOptionsFunctions.get(configKey) || [] : []
649
- ];
650
- if (optionsFns.length > 0) {
651
- const overrides = [];
652
- const defaults = [];
653
- for (const fn of optionsFns) {
654
- const options = fn();
655
- overrides.push(options.overrides);
656
- defaults.push(options.defaults);
657
- }
658
- if (configKey) {
659
- nuxt.options[configKey] = defu(...overrides, nuxt.options[configKey], ...defaults);
660
- }
661
- }
662
- const isDisabled = configKey && !ignoredConfigKeys.has(configKey) && nuxt.options[configKey] === false;
663
- if (!isDisabled) {
664
- await callLifecycleHooks(nuxtModule, meta, inlineOptions, nuxt);
665
- }
666
- const path = typeof moduleToInstall === "string" ? moduleToInstall : void 0;
667
- await callModule(nuxt, nuxtModule, inlineOptions, {
668
- meta: defu({ disabled: isDisabled }, meta, buildTimeModuleMeta),
669
- nameOrPath: path,
670
- modulePath: resolvedModulePath || path,
671
- localLayerModuleDirs
672
- });
673
- }
674
- delete nuxt._moduleOptionsFunctions;
675
- }
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
+ */
676
696
  async function installModule(moduleToInstall, inlineOptions, nuxt = useNuxt()) {
677
- const { nuxtModule, buildTimeModuleMeta, resolvedModulePath } = await loadNuxtModuleInstance(moduleToInstall, nuxt);
678
- const localLayerModuleDirs = [];
679
- for (const dirs of getLayerDirectories(nuxt)) {
680
- if (!NODE_MODULES_RE.test(dirs.app)) {
681
- localLayerModuleDirs.push(dirs.modules);
682
- }
683
- }
684
- const meta = await nuxtModule.getMeta?.();
685
- let mergedOptions = inlineOptions;
686
- const configKey = meta?.configKey;
687
- if (configKey && nuxt._moduleOptionsFunctions) {
688
- const optionsFns = [
689
- ...nuxt._moduleOptionsFunctions.get(moduleToInstall) || [],
690
- ...nuxt._moduleOptionsFunctions.get(configKey) || []
691
- ];
692
- if (optionsFns.length > 0) {
693
- const overrides = [];
694
- const defaults = [];
695
- for (const fn of optionsFns) {
696
- const options = fn();
697
- overrides.push(options.overrides);
698
- defaults.push(options.defaults);
699
- }
700
- mergedOptions = defu(inlineOptions, ...overrides, nuxt.options[configKey], ...defaults);
701
- nuxt.options[configKey] = mergedOptions;
702
- }
703
- }
704
- const isDisabled = configKey && !ignoredConfigKeys.has(configKey) && nuxt.options[configKey] === false;
705
- if (!isDisabled) {
706
- await callLifecycleHooks(nuxtModule, meta, mergedOptions, nuxt);
707
- }
708
- const path = typeof moduleToInstall === "string" ? moduleToInstall : void 0;
709
- await callModule(nuxt, nuxtModule, mergedOptions, {
710
- meta: defu({ disabled: isDisabled }, meta, buildTimeModuleMeta),
711
- nameOrPath: path,
712
- modulePath: resolvedModulePath || path,
713
- localLayerModuleDirs
714
- });
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
+ });
715
726
  }
716
727
  function resolveModuleWithOptions(definition, nuxt) {
717
- const [module, options = {}] = Array.isArray(definition) ? definition : [definition, {}];
718
- if (!module) {
719
- return;
720
- }
721
- if (typeof module !== "string") {
722
- return {
723
- module,
724
- options
725
- };
726
- }
727
- const modAlias = resolveAlias(module, nuxt.options.alias);
728
- const modPath = resolveModulePath(modAlias, {
729
- try: true,
730
- from: nuxt.options.modulesDir.map((m) => directoryToURL(m.replace(/\/node_modules\/?$/, "/"))),
731
- suffixes: ["nuxt", "nuxt/index", "module", "module/index", "", "index"],
732
- extensions: [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"]
733
- });
734
- return {
735
- module,
736
- resolvedPath: modPath || modAlias,
737
- options
738
- };
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
+ };
739
759
  }
740
760
  async function loadNuxtModuleInstance(nuxtModule, nuxt = useNuxt()) {
741
- let buildTimeModuleMeta = {};
742
- if (typeof nuxtModule === "function") {
743
- return {
744
- nuxtModule,
745
- buildTimeModuleMeta
746
- };
747
- }
748
- if (typeof nuxtModule !== "string") {
749
- throw new TypeError(`Nuxt module should be a function or a string to import. Received: ${nuxtModule}.`);
750
- }
751
- const jiti = createJiti(nuxt.options.rootDir, { alias: nuxt.options.alias });
752
- nuxtModule = resolveAlias(nuxtModule, nuxt.options.alias);
753
- if (isRelative(nuxtModule)) {
754
- nuxtModule = resolve(nuxt.options.rootDir, nuxtModule);
755
- }
756
- try {
757
- const src = resolveModuleURL(nuxtModule, {
758
- from: nuxt.options.modulesDir.map((m) => directoryToURL(m.replace(/\/node_modules\/?$/, "/"))),
759
- suffixes: ["nuxt", "nuxt/index", "module", "module/index", "", "index"],
760
- extensions: [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"]
761
- });
762
- const resolvedModulePath = fileURLToPath(src);
763
- const resolvedNuxtModule = await jiti.import(src, { default: true });
764
- if (typeof resolvedNuxtModule !== "function") {
765
- throw new TypeError(`Nuxt module should be a function: ${nuxtModule}.`);
766
- }
767
- const moduleMetadataPath = new URL("module.json", src);
768
- if (existsSync(moduleMetadataPath)) {
769
- buildTimeModuleMeta = JSON.parse(await promises.readFile(moduleMetadataPath, "utf-8"));
770
- }
771
- return { nuxtModule: resolvedNuxtModule, buildTimeModuleMeta, resolvedModulePath };
772
- } catch (error) {
773
- const code = error.code;
774
- if (code === "ERR_PACKAGE_PATH_NOT_EXPORTED" || code === "ERR_UNSUPPORTED_DIR_IMPORT" || code === "ENOTDIR") {
775
- throw new TypeError(`Could not load \`${nuxtModule}\`. Is it installed?`);
776
- }
777
- if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
778
- const module = MissingModuleMatcher.exec(error.message)?.[1];
779
- if (module && !module.includes(nuxtModule)) {
780
- throw new TypeError(`Error while importing module \`${nuxtModule}\`: ${error}`);
781
- }
782
- }
783
- }
784
- 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?`);
785
809
  }
786
810
  function getDirectory(p) {
787
- try {
788
- return isAbsolute(p) && lstatSync(p).isFile() ? dirname(p) : p;
789
- } catch {
790
- }
791
- return p;
811
+ try {
812
+ return isAbsolute(p) && lstatSync(p).isFile() ? dirname(p) : p;
813
+ } catch {}
814
+ return p;
792
815
  }
793
816
  const normalizeModuleTranspilePath = (p) => {
794
- return getDirectory(p).split("node_modules/").pop();
817
+ return getDirectory(p).split("node_modules/").pop();
795
818
  };
796
819
  const MissingModuleMatcher = /Cannot find module\s+['"]?([^'")\s]+)['"]?/i;
797
820
  async function callLifecycleHooks(nuxtModule, meta = {}, inlineOptions, nuxt = useNuxt()) {
798
- if (!meta.name || !meta.version) {
799
- return;
800
- }
801
- if (!nuxtModule.onInstall && !nuxtModule.onUpgrade) {
802
- return;
803
- }
804
- const rc = read({ dir: nuxt.options.rootDir, name: ".nuxtrc" });
805
- const previousVersion = rc?.setups?.[meta.name];
806
- try {
807
- if (!previousVersion) {
808
- await nuxtModule.onInstall?.(nuxt);
809
- } else if (semver.gt(meta.version, previousVersion)) {
810
- await nuxtModule.onUpgrade?.(nuxt, inlineOptions, previousVersion);
811
- }
812
- if (previousVersion !== meta.version) {
813
- update(
814
- { setups: { [meta.name]: meta?.version } },
815
- { dir: nuxt.options.rootDir, name: ".nuxtrc" }
816
- );
817
- }
818
- } catch (e) {
819
- logger.error(
820
- `Error while executing ${!previousVersion ? "install" : "upgrade"} hook for module \`${meta.name}\`: ${e}`
821
- );
822
- }
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
+ }
823
837
  }
824
838
  async function callModule(nuxt, nuxtModule, moduleOptions = {}, options) {
825
- const modulePath = options.modulePath;
826
- const nameOrPath = options.nameOrPath;
827
- const localLayerModuleDirs = options.localLayerModuleDirs;
828
- const fn = () => nuxt.options.experimental?.debugModuleMutation && nuxt._asyncLocalStorageModule ? nuxt._asyncLocalStorageModule.run(nuxtModule, () => nuxtModule(moduleOptions, nuxt)) : nuxtModule(moduleOptions, nuxt);
829
- const res = options.meta.disabled ? false : await fn();
830
- let entryPath;
831
- if (typeof modulePath === "string") {
832
- const parsed = parseNodeModulePath(modulePath);
833
- if (parsed.name) {
834
- const subpath = await lookupNodeModuleSubpath(modulePath) || ".";
835
- entryPath = join(parsed.name, subpath === "./" ? "." : subpath);
836
- }
837
- if (res !== false) {
838
- const moduleRoot = parsed.dir ? parsed.dir + parsed.name : await resolvePackageJSON(modulePath, { try: true }).then((r) => r ? dirname(r) : modulePath);
839
- nuxt.options.build.transpile.push(normalizeModuleTranspilePath(moduleRoot));
840
- const directory = moduleRoot.replace(/\/?$/, "/");
841
- if (moduleRoot !== nameOrPath && !localLayerModuleDirs.some((dir) => directory.startsWith(dir))) {
842
- nuxt.options.modulesDir.push(join(moduleRoot, "node_modules"));
843
- }
844
- }
845
- }
846
- if (nameOrPath) {
847
- entryPath ||= resolveAlias(nameOrPath, nuxt.options.alias);
848
- if (entryPath !== nameOrPath) {
849
- options.meta.rawPath = nameOrPath;
850
- }
851
- }
852
- nuxt.options._installedModules ||= [];
853
- nuxt.options._installedModules.push({
854
- meta: options.meta,
855
- module: nuxtModule,
856
- timings: (res || {}).timings,
857
- entryPath
858
- });
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
+ });
859
869
  }
860
870
 
871
+ //#endregion
872
+ //#region src/module/compatibility.ts
861
873
  function resolveNuxtModuleEntryName(m) {
862
- if (typeof m === "object" && !Array.isArray(m)) {
863
- return m.name;
864
- }
865
- if (Array.isArray(m)) {
866
- return resolveNuxtModuleEntryName(m[0]);
867
- }
868
- return m || false;
869
- }
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
+ */
870
884
  function hasNuxtModule(moduleName, nuxt = useNuxt()) {
871
- return nuxt.options._installedModules.some(({ meta }) => meta.name === moduleName) || // check modules to be installed
872
- 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));
873
886
  }
887
+ /**
888
+ * Checks if a Nuxt module is compatible with a given semver version.
889
+ */
874
890
  async function hasNuxtModuleCompatibility(module, semverVersion, nuxt = useNuxt()) {
875
- const version = await getNuxtModuleVersion(module, nuxt);
876
- if (!version) {
877
- return false;
878
- }
879
- return satisfies(normalizeSemanticVersion(version), semverVersion, {
880
- includePrerelease: true
881
- });
882
- }
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
+ */
883
900
  async function getNuxtModuleVersion(module, nuxt = useNuxt()) {
884
- const moduleMeta = (typeof module === "string" ? { name: module } : await module.getMeta?.()) || {};
885
- if (moduleMeta.version) {
886
- return moduleMeta.version;
887
- }
888
- if (!moduleMeta.name) {
889
- return false;
890
- }
891
- for (const m of nuxt.options._installedModules) {
892
- if (m.meta.name === moduleMeta.name && m.meta.version) {
893
- return m.meta.version;
894
- }
895
- }
896
- if (hasNuxtModule(moduleMeta.name)) {
897
- const { nuxtModule, buildTimeModuleMeta } = await loadNuxtModuleInstance(moduleMeta.name, nuxt);
898
- return buildTimeModuleMeta.version || await nuxtModule.getMeta?.().then((r) => r.version) || false;
899
- }
900
- 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;
901
910
  }
902
911
 
912
+ //#endregion
913
+ //#region src/loader/config.ts
903
914
  const merger = createDefu((obj, key, value) => {
904
- if (Array.isArray(obj[key]) && Array.isArray(value)) {
905
- obj[key] = obj[key].concat(value);
906
- return true;
907
- }
915
+ if (Array.isArray(obj[key]) && Array.isArray(value)) {
916
+ obj[key] = obj[key].concat(value);
917
+ return true;
918
+ }
908
919
  });
909
920
  async function loadNuxtConfig(opts) {
910
- const localLayers = (await glob("layers/*", {
911
- onlyDirectories: true,
912
- cwd: opts.cwd || process.cwd()
913
- })).map((d) => withTrailingSlash$2(d)).sort((a, b) => b.localeCompare(a));
914
- opts.overrides = defu(opts.overrides, { _extends: localLayers });
915
- const { configFile, layers = [], cwd, config: nuxtConfig, meta } = await withDefineNuxtConfig(
916
- () => loadConfig({
917
- name: "nuxt",
918
- configFile: "nuxt.config",
919
- rcFile: ".nuxtrc",
920
- extend: { extendKey: ["theme", "_extends", "extends"] },
921
- dotenv: true,
922
- globalRc: true,
923
- // @ts-expect-error TODO: fix type in c12, it should accept createDefu directly
924
- merger,
925
- ...opts
926
- })
927
- );
928
- nuxtConfig.rootDir ||= cwd;
929
- nuxtConfig._nuxtConfigFile = configFile;
930
- nuxtConfig._nuxtConfigFiles = [configFile];
931
- nuxtConfig._loadOptions = opts;
932
- nuxtConfig.alias ||= {};
933
- if (meta?.name) {
934
- const alias = `#layers/${meta.name}`;
935
- nuxtConfig.alias[alias] ||= withTrailingSlash$2(nuxtConfig.rootDir);
936
- }
937
- const defaultBuildDir = join(nuxtConfig.rootDir, ".nuxt");
938
- if (!opts.overrides?._prepare && !nuxtConfig.dev && !nuxtConfig.buildDir && existsSync(defaultBuildDir)) {
939
- nuxtConfig.buildDir = join(nuxtConfig.rootDir, "node_modules/.cache/nuxt/.nuxt");
940
- }
941
- const NuxtConfigSchema = await loadNuxtSchema(nuxtConfig.rootDir || cwd || process.cwd());
942
- const layerSchemaKeys = ["future", "srcDir", "rootDir", "serverDir", "dir"];
943
- const layerSchema = /* @__PURE__ */ Object.create(null);
944
- for (const key of layerSchemaKeys) {
945
- if (key in NuxtConfigSchema) {
946
- layerSchema[key] = NuxtConfigSchema[key];
947
- }
948
- }
949
- const _layers = [];
950
- const processedLayers = /* @__PURE__ */ new Set();
951
- const localRelativePaths = new Set(localLayers.map((layer) => withoutTrailingSlash(layer)));
952
- for (const layer of layers) {
953
- const resolvedRootDir = layer.config?.rootDir ?? layer.cwd;
954
- layer.config = {
955
- ...layer.config || {},
956
- rootDir: resolvedRootDir
957
- };
958
- if (processedLayers.has(resolvedRootDir)) {
959
- continue;
960
- }
961
- processedLayers.add(resolvedRootDir);
962
- layer.config = await applyDefaults(layerSchema, layer.config);
963
- if (!layer.configFile || layer.configFile.endsWith(".nuxtrc")) {
964
- continue;
965
- }
966
- if (layer.cwd && cwd && localRelativePaths.has(relative(cwd, layer.cwd))) {
967
- layer.meta ||= {};
968
- layer.meta.name ||= basename(layer.cwd);
969
- }
970
- if (layer.meta?.name) {
971
- const alias = `#layers/${layer.meta.name}`;
972
- nuxtConfig.alias[alias] ||= withTrailingSlash$2(layer.config.rootDir || layer.cwd);
973
- }
974
- _layers.push(layer);
975
- }
976
- nuxtConfig._layers = _layers;
977
- if (!_layers.length) {
978
- _layers.push({
979
- cwd,
980
- config: {
981
- rootDir: cwd,
982
- srcDir: cwd
983
- }
984
- });
985
- }
986
- 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);
987
993
  }
988
994
  async function loadNuxtSchema(cwd) {
989
- const url = directoryToURL(cwd);
990
- const urls = [url];
991
- const nuxtPath = resolveModuleURL("nuxt", { try: true, from: url }) ?? resolveModuleURL("nuxt-nightly", { try: true, from: url });
992
- if (nuxtPath) {
993
- urls.unshift(nuxtPath);
994
- }
995
- const schemaPath = resolveModuleURL("@nuxt/schema", { try: true, from: urls }) ?? "@nuxt/schema";
996
- 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);
997
1009
  }
998
1010
  async function withDefineNuxtConfig(fn) {
999
- const key = "defineNuxtConfig";
1000
- const globalSelf = globalThis;
1001
- if (!globalSelf[key]) {
1002
- globalSelf[key] = (c) => c;
1003
- globalSelf[key].count = 0;
1004
- }
1005
- globalSelf[key].count++;
1006
- try {
1007
- return await fn();
1008
- } finally {
1009
- globalSelf[key].count--;
1010
- if (!globalSelf[key].count) {
1011
- delete globalSelf[key];
1012
- }
1013
- }
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
+ }
1014
1024
  }
1015
1025
 
1026
+ //#endregion
1027
+ //#region src/loader/schema.ts
1016
1028
  function extendNuxtSchema(def) {
1017
- const nuxt = useNuxt();
1018
- nuxt.hook("schema:extend", (schemas) => {
1019
- schemas.push(typeof def === "function" ? def() : def);
1020
- });
1029
+ useNuxt().hook("schema:extend", (schemas) => {
1030
+ schemas.push(typeof def === "function" ? def() : def);
1031
+ });
1021
1032
  }
1022
1033
 
1034
+ //#endregion
1035
+ //#region src/loader/nuxt.ts
1023
1036
  async function loadNuxt(opts) {
1024
- opts.cwd = resolve(opts.cwd || opts.rootDir || ".");
1025
- opts.overrides ||= opts.config || {};
1026
- opts.overrides.dev = !!opts.dev;
1027
- const resolvedPath = ["nuxt-nightly", "nuxt"].reduce((resolvedPath2, pkg) => {
1028
- const path = resolveModulePath(pkg, { try: true, from: [directoryToURL(opts.cwd)] });
1029
- return path && path.length > resolvedPath2.length ? path : resolvedPath2;
1030
- }, "");
1031
- if (!resolvedPath) {
1032
- throw new Error(`Cannot find any nuxt version from ${opts.cwd}`);
1033
- }
1034
- const { loadNuxt: loadNuxt2 } = await import(pathToFileURL(resolvedPath).href).then((r) => interopDefault(r));
1035
- const nuxt = await loadNuxt2(opts);
1036
- 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);
1037
1050
  }
1038
1051
  async function buildNuxt(nuxt) {
1039
- const rootURL = directoryToURL(nuxt.options.rootDir);
1040
- const { build } = await tryImportModule("nuxt-nightly", { url: rootURL }) || await importModule("nuxt", { url: rootURL });
1041
- 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));
1042
1055
  }
1043
1056
 
1057
+ //#endregion
1058
+ //#region src/head.ts
1044
1059
  function setGlobalHead(head) {
1045
- const nuxt = useNuxt();
1046
- 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);
1047
1062
  }
1048
1063
 
1064
+ //#endregion
1065
+ //#region src/imports.ts
1049
1066
  function addImports(imports) {
1050
- useNuxt().hook("imports:extend", (_imports) => {
1051
- _imports.push(...toArray(imports));
1052
- });
1067
+ useNuxt().hook("imports:extend", (_imports) => {
1068
+ _imports.push(...toArray(imports));
1069
+ });
1053
1070
  }
1054
1071
  function addImportsDir(dirs, opts = {}) {
1055
- useNuxt().hook("imports:dirs", (_dirs) => {
1056
- for (const dir of toArray(dirs)) {
1057
- _dirs[opts.prepend ? "unshift" : "push"](dir);
1058
- }
1059
- });
1072
+ useNuxt().hook("imports:dirs", (_dirs) => {
1073
+ for (const dir of toArray(dirs)) _dirs[opts.prepend ? "unshift" : "push"](dir);
1074
+ });
1060
1075
  }
1061
1076
  function addImportsSources(presets) {
1062
- useNuxt().hook("imports:sources", (_presets) => {
1063
- for (const preset of toArray(presets)) {
1064
- _presets.push(preset);
1065
- }
1066
- });
1077
+ useNuxt().hook("imports:sources", (_presets) => {
1078
+ for (const preset of toArray(presets)) _presets.push(preset);
1079
+ });
1067
1080
  }
1068
1081
 
1082
+ //#endregion
1083
+ //#region src/nitro.ts
1069
1084
  const HANDLER_METHOD_RE = /\.(get|head|patch|post|put|delete|connect|options|trace)(\.\w+)*$/;
1085
+ /**
1086
+ * normalize handler object
1087
+ *
1088
+ */
1070
1089
  function normalizeHandlerMethod(handler) {
1071
- const [, method = void 0] = handler.handler.match(HANDLER_METHOD_RE) || [];
1072
- return {
1073
- method: method?.toUpperCase(),
1074
- ...handler,
1075
- handler: normalize(handler.handler)
1076
- };
1077
- }
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
+ */
1078
1101
  function addServerHandler(handler) {
1079
- useNuxt().options.serverHandlers.push(normalizeHandlerMethod(handler));
1102
+ useNuxt().options.serverHandlers.push(normalizeHandlerMethod(handler));
1080
1103
  }
1104
+ /**
1105
+ * Adds a nitro server handler for development-only
1106
+ *
1107
+ */
1081
1108
  function addDevServerHandler(handler) {
1082
- useNuxt().options.devServerHandlers.push(handler);
1109
+ useNuxt().options.devServerHandlers.push(handler);
1083
1110
  }
1111
+ /**
1112
+ * Adds a Nitro plugin
1113
+ */
1084
1114
  function addServerPlugin(plugin) {
1085
- const nuxt = useNuxt();
1086
- nuxt.options.nitro.plugins ||= [];
1087
- nuxt.options.nitro.plugins.push(normalize(plugin));
1115
+ const nuxt = useNuxt();
1116
+ nuxt.options.nitro.plugins ||= [];
1117
+ nuxt.options.nitro.plugins.push(normalize(plugin));
1088
1118
  }
1119
+ /**
1120
+ * Adds routes to be prerendered
1121
+ */
1089
1122
  function addPrerenderRoutes(routes) {
1090
- const nuxt = useNuxt();
1091
- routes = toArray(routes).filter(Boolean);
1092
- if (!routes.length) {
1093
- return;
1094
- }
1095
- nuxt.hook("prerender:routes", (ctx) => {
1096
- for (const route of routes) {
1097
- ctx.routes.add(route);
1098
- }
1099
- });
1100
- }
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
+ */
1101
1144
  function useNitro() {
1102
- const nuxt = useNuxt();
1103
- if (!nuxt._nitro) {
1104
- throw new Error("Nitro is not initialized yet. You can call `useNitro()` only after `ready` hook.");
1105
- }
1106
- 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;
1107
1148
  }
1149
+ /**
1150
+ * Add server imports to be auto-imported by Nitro
1151
+ */
1108
1152
  function addServerImports(imports) {
1109
- const nuxt = useNuxt();
1110
- const _imports = toArray(imports);
1111
- nuxt.hook("nitro:config", (config) => {
1112
- config.imports ||= {};
1113
- config.imports.imports ||= [];
1114
- config.imports.imports.push(..._imports);
1115
- });
1116
- }
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
+ */
1117
1164
  function addServerImportsDir(dirs, opts = {}) {
1118
- const nuxt = useNuxt();
1119
- const _dirs = toArray(dirs);
1120
- nuxt.hook("nitro:config", (config) => {
1121
- config.imports ||= {};
1122
- config.imports.dirs ||= [];
1123
- config.imports.dirs[opts.prepend ? "unshift" : "push"](..._dirs);
1124
- });
1125
- }
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
+ */
1126
1177
  function addServerScanDir(dirs, opts = {}) {
1127
- const nuxt = useNuxt();
1128
- nuxt.hook("nitro:config", (config) => {
1129
- config.scanDirs ||= [];
1130
- for (const dir of toArray(dirs)) {
1131
- config.scanDirs[opts.prepend ? "unshift" : "push"](dir);
1132
- }
1133
- });
1178
+ useNuxt().hook("nitro:config", (config) => {
1179
+ config.scanDirs ||= [];
1180
+ for (const dir of toArray(dirs)) config.scanDirs[opts.prepend ? "unshift" : "push"](dir);
1181
+ });
1134
1182
  }
1135
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
+ */
1136
1191
  function useRuntimeConfig() {
1137
- const nuxt = useNuxt();
1138
- return applyEnv(klona(nuxt.options.nitro.runtimeConfig), {
1139
- prefix: "NITRO_",
1140
- altPrefix: "NUXT_",
1141
- envExpansion: nuxt.options.nitro.experimental?.envExpansion ?? !!process.env.NITRO_ENV_EXPANSION
1142
- });
1143
- }
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
+ */
1144
1202
  function updateRuntimeConfig(runtimeConfig) {
1145
- const nuxt = useNuxt();
1146
- Object.assign(nuxt.options.nitro.runtimeConfig, defu(runtimeConfig, nuxt.options.nitro.runtimeConfig));
1147
- try {
1148
- return useNitro().updateConfig({ runtimeConfig });
1149
- } catch {
1150
- }
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 {}
1151
1208
  }
1152
1209
  function getEnv(key, opts, env = process.env) {
1153
- const envKey = snakeCase(key).toUpperCase();
1154
- return destr(
1155
- env[opts.prefix + envKey] ?? env[opts.altPrefix + envKey]
1156
- );
1210
+ const envKey = snakeCase(key).toUpperCase();
1211
+ return destr(env[opts.prefix + envKey] ?? env[opts.altPrefix + envKey]);
1157
1212
  }
1158
1213
  function _isObject(input) {
1159
- return typeof input === "object" && !Array.isArray(input);
1214
+ return typeof input === "object" && !Array.isArray(input);
1160
1215
  }
1161
1216
  function applyEnv(obj, opts, parentKey = "") {
1162
- for (const key in obj) {
1163
- const subKey = parentKey ? `${parentKey}_${key}` : key;
1164
- const envValue = getEnv(subKey, opts);
1165
- if (_isObject(obj[key])) {
1166
- if (_isObject(envValue)) {
1167
- obj[key] = { ...obj[key], ...envValue };
1168
- applyEnv(obj[key], opts, subKey);
1169
- } else if (envValue === void 0) {
1170
- applyEnv(obj[key], opts, subKey);
1171
- } else {
1172
- obj[key] = envValue ?? obj[key];
1173
- }
1174
- } else {
1175
- obj[key] = envValue ?? obj[key];
1176
- }
1177
- if (opts.envExpansion && typeof obj[key] === "string") {
1178
- obj[key] = _expandFromEnv(obj[key]);
1179
- }
1180
- }
1181
- 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;
1182
1232
  }
1183
1233
  const envExpandRx = /\{\{([^{}]*)\}\}/g;
1184
1234
  function _expandFromEnv(value, env = process.env) {
1185
- return value.replace(envExpandRx, (match, key) => {
1186
- return env[key] || match;
1187
- });
1235
+ return value.replace(envExpandRx, (match, key) => {
1236
+ return env[key] || match;
1237
+ });
1188
1238
  }
1189
1239
 
1240
+ //#endregion
1241
+ //#region src/build.ts
1190
1242
  const extendWebpackCompatibleConfig = (builder) => (fn, options = {}) => {
1191
- const nuxt = useNuxt();
1192
- if (options.dev === false && nuxt.options.dev) {
1193
- return;
1194
- }
1195
- if (options.build === false && nuxt.options.build) {
1196
- return;
1197
- }
1198
- nuxt.hook(`${builder}:config`, async (configs) => {
1199
- if (options.server !== false) {
1200
- const config = configs.find((i) => i.name === "server");
1201
- if (config) {
1202
- await fn(config);
1203
- }
1204
- }
1205
- if (options.client !== false) {
1206
- const config = configs.find((i) => i.name === "client");
1207
- if (config) {
1208
- await fn(config);
1209
- }
1210
- }
1211
- });
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
+ });
1212
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
+ */
1213
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
+ */
1214
1270
  const extendRspackConfig = extendWebpackCompatibleConfig("rspack");
1271
+ /**
1272
+ * Extend Vite config
1273
+ */
1215
1274
  function extendViteConfig(fn, options = {}) {
1216
- const nuxt = useNuxt();
1217
- if (options.dev === false && nuxt.options.dev) {
1218
- return;
1219
- }
1220
- if (options.build === false && nuxt.options.build) {
1221
- return;
1222
- }
1223
- if (options.server === false || options.client === false) {
1224
- const caller = getUserCaller();
1225
- const explanation = caller ? ` (used at \`${resolveAlias(caller.source)}:${caller.line}:${caller.column}\`)` : "";
1226
- 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.`;
1227
- warn(warning);
1228
- }
1229
- return nuxt.hook("vite:extend", ({ config }) => fn(config));
1230
- }
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
+ */
1231
1287
  function addWebpackPlugin(pluginOrGetter, options) {
1232
- extendWebpackConfig(async (config) => {
1233
- const method = options?.prepend ? "unshift" : "push";
1234
- const plugin = typeof pluginOrGetter === "function" ? await pluginOrGetter() : pluginOrGetter;
1235
- config.plugins ||= [];
1236
- config.plugins[method](...toArray(plugin));
1237
- }, options);
1238
- }
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
+ */
1239
1298
  function addRspackPlugin(pluginOrGetter, options) {
1240
- extendRspackConfig(async (config) => {
1241
- const method = options?.prepend ? "unshift" : "push";
1242
- const plugin = typeof pluginOrGetter === "function" ? await pluginOrGetter() : pluginOrGetter;
1243
- config.plugins ||= [];
1244
- config.plugins[method](...toArray(plugin));
1245
- }, options);
1246
- }
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
+ */
1247
1309
  function addVitePlugin(pluginOrGetter, options = {}) {
1248
- const nuxt = useNuxt();
1249
- if (options.dev === false && nuxt.options.dev) {
1250
- return;
1251
- }
1252
- if (options.build === false && nuxt.options.build) {
1253
- return;
1254
- }
1255
- let needsEnvInjection = false;
1256
- nuxt.hook("vite:extend", async ({ config }) => {
1257
- config.plugins ||= [];
1258
- const plugin = toArray(typeof pluginOrGetter === "function" ? await pluginOrGetter() : pluginOrGetter);
1259
- if (options.server !== false && options.client !== false) {
1260
- const method = options?.prepend ? "unshift" : "push";
1261
- config.plugins[method](...plugin);
1262
- return;
1263
- }
1264
- if (!config.environments?.ssr || !config.environments.client) {
1265
- needsEnvInjection = true;
1266
- return;
1267
- }
1268
- const environmentName = options.server === false ? "client" : "ssr";
1269
- const pluginName = plugin.map((p) => p.name).join("|");
1270
- config.plugins.push({
1271
- name: `${pluginName}:wrapper`,
1272
- enforce: options?.prepend ? "pre" : "post",
1273
- applyToEnvironment(environment) {
1274
- if (environment.name === environmentName) {
1275
- return plugin;
1276
- }
1277
- }
1278
- });
1279
- });
1280
- nuxt.hook("vite:extendConfig", async (config, env) => {
1281
- if (!needsEnvInjection) {
1282
- return;
1283
- }
1284
- const plugin = toArray(typeof pluginOrGetter === "function" ? await pluginOrGetter() : pluginOrGetter);
1285
- const method = options?.prepend ? "unshift" : "push";
1286
- if (env.isClient && options.server === false) {
1287
- config.plugins[method](...plugin);
1288
- }
1289
- if (env.isServer && options.client === false) {
1290
- config.plugins[method](...plugin);
1291
- }
1292
- });
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
+ });
1293
1343
  }
1294
1344
  function addBuildPlugin(pluginFactory, options) {
1295
- if (pluginFactory.vite) {
1296
- addVitePlugin(pluginFactory.vite, options);
1297
- }
1298
- if (pluginFactory.webpack) {
1299
- addWebpackPlugin(pluginFactory.webpack, options);
1300
- }
1301
- if (pluginFactory.rspack) {
1302
- addRspackPlugin(pluginFactory.rspack, options);
1303
- }
1345
+ if (pluginFactory.vite) addVitePlugin(pluginFactory.vite, options);
1346
+ if (pluginFactory.webpack) addWebpackPlugin(pluginFactory.webpack, options);
1347
+ if (pluginFactory.rspack) addRspackPlugin(pluginFactory.rspack, options);
1304
1348
  }
1305
1349
 
1350
+ //#endregion
1351
+ //#region src/components.ts
1352
+ /**
1353
+ * Register a directory to be scanned for components and imported only when used.
1354
+ */
1306
1355
  function addComponentsDir(dir, opts = {}) {
1307
- const nuxt = useNuxt();
1308
- nuxt.options.components ||= [];
1309
- dir.priority ||= 0;
1310
- nuxt.hook("components:dirs", (dirs) => {
1311
- dirs[opts.prepend ? "unshift" : "push"](dir);
1312
- });
1313
- }
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
+ */
1314
1366
  function addComponentExports(opts) {
1315
- const nuxt = useNuxt();
1316
- const components = [];
1317
- nuxt.hook("components:dirs", async () => {
1318
- const filePath = await resolvePath(opts.filePath);
1319
- const names = await resolveModuleExportNames(filePath, { extensions: nuxt.options.extensions });
1320
- components.length = 0;
1321
- for (const name of names) {
1322
- components.push(normalizeComponent({ name: pascalCase([opts.prefix || "", name === "default" ? "" : name]), export: name, ...opts }));
1323
- }
1324
- });
1325
- addComponents(components);
1326
- }
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
+ */
1327
1383
  function addComponent(opts) {
1328
- const component = normalizeComponent(opts);
1329
- addComponents([component]);
1384
+ addComponents([normalizeComponent(opts)]);
1330
1385
  }
1331
1386
  function addComponents(addedComponents) {
1332
- const nuxt = useNuxt();
1333
- nuxt.options.components ||= [];
1334
- nuxt.hook("components:extend", (components) => {
1335
- for (const component of addedComponents) {
1336
- const existingComponentIndex = components.findIndex((c) => (c.pascalName === component.pascalName || c.kebabName === component.kebabName) && c.mode === component.mode);
1337
- if (existingComponentIndex !== -1) {
1338
- const existingComponent = components[existingComponentIndex];
1339
- const existingPriority = existingComponent.priority ?? 0;
1340
- const newPriority = component.priority ?? 0;
1341
- if (newPriority < existingPriority) {
1342
- continue;
1343
- }
1344
- if (newPriority === existingPriority) {
1345
- const name = existingComponent.pascalName || existingComponent.kebabName;
1346
- logger.warn(`Overriding ${name} component. You can specify a \`priority\` option when calling \`addComponent\` to avoid this warning.`);
1347
- }
1348
- components.splice(existingComponentIndex, 1, component);
1349
- } else {
1350
- components.push(component);
1351
- }
1352
- }
1353
- });
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
+ });
1354
1405
  }
1355
1406
  function normalizeComponent(opts) {
1356
- if (!opts.mode) {
1357
- const [, mode = "all"] = opts.filePath.match(MODE_RE) || [];
1358
- opts.mode = mode;
1359
- }
1360
- const component = {
1361
- export: opts.export || "default",
1362
- chunkName: "components/" + kebabCase(opts.name),
1363
- global: opts.global ?? false,
1364
- kebabName: kebabCase(opts.name || ""),
1365
- pascalName: pascalCase(opts.name || ""),
1366
- prefetch: false,
1367
- preload: false,
1368
- mode: "all",
1369
- shortPath: opts.filePath,
1370
- priority: 0,
1371
- meta: {},
1372
- ...opts
1373
- };
1374
- 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
+ };
1375
1425
  }
1376
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
+ */
1377
1432
  function addTemplate(_template) {
1378
- const nuxt = useNuxt();
1379
- const template = normalizeTemplate(_template);
1380
- filterInPlace(nuxt.options.build.templates, (p) => (p.dst || normalizeTemplate(p).dst) !== template.dst);
1381
- try {
1382
- const distDir = distDirURL.toString();
1383
- const { source } = captureStackTrace().find((e) => e.source && !e.source.startsWith(distDir)) ?? {};
1384
- if (source) {
1385
- const path = normalize(fileURLToPath(source));
1386
- if (existsSync(path)) {
1387
- template._path = path;
1388
- }
1389
- }
1390
- } catch {
1391
- }
1392
- nuxt.options.build.templates.push(template);
1393
- return template;
1394
- }
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
+ */
1395
1450
  function addServerTemplate(template) {
1396
- const nuxt = useNuxt();
1397
- nuxt.options.nitro.virtual ||= {};
1398
- nuxt.options.nitro.virtual[template.filename] = template.getContents;
1399
- return template;
1400
- }
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
+ */
1401
1464
  function addTypeTemplate(_template, context) {
1402
- const nuxt = useNuxt();
1403
- const template = addTemplate(_template);
1404
- if (!template.filename.endsWith(".d.ts")) {
1405
- throw new Error(`Invalid type template. Filename must end with .d.ts : "${template.filename}"`);
1406
- }
1407
- if (!context || context.nuxt) {
1408
- nuxt.hook("prepare:types", (payload) => {
1409
- payload.references ||= [];
1410
- payload.references.push({ path: template.dst });
1411
- });
1412
- }
1413
- if (context?.node) {
1414
- nuxt.hook("prepare:types", (payload) => {
1415
- payload.nodeReferences ||= [];
1416
- payload.nodeReferences.push({ path: template.dst });
1417
- });
1418
- }
1419
- if (context?.shared) {
1420
- nuxt.hook("prepare:types", (payload) => {
1421
- payload.sharedReferences ||= [];
1422
- payload.sharedReferences.push({ path: template.dst });
1423
- });
1424
- }
1425
- if (!context || context.nuxt || context.shared) {
1426
- nuxt.options.vite.vue = defu(nuxt.options.vite.vue, {
1427
- script: {
1428
- globalTypeFiles: [template.dst]
1429
- }
1430
- });
1431
- }
1432
- if (context?.nitro) {
1433
- nuxt.hook("nitro:prepare:types", (payload) => {
1434
- payload.references ||= [];
1435
- payload.references.push({ path: template.dst });
1436
- });
1437
- }
1438
- return template;
1439
- }
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
+ */
1440
1490
  function normalizeTemplate(template, buildDir) {
1441
- if (!template) {
1442
- throw new Error("Invalid template: " + JSON.stringify(template));
1443
- }
1444
- if (typeof template === "string") {
1445
- template = { src: template };
1446
- } else {
1447
- template = { ...template };
1448
- }
1449
- if (template.src) {
1450
- if (!existsSync(template.src)) {
1451
- throw new Error("Template not found: " + template.src);
1452
- }
1453
- if (!template.filename) {
1454
- const srcPath = parse(template.src);
1455
- template.filename = template.fileName || `${basename(srcPath.dir)}.${srcPath.name}.${hash(template.src).replace(/-/g, "_")}${srcPath.ext}`;
1456
- }
1457
- }
1458
- if (!template.src && !template.getContents) {
1459
- throw new Error("Invalid template. Either `getContents` or `src` should be provided: " + JSON.stringify(template));
1460
- }
1461
- if (!template.filename) {
1462
- throw new Error("Invalid template. `filename` must be provided: " + JSON.stringify(template));
1463
- }
1464
- if (template.filename.endsWith(".d.ts")) {
1465
- template.write = true;
1466
- }
1467
- template.dst ||= resolve(buildDir ?? useNuxt().options.buildDir, template.filename);
1468
- return template;
1469
- }
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
+ */
1470
1512
  async function updateTemplates(options) {
1471
- return await tryUseNuxt()?.hooks.callHook("builder:generateApp", options);
1513
+ return await tryUseNuxt()?.hooks.callHook("builder:generateApp", options);
1472
1514
  }
1473
1515
  function resolveLayerPaths(dirs, projectBuildDir) {
1474
- const relativeRootDir = relativeWithDot(projectBuildDir, dirs.root);
1475
- const relativeSrcDir = relativeWithDot(projectBuildDir, dirs.app);
1476
- const relativeModulesDir = relativeWithDot(projectBuildDir, dirs.modules);
1477
- const relativeSharedDir = relativeWithDot(projectBuildDir, dirs.shared);
1478
- return {
1479
- nuxt: [
1480
- join(relativeSrcDir, "**/*"),
1481
- join(relativeModulesDir, `*/runtime/**/*`),
1482
- join(relativeRootDir, `test/nuxt/**/*`),
1483
- join(relativeRootDir, `tests/nuxt/**/*`),
1484
- join(relativeRootDir, `layers/*/app/**/*`),
1485
- join(relativeRootDir, `layers/*/modules/*/runtime/**/*`)
1486
- ],
1487
- nitro: [
1488
- join(relativeModulesDir, `*/runtime/server/**/*`),
1489
- join(relativeRootDir, `layers/*/server/**/*`),
1490
- join(relativeRootDir, `layers/*/modules/*/runtime/server/**/*`)
1491
- ],
1492
- node: [
1493
- join(relativeModulesDir, `*.*`),
1494
- join(relativeRootDir, `nuxt.config.*`),
1495
- join(relativeRootDir, `.config/nuxt.*`),
1496
- join(relativeRootDir, `layers/*/nuxt.config.*`),
1497
- join(relativeRootDir, `layers/*/.config/nuxt.*`),
1498
- join(relativeRootDir, `layers/*/modules/**/*`)
1499
- ],
1500
- shared: [
1501
- join(relativeSharedDir, `**/*`),
1502
- join(relativeModulesDir, `*/shared/**/*`),
1503
- join(relativeRootDir, `layers/*/shared/**/*`)
1504
- ],
1505
- sharedDeclarations: [
1506
- join(relativeSharedDir, `**/*.d.ts`),
1507
- join(relativeModulesDir, `*/shared/**/*.d.ts`),
1508
- join(relativeRootDir, `layers/*/shared/**/*.d.ts`)
1509
- ],
1510
- globalDeclarations: [
1511
- join(relativeRootDir, `*.d.ts`),
1512
- join(relativeRootDir, `layers/*/*.d.ts`)
1513
- ]
1514
- };
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
+ };
1515
1554
  }
1516
1555
  const EXTENSION_RE = /\b(?:\.d\.[cm]?ts|\.\w+)$/g;
1517
1556
  const excludedAlias = [/^@vue\/.*$/, /^#internal\/nuxt/];
1518
1557
  async function _generateTypes(nuxt) {
1519
- const include = /* @__PURE__ */ new Set(["./nuxt.d.ts"]);
1520
- const nodeInclude = /* @__PURE__ */ new Set(["./nuxt.node.d.ts"]);
1521
- const sharedInclude = /* @__PURE__ */ new Set(["./nuxt.shared.d.ts"]);
1522
- const legacyInclude = /* @__PURE__ */ new Set([...include, ...nodeInclude]);
1523
- const exclude = /* @__PURE__ */ new Set();
1524
- const nodeExclude = /* @__PURE__ */ new Set();
1525
- const sharedExclude = /* @__PURE__ */ new Set();
1526
- const legacyExclude = /* @__PURE__ */ new Set();
1527
- if (nuxt.options.typescript.includeWorkspace && nuxt.options.workspaceDir !== nuxt.options.srcDir) {
1528
- include.add(join(relative(nuxt.options.buildDir, nuxt.options.workspaceDir), "**/*"));
1529
- legacyInclude.add(join(relative(nuxt.options.buildDir, nuxt.options.workspaceDir), "**/*"));
1530
- }
1531
- const layerDirs = getLayerDirectories(nuxt);
1532
- const sourceDirs = layerDirs.map((layer) => layer.app);
1533
- for (const dir of nuxt.options.modulesDir) {
1534
- if (!sourceDirs.some((srcDir) => dir.startsWith(srcDir))) {
1535
- exclude.add(relativeWithDot(nuxt.options.buildDir, dir));
1536
- }
1537
- nodeExclude.add(relativeWithDot(nuxt.options.buildDir, dir));
1538
- legacyExclude.add(relativeWithDot(nuxt.options.buildDir, dir));
1539
- }
1540
- for (const dir of ["dist", ".data"]) {
1541
- exclude.add(relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, dir)));
1542
- nodeExclude.add(relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, dir)));
1543
- legacyExclude.add(relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, dir)));
1544
- }
1545
- const rootDirWithSlash = withTrailingSlash(nuxt.options.rootDir);
1546
- for (const dirs of layerDirs) {
1547
- if (!dirs.app.startsWith(rootDirWithSlash) || dirs.root === rootDirWithSlash || dirs.app.includes("node_modules")) {
1548
- const rootGlob = join(relativeWithDot(nuxt.options.buildDir, dirs.root), "**/*");
1549
- const paths = resolveLayerPaths(dirs, nuxt.options.buildDir);
1550
- for (const path of paths.nuxt) {
1551
- include.add(path);
1552
- legacyInclude.add(path);
1553
- if (path !== rootGlob) {
1554
- nodeExclude.add(path);
1555
- }
1556
- }
1557
- for (const path of paths.nitro) {
1558
- exclude.add(path);
1559
- nodeExclude.add(path);
1560
- legacyExclude.add(path);
1561
- }
1562
- for (const path of paths.node) {
1563
- nodeInclude.add(path);
1564
- legacyInclude.add(path);
1565
- exclude.add(path);
1566
- }
1567
- for (const path of paths.shared) {
1568
- legacyInclude.add(path);
1569
- sharedInclude.add(path);
1570
- }
1571
- for (const path of paths.sharedDeclarations) {
1572
- include.add(path);
1573
- }
1574
- for (const path of paths.globalDeclarations) {
1575
- include.add(path);
1576
- legacyInclude.add(path);
1577
- sharedInclude.add(path);
1578
- }
1579
- }
1580
- }
1581
- const moduleEntryPaths = [];
1582
- for (const m of nuxt.options._installedModules) {
1583
- const path = m.meta?.rawPath || m.entryPath;
1584
- if (path) {
1585
- moduleEntryPaths.push(getDirectory(path));
1586
- }
1587
- }
1588
- const modulePaths = await resolveNuxtModule(rootDirWithSlash, moduleEntryPaths);
1589
- for (const path of modulePaths) {
1590
- const relative2 = relativeWithDot(nuxt.options.buildDir, path);
1591
- if (!path.includes("node_modules") && path.startsWith(rootDirWithSlash)) {
1592
- include.add(join(relative2, "runtime"));
1593
- include.add(join(relative2, "dist/runtime"));
1594
- nodeInclude.add(join(relative2, "*.*"));
1595
- }
1596
- legacyInclude.add(join(relative2, "runtime"));
1597
- legacyInclude.add(join(relative2, "dist/runtime"));
1598
- nodeExclude.add(join(relative2, "runtime"));
1599
- nodeExclude.add(join(relative2, "dist/runtime"));
1600
- exclude.add(join(relative2, "runtime/server"));
1601
- exclude.add(join(relative2, "dist/runtime/server"));
1602
- exclude.add(join(relative2, "*.*"));
1603
- exclude.add(join(relative2, "dist/*.*"));
1604
- legacyExclude.add(join(relative2, "runtime/server"));
1605
- legacyExclude.add(join(relative2, "dist/runtime/server"));
1606
- }
1607
- const nestedModulesDirs = [];
1608
- for (const dir of [...nuxt.options.modulesDir].sort()) {
1609
- const withSlash = withTrailingSlash(dir);
1610
- if (nestedModulesDirs.every((d) => !d.startsWith(withSlash))) {
1611
- nestedModulesDirs.push(withSlash);
1612
- }
1613
- }
1614
- let hasTypescriptVersionWithModulePreserve;
1615
- for (const parent of nestedModulesDirs) {
1616
- hasTypescriptVersionWithModulePreserve ??= await readPackageJSON("typescript", { parent }).then((r) => r?.version && gte(r.version, "5.4.0")).catch(() => void 0);
1617
- }
1618
- hasTypescriptVersionWithModulePreserve ??= true;
1619
- const useDecorators = Boolean(nuxt.options.experimental?.decorators);
1620
- const tsConfig = defu(nuxt.options.typescript?.tsConfig, {
1621
- compilerOptions: {
1622
- /* Base options: */
1623
- esModuleInterop: true,
1624
- skipLibCheck: true,
1625
- target: "ESNext",
1626
- allowJs: true,
1627
- resolveJsonModule: true,
1628
- moduleDetection: "force",
1629
- isolatedModules: true,
1630
- verbatimModuleSyntax: true,
1631
- /* Strictness */
1632
- strict: nuxt.options.typescript?.strict ?? true,
1633
- noUncheckedIndexedAccess: true,
1634
- forceConsistentCasingInFileNames: true,
1635
- noImplicitOverride: true,
1636
- /* Decorator support */
1637
- ...useDecorators ? {
1638
- experimentalDecorators: false
1639
- } : {},
1640
- /* If NOT transpiling with TypeScript: */
1641
- module: hasTypescriptVersionWithModulePreserve ? "preserve" : "ESNext",
1642
- noEmit: true,
1643
- /* If your code runs in the DOM: */
1644
- lib: [
1645
- "ESNext",
1646
- ...useDecorators ? ["esnext.decorators"] : [],
1647
- "dom",
1648
- "dom.iterable",
1649
- "webworker"
1650
- ],
1651
- /* JSX support for Vue */
1652
- jsx: "preserve",
1653
- jsxImportSource: "vue",
1654
- /* remove auto-scanning for types */
1655
- types: [],
1656
- /* add paths object for filling-in later */
1657
- paths: {},
1658
- /* Possibly consider removing the following in future */
1659
- moduleResolution: nuxt.options.future?.typescriptBundlerResolution || nuxt.options.experimental?.typescriptBundlerResolution ? "Bundler" : "Node",
1660
- /* implied by module: preserve */
1661
- useDefineForClassFields: true,
1662
- /* implied by target: es2022+ */
1663
- noImplicitThis: true,
1664
- /* enabled with `strict` */
1665
- allowSyntheticDefaultImports: true
1666
- },
1667
- include: [...include],
1668
- exclude: [...exclude]
1669
- });
1670
- const nodeTsConfig = defu(nuxt.options.typescript?.nodeTsConfig, {
1671
- compilerOptions: {
1672
- /* Base options: */
1673
- esModuleInterop: tsConfig.compilerOptions?.esModuleInterop,
1674
- skipLibCheck: tsConfig.compilerOptions?.skipLibCheck,
1675
- target: tsConfig.compilerOptions?.target,
1676
- allowJs: tsConfig.compilerOptions?.allowJs,
1677
- resolveJsonModule: tsConfig.compilerOptions?.resolveJsonModule,
1678
- moduleDetection: tsConfig.compilerOptions?.moduleDetection,
1679
- isolatedModules: tsConfig.compilerOptions?.isolatedModules,
1680
- verbatimModuleSyntax: tsConfig.compilerOptions?.verbatimModuleSyntax,
1681
- /* Strictness */
1682
- strict: tsConfig.compilerOptions?.strict,
1683
- noUncheckedIndexedAccess: tsConfig.compilerOptions?.noUncheckedIndexedAccess,
1684
- forceConsistentCasingInFileNames: tsConfig.compilerOptions?.forceConsistentCasingInFileNames,
1685
- noImplicitOverride: tsConfig.compilerOptions?.noImplicitOverride,
1686
- /* If NOT transpiling with TypeScript: */
1687
- module: tsConfig.compilerOptions?.module,
1688
- noEmit: true,
1689
- /* remove auto-scanning for types */
1690
- types: [],
1691
- /* add paths object for filling-in later */
1692
- paths: {},
1693
- /* Possibly consider removing the following in future */
1694
- moduleResolution: tsConfig.compilerOptions?.moduleResolution,
1695
- useDefineForClassFields: tsConfig.compilerOptions?.useDefineForClassFields,
1696
- noImplicitThis: tsConfig.compilerOptions?.noImplicitThis,
1697
- allowSyntheticDefaultImports: tsConfig.compilerOptions?.allowSyntheticDefaultImports
1698
- },
1699
- include: [...nodeInclude],
1700
- exclude: [...nodeExclude]
1701
- });
1702
- const sharedTsConfig = defu(nuxt.options.typescript?.sharedTsConfig, {
1703
- compilerOptions: {
1704
- /* Base options: */
1705
- esModuleInterop: tsConfig.compilerOptions?.esModuleInterop,
1706
- skipLibCheck: tsConfig.compilerOptions?.skipLibCheck,
1707
- target: tsConfig.compilerOptions?.target,
1708
- allowJs: tsConfig.compilerOptions?.allowJs,
1709
- resolveJsonModule: tsConfig.compilerOptions?.resolveJsonModule,
1710
- moduleDetection: tsConfig.compilerOptions?.moduleDetection,
1711
- isolatedModules: tsConfig.compilerOptions?.isolatedModules,
1712
- verbatimModuleSyntax: tsConfig.compilerOptions?.verbatimModuleSyntax,
1713
- /* Strictness */
1714
- strict: tsConfig.compilerOptions?.strict,
1715
- noUncheckedIndexedAccess: tsConfig.compilerOptions?.noUncheckedIndexedAccess,
1716
- forceConsistentCasingInFileNames: tsConfig.compilerOptions?.forceConsistentCasingInFileNames,
1717
- noImplicitOverride: tsConfig.compilerOptions?.noImplicitOverride,
1718
- /* If NOT transpiling with TypeScript: */
1719
- module: tsConfig.compilerOptions?.module,
1720
- noEmit: true,
1721
- /* remove auto-scanning for types */
1722
- types: [],
1723
- /* add paths object for filling-in later */
1724
- paths: {},
1725
- /* Possibly consider removing the following in future */
1726
- moduleResolution: tsConfig.compilerOptions?.moduleResolution,
1727
- useDefineForClassFields: tsConfig.compilerOptions?.useDefineForClassFields,
1728
- noImplicitThis: tsConfig.compilerOptions?.noImplicitThis,
1729
- allowSyntheticDefaultImports: tsConfig.compilerOptions?.allowSyntheticDefaultImports
1730
- },
1731
- include: [...sharedInclude],
1732
- exclude: [...sharedExclude]
1733
- });
1734
- const aliases = nuxt.options.alias;
1735
- const basePath = tsConfig.compilerOptions.baseUrl ? resolve(nuxt.options.buildDir, tsConfig.compilerOptions.baseUrl) : nuxt.options.buildDir;
1736
- tsConfig.compilerOptions ||= {};
1737
- tsConfig.compilerOptions.paths ||= {};
1738
- tsConfig.include ||= [];
1739
- const importPaths = nuxt.options.modulesDir.map((d) => directoryToURL(d));
1740
- for (const alias in aliases) {
1741
- if (excludedAlias.some((re) => re.test(alias))) {
1742
- continue;
1743
- }
1744
- let absolutePath = resolve(basePath, aliases[alias]);
1745
- let stats = await promises.stat(absolutePath).catch(
1746
- () => null
1747
- /* file does not exist */
1748
- );
1749
- if (!stats) {
1750
- const resolvedModule = resolveModulePath(aliases[alias], {
1751
- try: true,
1752
- from: importPaths,
1753
- extensions: [...nuxt.options.extensions, ".d.ts", ".d.mts", ".d.cts"]
1754
- });
1755
- if (resolvedModule) {
1756
- absolutePath = resolvedModule;
1757
- stats = await promises.stat(resolvedModule).catch(() => null);
1758
- }
1759
- }
1760
- const relativePath = relativeWithDot(nuxt.options.buildDir, absolutePath);
1761
- if (stats?.isDirectory() || aliases[alias].endsWith("/")) {
1762
- tsConfig.compilerOptions.paths[alias] = [relativePath];
1763
- tsConfig.compilerOptions.paths[`${alias}/*`] = [`${relativePath}/*`];
1764
- } else {
1765
- const path = stats?.isFile() ? relativePath.replace(EXTENSION_RE, "") : aliases[alias];
1766
- tsConfig.compilerOptions.paths[alias] = [path];
1767
- }
1768
- }
1769
- const references = [];
1770
- const nodeReferences = [];
1771
- const sharedReferences = [];
1772
- await Promise.all([...nuxt.options.modules, ...nuxt.options._modules].map(async (id) => {
1773
- if (typeof id !== "string") {
1774
- return;
1775
- }
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", { references, declarations, tsConfig, nodeTsConfig, nodeReferences, sharedTsConfig, sharedReferences });
1789
- const legacyTsConfig = defu({}, {
1790
- ...tsConfig,
1791
- include: [...tsConfig.include, ...legacyInclude],
1792
- exclude: [...legacyExclude]
1793
- });
1794
- async function resolveConfig(tsConfig2) {
1795
- for (const alias in tsConfig2.compilerOptions.paths) {
1796
- const paths = tsConfig2.compilerOptions.paths[alias];
1797
- tsConfig2.compilerOptions.paths[alias] = [...new Set(await Promise.all(paths.map(async (path) => {
1798
- if (!isAbsolute(path)) {
1799
- return path;
1800
- }
1801
- const stats = await promises.stat(path).catch(
1802
- () => null
1803
- /* file does not exist */
1804
- );
1805
- return relativeWithDot(nuxt.options.buildDir, stats?.isFile() ? path.replace(EXTENSION_RE, "") : path);
1806
- })))];
1807
- }
1808
- sortTsPaths(tsConfig2.compilerOptions.paths);
1809
- tsConfig2.include = [...new Set(tsConfig2.include.map((p) => isAbsolute(p) ? relativeWithDot(nuxt.options.buildDir, p) : p))];
1810
- tsConfig2.exclude = [...new Set(tsConfig2.exclude.map((p) => isAbsolute(p) ? relativeWithDot(nuxt.options.buildDir, p) : p))];
1811
- }
1812
- await Promise.all([
1813
- resolveConfig(tsConfig),
1814
- resolveConfig(nodeTsConfig),
1815
- resolveConfig(sharedTsConfig),
1816
- resolveConfig(legacyTsConfig)
1817
- ]);
1818
- const declaration = [
1819
- ...references.map((ref) => {
1820
- if ("path" in ref && isAbsolute(ref.path)) {
1821
- ref.path = relative(nuxt.options.buildDir, ref.path);
1822
- }
1823
- return `/// <reference ${renderAttrs(ref)} />`;
1824
- }),
1825
- ...declarations,
1826
- "",
1827
- "export {}",
1828
- ""
1829
- ].join("\n");
1830
- const nodeDeclaration = [
1831
- ...nodeReferences.map((ref) => {
1832
- if ("path" in ref && isAbsolute(ref.path)) {
1833
- ref.path = relative(nuxt.options.buildDir, ref.path);
1834
- }
1835
- return `/// <reference ${renderAttrs(ref)} />`;
1836
- }),
1837
- "",
1838
- "export {}",
1839
- ""
1840
- ].join("\n");
1841
- const sharedDeclaration = [
1842
- ...sharedReferences.map((ref) => {
1843
- if ("path" in ref && isAbsolute(ref.path)) {
1844
- ref.path = relative(nuxt.options.buildDir, ref.path);
1845
- }
1846
- return `/// <reference ${renderAttrs(ref)} />`;
1847
- }),
1848
- "",
1849
- "export {}",
1850
- ""
1851
- ].join("\n");
1852
- return {
1853
- declaration,
1854
- sharedTsConfig,
1855
- sharedDeclaration,
1856
- nodeTsConfig,
1857
- nodeDeclaration,
1858
- tsConfig,
1859
- legacyTsConfig
1860
- };
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
+ strict: nuxt.options.typescript?.strict ?? true,
1656
+ noUncheckedIndexedAccess: true,
1657
+ forceConsistentCasingInFileNames: true,
1658
+ noImplicitOverride: true,
1659
+ ...useDecorators ? { experimentalDecorators: false } : {},
1660
+ module: hasTypescriptVersionWithModulePreserve ? "preserve" : "ESNext",
1661
+ noEmit: true,
1662
+ lib: [
1663
+ "ESNext",
1664
+ ...useDecorators ? ["esnext.decorators"] : [],
1665
+ "dom",
1666
+ "dom.iterable",
1667
+ "webworker"
1668
+ ],
1669
+ jsx: "preserve",
1670
+ jsxImportSource: "vue",
1671
+ types: [],
1672
+ paths: {},
1673
+ moduleResolution: nuxt.options.future?.typescriptBundlerResolution || nuxt.options.experimental?.typescriptBundlerResolution ? "Bundler" : "Node",
1674
+ useDefineForClassFields: true,
1675
+ noImplicitThis: true,
1676
+ allowSyntheticDefaultImports: true
1677
+ },
1678
+ include: [...include],
1679
+ exclude: [...exclude]
1680
+ });
1681
+ const nodeTsConfig = defu(nuxt.options.typescript?.nodeTsConfig, {
1682
+ compilerOptions: {
1683
+ esModuleInterop: tsConfig.compilerOptions?.esModuleInterop,
1684
+ skipLibCheck: tsConfig.compilerOptions?.skipLibCheck,
1685
+ target: tsConfig.compilerOptions?.target,
1686
+ allowJs: tsConfig.compilerOptions?.allowJs,
1687
+ resolveJsonModule: tsConfig.compilerOptions?.resolveJsonModule,
1688
+ moduleDetection: tsConfig.compilerOptions?.moduleDetection,
1689
+ isolatedModules: tsConfig.compilerOptions?.isolatedModules,
1690
+ verbatimModuleSyntax: tsConfig.compilerOptions?.verbatimModuleSyntax,
1691
+ strict: tsConfig.compilerOptions?.strict,
1692
+ noUncheckedIndexedAccess: tsConfig.compilerOptions?.noUncheckedIndexedAccess,
1693
+ forceConsistentCasingInFileNames: tsConfig.compilerOptions?.forceConsistentCasingInFileNames,
1694
+ noImplicitOverride: tsConfig.compilerOptions?.noImplicitOverride,
1695
+ module: tsConfig.compilerOptions?.module,
1696
+ noEmit: true,
1697
+ types: [],
1698
+ paths: {},
1699
+ moduleResolution: tsConfig.compilerOptions?.moduleResolution,
1700
+ useDefineForClassFields: tsConfig.compilerOptions?.useDefineForClassFields,
1701
+ noImplicitThis: tsConfig.compilerOptions?.noImplicitThis,
1702
+ allowSyntheticDefaultImports: tsConfig.compilerOptions?.allowSyntheticDefaultImports
1703
+ },
1704
+ include: [...nodeInclude],
1705
+ exclude: [...nodeExclude]
1706
+ });
1707
+ const sharedTsConfig = defu(nuxt.options.typescript?.sharedTsConfig, {
1708
+ compilerOptions: {
1709
+ esModuleInterop: tsConfig.compilerOptions?.esModuleInterop,
1710
+ skipLibCheck: tsConfig.compilerOptions?.skipLibCheck,
1711
+ target: tsConfig.compilerOptions?.target,
1712
+ allowJs: tsConfig.compilerOptions?.allowJs,
1713
+ resolveJsonModule: tsConfig.compilerOptions?.resolveJsonModule,
1714
+ moduleDetection: tsConfig.compilerOptions?.moduleDetection,
1715
+ isolatedModules: tsConfig.compilerOptions?.isolatedModules,
1716
+ verbatimModuleSyntax: tsConfig.compilerOptions?.verbatimModuleSyntax,
1717
+ strict: tsConfig.compilerOptions?.strict,
1718
+ noUncheckedIndexedAccess: tsConfig.compilerOptions?.noUncheckedIndexedAccess,
1719
+ forceConsistentCasingInFileNames: tsConfig.compilerOptions?.forceConsistentCasingInFileNames,
1720
+ noImplicitOverride: tsConfig.compilerOptions?.noImplicitOverride,
1721
+ module: tsConfig.compilerOptions?.module,
1722
+ noEmit: true,
1723
+ types: [],
1724
+ paths: {},
1725
+ moduleResolution: tsConfig.compilerOptions?.moduleResolution,
1726
+ useDefineForClassFields: tsConfig.compilerOptions?.useDefineForClassFields,
1727
+ noImplicitThis: tsConfig.compilerOptions?.noImplicitThis,
1728
+ allowSyntheticDefaultImports: tsConfig.compilerOptions?.allowSyntheticDefaultImports
1729
+ },
1730
+ include: [...sharedInclude],
1731
+ exclude: [...sharedExclude]
1732
+ });
1733
+ const aliases = nuxt.options.alias;
1734
+ const basePath = tsConfig.compilerOptions.baseUrl ? resolve(nuxt.options.buildDir, tsConfig.compilerOptions.baseUrl) : nuxt.options.buildDir;
1735
+ tsConfig.compilerOptions ||= {};
1736
+ tsConfig.compilerOptions.paths ||= {};
1737
+ tsConfig.include ||= [];
1738
+ const importPaths = nuxt.options.modulesDir.map((d) => directoryToURL(d));
1739
+ for (const alias in aliases) {
1740
+ if (excludedAlias.some((re) => re.test(alias))) continue;
1741
+ let absolutePath = resolve(basePath, aliases[alias]);
1742
+ let stats = await promises.stat(absolutePath).catch(() => null);
1743
+ if (!stats) {
1744
+ const resolvedModule = resolveModulePath(aliases[alias], {
1745
+ try: true,
1746
+ from: importPaths,
1747
+ extensions: [
1748
+ ...nuxt.options.extensions,
1749
+ ".d.ts",
1750
+ ".d.mts",
1751
+ ".d.cts"
1752
+ ]
1753
+ });
1754
+ if (resolvedModule) {
1755
+ absolutePath = resolvedModule;
1756
+ stats = await promises.stat(resolvedModule).catch(() => null);
1757
+ }
1758
+ }
1759
+ const relativePath = relativeWithDot(nuxt.options.buildDir, absolutePath);
1760
+ if (stats?.isDirectory() || aliases[alias].endsWith("/")) {
1761
+ tsConfig.compilerOptions.paths[alias] = [relativePath];
1762
+ tsConfig.compilerOptions.paths[`${alias}/*`] = [`${relativePath}/*`];
1763
+ } else {
1764
+ const path = stats?.isFile() ? relativePath.replace(EXTENSION_RE, "") : aliases[alias];
1765
+ tsConfig.compilerOptions.paths[alias] = [path];
1766
+ }
1767
+ }
1768
+ const references = [];
1769
+ const nodeReferences = [];
1770
+ const sharedReferences = [];
1771
+ await Promise.all([...nuxt.options.modules, ...nuxt.options._modules].map(async (id) => {
1772
+ if (typeof id !== "string") return;
1773
+ for (const parent of nestedModulesDirs) {
1774
+ const pkg = await readPackageJSON(id, { parent }).catch(() => null);
1775
+ if (pkg) {
1776
+ nodeReferences.push({ types: pkg.name ?? id });
1777
+ references.push({ types: pkg.name ?? id });
1778
+ return;
1779
+ }
1780
+ }
1781
+ nodeReferences.push({ types: id });
1782
+ references.push({ types: id });
1783
+ }));
1784
+ const declarations = [];
1785
+ await nuxt.callHook("prepare:types", {
1786
+ references,
1787
+ declarations,
1788
+ tsConfig,
1789
+ nodeTsConfig,
1790
+ nodeReferences,
1791
+ sharedTsConfig,
1792
+ sharedReferences
1793
+ });
1794
+ const legacyTsConfig = defu({}, {
1795
+ ...tsConfig,
1796
+ include: [...tsConfig.include, ...legacyInclude],
1797
+ exclude: [...legacyExclude]
1798
+ });
1799
+ async function resolveConfig(tsConfig$1) {
1800
+ for (const alias in tsConfig$1.compilerOptions.paths) {
1801
+ const paths = tsConfig$1.compilerOptions.paths[alias];
1802
+ tsConfig$1.compilerOptions.paths[alias] = [...new Set(await Promise.all(paths.map(async (path) => {
1803
+ if (!isAbsolute(path)) return path;
1804
+ const stats = await promises.stat(path).catch(() => null);
1805
+ return relativeWithDot(nuxt.options.buildDir, stats?.isFile() ? path.replace(EXTENSION_RE, "") : path);
1806
+ })))];
1807
+ }
1808
+ sortTsPaths(tsConfig$1.compilerOptions.paths);
1809
+ tsConfig$1.include = [...new Set(tsConfig$1.include.map((p) => isAbsolute(p) ? relativeWithDot(nuxt.options.buildDir, p) : p))];
1810
+ tsConfig$1.exclude = [...new Set(tsConfig$1.exclude.map((p) => isAbsolute(p) ? relativeWithDot(nuxt.options.buildDir, p) : p))];
1811
+ }
1812
+ await Promise.all([
1813
+ resolveConfig(tsConfig),
1814
+ resolveConfig(nodeTsConfig),
1815
+ resolveConfig(sharedTsConfig),
1816
+ resolveConfig(legacyTsConfig)
1817
+ ]);
1818
+ const declaration = [
1819
+ ...references.map((ref) => {
1820
+ if ("path" in ref && isAbsolute(ref.path)) ref.path = relative(nuxt.options.buildDir, ref.path);
1821
+ return `/// <reference ${renderAttrs(ref)} />`;
1822
+ }),
1823
+ ...declarations,
1824
+ "",
1825
+ "export {}",
1826
+ ""
1827
+ ].join("\n");
1828
+ const nodeDeclaration = [
1829
+ ...nodeReferences.map((ref) => {
1830
+ if ("path" in ref && isAbsolute(ref.path)) ref.path = relative(nuxt.options.buildDir, ref.path);
1831
+ return `/// <reference ${renderAttrs(ref)} />`;
1832
+ }),
1833
+ "",
1834
+ "export {}",
1835
+ ""
1836
+ ].join("\n");
1837
+ return {
1838
+ declaration,
1839
+ sharedTsConfig,
1840
+ sharedDeclaration: [
1841
+ ...sharedReferences.map((ref) => {
1842
+ if ("path" in ref && isAbsolute(ref.path)) ref.path = relative(nuxt.options.buildDir, ref.path);
1843
+ return `/// <reference ${renderAttrs(ref)} />`;
1844
+ }),
1845
+ "",
1846
+ "export {}",
1847
+ ""
1848
+ ].join("\n"),
1849
+ nodeTsConfig,
1850
+ nodeDeclaration,
1851
+ tsConfig,
1852
+ legacyTsConfig
1853
+ };
1861
1854
  }
1862
1855
  async function writeTypes(nuxt) {
1863
- const { tsConfig, nodeTsConfig, nodeDeclaration, declaration, legacyTsConfig, sharedDeclaration, sharedTsConfig } = await _generateTypes(nuxt);
1864
- const appTsConfigPath = resolve(nuxt.options.buildDir, "tsconfig.app.json");
1865
- const legacyTsConfigPath = resolve(nuxt.options.buildDir, "tsconfig.json");
1866
- const nodeTsConfigPath = resolve(nuxt.options.buildDir, "tsconfig.node.json");
1867
- const sharedTsConfigPath = resolve(nuxt.options.buildDir, "tsconfig.shared.json");
1868
- const declarationPath = resolve(nuxt.options.buildDir, "nuxt.d.ts");
1869
- const nodeDeclarationPath = resolve(nuxt.options.buildDir, "nuxt.node.d.ts");
1870
- const sharedDeclarationPath = resolve(nuxt.options.buildDir, "nuxt.shared.d.ts");
1871
- await promises.mkdir(nuxt.options.buildDir, { recursive: true });
1872
- await Promise.all([
1873
- promises.writeFile(appTsConfigPath, JSON.stringify(tsConfig, null, 2)),
1874
- promises.writeFile(legacyTsConfigPath, JSON.stringify(legacyTsConfig, null, 2)),
1875
- promises.writeFile(nodeTsConfigPath, JSON.stringify(nodeTsConfig, null, 2)),
1876
- promises.writeFile(sharedTsConfigPath, JSON.stringify(sharedTsConfig, null, 2)),
1877
- promises.writeFile(declarationPath, declaration),
1878
- promises.writeFile(nodeDeclarationPath, nodeDeclaration),
1879
- promises.writeFile(sharedDeclarationPath, sharedDeclaration)
1880
- ]);
1856
+ const { tsConfig, nodeTsConfig, nodeDeclaration, declaration, legacyTsConfig, sharedDeclaration, sharedTsConfig } = await _generateTypes(nuxt);
1857
+ const appTsConfigPath = resolve(nuxt.options.buildDir, "tsconfig.app.json");
1858
+ const legacyTsConfigPath = resolve(nuxt.options.buildDir, "tsconfig.json");
1859
+ const nodeTsConfigPath = resolve(nuxt.options.buildDir, "tsconfig.node.json");
1860
+ const sharedTsConfigPath = resolve(nuxt.options.buildDir, "tsconfig.shared.json");
1861
+ const declarationPath = resolve(nuxt.options.buildDir, "nuxt.d.ts");
1862
+ const nodeDeclarationPath = resolve(nuxt.options.buildDir, "nuxt.node.d.ts");
1863
+ const sharedDeclarationPath = resolve(nuxt.options.buildDir, "nuxt.shared.d.ts");
1864
+ await promises.mkdir(nuxt.options.buildDir, { recursive: true });
1865
+ await Promise.all([
1866
+ promises.writeFile(appTsConfigPath, JSON.stringify(tsConfig, null, 2)),
1867
+ promises.writeFile(legacyTsConfigPath, JSON.stringify(legacyTsConfig, null, 2)),
1868
+ promises.writeFile(nodeTsConfigPath, JSON.stringify(nodeTsConfig, null, 2)),
1869
+ promises.writeFile(sharedTsConfigPath, JSON.stringify(sharedTsConfig, null, 2)),
1870
+ promises.writeFile(declarationPath, declaration),
1871
+ promises.writeFile(nodeDeclarationPath, nodeDeclaration),
1872
+ promises.writeFile(sharedDeclarationPath, sharedDeclaration)
1873
+ ]);
1881
1874
  }
1882
1875
  function sortTsPaths(paths) {
1883
- for (const pathKey in paths) {
1884
- if (pathKey.startsWith("#build")) {
1885
- const pathValue = paths[pathKey];
1886
- delete paths[pathKey];
1887
- paths[pathKey] = pathValue;
1888
- }
1889
- }
1876
+ for (const pathKey in paths) if (pathKey.startsWith("#build")) {
1877
+ const pathValue = paths[pathKey];
1878
+ delete paths[pathKey];
1879
+ paths[pathKey] = pathValue;
1880
+ }
1890
1881
  }
1891
1882
  function renderAttrs(obj) {
1892
- const attrs = [];
1893
- for (const key in obj) {
1894
- attrs.push(renderAttr(key, obj[key]));
1895
- }
1896
- return attrs.join(" ");
1883
+ const attrs = [];
1884
+ for (const key in obj) attrs.push(renderAttr(key, obj[key]));
1885
+ return attrs.join(" ");
1897
1886
  }
1898
1887
  function renderAttr(key, value) {
1899
- return value ? `${key}="${value}"` : "";
1888
+ return value ? `${key}="${value}"` : "";
1900
1889
  }
1901
1890
  const RELATIVE_WITH_DOT_RE = /^([^.])/;
1902
1891
  function relativeWithDot(from, to) {
1903
- return relative(from, to).replace(RELATIVE_WITH_DOT_RE, "./$1") || ".";
1892
+ return relative(from, to).replace(RELATIVE_WITH_DOT_RE, "./$1") || ".";
1904
1893
  }
1905
- function withTrailingSlash(dir) {
1906
- return dir.replace(/[^/]$/, "$&/");
1894
+ function withTrailingSlash$1(dir) {
1895
+ return dir.replace(/[^/]$/, "$&/");
1907
1896
  }
1908
1897
 
1898
+ //#endregion
1899
+ //#region src/layout.ts
1909
1900
  const LAYOUT_RE = /["']/g;
1910
1901
  function addLayout(template, name) {
1911
- const nuxt = useNuxt();
1912
- const { filename, src } = addTemplate(template);
1913
- const layoutName = kebabCase(name || parse(filename).name).replace(LAYOUT_RE, "");
1914
- nuxt.hook("app:templates", (app) => {
1915
- if (layoutName in app.layouts) {
1916
- const relativePath = reverseResolveAlias(app.layouts[layoutName].file, { ...nuxt?.options.alias || {}, ...strippedAtAliases }).pop() || app.layouts[layoutName].file;
1917
- return logger.warn(
1918
- `Not overriding \`${layoutName}\` (provided by \`${relativePath}\`) with \`${src || filename}\`.`
1919
- );
1920
- }
1921
- app.layouts[layoutName] = {
1922
- file: join("#build", filename),
1923
- name: layoutName
1924
- };
1925
- });
1902
+ const nuxt = useNuxt();
1903
+ const { filename, src } = addTemplate(template);
1904
+ const layoutName = kebabCase(name || parse(filename).name).replace(LAYOUT_RE, "");
1905
+ nuxt.hook("app:templates", (app) => {
1906
+ if (layoutName in app.layouts) {
1907
+ const relativePath = reverseResolveAlias(app.layouts[layoutName].file, {
1908
+ ...nuxt?.options.alias || {},
1909
+ ...strippedAtAliases
1910
+ }).pop() || app.layouts[layoutName].file;
1911
+ return logger.warn(`Not overriding \`${layoutName}\` (provided by \`${relativePath}\`) with \`${src || filename}\`.`);
1912
+ }
1913
+ app.layouts[layoutName] = {
1914
+ file: join("#build", filename),
1915
+ name: layoutName
1916
+ };
1917
+ });
1926
1918
  }
1927
1919
  const strippedAtAliases = {
1928
- "@": "",
1929
- "@@": ""
1920
+ "@": "",
1921
+ "@@": ""
1930
1922
  };
1931
1923
 
1924
+ //#endregion
1925
+ //#region src/pages.ts
1932
1926
  function extendPages(cb) {
1933
- useNuxt().hook("pages:extend", cb);
1927
+ useNuxt().hook("pages:extend", cb);
1934
1928
  }
1935
1929
  function extendRouteRules(route, rule, options = {}) {
1936
- const nuxt = useNuxt();
1937
- for (const opts of [nuxt.options, nuxt.options.nitro]) {
1938
- opts.routeRules ||= {};
1939
- opts.routeRules[route] = options.override ? defu(rule, opts.routeRules[route]) : defu(opts.routeRules[route], rule);
1940
- }
1930
+ const nuxt = useNuxt();
1931
+ for (const opts of [nuxt.options, nuxt.options.nitro]) {
1932
+ opts.routeRules ||= {};
1933
+ opts.routeRules[route] = options.override ? defu(rule, opts.routeRules[route]) : defu(opts.routeRules[route], rule);
1934
+ }
1941
1935
  }
1942
1936
  function addRouteMiddleware(input, options = {}) {
1943
- const nuxt = useNuxt();
1944
- const middlewares = toArray(input);
1945
- nuxt.hook("app:resolve", (app) => {
1946
- for (const middleware of middlewares) {
1947
- const find = app.middleware.findIndex((item) => item.name === middleware.name);
1948
- if (find >= 0) {
1949
- const foundPath = app.middleware[find].path;
1950
- if (foundPath === middleware.path) {
1951
- continue;
1952
- }
1953
- if (options.override === true) {
1954
- app.middleware[find] = { ...middleware };
1955
- } else {
1956
- logger.warn(`'${middleware.name}' middleware already exists at '${foundPath}'. You can set \`override: true\` to replace it.`);
1957
- }
1958
- } else if (options.prepend === true) {
1959
- app.middleware.unshift({ ...middleware });
1960
- } else {
1961
- app.middleware.push({ ...middleware });
1962
- }
1963
- }
1964
- });
1937
+ const nuxt = useNuxt();
1938
+ const middlewares = toArray(input);
1939
+ nuxt.hook("app:resolve", (app) => {
1940
+ for (const middleware of middlewares) {
1941
+ const find = app.middleware.findIndex((item) => item.name === middleware.name);
1942
+ if (find >= 0) {
1943
+ const foundPath = app.middleware[find].path;
1944
+ if (foundPath === middleware.path) continue;
1945
+ if (options.override === true) app.middleware[find] = { ...middleware };
1946
+ else logger.warn(`'${middleware.name}' middleware already exists at '${foundPath}'. You can set \`override: true\` to replace it.`);
1947
+ } else if (options.prepend === true) app.middleware.unshift({ ...middleware });
1948
+ else app.middleware.push({ ...middleware });
1949
+ }
1950
+ });
1965
1951
  }
1966
1952
 
1953
+ //#endregion
1954
+ //#region src/plugin.ts
1955
+ /**
1956
+ * Normalize a nuxt plugin object
1957
+ */
1967
1958
  const pluginSymbol = Symbol.for("nuxt plugin");
1968
1959
  function normalizePlugin(plugin) {
1969
- if (typeof plugin === "string") {
1970
- plugin = { src: plugin };
1971
- } else {
1972
- plugin = { ...plugin };
1973
- }
1974
- if (pluginSymbol in plugin) {
1975
- return plugin;
1976
- }
1977
- if (!plugin.src) {
1978
- throw new Error("Invalid plugin. src option is required: " + JSON.stringify(plugin));
1979
- }
1980
- plugin.src = normalize(resolveAlias(plugin.src));
1981
- if (!existsSync(plugin.src) && isAbsolute$1(plugin.src)) {
1982
- try {
1983
- plugin.src = resolveModulePath(plugin.src, {
1984
- extensions: tryUseNuxt()?.options.extensions ?? [".js", ".mjs", ".cjs", ".ts", ".tsx", ".mts", ".cts"]
1985
- });
1986
- } catch {
1987
- }
1988
- }
1989
- if (plugin.ssr) {
1990
- plugin.mode = "server";
1991
- }
1992
- if (!plugin.mode) {
1993
- const [, mode = "all"] = plugin.src.match(MODE_RE) || [];
1994
- plugin.mode = mode;
1995
- }
1996
- plugin[pluginSymbol] = true;
1997
- return plugin;
1960
+ if (typeof plugin === "string") plugin = { src: plugin };
1961
+ else plugin = { ...plugin };
1962
+ if (pluginSymbol in plugin) return plugin;
1963
+ if (!plugin.src) throw new Error("Invalid plugin. src option is required: " + JSON.stringify(plugin));
1964
+ plugin.src = normalize(resolveAlias(plugin.src));
1965
+ if (!existsSync(plugin.src) && isAbsolute$1(plugin.src)) try {
1966
+ plugin.src = resolveModulePath(plugin.src, { extensions: tryUseNuxt()?.options.extensions ?? [
1967
+ ".js",
1968
+ ".mjs",
1969
+ ".cjs",
1970
+ ".ts",
1971
+ ".tsx",
1972
+ ".mts",
1973
+ ".cts"
1974
+ ] });
1975
+ } catch {}
1976
+ if (plugin.ssr) plugin.mode = "server";
1977
+ if (!plugin.mode) {
1978
+ const [, mode = "all"] = plugin.src.match(MODE_RE) || [];
1979
+ plugin.mode = mode;
1980
+ }
1981
+ plugin[pluginSymbol] = true;
1982
+ return plugin;
1998
1983
  }
1999
1984
  function addPlugin(_plugin, opts = {}) {
2000
- const nuxt = useNuxt();
2001
- const plugin = normalizePlugin(_plugin);
2002
- filterInPlace(nuxt.options.plugins, (p) => normalizePlugin(p).src !== plugin.src);
2003
- nuxt.options.plugins[opts.append ? "push" : "unshift"](plugin);
2004
- return plugin;
2005
- }
1985
+ const nuxt = useNuxt();
1986
+ const plugin = normalizePlugin(_plugin);
1987
+ filterInPlace(nuxt.options.plugins, (p) => normalizePlugin(p).src !== plugin.src);
1988
+ nuxt.options.plugins[opts.append ? "push" : "unshift"](plugin);
1989
+ return plugin;
1990
+ }
1991
+ /**
1992
+ * Adds a template and registers as a nuxt plugin.
1993
+ */
2006
1994
  function addPluginTemplate(plugin, opts = {}) {
2007
- const normalizedPlugin = typeof plugin === "string" ? { src: plugin } : { ...plugin, src: addTemplate(plugin).dst };
2008
- return addPlugin(normalizedPlugin, opts);
1995
+ return addPlugin(typeof plugin === "string" ? { src: plugin } : {
1996
+ ...plugin,
1997
+ src: addTemplate(plugin).dst
1998
+ }, opts);
2009
1999
  }
2010
2000
 
2011
- 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 };
2001
+ //#endregion
2002
+ 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 };