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.
- package/CHANGELOG.md +331 -1
- package/README.md +32 -24
- package/dist/compliance/data-classifier.d.ts +6 -0
- package/dist/compliance/data-classifier.js +6 -0
- package/dist/compliance/data-lineage.d.ts +4 -0
- package/dist/compliance/data-lineage.js +4 -0
- package/dist/compliance/data-masker.d.ts +4 -0
- package/dist/compliance/data-masker.js +4 -0
- package/dist/compliance/index.d.ts +4 -0
- package/dist/compliance/index.js +15 -1
- package/dist/compliance/pseudonymization.d.ts +4 -0
- package/dist/compliance/pseudonymization.js +4 -0
- package/dist/compliance/query-firewall.d.ts +9 -9
- package/dist/compliance/query-firewall.js +9 -9
- package/dist/compliance/rate-limiter.d.ts +4 -0
- package/dist/compliance/rate-limiter.js +4 -0
- package/dist/compliance/row-level-security.d.ts +2 -0
- package/dist/compliance/row-level-security.js +2 -0
- package/dist/compliance/security-decorator.d.ts +8 -0
- package/dist/compliance/security-decorator.js +8 -0
- package/dist/compliance/session-isolation.d.ts +4 -0
- package/dist/compliance/session-isolation.js +4 -0
- package/dist/compliance/worm-storage.d.ts +4 -0
- package/dist/compliance/worm-storage.js +4 -0
- 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/audit.d.ts +3 -1
- package/dist/decorators/audit.js +3 -1
- package/dist/decorators/check.d.ts +15 -15
- package/dist/decorators/check.js +15 -15
- package/dist/decorators/collate.d.ts +16 -0
- package/dist/decorators/collate.js +16 -0
- package/dist/decorators/comment.d.ts +3 -1
- package/dist/decorators/comment.js +3 -1
- package/dist/decorators/database-settings.d.ts +6 -0
- package/dist/decorators/database-settings.js +6 -0
- package/dist/decorators/default.d.ts +2 -0
- package/dist/decorators/default.js +2 -0
- package/dist/decorators/encryption.d.ts +7 -1
- package/dist/decorators/encryption.js +7 -1
- package/dist/decorators/engine.d.ts +4 -0
- package/dist/decorators/engine.js +4 -0
- package/dist/decorators/fk-constraints.d.ts +32 -32
- package/dist/decorators/fk-constraints.js +32 -32
- package/dist/decorators/foreign-table.d.ts +1 -1
- package/dist/decorators/generated.d.ts +8 -0
- package/dist/decorators/generated.js +8 -0
- package/dist/decorators/hstore.d.ts +6 -0
- package/dist/decorators/hstore.js +6 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.js +11 -1
- package/dist/decorators/json-column.d.ts +2 -0
- package/dist/decorators/json-column.js +2 -0
- package/dist/decorators/jsonb.d.ts +6 -0
- package/dist/decorators/jsonb.js +6 -0
- package/dist/decorators/permissions.d.ts +12 -0
- package/dist/decorators/permissions.js +12 -0
- package/dist/decorators/procedure.d.ts +4 -2
- package/dist/decorators/procedure.js +4 -2
- package/dist/decorators/query-options.d.ts +24 -0
- package/dist/decorators/query-options.js +24 -0
- package/dist/decorators/range.d.ts +8 -0
- package/dist/decorators/range.js +8 -0
- package/dist/decorators/set-column.d.ts +2 -0
- package/dist/decorators/set-column.js +2 -0
- package/dist/decorators/spatial.d.ts +2 -0
- package/dist/decorators/spatial.js +2 -0
- package/dist/decorators/storage.d.ts +24 -0
- package/dist/decorators/storage.js +24 -0
- package/dist/decorators/timezone.d.ts +7 -7
- package/dist/decorators/timezone.js +7 -7
- package/dist/decorators/trigger.d.ts +3 -1
- package/dist/decorators/trigger.js +3 -1
- package/dist/decorators/uuid.d.ts +6 -0
- package/dist/decorators/uuid.js +6 -0
- package/dist/decorators/view.d.ts +7 -1
- package/dist/decorators/view.js +7 -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 +141 -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/external-fields/decorator.d.ts +2 -0
- package/dist/external-fields/decorator.js +2 -0
- 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 +12 -3
- package/dist/index.js +53 -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/associations.d.ts +38 -0
- package/dist/models/associations.js +16 -0
- package/dist/models/decorators.d.ts +55 -19
- package/dist/models/decorators.js +95 -19
- 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 +1132 -553
- 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/schema-objects.d.ts +42 -0
- package/dist/schema-objects.js +28 -0
- package/dist/sql-constants.d.ts +44 -0
- package/dist/sql-constants.js +138 -1
- package/dist/types/index.d.ts +387 -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 +39 -8
- 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,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
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
|
-
*
|
|
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;
|
package/dist/decorators/uuid.js
CHANGED
|
@@ -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
|
-
*
|
|
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: {
|
package/dist/decorators/view.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
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
|
|
3
|
-
* as SVG, built against a real DOM document
|
|
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
|
|
8
|
-
* - Relationships
|
|
9
|
-
*
|
|
10
|
-
* - Attributes
|
|
11
|
-
*
|
|
12
|
-
*
|
|
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
|
-
*
|
|
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
|
|
4
|
-
* as SVG, built against a real DOM document
|
|
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
|
|
9
|
-
* - Relationships
|
|
10
|
-
*
|
|
11
|
-
* - Attributes
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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
|
-
*
|
|
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
|
|
61
|
-
const
|
|
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
|
-
//
|
|
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
|
|
90
|
-
// connector line entity
|
|
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:
|
|
97
|
-
'stroke-width':
|
|
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:
|
|
112
|
-
'stroke-width':
|
|
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:
|
|
122
|
-
stroke:
|
|
123
|
-
'stroke-width':
|
|
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':
|
|
132
|
-
'font-size':
|
|
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:
|
|
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(
|
|
136
|
+
.text((0, layout_1.truncate)(attr.name, rx * 2 - 8, theme_1.FONT.body + 1));
|
|
140
137
|
}
|
|
141
|
-
drawEntity(svg, p
|
|
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
|
|
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:
|
|
156
|
-
'stroke-width':
|
|
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
|
-
|
|
165
|
-
|
|
166
|
-
stroke:
|
|
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':
|
|
174
|
-
'font-size':
|
|
175
|
-
'font-weight':
|
|
176
|
-
fill:
|
|
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
|
|
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
|
|
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:
|
|
192
|
-
'stroke-width':
|
|
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:
|
|
200
|
-
'stroke-width':
|
|
194
|
+
stroke: theme_1.INK.line,
|
|
195
|
+
'stroke-width': theme_1.STROKE.hair,
|
|
201
196
|
});
|
|
202
|
-
// diamond (polygon) centered on mid
|
|
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:
|
|
212
|
-
stroke:
|
|
213
|
-
'stroke-width':
|
|
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':
|
|
220
|
-
'font-size':
|
|
221
|
-
'font-weight':
|
|
222
|
-
fill:
|
|
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':
|
|
237
|
-
'font-size':
|
|
238
|
-
'font-weight':
|
|
239
|
-
fill:
|
|
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
|
-
|
|
248
|
-
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
|
289
|
+
const doc = new svg_1.SvgDocument(svgW, svgH);
|
|
298
290
|
const svg = doc.root;
|
|
299
|
-
|
|
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':
|
|
310
|
-
'font-size':
|
|
311
|
-
'font-weight':
|
|
312
|
-
fill:
|
|
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
|
-
//
|
|
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
|
|
309
|
+
this.drawRelationship(svg, rel, A.center, B.center);
|
|
322
310
|
}
|
|
323
|
-
//
|
|
311
|
+
// Attributes (connectors + ellipses).
|
|
324
312
|
for (const target of attrTargets) {
|
|
325
|
-
this.drawAttribute(svg, target.from, target.at, target.attr
|
|
313
|
+
this.drawAttribute(svg, target.from, target.at, target.attr);
|
|
326
314
|
}
|
|
327
|
-
//
|
|
315
|
+
// Entities on top.
|
|
328
316
|
for (const p of placed)
|
|
329
|
-
this.drawEntity(svg, p
|
|
330
|
-
return doc
|
|
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
|
|
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
|
|
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
|
|
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
|
-
/**
|
|
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;
|