@msdshsk/react-er-canvas 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +48 -0
  3. package/README.ja.md +216 -0
  4. package/README.md +216 -0
  5. package/dist/components/JoinEdge.d.ts +10 -0
  6. package/dist/components/JoinEdge.d.ts.map +1 -0
  7. package/dist/components/MermaidER.d.ts +46 -0
  8. package/dist/components/MermaidER.d.ts.map +1 -0
  9. package/dist/components/TableNode.d.ts +30 -0
  10. package/dist/components/TableNode.d.ts.map +1 -0
  11. package/dist/core/index.d.ts +5 -0
  12. package/dist/core/index.d.ts.map +1 -0
  13. package/dist/core/layout.d.ts +58 -0
  14. package/dist/core/layout.d.ts.map +1 -0
  15. package/dist/core/layout.test.d.ts +2 -0
  16. package/dist/core/layout.test.d.ts.map +1 -0
  17. package/dist/core/model.d.ts +55 -0
  18. package/dist/core/model.d.ts.map +1 -0
  19. package/dist/core/parser/grammar.d.ts +22 -0
  20. package/dist/core/parser/grammar.d.ts.map +1 -0
  21. package/dist/core/parser/index.d.ts +15 -0
  22. package/dist/core/parser/index.d.ts.map +1 -0
  23. package/dist/core/parser/lexer.d.ts +18 -0
  24. package/dist/core/parser/lexer.d.ts.map +1 -0
  25. package/dist/core/parser/parser.test.d.ts +2 -0
  26. package/dist/core/parser/parser.test.d.ts.map +1 -0
  27. package/dist/core/parser/resolve.test.d.ts +2 -0
  28. package/dist/core/parser/resolve.test.d.ts.map +1 -0
  29. package/dist/core-BtdV83x9.cjs +2 -0
  30. package/dist/core-BtdV83x9.cjs.map +1 -0
  31. package/dist/core-DZ30VgUT.js +345 -0
  32. package/dist/core-DZ30VgUT.js.map +1 -0
  33. package/dist/core.cjs +1 -0
  34. package/dist/core.js +2 -0
  35. package/dist/index.cjs +2 -0
  36. package/dist/index.cjs.map +1 -0
  37. package/dist/index.d.ts +6 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +592 -0
  40. package/dist/index.js.map +1 -0
  41. package/package.json +92 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/core/layout.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAE/D,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,aAAa,GACb,QAAQ,CAAC;AAEb,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,UAAU,MAAM,CAAC;AAC9B,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,SAAS,EAAE,eAAe,CAAC;IAC3B,SAAS,EAAE,eAAe,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqCzB;AAOD,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CA6DvB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=layout.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.test.d.ts","sourceRoot":"","sources":["../../src/core/layout.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ export type Cardinality = 'one' | 'one-or-zero' | 'one-or-many' | 'zero-or-many';
