ts-prorm-orm 1.2.3 → 2.1.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 (204) hide show
  1. package/CHANGELOG.md +331 -1
  2. package/README.md +32 -24
  3. package/dist/compliance/data-classifier.d.ts +6 -0
  4. package/dist/compliance/data-classifier.js +6 -0
  5. package/dist/compliance/data-lineage.d.ts +4 -0
  6. package/dist/compliance/data-lineage.js +4 -0
  7. package/dist/compliance/data-masker.d.ts +4 -0
  8. package/dist/compliance/data-masker.js +4 -0
  9. package/dist/compliance/index.d.ts +4 -0
  10. package/dist/compliance/index.js +15 -1
  11. package/dist/compliance/pseudonymization.d.ts +4 -0
  12. package/dist/compliance/pseudonymization.js +4 -0
  13. package/dist/compliance/query-firewall.d.ts +9 -9
  14. package/dist/compliance/query-firewall.js +9 -9
  15. package/dist/compliance/rate-limiter.d.ts +4 -0
  16. package/dist/compliance/rate-limiter.js +4 -0
  17. package/dist/compliance/row-level-security.d.ts +2 -0
  18. package/dist/compliance/row-level-security.js +2 -0
  19. package/dist/compliance/security-decorator.d.ts +8 -0
  20. package/dist/compliance/security-decorator.js +8 -0
  21. package/dist/compliance/session-isolation.d.ts +4 -0
  22. package/dist/compliance/session-isolation.js +4 -0
  23. package/dist/compliance/worm-storage.d.ts +4 -0
  24. package/dist/compliance/worm-storage.js +4 -0
  25. package/dist/connection-manager.js +13 -1
  26. package/dist/core/expressions.d.ts +58 -0
  27. package/dist/core/expressions.js +83 -0
  28. package/dist/core/hooks-manager.d.ts +179 -0
  29. package/dist/core/hooks-manager.js +291 -0
  30. package/dist/core/types.d.ts +235 -0
  31. package/dist/core/types.js +9 -0
  32. package/dist/decorators/audit.d.ts +3 -1
  33. package/dist/decorators/audit.js +3 -1
  34. package/dist/decorators/check.d.ts +15 -15
  35. package/dist/decorators/check.js +15 -15
  36. package/dist/decorators/collate.d.ts +16 -0
  37. package/dist/decorators/collate.js +16 -0
  38. package/dist/decorators/comment.d.ts +3 -1
  39. package/dist/decorators/comment.js +3 -1
  40. package/dist/decorators/database-settings.d.ts +6 -0
  41. package/dist/decorators/database-settings.js +6 -0
  42. package/dist/decorators/default.d.ts +2 -0
  43. package/dist/decorators/default.js +2 -0
  44. package/dist/decorators/encryption.d.ts +7 -1
  45. package/dist/decorators/encryption.js +7 -1
  46. package/dist/decorators/engine.d.ts +4 -0
  47. package/dist/decorators/engine.js +4 -0
  48. package/dist/decorators/fk-constraints.d.ts +32 -32
  49. package/dist/decorators/fk-constraints.js +32 -32
  50. package/dist/decorators/foreign-table.d.ts +1 -1
  51. package/dist/decorators/generated.d.ts +8 -0
  52. package/dist/decorators/generated.js +8 -0
  53. package/dist/decorators/hstore.d.ts +6 -0
  54. package/dist/decorators/hstore.js +6 -0
  55. package/dist/decorators/index.d.ts +2 -0
  56. package/dist/decorators/index.js +11 -1
  57. package/dist/decorators/json-column.d.ts +2 -0
  58. package/dist/decorators/json-column.js +2 -0
  59. package/dist/decorators/jsonb.d.ts +6 -0
  60. package/dist/decorators/jsonb.js +6 -0
  61. package/dist/decorators/permissions.d.ts +12 -0
  62. package/dist/decorators/permissions.js +12 -0
  63. package/dist/decorators/procedure.d.ts +4 -2
  64. package/dist/decorators/procedure.js +4 -2
  65. package/dist/decorators/query-options.d.ts +24 -0
  66. package/dist/decorators/query-options.js +24 -0
  67. package/dist/decorators/range.d.ts +8 -0
  68. package/dist/decorators/range.js +8 -0
  69. package/dist/decorators/set-column.d.ts +2 -0
  70. package/dist/decorators/set-column.js +2 -0
  71. package/dist/decorators/spatial.d.ts +2 -0
  72. package/dist/decorators/spatial.js +2 -0
  73. package/dist/decorators/storage.d.ts +24 -0
  74. package/dist/decorators/storage.js +24 -0
  75. package/dist/decorators/timezone.d.ts +7 -7
  76. package/dist/decorators/timezone.js +7 -7
  77. package/dist/decorators/trigger.d.ts +3 -1
  78. package/dist/decorators/trigger.js +3 -1
  79. package/dist/decorators/uuid.d.ts +6 -0
  80. package/dist/decorators/uuid.js +6 -0
  81. package/dist/decorators/view.d.ts +7 -1
  82. package/dist/decorators/view.js +7 -1
  83. package/dist/diagrams/chen-diagram.d.ts +15 -12
  84. package/dist/diagrams/chen-diagram.js +76 -85
  85. package/dist/diagrams/class-diagram.d.ts +9 -8
  86. package/dist/diagrams/class-diagram.js +60 -82
  87. package/dist/diagrams/core/index.d.ts +13 -0
  88. package/dist/diagrams/core/index.js +33 -0
  89. package/dist/diagrams/core/layout.d.ts +104 -0
  90. package/dist/diagrams/core/layout.js +223 -0
  91. package/dist/diagrams/{svg-dom.d.ts → core/svg.d.ts} +8 -20
  92. package/dist/diagrams/{svg-dom.js → core/svg.js} +21 -29
  93. package/dist/diagrams/core/theme.d.ts +84 -0
  94. package/dist/diagrams/core/theme.js +62 -0
  95. package/dist/diagrams/dependency-diagram.d.ts +15 -14
  96. package/dist/diagrams/dependency-diagram.js +71 -105
  97. package/dist/diagrams/er-diagram.d.ts +13 -26
  98. package/dist/diagrams/er-diagram.js +180 -259
  99. package/dist/diagrams/flow-diagram.d.ts +16 -11
  100. package/dist/diagrams/flow-diagram.js +96 -91
  101. package/dist/diagrams/gantt-diagram.d.ts +10 -5
  102. package/dist/diagrams/gantt-diagram.js +77 -103
  103. package/dist/diagrams/index-diagram.d.ts +10 -10
  104. package/dist/diagrams/index-diagram.js +106 -116
  105. package/dist/diagrams/index.d.ts +6 -9
  106. package/dist/diagrams/index.js +9 -24
  107. package/dist/diagrams/migration-diagram.d.ts +8 -4
  108. package/dist/diagrams/migration-diagram.js +189 -161
  109. package/dist/diagrams/model-diagram.d.ts +34 -34
  110. package/dist/diagrams/model-diagram.js +106 -485
  111. package/dist/diagrams/package-diagram.d.ts +9 -6
  112. package/dist/diagrams/package-diagram.js +64 -101
  113. package/dist/diagrams/relational-diagram.d.ts +12 -10
  114. package/dist/diagrams/relational-diagram.js +87 -114
  115. package/dist/diagrams/schemadoc-diagram.d.ts +8 -8
  116. package/dist/diagrams/schemadoc-diagram.js +71 -93
  117. package/dist/diagrams/sequence-diagram.d.ts +10 -10
  118. package/dist/diagrams/sequence-diagram.js +64 -89
  119. package/dist/diagrams/state-diagram.d.ts +10 -9
  120. package/dist/diagrams/state-diagram.js +69 -92
  121. package/dist/diagrams/tree-diagram.d.ts +11 -5
  122. package/dist/diagrams/tree-diagram.js +41 -65
  123. package/dist/dialects/clickhouse/index.js +15 -0
  124. package/dist/dialects/cockroachdb/index.d.ts +1 -1
  125. package/dist/dialects/cockroachdb/index.js +32 -63
  126. package/dist/dialects/db2/index.js +23 -8
  127. package/dist/dialects/dialect.d.ts +141 -5
  128. package/dist/dialects/duckdb/index.js +9 -2
  129. package/dist/dialects/hana/index.js +22 -5
  130. package/dist/dialects/lock-clause-helper.d.ts +167 -0
  131. package/dist/dialects/lock-clause-helper.js +316 -0
  132. package/dist/dialects/mariadb/index.d.ts +7 -4
  133. package/dist/dialects/mariadb/index.js +36 -60
  134. package/dist/dialects/mssql/index.js +34 -3
  135. package/dist/dialects/mysql/index.d.ts +1 -1
  136. package/dist/dialects/mysql/index.js +17 -45
  137. package/dist/dialects/oracle/index.d.ts +14 -3
  138. package/dist/dialects/oracle/index.js +66 -36
  139. package/dist/dialects/order-expression-helper.d.ts +72 -0
  140. package/dist/dialects/order-expression-helper.js +154 -0
  141. package/dist/dialects/partial-index.d.ts +52 -0
  142. package/dist/dialects/partial-index.js +251 -0
  143. package/dist/dialects/postgres/index.d.ts +1 -1
  144. package/dist/dialects/postgres/index.js +43 -68
  145. package/dist/dialects/redshift/index.js +9 -2
  146. package/dist/dialects/snowflake/index.js +17 -0
  147. package/dist/dialects/spanner/index.js +7 -2
  148. package/dist/dialects/sqlite/driver.d.ts +55 -0
  149. package/dist/dialects/sqlite/driver.js +102 -0
  150. package/dist/dialects/sqlite/index.d.ts +1 -1
  151. package/dist/dialects/sqlite/index.js +49 -27
  152. package/dist/external-fields/decorator.d.ts +2 -0
  153. package/dist/external-fields/decorator.js +2 -0
  154. package/dist/graph/base-graph-dialect.d.ts +24 -3
  155. package/dist/graph/base-graph-dialect.js +43 -2
  156. package/dist/graph/dgraph/index.js +6 -0
  157. package/dist/graph/gremlin/index.d.ts +6 -0
  158. package/dist/graph/gremlin/index.js +12 -1
  159. package/dist/graph/index.d.ts +1 -1
  160. package/dist/graph/neo4j/index.d.ts +2 -0
  161. package/dist/graph/neo4j/index.js +6 -1
  162. package/dist/graph/types.d.ts +12 -1
  163. package/dist/index.d.ts +12 -3
  164. package/dist/index.js +53 -7
  165. package/dist/logging/index.d.ts +10 -0
  166. package/dist/logging/index.js +23 -0
  167. package/dist/logging/query-logging.d.ts +82 -0
  168. package/dist/logging/query-logging.js +102 -0
  169. package/dist/models/associations.d.ts +38 -0
  170. package/dist/models/associations.js +16 -0
  171. package/dist/models/decorators.d.ts +55 -19
  172. package/dist/models/decorators.js +95 -19
  173. package/dist/models/eager-load.d.ts +99 -0
  174. package/dist/models/eager-load.js +348 -5
  175. package/dist/models/indexes.d.ts +3 -2
  176. package/dist/models/indexes.js +7 -1
  177. package/dist/models/model.js +69 -43
  178. package/dist/prorm.d.ts +175 -409
  179. package/dist/prorm.js +1132 -553
  180. package/dist/query-builders/order-limit-builder.js +12 -10
  181. package/dist/query-builders/sql-compiler.d.ts +10 -3
  182. package/dist/query-builders/sql-compiler.js +14 -43
  183. package/dist/query-interface.d.ts +2 -1
  184. package/dist/schema-objects.d.ts +42 -0
  185. package/dist/schema-objects.js +28 -0
  186. package/dist/sql-constants.d.ts +44 -0
  187. package/dist/sql-constants.js +138 -1
  188. package/dist/types/index.d.ts +387 -17
  189. package/dist/types/index.js +10 -15
  190. package/dist/types/query-types.d.ts +26 -0
  191. package/dist/types/query-types.js +30 -0
  192. package/package.json +39 -8
  193. package/dist/decorators/belongs-to-many.js +0 -115
  194. package/dist/decorators/belongs-to.js +0 -115
  195. package/dist/decorators/has-many.js +0 -127
  196. package/dist/decorators/has-one.js +0 -116
  197. package/dist/diagrams/palette.d.ts +0 -138
  198. package/dist/diagrams/palette.js +0 -194
  199. package/dist/hooks/hooks-manager.d.ts +0 -189
  200. package/dist/hooks/hooks-manager.js +0 -350
  201. package/dist/hooks/index.d.ts +0 -8
  202. package/dist/hooks/index.js +0 -37
  203. /package/dist/{logging.d.ts → logging/logger.d.ts} +0 -0
  204. /package/dist/{logging.js → logging/logger.js} +0 -0
