{"version":3,"file":"index.cjs","sources":["../src/index.js"],"sourcesContent":["const VIRTUAL_MODULE_ID = 'virtual:auto-routes'\r\nconst RESOLVED_VIRTUAL_MODULE_ID = '\\0' + VIRTUAL_MODULE_ID\r\n\r\nexport default function VitePluginAutoRoutes(options = {}) {\r\n  const { pagesDir = 'src/views' } = options\r\n  let config\r\n\r\n  return {\r\n    name: 'vite-plugin-auto-routes',\r\n\r\n    configResolved(resolvedConfig) {\r\n      config = resolvedConfig\r\n    },\r\n\r\n    resolveId(id) {\r\n      if (id === VIRTUAL_MODULE_ID) {\r\n        return RESOLVED_VIRTUAL_MODULE_ID\r\n      }\r\n    },\r\n\r\n    load(id) {\r\n      if (id === RESOLVED_VIRTUAL_MODULE_ID) {\r\n        // 生成包含 import.meta.glob 的代码\r\n        // 将所有工具函数内联,避免用户项目找不到路径\r\n        const globPattern = `/${pagesDir}/**/[!_]*.vue`\r\n        const metaGlobPattern = `/${pagesDir}/**/[!_]*.meta.{js,ts}`\r\n        \r\n        const code = `\r\nfunction endWithIndex(filePath) {\r\n  const fileName = filePath.split('/').pop().replace(/\\\\.vue$/, '')\r\n  return fileName.includes('index')\r\n}\r\n\r\nfunction pathToRoute(filePath, pagesDir) {\r\n  let path = filePath\r\n    .replace(new RegExp(\\`^.*\\${pagesDir.replace(/\\\\//g, '\\\\\\\\/')}\\`), '')\r\n    .replace(/\\\\.vue$/, '')\r\n\r\n  path = path.replace(/\\\\/index(?=\\\\[)/g, '')\r\n  path = path.replace(/^index(?=\\\\[)/g, '')\r\n  path = path.replace(/\\\\/index$/g, '')\r\n  path = path.replace(/^index$/g, '')\r\n\r\n  path = path.replace(/\\\\[\\\\[\\\\.\\\\.\\\\.(\\w+)\\\\]\\\\]/g, '/:$1?(.*)')\r\n  path = path.replace(/\\\\[\\\\.\\\\.\\\\.(\\w+)\\\\]/g, '/:$1(.*)')\r\n  path = path.replace(/\\\\[\\\\[(\\\\w+)\\\\]\\\\]/g, '/:$1?')\r\n  path = path.replace(/\\\\[(\\\\w+)\\\\]/g, '/:$1')\r\n\r\n  if (!path || path === '/') return '/'\r\n  return path.startsWith('/') ? path : '/' + path\r\n}\r\n\r\nfunction isChilrenRoute(filePath1, filePath2) {\r\n  const str2 = filePath2.slice(0, filePath2.lastIndexOf('/'))\r\n  return filePath1 === str2\r\n}\r\n\r\nfunction RouterPathTometaPath(path) {\r\n  // 直接返回原始路径，因为 key 已经是完整的文件路径\r\n  // 只需要返回两种可能的扩展名版本\r\n  const basePath = path.replace(/\\.(js|ts)$/, '')\r\n  return [basePath + '.js', basePath + '.ts']\r\n}\r\n\r\nfunction generateRoutesByRouteObj(route) {\r\n  const routes = {}\r\n  const name = route.filePath.split('/').filter(item => !item.startsWith(':')).join('').toLowerCase()\r\n  let path = route.filePath.split('/').map(item =>\r\n    item.startsWith(':') ? item : item.toLowerCase()).join('/')\r\n  \r\n  if (name === 'home') {\r\n    path = path.split('/').filter(item => item !== 'home').join('/') || '/'\r\n  }\r\n  \r\n  routes.path = path\r\n  routes.name = name\r\n  routes.component = route.component\r\n  Object.assign(routes, { ...route.meta })\r\n  \r\n  if (route.children) {\r\n    routes.children = []\r\n    for (const childRoute of route.children) {\r\n      routes.children.push(generateRoutesByRouteObj(childRoute))\r\n    }\r\n  }\r\n  \r\n  return routes\r\n}\r\n// ============ 工具函数结束 ============\r\n\r\n// 动态导入所有页面组件(浏览器环境执行)\r\nconst modules = import.meta.glob('${globPattern}', { eager: false })\r\nconst metaModules = import.meta.glob('${metaGlobPattern}', { eager: true })\r\n\r\nconst newMetaModules = {}\r\nfor (const key in metaModules) {\r\n  const metaPaths = RouterPathTometaPath(key)\r\n  // 尝试匹配 .meta.js 或 .meta.ts\r\n  for (const metaPath of metaPaths) {\r\n    if (key.endsWith(metaPath)) {\r\n      newMetaModules[metaPath] = metaModules[key]\r\n      break\r\n    }\r\n  }\r\n}\r\n\r\n// 获取 meta 信息的辅助函数\r\nfunction getMetaForPath(key) {\r\n  // key 是 Vue 文件路径，需要转换为 meta 文件路径\r\n  const metaPath = key.replace(/\\\\.vue$/, '.meta.js')\r\n  const metaPathTs = key.replace(/\\\\.vue$/, '.meta.ts')\r\n  \r\n  if (newMetaModules[metaPath]) {\r\n    return newMetaModules[metaPath].default || {}\r\n  }\r\n  if (newMetaModules[metaPathTs]) {\r\n    return newMetaModules[metaPathTs].default || {}\r\n  }\r\n  return {}\r\n}\r\n\r\nconst maybeParentRoutes = []\r\n// 先找到所有可能有 children 的路由\r\nfor (const key in modules) {\r\n  if (endWithIndex(key)) {\r\n    maybeParentRoutes.push({\r\n      filePath: pathToRoute(key, '/${pagesDir}'),\r\n      component: modules[key],\r\n      meta: getMetaForPath(key)\r\n    })\r\n  }\r\n}\r\n\r\nconst childrenLength = maybeParentRoutes.length\r\n\r\n// 再遍历 modules 将可能有 children 的路由的 children 属性补全\r\nfor (const key in modules) {\r\n  if (endWithIndex(key)) continue\r\n  const keyPath = pathToRoute(key, '/${pagesDir}')\r\n  let isChild = false\r\n  \r\n  for (const parentRoute of maybeParentRoutes) {\r\n    if (isChilrenRoute(parentRoute.filePath, keyPath)) {\r\n      if (!parentRoute.children) {\r\n        parentRoute.children = []\r\n      }\r\n      const replacePath = parentRoute.filePath + '/'\r\n      parentRoute.children.push({\r\n        filePath: keyPath.replace(replacePath, ''),\r\n        component: modules[key],\r\n        meta: getMetaForPath(key)\r\n      })\r\n      isChild = true\r\n    }\r\n  }\r\n  \r\n  if (!isChild) {\r\n    maybeParentRoutes.push({\r\n      filePath: keyPath,\r\n      component: modules[key],\r\n      meta: getMetaForPath(key)\r\n    })\r\n  }\r\n}\r\n\r\n// 处理可能有 children 的路由之间的嵌套关系\r\nfor (let i = 0; i < childrenLength; i++) {\r\n  const parentRoute = maybeParentRoutes[i]\r\n  if (!parentRoute) continue // 跳过已被删除的路由\r\n  \r\n  const parentFilePath = parentRoute.filePath.split('/').filter(item => !item.startsWith(':')).join('/')\r\n\r\n  for (let j = 0; j < childrenLength; j++) {\r\n    if (i === j) continue\r\n    const potentialChildRoute = maybeParentRoutes[j]\r\n    if (!potentialChildRoute) continue // 跳过已被删除的路由\r\n    \r\n    const potentialChildFilePath = potentialChildRoute.filePath.split('/').filter(item => !item.startsWith(':')).join('/')\r\n    \r\n    if (isChilrenRoute(parentFilePath, potentialChildFilePath)) {\r\n      if (!parentRoute.children) {\r\n        parentRoute.children = []\r\n      }\r\n      parentRoute.children.push({\r\n        ...potentialChildRoute,\r\n        filePath: potentialChildRoute.filePath.replace(parentRoute.filePath + '/', '')\r\n      })\r\n      maybeParentRoutes[j] = null // 标记为 null 而不是删除\r\n    }\r\n  }\r\n}\r\n\r\n// 过滤掉 null 值\r\nconst filteredRoutes = maybeParentRoutes.filter(route => route !== null)\r\n\r\n// 生成最终路由配置\r\nfunction generateRoutes(routesArray) {\r\n  const routes = []\r\n  for (const routeInfo of routesArray) {\r\n    routes.push(generateRoutesByRouteObj(routeInfo, []))\r\n  }\r\n  return routes\r\n}\r\n\r\nexport const routes = generateRoutes(filteredRoutes)\r\n`\r\n        return code\r\n      }\r\n    }\r\n  }\r\n}"],"names":["VIRTUAL_MODULE_ID","RESOLVED_VIRTUAL_MODULE_ID","options","pagesDir","name","configResolved","resolvedConfig","resolveId","id","load"],"mappings":"aAAA,MAAMA,EAAoB,sBACpBC,EAA6B,KAAOD,iBAE3B,SAA8BE,EAAU,IACrD,MAAMC,SAAEA,EAAW,aAAgBD,EAGnC,MAAO,CACLE,KAAM,0BAEN,cAAAC,CAAeC,GAEf,EAEA,SAAAC,CAAUC,GACR,GAAIA,IAAOR,EACT,OAAOC,CAEX,EAEA,IAAAQ,CAAKD,GACH,GAAIA,IAAOP,EAA4B,CAyLrC,MAnLa,68DAHO,IAAIE,+EACA,IAAIA,q6BAqGCA,sSAYEA,q6DAqEjC,CACF,EAEJ"}