docs: diagrams plugin tooling (#5741)

* added plugin

* updated plugin + added component

* dummy data TO BE REMOVED

* (wip) workflow generator tool

* add workflow generator tooling

* updated the generator tool

* added code file creation

* fix design of diagrams

* configured diagram theme

* added build script

* removed comments + unnecessary files

* general fixes

* refactored plugin

* added README + more output types
This commit is contained in:
Shahed Nasser
2023-11-28 14:30:23 +00:00
committed by GitHub
parent d27b86ab8e
commit fa4935259c
19 changed files with 2961 additions and 167 deletions

View File

@@ -0,0 +1,119 @@
import { exec } from "child_process"
import { Dirent } from "fs"
import { readdir, readFile, writeFile } from "fs/promises"
import path from "path"
export default async function docusaurusPluginDiagram2codeShowcase(
context,
{ directoryPath, outputPath, debug = false }
) {
async function readIfExists(filePath) {
try {
return await readFile(filePath, "utf-8")
} catch (e) {
if (debug) {
console.error(
`[Diagram2Code Showcase Plugin] An error occurred while reading ${filePath}: ${e}`
)
}
return null
}
}
async function generateSpecs() {
let specs = {}
let diagramSpecDirectories = []
try {
// read files under the provided directory path
diagramSpecDirectories = (
await readdir(directoryPath, { withFileTypes: true })
).filter((dirent) => dirent.isDirectory())
} catch {
console.error(
`Directory ${directoryPath} doesn't exist. Skipping reading diagrams...`
)
return
}
await Promise.all(
diagramSpecDirectories.map(async (dirent) => {
const tempSpecs = {}
const specsPath = path.join(directoryPath, dirent.name)
const specDirents = (
await readdir(specsPath, { withFileTypes: true })
).filter((specDirent) => specDirent.isDirectory())
await Promise.all(
specDirents.map(async (specDirent) => {
const specPath = path.join(specsPath, specDirent.name)
// read the diagram and code files
const diagram = await readIfExists(
path.join(specPath, "diagram.mermaid")
)
const code =
(await readIfExists(path.join(specPath, "code.ts"))) ||
(await readIfExists(path.join(specPath, "code.tsx"))) ||
(await readIfExists(path.join(specPath, "code.js")))
if (!diagram) {
return
}
tempSpecs[specDirent.name] = {
diagram,
code,
}
})
)
if (Object.keys(tempSpecs).length) {
specs[dirent.name] = tempSpecs
}
})
)
// order steps alphabetically
specs = Object.keys(specs)
.sort()
.reduce((accumulator, key) => {
accumulator[key] = specs[key]
return accumulator
}, {})
// store specs in a JavaScript object that can be consumed
const specOutputFilePath = path.join(outputPath, "specs.ts")
await writeFile(
specOutputFilePath,
`export const specs = ${JSON.stringify(specs, null, "\t")}`
)
// execute eslint
exec(`eslint ${specOutputFilePath} --fix`)
return specOutputFilePath
}
return {
name: "docusaurus-plugin-diagram2code-showcase",
async loadContent() {
await generateSpecs()
},
extendCli(cli) {
cli
.command("diagram2code:generate")
.description(
"Generate the spec file used to create diagram-to-code showcase"
)
.action(async () => {
const specFile = await generateSpecs()
// eslint-disable-next-line no-console
console.log(`Generated diagram2code spec file at ${specFile}`)
})
},
getPathsToWatch() {
return [directoryPath]
},
}
}