mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-11-26 23:54:09 +01:00
Merge pull request #7136 from mermaid-js/feat/sequence-alias-support-new-participant-syntax
feat : add alias support for new participant syntax
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
[0-9]+(?=[ \n]+) return 'NUM';
|
||||
<ID>\@\{ { this.begin('CONFIG'); return 'CONFIG_START'; }
|
||||
<CONFIG>[^\}]+ { return 'CONFIG_CONTENT'; }
|
||||
<CONFIG>\}(?=\s+as\s) { this.popState(); this.begin('ALIAS'); return 'CONFIG_END'; }
|
||||
<CONFIG>\} { this.popState(); this.popState(); return 'CONFIG_END'; }
|
||||
<ID>[^\<->\->:\n,;@\s]+(?=\@\{) { yytext = yytext.trim(); return 'ACTOR'; }
|
||||
<ID>[^<>:\n,;@\s]+(?=\s+as\s) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
|
||||
@@ -264,7 +265,10 @@ participant_statement
|
||||
| 'participant_actor' actor 'AS' restOfLine 'NEWLINE' {$2.draw='actor'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;}
|
||||
| 'participant_actor' actor 'NEWLINE' {$2.draw='actor'; $2.type='addParticipant'; $$=$2;}
|
||||
| 'destroy' actor 'NEWLINE' {$2.type='destroyParticipant'; $$=$2;}
|
||||
| 'participant' actor_with_config 'AS' restOfLine 'NEWLINE' {$2.draw='participant'; $2.type='addParticipant'; $2.description=yy.parseMessage($4); $$=$2;}
|
||||
| 'participant' actor_with_config 'NEWLINE' {$2.draw='participant'; $2.type='addParticipant'; $$=$2;}
|
||||
| 'participant_actor' actor_with_config 'AS' restOfLine 'NEWLINE' {$2.draw='actor'; $2.type='addParticipant'; $2.description=yy.parseMessage($4); $$=$2;}
|
||||
| 'participant_actor' actor_with_config 'NEWLINE' {$2.draw='actor'; $2.type='addParticipant'; $$=$2;}
|
||||
|
||||
;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2621,5 +2621,114 @@ Bob->>Alice:Got it!
|
||||
}
|
||||
expect(error).toBe(true);
|
||||
});
|
||||
|
||||
it('should parse participant with stereotype and alias', async () => {
|
||||
const diagram = await Diagram.fromText(`
|
||||
sequenceDiagram
|
||||
participant Alice@{ "type" : "boundary" } as Public API
|
||||
participant Bob@{ "type" : "control" } as Controller
|
||||
Alice->>Bob: Request
|
||||
Bob-->>Alice: Response
|
||||
`);
|
||||
const actors = diagram.db.getActors();
|
||||
expect(actors.get('Alice').type).toBe('boundary');
|
||||
expect(actors.get('Alice').description).toBe('Public API');
|
||||
expect(actors.get('Bob').type).toBe('control');
|
||||
expect(actors.get('Bob').description).toBe('Controller');
|
||||
});
|
||||
|
||||
it('should parse actor with stereotype and alias', async () => {
|
||||
const diagram = await Diagram.fromText(`
|
||||
sequenceDiagram
|
||||
actor A@{ "type" : "database" } AS Database Server
|
||||
actor B@{ "type" : "queue" } as Message Queue
|
||||
A->>B: Send message
|
||||
`);
|
||||
const actors = diagram.db.getActors();
|
||||
expect(actors.get('A').type).toBe('database');
|
||||
expect(actors.get('A').description).toBe('Database Server');
|
||||
expect(actors.get('B').type).toBe('queue');
|
||||
expect(actors.get('B').description).toBe('Message Queue');
|
||||
});
|
||||
|
||||
it('should parse participant with stereotype and simple alias', async () => {
|
||||
const diagram = await Diagram.fromText(`
|
||||
sequenceDiagram
|
||||
participant API@{ "type" : "boundary" } AS Public API
|
||||
API->>API: test
|
||||
`);
|
||||
const actors = diagram.db.getActors();
|
||||
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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -120,7 +120,11 @@ sequenceDiagram
|
||||
|
||||
### Aliases
|
||||
|
||||
The actor can have a convenient identifier and a descriptive label.
|
||||
The actor can have a convenient identifier and a descriptive label. Aliases can be defined in two ways: using external syntax with the `as` keyword, or inline within the configuration object.
|
||||
|
||||
#### External Alias Syntax
|
||||
|
||||
You can define an alias using the `as` keyword after the participant declaration:
|
||||
|
||||
```mermaid-example
|
||||
sequenceDiagram
|
||||
@@ -130,6 +134,48 @@ sequenceDiagram
|
||||
J->>A: Great!
|
||||
```
|
||||
|
||||
The external alias syntax also works with participant stereotype configurations, allowing you to combine type specification with aliases:
|
||||
|
||||
```mermaid-example
|
||||
sequenceDiagram
|
||||
participant API@{ "type": "boundary" } as Public API
|
||||
actor DB@{ "type": "database" } as User Database
|
||||
participant Svc@{ "type": "control" } as Auth Service
|
||||
API->>Svc: Authenticate
|
||||
Svc->>DB: Query user
|
||||
DB-->>Svc: User data
|
||||
Svc-->>API: Token
|
||||
```
|
||||
|
||||
#### Inline Alias Syntax
|
||||
|
||||
Alternatively, you can define an alias directly inside the configuration object using the `"alias"` field. This works with both `participant` and `actor` keywords:
|
||||
|
||||
```mermaid-example
|
||||
sequenceDiagram
|
||||
participant API@{ "type": "boundary", "alias": "Public API" }
|
||||
participant Auth@{ "type": "control", "alias": "Auth Service" }
|
||||
participant DB@{ "type": "database", "alias": "User Database" }
|
||||
API->>Auth: Login request
|
||||
Auth->>DB: Query user
|
||||
DB-->>Auth: User data
|
||||
Auth-->>API: Access token
|
||||
```
|
||||
|
||||
#### Alias Precedence
|
||||
|
||||
When both inline alias (in the configuration object) and external alias (using `as` keyword) are provided, the **external alias takes precedence**:
|
||||
|
||||
```mermaid-example
|
||||
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
|
||||
```
|
||||
|
||||
In the example above, "External Name" and "External DB" will be displayed, not "Internal Name" and "Internal DB".
|
||||
|
||||
### Actor Creation and Destruction (v10.3.0+)
|
||||
|
||||
It is possible to create and destroy actors by messages. To do so, add a create or destroy directive before the message.
|
||||
|
||||
@@ -23,6 +23,7 @@ export interface ParticipantMetaData {
|
||||
| 'database'
|
||||
| 'collections'
|
||||
| 'queue';
|
||||
alias?: string;
|
||||
}
|
||||
|
||||
export interface EdgeMetaData {
|
||||
|
||||
Reference in New Issue
Block a user