dyna-record 0.0.1
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 +3 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/src/DynaRecord.d.ts +216 -0
- package/dist/src/DynaRecord.d.ts.map +1 -0
- package/dist/src/DynaRecord.js +217 -0
- package/dist/src/Logger.d.ts +42 -0
- package/dist/src/Logger.d.ts.map +1 -0
- package/dist/src/Logger.js +57 -0
- package/dist/src/decorators/Entity.d.ts +23 -0
- package/dist/src/decorators/Entity.d.ts.map +1 -0
- package/dist/src/decorators/Entity.js +32 -0
- package/dist/src/decorators/Table.d.ts +22 -0
- package/dist/src/decorators/Table.d.ts.map +1 -0
- package/dist/src/decorators/Table.js +31 -0
- package/dist/src/decorators/attributes/Attribute.d.ts +26 -0
- package/dist/src/decorators/attributes/Attribute.d.ts.map +1 -0
- package/dist/src/decorators/attributes/Attribute.js +41 -0
- package/dist/src/decorators/attributes/DateAttribute.d.ts +25 -0
- package/dist/src/decorators/attributes/DateAttribute.d.ts.map +1 -0
- package/dist/src/decorators/attributes/DateAttribute.js +43 -0
- package/dist/src/decorators/attributes/DateNullableAttribute.d.ts +26 -0
- package/dist/src/decorators/attributes/DateNullableAttribute.d.ts.map +1 -0
- package/dist/src/decorators/attributes/DateNullableAttribute.js +43 -0
- package/dist/src/decorators/attributes/ForeignKeyAttribute.d.ts +25 -0
- package/dist/src/decorators/attributes/ForeignKeyAttribute.d.ts.map +1 -0
- package/dist/src/decorators/attributes/ForeignKeyAttribute.js +40 -0
- package/dist/src/decorators/attributes/NullableAttribute.d.ts +27 -0
- package/dist/src/decorators/attributes/NullableAttribute.d.ts.map +1 -0
- package/dist/src/decorators/attributes/NullableAttribute.js +41 -0
- package/dist/src/decorators/attributes/NullableForeignKeyAttribute.d.ts +25 -0
- package/dist/src/decorators/attributes/NullableForeignKeyAttribute.d.ts.map +1 -0
- package/dist/src/decorators/attributes/NullableForeignKeyAttribute.js +40 -0
- package/dist/src/decorators/attributes/PartitionKeyAttribute.d.ts +24 -0
- package/dist/src/decorators/attributes/PartitionKeyAttribute.d.ts.map +1 -0
- package/dist/src/decorators/attributes/PartitionKeyAttribute.js +38 -0
- package/dist/src/decorators/attributes/SortKeyAttribute.d.ts +24 -0
- package/dist/src/decorators/attributes/SortKeyAttribute.d.ts.map +1 -0
- package/dist/src/decorators/attributes/SortKeyAttribute.js +38 -0
- package/dist/src/decorators/attributes/index.d.ts +10 -0
- package/dist/src/decorators/attributes/index.d.ts.map +1 -0
- package/dist/src/decorators/attributes/index.js +37 -0
- package/dist/src/decorators/attributes/serializers.d.ts +13 -0
- package/dist/src/decorators/attributes/serializers.d.ts.map +1 -0
- package/dist/src/decorators/attributes/serializers.js +19 -0
- package/dist/src/decorators/index.d.ts +6 -0
- package/dist/src/decorators/index.d.ts.map +1 -0
- package/dist/src/decorators/index.js +27 -0
- package/dist/src/decorators/relationships/BelongsTo.d.ts +34 -0
- package/dist/src/decorators/relationships/BelongsTo.d.ts.map +1 -0
- package/dist/src/decorators/relationships/BelongsTo.js +50 -0
- package/dist/src/decorators/relationships/HasAndBelongsToMany.d.ts +80 -0
- package/dist/src/decorators/relationships/HasAndBelongsToMany.d.ts.map +1 -0
- package/dist/src/decorators/relationships/HasAndBelongsToMany.js +70 -0
- package/dist/src/decorators/relationships/HasMany.d.ts +35 -0
- package/dist/src/decorators/relationships/HasMany.d.ts.map +1 -0
- package/dist/src/decorators/relationships/HasMany.js +48 -0
- package/dist/src/decorators/relationships/HasOne.d.ts +35 -0
- package/dist/src/decorators/relationships/HasOne.d.ts.map +1 -0
- package/dist/src/decorators/relationships/HasOne.js +48 -0
- package/dist/src/decorators/relationships/index.d.ts +6 -0
- package/dist/src/decorators/relationships/index.d.ts.map +1 -0
- package/dist/src/decorators/relationships/index.js +29 -0
- package/dist/src/decorators/relationships/types.d.ts +11 -0
- package/dist/src/decorators/relationships/types.d.ts.map +1 -0
- package/dist/src/decorators/relationships/types.js +2 -0
- package/dist/src/decorators/types.d.ts +30 -0
- package/dist/src/decorators/types.d.ts.map +1 -0
- package/dist/src/decorators/types.js +2 -0
- package/dist/src/dynamo-utils/DynamoClient.d.ts +34 -0
- package/dist/src/dynamo-utils/DynamoClient.d.ts.map +1 -0
- package/dist/src/dynamo-utils/DynamoClient.js +57 -0
- package/dist/src/dynamo-utils/TransactGetBuilder.d.ts +18 -0
- package/dist/src/dynamo-utils/TransactGetBuilder.d.ts.map +1 -0
- package/dist/src/dynamo-utils/TransactGetBuilder.js +32 -0
- package/dist/src/dynamo-utils/TransactWriteBuilder.d.ts +46 -0
- package/dist/src/dynamo-utils/TransactWriteBuilder.d.ts.map +1 -0
- package/dist/src/dynamo-utils/TransactWriteBuilder.js +100 -0
- package/dist/src/dynamo-utils/errors.d.ts +13 -0
- package/dist/src/dynamo-utils/errors.d.ts.map +1 -0
- package/dist/src/dynamo-utils/errors.js +17 -0
- package/dist/src/dynamo-utils/index.d.ts +8 -0
- package/dist/src/dynamo-utils/index.d.ts.map +1 -0
- package/dist/src/dynamo-utils/index.js +30 -0
- package/dist/src/dynamo-utils/types.d.ts +52 -0
- package/dist/src/dynamo-utils/types.d.ts.map +1 -0
- package/dist/src/dynamo-utils/types.js +2 -0
- package/dist/src/errors.d.ts +13 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +17 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +24 -0
- package/dist/src/metadata/AttributeMetadata.d.ts +22 -0
- package/dist/src/metadata/AttributeMetadata.d.ts.map +1 -0
- package/dist/src/metadata/AttributeMetadata.js +27 -0
- package/dist/src/metadata/EntityMetadata.d.ts +42 -0
- package/dist/src/metadata/EntityMetadata.d.ts.map +1 -0
- package/dist/src/metadata/EntityMetadata.js +49 -0
- package/dist/src/metadata/JoinTableMetadata.d.ts +23 -0
- package/dist/src/metadata/JoinTableMetadata.d.ts.map +1 -0
- package/dist/src/metadata/JoinTableMetadata.js +22 -0
- package/dist/src/metadata/MetadataStorage.d.ts +104 -0
- package/dist/src/metadata/MetadataStorage.d.ts.map +1 -0
- package/dist/src/metadata/MetadataStorage.js +194 -0
- package/dist/src/metadata/TableMetadata.d.ts +53 -0
- package/dist/src/metadata/TableMetadata.d.ts.map +1 -0
- package/dist/src/metadata/TableMetadata.js +100 -0
- package/dist/src/metadata/index.d.ts +13 -0
- package/dist/src/metadata/index.d.ts.map +1 -0
- package/dist/src/metadata/index.js +34 -0
- package/dist/src/metadata/relationship-metadata/BelongsToRelationship.d.ts +18 -0
- package/dist/src/metadata/relationship-metadata/BelongsToRelationship.d.ts.map +1 -0
- package/dist/src/metadata/relationship-metadata/BelongsToRelationship.js +26 -0
- package/dist/src/metadata/relationship-metadata/HasAndBelongsToManyRelationship.d.ts +16 -0
- package/dist/src/metadata/relationship-metadata/HasAndBelongsToManyRelationship.d.ts.map +1 -0
- package/dist/src/metadata/relationship-metadata/HasAndBelongsToManyRelationship.js +25 -0
- package/dist/src/metadata/relationship-metadata/HasManyRelationship.d.ts +18 -0
- package/dist/src/metadata/relationship-metadata/HasManyRelationship.d.ts.map +1 -0
- package/dist/src/metadata/relationship-metadata/HasManyRelationship.js +26 -0
- package/dist/src/metadata/relationship-metadata/HasOneRelationship.d.ts +17 -0
- package/dist/src/metadata/relationship-metadata/HasOneRelationship.d.ts.map +1 -0
- package/dist/src/metadata/relationship-metadata/HasOneRelationship.js +25 -0
- package/dist/src/metadata/relationship-metadata/RelationshipMetadata.d.ts +21 -0
- package/dist/src/metadata/relationship-metadata/RelationshipMetadata.d.ts.map +1 -0
- package/dist/src/metadata/relationship-metadata/RelationshipMetadata.js +18 -0
- package/dist/src/metadata/relationship-metadata/index.d.ts +7 -0
- package/dist/src/metadata/relationship-metadata/index.d.ts.map +1 -0
- package/dist/src/metadata/relationship-metadata/index.js +29 -0
- package/dist/src/metadata/relationship-metadata/types.d.ts +16 -0
- package/dist/src/metadata/relationship-metadata/types.d.ts.map +1 -0
- package/dist/src/metadata/relationship-metadata/types.js +2 -0
- package/dist/src/metadata/relationship-metadata/utils.d.ts +3 -0
- package/dist/src/metadata/relationship-metadata/utils.d.ts.map +1 -0
- package/dist/src/metadata/relationship-metadata/utils.js +25 -0
- package/dist/src/metadata/types.d.ts +90 -0
- package/dist/src/metadata/types.d.ts.map +1 -0
- package/dist/src/metadata/types.js +2 -0
- package/dist/src/metadata/utils.d.ts +42 -0
- package/dist/src/metadata/utils.d.ts.map +1 -0
- package/dist/src/metadata/utils.js +67 -0
- package/dist/src/operations/Create/Create.d.ts +39 -0
- package/dist/src/operations/Create/Create.d.ts.map +1 -0
- package/dist/src/operations/Create/Create.js +84 -0
- package/dist/src/operations/Create/index.d.ts +3 -0
- package/dist/src/operations/Create/index.d.ts.map +1 -0
- package/dist/src/operations/Create/index.js +23 -0
- package/dist/src/operations/Create/types.d.ts +7 -0
- package/dist/src/operations/Create/types.d.ts.map +1 -0
- package/dist/src/operations/Create/types.js +2 -0
- package/dist/src/operations/Delete/Delete.d.ts +74 -0
- package/dist/src/operations/Delete/Delete.d.ts.map +1 -0
- package/dist/src/operations/Delete/Delete.js +207 -0
- package/dist/src/operations/Delete/index.d.ts +2 -0
- package/dist/src/operations/Delete/index.d.ts.map +1 -0
- package/dist/src/operations/Delete/index.js +8 -0
- package/dist/src/operations/Delete/types.d.ts +7 -0
- package/dist/src/operations/Delete/types.d.ts.map +1 -0
- package/dist/src/operations/Delete/types.js +2 -0
- package/dist/src/operations/FindById/FindById.d.ts +91 -0
- package/dist/src/operations/FindById/FindById.d.ts.map +1 -0
- package/dist/src/operations/FindById/FindById.js +244 -0
- package/dist/src/operations/FindById/index.d.ts +3 -0
- package/dist/src/operations/FindById/index.d.ts.map +1 -0
- package/dist/src/operations/FindById/index.js +23 -0
- package/dist/src/operations/FindById/types.d.ts +57 -0
- package/dist/src/operations/FindById/types.d.ts.map +1 -0
- package/dist/src/operations/FindById/types.js +2 -0
- package/dist/src/operations/OperationBase.d.ts +37 -0
- package/dist/src/operations/OperationBase.d.ts.map +1 -0
- package/dist/src/operations/OperationBase.js +44 -0
- package/dist/src/operations/Query/Query.d.ts +45 -0
- package/dist/src/operations/Query/Query.d.ts.map +1 -0
- package/dist/src/operations/Query/Query.js +84 -0
- package/dist/src/operations/Query/index.d.ts +3 -0
- package/dist/src/operations/Query/index.d.ts.map +1 -0
- package/dist/src/operations/Query/index.js +23 -0
- package/dist/src/operations/Query/types.d.ts +38 -0
- package/dist/src/operations/Query/types.d.ts.map +1 -0
- package/dist/src/operations/Query/types.js +2 -0
- package/dist/src/operations/Update/Update.d.ts +48 -0
- package/dist/src/operations/Update/Update.d.ts.map +1 -0
- package/dist/src/operations/Update/Update.js +118 -0
- package/dist/src/operations/Update/index.d.ts +3 -0
- package/dist/src/operations/Update/index.d.ts.map +1 -0
- package/dist/src/operations/Update/index.js +23 -0
- package/dist/src/operations/Update/types.d.ts +32 -0
- package/dist/src/operations/Update/types.d.ts.map +1 -0
- package/dist/src/operations/Update/types.js +2 -0
- package/dist/src/operations/index.d.ts +7 -0
- package/dist/src/operations/index.d.ts.map +1 -0
- package/dist/src/operations/index.js +22 -0
- package/dist/src/operations/types.d.ts +59 -0
- package/dist/src/operations/types.d.ts.map +1 -0
- package/dist/src/operations/types.js +2 -0
- package/dist/src/operations/utils/RelationshipTransactions.d.ts +64 -0
- package/dist/src/operations/utils/RelationshipTransactions.d.ts.map +1 -0
- package/dist/src/operations/utils/RelationshipTransactions.js +125 -0
- package/dist/src/operations/utils/expressionBuilder.d.ts +9 -0
- package/dist/src/operations/utils/expressionBuilder.d.ts.map +1 -0
- package/dist/src/operations/utils/expressionBuilder.js +106 -0
- package/dist/src/operations/utils/index.d.ts +5 -0
- package/dist/src/operations/utils/index.d.ts.map +1 -0
- package/dist/src/operations/utils/index.js +25 -0
- package/dist/src/operations/utils/types.d.ts +21 -0
- package/dist/src/operations/utils/types.d.ts.map +1 -0
- package/dist/src/operations/utils/types.js +2 -0
- package/dist/src/operations/utils/utils.d.ts +19 -0
- package/dist/src/operations/utils/utils.d.ts.map +1 -0
- package/dist/src/operations/utils/utils.js +36 -0
- package/dist/src/query-utils/Filters.d.ts +10 -0
- package/dist/src/query-utils/Filters.d.ts.map +1 -0
- package/dist/src/query-utils/Filters.js +25 -0
- package/dist/src/query-utils/QueryBuilder.d.ts +90 -0
- package/dist/src/query-utils/QueryBuilder.d.ts.map +1 -0
- package/dist/src/query-utils/QueryBuilder.js +213 -0
- package/dist/src/query-utils/index.d.ts +3 -0
- package/dist/src/query-utils/index.d.ts.map +1 -0
- package/dist/src/query-utils/index.js +23 -0
- package/dist/src/query-utils/types.d.ts +89 -0
- package/dist/src/query-utils/types.d.ts.map +1 -0
- package/dist/src/query-utils/types.js +2 -0
- package/dist/src/relationships/BelongsToLink.d.ts +50 -0
- package/dist/src/relationships/BelongsToLink.d.ts.map +1 -0
- package/dist/src/relationships/BelongsToLink.js +57 -0
- package/dist/src/relationships/JoinTable.d.ts +68 -0
- package/dist/src/relationships/JoinTable.d.ts.map +1 -0
- package/dist/src/relationships/JoinTable.js +133 -0
- package/dist/src/relationships/index.d.ts +3 -0
- package/dist/src/relationships/index.d.ts.map +1 -0
- package/dist/src/relationships/index.js +10 -0
- package/dist/src/types.d.ts +73 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/utils.d.ts +89 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/utils.js +168 -0
- package/package.json +61 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type DynaRecord from "../../DynaRecord";
|
|
2
|
+
import OperationBase from "../OperationBase";
|
|
3
|
+
import type { UpdateOptions } from "./types";
|
|
4
|
+
import type { EntityClass } from "../../types";
|
|
5
|
+
/**
|
|
6
|
+
* Facilitates the operation of updating an existing entity in the database, including handling updates to its attributes and managing changes to its relationships. It will de-normalize data to support relationship links
|
|
7
|
+
*
|
|
8
|
+
* The `Update` operation supports updating entity attributes and ensures consistency in relationships, especially for "BelongsTo" relationships. It handles the complexity of managing foreign keys and associated "BelongsToLink" records, including creating new links for updated relationships and removing outdated links when necessary.
|
|
9
|
+
*
|
|
10
|
+
* @template T - The type of the entity being updated, extending `DynaRecord`.
|
|
11
|
+
*/
|
|
12
|
+
declare class Update<T extends DynaRecord> extends OperationBase<T> {
|
|
13
|
+
#private;
|
|
14
|
+
constructor(Entity: EntityClass<T>);
|
|
15
|
+
/**
|
|
16
|
+
* Update entity transactions, including transactions to create/update BelongsToLinks
|
|
17
|
+
* @param id The id of the entity being updated
|
|
18
|
+
* @param attributes Attributes on the model to update.
|
|
19
|
+
*/
|
|
20
|
+
run(id: string, attributes: UpdateOptions<T>): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Build the transaction to update the entity
|
|
23
|
+
* @param id The id of the entity being updated
|
|
24
|
+
* @param attributes Attributes on the model to update.
|
|
25
|
+
*/
|
|
26
|
+
private buildUpdateItemTransaction;
|
|
27
|
+
/**
|
|
28
|
+
* Builds the transactions to persist relationships
|
|
29
|
+
* - Creates BelongsToLinks when a foreign key changes
|
|
30
|
+
* - Removes outdated BelongsToLinks if the entity previously was associated with a different entity
|
|
31
|
+
* @param id The id of the entity being updated
|
|
32
|
+
* @param attributes Attributes on the model to update.
|
|
33
|
+
*/
|
|
34
|
+
private buildRelationshipTransactions;
|
|
35
|
+
/**
|
|
36
|
+
* When updating the foreign key of an entity, delete the BelongsToLink in the previous relationships partition
|
|
37
|
+
* @param rel
|
|
38
|
+
* @param relType
|
|
39
|
+
* @param entity
|
|
40
|
+
*/
|
|
41
|
+
private buildDeleteOldBelongsToLinkTransaction;
|
|
42
|
+
/**
|
|
43
|
+
* If updating a ForeignKey, look up the current state of the item to build transactions
|
|
44
|
+
*/
|
|
45
|
+
private getEntity;
|
|
46
|
+
}
|
|
47
|
+
export default Update;
|
|
48
|
+
//# sourceMappingURL=Update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Update.d.ts","sourceRoot":"","sources":["../../../../src/operations/Update/Update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAa/C,OAAO,aAAa,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;GAMG;AACH,cAAM,MAAM,CAAC,CAAC,SAAS,UAAU,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;;gBAK7C,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAKlC;;;;OAIG;IACU,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzE;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAkClC;;;;;;OAMG;YACW,6BAA6B;IAsB3C;;;;;OAKG;IACH,OAAO,CAAC,sCAAsC;IAyB9C;;OAEG;YACW,SAAS;CAOxB;AAED,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const dynamo_utils_1 = require("../../dynamo-utils");
|
|
7
|
+
const utils_1 = require("../../utils");
|
|
8
|
+
const utils_2 = require("../utils");
|
|
9
|
+
const OperationBase_1 = __importDefault(require("../OperationBase"));
|
|
10
|
+
/**
|
|
11
|
+
* Facilitates the operation of updating an existing entity in the database, including handling updates to its attributes and managing changes to its relationships. It will de-normalize data to support relationship links
|
|
12
|
+
*
|
|
13
|
+
* The `Update` operation supports updating entity attributes and ensures consistency in relationships, especially for "BelongsTo" relationships. It handles the complexity of managing foreign keys and associated "BelongsToLink" records, including creating new links for updated relationships and removing outdated links when necessary.
|
|
14
|
+
*
|
|
15
|
+
* @template T - The type of the entity being updated, extending `DynaRecord`.
|
|
16
|
+
*/
|
|
17
|
+
class Update extends OperationBase_1.default {
|
|
18
|
+
#transactionBuilder;
|
|
19
|
+
#entity;
|
|
20
|
+
constructor(Entity) {
|
|
21
|
+
super(Entity);
|
|
22
|
+
this.#transactionBuilder = new dynamo_utils_1.TransactWriteBuilder();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Update entity transactions, including transactions to create/update BelongsToLinks
|
|
26
|
+
* @param id The id of the entity being updated
|
|
27
|
+
* @param attributes Attributes on the model to update.
|
|
28
|
+
*/
|
|
29
|
+
async run(id, attributes) {
|
|
30
|
+
this.buildUpdateItemTransaction(id, attributes);
|
|
31
|
+
await this.buildRelationshipTransactions(id, attributes);
|
|
32
|
+
await this.#transactionBuilder.executeTransaction();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Build the transaction to update the entity
|
|
36
|
+
* @param id The id of the entity being updated
|
|
37
|
+
* @param attributes Attributes on the model to update.
|
|
38
|
+
*/
|
|
39
|
+
buildUpdateItemTransaction(id, attributes) {
|
|
40
|
+
const { name: tableName } = this.tableMetadata;
|
|
41
|
+
const pk = this.tableMetadata.partitionKeyAttribute.name;
|
|
42
|
+
const sk = this.tableMetadata.sortKeyAttribute.name;
|
|
43
|
+
const keys = {
|
|
44
|
+
[pk]: this.EntityClass.partitionKeyValue(id),
|
|
45
|
+
[sk]: this.EntityClass.name
|
|
46
|
+
};
|
|
47
|
+
const updatedAttrs = {
|
|
48
|
+
...attributes,
|
|
49
|
+
updatedAt: new Date()
|
|
50
|
+
};
|
|
51
|
+
const tableKeys = (0, utils_1.entityToTableItem)(this.EntityClass, keys);
|
|
52
|
+
const tableAttrs = (0, utils_1.entityToTableItem)(this.EntityClass, updatedAttrs);
|
|
53
|
+
const expression = (0, utils_2.expressionBuilder)(tableAttrs);
|
|
54
|
+
this.#transactionBuilder.addUpdate({
|
|
55
|
+
TableName: tableName,
|
|
56
|
+
Key: tableKeys,
|
|
57
|
+
ConditionExpression: `attribute_exists(${this.partitionKeyAlias})`, // Only update the item if it exists
|
|
58
|
+
...expression
|
|
59
|
+
}, `${this.EntityClass.name} with ID '${id}' does not exist`);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Builds the transactions to persist relationships
|
|
63
|
+
* - Creates BelongsToLinks when a foreign key changes
|
|
64
|
+
* - Removes outdated BelongsToLinks if the entity previously was associated with a different entity
|
|
65
|
+
* @param id The id of the entity being updated
|
|
66
|
+
* @param attributes Attributes on the model to update.
|
|
67
|
+
*/
|
|
68
|
+
async buildRelationshipTransactions(id, attributes) {
|
|
69
|
+
const entityData = { id, ...attributes };
|
|
70
|
+
const relationshipTransactions = new utils_2.RelationshipTransactions({
|
|
71
|
+
Entity: this.EntityClass,
|
|
72
|
+
transactionBuilder: this.#transactionBuilder,
|
|
73
|
+
belongsToHasManyCb: async (rel, entityId) => {
|
|
74
|
+
const entity = await this.getEntity(entityId);
|
|
75
|
+
this.buildDeleteOldBelongsToLinkTransaction(rel, "HasMany", entity);
|
|
76
|
+
},
|
|
77
|
+
belongsToHasOneCb: async (rel, entityId) => {
|
|
78
|
+
const entity = await this.getEntity(entityId);
|
|
79
|
+
this.buildDeleteOldBelongsToLinkTransaction(rel, "HasOne", entity);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
await relationshipTransactions.build(entityData);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* When updating the foreign key of an entity, delete the BelongsToLink in the previous relationships partition
|
|
86
|
+
* @param rel
|
|
87
|
+
* @param relType
|
|
88
|
+
* @param entity
|
|
89
|
+
*/
|
|
90
|
+
buildDeleteOldBelongsToLinkTransaction(rel, relType, entity) {
|
|
91
|
+
const { name: tableName } = this.tableMetadata;
|
|
92
|
+
const currentId = (0, utils_2.extractForeignKeyFromEntity)(rel, entity);
|
|
93
|
+
if (entity !== undefined && currentId !== undefined) {
|
|
94
|
+
const oldLinkKeys = {
|
|
95
|
+
[this.partitionKeyAlias]: rel.target.partitionKeyValue(currentId),
|
|
96
|
+
[this.sortKeyAlias]: relType === "HasMany"
|
|
97
|
+
? this.EntityClass.partitionKeyValue(entity.id)
|
|
98
|
+
: this.EntityClass.name
|
|
99
|
+
};
|
|
100
|
+
this.#transactionBuilder.addDelete({
|
|
101
|
+
TableName: tableName,
|
|
102
|
+
Key: oldLinkKeys
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* If updating a ForeignKey, look up the current state of the item to build transactions
|
|
108
|
+
*/
|
|
109
|
+
async getEntity(id) {
|
|
110
|
+
// Only get the item once per transaction
|
|
111
|
+
if (this.#entity !== undefined)
|
|
112
|
+
return this.#entity;
|
|
113
|
+
const res = (await this.EntityClass.findById(id));
|
|
114
|
+
this.#entity = res ?? undefined;
|
|
115
|
+
return this.#entity;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.default = Update;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/operations/Update/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.Update = void 0;
|
|
21
|
+
var Update_1 = require("./Update");
|
|
22
|
+
Object.defineProperty(exports, "Update", { enumerable: true, get: function () { return __importDefault(Update_1).default; } });
|
|
23
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type DynaRecord from "../../DynaRecord";
|
|
2
|
+
import type { EntityDefinedAttributes } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Extracts the keys of properties in type `T` that are explicitly allowed to be `undefined`.
|
|
5
|
+
*
|
|
6
|
+
* @typeParam T - The type whose properties are to be examined.
|
|
7
|
+
* @returns A union type of the keys of `T` that can be `undefined`.
|
|
8
|
+
*/
|
|
9
|
+
type NullableProperties<T> = {
|
|
10
|
+
[K in keyof T]: undefined extends T[K] ? K : never;
|
|
11
|
+
}[keyof T];
|
|
12
|
+
/**
|
|
13
|
+
* Transforms a type `T` by allowing `null` as an additional type for its nullable properties.
|
|
14
|
+
*
|
|
15
|
+
* @typeParam T - The type whose properties are to be transformed.
|
|
16
|
+
* @returns A new type with properties of `T` where each nullable property is also allowed to be `null`.
|
|
17
|
+
*/
|
|
18
|
+
type AllowNullForNullable<T> = {
|
|
19
|
+
[K in keyof T]: K extends NullableProperties<T> ? T[K] | null : T[K];
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Attributes of an entity to update. Not all properties are required. Setting a nullable property to null will remove the attribute from the item
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* await MockModel.update("123", {
|
|
26
|
+
* nonNullableAttr: "new val", // Sets new value
|
|
27
|
+
* nullableAttr: null // Remove the value. This will throw a compile time error if the property is not nullable
|
|
28
|
+
* })
|
|
29
|
+
*/
|
|
30
|
+
export type UpdateOptions<T extends DynaRecord> = Partial<AllowNullForNullable<EntityDefinedAttributes<T>>>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/operations/Update/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExD;;;;;GAKG;AACH,KAAK,kBAAkB,CAAC,CAAC,IAAI;KAC1B,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CACnD,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX;;;;;GAKG;AACH,KAAK,oBAAoB,CAAC,CAAC,IAAI;KAC5B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;CACrE,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,UAAU,IAAI,OAAO,CACvD,oBAAoB,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CACjD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/operations/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./FindById"), exports);
|
|
18
|
+
__exportStar(require("./Query"), exports);
|
|
19
|
+
__exportStar(require("./Update"), exports);
|
|
20
|
+
__exportStar(require("./Create"), exports);
|
|
21
|
+
__exportStar(require("./Delete"), exports);
|
|
22
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type DynaRecord from "../DynaRecord";
|
|
2
|
+
import type { ForeignKey, NullableForeignKey, Optional, PartitionKey, SortKey } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Represents the type of the partition key attribute for a given entity. It identifies the specific property of the entity that is marked as the partition key, which uniquely identifies each instance of the entity in the database.
|
|
5
|
+
*
|
|
6
|
+
* @template T - The type of the entity being examined.
|
|
7
|
+
* @returns The name of the partition key attribute as a string if one exists; otherwise, the result is `never`.
|
|
8
|
+
*/
|
|
9
|
+
export type PartitionKeyAttribute<T> = {
|
|
10
|
+
[K in keyof T]: T[K] extends PartitionKey ? K : never;
|
|
11
|
+
}[keyof T];
|
|
12
|
+
/**
|
|
13
|
+
* Represents the type of the sort key attribute for a given entity. It identifies the specific property of the entity that is marked as the sort key, used in conjunction with the partition key to provide additional sorting capability within the database.
|
|
14
|
+
*
|
|
15
|
+
* @template T - The type of the entity being examined.
|
|
16
|
+
* @returns The name of the sort key attribute as a string if one exists; otherwise, the result is `never`.
|
|
17
|
+
*/
|
|
18
|
+
export type SortKeyAttribute<T> = {
|
|
19
|
+
[K in keyof T]: T[K] extends SortKey ? K : never;
|
|
20
|
+
}[keyof T];
|
|
21
|
+
/**
|
|
22
|
+
* Identifies all properties of a given entity type `T` that are functions. This type is useful for filtering out or working with only the function fields of an entity.
|
|
23
|
+
*
|
|
24
|
+
* @template T - The type of the entity being examined.
|
|
25
|
+
* @returns The names of the function properties as strings if any exist; otherwise, the result is `never`.
|
|
26
|
+
*/
|
|
27
|
+
export type FunctionFields<T> = {
|
|
28
|
+
[K in keyof T]: T[K] extends Function ? K : never;
|
|
29
|
+
}[keyof T];
|
|
30
|
+
/**
|
|
31
|
+
* Allow ForeignKey attributes to be passes to the create method by using their inferred primitive type
|
|
32
|
+
* Ex:
|
|
33
|
+
* If ModelA has: attr1: ForeignKey
|
|
34
|
+
* This allows" ModelA.create({ attr1: "someVal" })
|
|
35
|
+
* Instead of: ModelA.create({ attr1: "someVal" as ForeignKey })
|
|
36
|
+
*/
|
|
37
|
+
export type ForeignKeyToValue<T> = {
|
|
38
|
+
[K in keyof T]: T[K] extends NullableForeignKey ? Optional<string> : T[K] extends ForeignKey ? string : T[K];
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Returns Keys of T which are HasMany, BelongsTo or HasOne relationships
|
|
42
|
+
*/
|
|
43
|
+
export type RelationshipAttributeNames<T> = {
|
|
44
|
+
[K in keyof T]: Exclude<T[K], undefined> extends DynaRecord | DynaRecord[] ? K : never;
|
|
45
|
+
}[keyof T];
|
|
46
|
+
/**
|
|
47
|
+
* Entity attributes excluding relationship attributes
|
|
48
|
+
*/
|
|
49
|
+
export type EntityAttributes<T extends DynaRecord> = Omit<T, RelationshipAttributeNames<T>>;
|
|
50
|
+
/**
|
|
51
|
+
* Attributes that are defined on the Entity using the @Attribute decorators. This excludes:
|
|
52
|
+
* - relationship attributes
|
|
53
|
+
* - partition key attribute
|
|
54
|
+
* - sort key attribute
|
|
55
|
+
* - dyna-record default attributes
|
|
56
|
+
* - Functions defined on the entity
|
|
57
|
+
*/
|
|
58
|
+
export type EntityDefinedAttributes<T extends DynaRecord> = Omit<ForeignKeyToValue<T>, keyof DynaRecord | RelationshipAttributeNames<T> | FunctionFields<T> | PartitionKeyAttribute<T> | SortKeyAttribute<T>>;
|
|
59
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/operations/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,OAAO,EACR,MAAM,UAAU,CAAC;AAElB;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI;KACpC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,YAAY,GAAG,CAAC,GAAG,KAAK;CACtD,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;KAC/B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,OAAO,GAAG,CAAC,GAAG,KAAK;CACjD,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX;;;;;GAKG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;KAE7B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,CAAC,GAAG,KAAK;CAClD,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;KAChC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,kBAAkB,GAC3C,QAAQ,CAAC,MAAM,CAAC,GAChB,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,GACrB,MAAM,GACN,CAAC,CAAC,CAAC,CAAC;CACX,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,0BAA0B,CAAC,CAAC,IAAI;KACzC,CAAC,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,SAAS,UAAU,GAAG,UAAU,EAAE,GACtE,CAAC,GACD,KAAK;CACV,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,UAAU,IAAI,IAAI,CACvD,CAAC,EACD,0BAA0B,CAAC,CAAC,CAAC,CAC9B,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,CAAC,CAAC,SAAS,UAAU,IAAI,IAAI,CAC9D,iBAAiB,CAAC,CAAC,CAAC,EAClB,MAAM,UAAU,GAChB,0BAA0B,CAAC,CAAC,CAAC,GAC7B,cAAc,CAAC,CAAC,CAAC,GACjB,qBAAqB,CAAC,CAAC,CAAC,GACxB,gBAAgB,CAAC,CAAC,CAAC,CACtB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type DynaRecord from "../../DynaRecord";
|
|
2
|
+
import type { TransactWriteBuilder } from "../../dynamo-utils";
|
|
3
|
+
import { type BelongsToRelationship } from "../../metadata";
|
|
4
|
+
import type { EntityClass } from "../../types";
|
|
5
|
+
type EntityData<T extends DynaRecord> = Pick<T, "id"> & Partial<T>;
|
|
6
|
+
interface RelationshipTransactionsProps<T extends DynaRecord> {
|
|
7
|
+
/**
|
|
8
|
+
* Entity for which relationships are being persisted
|
|
9
|
+
*/
|
|
10
|
+
readonly Entity: EntityClass<T>;
|
|
11
|
+
/**
|
|
12
|
+
* TransactionBuilder instance to add relationship transactions to
|
|
13
|
+
*/
|
|
14
|
+
readonly transactionBuilder: TransactWriteBuilder;
|
|
15
|
+
/**
|
|
16
|
+
* Optional callback to add logic to persisting BelongsTo HasMany relationships
|
|
17
|
+
* @param rel The BelongsToRelationship metadata of which the Entity BelongsTo HasMany of
|
|
18
|
+
* @param entityId The ID of the entity
|
|
19
|
+
* @returns
|
|
20
|
+
*/
|
|
21
|
+
belongsToHasManyCb?: (rel: BelongsToRelationship, entityId: string) => Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Optional callback to add logic to persisting BelongsTo HasOne relationships
|
|
24
|
+
* @param rel The BelongsToRelationship metadata of which the Entity BelongsTo HasOne of
|
|
25
|
+
* @param entityId The ID of the entity
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
28
|
+
belongsToHasOneCb?: (rel: BelongsToRelationship, entityId: string) => Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Builds transactions for persisting create/update relationships
|
|
32
|
+
* - Sets/removes ForeignKeys
|
|
33
|
+
* - Adds/removes BelongsToLinks
|
|
34
|
+
*/
|
|
35
|
+
declare class RelationshipTransactions<T extends DynaRecord> {
|
|
36
|
+
#private;
|
|
37
|
+
constructor(props: RelationshipTransactionsProps<T>);
|
|
38
|
+
build<T extends DynaRecord>(entityData: EntityData<T>): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Builds a ConditionCheck transaction that ensures the associated relationship exists
|
|
41
|
+
* @param rel
|
|
42
|
+
* @param relationshipId
|
|
43
|
+
* @returns
|
|
44
|
+
*/
|
|
45
|
+
private buildRelationshipExistsConditionTransaction;
|
|
46
|
+
/**
|
|
47
|
+
* Creates a BelongsToLink transaction item in the parents partition if the entity BelongsTo a HasOne association
|
|
48
|
+
* Adds conditional check to ensure the parent doesn't already have one of the entity being associated
|
|
49
|
+
* @param entityId Id of the entity being persisted
|
|
50
|
+
* @param rel BelongsTo relationship metadata for which the entity being persisted is a BelongsTo HasOne
|
|
51
|
+
* @param relationshipId Id of the parent entity of which the entity being persisted BelongsTo
|
|
52
|
+
*/
|
|
53
|
+
private buildBelongsToHasOne;
|
|
54
|
+
/**
|
|
55
|
+
* Creates a BelongsToLink transaction item in the parents partition if the entity BelongsTo a HasMany association
|
|
56
|
+
* @param rel BelongsTo relationship metadata for which the entity being persisted is a BelongsTo HasMany
|
|
57
|
+
* @param entityId Id of the entity being persisted
|
|
58
|
+
* @param relationshipId Id of the parent entity of which the entity being persisted BelongsTo
|
|
59
|
+
*/
|
|
60
|
+
private buildBelongsToHasMany;
|
|
61
|
+
private isNullableString;
|
|
62
|
+
}
|
|
63
|
+
export default RelationshipTransactions;
|
|
64
|
+
//# sourceMappingURL=RelationshipTransactions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RelationshipTransactions.d.ts","sourceRoot":"","sources":["../../../../src/operations/utils/RelationshipTransactions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAGV,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAiB,EAEf,KAAK,qBAAqB,EAE3B,MAAM,gBAAgB,CAAC;AAOxB,OAAO,KAAK,EAAE,WAAW,EAAY,MAAM,aAAa,CAAC;AAIzD,KAAK,UAAU,CAAC,CAAC,SAAS,UAAU,IAAI,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEnE,UAAU,6BAA6B,CAAC,CAAC,SAAS,UAAU;IAC1D;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAChC;;OAEG;IACH,QAAQ,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;IAClD;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,CACnB,GAAG,EAAE,qBAAqB,EAC1B,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAClB,GAAG,EAAE,qBAAqB,EAC1B,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB;AAED;;;;GAIG;AACH,cAAM,wBAAwB,CAAC,CAAC,SAAS,UAAU;;gBAOrC,KAAK,EAAE,6BAA6B,CAAC,CAAC,CAAC;IAUtC,KAAK,CAAC,CAAC,SAAS,UAAU,EACrC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,IAAI,CAAC;IAoChB;;;;;OAKG;IACH,OAAO,CAAC,2CAA2C;IAoBnD;;;;;;OAMG;YACW,oBAAoB;IAgClC;;;;;OAKG;YACW,qBAAqB;IAkCnC,OAAO,CAAC,gBAAgB;CAGzB;AAED,eAAe,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const metadata_1 = __importDefault(require("../../metadata"));
|
|
7
|
+
const utils_1 = require("../../metadata/utils");
|
|
8
|
+
const relationships_1 = require("../../relationships");
|
|
9
|
+
const utils_2 = require("../../utils");
|
|
10
|
+
const utils_3 = require("./utils");
|
|
11
|
+
/**
|
|
12
|
+
* Builds transactions for persisting create/update relationships
|
|
13
|
+
* - Sets/removes ForeignKeys
|
|
14
|
+
* - Adds/removes BelongsToLinks
|
|
15
|
+
*/
|
|
16
|
+
class RelationshipTransactions {
|
|
17
|
+
#props;
|
|
18
|
+
#entityMetadata;
|
|
19
|
+
#tableMetadata;
|
|
20
|
+
#partitionKeyAlias;
|
|
21
|
+
#sortKeyAlias;
|
|
22
|
+
constructor(props) {
|
|
23
|
+
this.#props = props;
|
|
24
|
+
this.#entityMetadata = metadata_1.default.getEntity(props.Entity.name);
|
|
25
|
+
this.#tableMetadata = metadata_1.default.getTable(this.#entityMetadata.tableClassName);
|
|
26
|
+
this.#partitionKeyAlias = this.#tableMetadata.partitionKeyAttribute.alias;
|
|
27
|
+
this.#sortKeyAlias = this.#tableMetadata.sortKeyAttribute.alias;
|
|
28
|
+
}
|
|
29
|
+
async build(entityData) {
|
|
30
|
+
const { relationships } = this.#entityMetadata;
|
|
31
|
+
for (const rel of Object.values(relationships)) {
|
|
32
|
+
const isBelongsTo = (0, utils_1.isBelongsToRelationship)(rel);
|
|
33
|
+
if (isBelongsTo) {
|
|
34
|
+
const relationshipId = (0, utils_3.extractForeignKeyFromEntity)(rel, entityData);
|
|
35
|
+
const isUpdatingRelationshipId = relationshipId !== undefined;
|
|
36
|
+
if (isUpdatingRelationshipId && this.isNullableString(relationshipId)) {
|
|
37
|
+
if (relationshipId !== null) {
|
|
38
|
+
this.buildRelationshipExistsConditionTransaction(rel, relationshipId);
|
|
39
|
+
}
|
|
40
|
+
const callbackParams = [rel, entityData.id, relationshipId];
|
|
41
|
+
if ((0, utils_1.doesEntityBelongToRelAsHasMany)(this.#props.Entity, rel)) {
|
|
42
|
+
await this.buildBelongsToHasMany(...callbackParams);
|
|
43
|
+
}
|
|
44
|
+
if ((0, utils_1.doesEntityBelongToRelAsHasOne)(this.#props.Entity, rel)) {
|
|
45
|
+
await this.buildBelongsToHasOne(...callbackParams);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Builds a ConditionCheck transaction that ensures the associated relationship exists
|
|
53
|
+
* @param rel
|
|
54
|
+
* @param relationshipId
|
|
55
|
+
* @returns
|
|
56
|
+
*/
|
|
57
|
+
buildRelationshipExistsConditionTransaction(rel, relationshipId) {
|
|
58
|
+
const { name: tableName } = this.#tableMetadata;
|
|
59
|
+
const errMsg = `${rel.target.name} with ID '${relationshipId}' does not exist`;
|
|
60
|
+
const conditionCheck = {
|
|
61
|
+
TableName: tableName,
|
|
62
|
+
Key: {
|
|
63
|
+
[this.#partitionKeyAlias]: rel.target.partitionKeyValue(relationshipId),
|
|
64
|
+
[this.#sortKeyAlias]: rel.target.name
|
|
65
|
+
},
|
|
66
|
+
ConditionExpression: `attribute_exists(${this.#partitionKeyAlias})`
|
|
67
|
+
};
|
|
68
|
+
this.#props.transactionBuilder.addConditionCheck(conditionCheck, errMsg);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Creates a BelongsToLink transaction item in the parents partition if the entity BelongsTo a HasOne association
|
|
72
|
+
* Adds conditional check to ensure the parent doesn't already have one of the entity being associated
|
|
73
|
+
* @param entityId Id of the entity being persisted
|
|
74
|
+
* @param rel BelongsTo relationship metadata for which the entity being persisted is a BelongsTo HasOne
|
|
75
|
+
* @param relationshipId Id of the parent entity of which the entity being persisted BelongsTo
|
|
76
|
+
*/
|
|
77
|
+
async buildBelongsToHasOne(rel, entityId, relationshipId) {
|
|
78
|
+
const { name: tableName } = this.#tableMetadata;
|
|
79
|
+
if (this.#props.belongsToHasOneCb !== undefined) {
|
|
80
|
+
await this.#props.belongsToHasOneCb(rel, entityId);
|
|
81
|
+
}
|
|
82
|
+
if (relationshipId !== null) {
|
|
83
|
+
const link = relationships_1.BelongsToLink.build(this.#props.Entity.name, entityId);
|
|
84
|
+
const keys = {
|
|
85
|
+
[this.#partitionKeyAlias]: rel.target.partitionKeyValue(relationshipId),
|
|
86
|
+
[this.#sortKeyAlias]: this.#props.Entity.name
|
|
87
|
+
};
|
|
88
|
+
const putExpression = {
|
|
89
|
+
TableName: tableName,
|
|
90
|
+
Item: { ...keys, ...(0, utils_2.entityToTableItem)(rel.target, link) },
|
|
91
|
+
ConditionExpression: `attribute_not_exists(${this.#partitionKeyAlias})` // Ensure item doesn't already exist
|
|
92
|
+
};
|
|
93
|
+
this.#props.transactionBuilder.addPut(putExpression, `${rel.target.name} with id: ${relationshipId} already has an associated ${this.#props.Entity.name}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Creates a BelongsToLink transaction item in the parents partition if the entity BelongsTo a HasMany association
|
|
98
|
+
* @param rel BelongsTo relationship metadata for which the entity being persisted is a BelongsTo HasMany
|
|
99
|
+
* @param entityId Id of the entity being persisted
|
|
100
|
+
* @param relationshipId Id of the parent entity of which the entity being persisted BelongsTo
|
|
101
|
+
*/
|
|
102
|
+
async buildBelongsToHasMany(rel, entityId, relationshipId) {
|
|
103
|
+
const { name: tableName } = this.#tableMetadata;
|
|
104
|
+
if (this.#props.belongsToHasManyCb !== undefined) {
|
|
105
|
+
await this.#props.belongsToHasManyCb(rel, entityId);
|
|
106
|
+
}
|
|
107
|
+
if (relationshipId !== null) {
|
|
108
|
+
const link = relationships_1.BelongsToLink.build(this.#props.Entity.name, entityId);
|
|
109
|
+
const keys = {
|
|
110
|
+
[this.#partitionKeyAlias]: rel.target.partitionKeyValue(relationshipId),
|
|
111
|
+
[this.#sortKeyAlias]: this.#props.Entity.partitionKeyValue(link.foreignKey)
|
|
112
|
+
};
|
|
113
|
+
const putExpression = {
|
|
114
|
+
TableName: tableName,
|
|
115
|
+
Item: { ...keys, ...(0, utils_2.entityToTableItem)(rel.target, link) },
|
|
116
|
+
ConditionExpression: `attribute_not_exists(${this.#partitionKeyAlias})` // Ensure item doesn't already exist
|
|
117
|
+
};
|
|
118
|
+
this.#props.transactionBuilder.addPut(putExpression, `${this.#props.Entity.name} with ID '${entityId}' already belongs to ${rel.target.name} with Id '${relationshipId}'`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
isNullableString(val) {
|
|
122
|
+
return typeof val === "string" || val === null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.default = RelationshipTransactions;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DynamoTableItem } from "../../types";
|
|
2
|
+
import type { UpdateExpression } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Builds a dynamo expression given the table attributes
|
|
5
|
+
* @param tableAttrs The table aliases of the entity attributes
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
8
|
+
export declare const expressionBuilder: (tableAttrs: DynamoTableItem) => UpdateExpression;
|
|
9
|
+
//# sourceMappingURL=expressionBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expressionBuilder.d.ts","sourceRoot":"","sources":["../../../../src/operations/utils/expressionBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EACV,gBAAgB,EAGjB,MAAM,SAAS,CAAC;AAUjB;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,eAChB,eAAe,KAC1B,gBAyBF,CAAC"}
|