(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('fs'), require('path'), require('prettier'), require('axios'), require('lodash'), require('@vue/compiler-sfc'), require('magic-string'), require('glob'), require('node:util'), require('svgo'), require('postcss-value-parser')) :
    typeof define === 'function' && define.amd ? define(['exports', 'fs', 'path', 'prettier', 'axios', 'lodash', '@vue/compiler-sfc', 'magic-string', 'glob', 'node:util', 'svgo', 'postcss-value-parser'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.index = {}, global.fs, global.path, global.prettier, global.axios, global.lodash, global.compilerSfc, global.magicString, global.glob, global.util, global.svgo, global.valueParser));
})(this, (function (exports, fs, path, prettier, axios, lodash, compilerSfc, magicString, glob, util, svgo, valueParser) { 'use strict';

    const config = {
        type: "admin",
        reqUrl: "",
        nameTag: true,
        eps: {
            enable: true,
            api: "",
            dist: "./build/cool",
            mapping: [
                {
                    // 自定义匹配
                    custom: ({ propertyName, type }) => {
                        // 如果没有，返回null或者不返回，则继续遍历其他匹配规则
                        return null;
                    },
                },
                {
                    type: "string",
                    test: ["varchar", "text", "simple-json"],
                },
                {
                    type: "string[]",
                    test: ["simple-array"],
                },
                {
                    type: "Date",
                    test: ["datetime", "date"],
                },
                {
                    type: "number",
                    test: ["tinyint", "int", "decimal"],
                },
                {
                    type: "BigInt",
                    test: ["bigint"],
                },
                {
                    type: "any",
                    test: ["json"],
                },
            ],
        },
        svg: {
            skipNames: ["base"],
        },
        tailwind: {
            enable: true,
            remUnit: 14,
            remPrecision: 6,
            rpxRatio: 2,
            darkTextClass: "dark:text-surface-50",
        },
    };

    // 根目录
    function rootDir(path$1) {
        switch (config.type) {
            case "app":
            case "uniapp-x":
                return path.join(process.env.UNI_INPUT_DIR, path$1);
            default:
                return path.join(process.cwd(), path$1);
        }
    }
    // 首字母大写
    function firstUpperCase(value) {
        return value.replace(/\b(\w)(\w*)/g, function ($0, $1, $2) {
            return $1.toUpperCase() + $2;
        });
    }
    // 横杠转驼峰
    function toCamel(str) {
        return str.replace(/([^-])(?:-+([^-]))/g, function ($0, $1, $2) {
            return $1 + $2.toUpperCase();
        });
    }
    // 创建目录
    function createDir(path, recursive) {
        try {
            if (!fs.existsSync(path))
                fs.mkdirSync(path, { recursive });
        }
        catch (err) { }
    }
    // 读取文件
    function readFile(path, json) {
        try {
            const content = fs.readFileSync(path, "utf8");
            return json
                ? JSON.parse(content.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, ""))
                : content;
        }
        catch (err) { }
        return "";
    }
    // 写入文件
    function writeFile(path, data) {
        try {
            return fs.writeFileSync(path, data);
        }
        catch (err) { }
        return "";
    }
    // 解析body
    function parseJson(req) {
        return new Promise((resolve) => {
            let d = "";
            req.on("data", function (chunk) {
                d += chunk;
            });
            req.on("end", function () {
                try {
                    resolve(JSON.parse(d));
                }
                catch {
                    resolve({});
                }
            });
        });
    }
    // 格式化内容
    function formatContent(content, options) {
        return prettier.format(content, {
            parser: "typescript",
            useTabs: true,
            tabWidth: 4,
            endOfLine: "lf",
            semi: true,
            ...options,
        });
    }
    function error(message) {
        console.log("\x1B[31m%s\x1B[0m", message);
    }

    /**
     * 将模板字符串扁平化处理，转换为 Service 类型定义
     * @param template - 包含 Service 类型定义的模板字符串
     * @returns 处理后的 Service 类型定义字符串
     * @throws {Error} 当模板中找不到 Service 类型定义时抛出错误
     */
    function flatten(template) {
        // 查找 Service 类型定义的起始位置
        const startIndex = template.indexOf("export type Service = {");
        // 保留 Service 类型定义前的内容
        let header = template.substring(0, startIndex);
        // 获取 Service 类型定义及其内容，去除换行和制表符
        const serviceContent = template.substring(startIndex).replace(/\n|\t/g, "");
        let interfaces = "";
        let serviceFields = "";
        // 解析内容并生成接口定义
        parse(serviceContent).forEach(({ key, content, level }) => {
            interfaces += `\nexport interface ${firstUpperCase(key)}Interface {${content}}\n`;
            serviceFields += `${key}: ${firstUpperCase(key)}Interface;`;
        });
        return `${header}${interfaces}\nexport type Service = {${serviceFields}}`;
    }
    /**
     * 查找匹配的右花括号位置
     * @param str - 要搜索的字符串
     * @param startIndex - 开始搜索的位置
     * @returns 匹配的右花括号位置
     * @throws {Error} 当找不到匹配的右花括号时抛出错误
     */
    function findClosingBrace(str, startIndex) {
        let braceCount = 1;
        let currentIndex = startIndex;
        while (currentIndex < str.length && braceCount > 0) {
            if (str[currentIndex] === "{")
                braceCount++;
            if (str[currentIndex] === "}")
                braceCount--;
            currentIndex++;
        }
        if (braceCount !== 0) {
            throw new Error("Unmatched braces in the template");
        }
        return currentIndex - 1;
    }
    /**
     * 解析内容中的嵌套结构
     * @param content - 要解析的内容字符串
     * @returns 解析结果数组，包含解析出的键值对
     */
    function parse(content, level = 0) {
        // 匹配形如 xxx: { ... } 的结构
        const interfacePattern = /(\w+)\s*:\s*\{/g;
        const result = [];
        let match;
        while ((match = interfacePattern.exec(content)) !== null) {
            const startIndex = match.index + match[0].length;
            const endIndex = findClosingBrace(content, startIndex);
            if (endIndex > startIndex) {
                let parsedContent = content.substring(startIndex, endIndex).trim();
                // 处理嵌套结构
                if (parsedContent.includes("{") && parsedContent.includes("}")) {
                    const nestedInterfaces = parse(parsedContent, level + 1);
                    // 替换嵌套的内容为接口引用
                    if (nestedInterfaces.length > 0) {
                        nestedInterfaces.forEach((nestedInterface) => {
                            const pattern = `${nestedInterface.key}: {${nestedInterface.content}};`;
                            const replacement = `${nestedInterface.key}: ${firstUpperCase(nestedInterface.key)}Interface`;
                            parsedContent = parsedContent.replace(pattern, replacement);
                        });
                    }
                }
                // 将解析结果添加到数组开头
                result.unshift({
                    key: match[1],
                    level,
                    content: parsedContent,
                });
            }
        }
        return result;
    }

    /**
     * 获取动态类名
     */
    const getDynamicClassNames = (value) => {
        const names = new Set();
        // 匹配函数调用中的对象参数（如 parseClass({'!bg-surface-50': hoverable})）
        const functionCallRegex = /\w+\s*\(\s*\{([^}]*)\}\s*\)/gs;
        let funcMatch;
        while ((funcMatch = functionCallRegex.exec(value)) !== null) {
            const objContent = funcMatch[1];
            // 提取对象中的键
            const keyRegex = /['"](.*?)['"]\s*:/gs;
            let keyMatch;
            while ((keyMatch = keyRegex.exec(objContent)) !== null) {
                keyMatch[1].trim() && names.add(keyMatch[1]);
            }
        }
        // 匹配对象键（如 { 'text-a': 1 }）- 优化版本，避免跨行错误匹配
        const objKeyRegex = /[{,]\s*['"](.*?)['"]\s*:/gs;
        let objKeyMatch;
        while ((objKeyMatch = objKeyRegex.exec(value)) !== null) {
            const className = objKeyMatch[1].trim();
            // 确保是有效的CSS类名，避免匹配到错误内容
            if (className && !className.includes("\n") && !className.includes("\t")) {
                names.add(className);
            }
        }
        // 匹配数组中的字符串元素（如 'text-center'）- 优化版本
        const arrayStringRegex = /(?:^|[,\[\s])\s*['"](.*?)['"]/gs;
        let arrayMatch;
        while ((arrayMatch = arrayStringRegex.exec(value)) !== null) {
            const className = arrayMatch[1].trim();
            // 确保是有效的CSS类名
            if (className && !className.includes("\n") && !className.includes("\t")) {
                names.add(className);
            }
        }
        // 匹配三元表达式中的字符串（如 'dark' 和 'light'）
        const ternaryRegex = /(\?|:)\s*['"](.*?)['"]/gs;
        let ternaryMatch;
        while ((ternaryMatch = ternaryRegex.exec(value)) !== null) {
            ternaryMatch[2].trim() && names.add(ternaryMatch[2]);
        }
        // 匹配反引号模板字符串 - 改进版本
        const templateRegex = /`([^`]*)`/gs;
        let templateMatch;
        while ((templateMatch = templateRegex.exec(value)) !== null) {
            const templateContent = templateMatch[1];
            // 提取模板字符串中的普通文本部分（排除 ${} 表达式）
            const textParts = templateContent.split(/\$\{[^}]*\}/);
            textParts.forEach((part) => {
                part.trim()
                    .split(/\s+/)
                    .forEach((className) => {
                    className.trim() && names.add(className.trim());
                });
            });
            // 提取模板字符串中 ${} 表达式内的字符串
            const expressionRegex = /\$\{([^}]*)\}/gs;
            let expressionMatch;
            while ((expressionMatch = expressionRegex.exec(templateContent)) !== null) {
                const expression = expressionMatch[1];
                // 递归处理表达式中的动态类名
                getDynamicClassNames(expression).forEach((name) => names.add(name));
            }
        }
        // 处理混合字符串（模板字符串 + 普通文本），如 "`text-red-900` text-red-1000"
        const mixedStringRegex = /`[^`]*`\s+([a-zA-Z0-9\-_\s]+)/g;
        let mixedMatch;
        while ((mixedMatch = mixedStringRegex.exec(value)) !== null) {
            const additionalClasses = mixedMatch[1].trim().split(/\s+/);
            additionalClasses.forEach((className) => {
                className.trim() && names.add(className.trim());
            });
        }
        // 处理普通字符串，多个类名用空格分割
        const stringRegex = /['"]([\w\s\-!:\/]+?)['"]/gs;
        let stringMatch;
        while ((stringMatch = stringRegex.exec(value)) !== null) {
            const classNames = stringMatch[1].trim().split(/\s+/);
            classNames.forEach((className) => {
                className.trim() && names.add(className.trim());
            });
        }
        return Array.from(names);
    };
    /**
     * 获取类名
     */
    function getClassNames(code) {
        // 修改正则表达式以支持多行匹配，避免内层引号冲突
        const classRegex = /(?:class|:class|:pt|:hover-class)\s*=\s*(['"`])((?:[^'"`\\]|\\.|`[^`]*`|'[^']*'|"[^"]*")*?)\1/gis;
        const classNames = new Set();
        let match;
        while ((match = classRegex.exec(code)) !== null) {
            const attribute = match[0].split("=")[0].trim();
            const isStaticClass = attribute === "class" || attribute === "hover-class";
            const isPtAttribute = attribute.includes("pt");
            const value = match[2].trim();
            if (isStaticClass) {
                // 处理静态 class 和 hover-class
                value.split(/\s+/).forEach((name) => name && classNames.add(name));
            }
            else if (isPtAttribute) {
                // 处理 :pt 属性中的 className
                parseClasNameFromPt(value, classNames);
            }
            else {
                // 处理动态 :class 和 :hover-class
                getDynamicClassNames(value).forEach((name) => classNames.add(name));
            }
        }
        return Array.from(classNames);
    }
    /**
     * 从 :pt 属性中解析 className
     */
    function parseClasNameFromPt(value, classNames) {
        // 递归查找所有 className 属性
        const classNameRegex = /className\s*:\s*/g;
        let match;
        while ((match = classNameRegex.exec(value)) !== null) {
            const startPos = match.index + match[0].length;
            const classNameValue = extractComplexValue(value, startPos);
            if (classNameValue) {
                // 如果是字符串字面量
                if (classNameValue.startsWith('"') ||
                    classNameValue.startsWith("'") ||
                    classNameValue.startsWith("`")) {
                    if (classNameValue.startsWith("`")) {
                        // 处理模板字符串
                        getDynamicClassNames(classNameValue).forEach((name) => classNames.add(name));
                    }
                    else {
                        // 处理普通字符串
                        const strMatch = classNameValue.match(/['"](.*?)['"]/);
                        if (strMatch) {
                            strMatch[1].split(/\s+/).forEach((name) => name && classNames.add(name));
                        }
                    }
                }
                else {
                    // 处理动态值（如函数调用、对象等）
                    getDynamicClassNames(classNameValue).forEach((name) => classNames.add(name));
                }
            }
        }
    }
    /**
     * 提取复杂值（支持嵌套引号和括号）
     */
    function extractComplexValue(text, startPos) {
        let pos = startPos;
        let depth = 0;
        let inString = false;
        let stringChar = "";
        let result = "";
        // 跳过开头的空白字符
        while (pos < text.length && /\s/.test(text[pos])) {
            pos++;
        }
        while (pos < text.length) {
            const char = text[pos];
            if (!inString) {
                if (char === '"' || char === "'" || char === "`") {
                    inString = true;
                    stringChar = char;
                    result += char;
                }
                else if (char === "{" || char === "(" || char === "[") {
                    depth++;
                    result += char;
                }
                else if (char === "}" || char === ")" || char === "]") {
                    if (depth === 0 && char === "}") {
                        // 遇到顶层的 } 时结束
                        break;
                    }
                    depth--;
                    result += char;
                }
                else if (char === "," && depth === 0) {
                    // 遇到顶层的逗号时结束
                    break;
                }
                else if (char === "\n" && depth === 0 && result.trim() !== "") {
                    // 如果遇到换行且不在嵌套结构中，且已有内容，则结束
                    break;
                }
                else {
                    result += char;
                }
            }
            else {
                result += char;
                if (char === stringChar && text[pos - 1] !== "\\") {
                    inString = false;
                    stringChar = "";
                    // 如果字符串结束且depth为0，检查是否应该结束
                    if (depth === 0) {
                        // 看看下一个非空白字符是什么
                        let nextPos = pos + 1;
                        while (nextPos < text.length && /\s/.test(text[nextPos])) {
                            nextPos++;
                        }
                        if (nextPos < text.length && (text[nextPos] === "," || text[nextPos] === "}")) {
                            // 如果下一个字符是逗号或右括号，则结束
                            break;
                        }
                    }
                }
            }
            pos++;
        }
        return result.trim() || null;
    }
    /**
     * 获取 class 内容
     */
    function getClassContent(code) {
        // 修改正则表达式以支持多行匹配，避免内层引号冲突
        const regex = /(?:class|:class|:pt|:hover-class)\s*=\s*(['"`])((?:[^'"`\\]|\\.|`[^`]*`|'[^']*'|"[^"]*")*?)\1/gis;
        const texts = [];
        let match;
        while ((match = regex.exec(code)) !== null) {
            const attribute = match[0].split("=")[0].trim();
            const isPtAttribute = attribute.includes("pt");
            const value = match[2];
            if (isPtAttribute) {
                // 手动解析 className 值
                const classNameRegex = /className\s*:\s*/g;
                let classNameMatchResult;
                while ((classNameMatchResult = classNameRegex.exec(value)) !== null) {
                    const startPos = classNameMatchResult.index + classNameMatchResult[0].length;
                    const classNameValue = extractComplexValue(value, startPos);
                    if (classNameValue) {
                        texts.push(classNameValue);
                    }
                }
            }
            else {
                texts.push(value);
            }
        }
        return texts;
    }
    /**
     * 获取节点
     */
    function getNodes(code) {
        const nodes = [];
        // 找到所有顶级template标签的完整内容
        function findTemplateContents(content) {
            const results = [];
            let index = 0;
            while (index < content.length) {
                const templateStart = content.indexOf("<template", index);
                if (templateStart === -1)
                    break;
                // 找到模板标签的结束位置
                const tagEnd = content.indexOf(">", templateStart);
                if (tagEnd === -1)
                    break;
                // 使用栈来匹配配对的template标签
                let stack = 1;
                let currentPos = tagEnd + 1;
                while (currentPos < content.length && stack > 0) {
                    const nextTemplateStart = content.indexOf("<template", currentPos);
                    const nextTemplateEnd = content.indexOf("</template>", currentPos);
                    if (nextTemplateEnd === -1)
                        break;
                    // 如果开始标签更近，说明有嵌套
                    if (nextTemplateStart !== -1 && nextTemplateStart < nextTemplateEnd) {
                        // 找到开始标签的完整结束
                        const nestedTagEnd = content.indexOf(">", nextTemplateStart);
                        if (nestedTagEnd !== -1) {
                            stack++;
                            currentPos = nestedTagEnd + 1;
                        }
                        else {
                            break;
                        }
                    }
                    else {
                        // 找到结束标签
                        stack--;
                        currentPos = nextTemplateEnd + 11; // '</template>'.length
                    }
                }
                if (stack === 0) {
                    // 提取template内容（不包括template标签本身）
                    const templateContent = content.substring(tagEnd + 1, currentPos - 11);
                    results.push(templateContent);
                    index = currentPos;
                }
                else {
                    // 如果没有找到匹配的结束标签，跳过这个开始标签
                    index = tagEnd + 1;
                }
            }
            return results;
        }
        // 递归提取所有template内容中的节点
        function extractNodesFromContent(content) {
            // 先提取当前内容中的所有标签
            const regex = /<([^>]+)>/g;
            let match;
            while ((match = regex.exec(content)) !== null) {
                if (!match[1].startsWith("/") && !match[1].startsWith("template")) {
                    nodes.push(match[1]);
                }
            }
            // 递归处理嵌套的template
            const nestedTemplates = findTemplateContents(content);
            nestedTemplates.forEach((templateContent) => {
                extractNodesFromContent(templateContent);
            });
        }
        // 获取所有顶级template内容
        const templateContents = findTemplateContents(code);
        // 处理每个template内容
        templateContents.forEach((templateContent) => {
            extractNodesFromContent(templateContent);
        });
        return nodes.map((e) => `<${e}>`);
    }
    /**
     * 添加 script 标签内容
     */
    function addScriptContent(code, content) {
        const scriptMatch = /<script\b[^>]*>([\s\S]*?)<\/script>/g.exec(code);
        if (!scriptMatch) {
            return code;
        }
        const scriptContent = scriptMatch[1];
        const scriptStartIndex = scriptMatch.index + scriptMatch[0].indexOf(">") + 1;
        const scriptEndIndex = scriptStartIndex + scriptContent.length;
        return (code.substring(0, scriptStartIndex) +
            "\n" +
            content +
            "\n" +
            scriptContent.trim() +
            code.substring(scriptEndIndex));
    }
    /**
     * 判断是否为 Tailwind 类名
     */
    function isTailwindClass(className) {
        const prefixes = [
            // 布局
            "container",
            "flex",
            "grid",
            "block",
            "inline",
            "hidden",
            "visible",
            // 间距
            "p-",
            "px-",
            "py-",
            "pt-",
            "pr-",
            "pb-",
            "pl-",
            "m-",
            "mx-",
            "my-",
            "mt-",
            "mr-",
            "mb-",
            "ml-",
            "space-",
            "gap-",
            // 尺寸
            "w-",
            "h-",
            "min-w-",
            "max-w-",
            "min-h-",
            "max-h-",
            // 颜色
            "bg-",
            "text-",
            "border-",
            "ring-",
            "shadow-",
            // 边框
            "border",
            "rounded",
            "ring",
            // 字体
            "font-",
            "text-",
            "leading-",
            "tracking-",
            "antialiased",
            // 定位
            "absolute",
            "relative",
            "fixed",
            "sticky",
            "static",
            "top-",
            "right-",
            "bottom-",
            "left-",
            "inset-",
            "z-",
            // 变换
            "transform",
            "translate-",
            "rotate-",
            "scale-",
            "skew-",
            // 过渡
            "transition",
            "duration-",
            "ease-",
            "delay-",
            // 交互
            "cursor-",
            "select-",
            "pointer-events-",
            // 溢出
            "overflow-",
            "truncate",
            // 滚动
            "scroll-",
            // 伪类和响应式
            "hover:",
            "focus:",
            "active:",
            "disabled:",
            "group-hover:",
        ];
        const statePrefixes = ["dark:", "dark:!", "light:", "sm:", "md:", "lg:", "xl:", "2xl:"];
        if (className.startsWith("!") && !className.includes("!=")) {
            return true;
        }
        for (const prefix of prefixes) {
            if (className.startsWith(prefix)) {
                return true;
            }
            for (const statePrefix of statePrefixes) {
                if (className.startsWith(statePrefix + prefix)) {
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 将 interface 转换为 type
     */
    function interfaceToType(code) {
        // 匹配 interface 定义
        const interfaceRegex = /interface\s+(\w+)(\s*extends\s+\w+)?\s*\{([^}]*)\}/g;
        // 将 interface 转换为 type
        return code.replace(interfaceRegex, (match, name, extends_, content) => {
            // 处理可能存在的 extends
            const extendsStr = extends_ ? extends_ : "";
            // 返回转换后的 type 定义
            return `type ${name}${extendsStr} = {${content}}`;
        });
    }

    // 全局 service 对象，用于存储服务结构
    const service = {};
    // eps 实体列表
    let list = [];
    /**
     * 获取 eps 请求地址
     * @returns {string} eps url
     */
    function getEpsUrl() {
        let url = config.eps.api;
        if (!url) {
            url = config.type;
        }
        switch (url) {
            case "app":
            case "uniapp-x":
                url = "/app/base/comm/eps";
                break;
            case "admin":
                url = "/admin/base/open/eps";
                break;
        }
        return url;
    }
    /**
     * 获取 eps 路径
     * @param filename 文件名
     * @returns {string} 完整路径
     */
    function getEpsPath(filename) {
        return path.join(config.type == "admin" ? config.eps.dist : rootDir(config.eps.dist), filename || "");
    }
    /**
     * 获取对象方法名（排除 namespace、permission 字段）
     * @param v 对象
     * @returns {string[]} 方法名数组
     */
    function getNames(v) {
        return Object.keys(v).filter((e) => !["namespace", "permission"].includes(e));
    }
    /**
     * 获取字段类型
     */
    function getType({ propertyName, type }) {
        for (const map of config.eps.mapping) {
            if (map.custom) {
                const resType = map.custom({ propertyName, type });
                if (resType)
                    return resType;
            }
            if (map.test) {
                if (map.test.includes(type))
                    return map.type;
            }
        }
        return type;
    }
    /**
     * 格式化方法名，去除特殊字符
     */
    function formatName(name) {
        return (name || "").replace(/[:,\s,\/,-]/g, "");
    }
    /**
     * 检查方法名是否合法（不包含特殊字符）
     */
    function checkName(name) {
        return name && !["{", "}", ":"].some((e) => name.includes(e));
    }
    /**
     * 不支持 uniapp-x 平台显示
     */
    function noUniappX(text, defaultText = "") {
        if (config.type == "uniapp-x") {
            return defaultText;
        }
        else {
            return text;
        }
    }
    /**
     * 查找字段
     * @param sources 字段 source 数组
     * @param item eps 实体
     * @returns {Eps.Column[]} 字段数组
     */
    function findColumns(sources, item) {
        const columns = [item.columns, item.pageColumns].flat().filter(Boolean);
        return (sources || [])
            .map((e) => columns.find((c) => c.source == e))
            .filter(Boolean);
    }
    /**
     * 使用 prettier 格式化 TypeScript 代码
     * @param text 代码文本
     * @returns {Promise<string|null>} 格式化后的代码
     */
    async function formatCode(text) {
        return prettier
            .format(text, {
            parser: "typescript",
            useTabs: true,
            tabWidth: 4,
            endOfLine: "lf",
            semi: true,
            singleQuote: false,
            printWidth: 100,
            trailingComma: "none",
        })
            .catch(() => {
            error(`[cool-eps] Failed to format /build/cool/eps.d.ts. Please delete the file and try again`);
            return null;
        });
    }
    /**
     * 获取 eps 数据（本地优先，远程兜底）
     */
    async function getData() {
        // 读取本地 eps.json
        list = readFile(getEpsPath("eps.json"), true) || [];
        // 拼接请求地址
        const url = config.reqUrl + getEpsUrl();
        // 请求远程 eps 数据
        await axios
            .get(url, {
            timeout: 5000,
        })
            .then((res) => {
            const { code, data, message } = res.data;
            if (code === 1000) {
                if (!lodash.isEmpty(data) && data) {
                    list = lodash.values(data).flat();
                }
            }
            else {
                error(`[cool-eps] ${message || "Failed to fetch data"}`);
            }
        })
            .catch(() => {
            error(`[cool-eps] API service is not running → ${url}`);
        });
        // 初始化处理，补全缺省字段
        list.forEach((e) => {
            if (!e.namespace)
                e.namespace = "";
            if (!e.api)
                e.api = [];
            if (!e.columns)
                e.columns = [];
            if (!e.search) {
                e.search = {
                    fieldEq: findColumns(e.pageQueryOp?.fieldEq, e),
                    fieldLike: findColumns(e.pageQueryOp?.fieldLike, e),
                    keyWordLikeFields: findColumns(e.pageQueryOp?.keyWordLikeFields, e),
                };
            }
        });
        if (config.type == "uniapp-x" || config.type == "app") {
            list = list.filter((e) => e.prefix.startsWith("/app"));
        }
    }
    /**
     * 创建 eps.json 文件
     * @returns {boolean} 是否有更新
     */
    function createJson() {
        if (config.type == "uniapp-x") {
            return false;
        }
        const arr = list.map((e) => {
            return {
                prefix: e.prefix,
                name: e.name || "",
                api: e.api.map((apiItem) => ({
                    name: apiItem.name,
                    method: apiItem.method,
                    path: apiItem.path,
                })),
                search: e.search,
            };
        });
        const content = JSON.stringify(arr);
        const local_content = readFile(getEpsPath("eps.json"));
        // 判断是否需要更新
        const isUpdate = content != local_content;
        if (isUpdate) {
            fs.createWriteStream(getEpsPath("eps.json"), {
                flags: "w",
            }).write(content);
        }
        return isUpdate;
    }
    /**
     * 创建 eps 类型描述文件（d.ts/ts）
     * @param param0 list: eps实体列表, service: service对象
     */
    async function createDescribe({ list, service }) {
        /**
         * 创建 Entity 接口定义
         */
        function createEntity() {
            const ignore = [];
            let t0 = "";
            for (const item of list) {
                if (!checkName(item.name))
                    continue;
                let t = `interface ${formatName(item.name)} {`;
                // 合并 columns 和 pageColumns，去重
                const columns = lodash.uniqBy(lodash.compact([...(item.columns || []), ...(item.pageColumns || [])]), "source");
                for (const col of columns || []) {
                    t += `
					/**
					 * ${col.comment}
					 */
					${col.propertyName}?: ${getType({
                    propertyName: col.propertyName,
                    type: col.type,
                })};
				`;
                }
                t += `
				/**
				 * 任意键值
				 */
				[key: string]: any;
			}
			`;
                if (!ignore.includes(item.name)) {
                    ignore.push(item.name);
                    t0 += t + "\n\n";
                }
            }
            return t0;
        }
        /**
         * 创建 Controller 接口定义
         */
        async function createController() {
            let controller = "";
            let chain = "";
            let pageResponse = "";
            /**
             * 递归处理 service 树，生成接口定义
             * @param d 当前节点
             * @param k 前缀
             */
            function deep(d, k) {
                if (!k)
                    k = "";
                for (const i in d) {
                    const name = k + toCamel(firstUpperCase(formatName(i)));
                    // 检查方法名
                    if (!checkName(name))
                        continue;
                    if (d[i].namespace) {
                        // 查找配置
                        const item = list.find((e) => (e.prefix || "") === `/${d[i].namespace}`);
                        if (item) {
                            //
                            let t = `interface ${name} {`;
                            // 插入方法
                            if (item.api) {
                                // 权限列表
                                const permission = [];
                                item.api.forEach((a) => {
                                    // 方法名
                                    const n = toCamel(formatName(a.name || lodash.last(a.path.split("/"))));
                                    // 检查方法名
                                    if (!checkName(n))
                                        return;
                                    if (n) {
                                        // 参数类型
                                        let q = [];
                                        // 参数列表
                                        const { parameters = [] } = a.dts || {};
                                        parameters.forEach((p) => {
                                            if (p.description) {
                                                q.push(`\n/** ${p.description}  */\n`);
                                            }
                                            // 检查参数名
                                            if (!checkName(p.name)) {
                                                return false;
                                            }
                                            const a = `${p.name}${p.required ? "" : "?"}`;
                                            const b = `${p.schema.type || "string"}`;
                                            q.push(`${a}: ${b};`);
                                        });
                                        if (lodash.isEmpty(q)) {
                                            q = ["any"];
                                        }
                                        else {
                                            q.unshift("{");
                                            q.push("}");
                                        }
                                        // 返回类型
                                        let res = "";
                                        // 实体名
                                        const en = item.name || "any";
                                        switch (a.path) {
                                            case "/page":
                                                res = `${name}PageResponse`;
                                                pageResponse += `
												interface ${name}PageResponse {
													pagination: PagePagination;
													list: ${en}[];
												}
											`;
                                                break;
                                            case "/list":
                                                res = `${en} []`;
                                                break;
                                            case "/info":
                                                res = en;
                                                break;
                                            default:
                                                res = "any";
                                                break;
                                        }
                                        // 方法描述
                                        t += `
										/**
										 * ${a.summary || n}
										 */
										${n}(data${q.length == 1 ? "?" : ""}: ${q.join("")}): Promise<${res}>;
									`;
                                        if (!permission.includes(n)) {
                                            permission.push(n);
                                        }
                                    }
                                });
                                // 权限标识
                                t += noUniappX(`
								/**
								 * 权限标识
								 */
								permission: { ${permission.map((e) => `${e}: string;`).join("\n")} };
							`);
                                // 权限状态
                                t += noUniappX(`
								/**
								 * 权限状态
								 */
								_permission: { ${permission.map((e) => `${e}: boolean;`).join("\n")} };
							`);
                                // 请求
                                t += noUniappX(`
								request: Request;
							`);
                            }
                            t += "}\n\n";
                            controller += t;
                            chain += `${formatName(i)}: ${name};`;
                        }
                    }
                    else {
                        chain += `${formatName(i)}: {`;
                        deep(d[i], name);
                        chain += "};";
                    }
                }
            }
            // 遍历 service 树
            deep(service);
            return `
			type json = any;

			interface PagePagination {
				size: number;
				page: number;
				total: number;
				[key: string]: any;
			};

			interface PageResponse<T> {
				pagination: PagePagination;
				list: T[];
				[key: string]: any;
			};

			${pageResponse}

			${controller}

			${noUniappX(`interface RequestOptions {
				url: string;
				method?: 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT';
				data?: any;
				params?: any;
				headers?: any;
				timeout?: number;
				[key: string]: any;
			}`)}

			${noUniappX("type Request = (options: RequestOptions) => Promise<any>;")}

			${await createDict()}

			type Service = {
				${noUniappX("request: Request;")}

				${chain}
			}
		`;
        }
        // 组装文件内容
        let text = `
		${createEntity()}
		${await createController()}
	`;
        // 文件名
        let name = "eps.d.ts";
        if (config.type == "uniapp-x") {
            name = "eps.ts";
            text = text
                .replaceAll("interface ", "export interface ")
                .replaceAll("type ", "export type ")
                .replaceAll("[key: string]: any;", "");
            text = flatten(text);
            text = interfaceToType(text);
        }
        else {
            text = `
			declare namespace Eps {
				${text}
			}
		`;
        }
        // 格式化文本内容
        const content = await formatCode(text);
        const local_content = readFile(getEpsPath(name));
        // 是否需要更新
        if (content && content != local_content && list.length > 0) {
            // 创建 eps 描述文件
            fs.createWriteStream(getEpsPath(name), {
                flags: "w",
            }).write(content);
        }
    }
    /**
     * 构建 service 对象树
     */
    function createService() {
        // 路径第一层作为 id 标识
        const id = getEpsUrl().split("/")[1];
        list.forEach((e) => {
            // 请求地址
            const path = e.prefix[0] == "/" ? e.prefix.substring(1, e.prefix.length) : e.prefix;
            // 分隔路径，去除 id，转驼峰
            const arr = path.replace(id, "").split("/").filter(Boolean).map(toCamel);
            /**
             * 递归构建 service 树
             * @param d 当前节点
             * @param i 当前索引
             */
            function deep(d, i) {
                const k = arr[i];
                if (k) {
                    // 是否最后一个
                    if (arr[i + 1]) {
                        if (!d[k]) {
                            d[k] = {};
                        }
                        deep(d[k], i + 1);
                    }
                    else {
                        // 不存在则创建
                        if (!d[k]) {
                            d[k] = {
                                permission: {},
                            };
                        }
                        if (!d[k].namespace) {
                            d[k].namespace = path;
                        }
                        // 创建权限
                        if (d[k].namespace) {
                            getNames(d[k]).forEach((i) => {
                                d[k].permission[i] =
                                    `${d[k].namespace.replace(`${id}/`, "")}/${i}`.replace(/\//g, ":");
                            });
                        }
                        // 创建搜索
                        d[k].search = e.search;
                        // 创建方法
                        e.api.forEach((a) => {
                            // 方法名
                            const n = a.path.replace("/", "");
                            if (n && !/[-:]/g.test(n)) {
                                d[k][n] = a;
                            }
                        });
                    }
                }
            }
            deep(service, 0);
        });
    }
    /**
     * 创建 service 代码
     * @returns {string} service 代码
     */
    function createServiceCode() {
        const types = [];
        let chain = "";
        /**
         * 递归处理 service 树，生成接口代码
         * @param d 当前节点
         * @param k 前缀
         */
        function deep(d, k) {
            if (!k)
                k = "";
            for (const i in d) {
                if (["swagger"].includes(i)) {
                    continue;
                }
                const name = k + toCamel(firstUpperCase(formatName(i)));
                // 检查方法名
                if (!checkName(name))
                    continue;
                if (d[i].namespace) {
                    // 查找配置
                    const item = list.find((e) => (e.prefix || "") === `/${d[i].namespace}`);
                    if (item) {
                        //
                        let t = `{`;
                        // 插入方法
                        if (item.api) {
                            item.api.forEach((a) => {
                                // 方法名
                                const n = toCamel(formatName(a.name || lodash.last(a.path.split("/"))));
                                // 检查方法名
                                if (!checkName(n))
                                    return;
                                if (n) {
                                    // 参数类型
                                    let q = [];
                                    // 参数列表
                                    const { parameters = [] } = a.dts || {};
                                    parameters.forEach((p) => {
                                        if (p.description) {
                                            q.push(`\n/** ${p.description}  */\n`);
                                        }
                                        // 检查参数名
                                        if (!checkName(p.name)) {
                                            return false;
                                        }
                                        const a = `${p.name}${p.required ? "" : "?"}`;
                                        const b = `${p.schema.type || "string"}`;
                                        q.push(`${a}: ${b}, `);
                                    });
                                    if (lodash.isEmpty(q)) {
                                        q = ["any"];
                                    }
                                    else {
                                        q.unshift("{");
                                        q.push("}");
                                    }
                                    if (item.name) {
                                        types.push(item.name);
                                    }
                                    // 返回类型
                                    let res = "";
                                    // 实体名
                                    const en = item.name || "any";
                                    switch (a.path) {
                                        case "/page":
                                            res = `${name}PageResponse`;
                                            types.push(res);
                                            break;
                                        case "/list":
                                            res = `${en}[]`;
                                            break;
                                        case "/info":
                                            res = en;
                                            break;
                                        default:
                                            res = "any";
                                            break;
                                    }
                                    // 方法描述
                                    t += `
									/**
									 * ${a.summary || n}
									 */
									${n}(data${q.length == 1 ? "?" : ""}: ${q.join("")})${noUniappX(`: Promise<${res}>`)} {
										return request<${res}>({
											url: "/${d[i].namespace}${a.path}",
											method: "${(a.method || "get").toLocaleUpperCase()}",
											data,
										});
									},
								`;
                                }
                            });
                        }
                        t += `} as ${name}\n`;
                        types.push(name);
                        chain += `${formatName(i)}: ${t},\n`;
                    }
                }
                else {
                    chain += `${formatName(i)}: {`;
                    deep(d[i], name);
                    chain += `} as ${firstUpperCase(i)}Interface,`;
                    types.push(`${firstUpperCase(i)}Interface`);
                }
            }
        }
        // 遍历 service 树
        deep(service);
        return {
            content: `{ ${chain} }`,
            types,
        };
    }
    /**
     * 获取字典类型定义
     * @returns {Promise<string>} 字典类型 type 定义
     */
    async function createDict() {
        let p = "";
        switch (config.type) {
            case "app":
            case "uniapp-x":
                p = "/app";
                break;
            case "admin":
                p = "/admin";
                break;
        }
        const url = config.reqUrl + p + "/dict/info/types";
        const text = await axios
            .get(url)
            .then((res) => {
            const { code, data } = res.data;
            if (code === 1000) {
                let v = "string";
                if (!lodash.isEmpty(data)) {
                    v = data.map((e) => `"${e.key}"`).join(" | ");
                }
                return `type DictKey = ${v}`;
            }
        })
            .catch(() => {
            error(`[cool-eps] Error：${url}`);
        });
        return text || "";
    }
    /**
     * 主入口：创建 eps 相关文件和 service
     */
    async function createEps() {
        if (config.eps.enable) {
            // 获取 eps 数据
            await getData();
            // 构建 service 对象
            createService();
            const serviceCode = createServiceCode();
            // 创建 eps 目录
            createDir(getEpsPath(), true);
            // 创建 eps.json 文件
            const isUpdate = createJson();
            // 创建类型描述文件
            createDescribe({ service, list });
            return {
                service,
                serviceCode,
                list,
                isUpdate,
            };
        }
        else {
            return {
                service: {},
                list: [],
            };
        }
    }

    function getPlugin(name) {
        let code = readFile(rootDir(`./src/plugins/${name}/config.ts`));
        // 设置插件配置
        const set = (key, value) => {
            const regex = new RegExp(`(return\\s*{[^}]*?\\b${key}\\b\\s*:\\s*)([^,}]+)`);
            if (regex.test(code)) {
                code = code.replace(regex, `$1${JSON.stringify(value)}`);
            }
            else {
                const insertPos = code.indexOf("return {") + 8;
                code =
                    code.slice(0, insertPos) +
                        `\n  ${key}: ${JSON.stringify(value)},` +
                        code.slice(insertPos);
            }
        };
        // 保存插件配置
        const save = async () => {
            const content = await formatContent(code);
            writeFile(rootDir(`./src/plugins/${name}/config.ts`), content);
        };
        return {
            set,
            save,
        };
    }
    // 修改插件
    async function updatePlugin(options) {
        const plugin = getPlugin(options.name);
        if (options.enable !== undefined) {
            plugin.set("enable", options.enable);
        }
        await plugin.save();
    }

    function getPath() {
        return rootDir(`.${config.type == "admin" ? "/src" : ""}/config/proxy.ts`);
    }
    async function updateProxy(data) {
        let code = readFile(getPath());
        const regex = /const\s+value\s*=\s*['"]([^'"]+)['"]/;
        if (regex.test(code)) {
            code = code.replace(regex, `const value = '${data.name}'`);
        }
        writeFile(getPath(), code);
    }
    function getProxyTarget(proxy) {
        const code = readFile(getPath());
        const regex = /const\s+value\s*=\s*['"]([^'"]+)['"]/;
        const match = code.match(regex);
        if (match) {
            const value = match[1];
            try {
                const { target, rewrite } = proxy[`/${value}/`];
                return target + rewrite(`/${value}`);
            }
            catch (err) {
                error(`[cool-proxy] Error：${value} → ` + getPath());
                return "";
            }
        }
    }

    // 创建文件
    async function createFile(data) {
        const list = lodash.isArray(data) ? data : [data];
        for (const item of list) {
            const { path: path$1, code } = item;
            // 格式化内容
            const content = await formatContent(code, {
                parser: "vue",
            });
            // 目录路径
            const dir = (path$1 || "").split("/");
            // 文件名
            const fname = dir.pop();
            // 源码路径
            const srcPath = `./src/${dir.join("/")}`;
            // 创建目录
            createDir(srcPath, true);
            // 创建文件
            fs.createWriteStream(path.join(srcPath, fname), {
                flags: "w",
            }).write(content);
        }
    }

    function createTag(code, id) {
        if (/\.vue$/.test(id)) {
            let s;
            const str = () => s || (s = new magicString(code));
            const { descriptor } = compilerSfc.parse(code);
            if (!descriptor.script && descriptor.scriptSetup) {
                const res = compilerSfc.compileScript(descriptor, { id });
                const { name, lang } = res.attrs;
                str().appendLeft(0, `<script lang="${lang}">
					import { defineComponent } from 'vue'
					export default defineComponent({
						name: "${name}"
					})
				<\/script>`);
                return {
                    map: str().generateMap(),
                    code: str().toString(),
                };
            }
        }
        return null;
    }

    function base() {
        return {
            name: "vite-cool-base",
            enforce: "pre",
            configureServer(server) {
                server.middlewares.use(async (req, res, next) => {
                    function done(data) {
                        res.writeHead(200, { "Content-Type": "text/html;charset=UTF-8" });
                        res.end(JSON.stringify(data));
                    }
                    if (req.originalUrl?.includes("__cool")) {
                        const body = await parseJson(req);
                        switch (req.url) {
                            // 创建文件
                            case "/__cool_createFile":
                                await createFile(body);
                                break;
                            // 创建 eps 文件
                            case "/__cool_eps":
                                await createEps();
                                break;
                            // 更新插件
                            case "/__cool_updatePlugin":
                                await updatePlugin(body);
                                break;
                            // 设置代理
                            case "/__cool_updateProxy":
                                await updateProxy(body);
                                break;
                            default:
                                return done({
                                    code: 1001,
                                    message: "Unknown request",
                                });
                        }
                        done({
                            code: 1000,
                        });
                    }
                    else {
                        next();
                    }
                });
            },
            transform(code, id) {
                if (config.nameTag) {
                    return createTag(code, id);
                }
                return code;
            },
        };
    }

    function demo(enable) {
        const virtualModuleIds = ["virtual:demo"];
        return {
            name: "vite-cool-demo",
            enforce: "pre",
            resolveId(id) {
                if (virtualModuleIds.includes(id)) {
                    return "\0" + id;
                }
            },
            async load(id) {
                if (id === "\0virtual:demo") {
                    const demo = {};
                    if (enable) {
                        const files = await glob.glob(rootDir("./src/modules/demo/views/crud/components") + "/**", {
                            stat: true,
                            withFileTypes: true,
                        });
                        for (const file of files) {
                            if (file.isFile()) {
                                const p = path.join(file.path, file.name);
                                demo[p
                                    .replace(/\\/g, "/")
                                    .split("src/modules/demo/views/crud/components/")[1]] = fs.readFileSync(p, "utf-8");
                            }
                        }
                    }
                    return `
					export const demo = ${JSON.stringify(demo)};
				`;
                }
            },
        };
    }

    async function createCtx() {
        let ctx = {
            serviceLang: "Node",
        };
        if (config.type == "app" || config.type == "uniapp-x") {
            const manifest = readFile(rootDir("manifest.json"), true);
            // 文件路径
            const ctxPath = rootDir("pages.json");
            // 页面配置
            ctx = readFile(ctxPath, true);
            // 原数据，做更新比较用
            const ctxData = lodash.cloneDeep(ctx);
            // 删除临时页面
            ctx.pages = ctx.pages?.filter((e) => !e.isTemp);
            ctx.subPackages = ctx.subPackages?.filter((e) => !e.isTemp);
            // 加载 uni_modules 配置文件
            const files = await glob.glob(rootDir("uni_modules") + "/**/pages_init.json", {
                stat: true,
                withFileTypes: true,
            });
            for (const file of files) {
                if (file.isFile()) {
                    const { pages = [], subPackages = [] } = readFile(path.join(file.path, file.name), true);
                    // 合并到 pages 中
                    [...pages, ...subPackages].forEach((e) => {
                        e.isTemp = true;
                        const isSub = !!e.root;
                        const d = isSub
                            ? ctx.subPackages?.find((a) => a.root == e.root)
                            : ctx.pages?.find((a) => a.path == e.path);
                        if (d) {
                            lodash.assign(d, e);
                        }
                        else {
                            if (isSub) {
                                ctx.subPackages?.unshift(e);
                            }
                            else {
                                ctx.pages?.unshift(e);
                            }
                        }
                    });
                }
            }
            // 排序后检测，避免加载顺序问题
            function order(d) {
                return {
                    pages: lodash.orderBy(d.pages, "path"),
                    subPackages: lodash.orderBy(d.subPackages, "root"),
                };
            }
            // 是否需要更新 pages.json
            if (!util.isDeepStrictEqual(order(ctxData), order(ctx))) {
                console.log("[cool-ctx] pages updated");
                writeFile(ctxPath, JSON.stringify(ctx, null, 4));
            }
            // appid
            ctx.appid = manifest.appid;
        }
        if (config.type == "admin") {
            const list = fs.readdirSync(rootDir("./src/modules"));
            ctx.modules = list.filter((e) => !e.includes("."));
            await axios
                .get(config.reqUrl + "/admin/base/comm/program", {
                timeout: 5000,
            })
                .then((res) => {
                const { code, data, message } = res.data;
                if (code === 1000) {
                    ctx.serviceLang = data || "Node";
                }
                else {
                    error(`[cool-ctx] ${message}`);
                }
            })
                .catch((err) => {
                // console.error(['[cool-ctx] ', err.message])
            });
        }
        return ctx;
    }

    let svgIcons = [];
    function findSvg(dir) {
        const arr = [];
        const dirs = fs.readdirSync(dir, {
            withFileTypes: true,
        });
        // 获取当前目录的模块名
        const moduleName = dir.match(/[/\\](?:src[/\\](?:plugins|modules)[/\\])([^/\\]+)/)?.[1] || "";
        for (const d of dirs) {
            if (d.isDirectory()) {
                arr.push(...findSvg(dir + d.name + "/"));
            }
            else {
                if (path.extname(d.name) == ".svg") {
                    const baseName = path.basename(d.name, ".svg");
                    // 判断是否需要跳过拼接模块名
                    let shouldSkip = config.svg.skipNames?.includes(moduleName);
                    // 跳过包含icon-
                    if (baseName.includes("icon-")) {
                        shouldSkip = true;
                    }
                    const iconName = shouldSkip ? baseName : `${moduleName}-${baseName}`;
                    svgIcons.push(iconName);
                    const svg = fs.readFileSync(dir + d.name)
                        .toString()
                        .replace(/(\r)|(\n)/g, "")
                        .replace(/<svg([^>+].*?)>/, (_, $2) => {
                        let width = 0;
                        let height = 0;
                        let content = $2.replace(/(width|height)="([^>+].*?)"/g, (_, s2, s3) => {
                            if (s2 === "width") {
                                width = s3;
                            }
                            else if (s2 === "height") {
                                height = s3;
                            }
                            return "";
                        });
                        if (!/(viewBox="[^>+].*?")/g.test($2)) {
                            content += `viewBox="0 0 ${width} ${height}"`;
                        }
                        return `<symbol id="icon-${iconName}" ${content}>`;
                    })
                        .replace("</svg>", "</symbol>");
                    arr.push(svg);
                }
            }
        }
        return arr;
    }
    function compilerSvg() {
        svgIcons = [];
        return findSvg(rootDir("./src/"))
            .map((e) => {
            return svgo.optimize(e)?.data || e;
        })
            .join("");
    }
    async function createSvg() {
        const html = compilerSvg();
        const code = `
if (typeof window !== 'undefined') {
	function loadSvg() {
		const svgDom = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
		svgDom.style.position = 'absolute';
		svgDom.style.width = '0';
		svgDom.style.height = '0';
		svgDom.setAttribute('xmlns','http://www.w3.org/2000/svg');
		svgDom.setAttribute('xmlns:link','http://www.w3.org/1999/xlink');
		svgDom.innerHTML = '${html}';
		document.body.insertBefore(svgDom, document.body.firstChild);
	}

	loadSvg();
}
		`;
        return { code, svgIcons };
    }

    async function virtual() {
        const virtualModuleIds = [
            "virtual:eps",
            "virtual:ctx",
            "virtual:svg-register",
            "virtual:svg-icons",
        ];
        createEps();
        return {
            name: "vite-cool-virtual",
            enforce: "pre",
            configureServer(server) {
                server.middlewares.use(async (req, res, next) => {
                    // 页面刷新时触发
                    if (req.url == "/@vite/client") {
                        // 重新加载虚拟模块
                        virtualModuleIds.forEach((vm) => {
                            const mod = server.moduleGraph.getModuleById(`\0${vm}`);
                            if (mod) {
                                server.moduleGraph.invalidateModule(mod);
                            }
                        });
                    }
                    next();
                });
            },
            handleHotUpdate({ file, server }) {
                // 文件修改时触发
                if (!["pages.json", "dist", "build/cool", "eps.json", "eps.d.ts"].some((e) => file.includes(e))) {
                    createCtx();
                    createEps().then((data) => {
                        if (data.isUpdate) {
                            // 通知客户端刷新
                            (server.hot || server.ws).send({
                                type: "custom",
                                event: "eps-update",
                                data,
                            });
                        }
                    });
                }
            },
            resolveId(id) {
                if (virtualModuleIds.includes(id)) {
                    return "\0" + id;
                }
            },
            async load(id) {
                if (id === "\0virtual:eps") {
                    const eps = await createEps();
                    return `
					export const eps = ${JSON.stringify(eps)}
				`;
                }
                if (id === "\0virtual:ctx") {
                    const ctx = await createCtx();
                    return `
					export const ctx = ${JSON.stringify(ctx)}
				`;
                }
                if (id == "\0virtual:svg-register") {
                    const { code } = await createSvg();
                    return code;
                }
                if (id == "\0virtual:svg-icons") {
                    const { svgIcons } = await createSvg();
                    return `
					export const svgIcons = ${JSON.stringify(svgIcons)}
				`;
                }
            },
        };
    }

    /**
     * 特殊字符映射表
     */
    const SAFE_CHAR_MAP = {
        "[": "-bracket-start-",
        "]": "-bracket-end-",
        "(": "-paren-start-",
        ")": "-paren-end-",
        "{": "-brace-start-",
        "}": "-brace-end-",
        $: "-dollar-",
        "#": "-hash-",
        "!": "-important-",
        "/": "-slash-",
        ":": "-colon-",
    };
    /**
     * 特殊字符映射表（国际化）
     */
    const SAFE_CHAR_MAP_LOCALE = {
        "[": "-bracket-start-",
        "]": "-bracket-end-",
        "(": "-paren-start-",
        ")": "-paren-end-",
        "{": "-brace-start-",
        "}": "-brace-end-",
        $: "-dollar-",
        "#": "-hash-",
        "!": "-important-",
        "/": "-slash-",
        ":": "-colon-",
        " ": "-space-",
        "<": "-lt-",
        ">": "-gt-",
        "&": "-amp-",
        "|": "-pipe-",
        "^": "-caret-",
        "~": "-tilde-",
        "`": "-backtick-",
        "'": "-single-quote-",
        ".": "-dot-",
        "?": "-question-",
        "*": "-star-",
        "+": "-plus-",
        "-": "-dash-",
        _: "-underscore-",
        "=": "-equal-",
        "%": "-percent-",
        "@": "-at-",
    };

    // @ts-ignore
    /**
     * 转换类名中的特殊字符为安全字符
     */
    function toSafeClass(className) {
        if (className.includes(":host")) {
            return className;
        }
        // 如果是表达式,则不进行转换
        if (["!=", "!==", "?", ":", "="].includes(className)) {
            return className;
        }
        let safeClassName = className;
        // 移除转义字符
        if (safeClassName.includes("\\")) {
            safeClassName = safeClassName.replace(/\\/g, "");
        }
        // 处理暗黑模式
        if (safeClassName.includes(":is")) {
            if (safeClassName.includes(":is(.dark *)")) {
                safeClassName = safeClassName.replace(/:is\(.dark \*\)/g, "");
                if (safeClassName.startsWith(".dark:")) {
                    const className = safeClassName.replace(/^\.dark:/, ".dark:");
                    safeClassName = `${className}`;
                }
            }
        }
        // 替换特殊字符
        for (const [char, replacement] of Object.entries(SAFE_CHAR_MAP)) {
            const regex = new RegExp("\\" + char, "g");
            if (regex.test(safeClassName)) {
                safeClassName = safeClassName.replace(regex, replacement);
            }
        }
        return safeClassName;
    }
    /**
     * 转换 RGB 为 RGBA 格式
     */
    function rgbToRgba(rgbValue) {
        const match = rgbValue.match(/rgb\(([\d\s]+)\/\s*([\d.]+)\)/);
        if (!match)
            return rgbValue;
        const [, rgb, alpha] = match;
        const [r, g, b] = rgb.split(/\s+/);
        return `rgba(${r}, ${g}, ${b}, ${alpha})`;
    }
    function remToRpx(remValue) {
        const { remUnit = 14, remPrecision = 6, rpxRatio = 2 } = config.tailwind;
        const conversionFactor = remUnit * rpxRatio;
        const precision = (remValue.split(".")[1] || "").length;
        const rpxValue = (parseFloat(remValue) * conversionFactor)
            .toFixed(precision || remPrecision)
            .replace(/\.?0+$/, "");
        return `${rpxValue}rpx`;
    }
    /**
     * PostCSS 插件
     * 处理类名和单位转换
     */
    function postcssPlugin() {
        return {
            name: "vite-cool-uniappx-postcss",
            enforce: "pre",
            config() {
                return {
                    css: {
                        postcss: {
                            plugins: [
                                {
                                    postcssPlugin: "vite-cool-uniappx-class-mapping",
                                    prepare() {
                                        return {
                                            // 处理选择器规则
                                            Rule(rule) {
                                                if (rule.selector.includes("uni-") ||
                                                    [".button-hover"].some((e) => rule.selector.includes(e))) {
                                                    return;
                                                }
                                                // 转换选择器为安全的类名格式
                                                rule.selector = toSafeClass(rule.selector.replace(/\\/g, ""));
                                            },
                                            // 处理声明规则
                                            Declaration(decl) {
                                                const className = decl.parent.selector || "";
                                                if (!decl.parent._twValues) {
                                                    decl.parent._twValues = {};
                                                }
                                                // 处理 Tailwind 自定义属性
                                                if (decl.prop.includes("--tw-")) {
                                                    decl.parent._twValues[decl.prop] =
                                                        decl.value.includes("rem")
                                                            ? remToRpx(decl.value)
                                                            : decl.value;
                                                    decl.remove();
                                                    return;
                                                }
                                                // 转换 RGB 颜色为 RGBA 格式
                                                if (decl.value.includes("rgb(") &&
                                                    decl.value.includes("/")) {
                                                    decl.value = rgbToRgba(decl.value);
                                                }
                                                // 处理文本大小相关样式
                                                if (decl.value.includes("rpx") &&
                                                    decl.prop == "color" &&
                                                    className.includes("text-")) {
                                                    decl.prop = "font-size";
                                                }
                                                // 删除不支持的属性
                                                if (["filter"].includes(decl.prop)) {
                                                    decl.remove();
                                                    return;
                                                }
                                                // 处理 flex-1
                                                if (decl.prop == "flex") {
                                                    if (decl.value.startsWith("1")) {
                                                        decl.value = "1";
                                                    }
                                                }
                                                // 处理 vertical-align 属性
                                                if (decl.prop == "vertical-align") {
                                                    decl.remove();
                                                }
                                                // 处理 visibility 属性
                                                if (decl.prop == "visibility") {
                                                    decl.remove();
                                                }
                                                // 处理 sticky 属性
                                                if (className == ".sticky") {
                                                    if (decl.prop == "position" ||
                                                        decl.value == "sticky") {
                                                        decl.remove();
                                                    }
                                                }
                                                // 解析声明值
                                                const parsed = valueParser(decl.value);
                                                let hasChanges = false;
                                                // 遍历并处理声明值中的节点
                                                parsed.walk((node) => {
                                                    // 处理单位转换(rem -> rpx)
                                                    if (node.type === "word") {
                                                        const unit = valueParser.unit(node.value);
                                                        if (typeof unit != "boolean") {
                                                            if (unit?.unit === "rem") {
                                                                node.value = remToRpx(unit.number);
                                                                hasChanges = true;
                                                            }
                                                        }
                                                    }
                                                    // 处理 CSS 变量
                                                    if (node.type === "function" &&
                                                        node.value === "var") {
                                                        const twKey = node.nodes[0]?.value;
                                                        // 替换 Tailwind 变量为实际值
                                                        if (twKey?.startsWith("--tw-")) {
                                                            if (decl.parent._twValues) {
                                                                node.type = "word";
                                                                node.value =
                                                                    decl.parent._twValues[twKey] ||
                                                                        "none";
                                                                hasChanges = true;
                                                            }
                                                        }
                                                    }
                                                });
                                                // 更新声明值
                                                if (hasChanges) {
                                                    decl.value = parsed.toString();
                                                }
                                                // 移除 Tailwind 生成的无效 none 变换
                                                const nones = [
                                                    "translate(none, none)",
                                                    "rotate(none)",
                                                    "skewX(none)",
                                                    "skewY(none)",
                                                    "scaleX(none)",
                                                    "scaleY(none)",
                                                ];
                                                if (decl.value) {
                                                    nones.forEach((noneStr) => {
                                                        decl.value = decl.value.replace(noneStr, "");
                                                        if (!decl.value || !decl.value.trim()) {
                                                            decl.value = "none";
                                                        }
                                                    });
                                                }
                                            },
                                        };
                                    },
                                },
                            ],
                        },
                    },
                };
            },
        };
    }
    /**
     * uvue class 转换插件
     */
    function transformPlugin() {
        return {
            name: "vite-cool-uniappx-transform",
            enforce: "pre",
            async transform(code, id) {
                const { darkTextClass } = config.tailwind;
                // 判断是否为 uvue 文件
                if (id.endsWith(".uvue") || id.includes(".uvue?type=page")) {
                    let modifiedCode = code;
                    // 获取所有节点
                    const nodes = getNodes(code);
                    // 遍历处理每个节点
                    nodes.forEach((node) => {
                        if (node.startsWith("<!--")) {
                            return;
                        }
                        let _node = node;
                        // 兼容 <input /> 标签
                        if (_node.startsWith("<input")) {
                            _node = _node.replace("/>", "</input>");
                        }
                        // 为 text 节点添加暗黑模式文本颜色
                        if (!_node.includes(darkTextClass) && _node.startsWith("<text")) {
                            let classIndex = _node.indexOf("class=");
                            // 处理动态 class
                            if (classIndex >= 0) {
                                if (_node[classIndex - 1] == ":") {
                                    classIndex = _node.lastIndexOf("class=");
                                }
                            }
                            // 添加暗黑模式类名
                            if (classIndex >= 0) {
                                _node =
                                    _node.substring(0, classIndex + 7) +
                                        `${darkTextClass} ` +
                                        _node.substring(classIndex + 7, _node.length);
                            }
                            else {
                                _node =
                                    _node.substring(0, 5) +
                                        ` class="${darkTextClass}" ` +
                                        _node.substring(5, _node.length);
                            }
                        }
                        // 获取所有类名
                        const classNames = getClassNames(_node);
                        // 转换 Tailwind 类名为安全类名
                        classNames.forEach((name, index) => {
                            if (isTailwindClass(name)) {
                                const safeName = toSafeClass(name);
                                _node = _node.replaceAll(name, safeName);
                                classNames[index] = safeName;
                            }
                        });
                        // 检查是否存在动态类名
                        const hasDynamicClass = _node.includes(":class=");
                        // 如果没有动态类名,添加空的动态类名绑定
                        if (!hasDynamicClass) {
                            _node = _node.slice(0, -1) + ` :class="{}"` + ">";
                        }
                        // 获取暗黑模式类名
                        const darkClassNames = classNames.filter((name) => name.startsWith("dark-colon-"));
                        // 生成暗黑模式类名的动态绑定
                        const darkClassContent = darkClassNames
                            .map((name) => {
                            _node = _node.replaceAll(name, "");
                            return `'${name}': __isDark`;
                        })
                            .join(",");
                        // 获取所有 class 内容
                        const classContents = getClassContent(_node);
                        // 处理对象形式的动态类名
                        const dynamicClassContent_1 = classContents.find((content) => content.startsWith("{") && content.endsWith("}"));
                        if (dynamicClassContent_1) {
                            const v = dynamicClassContent_1[0] +
                                (darkClassContent ? `${darkClassContent},` : "") +
                                dynamicClassContent_1.substring(1);
                            _node = _node.replaceAll(dynamicClassContent_1, v);
                        }
                        // 处理数组形式的动态类名
                        const dynamicClassContent_2 = classContents.find((content) => content.startsWith("[") && content.endsWith("]"));
                        if (dynamicClassContent_2) {
                            const v = dynamicClassContent_2[0] +
                                `{${darkClassContent}},` +
                                dynamicClassContent_2.substring(1);
                            _node = _node.replaceAll(dynamicClassContent_2, v);
                        }
                        // 更新节点内容
                        modifiedCode = modifiedCode.replace(node, _node);
                    });
                    // 如果代码有修改
                    if (modifiedCode !== code) {
                        // 添加暗黑模式依赖
                        if (modifiedCode.includes("__isDark")) {
                            if (!modifiedCode.includes("<script")) {
                                modifiedCode += '<script lang="ts" setup></script>';
                            }
                            modifiedCode = addScriptContent(modifiedCode, "\nimport { isDark as __isDark } from '@/cool';");
                        }
                        // 清理空的类名绑定
                        modifiedCode = modifiedCode
                            .replaceAll(':class="{}"', "")
                            .replaceAll('class=""', "")
                            .replaceAll('class=" "', "");
                        return {
                            code: modifiedCode,
                            map: { mappings: "" },
                        };
                    }
                    return null;
                }
                else {
                    return null;
                }
            },
        };
    }
    /**
     * Tailwind 类名转换插件
     */
    function tailwindPlugin() {
        return [postcssPlugin(), transformPlugin()];
    }

    function codePlugin() {
        return [
            {
                name: "vite-cool-uniappx-code-pre",
                enforce: "pre",
                async transform(code, id) {
                    if (id.includes("/cool/ctx/index.ts")) {
                        const ctx = await createCtx();
                        const theme = await readFile(rootDir("theme.json"), true);
                        ctx["SAFE_CHAR_MAP_LOCALE"] = [];
                        for (const i in SAFE_CHAR_MAP_LOCALE) {
                            ctx["SAFE_CHAR_MAP_LOCALE"].push([i, SAFE_CHAR_MAP_LOCALE[i]]);
                        }
                        ctx["theme"] = theme;
                        code = code.replace("const ctx = {}", `const ctx = ${JSON.stringify(ctx, null, 4)}`);
                    }
                    if (id.includes("/cool/service/index.ts")) {
                        const eps = await createEps();
                        if (eps.serviceCode) {
                            const { content, types } = eps.serviceCode;
                            const typeCode = `import type { ${lodash.uniq(types).join(", ")} } from '../types';`;
                            code =
                                typeCode +
                                    "\n\n" +
                                    code.replace("const service = {}", `const service = ${content}`);
                        }
                    }
                    if (id.endsWith(".json")) {
                        const d = JSON.parse(code);
                        for (let i in d) {
                            let k = i;
                            for (let j in SAFE_CHAR_MAP_LOCALE) {
                                k = k.replaceAll(j, SAFE_CHAR_MAP_LOCALE[j]);
                            }
                            if (k != i) {
                                d[k] = d[i];
                                delete d[i];
                            }
                        }
                        code = JSON.stringify(d);
                    }
                    return {
                        code,
                        map: { mappings: "" },
                    };
                },
            },
            {
                name: "vite-cool-uniappx-code",
                transform(code, id) {
                    if (id.endsWith(".json")) {
                        return {
                            code: code.replace("new UTSJSONObject", ""),
                            map: { mappings: "" },
                        };
                    }
                },
            },
        ];
    }

    /**
     * uniappX 入口，自动注入 Tailwind 类名转换插件
     * @param options 配置项
     * @returns Vite 插件数组
     */
    async function uniappX() {
        const plugins = [];
        if (config.type == "uniapp-x") {
            plugins.push(...codePlugin());
            if (config.tailwind.enable) {
                plugins.push(...tailwindPlugin());
            }
        }
        return plugins;
    }

    function cool(options) {
        // 应用类型，admin | app
        config.type = options.type;
        // 请求地址
        config.reqUrl = getProxyTarget(options.proxy);
        // 是否开启名称标签
        config.nameTag = options.nameTag ?? true;
        // svg
        if (options.svg) {
            lodash.assign(config.svg, options.svg);
        }
        // Eps
        if (options.eps) {
            const { dist, mapping, api, enable = true } = options.eps;
            // 是否开启
            config.eps.enable = enable;
            // 类型
            if (api) {
                config.eps.api = api;
            }
            // 输出目录
            if (dist) {
                config.eps.dist = dist;
            }
            // 匹配规则
            if (mapping) {
                lodash.merge(config.eps.mapping, mapping);
            }
        }
        // tailwind
        if (options.tailwind) {
            lodash.assign(config.tailwind, options.tailwind);
        }
        return [base(), virtual(), uniappX(), demo(options.demo)];
    }

    exports.cool = cool;

}));
