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.
Files changed (239) hide show
  1. package/README.md +3 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +17 -0
  5. package/dist/src/DynaRecord.d.ts +216 -0
  6. package/dist/src/DynaRecord.d.ts.map +1 -0
  7. package/dist/src/DynaRecord.js +217 -0
  8. package/dist/src/Logger.d.ts +42 -0
  9. package/dist/src/Logger.d.ts.map +1 -0
  10. package/dist/src/Logger.js +57 -0
  11. package/dist/src/decorators/Entity.d.ts +23 -0
  12. package/dist/src/decorators/Entity.d.ts.map +1 -0
  13. package/dist/src/decorators/Entity.js +32 -0
  14. package/dist/src/decorators/Table.d.ts +22 -0
  15. package/dist/src/decorators/Table.d.ts.map +1 -0
  16. package/dist/src/decorators/Table.js +31 -0
  17. package/dist/src/decorators/attributes/Attribute.d.ts +26 -0
  18. package/dist/src/decorators/attributes/Attribute.d.ts.map +1 -0
  19. package/dist/src/decorators/attributes/Attribute.js +41 -0
  20. package/dist/src/decorators/attributes/DateAttribute.d.ts +25 -0
  21. package/dist/src/decorators/attributes/DateAttribute.d.ts.map +1 -0
  22. package/dist/src/decorators/attributes/DateAttribute.js +43 -0
  23. package/dist/src/decorators/attributes/DateNullableAttribute.d.ts +26 -0
  24. package/dist/src/decorators/attributes/DateNullableAttribute.d.ts.map +1 -0
  25. package/dist/src/decorators/attributes/DateNullableAttribute.js +43 -0
  26. package/dist/src/decorators/attributes/ForeignKeyAttribute.d.ts +25 -0
  27. package/dist/src/decorators/attributes/ForeignKeyAttribute.d.ts.map +1 -0
  28. package/dist/src/decorators/attributes/ForeignKeyAttribute.js +40 -0
  29. package/dist/src/decorators/attributes/NullableAttribute.d.ts +27 -0
  30. package/dist/src/decorators/attributes/NullableAttribute.d.ts.map +1 -0
  31. package/dist/src/decorators/attributes/NullableAttribute.js +41 -0
  32. package/dist/src/decorators/attributes/NullableForeignKeyAttribute.d.ts +25 -0
  33. package/dist/src/decorators/attributes/NullableForeignKeyAttribute.d.ts.map +1 -0
  34. package/dist/src/decorators/attributes/NullableForeignKeyAttribute.js +40 -0
  35. package/dist/src/decorators/attributes/PartitionKeyAttribute.d.ts +24 -0
  36. package/dist/src/decorators/attributes/PartitionKeyAttribute.d.ts.map +1 -0
  37. package/dist/src/decorators/attributes/PartitionKeyAttribute.js +38 -0
  38. package/dist/src/decorators/attributes/SortKeyAttribute.d.ts +24 -0
  39. package/dist/src/decorators/attributes/SortKeyAttribute.d.ts.map +1 -0
  40. package/dist/src/decorators/attributes/SortKeyAttribute.js +38 -0
  41. package/dist/src/decorators/attributes/index.d.ts +10 -0
  42. package/dist/src/decorators/attributes/index.d.ts.map +1 -0
  43. package/dist/src/decorators/attributes/index.js +37 -0
  44. package/dist/src/decorators/attributes/serializers.d.ts +13 -0
  45. package/dist/src/decorators/attributes/serializers.d.ts.map +1 -0
  46. package/dist/src/decorators/attributes/serializers.js +19 -0
  47. package/dist/src/decorators/index.d.ts +6 -0
  48. package/dist/src/decorators/index.d.ts.map +1 -0
  49. package/dist/src/decorators/index.js +27 -0
  50. package/dist/src/decorators/relationships/BelongsTo.d.ts +34 -0
  51. package/dist/src/decorators/relationships/BelongsTo.d.ts.map +1 -0
  52. package/dist/src/decorators/relationships/BelongsTo.js +50 -0
  53. package/dist/src/decorators/relationships/HasAndBelongsToMany.d.ts +80 -0
  54. package/dist/src/decorators/relationships/HasAndBelongsToMany.d.ts.map +1 -0
  55. package/dist/src/decorators/relationships/HasAndBelongsToMany.js +70 -0
  56. package/dist/src/decorators/relationships/HasMany.d.ts +35 -0
  57. package/dist/src/decorators/relationships/HasMany.d.ts.map +1 -0
  58. package/dist/src/decorators/relationships/HasMany.js +48 -0
  59. package/dist/src/decorators/relationships/HasOne.d.ts +35 -0
  60. package/dist/src/decorators/relationships/HasOne.d.ts.map +1 -0
  61. package/dist/src/decorators/relationships/HasOne.js +48 -0
  62. package/dist/src/decorators/relationships/index.d.ts +6 -0
  63. package/dist/src/decorators/relationships/index.d.ts.map +1 -0
  64. package/dist/src/decorators/relationships/index.js +29 -0
  65. package/dist/src/decorators/relationships/types.d.ts +11 -0
  66. package/dist/src/decorators/relationships/types.d.ts.map +1 -0
  67. package/dist/src/decorators/relationships/types.js +2 -0
  68. package/dist/src/decorators/types.d.ts +30 -0
  69. package/dist/src/decorators/types.d.ts.map +1 -0
  70. package/dist/src/decorators/types.js +2 -0
  71. package/dist/src/dynamo-utils/DynamoClient.d.ts +34 -0
  72. package/dist/src/dynamo-utils/DynamoClient.d.ts.map +1 -0
  73. package/dist/src/dynamo-utils/DynamoClient.js +57 -0
  74. package/dist/src/dynamo-utils/TransactGetBuilder.d.ts +18 -0
  75. package/dist/src/dynamo-utils/TransactGetBuilder.d.ts.map +1 -0
  76. package/dist/src/dynamo-utils/TransactGetBuilder.js +32 -0
  77. package/dist/src/dynamo-utils/TransactWriteBuilder.d.ts +46 -0
  78. package/dist/src/dynamo-utils/TransactWriteBuilder.d.ts.map +1 -0
  79. package/dist/src/dynamo-utils/TransactWriteBuilder.js +100 -0
  80. package/dist/src/dynamo-utils/errors.d.ts +13 -0
  81. package/dist/src/dynamo-utils/errors.d.ts.map +1 -0
  82. package/dist/src/dynamo-utils/errors.js +17 -0
  83. package/dist/src/dynamo-utils/index.d.ts +8 -0
  84. package/dist/src/dynamo-utils/index.d.ts.map +1 -0
  85. package/dist/src/dynamo-utils/index.js +30 -0
  86. package/dist/src/dynamo-utils/types.d.ts +52 -0
  87. package/dist/src/dynamo-utils/types.d.ts.map +1 -0
  88. package/dist/src/dynamo-utils/types.js +2 -0
  89. package/dist/src/errors.d.ts +13 -0
  90. package/dist/src/errors.d.ts.map +1 -0
  91. package/dist/src/errors.js +17 -0
  92. package/dist/src/index.d.ts +6 -0
  93. package/dist/src/index.d.ts.map +1 -0
  94. package/dist/src/index.js +24 -0
  95. package/dist/src/metadata/AttributeMetadata.d.ts +22 -0
  96. package/dist/src/metadata/AttributeMetadata.d.ts.map +1 -0
  97. package/dist/src/metadata/AttributeMetadata.js +27 -0
  98. package/dist/src/metadata/EntityMetadata.d.ts +42 -0
  99. package/dist/src/metadata/EntityMetadata.d.ts.map +1 -0
  100. package/dist/src/metadata/EntityMetadata.js +49 -0
  101. package/dist/src/metadata/JoinTableMetadata.d.ts +23 -0
  102. package/dist/src/metadata/JoinTableMetadata.d.ts.map +1 -0
  103. package/dist/src/metadata/JoinTableMetadata.js +22 -0
  104. package/dist/src/metadata/MetadataStorage.d.ts +104 -0
  105. package/dist/src/metadata/MetadataStorage.d.ts.map +1 -0
  106. package/dist/src/metadata/MetadataStorage.js +194 -0
  107. package/dist/src/metadata/TableMetadata.d.ts +53 -0
  108. package/dist/src/metadata/TableMetadata.d.ts.map +1 -0
  109. package/dist/src/metadata/TableMetadata.js +100 -0
  110. package/dist/src/metadata/index.d.ts +13 -0
  111. package/dist/src/metadata/index.d.ts.map +1 -0
  112. package/dist/src/metadata/index.js +34 -0
  113. package/dist/src/metadata/relationship-metadata/BelongsToRelationship.d.ts +18 -0
  114. package/dist/src/metadata/relationship-metadata/BelongsToRelationship.d.ts.map +1 -0
  115. package/dist/src/metadata/relationship-metadata/BelongsToRelationship.js +26 -0
  116. package/dist/src/metadata/relationship-metadata/HasAndBelongsToManyRelationship.d.ts +16 -0
  117. package/dist/src/metadata/relationship-metadata/HasAndBelongsToManyRelationship.d.ts.map +1 -0
  118. package/dist/src/metadata/relationship-metadata/HasAndBelongsToManyRelationship.js +25 -0
  119. package/dist/src/metadata/relationship-metadata/HasManyRelationship.d.ts +18 -0
  120. package/dist/src/metadata/relationship-metadata/HasManyRelationship.d.ts.map +1 -0
  121. package/dist/src/metadata/relationship-metadata/HasManyRelationship.js +26 -0
  122. package/dist/src/metadata/relationship-metadata/HasOneRelationship.d.ts +17 -0
  123. package/dist/src/metadata/relationship-metadata/HasOneRelationship.d.ts.map +1 -0
  124. package/dist/src/metadata/relationship-metadata/HasOneRelationship.js +25 -0
  125. package/dist/src/metadata/relationship-metadata/RelationshipMetadata.d.ts +21 -0
  126. package/dist/src/metadata/relationship-metadata/RelationshipMetadata.d.ts.map +1 -0
  127. package/dist/src/metadata/relationship-metadata/RelationshipMetadata.js +18 -0
  128. package/dist/src/metadata/relationship-metadata/index.d.ts +7 -0
  129. package/dist/src/metadata/relationship-metadata/index.d.ts.map +1 -0
  130. package/dist/src/metadata/relationship-metadata/index.js +29 -0
  131. package/dist/src/metadata/relationship-metadata/types.d.ts +16 -0
  132. package/dist/src/metadata/relationship-metadata/types.d.ts.map +1 -0
  133. package/dist/src/metadata/relationship-metadata/types.js +2 -0
  134. package/dist/src/metadata/relationship-metadata/utils.d.ts +3 -0
  135. package/dist/src/metadata/relationship-metadata/utils.d.ts.map +1 -0
  136. package/dist/src/metadata/relationship-metadata/utils.js +25 -0
  137. package/dist/src/metadata/types.d.ts +90 -0
  138. package/dist/src/metadata/types.d.ts.map +1 -0
  139. package/dist/src/metadata/types.js +2 -0
  140. package/dist/src/metadata/utils.d.ts +42 -0
  141. package/dist/src/metadata/utils.d.ts.map +1 -0
  142. package/dist/src/metadata/utils.js +67 -0
  143. package/dist/src/operations/Create/Create.d.ts +39 -0
  144. package/dist/src/operations/Create/Create.d.ts.map +1 -0
  145. package/dist/src/operations/Create/Create.js +84 -0
  146. package/dist/src/operations/Create/index.d.ts +3 -0
  147. package/dist/src/operations/Create/index.d.ts.map +1 -0
  148. package/dist/src/operations/Create/index.js +23 -0
  149. package/dist/src/operations/Create/types.d.ts +7 -0
  150. package/dist/src/operations/Create/types.d.ts.map +1 -0
  151. package/dist/src/operations/Create/types.js +2 -0
  152. package/dist/src/operations/Delete/Delete.d.ts +74 -0
  153. package/dist/src/operations/Delete/Delete.d.ts.map +1 -0
  154. package/dist/src/operations/Delete/Delete.js +207 -0
  155. package/dist/src/operations/Delete/index.d.ts +2 -0
  156. package/dist/src/operations/Delete/index.d.ts.map +1 -0
  157. package/dist/src/operations/Delete/index.js +8 -0
  158. package/dist/src/operations/Delete/types.d.ts +7 -0
  159. package/dist/src/operations/Delete/types.d.ts.map +1 -0
  160. package/dist/src/operations/Delete/types.js +2 -0
  161. package/dist/src/operations/FindById/FindById.d.ts +91 -0
  162. package/dist/src/operations/FindById/FindById.d.ts.map +1 -0
  163. package/dist/src/operations/FindById/FindById.js +244 -0
  164. package/dist/src/operations/FindById/index.d.ts +3 -0
  165. package/dist/src/operations/FindById/index.d.ts.map +1 -0
  166. package/dist/src/operations/FindById/index.js +23 -0
  167. package/dist/src/operations/FindById/types.d.ts +57 -0
  168. package/dist/src/operations/FindById/types.d.ts.map +1 -0
  169. package/dist/src/operations/FindById/types.js +2 -0
  170. package/dist/src/operations/OperationBase.d.ts +37 -0
  171. package/dist/src/operations/OperationBase.d.ts.map +1 -0
  172. package/dist/src/operations/OperationBase.js +44 -0
  173. package/dist/src/operations/Query/Query.d.ts +45 -0
  174. package/dist/src/operations/Query/Query.d.ts.map +1 -0
  175. package/dist/src/operations/Query/Query.js +84 -0
  176. package/dist/src/operations/Query/index.d.ts +3 -0
  177. package/dist/src/operations/Query/index.d.ts.map +1 -0
  178. package/dist/src/operations/Query/index.js +23 -0
  179. package/dist/src/operations/Query/types.d.ts +38 -0
  180. package/dist/src/operations/Query/types.d.ts.map +1 -0
  181. package/dist/src/operations/Query/types.js +2 -0
  182. package/dist/src/operations/Update/Update.d.ts +48 -0
  183. package/dist/src/operations/Update/Update.d.ts.map +1 -0
  184. package/dist/src/operations/Update/Update.js +118 -0
  185. package/dist/src/operations/Update/index.d.ts +3 -0
  186. package/dist/src/operations/Update/index.d.ts.map +1 -0
  187. package/dist/src/operations/Update/index.js +23 -0
  188. package/dist/src/operations/Update/types.d.ts +32 -0
  189. package/dist/src/operations/Update/types.d.ts.map +1 -0
  190. package/dist/src/operations/Update/types.js +2 -0
  191. package/dist/src/operations/index.d.ts +7 -0
  192. package/dist/src/operations/index.d.ts.map +1 -0
  193. package/dist/src/operations/index.js +22 -0
  194. package/dist/src/operations/types.d.ts +59 -0
  195. package/dist/src/operations/types.d.ts.map +1 -0
  196. package/dist/src/operations/types.js +2 -0
  197. package/dist/src/operations/utils/RelationshipTransactions.d.ts +64 -0
  198. package/dist/src/operations/utils/RelationshipTransactions.d.ts.map +1 -0
  199. package/dist/src/operations/utils/RelationshipTransactions.js +125 -0
  200. package/dist/src/operations/utils/expressionBuilder.d.ts +9 -0
  201. package/dist/src/operations/utils/expressionBuilder.d.ts.map +1 -0
  202. package/dist/src/operations/utils/expressionBuilder.js +106 -0
  203. package/dist/src/operations/utils/index.d.ts +5 -0
  204. package/dist/src/operations/utils/index.d.ts.map +1 -0
  205. package/dist/src/operations/utils/index.js +25 -0
  206. package/dist/src/operations/utils/types.d.ts +21 -0
  207. package/dist/src/operations/utils/types.d.ts.map +1 -0
  208. package/dist/src/operations/utils/types.js +2 -0
  209. package/dist/src/operations/utils/utils.d.ts +19 -0
  210. package/dist/src/operations/utils/utils.d.ts.map +1 -0
  211. package/dist/src/operations/utils/utils.js +36 -0
  212. package/dist/src/query-utils/Filters.d.ts +10 -0
  213. package/dist/src/query-utils/Filters.d.ts.map +1 -0
  214. package/dist/src/query-utils/Filters.js +25 -0
  215. package/dist/src/query-utils/QueryBuilder.d.ts +90 -0
  216. package/dist/src/query-utils/QueryBuilder.d.ts.map +1 -0
  217. package/dist/src/query-utils/QueryBuilder.js +213 -0
  218. package/dist/src/query-utils/index.d.ts +3 -0
  219. package/dist/src/query-utils/index.d.ts.map +1 -0
  220. package/dist/src/query-utils/index.js +23 -0
  221. package/dist/src/query-utils/types.d.ts +89 -0
  222. package/dist/src/query-utils/types.d.ts.map +1 -0
  223. package/dist/src/query-utils/types.js +2 -0
  224. package/dist/src/relationships/BelongsToLink.d.ts +50 -0
  225. package/dist/src/relationships/BelongsToLink.d.ts.map +1 -0
  226. package/dist/src/relationships/BelongsToLink.js +57 -0
  227. package/dist/src/relationships/JoinTable.d.ts +68 -0
  228. package/dist/src/relationships/JoinTable.d.ts.map +1 -0
  229. package/dist/src/relationships/JoinTable.js +133 -0
  230. package/dist/src/relationships/index.d.ts +3 -0
  231. package/dist/src/relationships/index.d.ts.map +1 -0
  232. package/dist/src/relationships/index.js +10 -0
  233. package/dist/src/types.d.ts +73 -0
  234. package/dist/src/types.d.ts.map +1 -0
  235. package/dist/src/types.js +2 -0
  236. package/dist/src/utils.d.ts +89 -0
  237. package/dist/src/utils.d.ts.map +1 -0
  238. package/dist/src/utils.js +168 -0
  239. 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,3 @@
1
+ export { default as Update } from "./Update";
2
+ export * from "./types";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ export * from "./FindById";
2
+ export * from "./Query";
3
+ export * from "./Update";
4
+ export * from "./Create";
5
+ export * from "./Delete";
6
+ export * from "./types";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -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,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -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"}