@dovenv/examples
Version:
Tools for Examples files/directories for dovenv
19 lines (11 loc) • 4.89 kB
JavaScript
import{validate as r,LazyLoader as L,ensureDir as S,getDirName as P,writeFile as I,getStringType as k,getBaseName as j,getExtName as C,getStringFrom as D,joinPath as J,deepmergeCustom as M,getObjectFrom as N,getPaths as U,readFiles as v,truncate as Y,getRandomUUID as _}from"@dovenv/core/utils";const A={CONFIG:"config",PATH:"path",JSDOC:"jsdoc",MULTIPLE:"multiple",CUSTOM:"custom"},G={__proto__:null,TYPE:A},H=r.object({input:r.string().describe("Example input. Can be a file or a string"),title:r.string().optional().describe("Example title"),type:r.string().optional().describe("Input type. For example: bash, js, ts etc"),desc:r.string().optional().describe("Example description"),outro:r.string().optional().describe("Example outro")}),R=r.object({title:r.string().optional().describe("Example title"),desc:r.string().optional().describe("Example description"),outro:r.string().optional().describe("Example outro"),data:r.record(r.string(),H)}),z=r.record(r.string(),R),B="https://dovenv.pigeonposse.com/guide/plugin/examples",K=new L({commentParser:async()=>(await import("comment-parser")).parse});class T{const=G;utils;opts;constructor(e){this.utils=e.utils,this.opts=e.opts,this.utils.helpURL=B,this.utils.title="examples"}async#t(e,t){t&&(await S(P(t)),await I(t,e))}#e(e){const{title:t="Examples",desc:n}=e;let a="";return t&&(a+=`# ${t}
`),n&&(a+=`${n}
`),a}async#s(e){const{data:t,header:n=2,path:a=this.utils.process.cwd(),step:i=`
`}=e,o="#".repeat(n)+" ";let l="";for(const[p,s]of Object.entries(t)){const c=e.contentType||k(s.input),u=s.desc?s.desc+i:"",g=s.outro?i+s.outro:"",f=(s.title||(c==="path"?j(s.input):p))+i,w=s.type||(c==="path"?C(s.input).replace(".",""):"markdown"),h=await D(c==="path"?J(a,s.input):s.input);l+=`${o}${f}${u}\`\`\`${w}
${h}
\`\`\`${g}${i}`}return l}async#i(e,t,n){let a=this.#e(n||{});for(const[i,o]of Object.entries(e)){const l=(o.title||i)+`
`,p=o.desc?o.desc+`
`:"",s=o.outro?`
`+o.outro:"",c=o.data?await this.#s({data:o.data,header:3,path:t}):"";a+=`## ${l}${p}${c}${s}
`}return a}async fromConfig(e){const{input:t,config:n,title:a,desc:i,output:o}=e,l=M({}),p=typeof t=="string"?await N(t):t,s=l(p,n||{}),c=typeof t=="string"?P(t):this.utils.process.cwd();await this.utils.validateSchema(z,s,{showValid:!0});const u=await this.#i(s,c,{title:a,desc:i});return await this.#t(u,o),u}async fromPath(e){const{output:t,title:n,desc:a,input:i,opts:o}=e,l=await U(i,o),p={};for(const c of l)p[c]={input:c};let s=this.#e({title:n,desc:a});return s+=await this.#s({data:p,path:o?.cwd?.toString(),contentType:"path"}),await this.#t(s,t),s}async fromJsdoc(e){const{output:t,input:n,title:a,desc:i,opts:o}=e,l=await K.get("commentParser");console.debug({data:e});const p={};await v(n,{inputOpts:o,hook:{onFile:async({content:u,path:g})=>{const f=l(u),w=j(g),h=C(g).replace(".","")||"js",$=["ts","mts","cts"].includes(h)?"ts":["js","jts","jts"].includes(h)?"js":h;for(const m of f){const y=m.tags.find(b=>b.tag==="example");if(y&&y.description){const b=m.tags.find(d=>d.tag==="name"),E=m.tags.find(d=>d.tag==="description"),F=m.description||b?.name||E?.name||w;p[_()]={input:y.source.map(d=>d.tokens.postDelimiter.substring(1)+d.tokens.description).join(`
`).trim(),desc:m.description||E?.description,type:$,title:Y(F,100)}}}}}}),console.debug({examples:p});const s=await this.#s({data:p});if(!s||s.trim()=="")return console.log(),console.warn(this.utils.style.warn.msg("No JSDOC examples retrived")),"";const c=this.#e({title:a,desc:i})+s;return await this.#t(c,t),c}async fromMultiple(e){const{output:t,title:n,desc:a,...i}=e;let o=this.#e({title:n,desc:a});if(!i)throw new Error("No input found for any type.");return i.config&&(o+=await this.fromConfig({title:!1,...i.config})),i.jsdoc&&(o+=await this.fromJsdoc({title:!1,...i.jsdoc})),i.path&&(o+=await this.fromPath({title:!1,...i.path})),await this.#t(o,t),o}async fromCustom(e){const t=this.const.TYPE;return await e.fn({config:this.utils.config||{},run:{[t.CONFIG]:this.fromConfig.bind(this),[t.PATH]:this.fromPath.bind(this),[t.JSDOC]:this.fromJsdoc.bind(this),[t.MULTIPLE]:this.fromMultiple.bind(this)}})}async get(e){const t=this.const.TYPE,{type:n,...a}=e,i={[t.CONFIG]:this.fromConfig.bind(this),[t.PATH]:this.fromPath.bind(this),[t.JSDOC]:this.fromJsdoc.bind(this),[t.MULTIPLE]:this.fromMultiple.bind(this),[t.CUSTOM]:this.fromCustom.bind(this)};if(i[n])return await i[n](a);throw new Error("You need to set one type: "+Object.values(t).join(", "))}async#o(e){return await this.utils.mapOpts({input:this.opts,pattern:e,cb:async({value:t})=>await this.get(t)})}async run(e){return await this.utils.catchFn(this.#o(e))}}const O=x=>({custom:{examples:{desc:"Toolkit for managing example paths",opts:{key:{alias:"k",desc:"Key pattern",type:"array"}},fn:async({utils:e,opts:t})=>{await new T({opts:x,utils:e}).run(t?.key)}}}});export{T as Examples,O as default,O as examplesPlugin};