UNPKG

@dovenv/core

Version:

Quickly and easily set up your environment for your code projects

79 lines (62 loc) 25.1 kB
import{icon as h,line as M,color as m,box as $,highlight as st,indent as D,table as et,validate as it,promptLine as at,promptLineGroup as ot,process as f,performance as nt,spinner as rt,logger as ct,getBooleanFlagValue as lt,joinPath as C,cache as ht,getBaseName as pt,getPackageRuntimeFromContent as gt,getPackageManagerFromContent as ut,getPackageWorkspacePaths as dt,getPackageDataFromPath as mt,getPaths as yt,getLocalPkgPath as ft,exec as k,catchError as v,formatValidationError as wt,schema2type as kt,zod2schema as vt,getMatch as Et,resolvePath as x,getObjectFromFile as Ot,existsPath as bt,getObjectFromJSFile as $t,TypedError as L,createValidateSchemaFn as w,deepmergeCustom as Ct,createCli as Nt,hideBin as St,readFiles as At,readFile as Pt,writeFileContent as xt,deprecatedAlerts as Tt}from"@dovenv/utils";const It="@dovenv/core",Rt="1.6.1",jt="https://dovenv.pigeonposse.com/guide/core",Ft={dovenv:"./dist/bin.mjs"},G=It,S=Object.keys(Ft)[0],T=Rt,U=jt,I=U,_t={CONSTANTS:"const",CHECK:"check",TRANSFORM:"transform",ALIASES:"alias",CONFIG:"config",ALIAS_EXEC:"x"},V=["js","mjs","cjs","ts","mts","cts"],Mt={KEY:{key:"key",alias:"k"}},R={VERSION:{key:"version",alias:"v"},HELP:{key:"help",alias:"h"},CONFIG:{key:"config",alias:"c"},VERBOSE:{key:"verbose"},QUIET:{key:"silent"}},Dt={BUN:"bun",NPM:"npm",PNPM:"pnpm",YARN:"yarn"},Lt={NODE:"node",BUN:"bun",DENO:"deno"},j={__proto__:null,BIN_NAME:S,CMD:_t,CONFIG_EXTS:V,GLOBAL_OPTIONS:R,HELP_URL:I,HOMEPAGE:U,OPTIONS:Mt,PKG_MANAGER:Dt,PKG_NAME:G,RUNTIME:Lt,VERSION:T},K=({data:e,title:t=void 0,lang:s=void 0,borderColor:i})=>$(st(e,{language:s}),{headerText:t,borderColor:(a,o,r)=>m.dim(i?i(a,o,r):a),padding:{top:1,left:1,right:1},borderStyle:{bottom:h.line,top:h.line,left:"",right:"",bottomRight:h.line,topRight:h.line,bottomLeft:h.line,topLeft:h.line}}),E=(e,t)=>{const s=e?m[e]:m,i=n=>s(t?t+" "+n:n),a=n=>s.dim(n),o=n=>s(h.bullet+" "+n),r=n=>a(n),c=(n,p)=>o(n)+" "+r(p),l=n=>s.italic.underline(n),u=n=>s.inverse(" "+n+" "),g=n=>s.bold(n);return{icon:t,h1:n=>i(u(g(n))),h:n=>i(g(n)),text:n=>s(n),msg:(n,p)=>g(n)+(p?" "+a(p):""),code:({desc:n,code:p,lang:y,readmore:d})=>a(n)+(p?` `+K({data:p,title:"Example",lang:y,borderColor:tt=>s(tt)}):"")+(d?a(` Read more: `+l(d)):"")+` `,lk:n=>s(h.bullet+" "+n),lv:n=>a(n),li:(n,p)=>c(n,p),ul:n=>n.map(([p,y])=>c(p,y)).join(` `),p:a,a:l,b:g,badge:u,hr:(n,p,y)=>` ${M({title:n||n?.trim()!==""?n:"",lineColor:d=>s(d),titleAlign:p||"center",lineChar:h.line,lineDim:y})} `}},A=E(void 0,h.dot);class Gt{color=m;line=M;icon=h;indent=D;main=E("blue");section=E("blue",h.triangleRightSmall);error=E("red",h.cross);warn=E("yellow",h.warning);success=E("green",h.tick);info=E(void 0,h.info);a=A.a;p=A.p;badge=A.badge;b=A.b;table(t,s){return et(t,{wrapOnWordBoundary:!0,wordWrap:!0,...s||{}})}box({data:t,title:s=void 0,border:i=!0,dim:a=!0}){return $(t,{headerText:s,borderColor:a?o=>m.dim(o):void 0,padding:{top:1,left:1,right:1},borderStyle:i?"single":"none"})}code=K}class B{log;validate=it;prompt=at;promptGroup=ot;process=f;style=new Gt;performance=nt;spinner=rt;title="core";config;get configPath(){return globalThis.DOVENV_CONFIG_PATH}version=T;helpURL=I;pkg;wsDir=f.cwd();message;onDebug=(...t)=>{console.log(this.style.info.hr(this.style.info.b("DEBUG")+(this.title&&this.title.length?" "+this.title.toUpperCase():""),"top-center",!0));for(let s=0;s<t.length;s++)typeof t=="object"?console.dir(t,{depth:1/0}):console.log(t);console.log(this.style.info.hr("","top-center",!0))};onWarn=(...t)=>{console.log(this.style.warn.h1("WARN"),...t)};onError=(...t)=>{t&&t.length&&console.log(this.style.error.h1("ERROR"),...t),f.exit(0)};onCancel=async()=>{this.prompt.log.step(""),this.prompt.cancel("Process cancelled \u{1F494}"),f.exit(0)};constructor(t){try{this.log=ct,this.log.wrapConsole(),this.log.withTag(this.title),this.log.options.formatOptions={columns:80,colors:!1,compact:!1,date:!1};const s=this.log.options.reporters;this.log.options.reporters=[{log:(i,a)=>{i.type==="debug"?this.onDebug(...i.args):i.type==="warn"?this.onWarn(...i.args):i.type==="error"?this.onError(...i.args):s[0].log(i,a)}}],lt(R.VERBOSE.key)&&(this.log.options.level=999),this.config=t,this.config?.const?.pkg&&(this.pkg=this.config.const.pkg),this.config?.const?.workspaceDir&&typeof this.config.const.workspaceDir=="string"?this.wsDir=this.config.const.workspaceDir:this.config?.const?.wsDir&&typeof this.config.const.wsDir=="string"&&(this.wsDir=this.config.const.wsDir),this.message={pkgError:this.style.error.code({desc:`${this.style.b("const.pkg")} was not found in dovenv configuration. Add a ${this.style.b("const.pkg")} variable with your workspace package.json for a better workflow with dovenv.`,code:`import { defineConfig } from '@dovenv/core' import pkg from './package.json' export default defineConfig({ const: { pkg }, }); `}),noRuntime:this.style.error.code({desc:`No runtime found in your workspace. Add ${this.style.b("engines")} to your package.json (${C(this.wsDir,"package.json")}).`,code:`{ "engines": { "node": ">=16" } }`,lang:"json",readmore:"https://docs.npmjs.com/cli/v10/configuring-npm/package-json#engines"})}}catch(s){if(s instanceof Error){const{message:i,...a}=s;console.log(this.style.error.msg(this.title,`Error ${i} ${a}`))}else console.error(this.style.error.p(s));f.exit(1)}}async cache(t,s){return await ht({projectName:this.pkg?.name||pt(this.wsDir)||"shared",suffix:S,id:t,values:s})}#t;#s;#e;#i;get monorepo(){if(!this.pkg)throw new Error(this.message.pkgError);return!!this.pkg?.workspaces}get runtime(){if(!this.pkg)throw new Error(this.message.pkgError);return this.#s?this.#s:(this.#s=gt(this.pkg),this.#s)}get packageManager(){if(!this.pkg)throw new Error(this.message.pkgError);return this.#t?this.#t:(this.#t=ut(this.pkg),this.#t)}isMonorepo(){return this.monorepo}getPkgManager(){return this.packageManager.value}getPkgManagerCmds(){return this.packageManager.cmds}getRuntime(){return this.runtime.value}async getPkgPaths(){if(!this.pkg)throw new Error(this.message.pkgError);return this.#e?this.#e:(this.#e=await dt({wsDir:this.wsDir,pkg:this.pkg,manager:this.packageManager.value}),this.#e)}async getPkgsData(){if(this.#i)return this.#i;const t=await this.getPkgPaths();this.#i=[];for(const s of t){const i=await mt(s);this.#i.push(i)}return this.#i}async getPaths(t,s={}){return(await yt(t,{...s,cwd:this.wsDir})).map(i=>this.getWsPath(i))}getWsPath(t){return t||(t=""),t.startsWith(this.wsDir)?t:C(this.wsDir,t)}async execPkgBin(t,s,i){console.debug({name:t,args:s,opts:i});let a=ft(t);const o=s?s.join(" "):"";if(!a||i?.forceExec){i?.forceExec||console.info(`"${t}" is not installed or not detected in "node_modules"`);const r=`${this.packageManager.cmds.exec} ${t}@${i?.remoteVersion||"latest"} ${o}`;console.info(this.style.info.msg("Execute:",r),` `),await k(r)}else{const r=this.getRuntime();if(i?.path){const l=a.lastIndexOf(t);l!==-1&&(a=a.slice(0,l+t.length)),a=C(a,i?.path)}const c=`${r} ${a} ${o}`;console.info(this.style.info.msg("Execute:",c)),await k(c)}}async validateSchema(t,s,i){const[a,o]=await v((async()=>t.parse(s))());if(!a)return o;const r=wt(a).replace("Validation error:","").split(";").map(l=>l.trim()).filter(l=>l.length>0).join(` `);let c=this.style.error.b("Schema error!");if(c+=` `+this.style.error.lk("Details:")+` ${this.style.indent(r)}`,i?.showValid){const l=await kt({schema:await vt({schema:i?.validSchema||t})});c+=` ${this.style.error.lk("Valid schema:")} `+this.style.indent(l.startsWith("= ")?l.replace("= ",""):l)}throw new Error(c)}getKeys(t){const{pattern:s,input:i}=t,a=s?s.map(r=>String(r)):i,o=Et(i,a);if(o.length)return o;console.warn(this.style.warn.b("keys provided does not exist"),this.style.warn.text(` Available keys: ${this.style.warn.p(i.join(", "))}`))}getKey(t){const{value:s,input:i}=t;if(s&&i.includes(s))return s;console.warn(this.style.warn.b("key provided does not exist"),this.style.warn.text(` Available keys: ${this.style.warn.p(i.join(", "))}`))}async ensureOpts(t){return t.name||(t.name=this.title),t.input?!0:(console.warn(this.style.warn.p(`No options for "${this.style.b(t.name)}" found in ${S} configuration. Please add necessary configuration for correct usage. ${this.configPath?"Config path: "+this.style.color.italic(this.configPath)+` `:""}More info: ${this.style.a(this.helpURL)}`)),!1)}async getOptsKeys(t){if(t.name||(t.name=this.title),!(t.input&&Object.keys(t.input).length)){console.warn(this.style.warn.p(`No options for "${this.style.b(t.name)}" found in ${S} configuration. Please add necessary configuration for correct usage. ${this.configPath?"Config path: "+this.style.color.italic(this.configPath)+` `:""}More info: ${this.style.a(this.helpURL)}`));return}const s=Object.keys(t.input);if(t.pattern&&Array.isArray(t.pattern))return this.getKeys({input:s,pattern:t.pattern});if(typeof t.pattern=="string")return this.getKey({input:s,value:t.pattern});console.warn(this.style.warn.b("Any key provided"),this.style.warn.text(` Available keys: ${this.style.warn.p(s.join(", "))}`))}async getConsts(t){const s=this.config?.const||{},i=async a=>{if(!(s&&typeof a=="string"&&a in s))return;const o=s[a];if(typeof o=="function"){const[r,c]=await v((async()=>await o())());return r?"Error setting value of "+a+`: `+r.message:c}else return o};return t?await i(t):Object.fromEntries(await Promise.all(Object.entries(s).map(async([a])=>[a,i(a)])))}exitWithError(){this.process.exit(1)}logGroup(t){const s=(i,a)=>(o,r)=>this.prompt.log[i](this.style.info.badge(this.title)+(a?this.style[i].b(` (${a}) `):" ")+(r?this.style[i].msg(o,r):this.style[i].p(o)));return{info:s("info",t),success:s("success",t),warn:s("warn",t),error:s("error",t),step:i=>this.prompt.log.step(i||"")}}async mapOpts(t){const{input:s,pattern:i,cb:a}=t,o=await this.getOptsKeys({input:s,pattern:i})??[];if(!s)return{};const r=await Promise.all(o.map(async c=>{const l=this.logGroup(String(c));l.info("\u{1F3C1}","Starting...");const u=await a({key:c,value:s[c],log:l});return l.success("\u2728",`Finished Successfully `),[c,u]}));return Object.fromEntries(r)}async catchFn(t,s){const[i,a]=await v(t);if(i)console.log(this.style.error.h1(this.title)+(s?` ${this.style.error.h(s)}`:""),this.style.error.p(i.message)),this.exitWithError();else return a}}const W=async e=>{let{pkg:t}=e||{};const s=e?.wsDir?x(e.wsDir):f.cwd();if(!t){const i=C(s,"package.json");t=await Ot(i)}return new B({const:{wsDir:s,pkg:t}})},Ut=m.inverse(` ${h.cross} Configuration Error `),P={NO_ROUTE:"NO_ROUTE",NO_DEFAULT_ROUTE:"NO_DEFAULT_ROUTE",CONFIG_FILE_ERROR:"JS_FILE_ERROR"};class O extends L{}const F=["dovenv/main","dovenv/index","dovenv.config"],H=f.cwd(),Y=V,Vt=F.flatMap(e=>Y.flatMap(t=>[`.${e}.${t}`,`${e}.${t}`])).sort(e=>e.startsWith(".")?-1:1).map(e=>C(H,e)),_={headerTextColor:e=>m.dim(e),borderColor:e=>m.dim(e),padding:1,borderStyle:{bottom:h.line,top:h.line,left:"",right:"",bottomRight:h.line,topRight:h.line,bottomLeft:h.line,topLeft:h.line}},Kt=e=>{let t="";return e.cause&&(t+=` ${$(m.dim.italic(e.cause.toString()),{headerText:"Cause",..._})}`),t+=` ${$(m.dim.italic(e.stack),{headerText:"Details",..._})} `,t},X=`${h.dot} For more information, see: ${m.underline.dim.italic(I)}`,Bt=`${h.dot} Or use a custom route with: ${m.dim.italic("$0 --config <config-path>")}`,J=$(`${h.dot} You can create a configuration file in the following paths and it will be automatically detected: ${[...F.map(e=>`.${e}`),...F].map(e=>D(`${h.dot} ${m.dim.italic(e.replace(H,".")+`.{${Y.join(",")}}`)}`)).join(` `)} ${Bt}`,{headerText:"Info",..._})+` `,Q=async e=>{e=x(e);const t=await bt(e),s=`The configuration path [${e}] does not exist`;if(!t)throw new O(P.NO_ROUTE,{data:`${m.bold(s)} ${J} ${X}`});const[i,a]=await v($t(e));if(i)throw new O(P.CONFIG_FILE_ERROR,{data:`${i.message.trim()} ${i.stack?Kt(i):""} ${X}`});return{config:a,path:e}},Wt=async()=>{const e=[],t="Configuration path not found or not provided.";for(const s of Vt){const[i,a]=await v(Q(s));if(i)i instanceof O&&i.message===P.CONFIG_FILE_ERROR?e.push(i):i instanceof O||e.push(i);else return a}throw e.length?e[0]:new O(P.NO_DEFAULT_ROUTE,{data:`${m.bold(t)} ${J}`})},Ht=async e=>{try{return e?(e=x(e),await Q(e)):await Wt()}catch(t){const s=i=>new Error(`${Ut} ${i}`);throw t instanceof O?s(t.data?.data||t.message||"Unexpected error"):t instanceof Error?s(t.message||"Unexpected error"):s("Unexpected error")}},Yt=w(e=>e.record(e.string(),e.object({desc:e.string(),opts:e.record(e.string(),e.object({desc:e.string()})).optional(),cmds:e.record(e.string(),e.object({desc:e.string()})).optional(),examples:e.array(e.object({desc:e.string(),cmd:e.string()})).optional(),settings:e.object({wrapConsole:e.boolean().optional(),hide:e.boolean().optional()}).optional(),fn:e.any()}).strict())),Xt=class extends L{};class N{constructor(t,s){this.opts=t,this.utils=s,this.utils.title="core",this.schema=this.utils.validate.unknown()}schema;Error=Xt;catchError=v;description="";consts=j;setMainTitle(t,s){const{style:i}=this.utils;console.log(` ${i.main.h1(t)}${s?` `+i.main.p(s):""} `)}setTitle(){const{style:t,title:s}=this.utils;console.log(` ${t.section.h1(s)} ${t.section.p(this.description)} `)}setTime(t){const{style:s,title:i}=this.utils;console.log(` ${s.section.h1(i)} ${s.section.msg("Elapsed time:",t)} `)}async validateSchema(t){return await this.utils.validateSchema(this.schema,t,{showValid:!0})}getKeysFromArgv(t,s){const i=this.consts.OPTIONS.KEY.key,a=s&&s.opts&&i in s.opts&&Array.isArray(s.opts[i])?Object.values(s.opts[i]):t;return this.utils.getKeys({input:t,pattern:a})}}const Jt=Ct({});class z extends N{cli;constructor(t,s,i){super(s,i),this.cli=t,this.schema=Yt(this.utils.validate)}#t(t){const s=new Set(Object.entries(t)),i=a=>this.cli.showHelp(a||"log");s.forEach(([a,o])=>{this.cli.command({command:a,desc:o.settings?.hide?!1:o.desc.endsWith(".")?o.desc.slice(0,-1):o.desc,builder:async r=>await this.#s(r,o,i),handler:async r=>await this.#e(r,a,o,i)})})}async#s(t,s,i){return s.opts&&(t.group(Object.keys(s.opts),"Options:"),t.options(s.opts)),s.cmds&&new Set(Object.entries(s.cmds)).forEach(([a,o])=>{t.command({command:a,desc:s.settings?.hide?!1:o.desc,builder:async r=>await this.#s(r,{...o,fn:s.fn},i),handler:async r=>await this.#e(r,a,s,i)})}),s.examples&&s.examples.forEach(a=>t.example(a.cmd,a.desc)),t}async#e(t,s,i,a){const{_:o,$0:r,...c}=t,l=this.utils.performance(),u=this.utils.config?.name||void 0,g=this.utils.config?.desc||void 0,n=c?.[R.QUIET.key]||!1;u&&!n&&this.setMainTitle(u,g),this.utils.title=s,this.description=i.desc,n||this.setTitle();try{i.settings?.wrapConsole===!1?this.utils.log.restoreConsole():this.utils.log.wrapConsole(),await i.fn({bin:r,cmds:o,opts:c,utils:this.utils,showHelp:a}),n||this.setTime(l.prettyStop())}catch(p){this.utils.log.error(p instanceof Error?p.message:p||"No error message specified"),n||this.setTime(l.prettyStop()),this.utils.exitWithError()}}async run(){if(this.opts)try{await this.validateSchema(this.opts),this.#t(this.opts)}catch(t){this.utils.title="custom",this.description="Custom commands",this.setTitle(),this.utils.log.error(t instanceof Error?t.message:t),this.utils.exitWithError();return}}}const q=async e=>{const{GLOBAL_OPTIONS:t,BIN_NAME:s,VERSION:i}=j,{args:a=[],version:o=i,name:r=s,opts:c,hook:l,examples:u}=e||{};return await Nt({args:a,fn:async g=>{g.scriptName(r).version(o).usage("Usage: $0 <command> [options]").locale("en").help(!1).updateStrings({"Options:":"Global Options:"}).showHelpOnFail(!1).wrap(g.terminalWidth()).alias(t.HELP.key,t.HELP.alias).alias(t.VERSION.key,t.VERSION.alias).option(t.VERBOSE.key,{desc:"Verbose mode",type:"boolean"}).option(t.QUIET.key,{desc:"Quiet mode",type:"boolean"}),c&&g.options(c),u&&u.forEach(p=>g.example(p.cmd,p.desc));const n=await g.argv;return l&&(g=await l({cli:g,argv:n})),n._.length||g.showHelp("log"),g}})},Qt=async e=>{const{wsDir:t,pkg:s,cmds:i,hook:a,...o}=e||{},r=await W({wsDir:t,pkg:s});return o.args||(o.args=St(r.process.argv)),await q({...o,hook:async({cli:c,argv:l})=>(i&&await new z(c,i,r).run(),a&&(c=await a({cli:c,argv:l})),c)})},zt=w(e=>e.record(e.string(),e.strictObject({desc:e.string(),cmd:e.any()})));class Z extends N{argv;load;id;constructor(t){super(t.utils.config?.alias,t.utils),this.utils.title="alias",this.id=this.consts.CMD.ALIASES,this.argv=t,this.load=this.utils.spinner(),this.schema=zt(this.utils.validate).optional()}async#t(){if(!(!this.opts||Object.keys(this.opts).length===0)){for(const t of Object.keys(this.opts)){const{desc:s}=this.opts[t];console.log(this.utils.style.indent(this.utils.style.info.li(t,s)))}console.log()}}async#s(){if(!this.opts||Object.keys(this.opts).length===0)return;const t=Object.keys(this.opts).find(a=>this.argv?.cmds?.includes(a));if(!t){const a=this.argv?.cmds?.at(-1);console.log(this.utils.style.info.h(a!==this.consts.CMD.ALIAS_EXEC?`The key provided ${this.utils.style.badge(this.argv?.cmds?.at(-1))} does not exist. `:`No key provided. `),this.utils.style.info.msg(" Available keys:",this.utils.style.color.dim.italic(Object.keys(this.opts).join(", "))));return}const s=this.opts[t].cmd,i=()=>((a,o)=>a.includes(o)?a.slice(a.indexOf(o)+1):[])(this.utils.process.argv,this.consts.CMD.ALIAS_EXEC).slice(1)||"";if(s)if(typeof s=="function"){const a={runtime:this.utils.getRuntime(),pkgManager:this.utils.getPkgManager(),pkgManagerCmds:this.utils.getPkgManagerCmds(),isMonorepo:this.utils.isMonorepo(),bin:this.argv?.bin||this.consts.BIN_NAME};await s({data:a,utils:this.utils,opts:i(),exec:{command:async o=>await k(`${o}`),runtime:async o=>await k(`${a.runtime} ${o}`),pkgManager:async o=>await k(`${a.pkgManager} ${o}`),current:async o=>await k(`${a.bin} ${o}`),pkgBin:async(...o)=>await this.utils.execPkgBin(...o)}})}else typeof s=="string"&&await k(s)}async#e(){await this.utils.ensureOpts({input:this.opts})&&(await this.validateSchema(this.opts),this.argv?.cmds?.includes(this.id)?await this.#t():this.argv?.cmds?.includes(this.consts.CMD.ALIAS_EXEC)&&await this.#s())}async run(){return await this.utils.catchFn(this.#e())}}const b={DIR:"dir",FILE:"file",CUSTOM:"custom"},qt=w(e=>e.object({title:e.string().optional(),desc:e.string().optional(),type:e.literal(b.FILE),patterns:e.array(e.string()).nonempty(),validateAll:e.any(),validate:e.any()})),Zt=w(e=>e.strictObject({title:e.string().optional(),desc:e.string().optional(),type:e.literal(b.DIR),patterns:e.array(e.string()).nonempty(),validateAll:e.any(),validate:e.any()})),ts=w(e=>e.strictObject({title:e.string().optional(),desc:e.string().optional(),type:e.literal(b.CUSTOM),fn:e.any()})),ss=w(e=>e.record(e.string(),e.union([qt(e),Zt(e),ts(e)])));class es extends N{argv;constructor(t){super(t.utils.config?.check,t.utils),this.utils.title="check",this.argv=t,this.schema=ss(this.utils.validate)}async#t(t,s){try{return await t}catch(i){s.error(this.utils.style.error.msg(i instanceof Error?i.message:JSON.stringify(i))),this.utils.exitWithError()}}async file(t){const s="[file]",i=this.utils.logGroup(t.title);i.info(s,t.desc||"");const a=await this.utils.getPaths(t.patterns,{onlyFiles:!0});if(!a.length){i.warn(s,"No files matched the patterns");return}if(!t.validateAll&&!t.validate){i.warn(s,"Skipped because no validate function exists");return}t.validateAll&&await this.#t(t.validateAll({paths:a,utils:this.utils}),i),t.validate&&await At(t.patterns,{hook:{onFile:async({path:o,content:r})=>{await this.#t(t.validate?.({path:o,content:r.toString(),utils:this.utils}),i)}}}),i.success(s,"All file checks passed")}async dir(t){const s="[dir]",i=this.utils.logGroup(t.title);i.info(s,t.desc||"");const a=await this.utils.getPaths(t.patterns,{onlyDirectories:!0});if(!a.length){i.warn(s,"No directories matched the patterns");return}if(!t.validateAll&&!t.validate){i.warn(s,"Skipped because no validate function exists");return}t.validateAll&&await this.#t(t.validateAll({paths:a,utils:this.utils}),i),t.validate&&await Promise.all(a.map(o=>this.#t(t.validate?.({path:o,utils:this.utils}),i))),i.success(s,"All directory checks passed")}async custom(t){const s="[custom]",i=this.utils.logGroup(t.title);i.info(s,t.desc||""),await this.#t(t.fn({utils:this.utils,run:{dir:this.dir.bind(this),file:this.file.bind(this)}}),i),i.success(s,"Check function succesfully passed")}async multiple(t){const s=this.getKeysFromArgv(Object.keys(t),this.argv);if(!s||!s.length)return;const i=this.utils.logGroup("Multiple checks");await Promise.all(s.map(async a=>{const o={title:a,...t[a]};o.type===b.DIR?await this.dir(o):o.type===b.FILE?await this.file(o):o.type===b.CUSTOM?await this.custom(o):i.warn(`Unexpected or not provided type in ${this.utils.style.badge(a)}`)})),i.step(),i.success("\u2728","Checks for "+this.utils.style.b(s.join(", "))+" passed successfully!")}async#s(){if(!await this.utils.ensureOpts({input:this.opts}))return;const t=this.opts||{};await this.validateSchema(t),await this.multiple(t)}async run(){return await this.utils.catchFn(this.#s())}}const is=e=>e.union([e.string(),e.number(),e.boolean(),e.record(e.string(),e.unknown())]),as=w(e=>e.record(e.string(),e.union([is(e),e.any()])));class os extends N{argv;constructor(t){super(t.utils.config?.const,t.utils),this.argv=t,this.utils.title="const",this.schema=as(this.utils.validate)}async#t(t){return await this.utils.getConsts(t)}async#s(t){const s=Object.keys(t),i=async r=>{const c=await this.#t(r);c&&(console.log(` `+this.utils.style.info.h1(r)),console.dir(c,{depth:1/0,colors:!0}))},a=this.argv&&this.argv.opts&&"key"in this.argv.opts&&Array.isArray(this.argv.opts.key)?Object.values(this.argv.opts.key):s,o=this.utils.getKeys({input:s,pattern:a});!o||!o.length||await Promise.all(o.map(r=>i(r)))}async get(){return await this.utils.getConsts(void 0)}async#e(){await this.utils.ensureOpts({input:this.opts})&&(await this.validateSchema(this.opts),await this.#s(this.opts||{}))}async run(){return await this.utils.catchFn(this.#e())}}const ns=w(e=>e.record(e.string(),e.strictObject({desc:e.string().optional(),input:e.array(e.string()).nonempty(),fn:e.any()})));class rs extends N{argv;constructor(t){super(t.utils.config?.transform,t.utils),this.argv=t,this.utils.title="transform",this.schema=ns(this.utils.validate).optional()}async#t(){const t=this.opts||{},s=this.getKeysFromArgv(Object.keys(t),this.argv);!s||!s.length||await Promise.all(s.map(async i=>{const a=this.utils.logGroup(i);a.info("\u{1F3C1}","Staring...");try{const o=t[i];if(!o.input)throw new Error("No inputs provided");const r=await this.utils.getPaths(o.input,{onlyFiles:!0,dot:!0});if(!r.length)throw new Error(`inputs [${o.input.join(", ")}] do not exist`);for(const c of r){const l=await Pt(c,"utf8");if(!o.fn)continue;const u=await o.fn({path:c,content:l,utils:this.utils});u&&(await xt(c,u),a.info(`[${c}] successfully transformed`))}a.success("Inputs successfully transformed")}catch(o){a.error("Transformation failed. "+(o instanceof Error?o.message:JSON.stringify(o))),this.utils.exitWithError()}}))}async#s(){await this.utils.ensureOpts({input:this.opts})&&(await this.validateSchema(this.opts),await this.#t())}async run(){return await this.utils.catchFn(this.#s())}}class cs{config;#t=Tt();dovenvConfigPath;constructor(t){this.config=t?.config}async run(t=[]){this.#t.hide();const{CMD:s,GLOBAL_OPTIONS:i,OPTIONS:a,BIN_NAME:o}=j;await q({args:t,opts:{[i.CONFIG.key]:{alias:i.CONFIG.alias,desc:"Dovenv configuration file path",type:"string"}},hook:async({cli:r,argv:c})=>{const l={[s.CHECK]:{desc:"Make rules from your workspaces files or directories",opts:{[a.KEY.key]:{alias:a.KEY.alias,desc:"Set key patterns for check",type:"array"}},fn:async d=>{await new es(d).run()}},[s.CONSTANTS]:{desc:"Constants of your workspace",cmds:{view:{desc:"View all constants"},add:{desc:"Add new constant"}},opts:{[a.KEY.key]:{alias:a.KEY.alias,desc:"Set key patterns of your constants for viewed",type:"array"}},examples:[{desc:"View all constants",cmd:"$0 const"},{desc:'View all constants less "pkg"',cmd:"$0 const -k '!pkg'"}],fn:async d=>{await new os(d).run()}},[s.TRANSFORM]:{desc:"Transform your workspaces paths",opts:{[a.KEY.key]:{alias:a.KEY.alias,desc:"Set key patterns of your transforms",type:"array"}},examples:[{desc:"Transform all",cmd:"$0 transform"},{desc:'Transforms all less "pkg"',cmd:"$0 transform -k '!pkg'"}],fn:async d=>{await new rs(d).run()}},[s.ALIASES]:{desc:`List aliases of your config. For execute use: ${o} x `,fn:async d=>{await new Z(d).run()}},[s.ALIAS_EXEC]:{desc:"Execute aliases of your config",settings:{core:!0,hide:!0},fn:async d=>{await new Z(d).run()}},[s.CONFIG]:{desc:"Show your config",settings:{hide:!0},fn:async({utils:d})=>{console.dir(d.config||{},{depth:1/0})}}},[u,g]=this.config?[void 0,{config:this.config,path:this.dovenvConfigPath}]:await v(Ht(c.config&&typeof c.config=="string"?c.config:void 0));(c[i.HELP.key]&&u||!c._.length&&u)&&r.showHelp("log"),u&&(console.error(` `+m.red(u.message)),f.exit(0));const n=g.config,p=new B(n);globalThis.DOVENV_CONFIG=Object.freeze(n),globalThis.DOVENV_UTILS=p,globalThis.DOVENV_CONFIG_PATH=g.path;const y=n.custom||void 0;return await new z(r,y?Jt(l,y):l,p).run(),r}})}}export{cs as D,G as P,T as V,Qt as c,W as g};