@@ -1,11 +1,12 @@
1
1
  /**
2
- * @Trigger class decorator — declare a database trigger on a model class.
2
+ * `@Trigger` class decorator — declare a database trigger on a model class.
3
3
  *
4
4
  * Stores trigger metadata using plain class properties (no reflect-metadata
5
5
  * dependency) consistent with the rest of this decorator suite.
6
6
  *
7
7
  * Example:
8
8
  *
9
+ * ```ts
9
10
  * @Trigger({
10
11
  * name: 'trg_users_audit',
11
12
  * timing: 'AFTER',
@@ -20,6 +21,7 @@
20
21
  *
21
22
  * // Generate DDL:
22
23
  * const sql = buildCreateTriggerSQL('users', triggers[0], 'mysql');
24
+ * ```
23
25
  */
24
26
  export interface TriggerOptions {
25
27
  /** The trigger name in the database. */
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  /**
3
- * @Trigger class decorator — declare a database trigger on a model class.
3
+ * `@Trigger` class decorator — declare a database trigger on a model class.
4
4
  *
5
5
  * Stores trigger metadata using plain class properties (no reflect-metadata
6
6
  * dependency) consistent with the rest of this decorator suite.
7
7
  *
8
8
  * Example:
9
9
  *
10
+ * ```ts
10
11
  * @Trigger({
11
12
  * name: 'trg_users_audit',
12
13
  * timing: 'AFTER',
@@ -21,6 +22,7 @@
21
22
  *
22
23
  * // Generate DDL:
23
24
  * const sql = buildCreateTriggerSQL('users', triggers[0], 'mysql');
25
+ * ```
24
26
  */
25
27
  Object.defineProperty(exports, "__esModule", { value: true });
26
28
  exports.Trigger = Trigger;
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * Usage:
8
8
  *
9
+ * ```ts
9
10
  * // Auto-generate UUID using gen_random_uuid() (PostgreSQL 13+)
10
11
  * @UUID()
11
12
  * id: string;
@@ -17,6 +18,7 @@
17
18
  * // With custom default
18
19
  * @UUID({ defaultValue: 'gen_random_uuid' })
19
20
  * id: string;
21
+ * ```
20
22
  */
21
23
  /**
22
24
  * Options for UUID column type
@@ -49,14 +51,18 @@ export interface UUIDMetadata {
49
51
  * @example
50
52
  * // Auto-generate UUID
51
53
  * class User extends Model {
54
+ * ```ts
52
55
  * @UUID()
53
56
  * id: string;
57
+ * ```
54
58
  * }
55
59
  *
56
60
  * // With specific default
57
61
  * class User extends Model {
62
+ * ```ts
58
63
  * @UUID({ defaultValue: 'uuid_generate_v4' })
59
64
  * id: string;
65
+ * ```
60
66
  * }
61
67
  */
62
68
  export declare function UUID(options?: UUIDDecoratorOptions): PropertyDecorator;
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * Usage:
9
9
  *
10
+ * ```ts
10
11
  * // Auto-generate UUID using gen_random_uuid() (PostgreSQL 13+)
11
12
  * @UUID()
12
13
  * id: string;
@@ -18,6 +19,7 @@
18
19
  * // With custom default
19
20
  * @UUID({ defaultValue: 'gen_random_uuid' })
20
21
  * id: string;
22
+ * ```
21
23
  */
22
24
  Object.defineProperty(exports, "__esModule", { value: true });
23
25
  exports.UUID = UUID;
@@ -37,14 +39,18 @@ const uuidMetadataMap = new Map();
37
39
  * @example
38
40
  * // Auto-generate UUID
39
41
  * class User extends Model {
42
+ * ```ts
40
43
  * @UUID()
41
44
  * id: string;
45
+ * ```
42
46
  * }
43
47
  *
44
48
  * // With specific default
45
49
  * class User extends Model {
50
+ * ```ts
46
51
  * @UUID({ defaultValue: 'uuid_generate_v4' })
47
52
  * id: string;
53
+ * ```
48
54
  * }
49
55
  */
50
56
  function UUID(options) {
@@ -1,10 +1,11 @@
1
1
  /**
2
- * @View class decorator — annotate a Model class so it maps to a database view
2
+ * `@View` class decorator — annotate a Model class so it maps to a database view
3
3
  * instead of a base table. The ORM stores the view definition and can generate
4
4
  * the CREATE VIEW DDL for you.
5
5
  *
6
6
  * Example:
7
7
  *
8
+ * ```ts
8
9
  * @View({
9
10
  * name: 'active_users_view',
10
11
  * query: `
@@ -30,6 +31,7 @@
30
31
  *
31
32
  * // Query it just like a normal model:
32
33
  * const users = await ActiveUser.findAll({ where: { name: 'Alice' } });
34
+ * ```
33
35
  */
34
36
  import type { Prorm } from '../prorm';
35
37
  export interface ViewOptions {
@@ -83,8 +85,10 @@ export declare function getViewOptions(target: Function): ViewOptions | undefine
83
85
  * - Sets the `tableName` option to the view name so findAll() etc. work correctly.
84
86
  * - Registers view metadata so the ORM can generate CREATE VIEW DDL.
85
87
  *
88
+ * ```ts
86
89
  * @View({ name: 'active_users_view', query: 'SELECT ...' })
87
90
  * class ActiveUser extends Model { ... }
91
+ * ```
88
92
  */
89
93
  export declare function View(options: ViewOptions): (target: Function) => void;
90
94
  export declare const ViewRegistry: {
@@ -166,6 +170,7 @@ export declare function getMaterializedViewOptions(target: Function): Materializ
166
170
  * - Registers materialized view metadata so the ORM can generate CREATE MATERIALIZED VIEW DDL.
167
171
  * - Adds a `refresh()` static method for refreshing the view data.
168
172
  *
173
+ * ```ts
169
174
  * @MaterializedView({
170
175
  * name: 'user_stats_view',
171
176
  * query: `
@@ -194,6 +199,7 @@ export declare function getMaterializedViewOptions(target: Function): Materializ
194
199
  * await UserStats.refresh();
195
200
  * // Or concurrently (requires unique index):
196
201
  * await UserStats.refresh({ concurrently: true });
202
+ * ```
197
203
  */
198
204
  export declare function MaterializedView(options: MaterializedViewDecoratorOptions): (target: Function) => void;
199
205
  export declare const MaterializedViewRegistry: {
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  /**
3
- * @View class decorator — annotate a Model class so it maps to a database view
3
+ * `@View` class decorator — annotate a Model class so it maps to a database view
4
4
  * instead of a base table. The ORM stores the view definition and can generate
5
5
  * the CREATE VIEW DDL for you.
6
6
  *
7
7
  * Example:
8
8
  *
9
+ * ```ts
9
10
  * @View({
10
11
  * name: 'active_users_view',
11
12
  * query: `
@@ -31,6 +32,7 @@
31
32
  *
32
33
  * // Query it just like a normal model:
33
34
  * const users = await ActiveUser.findAll({ where: { name: 'Alice' } });
35
+ * ```
34
36
  */
35
37
  Object.defineProperty(exports, "__esModule", { value: true });
36
38
  exports.MaterializedViewRegistry = exports.ViewRegistry = void 0;
@@ -54,8 +56,10 @@ function getViewOptions(target) {
54
56
  * - Sets the `tableName` option to the view name so findAll() etc. work correctly.
55
57
  * - Registers view metadata so the ORM can generate CREATE VIEW DDL.
56
58
  *
59
+ * ```ts
57
60
  * @View({ name: 'active_users_view', query: 'SELECT ...' })
58
61
  * class ActiveUser extends Model { ... }
62
+ * ```
59
63
  */
60
64
  function View(options) {
61
65
  return function (target) {
@@ -143,6 +147,7 @@ function getMaterializedViewOptions(target) {
143
147
  * - Registers materialized view metadata so the ORM can generate CREATE MATERIALIZED VIEW DDL.
144
148
  * - Adds a `refresh()` static method for refreshing the view data.
145
149
  *
150
+ * ```ts
146
151
  * @MaterializedView({
147
152
  * name: 'user_stats_view',
148
153
  * query: `
@@ -171,6 +176,7 @@ function getMaterializedViewOptions(target) {
171
176
  * await UserStats.refresh();
172
177
  * // Or concurrently (requires unique index):
173
178
  * await UserStats.refresh({ concurrently: true });
179
+ * ```
174
180
  */
175
181
  function MaterializedView(options) {
176
182
  return function (target) {
@@ -1,19 +1,16 @@
1
1
  /**
2
- * ChenDiagram renders a classic Chen-notation Entity-Relationship diagram
3
- * as SVG, built against a real DOM document (via svg-dom) rather than
4
- * concatenated markup.
2
+ * ChenDiagram - renders a classic Chen-notation Entity-Relationship diagram
3
+ * as SVG, built against a real DOM document rather than concatenated markup.
5
4
  *
6
5
  * Chen notation (distinct from crow's-foot):
7
- * - Entities rectangles (weak entities get a double border)
8
- * - Relationships diamonds placed between the two entities they connect,
9
- * with cardinality labels (1, N, M) on the connecting lines
10
- * - Attributes ellipses connected to their entity by a line; key
11
- * attributes have underlined text, multivalued get a double
12
- * ellipse, derived get a dashed ellipse.
6
+ * - Entities -> rectangles (weak entities get a double border)
7
+ * - Relationships -> diamonds placed between the two entities they connect,
8
+ * with cardinality labels (1, N, M) on the connecting lines
9
+ * - Attributes -> ellipses connected to their entity by a line; key
10
+ * attributes have underlined text, multivalued get a
11
+ * double ellipse, derived get a dashed ellipse.
13
12
  *
14
- * Options honor `theme` (light|dark canvas/text) and `color` (accent for
15
- * entities/diamonds) via resolveTheme/resolveAccent, so both flags change the
16
- * generated output. The viewBox is auto-sized to the laid-out geometry.
13
+ * The viewBox is auto-sized to the laid-out geometry.
17
14
  *
18
15
  * Usage:
19
16
  * const diag = new ChenDiagram({ entities: [...], relationships: [...] });
@@ -41,7 +38,12 @@ export interface ChenDiagramOptions {
41
38
  entities: ChenEntity[];
42
39
  relationships?: ChenRelationship[];
43
40
  title?: string;
41
+ /**
42
+ * Accepted for backward compatibility and ignored: diagrams render in a
43
+ * single monochrome theme.
44
+ */
44
45
  theme?: 'light' | 'dark';
46
+ /** Accepted for backward compatibility and ignored. */
45
47
  color?: string;
46
48
  }
47
49
  export declare class ChenDiagram {
@@ -62,6 +64,7 @@ export declare class ChenDiagram {
62
64
  private drawAttribute;
63
65
  private drawEntity;
64
66
  private drawRelationship;
67
+ private build;
65
68
  generate(): string;
66
69
  /**
67
70
  * Write the SVG to a file. Creates parent directories if needed.
@@ -1,20 +1,17 @@
1
1
  "use strict";
2
2
  /**
3
- * ChenDiagram renders a classic Chen-notation Entity-Relationship diagram
4
- * as SVG, built against a real DOM document (via svg-dom) rather than
5
- * concatenated markup.
3
+ * ChenDiagram - renders a classic Chen-notation Entity-Relationship diagram
4
+ * as SVG, built against a real DOM document rather than concatenated markup.
6
5
  *
7
6
  * Chen notation (distinct from crow's-foot):
8
- * - Entities rectangles (weak entities get a double border)
9
- * - Relationships diamonds placed between the two entities they connect,
10
- * with cardinality labels (1, N, M) on the connecting lines
11
- * - Attributes ellipses connected to their entity by a line; key
12
- * attributes have underlined text, multivalued get a double
13
- * ellipse, derived get a dashed ellipse.
7
+ * - Entities -> rectangles (weak entities get a double border)
8
+ * - Relationships -> diamonds placed between the two entities they connect,
9
+ * with cardinality labels (1, N, M) on the connecting lines
10
+ * - Attributes -> ellipses connected to their entity by a line; key
11
+ * attributes have underlined text, multivalued get a
12
+ * double ellipse, derived get a dashed ellipse.
14
13
  *
15
- * Options honor `theme` (light|dark canvas/text) and `color` (accent for
16
- * entities/diamonds) via resolveTheme/resolveAccent, so both flags change the
17
- * generated output. The viewBox is auto-sized to the laid-out geometry.
14
+ * The viewBox is auto-sized to the laid-out geometry.
18
15
  *
19
16
  * Usage:
20
17
  * const diag = new ChenDiagram({ entities: [...], relationships: [...] });
@@ -57,8 +54,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
57
54
  exports.ChenDiagram = void 0;
58
55
  const fs = __importStar(require("fs"));
59
56
  const path = __importStar(require("path"));
60
- const palette_1 = require("./palette");
61
- const svg_dom_1 = require("./svg-dom");
57
+ const svg_1 = require("./core/svg");
58
+ const theme_1 = require("./core/theme");
59
+ const layout_1 = require("./core/layout");
62
60
  class ChenDiagram {
63
61
  constructor(options) {
64
62
  this.opts = {
@@ -69,7 +67,7 @@ class ChenDiagram {
69
67
  color: options.color ?? '',
70
68
  };
71
69
  }
72
- // ── Attribute anchor positions radially around an entity center ──────────
70
+ // -- Attribute anchor positions radially around an entity center ------------
73
71
  attributePositions(center, count) {
74
72
  const D = ChenDiagram.ATTR_DIST;
75
73
  const pts = [];
@@ -86,15 +84,15 @@ class ChenDiagram {
86
84
  }
87
85
  return pts;
88
86
  }
89
- drawAttribute(svg, from, at, attr, accent, t) {
90
- // connector line entity attribute
87
+ drawAttribute(svg, from, at, attr) {
88
+ // connector line entity -> attribute
91
89
  svg.child('line', {
92
90
  x1: from.x,
93
91
  y1: from.y,
94
92
  x2: at.x,
95
93
  y2: at.y,
96
- stroke: t.textSecondary,
97
- 'stroke-width': 1.5,
94
+ stroke: theme_1.INK.line,
95
+ 'stroke-width': theme_1.STROKE.hair,
98
96
  });
99
97
  const rx = ChenDiagram.ATTR_RX;
100
98
  const ry = ChenDiagram.ATTR_RY;
@@ -108,8 +106,8 @@ class ChenDiagram {
108
106
  rx: rx + 5,
109
107
  ry: ry + 5,
110
108
  fill: 'none',
111
- stroke: accent.mid,
112
- 'stroke-width': 1.5,
109
+ stroke: theme_1.INK.line,
110
+ 'stroke-width': theme_1.STROKE.hair,
113
111
  'stroke-dasharray': strokeDash,
114
112
  });
115
113
  }
@@ -118,42 +116,40 @@ class ChenDiagram {
118
116
  cy: at.y,
119
117
  rx,
120
118
  ry,
121
- fill: t.cardBg,
122
- stroke: accent.mid,
123
- 'stroke-width': 1.6,
119
+ fill: theme_1.INK.ground,
120
+ stroke: theme_1.INK.line,
121
+ 'stroke-width': theme_1.STROKE.hair,
124
122
  'stroke-dasharray': strokeDash,
125
123
  });
126
- const label = attr.name.length > 14 ? attr.name.slice(0, 13) + '…' : attr.name;
127
124
  svg
128
125
  .child('text', {
129
126
  x: at.x,
130
127
  y: at.y + 4,
131
- 'font-family': palette_1.FONTS.body,
132
- 'font-size': 12,
128
+ 'font-family': theme_1.FONT.family,
129
+ 'font-size': theme_1.FONT.body + 1,
133
130
  'font-weight': attr.key ? 600 : 400,
134
- fill: t.textPrimary,
131
+ fill: theme_1.INK.line,
135
132
  'text-anchor': 'middle',
136
133
  // key attributes are underlined in Chen notation
137
134
  'text-decoration': attr.key ? 'underline' : undefined,
138
135
  })
139
- .text(label);
136
+ .text((0, layout_1.truncate)(attr.name, rx * 2 - 8, theme_1.FONT.body + 1));
140
137
  }
141
- drawEntity(svg, p, accent, t) {
138
+ drawEntity(svg, p) {
142
139
  const W = ChenDiagram.ENT_W;
143
140
  const H = ChenDiagram.ENT_H;
144
141
  const x = p.center.x - W / 2;
145
142
  const y = p.center.y - H / 2;
146
- // weak entities double rectangle border
143
+ // weak entities -> double rectangle border
147
144
  if (p.entity.weak) {
148
145
  svg.child('rect', {
149
146
  x: x - 5,
150
147
  y: y - 5,
151
148
  width: W + 10,
152
149
  height: H + 10,
153
- rx: 0,
154
150
  fill: 'none',
155
- stroke: accent.mid,
156
- 'stroke-width': 1.4,
151
+ stroke: theme_1.INK.line,
152
+ 'stroke-width': theme_1.STROKE.hair,
157
153
  });
158
154
  }
159
155
  svg.child('rect', {
@@ -161,45 +157,44 @@ class ChenDiagram {
161
157
  y,
162
158
  width: W,
163
159
  height: H,
164
- rx: 0,
165
- fill: accent.light,
166
- stroke: accent.mid,
167
- 'stroke-width': 1.6,
160
+ fill: theme_1.INK.wash,
161
+ stroke: theme_1.INK.line,
162
+ 'stroke-width': theme_1.STROKE.hair,
168
163
  });
169
164
  svg
170
165
  .child('text', {
171
166
  x: p.center.x,
172
167
  y: p.center.y + 5,
173
- 'font-family': palette_1.FONTS.heading,
174
- 'font-size': 17,
175
- 'font-weight': 600,
176
- fill: accent.text,
168
+ 'font-family': theme_1.FONT.family,
169
+ 'font-size': theme_1.FONT.title + 4,
170
+ 'font-weight': 'bold',
171
+ fill: theme_1.INK.line,
177
172
  'text-anchor': 'middle',
178
173
  })
179
174
  .text(p.entity.name);
180
175
  }
181
- drawRelationship(svg, rel, a, b, accent, t) {
176
+ drawRelationship(svg, rel, a, b) {
182
177
  const mid = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
183
178
  const DW = ChenDiagram.DIA_W;
184
179
  const DH = ChenDiagram.DIA_H;
185
- // connecting lines: entity-a diamond entity-b
180
+ // connecting lines: entity-a -> diamond -> entity-b
186
181
  svg.child('line', {
187
182
  x1: a.x,
188
183
  y1: a.y,
189
184
  x2: mid.x,
190
185
  y2: mid.y,
191
- stroke: palette_1.INDUSTRY.neutral[600],
192
- 'stroke-width': 1.4,
186
+ stroke: theme_1.INK.line,
187
+ 'stroke-width': theme_1.STROKE.hair,
193
188
  });
194
189
  svg.child('line', {
195
190
  x1: mid.x,
196
191
  y1: mid.y,
197
192
  x2: b.x,
198
193
  y2: b.y,
199
- stroke: palette_1.INDUSTRY.neutral[600],
200
- 'stroke-width': 1.4,
194
+ stroke: theme_1.INK.line,
195
+ 'stroke-width': theme_1.STROKE.hair,
201
196
  });
202
- // diamond (polygon) centered on mid — solid accent fill, white label
197
+ // diamond (polygon) centered on mid.
203
198
  const pts = [
204
199
  `${mid.x},${mid.y - DH / 2}`,
205
200
  `${mid.x + DW / 2},${mid.y}`,
@@ -208,18 +203,18 @@ class ChenDiagram {
208
203
  ].join(' ');
209
204
  svg.child('polygon', {
210
205
  points: pts,
211
- fill: accent.mid,
212
- stroke: accent.text,
213
- 'stroke-width': 1.4,
206
+ fill: theme_1.INK.wash,
207
+ stroke: theme_1.INK.line,
208
+ 'stroke-width': theme_1.STROKE.hair,
214
209
  });
215
210
  svg
216
211
  .child('text', {
217
212
  x: mid.x,
218
213
  y: mid.y + 5,
219
- 'font-family': palette_1.FONTS.heading,
220
- 'font-size': 14,
221
- 'font-weight': 600,
222
- fill: '#FFFFFF',
214
+ 'font-family': theme_1.FONT.family,
215
+ 'font-size': theme_1.FONT.body + 3,
216
+ 'font-weight': 'bold',
217
+ fill: theme_1.INK.line,
223
218
  'text-anchor': 'middle',
224
219
  })
225
220
  .text(rel.name);
@@ -233,10 +228,10 @@ class ChenDiagram {
233
228
  .child('text', {
234
229
  x: lx,
235
230
  y: ly,
236
- 'font-family': palette_1.FONTS.mono,
237
- 'font-size': 13,
238
- 'font-weight': 600,
239
- fill: t.textPrimary,
231
+ 'font-family': theme_1.FONT.mono,
232
+ 'font-size': theme_1.FONT.body + 2,
233
+ 'font-weight': 'bold',
234
+ fill: theme_1.INK.line,
240
235
  'text-anchor': 'middle',
241
236
  })
242
237
  .text(card);
@@ -244,15 +239,12 @@ class ChenDiagram {
244
239
  label(a, rel.fromCardinality);
245
240
  label(b, rel.toCardinality);
246
241
  }
247
- // ── Generate the full SVG string (built via a real DOM document) ──────────
248
- generate() {
249
- const { entities, relationships, title, theme, color } = this.opts;
250
- const accent = (0, palette_1.resolveAccent)(color);
251
- const t = (0, palette_1.resolveTheme)(theme);
242
+ build() {
243
+ const { entities, relationships, title } = this.opts;
252
244
  const PAD = ChenDiagram.PAD;
253
245
  const COL_GAP = ChenDiagram.COL_GAP;
254
246
  const ROW_GAP = ChenDiagram.ROW_GAP;
255
- // ── Place entities on a grid (2 per row) ────────────────────────────
247
+ // Place entities on a grid (2 per row).
256
248
  const perRow = Math.min(2, Math.max(1, entities.length));
257
249
  const originX = PAD + COL_GAP / 2;
258
250
  const originY = PAD + (title ? ChenDiagram.TITLE_H : 0) + ROW_GAP / 2;
@@ -267,7 +259,7 @@ class ChenDiagram {
267
259
  const byName = new Map();
268
260
  for (const p of placed)
269
261
  byName.set(p.entity.name, p);
270
- // ── Compute bounds (attributes extend furthest) ─────────────────────
262
+ // Compute bounds (attributes extend furthest).
271
263
  let maxX = 0;
272
264
  let maxY = 0;
273
265
  const attrTargets = [];
@@ -294,40 +286,39 @@ class ChenDiagram {
294
286
  }
295
287
  const svgW = Math.ceil(maxX + PAD);
296
288
  const svgH = Math.ceil(maxY + PAD);
297
- const doc = new svg_dom_1.SvgDocument(svgW, svgH);
289
+ const doc = new svg_1.SvgDocument(svgW, svgH);
298
290
  const svg = doc.root;
299
- // Web fonts for browser renderers.
300
- doc.style(palette_1.FONT_IMPORT);
301
- // ── Ground ──────────────────────────────────────────────────────────
302
- svg.child('rect', { width: svgW, height: svgH, fill: t.canvasBg });
303
- // ── Title ───────────────────────────────────────────────────────────
291
+ svg.child('rect', { width: svgW, height: svgH, fill: theme_1.INK.ground });
304
292
  if (title) {
305
293
  svg
306
294
  .child('text', {
307
295
  x: PAD,
308
296
  y: PAD,
309
- 'font-family': palette_1.FONTS.heading,
310
- 'font-size': 24,
311
- 'font-weight': 600,
312
- fill: t.textPrimary,
297
+ 'font-family': theme_1.FONT.family,
298
+ 'font-size': theme_1.FONT.title + 13,
299
+ 'font-weight': 'bold',
300
+ fill: theme_1.INK.line,
313
301
  })
314
302
  .text(title);
315
303
  }
316
- // ── Relationships first (so lines/diamonds sit under entities) ──────
304
+ // Relationships first, so lines/diamonds sit under entities.
317
305
  for (const rel of relationships) {
318
306
  const A = byName.get(rel.from);
319
307
  const B = byName.get(rel.to);
320
308
  if (A && B)
321
- this.drawRelationship(svg, rel, A.center, B.center, accent, t);
309
+ this.drawRelationship(svg, rel, A.center, B.center);
322
310
  }
323
- // ── Attributes (connectors + ellipses) ──────────────────────────────
311
+ // Attributes (connectors + ellipses).
324
312
  for (const target of attrTargets) {
325
- this.drawAttribute(svg, target.from, target.at, target.attr, accent, t);
313
+ this.drawAttribute(svg, target.from, target.at, target.attr);
326
314
  }
327
- // ── Entities on top ─────────────────────────────────────────────────
315
+ // Entities on top.
328
316
  for (const p of placed)
329
- this.drawEntity(svg, p, accent, t);
330
- return doc.toString('Generated by ts-prorm-orm ChenDiagram');
317
+ this.drawEntity(svg, p);
318
+ return doc;
319
+ }
320
+ generate() {
321
+ return this.build().toString('Generated by ts-prorm-orm ChenDiagram');
331
322
  }
332
323
  /**
333
324
  * Write the SVG to a file. Creates parent directories if needed.
@@ -351,6 +342,6 @@ ChenDiagram.DIA_W = 130;
351
342
  ChenDiagram.DIA_H = 74;
352
343
  ChenDiagram.ATTR_RX = 52;
353
344
  ChenDiagram.ATTR_RY = 24;
354
- ChenDiagram.ATTR_DIST = 96; // center-of-entity center-of-attribute
345
+ ChenDiagram.ATTR_DIST = 96; // center-of-entity to center-of-attribute
355
346
  ChenDiagram.COL_GAP = 300; // horizontal spacing between entity centers
356
347
  ChenDiagram.ROW_GAP = 320; // vertical spacing between entity rows
@@ -1,8 +1,8 @@
1
1
  /**
2
- * ClassDiagram renders one or more classes as UML class boxes.
2
+ * ClassDiagram - renders one or more classes as UML class boxes.
3
3
  *
4
4
  * Each class box has three compartments:
5
- * - a title bar (class name + optional «stereotype»),
5
+ * - a title bar (class name + optional <<stereotype>>),
6
6
  * - an attributes compartment (`+ name: type`, with +/-/# visibility markers),
7
7
  * - a methods compartment (`+ name(args): returnType`).
8
8
  *
@@ -11,12 +11,8 @@
11
11
  * (hollow triangle arrowhead) is drawn to its parent; when it declares plain
12
12
  * associations, a simple line connector is drawn instead.
13
13
  *
14
- * `--theme light|dark` drives canvas/box/text colors and `--color <name|hex>`
15
- * drives the accent used for title bars — both genuinely change fill/stroke
16
- * values in the generated SVG.
17
- *
18
14
  * Usage:
19
- * const diag = new ClassDiagram({ classes: [] });
15
+ * const diag = new ClassDiagram({ classes: [...] });
20
16
  * diag.save('./diagrams/classes.svg');
21
17
  * // or:
22
18
  * const svgString = diag.generate();
@@ -46,8 +42,12 @@ export interface UmlClass {
46
42
  export interface ClassDiagramOptions {
47
43
  classes: UmlClass[];
48
44
  title?: string;
45
+ /**
46
+ * Accepted for backward compatibility and ignored: diagrams render in a
47
+ * single monochrome theme.
48
+ */
49
49
  theme?: 'light' | 'dark';
50
- /** Named palette (e.g. "emerald") or a hex color string. */
50
+ /** Accepted for backward compatibility and ignored. */
51
51
  color?: string;
52
52
  /** Number of columns before wrapping. Defaults to an auto value. */
53
53
  columns?: number;
@@ -66,6 +66,7 @@ export declare class ClassDiagram {
66
66
  constructor(options: ClassDiagramOptions);
67
67
  private boxHeight;
68
68
  private layout;
69
+ private build;
69
70
  generate(): string;
70
71
  private center;
71
72
  private drawAssociation;