mdat 0.2.0 → 0.3.1
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/bin/cli.js +303 -3
- package/dist/api.d.ts +7 -24
- package/dist/config.d.ts +33 -8
- package/dist/index.d.ts +4 -2
- package/dist/index.js +33 -3
- package/dist/readme/api.d.ts +13 -0
- package/dist/readme/rules/badges.d.ts +8 -0
- package/dist/readme/rules/banner.d.ts +7 -0
- package/dist/readme/rules/cli-help/index.d.ts +6 -0
- package/dist/readme/rules/cli-help/utilities/get-help-markdown.d.ts +4 -0
- package/dist/readme/rules/cli-help/utilities/help-cst-to-object.d.ts +35 -0
- package/dist/readme/rules/cli-help/utilities/help-object-to-markdown.d.ts +7 -0
- package/dist/readme/rules/cli-help/utilities/help-string-to-cst.d.ts +13 -0
- package/dist/readme/rules/cli-help/utilities/infer-command.d.ts +7 -0
- package/dist/readme/rules/code.d.ts +6 -0
- package/dist/readme/rules/contributing.d.ts +8 -0
- package/dist/readme/rules/footer.d.ts +11 -0
- package/dist/readme/rules/header.d.ts +11 -0
- package/dist/readme/rules/index.d.ts +71 -0
- package/dist/readme/rules/license.d.ts +8 -0
- package/dist/readme/rules/short-description.d.ts +8 -0
- package/dist/readme/rules/table-of-contents.d.ts +9 -0
- package/dist/readme/rules/title.d.ts +9 -0
- package/dist/readme/rules/tldraw.d.ts +6 -0
- package/dist/readme/rules/toc.d.ts +14 -0
- package/dist/utilities.d.ts +11 -0
- package/package.json +20 -8
- package/readme.md +504 -47
package/dist/index.js
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
-
import{defaultLoaders as
|
|
2
|
-
${JSON.stringify(
|
|
3
|
-
${JSON.stringify(
|
|
1
|
+
import{defaultLoaders as st}from"cosmiconfig";function H(t,e){let n=st[".json"],i=n(t,e);return Re(i)}function Re(t,e="",n={}){for(let[i,o]of Object.entries(t)){let a=e?`${e}.${i}`:i;typeof o=="object"&&o!==null&&!Array.isArray(o)?Re(o,a,n):o===null?n[a]="null":n[a]=o.toString()}return n}import{findUp as mt}from"find-up";import dt from"node:fs";import C from"node:path";import{packageUp as ct}from"package-up";import{isFileSync as Se}from"path-type";import{packageDirectory as ut}from"pkg-dir";import{log as ke}from"remark-mdat";import ft from"untildify";function pt(t,e){let n=e===0?1:Math.floor(Math.log10(Math.abs(e))+1);return t.toString().padStart(n,"0")}function z(t,e,n,i){let o=[];for(let[a,r]of t.entries()){let s=n&&t.length>1?`-${pt(a+1,t.length+1)}`:"",m=O(r,e,n,i,s);o.push(m)}return o}function O(t,e,n,i,o=""){let a=$e(t),r=e?$e(e):void 0;if(!Se(a))throw new Error(`Input file not found: "${a}"`);if(r){if(Se(r))throw new Error(`Output path must be a directory, received a file path: "${r}"`);dt.mkdirSync(r,{recursive:!0})}let s=n?C.basename(n,C.extname(n)):C.basename(a,C.extname(a)),m=`.${i??(n&&C.extname(n)!==""?C.extname(n):C.extname(t)===""?"":C.extname(t))}`,d=`${s}${o}${m}`,u=r??C.dirname(a);return{input:a,name:d,output:u}}function $e(t){return ft(t)}async function Ee(){ke.info("Searching for package directory...");let t=await ut()??process.cwd(),e=await mt("readme.md",{stopAt:t,type:"file"});if(e!==void 0)return ke.info(`Found closest readme at "${e}"`),e}async function xe(){return ct()}import Ne from"chalk";import{cosmiconfig as Oe}from"cosmiconfig";import lt from"node:fs/promises";import Te from"node:path";import gt from"plur";import{readPackage as ht}from"read-pkg";import{deepMergeDefined as q,log as g,optionsSchema as yt,rulesSchema as wt}from"remark-mdat";import{z as L}from"zod";var Le=yt.merge(L.object({assetsPath:L.string().optional(),packageFile:L.string().optional(),readmeFile:L.string().optional()})).describe("Config Extension");async function h(t){let{additionalConfig:e,additionalRules:n,searchFrom:i}=t??{},o={addMetaComment:!1,assetsPath:"./assets",closingPrefix:"/",keywordPrefix:"",metaCommentIdentifier:"+",packageFile:await xe(),readmeFile:await Ee(),rules:{mdat:"Powered by the Markdown Autophagic Template system: [mdat](https://github.com/kitschpatrol/mdat)."}},a=Oe("mdat"),r=await a.search(i);if(r){let{config:s,filepath:m}=r;g.info(`Using config from "${m}"`);let d=Fe(s,Le);d&&(o=q(o,d))}if(e!==void 0){let s=Array.isArray(e)?e:[e];for(let m of s){let d;if(typeof m=="string"){let f=await a.load(m);if(f==null)continue;let{config:p,filepath:w}=f;g.info(`Loaded additional config from "${w}"`),d=p}else d=m;if(d===void 0)continue;g.info("Merging configuration object");let u=Fe(d,Le);u!==void 0&&(o=q(o,u))}}if(n!==void 0){let s=Array.isArray(n)?n:[n],m=Oe("mdat",{loaders:{".json":H}});for(let d of s){let u;if(typeof d=="string"){let p;if(Te.basename(d).endsWith("package.json")){let at=await lt.readFile(d,"utf8");p={config:H(d,at),filepath:d}}else p=await m.load(d);if(p==null)continue;let{config:w,filepath:b}=p;g.info(`Loaded additional config from "${b}"`),u=w}else u=d;if(u===void 0)continue;g.info("Merging rules into configuration object");let f=Ct(u,wt);f!==void 0&&(o=q(o,f))}}if(o.rules){let s=Object.keys(o.rules).sort().map(m=>`"${Ne.bold.green(m)}"`);g.info(`Loaded ${Ne.bold(s.length)} mdat comment expansion ${gt("rule",s.length)}:`);for(let m of s)g.info(` ${m}`)}else g.error("No rules loaded from additional configurations or rules, using default.");return F=o,o}function Ct(t,e){if(e.safeParse(t).success)return{rules:t};g.error(`Rules object has the wrong shape. Ignoring and using default configuration:
|
|
2
|
+
${JSON.stringify(t,void 0,2)}`)}function Fe(t,e){if(e.safeParse(t).success)return t;g.error(`Config object has the wrong shape. Ignoring and using default configuration:
|
|
3
|
+
${JSON.stringify(t,void 0,2)}`)}var F;async function R(){return F===void 0&&(g.warn("getConfig(): config was undefined"),F??=await h()),F}var W;async function l(){let{packageFile:t}=await R();if(t===void 0)throw new Error("No packageFile found or set in config");if(W??=await ht({cwd:Te.dirname(t)}),W===void 0)throw new Error("No package.json found");return W}import{remark as Ae}from"remark";import je from"remark-gfm";import{mdatClean as Pt,mdatSplit as bt,default as Rt}from"remark-mdat";import{read as T}from"to-vfile";import{VFile as Me}from"vfile";async function St(t,e,n,i,o){let a=await h({additionalConfig:i,additionalRules:o});i=a;let r=z(t,n,e,"md"),s=[],m=Z(a);for(let{input:d,name:u,output:f}of r){let p=await T(d),w=await m.process(p);w.dirname=f,w.basename=u,s.push(w)}return s}async function Y(t,e,n,i,o){let a=await h({additionalConfig:i,additionalRules:o});i=a;let r=O(t,n,e,"md"),s=await T(r.input),m=await Z(a).process(s);return m.dirname=r.output,m.basename=r.name,m}async function K(t,e,n){let i=await h({additionalConfig:e,additionalRules:n});return e=i,Z(i).process(new Me(t))}async function kt(t,e,n,i){let o=await h({additionalConfig:i});i=o;let a=z(t,n,e,"md"),r=[],s=Q(o);for(let{input:m,name:d,output:u}of a){let f=await T(m),p=await s.process(f);p.dirname=u,p.basename=d,r.push(p)}return r}async function G(t,e,n,i){let o=await h({additionalConfig:i});i=o;let a=O(t,n,e,"md"),r=await T(a.input),s=await Q(o).process(r);return s.dirname=a.output,s.basename=a.name,s}async function $t(t,e){let n=await h({additionalConfig:e});return e=n,Q(n).process(new Me(t))}function Z(t){return Ae().use({settings:{bullet:"-",emphasis:"_"}}).use(je).use(Rt,t??{})}function Q(t){let{closingPrefix:e,keywordPrefix:n,metaCommentIdentifier:i}=t;return Ae().use({settings:{bullet:"-",emphasis:"_"}}).use(je).use(()=>function(a,r){bt(a,r),Pt(a,r,{closingPrefix:e,keywordPrefix:n,metaCommentIdentifier:i})})}import{z as x}from"zod";var A={badges:{async content(t){var r;let e=x.object({custom:x.record(x.object({image:x.string(),link:x.string()})).optional()}).optional().parse(t),n=await l(),{name:i}=n,o=[];!n.private&&((r=n.publishConfig)==null?void 0:r.access)==="public"&&o.push(`[](https://npmjs.com/package/${i})`);let{license:a}=n;if(a!==void 0&&o.push(`[](https://opensource.org/licenses/${a})`),(e==null?void 0:e.custom)!==void 0)for(let[s,{image:m,link:d}]of Object.entries(e.custom))o.push(`[](${d})`);return o.join(`
|
|
4
|
+
`)},order:3,required:!1}};import{globby as Et}from"globby";import j from"node:path";import{isFile as xt}from"path-type";import{readPackage as Nt}from"read-pkg";import{z as X}from"zod";async function Ot(t){let{packageFile:e}=await R();if(e===void 0)throw new Error("No package.json found");let n=j.dirname(e),i=t===void 0?[".","assets","media","readme-assets","readme-media","readme","images"]:[t],o=["banner","header","logo","readme","cover","screenshot","screenshots","demo","overview","image","hero"],a=["png","gif","jpg","jpeg","svg","webp"],r=await Et(i.map(s=>j.join(n,s)),{expandDirectories:{extensions:a,files:o}});if(r.length>0)return j.relative(process.cwd(),r[0])}var M={banner:{async content(t){let e=X.object({alt:X.string().optional(),src:X.string().optional()}).optional().parse(t),{assetsPath:n,packageFile:i}=await R();if(i===void 0)throw new Error("No package.json found");let o=(e==null?void 0:e.src)??await Ot(n);if(o===void 0||!await xt(o))throw new Error(`Banner image not found at ${o===void 0?"any typical location, consider adding something at ./assets/banner.webp":`"${o}"`}`);let a=(e==null?void 0:e.alt)??`${(await Nt({cwd:j.dirname(i)})).name} banner`;if(a===void 0||a==="undefined banner")throw new Error("Banner image alt text not available");return``},order:2}};import{CstParser as Lt,Lexer as S,createToken as c}from"chevrotain";var ne=c({name:"flag",pattern:/--[\w-_]+/}),oe=c({name:"alias",pattern:/-[A-Za-z]/}),ve=c({group:S.SKIPPED,name:"comma",pattern:/,/}),$=c({name:"word",pattern:/\S+/}),N=c({name:"argument",pattern:/<\S+>|\[\S+]/}),ie=c({name:"type",pattern:/\[(boolean|string|array)]/}),re=c({name:"defaultInfo",pattern:/\[default]/}),ae=c({name:"required",pattern:/\[required]/}),se=c({name:"defaultInfoDescription",pattern:/\[default:\s.+?]/}),me=c({name:"choices",pattern:/\[choices:\s.+?]/}),ee=c({group:S.SKIPPED,name:"whiteSpace",pattern:/\s/}),De=c({group:S.SKIPPED,name:"startProgramDescription",pattern:/\n\n/,push_mode:"PROGRAM_DESCRIPTION_MODE"}),de=c({name:"programDescription",pattern:/.+/}),Ue=c({group:S.SKIPPED,name:"endProgramDescription",pattern:/\n\n/,pop_mode:!0}),ce=c({name:"startOptionsSection",pattern:/Options:\n/,push_mode:"SECTION_MODE"}),ue=c({name:"startPositionalsSection",pattern:/Positionals:\n/,push_mode:"SECTION_MODE"}),fe=c({name:"startCommandsSection",pattern:/Commands:\n/,push_mode:"SECTION_MODE"}),pe=c({name:"startRow",pattern:/ {2,}/,push_mode:"ROW_MODE"}),le=c({name:"rowDescription",pattern:/ {2}\w.+ {2}/}),ge=c({name:"rowDescriptionTerminal",pattern:/ {2}\w.+/}),_e=c({group:S.SKIPPED,name:"endRow",pattern:/\n/,pop_mode:!0}),Ie=c({group:S.SKIPPED,name:"endSection",pattern:/\n+/,pop_mode:!0}),Ft=new S({defaultMode:"DEFAULT_MODE",modes:{DEFAULT_MODE:[ce,ue,fe,De,N,$,ee],PROGRAM_DESCRIPTION_MODE:[Ue,de],ROW_MODE:[_e,ve,ie,le,ge,se,re,ae,me,ne,oe,N,$,ee],SECTION_MODE:[pe,Ie]}}),Tt=[ne,oe,ve,$,N,ie,re,ae,se,me,ee,De,de,Ue,ce,ue,fe,pe,le,ge,_e,Ie];function At(t){return Ft.tokenize(t.trim())}var te=class extends Lt{programHelp=this.RULE("programHelp",()=>{this.AT_LEAST_ONE(()=>{this.CONSUME($,{LABEL:"commandName"})}),this.MANY1(()=>{this.CONSUME(N)}),this.OPTION(()=>{this.CONSUME(de,{LABEL:"description"})}),this.OPTION1(()=>{this.SUBRULE(this.commandsSection)}),this.OPTION2(()=>{this.SUBRULE(this.positionalsSection)}),this.OPTION3(()=>{this.SUBRULE(this.optionsSection)})});positionalsSection=this.RULE("positionalsSection",()=>{this.CONSUME(ue),this.MANY(()=>{this.SUBRULE(this.sectionRow)})});commandsSection=this.RULE("commandsSection",()=>{this.CONSUME(fe),this.MANY1(()=>{this.SUBRULE1(this.sectionRow)})});optionsSection=this.RULE("optionsSection",()=>{this.CONSUME(ce),this.MANY2(()=>{this.SUBRULE2(this.sectionRow)})});sectionRow=this.RULE("sectionRow",()=>{this.CONSUME(pe),this.OPTION(()=>{this.CONSUME($,{LABEL:"parentCommandName"})}),this.MANY(()=>{this.CONSUME1($,{LABEL:"commandName"})}),this.MANY1(()=>{this.OR([{ALT:()=>this.CONSUME(N)},{ALT:()=>this.CONSUME(oe)},{ALT:()=>this.CONSUME(ne)},{ALT:()=>this.CONSUME(le,{LABEL:"description"})},{ALT:()=>this.CONSUME(ge,{LABEL:"description"})},{ALT:()=>this.CONSUME(ie)},{ALT:()=>this.CONSUME(ae)},{ALT:()=>this.CONSUME(se)},{ALT:()=>this.CONSUME(re)},{ALT:()=>this.CONSUME(me)}])})});constructor(){super(Tt),this.performSelfAnalysis()}},k=new te;function Ve(t){let e=At(t);k.input=e.tokens;let n=k.programHelp();if(k.errors.length>0)throw new Error(`Errors parsing CLI command help text output: ${JSON.stringify(k.errors,void 0,2)}`);return n}var he=class extends k.getBaseCstVisitorConstructor(){constructor(){super(),this.validateVisitor()}programHelp(e){let{command:n,subcommand:i}=Mt(this.getString(e.commandName));return{arguments:this.getArray(e.argument),commandName:n,commands:e.commandsSection?this.visit(e.commandsSection):void 0,description:this.getString(e.description),options:e.optionsSection?this.visit(e.optionsSection):void 0,positionals:e.positionalsSection?this.visit(e.positionalsSection):void 0,subcommandName:i}}positionalsSection(e){return e.sectionRow.map(n=>this.positionalParentCommandToArguments(this.visit(n)))}commandsSection(e){return e.sectionRow.map(n=>this.visit(n))}optionsSection(e){return e.sectionRow.map(n=>this.visit(n))}sectionRow(e){return{aliases:this.getArray(e.alias),arguments:this.getArray(e.argument),choices:this.splitChoices(this.getString(e.choices)),commandName:this.getString(e.commandName),default:e.defaultInfo?!0:void 0,defaultValue:this.getString(e.defaultInfoDescription,!0),description:this.getString(e.description,!0),flags:this.getArray(e.flag),parentCommandName:this.getString(e.parentCommandName),required:e.required?!0:void 0,type:this.getString(e.type,!0)}}positionalParentCommandToArguments(e){let{arguments:n,parentCommandName:i,...o}=e;return i===void 0?e:{arguments:[i,...n??[]],...o}}getString(e,n=!1){if(e!==void 0)return e.map(i=>n?this.clean(i.image):i.image).join(" ")}getArray(e){if(e!==void 0)return e.map(n=>n.image)}clean(e){return e.replaceAll(/^[\s[]*(default:)?\s*|[\s\]]*$/g,"")}splitChoices(e){if(e!==void 0)return this.clean(e.replaceAll(/^\[choices:\s/g,"")).split(", ")}},jt=new he;function Je(t){return jt.visit(t)}function Mt(t){if(t===void 0)throw new Error('Could not find "commandName" entry in help');let e=t.split(" ");if(e.length===0&&t===void 0)throw new Error('Could not find "commandName" entry in help');if(e.length===1)return{command:e[0],subcommand:void 0};let n=e.at(-1);return{command:e.slice(0,-1).join(" "),subcommand:n}}function Be(t,e=!1){var i,o,a;let n=[];if(e){let r=(i=t.commands)==null?void 0:i.find(d=>d.default),s=(o=t.commands)==null?void 0:o.find(d=>d.commandName===void 0),m=`${t.commandName}${t.subcommandName?` ${t.subcommandName}`:""}`;n.push(`#### Command: \`${m}\``),s!=null&&s.description&&n.push(s==null?void 0:s.description),n.push(`This section lists top-level commands for \`${m}\`.`),r&&n.push(`If no command is provided, \`${r.parentCommandName} ${r.commandName}\` is run by default.`),n.push("Usage:"),s&&n.push(`\`\`\`txt
|
|
5
|
+
${s.parentCommandName}${s.arguments?` ${s.arguments.join(" ")}`:""}
|
|
6
|
+
\`\`\``),t.commands=(a=t.commands)==null?void 0:a.filter(d=>d!==s)}else n.push(`#### Subcommand: \`${t.commandName} ${t.subcommandName}\``),n.push(t.description),n.push("Usage:"),n.push(`\`\`\`txt
|
|
7
|
+
${t.commandName} ${t.subcommandName}${t.arguments?` ${t.arguments.join(" ")}`:""}
|
|
8
|
+
\`\`\``);return t.positionals&&!e&&n.push(ye(["Positional Argument","Description","Type","Default"],t.positionals.map(r=>[r.arguments?[r.arguments.map(s=>`\`${s}\``)].join(" "):"",`${r.description??""}${r.required?" _(Required.)_":" _(Optional.)_"}`,r.type?`\`${r.type}\``:"",r.defaultValue?r.defaultValue.includes(" ")?r.defaultValue:`\`${r.defaultValue}\``:""]))),t.commands&&n.push(ye(["Command","Argument","Description"],t.commands.map(r=>{var s;return[`\`${r.commandName??(r.default?"[default]":"")}\``,r.arguments?(s=r.arguments)==null?void 0:s.map(m=>`\`${m}\``).join(" "):"",`${r.description??""}${r.default?" _(Default command.)_":""}`]}))),t.options&&!e&&n.push(ye(["Option","Alias","Argument","Description","Type","Default"],t.options.map(r=>[r.flags?r.flags.map(s=>`\`${s}\``).join(" "):"",r.aliases?r.aliases.map(s=>`\`${s}\``).join(" "):"",r.arguments?r.arguments.map(s=>`\`${s}\``).join(" "):"",r.description??"",r.type?`\`${r.type}\``:"",r.defaultValue?r.defaultValue.includes(" ")?r.defaultValue:`\`${r.defaultValue}\``:""]))),e&&n.push("_See the sections below for more information on each subcommand._"),n.join(`
|
|
9
|
+
|
|
10
|
+
`)}function ye(t,e){let n=vt(e);t=t.filter((o,a)=>!n.includes(a)),e=e.map(o=>o.filter((a,r)=>!n.includes(r)));let i="";i+=`| ${t.join(" | ")} |
|
|
11
|
+
`,i+=`| ${t.map(()=>"---").join(" | ")} |
|
|
12
|
+
`;for(let o of e)i+=`| ${o.join(" | ")} |
|
|
13
|
+
`;return i}function vt(t){var i;let e=[],n=((i=t[0])==null?void 0:i.length)||0;for(let o=0;o<n;o++){let a=!0;for(let r of t)if(r[o]!==""){a=!1;break}a&&e.push(o)}return e}import{execaCommand as Dt}from"execa";import{log as He}from"remark-mdat";async function we(t){let e=`${t} --help`,n;try{let{stderr:o,stdout:a}=await Dt(e);n=a,(n===void 0||n==="")&&(n=o)}catch(o){if(o instanceof Error)throw new TypeError(`Error running CLI help command: ${e}
|
|
14
|
+
${o.message}
|
|
15
|
+
`)}if(n===void 0||n==="")throw new Error(`No result from running CLI help command: ${e}
|
|
16
|
+
`);let i;try{let o=Ve(n);i=Je(o)}catch(o){o instanceof Error&&(i=void 0,He.warn(`Error parsing help output for command: ${t}
|
|
17
|
+
${o.message}`),He.warn("Falling back to basic cli help text output."))}return i===void 0?_t(n):Ut(t,i)}async function Ut(t,e){let n=(e.commands&&e.commands.some(a=>a.default))??!1,i=Be(e,n),o=t.split(" ")[0];if(e.commands)for(let a of e.commands){if(!a.parentCommandName||!a.commandName)continue;let r=await we(`${o} ${a.commandName}`);i+=`
|
|
18
|
+
|
|
19
|
+
${r}`}return i}function _t(t){return`\`\`\`txt
|
|
20
|
+
${t}
|
|
21
|
+
\`\`\``}import{isExecutable as It}from"is-executable";import Vt from"node:path";import{log as Jt}from"remark-mdat";import Bt from"which";async function ze(t){return t??=await Ht(),qt(t)}async function Ht(){let t=await l();if(t!=null&&t.bin){let e=typeof t.bin=="string"?t.bin:String(Object.values(t.bin).at(0));if(zt(e))return Jt.info(`Inferred <!-- cli-help --> command to run from package.json: ${e}`),e}throw new Error(`Could not infer which command to run for the <!-- cli-help --> rule. Please pass a "cliCommand" option to the expansion comment, e.g. <!-- cli-help {cliCommend: './dist/bin.js'} -->`)}function zt(t){let e=Vt.parse(t);return e.root!==""||e.dir!==""}async function qt(t){let e=await Bt(t,{nothrow:!0});if(e===null&&(e=await Wt(t)??void 0),e!==void 0&&await It(e))return e;throw new Error(`The cli-help rule noticed that "${e}" is not executable.`)}async function Wt(t){var n;let e=await l();return((n=e==null?void 0:e.bin)==null?void 0:n[t])??void 0}import{z as qe}from"zod";var We={"cli-help":{async content(t){let e=qe.object({cliCommand:qe.string().optional()}).optional().parse(t),n=await ze(e==null?void 0:e.cliCommand);return we(n)}}};import Yt from"node:fs/promises";import Ye from"node:path";import{z as Ce}from"zod";var Ke={code:{async content(t){let e=Ce.object({file:Ce.string(),language:Ce.string().optional()}).parse(t),n=Ye.extname(e.file)??"",i=await Yt.readFile(Ye.join(process.cwd(),e.file),"utf8");return`\`\`\`${n}
|
|
22
|
+
${i}
|
|
23
|
+
\`\`\``}}};var v={contributing:{async content(){var n;let t=await l(),e=(n=t==null?void 0:t.bugs)==null?void 0:n.url;if(e===void 0)throw new Error('Could not find "bugs.url" entry in package.json');return`## Contributing
|
|
24
|
+
[Issues](${e}) and pull requests are welcome.`},order:15,required:!0}};var D={license:{async content(){let t=await l(),{author:e,license:n}=t;if((e==null?void 0:e.name)===void 0)throw new Error('Could not find "author.name" entry in package.json');if(n===void 0)throw new Error('Could not find "license" entry in package.json');return`## License
|
|
25
|
+
[${n}](license.txt) \xA9 ${e.name}`},order:16,required:!0}};import{getSoleRule as Ge}from"remark-mdat";var Ze={footer:{content:[Ge(v),Ge(D)],order:17}};var U={"short-description":{async content(){let t=await l();if(t.description===void 0)throw new Error('Could not find "description" entry in package.json');return`**${t.description}**`},order:4,required:!0}};import{z as _}from"zod";var I={title:{applicationOrder:2,async content(t){let{postfix:e,prefix:n,titleCase:i}=_.object({postfix:_.string().optional().default(""),prefix:_.string().optional().default(""),titleCase:_.boolean().optional().default(!1)}).parse(t??{}),{name:o}=await l();return`# ${n}${i?Kt(o):o}${e}`},order:1,required:!0}};function Kt(t){return t.split(/[ _-]/).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}import{getSoleRule as V}from"remark-mdat";var Qe={header:{applicationOrder:2,content:[V(I),V(M),V(A),V(U)],order:1}};import{toc as Gt}from"mdast-util-toc";import{remark as Zt}from"remark";import Qt from"remark-gfm";import{z as P}from"zod";var J={"table-of-contents":{applicationOrder:1,async content(t,e){let n=P.object({maxDepth:P.union([P.literal(1),P.literal(2),P.literal(3),P.literal(4),P.literal(5),P.literal(6)]).optional()}).optional().parse(t),i=Gt(e,{heading:null,maxDepth:(n==null?void 0:n.maxDepth)??3,tight:!0}),o="## Table of contents";if(i.map===void 0)throw new Error("Could not generate table of contents");let a={children:i.map.children,type:"root"},r=Zt().use(Qt).stringify(a).replaceAll(`
|
|
26
|
+
|
|
27
|
+
`,`
|
|
28
|
+
`);return[o,r].join(`
|
|
29
|
+
`)},order:6}};import{tldrawToImage as Xe}from"@kitschpatrol/tldraw-cli";import Xt from"node:crypto";import E from"node:fs/promises";import y from"node:path";import{isFile as Pe}from"path-type";import{z as be}from"zod";var ot={tldraw:{async content(t){let{alt:e="tldraw diagram",src:n}=be.object({alt:be.string().optional(),src:be.string()}).parse(t),{assetsPath:i}=await R();if(i===void 0)throw new Error("No assets path found");await E.mkdir(i,{recursive:!0});let o=await Pe(n)?await tt(n):void 0;if(o!==void 0){let d=y.basename(n,y.extname(n)),u=y.join(i,`${d}-${o}-light.svg`),f=y.join(i,`${d}-${o}-dark.svg`);if(await Pe(u)&&await Pe(f))return et(u,f,e)}let[a]=await Xe(n,{dark:!1,format:"svg",output:i,transparent:!0});o??=await tt(a);let r=`${nt(a)}-${o}-light.svg`;await E.rename(a,r);let[s]=await Xe(n,{dark:!0,format:"svg",output:i,transparent:!0}),m=`${nt(s)}-${o}-dark.svg`;if(await E.rename(s,m),o!==void 0){let d=y.basename(m),u=y.basename(r),f=u.replace(`${o}-light.svg`,""),p=await E.readdir(i);for(let w of p){let b=y.basename(w);b!==d&&b!==u&&b.startsWith(f)&&b.endsWith(".svg")&&await E.rm(y.join(i,b))}}return et(r,m,e)}}};async function et(t,e,n){let{readmeFile:i}=await R();if(i===void 0)throw new Error("No readme file found");let o=y.dirname(i),a=y.relative(o,t);return`<picture>
|
|
30
|
+
<source media="(prefers-color-scheme: dark)" srcset="${y.relative(o,e)}">
|
|
31
|
+
<source media="(prefers-color-scheme: light)" srcset="${a}">
|
|
32
|
+
<img alt="${n}" src="${a}">
|
|
33
|
+
</picture>`}async function tt(t){let e=await E.readFile(t),n=Xt.createHash("sha1");return n.update(e),n.digest("hex").slice(0,8)}function nt(t){return t.replace(/\.[^./]+$/,"")}import{getSoleRule as en}from"remark-mdat";var it={toc:{applicationOrder:1,content:[en(J)]}};var rt={...A,...M,...We,...Ke,...v,...Ze,...Qe,...D,...U,...J,...ot,...it,...I};async function tn(t,e,n,i){let o=await B({additionalConfig:n,additionalRules:i});return Y(o.readmeFile,t,e,o)}async function nn(t,e,n){let i=await B({additionalConfig:e,additionalRules:n});return K(t,i)}async function on(t){let e=await B({additionalConfig:t});return G(e.readmeFile,void 0,void 0,e)}async function B(t){let e={addMetaComment:!0,rules:rt},{additionalConfig:n=[],...i}=t??{},o=Array.isArray(n)?n:[n],a=await h({additionalConfig:[e,...o],...i});if(a.packageFile===void 0||a.readmeFile===void 0)throw new Error("Package and readme files are required in `mdat readme` config");return a}export{G as cleanFile,kt as cleanFiles,on as cleanReadme,$t as cleanString,Y as expandFile,St as expandFiles,tn as expandReadme,nn as expandReadmeString,K as expandString,h as loadConfig,B as loadConfigReadme};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ConfigLoaded, type ConfigToLoad, type RulesToLoad, loadConfig } from '../config';
|
|
2
|
+
import { type Simplify } from 'type-fest';
|
|
3
|
+
import { type VFile } from 'vfile';
|
|
4
|
+
type ReadmeConfigLoaded = Simplify<{
|
|
5
|
+
packageFile: string;
|
|
6
|
+
readmeFile: string;
|
|
7
|
+
} & ConfigLoaded>;
|
|
8
|
+
export declare function expandReadme(name?: string, output?: string, config?: ConfigToLoad, rules?: RulesToLoad): Promise<VFile>;
|
|
9
|
+
export declare function expandReadmeString(markdown: string, config?: ConfigToLoad, rules?: RulesToLoad): Promise<VFile>;
|
|
10
|
+
export declare function cleanReadme(config?: ConfigToLoad): Promise<VFile>;
|
|
11
|
+
type LoadConfigOptions = Parameters<typeof loadConfig>[0];
|
|
12
|
+
export declare function loadConfigReadme(options?: LoadConfigOptions): Promise<ReadmeConfigLoaded>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type CstNode } from 'chevrotain';
|
|
2
|
+
type Command = {
|
|
3
|
+
arguments?: string[];
|
|
4
|
+
commandName?: string;
|
|
5
|
+
default?: boolean;
|
|
6
|
+
description?: string;
|
|
7
|
+
parentCommandName?: string;
|
|
8
|
+
};
|
|
9
|
+
type Positional = {
|
|
10
|
+
arguments?: string[];
|
|
11
|
+
defaultValue?: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
required?: boolean;
|
|
14
|
+
type?: string;
|
|
15
|
+
};
|
|
16
|
+
type Option = {
|
|
17
|
+
aliases?: string[];
|
|
18
|
+
arguments?: string[];
|
|
19
|
+
choices?: string[];
|
|
20
|
+
defaultValue?: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
flags?: string[];
|
|
23
|
+
type?: string;
|
|
24
|
+
};
|
|
25
|
+
export type ProgramInfo = {
|
|
26
|
+
arguments?: string[];
|
|
27
|
+
commandName: string;
|
|
28
|
+
commands?: Command[];
|
|
29
|
+
description?: string;
|
|
30
|
+
options?: Option[];
|
|
31
|
+
positionals?: Positional[];
|
|
32
|
+
subcommandName?: string;
|
|
33
|
+
};
|
|
34
|
+
export declare function helpCstToObject(cst: CstNode): ProgramInfo;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ProgramInfo } from './help-cst-to-object';
|
|
2
|
+
/**
|
|
3
|
+
* Simple case without subcommands
|
|
4
|
+
* @param programInfo - a ProgramInfo object, likely output from helpCstToObject()
|
|
5
|
+
* @returns - markdown string with help in table form, ready to be rendered
|
|
6
|
+
*/
|
|
7
|
+
export declare function helpObjectToMarkdown(programInfo: ProgramInfo, commandsOnly?: boolean): string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type CstNode, CstParser, type ILexingResult } from 'chevrotain';
|
|
2
|
+
export declare function tokenizeHelp(text: string): ILexingResult;
|
|
3
|
+
declare class CliParser extends CstParser {
|
|
4
|
+
programHelp: import("chevrotain").ParserMethod<[], CstNode>;
|
|
5
|
+
private readonly positionalsSection;
|
|
6
|
+
private readonly commandsSection;
|
|
7
|
+
private readonly optionsSection;
|
|
8
|
+
private readonly sectionRow;
|
|
9
|
+
constructor();
|
|
10
|
+
}
|
|
11
|
+
export declare const parser: CliParser;
|
|
12
|
+
export declare function helpStringToCst(text: string): CstNode;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accommodate missing or sloppy cli help command input
|
|
3
|
+
* @param cliCommand - Can be nothing, a command name on the path like `git`, or a path to an executable like `./bin/cli.js`
|
|
4
|
+
* @returns The path to a verified executable
|
|
5
|
+
* @throws If nothing can be inferred or resolved
|
|
6
|
+
*/
|
|
7
|
+
export declare function inferCommand(cliCommand: string | undefined): Promise<string>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
title: {
|
|
3
|
+
applicationOrder: number;
|
|
4
|
+
content(options?: import("type-fest").JsonValue | undefined): Promise<string>;
|
|
5
|
+
order: number;
|
|
6
|
+
required: true;
|
|
7
|
+
};
|
|
8
|
+
toc: {
|
|
9
|
+
applicationOrder: number;
|
|
10
|
+
content: {
|
|
11
|
+
applicationOrder: number;
|
|
12
|
+
content(options: import("type-fest").JsonValue, tree: import("mdast").Root): Promise<string>;
|
|
13
|
+
order: number;
|
|
14
|
+
}[];
|
|
15
|
+
};
|
|
16
|
+
tldraw: {
|
|
17
|
+
content(options?: import("type-fest").JsonValue | undefined): Promise<string>;
|
|
18
|
+
};
|
|
19
|
+
'table-of-contents': {
|
|
20
|
+
applicationOrder: number;
|
|
21
|
+
content(options: import("type-fest").JsonValue, tree: import("mdast").Root): Promise<string>;
|
|
22
|
+
order: number;
|
|
23
|
+
};
|
|
24
|
+
'short-description': {
|
|
25
|
+
content(): Promise<string>;
|
|
26
|
+
order: number;
|
|
27
|
+
required: true;
|
|
28
|
+
};
|
|
29
|
+
license: {
|
|
30
|
+
content(): Promise<string>;
|
|
31
|
+
order: number;
|
|
32
|
+
required: true;
|
|
33
|
+
};
|
|
34
|
+
header: {
|
|
35
|
+
applicationOrder: number;
|
|
36
|
+
content: {
|
|
37
|
+
content(options?: import("type-fest").JsonValue | undefined): Promise<string>;
|
|
38
|
+
order: number;
|
|
39
|
+
}[];
|
|
40
|
+
order: number;
|
|
41
|
+
};
|
|
42
|
+
footer: {
|
|
43
|
+
content: {
|
|
44
|
+
content(): Promise<string>;
|
|
45
|
+
order: number;
|
|
46
|
+
required: true;
|
|
47
|
+
}[];
|
|
48
|
+
order: number;
|
|
49
|
+
};
|
|
50
|
+
contributing: {
|
|
51
|
+
content(): Promise<string>;
|
|
52
|
+
order: number;
|
|
53
|
+
required: true;
|
|
54
|
+
};
|
|
55
|
+
code: {
|
|
56
|
+
content(options: import("type-fest").JsonValue): Promise<string>;
|
|
57
|
+
};
|
|
58
|
+
'cli-help': {
|
|
59
|
+
content(options?: import("type-fest").JsonValue | undefined): Promise<string>;
|
|
60
|
+
};
|
|
61
|
+
banner: {
|
|
62
|
+
content(options?: import("type-fest").JsonValue | undefined): Promise<string>;
|
|
63
|
+
order: number;
|
|
64
|
+
};
|
|
65
|
+
badges: {
|
|
66
|
+
content(options?: import("type-fest").JsonValue | undefined): Promise<string>;
|
|
67
|
+
order: number;
|
|
68
|
+
required: false;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
export default _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple alias for table-of-contents
|
|
3
|
+
*/
|
|
4
|
+
declare const _default: {
|
|
5
|
+
toc: {
|
|
6
|
+
applicationOrder: number;
|
|
7
|
+
content: {
|
|
8
|
+
applicationOrder: number;
|
|
9
|
+
content(options: import("type-fest").JsonValue, tree: import("mdast").Root): Promise<string>;
|
|
10
|
+
order: number;
|
|
11
|
+
}[];
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export default _default;
|
package/dist/utilities.d.ts
CHANGED
|
@@ -9,3 +9,14 @@ export declare function getInputOutputPath(input: string, output: string | undef
|
|
|
9
9
|
output: string;
|
|
10
10
|
};
|
|
11
11
|
export declare function expandPath(file: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Searches for a readme file in the following order:
|
|
14
|
+
* 1. Searches the current working directly for readme.md
|
|
15
|
+
* 2. If there's no readme.md in the current directory, search up to the closest package directory
|
|
16
|
+
* 3. Give up and return undefined if no readme is found
|
|
17
|
+
*
|
|
18
|
+
* @returns The path to the readme file
|
|
19
|
+
* @throws If no readme is found
|
|
20
|
+
*/
|
|
21
|
+
export declare function findReadme(): Promise<string | undefined>;
|
|
22
|
+
export declare function findPackage(): Promise<string | undefined>;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mdat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "CLI tool and library for using comments as content templates in Markdown files.",
|
|
5
|
+
"description": "CLI tool and library for using comments as content templates in Markdown files, with helpful presets for readmes.",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git@github.com:kitschpatrol/mdat.git",
|
|
@@ -42,28 +42,40 @@
|
|
|
42
42
|
"cli"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
+
"@clack/prompts": "^0.7.0",
|
|
46
|
+
"@kitschpatrol/tldraw-cli": "^4.0.0",
|
|
45
47
|
"@types/mdast": "^4.0.3",
|
|
46
48
|
"@types/unist": "^3.0.2",
|
|
47
49
|
"chalk": "^5.3.0",
|
|
50
|
+
"chevrotain": "^11.0.3",
|
|
48
51
|
"cosmiconfig": "^9.0.0",
|
|
52
|
+
"execa": "^8.0.1",
|
|
53
|
+
"find-up": "^7.0.0",
|
|
54
|
+
"globby": "^14.0.0",
|
|
55
|
+
"is-executable": "^2.0.1",
|
|
56
|
+
"mdast-util-toc": "^7.0.0",
|
|
57
|
+
"nanoid": "^5.0.5",
|
|
58
|
+
"package-up": "^5.0.0",
|
|
49
59
|
"path-type": "^5.0.0",
|
|
60
|
+
"pkg-dir": "^8.0.0",
|
|
50
61
|
"plur": "^5.1.0",
|
|
51
62
|
"pretty-ms": "^9.0.0",
|
|
63
|
+
"read-pkg": "^9.0.1",
|
|
52
64
|
"remark": "^15.0.1",
|
|
53
65
|
"remark-gfm": "^4.0.0",
|
|
54
66
|
"to-vfile": "^8.0.0",
|
|
55
67
|
"type-fest": "^4.10.2",
|
|
56
68
|
"untildify": "^5.0.0",
|
|
57
69
|
"vfile": "^6.0.1",
|
|
70
|
+
"which": "^4.0.0",
|
|
58
71
|
"yargs": "^17.7.2",
|
|
59
72
|
"zod": "^3.22.4",
|
|
60
|
-
"remark-mdat": "0.
|
|
73
|
+
"remark-mdat": "0.3.1"
|
|
61
74
|
},
|
|
62
75
|
"devDependencies": {
|
|
63
|
-
"@types/node": "^20.11.
|
|
76
|
+
"@types/node": "^20.11.17",
|
|
77
|
+
"@types/which": "^3.0.3",
|
|
64
78
|
"@types/yargs": "^17.0.32",
|
|
65
|
-
"execa": "^8.0.1",
|
|
66
|
-
"nanoid": "^5.0.5",
|
|
67
79
|
"tsup": "^8.0.1",
|
|
68
80
|
"typescript": "^5.3.3",
|
|
69
81
|
"vitest": "^1.2.2"
|
|
@@ -74,8 +86,8 @@
|
|
|
74
86
|
"scripts": {
|
|
75
87
|
"build": "tsup && tsc -p tsconfig.build.json",
|
|
76
88
|
"dev": "pnpm run test",
|
|
77
|
-
"mdat": "
|
|
89
|
+
"mdat": "./bin/cli.js readme --config ../../mdat.config.ts",
|
|
78
90
|
"pretest": "pnpm run build",
|
|
79
|
-
"test": "vitest"
|
|
91
|
+
"test": "vitest -no-file-parallelism"
|
|
80
92
|
}
|
|
81
93
|
}
|