diff --git a/cypress/integration/rendering/sequencediagram-v2.spec.js b/cypress/integration/rendering/sequencediagram-v2.spec.js index 9e5686322..488e41613 100644 --- a/cypress/integration/rendering/sequencediagram-v2.spec.js +++ b/cypress/integration/rendering/sequencediagram-v2.spec.js @@ -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 } } + ); + }); + }); }); }); diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDb.ts b/packages/mermaid/src/diagrams/sequence/sequenceDb.ts index d4758f39e..3d79b9ea6 100644 --- a/packages/mermaid/src/diagrams/sequence/sequenceDb.ts +++ b/packages/mermaid/src/diagrams/sequence/sequenceDb.ts @@ -172,6 +172,12 @@ export class SequenceDB implements DiagramDB { doc = yaml.load(yamlData, { schema: yaml.JSON_SCHEMA }) as ParticipantMetaData; } 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); if (old) { // If already set and trying to set to a new one throw error diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js index c5110c19c..7b75f1d43 100644 --- a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js +++ b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js @@ -2661,5 +2661,74 @@ Bob->>Alice:Got it! expect(actors.get('API').type).toBe('boundary'); 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'); + }); }); }); diff --git a/packages/mermaid/src/types.ts b/packages/mermaid/src/types.ts index 727b6bb3a..499404106 100644 --- a/packages/mermaid/src/types.ts +++ b/packages/mermaid/src/types.ts @@ -23,6 +23,7 @@ export interface ParticipantMetaData { | 'database' | 'collections' | 'queue'; + alias?: string; } export interface EdgeMetaData {