@depup/nuxt 4.2.2-depup.0 → 4.3.0-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +4 -2
  2. package/app.d.ts +1 -1
  3. package/dist/app/compat/capi.d.ts +1 -1
  4. package/dist/app/compat/interval.d.ts +1 -1
  5. package/dist/app/compat/interval.js +3 -3
  6. package/dist/app/components/client-fallback.client.js +5 -1
  7. package/dist/app/components/client-fallback.server.js +5 -1
  8. package/dist/app/components/error-404.d.vue.ts +6 -6
  9. package/dist/app/components/error-404.vue +4 -4
  10. package/dist/app/components/error-404.vue.d.ts +6 -6
  11. package/dist/app/components/error-500.d.vue.ts +6 -6
  12. package/dist/app/components/error-500.vue +4 -4
  13. package/dist/app/components/error-500.vue.d.ts +6 -6
  14. package/dist/app/components/island-renderer.js +2 -2
  15. package/dist/app/components/nuxt-error-page.vue +4 -4
  16. package/dist/app/components/nuxt-island.js +1 -1
  17. package/dist/app/components/nuxt-layout.js +6 -3
  18. package/dist/app/components/nuxt-link.js +1 -1
  19. package/dist/app/components/nuxt-stubs.d.ts +2 -2
  20. package/dist/app/components/nuxt-stubs.js +2 -2
  21. package/dist/app/components/welcome.vue +1 -1
  22. package/dist/app/composables/asyncData.d.ts +6 -1
  23. package/dist/app/composables/asyncData.js +8 -3
  24. package/dist/app/composables/component.js +1 -2
  25. package/dist/app/composables/cookie.js +8 -1
  26. package/dist/app/composables/error.d.ts +8 -5
  27. package/dist/app/composables/error.js +3 -0
  28. package/dist/app/composables/manifest.d.ts +3 -5
  29. package/dist/app/composables/manifest.js +6 -21
  30. package/dist/app/composables/payload.d.ts +4 -0
  31. package/dist/app/composables/payload.js +32 -14
  32. package/dist/app/composables/router.d.ts +7 -3
  33. package/dist/app/composables/router.js +7 -3
  34. package/dist/app/composables/script-stubs.js +2 -2
  35. package/dist/app/composables/ssr.d.ts +1 -1
  36. package/dist/app/entry.async.d.ts +2 -2
  37. package/dist/app/entry.d.ts +3 -2
  38. package/dist/app/entry.js +2 -2
  39. package/dist/app/index.d.ts +1 -1
  40. package/dist/app/middleware/{manifest-route-rule.js → route-rules.js} +2 -2
  41. package/dist/app/nuxt.d.ts +12 -9
  42. package/dist/app/plugins/dev-server-logs.js +1 -1
  43. package/dist/app/plugins/payload.client.js +0 -3
  44. package/dist/app/plugins/preload.server.js +3 -1
  45. package/dist/app/plugins/router.js +15 -16
  46. package/dist/app/types.d.ts +1 -1
  47. package/dist/app/utils.d.ts +6 -9
  48. package/dist/components/runtime/lazy-hydrated-component.js +2 -1
  49. package/dist/components/runtime/server-component.js +0 -1
  50. package/dist/head/runtime/components.js +70 -26
  51. package/dist/index.d.mts +1 -1
  52. package/dist/index.d.ts +1 -1
  53. package/dist/index.mjs +1004 -644
  54. package/dist/pages/runtime/composables.d.ts +10 -1
  55. package/dist/pages/runtime/index.d.ts +1 -1
  56. package/dist/pages/runtime/page.js +13 -3
  57. package/dist/pages/runtime/plugins/prerender.server.js +5 -10
  58. package/dist/pages/runtime/plugins/router.js +15 -18
  59. package/dist/pages/runtime/utils.d.ts +7 -0
  60. package/dist/pages/runtime/validate.js +4 -2
  61. package/meta.d.ts +1 -0
  62. package/meta.js +18 -0
  63. package/package.json +34 -49
  64. package/types.d.ts +1 -1
  65. /package/dist/app/middleware/{manifest-route-rule.d.ts → route-rules.d.ts} +0 -0
package/dist/index.mjs CHANGED
@@ -1,22 +1,22 @@
1
1
  import process from 'node:process';
2
- import fs, { promises, existsSync, readdirSync, statSync, mkdirSync, writeFileSync } from 'node:fs';
2
+ import fs, { statSync, promises, existsSync, readdirSync, mkdirSync, writeFileSync } from 'node:fs';
3
3
  import { mkdir, readFile, readdir, writeFile, rm, stat, unlink, open } from 'node:fs/promises';
4
4
  import { randomUUID } from 'node:crypto';
5
5
  import { AsyncLocalStorage } from 'node:async_hooks';
6
- import { dirname, resolve, normalize, basename, extname, relative, isAbsolute, join } from 'pathe';
6
+ import { dirname, resolve, normalize, basename, extname, relative, isAbsolute, join, parse as parse$1 } from 'pathe';
7
7
  import { createHooks, createDebugger } from 'hookable';
8
8
  import ignore from 'ignore';
9
- import { useLogger, tryUseNuxt, useNuxt, directoryToURL, getLayerDirectories, resolveFiles, resolvePath, defineNuxtModule, findPath, addPlugin, addTemplate, addTypeTemplate, addComponent, useNitro, addBuildPlugin, isIgnored, resolveAlias as resolveAlias$1, addPluginTemplate, addImportsSources, addVitePlugin, createIsIgnored, updateTemplates, tryResolveModule, normalizeModuleTranspilePath, importModule, createResolver, tryImportModule, runWithNuxtContext, nuxtCtx, loadNuxtConfig, addWebpackPlugin, installModules, resolveIgnorePatterns, addRouteMiddleware, resolveModuleWithOptions, normalizeTemplate, normalizePlugin } from '@nuxt/kit';
9
+ import { useLogger, tryUseNuxt, useNuxt, directoryToURL, getLayerDirectories, resolveFiles, resolvePath, defineNuxtModule, findPath, addPlugin, addTemplate, addTypeTemplate, addComponent, useNitro, addBuildPlugin, isIgnored, resolveAlias as resolveAlias$1, addPluginTemplate, addImportsSources, addVitePlugin, createIsIgnored, updateTemplates, tryResolveModule, normalizeModuleTranspilePath, importModule, createResolver, runWithNuxtContext, nuxtCtx, loadNuxtConfig, installModules, resolveIgnorePatterns, addRouteMiddleware, resolveModuleWithOptions, normalizeTemplate, normalizePlugin } from '@nuxt/kit';
10
10
  import { resolvePackageJSON, readPackage, readPackageJSON } from 'pkg-types';
11
11
  import { hash, isEqual, serialize } from 'ohash';
12
- import consola, { consola as consola$1 } from 'consola';
12
+ import { consola } from 'consola';
13
13
  import onChange from 'on-change';
14
14
  import { colors } from 'consola/utils';
15
15
  import { resolveCompatibilityDatesFromEnv, formatDate } from 'compatx';
16
16
  import escapeRE from 'escape-string-regexp';
17
- import { withTrailingSlash as withTrailingSlash$1, parseURL, parseQuery, joinURL, withLeadingSlash, encodePath, withoutLeadingSlash } from 'ufo';
17
+ import { withTrailingSlash as withTrailingSlash$1, parseURL, parseQuery, joinURL, withLeadingSlash, withoutLeadingSlash } from 'ufo';
18
18
  import { ImpoundPlugin } from 'impound';
19
- import defu$1, { defu } from 'defu';
19
+ import { defu } from 'defu';
20
20
  import { satisfies, coerce } from 'semver';
21
21
  import { isCI, provider, hasTTY } from 'std-env';
22
22
  import { genArrayFromRaw, genSafeVariableName, genImport, genDynamicImport, genObjectFromRawEntries, genString, genDynamicTypeImport, genExport } from 'knitwork';
@@ -25,7 +25,7 @@ import { addDependency } from 'nypm';
25
25
  import { reverseResolveAlias, filename, resolveAlias } from 'pathe/utils';
26
26
  import { createRoutesContext } from 'unplugin-vue-router';
27
27
  import { resolveOptions } from 'unplugin-vue-router/options';
28
- import { toRouteMatcher, createRouter } from 'radix3';
28
+ import { createRouter, addRoute, findAllRoutes } from 'rou3';
29
29
  import { fileURLToPath, pathToFileURL } from 'node:url';
30
30
  import { runInNewContext } from 'node:vm';
31
31
  import { klona } from 'klona';
@@ -37,7 +37,7 @@ import { createUnplugin } from 'unplugin';
37
37
  import { findStaticImports, findExports, parseStaticImport, parseNodeModulePath, lookupNodeModuleSubpath } from 'mlly';
38
38
  import MagicString from 'magic-string';
39
39
  import { unheadVueComposablesImports } from '@unhead/vue';
40
- import { defineUnimportPreset, createUnimport, toExports, scanDirExports } from 'unimport';
40
+ import { defineUnimportPreset, createUnimport, toExports, toTypeDeclarationFile, scanDirExports } from 'unimport';
41
41
  import { glob } from 'tinyglobby';
42
42
  import { parse, walk as walk$1, ELEMENT_NODE } from 'ultrahtml';
43
43
  import { isObject } from '@vue/shared';
@@ -56,9 +56,24 @@ import { parseTar, createTar } from 'nanotar';
56
56
  function toArray(value) {
57
57
  return Array.isArray(value) ? value : [value];
58
58
  }
