dyna-record 0.7.1 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -0
- package/dist/src/DynaRecord.d.ts +1 -1
- package/dist/src/DynaRecord.js +1 -1
- package/dist/src/decorators/Entity.d.ts +19 -1
- package/dist/src/decorators/Entity.d.ts.map +1 -1
- package/dist/src/decorators/Entity.js +20 -3
- package/dist/src/decorators/Table.d.ts +1 -1
- package/dist/src/decorators/Table.js +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/metadata/MetadataStorage.d.ts +14 -4
- package/dist/src/metadata/MetadataStorage.d.ts.map +1 -1
- package/dist/src/metadata/MetadataStorage.js +24 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ Note: ACID compliant according to DynamoDB [limitations](https://docs.aws.amazon
|
|
|
14
14
|
- [Installation](#installation)
|
|
15
15
|
- [Configuration](#configuration)
|
|
16
16
|
- [Defining Entities](#defining-entities)
|
|
17
|
+
- [Entity inheritance and shared base classes](#entity-inheritance-and-shared-base-classes)
|
|
17
18
|
- [Attributes](#attributes)
|
|
18
19
|
- [Relationships](#relationships)
|
|
19
20
|
- [CRUD Operations](#crud-operations)
|
|
@@ -157,6 +158,54 @@ class Course extends MyTable {
|
|
|
157
158
|
|
|
158
159
|
> **Note:** `declare readonly type` is a pure TypeScript type annotation with zero runtime impact. The ORM sets `type` to the class name automatically. The declaration simply tells TypeScript the exact literal type, enabling typed query filters and return type narrowing.
|
|
159
160
|
|
|
161
|
+
#### Entity inheritance and shared base classes
|
|
162
|
+
|
|
163
|
+
Entities do not have to extend the table class directly. The `@Entity` decorator resolves an entity's table by walking the class hierarchy until it finds a class decorated with `@Table`, so shared attributes and relationships can live in an abstract base class between the table and the concrete entities:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import {
|
|
167
|
+
Entity,
|
|
168
|
+
StringAttribute,
|
|
169
|
+
NumberAttribute,
|
|
170
|
+
BooleanAttribute
|
|
171
|
+
} from "dyna-record";
|
|
172
|
+
|
|
173
|
+
// Not decorated with @Entity — this class is never registered as an entity,
|
|
174
|
+
// never appears in table metadata, and no records of its own type exist
|
|
175
|
+
abstract class Vehicle extends MyTable {
|
|
176
|
+
@StringAttribute({ alias: "Make" })
|
|
177
|
+
public readonly make: string;
|
|
178
|
+
|
|
179
|
+
@NumberAttribute({ alias: "Year" })
|
|
180
|
+
public readonly year: number;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
@Entity
|
|
184
|
+
class Car extends Vehicle {
|
|
185
|
+
declare readonly type: "Car";
|
|
186
|
+
|
|
187
|
+
@NumberAttribute({ alias: "Doors" })
|
|
188
|
+
public readonly doors: number;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@Entity
|
|
192
|
+
class Motorcycle extends Vehicle {
|
|
193
|
+
declare readonly type: "Motorcycle";
|
|
194
|
+
|
|
195
|
+
@BooleanAttribute({ alias: "HasSidecar" })
|
|
196
|
+
public readonly hasSidecar: boolean;
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`Car` and `Motorcycle` are full entities of `MyTable`: each inherits `make` and `year` (including runtime schema validation for them), and all CRUD operations work as if the attributes were declared on the entity itself. The abstract base class is only a container for shared code — it cannot be queried or persisted.
|
|
201
|
+
|
|
202
|
+
A few things to keep in mind:
|
|
203
|
+
|
|
204
|
+
- If an entity class does not extend a class decorated with `@Table` anywhere in its hierarchy, the `@Entity` decorator throws at class definition time.
|
|
205
|
+
- Extending a **concrete** entity (e.g. `class Pickup extends Truck`) is supported at runtime, but TypeScript will not allow the subclass to narrow the inherited `type` literal (`"Pickup"` is not assignable to `"Truck"`). Prefer abstract base classes for shared attributes.
|
|
206
|
+
- There is no polymorphic querying: entities are stored and queried by their exact class name. Querying `Car` will never return `Motorcycle` records, even though they share a base class.
|
|
207
|
+
- A base class couples its subclasses to one table, since it must extend a specific table class. To share a shape across entities in different tables, use a TypeScript interface instead (each entity must still declare its own decorated attributes).
|
|
208
|
+
|
|
160
209
|
### Attributes
|
|
161
210
|
|
|
162
211
|
Use the attribute decorators below to define attributes on a model. The decorator maps class properties to DynamoDB table attributes.
|
package/dist/src/DynaRecord.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ interface DynaRecordBase {
|
|
|
10
10
|
/**
|
|
11
11
|
* Serves as an abstract base class for entities in the ORM system. It defines standard fields such as `id`, `type`, `createdAt`, and `updatedAt`, and provides static methods for CRUD operations and queries. This class encapsulates common behaviors and properties that all entities share, leveraging decorators for attribute metadata and supporting operations like finding, creating, updating, and deleting entities.
|
|
12
12
|
*
|
|
13
|
-
* Table classes should extend this class, and each entity should extend the table class
|
|
13
|
+
* Table classes should extend this class, and each entity should extend the table class — either directly or through intermediate abstract base classes that hold shared attributes
|
|
14
14
|
*
|
|
15
15
|
* Entities extending `DynaRecord` can utilize these operations to interact with their corresponding records in the database, including handling relationships between different entities.
|
|
16
16
|
* @example
|
package/dist/src/DynaRecord.js
CHANGED
|
@@ -40,7 +40,7 @@ import { createInstance, tableItemToEntity } from "./utils.js";
|
|
|
40
40
|
/**
|
|
41
41
|
* Serves as an abstract base class for entities in the ORM system. It defines standard fields such as `id`, `type`, `createdAt`, and `updatedAt`, and provides static methods for CRUD operations and queries. This class encapsulates common behaviors and properties that all entities share, leveraging decorators for attribute metadata and supporting operations like finding, creating, updating, and deleting entities.
|
|
42
42
|
*
|
|
43
|
-
* Table classes should extend this class, and each entity should extend the table class
|
|
43
|
+
* Table classes should extend this class, and each entity should extend the table class — either directly or through intermediate abstract base classes that hold shared attributes
|
|
44
44
|
*
|
|
45
45
|
* Entities extending `DynaRecord` can utilize these operations to interact with their corresponding records in the database, including handling relationships between different entities.
|
|
46
46
|
* @example
|
|
@@ -2,7 +2,7 @@ import type DynaRecord from "../DynaRecord.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* A class decorator for marking a class as an entity within the context of the ORM system. This decorator is essential for registering the class as a distinct entity in the ORM's metadata system, enabling the ORM to recognize and manage instances of this class as part of its data model. By designating classes as entities, it facilitates their integration into the ORM framework, allowing for operations such as querying, persisting, and managing relationships between entities.
|
|
4
4
|
*
|
|
5
|
-
* IMPORTANT - All entity classes
|
|
5
|
+
* IMPORTANT - All entity classes must extend a table class decorated by {@link Table}, either directly or through intermediate classes. The entity's table is resolved by walking the class hierarchy until a class decorated with {@link Table} is found, so entities can share attributes and relationships through abstract base classes. A base class that is not decorated with `Entity` is never registered as an entity itself — only the decorated subclasses are part of the table's metadata.
|
|
6
6
|
*
|
|
7
7
|
* Entities MUST declare their `type` property as a string literal matching the class name.
|
|
8
8
|
* This enables compile-time type safety for query filters and return types.
|
|
@@ -12,6 +12,7 @@ import type DynaRecord from "../DynaRecord.js";
|
|
|
12
12
|
* @param target The constructor function of the class being decorated.
|
|
13
13
|
* @param context The context in which the decorator is applied, provided by the TypeScript runtime.
|
|
14
14
|
* @returns {void} The decorator does not return a value.
|
|
15
|
+
* @throws Error if the decorated class does not extend a class decorated with {@link Table} anywhere in its class hierarchy.
|
|
15
16
|
*
|
|
16
17
|
* Usage example:
|
|
17
18
|
* ```typescript
|
|
@@ -21,6 +22,23 @@ import type DynaRecord from "../DynaRecord.js";
|
|
|
21
22
|
* // User entity implementation
|
|
22
23
|
* }
|
|
23
24
|
* ```
|
|
25
|
+
*
|
|
26
|
+
* Sharing attributes through an abstract base class:
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // Not decorated with Entity — never registered and never persisted itself
|
|
29
|
+
* abstract class Vehicle extends MyTable {
|
|
30
|
+
* @StringAttribute({ alias: "Make" })
|
|
31
|
+
* public readonly make: string;
|
|
32
|
+
* }
|
|
33
|
+
*
|
|
34
|
+
* @Entity
|
|
35
|
+
* class Car extends Vehicle {
|
|
36
|
+
* declare readonly type: "Car";
|
|
37
|
+
* // Inherits the `make` attribute from Vehicle
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* Note: extending a concrete entity (rather than an abstract base class) is supported at runtime, but TypeScript will not allow the subclass to narrow the inherited `type` literal of its parent. Prefer abstract base classes for shared attributes.
|
|
24
42
|
*/
|
|
25
43
|
declare function Entity<C extends abstract new (...args: never[]) => DynaRecord>(target: C & (string extends InstanceType<C>["type"] ? {
|
|
26
44
|
__entityTypeError: 'Entity must declare: declare readonly type: "ClassName"';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Entity.d.ts","sourceRoot":"","sources":["../../../src/decorators/Entity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C
|
|
1
|
+
{"version":3,"file":"Entity.d.ts","sourceRoot":"","sources":["../../../src/decorators/Entity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,iBAAS,MAAM,CAAC,CAAC,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,UAAU,EACrE,MAAM,EAAE,CAAC,GACP,CAAC,MAAM,SAAS,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GACnC;IACE,iBAAiB,EAAE,yDAAyD,CAAC;CAC9E,GACD,OAAO,CAAC,EACd,QAAQ,EAAE,qBAAqB,CAAC,CAAC,CAAC,GACjC,IAAI,CAEN;AAED,eAAe,MAAM,CAAC"}
|
|
@@ -2,7 +2,7 @@ import Metadata from "../metadata/index.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* A class decorator for marking a class as an entity within the context of the ORM system. This decorator is essential for registering the class as a distinct entity in the ORM's metadata system, enabling the ORM to recognize and manage instances of this class as part of its data model. By designating classes as entities, it facilitates their integration into the ORM framework, allowing for operations such as querying, persisting, and managing relationships between entities.
|
|
4
4
|
*
|
|
5
|
-
* IMPORTANT - All entity classes
|
|
5
|
+
* IMPORTANT - All entity classes must extend a table class decorated by {@link Table}, either directly or through intermediate classes. The entity's table is resolved by walking the class hierarchy until a class decorated with {@link Table} is found, so entities can share attributes and relationships through abstract base classes. A base class that is not decorated with `Entity` is never registered as an entity itself — only the decorated subclasses are part of the table's metadata.
|
|
6
6
|
*
|
|
7
7
|
* Entities MUST declare their `type` property as a string literal matching the class name.
|
|
8
8
|
* This enables compile-time type safety for query filters and return types.
|
|
@@ -12,6 +12,7 @@ import Metadata from "../metadata/index.js";
|
|
|
12
12
|
* @param target The constructor function of the class being decorated.
|
|
13
13
|
* @param context The context in which the decorator is applied, provided by the TypeScript runtime.
|
|
14
14
|
* @returns {void} The decorator does not return a value.
|
|
15
|
+
* @throws Error if the decorated class does not extend a class decorated with {@link Table} anywhere in its class hierarchy.
|
|
15
16
|
*
|
|
16
17
|
* Usage example:
|
|
17
18
|
* ```typescript
|
|
@@ -21,9 +22,25 @@ import Metadata from "../metadata/index.js";
|
|
|
21
22
|
* // User entity implementation
|
|
22
23
|
* }
|
|
23
24
|
* ```
|
|
25
|
+
*
|
|
26
|
+
* Sharing attributes through an abstract base class:
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // Not decorated with Entity — never registered and never persisted itself
|
|
29
|
+
* abstract class Vehicle extends MyTable {
|
|
30
|
+
* @StringAttribute({ alias: "Make" })
|
|
31
|
+
* public readonly make: string;
|
|
32
|
+
* }
|
|
33
|
+
*
|
|
34
|
+
* @Entity
|
|
35
|
+
* class Car extends Vehicle {
|
|
36
|
+
* declare readonly type: "Car";
|
|
37
|
+
* // Inherits the `make` attribute from Vehicle
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* Note: extending a concrete entity (rather than an abstract base class) is supported at runtime, but TypeScript will not allow the subclass to narrow the inherited `type` literal of its parent. Prefer abstract base classes for shared attributes.
|
|
24
42
|
*/
|
|
25
43
|
function Entity(target, _context) {
|
|
26
|
-
|
|
27
|
-
Metadata.addEntity(target, tableClassName);
|
|
44
|
+
Metadata.addEntity(target);
|
|
28
45
|
}
|
|
29
46
|
export default Entity;
|
|
@@ -3,7 +3,7 @@ import type DynaRecord from "../DynaRecord.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* A class decorator for defining and customizing the table metadata associated with an entity class within the ORM system. This decorator enriches the entity with additional metadata, specifying how the entity relates to the underlying database table. By providing custom table options, such as table names or schema definitions, this decorator plays a crucial role in bridging the gap between the ORM's abstract entities and their concrete database representations.
|
|
5
5
|
*
|
|
6
|
-
* IMPORTANT - All entity classes should extend a table
|
|
6
|
+
* IMPORTANT - All entity classes should extend a table, either directly or through intermediate base classes (see {@link Entity})
|
|
7
7
|
*
|
|
8
8
|
* @param props The {@link TableMetadataOptions} object containing metadata configuration for the table. This can include options like the table's name, delimiter and default field customizations.
|
|
9
9
|
* @returns A class decorator factory function that takes a target class extending `DynaRecord` and a context object provided by the TypeScript runtime. The decorator function registers the provided metadata options with the ORM's metadata system, ensuring the entity is properly configured and recognized by the ORM.
|
|
@@ -2,7 +2,7 @@ import Metadata from "../metadata/index.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* A class decorator for defining and customizing the table metadata associated with an entity class within the ORM system. This decorator enriches the entity with additional metadata, specifying how the entity relates to the underlying database table. By providing custom table options, such as table names or schema definitions, this decorator plays a crucial role in bridging the gap between the ORM's abstract entities and their concrete database representations.
|
|
4
4
|
*
|
|
5
|
-
* IMPORTANT - All entity classes should extend a table
|
|
5
|
+
* IMPORTANT - All entity classes should extend a table, either directly or through intermediate base classes (see {@link Entity})
|
|
6
6
|
*
|
|
7
7
|
* @param props The {@link TableMetadataOptions} object containing metadata configuration for the table. This can include options like the table's name, delimiter and default field customizations.
|
|
8
8
|
* @returns A class decorator factory function that takes a target class extending `DynaRecord` and a context object provided by the TypeScript runtime. The decorator function registers the provided metadata options with the ORM's metadata system, ensuring the entity is properly configured and recognized by the ORM.
|
package/dist/src/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export * from "./errors.js";
|
|
|
3
3
|
export * from "./relationships/index.js";
|
|
4
4
|
export * from "./dynamo-utils/errors.js";
|
|
5
5
|
export type { EntityAttributesOnly, EntityAttributesInstance as EntityInstance, FindByIdIncludesRes, TypedFilterParams, TypedSortKeyCondition, SKScopedFilterParams, InferQueryResults, PartitionEntityNames, ShouldNarrow, NarrowByNames, FallbackToFilterKeys, IntersectTypeWithOr } from "./operations/index.js";
|
|
6
|
-
export type { PartitionKey, SortKey, ForeignKey, NullableForeignKey, Optional } from "./types.js";
|
|
6
|
+
export type { Brand, PartitionKey, SortKey, ForeignKey, NullableForeignKey, Optional } from "./types.js";
|
|
7
7
|
export type { AttributeKind } from "./metadata/types.js";
|
|
8
8
|
export type { SerializedTableMetadata } from "./metadata/schemas.js";
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AAEzC,YAAY,EACV,oBAAoB,EACpB,wBAAwB,IAAI,cAAc,EAC1C,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,YAAY,EACZ,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACT,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AAEzC,YAAY,EACV,oBAAoB,EACpB,wBAAwB,IAAI,cAAc,EAC1C,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,KAAK,EACL,YAAY,EACZ,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACT,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -60,11 +60,13 @@ declare class MetadataStorage {
|
|
|
60
60
|
*/
|
|
61
61
|
addTable(tableClassName: string, options: TableMetadataOptions): void;
|
|
62
62
|
/**
|
|
63
|
-
* Add an entity to metadata storage
|
|
64
|
-
*
|
|
65
|
-
*
|
|
63
|
+
* Add an entity to metadata storage. The table the entity belongs to is
|
|
64
|
+
* resolved by walking the entity's class hierarchy until a class decorated
|
|
65
|
+
* with the Table decorator is found, supporting entities that extend other
|
|
66
|
+
* entities or intermediate abstract classes.
|
|
67
|
+
* @param entityClass
|
|
66
68
|
*/
|
|
67
|
-
addEntity(entityClass: EntityMetadata["EntityClass"]
|
|
69
|
+
addEntity(entityClass: EntityMetadata["EntityClass"]): void;
|
|
68
70
|
/**
|
|
69
71
|
* Adds a relationship to an Entity's metadata storage
|
|
70
72
|
* @param entityName
|
|
@@ -105,6 +107,14 @@ declare class MetadataStorage {
|
|
|
105
107
|
* Initialize metadata object
|
|
106
108
|
*/
|
|
107
109
|
private init;
|
|
110
|
+
/**
|
|
111
|
+
* Walks an entity class's hierarchy and returns the name of the first
|
|
112
|
+
* ancestor registered as a table via the Table decorator. Throws if the
|
|
113
|
+
* entity does not extend a table class anywhere in its hierarchy.
|
|
114
|
+
* @param entityClass
|
|
115
|
+
* @returns Name of the table class the entity belongs to
|
|
116
|
+
*/
|
|
117
|
+
private resolveTableClassName;
|
|
108
118
|
/**
|
|
109
119
|
* Recursively search prototype chain and return TableMetadata for an entity class if it exists
|
|
110
120
|
* @param classPrototype
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetadataStorage.d.ts","sourceRoot":"","sources":["../../../src/metadata/MetadataStorage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,cAAc,MAAM,qBAAqB,CAAC;AAEjD,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,KAAK,EACV,wBAAwB,EAExB,qBAAqB,EAErB,oBAAoB,EAEpB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,cAAM,eAAe;;IAOnB;;;;OAIG;IACI,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc;IAKpD;;;;OAIG;IACI,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa;IAKjD;;;;OAIG;IACI,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa;IAMxD;;;;OAIG;IACI,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAK/D;;;;OAIG;IACI,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,qBAAqB;IAWzE;;;OAGG;IACI,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,wBAAwB;IAYxE;;;;OAIG;IACI,wBAAwB,CAC7B,UAAU,EAAE,MAAM,GACjB,wBAAwB;IAY3B;;;;OAIG;IACI,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAI5E
|
|
1
|
+
{"version":3,"file":"MetadataStorage.d.ts","sourceRoot":"","sources":["../../../src/metadata/MetadataStorage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,cAAc,MAAM,qBAAqB,CAAC;AAEjD,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,KAAK,EACV,wBAAwB,EAExB,qBAAqB,EAErB,oBAAoB,EAEpB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,cAAM,eAAe;;IAOnB;;;;OAIG;IACI,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc;IAKpD;;;;OAIG;IACI,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa;IAKjD;;;;OAIG;IACI,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa;IAMxD;;;;OAIG;IACI,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAK/D;;;;OAIG;IACI,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,qBAAqB;IAWzE;;;OAGG;IACI,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,wBAAwB;IAYxE;;;;OAIG;IACI,wBAAwB,CAC7B,UAAU,EAAE,MAAM,GACjB,wBAAwB;IAY3B;;;;OAIG;IACI,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAI5E;;;;;;OAMG;IACI,SAAS,CAAC,WAAW,EAAE,cAAc,CAAC,aAAa,CAAC,GAAG,IAAI;IAQlE;;;;OAIG;IACI,qBAAqB,CAC1B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,oBAAoB,GAC5B,IAAI;IAQP;;;;OAIG;IACI,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAW5E;;;;OAIG;IACI,kBAAkB,CACvB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,CAAC,wBAAwB,EAAE,OAAO,CAAC,GACvD,IAAI;IAYP;;;;OAIG;IACI,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAKpE;;;;OAIG;IACI,wBAAwB,CAC7B,WAAW,EAAE,UAAU,EACvB,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,0BAA0B,CAAC,CAAC,CAAC,MAAM,CAAC,GACrE,IAAI;IAQP;;;;OAIG;IACI,mBAAmB,CACxB,WAAW,EAAE,UAAU,EACvB,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,0BAA0B,CAAC,CAAC,CAAC,MAAM,CAAC,GACrE,IAAI;IAQP;;OAEG;IACH,OAAO,CAAC,IAAI;IAUZ;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAgB7B;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;CAe/B;AAED,eAAe,eAAe,CAAC"}
|
|
@@ -103,11 +103,14 @@ class MetadataStorage {
|
|
|
103
103
|
this.#tables[tableClassName] = new TableMetadata(options);
|
|
104
104
|
}
|
|
105
105
|
/**
|
|
106
|
-
* Add an entity to metadata storage
|
|
107
|
-
*
|
|
108
|
-
*
|
|
106
|
+
* Add an entity to metadata storage. The table the entity belongs to is
|
|
107
|
+
* resolved by walking the entity's class hierarchy until a class decorated
|
|
108
|
+
* with the Table decorator is found, supporting entities that extend other
|
|
109
|
+
* entities or intermediate abstract classes.
|
|
110
|
+
* @param entityClass
|
|
109
111
|
*/
|
|
110
|
-
addEntity(entityClass
|
|
112
|
+
addEntity(entityClass) {
|
|
113
|
+
const tableClassName = this.resolveTableClassName(entityClass);
|
|
111
114
|
this.#entities[entityClass.name] = new EntityMetadata(entityClass, tableClassName);
|
|
112
115
|
}
|
|
113
116
|
/**
|
|
@@ -193,6 +196,23 @@ class MetadataStorage {
|
|
|
193
196
|
this.#initialized = true;
|
|
194
197
|
}
|
|
195
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* Walks an entity class's hierarchy and returns the name of the first
|
|
201
|
+
* ancestor registered as a table via the Table decorator. Throws if the
|
|
202
|
+
* entity does not extend a table class anywhere in its hierarchy.
|
|
203
|
+
* @param entityClass
|
|
204
|
+
* @returns Name of the table class the entity belongs to
|
|
205
|
+
*/
|
|
206
|
+
resolveTableClassName(entityClass) {
|
|
207
|
+
let current = Object.getPrototypeOf(entityClass);
|
|
208
|
+
// The constructor chain ends at Function.prototype, whose name is ""
|
|
209
|
+
while (typeof current === "function" && current.name !== "") {
|
|
210
|
+
if (current.name in this.#tables)
|
|
211
|
+
return current.name;
|
|
212
|
+
current = Object.getPrototypeOf(current);
|
|
213
|
+
}
|
|
214
|
+
throw new Error(`Entity ${entityClass.name} must extend a class decorated with @Table, either directly or through its class hierarchy`);
|
|
215
|
+
}
|
|
196
216
|
/**
|
|
197
217
|
* Recursively search prototype chain and return TableMetadata for an entity class if it exists
|
|
198
218
|
* @param classPrototype
|