UNPKG

@dovenv/repo

Version:

Repository tools for any runtime

47 lines (39 loc) 34.3 kB
import{joinPath as x,getPackageRepoUrlFromContent as X,existsLocalBin as O,isGitHubAuthenticated as Q,execChild as y,catchExecOutput as Z,exec as R,existsDir as L,catchError as A,getPaths as tt,relativePath as st,getDirTree as et,box as it,getFilteredFileNames as ot,joinUrl as at,LazyLoader as rt,deprecatedAlerts as nt,getObjectFromFile as lt,getPackageVersion as ct,color as ut,downloadGitHubPath as pt,getMatch as ht,md2html as dt,md2terminal as gt}from"@dovenv/core/utils";import wt from"husky";import{exec as mt}from"node:child_process";import{defineConfig as yt}from"@dovenv/core";const ft="https://dovenv.pigeonposse.com/guide/plugin/repo";class S{utils;opts;constructor({opts:t,utils:s}){this.opts=t,this.utils=s,this.utils.helpURL=ft,this.utils.title="repo",this.onInit()}onInit(){this.opts||(this.opts={}),!this.opts?.homepageURL&&this.utils.pkg?.homepage&&(this.opts.homepageURL=this.utils.pkg.homepage),!this.opts?.tags&&this.utils.pkg?.keywords&&(this.opts.tags=this.utils.pkg.keywords),!this.opts?.desc&&this.utils.pkg?.description&&(this.opts.desc=this.utils.pkg.description),!this.opts?.workflowsDir&&this.utils.wsDir&&(this.opts.workflowsDir=x(this.utils.wsDir,".github","workflows")),this.opts?.defaultBranch||(this.opts.defaultBranch="main"),!this.opts?.URL&&this.utils.pkg&&(this.opts.URL=X(this.utils.pkg)),!this.opts?.ID&&this.utils.pkg?.extra&&this.utils.pkg.extra.repoID&&(this.opts.ID=this.utils.pkg.extra.repoID),!this.opts?.ID&&this.utils.pkg?.extra&&this.utils.pkg.extra.repoId&&(this.opts.ID=this.utils.pkg.extra.repoId),!this.opts?.userID&&this.utils.pkg?.extra&&this.utils.pkg.extra.userID&&(this.opts.userID=this.utils.pkg.extra.userID),!this.opts?.URL&&this.opts?.ID&&this.opts?.userID&&(this.opts.URL=`https://github.com/${this.opts.userID}/${this.opts.ID}`),!this.opts?.ID&&this.opts.URL&&(this.opts.ID=this.opts.URL.split("/").pop()),!this.opts?.userID&&this.opts.URL&&(this.opts.userID=this.opts.URL.split("/").slice(-2,-1)[0])}async _existsLocalGit(){return await O("git")}async initGH(){if(!await O("gh")){console.warn("You must install gh binary for use `gh` commands. See: https://cli.github.com/");return}if(!await Q()){console.warn("You must login to GitHub for use gh commands. Use `gh auth login`.See: https://cli.github.com/manual/gh_auth_login");return}}async init(){if(!await this._existsLocalGit()){console.warn(`Git is not installed or not detected. Git is required to run this command. Please Install git and try again`);return}}}class $ extends S{async getGitRemoteURL(){return this.opts?.URL||(await y("git remote get-url origin")).stdout||void 0}}class D extends ${async ask(t="."){const s=await this.utils.prompt.text({message:"What paths do you want to add?",placeholder:".",initialValue:t});return this.utils.prompt.isCancel(s)&&await this.utils.onCancel(),s}async exec(t){const s=`git add ${t}`,[e,o]=await Z(`git add ${t}`);e?console.error(this.utils.style.error.msg(e.message)):o&&o!==""&&(console.log(this.utils.style.info.hr(s)),console.log(this.utils.style.success.p(o)),console.log(this.utils.style.info.hr()))}async run(){await this.init();const t=await this.ask();this.exec(t)}}class E extends ${async askSelectBranch(t,s=!0){const e=await this.getAll(s),o=await this.utils.prompt.select({message:"Select branch of the repository",options:e.map(i=>({value:i,label:i})),initialValue:t&&e.includes(t)?t:void 0});if(this.utils.prompt.isCancel(o))await this.utils.onCancel();else if(!o||typeof o!="string")throw new Error("Unexpected error: No branch selected");return o}async#t(){const t=await this.utils.prompt.text({message:"Set new branch name"});if(this.utils.prompt.isCancel(t))await this.utils.onCancel();else if(!t||typeof t!="string")throw new Error("Unexpected error: No branch selected");return t}async getCurrent(){const{stdout:t}=await y("git branch --show-current");return t}async showCurrent(){const t=await this.getCurrent();this.utils.prompt.note(this.utils.style.info.lk(t),"Current branch"),this.utils.prompt.log.step("")}async getAll(t=!0){const s=t?"git branch -a":"git branch",{stdout:e}=await y(s);return e.split(` `).map(o=>o.replace(/[*\s]/g,"").trim()).filter(o=>o.length>0)}async showAll(t=!0){const s=(await this.getAll(t)).map(e=>this.utils.style.info.lk(e)).join(` `);this.utils.prompt.note(s,"All branches"),this.utils.prompt.log.step("")}async change(t,s=!1){const e=t||await this.askSelectBranch(),o=s?`git checkout -f ${e}`:`git checkout ${e}`,{stdout:i,stderr:r}=await y(o);if(r)throw new Error(`Error changing branch: ${r}`);this.utils.prompt.log.success(`Switched to branch: ${i.trim()}`)}async switch(t){const s=t||await this.askSelectBranch(),{stderr:e}=await y(`git switch ${s}`);if(e)throw new Error(`Error switching to branch: ${e}`);this.utils.prompt.log.success(`Switched to branch: ${s}`)}async create(t){const s=t||await this.#t(),{stderr:e}=await y(`git branch ${s}`);if(e)throw new Error(`Error creating branch: ${e}`);this.utils.prompt.log.success(`Created branch: ${s}`)}async createAndSwitch(t){const s=t||await this.#t(),{stderr:e}=await y(`git checkout -b ${s}`);if(e)throw new Error(`Error creating and switching to branch: ${e}`);this.utils.prompt.log.success(`Created and switched to branch: ${s}`)}async delete(t,s=!1){const e=t||await this.askSelectBranch(),o=s?`git branch -D ${e}`:`git branch -d ${e}`,{stderr:i}=await y(o);if(i)throw new Error(`Error deleting branch: ${i}`);this.utils.prompt.log.success(`Deleted branch: ${e}`)}}class U extends ${types=[{value:":sparkles: feat",title:"\u2728 feat",desc:"Adding a new feature"},{value:":bug: fix",title:"\u{1F41B} fix",desc:"Fixing a bug"},{value:":memo: docs",title:"\u{1F4DD} docs",desc:"Add or update documentation"},{value:":lipstick: style",title:"\u{1F484} style",desc:"Add or update styles, UI, or UX"},{value:":recycle: refactor",title:"\u267B\uFE0F refactor",desc:"Code change that neither fixes a bug nor adds a feature"},{value:":zap: perf",title:"\u26A1\uFE0F perf",desc:"Code change that improves performance"},{value:":white_check_mark: test",title:"\u2705 test",desc:"Adding test cases"},{value:":truck: chore",title:"\u{1F69A} chore",desc:"Changes to the build process or auxiliary tools and libraries (e.g., documentation generation)"},{value:":rewind: revert",title:"\u23EA\uFE0F revert",desc:"Revert to a previous commit"},{value:":construction: wip",title:"\u{1F6A7} wip",desc:"Work in progress"},{value:":construction_worker: build",title:"\u{1F477} build",desc:"Add or update related to build process"},{value:":green_heart: ci",title:"\u{1F49A} ci",desc:"Add or update related to CI process"}];scopes=[{value:"core",desc:"Core functionality of the application"},{value:"env",desc:"Reference for workspace environment"},{value:"all",desc:"Reference all changes affecting multiple scopes"}];async getStagedFiles(){const{stdout:t}=await y("git status --short");return t.trim().split(` `).map(s=>s.trim()).join(` `)}async getStagedFilesList(){return(await this.getStagedFiles()).split(` `)}async getLastCommit(){const{stdout:t}=await y("git log -1 --pretty=%B");return t.trim()}async isStageEmpty(){const{stdout:t}=await y("git diff --cached");return t===""}async exec(t){const s=`git commit -m "${t}"`;console.log(this.utils.style.info.hr("git commit")),await R(s),console.log(this.utils.style.info.hr())}async ask(t=!0){const s=this.opts?.commit?.types||this.types,e=this.opts?.commit?.scopes||this.scopes,o={type:"type",scope:"scope",msg:"message"},i={[o.type]:void 0,[o.scope]:void 0,[o.msg]:""},r=await this.utils.cache("commit",i),l=await r.get(),n=await this.utils.promptGroup({onCancel:async()=>this.utils.onCancel(),list:async a=>{const g={[o.type]:async()=>{const c=s?await a.select({message:"Select type of commit",options:s.map(u=>({value:u.value,label:u.title||u.value,hint:u.desc})),initialValue:s.some(u=>u.value===l[o.type])?l[o.type]:void 0}):void 0;return await r.set({[o.type]:c}),c},[o.scope]:async()=>{const c=e?await a.select({message:"Select scope of commit",options:e.map(u=>({value:u.value,label:u.title||u.value,hint:u.desc})),initialValue:e.some(u=>u.value===l[o.scope])?l[o.scope]:void 0}):void 0;return await r.set({[o.scope]:c}),c},[o.msg]:async()=>{const c=await a.text({message:"Commit message",placeholder:await r.get(o.msg),validate:u=>{if(!u.trim())return"Commit message is required"}});return await r.set({[o.msg]:c}),c}};return{desc:()=>a.log.info(this.utils.style.p("Prompt for commit message")),...g,commit:async({results:c})=>{const u=c.message,d=c.scope,h=c.type,b=()=>{if(u)return!d&&!h?u:d?h?`${h}(${d}): ${u}`:`${d}: ${u}`:`${h}: ${u}`};try{const w=b();if(!w){console.warn("Unexpected: Commit message is not defined");return}return a.log.info(this.utils.style.info.msg("Total message",w)),t&&await this.exec(w),w}catch(w){w instanceof Error?a.log.error(w.message):console.error(w),await this.utils.onCancel()}}}}});return console.debug({"commit-results":n}),n.commit}async run(){if(await this.init(),!await this.isStageEmpty())return await this.ask();console.warn(`Nothing to commit. Stage your changes executing: ${this.utils.style.badge("dovenv git push")} Or stage your changes manually using ${this.utils.style.badge("git add")} and executing again: ${this.utils.style.badge("dovenv git commit")}`)}}class V extends ${async#t(t){const s=x(t,"_"),e=await L(s);if(console.debug({path:t,exist:e}),e)return!0;await this.init();const o=await wt(t);if(o)throw new Error(o);return!1}async run(){const t=this.opts?.husky?.path??x(this.utils.wsDir,".dovenv/husky"),[s,e]=await A((async()=>this.#t(t))());if(s)return console.log(this.utils.style.error.msg(s.message));console.log(e?this.utils.style.success.msg("Husky exists in:",t):this.utils.style.success.msg("Husky folder is now in",t)),console.log(this.utils.style.success.p(` Add now you Git hooks! More info: ${this.utils.style.a("https://typicode.github.io/husky")}`))}}class j extends ${async isInit(){return await L(x(this.utils.wsDir,".git"))}async#t(){const t=this.utils.pkg?.extra.repoId||this.utils.pkg?.repoID||this.utils.pkg?.name,s=this.utils.pkg?.extra.collective.id,e=t&&s?`https://github.com/${s}/${t}.git`:this.utils.pkg?.reppsitory.url;if(!e)throw new Error("Invalid repository url: "+e);const o=await this.utils.prompt.text({message:"Write your origin git url",placeholder:e,initialValue:e});return this.utils.prompt.isCancel(o)&&await this.utils.onCancel(),o}async#s(){const t=await this.utils.prompt.confirm({message:"Do you want to execute the command?"});return this.utils.prompt.isCancel(t)&&await this.utils.onCancel(),t}async#e(){const t="main",s=await this.utils.prompt.text({message:"Write your init branch",placeholder:t,initialValue:t});return this.utils.prompt.isCancel(s)&&await this.utils.onCancel(),s}async run(t=!1){if(await this.isInit()){if(t)return;this.utils.prompt.log.success(this.utils.style.success.msg("Git is initialized \u2728")),this.utils.prompt.log.step("");return}this.utils.prompt.log.info(this.utils.style.p("Init your repository"));const s=new D({opts:this.opts,utils:this.utils}),e=new U({opts:this.opts,utils:this.utils}),o=await s.ask(),i=await e.ask(!1),r=await this.#e(),l=await this.#t(),n=`git init && git add ${o} && git commit -m "${i}" && git branch -M ${r} && git remote add origin ${l} && git push -u origin ${r}`;this.utils.prompt.note(`Command to be executed: ${n}`),await this.#s()?(console.log(this.utils.style.info.hr("git init")),await mt(n),console.log(this.utils.style.info.hr()),this.utils.prompt.log.success(this.utils.style.success.msg("Git is initialized \u2728"))):this.utils.prompt.log.success(this.utils.style.success.msg("Git init skipped from execution \u2728")),this.utils.prompt.log.step("")}}class B extends ${async#t(t,s,e="main",o=!1){try{const i=await y(`gh pr create --title "${t}" --body "${s}" --base ${e}${o?" --web":""}`);if(i.stderr&&i.stderr.trim()!=="")throw new Error(i.stderr);return this.utils.prompt.log.success(i.stdout),!0}catch(i){this.utils.prompt.log.step("");const r=i?.stderr||i?.message;return this.utils.prompt.cancel(`Error creating pull request: `+r),!1}}async run(){await this.init(),await this.initGH();const t=this.opts?.defaultBranch,s=new E({opts:this.opts,utils:this.utils}),e={title:"title",body:"body",base:"base",open:"open"},o={[e.title]:"",[e.body]:"",[e.base]:t,[e.open]:!1},i=await this.utils.cache("pull",o),r=await i.get();console.debug("cached data",r),await this.utils.promptGroup({outro:`Finished ${this.utils.style.badge("pull")} process \u{1F308}`,onCancel:async()=>this.utils.onCancel(),list:async l=>({desc:()=>l.log.info(this.utils.style.p("Create a pull request on GitHub.")),[e.title]:async()=>{const n=await l.text({message:"Title of pull request",placeholder:r[e.title],initialValue:r[e.title],validate:a=>{if(a.length===0)return"Body can not be empty."}});return await i.set({[e.title]:n}),n},[e.body]:async()=>{const n=await l.text({message:"Body of pull request",placeholder:r[e.body],initialValue:r[e.body],validate:a=>{if(a.length===0)return"Body can not be empty.";if(a.length>50)return"Body can not be longer than 50 characters."}});return await i.set({[e.body]:n}),n},[e.base]:async()=>{const n=await s.askSelectBranch(r[e.base]||t);return await i.set({[e.base]:n}),n},[e.open]:async()=>{const n=await l.confirm({message:"Open pull request in browser?",initialValue:r[e.open]});return await i.set({[e.open]:n}),n},run:async({results:n})=>{await this.#t(n[e.title],n[e.body],n[e.base],n[e.open])||this.utils.process.exit(0)}})})}}class I extends S{async getRepoList(t){const{archived:s,fork:e,visibility:o}=t||{},i=[];await this.init(),await this.initGH(),s===!0?i.push("--archived"):s===!1&&i.push("--no-archived"),e===!0?i.push("--fork"):e===!1&&i.push("--source"),o&&i.push(`--visibility ${o}`);const r=`gh repo list ${this.opts?.userID||""} --json url,name,owner,homepageUrl,description,repositoryTopics`,{stdout:l,stderr:n}=await y(i.length?`${r} ${i.join(" ")}`:r);if(n)throw new Error(`Error getting repo list: ${n}`);return JSON.parse(l.trim()).map(a=>({desc:a.description?.trim()===""?void 0:a.description,homepage:a.homepageUrl?.trim()===""?void 0:a.homepageUrl,name:a.name,owner:a.owner.login,topics:a.repositoryTopics?.map(g=>g.name),url:a.url}))}}class P extends I{async list(){const{workflowsDir:t,URL:s}=this.opts||{};if(!t)return console.warn("No workflows dir provided. You need to provide a workflows dir");console.debug({workflowsDir:t});const e=await tt([t+"/*.yml"],{onlyFiles:!0}),o=this.utils.style,i=st(this.utils.process.cwd(),t),r=o.info.b(i)+` `+(e&&e.length?await et({input:t}):o.warn.p("No workflows found it!")).split(` `).map(l=>" "+l).join(` `)+` `+o.info.li("PATH:",i)+(s?` `+o.info.li("URL:",o.info.a(s)):"");console.log(it(r,{padding:1,borderStyle:"none"}))}async run(){await this.init(),await this.initGH();const{workflowDefaultInputs:t,workflowsDir:s,URL:e}=this.opts||{};if(!(s&&await L(s))||!s){this.utils.prompt.log.warn(this.utils.style.warn.msg("Does not exist workflows directory:",s));return}const o=await ot({path:s,extensions:[".yml"]});if(!o.length){this.utils.prompt.log.warn(this.utils.style.warn.msg("No local workflows found in",s));return}const i={file:"file",inputs:"inputs"},r={[i.file]:o[0],[i.inputs]:t||""},l=await this.utils.cache("workflow",r),n=await l.get();await this.utils.promptGroup({onCancel:this.utils.onCancel,list:async a=>({desc:()=>a.log.info(this.utils.style.p("Prompt for run workflow")),[i.file]:async()=>a.select({message:"Select a workflow:",options:o.map(g=>({value:g,label:g})),initialValue:n[i.file]}),[i.inputs]:async()=>a.text({initialValue:n[i.inputs],message:`Set inputs for workflow in comma separed. ${this.utils.style.color.dim("(Leave empty to not use any input)")}`}),fn:async({results:g})=>{try{const c=g;let u="";if(c.inputs&&c.inputs.trim()!=="")try{u=c.inputs.split(",").map(h=>h.trim()).map(h=>{const[b,w]=h.split("=");return`-f ${b}=${w}`}).join(" ")}catch{u=""}if(await l.set({[i.file]:c.file,[i.inputs]:c.inputs||""}),(await y(`gh workflow run ${c.file}.yml ${u}`)).stderr)throw Error("Error creating workflow");const d=await y("echo $(gh run list --limit 1 --json databaseId,url --jq '.[0].url')");d.stdout&&d.stdout.trim()!==""&&a.log.info("GitHub action url: "+this.utils.style.p(d.stdout)),a.log.success(e?this.utils.style.success.msg("See action progress:",this.utils.style.a(at(e,"actions"))):this.utils.style.success.msg("Succesfully finished \u{1F308}"))}catch(c){const u=c instanceof Error?c.message:c&&typeof c=="object"&&"stderr"in c?`${c.stderr}`:typeof c=="object"?JSON.stringify(c):`${c}`;a.log.error(this.utils.style.error.msg(`Workflow error `,u))}}})})}}const bt=new rt({sizium:()=>import("@sizium/core")});class G extends S{async#t(t){try{nt().hide(),await this.utils.execPkgBin("@changesets/cli",t)}catch(s){s instanceof Error&&await this.utils.onCancel()}}async init(){await this.#t(["init"])}async publish(t){return console.log(this.utils.style.info.hr("Publish packages")),t&&typeof t=="string"&&await R(t),await this.#t(["publish"])}async version(){return console.log(this.utils.style.info.hr("Update package version")),await this.#t(["version"])}async prepare(){return console.log(this.utils.style.info.hr("Prepare update")),await this.#t()}async getPkgVersion(t=!0,s=!0){const e=await this.utils.getPkgPaths();return(await Promise.all(e.map(async o=>{const i=await lt(o),r=!!i.private&&i.private!=="false";if(r&&!s||!i.name||!i.version)return null;const[l,n]=t&&!r?await A(ct(i.name)):[void 0,void 0];return{name:i.name,version:i.version,npm:n,private:r}}))).filter(o=>!!o)}async showPackageVersion(t=!0){const s=this.utils.prompt,e=s.spinner();try{e.start("Getting package(s) version info");const o=await this.getPkgVersion(t);e.stop("Getted pscakge(s) version info"),s.log.step(""),await s.box({value:`Your package version(s): ${o.map(i=>this.utils.style.section.li(i.name,`local: ${i.version}`+(t?` | npm: ${i.npm||"none"}`:"")+(i.private?" | private":""))).join(` `)} `,opts:{borderStyle:"none",padding:0}})}catch(o){o instanceof Error?s.log.error(o.message):s.log.error(o?o.toString():"Unknown error"),e.stop("Error getting package version")}}async ask(){const t={publish:"publish",run:"run",none:"none"},s={publishOrRun:"publish-or-run",prepare:"prepare",version:"version",command:"command"},e={[s.publishOrRun]:Object.values(t)[0],[s.prepare]:!0,[s.version]:!0,[s.command]:""},o=await this.utils.cache("pkg-ask",e),i=await o.get();return console.debug("cached data",i),await this.utils.promptGroup({onCancel:async()=>await this.utils.onCancel(),list:async r=>({prepare:async()=>{const l=await r.confirm({message:"Prepare new version(s)?",initialValue:i[s.prepare]});if(r.isCancel(l))return await this.utils.onCancel();if(await o.set({[s.prepare]:l}),!l)return l;await this.prepare(),console.log(this.utils.style.info.hr())},[s.version]:async()=>{const l=await r.confirm({message:"Update the version of the package(s) with the new prepared versions?",initialValue:i[s.version]});return r.isCancel(l)?await this.utils.onCancel():(await o.set({[s.version]:l}),l&&(await this.version(),console.log(this.utils.style.info.hr()),await this.showPackageVersion(!1),l))},publish:async({results:l})=>{let n=[];s.version in l&&n.push("Update the version of the package(s)"),n=[...n,"Build your package(s), if necessary","Run the tests to make sure everything works as expected"],await r.box({value:`Best practices before publishing: ${n.map(g=>this.utils.style.section.lk(g)).join(` `)} `,opts:{borderStyle:"none",padding:0}});const a=await r.select({message:"Publish the package now?",options:[{value:t.publish,label:"Publish package"},{value:t.run,label:"Run a command first"},{value:t.none,label:"Skip"}],initialValue:i[s.publishOrRun]});if(r.isCancel(a))return await this.utils.onCancel();if(await o.set({[s.publishOrRun]:a}),a===t.publish)await this.publish(),console.log(this.utils.style.info.hr());else if(a===t.run){const g=await r.text({message:"What command do you want to run?",initialValue:i[s.command]});if(r.isCancel(g))return await this.utils.onCancel();await o.set({[s.command]:g}),await this.publish(g),console.log(this.utils.style.info.hr())}else a!==t.none&&console.error(this.utils.style.error.msg("Unexpected error","No publish or run selected"))}})})}async release(){try{await this.prepare(),await this.version(),await this.publish()}catch(t){t instanceof Error?console.error("Release failed:",t.message):console.error("Release failed:",t)}}async getSizeData(t="./"){const{Sizium:s}=await bt.get("sizium"),e=new s(t);return{data:await e.get(),inputType:e.inputType}}async getSize(t="./"){const s=await this.getSizeData(t),e=s.inputType,{packageNum:o,size:i,id:r,packages:l}=s.data,n=e!=="string",a=c=>`${(c/(1024*1024)).toFixed(2)}mb (${(c/1024).toFixed(2)}kb)`;let g=this.utils.style.table([["Name",this.utils.style.info.b(r)],["Packages Installed",this.utils.style.p(o)],["Local package",this.utils.style.p(n)],["",""],["Unpacked size",this.utils.style.p(a(l[0].unpackedSize))],["Total size",this.utils.style.success.p(a(i))],["",""]],{chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:"","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:""}});return n||(g+=` `+this.utils.style.p(` View more details in ${this.utils.style.a(`https://sizium.pigeonposse.com/?s=${t}`)} `)),this.utils.prompt.log.message(g),s}}class z extends ${async exec(t){const s=`git push -f origin ${t}`;console.log(this.utils.style.info.hr(s)),await R(s),console.log(this.utils.style.info.hr())}async run(t){await this.init();const s=this.opts?.defaultBranch,e={opts:this.opts,utils:this.utils},o=new E(e),i=new U(e),r=new D(e),l=new j(e),n=new G(e);await l.run(!0);const a={staged:"staged",view:"view",update:"update",add:"add",origin:"origin",workflow:"workflow"},g={[a.staged]:!1,[a.view]:!0,[a.update]:!1,[a.add]:".",[a.origin]:s,[a.workflow]:!1},c=await this.utils.cache("push",g),u=await c.get();console.debug("cached data",u),await this.utils.promptGroup({outro:`Finished ${this.utils.style.badge("push")} process \u{1F308}`,onCancel:async()=>await this.utils.onCancel(),list:async d=>({desc:async()=>d.log.info(this.utils.style.p("Push your repository")),...t?.skipUpdate?{}:{[a.staged]:async()=>{const h=await d.confirm({message:"View staged files?",initialValue:u[a.staged]});if(d.isCancel(h))return await this.utils.onCancel();if(await c.set({[a.staged]:h}),!h)return;const b=await i.getStagedFiles();return d.log.message(this.utils.style.p(b)),h},[a.view]:async()=>{const h=await d.confirm({message:"View package version(s)?",initialValue:u[a.view]});return d.isCancel(h)?await this.utils.onCancel():(await c.set({[a.view]:h}),h&&await n.showPackageVersion(),h)},[a.update]:async()=>{const h=await d.confirm({message:"Update the version(s)?",initialValue:u[a.update]});return d.isCancel(h)?await this.utils.onCancel():(await c.set({[a.update]:h}),h)},"update-res":async({results:h})=>{h[a.update]&&await n.ask()}},"desc-add":async()=>d.log.info(this.utils.style.p("Prompt for add to repository")),[a.add]:async()=>await r.ask(u[a.add]),[a.origin]:async()=>await o.askSelectBranch(u[a.origin]||s),"add-res":async({results:h})=>{const b=h,w={[a.add]:b[a.add],[a.origin]:b[a.origin]};if(await c.set(w),w[a.add]&&w[a.origin])try{console.log(),await r.exec(w[a.add]),await i.run(),await this.exec(w[a.origin]),console.log(),d.log.success(this.utils.style.success.h("Successfully pushed to")+" "+this.utils.style.success.p(`${this.utils.style.a(await this.getGitRemoteURL()||"[no repoURL provided]")} `))}catch(C){C instanceof Error&&d.log.error(C.message),await this.utils.onCancel()}},...t?.skipWorkflow?{}:{[a.workflow]:async()=>{const h=await d.confirm({message:"Run GitHub workflow?",initialValue:u[a.workflow]});return d.isCancel(h)?await this.utils.onCancel():(await c.set({[a.workflow]:h}),h)},"workflow-res":async({results:h})=>{h[a.workflow]&&await new P({opts:this.opts,utils:this.utils}).run()}}})})}}class N extends S{add;branch;commit;husky;pull;push;initialize;constructor(t){super(t),this.add=new D(t),this.branch=new E(t),this.commit=new U(t),this.husky=new V(t),this.pull=new B(t),this.push=new z(t),this.initialize=new j(t)}}const k={list:"list",current:"current",change:"change",create:"create",delete:"delete",switch:"switch",createSwitch:"create-switch"},f={add:"add",commit:"commit",branch:"branch",push:"push",pull:"pr",husky:"husky",init:"init"},H=p=>({custom:{git:{desc:"Git commands (add, commit, branch, pull, push...)",cmds:{[f.init]:{desc:"Initialize git project"},[f.add]:{desc:"Add files to git"},[f.commit]:{desc:"Commit configuration"},[f.branch]:{desc:"branch configuration",opts:{[k.list]:{desc:"List branches",type:"boolean"},[k.current]:{desc:"Show current branch",type:"boolean"},[k.change]:{desc:"Change branch",type:"string"},[k.create]:{desc:"Create branch",type:"string"},[k.delete]:{desc:"Delete branch",type:"string"},[k.switch]:{desc:"Switch branch",type:"string"},[k.createSwitch]:{desc:"Create and switch branch",type:"string"}}},[f.pull]:{desc:"Pull request configuration"},[f.push]:{desc:"Push your code to a branch",opts:{"skip-update":{desc:"Skip update",type:"boolean"},"skip-wf":{desc:"Skip workflow",type:"boolean"}}},[f.husky]:{desc:"Husky configuration"}},fn:async({cmds:t,utils:s,opts:e,showHelp:o})=>{const i=l=>Object.values(l).map(n=>ut.gray.dim.italic(n)).join(", "),r=new N({opts:p,utils:s});t?.includes(f.commit)?await r.commit.run():t?.includes(f.init)?await r.initialize.run():t?.includes(f.add)?await r.add.run():t?.includes(f.pull)?await r.pull.run():t?.includes(f.branch)?e?.list?await r.branch.showAll():e?.current?await r.branch.showCurrent():e?.change||e?.change===""?await r.branch.change(e.change):e?.create||e?.create===""?await r.branch.create(e.create):e?.delete||e?.delete===""?await r.branch.delete(e.delete):e?.switch||e?.switch===""?await r.branch.switch(e.switch):e?.[k.createSwitch]||e?.[k.createSwitch]===""?await r.branch.createAndSwitch(e.createAndSwitch):console.warn(`No option provided. Use: ${i(k)}`):t?.includes(f.push)?await r.push.run({skipUpdate:e?.["skip-update"],skipWorkflow:e?.skipWorkflow}):t?.includes(f.husky)?await r.husky.run():o()}}}});class kt extends I{async run(){await this.init(),await this.initGH(),console.log(this.utils.style.info.hr("Publish packages")),await R("gh repo create")}}class W extends I{async viewAll(){const t=await this.getRepoList();t&&t.length>0?console.dir(t,{depth:1/0}):console.error("No data found")}async view(){const t=(await this.getRepoList()).filter(s=>s.name===this.opts?.ID)[0];t?console.dir(t,{depth:1/0}):console.error("No data found")}async update(){try{await this.init(),await this.initGH();const{URL:t,homepageURL:s,tags:e,desc:o}=this.opts||{};if(!t)return this.utils.prompt.log.warn(this.utils.style.warn.msg("No repo url provided","You need to provide a repo url"));const i=s?`--homepage "${s}"`:"",r=e?`--add-topic "${e}"`:"",l=o?`-d "${o}"`:"",n=[["homepage",s||"none"],["topics",e?.join(", ")||"none"],["description",o||"none"]];if(await this.utils.prompt.box({value:`Repo info to update: ${n.map(a=>this.utils.style.info.li(...a)).join(` `)} `,opts:{borderStyle:"none",padding:0},type:"info"}),i||r||l){const{stderr:a}=await y(`gh repo edit "${t}" ${i} ${r} ${l}`);if(a)return this.utils.prompt.log.errorWithExit(this.utils.style.error.msg("Error updating repo info",a));this.utils.prompt.log.success(this.utils.style.success.h("Updated repo info in")+" "+this.utils.style.success.p(`${this.utils.style.a(t)}`))}else this.utils.prompt.log.errorWithExit(this.utils.style.error.msg("Nothing to update."));this.utils.prompt.log.step("")}catch(t){console.error("Unexpected error",t)}}}const v={DOWNLOAD:"download",WORKFLOW:"workflow",INFO:"info",CREATE:"create"},vt={WORKFLOW:"wf"};class T{info;workflow;create;opts;utils;constructor({opts:t,utils:s}){this.opts=t,this.utils=s,this.info=new W({opts:t,utils:s}),this.workflow=new P({opts:t,utils:s}),this.create=new kt({opts:t,utils:s})}async download(t,s){return await pt({input:t,output:s})}}const M=p=>({custom:{gh:{desc:"GitHub Repo commands and configuration",cmds:{[v.DOWNLOAD]:{desc:"Download a repository or a part of it",opts:{input:{type:"string",desc:"Repository or Repository path to download",alias:"i"},output:{type:"string",desc:"Output directory",alias:"o"}}},[v.CREATE]:{desc:"Create a new repo"},[v.WORKFLOW]:{desc:"Run or list a workflow",opts:{list:{desc:"List workflows",alias:"l"}}},[v.INFO]:{desc:"Repo information",cmds:{update:{desc:"Update repo info"},view:{desc:"View repo info",opts:{all:{desc:"Show repo info for all repositories"}}}}}},fn:async({cmds:t,opts:s,utils:e,showHelp:o})=>{const i=new T({opts:p,utils:e});t?.includes(v.DOWNLOAD)&&s?.input&&s?.output?await i.download(s.input,s.output):t?.includes(v.WORKFLOW)||t?.includes(vt.WORKFLOW)?s?.list?await i.workflow.list():await i.workflow.run():t?.includes(v.CREATE)?await i.create.run():t?.includes(v.INFO)&&(t?.includes("update")||t?.includes("up"))?await i.info.update():t?.includes(v.INFO)&&t?.includes("view")?s?.all?await i.info.viewAll():await i.info.view():o()}}}}),m={release:"release",publish:"publish",init:"init",version:"version",prepare:"prepare",ask:"ask",showVersion:"show-version",size:"size"},_=p=>({custom:{pkg:{desc:"Packages commands: update, publish...",cmds:{[m.init]:{desc:"Init package(s)"},[m.ask]:{desc:"Ask for changes"},[m.prepare]:{desc:"Preprare version changelog"},[m.version]:{desc:"Update version of package(s)"},[m.publish]:{desc:"Publish package(s)"},[m.release]:{desc:"Update version and publish package(s)"},[m.showVersion]:{desc:"Show version of package(s). (Local and NPM)",opts:{local:{desc:"show Local version only",type:"boolean"}}},[m.size]:{desc:"Get package size of package. (Local and NPM)",opts:{input:{alias:"i",desc:"Local path package directory/file or npm package name",type:"string"}}}},fn:async({utils:t,cmds:s,showHelp:e,opts:o})=>{const i=new G({opts:p,utils:t});s?.includes(m.release)?await i.release():s?.includes(m.publish)?await i.publish():s?.includes(m.prepare)?await i.prepare():s?.includes(m.init)?await i.init():s?.includes(m.version)?await i.version():s?.includes(m.ask)?await i.ask():s?.includes(m.size)?await i.getSize(o?.input):s?.includes(m.showVersion)?await i.showPackageVersion(!o?.local):e()},examples:[{cmd:`$0 pkg ${m.release}`,desc:"Directly update version and publish packages"}]}}}),F={author:{name:"Author",emoji:"\u{1F451}",desc:"Author of the project."},developer:{name:"Developer",emoji:"\u{1F4BB}",desc:"Contributor for the development of the project. Code, docs, etc."},contributor:{name:"Contributor",emoji:"\u{1F4BB}",desc:"Contributor for the development of the project. Code, docs, etc."},mantainer:{name:"Mantainer",emoji:"\u{1F6A7}",desc:"Maintainer of the project. Code, docs, etc."},designer:{name:"Designer",emoji:"\u{1F484}",desc:"Contributor for the design of the project. Images, icons, etc."},organization:{name:"Organization",emoji:"\u{1F3E2}",desc:"Organization of the project."},sponsor:{name:"Sponsor",emoji:"\u{1F91D}",desc:"Sponsor of the project."},translator:{name:"Translator",emoji:"\u{1F30F}",desc:"Translator for the project."}},$t=p=>{if(p.includes("github.com")){const t=p.match(/github\.com\/([^/]+)/);return t?t[1]:"unknown"}return p.split("@")[0]||"unknown"},q=(p,t)=>{if(!p)throw new Error("No package provided");const s=t?.member||[],e={author:F.author,contributor:F.contributor,mantainer:F.mantainer,...t?.role||{}},o={contributors:p.contributors||[],author:p.author?[p.author]:[],maintainers:p.maintainers||[]};for(const[i,r]of Object.entries(o))for(const l of r)if(typeof l=="string")s.push({role:i,ghUsername:l,name:l});else{const{name:n,url:a,email:g}=l,c=$t(a||g||"");s.push({role:i,ghUsername:c,name:n||c,url:a})}return s.length?{role:e,member:s}:void 0};class K{opts;utils;constructor(t){this.utils=t?.utils,!t?.opts||!t?.opts.role||!t?.opts.member?this.utils?.pkg&&(this.opts=q(this.utils.pkg)):this.opts=t?.opts}async filterByRole(t){if(!this.opts?.member||!this.opts?.role)throw new Error("Missing role or member");return t.length?{role:Object.fromEntries(Object.entries(this.opts.role).filter(([s])=>t.includes(s))),member:this.opts.member.filter(s=>t.includes(s.role))}:void 0}async filterByRolePattern(t){if(!this.opts?.role)throw new Error("Missing role");const s=ht(Object.keys(this.opts.role),t);return await this.filterByRole(s)}async getMarkdownContent(t){const s=t?.role||this.opts?.role,e=t?.member||this.opts?.member;if(!e||!s)throw new Error("Missing role or member");const o=t?.content?.name??!0,i=t?.content?.image??!0,r=t?.role!==void 0?t.role:!0,l=[],n=[];i&&(l.push(" "),n.push("-----")),o&&(l.push("Name"),n.push("----")),r&&(l.push("Role"),n.push("----"));const a=`| ${l.join(" | ")} |`,g=`| ${n.join(" | ")} |`,c=e.map(u=>{const d=u.url||`https://github.com/${u.ghUsername}`,h=u.avatar||`https://github.com/${u.ghUsername}.png?size=72`,b=s[u.role],w=[];if(i&&w.push(`![${u.name}](${h})`),o&&w.push(`[${u.name}](${d})`),r){const C=`${b?.emoji??""} ${b?.name??""}`.trim();w.push(C)}return`| ${w.join(" | ")} |`});return["## Contributors","",a,g,...c].join(` `).trim()}async getHtmlContent(t){return dt(await this.getMarkdownContent(t))}async getTerminalContent(t){return await gt(await this.getMarkdownContent(t))}async showTerminalOutput(t){console.log(await this.getTerminalContent(t))}}const Y=p=>({const:p?{contributors:p}:void 0,custom:{contributors:{desc:"Toolkit for workspace contributors",cmds:{list:{desc:"List workspace contributors",opts:{role:{type:"array",desc:"Contributor role pattern"}}}},fn:async({cmds:t,showHelp:s,opts:e,utils:o})=>{const i=new K({opts:p,utils:o});if(t?.includes("list"))if(e?.role){const r=await i.filterByRolePattern(e.role);await i.showTerminalOutput({...r,content:{image:!1}})}else await i.showTerminalOutput({content:{image:!1}});else s()}}}}),J=p=>{const{contributors:t,...s}=p||{};return yt([Y(t),M(s),H(s),_(s)])};export{F as CONTRIBUTOR_ROLE,K as Contributors,N as Git,D as GitAdd,E as GitBranch,U as GitCommit,T as GitHub,W as GitHubInfo,P as GitHubWorkflow,j as GitInit,B as GitPull,z as GitPush,V as Husky,G as Packages,Y as contributorsPlugin,J as default,M as ghPlugin,H as gitPlugin,q as package2Contributors,_ as pkgPlugin,J as repoPlugin};