diff --git a/packages/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison b/packages/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison index 442bec590..87ef8212f 100644 --- a/packages/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison +++ b/packages/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison @@ -12,7 +12,6 @@ %options case-insensitive - // Special states for recognizing aliases // A special state for grabbing text up to the first comment/newline %x ID ALIAS LINE CONFIG CONFIG_DATA @@ -22,92 +21,79 @@ %x acc_descr_multiline %% -[\n]+ { console.log("NEWLINE"); return 'NEWLINE'; } -\s+ { console.log("WHITESPACE"); /* skip whitespace */ } -((?!\n)\s)+ { console.log("SAME-LINE-WHITESPACE"); /* skip same-line whitespace */ } -\#[^\n]* { console.log("COMMENT"); /* skip comments */ } -\%%(?!\{)[^\n]* { console.log("COMMENT"); /* skip comments */ } -[^\}]\%\%[^\n]* { console.log("COMMENT"); /* skip comments */ } -[0-9]+(?=[ \n]+) { console.log("NUM:", yytext); return 'NUM'; } -// Enhanced config handling rules - moved before other ID rules for proper precedence -\@\{ { console.log("CONFIG_START"); this.begin('CONFIG'); return 'CONFIG_START'; } -[^\}]+ { console.log("CONFIG_CONTENT:", yytext); return 'CONFIG_CONTENT'; } -\} { console.log("CONFIG_END"); this.popState(); this.popState(); return 'CONFIG_END'; } -// ACTOR_WITH_CONFIG rule must come before general ACTOR rule for proper precedence -[^\<->\->:\n,;@]+?([\-]*[^\<->\->:\n,;@]+?)*?(?=\@\{) { console.log("LEXER:ACTOR_WITH_CONFIG_OBJECT:", yytext); yytext = yytext.trim(); return 'ACTOR_WITH_CONFIG'; } -// General ACTOR rule - now comes after the more specific ACTOR_WITH_CONFIG rule -[^\<->\->:\n,;@]+?([\-]*[^\<->\->:\n,;@]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { console.log("ACTOR:", yytext); yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; } -"box" { console.log("BOX"); this.begin('LINE'); return 'box'; } -"participant" { console.log("PARTICIPANT"); this.begin('ID'); return 'participant'; } -"actor" { console.log("ACTOR_TYPE_ACTOR"); this.begin('ID'); return 'participant_actor'; } -"boundary" { return yy.matchAsActorOrParticipant('boundary', 'participant_boundary', this._input, this); } -"control" { return yy.matchAsActorOrParticipant('control', 'participant_control', this._input, this); } -"entity" { return yy.matchAsActorOrParticipant('entity', 'participant_entity', this._input, this); } -"database" { return yy.matchAsActorOrParticipant('database', 'participant_database', this._input, this); } -"collections" { return yy.matchAsActorOrParticipant('collections', 'participant_collections', this._input, this); } -"queue" { return yy.matchAsActorOrParticipant('queue', 'participant_queue', this._input, this); } -"create" { console.log("CREATE"); return 'create'; } -"destroy" { console.log("DESTROY"); this.begin('ID'); return 'destroy'; } -"as" { console.log("AS"); this.popState(); this.popState(); this.begin('LINE'); return 'AS'; } -(?:) { console.log("ALIAS_END"); this.popState(); this.popState(); return 'NEWLINE'; } -// // Enhanced config handling rules -// \@\{ { console.log("CONFIG_START"); this.begin('CONFIG'); return 'CONFIG_START'; } -// [^\}]+ { console.log("CONFIG_CONTENT:", yytext); return 'CONFIG_CONTENT'; } -// \} { console.log("CONFIG_END"); this.popState(); return 'CONFIG_END'; } -"loop" { console.log("LOOP"); this.begin('LINE'); return 'loop'; } -"rect" { console.log("RECT"); this.begin('LINE'); return 'rect'; } -"opt" { console.log("OPT"); this.begin('LINE'); return 'opt'; } -"alt" { console.log("ALT"); this.begin('LINE'); return 'alt'; } -"else" { console.log("ELSE"); this.begin('LINE'); return 'else'; } -"par" { console.log("PAR"); this.begin('LINE'); return 'par'; } -"par_over" { console.log("PAR_OVER"); this.begin('LINE'); return 'par_over'; } -"and" { console.log("AND"); this.begin('LINE'); return 'and'; } -"critical" { console.log("CRITICAL"); this.begin('LINE'); return 'critical'; } -"option" { console.log("OPTION"); this.begin('LINE'); return 'option'; } -"break" { console.log("BREAK"); this.begin('LINE'); return 'break'; } -(?:[:]?(?:no)?wrap:)?[^#\n;]* { console.log("REST_OF_LINE:", yytext); this.popState(); return 'restOfLine'; } -"end" { console.log("END"); return 'end'; } -"left of" { console.log("LEFT_OF"); return 'left_of'; } -"right of" { console.log("RIGHT_OF"); return 'right_of'; } -"links" { console.log("LINKS"); return 'links'; } -"link" { console.log("LINK"); return 'link'; } -"properties" { console.log("PROPERTIES"); return 'properties'; } -"details" { console.log("DETAILS"); return 'details'; } -"over" { console.log("OVER"); return 'over'; } -"note" { console.log("NOTE"); return 'note'; } -"activate" { console.log("ACTIVATE"); this.begin('ID'); return 'activate'; } -"deactivate" { console.log("DEACTIVATE"); this.begin('ID'); return 'deactivate'; } -"title"\s[^#\n;]+ { console.log("TITLE"); return 'title'; } -"title:"\s[^#\n;]+ { console.log("LEGACY_TITLE"); return 'legacy_title'; } -accTitle\s*":"\s* { console.log("ACC_TITLE"); this.begin("acc_title"); return 'acc_title'; } -(?!\n|;|#)*[^\n]* { console.log("ACC_TITLE_VALUE:", yytext); this.popState(); return "acc_title_value"; } -accDescr\s*":"\s* { console.log("ACC_DESCR"); this.begin("acc_descr"); return 'acc_descr'; } -(?!\n|;|#)*[^\n]* { console.log("ACC_DESCR_VALUE:", yytext); this.popState(); return "acc_descr_value"; } -accDescr\s*"{"\s* { console.log("ACC_DESCR_MULTILINE_START"); this.begin("acc_descr_multiline"); } -[\}] { console.log("ACC_DESCR_MULTILINE_END"); this.popState(); } -[^\}]* { console.log("ACC_DESCR_MULTILINE_VALUE:", yytext); return "acc_descr_multiline_value"; } -"sequenceDiagram" { console.log("SEQUENCE_DIAGRAM"); return 'SD'; } -"autonumber" { console.log("AUTONUMBER"); return 'autonumber'; } -"off" { console.log("OFF"); return 'off'; } -"," { console.log("COMMA"); return ','; } -";" { console.log("SEMICOLON"); return 'NEWLINE'; } -[^\+\<->\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+\<->\->:\n,;]+)* { console.log("ACTOR_GENERIC:", yytext); yytext = yytext.trim(); return 'ACTOR'; } -"->>" { console.log("SOLID_ARROW"); return 'SOLID_ARROW'; } -"<<->>" { console.log("BIDIRECTIONAL_SOLID_ARROW"); return 'BIDIRECTIONAL_SOLID_ARROW'; } -"-->>" { console.log("DOTTED_ARROW"); return 'DOTTED_ARROW'; } -"<<-->>" { console.log("BIDIRECTIONAL_DOTTED_ARROW"); return 'BIDIRECTIONAL_DOTTED_ARROW'; } -"->" { console.log("SOLID_OPEN_ARROW"); return 'SOLID_OPEN_ARROW'; } -"-->" { console.log("DOTTED_OPEN_ARROW"); return 'DOTTED_OPEN_ARROW'; } -\-[x] { console.log("SOLID_CROSS"); return 'SOLID_CROSS'; } -\-\-[x] { console.log("DOTTED_CROSS"); return 'DOTTED_CROSS'; } -\-[\)] { console.log("SOLID_POINT"); return 'SOLID_POINT'; } -\-\-[\)] { console.log("DOTTED_POINT"); return 'DOTTED_POINT'; } -":"(?:(?:no)?wrap:)?[^#\n;]* { console.log("TEXT_WITH_WRAP:", yytext); return 'TXT'; } -":" { console.log("TEXT"); return 'TXT'; } -"+" { console.log("PLUS"); return '+'; } -"-" { console.log("MINUS"); return '-'; } -<> { console.log("EOF"); return 'NEWLINE'; } -. { console.log("INVALID:", yytext); return 'INVALID'; } +[\n]+ return 'NEWLINE'; +\s+ /* skip all whitespace */ +((?!\n)\s)+ /* skip same-line whitespace */ +\#[^\n]* /* skip comments */ +\%%(?!\{)[^\n]* /* skip comments */ +[^\}]\%\%[^\n]* /* skip comments */ +[0-9]+(?=[ \n]+) return 'NUM'; +\@\{ { this.begin('CONFIG'); return 'CONFIG_START'; } +[^\}]+ { return 'CONFIG_CONTENT'; } +\} { this.popState(); this.popState(); return 'CONFIG_END'; } +[^\<->\->:\n,;@]+?([\-]*[^\<->\->:\n,;@]+?)*?(?=\@\{) { yytext = yytext.trim(); return 'ACTOR'; } +[^\<->\->:\n,;@]+?([\-]*[^\<->\->:\n,;@]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; } +"box" { this.begin('LINE'); return 'box'; } +"participant" { this.begin('ID'); return 'participant'; } +"actor" { this.begin('ID'); return 'participant_actor'; } +"create" return 'create'; +"destroy" { this.begin('ID'); return 'destroy'; } +"as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; } +(?:) { this.popState(); this.popState(); return 'NEWLINE'; } +"loop" { this.begin('LINE'); return 'loop'; } +"rect" { this.begin('LINE'); return 'rect'; } +"opt" { this.begin('LINE'); return 'opt'; } +"alt" { this.begin('LINE'); return 'alt'; } +"else" { this.begin('LINE'); return 'else'; } +"par" { this.begin('LINE'); return 'par'; } +"par_over" { this.begin('LINE'); return 'par_over'; } +"and" { this.begin('LINE'); return 'and'; } +"critical" { this.begin('LINE'); return 'critical'; } +"option" { this.begin('LINE'); return 'option'; } +"break" { this.begin('LINE'); return 'break'; } +(?:[:]?(?:no)?wrap:)?[^#\n;]* { this.popState(); return 'restOfLine'; } +"end" return 'end'; +"left of" return 'left_of'; +"right of" return 'right_of'; +"links" return 'links'; +"link" return 'link'; +"properties" return 'properties'; +"details" return 'details'; +"over" return 'over'; +"note" return 'note'; +"activate" { this.begin('ID'); return 'activate'; } +"deactivate" { this.begin('ID'); return 'deactivate'; } +"title"\s[^#\n;]+ return 'title'; +"title:"\s[^#\n;]+ return 'legacy_title'; +accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; } +(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; } +accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; } +(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; } +accDescr\s*"{"\s* { this.begin("acc_descr_multiline");} +[\}] { this.popState(); } +[^\}]* return "acc_descr_multiline_value"; +"sequenceDiagram" return 'SD'; +"autonumber" return 'autonumber'; +"off" return 'off'; +"," return ','; +";" return 'NEWLINE'; +[^\+\<->\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+\<->\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; } +"->>" return 'SOLID_ARROW'; +"<<->>" return 'BIDIRECTIONAL_SOLID_ARROW'; +"-->>" return 'DOTTED_ARROW'; +"<<-->>" return 'BIDIRECTIONAL_DOTTED_ARROW'; +"->" return 'SOLID_OPEN_ARROW'; +"-->" return 'DOTTED_OPEN_ARROW'; +\-[x] return 'SOLID_CROSS'; +\-\-[x] return 'DOTTED_CROSS'; +\-[\)] return 'SOLID_POINT'; +\-\-[\)] return 'DOTTED_POINT'; +":"(?:(?:no)?wrap:)?[^#\n;]* return 'TXT'; +":" return 'TXT'; +"+" return '+'; +"-" return '-'; +<> return 'NEWLINE'; +. return 'INVALID'; /lex @@ -244,56 +230,12 @@ else_sections ; participant_statement - : 'participant' actor_with_config 'AS' restOfLine 'NEWLINE' - { - console.log('Participant with config and alias:', $2, $4); - $2.draw = 'participant'; - $2.type = 'addParticipant'; - $2.description = yy.parseMessage($4); - $$ = $2; - } - | 'participant' actor_with_config 'NEWLINE' - { - console.log('Participant with config without alias:', $2); - $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; - } - | 'destroy' actor 'NEWLINE' - { - $2.type = 'destroyParticipant'; - $$ = $2; - } - | 'participant_boundary' actor 'AS' restOfLine 'NEWLINE' {$2.draw='boundary'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;} - | 'participant_boundary' actor 'NEWLINE' {$2.draw='boundary'; $2.type='addParticipant'; $$=$2;} - - | 'participant_control' actor 'AS' restOfLine 'NEWLINE' {$2.draw='control'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;} - | 'participant_control' actor 'NEWLINE' {$2.draw='control'; $2.type='addParticipant'; $$=$2;} - - | 'participant_entity' actor 'AS' restOfLine 'NEWLINE' {$2.draw='entity'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;} - | 'participant_entity' actor 'NEWLINE' {$2.draw='entity'; $2.type='addParticipant'; $$=$2;} - - | 'participant_database' actor 'AS' restOfLine 'NEWLINE' {$2.draw='database'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;} - | 'participant_database' actor 'NEWLINE' {$2.draw='database'; $2.type='addParticipant'; $$=$2;} - - | 'participant_collections' actor 'AS' restOfLine 'NEWLINE' {$2.draw='collections'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;} - | 'participant_collections' actor 'NEWLINE' {$2.draw='collections'; $2.type='addParticipant'; $$=$2;} - - | 'participant_queue' actor 'AS' restOfLine 'NEWLINE' {$2.draw='queue'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;} - | 'participant_queue' actor 'NEWLINE' {$2.draw='queue'; $2.type='addParticipant'; $$=$2;} + : 'participant' actor 'AS' restOfLine 'NEWLINE' {$2.draw='participant'; $2.type='addParticipant';$2.description=yy.parseMessage($4); $$=$2;} + | 'participant' actor 'NEWLINE' {$2.draw='participant'; $2.type='addParticipant';$$=$2;} + | '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 'NEWLINE' { $2.draw = 'participant'; $2.type = 'addParticipant'; $$ = $2;} ; @@ -366,76 +308,35 @@ signal ; actor_with_config - : ACTOR_WITH_CONFIG config_object // Changed from ACTOR + : ACTOR config_object { - console.log("ACTOR_WITH_CONFIG Actor with config:", $1, $2); $$ = { type: 'addParticipant', actor: $1, config: $2 }; } - | ACTOR config_object - { - console.log("Actor with config:", $1, $2); - $$ = { - type: 'addParticipant', - actor: $1, - config: $2 - }; - } - | ACTOR - { - console.log("Actor without config:", $1); - $$ = { - type: 'addParticipant', - actor: $1, - }; - } ; config_object : CONFIG_START CONFIG_CONTENT CONFIG_END { - console.log("Parsing config content:", $2); - try { - // Remove any trailing whitespace/newlines - const content = $2.trim(); - $$ = JSON.parse(content); - console.log("Successfully parsed JSON config:", $$); - } catch (e) { - console.log("JSON parse failed, using raw content"); - $$ = $2.trim(); - } - } - ; -actor - : ACTOR_WITH_CONFIG // Add this case - { - console.log("Actor with config flag:", $1); - $$ = { type: 'addParticipant', actor: $1 }; - } - | actor config_object - { - console.log("Actor with config:", $1, $2); - $$ = { - type: 'addParticipant', - actor: $1.actor, - config: $2 - }; - } - | ACTOR - { - console.log("Basic actor:", $1); - $$ = { type: 'addParticipant', actor: $1 }; + $$ = $2.trim(); } ; +// actor +// : actor_participant +// | actor_actor +// ; + +actor: ACTOR {$$={ type: 'addParticipant', actor:$1}}; +// actor_actor: ACTOR {$$={type: 'addActor', actor:$1}}; signaltype : SOLID_OPEN_ARROW { $$ = yy.LINETYPE.SOLID_OPEN; } | DOTTED_OPEN_ARROW { $$ = yy.LINETYPE.DOTTED_OPEN; } | SOLID_ARROW { $$ = yy.LINETYPE.SOLID; } - | BIDIRECTIONAL_SOLID_ARROW { $$ = yy.LINETYPE.BIDIRECTIONAL_SOLID; } + | BIDIRECTIONAL_SOLID_ARROW { $$ = yy.LINETYPE.BIDIRECTIONAL_SOLID; } | DOTTED_ARROW { $$ = yy.LINETYPE.DOTTED; } | BIDIRECTIONAL_DOTTED_ARROW { $$ = yy.LINETYPE.BIDIRECTIONAL_DOTTED; } | SOLID_CROSS { $$ = yy.LINETYPE.SOLID_CROSS; } diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDb.ts b/packages/mermaid/src/diagrams/sequence/sequenceDb.ts index dc8a645fd..4f06a1ebe 100644 --- a/packages/mermaid/src/diagrams/sequence/sequenceDb.ts +++ b/packages/mermaid/src/diagrams/sequence/sequenceDb.ts @@ -1,4 +1,5 @@ import { getConfig } from '../../diagram-api/diagramAPI.js'; +import * as yaml from 'js-yaml'; import type { DiagramDB } from '../../diagram-api/types.js'; import { log } from '../../logger.js'; import { ImperativeState } from '../../utils/imperativeState.js'; @@ -13,6 +14,7 @@ import { setDiagramTitle, } from '../common/commonDb.js'; import type { Actor, AddMessageParams, Box, Message, Note } from './types.js'; +import type { ParticipantMetaData } from '../../types.js'; interface SequenceState { prevActor?: string; @@ -107,7 +109,6 @@ export class SequenceDB implements DiagramDB { this.apply = this.apply.bind(this); this.parseBoxData = this.parseBoxData.bind(this); this.parseMessage = this.parseMessage.bind(this); - this.matchAsActorOrParticipant = this.matchAsActorOrParticipant.bind(this); this.clear(); @@ -131,9 +132,22 @@ export class SequenceDB implements DiagramDB { id: string, name: string, description: { text: string; wrap?: boolean | null; type: string }, - type: string + type: string, + metadata?: any ) { let assignedBox = this.state.records.currentBox; + let doc; + if (metadata !== undefined) { + let yamlData; + // detect if shapeData contains a newline character + if (!metadata.includes('\n')) { + yamlData = '{\n' + metadata + '\n}'; + } else { + yamlData = metadata + '\n'; + } + doc = yaml.load(yamlData, { schema: yaml.JSON_SCHEMA }) as ParticipantMetaData; + } + type = doc?.type ?? type; const old = this.state.records.actors.get(id); if (old) { // If already set and trying to set to a new one throw error @@ -342,22 +356,6 @@ export class SequenceDB implements DiagramDB { return message; } - public matchAsActorOrParticipant( - tokenName: string, - tokenType: string, - inputRemainder: string, - lexer: any - ): string { - const arrowLike = /^\s*(->>|-->>|->|-->|<<->>|<<-->>|-x|--x|-\))/; - const colonLike = /^\s*:/; - - if (arrowLike.test(inputRemainder) || colonLike.test(inputRemainder)) { - return 'ACTOR'; - } - lexer.begin('ID'); // used the passed lexer - return tokenType; - } - // We expect the box statement to be color first then description // The color can be rgb,rgba,hsl,hsla, or css code names #hex codes are not supported for now because of the way the char # is handled // We extract first segment as color, the rest of the line is considered as text @@ -546,7 +544,7 @@ export class SequenceDB implements DiagramDB { }); break; case 'addParticipant': - this.addActor(param.actor, param.actor, param.description, param.draw); + this.addActor(param.actor, param.actor, param.description, param.draw, param.config); break; case 'createParticipant': if (this.state.records.actors.has(param.actor)) { diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js index 7bd278c23..8088f3c44 100644 --- a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js +++ b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js @@ -2043,8 +2043,8 @@ Bob->>Alice:Got it! const actor1 = 'database'; const diagram = await Diagram.fromText(` sequenceDiagram - database Alice - database Bob + participant Alice@{ "type" : "database" } + participant Bob@{ "type" : "database" } Bob->>+Alice: Hi Alice Alice->>+Bob: Hi Bob `); @@ -2057,10 +2057,10 @@ Bob->>Alice:Got it! const diagram = await Diagram.fromText(` sequenceDiagram participant lead - queue dsa + participant dsa@{ "type" : "queue" } API->>+Database: getUserb Database-->>-API: userb - queue --> Database: hello + dsa --> Database: hello `); const messages = diagram.db.getMessages(); @@ -2070,67 +2070,67 @@ Bob->>Alice:Got it! it('should parse boundary participant', async () => { const diagram = await Diagram.fromText(` sequenceDiagram - boundary B as Boundary Box - B->B: test + participant boundary@{ "type" : "boundary" } + boundary->boundary: test `); const actors = diagram.db.getActors(); - expect(actors.get('B').type).toBe('boundary'); - expect(actors.get('B').description).toBe('Boundary Box'); + expect(actors.get('boundary').type).toBe('boundary'); + expect(actors.get('boundary').description).toBe('boundary'); }); it('should parse control participant', async () => { const diagram = await Diagram.fromText(` sequenceDiagram - control C as Controller + participant C@{ "type" : "control" } C->C: test `); const actors = diagram.db.getActors(); expect(actors.get('C').type).toBe('control'); - expect(actors.get('C').description).toBe('Controller'); + expect(actors.get('C').description).toBe('C'); }); it('should parse entity participant', async () => { const diagram = await Diagram.fromText(` sequenceDiagram - entity E as Entity + participant E@{ "type" : "entity" } E->E: test `); const actors = diagram.db.getActors(); expect(actors.get('E').type).toBe('entity'); - expect(actors.get('E').description).toBe('Entity'); + expect(actors.get('E').description).toBe('E'); }); it('should parse database participant', async () => { const diagram = await Diagram.fromText(` sequenceDiagram - database D as Database + participant D@{ "type" : "database" } D->D: test `); const actors = diagram.db.getActors(); expect(actors.get('D').type).toBe('database'); - expect(actors.get('D').description).toBe('Database'); + expect(actors.get('D').description).toBe('D'); }); it('should parse collections participant', async () => { const diagram = await Diagram.fromText(` sequenceDiagram - collections L as List + participant L@{ "type" : "collections" } L->L: test `); const actors = diagram.db.getActors(); expect(actors.get('L').type).toBe('collections'); - expect(actors.get('L').description).toBe('List'); + expect(actors.get('L').description).toBe('L'); }); it('should parse queue participant', async () => { const diagram = await Diagram.fromText(` sequenceDiagram - queue Q as Jobs + participant Q@{ "type" : "queue" } Q->Q: test `); const actors = diagram.db.getActors(); expect(actors.get('Q').type).toBe('queue'); - expect(actors.get('Q').description).toBe('Jobs'); + expect(actors.get('Q').description).toBe('Q'); }); }); @@ -2138,89 +2138,58 @@ Bob->>Alice:Got it! it('should parse actor participant', async () => { const diagram = await Diagram.fromText(` sequenceDiagram - queue A as ActorName + participant A@{ "type" : "queue" } A->A: test `); const actors = diagram.db.getActors(); expect(actors.get('A').type).toBe('queue'); - expect(actors.get('A').description).toBe('ActorName'); + expect(actors.get('A').description).toBe('A'); }); it('should parse participant participant', async () => { const diagram = await Diagram.fromText(` sequenceDiagram - database P as PartName + participant P@{ "type" : "database" } P->P: test `); const actors = diagram.db.getActors(); expect(actors.get('P').type).toBe('database'); - expect(actors.get('P').description).toBe('PartName'); + expect(actors.get('P').description).toBe('P'); }); it('should parse boundary using actor keyword', async () => { const diagram = await Diagram.fromText(` sequenceDiagram - collections B as Boundary - B->B: test + participant Alice@{ "type" : "collections" } + participant Bob@{ "type" : "control" } + Alice->>Bob: Hello Bob, how are you? `); const actors = diagram.db.getActors(); - expect(actors.get('B').type).toBe('collections'); - expect(actors.get('B').description).toBe('Boundary'); + expect(actors.get('Alice').type).toBe('collections'); + expect(actors.get('Bob').type).toBe('control'); + expect(actors.get('Bob').description).toBe('Bob'); }); it('should parse control using participant keyword', async () => { const diagram = await Diagram.fromText(` sequenceDiagram - control C as Controller + participant C@{ "type" : "control" } C->C: test `); const actors = diagram.db.getActors(); expect(actors.get('C').type).toBe('control'); - expect(actors.get('C').description).toBe('Controller'); + expect(actors.get('C').description).toBe('C'); }); it('should parse entity using actor keyword', async () => { const diagram = await Diagram.fromText(` sequenceDiagram - entity E as Entity + participant E@{ "type" : "entity" } E->E: test `); const actors = diagram.db.getActors(); expect(actors.get('E').type).toBe('entity'); - expect(actors.get('E').description).toBe('Entity'); - }); - - it('should parse database using participant keyword', async () => { - const diagram = await Diagram.fromText(` - sequenceDiagram - participant D as Database - D->D: test - `); - const actors = diagram.db.getActors(); - expect(actors.get('D').type).toBe('participant'); - expect(actors.get('D').description).toBe('Database'); - }); - - it('should parse collections using actor keyword', async () => { - const diagram = await Diagram.fromText(` - sequenceDiagram - actor L as List - L->L: test - `); - const actors = diagram.db.getActors(); - expect(actors.get('L').type).toBe('actor'); - expect(actors.get('L').description).toBe('List'); - }); - - it('should parse queue using participant keyword', async () => { - const diagram = await Diagram.fromText(` - sequenceDiagram - participant Q as Jobs - Q->Q: test - `); - const actors = diagram.db.getActors(); - expect(actors.get('Q').type).toBe('participant'); - expect(actors.get('Q').description).toBe('Jobs'); + expect(actors.get('E').description).toBe('E'); }); }); }); diff --git a/packages/mermaid/src/types.ts b/packages/mermaid/src/types.ts index d1394e71b..477fb17b1 100644 --- a/packages/mermaid/src/types.ts +++ b/packages/mermaid/src/types.ts @@ -13,6 +13,18 @@ export interface NodeMetaData { ticket?: string; } +export interface ParticipantMetaData { + type?: + | 'actor' + | 'participant' + | 'boundary' + | 'control' + | 'entity' + | 'database' + | 'collections' + | 'queue'; +} + export interface EdgeMetaData { animation?: 'fast' | 'slow'; animate?: boolean;