import fs from "fs" ; import path from "path" ; import { Options } from "yargs" ; import { omit } from "lodash" ; import { cmds } from "../src/cmds" ; import { ICliCommand } from "../src/util" ; import { globalOptions } from "../src/options" ; import { beaconOptions } from "../src/cmds/beacon/options" ; import { renderMarkdownSections , toMarkdownTable , IMarkdownSection } from "./markdown" ; const docsMarkdownPath = process . argv [ 2 ] ; if ( ! docsMarkdownPath ) throw Error ( "Run script with output path: 'ts-node docsgen docs/cli.md'" ) ; const docsString = renderMarkdownSections ( [ { title : "Command Line Reference" , body : "This reference describes the syntax of the Lodestar CLI commands and their options." , subsections : [ { title : "Global Options" , body : getOptionsTable ( globalOptions ) , } , ... cmds . map ( ( cmd ) => cmdToMarkdownSection ( cmd ) ) , ] , } , ] ) ; fs . mkdirSync ( path . parse ( docsMarkdownPath ) . dir , { recursive : true } ) ; fs . writeFileSync ( docsMarkdownPath , docsString ) ; /**
 * Parse an ICliCommand type recursively and output a IMarkdownSection
 */ function cmdToMarkdownSection ( cmd , parentCommand ? ) { const commandJson = [ parentCommand , cmd . command . replace ( "<command>" , "" ) ] . filter ( Boolean ) . join ( " " ) ; const body = [ cmd . describe ] ; if ( cmd . examples ) { body . push ( "**Examples**" ) ; for ( const example of cmd . examples ) { if ( example . command . startsWith ( "lodestar" ) ) example . command = `lodestar ${ example . command }` ; body . push ( example . description ) ; body . push ( `\`\`\` \n${ example . command }\n\`\`\`` ) ; } } if ( cmd . options ) { body . push ( "**Options**" ) ; if ( cmd . subcommands ) { body . push ( "The options below apply to all subcommands." ) ; } if ( cmds . some ( ( c ) => c . command === "beacon" ) && commandJson !== "beacon" && Object . keys ( beaconOptions ) . every ( ( key ) => cmd . options ! [ key ] ) ) { cmd . options = omit ( cmd . options , Object . keys ( beaconOptions ) ) ; body . push ( `Cmd \`${ commandJson }\` has all the options from the [\`beacon\` cmd](#beacon).` ) ; } body . push ( getOptionsTable ( cmd . options ) ) ; } return { title : `\`${ commandJson }\`` , body , subsections : ( cmd . subcommands || [ ] ) . map ( ( subcmd ) => cmdToMarkdownSection ( subcmd , commandJson ) ) , } ; } /**
 * Render a Yargs options dictionary to a markdown table
 */ function getOptionsTable ( options , { showHidden } = { } ) { const visibleOptions = Object . entries ( options ) . filter ( ( [ , opt ] ) => showHidden || ! opt . hidden ) ; if ( visibleOptions . length === 0 ) { return "" ; } return toMarkdownTable ( visibleOptions . map ( ( [ key , opt ] ) => ( { Option : `\`--${ key }\`` , Type : opt . type , Description : opt . description , Default : opt . defaultDescription || opt . default || "" , } ) ) , [ "Option" , "Type" , "Description" , "Default" ] ) ; }