Last active
June 13, 2023 19:55
-
-
Save dawaltconley/673a2e6eb7c45dde66e7ff5d84791f0a to your computer and use it in GitHub Desktop.
Generate markdown documentation from CloudFormation templates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @typedef {{ | |
* [Prop: string]: any; | |
* Default?: string | number; | |
* Description?: string; | |
* }} Parameter | |
*/ | |
/** | |
* @typedef {{ | |
* [Unused: string]: any; | |
* Type: string; | |
* Properties: Object; | |
* }} Resource | |
*/ | |
/** | |
* @typedef {Object} Output | |
* @property {string} [Output.Description] | |
* @property {string} [Output.Value] | |
* @property {string} [Output.Export] | |
*/ | |
/** | |
* @typedef {{ | |
* [Unused: string]: any; | |
* Description?: string; | |
* Parameters?: Object.<string, Parameter>; | |
* Resources?: Object.<string, Resource>; | |
* Outputs?: Object.<string, Output>; | |
* }} Template | |
*/ | |
const quote = (str) => `"${str}"`; | |
const list = (items, indent = 0) => | |
items | |
.map((item) => `${" ".repeat(indent)}- ${item}`) | |
.join("\n"); | |
const defineProperties = (props) => { | |
let defs = Object.entries(props) | |
.map(([property, value]) => { | |
if (value === "") value = quote(value); | |
if (property === "AllowedValues") { | |
return `${property}:\n${list(value, 2)}`; | |
} | |
return `${property}: ${value}`; | |
}); | |
defs = list(defs); | |
return defs; | |
}; | |
/** | |
* Takes a title and a parsed CloudFormation template object. | |
* @param {string} title | |
* @param {Template} template | |
* @returns string Markdown documentation of the template. | |
*/ | |
export const generateDocs = ( | |
title, | |
{ Description, Parameters, Resources, Outputs }, | |
) => { | |
const lines = []; | |
lines.push(`# ${title}`); | |
lines.push(Description); | |
const requiredParameters = []; | |
const optionalParameters = []; | |
for (const name in Parameters) { | |
const parameter = Parameters[name]; | |
const type = parameter.Default === undefined | |
? requiredParameters | |
: optionalParameters; | |
const { Description } = parameter; | |
delete parameter.Description; | |
type.push(`### ${name}`); | |
if (Description) type.push(Description); | |
type.push(defineProperties(parameter)); | |
} | |
if (requiredParameters.length) { | |
lines.push("## Required Parameters"); | |
requiredParameters.forEach((p) => lines.push(p)); | |
} | |
if (optionalParameters.length) { | |
lines.push("## Optional Parameters"); | |
optionalParameters.forEach((p) => lines.push(p)); | |
} | |
if (Resources) { | |
lines.push("## Resources"); | |
for (const name in Resources) { | |
const resource = Resources[name]; | |
delete resource.Properties; | |
lines.push(`### ${name}`); | |
lines.push(defineProperties(resource)); | |
} | |
} | |
if (Outputs) { | |
lines.push("## Outputs"); | |
for (const name in Outputs) { | |
const output = Outputs[name]; | |
const { Description } = output; | |
delete output.Description; | |
delete output.Value; | |
lines.push(`### ${name}`); | |
if (Description) lines.push(Description); | |
lines.push(defineProperties(output)); | |
} | |
} | |
return lines.filter(Boolean).join("\n\n"); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"version": "0.1.0", | |
"name": "cfn-generate-docs", | |
"main": "index.js" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment