mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-14 22:09:29 +02:00
build: use vite to get default mermaid config
Adds a vitepress JsonSchema plugin that automatically loads the Mermaid Config JSON Schema from a .schema.yaml file and gets the default values from it.
This commit is contained in:
@@ -2,6 +2,7 @@ import { build, InlineConfig, type PluginOption } from 'vite';
|
|||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import jisonPlugin from './jisonPlugin.js';
|
import jisonPlugin from './jisonPlugin.js';
|
||||||
|
import jsonSchemaPlugin from './jsonSchemaPlugin.js';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import typescript from '@rollup/plugin-typescript';
|
import typescript from '@rollup/plugin-typescript';
|
||||||
import { visualizer } from 'rollup-plugin-visualizer';
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
@@ -121,6 +122,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
|
|||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
jisonPlugin(),
|
jisonPlugin(),
|
||||||
|
jsonSchemaPlugin(), // handles `.schema.yaml` files
|
||||||
// @ts-expect-error According to the type definitions, rollup plugins are incompatible with vite
|
// @ts-expect-error According to the type definitions, rollup plugins are incompatible with vite
|
||||||
typescript({ compilerOptions: { declaration: false } }),
|
typescript({ compilerOptions: { declaration: false } }),
|
||||||
istanbul({
|
istanbul({
|
||||||
|
150
.vite/jsonSchemaPlugin.ts
Normal file
150
.vite/jsonSchemaPlugin.ts
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
import { load, JSON_SCHEMA } from 'js-yaml';
|
||||||
|
import assert from 'node:assert';
|
||||||
|
import Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js';
|
||||||
|
import { PluginOption } from 'vite';
|
||||||
|
|
||||||
|
import type { MermaidConfig, BaseDiagramConfig } from '../packages/mermaid/src/config.type.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All of the keys in the mermaid config that have a mermaid diagram config.
|
||||||
|
*/
|
||||||
|
const MERMAID_CONFIG_DIAGRAM_KEYS = [
|
||||||
|
'flowchart',
|
||||||
|
'sequence',
|
||||||
|
'gantt',
|
||||||
|
'journey',
|
||||||
|
'class',
|
||||||
|
'state',
|
||||||
|
'er',
|
||||||
|
'pie',
|
||||||
|
'quadrantChart',
|
||||||
|
'requirement',
|
||||||
|
'mindmap',
|
||||||
|
'timeline',
|
||||||
|
'gitGraph',
|
||||||
|
'c4',
|
||||||
|
'sankey',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate default values from the JSON Schema.
|
||||||
|
*
|
||||||
|
* AJV does not support nested default values yet (or default values with $ref),
|
||||||
|
* so we need to manually find them (this may be fixed in ajv v9).
|
||||||
|
*
|
||||||
|
* @param mermaidConfigSchema - The Mermaid JSON Schema to use.
|
||||||
|
* @returns The default mermaid config object.
|
||||||
|
*/
|
||||||
|
function generateDefaults(mermaidConfigSchema: JSONSchemaType<MermaidConfig>) {
|
||||||
|
const ajv = new Ajv2019({
|
||||||
|
useDefaults: true,
|
||||||
|
allowUnionTypes: true,
|
||||||
|
strict: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
ajv.addKeyword({
|
||||||
|
keyword: 'meta:enum', // used by jsonschema2md
|
||||||
|
errors: false,
|
||||||
|
});
|
||||||
|
ajv.addKeyword({
|
||||||
|
keyword: 'tsType', // used by json-schema-to-typescript
|
||||||
|
errors: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
// ajv currently doesn't support nested default values, see https://github.com/ajv-validator/ajv/issues/1718
|
||||||
|
// (may be fixed in v9) so we need to manually use sub-schemas
|
||||||
|
const mermaidDefaultConfig = {};
|
||||||
|
|
||||||
|
assert.ok(mermaidConfigSchema.$defs);
|
||||||
|
const baseDiagramConfig = mermaidConfigSchema.$defs.BaseDiagramConfig;
|
||||||
|
|
||||||
|
for (const key of MERMAID_CONFIG_DIAGRAM_KEYS) {
|
||||||
|
const subSchemaRef = mermaidConfigSchema.properties[key].$ref;
|
||||||
|
const [root, defs, defName] = subSchemaRef.split('/');
|
||||||
|
assert.strictEqual(root, '#');
|
||||||
|
assert.strictEqual(defs, '$defs');
|
||||||
|
const subSchema = {
|
||||||
|
$schema: mermaidConfigSchema.$schema,
|
||||||
|
$defs: mermaidConfigSchema.$defs,
|
||||||
|
...mermaidConfigSchema.$defs[defName],
|
||||||
|
} as JSONSchemaType<BaseDiagramConfig>;
|
||||||
|
|
||||||
|
const validate = ajv.compile(subSchema);
|
||||||
|
|
||||||
|
mermaidDefaultConfig[key] = {};
|
||||||
|
|
||||||
|
for (const required of subSchema.required ?? []) {
|
||||||
|
if (subSchema.properties[required] === undefined && baseDiagramConfig.properties[required]) {
|
||||||
|
mermaidDefaultConfig[key][required] = baseDiagramConfig.properties[required].default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!validate(mermaidDefaultConfig[key])) {
|
||||||
|
throw new Error(
|
||||||
|
`schema for subconfig ${key} does not have valid defaults! Errors were ${JSON.stringify(
|
||||||
|
validate.errors,
|
||||||
|
undefined,
|
||||||
|
2
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const validate = ajv.compile(mermaidConfigSchema);
|
||||||
|
|
||||||
|
if (!validate(mermaidDefaultConfig)) {
|
||||||
|
throw new Error(
|
||||||
|
`Mermaid config JSON Schema does not have valid defaults! Errors were ${JSON.stringify(
|
||||||
|
validate.errors,
|
||||||
|
undefined,
|
||||||
|
2
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mermaidDefaultConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vite plugin that handles JSON Schemas saved as a `.schema.yaml` file.
|
||||||
|
*
|
||||||
|
* Use `my-example.schema.yaml?only-defaults=true` to only load the default values.
|
||||||
|
*/
|
||||||
|
export default function jsonSchemaPlugin(): PluginOption {
|
||||||
|
return {
|
||||||
|
name: 'json-schema-plugin',
|
||||||
|
transform(src: string, id: string) {
|
||||||
|
const idAsUrl = new URL(id, 'file:///');
|
||||||
|
|
||||||
|
if (!idAsUrl.pathname.endsWith('schema.yaml')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idAsUrl.searchParams.get('only-defaults')) {
|
||||||
|
const jsonSchema = load(src, {
|
||||||
|
filename: idAsUrl.pathname,
|
||||||
|
// 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,
|
||||||
|
}) as JSONSchemaType<MermaidConfig>;
|
||||||
|
return {
|
||||||
|
code: `export default ${JSON.stringify(generateDefaults(jsonSchema), undefined, 2)};`,
|
||||||
|
map: null, // no source map
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: `export default ${JSON.stringify(
|
||||||
|
load(src, {
|
||||||
|
filename: idAsUrl.pathname,
|
||||||
|
// 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,
|
||||||
|
}),
|
||||||
|
undefined,
|
||||||
|
2
|
||||||
|
)};`,
|
||||||
|
map: null, // provide source map if available
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[defaultConfig.ts:2300](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L2300)
|
[defaultConfig.ts:266](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L266)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -22,35 +22,12 @@
|
|||||||
|
|
||||||
• `Const` **default**: `Partial`<`MermaidConfig`>
|
• `Const` **default**: `Partial`<`MermaidConfig`>
|
||||||
|
|
||||||
**Configuration methods in Mermaid version 8.6.0 have been updated, to learn more\[[click
|
Default mermaid configuration options.
|
||||||
here](8.6.0_docs.md)].**
|
|
||||||
|
|
||||||
## **What follows are config instructions for older versions**
|
Please see the Mermaid config JSON Schema for the default JSON values.
|
||||||
|
Non-JSON JS default values are listed in this file, e.g. functions, or
|
||||||
These are the default options which can be overridden with the initialization call like so:
|
`undefined` (explicitly set so that `configKeys` finds them).
|
||||||
|
|
||||||
**Example 1:**
|
|
||||||
|
|
||||||
```js
|
|
||||||
mermaid.initialize({ flowchart: { htmlLabels: false } });
|
|
||||||
```
|
|
||||||
|
|
||||||
**Example 2:**
|
|
||||||
|
|
||||||
```html
|
|
||||||
<script>
|
|
||||||
const config = {
|
|
||||||
startOnLoad: true,
|
|
||||||
flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' },
|
|
||||||
securityLevel: 'loose',
|
|
||||||
};
|
|
||||||
mermaid.initialize(config);
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
A summary of all options and their defaults is found [here](#mermaidapi-configuration-defaults).
|
|
||||||
A description of each option follows below.
|
|
||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[defaultConfig.ts:33](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L33)
|
[defaultConfig.ts:16](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L16)
|
||||||
|
@@ -81,6 +81,7 @@
|
|||||||
"@vitest/coverage-v8": "^0.32.2",
|
"@vitest/coverage-v8": "^0.32.2",
|
||||||
"@vitest/spy": "^0.32.2",
|
"@vitest/spy": "^0.32.2",
|
||||||
"@vitest/ui": "^0.32.2",
|
"@vitest/ui": "^0.32.2",
|
||||||
|
"ajv": "^8.12.0",
|
||||||
"concurrently": "^8.0.1",
|
"concurrently": "^8.0.1",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"coveralls": "^3.1.1",
|
"coveralls": "^3.1.1",
|
||||||
|
File diff suppressed because it is too large
Load Diff
33
pnpm-lock.yaml
generated
33
pnpm-lock.yaml
generated
@@ -71,6 +71,9 @@ importers:
|
|||||||
'@vitest/ui':
|
'@vitest/ui':
|
||||||
specifier: ^0.32.2
|
specifier: ^0.32.2
|
||||||
version: 0.32.2(vitest@0.32.2)
|
version: 0.32.2(vitest@0.32.2)
|
||||||
|
ajv:
|
||||||
|
specifier: ^8.12.0
|
||||||
|
version: 8.12.0
|
||||||
concurrently:
|
concurrently:
|
||||||
specifier: ^8.0.1
|
specifier: ^8.0.1
|
||||||
version: 8.0.1
|
version: 8.0.1
|
||||||
@@ -663,13 +666,13 @@ packages:
|
|||||||
resolution: {integrity: sha512-qe8Nmh9rYI/HIspLSTwtbMFPj6dISG6+dJnOguTlPNXtCvS2uezdxscVBb7/3DrmNbQK49TDqpkSQ1chbRGdpQ==}
|
resolution: {integrity: sha512-qe8Nmh9rYI/HIspLSTwtbMFPj6dISG6+dJnOguTlPNXtCvS2uezdxscVBb7/3DrmNbQK49TDqpkSQ1chbRGdpQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@apideck/better-ajv-errors@0.3.6(ajv@8.11.0):
|
/@apideck/better-ajv-errors@0.3.6(ajv@8.12.0):
|
||||||
resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==}
|
resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
ajv: '>=8'
|
ajv: '>=8'
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv: 8.11.0
|
ajv: 8.12.0
|
||||||
json-schema: 0.4.0
|
json-schema: 0.4.0
|
||||||
jsonpointer: 5.0.1
|
jsonpointer: 5.0.1
|
||||||
leven: 3.1.0
|
leven: 3.1.0
|
||||||
@@ -2258,7 +2261,7 @@ packages:
|
|||||||
engines: {node: '>=v14'}
|
engines: {node: '>=v14'}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@commitlint/types': 17.4.4
|
'@commitlint/types': 17.4.4
|
||||||
ajv: 8.11.0
|
ajv: 8.12.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@commitlint/ensure@17.4.4:
|
/@commitlint/ensure@17.4.4:
|
||||||
@@ -5799,7 +5802,7 @@ packages:
|
|||||||
indent-string: 5.0.0
|
indent-string: 5.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/ajv-formats@2.1.1(ajv@8.11.0):
|
/ajv-formats@2.1.1(ajv@8.12.0):
|
||||||
resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
|
resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
ajv: ^8.0.0
|
ajv: ^8.0.0
|
||||||
@@ -5807,7 +5810,7 @@ packages:
|
|||||||
ajv:
|
ajv:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv: 8.11.0
|
ajv: 8.12.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/ajv-keywords@3.5.2(ajv@6.12.6):
|
/ajv-keywords@3.5.2(ajv@6.12.6):
|
||||||
@@ -5818,12 +5821,12 @@ packages:
|
|||||||
ajv: 6.12.6
|
ajv: 6.12.6
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/ajv-keywords@5.1.0(ajv@8.11.0):
|
/ajv-keywords@5.1.0(ajv@8.12.0):
|
||||||
resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==}
|
resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
ajv: ^8.8.2
|
ajv: ^8.8.2
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv: 8.11.0
|
ajv: 8.12.0
|
||||||
fast-deep-equal: 3.1.3
|
fast-deep-equal: 3.1.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
@@ -5836,8 +5839,8 @@ packages:
|
|||||||
uri-js: 4.4.1
|
uri-js: 4.4.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/ajv@8.11.0:
|
/ajv@8.12.0:
|
||||||
resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==}
|
resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
fast-deep-equal: 3.1.3
|
fast-deep-equal: 3.1.3
|
||||||
json-schema-traverse: 1.0.0
|
json-schema-traverse: 1.0.0
|
||||||
@@ -11063,7 +11066,7 @@ packages:
|
|||||||
/light-my-request@4.12.0:
|
/light-my-request@4.12.0:
|
||||||
resolution: {integrity: sha512-0y+9VIfJEsPVzK5ArSIJ8Dkxp8QMP7/aCuxCUtG/tr9a2NoOf/snATE/OUc05XUplJCEnRh6gTkH7xh9POt1DQ==}
|
resolution: {integrity: sha512-0y+9VIfJEsPVzK5ArSIJ8Dkxp8QMP7/aCuxCUtG/tr9a2NoOf/snATE/OUc05XUplJCEnRh6gTkH7xh9POt1DQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv: 8.11.0
|
ajv: 8.12.0
|
||||||
cookie: 0.5.0
|
cookie: 0.5.0
|
||||||
process-warning: 1.0.0
|
process-warning: 1.0.0
|
||||||
set-cookie-parser: 2.6.0
|
set-cookie-parser: 2.6.0
|
||||||
@@ -13514,9 +13517,9 @@ packages:
|
|||||||
engines: {node: '>= 12.13.0'}
|
engines: {node: '>= 12.13.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/json-schema': 7.0.11
|
'@types/json-schema': 7.0.11
|
||||||
ajv: 8.11.0
|
ajv: 8.12.0
|
||||||
ajv-formats: 2.1.1(ajv@8.11.0)
|
ajv-formats: 2.1.1(ajv@8.12.0)
|
||||||
ajv-keywords: 5.1.0(ajv@8.11.0)
|
ajv-keywords: 5.1.0(ajv@8.12.0)
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/search-insights@2.6.0:
|
/search-insights@2.6.0:
|
||||||
@@ -15924,7 +15927,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-CttE7WCYW9sZC+nUYhQg3WzzGPr4IHmrPnjKiu3AMXsiNQKx+l4hHl63WTrnicLmKEKHScWDH8xsGBdrYgtBzg==}
|
resolution: {integrity: sha512-CttE7WCYW9sZC+nUYhQg3WzzGPr4IHmrPnjKiu3AMXsiNQKx+l4hHl63WTrnicLmKEKHScWDH8xsGBdrYgtBzg==}
|
||||||
engines: {node: '>=16.0.0'}
|
engines: {node: '>=16.0.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@apideck/better-ajv-errors': 0.3.6(ajv@8.11.0)
|
'@apideck/better-ajv-errors': 0.3.6(ajv@8.12.0)
|
||||||
'@babel/core': 7.12.3
|
'@babel/core': 7.12.3
|
||||||
'@babel/preset-env': 7.20.2(@babel/core@7.12.3)
|
'@babel/preset-env': 7.20.2(@babel/core@7.12.3)
|
||||||
'@babel/runtime': 7.21.0
|
'@babel/runtime': 7.21.0
|
||||||
@@ -15932,7 +15935,7 @@ packages:
|
|||||||
'@rollup/plugin-node-resolve': 11.2.1(rollup@2.79.1)
|
'@rollup/plugin-node-resolve': 11.2.1(rollup@2.79.1)
|
||||||
'@rollup/plugin-replace': 2.4.2(rollup@2.79.1)
|
'@rollup/plugin-replace': 2.4.2(rollup@2.79.1)
|
||||||
'@surma/rollup-plugin-off-main-thread': 2.2.3
|
'@surma/rollup-plugin-off-main-thread': 2.2.3
|
||||||
ajv: 8.11.0
|
ajv: 8.12.0
|
||||||
common-tags: 1.8.2
|
common-tags: 1.8.2
|
||||||
fast-json-stable-stringify: 2.1.0
|
fast-json-stable-stringify: 2.1.0
|
||||||
fs-extra: 9.1.0
|
fs-extra: 9.1.0
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import jison from './.vite/jisonPlugin.js';
|
import jison from './.vite/jisonPlugin.js';
|
||||||
|
import jsonSchemaPlugin from './.vite/jsonSchemaPlugin.js';
|
||||||
import typescript from '@rollup/plugin-typescript';
|
import typescript from '@rollup/plugin-typescript';
|
||||||
import { defineConfig } from 'vitest/config';
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
@@ -8,6 +9,7 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
jison(),
|
jison(),
|
||||||
|
jsonSchemaPlugin(), // handles .schema.yaml JSON Schema files
|
||||||
// @ts-expect-error According to the type definitions, rollup plugins are incompatible with vite
|
// @ts-expect-error According to the type definitions, rollup plugins are incompatible with vite
|
||||||
typescript({ compilerOptions: { declaration: false } }),
|
typescript({ compilerOptions: { declaration: false } }),
|
||||||
],
|
],
|
||||||
|
Reference in New Issue
Block a user