5043 Allow registered diagrams to be overridden.

This commit is contained in:
Sidharth Vinod
2023-11-20 00:29:13 +05:30
parent 0fec0ef624
commit 38b3a2080b
4 changed files with 42 additions and 23 deletions

View File

@@ -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' : ''}`);
}; };

View File

@@ -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) {

View File

@@ -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:

View File

@@ -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();