create-arco-pro
Version:
A template to quickly initialize an Arco project
10 lines • 16.7 kB
JavaScript
import*as t from"readline";import*as e from"events";import*as s from"sisteransi";import*as i from"node:fs";import*as r from"axios";import*as a from"node:zlib";import*as o from"node:path";import*as n from"node:os";import*as l from"tar";import*as h from"child_process";import*as u from"node:util";function c(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}class m{color(t=255){return this.styles.push(`\x1b[38;5;${t}m`),this}background(t=255){return this.styles.push(`\x1b[48;5;${t}m`),this}bold(){return this.styles.push("\x1b[1m"),this}underline(){return this.styles.push("\x1b[4m"),this}strikethrough(){return this.styles.push("\x1b[9m"),this}italic(){return this.styles.push("\x1b[3m"),this}red(){return this.color(196)}green(){return this.color(46)}blue(){return this.color(27)}yellow(){return this.color(226)}cyan(){return this.color(50)}gray(){return this.color(240)}toString(){return`${this.styles.join("")}${this.text}\x1b[0m`}constructor(t,e){c(this,"text",void 0),c(this,"styles",void 0),this.text=t,this.styles=[];let s=t=>{"number"==typeof t?this.color(t):"function"==typeof this[t]&&this[t].call(this)};if(Array.isArray(e))for(let t of e)s(t);else void 0!==e&&s(e)}}let p=(t,e)=>e?new m(t,e).toString():t;function d(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}let b={"ctrl+a":"first","ctrl+c":"abort","ctrl+d":"abort","ctrl+e":"last","meta+escape":"exit",return:"submit",enter:"submit",backspace:"delete",delete:"deleteForward",escape:"exit",tab:"next",pagedown:"nextPage",pageup:"prevPage",home:"home",end:"end",up:"up",down:"down",left:"left",right:"right"},v=t=>b[`${t.ctrl?"ctrl+":""}${t.meta?"meta+":""}${t.name}`]||!1;class g extends e.default{close(){this.out.write(s.cursor.show),this.in.off("keypress",this.handleKeypress),this.in.isTTY&&this.in.setRawMode(!1),this.rl.close(),this.emit(this.status,this.value)}bell(){this.out.write(s.beep)}constructor(){super(),d(this,"in",process.stdin),d(this,"out",process.stdout),d(this,"status","none"),d(this,"rl",void 0),d(this,"handleKeypress",(t,e)=>{let s=v(e);if(s)"function"==typeof this[s]?this[s](e):this.bell();else{var i;null===(i=this.input)||void 0===i||i.call(this,t)}}),this.in=process.stdin,this.out=process.stdout,this.rl=t.default.createInterface({input:this.in,escapeCodeTimeout:50}),t.default.emitKeypressEvents(this.in,this.rl),this.in.isTTY&&this.in.setRawMode(!0),this.in.on("keypress",this.handleKeypress)}}let x=t=>/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(t),f=t=>i.default.readdirSync(process.cwd()).includes(t),y=["https://fastgit.cc","https://gh.llkk.cc","https://gh-proxy.com","https://github.tbedu.top","https://gh.idayer.com","https://gh.zhaojun.im","https://ghp.keleyaa.com"],w=async()=>{try{let t=(await r.default.get("https://api.akams.cn/github")).data.data.map(t=>t.url);y=[...y,...t]}catch{}},$=async(t,e,s)=>new Promise((a,o)=>{let n=120,l=0,h=setInterval(()=>{n-=1,s.start().update(`正在生成项目 尝试时间${n}s \u{23F3}`),0===n&&u(!1)},1e3),u=(t,e)=>{clearInterval(h),t?(s.succeed(e||"初始化完成"),a()):(s.fail(e||"网络超时请稍后重试"),o())};w();let c=()=>{let e=`${y[l]}/${t}`;return(l+=1)>=y.length&&(l=0),e},m=async(t=c())=>{try{let a=await r.default.get(t,{timeout:1e4,responseType:"stream"}),o=a.status||0;if(o>=400)m(c());else if(o>=300&&a.headers.location)m(a.headers.location);else{clearInterval(h);let t=0,r=Date.now();a.data.on("data",e=>{t+=e.length;let i=Math.round((t>>10)/((Date.now()-r)/1e3));s.update(`正在下载中 ${i} KB/s \u{23F3}`)}),a.data.pipe(i.default.createWriteStream(e)).on("finish",()=>u(!0)).on("error",()=>u(!1,"初始化失败"))}}catch{m(c())}};m(t)});async function S(t,e){return new Promise((s,r)=>{let o=i.default.createReadStream(t),n=a.default.createGunzip();i.default.existsSync(e)||i.default.mkdirSync(e,{recursive:!0}),o.pipe(n).pipe((0,l.x)({cwd:e,strip:1})).on("finish",s).on("error",r)})}let k=t=>{let e=t||n.default.tmpdir(),s=o.default.join(e,".create-arco-temp");return i.default.existsSync(s)||i.default.mkdirSync(s,{recursive:!0}),{tempDir:s,cleanup:()=>{i.default.existsSync(s)&&i.default.rmSync(s,{recursive:!0,force:!0})}}},C=(t,e,s)=>new Promise((i,r)=>{let a=(0,h.spawn)(t,e,{shell:"win32"===process.platform,stdio:["ignore","ignore","ignore"],cwd:s});a.on("close",i),a.on("error",r)}),M={arrowUp:"↑",arrowDown:"↓",arrowLeft:"←",arrowRight:"→",pointer:">",ellipsis:":",tick:"✔",cross:"✖",pointerSmall:"›",..."win32"===process.platform?{tick:"√",cross:"\xd7",pointerSmall:"\xbb"}:{}},z={abort:p(M.cross,"red"),exit:p(M.cross,"yellow"),submit:p(M.tick,"green"),none:p("?","cyan")},P=t=>z[t],j=t=>p(t?M.ellipsis:M.pointerSmall,"gray");function I(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}class A extends g{moveCursor(t){this.cursor=t,this.value=this.options[t].value,this.render()}exit(){this.status="exit",this.end()}abort(){this.status="abort",this.end()}end(){this.render(),this.out.write("\n"),this.close()}submit(){this.options[this.cursor].disabled?this.bell():(this.status="submit",this.end())}first(){this.moveCursor(0)}last(){this.moveCursor(this.total-1)}up(){0===this.cursor?this.moveCursor(this.total-1):this.moveCursor(this.cursor-1)}down(){this.cursor===this.total-1?this.moveCursor(0):this.moveCursor(this.cursor+1)}next(){this.moveCursor((this.cursor+1)%this.total)}input(t){return" "===t?this.submit():this.bell()}paginate(){let t=Math.min(this.total-this.pageSize,this.cursor-Math.floor(this.pageSize/2));t<0&&(t=0);let e=Math.min(t+this.pageSize,this.total);return{startIndex:t,endIndex:e}}render(){this.out.write(s.cursor.restore+s.erase.down(this.pageSize)+s.cursor.save);let{startIndex:t,endIndex:e}=this.paginate(),i=this.options[this.cursor],r="submit"===this.status?i.label:i.disabled?p(i.warn||"","red"):p("箭头键选择,回车键确认","gray"),a=`${P(this.status)} ${p(this.msg,"bold")} ${j("submit"===this.status)} ${r}`;if("none"===this.status){a+="\n";for(let s=t;s<e;s++){let i=this.options[s],r=i.disabled?"gray":void 0,o=" ",n=p(i.label,r),l="";s===t&&t>0?o+=M.arrowUp:s===e-1&&e<this.total&&(o+=M.arrowDown),this.cursor===s&&(n=p(i.label,[r||"cyan","bold"]),o=" "+p(M.pointer,r||"cyan")),l=p(` ${i.description||""}`,"gray"),a+=`${o} ${n} ${l}
`}}this.out.write(a)}constructor(t){var e;super(),I(this,"msg",void 0),I(this,"options",void 0),I(this,"pageSize",void 0),I(this,"cursor",void 0),I(this,"total",void 0),I(this,"value",void 0),this.msg=t.message,this.pageSize=t.pageSize||10,this.options=t.options||[],this.cursor=Math.max(0,this.options.findIndex(e=>e.value===t.initial)),this.total=this.options.length,this.value=(null===(e=this.options[this.cursor])||void 0===e?void 0:e.value)||"",this.out.write(s.erase.line+s.cursor.to(0)+s.cursor.save+s.cursor.hide),this.render()}}function G(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}class K extends g{end(){this.value=this.value||this.initial,this.render(),this.out.write("\n"),this.close()}exit(){this.status="exit",this.end()}abort(){this.status="abort",this.end()}async validate(){let t=await this.validator(this.value);"string"==typeof t&&(this.errorMsg=t,t=!1),this.error=!t}async submit(){this.value=this.value||this.initial,await this.validate(),this.error?this.render():(this.status="submit",this.render(),this.out.write("\n"),this.close())}moveCursor(t){this.cursor=Math.max(0,Math.min(this.cursor+t,this.value.length)),this.render()}input(t){let e=this.value.slice(0,this.cursor),s=this.value.slice(this.cursor);this.value=this.format(`${e}${t}${s}`),this.moveCursor(1)}delete(){if(0===this.cursor)return this.bell();let t=this.value.slice(0,this.cursor-1),e=this.value.slice(this.cursor);this.value=this.format(`${t}${e}`),this.moveCursor(-1)}next(){if(!this.initial)return this.bell();this.value=this.initial,this.cursor=this.value.length,this.render()}first(){this.cursor=0,this.render()}last(){this.cursor=this.value.length,this.render()}left(){if(this.cursor<=0||!this.value)return this.bell();this.moveCursor(-1)}right(){if(this.cursor>=this.value.length)return this.bell();this.moveCursor(1)}render(){let t=this.value?this.value:p(` ${this.initial}`,"gray"),e=this.error?`
${M.pointerSmall} ${p(this.errorMsg,["red","italic"])}`:"",i=`${P(this.status)} ${p(this.message,"bold")} ${j("submit"==this.status)} ${t}`,r=this.value?this.cursor-this.value.length:-this.initial.length-1;this.out.write(s.erase.line+s.cursor.to(0)+i+s.cursor.save+e+s.cursor.restore+s.cursor.move(r,0))}constructor(t){super(),G(this,"message",void 0),G(this,"initial",void 0),G(this,"format",void 0),G(this,"validator",void 0),G(this,"value",void 0),G(this,"errorMsg",void 0),G(this,"error",void 0),G(this,"cursor",void 0),this.message=t.message,this.initial=t.initial||"",this.format=t.format||(t=>t),this.validator=t.validate||(()=>!0),this.value="",this.errorMsg=t.error||`请输入有效值`,this.error=!1,this.cursor=0,this.render()}}function O(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}class T extends g{exit(){this.status="exit",this.end()}abort(){this.status="abort",this.end()}end(){this.render(),this.out.write("\n"),this.close()}toggleValue(t){this.value=t,this.render()}right(){this.toggleValue(!1)}left(){this.toggleValue(!0)}up(){this.toggleValue(!this.value)}down(){this.toggleValue(!this.value)}submit(){this.status="submit",this.end()}input(t){return"y"===t.toLowerCase()?(this.value=!0,this.submit()):"n"===t.toLowerCase()?(this.value=!1,this.submit()):this.bell()}render(){let t=t=>p(t,["cyan","bold"]),e=this.value?`${t(this.yes)}/${this.no}`:`${this.yes}/${t(this.no)}`,i=P(this.status),r=p(this.msg,"bold"),a=j("submit"===this.status),o="submit"===this.status?this.value?this.yes:this.no:e,n=`${i} ${r} ${a} ${o}`;this.out.write(s.erase.line+s.cursor.to(0)+n)}constructor(t){super(),O(this,"msg",void 0),O(this,"value",void 0),O(this,"yes",void 0),O(this,"no",void 0),this.msg=t.message,this.value=t.initial||!0,this.yes=t.yes||"Yes",this.no=t.no||"No",this.out.write(s.cursor.hide),this.render()}}async function W(t,{onCancel:e=()=>{}}={}){let s={},i=t=>"function"==typeof t;for(let r of t){let{name:t,type:a,when:o}=r;if(!o||(i(o)?!!o(s):!!o)){i(r.options)&&(r.options=await r.options(s)),i(r.initial)&&(r.initial=await r.initial(s));try{let e=new(function(t){switch(t){case"select":return A;case"input":return K;case"confirm":return T;default:throw Error(`Unknown prompt type: ${t}`)}}(a))({...r});s[t]=await new Promise((t,s)=>{e.on("submit",t),e.on("exit",s),e.on("abort",s)})}catch{await e();break}}}return s}var R=JSON.parse('{"u2":"create-arco","i8":"0.2.8"}'),V=JSON.parse('{"react":[],"vue":[{"name":"Arco Admin","repo":"https://github.com/oljc/arco-admin","packageManager":"pnpm","branch":"main","start":"pnpm run dev"},{"name":"Gi Admin Pro","repo":"https://github.com/lin-97/gi-demo","packageManager":"npm","branch":"master","start":"npm run dev"},{"name":"Fantastic Admin","repo":"https://github.com/fantastic-admin/basic","packageManager":"pnpm","branch":"main","start":"pnpm run dev"},{"name":"Arco Work","repo":"https://github.com/qingqingxuan/arco-work","packageManager":"npm","branch":"master","start":"npm run dev"}]}');function q(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}class D{stopWithStatus(t,e){this.stop(),process.stdout.write(`\r\x1b[K${t} ${e}\x1b[?25h
`)}start(t){return t&&(this.text=t),this.stop(),this.interval=setInterval(()=>{let t=this.frames[this.frameIndex];process.stdout.write(`\r\x1b[K${t} ${this.text}`),this.frameIndex=(this.frameIndex+1)%this.frames.length},100),this}stop(){this.interval&&(clearInterval(this.interval),this.interval=null)}update(t){return this.text=t,this}succeed(t="成功!"){this.stopWithStatus(p("✔","green"),t)}fail(t="失败!"){this.stopWithStatus(p("✖","red"),t)}warn(t="警告!"){this.stopWithStatus(p("!","yellow"),t)}constructor(t="加载中..."){q(this,"text",void 0),q(this,"interval",null),q(this,"frames",["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"]),q(this,"frameIndex",0),this.text=t,process.stdout.write("\x1b[?25l")}}let F=t=>new D(t);(async function(){let{values:t,positionals:e}=(0,u.parseArgs)({args:process.argv.slice(2),options:{version:{type:"boolean",short:"v"}},strict:!1});t.version&&(console.log(`${R.u2} ${p(`v${R.i8}`,"blue")}`),process.exit(0)),console.log(`
${process.stdout.isTTY&&process.stdout.getColorDepth()>=8?"\x1b[38;5;43mW\x1b[39m\x1b[38;5;44me\x1b[39m\x1b[38;5;44ml\x1b[39m\x1b[38;5;38mc\x1b[39m\x1b[38;5;38mo\x1b[39m\x1b[38;5;38mm\x1b[39m\x1b[38;5;38me\x1b[39m\x1b[38;5;39m!\x1b[39m \x1b[38;5;33mL\x1b[39m\x1b[38;5;33me\x1b[39m\x1b[38;5;33mt\x1b[39m\x1b[38;5;33m’\x1b[39m\x1b[38;5;69ms\x1b[39m \x1b[38;5;69mB\x1b[39m\x1b[38;5;69mu\x1b[39m\x1b[38;5;69mi\x1b[39m\x1b[38;5;69ml\x1b[39m\x1b[38;5;69md\x1b[39m \x1b[38;5;69mw\x1b[39m\x1b[38;5;69mi\x1b[39m\x1b[38;5;69mt\x1b[39m\x1b[38;5;69mh\x1b[39m \x1b[38;5;69mc\x1b[39m\x1b[38;5;69mr\x1b[39m\x1b[38;5;69me\x1b[39m\x1b[38;5;69ma\x1b[39m\x1b[38;5;69mt\x1b[39m\x1b[38;5;69me\x1b[39m\x1b[38;5;69m-\x1b[39m\x1b[38;5;69ma\x1b[39m\x1b[38;5;69mr\x1b[39m\x1b[38;5;69mc\x1b[39m\x1b[38;5;69mo\x1b[39m\x1b[38;5;75m!\x1b[39m":p("Welcome! Let’s Build with create-arco!","blue")}
`);let s=await Promise.all(["pnpm","yarn","npm"].map(async t=>{try{return await C(t,["--version"]),t}catch{return null}})).then(t=>t.filter(Boolean)),i={};try{i=await W([{name:"projectName",type:"input",message:"请输入项目名称",initial:e[0]||"hello-arco-pro",format:t=>t.trim(),validate:t=>x(t)?!f(t)||"当前目录下存在同名项目":"请输入合法的项目名"},{name:"techStack",type:"select",message:"请选择你希望使用的技术栈",options:[{label:"Vue",value:"vue"},{label:"React",value:"react"}]},{name:"version",type:"select",message:"请选择版本",options:t=>[{label:"基础版",value:"basic"},{label:"完整版",value:"full"},{label:"开源项目",value:"community",disabled:V[t.techStack].length<=0,warn:"暂无社区开源项目",description:"来自社区的优秀活跃开源项目"}]},{name:"community",type:"select",message:"请选择社区开源模板",when:t=>"community"===t.version,options:t=>V[t.techStack].map(t=>({label:t.name,value:t}))},{name:"manager",type:"select",message:"请选择包管理器",options:t=>{var e;let i=(null===(e=t.community)||void 0===e?void 0:e.packageManager)||"pnpm";return s.map(t=>({label:t,value:t,description:t===i?"推荐":null}))}},{name:"initGit",type:"confirm",message:"是否初始化Git",initial:!0},{name:"confirm",type:"confirm",message:"确认生成项目吗",initial:!0}],{onCancel:()=>{console.log(p("✖","red")+" 取消创建项目"),process.exit(0)}})}catch{process.exit(1)}i.confirm||(console.log(p("✖","red")+" 取消创建项目"),process.exit(0));let{projectName:r,techStack:a,version:o,community:n,manager:l,initGit:h}=i,{tempDir:c,cleanup:m}=k(),d="community"===o&&n?`${n.repo}/archive/refs/heads/${n.branch}.tar.gz`:`https://github.com/RenderUI/${a}-${o}/archive/refs/heads/main.tar.gz`,b=`${c}/${r}.tar.gz`,v=`${process.cwd()}/${r}`,g=F();if(await $(d,b,g),await S(b,v),m(),h){g.start("初始化 Git");try{await C("git",["init","--quiet"],v),g.update("Git 初始化成功")}catch{g.fail("Git 初始化失败, 请自行初始化")}}let y=async()=>{g.start("安装项目依赖中");let t=!1;for(let e of[["install","--quiet","--silent"],["install","--quiet","--silent","--registry","https://registry.npmmirror.com"]])try{await C(l,e,v),g.succeed("项目依赖安装成功"),t=!0;break}catch{continue}if(!t){g.fail("项目依赖安装失败");let{install:t}=await W([{name:"install",type:"select",message:"依赖安装失败,是否继续尝试?",options:[{label:"再次尝试",value:"retry"},{label:"跳过",value:"skip"}]}]);"retry"===t?(process.stdout.write("\x1b[2A\x1b[K"),await y()):g.warn("已选择跳过,请自行安装依赖")}};await y(),console.log(`
\u{1F389}快速开始:`),console.log(` - ${p(`cd ${r}`,192)}`);let w=((null==n?void 0:n.start)||`${l} run dev`).replace(/\b(pnpm|yarn|npm)\b/,l);console.log(` - ${p(w,192)}`),"community"===o&&n&&console.log(p(`
当前模板文档:${p(n.repo,"underline")}`,"blue")),console.log(p(`
GitHub: ${p("https://github.com/oljc/create-arco","underline")}`,"blue")),console.log(p("感谢您的使用!如有反馈或需要支持,欢迎访问项目仓库并给予Star!\n","blue")),process.exit(0)})().catch(t=>{t&&console.error("错误信息",t),process.exit(1)});