ts-prorm-orm 1.2.2 → 2.0.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/CHANGELOG.md +209 -0
- package/README.md +32 -24
- package/dist/compliance/index.d.ts +2 -0
- package/dist/compliance/index.js +13 -1
- package/dist/connection-manager.js +13 -1
- package/dist/core/expressions.d.ts +58 -0
- package/dist/core/expressions.js +83 -0
- package/dist/core/hooks-manager.d.ts +179 -0
- package/dist/core/hooks-manager.js +291 -0
- package/dist/core/types.d.ts +235 -0
- package/dist/core/types.js +9 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.js +11 -1
- package/dist/diagrams/chen-diagram.d.ts +15 -12
- package/dist/diagrams/chen-diagram.js +76 -85
- package/dist/diagrams/class-diagram.d.ts +9 -8
- package/dist/diagrams/class-diagram.js +60 -82
- package/dist/diagrams/core/index.d.ts +13 -0
- package/dist/diagrams/core/index.js +33 -0
- package/dist/diagrams/core/layout.d.ts +104 -0
- package/dist/diagrams/core/layout.js +223 -0
- package/dist/diagrams/{svg-dom.d.ts → core/svg.d.ts} +8 -20
- package/dist/diagrams/{svg-dom.js → core/svg.js} +21 -29
- package/dist/diagrams/core/theme.d.ts +84 -0
- package/dist/diagrams/core/theme.js +62 -0
- package/dist/diagrams/dependency-diagram.d.ts +15 -14
- package/dist/diagrams/dependency-diagram.js +71 -105
- package/dist/diagrams/er-diagram.d.ts +13 -26
- package/dist/diagrams/er-diagram.js +180 -259
- package/dist/diagrams/flow-diagram.d.ts +16 -11
- package/dist/diagrams/flow-diagram.js +96 -91
- package/dist/diagrams/gantt-diagram.d.ts +10 -5
- package/dist/diagrams/gantt-diagram.js +77 -103
- package/dist/diagrams/index-diagram.d.ts +10 -10
- package/dist/diagrams/index-diagram.js +106 -116
- package/dist/diagrams/index.d.ts +6 -9
- package/dist/diagrams/index.js +9 -24
- package/dist/diagrams/migration-diagram.d.ts +8 -4
- package/dist/diagrams/migration-diagram.js +189 -161
- package/dist/diagrams/model-diagram.d.ts +34 -34
- package/dist/diagrams/model-diagram.js +106 -485
- package/dist/diagrams/package-diagram.d.ts +9 -6
- package/dist/diagrams/package-diagram.js +64 -101
- package/dist/diagrams/relational-diagram.d.ts +12 -10
- package/dist/diagrams/relational-diagram.js +87 -114
- package/dist/diagrams/schemadoc-diagram.d.ts +8 -8
- package/dist/diagrams/schemadoc-diagram.js +71 -93
- package/dist/diagrams/sequence-diagram.d.ts +10 -10
- package/dist/diagrams/sequence-diagram.js +64 -89
- package/dist/diagrams/state-diagram.d.ts +10 -9
- package/dist/diagrams/state-diagram.js +69 -92
- package/dist/diagrams/tree-diagram.d.ts +11 -5
- package/dist/diagrams/tree-diagram.js +41 -65
- package/dist/dialects/clickhouse/index.js +15 -0
- package/dist/dialects/cockroachdb/index.d.ts +1 -1
- package/dist/dialects/cockroachdb/index.js +32 -63
- package/dist/dialects/db2/index.js +23 -8
- package/dist/dialects/dialect.d.ts +29 -5
- package/dist/dialects/duckdb/index.js +9 -2
- package/dist/dialects/hana/index.js +22 -5
- package/dist/dialects/lock-clause-helper.d.ts +167 -0
- package/dist/dialects/lock-clause-helper.js +316 -0
- package/dist/dialects/mariadb/index.d.ts +7 -4
- package/dist/dialects/mariadb/index.js +36 -60
- package/dist/dialects/mssql/index.js +34 -3
- package/dist/dialects/mysql/index.d.ts +1 -1
- package/dist/dialects/mysql/index.js +17 -45
- package/dist/dialects/oracle/index.d.ts +14 -3
- package/dist/dialects/oracle/index.js +66 -36
- package/dist/dialects/order-expression-helper.d.ts +72 -0
- package/dist/dialects/order-expression-helper.js +154 -0
- package/dist/dialects/partial-index.d.ts +52 -0
- package/dist/dialects/partial-index.js +251 -0
- package/dist/dialects/postgres/index.d.ts +1 -1
- package/dist/dialects/postgres/index.js +43 -68
- package/dist/dialects/redshift/index.js +9 -2
- package/dist/dialects/snowflake/index.js +17 -0
- package/dist/dialects/spanner/index.js +7 -2
- package/dist/dialects/sqlite/driver.d.ts +55 -0
- package/dist/dialects/sqlite/driver.js +102 -0
- package/dist/dialects/sqlite/index.d.ts +1 -1
- package/dist/dialects/sqlite/index.js +49 -27
- package/dist/graph/base-graph-dialect.d.ts +24 -3
- package/dist/graph/base-graph-dialect.js +43 -2
- package/dist/graph/dgraph/index.js +6 -0
- package/dist/graph/gremlin/index.d.ts +6 -0
- package/dist/graph/gremlin/index.js +12 -1
- package/dist/graph/index.d.ts +1 -1
- package/dist/graph/neo4j/index.d.ts +2 -0
- package/dist/graph/neo4j/index.js +6 -1
- package/dist/graph/types.d.ts +12 -1
- package/dist/index.d.ts +13 -4
- package/dist/index.js +54 -7
- package/dist/logging/index.d.ts +10 -0
- package/dist/logging/index.js +23 -0
- package/dist/logging/query-logging.d.ts +82 -0
- package/dist/logging/query-logging.js +102 -0
- package/dist/models/decorators.d.ts +39 -3
- package/dist/models/decorators.js +74 -0
- package/dist/models/eager-load.d.ts +99 -0
- package/dist/models/eager-load.js +348 -5
- package/dist/models/indexes.d.ts +3 -2
- package/dist/models/indexes.js +7 -1
- package/dist/models/model.js +69 -43
- package/dist/prorm.d.ts +175 -409
- package/dist/prorm.js +1142 -557
- package/dist/query-builders/order-limit-builder.js +12 -10
- package/dist/query-builders/sql-compiler.d.ts +10 -3
- package/dist/query-builders/sql-compiler.js +14 -43
- package/dist/query-interface.d.ts +2 -1
- package/dist/sql-constants.d.ts +44 -0
- package/dist/sql-constants.js +138 -1
- package/dist/types/index.d.ts +53 -17
- package/dist/types/index.js +10 -15
- package/dist/types/query-types.d.ts +26 -0
- package/dist/types/query-types.js +30 -0
- package/package.json +32 -5
- package/dist/decorators/belongs-to-many.js +0 -115
- package/dist/decorators/belongs-to.js +0 -115
- package/dist/decorators/has-many.js +0 -127
- package/dist/decorators/has-one.js +0 -116
- package/dist/diagrams/palette.d.ts +0 -138
- package/dist/diagrams/palette.js +0 -194
- package/dist/hooks/hooks-manager.d.ts +0 -189
- package/dist/hooks/hooks-manager.js +0 -350
- package/dist/hooks/index.d.ts +0 -8
- package/dist/hooks/index.js +0 -37
- /package/dist/{logging.d.ts → logging/logger.d.ts} +0 -0
- /package/dist/{logging.js → logging/logger.js} +0 -0
|
@@ -1,30 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* RelationalDiagram
|
|
3
|
+
* RelationalDiagram - renders a relational schema as entity boxes with their
|
|
4
4
|
* columns and draws connectors between related tables using proper crow's-foot
|
|
5
5
|
* cardinality notation.
|
|
6
6
|
*
|
|
7
7
|
* Each entity is a box listing its columns; primary-key columns are marked and
|
|
8
8
|
* underlined, foreign-key columns are marked. Relationship connectors terminate
|
|
9
9
|
* with crow's-foot endpoints:
|
|
10
|
-
* - "one"
|
|
11
|
-
* - "many"
|
|
12
|
-
* - "optional" → a small circle just outside the endpoint (zero cardinality)
|
|
10
|
+
* - "one" -> a small perpendicular tick (single bar)
|
|
11
|
+
* - "many" -> the three-pronged crow's foot
|
|
13
12
|
*
|
|
14
13
|
* Supported relationship types: one-to-one, one-to-many, many-to-one,
|
|
15
14
|
* many-to-many. Entities are laid out on a grid and connectors are routed
|
|
16
15
|
* between the nearest entity edges.
|
|
17
16
|
*
|
|
18
|
-
*
|
|
19
|
-
* / `El` builder — never by concatenating markup strings — and the viewBox is
|
|
20
|
-
* auto-sized to the content. Both `theme` and `color` change real fill/stroke
|
|
21
|
-
* values in the output (via `resolveTheme` / `resolveAccent`).
|
|
17
|
+
* The viewBox is auto-sized to the content.
|
|
22
18
|
*
|
|
23
19
|
* Usage:
|
|
24
20
|
* const rel = new RelationalDiagram({
|
|
25
21
|
* title: 'Shop Schema',
|
|
26
|
-
* entities: [
|
|
27
|
-
* relationships: [
|
|
22
|
+
* entities: [ ...RelEntity ],
|
|
23
|
+
* relationships: [ ...RelRelationship ],
|
|
28
24
|
* });
|
|
29
25
|
* rel.save('./diagrams/schema.svg');
|
|
30
26
|
* // or: const svg = rel.generate();
|
|
@@ -66,9 +62,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
66
62
|
exports.RelationalDiagram = void 0;
|
|
67
63
|
const fs = __importStar(require("fs"));
|
|
68
64
|
const path = __importStar(require("path"));
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
|
|
65
|
+
const svg_1 = require("./core/svg");
|
|
66
|
+
const theme_1 = require("./core/theme");
|
|
67
|
+
const layout_1 = require("./core/layout");
|
|
72
68
|
class RelationalDiagram {
|
|
73
69
|
constructor(options) {
|
|
74
70
|
this.opts = {
|
|
@@ -80,12 +76,12 @@ class RelationalDiagram {
|
|
|
80
76
|
columns: options.columns ?? 3,
|
|
81
77
|
};
|
|
82
78
|
}
|
|
83
|
-
//
|
|
79
|
+
// -- Box height for an entity -----------------------------------------------
|
|
84
80
|
boxHeight(entity) {
|
|
85
81
|
const h = RelationalDiagram.HDR_H + entity.columns.length * RelationalDiagram.ROW_H + 8;
|
|
86
82
|
return Math.max(h, RelationalDiagram.BOX_MIN_H);
|
|
87
83
|
}
|
|
88
|
-
//
|
|
84
|
+
// -- Grid layout --------------------------------------------------------------
|
|
89
85
|
computeLayout() {
|
|
90
86
|
const { entities, columns } = this.opts;
|
|
91
87
|
const W = RelationalDiagram.BOX_W;
|
|
@@ -121,40 +117,23 @@ class RelationalDiagram {
|
|
|
121
117
|
});
|
|
122
118
|
return layout;
|
|
123
119
|
}
|
|
124
|
-
//
|
|
125
|
-
renderBox(
|
|
126
|
-
void doc;
|
|
120
|
+
// -- Render a single entity box ------------------------------------------------
|
|
121
|
+
renderBox(svg, box) {
|
|
127
122
|
const { entity, x, y, w, h } = box;
|
|
128
|
-
const t = (0, palette_1.resolveTheme)(this.opts.theme);
|
|
129
|
-
const primary = (0, palette_1.resolveAccent)(this.opts.color);
|
|
130
|
-
const secondary = (0, palette_1.accent2Of)(primary);
|
|
131
|
-
// Two-tone blueprint: even entities accent, odd accent-2.
|
|
132
|
-
const header = idx % 2 === 0 ? primary.mid : secondary.color;
|
|
133
|
-
const accentText = primary.text;
|
|
134
|
-
const accent2Text = secondary.text;
|
|
135
123
|
const HDR = RelationalDiagram.HDR_H;
|
|
136
124
|
const ROW = RelationalDiagram.ROW_H;
|
|
137
|
-
// Surface + hairline frame
|
|
138
|
-
svg.child('rect', { x, y, width: w, height: h, fill:
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
y,
|
|
142
|
-
width: w,
|
|
143
|
-
height: h,
|
|
144
|
-
fill: 'none',
|
|
145
|
-
stroke: t.border,
|
|
146
|
-
'stroke-width': 1,
|
|
147
|
-
});
|
|
148
|
-
// Header (solid accent bar).
|
|
149
|
-
svg.child('rect', { x, y, width: w, height: HDR, fill: header });
|
|
125
|
+
// Surface + hairline frame.
|
|
126
|
+
svg.child('rect', { x, y, width: w, height: h, fill: theme_1.INK.ground, stroke: theme_1.INK.line, 'stroke-width': theme_1.STROKE.hair });
|
|
127
|
+
// Header.
|
|
128
|
+
svg.child('rect', { x, y, width: w, height: HDR, fill: theme_1.INK.wash, stroke: theme_1.INK.line, 'stroke-width': theme_1.STROKE.hair });
|
|
150
129
|
svg
|
|
151
130
|
.child('text', {
|
|
152
131
|
x: x + 12,
|
|
153
132
|
y: y + 25,
|
|
154
|
-
'font-family':
|
|
155
|
-
'font-size':
|
|
156
|
-
'font-weight':
|
|
157
|
-
fill:
|
|
133
|
+
'font-family': theme_1.FONT.family,
|
|
134
|
+
'font-size': theme_1.FONT.body + 5,
|
|
135
|
+
'font-weight': 'bold',
|
|
136
|
+
fill: theme_1.INK.line,
|
|
158
137
|
})
|
|
159
138
|
.text(entity.name);
|
|
160
139
|
// Column rows.
|
|
@@ -164,12 +143,12 @@ class RelationalDiagram {
|
|
|
164
143
|
const textY = midY + 4;
|
|
165
144
|
const isPK = !!colDef.primaryKey;
|
|
166
145
|
const isFK = !!colDef.foreignKey;
|
|
167
|
-
const rowBg = ci % 2 === 0 ?
|
|
146
|
+
const rowBg = ci % 2 === 0 ? theme_1.INK.ground : theme_1.INK.wash;
|
|
168
147
|
svg.child('rect', { x, y: ry, width: w, height: ROW, fill: rowBg });
|
|
169
148
|
// Key marker.
|
|
170
149
|
const markX = x + 14;
|
|
171
150
|
if (isPK) {
|
|
172
|
-
svg.child('circle', { cx: markX, cy: midY, r: 3.5, fill:
|
|
151
|
+
svg.child('circle', { cx: markX, cy: midY, r: 3.5, fill: theme_1.INK.line });
|
|
173
152
|
}
|
|
174
153
|
else if (isFK) {
|
|
175
154
|
svg.child('circle', {
|
|
@@ -177,37 +156,36 @@ class RelationalDiagram {
|
|
|
177
156
|
cy: midY,
|
|
178
157
|
r: 3.5,
|
|
179
158
|
fill: 'none',
|
|
180
|
-
stroke:
|
|
181
|
-
'stroke-width':
|
|
159
|
+
stroke: theme_1.INK.line,
|
|
160
|
+
'stroke-width': theme_1.STROKE.hair,
|
|
182
161
|
});
|
|
183
162
|
}
|
|
184
163
|
else {
|
|
185
|
-
svg.child('circle', { cx: markX, cy: midY, r: 2, fill:
|
|
164
|
+
svg.child('circle', { cx: markX, cy: midY, r: 2, fill: theme_1.INK.muted });
|
|
186
165
|
}
|
|
187
|
-
// Column name (PK underlined, PK/FK
|
|
188
|
-
const
|
|
189
|
-
const nameWeight = isPK ? 600 : isFK ? 600 : 400;
|
|
166
|
+
// Column name (PK underlined, PK/FK bold).
|
|
167
|
+
const nameWeight = isPK || isFK ? 'bold' : 'normal';
|
|
190
168
|
const nameX = x + 28;
|
|
191
169
|
svg
|
|
192
170
|
.child('text', {
|
|
193
171
|
x: nameX,
|
|
194
172
|
y: textY,
|
|
195
|
-
'font-family':
|
|
196
|
-
'font-size':
|
|
173
|
+
'font-family': theme_1.FONT.mono,
|
|
174
|
+
'font-size': theme_1.FONT.small + 2,
|
|
197
175
|
'font-weight': nameWeight,
|
|
198
176
|
'text-decoration': isPK ? 'underline' : undefined,
|
|
199
|
-
fill:
|
|
177
|
+
fill: theme_1.INK.line,
|
|
200
178
|
})
|
|
201
|
-
.text(colDef.name);
|
|
202
|
-
// Type (right-aligned, mono
|
|
179
|
+
.text((0, layout_1.truncate)(colDef.name, x + w - 60 - nameX, theme_1.FONT.small + 2, true));
|
|
180
|
+
// Type (right-aligned, mono muted).
|
|
203
181
|
if (colDef.type) {
|
|
204
182
|
svg
|
|
205
183
|
.child('text', {
|
|
206
184
|
x: x + w - 10,
|
|
207
185
|
y: textY,
|
|
208
|
-
'font-family':
|
|
209
|
-
'font-size':
|
|
210
|
-
fill:
|
|
186
|
+
'font-family': theme_1.FONT.mono,
|
|
187
|
+
'font-size': theme_1.FONT.small + 1,
|
|
188
|
+
fill: theme_1.INK.muted,
|
|
211
189
|
'text-anchor': 'end',
|
|
212
190
|
})
|
|
213
191
|
.text(colDef.type);
|
|
@@ -218,25 +196,25 @@ class RelationalDiagram {
|
|
|
218
196
|
.child('text', {
|
|
219
197
|
x: nameX,
|
|
220
198
|
y: ry + ROW - 4,
|
|
221
|
-
'font-family':
|
|
222
|
-
'font-size':
|
|
223
|
-
'font-weight':
|
|
224
|
-
fill:
|
|
199
|
+
'font-family': theme_1.FONT.family,
|
|
200
|
+
'font-size': theme_1.FONT.small - 1,
|
|
201
|
+
'font-weight': 'bold',
|
|
202
|
+
fill: theme_1.INK.muted,
|
|
225
203
|
})
|
|
226
204
|
.text(isPK ? 'PK' : 'FK');
|
|
227
205
|
}
|
|
228
|
-
// Row separator
|
|
206
|
+
// Row separator.
|
|
229
207
|
svg.child('line', {
|
|
230
208
|
x1: x,
|
|
231
209
|
y1: ry + ROW,
|
|
232
210
|
x2: x + w,
|
|
233
211
|
y2: ry + ROW,
|
|
234
|
-
stroke:
|
|
235
|
-
'stroke-width':
|
|
212
|
+
stroke: theme_1.INK.line,
|
|
213
|
+
'stroke-width': theme_1.STROKE.hair,
|
|
236
214
|
});
|
|
237
215
|
});
|
|
238
216
|
}
|
|
239
|
-
//
|
|
217
|
+
// -- Pick the connection point on the nearest edges of two boxes --------------
|
|
240
218
|
edgePoint(box, side) {
|
|
241
219
|
switch (side) {
|
|
242
220
|
case 'left':
|
|
@@ -260,8 +238,8 @@ class RelationalDiagram {
|
|
|
260
238
|
}
|
|
261
239
|
return bMidX >= aMidX ? ['right', 'left'] : ['left', 'right'];
|
|
262
240
|
}
|
|
263
|
-
//
|
|
264
|
-
crowFoot(parent, x, y, side
|
|
241
|
+
// -- Crow's-foot "many" endpoint (three prongs + arc bar) ----------------------
|
|
242
|
+
crowFoot(parent, x, y, side) {
|
|
265
243
|
// Symbol points AWAY from the box, back along the connector.
|
|
266
244
|
const reach = 13;
|
|
267
245
|
const spread = 7;
|
|
@@ -285,34 +263,34 @@ class RelationalDiagram {
|
|
|
285
263
|
];
|
|
286
264
|
}
|
|
287
265
|
// Three prongs converging at the box edge.
|
|
288
|
-
parent.child('line', { x1: x, y1: y, x2: perp[0][0], y2: perp[0][1], stroke:
|
|
289
|
-
parent.child('line', { x1: x, y1: y, x2: ex, y2: ey, stroke:
|
|
290
|
-
parent.child('line', { x1: x, y1: y, x2: perp[1][0], y2: perp[1][1], stroke:
|
|
266
|
+
parent.child('line', { x1: x, y1: y, x2: perp[0][0], y2: perp[0][1], stroke: theme_1.INK.line, 'stroke-width': theme_1.STROKE.hair });
|
|
267
|
+
parent.child('line', { x1: x, y1: y, x2: ex, y2: ey, stroke: theme_1.INK.line, 'stroke-width': theme_1.STROKE.hair });
|
|
268
|
+
parent.child('line', { x1: x, y1: y, x2: perp[1][0], y2: perp[1][1], stroke: theme_1.INK.line, 'stroke-width': theme_1.STROKE.hair });
|
|
291
269
|
// Connecting bar across the prongs.
|
|
292
270
|
parent.child('line', {
|
|
293
271
|
x1: perp[0][0],
|
|
294
272
|
y1: perp[0][1],
|
|
295
273
|
x2: perp[1][0],
|
|
296
274
|
y2: perp[1][1],
|
|
297
|
-
stroke:
|
|
298
|
-
'stroke-width':
|
|
275
|
+
stroke: theme_1.INK.line,
|
|
276
|
+
'stroke-width': theme_1.STROKE.hair,
|
|
299
277
|
});
|
|
300
278
|
}
|
|
301
|
-
//
|
|
302
|
-
oneBar(parent, x, y, side
|
|
279
|
+
// -- "One" endpoint (single perpendicular tick) --------------------------------
|
|
280
|
+
oneBar(parent, x, y, side) {
|
|
303
281
|
const gap = 11;
|
|
304
282
|
const ht = 7;
|
|
305
283
|
if (side === 'left' || side === 'right') {
|
|
306
284
|
const bx = side === 'right' ? x + gap : x - gap;
|
|
307
|
-
parent.child('line', { x1: bx, y1: y - ht, x2: bx, y2: y + ht, stroke:
|
|
285
|
+
parent.child('line', { x1: bx, y1: y - ht, x2: bx, y2: y + ht, stroke: theme_1.INK.line, 'stroke-width': theme_1.STROKE.heavy });
|
|
308
286
|
}
|
|
309
287
|
else {
|
|
310
288
|
const by = side === 'bottom' ? y + gap : y - gap;
|
|
311
|
-
parent.child('line', { x1: x - ht, y1: by, x2: x + ht, y2: by, stroke:
|
|
289
|
+
parent.child('line', { x1: x - ht, y1: by, x2: x + ht, y2: by, stroke: theme_1.INK.line, 'stroke-width': theme_1.STROKE.heavy });
|
|
312
290
|
}
|
|
313
291
|
}
|
|
314
|
-
//
|
|
315
|
-
renderRelationship(svg, rel, byName
|
|
292
|
+
// -- Draw one relationship connector with crow's-foot ends ----------------------
|
|
293
|
+
renderRelationship(svg, rel, byName) {
|
|
316
294
|
const a = byName.get(rel.from);
|
|
317
295
|
const b = byName.get(rel.to);
|
|
318
296
|
if (!a || !b)
|
|
@@ -339,21 +317,20 @@ class RelationalDiagram {
|
|
|
339
317
|
group.child('path', {
|
|
340
318
|
d,
|
|
341
319
|
fill: 'none',
|
|
342
|
-
stroke:
|
|
343
|
-
'stroke-width':
|
|
344
|
-
opacity: 0.85,
|
|
320
|
+
stroke: theme_1.INK.line,
|
|
321
|
+
'stroke-width': theme_1.STROKE.hair,
|
|
345
322
|
});
|
|
346
323
|
// Cardinality endpoints.
|
|
347
324
|
const manyAtFrom = rel.type === 'many-to-one' || rel.type === 'many-to-many';
|
|
348
325
|
const manyAtTo = rel.type === 'one-to-many' || rel.type === 'many-to-many';
|
|
349
326
|
if (manyAtFrom)
|
|
350
|
-
this.crowFoot(group, p.x, p.y, sideA
|
|
327
|
+
this.crowFoot(group, p.x, p.y, sideA);
|
|
351
328
|
else
|
|
352
|
-
this.oneBar(group, p.x, p.y, sideA
|
|
329
|
+
this.oneBar(group, p.x, p.y, sideA);
|
|
353
330
|
if (manyAtTo)
|
|
354
|
-
this.crowFoot(group, q.x, q.y, sideB
|
|
331
|
+
this.crowFoot(group, q.x, q.y, sideB);
|
|
355
332
|
else
|
|
356
|
-
this.oneBar(group, q.x, q.y, sideB
|
|
333
|
+
this.oneBar(group, q.x, q.y, sideB);
|
|
357
334
|
// Midpoint label (mono, hairline chip).
|
|
358
335
|
const label = rel.label ?? rel.type;
|
|
359
336
|
const mx = (p.x + q.x) / 2;
|
|
@@ -364,28 +341,25 @@ class RelationalDiagram {
|
|
|
364
341
|
y: my - 10,
|
|
365
342
|
width: lw,
|
|
366
343
|
height: 18,
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
stroke:
|
|
370
|
-
'stroke-width': 1,
|
|
344
|
+
fill: theme_1.INK.ground,
|
|
345
|
+
stroke: theme_1.INK.line,
|
|
346
|
+
'stroke-width': theme_1.STROKE.hair,
|
|
371
347
|
});
|
|
372
348
|
group
|
|
373
349
|
.child('text', {
|
|
374
350
|
x: mx,
|
|
375
351
|
y: my + 3,
|
|
376
|
-
'font-family':
|
|
377
|
-
'font-size':
|
|
378
|
-
'font-weight':
|
|
379
|
-
fill:
|
|
352
|
+
'font-family': theme_1.FONT.mono,
|
|
353
|
+
'font-size': theme_1.FONT.small + 1,
|
|
354
|
+
'font-weight': 'bold',
|
|
355
|
+
fill: theme_1.INK.line,
|
|
380
356
|
'text-anchor': 'middle',
|
|
381
357
|
})
|
|
382
358
|
.text(label);
|
|
383
359
|
}
|
|
384
|
-
//
|
|
385
|
-
|
|
360
|
+
// -- Build the SVG document ------------------------------------------------------
|
|
361
|
+
build() {
|
|
386
362
|
const { title, relationships } = this.opts;
|
|
387
|
-
const t = (0, palette_1.resolveTheme)(this.opts.theme);
|
|
388
|
-
const accent = (0, palette_1.resolveAccent)(this.opts.color);
|
|
389
363
|
const MARGIN = RelationalDiagram.MARGIN;
|
|
390
364
|
const BANNER = RelationalDiagram.BANNER_H;
|
|
391
365
|
const layout = this.computeLayout();
|
|
@@ -396,30 +370,29 @@ class RelationalDiagram {
|
|
|
396
370
|
const maxY = layout.length ? Math.max(...layout.map((b) => b.y + b.h)) : BANNER;
|
|
397
371
|
const totalW = maxX + MARGIN;
|
|
398
372
|
const totalH = maxY + MARGIN;
|
|
399
|
-
const doc = new
|
|
373
|
+
const doc = new svg_1.SvgDocument(totalW, totalH);
|
|
400
374
|
const svg = doc.root;
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
svg.child('rect', { width: totalW, height: totalH, fill: t.canvasBg });
|
|
405
|
-
// Banner (solid accent bar so `color` shows here too).
|
|
406
|
-
svg.child('rect', { width: totalW, height: BANNER, fill: accent.mid });
|
|
375
|
+
svg.child('rect', { width: totalW, height: totalH, fill: theme_1.INK.ground });
|
|
376
|
+
// Banner.
|
|
377
|
+
svg.child('rect', { width: totalW, height: BANNER, fill: theme_1.INK.wash, stroke: theme_1.INK.line, 'stroke-width': theme_1.STROKE.hair });
|
|
407
378
|
svg
|
|
408
379
|
.child('text', {
|
|
409
380
|
x: 24,
|
|
410
381
|
y: 38,
|
|
411
|
-
'font-family':
|
|
412
|
-
'font-size':
|
|
413
|
-
'font-weight':
|
|
414
|
-
fill:
|
|
382
|
+
'font-family': theme_1.FONT.family,
|
|
383
|
+
'font-size': theme_1.FONT.title + 11,
|
|
384
|
+
'font-weight': 'bold',
|
|
385
|
+
fill: theme_1.INK.line,
|
|
415
386
|
})
|
|
416
387
|
.text(title);
|
|
417
|
-
// Relationship connectors
|
|
418
|
-
|
|
419
|
-
relationships.forEach((rel) => this.renderRelationship(svg, rel, byName, relColor));
|
|
388
|
+
// Relationship connectors, drawn under the boxes.
|
|
389
|
+
relationships.forEach((rel) => this.renderRelationship(svg, rel, byName));
|
|
420
390
|
// Entity boxes on top.
|
|
421
|
-
layout.forEach((box
|
|
422
|
-
return doc
|
|
391
|
+
layout.forEach((box) => this.renderBox(svg, box));
|
|
392
|
+
return doc;
|
|
393
|
+
}
|
|
394
|
+
generate() {
|
|
395
|
+
return this.build().toString('Generated by ts-prorm-orm RelationalDiagram');
|
|
423
396
|
}
|
|
424
397
|
/**
|
|
425
398
|
* Write the SVG to a file, creating parent directories as needed.
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SchemaDocDiagram
|
|
2
|
+
* SchemaDocDiagram - generates a print-friendly "data dictionary" / schema
|
|
3
3
|
* documentation sheet as SVG.
|
|
4
4
|
*
|
|
5
5
|
* Where ERDiagram / ModelDiagram render the *visual* shape of a schema, this
|
|
6
6
|
* generator renders the *reference* counterpart: for every table a titled
|
|
7
7
|
* section followed by a tabular grid with one row per column, listing
|
|
8
|
-
* Column
|
|
9
|
-
* zebra-striped and each grid's header row is painted in the accent color.
|
|
8
|
+
* Column, Type, Nullable, Key, Default, Description. Rows are zebra-striped.
|
|
10
9
|
* A document title banner and a summary line ("N tables, M columns") top the
|
|
11
10
|
* sheet.
|
|
12
11
|
*
|
|
13
|
-
* All markup is built against a real DOM document (see ./svg-dom) — never by
|
|
14
|
-
* concatenating strings — and both `--theme` and `--color` genuinely change
|
|
15
|
-
* fill/stroke values in the output.
|
|
16
|
-
*
|
|
17
12
|
* Usage:
|
|
18
13
|
* const doc = new SchemaDocDiagram({ tables: [...], title: 'My Schema' });
|
|
19
14
|
* doc.save('./diagrams/schema.svg');
|
|
@@ -36,8 +31,12 @@ export interface DocTable {
|
|
|
36
31
|
export interface SchemaDocDiagramOptions {
|
|
37
32
|
tables: DocTable[];
|
|
38
33
|
title?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Accepted for backward compatibility and ignored: diagrams render in a
|
|
36
|
+
* single monochrome theme.
|
|
37
|
+
*/
|
|
39
38
|
theme?: 'light' | 'dark';
|
|
40
|
-
/**
|
|
39
|
+
/** Accepted for backward compatibility and ignored. */
|
|
41
40
|
color?: string;
|
|
42
41
|
}
|
|
43
42
|
export declare class SchemaDocDiagram {
|
|
@@ -47,6 +46,7 @@ export declare class SchemaDocDiagram {
|
|
|
47
46
|
private totalColumns;
|
|
48
47
|
/** Height of one table's rendered section. */
|
|
49
48
|
private sectionHeight;
|
|
49
|
+
private build;
|
|
50
50
|
generate(): string;
|
|
51
51
|
/** Draw one table section starting at `y`; returns the y after the section. */
|
|
52
52
|
private drawTable;
|