UNPKG

unplugin-convention-routes

Version:
795 lines (775 loc) 27.4 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); // src/index.ts import path3 from "node:path"; import process4 from "node:process"; import { createUnplugin } from "unplugin"; // src/core/context.ts import { existsSync, writeFileSync } from "node:fs"; import path2, { join as join2, resolve as resolve3 } from "node:path"; import process3 from "node:process"; import { slash as slash4, toArray as toArray2 } from "@antfu/utils"; import chokidar from "chokidar"; // src/core/files.ts import { join } from "node:path"; import { slash as slash2 } from "@antfu/utils"; import fg from "fast-glob"; // src/core/utils.ts import { resolve, win32 } from "node:path"; import { slash } from "@antfu/utils"; import Debug from "debug"; // src/core/constants.ts var MODULE_IDS = [ "~pages", "~react-pages", "~solid-pages", "pages-generated", "virtual:generated-pages", "virtual:generated-pages-react" ]; var ROUTE_IMPORT_NAME = "__pages_import_$1__"; var dynamicRouteRE = /^\[(.+)\]$/; var cacheAllRouteRE = /^\[\.{3}(.*)\]$/; var replaceDynamicRouteRE = /^\[(?:\.{3})?(.*)\]$/; var nuxtDynamicRouteRE = /^_(.*)$/; var nuxtCacheAllRouteRE = /^_$/; var countSlashRE = /\//g; var replaceIndexRE = /\/?index$/; // src/core/utils.ts var debug = { // hmr: Debug('unplugin-convention-routes:hmr'), routeBlock: Debug("unplugin-convention-routes:routeBlock"), options: Debug("unplugin-convention-routes:options"), pages: Debug("unplugin-convention-routes:pages"), search: Debug("unplugin-convention-routes:search"), env: Debug("unplugin-convention-routes:env"), cache: Debug("unplugin-convention-routes:cache"), resolver: Debug("unplugin-convention-routes:resolver") }; function extsToGlob(extensions) { return extensions.length > 1 ? `{${extensions.join(",")}}` : extensions[0] || ""; } function countSlash(value) { return (value.match(countSlashRE) || []).length; } function isPagesDir(path4, options) { for (const page of options.dirs) { const dirPath = slash(resolve(options.root, page.dir)); if (path4.startsWith(dirPath)) return true; } return false; } function isTarget(path4, options) { return isPagesDir(path4, options) && options.extensionsRE.test(path4); } function isDynamicRoute(routePath, nuxtStyle = false) { return nuxtStyle ? nuxtDynamicRouteRE.test(routePath) : dynamicRouteRE.test(routePath); } function isCatchAllRoute(routePath, nuxtStyle = false) { return nuxtStyle ? nuxtCacheAllRouteRE.test(routePath) : cacheAllRouteRE.test(routePath); } function resolveImportMode(filepath, options) { const mode = options.importMode; if (typeof mode === "function") return mode(filepath, options); return mode; } function normalizeCase(str, caseSensitive) { if (!caseSensitive) return str.toLocaleLowerCase(); return str; } function normalizeName(name, isDynamic, nuxtStyle = false) { if (!isDynamic) return name; return nuxtStyle ? name.replace(nuxtDynamicRouteRE, "$1") || "all" : name.replace(replaceDynamicRouteRE, "$1"); } function buildReactRoutePath(node, nuxtStyle = false) { const isDynamic = isDynamicRoute(node, nuxtStyle); const isCatchAll = isCatchAllRoute(node, nuxtStyle); const normalizedName = normalizeName(node, isDynamic, nuxtStyle); if (isDynamic) { if (isCatchAll) return "*"; return `:${normalizedName}`; } return `${normalizedName}`; } function buildReactRemixRoutePath(node) { const escapeStart = "["; const escapeEnd = "]"; let result = ""; let rawSegmentBuffer = ""; let inEscapeSequence = 0; let skipSegment = false; for (let i = 0; i < node.length; i++) { let isNewEscapeSequence2 = function() { return !inEscapeSequence && char === escapeStart && lastChar !== escapeStart; }, isCloseEscapeSequence2 = function() { return inEscapeSequence && char === escapeEnd && nextChar !== escapeEnd; }, isStartOfLayoutSegment2 = function() { return char === "_" && nextChar === "_" && !rawSegmentBuffer; }; var isNewEscapeSequence = isNewEscapeSequence2, isCloseEscapeSequence = isCloseEscapeSequence2, isStartOfLayoutSegment = isStartOfLayoutSegment2; const char = node.charAt(i); const lastChar = i > 0 ? node.charAt(i - 1) : void 0; const nextChar = i < node.length - 1 ? node.charAt(i + 1) : void 0; if (skipSegment) { if (char === "/" || char === "." || char === win32.sep) skipSegment = false; continue; } if (isNewEscapeSequence2()) { inEscapeSequence++; continue; } if (isCloseEscapeSequence2()) { inEscapeSequence--; continue; } if (inEscapeSequence) { result += char; continue; } if (char === "/" || char === win32.sep || char === ".") { if (rawSegmentBuffer === "index" && result.endsWith("index")) result = result.replace(replaceIndexRE, ""); else result += "/"; rawSegmentBuffer = ""; continue; } if (isStartOfLayoutSegment2()) { skipSegment = true; continue; } rawSegmentBuffer += char; if (char === "$") { result += typeof nextChar === "undefined" ? "*" : ":"; continue; } result += char; } if (rawSegmentBuffer === "index" && result.endsWith("index")) result = result.replace(replaceIndexRE, ""); return result || void 0; } // src/core/files.ts function getPageDirs(PageOptions, root, exclude) { const dirs = fg.sync(slash2(PageOptions.dir), { ignore: exclude, onlyDirectories: true, dot: true, unique: true, cwd: root }); const pageDirs = dirs.map((dir) => __spreadProps(__spreadValues({}, PageOptions), { dir })); return pageDirs; } function getPageFiles(path4, options, pageOptions) { var _a; const { exclude, extensions } = options; const ext = extsToGlob(extensions); const pattern = (_a = (pageOptions == null ? void 0 : pageOptions.filePatern) || (pageOptions == null ? void 0 : pageOptions.filePattern)) != null ? _a : `**/*.${ext}`; const files = fg.sync(pattern, { ignore: exclude, onlyFiles: true, cwd: path4 }).map((p) => slash2(join(path4, p))); return files; } // src/core/initVirualPackage.ts import fs from "node:fs"; import path from "node:path"; import process from "node:process"; function initVirtualPackage() { copyFile("node_modules/unplugin-convention-routes/virtual-package", "node_modules/~unplugin-convention-routes"); } function copyFile(copiedPath, resultPath) { const _copiedPath = path.join(process.cwd(), copiedPath); const _resultPath = path.join(process.cwd(), resultPath); fs.cpSync(_copiedPath, _resultPath, { recursive: true }); } // src/core/options.ts import { resolve as resolve2 } from "node:path"; import process2 from "node:process"; import { slash as slash3, toArray } from "@antfu/utils"; // src/core/stringify.ts var componentRE = /"(?:component|element)":("(.*?)")/g; var hasFunctionRE = /"(?:props|beforeEnter)":("(.*?)")/g; var multilineCommentsRE = /\/\*(.|[\r\n])*?\*\//g; var singlelineCommentsRE = /\/\/.*/g; function replaceFunction(_, value) { if (value instanceof Function || typeof value === "function") { const fnBody = value.toString().replace(multilineCommentsRE, "").replace(singlelineCommentsRE, "").replace(/(\s)/g, ""); if (fnBody.length < 8 || fnBody.substring(0, 8) !== "function") return `_NuFrRa_${fnBody}`; return fnBody; } return value; } function stringifyRoutes(preparedRoutes, options) { const importsMap = /* @__PURE__ */ new Map(); function getImportString(path4, importName) { var _a, _b; const mode = resolveImportMode(path4, options); return mode === "sync" ? `import ${importName} from "${path4}"` : `const ${importName} = ${((_b = (_a = options.resolver.stringify) == null ? void 0 : _a.dynamicImport) == null ? void 0 : _b.call(_a, path4)) || `() => import("${path4}")`}`; } function componentReplacer(str, replaceStr, path4) { var _a, _b; let importName = importsMap.get(path4); if (!importName) importName = ROUTE_IMPORT_NAME.replace("$1", `${importsMap.size}`); importsMap.set(path4, importName); importName = ((_b = (_a = options.resolver.stringify) == null ? void 0 : _a.component) == null ? void 0 : _b.call(_a, importName)) || importName; return str.replace(replaceStr, importName); } function functionReplacer(str, replaceStr, content) { if (content.startsWith("function")) return str.replace(replaceStr, content); if (content.startsWith("_NuFrRa_")) return str.replace(replaceStr, content.slice(8)); return str; } const stringRoutes = JSON.stringify(preparedRoutes, replaceFunction).replace(componentRE, componentReplacer).replace(hasFunctionRE, functionReplacer); const imports = Array.from(importsMap).map((args) => getImportString(...args)); return { imports, stringRoutes }; } function generateClientCode(routes, options) { var _a, _b; const { imports, stringRoutes } = stringifyRoutes(routes, options); const code = `${imports.join(";\n")}; const routes = ${stringRoutes}; export default routes;`; return ((_b = (_a = options.resolver.stringify) == null ? void 0 : _a.final) == null ? void 0 : _b.call(_a, code)) || code; } // src/core/resolvers/react.ts function prepareRoutes(routes, options, parent) { var _a, _b; for (const route of routes) { if (parent) route.path = (_a = route.path) == null ? void 0 : _a.replace(/^\//, ""); if (route.children) route.children = prepareRoutes(route.children, options, route); delete route.rawRoute; Object.assign(route, ((_b = options.extendRoute) == null ? void 0 : _b.call(options, route, parent)) || {}); } return routes; } async function computeReactRoutes(ctx) { var _a, _b; const { routeStyle, caseSensitive = false, importPath } = ctx.options; const nuxtStyle = routeStyle === "nuxt"; const pageRoutes = [...ctx.pageRouteMap.values()].sort((a, b) => countSlash(a.route) - countSlash(b.route)); const routes = []; pageRoutes.forEach((page) => { const pathNodes = page.route.split("/"); const element = importPath === "relative" ? page.path.replace(ctx.root, "") : page.path; let parentRoutes = routes; for (let i = 0; i < pathNodes.length; i++) { const node = pathNodes[i]; const route = { caseSensitive, path: "", rawRoute: pathNodes.slice(0, i + 1).join("/") }; if (i === pathNodes.length - 1) route.element = element; const isIndexRoute = normalizeCase(node, caseSensitive).endsWith("index"); if (!route.path && isIndexRoute) { route.path = "/"; } else if (!isIndexRoute) { if (routeStyle === "remix") route.path = buildReactRemixRoutePath(node); else route.path = buildReactRoutePath(node, nuxtStyle); } const parent = parentRoutes.find((parent2) => { return pathNodes.slice(0, i).join("/") === parent2.rawRoute; }); if (parent) { parent.children = parent.children || []; parentRoutes = parent.children; } const exits = parentRoutes.some((parent2) => { return pathNodes.slice(0, i + 1).join("/") === parent2.rawRoute; }); if (!exits) parentRoutes.push(route); } }); let finalRoutes = prepareRoutes(routes, ctx.options); finalRoutes = await ((_b = (_a = ctx.options).onRoutesGenerated) == null ? void 0 : _b.call(_a, finalRoutes)) || finalRoutes; return finalRoutes; } async function resolveReactRoutes(ctx) { var _a, _b; const finalRoutes = await computeReactRoutes(ctx); let client = generateClientCode(finalRoutes, ctx.options); client = await ((_b = (_a = ctx.options).onClientGenerated) == null ? void 0 : _b.call(_a, client)) || client; return client; } function reactResolver() { return { resolveModuleIds() { return ["~react-pages", "virtual:generated-pages-react"]; }, resolveExtensions() { return ["tsx", "jsx", "ts", "js"]; }, async resolveRoutes(ctx) { return resolveReactRoutes(ctx); }, async getComputedRoutes(ctx) { return computeReactRoutes(ctx); }, stringify: { component: (path4) => `React.createElement(${path4})`, dynamicImport: (path4) => `React.lazy(() => import("${path4}"))`, final: (code) => `import React from "react"; ${code}` } }; } // src/core/resolvers/solid.ts function prepareRoutes2(options, routes, parent) { var _a, _b; for (const route of routes) { if (parent) route.path = (_a = route.path) == null ? void 0 : _a.replace(/^\//, ""); if (route.children) route.children = prepareRoutes2(options, route.children, route); delete route.rawRoute; Object.assign(route, ((_b = options.extendRoute) == null ? void 0 : _b.call(options, route, parent)) || {}); } return routes; } async function computeSolidRoutes(ctx) { var _a, _b; const { routeStyle, caseSensitive = false, importPath } = ctx.options; const nuxtStyle = routeStyle === "nuxt"; const pageRoutes = [...ctx.pageRouteMap.values()].sort((a, b) => countSlash(a.route) - countSlash(b.route)); const routes = []; pageRoutes.forEach((page) => { const pathNodes = page.route.split("/"); const component = importPath === "relative" ? page.path.replace(ctx.root, "") : page.path; const element = importPath === "relative" ? page.path.replace(ctx.root, "") : page.path; let parentRoutes = routes; for (let i = 0; i < pathNodes.length; i++) { const node = pathNodes[i]; const normalizedPath = normalizeCase(node, caseSensitive); const route = { path: "", rawRoute: pathNodes.slice(0, i + 1).join("/") }; const parent = parentRoutes.find( (parent2) => pathNodes.slice(0, i).join("/") === parent2.rawRoute ); if (parent) { parent.children = parent.children || []; parentRoutes = parent.children; } if (i === pathNodes.length - 1) { route.element = element; route.component = component; } if (normalizedPath === "index") { if (!route.path) route.path = "/"; } else if (normalizedPath !== "index") { if (routeStyle === "remix") route.path = buildReactRemixRoutePath(node) || ""; else route.path = buildReactRoutePath(node, nuxtStyle) || ""; } const exist = parentRoutes.some((parent2) => { return pathNodes.slice(0, i + 1).join("/") === parent2.rawRoute; }); if (!exist) parentRoutes.push(route); } }); let finalRoutes = prepareRoutes2(ctx.options, routes); finalRoutes = await ((_b = (_a = ctx.options).onRoutesGenerated) == null ? void 0 : _b.call(_a, finalRoutes)) || finalRoutes; return finalRoutes; } async function resolveSolidRoutes(ctx) { var _a, _b; const finalRoutes = await computeSolidRoutes(ctx); let client = generateClientCode(finalRoutes, ctx.options); client = await ((_b = (_a = ctx.options).onClientGenerated) == null ? void 0 : _b.call(_a, client)) || client; return client; } function solidResolver() { return { resolveModuleIds() { return ["~solid-pages"]; }, resolveExtensions() { return ["tsx", "jsx", "ts", "js"]; }, async resolveRoutes(ctx) { return resolveSolidRoutes(ctx); }, async getComputedRoutes(ctx) { return computeSolidRoutes(ctx); }, stringify: { dynamicImport: (path4) => `Solid.lazy(() => import("${path4}"))`, final: (code) => `import * as Solid from "solid-js"; ${code}` } }; } // src/core/resolvers/vue.ts function prepareRoutes3(ctx, routes, parent) { var _a, _b, _c, _d; for (const route of routes) { if (route.name) route.name = route.name.replace(new RegExp(`${ctx.options.routeNameSeparator}index$`), ""); if (parent) route.path = (_a = route.path) == null ? void 0 : _a.replace(/^\//, ""); if (route.children) route.children = prepareRoutes3(ctx, route.children, route); if ((_b = route.children) == null ? void 0 : _b.find((c) => c.name === route.name)) delete route.name; route.props = true; delete route.rawRoute; if (route.customBlock) { Object.assign(route, route.customBlock || {}); delete route.customBlock; } Object.assign(route, ((_d = (_c = ctx.options).extendRoute) == null ? void 0 : _d.call(_c, route, parent)) || {}); } return routes; } async function computeVueRoutes(ctx, customBlockMap) { var _a, _b; const { routeStyle, caseSensitive = false, importPath, routeNameSeparator } = ctx.options; const pageRoutes = [...ctx.pageRouteMap.values()].sort((a, b) => countSlash(a.route) - countSlash(b.route)); const routes = []; pageRoutes.forEach((page) => { const pathNodes = page.route.split("/"); const component = importPath === "relative" ? page.path.replace(ctx.root, "") : page.path; const customBlock = customBlockMap.get(page.path); const route = { name: "", path: "", component, customBlock, rawRoute: page.route }; let parentRoutes = routes; let dynamicRoute = false; for (let i = 0; i < pathNodes.length; i++) { const node = pathNodes[i]; const nuxtStyle = routeStyle === "nuxt"; const isDynamic = isDynamicRoute(node, nuxtStyle); const isCatchAll = isCatchAllRoute(node, nuxtStyle); const normalizedName = normalizeName(node, isDynamic, nuxtStyle); const normalizedPath = normalizeCase(normalizedName, caseSensitive); if (isDynamic) dynamicRoute = true; route.name += route.name ? `${routeNameSeparator}${normalizedName}` : normalizedName; const parent = parentRoutes.find((parent2) => { return pathNodes.slice(0, i + 1).join("/") === parent2.rawRoute; }); if (parent) { parent.children = parent.children || []; parentRoutes = parent.children; route.path = ""; } else if (normalizedPath === "index") { if (!route.path) route.path = "/"; } else if (normalizedPath !== "index") { if (isDynamic) { route.path += `/:${normalizedName}`; if (isCatchAll) { if (i === 0) route.path += "(.*)*"; else route.path += "(.*)"; } else if (nuxtStyle && i === pathNodes.length - 1) { const isIndexFound = pageRoutes.find(({ route: route2 }) => { return route2 === page.route.replace(pathNodes[i], "index"); }); if (!isIndexFound) route.path += "?"; } } else { route.path += `/${normalizedPath}`; } } } if (dynamicRoute) parentRoutes.push(route); else parentRoutes.unshift(route); }); let finalRoutes = prepareRoutes3(ctx, routes); finalRoutes = await ((_b = (_a = ctx.options).onRoutesGenerated) == null ? void 0 : _b.call(_a, finalRoutes)) || finalRoutes; return finalRoutes; } async function resolveVueRoutes(ctx, customBlockMap) { var _a, _b; const finalRoutes = await computeVueRoutes(ctx, customBlockMap); let client = generateClientCode(finalRoutes, ctx.options); client = await ((_b = (_a = ctx.options).onClientGenerated) == null ? void 0 : _b.call(_a, client)) || client; return client; } function vueResolver() { const customBlockMap = /* @__PURE__ */ new Map(); return { resolveExtensions() { return ["vue", "ts", "js"]; }, resolveModuleIds() { return ["~pages", "pages-generated", "virtual:generated-pages"]; }, async resolveRoutes(ctx) { return resolveVueRoutes(ctx, customBlockMap); }, async getComputedRoutes(ctx) { return computeVueRoutes(ctx, customBlockMap); } // hmr: { // added: async (ctx, path) => checkCustomBlockChange(ctx, path), // changed: async (ctx, path) => checkCustomBlockChange(ctx, path), // removed: async (_ctx, path) => { // customBlockMap.delete(path) // }, // }, }; } // src/core/options.ts function resolvePageDirs(dirs, root, exclude) { dirs = toArray(dirs); return dirs.flatMap((dir) => { const option = typeof dir === "string" ? { dir, baseRoute: "" } : dir; option.dir = slash3(resolve2(root, option.dir)).replace(`${root}/`, ""); option.baseRoute = option.baseRoute.replace(/^\//, "").replace(/\/$/, ""); return getPageDirs(option, root, exclude); }); } var syncIndexResolver = (filepath, options) => { for (const page of options.dirs) { if (page.baseRoute === "" && filepath.startsWith(`/${page.dir}/index`)) return "sync"; } return "async"; }; function getResolver(originalResolver) { let resolver = originalResolver || "vue"; if (typeof resolver !== "string") return resolver; switch (resolver) { case "vue": resolver = vueResolver(); break; case "react": resolver = reactResolver(); break; case "solid": resolver = solidResolver(); break; default: throw new Error(`Unsupported resolver: ${resolver}`); } return resolver; } function resolveOptions(userOptions, projectRoot) { var _a; const { dirs = userOptions.pagesDir || ["src/pages"], routeBlockLang = "json5", exclude = ["node_modules", ".git", "**/__*__/**"], caseSensitive = false, syncIndex = true, routeNameSeparator = "-", extendRoute, onRoutesGenerated, onClientGenerated } = userOptions; const root = projectRoot || slash3(process2.cwd()); const importMode = userOptions.importMode || (syncIndex ? syncIndexResolver : "async"); const importPath = userOptions.importPath || "relative"; const resolver = getResolver(userOptions.resolver); const extensions = userOptions.extensions || resolver.resolveExtensions(); const extensionsRE = new RegExp(`\\.(${extensions.join("|")})$`); const resolvedDirs = resolvePageDirs(dirs, root, exclude); const routeStyle = userOptions.nuxtStyle ? "nuxt" : userOptions.routeStyle || "next"; const moduleIds = userOptions.moduleId ? [userOptions.moduleId] : ((_a = resolver.resolveModuleIds) == null ? void 0 : _a.call(resolver)) || MODULE_IDS; const resolvedOptions = { dirs: resolvedDirs, routeStyle, routeBlockLang, moduleIds, root, extensions, importMode, importPath, exclude, caseSensitive, resolver, extensionsRE, extendRoute, onRoutesGenerated, onClientGenerated, routeNameSeparator }; return resolvedOptions; } // src/core/context.ts var directoryToWatch = "src/pages"; var PageContext = class { constructor(userOptions, projectRoot = process3.cwd()) { // private _server: ViteDevServer | undefined this._pageRouteMap = /* @__PURE__ */ new Map(); this.rawOptions = userOptions; this.root = slash4(projectRoot); debug.env("root", this.root); this.options = resolveOptions(userOptions, this.root); debug.options(this.options); if (this.rawOptions.watcher) { this.watcher = chokidar.watch(directoryToWatch, { ignored: /(^|[/\\])\../, // 忽略隐藏文件 persistent: true, // 持续监视 ignoreInitial: true // 忽略初始扫描 }); this.setupWatcher(this.watcher); } this.searchGlob().then(() => { this.writeFile(); }); } // setupViteServer(server: ViteDevServer) { // if (this._server === server) // return // this._server = server // this.setupWatcher(server.watcher) // } setupWatcher(watcher) { watcher.on("unlink", async (path4) => { path4 = `${process3.cwd()}\\${path4}`; path4 = slash4(path4); if (!isTarget(path4, this.options)) return; await this.removePage(path4); this.onUpdate(); }); watcher.on("add", async (path4) => { path4 = `${process3.cwd()}\\${path4}`; path4 = slash4(path4); if (!isTarget(path4, this.options)) return; const page = this.options.dirs.find((i) => path4.startsWith(slash4(resolve3(this.root, i.dir)))); await this.addPage(path4, page); this.onUpdate(); }); } async addPage(path4, pageDir) { for (const p of toArray2(path4)) { const pageDirPath = slash4(resolve3(this.root, pageDir.dir)); const extension = this.options.extensions.find((ext) => p.endsWith(`.${ext}`)); if (!extension) continue; const route = slash4(join2(pageDir.baseRoute, p.replace(`${pageDirPath}/`, "").replace(`.${extension}`, ""))); this._pageRouteMap.set(p, { path: p, route }); } } async removePage(path4) { debug.pages("remove", path4); this._pageRouteMap.delete(path4); } onUpdate() { this.writeFile(); } async writeFile() { const fullPath = path2.join(process3.cwd(), "node_modules", "~unplugin-convention-routes"); if (!existsSync(fullPath)) { initVirtualPackage(); } const result = await this.resolveRoutes(); const resolver = this.rawOptions.resolver; writeFileSync(path2.join(fullPath, `${resolver}.js`), result); } async resolveRoutes() { return this.options.resolver.resolveRoutes(this); } async searchGlob() { const pageDirFiles = this.options.dirs.map((page) => { const pagesDirPath = slash4(resolve3(this.options.root, page.dir)); const files = getPageFiles(pagesDirPath, this.options, page); debug.search(page.dir, files); return __spreadProps(__spreadValues({}, page), { files: files.map((file) => slash4(file)) }); }); for (const page of pageDirFiles) await this.addPage(page.files, page); debug.cache(this.pageRouteMap); } get debug() { return debug; } get pageRouteMap() { return this._pageRouteMap; } }; // src/index.ts var unpluginFactory = (userOptions = { resolver: "vue" }) => { const ctx = new PageContext(userOptions); return { name: "unplugin-convention-routes", buildEnd() { var _a; (_a = ctx.watcher) == null ? void 0 : _a.close(); }, resolveId(id) { if (["~unplugin-convention-routes/react", "~unplugin-convention-routes/vue", "~unplugin-convention-routes/solid"].includes(id)) { return path3.resolve(process4.cwd(), "node_modules", "~unplugin-convention-routes", `${id.split("/")[1]}.js`); } return null; } }; }; var unplugin = /* @__PURE__ */ createUnplugin(unpluginFactory); var src_default = unplugin; export { unpluginFactory, unplugin, src_default };