2
+ export interface ColumnKey {
3
+ pk?: boolean;
4
+ fk?: boolean;
5
+ uk?: boolean;
6
+ }
7
+ export interface Column {
8
+ name: string;
9
+ type?: string;
10
+ comment?: string;
11
+ keys: ColumnKey;
12
+ }
13
+ export interface Table {
14
+ name: string;
15
+ columns: Column[];
16
+ group?: string;
17
+ }
18
+ export interface Relation {
19
+ id: string;
20
+ from: string;
21
+ to: string;
22
+ fromCardinality: Cardinality;
23
+ toCardinality: Cardinality;
24
+ identifying: boolean;
25
+ label?: string;
26
+ /** Column name on the `from` table that participates in this relation. */
27
+ fromColumn?: string;
28
+ /** Column name on the `to` table that participates in this relation. */
29
+ toColumn?: string;
30
+ }
31
+ export interface Group {
32
+ name: string;
33
+ tables: string[];
34
+ }
35
+ export interface ERModel {
36
+ tables: Table[];
37
+ relations: Relation[];
38
+ groups: Group[];
39
+ }
40
+ export interface ColumnRef {
41
+ table: string;
42
+ column: string;
43
+ }
44
+ export interface PartialColumnRef {
45
+ table: string;
46
+ column?: string;
47
+ }
48
+ export type JoinType = 'INNER' | 'LEFT' | 'RIGHT' | 'FULL' | 'CROSS';
49
+ export interface Join {
50
+ id: string;
51
+ source: ColumnRef;
52
+ target: ColumnRef;
53
+ type: JoinType;
54
+ }
55
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/core/model.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GACnB,KAAK,GACL,aAAa,GACb,aAAa,GACb,cAAc,CAAC;AAEnB,MAAM,WAAW,SAAS;IACxB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,EAAE,WAAW,CAAC;IAC7B,aAAa,EAAE,WAAW,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAErE,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,QAAQ,CAAC;CAChB"}
@@ -0,0 +1,22 @@
1
+ import { EmbeddedActionsParser } from 'chevrotain';
2
+ import { ERModel } from '../model';
3
+ declare class ERGrammar extends EmbeddedActionsParser {
4
+ private tables;
5
+ private relations;
6
+ private groupOrder;
7
+ private groupMembers;
8
+ private currentGroup;
9
+ private lastRelation;
10
+ constructor();
11
+ resetState(): void;
12
+ buildModel(): ERModel;
13
+ private ensureTable;
14
+ diagram: import('chevrotain').ParserMethod<[], void>;
15
+ private statement;
16
+ private entityOrRelation;
17
+ private entityBody;
18
+ private attribute;
19
+ }
20
+ export declare const erGrammar: ERGrammar;
21
+ export {};
22
+ //# sourceMappingURL=grammar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grammar.d.ts","sourceRoot":"","sources":["../../../src/core/parser/grammar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAenD,OAAO,KAAK,EAAuB,OAAO,EAA0B,MAAM,UAAU,CAAC;AA+BrF,cAAM,SAAU,SAAQ,qBAAqB;IAC3C,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,YAAY,CAAuB;;IAOpC,UAAU,IAAI,IAAI;IAalB,UAAU,IAAI,OAAO;IAY5B,OAAO,CAAC,WAAW;IAmBZ,OAAO,8CAGX;IAEH,OAAO,CAAC,SAAS,CA8Cd;IAEH,OAAO,CAAC,gBAAgB,CAoDrB;IAEH,OAAO,CAAC,UAAU,CASf;IAEH,OAAO,CAAC,SAAS,CAgBd;CACJ;AAED,eAAO,MAAM,SAAS,WAAkB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { ERModel } from '../model';
2
+ export declare class MermaidERParseError extends Error {
3
+ readonly errors: ReadonlyArray<{
4
+ message: string;
5
+ line?: number;
6
+ column?: number;
7
+ }>;
8
+ constructor(message: string, errors: ReadonlyArray<{
9
+ message: string;
10
+ line?: number;
11
+ column?: number;
12
+ }>);
13
+ }
14
+ export declare function parseMermaidER(source: string): ERModel;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,OAAO,EAAmB,MAAM,UAAU,CAAC;AAI9E,qBAAa,mBAAoB,SAAQ,KAAK;aAG1B,MAAM,EAAE,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;gBAD1F,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAK7F;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAgCtD"}
@@ -0,0 +1,18 @@
1
+ import { Lexer } from 'chevrotain';
2
+ export declare const WhiteSpace: import('chevrotain').TokenType;
3
+ export declare const GroupStart: import('chevrotain').TokenType;
4
+ export declare const GroupEnd: import('chevrotain').TokenType;
5
+ export declare const Comment: import('chevrotain').TokenType;
6
+ export declare const ErDiagram: import('chevrotain').TokenType;
7
+ export declare const KeyConstraint: import('chevrotain').TokenType;
8
+ export declare const Identifier: import('chevrotain').TokenType;
9
+ export declare const RelSymbol: import('chevrotain').TokenType;
10
+ export declare const StringLiteral: import('chevrotain').TokenType;
11
+ export declare const LBrace: import('chevrotain').TokenType;
12
+ export declare const RBrace: import('chevrotain').TokenType;
13
+ export declare const Colon: import('chevrotain').TokenType;
14
+ export declare const Comma: import('chevrotain').TokenType;
15
+ export declare const RefDirective: import('chevrotain').TokenType;
16
+ export declare const allTokens: import('chevrotain').TokenType[];
17
+ export declare const erLexer: Lexer;
18
+ //# sourceMappingURL=lexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../../src/core/parser/lexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,UAAU,gCAIrB,CAAC;AAEH,eAAO,MAAM,UAAU,gCAGrB,CAAC;AAEH,eAAO,MAAM,QAAQ,gCAGnB,CAAC;AAEH,eAAO,MAAM,OAAO,gCAIlB,CAAC;AAEH,eAAO,MAAM,SAAS,gCAGpB,CAAC;AAEH,eAAO,MAAM,aAAa,gCAGxB,CAAC;AAEH,eAAO,MAAM,UAAU,gCAGrB,CAAC;AAEH,eAAO,MAAM,SAAS,gCAGpB,CAAC;AAEH,eAAO,MAAM,aAAa,gCAGxB,CAAC;AAEH,eAAO,MAAM,MAAM,gCAAiD,CAAC;AACrE,eAAO,MAAM,MAAM,gCAAiD,CAAC;AACrE,eAAO,MAAM,KAAK,gCAA+C,CAAC;AAElE,eAAO,MAAM,KAAK,gCAIhB,CAAC;AAEH,eAAO,MAAM,YAAY,gCAGvB,CAAC;AAEH,eAAO,MAAM,SAAS,kCAerB,CAAC;AAEF,eAAO,MAAM,OAAO,OAAuB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=parser.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.test.d.ts","sourceRoot":"","sources":["../../../src/core/parser/parser.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=resolve.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.test.d.ts","sourceRoot":"","sources":["../../../src/core/parser/resolve.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`chevrotain`),l=require(`elkjs/lib/elk.bundled.js`);l=s(l,1);var u=(0,c.createToken)({name:`WhiteSpace`,pattern:/[\s\r\n]+/,group:c.Lexer.SKIPPED}),d=(0,c.createToken)({name:`GroupStart`,pattern:/%%[ \t]*@group[ \t]+[A-Za-z_][A-Za-z0-9_]*/}),f=(0,c.createToken)({name:`GroupEnd`,pattern:/%%[ \t]*@endgroup\b/}),p=(0,c.createToken)({name:`Comment`,pattern:/%%[^\r\n]*/,group:c.Lexer.SKIPPED}),m=(0,c.createToken)({name:`ErDiagram`,pattern:/erDiagram\b/}),h=(0,c.createToken)({name:`KeyConstraint`,pattern:/(?:PK|FK|UK)\b/}),g=(0,c.createToken)({name:`Identifier`,pattern:/[A-Za-z_][A-Za-z0-9_-]*(?:\([^)\r\n]*\))?/}),_=(0,c.createToken)({name:`RelSymbol`,pattern:/(?:\|\||\|o|\}\||\}o)(?:--|\.\.)(?:\|\||o\||\|\{|o\{)/}),v=(0,c.createToken)({name:`StringLiteral`,pattern:/"[^"\r\n]*"/}),y=(0,c.createToken)({name:`LBrace`,pattern:/\{/}),b=(0,c.createToken)({name:`RBrace`,pattern:/\}/}),x=(0,c.createToken)({name:`Colon`,pattern:/:/}),S=(0,c.createToken)({name:`Comma`,pattern:/,/,group:c.Lexer.SKIPPED}),C=(0,c.createToken)({name:`RefDirective`,pattern:/%%[ \t]*@ref[ \t]+[A-Za-z_][A-Za-z0-9_]*\.[A-Za-z_][A-Za-z0-9_-]*[ \t]*->[ \t]*[A-Za-z_][A-Za-z0-9_]*\.[A-Za-z_][A-Za-z0-9_-]*/}),w=[u,S,d,f,C,p,m,h,g,_,v,y,b,x],T=new c.Lexer(w),E={"||":`one`,"|o":`one-or-zero`,"}|":`one-or-many`,"}o":`zero-or-many`},D={"||":`one`,"o|":`one-or-zero`,"|{":`one-or-many`,"o{":`zero-or-many`};function O(e){let t=e.includes(`--`),n=t?`--`:`..`,[r,i]=e.split(n);return{from:E[r]??`one`,to:D[i]??`one`,identifying:t}}var k=new class extends c.EmbeddedActionsParser{tables=new Map;relations=[];groupOrder=[];groupMembers=new Map;currentGroup;lastRelation;constructor(){super(w),this.performSelfAnalysis()}resetState(){super.reset(),this.tables=new Map,this.relations=[],this.groupOrder=[],this.groupMembers=new Map,this.currentGroup=void 0,this.lastRelation=void 0}buildModel(){let e=this.groupOrder.map(e=>({name:e,tables:this.groupMembers.get(e)??[]}));return{tables:Array.from(this.tables.values()),relations:this.relations,groups:e}}ensureTable(e){let t=this.tables.get(e);if(t||(t={name:e,columns:[],group:this.currentGroup},this.tables.set(e,t)),this.currentGroup&&!t.group&&(t.group=this.currentGroup),this.currentGroup){let t=this.groupMembers.get(this.currentGroup)??[];t.includes(e)||(t.push(e),this.groupMembers.set(this.currentGroup,t))}return t}diagram=this.RULE(`diagram`,()=>{this.CONSUME(m),this.MANY(()=>this.SUBRULE(this.statement))});statement=this.RULE(`statement`,()=>{this.OR([{ALT:()=>this.SUBRULE(this.entityOrRelation)},{ALT:()=>{let e=this.CONSUME(d);this.ACTION(()=>{let t=/@group[ \t]+([A-Za-z_][A-Za-z0-9_]*)/.exec(e.image),n=t?t[1]:`unnamed`;this.currentGroup=n,this.groupMembers.has(n)||(this.groupMembers.set(n,[]),this.groupOrder.push(n))})}},{ALT:()=>{this.CONSUME(f),this.ACTION(()=>{this.currentGroup=void 0})}},{ALT:()=>{let e=this.CONSUME(C);this.ACTION(()=>{let t=/@ref[ \t]+([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_-]*)[ \t]*->[ \t]*([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_-]*)/.exec(e.image);if(!t||!this.lastRelation)return;let[,n,r,i,a]=t,o=this.lastRelation;n===o.from&&i===o.to?(o.fromColumn=r,o.toColumn=a):n===o.to&&i===o.from&&(o.fromColumn=a,o.toColumn=r)})}}])});entityOrRelation=this.RULE(`entityOrRelation`,()=>{let e=this.CONSUME(g).image;this.OR([{ALT:()=>{let t=this.SUBRULE(this.entityBody);this.ACTION(()=>{let n=this.ensureTable(e);n.columns=t})}},{ALT:()=>{let t=this.CONSUME(_),n=this.CONSUME2(g).image,r;this.OPTION(()=>{this.CONSUME(x),this.OR2([{ALT:()=>{r=this.CONSUME3(g).image}},{ALT:()=>{r=this.CONSUME(v).image.slice(1,-1)}}])}),this.ACTION(()=>{this.ensureTable(e),this.ensureTable(n);let i=O(t.image),a={id:`${e}__${n}__${this.relations.length}`,from:e,to:n,fromCardinality:i.from,toCardinality:i.to,identifying:i.identifying,label:r};this.relations.push(a),this.lastRelation=a})}}])});entityBody=this.RULE(`entityBody`,()=>{let e=[];return this.CONSUME(y),this.MANY(()=>{let t=this.SUBRULE(this.attribute);e.push(t)}),this.CONSUME(b),e});attribute=this.RULE(`attribute`,()=>{let e=this.CONSUME(g,{LABEL:`type`}).image,t=this.CONSUME2(g,{LABEL:`name`}).image,n={};this.MANY(()=>{let e=this.CONSUME(h).image.toUpperCase();e===`PK`?n.pk=!0:e===`FK`?n.fk=!0:e===`UK`&&(n.uk=!0)});let r;return this.OPTION(()=>{r=this.CONSUME(v).image.slice(1,-1)}),{type:e,name:t,keys:n,comment:r}})},A=class extends Error{constructor(e,t){super(e),this.errors=t,this.name=`MermaidERParseError`}};function j(e){let t=T.tokenize(e);if(t.errors.length>0){let e=t.errors[0];throw new A(`Lex error at line ${e.line}:${e.column}: ${e.message}`,t.errors.map(e=>({message:e.message,line:e.line??void 0,column:e.column??void 0})))}if(k.resetState(),k.input=t.tokens,k.diagram(),k.errors.length>0){let e=k.errors[0];throw new A(`Parse error at line ${e.token.startLine}:${e.token.startColumn}: ${e.message}`,k.errors.map(e=>({message:e.message,line:e.token.startLine,column:e.token.startColumn})))}return N(k.buildModel())}var M=new Set([`one`,`one-or-zero`]);function N(e){let t=new Map(e.tables.map(e=>[e.name,e]));for(let n of e.relations){if(n.fromColumn&&n.toColumn)continue;let e=t.get(n.from),r=t.get(n.to);if(!e||!r)continue;let i=M.has(n.fromCardinality),a=M.has(n.toCardinality),o,s,c;i&&!a?(o=e,s=r,c=!0):a&&!i?(o=r,s=e,c=!1):(o=e,s=r,c=!0);let l=o.columns.find(e=>e.keys.pk),u=P(n,s,o,l?.name);!l||!u||(c?(n.fromColumn||=l.name,n.toColumn||=u.name):(n.fromColumn||=u.name,n.toColumn||=l.name))}return e}function P(e,t,n,r){let i=t.columns.filter(e=>e.keys.fk);if(i.length===0)return F(t.columns,n.name,r);if(i.length===1)return i[0];if(e.label){let n=`${t.name}_`;if(e.label.startsWith(n)&&e.label.endsWith(`_foreign`)){let t=e.label.slice(n.length,e.label.length-8),r=i.find(e=>e.name===t);if(r)return r}if(e.label.startsWith(n)){let t=e.label.slice(n.length),r=i.find(e=>e.name===t);if(r)return r}}return F(i,n.name,r)||i[0]}function F(e,t,n){let r=t.toLowerCase(),i=n?.toLowerCase()??`id`;return e.find(e=>e.name.toLowerCase()===`${r}_${i}`)??e.find(e=>e.name.toLowerCase()===`${r}_id`)??e.find(e=>e.name.toLowerCase().includes(r)&&(e.keys.fk||e.name.toLowerCase().endsWith(`_id`)))}var I=240,L=32,R=22,z=8;function B(e){return 32+Math.max(e,1)*22+16}function V(e){let t={"elk.algorithm":e.algorithm,"elk.spacing.nodeNode":String(e.nodeSpacing)};switch(e.aspectRatio!==void 0&&(t[`elk.aspectRatio`]=String(e.aspectRatio)),e.algorithm){case`layered`:t[`elk.direction`]=e.direction,t[`elk.layered.spacing.nodeNodeBetweenLayers`]=String(e.rankSpacing),t[`elk.edgeRouting`]=`ORTHOGONAL`,e.aspectRatio!==void 0&&(t[`elk.layered.wrapping.strategy`]=`MULTI_EDGE`);break;case`mrtree`:t[`elk.direction`]=e.direction;break;case`stress`:t[`elk.stress.desiredEdgeLength`]=String(e.nodeSpacing*4);break;case`force`:t[`elk.force.repulsivePower`]=`1`;break;case`rectpacking`:t[`elk.rectpacking.packing.strategy`]=`SIMPLE`;break;case`radial`:break}return{...t,...e.raw}}var H=new l.default;async function U(e,t={}){let{algorithm:n=`layered`,direction:r=`DOWN`,aspectRatio:i,nodeSpacing:a=60,rankSpacing:o=80,raw:s={}}=t,c={id:`root`,layoutOptions:V({algorithm:n,direction:r,aspectRatio:i,nodeSpacing:a,rankSpacing:o,raw:s}),children:e.tables.map(e=>({id:e.name,width:240,height:B(e.columns.length)})),edges:e.relations.map(e=>({id:e.id,sources:[e.from],targets:[e.to]}))},l=await H.layout(c);return{nodes:(l.children??[]).map(e=>({id:e.id,x:e.x??0,y:e.y??0,width:e.width??240,height:e.height??B(0)})),edges:(l.edges??[]).map(e=>{let t=e.sections?.[0];return{id:e.id,source:e.sources[0],target:e.targets[0],startPoint:t?.startPoint,endPoint:t?.endPoint,bendPoints:t?.bendPoints}}),width:l.width??0,height:l.height??0}}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return L}});
2
+ //# sourceMappingURL=core-BtdV83x9.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core-BtdV83x9.cjs","names":[],"sources":["../src/core/parser/lexer.ts","../src/core/parser/grammar.ts","../src/core/parser/index.ts","../src/core/layout.ts"],"sourcesContent":["import { createToken, Lexer } from 'chevrotain';\n\nexport const WhiteSpace = createToken({\n name: 'WhiteSpace',\n pattern: /[\\s\\r\\n]+/,\n group: Lexer.SKIPPED,\n});\n\nexport const GroupStart = createToken({\n name: 'GroupStart',\n pattern: /%%[ \\t]*@group[ \\t]+[A-Za-z_][A-Za-z0-9_]*/,\n});\n\nexport const GroupEnd = createToken({\n name: 'GroupEnd',\n pattern: /%%[ \\t]*@endgroup\\b/,\n});\n\nexport const Comment = createToken({\n name: 'Comment',\n pattern: /%%[^\\r\\n]*/,\n group: Lexer.SKIPPED,\n});\n\nexport const ErDiagram = createToken({\n name: 'ErDiagram',\n pattern: /erDiagram\\b/,\n});\n\nexport const KeyConstraint = createToken({\n name: 'KeyConstraint',\n pattern: /(?:PK|FK|UK)\\b/,\n});\n\nexport const Identifier = createToken({\n name: 'Identifier',\n pattern: /[A-Za-z_][A-Za-z0-9_-]*(?:\\([^)\\r\\n]*\\))?/,\n});\n\nexport const RelSymbol = createToken({\n name: 'RelSymbol',\n pattern: /(?:\\|\\||\\|o|\\}\\||\\}o)(?:--|\\.\\.)(?:\\|\\||o\\||\\|\\{|o\\{)/,\n});\n\nexport const StringLiteral = createToken({\n name: 'StringLiteral',\n pattern: /\"[^\"\\r\\n]*\"/,\n});\n\nexport const LBrace = createToken({ name: 'LBrace', pattern: /\\{/ });\nexport const RBrace = createToken({ name: 'RBrace', pattern: /\\}/ });\nexport const Colon = createToken({ name: 'Colon', pattern: /:/ });\n\nexport const Comma = createToken({\n name: 'Comma',\n pattern: /,/,\n group: Lexer.SKIPPED,\n});\n\nexport const RefDirective = createToken({\n name: 'RefDirective',\n pattern: /%%[ \\t]*@ref[ \\t]+[A-Za-z_][A-Za-z0-9_]*\\.[A-Za-z_][A-Za-z0-9_-]*[ \\t]*->[ \\t]*[A-Za-z_][A-Za-z0-9_]*\\.[A-Za-z_][A-Za-z0-9_-]*/,\n});\n\nexport const allTokens = [\n WhiteSpace,\n Comma,\n GroupStart,\n GroupEnd,\n RefDirective,\n Comment,\n ErDiagram,\n KeyConstraint,\n Identifier,\n RelSymbol,\n StringLiteral,\n LBrace,\n RBrace,\n Colon,\n];\n\nexport const erLexer = new Lexer(allTokens);\n","import { EmbeddedActionsParser } from 'chevrotain';\nimport {\n allTokens,\n ErDiagram,\n Identifier,\n LBrace,\n RBrace,\n Colon,\n RelSymbol,\n StringLiteral,\n KeyConstraint,\n GroupStart,\n GroupEnd,\n RefDirective,\n} from './lexer';\nimport type { Cardinality, Column, ERModel, Group, Relation, Table } from '../model';\n\nconst LEFT_CARDINALITY: Record<string, Cardinality> = {\n '||': 'one',\n '|o': 'one-or-zero',\n '}|': 'one-or-many',\n '}o': 'zero-or-many',\n};\n\nconst RIGHT_CARDINALITY: Record<string, Cardinality> = {\n '||': 'one',\n 'o|': 'one-or-zero',\n '|{': 'one-or-many',\n 'o{': 'zero-or-many',\n};\n\nfunction parseRelSymbol(symbol: string): {\n from: Cardinality;\n to: Cardinality;\n identifying: boolean;\n} {\n const identifying = symbol.includes('--');\n const middle = identifying ? '--' : '..';\n const [leftSym, rightSym] = symbol.split(middle);\n return {\n from: LEFT_CARDINALITY[leftSym] ?? 'one',\n to: RIGHT_CARDINALITY[rightSym] ?? 'one',\n identifying,\n };\n}\n\nclass ERGrammar extends EmbeddedActionsParser {\n private tables: Map<string, Table> = new Map();\n private relations: Relation[] = [];\n private groupOrder: string[] = [];\n private groupMembers: Map<string, string[]> = new Map();\n private currentGroup: string | undefined;\n private lastRelation: Relation | undefined;\n\n constructor() {\n super(allTokens);\n this.performSelfAnalysis();\n }\n\n public resetState(): void {\n // Chevrotain's parent class provides its own reset() that clears\n // internal recognizer state (errors, RULE_STACK, lookahead caches).\n // We invoke that here, then clear our domain state.\n super.reset();\n this.tables = new Map();\n this.relations = [];\n this.groupOrder = [];\n this.groupMembers = new Map();\n this.currentGroup = undefined;\n this.lastRelation = undefined;\n }\n\n public buildModel(): ERModel {\n const groups: Group[] = this.groupOrder.map((name) => ({\n name,\n tables: this.groupMembers.get(name) ?? [],\n }));\n return {\n tables: Array.from(this.tables.values()),\n relations: this.relations,\n groups,\n };\n }\n\n private ensureTable(name: string): Table {\n let table = this.tables.get(name);\n if (!table) {\n table = { name, columns: [], group: this.currentGroup };\n this.tables.set(name, table);\n }\n if (this.currentGroup && !table.group) {\n table.group = this.currentGroup;\n }\n if (this.currentGroup) {\n const members = this.groupMembers.get(this.currentGroup) ?? [];\n if (!members.includes(name)) {\n members.push(name);\n this.groupMembers.set(this.currentGroup, members);\n }\n }\n return table;\n }\n\n public diagram = this.RULE('diagram', () => {\n this.CONSUME(ErDiagram);\n this.MANY(() => this.SUBRULE(this.statement));\n });\n\n private statement = this.RULE('statement', () => {\n this.OR([\n { ALT: () => this.SUBRULE(this.entityOrRelation) },\n {\n ALT: () => {\n const tok = this.CONSUME(GroupStart);\n this.ACTION(() => {\n const match = /@group[ \\t]+([A-Za-z_][A-Za-z0-9_]*)/.exec(tok.image);\n const name = match ? match[1] : 'unnamed';\n this.currentGroup = name;\n if (!this.groupMembers.has(name)) {\n this.groupMembers.set(name, []);\n this.groupOrder.push(name);\n }\n });\n },\n },\n {\n ALT: () => {\n this.CONSUME(GroupEnd);\n this.ACTION(() => {\n this.currentGroup = undefined;\n });\n },\n },\n {\n ALT: () => {\n const tok = this.CONSUME(RefDirective);\n this.ACTION(() => {\n const m = /@ref[ \\t]+([A-Za-z_][A-Za-z0-9_]*)\\.([A-Za-z_][A-Za-z0-9_-]*)[ \\t]*->[ \\t]*([A-Za-z_][A-Za-z0-9_]*)\\.([A-Za-z_][A-Za-z0-9_-]*)/.exec(\n tok.image,\n );\n if (!m || !this.lastRelation) return;\n const [, aTable, aCol, bTable, bCol] = m;\n const rel = this.lastRelation;\n if (aTable === rel.from && bTable === rel.to) {\n rel.fromColumn = aCol;\n rel.toColumn = bCol;\n } else if (aTable === rel.to && bTable === rel.from) {\n rel.fromColumn = bCol;\n rel.toColumn = aCol;\n }\n });\n },\n },\n ]);\n });\n\n private entityOrRelation = this.RULE('entityOrRelation', () => {\n const left = this.CONSUME(Identifier).image;\n this.OR([\n {\n ALT: () => {\n const columns = this.SUBRULE(this.entityBody);\n this.ACTION(() => {\n const table = this.ensureTable(left);\n table.columns = columns;\n });\n },\n },\n {\n ALT: () => {\n const symbolToken = this.CONSUME(RelSymbol);\n const right = this.CONSUME2(Identifier).image;\n let label: string | undefined;\n this.OPTION(() => {\n this.CONSUME(Colon);\n this.OR2([\n {\n ALT: () => {\n label = this.CONSUME3(Identifier).image;\n },\n },\n {\n ALT: () => {\n const s = this.CONSUME(StringLiteral).image;\n label = s.slice(1, -1);\n },\n },\n ]);\n });\n this.ACTION(() => {\n this.ensureTable(left);\n this.ensureTable(right);\n const card = parseRelSymbol(symbolToken.image);\n const relation: Relation = {\n id: `${left}__${right}__${this.relations.length}`,\n from: left,\n to: right,\n fromCardinality: card.from,\n toCardinality: card.to,\n identifying: card.identifying,\n label,\n };\n this.relations.push(relation);\n this.lastRelation = relation;\n });\n },\n },\n ]);\n });\n\n private entityBody = this.RULE('entityBody', (): Column[] => {\n const columns: Column[] = [];\n this.CONSUME(LBrace);\n this.MANY(() => {\n const col = this.SUBRULE(this.attribute);\n columns.push(col);\n });\n this.CONSUME(RBrace);\n return columns;\n });\n\n private attribute = this.RULE('attribute', (): Column => {\n const type = this.CONSUME(Identifier, { LABEL: 'type' }).image;\n const name = this.CONSUME2(Identifier, { LABEL: 'name' }).image;\n const keys: { pk?: boolean; fk?: boolean; uk?: boolean } = {};\n this.MANY(() => {\n const k = this.CONSUME(KeyConstraint).image.toUpperCase();\n if (k === 'PK') keys.pk = true;\n else if (k === 'FK') keys.fk = true;\n else if (k === 'UK') keys.uk = true;\n });\n let comment: string | undefined;\n this.OPTION(() => {\n const s = this.CONSUME(StringLiteral).image;\n comment = s.slice(1, -1);\n });\n return { type, name, keys, comment };\n });\n}\n\nexport const erGrammar = new ERGrammar();\n","import type { Cardinality, Column, ERModel, Relation, Table } from '../model';\nimport { erLexer } from './lexer';\nimport { erGrammar } from './grammar';\n\nexport class MermaidERParseError extends Error {\n constructor(\n message: string,\n public readonly errors: ReadonlyArray<{ message: string; line?: number; column?: number }>,\n ) {\n super(message);\n this.name = 'MermaidERParseError';\n }\n}\n\nexport function parseMermaidER(source: string): ERModel {\n const lexed = erLexer.tokenize(source);\n if (lexed.errors.length > 0) {\n const first = lexed.errors[0];\n throw new MermaidERParseError(\n `Lex error at line ${first.line}:${first.column}: ${first.message}`,\n lexed.errors.map((e) => ({\n message: e.message,\n line: e.line ?? undefined,\n column: e.column ?? undefined,\n })),\n );\n }\n\n erGrammar.resetState();\n erGrammar.input = lexed.tokens;\n erGrammar.diagram();\n\n if (erGrammar.errors.length > 0) {\n const first = erGrammar.errors[0];\n throw new MermaidERParseError(\n `Parse error at line ${first.token.startLine}:${first.token.startColumn}: ${first.message}`,\n erGrammar.errors.map((e) => ({\n message: e.message,\n line: e.token.startLine,\n column: e.token.startColumn,\n })),\n );\n }\n\n const model = erGrammar.buildModel();\n return resolveColumnRefs(model);\n}\n\nconst PK_CARDINALITIES: ReadonlySet<Cardinality> = new Set(['one', 'one-or-zero']);\n\nfunction resolveColumnRefs(model: ERModel): ERModel {\n const tableMap = new Map(model.tables.map((t) => [t.name, t]));\n\n for (const rel of model.relations) {\n if (rel.fromColumn && rel.toColumn) continue;\n\n const fromTable = tableMap.get(rel.from);\n const toTable = tableMap.get(rel.to);\n if (!fromTable || !toTable) continue;\n\n const fromIsPkSide = PK_CARDINALITIES.has(rel.fromCardinality);\n const toIsPkSide = PK_CARDINALITIES.has(rel.toCardinality);\n\n let pkTable: Table;\n let fkTable: Table;\n let pkOnFromSide: boolean;\n\n if (fromIsPkSide && !toIsPkSide) {\n pkTable = fromTable;\n fkTable = toTable;\n pkOnFromSide = true;\n } else if (toIsPkSide && !fromIsPkSide) {\n pkTable = toTable;\n fkTable = fromTable;\n pkOnFromSide = false;\n } else {\n pkTable = fromTable;\n fkTable = toTable;\n pkOnFromSide = true;\n }\n\n const pkCol = pkTable.columns.find((c) => c.keys.pk);\n const fkCol = inferFkColumn(rel, fkTable, pkTable, pkCol?.name);\n\n if (!pkCol || !fkCol) continue;\n\n if (pkOnFromSide) {\n if (!rel.fromColumn) rel.fromColumn = pkCol.name;\n if (!rel.toColumn) rel.toColumn = fkCol.name;\n } else {\n if (!rel.fromColumn) rel.fromColumn = fkCol.name;\n if (!rel.toColumn) rel.toColumn = pkCol.name;\n }\n }\n\n return model;\n}\n\nfunction inferFkColumn(\n rel: Relation,\n fkTable: Table,\n pkTable: Table,\n pkColName: string | undefined,\n): Column | undefined {\n const fkCols = fkTable.columns.filter((c) => c.keys.fk);\n\n if (fkCols.length === 0) {\n return guessByNaming(fkTable.columns, pkTable.name, pkColName);\n }\n if (fkCols.length === 1) return fkCols[0];\n\n if (rel.label) {\n const prefix = `${fkTable.name}_`;\n const suffix = '_foreign';\n if (rel.label.startsWith(prefix) && rel.label.endsWith(suffix)) {\n const colName = rel.label.slice(prefix.length, rel.label.length - suffix.length);\n const col = fkCols.find((c) => c.name === colName);\n if (col) return col;\n }\n if (rel.label.startsWith(prefix)) {\n const colCandidate = rel.label.slice(prefix.length);\n const col = fkCols.find((c) => c.name === colCandidate);\n if (col) return col;\n }\n }\n\n const guessed = guessByNaming(fkCols, pkTable.name, pkColName);\n if (guessed) return guessed;\n\n return fkCols[0];\n}\n\nfunction guessByNaming(\n candidates: Column[],\n pkTableName: string,\n pkColName: string | undefined,\n): Column | undefined {\n const pkTableLower = pkTableName.toLowerCase();\n const pkColLower = pkColName?.toLowerCase() ?? 'id';\n\n return (\n candidates.find((c) => c.name.toLowerCase() === `${pkTableLower}_${pkColLower}`) ??\n candidates.find((c) => c.name.toLowerCase() === `${pkTableLower}_id`) ??\n candidates.find(\n (c) =>\n c.name.toLowerCase().includes(pkTableLower) &&\n (c.keys.fk || c.name.toLowerCase().endsWith('_id')),\n )\n );\n}\n","import ELK from 'elkjs/lib/elk.bundled.js';\nimport type { ElkExtendedEdge, ElkNode } from 'elkjs/lib/elk-api';\nimport type { ERModel } from './model';\n\nexport type LayoutDirection = 'RIGHT' | 'DOWN' | 'LEFT' | 'UP';\n\nexport type LayoutAlgorithm =\n | 'layered'\n | 'stress'\n | 'force'\n | 'mrtree'\n | 'rectpacking'\n | 'radial';\n\nexport interface LayoutOptions {\n engine?: 'elk';\n algorithm?: LayoutAlgorithm;\n direction?: LayoutDirection;\n /**\n * Target aspect ratio (width / height). Combined with the layered algorithm,\n * enables wrapping so the layout fits common screen sizes.\n * Example: `16/9`, `Math.SQRT2` for A4 landscape, `1` for square.\n */\n aspectRatio?: number;\n nodeSpacing?: number;\n rankSpacing?: number;\n /** Raw ELK layoutOptions, merged after the defaults. */\n raw?: Record<string, string>;\n}\n\nexport interface PositionedNode {\n id: string;\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface EdgePoint {\n x: number;\n y: number;\n}\n\nexport interface PositionedEdge {\n id: string;\n source: string;\n target: string;\n startPoint?: EdgePoint;\n endPoint?: EdgePoint;\n bendPoints?: EdgePoint[];\n}\n\nexport interface LayoutResult {\n nodes: PositionedNode[];\n edges: PositionedEdge[];\n width: number;\n height: number;\n}\n\nexport const NODE_WIDTH = 240;\nexport const HEADER_HEIGHT = 32;\nexport const ROW_HEIGHT = 22;\nexport const VERTICAL_PADDING = 8;\n\nexport function estimateNodeHeight(columnCount: number): number {\n return HEADER_HEIGHT + Math.max(columnCount, 1) * ROW_HEIGHT + VERTICAL_PADDING * 2;\n}\n\nexport function buildElkLayoutOptions(opts: {\n algorithm: LayoutAlgorithm;\n direction: LayoutDirection;\n aspectRatio: number | undefined;\n nodeSpacing: number;\n rankSpacing: number;\n raw: Record<string, string>;\n}): Record<string, string> {\n const out: Record<string, string> = {\n 'elk.algorithm': opts.algorithm,\n 'elk.spacing.nodeNode': String(opts.nodeSpacing),\n };\n\n if (opts.aspectRatio !== undefined) {\n out['elk.aspectRatio'] = String(opts.aspectRatio);\n }\n\n switch (opts.algorithm) {\n case 'layered':\n out['elk.direction'] = opts.direction;\n out['elk.layered.spacing.nodeNodeBetweenLayers'] = String(opts.rankSpacing);\n out['elk.edgeRouting'] = 'ORTHOGONAL';\n if (opts.aspectRatio !== undefined) {\n out['elk.layered.wrapping.strategy'] = 'MULTI_EDGE';\n }\n break;\n case 'mrtree':\n out['elk.direction'] = opts.direction;\n break;\n case 'stress':\n out['elk.stress.desiredEdgeLength'] = String(opts.nodeSpacing * 4);\n break;\n case 'force':\n out['elk.force.repulsivePower'] = '1';\n break;\n case 'rectpacking':\n out['elk.rectpacking.packing.strategy'] = 'SIMPLE';\n break;\n case 'radial':\n // radial defaults\n break;\n }\n\n return { ...out, ...opts.raw };\n}\n\n// Reuse a single ELK instance across calls. Constructing one allocates a heavy\n// engine; doing it per layout (i.e., per keystroke in live-editing scenarios)\n// is wasteful. ELK's `layout()` is reentrant-safe enough for our usage.\nconst elk = new ELK();\n\nexport async function layoutER(\n model: ERModel,\n options: LayoutOptions = {},\n): Promise<LayoutResult> {\n const {\n algorithm = 'layered',\n direction = 'DOWN',\n aspectRatio,\n nodeSpacing = 60,\n rankSpacing = 80,\n raw = {},\n } = options;\n\n const graph: ElkNode = {\n id: 'root',\n layoutOptions: buildElkLayoutOptions({\n algorithm,\n direction,\n aspectRatio,\n nodeSpacing,\n rankSpacing,\n raw,\n }),\n children: model.tables.map((t) => ({\n id: t.name,\n width: NODE_WIDTH,\n height: estimateNodeHeight(t.columns.length),\n })),\n edges: model.relations.map<ElkExtendedEdge>((r) => ({\n id: r.id,\n sources: [r.from],\n targets: [r.to],\n })),\n };\n\n const layouted = await elk.layout(graph);\n\n const nodes: PositionedNode[] = (layouted.children ?? []).map((c) => ({\n id: c.id,\n x: c.x ?? 0,\n y: c.y ?? 0,\n width: c.width ?? NODE_WIDTH,\n height: c.height ?? estimateNodeHeight(0),\n }));\n\n const layoutedEdges = (layouted.edges ?? []) as ElkExtendedEdge[];\n const edges: PositionedEdge[] = layoutedEdges.map((e) => {\n const section = e.sections?.[0];\n return {\n id: e.id,\n source: e.sources[0],\n target: e.targets[0],\n startPoint: section?.startPoint,\n endPoint: section?.endPoint,\n bendPoints: section?.bendPoints,\n };\n });\n\n return {\n nodes,\n edges,\n width: layouted.width ?? 0,\n height: layouted.height ?? 0,\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,345 @@
1
+ import { EmbeddedActionsParser as e, Lexer as t, createToken as n } from "chevrotain";
2
+ import r from "elkjs/lib/elk.bundled.js";
3
+ //#region src/core/parser/lexer.ts
4
+ var i = n({
5
+ name: "WhiteSpace",
6
+ pattern: /[\s\r\n]+/,
7
+ group: t.SKIPPED
8
+ }), a = n({
9
+ name: "GroupStart",
10
+ pattern: /%%[ \t]*@group[ \t]+[A-Za-z_][A-Za-z0-9_]*/
11
+ }), o = n({
12
+ name: "GroupEnd",
13
+ pattern: /%%[ \t]*@endgroup\b/
14
+ }), s = n({
15
+ name: "Comment",
16
+ pattern: /%%[^\r\n]*/,
17
+ group: t.SKIPPED
18
+ }), c = n({
19
+ name: "ErDiagram",
20
+ pattern: /erDiagram\b/
21
+ }), l = n({
22
+ name: "KeyConstraint",
23
+ pattern: /(?:PK|FK|UK)\b/
24
+ }), u = n({
25
+ name: "Identifier",
26
+ pattern: /[A-Za-z_][A-Za-z0-9_-]*(?:\([^)\r\n]*\))?/
27
+ }), d = n({
28
+ name: "RelSymbol",
29
+ pattern: /(?:\|\||\|o|\}\||\}o)(?:--|\.\.)(?:\|\||o\||\|\{|o\{)/
30
+ }), f = n({
31
+ name: "StringLiteral",
32
+ pattern: /"[^"\r\n]*"/
33
+ }), p = n({
34
+ name: "LBrace",
35
+ pattern: /\{/
36
+ }), m = n({
37
+ name: "RBrace",
38
+ pattern: /\}/
39
+ }), h = n({
40
+ name: "Colon",
41
+ pattern: /:/
42
+ }), g = n({
43
+ name: "Comma",
44
+ pattern: /,/,
45
+ group: t.SKIPPED
46
+ }), _ = n({
47
+ name: "RefDirective",
48
+ pattern: /%%[ \t]*@ref[ \t]+[A-Za-z_][A-Za-z0-9_]*\.[A-Za-z_][A-Za-z0-9_-]*[ \t]*->[ \t]*[A-Za-z_][A-Za-z0-9_]*\.[A-Za-z_][A-Za-z0-9_-]*/
49
+ }), v = [
50
+ i,
51
+ g,
52
+ a,
53
+ o,
54
+ _,
55
+ s,
56
+ c,
57
+ l,
58
+ u,
59
+ d,
60
+ f,
61
+ p,
62
+ m,
63
+ h
64
+ ], y = new t(v), b = {
65
+ "||": "one",
66
+ "|o": "one-or-zero",
67
+ "}|": "one-or-many",
68
+ "}o": "zero-or-many"
69
+ }, x = {
70
+ "||": "one",
71
+ "o|": "one-or-zero",
72
+ "|{": "one-or-many",
73
+ "o{": "zero-or-many"
74
+ };
75
+ function S(e) {
76
+ let t = e.includes("--"), n = t ? "--" : "..", [r, i] = e.split(n);
77
+ return {
78
+ from: b[r] ?? "one",
79
+ to: x[i] ?? "one",
80
+ identifying: t
81
+ };
82
+ }
83
+ var C = new class extends e {
84
+ tables = /* @__PURE__ */ new Map();
85
+ relations = [];
86
+ groupOrder = [];
87
+ groupMembers = /* @__PURE__ */ new Map();
88
+ currentGroup;
89
+ lastRelation;
90
+ constructor() {
91
+ super(v), this.performSelfAnalysis();
92
+ }
93
+ resetState() {
94
+ super.reset(), this.tables = /* @__PURE__ */ new Map(), this.relations = [], this.groupOrder = [], this.groupMembers = /* @__PURE__ */ new Map(), this.currentGroup = void 0, this.lastRelation = void 0;
95
+ }
96
+ buildModel() {
97
+ let e = this.groupOrder.map((e) => ({
98
+ name: e,
99
+ tables: this.groupMembers.get(e) ?? []
100
+ }));
101
+ return {
102
+ tables: Array.from(this.tables.values()),
103
+ relations: this.relations,
104
+ groups: e
105
+ };
106
+ }
107
+ ensureTable(e) {
108
+ let t = this.tables.get(e);
109
+ if (t || (t = {
110
+ name: e,
111
+ columns: [],
112
+ group: this.currentGroup
113
+ }, this.tables.set(e, t)), this.currentGroup && !t.group && (t.group = this.currentGroup), this.currentGroup) {
114
+ let t = this.groupMembers.get(this.currentGroup) ?? [];
115
+ t.includes(e) || (t.push(e), this.groupMembers.set(this.currentGroup, t));
116
+ }
117
+ return t;
118
+ }
119
+ diagram = this.RULE("diagram", () => {
120
+ this.CONSUME(c), this.MANY(() => this.SUBRULE(this.statement));
121
+ });
122
+ statement = this.RULE("statement", () => {
123
+ this.OR([
124
+ { ALT: () => this.SUBRULE(this.entityOrRelation) },
125
+ { ALT: () => {
126
+ let e = this.CONSUME(a);
127
+ this.ACTION(() => {
128
+ let t = /@group[ \t]+([A-Za-z_][A-Za-z0-9_]*)/.exec(e.image), n = t ? t[1] : "unnamed";
129
+ this.currentGroup = n, this.groupMembers.has(n) || (this.groupMembers.set(n, []), this.groupOrder.push(n));
130
+ });
131
+ } },
132
+ { ALT: () => {
133
+ this.CONSUME(o), this.ACTION(() => {
134
+ this.currentGroup = void 0;
135
+ });
136
+ } },
137
+ { ALT: () => {
138
+ let e = this.CONSUME(_);
139
+ this.ACTION(() => {
140
+ let t = /@ref[ \t]+([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_-]*)[ \t]*->[ \t]*([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_-]*)/.exec(e.image);
141
+ if (!t || !this.lastRelation) return;
142
+ let [, n, r, i, a] = t, o = this.lastRelation;
143
+ n === o.from && i === o.to ? (o.fromColumn = r, o.toColumn = a) : n === o.to && i === o.from && (o.fromColumn = a, o.toColumn = r);
144
+ });
145
+ } }
146
+ ]);
147
+ });
148
+ entityOrRelation = this.RULE("entityOrRelation", () => {
149
+ let e = this.CONSUME(u).image;
150
+ this.OR([{ ALT: () => {
151
+ let t = this.SUBRULE(this.entityBody);
152
+ this.ACTION(() => {
153
+ let n = this.ensureTable(e);
154
+ n.columns = t;
155
+ });
156
+ } }, { ALT: () => {
157
+ let t = this.CONSUME(d), n = this.CONSUME2(u).image, r;
158
+ this.OPTION(() => {
159
+ this.CONSUME(h), this.OR2([{ ALT: () => {
160
+ r = this.CONSUME3(u).image;
161
+ } }, { ALT: () => {
162
+ r = this.CONSUME(f).image.slice(1, -1);
163
+ } }]);
164
+ }), this.ACTION(() => {
165
+ this.ensureTable(e), this.ensureTable(n);
166
+ let i = S(t.image), a = {
167
+ id: `${e}__${n}__${this.relations.length}`,
168
+ from: e,
169
+ to: n,
170
+ fromCardinality: i.from,
171
+ toCardinality: i.to,
172
+ identifying: i.identifying,
173
+ label: r
174
+ };
175
+ this.relations.push(a), this.lastRelation = a;
176
+ });
177
+ } }]);
178
+ });
179
+ entityBody = this.RULE("entityBody", () => {
180
+ let e = [];
181
+ return this.CONSUME(p), this.MANY(() => {
182
+ let t = this.SUBRULE(this.attribute);
183
+ e.push(t);
184
+ }), this.CONSUME(m), e;
185
+ });
186
+ attribute = this.RULE("attribute", () => {
187
+ let e = this.CONSUME(u, { LABEL: "type" }).image, t = this.CONSUME2(u, { LABEL: "name" }).image, n = {};
188
+ this.MANY(() => {
189
+ let e = this.CONSUME(l).image.toUpperCase();
190
+ e === "PK" ? n.pk = !0 : e === "FK" ? n.fk = !0 : e === "UK" && (n.uk = !0);
191
+ });
192
+ let r;
193
+ return this.OPTION(() => {
194
+ r = this.CONSUME(f).image.slice(1, -1);
195
+ }), {
196
+ type: e,
197
+ name: t,
198
+ keys: n,
199
+ comment: r
200
+ };
201
+ });
202
+ }(), w = class extends Error {
203
+ constructor(e, t) {
204
+ super(e), this.errors = t, this.name = "MermaidERParseError";
205
+ }
206
+ };
207
+ function T(e) {
208
+ let t = y.tokenize(e);
209
+ if (t.errors.length > 0) {
210
+ let e = t.errors[0];
211
+ throw new w(`Lex error at line ${e.line}:${e.column}: ${e.message}`, t.errors.map((e) => ({
212
+ message: e.message,
213
+ line: e.line ?? void 0,
214
+ column: e.column ?? void 0
215
+ })));
216
+ }
217
+ if (C.resetState(), C.input = t.tokens, C.diagram(), C.errors.length > 0) {
218
+ let e = C.errors[0];
219
+ throw new w(`Parse error at line ${e.token.startLine}:${e.token.startColumn}: ${e.message}`, C.errors.map((e) => ({
220
+ message: e.message,
221
+ line: e.token.startLine,
222
+ column: e.token.startColumn
223
+ })));
224
+ }
225
+ return D(C.buildModel());
226
+ }
227
+ var E = new Set(["one", "one-or-zero"]);
228
+ function D(e) {
229
+ let t = new Map(e.tables.map((e) => [e.name, e]));
230
+ for (let n of e.relations) {
231
+ if (n.fromColumn && n.toColumn) continue;
232
+ let e = t.get(n.from), r = t.get(n.to);
233
+ if (!e || !r) continue;
234
+ let i = E.has(n.fromCardinality), a = E.has(n.toCardinality), o, s, c;
235
+ i && !a ? (o = e, s = r, c = !0) : a && !i ? (o = r, s = e, c = !1) : (o = e, s = r, c = !0);
236
+ let l = o.columns.find((e) => e.keys.pk), u = O(n, s, o, l?.name);
237
+ !l || !u || (c ? (n.fromColumn ||= l.name, n.toColumn ||= u.name) : (n.fromColumn ||= u.name, n.toColumn ||= l.name));
238
+ }
239
+ return e;
240
+ }
241
+ function O(e, t, n, r) {
242
+ let i = t.columns.filter((e) => e.keys.fk);
243
+ if (i.length === 0) return k(t.columns, n.name, r);
244
+ if (i.length === 1) return i[0];
245
+ if (e.label) {
246
+ let n = `${t.name}_`;
247
+ if (e.label.startsWith(n) && e.label.endsWith("_foreign")) {
248
+ let t = e.label.slice(n.length, e.label.length - 8), r = i.find((e) => e.name === t);
249
+ if (r) return r;
250
+ }
251
+ if (e.label.startsWith(n)) {
252
+ let t = e.label.slice(n.length), r = i.find((e) => e.name === t);
253
+ if (r) return r;
254
+ }
255
+ }
256
+ return k(i, n.name, r) || i[0];
257
+ }
258
+ function k(e, t, n) {
259
+ let r = t.toLowerCase(), i = n?.toLowerCase() ?? "id";
260
+ return e.find((e) => e.name.toLowerCase() === `${r}_${i}`) ?? e.find((e) => e.name.toLowerCase() === `${r}_id`) ?? e.find((e) => e.name.toLowerCase().includes(r) && (e.keys.fk || e.name.toLowerCase().endsWith("_id")));
261
+ }
262
+ //#endregion
263
+ //#region src/core/layout.ts
264
+ var A = 240, j = 32, M = 22, N = 8;
265
+ function P(e) {
266
+ return 32 + Math.max(e, 1) * 22 + 16;
267
+ }
268
+ function F(e) {
269
+ let t = {
270
+ "elk.algorithm": e.algorithm,
271
+ "elk.spacing.nodeNode": String(e.nodeSpacing)
272
+ };
273
+ switch (e.aspectRatio !== void 0 && (t["elk.aspectRatio"] = String(e.aspectRatio)), e.algorithm) {
274
+ case "layered":
275
+ t["elk.direction"] = e.direction, t["elk.layered.spacing.nodeNodeBetweenLayers"] = String(e.rankSpacing), t["elk.edgeRouting"] = "ORTHOGONAL", e.aspectRatio !== void 0 && (t["elk.layered.wrapping.strategy"] = "MULTI_EDGE");
276
+ break;
277
+ case "mrtree":
278
+ t["elk.direction"] = e.direction;
279
+ break;
280
+ case "stress":
281
+ t["elk.stress.desiredEdgeLength"] = String(e.nodeSpacing * 4);
282
+ break;
283
+ case "force":
284
+ t["elk.force.repulsivePower"] = "1";
285
+ break;
286
+ case "rectpacking":
287
+ t["elk.rectpacking.packing.strategy"] = "SIMPLE";
288
+ break;
289
+ case "radial": break;
290
+ }
291
+ return {
292
+ ...t,
293
+ ...e.raw
294
+ };
295
+ }
296
+ var I = new r();
297
+ async function L(e, t = {}) {
298
+ let { algorithm: n = "layered", direction: r = "DOWN", aspectRatio: i, nodeSpacing: a = 60, rankSpacing: o = 80, raw: s = {} } = t, c = {
299
+ id: "root",
300
+ layoutOptions: F({
301
+ algorithm: n,
302
+ direction: r,
303
+ aspectRatio: i,
304
+ nodeSpacing: a,
305
+ rankSpacing: o,
306
+ raw: s
307
+ }),
308
+ children: e.tables.map((e) => ({
309
+ id: e.name,
310
+ width: 240,
311
+ height: P(e.columns.length)
312
+ })),
313
+ edges: e.relations.map((e) => ({
314
+ id: e.id,
315
+ sources: [e.from],
316
+ targets: [e.to]
317
+ }))
318
+ }, l = await I.layout(c);
319
+ return {
320
+ nodes: (l.children ?? []).map((e) => ({
321
+ id: e.id,
322
+ x: e.x ?? 0,
323
+ y: e.y ?? 0,
324
+ width: e.width ?? 240,
325
+ height: e.height ?? P(0)
326
+ })),
327
+ edges: (l.edges ?? []).map((e) => {
328
+ let t = e.sections?.[0];
329
+ return {
330
+ id: e.id,
331
+ source: e.sources[0],
332
+ target: e.targets[0],
333
+ startPoint: t?.startPoint,
334
+ endPoint: t?.endPoint,
335
+ bendPoints: t?.bendPoints
336
+ };
337
+ }),
338
+ width: l.width ?? 0,
339
+ height: l.height ?? 0
340
+ };
341
+ }
342
+ //#endregion
343
+ export { P as a, T as c, N as i, A as n, L as o, M as r, w as s, j as t };
344
+
345
+ //# sourceMappingURL=core-DZ30VgUT.js.map