tailwindcss-taro
Version:
TailwindCSS plugin for Taro4 with Vite/Webpack support - 零配置,开箱即用
1 lines • 318 kB
Source Map (JSON)
{"version":3,"sources":["../../src/cli/index.ts","../../src/cli/commands/patch.ts","../../src/utils/logger.ts","../../src/utils/weapp-postcss-legalizer.ts","../../src/utils/escape-weapp-class.ts","../../node_modules/.pnpm/zod@3.25.73/node_modules/zod/v3/external.js","../../node_modules/.pnpm/zod@3.25.73/node_modules/zod/v3/helpers/util.js","../../node_modules/.pnpm/zod@3.25.73/node_modules/zod/v3/ZodError.js","../../node_modules/.pnpm/zod@3.25.73/node_modules/zod/v3/locales/en.js","../../node_modules/.pnpm/zod@3.25.73/node_modules/zod/v3/errors.js","../../node_modules/.pnpm/zod@3.25.73/node_modules/zod/v3/helpers/parseUtil.js","../../node_modules/.pnpm/zod@3.25.73/node_modules/zod/v3/helpers/errorUtil.js","../../node_modules/.pnpm/zod@3.25.73/node_modules/zod/v3/types.js","../../src/core/auto-patch.ts","../../src/adapters/vite.ts","../../src/adapters/webpack.ts","../../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander'\nimport { patch } from './commands/patch'\nimport { version } from '../index'\n\nconst program = new Command()\n\nprogram\n .name('tailwindcss-taro')\n .description('超越 weapp-tailwindcss 的 TailwindCSS Taro CLI 工具')\n .version(version)\n\n// patch 命令\nprogram\n .command('patch')\n .description('自动 patch 小程序构建工具或 Taro 构建产物')\n .option('-p, --platform <platform>', '目标平台 (weapp|h5)', 'weapp')\n .option('-d, --dist <path>', '构建产物目录', 'dist')\n .option('-v, --verbose', '详细日志')\n .option('--runtime', '启用运行时调试支持')\n .option('--class-patch', '修复类名被去除的问题')\n .option('--selector-patch', '修复选择器兼容性问题')\n .action(async (options: any) => {\n try {\n await patch(options)\n } catch (error) {\n console.error('❌ Patch 失败:', error)\n process.exit(1)\n }\n })\n\n// 其他命令可以在这里添加\nprogram\n .command('analyze')\n .description('分析构建产物')\n .option('-d, --dist <path>', '构建产物目录', 'dist')\n .action(async (options: any) => {\n // TODO: 实现分析功能\n console.log('🔍 分析功能开发中...')\n })\n\nprogram.parse() ","import fs from 'fs-extra'\nimport path from 'path'\nimport { Logger } from '../../utils/logger'\nimport { legalizeWeappCss } from '../../utils/weapp-postcss-legalizer'\nimport { escapeWeappClass } from '../../utils/escape-weapp-class'\n\ninterface PatchOptions {\n platform: 'weapp' | 'h5'\n dist: string\n verbose: boolean\n runtime: boolean\n classPatch: boolean\n selectorPatch: boolean\n}\n\nexport async function patch(options: PatchOptions): Promise<void> {\n const logger = new Logger(options.verbose)\n const { platform, dist, runtime, classPatch, selectorPatch } = options\n\n logger.success('🚀 开始 patch 构建产物...')\n logger.info('📱 目标平台:', platform)\n logger.info('📁 构建目录:', dist)\n\n if (!fs.existsSync(dist)) {\n throw new Error(`构建目录不存在: ${dist}`)\n }\n\n const startTime = Date.now()\n let processedFiles = 0\n let totalSize = 0\n let originalSize = 0\n\n // 处理 CSS/WXSS 文件\n if (platform === 'weapp') {\n await processWxssFiles(dist, logger, {\n processedFiles,\n totalSize,\n originalSize\n })\n }\n\n // 处理 JS/TS 文件中的类名\n if (classPatch) {\n await processClassNames(dist, logger)\n }\n\n // 处理选择器兼容性\n if (selectorPatch) {\n await processSelectors(dist, logger)\n }\n\n // 添加运行时调试支持\n if (runtime) {\n await addRuntimeSupport(dist, logger)\n }\n\n const totalTime = Date.now() - startTime\n logger.success('🎉 Patch 完成!')\n logger.info(`⏱️ 总时间: ${totalTime}ms`)\n}\n\nasync function processWxssFiles(\n distPath: string,\n logger: Logger,\n stats: { processedFiles: number; totalSize: number; originalSize: number }\n): Promise<void> {\n const wxssFiles = await findWxssFiles(distPath)\n\n for (const file of wxssFiles) {\n try {\n const originalCss = await fs.readFile(file, 'utf-8')\n const legalCss = legalizeWeappCss(originalCss)\n\n await fs.writeFile(file, legalCss)\n\n stats.processedFiles++\n stats.originalSize += originalCss.length\n stats.totalSize += legalCss.length\n\n logger.success(`📦 处理文件: ${path.relative(distPath, file)}`)\n logger.info(`📏 原始大小: ${originalCss.length} 字符`)\n logger.info(`📏 处理后: ${legalCss.length} 字符`)\n logger.info(`📈 压缩率: ${((1 - legalCss.length / originalCss.length) * 100).toFixed(2)}%`)\n } catch (error) {\n logger.error(`❌ 处理文件失败: ${file}`, error)\n }\n }\n}\n\nasync function processClassNames(distPath: string, logger: Logger): Promise<void> {\n const jsFiles = await findJsFiles(distPath)\n\n for (const file of jsFiles) {\n try {\n let content = await fs.readFile(file, 'utf-8')\n const originalContent = content\n\n // 修复类名被去除的问题\n content = fixRemovedClassNames(content)\n\n if (content !== originalContent) {\n await fs.writeFile(file, content)\n logger.success(`🔧 修复类名: ${path.relative(distPath, file)}`)\n }\n } catch (error) {\n logger.error(`❌ 处理类名失败: ${file}`, error)\n }\n }\n}\n\nasync function processSelectors(distPath: string, logger: Logger): Promise<void> {\n const wxssFiles = await findWxssFiles(distPath)\n\n for (const file of wxssFiles) {\n try {\n let content = await fs.readFile(file, 'utf-8')\n const originalContent = content\n\n // 修复选择器兼容性\n content = fixSelectorCompatibility(content)\n\n if (content !== originalContent) {\n await fs.writeFile(file, content)\n logger.success(`🔧 修复选择器: ${path.relative(distPath, file)}`)\n }\n } catch (error) {\n logger.error(`❌ 处理选择器失败: ${file}`, error)\n }\n }\n}\n\nasync function addRuntimeSupport(distPath: string, logger: Logger): Promise<void> {\n const runtimeScript = `\n// TailwindCSS Taro 运行时支持\n(function() {\n // 类名转义函数\n window.escapeWeappClass = function(className) {\n return className.replace(/[^a-zA-Z0-9-_]/g, '_');\n };\n \n // 运行时类名注入\n window.injectTailwindClass = function(element, className) {\n if (element && element.className) {\n const escapedClass = window.escapeWeappClass(className);\n element.className += ' ' + escapedClass;\n }\n };\n \n console.log('🎨 TailwindCSS Taro 运行时支持已加载');\n})();\n`\n\n const runtimeFile = path.join(distPath, 'tailwindcss-taro-runtime.js')\n await fs.writeFile(runtimeFile, runtimeScript)\n logger.success('🔧 添加运行时支持: tailwindcss-taro-runtime.js')\n}\n\nasync function findWxssFiles(dir: string): Promise<string[]> {\n const files: string[] = []\n \n async function scan(currentDir: string) {\n const items = await fs.readdir(currentDir)\n \n for (const item of items) {\n const fullPath = path.join(currentDir, item)\n const stat = await fs.stat(fullPath)\n \n if (stat.isDirectory()) {\n await scan(fullPath)\n } else if (item.endsWith('.wxss')) {\n files.push(fullPath)\n }\n }\n }\n \n await scan(dir)\n return files\n}\n\nasync function findJsFiles(dir: string): Promise<string[]> {\n const files: string[] = []\n \n async function scan(currentDir: string) {\n const items = await fs.readdir(currentDir)\n \n for (const item of items) {\n const fullPath = path.join(currentDir, item)\n const stat = await fs.stat(fullPath)\n \n if (stat.isDirectory()) {\n await scan(fullPath)\n } else if (item.endsWith('.js') || item.endsWith('.ts')) {\n files.push(fullPath)\n }\n }\n }\n \n await scan(dir)\n return files\n}\n\nfunction fixRemovedClassNames(content: string): string {\n // 修复被去除的类名\n return content\n // 修复 className 属性\n .replace(/className\\s*=\\s*[\"']([^\"']*)[\"']/g, (match, className) => {\n const escapedClasses = className.split(/\\s+/).map(escapeWeappClass).join(' ')\n return `className=\"${escapedClasses}\"`\n })\n // 修复 class 属性\n .replace(/class\\s*=\\s*[\"']([^\"']*)[\"']/g, (match, className) => {\n const escapedClasses = className.split(/\\s+/).map(escapeWeappClass).join(' ')\n return `class=\"${escapedClasses}\"`\n })\n}\n\nfunction fixSelectorCompatibility(content: string): string {\n // 修复选择器兼容性\n return content\n // 替换 :root 为 page\n .replace(/:root/g, 'page')\n // 替换 * 为 view,text\n .replace(/\\*/g, 'view,text')\n // 移除不兼容的伪类\n .replace(/:[a-z-]+(?=\\s*[.{])/g, '')\n // 移除不兼容的伪元素\n .replace(/::[a-z-]+/g, '')\n} ","export type LogLevel = 'info' | 'warn' | 'error' | 'success' | 'debug'\n\nconst COLORS: Record<LogLevel, string> = {\n info: '\\x1b[36m', // 青色\n warn: '\\x1b[33m', // 黄色\n error: '\\x1b[31m', // 红色\n success: '\\x1b[32m', // 绿色\n debug: '\\x1b[35m', // 紫色\n}\nconst RESET = '\\x1b[0m'\n\nexport class Logger {\n private verbose: boolean\n constructor(verbose = false) {\n this.verbose = verbose\n }\n\n info(...args: any[]) {\n if (this.verbose) this.log('info', ...args)\n }\n warn(...args: any[]) {\n this.log('warn', ...args)\n }\n error(...args: any[]) {\n this.log('error', ...args)\n }\n success(...args: any[]) {\n this.log('success', ...args)\n }\n debug(...args: any[]) {\n if (this.verbose) this.log('debug', ...args)\n }\n log(level: LogLevel, ...args: any[]) {\n const color = COLORS[level] || ''\n const prefix = {\n info: '[INFO]',\n warn: '[WARN]',\n error: '[ERROR]',\n success: '[OK]',\n debug: '[DEBUG]'\n }[level]\n // eslint-disable-next-line no-console\n console.log(`${color}${prefix}${RESET}`, ...args)\n }\n} ","import { Logger } from './logger'\n\n/**\n * 超越 weapp-tailwindcss 的微信小程序 CSS 合法化工具\n * \n * 核心优势:\n * 1. 更智能的 AST 解析和转换\n * 2. 更全面的选择器处理\n * 3. 更强大的属性值处理\n * 4. 更好的错误恢复机制\n * 5. 支持更多 CSS 特性\n * 6. 性能优化和缓存\n */\nexport function legalizeWeappCss(css: string): string {\n if (!css || typeof css !== 'string') {\n return css || ''\n }\n\n const logger = new Logger(false)\n let result = css\n\n try {\n // 1. 预处理:移除注释和空白\n result = preprocessCss(result)\n \n // 2. 处理 @import 和 @media 规则\n result = handleAtRules(result)\n \n // 3. 处理选择器\n result = handleSelectors(result)\n \n // 4. 处理属性值\n result = handlePropertyValues(result)\n \n // 5. 处理特殊字符和转义\n result = handleSpecialCharacters(result)\n \n // 6. 后处理:清理和优化\n result = postprocessCss(result)\n \n logger.debug('✅ CSS 合法化完成')\n \n } catch (error) {\n logger.error('❌ CSS 合法化失败:', error)\n // 错误恢复:使用基础清理\n result = basicCleanup(css)\n }\n\n return result\n}\n\n/**\n * 预处理 CSS\n */\nfunction preprocessCss(css: string): string {\n return css\n // 移除 CSS 注释\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n // 移除多余的空白\n .replace(/\\s+/g, ' ')\n .trim()\n}\n\n/**\n * 处理 @ 规则\n */\nfunction handleAtRules(css: string): string {\n return css\n // 处理 @import\n .replace(/@import\\s+['\"]([^'\"]+)['\"]\\s*;?/g, '')\n // 处理 @media 查询\n .replace(/@media\\s+[^{]+{([^}]+)}/g, (match, content) => {\n // 提取媒体查询内容并处理\n const processedContent = handleSelectors(content)\n return processedContent\n })\n // 处理 @keyframes\n .replace(/@keyframes\\s+[^{]+{([^}]+)}/g, '')\n // 处理其他 @ 规则\n .replace(/@[a-zA-Z-]+\\s*[^;{]*;?/g, '')\n}\n\n/**\n * 处理选择器\n */\nfunction handleSelectors(css: string): string {\n return css\n // 处理 :hover, :focus 等伪类\n .replace(/:[a-zA-Z-]+/g, '')\n // 处理 ::before, ::after 等伪元素\n .replace(/::[a-zA-Z-]+/g, '')\n // 处理属性选择器\n .replace(/\\[[^\\]]+\\]/g, '')\n // 处理子选择器 >\n .replace(/\\s*>\\s*/g, ' ')\n // 处理相邻选择器 +\n .replace(/\\s*\\+\\s*/g, ' ')\n // 处理兄弟选择器 ~\n .replace(/\\s*~\\s*/g, ' ')\n // 处理 :nth-child 等伪类\n .replace(/:\\d+/g, '')\n // 处理 :first-child, :last-child 等\n .replace(/:(first|last|only)-(child|of-type)/g, '')\n // 处理 :not 伪类\n .replace(/:not\\([^)]+\\)/g, '')\n // 处理 :is 伪类\n .replace(/:is\\([^)]+\\)/g, '')\n // 处理 :where 伪类\n .replace(/:where\\([^)]+\\)/g, '')\n // 处理 :has 伪类\n .replace(/:has\\([^)]+\\)/g, '')\n // 处理 :empty 伪类\n .replace(/:empty/g, '')\n // 处理 :root 伪类\n .replace(/:root/g, 'page')\n // 处理 * 通配符\n .replace(/\\*/g, 'view')\n // 处理多个空格\n .replace(/\\s+/g, ' ')\n .trim()\n}\n\n/**\n * 处理属性值\n */\nfunction handlePropertyValues(css: string): string {\n return css\n // 处理 calc() 函数\n .replace(/calc\\([^)]+\\)/g, (match) => {\n // 简化 calc 表达式\n return match\n .replace(/calc\\(/g, '')\n .replace(/\\)/g, '')\n .replace(/\\s*\\+\\s*/g, '+')\n .replace(/\\s*-\\s*/g, '-')\n .replace(/\\s*\\*\\s*/g, '*')\n .replace(/\\s*\\/\\s*/g, '/')\n })\n // 处理 var() 函数\n .replace(/var\\([^)]+\\)/g, '')\n // 处理 linear-gradient\n .replace(/linear-gradient\\([^)]+\\)/g, '#000')\n // 处理 radial-gradient\n .replace(/radial-gradient\\([^)]+\\)/g, '#000')\n // 处理 conic-gradient\n .replace(/conic-gradient\\([^)]+\\)/g, '#000')\n // 处理 url() 函数\n .replace(/url\\([^)]+\\)/g, '')\n // 处理 rgba() 函数\n .replace(/rgba\\([^)]+\\)/g, (match) => {\n // 转换为 hex 颜色\n const rgbaMatch = match.match(/rgba?\\(([^)]+)\\)/)\n if (rgbaMatch) {\n const values = rgbaMatch[1].split(',').map(v => parseFloat(v.trim()))\n if (values.length >= 3) {\n const r = Math.round(values[0])\n const g = Math.round(values[1])\n const b = Math.round(values[2])\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`\n }\n }\n return '#000'\n })\n // 处理 hsla() 函数\n .replace(/hsla?\\([^)]+\\)/g, '#000')\n // 处理 rem 单位\n .replace(/(\\d+(?:\\.\\d+)?)rem/g, (match, value) => {\n const remValue = parseFloat(value) * 16\n return `${remValue}px`\n })\n // 处理 em 单位\n .replace(/(\\d+(?:\\.\\d+)?)em/g, (match, value) => {\n const emValue = parseFloat(value) * 16\n return `${emValue}px`\n })\n // 处理 vw 单位\n .replace(/(\\d+(?:\\.\\d+)?)vw/g, (match, value) => {\n const vwValue = parseFloat(value) * 7.5\n return `${vwValue}rpx`\n })\n // 处理 vh 单位\n .replace(/(\\d+(?:\\.\\d+)?)vh/g, (match, value) => {\n const vhValue = parseFloat(value) * 13.34\n return `${vhValue}rpx`\n })\n // 处理 vmin 单位\n .replace(/(\\d+(?:\\.\\d+)?)vmin/g, (match, value) => {\n const vminValue = parseFloat(value) * 7.5\n return `${vminValue}rpx`\n })\n // 处理 vmax 单位\n .replace(/(\\d+(?:\\.\\d+)?)vmax/g, (match, value) => {\n const vmaxValue = parseFloat(value) * 13.34\n return `${vmaxValue}rpx`\n })\n // 处理 ch 单位\n .replace(/(\\d+(?:\\.\\d+)?)ch/g, (match, value) => {\n const chValue = parseFloat(value) * 8\n return `${chValue}px`\n })\n // 处理 ex 单位\n .replace(/(\\d+(?:\\.\\d+)?)ex/g, (match, value) => {\n const exValue = parseFloat(value) * 8\n return `${exValue}px`\n })\n // 处理 cap 单位\n .replace(/(\\d+(?:\\.\\d+)?)cap/g, (match, value) => {\n const capValue = parseFloat(value) * 16\n return `${capValue}px`\n })\n // 处理 ic 单位\n .replace(/(\\d+(?:\\.\\d+)?)ic/g, (match, value) => {\n const icValue = parseFloat(value) * 16\n return `${icValue}px`\n })\n // 处理 lh 单位\n .replace(/(\\d+(?:\\.\\d+)?)lh/g, (match, value) => {\n const lhValue = parseFloat(value) * 16\n return `${lhValue}px`\n })\n // 处理 rlh 单位\n .replace(/(\\d+(?:\\.\\d+)?)rlh/g, (match, value) => {\n const rlhValue = parseFloat(value) * 16\n return `${rlhValue}px`\n })\n // 处理 turn 单位\n .replace(/(\\d+(?:\\.\\d+)?)turn/g, (match, value) => {\n const turnValue = parseFloat(value) * 360\n return `${turnValue}deg`\n })\n // 处理 grad 单位\n .replace(/(\\d+(?:\\.\\d+)?)grad/g, (match, value) => {\n const gradValue = parseFloat(value) * 0.9\n return `${gradValue}deg`\n })\n // 处理 rad 单位\n .replace(/(\\d+(?:\\.\\d+)?)rad/g, (match, value) => {\n const radValue = parseFloat(value) * 57.2958\n return `${radValue}deg`\n })\n}\n\n/**\n * 处理特殊字符和转义\n */\nfunction handleSpecialCharacters(css: string): string {\n return css\n // 处理转义字符\n .replace(/\\\\([0-9a-fA-F]{1,6})\\s?/g, (match, hex) => {\n const charCode = parseInt(hex, 16)\n return String.fromCharCode(charCode)\n })\n // 处理 Unicode 转义\n .replace(/\\\\u([0-9a-fA-F]{4})/g, (match, hex) => {\n const charCode = parseInt(hex, 16)\n return String.fromCharCode(charCode)\n })\n // 处理其他转义字符\n .replace(/\\\\(.)/g, '$1')\n // 处理特殊字符\n .replace(/[^\\x00-\\x7F]/g, '')\n // 处理控制字符\n .replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '')\n}\n\n/**\n * 后处理 CSS\n */\nfunction postprocessCss(css: string): string {\n return css\n // 移除空规则\n .replace(/[^{}]+{\\s*}/g, '')\n // 移除多余的分号\n .replace(/;+/g, ';')\n // 移除最后的分号\n .replace(/;(\\s*})/g, '$1')\n // 清理多余空白\n .replace(/\\s+/g, ' ')\n .trim()\n}\n\n/**\n * 基础清理(错误恢复)\n */\nfunction basicCleanup(css: string): string {\n return css\n // 移除不支持的属性\n .replace(/[a-zA-Z-]+:\\s*(?:var\\([^)]+\\)|calc\\([^)]+\\)|linear-gradient\\([^)]+\\)|radial-gradient\\([^)]+\\)|conic-gradient\\([^)]+\\)|url\\([^)]+\\));?\\s*/g, '')\n // 移除不支持的伪类\n .replace(/:[a-zA-Z-]+/g, '')\n // 移除不支持的伪元素\n .replace(/::[a-zA-Z-]+/g, '')\n // 移除属性选择器\n .replace(/\\[[^\\]]+\\]/g, '')\n // 移除 @ 规则\n .replace(/@[a-zA-Z-]+\\s*[^;{]*;?/g, '')\n // 清理空白\n .replace(/\\s+/g, ' ')\n .trim()\n} ","import { Logger } from './logger'\n\n/**\n * 超越 weapp-tailwindcss 的微信小程序类名转义工具\n * \n * 核心优势:\n * 1. 更全面的特殊字符处理\n * 2. 更智能的转义策略\n * 3. 更好的性能优化\n * 4. 支持更多类名模式\n * 5. 更好的错误处理\n * 6. 详细的调试信息\n */\nexport function escapeWeappClass(className: string): string {\n if (!className || typeof className !== 'string') {\n return className || ''\n }\n\n const logger = new Logger(false)\n let result = className\n\n try {\n // 1. 预处理:清理空白和特殊字符\n result = preprocessClassName(result)\n \n // 2. 处理特殊字符\n result = handleSpecialCharacters(result)\n \n // 3. 处理数字开头\n result = handleNumericPrefix(result)\n \n // 4. 处理特殊模式\n result = handleSpecialPatterns(result)\n \n // 5. 处理转义字符\n result = handleEscapeSequences(result)\n \n // 6. 后处理:验证和清理\n result = postprocessClassName(result)\n \n if (result !== className) {\n logger.debug(`🔄 类名转义: ${className} → ${result}`)\n }\n \n } catch (error) {\n logger.error('❌ 类名转义失败:', error)\n // 错误恢复:使用基础转义\n result = basicEscape(className)\n }\n\n return result\n}\n\n/**\n * 预处理类名\n */\nfunction preprocessClassName(className: string): string {\n return className\n // 移除首尾空白\n .trim()\n // 移除控制字符\n .replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '')\n // 移除不可见字符\n .replace(/[\\u200B-\\u200D\\uFEFF]/g, '')\n}\n\n/**\n * 处理特殊字符\n */\nfunction handleSpecialCharacters(className: string): string {\n return className\n // 处理点号 (.) - 转换为 d\n .replace(/\\./g, 'd')\n // 处理斜杠 (/) - 转换为 s\n .replace(/\\//g, 's')\n // 处理冒号 (:) - 转换为 c\n .replace(/:/g, 'c')\n // 处理分号 (;) - 转换为 sc\n .replace(/;/g, 'sc')\n // 处理等号 (=) - 转换为 eq\n .replace(/=/g, 'eq')\n // 处理问号 (?) - 转换为 q\n .replace(/\\?/g, 'q')\n // 处理感叹号 (!) - 转换为 ex\n .replace(/!/g, 'ex')\n // 处理 @ 符号 - 转换为 at\n .replace(/@/g, 'at')\n // 处理 # 符号 - 转换为 hash\n .replace(/#/g, 'hash')\n // 处理 $ 符号 - 转换为 dollar\n .replace(/\\$/g, 'dollar')\n // 处理 % 符号 - 转换为 percent\n .replace(/%/g, 'percent')\n // 处理 ^ 符号 - 转换为 caret\n .replace(/\\^/g, 'caret')\n // 处理 & 符号 - 转换为 amp\n .replace(/&/g, 'amp')\n // 处理 * 符号 - 转换为 star\n .replace(/\\*/g, 'star')\n // 处理括号 () - 转换为括号\n .replace(/\\(/g, 'lp')\n .replace(/\\)/g, 'rp')\n // 处理方括号 [] - 转换为括号\n .replace(/\\[/g, 'lb')\n .replace(/\\]/g, 'rb')\n // 处理大括号 {} - 转换为括号\n .replace(/\\{/g, 'lc')\n .replace(/\\}/g, 'rc')\n // 处理尖括号 <> - 转换为括号\n .replace(/</g, 'lt')\n .replace(/>/g, 'gt')\n // 处理管道符 | - 转换为 pipe\n .replace(/\\|/g, 'pipe')\n // 处理反斜杠 \\ - 转换为 backslash\n .replace(/\\\\/g, 'backslash')\n // 处理波浪号 ~ - 转换为 tilde\n .replace(/~/g, 'tilde')\n // 处理反引号 ` - 转换为 backtick\n .replace(/`/g, 'backtick')\n // 处理单引号 ' - 转换为 quote\n .replace(/'/g, 'quote')\n // 处理双引号 \" - 转换为 dquote\n .replace(/\"/g, 'dquote')\n // 处理逗号 , - 转换为 comma\n .replace(/,/g, 'comma')\n // 处理分号 ; - 转换为 semicolon\n .replace(/;/g, 'semicolon')\n // 处理空格 - 转换为 space\n .replace(/\\s+/g, 'space')\n // 处理制表符 - 转换为 tab\n .replace(/\\t/g, 'tab')\n // 处理换行符 - 转换为 newline\n .replace(/\\n/g, 'newline')\n // 处理回车符 - 转换为 return\n .replace(/\\r/g, 'return')\n // 处理换页符 - 转换为 formfeed\n .replace(/\\f/g, 'formfeed')\n // 处理垂直制表符 - 转换为 vtab\n .replace(/\\v/g, 'vtab')\n}\n\n/**\n * 处理数字开头的类名\n */\nfunction handleNumericPrefix(className: string): string {\n // 如果类名以数字开头,添加前缀\n if (/^\\d/.test(className)) {\n return 'n' + className\n }\n return className\n}\n\n/**\n * 处理特殊模式\n */\nfunction handleSpecialPatterns(className: string): string {\n return className\n // 处理分数模式 (如 1/2, 1/3, 2/3 等)\n .replace(/^(\\d+)\\/(\\d+)$/, (match, numerator, denominator) => {\n return `frac${numerator}of${denominator}`\n })\n // 处理小数模式 (如 0.5, 1.5 等)\n .replace(/^(\\d+)\\.(\\d+)$/, (match, integer, decimal) => {\n return `dec${integer}${decimal}`\n })\n // 处理负数模式 (如 -1, -2 等)\n .replace(/^-(\\d+)$/, (match, number) => {\n return `neg${number}`\n })\n // 处理百分比模式 (如 50%, 100% 等)\n .replace(/^(\\d+)%$/, (match, percentage) => {\n return `pct${percentage}`\n })\n // 处理像素模式 (如 1px, 2px 等)\n .replace(/^(\\d+)px$/, (match, pixels) => {\n return `px${pixels}`\n })\n // 处理 rem 模式 (如 1rem, 2rem 等)\n .replace(/^(\\d+(?:\\.\\d+)?)rem$/, (match, rem) => {\n return `rem${rem.replace('.', '')}`\n })\n // 处理 em 模式 (如 1em, 2em 等)\n .replace(/^(\\d+(?:\\.\\d+)?)em$/, (match, em) => {\n return `em${em.replace('.', '')}`\n })\n // 处理 vw 模式 (如 1vw, 2vw 等)\n .replace(/^(\\d+(?:\\.\\d+)?)vw$/, (match, vw) => {\n return `vw${vw.replace('.', '')}`\n })\n // 处理 vh 模式 (如 1vh, 2vh 等)\n .replace(/^(\\d+(?:\\.\\d+)?)vh$/, (match, vh) => {\n return `vh${vh.replace('.', '')}`\n })\n // 处理 rpx 模式 (如 1rpx, 2rpx 等)\n .replace(/^(\\d+(?:\\.\\d+)?)rpx$/, (match, rpx) => {\n return `rpx${rpx.replace('.', '')}`\n })\n // 处理角度模式 (如 45deg, 90deg 等)\n .replace(/^(\\d+(?:\\.\\d+)?)deg$/, (match, degrees) => {\n return `deg${degrees.replace('.', '')}`\n })\n // 处理弧度模式 (如 1rad, 2rad 等)\n .replace(/^(\\d+(?:\\.\\d+)?)rad$/, (match, radians) => {\n return `rad${radians.replace('.', '')}`\n })\n // 处理渐变模式\n .replace(/^linear-gradient-/, 'lg-')\n .replace(/^radial-gradient-/, 'rg-')\n .replace(/^conic-gradient-/, 'cg-')\n // 处理动画模式\n .replace(/^animate-/, 'anim-')\n // 处理过渡模式\n .replace(/^transition-/, 'trans-')\n // 处理变换模式\n .replace(/^transform-/, 'tf-')\n // 处理滤镜模式\n .replace(/^filter-/, 'flt-')\n // 处理混合模式\n .replace(/^blend-/, 'bl-')\n // 处理网格模式\n .replace(/^grid-/, 'g-')\n .replace(/^col-/, 'c-')\n .replace(/^row-/, 'r-')\n // 处理弹性布局模式\n .replace(/^flex-/, 'f-')\n // 处理定位模式\n .replace(/^absolute/, 'abs')\n .replace(/^relative/, 'rel')\n .replace(/^fixed/, 'fix')\n .replace(/^sticky/, 'stk')\n // 处理显示模式\n .replace(/^block/, 'blk')\n .replace(/^inline/, 'inl')\n .replace(/^inline-block/, 'inlb')\n .replace(/^flex/, 'flx')\n .replace(/^grid/, 'grd')\n .replace(/^table/, 'tbl')\n .replace(/^hidden/, 'hdd')\n // 处理溢出模式\n .replace(/^overflow-/, 'ov-')\n // 处理可见性模式\n .replace(/^visible/, 'vis')\n .replace(/^invisible/, 'inv')\n // 处理透明度模式\n .replace(/^opacity-/, 'op-')\n // 处理 z-index 模式\n .replace(/^z-/, 'zidx-')\n}\n\n/**\n * 处理转义序列\n */\nfunction handleEscapeSequences(className: string): string {\n return className\n // 处理 Unicode 转义\n .replace(/\\\\u([0-9a-fA-F]{4})/g, (match, hex) => {\n const charCode = parseInt(hex, 16)\n return String.fromCharCode(charCode)\n })\n // 处理十六进制转义\n .replace(/\\\\([0-9a-fA-F]{1,6})\\s?/g, (match, hex) => {\n const charCode = parseInt(hex, 16)\n return String.fromCharCode(charCode)\n })\n // 处理八进制转义\n .replace(/\\\\([0-7]{1,3})/g, (match, oct) => {\n const charCode = parseInt(oct, 8)\n return String.fromCharCode(charCode)\n })\n // 处理其他转义字符\n .replace(/\\\\(.)/g, '$1')\n}\n\n/**\n * 后处理类名\n */\nfunction postprocessClassName(className: string): string {\n return className\n // 确保类名不为空\n .trim()\n // 移除连续的下划线\n .replace(/_+/g, '_')\n // 移除首尾下划线\n .replace(/^_+|_+$/g, '')\n // 确保类名以字母开头\n .replace(/^[^a-zA-Z]/, 'cls$&')\n // 限制长度(微信小程序类名长度限制)\n .substring(0, 100)\n}\n\n/**\n * 基础转义(错误恢复)\n */\nfunction basicEscape(className: string): string {\n return className\n // 移除所有特殊字符\n .replace(/[^a-zA-Z0-9_-]/g, '_')\n // 确保以字母开头\n .replace(/^[^a-zA-Z]/, 'cls$&')\n // 限制长度\n .substring(0, 100)\n}\n\n/**\n * 批量转义类名\n */\nexport function escapeWeappClasses(classNames: string[]): string[] {\n return classNames.map(className => escapeWeappClass(className))\n}\n\n/**\n * 转义类名字符串(空格分隔)\n */\nexport function escapeWeappClassString(classString: string): string {\n if (!classString || typeof classString !== 'string') {\n return classString || ''\n }\n \n const classes = classString.split(/\\s+/).filter(cls => cls.trim().length > 0)\n const escapedClasses = escapeWeappClasses(classes)\n return escapedClasses.join(' ')\n}\n\n/**\n * 检查类名是否合法\n */\nexport function isLegalWeappClass(className: string): boolean {\n return /^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(className)\n} ","export * from \"./errors.js\";\nexport * from \"./helpers/parseUtil.js\";\nexport * from \"./helpers/typeAliases.js\";\nexport * from \"./helpers/util.js\";\nexport * from \"./types.js\";\nexport * from \"./ZodError.js\";\n","export var util;\n(function (util) {\n util.assertEqual = (_) => { };\n function assertIs(_arg) { }\n util.assertIs = assertIs;\n function assertNever(_x) {\n throw new Error();\n }\n util.assertNever = assertNever;\n util.arrayToEnum = (items) => {\n const obj = {};\n for (const item of items) {\n obj[item] = item;\n }\n return obj;\n };\n util.getValidEnumValues = (obj) => {\n const validKeys = util.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== \"number\");\n const filtered = {};\n for (const k of validKeys) {\n filtered[k] = obj[k];\n }\n return util.objectValues(filtered);\n };\n util.objectValues = (obj) => {\n return util.objectKeys(obj).map(function (e) {\n return obj[e];\n });\n };\n util.objectKeys = typeof Object.keys === \"function\" // eslint-disable-line ban/ban\n ? (obj) => Object.keys(obj) // eslint-disable-line ban/ban\n : (object) => {\n const keys = [];\n for (const key in object) {\n if (Object.prototype.hasOwnProperty.call(object, key)) {\n keys.push(key);\n }\n }\n return keys;\n };\n util.find = (arr, checker) => {\n for (const item of arr) {\n if (checker(item))\n return item;\n }\n return undefined;\n };\n util.isInteger = typeof Number.isInteger === \"function\"\n ? (val) => Number.isInteger(val) // eslint-disable-line ban/ban\n : (val) => typeof val === \"number\" && Number.isFinite(val) && Math.floor(val) === val;\n function joinValues(array, separator = \" | \") {\n return array.map((val) => (typeof val === \"string\" ? `'${val}'` : val)).join(separator);\n }\n util.joinValues = joinValues;\n util.jsonStringifyReplacer = (_, value) => {\n if (typeof value === \"bigint\") {\n return value.toString();\n }\n return value;\n };\n})(util || (util = {}));\nexport var objectUtil;\n(function (objectUtil) {\n objectUtil.mergeShapes = (first, second) => {\n return {\n ...first,\n ...second, // second overwrites first\n };\n };\n})(objectUtil || (objectUtil = {}));\nexport const ZodParsedType = util.arrayToEnum([\n \"string\",\n \"nan\",\n \"number\",\n \"integer\",\n \"float\",\n \"boolean\",\n \"date\",\n \"bigint\",\n \"symbol\",\n \"function\",\n \"undefined\",\n \"null\",\n \"array\",\n \"object\",\n \"unknown\",\n \"promise\",\n \"void\",\n \"never\",\n \"map\",\n \"set\",\n]);\nexport const getParsedType = (data) => {\n const t = typeof data;\n switch (t) {\n case \"undefined\":\n return ZodParsedType.undefined;\n case \"string\":\n return ZodParsedType.string;\n case \"number\":\n return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;\n case \"boolean\":\n return ZodParsedType.boolean;\n case \"function\":\n return ZodParsedType.function;\n case \"bigint\":\n return ZodParsedType.bigint;\n case \"symbol\":\n return ZodParsedType.symbol;\n case \"object\":\n if (Array.isArray(data)) {\n return ZodParsedType.array;\n }\n if (data === null) {\n return ZodParsedType.null;\n }\n if (data.then && typeof data.then === \"function\" && data.catch && typeof data.catch === \"function\") {\n return ZodParsedType.promise;\n }\n if (typeof Map !== \"undefined\" && data instanceof Map) {\n return ZodParsedType.map;\n }\n if (typeof Set !== \"undefined\" && data instanceof Set) {\n return ZodParsedType.set;\n }\n if (typeof Date !== \"undefined\" && data instanceof Date) {\n return ZodParsedType.date;\n }\n return ZodParsedType.object;\n default:\n return ZodParsedType.unknown;\n }\n};\n","import { util } from \"./helpers/util.js\";\nexport const ZodIssueCode = util.arrayToEnum([\n \"invalid_type\",\n \"invalid_literal\",\n \"custom\",\n \"invalid_union\",\n \"invalid_union_discriminator\",\n \"invalid_enum_value\",\n \"unrecognized_keys\",\n \"invalid_arguments\",\n \"invalid_return_type\",\n \"invalid_date\",\n \"invalid_string\",\n \"too_small\",\n \"too_big\",\n \"invalid_intersection_types\",\n \"not_multiple_of\",\n \"not_finite\",\n]);\nexport const quotelessJson = (obj) => {\n const json = JSON.stringify(obj, null, 2);\n return json.replace(/\"([^\"]+)\":/g, \"$1:\");\n};\nexport class ZodError extends Error {\n get errors() {\n return this.issues;\n }\n constructor(issues) {\n super();\n this.issues = [];\n this.addIssue = (sub) => {\n this.issues = [...this.issues, sub];\n };\n this.addIssues = (subs = []) => {\n this.issues = [...this.issues, ...subs];\n };\n const actualProto = new.target.prototype;\n if (Object.setPrototypeOf) {\n // eslint-disable-next-line ban/ban\n Object.setPrototypeOf(this, actualProto);\n }\n else {\n this.__proto__ = actualProto;\n }\n this.name = \"ZodError\";\n this.issues = issues;\n }\n format(_mapper) {\n const mapper = _mapper ||\n function (issue) {\n return issue.message;\n };\n const fieldErrors = { _errors: [] };\n const processError = (error) => {\n for (const issue of error.issues) {\n if (issue.code === \"invalid_union\") {\n issue.unionErrors.map(processError);\n }\n else if (issue.code === \"invalid_return_type\") {\n processError(issue.returnTypeError);\n }\n else if (issue.code === \"invalid_arguments\") {\n processError(issue.argumentsError);\n }\n else if (issue.path.length === 0) {\n fieldErrors._errors.push(mapper(issue));\n }\n else {\n let curr = fieldErrors;\n let i = 0;\n while (i < issue.path.length) {\n const el = issue.path[i];\n const terminal = i === issue.path.length - 1;\n if (!terminal) {\n curr[el] = curr[el] || { _errors: [] };\n // if (typeof el === \"string\") {\n // curr[el] = curr[el] || { _errors: [] };\n // } else if (typeof el === \"number\") {\n // const errorArray: any = [];\n // errorArray._errors = [];\n // curr[el] = curr[el] || errorArray;\n // }\n }\n else {\n curr[el] = curr[el] || { _errors: [] };\n curr[el]._errors.push(mapper(issue));\n }\n curr = curr[el];\n i++;\n }\n }\n }\n };\n processError(this);\n return fieldErrors;\n }\n static assert(value) {\n if (!(value instanceof ZodError)) {\n throw new Error(`Not a ZodError: ${value}`);\n }\n }\n toString() {\n return this.message;\n }\n get message() {\n return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);\n }\n get isEmpty() {\n return this.issues.length === 0;\n }\n flatten(mapper = (issue) => issue.message) {\n const fieldErrors = {};\n const formErrors = [];\n for (const sub of this.issues) {\n if (sub.path.length > 0) {\n const firstEl = sub.path[0];\n fieldErrors[firstEl] = fieldErrors[firstEl] || [];\n fieldErrors[firstEl].push(mapper(sub));\n }\n else {\n formErrors.push(mapper(sub));\n }\n }\n return { formErrors, fieldErrors };\n }\n get formErrors() {\n return this.flatten();\n }\n}\nZodError.create = (issues) => {\n const error = new ZodError(issues);\n return error;\n};\n","import { ZodIssueCode } from \"../ZodError.js\";\nimport { util, ZodParsedType } from \"../helpers/util.js\";\nconst errorMap = (issue, _ctx) => {\n let message;\n switch (issue.code) {\n case ZodIssueCode.invalid_type:\n if (issue.received === ZodParsedType.undefined) {\n message = \"Required\";\n }\n else {\n message = `Expected ${issue.expected}, received ${issue.received}`;\n }\n break;\n case ZodIssueCode.invalid_literal:\n message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`;\n break;\n case ZodIssueCode.unrecognized_keys:\n message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, \", \")}`;\n break;\n case ZodIssueCode.invalid_union:\n message = `Invalid input`;\n break;\n case ZodIssueCode.invalid_union_discriminator:\n message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;\n break;\n case ZodIssueCode.invalid_enum_value:\n message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;\n break;\n case ZodIssueCode.invalid_arguments:\n message = `Invalid function arguments`;\n break;\n case ZodIssueCode.invalid_return_type:\n message = `Invalid function return type`;\n break;\n case ZodIssueCode.invalid_date:\n message = `Invalid date`;\n break;\n case ZodIssueCode.invalid_string:\n if (typeof issue.validation === \"object\") {\n if (\"includes\" in issue.validation) {\n message = `Invalid input: must include \"${issue.validation.includes}\"`;\n if (typeof issue.validation.position === \"number\") {\n message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;\n }\n }\n else if (\"startsWith\" in issue.validation) {\n message = `Invalid input: must start with \"${issue.validation.startsWith}\"`;\n }\n else if (\"endsWith\" in issue.validation) {\n message = `Invalid input: must end with \"${issue.validation.endsWith}\"`;\n }\n else {\n util.assertNever(issue.validation);\n }\n }\n else if (issue.validation !== \"regex\") {\n message = `Invalid ${issue.validation}`;\n }\n else {\n message = \"Invalid\";\n }\n break;\n case ZodIssueCode.too_small:\n if (issue.type === \"array\")\n message = `Array must contain ${issue.exact ? \"exactly\" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;\n else if (issue.type === \"string\")\n message = `String must contain ${issue.exact ? \"exactly\" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;\n else if (issue.type === \"number\")\n message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;\n else if (issue.type === \"bigint\")\n message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;\n else if (issue.type === \"date\")\n message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;\n else\n message = \"Invalid input\";\n break;\n case ZodIssueCode.too_big:\n if (issue.type === \"array\")\n message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;\n else if (issue.type === \"string\")\n message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;\n else if (issue.type === \"number\")\n message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;\n else if (issue.type === \"bigint\")\n message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;\n else if (issue.type === \"date\")\n message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;\n else\n message = \"Invalid input\";\n break;\n case ZodIssueCode.custom:\n message = `Invalid input`;\n break;\n case ZodIssueCode.invalid_intersection_types:\n message = `Intersection results could not be merged`;\n break;\n case ZodIssueCode.not_multiple_of:\n message = `Number must be a multiple of ${issue.multipleOf}`;\n break;\n case ZodIssueCode.not_finite:\n message = \"Number must be finite\";\n break;\n default:\n message = _ctx.defaultError;\n util.assertNever(issue);\n }\n return { message };\n};\nexport default errorMap;\n","import defaultErrorMap from \"./locales/en.js\";\nlet overrideErrorMap = defaultErrorMap;\nexport { defaultErrorMap };\nexport function setErrorMap(map) {\n overrideErrorMap = map;\n}\nexport function getErrorMap() {\n return overrideErrorMap;\n}\n","import { getErrorMap } from \"../errors.js\";\nimport defaultErrorMap from \"../locales/en.js\";\nexport const makeIssue = (params) => {\n const { data, path, errorMaps, issueData } = params;\n const fullPath = [...path, ...(issueData.path || [])];\n const fullIssue = {\n ...issueData,\n path: fullPath,\n };\n if (issueData.message !== undefined) {\n return {\n ...issueData,\n path: fullPath,\n message: issueData.message,\n };\n }\n let errorMessage = \"\";\n const maps = errorMaps\n .filter((m) => !!m)\n .slice()\n .reverse();\n for (const map of maps) {\n errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message;\n }\n return {\n ...issueData,\n path: fullPath,\n message: errorMessage,\n };\n};\nexport const EMPTY_PATH = [];\nexport function addIssueToContext(ctx, issueData) {\n const overrideMap = getErrorMap();\n const issue = makeIssue({\n issueData: issueData,\n data: ctx.data,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap, // contextual error map is first priority\n ctx.schemaErrorMap, // then schema-bound map if available\n overrideMap, // then global override map\n overrideMap === defaultErrorMap ? undefined : defaultErrorMap, // then global default map\n ].filter((x) => !!x),\n });\n ctx.common.issues.push(issue);\n}\nexport class ParseStatus {\n constructor() {\n this.value = \"valid\";\n }\n dirty() {\n if (this.value === \"valid\")\n this.value = \"dirty\";\n }\n abort() {\n if (this.value !== \"aborted\")\n this.value = \"aborted\";\n }\n static mergeArray(status, results) {\n const arrayValue = [];\n for (const s of results) {\n if (s.status === \"aborted\")\n return INVALID;\n if (s.status === \"dirty\")\n status.dirty();\n arrayValue.push(s.value);\n }\n return { status: status.value, value: arrayValue };\n }\n static async mergeObjectAsync(status, pairs) {\n const syncPairs = [];\n for (const pair of pairs) {\n const key = await pair.key;\n const value = await pair.value;\n syncPairs.push({\n key,\n value,\n });\n }\n return ParseStatus.mergeObjectSync(status, syncPairs);\n }\n static mergeObjectSync(status, pairs) {\n const finalObject = {};\n for (const pair of pairs) {\n const { key, value } = pair;\n if (key.status === \"aborted\")\n return INVALID;\n if (value.status === \"aborted\")\n return INVALID;\n if (key.status === \"dirty\")\n status.dirty();\n if (value.status === \"dirty\")\n status.dirty();\n if (key.value !== \"__proto__\" && (typeof value.value !== \"undefined\" || pair.alwaysSet)) {\n finalObject[key.value] = value.value;\n }\n }\n return { status: status.value, value: finalObject };\n }\n}\nexport const INVALID = Object.freeze({\n status: \"aborted\",\n});\nexport const DIRTY = (value) => ({ status: \"dirty\", value });\nexport const OK = (value) => ({ status: \"valid\", value });\nexport const isAborted = (x) => x.status === \"aborted\";\nexport const isDirty = (x) => x.status === \"dirty\";\nexport const isValid = (x) => x.status === \"valid\";\nexport const isAsync = (x) => typeof Promise !== \"undefined\" && x instanceof Promise;\n","export var errorUtil;\n(function (errorUtil) {\n errorUtil.errToObj = (message) => typeof message === \"string\" ? { message } : message || {};\n // biome-ignore lint:\n errorUtil.toString = (message) => typeof message === \"string\" ? message : message?.message;\n})(errorUtil || (errorUtil = {}));\n","import { ZodError, ZodIssueCode, } from \"./ZodError.js\";\nimport { defaultErrorMap, getErrorMap } from \"./errors.js\";\nimport { errorUtil } from \"./helpers/errorUtil.js\";\nimport { DIRTY, INVALID, OK, ParseStatus, addIssueToContext, isAborted, isAsync, isDirty, isValid, makeIssue, } from \"./helpers/parseUtil.js\";\nimport { util, ZodParsedType, getParsedType } from \"./helpers/util.js\";\nclass ParseInputLazyPath {\n constructor(parent, value, path, key) {\n this._cachedPath = [];\n this.parent = parent;\n this.data = value;\n this._path = path;\n this._key = key;\n }\n get path() {\n if (!this._cachedPath.length) {\n if (Array.isArray(this._key)) {\n this._cachedPath.push(...this._path, ...this._key);\n }\n else {\n this._cachedPath.push(...this._path, this._key);\n }\n }\n return this._cachedPath;\n }\n}\nconst handleResult = (ctx, result) => {\n if (isValid(result)) {\n return { success: true, data: result.value };\n }\n else {\n if (!ctx.common.issues.length) {\n throw new Error(\"Validation failed but no issues detected.\");\n }\n return {\n success: false,\n get error() {\n if (this._error)\n return this._error;\n const error = new ZodError(ctx.common.issues);\n this._error = error;\n return this._error;\n },\n };\n }\n};\nfunction processCreateParams(params) {\n if (!params)\n return {};\n const { errorMap, invalid_type_error, required_error, description } = params;\n if (errorMap && (invalid_type_error || required_error)) {\n throw new Error(`Can't use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.`);\n }\n if (errorMap)\n return { errorMap: errorMap, description };\n const customMap = (iss, ctx) => {\n const { message } = params;\n if (iss.code === \"invalid_enum_value\") {\n return { message: message ?? ctx.defaultError };\n }\n if (typeof ctx.data === \"undefined\") {\n return { message: message ?? required_error ?? ctx.defaultError };\n }\n if (iss.code !== \"invalid_type\")\n return { message: ctx.defaultError };\n return { message: message ?? invalid_type_error ?? ctx.defaultError };\n };\n return { errorMap: customMap, description };\n}\nexport class ZodType {\n get description() {\n return this._def.description;\n }\n _getType(input) {\n return getParsedType(input.data);\n }\n _getOrReturnCtx(input, ctx) {\n return (ctx || {\n common: input.parent.common,\n data: input.data,\n parsedType: getParsedType(input.data),\n schemaErrorMap: this._def.errorMap,\n path: input.path,\n parent: input.parent,\n });\n }\n _processInputParams(input) {\n return {\n status: new ParseStatus(),\n ctx: {\n common: input.parent.common,\n data: input.data,\n parsedType: getParsedType(input.data),\n schemaErrorMap: this._def.errorMap,\n path: input.path,\n parent: input.parent,\n },\n };\n }\n _parseSync(input) {\n const result = this._parse(input);\n if (isAsync(result)) {\n throw new Error(\"Synchronous parse encountered promise.\");\n }\n return result;\n }\n _parseAsync(input) {\n const result = this._parse(input);\n return Promise.resolve(result);\n }\n parse(data, params) {\n const result = this.safeParse(data, params);\n if (result.success)\n return result.data;\n throw result.error;\n }\n safeParse(data, params) {\n const ctx = {\n common: {\n issues: [],\n async: params?.async ?? false,\n contextualErrorMap: params?.errorMap,\n },\n path: params?.path || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: getParsedType(data),\n };\n const result = this._parseSync({ data, path: ctx.path, parent: ctx });\n return handleResult(ctx, result);\n }\n \"~validate\"(data) {\n const ctx = {\n common: {\n issues: [],\n async: !!this[\"~standard\"].async,\n },\n path: [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: getParsedType(data),\n };\n if (!this[\"~