feat: add inline alias attribute support for participants and actors in sequence diagrams

on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
This commit is contained in:
omkarht
2025-11-14 12:15:03 +05:30
parent 6bc6617ca6
commit 96f87fd597
4 changed files with 142 additions and 0 deletions

View File

@@ -899,5 +899,71 @@ describe('Sequence Diagram Special Cases', () => {
); );
}); });
}); });
describe('Participant Inline Alias in Config', () => {
it('should render participants with inline alias in config object', () => {
imgSnapshotTest(
`sequenceDiagram
participant API@{ "type" : "boundary", "alias": "Public API" }
participant Auth@{ "type" : "control", "alias": "Auth Service" }
participant DB@{ "type" : "database", "alias": "User DB" }
API ->> Auth: Login request
Auth ->> DB: Query user
DB -->> Auth: User data
Auth -->> API: Token`,
{ look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
);
});
it('should render actors with inline alias in config object', () => {
imgSnapshotTest(
`sequenceDiagram
actor U@{ "type" : "actor", "alias": "End User" }
actor G@{ "type" : "boundary", "alias": "Gateway" }
actor S@{ "type" : "control", "alias": "Service" }
U ->> G: Request
G ->> S: Process
S -->> G: Response
G -->> U: Result`,
{ look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
);
});
it('should handle mixed inline and external alias syntax', () => {
imgSnapshotTest(
`sequenceDiagram
participant A@{ "type" : "boundary", "alias": "Service A" }
participant B@{ "type" : "control" } as Service B
participant C@{ "type" : "database" }
A ->> B: Request
B ->> C: Query
C -->> B: Data
B -->> A: Response`,
{ look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
);
});
it('should prioritize external alias over inline alias', () => {
imgSnapshotTest(
`sequenceDiagram
participant API@{ "type" : "boundary", "alias": "Internal Name" } as External Name
participant DB@{ "type" : "database", "alias": "Internal DB" } AS External DB
API ->> DB: Query
DB -->> API: Result`,
{ look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
);
});
it('should render inline alias with only alias field (no type)', () => {
imgSnapshotTest(
`sequenceDiagram
participant API@{ "alias": "Public API" }
participant Auth@{ "alias": "Auth Service" }
API ->> Auth: Request
Auth -->> API: Response`,
{ look: 'classic', sequence: { diagramMarginX: 50, diagramMarginY: 10 } }
);
});
});
}); });
}); });

View File

@@ -172,6 +172,12 @@ export class SequenceDB implements DiagramDB {
doc = yaml.load(yamlData, { schema: yaml.JSON_SCHEMA }) as ParticipantMetaData; doc = yaml.load(yamlData, { schema: yaml.JSON_SCHEMA }) as ParticipantMetaData;
} }
type = doc?.type ?? type; type = doc?.type ?? type;
// If alias is provided in metadata and description is not already set, use the alias
if (doc?.alias && (!description || description.text === name)) {
description = { text: doc.alias, wrap: description?.wrap, type };
}
const old = this.state.records.actors.get(id); const old = this.state.records.actors.get(id);
if (old) { if (old) {
// If already set and trying to set to a new one throw error // If already set and trying to set to a new one throw error

View File

@@ -2661,5 +2661,74 @@ Bob->>Alice:Got it!
expect(actors.get('API').type).toBe('boundary'); expect(actors.get('API').type).toBe('boundary');
expect(actors.get('API').description).toBe('Public API'); expect(actors.get('API').description).toBe('Public API');
}); });
it('should parse participant with inline alias in config object', async () => {
const diagram = await Diagram.fromText(`
sequenceDiagram
participant API@{ "type" : "boundary", "alias": "Public API" }
participant Auth@{ "type" : "control", "alias": "Auth Controller" }
API->>Auth: Request
Auth-->>API: Response
`);
const actors = diagram.db.getActors();
expect(actors.get('API').type).toBe('boundary');
expect(actors.get('API').description).toBe('Public API');
expect(actors.get('Auth').type).toBe('control');
expect(actors.get('Auth').description).toBe('Auth Controller');
});
it('should parse actor with inline alias in config object', async () => {
const diagram = await Diagram.fromText(`
sequenceDiagram
actor U@{ "type" : "actor", "alias": "End User" }
actor DB@{ "type" : "database", "alias": "User Database" }
U->>DB: Query
DB-->>U: Result
`);
const actors = diagram.db.getActors();
expect(actors.get('U').type).toBe('actor');
expect(actors.get('U').description).toBe('End User');
expect(actors.get('DB').type).toBe('database');
expect(actors.get('DB').description).toBe('User Database');
});
it('should prioritize external alias over inline alias', async () => {
const diagram = await Diagram.fromText(`
sequenceDiagram
participant API@{ "type" : "boundary", "alias": "Internal Name" } as External Name
API->>API: test
`);
const actors = diagram.db.getActors();
expect(actors.get('API').type).toBe('boundary');
expect(actors.get('API').description).toBe('External Name');
});
it('should handle participant with only inline alias (no type)', async () => {
const diagram = await Diagram.fromText(`
sequenceDiagram
participant API@{ "alias": "Public API" }
API->>API: test
`);
const actors = diagram.db.getActors();
expect(actors.get('API').description).toBe('Public API');
});
it('should handle mixed inline and external alias syntax', async () => {
const diagram = await Diagram.fromText(`
sequenceDiagram
participant A@{ "type" : "boundary", "alias": "Service A" }
participant B@{ "type" : "control" } as Service B
participant C@{ "type" : "database" }
A->>B: Request
B->>C: Query
`);
const actors = diagram.db.getActors();
expect(actors.get('A').type).toBe('boundary');
expect(actors.get('A').description).toBe('Service A');
expect(actors.get('B').type).toBe('control');
expect(actors.get('B').description).toBe('Service B');
expect(actors.get('C').type).toBe('database');
expect(actors.get('C').description).toBe('C');
});
}); });
}); });

View File

@@ -23,6 +23,7 @@ export interface ParticipantMetaData {
| 'database' | 'database'
| 'collections' | 'collections'
| 'queue'; | 'queue';
alias?: string;
} }
export interface EdgeMetaData { export interface EdgeMetaData {