cli-z-develop
Advanced tools
Comparing version
@@ -1,1 +0,1 @@ | ||
import{program as e}from"commander";import t from"node:child_process";import n from"node:fs";import i from"node:path";import a,{AxiosError as s}from"axios";import r from"chalk";import o from"dayjs";import c from"shelljs";import u from"node:os";import l from"child_process";import{confirm as p,select as m,input as d,password as g,checkbox as f}from"@inquirer/prompts";import h from"ora";import w from"fs-extra";import{select as y}from"inquirer-select-pro";import v from"lint-staged";import $ from"semver";import{run as b}from"npm-check-updates";import j from"minimist";var S,E,k;!function(e){e.DEV="dev",e.TEST="test",e.RELEASE="release",e.PROD="production"}(S||(S={})),function(e){e.DEV="dev",e.TEST="test",e.RELEASE="release",e.MASTER="master"}(E||(E={})),function(e){e.H5="h5",e.NPM="npm"}(k||(k={}));const T=[{name:`开发环境 - ${S.DEV}`,value:S.DEV},{name:`测试环境 - ${S.TEST}`,value:S.TEST},{name:`预发环境 - ${S.RELEASE}`,value:S.RELEASE},{name:`正式环境 - ${S.PROD}`,value:S.PROD}],A=[{name:`网页 - ${k.H5}`,value:k.H5},{name:`依赖包 - ${k.NPM}`,value:k.NPM}];var x,C;!function(e){e.FEAT="feat",e.FIX="fix",e.REFACTOR="refactor"}(x||(x={})),function(e){e.JAVA="Java",e.JAVASCRIPT="JavaScript"}(C||(C={}));const R={1:"研发",2:"测试",3:"产品",4:"设计",5:"运营",6:"销售",7:"行政",8:"财务",9:"其他"},N="http://git.cxlqd.com",P={PROJECT_NAME:"fe-pages-tpl",GIT_URL:`${N}/fe-component/fe-pages-tpl.git`},D=["fe-biz","fe-base","fe-tpl","fe-component","fe-demo"];var z;!function(e){e.FEAT="feat",e.FIX="fix",e.REFACTOR="refactor",e.CHORE="chore",e.CI="ci",e.Break="BREAKING CHANGE"}(z||(z={}));const O="fe-biz7tvsd";const M='{\n "printWidth": 120,\n "tabWidth": 2,\n "useTabs": false,\n "semi": true,\n "singleQuote": false,\n "quoteProps": "as-needed",\n "jsxSingleQuote": false,\n "trailingComma": "all",\n "bracketSpacing": true,\n "bracketSameLine": false,\n "arrowParens": "always",\n "requirePragma": false,\n "insertPragma": false,\n "proseWrap": "preserve",\n "htmlWhitespaceSensitivity": "css",\n "vueIndentScriptAndStyle": false,\n "endOfLine": "lf",\n "embeddedLanguageFormatting": "auto",\n "singleAttributePerLine": false\n}\n',F="# 系统 信息文件\n.DS_Store/\nThumbs.db\n\n# 编辑器配置文件\n.idea/\n.vscode/\n\n# 输出目录\ndist/\n\n# Log files\n*.log\n\n# 本地配置文件\n*.local\n\n# 缓存文件\n*.cache\n\n# 垃圾文件\n.Trashes\n",B={[C.JAVA]:{"**/*.{java}":"./run.sh pmd -d ../../../src/main/java/ -f text -R rulesets/java/quickstart.xml"},[C.JAVASCRIPT]:{"**/*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}":"eslint --fix","*":"prettier -wu"}},I=".z",_="develop-config.json",J=".z",L=".commit-msg-tpl",W="project.json";function U(e=""){return i.join(J,e)}function q(){return U(W)}function V(){return U(L)}function H(){l.spawnSync("git",["config","core.hooksPath",U()]),l.spawnSync("git",["config","commit.template",V()])}function G(e=""){return i.resolve(u.homedir(),I,e)}function K(){return G(_)}function Q(){return n.existsSync(G())&&n.existsSync(K())}const{red:X,green:Z,blue:Y,magenta:ee}=r;function te(...e){console.log(Z(...e))}function ne(e,t=!1){let n=e;e instanceof Error?(n=e.message,a.isAxiosError(e)&&(n=`请求失败:${e.message}`),console.log(X(n)),console.log(ee(e.stack))):console.log(X(e)),t||process.exit(1)}function ie(e){return!!n.existsSync(e)&&n.lstatSync(e).isDirectory()}function ae(e=process.cwd()){if(ie(e)){return n.readdirSync(e).filter((t=>ie(i.resolve(e,t))))}return[]}function se(e=process.cwd()){if(ie(e)){return n.readdirSync(e).filter((t=>!ie(i.resolve(e,t))))}return[]}async function re(e,t={removeTailLinkBreak:!0,silent:!0}){let n=await new Promise(((n,i)=>{try{n(c.exec(e,{silent:t.silent}))}catch(e){i(e)}}));return n=n.toString(),t.removeTailLinkBreak&&(n=n.replace(/\n$/,"")),n}function oe(e){t.execSync(e,{stdio:"inherit"})}function ce(){return o(Date.now()).format("YYMMDD")}function ue(){n.existsSync(U())||ne("当前不在项目根目录。请切换到项目根目录")}function le(){n.existsSync(i.resolve(".git"))||ne("当前不是git项目根目录,请先执行git init,或切换到根目录")}async function pe(){""!==await re("git status -s")&&ne("请先提交代码变动,再进行操作")}function me(e){return["fe-biz"].includes(e)}var de={name:"cli-z-develop",version:"0.4.2",description:"前端本地开发命令行工具",main:"dist/index.js",bin:{z:"bin/z.js","z-develop":"bin/z.js"},scripts:{prepare:"[ -n '$z' ] && z init prepare || echo 'Warning: z not exist at global'",dev:"rollup -c -w --environment DEBUG:true",build:"rollup -c",eslint:"eslint '**/*.{ts,js}' --fix",prettier:"prettier -wu .",upload:"npm run build && npm publish --access public --registry https://registry.npmjs.org/","upload:patch":"npm version patch && npm run upload","upload:minor":"npm version minor && npm run upload","upload:major":"npm version major && npm run upload"},type:"module",author:"z",devDependencies:{"@lonely9/eslint-config-team":"^1.2.3","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^16.0.1","@rollup/plugin-replace":"v6.0.2","@rollup/plugin-terser":"^0.4.4","@tsconfig/node22":"^22.0.2","@types/fs-extra":"^11.0.4","@types/inquirer":"^9.0.8","@types/minimist":"^1.2.5","@types/node":"^22.15.29","@types/semver":"^7.7.0","@types/shelljs":"^0.8.16","@typescript-eslint/eslint-plugin":"^8.32.1","@typescript-eslint/parser":"^8.32.1",eslint:"^9.27.0",jiti:"^2.4.2",prettier:"^3.5.3",rollup:"^4.41.1","rollup-plugin-typescript2":"^0.36.0",typescript:"^5.8.3","vue-tsc":"^2.2.10"},dependencies:{"@inquirer/prompts":"^7.5.3",axios:"^1.9.0",chalk:"^5.4.1",commander:"^14.0.0",dayjs:"^1.11.13",figures:"^6.1.0","fs-extra":"^11.3.0","inquirer-select-pro":"^1.0.0-alpha.9","lint-staged":"^16.1.0",minimist:"^1.2.8","npm-check-updates":"^18.0.1",ora:"^8.2.0",rxjs:"^7.8.2",semver:"^7.7.2",shelljs:"^0.10.0"}};const ge={profile:{ldapAccount:"",ldapPassword:"",gitToken:"",gitUserId:0,gitName:"",gitEnglishName:"",gitEmail:"",weWorkName:"",weWorkUserId:"",jobType:"fe",zenTaoToken:"",k8sToken:""},main:{version:de.version,latestCheckVersionTimestamp:0,versionCheckDuring:3,weWorkListCache:[]},constants:{ZenTaoDomain:"",K8sDomain:"",FEServerDomain:"",K8SWebDomain:""}};function fe(e){return e?ge.profile[e]:ge.profile}function he(e){return e?ge.main[e]:ge.main}function we(e){return e?ge.constants[e]:ge.constants}let ye=null,ve=null;function $e(){if(ye)return ye;const e=i.join("package.json");return n.existsSync(e)||ne(`当前目录(${c.pwd()})不存在${e}文件,请在项目根目录执行该命令。`),ye=w.readJsonSync(e),ye}function be(){if(ve)return ve;const e=q();return n.existsSync(e)||ne(`当前目录(${c.pwd()})不存在${e}文件,请在项目根目录执行该命令,或者初始化项目(z init .)。`),ve=w.readJsonSync(e),ve}function je(e){ve=ve?{...ve,...e}:e,w.writeJSONSync(q(),ve,{spaces:2})}const Se={id:0,name:"",group:"",sourceBranch:"",mergeRequestUrl:""};async function Ee(){if(!Se.name){const e=$e();Se.name=e.name}if(!Se.group){const e=be();e.repository.group&&(Se.group=e.repository.group)}if(!Se.id)try{const e=Se.group?`${Se.group}/${Se.name}`:Se.name,[t]=await We(e);Se.mergeRequestUrl=`${t.web_url}/merge_requests`,Se.id=t.id,Se.group=t.namespace.path;const n=be();n.repository.group||je({repository:{...n.repository,group:t.namespace.path}})}catch(e){ne(e)}return Se.sourceBranch||(Se.sourceBranch=await re("git branch --show-current")),Se}function ke(){w.writeJSONSync(K(),{main:he(),profile:fe(),constants:we()},{spaces:2})}async function Te(e){const t=G(),a=process.cwd(),s=i.join(t,P.PROJECT_NAME);n.existsSync(s)?(c.cd(s),await re("git pull"),c.cd(a)):(c.cd(t),await re(`git clone ${P.GIT_URL} --depth=1`),c.cd(a));const r=i.join(s,"src",e);return n.existsSync(r)||ne("模板库错误!"),r}function Ae(e){return e.split("-").map((e=>e.charAt(0).toUpperCase()+e.slice(1))).join("")}function xe(e,t){const i=n.readFileSync(e,"utf-8"),a=t.replace(/\//g,"-"),s=i.replace(/name: "-_-NAME-_-"/g,`name: "${Ae(a)}"`).replace(/class="-_-NAME-_-"/g,`class="${a}"`).replace(/.-_-NAME-_-/g,`.${a}`);n.writeFileSync(e,s,"utf-8")}function Ce(e,t){void 0!==t?ge.profile[e]=t:ge.profile={...ge.profile,...e}}function Re(e,t){ge.constants={...ge.constants,...e}}function Ne(e,t){void 0!==t?ge.main[e]=t:ge.main={...ge.main,...e}}async function Pe(e){const t=e.method||"get",n=e.headers||{},i=e.data||{},o=e.dataKey||["GET","get"].includes(t)?"params":"data";try{const s={url:e.url,method:t,[o]:i,headers:n};r.magenta(s.method.toUpperCase()),r.yellow(s.url),JSON.stringify(s.headers),r.gray(JSON.stringify(s[o],null,2));const c=await a(s);return r.green("Response"),r.grey(JSON.stringify(c.data,null,2)),Promise.resolve(c.data)}catch(e){return e instanceof s&&(r.red("Error"),r.grey(JSON.stringify(e?.response?.data))),Promise.reject(e)}}async function De(){const e=fe("gitToken");if(e)return e;{const{access_token:e}=await Pe({url:`${N}/oauth/token`,method:"post",data:{grant_type:"password",username:fe("ldapAccount"),password:fe("ldapPassword")}}),t=`Bearer ${e}`;return Ce("gitToken",t),ke(),t}}async function ze(e){return Pe({...e,headers:{Authorization:await De()}})}async function Oe(){const e=fe("zenTaoToken");if(e)return e;{const{token:e}=await Pe({url:`${we("ZenTaoDomain")}/api.php/v1/tokens`,method:"post",data:{account:fe("ldapAccount"),password:fe("ldapPassword")}});return Ce("zenTaoToken",e),ke(),e}}async function Me(e){const t=await Pe({...e,headers:{Token:await Oe()}});if("string"==typeof t){const e=JSON.parse(t.slice(0,t.indexOf("<script>")));return JSON.parse(e.data)}if("object"==typeof t)return"Unauthorized"===t.error||t.data.indexOf("<script>")<0?(Ce("zenTaoToken",""),Me({...e})):t}async function Fe(){const e=fe("k8sToken");if(e)return e;{const{access_token:e}=await Pe({url:`${we("K8sDomain")}/oauth/login/LDAP`,method:"post",headers:{"Content-Type":"application/x-www-form-urlencoded"},data:{username:fe("ldapAccount"),password:fe("ldapPassword")}}),t=`Bearer ${e}`;return Ce("k8sToken",t),ke(),t}}async function Be(e){const t=await Pe({...e,headers:{Authorization:await Fe()}});return 401===t.code?(Ce("k8sToken",""),Be({...e})):t}const Ie=()=>`${N}/api/v4`,_e=e=>`${Ie()}/projects/100/repository/files/${encodeURIComponent(e)}/raw?ref=master`;function Je(){return ze({url:_e("src/data/template-projects.json")})}function Le(){return ze({url:_e("src/data/z-develop-config.json")})}function We(e){return ze({url:`${Ie()}/projects`,data:{search:e,search_namespaces:!0}})}async function Ue(){const e=await ze({url:`${Ie()}/groups`}),t=D.map((t=>{const n=e.find((e=>e.name===t));return!!n&&{name:n.name,id:n.id,description:n.description}})).filter((e=>Boolean(e)));w.writeJSONSync(G("fe-groups.json"),{groups:t},{spaces:2})}function qe(){return async function(e){const t=`${we("FEServerDomain")}/api`,{data:n}=await Pe({url:`${t}/auth/z-develop/login`,method:"post"}),i=await Pe({url:t+e.url,headers:{Authorization:`Bearer ${n}`},data:e.data,method:e.method||"post"});return 0!==i.code&&ne(`${i.code}: ${i.message}`),i.data}({url:"/user/list2"})}async function Ve(){const e=(await qe()).filter((e=>[1,2,3,4,5].includes(e.title))).map((e=>({name:`${e.nick} - ${R[e.title]}`,value:e.weWorkUserId}))),t=he("weWorkListCache"),n=t.map((e=>e.value)),i=[];return e.forEach((e=>{const a=n.indexOf(e.value);i.push({...e,usageCount:a>-1?t[a].usageCount:0})})),i.sort(((e,t)=>t.usageCount-e.usageCount))}async function He(e,t,n){const i=await Ve();let a=await y({message:e,loop:!0,pageSize:i.length||5,clearInputWhenSelected:!0,multiple:n,options:e=>e?i.filter((t=>t.name.includes(e))):i,validate:t});return a=Array.isArray(a)?a:[a],function(e,t){const n=[];t.forEach((t=>{e.includes(t.value)&&n.push(t)}));const i=he("weWorkListCache"),a=i.map((e=>e.value));n.forEach((e=>{const t=a.indexOf(e.value);t>-1?i[t].usageCount+=1:i.push({...e,usageCount:1})})),Ne({weWorkListCache:i.sort(((e,t)=>t.usageCount-e.usageCount))}),ke()}(a,i),a}async function Ge(){try{if(Q()){await p({message:"系统中已存在z的配置文件,确认重新配置?"})?c.rm("-rf",K()):process.exit(0)}n.mkdirSync(G(),{recursive:!0});const e=await m({message:"请选择岗位类型",choices:[{name:"前端",value:"fe"},{name:"后端",value:"be"}]}),t=await d({message:"请输入LDAP账号:"}),i=await g({message:"请输入LDAP密码:",mask:!0});Ce("jobType",e),Ce("ldapAccount",t),Ce("ldapPassword",i);Re(await Le());const a=await Ve(),s=await He("请选择你自己(用于企微通知):",(e=>e.length>1?"只能选一个":!(e.length<1)||"请选一个"),!1),{name:r,value:o}=a.find((e=>e.value===s[0]));Ce({weWorkName:r,weWorkUserId:o})}catch(e){ne(e)}const e=h("配置信息初始化中").start();try{const t=await ze({url:`${Ie()}/user`});Ce({gitUserId:t.id,gitName:t.name,gitEnglishName:t.username,gitEmail:t.email}),Ne("latestCheckVersionTimestamp",Date.now()),ke(),await Ue(),e.succeed("配置信息初始化完成"),process.exit(0)}catch(t){e.fail("配置信息初始化失败"),a.isAxiosError(t)&&ne("请检查你的域名及令牌配置"),ne(t)}}const Ke='{\n "$schema": "https://json.schemastore.org/tsconfig",\n "_version": "0.0.1",\n "compilerOptions": {\n "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.browser.tsbuildinfo",\n "lib": ["ESNext", "DOM", "DOM.Iterable", "WebWorker"],\n // 编译时无需导出类型文件\n "noEmit": true,\n\n // 编译时用模块最新规范,至于打包代码时的兼容问题,交给vite/webpack们解决\n "module": "ESNext",\n // 模块解析策略。同上\n "moduleResolution": "Bundler",\n // 可以使用import...from导入json文件\n "resolveJsonModule": true,\n // 带上文件后缀,避免歧义。至于兼容性,交给vite/webpack们解决\n "allowImportingTsExtensions": true,\n // 识别一个文件是模块还是脚本,由于使用了打包工具,所以所有文件都是模块\n "moduleDetection": "force",\n\n // tsc编译时不转化jsx,留给打包工具处理\n "jsx": "preserve",\n // 指定处理jsx的库\n "jsxImportSource": "vue",\n\n // 必须显式声明this的类型,否则报错\n "noImplicitThis": true,\n // 严格模式。将默认开启以下规则:\n // noImplicitAny noImplicitThis alwaysStrict strictBindCallApply strictNullChecks strictFunctionTypes strictPropertyInitialization\n "strict": true,\n\n // 引入类型需要type关键字\n "verbatimModuleSyntax": true,\n\n // 编译目标用最新规范,至于打包代码时的兼容问题,交给vite/webpack们解决\n "target": "ESNext",\n // 合理编译class\n "useDefineForClassFields": true,\n\n // commonjs 和 es module之间可以互操作\n "esModuleInterop": true,\n // 引用路径中文件名大小写敏感\n "forceConsistentCasingInFileNames": true,\n // 会检查自建的和依赖库的所有.d.ts。调试自建d.ts文件时可以考虑打开\n "skipLibCheck": true\n }\n}',Qe='{\n "$schema": "https://json.schemastore.org/tsconfig",\n "_version": "0.0.1",\n "compilerOptions": {\n "lib": ["ESNext"],\n // 编译时无需导出类型文件\n "noEmit": true,\n\n // 编译时用模块最新规范,至于打包代码时的兼容问题,交给vite/webpack们解决\n "module": "ESNext",\n // 模块解析策略。同上\n "moduleResolution": "Bundler",\n // 可以使用import...from导入json文件\n "resolveJsonModule": true,\n // 识别一个文件是模块还是脚本,由于使用了打包工具,所以所有文件都是模块\n "moduleDetection": "force",\n\n // 必须显式声明this的类型,否则报错\n "noImplicitThis": true,\n // 严格模式。将默认开启以下规则:\n // noImplicitAny noImplicitThis alwaysStrict strictBindCallApply strictNullChecks strictFunctionTypes strictPropertyInitialization\n "strict": true,\n\n // 引入类型需要type关键字\n "verbatimModuleSyntax": true,\n\n // 编译目标用最新规范,至于打包代码时的兼容问题,交给vite/webpack们解决\n "target": "ESNext",\n // 合理编译class\n "useDefineForClassFields": true,\n\n // commonjs 和 es module之间可以互操作\n "esModuleInterop": true,\n // 引用路径中文件名大小写敏感\n "forceConsistentCasingInFileNames": true,\n // 会检查自建的和依赖库的所有.d.ts。调试自建d.ts文件时可以考虑打开\n "skipLibCheck": true,\n },\n}';let Xe;async function Ze(e,t){if(e)c.rm("-rf",J);else if(n.existsSync(U())){await p({message:`当前项目中已存在配置文件夹${J},确认重新配置?`})?c.rm("-rf",J):process.exit(0)}n.mkdirSync(U(),{recursive:!0}),await async function(e,t){const n=await re("git remote get-url --push origin");n||ne("获取项目远程地址失败,请配置后重试");let i=e;i||(i=await m({message:"请选择项目语言",choices:[{name:C.JAVASCRIPT,value:C.JAVASCRIPT},{name:C.JAVA,value:C.JAVA}]}));let a=t;const s=$e();if(!a){const e=await We(s.name);1===e.length?a=e[0].namespace.path:e.length>1&&(a=await m({message:"请选择当前项目所属分组",choices:e.map((e=>({name:e.namespace.path,value:e.namespace.path})))}))}Xe=h("项目初始化中").start(),je({language:i,"lint-staged":B[i],repository:{url:n,group:a}})}(e,t),n.writeFileSync(V(),"",{mode:493}),n.writeFileSync(U("commit-msg"),"#!/usr/bin/env sh\nz run commit-msg",{mode:493}),n.writeFileSync(U("pre-commit"),"#!/usr/bin/env sh\nz run commit-files",{mode:493}),n.writeFileSync(U(".prettierrc.json"),M,{mode:493}),n.writeFileSync(U(".prettierignore"),F,{mode:493}),n.writeFileSync(U("tsconfig.node.json"),Qe,{mode:493}),n.writeFileSync(U("tsconfig.browser.json"),Ke,{mode:493}),H(),Xe?.succeed("初始化完成。")}async function Ye(e){if(!e)return"不能为空";if(!/^[a-z0-9-]+$/.test(e))return"格式为小写字母、中横线(可选)、数字(不推荐)。如apple, apple-tree";if(ae().includes(e))return"当前目录下已存在同名文件夹,请先处理。";return!(await We(e)).find((t=>t.name===e))||"远程仓库中已存在同名项目"}function et(e){return!!e||"不能为空"}function tt(e){return e?!!/^[a-zA-Z0-9.]+$/.test(e)||"格式为大小写字母、数字、小数点,小驼峰命名。如userInfo、systemRouter3":"不能为空"}function nt(e){if(!e)return"目录名称不能为空";if(!/^[a-z][a-z0-9\-/]*$/.test(e))return"支持小写字母、数字,连字符(-)命名,小写字母开头,多层目录使用/隔开。如user、modules-3、setting/profile";if(e.includes("/")){const t=e.split("/");for(const e of t){if(!e)return"子级目录/页面名称不能为空";if(!/^[a-z][a-z0-9-]*$/.test(e))return"支持小写字母、数字,连字符(-)命名,小写字母开头。如user、modules-3"}}let t,a;t=e.includes("/")?i.resolve("src","pages",...e.split("/")):i.resolve("src","pages",e);const s=i.resolve(t,"..");return a=!!n.existsSync(s)&&n.readdirSync(s).map((e=>{const t=e.lastIndexOf(".");return t>-1?e.slice(0,t):e})).includes(e),!a||"本地目录已存在该文件"}e.command("init").alias("i").argument("[type]","非必填。不传为初始化工具配置;传 . 为初始化当前项目。").option("--project-language","项目语言。可选值:Java / Javascript").description("初始化工具配置、项目配置").action((async function(e,t){e?(le(),"."===e?(t.projectLanguage&&!Object.values(C).includes(t.projectLanguage)&&ne("项目语言错误"),await Ze(t.projectLanguage,void 0),process.exit(0)):"prepare"===e?await async function(){n.existsSync(U())&&n.existsSync(V())?H():await Ze(),process.exit(0)}():ne("参数错误。执行 z init -h 查看帮助。")):await Ge()}));const it=e=>`${we("ZenTaoDomain")}${e}`;function at(e,t){let i="";if([z.FEAT,z.FIX,z.REFACTOR].includes(e)){i=`${e}(${t.map((e=>e.value)).join(",")}): ${t.map((e=>e.name)).join(";")}`}e===z.CHORE&&(i=`${e}: ${t}`),n.writeFileSync(V(),i,"utf-8"),console.log(r.yellow(i)),te("commit msg模板写入成功,可以进行提交了")}async function st(){const e=await m({message:"请选择你要创建的模板类型",choices:[{name:"feat - 业务需求开发",value:z.FEAT},{name:"fix - bug修复",value:z.FIX},{name:"refactor - 技术内部需求",value:z.REFACTOR},{name:"chore - 其他",value:z.CHORE}]});if([z.FEAT,z.REFACTOR].includes(e)){const e=await async function(){const e=await Me({url:it("/my-work-task.json?tid=mrrferp8"),method:"get"});return e?.tasks.filter((e=>"done"!==e.status)).map((({id:e,name:t})=>({value:{name:t,value:e},name:t})))}(),t=await f({message:"请关联开发任务(可多选):",validate:e=>0!==e.length||"请选择项",choices:e.map((e=>({...e,name:`[${e.value.value}]: ${e.name}`})))});at(z.FEAT,t)}if(e===z.FIX){const e=await async function(){const e=await Me({url:it("/my-work-bug.json?tid=mrrferp8"),method:"get"});return e?.bugs.map((({id:e,title:t})=>({name:t,value:{name:t,value:e}})))}(),t=await f({message:"请关联Bug(可多选):",validate:e=>0!==e.length||"请选择项",choices:e.map((e=>({...e,name:`[${e.value.value}]: ${e.name}`})))});at(z.FIX,t)}if(e===z.CHORE){const e=await d({message:"请输入commit msg:",validate:e=>0!==e.length||"请输入commit msg"});at(z.CHORE,e)}process.exit(0)}async function rt(){try{const a={},s=async()=>{const e=ae(),{projects:t}=await Je(),n=t.map((t=>{const n={name:`${t.name} [${t.desc}]`,value:t.name,disabled:!1};return e.includes(t.name)&&(n.disabled="目录下已存在同名文件夹"),n})),i=await m({message:"请选择一个项目模板",choices:n}),s=t.find((e=>e.name===i));a.tplName=s.name,a.tplUrl=s.url,a.tplLanguage=s.language},o=async()=>{const{groups:e}=function(){const e=G("fe-groups.json");return n.existsSync(e)?w.readJSONSync(e):{groups:[]}}(),t=await m({message:"请选择一个分组",choices:e.map((e=>({name:`${e.name} [${e.description}]`,value:e.id,short:e.name})))});a.group={id:t,name:e.find((e=>e.id===t))?.name}},u=async()=>{a.projectName=await d({message:"请输入项目名称",validate:Ye}),a.projectDesc=await d({message:"请输入项目描述",validate:et})};await s(),await o(),await u();const l=`${N}/${a.group?.name}/${a.projectName}.git`,p=h("模版初始化中").start();await re(`git clone --depth=1 ${a.tplUrl}`),n.renameSync(a.tplName,a.projectName),c.cd(a.projectName),c.rm("-rf",".git"),await re(`git init --initial-branch=${E.MASTER}`),await re(`git remote add origin ${l}`),await re(`git config user.name ${fe("gitName")}`),await re(`git config user.email ${fe("gitEmail")}`);const g=$e();t={...g,name:a.projectName,description:a.projectDesc,scripts:{...g.scripts,prepare:"[ -n '$z' ] && z init prepare || echo 'Warning: z not exist at global'"}},ye=ye?{...ye,...t}:t,w.writeJSONSync(i.join("package.json"),ye,{spaces:2}),await w.writeFile(i.resolve("README.md"),function(e="项目中文名",t="项目描述"){return`\n# ${e}\n${t}\n\n## 快速开始\n### 安装依赖\n\`\`\`bash\n npm i\n\`\`\`\n\n### 本地开发\n\`\`\`bash\n npm run dev:<environment>:[platform]\n\`\`\`\n\n### 打包代码\n\`\`\`bash\n npm run build:<environment>:[platform]\n\`\`\`\n\n\n### 查找、修复代码问题\n\`\`\`bash\n z run eslint\n # 或者\n z r e\n\`\`\`\n\n### 格式化代码\n\`\`\`bash\n z run prettier\n # 或者\n z r p\n\`\`\`\n\n### 检测类型问题\n\`\`\`bash\n z run type-check\n # 或者\n z r tc\n\`\`\`\n\n### 检测依赖更新\n\`\`\`bash\n z run dependency-check\n # 或者\n z r dc\n\`\`\`\n\n## 常见问题\n列出开发中常见的问题和解决方案\n\n## 了解更多\n在此处放入飞书文档链接。请在[前端团队-项目手册](https://hxhtbr8t8uy.feishu.cn/drive/folder/QfQ7favVWljQk7d63Prc8mUGnJf)中按照分类新建文档。\n`}(a.projectName,a.projectDesc)),p.succeed("模版初始化完成"),await Ze(a.tplLanguage,a.group?.name);const f=h("依赖安装中").start();await re("npm install --registry https://registry.npmmirror.com/"),f.succeed("依赖安装完成");const y=h("项目推送中").start();await re('git add . && git commit -m "chore: 项目初始化"'),await re("git tag v0.0.1");const v=await(e={name:a.projectName,description:a.projectDesc,path:a.projectName,visibility:"private",namespace_id:a.group?.id},ze({url:`${Ie()}/projects`,method:"post",data:e}));await re(`git push -u origin ${E.MASTER}`),await re(`git push origin HEAD:${E.MASTER} --tags`),y.succeed(`项目已推送到远程,地址: ${r.blue(l)}`);const $=h("初始化分支中").start(),b=`feat_init_${ce()}`,j=me(a.group?.name)?[E.DEV,E.TEST,E.RELEASE,b]:[b],S=await Promise.allSettled(j.map((e=>function(e){return ze({url:`${Ie()}/projects/${e.id}/repository/branches`,method:"post",data:e})}({id:v.id,branch:e,ref:E.MASTER})))),k=[];S.forEach((({status:e},t)=>{"fulfilled"===e&&k.push(j[t])})),await re("git pull"),k.includes(b)?(await re(`git checkout -b ${b} origin/${b}`),$.succeed(`项目已切换到初始分支: ${r.blue(b)}`)):$.warn("开发分支检出失败!项目当前在主分支,请自行检出开发分支。");const T=`cd ${a.projectName} && z start`;console.log(`输入 ${r.green(T)} 开始开发吧~`),process.exit(0)}catch(e){ne(e)}var e,t}var ot,ct;function ut(e){return Be({url:`${we("K8sDomain")}/kapis/clusters/youshou-local/devops.kubesphere.io/v1alpha3/namespaces/${O}/pipelines/${e.projectName}/pipelineruns?branch=${e.branchName}`,method:"post",data:e.params})}async function lt(e,t){ue(),le(),await pe();let n=e,i=t.platform;if(n&&!Object.values(E).includes(n)&&ne("仅支持发布指定环境分支"),i&&!Object.values(k).includes(i)&&ne("发布平台错误"),i||(i=await m({message:"请选择平台",choices:A})),i===k.NPM&&(n=E.MASTER),!n){const e=await m({message:"请选择部署环境",choices:T});n=(a=e)===S.PROD?E.MASTER:a}var a;let s=[];t.skipSelectionNotification||(s=await He("请选择部署成功要通知的人员:",(()=>!0),!0));var o;!function(e,t){const n=$e(),i=be();if(i?.repository?.url||ne(".z/project.json中缺少repository.url"),t===k.H5){const t=`build:${e}`;n?.scripts[t]||ne(`项目package.json文件scripts不存在命令${t}。`)}t===k.NPM&&(n?.scripts.build||ne("项目package.json文件scripts不存在命令build。"))}((o=n)===E.MASTER?S.PROD:o,i);const c=$e();await async function(e){const t=h("部署任务创建中").start(),{targetBranch:n,notify:i,projectName:a}=e,s=i?[...new Set([fe("weWorkUserId"),...i])]:[fe("weWorkUserId")];try{const{metadata:e,spec:i}=await ut({projectName:a,branchName:n,params:{parameters:[{name:"QW_NOTIFY_USER",value:s.join(",")}]}}),o=`${we("K8SWebDomain")}/youshou-local/clusters/youshou-local/devops/${e.namespace}/pipelines/${i.pipelineRef.name}/branch/${i.scm.refName}/run/${e.name}/task-status`;t.succeed("部署任务创建完成"),console.log(`如有需要,可在k8s中查看 ${r.blue(o)}`),process.exit(0)}catch(e){t.fail("部署任务创建失败"),ne(e)}}({projectName:c.name,targetBranch:n,notify:s})}async function pt(e,t,n){const i=h(`分支合并中,${e} -> ${t}`).start();let s=0;try{const{iid:i}=await(r={title:`${e} -> ${t} by z-develop`,id:n.id,source_branch:e,target_branch:t,remove_source_branch:E.MASTER===t},ze({url:`${Ie()}/projects/${r.id}/merge_requests`,method:"post",data:r}));s=i}catch(e){if(a.isAxiosError(e)){const t=e?.response?.status;409===t&&ne(`存在重复的合并请求,前往查看${n.mergeRequestUrl}`)}ne(e)}var r;const o=async()=>{try{await new Promise((e=>{setTimeout(e,5e3)})),await function(e){return ze({url:`${Ie()}/projects/${e.id}/merge_requests/${e.iid}/merge`,method:"put"})}({id:n.id,iid:s}),i.succeed(`分支${e}已合并到分支${t}`)}catch(e){a.isAxiosError(e)||ne(e);const t=e?.response?.status;if(406===t)return await o();if(await function(e){return ze({url:`${Ie()}/projects/${e.id}/merge_requests/${e.iid}`,method:"put",data:e})}({id:n.id,iid:s,state_event:"close"}),405===t){const e=await function(e){return ze({url:`${Ie()}/projects/${e.id}/merge_requests/${e.iid}`,method:"get"})}({id:n.id,iid:s});if("cannot_be_merged"===e.merge_status&&e.diff_refs.base_sha===e.diff_refs.head_sha)return void i.warn("MR已关闭。判定为空的合并请求(没有新内容),可继续进行部署")}i.fail("合并过程中出现冲突,MR已关闭。建议在本地完成合并。"),process.exit(1)}};await o()}function mt(){const e=q();if(n.existsSync(e)){const t=w.readJsonSync(e);if(t["lint-staged"])return t["lint-staged"];throw new Error("未找到lint配置")}throw new Error("请先初始化项目(z i .)。")}function dt(){const e=function(e){if(e.includes("Merge")&&e.includes("# Conflicts:"))return!0;if($.valid(e))return!0;const t=e.split(": ");if(1===t.length)return"body前缺少「: 」";const n=t[0];return/^(feat|fix|refactor)/.test(n)?!!/\(\d+(?:,\d+)*\)/.test(n)||"ID缺少或者格式不正确。":/^(chore|ci)/.test(n)?!![z.CHORE,z.CI].includes(n)||"chore/ci类型无需填写ID。":z.Break===n||"不存在的提交类型。"}(n.readFileSync(i.resolve(".git","COMMIT_EDITMSG"),"utf-8"));!0===e?(te("commit msg validate success."),process.exit(0)):ne(`commit msg格式错误。${e}`)}async function gt(e="latest"){await re(`npm i -g ${de.name}@${e} --registry https://registry.npmmirror.com/`),Ne("latestCheckVersionTimestamp",Date.now()),Ne("version",e),ke(),console.log(r.green(`升级完成,当前版本${e}`)),process.exit(0)}async function ft(){const e=j(process.argv.slice(2));if(!(e.h||e.help||e.v||e.version)&&(!["init","i"].includes(e._[0])||[".","prepare"].includes(e._[1])))if(Q()){const e=w.readJSONSync(K());Ce(e.profile),Ne(e.main),Re(e.constants),await async function(){const e=he("latestCheckVersionTimestamp"),t=he("versionCheckDuring");if(Date.now()-Number(e)>24*Number(t)*3600*1e3){let e;Re(await Le());try{const t="TIME_OUT",n=new Promise((e=>{setTimeout((()=>e(t)),3e3)}));e=await Promise.race([n,re(`npm view ${de.name} version --registry https://registry.npmmirror.com/`)]),e!==t&&e!==de.version&&(console.log(`${r.blue(de.name)}本地版本为${de.version},低于线上版本${e},开始升级`),await gt(e)),Ne("latestCheckVersionTimestamp",Date.now()),ke()}catch(e){console.log("升级出错!请重试,或者手动升级"),ne(e)}}}()}else ne("请先初始化z-develop(执行 z i)。更多见https://hxhtbr8t8uy.feishu.cn/docx/RnOhdtqJWo5UooxHTaUcQFwtnKg")}!function(e){e.Project="project",e.ProjectAbbr="pr",e.Branch="branch",e.BranchAbbr="b",e.Page="page",e.PageAbbr="pa",e.Component="component",e.ComponentAbbr="co",e.CommitMsg="commit-msg",e.CommitMsgAbbr="cm"}(ot||(ot={})),e.command("create").alias("c").argument("[type]","可选值为project|pr, branch|b, commit-msg|cm, page|p, component|co").option("--branch-type <type>",`分支类型。可选值:${Object.values(x).join(", ")}`).option("--branch-purpose <purpose>","创建分支的目的").description("创建项目/分支/提交信息/页面/组件").action((async function(e,t){let a;e?[ot.Project,ot.ProjectAbbr].includes(e)?a=ot.Project:[ot.Branch,ot.BranchAbbr].includes(e)?a=ot.Branch:[ot.Page,ot.PageAbbr].includes(e)?a=ot.Page:[ot.Component,ot.ComponentAbbr].includes(e)?a=ot.Component:[ot.CommitMsg,ot.CommitMsgAbbr].includes(e)?a=ot.CommitMsg:ne("参数输入错误"):a=await m({message:"请选择你要创建的类型",choices:[{name:"提交信息(commit message)",value:ot.CommitMsg},{name:"分支(branch)",value:ot.Branch},{name:"页面(page)",value:ot.Page},{name:"组件(component)",value:ot.Component},{name:"项目(project)",value:ot.Project}]}),a===ot.Project?await rt():(ue(),le(),a===ot.Branch?(await pe(),await async function(e){let t,n;ue(),le(),await pe(),t=e.branchType?e.branchType:await m({message:"请选择创建分支的类型",choices:[{name:"开发新功能(feat)",value:x.FEAT},{name:"修复BUG(fix)",value:x.FIX},{name:"重构/优化代码(refactor)",value:x.REFACTOR}]}),n=e.branchPurpose?e.branchPurpose:await d({message:"请输入创建分支的目的(大小写字母、数字,小驼峰式命名。如userInfo)",validate:tt});const i=`${t}_${n}_${ce()}`;await re(`git fetch origin ${E.MASTER}`),await re(`git checkout -b ${i} origin/${E.MASTER}`),await re(`git push -u origin ${i}`),process.exit(0)}(t)):a===ot.CommitMsg?await st():a===ot.Page?await async function(){const e="pages",t=await Te(e);n.mkdirSync(i.resolve("src",e),{recursive:!0});const a=await d({message:"请输入目录及页面名称(如user/list,不带文件后缀)",validate:nt});let s;if(a.includes("/")){const t=a.split("/");t.pop(),s=i.resolve("src",e,...a.split("/")),n.mkdirSync(i.resolve("src",e,...t),{recursive:!0})}else s=i.resolve("src",e,a);const{pages:r}=await Je(),o=n.readdirSync(t),u=await m({message:"请选择模版",choices:r.filter((e=>o.includes(e.name))).map((e=>({name:`${e.name}: ${e.desc}(${e.author})`,value:e.name})))}),l=h("页面生成中...").start(),p=s+i.extname(i.join(t,u));c.cp("-r",i.join(t,u),p),ie(p)?se(p).forEach((e=>{xe(i.join(p,e),a)})):xe(p,a),l.succeed("页面生成成功"),process.exit(0)}():a===ot.Component&&await async function(){const e="components",t=await Te("components");n.mkdirSync(i.resolve("src",e),{recursive:!0});const a=await d({message:"请输入目录及组件名称(如user/list,不带文件后缀)",validate:nt});let s;if(a.includes("/")){const t=a.split("/"),r=t.pop();s=i.resolve("src",e,...t,Ae(r)),n.mkdirSync(i.resolve("src",e,...t),{recursive:!0})}else s=i.resolve("src",e,Ae(a));const{components:r}=await Je(),o=n.readdirSync(t),u=await m({message:"请选择模版",choices:r.filter((e=>o.includes(e.name))).map((e=>({name:`${e.name}: ${e.desc}(${e.author})`,value:e.name})))}),l=h("组件生成中...").start(),p=s+i.extname(i.join(t,u));c.cp("-r",i.join(t,u),p),ie(p)?se(p).forEach((e=>{xe(i.join(p,e),a)})):xe(p,a),l.succeed("组件生成成功"),process.exit(0)}())})),e.command("merge").alias("m").argument("[branch]","目标分支名称").option("--deploy-platform <platform>",`合并成功后要部署的平台。可选值:${Object.values(k).join("/")}`).option("--deploy-skip-selection-notification","部署时,是否跳过选择部署通知人环节").description("合并当前分支到指定远程分支,并部署。").action((async function(e,t){ue(),le(),await pe();const n=await Ee();Object.values(E).includes(n.sourceBranch)&&ne(`当前分支${n.sourceBranch}不可作为源分支合并到目标分支。`);const i=await(a=n.id,ze({url:`${Ie()}/projects/${a}/repository/branches`}));var a;const s=me(n.group),o=i.filter((e=>![n.sourceBranch].includes(e.name))).map((e=>{let t=e.name;return s&&Object.values(E).includes(t)&&(t=r.bold.blue(t)),{name:t,value:e.name}}));let c;e&&!o.filter((t=>t.value===e)).length&&ne(`未找到目标分支${e}`),c=e||await m({message:"请选择要合并到的目标分支:",choices:o});const u=h(`${n.sourceBranch}分支代码检测中`).start();if(await re(`git ls-remote --heads origin ${n.sourceBranch}`)){u.text=`存在远程分支origin/${n.sourceBranch}`,await re("git fetch");const e=await re(`git rev-parse ${n.sourceBranch}`),t=await re(`git rev-parse origin/${n.sourceBranch}`);if(await re(`git merge-base ${t} HEAD`)===t)await re(`git push -u origin ${n.sourceBranch}`),u.succeed(`${n.sourceBranch}分支代码已推送到远程`);else{await re(`git merge-base ${e} ${t}`)===e?(await re("git pull"),u.succeed(`${n.sourceBranch}分支代码已更新`)):(u.fail(`远程分支origin/${n.sourceBranch}和本地分支${n.sourceBranch}都有新的提交,请手动合并后再试。`),process.exit(1))}}else await re(`git push -u origin ${n.sourceBranch}`),u.succeed(`${n.sourceBranch}已推送到远程`);await async function(e,t,n){const i=`origin/${e.sourceBranch}`,a=await re(`git log -b origin/${E.MASTER} -1 --format=%H`),s=await re(`git log -b origin/${e.sourceBranch} -1 --format=%H`),o=await re(`git log ${a}...${s} -b ${i}`);if(o||ne(`分支${e.sourceBranch}上不存在新的commit,不需要合并。`),await re(`git branch --contains ${a} -r ${i}`)||(console.log(r.yellow("注意:当前分支上不存在远程主分支最新代码,将在自动合入后继续。")),await pt(E.MASTER,e.sourceBranch,e)),t===E.MASTER&&n){const e=o.split("\n").filter((e=>e)),t=await re(`git log -b origin/${S.TEST} -1 --format=%H`);(function(e,t){for(const n of t)if(!e.includes(n))return!1;return!0})((await re(`git log ${a}...${t} -b origin/${S.TEST}`)).split("\n").filter((e=>e)),e)||ne("请先在测试环境发布要部署的代码")}}(n,c,s),await pt(n.sourceBranch,c,n),E.MASTER===c&&(await re(`git checkout ${E.MASTER}`),await re("git pull"),await re(`git branch -d ${n.sourceBranch}`),te(`${n.sourceBranch}分支已移除,当前已切换到最新的${E.MASTER}。如需继续开发,请检出新分支(z c b)。`)),s&&Object.values(E).includes(c)&&await lt(c,{platform:t.deployPlatform,skipSelectionNotification:t.deploySkipSelectionNotification})})),e.command("deploy").alias("d").description("部署到指定环境").argument("[branchName]",`部署环境。可选值:${Object.values(E).join("/")}`).option("--platform <platform>",`部署平台。可选值:${Object.values(k).join("/")}`).option("--skip-selection-notification","是否跳过选择部署通知人环节").action(lt),e.command("start").alias("s").description("启动本地开发环境").argument("[env]","业务环境。可选值 dev|d, test|t, release|r, prod|p").action((async function(e){let t=e;t?[S.DEV,S.TEST,S.RELEASE,S.PROD,"d","t","r","p"].includes(e)?"d"===t?t=S.DEV:"t"===t?t=S.TEST:"r"===t?t=S.RELEASE:"p"===t&&(t=S.PROD):ne("参数输入有误"):t=await m({message:"请选择环境",choices:T});const n=`dev:${t}`;$e().scripts[n]?oe(`npm run ${n}`):ne(`项目中(package.josn > scripts)不存在命令${n},请先添加!`)})),function(e){e.CommitMsg="commit-msg",e.CommitMsgAbbr="cm",e.CommitFiles="commit-files",e.CommitFilesAbbr="cf",e.Prettier="prettier",e.PrettierAbbr="p",e.Eslint="eslint",e.EslintAbbr="e",e.TypeCheck="type-check",e.TypeCheckAbbr="tc",e.DependencyCheck="dependency-check",e.DependencyCheckAbbr="dc"}(ct||(ct={})),e.command("run").aliases(["r","l","lint"]).argument("[type]","非必填。可选值为commit-msg|cm, commit-files|cf, prettier|p, eslint|e, type-check|tc, dependency-check|dc。").option("--quiet","eslint只打印error").option("--max-warnings [VALUE]","eslint结果warn超过多少个会异常退出,默认为100",parseInt).description("执行 eslint / prettier / type-check / dependency-check 脚本。").action((async function(e,t){let a;ue(),le(),e?[ct.CommitMsg,ct.CommitMsgAbbr].includes(e)?a=ct.CommitMsg:[ct.CommitFiles,ct.CommitFilesAbbr].includes(e)?a=ct.CommitFiles:[ct.Prettier,ct.PrettierAbbr].includes(e)?a=ct.Prettier:[ct.Eslint,ct.EslintAbbr].includes(e)?a=ct.Eslint:[ct.TypeCheck,ct.TypeCheckAbbr].includes(e)?a=ct.TypeCheck:[ct.DependencyCheck,ct.DependencyCheckAbbr].includes(e)?a=ct.DependencyCheck:ne("参数输入错误"):a=await m({message:"请选择你要执行的操作",choices:[{name:"执行 prettier",value:ct.Prettier},{name:"执行 eslint",value:ct.Eslint},{name:"执行 type-check",value:ct.TypeCheck},{name:"执行 dependency-check",value:ct.DependencyCheck}]}),a===ct.CommitMsg?dt():a===ct.CommitFiles?await async function(){await v({concurrent:!1,debug:!1,config:mt()})?(te("代码风格检测通过!"),process.exit(0)):ne("代码风格检测未通过!")}():a===ct.Prettier?await async function(){n.existsSync(i.resolve("node_modules",".bin","prettier"))||ne("该项目未安装prettier,请安装后重试");try{await re("npx prettier --write . --config .z/.prettierrc.json --ignore-path .z/.prettierignore --ignore-unknown --no-error-on-unmatched-pattern",{silent:!1}),te("prettier执行成功"),process.exit(0)}catch(e){ne("prettier校验出错")}}():a===ct.Eslint?await async function(e){n.existsSync(i.resolve("node_modules",".bin","eslint"))||ne("该项目未安装eslint,请安装后重试");try{let t="npx eslint '**/*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}' --fix";"win32"===process.platform&&(t='npx eslint "**/*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}" --fix'),e.quiet&&(t+=" --quiet"),e.maxWarnings&&!isNaN(Number(e.maxWarnings))?t+=` --max-warnings ${Number(e.maxWarnings)}`:t+=" --max-warnings 100",await re(t,{silent:!1}),te("eslint执行成功"),process.exit(0)}catch(e){ne("eslint校验出错")}}(t):a===ct.TypeCheck?(n.existsSync(i.resolve("./node_modules/.bin/vue-tsc"))||ne("请先安装vue-tsc。推荐命令: npm i -D vue-tsc"),oe("vue-tsc --build"),process.exit(0)):a===ct.DependencyCheck&&await async function(){await pe();const e=await b({format:["group","repo"],interactive:!0,upgrade:!0,install:"always"});if(e&&Object.keys(e).length){console.log(r.green("升级完成 🎉"));const t=Object.entries(e).map((([e,t])=>`${e}@${t}`)).join("; ");await re(`git add . && git commit -m "chore: 依赖升级。${t}"`)}process.exit(0)}()})),e.command("update").alias("u").argument("[version]","版本号","latest").description("升级").action(gt),e.name("z-develop").alias("z").description(`z-develop, 开发流程管理工具。\n了解更多: ${r.blue("https://hxhtbr8t8uy.feishu.cn/docx/RnOhdtqJWo5UooxHTaUcQFwtnKg")}`).usage("<command> [options]").hook("preAction",(async function(){process.on("unhandledRejection",(e=>{})),process.on("uncaughtException",(e=>{})),c.config.fatal=!0,c.config.silent=!0,c.config.verbose=Boolean(void 0)||!1,await ft()})).version(de.version,"-v, --version","当前版本号").helpOption("-h, --help","帮助").showHelpAfterError("可以使用z -h查看帮助。"),e.parse(); | ||
import{program as e}from"commander";import t from"node:child_process";import n from"node:fs";import i from"node:path";import a,{AxiosError as s}from"axios";import r from"chalk";import o from"dayjs";import c from"shelljs";import u from"node:os";import l from"child_process";import{confirm as p,select as m,input as d,password as g,checkbox as f}from"@inquirer/prompts";import h from"ora";import w from"fs-extra";import{select as y}from"inquirer-select-pro";import v from"lint-staged";import $ from"semver";import{run as b}from"npm-check-updates";import j from"minimist";var S,E,k;!function(e){e.DEV="dev",e.TEST="test",e.RELEASE="release",e.PROD="production"}(S||(S={})),function(e){e.DEV="dev",e.TEST="test",e.RELEASE="release",e.MASTER="master"}(E||(E={})),function(e){e.H5="h5",e.NPM="npm"}(k||(k={}));const T=[{name:`开发环境 - ${S.DEV}`,value:S.DEV},{name:`测试环境 - ${S.TEST}`,value:S.TEST},{name:`预发环境 - ${S.RELEASE}`,value:S.RELEASE},{name:`正式环境 - ${S.PROD}`,value:S.PROD}],A=[{name:`网页 - ${k.H5}`,value:k.H5},{name:`依赖包 - ${k.NPM}`,value:k.NPM}];var x,C;!function(e){e.FEAT="feat",e.FIX="fix",e.REFACTOR="refactor"}(x||(x={})),function(e){e.JAVA="Java",e.JAVASCRIPT="JavaScript"}(C||(C={}));const R={1:"研发",2:"测试",3:"产品",4:"设计",5:"运营",6:"销售",7:"行政",8:"财务",9:"其他"},N="http://git.cxlqd.com",P={PROJECT_NAME:"fe-pages-tpl",GIT_URL:`${N}/fe-component/fe-pages-tpl.git`},D=["fe-biz","fe-base","fe-tpl","fe-component","fe-demo"];var z;!function(e){e.FEAT="feat",e.FIX="fix",e.REFACTOR="refactor",e.CHORE="chore",e.CI="ci",e.Break="BREAKING CHANGE"}(z||(z={}));const O="fe-biz7tvsd",M=".z",F="develop-config.json",B=".z",I=".commit-msg-tpl",_="project.json";function J(e=""){return i.join(B,e)}function L(){return J(_)}function W(){return J(I)}function U(){l.spawnSync("git",["config","core.hooksPath",J()]),l.spawnSync("git",["config","commit.template",W()])}function q(e=""){return i.resolve(u.homedir(),M,e)}function V(){return q(F)}function H(){return n.existsSync(q())&&n.existsSync(V())}const{red:G,green:K,blue:Q,magenta:X}=r;function Z(...e){console.log(K(...e))}function Y(e,t=!1){let n=e;e instanceof Error?(n=e.message,a.isAxiosError(e)&&(n=`请求失败:${e.message}`),console.log(G(n)),console.log(X(e.stack))):console.log(G(e)),t||process.exit(1)}function ee(e){return!!n.existsSync(e)&&n.lstatSync(e).isDirectory()}function te(e=process.cwd()){if(ee(e)){return n.readdirSync(e).filter((t=>ee(i.resolve(e,t))))}return[]}function ne(e=process.cwd()){if(ee(e)){return n.readdirSync(e).filter((t=>!ee(i.resolve(e,t))))}return[]}async function ie(e,t={removeTailLinkBreak:!0,silent:!0}){let n=await new Promise(((n,i)=>{try{n(c.exec(e,{silent:t.silent}))}catch(e){i(e)}}));return n=n.toString(),t.removeTailLinkBreak&&(n=n.replace(/\n$/,"")),n}function ae(e){t.execSync(e,{stdio:"inherit"})}function se(){return o(Date.now()).format("YYMMDD")}function re(){n.existsSync(J())||Y("当前不在项目根目录。请切换到项目根目录")}function oe(){n.existsSync(i.resolve(".git"))||Y("当前不是git项目根目录,请先执行git init,或切换到根目录")}async function ce(){""!==await ie("git status -s")&&Y("请先提交代码变动,再进行操作")}function ue(e){return["fe-biz"].includes(e)}async function le(e,...t){try{await e(...t)}catch(e){if(!(e instanceof Error&&"ExitPromptError"===e.name))throw e;console.log(),console.log(r.cyan(" 👋 下次见~")),console.log()}}const pe='{\n "printWidth": 120,\n "tabWidth": 2,\n "useTabs": false,\n "semi": true,\n "singleQuote": false,\n "quoteProps": "as-needed",\n "jsxSingleQuote": false,\n "trailingComma": "all",\n "bracketSpacing": true,\n "bracketSameLine": false,\n "arrowParens": "always",\n "requirePragma": false,\n "insertPragma": false,\n "proseWrap": "preserve",\n "htmlWhitespaceSensitivity": "css",\n "vueIndentScriptAndStyle": false,\n "endOfLine": "lf",\n "embeddedLanguageFormatting": "auto",\n "singleAttributePerLine": false\n}\n',me="# 系统 信息文件\n.DS_Store/\nThumbs.db\n\n# 编辑器配置文件\n.idea/\n.vscode/\n\n# 输出目录\ndist/\n\n# Log files\n*.log\n\n# 本地配置文件\n*.local\n\n# 缓存文件\n*.cache\n\n# 垃圾文件\n.Trashes\n",de={[C.JAVA]:{"**/*.{java}":"./run.sh pmd -d ../../../src/main/java/ -f text -R rulesets/java/quickstart.xml"},[C.JAVASCRIPT]:{"**/*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}":"eslint --fix","*":"prettier -wu"}};var ge={name:"cli-z-develop",version:"0.4.3",description:"前端本地开发命令行工具",main:"dist/index.js",bin:{z:"bin/z.js","z-develop":"bin/z.js"},scripts:{prepare:"[ -n '$z' ] && z init prepare || echo 'Warning: z not exist at global'",dev:"rollup -c -w --environment DEBUG:true",build:"rollup -c",eslint:"eslint '**/*.{ts,js}' --fix",prettier:"prettier -wu .",upload:"npm run build && npm publish --access public --registry https://registry.npmjs.org/","upload:patch":"npm version patch && npm run upload","upload:minor":"npm version minor && npm run upload","upload:major":"npm version major && npm run upload"},type:"module",author:"z",devDependencies:{"@lonely9/eslint-config-team":"^1.2.3","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^16.0.1","@rollup/plugin-replace":"v6.0.2","@rollup/plugin-terser":"^0.4.4","@tsconfig/node22":"^22.0.2","@types/fs-extra":"^11.0.4","@types/inquirer":"^9.0.8","@types/minimist":"^1.2.5","@types/node":"^22.15.29","@types/semver":"^7.7.0","@types/shelljs":"^0.8.16","@typescript-eslint/eslint-plugin":"^8.32.1","@typescript-eslint/parser":"^8.32.1",eslint:"^9.27.0",jiti:"^2.4.2",prettier:"^3.5.3",rollup:"^4.41.1","rollup-plugin-typescript2":"^0.36.0",typescript:"^5.8.3","vue-tsc":"^2.2.10"},dependencies:{"@inquirer/prompts":"^7.5.3",axios:"^1.9.0",chalk:"^5.4.1",commander:"^14.0.0",dayjs:"^1.11.13",figures:"^6.1.0","fs-extra":"^11.3.0","inquirer-select-pro":"^1.0.0-alpha.9","lint-staged":"^16.1.0",minimist:"^1.2.8","npm-check-updates":"^18.0.1",ora:"^8.2.0",rxjs:"^7.8.2",semver:"^7.7.2",shelljs:"^0.10.0"}};const fe={profile:{ldapAccount:"",ldapPassword:"",gitToken:"",gitUserId:0,gitName:"",gitEnglishName:"",gitEmail:"",weWorkName:"",weWorkUserId:"",jobType:"fe",zenTaoToken:"",k8sToken:""},main:{version:ge.version,latestCheckVersionTimestamp:0,versionCheckDuring:3,weWorkListCache:[]},constants:{ZenTaoDomain:"",K8sDomain:"",FEServerDomain:"",K8SWebDomain:""}};function he(e){return e?fe.profile[e]:fe.profile}function we(e){return e?fe.main[e]:fe.main}function ye(e){return e?fe.constants[e]:fe.constants}let ve=null,$e=null;function be(){if(ve)return ve;const e=i.join("package.json");return n.existsSync(e)||Y(`当前目录(${c.pwd()})不存在${e}文件,请在项目根目录执行该命令。`),ve=w.readJsonSync(e),ve}function je(){if($e)return $e;const e=L();return n.existsSync(e)||Y(`当前目录(${c.pwd()})不存在${e}文件,请在项目根目录执行该命令,或者初始化项目(z init .)。`),$e=w.readJsonSync(e),$e}function Se(e){$e=$e?{...$e,...e}:e,w.writeJSONSync(L(),$e,{spaces:2})}const Ee={id:0,name:"",group:"",sourceBranch:"",mergeRequestUrl:""};async function ke(){if(!Ee.name){const e=be();Ee.name=e.name}if(!Ee.group){const e=je();e.repository.group&&(Ee.group=e.repository.group)}if(!Ee.id)try{const e=Ee.group?`${Ee.group}/${Ee.name}`:Ee.name,[t]=await Ue(e);Ee.mergeRequestUrl=`${t.web_url}/merge_requests`,Ee.id=t.id,Ee.group=t.namespace.path;const n=je();n.repository.group||Se({repository:{...n.repository,group:t.namespace.path}})}catch(e){Y(e)}return Ee.sourceBranch||(Ee.sourceBranch=await ie("git branch --show-current")),Ee}function Te(){w.writeJSONSync(V(),{main:we(),profile:he(),constants:ye()},{spaces:2})}async function Ae(e){const t=q(),a=process.cwd(),s=i.join(t,P.PROJECT_NAME);n.existsSync(s)?(c.cd(s),await ie("git pull"),c.cd(a)):(c.cd(t),await ie(`git clone ${P.GIT_URL} --depth=1`),c.cd(a));const r=i.join(s,"src",e);return n.existsSync(r)||Y("模板库错误!"),r}function xe(e){return e.split("-").map((e=>e.charAt(0).toUpperCase()+e.slice(1))).join("")}function Ce(e,t){const i=n.readFileSync(e,"utf-8"),a=t.replace(/\//g,"-"),s=i.replace(/name: "-_-NAME-_-"/g,`name: "${xe(a)}"`).replace(/class="-_-NAME-_-"/g,`class="${a}"`).replace(/.-_-NAME-_-/g,`.${a}`);n.writeFileSync(e,s,"utf-8")}function Re(e,t){void 0!==t?fe.profile[e]=t:fe.profile={...fe.profile,...e}}function Ne(e,t){fe.constants={...fe.constants,...e}}function Pe(e,t){void 0!==t?fe.main[e]=t:fe.main={...fe.main,...e}}async function De(e){const t=e.method||"get",n=e.headers||{},i=e.data||{},o=e.dataKey||["GET","get"].includes(t)?"params":"data";try{const s={url:e.url,method:t,[o]:i,headers:n};r.magenta(s.method.toUpperCase()),r.yellow(s.url),JSON.stringify(s.headers),r.gray(JSON.stringify(s[o],null,2));const c=await a(s);return r.green("Response"),r.grey(JSON.stringify(c.data,null,2)),Promise.resolve(c.data)}catch(e){return e instanceof s&&(r.red("Error"),r.grey(JSON.stringify(e?.response?.data))),Promise.reject(e)}}async function ze(){const e=he("gitToken");if(e)return e;{const{access_token:e}=await De({url:`${N}/oauth/token`,method:"post",data:{grant_type:"password",username:he("ldapAccount"),password:he("ldapPassword")}}),t=`Bearer ${e}`;return Re("gitToken",t),Te(),t}}async function Oe(e){return De({...e,headers:{Authorization:await ze()}})}async function Me(){const e=he("zenTaoToken");if(e)return e;{const{token:e}=await De({url:`${ye("ZenTaoDomain")}/api.php/v1/tokens`,method:"post",data:{account:he("ldapAccount"),password:he("ldapPassword")}});return Re("zenTaoToken",e),Te(),e}}async function Fe(e){const t=await De({...e,headers:{Token:await Me()}});if("string"==typeof t){const e=JSON.parse(t.slice(0,t.indexOf("<script>")));return JSON.parse(e.data)}if("object"==typeof t)return"Unauthorized"===t.error||t.data.indexOf("<script>")<0?(Re("zenTaoToken",""),Fe({...e})):t}async function Be(){const e=he("k8sToken");if(e)return e;{const{access_token:e}=await De({url:`${ye("K8sDomain")}/oauth/login/LDAP`,method:"post",headers:{"Content-Type":"application/x-www-form-urlencoded"},data:{username:he("ldapAccount"),password:he("ldapPassword")}}),t=`Bearer ${e}`;return Re("k8sToken",t),Te(),t}}async function Ie(e){const t=await De({...e,headers:{Authorization:await Be()}});return 401===t.code?(Re("k8sToken",""),Ie({...e})):t}const _e=()=>`${N}/api/v4`,Je=e=>`${_e()}/projects/100/repository/files/${encodeURIComponent(e)}/raw?ref=master`;function Le(){return Oe({url:Je("src/data/template-projects.json")})}function We(){return Oe({url:Je("src/data/z-develop-config.json")})}function Ue(e){return Oe({url:`${_e()}/projects`,data:{search:e,search_namespaces:!0}})}async function qe(){const e=await Oe({url:`${_e()}/groups`}),t=D.map((t=>{const n=e.find((e=>e.name===t));return!!n&&{name:n.name,id:n.id,description:n.description}})).filter((e=>Boolean(e)));w.writeJSONSync(q("fe-groups.json"),{groups:t},{spaces:2})}function Ve(){return async function(e){const t=`${ye("FEServerDomain")}/api`,{data:n}=await De({url:`${t}/auth/z-develop/login`,method:"post"}),i=await De({url:t+e.url,headers:{Authorization:`Bearer ${n}`},data:e.data,method:e.method||"post"});return 0!==i.code&&Y(`${i.code}: ${i.message}`),i.data}({url:"/user/list2"})}async function He(){const e=(await Ve()).filter((e=>[1,2,3,4,5].includes(e.title))).map((e=>({name:`${e.nick} - ${R[e.title]}`,value:e.weWorkUserId}))),t=we("weWorkListCache"),n=t.map((e=>e.value)),i=[];return e.forEach((e=>{const a=n.indexOf(e.value);i.push({...e,usageCount:a>-1?t[a].usageCount:0})})),i.sort(((e,t)=>t.usageCount-e.usageCount))}async function Ge(e,t,n){const i=await He();let a=await y({message:e,loop:!0,pageSize:i.length||5,clearInputWhenSelected:!0,multiple:n,options:e=>e?i.filter((t=>t.name.includes(e))):i,validate:t});return a=Array.isArray(a)?a:[a],function(e,t){const n=[];t.forEach((t=>{e.includes(t.value)&&n.push(t)}));const i=we("weWorkListCache"),a=i.map((e=>e.value));n.forEach((e=>{const t=a.indexOf(e.value);t>-1?i[t].usageCount+=1:i.push({...e,usageCount:1})})),Pe({weWorkListCache:i.sort(((e,t)=>t.usageCount-e.usageCount))}),Te()}(a,i),a}async function Ke(){try{if(H()){await p({message:"系统中已存在z的配置文件,确认重新配置?"})?c.rm("-rf",V()):process.exit(0)}n.mkdirSync(q(),{recursive:!0});const e=await m({message:"请选择岗位类型",choices:[{name:"前端",value:"fe"},{name:"后端",value:"be"}]}),t=await d({message:"请输入LDAP账号:"}),i=await g({message:"请输入LDAP密码:",mask:!0});Re("jobType",e),Re("ldapAccount",t),Re("ldapPassword",i);Ne(await We());const a=await He(),s=await Ge("请选择你自己(用于企微通知):",(e=>e.length>1?"只能选一个":!(e.length<1)||"请选一个"),!1),{name:r,value:o}=a.find((e=>e.value===s[0]));Re({weWorkName:r,weWorkUserId:o})}catch(e){Y(e)}const e=h("配置信息初始化中").start();try{const t=await Oe({url:`${_e()}/user`});Re({gitUserId:t.id,gitName:t.name,gitEnglishName:t.username,gitEmail:t.email}),Pe("latestCheckVersionTimestamp",Date.now()),Te(),await qe(),e.succeed("配置信息初始化完成"),process.exit(0)}catch(t){e.fail("配置信息初始化失败"),a.isAxiosError(t)&&Y("请检查你的域名及令牌配置"),Y(t)}}const Qe='{\n "$schema": "https://json.schemastore.org/tsconfig",\n "_version": "0.0.1",\n "compilerOptions": {\n "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.browser.tsbuildinfo",\n "lib": ["ESNext", "DOM", "DOM.Iterable", "WebWorker"],\n // 编译时无需导出类型文件\n "noEmit": true,\n\n // 编译时用模块最新规范,至于打包代码时的兼容问题,交给vite/webpack们解决\n "module": "ESNext",\n // 模块解析策略。同上\n "moduleResolution": "Bundler",\n // 可以使用import...from导入json文件\n "resolveJsonModule": true,\n // 带上文件后缀,避免歧义。至于兼容性,交给vite/webpack们解决\n "allowImportingTsExtensions": true,\n // 识别一个文件是模块还是脚本,由于使用了打包工具,所以所有文件都是模块\n "moduleDetection": "force",\n\n // tsc编译时不转化jsx,留给打包工具处理\n "jsx": "preserve",\n // 指定处理jsx的库\n "jsxImportSource": "vue",\n\n // 必须显式声明this的类型,否则报错\n "noImplicitThis": true,\n // 严格模式。将默认开启以下规则:\n // noImplicitAny noImplicitThis alwaysStrict strictBindCallApply strictNullChecks strictFunctionTypes strictPropertyInitialization\n "strict": true,\n\n // 引入类型需要type关键字\n "verbatimModuleSyntax": true,\n\n // 编译目标用最新规范,至于打包代码时的兼容问题,交给vite/webpack们解决\n "target": "ESNext",\n // 合理编译class\n "useDefineForClassFields": true,\n\n // commonjs 和 es module之间可以互操作\n "esModuleInterop": true,\n // 引用路径中文件名大小写敏感\n "forceConsistentCasingInFileNames": true,\n // 会检查自建的和依赖库的所有.d.ts。调试自建d.ts文件时可以考虑打开\n "skipLibCheck": true\n }\n}',Xe='{\n "$schema": "https://json.schemastore.org/tsconfig",\n "_version": "0.0.1",\n "compilerOptions": {\n "lib": ["ESNext"],\n // 编译时无需导出类型文件\n "noEmit": true,\n\n // 编译时用模块最新规范,至于打包代码时的兼容问题,交给vite/webpack们解决\n "module": "ESNext",\n // 模块解析策略。同上\n "moduleResolution": "Bundler",\n // 可以使用import...from导入json文件\n "resolveJsonModule": true,\n // 识别一个文件是模块还是脚本,由于使用了打包工具,所以所有文件都是模块\n "moduleDetection": "force",\n\n // 必须显式声明this的类型,否则报错\n "noImplicitThis": true,\n // 严格模式。将默认开启以下规则:\n // noImplicitAny noImplicitThis alwaysStrict strictBindCallApply strictNullChecks strictFunctionTypes strictPropertyInitialization\n "strict": true,\n\n // 引入类型需要type关键字\n "verbatimModuleSyntax": true,\n\n // 编译目标用最新规范,至于打包代码时的兼容问题,交给vite/webpack们解决\n "target": "ESNext",\n // 合理编译class\n "useDefineForClassFields": true,\n\n // commonjs 和 es module之间可以互操作\n "esModuleInterop": true,\n // 引用路径中文件名大小写敏感\n "forceConsistentCasingInFileNames": true,\n // 会检查自建的和依赖库的所有.d.ts。调试自建d.ts文件时可以考虑打开\n "skipLibCheck": true,\n },\n}';let Ze;async function Ye(e,t){if(e)c.rm("-rf",B);else if(n.existsSync(J())){await p({message:`当前项目中已存在配置文件夹${B},确认重新配置?`})?c.rm("-rf",B):process.exit(0)}n.mkdirSync(J(),{recursive:!0}),await async function(e,t){const n=await ie("git remote get-url --push origin");n||Y("获取项目远程地址失败,请配置后重试");let i=e;i||(i=await m({message:"请选择项目语言",choices:[{name:C.JAVASCRIPT,value:C.JAVASCRIPT},{name:C.JAVA,value:C.JAVA}]}));let a=t;const s=be();if(!a){const e=await Ue(s.name);1===e.length?a=e[0].namespace.path:e.length>1&&(a=await m({message:"请选择当前项目所属分组",choices:e.map((e=>({name:e.namespace.path,value:e.namespace.path})))}))}Ze=h("项目初始化中").start(),Se({language:i,"lint-staged":de[i],repository:{url:n,group:a}})}(e,t),n.writeFileSync(W(),"",{mode:493}),n.writeFileSync(J("commit-msg"),"#!/usr/bin/env sh\nz run commit-msg",{mode:493}),n.writeFileSync(J("pre-commit"),"#!/usr/bin/env sh\nz run commit-files",{mode:493}),n.writeFileSync(J(".prettierrc.json"),pe,{mode:493}),n.writeFileSync(J(".prettierignore"),me,{mode:493}),n.writeFileSync(J("tsconfig.node.json"),Xe,{mode:493}),n.writeFileSync(J("tsconfig.browser.json"),Qe,{mode:493}),U(),Ze?.succeed("初始化完成。")}async function et(e,t){e?(oe(),"."===e?(t.projectLanguage&&!Object.values(C).includes(t.projectLanguage)&&Y("项目语言错误"),await Ye(t.projectLanguage,void 0),process.exit(0)):"prepare"===e?await async function(){n.existsSync(J())&&n.existsSync(W())?U():await Ye(),process.exit(0)}():Y("参数错误。执行 z init -h 查看帮助。")):await Ke()}async function tt(e){if(!e)return"不能为空";if(!/^[a-z0-9-]+$/.test(e))return"格式为小写字母、中横线(可选)、数字(不推荐)。如apple, apple-tree";if(te().includes(e))return"当前目录下已存在同名文件夹,请先处理。";return!(await Ue(e)).find((t=>t.name===e))||"远程仓库中已存在同名项目"}function nt(e){return!!e||"不能为空"}function it(e){return e?!!/^[a-zA-Z0-9.]+$/.test(e)||"格式为大小写字母、数字、小数点,小驼峰命名。如userInfo、systemRouter3":"不能为空"}function at(e){if(!e)return"目录名称不能为空";if(!/^[a-z][a-z0-9\-/]*$/.test(e))return"支持小写字母、数字,连字符(-)命名,小写字母开头,多层目录使用/隔开。如user、modules-3、setting/profile";if(e.includes("/")){const t=e.split("/");for(const e of t){if(!e)return"子级目录/页面名称不能为空";if(!/^[a-z][a-z0-9-]*$/.test(e))return"支持小写字母、数字,连字符(-)命名,小写字母开头。如user、modules-3"}}let t,a;t=e.includes("/")?i.resolve("src","pages",...e.split("/")):i.resolve("src","pages",e);const s=i.resolve(t,"..");return a=!!n.existsSync(s)&&n.readdirSync(s).map((e=>{const t=e.lastIndexOf(".");return t>-1?e.slice(0,t):e})).includes(e),!a||"本地目录已存在该文件"}e.command("init").alias("i").argument("[type]","非必填。不传为初始化工具配置;传 . 为初始化当前项目。").option("--project-language","项目语言。可选值:Java / Javascript").description("初始化工具配置、项目配置").action(((...e)=>le(et,...e)));const st=e=>`${ye("ZenTaoDomain")}${e}`;function rt(e,t){let i="";if([z.FEAT,z.FIX,z.REFACTOR].includes(e)){i=`${e}(${t.map((e=>e.value)).join(",")}): ${t.map((e=>e.name)).join(";")}`}e===z.CHORE&&(i=`${e}: ${t}`),n.writeFileSync(W(),i,"utf-8"),console.log(r.yellow(i)),Z("commit msg模板写入成功,可以进行提交了")}async function ot(){const e=await m({message:"请选择你要创建的模板类型",choices:[{name:"feat - 业务需求开发",value:z.FEAT},{name:"fix - bug修复",value:z.FIX},{name:"refactor - 技术内部需求",value:z.REFACTOR},{name:"chore - 其他",value:z.CHORE}]});if([z.FEAT,z.REFACTOR].includes(e)){const e=await async function(){const e=await Fe({url:st("/my-work-task.json?tid=mrrferp8"),method:"get"});return e?.tasks.filter((e=>"done"!==e.status)).map((({id:e,name:t})=>({value:{name:t,value:e},name:t})))}(),t=await f({message:"请关联开发任务(可多选):",validate:e=>0!==e.length||"请选择项",choices:e.map((e=>({...e,name:`[${e.value.value}]: ${e.name}`})))});rt(z.FEAT,t)}if(e===z.FIX){const e=await async function(){const e=await Fe({url:st("/my-work-bug.json?tid=mrrferp8"),method:"get"});return e?.bugs.map((({id:e,title:t})=>({name:t,value:{name:t,value:e}})))}(),t=await f({message:"请关联Bug(可多选):",validate:e=>0!==e.length||"请选择项",choices:e.map((e=>({...e,name:`[${e.value.value}]: ${e.name}`})))});rt(z.FIX,t)}if(e===z.CHORE){const e=await d({message:"请输入commit msg:",validate:e=>0!==e.length||"请输入commit msg"});rt(z.CHORE,e)}process.exit(0)}async function ct(){try{const a={},s=async()=>{const e=te(),{projects:t}=await Le(),n=t.map((t=>{const n={name:`${t.name} [${t.desc}]`,value:t.name,disabled:!1};return e.includes(t.name)&&(n.disabled="目录下已存在同名文件夹"),n})),i=await m({message:"请选择一个项目模板",choices:n}),s=t.find((e=>e.name===i));a.tplName=s.name,a.tplUrl=s.url,a.tplLanguage=s.language},o=async()=>{const{groups:e}=function(){const e=q("fe-groups.json");return n.existsSync(e)?w.readJSONSync(e):{groups:[]}}(),t=await m({message:"请选择一个分组",choices:e.map((e=>({name:`${e.name} [${e.description}]`,value:e.id,short:e.name})))});a.group={id:t,name:e.find((e=>e.id===t))?.name}},u=async()=>{a.projectName=await d({message:"请输入项目名称",validate:tt}),a.projectDesc=await d({message:"请输入项目描述",validate:nt})};await s(),await o(),await u();const l=`${N}/${a.group?.name}/${a.projectName}.git`,p=h("模版初始化中").start();await ie(`git clone --depth=1 ${a.tplUrl}`),n.renameSync(a.tplName,a.projectName),c.cd(a.projectName),c.rm("-rf",".git"),await ie(`git init --initial-branch=${E.MASTER}`),await ie(`git remote add origin ${l}`),await ie(`git config user.name ${he("gitName")}`),await ie(`git config user.email ${he("gitEmail")}`);const g=be();t={...g,name:a.projectName,description:a.projectDesc,scripts:{...g.scripts,prepare:"[ -n '$z' ] && z init prepare || echo 'Warning: z not exist at global'"}},ve=ve?{...ve,...t}:t,w.writeJSONSync(i.join("package.json"),ve,{spaces:2}),await w.writeFile(i.resolve("README.md"),function(e="项目中文名",t="项目描述"){return`\n# ${e}\n${t}\n\n## 快速开始\n### 安装依赖\n\`\`\`bash\n npm i\n\`\`\`\n\n### 本地开发\n\`\`\`bash\n npm run dev:<environment>:[platform]\n\`\`\`\n\n### 打包代码\n\`\`\`bash\n npm run build:<environment>:[platform]\n\`\`\`\n\n\n### 查找、修复代码问题\n\`\`\`bash\n z run eslint\n # 或者\n z r e\n\`\`\`\n\n### 格式化代码\n\`\`\`bash\n z run prettier\n # 或者\n z r p\n\`\`\`\n\n### 检测类型问题\n\`\`\`bash\n z run type-check\n # 或者\n z r tc\n\`\`\`\n\n### 检测依赖更新\n\`\`\`bash\n z run dependency-check\n # 或者\n z r dc\n\`\`\`\n\n## 常见问题\n列出开发中常见的问题和解决方案\n\n## 了解更多\n在此处放入飞书文档链接。请在[前端团队-项目手册](https://hxhtbr8t8uy.feishu.cn/drive/folder/QfQ7favVWljQk7d63Prc8mUGnJf)中按照分类新建文档。\n`}(a.projectName,a.projectDesc)),p.succeed("模版初始化完成"),await Ye(a.tplLanguage,a.group?.name);const f=h("依赖安装中").start();await ie("npm install --registry https://registry.npmmirror.com/"),f.succeed("依赖安装完成");const y=h("项目推送中").start();await ie('git add . && git commit -m "chore: 项目初始化"'),await ie("git tag v0.0.1");const v=await(e={name:a.projectName,description:a.projectDesc,path:a.projectName,visibility:"private",namespace_id:a.group?.id},Oe({url:`${_e()}/projects`,method:"post",data:e}));await ie(`git push -u origin ${E.MASTER}`),await ie(`git push origin HEAD:${E.MASTER} --tags`),y.succeed(`项目已推送到远程,地址: ${r.blue(l)}`);const $=h("初始化分支中").start(),b=`feat_init_${se()}`,j=ue(a.group?.name)?[E.DEV,E.TEST,E.RELEASE,b]:[b],S=await Promise.allSettled(j.map((e=>function(e){return Oe({url:`${_e()}/projects/${e.id}/repository/branches`,method:"post",data:e})}({id:v.id,branch:e,ref:E.MASTER})))),k=[];S.forEach((({status:e},t)=>{"fulfilled"===e&&k.push(j[t])})),await ie("git pull"),k.includes(b)?(await ie(`git checkout -b ${b} origin/${b}`),$.succeed(`项目已切换到初始分支: ${r.blue(b)}`)):$.warn("开发分支检出失败!项目当前在主分支,请自行检出开发分支。");const T=`cd ${a.projectName} && z start`;console.log(`输入 ${r.green(T)} 开始开发吧~`),process.exit(0)}catch(e){Y(e)}var e,t}var ut,lt;async function pt(e,t){let a;e?[ut.Project,ut.ProjectAbbr].includes(e)?a=ut.Project:[ut.Branch,ut.BranchAbbr].includes(e)?a=ut.Branch:[ut.Page,ut.PageAbbr].includes(e)?a=ut.Page:[ut.Component,ut.ComponentAbbr].includes(e)?a=ut.Component:[ut.CommitMsg,ut.CommitMsgAbbr].includes(e)?a=ut.CommitMsg:Y("参数输入错误"):a=await m({message:"请选择你要创建的类型",choices:[{name:"提交信息(commit message)",value:ut.CommitMsg},{name:"分支(branch)",value:ut.Branch},{name:"页面(page)",value:ut.Page},{name:"组件(component)",value:ut.Component},{name:"项目(project)",value:ut.Project}]}),a===ut.Project?await ct():(re(),oe(),a===ut.Branch?(await ce(),await async function(e){let t,n;re(),oe(),await ce(),t=e.branchType?e.branchType:await m({message:"请选择创建分支的类型",choices:[{name:"开发新功能(feat)",value:x.FEAT},{name:"修复BUG(fix)",value:x.FIX},{name:"重构/优化代码(refactor)",value:x.REFACTOR}]}),n=e.branchPurpose?e.branchPurpose:await d({message:"请输入创建分支的目的(大小写字母、数字,小驼峰式命名。如userInfo)",validate:it});const i=`${t}_${n}_${se()}`;await ie(`git fetch origin ${E.MASTER}`),await ie(`git checkout -b ${i} origin/${E.MASTER}`),await ie(`git push -u origin ${i}`),process.exit(0)}(t)):a===ut.CommitMsg?await ot():a===ut.Page?await async function(){const e="pages",t=await Ae(e);n.mkdirSync(i.resolve("src",e),{recursive:!0});const a=await d({message:"请输入目录及页面名称(如user/list,不带文件后缀)",validate:at});let s;if(a.includes("/")){const t=a.split("/");t.pop(),s=i.resolve("src",e,...a.split("/")),n.mkdirSync(i.resolve("src",e,...t),{recursive:!0})}else s=i.resolve("src",e,a);const{pages:r}=await Le(),o=n.readdirSync(t),u=await m({message:"请选择模版",choices:r.filter((e=>o.includes(e.name))).map((e=>({name:`${e.name}: ${e.desc}(${e.author})`,value:e.name})))}),l=h("页面生成中...").start(),p=s+i.extname(i.join(t,u));c.cp("-r",i.join(t,u),p),ee(p)?ne(p).forEach((e=>{Ce(i.join(p,e),a)})):Ce(p,a),l.succeed("页面生成成功"),process.exit(0)}():a===ut.Component&&await async function(){const e="components",t=await Ae("components");n.mkdirSync(i.resolve("src",e),{recursive:!0});const a=await d({message:"请输入目录及组件名称(如user/list,不带文件后缀)",validate:at});let s;if(a.includes("/")){const t=a.split("/"),r=t.pop();s=i.resolve("src",e,...t,xe(r)),n.mkdirSync(i.resolve("src",e,...t),{recursive:!0})}else s=i.resolve("src",e,xe(a));const{components:r}=await Le(),o=n.readdirSync(t),u=await m({message:"请选择模版",choices:r.filter((e=>o.includes(e.name))).map((e=>({name:`${e.name}: ${e.desc}(${e.author})`,value:e.name})))}),l=h("组件生成中...").start(),p=s+i.extname(i.join(t,u));c.cp("-r",i.join(t,u),p),ee(p)?ne(p).forEach((e=>{Ce(i.join(p,e),a)})):Ce(p,a),l.succeed("组件生成成功"),process.exit(0)}())}function mt(e){return Ie({url:`${ye("K8sDomain")}/kapis/clusters/youshou-local/devops.kubesphere.io/v1alpha3/namespaces/${O}/pipelines/${e.projectName}/pipelineruns?branch=${e.branchName}`,method:"post",data:e.params})}async function dt(e,t){re(),oe(),await ce();let n=e,i=t.platform;if(n&&!Object.values(E).includes(n)&&Y("仅支持发布指定环境分支"),i&&!Object.values(k).includes(i)&&Y("发布平台错误"),i||(i=await m({message:"请选择平台",choices:A})),i===k.NPM&&(n=E.MASTER),!n){const e=await m({message:"请选择部署环境",choices:T});n=(a=e)===S.PROD?E.MASTER:a}var a;let s=[];t.skipSelectionNotification||(s=await Ge("请选择部署成功要通知的人员:",(()=>!0),!0));var o;!function(e,t){const n=be(),i=je();if(i?.repository?.url||Y(".z/project.json中缺少repository.url"),t===k.H5){const t=`build:${e}`;n?.scripts[t]||Y(`项目package.json文件scripts不存在命令${t}。`)}t===k.NPM&&(n?.scripts.build||Y("项目package.json文件scripts不存在命令build。"))}((o=n)===E.MASTER?S.PROD:o,i);const c=be();await async function(e){const t=h("部署任务创建中").start(),{targetBranch:n,notify:i,projectName:a}=e,s=i?[...new Set([he("weWorkUserId"),...i])]:[he("weWorkUserId")];try{const{metadata:e,spec:i}=await mt({projectName:a,branchName:n,params:{parameters:[{name:"QW_NOTIFY_USER",value:s.join(",")}]}}),o=`${ye("K8SWebDomain")}/youshou-local/clusters/youshou-local/devops/${e.namespace}/pipelines/${i.pipelineRef.name}/branch/${i.scm.refName}/run/${e.name}/task-status`;t.succeed("部署任务创建完成"),console.log(`如有需要,可在k8s中查看 ${r.blue(o)}`),process.exit(0)}catch(e){t.fail("部署任务创建失败"),Y(e)}}({projectName:c.name,targetBranch:n,notify:s})}async function gt(e,t,n){const i=h(`分支合并中,${e} -> ${t}`).start();let s=0;try{const{iid:i}=await(r={title:`${e} -> ${t} by z-develop`,id:n.id,source_branch:e,target_branch:t,remove_source_branch:E.MASTER===t},Oe({url:`${_e()}/projects/${r.id}/merge_requests`,method:"post",data:r}));s=i}catch(e){if(a.isAxiosError(e)){const t=e?.response?.status;409===t&&Y(`存在重复的合并请求,前往查看${n.mergeRequestUrl}`)}Y(e)}var r;const o=async()=>{try{await new Promise((e=>{setTimeout(e,5e3)})),await function(e){return Oe({url:`${_e()}/projects/${e.id}/merge_requests/${e.iid}/merge`,method:"put"})}({id:n.id,iid:s}),i.succeed(`分支${e}已合并到分支${t}`)}catch(e){a.isAxiosError(e)||Y(e);const t=e?.response?.status;if(406===t)return await o();if(await function(e){return Oe({url:`${_e()}/projects/${e.id}/merge_requests/${e.iid}`,method:"put",data:e})}({id:n.id,iid:s,state_event:"close"}),405===t){const e=await function(e){return Oe({url:`${_e()}/projects/${e.id}/merge_requests/${e.iid}`,method:"get"})}({id:n.id,iid:s});if("cannot_be_merged"===e.merge_status&&e.diff_refs.base_sha===e.diff_refs.head_sha)return void i.warn("MR已关闭。判定为空的合并请求(没有新内容),可继续进行部署")}i.fail("合并过程中出现冲突,MR已关闭。建议在本地完成合并。"),process.exit(1)}};await o()}async function ft(e,t){re(),oe(),await ce();const n=await ke();Object.values(E).includes(n.sourceBranch)&&Y(`当前分支${n.sourceBranch}不可作为源分支合并到目标分支。`);const i=await(a=n.id,Oe({url:`${_e()}/projects/${a}/repository/branches`}));var a;const s=ue(n.group),o=i.filter((e=>![n.sourceBranch].includes(e.name))).map((e=>{let t=e.name;return s&&Object.values(E).includes(t)&&(t=r.bold.blue(t)),{name:t,value:e.name}}));let c;e&&!o.filter((t=>t.value===e)).length&&Y(`未找到目标分支${e}`),c=e||await m({message:"请选择要合并到的目标分支:",choices:o});const u=h(`${n.sourceBranch}分支代码检测中`).start();if(await ie(`git ls-remote --heads origin ${n.sourceBranch}`)){u.text=`存在远程分支origin/${n.sourceBranch}`,await ie("git fetch");const e=await ie(`git rev-parse ${n.sourceBranch}`),t=await ie(`git rev-parse origin/${n.sourceBranch}`);if(await ie(`git merge-base ${t} HEAD`)===t)await ie(`git push -u origin ${n.sourceBranch}`),u.succeed(`${n.sourceBranch}分支代码已推送到远程`);else{await ie(`git merge-base ${e} ${t}`)===e?(await ie("git pull"),u.succeed(`${n.sourceBranch}分支代码已更新`)):(u.fail(`远程分支origin/${n.sourceBranch}和本地分支${n.sourceBranch}都有新的提交,请手动合并后再试。`),process.exit(1))}}else await ie(`git push -u origin ${n.sourceBranch}`),u.succeed(`${n.sourceBranch}已推送到远程`);await async function(e,t,n){const i=`origin/${e.sourceBranch}`,a=await ie(`git log -b origin/${E.MASTER} -1 --format=%H`),s=await ie(`git log -b origin/${e.sourceBranch} -1 --format=%H`),o=await ie(`git log ${a}...${s} -b ${i}`);if(o||Y(`分支${e.sourceBranch}上不存在新的commit,不需要合并。`),await ie(`git branch --contains ${a} -r ${i}`)||(console.log(r.yellow("注意:当前分支上不存在远程主分支最新代码,将在自动合入后继续。")),await gt(E.MASTER,e.sourceBranch,e)),t===E.MASTER&&n){const e=o.split("\n").filter((e=>e)),t=await ie(`git log -b origin/${S.TEST} -1 --format=%H`);(function(e,t){for(const n of t)if(!e.includes(n))return!1;return!0})((await ie(`git log ${a}...${t} -b origin/${S.TEST}`)).split("\n").filter((e=>e)),e)||Y("请先在测试环境发布要部署的代码")}}(n,c,s),await gt(n.sourceBranch,c,n),E.MASTER===c&&(await ie(`git checkout ${E.MASTER}`),await ie(`git pull origin ${E.MASTER}`),await ie(`git branch -d ${n.sourceBranch}`),Z(`${n.sourceBranch}分支已移除,当前已切换到最新的${E.MASTER}。如需继续开发,请检出新分支(z c b)。`)),s&&Object.values(E).includes(c)&&await dt(c,{platform:t.deployPlatform,skipSelectionNotification:t.deploySkipSelectionNotification})}async function ht(e){let t=e;t?[S.DEV,S.TEST,S.RELEASE,S.PROD,"d","t","r","p"].includes(e)?"d"===t?t=S.DEV:"t"===t?t=S.TEST:"r"===t?t=S.RELEASE:"p"===t&&(t=S.PROD):Y("参数输入有误"):t=await m({message:"请选择环境",choices:T});const n=`dev:${t}`;be().scripts[n]?ae(`npm run ${n}`):Y(`项目中(package.josn > scripts)不存在命令${n},请先添加!`)}function wt(){const e=L();if(n.existsSync(e)){const t=w.readJsonSync(e);if(t["lint-staged"])return t["lint-staged"];throw new Error("未找到lint配置")}throw new Error("请先初始化项目(z i .)。")}function yt(){const e=function(e){if(e.includes("Merge")&&e.includes("# Conflicts:"))return!0;if($.valid(e))return!0;const t=e.split(": ");if(1===t.length)return"body前缺少「: 」";const n=t[0];return/^(feat|fix|refactor)/.test(n)?!!/\(\d+(?:,\d+)*\)/.test(n)||"ID缺少或者格式不正确。":/^(chore|ci)/.test(n)?!![z.CHORE,z.CI].includes(n)||"chore/ci类型无需填写ID。":z.Break===n||"不存在的提交类型。"}(n.readFileSync(i.resolve(".git","COMMIT_EDITMSG"),"utf-8"));!0===e?(Z("commit msg validate success."),process.exit(0)):Y(`commit msg格式错误。${e}`)}async function vt(e,t){let a;re(),oe(),e?[lt.CommitMsg,lt.CommitMsgAbbr].includes(e)?a=lt.CommitMsg:[lt.CommitFiles,lt.CommitFilesAbbr].includes(e)?a=lt.CommitFiles:[lt.Prettier,lt.PrettierAbbr].includes(e)?a=lt.Prettier:[lt.Eslint,lt.EslintAbbr].includes(e)?a=lt.Eslint:[lt.TypeCheck,lt.TypeCheckAbbr].includes(e)?a=lt.TypeCheck:[lt.DependencyCheck,lt.DependencyCheckAbbr].includes(e)?a=lt.DependencyCheck:Y("参数输入错误"):a=await m({message:"请选择你要执行的操作",choices:[{name:"执行 prettier",value:lt.Prettier},{name:"执行 eslint",value:lt.Eslint},{name:"执行 type-check",value:lt.TypeCheck},{name:"执行 dependency-check",value:lt.DependencyCheck}]}),a===lt.CommitMsg?yt():a===lt.CommitFiles?await async function(){await v({concurrent:!1,debug:!1,config:wt()})?(Z("代码风格检测通过!"),process.exit(0)):Y("代码风格检测未通过!")}():a===lt.Prettier?await async function(){n.existsSync(i.resolve("node_modules",".bin","prettier"))||Y("该项目未安装prettier,请安装后重试");try{await ie("npx prettier --write . --config .z/.prettierrc.json --ignore-path .z/.prettierignore --ignore-unknown --no-error-on-unmatched-pattern",{silent:!1}),Z("prettier执行成功"),process.exit(0)}catch(e){Y("prettier校验出错")}}():a===lt.Eslint?await async function(e){n.existsSync(i.resolve("node_modules",".bin","eslint"))||Y("该项目未安装eslint,请安装后重试");try{let t="npx eslint '**/*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}' --fix";"win32"===process.platform&&(t='npx eslint "**/*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}" --fix'),e.quiet&&(t+=" --quiet"),e.maxWarnings&&!isNaN(Number(e.maxWarnings))?t+=` --max-warnings ${Number(e.maxWarnings)}`:t+=" --max-warnings 100",await ie(t,{silent:!1}),Z("eslint执行成功"),process.exit(0)}catch(e){Y("eslint校验出错")}}(t):a===lt.TypeCheck?(n.existsSync(i.resolve("./node_modules/.bin/vue-tsc"))||Y("请先安装vue-tsc。推荐命令: npm i -D vue-tsc"),ae("vue-tsc --build"),process.exit(0)):a===lt.DependencyCheck&&await async function(){await ce();const e=await b({format:["group","repo"],interactive:!0,upgrade:!0,install:"always"});if(e&&Object.keys(e).length){console.log(r.green("升级完成 🎉"));const t=Object.entries(e).map((([e,t])=>`${e}@${t}`)).join("; ");await ie(`git add . && git commit -m "chore: 依赖升级。${t}"`)}process.exit(0)}()}async function $t(e="latest"){await ie(`npm i -g ${ge.name}@${e} --registry https://registry.npmmirror.com/`),Pe("latestCheckVersionTimestamp",Date.now()),Pe("version",e),Te(),console.log(r.green(`升级完成,当前版本${e}`)),process.exit(0)}async function bt(){const e=j(process.argv.slice(2));if(!(e.h||e.help||e.v||e.version)&&(!["init","i"].includes(e._[0])||[".","prepare"].includes(e._[1])))if(H()){const e=w.readJSONSync(V());Re(e.profile),Pe(e.main),Ne(e.constants),await async function(){const e=we("latestCheckVersionTimestamp"),t=we("versionCheckDuring");if(Date.now()-Number(e)>24*Number(t)*3600*1e3){let e;Ne(await We());try{const t="TIME_OUT",n=new Promise((e=>{setTimeout((()=>e(t)),3e3)}));e=await Promise.race([n,ie(`npm view ${ge.name} version --registry https://registry.npmmirror.com/`)]),e!==t&&e!==ge.version&&(console.log(`${r.blue(ge.name)}本地版本为${ge.version},低于线上版本${e},开始升级`),await $t(e)),Pe("latestCheckVersionTimestamp",Date.now()),Te()}catch(e){console.log("升级出错!请重试,或者手动升级"),Y(e)}}}()}else Y("请先初始化z-develop(执行 z i)。更多见https://hxhtbr8t8uy.feishu.cn/docx/RnOhdtqJWo5UooxHTaUcQFwtnKg")}!function(e){e.Project="project",e.ProjectAbbr="pr",e.Branch="branch",e.BranchAbbr="b",e.Page="page",e.PageAbbr="pa",e.Component="component",e.ComponentAbbr="co",e.CommitMsg="commit-msg",e.CommitMsgAbbr="cm"}(ut||(ut={})),e.command("create").alias("c").argument("[type]","可选值为project|pr, branch|b, commit-msg|cm, page|p, component|co").option("--branch-type <type>",`分支类型。可选值:${Object.values(x).join(", ")}`).option("--branch-purpose <purpose>","创建分支的目的").description("创建项目/分支/提交信息/页面/组件").action(((...e)=>le(pt,...e))),e.command("merge").alias("m").argument("[branch]","目标分支名称").option("--deploy-platform <platform>",`合并成功后要部署的平台。可选值:${Object.values(k).join("/")}`).option("--deploy-skip-selection-notification","部署时,是否跳过选择部署通知人环节").description("合并当前分支到指定远程分支,并部署。").action(((...e)=>le(ft,...e))),e.command("deploy").alias("d").description("部署到指定环境").argument("[branchName]",`部署环境。可选值:${Object.values(E).join("/")}`).option("--platform <platform>",`部署平台。可选值:${Object.values(k).join("/")}`).option("--skip-selection-notification","是否跳过选择部署通知人环节").action(((...e)=>le(dt,...e))),e.command("start").alias("s").description("启动本地开发环境").argument("[env]","业务环境。可选值 dev|d, test|t, release|r, prod|p").action(((...e)=>le(ht,...e))),function(e){e.CommitMsg="commit-msg",e.CommitMsgAbbr="cm",e.CommitFiles="commit-files",e.CommitFilesAbbr="cf",e.Prettier="prettier",e.PrettierAbbr="p",e.Eslint="eslint",e.EslintAbbr="e",e.TypeCheck="type-check",e.TypeCheckAbbr="tc",e.DependencyCheck="dependency-check",e.DependencyCheckAbbr="dc"}(lt||(lt={})),e.command("run").aliases(["r","l","lint"]).argument("[type]","非必填。可选值为commit-msg|cm, commit-files|cf, prettier|p, eslint|e, type-check|tc, dependency-check|dc。").option("--quiet","eslint只打印error").option("--max-warnings [VALUE]","eslint结果warn超过多少个会异常退出,默认为100",parseInt).description("执行 eslint / prettier / type-check / dependency-check 脚本。").action(((...e)=>le(vt,...e))),e.command("update").alias("u").argument("[version]","版本号","latest").description("升级").action(((...e)=>le($t,...e))),e.name("z-develop").alias("z").description(`z-develop, 开发流程管理工具。\n了解更多: ${r.blue("https://hxhtbr8t8uy.feishu.cn/docx/RnOhdtqJWo5UooxHTaUcQFwtnKg")}`).usage("<command> [options]").hook("preAction",(async function(){process.on("unhandledRejection",(e=>{})),process.on("uncaughtException",(e=>{})),c.config.fatal=!0,c.config.silent=!0,c.config.verbose=Boolean(void 0)||!1,await bt()})).version(ge.version,"-v, --version","当前版本号").helpOption("-h, --help","帮助").showHelpAfterError("可以使用z -h查看帮助。"),e.parse(); |
{ | ||
"name": "cli-z-develop", | ||
"version": "0.4.2", | ||
"version": "0.4.3", | ||
"description": "前端本地开发命令行工具", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
48602
0.63%267
0.38%