cli-z-develop 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{program as e}from"commander";import t from"chalk";import i from"shelljs";import n from"fs-extra";import o from"minimist";import s from"node:fs";import r from"node:path";import a from"node:os";import c,{AxiosError as l}from"axios";import u from"dayjs";import p from"inquirer";import d from"inquirer/lib/prompts/base.js";import m from"inquirer/lib/utils/paginator.js";import f from"inquirer/lib/utils/events.js";import"inquirer/lib/objects/choices.js";import{map as g,takeUntil as h,filter as y}from"rxjs";import v from"figures";import b from"ora";import j from"child_process";import $ from"lint-staged";var w={name:"cli-z-develop",version:"0.0.21",description:"前端本地开发命令行工具",main:"dist/index.js",bin:{z:"./bin/z.js","z-develop":"./bin/z.js"},scripts:{prepare:"husky",dev:"rollup -c -w --environment DEBUG:true",build:"rollup -c",eslint:"eslint '**/*.{ts,js}' --fix",prettier:"prettier -wu .",upload:"npm version patch && npm run build && npm publish --access public --registry https://registry.npmjs.org/"},type:"module",repository:{type:"git",url:"http://git.cxlqd.com/fe-base/cli-z-develop.git"},author:"z",devDependencies:{"@commitlint/cli":"^19.3.0","@commitlint/config-conventional":"^19.2.2","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^15.2.3","@rollup/plugin-replace":"^5.0.5","@rollup/plugin-terser":"^0.4.4","@types/fs-extra":"^11.0.4","@types/inquirer":"^9.0.7","@types/minimist":"^1.2.5","@types/node":"^20.12.12","@types/shelljs":"^0.8.15","@types/tough-cookie":"^4.0.5","@typescript-eslint/eslint-plugin":"^7.9.0","@typescript-eslint/parser":"^7.9.0",eslint:"^8.57.0","eslint-config-alloy":"^5.1.2","eslint-config-prettier":"^9.1.0",husky:"^9.0.11",prettier:"^3.2.5",rollup:"^4.17.2","rollup-plugin-typescript2":"^0.36.0",tslib:"^2.6.2",typescript:"^5.4.5"},dependencies:{axios:"^1.7.1",chalk:"^5.3.0",commander:"^12.1.0",dayjs:"^1.11.11",figures:"^6.1.0","fs-extra":"^11.2.0",inquirer:"^9.2.22",minimist:"^1.2.8",ora:"^8.0.1",rxjs:"^7.8.1",shelljs:"^0.8.5","lint-staged":"^15.2.2"}};function k(e,t,i,n){return new(i||(i=Promise))((function(o,s){function r(e){try{c(n.next(e))}catch(e){s(e)}}function a(e){try{c(n.throw(e))}catch(e){s(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(r,a)}c((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const S='{\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',x="# 系统 信息文件\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",z={Java:{"**/*.{java}":"./run.sh pmd -d ../../../src/main/java/ -f text -R rulesets/java/quickstart.xml"},JavaScript:{"**/*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}":"eslint --fix","*":"prettier -wu"}},O=[{name:"开发环境 - dev",value:"dev"},{name:"测试环境 - test",value:"test"},{name:"预发环境 - release",value:"release"},{name:"正式环境 - production",value:"production"}],N=[{name:"网页 - h5",value:"h5"},{name:"支付宝小程序 - alipay",value:"alipay"},{name:"微信小程序 - weapp",value:"weapp"},{name:"node module - npm",value:"npm"}],E=["main","master"],q=["dev","test","release"],D=["fix","feat","refactor"],T={1:"研发",2:"测试",3:"产品",4:"设计",5:"运营",6:"销售",7:"行政",8:"财务",9:"其他"},C="http://git.cxlqd.com",_={PROJECT_NAME:"fe-pages-tpl",GIT_URL:`${C}/fe-component/fe-pages-tpl.git`},I=["fe-biz","fe-base","fe-tpl","fe-component","fe-demo"];function J(e){if(!e)return"不能为空";if(!/^[a-z0-9-]+$/.test(e))return"格式为小写字母、中横线(可选)、数字(不推荐)。如apple, apple-tree";return!V().includes(e)||"当前目录下已存在同名文件夹,请先处理。"}function L(e){return!!e||"不能为空"}function P(e){return e?!!/^[a-zA-Z0-9]+$/.test(e)||"格式为大小写字母、数字,小驼峰命名。如userInfo、systemRouter3":"不能为空"}function A(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"}}return!0}const{red:U,green:B,blue:W,magenta:R}=t;function K(...e){console.log(B(...e))}function F(e,t=!1){let i=e;e instanceof Error?(i=e.message,c.isAxiosError(e)&&(i=`请求失败:${e.message}`),console.log(U(i)),console.log(R(e.stack))):console.log(U(e)),t||process.exit(1)}function M(e){return!!s.existsSync(e)&&s.lstatSync(e).isDirectory()}function V(e=process.cwd()){if(M(e)){return s.readdirSync(e).filter((t=>M(r.resolve(e,t))))}return[]}function G(){return r.resolve(a.homedir(),".z")}function H(){return r.resolve(G(),"develop-config.json")}function Q(){return s.existsSync(G())&&s.existsSync(H())}function Z(e){return k(this,arguments,void 0,(function*(e,t={removeTailLinkBreak:!0,silent:!0}){let n=yield new Promise(((n,o)=>{try{n(i.exec(e,{silent:t.silent}))}catch(e){o(e)}}));return n=n.toString(),t.removeTailLinkBreak&&(n=n.replace(/\n$/,"")),n}))}function Y(){return u(Date.now()).format("YYMMDD")}function X(){s.existsSync(r.resolve(".z"))||F("当前不在项目根目录。请切换到项目根目录")}function ee(){s.existsSync(r.resolve(".git"))||F("当前不是git项目根目录,请先执行git init,或切换到根目录")}function te(){return k(this,void 0,void 0,(function*(){""!==(yield Z("git status -s"))&&F("请先提交代码变动,再进行操作")}))}function ie(e){return!["fe-tpl","fe-component"].includes(e)}const ne={profile:{ldapAccount:"",ldapPassword:"",gitToken:"",gitUserId:0,gitName:"",gitEnglishName:"",gitEmail:"",weWorkName:"",weWorkUserId:"",jobType:"fe",zenTaoToken:""},main:{version:w.version,latestCheckVersionTimestamp:0,versionCheckDuring:3,weWorkListCache:[]},constants:{ZenTaoDomain:"",FEServerDomain:"",jenkinsDomain:"",jenkinsUsername:"",jenkinsPassword:"",OSSEndpoint:"",OSSAccessKeyID:"",OSSAccessKeySecret:"",OSSBucketName:""}};function oe(e,t){void 0!==t?ne.profile[e]=t:ne.profile=Object.assign(Object.assign({},ne.profile),e)}function se(e,t){ne.constants=Object.assign(Object.assign({},ne.constants),e)}function re(e,t){void 0!==t?ne.main[e]=t:ne.main=Object.assign(Object.assign({},ne.main),e)}function ae(e){return e?ne.profile[e]:ne.profile}function ce(e){return e?ne.main[e]:ne.main}function le(e){return e?ne.constants[e]:ne.constants}let ue=null,pe=null;function de(){if(ue)return ue;const e=r.resolve("package.json");try{ue=n.readJsonSync(e)}catch(t){F(`当前目录(${i.pwd()})不存在${e}文件,请在项目根目录执行该命令。`)}return ue}function me(){if(pe)return pe;const e=r.resolve(".z","project.json");try{pe=n.readJsonSync(e)}catch(t){F(`当前目录(${i.pwd()})不存在${e}文件,请在项目根目录执行该命令,或者初始化项目(z init .)。`)}return pe}function fe(e){pe=pe?Object.assign(Object.assign({},pe),e):e,n.writeJSONSync(r.resolve(".z","project.json"),pe,{spaces:2})}function ge(){return k(this,void 0,void 0,(function*(){const e=yield ke({url:`${Oe()}/groups`}),t=I.map((t=>{const i=e.find((e=>e.name===t));return!!i&&{name:i.name,id:i.id,description:i.description}})).filter((e=>!!e)),i=r.join(G(),"fe-groups.json");n.writeJSONSync(i,{groups:t},{spaces:2})}))}const he={id:0,name:"",group:"",sourceBranch:"",mergeRequestUrl:""};function ye(){return k(this,void 0,void 0,(function*(){if(!he.name){const e=de();he.name=e.name}if(!he.group){const e=me();e.repository.group&&(he.group=e.repository.group)}if(!he.id)try{const e=he.group?`${he.group}/${he.name}`:he.name,[t]=yield qe(e);he.mergeRequestUrl=t.web_url+"/merge_requests",he.id=t.id,he.group=t.namespace.path;const i=me();i.repository.group||fe({repository:Object.assign(Object.assign({},i.repository),{group:t.namespace.path})})}catch(e){F(e)}return he.sourceBranch||(he.sourceBranch=yield Z("git branch --show-current")),he}))}function ve(){n.writeJSONSync(H(),{main:ce(),profile:ae(),constants:le()},{spaces:2})}function be(e,t){const i=[];t.forEach((t=>{e.includes(t.value)&&i.push(t)}));const n=ce("weWorkListCache"),o=n.map((e=>e.value));i.forEach((e=>{const t=o.indexOf(e.value);t>-1?n[t].usageCount+=1:n.push(Object.assign(Object.assign({},e),{usageCount:1}))})),re({weWorkListCache:n.sort(((e,t)=>t.usageCount-e.usageCount))}),ve()}function je(){return k(this,void 0,void 0,(function*(){const{data:e}=yield ze({url:"/user/list"}),t=e.filter((e=>[1,2,3].includes(e.title))).map((e=>({name:`${e.nick} - ${T[e.title]}`,value:e.weWorkUserId}))),i=ce("weWorkListCache"),n=i.map((e=>e.value)),o=[];return t.forEach((e=>{const t=n.indexOf(e.value);o.push(Object.assign(Object.assign({},e),{usageCount:t>-1?i[t].usageCount:0}))})),o.sort(((e,t)=>t.usageCount-e.usageCount))}))}function $e(e){return k(this,void 0,void 0,(function*(){var i;const n=e.method||"get",o=e.headers||{},s=e.data||{},r=e.dataKey||["GET","get"].includes(n)?"params":"data",a=e.auth||void 0;try{const i={url:e.url,method:n,[r]:s,headers:o,auth:a};t.magenta(i.method.toUpperCase()),t.yellow(i.url),JSON.stringify(i.headers),JSON.stringify(i.auth||{}),t.gray(JSON.stringify(i[r],null,2));const l=yield c(i);return t.green("Response"),t.grey(JSON.stringify(l.data,null,2)),Promise.resolve(l.data)}catch(e){return e instanceof l&&(t.red("Error"),t.grey(JSON.stringify(null===(i=null==e?void 0:e.response)||void 0===i?void 0:i.data))),Promise.reject(e)}}))}function we(){return k(this,void 0,void 0,(function*(){const e=ae("gitToken");if(e)return e;{const{access_token:e}=yield $e({url:`${C}/oauth/token`,method:"post",data:{grant_type:"password",username:ae("ldapAccount"),password:ae("ldapPassword")}}),t=`Bearer ${e}`;return oe("gitToken",t),ve(),t}}))}function ke(e){return k(this,void 0,void 0,(function*(){return $e(Object.assign(Object.assign({},e),{headers:{Authorization:yield we()}}))}))}function Se(){return k(this,void 0,void 0,(function*(){const e=ae("zenTaoToken");if(e)return e;{const{token:e}=yield $e({url:`${le("ZenTaoDomain")}/api.php/v1/tokens`,method:"post",data:{account:ae("ldapAccount"),password:ae("ldapPassword")}});return oe("zenTaoToken",e),ve(),e}}))}function xe(e){return k(this,void 0,void 0,(function*(){const t=yield $e(Object.assign(Object.assign({},e),{headers:{Token:yield Se()}}));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?(oe("zenTaoToken",""),xe(Object.assign({},e))):t}))}function ze(e){return k(this,void 0,void 0,(function*(){const t=`${le("FEServerDomain")}/api`,{data:i}=yield $e({url:`${t}/auth/z-develop/login`,method:"post"});return $e({url:t+e.url,headers:{Authorization:`Bearer ${i}`},data:e.data,method:e.method||"post"})}))}const Oe=()=>`${C}/api/v4`,Ne=e=>Oe()+"/projects/100/repository/files/"+encodeURIComponent(e)+"/raw?ref=master";function Ee(){return ke({url:Ne("src/data/z-develop-config.json")})}function qe(e){return ke({url:`${Oe()}/projects`,data:{search:e,search_namespaces:!0}})}function De(e){return ke({url:`${Oe()}/projects/${e}/repository/branches`})}const Te=e=>`${le("ZenTaoDomain")}${e}`;function Ce(e,i){let n="";return e.forEach(((e,o)=>{if(e.disabled)n=`${n} - ${e.name} (Disabled)`;else{n+=o===i?t.cyan(v.pointer)+" ":" ",n+=(e.checked||!1?t.green(v.radioOn):v.radioOff)+" "+e.name}n+="\n"})),n.replace(/\n$/,"")}class _e extends d{constructor(e,t,i){super(e,t,i),this.pointer=0,this.opt.choices||this.throwParamError("choices"),this.opt.choices.forEach(((e,t)=>{const i=e;i.checked=!1,i.id=t}));if(this.opt.choices.find((e=>"separator"===e.type)))throw new Error("Separator is not allowed in choices.");Array.isArray(this.opt.default)&&this.opt.choices.forEach((e=>{"separator"!==e.type&&this.opt.default.includes(e.value)&&(e.checked=!0)})),this.pointer=0,this.selection=[],this.done=e=>{console.log(e)},this.opt.default=null,this.paginator=new m(this.screen,{isInfinite:!0}),this.filterList=this.allList=this.opt.choices.choices}_run(e){this.done=e;const t=f(this.rl),i=this.handleSubmitEvents(t.line.pipe(g(this.getCurrentValue.bind(this))));i.success.forEach(this.onEnd.bind(this)),i.error.forEach(this.onError.bind(this)),t.normalizedUpKey.pipe(h(i.success)).forEach(this.onUpKey.bind(this)),t.normalizedDownKey.pipe(h(i.success)).forEach(this.onDownKey.bind(this)),t.spaceKey.pipe(h(i.success)).forEach(this.onSpaceKey.bind(this));const n=["up","down","space"];return t.keypress.pipe(y((e=>!e.key.ctrl&&!n.includes(e.key.name||"")))).pipe(h(i.success)).forEach(this.onKeyPress.bind(this)),this.render(),this}render(e){let i=this.getQuestion(),n="";if(this.getCurrentValue(),"answered"===this.status)i+=t.cyan(this.selection.join(","));else{this.selection.length?i+=t.magenta(`[已选: ${this.selection.join(",")}]`):i+="("+t.blue.bold("空格键")+"选择,"+t.blue.bold("回车键")+"提交,"+t.blue.bold("输入中文")+"搜索)",i+=t.bgYellowBright(t.black(this.rl.line));const e=Ce(this.filterList,this.pointer);n=this.paginator.paginate(e,this.pointer,this.opt.pageSize)}e&&(n=t.red(">> ")+e),this.screen.render(i,n)}getCurrentValue(){const e=this.allList.filter((e=>e.checked&&!e.disabled));return this.selection=e.map((e=>e.short)),e.map((e=>e.value))}toggleChoice(e){const t=this.filterList[e];t&&(this.allList[t.id].checked=!t.checked)}filterChoices(){this.filterList=this.allList.filter((e=>{var t;return null===(t=e.name)||void 0===t?void 0:t.includes(this.rl.line.trim())}))}onSpaceKey(){this.toggleChoice(this.pointer),this.render(),this.rl.resume()}onDownKey(){const e=this.filterList.length;this.pointer=this.pointer<e-1?this.pointer+1:0,this.render()}onUpKey(){const e=this.filterList.length;this.pointer=this.pointer>0?this.pointer-1:e-1,this.render()}onKeyPress(){this.pointer=0,this.filterChoices(),this.render()}onEnd(e){this.status="answered",this.render(),this.screen.done(),this.done(e.value)}onError(e){this.render(e.isValid)}}function Ie(){return k(this,void 0,void 0,(function*(){const e=o(process.argv.slice(2));if(!["init","i"].includes(e._[0]))if(Q()){const e=n.readJSONSync(H());oe(e.profile),re(e.main),se(e.constants),yield function(){return k(this,void 0,void 0,(function*(){const e=ce("latestCheckVersionTimestamp"),i=ce("versionCheckDuring");if(Date.now()-Number(e)>24*Number(i)*3600*1e3){se(yield Ee());const e=yield Z(`npm view ${w.name} version`);if(e!==w.version){console.log(`${t.blue(w.name)}本地版本为${w.version},低于线上版本${e},开始升级`);try{yield Z(`npm i -g ${w.name}`),re("latestCheckVersionTimestamp",Date.now()),ve(),console.log(t.green("升级完成!")),process.exit(0)}catch(e){console.log("升级出错!请重试,或者手动升级"),F(e)}}}}))}()}else e.h||e.help||e.v||e.version||F("请先初始化z-develop(执行 z i)。更多见https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/us8lgdb5cq4kf3aa#PJK7q")}))}function Je(){return k(this,void 0,void 0,(function*(){try{if(Q()){const{isRemove:e}=yield p.prompt([{type:"confirm",name:"isRemove",message:"系统中已存在z的配置文件,确认重新配置?"}]);e?i.rm("-rf",H()):process.exit(0)}s.mkdirSync(G(),{recursive:!0});const{jobType:e,account:t,password:n}=yield p.prompt([{type:"list",name:"jobType",message:"请选择岗位类型",choices:[{name:"前端",value:"fe"},{name:"后端",value:"be"}]},{type:"input",name:"account",message:"请输入LDAP账号:"},{type:"input",name:"password",message:"请输入LDAP密码:"}]);oe("jobType",e),oe("ldapAccount",t),oe("ldapPassword",n);se(yield Ee());const o=yield je(),{weWork:r}=yield p.prompt([{type:"search-checkbox",name:"weWork",message:"请选择你自己(用于企微通知):",choices:o,validate:e=>e.length>1?"只能选一个":!(e.length<1)||"请选一个"}]),{name:a,value:c}=o.find((e=>e.value===r[0]));oe({weWorkName:a,weWorkUserId:c})}catch(e){F(e)}const e=b("配置信息初始化中").start();try{const t=yield ke({url:`${Oe()}/user`});oe({gitUserId:t.id,gitName:t.name,gitEnglishName:t.username,gitEmail:t.email}),re("latestCheckVersionTimestamp",Date.now()),ve(),yield ge(),e.succeed("配置信息初始化完成")}catch(t){e.fail("配置信息初始化失败"),c.isAxiosError(t)&&F("请检查你的域名及令牌配置"),F(t)}}))}const Le=".z",Pe=(e="")=>r.join(Le,e);let Ae;function Ue(e,t){return k(this,void 0,void 0,(function*(){if(s.existsSync(Pe())){const{isRemove:e}=yield p.prompt([{type:"confirm",name:"isRemove",message:`当前项目中已存在配置文件夹${Le},确认重新配置?`}]);e?i.rm("-rf",".z"):process.exit(0)}s.mkdirSync(Pe(),{recursive:!0}),yield function(e,t){return k(this,void 0,void 0,(function*(){const i=yield Z("git remote get-url --push origin");i||F("获取项目远程地址失败,请配置后重试");let n=e;if(!n){const{language:e}=yield p.prompt([{type:"list",name:"language",message:"请选择项目语言",choices:[{name:"JavaScript",value:"JavaScript"},{name:"Java",value:"Java"}]}]);n=e}let o=t;const s=me();if(s.repository.group)o=s.repository.group;else if(!o){const e=de(),t=yield qe(e.name);if(1===t.length)o=t[0].namespace.path;else if(t.length>1){const{groupName:e}=yield p.prompt([{type:"list",name:"groupName",message:"请选择当前项目所属分组",choices:t.map((e=>({name:e.namespace.path,value:e.namespace.path})))}]);o=e}}Ae=b("项目初始化中").start(),fe({language:n,"lint-staged":z[n],repository:{url:i,group:o}})}))}(e,t),yield function(){return k(this,void 0,void 0,(function*(){j.spawnSync("git",["config","core.hooksPath",Le]),s.writeFileSync(Pe(".commit-msg-tpl"),"",{mode:493}),j.spawnSync("git",["config","commit.template",r.join(Le,".commit-msg-tpl")]),s.writeFileSync(Pe("commit-msg"),"#!/usr/bin/env sh\nz lint commit-msg",{mode:493}),s.writeFileSync(Pe("pre-commit"),"#!/usr/bin/env sh\nz lint commit-files",{mode:493}),s.writeFileSync(Pe(".prettierrc.json"),S,{mode:493}),s.writeFileSync(Pe(".prettierignore"),x,{mode:493}),s.writeFileSync(Pe(".gitignore"),".commit-msg-tpl\n",{mode:493})}))}(),null==Ae||Ae.succeed("初始化完成。")}))}function Be(){return k(this,void 0,void 0,(function*(){var e,o,a,c,l,u;try{const d={},m=()=>k(this,void 0,void 0,(function*(){const e=V(),{projects:t}=yield ke({url:Ne("src/data/template-projects.json")}),i=t.map((t=>{const i={name:`${t.name} [${t.desc}]`,value:t.name,short:t.name,disabled:!1};return e.includes(t.name)&&(i.disabled="目录下已存在同名文件夹"),i})),{project:n}=yield p.prompt([{type:"list",name:"project",message:"请选择一个项目模板",choices:i}]),o=t.find((e=>e.name===n));d.tplName=o.name,d.tplUrl=o.url})),f=()=>k(this,void 0,void 0,(function*(){var e;const{groups:t}=function(){const e=r.join(G(),"fe-groups.json");return s.existsSync(e)?n.readJSONSync(e):{groups:[]}}(),{group:i}=yield p.prompt([{type:"list",name:"group",message:"请选择一个分组",choices:t.map((e=>({name:`${e.name} [${e.description}]`,value:e.id,short:e.name})))}]);d.group={id:i,name:null===(e=t.find((e=>e.id===i)))||void 0===e?void 0:e.name}})),g=()=>k(this,void 0,void 0,(function*(){const{name:e,desc:t}=yield p.prompt([{type:"input",name:"name",message:"请输入项目名称",validate:J},{type:"input",name:"desc",message:"请输入项目描述",validate:L}]);d.projectName=e,d.projectDesc=t}));yield m(),yield f(),yield g();const h=`${C}/${null===(e=d.group)||void 0===e?void 0:e.name}/${d.projectName}.git`,y=b("模版初始化中").start();yield Z(`git clone --depth=1 ${d.tplUrl}`),i.mv(d.tplName,d.projectName),i.cd(d.projectName),i.rm("-rf",".git"),yield Z("git init --initial-branch=master"),yield Z(`git remote add origin ${h}`),yield Z(`git config user.name ${ae("gitName")}`),yield Z(`git config user.email ${ae("gitEmail")}`),u=Object.assign(Object.assign({},de()),{name:d.projectName,description:d.projectDesc}),ue=ue?Object.assign(Object.assign({},ue),u):u,n.writeJSONSync(r.resolve("package.json"),ue,{spaces:2}),yield n.writeFile(r.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> 查看更多关于 [platform](https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/nttvbeif4a62gtpz#faWqt) 和 [environment](https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/nttvbeif4a62gtpz#faWqt)\n\n### 打包代码\n\`\`\`bash\n npm run build:{environment}:{platform}\n\`\`\`\n\n### 格式化、修复代码语法\n\`\`\`bash\n z lint prettier\n\`\`\`\n\n> [ESLint相关规范](https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/ul914hdkqz8fr02g#AkvQ4)\n\n### 格式化文档\n\`\`\`bash\n z lint prettier\n\`\`\`\n\n> [Prettier相关规范](https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/ul914hdkqz8fr02g#ojpwI)\n\n## 常见问题\n列出开发中常见的问题和解决方案\n\n## 了解更多\n在此处放入语雀文档链接。请在[前端团队-项目手册](https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/bfrcicwzosoyaifg)中按照分类新建文档。\n`}(d.projectName,d.projectDesc)),y.succeed("模版初始化完成"),yield Ue("JavaScript",null===(o=d.group)||void 0===o?void 0:o.name);const v=b("依赖安装中").start();yield Z("npm install"),v.succeed("依赖安装完成");const j=b("项目推送中").start();yield Z('git add . && git commit -m "chore: init"');const $=yield(l={name:d.projectName,description:d.projectDesc,path:d.projectName,visibility:"private",namespace_id:null===(a=d.group)||void 0===a?void 0:a.id},ke({url:`${Oe()}/projects`,method:"post",data:l}));yield Z("git push -u origin master"),j.succeed(`项目已推送到远程,地址: ${t.blue(h)}`);const w=b("初始化分支中").start(),S=`feat_init_${Y()}`,x=ie(null===(c=d.group)||void 0===c?void 0:c.name)?[...q,S]:[S],z=yield Promise.allSettled(x.map((e=>function(e){return ke({url:`${Oe()}/projects/${e.id}/repository/branches`,method:"post",data:e})}({id:$.id,branch:e,ref:"master"})))),O=[];z.forEach((({status:e},t)=>{"fulfilled"===e&&O.push(x[t])})),yield Z("git fetch origin"),O.includes(S)?(yield Z(`git checkout -b ${S} origin/${S}`),w.succeed(`项目已切换到初始分支: ${t.blue(S)}`)):w.warn("开发分支检出失败!项目当前在主分支,请自行检出开发分支。");const N=`cd ${d.projectName} && z start`;console.log(`输入 ${t.green(N)} 开始开发吧~`)}catch(e){F(e)}}))}function We(e){return 0!==e.length||"请选择项"}function Re(){return k(this,void 0,void 0,(function*(){const{type:e}=yield p.prompt({type:"list",name:"type",message:"请选择你要创建的模板类型",choices:[{name:"feat - 业务需求开发",value:"feat"},{name:"fix - bug修复",value:"fix"},{name:"refactor - 技术内部需求",value:"refactor"},{name:"chore - 其他",value:"chore"}]});if(["feat","refactor"].includes(e)){const e=yield function(){return k(this,void 0,void 0,(function*(){const e=yield xe({url:Te("/my-work-task.json?tid=mrrferp8"),method:"get"});return null==e?void 0:e.tasks.map((({id:e,name:t})=>({value:{name:t,value:e},name:t})))}))}(),{tasks:t}=yield p.prompt({type:"checkbox",name:"tasks",message:"请关联开发任务(可多选):",validate:We,choices:e.map((e=>Object.assign(Object.assign({},e),{name:`[${e.value.value}]: ${e.name}`})))});Ke("feat",t)}else if("fix"===e){const e=yield function(){return k(this,void 0,void 0,(function*(){const e=yield xe({url:Te("/my-work-bug.json?tid=mrrferp8"),method:"get"});return null==e?void 0:e.bugs.map((({id:e,title:t})=>({name:t,value:{name:t,value:e}})))}))}(),{bugs:t}=yield p.prompt({type:"checkbox",name:"bugs",message:"请关联Bug(可多选):",validate:We,choices:e.map((e=>Object.assign(Object.assign({},e),{name:`[${e.value.value}]: ${e.name}`})))});Ke("fix",t)}else if("chore"===e){const{msg:e}=yield p.prompt({type:"input",name:"msg",message:"请输入commit msg:",validate:e=>0!==e.length||"请输入commit msg"});Ke("chore",[e])}}))}function Ke(e,i){let n="";if(["feat","refactor","fix"].includes(e)){n=`${e}(${i.map((e=>e.value)).join(",")}): ${i.map((e=>e.name)).join(";")}`}"chore"===e&&(n=`${e}: ${i[0]}`),s.writeFileSync(r.resolve(".z",".commit-msg-tpl"),n,"utf-8"),console.log(t.yellow(n)),K("commit msg模板写入成功,可以进行提交了")}function Fe(){return k(this,void 0,void 0,(function*(){const e=G(),t=r.join(e,_.PROJECT_NAME);s.existsSync(t)?yield Z("git fetch origin"):(i.cd(e),yield Z(`git clone ${_.GIT_URL} --depth=1`));const n=r.join(t,"src","pages");s.existsSync(n)||F("模板库不存在!");const o=s.readdirSync(n),{tplName:a}=yield p.prompt([{name:"tplName",type:"list",message:"请选择页面模板",choices:o.map((e=>({name:e,value:e})))}]);console.log(a),s.mkdirSync(r.resolve("src","pages"),{recursive:!0});const{dirName:c}=yield p.prompt([{name:"dirName",type:"input",message:"请输入页面目录名称(已存在则跳过创建)",validate:A}]);s.mkdirSync(r.resolve("src","pages",c),{recursive:!0});const l=function(e=process.cwd()){if(M(e))return s.readdirSync(e).filter((t=>!M(r.resolve(e,t))));return[]}(r.resolve("src","pages",c)),{pageName:u}=yield p.prompt([{name:"pageName",type:"input",message:"请输入页面名称",validate:e=>function(e,t){return e?/^[a-z][a-z0-9\-]+$/.test(e)?!t.includes(e)||"页面已存在":"支持小写字母、数字,连字符(-)命名,小写字母开头。如user、modules-3":"页面名称不能为空"}(e,l)}]);console.log(u)}))}function Me(e,t){return k(this,void 0,void 0,(function*(){const i=function(e){const{pathname:t}=new URL(e),i=t.match(/\/(.+)\.git/);if(i)return i[1];F("GitLab URL有误")}(e),{originBranch:n,environment:o,platform:s,notify:r,processId:a}=t;var c;yield(c={params:{command:"build",params:JSON.stringify({originBranch:n,environment:o,platform:s,profile:{weWorkName:ae("weWorkName"),weWorkUserId:ae("weWorkUserId")}}),options:JSON.stringify({processId:a,notify:r||[]})},jobName:i},$e({url:`${le("jenkinsDomain")}/job/${c.jobName}/buildWithParameters`,method:"post",dataKey:"params",data:c.params,auth:{username:le("jenkinsUsername"),password:le("jenkinsPassword")}}))}))}function Ve(e){return k(this,void 0,void 0,(function*(){try{const{originBranch:t,environment:i,platform:n,notify:o,processId:s}=e,r=me();!function(e,t){var i,n,o,s,r;const a=de(),c=me();(null===(i=null==c?void 0:c.repository)||void 0===i?void 0:i.url)||F("项目package.json文件中缺少repository.url");const l=`build:${e}:${t}`;(null==a?void 0:a.scripts[l])||F(`项目package.json文件scripts不存在命令${l}。`),["alipay","weapp"].includes(t)&&(a.mini||F("请在package.json配置mini字段"),"alipay"===t&&((null===(o=null===(n=a.mini)||void 0===n?void 0:n.alipay)||void 0===o?void 0:o.appid)||F("请在package.json配置mini.alipay.appid字段")),"weapp"===t&&((null===(r=null===(s=a.mini)||void 0===s?void 0:s.weapp)||void 0===r?void 0:r.appid)||F("请在package.json配置mini.weapp.appid字段")))}(i,n),yield Z("git fetch origin"),yield function(e,t){return k(this,void 0,void 0,(function*(){const i=me(),n=yield Z(`git remote show ${i.repository.url}`),[,o]=n.match(/HEAD branch: (.+)\n/),s=yield Z(`git log -b origin/${o} -1 --format=%H`),r=`origin/${e}`;if((yield Z(`git branch --contains ${s} -r ${r}`))||F(`请先将最新的主分支(${o})代码合并到${r},再进行部署。`),"production"!==t)return;const a=yield Z(`git log -b origin/${e} -1 --format=%H`),c=(yield Z(`git log ${s}...${a} -b ${r}`)).split("\n");c.length||F(`分支${e}上没有要发布的commit`);const l=yield Z("git log -b origin/test -1 --format=%H");(function(e,t){for(let i of t)if(!e.includes(i))return!1;return!0})((yield Z(`git log ${s}...${l} -b origin/test`)).split("\n"),c)||F("请先在测试环境发布要部署的代码")}))}(t,i),yield Me(r.repository.url,{originBranch:t,environment:i,platform:n,notify:o,processId:s})}catch(e){F(e)}}))}function Ge(){if(s.existsSync(r.resolve(".z","project.json"))){const e=n.readJsonSync(r.resolve(".z","project.json"));if(e["lint-staged"])return e["lint-staged"];throw new Error("未找到lint配置")}throw new Error("请先初始化项目(z i .)。")}e.command("init").alias("i").argument("[type]","非必填。可选值:.。不传为初始化工具配置;传 . 为初始化当前项目。").description("初始化工具配置、项目配置").action((function(e){return k(this,void 0,void 0,(function*(){e?"."===e?(ee(),yield Ue(void 0,void 0)):F("参数错误。执行 z init -h 查看帮助。"):yield Je()}))})),e.command("create").alias("c").argument("[type]","可选值为project|p, branch|b, commit-msg|cm。传 p 为创建项目;传 b 为创建分支;传 cm 为创建提交信息").description("创建项目/分支/提交信息").action((function(e){return k(this,void 0,void 0,(function*(){let t;if(e)["project","pr"].includes(e)?t="project":["branch","b"].includes(e)?t="branch":["page","pa"].includes(e)?t="page":["commit-msg","cm"].includes(e)?t="commit-msg":F("参数输入错误");else{t=(yield p.prompt({type:"list",name:"type",message:"请选择你要创建的类型",choices:[{name:"提交信息",value:"commit-msg"},{name:"分支",value:"branch"},{name:"页面",value:"page"},{name:"项目",value:"project"}]})).type}"project"===t?yield Be():"branch"===t?(X(),ee(),yield te(),yield function(){return k(this,void 0,void 0,(function*(){const{type:e,purpose:t}=yield p.prompt([{name:"type",type:"list",message:"请选择创建分支的类型",choices:[{name:"开发新功能(feat)",value:"feat"},{name:"修复BUG(fix)",value:"fix"},{name:"重构/优化代码(refactor)",value:"refactor"}]},{name:"purpose",type:"input",message:"请输入创建分支的目的(大小写字母、数字,小驼峰式命名。如userInfo)",validate:P}]),i=`${e}_${t}_${Y()}`,n=me(),o=yield Z(`git remote show ${n.repository.url}`),[,s]=o.match(/HEAD branch: (.+)\n/);yield Z("git fetch origin"),yield Z(`git checkout -b ${i} origin/${s}`)}))}()):"commit-msg"===t?(X(),ee(),yield Re()):"page"===t&&(X(),ee(),yield Fe())}))})),e.command("merge").alias("m").description("合并当前分支到指定远程分支,并部署。").action((function(){return k(this,void 0,void 0,(function*(){var e;X(),ee(),yield te();const i=yield ye(),n=yield De(i.id),o=[...q],s=ie(i.group),r=n.filter((e=>s?![...E,i.sourceBranch].includes(e.name):![i.sourceBranch].includes(e.name))).map((e=>{let i=e.name;return s&&o.includes(i)&&(i=t.bold.blue(i)),{name:i,value:e.name}})),{target:a}=yield p.prompt([{type:"list",name:"target",message:"请选择要合并到的目标分支:",choices:r}]),l=o.includes(a);let u="h5",d=[];if(l){const e=yield je(),t=yield p.prompt([{type:"list",name:"platform",message:"请选择平台",choices:[{name:"网页 - h5",value:"h5"},{name:"支付宝小程序 - alipay",value:"alipay"},{name:"微信小程序 - weapp",value:"weapp"}]},{type:"search-checkbox",name:"notify",message:"请选择部署成功要通知的人员:",choices:e,validate:e=>!(e.length<1)||"至少选一个"}]);be(d,e),u=t.platform,d=t.notify}yield Z("git fetch origin"),yield Z(`git push -u origin ${i.sourceBranch}`);let m=0;try{const{iid:e}=yield(f={title:"MR by z-develop",id:i.id,source_branch:i.sourceBranch,target_branch:a,remove_source_branch:!s&&E.includes(a)},ke({url:`${Oe()}/projects/${f.id}/merge_requests`,method:"post",data:f}));m=e}catch(t){if(c.isAxiosError(t)){409===(null===(e=null==t?void 0:t.response)||void 0===e?void 0:e.status)&&F(`存在重复的合并请求,前往查看${i.mergeRequestUrl}`)}F(t)}var f;const g=()=>k(this,void 0,void 0,(function*(){var e;try{yield new Promise((e=>{setTimeout(e,5e3)})),yield function(e){return ke({url:`${Oe()}/projects/${e.id}/merge_requests/${e.iid}/merge`,method:"put"})}({id:i.id,iid:m})}catch(t){if(c.isAxiosError(t)){406===(null===(e=null==t?void 0:t.response)||void 0===e?void 0:e.status)?yield g():(yield function(e){return ke({url:`${Oe()}/projects/${e.id}/merge_requests/${e.iid}`,method:"put",data:e})}({id:i.id,iid:m,state_event:"close"}),F("合并过程中出现冲突,MR已关闭。建议在本地完成合并。"))}else F(t)}}));yield g(),l&&(yield Ve({originBranch:a,environment:a,platform:u,notify:d,processId:""}))}))})),e.command("deploy").alias("d").description("发布指定远程分支").action((function(){return k(this,void 0,void 0,(function*(){const e=yield je(),{environment:t,platform:i,notify:n}=yield p.prompt([{type:"list",name:"environment",message:"请选择部署环境",choices:O},{type:"list",name:"platform",message:"请选择平台",choices:N},{type:"search-checkbox",name:"notify",message:"请选择部署成功要通知的人员:",choices:e,validate:e=>!(e.length<1)||"至少选一个"}]);be(n,e);let o=t,s="";if("production"===t){const e=yield ye(),t=(yield De(e.id)).filter((e=>![...E,...q].includes(e.name))).map((e=>({name:e.name,value:e.name}))),n=yield p.prompt([{type:"list",name:"branchName",message:"请输入要部署的分支:",choices:t},{type:"input",name:"processId",message:"请输入本次部署的企微审批编号"}]);o=n.branchName,s=n.processId,function(e){const t=e.split("_");if(4!==t.length)return!1;const[i,n,o]=t;return!!D.includes(i)&&!0===P(n)&&8===o.length&&!isNaN(Number(o))}(o)||F("分支命名不符合规范,参见https://zhongshitech.yuque.com/nx4ugr/guide/mg8t44#bQhu4");const{data:{state:a,content:c}}=yield(r={businessId:s},ze({url:"/approval/findByBusinessId",data:r}));1===a&&F("当前审批流程状态为审批中,审批通过才能进行发布。"),3===a&&F("当前审批流程状态为已驳回,请重新提交审批。"),4===a&&F("当前审批流程状态为已发布,如需再次发布,请重新提交审批。");const{formComponentValues:l}=JSON.parse(c),u={};l.forEach((e=>{u[e.name]=e.value})),u["申请人"]!==ae("weWorkName")&&F("发布审批申请人与当前发布人不一致!"),u["项目名称"]!==de().name&&F("发布审批项目名称与当前发布项目名称不一致!"),u["发布分支"]!==o&&F("发布审批发布分支与当前发布分支不一致!"),u["发布平台"]!==i&&F("发布审批发布平台与当前发布平台不一致!")}var r;yield Ve({originBranch:o,environment:t,platform:i,notify:n,processId:s})}))})),e.command("start").alias("s").description("启动本地开发环境").action((function(){return k(this,void 0,void 0,(function*(){const e=de(),{environment:t}=yield p.prompt([{type:"list",name:"environment",message:"请选择环境",choices:O}]),n=`dev:${t}`;if(e.scripts[n])try{i.exec(`npm run ${n}`,{silent:!1})}catch(e){F(e)}else F(`项目中(package.josn > scripts)不存在命令${n},请先添加!`)}))})),e.command("lint").alias("l").argument("[type]","非必填。可选值为commit-msg|cm, commit-files|cf, prettier|p, eslint|e。传 cm 为执行 lint commit-msg;传 cf 为执行 lint commit-files;传 p 为全部文件执行prettier;传 e 为全部文件执行eslint。cm 和 cf属于内部命令,会在git hooks中自动执行。").description("执行 lint 脚本。包含 lint staged 、 lint commit message、 prettier、 eslint。").action((function(e){return k(this,void 0,void 0,(function*(){let t;if(X(),ee(),e)["commit-msg","cm"].includes(e)?t="commit-msg":["commit-files","cf"].includes(e)?t="commit-files":["prettier","p"].includes(e)?t="prettier":["eslint","e"].includes(e)?t="eslint":F("参数输入错误");else{t=(yield p.prompt({type:"list",name:"type",message:"请选择你要执行的操作",choices:[{name:"全局执行 prettier",value:"prettier"},{name:"全局执行 eslint",value:"eslint"}]})).type}if("commit-msg"===t)yield function(){return k(this,void 0,void 0,(function*(){const e=function(e){const t=s.readFileSync(r.resolve(".git","COMMIT_EDITMSG"),"utf-8").split(": ");if(1===t.length)return"body前缺少「:」";{const e=t[0];return/^(feat|fix|refactor)/.test(e)?!!/\(\d+(?:,\d+)*\)/.test(e)||"ID缺少或者格式不正确。":/^chore/.test(e)?"chore"===e||"chore类型无需填写ID。":"不存在的提交类型。"}}();!0===e?K("commit msg validate success."):F(`commit msg格式错误。${e}`)}))}();else if("commit-files"===t)yield function(){return k(this,void 0,void 0,(function*(){(yield $({concurrent:!1,debug:void 0,config:Ge()}))?K("代码风格检测通过!"):F("代码风格检测未通过!")}))}();else if("prettier"===t){s.existsSync(r.resolve("node_modules",".bin","prettier"))||F("该项目未安装prettier,请安装后重试");try{yield Z("prettier --write . --config .z/.prettierrc.json --ignore-path .z/.prettierignore --ignore-unknown --no-error-on-unmatched-pattern",{silent:!1}),K("prettier执行成功")}catch(e){F("prettier校验出错")}}else if("eslint"===t){console.log(r.resolve("node_modules",".bin","eslint")),s.existsSync(r.resolve("node_modules",".bin","eslint"))||F("该项目未安装eslint,请安装后重试");try{yield Z("eslint '**/*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}' --fix",{silent:!1}),K("eslint执行成功")}catch(e){F("eslint校验出错")}}}))})),function(){k(this,void 0,void 0,(function*(){process.on("unhandledRejection",(e=>{})),process.on("uncaughtException",(e=>{})),i.config.fatal=!0,i.config.silent=!0,i.config.verbose=!1,yield Ie(),p.registerPrompt("search-checkbox",_e)}))}(),e.name("z-develop").alias("z").description(`z-develop, 开发流程管理工具。\n了解更多: ${t.blue("https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/us8lgdb5cq4kf3aa")}`).usage("<command> [options]").version(w.version,"-v, --version","当前版本号").helpOption("-h, --help","帮助").showHelpAfterError("可以使用z -h查看帮助。"),e.parse();
|
|
1
|
+
import{program as e}from"commander";import t from"chalk";import i from"shelljs";import n from"fs-extra";import o from"minimist";import s from"node:fs";import r from"node:path";import a from"node:os";import c,{AxiosError as l}from"axios";import u from"dayjs";import p from"inquirer";import d from"inquirer/lib/prompts/base.js";import m from"inquirer/lib/utils/paginator.js";import f from"inquirer/lib/utils/events.js";import"inquirer/lib/objects/choices.js";import{map as g,takeUntil as h,filter as y}from"rxjs";import v from"figures";import b from"ora";import j from"child_process";import $ from"lint-staged";var w={name:"cli-z-develop",version:"0.0.23",description:"前端本地开发命令行工具",main:"dist/index.js",bin:{z:"./bin/z.js","z-develop":"./bin/z.js"},scripts:{prepare:"husky",dev:"rollup -c -w --environment DEBUG:true",build:"rollup -c",eslint:"eslint '**/*.{ts,js}' --fix",prettier:"prettier -wu .",upload:"npm version patch && npm run build && npm publish --access public --registry https://registry.npmjs.org/"},type:"module",repository:{type:"git",url:"http://git.cxlqd.com/fe-base/cli-z-develop.git"},author:"z",devDependencies:{"@commitlint/cli":"^19.3.0","@commitlint/config-conventional":"^19.2.2","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^15.2.3","@rollup/plugin-replace":"^5.0.5","@rollup/plugin-terser":"^0.4.4","@types/fs-extra":"^11.0.4","@types/inquirer":"^9.0.7","@types/minimist":"^1.2.5","@types/node":"^20.12.12","@types/shelljs":"^0.8.15","@types/tough-cookie":"^4.0.5","@typescript-eslint/eslint-plugin":"^7.9.0","@typescript-eslint/parser":"^7.9.0",eslint:"^8.57.0","eslint-config-alloy":"^5.1.2","eslint-config-prettier":"^9.1.0",husky:"^9.0.11",prettier:"^3.2.5",rollup:"^4.17.2","rollup-plugin-typescript2":"^0.36.0",tslib:"^2.6.2",typescript:"^5.4.5"},dependencies:{axios:"^1.7.1",chalk:"^5.3.0",commander:"^12.1.0",dayjs:"^1.11.11",figures:"^6.1.0","fs-extra":"^11.2.0",inquirer:"^9.2.22",minimist:"^1.2.8",ora:"^8.0.1",rxjs:"^7.8.1",shelljs:"^0.8.5","lint-staged":"^15.2.2"}};function k(e,t,i,n){return new(i||(i=Promise))((function(o,s){function r(e){try{c(n.next(e))}catch(e){s(e)}}function a(e){try{c(n.throw(e))}catch(e){s(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(r,a)}c((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const{red:S,green:x,blue:z,magenta:O}=t;function N(...e){console.log(x(...e))}function E(e,t=!1){let i=e;e instanceof Error?(i=e.message,c.isAxiosError(e)&&(i=`请求失败:${e.message}`),console.log(S(i)),console.log(O(e.stack))):console.log(S(e)),t||process.exit(1)}function q(e){return!!s.existsSync(e)&&s.lstatSync(e).isDirectory()}function D(e=process.cwd()){if(q(e)){return s.readdirSync(e).filter((t=>q(r.resolve(e,t))))}return[]}function T(){return r.resolve(a.homedir(),".z")}function C(){return r.resolve(T(),"develop-config.json")}function _(){return s.existsSync(T())&&s.existsSync(C())}function I(e){return k(this,arguments,void 0,(function*(e,t={removeTailLinkBreak:!0,silent:!0}){let n=yield new Promise(((n,o)=>{try{n(i.exec(e,{silent:t.silent}))}catch(e){o(e)}}));return n=n.toString(),t.removeTailLinkBreak&&(n=n.replace(/\n$/,"")),n}))}function J(){return u(Date.now()).format("YYMMDD")}function L(){s.existsSync(r.resolve(".z"))||E("当前不在项目根目录。请切换到项目根目录")}function P(){s.existsSync(r.resolve(".git"))||E("当前不是git项目根目录,请先执行git init,或切换到根目录")}function A(){return k(this,void 0,void 0,(function*(){""!==(yield I("git status -s"))&&E("请先提交代码变动,再进行操作")}))}function U(e){return!["fe-tpl","fe-component"].includes(e)}const B={profile:{ldapAccount:"",ldapPassword:"",gitToken:"",gitUserId:0,gitName:"",gitEnglishName:"",gitEmail:"",weWorkName:"",weWorkUserId:"",jobType:"fe",zenTaoToken:""},main:{version:w.version,latestCheckVersionTimestamp:0,versionCheckDuring:3,weWorkListCache:[]},constants:{ZenTaoDomain:"",FEServerDomain:"",jenkinsDomain:"",jenkinsUsername:"",jenkinsPassword:"",OSSEndpoint:"",OSSAccessKeyID:"",OSSAccessKeySecret:"",OSSBucketName:""}};function W(e,t){void 0!==t?B.profile[e]=t:B.profile=Object.assign(Object.assign({},B.profile),e)}function R(e,t){B.constants=Object.assign(Object.assign({},B.constants),e)}function K(e,t){void 0!==t?B.main[e]=t:B.main=Object.assign(Object.assign({},B.main),e)}function F(e){return e?B.profile[e]:B.profile}function M(e){return e?B.main[e]:B.main}function V(e){return e?B.constants[e]:B.constants}const G='{\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',H="# 系统 信息文件\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",Q={Java:{"**/*.{java}":"./run.sh pmd -d ../../../src/main/java/ -f text -R rulesets/java/quickstart.xml"},JavaScript:{"**/*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}":"eslint --fix","*":"prettier -wu"}},Z=[{name:"开发环境 - dev",value:"dev"},{name:"测试环境 - test",value:"test"},{name:"预发环境 - release",value:"release"},{name:"正式环境 - production",value:"production"}],Y=[{name:"网页 - h5",value:"h5"},{name:"支付宝小程序 - alipay",value:"alipay"},{name:"微信小程序 - weapp",value:"weapp"},{name:"node module - npm",value:"npm"}],X=["main","master"],ee=["dev","test","release"],te=["fix","feat","refactor"],ie={1:"研发",2:"测试",3:"产品",4:"设计",5:"运营",6:"销售",7:"行政",8:"财务",9:"其他"},ne="http://git.cxlqd.com",oe={PROJECT_NAME:"fe-pages-tpl",GIT_URL:`${ne}/fe-component/fe-pages-tpl.git`},se=["fe-biz","fe-base","fe-tpl","fe-component","fe-demo"];let re=null,ae=null;function ce(){if(re)return re;const e=r.resolve("package.json");try{re=n.readJsonSync(e)}catch(t){E(`当前目录(${i.pwd()})不存在${e}文件,请在项目根目录执行该命令。`)}return re}function le(){if(ae)return ae;const e=r.resolve(".z","project.json");try{ae=n.readJsonSync(e)}catch(t){E(`当前目录(${i.pwd()})不存在${e}文件,请在项目根目录执行该命令,或者初始化项目(z init .)。`)}return ae}function ue(e){ae=ae?Object.assign(Object.assign({},ae),e):e,n.writeJSONSync(r.resolve(".z","project.json"),ae,{spaces:2})}function pe(){return k(this,void 0,void 0,(function*(){const e=yield be({url:`${ke()}/groups`}),t=se.map((t=>{const i=e.find((e=>e.name===t));return!!i&&{name:i.name,id:i.id,description:i.description}})).filter((e=>!!e)),i=r.join(T(),"fe-groups.json");n.writeJSONSync(i,{groups:t},{spaces:2})}))}const de={id:0,name:"",group:"",sourceBranch:"",mergeRequestUrl:""};function me(){return k(this,void 0,void 0,(function*(){if(!de.name){const e=ce();de.name=e.name}if(!de.group){const e=le();e.repository.group&&(de.group=e.repository.group)}if(!de.id)try{const e=de.group?`${de.group}/${de.name}`:de.name,[t]=yield ze(e);de.mergeRequestUrl=t.web_url+"/merge_requests",de.id=t.id,de.group=t.namespace.path;const i=le();i.repository.group||ue({repository:Object.assign(Object.assign({},i.repository),{group:t.namespace.path})})}catch(e){E(e)}return de.sourceBranch||(de.sourceBranch=yield I("git branch --show-current")),de}))}function fe(){n.writeJSONSync(C(),{main:M(),profile:F(),constants:V()},{spaces:2})}function ge(e,t){const i=[];t.forEach((t=>{e.includes(t.value)&&i.push(t)}));const n=M("weWorkListCache"),o=n.map((e=>e.value));i.forEach((e=>{const t=o.indexOf(e.value);t>-1?n[t].usageCount+=1:n.push(Object.assign(Object.assign({},e),{usageCount:1}))})),K({weWorkListCache:n.sort(((e,t)=>t.usageCount-e.usageCount))}),fe()}function he(){return k(this,void 0,void 0,(function*(){const{data:e}=yield we({url:"/user/list"}),t=e.filter((e=>[1,2,3].includes(e.title))).map((e=>({name:`${e.nick} - ${ie[e.title]}`,value:e.weWorkUserId}))),i=M("weWorkListCache"),n=i.map((e=>e.value)),o=[];return t.forEach((e=>{const t=n.indexOf(e.value);o.push(Object.assign(Object.assign({},e),{usageCount:t>-1?i[t].usageCount:0}))})),o.sort(((e,t)=>t.usageCount-e.usageCount))}))}function ye(e){return k(this,void 0,void 0,(function*(){var i;const n=e.method||"get",o=e.headers||{},s=e.data||{},r=e.dataKey||["GET","get"].includes(n)?"params":"data",a=e.auth||void 0;try{const i={url:e.url,method:n,[r]:s,headers:o,auth:a};t.magenta(i.method.toUpperCase()),t.yellow(i.url),JSON.stringify(i.headers),JSON.stringify(i.auth||{}),t.gray(JSON.stringify(i[r],null,2));const l=yield c(i);return t.green("Response"),t.grey(JSON.stringify(l.data,null,2)),Promise.resolve(l.data)}catch(e){return e instanceof l&&(t.red("Error"),t.grey(JSON.stringify(null===(i=null==e?void 0:e.response)||void 0===i?void 0:i.data))),Promise.reject(e)}}))}function ve(){return k(this,void 0,void 0,(function*(){const e=F("gitToken");if(e)return e;{const{access_token:e}=yield ye({url:`${ne}/oauth/token`,method:"post",data:{grant_type:"password",username:F("ldapAccount"),password:F("ldapPassword")}}),t=`Bearer ${e}`;return W("gitToken",t),fe(),t}}))}function be(e){return k(this,void 0,void 0,(function*(){return ye(Object.assign(Object.assign({},e),{headers:{Authorization:yield ve()}}))}))}function je(){return k(this,void 0,void 0,(function*(){const e=F("zenTaoToken");if(e)return e;{const{token:e}=yield ye({url:`${V("ZenTaoDomain")}/api.php/v1/tokens`,method:"post",data:{account:F("ldapAccount"),password:F("ldapPassword")}});return W("zenTaoToken",e),fe(),e}}))}function $e(e){return k(this,void 0,void 0,(function*(){const t=yield ye(Object.assign(Object.assign({},e),{headers:{Token:yield je()}}));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?(W("zenTaoToken",""),$e(Object.assign({},e))):t}))}function we(e){return k(this,void 0,void 0,(function*(){const t=`${V("FEServerDomain")}/api`,{data:i}=yield ye({url:`${t}/auth/z-develop/login`,method:"post"});return ye({url:t+e.url,headers:{Authorization:`Bearer ${i}`},data:e.data,method:e.method||"post"})}))}const ke=()=>`${ne}/api/v4`,Se=e=>ke()+"/projects/100/repository/files/"+encodeURIComponent(e)+"/raw?ref=master";function xe(){return be({url:Se("src/data/z-develop-config.json")})}function ze(e){return be({url:`${ke()}/projects`,data:{search:e,search_namespaces:!0}})}function Oe(e){return be({url:`${ke()}/projects/${e}/repository/branches`})}const Ne=e=>`${V("ZenTaoDomain")}${e}`;function Ee(e,i){let n="";return e.forEach(((e,o)=>{if(e.disabled)n=`${n} - ${e.name} (Disabled)`;else{n+=o===i?t.cyan(v.pointer)+" ":" ",n+=(e.checked||!1?t.green(v.radioOn):v.radioOff)+" "+e.name}n+="\n"})),n.replace(/\n$/,"")}class qe extends d{constructor(e,t,i){super(e,t,i),this.pointer=0,this.opt.choices||this.throwParamError("choices"),this.opt.choices.forEach(((e,t)=>{const i=e;i.checked=!1,i.id=t}));if(this.opt.choices.find((e=>"separator"===e.type)))throw new Error("Separator is not allowed in choices.");Array.isArray(this.opt.default)&&this.opt.choices.forEach((e=>{"separator"!==e.type&&this.opt.default.includes(e.value)&&(e.checked=!0)})),this.pointer=0,this.selection=[],this.done=e=>{console.log(e)},this.opt.default=null,this.paginator=new m(this.screen,{isInfinite:!0}),this.filterList=this.allList=this.opt.choices.choices}_run(e){this.done=e;const t=f(this.rl),i=this.handleSubmitEvents(t.line.pipe(g(this.getCurrentValue.bind(this))));i.success.forEach(this.onEnd.bind(this)),i.error.forEach(this.onError.bind(this)),t.normalizedUpKey.pipe(h(i.success)).forEach(this.onUpKey.bind(this)),t.normalizedDownKey.pipe(h(i.success)).forEach(this.onDownKey.bind(this)),t.spaceKey.pipe(h(i.success)).forEach(this.onSpaceKey.bind(this));const n=["up","down","space"];return t.keypress.pipe(y((e=>!e.key.ctrl&&!n.includes(e.key.name||"")))).pipe(h(i.success)).forEach(this.onKeyPress.bind(this)),this.render(),this}render(e){let i=this.getQuestion(),n="";if(this.getCurrentValue(),"answered"===this.status)i+=t.cyan(this.selection.join(","));else{this.selection.length?i+=t.magenta(`[已选: ${this.selection.join(",")}]`):i+="("+t.blue.bold("空格键")+"选择,"+t.blue.bold("回车键")+"提交,"+t.blue.bold("输入中文")+"搜索)",i+=t.bgYellowBright(t.black(this.rl.line));const e=Ee(this.filterList,this.pointer);n=this.paginator.paginate(e,this.pointer,this.opt.pageSize)}e&&(n=t.red(">> ")+e),this.screen.render(i,n)}getCurrentValue(){const e=this.allList.filter((e=>e.checked&&!e.disabled));return this.selection=e.map((e=>e.short)),e.map((e=>e.value))}toggleChoice(e){const t=this.filterList[e];t&&(this.allList[t.id].checked=!t.checked)}filterChoices(){this.filterList=this.allList.filter((e=>{var t;return null===(t=e.name)||void 0===t?void 0:t.includes(this.rl.line.trim())}))}onSpaceKey(){this.toggleChoice(this.pointer),this.render(),this.rl.resume()}onDownKey(){const e=this.filterList.length;this.pointer=this.pointer<e-1?this.pointer+1:0,this.render()}onUpKey(){const e=this.filterList.length;this.pointer=this.pointer>0?this.pointer-1:e-1,this.render()}onKeyPress(){this.pointer=0,this.filterChoices(),this.render()}onEnd(e){this.status="answered",this.render(),this.screen.done(),this.done(e.value)}onError(e){this.render(e.isValid)}}function De(){return k(this,void 0,void 0,(function*(){const e=o(process.argv.slice(2));if(!["init","i"].includes(e._[0]))if(_()){const e=n.readJSONSync(C());W(e.profile),K(e.main),R(e.constants),yield function(){return k(this,void 0,void 0,(function*(){const e=M("latestCheckVersionTimestamp"),i=M("versionCheckDuring");if(Date.now()-Number(e)>24*Number(i)*3600*1e3){R(yield xe());const e=yield I(`npm view ${w.name} version`);if(e!==w.version){console.log(`${t.blue(w.name)}本地版本为${w.version},低于线上版本${e},开始升级`);try{yield I(`npm i -g ${w.name}`),K("latestCheckVersionTimestamp",Date.now()),fe(),console.log(t.green("升级完成!")),process.exit(0)}catch(e){console.log("升级出错!请重试,或者手动升级"),E(e)}}}}))}()}else e.h||e.help||e.v||e.version||E("请先初始化z-develop(执行 z i)。更多见https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/us8lgdb5cq4kf3aa#PJK7q")}))}function Te(){return k(this,void 0,void 0,(function*(){try{if(_()){const{isRemove:e}=yield p.prompt([{type:"confirm",name:"isRemove",message:"系统中已存在z的配置文件,确认重新配置?"}]);e?i.rm("-rf",C()):process.exit(0)}s.mkdirSync(T(),{recursive:!0});const{jobType:e,account:t,password:n}=yield p.prompt([{type:"list",name:"jobType",message:"请选择岗位类型",choices:[{name:"前端",value:"fe"},{name:"后端",value:"be"}]},{type:"input",name:"account",message:"请输入LDAP账号:"},{type:"input",name:"password",message:"请输入LDAP密码:"}]);W("jobType",e),W("ldapAccount",t),W("ldapPassword",n);R(yield xe());const o=yield he(),{weWork:r}=yield p.prompt([{type:"search-checkbox",name:"weWork",message:"请选择你自己(用于企微通知):",choices:o,validate:e=>e.length>1?"只能选一个":!(e.length<1)||"请选一个"}]),{name:a,value:c}=o.find((e=>e.value===r[0]));W({weWorkName:a,weWorkUserId:c})}catch(e){E(e)}const e=b("配置信息初始化中").start();try{const t=yield be({url:`${ke()}/user`});W({gitUserId:t.id,gitName:t.name,gitEnglishName:t.username,gitEmail:t.email}),K("latestCheckVersionTimestamp",Date.now()),fe(),yield pe(),e.succeed("配置信息初始化完成")}catch(t){e.fail("配置信息初始化失败"),c.isAxiosError(t)&&E("请检查你的域名及令牌配置"),E(t)}}))}const Ce=".z",_e=(e="")=>r.join(Ce,e);let Ie;function Je(e,t){return k(this,void 0,void 0,(function*(){if(s.existsSync(_e())){const{isRemove:e}=yield p.prompt([{type:"confirm",name:"isRemove",message:`当前项目中已存在配置文件夹${Ce},确认重新配置?`}]);e?i.rm("-rf",".z"):process.exit(0)}s.mkdirSync(_e(),{recursive:!0}),yield function(e,t){return k(this,void 0,void 0,(function*(){const i=yield I("git remote get-url --push origin");i||E("获取项目远程地址失败,请配置后重试");let n=e;if(!n){const{language:e}=yield p.prompt([{type:"list",name:"language",message:"请选择项目语言",choices:[{name:"JavaScript",value:"JavaScript"},{name:"Java",value:"Java"}]}]);n=e}let o=t;const s=le();if(s.repository.group)o=s.repository.group;else if(!o){const e=ce(),t=yield ze(e.name);if(1===t.length)o=t[0].namespace.path;else if(t.length>1){const{groupName:e}=yield p.prompt([{type:"list",name:"groupName",message:"请选择当前项目所属分组",choices:t.map((e=>({name:e.namespace.path,value:e.namespace.path})))}]);o=e}}Ie=b("项目初始化中").start(),ue({language:n,"lint-staged":Q[n],repository:{url:i,group:o}})}))}(e,t),yield function(){return k(this,void 0,void 0,(function*(){j.spawnSync("git",["config","core.hooksPath",Ce]),s.writeFileSync(_e(".commit-msg-tpl"),"",{mode:493}),j.spawnSync("git",["config","commit.template",r.join(Ce,".commit-msg-tpl")]),s.writeFileSync(_e("commit-msg"),"#!/usr/bin/env sh\nz lint commit-msg",{mode:493}),s.writeFileSync(_e("pre-commit"),"#!/usr/bin/env sh\nz lint commit-files",{mode:493}),s.writeFileSync(_e(".prettierrc.json"),G,{mode:493}),s.writeFileSync(_e(".prettierignore"),H,{mode:493}),s.writeFileSync(_e(".gitignore"),".commit-msg-tpl\n",{mode:493})}))}(),null==Ie||Ie.succeed("初始化完成。")}))}function Le(e){return k(this,void 0,void 0,(function*(){if(!e)return"不能为空";if(!/^[a-z0-9-]+$/.test(e))return"格式为小写字母、中横线(可选)、数字(不推荐)。如apple, apple-tree";if(D().includes(e))return"当前目录下已存在同名文件夹,请先处理。";return!(yield ze(e)).find((t=>t.name===e))||"远程仓库中已存在同名项目"}))}function Pe(e){return!!e||"不能为空"}function Ae(e){return e?!!/^[a-zA-Z0-9]+$/.test(e)||"格式为大小写字母、数字,小驼峰命名。如userInfo、systemRouter3":"不能为空"}function Ue(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"}}return!0}function Be(){return k(this,void 0,void 0,(function*(){var e,o,a,c,l,u;try{const d={},m=()=>k(this,void 0,void 0,(function*(){const e=D(),{projects:t}=yield be({url:Se("src/data/template-projects.json")}),i=t.map((t=>{const i={name:`${t.name} [${t.desc}]`,value:t.name,short:t.name,disabled:!1};return e.includes(t.name)&&(i.disabled="目录下已存在同名文件夹"),i})),{project:n}=yield p.prompt([{type:"list",name:"project",message:"请选择一个项目模板",choices:i}]),o=t.find((e=>e.name===n));d.tplName=o.name,d.tplUrl=o.url})),f=()=>k(this,void 0,void 0,(function*(){var e;const{groups:t}=function(){const e=r.join(T(),"fe-groups.json");return s.existsSync(e)?n.readJSONSync(e):{groups:[]}}(),{group:i}=yield p.prompt([{type:"list",name:"group",message:"请选择一个分组",choices:t.map((e=>({name:`${e.name} [${e.description}]`,value:e.id,short:e.name})))}]);d.group={id:i,name:null===(e=t.find((e=>e.id===i)))||void 0===e?void 0:e.name}})),g=()=>k(this,void 0,void 0,(function*(){const{name:e}=yield p.prompt([{type:"input",name:"name",message:"请输入项目名称",validate:Le}]);d.projectName=e;const{desc:t}=yield p.prompt([{type:"input",name:"desc",message:"请输入项目描述",validate:Pe}]);d.projectDesc=t}));yield m(),yield f(),yield g();const h=`${ne}/${null===(e=d.group)||void 0===e?void 0:e.name}/${d.projectName}.git`,y=b("模版初始化中").start();yield I(`git clone --depth=1 ${d.tplUrl}`),i.mv(d.tplName,d.projectName),i.cd(d.projectName),i.rm("-rf",".git"),yield I("git init --initial-branch=master"),yield I(`git remote add origin ${h}`),yield I(`git config user.name ${F("gitName")}`),yield I(`git config user.email ${F("gitEmail")}`),u=Object.assign(Object.assign({},ce()),{name:d.projectName,description:d.projectDesc}),re=re?Object.assign(Object.assign({},re),u):u,n.writeJSONSync(r.resolve("package.json"),re,{spaces:2}),yield n.writeFile(r.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> 查看更多关于 [platform](https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/nttvbeif4a62gtpz#faWqt) 和 [environment](https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/nttvbeif4a62gtpz#faWqt)\n\n### 打包代码\n\`\`\`bash\n npm run build:{environment}:{platform}\n\`\`\`\n\n### 格式化、修复代码语法\n\`\`\`bash\n z lint prettier\n\`\`\`\n\n> [ESLint相关规范](https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/ul914hdkqz8fr02g#AkvQ4)\n\n### 格式化文档\n\`\`\`bash\n z lint prettier\n\`\`\`\n\n> [Prettier相关规范](https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/ul914hdkqz8fr02g#ojpwI)\n\n## 常见问题\n列出开发中常见的问题和解决方案\n\n## 了解更多\n在此处放入语雀文档链接。请在[前端团队-项目手册](https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/bfrcicwzosoyaifg)中按照分类新建文档。\n`}(d.projectName,d.projectDesc)),y.succeed("模版初始化完成"),yield Je("JavaScript",null===(o=d.group)||void 0===o?void 0:o.name);const v=b("依赖安装中").start();yield I("npm install"),v.succeed("依赖安装完成");const j=b("项目推送中").start();yield I('git add . && git commit -m "chore: init"');const $=yield(l={name:d.projectName,description:d.projectDesc,path:d.projectName,visibility:"private",namespace_id:null===(a=d.group)||void 0===a?void 0:a.id},be({url:`${ke()}/projects`,method:"post",data:l}));yield I("git push -u origin master"),j.succeed(`项目已推送到远程,地址: ${t.blue(h)}`);const w=b("初始化分支中").start(),S=`feat_init_${J()}`,x=U(null===(c=d.group)||void 0===c?void 0:c.name)?[...ee,S]:[S],z=yield Promise.allSettled(x.map((e=>function(e){return be({url:`${ke()}/projects/${e.id}/repository/branches`,method:"post",data:e})}({id:$.id,branch:e,ref:"master"})))),O=[];z.forEach((({status:e},t)=>{"fulfilled"===e&&O.push(x[t])})),yield I("git fetch origin"),O.includes(S)?(yield I(`git checkout -b ${S} origin/${S}`),w.succeed(`项目已切换到初始分支: ${t.blue(S)}`)):w.warn("开发分支检出失败!项目当前在主分支,请自行检出开发分支。");const N=`cd ${d.projectName} && z start`;console.log(`输入 ${t.green(N)} 开始开发吧~`)}catch(e){E(e)}}))}function We(e){return 0!==e.length||"请选择项"}function Re(){return k(this,void 0,void 0,(function*(){const{type:e}=yield p.prompt({type:"list",name:"type",message:"请选择你要创建的模板类型",choices:[{name:"feat - 业务需求开发",value:"feat"},{name:"fix - bug修复",value:"fix"},{name:"refactor - 技术内部需求",value:"refactor"},{name:"chore - 其他",value:"chore"}]});if(["feat","refactor"].includes(e)){const e=yield function(){return k(this,void 0,void 0,(function*(){const e=yield $e({url:Ne("/my-work-task.json?tid=mrrferp8"),method:"get"});return null==e?void 0:e.tasks.map((({id:e,name:t})=>({value:{name:t,value:e},name:t})))}))}(),{tasks:t}=yield p.prompt({type:"checkbox",name:"tasks",message:"请关联开发任务(可多选):",validate:We,choices:e.map((e=>Object.assign(Object.assign({},e),{name:`[${e.value.value}]: ${e.name}`})))});Ke("feat",t)}else if("fix"===e){const e=yield function(){return k(this,void 0,void 0,(function*(){const e=yield $e({url:Ne("/my-work-bug.json?tid=mrrferp8"),method:"get"});return null==e?void 0:e.bugs.map((({id:e,title:t})=>({name:t,value:{name:t,value:e}})))}))}(),{bugs:t}=yield p.prompt({type:"checkbox",name:"bugs",message:"请关联Bug(可多选):",validate:We,choices:e.map((e=>Object.assign(Object.assign({},e),{name:`[${e.value.value}]: ${e.name}`})))});Ke("fix",t)}else if("chore"===e){const{msg:e}=yield p.prompt({type:"input",name:"msg",message:"请输入commit msg:",validate:e=>0!==e.length||"请输入commit msg"});Ke("chore",[e])}}))}function Ke(e,i){let n="";if(["feat","refactor","fix"].includes(e)){n=`${e}(${i.map((e=>e.value)).join(",")}): ${i.map((e=>e.name)).join(";")}`}"chore"===e&&(n=`${e}: ${i[0]}`),s.writeFileSync(r.resolve(".z",".commit-msg-tpl"),n,"utf-8"),console.log(t.yellow(n)),N("commit msg模板写入成功,可以进行提交了")}function Fe(){return k(this,void 0,void 0,(function*(){const e=T(),t=r.join(e,oe.PROJECT_NAME);s.existsSync(t)?yield I("git fetch origin"):(i.cd(e),yield I(`git clone ${oe.GIT_URL} --depth=1`));const n=r.join(t,"src","pages");s.existsSync(n)||E("模板库不存在!");const o=s.readdirSync(n),{tplName:a}=yield p.prompt([{name:"tplName",type:"list",message:"请选择页面模板",choices:o.map((e=>({name:e,value:e})))}]);console.log(a),s.mkdirSync(r.resolve("src","pages"),{recursive:!0});const{dirName:c}=yield p.prompt([{name:"dirName",type:"input",message:"请输入页面目录名称(已存在则跳过创建)",validate:Ue}]);s.mkdirSync(r.resolve("src","pages",c),{recursive:!0});const l=function(e=process.cwd()){if(q(e))return s.readdirSync(e).filter((t=>!q(r.resolve(e,t))));return[]}(r.resolve("src","pages",c)),{pageName:u}=yield p.prompt([{name:"pageName",type:"input",message:"请输入页面名称",validate:e=>function(e,t){return e?/^[a-z][a-z0-9\-]+$/.test(e)?!t.includes(e)||"页面已存在":"支持小写字母、数字,连字符(-)命名,小写字母开头。如user、modules-3":"页面名称不能为空"}(e,l)}]);console.log(u)}))}function Me(e,t){return k(this,void 0,void 0,(function*(){const i=function(e){const{pathname:t}=new URL(e),i=t.match(/\/(.+)\.git/);if(i)return i[1];E("GitLab URL有误")}(e),{originBranch:n,environment:o,platform:s,notify:r,processId:a}=t;var c;yield(c={params:{command:"build",params:JSON.stringify({originBranch:n,environment:o,platform:s,profile:{weWorkName:F("weWorkName"),weWorkUserId:F("weWorkUserId")}}),options:JSON.stringify({processId:a,notify:r||[]})},jobName:i},ye({url:`${V("jenkinsDomain")}/job/${c.jobName}/buildWithParameters`,method:"post",dataKey:"params",data:c.params,auth:{username:V("jenkinsUsername"),password:V("jenkinsPassword")}}))}))}function Ve(e){return k(this,void 0,void 0,(function*(){try{const{originBranch:t,environment:i,platform:n,notify:o,processId:s}=e,r=le();!function(e,t){var i,n,o,s,r;const a=ce(),c=le();(null===(i=null==c?void 0:c.repository)||void 0===i?void 0:i.url)||E("项目package.json文件中缺少repository.url");const l=`build:${e}:${t}`;(null==a?void 0:a.scripts[l])||E(`项目package.json文件scripts不存在命令${l}。`),["alipay","weapp"].includes(t)&&(a.mini||E("请在package.json配置mini字段"),"alipay"===t&&((null===(o=null===(n=a.mini)||void 0===n?void 0:n.alipay)||void 0===o?void 0:o.appid)||E("请在package.json配置mini.alipay.appid字段")),"weapp"===t&&((null===(r=null===(s=a.mini)||void 0===s?void 0:s.weapp)||void 0===r?void 0:r.appid)||E("请在package.json配置mini.weapp.appid字段")))}(i,n),yield I("git fetch origin"),yield function(e,t){return k(this,void 0,void 0,(function*(){const i=le(),n=yield I(`git remote show ${i.repository.url}`),[,o]=n.match(/HEAD branch: (.+)\n/),s=yield I(`git log -b origin/${o} -1 --format=%H`),r=`origin/${e}`;if((yield I(`git branch --contains ${s} -r ${r}`))||E(`请先将最新的主分支(${o})代码合并到${r},再进行部署。`),"production"!==t)return;const a=yield I(`git log -b origin/${e} -1 --format=%H`),c=(yield I(`git log ${s}...${a} -b ${r}`)).split("\n");c.length||E(`分支${e}上没有要发布的commit`);const l=yield I("git log -b origin/test -1 --format=%H");(function(e,t){for(let i of t)if(!e.includes(i))return!1;return!0})((yield I(`git log ${s}...${l} -b origin/test`)).split("\n"),c)||E("请先在测试环境发布要部署的代码")}))}(t,i),yield Me(r.repository.url,{originBranch:t,environment:i,platform:n,notify:o,processId:s})}catch(e){E(e)}}))}function Ge(){if(s.existsSync(r.resolve(".z","project.json"))){const e=n.readJsonSync(r.resolve(".z","project.json"));if(e["lint-staged"])return e["lint-staged"];throw new Error("未找到lint配置")}throw new Error("请先初始化项目(z i .)。")}e.command("init").alias("i").argument("[type]","非必填。可选值:.。不传为初始化工具配置;传 . 为初始化当前项目。").description("初始化工具配置、项目配置").action((function(e){return k(this,void 0,void 0,(function*(){e?"."===e?(P(),yield Je(void 0,void 0)):E("参数错误。执行 z init -h 查看帮助。"):yield Te()}))})),e.command("create").alias("c").argument("[type]","可选值为project|p, branch|b, commit-msg|cm。传 p 为创建项目;传 b 为创建分支;传 cm 为创建提交信息").description("创建项目/分支/提交信息").action((function(e){return k(this,void 0,void 0,(function*(){let t;if(e)["project","pr"].includes(e)?t="project":["branch","b"].includes(e)?t="branch":["page","pa"].includes(e)?t="page":["commit-msg","cm"].includes(e)?t="commit-msg":E("参数输入错误");else{t=(yield p.prompt({type:"list",name:"type",message:"请选择你要创建的类型",choices:[{name:"提交信息",value:"commit-msg"},{name:"分支",value:"branch"},{name:"页面",value:"page"},{name:"项目",value:"project"}]})).type}"project"===t?yield Be():"branch"===t?(L(),P(),yield A(),yield function(){return k(this,void 0,void 0,(function*(){const{type:e,purpose:t}=yield p.prompt([{name:"type",type:"list",message:"请选择创建分支的类型",choices:[{name:"开发新功能(feat)",value:"feat"},{name:"修复BUG(fix)",value:"fix"},{name:"重构/优化代码(refactor)",value:"refactor"}]},{name:"purpose",type:"input",message:"请输入创建分支的目的(大小写字母、数字,小驼峰式命名。如userInfo)",validate:Ae}]),i=`${e}_${t}_${J()}`,n=le(),o=yield I(`git remote show ${n.repository.url}`),[,s]=o.match(/HEAD branch: (.+)\n/);yield I("git fetch origin"),yield I(`git checkout -b ${i} origin/${s}`)}))}()):"commit-msg"===t?(L(),P(),yield Re()):"page"===t&&(L(),P(),yield Fe())}))})),e.command("merge").alias("m").description("合并当前分支到指定远程分支,并部署。").action((function(){return k(this,void 0,void 0,(function*(){var e;L(),P(),yield A();const i=yield me(),n=yield Oe(i.id),o=[...ee],s=U(i.group),r=n.filter((e=>s?![...X,i.sourceBranch].includes(e.name):![i.sourceBranch].includes(e.name))).map((e=>{let i=e.name;return s&&o.includes(i)&&(i=t.bold.blue(i)),{name:i,value:e.name}})),{target:a}=yield p.prompt([{type:"list",name:"target",message:"请选择要合并到的目标分支:",choices:r}]),l=o.includes(a);let u="h5",d=[];if(l){const e=yield he(),t=yield p.prompt([{type:"list",name:"platform",message:"请选择平台",choices:[{name:"网页 - h5",value:"h5"},{name:"支付宝小程序 - alipay",value:"alipay"},{name:"微信小程序 - weapp",value:"weapp"}]},{type:"search-checkbox",name:"notify",message:"请选择部署成功要通知的人员:",choices:e,validate:e=>!(e.length<1)||"至少选一个"}]);ge(d,e),u=t.platform,d=t.notify}yield I("git fetch origin"),yield I(`git push -u origin ${i.sourceBranch}`);let m=0;try{const{iid:e}=yield(f={title:"MR by z-develop",id:i.id,source_branch:i.sourceBranch,target_branch:a,remove_source_branch:!s&&X.includes(a)},be({url:`${ke()}/projects/${f.id}/merge_requests`,method:"post",data:f}));m=e}catch(t){if(c.isAxiosError(t)){409===(null===(e=null==t?void 0:t.response)||void 0===e?void 0:e.status)&&E(`存在重复的合并请求,前往查看${i.mergeRequestUrl}`)}E(t)}var f;const g=()=>k(this,void 0,void 0,(function*(){var e;try{yield new Promise((e=>{setTimeout(e,5e3)})),yield function(e){return be({url:`${ke()}/projects/${e.id}/merge_requests/${e.iid}/merge`,method:"put"})}({id:i.id,iid:m})}catch(t){if(c.isAxiosError(t)){406===(null===(e=null==t?void 0:t.response)||void 0===e?void 0:e.status)?yield g():(yield function(e){return be({url:`${ke()}/projects/${e.id}/merge_requests/${e.iid}`,method:"put",data:e})}({id:i.id,iid:m,state_event:"close"}),E("合并过程中出现冲突,MR已关闭。建议在本地完成合并。"))}else E(t)}}));yield g(),l&&(yield Ve({originBranch:a,environment:a,platform:u,notify:d,processId:""}))}))})),e.command("deploy").alias("d").description("发布指定远程分支").action((function(){return k(this,void 0,void 0,(function*(){const e=yield he(),{environment:t,platform:i,notify:n}=yield p.prompt([{type:"list",name:"environment",message:"请选择部署环境",choices:Z},{type:"list",name:"platform",message:"请选择平台",choices:Y},{type:"search-checkbox",name:"notify",message:"请选择部署成功要通知的人员:",choices:e,validate:e=>!(e.length<1)||"至少选一个"}]);ge(n,e);let o=t,s="";if("production"===t){const e=yield me(),t=(yield Oe(e.id)).filter((e=>![...X,...ee].includes(e.name))).map((e=>({name:e.name,value:e.name}))),n=yield p.prompt([{type:"list",name:"branchName",message:"请输入要部署的分支:",choices:t},{type:"input",name:"processId",message:"请输入本次部署的企微审批编号"}]);o=n.branchName,s=n.processId,function(e){const t=e.split("_");if(4!==t.length)return!1;const[i,n,o]=t;return!!te.includes(i)&&!0===Ae(n)&&8===o.length&&!isNaN(Number(o))}(o)||E("分支命名不符合规范,参见https://zhongshitech.yuque.com/nx4ugr/guide/mg8t44#bQhu4");const{data:{state:a,content:c}}=yield(r={businessId:s},we({url:"/approval/findByBusinessId",data:r}));1===a&&E("当前审批流程状态为审批中,审批通过才能进行发布。"),3===a&&E("当前审批流程状态为已驳回,请重新提交审批。"),4===a&&E("当前审批流程状态为已发布,如需再次发布,请重新提交审批。");const{formComponentValues:l}=JSON.parse(c),u={};l.forEach((e=>{u[e.name]=e.value})),u["申请人"]!==F("weWorkName")&&E("发布审批申请人与当前发布人不一致!"),u["项目名称"]!==ce().name&&E("发布审批项目名称与当前发布项目名称不一致!"),u["发布分支"]!==o&&E("发布审批发布分支与当前发布分支不一致!"),u["发布平台"]!==i&&E("发布审批发布平台与当前发布平台不一致!")}var r;yield Ve({originBranch:o,environment:t,platform:i,notify:n,processId:s})}))})),e.command("start").alias("s").description("启动本地开发环境").action((function(){return k(this,void 0,void 0,(function*(){const e=ce(),{environment:t}=yield p.prompt([{type:"list",name:"environment",message:"请选择环境",choices:Z}]),n=`dev:${t}`;if(e.scripts[n])try{i.exec(`npm run ${n}`,{silent:!1})}catch(e){E(e)}else E(`项目中(package.josn > scripts)不存在命令${n},请先添加!`)}))})),e.command("lint").alias("l").argument("[type]","非必填。可选值为commit-msg|cm, commit-files|cf, prettier|p, eslint|e。传 cm 为执行 lint commit-msg;传 cf 为执行 lint commit-files;传 p 为全部文件执行prettier;传 e 为全部文件执行eslint。cm 和 cf属于内部命令,会在git hooks中自动执行。").description("执行 lint 脚本。包含 lint staged 、 lint commit message、 prettier、 eslint。").action((function(e){return k(this,void 0,void 0,(function*(){let t;if(L(),P(),e)["commit-msg","cm"].includes(e)?t="commit-msg":["commit-files","cf"].includes(e)?t="commit-files":["prettier","p"].includes(e)?t="prettier":["eslint","e"].includes(e)?t="eslint":E("参数输入错误");else{t=(yield p.prompt({type:"list",name:"type",message:"请选择你要执行的操作",choices:[{name:"全局执行 prettier",value:"prettier"},{name:"全局执行 eslint",value:"eslint"}]})).type}if("commit-msg"===t)yield function(){return k(this,void 0,void 0,(function*(){const e=function(e){const t=s.readFileSync(r.resolve(".git","COMMIT_EDITMSG"),"utf-8").split(": ");if(1===t.length)return"body前缺少「:」";{const e=t[0];return/^(feat|fix|refactor)/.test(e)?!!/\(\d+(?:,\d+)*\)/.test(e)||"ID缺少或者格式不正确。":/^chore/.test(e)?"chore"===e||"chore类型无需填写ID。":"不存在的提交类型。"}}();!0===e?N("commit msg validate success."):E(`commit msg格式错误。${e}`)}))}();else if("commit-files"===t)yield function(){return k(this,void 0,void 0,(function*(){(yield $({concurrent:!1,debug:void 0,config:Ge()}))?N("代码风格检测通过!"):E("代码风格检测未通过!")}))}();else if("prettier"===t){s.existsSync(r.resolve("node_modules",".bin","prettier"))||E("该项目未安装prettier,请安装后重试");try{yield I("prettier --write . --config .z/.prettierrc.json --ignore-path .z/.prettierignore --ignore-unknown --no-error-on-unmatched-pattern",{silent:!1}),N("prettier执行成功")}catch(e){E("prettier校验出错")}}else if("eslint"===t){console.log(r.resolve("node_modules",".bin","eslint")),s.existsSync(r.resolve("node_modules",".bin","eslint"))||E("该项目未安装eslint,请安装后重试");try{yield I("eslint '**/*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}' --fix",{silent:!1}),N("eslint执行成功")}catch(e){E("eslint校验出错")}}}))})),function(){k(this,void 0,void 0,(function*(){process.on("unhandledRejection",(e=>{})),process.on("uncaughtException",(e=>{})),i.config.fatal=!0,i.config.silent=!0,i.config.verbose=!1,yield De(),p.registerPrompt("search-checkbox",qe)}))}(),e.name("z-develop").alias("z").description(`z-develop, 开发流程管理工具。\n了解更多: ${t.blue("https://zxf-fe.yuque.com/org-wiki-zxf-fe-ex4bve/qi89vg/us8lgdb5cq4kf3aa")}`).usage("<command> [options]").version(w.version,"-v, --version","当前版本号").helpOption("-h, --help","帮助").showHelpAfterError("可以使用z -h查看帮助。"),e.parse();
|