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.
Files changed (129) hide show
  1. package/CHANGELOG.md +209 -0
  2. package/README.md +32 -24
  3. package/dist/compliance/index.d.ts +2 -0
  4. package/dist/compliance/index.js +13 -1
  5. package/dist/connection-manager.js +13 -1
  6. package/dist/core/expressions.d.ts +58 -0
  7. package/dist/core/expressions.js +83 -0
  8. package/dist/core/hooks-manager.d.ts +179 -0
  9. package/dist/core/hooks-manager.js +291 -0
  10. package/dist/core/types.d.ts +235 -0
  11. package/dist/core/types.js +9 -0
  12. package/dist/decorators/index.d.ts +2 -0
  13. package/dist/decorators/index.js +11 -1
  14. package/dist/diagrams/chen-diagram.d.ts +15 -12
  15. package/dist/diagrams/chen-diagram.js +76 -85
  16. package/dist/diagrams/class-diagram.d.ts +9 -8
  17. package/dist/diagrams/class-diagram.js +60 -82
  18. package/dist/diagrams/core/index.d.ts +13 -0
  19. package/dist/diagrams/core/index.js +33 -0
  20. package/dist/diagrams/core/layout.d.ts +104 -0
  21. package/dist/diagrams/core/layout.js +223 -0
  22. package/dist/diagrams/{svg-dom.d.ts → core/svg.d.ts} +8 -20
  23. package/dist/diagrams/{svg-dom.js → core/svg.js} +21 -29
  24. package/dist/diagrams/core/theme.d.ts +84 -0
  25. package/dist/diagrams/core/theme.js +62 -0
  26. package/dist/diagrams/dependency-diagram.d.ts +15 -14
  27. package/dist/diagrams/dependency-diagram.js +71 -105
  28. package/dist/diagrams/er-diagram.d.ts +13 -26
  29. package/dist/diagrams/er-diagram.js +180 -259
  30. package/dist/diagrams/flow-diagram.d.ts +16 -11
  31. package/dist/diagrams/flow-diagram.js +96 -91
  32. package/dist/diagrams/gantt-diagram.d.ts +10 -5
  33. package/dist/diagrams/gantt-diagram.js +77 -103
  34. package/dist/diagrams/index-diagram.d.ts +10 -10
  35. package/dist/diagrams/index-diagram.js +106 -116
  36. package/dist/diagrams/index.d.ts +6 -9
  37. package/dist/diagrams/index.js +9 -24
  38. package/dist/diagrams/migration-diagram.d.ts +8 -4
  39. package/dist/diagrams/migration-diagram.js +189 -161
  40. package/dist/diagrams/model-diagram.d.ts +34 -34
  41. package/dist/diagrams/model-diagram.js +106 -485
  42. package/dist/diagrams/package-diagram.d.ts +9 -6
  43. package/dist/diagrams/package-diagram.js +64 -101
  44. package/dist/diagrams/relational-diagram.d.ts +12 -10
  45. package/dist/diagrams/relational-diagram.js +87 -114
  46. package/dist/diagrams/schemadoc-diagram.d.ts +8 -8
  47. package/dist/diagrams/schemadoc-diagram.js +71 -93
  48. package/dist/diagrams/sequence-diagram.d.ts +10 -10
  49. package/dist/diagrams/sequence-diagram.js +64 -89
  50. package/dist/diagrams/state-diagram.d.ts +10 -9
  51. package/dist/diagrams/state-diagram.js +69 -92
  52. package/dist/diagrams/tree-diagram.d.ts +11 -5
  53. package/dist/diagrams/tree-diagram.js +41 -65
  54. package/dist/dialects/clickhouse/index.js +15 -0
  55. package/dist/dialects/cockroachdb/index.d.ts +1 -1
  56. package/dist/dialects/cockroachdb/index.js +32 -63
  57. package/dist/dialects/db2/index.js +23 -8
  58. package/dist/dialects/dialect.d.ts +29 -5
  59. package/dist/dialects/duckdb/index.js +9 -2
  60. package/dist/dialects/hana/index.js +22 -5
  61. package/dist/dialects/lock-clause-helper.d.ts +167 -0
  62. package/dist/dialects/lock-clause-helper.js +316 -0
  63. package/dist/dialects/mariadb/index.d.ts +7 -4
  64. package/dist/dialects/mariadb/index.js +36 -60
  65. package/dist/dialects/mssql/index.js +34 -3
  66. package/dist/dialects/mysql/index.d.ts +1 -1
  67. package/dist/dialects/mysql/index.js +17 -45
  68. package/dist/dialects/oracle/index.d.ts +14 -3
  69. package/dist/dialects/oracle/index.js +66 -36
  70. package/dist/dialects/order-expression-helper.d.ts +72 -0
  71. package/dist/dialects/order-expression-helper.js +154 -0
  72. package/dist/dialects/partial-index.d.ts +52 -0
  73. package/dist/dialects/partial-index.js +251 -0
  74. package/dist/dialects/postgres/index.d.ts +1 -1
  75. package/dist/dialects/postgres/index.js +43 -68
  76. package/dist/dialects/redshift/index.js +9 -2
  77. package/dist/dialects/snowflake/index.js +17 -0
  78. package/dist/dialects/spanner/index.js +7 -2
  79. package/dist/dialects/sqlite/driver.d.ts +55 -0
  80. package/dist/dialects/sqlite/driver.js +102 -0
  81. package/dist/dialects/sqlite/index.d.ts +1 -1
  82. package/dist/dialects/sqlite/index.js +49 -27
  83. package/dist/graph/base-graph-dialect.d.ts +24 -3
  84. package/dist/graph/base-graph-dialect.js +43 -2
  85. package/dist/graph/dgraph/index.js +6 -0
  86. package/dist/graph/gremlin/index.d.ts +6 -0
  87. package/dist/graph/gremlin/index.js +12 -1
  88. package/dist/graph/index.d.ts +1 -1
  89. package/dist/graph/neo4j/index.d.ts +2 -0
  90. package/dist/graph/neo4j/index.js +6 -1
  91. package/dist/graph/types.d.ts +12 -1
  92. package/dist/index.d.ts +13 -4
  93. package/dist/index.js +54 -7
  94. package/dist/logging/index.d.ts +10 -0
  95. package/dist/logging/index.js +23 -0
  96. package/dist/logging/query-logging.d.ts +82 -0
  97. package/dist/logging/query-logging.js +102 -0
  98. package/dist/models/decorators.d.ts +39 -3
  99. package/dist/models/decorators.js +74 -0
  100. package/dist/models/eager-load.d.ts +99 -0
  101. package/dist/models/eager-load.js +348 -5
  102. package/dist/models/indexes.d.ts +3 -2
  103. package/dist/models/indexes.js +7 -1
  104. package/dist/models/model.js +69 -43
  105. package/dist/prorm.d.ts +175 -409
  106. package/dist/prorm.js +1142 -557
  107. package/dist/query-builders/order-limit-builder.js +12 -10
  108. package/dist/query-builders/sql-compiler.d.ts +10 -3
  109. package/dist/query-builders/sql-compiler.js +14 -43
  110. package/dist/query-interface.d.ts +2 -1
  111. package/dist/sql-constants.d.ts +44 -0
  112. package/dist/sql-constants.js +138 -1
  113. package/dist/types/index.d.ts +53 -17
  114. package/dist/types/index.js +10 -15
  115. package/dist/types/query-types.d.ts +26 -0
  116. package/dist/types/query-types.js +30 -0
  117. package/package.json +32 -5
  118. package/dist/decorators/belongs-to-many.js +0 -115
  119. package/dist/decorators/belongs-to.js +0 -115
  120. package/dist/decorators/has-many.js +0 -127
  121. package/dist/decorators/has-one.js +0 -116
  122. package/dist/diagrams/palette.d.ts +0 -138
  123. package/dist/diagrams/palette.js +0 -194
  124. package/dist/hooks/hooks-manager.d.ts +0 -189
  125. package/dist/hooks/hooks-manager.js +0 -350
  126. package/dist/hooks/index.d.ts +0 -8
  127. package/dist/hooks/index.js +0 -37
  128. /package/dist/{logging.d.ts → logging/logger.d.ts} +0 -0
  129. /package/dist/{logging.js → logging/logger.js} +0 -0
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ /**
3
+ * Layout primitives shared by every generator.
4
+ *
5
+ * Each generator previously carried its own text measurement, box drawing,
6
+ * arrow routing and footer code. These are the pieces that were duplicated,
7
+ * factored once so a change to how a panel or an edge looks lands everywhere.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.measureText = measureText;
11
+ exports.truncate = truncate;
12
+ exports.rect = rect;
13
+ exports.line = line;
14
+ exports.text = text;
15
+ exports.panelSize = panelSize;
16
+ exports.panel = panel;
17
+ exports.defineArrowhead = defineArrowhead;
18
+ exports.edge = edge;
19
+ exports.gridPack = gridPack;
20
+ exports.documentTitle = documentTitle;
21
+ exports.footer = footer;
22
+ const theme_1 = require("./theme");
23
+ /**
24
+ * Approximate rendered width of a string.
25
+ *
26
+ * SVG has no text metrics without a layout engine, so this is the usual
27
+ * average-advance estimate. It is deliberately slightly generous: under-
28
+ * measuring clips text, over-measuring only adds whitespace.
29
+ */
30
+ function measureText(text, size = theme_1.FONT.body, mono = false) {
31
+ const ratio = mono ? 0.6 : 0.55;
32
+ return Math.ceil(text.length * size * ratio);
33
+ }
34
+ /** Truncate to fit `maxWidth`, appending a single-character ellipsis. */
35
+ function truncate(text, maxWidth, size = theme_1.FONT.body, mono = false) {
36
+ if (measureText(text, size, mono) <= maxWidth)
37
+ return text;
38
+ let out = text;
39
+ while (out.length > 1 && measureText(out + '...', size, mono) > maxWidth) {
40
+ out = out.slice(0, -1);
41
+ }
42
+ return out + '...';
43
+ }
44
+ /** Draw a plain hairline rectangle. */
45
+ function rect(parent, box, fill = theme_1.INK.ground) {
46
+ return parent.child('rect', {
47
+ x: box.x,
48
+ y: box.y,
49
+ width: box.w,
50
+ height: box.h,
51
+ fill,
52
+ stroke: theme_1.INK.line,
53
+ 'stroke-width': theme_1.STROKE.hair,
54
+ });
55
+ }
56
+ /** Draw a hairline between two points. */
57
+ function line(parent, x1, y1, x2, y2, dashed = false) {
58
+ const el = parent.child('line', {
59
+ x1,
60
+ y1,
61
+ x2,
62
+ y2,
63
+ stroke: theme_1.INK.line,
64
+ 'stroke-width': theme_1.STROKE.hair,
65
+ });
66
+ if (dashed)
67
+ el.attr('stroke-dasharray', '4 3');
68
+ return el;
69
+ }
70
+ /** Draw a run of text. */
71
+ function text(parent, x, y, value, opts = {}) {
72
+ const el = parent
73
+ .child('text', {
74
+ x,
75
+ y,
76
+ 'font-family': opts.mono ? theme_1.FONT.mono : theme_1.FONT.family,
77
+ 'font-size': opts.size ?? theme_1.FONT.body,
78
+ fill: opts.fill ?? theme_1.INK.line,
79
+ })
80
+ .text(value);
81
+ if (opts.anchor && opts.anchor !== 'start')
82
+ el.attr('text-anchor', opts.anchor);
83
+ if (opts.weight === 'bold')
84
+ el.attr('font-weight', 'bold');
85
+ return el;
86
+ }
87
+ /** Compute a panel's size without drawing it, for layout passes. */
88
+ function panelSize(opts) {
89
+ const rows = opts.rows ?? [];
90
+ const headerH = opts.subtitle ? theme_1.ROW_HEIGHT * 2 : theme_1.ROW_HEIGHT + theme_1.SPACE.sm;
91
+ let contentW = measureText(opts.title, theme_1.FONT.title) + theme_1.SPACE.lg;
92
+ if (opts.subtitle)
93
+ contentW = Math.max(contentW, measureText(opts.subtitle, theme_1.FONT.small) + theme_1.SPACE.lg);
94
+ for (const r of rows) {
95
+ const marker = r.marker ? measureText(r.marker, theme_1.FONT.small, true) + theme_1.SPACE.sm : 0;
96
+ const label = measureText(r.label, theme_1.FONT.body);
97
+ const detail = r.detail ? measureText(r.detail, theme_1.FONT.small, true) + theme_1.SPACE.lg : 0;
98
+ contentW = Math.max(contentW, marker + label + detail + theme_1.SPACE.lg * 2);
99
+ }
100
+ return {
101
+ w: Math.max(opts.minWidth ?? 0, contentW),
102
+ h: headerH + rows.length * theme_1.ROW_HEIGHT + (rows.length ? theme_1.SPACE.xs : 0),
103
+ };
104
+ }
105
+ /**
106
+ * Draw a titled panel at `x,y` and return the box it occupies.
107
+ *
108
+ * The header is a washed bar with a hairline under it; rows are plain text with
109
+ * the detail column right-aligned.
110
+ */
111
+ function panel(parent, x, y, opts) {
112
+ const { w, h } = panelSize(opts);
113
+ const rows = opts.rows ?? [];
114
+ const headerH = opts.subtitle ? theme_1.ROW_HEIGHT * 2 : theme_1.ROW_HEIGHT + theme_1.SPACE.sm;
115
+ const box = { x, y, w, h };
116
+ const g = parent.child('g');
117
+ rect(g, box);
118
+ // Header bar
119
+ g.child('rect', {
120
+ x,
121
+ y,
122
+ width: w,
123
+ height: headerH,
124
+ fill: theme_1.INK.wash,
125
+ stroke: theme_1.INK.line,
126
+ 'stroke-width': theme_1.STROKE.hair,
127
+ });
128
+ text(g, x + theme_1.SPACE.sm, y + theme_1.FONT.title + theme_1.SPACE.xs, opts.title, {
129
+ size: theme_1.FONT.title,
130
+ weight: 'bold',
131
+ });
132
+ if (opts.subtitle) {
133
+ text(g, x + theme_1.SPACE.sm, y + theme_1.ROW_HEIGHT + theme_1.FONT.small + theme_1.SPACE.xs, opts.subtitle, {
134
+ size: theme_1.FONT.small,
135
+ fill: theme_1.INK.muted,
136
+ mono: true,
137
+ });
138
+ }
139
+ rows.forEach((r, i) => {
140
+ const rowY = y + headerH + i * theme_1.ROW_HEIGHT;
141
+ const baseline = rowY + theme_1.ROW_HEIGHT - theme_1.SPACE.xs - 1;
142
+ if (r.rule)
143
+ line(g, x, rowY, x + w, rowY);
144
+ let cursor = x + theme_1.SPACE.sm;
145
+ if (r.marker) {
146
+ text(g, cursor, baseline, r.marker, { size: theme_1.FONT.small, mono: true, fill: theme_1.INK.muted });
147
+ cursor += measureText(r.marker, theme_1.FONT.small, true) + theme_1.SPACE.sm;
148
+ }
149
+ text(g, cursor, baseline, r.label, { size: theme_1.FONT.body });
150
+ if (r.detail) {
151
+ text(g, x + w - theme_1.SPACE.sm, baseline, r.detail, {
152
+ size: theme_1.FONT.small,
153
+ mono: true,
154
+ fill: theme_1.INK.muted,
155
+ anchor: 'end',
156
+ });
157
+ }
158
+ });
159
+ return box;
160
+ }
161
+ /** Register the single arrowhead marker. Call once per document. */
162
+ function defineArrowhead(defs, id = 'arrow') {
163
+ defs
164
+ .child('marker', {
165
+ id,
166
+ viewBox: '0 0 10 10',
167
+ refX: 9,
168
+ refY: 5,
169
+ markerWidth: 6,
170
+ markerHeight: 6,
171
+ orient: 'auto-start-reverse',
172
+ })
173
+ .child('path', { d: 'M 0 0 L 10 5 L 0 10 z', fill: theme_1.INK.line });
174
+ }
175
+ /** Draw a straight edge, optionally arrowed and/or dashed, with a label. */
176
+ function edge(parent, from, to, opts = {}) {
177
+ const el = line(parent, from.x, from.y, to.x, to.y, opts.dashed);
178
+ if (opts.arrow)
179
+ el.attr('marker-end', `url(#${opts.markerId ?? 'arrow'})`);
180
+ if (opts.label) {
181
+ text(parent, (from.x + to.x) / 2, (from.y + to.y) / 2 - theme_1.SPACE.xs, opts.label, {
182
+ size: theme_1.FONT.small,
183
+ fill: theme_1.INK.muted,
184
+ anchor: 'middle',
185
+ });
186
+ }
187
+ return el;
188
+ }
189
+ /** Pack boxes into a grid, returning positions and the total canvas size. */
190
+ function gridPack(sizes, columns, gap = theme_1.SPACE.xl, origin = { x: theme_1.SPACE.xl, y: theme_1.SPACE.xl }) {
191
+ const cols = Math.max(1, columns);
192
+ const colWidth = sizes.length ? Math.max(...sizes.map((s) => s.w)) : 0;
193
+ const positions = [];
194
+ let rowTop = origin.y;
195
+ let rowHeight = 0;
196
+ sizes.forEach((s, i) => {
197
+ const col = i % cols;
198
+ if (col === 0 && i > 0) {
199
+ rowTop += rowHeight + gap;
200
+ rowHeight = 0;
201
+ }
202
+ positions.push({ x: origin.x + col * (colWidth + gap), y: rowTop });
203
+ rowHeight = Math.max(rowHeight, s.h);
204
+ });
205
+ const rows = Math.ceil(sizes.length / cols);
206
+ return {
207
+ positions,
208
+ width: origin.x * 2 + cols * colWidth + (cols - 1) * gap,
209
+ height: rowTop + rowHeight + origin.y,
210
+ };
211
+ }
212
+ /** Draw a title at the top of a document. Returns the y to continue from. */
213
+ function documentTitle(parent, x, y, title) {
214
+ text(parent, x, y + theme_1.FONT.title, title, { size: theme_1.FONT.title + 3, weight: 'bold' });
215
+ return y + theme_1.FONT.title + theme_1.SPACE.md;
216
+ }
217
+ /** Draw a footer line. Plain text, no separators or glyphs. */
218
+ function footer(parent, x, y, parts) {
219
+ return text(parent, x, y, parts.filter(Boolean).join(' '), {
220
+ size: theme_1.FONT.small,
221
+ fill: theme_1.INK.muted,
222
+ });
223
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * svg-dom — a small DOM-backed SVG builder shared by every diagram generator.
2
+ * A small DOM-backed SVG builder shared by every diagram generator.
3
3
  *
4
4
  * Diagrams are constructed against a real DOM document (via `@xmldom/xmldom`)
5
5
  * using `createElement`/`setAttribute`/`appendChild`, then serialized once with
@@ -7,9 +7,12 @@
7
7
  * values are escaped by the serializer, element nesting can't be malformed, and
8
8
  * every generator shares one construction API.
9
9
  *
10
- * The `El` wrapper is a thin fluent facade over a DOM `Element` `.attr()`,
11
- * `.text()`, `.child()` so generator code reads declaratively while the
12
- * underlying nodes remain inspectable/testable as real DOM.
10
+ * The `El` wrapper is a thin fluent facade over a DOM `Element` - `.attr()`,
11
+ * `.text()`, `.child()` - so generator code reads declaratively while the
12
+ * underlying nodes remain inspectable and testable as real DOM.
13
+ *
14
+ * The gradient helper was removed with the move to a monochrome theme; nothing
15
+ * in the redesigned generators emits a gradient.
13
16
  */
14
17
  export type AttrValue = string | number | undefined | null;
15
18
  export type Attrs = Record<string, AttrValue>;
@@ -38,25 +41,10 @@ export declare class SvgDocument {
38
41
  constructor(width: number, height: number, viewBox?: string);
39
42
  /** Create a standalone element not yet attached to the tree. */
40
43
  create(tag: string, attrs?: Attrs): El;
41
- /**
42
- * Embed a `<style>` block (inside <defs>) so browser renderers can resolve
43
- * web fonts / CSS. Used by the Industry-styled generators to @import Barlow /
44
- * Barlow Condensed / JetBrains Mono; non-browser renderers ignore it and fall
45
- * back to the system fonts declared per family.
46
- */
44
+ /** Embed a `<style>` block inside <defs>. */
47
45
  style(css: string): this;
48
46
  /** Get (creating on first use) the shared <defs> block. */
49
47
  defs(): El;
50
- /**
51
- * Convenience: add a linear gradient to <defs> and return its id.
52
- * `stops` is a list of [offsetPercent, color] pairs.
53
- */
54
- linearGradient(id: string, stops: Array<[number, string]>, opts?: {
55
- x1?: number;
56
- y1?: number;
57
- x2?: number;
58
- y2?: number;
59
- }): string;
60
48
  /** Serialize the whole document to an XML/SVG string (with XML prolog). */
61
49
  toString(comment?: string): string;
62
50
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * svg-dom — a small DOM-backed SVG builder shared by every diagram generator.
3
+ * A small DOM-backed SVG builder shared by every diagram generator.
4
4
  *
5
5
  * Diagrams are constructed against a real DOM document (via `@xmldom/xmldom`)
6
6
  * using `createElement`/`setAttribute`/`appendChild`, then serialized once with
@@ -8,9 +8,12 @@
8
8
  * values are escaped by the serializer, element nesting can't be malformed, and
9
9
  * every generator shares one construction API.
10
10
  *
11
- * The `El` wrapper is a thin fluent facade over a DOM `Element` `.attr()`,
12
- * `.text()`, `.child()` so generator code reads declaratively while the
13
- * underlying nodes remain inspectable/testable as real DOM.
11
+ * The `El` wrapper is a thin fluent facade over a DOM `Element` - `.attr()`,
12
+ * `.text()`, `.child()` - so generator code reads declaratively while the
13
+ * underlying nodes remain inspectable and testable as real DOM.
14
+ *
15
+ * The gradient helper was removed with the move to a monochrome theme; nothing
16
+ * in the redesigned generators emits a gradient.
14
17
  */
15
18
  Object.defineProperty(exports, "__esModule", { value: true });
16
19
  exports.SvgDocument = exports.El = void 0;
@@ -74,12 +77,7 @@ class SvgDocument {
74
77
  el.attrs(attrs);
75
78
  return el;
76
79
  }
77
- /**
78
- * Embed a `<style>` block (inside <defs>) so browser renderers can resolve
79
- * web fonts / CSS. Used by the Industry-styled generators to @import Barlow /
80
- * Barlow Condensed / JetBrains Mono; non-browser renderers ignore it and fall
81
- * back to the system fonts declared per family.
82
- */
80
+ /** Embed a `<style>` block inside <defs>. */
83
81
  style(css) {
84
82
  const s = this.defs().child('style', { type: 'text/css' });
85
83
  s.node.appendChild(this.doc.createTextNode(css));
@@ -94,29 +92,23 @@ class SvgDocument {
94
92
  }
95
93
  return this._defs;
96
94
  }
97
- /**
98
- * Convenience: add a linear gradient to <defs> and return its id.
99
- * `stops` is a list of [offsetPercent, color] pairs.
100
- */
101
- linearGradient(id, stops, opts) {
102
- const g = this.defs().child('linearGradient', {
103
- id,
104
- x1: opts?.x1 ?? 0,
105
- y1: opts?.y1 ?? 0,
106
- x2: opts?.x2 ?? 1,
107
- y2: opts?.y2 ?? 1,
108
- gradientUnits: 'objectBoundingBox',
109
- });
110
- for (const [offset, color] of stops) {
111
- g.child('stop', { offset: `${offset}%`, 'stop-color': color });
112
- }
113
- return id;
114
- }
115
95
  /** Serialize the whole document to an XML/SVG string (with XML prolog). */
116
96
  toString(comment) {
117
97
  const body = new xmldom_1.XMLSerializer().serializeToString(this.doc);
118
98
  const prolog = `<?xml version="1.0" encoding="UTF-8"?>`;
119
- return comment ? `${prolog}\n<!-- ${comment} -->\n${body}` : `${prolog}\n${body}`;
99
+ if (!comment)
100
+ return `${prolog}\n${body}`;
101
+ // The comment is concatenated outside the serializer, so it has to be made
102
+ // safe here. Caller-supplied text (a model name) reaches this, and an
103
+ // unescaped `&` or an embedded `--` produces a document that is not
104
+ // well-formed XML - which some SVG consumers reject outright.
105
+ const safe = comment
106
+ .replace(/&/g, '&amp;')
107
+ .replace(/</g, '&lt;')
108
+ .replace(/>/g, '&gt;')
109
+ .replace(/-{2,}/g, '-')
110
+ .trim();
111
+ return `${prolog}\n<!-- ${safe} -->\n${body}`;
120
112
  }
121
113
  }
122
114
  exports.SvgDocument = SvgDocument;
@@ -0,0 +1,84 @@
1
+ /**
2
+ * One theme, monochrome hairline.
3
+ *
4
+ * This replaces a 239-line palette module that carried nine accent palettes,
5
+ * three-stop gradient definitions, badge tint tables and a light/dark theme
6
+ * resolver. Diagrams are technical drawings: black on white, 1px rules, square
7
+ * corners, one font stack. They print, diff and embed predictably, and there is
8
+ * no colour to keep consistent across fifteen generators.
9
+ *
10
+ * The old `resolveAccent` / `resolveTheme` / `rotatedPalettes` entry points are
11
+ * kept as thin shims in ./legacy-palette so existing generators and callers
12
+ * keep compiling while they are converted.
13
+ */
14
+ /** Ink, rules and fills. Every generator draws from these four values. */
15
+ export declare const INK: {
16
+ /** Text, borders, arrowheads. */
17
+ readonly line: "#000000";
18
+ /** Page and shape fill. */
19
+ readonly ground: "#ffffff";
20
+ /** Secondary text: types, counts, footers. */
21
+ readonly muted: "#666666";
22
+ /** Fill for header bars and emphasis rows. */
23
+ readonly wash: "#f0f0f0";
24
+ };
25
+ /** Stroke widths. Hairline everywhere; `heavy` only for emphasis. */
26
+ export declare const STROKE: {
27
+ readonly hair: 1;
28
+ readonly heavy: 2;
29
+ };
30
+ /**
31
+ * One font stack, three sizes. No web-font import: diagrams should render the
32
+ * same offline and in a PDF pipeline, which a Google Fonts `@import` cannot
33
+ * guarantee.
34
+ */
35
+ export declare const FONT: {
36
+ readonly family: "ui-sans-serif, -apple-system, Segoe UI, Helvetica, Arial, sans-serif";
37
+ readonly mono: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
38
+ readonly title: 13;
39
+ readonly body: 11;
40
+ readonly small: 9;
41
+ };
42
+ /** Spacing scale. Multiples of 4 keep everything on a grid. */
43
+ export declare const SPACE: {
44
+ readonly xs: 4;
45
+ readonly sm: 8;
46
+ readonly md: 12;
47
+ readonly lg: 16;
48
+ readonly xl: 24;
49
+ };
50
+ /** Row height for tabular content (field lists, columns, tasks). */
51
+ export declare const ROW_HEIGHT = 18;
52
+ /** The complete theme, for generators that prefer one object. */
53
+ export declare const THEME: {
54
+ readonly ink: {
55
+ /** Text, borders, arrowheads. */
56
+ readonly line: "#000000";
57
+ /** Page and shape fill. */
58
+ readonly ground: "#ffffff";
59
+ /** Secondary text: types, counts, footers. */
60
+ readonly muted: "#666666";
61
+ /** Fill for header bars and emphasis rows. */
62
+ readonly wash: "#f0f0f0";
63
+ };
64
+ readonly stroke: {
65
+ readonly hair: 1;
66
+ readonly heavy: 2;
67
+ };
68
+ readonly font: {
69
+ readonly family: "ui-sans-serif, -apple-system, Segoe UI, Helvetica, Arial, sans-serif";
70
+ readonly mono: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
71
+ readonly title: 13;
72
+ readonly body: 11;
73
+ readonly small: 9;
74
+ };
75
+ readonly space: {
76
+ readonly xs: 4;
77
+ readonly sm: 8;
78
+ readonly md: 12;
79
+ readonly lg: 16;
80
+ readonly xl: 24;
81
+ };
82
+ readonly rowHeight: 18;
83
+ };
84
+ export type Theme = typeof THEME;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ /**
3
+ * One theme, monochrome hairline.
4
+ *
5
+ * This replaces a 239-line palette module that carried nine accent palettes,
6
+ * three-stop gradient definitions, badge tint tables and a light/dark theme
7
+ * resolver. Diagrams are technical drawings: black on white, 1px rules, square
8
+ * corners, one font stack. They print, diff and embed predictably, and there is
9
+ * no colour to keep consistent across fifteen generators.
10
+ *
11
+ * The old `resolveAccent` / `resolveTheme` / `rotatedPalettes` entry points are
12
+ * kept as thin shims in ./legacy-palette so existing generators and callers
13
+ * keep compiling while they are converted.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.THEME = exports.ROW_HEIGHT = exports.SPACE = exports.FONT = exports.STROKE = exports.INK = void 0;
17
+ /** Ink, rules and fills. Every generator draws from these four values. */
18
+ exports.INK = {
19
+ /** Text, borders, arrowheads. */
20
+ line: '#000000',
21
+ /** Page and shape fill. */
22
+ ground: '#ffffff',
23
+ /** Secondary text: types, counts, footers. */
24
+ muted: '#666666',
25
+ /** Fill for header bars and emphasis rows. */
26
+ wash: '#f0f0f0',
27
+ };
28
+ /** Stroke widths. Hairline everywhere; `heavy` only for emphasis. */
29
+ exports.STROKE = {
30
+ hair: 1,
31
+ heavy: 2,
32
+ };
33
+ /**
34
+ * One font stack, three sizes. No web-font import: diagrams should render the
35
+ * same offline and in a PDF pipeline, which a Google Fonts `@import` cannot
36
+ * guarantee.
37
+ */
38
+ exports.FONT = {
39
+ family: 'ui-sans-serif, -apple-system, Segoe UI, Helvetica, Arial, sans-serif',
40
+ mono: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',
41
+ title: 13,
42
+ body: 11,
43
+ small: 9,
44
+ };
45
+ /** Spacing scale. Multiples of 4 keep everything on a grid. */
46
+ exports.SPACE = {
47
+ xs: 4,
48
+ sm: 8,
49
+ md: 12,
50
+ lg: 16,
51
+ xl: 24,
52
+ };
53
+ /** Row height for tabular content (field lists, columns, tasks). */
54
+ exports.ROW_HEIGHT = 18;
55
+ /** The complete theme, for generators that prefer one object. */
56
+ exports.THEME = {
57
+ ink: exports.INK,
58
+ stroke: exports.STROKE,
59
+ font: exports.FONT,
60
+ space: exports.SPACE,
61
+ rowHeight: exports.ROW_HEIGHT,
62
+ };
@@ -1,22 +1,19 @@
1
1
  /**
2
- * DependencyDiagram renders a directed dependency graph of models/tables.
2
+ * DependencyDiagram - renders a directed dependency graph of models/tables.
3
3
  *
4
- * Nodes are models/tables; a directed edge `from to` means "from depends on
4
+ * Nodes are models/tables; a directed edge `from -> to` means "from depends on
5
5
  * to" (e.g. table `from` holds a foreign key into table `to`). The generator:
6
6
  *
7
7
  * - Computes a layered / topological layout: each node's layer is the longest
8
8
  * dependency path to a leaf. Nodes with no dependencies sit in layer 0;
9
9
  * their dependents fan out into higher layers.
10
10
  * - Detects cycles (back edges) with a DFS colouring pass and visually flags
11
- * the cyclic edges in red. The layering pass carries its own visited guard
12
- * so a cycle can never send it into an infinite loop.
13
- * - Draws each node as a labelled rounded box sized to its label, with arrows
11
+ * the cyclic edges with a heavier dashed stroke. The layering pass carries
12
+ * its own visited guard so a cycle can never send it into an infinite loop.
13
+ * - Draws each node as a labelled box sized to its label, with arrows
14
14
  * between dependent boxes.
15
15
  *
16
- * Accent colour (`color`) drives the node fills / arrowheads; the theme
17
- * (`light` | `dark`) drives the canvas + text colours. Both genuinely change
18
- * real fill/stroke values in the emitted SVG. The viewBox auto-sizes to the
19
- * computed layout.
16
+ * The viewBox auto-sizes to the computed layout.
20
17
  *
21
18
  * Usage:
22
19
  * const d = new DependencyDiagram({ nodes, edges, title: 'Schema deps' });
@@ -36,8 +33,12 @@ export interface DependencyDiagramOptions {
36
33
  nodes: DepNode[];
37
34
  edges: DepEdge[];
38
35
  title?: string;
36
+ /**
37
+ * Accepted for backward compatibility and ignored: diagrams render in a
38
+ * single monochrome theme.
39
+ */
39
40
  theme?: 'light' | 'dark';
40
- /** Named palette or hex accent colour */
41
+ /** Accepted for backward compatibility and ignored. */
41
42
  color?: string;
42
43
  direction?: 'horizontal' | 'vertical';
43
44
  }
