{"version":3,"sources":["jsdelivr-header.js","/npm/buijs@1.9.31/buijs-cli.js"],"names":[],"mappings":"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","file":"/npm/buijs@1.9.31/buijs-cli.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.37.0.\n * Original file: /npm/buijs@1.9.31/buijs-cli.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","#!/usr/bin/env node\n\nconst process = require(\"process\");\nconst shell = require(\"shelljs\");\nconst yargs = require(\"yargs\");\nconst chalk = require('chalk');\nconst path = require(\"path\");\nconst fs = require(\"fs-extra\");\nconst decompress = require(\"decompress\");\nconst jsonfile = require('jsonfile');\nconst request = require('request').defaults({\n    headers: {\n        'User-Agent': 'node request' // GitHub ask for this.\n    }\n});\nconst confirm = require('prompt-confirm');\nconst prompts = require('prompt');\n\nconst infoLabel = chalk.inverse.green(\"INFO\");\nconst warningLabel = chalk.inverse(\"WARN\");\nconst errorLabel = chalk.inverse(\"ERROR\");\n\nfunction log(msg) {\n    console.log(`${infoLabel} ${msg}`);\n}\n\nfunction warn(msg) {\n    console.log(chalk.yellow(`${warningLabel} ${msg}`));\n}\n\nfunction error(msg) {\n    console.log(chalk.red(`${errorLabel} ${msg}`));\n    process.exit(1);\n}\n\n// -----------------配置---------start\nconst currentVersion = \"1.7.35\";\nconst templateDirName = \"templates\";\nconst platformDirName = \"platforms\";\n// 1.6.x 的工程改为\nconst devDirName = \"node\";\n\n// 默认缓存内容至 ~/CACHE_DIR\n// /Users/xxx/.buijs/\nconst CACHE_DIR_NAME = \".buijs\";\nconst CACHE_DIR_PATH = path.join(require('os').homedir(), CACHE_DIR_NAME);\nconst CACHE_TEMPLATE_PATH = path.join(CACHE_DIR_PATH, \"template\");\nconst TMP_DOWNLOAD_PATH = path.join(CACHE_TEMPLATE_PATH, \"download.zip\");\nconst RELEASES_JSON_PATH = path.join(CACHE_TEMPLATE_PATH, \"release.json\");\nconst Author_JSON_PATH = path.join(CACHE_TEMPLATE_PATH, \"author.json\");\nconst Record_JSON_PATH = path.join(CACHE_TEMPLATE_PATH, \"record.json\");\n\n// Github api\nconst GITHUB_REPO = \"https://api.github.com/repos/imouou/BUI-Template/releases\";\n// Github下载: https://github.com/imouou/BUI-Template/archive/1.5.14.zip\n// Gitee API \nconst GITEE_REPO = \"https://gitee.com/api/v5/repos/imouou/BUI-Template/releases\";\n// Gitee 下载, https://gitee.com/imouou/BUI-Template/repository/archive/1.5.14.zip\n// easybui API \nconst repoPath = 'https://www.easybui.com';\n// 版本列表\nconst EASYBUI_REPO = repoPath + \"/addons/cms/api.archives/index?page=1&channel=35\";\n// 版本详情\nconst releaseDetailUrl = repoPath + \"/addons/cms/api.archives/detail\";\n// Gitee 下载, https://www.easybui.com/downloads/source/bui/bui_router_dev_latest.zip\nconst releaseCountUrl = repoPath + \"/addons/cms/archives/download.html\"\n\nvar BUI_TEMPLATE_RELEASE_URL = EASYBUI_REPO;\n\n// 登录地址\nvar LoginUrl = repoPath + '/addons/cms/api.login/login';\n\n// -----------------配置---------end\n\n// toggle repo 数据源切换\nfunction toggleRepo(name) {\n\n    switch (name) {\n        case \"github\":\n        // warn(\"由于Github国内连接不稳定，已不再支持\")\n        // BUI_TEMPLATE_RELEASE_URL = GITHUB_REPO;\n        // log(\"change repo github\", BUI_TEMPLATE_RELEASE_URL)\n        // break;\n        case \"gitee\":\n        // BUI_TEMPLATE_RELEASE_URL = GITEE_REPO;\n        // log(\"change repo gitee\", BUI_TEMPLATE_RELEASE_URL)\n        // break;\n        case \"easybui\":\n        default:\n            BUI_TEMPLATE_RELEASE_URL = EASYBUI_REPO;\n            // log(\"change repo easybui\", BUI_TEMPLATE_RELEASE_URL)\n            break;\n    }\n}\n\nfunction getReleaseUrl(tag) {\n    return BUI_TEMPLATE_RELEASE_URL + \"/\" + (tag ? `tags/${tag}` : \"latest\");\n}\n\n// log(RELEASES_JSON_PATH)\nfs.ensureFileSync(RELEASES_JSON_PATH);\n\nfs.ensureFileSync(Record_JSON_PATH);\n\ntry {\n    var releasesInfo = jsonfile.readFileSync(RELEASES_JSON_PATH);\n} catch (e) {\n    releasesInfo = {};\n}\n\n\n/**\n * 获取刚下载解压的 release 的路径\n * TODO: 目前无法准确获取 release 解压之后的目录名称，只能根据某种模式推断\n */\nfunction getLastReleasePath() {\n    let files = fs.readdirSync(CACHE_TEMPLATE_PATH);\n    // 必须跟BUI模板的github的地址目录名一致.\n    const pattern = \"BUI-Template\";\n    for (let f of files) {\n        if (f.indexOf(pattern) != -1) {\n            return path.join(CACHE_TEMPLATE_PATH, f);\n        }\n    }\n\n    error(\"版本的压缩包应该以 BUI-Template-版本号 命名 .\");\n}\n\n/**\n * 把 url (zipball_url) 的内容下载并解压到 savePath\n * @param {string} url\n * @param {string} savePath\n * @param {Function} cb\n */\nfunction downloadAndUnzip(url, savePath, cb) {\n    log(\"开始下载...\");\n    let file = fs.createWriteStream(TMP_DOWNLOAD_PATH);\n    file.on(\"close\", function () {\n        log(\"请稍候...\");\n        decompress(TMP_DOWNLOAD_PATH, CACHE_TEMPLATE_PATH).then(function () {\n            // log(\"处理完成.\");\n            let origPath = getLastReleasePath();\n\n            fs.moveSync(origPath, savePath); // 重命名为指定名\n            fs.unlinkSync(TMP_DOWNLOAD_PATH); // 删除下载的压缩包\n            if (cb) cb();\n        })\n    }).on(\"error\", function (err) {\n        console.log(err);\n    });\n    // log(url);\n    if( url ){\n\n        request.get(url)\n        .on(\"error\", function (err) {\n            error(`Error downloading release: ${err}`);\n        })\n        .on(\"response\", function (res) {\n            if (res.statusCode != 200) {\n                error(\"Get zipUrl return a non-200 response.\");\n            }\n        })\n        .on(\"end\", function () {\n            log(\"下载完成.\");\n        })\n        .pipe(file);\n    }else{\n        error(\"Token已过期，请重新执行 buijs login 进行登录, 如果没有账号，请从 https://www.easybui.com 免费注册.\")\n    }\n}\n\n/**\n * 获取指定版本的 release，首先尝试缓存（CACHE_TEMPLATE_PATH），再尝试下载\n * @param {string} version 指定版本，如果为空，表示最新版本\n * @param {Function} cb 通过该回调返回 release 的路径，一般形如 ~/.bui-weex/template/0.1.0\n */\nfunction fetchEasybuiRelease(version, cb, needRequest) {\n    needRequest = needRequest === false ? false : true;\n\n\n    if (version) {\n        // Version specified, try cache.\n        let info = releasesInfo[version];\n        if (info) {\n            // Hit cache.\n            log(\"从缓存创建.\")\n            cb(path.join(CACHE_TEMPLATE_PATH, info.path));\n            return;\n        } else {\n            log(\"没有缓存文件.\");\n        }\n    }\n\n    // last release 版本\n    let lasRelease = function (argument) {\n        // When fetch error, and no version specified, try to figure out the latest release.\n        var latestRleaseInfo = null;\n        for (let tag in releasesInfo) {\n            let info = releasesInfo[tag];\n\n            if (!latestRleaseInfo) {\n                latestRleaseInfo = info;\n            } else {\n\n                let infoversion = info.tag.replace(/\\./g, '');\n                let lastversion = latestRleaseInfo.tag.replace(/\\./g, '');\n                if (parseInt(infoversion) > parseInt(lastversion)) latestRleaseInfo = info;\n            }\n        }\n\n        return latestRleaseInfo;\n    }\n    // log(`获取版本: ${version ? version : \"latest\"}...`);\n\n    if (!needRequest) {\n        // When fetch error, and no version specified, try to figure out the latest release.\n        let latestRleaseInfo = lasRelease();\n\n        if (latestRleaseInfo) {\n            // Figured out latest release in cache.\n            log(`从缓存创建中, 请稍候...`)\n            cb(path.join(CACHE_TEMPLATE_PATH, latestRleaseInfo.path));\n            return;\n        } else {\n            log(`需要先创建工程以后,才能创建模块.`)\n        }\n        return;\n    }\n    // 获取所有版本列表\n    request(EASYBUI_REPO, function (err, res, body) {\n        let latestRleaseInfo = lasRelease();\n\n        if (err) {\n            // When fetch error, and no version specified, try to figure out the latest release.\n\n            if (latestRleaseInfo) {\n                // Figured out latest release in cache.\n                log(`从缓存创建中, 请稍候...`)\n                cb(path.join(CACHE_TEMPLATE_PATH, latestRleaseInfo.path));\n                return;\n            }\n            error(err);\n        }\n        if (res.statusCode != 200) {\n            warn(`Failed to fetch ${url} - ${res.statusCode}: ${res.body}`);\n            if (!version) {\n                // When fetch error, and no version specified, try to figure out the latest release.\n\n                if (latestRleaseInfo) {\n                    // Figured out latest release in cache.\n                    log(`Found latest release in cache: ${latestRleaseInfo.tag}.`)\n                    cb(path.join(CACHE_TEMPLATE_PATH, latestRleaseInfo.path));\n                    return;\n                }\n            }\n            error(`Failed to fetch release of ${version ? version : \"latest\"}`);\n        }\n        // Successfully fetched info.\n        let info = JSON.parse(body);\n\n        if (!info.data) {\n            error(`Failed to fetch release`);\n            return;\n        }\n        // 最新的版本\n        let releaseInfo = info.data ? info.data.pageList.data[0] : {};\n        // info.data.pageList.data[]\n\n        if (version) {\n            for (let i in info.data.pageList.data) {\n                let item = info.data.pageList.data[i];\n                if (item.version == version) {\n                    releaseInfo = item;\n                    break;\n                }\n            }\n        }\n\n        let newInfo = {};\n        let tag = newInfo.tag = releaseInfo[\"version\"];\n        newInfo.time = releaseInfo[\"publishtime\"] || releaseInfo[\"createtime\"];\n        newInfo.path = newInfo.tag;\n        newInfo.id = releaseInfo.id;\n        let targetPath = path.join(CACHE_TEMPLATE_PATH, newInfo.path);\n\n        if (fs.pathExistsSync(targetPath) && latestRleaseInfo && latestRleaseInfo.time >= newInfo.time) {\n            // Probably we are fetching latest release...\n            log(`获取缓存, 请稍候...`);\n            cb(targetPath);\n\n            // 增加统计\n            addup({ id: releaseInfo.id })\n            return;\n        }\n\n        var token = checkLogin();\n        let detailurl = releaseDetailUrl + \"?id=\" + releaseInfo.id + \"&token=\" + token;\n\n        // url 地址需要从详情再次获取\n        request(detailurl, function (err, res, body) {\n\n            if (err) {\n                // When fetch error, and no version specified, try to figure out the latest release.\n                error(err);\n                if (latestRleaseInfo) {\n                    // Figured out latest release in cache.\n                    log(`从缓存创建中, 请稍候...`)\n                    cb(path.join(CACHE_TEMPLATE_PATH, latestRleaseInfo.path));\n                    return;\n                }\n            }\n            \n            let newinfo = JSON.parse(res.body);\n            let detailinfo = newinfo?.data?.archivesInfo || {};\n\n            let downloadUrls = detailinfo[\"downloadurl\"];\n\n            let downloadUrl = \"\";\n            for (let urlitem in downloadUrls) {\n                let localUrl = downloadUrls[urlitem][\"url\"];\n                if (localUrl) {\n                    downloadUrl = localUrl;\n                    break;\n                }\n            }\n\n            downloadAndUnzip(downloadUrl, targetPath, function () {\n                releasesInfo[tag] = newInfo;\n                jsonfile.writeFileSync(RELEASES_JSON_PATH, releasesInfo, { spaces: 2 });\n                cb(targetPath);\n                return;\n            });\n\n            // 统计\n            addup({ id: releaseInfo.id });\n\n        })\n\n    })\n\n}\n\n/**\n * 获取远程组件模板 -s pages/\n * @param {object} opt \n * @param {string} opt.id 远程模板的id\n * @param {string} [opt.name] 本地的名字\n * @param {string} [opt.save] 保存的路径 默认从 pages/\n * @param {string} [opt.remote] 获取远程模板\n */\nfunction getComponent(opt) {\n\n    if (!fs.existsSync(\"package.json\")) {\n        error(\"当前目录下没有package.json，您可能还没创建BUI工程，请通过 buijs create 构建.\")\n        return;\n    }\n    if (!opt.id) {\n        log(\"模板ID 不能为空.\");\n        return;\n    }\n    let save = opt.save ? `pages/` + opt.save : `pages`;\n    let url = releaseDetailUrl + \"?id=\" + opt.id + \"&token=\" + opt.token;\n    var releasesInfo = null;\n    try {\n        releasesInfo = jsonfile.readFileSync(Record_JSON_PATH);\n    } catch (e) {\n        releasesInfo = {};\n    }\n    let currentInfo = releasesInfo[opt.id];\n\n    // log(\"获取最新版本 ...\");\n\n    // 从本地文件复制\n    function copyLocalFile(opt) {\n        let name = (opt.name || currentInfo.name || currentInfo.id);\n        let idpath = currentInfo.path;\n        let targetPath = path.join(CACHE_TEMPLATE_PATH, idpath);\n        let savePath = save + \"/\" + name;\n\n        let origPath = path.resolve(`./src/${savePath}`);;\n\n        fs.copySync(targetPath, origPath); // 重命名为指定名\n        // 统计\n        addup({ id: opt.id });\n    }\n\n    // 获取组件模板\n    request(url, function (err, res, body) {\n        try {\n            var info = JSON.parse(body);\n        } catch (e) {\n            warn(\"返回的数据格式错误\")\n        }\n\n        if (info && info.code == 0) {\n            switch (info.msg) {\n                case \"请登录后再操作\":\n                    warn(`${info.msg}，终端执行 buijs login `);\n                    break;\n                default:\n                    warn(info.msg);\n                    break;\n            }\n            return;\n        }\n\n        let archiveInfo = info.data.archivesInfo || {};\n        let name = (opt.name || archiveInfo.compentname || archiveInfo.id);\n        let idpath = `components/${opt.id}`;\n        let targetPath = path.join(CACHE_TEMPLATE_PATH, idpath);\n        let savePath = save + \"/\" + name;\n\n        // info.data.archivesInfo\n        // 组件信息\n        let componentInfo = {\n            id: archiveInfo.id,\n            title: archiveInfo.title,\n            image: archiveInfo.image,\n            name: name,\n            path: idpath,\n            fullpath: targetPath,\n            publishtime: archiveInfo.publishtime\n        }\n\n        if (archiveInfo.channel_id != \"13\" && archiveInfo.channel_id != \"12\" && archiveInfo.channel_id != \"29\") {\n            error(\"仅支持组件及模板的下载\");\n            return;\n        }\n\n        let downloadUrls = archiveInfo[\"downloadurl\"] || [];\n\n        if (!downloadUrls.length) {\n            log(\"您可能没有该文档的下载权限，请从 www.easybui.com 官网进入查看是否可以下载。\");\n            return;\n        }\n\n        let downloadUrl = \"\";\n        for (let urlitem in downloadUrls) {\n            let localUrl = downloadUrls[urlitem][\"url\"];\n            if (localUrl) {\n                downloadUrl = localUrl;\n                break;\n            }\n        }\n\n        if (!downloadUrls) {\n            log(\"您可能没有该文档的下载权限，请从 www.easybui.com 官网进入查看是否可以下载。\");\n            return;\n        }\n\n\n        // 如果有本地文件，且发布时间没有改变，不需要重新下载，减少服务器负担\n        if (!opt.remote && currentInfo && currentInfo.publishtime >= componentInfo.publishtime) {\n            log(\"从缓存创建 ...\");\n\n            copyLocalFile(opt);\n\n            log(`创建完成，预览地址: http://localhost:port/#${savePath}/index`);\n\n            return;\n        }\n\n        // 重新下载更新\n        downloadCompentUnzip(downloadUrl, targetPath, savePath, function () {\n\n            releasesInfo[componentInfo.id] = componentInfo;\n            // 下载记录\n            jsonfile.writeFileSync(Record_JSON_PATH, releasesInfo, { spaces: 2 });\n\n            log(`创建完成，预览地址: http://localhost:port/#${savePath}/index`);\n\n        });\n\n        // 统计\n        addup({ id: archiveInfo.id });\n\n    })\n\n}\n\n// 获取版本更新提醒\nfunction getCliVersion(opt) {\n\n    let url = releaseDetailUrl + \"?id=\" + opt.id;\n\n    // 获取组件模板\n    request(url, function (err, res, body) {\n        try {\n            var info = JSON.parse(body);\n        } catch (e) {\n            warn(\"返回的数据格式错误\")\n        }\n\n        if (info && info.code == 0) {\n            switch (info.msg) {\n                case \"请登录后再操作\":\n                    warn(`${info.msg}，终端执行 buijs login `);\n                    break;\n                default:\n                    warn(info.msg);\n                    break;\n            }\n            return;\n        }\n        if (!info) {\n            return;\n        }\n        let archiveInfo = info.data.archivesInfo || {};\n        let remoteVersion = String(archiveInfo.version).replace(/\\./g, \"\");\n        let currentV = String(currentVersion).replace(/\\./g, \"\");\n\n        if (parseInt(remoteVersion) > parseInt(currentV)) {\n            warn(`buijs cli有新版: ${archiveInfo.version}，执行 npm i -g buijs 更新`);\n        }\n\n    })\n}\n\n\n/**\n * 把 url (zipball_url) 的内容下载并解压到 savePath\n * @param {string} url\n * @param {string} savePath\n * @param {Function} cb\n */\nfunction downloadCompentUnzip(url, targetPath, savePath, cb) {\n    log(\"开始下载...\");\n    let file = fs.createWriteStream(TMP_DOWNLOAD_PATH);\n    file.on(\"close\", function () {\n        log(\"请稍候...\");\n        // decompress(TMP_DOWNLOAD_PATH, CACHE_TEMPLATE_PATH).then(function () {\n        decompress(TMP_DOWNLOAD_PATH, targetPath).then(function () {\n            // log(\"处理完成.\");\n            let origPath = path.resolve(`./src/${savePath}`);;\n\n            fs.copySync(targetPath, origPath); // 重命名为指定名\n            fs.unlinkSync(TMP_DOWNLOAD_PATH); // 删除下载的压缩包\n            if (cb) cb();\n        })\n    }).on(\"error\", function (err) {\n        console.log(err);\n    });\n\n    request.get(url)\n        .on(\"error\", function (err) {\n            error(`Error downloading release: ${err}`);\n        })\n        .on(\"response\", function (res) {\n            if (res.statusCode != 200) {\n                error(\"Get zipUrl return a non-200 response.\");\n            }\n        })\n        .on(\"end\", function () {\n            log(\"下载完成.\");\n        })\n        .pipe(file);\n}\n\nvar fetchMethod = {\n    fetchEasybuiRelease: fetchEasybuiRelease\n}\n\n// 增加下载次数\nfunction addup(opt) {\n\n    // 统计\n    request.post({\n        url: releaseCountUrl,\n        form: opt\n    }, function (err, httpResponse, body) {\n\n    })\n}\n\n// 自动安装提醒\nfunction autoInstall(name) {\n    let commandtip = name ? `cd ${name} && npm install && npm run dev` : `npm install && npm run dev`;\n    let command = name ? `cd ${name} && npm install --registry=https://registry.npmmirror.com && npm run dev` : `npm install --registry=https://registry.npmmirror.com && npm run dev`;\n    log(`创建工程完成，执行 ${commandtip} 命令预览工程.`);\n    // warn(\"如果安装依赖报错，请先设置淘宝源 npm config set registry https://registry.npmmirror.com \")\n\n    var prompt = new confirm('要自动安装依赖并且打开预览吗?');\n    prompt.ask(function (answer) {\n        if (!answer) {\n            return;\n        } else {\n            log(`需要耗费几分钟时间，请耐心等待.`);\n            // Run external tool synchronously\n            if (shell.exec(command).code !== 0) {\n                shell.echo(`安装失败，请尝试自己执行 ${commandtip} 命令预览工程.`);\n                shell.exit(1);\n            }\n        }\n    });\n}\n/**\n * 复制 template 文件以创建 bui 工程.\n * @param  {string} [name] project name.\n * @param  {string} [version] template version.\n * @param  {string} [templateName] init templates/ dir with specified template\n * @param  {string} [platformName] init platforms/ dir with specified template\n * @param  {string} [dev] init NPM Package.json\n */\nfunction initProject(names, version, templateName, platformName, moduleName, repoName) {\n    // 获得当前路径\n    let name = '';\n    // repoName = repoName || \"gitee\";\n    // 判断工程文件是否需要使用新版的\n    let nodeVersion = process.version.slice(1);\n    let hightVersion = parseFloat(nodeVersion) > 10;\n\n    let defaultNewModule = \"page-newmodule\"; // 默认新模块的名字\n    if (names && names.includes('.')) {\n        name = path.resolve('./');\n        version = names;\n    } else {\n        name = names || path.resolve('./');\n        version = version;\n    }\n    // if (repoName) {\n    //     toggleRepo(repoName);\n    // }\n\n    let jsDir = path.join(name, \"js\");\n    let pagesDir = path.join(name, \"pages\");\n    // 通过判断当前目录下是否有\n    let hasJsFolder = fs.existsSync(jsDir) || fs.existsSync(pagesDir);\n    // 如果是开发模式,源码全在src目录,并且有 package.json\n    let rootName = hasJsFolder ? name : name + '/src';\n\n    // 检测是否存在当前模板\n    let tplName = templateName && templateName.indexOf(\"-\") ? (templateName.split(\"-\")[1] || \"\") : \"\";\n    let tplNameDir = path.join(rootName, \"pages\", tplName);\n    let hasTplName = fs.existsSync(tplNameDir);\n    // 项目是否已经存在的检测\n    let isExistProject = false;\n    // 先检测有没有相同模板\n    if (hasTplName) {\n        var prompt = new confirm('模板已存在，要覆盖吗？继续请按回车键');\n        prompt.ask(function (answer) {\n            if (!answer) {\n                return;\n            } else {\n                // 如果用户有传项目名称,没有则在当前目录创建,检测是否存在js目录,用于检测\n                checkProjectIsExist();\n\n                return;\n            }\n        });\n    } else {\n        // 如果用户有传项目名称,没有则在当前目录创建,检测是否存在js目录,用于检测\n        checkProjectIsExist();\n    }\n\n    // 检测工程目录是否存在, 警告用户会覆盖工程\n    function checkProjectIsExist() {\n        // 如果存在js目录,或者src目录,提示可能会覆盖\n        // 如果创建子目录,并且子目录不存在,则认为项目不存在,不弹出提醒.\n        if (hasJsFolder || fs.existsSync(\"src\") || (names && fs.existsSync(names))) {\n\n            isExistProject = true;\n\n            createProject();\n\n            return;\n        }\n        isExistProject = false;\n        createProject();\n    }\n\n    // 创建工程\n    function createProject() {\n\n        var typename = \"工程\";\n        if (templateName) {\n            typename = \"模板\";\n        } else if (platformName) {\n            typename = \"平台\";\n        } else if (moduleName) {\n            typename = \"组件\";\n        }\n        log(`开始创建${typename}`);\n\n        // 创建模块名的时候无需请求\n        let needRequest = moduleName ? false : true;\n        // 获取bui版本，操作方式跟github不一样\n        // var fetchRepo = repoName && repoName == 'easybui' ? fetchMethod[\"fetchEasybuiRelease\"] : fetchMethod[\"fetchRelease\"];\n        var fetchRepo = fetchMethod[\"fetchEasybuiRelease\"];\n\n        fetchRepo(version, function (releasePath) {\n            // 工程缓存路径 /demo/cache\n            let cachePath = path.join(name, \"cache\");\n            // 项目模板文件夹路径 /demo/src/templates\n            let templateDir = path.join(rootName, templateDirName);\n            // NPM 开发目录 /demo/src/dev 新版为 /demo/src/node\n            let devDir = path.join(rootName, devDirName);\n            // 项目平台文件夹路径 /demo/src/platforms\n            let platformDir = path.join(rootName, platformDirName);\n\n            // log(\"Copying default template file...\");\n            // 复制文件到项目的cache目录\n            // fs.copySync(releasePath, cachePath);\n            // 再从cache复制到根目录,防止多次创建覆盖\n            // 如果没有加参数,创建默认工程不会覆盖之前的工程\n            // 如果项目存在但是有名称,允许复制\n            if (isExistProject && names != undefined) {\n                fs.copySync(releasePath, rootName);\n            }\n            // 如果项目不存在才会复制\n            if (!isExistProject) {\n                fs.copySync(releasePath, rootName);\n\n            }\n\n            if (fs.existsSync(\"package.json\") && names) {\n\n                // 修改多工程的项目名\n                modifyPackage(names);\n            }\n\n            // 复制模板或者平台或者新的模块\n            if (templateName || platformName || moduleName) {\n\n                // 缓存模板文件夹路径 /demo/cache/templates/\n                let templateCacheDir = path.join(releasePath, templateDirName);\n                // 模板平台文件夹路径 /demo/cache/platforms/\n                let platformCacheDir = path.join(releasePath, platformDirName);\n\n                // 删除根路径并复制模板\n                if (templateName) {\n\n                    // /demo/cache/templates/main-tab\n                    let templateNameCache = path.join(templateCacheDir, templateName);\n                    if (!fs.existsSync(templateNameCache)) {\n                        // 删除缓存\n                        // fs.removeSync(cachePath);\n                        error(\"template \" + templateName + \" is not exist\");\n                        // return;\n                    }\n                    // log(\"Copying template file.\");\n                    initTemplate(templateNameCache);\n                }\n                if (moduleName) {\n                    // /demo/cache/templates/page-newmodule\n                    let templateNameCache = path.join(templateCacheDir, defaultNewModule);\n\n                    if (!fs.existsSync(templateNameCache)) {\n                        // 删除缓存\n                        // fs.removeSync(cachePath);\n                        error(\"template \" + templateName + \" is not exist\");\n                        // return;\n                    }\n                    // log(\"Copying template file.\");\n                    initTemplate(templateNameCache);\n                    // 重命名新模块\n                    moduleName && renameModule(moduleName);\n                }\n                // 复制平台需要的文件\n                if (platformName) {\n                    // /demo/cache/platforms/link\n                    let platformNameCache = path.join(platformCacheDir, platformName);\n                    if (!fs.existsSync(platformNameCache)) {\n\n                        // fs.removeSync(cachePath);\n                        error(\"platform \" + platformName + \" is not exist\");\n                        // return;\n                    }\n                    // log(\"Copying platform file.\");\n                    initPlatform(platformNameCache);\n                }\n\n            }\n            if (!hasJsFolder && !fs.existsSync(path.join(name, \"package.json\"))) {\n                let devCacheDir = hightVersion ? path.join(releasePath, devDirName + \"/node10\") : path.join(releasePath, devDirName + \"/node8\");\n\n                // 初始化NPM模式\n                initDev(devCacheDir);\n\n            }\n            // 最后删除模板文件夹\n            fs.removeSync(templateDir);\n            // 删除开发模式node文件夹\n            fs.removeSync(devDir);\n            // 删除旧版的dev文件夹\n            fs.removeSync(path.join(rootName, \"dev\"));\n            // 最后删除平台文件夹\n            fs.removeSync(platformDir);\n            // 删除缓存\n            // fs.removeSync(cachePath);\n\n            if (typename == \"工程\" || typename == \"平台\") {\n                autoInstall(name);\n            } else {\n                log(`创建${typename}完成.`);\n            }\n\n            // 写入package配置多工程名\n            function modifyPackage(name) {\n                // log(\"modify package.json\");\n                // 获取根目录下的package.json\n                var packageFile = path.join(path.resolve('./'), 'package.json');\n                var package = require(packageFile);\n\n                if (\"projects\" in package) {\n                    // 设置json文件\n                    package.projects[name] = name + '/app.json';\n                    package.scripts[`dev-${name}`] = `cross-env NODE_ENV=${name} gulp dev`;\n                    package.scripts[`build-${name}`] = `cross-env NODE_ENV=${name} gulp build`;\n                    package.scripts[`package-${name}`] = `cross-env NODE_ENV=${name} gulp package`;\n                    // 找到文件并同步修改\n                    fs.writeFileSync(path.resolve(packageFile), JSON.stringify(package, null, 2));\n                } else {\n                    package.projects = {};\n                    package.projects[name] = name + '/app.json';\n                    package.scripts[`dev-${name}`] = `cross-env NODE_ENV=${name} gulp dev`;\n                    package.scripts[`build-${name}`] = `cross-env NODE_ENV=${name} gulp build`;\n                    package.scripts[`package-${name}`] = `cross-env NODE_ENV=${name} gulp package`;\n                    // 找到文件并同步修改\n                    fs.writeFileSync(path.resolve(packageFile), JSON.stringify(package, null, 2));\n                }\n\n            }\n            // 初始化平台\n            function initPlatform(platformDirName) {\n                // log(\"Initing platform...\");\n                // 平台路径 /cache/platforms/link\n                if (!fs.existsSync(platformDirName)) {\n                    warn(`Platform not exist. Using default platform webapp.`);\n                    return\n                }\n                // 项目路径 /\n                fs.copySync(platformDirName, rootName);\n                // sass 平台对应不同的sass工程文件\n                if (platformName === \"sass\") {\n                    let devCacheDir = \"\";\n                    let nodeVerNum = parseFloat(nodeVersion);\n                    if (nodeVerNum > 16) {\n                        devCacheDir = path.join(releasePath, devDirName + \"/node16-sass\");\n                    } else if (nodeVerNum > 10 && nodeVerNum < 16) {\n                        devCacheDir = path.join(releasePath, devDirName + \"/node10-sass\");\n                    } else if (nodeVerNum < 10) {\n                        devCacheDir = path.join(releasePath, devDirName + \"/node8-sass\");\n                    }\n                    // 初始化NPM模式\n                    fs.existsSync(devCacheDir) && initDev(devCacheDir);\n                }\n                else if (platformName === \"typescript\") {\n                    let devCacheDir = path.join(releasePath, devDirName + \"/typescript\");\n                    // 初始化NPM模式\n                    initDev(devCacheDir);\n                }\n                // log(\"Copy platforms done.\");\n            }\n\n            // 修改模块名字\n\n            function renameModule(moduleName) {\n\n                // 修改目录\n                var pathModuleRoot = path.join(rootName, `pages/${defaultNewModule}`)\n                var pathNewModuleRoot = path.join(rootName, `pages/${moduleName}`)\n                // 修改目录\n                fs.rename(pathModuleRoot, pathNewModuleRoot, function (err) {\n                    if (err) {\n                        warn(`存在相同的模块目录:${moduleName},请更换个名字重试!`);\n                        fs.removeSync(pathModuleRoot);\n\n                        return;\n                        // throw err;\n                    }\n                    log(`create ${moduleName} Module done!`);\n                })\n\n            }\n            // 初始化模板\n            function initTemplate(templateDirName) {\n                log(\"创建模板中...\");\n                // 模板路径 /cache/templates/main-tab\n                if (!fs.existsSync(templateDirName)) {\n                    warn(`模板不存在，请检查后重试`);\n                    return;\n                }\n                // 项目路径 /\n                fs.copySync(templateDirName, rootName);\n                // log(\"模板创建完成.\");\n            }\n            // 初始化开发模式到根路径\n            function initDev(devsDirName) {\n                // 项目路径 /\n                fs.copySync(devsDirName, name);\n                // log(\"Copy Dev done.\");\n            }\n        }, needRequest);\n\n    }\n\n\n}\n\n// 清除掉下载的缓存\nfunction clearCache() {\n    let hasCache = fs.existsSync(CACHE_TEMPLATE_PATH);\n\n    if (hasCache) {\n        // 最后删除模板文件夹\n        fs.removeSync(CACHE_TEMPLATE_PATH);\n    }\n}\n\n/**\n * 升级项目的bui版本,不覆盖index.html,index.js两个文件.\n * @param  {string} [name] project name.\n * @param  {string} [version] bui version.\n * @param  {string} [platformName] init platforms/ dir with specified template\n * @param  {string} [dev] 更新gulpfile.js package.js app.json\n */\nfunction updateProject(names, version, platformName, devName, repoName) {\n    var name = '';\n    repoName = repoName || 'easybui';\n    if (names && names.includes('.')) {\n        name = path.resolve('./');\n        version = names;\n    } else {\n        name = names || path.resolve('./');\n        version = version;\n    }\n\n    // if (repoName) {\n    //     toggleRepo(repoName);\n    // }\n\n    // 通过判断当前目录下是否有\n    let hasJsFolder = fs.existsSync(path.join(name, \"js\")) || fs.existsSync(path.join(name, \"pages\"));\n    // 如果是开发模式,源码全在src目录,并且有 package.json\n    let rootName = hasJsFolder ? name : name + '/src';\n\n    // 如果用户有传项目名称,没有则在当前目录创建,检测是否存在js目录,用于检测\n    checkProjectIsExist();\n\n    // 检测工程目录是否存在, 警告用户会覆盖工程\n    function checkProjectIsExist() {\n        // 如果存在js目录\n        if (hasJsFolder || fs.existsSync(\"src\")) {\n            warn(`已经存在一个工程.`);\n            var prompt = new confirm('是否覆盖工程，继续请按回车键?');\n            prompt.ask(function (answer) {\n                if (!answer) {\n                    // error(`File already exist.`);\n                    return;\n                } else {\n                    // log(\"Overwrite project...\");\n                    createProject();\n                }\n            });\n            return;\n        }\n        log(\"开始更新工程...\");\n        createProject();\n    }\n    // 创建工程\n    function createProject() {\n        // 获取bui版本，操作方式跟github不一样\n        // var fetchRepo = repoName && repoName == 'easybui' ? fetchMethod[\"fetchEasybuiRelease\"] : fetchMethod[\"fetchRelease\"];\n        var fetchRepo = fetchMethod[\"fetchEasybuiRelease\"];\n\n        fetchRepo(version, function (releasePath) {\n            // 工程缓存路径 /demo/cache\n            let cachePath = path.join(name, \"cache\");\n\n            // 开发包\n            let devCachePath = path.join(releasePath, \"dev\");\n            let packageFile = path.join(name, \"package.json\");\n            // 平台\n            let buiCssCachePath = path.join(releasePath, \"css\");\n            let buiCssFileCachePath = path.join(buiCssCachePath, \"bui.css\");\n            let buiJsCachePath = path.join(releasePath, \"js\");\n            let buiJsFileCachePath = path.join(buiJsCachePath, \"bui.js\");\n            // 项目目录\n            let buiCssPath = path.join(rootName, \"css\");\n            let buiCssFilePath = path.join(buiCssPath, \"bui.css\");\n            let buiJsPath = path.join(rootName, \"js\");\n            let buiJsFilePath = path.join(buiJsPath, \"bui.js\");\n\n            // 项目平台文件夹路径 /demo/platforms\n            let platformDir = path.join(rootName, platformDirName);\n\n            log(\"copy cache file...\");\n            try {\n                // 复制文件到项目的cache目录\n                // fs.copySync(releasePath, cachePath);\n                // 再从cache复制bui.css文件到根目录,样式是通用的\n                fs.copySync(buiCssFileCachePath, buiCssFilePath);\n            } catch (e) {\n                warn(`copy bui.css file error`);\n            }\n\n            if (platformName) {\n\n                // 模板平台文件夹路径 /demo/cache/platforms/\n                let platformCacheDir = path.join(releasePath, platformDirName);\n\n\n                // 复制平台需要的文件\n                // /demo/cache/platforms/link\n                let platformNameCache = path.join(platformCacheDir, platformName);\n                initPlatform(platformNameCache);\n            } else {\n                try {\n                    // 再从cache复制bui.js webapp版文件到根目录\n                    fs.copySync(buiJsFileCachePath, buiJsFilePath);\n                } catch (e) {\n                    warn(`copy bui.js file error`);\n                }\n\n            }\n\n            // 更新npm 的包\n            if (devName) {\n                // 默认: 模板平台文件夹路径 /demo/cache/node/  如果有名称则是创建 /demo/cache/node/node10 之类的文件名\n                let devCacheDir = devName === true ? path.join(releasePath, devDirName + \"/node10\") : path.join(releasePath, devDirName + \"/\" + devName);\n                // 初始化NPM模式\n                initDev(devCacheDir);\n\n            }\n\n            // 删除缓存\n            // fs.removeSync(cachePath);\n\n\n            // 过滤掉 index.html, index.js 文件\n            function filterFunc(src, dest) {\n                // cache/index.html , cache/index.js\n                let indexHtml = path.join(src, \"index.html\");\n                let indexJs = path.join(src, \"index.js\");\n\n                try {\n                    // // 删除index.html,index.js文件以后再复制,防止覆盖用户原本的业务\n                    fs.existsSync(indexHtml) && fs.unlink(indexHtml);\n                    fs.existsSync(indexJs) && fs.unlink(indexJs);\n                } catch (e) {\n                    console.log(e);\n                }\n                return true;\n            }\n            // 初始化平台\n            function initPlatform(platformDirName) {\n\n                // 平台路径 /cache/platforms/link\n                if (!fs.existsSync(platformDirName)) {\n                    warn(`Platform not exist.`);\n                    return\n                }\n                log(\"Update platform...\");\n                let buijs = path.join(platformDirName, \"js\");\n                let buijsSrc = path.join(rootName, \"js\");\n                // 更新平台下的js目录\n                // fs.copySync(platformDirName, rootName, { filter: filterFunc });\n                fs.copySync(buijs, buijsSrc);\n                log(\"Platform update done.\");\n            }\n            // 初始化dev\n            function initDev(devsDirName) {\n                log(\"Overwrite npm command...\");\n                // // 平台路径 /cache/dev\n                fs.copySync(devsDirName, name);\n                log(\"npm command update done.\");\n            }\n        });\n    }\n\n\n}\n\n\n// 清空某个文件夹目录\nfunction emptyDir(fileUrl) {\n\n    var files = fs.readdirSync(fileUrl); //读取该文件夹\n\n    for (let i = 0; i < files.length; i++) {\n        var file = files[i];\n        var stats = fs.statSync(fileUrl + '/' + file);\n        if (stats.isDirectory()) {\n            // templates 目录不删\n            // 清空文件,不包含文件夹\n            // file !== templateDirName && emptyDir(fileUrl+'/'+file);\n            // 清空文件夹,包含文件夹\n            file !== templateDirName && fs.removeSync(fileUrl + '/' + file);;\n        } else {\n            file !== \"README.md\" && fs.unlinkSync(fileUrl + '/' + file);\n            // log(\"删除文件\"+fileUrl+'/'+file+\"成功\");\n        }\n    }\n}\n\n// 获取版本列表\nfunction displayReleases(from) {\n    log(\"Fetching version info...\");\n    from = from || \"easybui\";\n    // toggleRepo(from);\n    request.get(BUI_TEMPLATE_RELEASE_URL, function (err, res, body) {\n        if (err) error(err);\n        if (res.statusCode != 200) error(`Failed to fetch releases info - ${res.statusCode}: ${res.body}`);\n        let alltags = JSON.parse(body);\n        // let whichTags = from == \"easybui\" ? alltags.data.pageList.data : alltags;\n        let whichTags = alltags.data.pageList.data;\n        // let tags = whichTags.map(function (e) { return from == \"easybui\" ? e[\"version\"] : e[\"tag_name\"] });\n        let tags = whichTags.map(function (e) { return e[\"version\"] });\n        log(\"Available versions:\")\n        tags.forEach(t => {\n            console.log(chalk.green.underline(t));\n        })\n    });\n}\n\n// 获取模板列表\nfunction getAvailableTemplateNames(projectPath, tplName) {\n    let result = [];\n    let tDir = path.join(projectPath, tplName);\n    if (!fs.existsSync(tDir)) return result;\n    let files = fs.readdirSync(tDir);\n    for (let f of files) {\n        if (fs.statSync(path.join(tDir, f)).isDirectory()) {\n            result.push(f);\n        }\n    }\n    return result;\n}\n\n\n// 登录\nfunction login(name) {\n    // log(\"login easybui.com\");\n\n    var schema = {\n    };\n    if (!name) {\n        schema = {\n            properties: {\n                name: {\n                    // pattern: /^[a-zA-Z\\s\\-]+$/,\n                    // message: 'Name must be only letters, spaces, or dashes',\n                    required: true\n                },\n                password: {\n                    hidden: true,\n                    required: true\n                }\n            }\n        };\n        log(\"请输入账号密码，按回车键提交\");\n    } else {\n        schema = {\n            properties: {\n                password: {\n                    hidden: true,\n                    required: true\n                }\n            }\n        };\n        log(\"请输入密码，按回车键提交\");\n    }\n\n\n    prompts.get(schema, function (err, result) {\n        if (err) error(err);\n        //\n        request.post({\n            url: LoginUrl,\n            form: {\n                account: name || result.name,\n                password: result.password\n            }\n        }, function (err, res, body) {\n            if (err) error(err);\n\n            try {\n                var result = JSON.parse(body);\n            } catch (e) {\n            }\n\n            if (result.code) {\n\n                // 保存用户信息\n                jsonfile.writeFileSync(Author_JSON_PATH, body, { spaces: 2 });\n\n                log(\"登录成功\")\n            } else {\n                log(result.msg)\n            }\n\n        });\n    });\n\n}\n\n// 注销\nfunction logout(name) {\n    // log(\"您确定要注销登录吗？\");\n\n    var prompt = new confirm('确定要注销吗?');\n    prompt.ask(function (answer) {\n        if (!answer) {\n            return;\n        } else {\n            try {\n                fs.removeSync(Author_JSON_PATH);\n            } catch (e) {\n            }\n        }\n    });\n\n}\n// 检测是否登录过\nfunction checkLogin() {\n    var authorInfo = { data: { token: \"\" } };\n    if (fs.existsSync(Author_JSON_PATH)) {\n        // 必须使用jsonfile写入跟读取才能转化成对象\n        authorInfo = jsonfile.readFileSync(Author_JSON_PATH);\n\n        try {\n            authorInfo = JSON.parse(authorInfo);\n        } catch (e) {\n        }\n    }\n\n    return authorInfo?.data?.token;\n}\n\nvar args = yargs\n    .command({\n        command: \"login [name] [password]\",\n        desc: \"登录网站，如果没有账号密码，可以从 easybui.com 免费注册。If you don't know the account password, you can register for free from easybui.com \",\n        handler: function (argv) {\n            login(argv.name, argv.password);\n        }\n    })\n    .command({\n        command: \"logout\",\n        desc: \"注销登录 \",\n        handler: function (argv) {\n            logout();\n        }\n    })\n    .command({\n        command: \"create [name] [version]\",\n        desc: \"创建BUI的脚手架工程. 参数: name:工程名, version: bui版本. Create scaffolding project for BUI. Parameters: name: project name, version: bui version.\",\n        builder: (yargs) => {\n            yargs.option('template', {\n                alias: 't',\n                describe: '使用某个模板创建. build using a template.'\n            }).option('platform', {\n                alias: 'p',\n                describe: '使用某个平台工程创建. Build with a platform project.'\n            }).option('module', {\n                alias: 'm',\n                describe: '创建新模块. Create new module'\n            }).option('from', {\n                alias: 'f',\n                describe: '从哪个源创建，默认 easybui | github. Which source to create from, default easybui | github'\n            })\n        },\n        handler: function (argv) {\n\n            // 获取cli是否有最新版本\n            getCliVersion({\n                id: \"267\"\n            });\n\n            var isLogin = checkLogin();\n\n            // 第一步验证是否登录过，第二步验证token过期\n            if (isLogin) {\n\n                initProject(argv.name, argv.version, argv.template, argv.platform, argv.module, argv.from);\n\n            } else {\n                error(\"先执行 buijs login 进行登录, 如果没有账号，请从 https://www.easybui.com 免费注册.\")\n            }\n        }\n    })\n    .command({\n        command: \"update [name] [version]\",\n        desc: \"更新工程里bui的版本, 不传参数时，默认为最新版本. Update the version of bui in the project. When no parameter is passed, the default is the latest version.\",\n        builder: (yargs) => {\n            yargs.option('platform', {\n                alias: 'p',\n                describe: 'Update with specified platform.'\n            }).option('dev', {\n                alias: 'd',\n                describe: 'Update npm command.'\n            }).option('from', {\n                alias: 'f',\n                describe: 'from repo.'\n            })\n        },\n        handler: function (argv) {\n            var isLogin = checkLogin();\n\n            // 第一步验证是否登录过，第二步验证token过期\n            if (isLogin) {\n                updateProject(argv.name, argv.version, argv.platform, argv.dev, argv.from);\n            } else {\n                error(\"先执行 buijs login 进行登录, 如果没有账号，请从 https://www.easybui.com 免费注册.\")\n            }\n        }\n    })\n    .command({\n        command: \"get [id] [name]\",\n        desc: \"获取远程组件跟模板\",\n        builder: (yargs) => {\n            yargs.option('save', {\n                alias: 's',\n                describe: '保存本地路径 默认 pages/.'\n            }).option('remote', {\n                alias: 'r',\n                describe: '获取远程模板'\n            })\n        },\n        handler: function (argv) {\n\n            var token = checkLogin();\n\n            // 第一步验证是否登录过，第二步验证token过期\n            if (token) {\n                argv.token = token;\n                getComponent(argv);\n            } else {\n                error(\"先执行 buijs login 进行登录, 如果没有账号，请从 https://www.easybui.com 免费注册.\")\n            }\n        }\n    })\n    .command({\n        command: \"add [name] [target]\",\n        desc: \"添加bui npm的组件到工程里. Add npm module to the project\",\n        builder: (yargs) => {\n            yargs.option('add', {\n                alias: 'a',\n                describe: '把npm里面的bui组件 添加到工程里，默认 pages/.'\n            })\n        },\n        handler: function (argv) {\n\n            let targetpath = argv.target || \"pages/components/\";\n            let componentpath = path.join(process.cwd(), 'node_modules', argv.name);\n            let targetPath = path.join(process.cwd(), 'src', targetpath, argv.name);\n\n            // nodemodule 是否存在这个组件\n            let hasNodeModule = fs.pathExistsSync(componentpath);\n            // 工程是否有存在目录\n            let hasProjectModule = fs.pathExistsSync(targetPath);\n            if( hasNodeModule ){\n                // 复制组件过去\n                fs.copySync(componentpath, targetPath); \n            }else{\n                error(`请先执行 npm i ${argv.name} --save`);\n            }\n\n        }\n    })\n    .command({\n        command: \"list\",\n        desc: \"列出所有能创建的版本标签. List all version tags that can be created.\",\n        builder: (yargs) => {\n            yargs.option('from', {\n                alias: 'f',\n                describe: 'from repo.'\n            })\n        },\n        handler: function (argv) {\n            displayReleases(argv.from);\n        }\n    })\n    .command({\n        command: \"list-template\",\n        desc: \"列出所有模板名字，结合-t参数使用. List all template names, use with -t parameter\",\n        handler: function () {\n\n            fetchEasybuiRelease(null, (projectPath) => {\n                let names = getAvailableTemplateNames(projectPath, templateDirName);\n                if (names.length) {\n                    console.log(\"Available templates:\");\n                    names.forEach(n => {\n                        console.log(chalk.green.underline(n));\n                    })\n                } else {\n                    console.log(\"No templates available.\");\n                }\n            })\n        }\n    })\n    .command({\n        command: \"list-platform\",\n        desc: \"列出所有平台名字，结合-p参数使用. List all platform names, used in conjunction with the -p parameter\",\n        handler: function () {\n            fetchEasybuiRelease(null, (projectPath) => {\n                let names = getAvailableTemplateNames(projectPath, platformDirName);\n                if (names.length) {\n                    console.log(\"Available platforms:\");\n                    names.forEach(n => {\n                        console.log(chalk.green.underline(n));\n                    })\n                } else {\n                    console.log(\"No platforms available.\");\n                }\n            })\n        }\n    })\n    .command({\n        command: \"opendoc [name]\",\n        desc: \"buijs opendoc 打开入门文档，buijs opendoc api 打开api文档\",\n        handler: function (argv) {\n            var open = require('open');\n\n            if (argv.name == \"component\") {\n                // 使用默认浏览器打开\n                open('https://www.easybui.com/p/component.html');\n            } else {\n                // 使用默认浏览器打开\n                open('https://www.easybui.com/p/doc.html');\n            }\n        }\n    })\n    .command({\n        command: \"openapi\",\n        desc: \"buijs opendoc 打开入门文档，buijs opendoc api 打开api文档\",\n        handler: function (argv) {\n            var open = require('open');\n\n            // 使用默认浏览器打开\n            open('https://www.easybui.com/p/api.html');\n        }\n    })\n    .command({\n        command: \"clear\",\n        desc: \"清除创建缓存. clear cache.\",\n        handler: function () {\n            clearCache();\n        }\n    })\n    .version() // Use package.json's version\n    .help()\n    .alias({\n        \"h\": \"help\",\n        \"v\": \"version\"\n    })\n    .strict(true)\n    .demandCommand()\n    .epilogue('buijs cli 当前版本：' + currentVersion)\n    .argv;"]}