���Root Mod By V1rus_Alfa
User / IP
:
216.73.216.158
Host / Server
:
195.214.235.115 / npln.ir
System
:
Linux damavand.pws-dns.net 5.14.0-503.35.1.el9_5.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Apr 4 05:23:43 EDT 2025 x86_64
Command
|
Upload
|
Mass Deface
|
Create
:
/
home2
/
cutunixc
/
.trash
/
node_modules.2
/
nuxt
/
dist
/
Viewing: index.mjs
import fs, { promises, existsSync, readdirSync, statSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs'; import { mkdir, readFile, readdir, writeFile, rm } from 'node:fs/promises'; import { dirname, resolve, normalize, basename, extname, relative, isAbsolute, join } from 'pathe'; import { createHooks, createDebugger } from 'hookable'; import ignore from 'ignore'; import { tryUseNuxt, useNuxt, resolveFiles, resolvePath as resolvePath$1, logger, defineNuxtModule, addPlugin, addTemplate, addTypeTemplate, addComponent, updateTemplates, useNitro, addVitePlugin, addWebpackPlugin, addBuildPlugin, findPath, addImportsSources, tryResolveModule, isIgnored, resolveAlias, addPluginTemplate, normalizeModuleTranspilePath, resolveNuxtModule, resolveIgnorePatterns, createResolver, nuxtCtx, addServerPlugin, installModule, addRouteMiddleware, loadNuxtConfig, normalizeTemplate, compileTemplate, normalizePlugin, templateUtils } from '@nuxt/kit'; import { resolvePackageJSON, readPackageJSON } from 'pkg-types'; import { hash } from 'ohash'; import consola from 'consola'; import { colorize } from 'consola/utils'; import { updateConfig } from 'c12/update'; import { resolveCompatibilityDatesFromEnv, formatDate } from 'compatx'; import escapeRE from 'escape-string-regexp'; import { withTrailingSlash, parseURL, parseQuery, withLeadingSlash, joinURL, encodePath, withoutLeadingSlash } from 'ufo'; import defu$1, { defu } from 'defu'; import { satisfies, gt } from 'semver'; import { isWindows, hasTTY, isCI } from 'std-env'; import { genArrayFromRaw, genSafeVariableName, genImport, genDynamicImport, genObjectFromRawEntries, genString, genExport } from 'knitwork'; import { createRoutesContext } from 'unplugin-vue-router'; import { resolveOptions } from 'unplugin-vue-router/options'; import { fileURLToPath, pathToFileURL } from 'node:url'; import { resolvePath, findStaticImports, findExports, parseStaticImport, parseNodeModulePath, lookupNodeModuleSubpath, interopDefault } from 'mlly'; import { runInNewContext } from 'node:vm'; import { filename } from 'pathe/utils'; import { transform } from 'esbuild'; import { parse } from 'acorn'; import { walk } from 'estree-walker'; import { splitByCase, kebabCase, pascalCase, camelCase } from 'scule'; import { createUnplugin } from 'unplugin'; import MagicString from 'magic-string'; import { stripLiteral } from 'strip-literal'; import { globby } from 'globby'; import { parse as parse$1, walk as walk$1, ELEMENT_NODE } from 'ultrahtml'; import { createUnimport, defineUnimportPreset, toExports, scanDirExports } from 'unimport'; import { parseQuery as parseQuery$1 } from 'vue-router'; import { createTransformer } from 'unctx/transform'; import { cpus } from 'node:os'; import { toRouteMatcher, createRouter, exportMatcher } from 'radix3'; import { createNitro, scanHandlers, writeTypes, copyPublicAssets, build as build$1, prepare, prerender, createDevServer } from 'nitropack'; import { dynamicEventHandler } from 'h3'; import chokidar from 'chokidar'; import { debounce } from 'perfect-debounce'; import { resolveSchema, generateTypes } from 'untyped'; import untypedPlugin from 'untyped/babel-plugin'; import jiti from 'jiti'; let _distDir = dirname(fileURLToPath(import.meta.url)); if (_distDir.match(/(chunks|shared)$/)) { _distDir = dirname(_distDir); } const distDir = _distDir; const pkgDir = resolve(distDir, ".."); async function resolveTypePath(path, subpath, searchPaths = tryUseNuxt()?.options.modulesDir) { try { const r = await resolvePath(path, { url: searchPaths, conditions: ["types", "import", "require"] }); if (subpath) { return r.replace(/(?:\.d)?\.[mc]?[jt]s$/, ""); } const rootPath = await resolvePackageJSON(r); return dirname(rootPath); } catch { return null; } } function getNameFromPath(path, relativeTo) { const relativePath = relativeTo ? normalize(path).replace(withTrailingSlash(normalize(relativeTo)), "") : basename(path); const prefixParts = splitByCase(dirname(relativePath)); const fileName = basename(relativePath, extname(relativePath)); const segments = resolveComponentNameSegments(fileName.toLowerCase() === "index" ? "" : fileName, prefixParts).filter(Boolean); return kebabCase(segments).replace(/["']/g, ""); } function hasSuffix(path, suffix) { return basename(path, extname(path)).endsWith(suffix); } function resolveComponentNameSegments(fileName, prefixParts) { const fileNameParts = splitByCase(fileName); const fileNamePartsContent = fileNameParts.join("/").toLowerCase(); const componentNameParts = prefixParts.flatMap((p) => splitByCase(p)); let index = prefixParts.length - 1; const matchedSuffix = []; while (index >= 0) { matchedSuffix.unshift(...splitByCase(prefixParts[index]).map((p) => p.toLowerCase())); const matchedSuffixContent = matchedSuffix.join("/"); if (fileNamePartsContent === matchedSuffixContent || fileNamePartsContent.startsWith(matchedSuffixContent + "/") || // e.g Item/Item/Item.vue -> Item prefixParts[index].toLowerCase() === fileNamePartsContent && prefixParts[index + 1] && prefixParts[index] === prefixParts[index + 1]) { componentNameParts.length = index; } index--; } return [...componentNameParts, ...fileNameParts]; } function isVue(id, opts = {}) { const { search } = parseURL(decodeURIComponent(pathToFileURL(id).href)); if (id.endsWith(".vue") && !search) { return true; } if (!search) { return false; } const query = parseQuery(search); if (query.nuxt_component) { return false; } if (query.macro && (search === "?macro=true" || !opts.type || opts.type.includes("script"))) { return true; } const type = "setup" in query ? "script" : query.type; if (!("vue" in query) || opts.type && !opts.type.includes(type)) { return false; } return true; } const JS_RE = /\.(?:[cm]?j|t)sx?$/; function isJS(id) { const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href)); return JS_RE.test(pathname); } function getLoader(id) { const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href)); const ext = extname(pathname); if (ext === ".vue") { return "vue"; } if (!JS_RE.test(ext)) { return null; } return ext.endsWith("x") ? "tsx" : "ts"; } function uniqueBy(arr, key) { if (arr.length < 2) { return arr; } const res = []; const seen = /* @__PURE__ */ new Set(); for (const item of arr) { if (seen.has(item[key])) { continue; } seen.add(item[key]); res.push(item); } return res; } function toArray(value) { return Array.isArray(value) ? value : [value]; } async function isDirectory$1(path) { return (await promises.lstat(path)).isDirectory(); } async function resolvePagesRoutes() { const nuxt = useNuxt(); const pagesDirs = nuxt.options._layers.map( (layer) => resolve(layer.config.srcDir, (layer.config.rootDir === nuxt.options.rootDir ? nuxt.options : layer.config).dir?.pages || "pages") ); const scannedFiles = []; for (const dir of pagesDirs) { const files = await resolveFiles(dir, `**/*{${nuxt.options.extensions.join(",")}}`); scannedFiles.push(...files.map((file) => ({ relativePath: relative(dir, file), absolutePath: file }))); } scannedFiles.sort((a, b) => a.relativePath.localeCompare(b.relativePath, "en-US")); const allRoutes = generateRoutesFromFiles(uniqueBy(scannedFiles, "relativePath"), { shouldUseServerComponents: !!nuxt.options.experimental.componentIslands }); const pages = uniqueBy(allRoutes, "path"); const shouldAugment = nuxt.options.experimental.scanPageMeta || nuxt.options.experimental.typedPages; if (shouldAugment) { const augmentedPages = await augmentPages(pages, nuxt.vfs); await nuxt.callHook("pages:extend", pages); await augmentPages(pages, nuxt.vfs, augmentedPages); augmentedPages.clear(); } else { await nuxt.callHook("pages:extend", pages); } return pages; } function generateRoutesFromFiles(files, options = {}) { const routes = []; for (const file of files) { const segments = file.relativePath.replace(new RegExp(`${escapeRE(extname(file.relativePath))}$`), "").split("/"); const route = { name: "", path: "", file: file.absolutePath, children: [] }; let parent = routes; const lastSegment = segments[segments.length - 1]; if (lastSegment.endsWith(".server")) { segments[segments.length - 1] = lastSegment.replace(".server", ""); if (options.shouldUseServerComponents) { route.mode = "server"; } } else if (lastSegment.endsWith(".client")) { segments[segments.length - 1] = lastSegment.replace(".client", ""); route.mode = "client"; } for (let i = 0; i < segments.length; i++) { const segment = segments[i]; const tokens = parseSegment(segment); if (tokens.every((token) => token.type === 4 /* group */)) { continue; } const segmentName = tokens.map(({ value, type }) => type === 4 /* group */ ? "" : value).join(""); route.name += (route.name && "/") + segmentName; const path = withLeadingSlash(joinURL(route.path, getRoutePath(tokens).replace(/\/index$/, "/"))); const child = parent.find((parentRoute) => parentRoute.name === route.name && parentRoute.path === path); if (child && child.children) { parent = child.children; route.path = ""; } else if (segmentName === "index" && !route.path) { route.path += "/"; } else if (segmentName !== "index") { route.path += getRoutePath(tokens); } } parent.push(route); } return prepareRoutes(routes); } async function augmentPages(routes, vfs, augmentedPages = /* @__PURE__ */ new Set()) { for (const route of routes) { if (route.file && !augmentedPages.has(route.file)) { const fileContent = route.file in vfs ? vfs[route.file] : fs.readFileSync(await resolvePath$1(route.file), "utf-8"); const routeMeta = await getRouteMeta(fileContent, route.file); if (route.meta) { routeMeta.meta = { ...routeMeta.meta, ...route.meta }; } Object.assign(route, routeMeta); augmentedPages.add(route.file); } if (route.children && route.children.length > 0) { await augmentPages(route.children, vfs, augmentedPages); } } return augmentedPages; } const SFC_SCRIPT_RE = /<script(?<attrs>[^>]*)>(?<content>[\s\S]*?)<\/script[^>]*>/gi; function extractScriptContent(html) { const contents = []; for (const match of html.matchAll(SFC_SCRIPT_RE)) { if (match?.groups?.content) { contents.push({ loader: match.groups.attrs.includes("tsx") ? "tsx" : "ts", code: match.groups.content.trim() }); } } return contents; } const PAGE_META_RE = /definePageMeta\([\s\S]*?\)/; const extractionKeys = ["name", "path", "alias", "redirect"]; const DYNAMIC_META_KEY = "__nuxt_dynamic_meta_key"; const pageContentsCache = {}; const metaCache$1 = {}; async function getRouteMeta(contents, absolutePath) { if (!(absolutePath in pageContentsCache) || pageContentsCache[absolutePath] !== contents) { pageContentsCache[absolutePath] = contents; delete metaCache$1[absolutePath]; } if (absolutePath in metaCache$1) { return metaCache$1[absolutePath]; } const loader = getLoader(absolutePath); const scriptBlocks = !loader ? null : loader === "vue" ? extractScriptContent(contents) : [{ code: contents, loader }]; if (!scriptBlocks) { metaCache$1[absolutePath] = {}; return {}; } const extractedMeta = {}; for (const script of scriptBlocks) { if (!PAGE_META_RE.test(script.code)) { continue; } const js = await transform(script.code, { loader: script.loader }); const ast = parse(js.code, { sourceType: "module", ecmaVersion: "latest", ranges: true }); const dynamicProperties = /* @__PURE__ */ new Set(); let foundMeta = false; walk(ast, { enter(node) { if (foundMeta) { return; } if (node.type !== "ExpressionStatement" || node.expression.type !== "CallExpression" || node.expression.callee.type !== "Identifier" || node.expression.callee.name !== "definePageMeta") { return; } foundMeta = true; const pageMetaArgument = node.expression.arguments[0]; for (const key of extractionKeys) { const property = pageMetaArgument.properties.find((property2) => property2.type === "Property" && property2.key.type === "Identifier" && property2.key.name === key); if (!property) { continue; } if (property.value.type === "ObjectExpression") { const valueString = js.code.slice(property.value.range[0], property.value.range[1]); try { extractedMeta[key] = JSON.parse(runInNewContext(`JSON.stringify(${valueString})`, {})); } catch { console.debug(`[nuxt] Skipping extraction of \`${key}\` metadata as it is not JSON-serializable (reading \`${absolutePath}\`).`); dynamicProperties.add(key); continue; } } if (property.value.type === "ArrayExpression") { const values = []; for (const element of property.value.elements) { if (!element) { continue; } if (element.type !== "Literal" || typeof element.value !== "string") { console.debug(`[nuxt] Skipping extraction of \`${key}\` metadata as it is not an array of string literals (reading \`${absolutePath}\`).`); dynamicProperties.add(key); continue; } values.push(element.value); } extractedMeta[key] = values; continue; } if (property.value.type !== "Literal" || typeof property.value.value !== "string") { console.debug(`[nuxt] Skipping extraction of \`${key}\` metadata as it is not a string literal or array of string literals (reading \`${absolutePath}\`).`); dynamicProperties.add(key); continue; } extractedMeta[key] = property.value.value; } for (const property of pageMetaArgument.properties) { if (property.type !== "Property") { continue; } const isIdentifierOrLiteral = property.key.type === "Literal" || property.key.type === "Identifier"; if (!isIdentifierOrLiteral) { continue; } const name = property.key.type === "Identifier" ? property.key.name : String(property.value); if (name) { dynamicProperties.add("meta"); break; } } if (dynamicProperties.size) { extractedMeta.meta ?? (extractedMeta.meta = {}); extractedMeta.meta[DYNAMIC_META_KEY] = dynamicProperties; } } }); } metaCache$1[absolutePath] = extractedMeta; return extractedMeta; } function getRoutePath(tokens) { return tokens.reduce((path, token) => { return path + (token.type === 2 /* optional */ ? `:${token.value}?` : token.type === 1 /* dynamic */ ? `:${token.value}()` : token.type === 3 /* catchall */ ? `:${token.value}(.*)*` : token.type === 4 /* group */ ? "" : encodePath(token.value).replace(/:/g, "\\:")); }, "/"); } const PARAM_CHAR_RE = /[\w.]/; function parseSegment(segment) { let state = 0 /* initial */; let i = 0; let buffer = ""; const tokens = []; function consumeBuffer() { if (!buffer) { return; } if (state === 0 /* initial */) { throw new Error("wrong state"); } tokens.push({ type: state === 1 /* static */ ? 0 /* static */ : state === 2 /* dynamic */ ? 1 /* dynamic */ : state === 3 /* optional */ ? 2 /* optional */ : state === 4 /* catchall */ ? 3 /* catchall */ : 4 /* group */, value: buffer }); buffer = ""; } while (i < segment.length) { const c = segment[i]; switch (state) { case 0 /* initial */: buffer = ""; if (c === "[") { state = 2 /* dynamic */; } else if (c === "(") { state = 5 /* group */; } else { i--; state = 1 /* static */; } break; case 1 /* static */: if (c === "[") { consumeBuffer(); state = 2 /* dynamic */; } else if (c === "(") { consumeBuffer(); state = 5 /* group */; } else { buffer += c; } break; case 4 /* catchall */: case 2 /* dynamic */: case 3 /* optional */: case 5 /* group */: if (buffer === "...") { buffer = ""; state = 4 /* catchall */; } if (c === "[" && state === 2 /* dynamic */) { state = 3 /* optional */; } if (c === "]" && (state !== 3 /* optional */ || segment[i - 1] === "]")) { if (!buffer) { throw new Error("Empty param"); } else { consumeBuffer(); } state = 0 /* initial */; } else if (c === ")" && state === 5 /* group */) { if (!buffer) { throw new Error("Empty group"); } else { consumeBuffer(); } state = 0 /* initial */; } else if (PARAM_CHAR_RE.test(c)) { buffer += c; } else ; break; } i++; } if (state === 2 /* dynamic */) { throw new Error(`Unfinished param "${buffer}"`); } consumeBuffer(); return tokens; } function findRouteByName(name, routes) { for (const route of routes) { if (route.name === name) { return route; } } return findRouteByName(name, routes); } function prepareRoutes(routes, parent, names = /* @__PURE__ */ new Set()) { for (const route of routes) { if (route.name) { route.name = route.name.replace(/\/index$/, "").replace(/\//g, "-"); if (names.has(route.name)) { const existingRoute = findRouteByName(route.name, routes); const extra = existingRoute?.name ? `is the same as \`${existingRoute.file}\`` : "is a duplicate"; logger.warn(`Route name generated for \`${route.file}\` ${extra}. You may wish to set a custom name using \`definePageMeta\` within the page file.`); } } if (parent && route.path[0] === "/") { route.path = route.path.slice(1); } if (route.children?.length) { route.children = prepareRoutes(route.children, route, names); } if (route.children?.find((childRoute) => childRoute.path === "")) { delete route.name; } if (route.name) { names.add(route.name); } } return routes; } function serializeRouteValue(value, skipSerialisation = false) { if (skipSerialisation || value === void 0) { return void 0; } return JSON.stringify(value); } function normalizeRoutes(routes, metaImports = /* @__PURE__ */ new Set(), overrideMeta = false) { return { imports: metaImports, routes: genArrayFromRaw(routes.map((page) => { const markedDynamic = page.meta?.[DYNAMIC_META_KEY] ?? /* @__PURE__ */ new Set(); const metaFiltered = {}; let skipMeta = true; for (const key in page.meta || {}) { if (key !== DYNAMIC_META_KEY && page.meta[key] !== void 0) { skipMeta = false; metaFiltered[key] = page.meta[key]; } } const skipAlias = toArray(page.alias).every((val) => !val); const route = { path: serializeRouteValue(page.path), name: serializeRouteValue(page.name), meta: serializeRouteValue(metaFiltered, skipMeta), alias: serializeRouteValue(toArray(page.alias), skipAlias), redirect: serializeRouteValue(page.redirect) }; for (const key of ["path", "name", "meta", "alias", "redirect"]) { if (route[key] === void 0) { delete route[key]; } } if (page.children?.length) { route.children = normalizeRoutes(page.children, metaImports, overrideMeta).routes; } if (!page.file) { return route; } const file = normalize(page.file); const pageImportName = genSafeVariableName(filename(file) + hash(file)); const metaImportName = pageImportName + "Meta"; metaImports.add(genImport(`${file}?macro=true`, [{ name: "default", as: metaImportName }])); if (page._sync) { metaImports.add(genImport(file, [{ name: "default", as: pageImportName }])); } const pageImport = page._sync && page.mode !== "client" ? pageImportName : genDynamicImport(file, { interopDefault: true }); const metaRoute = { name: `${metaImportName}?.name ?? ${route.name}`, path: `${metaImportName}?.path ?? ${route.path}`, meta: `${metaImportName} || {}`, alias: `${metaImportName}?.alias || []`, redirect: `${metaImportName}?.redirect`, component: page.mode === "server" ? `() => createIslandPage(${route.name})` : page.mode === "client" ? `() => createClientPage(${pageImport})` : pageImport }; if (page.mode === "server") { metaImports.add(` let _createIslandPage async function createIslandPage (name) { _createIslandPage ||= await import(${JSON.stringify(resolve(distDir, "components/runtime/server-component"))}).then(r => r.createIslandPage) return _createIslandPage(name) };`); } else if (page.mode === "client") { metaImports.add(` let _createClientPage async function createClientPage(loader) { _createClientPage ||= await import(${JSON.stringify(resolve(distDir, "components/runtime/client-component"))}).then(r => r.createClientPage) return _createClientPage(loader); }`); } if (route.children) { metaRoute.children = route.children; } if (route.meta) { metaRoute.meta = `{ ...(${metaImportName} || {}), ...${route.meta} }`; } if (overrideMeta) { for (const key of ["name", "path"]) { if (markedDynamic.has(key)) { continue; } metaRoute[key] = route[key] ?? `${metaImportName}?.${key}`; } for (const key of ["meta", "alias", "redirect"]) { if (markedDynamic.has(key)) { continue; } if (route[key] == null) { delete metaRoute[key]; continue; } metaRoute[key] = route[key]; } } else { if (route.alias != null) { metaRoute.alias = `${route.alias}.concat(${metaImportName}?.alias || [])`; } if (route.redirect != null) { metaRoute.redirect = route.redirect; } } return metaRoute; })) }; } function pathToNitroGlob(path) { if (!path) { return null; } if (path.indexOf(":") !== path.lastIndexOf(":")) { return null; } return path.replace(/\/[^:/]*:\w.*$/, "/**"); } function resolveRoutePaths(page, parent = "/") { return [ joinURL(parent, page.path), ...page.children?.flatMap((child) => resolveRoutePaths(child, joinURL(parent, page.path))) || [] ]; } const ROUTE_RULE_RE = /\bdefineRouteRules\(/; const ruleCache = {}; async function extractRouteRules(code) { if (code in ruleCache) { return ruleCache[code]; } if (!ROUTE_RULE_RE.test(code)) { return null; } let rule = null; const contents = extractScriptContent(code); for (const script of contents) { if (rule) { break; } code = script?.code || code; const js = await transform(code, { loader: script?.loader || "ts" }); walk(parse(js.code, { sourceType: "module", ecmaVersion: "latest" }), { enter(_node) { if (_node.type !== "CallExpression" || _node.callee.type !== "Identifier") { return; } const node = _node; const name = "name" in node.callee && node.callee.name; if (name === "defineRouteRules") { const rulesString = js.code.slice(node.start, node.end); try { rule = JSON.parse(runInNewContext(rulesString.replace("defineRouteRules", "JSON.stringify"), {})); } catch { throw new Error("[nuxt] Error parsing route rules. They should be JSON-serializable."); } } } }); } ruleCache[code] = rule; return rule; } function getMappedPages(pages, paths = {}, prefix = "") { for (const page of pages) { if (page.file) { const filename = normalize(page.file); paths[filename] = pathToNitroGlob(prefix + page.path); } if (page.children) { getMappedPages(page.children, paths, page.path + "/"); } } return paths; } const HAS_MACRO_RE = /\bdefinePageMeta\s*\(\s*/; const CODE_EMPTY = ` const __nuxt_page_meta = null export default __nuxt_page_meta `; const CODE_HMR = ` // Vite if (import.meta.hot) { import.meta.hot.accept(mod => { Object.assign(__nuxt_page_meta, mod) }) } // webpack if (import.meta.webpackHot) { import.meta.webpackHot.accept((err) => { if (err) { window.location = window.location.href } }) }`; const PageMetaPlugin = createUnplugin((options) => { return { name: "nuxt:pages-macros-transform", enforce: "post", transformInclude(id) { return !!parseMacroQuery(id).macro; }, transform(code, id) { const query = parseMacroQuery(id); if (query.type && query.type !== "script") { return; } const s = new MagicString(code); function result() { if (s.hasChanged()) { return { code: s.toString(), map: options.sourcemap ? s.generateMap({ hires: true }) : void 0 }; } } const hasMacro = HAS_MACRO_RE.test(code); const imports = findStaticImports(code); const scriptImport = imports.find((i) => parseMacroQuery(i.specifier).type === "script"); if (scriptImport) { const reorderedQuery = rewriteQuery(scriptImport.specifier); const quotedSpecifier = getQuotedSpecifier(scriptImport.code)?.replace(scriptImport.specifier, reorderedQuery) ?? JSON.stringify(reorderedQuery); s.overwrite(0, code.length, `export { default } from ${quotedSpecifier}`); return result(); } const currentExports = findExports(code); for (const match of currentExports) { if (match.type !== "default" || !match.specifier) { continue; } const reorderedQuery = rewriteQuery(match.specifier); const quotedSpecifier = getQuotedSpecifier(match.code)?.replace(match.specifier, reorderedQuery) ?? JSON.stringify(reorderedQuery); s.overwrite(0, code.length, `export { default } from ${quotedSpecifier}`); return result(); } if (!hasMacro && !code.includes("export { default }") && !code.includes("__nuxt_page_meta")) { if (!code) { s.append(CODE_EMPTY + (options.dev ? CODE_HMR : "")); const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href)); logger.error(`The file \`${pathname}\` is not a valid page as it has no content.`); } else { s.overwrite(0, code.length, CODE_EMPTY + (options.dev ? CODE_HMR : "")); } return result(); } const importMap = /* @__PURE__ */ new Map(); const addedImports = /* @__PURE__ */ new Set(); for (const i of imports) { const parsed = parseStaticImport(i); for (const name of [ parsed.defaultImport, ...Object.values(parsed.namedImports || {}), parsed.namespacedImport ].filter(Boolean)) { importMap.set(name, i); } } walk(this.parse(code, { sourceType: "module", ecmaVersion: "latest" }), { enter(_node) { if (_node.type !== "CallExpression" || _node.callee.type !== "Identifier") { return; } const node = _node; const name = "name" in node.callee && node.callee.name; if (name !== "definePageMeta") { return; } const meta = node.arguments[0]; let contents = `const __nuxt_page_meta = ${code.slice(meta.start, meta.end) || "null"} export default __nuxt_page_meta` + (options.dev ? CODE_HMR : ""); function addImport(name2) { if (name2 && importMap.has(name2)) { const importValue = importMap.get(name2).code; if (!addedImports.has(importValue)) { contents = importMap.get(name2).code + "\n" + contents; addedImports.add(importValue); } } } walk(meta, { enter(_node2) { if (_node2.type === "CallExpression") { const node2 = _node2; addImport("name" in node2.callee && node2.callee.name); } if (_node2.type === "Identifier") { const node2 = _node2; addImport(node2.name); } } }); s.overwrite(0, code.length, contents); } }); if (!s.hasChanged() && !code.includes("__nuxt_page_meta")) { s.overwrite(0, code.length, CODE_EMPTY + (options.dev ? CODE_HMR : "")); } return result(); }, vite: { handleHotUpdate: { order: "pre", handler: ({ modules }) => { const index = modules.findIndex((i) => i.id?.includes("?macro=true")); if (index !== -1) { modules.splice(index, 1); } } } } }; }); function rewriteQuery(id) { return id.replace(/\?.+$/, (r) => "?macro=true&" + r.replace(/^\?/, "").replace(/¯o=true/, "")); } function parseMacroQuery(id) { const { search } = parseURL(decodeURIComponent(isAbsolute(id) ? pathToFileURL(id).href : id).replace(/\?macro=true$/, "")); const query = parseQuery(search); if (id.includes("?macro=true")) { return { macro: "true", ...query }; } return query; } function getQuotedSpecifier(id) { return id.match(/(["']).*\1/)?.[0]; } const INJECTION_RE_TEMPLATE = /\b_ctx\.\$route\b/g; const INJECTION_RE_SCRIPT = /\bthis\.\$route\b/g; const INJECTION_SINGLE_RE = /\bthis\.\$route\b|\b_ctx\.\$route\b/; const RouteInjectionPlugin = (nuxt) => createUnplugin(() => { return { name: "nuxt:route-injection-plugin", enforce: "post", transformInclude(id) { return isVue(id, { type: ["template", "script"] }); }, transform(code) { if (!INJECTION_SINGLE_RE.test(code) || code.includes("_ctx._.provides[__nuxt_route_symbol") || code.includes("this._.provides[__nuxt_route_symbol")) { return; } let replaced = false; const s = new MagicString(code); const strippedCode = stripLiteral(code); const replaceMatches = (regExp, replacement) => { for (const match of strippedCode.matchAll(regExp)) { const start = match.index; const end = start + match[0].length; s.overwrite(start, end, replacement); if (!replaced) { replaced = true; } } }; replaceMatches(INJECTION_RE_TEMPLATE, "(_ctx._.provides[__nuxt_route_symbol] || _ctx.$route)"); replaceMatches(INJECTION_RE_SCRIPT, "(this._.provides[__nuxt_route_symbol] || this.$route)"); if (replaced) { s.prepend("import { PageRouteSymbol as __nuxt_route_symbol } from '#app/components/injections';\n"); } if (s.hasChanged()) { return { code: s.toString(), map: nuxt.options.sourcemap.client || nuxt.options.sourcemap.server ? s.generateMap({ hires: true }) : void 0 }; } } }; }); const OPTIONAL_PARAM_RE = /^\/?:.*(?:\?|\(\.\*\)\*)$/; const pagesModule = defineNuxtModule({ meta: { name: "pages" }, async setup(_options, nuxt) { const useExperimentalTypedPages = nuxt.options.experimental.typedPages; const runtimeDir = resolve(distDir, "pages/runtime"); const pagesDirs = nuxt.options._layers.map( (layer) => resolve(layer.config.srcDir, (layer.config.rootDir === nuxt.options.rootDir ? nuxt.options : layer.config).dir?.pages || "pages") ); nuxt.options.alias["#vue-router"] = "vue-router"; const routerPath = await resolveTypePath("vue-router", "", nuxt.options.modulesDir) || "vue-router"; nuxt.hook("prepare:types", ({ tsConfig }) => { var _a; tsConfig.compilerOptions || (tsConfig.compilerOptions = {}); (_a = tsConfig.compilerOptions).paths || (_a.paths = {}); tsConfig.compilerOptions.paths["#vue-router"] = [routerPath]; delete tsConfig.compilerOptions.paths["#vue-router/*"]; }); async function resolveRouterOptions() { const context = { files: [] }; for (const layer of nuxt.options._layers) { const path = await findPath(resolve(layer.config.srcDir, layer.config.dir?.app || "app", "router.options")); if (path) { context.files.unshift({ path }); } } context.files.unshift({ path: resolve(runtimeDir, "router.options"), optional: true }); await nuxt.callHook("pages:routerOptions", context); return context.files; } const isNonEmptyDir = (dir) => existsSync(dir) && readdirSync(dir).length; const userPreference = nuxt.options.pages; const isPagesEnabled = async () => { if (typeof userPreference === "boolean") { return userPreference; } const routerOptionsFiles = await resolveRouterOptions(); if (routerOptionsFiles.filter((p) => !p.optional).length > 0) { return true; } if (pagesDirs.some((dir) => isNonEmptyDir(dir))) { return true; } const pages = await resolvePagesRoutes(); if (pages.length) { if (nuxt.apps.default) { nuxt.apps.default.pages = pages; } return true; } return false; }; nuxt.options.pages = await isPagesEnabled(); if (nuxt.options.dev && nuxt.options.pages) { addPlugin(resolve(runtimeDir, "plugins/check-if-page-unused")); } nuxt.hook("app:templates", async (app) => { app.pages = await resolvePagesRoutes(); if (!nuxt.options.ssr && app.pages.some((p) => p.mode === "server")) { logger.warn("Using server pages with `ssr: false` is not supported with auto-detected component islands. Set `experimental.componentIslands` to `true`."); } }); const restartPaths = nuxt.options._layers.flatMap((layer) => { const pagesDir = (layer.config.rootDir === nuxt.options.rootDir ? nuxt.options : layer.config).dir?.pages || "pages"; return [ resolve(layer.config.srcDir || layer.cwd, layer.config.dir?.app || "app", "router.options.ts"), resolve(layer.config.srcDir || layer.cwd, pagesDir) ]; }); nuxt.hooks.hook("builder:watch", async (event, relativePath) => { const path = resolve(nuxt.options.srcDir, relativePath); if (restartPaths.some((p) => p === path || path.startsWith(p + "/"))) { const newSetting = await isPagesEnabled(); if (nuxt.options.pages !== newSetting) { logger.info("Pages", newSetting ? "enabled" : "disabled"); return nuxt.callHook("restart"); } } }); if (!nuxt.options.pages) { addPlugin(resolve(distDir, "app/plugins/router")); addTemplate({ filename: "pages.mjs", getContents: () => [ "export { useRoute } from '#app/composables/router'", "export const START_LOCATION = Symbol('router:start-location')" ].join("\n") }); addTypeTemplate({ filename: "types/middleware.d.ts", getContents: () => [ "declare module 'nitropack' {", " interface NitroRouteConfig {", " appMiddleware?: string | string[] | Record<string, boolean>", " }", "}", "export {}" ].join("\n") }); addComponent({ name: "NuxtPage", priority: 10, // built-in that we do not expect the user to override filePath: resolve(distDir, "pages/runtime/page-placeholder") }); nuxt.hook("nitro:init", (nitro) => { if (nuxt.options.dev || !nuxt.options.ssr || !nitro.options.static || !nitro.options.prerender.crawlLinks) { return; } nitro.options.prerender.routes.push("/"); }); return; } if (useExperimentalTypedPages) { const declarationFile = "./types/typed-router.d.ts"; const options = { routesFolder: [], dts: resolve(nuxt.options.buildDir, declarationFile), logs: nuxt.options.debug, async beforeWriteFiles(rootPage) { rootPage.children.forEach((child) => child.delete()); const pages = nuxt.apps.default?.pages || await resolvePagesRoutes(); if (nuxt.apps.default) { nuxt.apps.default.pages = pages; } function addPage(parent, page) { const route = parent.insert(page.path, page.file); if (page.meta) { route.addToMeta(page.meta); } if (page.alias) { route.addAlias(page.alias); } if (page.name) { route.name = page.name; } if (page.children) { page.children.forEach((child) => addPage(route, child)); } } for (const page of pages) { addPage(rootPage, page); } } }; nuxt.hook("prepare:types", ({ references }) => { references.push({ path: declarationFile }); references.push({ types: "unplugin-vue-router/client" }); }); const context = createRoutesContext(resolveOptions(options)); const dtsFile = resolve(nuxt.options.buildDir, declarationFile); await mkdir(dirname(dtsFile), { recursive: true }); await context.scanPages(false); if (nuxt.options._prepare || !nuxt.options.dev) { const dts = await readFile(dtsFile, "utf-8"); addTemplate({ filename: "types/typed-router.d.ts", getContents: () => dts }); } nuxt.hook("app:templatesGenerated", async (_app, _templates, options2) => { if (!options2?.filter || options2.filter({ filename: "routes.mjs" })) { await context.scanPages(); } }); } nuxt.hook("prepare:types", ({ references }) => { references.push({ types: useExperimentalTypedPages ? "vue-router/auto-routes" : "vue-router" }); }); nuxt.hook("imports:sources", (sources) => { const routerImports = sources.find((s) => s.from === "#app/composables/router" && s.imports.includes("onBeforeRouteLeave")); if (routerImports) { routerImports.from = "vue-router"; } }); const updateTemplatePaths = nuxt.options._layers.flatMap((l) => { const dir = (l.config.rootDir === nuxt.options.rootDir ? nuxt.options : l.config).dir; return [ resolve(l.config.srcDir || l.cwd, dir?.pages || "pages") + "/", resolve(l.config.srcDir || l.cwd, dir?.layouts || "layouts") + "/", resolve(l.config.srcDir || l.cwd, dir?.middleware || "middleware") + "/" ]; }); function isPage(file, pages = nuxt.apps.default.pages) { if (!pages) { return false; } return pages.some((page) => page.file === file) || pages.some((page) => page.children && isPage(file, page.children)); } nuxt.hook("builder:watch", async (event, relativePath) => { const path = resolve(nuxt.options.srcDir, relativePath); const shouldAlwaysRegenerate = nuxt.options.experimental.scanPageMeta && isPage(path); if (event === "change" && !shouldAlwaysRegenerate) { return; } if (shouldAlwaysRegenerate || updateTemplatePaths.some((dir) => path.startsWith(dir))) { await updateTemplates({ filter: (template) => template.filename === "routes.mjs" }); } }); nuxt.hook("app:resolve", (app) => { if (app.mainComponent === resolve(nuxt.options.appDir, "components/welcome.vue")) { app.mainComponent = resolve(runtimeDir, "app.vue"); } app.middleware.unshift({ name: "validate", path: resolve(runtimeDir, "validate"), global: true }); }); nuxt.hook("app:resolve", (app) => { const nitro = useNitro(); if (nitro.options.prerender.crawlLinks) { app.plugins.push({ src: resolve(runtimeDir, "plugins/prerender.server"), mode: "server" }); } }); const prerenderRoutes = /* @__PURE__ */ new Set(); function processPages(pages, currentPath = "/") { for (const page of pages) { if (OPTIONAL_PARAM_RE.test(page.path) && !page.children?.length) { prerenderRoutes.add(currentPath); } if (page.path.includes(":")) { continue; } const route = joinURL(currentPath, page.path); prerenderRoutes.add(route); if (page.children) { processPages(page.children, route); } } } nuxt.hook("pages:extend", (pages) => { if (nuxt.options.dev) { return; } prerenderRoutes.clear(); processPages(pages); }); nuxt.hook("nitro:build:before", (nitro) => { if (nuxt.options.dev || !nitro.options.static || nuxt.options.router.options.hashMode || !nitro.options.prerender.crawlLinks) { return; } if (nuxt.options.ssr) { const [firstPage] = [...prerenderRoutes].sort(); nitro.options.prerender.routes.push(firstPage || "/"); return; } for (const route of nitro.options.prerender.routes || []) { prerenderRoutes.add(route); } nitro.options.prerender.routes = Array.from(prerenderRoutes); }); nuxt.hook("imports:extend", (imports) => { imports.push( { name: "definePageMeta", as: "definePageMeta", from: resolve(runtimeDir, "composables") }, { name: "useLink", as: "useLink", from: "vue-router" } ); if (nuxt.options.experimental.inlineRouteRules) { imports.push({ name: "defineRouteRules", as: "defineRouteRules", from: resolve(runtimeDir, "composables") }); } }); if (nuxt.options.experimental.inlineRouteRules) { let pageToGlobMap = {}; nuxt.hook("pages:extend", (pages) => { pageToGlobMap = getMappedPages(pages); }); const inlineRules = {}; let updateRouteConfig; nuxt.hook("nitro:init", (nitro) => { updateRouteConfig = () => nitro.updateConfig({ routeRules: defu(inlineRules, nitro.options._config.routeRules) }); }); const updatePage = async function updatePage2(path) { const glob = pageToGlobMap[path]; const code = path in nuxt.vfs ? nuxt.vfs[path] : await readFile(path, "utf-8"); try { const extractedRule = await extractRouteRules(code); if (extractedRule) { if (!glob) { const relativePath = relative(nuxt.options.srcDir, path); logger.error(`Could not set inline route rules in \`~/${relativePath}\` as it could not be mapped to a Nitro route.`); return; } inlineRules[glob] = extractedRule; } else if (glob) { delete inlineRules[glob]; } } catch (e) { if (e.toString().includes("Error parsing route rules")) { const relativePath = relative(nuxt.options.srcDir, path); logger.error(`Error parsing route rules within \`~/${relativePath}\`. They should be JSON-serializable.`); } else { logger.error(e); } } }; nuxt.hook("builder:watch", async (event, relativePath) => { const path = resolve(nuxt.options.srcDir, relativePath); if (!(path in pageToGlobMap)) { return; } if (event === "unlink") { delete inlineRules[path]; delete pageToGlobMap[path]; } else { await updatePage(path); } await updateRouteConfig?.(); }); nuxt.hooks.hookOnce("pages:extend", async () => { for (const page in pageToGlobMap) { await updatePage(page); } await updateRouteConfig?.(); }); } if (nuxt.options.experimental.appManifest) { const componentStubPath = await resolvePath$1(resolve(runtimeDir, "component-stub")); nuxt.hook("pages:extend", (routes) => { const nitro = useNitro(); let resolvedRoutes; for (const path in nitro.options.routeRules) { const rule = nitro.options.routeRules[path]; if (!rule.redirect) { continue; } resolvedRoutes || (resolvedRoutes = routes.flatMap((route) => resolveRoutePaths(route))); if (resolvedRoutes.includes(path)) { continue; } routes.push({ _sync: true, path: path.replace(/\/[^/]*\*\*/, "/:pathMatch(.*)"), file: componentStubPath }); } }); } const pageMetaOptions = { dev: nuxt.options.dev, sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client }; nuxt.hook("modules:done", () => { addVitePlugin(() => PageMetaPlugin.vite(pageMetaOptions)); addWebpackPlugin(() => PageMetaPlugin.webpack(pageMetaOptions)); }); addPlugin(resolve(runtimeDir, "plugins/prefetch.client")); if (nuxt.options.experimental.templateRouteInjection) { addBuildPlugin(RouteInjectionPlugin(nuxt), { server: false }); } addPlugin(resolve(runtimeDir, "plugins/router")); const getSources = (pages) => pages.filter((p) => Boolean(p.file)).flatMap( (p) => [relative(nuxt.options.srcDir, p.file), ...p.children?.length ? getSources(p.children) : []] ); nuxt.hook("build:manifest", (manifest) => { if (nuxt.options.dev) { return; } const sourceFiles = nuxt.apps.default?.pages?.length ? getSources(nuxt.apps.default.pages) : []; for (const key in manifest) { if (manifest[key].src && Object.values(nuxt.apps).some((app) => app.pages?.some((page) => page.mode === "server" && page.file === join(nuxt.options.srcDir, manifest[key].src)))) { delete manifest[key]; continue; } if (manifest[key].isEntry) { manifest[key].dynamicImports = manifest[key].dynamicImports?.filter((i) => !sourceFiles.includes(i)); } } }); addTemplate({ filename: "routes.mjs", getContents({ app }) { if (!app.pages) { return "export default []"; } const { routes, imports } = normalizeRoutes(app.pages, /* @__PURE__ */ new Set(), nuxt.options.experimental.scanPageMeta); return [...imports, `export default ${routes}`].join("\n"); } }); addTemplate({ filename: "pages.mjs", getContents: () => "export { START_LOCATION, useRoute } from 'vue-router'" }); nuxt.options.vite.resolve = nuxt.options.vite.resolve || {}; nuxt.options.vite.resolve.dedupe = nuxt.options.vite.resolve.dedupe || []; nuxt.options.vite.resolve.dedupe.push("vue-router"); addTemplate({ filename: "router.options.mjs", getContents: async () => { const routerOptionsFiles = await resolveRouterOptions(); const configRouterOptions = genObjectFromRawEntries(Object.entries(nuxt.options.router.options).map(([key, value]) => [key, genString(value)])); return [ ...routerOptionsFiles.map((file, index) => genImport(file.path, `routerOptions${index}`)), `const configRouterOptions = ${configRouterOptions}`, "export default {", "...configRouterOptions,", ...routerOptionsFiles.map((_, index) => `...routerOptions${index},`), "}" ].join("\n"); } }); addTypeTemplate({ filename: "types/middleware.d.ts", getContents: ({ nuxt: nuxt2, app }) => { const composablesFile = relative(join(nuxt2.options.buildDir, "types"), resolve(runtimeDir, "composables")); const namedMiddleware = app.middleware.filter((mw) => !mw.global); return [ "import type { NavigationGuard } from 'vue-router'", `export type MiddlewareKey = ${namedMiddleware.map((mw) => genString(mw.name)).join(" | ") || "string"}`, `declare module ${genString(composablesFile)} {`, " interface PageMeta {", " middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>", " }", "}", "declare module 'nitropack' {", " interface NitroRouteConfig {", " appMiddleware?: MiddlewareKey | MiddlewareKey[] | Record<MiddlewareKey, boolean>", " }", "}" ].join("\n"); } }); addTypeTemplate({ filename: "types/layouts.d.ts", getContents: ({ nuxt: nuxt2, app }) => { const composablesFile = relative(join(nuxt2.options.buildDir, "types"), resolve(runtimeDir, "composables")); return [ "import type { ComputedRef, MaybeRef } from 'vue'", `export type LayoutKey = ${Object.keys(app.layouts).map((name) => genString(name)).join(" | ") || "string"}`, `declare module ${genString(composablesFile)} {`, " interface PageMeta {", " layout?: MaybeRef<LayoutKey | false> | ComputedRef<LayoutKey | false>", " }", "}" ].join("\n"); } }); if (nuxt.options.experimental.viewTransition) { addTypeTemplate({ filename: "types/view-transitions.d.ts", getContents: ({ nuxt: nuxt2 }) => { const runtimeDir2 = resolve(distDir, "pages/runtime"); const composablesFile = relative(join(nuxt2.options.buildDir, "types"), resolve(runtimeDir2, "composables")); return [ "import type { ComputedRef, MaybeRef } from 'vue'", `declare module ${genString(composablesFile)} {`, " interface PageMeta {", " viewTransition?: boolean | 'always'", " }", "}" ].join("\n"); } }); } addComponent({ name: "NuxtPage", priority: 10, // built-in that we do not expect the user to override filePath: resolve(distDir, "pages/runtime/page") }); } }); const components = ["NoScript", "Link", "Base", "Title", "Meta", "Style", "Head", "Html", "Body"]; const metaModule = defineNuxtModule({ meta: { name: "meta", configKey: "unhead" }, async setup(options, nuxt) { const runtimeDir = resolve(distDir, "head/runtime"); nuxt.options.build.transpile.push("@unhead/vue"); const componentsPath = resolve(runtimeDir, "components"); for (const componentName of components) { addComponent({ name: componentName, filePath: componentsPath, export: componentName, // built-in that we do not expect the user to override priority: 10, // kebab case version of these tags is not valid kebabName: componentName }); } if (!nuxt.options.dev) { nuxt.options.optimization.treeShake.composables.client["@unhead/vue"] = [ "useServerHead", "useServerSeoMeta", "useServerHeadSafe" ]; } addImportsSources({ from: "@unhead/vue", // hard-coded for now we so don't support auto-imports on the deprecated composables imports: [ "injectHead", "useHead", "useSeoMeta", "useHeadSafe", "useServerHead", "useServerSeoMeta", "useServerHeadSafe" ] }); const unheadVue = await tryResolveModule("@unhead/vue", nuxt.options.modulesDir) || "@unhead/vue"; if (nuxt.options.experimental.polyfillVueUseHead) { nuxt.options.alias["@vueuse/head"] = unheadVue; addPlugin({ src: resolve(runtimeDir, "plugins/vueuse-head-polyfill") }); } addTemplate({ filename: "unhead-plugins.mjs", getContents() { if (!nuxt.options.experimental.headNext) { return "export default []"; } return `import { CapoPlugin } from ${JSON.stringify(unheadVue)}; export default import.meta.server ? [CapoPlugin({ track: true })] : [];`; } }); addTemplate({ filename: "unhead.config.mjs", getContents() { return [ `export const renderSSRHeadOptions = ${JSON.stringify(options.renderSSRHeadOptions || {})}` ].join("\n"); } }); nuxt.hooks.hook("nitro:config", (config) => { config.virtual["#internal/unhead-plugins.mjs"] = () => nuxt.vfs["#build/unhead-plugins"]; config.virtual["#internal/unhead.config.mjs"] = () => nuxt.vfs["#build/unhead.config"]; }); addPlugin({ src: resolve(runtimeDir, "plugins/unhead") }); } }); const CLIENT_FALLBACK_RE = /<(?:NuxtClientFallback|nuxt-client-fallback)(?: [^>]*)?>/; const CLIENT_FALLBACK_GLOBAL_RE = /<(NuxtClientFallback|nuxt-client-fallback)( [^>]*)?>/g; const clientFallbackAutoIdPlugin = createUnplugin((options) => { const exclude = options.transform?.exclude || []; const include = options.transform?.include || []; return { name: "nuxt:client-fallback-auto-id", enforce: "pre", transformInclude(id) { if (exclude.some((pattern) => pattern.test(id))) { return false; } if (include.some((pattern) => pattern.test(id))) { return true; } return isVue(id); }, transform(code, id) { if (!CLIENT_FALLBACK_RE.test(code)) { return; } const s = new MagicString(code); const relativeID = isAbsolute(id) ? relative(options.rootDir, id) : id; let count = 0; s.replace(CLIENT_FALLBACK_GLOBAL_RE, (full, name, attrs) => { count++; if (/ :?uid=/.test(attrs)) { return full; } return `<${name} :uid="'${hash(relativeID)}' + JSON.stringify($props) + '${count}'" ${attrs ?? ""}>`; }); if (s.hasChanged()) { return { code: s.toString(), map: options.sourcemap ? s.generateMap({ hires: true }) : void 0 }; } } }; }); const createImportMagicComments = (options) => { const { chunkName, prefetch, preload } = options; return [ `webpackChunkName: "${chunkName}"`, prefetch === true || typeof prefetch === "number" ? `webpackPrefetch: ${prefetch}` : false, preload === true || typeof preload === "number" ? `webpackPreload: ${preload}` : false ].filter(Boolean).join(", "); }; const emptyComponentsPlugin = ` import { defineNuxtPlugin } from '#app/nuxt' export default defineNuxtPlugin({ name: 'nuxt:global-components', }) `; const componentsPluginTemplate = { filename: "components.plugin.mjs", getContents({ app }) { const lazyGlobalComponents = /* @__PURE__ */ new Set(); const syncGlobalComponents = /* @__PURE__ */ new Set(); for (const component of app.components) { if (component.global === "sync") { syncGlobalComponents.add(component.pascalName); } else if (component.global) { lazyGlobalComponents.add(component.pascalName); } } if (!lazyGlobalComponents.size && !syncGlobalComponents.size) { return emptyComponentsPlugin; } const lazyComponents = [...lazyGlobalComponents]; const syncComponents = [...syncGlobalComponents]; return `import { defineNuxtPlugin } from '#app/nuxt' import { ${[...lazyComponents.map((c) => "Lazy" + c), ...syncComponents].join(", ")} } from '#components' const lazyGlobalComponents = [ ${lazyComponents.map((c) => `["${c}", Lazy${c}]`).join(",\n")}, ${syncComponents.map((c) => `["${c}", ${c}]`).join(",\n")} ] export default defineNuxtPlugin({ name: 'nuxt:global-components', setup (nuxtApp) { for (const [name, component] of lazyGlobalComponents) { nuxtApp.vueApp.component(name, component) nuxtApp.vueApp.component('Lazy' + name, component) } } }) `; } }; const componentNamesTemplate = { filename: "component-names.mjs", getContents({ app }) { return `export const componentNames = ${JSON.stringify(app.components.filter((c) => !c.island).map((c) => c.pascalName))}`; } }; const componentsIslandsTemplate = { // components.islands.mjs' getContents({ app, nuxt }) { if (!nuxt.options.experimental.componentIslands) { return "export const islandComponents = {}"; } const components = app.components; const pages = app.pages; const islands = components.filter( (component) => component.island || // .server components without a corresponding .client component will need to be rendered as an island component.mode === "server" && !components.some((c) => c.pascalName === component.pascalName && c.mode === "client") ); const pageExports = pages?.filter((p) => p.mode === "server" && p.file && p.name).map((p) => { return `"page:${p.name}": defineAsyncComponent(${genDynamicImport(p.file)}.then(c => c.default || c))`; }) || []; return [ "import { defineAsyncComponent } from 'vue'", "export const islandComponents = import.meta.client ? {} : {", islands.map( (c) => { const exp = c.export === "default" ? "c.default || c" : `c['${c.export}']`; const comment = createImportMagicComments(c); return ` "${c.pascalName}": defineAsyncComponent(${genDynamicImport(c.filePath, { comment })}.then(c => ${exp}))`; } ).concat(pageExports).join(",\n"), "}" ].join("\n"); } }; const componentsTypeTemplate = { filename: "components.d.ts", getContents: ({ app, nuxt }) => { const buildDir = nuxt.options.buildDir; const componentTypes = app.components.filter((c) => !c.island).map((c) => { const type = `typeof ${genDynamicImport(isAbsolute(c.filePath) ? relative(buildDir, c.filePath).replace(/\b\.(?!vue)\w+$/g, "") : c.filePath.replace(/\b\.(?!vue)\w+$/g, ""), { wrapper: false })}['${c.export}']`; return [ c.pascalName, c.island || c.mode === "server" ? `IslandComponent<${type}>` : type ]; }); const islandType = "type IslandComponent<T extends DefineComponent> = T & DefineComponent<{}, {refresh: () => Promise<void>}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, SlotsType<{ fallback: { error: unknown } }>>"; return ` import type { DefineComponent, SlotsType } from 'vue' ${nuxt.options.experimental.componentIslands ? islandType : ""} interface _GlobalComponents { ${componentTypes.map(([pascalName, type]) => ` '${pascalName}': ${type}`).join("\n")} ${componentTypes.map(([pascalName, type]) => ` 'Lazy${pascalName}': ${type}`).join("\n")} } declare module 'vue' { export interface GlobalComponents extends _GlobalComponents { } } ${componentTypes.map(([pascalName, type]) => `export const ${pascalName}: ${type}`).join("\n")} ${componentTypes.map(([pascalName, type]) => `export const Lazy${pascalName}: ${type}`).join("\n")} export const componentNames: string[] `; } }; const componentsMetadataTemplate = { filename: "components.json", write: true, getContents: ({ app }) => JSON.stringify(app.components, null, 2) }; async function scanComponents(dirs, srcDir) { const components = []; const filePaths = /* @__PURE__ */ new Set(); const scannedPaths = []; for (const dir of dirs) { if (dir.enabled === false) { continue; } const resolvedNames = /* @__PURE__ */ new Map(); const files = (await globby(dir.pattern, { cwd: dir.path, ignore: dir.ignore })).sort(); if (files.length) { const siblings = await readdir(dirname(dir.path)).catch(() => []); const directory = basename(dir.path); if (!siblings.includes(directory)) { const directoryLowerCase = directory.toLowerCase(); const caseCorrected = siblings.find((sibling) => sibling.toLowerCase() === directoryLowerCase); if (caseCorrected) { const nuxt = useNuxt(); const original = relative(nuxt.options.srcDir, dir.path); const corrected = relative(nuxt.options.srcDir, join(dirname(dir.path), caseCorrected)); logger.warn(`Components not scanned from \`~/${corrected}\`. Did you mean to name the directory \`~/${original}\` instead?`); continue; } } } for (const _file of files) { const filePath = join(dir.path, _file); if (scannedPaths.find((d) => filePath.startsWith(withTrailingSlash(d))) || isIgnored(filePath)) { continue; } if (filePaths.has(filePath)) { continue; } filePaths.add(filePath); const prefixParts = [].concat( dir.prefix ? splitByCase(dir.prefix) : [], dir.pathPrefix !== false ? splitByCase(relative(dir.path, dirname(filePath))) : [] ); let fileName = basename(filePath, extname(filePath)); const island = /\.island(?:\.global)?$/.test(fileName) || dir.island; const global = /\.global(?:\.island)?$/.test(fileName) || dir.global; const mode = island ? "server" : fileName.match(/(?<=\.)(client|server)(\.global|\.island)*$/)?.[1] || "all"; fileName = fileName.replace(/(\.(client|server))?(\.global|\.island)*$/, ""); if (fileName.toLowerCase() === "index") { fileName = dir.pathPrefix === false ? basename(dirname(filePath)) : ""; } const suffix = mode !== "all" ? `-${mode}` : ""; const componentNameSegments = resolveComponentNameSegments(fileName.replace(/["']/g, ""), prefixParts); const pascalName = pascalCase(componentNameSegments); if (LAZY_COMPONENT_NAME_REGEX.test(pascalName)) { logger.warn(`The component \`${pascalName}\` (in \`${filePath}\`) is using the reserved "Lazy" prefix used for dynamic imports, which may cause it to break at runtime.`); } if (resolvedNames.has(pascalName + suffix) || resolvedNames.has(pascalName)) { warnAboutDuplicateComponent(pascalName, filePath, resolvedNames.get(pascalName) || resolvedNames.get(pascalName + suffix)); continue; } resolvedNames.set(pascalName + suffix, filePath); const kebabName = kebabCase(componentNameSegments); const shortPath = relative(srcDir, filePath); const chunkName = "components/" + kebabName + suffix; let component = { // inheritable from directory configuration mode, global, island, prefetch: Boolean(dir.prefetch), preload: Boolean(dir.preload), // specific to the file filePath, pascalName, kebabName, chunkName, shortPath, export: "default", // by default, give priority to scanned components priority: dir.priority ?? 1 }; if (typeof dir.extendComponent === "function") { component = await dir.extendComponent(component) || component; } if (!pascalName) { logger.warn(`Component did not resolve to a file name in \`~/${relative(srcDir, filePath)}\`.`); continue; } const existingComponent = components.find((c) => c.pascalName === component.pascalName && ["all", component.mode].includes(c.mode)); if (existingComponent) { const existingPriority = existingComponent.priority ?? 0; const newPriority = component.priority ?? 0; if (newPriority > existingPriority) { components.splice(components.indexOf(existingComponent), 1, component); } if (newPriority > 0 && newPriority === existingPriority) { warnAboutDuplicateComponent(pascalName, filePath, existingComponent.filePath); } continue; } components.push(component); } scannedPaths.push(dir.path); } return components; } function warnAboutDuplicateComponent(componentName, filePath, duplicatePath) { logger.warn( `Two component files resolving to the same name \`${componentName}\`: - ${filePath} - ${duplicatePath}` ); } const LAZY_COMPONENT_NAME_REGEX = /^Lazy(?=[A-Z])/; const loaderPlugin = createUnplugin((options) => { const exclude = options.transform?.exclude || []; const include = options.transform?.include || []; const serverComponentRuntime = resolve(distDir, "components/runtime/server-component"); return { name: "nuxt:components-loader", enforce: "post", transformInclude(id) { if (exclude.some((pattern) => pattern.test(id))) { return false; } if (include.some((pattern) => pattern.test(id))) { return true; } return isVue(id, { type: ["template", "script"] }) || !!id.match(/\.[tj]sx$/); }, transform(code) { const components = options.getComponents(); let num = 0; const imports = /* @__PURE__ */ new Set(); const map = /* @__PURE__ */ new Map(); const s = new MagicString(code); s.replace(/(?<=[ (])_?resolveComponent\(\s*["'](lazy-|Lazy(?=[A-Z]))?([^'"]*)["'][^)]*\)/g, (full, lazy, name) => { const component = findComponent(components, name, options.mode); if (component) { if (component._internal_install && tryUseNuxt()?.options.test === false) { import('./chunks/features.mjs').then(({ installNuxtModule }) => installNuxtModule(component._internal_install)); } let identifier = map.get(component) || `__nuxt_component_${num++}`; map.set(component, identifier); const isServerOnly = !component._raw && component.mode === "server" && !components.some((c) => c.pascalName === component.pascalName && c.mode === "client"); if (isServerOnly) { imports.add(genImport(serverComponentRuntime, [{ name: "createServerComponent" }])); imports.add(`const ${identifier} = createServerComponent(${JSON.stringify(component.pascalName)})`); if (!options.experimentalComponentIslands) { logger.warn(`Standalone server components (\`${name}\`) are not yet supported without enabling \`experimental.componentIslands\`.`); } return identifier; } const isClientOnly = !component._raw && component.mode === "client"; if (isClientOnly) { imports.add(genImport("#app/components/client-only", [{ name: "createClientOnly" }])); identifier += "_client"; } if (lazy) { imports.add(genImport("vue", [{ name: "defineAsyncComponent", as: "__defineAsyncComponent" }])); identifier += "_lazy"; imports.add(`const ${identifier} = __defineAsyncComponent(${genDynamicImport(component.filePath, { interopDefault: false })}.then(c => c.${component.export ?? "default"} || c)${isClientOnly ? ".then(c => createClientOnly(c))" : ""})`); } else { imports.add(genImport(component.filePath, [{ name: component._raw ? "default" : component.export, as: identifier }])); if (isClientOnly) { imports.add(`const ${identifier}_wrapped = createClientOnly(${identifier})`); identifier += "_wrapped"; } } return identifier; } return full; }); if (imports.size) { s.prepend([...imports, ""].join("\n")); } if (s.hasChanged()) { return { code: s.toString(), map: options.sourcemap ? s.generateMap({ hires: true }) : void 0 }; } } }; }); function findComponent(components, name, mode) { const id = pascalCase(name).replace(/["']/g, ""); const component = components.find((component2) => id === component2.pascalName && ["all", mode, void 0].includes(component2.mode)); if (component) { return component; } const otherModeComponent = components.find((component2) => id === component2.pascalName); if (mode === "server" && otherModeComponent) { return components.find((c) => c.pascalName === "ServerPlaceholder"); } return otherModeComponent; } const SSR_RENDER_RE = /ssrRenderComponent/; const PLACEHOLDER_EXACT_RE = /^(?:fallback|placeholder)$/; const CLIENT_ONLY_NAME_RE = /^(?:_unref\()?(?:_component_)?(?:Lazy|lazy_)?(?:client_only|ClientOnly\)?)$/; const PARSER_OPTIONS = { sourceType: "module", ecmaVersion: "latest" }; const TreeShakeTemplatePlugin = createUnplugin((options) => { const regexpMap = /* @__PURE__ */ new WeakMap(); return { name: "nuxt:tree-shake-template", enforce: "post", transformInclude(id) { const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href)); return pathname.endsWith(".vue"); }, transform(code) { const components = options.getComponents(); if (!regexpMap.has(components)) { const clientOnlyComponents = components.filter((c) => c.mode === "client" && !components.some((other) => other.mode !== "client" && other.pascalName === c.pascalName && other.filePath !== resolve(distDir, "app/components/server-placeholder"))).flatMap((c) => [c.pascalName, c.kebabName.replaceAll("-", "_")]).concat(["ClientOnly", "client_only"]); regexpMap.set(components, [new RegExp(`(${clientOnlyComponents.join("|")})`), new RegExp(`^(${clientOnlyComponents.map((c) => `(?:(?:_unref\\()?(?:_component_)?(?:Lazy|lazy_)?${c}\\)?)`).join("|")})$`), clientOnlyComponents]); } const s = new MagicString(code); const [COMPONENTS_RE, COMPONENTS_IDENTIFIERS_RE] = regexpMap.get(components); if (!COMPONENTS_RE.test(code)) { return; } const codeAst = this.parse(code, PARSER_OPTIONS); const componentsToRemoveSet = /* @__PURE__ */ new Set(); walk(codeAst, { enter: (_node) => { const node = _node; if (isSsrRender(node)) { const [componentCall, _, children] = node.arguments; if (componentCall.type === "Identifier" || componentCall.type === "MemberExpression" || componentCall.type === "CallExpression") { const componentName = getComponentName(node); const isClientComponent = COMPONENTS_IDENTIFIERS_RE.test(componentName); const isClientOnlyComponent = CLIENT_ONLY_NAME_RE.test(componentName); if (isClientComponent && children?.type === "ObjectExpression") { const slotsToRemove = isClientOnlyComponent ? children.properties.filter((prop) => prop.type === "Property" && prop.key.type === "Identifier" && !PLACEHOLDER_EXACT_RE.test(prop.key.name)) : children.properties; for (const slot of slotsToRemove) { s.remove(slot.start, slot.end + 1); const removedCode = `({${code.slice(slot.start, slot.end + 1)}})`; const currentCodeAst = this.parse(s.toString(), PARSER_OPTIONS); walk(this.parse(removedCode, PARSER_OPTIONS), { enter: (_node2) => { const node2 = _node2; if (isSsrRender(node2)) { const name = getComponentName(node2); const nameToRemove = isComponentNotCalledInSetup(currentCodeAst, name); if (nameToRemove) { componentsToRemoveSet.add(nameToRemove); } } } }); } } } } } }); const componentsToRemove = [...componentsToRemoveSet]; const removedNodes = /* @__PURE__ */ new WeakSet(); for (const componentName of componentsToRemove) { removeImportDeclaration(codeAst, componentName, s); removeVariableDeclarator(codeAst, componentName, s, removedNodes); removeFromSetupReturn(codeAst, componentName, s); } if (s.hasChanged()) { return { code: s.toString(), map: options.sourcemap ? s.generateMap({ hires: true }) : void 0 }; } } }; }); function removeFromSetupReturn(codeAst, name, magicString) { let walkedInSetup = false; walk(codeAst, { enter(node) { if (walkedInSetup) { this.skip(); } else if (node.type === "Property" && node.key.type === "Identifier" && node.key.name === "setup" && (node.value.type === "FunctionExpression" || node.value.type === "ArrowFunctionExpression")) { walkedInSetup = true; if (node.value.body.type === "BlockStatement") { const returnStatement = node.value.body.body.find((statement) => statement.type === "ReturnStatement"); if (returnStatement && returnStatement.argument?.type === "ObjectExpression") { removePropertyFromObject(returnStatement.argument, name, magicString); } const variableList = node.value.body.body.filter((statement) => statement.type === "VariableDeclaration"); const returnedVariableDeclaration = variableList.find((declaration) => declaration.declarations[0]?.id.type === "Identifier" && declaration.declarations[0]?.id.name === "__returned__" && declaration.declarations[0]?.init?.type === "ObjectExpression"); if (returnedVariableDeclaration) { const init = returnedVariableDeclaration.declarations[0].init; removePropertyFromObject(init, name, magicString); } } } } }); } function removePropertyFromObject(node, name, magicString) { for (const property of node.properties) { if (property.type === "Property" && property.key.type === "Identifier" && property.key.name === name) { magicString.remove(property.start, property.end + 1); return true; } } return false; } function isSsrRender(node) { return node.type === "CallExpression" && node.callee.type === "Identifier" && SSR_RENDER_RE.test(node.callee.name); } function removeImportDeclaration(ast, importName, magicString) { for (const node of ast.body) { if (node.type === "ImportDeclaration") { const specifier = node.specifiers.find((s) => s.local.name === importName); if (specifier) { if (node.specifiers.length > 1) { const specifierIndex = node.specifiers.findIndex((s) => s.local.name === importName); if (specifierIndex > -1) { magicString.remove(node.specifiers[specifierIndex].start, node.specifiers[specifierIndex].end + 1); node.specifiers.splice(specifierIndex, 1); } } else { magicString.remove(node.start, node.end); } return true; } } } return false; } function isComponentNotCalledInSetup(codeAst, name) { if (name) { let found = false; walk(codeAst, { enter(node) { if (node.type === "Property" && node.key.type === "Identifier" && node.value.type === "FunctionExpression" && node.key.name === "setup" || node.type === "FunctionDeclaration" && (node.id?.name === "_sfc_ssrRender" || node.id?.name === "ssrRender")) { walk(node, { enter(node2) { if (found || node2.type === "VariableDeclaration") { this.skip(); } else if (node2.type === "Identifier" && node2.name === name) { found = true; } else if (node2.type === "MemberExpression") { found = node2.property.type === "Literal" && node2.property.value === name || node2.property.type === "Identifier" && node2.property.name === name; } } }); } } }); if (!found) { return name; } } } function getComponentName(ssrRenderNode) { const componentCall = ssrRenderNode.arguments[0]; if (componentCall.type === "Identifier") { return componentCall.name; } else if (componentCall.type === "MemberExpression") { return componentCall.property.value; } return componentCall.arguments[0].name; } function removeVariableDeclarator(codeAst, name, magicString, removedNodes) { walk(codeAst, { enter(node) { if (node.type === "VariableDeclaration") { for (const declarator of node.declarations) { const toRemove = findMatchingPatternToRemove(declarator.id, node, name, removedNodes); if (toRemove) { magicString.remove(toRemove.start, toRemove.end + 1); removedNodes.add(toRemove); return toRemove; } } } } }); } function findMatchingPatternToRemove(node, toRemoveIfMatched, name, removedNodeSet) { if (node.type === "Identifier") { if (node.name === name) { return toRemoveIfMatched; } } else if (node.type === "ArrayPattern") { const elements = node.elements.filter((e) => e !== null && !removedNodeSet.has(e)); for (const element of elements) { const matched = findMatchingPatternToRemove(element, elements.length > 1 ? element : toRemoveIfMatched, name, removedNodeSet); if (matched) { return matched; } } } else if (node.type === "ObjectPattern") { const properties = node.properties.filter((e) => e.type === "Property" && !removedNodeSet.has(e)); for (const [index, property] of properties.entries()) { let nodeToRemove = property; if (properties.length < 2) { nodeToRemove = toRemoveIfMatched; } const matched = findMatchingPatternToRemove(property.value, nodeToRemove, name, removedNodeSet); if (matched) { if (matched === property) { properties.splice(index, 1); } return matched; } } } else if (node.type === "AssignmentPattern") { const matched = findMatchingPatternToRemove(node.left, toRemoveIfMatched, name, removedNodeSet); if (matched) { return matched; } } } const SCRIPT_RE = /<script[^>]*>/g; const HAS_SLOT_OR_CLIENT_RE = /<slot[^>]*>|nuxt-client/; const TEMPLATE_RE = /<template>([\s\S]*)<\/template>/; const NUXTCLIENT_ATTR_RE = /\s:?nuxt-client(="[^"]*")?/g; const IMPORT_CODE = "\nimport { mergeProps as __mergeProps } from 'vue'\nimport { vforToArray as __vforToArray } from '#app/components/utils'\nimport NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component'\nimport NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'"; const EXTRACTED_ATTRS_RE = /v-(?:if|else-if|else)(="[^"]*")?/g; function wrapWithVForDiv(code, vfor) { return `<div v-for="${vfor}" style="display: contents;">${code}</div>`; } const islandsTransform = createUnplugin((options, meta) => { const isVite = meta.framework === "vite"; return { name: "server-only-component-transform", enforce: "pre", transformInclude(id) { if (!isVue(id)) { return false; } if (options.selectiveClient === "deep") { return true; } const components = options.getComponents(); const islands = components.filter( (component) => component.island || component.mode === "server" && !components.some((c) => c.pascalName === component.pascalName && c.mode === "client") ); const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href)); return islands.some((c) => c.filePath === pathname); }, async transform(code, id) { if (!HAS_SLOT_OR_CLIENT_RE.test(code)) { return; } const template = code.match(TEMPLATE_RE); if (!template) { return; } const startingIndex = template.index || 0; const s = new MagicString(code); if (!code.match(SCRIPT_RE)) { s.prepend("<script setup>" + IMPORT_CODE + "<\/script>"); } else { s.replace(SCRIPT_RE, (full) => { return full + IMPORT_CODE; }); } let hasNuxtClient = false; const ast = parse$1(template[0]); await walk$1(ast, (node) => { if (node.type === ELEMENT_NODE) { if (node.name === "slot") { const { attributes, children, loc } = node; const slotName = attributes.name ?? "default"; if (attributes.name) { delete attributes.name; } if (attributes["v-bind"]) { attributes._bind = extractAttributes(attributes, ["v-bind"])["v-bind"]; } const teleportAttributes = extractAttributes(attributes, ["v-if", "v-else-if", "v-else"]); const bindings = getPropsToString(attributes); s.appendLeft(startingIndex + loc[0].start, `<NuxtTeleportSsrSlot${attributeToString(teleportAttributes)} name="${slotName}" :props="${bindings}">`); if (children.length) { const attrString = attributeToString(attributes); const slice = code.slice(startingIndex + loc[0].end, startingIndex + loc[1].start).replaceAll(/:?key="[^"]"/g, ""); s.overwrite(startingIndex + loc[0].start, startingIndex + loc[1].end, `<slot${attrString.replaceAll(EXTRACTED_ATTRS_RE, "")}/><template #fallback>${attributes["v-for"] ? wrapWithVForDiv(slice, attributes["v-for"]) : slice}</template>`); } else { s.overwrite(startingIndex + loc[0].start, startingIndex + loc[0].end, code.slice(startingIndex + loc[0].start, startingIndex + loc[0].end).replaceAll(EXTRACTED_ATTRS_RE, "")); } s.appendRight(startingIndex + loc[1].end, "</NuxtTeleportSsrSlot>"); } else if (options.selectiveClient && ("nuxt-client" in node.attributes || ":nuxt-client" in node.attributes)) { hasNuxtClient = true; const { loc, attributes } = node; const attributeValue = attributes[":nuxt-client"] || attributes["nuxt-client"] || "true"; if (isVite) { const uid = hash(id + node.loc[0].start + node.loc[0].end); const wrapperAttributes = extractAttributes(attributes, ["v-if", "v-else-if", "v-else"]); let startTag = code.slice(startingIndex + loc[0].start, startingIndex + loc[0].end).replace(NUXTCLIENT_ATTR_RE, ""); if (wrapperAttributes) { startTag = startTag.replaceAll(EXTRACTED_ATTRS_RE, ""); } s.appendLeft(startingIndex + loc[0].start, `<NuxtTeleportIslandComponent${attributeToString(wrapperAttributes)} to="${node.name}-${uid}" :nuxt-client="${attributeValue}">`); s.overwrite(startingIndex + loc[0].start, startingIndex + loc[0].end, startTag); s.appendRight(startingIndex + loc[1].end, "</NuxtTeleportIslandComponent>"); } } } }); if (!isVite && hasNuxtClient) { console.warn(`nuxt-client attribute and client components within islands is only supported with Vite. file: ${id}`); } if (s.hasChanged()) { return { code: s.toString(), map: s.generateMap({ source: id, includeContent: true }) }; } } }; }); function extractAttributes(attributes, names) { const extracted = {}; for (const name of names) { if (name in attributes) { extracted[name] = attributes[name]; delete attributes[name]; } } return extracted; } function attributeToString(attributes) { return Object.entries(attributes).map(([name, value]) => value ? ` ${name}="${value}"` : ` ${name}`).join(""); } function isBinding(attr) { return attr.startsWith(":"); } function getPropsToString(bindings) { const vfor = bindings["v-for"]?.split(" in ").map((v) => v.trim()); if (Object.keys(bindings).length === 0) { return "undefined"; } const content = Object.entries(bindings).filter((b) => b[0] && (b[0] !== "_bind" && b[0] !== "v-for")).map(([name, value]) => isBinding(name) ? `[\`${name.slice(1)}\`]: ${value}` : `[\`${name}\`]: \`${value}\``).join(","); const data = bindings._bind ? `__mergeProps(${bindings._bind}, { ${content} })` : `{ ${content} }`; if (!vfor) { return `[${data}]`; } else { return `__vforToArray(${vfor[1]}).map(${vfor[0]} => (${data}))`; } } const componentsChunkPlugin = createUnplugin((options) => { const { buildDir } = options; return { name: "componentsChunkPlugin", vite: { async config(config) { const components = options.getComponents(); config.build = defu$1(config.build, { rollupOptions: { input: {}, output: {} } }); const rollupOptions = config.build.rollupOptions; if (typeof rollupOptions.input === "string") { rollupOptions.input = { entry: rollupOptions.input }; } else if (typeof rollupOptions.input === "object" && Array.isArray(rollupOptions.input)) { rollupOptions.input = rollupOptions.input.reduce((acc, input) => { acc[input] = input; return acc; }, {}); } rollupOptions.preserveEntrySignatures = "allow-extension"; for (const component of components) { if (component.mode === "client" || component.mode === "all") { rollupOptions.input[component.pascalName] = await resolvePath$1(component.filePath); } } }, async generateBundle(_opts, bundle) { const components = options.getComponents().filter((c) => c.mode === "client" || c.mode === "all"); const pathAssociation = {}; for (const [chunkPath, chunkInfo] of Object.entries(bundle)) { if (chunkInfo.type !== "chunk") { continue; } for (const component of components) { if (chunkInfo.facadeModuleId && chunkInfo.exports.length > 0) { const { pathname } = parseURL(decodeURIComponent(pathToFileURL(chunkInfo.facadeModuleId).href)); const isPath = await resolvePath$1(component.filePath) === pathname; if (isPath) { chunkInfo.isEntry = false; pathAssociation[component.pascalName] = chunkPath; } } } } fs.writeFileSync(join(buildDir, "components-chunk.mjs"), `export const paths = ${JSON.stringify(pathAssociation, null, 2)}`); } } }; }); const COMPONENT_QUERY_RE = /[?&]nuxt_component=/; function createTransformPlugin(nuxt, getComponents, mode) { const serverComponentRuntime = resolve(distDir, "components/runtime/server-component"); const componentUnimport = createUnimport({ imports: [ { name: "componentNames", from: "#build/component-names" } ], virtualImports: ["#components"] }); function getComponentsImports() { const components = getComponents(mode); return components.flatMap((c) => { const withMode = (mode3) => mode3 ? `${c.filePath}${c.filePath.includes("?") ? "&" : "?"}nuxt_component=${mode3}&nuxt_component_name=${c.pascalName}&nuxt_component_export=${c.export || "default"}` : c.filePath; const mode2 = !c._raw && c.mode && ["client", "server"].includes(c.mode) ? c.mode : void 0; return [ { as: c.pascalName, from: withMode(mode2), name: c.export || "default" }, { as: "Lazy" + c.pascalName, from: withMode([mode2, "async"].filter(Boolean).join(",")), name: c.export || "default" } ]; }); } return createUnplugin(() => ({ name: "nuxt:components:imports", transformInclude(id) { id = normalize(id); return id.startsWith("virtual:") || id.startsWith("\0virtual:") || id.startsWith(nuxt.options.buildDir) || !isIgnored(id); }, async transform(code, id) { if (COMPONENT_QUERY_RE.test(id)) { const { search } = parseURL(id); const query = parseQuery$1(search); const mode2 = query.nuxt_component; const bare = id.replace(/\?.*/, ""); const componentExport = query.nuxt_component_export || "default"; const exportWording = componentExport === "default" ? "export default" : `export const ${componentExport} =`; if (mode2 === "async") { return { code: [ 'import { defineAsyncComponent } from "vue"', `${exportWording} defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => r[${JSON.stringify(componentExport)}] || r.default || r))` ].join("\n"), map: null }; } else if (mode2 === "client") { return { code: [ genImport(bare, [{ name: componentExport, as: "__component" }]), 'import { createClientOnly } from "#app/components/client-only"', `${exportWording} createClientOnly(__component)` ].join("\n"), map: null }; } else if (mode2 === "client,async") { return { code: [ 'import { defineAsyncComponent } from "vue"', 'import { createClientOnly } from "#app/components/client-only"', `${exportWording} defineAsyncComponent(() => import(${JSON.stringify(bare)}).then(r => createClientOnly(r[${JSON.stringify(componentExport)}] || r.default || r)))` ].join("\n"), map: null }; } else if (mode2 === "server" || mode2 === "server,async") { const name = query.nuxt_component_name; return { code: [ `import { createServerComponent } from ${JSON.stringify(serverComponentRuntime)}`, `${exportWording} createServerComponent(${JSON.stringify(name)})` ].join("\n"), map: null }; } else { throw new Error(`Unknown component mode: ${mode2}, this might be an internal bug of Nuxt.`); } } if (!code.includes("#components")) { return; } componentUnimport.modifyDynamicImports((imports) => { imports.length = 0; imports.push(...getComponentsImports()); return imports; }); const result = await componentUnimport.injectImports(code, id, { autoImport: false, transformVirtualImports: true }); if (!result) { return; } return { code: result.code, map: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client ? result.s.generateMap({ hires: true }) : void 0 }; } })); } const isPureObjectOrString = (val) => !Array.isArray(val) && typeof val === "object" || typeof val === "string"; const isDirectory = (p) => { try { return statSync(p).isDirectory(); } catch { return false; } }; function compareDirByPathLength({ path: pathA }, { path: pathB }) { return pathB.split(/[\\/]/).filter(Boolean).length - pathA.split(/[\\/]/).filter(Boolean).length; } const DEFAULT_COMPONENTS_DIRS_RE = /\/components(?:\/(?:global|islands))?$/; const componentsModule = defineNuxtModule({ meta: { name: "components", configKey: "components" }, defaults: { dirs: [] }, setup(componentOptions, nuxt) { let componentDirs = []; const context = { components: [] }; const getComponents = (mode) => { return mode && mode !== "all" ? context.components.filter((c) => c.mode === mode || c.mode === "all" || c.mode === "server" && !context.components.some((otherComponent) => otherComponent.mode !== "server" && otherComponent.pascalName === c.pascalName)) : context.components; }; const normalizeDirs = (dir, cwd, options) => { if (Array.isArray(dir)) { return dir.map((dir2) => normalizeDirs(dir2, cwd, options)).flat().sort(compareDirByPathLength); } if (dir === true || dir === void 0) { return [ { priority: options?.priority || 0, path: resolve(cwd, "components/islands"), island: true }, { priority: options?.priority || 0, path: resolve(cwd, "components/global"), global: true }, { priority: options?.priority || 0, path: resolve(cwd, "components") } ]; } if (typeof dir === "string") { return [ { priority: options?.priority || 0, path: resolve(cwd, resolveAlias(dir)) } ]; } if (!dir) { return []; } const dirs = (dir.dirs || [dir]).map((dir2) => typeof dir2 === "string" ? { path: dir2 } : dir2).filter((_dir) => _dir.path); return dirs.map((_dir) => ({ priority: options?.priority || 0, ..._dir, path: resolve(cwd, resolveAlias(_dir.path)) })); }; nuxt.hook("app:resolve", async () => { const allDirs = nuxt.options._layers.map((layer) => normalizeDirs(layer.config.components, layer.config.srcDir, { priority: layer.config.srcDir === nuxt.options.srcDir ? 1 : 0 })).flat(); await nuxt.callHook("components:dirs", allDirs); componentDirs = allDirs.filter(isPureObjectOrString).map((dir) => { const dirOptions = typeof dir === "object" ? dir : { path: dir }; const dirPath = resolveAlias(dirOptions.path); const transpile = typeof dirOptions.transpile === "boolean" ? dirOptions.transpile : "auto"; const extensions = (dirOptions.extensions || nuxt.options.extensions).map((e) => e.replace(/^\./g, "")); const present = isDirectory(dirPath); if (!present && !DEFAULT_COMPONENTS_DIRS_RE.test(dirOptions.path)) { logger.warn("Components directory not found: `" + dirPath + "`"); } return { global: componentOptions.global, ...dirOptions, // TODO: https://github.com/nuxt/framework/pull/251 enabled: true, path: dirPath, extensions, pattern: dirOptions.pattern || `**/*.{${extensions.join(",")},}`, ignore: [ "**/*{M,.m,-m}ixin.{js,ts,jsx,tsx}", // ignore mixins "**/*.d.{cts,mts,ts}", // .d.ts files ...dirOptions.ignore || [] ], transpile: transpile === "auto" ? dirPath.includes("node_modules") : transpile }; }).filter((d) => d.enabled); componentDirs = [ ...componentDirs.filter((dir) => !dir.path.includes("node_modules")), ...componentDirs.filter((dir) => dir.path.includes("node_modules")) ]; nuxt.options.build.transpile.push(...componentDirs.filter((dir) => dir.transpile).map((dir) => dir.path)); }); addTypeTemplate(componentsTypeTemplate); addPluginTemplate(componentsPluginTemplate); addTemplate(componentNamesTemplate); addTemplate({ ...componentsIslandsTemplate, filename: "components.islands.mjs" }); if (componentOptions.generateMetadata) { addTemplate(componentsMetadataTemplate); } const unpluginServer = createTransformPlugin(nuxt, getComponents, "server"); const unpluginClient = createTransformPlugin(nuxt, getComponents, "client"); addVitePlugin(() => unpluginServer.vite(), { server: true, client: false }); addVitePlugin(() => unpluginClient.vite(), { server: false, client: true }); addWebpackPlugin(() => unpluginServer.webpack(), { server: true, client: false }); addWebpackPlugin(() => unpluginClient.webpack(), { server: false, client: true }); nuxt.hook("build:manifest", (manifest) => { const sourceFiles = getComponents().filter((c) => c.global).map((c) => relative(nuxt.options.srcDir, c.filePath)); for (const key in manifest) { if (manifest[key].isEntry) { manifest[key].dynamicImports = manifest[key].dynamicImports?.filter((i) => !sourceFiles.includes(i)); } } }); nuxt.hook("builder:watch", (event, relativePath) => { if (!["addDir", "unlinkDir"].includes(event)) { return; } const path = resolve(nuxt.options.srcDir, relativePath); if (componentDirs.some((dir) => dir.path === path)) { logger.info(`Directory \`${relativePath}/\` ${event === "addDir" ? "created" : "removed"}`); return nuxt.callHook("restart"); } }); const serverPlaceholderPath = resolve(distDir, "app/components/server-placeholder"); nuxt.hook("app:templates", async (app) => { const newComponents = await scanComponents(componentDirs, nuxt.options.srcDir); await nuxt.callHook("components:extend", newComponents); for (const component of newComponents) { if (component.mode === "client" && !newComponents.some((c) => c.pascalName === component.pascalName && c.mode === "server")) { newComponents.push({ ...component, _raw: true, mode: "server", filePath: serverPlaceholderPath, chunkName: "components/" + component.kebabName }); } if (component.mode === "server" && !nuxt.options.ssr && !newComponents.some((other) => other.pascalName === component.pascalName && other.mode === "client")) { logger.warn(`Using server components with \`ssr: false\` is not supported with auto-detected component islands. If you need to use server component \`${component.pascalName}\`, set \`experimental.componentIslands\` to \`true\`.`); } } context.components = newComponents; app.components = newComponents; }); nuxt.hook("prepare:types", ({ tsConfig }) => { tsConfig.compilerOptions.paths["#components"] = [resolve(nuxt.options.buildDir, "components")]; }); nuxt.hook("builder:watch", async (event, relativePath) => { if (!["add", "unlink"].includes(event)) { return; } const path = resolve(nuxt.options.srcDir, relativePath); if (componentDirs.some((dir) => path.startsWith(dir.path + "/"))) { await updateTemplates({ filter: (template) => [ "components.plugin.mjs", "components.d.ts", "components.server.mjs", "components.client.mjs" ].includes(template.filename) }); } }); nuxt.hook("vite:extendConfig", (config, { isClient, isServer }) => { const mode = isClient ? "client" : "server"; config.plugins = config.plugins || []; if (nuxt.options.experimental.treeshakeClientOnly && isServer) { config.plugins.push(TreeShakeTemplatePlugin.vite({ sourcemap: !!nuxt.options.sourcemap[mode], getComponents })); } if (nuxt.options.experimental.clientFallback) { config.plugins.push(clientFallbackAutoIdPlugin.vite({ sourcemap: !!nuxt.options.sourcemap[mode], rootDir: nuxt.options.rootDir })); } config.plugins.push(loaderPlugin.vite({ sourcemap: !!nuxt.options.sourcemap[mode], getComponents, mode, transform: typeof nuxt.options.components === "object" && !Array.isArray(nuxt.options.components) ? nuxt.options.components.transform : void 0, experimentalComponentIslands: !!nuxt.options.experimental.componentIslands })); if (nuxt.options.experimental.componentIslands) { const selectiveClient = typeof nuxt.options.experimental.componentIslands === "object" && nuxt.options.experimental.componentIslands.selectiveClient; if (isClient && selectiveClient) { fs.writeFileSync(join(nuxt.options.buildDir, "components-chunk.mjs"), "export const paths = {}"); if (!nuxt.options.dev) { config.plugins.push(componentsChunkPlugin.vite({ getComponents, buildDir: nuxt.options.buildDir })); } else { fs.writeFileSync(join(nuxt.options.buildDir, "components-chunk.mjs"), `export const paths = ${JSON.stringify( getComponents().filter((c) => c.mode === "client" || c.mode === "all").reduce((acc, c) => { if (c.filePath.endsWith(".vue") || c.filePath.endsWith(".js") || c.filePath.endsWith(".ts")) { return Object.assign(acc, { [c.pascalName]: `/@fs/${c.filePath}` }); } const filePath = fs.existsSync(`${c.filePath}.vue`) ? `${c.filePath}.vue` : fs.existsSync(`${c.filePath}.js`) ? `${c.filePath}.js` : `${c.filePath}.ts`; return Object.assign(acc, { [c.pascalName]: `/@fs/${filePath}` }); }, {}) )}`); } } if (isServer) { config.plugins.push(islandsTransform.vite({ getComponents, selectiveClient })); } } if (!isServer && nuxt.options.experimental.componentIslands) { config.plugins.push({ name: "nuxt-server-component-hmr", handleHotUpdate(ctx) { const components = getComponents(); const filePath = normalize(ctx.file); const comp = components.find((c) => c.filePath === filePath); if (comp?.mode === "server") { ctx.server.ws.send({ event: `nuxt-server-component:${comp.pascalName}`, type: "custom" }); } } }); } }); nuxt.hook("webpack:config", (configs) => { configs.forEach((config) => { const mode = config.name === "client" ? "client" : "server"; config.plugins = config.plugins || []; if (nuxt.options.experimental.treeshakeClientOnly && mode === "server") { config.plugins.push(TreeShakeTemplatePlugin.webpack({ sourcemap: !!nuxt.options.sourcemap[mode], getComponents })); } if (nuxt.options.experimental.clientFallback) { config.plugins.push(clientFallbackAutoIdPlugin.webpack({ sourcemap: !!nuxt.options.sourcemap[mode], rootDir: nuxt.options.rootDir })); } config.plugins.push(loaderPlugin.webpack({ sourcemap: !!nuxt.options.sourcemap[mode], getComponents, mode, transform: typeof nuxt.options.components === "object" && !Array.isArray(nuxt.options.components) ? nuxt.options.components.transform : void 0, experimentalComponentIslands: !!nuxt.options.experimental.componentIslands })); if (nuxt.options.experimental.componentIslands) { if (mode === "server") { config.plugins.push(islandsTransform.webpack({ getComponents })); } else { fs.writeFileSync(join(nuxt.options.buildDir, "components-chunk.mjs"), "export const paths = {}"); } } }); }); } }); const NODE_MODULES_RE = /[\\/]node_modules[\\/]/; const IMPORTS_RE = /(['"])#imports\1/; const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }) => { return { name: "nuxt:imports-transform", enforce: "post", transformInclude(id) { if (options.transform?.include?.some((pattern) => pattern.test(id))) { return true; } if (options.transform?.exclude?.some((pattern) => pattern.test(id))) { return false; } if (isVue(id, { type: ["script", "template"] })) { return true; } return isJS(id); }, async transform(code, id) { id = normalize(id); const isNodeModule = NODE_MODULES_RE.test(id) && !options.transform?.include?.some((pattern) => pattern.test(id)); if (isNodeModule && !IMPORTS_RE.test(code)) { return; } const { s, imports } = await ctx.injectImports(code, id, { autoImport: options.autoImport && !isNodeModule }); if (imports.some((i) => i.from === "#app/composables/script-stubs") && tryUseNuxt()?.options.test === false) { import('./chunks/features.mjs').then(({ installNuxtModule }) => installNuxtModule("@nuxt/scripts")); } if (s.hasChanged()) { return { code: s.toString(), map: sourcemap ? s.generateMap({ hires: true }) : void 0 }; } } }; }); const commonPresets = [ // vue-demi (mocked) defineUnimportPreset({ from: "vue-demi", imports: [ "isVue2", "isVue3" ] }) ]; const granularAppPresets = [ { from: "#app/components/nuxt-link", imports: ["defineNuxtLink"] }, { imports: ["useNuxtApp", "tryUseNuxtApp", "defineNuxtPlugin", "definePayloadPlugin", "useRuntimeConfig", "defineAppConfig"], from: "#app/nuxt" }, { imports: ["requestIdleCallback", "cancelIdleCallback"], from: "#app/compat/idle-callback" }, { imports: ["setInterval"], from: "#app/compat/interval" }, { imports: ["useAppConfig", "updateAppConfig"], from: "#app/config" }, { imports: ["defineNuxtComponent"], from: "#app/composables/component" }, { imports: ["useAsyncData", "useLazyAsyncData", "useNuxtData", "refreshNuxtData", "clearNuxtData"], from: "#app/composables/asyncData" }, { imports: ["useHydration"], from: "#app/composables/hydrate" }, { imports: ["callOnce"], from: "#app/composables/once" }, { imports: ["useState", "clearNuxtState"], from: "#app/composables/state" }, { imports: ["clearError", "createError", "isNuxtError", "showError", "useError"], from: "#app/composables/error" }, { imports: ["useFetch", "useLazyFetch"], from: "#app/composables/fetch" }, { imports: ["useCookie", "refreshCookie"], from: "#app/composables/cookie" }, { imports: ["onPrehydrate", "prerenderRoutes", "useRequestHeader", "useRequestHeaders", "useRequestEvent", "useRequestFetch", "setResponseStatus"], from: "#app/composables/ssr" }, { imports: ["onNuxtReady"], from: "#app/composables/ready" }, { imports: ["preloadComponents", "prefetchComponents", "preloadRouteComponents"], from: "#app/composables/preload" }, { imports: ["abortNavigation", "addRouteMiddleware", "defineNuxtRouteMiddleware", "setPageLayout", "navigateTo", "useRoute", "useRouter"], from: "#app/composables/router" }, { imports: ["isPrerendered", "loadPayload", "preloadPayload", "definePayloadReducer", "definePayloadReviver"], from: "#app/composables/payload" }, { imports: ["useLoadingIndicator"], from: "#app/composables/loading-indicator" }, { imports: ["getAppManifest", "getRouteRules"], from: "#app/composables/manifest" }, { imports: ["reloadNuxtApp"], from: "#app/composables/chunk" }, { imports: ["useRequestURL"], from: "#app/composables/url" }, { imports: ["usePreviewMode"], from: "#app/composables/preview" }, { imports: ["useId"], from: "#app/composables/id" }, { imports: ["useRouteAnnouncer"], from: "#app/composables/route-announcer" } ]; const scriptsStubsPreset = { imports: [ "useScriptTriggerConsent", "useScriptEventPage", "useScriptTriggerElement", "useScript", "useScriptGoogleAnalytics", "useScriptPlausibleAnalytics", "useScriptClarity", "useScriptCloudflareWebAnalytics", "useScriptFathomAnalytics", "useScriptMatomoAnalytics", "useScriptGoogleTagManager", "useScriptGoogleAdsense", "useScriptSegment", "useScriptMetaPixel", "useScriptXPixel", "useScriptIntercom", "useScriptHotjar", "useScriptStripe", "useScriptLemonSqueezy", "useScriptVimeoPlayer", "useScriptYouTubePlayer", "useScriptGoogleMaps", "useScriptNpm", "useScriptCrisp" ], priority: -1, from: "#app/composables/script-stubs" }; const routerPreset = defineUnimportPreset({ imports: ["onBeforeRouteLeave", "onBeforeRouteUpdate"], from: "#app/composables/router" }); const vuePreset = defineUnimportPreset({ from: "vue", imports: [ // <script setup> "withCtx", "withDirectives", "withKeys", "withMemo", "withModifiers", "withScopeId", // Lifecycle "onActivated", "onBeforeMount", "onBeforeUnmount", "onBeforeUpdate", "onDeactivated", "onErrorCaptured", "onMounted", "onRenderTracked", "onRenderTriggered", "onServerPrefetch", "onUnmounted", "onUpdated", // Reactivity "computed", "customRef", "isProxy", "isReactive", "isReadonly", "isRef", "markRaw", "proxyRefs", "reactive", "readonly", "ref", "shallowReactive", "shallowReadonly", "shallowRef", "toRaw", "toRef", "toRefs", "triggerRef", "unref", "watch", "watchEffect", "watchPostEffect", "watchSyncEffect", "isShallow", // effect "effect", "effectScope", "getCurrentScope", "onScopeDispose", // Component "defineComponent", "defineAsyncComponent", "resolveComponent", "getCurrentInstance", "h", "inject", "hasInjectionContext", "nextTick", "provide", "defineModel", "defineOptions", "defineSlots", "mergeModels", "toValue", "useModel", "useAttrs", "useCssModule", "useCssVars", "useSlots", "useTransitionState" ] }); const vueTypesPreset = defineUnimportPreset({ from: "vue", type: true, imports: [ "Component", "ComponentPublicInstance", "ComputedRef", "ExtractPropTypes", "ExtractPublicPropTypes", "InjectionKey", "PropType", "Ref", "MaybeRef", "MaybeRefOrGetter", "VNode" ] }); const defaultPresets = [ ...commonPresets, ...granularAppPresets, routerPreset, vuePreset, vueTypesPreset ]; const importsModule = defineNuxtModule({ meta: { name: "imports", configKey: "imports" }, defaults: { autoImport: true, scan: true, presets: defaultPresets, global: false, imports: [], dirs: [], transform: { include: [], exclude: void 0 }, virtualImports: ["#imports"] }, async setup(options, nuxt) { const presets = JSON.parse(JSON.stringify(options.presets)); await nuxt.callHook("imports:sources", presets); const ctx = createUnimport({ ...options, addons: { vueTemplate: options.autoImport, ...options.addons }, presets }); await nuxt.callHook("imports:context", ctx); let composablesDirs = []; if (options.scan) { for (const layer of nuxt.options._layers) { if (layer.config?.imports?.scan === false) { continue; } composablesDirs.push(resolve(layer.config.srcDir, "composables")); composablesDirs.push(resolve(layer.config.srcDir, "utils")); for (const dir of layer.config.imports?.dirs ?? []) { if (!dir) { continue; } composablesDirs.push(resolve(layer.config.srcDir, dir)); } } await nuxt.callHook("imports:dirs", composablesDirs); composablesDirs = composablesDirs.map((dir) => normalize(dir)); nuxt.hook("builder:watch", (event, relativePath) => { if (!["addDir", "unlinkDir"].includes(event)) { return; } const path = resolve(nuxt.options.srcDir, relativePath); if (composablesDirs.includes(path)) { logger.info(`Directory \`${relativePath}/\` ${event === "addDir" ? "created" : "removed"}`); return nuxt.callHook("restart"); } }); } addTemplate({ filename: "imports.mjs", getContents: async () => toExports(await ctx.getImports()) + '\nif (import.meta.dev) { console.warn("[nuxt] `#imports` should be transformed with real imports. There seems to be something wrong with the imports plugin.") }' }); nuxt.options.alias["#imports"] = join(nuxt.options.buildDir, "imports"); addVitePlugin(() => TransformPlugin.vite({ ctx, options, sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client })); addWebpackPlugin(() => TransformPlugin.webpack({ ctx, options, sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client })); const priorities = nuxt.options._layers.map((layer, i) => [layer.config.srcDir, -i]).sort(([a], [b]) => b.length - a.length); function isImportsTemplate(template) { return [ "/types/imports.d.ts", "/imports.d.ts", "/imports.mjs" ].some((i) => template.filename.endsWith(i)); } const regenerateImports = async () => { await ctx.modifyDynamicImports(async (imports) => { imports.length = 0; if (options.scan) { const scannedImports = await scanDirExports(composablesDirs, { fileFilter: (file) => !isIgnored(file) }); for (const i of scannedImports) { i.priority = i.priority || priorities.find(([dir]) => i.from.startsWith(dir))?.[1]; } imports.push(...scannedImports); } await nuxt.callHook("imports:extend", imports); return imports; }); await updateTemplates({ filter: isImportsTemplate }); }; await regenerateImports(); addDeclarationTemplates(ctx, options); nuxt.hook("builder:watch", async (_, relativePath) => { const path = resolve(nuxt.options.srcDir, relativePath); if (options.scan && composablesDirs.some((dir) => dir === path || path.startsWith(dir + "/"))) { await regenerateImports(); } }); nuxt.hook("app:templatesGenerated", async (_app, templates) => { if (templates.some((t) => !isImportsTemplate(t))) { await regenerateImports(); } }); } }); function addDeclarationTemplates(ctx, options) { const nuxt = useNuxt(); const resolvedImportPathMap = /* @__PURE__ */ new Map(); const r = ({ from }) => resolvedImportPathMap.get(from); const SUPPORTED_EXTENSION_RE = new RegExp(`\\.(${nuxt.options.extensions.map((i) => i.replace(".", "")).join("|")})$`); async function cacheImportPaths(imports) { const importSource = Array.from(new Set(imports.map((i) => i.from))); await Promise.all(importSource.map(async (from) => { if (resolvedImportPathMap.has(from)) { return; } let path = resolveAlias(from); if (!isAbsolute(path)) { path = await tryResolveModule(from, nuxt.options.modulesDir).then(async (r2) => { if (!r2) { return r2; } const { dir, name } = parseNodeModulePath(r2); if (!dir || !name) { return r2; } const subpath = await lookupNodeModuleSubpath(r2); return join(dir, name, subpath || ""); }) ?? path; } if (existsSync(path) && !await isDirectory$1(path)) { path = path.replace(SUPPORTED_EXTENSION_RE, ""); } if (isAbsolute(path)) { path = relative(join(nuxt.options.buildDir, "types"), path); } resolvedImportPathMap.set(from, path); })); } addTypeTemplate({ filename: "imports.d.ts", getContents: async ({ nuxt: nuxt2 }) => toExports(await ctx.getImports(), nuxt2.options.buildDir, true) }); addTypeTemplate({ filename: "types/imports.d.ts", getContents: async () => { const imports = await ctx.getImports(); await cacheImportPaths(imports); 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."); } }); } const version = "3.13.0"; const nuxtImportProtections = (nuxt, options = {}) => { const patterns = []; patterns.push([ /^(nuxt|nuxt3|nuxt-nightly)$/, "`nuxt`, `nuxt3` or `nuxt-nightly` cannot be imported directly." + (options.isNitro ? "" : " Instead, import runtime Nuxt composables from `#app` or `#imports`.") ]); patterns.push([ /^((~|~~|@|@@)?\/)?nuxt\.config(\.|$)/, "Importing directly from a `nuxt.config` file is not allowed. Instead, use runtime config or a module." ]); patterns.push([/(^|node_modules\/)@vue\/composition-api/]); for (const mod of nuxt.options.modules.filter((m) => typeof m === "string")) { patterns.push([ new RegExp(`^${escapeRE(mod)}$`), "Importing directly from module entry-points is not allowed." ]); } for (const i of [/(^|node_modules\/)@nuxt\/(kit|test-utils)/, /(^|node_modules\/)nuxi/, /(^|node_modules\/)nuxt\/(config|kit|schema)/, "nitropack"]) { patterns.push([i, "This module cannot be imported" + (options.isNitro ? " in server runtime." : " in the Vue part of your app.")]); } if (options.isNitro) { for (const i of ["#app", /^#build(\/|$)/]) { patterns.push([i, "Vue app aliases are not allowed in server runtime."]); } } if (!options.isNitro) { patterns.push([ new RegExp(escapeRE(relative(nuxt.options.srcDir, resolve(nuxt.options.srcDir, nuxt.options.serverDir || "server"))) + "\\/(api|routes|middleware|plugins)\\/"), "Importing from server is not allowed in the Vue part of your app." ]); } return patterns; }; const ImportProtectionPlugin = createUnplugin(function(options) { const cache = {}; const importersToExclude = options?.exclude || []; const proxy = resolvePath("unenv/runtime/mock/proxy", { url: options.modulesDir }); return { name: "nuxt:import-protection", enforce: "pre", resolveId(id, importer) { if (!importer) { return; } if (id[0] === ".") { id = join(importer, "..", id); } if (isAbsolute(id)) { id = relative(options.rootDir, id); } if (importersToExclude.some((p) => typeof p === "string" ? importer === p : p.test(importer))) { return; } const invalidImports = options.patterns.filter(([pattern]) => pattern instanceof RegExp ? pattern.test(id) : pattern === id); let matched = false; for (const match of invalidImports) { cache[id] = cache[id] || /* @__PURE__ */ new Map(); const [pattern, warning] = match; if (cache[id].has(pattern)) { continue; } const relativeImporter = isAbsolute(importer) ? relative(options.rootDir, importer) : importer; logger.error(warning || "Invalid import", `[importing \`${id}\` from \`${relativeImporter}\`]`); cache[id].set(pattern, true); matched = true; } if (matched) { return proxy; } return null; } }; }); const TRANSFORM_MARKER = "/* _processed_nuxt_unctx_transform */\n"; const UnctxTransformPlugin = createUnplugin((options) => { const transformer = createTransformer(options.transformerOptions); return { name: "unctx:transform", enforce: "post", transformInclude(id) { return isVue(id, { type: ["template", "script"] }) || isJS(id); }, transform(code) { if (code.startsWith(TRANSFORM_MARKER) || !transformer.shouldTransform(code)) { return; } const result = transformer.transform(code); if (result) { return { code: TRANSFORM_MARKER + result.code, map: options.sourcemap ? result.magicString.generateMap({ hires: true }) : void 0 }; } } }; }); const TreeShakeComposablesPlugin = createUnplugin((options) => { const composableNames = Object.values(options.composables).flat(); const regexp = `(^\\s*)(${composableNames.join("|")})(?=\\((?!\\) \\{))`; const COMPOSABLE_RE = new RegExp(regexp, "m"); const COMPOSABLE_RE_GLOBAL = new RegExp(regexp, "gm"); return { name: "nuxt:tree-shake-composables:transform", enforce: "post", transformInclude(id) { return isVue(id, { type: ["script"] }) || isJS(id); }, transform(code) { if (!COMPOSABLE_RE.test(code)) { return; } const s = new MagicString(code); const strippedCode = stripLiteral(code); for (const match of strippedCode.matchAll(COMPOSABLE_RE_GLOBAL)) { s.overwrite(match.index, match.index + match[0].length, `${match[1]} false && /*@__PURE__*/ ${match[2]}`); } if (s.hasChanged()) { return { code: s.toString(), map: options.sourcemap ? s.generateMap({ hires: true }) : void 0 }; } } }; }); const DEVONLY_COMP_SINGLE_RE = /<(?:dev-only|DevOnly|lazy-dev-only|LazyDevOnly)>[\s\S]*?<\/(?:dev-only|DevOnly|lazy-dev-only|LazyDevOnly)>/; const DEVONLY_COMP_RE = /<(?:dev-only|DevOnly|lazy-dev-only|LazyDevOnly)>[\s\S]*?<\/(?:dev-only|DevOnly|lazy-dev-only|LazyDevOnly)>/g; const DevOnlyPlugin = createUnplugin((options) => { return { name: "nuxt:server-devonly:transform", enforce: "pre", transformInclude(id) { return isVue(id, { type: ["template"] }); }, transform(code) { if (!DEVONLY_COMP_SINGLE_RE.test(code)) { return; } const s = new MagicString(code); for (const match of code.matchAll(DEVONLY_COMP_RE)) { const ast = parse$1(match[0]).children[0]; const fallback = ast.children?.find((n) => n.name === "template" && Object.values(n.attributes).includes("#fallback")); const replacement = fallback ? match[0].slice(fallback.loc[0].end, fallback.loc[fallback.loc.length - 1].start) : ""; s.overwrite(match.index, match.index + match[0].length, replacement); } if (s.hasChanged()) { return { code: s.toString(), map: options.sourcemap ? s.generateMap({ hires: true }) : void 0 }; } } }; }); const ALIAS_RE = /(?<=['"])[~@]{1,2}(?=\/)/g; const ALIAS_RE_SINGLE = /(?<=['"])[~@]{1,2}(?=\/)/; const LayerAliasingPlugin = createUnplugin((options) => { const aliases = {}; for (const layer of options.layers) { const srcDir = layer.config.srcDir || layer.cwd; const rootDir = layer.config.rootDir || layer.cwd; aliases[srcDir] = { "~": layer.config?.alias?.["~"] || srcDir, "@": layer.config?.alias?.["@"] || srcDir, "~~": layer.config?.alias?.["~~"] || rootDir, "@@": layer.config?.alias?.["@@"] || rootDir }; } const layers = Object.keys(aliases).sort((a, b) => b.length - a.length); return { name: "nuxt:layer-aliasing", enforce: "pre", vite: { resolveId: { order: "pre", async handler(id, importer) { if (!importer) { return; } const layer = layers.find((l) => importer.startsWith(l)); if (!layer) { return; } const resolvedId = resolveAlias(id, aliases[layer]); if (resolvedId !== id) { return await this.resolve(resolvedId, importer, { skipSelf: true }); } } } }, // webpack-only transform transformInclude: (id) => { if (!options.transform) { return false; } const _id = normalize(id); return layers.some((dir) => _id.startsWith(dir)); }, transform(code, id) { if (!options.transform) { return; } const _id = normalize(id); const layer = layers.find((l) => _id.startsWith(l)); if (!layer || !ALIAS_RE_SINGLE.test(code)) { return; } const s = new MagicString(code); s.replace(ALIAS_RE, (r) => aliases[layer][r] || r); if (s.hasChanged()) { return { code: s.toString(), map: options.sourcemap ? s.generateMap({ hires: true }) : void 0 }; } } }; }); const addModuleTranspiles = (opts = {}) => { const nuxt = useNuxt(); const modules = [ ...opts.additionalModules || [], ...nuxt.options.modules, ...nuxt.options._modules ].map((m) => typeof m === "string" ? m : Array.isArray(m) ? m[0] : m.src).filter((m) => typeof m === "string").map(normalizeModuleTranspilePath); nuxt.options.build.transpile = nuxt.options.build.transpile.map((m) => typeof m === "string" ? m.split("node_modules/").pop() : m).filter((x) => !!x); function isTranspilePresent(mod) { return nuxt.options.build.transpile.some((t) => !(t instanceof Function) && (t instanceof RegExp ? t.test(mod) : new RegExp(t).test(mod))); } for (const module of modules) { if (!isTranspilePresent(module)) { nuxt.options.build.transpile.push(module); } } }; const template = () => { return '<svg class="nuxt-spa-loading" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 37 25" fill="none" width="80"><path d="M24.236 22.006h10.742L25.563 5.822l-8.979 14.31a4 4 0 0 1-3.388 1.874H2.978l11.631-20 5.897 10.567"/></svg><style>.nuxt-spa-loading {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n }\n\n .nuxt-spa-loading>path {\n fill: none;\n stroke: #00DC82;\n stroke-width: 4px;\n stroke-linecap: round;\n stroke-linejoin: round;\n /* Stroke-dasharray property */\n stroke-dasharray: 128;\n stroke-dashoffset: 128;\n animation: nuxt-spa-loading-move 3s linear infinite;\n }\n\n @keyframes nuxt-spa-loading-move {\n 100% {\n stroke-dashoffset: -128;\n }\n }</style>'; }; const logLevelMapReverse = { silent: 0, info: 3, verbose: 3 }; async function initNitro(nuxt) { var _a, _b; const excludePaths = nuxt.options._layers.flatMap((l) => [ l.cwd.match(/(?<=\/)node_modules\/(.+)$/)?.[1], l.cwd.match(/\.pnpm\/.+\/node_modules\/(.+)$/)?.[1] ]).filter((dir) => Boolean(dir)).map((dir) => escapeRE(dir)); const excludePattern = excludePaths.length ? [new RegExp(`node_modules\\/(?!${excludePaths.join("|")})`)] : [/node_modules/]; const rootDirWithSlash = withTrailingSlash(nuxt.options.rootDir); const modules = await resolveNuxtModule( rootDirWithSlash, nuxt.options._installedModules.filter((m) => m.entryPath).map((m) => m.entryPath) ); const nitroConfig = defu(nuxt.options.nitro, { debug: nuxt.options.debug, rootDir: nuxt.options.rootDir, workspaceDir: nuxt.options.workspaceDir, srcDir: nuxt.options.serverDir, dev: nuxt.options.dev, buildDir: nuxt.options.buildDir, experimental: { asyncContext: nuxt.options.experimental.asyncContext, typescriptBundlerResolution: nuxt.options.future.typescriptBundlerResolution || nuxt.options.typescript?.tsConfig?.compilerOptions?.moduleResolution?.toLowerCase() === "bundler" || nuxt.options.nitro.typescript?.tsConfig?.compilerOptions?.moduleResolution?.toLowerCase() === "bundler" }, framework: { name: "nuxt", version: version }, imports: { autoImport: nuxt.options.imports.autoImport, imports: [ { as: "__buildAssetsURL", name: "buildAssetsURL", from: resolve(distDir, "core/runtime/nitro/paths") }, { as: "__publicAssetsURL", name: "publicAssetsURL", from: resolve(distDir, "core/runtime/nitro/paths") }, { // TODO: Remove after https://github.com/unjs/nitro/issues/1049 as: "defineAppConfig", name: "defineAppConfig", from: resolve(distDir, "core/runtime/nitro/config"), priority: -1 } ], exclude: [...excludePattern, /[\\/]\.git[\\/]/] }, esbuild: { options: { exclude: excludePattern } }, analyze: !nuxt.options.test && nuxt.options.build.analyze && (nuxt.options.build.analyze === true || nuxt.options.build.analyze.enabled) ? { template: "treemap", projectRoot: nuxt.options.rootDir, filename: join(nuxt.options.analyzeDir, "{name}.html") } : false, scanDirs: nuxt.options._layers.map((layer) => (layer.config.serverDir || layer.config.srcDir) && resolve(layer.cwd, layer.config.serverDir || resolve(layer.config.srcDir, "server"))).filter(Boolean), renderer: resolve(distDir, "core/runtime/nitro/renderer"), errorHandler: resolve(distDir, "core/runtime/nitro/error"), nodeModulesDirs: nuxt.options.modulesDir, handlers: nuxt.options.serverHandlers, devHandlers: [], baseURL: nuxt.options.app.baseURL, virtual: { "#internal/nuxt.config.mjs": () => nuxt.vfs["#build/nuxt.config"], "#spa-template": async () => `export const template = ${JSON.stringify(await spaLoadingTemplate(nuxt))}` }, routeRules: { "/__nuxt_error": { cache: false } }, appConfig: nuxt.options.appConfig, appConfigFiles: nuxt.options._layers.map( (layer) => resolve(layer.config.srcDir, "app.config") ), typescript: { strict: true, generateTsConfig: true, tsconfigPath: "tsconfig.server.json", tsConfig: { compilerOptions: { lib: ["esnext", "webworker", "dom.iterable"] }, include: [ join(nuxt.options.buildDir, "types/nitro-nuxt.d.ts"), ...modules.map((m) => join(relativeWithDot(nuxt.options.buildDir, m), "runtime/server")) ], exclude: [ ...nuxt.options.modulesDir.map((m) => relativeWithDot(nuxt.options.buildDir, m)), // nitro generate output: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/nitro.ts#L186 relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, "dist")) ] } }, publicAssets: [ nuxt.options.dev ? { dir: resolve(nuxt.options.buildDir, "dist/client") } : { dir: join(nuxt.options.buildDir, "dist/client", nuxt.options.app.buildAssetsDir), maxAge: 31536e3, baseURL: nuxt.options.app.buildAssetsDir }, ...nuxt.options._layers.map((layer) => resolve(layer.config.srcDir, (layer.config.rootDir === nuxt.options.rootDir ? nuxt.options : layer.config).dir?.public || "public")).filter((dir) => existsSync(dir)).map((dir) => ({ dir })) ], prerender: { failOnError: true, concurrency: cpus().length * 4 || 4, routes: [].concat(nuxt.options.generate.routes) }, sourceMap: nuxt.options.sourcemap.server, externals: { inline: [ ...nuxt.options.dev ? [] : [ ...nuxt.options.experimental.externalVue ? [] : ["vue", "@vue/"], "@nuxt/", nuxt.options.buildDir ], ...nuxt.options.build.transpile.filter((i) => typeof i === "string"), "nuxt/dist", "nuxt3/dist", "nuxt-nightly/dist", distDir, // Ensure app config files have auto-imports injected even if they are pure .js files ...nuxt.options._layers.map((layer) => resolve(layer.config.srcDir, "app.config")) ], traceInclude: [ // force include files used in generated code from the runtime-compiler ...nuxt.options.vue.runtimeCompiler && !nuxt.options.experimental.externalVue ? [ ...nuxt.options.modulesDir.reduce((targets, path) => { const serverRendererPath = resolve(path, "vue/server-renderer/index.js"); if (existsSync(serverRendererPath)) { targets.push(serverRendererPath); } return targets; }, []) ] : [] ] }, alias: { // Vue 3 mocks ...nuxt.options.vue.runtimeCompiler || nuxt.options.experimental.externalVue ? {} : { "estree-walker": "unenv/runtime/mock/proxy", "@babel/parser": "unenv/runtime/mock/proxy", "@vue/compiler-core": "unenv/runtime/mock/proxy", "@vue/compiler-dom": "unenv/runtime/mock/proxy", "@vue/compiler-ssr": "unenv/runtime/mock/proxy" }, "@vue/devtools-api": "vue-devtools-stub", // Paths "#internal/nuxt/paths": resolve(distDir, "core/runtime/nitro/paths"), // Nuxt aliases ...nuxt.options.alias }, replace: { "process.env.NUXT_NO_SSR": nuxt.options.ssr === false, "process.env.NUXT_EARLY_HINTS": nuxt.options.experimental.writeEarlyHints !== false, "process.env.NUXT_NO_SCRIPTS": !!nuxt.options.features.noScripts && !nuxt.options.dev, "process.env.NUXT_INLINE_STYLES": !!nuxt.options.features.inlineStyles, "process.env.NUXT_JSON_PAYLOADS": !!nuxt.options.experimental.renderJsonPayloads, "process.env.NUXT_ASYNC_CONTEXT": !!nuxt.options.experimental.asyncContext, "process.env.NUXT_SHARED_DATA": !!nuxt.options.experimental.sharedPrerenderData, "process.dev": nuxt.options.dev, "__VUE_PROD_DEVTOOLS__": false }, rollupConfig: { output: {}, plugins: [] }, logLevel: logLevelMapReverse[nuxt.options.logLevel] }); nitroConfig.srcDir = resolve(nuxt.options.rootDir, nuxt.options.srcDir, nitroConfig.srcDir); nitroConfig.ignore = [...nitroConfig.ignore || [], ...resolveIgnorePatterns(nitroConfig.srcDir), `!${join(nuxt.options.buildDir, "dist/client", nuxt.options.app.buildAssetsDir, "**/*")}`]; nitroConfig.plugins = nitroConfig.plugins?.map((plugin) => plugin ? resolveAlias(plugin, nuxt.options.alias) : plugin); if (nuxt.options.experimental.appManifest) { const buildId = (_a = nuxt.options.runtimeConfig.app).buildId || (_a.buildId = nuxt.options.buildId); const buildTimestamp = Date.now(); const manifestPrefix = joinURL(nuxt.options.app.buildAssetsDir, "builds"); const tempDir = join(nuxt.options.buildDir, "manifest"); nitroConfig.prerender || (nitroConfig.prerender = {}); (_b = nitroConfig.prerender).ignore || (_b.ignore = []); nitroConfig.prerender.ignore.push(manifestPrefix); nitroConfig.publicAssets.unshift( // build manifest { dir: join(tempDir, "meta"), maxAge: 31536e3, baseURL: joinURL(manifestPrefix, "meta") }, // latest build { dir: tempDir, maxAge: 1, baseURL: manifestPrefix } ); nuxt.options.alias["#app-manifest"] = join(tempDir, `meta/${buildId}.json`); nuxt.hook("nitro:config", (config) => { const rules = config.routeRules; for (const rule in rules) { if (!rules[rule].appMiddleware) { continue; } const value = rules[rule].appMiddleware; if (typeof value === "string") { rules[rule].appMiddleware = { [value]: true }; } else if (Array.isArray(value)) { const normalizedRules = {}; for (const middleware of value) { normalizedRules[middleware] = true; } rules[rule].appMiddleware = normalizedRules; } } }); nuxt.hook("nitro:init", (nitro2) => { nitro2.hooks.hook("rollup:before", async (nitro3) => { const routeRules = {}; const _routeRules = nitro3.options.routeRules; for (const key in _routeRules) { if (key === "/__nuxt_error") { continue; } let hasRules = false; const filteredRules = {}; for (const routeKey in _routeRules[key]) { const value = _routeRules[key][routeKey]; if (["prerender", "redirect", "appMiddleware"].includes(routeKey) && value) { if (routeKey === "redirect") { filteredRules[routeKey] = typeof value === "string" ? value : value.to; } else { filteredRules[routeKey] = value; } hasRules = true; } } if (hasRules) { routeRules[key] = filteredRules; } } const prerenderedRoutes = /* @__PURE__ */ new Set(); const routeRulesMatcher = toRouteMatcher( createRouter({ routes: routeRules }) ); if (nitro3._prerenderedRoutes?.length) { const payloadSuffix = nuxt.options.experimental.renderJsonPayloads ? "/_payload.json" : "/_payload.js"; for (const route of nitro3._prerenderedRoutes) { if (!route.error && route.route.endsWith(payloadSuffix)) { const url = route.route.slice(0, -payloadSuffix.length) || "/"; const rules = defu({}, ...routeRulesMatcher.matchAll(url).reverse()); if (!rules.prerender) { prerenderedRoutes.add(url); } } } } const manifest = { id: buildId, timestamp: buildTimestamp, matcher: exportMatcher(routeRulesMatcher), prerendered: nuxt.options.dev ? [] : [...prerenderedRoutes] }; await promises.mkdir(join(tempDir, "meta"), { recursive: true }); await promises.writeFile(join(tempDir, "latest.json"), JSON.stringify({ id: buildId, timestamp: buildTimestamp })); await promises.writeFile(join(tempDir, `meta/${buildId}.json`), JSON.stringify(manifest)); }); }); } if (!nuxt.options.ssr) { nitroConfig.virtual["#build/dist/server/server.mjs"] = "export default () => {}"; if (process.platform === "win32") { nitroConfig.virtual["#build/dist/server/server.mjs".replace(/\//g, "\\")] = "export default () => {}"; } } if (nuxt.options.builder === "@nuxt/webpack-builder" || nuxt.options.dev) { nitroConfig.virtual["#build/dist/server/styles.mjs"] = "export default {}"; if (process.platform === "win32") { nitroConfig.virtual["#build/dist/server/styles.mjs".replace(/\//g, "\\")] = "export default {}"; } } if (nuxt.options.experimental.respectNoSSRHeader) { nitroConfig.handlers = nitroConfig.handlers || []; nitroConfig.handlers.push({ handler: resolve(distDir, "core/runtime/nitro/no-ssr"), middleware: true }); } nitroConfig.rollupConfig.plugins = await nitroConfig.rollupConfig.plugins || []; nitroConfig.rollupConfig.plugins = toArray(nitroConfig.rollupConfig.plugins); nitroConfig.rollupConfig.plugins.push( ImportProtectionPlugin.rollup({ rootDir: nuxt.options.rootDir, modulesDir: nuxt.options.modulesDir, patterns: nuxtImportProtections(nuxt, { isNitro: true }), exclude: [/core[\\/]runtime[\\/]nitro[\\/]renderer/] }) ); await nuxt.callHook("nitro:config", nitroConfig); const excludedAlias = [/^@vue\/.*$/, "#imports", "vue-demi", /^#app/]; const basePath = nitroConfig.typescript.tsConfig.compilerOptions?.baseUrl ? resolve(nuxt.options.buildDir, nitroConfig.typescript.tsConfig.compilerOptions?.baseUrl) : nuxt.options.buildDir; const aliases = nitroConfig.alias; const tsConfig = nitroConfig.typescript.tsConfig; tsConfig.compilerOptions = tsConfig.compilerOptions || {}; tsConfig.compilerOptions.paths = tsConfig.compilerOptions.paths || {}; for (const _alias in aliases) { const alias = _alias; if (excludedAlias.some((pattern) => typeof pattern === "string" ? alias === pattern : pattern.test(alias))) { continue; } if (alias in tsConfig.compilerOptions.paths) { continue; } const absolutePath = resolve(basePath, aliases[alias]); const stats = await promises.stat(absolutePath).catch( () => null /* file does not exist */ ); if (stats?.isDirectory()) { tsConfig.compilerOptions.paths[alias] = [absolutePath]; tsConfig.compilerOptions.paths[`${alias}/*`] = [`${absolutePath}/*`]; } else { tsConfig.compilerOptions.paths[alias] = [absolutePath.replace(/\b\.\w+$/g, "")]; } } const nitro = await createNitro(nitroConfig, { // @ts-expect-error this will be valid in a future version of Nitro compatibilityDate: nuxt.options.compatibilityDate }); const spaLoadingTemplateFilePath = await spaLoadingTemplatePath(nuxt); nuxt.hook("builder:watch", async (_event, relativePath) => { const path = resolve(nuxt.options.srcDir, relativePath); if (path === spaLoadingTemplateFilePath) { await nitro.hooks.callHook("rollup:reload"); } }); const cacheDir = resolve(nuxt.options.buildDir, "cache/nitro/prerender"); const cacheDriverPath = await resolvePath$1(join(distDir, "core/runtime/nitro/cache-driver")); await promises.rm(cacheDir, { recursive: true, force: true }).catch(() => { }); nitro.options._config.storage = defu(nitro.options._config.storage, { "internal:nuxt:prerender": { // TODO: resolve upstream where file URLs are not being resolved/inlined correctly driver: isWindows ? pathToFileURL(cacheDriverPath).href : cacheDriverPath, base: cacheDir } }); nuxt._nitro = nitro; await nuxt.callHook("nitro:init", nitro); nitro.vfs = nuxt.vfs = nitro.vfs || nuxt.vfs || {}; nuxt.hook("close", () => nitro.hooks.callHook("close")); nitro.hooks.hook("prerender:routes", (routes) => { return nuxt.callHook("prerender:routes", { routes }); }); if (nuxt.options.vue.runtimeCompiler) { nuxt.hook("vite:extendConfig", (config, { isClient }) => { if (isClient) { if (Array.isArray(config.resolve.alias)) { config.resolve.alias.push({ find: "vue", replacement: "vue/dist/vue.esm-bundler" }); } else { config.resolve.alias = { ...config.resolve.alias, vue: "vue/dist/vue.esm-bundler" }; } } }); nuxt.hook("webpack:config", (configuration) => { const clientConfig = configuration.find((config) => config.name === "client"); if (!clientConfig.resolve) { clientConfig.resolve.alias = {}; } if (Array.isArray(clientConfig.resolve.alias)) { clientConfig.resolve.alias.push({ name: "vue", alias: "vue/dist/vue.esm-bundler" }); } else { clientConfig.resolve.alias.vue = "vue/dist/vue.esm-bundler"; } }); } const devMiddlewareHandler = dynamicEventHandler(); nitro.options.devHandlers.unshift({ handler: devMiddlewareHandler }); nitro.options.devHandlers.push(...nuxt.options.devServerHandlers); nitro.options.handlers.unshift({ route: "/__nuxt_error", lazy: true, handler: resolve(distDir, "core/runtime/nitro/renderer") }); if (!nuxt.options.dev && nuxt.options.experimental.noVueServer) { nitro.hooks.hook("rollup:before", (nitro2) => { if (nitro2.options.preset === "nitro-prerender") { return; } const nuxtErrorHandler = nitro2.options.handlers.findIndex((h) => h.route === "/__nuxt_error"); if (nuxtErrorHandler >= 0) { nitro2.options.handlers.splice(nuxtErrorHandler, 1); } nitro2.options.renderer = void 0; nitro2.options.errorHandler = "#internal/nitro/error"; }); } nuxt.hook("prepare:types", async (opts) => { if (!nuxt.options.dev) { await scanHandlers(nitro); await writeTypes(nitro); } opts.tsConfig.exclude = opts.tsConfig.exclude || []; opts.tsConfig.exclude.push(relative(nuxt.options.buildDir, resolve(nuxt.options.rootDir, nitro.options.output.dir))); opts.references.push({ path: resolve(nuxt.options.buildDir, "types/nitro.d.ts") }); }); if (nitro.options.static) { nitro.hooks.hook("prerender:routes", (routes) => { for (const route of ["/200.html", "/404.html"]) { routes.add(route); } if (!nuxt.options.ssr) { routes.add("/index.html"); } }); } if (!nuxt.options.dev) { nitro.hooks.hook("rollup:before", async (nitro2) => { await copyPublicAssets(nitro2); await nuxt.callHook("nitro:build:public-assets", nitro2); }); } nuxt.hook("build:done", async () => { await nuxt.callHook("nitro:build:before", nitro); if (nuxt.options.dev) { await build$1(nitro); } else { await prepare(nitro); await prerender(nitro); logger.restoreAll(); await build$1(nitro); logger.wrapAll(); if (nitro.options.static) { const distDir2 = resolve(nuxt.options.rootDir, "dist"); if (!existsSync(distDir2)) { await promises.symlink(nitro.options.output.publicDir, distDir2, "junction").catch(() => { }); } } } }); if (nuxt.options.dev) { nuxt.hook("webpack:compiled", () => { nuxt.server.reload(); }); nuxt.hook("vite:compiled", () => { nuxt.server.reload(); }); nuxt.hook("server:devHandler", (h) => { devMiddlewareHandler.set(h); }); nuxt.server = createDevServer(nitro); const waitUntilCompile = new Promise((resolve2) => nitro.hooks.hook("compiled", () => resolve2())); nuxt.hook("build:done", () => waitUntilCompile); } } function relativeWithDot(from, to) { return relative(from, to).replace(/^([^.])/, "./$1") || "."; } async function spaLoadingTemplatePath(nuxt) { if (typeof nuxt.options.spaLoadingTemplate === "string") { return resolve(nuxt.options.srcDir, nuxt.options.spaLoadingTemplate); } const possiblePaths = nuxt.options._layers.map((layer) => resolve(layer.config.srcDir, layer.config.dir?.app || "app", "spa-loading-template.html")); return await findPath(possiblePaths) ?? resolve(nuxt.options.srcDir, nuxt.options.dir?.app || "app", "spa-loading-template.html"); } async function spaLoadingTemplate(nuxt) { if (nuxt.options.spaLoadingTemplate === false) { return ""; } const spaLoadingTemplate2 = await spaLoadingTemplatePath(nuxt); try { if (existsSync(spaLoadingTemplate2)) { return readFileSync(spaLoadingTemplate2, "utf-8"); } } catch { } if (nuxt.options.spaLoadingTemplate === true) { return template(); } if (nuxt.options.spaLoadingTemplate) { logger.warn(`Could not load custom \`spaLoadingTemplate\` path as it does not exist: \`${nuxt.options.spaLoadingTemplate}\`.`); } return ""; } const schemaModule = defineNuxtModule({ meta: { name: "nuxt-config-schema" }, async setup(_, nuxt) { if (!nuxt.options.experimental.configSchema) { return; } const resolver = createResolver(import.meta.url); const _resolveSchema = jiti(dirname(fileURLToPath(import.meta.url)), { esmResolve: true, interopDefault: true, cache: false, requireCache: false, transformOptions: { babel: { plugins: [untypedPlugin] } } }); nuxt.hook("prepare:types", async (ctx) => { ctx.references.push({ path: "schema/nuxt.schema.d.ts" }); if (nuxt.options._prepare) { await writeSchema(schema); } }); let schema; nuxt.hook("modules:done", async () => { schema = await resolveSchema$1(); }); nuxt.hooks.hook("build:done", () => writeSchema(schema)); if (nuxt.options.dev) { const onChange = debounce(async () => { schema = await resolveSchema$1(); await writeSchema(schema); }); if (nuxt.options.experimental.watcher === "parcel") { const watcherPath = await tryResolveModule("@parcel/watcher", [nuxt.options.rootDir, ...nuxt.options.modulesDir]); if (watcherPath) { const { subscribe } = await import(pathToFileURL(watcherPath).href).then(interopDefault); for (const layer of nuxt.options._layers) { const subscription = await subscribe(layer.config.rootDir, onChange, { ignore: ["!nuxt.schema.*"] }); nuxt.hook("close", () => subscription.unsubscribe()); } return; } logger.warn("Falling back to `chokidar` as `@parcel/watcher` cannot be resolved in your project."); } const filesToWatch = await Promise.all(nuxt.options._layers.map( (layer) => resolver.resolve(layer.config.rootDir, "nuxt.schema.*") )); const watcher = chokidar.watch(filesToWatch, { ...nuxt.options.watchers.chokidar, ignoreInitial: true }); watcher.on("all", onChange); nuxt.hook("close", () => watcher.close()); } async function resolveSchema$1() { globalThis.defineNuxtSchema = (val) => val; const schemaDefs = [nuxt.options.$schema]; for (const layer of nuxt.options._layers) { const filePath = await resolver.resolvePath(resolve(layer.config.rootDir, "nuxt.schema")); if (filePath && existsSync(filePath)) { let loadedConfig; try { loadedConfig = await _resolveSchema.import(filePath, {}); } catch (err) { logger.warn( "Unable to load schema from", filePath, err ); continue; } schemaDefs.push(loadedConfig); } } await nuxt.hooks.callHook("schema:extend", schemaDefs); const schemas = await Promise.all( schemaDefs.map((schemaDef) => resolveSchema(schemaDef)) ); const schema2 = defu(...schemas); await nuxt.hooks.callHook("schema:resolved", schema2); return schema2; } async function writeSchema(schema2) { await nuxt.hooks.callHook("schema:beforeWrite", schema2); await mkdir(resolve(nuxt.options.buildDir, "schema"), { recursive: true }); await writeFile( resolve(nuxt.options.buildDir, "schema/nuxt.schema.json"), JSON.stringify(schema2, null, 2), "utf8" ); const _types = generateTypes(schema2, { addExport: true, interfaceName: "NuxtCustomSchema", partial: true, allowExtraKeys: false }); const types = _types + ` export type CustomAppConfig = Exclude<NuxtCustomSchema['appConfig'], undefined> type _CustomAppConfig = CustomAppConfig declare module '@nuxt/schema' { interface NuxtConfig extends Omit<NuxtCustomSchema, 'appConfig'> {} interface NuxtOptions extends Omit<NuxtCustomSchema, 'appConfig'> {} interface CustomAppConfig extends _CustomAppConfig {} } declare module 'nuxt/schema' { interface NuxtConfig extends Omit<NuxtCustomSchema, 'appConfig'> {} interface NuxtOptions extends Omit<NuxtCustomSchema, 'appConfig'> {} interface CustomAppConfig extends _CustomAppConfig {} } `; const typesPath = resolve( nuxt.options.buildDir, "schema/nuxt.schema.d.ts" ); await writeFile(typesPath, types, "utf8"); await nuxt.hooks.callHook("schema:written"); } } }); const internalOrderMap = { // -50: pre-all (nuxt) "nuxt-pre-all": -50, // -40: custom payload revivers (user) "user-revivers": -40, // -30: payload reviving (nuxt) "nuxt-revivers": -30, // -20: pre (user) <-- pre mapped to this "user-pre": -20, // -10: default (nuxt) "nuxt-default": -10, // 0: default (user) <-- default behavior "user-default": 0, // +10: post (nuxt) "nuxt-post": 10, // +20: post (user) <-- post mapped to this "user-post": 20, // +30: post-all (nuxt) "nuxt-post-all": 30 }; const orderMap = { pre: internalOrderMap["user-pre"], default: internalOrderMap["user-default"], post: internalOrderMap["user-post"] }; const metaCache = {}; async function extractMetadata(code, loader = "ts") { let meta = {}; if (metaCache[code]) { return metaCache[code]; } const js = await transform(code, { loader }); walk(parse(js.code, { sourceType: "module", ecmaVersion: "latest" }), { enter(_node) { if (_node.type !== "CallExpression" || _node.callee.type !== "Identifier") { return; } const node = _node; const name = "name" in node.callee && node.callee.name; if (name !== "defineNuxtPlugin" && name !== "definePayloadPlugin") { return; } if (name === "definePayloadPlugin") { meta.order = internalOrderMap["user-revivers"]; } const metaArg = node.arguments[1]; if (metaArg) { if (metaArg.type !== "ObjectExpression") { throw new Error("Invalid plugin metadata"); } meta = extractMetaFromObject(metaArg.properties); } const plugin = node.arguments[0]; if (plugin.type === "ObjectExpression") { meta = defu(extractMetaFromObject(plugin.properties), meta); } meta.order = meta.order || orderMap[meta.enforce || "default"] || orderMap.default; delete meta.enforce; } }); metaCache[code] = meta; return meta; } const keys = { name: "name", order: "order", enforce: "enforce", dependsOn: "dependsOn" }; function isMetadataKey(key) { return key in keys; } function extractMetaFromObject(properties) { const meta = {}; for (const property of properties) { if (property.type === "SpreadElement" || !("name" in property.key)) { throw new Error("Invalid plugin metadata"); } const propertyKey = property.key.name; if (!isMetadataKey(propertyKey)) { continue; } if (property.value.type === "Literal") { meta[propertyKey] = property.value.value; } if (property.value.type === "UnaryExpression" && property.value.argument.type === "Literal") { meta[propertyKey] = JSON.parse(property.value.operator + property.value.argument.raw); } if (propertyKey === "dependsOn" && property.value.type === "ArrayExpression") { if (property.value.elements.some((e) => !e || e.type !== "Literal" || typeof e.value !== "string")) { throw new Error("dependsOn must take an array of string literals"); } meta[propertyKey] = property.value.elements.map((e) => e.value); } } return meta; } const RemovePluginMetadataPlugin = (nuxt) => createUnplugin(() => { return { name: "nuxt:remove-plugin-metadata", transform(code, id) { id = normalize(id); const plugin = nuxt.apps.default.plugins.find((p) => p.src === id); if (!plugin) { return; } const s = new MagicString(code); const exports = findExports(code); const defaultExport = exports.find((e) => e.type === "default" || e.name === "default"); if (!defaultExport) { logger.warn(`Plugin \`${plugin.src}\` has no default export and will be ignored at build time. Add \`export default defineNuxtPlugin(() => {})\` to your plugin.`); s.overwrite(0, code.length, "export default () => {}"); return { code: s.toString(), map: nuxt.options.sourcemap.client || nuxt.options.sourcemap.server ? s.generateMap({ hires: true }) : null }; } let wrapped = false; const wrapperNames = /* @__PURE__ */ new Set(["defineNuxtPlugin", "definePayloadPlugin"]); try { walk(this.parse(code, { sourceType: "module", ecmaVersion: "latest" }), { enter(_node) { if (_node.type === "ImportSpecifier" && (_node.imported.name === "defineNuxtPlugin" || _node.imported.name === "definePayloadPlugin")) { wrapperNames.add(_node.local.name); } if (_node.type === "ExportDefaultDeclaration" && (_node.declaration.type === "FunctionDeclaration" || _node.declaration.type === "ArrowFunctionExpression")) { if ("params" in _node.declaration && _node.declaration.params.length > 1) { logger.warn(`Plugin \`${plugin.src}\` is in legacy Nuxt 2 format (context, inject) which is likely to be broken and will be ignored.`); s.overwrite(0, code.length, "export default () => {}"); wrapped = true; return; } } if (_node.type !== "CallExpression" || _node.callee.type !== "Identifier") { return; } const node = _node; const name = "name" in node.callee && node.callee.name; if (!name || !wrapperNames.has(name)) { return; } wrapped = true; if (node.arguments[0].type !== "ObjectExpression") { if ("params" in node.arguments[0] && node.arguments[0].params.length > 1) { logger.warn(`Plugin \`${plugin.src}\` is in legacy Nuxt 2 format (context, inject) which is likely to be broken and will be ignored.`); s.overwrite(0, code.length, "export default () => {}"); return; } } if (!("order" in plugin) && !("name" in plugin)) { return; } for (const [argIndex, _arg] of node.arguments.entries()) { if (_arg.type !== "ObjectExpression") { continue; } const arg = _arg; for (const [propertyIndex, _property] of arg.properties.entries()) { if (_property.type === "SpreadElement" || !("name" in _property.key)) { continue; } const property = _property; const propertyKey = _property.key.name; if (propertyKey === "order" || propertyKey === "enforce" || propertyKey === "name") { const _nextNode = arg.properties[propertyIndex + 1] || node.arguments[argIndex + 1]; const nextNode = _nextNode; const nextIndex = nextNode?.start || arg.end - 1; s.remove(property.start, nextIndex); } } } } }); } catch (e) { logger.error(e); return; } if (!wrapped) { logger.warn(`Plugin \`${plugin.src}\` is not wrapped in \`defineNuxtPlugin\`. It is advised to wrap your plugins as in the future this may enable enhancements.`); } if (s.hasChanged()) { return { code: s.toString(), map: nuxt.options.sourcemap.client || nuxt.options.sourcemap.server ? s.generateMap({ hires: true }) : null }; } } }; }); const AsyncContextInjectionPlugin = (nuxt) => createUnplugin(() => { return { name: "nuxt:vue-async-context", transformInclude(id) { return isVue(id, { type: ["template", "script"] }); }, transform(code) { if (!code.includes("_withAsyncContext")) { return; } const s = new MagicString(code); s.prepend('import { withAsyncContext as _withAsyncContext } from "#app/composables/asyncContext";\n'); s.replace(/withAsyncContext as _withAsyncContext,?/, ""); if (s.hasChanged()) { return { code: s.toString(), map: nuxt.options.sourcemap.client || nuxt.options.sourcemap.server ? s.generateMap({ hires: true }) : void 0 }; } } }; }); function resolveDeepImportsPlugin(nuxt) { const exclude = ["virtual:", "\0virtual:", "/__skip_vite"]; return { name: "nuxt:resolve-bare-imports", enforce: "post", async resolveId(id, importer, options) { if (!importer || isAbsolute(id) || !isAbsolute(importer) && !importer.startsWith("virtual:") || exclude.some((e) => id.startsWith(e))) { return; } id = normalize(id); id = resolveAlias(id, nuxt.options.alias); const { dir } = parseNodeModulePath(importer); return await this.resolve?.(id, dir || pkgDir, { skipSelf: true }) ?? await resolvePath(id, { url: [dir || pkgDir, ...nuxt.options.modulesDir], // TODO: respect nitro runtime conditions conditions: options.ssr ? ["node", "import", "require"] : ["import", "require"] }).catch(() => { logger.debug("Could not resolve id", id, importer); return null; }); } }; } function prehydrateTransformPlugin(nuxt) { return createUnplugin(() => ({ name: "nuxt:prehydrate-transform", transformInclude(id) { return isJS(id) || isVue(id, { type: ["script"] }); }, async transform(code, id) { if (!code.includes("onPrehydrate(")) { return; } const s = new MagicString(code); const promises = []; walk(parse(code, { sourceType: "module", ecmaVersion: "latest", ranges: true }), { enter(_node) { if (_node.type !== "CallExpression" || _node.callee.type !== "Identifier") { return; } const node = _node; const name = "name" in node.callee && node.callee.name; if (name === "onPrehydrate") { if (node.arguments[0].type !== "ArrowFunctionExpression" && node.arguments[0].type !== "FunctionExpression") { return; } const needsAttr = node.arguments[0].params.length > 0; const { start, end } = node.arguments[0]; const p = transform(`forEach(${code.slice(start, end)})`, { loader: "ts", minify: true }); promises.push(p.then(({ code: result }) => { const cleaned = result.slice("forEach".length).replace(/;\s+$/, ""); const args = [JSON.stringify(cleaned)]; if (needsAttr) { args.push(JSON.stringify(hash(result))); } s.overwrite(start, end, args.join(", ")); })); } } }); await Promise.all(promises).catch((e) => { console.error(`[nuxt] Could not transform onPrehydrate in \`${id}\`:`, e); }); if (s.hasChanged()) { return { code: s.toString(), map: nuxt.options.sourcemap.server || nuxt.options.sourcemap.client ? s.generateMap({ hires: true }) : void 0 }; } } })); } function createNuxt(options) { const hooks = createHooks(); const nuxt = { _version: version, options, hooks, callHook: hooks.callHook, addHooks: hooks.addHooks, hook: hooks.hook, ready: () => initNuxt(nuxt), close: () => hooks.callHook("close", nuxt), vfs: {}, apps: {} }; hooks.hookOnce("close", () => { hooks.removeAllHooks(); }); return nuxt; } const fallbackCompatibilityDate = "2024-04-03"; const nightlies = { "nitropack": "nitropack-nightly", "h3": "h3-nightly", "nuxt": "nuxt-nightly", "@nuxt/schema": "@nuxt/schema-nightly", "@nuxt/kit": "@nuxt/kit-nightly" }; const keyDependencies = [ "@nuxt/kit", "@nuxt/schema" ]; let warnedAboutCompatDate = false; async function initNuxt(nuxt) { var _a; for (const config2 of nuxt.options._layers.map((layer) => layer.config).reverse()) { if (config2.hooks) { nuxt.hooks.addHooks(config2.hooks); } } nuxt.options.compatibilityDate = resolveCompatibilityDatesFromEnv(nuxt.options.compatibilityDate); if (!nuxt.options.compatibilityDate.default) { const todaysDate = formatDate(/* @__PURE__ */ new Date()); nuxt.options.compatibilityDate.default = fallbackCompatibilityDate; const shouldShowPrompt = nuxt.options.dev && hasTTY && !isCI; if (!shouldShowPrompt) { console.log(`Using \`${fallbackCompatibilityDate}\` as fallback compatibility date.`); } async function promptAndUpdate() { const result = await consola.prompt(`Do you want to update your ${colorize("cyan", "nuxt.config")} to set ${colorize("cyan", `compatibilityDate: '${todaysDate}'`)}?`, { type: "confirm", default: true }); if (result !== true) { console.log(`Using \`${fallbackCompatibilityDate}\` as fallback compatibility date.`); return; } try { const res = await updateConfig({ configFile: "nuxt.config", cwd: nuxt.options.rootDir, async onCreate({ configFile }) { const shallCreate = await consola.prompt(`Do you want to create ${colorize("cyan", relative(nuxt.options.rootDir, configFile))}?`, { type: "confirm", default: true }); if (shallCreate !== true) { return false; } return _getDefaultNuxtConfig(); }, onUpdate(config2) { config2.compatibilityDate = todaysDate; } }); if (res?.configFile) { nuxt.options.compatibilityDate = resolveCompatibilityDatesFromEnv(todaysDate); consola.success(`Compatibility date set to \`${todaysDate}\` in \`${relative(nuxt.options.rootDir, res.configFile)}\``); return; } } catch (err) { const message = err instanceof Error ? err.message : err; consola.error(`Failed to update config: ${message}`); } console.log(`Using \`${fallbackCompatibilityDate}\` as fallback compatibility date.`); } nuxt.hooks.hookOnce("nitro:init", (nitro2) => { if (warnedAboutCompatDate) { return; } nitro2.hooks.hookOnce("compiled", () => { warnedAboutCompatDate = true; console.info(`Nuxt now supports pinning the behavior of provider and deployment presets with a compatibility date. We recommend you specify a \`compatibilityDate\` in your \`nuxt.config\` file, or set an environment variable, such as \`COMPATIBILITY_DATE=${todaysDate}\`.`); if (shouldShowPrompt) { promptAndUpdate(); } }); }); } const layersDir = withTrailingSlash(resolve(nuxt.options.rootDir, "layers")); nuxt.hook("builder:watch", (event, relativePath) => { const path = resolve(nuxt.options.srcDir, relativePath); if (event === "addDir" || event === "unlinkDir") { if (path.startsWith(layersDir)) { return nuxt.callHook("restart", { hard: true }); } } }); nuxtCtx.set(nuxt); nuxt.hook("close", () => nuxtCtx.unset()); const coreTypePackages = nuxt.options.typescript.hoist || []; const packageJSON = await readPackageJSON(nuxt.options.rootDir).catch(() => ({})); const dependencies = /* @__PURE__ */ new Set([...Object.keys(packageJSON.dependencies || {}), ...Object.keys(packageJSON.devDependencies || {})]); const paths = Object.fromEntries(await Promise.all(coreTypePackages.map(async (pkg) => { const [_pkg = pkg, _subpath] = /^[^@]+\//.test(pkg) ? pkg.split("/") : [pkg]; const subpath = _subpath ? "/" + _subpath : ""; if (dependencies.has(_pkg) && !(_pkg in nightlies)) { return []; } if (_pkg in nightlies) { const nightly = nightlies[_pkg]; const path2 = await resolveTypePath(nightly + subpath, subpath, nuxt.options.modulesDir); if (path2) { return [[pkg, [path2]], [nightly + subpath, [path2]]]; } } const path = await resolveTypePath(_pkg + subpath, subpath, nuxt.options.modulesDir); if (path) { return [[pkg, [path]]]; } return []; })).then((r) => r.flat())); nuxt.options.nitro.typescript = defu$1(nuxt.options.nitro.typescript, { tsConfig: { compilerOptions: { paths: { ...paths } } } }); nuxt.hook("prepare:types", (opts) => { opts.references.push({ types: "nuxt" }); opts.references.push({ path: resolve(nuxt.options.buildDir, "types/app-defaults.d.ts") }); opts.references.push({ path: resolve(nuxt.options.buildDir, "types/plugins.d.ts") }); if (nuxt.options.typescript.shim) { opts.references.push({ path: resolve(nuxt.options.buildDir, "types/vue-shim.d.ts") }); } opts.references.push({ path: resolve(nuxt.options.buildDir, "types/build.d.ts") }); opts.references.push({ path: resolve(nuxt.options.buildDir, "types/schema.d.ts") }); opts.references.push({ path: resolve(nuxt.options.buildDir, "types/app.config.d.ts") }); opts.tsConfig.compilerOptions = defu$1(opts.tsConfig.compilerOptions, { paths: { ...paths } }); for (const layer of nuxt.options._layers) { const declaration = join(layer.cwd, "index.d.ts"); if (existsSync(declaration)) { opts.references.push({ path: declaration }); } } }); if (nuxt.options.scripts) { if (!nuxt.options._modules.some((m) => m === "@nuxt/scripts" || m === "@nuxt/scripts-nightly")) { await import('./chunks/features.mjs').then(({ installNuxtModule }) => installNuxtModule("@nuxt/scripts")); } } addBuildPlugin(RemovePluginMetadataPlugin(nuxt)); const config = { rootDir: nuxt.options.rootDir, // Exclude top-level resolutions by plugins exclude: [join(nuxt.options.srcDir, "index.html")], patterns: nuxtImportProtections(nuxt), modulesDir: nuxt.options.modulesDir }; addVitePlugin(() => ImportProtectionPlugin.vite(config)); addWebpackPlugin(() => ImportProtectionPlugin.webpack(config)); addVitePlugin(() => resolveDeepImportsPlugin(nuxt)); addBuildPlugin(prehydrateTransformPlugin(nuxt)); if (nuxt.options.experimental.localLayerAliases) { addVitePlugin(() => LayerAliasingPlugin.vite({ sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client, dev: nuxt.options.dev, root: nuxt.options.srcDir, // skip top-level layer (user's project) as the aliases will already be correctly resolved layers: nuxt.options._layers.slice(1) })); addWebpackPlugin(() => LayerAliasingPlugin.webpack({ sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client, dev: nuxt.options.dev, root: nuxt.options.srcDir, // skip top-level layer (user's project) as the aliases will already be correctly resolved layers: nuxt.options._layers.slice(1), transform: true })); } nuxt.hook("modules:done", async () => { const options = { sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client, transformerOptions: { ...nuxt.options.optimization.asyncTransforms, helperModule: await tryResolveModule("unctx", nuxt.options.modulesDir) ?? "unctx" } }; addVitePlugin(() => UnctxTransformPlugin.vite(options)); addWebpackPlugin(() => UnctxTransformPlugin.webpack(options)); const serverTreeShakeOptions = { sourcemap: !!nuxt.options.sourcemap.server, composables: nuxt.options.optimization.treeShake.composables.server }; if (Object.keys(serverTreeShakeOptions.composables).length) { addVitePlugin(() => TreeShakeComposablesPlugin.vite(serverTreeShakeOptions), { client: false }); addWebpackPlugin(() => TreeShakeComposablesPlugin.webpack(serverTreeShakeOptions), { client: false }); } const clientTreeShakeOptions = { sourcemap: !!nuxt.options.sourcemap.client, composables: nuxt.options.optimization.treeShake.composables.client }; if (Object.keys(clientTreeShakeOptions.composables).length) { addVitePlugin(() => TreeShakeComposablesPlugin.vite(clientTreeShakeOptions), { server: false }); addWebpackPlugin(() => TreeShakeComposablesPlugin.webpack(clientTreeShakeOptions), { server: false }); } }); if (!nuxt.options.dev) { addVitePlugin(() => DevOnlyPlugin.vite({ sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client })); addWebpackPlugin(() => DevOnlyPlugin.webpack({ sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client })); } if (nuxt.options.dev) { addPlugin(resolve(nuxt.options.appDir, "plugins/check-if-layout-used")); } if (nuxt.options.dev && nuxt.options.features.devLogs) { addPlugin(resolve(nuxt.options.appDir, "plugins/dev-server-logs")); addServerPlugin(resolve(distDir, "core/runtime/nitro/dev-server-logs")); nuxt.options.nitro = defu$1(nuxt.options.nitro, { externals: { inline: [/#internal\/dev-server-logs-options/] }, virtual: { "#internal/dev-server-logs-options": () => `export const rootDir = ${JSON.stringify(nuxt.options.rootDir)};` } }); } if (nuxt.options.experimental.asyncContext) { addBuildPlugin(AsyncContextInjectionPlugin(nuxt)); } if (nuxt.options.features.noScripts && !nuxt.options.dev) { nuxt.hook("build:manifest", async (manifest) => { for (const file in manifest) { if (manifest[file].resourceType === "script") { await rm(resolve(nuxt.options.buildDir, "dist/client", withoutLeadingSlash(nuxt.options.app.buildAssetsDir), manifest[file].file), { force: true }); manifest[file].file = ""; } } }); } nuxt.options.build.transpile.push("nuxt/app"); nuxt.options.build.transpile.push( ...nuxt.options._layers.filter((i) => i.cwd.includes("node_modules")).map((i) => i.cwd) ); nuxt.options.modulesDir.push(...nuxt.options._layers.map((l) => resolve(l.cwd, "node_modules"))); await nuxt.callHook("modules:before"); const modulesToInstall = /* @__PURE__ */ new Map(); const watchedPaths = /* @__PURE__ */ new Set(); const specifiedModules = /* @__PURE__ */ new Set(); for (const _mod of nuxt.options.modules) { const mod = Array.isArray(_mod) ? _mod[0] : _mod; if (typeof mod !== "string") { continue; } const modPath = await resolvePath$1(resolveAlias(mod), { fallbackToOriginal: true }); specifiedModules.add(modPath); } for (const config2 of nuxt.options._layers.map((layer) => layer.config).reverse()) { const modulesDir = (config2.rootDir === nuxt.options.rootDir ? nuxt.options : config2).dir?.modules || "modules"; const layerModules = await resolveFiles(config2.srcDir, [ `${modulesDir}/*{${nuxt.options.extensions.join(",")}}`, `${modulesDir}/*/index{${nuxt.options.extensions.join(",")}}` ]); for (const mod of layerModules) { watchedPaths.add(mod); if (specifiedModules.has(mod)) { continue; } specifiedModules.add(mod); modulesToInstall.set(mod, {}); } } for (const key of ["modules", "_modules"]) { for (const item of nuxt.options[key]) { if (item) { const [key2, options = {}] = Array.isArray(item) ? item : [item]; if (!modulesToInstall.has(key2)) { modulesToInstall.set(key2, options); } } } } addComponent({ name: "NuxtWelcome", priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, "components/welcome") }); addComponent({ name: "NuxtLayout", priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, "components/nuxt-layout") }); addComponent({ name: "NuxtErrorBoundary", priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, "components/nuxt-error-boundary") }); addComponent({ name: "ClientOnly", priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, "components/client-only") }); addComponent({ name: "DevOnly", priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, "components/dev-only") }); addComponent({ name: "ServerPlaceholder", priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, "components/server-placeholder") }); addComponent({ name: "NuxtLink", priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, "components/nuxt-link") }); addComponent({ name: "NuxtLoadingIndicator", priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, "components/nuxt-loading-indicator") }); addComponent({ name: "NuxtRouteAnnouncer", priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, "components/nuxt-route-announcer"), mode: "client" }); if (nuxt.options.experimental.clientFallback) { addComponent({ name: "NuxtClientFallback", _raw: true, priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, "components/client-fallback.client"), mode: "client" }); addComponent({ name: "NuxtClientFallback", _raw: true, priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, "components/client-fallback.server"), mode: "server" }); } for (const name of ["NuxtImg", "NuxtPicture"]) { addComponent({ name, export: name, priority: -1, filePath: resolve(nuxt.options.appDir, "components/nuxt-stubs"), // @ts-expect-error TODO: refactor to nuxi _internal_install: "@nuxt/image" }); } if (nuxt.options.builder === "@nuxt/webpack-builder") { addPlugin(resolve(nuxt.options.appDir, "plugins/preload.server")); } const envMap = { // defaults from `builder` based on package name "@nuxt/vite-builder": "vite/client", "@nuxt/webpack-builder": "webpack/module", // simpler overrides from `typescript.builder` for better DX "vite": "vite/client", "webpack": "webpack/module", // default 'merged' builder environment for module authors "shared": "@nuxt/schema/builder-env" }; nuxt.hook("prepare:types", ({ references }) => { if (nuxt.options.typescript.builder === false) { return; } const overrideEnv = nuxt.options.typescript.builder && envMap[nuxt.options.typescript.builder]; const defaultEnv = typeof nuxt.options.builder === "string" ? envMap[nuxt.options.builder] : false; const types = overrideEnv || defaultEnv; if (types) { references.push({ types }); } }); if (nuxt.options.debug) { addPlugin(resolve(nuxt.options.appDir, "plugins/debug")); } for (const [key, options] of modulesToInstall) { await installModule(key, options); } nuxt._ignore = ignore(nuxt.options.ignoreOptions); nuxt._ignore.add(resolveIgnorePatterns()); await nuxt.callHook("modules:done"); if (nuxt.options.experimental.componentIslands) { addComponent({ name: "NuxtIsland", priority: 10, // built-in that we do not expect the user to override filePath: resolve(nuxt.options.appDir, "components/nuxt-island") }); if (!nuxt.options.ssr && nuxt.options.experimental.componentIslands !== "auto") { nuxt.options.ssr = true; (_a = nuxt.options.nitro).routeRules || (_a.routeRules = {}); nuxt.options.nitro.routeRules["/**"] = defu$1(nuxt.options.nitro.routeRules["/**"], { ssr: false }); } } if (!nuxt.options.dev && nuxt.options.experimental.payloadExtraction) { addPlugin(resolve(nuxt.options.appDir, "plugins/payload.client")); } if (nuxt.options.experimental.crossOriginPrefetch) { addPlugin(resolve(nuxt.options.appDir, "plugins/cross-origin-prefetch.client")); } if (nuxt.options.experimental.emitRouteChunkError === "automatic") { addPlugin(resolve(nuxt.options.appDir, "plugins/chunk-reload.client")); } if (nuxt.options.experimental.restoreState) { addPlugin(resolve(nuxt.options.appDir, "plugins/restore-state.client")); } if (nuxt.options.experimental.viewTransition) { addPlugin(resolve(nuxt.options.appDir, "plugins/view-transitions.client")); } if (nuxt.options.experimental.renderJsonPayloads) { addPlugin(resolve(nuxt.options.appDir, "plugins/revive-payload.client")); addPlugin(resolve(nuxt.options.appDir, "plugins/revive-payload.server")); } if (nuxt.options.experimental.appManifest) { addRouteMiddleware({ name: "manifest-route-rule", path: resolve(nuxt.options.appDir, "middleware/manifest-route-rule"), global: true }); if (nuxt.options.experimental.checkOutdatedBuildInterval !== false) { addPlugin(resolve(nuxt.options.appDir, "plugins/check-outdated-build.client")); } } if (nuxt.options.experimental.navigationRepaint) { addPlugin({ src: resolve(nuxt.options.appDir, "plugins/navigation-repaint.client") }); } nuxt.hooks.hook("builder:watch", (event, relativePath) => { const path = resolve(nuxt.options.srcDir, relativePath); if (watchedPaths.has(path)) { return nuxt.callHook("restart", { hard: true }); } const layerRelativePaths = nuxt.options._layers.map((l) => relative(l.config.srcDir || l.cwd, path)); for (const pattern of nuxt.options.watch) { if (typeof pattern === "string") { if (pattern === path || layerRelativePaths.includes(pattern)) { return nuxt.callHook("restart"); } continue; } if (layerRelativePaths.some((p) => pattern.test(p))) { return nuxt.callHook("restart"); } } if (event === "addDir" && path === resolve(nuxt.options.srcDir, "app")) { logger.info(`\`${path}/\` ${event === "addDir" ? "created" : "removed"}`); return nuxt.callHook("restart", { hard: true }); } const isFileChange = ["add", "unlink"].includes(event); if (isFileChange && RESTART_RE.test(path)) { logger.info(`\`${path}\` ${event === "add" ? "created" : "removed"}`); return nuxt.callHook("restart"); } }); nuxt.options.build.transpile = nuxt.options.build.transpile.map((t) => typeof t === "string" ? normalize(t) : t); addModuleTranspiles(); await initNitro(nuxt); const nitro = useNitro(); if (nitro.options.static && nuxt.options.experimental.payloadExtraction === void 0) { logger.warn("Using experimental payload extraction for full-static output. You can opt-out by setting `experimental.payloadExtraction` to `false`."); nuxt.options.experimental.payloadExtraction = true; } nitro.options.replace["process.env.NUXT_PAYLOAD_EXTRACTION"] = String(!!nuxt.options.experimental.payloadExtraction); nitro.options._config.replace["process.env.NUXT_PAYLOAD_EXTRACTION"] = String(!!nuxt.options.experimental.payloadExtraction); if (!nuxt.options.dev && nuxt.options.experimental.payloadExtraction) { addPlugin(resolve(nuxt.options.appDir, "plugins/payload.client")); } if (!satisfies(nuxt._version, nuxt.options.future.compatibilityVersion + ".x")) { console.info(`Running with compatibility version \`${nuxt.options.future.compatibilityVersion}\``); } await nuxt.callHook("ready", nuxt); } async function loadNuxt(opts) { const options = await loadNuxtConfig(opts); options.appDir = options.alias["#app"] = resolve(distDir, "app"); options._majorVersion = 3; for (const key in options.app.head || {}) { options.app.head[key] = deduplicateArray(options.app.head[key]); } if (options.builder === "@nuxt/vite-builder") { const isDevToolsEnabled = typeof options.devtools === "boolean" ? options.devtools : options.devtools?.enabled !== false; if (isDevToolsEnabled) { if (!options._modules.some((m) => m === "@nuxt/devtools" || m === "@nuxt/devtools-edge")) { options._modules.push("@nuxt/devtools"); } } } if (!options._modules.some((m) => m === "@nuxt/scripts" || m === "@nuxt/scripts-nightly")) { options.imports = defu$1(options.imports, { presets: [scriptsStubsPreset] }); } if (options.builder === "@nuxt/webpack-builder") { if (!await import('./chunks/features.mjs').then((r) => r.ensurePackageInstalled("@nuxt/webpack-builder", { rootDir: options.rootDir, searchPaths: options.modulesDir }))) { logger.warn("Failed to install `@nuxt/webpack-builder`, please install it manually, or change the `builder` option to vite in `nuxt.config`"); } } options._modules.push(pagesModule, metaModule, componentsModule); options._modules.push([importsModule, { transform: { include: options._layers.filter((i) => i.cwd && i.cwd.includes("node_modules")).map((i) => new RegExp(`(^|\\/)${escapeRE(i.cwd.split("node_modules/").pop())}(\\/|$)(?!node_modules\\/)`)) } }]); options._modules.push(schemaModule); options.modulesDir.push(resolve(options.workspaceDir, "node_modules")); options.modulesDir.push(resolve(pkgDir, "node_modules")); options.build.transpile.push( "std-env" // we need to statically replace process.env when used in runtime code ); options.alias["vue-demi"] = resolve(options.appDir, "compat/vue-demi"); options.alias["@vue/composition-api"] = resolve(options.appDir, "compat/capi"); if (options.telemetry !== false && !process.env.NUXT_TELEMETRY_DISABLED) { options._modules.push("@nuxt/telemetry"); } createPortalProperties(options.nitro.runtimeConfig, options, ["nitro.runtimeConfig", "runtimeConfig"]); createPortalProperties(options.nitro.routeRules, options, ["nitro.routeRules", "routeRules"]); const nitroOptions = options.nitro; Object.defineProperties(options, { nitro: { configurable: false, enumerable: true, get: () => nitroOptions, set(value) { Object.assign(nitroOptions, value); } } }); const nuxt = createNuxt(options); for (const dep of keyDependencies) { checkDependencyVersion(dep, nuxt._version); } if (opts.overrides?.hooks) { nuxt.hooks.addHooks(opts.overrides.hooks); } if (nuxt.options.debug) { createDebugger(nuxt.hooks, { tag: "nuxt" }); } if (opts.ready !== false) { await nuxt.ready(); } return nuxt; } async function checkDependencyVersion(name, nuxtVersion) { const path = await resolvePath$1(name, { fallbackToOriginal: true }).catch(() => null); if (!path || path === name) { return; } const { version: version2 } = await readPackageJSON(path); if (version2 && gt(nuxtVersion, version2)) { console.warn(`[nuxt] Expected \`${name}\` to be at least \`${nuxtVersion}\` but got \`${version2}\`. This might lead to unexpected behavior. Check your package.json or refresh your lockfile.`); } } const RESTART_RE = /^(?:app|error|app\.config)\.(?:js|ts|mjs|jsx|tsx|vue)$/i; function deduplicateArray(maybeArray) { if (!Array.isArray(maybeArray)) { return maybeArray; } const fresh = []; const hashes = /* @__PURE__ */ new Set(); for (const item of maybeArray) { const _hash = hash(item); if (!hashes.has(_hash)) { hashes.add(_hash); fresh.push(item); } } return fresh; } function createPortalProperties(sourceValue, options, paths) { let sharedValue = sourceValue; for (const path of paths) { const segments = path.split("."); const key = segments.pop(); let parent = options; while (segments.length) { const key2 = segments.shift(); parent = parent[key2] || (parent[key2] = {}); } delete parent[key]; Object.defineProperties(parent, { [key]: { configurable: false, enumerable: true, get: () => sharedValue, set(value) { sharedValue = value; } } }); } } const _getDefaultNuxtConfig = () => ( /* js */ `// https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ devtools: { enabled: true } }) ` ); const vueShim = { filename: "types/vue-shim.d.ts", getContents: ({ nuxt }) => { if (!nuxt.options.typescript.shim) { return ""; } return [ "declare module '*.vue' {", " import { DefineComponent } from 'vue'", " const component: DefineComponent<{}, {}, any>", " export default component", "}" ].join("\n"); } }; const appComponentTemplate = { filename: "app-component.mjs", getContents: (ctx) => genExport(ctx.app.mainComponent, ["default"]) }; const rootComponentTemplate = { filename: "root-component.mjs", // TODO: fix upstream in vite - this ensures that vite generates a module graph for islands // but should not be necessary (and has a warmup performance cost). See https://github.com/nuxt/nuxt/pull/24584. getContents: (ctx) => (ctx.nuxt.options.dev ? "import '#build/components.islands.mjs';\n" : "") + genExport(ctx.app.rootComponent, ["default"]) }; const errorComponentTemplate = { filename: "error-component.mjs", getContents: (ctx) => genExport(ctx.app.errorComponent, ["default"]) }; const testComponentWrapperTemplate = { filename: "test-component-wrapper.mjs", getContents: (ctx) => genExport(resolve(ctx.nuxt.options.appDir, "components/test-component-wrapper"), ["default"]) }; const cssTemplate = { filename: "css.mjs", getContents: (ctx) => ctx.nuxt.options.css.map((i) => genImport(i)).join("\n") }; const clientPluginTemplate = { filename: "plugins/client.mjs", async getContents(ctx) { const clientPlugins = await annotatePlugins(ctx.nuxt, ctx.app.plugins.filter((p) => !p.mode || p.mode !== "server")); checkForCircularDependencies(clientPlugins); const exports = []; const imports = []; for (const plugin of clientPlugins) { const path = relative(ctx.nuxt.options.rootDir, plugin.src); const variable = genSafeVariableName(filename(plugin.src)).replace(/_(45|46|47)/g, "_") + "_" + hash(path); exports.push(variable); imports.push(genImport(plugin.src, variable)); } return [ ...imports, `export default ${genArrayFromRaw(exports)}` ].join("\n"); } }; const serverPluginTemplate = { filename: "plugins/server.mjs", async getContents(ctx) { const serverPlugins = await annotatePlugins(ctx.nuxt, ctx.app.plugins.filter((p) => !p.mode || p.mode !== "client")); checkForCircularDependencies(serverPlugins); const exports = []; const imports = []; for (const plugin of serverPlugins) { const path = relative(ctx.nuxt.options.rootDir, plugin.src); const variable = genSafeVariableName(filename(path)).replace(/_(45|46|47)/g, "_") + "_" + hash(path); exports.push(variable); imports.push(genImport(plugin.src, variable)); } return [ ...imports, `export default ${genArrayFromRaw(exports)}` ].join("\n"); } }; const appDefaults = { filename: "types/app-defaults.d.ts", getContents: (ctx) => { const isV4 = ctx.nuxt.options.future.compatibilityVersion === 4; return ` declare module '#app/defaults' { type DefaultAsyncDataErrorValue = ${isV4 ? "undefined" : "null"} type DefaultAsyncDataValue = ${isV4 ? "undefined" : "null"} type DefaultErrorValue = ${isV4 ? "undefined" : "null"} type DedupeOption = ${isV4 ? "'cancel' | 'defer'" : "boolean | 'cancel' | 'defer'"} }`; } }; const TS_RE = /\.[cm]?tsx?$/; const pluginsDeclaration = { filename: "types/plugins.d.ts", getContents: async ({ nuxt, app }) => { const EXTENSION_RE = new RegExp(`(?<=\\w)(${nuxt.options.extensions.map((e) => escapeRE(e)).join("|")})$`, "g"); const typesDir = join(nuxt.options.buildDir, "types"); const tsImports = []; const pluginNames = []; function exists(path) { return app.templates.some((t) => t.write && path === t.dst) || existsSync(path); } for (const plugin of await annotatePlugins(nuxt, app.plugins)) { if (plugin.name) { pluginNames.push(`'${plugin.name}'`); } const pluginPath = resolve(typesDir, plugin.src); const relativePath = relative(typesDir, pluginPath); const correspondingDeclaration = pluginPath.replace(/\.(?<letter>[cm])?jsx?$/, ".d.$<letter>ts"); if (correspondingDeclaration !== pluginPath && exists(correspondingDeclaration)) { tsImports.push(relativePath); continue; } if (exists(pluginPath)) { if (TS_RE.test(pluginPath)) { tsImports.push(relativePath.replace(EXTENSION_RE, "")); continue; } tsImports.push(relativePath); } } return `// Generated by Nuxt' import type { Plugin } from '#app' type Decorate<T extends Record<string, any>> = { [K in keyof T as K extends string ? \`$\${K}\` : never]: T[K] } type IsAny<T> = 0 extends 1 & T ? true : false type InjectionType<A extends Plugin> = IsAny<A> extends true ? unknown : A extends Plugin<infer T> ? Decorate<T> : unknown type NuxtAppInjections = ${tsImports.map((p) => `InjectionType<typeof ${genDynamicImport(p, { wrapper: false })}.default>`).join(" &\n ")} declare module '#app' { interface NuxtApp extends NuxtAppInjections { } interface NuxtAppLiterals { pluginName: ${pluginNames.join(" | ")} } } declare module 'vue' { interface ComponentCustomProperties extends NuxtAppInjections { } } export { } `; } }; const adHocModules = ["router", "pages", "imports", "meta", "components", "nuxt-config-schema"]; const schemaTemplate = { filename: "types/schema.d.ts", getContents: async ({ nuxt }) => { const moduleInfo = nuxt.options._installedModules.map((m) => ({ ...m.meta, importName: m.entryPath || m.meta?.name })).filter((m) => m.configKey && m.name && !adHocModules.includes(m.name)); const relativeRoot = relative(resolve(nuxt.options.buildDir, "types"), nuxt.options.rootDir); const getImportName = (name) => (name[0] === "." ? "./" + join(relativeRoot, name) : name).replace(/\.\w+$/, ""); const modules = moduleInfo.map((meta) => [genString(meta.configKey), getImportName(meta.importName), meta]); const privateRuntimeConfig = /* @__PURE__ */ Object.create(null); for (const key in nuxt.options.runtimeConfig) { if (key !== "public") { privateRuntimeConfig[key] = nuxt.options.runtimeConfig[key]; } } const moduleOptionsInterface = [ ...modules.map( ([configKey, importName]) => ` [${configKey}]?: typeof ${genDynamicImport(importName, { wrapper: false })}.default extends NuxtModule<infer O> ? Partial<O> : Record<string, any>` ), modules.length > 0 ? ` modules?: (undefined | null | false | NuxtModule | string | [NuxtModule | string, Record<string, any>] | ${modules.map(([configKey, importName, meta]) => `[${genString(meta?.rawPath || importName)}, Exclude<NuxtConfig[${configKey}], boolean>]`).join(" | ")})[],` : "" ]; return [ "import { NuxtModule, RuntimeConfig } from '@nuxt/schema'", "declare module '@nuxt/schema' {", " interface NuxtConfig {", moduleOptionsInterface, " }", "}", "declare module 'nuxt/schema' {", " interface NuxtConfig {", moduleOptionsInterface, " }", generateTypes( await resolveSchema(privateRuntimeConfig), { interfaceName: "RuntimeConfig", addExport: false, addDefaults: false, allowExtraKeys: false, indentation: 2 } ), generateTypes( await resolveSchema(nuxt.options.runtimeConfig.public), { interfaceName: "PublicRuntimeConfig", addExport: false, addDefaults: false, allowExtraKeys: false, indentation: 2 } ), "}", `declare module 'vue' { interface ComponentCustomProperties { $config: RuntimeConfig } }` ].join("\n"); } }; const layoutTemplate = { filename: "layouts.mjs", getContents({ app }) { const layoutsObject = genObjectFromRawEntries(Object.values(app.layouts).map(({ name, file }) => { return [name, genDynamicImport(file, { interopDefault: true })]; })); return [ `export default ${layoutsObject}` ].join("\n"); } }; const middlewareTemplate = { filename: "middleware.mjs", getContents({ app }) { const globalMiddleware = app.middleware.filter((mw) => mw.global); const namedMiddleware = app.middleware.filter((mw) => !mw.global); const namedMiddlewareObject = genObjectFromRawEntries(namedMiddleware.map((mw) => [mw.name, genDynamicImport(mw.path)])); return [ ...globalMiddleware.map((mw) => genImport(mw.path, genSafeVariableName(mw.name))), `export const globalMiddleware = ${genArrayFromRaw(globalMiddleware.map((mw) => genSafeVariableName(mw.name)))}`, `export const namedMiddleware = ${namedMiddlewareObject}` ].join("\n"); } }; const nitroSchemaTemplate = { filename: "types/nitro-nuxt.d.ts", getContents() { return ( /* typescript */ ` /// <reference path="./schema.d.ts" /> import type { RuntimeConfig } from 'nuxt/schema' import type { H3Event } from 'h3' import type { LogObject } from 'consola' import type { NuxtIslandContext, NuxtIslandResponse, NuxtRenderHTMLContext } from 'nuxt/app' declare module 'nitropack' { interface NitroRuntimeConfigApp { buildAssetsDir: string cdnURL: string } interface NitroRuntimeConfig extends RuntimeConfig {} interface NitroRouteConfig { ssr?: boolean experimentalNoScripts?: boolean } interface NitroRouteRules { ssr?: boolean experimentalNoScripts?: boolean appMiddleware?: Record<string, boolean> } interface NitroRuntimeHooks { 'dev:ssr-logs': (ctx: { logs: LogObject[], path: string }) => void | Promise<void> 'render:html': (htmlContext: NuxtRenderHTMLContext, context: { event: H3Event }) => void | Promise<void> 'render:island': (islandResponse: NuxtIslandResponse, context: { event: H3Event, islandContext: NuxtIslandContext }) => void | Promise<void> } } ` ); } }; const clientConfigTemplate = { filename: "nitro.client.mjs", getContents: ({ nuxt }) => { const appId = JSON.stringify(nuxt.options.appId); return [ "export const useRuntimeConfig = () => ", (!nuxt.options.future.multiApp ? "window?.__NUXT__?.config || {}" : `window?.__NUXT__?.[${appId}]?.config || {}`) || {} ].join("\n"); } }; const appConfigDeclarationTemplate = { filename: "types/app.config.d.ts", getContents({ app, nuxt }) { const typesDir = join(nuxt.options.buildDir, "types"); const configPaths = app.configs.map((path) => relative(typesDir, path).replace(/\b\.\w+$/g, "")); return ` import type { CustomAppConfig } from 'nuxt/schema' import type { Defu } from 'defu' ${configPaths.map((id, index) => `import ${`cfg${index}`} from ${JSON.stringify(id)}`).join("\n")} declare const inlineConfig = ${JSON.stringify(nuxt.options.appConfig, null, 2)} type ResolvedAppConfig = Defu<typeof inlineConfig, [${app.configs.map((_id, index) => `typeof cfg${index}`).join(", ")}]> type IsAny<T> = 0 extends 1 & T ? true : false type MergedAppConfig<Resolved extends Record<string, unknown>, Custom extends Record<string, unknown>> = { [K in keyof (Resolved & Custom)]: K extends keyof Custom ? unknown extends Custom[K] ? Resolved[K] : IsAny<Custom[K]> extends true ? Resolved[K] : Custom[K] extends Record<string, any> ? Resolved[K] extends Record<string, any> ? MergedAppConfig<Resolved[K], Custom[K]> : Exclude<Custom[K], undefined> : Exclude<Custom[K], undefined> : Resolved[K] } declare module 'nuxt/schema' { interface AppConfig extends MergedAppConfig<ResolvedAppConfig, CustomAppConfig> { } } declare module '@nuxt/schema' { interface AppConfig extends MergedAppConfig<ResolvedAppConfig, CustomAppConfig> { } } `; } }; const appConfigTemplate = { filename: "app.config.mjs", write: true, getContents({ app, nuxt }) { return ` import { updateAppConfig } from '#app/config' import { defuFn } from 'defu' const inlineConfig = ${JSON.stringify(nuxt.options.appConfig, null, 2)} // Vite - webpack is handled directly in #app/config if (import.meta.hot) { import.meta.hot.accept((newModule) => { updateAppConfig(newModule.default) }) } ${app.configs.map((id, index) => `import ${`cfg${index}`} from ${JSON.stringify(id)}`).join("\n")} export default /*@__PURE__*/ defuFn(${app.configs.map((_id, index) => `cfg${index}`).concat(["inlineConfig"]).join(", ")}) `; } }; const publicPathTemplate = { filename: "paths.mjs", getContents({ nuxt }) { return [ "import { joinRelativeURL } from 'ufo'", !nuxt.options.dev && "import { useRuntimeConfig } from '#internal/nitro'", nuxt.options.dev ? `const appConfig = ${JSON.stringify(nuxt.options.app)}` : "const appConfig = useRuntimeConfig().app", "export const baseURL = () => appConfig.baseURL", "export const buildAssetsDir = () => appConfig.buildAssetsDir", "export const buildAssetsURL = (...path) => joinRelativeURL(publicAssetsURL(), buildAssetsDir(), ...path)", "export const publicAssetsURL = (...path) => {", " const publicBase = appConfig.cdnURL || appConfig.baseURL", " return path.length ? joinRelativeURL(publicBase, ...path) : publicBase", "}", // On server these are registered directly in packages/nuxt/src/core/runtime/nitro/renderer.ts "if (import.meta.client) {", " globalThis.__buildAssetsURL = buildAssetsURL", " globalThis.__publicAssetsURL = publicAssetsURL", "}" ].filter(Boolean).join("\n"); } }; const dollarFetchTemplate = { filename: "fetch.mjs", getContents() { return [ "import { $fetch } from 'ofetch'", "import { baseURL } from '#internal/nuxt/paths'", "if (!globalThis.$fetch) {", " globalThis.$fetch = $fetch.create({", " baseURL: baseURL()", " })", "}" ].join("\n"); } }; const nuxtConfigTemplate = { filename: "nuxt.config.mjs", getContents: (ctx) => { const fetchDefaults = { ...ctx.nuxt.options.experimental.defaults.useFetch, baseURL: void 0, headers: void 0 }; 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"))); return [ ...Object.entries(ctx.nuxt.options.app).map(([k, v]) => `export const ${camelCase("app-" + k)} = ${JSON.stringify(v)}`), `export const renderJsonPayloads = ${!!ctx.nuxt.options.experimental.renderJsonPayloads}`, `export const componentIslands = ${shouldEnableComponentIslands}`, `export const payloadExtraction = ${!!ctx.nuxt.options.experimental.payloadExtraction}`, `export const cookieStore = ${!!ctx.nuxt.options.experimental.cookieStore}`, `export const appManifest = ${!!ctx.nuxt.options.experimental.appManifest}`, `export const remoteComponentIslands = ${typeof ctx.nuxt.options.experimental.componentIslands === "object" && ctx.nuxt.options.experimental.componentIslands.remoteIsland}`, `export const selectiveClient = ${typeof ctx.nuxt.options.experimental.componentIslands === "object" && Boolean(ctx.nuxt.options.experimental.componentIslands.selectiveClient)}`, `export const devPagesDir = ${ctx.nuxt.options.dev ? JSON.stringify(ctx.nuxt.options.dir.pages) : "null"}`, `export const devRootDir = ${ctx.nuxt.options.dev ? JSON.stringify(ctx.nuxt.options.rootDir) : "null"}`, `export const devLogs = ${JSON.stringify(ctx.nuxt.options.features.devLogs)}`, `export const nuxtLinkDefaults = ${JSON.stringify(ctx.nuxt.options.experimental.defaults.nuxtLink)}`, `export const asyncDataDefaults = ${JSON.stringify({ ...ctx.nuxt.options.experimental.defaults.useAsyncData, value: ctx.nuxt.options.experimental.defaults.useAsyncData.value === "null" ? null : void 0, errorValue: ctx.nuxt.options.experimental.defaults.useAsyncData.errorValue === "null" ? null : void 0 })}`, `export const resetAsyncDataToUndefined = ${ctx.nuxt.options.experimental.resetAsyncDataToUndefined}`, `export const nuxtDefaultErrorValue = ${ctx.nuxt.options.future.compatibilityVersion === 4 ? "undefined" : "null"}`, `export const fetchDefaults = ${JSON.stringify(fetchDefaults)}`, `export const vueAppRootContainer = ${ctx.nuxt.options.app.rootAttrs.id ? `'#${ctx.nuxt.options.app.rootAttrs.id}'` : `'body > ${ctx.nuxt.options.app.rootTag}'`}`, `export const viewTransition = ${ctx.nuxt.options.experimental.viewTransition}`, `export const appId = ${JSON.stringify(ctx.nuxt.options.appId)}`, `export const outdatedBuildInterval = ${ctx.nuxt.options.experimental.checkOutdatedBuildInterval}`, `export const multiApp = ${!!ctx.nuxt.options.future.multiApp}` ].join("\n\n"); } }; const TYPE_FILENAME_RE = /\.([cm])?[jt]s$/; const DECLARATION_RE = /\.d\.[cm]?ts$/; const buildTypeTemplate = { filename: "types/build.d.ts", getContents({ app }) { let declarations = ""; for (const file of app.templates) { if (file.write || !file.filename || DECLARATION_RE.test(file.filename)) { continue; } if (TYPE_FILENAME_RE.test(file.filename)) { const typeFilenames = /* @__PURE__ */ new Set([file.filename.replace(TYPE_FILENAME_RE, ".d.$1ts"), file.filename.replace(TYPE_FILENAME_RE, ".d.ts")]); if (app.templates.some((f) => f.filename && typeFilenames.has(f.filename))) { continue; } } declarations += "declare module " + JSON.stringify(join("#build", file.filename)) + ";\n"; } return declarations; } }; const defaultTemplates = { __proto__: null, appComponentTemplate: appComponentTemplate, appConfigDeclarationTemplate: appConfigDeclarationTemplate, appConfigTemplate: appConfigTemplate, appDefaults: appDefaults, buildTypeTemplate: buildTypeTemplate, clientConfigTemplate: clientConfigTemplate, clientPluginTemplate: clientPluginTemplate, cssTemplate: cssTemplate, dollarFetchTemplate: dollarFetchTemplate, errorComponentTemplate: errorComponentTemplate, layoutTemplate: layoutTemplate, middlewareTemplate: middlewareTemplate, nitroSchemaTemplate: nitroSchemaTemplate, nuxtConfigTemplate: nuxtConfigTemplate, pluginsDeclaration: pluginsDeclaration, publicPathTemplate: publicPathTemplate, rootComponentTemplate: rootComponentTemplate, schemaTemplate: schemaTemplate, serverPluginTemplate: serverPluginTemplate, testComponentWrapperTemplate: testComponentWrapperTemplate, vueShim: vueShim }; function createApp(nuxt, options = {}) { return defu(options, { dir: nuxt.options.srcDir, extensions: nuxt.options.extensions, plugins: [], components: [], templates: [] }); } const postTemplates = [ clientPluginTemplate.filename, serverPluginTemplate.filename, pluginsDeclaration.filename ]; async function generateApp(nuxt, app, options = {}) { await resolveApp(nuxt, app); app.templates = Object.values(defaultTemplates).concat(nuxt.options.build.templates); await nuxt.callHook("app:templates", app); app.templates = app.templates.map((tmpl) => normalizeTemplate(tmpl)); const filteredTemplates = { pre: [], post: [] }; for (const template of app.templates) { if (options.filter && !options.filter(template)) { continue; } const key = template.filename && postTemplates.includes(template.filename) ? "post" : "pre"; filteredTemplates[key].push(template); } const templateContext = { utils: templateUtils, nuxt, app }; const compileTemplate$1 = nuxt.options.experimental.compileTemplate ? compileTemplate : futureCompileTemplate; const writes = []; const changedTemplates = []; async function processTemplate(template) { const fullPath = template.dst || resolve(nuxt.options.buildDir, template.filename); const start = performance.now(); const oldContents = nuxt.vfs[fullPath]; const contents = await compileTemplate$1(template, templateContext).catch((e) => { logger.error(`Could not compile template \`${template.filename}\`.`); logger.error(e); throw e; }); template.modified = oldContents !== contents; if (template.modified) { nuxt.vfs[fullPath] = contents; const aliasPath = "#build/" + template.filename.replace(/\.\w+$/, ""); nuxt.vfs[aliasPath] = contents; if (process.platform === "win32") { nuxt.vfs[fullPath.replace(/\//g, "\\")] = contents; } changedTemplates.push(template); } const perf = performance.now() - start; const setupTime = Math.round(perf * 100) / 100; if (nuxt.options.debug || setupTime > 500) { logger.info(`Compiled \`${template.filename}\` in ${setupTime}ms`); } if (template.modified && template.write) { writes.push(() => { mkdirSync(dirname(fullPath), { recursive: true }); writeFileSync(fullPath, contents, "utf8"); }); } } await Promise.allSettled(filteredTemplates.pre.map(processTemplate)); await Promise.allSettled(filteredTemplates.post.map(processTemplate)); for (const write of writes) { write(); } if (changedTemplates.length) { await nuxt.callHook("app:templatesGenerated", app, changedTemplates, options); } } async function futureCompileTemplate(template, ctx) { delete ctx.utils; if (template.src) { try { return await promises.readFile(template.src, "utf-8"); } catch (err) { logger.error(`[nuxt] Error reading template from \`${template.src}\``); throw err; } } if (template.getContents) { return template.getContents({ ...ctx, options: template.options }); } throw new Error("[nuxt] Invalid template. Templates must have either `src` or `getContents`: " + JSON.stringify(template)); } async function resolveApp(nuxt, app) { if (!app.mainComponent) { app.mainComponent = await findPath( nuxt.options._layers.flatMap((layer) => [ join(layer.config.srcDir, "App"), join(layer.config.srcDir, "app") ]) ); } if (!app.mainComponent) { app.mainComponent = resolve(nuxt.options.appDir, "components/welcome.vue"); } if (!app.rootComponent) { app.rootComponent = await findPath(["~/app.root", resolve(nuxt.options.appDir, "components/nuxt-root.vue")]); } if (!app.errorComponent) { app.errorComponent = await findPath( nuxt.options._layers.map((layer) => join(layer.config.srcDir, "error")) ) ?? resolve(nuxt.options.appDir, "components/nuxt-error-page.vue"); } const layerConfigs = nuxt.options._layers.map((layer) => layer.config); const reversedConfigs = layerConfigs.slice().reverse(); app.layouts = {}; for (const config of layerConfigs) { const layoutDir = (config.rootDir === nuxt.options.rootDir ? nuxt.options : config).dir?.layouts || "layouts"; const layoutFiles = await resolveFiles(config.srcDir, `${layoutDir}/**/*{${nuxt.options.extensions.join(",")}}`); for (const file of layoutFiles) { const name = getNameFromPath(file, resolve(config.srcDir, layoutDir)); if (!name) { logger.warn(`No layout name could be resolved for \`~/${relative(nuxt.options.srcDir, file)}\`. Bear in mind that \`index\` is ignored for the purpose of creating a layout name.`); continue; } app.layouts[name] = app.layouts[name] || { name, file }; } } app.middleware = []; for (const config of reversedConfigs) { const middlewareDir = (config.rootDir === nuxt.options.rootDir ? nuxt.options : config).dir?.middleware || "middleware"; const middlewareFiles = await resolveFiles(config.srcDir, [ `${middlewareDir}/*{${nuxt.options.extensions.join(",")}}`, ...nuxt.options.future.compatibilityVersion === 4 ? [`${middlewareDir}/*/index{${nuxt.options.extensions.join(",")}}`] : [] ]); for (const file of middlewareFiles) { const name = getNameFromPath(file); if (!name) { logger.warn(`No middleware name could be resolved for \`~/${relative(nuxt.options.srcDir, file)}\`. Bear in mind that \`index\` is ignored for the purpose of creating a middleware name.`); continue; } app.middleware.push({ name, path: file, global: hasSuffix(file, ".global") }); } } app.plugins = []; for (const config of reversedConfigs) { const pluginDir = (config.rootDir === nuxt.options.rootDir ? nuxt.options : config).dir?.plugins || "plugins"; app.plugins.push(...[ ...config.plugins || [], ...config.srcDir ? await resolveFiles(config.srcDir, [ `${pluginDir}/*{${nuxt.options.extensions.join(",")}}`, `${pluginDir}/*/index{${nuxt.options.extensions.join(",")}}` ]) : [] ].map((plugin) => normalizePlugin(plugin))); } for (const p of [...nuxt.options.plugins].reverse()) { const plugin = normalizePlugin(p); if (!app.plugins.some((p2) => p2.src === plugin.src)) { app.plugins.unshift(plugin); } } app.middleware = uniqueBy(await resolvePaths([...app.middleware].reverse(), "path"), "name").reverse(); app.plugins = uniqueBy(await resolvePaths(app.plugins, "src"), "src"); app.configs = []; for (const config of layerConfigs) { const appConfigPath = await findPath(resolve(config.srcDir, "app.config")); if (appConfigPath) { app.configs.push(appConfigPath); } } await nuxt.callHook("app:resolve", app); app.middleware = uniqueBy(await resolvePaths(app.middleware, "path"), "name"); app.plugins = uniqueBy(await resolvePaths(app.plugins, "src"), "src"); } function resolvePaths(items, key) { return Promise.all(items.map(async (item) => { if (!item[key]) { return item; } return { ...item, [key]: await resolvePath$1(resolveAlias(item[key])) }; })); } const IS_TSX = /\.[jt]sx$/; async function annotatePlugins(nuxt, plugins) { const _plugins = []; for (const plugin of plugins) { try { const code = plugin.src in nuxt.vfs ? nuxt.vfs[plugin.src] : await promises.readFile(plugin.src, "utf-8"); _plugins.push({ ...await extractMetadata(code, IS_TSX.test(plugin.src) ? "tsx" : "ts"), ...plugin }); } catch (e) { const relativePluginSrc = relative(nuxt.options.rootDir, plugin.src); if (e.message === "Invalid plugin metadata") { logger.warn(`Failed to parse static properties from plugin \`${relativePluginSrc}\`, falling back to non-optimized runtime meta. Learn more: https://nuxt.com/docs/guide/directory-structure/plugins#object-syntax-plugins`); } else { logger.warn(`Failed to parse static properties from plugin \`${relativePluginSrc}\`.`, e); } _plugins.push(plugin); } } return _plugins.sort((a, b) => (a.order ?? orderMap.default) - (b.order ?? orderMap.default)); } function checkForCircularDependencies(_plugins) { const deps = /* @__PURE__ */ Object.create(null); const pluginNames = _plugins.map((plugin) => plugin.name); for (const plugin of _plugins) { if (plugin.dependsOn && plugin.dependsOn.some((name) => !pluginNames.includes(name))) { console.error(`Plugin \`${plugin.name}\` depends on \`${plugin.dependsOn.filter((name) => !pluginNames.includes(name)).join(", ")}\` but they are not registered.`); } if (plugin.name) { deps[plugin.name] = plugin.dependsOn || []; } } const checkDeps = (name, visited = []) => { if (visited.includes(name)) { console.error(`Circular dependency detected in plugins: ${visited.join(" -> ")} -> ${name}`); return []; } visited.push(name); return deps[name]?.length ? deps[name].flatMap((dep) => checkDeps(dep, [...visited])) : []; }; for (const name in deps) { checkDeps(name); } } async function checkForExternalConfigurationFiles() { const checkResults = await Promise.all([checkViteConfig(), checkWebpackConfig(), checkNitroConfig(), checkPostCSSConfig()]); const warningMessages = checkResults.filter(Boolean); if (!warningMessages.length) { return; } const foundOneExternalConfig = warningMessages.length === 1; if (foundOneExternalConfig) { logger.warn(warningMessages[0]); } else { const warningsAsList = warningMessages.map((message) => `- ${message}`).join("\n"); const warning = `Found multiple external configuration files: ${warningsAsList}`; logger.warn(warning); } } async function checkViteConfig() { return await checkAndWarnAboutConfigFileExistence({ fileName: "vite.config", extensions: [".js", ".mjs", ".ts", ".cjs", ".mts", ".cts"], createWarningMessage: (foundFile) => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.vite\` instead. You can read more in \`https://nuxt.com/docs/api/nuxt-config#vite\`.` }); } async function checkWebpackConfig() { return await checkAndWarnAboutConfigFileExistence({ fileName: "webpack.config", extensions: [".js", ".mjs", ".ts", ".cjs", ".mts", ".cts", "coffee"], createWarningMessage: (foundFile) => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.webpack\` instead. You can read more in \`https://nuxt.com/docs/api/nuxt-config#webpack-1\`.` }); } async function checkNitroConfig() { return await checkAndWarnAboutConfigFileExistence({ fileName: "nitro.config", extensions: [".ts", ".mts"], createWarningMessage: (foundFile) => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.nitro\` instead. You can read more in \`https://nuxt.com/docs/api/nuxt-config#nitro\`.` }); } async function checkPostCSSConfig() { return await checkAndWarnAboutConfigFileExistence({ fileName: "postcss.config", extensions: [".js", ".cjs"], createWarningMessage: (foundFile) => `Using \`${foundFile}\` is not supported together with Nuxt. Use \`options.postcss\` instead. You can read more in \`https://nuxt.com/docs/api/nuxt-config#postcss\`.` }); } async function checkAndWarnAboutConfigFileExistence(options) { const { fileName, extensions, createWarningMessage } = options; const configFile = await findPath(fileName, { extensions }).catch(() => null); if (configFile) { return createWarningMessage(basename(configFile)); } } async function build(nuxt) { const app = createApp(nuxt); nuxt.apps.default = app; const generateApp$1 = debounce(() => generateApp(nuxt, app), void 0, { leading: true }); await generateApp$1(); if (nuxt.options.dev) { watch(nuxt); nuxt.hook("builder:watch", async (event, relativePath) => { if (event === "change") { return; } const path = resolve(nuxt.options.srcDir, relativePath); const relativePaths = nuxt.options._layers.map((l) => relative(l.config.srcDir || l.cwd, path)); const restartPath = relativePaths.find((relativePath2) => /^(?:app\.|error\.|plugins\/|middleware\/|layouts\/)/i.test(relativePath2)); if (restartPath) { if (restartPath.startsWith("app")) { app.mainComponent = void 0; } if (restartPath.startsWith("error")) { app.errorComponent = void 0; } await generateApp$1(); } }); nuxt.hook("builder:generateApp", (options) => { if (options) { return generateApp(nuxt, app, options); } return generateApp$1(); }); } await nuxt.callHook("build:before"); if (!nuxt.options._prepare) { await Promise.all([checkForExternalConfigurationFiles(), bundle(nuxt)]); await nuxt.callHook("build:done"); if (!nuxt.options.dev) { await nuxt.callHook("close", nuxt); } } else { nuxt.hook("prepare:types", () => nuxt.close()); } } const watchEvents = { create: "add", delete: "unlink", update: "change" }; async function watch(nuxt) { if (nuxt.options.experimental.watcher === "parcel") { const success = await createParcelWatcher(); if (success) { return; } } if (nuxt.options.experimental.watcher === "chokidar") { return createWatcher(); } return createGranularWatcher(); } function createWatcher() { const nuxt = useNuxt(); const watcher = chokidar.watch(nuxt.options._layers.map((i) => i.config.srcDir).filter(Boolean), { ...nuxt.options.watchers.chokidar, ignoreInitial: true, ignored: [ isIgnored, "node_modules" ] }); watcher.on("all", (event, path) => nuxt.callHook("builder:watch", event, nuxt.options.experimental.relativeWatchPaths ? normalize(relative(nuxt.options.srcDir, path)) : normalize(path))); nuxt.hook("close", () => watcher?.close()); } function createGranularWatcher() { const nuxt = useNuxt(); if (nuxt.options.debug) { console.time("[nuxt] builder:chokidar:watch"); } let pending = 0; const ignoredDirs = /* @__PURE__ */ new Set([...nuxt.options.modulesDir, nuxt.options.buildDir]); const pathsToWatch = nuxt.options._layers.map((layer) => layer.config.srcDir || layer.cwd).filter((d) => d && !isIgnored(d)); for (const pattern of nuxt.options.watch) { if (typeof pattern !== "string") { continue; } const path = resolve(nuxt.options.srcDir, pattern); if (pathsToWatch.some((w) => path.startsWith(w.replace(/[^/]$/, "$&/")))) { continue; } pathsToWatch.push(path); } for (const dir of pathsToWatch) { pending++; const watcher = chokidar.watch(dir, { ...nuxt.options.watchers.chokidar, ignoreInitial: false, depth: 0, ignored: [isIgnored, "**/node_modules"] }); const watchers = {}; watcher.on("all", (event, path) => { path = normalize(path); if (!pending) { nuxt.callHook("builder:watch", event, nuxt.options.experimental.relativeWatchPaths ? relative(nuxt.options.srcDir, path) : path); } if (event === "unlinkDir" && path in watchers) { watchers[path]?.close(); delete watchers[path]; } if (event === "addDir" && path !== dir && !ignoredDirs.has(path) && !pathsToWatch.includes(path) && !(path in watchers) && !isIgnored(path)) { watchers[path] = chokidar.watch(path, { ...nuxt.options.watchers.chokidar, ignored: [isIgnored] }); watchers[path].on("all", (event2, p) => nuxt.callHook("builder:watch", event2, nuxt.options.experimental.relativeWatchPaths ? normalize(relative(nuxt.options.srcDir, p)) : normalize(p))); nuxt.hook("close", () => watchers[path]?.close()); } }); watcher.on("ready", () => { pending--; if (nuxt.options.debug && !pending) { console.timeEnd("[nuxt] builder:chokidar:watch"); } }); nuxt.hook("close", () => watcher?.close()); } } async function createParcelWatcher() { const nuxt = useNuxt(); if (nuxt.options.debug) { console.time("[nuxt] builder:parcel:watch"); } const watcherPath = await tryResolveModule("@parcel/watcher", [nuxt.options.rootDir, ...nuxt.options.modulesDir]); if (!watcherPath) { logger.warn("Falling back to `chokidar-granular` as `@parcel/watcher` cannot be resolved in your project."); return false; } const { subscribe } = await import(pathToFileURL(watcherPath).href).then(interopDefault); for (const layer of nuxt.options._layers) { if (!layer.config.srcDir) { continue; } const watcher = subscribe(layer.config.srcDir, (err, events) => { if (err) { return; } for (const event of events) { if (isIgnored(event.path)) { continue; } nuxt.callHook("builder:watch", watchEvents[event.type], nuxt.options.experimental.relativeWatchPaths ? normalize(relative(nuxt.options.srcDir, event.path)) : normalize(event.path)); } }, { ignore: [ ...nuxt.options.ignore, "node_modules" ] }); watcher.then((subscription) => { if (nuxt.options.debug) { console.timeEnd("[nuxt] builder:parcel:watch"); } nuxt.hook("close", () => subscription.unsubscribe()); }); } return true; } async function bundle(nuxt) { try { const { bundle: bundle2 } = typeof nuxt.options.builder === "string" ? await loadBuilder(nuxt, nuxt.options.builder) : nuxt.options.builder; await bundle2(nuxt); } catch (error) { await nuxt.callHook("build:error", error); if (error.toString().includes("Cannot find module '@nuxt/webpack-builder'")) { throw new Error("Could not load `@nuxt/webpack-builder`. You may need to add it to your project dependencies, following the steps in `https://github.com/nuxt/framework/pull/2812`."); } throw error; } } async function loadBuilder(nuxt, builder) { const builderPath = await tryResolveModule(builder, [nuxt.options.rootDir, import.meta.url]); if (!builderPath) { throw new Error(`Loading \`${builder}\` builder failed. You can read more about the nuxt \`builder\` option at: \`https://nuxt.com/docs/api/nuxt-config#builder\``); } return import(pathToFileURL(builderPath).href); } export { build, createNuxt, loadNuxt };
Coded With 💗 by
0x6ick Mod By V1rus_Alfa