@@ -51,9 +52,8 @@ export declare class DependencyDiagram {
51
52
  private static readonly MIN_NODE_W;
52
53
  private static readonly LAYER_GAP;
53
54
  private static readonly NODE_GAP;
54
- private static readonly R;
55
55
  constructor(options: DependencyDiagramOptions);
56
- /** Adjacency: node the nodes it depends on (its outgoing edge targets). */
56
+ /** Adjacency: node -> the nodes it depends on (its outgoing edge targets). */
57
57
  private buildAdjacency;
58
58
  /**
59
59
  * Assign each node a layer = longest dependency path length (0 for nodes with
@@ -62,16 +62,17 @@ export declare class DependencyDiagram {
62
62
  */
63
63
  private computeLayers;
64
64
  /**
65
- * Detect cyclic edges via DFS colouring. Returns a set of "fromto" keys that
65
+ * Detect cyclic edges via DFS colouring. Returns a set of "from-to" keys that
66
66
  * are back edges (participate in a cycle).
67
67
  */
68
68
  private detectCyclicEdges;
69
69
  private nodeWidth;
70
70
  /**
71
71
  * Point on the boundary of a rectangle along the line from the rect centre
72
- * toward an external point used so arrowheads land on the box edge.
72
+ * toward an external point - used so arrowheads land on the box edge.
73
73
  */
74
74
  private edgePoint;
75
+ private build;
75
76
  generate(): string;
76
77
  private place;
77
78
  private defineArrow;