@nuxt/kit 3.18.1 → 3.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -7,6 +7,7 @@ import { RspackPluginInstance } from '@rspack/core';
7
7
  import { Plugin, UserConfig } from 'vite';
8
8
  import * as unctx from 'unctx';
9
9
  import { NitroRouteConfig, NitroEventHandler, NitroDevEventHandler, Nitro } from 'nitropack';
10
+ import { GlobOptions } from 'tinyglobby';
10
11
  import * as consola from 'consola';
11
12
  import { ConsolaOptions } from 'consola';
12
13
  import { genSafeVariableName } from 'knitwork';
@@ -20,15 +21,29 @@ declare function defineNuxtModule<TOptions extends ModuleOptions>(): {
20
21
  with: <TOptionsDefaults extends Partial<TOptions>>(definition: ModuleDefinition<TOptions, TOptionsDefaults, true> | NuxtModule<TOptions, TOptionsDefaults, true>) => NuxtModule<TOptions, TOptionsDefaults, true>;
21
22
  };
22
23
 
23
- /** Installs a module on a Nuxt instance. */
24
+ type ModuleToInstall = string | NuxtModule<ModuleOptions, Partial<ModuleOptions>, false>;
25
+ /**
26
+ * Installs a set of modules on a Nuxt instance.
27
+ * @internal
28
+ */
29
+ declare function installModules(modulesToInstall: Map<ModuleToInstall, Record<string, any>>, resolvedModulePaths: Set<string>, nuxt?: Nuxt): Promise<void>;
30
+ /**
31
+ * Installs a module on a Nuxt instance.
32
+ * @deprecated Use module dependencies.
33
+ */
24
34
  declare function installModule<T extends string | NuxtModule, Config extends Extract<NonNullable<NuxtConfig['modules']>[number], [T, any]>>(moduleToInstall: T, inlineOptions?: [Config] extends [never] ? any : Config[1], nuxt?: Nuxt): Promise<void>;
25
- declare function getDirectory(p: string): string;
26
- declare const normalizeModuleTranspilePath: (p: string) => string;
35
+ declare function resolveModuleWithOptions(definition: NuxtModule<any> | string | false | undefined | null | [(NuxtModule | string)?, Record<string, any>?], nuxt: Nuxt): {
36
+ resolvedPath?: string;
37
+ module: string | NuxtModule<any>;
38
+ options: Record<string, any>;
39
+ } | undefined;
27
40
  declare function loadNuxtModuleInstance(nuxtModule: string | NuxtModule, nuxt?: Nuxt): Promise<{
28
41
  nuxtModule: NuxtModule<any>;
29
42
  buildTimeModuleMeta: ModuleMeta;
30
43
  resolvedModulePath?: string;
31
44
  }>;
45
+ declare function getDirectory(p: string): string;
46
+ declare const normalizeModuleTranspilePath: (p: string) => string;
32
47
 
33
48
  /**
34
49
  * Check if a Nuxt module is installed by name.
@@ -68,6 +83,41 @@ interface LoadNuxtOptions extends LoadNuxtConfigOptions {
68
83
  declare function loadNuxt(opts: LoadNuxtOptions): Promise<Nuxt>;
69
84
  declare function buildNuxt(nuxt: Nuxt): Promise<any>;
70
85
 
86
+ interface LayerDirectories {
87
+ /** Nuxt rootDir (`/` by default) */
88
+ readonly root: string;
89
+ /** Nitro source directory (`/server` by default) */
90
+ readonly server: string;
91
+ /** Local modules directory (`/modules` by default) */
92
+ readonly modules: string;
93
+ /** Shared directory (`/shared` by default) */
94
+ readonly shared: string;
95
+ /** Public directory (`/public` by default) */
96
+ readonly public: string;
97
+ /** Nuxt srcDir (`/app/` by default) */
98
+ readonly app: string;
99
+ /** Layouts directory (`/app/layouts` by default) */
100
+ readonly appLayouts: string;
101
+ /** Middleware directory (`/app/middleware` by default) */
102
+ readonly appMiddleware: string;
103
+ /** Pages directory (`/app/pages` by default) */
104
+ readonly appPages: string;
105
+ /** Plugins directory (`/app/plugins` by default) */
106
+ readonly appPlugins: string;
107
+ }
108
+ /**
109
+ * Get the resolved directory paths for all layers in a Nuxt application.
110
+ *
111
+ * Returns an array of LayerDirectories objects, ordered by layer priority:
112
+ * - The first layer is the user/project layer (highest priority)
113
+ * - Earlier layers override later layers in the array
114
+ * - Base layers appear last in the array (lowest priority)
115
+ *
116
+ * @param nuxt - The Nuxt instance to get layers from. Defaults to the current Nuxt context.
117
+ * @returns Array of LayerDirectories objects, ordered by priority (user layer first)
118
+ */
119
+ declare function getLayerDirectories(nuxt?: _nuxt_schema.Nuxt): LayerDirectories[];
120
+
71
121
  declare function addImports(imports: Import | Import[]): void;
