mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-23 17:29:54 +02:00
5043 Allow registered diagrams to be overridden.
This commit is contained in:
@@ -71,10 +71,9 @@ export const registerLazyLoadedDiagrams = (...diagrams: ExternalDiagramDefinitio
|
|||||||
|
|
||||||
export const addDetector = (key: string, detector: DiagramDetector, loader?: DiagramLoader) => {
|
export const addDetector = (key: string, detector: DiagramDetector, loader?: DiagramLoader) => {
|
||||||
if (detectors[key]) {
|
if (detectors[key]) {
|
||||||
log.error(`Detector with key ${key} already exists`);
|
log.warn(`Detector with key ${key} already exists. Overwriting.`);
|
||||||
} else {
|
|
||||||
detectors[key] = { detector, loader };
|
|
||||||
}
|
}
|
||||||
|
detectors[key] = { detector, loader };
|
||||||
log.debug(`Detector with key ${key} added${loader ? ' with loader' : ''}`);
|
log.debug(`Detector with key ${key} added${loader ? ' with loader' : ''}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -49,7 +49,7 @@ export const registerDiagram = (
|
|||||||
detector?: DiagramDetector
|
detector?: DiagramDetector
|
||||||
) => {
|
) => {
|
||||||
if (diagrams[id]) {
|
if (diagrams[id]) {
|
||||||
throw new Error(`Diagram ${id} already registered.`);
|
log.warn(`Diagram with id ${id} already registered. Overwriting.`);
|
||||||
}
|
}
|
||||||
diagrams[id] = diagram;
|
diagrams[id] = diagram;
|
||||||
if (detector) {
|
if (detector) {
|
||||||
|
@@ -2,9 +2,32 @@ import { describe, test, expect } from 'vitest';
|
|||||||
import { Diagram, getDiagramFromText } from './Diagram.js';
|
import { Diagram, getDiagramFromText } from './Diagram.js';
|
||||||
import { addDetector } from './diagram-api/detectType.js';
|
import { addDetector } from './diagram-api/detectType.js';
|
||||||
import { addDiagrams } from './diagram-api/diagram-orchestration.js';
|
import { addDiagrams } from './diagram-api/diagram-orchestration.js';
|
||||||
|
import type { DiagramLoader } from './diagram-api/types.js';
|
||||||
|
|
||||||
addDiagrams();
|
addDiagrams();
|
||||||
|
|
||||||
|
const getDummyDiagram = (id: string, title?: string): Awaited<ReturnType<DiagramLoader>> => {
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
diagram: {
|
||||||
|
db: {
|
||||||
|
getDiagramTitle: () => title ?? id,
|
||||||
|
},
|
||||||
|
parser: {
|
||||||
|
parse: () => {
|
||||||
|
// no-op
|
||||||
|
},
|
||||||
|
},
|
||||||
|
renderer: {
|
||||||
|
draw: () => {
|
||||||
|
// no-op
|
||||||
|
},
|
||||||
|
},
|
||||||
|
styles: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
describe('diagram detection', () => {
|
describe('diagram detection', () => {
|
||||||
test('should detect inbuilt diagrams', async () => {
|
test('should detect inbuilt diagrams', async () => {
|
||||||
const graph = (await getDiagramFromText('graph TD; A-->B')) as Diagram;
|
const graph = (await getDiagramFromText('graph TD; A-->B')) as Diagram;
|
||||||
@@ -21,30 +44,25 @@ describe('diagram detection', () => {
|
|||||||
addDetector(
|
addDetector(
|
||||||
'loki',
|
'loki',
|
||||||
(str) => str.startsWith('loki'),
|
(str) => str.startsWith('loki'),
|
||||||
() =>
|
() => Promise.resolve(getDummyDiagram('loki'))
|
||||||
Promise.resolve({
|
|
||||||
id: 'loki',
|
|
||||||
diagram: {
|
|
||||||
db: {},
|
|
||||||
parser: {
|
|
||||||
parse: () => {
|
|
||||||
// no-op
|
|
||||||
},
|
|
||||||
},
|
|
||||||
renderer: {
|
|
||||||
draw: () => {
|
|
||||||
// no-op
|
|
||||||
},
|
|
||||||
},
|
|
||||||
styles: {},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
const diagram = (await getDiagramFromText('loki TD; A-->B')) as Diagram;
|
const diagram = await getDiagramFromText('loki TD; A-->B');
|
||||||
expect(diagram).toBeInstanceOf(Diagram);
|
expect(diagram).toBeInstanceOf(Diagram);
|
||||||
expect(diagram.type).toBe('loki');
|
expect(diagram.type).toBe('loki');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should allow external diagrams to override internal ones with same ID', async () => {
|
||||||
|
const title = 'overridden';
|
||||||
|
addDetector(
|
||||||
|
'flowchart-elk',
|
||||||
|
(str) => str.startsWith('flowchart-elk'),
|
||||||
|
() => Promise.resolve(getDummyDiagram('flowchart-elk', title))
|
||||||
|
);
|
||||||
|
const diagram = await getDiagramFromText('flowchart-elk TD; A-->B');
|
||||||
|
expect(diagram).toBeInstanceOf(Diagram);
|
||||||
|
expect(diagram.db.getDiagramTitle?.()).toBe(title);
|
||||||
|
});
|
||||||
|
|
||||||
test('should throw the right error for incorrect diagram', async () => {
|
test('should throw the right error for incorrect diagram', async () => {
|
||||||
await expect(getDiagramFromText('graph TD; A-->')).rejects.toThrowErrorMatchingInlineSnapshot(`
|
await expect(getDiagramFromText('graph TD; A-->')).rejects.toThrowErrorMatchingInlineSnapshot(`
|
||||||
"Parse error on line 2:
|
"Parse error on line 2:
|
||||||
|
@@ -15,6 +15,7 @@ import { isDetailedError } from './utils.js';
|
|||||||
import type { DetailedError } from './utils.js';
|
import type { DetailedError } from './utils.js';
|
||||||
import type { ExternalDiagramDefinition } from './diagram-api/types.js';
|
import type { ExternalDiagramDefinition } from './diagram-api/types.js';
|
||||||
import type { UnknownDiagramError } from './errors.js';
|
import type { UnknownDiagramError } from './errors.js';
|
||||||
|
import { addDiagrams } from './diagram-api/diagram-orchestration.js';
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
MermaidConfig,
|
MermaidConfig,
|
||||||
@@ -243,6 +244,7 @@ const registerExternalDiagrams = async (
|
|||||||
lazyLoad?: boolean;
|
lazyLoad?: boolean;
|
||||||
} = {}
|
} = {}
|
||||||
) => {
|
) => {
|
||||||
|
addDiagrams();
|
||||||
registerLazyLoadedDiagrams(...diagrams);
|
registerLazyLoadedDiagrams(...diagrams);
|
||||||
if (lazyLoad === false) {
|
if (lazyLoad === false) {
|
||||||
await loadRegisteredDiagrams();
|
await loadRegisteredDiagrams();
|
||||||
|
Reference in New Issue
Block a user