drizzle-docs-generator 0.2.0 → 0.3.0
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.
- package/README.ja.md +50 -13
- package/README.md +45 -8
- package/dist/adapter/index.d.ts +10 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/types.d.ts +40 -0
- package/dist/adapter/types.d.ts.map +1 -0
- package/dist/adapter/v0-adapter.d.ts +73 -0
- package/dist/adapter/v0-adapter.d.ts.map +1 -0
- package/dist/adapter/v0-adapter.js +136 -0
- package/dist/adapter/v0-adapter.js.map +1 -0
- package/dist/adapter/v1-adapter.d.ts +40 -0
- package/dist/adapter/v1-adapter.d.ts.map +1 -0
- package/dist/adapter/v1-adapter.js +83 -0
- package/dist/adapter/v1-adapter.js.map +1 -0
- package/dist/cli/index.js +198 -66
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/integration-test-utils.d.ts +19 -0
- package/dist/cli/integration-test-utils.d.ts.map +1 -0
- package/dist/formatter/dbml-builder.d.ts +29 -0
- package/dist/formatter/dbml-builder.d.ts.map +1 -0
- package/dist/formatter/dbml-builder.js +39 -0
- package/dist/formatter/dbml-builder.js.map +1 -0
- package/dist/formatter/dbml.d.ts +81 -0
- package/dist/formatter/dbml.d.ts.map +1 -0
- package/dist/formatter/dbml.js +163 -0
- package/dist/formatter/dbml.js.map +1 -0
- package/dist/formatter/index.d.ts +7 -0
- package/dist/formatter/index.d.ts.map +1 -0
- package/dist/formatter/markdown.d.ts +125 -0
- package/dist/formatter/markdown.d.ts.map +1 -0
- package/dist/formatter/markdown.js +235 -0
- package/dist/formatter/markdown.js.map +1 -0
- package/dist/formatter/mermaid.d.ts +102 -0
- package/dist/formatter/mermaid.d.ts.map +1 -0
- package/dist/formatter/mermaid.js +177 -0
- package/dist/formatter/mermaid.js.map +1 -0
- package/dist/formatter/types.d.ts +37 -0
- package/dist/formatter/types.d.ts.map +1 -0
- package/dist/generator/common.d.ts +109 -211
- package/dist/generator/common.d.ts.map +1 -1
- package/dist/generator/common.js +252 -481
- package/dist/generator/common.js.map +1 -1
- package/dist/generator/index.d.ts +2 -1
- package/dist/generator/index.d.ts.map +1 -1
- package/dist/generator/mysql.js +3 -3
- package/dist/generator/pg.d.ts +8 -7
- package/dist/generator/pg.d.ts.map +1 -1
- package/dist/generator/pg.js +29 -31
- package/dist/generator/pg.js.map +1 -1
- package/dist/generator/sqlite.js +3 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -9
- package/dist/index.js.map +1 -1
- package/dist/test-utils/cli-runner.d.ts +4 -0
- package/dist/test-utils/cli-runner.d.ts.map +1 -1
- package/dist/test-utils/dbml-validator.d.ts +37 -0
- package/dist/test-utils/dbml-validator.d.ts.map +1 -1
- package/dist/types.d.ts +132 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { IntermediateSchema } from '../types';
|
|
2
|
+
import { OutputFormatter, FormatterOptions } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Options for MermaidErDiagramFormatter
|
|
5
|
+
*/
|
|
6
|
+
export interface MermaidFormatterOptions extends FormatterOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Whether to include column types in the diagram
|
|
9
|
+
* @default true
|
|
10
|
+
*/
|
|
11
|
+
includeColumnTypes?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* MermaidErDiagramFormatter generates Mermaid ER diagram syntax from IntermediateSchema
|
|
15
|
+
*
|
|
16
|
+
* This formatter creates Mermaid-compatible ER diagrams that can be rendered
|
|
17
|
+
* in GitHub, GitLab, or any Mermaid-supporting platform.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const formatter = new MermaidErDiagramFormatter();
|
|
22
|
+
* const mermaid = formatter.format(schema);
|
|
23
|
+
* // Output:
|
|
24
|
+
* // erDiagram
|
|
25
|
+
* // users ||--o{ posts : "author_id"
|
|
26
|
+
* // users {
|
|
27
|
+
* // int id PK
|
|
28
|
+
* // varchar username
|
|
29
|
+
* // }
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @see https://mermaid.js.org/syntax/entityRelationshipDiagram.html
|
|
33
|
+
*/
|
|
34
|
+
export declare class MermaidErDiagramFormatter implements OutputFormatter {
|
|
35
|
+
private options;
|
|
36
|
+
/**
|
|
37
|
+
* Create a new MermaidErDiagramFormatter
|
|
38
|
+
*
|
|
39
|
+
* @param options - Formatter options
|
|
40
|
+
*/
|
|
41
|
+
constructor(options?: MermaidFormatterOptions);
|
|
42
|
+
/**
|
|
43
|
+
* Format the intermediate schema into a Mermaid ER diagram
|
|
44
|
+
*
|
|
45
|
+
* @param schema - The intermediate schema to format
|
|
46
|
+
* @returns Mermaid ER diagram string
|
|
47
|
+
*/
|
|
48
|
+
format(schema: IntermediateSchema): string;
|
|
49
|
+
/**
|
|
50
|
+
* Format a focused ER diagram showing only a specific table and its related tables
|
|
51
|
+
*
|
|
52
|
+
* @param schema - The intermediate schema
|
|
53
|
+
* @param tableName - The name of the table to focus on
|
|
54
|
+
* @returns Mermaid ER diagram string showing only the focused table and its relations
|
|
55
|
+
*/
|
|
56
|
+
formatFocused(schema: IntermediateSchema, tableName: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* Collect foreign key columns from relations for FK marker assignment
|
|
59
|
+
*/
|
|
60
|
+
private collectForeignKeyColumns;
|
|
61
|
+
/**
|
|
62
|
+
* Format a table definition to Mermaid syntax
|
|
63
|
+
*/
|
|
64
|
+
private formatTable;
|
|
65
|
+
/**
|
|
66
|
+
* Format a column definition to Mermaid syntax
|
|
67
|
+
*/
|
|
68
|
+
private formatColumn;
|
|
69
|
+
/**
|
|
70
|
+
* Simplify SQL type for Mermaid display
|
|
71
|
+
*
|
|
72
|
+
* Mermaid ER diagrams work best with simple type names
|
|
73
|
+
*/
|
|
74
|
+
private simplifyType;
|
|
75
|
+
/**
|
|
76
|
+
* Format a relation definition to Mermaid syntax
|
|
77
|
+
*
|
|
78
|
+
* Mermaid ER diagram relation syntax:
|
|
79
|
+
* - ||--|| : one-to-one
|
|
80
|
+
* - ||--o{ : one-to-many
|
|
81
|
+
* - }o--|| : many-to-one
|
|
82
|
+
* - }o--o{ : many-to-many
|
|
83
|
+
*/
|
|
84
|
+
private formatRelation;
|
|
85
|
+
/**
|
|
86
|
+
* Convert IntermediateRelationType to Mermaid relation symbol
|
|
87
|
+
*
|
|
88
|
+
* @see https://mermaid.js.org/syntax/entityRelationshipDiagram.html#relationship-syntax
|
|
89
|
+
*/
|
|
90
|
+
private getRelationSymbol;
|
|
91
|
+
/**
|
|
92
|
+
* Escape a name for Mermaid if it contains special characters
|
|
93
|
+
*
|
|
94
|
+
* Mermaid entity names should be alphanumeric with underscores
|
|
95
|
+
*/
|
|
96
|
+
private escapeName;
|
|
97
|
+
/**
|
|
98
|
+
* Escape a string for use in Mermaid quoted strings
|
|
99
|
+
*/
|
|
100
|
+
private escapeString;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=mermaid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid.d.ts","sourceRoot":"","sources":["../../src/formatter/mermaid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAInB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,gBAAgB;IAC/D;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAYD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,yBAA0B,YAAW,eAAe;IAC/D,OAAO,CAAC,OAAO,CAAoC;IAEnD;;;;OAIG;gBACS,OAAO,GAAE,uBAA4B;IAIjD;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM;IA4B1C;;;;;;OAMG;IACH,aAAa,CAAC,MAAM,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAiDpE;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAgBhC;;OAEG;IACH,OAAO,CAAC,WAAW;IAiBnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAmCpB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAkCpB;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IAStB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAazB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAUlB;;OAEG;IACH,OAAO,CAAC,YAAY;CAGrB"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
const c = {
|
|
2
|
+
includeComments: !0,
|
|
3
|
+
includeIndexes: !0,
|
|
4
|
+
includeConstraints: !0,
|
|
5
|
+
includeColumnTypes: !0
|
|
6
|
+
};
|
|
7
|
+
class f {
|
|
8
|
+
options;
|
|
9
|
+
/**
|
|
10
|
+
* Create a new MermaidErDiagramFormatter
|
|
11
|
+
*
|
|
12
|
+
* @param options - Formatter options
|
|
13
|
+
*/
|
|
14
|
+
constructor(e = {}) {
|
|
15
|
+
this.options = { ...c, ...e };
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Format the intermediate schema into a Mermaid ER diagram
|
|
19
|
+
*
|
|
20
|
+
* @param schema - The intermediate schema to format
|
|
21
|
+
* @returns Mermaid ER diagram string
|
|
22
|
+
*/
|
|
23
|
+
format(e) {
|
|
24
|
+
const t = ["erDiagram"], o = this.collectForeignKeyColumns(e.relations);
|
|
25
|
+
for (const n of e.relations) {
|
|
26
|
+
const s = this.formatRelation(n);
|
|
27
|
+
s && t.push(` ${s}`);
|
|
28
|
+
}
|
|
29
|
+
e.relations.length > 0 && e.tables.length > 0 && t.push("");
|
|
30
|
+
for (const n of e.tables) {
|
|
31
|
+
const s = this.formatTable(n, o);
|
|
32
|
+
t.push(...s);
|
|
33
|
+
}
|
|
34
|
+
return t.join(`
|
|
35
|
+
`);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Format a focused ER diagram showing only a specific table and its related tables
|
|
39
|
+
*
|
|
40
|
+
* @param schema - The intermediate schema
|
|
41
|
+
* @param tableName - The name of the table to focus on
|
|
42
|
+
* @returns Mermaid ER diagram string showing only the focused table and its relations
|
|
43
|
+
*/
|
|
44
|
+
formatFocused(e, t) {
|
|
45
|
+
if (!e.tables.find((a) => a.name === t))
|
|
46
|
+
return "erDiagram";
|
|
47
|
+
const n = /* @__PURE__ */ new Set([t]), s = [];
|
|
48
|
+
for (const a of e.relations)
|
|
49
|
+
(a.fromTable === t || a.toTable === t) && (n.add(a.fromTable), n.add(a.toTable), s.push(a));
|
|
50
|
+
const r = e.tables.filter((a) => n.has(a.name)), m = this.collectForeignKeyColumns(s), i = ["erDiagram"];
|
|
51
|
+
for (const a of s) {
|
|
52
|
+
const l = this.formatRelation(a);
|
|
53
|
+
l && i.push(` ${l}`);
|
|
54
|
+
}
|
|
55
|
+
s.length > 0 && r.length > 0 && i.push("");
|
|
56
|
+
for (const a of r) {
|
|
57
|
+
const l = this.formatTable(a, m);
|
|
58
|
+
i.push(...l);
|
|
59
|
+
}
|
|
60
|
+
return i.join(`
|
|
61
|
+
`);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Collect foreign key columns from relations for FK marker assignment
|
|
65
|
+
*/
|
|
66
|
+
collectForeignKeyColumns(e) {
|
|
67
|
+
const t = /* @__PURE__ */ new Map();
|
|
68
|
+
for (const o of e) {
|
|
69
|
+
t.has(o.fromTable) || t.set(o.fromTable, /* @__PURE__ */ new Set());
|
|
70
|
+
for (const n of o.fromColumns)
|
|
71
|
+
t.get(o.fromTable).add(n);
|
|
72
|
+
}
|
|
73
|
+
return t;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Format a table definition to Mermaid syntax
|
|
77
|
+
*/
|
|
78
|
+
formatTable(e, t) {
|
|
79
|
+
const o = [], n = this.escapeName(e.name), s = t.get(e.name) || /* @__PURE__ */ new Set();
|
|
80
|
+
o.push(` ${n} {`);
|
|
81
|
+
for (const r of e.columns) {
|
|
82
|
+
const m = this.formatColumn(r, s);
|
|
83
|
+
o.push(` ${m}`);
|
|
84
|
+
}
|
|
85
|
+
return o.push(" }"), o;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Format a column definition to Mermaid syntax
|
|
89
|
+
*/
|
|
90
|
+
formatColumn(e, t) {
|
|
91
|
+
const o = [];
|
|
92
|
+
this.options.includeColumnTypes && o.push(this.simplifyType(e.type)), o.push(this.escapeName(e.name));
|
|
93
|
+
const n = [];
|
|
94
|
+
return e.primaryKey && n.push("PK"), t.has(e.name) && n.push("FK"), e.unique && !e.primaryKey && n.push("UK"), n.length > 0 && o.push(n.join(",")), this.options.includeComments && e.comment && o.push(`"${this.escapeString(e.comment)}"`), o.join(" ");
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Simplify SQL type for Mermaid display
|
|
98
|
+
*
|
|
99
|
+
* Mermaid ER diagrams work best with simple type names
|
|
100
|
+
*/
|
|
101
|
+
simplifyType(e) {
|
|
102
|
+
const t = e.replace(/\([^)]*\)/g, "").toLowerCase();
|
|
103
|
+
return {
|
|
104
|
+
integer: "int",
|
|
105
|
+
bigint: "bigint",
|
|
106
|
+
smallint: "smallint",
|
|
107
|
+
serial: "serial",
|
|
108
|
+
bigserial: "bigserial",
|
|
109
|
+
text: "text",
|
|
110
|
+
varchar: "varchar",
|
|
111
|
+
char: "char",
|
|
112
|
+
boolean: "boolean",
|
|
113
|
+
timestamp: "timestamp",
|
|
114
|
+
timestamptz: "timestamptz",
|
|
115
|
+
date: "date",
|
|
116
|
+
time: "time",
|
|
117
|
+
json: "json",
|
|
118
|
+
jsonb: "jsonb",
|
|
119
|
+
uuid: "uuid",
|
|
120
|
+
real: "real",
|
|
121
|
+
float: "float",
|
|
122
|
+
double: "double",
|
|
123
|
+
decimal: "decimal",
|
|
124
|
+
numeric: "numeric",
|
|
125
|
+
blob: "blob",
|
|
126
|
+
bytea: "bytea"
|
|
127
|
+
}[t] || t;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Format a relation definition to Mermaid syntax
|
|
131
|
+
*
|
|
132
|
+
* Mermaid ER diagram relation syntax:
|
|
133
|
+
* - ||--|| : one-to-one
|
|
134
|
+
* - ||--o{ : one-to-many
|
|
135
|
+
* - }o--|| : many-to-one
|
|
136
|
+
* - }o--o{ : many-to-many
|
|
137
|
+
*/
|
|
138
|
+
formatRelation(e) {
|
|
139
|
+
const t = this.escapeName(e.fromTable), o = this.escapeName(e.toTable), n = this.getRelationSymbol(e.type), s = e.fromColumns.join(", ");
|
|
140
|
+
return `${t} ${n} ${o} : "${s}"`;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Convert IntermediateRelationType to Mermaid relation symbol
|
|
144
|
+
*
|
|
145
|
+
* @see https://mermaid.js.org/syntax/entityRelationshipDiagram.html#relationship-syntax
|
|
146
|
+
*/
|
|
147
|
+
getRelationSymbol(e) {
|
|
148
|
+
switch (e) {
|
|
149
|
+
case "one-to-one":
|
|
150
|
+
return "||--||";
|
|
151
|
+
case "one-to-many":
|
|
152
|
+
return "||--o{";
|
|
153
|
+
case "many-to-one":
|
|
154
|
+
return "}o--||";
|
|
155
|
+
case "many-to-many":
|
|
156
|
+
return "}o--o{";
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Escape a name for Mermaid if it contains special characters
|
|
161
|
+
*
|
|
162
|
+
* Mermaid entity names should be alphanumeric with underscores
|
|
163
|
+
*/
|
|
164
|
+
escapeName(e) {
|
|
165
|
+
return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(e) ? e : e.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Escape a string for use in Mermaid quoted strings
|
|
169
|
+
*/
|
|
170
|
+
escapeString(e) {
|
|
171
|
+
return e.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, " ");
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
export {
|
|
175
|
+
f as MermaidErDiagramFormatter
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=mermaid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid.js","sources":["../../src/formatter/mermaid.ts"],"sourcesContent":["import type {\n IntermediateSchema,\n TableDefinition,\n ColumnDefinition,\n RelationDefinition,\n} from \"../types\";\nimport type { OutputFormatter, FormatterOptions } from \"./types\";\n\n/**\n * Options for MermaidErDiagramFormatter\n */\nexport interface MermaidFormatterOptions extends FormatterOptions {\n /**\n * Whether to include column types in the diagram\n * @default true\n */\n includeColumnTypes?: boolean;\n}\n\n/**\n * Default formatter options\n */\nconst DEFAULT_OPTIONS: Required<MermaidFormatterOptions> = {\n includeComments: true,\n includeIndexes: true,\n includeConstraints: true,\n includeColumnTypes: true,\n};\n\n/**\n * MermaidErDiagramFormatter generates Mermaid ER diagram syntax from IntermediateSchema\n *\n * This formatter creates Mermaid-compatible ER diagrams that can be rendered\n * in GitHub, GitLab, or any Mermaid-supporting platform.\n *\n * @example\n * ```typescript\n * const formatter = new MermaidErDiagramFormatter();\n * const mermaid = formatter.format(schema);\n * // Output:\n * // erDiagram\n * // users ||--o{ posts : \"author_id\"\n * // users {\n * // int id PK\n * // varchar username\n * // }\n * ```\n *\n * @see https://mermaid.js.org/syntax/entityRelationshipDiagram.html\n */\nexport class MermaidErDiagramFormatter implements OutputFormatter {\n private options: Required<MermaidFormatterOptions>;\n\n /**\n * Create a new MermaidErDiagramFormatter\n *\n * @param options - Formatter options\n */\n constructor(options: MermaidFormatterOptions = {}) {\n this.options = { ...DEFAULT_OPTIONS, ...options };\n }\n\n /**\n * Format the intermediate schema into a Mermaid ER diagram\n *\n * @param schema - The intermediate schema to format\n * @returns Mermaid ER diagram string\n */\n format(schema: IntermediateSchema): string {\n const lines: string[] = [\"erDiagram\"];\n\n // Collect foreign key columns for FK markers\n const fkColumns = this.collectForeignKeyColumns(schema.relations);\n\n // Generate relations first (at the top of the diagram)\n for (const relation of schema.relations) {\n const relationLine = this.formatRelation(relation);\n if (relationLine) {\n lines.push(` ${relationLine}`);\n }\n }\n\n // Add blank line between relations and tables if there are both\n if (schema.relations.length > 0 && schema.tables.length > 0) {\n lines.push(\"\");\n }\n\n // Generate tables\n for (const table of schema.tables) {\n const tableLines = this.formatTable(table, fkColumns);\n lines.push(...tableLines);\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Format a focused ER diagram showing only a specific table and its related tables\n *\n * @param schema - The intermediate schema\n * @param tableName - The name of the table to focus on\n * @returns Mermaid ER diagram string showing only the focused table and its relations\n */\n formatFocused(schema: IntermediateSchema, tableName: string): string {\n // Find the target table\n const targetTable = schema.tables.find((t) => t.name === tableName);\n if (!targetTable) {\n return \"erDiagram\";\n }\n\n // Find related tables through relations\n const relatedTableNames = new Set<string>([tableName]);\n const relevantRelations: RelationDefinition[] = [];\n\n for (const relation of schema.relations) {\n if (relation.fromTable === tableName || relation.toTable === tableName) {\n relatedTableNames.add(relation.fromTable);\n relatedTableNames.add(relation.toTable);\n relevantRelations.push(relation);\n }\n }\n\n // Filter tables to only include related ones\n const relevantTables = schema.tables.filter((t) => relatedTableNames.has(t.name));\n\n // Collect foreign key columns for FK markers\n const fkColumns = this.collectForeignKeyColumns(relevantRelations);\n\n const lines: string[] = [\"erDiagram\"];\n\n // Generate relations\n for (const relation of relevantRelations) {\n const relationLine = this.formatRelation(relation);\n if (relationLine) {\n lines.push(` ${relationLine}`);\n }\n }\n\n // Add blank line between relations and tables if there are both\n if (relevantRelations.length > 0 && relevantTables.length > 0) {\n lines.push(\"\");\n }\n\n // Generate tables\n for (const table of relevantTables) {\n const tableLines = this.formatTable(table, fkColumns);\n lines.push(...tableLines);\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Collect foreign key columns from relations for FK marker assignment\n */\n private collectForeignKeyColumns(relations: RelationDefinition[]): Map<string, Set<string>> {\n const fkColumns = new Map<string, Set<string>>();\n\n for (const relation of relations) {\n // The \"from\" side of the relation has the FK column\n if (!fkColumns.has(relation.fromTable)) {\n fkColumns.set(relation.fromTable, new Set());\n }\n for (const col of relation.fromColumns) {\n fkColumns.get(relation.fromTable)!.add(col);\n }\n }\n\n return fkColumns;\n }\n\n /**\n * Format a table definition to Mermaid syntax\n */\n private formatTable(table: TableDefinition, fkColumns: Map<string, Set<string>>): string[] {\n const lines: string[] = [];\n const tableName = this.escapeName(table.name);\n const tableFkColumns = fkColumns.get(table.name) || new Set();\n\n lines.push(` ${tableName} {`);\n\n for (const column of table.columns) {\n const columnLine = this.formatColumn(column, tableFkColumns);\n lines.push(` ${columnLine}`);\n }\n\n lines.push(\" }\");\n\n return lines;\n }\n\n /**\n * Format a column definition to Mermaid syntax\n */\n private formatColumn(column: ColumnDefinition, fkColumns: Set<string>): string {\n const parts: string[] = [];\n\n // Column type (simplified for Mermaid)\n if (this.options.includeColumnTypes) {\n parts.push(this.simplifyType(column.type));\n }\n\n // Column name\n parts.push(this.escapeName(column.name));\n\n // PK/FK markers\n const markers: string[] = [];\n if (column.primaryKey) {\n markers.push(\"PK\");\n }\n if (fkColumns.has(column.name)) {\n markers.push(\"FK\");\n }\n if (column.unique && !column.primaryKey) {\n markers.push(\"UK\");\n }\n\n if (markers.length > 0) {\n parts.push(markers.join(\",\"));\n }\n\n // Add comment as Mermaid comment (quoted string after markers)\n if (this.options.includeComments && column.comment) {\n parts.push(`\"${this.escapeString(column.comment)}\"`);\n }\n\n return parts.join(\" \");\n }\n\n /**\n * Simplify SQL type for Mermaid display\n *\n * Mermaid ER diagrams work best with simple type names\n */\n private simplifyType(type: string): string {\n // Remove parentheses content for cleaner display (e.g., varchar(255) -> varchar)\n const simplified = type.replace(/\\([^)]*\\)/g, \"\").toLowerCase();\n\n // Map common types to shorter versions\n const typeMap: Record<string, string> = {\n integer: \"int\",\n bigint: \"bigint\",\n smallint: \"smallint\",\n serial: \"serial\",\n bigserial: \"bigserial\",\n text: \"text\",\n varchar: \"varchar\",\n char: \"char\",\n boolean: \"boolean\",\n timestamp: \"timestamp\",\n timestamptz: \"timestamptz\",\n date: \"date\",\n time: \"time\",\n json: \"json\",\n jsonb: \"jsonb\",\n uuid: \"uuid\",\n real: \"real\",\n float: \"float\",\n double: \"double\",\n decimal: \"decimal\",\n numeric: \"numeric\",\n blob: \"blob\",\n bytea: \"bytea\",\n };\n\n return typeMap[simplified] || simplified;\n }\n\n /**\n * Format a relation definition to Mermaid syntax\n *\n * Mermaid ER diagram relation syntax:\n * - ||--|| : one-to-one\n * - ||--o{ : one-to-many\n * - }o--|| : many-to-one\n * - }o--o{ : many-to-many\n */\n private formatRelation(relation: RelationDefinition): string {\n const fromTable = this.escapeName(relation.fromTable);\n const toTable = this.escapeName(relation.toTable);\n const symbol = this.getRelationSymbol(relation.type);\n const label = relation.fromColumns.join(\", \");\n\n return `${fromTable} ${symbol} ${toTable} : \"${label}\"`;\n }\n\n /**\n * Convert IntermediateRelationType to Mermaid relation symbol\n *\n * @see https://mermaid.js.org/syntax/entityRelationshipDiagram.html#relationship-syntax\n */\n private getRelationSymbol(type: RelationDefinition[\"type\"]): string {\n switch (type) {\n case \"one-to-one\":\n return \"||--||\";\n case \"one-to-many\":\n return \"||--o{\";\n case \"many-to-one\":\n return \"}o--||\";\n case \"many-to-many\":\n return \"}o--o{\";\n }\n }\n\n /**\n * Escape a name for Mermaid if it contains special characters\n *\n * Mermaid entity names should be alphanumeric with underscores\n */\n private escapeName(name: string): string {\n // Mermaid accepts alphanumeric and underscores\n // For names with special characters, we need to quote them\n if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {\n return name;\n }\n // Replace special characters with underscores for Mermaid compatibility\n return name.replace(/[^a-zA-Z0-9_]/g, \"_\");\n }\n\n /**\n * Escape a string for use in Mermaid quoted strings\n */\n private escapeString(str: string): string {\n return str.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \" \");\n }\n}\n"],"names":["DEFAULT_OPTIONS","MermaidErDiagramFormatter","options","schema","lines","fkColumns","relation","relationLine","table","tableLines","tableName","t","relatedTableNames","relevantRelations","relevantTables","relations","col","tableFkColumns","column","columnLine","parts","markers","type","simplified","fromTable","toTable","symbol","label","name","str"],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { IntermediateSchema } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Options for output formatters
|
|
4
|
+
*/
|
|
5
|
+
export interface FormatterOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Whether to include table/column comments in the output
|
|
8
|
+
* @default true
|
|
9
|
+
*/
|
|
10
|
+
includeComments?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Whether to include indexes in the output
|
|
13
|
+
* @default true
|
|
14
|
+
*/
|
|
15
|
+
includeIndexes?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Whether to include constraints in the output
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
includeConstraints?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* OutputFormatter interface for generating various output formats from IntermediateSchema
|
|
24
|
+
*
|
|
25
|
+
* Implementations of this interface convert the database-agnostic IntermediateSchema
|
|
26
|
+
* representation into specific output formats (DBML, Markdown, JSON, etc.)
|
|
27
|
+
*/
|
|
28
|
+
export interface OutputFormatter {
|
|
29
|
+
/**
|
|
30
|
+
* Format the intermediate schema into the target output format
|
|
31
|
+
*
|
|
32
|
+
* @param schema - The intermediate schema representation to format
|
|
33
|
+
* @returns The formatted output as a string
|
|
34
|
+
*/
|
|
35
|
+
format(schema: IntermediateSchema): string;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/formatter/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAAC;CAC5C"}
|