72
122
  declare function addImportsDir(dirs: string | string[], opts?: {
73
123
  prepend?: boolean;
@@ -304,7 +354,12 @@ interface ResolvePathOptions {
304
354
  cwd?: string;
305
355
  /** An object of aliases. Default is Nuxt configured aliases. */
306
356
  alias?: Record<string, string>;
307
- /** The file extensions to try. Default is Nuxt configured extensions. */
357
+ /**
358
+ * The file extensions to try.
359
+ * Default is Nuxt configured extensions.
360
+ *
361
+ * Isn't considered when `type` is set to `'dir'`.
362
+ */
308
363
  extensions?: string[];
309
364
  /**
310
365
  * Whether to resolve files that exist in the Nuxt VFS (for example, as a Nuxt template).
@@ -313,21 +368,26 @@ interface ResolvePathOptions {
313
368
  virtual?: boolean;
314
369
  /**
315
370
  * Whether to fallback to the original path if the resolved path does not exist instead of returning the normalized input path.
316
- *
317
371
  * @default false
318
372
  */
319
373
  fallbackToOriginal?: boolean;
374
+ /**
375
+ * The type of the path to be resolved.
376
+ * @default 'file'
377
+ */
378
+ type?: PathType;
320
379
  }
321
380
  /**
322
- * Resolve full path to a file or directory respecting Nuxt alias and extensions options
381
+ * Resolve the full path to a file or a directory (based on the provided type), respecting Nuxt alias and extensions options.
323
382
  *
324
- * If path could not be resolved, normalized input path will be returned
383
+ * If a path cannot be resolved, normalized input will be returned unless the `fallbackToOriginal` option is set to `true`,
384
+ * in which case the original input path will be returned.
325
385
  */
326
386
  declare function resolvePath(path: string, opts?: ResolvePathOptions): Promise<string>;
327
387
  /**
328
388
  * Try to resolve first existing file in paths
329
389
  */
330
- declare function findPath(paths: string | string[], opts?: ResolvePathOptions, pathType?: 'file' | 'dir'): Promise<string | null>;
390
+ declare function findPath(paths: string | string[], opts?: ResolvePathOptions, pathType?: PathType): Promise<string | null>;
331
391
  /**
332
392
  * Resolve path aliases respecting Nuxt alias options
333
393
  */
@@ -341,8 +401,16 @@ interface Resolver {
341
401
  */
342
402
  declare function createResolver(base: string | URL): Resolver;
343
403
  declare function resolveNuxtModule(base: string, paths: string[]): Promise<string[]>;
404
+ type PathType = 'file' | 'dir';
405
+ /**
406
+ * Resolve absolute file paths in the provided directory with respect to `.nuxtignore` and return them sorted.
407
+ * @param path path to the directory to resolve files in
408
+ * @param pattern glob pattern or an array of glob patterns to match files
409
+ * @param opts options for globbing
410
+ */
344
411
  declare function resolveFiles(path: string, pattern: string | string[], opts?: {
345
412
  followSymbolicLinks?: boolean;
413
+ ignore?: GlobOptions['ignore'];
346
414
  }): Promise<string[]>;
347
415
 
348
416
  /**
@@ -475,5 +543,5 @@ declare const templateUtils: {
475
543
  }) => string;
476
544
  };
477
545
 
478
- 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, compileTemplate, createIsIgnored, createResolver, defineNuxtModule, directoryToURL, extendNuxtSchema, extendPages, extendRouteRules, extendRspackConfig, extendViteConfig, extendWebpackConfig, findPath, getDirectory, getNuxtCtx, getNuxtModuleVersion, getNuxtVersion, hasNuxtCompatibility, hasNuxtModule, hasNuxtModuleCompatibility, importModule, installModule, isIgnored, isNuxt2, isNuxt3, isNuxtMajorVersion, loadNuxt, loadNuxtConfig, loadNuxtModuleInstance, logger, normalizeModuleTranspilePath, normalizePlugin, normalizeSemanticVersion, normalizeTemplate, nuxtCtx, requireModule, resolveAlias, resolveFiles, resolveIgnorePatterns, resolveModule, resolveNuxtModule, resolvePath, runWithNuxtContext, templateUtils, tryImportModule, tryRequireModule, tryResolveModule, tryUseNuxt, updateRuntimeConfig, updateTemplates, useLogger, useNitro, useNuxt, useRuntimeConfig, writeTypes };
479
- export type { AddComponentOptions, AddPluginOptions, AddRouteMiddlewareOptions, ExtendConfigOptions, ExtendRouteRulesOptions, ExtendViteConfigOptions, ExtendWebpackConfigOptions, ImportModuleOptions, LoadNuxtConfigOptions, LoadNuxtOptions, ResolveModuleOptions, ResolvePathOptions, Resolver };
546
+ 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, compileTemplate, 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, templateUtils, tryImportModule, tryRequireModule, tryResolveModule, tryUseNuxt, updateRuntimeConfig, updateTemplates, useLogger, useNitro, useNuxt, useRuntimeConfig, writeTypes };
547
+ export type { AddComponentOptions, AddPluginOptions, AddRouteMiddlewareOptions, ExtendConfigOptions, ExtendRouteRulesOptions, ExtendViteConfigOptions, ExtendWebpackConfigOptions, ImportModuleOptions, LayerDirectories, LoadNuxtConfigOptions, LoadNuxtOptions, ResolveModuleOptions, ResolvePathOptions, Resolver };
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ import { RspackPluginInstance } from '@rspack/core';
7
7
  import { Plugin, UserConfig } from 'vite';
8
8
  import * as unctx from 'unctx';
9
9
  import { NitroRouteConfig, NitroEventHandler, NitroDevEventHandler, Nitro } from 'nitropack';
10
+ import { GlobOptions } from 'tinyglobby';
10
11
  import * as consola from 'consola';
11
12
  import { ConsolaOptions } from 'consola';
12
13
  import { genSafeVariableName } from 'knitwork';
@@ -20,15 +21,29 @@ declare function defineNuxtModule<TOptions extends ModuleOptions>(): {
20
21
  with: <TOptionsDefaults extends Partial<TOptions>>(definition: ModuleDefinition<TOptions, TOptionsDefaults, true> | NuxtModule<TOptions, TOptionsDefaults, true>) => NuxtModule<TOptions, TOptionsDefaults, true>;
21
22
  };
22
23
 
23
- /** Installs a module on a Nuxt instance. */
24
+ type ModuleToInstall = string | NuxtModule<ModuleOptions, Partial<ModuleOptions>, false>;
25
+ /**
26
+ * Installs a set of modules on a Nuxt instance.
27
+ * @internal
28
+ */
29
+ declare function installModules(modulesToInstall: Map<ModuleToInstall, Record<string, any>>, resolvedModulePaths: Set<string>, nuxt?: Nuxt): Promise<void>;
30
+ /**
31
+ * Installs a module on a Nuxt instance.
32
+ * @deprecated Use module dependencies.
33
+ */
24
34
  declare function installModule<T extends string | NuxtModule, Config extends Extract<NonNullable<NuxtConfig['modules']>[number], [T, any]>>(moduleToInstall: T, inlineOptions?: [Config] extends [never] ? any : Config[1], nuxt?: Nuxt): Promise<void>;
25
- declare function getDirectory(p: string): string;
26
- declare const normalizeModuleTranspilePath: (p: string) => string;
35
+ declare function resolveModuleWithOptions(definition: NuxtModule<any> | string | false | undefined | null | [(NuxtModule | string)?, Record<string, any>?], nuxt: Nuxt): {
36
+ resolvedPath?: string;
37
+ module: string | NuxtModule<any>;
38
+ options: Record<string, any>;
39
+ } | undefined;
27
40
  declare function loadNuxtModuleInstance(nuxtModule: string | NuxtModule, nuxt?: Nuxt): Promise<{
28
41
  nuxtModule: NuxtModule<any>;
29
42
  buildTimeModuleMeta: ModuleMeta;
30
43
  resolvedModulePath?: string;
31
44
  }>;
45
+ declare function getDirectory(p: string): string;
46
+ declare const normalizeModuleTranspilePath: (p: string) => string;
32
47
 
33
48
  /**
34
49
  * Check if a Nuxt module is installed by name.
@@ -68,6 +83,41 @@ interface LoadNuxtOptions extends LoadNuxtConfigOptions {
68
83
  declare function loadNuxt(opts: LoadNuxtOptions): Promise<Nuxt>;
69
84
  declare function buildNuxt(nuxt: Nuxt): Promise<any>;
70
85
 
86
+ interface LayerDirectories {
87
+ /** Nuxt rootDir (`/` by default) */
88
+ readonly root: string;
89
+ /** Nitro source directory (`/server` by default) */
90
+ readonly server: string;
91
+ /** Local modules directory (`/modules` by default) */
92
+ readonly modules: string;
93
+ /** Shared directory (`/shared` by default) */
94
+ readonly shared: string;
95
+ /** Public directory (`/public` by default) */
96
+ readonly public: string;
97
+ /** Nuxt srcDir (`/app/` by default) */
98
+ readonly app: string;
99
+ /** Layouts directory (`/app/layouts` by default) */
100
+ readonly appLayouts: string;
101
+ /** Middleware directory (`/app/middleware` by default) */
102
+ readonly appMiddleware: string;
103
+ /** Pages directory (`/app/pages` by default) */
104
+ readonly appPages: string;
105
+ /** Plugins directory (`/app/plugins` by default) */
106
+ readonly appPlugins: string;
107
+ }
108
+ /**
109
+ * Get the resolved directory paths for all layers in a Nuxt application.
110
+ *
111
+ * Returns an array of LayerDirectories objects, ordered by layer priority:
112
+ * - The first layer is the user/project layer (highest priority)
113
+ * - Earlier layers override later layers in the array
114
+ * - Base layers appear last in the array (lowest priority)
115
+ *
116
+ * @param nuxt - The Nuxt instance to get layers from. Defaults to the current Nuxt context.
117
+ * @returns Array of LayerDirectories objects, ordered by priority (user layer first)
118
+ */
119
+ declare function getLayerDirectories(nuxt?: _nuxt_schema.Nuxt): LayerDirectories[];
120
+
71
121
  declare function addImports(imports: Import | Import[]): void;
72
122
  declare function addImportsDir(dirs: string | string[], opts?: {
73
123
  prepend?: boolean;
@@ -304,7 +354,12 @@ interface ResolvePathOptions {
304
354
  cwd?: string;
305
355
  /** An object of aliases. Default is Nuxt configured aliases. */
306
356
  alias?: Record<string, string>;
307
- /** The file extensions to try. Default is Nuxt configured extensions. */
357
+ /**
358
+ * The file extensions to try.
359
+ * Default is Nuxt configured extensions.
360
+ *
361
+ * Isn't considered when `type` is set to `'dir'`.
362
+ */
308
363
  extensions?: string[];
309
364
  /**
310
365
  * Whether to resolve files that exist in the Nuxt VFS (for example, as a Nuxt template).
@@ -313,21 +368,26 @@ interface ResolvePathOptions {
313
368
  virtual?: boolean;
314
369
  /**
315
370
  * Whether to fallback to the original path if the resolved path does not exist instead of returning the normalized input path.
316
- *
317
371
  * @default false
318
372
  */
319
373
  fallbackToOriginal?: boolean;
374
+ /**
375
+ * The type of the path to be resolved.
376
+ * @default 'file'
377
+ */
378
+ type?: PathType;
320
379
  }
321
380
  /**
322
- * Resolve full path to a file or directory respecting Nuxt alias and extensions options
381
+ * Resolve the full path to a file or a directory (based on the provided type), respecting Nuxt alias and extensions options.
323
382
  *
324
- * If path could not be resolved, normalized input path will be returned
383
+ * If a path cannot be resolved, normalized input will be returned unless the `fallbackToOriginal` option is set to `true`,
384
+ * in which case the original input path will be returned.
325
385
  */
326
386
  declare function resolvePath(path: string, opts?: ResolvePathOptions): Promise<string>;
327
387
  /**
328
388
  * Try to resolve first existing file in paths
329
389
  */
330
- declare function findPath(paths: string | string[], opts?: ResolvePathOptions, pathType?: 'file' | 'dir'): Promise<string | null>;
390
+ declare function findPath(paths: string | string[], opts?: ResolvePathOptions, pathType?: PathType): Promise<string | null>;
331
391
  /**
332
392
  * Resolve path aliases respecting Nuxt alias options
333
393
  */
@@ -341,8 +401,16 @@ interface Resolver {
341
401
  */
342
402
  declare function createResolver(base: string | URL): Resolver;
343
403
  declare function resolveNuxtModule(base: string, paths: string[]): Promise<string[]>;
404
+ type PathType = 'file' | 'dir';
405
+ /**
406
+ * Resolve absolute file paths in the provided directory with respect to `.nuxtignore` and return them sorted.
407
+ * @param path path to the directory to resolve files in
408
+ * @param pattern glob pattern or an array of glob patterns to match files
409
+ * @param opts options for globbing
410
+ */
344
411
  declare function resolveFiles(path: string, pattern: string | string[], opts?: {
345
412
  followSymbolicLinks?: boolean;
413
+ ignore?: GlobOptions['ignore'];
346
414
  }): Promise<string[]>;
347
415
 
348
416
  /**
@@ -475,5 +543,5 @@ declare const templateUtils: {
475
543
  }) => string;
476
544
  };
477
545
 
478
- 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, compileTemplate, createIsIgnored, createResolver, defineNuxtModule, directoryToURL, extendNuxtSchema, extendPages, extendRouteRules, extendRspackConfig, extendViteConfig, extendWebpackConfig, findPath, getDirectory, getNuxtCtx, getNuxtModuleVersion, getNuxtVersion, hasNuxtCompatibility, hasNuxtModule, hasNuxtModuleCompatibility, importModule, installModule, isIgnored, isNuxt2, isNuxt3, isNuxtMajorVersion, loadNuxt, loadNuxtConfig, loadNuxtModuleInstance, logger, normalizeModuleTranspilePath, normalizePlugin, normalizeSemanticVersion, normalizeTemplate, nuxtCtx, requireModule, resolveAlias, resolveFiles, resolveIgnorePatterns, resolveModule, resolveNuxtModule, resolvePath, runWithNuxtContext, templateUtils, tryImportModule, tryRequireModule, tryResolveModule, tryUseNuxt, updateRuntimeConfig, updateTemplates, useLogger, useNitro, useNuxt, useRuntimeConfig, writeTypes };
479
- export type { AddComponentOptions, AddPluginOptions, AddRouteMiddlewareOptions, ExtendConfigOptions, ExtendRouteRulesOptions, ExtendViteConfigOptions, ExtendWebpackConfigOptions, ImportModuleOptions, LoadNuxtConfigOptions, LoadNuxtOptions, ResolveModuleOptions, ResolvePathOptions, Resolver };
546
+ 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, compileTemplate, 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, templateUtils, tryImportModule, tryRequireModule, tryResolveModule, tryUseNuxt, updateRuntimeConfig, updateTemplates, useLogger, useNitro, useNuxt, useRuntimeConfig, writeTypes };
547
+ export type { AddComponentOptions, AddPluginOptions, AddRouteMiddlewareOptions, ExtendConfigOptions, ExtendRouteRulesOptions, ExtendViteConfigOptions, ExtendWebpackConfigOptions, ImportModuleOptions, LayerDirectories, LoadNuxtConfigOptions, LoadNuxtOptions, ResolveModuleOptions, ResolvePathOptions, Resolver };
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ import { promises, existsSync, readFileSync, lstatSync } from 'node:fs';
2
2
  import { performance } from 'node:perf_hooks';
3
3
  import defu$1, { defu } from 'defu';
4
4
  import { applyDefaults } from 'untyped';
5
- import { dirname, relative, join, resolve, normalize, isAbsolute, basename, parse } from 'pathe';
5
+ import { dirname, resolve, relative, join, normalize, isAbsolute, basename, parse } from 'pathe';
6
6
  import { consola } from 'consola';
7
7
  import { AsyncLocalStorage } from 'node:async_hooks';
8
8
  import { getContext, createContext } from 'unctx';
@@ -13,7 +13,9 @@ import { pathToFileURL, fileURLToPath } from 'node:url';
13
13
  import { createJiti } from 'jiti';
14
14
  import { interopDefault, parseNodeModulePath, resolveModuleExportNames } from 'mlly';
15
15
  import { resolveModulePath, resolveModuleURL } from 'exsolve';
16
- import { isRelative, withTrailingSlash } from 'ufo';
16
+ import { isRelative, withTrailingSlash as withTrailingSlash$2 } from 'ufo';
17
+ import { read, update } from 'rc9';
18
+ import semver, { gte } from 'semver';
17
19
  import { glob } from 'tinyglobby';
18
20
  import { resolveAlias as resolveAlias$1, reverseResolveAlias } from 'pathe/utils';
19
21
  import ignore from 'ignore';
@@ -23,7 +25,6 @@ import destr from 'destr';
23
25
  import { snakeCase, pascalCase, kebabCase } from 'scule';
24
26
  import { klona } from 'klona';
25
27
  import { hash } from 'ohash';
26
- import { gte } from 'semver';
27
28
  import { captureStackTrace } from 'errx';
28
29
  import { isAbsolute as isAbsolute$1 } from 'node:path';
29
30
 
@@ -76,7 +77,7 @@ async function checkNuxtCompatibility(constraints, nuxt = useNuxt()) {
76
77
  });
77
78
  }
78
79
  }
79
- if (isNuxt2(nuxt)) {
80
+ if (isNuxtMajorVersion(2, nuxt)) {
80
81
  const bridgeRequirement = constraints.bridge;
81
82
  const hasBridge = !!nuxt.options.bridge;
82
83
  if (bridgeRequirement === true && !hasBridge) {
@@ -2099,7 +2100,7 @@ async function compileTemplate(template$1, ctx) {
2099
2100
  }
2100
2101
  throw new Error("Invalid template: " + JSON.stringify(template$1));
2101
2102
  }
2102
- const serialize = (data) => JSON.stringify(data, null, 2).replace(/"\{(.+)\}"(?=,?$)/gm, (r) => JSON.parse(r).replace(/^\{(.*)\}$/, "$1"));
2103
+ const serialize = (data) => JSON.stringify(data, null, 2).replace(/"\{.+\}"(?=,?$)/gm, (r) => JSON.parse(r).replace(/^\{(.*)\}$/, "$1"));
2103
2104
  const importSources = (sources, { lazy = false } = {}) => {
2104
2105
  return toArray(sources).map((src) => {
2105
2106
  const safeVariableName = genSafeVariableName(src);
@@ -2136,6 +2137,12 @@ function _defineNuxtModule(definition) {
2136
2137
  }
2137
2138
  return Promise.resolve(options);
2138
2139
  }
2140
+ function getModuleDependencies(nuxt = useNuxt()) {
2141
+ if (typeof module.moduleDependencies === "function") {
2142
+ return module.moduleDependencies(nuxt);
2143
+ }
2144
+ return module.moduleDependencies;
2145
+ }
2139
2146
  async function normalizedModule(inlineOptions, nuxt) {
2140
2147
  nuxt ||= tryUseNuxt() || this.nuxt;
2141
2148
  const uniqueKey = module.meta.name || module.meta.configKey;
@@ -2185,11 +2192,14 @@ ${issues.toString()}`;
2185
2192
  }
2186
2193
  normalizedModule.getMeta = () => Promise.resolve(module.meta);
2187
2194
  normalizedModule.getOptions = getOptions;
2195
+ normalizedModule.getModuleDependencies = getModuleDependencies;
2196
+ normalizedModule.onInstall = module.onInstall;
2197
+ normalizedModule.onUpgrade = module.onUpgrade;
2188
2198
  return normalizedModule;
2189
2199
  }
2190
2200
  const NUXT2_SHIMS_KEY = "__nuxt2_shims_key__";
2191
2201
  function nuxt2Shims(nuxt) {
2192
- if (!isNuxt2(nuxt) || nuxt[NUXT2_SHIMS_KEY]) {
2202
+ if (!isNuxtMajorVersion(2, nuxt) || nuxt[NUXT2_SHIMS_KEY]) {
2193
2203
  return;
2194
2204
  }
2195
2205
  nuxt[NUXT2_SHIMS_KEY] = true;
@@ -2208,6 +2218,7 @@ function nuxt2Shims(nuxt) {
2208
2218
  nuxt.hook("build:templates", async (templates) => {
2209
2219
  const context = {
2210
2220
  nuxt,
2221
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
2211
2222
  utils: templateUtils,
2212
2223
  app: {
2213
2224
  dir: nuxt.options.srcDir,
@@ -2240,6 +2251,7 @@ function tryResolveModule(id, url = import.meta.url) {
2240
2251
  }
2241
2252
  function resolveModule(id, options) {
2242
2253
  return resolveModulePath(id, {
2254
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
2243
2255
  from: options?.url ?? options?.paths ?? [import.meta.url],
2244
2256
  extensions: [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"]
2245
2257
  });
@@ -2273,6 +2285,39 @@ function tryRequireModule(id, opts) {
2273
2285
  }
2274
2286
  }
2275
2287
 
2288
+ const layerMap = /* @__PURE__ */ new WeakMap();
2289
+ function getLayerDirectories(nuxt = useNuxt()) {
2290
+ return nuxt.options._layers.map((layer) => {
2291
+ if (layerMap.has(layer)) {
2292
+ return layerMap.get(layer);
2293
+ }
2294
+ const isRoot = withTrailingSlash$1(layer.config.rootDir) === withTrailingSlash$1(nuxt.options.rootDir);
2295
+ const config = isRoot ? nuxt.options : layer.config;
2296
+ const src = withTrailingSlash$1(config.srcDir || layer.cwd);
2297
+ const root = withTrailingSlash$1(config.rootDir || layer.cwd);
2298
+ const directories = {
2299
+ root,
2300
+ shared: withTrailingSlash$1(resolve(root, resolveAlias(config.dir?.shared || "shared", nuxt.options.alias))),
2301
+ // these are resolved relative to root in `@nuxt/schema` for v4+
2302
+ // so resolving relative to `src` covers backward compatibility for v3
2303
+ server: withTrailingSlash$1(resolve(src, resolveAlias(config.serverDir || "server", nuxt.options.alias))),
2304
+ modules: withTrailingSlash$1(resolve(src, resolveAlias(config.dir?.modules || "modules", nuxt.options.alias))),
2305
+ public: withTrailingSlash$1(resolve(src, config.dir?.public || "public")),
2306
+ // nuxt app
2307
+ app: src,
2308
+ appLayouts: withTrailingSlash$1(resolve(src, resolveAlias(config.dir?.layouts || "layouts", nuxt.options.alias))),
2309
+ appMiddleware: withTrailingSlash$1(resolve(src, resolveAlias(config.dir?.middleware || "middleware", nuxt.options.alias))),
2310
+ appPages: withTrailingSlash$1(resolve(src, resolveAlias(config.dir?.pages || "pages", nuxt.options.alias))),
2311
+ appPlugins: withTrailingSlash$1(resolve(src, resolveAlias(config.dir?.plugins || "plugins", nuxt.options.alias)))
2312
+ };
2313
+ layerMap.set(layer, directories);
2314
+ return directories;
2315
+ });
2316
+ }
2317
+ function withTrailingSlash$1(dir) {
2318
+ return dir.replace(/[^/]$/, "$&/");
2319
+ }
2320
+
2276
2321
  function createIsIgnored(nuxt = tryUseNuxt()) {
2277
2322
  return (pathname, stats) => isIgnored(pathname, stats, nuxt);
2278
2323
  }
@@ -2284,8 +2329,8 @@ function isIgnored(pathname, _stats, nuxt = tryUseNuxt()) {
2284
2329
  nuxt._ignore = ignore(nuxt.options.ignoreOptions);
2285
2330
  nuxt._ignore.add(resolveIgnorePatterns());
2286
2331
  }
2287
- const cwds = nuxt.options._layers?.map((layer2) => layer2.cwd).sort((a, b) => b.length - a.length);
2288
- const layer = cwds?.find((cwd) => pathname.startsWith(cwd));
2332
+ const cwds = getLayerDirectories(nuxt).map((dirs) => dirs.root).sort((a, b) => b.length - a.length);
2333
+ const layer = cwds.find((cwd) => pathname.startsWith(cwd));
2289
2334
  const relativePath = relative(layer ?? nuxt.options.rootDir, pathname);
2290
2335
  if (relativePath[0] === "." && relativePath[1] === ".") {
2291
2336
  return false;
@@ -2331,15 +2376,20 @@ function resolveGroupSyntax(group) {
2331
2376
  }
2332
2377
 
2333
2378
  async function resolvePath(path, opts = {}) {
2334
- const res = await _resolvePathGranularly(path, opts);
2335
- if (res.type === "file") {
2379
+ const { type = "file" } = opts;
2380
+ const res = await _resolvePathGranularly(path, { ...opts, type });
2381
+ if (res.type === type) {
2336
2382
  return res.path;
2337
2383
  }
2338
2384
  return opts.fallbackToOriginal ? path : res.path;
2339
2385
  }
2340
2386
  async function findPath(paths, opts, pathType = "file") {
2341
2387
  for (const path of toArray(paths)) {
2342
- const res = await _resolvePathGranularly(path, opts);
2388
+ const res = await _resolvePathGranularly(path, {
2389
+ ...opts,
2390
+ // TODO: this is for backwards compatibility, remove the `pathType` argument in Nuxt 5
2391
+ type: opts?.type || pathType
2392
+ });
2343
2393
  if (!res.type || pathType && res.type !== pathType) {
2344
2394
  continue;
2345
2395
  }
@@ -2410,12 +2460,15 @@ async function _resolvePathType(path, opts = {}, skipFs = false) {
2410
2460
  fd?.close();
2411
2461
  }
2412
2462
  }
2413
- async function _resolvePathGranularly(path, opts = {}) {
2463
+ function normalizeExtension(ext) {
2464
+ return ext.startsWith(".") ? ext : `.${ext}`;
2465
+ }
2466
+ async function _resolvePathGranularly(path, opts = { type: "file" }) {
2414
2467
  const _path = path;
2415
2468
  path = normalize(path);
2416
2469
  if (isAbsolute(path)) {
2417
2470
  const res2 = await _resolvePathType(path, opts);
2418
- if (res2 && res2.type === "file") {
2471
+ if (res2 && res2.type === opts.type) {
2419
2472
  return res2;
2420
2473
  }
2421
2474
  }
@@ -2428,36 +2481,39 @@ async function _resolvePathGranularly(path, opts = {}) {
2428
2481
  path = resolve(cwd, path);
2429
2482
  }
2430
2483
  const res = await _resolvePathType(path, opts);
2431
- if (res && res.type === "file") {
2484
+ if (res && res.type === opts.type) {
2432
2485
  return res;
2433
2486
  }
2434
- for (const ext of extensions) {
2435
- const extPath = await _resolvePathType(path + ext, opts);
2436
- if (extPath && extPath.type === "file") {
2437
- return extPath;
2487
+ if (opts.type === "file") {
2488
+ for (const ext of extensions) {
2489
+ const normalizedExt = normalizeExtension(ext);
2490
+ const extPath = await _resolvePathType(path + normalizedExt, opts);
2491
+ if (extPath && extPath.type === "file") {
2492
+ return extPath;
2493
+ }
2494
+ const indexPath = await _resolvePathType(
2495
+ join(path, "index" + normalizedExt),
2496
+ opts,
2497
+ res?.type !== "dir"
2498
+ /* skip checking if parent is not a directory */
2499
+ );
2500
+ if (indexPath && indexPath.type === "file") {
2501
+ return indexPath;
2502
+ }
2438
2503
  }
2439
- const indexPath = await _resolvePathType(
2440
- join(path, "index" + ext),
2441
- opts,
2442
- res?.type !== "dir"
2443
- /* skip checking if parent is not a directory */
2444
- );
2445
- if (indexPath && indexPath.type === "file") {
2446
- return indexPath;
2504
+ const resolvedModulePath = resolveModulePath(_path, {
2505
+ try: true,
2506
+ suffixes: ["", "index"],
2507
+ from: [cwd, ...modulesDir].map((d) => directoryToURL(d))
2508
+ });
2509
+ if (resolvedModulePath) {
2510
+ return {
2511
+ path: resolvedModulePath,
2512
+ type: "file",
2513
+ virtual: false
2514
+ };
2447
2515
  }
2448
2516
  }
2449
- const resolvedModulePath = resolveModulePath(_path, {
2450
- try: true,
2451
- suffixes: ["", "index"],
2452
- from: [cwd, ...modulesDir].map((d) => directoryToURL(d))
2453
- });
2454
- if (resolvedModulePath) {
2455
- return {
2456
- path: resolvedModulePath,
2457
- type: "file",
2458
- virtual: false
2459
- };
2460
- }
2461
2517
  return {
2462
2518
  path
2463
2519
  };
@@ -2478,7 +2534,7 @@ function existsInVFS(path, nuxt = tryUseNuxt()) {
2478
2534
  }
2479
2535
  async function resolveFiles(path, pattern, opts = {}) {
2480
2536
  const files = [];
2481
- for (const p of await glob(pattern, { cwd: path, followSymbolicLinks: opts.followSymbolicLinks ?? true, absolute: true })) {
2537
+ for (const p of await glob(pattern, { cwd: path, followSymbolicLinks: opts.followSymbolicLinks ?? true, absolute: true, ignore: opts.ignore })) {
2482
2538
  if (!isIgnored(p)) {
2483
2539
  files.push(p);
2484
2540
  }
@@ -2487,8 +2543,7 @@ async function resolveFiles(path, pattern, opts = {}) {
2487
2543
  }
2488
2544
 
2489
2545
  const NODE_MODULES_RE = /[/\\]node_modules[/\\]/;
2490
- async function installModule(moduleToInstall, inlineOptions, nuxt = useNuxt()) {
2491
- const { nuxtModule, buildTimeModuleMeta, resolvedModulePath } = await loadNuxtModuleInstance(moduleToInstall, nuxt);
2546
+ async function installModules(modulesToInstall, resolvedModulePaths, nuxt = useNuxt()) {
2492
2547
  const localLayerModuleDirs = [];
2493
2548
  for (const l of nuxt.options._layers) {
2494
2549
  const srcDir = l.config.srcDir || l.cwd;
@@ -2496,43 +2551,132 @@ async function installModule(moduleToInstall, inlineOptions, nuxt = useNuxt()) {
2496
2551
  localLayerModuleDirs.push(resolve(srcDir, l.config?.dir?.modules || "modules").replace(/\/?$/, "/"));
2497
2552
  }
2498
2553
  }
2499
- const res = (isNuxt2() ? await nuxtModule.call(nuxt.moduleContainer, inlineOptions, nuxt) : nuxt.options.experimental?.debugModuleMutation && nuxt._asyncLocalStorageModule ? await nuxt._asyncLocalStorageModule.run(nuxtModule, () => nuxtModule(inlineOptions || {}, nuxt)) : await nuxtModule(inlineOptions || {}, nuxt)) ?? {};
2500
- if (res === false) {
2501
- return;
2554
+ const optionsFunctions = /* @__PURE__ */ new Map();
2555
+ const resolvedModules = [];
2556
+ const inlineConfigKeys = new Set(
2557
+ await Promise.all([...modulesToInstall].map(([mod]) => typeof mod !== "string" && Promise.resolve(mod.getMeta?.())?.then((r) => r?.configKey)))
2558
+ );
2559
+ let error;
2560
+ const dependencyMap = /* @__PURE__ */ new Map();
2561
+ for (const [key, options] of modulesToInstall) {
2562
+ const res = await loadNuxtModuleInstance(key, nuxt).catch((err) => {
2563
+ if (dependencyMap.has(key) && typeof key === "string") {
2564
+ err.cause = `Could not resolve \`${key}\` (specified as a dependency of ${dependencyMap.get(key)}).`;
2565
+ }
2566
+ throw err;
2567
+ });
2568
+ const dependencyMeta = res.nuxtModule.getModuleDependencies?.(nuxt) || {};
2569
+ for (const [name, value] of Object.entries(dependencyMeta)) {
2570
+ if (!value.overrides && !value.defaults && !value.version && value.optional) {
2571
+ continue;
2572
+ }
2573
+ const resolvedModule = resolveModuleWithOptions(name, nuxt);
2574
+ const moduleToAttribute = typeof key === "string" ? `\`${key}\`` : "a module in `nuxt.options`";
2575
+ if (!resolvedModule?.module) {
2576
+ const message = `Could not resolve \`${name}\` (specified as a dependency of ${moduleToAttribute}).`;
2577
+ error = new TypeError(message);
2578
+ continue;
2579
+ }
2580
+ if (value.version) {
2581
+ const resolvePaths = [res.resolvedModulePath, ...nuxt.options.modulesDir].filter(Boolean);
2582
+ const pkg = await readPackageJSON(name, { from: resolvePaths }).catch(() => null);
2583
+ if (pkg?.version && !semver.satisfies(pkg.version, value.version)) {
2584
+ const message = `Module \`${name}\` version (\`${pkg.version}\`) does not satisfy \`${value.version}\` (requested by ${moduleToAttribute}).`;
2585
+ error = new TypeError(message);
2586
+ }
2587
+ }
2588
+ if (value.overrides || value.defaults) {
2589
+ const currentFns = optionsFunctions.get(resolvedModule.module) || [];
2590
+ optionsFunctions.set(resolvedModule.module, [
2591
+ ...currentFns,
2592
+ () => ({ defaults: value.defaults, overrides: value.overrides })
2593
+ ]);
2594
+ }
2595
+ if (value.optional === true) {
2596
+ continue;
2597
+ }
2598
+ if (resolvedModule && !modulesToInstall.has(resolvedModule.module) && (!resolvedModule.resolvedPath || !resolvedModulePaths.has(resolvedModule.resolvedPath))) {
2599
+ if (typeof resolvedModule.module === "string" && inlineConfigKeys.has(resolvedModule.module)) {
2600
+ continue;
2601
+ }
2602
+ modulesToInstall.set(resolvedModule.module, resolvedModule.options);
2603
+ dependencyMap.set(resolvedModule.module, moduleToAttribute);
2604
+ const path = resolvedModule.resolvedPath || resolvedModule.module;
2605
+ if (typeof path === "string") {
2606
+ resolvedModulePaths.add(path);
2607
+ }
2608
+ }
2609
+ }
2610
+ resolvedModules.push({
2611
+ moduleToInstall: key,
2612
+ meta: await res.nuxtModule.getMeta?.(),
2613
+ nuxtModule: res.nuxtModule,
2614
+ buildTimeModuleMeta: res.buildTimeModuleMeta,
2615
+ resolvedModulePath: res.resolvedModulePath,
2616
+ inlineOptions: options
2617
+ });
2502
2618
  }
2503
- const modulePath = resolvedModulePath || moduleToInstall;
2504
- if (typeof modulePath === "string") {
2505
- const parsed = parseNodeModulePath(modulePath);
2506
- const moduleRoot = parsed.dir ? parsed.dir + parsed.name : await resolvePackageJSON(modulePath, { try: true }).then((r) => r ? dirname(r) : modulePath);
2507
- nuxt.options.build.transpile.push(normalizeModuleTranspilePath(moduleRoot));
2508
- const directory = moduleRoot.replace(/\/?$/, "/");
2509
- if (moduleRoot !== moduleToInstall && !localLayerModuleDirs.some((dir) => directory.startsWith(dir))) {
2510
- nuxt.options.modulesDir.push(join(moduleRoot, "node_modules"));
2619
+ if (error) {
2620
+ throw error;
2621
+ }
2622
+ for (const { nuxtModule, meta, moduleToInstall, buildTimeModuleMeta, resolvedModulePath, inlineOptions } of resolvedModules) {
2623
+ const configKey = meta?.configKey;
2624
+ if (configKey) {
2625
+ const optionsFns = [
2626
+ ...optionsFunctions.get(moduleToInstall) || [],
2627
+ ...optionsFunctions.get(configKey) || []
2628
+ ];
2629
+ if (optionsFns.length > 0) {
2630
+ const overrides = [];
2631
+ const defaults = [];
2632
+ for (const fn of optionsFns) {
2633
+ const options = fn();
2634
+ overrides.push(options.overrides);
2635
+ defaults.push(options.defaults);
2636
+ }
2637
+ nuxt.options[configKey] = defu(...overrides, nuxt.options[configKey], ...defaults);
2638
+ }
2511
2639
  }
2640
+ await callLifecycleHooks(nuxtModule, meta, inlineOptions, nuxt);
2641
+ await callModule(nuxtModule, meta, inlineOptions, resolvedModulePath, moduleToInstall, localLayerModuleDirs, buildTimeModuleMeta, nuxt);
2512
2642
  }
2513
- nuxt.options._installedModules ||= [];
2514
- const entryPath = typeof moduleToInstall === "string" ? resolveAlias(moduleToInstall) : void 0;
2515
- if (typeof moduleToInstall === "string" && entryPath !== moduleToInstall) {
2516
- buildTimeModuleMeta.rawPath = moduleToInstall;
2643
+ }
2644
+ async function installModule(moduleToInstall, inlineOptions, nuxt = useNuxt()) {
2645
+ const { nuxtModule, buildTimeModuleMeta, resolvedModulePath } = await loadNuxtModuleInstance(moduleToInstall, nuxt);
2646
+ const localLayerModuleDirs = [];
2647
+ for (const dirs of getLayerDirectories(nuxt)) {
2648
+ if (!NODE_MODULES_RE.test(dirs.app)) {
2649
+ localLayerModuleDirs.push(dirs.modules);
2650
+ }
2517
2651
  }
2518
- nuxt.options._installedModules.push({
2519
- meta: defu(await nuxtModule.getMeta?.(), buildTimeModuleMeta),
2520
- module: nuxtModule,
2521
- timings: res.timings,
2522
- entryPath
2523
- });
2652
+ const meta = await nuxtModule.getMeta?.();
2653
+ await callLifecycleHooks(nuxtModule, meta, inlineOptions, nuxt);
2654
+ await callModule(nuxtModule, meta, inlineOptions, resolvedModulePath, moduleToInstall, localLayerModuleDirs, buildTimeModuleMeta, nuxt);
2524
2655
  }
2525
- function getDirectory(p) {
2526
- try {
2527
- return isAbsolute(p) && lstatSync(p).isFile() ? dirname(p) : p;
2528
- } catch {
2656
+ function resolveModuleWithOptions(definition, nuxt) {
2657
+ const [module, options = {}] = Array.isArray(definition) ? definition : [definition, {}];
2658
+ if (!module) {
2659
+ return;
2529
2660
  }
2530
- return p;
2661
+ if (typeof module !== "string") {
2662
+ return {
2663
+ module,
2664
+ options
2665
+ };
2666
+ }
2667
+ const modAlias = resolveAlias(module, nuxt.options.alias);
2668
+ const modPath = resolveModulePath(modAlias, {
2669
+ try: true,
2670
+ from: nuxt.options.modulesDir.map((m) => directoryToURL(m.replace(/\/node_modules\/?$/, "/"))),
2671
+ suffixes: ["nuxt", "nuxt/index", "module", "module/index", "", "index"],
2672
+ extensions: [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"]
2673
+ });
2674
+ return {
2675
+ module,
2676
+ resolvedPath: modPath || modAlias,
2677
+ options
2678
+ };
2531
2679
  }
2532
- const normalizeModuleTranspilePath = (p) => {
2533
- return getDirectory(p).split("node_modules/").pop();
2534
- };
2535
- const MissingModuleMatcher = /Cannot find module\s+['"]?([^'")\s]+)['"]?/i;
2536
2680
  async function loadNuxtModuleInstance(nuxtModule, nuxt = useNuxt()) {
2537
2681
  let buildTimeModuleMeta = {};
2538
2682
  if (typeof nuxtModule === "function") {
@@ -2579,6 +2723,71 @@ async function loadNuxtModuleInstance(nuxtModule, nuxt = useNuxt()) {
2579
2723
  }
2580
2724
  throw new TypeError(`Could not load \`${nuxtModule}\`. Is it installed?`);
2581
2725
  }
2726
+ function getDirectory(p) {
2727
+ try {
2728
+ return isAbsolute(p) && lstatSync(p).isFile() ? dirname(p) : p;
2729
+ } catch {
2730
+ }
2731
+ return p;
2732
+ }
2733
+ const normalizeModuleTranspilePath = (p) => {
2734
+ return getDirectory(p).split("node_modules/").pop();
2735
+ };
2736
+ const MissingModuleMatcher = /Cannot find module\s+['"]?([^'")\s]+)['"]?/i;
2737
+ async function callLifecycleHooks(nuxtModule, meta = {}, inlineOptions, nuxt = useNuxt()) {
2738
+ if (!meta.name || !meta.version) {
2739
+ return;
2740
+ }
2741
+ if (!nuxtModule.onInstall && !nuxtModule.onUpgrade) {
2742
+ return;
2743
+ }
2744
+ const rc = read({ dir: nuxt.options.rootDir, name: ".nuxtrc" });
2745
+ const previousVersion = rc?.setups?.[meta.name];
2746
+ try {
2747
+ if (!previousVersion) {
2748
+ await nuxtModule.onInstall?.(nuxt);
2749
+ } else if (semver.gt(meta.version, previousVersion)) {
2750
+ await nuxtModule.onUpgrade?.(inlineOptions, nuxt, previousVersion);
2751
+ }
2752
+ if (previousVersion !== meta.version) {
2753
+ update(
2754
+ { setups: { [meta.name]: meta?.version } },
2755
+ { dir: nuxt.options.rootDir, name: ".nuxtrc" }
2756
+ );
2757
+ }
2758
+ } catch (e) {
2759
+ logger.error(
2760
+ `Error while executing ${!previousVersion ? "install" : "upgrade"} hook for module \`${meta.name}\`: ${e}`
2761
+ );
2762
+ }
2763
+ }
2764
+ async function callModule(nuxtModule, meta = {}, inlineOptions, resolvedModulePath, moduleToInstall, localLayerModuleDirs, buildTimeModuleMeta, nuxt = useNuxt()) {
2765
+ const res = (isNuxtMajorVersion(2, nuxt) ? await nuxtModule.call(nuxt.moduleContainer, inlineOptions, nuxt) : nuxt.options.experimental?.debugModuleMutation && nuxt._asyncLocalStorageModule ? await nuxt._asyncLocalStorageModule.run(nuxtModule, () => nuxtModule(inlineOptions || {}, nuxt)) : await nuxtModule(inlineOptions || {}, nuxt)) ?? {};
2766
+ if (res === false) {
2767
+ return;
2768
+ }
2769
+ const modulePath = resolvedModulePath || moduleToInstall;
2770
+ if (typeof modulePath === "string") {
2771
+ const parsed = parseNodeModulePath(modulePath);
2772
+ const moduleRoot = parsed.dir ? parsed.dir + parsed.name : await resolvePackageJSON(modulePath, { try: true }).then((r) => r ? dirname(r) : modulePath);
2773
+ nuxt.options.build.transpile.push(normalizeModuleTranspilePath(moduleRoot));
2774
+ const directory = moduleRoot.replace(/\/?$/, "/");
2775
+ if (moduleRoot !== moduleToInstall && !localLayerModuleDirs.some((dir) => directory.startsWith(dir))) {
2776
+ nuxt.options.modulesDir.push(join(moduleRoot, "node_modules"));
2777
+ }
2778
+ }
2779
+ nuxt.options._installedModules ||= [];
2780
+ const entryPath = typeof moduleToInstall === "string" ? resolveAlias(moduleToInstall, nuxt.options.alias) : void 0;
2781
+ if (typeof moduleToInstall === "string" && entryPath !== moduleToInstall) {
2782
+ buildTimeModuleMeta.rawPath = moduleToInstall;
2783
+ }
2784
+ nuxt.options._installedModules.push({
2785
+ meta: defu(meta, buildTimeModuleMeta),
2786
+ module: nuxtModule,
2787
+ timings: res.timings,
2788
+ entryPath
2789
+ });
2790
+ }
2582
2791
 
2583
2792
  function resolveNuxtModuleEntryName(m) {
2584
2793
  if (typeof m === "object" && !Array.isArray(m)) {
@@ -2623,14 +2832,17 @@ async function getNuxtModuleVersion(module, nuxt = useNuxt()) {
2623
2832
  }
2624
2833
 
2625
2834
  async function loadNuxtConfig(opts) {
2626
- const localLayers = (await glob("layers/*", { onlyDirectories: true, cwd: opts.cwd || process.cwd() })).map((d) => d.endsWith("/") ? d.substring(0, d.length - 1) : d);
2835
+ const localLayers = (await glob("layers/*", {
2836
+ onlyDirectories: true,
2837
+ cwd: opts.cwd || process.cwd()
2838
+ })).map((d) => d.endsWith("/") ? d.substring(0, d.length - 1) : d).sort((a, b) => b.localeCompare(a));
2627
2839
  opts.overrides = defu$1(opts.overrides, { _extends: localLayers });
2628
2840
  globalThis.defineNuxtConfig = (c) => c;
2629
2841
  const { configFile, layers = [], cwd, config: nuxtConfig, meta } = await loadConfig({
2630
2842
  name: "nuxt",
2631
2843
  configFile: "nuxt.config",
2632
2844
  rcFile: ".nuxtrc",
2633
- extend: { extendKey: ["theme", "extends", "_extends"] },
2845
+ extend: { extendKey: ["theme", "_extends", "extends"] },
2634
2846
  dotenv: true,
2635
2847
  globalRc: true,
2636
2848
  ...opts
@@ -2643,7 +2855,7 @@ async function loadNuxtConfig(opts) {
2643
2855
  nuxtConfig.alias ||= {};
2644
2856
  if (meta?.name) {
2645
2857
  const alias = `#layers/${meta.name}`;
2646
- nuxtConfig.alias[alias] ||= withTrailingSlash(nuxtConfig.rootDir);
2858
+ nuxtConfig.alias[alias] ||= withTrailingSlash$2(nuxtConfig.rootDir);
2647
2859
  }
2648
2860
  const defaultBuildDir = join(nuxtConfig.rootDir, ".nuxt");
2649
2861
  if (!opts.overrides?._prepare && !nuxtConfig.dev && !nuxtConfig.buildDir && nuxtConfig.future?.compatibilityVersion === 4 && existsSync(defaultBuildDir)) {
@@ -2677,7 +2889,7 @@ async function loadNuxtConfig(opts) {
2677
2889
  }
2678
2890
  if (layer.meta?.name) {
2679
2891
  const alias = `#layers/${layer.meta.name}`;
2680
- nuxtConfig.alias[alias] ||= withTrailingSlash(layer.config.rootDir || layer.cwd);
2892
+ nuxtConfig.alias[alias] ||= withTrailingSlash$2(layer.config.rootDir || layer.cwd);
2681
2893
  }
2682
2894
  _layers.push(layer);
2683
2895
  }
@@ -3094,6 +3306,11 @@ function addTypeTemplate(_template, context) {
3094
3306
  nuxt.hook("prepare:types", ({ references }) => {
3095
3307
  references.push({ path: template.dst });
3096
3308
  });
3309
+ nuxt.options.vite.vue = defu(nuxt.options.vite.vue, {
3310
+ script: {
3311
+ globalTypeFiles: [template.dst]
3312
+ }
3313
+ });
3097
3314
  }
3098
3315
  if (context?.nitro) {
3099
3316
  nuxt.hook("nitro:prepare:types", ({ references }) => {
@@ -3140,6 +3357,7 @@ const excludedAlias = [/^@vue\/.*$/, /^#internal\/nuxt/];
3140
3357
  async function _generateTypes(nuxt) {
3141
3358
  const rootDirWithSlash = withTrailingSlash(nuxt.options.rootDir);
3142
3359
  const relativeRootDir = relativeWithDot(nuxt.options.buildDir, nuxt.options.rootDir);
3360
+ const layerDirs = getLayerDirectories(nuxt);
3143
3361
  const include = /* @__PURE__ */ new Set([
3144
3362
  join(relativeRootDir, "**/*"),
3145
3363
  join(relativeRootDir, ".config/nuxt.*"),
@@ -3151,10 +3369,9 @@ async function _generateTypes(nuxt) {
3151
3369
  if (nuxt.options.typescript.includeWorkspace && nuxt.options.workspaceDir !== nuxt.options.rootDir) {
3152
3370
  include.add(join(relative(nuxt.options.buildDir, nuxt.options.workspaceDir), "**/*"));
3153
3371
  }
3154
- for (const layer of nuxt.options._layers) {
3155
- const srcOrCwd = layer.config.srcDir ?? layer.cwd;
3156
- if (!srcOrCwd.startsWith(rootDirWithSlash) || srcOrCwd.includes("node_modules")) {
3157
- include.add(join(relative(nuxt.options.buildDir, srcOrCwd), "**/*"));
3372
+ for (const dirs of layerDirs) {
3373
+ if (!dirs.app.startsWith(rootDirWithSlash) || dirs.app.includes("node_modules")) {
3374
+ include.add(join(relative(nuxt.options.buildDir, dirs.app), "**/*"));
3158
3375
  }
3159
3376
  }
3160
3377
  const exclude = /* @__PURE__ */ new Set([
@@ -3163,8 +3380,11 @@ async function _generateTypes(nuxt) {
3163
3380
  // nitro generate .data in development when kv storage is used
3164
3381
  relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, ".data"))
3165
3382
  ]);
3383
+ const sourceDirs = layerDirs.map((d) => d.app);
3166
3384
  for (const dir of nuxt.options.modulesDir) {
3167
- exclude.add(relativeWithDot(nuxt.options.buildDir, dir));
3385
+ if (!sourceDirs.some((srcDir) => dir.startsWith(srcDir))) {
3386
+ exclude.add(relativeWithDot(nuxt.options.buildDir, dir));
3387
+ }
3168
3388
  }
3169
3389
  const moduleEntryPaths = [];
3170
3390
  for (const m of nuxt.options._installedModules) {
@@ -3370,13 +3590,16 @@ const RELATIVE_WITH_DOT_RE = /^([^.])/;
3370
3590
  function relativeWithDot(from, to) {
3371
3591
  return relative(from, to).replace(RELATIVE_WITH_DOT_RE, "./$1") || ".";
3372
3592
  }
3593
+ function withTrailingSlash(dir) {
3594
+ return dir.replace(/[^/]$/, "$&/");
3595
+ }
3373
3596
 
3374
3597
  const LAYOUT_RE = /["']/g;
3375
3598
  function addLayout(template, name) {
3376
3599
  const nuxt = useNuxt();
3377
3600
  const { filename, src } = addTemplate(template);
3378
3601
  const layoutName = kebabCase(name || parse(filename).name).replace(LAYOUT_RE, "");
3379
- if (isNuxt2(nuxt)) {
3602
+ if (isNuxtMajorVersion(2, nuxt)) {
3380
3603
  const layout = nuxt.options.layouts[layoutName];
3381
3604
  if (layout) {
3382
3605
  return logger.warn(
@@ -3409,7 +3632,7 @@ const strippedAtAliases = {
3409
3632
 
3410
3633
  function extendPages(cb) {
3411
3634
  const nuxt = useNuxt();
3412
- if (isNuxt2(nuxt)) {
3635
+ if (isNuxtMajorVersion(2, nuxt)) {
3413
3636
  nuxt.hook("build:extendRoutes", cb);
3414
3637
  } else {
3415
3638
  nuxt.hook("pages:extend", cb);
@@ -3491,4 +3714,4 @@ function addPluginTemplate(plugin, opts = {}) {
3491
3714
  return addPlugin(normalizedPlugin, opts);
3492
3715
  }
3493
3716
 
3494
- 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, compileTemplate, createIsIgnored, createResolver, defineNuxtModule, directoryToURL, extendNuxtSchema, extendPages, extendRouteRules, extendRspackConfig, extendViteConfig, extendWebpackConfig, findPath, getDirectory, getNuxtCtx, getNuxtModuleVersion, getNuxtVersion, hasNuxtCompatibility, hasNuxtModule, hasNuxtModuleCompatibility, importModule, installModule, isIgnored, isNuxt2, isNuxt3, isNuxtMajorVersion, loadNuxt, loadNuxtConfig, loadNuxtModuleInstance, logger, normalizeModuleTranspilePath, normalizePlugin, normalizeSemanticVersion, normalizeTemplate, nuxtCtx, requireModule, resolveAlias, resolveFiles, resolveIgnorePatterns, resolveModule, resolveNuxtModule, resolvePath, runWithNuxtContext, templateUtils, tryImportModule, tryRequireModule, tryResolveModule, tryUseNuxt, updateRuntimeConfig, updateTemplates, useLogger, useNitro, useNuxt, useRuntimeConfig, writeTypes };
3717
+ 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, compileTemplate, 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, templateUtils, tryImportModule, tryRequireModule, tryResolveModule, tryUseNuxt, updateRuntimeConfig, updateTemplates, useLogger, useNitro, useNuxt, useRuntimeConfig, writeTypes };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/kit",
3
- "version": "3.18.1",
3
+ "version": "3.19.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/nuxt/nuxt.git",
@@ -33,10 +33,11 @@
33
33
  "jiti": "^2.5.1",
34
34
  "klona": "^2.0.6",
35
35
  "knitwork": "^1.2.0",
36
- "mlly": "^1.7.4",
36
+ "mlly": "^1.8.0",
37
37
  "ohash": "^2.0.11",
38
38
  "pathe": "^2.0.3",
39
- "pkg-types": "^2.2.0",
39
+ "pkg-types": "^2.3.0",
40
+ "rc9": "^2.1.2",
40
41
  "scule": "^1.3.0",
41
42
  "semver": "^7.7.2",
42
43
  "std-env": "^3.9.0",
@@ -47,17 +48,17 @@
47
48
  "untyped": "^2.0.0"
48
49
  },
49
50
  "devDependencies": {
50
- "@rspack/core": "1.4.11",
51
+ "@rspack/core": "1.5.2",
51
52
  "@types/lodash-es": "4.17.12",
52
53
  "@types/semver": "7.7.0",
53
54
  "hookable": "5.5.3",
54
55
  "lodash-es": "4.17.21",
55
56
  "nitropack": "2.12.4",
56
- "unbuild": "3.6.0",
57
- "vite": "7.0.6",
57
+ "unbuild": "3.6.1",
58
+ "vite": "7.1.4",
58
59
  "vitest": "3.2.4",
59
- "webpack": "5.101.0",
60
- "@nuxt/schema": "3.18.1"
60
+ "webpack": "5.101.3",
61
+ "@nuxt/schema": "3.19.0"
61
62
  },
62
63
  "engines": {
63
64
  "node": ">=18.12.0"