diff --git a/.build/jsonSchema.ts b/.build/jsonSchema.ts index 6fd8ca3f5..ab3d1f2fa 100644 --- a/.build/jsonSchema.ts +++ b/.build/jsonSchema.ts @@ -1,7 +1,10 @@ import { load, JSON_SCHEMA } from 'js-yaml'; import assert from 'node:assert'; import Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js'; -import type { MermaidConfig, BaseDiagramConfig } from '../packages/mermaid/src/config.type.js'; +import type { + MermaidConfigWithDefaults, + BaseDiagramConfig, +} from '../packages/mermaid/src/config.type.js'; /** * All of the keys in the mermaid config that have a mermaid diagram config. @@ -36,7 +39,7 @@ const MERMAID_CONFIG_DIAGRAM_KEYS = [ * @param mermaidConfigSchema - The Mermaid JSON Schema to use. * @returns The default mermaid config object. */ -function generateDefaults(mermaidConfigSchema: JSONSchemaType) { +function generateDefaults(mermaidConfigSchema: JSONSchemaType) { const ajv = new Ajv2019({ useDefaults: true, allowUnionTypes: true, @@ -105,20 +108,23 @@ function generateDefaults(mermaidConfigSchema: JSONSchemaType) { return mermaidDefaultConfig; } -export const loadSchema = (src: string, filename: string): JSONSchemaType => { +export const loadSchema = ( + src: string, + filename: string +): JSONSchemaType => { const jsonSchema = load(src, { filename, // 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; + }) as JSONSchemaType; return jsonSchema; }; -export const getDefaults = (schema: JSONSchemaType) => { +export const getDefaults = (schema: JSONSchemaType) => { return `export default ${JSON.stringify(generateDefaults(schema), undefined, 2)};`; }; -export const getSchema = (schema: JSONSchemaType) => { +export const getSchema = (schema: JSONSchemaType) => { return `export default ${JSON.stringify(schema, undefined, 2)};`; }; diff --git a/.esbuild/jsonSchemaPlugin.ts b/.esbuild/jsonSchemaPlugin.ts index e90c185ab..a4206cddd 100644 --- a/.esbuild/jsonSchemaPlugin.ts +++ b/.esbuild/jsonSchemaPlugin.ts @@ -1,5 +1,5 @@ import type { JSONSchemaType } from 'ajv/dist/2019.js'; -import type { MermaidConfig } from '../packages/mermaid/src/config.type.js'; +import type { MermaidConfigWithDefaults } from '../packages/mermaid/src/config.type.js'; import { readFile } from 'node:fs/promises'; import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js'; @@ -12,13 +12,13 @@ import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js'; export const jsonSchemaPlugin = { name: 'json-schema-plugin', setup(build) { - let schema: JSONSchemaType | undefined = undefined; + let schema: JSONSchemaType | undefined = undefined; let content = ''; build.onLoad({ filter: /config\.schema\.yaml$/ }, async (args) => { // Load the file from the file system const source = await readFile(args.path, 'utf8'); - const resolvedSchema: JSONSchemaType = + const resolvedSchema: JSONSchemaType = content === source && schema ? schema : loadSchema(source, args.path); if (content !== source) { content = source; diff --git a/docs/config/setup/modules/config.md b/docs/config/setup/modules/config.md index ff5aa7640..6ff06560b 100644 --- a/docs/config/setup/modules/config.md +++ b/docs/config/setup/modules/config.md @@ -10,7 +10,7 @@ ### defaultConfig -• `Const` **defaultConfig**: `MermaidConfig` +• `Const` **defaultConfig**: `MermaidConfigWithDefaults` #### Defined in @@ -26,9 +26,9 @@ Pushes in a directive to the configuration #### Parameters -| Name | Type | Description | -| :---------- | :--------------------------------------- | :----------------------- | -| `directive` | `PartialObjectDeep`<`MermaidConfig`, {}> | The directive to push in | +| Name | Type | Description | +| :---------- | :--------------------------------------------------- | :----------------------- | +| `directive` | `PartialObjectDeep`<`MermaidConfigWithDefaults`, {}> | The directive to push in | #### Returns @@ -42,7 +42,7 @@ Pushes in a directive to the configuration ### getConfig -▸ **getConfig**(): `MermaidConfig` +▸ **getConfig**(): `MermaidConfigWithDefaults` ## getConfig @@ -54,7 +54,7 @@ Pushes in a directive to the configuration #### Returns -`MermaidConfig` +`MermaidConfigWithDefaults` The currentConfig @@ -66,7 +66,7 @@ The currentConfig ### getSiteConfig -▸ **getSiteConfig**(): `MermaidConfig` +▸ **getSiteConfig**(): `MermaidConfigWithDefaults` ## getSiteConfig @@ -78,7 +78,7 @@ The currentConfig #### Returns -`MermaidConfig` +`MermaidConfigWithDefaults` The siteConfig @@ -108,9 +108,9 @@ The siteConfig #### Parameters -| Name | Type | Default value | Description | -| :------- | :-------------- | :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `config` | `MermaidConfig` | `siteConfig` | base set of values, which currentConfig could be **reset** to. Defaults to the current siteConfig (e.g returned by [getSiteConfig](config.md#getsiteconfig)). | +| Name | Type | Default value | Description | +| :------- | :-------------------------- | :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `config` | `MermaidConfigWithDefaults` | `siteConfig` | base set of values, which currentConfig could be **reset** to. Defaults to the current siteConfig (e.g returned by [getSiteConfig](config.md#getsiteconfig)). | #### Returns @@ -157,9 +157,9 @@ options in-place #### Parameters -| Name | Type | -| :----- | :--------------------------------------- | -| `conf` | `PartialObjectDeep`<`MermaidConfig`, {}> | +| Name | Type | +| :----- | :--------------------------------------------------- | +| `conf` | `PartialObjectDeep`<`MermaidConfigWithDefaults`, {}> | #### Returns @@ -173,7 +173,7 @@ options in-place ### setConfig -▸ **setConfig**(`conf`): `MermaidConfig` +▸ **setConfig**(`conf`): `MermaidConfigWithDefaults` ## setConfig @@ -187,13 +187,13 @@ corresponding siteConfig value. #### Parameters -| Name | Type | Description | -| :----- | :--------------------------------------- | :-------------------------- | -| `conf` | `PartialObjectDeep`<`MermaidConfig`, {}> | The potential currentConfig | +| Name | Type | Description | +| :----- | :--------------------------------------------------- | :-------------------------- | +| `conf` | `PartialObjectDeep`<`MermaidConfigWithDefaults`, {}> | The potential currentConfig | #### Returns -`MermaidConfig` +`MermaidConfigWithDefaults` The currentConfig merged with the sanitized conf @@ -205,7 +205,7 @@ The currentConfig merged with the sanitized conf ### setSiteConfig -▸ **setSiteConfig**(`conf`): `MermaidConfig` +▸ **setSiteConfig**(`conf`): `MermaidConfigWithDefaults` ## setSiteConfig @@ -220,13 +220,13 @@ function _Default value: At default, will mirror Global Config_ #### Parameters -| Name | Type | Description | -| :----- | :--------------------------------------- | :------------------------------------------ | -| `conf` | `PartialObjectDeep`<`MermaidConfig`, {}> | The base currentConfig to use as siteConfig | +| Name | Type | Description | +| :----- | :--------------------------------------------------- | :------------------------------------------ | +| `conf` | `PartialObjectDeep`<`MermaidConfigWithDefaults`, {}> | The base currentConfig to use as siteConfig | #### Returns -`MermaidConfig` +`MermaidConfigWithDefaults` The new siteConfig @@ -238,18 +238,18 @@ The new siteConfig ### updateCurrentConfig -▸ **updateCurrentConfig**(`siteCfg`, `_directives`): `MermaidConfig` +▸ **updateCurrentConfig**(`siteCfg`, `_directives`): `MermaidConfigWithDefaults` #### Parameters -| Name | Type | -| :------------ | :------------------------------------------ | -| `siteCfg` | `MermaidConfig` | -| `_directives` | `PartialObjectDeep`<`MermaidConfig`, {}>\[] | +| Name | Type | +| :------------ | :------------------------------------------------------ | +| `siteCfg` | `MermaidConfigWithDefaults` | +| `_directives` | `PartialObjectDeep`<`MermaidConfigWithDefaults`, {}>\[] | #### Returns -`MermaidConfig` +`MermaidConfigWithDefaults` #### Defined in @@ -259,17 +259,17 @@ The new siteConfig ### updateSiteConfig -▸ **updateSiteConfig**(`conf`): `MermaidConfig` +▸ **updateSiteConfig**(`conf`): `MermaidConfigWithDefaults` #### Parameters -| Name | Type | -| :----- | :--------------------------------------- | -| `conf` | `PartialObjectDeep`<`MermaidConfig`, {}> | +| Name | Type | +| :----- | :--------------------------------------------------- | +| `conf` | `PartialObjectDeep`<`MermaidConfigWithDefaults`, {}> | #### Returns -`MermaidConfig` +`MermaidConfigWithDefaults` #### Defined in diff --git a/docs/config/setup/modules/defaultConfig.md b/docs/config/setup/modules/defaultConfig.md index d3495bc0c..965a5fad3 100644 --- a/docs/config/setup/modules/defaultConfig.md +++ b/docs/config/setup/modules/defaultConfig.md @@ -20,7 +20,7 @@ ### default -• `Const` **default**: `RequiredDeep`<`MermaidConfig`> +• `Const` **default**: `RequiredDeep`<`MermaidConfigWithDefaults`> Default mermaid configuration options. diff --git a/docs/config/setup/modules/mermaidAPI.md b/docs/config/setup/modules/mermaidAPI.md index c370c0122..6d1d356fa 100644 --- a/docs/config/setup/modules/mermaidAPI.md +++ b/docs/config/setup/modules/mermaidAPI.md @@ -32,7 +32,7 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi) ### mermaidAPI -• `Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfig` = configApi.defaultConfig; `getConfig`: () => `MermaidConfig` = configApi.getConfig; `getDiagramFromText`: (`text`: `string`, `metadata`: `Pick`<`DiagramMetadata`, `"title"`>) => `Promise`<`Diagram`> ; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `PartialObjectDeep`<`MermaidConfig`, {}>) => `void` ; `parse`: (`text`: `string`, `parseOptions`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md) & { `suppressErrors`: `true` }) => `Promise`<[`ParseResult`](../interfaces/mermaidAPI.ParseResult.md) | `false`>(`text`: `string`, `parseOptions?`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md)) => `Promise`<[`ParseResult`](../interfaces/mermaidAPI.ParseResult.md)> ; `render`: (`id`: `string`, `text`: `string`, `svgContainingElement?`: `Element`) => `Promise`<[`RenderResult`](../interfaces/mermaidAPI.RenderResult.md)> ; `reset`: () => `void` ; `setConfig`: (`conf`: `PartialObjectDeep`<`MermaidConfig`, {}>) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `PartialObjectDeep`<`MermaidConfig`, {}>) => `MermaidConfig` = configApi.updateSiteConfig }> +• `Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfigWithDefaults` = configApi.defaultConfig; `getConfig`: () => `MermaidConfigWithDefaults` = configApi.getConfig; `getDiagramFromText`: (`text`: `string`, `metadata`: `Pick`<`DiagramMetadata`, `"title"`>) => `Promise`<`Diagram`> ; `getSiteConfig`: () => `MermaidConfigWithDefaults` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `PartialObjectDeep`<`MermaidConfigWithDefaults`, {}>) => `void` ; `parse`: (`text`: `string`, `parseOptions`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md) & { `suppressErrors`: `true` }) => `Promise`<[`ParseResult`](../interfaces/mermaidAPI.ParseResult.md) | `false`>(`text`: `string`, `parseOptions?`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md)) => `Promise`<[`ParseResult`](../interfaces/mermaidAPI.ParseResult.md)> ; `render`: (`id`: `string`, `text`: `string`, `svgContainingElement?`: `Element`) => `Promise`<[`RenderResult`](../interfaces/mermaidAPI.RenderResult.md)> ; `reset`: () => `void` ; `setConfig`: (`conf`: `PartialObjectDeep`<`MermaidConfigWithDefaults`, {}>) => `MermaidConfigWithDefaults` = configApi.setConfig; `updateSiteConfig`: (`conf`: `PartialObjectDeep`<`MermaidConfigWithDefaults`, {}>) => `MermaidConfigWithDefaults` = configApi.updateSiteConfig }> ## mermaidAPI configuration defaults @@ -169,7 +169,7 @@ Create the user styles | Name | Type | Description | | :---------- | :------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------ | -| `config` | `MermaidConfig` | configuration that has style and theme settings to use | +| `config` | `MermaidConfigWithDefaults` | configuration that has style and theme settings to use | | `classDefs` | `undefined` \| `null` \| `Record`<`string`, `DiagramStyleClassDef`> | the classDefs in the diagram text. Might be null if none were defined. Usually is the result of a call to getClasses(...) | #### Returns @@ -192,7 +192,7 @@ the string with all the user styles | Name | Type | | :---------- | :-------------------------------------------------------- | -| `config` | `MermaidConfig` | +| `config` | `MermaidConfigWithDefaults` | | `graphType` | `string` | | `classDefs` | `undefined` \| `Record`<`string`, `DiagramStyleClassDef`> | | `svgId` | `string` | diff --git a/packages/mermaid-zenuml/src/mermaidUtils.ts b/packages/mermaid-zenuml/src/mermaidUtils.ts index 623685879..e054a3ddd 100644 --- a/packages/mermaid-zenuml/src/mermaidUtils.ts +++ b/packages/mermaid-zenuml/src/mermaidUtils.ts @@ -1,4 +1,4 @@ -import type { MermaidConfig } from 'mermaid'; +import type { MermaidConfigWithDefaults } from 'mermaid'; const warning = (s: string) => { // Todo remove debug code @@ -27,7 +27,7 @@ export const log: Record = { }; export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void; -export let getConfig: () => MermaidConfig; +export let getConfig: () => MermaidConfigWithDefaults; export let sanitizeText: (str: string) => string; // eslint-disable @typescript-eslint/no-explicit-any export let setupGraphViewbox: ( diff --git a/packages/mermaid/scripts/create-types-from-json-schema.mts b/packages/mermaid/scripts/create-types-from-json-schema.mts index 317d6b547..d2f2c971f 100644 --- a/packages/mermaid/scripts/create-types-from-json-schema.mts +++ b/packages/mermaid/scripts/create-types-from-json-schema.mts @@ -25,7 +25,7 @@ import prettier from 'prettier'; const Ajv2019 = _Ajv2019 as unknown as typeof _Ajv2019.default; // !!! -- The config.type.js file is created by this script -- !!! -import type { MermaidConfig } from '../src/config.type.js'; +import type { MermaidConfigWithDefaults } from '../src/config.type.js'; // options for running the main command const verifyOnly = process.argv.includes('--verify'); @@ -33,7 +33,7 @@ const verifyOnly = process.argv.includes('--verify'); const git = process.argv.includes('--git'); /** - * Loads the MermaidConfig JSON schema YAML file. + * Loads the MermaidConfigWithDefaults JSON schema YAML file. * * @returns The loaded JSON Schema, use {@link validateSchema} to confirm it is a valid JSON Schema. */ @@ -55,7 +55,9 @@ async function loadJsonSchemaFromYaml() { * @param jsonSchema - The value to validate as JSON Schema 2019-09 * @throws {Error} if the given object is invalid. */ -function validateSchema(jsonSchema: unknown): asserts jsonSchema is JSONSchemaType { +function validateSchema( + jsonSchema: unknown +): asserts jsonSchema is JSONSchemaType { if (typeof jsonSchema !== 'object') { throw new Error(`jsonSchema param is not an object: actual type is ${typeof jsonSchema}`); } @@ -85,7 +87,7 @@ function validateSchema(jsonSchema: unknown): asserts jsonSchema is JSONSchemaTy * * @param mermaidConfigSchema - The input JSON Schema. */ -async function generateTypescript(mermaidConfigSchema: JSONSchemaType) { +async function generateTypescript(mermaidConfigSchema: JSONSchemaType) { /** * Replace all usages of `allOf` with `extends`. * @@ -119,7 +121,7 @@ async function generateTypescript(mermaidConfigSchema: JSONSchemaType { beforeEach(() => { @@ -22,15 +23,15 @@ describe('when working with site config', () => { securityLevel: 'strict', // can't be changed fontSize: 12345, // can't be changed secure: [...configApi.defaultConfig.secure!, 'fontSize'], - } as MermaidConfig; + } as MermaidConfigWithDefaults; configApi.setSiteConfig(config_0); - const directive: PartialMermaidConfig = { + const directive: MermaidConfig = { fontFamily: 'baf', // fontSize and securityLevel shouldn't be changed fontSize: 54321, securityLevel: 'loose', }; - const cfg: MermaidConfig = configApi.updateCurrentConfig(config_0, [directive]); + const cfg: MermaidConfigWithDefaults = configApi.updateCurrentConfig(config_0, [directive]); expect(cfg.fontFamily).toEqual(directive.fontFamily); expect(cfg.fontSize).toBe(config_0.fontSize); expect(cfg.securityLevel).toBe(config_0.securityLevel); diff --git a/packages/mermaid/src/config.ts b/packages/mermaid/src/config.ts index 0d849a475..5fb47f6b7 100644 --- a/packages/mermaid/src/config.ts +++ b/packages/mermaid/src/config.ts @@ -1,27 +1,27 @@ import assignWithDepth from './assignWithDepth.js'; -import type { MermaidConfig, PartialMermaidConfig } from './config.type.js'; +import type { MermaidConfigWithDefaults, MermaidConfig } from './config.type.js'; import config from './defaultConfig.js'; import { log } from './logger.js'; import theme from './themes/index.js'; import { sanitizeDirective } from './utils/sanitizeDirective.js'; -export const defaultConfig: MermaidConfig = Object.freeze(config); +export const defaultConfig: MermaidConfigWithDefaults = Object.freeze(config); -let siteConfig: MermaidConfig = assignWithDepth({}, defaultConfig); -let configFromInitialize: PartialMermaidConfig; -let directives: PartialMermaidConfig[] = []; -let currentConfig: MermaidConfig = assignWithDepth({}, defaultConfig); +let siteConfig: MermaidConfigWithDefaults = assignWithDepth({}, defaultConfig); +let configFromInitialize: MermaidConfig; +let directives: MermaidConfig[] = []; +let currentConfig: MermaidConfigWithDefaults = assignWithDepth({}, defaultConfig); export const updateCurrentConfig = ( - siteCfg: MermaidConfig, - _directives: PartialMermaidConfig[] + siteCfg: MermaidConfigWithDefaults, + _directives: MermaidConfig[] ) => { // start with config being the siteConfig - let cfg: MermaidConfig = assignWithDepth({}, siteCfg); + let cfg: MermaidConfigWithDefaults = assignWithDepth({}, siteCfg); // let sCfg = assignWithDepth(defaultConfig, siteConfigDelta); // Join directives - let sumOfDirectives: PartialMermaidConfig = {}; + let sumOfDirectives: MermaidConfig = {}; for (const d of _directives) { sanitize(d); // Apply the data from the directive where the overrides the themeVariables @@ -61,7 +61,7 @@ export const updateCurrentConfig = ( * @param conf - The base currentConfig to use as siteConfig * @returns The new siteConfig */ -export const setSiteConfig = (conf: PartialMermaidConfig): MermaidConfig => { +export const setSiteConfig = (conf: MermaidConfig): MermaidConfigWithDefaults => { siteConfig = assignWithDepth({}, defaultConfig); siteConfig = assignWithDepth(siteConfig, conf); @@ -75,11 +75,11 @@ export const setSiteConfig = (conf: PartialMermaidConfig): MermaidConfig => { return siteConfig; }; -export const saveConfigFromInitialize = (conf: PartialMermaidConfig): void => { +export const saveConfigFromInitialize = (conf: MermaidConfig): void => { configFromInitialize = assignWithDepth({}, conf); }; -export const updateSiteConfig = (conf: PartialMermaidConfig): MermaidConfig => { +export const updateSiteConfig = (conf: MermaidConfig): MermaidConfigWithDefaults => { siteConfig = assignWithDepth(siteConfig, conf); updateCurrentConfig(siteConfig, directives); @@ -96,7 +96,7 @@ export const updateSiteConfig = (conf: PartialMermaidConfig): MermaidConfig => { * * @returns The siteConfig */ -export const getSiteConfig = (): MermaidConfig => { +export const getSiteConfig = (): MermaidConfigWithDefaults => { return assignWithDepth({}, siteConfig); }; /** @@ -113,7 +113,7 @@ export const getSiteConfig = (): MermaidConfig => { * @param conf - The potential currentConfig * @returns The currentConfig merged with the sanitized conf */ -export const setConfig = (conf: PartialMermaidConfig): MermaidConfig => { +export const setConfig = (conf: MermaidConfig): MermaidConfigWithDefaults => { checkConfig(conf); assignWithDepth(currentConfig, conf); @@ -131,7 +131,7 @@ export const setConfig = (conf: PartialMermaidConfig): MermaidConfig => { * * @returns The currentConfig */ -export const getConfig = (): MermaidConfig => { +export const getConfig = (): MermaidConfigWithDefaults => { return assignWithDepth({}, currentConfig); }; /** @@ -188,7 +188,7 @@ export const sanitize = (options: any) => { * * @param directive - The directive to push in */ -export const addDirective = (directive: PartialMermaidConfig) => { +export const addDirective = (directive: MermaidConfig) => { sanitizeDirective(directive); // If the directive has a fontFamily, but no themeVariables, add the fontFamily to the themeVariables @@ -239,7 +239,7 @@ const issueWarning = (warning: ConfigWarningStrings) => { issuedWarnings[warning] = true; }; -const checkConfig = (config: PartialMermaidConfig) => { +const checkConfig = (config: MermaidConfig) => { if (!config) { return; } diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index 512e86712..fd0397592 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -24,7 +24,7 @@ * ``` * * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "FontCalculator". */ export type FontCalculator = () => Partial; @@ -32,7 +32,7 @@ export type FontCalculator = () => Partial; * Picks the color of the sankey diagram links, using the colors of the source and/or target of the links. * * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "SankeyLinkColor". */ export type SankeyLinkColor = 'source' | 'target' | 'gradient'; @@ -42,7 +42,7 @@ export type SankeyLinkColor = 'source' | 'target' | 'gradient'; * See . * * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "SankeyNodeAlignment". */ export type SankeyNodeAlignment = 'left' | 'right' | 'center' | 'justify'; @@ -51,18 +51,18 @@ export type SankeyNodeAlignment = 'left' | 'right' | 'center' | 'justify'; */ export type DOMPurifyConfiguration = import('dompurify').Config; /** - * MermaidConfig with all fields optional + * MermaidConfigWithDefaults with all fields optional * - * This interface was referenced by `MermaidConfig`'s JSON-Schema - * via the `definition` "PartialMermaidConfig". + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema + * via the `definition` "MermaidConfig". */ -export type PartialMermaidConfig = import('type-fest').PartialDeep; +export type MermaidConfig = import('type-fest').PartialDeep; /** * The font size to use */ export type CSSFontSize = string | number; -export interface MermaidConfig { +export interface MermaidConfigWithDefaults { /** * Theme, the CSS style sheet. * You may also use `themeCSS` to override this value. @@ -184,7 +184,7 @@ export interface MermaidConfig { /** * The object containing configurations specific for flowcharts * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "FlowchartDiagramConfig". */ export interface FlowchartDiagramConfig extends BaseDiagramConfig { @@ -255,7 +255,7 @@ export interface FlowchartDiagramConfig extends BaseDiagramConfig { wrappingWidth: number; } /** - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "BaseDiagramConfig". */ export interface BaseDiagramConfig { @@ -271,7 +271,7 @@ export interface BaseDiagramConfig { /** * The object containing configurations specific for sequence diagrams * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "SequenceDiagramConfig". */ export interface SequenceDiagramConfig extends BaseDiagramConfig { @@ -414,7 +414,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig { * The object containing configurations specific for gantt diagrams * * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "GanttDiagramConfig". */ export interface GanttDiagramConfig extends BaseDiagramConfig { @@ -499,7 +499,7 @@ export interface GanttDiagramConfig extends BaseDiagramConfig { * The object containing configurations specific for journey diagrams * * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "JourneyDiagramConfig". */ export interface JourneyDiagramConfig extends BaseDiagramConfig { @@ -577,7 +577,7 @@ export interface JourneyDiagramConfig extends BaseDiagramConfig { sectionColours?: string[]; } /** - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "TimelineDiagramConfig". */ export interface TimelineDiagramConfig extends BaseDiagramConfig { @@ -657,7 +657,7 @@ export interface TimelineDiagramConfig extends BaseDiagramConfig { disableMulticolor?: boolean; } /** - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "ClassDiagramConfig". */ export interface ClassDiagramConfig extends BaseDiagramConfig { @@ -692,7 +692,7 @@ export interface ClassDiagramConfig extends BaseDiagramConfig { /** * The object containing configurations specific for entity relationship diagrams * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "StateDiagramConfig". */ export interface StateDiagramConfig extends BaseDiagramConfig { @@ -731,7 +731,7 @@ export interface StateDiagramConfig extends BaseDiagramConfig { /** * The object containing configurations specific for entity relationship diagrams * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "ErDiagramConfig". */ export interface ErDiagramConfig extends BaseDiagramConfig { @@ -777,7 +777,7 @@ export interface ErDiagramConfig extends BaseDiagramConfig { fontSize?: number; } /** - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "PieDiagramConfig". */ export interface PieDiagramConfig extends BaseDiagramConfig { @@ -788,7 +788,7 @@ export interface PieDiagramConfig extends BaseDiagramConfig { textPosition?: number; } /** - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "QuadrantChartConfig". */ export interface QuadrantChartConfig extends BaseDiagramConfig { @@ -868,7 +868,7 @@ export interface QuadrantChartConfig extends BaseDiagramConfig { /** * This object contains configuration specific to XYCharts * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "XYChartConfig". */ export interface XYChartConfig extends BaseDiagramConfig { @@ -906,7 +906,7 @@ export interface XYChartConfig extends BaseDiagramConfig { /** * This object contains configuration for XYChart axis config * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "XYChartAxisConfig". */ export interface XYChartAxisConfig { @@ -958,7 +958,7 @@ export interface XYChartAxisConfig { /** * The object containing configurations specific for req diagrams * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "RequirementDiagramConfig". */ export interface RequirementDiagramConfig extends BaseDiagramConfig { @@ -975,7 +975,7 @@ export interface RequirementDiagramConfig extends BaseDiagramConfig { /** * The object containing configurations specific for mindmap diagrams * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "MindmapDiagramConfig". */ export interface MindmapDiagramConfig extends BaseDiagramConfig { @@ -983,7 +983,7 @@ export interface MindmapDiagramConfig extends BaseDiagramConfig { maxNodeWidth: number; } /** - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "GitGraphDiagramConfig". */ export interface GitGraphDiagramConfig extends BaseDiagramConfig { @@ -1007,7 +1007,7 @@ export interface GitGraphDiagramConfig extends BaseDiagramConfig { arrowMarkerAbsolute?: boolean; } /** - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "NodeLabel". */ export interface NodeLabel { @@ -1019,7 +1019,7 @@ export interface NodeLabel { /** * The object containing configurations specific for c4 diagrams * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "C4DiagramConfig". */ export interface C4DiagramConfig extends BaseDiagramConfig { @@ -1400,7 +1400,7 @@ export interface C4DiagramConfig extends BaseDiagramConfig { /** * The object containing configurations specific for sankey diagrams. * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "SankeyDiagramConfig". */ export interface SankeyDiagramConfig extends BaseDiagramConfig { @@ -1432,7 +1432,7 @@ export interface SankeyDiagramConfig extends BaseDiagramConfig { /** * The object containing configurations specific for packet diagrams. * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "PacketDiagramConfig". */ export interface PacketDiagramConfig extends BaseDiagramConfig { @@ -1464,14 +1464,14 @@ export interface PacketDiagramConfig extends BaseDiagramConfig { /** * The object containing configurations specific for block diagrams. * - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "BlockDiagramConfig". */ export interface BlockDiagramConfig extends BaseDiagramConfig { padding?: number; } /** - * This interface was referenced by `MermaidConfig`'s JSON-Schema + * This interface was referenced by `MermaidConfigWithDefaults`'s JSON-Schema * via the `definition` "FontConfig". */ export interface FontConfig { diff --git a/packages/mermaid/src/defaultConfig.ts b/packages/mermaid/src/defaultConfig.ts index 76a8152b7..01ac8a0b5 100644 --- a/packages/mermaid/src/defaultConfig.ts +++ b/packages/mermaid/src/defaultConfig.ts @@ -1,8 +1,5 @@ -import type { RequiredDeep } from 'type-fest'; - +import type { MermaidConfigWithDefaults } from './config.type.js'; import theme from './themes/index.js'; -import type { MermaidConfig } from './config.type.js'; - // Uses our custom Vite jsonSchemaPlugin to load only the default values from // our JSON Schema // @ts-expect-error This file is automatically generated via a custom Vite plugin @@ -15,7 +12,7 @@ import defaultConfigJson from './schemas/config.schema.yaml?only-defaults=true'; * Non-JSON JS default values are listed in this file, e.g. functions, or * `undefined` (explicitly set so that `configKeys` finds them). */ -const config: RequiredDeep = { +const config: MermaidConfigWithDefaults = { ...defaultConfigJson, // Set, even though they're `undefined` so that `configKeys` finds these keys // TODO: Should we replace these with `null` so that they can go in the JSON Schema? diff --git a/packages/mermaid/src/diagram-api/detectType.ts b/packages/mermaid/src/diagram-api/detectType.ts index cfff2fbb3..8d7d52357 100644 --- a/packages/mermaid/src/diagram-api/detectType.ts +++ b/packages/mermaid/src/diagram-api/detectType.ts @@ -1,4 +1,4 @@ -import type { MermaidConfig } from '../config.type.js'; +import type { MermaidConfigWithDefaults } from '../config.type.js'; import { UnknownDiagramError } from '../errors.js'; import { log } from '../logger.js'; import { anyCommentRegex, directiveRegex, frontMatterRegex } from './regexes.js'; @@ -33,7 +33,7 @@ export const detectors: Record = {}; * @param config - The mermaid config. * @returns A graph definition key */ -export const detectType = function (text: string, config?: MermaidConfig): string { +export const detectType = function (text: string, config?: MermaidConfigWithDefaults): string { text = text .replace(frontMatterRegex, '') .replace(directiveRegex, '') diff --git a/packages/mermaid/src/diagram-api/diagram-orchestration.spec.ts b/packages/mermaid/src/diagram-api/diagram-orchestration.spec.ts index 1ceda0a46..e90573554 100644 --- a/packages/mermaid/src/diagram-api/diagram-orchestration.spec.ts +++ b/packages/mermaid/src/diagram-api/diagram-orchestration.spec.ts @@ -1,5 +1,5 @@ -import { describe, expect, it } from 'vitest'; -import type { MermaidConfig } from '../config.type.js'; +import { describe, expect, it, beforeAll } from 'vitest'; +import type { MermaidConfigWithDefaults } from '../config.type.js'; import { detectType } from './detectType.js'; import { addDiagrams } from './diagram-orchestration.js'; @@ -50,13 +50,13 @@ describe('diagram-orchestration', () => { expect( detectType('graph TD; A-->B', { flowchart: { defaultRenderer: 'dagre-d3' }, - } as MermaidConfig) + } as MermaidConfigWithDefaults) ).toBe('flowchart'); // flowchart & dagre-d3 => error expect(() => detectType('flowchart TD; A-->B', { flowchart: { defaultRenderer: 'dagre-d3' }, - } as MermaidConfig) + } as MermaidConfigWithDefaults) ).toThrowErrorMatchingInlineSnapshot( `[UnknownDiagramError: No diagram type detected matching given configuration for text: flowchart TD; A-->B]` ); @@ -65,7 +65,7 @@ describe('diagram-orchestration', () => { expect( detectType('graph TD; A-->B', { flowchart: { defaultRenderer: 'dagre-wrapper' }, - } as MermaidConfig) + } as MermaidConfigWithDefaults) ).toBe('flowchart-v2'); // flowchart ==> flowchart-v2 expect(detectType('flowchart TD; A-->B')).toBe('flowchart-v2'); @@ -73,13 +73,13 @@ describe('diagram-orchestration', () => { expect( detectType('flowchart TD; A-->B', { flowchart: { defaultRenderer: 'dagre-wrapper' }, - } as MermaidConfig) + } as MermaidConfigWithDefaults) ).toBe('flowchart-v2'); // flowchart && elk ==> flowchart-elk expect( detectType('flowchart TD; A-->B', { flowchart: { defaultRenderer: 'elk' }, - } as MermaidConfig) + } as MermaidConfigWithDefaults) ).toBe('flowchart-elk'); }); diff --git a/packages/mermaid/src/diagram-api/frontmatter.ts b/packages/mermaid/src/diagram-api/frontmatter.ts index 86ea84a25..c8d662c28 100644 --- a/packages/mermaid/src/diagram-api/frontmatter.ts +++ b/packages/mermaid/src/diagram-api/frontmatter.ts @@ -1,4 +1,4 @@ -import type { GanttDiagramConfig, PartialMermaidConfig } from '../config.type.js'; +import type { GanttDiagramConfig, MermaidConfig } from '../config.type.js'; import { frontMatterRegex } from './regexes.js'; // The "* as yaml" part is necessary for tree-shaking import * as yaml from 'js-yaml'; @@ -7,7 +7,7 @@ interface FrontMatterMetadata { title?: string; // Allows custom display modes. Currently used for compact mode in gantt charts. displayMode?: GanttDiagramConfig['displayMode']; - config?: PartialMermaidConfig; + config?: MermaidConfig; } export interface FrontMatterResult { diff --git a/packages/mermaid/src/diagram-api/types.ts b/packages/mermaid/src/diagram-api/types.ts index d4c187891..6ab82bd0d 100644 --- a/packages/mermaid/src/diagram-api/types.ts +++ b/packages/mermaid/src/diagram-api/types.ts @@ -2,11 +2,11 @@ import type * as d3 from 'd3'; import type { SetRequired } from 'type-fest'; import type { Diagram } from '../Diagram.js'; -import type { BaseDiagramConfig, PartialMermaidConfig } from '../config.type.js'; +import type { BaseDiagramConfig, MermaidConfig } from '../config.type.js'; export interface DiagramMetadata { title?: string; - config?: PartialMermaidConfig; + config?: MermaidConfig; } export interface InjectUtils { @@ -78,7 +78,7 @@ export interface DiagramDefinition { renderer: DiagramRenderer; parser: ParserDefinition; styles?: any; - init?: (config: PartialMermaidConfig) => void; + init?: (config: MermaidConfig) => void; injectUtils?: ( _log: InjectUtils['_log'], _setLogLevel: InjectUtils['_setLogLevel'], @@ -102,7 +102,7 @@ export interface ExternalDiagramDefinition { loader: DiagramLoader; } -export type DiagramDetector = (text: string, config?: PartialMermaidConfig) => boolean; +export type DiagramDetector = (text: string, config?: MermaidConfig) => boolean; export type DiagramLoader = () => Promise<{ id: string; diagram: DiagramDefinition }>; /** diff --git a/packages/mermaid/src/diagrams/block/blockRenderer.ts b/packages/mermaid/src/diagrams/block/blockRenderer.ts index e6289ad82..9268a15a6 100644 --- a/packages/mermaid/src/diagrams/block/blockRenderer.ts +++ b/packages/mermaid/src/diagrams/block/blockRenderer.ts @@ -5,7 +5,7 @@ import { } from 'd3'; import type { Diagram } from '../../Diagram.js'; import * as configApi from '../../config.js'; -import type { MermaidConfig } from '../../config.type.js'; +import type { MermaidConfigWithDefaults } from '../../config.type.js'; import insertMarkers from '../../dagre-wrapper/markers.js'; import { log } from '../../logger.js'; import { configureSvgSize } from '../../setupGraphViewbox.js'; @@ -75,7 +75,7 @@ export const draw = async function ( const magicFactor = Math.max(1, Math.round(0.125 * (bounds2.width / bounds2.height))); const height = bounds2.height + magicFactor + 10; const width = bounds2.width + 10; - const { useMaxWidth } = conf as Exclude; + const { useMaxWidth } = conf as Exclude; configureSvgSize(svg, height, width, !!useMaxWidth); log.debug('Here Bounds', bounds, bounds2); svg.attr( diff --git a/packages/mermaid/src/diagrams/common/common.spec.ts b/packages/mermaid/src/diagrams/common/common.spec.ts index d382d0399..86d028939 100644 --- a/packages/mermaid/src/diagrams/common/common.spec.ts +++ b/packages/mermaid/src/diagrams/common/common.spec.ts @@ -1,4 +1,5 @@ -import type { MermaidConfig } from '../../config.type.js'; +import { describe, expect, it } from 'vitest'; +import type { MermaidConfigWithDefaults } from '../../config.type.js'; import { countOccurrence, parseGenericTypes, removeScript, sanitizeText } from './common.js'; describe('when securityLevel is antiscript, all script must be removed', () => { @@ -68,7 +69,7 @@ describe('Sanitize text', () => { const result = sanitizeText(maliciousStr, { securityLevel: 'strict', flowchart: { htmlLabels: true }, - } as MermaidConfig); + } as MermaidConfigWithDefaults); expect(result).not.toContain('javascript:alert(1)'); }); }); diff --git a/packages/mermaid/src/diagrams/common/common.ts b/packages/mermaid/src/diagrams/common/common.ts index 66cc5ff6f..1b44bdfbe 100644 --- a/packages/mermaid/src/diagrams/common/common.ts +++ b/packages/mermaid/src/diagrams/common/common.ts @@ -1,5 +1,5 @@ import DOMPurify from 'dompurify'; -import type { MermaidConfig } from '../../config.type.js'; +import type { MermaidConfigWithDefaults } from '../../config.type.js'; // Remove and ignore br:s export const lineBreakRegex = //gi; @@ -63,7 +63,7 @@ export const removeScript = (txt: string): string => { return sanitizedText; }; -const sanitizeMore = (text: string, config: MermaidConfig) => { +const sanitizeMore = (text: string, config: MermaidConfigWithDefaults) => { if (config.flowchart?.htmlLabels !== false) { const level = config.securityLevel; if (level === 'antiscript' || level === 'strict') { @@ -78,7 +78,7 @@ const sanitizeMore = (text: string, config: MermaidConfig) => { return text; }; -export const sanitizeText = (text: string, config: MermaidConfig): string => { +export const sanitizeText = (text: string, config: MermaidConfigWithDefaults): string => { if (!text) { return text; } @@ -94,7 +94,7 @@ export const sanitizeText = (text: string, config: MermaidConfig): string => { export const sanitizeTextOrArray = ( a: string | string[] | string[][], - config: MermaidConfig + config: MermaidConfigWithDefaults ): string | string[] => { if (typeof a === 'string') { return sanitizeText(a, config); @@ -310,7 +310,10 @@ export const hasKatex = (text: string): boolean => (text.match(katexRegex)?.leng * @param config - Configuration for Mermaid * @returns Object containing \{width, height\} */ -export const calculateMathMLDimensions = async (text: string, config: MermaidConfig) => { +export const calculateMathMLDimensions = async ( + text: string, + config: MermaidConfigWithDefaults +) => { text = await renderKatex(text, config); const divElem = document.createElement('div'); divElem.innerHTML = text; @@ -332,7 +335,10 @@ export const calculateMathMLDimensions = async (text: string, config: MermaidCon * @param config - Configuration for Mermaid * @returns String containing MathML if KaTeX is supported, or an error message if it is not and stylesheets aren't present */ -export const renderKatex = async (text: string, config: MermaidConfig): Promise => { +export const renderKatex = async ( + text: string, + config: MermaidConfigWithDefaults +): Promise => { if (!hasKatex(text)) { return text; } diff --git a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts index 978647994..30c0d764b 100644 --- a/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts +++ b/packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts @@ -1,8 +1,8 @@ import cytoscape from 'cytoscape'; -// @ts-expect-error No types available +// @ts-ignore Types for cose-bilkent are not present import coseBilkent from 'cytoscape-cose-bilkent'; import { select } from 'd3'; -import type { MermaidConfig } from '../../config.type.js'; +import type { MermaidConfigWithDefaults } from '../../config.type.js'; import { getConfig } from '../../diagram-api/diagramAPI.js'; import type { DrawDefinition } from '../../diagram-api/types.js'; import { log } from '../../logger.js'; @@ -21,7 +21,7 @@ function drawNodes( svg: D3Element, mindmap: FilledMindMapNode, section: number, - conf: MermaidConfig + conf: MermaidConfigWithDefaults ) { drawNode(db, svg, mindmap, section, conf); if (mindmap.children) { @@ -64,7 +64,12 @@ function drawEdges(edgesEl: D3Element, cy: cytoscape.Core) { }); } -function addNodes(mindmap: MindmapNode, cy: cytoscape.Core, conf: MermaidConfig, level: number) { +function addNodes( + mindmap: MindmapNode, + cy: cytoscape.Core, + conf: MermaidConfigWithDefaults, + level: number +) { cy.add({ group: 'nodes', data: { @@ -99,7 +104,10 @@ function addNodes(mindmap: MindmapNode, cy: cytoscape.Core, conf: MermaidConfig, } } -function layoutMindmap(node: MindmapNode, conf: MermaidConfig): Promise { +function layoutMindmap( + node: MindmapNode, + conf: MermaidConfigWithDefaults +): Promise { return new Promise((resolve) => { // Add temporary render element const renderEl = select('body').append('div').attr('id', 'cy').attr('style', 'display:none'); diff --git a/packages/mermaid/src/diagrams/mindmap/svgDraw.ts b/packages/mermaid/src/diagrams/mindmap/svgDraw.ts index c84a7b16c..8baf84957 100644 --- a/packages/mermaid/src/diagrams/mindmap/svgDraw.ts +++ b/packages/mermaid/src/diagrams/mindmap/svgDraw.ts @@ -3,7 +3,7 @@ import { createText } from '../../rendering-util/createText.js'; import type { FilledMindMapNode, MindmapDB } from './mindmapTypes.js'; import type { Point } from '../../types.js'; import { parseFontSize } from '../../utils.js'; -import type { MermaidConfig } from '../../config.type.js'; +import type { MermaidConfigWithDefaults } from '../../config.type.js'; const MAX_SECTIONS = 12; @@ -180,7 +180,7 @@ export const drawNode = function ( elem: D3Element, node: FilledMindMapNode, fullSection: number, - conf: MermaidConfig + conf: MermaidConfigWithDefaults ): number { const htmlLabels = conf.htmlLabels; const section = fullSection % (MAX_SECTIONS - 1); diff --git a/packages/mermaid/src/diagrams/pie/pieRenderer.ts b/packages/mermaid/src/diagrams/pie/pieRenderer.ts index fb386863b..8c07a2ad7 100644 --- a/packages/mermaid/src/diagrams/pie/pieRenderer.ts +++ b/packages/mermaid/src/diagrams/pie/pieRenderer.ts @@ -6,7 +6,7 @@ import { getConfig } from '../../diagram-api/diagramAPI.js'; import { cleanAndMerge, parseFontSize } from '../../utils.js'; import type { DrawDefinition, Group, SVG } from '../../diagram-api/types.js'; import type { D3Section, PieDB, Sections } from './pieTypes.js'; -import type { MermaidConfig, PieDiagramConfig } from '../../config.type.js'; +import type { MermaidConfigWithDefaults, PieDiagramConfig } from '../../config.type.js'; import { selectSvgElement } from '../../rendering-util/selectSvgElement.js'; const createPieArcs = (sections: Sections): d3.PieArcDatum[] => { @@ -38,7 +38,7 @@ const createPieArcs = (sections: Sections): d3.PieArcDatum[] => { export const draw: DrawDefinition = (text, id, _version, diagObj) => { log.debug('rendering pie chart\n' + text); const db = diagObj.db as PieDB; - const globalConfig: MermaidConfig = getConfig(); + const globalConfig: MermaidConfigWithDefaults = getConfig(); const pieConfig: Required = cleanAndMerge(db.getConfig(), globalConfig.pie); const MARGIN = 40; const LEGEND_RECT_SIZE = 18; diff --git a/packages/mermaid/src/diagrams/timeline/timelineRenderer.ts b/packages/mermaid/src/diagrams/timeline/timelineRenderer.ts index 2f1f15689..f37cb3331 100644 --- a/packages/mermaid/src/diagrams/timeline/timelineRenderer.ts +++ b/packages/mermaid/src/diagrams/timeline/timelineRenderer.ts @@ -6,7 +6,7 @@ import { log } from '../../logger.js'; import { getConfig } from '../../diagram-api/diagramAPI.js'; import { setupGraphViewbox } from '../../setupGraphViewbox.js'; import type { Diagram } from '../../Diagram.js'; -import type { MermaidConfig } from '../../config.type.js'; +import type { MermaidConfigWithDefaults } from '../../config.type.js'; interface Block { number: number; @@ -241,7 +241,7 @@ export const drawTasks = function ( masterX: number, masterY: number, maxTaskHeight: number, - conf: MermaidConfig, + conf: MermaidConfigWithDefaults, maxEventCount: number, maxEventLineLength: number, maxSectionHeight: number, @@ -318,7 +318,7 @@ export const drawEvents = function ( sectionColor: number, masterX: number, masterY: number, - conf: MermaidConfig + conf: MermaidConfigWithDefaults ) { let maxEventHeight = 0; const eventBeginY = masterY; diff --git a/packages/mermaid/src/docs/.vitepress/theme/mermaid.ts b/packages/mermaid/src/docs/.vitepress/theme/mermaid.ts index 47e238692..0931c4d73 100644 --- a/packages/mermaid/src/docs/.vitepress/theme/mermaid.ts +++ b/packages/mermaid/src/docs/.vitepress/theme/mermaid.ts @@ -1,9 +1,13 @@ -import mermaid, { type MermaidConfig } from 'mermaid'; +import mermaid, { type MermaidConfigWithDefaults } from 'mermaid'; import zenuml from '../../../../../mermaid-zenuml/dist/mermaid-zenuml.core.mjs'; const init = mermaid.registerExternalDiagrams([zenuml]); -export const render = async (id: string, code: string, config: MermaidConfig): Promise => { +export const render = async ( + id: string, + code: string, + config: MermaidConfigWithDefaults +): Promise => { await init; mermaid.initialize(config); const { svg } = await mermaid.render(id, code); diff --git a/packages/mermaid/src/mermaid.ts b/packages/mermaid/src/mermaid.ts index 8194872d4..791ddd808 100644 --- a/packages/mermaid/src/mermaid.ts +++ b/packages/mermaid/src/mermaid.ts @@ -3,7 +3,7 @@ * functionality and to render the diagrams to svg code! */ import { dedent } from 'ts-dedent'; -import type { MermaidConfig } from './config.type.js'; +import type { MermaidConfigWithDefaults, MermaidConfig } from './config.type.js'; import { log } from './logger.js'; import utils from './utils.js'; import type { ParseOptions, ParseResult, RenderResult } from './mermaidAPI.js'; @@ -18,6 +18,7 @@ import type { UnknownDiagramError } from './errors.js'; import { addDiagrams } from './diagram-api/diagram-orchestration.js'; export type { + MermaidConfigWithDefaults, MermaidConfig, DetailedError, ExternalDiagramDefinition, @@ -330,8 +331,8 @@ const executeQueue = async () => { * // throws Error * ``` */ -const parse: typeof mermaidAPI.parse = async (text, parseOptions) => { - return new Promise((resolve, reject) => { +const parse = async (text: string, parseOptions?: ParseOptions & { suppressErrors: true }) => { + return new Promise((resolve, reject) => { // This promise will resolve when the render call is done. // It will be queued first and will be executed when it is first in line const performCall = () => diff --git a/packages/mermaid/src/mermaidAPI.spec.ts b/packages/mermaid/src/mermaidAPI.spec.ts index 849f8f026..a836fda7a 100644 --- a/packages/mermaid/src/mermaidAPI.spec.ts +++ b/packages/mermaid/src/mermaidAPI.spec.ts @@ -35,7 +35,7 @@ vi.mock('./diagrams/state/stateRenderer-v2.js'); // ------------------------------------- import assignWithDepth from './assignWithDepth.js'; -import type { MermaidConfig } from './config.type.js'; +import type { MermaidConfigWithDefaults } from './config.type.js'; import mermaid from './mermaid.js'; import mermaidAPI, { appendDivSvgG, @@ -288,7 +288,7 @@ describe('mermaidAPI', () => { fontFamily: serif, altFontFamily: sansSerif, htmlLabels: true, - } as MermaidConfig; + } as MermaidConfigWithDefaults; it('gets the cssStyles from the theme', () => { const styles = createCssStyles(mocked_config_with_htmlLabels, null); @@ -367,7 +367,7 @@ describe('mermaidAPI', () => { } // common suite and tests to verify that the right styles are created with the right htmlElements - function expect_correct_styles_with_htmlElements(mocked_config: MermaidConfig) { + function expect_correct_styles_with_htmlElements(mocked_config: MermaidConfigWithDefaults) { describe('creates styles for "> *" and "span" elements', () => { const htmlElements = ['> *', 'span']; @@ -396,7 +396,7 @@ describe('mermaidAPI', () => { flowchart: { htmlLabels: true, }, - } as MermaidConfig; + } as MermaidConfigWithDefaults; expect_correct_styles_with_htmlElements(mocked_config_flowchart_htmlLabels); }); @@ -405,7 +405,7 @@ describe('mermaidAPI', () => { themeCSS: 'default', fontFamily: 'serif', altFontFamily: 'sans-serif', - } as MermaidConfig; + } as MermaidConfigWithDefaults; describe('creates styles for shape elements "rect", "polygon", "ellipse", and "circle"', () => { const htmlElements = ['rect', 'polygon', 'ellipse', 'circle']; @@ -430,7 +430,7 @@ describe('mermaidAPI', () => { themeCSS: 'default', htmlLabels: true, themeVariables: { fontFamily: 'serif' }, - } as MermaidConfig; + } as MermaidConfigWithDefaults; const classDef1 = { id: 'classDef1', styles: ['style1-1'], textStyles: [] }; diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts index 64508aa68..df79ed7f2 100644 --- a/packages/mermaid/src/mermaidAPI.ts +++ b/packages/mermaid/src/mermaidAPI.ts @@ -20,7 +20,7 @@ import { version } from '../package.json'; import { Diagram } from './Diagram.js'; import { addSVGa11yTitleDescription, setA11yDiagramInfo } from './accessibility.js'; import * as configApi from './config.js'; -import type { MermaidConfig, PartialMermaidConfig } from './config.type.js'; +import type { MermaidConfigWithDefaults, MermaidConfig } from './config.type.js'; import { addDiagrams } from './diagram-api/diagram-orchestration.js'; import type { DiagramMetadata, DiagramStyleClassDef } from './diagram-api/types.js'; import { evaluate } from './diagrams/common/common.js'; @@ -151,7 +151,7 @@ export const cssImportantStyles = ( * @returns the string with all the user styles */ export const createCssStyles = ( - config: MermaidConfig, + config: MermaidConfigWithDefaults, classDefs: Record | null | undefined = {} ): string => { let cssStyles = ''; @@ -198,7 +198,7 @@ export const createCssStyles = ( }; export const createUserStyles = ( - config: MermaidConfig, + config: MermaidConfigWithDefaults, graphType: string, classDefs: Record | undefined, svgId: string @@ -517,7 +517,7 @@ const render = async function ( /** * @param options - Initial Mermaid options */ -function initialize(options: PartialMermaidConfig = {}) { +function initialize(options: MermaidConfig = {}) { // Handle legacy location of font-family configuration if (options?.fontFamily && !options.themeVariables?.fontFamily) { if (!options.themeVariables) { diff --git a/packages/mermaid/src/preprocess.ts b/packages/mermaid/src/preprocess.ts index e8504953b..c7cbc17c7 100644 --- a/packages/mermaid/src/preprocess.ts +++ b/packages/mermaid/src/preprocess.ts @@ -1,4 +1,4 @@ -import type { PartialMermaidConfig } from './config.type.js'; +import type { MermaidConfig } from './config.type.js'; import { cleanupComments } from './diagram-api/comments.js'; import { extractFrontMatter } from './diagram-api/frontmatter.js'; import type { DiagramMetadata } from './diagram-api/types.js'; @@ -31,7 +31,7 @@ const processFrontmatter = (code: string) => { }; const processDirectives = (code: string) => { - const initDirective: PartialMermaidConfig = utils.detectInit(code) ?? {}; + const initDirective: MermaidConfig = utils.detectInit(code) ?? {}; const wrapDirectives = utils.detectDirective(code, 'wrap'); if (Array.isArray(wrapDirectives)) { initDirective.wrap = wrapDirectives.some(({ type }) => { diff --git a/packages/mermaid/src/rendering-util/createText.ts b/packages/mermaid/src/rendering-util/createText.ts index 0a7e3bbb0..3697d6e40 100644 --- a/packages/mermaid/src/rendering-util/createText.ts +++ b/packages/mermaid/src/rendering-util/createText.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ // @ts-nocheck TODO: Fix types -import type { MermaidConfig } from '../config.type.js'; +import type { MermaidConfigWithDefaults } from '../config.type.js'; import type { Group } from '../diagram-api/types.js'; import type { D3TSpanElement, D3TextElement } from '../diagrams/common/commonTypes.js'; import { log } from '../logger.js'; @@ -195,7 +195,7 @@ export const createText = ( width = 200, addSvgBackground = false, } = {}, - config: MermaidConfig + config: MermaidConfigWithDefaults ) => { log.info('createText', text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); if (useHtmlLabels) { diff --git a/packages/mermaid/src/rendering-util/handle-markdown-text.ts b/packages/mermaid/src/rendering-util/handle-markdown-text.ts index 4b20e368d..f5cf0f69d 100644 --- a/packages/mermaid/src/rendering-util/handle-markdown-text.ts +++ b/packages/mermaid/src/rendering-util/handle-markdown-text.ts @@ -1,14 +1,16 @@ -import type { Content } from 'mdast'; import { fromMarkdown } from 'mdast-util-from-markdown'; import { dedent } from 'ts-dedent'; -import type { PartialMermaidConfig } from '../config.type.js'; +import type { MermaidConfigWithDefaults } from '../config.type.js'; import type { MarkdownLine, MarkdownWordType } from './types.js'; +import { RootContent } from 'mdast'; + +type MarkdownConfig = Partial>; /** * @param markdown - markdown to process * @returns processed markdown */ -function preprocessMarkdown(markdown: string, { markdownAutoWrap }: PartialMermaidConfig): string { +function preprocessMarkdown(markdown: string, { markdownAutoWrap }: MarkdownConfig): string { // Replace multiple newlines with a single newline const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, '\n'); // Remove extra spaces at the beginning of each line @@ -22,16 +24,13 @@ function preprocessMarkdown(markdown: string, { markdownAutoWrap }: PartialMerma /** * @param markdown - markdown to split into lines */ -export function markdownToLines( - markdown: string, - config: PartialMermaidConfig = {} -): MarkdownLine[] { +export function markdownToLines(markdown: string, config: MarkdownConfig = {}): MarkdownLine[] { const preprocessedMarkdown = preprocessMarkdown(markdown, config); const { children } = fromMarkdown(preprocessedMarkdown); const lines: MarkdownLine[] = [[]]; let currentLine = 0; - function processNode(node: Content, parentType: MarkdownWordType = 'normal') { + function processNode(node: RootContent, parentType: MarkdownWordType = 'normal') { if (node.type === 'text') { const textLines = node.value.split('\n'); textLines.forEach((textLine, index) => { @@ -63,10 +62,10 @@ export function markdownToLines( return lines; } -export function markdownToHTML(markdown: string, { markdownAutoWrap }: PartialMermaidConfig = {}) { +export function markdownToHTML(markdown: string, { markdownAutoWrap }: MarkdownConfig = {}) { const { children } = fromMarkdown(markdown); - function output(node: Content): string { + function output(node: RootContent): string { if (node.type === 'text') { if (markdownAutoWrap === false) { return node.value.replace(/\n/g, '
').replace(/ /g, ' '); diff --git a/packages/mermaid/src/schemas/config.schema.yaml b/packages/mermaid/src/schemas/config.schema.yaml index 8af9e6314..2a89d4d0b 100644 --- a/packages/mermaid/src/schemas/config.schema.yaml +++ b/packages/mermaid/src/schemas/config.schema.yaml @@ -1,11 +1,11 @@ # Used for VS Code's YAML plugin to automatically error on invalid types # yaml-language-server: $schema=https://json-schema.org/draft/2019-09/schema -# This file defines the MermaidConfig JSON Schema as a YAML file. +# This file defines the MermaidConfigWithDefaults JSON Schema as a YAML file. # # From this file, the following things can be generated: # - `scripts/create-types-from-json-schema.mjs` -# Used to generate the `src/config.type.ts` TypeScript types for MermaidConfig +# Used to generate the `src/config.type.ts` TypeScript types for MermaidConfigWithDefaults # with the `json-schema-to-typescript` NPM package. # - `.build/jsonSchema.ts` # Used to generate the default values from the `default` keys in this @@ -20,13 +20,13 @@ # - Use the `|` character for multi-line strings # - Use `meta:enum` to document enum values (from jsonschema2md) # - Use `tsType` to override the TypeScript type (from json-schema-to-typescript) -# - If adding a new object to `MermaidConfig` (e.g. a new diagram type), +# - If adding a new object to `MermaidConfigWithDefaults` (e.g. a new diagram type), # you may need to add it to `.build/jsonSchema.ts`, `src/docs.mts` # and `scripts/create-types-from-json-schema.mjs` # to get the default values/docs/types to generate properly. $id: https://mermaid.js.org/schemas/config.schema.json $schema: https://json-schema.org/draft/2019-09/schema -title: Mermaid Config +title: MermaidConfigWithDefaults type: object additionalProperties: false required: @@ -261,11 +261,11 @@ properties: This is useful when you want to control how to handle syntax errors in your application. $defs: # JSON Schema definition (maybe we should move these to a separate file) - PartialMermaidConfig: - title: PartialMermaidConfig - description: MermaidConfig with all fields optional + MermaidConfig: + title: MermaidConfig + description: MermaidConfigWithDefaults with all fields optional type: object - tsType: "import('type-fest').PartialDeep" + tsType: "import('type-fest').PartialDeep" BaseDiagramConfig: # TODO: More config needs to be moved here title: Base Diagram Config diff --git a/packages/mermaid/src/utils.ts b/packages/mermaid/src/utils.ts index c05706714..fd1132eba 100644 --- a/packages/mermaid/src/utils.ts +++ b/packages/mermaid/src/utils.ts @@ -26,7 +26,7 @@ import { import memoize from 'lodash-es/memoize.js'; import merge from 'lodash-es/merge.js'; import assignWithDepth from './assignWithDepth.js'; -import type { MermaidConfig, PartialMermaidConfig } from './config.type.js'; +import type { MermaidConfigWithDefaults, MermaidConfig } from './config.type.js'; import { detectType } from './diagram-api/detectType.js'; import { directiveRegex } from './diagram-api/regexes.js'; import common from './diagrams/common/common.js'; @@ -97,16 +97,16 @@ const directiveWithoutOpen = * @param config - Optional mermaid configuration object. * @returns The json object representing the init passed to mermaid.initialize() */ -export const detectInit = function (text: string): PartialMermaidConfig | undefined { +export const detectInit = function (text: string): MermaidConfig | undefined { const inits = detectDirective(text, /(?:init\b)|(?:initialize\b)/); - let results: PartialMermaidConfig & { config?: unknown } = {}; + let results: MermaidConfig & { config?: unknown } = {}; if (Array.isArray(inits)) { const args = inits.map((init) => init.args); sanitizeDirective(args); results = assignWithDepth(results, [...args]); } else { - results = inits.args as PartialMermaidConfig; + results = inits.args as MermaidConfig; } if (!results) { @@ -121,7 +121,7 @@ export const detectInit = function (text: string): PartialMermaidConfig | undefi if (type === 'flowchart-v2') { type = 'flowchart'; } - results[type as keyof MermaidConfig] = results[prop]; + results[type as keyof MermaidConfigWithDefaults] = results[prop]; delete results[prop]; } @@ -249,7 +249,7 @@ export function interpolateToCurve( */ export function formatUrl( linkStr: string, - config: Pick + config: Pick ): string | undefined { const url = linkStr.trim();