59
- async function isDirectory$1(path) {
59
+ async function isDirectory(path) {
60
60
  return (await promises.lstat(path)).isDirectory();
61
61
  }
62
+ function isDirectorySync(path) {
63
+ try {
64
+ return statSync(path).isDirectory();
65
+ } catch {
66
+ return false;
67
+ }
68
+ }
69
+ function stripExtension(path) {
70
+ return path.replace(/\.[^./\\]+$/, "");
71
+ }
72
+ function isWhitespace(char) {
73
+ const c = typeof char === "string" ? char.charCodeAt(0) : char;
74
+ return c === 32 || c === 9 || c === 10 || c === 13 || c === 12;
75
+ }
76
+ const DECLARATION_EXTENSIONS = ["d.ts", "d.mts", "d.cts", "d.vue.ts", "d.vue.mts", "d.vue.cts"];
62
77
  const logger = useLogger("nuxt");
63
78
  function resolveToAlias(path, nuxt = tryUseNuxt()) {
64
79
  return reverseResolveAlias(path, { ...nuxt?.options.alias || {}, ...strippedAtAliases$1 }).pop() || path;
@@ -214,14 +229,6 @@ function getLoader(id) {
214
229
  }
215
230
  return ext.endsWith("x") ? "tsx" : "ts";
216
231
  }
217
- function matchWithStringOrRegex(value, matcher) {
218
- if (typeof matcher === "string") {
219
- return value === matcher;
220
- } else if (matcher instanceof RegExp) {
221
- return matcher.test(value);
222
- }
223
- return false;
224
- }
225
232
 
226
233
  function uniqueBy(arr, key) {
227
234
  if (arr.length < 2) {
@@ -307,6 +314,7 @@ function generateRoutesFromFiles(files, options = {}) {
307
314
  children: []
308
315
  };
309
316
  let parent = routes;
317
+ const routeGroups = [];
310
318
  const lastSegment = segments[segments.length - 1];
311
319
  if (lastSegment.endsWith(".server")) {
312
320
  segments[segments.length - 1] = lastSegment.replace(".server", "");
@@ -321,6 +329,8 @@ function generateRoutesFromFiles(files, options = {}) {
321
329
  const segment = segments[i];
322
330
  const tokens = parseSegment(segment, file.absolutePath);
323
331
  if (tokens.every((token) => token.type === SegmentTokenType.group)) {
332
+ const groupNames = tokens.map((t) => t.value);
333
+ routeGroups.push(...groupNames);
324
334
  continue;
325
335
  }
326
336
  const segmentName = tokens.map(({ value, type }) => type === SegmentTokenType.group ? "" : value).join("");
@@ -337,6 +347,10 @@ function generateRoutesFromFiles(files, options = {}) {
337
347
  route.path += routePath;
338
348
  }
339
349
  }
350
+ if (routeGroups.length > 0) {
351
+ route.meta ||= {};
352
+ route.meta.groups = routeGroups;
353
+ }
340
354
  parent.push(route);
341
355
  }
342
356
  return prepareRoutes(routes);
@@ -483,7 +497,7 @@ function getRouteMeta(contents, absolutePath, extraExtractionKeys = /* @__PURE__
483
497
  extractCache[absolutePath] = extractedData;
484
498
  return klona(extractedData);
485
499
  }
486
- const COLON_RE = /:/g;
500
+ const ESCAPE_CHARS_RE = /[\\:]/g;
487
501
  function getRoutePath(tokens, hasSucceedingSegment = false) {
488
502
  return tokens.reduce((path, token) => {
489
503
  switch (token.type) {
@@ -497,7 +511,7 @@ function getRoutePath(tokens, hasSucceedingSegment = false) {
497
511
  return path;
498
512
  case SegmentTokenType.static:
499
513
  default:
500
- return path + encodePath(token.value).replace(COLON_RE, "\\:");
514
+ return path + token.value.replace(ESCAPE_CHARS_RE, "\\$&");
501
515
  }
502
516
  }, "/");
503
517
  }
@@ -855,212 +869,227 @@ const PageMetaPlugin = (options = {}) => createUnplugin(() => {
855
869
  transformInclude(id) {
856
870
  return !!parseMacroQuery(id).macro;
857
871
  },
858
- transform(code, id) {
859
- const query = parseMacroQuery(id);
860
- if (query.type && query.type !== "script") {
861
- return;
862
- }
863
- const s = new MagicString(code);
864
- function result() {
865
- if (s.hasChanged()) {
866
- return {
867
- code: s.toString(),
868
- map: options.sourcemap ? s.generateMap({ hires: true }) : void 0
869
- };
870
- }
871
- }
872
- const hasMacro = HAS_MACRO_RE.test(code);
873
- const imports = findStaticImports(code);
874
- const scriptImport = imports.find((i) => parseMacroQuery(i.specifier).type === "script");
875
- if (scriptImport) {
876
- const reorderedQuery = rewriteQuery(scriptImport.specifier);
877
- const quotedSpecifier = getQuotedSpecifier(scriptImport.code)?.replace(scriptImport.specifier, reorderedQuery) ?? JSON.stringify(reorderedQuery);
878
- s.overwrite(0, code.length, `export { default } from ${quotedSpecifier}`);
879
- return result();
880
- }
881
- const currentExports = findExports(code);
882
- for (const match of currentExports) {
883
- if (match.type !== "default" || !match.specifier) {
884
- continue;
885
- }
886
- const reorderedQuery = rewriteQuery(match.specifier);
887
- const quotedSpecifier = getQuotedSpecifier(match.code)?.replace(match.specifier, reorderedQuery) ?? JSON.stringify(reorderedQuery);
888
- s.overwrite(0, code.length, `export { default } from ${quotedSpecifier}`);
889
- return result();
890
- }
891
- if (!hasMacro && !code.includes("export { default }") && !code.includes("__nuxt_page_meta")) {
892
- if (!code) {
893
- s.append(options.dev ? CODE_DEV_EMPTY + CODE_HMR : CODE_EMPTY);
894
- const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href));
895
- logger.error(`The file \`${pathname}\` is not a valid page as it has no content.`);
896
- } else {
897
- s.overwrite(0, code.length, options.dev ? CODE_DEV_EMPTY + CODE_HMR : CODE_EMPTY);
898
- }
899
- return result();
900
- }
901
- const importMap = /* @__PURE__ */ new Map();
902
- const addedImports = /* @__PURE__ */ new Set();
903
- for (const i of imports) {
904
- const parsed = parseStaticImport(i);
905
- for (const name of [
906
- parsed.defaultImport,
907
- ...Object.values(parsed.namedImports || {}),
908
- parsed.namespacedImport
909
- ].filter(Boolean)) {
910
- importMap.set(name, i);
911
- }
912
- }
913
- function isStaticIdentifier(name) {
914
- return !!(name && importMap.has(name));
915
- }
916
- function addImport(name) {
917
- if (!isStaticIdentifier(name)) {
918
- return;
919
- }
920
- const importValue = importMap.get(name).code.trim();
921
- if (!addedImports.has(importValue)) {
922
- addedImports.add(importValue);
872
+ transform: {
873
+ filter: {
874
+ id: {
875
+ exclude: [/(?:\?|%3F).*type=(?:style|template)/]
876
+ },
877
+ code: {
878
+ include: [
879
+ HAS_MACRO_RE,
880
+ /\bfrom\s+["'][^"'?]*\?[^"']*type=script[^"']*["']/,
881
+ /export\s+\{\s*default\s*\}\s+from\s+["'][^"'?]*\?[^"']*type=script[^"']*["']/,
882
+ /^(?!.*__nuxt_page_meta)(?!.*export\s+\{\s*default\s*\})(?!.*\bdefinePageMeta\s*\()[\s\S]*$/
883
+ ]
923
884
  }
924
- }
925
- const declarationNodes = [];
926
- const addedDeclarations = /* @__PURE__ */ new Set();
927
- function addDeclaration(node) {
928
- const codeSectionKey = `${resolveStart(node)}-${resolveEnd(node)}`;
929
- if (addedDeclarations.has(codeSectionKey)) {
885
+ },
886
+ handler(code, id) {
887
+ const query = parseMacroQuery(id);
888
+ if (query.type && query.type !== "script") {
930
889
  return;
931
890
  }
932
- addedDeclarations.add(codeSectionKey);
933
- declarationNodes.push(node);
934
- }
935
- function addImportOrDeclaration(name, node) {
936
- if (isStaticIdentifier(name)) {
937
- addImport(name);
938
- } else {
939
- const declaration = scopeTracker.getDeclaration(name);
940
- if (declaration && declaration !== node) {
941
- processDeclaration(declaration);
891
+ const s = new MagicString(code);
892
+ function result() {
893
+ if (s.hasChanged()) {
894
+ return {
895
+ code: s.toString(),
896
+ map: options.sourcemap ? s.generateMap({ hires: true }) : void 0
897
+ };
942
898
  }
943
899
  }
944
- }
945
- const scopeTracker = new ScopeTracker({
946
- preserveExitedScopes: true
947
- });
948
- function processDeclaration(scopeTrackerNode) {
949
- if (scopeTrackerNode?.type === "Variable") {
950
- addDeclaration(scopeTrackerNode);
951
- for (const decl of scopeTrackerNode.variableNode.declarations) {
952
- if (!decl.init) {
953
- continue;
954
- }
955
- walk(decl.init, {
956
- enter: (node, parent) => {
957
- if (node.type === "AwaitExpression") {
958
- logger.error(`Await expressions are not supported in definePageMeta. File: '${id}'`);
959
- throw new Error("await in definePageMeta");
960
- }
961
- if (isBindingIdentifier(node, parent) || node.type !== "Identifier") {
962
- return;
963
- }
964
- addImportOrDeclaration(node.name, scopeTrackerNode);
965
- }
966
- });
967
- }
968
- } else if (scopeTrackerNode?.type === "Function") {
969
- if (scopeTrackerNode.node.type === "ArrowFunctionExpression") {
970
- return;
900
+ const hasMacro = HAS_MACRO_RE.test(code);
901
+ const imports = findStaticImports(code);
902
+ const scriptImport = imports.find((i) => parseMacroQuery(i.specifier).type === "script");
903
+ if (scriptImport) {
904
+ const reorderedQuery = rewriteQuery(scriptImport.specifier);
905
+ const quotedSpecifier = getQuotedSpecifier(scriptImport.code)?.replace(scriptImport.specifier, reorderedQuery) ?? JSON.stringify(reorderedQuery);
906
+ s.overwrite(0, code.length, `export { default } from ${quotedSpecifier}`);
907
+ return result();
908
+ }
909
+ const currentExports = findExports(code);
910
+ for (const match of currentExports) {
911
+ if (match.type !== "default" || !match.specifier) {
912
+ continue;
971
913
  }
972
- const name = scopeTrackerNode.node.id?.name;
973
- if (!name) {
974
- return;
914
+ const reorderedQuery = rewriteQuery(match.specifier);
915
+ const quotedSpecifier = getQuotedSpecifier(match.code)?.replace(match.specifier, reorderedQuery) ?? JSON.stringify(reorderedQuery);
916
+ s.overwrite(0, code.length, `export { default } from ${quotedSpecifier}`);
917
+ return result();
918
+ }
919
+ if (!hasMacro && !code.includes("export { default }") && !code.includes("__nuxt_page_meta")) {
920
+ if (!code) {
921
+ s.append(options.dev ? CODE_DEV_EMPTY + CODE_HMR : CODE_EMPTY);
922
+ const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href));
923
+ logger.error(`The file \`${pathname}\` is not a valid page as it has no content.`);
924
+ } else {
925
+ s.overwrite(0, code.length, options.dev ? CODE_DEV_EMPTY + CODE_HMR : CODE_EMPTY);
975
926
  }
976
- addDeclaration(scopeTrackerNode);
977
- const undeclaredIdentifiers = getUndeclaredIdentifiersInFunction(scopeTrackerNode.node);
978
- for (const name2 of undeclaredIdentifiers) {
979
- addImportOrDeclaration(name2);
927
+ return result();
928
+ }
929
+ const importMap = /* @__PURE__ */ new Map();
930
+ const addedImports = /* @__PURE__ */ new Set();
931
+ for (const i of imports) {
932
+ const parsed = parseStaticImport(i);
933
+ for (const name of [
934
+ parsed.defaultImport,
935
+ ...Object.values(parsed.namedImports || {}),
936
+ parsed.namespacedImport
937
+ ].filter(Boolean)) {
938
+ importMap.set(name, i);
980
939
  }
981
940
  }
982
- }
983
- const { program: ast } = parseAndWalk(code, id, {
984
- scopeTracker,
985
- parseOptions: {
986
- lang: query.lang ?? "ts"
941
+ function isStaticIdentifier(name) {
942
+ return !!(name && importMap.has(name));
987
943
  }
988
- });
989
- scopeTracker.freeze();
990
- let instances = 0;
991
- walk(ast, {
992
- scopeTracker,
993
- enter: (node) => {
994
- if (node.type !== "CallExpression" || node.callee.type !== "Identifier") {
944
+ function addImport(name) {
945
+ if (!isStaticIdentifier(name)) {
995
946
  return;
996
947
  }
997
- if (!("name" in node.callee) || node.callee.name !== "definePageMeta") {
998
- return;
948
+ const importValue = importMap.get(name).code.trim();
949
+ if (!addedImports.has(importValue)) {
950
+ addedImports.add(importValue);
999
951
  }
1000
- instances++;
1001
- const meta = node.arguments[0];
1002
- if (!meta) {
952
+ }
953
+ const declarationNodes = [];
954
+ const addedDeclarations = /* @__PURE__ */ new Set();
955
+ function addDeclaration(node) {
956
+ const codeSectionKey = `${resolveStart(node)}-${resolveEnd(node)}`;
957
+ if (addedDeclarations.has(codeSectionKey)) {
1003
958
  return;
1004
959
  }
1005
- const metaCode = code.slice(meta.start, meta.end);
1006
- const m = new MagicString(metaCode);
1007
- if (meta.type === "ObjectExpression") {
1008
- for (let i = 0; i < meta.properties.length; i++) {
1009
- const prop = meta.properties[i];
1010
- if (prop.type === "Property" && prop.key.type === "Identifier" && options.extractedKeys?.includes(prop.key.name)) {
1011
- const { serializable } = isSerializable(metaCode, prop.value);
1012
- if (!serializable) {
1013
- continue;
1014
- }
1015
- const nextProperty = meta.properties[i + 1];
1016
- if (nextProperty) {
1017
- m.overwrite(prop.start - meta.start, nextProperty.start - meta.start, "");
1018
- } else if (code[prop.end] === ",") {
1019
- m.overwrite(prop.start - meta.start, prop.end - meta.start + 1, "");
1020
- } else {
1021
- m.overwrite(prop.start - meta.start, prop.end - meta.start, "");
1022
- }
960
+ addedDeclarations.add(codeSectionKey);
961
+ declarationNodes.push(node);
962
+ }
963
+ function addImportOrDeclaration(name, node) {
964
+ if (isStaticIdentifier(name)) {
965
+ addImport(name);
966
+ } else {
967
+ const declaration = scopeTracker.getDeclaration(name);
968
+ if (declaration && declaration !== node) {
969
+ processDeclaration(declaration);
970
+ }
971
+ }
972
+ }
973
+ const scopeTracker = new ScopeTracker({
974
+ preserveExitedScopes: true
975
+ });
976
+ function processDeclaration(scopeTrackerNode) {
977
+ if (scopeTrackerNode?.type === "Variable") {
978
+ addDeclaration(scopeTrackerNode);
979
+ for (const decl of scopeTrackerNode.variableNode.declarations) {
980
+ if (!decl.init) {
981
+ continue;
1023
982
  }
983
+ walk(decl.init, {
984
+ enter: (node, parent) => {
985
+ if (node.type === "AwaitExpression") {
986
+ logger.error(`Await expressions are not supported in definePageMeta. File: '${id}'`);
987
+ throw new Error("await in definePageMeta");
988
+ }
989
+ if (isBindingIdentifier(node, parent) || node.type !== "Identifier") {
990
+ return;
991
+ }
992
+ addImportOrDeclaration(node.name, scopeTrackerNode);
993
+ }
994
+ });
995
+ }
996
+ } else if (scopeTrackerNode?.type === "Function") {
997
+ if (scopeTrackerNode.node.type === "ArrowFunctionExpression") {
998
+ return;
999
+ }
1000
+ const name = scopeTrackerNode.node.id?.name;
1001
+ if (!name) {
1002
+ return;
1003
+ }
1004
+ addDeclaration(scopeTrackerNode);
1005
+ const undeclaredIdentifiers = getUndeclaredIdentifiersInFunction(scopeTrackerNode.node);
1006
+ for (const name2 of undeclaredIdentifiers) {
1007
+ addImportOrDeclaration(name2);
1024
1008
  }
1025
1009
  }
1026
- const definePageMetaScope = scopeTracker.getCurrentScope();
1027
- walk(meta, {
1028
- scopeTracker,
1029
- enter(node2, parent) {
1030
- if (isBindingIdentifier(node2, parent) || node2.type !== "Identifier") {
1031
- return;
1010
+ }
1011
+ const { program: ast } = parseAndWalk(code, id, {
1012
+ scopeTracker,
1013
+ parseOptions: {
1014
+ lang: query.lang ?? "ts"
1015
+ }
1016
+ });
1017
+ scopeTracker.freeze();
1018
+ let instances = 0;
1019
+ walk(ast, {
1020
+ scopeTracker,
1021
+ enter: (node) => {
1022
+ if (node.type !== "CallExpression" || node.callee.type !== "Identifier") {
1023
+ return;
1024
+ }
1025
+ if (!("name" in node.callee) || node.callee.name !== "definePageMeta") {
1026
+ return;
1027
+ }
1028
+ instances++;
1029
+ const meta = node.arguments[0];
1030
+ if (!meta) {
1031
+ return;
1032
+ }
1033
+ const metaCode = code.slice(meta.start, meta.end);
1034
+ const m = new MagicString(metaCode);
1035
+ if (meta.type === "ObjectExpression") {
1036
+ for (let i = 0; i < meta.properties.length; i++) {
1037
+ const prop = meta.properties[i];
1038
+ if (prop.type === "Property" && prop.key.type === "Identifier" && options.extractedKeys?.includes(prop.key.name)) {
1039
+ const { serializable } = isSerializable(metaCode, prop.value);
1040
+ if (!serializable) {
1041
+ continue;
1042
+ }
1043
+ const nextProperty = meta.properties[i + 1];
1044
+ if (nextProperty) {
1045
+ m.overwrite(prop.start - meta.start, nextProperty.start - meta.start, "");
1046
+ } else if (code[prop.end] === ",") {
1047
+ m.overwrite(prop.start - meta.start, prop.end - meta.start + 1, "");
1048
+ } else {
1049
+ m.overwrite(prop.start - meta.start, prop.end - meta.start, "");
1050
+ }
1051
+ }
1032
1052
  }
1033
- const declaration = scopeTracker.getDeclaration(node2.name);
1034
- if (declaration) {
1035
- if (declaration.isUnderScope(definePageMetaScope) && (scopeTracker.isCurrentScopeUnder(declaration.scope) || resolveStart(declaration) < node2.start)) {
1053
+ }
1054
+ const definePageMetaScope = scopeTracker.getCurrentScope();
1055
+ walk(meta, {
1056
+ scopeTracker,
1057
+ enter(node2, parent) {
1058
+ if (isBindingIdentifier(node2, parent) || node2.type !== "Identifier") {
1036
1059
  return;
1037
1060
  }
1061
+ const declaration = scopeTracker.getDeclaration(node2.name);
1062
+ if (declaration) {
1063
+ if (declaration.isUnderScope(definePageMetaScope) && (scopeTracker.isCurrentScopeUnder(declaration.scope) || resolveStart(declaration) < node2.start)) {
1064
+ return;
1065
+ }
1066
+ }
1067
+ if (isStaticIdentifier(node2.name)) {
1068
+ addImport(node2.name);
1069
+ } else if (declaration) {
1070
+ processDeclaration(declaration);
1071
+ }
1038
1072
  }
1039
- if (isStaticIdentifier(node2.name)) {
1040
- addImport(node2.name);
1041
- } else if (declaration) {
1042
- processDeclaration(declaration);
1043
- }
1044
- }
1045
- });
1046
- const importStatements = Array.from(addedImports).join("\n");
1047
- const declarations = declarationNodes.sort((a, b) => resolveStart(a) - resolveStart(b)).map((node2) => code.slice(resolveStart(node2), resolveEnd(node2))).join("\n");
1048
- const extracted = [
1049
- importStatements,
1050
- declarations,
1051
- `const __nuxt_page_meta = ${m.toString() || "null"}
1073
+ });
1074
+ const importStatements = Array.from(addedImports).join("\n");
1075
+ const declarations = declarationNodes.sort((a, b) => resolveStart(a) - resolveStart(b)).map((node2) => code.slice(resolveStart(node2), resolveEnd(node2))).join("\n");
1076
+ const extracted = [
1077
+ importStatements,
1078
+ declarations,
1079
+ `const __nuxt_page_meta = ${m.toString() || "null"}
1052
1080
  export default __nuxt_page_meta` + (options.dev ? CODE_HMR : "")
1053
- ].join("\n");
1054
- s.overwrite(0, code.length, extracted.trim());
1081
+ ].join("\n");
1082
+ s.overwrite(0, code.length, extracted.trim());
1083
+ }
1084
+ });
1085
+ if (instances > 1) {
1086
+ throw new Error("Multiple `definePageMeta` calls are not supported. File: " + id.replace(/\?.+$/, ""));
1055
1087
  }
1056
- });
1057
- if (instances > 1) {
1058
- throw new Error("Multiple `definePageMeta` calls are not supported. File: " + id.replace(/\?.+$/, ""));
1059
- }
1060
- if (!s.hasChanged() && !code.includes("__nuxt_page_meta")) {
1061
- s.overwrite(0, code.length, options.dev ? CODE_DEV_EMPTY + CODE_HMR : CODE_EMPTY);
1088
+ if (!s.hasChanged() && !code.includes("__nuxt_page_meta")) {
1089
+ s.overwrite(0, code.length, options.dev ? CODE_DEV_EMPTY + CODE_HMR : CODE_EMPTY);
1090
+ }
1091
+ return result();
1062
1092
  }
1063
- return result();
1064
1093
  },
1065
1094
  vite: {
1066
1095
  handleHotUpdate: {
@@ -1431,6 +1460,9 @@ const pagesModule = defineNuxtModule({
1431
1460
  const prerenderRoutes = /* @__PURE__ */ new Set();
1432
1461
  function processPages(pages, currentPath = "/") {
1433
1462
  for (const page of pages) {
1463
+ if (page._sync) {
1464
+ continue;
1465
+ }
1434
1466
  if (OPTIONAL_PARAM_RE.test(page.path) && !page.children?.length) {
1435
1467
  prerenderRoutes.add(currentPath);
1436
1468
  }
@@ -1460,9 +1492,12 @@ const pagesModule = defineNuxtModule({
1460
1492
  ...toRou3Patterns(nuxt.apps.default?.pages || [])
1461
1493
  ];
1462
1494
  if (!nitro.options.static && !nitro.options.prerender.crawlLinks) {
1463
- const routeRulesMatcher = toRouteMatcher(createRouter({ routes: nitro.options.routeRules }));
1495
+ const routeRulesRouter = createRouter();
1496
+ for (const [route, rules] of Object.entries(nitro.options.routeRules)) {
1497
+ addRoute(routeRulesRouter, void 0, route, rules);
1498
+ }
1464
1499
  for (const route of prerenderRoutes) {
1465
- const rules = defu({}, ...routeRulesMatcher.matchAll(route).reverse());
1500
+ const rules = defu({}, ...findAllRoutes(routeRulesRouter, void 0, route).reverse());
1466
1501
  if (rules.prerender) {
1467
1502
  nitro.options.prerender.routes.push(route);
1468
1503
  }
@@ -1497,26 +1532,24 @@ const pagesModule = defineNuxtModule({
1497
1532
  });
1498
1533
  });
1499
1534
  }
1500
- if (nuxt.options.experimental.appManifest) {
1501
- nuxt.hook("pages:extend", (routes) => {
1502
- const nitro = useNitro();
1503
- let resolvedRoutes;
1504
- for (const [path, rule] of Object.entries(nitro.options.routeRules)) {
1505
- if (!rule.redirect) {
1506
- continue;
1507
- }
1508
- resolvedRoutes ||= routes.flatMap((route) => resolveRoutePaths(route));
1509
- if (resolvedRoutes.includes(path)) {
1510
- continue;
1511
- }
1512
- routes.push({
1513
- _sync: true,
1514
- path: path.replace(/\/[^/]*\*\*/, "/:pathMatch(.*)"),
1515
- file: componentStubPath
1516
- });
1535
+ nuxt.hook("pages:extend", (routes) => {
1536
+ const nitro = useNitro();
1537
+ let resolvedRoutes;
1538
+ for (const [path, rule] of Object.entries(nitro.options.routeRules)) {
1539
+ if (!rule.redirect) {
1540
+ continue;
1517
1541
  }
1518
- });
1519
- }
1542
+ resolvedRoutes ||= routes.flatMap((route) => resolveRoutePaths(route));
1543
+ if (resolvedRoutes.includes(path)) {
1544
+ continue;
1545
+ }
1546
+ routes.push({
1547
+ _sync: true,
1548
+ path: path.replace(/\/[^/]*\*\*/, "/:pathMatch(.*)"),
1549
+ file: componentStubPath
1550
+ });
1551
+ }
1552
+ });
1520
1553
  const extraPageMetaExtractionKeys = nuxt.options?.experimental?.extraPageMetaExtractionKeys || [];
1521
1554
  const extractedKeys = [
1522
1555
  ...defaultExtractionKeys,
@@ -1640,10 +1673,21 @@ const pagesModule = defineNuxtModule({
1640
1673
  addTypeTemplate({
1641
1674
  filename: "types/layouts.d.ts",
1642
1675
  getContents: ({ app }) => {
1676
+ const imports = /* @__PURE__ */ new Set();
1677
+ const interfaceKeyValues = /* @__PURE__ */ new Map();
1678
+ for (const layout of Object.values(app.layouts)) {
1679
+ const varName = genSafeVariableName(layout.name);
1680
+ imports.add(genImport(layout.file, varName));
1681
+ interfaceKeyValues.set(layout.name, varName);
1682
+ }
1643
1683
  return [
1684
+ ...Array.from(imports),
1644
1685
  "import type { ComputedRef, MaybeRef } from 'vue'",
1645
- `export type LayoutKey = ${Object.keys(app.layouts).map((name) => genString(name)).join(" | ") || "string"}`,
1646
1686
  "declare module 'nuxt/app' {",
1687
+ " interface NuxtLayouts {",
1688
+ ...Array.from(interfaceKeyValues.entries()).map(([key, value]) => ` '${key}': InstanceType<typeof ${value}>['$props'],`),
1689
+ "}",
1690
+ " export type LayoutKey = keyof NuxtLayouts extends never ? string : keyof NuxtLayouts",
1647
1691
  " interface PageMeta {",
1648
1692
  " layout?: MaybeRef<LayoutKey | false> | ComputedRef<LayoutKey | false>",
1649
1693
  " }",
@@ -1691,7 +1735,15 @@ if (import.meta.hot) {
1691
1735
  for (const route of routes) {
1692
1736
  router.addRoute(route)
1693
1737
  }
1694
- router.replace(router.currentRoute.value.fullPath)
1738
+ router.isReady().then(() => {
1739
+ // Resolve the current path against the new routes to get updated meta
1740
+ const newRoute = router.resolve(router.currentRoute.value.fullPath)
1741
+ // Clear old meta values and assign new ones
1742
+ for (const key of Object.keys(router.currentRoute.value.meta)) {
1743
+ delete router.currentRoute.value.meta[key]
1744
+ }
1745
+ Object.assign(router.currentRoute.value.meta, newRoute.meta)
1746
+ })
1695
1747
  }
1696
1748
  if (routes && 'then' in routes) {
1697
1749
  routes.then(addRoutes)
@@ -2787,82 +2839,99 @@ function TransformPlugin$1(nuxt, options) {
2787
2839
  ];
2788
2840
  });
2789
2841
  }
2790
- return createUnplugin(() => ({
2791
- name: "nuxt:components:imports",
2792
- enforce: "post",
2793
- transformInclude(id) {
2794
- id = normalize(id);
2795
- return id.startsWith("virtual:") || id.startsWith("\0virtual:") || id.startsWith(nuxt.options.buildDir) || !isIgnored(id, void 0, nuxt);
2842
+ return createUnplugin(() => [
2843
+ {
2844
+ name: "nuxt:components:imports-wrapper",
2845
+ enforce: "post",
2846
+ transformInclude(id) {
2847
+ id = normalize(id);
2848
+ return id.startsWith("virtual:") || id.startsWith("\0virtual:") || id.startsWith(nuxt.options.buildDir) || !isIgnored(id, void 0, nuxt);
2849
+ },
2850
+ transform: {
2851
+ filter: {
2852
+ id: COMPONENT_QUERY_RE
2853
+ },
2854
+ handler(_code, id) {
2855
+ const { search } = parseURL(id);
2856
+ const query = parseQuery$1(search);
2857
+ const mode = query.nuxt_component;
2858
+ const bare = id.replace(/\?.*/, "");
2859
+ const componentExport = query.nuxt_component_export || "default";
2860
+ const exportWording = componentExport === "default" ? "export default" : `export const ${componentExport} =`;
2861
+ if (mode === "async") {
2862
+ return {
2863
+ code: [
2864
+ 'import { defineAsyncComponent } from "vue"',
2865
+ `${exportWording} defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => r[${JSON.stringify(componentExport)}] || r.default || r))`
2866
+ ].join("\n"),
2867
+ map: null
2868
+ };
2869
+ } else if (mode === "client") {
2870
+ return {
2871
+ code: [
2872
+ genImport(bare, [{ name: componentExport, as: "__component" }]),
2873
+ 'import { createClientOnly } from "#app/components/client-only"',
2874
+ `${exportWording} createClientOnly(__component)`
2875
+ ].join("\n"),
2876
+ map: null
2877
+ };
2878
+ } else if (mode === "client,async") {
2879
+ return {
2880
+ code: [
2881
+ 'import { defineAsyncComponent } from "vue"',
2882
+ 'import { createClientOnly } from "#app/components/client-only"',
2883
+ `${exportWording} defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => createClientOnly(r[${JSON.stringify(componentExport)}] || r.default || r)))`
2884
+ ].join("\n"),
2885
+ map: null
2886
+ };
2887
+ } else if (mode === "server" || mode === "server,async") {
2888
+ const name = query.nuxt_component_name;
2889
+ return {
2890
+ code: [
2891
+ `import { createServerComponent } from ${JSON.stringify(options.serverComponentRuntime)}`,
2892
+ `${exportWording} createServerComponent(${JSON.stringify(name)})`
2893
+ ].join("\n"),
2894
+ map: null
2895
+ };
2896
+ } else {
2897
+ throw new Error(`Unknown component mode: ${mode}, this might be an internal bug of Nuxt.`);
2898
+ }
2899
+ }
2900
+ }
2796
2901
  },
2797
- async transform(code, id) {
2798
- if (COMPONENT_QUERY_RE.test(id)) {
2799
- const { search } = parseURL(id);
2800
- const query = parseQuery$1(search);
2801
- const mode = query.nuxt_component;
2802
- const bare = id.replace(/\?.*/, "");
2803
- const componentExport = query.nuxt_component_export || "default";
2804
- const exportWording = componentExport === "default" ? "export default" : `export const ${componentExport} =`;
2805
- if (mode === "async") {
2806
- return {
2807
- code: [
2808
- 'import { defineAsyncComponent } from "vue"',
2809
- `${exportWording} defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => r[${JSON.stringify(componentExport)}] || r.default || r))`
2810
- ].join("\n"),
2811
- map: null
2812
- };
2813
- } else if (mode === "client") {
2814
- return {
2815
- code: [
2816
- genImport(bare, [{ name: componentExport, as: "__component" }]),
2817
- 'import { createClientOnly } from "#app/components/client-only"',
2818
- `${exportWording} createClientOnly(__component)`
2819
- ].join("\n"),
2820
- map: null
2821
- };
2822
- } else if (mode === "client,async") {
2823
- return {
2824
- code: [
2825
- 'import { defineAsyncComponent } from "vue"',
2826
- 'import { createClientOnly } from "#app/components/client-only"',
2827
- `${exportWording} defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => createClientOnly(r[${JSON.stringify(componentExport)}] || r.default || r)))`
2828
- ].join("\n"),
2829
- map: null
2830
- };
2831
- } else if (mode === "server" || mode === "server,async") {
2832
- const name = query.nuxt_component_name;
2902
+ {
2903
+ name: "nuxt:components:imports-alias",
2904
+ enforce: "post",
2905
+ transformInclude(id) {
2906
+ id = normalize(id);
2907
+ return id.startsWith("virtual:") || id.startsWith("\0virtual:") || id.startsWith(nuxt.options.buildDir) || !isIgnored(id, void 0, nuxt);
2908
+ },
2909
+ transform: {
2910
+ filter: {
2911
+ code: /#components/
2912
+ },
2913
+ async handler(code, id) {
2914
+ const pkg = isAbsolute(id) && /node_modules[\\/](?!\.virtual)/.test(id) ? await readPackage(id, { try: true }) : void 0;
2915
+ if (isObject(pkg) && isObject(pkg.imports) && Object.hasOwn(pkg.imports, "#components")) {
2916
+ return;
2917
+ }
2918
+ componentUnimport.modifyDynamicImports((imports) => {
2919
+ imports.length = 0;
2920
+ imports.push(...getComponentsImports());
2921
+ return imports;
2922
+ });
2923
+ const result = await componentUnimport.injectImports(code, id, { autoImport: false, transformVirtualImports: true });
2924
+ if (!result) {
2925
+ return;
2926
+ }
2833
2927
  return {
2834
- code: [
2835
- `import { createServerComponent } from ${JSON.stringify(options.serverComponentRuntime)}`,
2836
- `${exportWording} createServerComponent(${JSON.stringify(name)})`
2837
- ].join("\n"),
2838
- map: null
2928
+ code: result.code,
2929
+ map: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client ? result.s.generateMap({ hires: true }) : void 0
2839
2930
  };
2840
- } else {
2841
- throw new Error(`Unknown component mode: ${mode}, this might be an internal bug of Nuxt.`);
2842
2931
  }
2843
2932
  }
2844
- if (!code.includes("#components")) {
2845
- return;
2846
- }
2847
- const pkg = isAbsolute(id) && /node_modules[\\/](?!\.virtual)/.test(id) ? await readPackage(id, { try: true }) : void 0;
2848
- if (isObject(pkg) && isObject(pkg.imports) && Object.hasOwn(pkg.imports, "#components")) {
2849
- return;
2850
- }
2851
- componentUnimport.modifyDynamicImports((imports) => {
2852
- imports.length = 0;
2853
- imports.push(...getComponentsImports());
2854
- return imports;
2855
- });
2856
- const result = await componentUnimport.injectImports(code, id, { autoImport: false, transformVirtualImports: true });
2857
- if (!result) {
2858
- return;
2859
- }
2860
- return {
2861
- code: result.code,
2862
- map: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client ? result.s.generateMap({ hires: true }) : void 0
2863
- };
2864
2933
  }
2865
- }));
2934
+ ]);
2866
2935
  }
2867
2936
 
2868
2937
  const SSR_RENDER_RE = /ssrRenderComponent/;
@@ -3369,13 +3438,6 @@ function findImportExpression(node) {
3369
3438
  }
3370
3439
 
3371
3440
  const isPureObjectOrString = (val) => !Array.isArray(val) && typeof val === "object" || typeof val === "string";
3372
- const isDirectory = (p) => {
3373
- try {
3374
- return statSync(p).isDirectory();
3375
- } catch {
3376
- return false;
3377
- }
3378
- };
3379
3441
  const SLASH_SEPARATOR_RE = /[\\/]/;
3380
3442
  function compareDirByPathLength({ path: pathA }, { path: pathB }) {
3381
3443
  return pathB.split(SLASH_SEPARATOR_RE).filter(Boolean).length - pathA.split(SLASH_SEPARATOR_RE).filter(Boolean).length;
@@ -3425,7 +3487,7 @@ const componentsModule = defineNuxtModule({
3425
3487
  if (transpile) {
3426
3488
  nuxt.options.build.transpile.push(dirPath);
3427
3489
  }
3428
- const present = isDirectory(dirPath);
3490
+ const present = isDirectorySync(dirPath);
3429
3491
  if (!present && !DEFAULT_COMPONENTS_DIRS_RE.test(dirOptions.path)) {
3430
3492
  logger.warn("Components directory not found: `" + dirPath + "`");
3431
3493
  }
@@ -3439,10 +3501,8 @@ const componentsModule = defineNuxtModule({
3439
3501
  ignore: [
3440
3502
  "**/*{M,.m,-m}ixin.{js,ts,jsx,tsx}",
3441
3503
  // ignore mixins
3442
- "**/*.d.{cts,mts,ts}",
3504
+ `**/*.{${DECLARATION_EXTENSIONS.join(",")},}`,
3443
3505
  // .d.ts files
3444
- "**/*.d.vue.{cts,mts,ts}",
3445
- // .d.vue.ts files
3446
3506
  ...dirOptions.ignore || []
3447
3507
  ],
3448
3508
  transpile
@@ -3727,7 +3787,9 @@ const importsModule = defineNuxtModule({
3727
3787
  });
3728
3788
  nuxt.options.alias["#imports"] = join(nuxt.options.buildDir, "imports");
3729
3789
  addBuildPlugin(TransformPlugin({
3730
- ctx: { injectImports: (code, id, options2) => ctx.injectImports(code, id, options2) },
3790
+ ctx: {
3791
+ injectImports: (code, id, options2) => ctx.injectImports(code, id, options2)
3792
+ },
3731
3793
  options,
3732
3794
  sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client
3733
3795
  }));
@@ -3814,7 +3876,7 @@ function addDeclarationTemplates(ctx, options) {
3814
3876
  return join(dir, name, subpath || "");
3815
3877
  }) ?? path;
3816
3878
  }
3817
- if (existsSync(path) && !await isDirectory$1(path)) {
3879
+ if (existsSync(path) && !await isDirectory(path)) {
3818
3880
  path = path.replace(SUPPORTED_EXTENSION_RE, "");
3819
3881
  }
3820
3882
  if (isAbsolute(path)) {
@@ -3825,19 +3887,65 @@ function addDeclarationTemplates(ctx, options) {
3825
3887
  }
3826
3888
  addTypeTemplate({
3827
3889
  filename: "imports.d.ts",
3828
- getContents: async ({ nuxt: nuxt2 }) => toExports(await ctx.getImports(), nuxt2.options.buildDir, true)
3890
+ getContents: async ({ nuxt: nuxt2 }) => toExports(await ctx.getImports(), nuxt2.options.buildDir, true, { declaration: true })
3829
3891
  });
3892
+ const GENERATED_BY_COMMENT = "// Generated by auto imports\n";
3893
+ const AUTO_IMPORTS_DISABLED_COMMENT = "// Implicit auto importing is disabled, you can explicitly import from `#imports` instead.\n";
3830
3894
  addTypeTemplate({
3831
3895
  filename: "types/imports.d.ts",
3832
3896
  getContents: async () => {
3833
3897
  const imports = await ctx.getImports();
3834
3898
  await cacheImportPaths(imports);
3835
- return "// Generated by auto imports\n" + (options.autoImport ? await ctx.generateTypeDeclarations({ resolvePath: r }) : "// Implicit auto importing is disabled, you can use explicitly import from `#imports` instead.");
3899
+ return GENERATED_BY_COMMENT + (options.autoImport ? await ctx.generateTypeDeclarations({ resolvePath: r }) : AUTO_IMPORTS_DISABLED_COMMENT);
3900
+ }
3901
+ });
3902
+ addTemplate({
3903
+ filename: "types/shared-imports.d.ts",
3904
+ getContents: async () => {
3905
+ if (!options.autoImport) {
3906
+ return GENERATED_BY_COMMENT + AUTO_IMPORTS_DISABLED_COMMENT;
3907
+ }
3908
+ const nitro = useNitro();
3909
+ const nuxtImports = await ctx.getImports();
3910
+ const nitroImports = await nitro.unimport?.getImports() ?? [];
3911
+ const nitroImportsByName = new Map(nitroImports.map((i) => [i.as || i.name, i]));
3912
+ const sharedImports = [];
3913
+ for (const i of nuxtImports) {
3914
+ const importName = i.as || i.name;
3915
+ const nitroImport = nitroImportsByName.get(importName);
3916
+ if (!nitroImport || i.dtsDisabled || nitroImport.dtsDisabled) {
3917
+ continue;
3918
+ }
3919
+ sharedImports.push(i);
3920
+ }
3921
+ await cacheImportPaths(sharedImports);
3922
+ return GENERATED_BY_COMMENT + toTypeDeclarationFile(sharedImports, { resolvePath: r });
3836
3923
  }
3837
3924
  });
3838
3925
  }
3839
3926
 
3840
- const version = "4.2.2";
3927
+ const runtimeDependencies = [
3928
+ // other deps
3929
+ "devalue",
3930
+ "klona",
3931
+ // unjs ecosystem
3932
+ "defu",
3933
+ "ufo",
3934
+ "h3",
3935
+ "destr",
3936
+ "consola",
3937
+ "hookable",
3938
+ "unctx",
3939
+ "cookie-es",
3940
+ "perfect-debounce",
3941
+ "ohash",
3942
+ "pathe",
3943
+ "uncrypto"
3944
+ ];
3945
+
3946
+ const version = "4.3.0";
3947
+ const pkg = {
3948
+ version: version};
3841
3949
 
3842
3950
  function createImportProtectionPatterns(nuxt, options) {
3843
3951
  const patterns = [];
@@ -3872,6 +3980,10 @@ function createImportProtectionPatterns(nuxt, options) {
3872
3980
  new RegExp(escapeRE(relative(nuxt.options.srcDir, resolve(nuxt.options.srcDir, nuxt.options.serverDir || "server"))) + "\\/(api|routes|middleware|plugins)\\/"),
3873
3981
  `Importing from server is not allowed in ${context}.`
3874
3982
  ]);
3983
+ patterns.push([
3984
+ /^#server(\/|$)/,
3985
+ `Server aliases are not allowed in ${context}.`
3986
+ ]);
3875
3987
  }
3876
3988
  return patterns;
3877
3989
  }
@@ -3893,7 +4005,11 @@ const UnctxTransformPlugin = (options) => createUnplugin(() => {
3893
4005
  },
3894
4006
  transform: {
3895
4007
  filter: {
3896
- code: { exclude: TRANSFORM_MARKER_RE }
4008
+ ...transformer.filter,
4009
+ code: {
4010
+ ...transformer.filter.code,
4011
+ exclude: TRANSFORM_MARKER_RE
4012
+ }
3897
4013
  },
3898
4014
  handler(code) {
3899
4015
  if (!transformer.shouldTransform(code)) {
@@ -4013,6 +4129,7 @@ const DevOnlyPlugin = (options) => createUnplugin(() => {
4013
4129
 
4014
4130
  const ALIAS_RE = /(?<=['"])[~@]{1,2}(?=\/)/g;
4015
4131
  const ALIAS_RE_SINGLE = /(?<=['"])[~@]{1,2}(?=\/)/;
4132
+ const ALIAS_ID_RE = /^[~@]{1,2}\//;
4016
4133
  const LayerAliasingPlugin = (options) => createUnplugin((_options, meta) => {
4017
4134
  const aliases = {};
4018
4135
  for (const layer of options.layers) {
@@ -4026,19 +4143,46 @@ const LayerAliasingPlugin = (options) => createUnplugin((_options, meta) => {
4026
4143
  };
4027
4144
  }
4028
4145
  const layers = Object.keys(aliases).sort((a, b) => b.length - a.length);
4029
- return {
4030
- name: "nuxt:layer-aliasing",
4031
- enforce: "pre",
4032
- vite: {
4033
- resolveId: {
4034
- order: "pre",
4035
- async handler(id, importer) {
4036
- if (!importer) {
4037
- return;
4038
- }
4039
- const layer = layers.find((l) => importer.startsWith(l));
4040
- if (!layer) {
4041
- return;
4146
+ const nonViteTransformIncludes = (id) => {
4147
+ const _id = normalize(id);
4148
+ return layers.some((dir) => _id.startsWith(dir));
4149
+ };
4150
+ const nonViteTransform = {
4151
+ filter: {
4152
+ code: { include: ALIAS_RE_SINGLE }
4153
+ },
4154
+ handler(code, id) {
4155
+ const _id = normalize(id);
4156
+ const layer = layers.find((l) => _id.startsWith(l));
4157
+ if (!layer) {
4158
+ return;
4159
+ }
4160
+ const s = new MagicString(code);
4161
+ s.replace(ALIAS_RE, (r) => aliases[layer]?.[r] || r);
4162
+ if (s.hasChanged()) {
4163
+ return {
4164
+ code: s.toString(),
4165
+ map: options.sourcemap ? s.generateMap({ hires: true }) : void 0
4166
+ };
4167
+ }
4168
+ }
4169
+ };
4170
+ return {
4171
+ name: "nuxt:layer-aliasing",
4172
+ enforce: "pre",
4173
+ vite: {
4174
+ resolveId: {
4175
+ order: "pre",
4176
+ filter: {
4177
+ id: ALIAS_ID_RE
4178
+ },
4179
+ async handler(id, importer) {
4180
+ if (!importer) {
4181
+ return;
4182
+ }
4183
+ const layer = layers.find((l) => importer.startsWith(l));
4184
+ if (!layer) {
4185
+ return;
4042
4186
  }
4043
4187
  const resolvedId = resolveAlias$1(id, aliases[layer]);
4044
4188
  if (resolvedId !== id) {
@@ -4048,36 +4192,8 @@ const LayerAliasingPlugin = (options) => createUnplugin((_options, meta) => {
4048
4192
  }
4049
4193
  },
4050
4194
  // webpack-only transform
4051
- transformInclude: (id) => {
4052
- if (meta.framework === "vite") {
4053
- return false;
4054
- }
4055
- const _id = normalize(id);
4056
- return layers.some((dir) => _id.startsWith(dir));
4057
- },
4058
- transform: {
4059
- filter: {
4060
- code: { include: ALIAS_RE_SINGLE }
4061
- },
4062
- handler(code, id) {
4063
- if (meta.framework === "vite") {
4064
- return;
4065
- }
4066
- const _id = normalize(id);
4067
- const layer = layers.find((l) => _id.startsWith(l));
4068
- if (!layer) {
4069
- return;
4070
- }
4071
- const s = new MagicString(code);
4072
- s.replace(ALIAS_RE, (r) => aliases[layer]?.[r] || r);
4073
- if (s.hasChanged()) {
4074
- return {
4075
- code: s.toString(),
4076
- map: options.sourcemap ? s.generateMap({ hires: true }) : void 0
4077
- };
4078
- }
4079
- }
4080
- }
4195
+ transformInclude: meta.framework !== "vite" ? nonViteTransformIncludes : void 0,
4196
+ transform: meta.framework !== "vite" ? nonViteTransform : void 0
4081
4197
  };
4082
4198
  });
4083
4199
 
@@ -4118,7 +4234,7 @@ async function loadServerBuilder(nuxt, builder = "@nuxt/nitro-server") {
4118
4234
  try {
4119
4235
  return await importModule(builder, { url: [directoryToURL(nuxt.options.rootDir), new URL(import.meta.url)] });
4120
4236
  } catch (err) {
4121
- throw new Error(`Loading \`${builder}\` server builder failed.`, { cause: err });
4237
+ throw new Error(`Loading \`${builder}\` server builder failed. You can read more about the nuxt \`server.builder\` option at: \`https://nuxt.com/docs/4.x/api/nuxt-config#builder-1\``, { cause: err });
4122
4238
  }
4123
4239
  }
4124
4240
 
@@ -4445,99 +4561,446 @@ const AsyncContextInjectionPlugin = (nuxt) => createUnplugin(() => {
4445
4561
  };
4446
4562
  });
4447
4563
 
4564
+ function processImports(imports) {
4565
+ const directImports = /* @__PURE__ */ new Map();
4566
+ const namespaces = /* @__PURE__ */ new Map();
4567
+ for (const i of imports) {
4568
+ const resolvedSpecifier = stripExtension(resolveAlias$1(i.specifier));
4569
+ const namedImports = i.namedImports ?? {};
4570
+ for (const originalIdentifier in namedImports) {
4571
+ const localIdentifier = namedImports[originalIdentifier] || originalIdentifier;
4572
+ directImports.set(localIdentifier, {
4573
+ originalName: originalIdentifier,
4574
+ source: resolvedSpecifier
4575
+ });
4576
+ }
4577
+ if (i.namespacedImport || i.defaultImport) {
4578
+ if (!namespaces.has(resolvedSpecifier)) {
4579
+ namespaces.set(resolvedSpecifier, {
4580
+ namespaces: /* @__PURE__ */ new Set()
4581
+ });
4582
+ }
4583
+ }
4584
+ if (i.defaultImport) {
4585
+ const namespace = i.defaultImport;
4586
+ const entry = namespaces.get(resolvedSpecifier);
4587
+ entry.namespaces.add(namespace);
4588
+ directImports.set(i.defaultImport, {
4589
+ originalName: "default",
4590
+ source: resolvedSpecifier
4591
+ });
4592
+ } else if (i.namespacedImport) {
4593
+ const namespace = i.namespacedImport;
4594
+ const entry = namespaces.get(resolvedSpecifier);
4595
+ entry.namespaces.add(namespace);
4596
+ }
4597
+ }
4598
+ return {
4599
+ directImports,
4600
+ namespaces
4601
+ };
4602
+ }
4603
+ function parseStaticFunctionCall(node, filter) {
4604
+ const callExpression = node.type === "CallExpression" ? node : node.type === "ChainExpression" && node.expression.type === "CallExpression" ? node.expression : null;
4605
+ if (!callExpression) {
4606
+ return null;
4607
+ }
4608
+ let functionName;
4609
+ let identifierNode;
4610
+ if (callExpression.callee.type === "Identifier") {
4611
+ functionName = callExpression.callee.name;
4612
+ identifierNode = callExpression.callee;
4613
+ } else if (callExpression.callee.type === "ParenthesizedExpression") {
4614
+ if (callExpression.callee.expression.type === "Identifier") {
4615
+ functionName = callExpression.callee.expression.name;
4616
+ identifierNode = callExpression.callee;
4617
+ } else if ((callExpression.callee.expression.type === "TSAsExpression" || callExpression.callee.expression.type === "TSTypeAssertion" || callExpression.callee.expression.type === "TSNonNullExpression") && callExpression.callee.expression.expression.type === "Identifier") {
4618
+ functionName = callExpression.callee.expression.expression.name;
4619
+ identifierNode = callExpression.callee;
4620
+ }
4621
+ }
4622
+ if (functionName && identifierNode && filter.test(functionName)) {
4623
+ return {
4624
+ name: functionName,
4625
+ namespace: null,
4626
+ node: identifierNode,
4627
+ callExpression
4628
+ };
4629
+ }
4630
+ function getParsedMemberExpression(memberExpression) {
4631
+ let memberObjectName;
4632
+ if (memberExpression.object.type === "Identifier") {
4633
+ memberObjectName = memberExpression.object.name;
4634
+ } else if (memberExpression.object.type === "ParenthesizedExpression") {
4635
+ if (memberExpression.object.expression.type === "Identifier") {
4636
+ memberObjectName = memberExpression.object.expression.name;
4637
+ } else if ((memberExpression.object.expression.type === "TSAsExpression" || memberExpression.object.expression.type === "TSTypeAssertion" || memberExpression.object.expression.type === "TSNonNullExpression") && memberExpression.object.expression.expression.type === "Identifier") {
4638
+ memberObjectName = memberExpression.object.expression.expression.name;
4639
+ }
4640
+ }
4641
+ if (memberObjectName) {
4642
+ if (memberExpression.property.type === "Identifier" && filter.test(memberExpression.property.name)) {
4643
+ return {
4644
+ name: memberExpression.property.name,
4645
+ namespace: memberObjectName,
4646
+ node: memberExpression.property
4647
+ };
4648
+ }
4649
+ if (memberExpression.property.type === "Literal" && typeof memberExpression.property.value === "string" && filter.test(memberExpression.property.value)) {
4650
+ return {
4651
+ name: memberExpression.property.value,
4652
+ namespace: memberObjectName,
4653
+ node: memberExpression
4654
+ };
4655
+ }
4656
+ }
4657
+ return null;
4658
+ }
4659
+ if (callExpression.callee.type === "MemberExpression") {
4660
+ const val = getParsedMemberExpression(callExpression.callee);
4661
+ if (val) {
4662
+ return {
4663
+ ...val,
4664
+ callExpression
4665
+ };
4666
+ }
4667
+ } else if (callExpression.callee.type === "ParenthesizedExpression" && callExpression.callee.expression.type === "MemberExpression") {
4668
+ const val = getParsedMemberExpression(callExpression.callee.expression);
4669
+ if (val) {
4670
+ return {
4671
+ ...val,
4672
+ node: callExpression.callee,
4673
+ callExpression
4674
+ };
4675
+ }
4676
+ }
4677
+ return null;
4678
+ }
4679
+ function parseStaticExportIdentifiers(node, filter) {
4680
+ if (node.type === "ExportNamedDeclaration" && node.exportKind !== "type") {
4681
+ if (node.declaration?.type === "VariableDeclaration") {
4682
+ return node.declaration.declarations.map((d) => {
4683
+ if (d.id.type === "Identifier" && (true)) {
4684
+ return {
4685
+ localName: d.id.name,
4686
+ exportedName: d.id.name
4687
+ };
4688
+ }
4689
+ return null;
4690
+ }).filter((v) => !!v);
4691
+ }
4692
+ if (node.declaration?.type === "FunctionDeclaration") {
4693
+ if (node.declaration.id?.type === "Identifier" && (true)) {
4694
+ return [{
4695
+ localName: node.declaration.id.name,
4696
+ exportedName: node.declaration.id.name
4697
+ }];
4698
+ }
4699
+ return [];
4700
+ }
4701
+ if (node.declaration?.type === "ClassDeclaration") {
4702
+ if (node.declaration.id?.type === "Identifier" && (true)) {
4703
+ return [{
4704
+ localName: node.declaration.id.name,
4705
+ exportedName: node.declaration.id.name
4706
+ }];
4707
+ }
4708
+ return [];
4709
+ }
4710
+ if (node.specifiers && node.specifiers.length) {
4711
+ return node.specifiers.map((s) => {
4712
+ if (s.exported.type === "Identifier" && s.exportKind !== "type" && s.local.type === "Identifier" && (true)) {
4713
+ return {
4714
+ localName: s.local.name,
4715
+ exportedName: s.exported.name
4716
+ };
4717
+ }
4718
+ return null;
4719
+ }).filter((v) => !!v);
4720
+ }
4721
+ return [];
4722
+ }
4723
+ if (node.type === "ExportDefaultDeclaration" && (!node.exportKind || node.exportKind === "value")) {
4724
+ if (node.declaration.type === "Identifier") {
4725
+ return [{
4726
+ localName: node.declaration.name,
4727
+ exportedName: "default"
4728
+ }];
4729
+ }
4730
+ if (node.declaration.type === "FunctionDeclaration") {
4731
+ if (node.declaration.id?.type === "Identifier") {
4732
+ return [{
4733
+ localName: node.declaration.id.name,
4734
+ exportedName: "default"
4735
+ }];
4736
+ }
4737
+ return [];
4738
+ }
4739
+ if (node.declaration.type === "ClassDeclaration") {
4740
+ if (node.declaration.id?.type === "Identifier") {
4741
+ return [{
4742
+ localName: node.declaration.id.name,
4743
+ exportedName: "default"
4744
+ }];
4745
+ }
4746
+ return [];
4747
+ }
4748
+ }
4749
+ if (node.type === "TSExportAssignment") {
4750
+ if (node.expression.type === "Identifier") {
4751
+ {
4752
+ return [{
4753
+ localName: node.expression.name,
4754
+ exportedName: "default"
4755
+ }];
4756
+ }
4757
+ }
4758
+ }
4759
+ return [];
4760
+ }
4761
+
4448
4762
  const stringTypes = ["Literal", "TemplateLiteral"];
4449
- const NUXT_LIB_RE = /node_modules\/(?:nuxt|nuxt3|nuxt-nightly)\//;
4763
+ const NUXT_LIB_RE = /node_modules\/(?:nuxt|nuxt3|nuxt-nightly|@nuxt)\//;
4450
4764
  const SUPPORTED_EXT_RE$1 = /\.(?:m?[jt]sx?|vue)/;
4451
4765
  const SCRIPT_RE$1 = /(?<=<script[^>]*>)[\s\S]*?(?=<\/script>)/i;
4452
- const ComposableKeysPlugin = (options) => createUnplugin(() => {
4453
- const composableMeta = {};
4454
- const composableLengths = /* @__PURE__ */ new Set();
4455
- const keyedFunctions = /* @__PURE__ */ new Set();
4456
- for (const { name, ...meta } of options.composables) {
4457
- composableMeta[name] = meta;
4458
- keyedFunctions.add(name);
4459
- composableLengths.add(meta.argumentLength);
4460
- }
4461
- const maxLength = Math.max(...composableLengths);
4462
- const KEYED_FUNCTIONS_RE = new RegExp(`\\b(${[...keyedFunctions].map((f) => escapeRE(f)).join("|")})\\b`);
4766
+ const NUXT_INJECTED_MARKER = "/* nuxt-injected */";
4767
+ function shouldTransformFile(id, extensions) {
4768
+ const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
4769
+ return !NUXT_LIB_RE.test(pathname) && (extensions instanceof RegExp ? extensions.test(pathname) : new RegExp(`\\.(${extensions.map((e) => escapeRE(e)).join("|")})$`).test(pathname)) && parseQuery(search).type !== "style" && !parseQuery(search).macro;
4770
+ }
4771
+ const KeyedFunctionsPlugin = (options) => createUnplugin(() => {
4772
+ const namesToSourcesToFunctionMeta = /* @__PURE__ */ new Map();
4773
+ const defaultExportSources = /* @__PURE__ */ new Set();
4774
+ for (const f of options.keyedFunctions) {
4775
+ let functionName = f.name;
4776
+ const fnSource = typeof f.source === "string" ? stripExtension(f.source) : "";
4777
+ if (f.name === "default") {
4778
+ const parsedSource = parse$1(f.source);
4779
+ defaultExportSources.add(parsedSource.name);
4780
+ functionName = camelCase(parsedSource.name);
4781
+ }
4782
+ if (import.meta.dev) {
4783
+ const sourcesToFunctionMeta2 = namesToSourcesToFunctionMeta.get(functionName);
4784
+ const existingEntry = sourcesToFunctionMeta2?.get(fnSource);
4785
+ if (existingEntry?.source && existingEntry.source === fnSource) {
4786
+ logger.warn(`[nuxt:compiler] [keyed-functions] Duplicate function name \`${functionName}\`${functionName !== f.name ? ` defined as \`${f.name}\`` : ""} with ${f.source ? `the same source \`${f.source}\`` : "no source"} found. Overwriting the existing entry.`);
4787
+ }
4788
+ }
4789
+ let sourcesToFunctionMeta = namesToSourcesToFunctionMeta.get(functionName);
4790
+ if (!sourcesToFunctionMeta) {
4791
+ sourcesToFunctionMeta = /* @__PURE__ */ new Map();
4792
+ namesToSourcesToFunctionMeta.set(functionName, sourcesToFunctionMeta);
4793
+ }
4794
+ sourcesToFunctionMeta.set(fnSource, {
4795
+ ...f,
4796
+ // TODO: use only `fnSource` in Nuxt 5
4797
+ source: typeof f.source === "string" ? fnSource : f.source
4798
+ });
4799
+ }
4800
+ const sources = /* @__PURE__ */ new Set();
4801
+ for (const sourcesToFunctionMeta of namesToSourcesToFunctionMeta.values()) {
4802
+ for (const f of sourcesToFunctionMeta.values()) {
4803
+ if (f.source && typeof f.source === "string") {
4804
+ sources.add(f.source);
4805
+ }
4806
+ }
4807
+ }
4808
+ const CODE_INCLUDE_RE = new RegExp(`\\b(${[...namesToSourcesToFunctionMeta.keys(), ...defaultExportSources].map((f) => escapeRE(f)).join("|")})\\b`);
4463
4809
  return {
4464
- name: "nuxt:composable-keys",
4810
+ name: "nuxt:compiler:keyed-functions",
4465
4811
  enforce: "post",
4466
- transformInclude(id) {
4467
- const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
4468
- return !NUXT_LIB_RE.test(pathname) && SUPPORTED_EXT_RE$1.test(pathname) && parseQuery(search).type !== "style" && !parseQuery(search).macro;
4469
- },
4812
+ transformInclude: (id) => shouldTransformFile(id, SUPPORTED_EXT_RE$1),
4470
4813
  transform: {
4471
4814
  filter: {
4472
- code: { include: KEYED_FUNCTIONS_RE }
4815
+ code: { include: CODE_INCLUDE_RE }
4473
4816
  },
4474
- handler(code, id) {
4475
- const { 0: script = code, index: codeIndex = 0 } = code.match(SCRIPT_RE$1) || { index: 0, 0: code };
4817
+ async handler(code, _id) {
4818
+ const { 0: script = code, index: codeIndex = 0 } = code.match(SCRIPT_RE$1) || { 0: code, index: 0 };
4819
+ const id = stripExtension(_id);
4820
+ const { directImports, namespaces } = processImports(findStaticImports(script).map((i) => parseStaticImport(i)));
4821
+ const shouldConsiderExports = sources.has(id);
4822
+ const localNamesToExportedName = /* @__PURE__ */ new Map();
4823
+ const possibleLocalFunctionNames = new Set(namesToSourcesToFunctionMeta.keys());
4824
+ for (const [localName, directImport] of directImports) {
4825
+ const functionName = directImport.originalName === "default" ? camelCase(parse$1(directImport.source).name) : directImport.originalName;
4826
+ if (namesToSourcesToFunctionMeta.has(functionName)) {
4827
+ possibleLocalFunctionNames.add(localName);
4828
+ }
4829
+ }
4830
+ const autoImports = await options.getAutoImports();
4831
+ const autoImportsToSources = new Map(autoImports.map((i) => [i.as || i.name, i.from]));
4832
+ function getFunctionMetaByLocalName(localName, source) {
4833
+ if (!localName) {
4834
+ return;
4835
+ }
4836
+ const exportedName = localNamesToExportedName.get(localName);
4837
+ if (exportedName) {
4838
+ return namesToSourcesToFunctionMeta.get(exportedName)?.get(source);
4839
+ }
4840
+ const directImport = directImports.get(localName);
4841
+ if (directImport) {
4842
+ const functionName = directImport.originalName === "default" ? camelCase(parse$1(directImport.source).name) : directImport.originalName;
4843
+ const sourcesToMetas = namesToSourcesToFunctionMeta.get(functionName);
4844
+ if (!sourcesToMetas) {
4845
+ return;
4846
+ }
4847
+ const fnMeta = sourcesToMetas.get(source);
4848
+ if (fnMeta) {
4849
+ return fnMeta;
4850
+ }
4851
+ const backwardsCompatibleFnMeta = sourcesToMetas.get("");
4852
+ if (backwardsCompatibleFnMeta?.source === void 0) {
4853
+ const autoImportResolvedSource = stripExtension(resolveAlias$1(autoImportsToSources.get(localName) ?? ""));
4854
+ if (autoImportResolvedSource === source) {
4855
+ return backwardsCompatibleFnMeta;
4856
+ }
4857
+ } else if (backwardsCompatibleFnMeta.source instanceof RegExp && backwardsCompatibleFnMeta.source.test(source)) {
4858
+ return backwardsCompatibleFnMeta;
4859
+ }
4860
+ return;
4861
+ }
4862
+ return namesToSourcesToFunctionMeta.get(localName)?.get(source);
4863
+ }
4864
+ function _resolvePath(path) {
4865
+ let p = path;
4866
+ if (isAbsolute(p)) {
4867
+ return p;
4868
+ }
4869
+ p = resolveAlias$1(p, options.alias);
4870
+ if (isAbsolute(p)) {
4871
+ return p;
4872
+ }
4873
+ return join(parse$1(id).dir, p);
4874
+ }
4476
4875
  const s = new MagicString(code);
4477
- let imports;
4478
4876
  let count = 0;
4479
- const relativeID = isAbsolute(id) ? relative(options.rootDir, id) : id;
4480
- const { pathname: relativePathname } = parseURL(relativeID);
4481
4877
  const scopeTracker = new ScopeTracker({
4482
4878
  preserveExitedScopes: true
4483
4879
  });
4484
- const parseResult = parseAndWalk(script, id, {
4485
- scopeTracker
4486
- });
4487
- scopeTracker.freeze();
4488
- walk(parseResult.program, {
4880
+ const { program } = parseAndWalk(code, _id, {
4489
4881
  scopeTracker,
4490
4882
  enter(node) {
4491
- if (node.type !== "CallExpression" || node.callee.type !== "Identifier") {
4492
- return;
4493
- }
4494
- const name = node.callee.name;
4495
- if (!name || !keyedFunctions.has(name) || node.arguments.length >= maxLength) {
4883
+ if (!shouldConsiderExports) {
4496
4884
  return;
4497
4885
  }
4498
- imports ||= detectImportNames(script, composableMeta);
4499
- if (imports.has(name)) {
4886
+ if (node.type !== "ExportNamedDeclaration" && node.type !== "ExportDefaultDeclaration") {
4500
4887
  return;
4501
4888
  }
4502
- const meta = composableMeta[name];
4503
- const declaration = scopeTracker.getDeclaration(name);
4504
- if (declaration && declaration.type !== "Import") {
4505
- let skip = true;
4506
- if (meta.source) {
4507
- skip = !matchWithStringOrRegex(relativePathname, meta.source);
4508
- }
4509
- if (skip) {
4510
- return;
4889
+ const result = parseStaticExportIdentifiers(node);
4890
+ for (const exportMeta of result) {
4891
+ const { localName, exportedName } = exportMeta;
4892
+ const functionName = exportedName === "default" ? camelCase(parse$1(id).name) : getFunctionMetaByLocalName(exportedName, id)?.name;
4893
+ if (!functionName) {
4894
+ continue;
4511
4895
  }
4896
+ localNamesToExportedName.set(localName, functionName);
4512
4897
  }
4513
- if (node.arguments.length >= meta.argumentLength) {
4898
+ }
4899
+ });
4900
+ scopeTracker.freeze();
4901
+ for (const localName of localNamesToExportedName.keys()) {
4902
+ possibleLocalFunctionNames.add(localName);
4903
+ }
4904
+ const LOCAL_FUNCTION_NAMES_RE = new RegExp(`\\b(${[...possibleLocalFunctionNames].map((f) => escapeRE(f)).join("|")})\\b`);
4905
+ function processKeyedFunction(walkContext, node, handler) {
4906
+ if (node.type !== "CallExpression" && node.type !== "ChainExpression") {
4907
+ return;
4908
+ }
4909
+ const parsedCall = parseStaticFunctionCall(node, LOCAL_FUNCTION_NAMES_RE);
4910
+ if (!parsedCall) {
4911
+ return;
4912
+ }
4913
+ const functionScopeTrackerNode = scopeTracker.getDeclaration(!parsedCall.namespace ? parsedCall.name : parsedCall.namespace);
4914
+ function isKeyedFunctionImport(node2) {
4915
+ return node2?.type === "Import" && node2.importNode.importKind !== "type";
4916
+ }
4917
+ let importSourceResolved;
4918
+ if (localNamesToExportedName.has(parsedCall.name) && functionScopeTrackerNode?.scope === "") {
4919
+ importSourceResolved = id;
4920
+ } else if (isKeyedFunctionImport(functionScopeTrackerNode)) {
4921
+ importSourceResolved = stripExtension(_resolvePath(functionScopeTrackerNode.importNode.source.value));
4922
+ }
4923
+ if (!importSourceResolved) {
4924
+ walkContext.skip();
4925
+ return;
4926
+ }
4927
+ const fnMeta = getFunctionMetaByLocalName(parsedCall.name, importSourceResolved);
4928
+ if (!fnMeta) {
4929
+ walkContext.skip();
4930
+ return;
4931
+ }
4932
+ if (!parsedCall.namespace) {
4933
+ if (parsedCall.callExpression.arguments.length >= fnMeta.argumentLength && !parsedCall.callExpression.arguments.some((a) => a.type === "SpreadElement")) {
4934
+ walkContext.skip();
4514
4935
  return;
4515
4936
  }
4516
- switch (name) {
4517
- case "useState":
4518
- if (stringTypes.includes(node.arguments[0]?.type)) {
4519
- return;
4520
- }
4521
- break;
4522
- case "useFetch":
4523
- case "useLazyFetch":
4524
- if (stringTypes.includes(node.arguments[1]?.type)) {
4525
- return;
4937
+ if (
4938
+ // the function is imported
4939
+ isKeyedFunctionImport(functionScopeTrackerNode) && // import { useKeyed } from '...'
4940
+ (functionScopeTrackerNode.node.type === "ImportSpecifier" && functionScopeTrackerNode.node.importKind !== "type" || functionScopeTrackerNode.node.type === "ImportDefaultSpecifier" && fnMeta.name === "default") && // the function is imported from the correct source when `source` is specified
4941
+ (typeof fnMeta.source === "string" && stripExtension(fnMeta.source) === importSourceResolved || !fnMeta.source && stripExtension(_resolvePath(autoImportsToSources.get(parsedCall.name) ?? "")) === importSourceResolved || fnMeta.source instanceof RegExp && fnMeta.source.test(importSourceResolved)) || localNamesToExportedName.has(parsedCall.name) && functionScopeTrackerNode?.scope === ""
4942
+ ) {
4943
+ handler({ parsedCall, fnMeta });
4944
+ }
4945
+ walkContext.skip();
4946
+ return;
4947
+ }
4948
+ if (parsedCall.namespace) {
4949
+ const namespacedImportMeta = namespaces.get(importSourceResolved);
4950
+ const namespaceScopeTrackerNode = scopeTracker.getDeclaration(parsedCall.namespace);
4951
+ if (namespacedImportMeta && namespacedImportMeta.namespaces.has(parsedCall.namespace) && namespaceScopeTrackerNode?.type === "Import" && namespaceScopeTrackerNode.node.type === "ImportNamespaceSpecifier") {
4952
+ handler({ parsedCall, fnMeta });
4953
+ }
4954
+ walkContext.skip();
4955
+ return;
4956
+ }
4957
+ }
4958
+ walk(program, {
4959
+ scopeTracker,
4960
+ enter(node) {
4961
+ processKeyedFunction(this, node, ({ parsedCall, fnMeta }) => {
4962
+ const lastArgument = parsedCall.callExpression.arguments[parsedCall.callExpression.arguments.length - 1];
4963
+ if (lastArgument?.type === "Literal" && typeof lastArgument.value === "string" && lastArgument.end + NUXT_INJECTED_MARKER.length + 1 < parsedCall.callExpression.end) {
4964
+ let wasKeyInjected = true;
4965
+ for (let i2 = 0; i2 < NUXT_INJECTED_MARKER.length; i2++) {
4966
+ if (code[codeIndex + lastArgument.end + 1 + i2] !== NUXT_INJECTED_MARKER[i2]) {
4967
+ wasKeyInjected = false;
4968
+ break;
4969
+ }
4526
4970
  }
4527
- break;
4528
- case "useAsyncData":
4529
- case "useLazyAsyncData":
4530
- if (stringTypes.includes(node.arguments[0]?.type) || stringTypes.includes(node.arguments[node.arguments.length - 1]?.type)) {
4971
+ if (wasKeyInjected) {
4531
4972
  return;
4532
4973
  }
4533
- break;
4534
- }
4535
- const newCode = code.slice(codeIndex + node.start, codeIndex + node.end - 1).trim();
4536
- const endsWithComma = newCode[newCode.length - 1] === ",";
4537
- s.appendLeft(
4538
- codeIndex + node.end - 1,
4539
- (node.arguments.length && !endsWithComma ? ", " : "") + "'$" + hash(`${relativeID}-${++count}`).slice(0, 10) + "'"
4540
- );
4974
+ }
4975
+ switch (parsedCall.name) {
4976
+ case "useState":
4977
+ if (stringTypes.includes(parsedCall.callExpression.arguments[0]?.type) && typeof fnMeta.source === "string" && stripExtension(fnMeta.source) === stripExtension(resolveAlias$1("#app/composables/state", options.alias))) {
4978
+ return;
4979
+ }
4980
+ break;
4981
+ case "useFetch":
4982
+ case "useLazyFetch":
4983
+ if (stringTypes.includes(parsedCall.callExpression.arguments[1]?.type) && typeof fnMeta.source === "string" && stripExtension(fnMeta.source) === stripExtension(resolveAlias$1("#app/composables/fetch", options.alias))) {
4984
+ return;
4985
+ }
4986
+ break;
4987
+ case "useAsyncData":
4988
+ case "useLazyAsyncData":
4989
+ if (stringTypes.includes(parsedCall.callExpression.arguments[0]?.type) && typeof fnMeta.source === "string" && stripExtension(fnMeta.source) === stripExtension(resolveAlias$1("#app/composables/asyncData", options.alias))) {
4990
+ return;
4991
+ }
4992
+ break;
4993
+ }
4994
+ let i = codeIndex + parsedCall.callExpression.end - 2;
4995
+ while (i >= codeIndex + parsedCall.callExpression.start && isWhitespace(code[i])) {
4996
+ i--;
4997
+ }
4998
+ const endsWithComma = code[i] === ",";
4999
+ s.appendLeft(
5000
+ codeIndex + parsedCall.callExpression.end - 1,
5001
+ (parsedCall.callExpression.arguments.length && !endsWithComma ? ", " : "") + "'$" + hash(`${_id}-${++count}`).slice(0, 10) + `' ${NUXT_INJECTED_MARKER}`
5002
+ );
5003
+ });
4541
5004
  }
4542
5005
  });
4543
5006
  if (s.hasChanged()) {
@@ -4550,170 +5013,6 @@ const ComposableKeysPlugin = (options) => createUnplugin(() => {
4550
5013
  }
4551
5014
  };
4552
5015
  });
4553
- const NUXT_IMPORT_RE = /nuxt|#app|#imports/;
4554
- function detectImportNames(code, composableMeta) {
4555
- const names = /* @__PURE__ */ new Set();
4556
- function addName(name, specifier) {
4557
- const source = composableMeta[name]?.source;
4558
- if (source && matchWithStringOrRegex(specifier, source)) {
4559
- return;
4560
- }
4561
- names.add(name);
4562
- }
4563
- for (const i of findStaticImports(code)) {
4564
- if (NUXT_IMPORT_RE.test(i.specifier)) {
4565
- continue;
4566
- }
4567
- const { namedImports = {}, defaultImport, namespacedImport } = parseStaticImport(i);
4568
- for (const name in namedImports) {
4569
- addName(namedImports[name], i.specifier);
4570
- }
4571
- if (defaultImport) {
4572
- addName(defaultImport, i.specifier);
4573
- }
4574
- if (namespacedImport) {
4575
- addName(namespacedImport, i.specifier);
4576
- }
4577
- }
4578
- return names;
4579
- }
4580
-
4581
- const VIRTUAL_RE = /^\0?virtual:(?:nuxt:)?/;
4582
- function ResolveDeepImportsPlugin(nuxt) {
4583
- const exclude = ["virtual:", "\0virtual:", "/__skip_vite", "@vitest/"];
4584
- const conditions = {};
4585
- function resolveConditions(environment) {
4586
- const resolvedConditions = /* @__PURE__ */ new Set([nuxt.options.dev ? "development" : "production", ...environment.config.resolve.conditions]);
4587
- if (resolvedConditions.has("browser")) {
4588
- resolvedConditions.add("web");
4589
- resolvedConditions.add("import");
4590
- resolvedConditions.add("module");
4591
- resolvedConditions.add("default");
4592
- }
4593
- if (environment.config.mode === "test") {
4594
- resolvedConditions.add("import");
4595
- resolvedConditions.add("require");
4596
- }
4597
- return [...resolvedConditions];
4598
- }
4599
- return {
4600
- name: "nuxt:resolve-bare-imports",
4601
- enforce: "post",
4602
- async resolveId(id, importer) {
4603
- if (!importer || isAbsolute(id) || !isAbsolute(importer) && !VIRTUAL_RE.test(importer) || exclude.some((e) => id.startsWith(e))) {
4604
- return;
4605
- }
4606
- const normalisedId = resolveAlias$1(normalize(id), nuxt.options.alias);
4607
- const isNuxtTemplate = importer.startsWith("virtual:nuxt");
4608
- const normalisedImporter = (isNuxtTemplate ? decodeURIComponent(importer) : importer).replace(VIRTUAL_RE, "");
4609
- if (nuxt.options.experimental.templateImportResolution !== false && isNuxtTemplate) {
4610
- const template = nuxt.options.build.templates.find((t) => resolve(nuxt.options.buildDir, t.filename) === normalisedImporter);
4611
- if (template?._path) {
4612
- const res2 = await this.resolve?.(normalisedId, template._path, { skipSelf: true });
4613
- if (res2 !== void 0 && res2 !== null) {
4614
- return res2;
4615
- }
4616
- }
4617
- }
4618
- const dir = parseNodeModulePath(normalisedImporter).dir || pkgDir;
4619
- const res = await this.resolve?.(normalisedId, dir, { skipSelf: true });
4620
- if (res !== void 0 && res !== null) {
4621
- return res;
4622
- }
4623
- const environmentConditions = conditions[this.environment.name] ||= resolveConditions(this.environment);
4624
- const path = resolveModulePath(id, {
4625
- from: [dir, ...nuxt.options.modulesDir].map((d) => directoryToURL(d)),
4626
- suffixes: ["", "index"],
4627
- conditions: environmentConditions,
4628
- try: true
4629
- });
4630
- if (!path) {
4631
- logger.debug("Could not resolve id", id, importer);
4632
- return null;
4633
- }
4634
- return normalize(path);
4635
- }
4636
- };
4637
- }
4638
-
4639
- const runtimeDependencies = [
4640
- // other deps
4641
- "devalue",
4642
- "klona",
4643
- // unjs ecosystem
4644
- "defu",
4645
- "ufo",
4646
- "h3",
4647
- "destr",
4648
- "consola",
4649
- "hookable",
4650
- "unctx",
4651
- "cookie-es",
4652
- "perfect-debounce",
4653
- "radix3",
4654
- "ohash",
4655
- "pathe",
4656
- "uncrypto"
4657
- ];
4658
-
4659
- function ResolveExternalsPlugin(nuxt) {
4660
- let external = /* @__PURE__ */ new Set();
4661
- const nitro = useNitro();
4662
- return {
4663
- name: "nuxt:resolve-externals",
4664
- enforce: "pre",
4665
- async config() {
4666
- const { runtimeDependencies: runtimeNitroDependencies = [] } = await tryImportModule("nitropack/runtime/meta", {
4667
- url: new URL(import.meta.url)
4668
- }) || {};
4669
- external = /* @__PURE__ */ new Set([
4670
- // explicit dependencies we use in our ssr renderer - these can be inlined (if necessary) in the nitro build
4671
- "unhead",
4672
- "@unhead/vue",
4673
- "@nuxt/devalue",
4674
- "rou3",
4675
- "unstorage",
4676
- // ensure we only have one version of vue if nitro is going to inline anyway
4677
- ...nitro.options.inlineDynamicImports ? ["vue", "@vue/server-renderer"] : [],
4678
- ...runtimeDependencies,
4679
- // dependencies we might share with nitro - these can be inlined (if necessary) in the nitro build
4680
- ...runtimeNitroDependencies
4681
- ]);
4682
- return {
4683
- optimizeDeps: {
4684
- exclude: Array.from(external)
4685
- }
4686
- };
4687
- },
4688
- applyToEnvironment(environment) {
4689
- if (nuxt.options.dev || environment.name !== "ssr") {
4690
- return false;
4691
- }
4692
- return {
4693
- name: "nuxt:resolve-externals:external",
4694
- async resolveId(id, importer) {
4695
- if (!external.has(id)) {
4696
- return;
4697
- }
4698
- const res = await this.resolve?.(id, importer, { skipSelf: true });
4699
- if (res !== void 0 && res !== null) {
4700
- if (res.id === id) {
4701
- res.id = resolveModulePath(res.id, {
4702
- try: true,
4703
- from: importer,
4704
- extensions: nuxt.options.extensions
4705
- }) || res.id;
4706
- }
4707
- return {
4708
- ...res,
4709
- external: "absolute"
4710
- };
4711
- }
4712
- }
4713
- };
4714
- }
4715
- };
4716
- }
4717
5016
 
4718
5017
  function transformAndMinify(input, options) {
4719
5018
  const oxcOptions = tryUseNuxt()?.options.oxc;
@@ -4942,12 +5241,36 @@ const VirtualFSPlugin = (nuxt, options) => createUnplugin((_, meta) => {
4942
5241
  }
4943
5242
  }
4944
5243
  }
5244
+ const relevantAliases = /* @__PURE__ */ new Set();
5245
+ for (const key in alias) {
5246
+ const value = alias[key];
5247
+ if (value && Object.keys(nuxt.vfs).some((vfsPath) => vfsPath.startsWith(value))) {
5248
+ relevantAliases.add(escapeDirectory(key));
5249
+ }
5250
+ }
5251
+ const vfsEntries = /* @__PURE__ */ new Set();
5252
+ for (const key in nuxt.vfs) {
5253
+ if (!key.startsWith("#build/") && !key.startsWith(nuxt.options.buildDir)) {
5254
+ vfsEntries.add(escapeDirectory(dirname(key)));
5255
+ }
5256
+ }
5257
+ const filter = {
5258
+ id: [
5259
+ PREFIX_RE,
5260
+ RELATIVE_ID_RE,
5261
+ /^#build\//,
5262
+ new RegExp("^(\\w:)?" + escapeDirectory(nuxt.options.buildDir)),
5263
+ ...Array.from(vfsEntries).map((id) => new RegExp("^" + id)),
5264
+ ...relevantAliases.size ? [new RegExp("^" + Array.from(relevantAliases).join("|") + "([\\\\/]|$)")] : []
5265
+ ]
5266
+ };
4945
5267
  return {
4946
5268
  name: "nuxt:virtual",
4947
- resolveId: meta.framework === "vite" ? void 0 : { order: "pre", handler: resolveId },
5269
+ resolveId: meta.framework === "vite" ? void 0 : { order: "pre", filter, handler: resolveId },
4948
5270
  vite: {
4949
5271
  resolveId: {
4950
5272
  order: "pre",
5273
+ filter,
4951
5274
  handler(id, importer) {
4952
5275
  const res = resolveId(id, importer);
4953
5276
  if (res) {
@@ -4959,15 +5282,17 @@ const VirtualFSPlugin = (nuxt, options) => createUnplugin((_, meta) => {
4959
5282
  }
4960
5283
  }
4961
5284
  },
4962
- loadInclude(id) {
4963
- return PREFIX_RE.test(id) && withoutQuery(withoutPrefix(decodeURIComponent(id))) in nuxt.vfs;
4964
- },
4965
- load(id) {
4966
- const key = withoutQuery(withoutPrefix(decodeURIComponent(id)));
4967
- return {
4968
- code: nuxt.vfs[key] || "",
4969
- map: null
4970
- };
5285
+ load: {
5286
+ filter: {
5287
+ id: PREFIX_RE
5288
+ },
5289
+ handler(id) {
5290
+ const key = withoutQuery(withoutPrefix(decodeURIComponent(id)));
5291
+ return {
5292
+ code: nuxt.vfs[key] || "",
5293
+ map: null
5294
+ };
5295
+ }
4971
5296
  }
4972
5297
  };
4973
5298
  });
@@ -4978,6 +5303,9 @@ const QUERY_RE = /\?.*$/;
4978
5303
  function withoutQuery(id) {
4979
5304
  return id.replace(QUERY_RE, "");
4980
5305
  }
5306
+ function escapeDirectory(path) {
5307
+ return escapeRE(path).replace(/\//g, "[\\\\/]");
5308
+ }
4981
5309
 
4982
5310
  function createNuxt(options) {
4983
5311
  const hooks = createHooks();
@@ -4987,7 +5315,7 @@ function createNuxt(options) {
4987
5315
  hooks.callHookWith = (...args) => runWithNuxtContext(nuxt, () => callHookWith(...args));
4988
5316
  const nuxt = {
4989
5317
  __name: randomUUID(),
4990
- _version: version,
5318
+ _version: pkg.version,
4991
5319
  _asyncLocalStorageModule: options.experimental.debugModuleMutation ? new AsyncLocalStorage() : void 0,
4992
5320
  hooks,
4993
5321
  callHook: hooks.callHook,
@@ -5087,6 +5415,30 @@ Using \`${fallbackCompatibilityDate}\` as fallback. More info at: ${colors.under
5087
5415
  }
5088
5416
  }
5089
5417
  });
5418
+ addTypeTemplate({
5419
+ filename: "types/nitro-layouts.d.ts",
5420
+ getContents: ({ app }) => {
5421
+ return [
5422
+ `export type LayoutKey = ${Object.keys(app.layouts).map((name) => genString(name)).join(" | ") || "string"}`,
5423
+ "declare module 'nitropack' {",
5424
+ " interface NitroRouteConfig {",
5425
+ " appLayout?: LayoutKey | false",
5426
+ " }",
5427
+ " interface NitroRouteRules {",
5428
+ " appLayout?: LayoutKey | false",
5429
+ " }",
5430
+ "}",
5431
+ "declare module 'nitropack/types' {",
5432
+ " interface NitroRouteConfig {",
5433
+ " appLayout?: LayoutKey | false",
5434
+ " }",
5435
+ " interface NitroRouteRules {",
5436
+ " appLayout?: LayoutKey | false",
5437
+ " }",
5438
+ "}"
5439
+ ].join("\n");
5440
+ }
5441
+ }, { nuxt: true, nitro: true, node: true });
5090
5442
  if (nuxt.options.typescript.builder !== false) {
5091
5443
  const envMap = {
5092
5444
  // defaults from `builder` based on package name
@@ -5113,10 +5465,11 @@ Using \`${fallbackCompatibilityDate}\` as fallback. More info at: ${colors.under
5113
5465
  }
5114
5466
  const packageJSON = await readPackageJSON(nuxt.options.rootDir).catch(() => ({}));
5115
5467
  nuxt._dependencies = /* @__PURE__ */ new Set([...Object.keys(packageJSON.dependencies || {}), ...Object.keys(packageJSON.devDependencies || {})]);
5468
+ nuxt["~runtimeDependencies"] = [...runtimeDependencies];
5116
5469
  let paths;
5117
5470
  nuxt.hook("nitro:config", async (nitroConfig) => {
5118
5471
  paths ||= await resolveTypescriptPaths(nuxt);
5119
- nitroConfig.typescript = defu$1(nitroConfig.typescript, {
5472
+ nitroConfig.typescript = defu(nitroConfig.typescript, {
5120
5473
  tsConfig: { compilerOptions: { paths: { ...paths } } }
5121
5474
  });
5122
5475
  });
@@ -5144,10 +5497,11 @@ Using \`${fallbackCompatibilityDate}\` as fallback. More info at: ${colors.under
5144
5497
  }
5145
5498
  opts.sharedReferences.push({ path: resolve(nuxt.options.buildDir, "types/runtime-config.d.ts") });
5146
5499
  opts.sharedReferences.push({ path: resolve(nuxt.options.buildDir, "types/app.config.d.ts") });
5500
+ opts.sharedReferences.push({ path: resolve(nuxt.options.buildDir, "types/shared-imports.d.ts") });
5147
5501
  paths ||= await resolveTypescriptPaths(nuxt);
5148
- opts.tsConfig.compilerOptions = defu$1(opts.tsConfig.compilerOptions, { paths: { ...paths } });
5149
- opts.nodeTsConfig.compilerOptions = defu$1(opts.nodeTsConfig.compilerOptions, { paths: { ...paths } });
5150
- opts.sharedTsConfig.compilerOptions = defu$1(opts.sharedTsConfig.compilerOptions, { paths: { ...paths } });
5502
+ opts.tsConfig.compilerOptions = defu(opts.tsConfig.compilerOptions, { paths: { ...paths } });
5503
+ opts.nodeTsConfig.compilerOptions = defu(opts.nodeTsConfig.compilerOptions, { paths: { ...paths } });
5504
+ opts.sharedTsConfig.compilerOptions = defu(opts.sharedTsConfig.compilerOptions, { paths: { ...paths } });
5151
5505
  for (const dirs of layerDirs) {
5152
5506
  const declaration = join(dirs.root, "index.d.ts");
5153
5507
  if (existsSync(declaration)) {
@@ -5179,13 +5533,6 @@ Using \`${fallbackCompatibilityDate}\` as fallback. More info at: ${colors.under
5179
5533
  }
5180
5534
  }), { server: false });
5181
5535
  addBuildPlugin(RemovePluginMetadataPlugin(nuxt));
5182
- addBuildPlugin(ComposableKeysPlugin({
5183
- sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client,
5184
- rootDir: nuxt.options.rootDir,
5185
- composables: nuxt.options.optimization.keyedComposables
5186
- }));
5187
- addVitePlugin(() => ResolveDeepImportsPlugin(nuxt));
5188
- addVitePlugin(() => ResolveExternalsPlugin(nuxt), { prepend: true });
5189
5536
  addBuildPlugin(PrehydrateTransformPlugin({ sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client }));
5190
5537
  if (nuxt.options.experimental.localLayerAliases) {
5191
5538
  addBuildPlugin(LayerAliasingPlugin({
@@ -5224,17 +5571,23 @@ Using \`${fallbackCompatibilityDate}\` as fallback. More info at: ${colors.under
5224
5571
  include: sharedPatterns,
5225
5572
  patterns: createImportProtectionPatterns(nuxt, { context: "shared" })
5226
5573
  };
5227
- addVitePlugin(() => ImpoundPlugin.vite(sharedProtectionConfig), { server: false });
5228
- addWebpackPlugin(() => ImpoundPlugin.webpack(sharedProtectionConfig), { server: false });
5574
+ addBuildPlugin({
5575
+ vite: () => ImpoundPlugin.vite(sharedProtectionConfig),
5576
+ webpack: () => ImpoundPlugin.webpack(sharedProtectionConfig),
5577
+ rspack: () => ImpoundPlugin.rspack(sharedProtectionConfig)
5578
+ }, { server: false });
5229
5579
  const nuxtProtectionConfig = {
5230
5580
  cwd: nuxt.options.rootDir,
5231
5581
  // Exclude top-level resolutions by plugins
5232
5582
  exclude: [relative(nuxt.options.rootDir, join(nuxt.options.srcDir, "index.html")), ...sharedPatterns],
5233
5583
  patterns: createImportProtectionPatterns(nuxt, { context: "nuxt-app" })
5234
5584
  };
5585
+ addBuildPlugin({
5586
+ webpack: () => ImpoundPlugin.webpack(nuxtProtectionConfig),
5587
+ rspack: () => ImpoundPlugin.rspack(nuxtProtectionConfig)
5588
+ });
5235
5589
  addVitePlugin(() => Object.assign(ImpoundPlugin.vite({ ...nuxtProtectionConfig, error: false }), { name: "nuxt:import-protection" }), { client: false });
5236
5590
  addVitePlugin(() => Object.assign(ImpoundPlugin.vite({ ...nuxtProtectionConfig, error: true }), { name: "nuxt:import-protection" }), { server: false });
5237
- addWebpackPlugin(() => ImpoundPlugin.webpack(nuxtProtectionConfig));
5238
5591
  });
5239
5592
  if (!nuxt.options.dev) {
5240
5593
  addBuildPlugin(DevOnlyPlugin({
@@ -5375,7 +5728,7 @@ Using \`${fallbackCompatibilityDate}\` as fallback. More info at: ${colors.under
5375
5728
  _internal_install: "@nuxt/image"
5376
5729
  });
5377
5730
  }
5378
- if (nuxt.options.builder === "@nuxt/webpack-builder") {
5731
+ if (nuxt.options.builder === "@nuxt/webpack-builder" || nuxt.options.builder === "@nuxt/rspack-builder") {
5379
5732
  addPlugin(resolve(nuxt.options.appDir, "plugins/preload.server"));
5380
5733
  }
5381
5734
  if (nuxt.options.debug && nuxt.options.debug.hooks && (nuxt.options.debug.hooks === true || nuxt.options.debug.hooks.client)) {
@@ -5387,7 +5740,21 @@ Using \`${fallbackCompatibilityDate}\` as fallback. More info at: ${colors.under
5387
5740
  await installModules(modules, resolvedModulePaths, nuxt);
5388
5741
  nuxt._ignore = ignore(nuxt.options.ignoreOptions);
5389
5742
  nuxt._ignore.add(resolveIgnorePatterns());
5743
+ let unimport;
5744
+ nuxt.hook("imports:context", (ctx) => {
5745
+ unimport = ctx;
5746
+ });
5390
5747
  await nuxt.callHook("modules:done");
5748
+ const normalizedKeyedFunctions = await Promise.all(nuxt.options.optimization.keyedComposables.map(async ({ source, ...rest }) => ({
5749
+ ...rest,
5750
+ source: typeof source === "string" ? await resolvePath(source, { fallbackToOriginal: true }) ?? source : source
5751
+ })));
5752
+ addBuildPlugin(KeyedFunctionsPlugin({
5753
+ sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client,
5754
+ keyedFunctions: normalizedKeyedFunctions,
5755
+ alias: nuxt.options.alias,
5756
+ getAutoImports: unimport.getImports
5757
+ }));
5391
5758
  nuxt.options.css = nuxt.options.css.filter((value, index, array) => !array.includes(value, index + 1));
5392
5759
  if (nuxt.options.experimental.componentIslands) {
5393
5760
  addComponent({
@@ -5397,9 +5764,6 @@ Using \`${fallbackCompatibilityDate}\` as fallback. More info at: ${colors.under
5397
5764
  filePath: resolve(nuxt.options.appDir, "components/nuxt-island")
5398
5765
  });
5399
5766
  }
5400
- if (!nuxt.options.dev && nuxt.options.experimental.payloadExtraction) {
5401
- addPlugin(resolve(nuxt.options.appDir, "plugins/payload.client"));
5402
- }
5403
5767
  if (nuxt.options.experimental.crossOriginPrefetch) {
5404
5768
  addPlugin(resolve(nuxt.options.appDir, "plugins/cross-origin-prefetch.client"));
5405
5769
  }
@@ -5419,12 +5783,12 @@ Using \`${fallbackCompatibilityDate}\` as fallback. More info at: ${colors.under
5419
5783
  addPlugin(resolve(nuxt.options.appDir, "plugins/revive-payload.client"));
5420
5784
  addPlugin(resolve(nuxt.options.appDir, "plugins/revive-payload.server"));
5421
5785
  }
5786
+ addRouteMiddleware({
5787
+ name: "manifest-route-rule",
5788
+ path: resolve(nuxt.options.appDir, "middleware/route-rules"),
5789
+ global: true
5790
+ });
5422
5791
  if (nuxt.options.experimental.appManifest) {
5423
- addRouteMiddleware({
5424
- name: "manifest-route-rule",
5425
- path: resolve(nuxt.options.appDir, "middleware/manifest-route-rule"),
5426
- global: true
5427
- });
5428
5792
  if (nuxt.options.experimental.checkOutdatedBuildInterval !== false) {
5429
5793
  addPlugin(resolve(nuxt.options.appDir, "plugins/check-outdated-build.client"));
5430
5794
  }
@@ -5485,14 +5849,7 @@ export default defineNuxtPlugin({
5485
5849
  });
5486
5850
  addModuleTranspiles(nuxt);
5487
5851
  await bundleServer(nuxt);
5488
- const nitro = useNitro();
5489
- if (nitro.options.static && nuxt.options.experimental.payloadExtraction === void 0) {
5490
- logger.warn("Using experimental payload extraction for full-static output. You can opt-out by setting `experimental.payloadExtraction` to `false`.");
5491
- nuxt.options.experimental.payloadExtraction = true;
5492
- }
5493
- nitro.options.replace["process.env.NUXT_PAYLOAD_EXTRACTION"] = String(!!nuxt.options.experimental.payloadExtraction);
5494
- nitro.options._config.replace["process.env.NUXT_PAYLOAD_EXTRACTION"] = String(!!nuxt.options.experimental.payloadExtraction);
5495
- if (!nuxt.options.dev && nuxt.options.experimental.payloadExtraction) {
5852
+ if (nuxt.options.experimental.payloadExtraction) {
5496
5853
  addPlugin(resolve(nuxt.options.appDir, "plugins/payload.client"));
5497
5854
  }
5498
5855
  if (!satisfies(coerce(nuxt._version) ?? nuxt._version, nuxt.options.future.compatibilityVersion + ".x")) {
@@ -5516,7 +5873,7 @@ async function loadNuxt(opts) {
5516
5873
  }
5517
5874
  }
5518
5875
  if (!options._modules.some((m) => m === "@nuxt/scripts" || m === "@nuxt/scripts-nightly")) {
5519
- options.imports = defu$1(options.imports, {
5876
+ options.imports = defu(options.imports, {
5520
5877
  presets: [scriptsStubsPreset]
5521
5878
  });
5522
5879
  }
@@ -5563,9 +5920,9 @@ async function loadNuxt(opts) {
5563
5920
  delete options.runtimeConfig.app[key];
5564
5921
  }
5565
5922
  }
5566
- createPortalProperties(options.nitro.runtimeConfig, options, ["nitro.runtimeConfig", "runtimeConfig"]);
5567
- createPortalProperties(options.nitro.routeRules, options, ["nitro.routeRules", "routeRules"]);
5568
5923
  const nitroOptions = options.nitro;
5924
+ createPortalProperties(nitroOptions.runtimeConfig, options, ["nitro.runtimeConfig", "runtimeConfig"]);
5925
+ createPortalProperties(nitroOptions.routeRules, options, ["nitro.routeRules", "routeRules"]);
5569
5926
  Object.defineProperties(options, {
5570
5927
  nitro: {
5571
5928
  configurable: false,
@@ -5679,8 +6036,8 @@ async function resolveModules(nuxt) {
5679
6036
  const NESTED_PKG_RE = /^[^@]+\//;
5680
6037
  async function resolveTypescriptPaths(nuxt) {
5681
6038
  nuxt.options.typescript.hoist ||= [];
5682
- const paths = Object.fromEntries(await Promise.all(nuxt.options.typescript.hoist.map(async (pkg) => {
5683
- const [_pkg = pkg, _subpath] = NESTED_PKG_RE.test(pkg) ? pkg.split("/") : [pkg];
6039
+ const paths = Object.fromEntries(await Promise.all(nuxt.options.typescript.hoist.map(async (pkg2) => {
6040
+ const [_pkg = pkg2, _subpath] = NESTED_PKG_RE.test(pkg2) ? pkg2.split("/") : [pkg2];
5684
6041
  const subpath = _subpath ? "/" + _subpath : "";
5685
6042
  if (nuxt._dependencies?.has(_pkg) && !(_pkg in nightlies)) {
5686
6043
  return [];
@@ -5689,12 +6046,12 @@ async function resolveTypescriptPaths(nuxt) {
5689
6046
  const nightly = nightlies[_pkg];
5690
6047
  const path2 = await resolveTypePath(nightly + subpath, subpath, nuxt.options.modulesDir);
5691
6048
  if (path2) {
5692
- return [[pkg, [path2]], [nightly + subpath, [path2]]];
6049
+ return [[pkg2, [path2]], [nightly + subpath, [path2]]];
5693
6050
  }
5694
6051
  }
5695
6052
  const path = await resolveTypePath(_pkg + subpath, subpath, nuxt.options.modulesDir);
5696
6053
  if (path) {
5697
- return [[pkg, [path]]];
6054
+ return [[pkg2, [path]]];
5698
6055
  }
5699
6056
  return [];
5700
6057
  })).then((r) => r.flat()));
@@ -5936,13 +6293,13 @@ const schemaNodeTemplate = {
5936
6293
  ` * Configuration for \`${importName}\``,
5937
6294
  ...options.addJSDocTags && link ? [` * @see ${link}`] : [],
5938
6295
  ` */`,
5939
- ` [${configKey}]${options.unresolved ? "?" : ""}: typeof ${genDynamicImport(importName, { wrapper: false })}.default extends NuxtModule<infer O, unknown, boolean> ? ${options.unresolved ? "Partial<O>" : "O"} : Record<string, any>`
6296
+ ` [${configKey}]${options.unresolved ? "?" : ""}: typeof ${genDynamicImport(importName, { wrapper: false })}.default extends NuxtModule<infer O, unknown, boolean> ? ${options.unresolved ? "Partial<O>" : "O"} | false : Record<string, any> | false`
5940
6297
  ];
5941
6298
  }),
5942
6299
  modules.length > 0 && options.unresolved ? ` modules?: (undefined | null | false | NuxtModule<any> | string | [NuxtModule | string, Record<string, any>] | ${modules.map(([configKey, importName, mod]) => `[${genString(mod.meta?.rawPath || importName)}, Exclude<NuxtConfig[${configKey}], boolean>]`).join(" | ")})[],` : ""
5943
6300
  ].filter(Boolean);
5944
6301
  const moduleDependencies = modules.flatMap(([_configKey, importName, mod]) => [
5945
- ` [${genString(mod.meta.name || importName)}]?: ModuleDependencyMeta<typeof ${genDynamicImport(importName, { wrapper: false })}.default extends NuxtModule<infer O> ? O : Record<string, unknown>>`
6302
+ ` [${genString(mod.meta.name || importName)}]?: ModuleDependencyMeta<typeof ${genDynamicImport(importName, { wrapper: false })}.default extends NuxtModule<infer O> ? O | false : Record<string, unknown>> | false`
5946
6303
  ]).join("\n");
5947
6304
  return [
5948
6305
  "import { NuxtModule, ModuleDependencyMeta } from '@nuxt/schema'",
@@ -6151,11 +6508,14 @@ const nuxtConfigTemplate = {
6151
6508
  headers: void 0
6152
6509
  };
6153
6510
  const shouldEnableComponentIslands = ctx.nuxt.options.experimental.componentIslands && (ctx.nuxt.options.dev || ctx.nuxt.options.experimental.componentIslands !== "auto" || ctx.app.pages?.some((p) => p.mode === "server") || ctx.app.components?.some((c) => c.mode === "server" && !ctx.app.components.some((other) => other.pascalName === c.pascalName && other.mode === "client")));
6511
+ const nitro = useNitro();
6512
+ const hasCachedRoutes = Object.values(nitro.options.routeRules).some((r) => r.isr || r.cache);
6513
+ const payloadExtraction = !!ctx.nuxt.options.experimental.payloadExtraction && (nitro.options.static || hasCachedRoutes || nitro.options.prerender.routes.length > 0 || Object.values(nitro.options.routeRules).some((r) => r.prerender));
6154
6514
  return [
6155
6515
  ...Object.entries(ctx.nuxt.options.app).map(([k, v]) => `export const ${camelCase("app-" + k)} = ${JSON.stringify(v)}`),
6156
6516
  `export const renderJsonPayloads = ${!!ctx.nuxt.options.experimental.renderJsonPayloads}`,
6157
6517
  `export const componentIslands = ${shouldEnableComponentIslands}`,
6158
- `export const payloadExtraction = ${!!ctx.nuxt.options.experimental.payloadExtraction}`,
6518
+ `export const payloadExtraction = ${payloadExtraction}`,
6159
6519
  `export const cookieStore = ${!!ctx.nuxt.options.experimental.cookieStore}`,
6160
6520
  `export const appManifest = ${!!ctx.nuxt.options.experimental.appManifest}`,
6161
6521
  `export const remoteComponentIslands = ${typeof ctx.nuxt.options.experimental.componentIslands === "object" && ctx.nuxt.options.experimental.componentIslands.remoteIsland}`,
@@ -6172,7 +6532,7 @@ const nuxtConfigTemplate = {
6172
6532
  `export const outdatedBuildInterval = ${ctx.nuxt.options.experimental.checkOutdatedBuildInterval}`,
6173
6533
  `export const multiApp = ${!!ctx.nuxt.options.future.multiApp}`,
6174
6534
  `export const chunkErrorEvent = ${ctx.nuxt.options.experimental.emitRouteChunkError ? ctx.nuxt.options.builder === "@nuxt/vite-builder" ? '"vite:preloadError"' : '"nuxt:preloadError"' : "false"}`,
6175
- `export const crawlLinks = ${!!ctx.nuxt._nitro.options.prerender.crawlLinks}`,
6535
+ `export const crawlLinks = ${!!nitro.options.prerender.crawlLinks}`,
6176
6536
  `export const spaLoadingTemplateOutside = ${ctx.nuxt.options.experimental.spaLoadingTemplateLocation === "body"}`,
6177
6537
  `export const purgeCachedData = ${!!ctx.nuxt.options.experimental.purgeCachedData}`,
6178
6538
  `export const granularCachedData = ${!!ctx.nuxt.options.experimental.granularCachedData}`,
@@ -6540,14 +6900,14 @@ async function getVueHash(nuxt) {
6540
6900
  const start = Date.now();
6541
6901
  await writeCache(nuxt.options.buildDir, nuxt.options.buildDir, cacheFile);
6542
6902
  const elapsed = Date.now() - start;
6543
- consola$1.success(`Cached Vue client and server builds in \`${elapsed}ms\`.`);
6903
+ consola.success(`Cached Vue client and server builds in \`${elapsed}ms\`.`);
6544
6904
  },
6545
6905
  async restoreCache() {
6546
6906
  const start = Date.now();
6547
6907
  const res = await restoreCache(nuxt.options.buildDir, cacheFile);
6548
6908
  const elapsed = Date.now() - start;
6549
6909
  if (res) {
6550
- consola$1.success(`Restored Vue client and server builds from cache in \`${elapsed}ms\`.`);
6910
+ consola.success(`Restored Vue client and server builds from cache in \`${elapsed}ms\`.`);
6551
6911
  }
6552
6912
  return res;
6553
6913
  }
@@ -6568,7 +6928,7 @@ async function cleanupCaches(nuxt) {
6568
6928
  await unlink(cache);
6569
6929
  }
6570
6930
  const elapsed = Date.now() - start;
6571
- consola$1.success(`Cleaned up old build caches in \`${elapsed}ms\`.`);
6931
+ consola.success(`Cleaned up old build caches in \`${elapsed}ms\`.`);
6572
6932
  }
6573
6933
  }
6574
6934
  async function getHashes(nuxt, options) {
@@ -6633,7 +6993,7 @@ async function getHashes(nuxt, options) {
6633
6993
  sources: hashSources
6634
6994
  };
6635
6995
  const elapsed = Date.now() - start;
6636
- consola$1.debug(`Computed \`${options.id}\` build hash in \`${elapsed}ms\`.`);
6996
+ consola.debug(`Computed \`${options.id}\` build hash in \`${elapsed}ms\`.`);
6637
6997
  return res;
6638
6998
  }
6639
6999
  async function readFilesRecursive(dir, opts) {
@@ -6701,7 +7061,7 @@ async function restoreCache(cwd, cacheFile) {
6701
7061
  if (stats?.isFile() && stats.size) {
6702
7062
  const lastModified = Number.parseInt(file.attrs?.mtime?.toString().padEnd(13, "0") || "0");
6703
7063
  if (stats.mtime.getTime() >= lastModified) {
6704
- consola$1.debug(`Skipping \`${file.name}\` (up to date or newer than cache)`);
7064
+ consola.debug(`Skipping \`${file.name}\` (up to date or newer than cache)`);
6705
7065
  continue;
6706
7066
  }
6707
7067
  }
@@ -6891,7 +7251,7 @@ async function createParcelWatcher() {
6891
7251
  const { subscribe } = await importModule("@parcel/watcher", { url: [nuxt.options.rootDir, ...nuxt.options.modulesDir].map((d) => directoryToURL(d)) });
6892
7252
  const pathsToWatch = resolvePathsToWatch(nuxt, { parentDirectories: true });
6893
7253
  for (const dir of pathsToWatch) {
6894
- if (!await isDirectory$1(dir)) {
7254
+ if (!await isDirectory(dir)) {
6895
7255
  continue;
6896
7256
  }
6897
7257
  const watcher = subscribe(dir, (err, events) => {