@monorise/core 0.1.2 → 0.1.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.
Files changed (69) hide show
  1. package/dist/base/utils/index.js +2 -9
  2. package/dist/base/utils/index.js.map +1 -1
  3. package/dist/core/controllers/entity/create-entity.controller.js +39 -32
  4. package/dist/core/controllers/entity/create-entity.controller.js.map +1 -1
  5. package/dist/core/controllers/entity/delete-entity.controller.js +26 -20
  6. package/dist/core/controllers/entity/delete-entity.controller.js.map +1 -1
  7. package/dist/core/controllers/entity/get-entity-by-unique-field-value.controller.js +25 -17
  8. package/dist/core/controllers/entity/get-entity-by-unique-field-value.controller.js.map +1 -1
  9. package/dist/core/controllers/entity/get-entity.controller.js +25 -17
  10. package/dist/core/controllers/entity/get-entity.controller.js.map +1 -1
  11. package/dist/core/controllers/entity/list-entities.controller.js +39 -36
  12. package/dist/core/controllers/entity/list-entities.controller.js.map +1 -1
  13. package/dist/core/controllers/entity/update-entity.controller.js +40 -33
  14. package/dist/core/controllers/entity/update-entity.controller.js.map +1 -1
  15. package/dist/core/controllers/entity/upsert-entity.controller.js +64 -59
  16. package/dist/core/controllers/entity/upsert-entity.controller.js.map +1 -1
  17. package/dist/core/controllers/mutual/create-mutual.controller.js +42 -38
  18. package/dist/core/controllers/mutual/create-mutual.controller.js.map +1 -1
  19. package/dist/core/controllers/mutual/delete-mutual.controller.js +28 -22
  20. package/dist/core/controllers/mutual/delete-mutual.controller.js.map +1 -1
  21. package/dist/core/controllers/mutual/get-mutual.controller.js +25 -17
  22. package/dist/core/controllers/mutual/get-mutual.controller.js.map +1 -1
  23. package/dist/core/controllers/mutual/list-entities-by-entity.controller.js +52 -44
  24. package/dist/core/controllers/mutual/list-entities-by-entity.controller.js.map +1 -1
  25. package/dist/core/controllers/mutual/update-mutual.controller.js +38 -32
  26. package/dist/core/controllers/mutual/update-mutual.controller.js.map +1 -1
  27. package/dist/core/controllers/tag/list-tags.controller.js +39 -31
  28. package/dist/core/controllers/tag/list-tags.controller.js.map +1 -1
  29. package/dist/core/data/DbUtils.js +23 -12
  30. package/dist/core/data/DbUtils.js.map +1 -1
  31. package/dist/core/data/Entity.js +298 -334
  32. package/dist/core/data/Entity.js.map +1 -1
  33. package/dist/core/data/EventUtils.js +35 -27
  34. package/dist/core/data/EventUtils.js.map +1 -1
  35. package/dist/core/data/Mutual.js +282 -342
  36. package/dist/core/data/Mutual.js.map +1 -1
  37. package/dist/core/data/Tag.js +225 -228
  38. package/dist/core/data/Tag.js.map +1 -1
  39. package/dist/core/data/abstract/Repository.base.js +4 -7
  40. package/dist/core/data/abstract/Repository.base.js.map +1 -1
  41. package/dist/core/errors/extendable-error.js +0 -7
  42. package/dist/core/errors/extendable-error.js.map +1 -1
  43. package/dist/core/errors/standard-error.js +0 -3
  44. package/dist/core/errors/standard-error.js.map +1 -1
  45. package/dist/core/helpers/event.js +35 -34
  46. package/dist/core/helpers/event.js.map +1 -1
  47. package/dist/core/helpers/test/test-utils.js +60 -58
  48. package/dist/core/helpers/test/test-utils.js.map +1 -1
  49. package/dist/core/index.js +0 -8
  50. package/dist/core/index.js.map +1 -1
  51. package/dist/core/processors/create-entity-processor.js +12 -3
  52. package/dist/core/processors/create-entity-processor.js.map +1 -1
  53. package/dist/core/processors/mutual-processor.js +33 -23
  54. package/dist/core/processors/mutual-processor.js.map +1 -1
  55. package/dist/core/processors/prejoin-processor.js +117 -105
  56. package/dist/core/processors/prejoin-processor.js.map +1 -1
  57. package/dist/core/processors/replication-processor.js +27 -26
  58. package/dist/core/processors/replication-processor.js.map +1 -1
  59. package/dist/core/processors/tag-processor.js +47 -35
  60. package/dist/core/processors/tag-processor.js.map +1 -1
  61. package/dist/core/services/DependencyContainer.js +0 -4
  62. package/dist/core/services/DependencyContainer.js.map +1 -1
  63. package/dist/core/services/entity-service-lifecycle.js +29 -20
  64. package/dist/core/services/entity-service-lifecycle.js.map +1 -1
  65. package/dist/core/services/entity.service.js +95 -92
  66. package/dist/core/services/entity.service.js.map +1 -1
  67. package/dist/core/services/mutual.service.js +117 -113
  68. package/dist/core/services/mutual.service.js.map +1 -1
  69. package/package.json +1 -1
