mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-11-03 12:25:22 +01:00
build(docs): build JSON Schema docs
Automatically build documentation for JSON Schema. This is only built when running with `--vitepress`, as it currently produces loads of markdown files, which I feel like we shouldn't be committing. This currently manually uses some internal `jsonschema2md` functions so that we can manually control the Markdown output.
This commit is contained in:
@@ -74,6 +74,7 @@
|
||||
"web-worker": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@adobe/jsonschema2md": "^7.1.4",
|
||||
"@types/cytoscape": "^3.19.9",
|
||||
"@types/d3": "^7.4.0",
|
||||
"@types/d3-sankey": "^0.12.1",
|
||||
@@ -109,6 +110,7 @@
|
||||
"typedoc-plugin-markdown": "^3.15.2",
|
||||
"typescript": "^5.0.4",
|
||||
"unist-util-flatmap": "^1.0.0",
|
||||
"unist-util-visit": "^4.1.2",
|
||||
"vitepress": "^1.0.0-alpha.72",
|
||||
"vitepress-plugin-search": "^1.0.4-alpha.20"
|
||||
},
|
||||
|
||||
@@ -34,7 +34,7 @@ import { readFileSync, writeFileSync, mkdirSync, existsSync, rmSync, rmdirSync }
|
||||
import { exec } from 'child_process';
|
||||
import { globby } from 'globby';
|
||||
import { JSDOM } from 'jsdom';
|
||||
import type { Code, Root } from 'mdast';
|
||||
import type { Code, ListItem, Root, Text } from 'mdast';
|
||||
import { posix, dirname, relative, join } from 'path';
|
||||
import prettier from 'prettier';
|
||||
import { remark } from 'remark';
|
||||
@@ -44,6 +44,7 @@ import chokidar from 'chokidar';
|
||||
import mm from 'micromatch';
|
||||
// @ts-ignore No typescript declaration file
|
||||
import flatmap from 'unist-util-flatmap';
|
||||
import { visit } from 'unist-util-visit';
|
||||
|
||||
const MERMAID_MAJOR_VERSION = (
|
||||
JSON.parse(readFileSync('../mermaid/package.json', 'utf8')).version as string
|
||||
@@ -150,6 +151,7 @@ const copyTransformedContents = (filename: string, doCopy = false, transformedCo
|
||||
}
|
||||
|
||||
filesTransformed.add(fileInFinalDocDir);
|
||||
|
||||
if (doCopy) {
|
||||
writeFileSync(fileInFinalDocDir, newBuffer);
|
||||
}
|
||||
@@ -321,6 +323,93 @@ const transformMarkdown = (file: string) => {
|
||||
copyTransformedContents(file, !verifyOnly, formatted);
|
||||
};
|
||||
|
||||
import { load, JSON_SCHEMA } from 'js-yaml';
|
||||
// @ts-ignore: we're importing internal jsonschema2md functions
|
||||
import { default as schemaLoader } from '@adobe/jsonschema2md/lib/schemaProxy.js';
|
||||
// @ts-ignore: we're importing internal jsonschema2md functions
|
||||
import { default as traverseSchemas } from '@adobe/jsonschema2md/lib/traverseSchema.js';
|
||||
// @ts-ignore: we're importing internal jsonschema2md functions
|
||||
import { default as buildMarkdownFromSchema } from '@adobe/jsonschema2md/lib/markdownBuilder.js';
|
||||
// @ts-ignore: we're importing internal jsonschema2md functions
|
||||
import { default as jsonSchemaReadmeBuilder } from '@adobe/jsonschema2md/lib/readmeBuilder.js';
|
||||
|
||||
/**
|
||||
* Transforms the given JSON Schema into Markdown documentation
|
||||
*/
|
||||
async function transormJsonSchema(file: string) {
|
||||
const yamlContents = readSyncedUTF8file(file);
|
||||
const jsonSchema = load(yamlContents, {
|
||||
filename: file,
|
||||
// only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
|
||||
// e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
|
||||
schema: JSON_SCHEMA,
|
||||
});
|
||||
|
||||
// write .schema.json files
|
||||
const jsonFileName = file
|
||||
.replace('.schema.yaml', '.schema.json')
|
||||
.replace('src/schemas/', 'src/docs/schemas/');
|
||||
copyTransformedContents(jsonFileName, !verifyOnly, JSON.stringify(jsonSchema, undefined, 2));
|
||||
|
||||
const schemas = traverseSchemas([schemaLoader()(file, jsonSchema)]);
|
||||
|
||||
// ignore output of this function
|
||||
// for some reason, without calling this function, we get some broken links
|
||||
// this is probably a bug in @adobe/jsonschema2md
|
||||
jsonSchemaReadmeBuilder({ readme: true })(schemas);
|
||||
|
||||
// write Markdown files
|
||||
const markdownFiles = buildMarkdownFromSchema({
|
||||
header: true,
|
||||
// links,
|
||||
includeProperties: ['tsType'], // Custom TypeScript type
|
||||
exampleFormat: 'json',
|
||||
// skipProperties,
|
||||
})(schemas);
|
||||
|
||||
for (const [name, markdownAst] of Object.entries(markdownFiles)) {
|
||||
/*
|
||||
* Converts list entries of shape '- tsType: () => Partial<FontConfig>'
|
||||
* into '- tsType: `() => Partial<FontConfig>`' (e.g. escaping with back-ticks),
|
||||
* as otherwise VitePress doesn't like the <FontConfig> bit.
|
||||
*/
|
||||
visit(markdownAst as Root, 'listItem', (listEntry: ListItem) => {
|
||||
let listText: Text;
|
||||
const blockItem = listEntry.children[0];
|
||||
if (blockItem.type === 'paragraph' && blockItem.children[0].type === 'text') {
|
||||
listText = blockItem.children[0];
|
||||
} // @ts-expect-error: MD AST output from @adobe/jsonschema2md is technically wrong
|
||||
else if (blockItem.type === 'text') {
|
||||
listText = blockItem;
|
||||
} else {
|
||||
return; // skip
|
||||
}
|
||||
|
||||
if (listText.value.startsWith('tsType: ')) {
|
||||
listText.value = listText.value.replace(/tsType: (.*)/g, 'tsType: `$1`');
|
||||
}
|
||||
});
|
||||
|
||||
const transformed = remark()
|
||||
.use(remarkGfm)
|
||||
.use(remarkFrontmatter, ['yaml']) // support YAML front-matter in Markdown
|
||||
.use(transformMarkdownAst, {
|
||||
// mermaid project specific plugin
|
||||
originalFilename: file,
|
||||
addAutogeneratedWarning: !noHeader,
|
||||
removeYAML: !noHeader,
|
||||
})
|
||||
.stringify(markdownAst as Root);
|
||||
|
||||
const formatted = prettier.format(transformed, {
|
||||
parser: 'markdown',
|
||||
...prettierConfig,
|
||||
});
|
||||
const newFileName = join('src', 'docs', 'config', 'schema-docs', `${name}.md`);
|
||||
copyTransformedContents(newFileName, !verifyOnly, formatted);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform an HTML file and write the transformed file to the directory for published
|
||||
* documentation
|
||||
@@ -388,6 +477,14 @@ const main = async () => {
|
||||
const sourceDirGlob = posix.join('.', SOURCE_DOCS_DIR, '**');
|
||||
const action = verifyOnly ? 'Verifying' : 'Transforming';
|
||||
|
||||
if (vitepress) {
|
||||
console.log(`${action} 1 .schema.yaml file`);
|
||||
await transormJsonSchema('src/schemas/config.schema.yaml');
|
||||
} else {
|
||||
// skip because this creates so many Markdown files that it lags git
|
||||
console.log('Skipping 1 .schema.yaml file');
|
||||
}
|
||||
|
||||
const mdFileGlobs = getGlobs([posix.join(sourceDirGlob, '*.md')]);
|
||||
const mdFiles = await getFilesFromGlobs(mdFileGlobs);
|
||||
console.log(`${action} ${mdFiles.length} markdown files...`);
|
||||
|
||||
Reference in New Issue
Block a user