{"version":3,"sources":["../../../node_modules/.pnpm/tsup@8.5.1_@microsoft+api-extractor@7.55.2_@types+node@25.0.3__jiti@2.6.1_postcss@8.5.22_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","../src/cli.ts","../src/sync.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n  typeof document === \"undefined\" \n    ? new URL(`file:${__filename}`).href \n    : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n      ? document.currentScript.src \n      : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","#!/usr/bin/env node\n\nimport type { FigmaIconsConfigFile } from './types'\nimport { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport process from 'node:process'\nimport { config as loadEnv } from 'dotenv'\nimport { createJiti } from 'jiti'\nimport { fetchAllIconsFromFigma, filterAndProcessIcons } from './sync'\n\n// 自动加载 .env.local 文件（如果存在）\nconst envPath = resolve(process.cwd(), '.env.local')\nif (existsSync(envPath)) {\n  loadEnv({ path: envPath })\n}\n\nconst colors = {\n  reset: '\\x1B[0m',\n  red: '\\x1B[31m',\n  green: '\\x1B[32m',\n  yellow: '\\x1B[33m',\n  cyan: '\\x1B[36m',\n}\n\nfunction log(message: string, color: keyof typeof colors = 'reset') {\n  console.log(`${colors[color]}${message}${colors.reset}`)\n}\n\nfunction showHelp() {\n  log('\\n📦 Figma Icons Sync - 从 Figma 同步图标到 Iconify JSON\\n', 'cyan')\n  log('用法:', 'cyan')\n  log('  figma-icons [options]\\n')\n\n  log('参数:', 'cyan')\n  log('  --config       配置文件路径 (默认: figma-icons.config.ts)')\n  log('  --force, -f    强制同步，跳过所有缓存')\n  log('  --help, -h     显示帮助\\n')\n\n  log('环境变量:', 'cyan')\n  log('  FIGMA_TOKEN    Figma API Token (必需)')\n  log('  FIGMA_FILE_ID  Figma 文件 ID (必需)\\n')\n\n  log('配置文件示例 (figma-icons.config.ts):', 'cyan')\n  log(`  import { defineConfig } from '@creatly/figma-icons'\n\n  export default defineConfig({\n    prefix: 'local',\n    output: 'json/icons.json',\n    collections: [\n      {\n        pages: ['Icons'],\n        convertToCurrentColor: true,\n      },\n      {\n        pages: ['Icons-Colored'],\n        convertToCurrentColor: false,\n      },\n    ],\n    depth: 4,\n  })\\n`, 'yellow')\n\n  log('使用方式:', 'cyan')\n  log('  1. 创建 .env.local 文件，添加 FIGMA_TOKEN 和 FIGMA_FILE_ID')\n  log('  2. 创建 figma-icons.config.ts 配置文件')\n  log('  3. 运行: figma-icons')\n  log('  4. 强制同步: figma-icons --force\\n')\n}\n\nasync function main() {\n  const args = process.argv.slice(2)\n\n  // 显示帮助\n  if (args.includes('--help') || args.includes('-h')) {\n    showHelp()\n    process.exit(0)\n  }\n\n  // 解析参数\n  function getArg(name: string, fallback?: string): string | undefined {\n    const index = args.indexOf(`--${name}`)\n    return index !== -1 && args[index + 1]\n      ? args[index + 1]\n      : fallback\n  }\n\n  // 检查是否强制同步（跳过缓存）\n  const force = args.includes('--force') || args.includes('-f')\n\n  // 获取环境变量\n  const fileId = process.env.FIGMA_FILE_ID\n  const token = process.env.FIGMA_TOKEN\n\n  // 验证必需的环境变量\n  if (!fileId || !token) {\n    log('❌ 缺少必需的环境变量\\n', 'red')\n    log('请设置以下环境变量:', 'yellow')\n    log('  FIGMA_FILE_ID  - Figma 文件 ID')\n    log('  FIGMA_TOKEN    - Figma API Token\\n')\n    log('使用方式: node --env-file=.env.local dist/cli.js\\n')\n    process.exit(1)\n  }\n\n  // 读取配置文件\n  const configArg = getArg('config', 'figma-icons.config.ts')\n  const configPath = configArg ?? 'figma-icons.config.ts'\n\n  // 尝试多个配置文件扩展名\n  const possiblePaths = [\n    resolve(process.cwd(), configPath),\n    resolve(process.cwd(), 'figma-icons.config.ts'),\n    resolve(process.cwd(), 'figma-icons.config.js'),\n    resolve(process.cwd(), 'figma-icons.config.json'),\n  ]\n\n  let configFilePath: string | undefined\n  for (const path of possiblePaths) {\n    if (existsSync(path)) {\n      configFilePath = path\n      break\n    }\n  }\n\n  if (!configFilePath) {\n    log(`❌ 无法找到配置文件\\n`, 'red')\n    log('尝试的路径:', 'yellow')\n    possiblePaths.forEach(p => log(`  - ${p}`))\n    log('\\n运行 figma-icons --help 查看配置文件示例\\n')\n    process.exit(1)\n  }\n\n  let config: FigmaIconsConfigFile\n\n  try {\n    // 使用 jiti 加载配置文件 (支持 .ts, .js, .json)\n    const jiti = createJiti(import.meta.url)\n    const loadedConfig = jiti(configFilePath)\n    config = loadedConfig.default || loadedConfig\n  }\n  catch (error) {\n    log(`❌ 无法加载配置文件: ${configFilePath}\\n`, 'red')\n    log('请确保配置文件格式正确\\n', 'yellow')\n    log('运行 figma-icons --help 查看配置文件示例\\n')\n    console.error(error)\n    process.exit(1)\n  }\n\n  // 验证配置文件\n  if (!config.collections || config.collections.length === 0) {\n    log('❌ 配置文件中没有定义任何图标集合\\n', 'red')\n    process.exit(1)\n  }\n\n  if (!config.prefix || !config.output) {\n    log('❌ 配置文件缺少必需的字段: prefix 或 output\\n', 'red')\n    process.exit(1)\n  }\n\n  log('🚀 开始同步图标...', 'cyan')\n  log(`📄 配置文件: ${configFilePath}`)\n  log(`📦 图标来源数量: ${config.collections.length}`)\n  log(`🎨 输出前缀: ${config.prefix}`)\n  log(`📁 输出文件: ${config.output}\\n`)\n\n  try {\n    // 收集所有需要的 pages\n    const allPages = [...new Set(config.collections.flatMap(c => c.pages))]\n\n    // 一次性从 Figma 获取所有图标（只调用一次 API）\n    log(`\\n📦 正在获取所有图标 (Pages: ${allPages.join(', ')})...`, 'cyan')\n    const fetchResult = await fetchAllIconsFromFigma({\n      fileId,\n      token,\n      prefix: config.prefix,\n      depth: config.depth ?? 2,\n      cacheDir: config.cacheDir ?? '.figma-cache',\n      excludeNodeIds: config.excludeNodeIds,\n      force,\n      allPages,\n    })\n\n    if (!fetchResult) {\n      log(`\\n✅ 图标未修改，无需更新`, 'green')\n      process.exit(0)\n    }\n\n    const { iconSet: allIconsSet, pageMap } = fetchResult\n\n    // 创建合并的 JSON 对象\n    const mergedJSON: any = {\n      prefix: config.prefix,\n      icons: {},\n      width: undefined,\n      height: undefined,\n    }\n\n    let totalIcons = 0\n\n    // 遍历所有集合，在本地过滤和处理图标\n    for (const collection of config.collections) {\n      log(`\\n📌 处理来源: Pages [${collection.pages.join(', ')}]`, 'cyan')\n      log(`   转换为 currentColor: ${collection.convertToCurrentColor ?? true}`)\n\n      // 过滤并处理当前 collection 的图标\n      const processedIconSet = await filterAndProcessIcons(\n        allIconsSet,\n        pageMap,\n        {\n          pages: collection.pages,\n          convertToCurrentColor: collection.convertToCurrentColor ?? true,\n        },\n      )\n\n      const iconCount = processedIconSet.count()\n      log(`   ✓ 处理 ${iconCount} 个图标`)\n\n      // 合并图标到 JSON\n      const iconSetJSON = processedIconSet.export()\n\n      // 保留图标的原始尺寸，不强制标准化\n      // 这样可以支持不同尺寸的图标（如 64x16 的品牌标识）\n      // 通过 CSS 控制显示大小，保持灵活性\n\n      // Iconify Tools 会省略默认值（如 height: 16），需要补全\n      for (const iconName in iconSetJSON.icons) {\n        const icon = iconSetJSON.icons[iconName]\n\n        // 如果有 width 但没有 height，根据 width 推断 height\n        // 对于非正方形图标（如 brand 64x16），需要明确设置 height\n        if (icon.width && !icon.height) {\n          // 默认假设是正方形，或者使用图标集的默认 height\n          icon.height = iconSetJSON.height || 16\n        }\n        // 如果有 height 但没有 width，同理\n        else if (icon.height && !icon.width) {\n          icon.width = iconSetJSON.width || 16\n        }\n      }\n\n      Object.assign(mergedJSON.icons, iconSetJSON.icons)\n\n      // 保存默认宽高 (如果还没设置的话)\n      if (mergedJSON.width === undefined && iconSetJSON.width) {\n        mergedJSON.width = iconSetJSON.width\n      }\n      if (mergedJSON.height === undefined && iconSetJSON.height) {\n        mergedJSON.height = iconSetJSON.height\n      }\n\n      totalIcons += iconCount\n    }\n\n    // 设置全局默认尺寸为 16x16\n    // 大部分图标都是这个尺寸，只有特殊图标（如 brand 64x16）会覆盖\n    // 这样可以减小 JSON 文件大小，符合 Iconify 最佳实践\n    mergedJSON.width = 16\n    mergedJSON.height = 16\n\n    // 导出合并后的 JSON\n    log(`\\n💾 导出图标集...`, 'cyan')\n    const { writeFile, mkdir } = await import('node:fs/promises')\n    const { dirname } = await import('node:path')\n\n    const outputPath = resolve(process.cwd(), config.output)\n    await mkdir(dirname(outputPath), { recursive: true })\n    await writeFile(\n      outputPath,\n      JSON.stringify(mergedJSON, null, 2),\n      'utf-8',\n    )\n\n    // 总结\n    log(`\\n${'='.repeat(50)}`, 'cyan')\n    log(`✅ 同步完成!`, 'green')\n    log(`📊 总计: ${totalIcons} 个图标`)\n    log(`📁 输出: ${config.output}`)\n    log(`${'='.repeat(50)}\\n`, 'cyan')\n  }\n  catch (error) {\n    log(`\\n❌ 同步失败:`, 'red')\n    console.error(error)\n    process.exit(1)\n  }\n}\n\nmain()\n","/* eslint-disable no-console */\nimport type { DocumentNotModified } from '@iconify/tools/lib/download/types/modified'\nimport type { FigmaImportNodeData } from '@iconify/tools/lib/import/figma/types/nodes'\nimport type { FigmaImportResult } from '@iconify/tools/lib/import/figma/types/result'\nimport type { FigmaIconsConfig, SyncResult } from './types'\nimport process from 'node:process'\nimport { cleanupSVG, IconSet, importFromFigma, isEmptyColor, parseColors, runSVGO } from '@iconify/tools'\n\ninterface IconNodeDetail {\n  nodeId: string\n  nodeName: string\n  pageName: string\n  path: string\n}\n\nfunction normalizeIconName(name: string): string {\n  return name\n    .toLowerCase()\n    .replace(/\\s+/g, '-')\n    .replace(/[^a-z0-9-]/g, '')\n}\n\nfunction isValidIconName(name: string): boolean {\n  return name.length > 0 && !name.startsWith('-')\n}\n\nfunction formatIconNameForLog(iconName: string): string {\n  return iconName || '(empty)'\n}\n\nfunction getNodeDetail(node: FigmaImportNodeData): IconNodeDetail {\n  const pageParent = node.parents.find(parent => parent.type === 'CANVAS')\n  const pageName = pageParent?.name ?? '(unknown-page)'\n  const path = [...node.parents.map(parent => parent.name), node.name].join(' / ')\n\n  return {\n    nodeId: node.id,\n    nodeName: node.name,\n    pageName,\n    path,\n  }\n}\n\nfunction collectIconNameDetail(\n  iconNameDetailsMap: Map<string, IconNodeDetail[]>,\n  iconName: string,\n  node: FigmaImportNodeData,\n): IconNodeDetail {\n  const detail = getNodeDetail(node)\n  const details = iconNameDetailsMap.get(iconName)\n\n  if (details) {\n    details.push(detail)\n  }\n  else {\n    iconNameDetailsMap.set(iconName, [detail])\n  }\n\n  return detail\n}\n\nfunction collectValidIconNameDetail(\n  iconNameDetailsMap: Map<string, IconNodeDetail[]>,\n  node: FigmaImportNodeData,\n): { iconName: string, detail: IconNodeDetail } | null {\n  const iconName = normalizeIconName(node.name)\n\n  if (!isValidIconName(iconName)) {\n    const detail = getNodeDetail(node)\n    console.log(`跳过非法图标名称: normalized=\"${formatIconNameForLog(iconName)}\" | Node=\"${detail.nodeName}\" | ID=${detail.nodeId} | Path=${detail.path}`)\n    return null\n  }\n\n  return {\n    iconName,\n    detail: collectIconNameDetail(iconNameDetailsMap, iconName, node),\n  }\n}\n\nfunction getDuplicateIconDetails(\n  iconNameDetailsMap: Map<string, IconNodeDetail[]>,\n): Array<[string, IconNodeDetail[]]> {\n  return [...iconNameDetailsMap.entries()]\n    .filter(([, details]) => details.length > 1)\n    .sort(([nameA], [nameB]) => nameA.localeCompare(nameB))\n}\n\nfunction formatDuplicateIconErrorMessage(\n  duplicateDetails: Array<[string, IconNodeDetail[]]>,\n): string {\n  const lines = [\n    `检测到 ${duplicateDetails.length} 组重名图标，已终止同步。`,\n    'Figma 允许重名，但同步时会按规范化名称生成 icon key（小写、空格转 -、移除特殊字符），重名会导致覆盖。',\n    '请在 Figma 中改为唯一名称后重试。',\n    '',\n    '重名明细：',\n  ]\n\n  for (const [iconName, details] of duplicateDetails) {\n    lines.push(`- \"${iconName}\" (${details.length} 个节点)`)\n    details.forEach((detail, index) => {\n      lines.push(`  ${index + 1}. Page=\"${detail.pageName}\" | Node=\"${detail.nodeName}\" | ID=${detail.nodeId} | Path=${detail.path}`)\n    })\n  }\n\n  return lines.join('\\n')\n}\n\nfunction assertNoDuplicateIconNames(iconNameDetailsMap: Map<string, IconNodeDetail[]>): void {\n  const duplicateDetails = getDuplicateIconDetails(iconNameDetailsMap)\n  if (!duplicateDetails.length) {\n    return\n  }\n  throw new Error(formatDuplicateIconErrorMessage(duplicateDetails))\n}\n\n/**\n * 从 Figma 获取所有图标\n * 只调用一次 API，返回完整的 iconSet 和 page 映射信息\n */\nexport async function fetchAllIconsFromFigma(\n  config: Omit<FigmaIconsConfig, 'pages' | 'convertToCurrentColor' | 'colorsToReplace'> & {\n    allPages: string[]\n  },\n): Promise<{ iconSet: IconSet, pageMap: Map<string, string> } | null> {\n  const {\n    fileId,\n    token,\n    prefix,\n    depth = 2,\n    cacheDir = '.figma-cache',\n    force = false,\n    allPages,\n    excludeNodeIds = [],\n  } = config\n  const excludedNodeIds = new Set(excludeNodeIds)\n\n  // 如果强制同步，先删除缓存目录\n  if (force) {\n    const { rm } = await import('node:fs/promises')\n    const { resolve } = await import('node:path')\n    const cachePath = resolve(process.cwd(), cacheDir)\n    try {\n      await rm(cachePath, { recursive: true, force: true })\n      console.log(`🗑️  已清除缓存目录: ${cacheDir}`)\n    }\n    catch (err) {\n      // 缓存目录不存在也没关系\n      console.error(`⚠️  清除缓存目录时出错: ${err}`)\n    }\n  }\n\n  // 如果强制同步，将缓存 TTL 设置为 0 以跳过缓存\n  const cacheAPITTL = force ? 0 : (config.cacheAPITTL ?? 1000 * 60 * 60 * 24 * 3) // 3 days\n  const cacheSVGTTL = force ? 0 : (config.cacheSVGTTL ?? 1000 * 60 * 60 * 24 * 30) // 30 days\n\n  console.log(`📦 从 Figma 获取图标 (一次性获取所有 pages)...`)\n  console.log(`   文件 ID: ${fileId}`)\n  console.log(`   前缀: ${prefix}`)\n  console.log(`   目标 Pages: ${allPages.join(', ')}`)\n  if (force) {\n    console.log(`   ⚠️  强制同步模式：已清除所有缓存`)\n  }\n\n  // 用于记录每个图标所属的 page\n  const pageMap = new Map<string, string>()\n  const iconNameDetailsMap = new Map<string, IconNodeDetail[]>()\n\n  // 从 Figma 导入所有图标\n  const result: FigmaImportResult | DocumentNotModified = await importFromFigma({\n    // 必需参数\n    file: fileId,\n    token,\n    prefix,\n\n    // 缓存配置\n    cacheDir,\n    cacheAPITTL,\n    cacheSVGTTL,\n\n    // 图标发现\n    depth,\n\n    // 获取所有图标，并记录它们所属的 page\n    iconNameForNode: (node) => {\n      if (excludedNodeIds.has(node.id)) {\n        console.log(`跳过已排除图标节点: Node=\"${node.name}\" | ID=${node.id}`)\n        return null\n      }\n\n      // 排除顶层容器本身（Icons 和 Icons-Colored 的 Frame 或 Section）\n      const hasContainerParent = node.parents.some(parent =>\n        parent.type === 'FRAME' || parent.type === 'SECTION',\n      )\n\n      if (!hasContainerParent) {\n        return null\n      }\n\n      // 查找图标所属的 page (CANVAS 类型的父节点)\n      const pageParent = node.parents.find(parent => parent.type === 'CANVAS')\n      if (!pageParent) {\n        return null\n      }\n\n      // 检查是否在目标 pages 中\n      if (allPages.length > 0 && !allPages.includes(pageParent.name)) {\n        return null\n      }\n\n      const iconDetail = collectValidIconNameDetail(iconNameDetailsMap, node)\n      if (!iconDetail) {\n        return null\n      }\n\n      const { iconName, detail } = iconDetail\n\n      // 记录图标所属的 page\n      if (!pageMap.has(iconName)) {\n        pageMap.set(iconName, detail.pageName)\n      }\n\n      return iconName\n    },\n  })\n\n  // 处理未修改的情况\n  if (typeof result === 'string') {\n    console.log('✅ 图标未修改，跳过')\n    return null\n  }\n\n  assertNoDuplicateIconNames(iconNameDetailsMap)\n\n  const { iconSet } = result\n  console.log(`📊 获取到 ${iconSet.count()} 个图标`)\n\n  return { iconSet, pageMap }\n}\n\n/**\n * 过滤并处理 IconSet 中的图标\n * 根据 pages 过滤，应用颜色转换和 SVG 优化\n */\nexport async function filterAndProcessIcons(\n  iconSet: IconSet,\n  pageMap: Map<string, string>,\n  options: {\n    convertToCurrentColor?: boolean\n    pages?: string[]\n  } = {},\n): Promise<IconSet> {\n  const { convertToCurrentColor = true, pages = [] } = options\n\n  // 创建一个新的 IconSet 用于存储过滤后的图标\n  const newIconSet = new IconSet({\n    prefix: iconSet.prefix,\n    icons: {},\n  })\n\n  await iconSet.forEach(async (name: string, type: string) => {\n    if (type !== 'icon') {\n      return\n    }\n\n    if (!isValidIconName(name)) {\n      return\n    }\n\n    // 根据 pages 过滤图标\n    if (pages.length > 0) {\n      const iconPage = pageMap.get(name)\n      if (!iconPage || !pages.includes(iconPage)) {\n        return\n      }\n    }\n\n    const svg = iconSet.toSVG(name)\n    if (!svg) {\n      return\n    }\n\n    try {\n      // 清理 SVG\n      cleanupSVG(svg)\n\n      // 先运行 SVGO 优化\n      runSVGO(svg)\n\n      // 然后处理颜色（在 SVGO 优化之后）\n      if (convertToCurrentColor) {\n        // 使用 Iconify 官方的 parseColors 函数处理颜色\n        parseColors(svg, {\n          defaultColor: 'currentColor',\n          callback: (_attr, colorStr, color) => {\n            // 如果颜色为空（如 fill=\"none\"），保持原样\n            if (!color || isEmptyColor(color)) {\n              return colorStr\n            }\n            // 将所有其他颜色转换为 currentColor\n            return 'currentColor'\n          },\n        })\n      }\n\n      // 将处理后的图标添加到新 IconSet\n      newIconSet.fromSVG(name, svg)\n    }\n    catch (err) {\n      console.error(`❌ 处理图标 ${name} 失败:`, err)\n    }\n  })\n\n  return newIconSet\n}\n\n/**\n * 从 Figma 同步图标\n */\nexport async function syncIconsFromFigma(\n  config: FigmaIconsConfig,\n): Promise<SyncResult> {\n  const {\n    fileId,\n    token,\n    prefix,\n    pages = [],\n    depth = 2,\n    convertToCurrentColor = true,\n    cacheDir = '.figma-cache',\n    force = false,\n    excludeNodeIds = [],\n  } = config\n  const excludedNodeIds = new Set(excludeNodeIds)\n\n  // 如果强制同步，先删除缓存目录\n  if (force) {\n    const { rm } = await import('node:fs/promises')\n    const { resolve } = await import('node:path')\n    const cachePath = resolve(process.cwd(), cacheDir)\n    try {\n      await rm(cachePath, { recursive: true, force: true })\n      console.log(`🗑️  已清除缓存目录: ${cacheDir}`)\n    }\n    catch (err) {\n      // 缓存目录不存在也没关系\n      console.error(`⚠️  清除缓存目录时出错: ${err}`)\n    }\n  }\n\n  // 如果强制同步，将缓存 TTL 设置为 0 以跳过缓存\n  const cacheAPITTL = force ? 0 : (config.cacheAPITTL ?? 1000 * 60 * 60 * 24 * 3) // 3 days\n  const cacheSVGTTL = force ? 0 : (config.cacheSVGTTL ?? 1000 * 60 * 60 * 24 * 30) // 30 days\n\n  console.log(`📦 开始从 Figma 同步图标...`)\n  console.log(`   文件 ID: ${fileId}`)\n  console.log(`   前缀: ${prefix}`)\n  if (pages.length > 0) {\n    console.log(`   Pages: ${pages.join(', ')}`)\n  }\n  if (force) {\n    console.log(`   ⚠️  强制同步模式：已清除所有缓存`)\n  }\n\n  const iconNameDetailsMap = new Map<string, IconNodeDetail[]>()\n\n  // 从 Figma 导入图标\n  const result: FigmaImportResult | DocumentNotModified = await importFromFigma({\n    // 必需参数\n    file: fileId,\n    token,\n    prefix,\n\n    // 图标识别\n    iconNameForNode: (node) => {\n      if (excludedNodeIds.has(node.id)) {\n        console.log(`跳过已排除图标节点: Node=\"${node.name}\" | ID=${node.id}`)\n        return null\n      }\n\n      // 如果指定了 pages 参数，只处理来自这些 Page 的图标\n      if (pages.length > 0) {\n        const isFromSpecifiedPage = node.parents.some(parent =>\n          parent.type === 'CANVAS' && pages.includes(parent.name),\n        )\n        if (!isFromSpecifiedPage) {\n          return null\n        }\n      }\n\n      // 排除顶层容器本身（Icons 和 Icons-Colored 的 Frame 或 Section）\n      // 检查是否有 Frame 或 Section 类型的父节点\n      const hasContainerParent = node.parents.some(parent =>\n        parent.type === 'FRAME' || parent.type === 'SECTION',\n      )\n\n      // 如果没有容器父节点，说明当前节点可能就是容器本身，需要排除\n      if (!hasContainerParent) {\n        return null\n      }\n\n      const iconDetail = collectValidIconNameDetail(iconNameDetailsMap, node)\n      return iconDetail?.iconName ?? null\n    },\n\n    // 缓存配置\n    cacheDir,\n    cacheAPITTL,\n    cacheSVGTTL,\n\n    // 文档检索\n    pages: pages.length > 0 ? pages : undefined,\n\n    // 图标发现\n    depth,\n\n    // 不过滤父节点，接受所有图标\n    // filterParentNode: undefined,\n  })\n\n  // 处理未修改的情况\n  if (typeof result === 'string') {\n    console.log('✅ 图标未修改，跳过')\n    return {\n      iconSet: null,\n      count: 0,\n      modified: false,\n      icons: [],\n    }\n  }\n\n  assertNoDuplicateIconNames(iconNameDetailsMap)\n\n  const { iconSet } = result\n\n  console.log(`📊 找到 ${iconSet.count()} 个图标`)\n\n  // 处理每个图标\n  await iconSet.forEach(async (name, type) => {\n    if (type !== 'icon')\n      return\n\n    if (!isValidIconName(name)) {\n      iconSet.remove(name)\n      return\n    }\n\n    const svg = iconSet.toSVG(name)\n    if (!svg) {\n      iconSet.remove(name)\n      return\n    }\n\n    try {\n      // 清理 SVG\n      cleanupSVG(svg)\n\n      // 先运行 SVGO 优化\n      runSVGO(svg)\n\n      // 然后处理颜色（在 SVGO 优化之后）\n      if (convertToCurrentColor) {\n        // 使用 Iconify 官方的 parseColors 函数处理颜色\n        // 这会自动：\n        // 1. 转换已有的颜色为 currentColor\n        // 2. 为没有颜色的元素添加 defaultColor\n        parseColors(svg, {\n          defaultColor: 'currentColor',\n          callback: (_attr, colorStr, color) => {\n            // 如果颜色为空（如 fill=\"none\"），保持原样\n            if (!color || isEmptyColor(color)) {\n              return colorStr\n            }\n            // 将所有其他颜色转换为 currentColor\n            return 'currentColor'\n          },\n        })\n      }\n\n      // 从 SVG 对象更新图标数据（包括颜色更改）\n      iconSet.fromSVG(name, svg)\n    }\n    catch (err) {\n      console.error(`❌ 处理图标 ${name} 失败:`, err)\n      iconSet.remove(name)\n    }\n  })\n\n  const icons = iconSet.list()\n  console.log(`✅ 成功处理 ${icons.length} 个图标`)\n\n  return {\n    iconSet,\n    count: icons.length,\n    modified: true,\n    icons,\n  }\n}\n"],"mappings":"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","names":["import_node_process","resolve","process","process","loadEnv"]}