@@ -1,3 +1,12 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import { ConditionalCheckFailedException, } from '@aws-sdk/client-dynamodb';
2
11
  import { marshall, unmarshall } from '@aws-sdk/util-dynamodb';
3
12
  import { ulid } from 'ulid';
@@ -5,12 +14,6 @@ import { StandardError } from '../errors/standard-error';
5
14
  import { Item } from './abstract/Item.base';
6
15
  import { Repository } from './abstract/Repository.base';
7
16
  export class Entity extends Item {
8
- entityType;
9
- entityId;
10
- data;
11
- _createdAt;
12
- _updatedAt;
13
- fullId;
14
17
  constructor(entityType, entityId, data = {}, _createdAt, _updatedAt) {
15
18
  super();
16
19
  this.entityType = entityType;
@@ -46,16 +49,15 @@ export class Entity extends Item {
46
49
  };
47
50
  }
48
51
  get createdAt() {
49
- return this._createdAt?.toISOString();
52
+ var _a;
53
+ return (_a = this._createdAt) === null || _a === void 0 ? void 0 : _a.toISOString();
50
54
  }
51
55
  get updatedAt() {
52
- return this._updatedAt?.toISOString();
56
+ var _a;
57
+ return (_a = this._updatedAt) === null || _a === void 0 ? void 0 : _a.toISOString();
53
58
  }
54
59
  toItem() {
55
- return {
56
- ...marshall(this.toJSON(), { removeUndefinedValues: true }),
57
- ...this.keys(),
58
- };
60
+ return Object.assign(Object.assign({}, marshall(this.toJSON(), { removeUndefinedValues: true })), this.keys());
59
61
  }
60
62
  toJSON() {
61
63
  return {
@@ -68,10 +70,6 @@ export class Entity extends Item {
68
70
  }
69
71
  }
70
72
  export class EntityRepository extends Repository {
71
- EntityConfig;
72
- TABLE_NAME;
73
- dynamodbClient;
74
- EmailAuthEnabledEntities;
75
73
  constructor(EntityConfig, TABLE_NAME, dynamodbClient, EmailAuthEnabledEntities) {
76
74
  super();
77
75
  this.EntityConfig = EntityConfig;
@@ -79,147 +77,154 @@ export class EntityRepository extends Repository {
79
77
  this.dynamodbClient = dynamodbClient;
80
78
  this.EmailAuthEnabledEntities = EmailAuthEnabledEntities;
81
79
  }
82
- async listEntities({ entityType, limit, // if this is not set, it will return all items
83
- between, options = {}, }) {
84
- const entity = new Entity(entityType);
85
- // when query for records that SK are between provided start and end
86
- const expression = between
87
- ? {
88
- KeyConditionExpression: '#PK = :PK and #SK between :SKStart and :SKEnd',
80
+ listEntities(_a) {
81
+ return __awaiter(this, arguments, void 0, function* ({ entityType, limit, // if this is not set, it will return all items
82
+ between, options = {}, }) {
83
+ var _b, _c, _d;
84
+ const entity = new Entity(entityType);
85
+ // when query for records that SK are between provided start and end
86
+ const expression = between
87
+ ? {
88
+ KeyConditionExpression: '#PK = :PK and #SK between :SKStart and :SKEnd',
89
+ ExpressionAttributeNames: {
90
+ '#PK': 'PK',
91
+ '#SK': 'SK',
92
+ },
93
+ ExpressionAttributeValues: {
94
+ ':PK': {
95
+ S: entity.listActionKey,
96
+ },
97
+ ':SKStart': {
98
+ S: `${entityType}#${between.start}`,
99
+ },
100
+ ':SKEnd': {
101
+ S: `${entityType}#${between.end}`,
102
+ },
103
+ },
104
+ }
105
+ : {
106
+ KeyConditionExpression: '#PK = :PK',
107
+ ExpressionAttributeNames: {
108
+ '#PK': 'PK',
109
+ },
110
+ ExpressionAttributeValues: {
111
+ ':PK': {
112
+ S: entity.listActionKey,
113
+ },
114
+ },
115
+ };
116
+ const defaultListQuery = Object.assign({ TableName: this.TABLE_NAME, Limit: limit, ScanIndexForward: false, ProjectionExpression: options === null || options === void 0 ? void 0 : options.ProjectionExpression }, expression);
117
+ let lastKey = options.lastKey;
118
+ let items = [];
119
+ let remainingCount = limit !== null && limit !== void 0 ? limit : 0;
120
+ do {
121
+ const resp = yield this.dynamodbClient.query(Object.assign(Object.assign(Object.assign({}, defaultListQuery), (remainingCount && { Limit: remainingCount })), (lastKey && {
122
+ ExclusiveStartKey: lastKey,
123
+ })));
124
+ items = items.concat((_b = resp.Items) !== null && _b !== void 0 ? _b : []);
125
+ lastKey = resp.LastEvaluatedKey;
126
+ if (limit) {
127
+ remainingCount = remainingCount - ((_d = (_c = resp.Items) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0);
128
+ }
129
+ } while (
130
+ // limit is given, haven't reach limit, and there are still items to retrieve
131
+ (limit && remainingCount && lastKey) ||
132
+ // no limit is given and there are still items to retrieve
133
+ (!limit && lastKey));
134
+ return {
135
+ items: (items || []).map((Entity.fromItem)),
136
+ totalCount: items.length,
137
+ lastKey,
138
+ };
139
+ });
140
+ }
141
+ getEntity(entityType, entityId) {
142
+ return __awaiter(this, void 0, void 0, function* () {
143
+ const entity = new Entity(entityType, entityId);
144
+ const resp = yield this.dynamodbClient.getItem({
145
+ TableName: this.TABLE_NAME,
146
+ Key: entity.keys(),
147
+ });
148
+ return Entity.fromItem(resp.Item);
149
+ });
150
+ }
151
+ getEntityByEmail(entityType, email) {
152
+ return __awaiter(this, void 0, void 0, function* () {
153
+ var _a;
154
+ const resp = yield this.dynamodbClient.query({
155
+ TableName: this.TABLE_NAME,
156
+ KeyConditionExpression: '#PK = :PK and begins_with(#SK, :SK)',
89
157
  ExpressionAttributeNames: {
90
158
  '#PK': 'PK',
91
159
  '#SK': 'SK',
92
160
  },
93
161
  ExpressionAttributeValues: {
94
- ':PK': {
95
- S: entity.listActionKey,
96
- },
97
- ':SKStart': {
98
- S: `${entityType}#${between.start}`,
99
- },
100
- ':SKEnd': {
101
- S: `${entityType}#${between.end}`,
102
- },
162
+ ':PK': { S: `EMAIL#${email}` },
163
+ ':SK': { S: entityType },
103
164
  },
104
- }
105
- : {
106
- KeyConditionExpression: '#PK = :PK',
165
+ });
166
+ return Entity.fromItem((_a = resp.Items) === null || _a === void 0 ? void 0 : _a[0]);
167
+ });
168
+ }
169
+ getEmailAvailability(entityType, email) {
170
+ return __awaiter(this, void 0, void 0, function* () {
171
+ var _a;
172
+ const resp = yield this.dynamodbClient.query({
173
+ TableName: this.TABLE_NAME,
174
+ KeyConditionExpression: '#PK = :PK and begins_with(#SK, :SK)',
107
175
  ExpressionAttributeNames: {
108
176
  '#PK': 'PK',
177
+ '#SK': 'SK',
109
178
  },
110
179
  ExpressionAttributeValues: {
111
- ':PK': {
112
- S: entity.listActionKey,
113
- },
180
+ ':PK': { S: `EMAIL#${email}` },
181
+ ':SK': { S: entityType },
114
182
  },
115
- };
116
- const defaultListQuery = {
117
- TableName: this.TABLE_NAME,
118
- Limit: limit,
119
- ScanIndexForward: false,
120
- ProjectionExpression: options?.ProjectionExpression,
121
- ...expression,
122
- };
123
- let lastKey = options.lastKey;
124
- let items = [];
125
- let remainingCount = limit ?? 0;
126
- do {
127
- const resp = await this.dynamodbClient.query({
128
- ...defaultListQuery,
129
- ...(remainingCount && { Limit: remainingCount }),
130
- ...(lastKey && {
131
- ExclusiveStartKey: lastKey,
132
- }),
133
183
  });
134
- items = items.concat(resp.Items ?? []);
135
- lastKey = resp.LastEvaluatedKey;
136
- if (limit) {
137
- remainingCount = remainingCount - (resp.Items?.length ?? 0);
184
+ if ((_a = resp.Items) === null || _a === void 0 ? void 0 : _a[0]) {
185
+ throw new StandardError('EMAIL_EXISTS', 'Email already exists');
138
186
  }
139
- } while (
140
- // limit is given, haven't reach limit, and there are still items to retrieve
141
- (limit && remainingCount && lastKey) ||
142
- // no limit is given and there are still items to retrieve
143
- (!limit && lastKey));
144
- return {
145
- items: (items || []).map((Entity.fromItem)),
146
- totalCount: items.length,
147
- lastKey,
148
- };
149
- }
150
- async getEntity(entityType, entityId) {
151
- const entity = new Entity(entityType, entityId);
152
- const resp = await this.dynamodbClient.getItem({
153
- TableName: this.TABLE_NAME,
154
- Key: entity.keys(),
187
+ return;
155
188
  });
156
- return Entity.fromItem(resp.Item);
157
189
  }
158
- async getEntityByEmail(entityType, email) {
159
- const resp = await this.dynamodbClient.query({
160
- TableName: this.TABLE_NAME,
161
- KeyConditionExpression: '#PK = :PK and begins_with(#SK, :SK)',
162
- ExpressionAttributeNames: {
163
- '#PK': 'PK',
164
- '#SK': 'SK',
165
- },
166
- ExpressionAttributeValues: {
167
- ':PK': { S: `EMAIL#${email}` },
168
- ':SK': { S: entityType },
169
- },
170
- });
171
- return Entity.fromItem(resp.Items?.[0]);
172
- }
173
- async getEmailAvailability(entityType, email) {
174
- const resp = await this.dynamodbClient.query({
175
- TableName: this.TABLE_NAME,
176
- KeyConditionExpression: '#PK = :PK and begins_with(#SK, :SK)',
177
- ExpressionAttributeNames: {
178
- '#PK': 'PK',
179
- '#SK': 'SK',
180
- },
181
- ExpressionAttributeValues: {
182
- ':PK': { S: `EMAIL#${email}` },
183
- ':SK': { S: entityType },
184
- },
185
- });
186
- if (resp.Items?.[0]) {
187
- throw new StandardError('EMAIL_EXISTS', 'Email already exists');
188
- }
189
- return;
190
- }
191
- async getEntityByUniqueField(entityType, fieldName, value) {
192
- const resp = await this.dynamodbClient.query({
193
- TableName: this.TABLE_NAME,
194
- KeyConditionExpression: '#PK = :PK and begins_with(#SK, :SK)',
195
- ExpressionAttributeNames: {
196
- '#PK': 'PK',
197
- '#SK': 'SK',
198
- },
199
- ExpressionAttributeValues: {
200
- ':PK': { S: `UNIQUE#${fieldName}#${value}` },
201
- ':SK': { S: entityType },
202
- },
190
+ getEntityByUniqueField(entityType, fieldName, value) {
191
+ return __awaiter(this, void 0, void 0, function* () {
192
+ var _a;
193
+ const resp = yield this.dynamodbClient.query({
194
+ TableName: this.TABLE_NAME,
195
+ KeyConditionExpression: '#PK = :PK and begins_with(#SK, :SK)',
196
+ ExpressionAttributeNames: {
197
+ '#PK': 'PK',
198
+ '#SK': 'SK',
199
+ },
200
+ ExpressionAttributeValues: {
201
+ ':PK': { S: `UNIQUE#${fieldName}#${value}` },
202
+ ':SK': { S: entityType },
203
+ },
204
+ });
205
+ return Entity.fromItem((_a = resp.Items) === null || _a === void 0 ? void 0 : _a[0]);
203
206
  });
204
- return Entity.fromItem(resp.Items?.[0]);
205
207
  }
206
- async getUniqueFieldValueAvailability(entityType, fieldName, value) {
207
- const resp = await this.dynamodbClient.query({
208
- TableName: this.TABLE_NAME,
209
- KeyConditionExpression: '#PK = :PK and begins_with(#SK, :SK)',
210
- ExpressionAttributeNames: {
211
- '#PK': 'PK',
212
- '#SK': 'SK',
213
- },
214
- ExpressionAttributeValues: {
215
- ':PK': { S: `UNIQUE#${fieldName}#${value}` },
216
- ':SK': { S: entityType },
217
- },
208
+ getUniqueFieldValueAvailability(entityType, fieldName, value) {
209
+ return __awaiter(this, void 0, void 0, function* () {
210
+ var _a;
211
+ const resp = yield this.dynamodbClient.query({
212
+ TableName: this.TABLE_NAME,
213
+ KeyConditionExpression: '#PK = :PK and begins_with(#SK, :SK)',
214
+ ExpressionAttributeNames: {
215
+ '#PK': 'PK',
216
+ '#SK': 'SK',
217
+ },
218
+ ExpressionAttributeValues: {
219
+ ':PK': { S: `UNIQUE#${fieldName}#${value}` },
220
+ ':SK': { S: entityType },
221
+ },
222
+ });
223
+ if ((_a = resp.Items) === null || _a === void 0 ? void 0 : _a[0]) {
224
+ throw new StandardError('UNIQUE_VALUE_EXISTS', `${fieldName} '${value}' already exists`);
225
+ }
226
+ return;
218
227
  });
219
- if (resp.Items?.[0]) {
220
- throw new StandardError('UNIQUE_VALUE_EXISTS', `${fieldName} '${value}' already exists`);
221
- }
222
- return;
223
228
  }
224
229
  createEntityTransactItems(entity, opts) {
225
230
  const TransactItems = [
@@ -227,26 +232,17 @@ export class EntityRepository extends Repository {
227
232
  Put: {
228
233
  TableName: this.TABLE_NAME,
229
234
  ConditionExpression: 'attribute_not_exists(PK)',
230
- Item: {
231
- ...entity.toItem(),
232
- ...(opts?.mutualId && {
233
- R2PK: { S: opts.mutualId },
234
- R2SK: { S: entity.pk },
235
- }),
236
- },
235
+ Item: Object.assign(Object.assign({}, entity.toItem()), ((opts === null || opts === void 0 ? void 0 : opts.mutualId) && {
236
+ R2PK: { S: opts.mutualId },
237
+ R2SK: { S: entity.pk },
238
+ })),
237
239
  },
238
240
  },
239
241
  {
240
242
  Put: {
241
243
  TableName: this.TABLE_NAME,
242
244
  ConditionExpression: 'attribute_not_exists(PK)',
243
- Item: {
244
- ...entity.toItem(),
245
- PK: { S: entity.listActionKey },
246
- SK: entity.keys().PK,
247
- R1PK: entity.keys().PK,
248
- R1SK: { S: entity.listActionKey },
249
- },
245
+ Item: Object.assign(Object.assign({}, entity.toItem()), { PK: { S: entity.listActionKey }, SK: entity.keys().PK, R1PK: entity.keys().PK, R1SK: { S: entity.listActionKey } }),
250
246
  },
251
247
  },
252
248
  ];
@@ -259,12 +255,7 @@ export class EntityRepository extends Repository {
259
255
  Put: {
260
256
  TableName: this.TABLE_NAME,
261
257
  ConditionExpression: 'attribute_not_exists(PK)',
262
- Item: {
263
- ...entity.toItem(),
264
- ...entity.emailKeys,
265
- R1PK: entity.emailKeys.SK,
266
- R1SK: entity.emailKeys.PK,
267
- },
258
+ Item: Object.assign(Object.assign(Object.assign({}, entity.toItem()), entity.emailKeys), { R1PK: entity.emailKeys.SK, R1SK: entity.emailKeys.PK }),
268
259
  },
269
260
  });
270
261
  }
@@ -273,76 +264,65 @@ export class EntityRepository extends Repository {
273
264
  Put: {
274
265
  TableName: this.TABLE_NAME,
275
266
  ConditionExpression: 'attribute_not_exists(PK)',
276
- Item: {
277
- ...entity.toItem(),
278
- PK: {
267
+ Item: Object.assign(Object.assign({}, entity.toItem()), { PK: {
279
268
  S: `UNIQUE#${field}#${entity.data[field]}`,
280
- },
281
- SK: { S: entity.entityType },
282
- R1PK: entity.keys().PK,
283
- R1SK: entity.keys().SK,
284
- },
269
+ }, SK: { S: entity.entityType }, R1PK: entity.keys().PK, R1SK: entity.keys().SK }),
285
270
  },
286
271
  });
287
272
  }
288
273
  return TransactItems;
289
274
  }
290
- async createEntity(entityType, entityPayload, entityId, opts) {
291
- const currentDatetime = opts?.createAndUpdateDatetime ?? new Date();
292
- const entity = new Entity(entityType, entityId || ulid(), entityPayload, currentDatetime, currentDatetime);
293
- const uniqueFields = (this.EntityConfig[entityType].uniqueFields ||
294
- []);
295
- const hasUniqueFields = Object.keys(entityPayload).some((field) => uniqueFields.includes(field));
296
- let uniqueFieldValues = {};
297
- if (hasUniqueFields) {
298
- for (const field of uniqueFields) {
299
- if (typeof entityPayload[field] !== 'string') {
300
- throw new StandardError('INVALID_UNIQUE_VALUE_TYPE', `Invalid type. ${field} is not a 'string'.`);
275
+ createEntity(entityType, entityPayload, entityId, opts) {
276
+ return __awaiter(this, void 0, void 0, function* () {
277
+ var _a;
278
+ const currentDatetime = (_a = opts === null || opts === void 0 ? void 0 : opts.createAndUpdateDatetime) !== null && _a !== void 0 ? _a : new Date();
279
+ const entity = new Entity(entityType, entityId || ulid(), entityPayload, currentDatetime, currentDatetime);
280
+ const uniqueFields = (this.EntityConfig[entityType].uniqueFields ||
281
+ []);
282
+ const hasUniqueFields = Object.keys(entityPayload).some((field) => uniqueFields.includes(field));
283
+ let uniqueFieldValues = {};
284
+ if (hasUniqueFields) {
285
+ for (const field of uniqueFields) {
286
+ if (typeof entityPayload[field] !== 'string') {
287
+ throw new StandardError('INVALID_UNIQUE_VALUE_TYPE', `Invalid type. ${field} is not a 'string'.`);
288
+ }
301
289
  }
290
+ uniqueFieldValues = uniqueFields.reduce((acc, field) => (Object.assign(Object.assign({}, acc), { [field]: entityPayload[field] })), {});
302
291
  }
303
- uniqueFieldValues = uniqueFields.reduce((acc, field) => ({
304
- ...acc,
305
- [field]: entityPayload[field],
306
- }), {});
307
- }
308
- const TransactItems = this.createEntityTransactItems(entity, {
309
- mutualId: opts?.mutualId,
310
- uniqueFieldValues,
292
+ const TransactItems = this.createEntityTransactItems(entity, {
293
+ mutualId: opts === null || opts === void 0 ? void 0 : opts.mutualId,
294
+ uniqueFieldValues,
295
+ });
296
+ yield this.dynamodbClient.transactWriteItems({ TransactItems });
297
+ return entity;
311
298
  });
312
- await this.dynamodbClient.transactWriteItems({ TransactItems });
313
- return entity;
314
299
  }
315
- async upsertEntity(entityType, entityId, payload) {
316
- const currentDatetime = new Date().toISOString();
317
- const toUpdateExpressions = this.toUpdate({
318
- entityType,
319
- entityId,
320
- data: payload,
321
- updatedAt: currentDatetime,
300
+ upsertEntity(entityType, entityId, payload) {
301
+ return __awaiter(this, void 0, void 0, function* () {
302
+ const currentDatetime = new Date().toISOString();
303
+ const toUpdateExpressions = this.toUpdate({
304
+ entityType,
305
+ entityId,
306
+ data: payload,
307
+ updatedAt: currentDatetime,
308
+ });
309
+ const params = {
310
+ TableName: this.TABLE_NAME,
311
+ ReturnValues: 'ALL_NEW',
312
+ Key: new Entity(entityType, entityId).keys(),
313
+ UpdateExpression: toUpdateExpressions.UpdateExpression,
314
+ ExpressionAttributeNames: Object.assign({}, toUpdateExpressions.ExpressionAttributeNames),
315
+ ExpressionAttributeValues: Object.assign({}, toUpdateExpressions.ExpressionAttributeValues),
316
+ };
317
+ const resp = yield this.dynamodbClient.updateItem(params);
318
+ const updatedEntity = Entity.fromItem(resp.Attributes);
319
+ return updatedEntity;
322
320
  });
323
- const params = {
324
- TableName: this.TABLE_NAME,
325
- ReturnValues: 'ALL_NEW',
326
- Key: new Entity(entityType, entityId).keys(),
327
- UpdateExpression: toUpdateExpressions.UpdateExpression,
328
- ExpressionAttributeNames: {
329
- ...toUpdateExpressions.ExpressionAttributeNames,
330
- },
331
- ExpressionAttributeValues: {
332
- ...toUpdateExpressions.ExpressionAttributeValues,
333
- },
334
- };
335
- const resp = await this.dynamodbClient.updateItem(params);
336
- const updatedEntity = Entity.fromItem(resp.Attributes);
337
- return updatedEntity;
338
321
  }
339
322
  updateEntityTransactItems(entity, updateParams, previousUniqueFieldValues, previousEntity) {
340
323
  const transactItems = [
341
324
  {
342
- Update: {
343
- ...updateParams,
344
- UpdateExpression: updateParams.UpdateExpression,
345
- },
325
+ Update: Object.assign(Object.assign({}, updateParams), { UpdateExpression: updateParams.UpdateExpression }),
346
326
  },
347
327
  ];
348
328
  for (const field in previousUniqueFieldValues) {
@@ -358,142 +338,126 @@ export class EntityRepository extends Repository {
358
338
  Put: {
359
339
  TableName: this.TABLE_NAME,
360
340
  ConditionExpression: 'attribute_not_exists(PK)',
361
- Item: {
362
- ...entity.toItem(),
363
- data: {
364
- M: {
365
- ...previousEntity.toItem().data.M,
366
- ...entity.toItem().data.M,
367
- },
368
- },
369
- PK: {
341
+ Item: Object.assign(Object.assign({}, entity.toItem()), { data: {
342
+ M: Object.assign(Object.assign({}, previousEntity.toItem().data.M), entity.toItem().data.M),
343
+ }, PK: {
370
344
  S: `UNIQUE#${field}#${entity.data[field]}`,
371
- },
372
- SK: { S: entity.entityType },
373
- R1PK: entity.keys().PK,
374
- R1SK: entity.keys().SK,
375
- },
345
+ }, SK: { S: entity.entityType }, R1PK: entity.keys().PK, R1SK: entity.keys().SK }),
376
346
  },
377
347
  });
378
348
  }
379
349
  return transactItems;
380
350
  }
381
- async updateEntity(entityType, entityId, toUpdate, opts) {
382
- try {
383
- const currentDatetime = new Date().toISOString();
384
- const toUpdateExpressions = this.toUpdate({
385
- updatedAt: currentDatetime,
386
- ...toUpdate,
387
- });
388
- const params = {
389
- TableName: this.TABLE_NAME,
390
- ReturnValues: 'ALL_NEW',
391
- Key: new Entity(entityType, entityId).keys(),
392
- ConditionExpression: opts?.ConditionExpression || 'attribute_exists(PK)',
393
- UpdateExpression: toUpdateExpressions.UpdateExpression,
394
- ExpressionAttributeNames: {
395
- ...toUpdateExpressions.ExpressionAttributeNames,
396
- ...opts?.ExpressionAttributeNames,
397
- },
398
- ExpressionAttributeValues: {
399
- ...toUpdateExpressions.ExpressionAttributeValues,
400
- ...opts?.ExpressionAttributeValues,
401
- },
402
- };
403
- const entity = new Entity(entityType, entityId, toUpdate.data);
404
- const uniqueFields = (this.EntityConfig[entityType].uniqueFields ||
405
- []);
406
- const hasUniqueFields = Object.keys(toUpdate.data).some((field) => uniqueFields.includes(field));
407
- let updatedUniqueFields = [];
408
- let previousUniqueFieldValues = {};
409
- let previousEntity;
410
- if (hasUniqueFields) {
411
- previousEntity = await this.getEntity(entityType, entityId);
412
- // check if any of the unique fields has changed
413
- updatedUniqueFields = uniqueFields.filter((field) => toUpdate.data[field] !==
414
- previousEntity.data[field]);
415
- previousUniqueFieldValues = updatedUniqueFields.reduce((acc, field) => ({
416
- ...acc,
417
- [field]: previousEntity.data[field],
418
- }), {});
419
- for (const field in previousUniqueFieldValues) {
420
- if (typeof toUpdate.data[field] !==
421
- 'string') {
422
- throw new StandardError('INVALID_UNIQUE_VALUE_TYPE', `Invalid type. ${field} is not a 'string'.`);
351
+ updateEntity(entityType, entityId, toUpdate, opts) {
352
+ return __awaiter(this, void 0, void 0, function* () {
353
+ try {
354
+ const currentDatetime = new Date().toISOString();
355
+ const toUpdateExpressions = this.toUpdate(Object.assign({ updatedAt: currentDatetime }, toUpdate));
356
+ const params = {
357
+ TableName: this.TABLE_NAME,
358
+ ReturnValues: 'ALL_NEW',
359
+ Key: new Entity(entityType, entityId).keys(),
360
+ ConditionExpression: (opts === null || opts === void 0 ? void 0 : opts.ConditionExpression) || 'attribute_exists(PK)',
361
+ UpdateExpression: toUpdateExpressions.UpdateExpression,
362
+ ExpressionAttributeNames: Object.assign(Object.assign({}, toUpdateExpressions.ExpressionAttributeNames), opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames),
363
+ ExpressionAttributeValues: Object.assign(Object.assign({}, toUpdateExpressions.ExpressionAttributeValues), opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues),
364
+ };
365
+ const entity = new Entity(entityType, entityId, toUpdate.data);
366
+ const uniqueFields = (this.EntityConfig[entityType].uniqueFields ||
367
+ []);
368
+ const hasUniqueFields = Object.keys(toUpdate.data).some((field) => uniqueFields.includes(field));
369
+ let updatedUniqueFields = [];
370
+ let previousUniqueFieldValues = {};
371
+ let previousEntity;
372
+ if (hasUniqueFields) {
373
+ previousEntity = yield this.getEntity(entityType, entityId);
374
+ // check if any of the unique fields has changed
375
+ updatedUniqueFields = uniqueFields.filter((field) => toUpdate.data[field] !==
376
+ previousEntity.data[field]);
377
+ previousUniqueFieldValues = updatedUniqueFields.reduce((acc, field) => (Object.assign(Object.assign({}, acc), { [field]: previousEntity.data[field] })), {});
378
+ for (const field in previousUniqueFieldValues) {
379
+ if (typeof toUpdate.data[field] !==
380
+ 'string') {
381
+ throw new StandardError('INVALID_UNIQUE_VALUE_TYPE', `Invalid type. ${field} is not a 'string'.`);
382
+ }
383
+ }
384
+ if (updatedUniqueFields.length > 0) {
385
+ const TransactItems = this.updateEntityTransactItems(entity, params, previousUniqueFieldValues, previousEntity);
386
+ yield this.dynamodbClient.transactWriteItems({ TransactItems });
387
+ return yield this.getEntity(entityType, entityId);
423
388
  }
424
389
  }
425
- if (updatedUniqueFields.length > 0) {
426
- const TransactItems = this.updateEntityTransactItems(entity, params, previousUniqueFieldValues, previousEntity);
427
- await this.dynamodbClient.transactWriteItems({ TransactItems });
428
- return await this.getEntity(entityType, entityId);
390
+ const resp = yield this.dynamodbClient.updateItem(params);
391
+ const updatedEntity = Entity.fromItem(resp.Attributes);
392
+ return updatedEntity;
393
+ }
394
+ catch (err) {
395
+ if (err instanceof ConditionalCheckFailedException) {
396
+ throw new StandardError('ENTITY_NOT_FOUND', 'Entity not found', err, {
397
+ entityId,
398
+ toUpdate,
399
+ });
429
400
  }
401
+ throw err;
430
402
  }
431
- const resp = await this.dynamodbClient.updateItem(params);
432
- const updatedEntity = Entity.fromItem(resp.Attributes);
433
- return updatedEntity;
434
- }
435
- catch (err) {
436
- if (err instanceof ConditionalCheckFailedException) {
437
- throw new StandardError('ENTITY_NOT_FOUND', 'Entity not found', err, {
438
- entityId,
439
- toUpdate,
403
+ });
404
+ }
405
+ deleteEntity(entityType, entityId) {
406
+ return __awaiter(this, void 0, void 0, function* () {
407
+ try {
408
+ const entity = new Entity(entityType, entityId);
409
+ yield this.dynamodbClient.deleteItem({
410
+ TableName: this.TABLE_NAME,
411
+ Key: entity.keys(),
412
+ ConditionExpression: 'attribute_exists(PK)',
440
413
  });
441
414
  }
442
- throw err;
443
- }
415
+ catch (err) {
416
+ if (err instanceof ConditionalCheckFailedException) {
417
+ throw new StandardError('ENTITY_NOT_FOUND', 'Entity not found', err, {
418
+ entityId,
419
+ });
420
+ }
421
+ throw err;
422
+ }
423
+ });
444
424
  }
445
- async deleteEntity(entityType, entityId) {
446
- try {
447
- const entity = new Entity(entityType, entityId);
448
- await this.dynamodbClient.deleteItem({
449
- TableName: this.TABLE_NAME,
450
- Key: entity.keys(),
451
- ConditionExpression: 'attribute_exists(PK)',
425
+ queryEntities(entityType, query) {
426
+ return __awaiter(this, void 0, void 0, function* () {
427
+ const results = {
428
+ items: [],
429
+ totalCount: 0,
430
+ };
431
+ // let regex be empty if its invalid (eg. +)
432
+ let queryRegex = /(?:)/;
433
+ try {
434
+ queryRegex = new RegExp(query.toLowerCase());
435
+ }
436
+ catch (err) {
437
+ return results;
438
+ }
439
+ const listResults = yield this.listEntities({
440
+ entityType,
452
441
  });
453
- }
454
- catch (err) {
455
- if (err instanceof ConditionalCheckFailedException) {
456
- throw new StandardError('ENTITY_NOT_FOUND', 'Entity not found', err, {
457
- entityId,
458
- });
442
+ results.items.push(...listResults.items);
443
+ results.totalCount += listResults.totalCount || 0;
444
+ const filteredItems = [];
445
+ const { searchableFields } = this.EntityConfig[entityType];
446
+ for (const item of results.items) {
447
+ const searchTerm = (searchableFields !== null && searchableFields !== void 0 ? searchableFields : [])
448
+ .map((field) => { var _a; return (_a = item.data[field]) === null || _a === void 0 ? void 0 : _a.toLowerCase(); })
449
+ .join(' ');
450
+ const isMatched = queryRegex.test(searchTerm);
451
+ if (isMatched) {
452
+ filteredItems.push(item);
453
+ }
459
454
  }
460
- throw err;
461
- }
462
- }
463
- async queryEntities(entityType, query) {
464
- const results = {
465
- items: [],
466
- totalCount: 0,
467
- };
468
- // let regex be empty if its invalid (eg. +)
469
- let queryRegex = /(?:)/;
470
- try {
471
- queryRegex = new RegExp(query.toLowerCase());
472
- }
473
- catch (err) {
474
- return results;
475
- }
476
- const listResults = await this.listEntities({
477
- entityType,
455
+ return {
456
+ items: filteredItems,
457
+ totalCount: results.totalCount,
458
+ filteredCount: filteredItems.length,
459
+ };
478
460
  });
479
- results.items.push(...listResults.items);
480
- results.totalCount += listResults.totalCount || 0;
481
- const filteredItems = [];
482
- const { searchableFields } = this.EntityConfig[entityType];
483
- for (const item of results.items) {
484
- const searchTerm = (searchableFields ?? [])
485
- .map((field) => item.data[field]?.toLowerCase())
486
- .join(' ');
487
- const isMatched = queryRegex.test(searchTerm);
488
- if (isMatched) {
489
- filteredItems.push(item);
490
- }
491
- }
492
- return {
493
- items: filteredItems,
494
- totalCount: results.totalCount,
495
- filteredCount: filteredItems.length,
496
- };
497
461
  }
498
462
  }
499
463
  //# sourceMappingURL=Entity.js.map