@monorise/core 1.0.4-7 → 3.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/dist/constants/table.d.ts +0 -1
- package/dist/constants/table.d.ts.map +1 -1
- package/dist/constants/table.js +0 -1
- package/dist/constants/table.js.map +1 -1
- package/dist/controllers/entity/create-entity.controller.d.ts +1 -2
- package/dist/controllers/entity/create-entity.controller.d.ts.map +1 -1
- package/dist/controllers/entity/create-entity.controller.js +54 -34
- package/dist/controllers/entity/create-entity.controller.js.map +1 -1
- package/dist/controllers/entity/delete-entity.controller.d.ts +1 -2
- package/dist/controllers/entity/delete-entity.controller.d.ts.map +1 -1
- package/dist/controllers/entity/delete-entity.controller.js +30 -21
- package/dist/controllers/entity/delete-entity.controller.js.map +1 -1
- package/dist/controllers/entity/get-entity-by-unique-field-value.controller.d.ts +7 -0
- package/dist/controllers/entity/get-entity-by-unique-field-value.controller.d.ts.map +1 -0
- package/dist/controllers/entity/get-entity-by-unique-field-value.controller.js +36 -0
- package/dist/controllers/entity/get-entity-by-unique-field-value.controller.js.map +1 -0
- package/dist/controllers/entity/get-entity.controller.d.ts +1 -2
- package/dist/controllers/entity/get-entity.controller.d.ts.map +1 -1
- package/dist/controllers/entity/get-entity.controller.js +30 -17
- package/dist/controllers/entity/get-entity.controller.js.map +1 -1
- package/dist/controllers/entity/list-entities.controller.d.ts +1 -2
- package/dist/controllers/entity/list-entities.controller.d.ts.map +1 -1
- package/dist/controllers/entity/list-entities.controller.js +44 -39
- package/dist/controllers/entity/list-entities.controller.js.map +1 -1
- package/dist/controllers/entity/update-entity.controller.d.ts +1 -2
- package/dist/controllers/entity/update-entity.controller.d.ts.map +1 -1
- package/dist/controllers/entity/update-entity.controller.js +52 -35
- package/dist/controllers/entity/update-entity.controller.js.map +1 -1
- package/dist/controllers/entity/upsert-entity.controller.d.ts +3 -3
- package/dist/controllers/entity/upsert-entity.controller.d.ts.map +1 -1
- package/dist/controllers/entity/upsert-entity.controller.js +70 -60
- package/dist/controllers/entity/upsert-entity.controller.js.map +1 -1
- package/dist/controllers/mutual/create-mutual.controller.d.ts +2 -4
- package/dist/controllers/mutual/create-mutual.controller.d.ts.map +1 -1
- package/dist/controllers/mutual/create-mutual.controller.js +51 -45
- package/dist/controllers/mutual/create-mutual.controller.js.map +1 -1
- package/dist/controllers/mutual/delete-mutual.controller.d.ts +1 -2
- package/dist/controllers/mutual/delete-mutual.controller.d.ts.map +1 -1
- package/dist/controllers/mutual/delete-mutual.controller.js +32 -23
- package/dist/controllers/mutual/delete-mutual.controller.js.map +1 -1
- package/dist/controllers/mutual/get-mutual.controller.d.ts +1 -2
- package/dist/controllers/mutual/get-mutual.controller.d.ts.map +1 -1
- package/dist/controllers/mutual/get-mutual.controller.js +29 -17
- package/dist/controllers/mutual/get-mutual.controller.js.map +1 -1
- package/dist/controllers/mutual/list-entities-by-entity.controller.d.ts +1 -2
- package/dist/controllers/mutual/list-entities-by-entity.controller.d.ts.map +1 -1
- package/dist/controllers/mutual/list-entities-by-entity.controller.js +60 -44
- package/dist/controllers/mutual/list-entities-by-entity.controller.js.map +1 -1
- package/dist/controllers/mutual/update-mutual.controller.d.ts +1 -2
- package/dist/controllers/mutual/update-mutual.controller.d.ts.map +1 -1
- package/dist/controllers/mutual/update-mutual.controller.js +44 -30
- package/dist/controllers/mutual/update-mutual.controller.js.map +1 -1
- package/dist/controllers/setupRoutes.d.ts +2 -3
- package/dist/controllers/setupRoutes.d.ts.map +1 -1
- package/dist/controllers/setupRoutes.js +19 -17
- package/dist/controllers/setupRoutes.js.map +1 -1
- package/dist/controllers/tag/list-tags.controller.d.ts +1 -2
- package/dist/controllers/tag/list-tags.controller.d.ts.map +1 -1
- package/dist/controllers/tag/list-tags.controller.js +42 -33
- package/dist/controllers/tag/list-tags.controller.js.map +1 -1
- package/dist/data/DbUtils.js +24 -13
- package/dist/data/DbUtils.js.map +1 -1
- package/dist/data/Entity.d.ts +14 -10
- package/dist/data/Entity.d.ts.map +1 -1
- package/dist/data/Entity.js +370 -227
- package/dist/data/Entity.js.map +1 -1
- package/dist/data/EventUtils.d.ts +3 -3
- package/dist/data/EventUtils.d.ts.map +1 -1
- package/dist/data/EventUtils.js +35 -27
- package/dist/data/EventUtils.js.map +1 -1
- package/dist/data/Mutual.d.ts +7 -8
- package/dist/data/Mutual.d.ts.map +1 -1
- package/dist/data/Mutual.js +289 -341
- package/dist/data/Mutual.js.map +1 -1
- package/dist/data/Tag.d.ts +2 -2
- package/dist/data/Tag.d.ts.map +1 -1
- package/dist/data/Tag.js +229 -230
- package/dist/data/Tag.js.map +1 -1
- package/dist/data/abstract/Repository.base.js +4 -7
- package/dist/data/abstract/Repository.base.js.map +1 -1
- package/dist/errors/extendable-error.js +0 -7
- package/dist/errors/extendable-error.js.map +1 -1
- package/dist/errors/standard-error.d.ts +22 -0
- package/dist/errors/standard-error.d.ts.map +1 -1
- package/dist/errors/standard-error.js +21 -3
- package/dist/errors/standard-error.js.map +1 -1
- package/dist/handles/app.d.ts +16 -0
- package/dist/handles/app.d.ts.map +1 -0
- package/dist/handles/app.js +31 -0
- package/dist/handles/app.js.map +1 -0
- package/dist/helpers/event.d.ts.map +1 -1
- package/dist/helpers/event.js +35 -34
- package/dist/helpers/event.js.map +1 -1
- package/dist/index.d.ts +24 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -21
- package/dist/index.js.map +1 -1
- package/dist/middlewares/api-key-auth.d.ts +3 -0
- package/dist/middlewares/api-key-auth.d.ts.map +1 -0
- package/dist/middlewares/api-key-auth.js +32 -0
- package/dist/middlewares/api-key-auth.js.map +1 -0
- package/dist/middlewares/entity-type-check.d.ts +1 -1
- package/dist/middlewares/entity-type-check.d.ts.map +1 -1
- package/dist/middlewares/entity-type-check.js +17 -7
- package/dist/middlewares/entity-type-check.js.map +1 -1
- package/dist/middlewares/general-error-handler.d.ts +7 -0
- package/dist/middlewares/general-error-handler.d.ts.map +1 -0
- package/dist/middlewares/general-error-handler.js +40 -0
- package/dist/middlewares/general-error-handler.js.map +1 -0
- package/dist/middlewares/mutual-type-check.d.ts +1 -1
- package/dist/middlewares/mutual-type-check.d.ts.map +1 -1
- package/dist/middlewares/mutual-type-check.js +18 -8
- package/dist/middlewares/mutual-type-check.js.map +1 -1
- package/dist/processors/create-entity-processor.d.ts.map +1 -1
- package/dist/processors/create-entity-processor.js +17 -5
- package/dist/processors/create-entity-processor.js.map +1 -1
- package/dist/processors/mutual-processor.d.ts.map +1 -1
- package/dist/processors/mutual-processor.js +39 -29
- package/dist/processors/mutual-processor.js.map +1 -1
- package/dist/processors/prejoin-processor.d.ts.map +1 -1
- package/dist/processors/prejoin-processor.js +117 -104
- package/dist/processors/prejoin-processor.js.map +1 -1
- package/dist/processors/replication-processor.d.ts.map +1 -1
- package/dist/processors/replication-processor.js +31 -31
- package/dist/processors/replication-processor.js.map +1 -1
- package/dist/processors/tag-processor.js +48 -35
- package/dist/processors/tag-processor.js.map +1 -1
- package/dist/services/DependencyContainer.d.ts +16 -7
- package/dist/services/DependencyContainer.d.ts.map +1 -1
- package/dist/services/DependencyContainer.js +13 -24
- package/dist/services/DependencyContainer.js.map +1 -1
- package/dist/services/entity-service-lifecycle.js +29 -20
- package/dist/services/entity-service-lifecycle.js.map +1 -1
- package/dist/services/entity.service.d.ts +6 -6
- package/dist/services/entity.service.d.ts.map +1 -1
- package/dist/services/entity.service.js +96 -93
- package/dist/services/entity.service.js.map +1 -1
- package/dist/services/mutual.service.js +117 -113
- package/dist/services/mutual.service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/entity.type.d.ts.map +1 -1
- package/dist/types/event.d.ts +4 -3
- package/dist/types/event.d.ts.map +1 -1
- package/dist/types/event.js +9 -9
- package/dist/types/event.js.map +1 -1
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +10 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +8 -6
- package/dist/mock/entity.d.ts +0 -13
- package/dist/mock/entity.d.ts.map +0 -1
- package/dist/mock/entity.js +0 -14
- package/dist/mock/entity.js.map +0 -1
- package/dist/mock/monorise/admin.d.ts +0 -127
- package/dist/mock/monorise/admin.d.ts.map +0 -1
- package/dist/mock/monorise/admin.js +0 -29
- package/dist/mock/monorise/admin.js.map +0 -1
- package/dist/mock/monorise/chapter.d.ts +0 -457
- package/dist/mock/monorise/chapter.d.ts.map +0 -1
- package/dist/mock/monorise/chapter.js +0 -81
- package/dist/mock/monorise/chapter.js.map +0 -1
- package/dist/mock/monorise/course.d.ts +0 -311
- package/dist/mock/monorise/course.d.ts.map +0 -1
- package/dist/mock/monorise/course.js +0 -128
- package/dist/mock/monorise/course.js.map +0 -1
- package/dist/mock/monorise/index.d.ts +0 -3599
- package/dist/mock/monorise/index.d.ts.map +0 -1
- package/dist/mock/monorise/index.js +0 -62
- package/dist/mock/monorise/index.js.map +0 -1
- package/dist/mock/monorise/learner.d.ts +0 -390
- package/dist/mock/monorise/learner.d.ts.map +0 -1
- package/dist/mock/monorise/learner.js +0 -59
- package/dist/mock/monorise/learner.js.map +0 -1
- package/dist/mock/monorise/learning-activity.d.ts +0 -266
- package/dist/mock/monorise/learning-activity.d.ts.map +0 -1
- package/dist/mock/monorise/learning-activity.js +0 -50
- package/dist/mock/monorise/learning-activity.js.map +0 -1
- package/dist/mock/monorise/learning-journey-config.d.ts +0 -84
- package/dist/mock/monorise/learning-journey-config.d.ts.map +0 -1
- package/dist/mock/monorise/learning-journey-config.js +0 -27
- package/dist/mock/monorise/learning-journey-config.js.map +0 -1
- package/dist/mock/monorise/module.d.ts +0 -211
- package/dist/mock/monorise/module.d.ts.map +0 -1
- package/dist/mock/monorise/module.js +0 -91
- package/dist/mock/monorise/module.js.map +0 -1
- package/dist/mock/monorise/organization.d.ts +0 -346
- package/dist/mock/monorise/organization.d.ts.map +0 -1
- package/dist/mock/monorise/organization.js +0 -54
- package/dist/mock/monorise/organization.js.map +0 -1
- package/dist/mock/monorise/reference.d.ts +0 -171
- package/dist/mock/monorise/reference.d.ts.map +0 -1
- package/dist/mock/monorise/reference.js +0 -25
- package/dist/mock/monorise/reference.js.map +0 -1
- package/dist/mock/monorise/video.d.ts +0 -346
- package/dist/mock/monorise/video.d.ts.map +0 -1
- package/dist/mock/monorise/video.js +0 -33
- package/dist/mock/monorise/video.js.map +0 -1
package/dist/data/Mutual.js
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
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 { BatchStatementErrorCodeEnum, TransactionCanceledException, } from '@aws-sdk/client-dynamodb';
|
|
2
11
|
import { marshall, unmarshall } from '@aws-sdk/util-dynamodb';
|
|
3
12
|
import { ulid } from 'ulid';
|
|
4
|
-
import { StandardError } from '../errors/standard-error';
|
|
13
|
+
import { StandardError, StandardErrorCode } from '../errors/standard-error';
|
|
14
|
+
import { fromLastKeyQuery } from '../helpers/fromLastKeyQuery';
|
|
5
15
|
import { sleep } from '../helpers/sleep';
|
|
16
|
+
import { toLastKeyResponse } from '../helpers/toLastKeyResponse';
|
|
6
17
|
import { PROJECTION_EXPRESSION, } from './ProjectionExpression';
|
|
7
18
|
import { Repository } from './abstract/Repository.base';
|
|
8
19
|
export class Mutual {
|
|
9
|
-
byEntityType;
|
|
10
|
-
byEntityId;
|
|
11
|
-
byData;
|
|
12
|
-
entityType;
|
|
13
|
-
entityId;
|
|
14
|
-
data;
|
|
15
|
-
mutualData;
|
|
16
|
-
mutualId;
|
|
17
|
-
_createdAt;
|
|
18
|
-
_updatedAt;
|
|
19
|
-
_mutualUpdatedAt;
|
|
20
|
-
_expiresAt;
|
|
21
20
|
constructor(byEntityType, byEntityId, byData, entityType, entityId, data, mutualData, mutualId, _createdAt, _updatedAt, _mutualUpdatedAt, _expiresAt) {
|
|
22
21
|
this.byEntityType = byEntityType;
|
|
23
22
|
this.byEntityId = byEntityId;
|
|
@@ -34,7 +33,7 @@ export class Mutual {
|
|
|
34
33
|
}
|
|
35
34
|
static fromItem(item) {
|
|
36
35
|
if (!item)
|
|
37
|
-
throw new StandardError(
|
|
36
|
+
throw new StandardError(StandardErrorCode.MUTUAL_IS_UNDEFINED, 'Mutual item empty');
|
|
38
37
|
const parsedItem = unmarshall(item);
|
|
39
38
|
return new Mutual(parsedItem.byEntityType, parsedItem.byEntityId, parsedItem.byData, parsedItem.entityType, parsedItem.entityId, parsedItem.data, parsedItem.mutualData, parsedItem.mutualId, parsedItem.createdAt ? new Date(parsedItem.createdAt) : undefined, parsedItem.updatedAt ? new Date(parsedItem.updatedAt) : undefined, parsedItem.mutualUpdatedAt
|
|
40
39
|
? new Date(parsedItem.mutualUpdatedAt)
|
|
@@ -68,44 +67,28 @@ export class Mutual {
|
|
|
68
67
|
return '#METADATA#';
|
|
69
68
|
}
|
|
70
69
|
get createdAt() {
|
|
71
|
-
|
|
70
|
+
var _a;
|
|
71
|
+
return (_a = this._createdAt) === null || _a === void 0 ? void 0 : _a.toISOString();
|
|
72
72
|
}
|
|
73
73
|
get updatedAt() {
|
|
74
|
-
|
|
74
|
+
var _a;
|
|
75
|
+
return (_a = this._updatedAt) === null || _a === void 0 ? void 0 : _a.toISOString();
|
|
75
76
|
}
|
|
76
77
|
get mutualUpdatedAt() {
|
|
77
|
-
|
|
78
|
+
var _a;
|
|
79
|
+
return (_a = this._mutualUpdatedAt) === null || _a === void 0 ? void 0 : _a.toISOString();
|
|
78
80
|
}
|
|
79
81
|
get expiresAt() {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
toMutualItemOnly() {
|
|
83
|
-
// Mutual #METADATA# has `mutualData` only
|
|
84
|
-
return {
|
|
85
|
-
...marshall({ ...this.toJSON(), data: {} }, { removeUndefinedValues: true }),
|
|
86
|
-
...this.mainKeys(),
|
|
87
|
-
};
|
|
82
|
+
var _a;
|
|
83
|
+
return (_a = this._expiresAt) === null || _a === void 0 ? void 0 : _a.toISOString();
|
|
88
84
|
}
|
|
89
85
|
toItem() {
|
|
90
|
-
return {
|
|
91
|
-
...marshall(this.toJSON(), { removeUndefinedValues: true }),
|
|
92
|
-
...this.mainKeys(),
|
|
93
|
-
};
|
|
86
|
+
return Object.assign(Object.assign({}, marshall(this.toJSON(), { removeUndefinedValues: true })), this.mainKeys());
|
|
94
87
|
}
|
|
95
88
|
toReversedItem() {
|
|
96
89
|
const item = this.toJSON();
|
|
97
|
-
const reversedMutual = {
|
|
98
|
-
|
|
99
|
-
byEntityType: item.entityType,
|
|
100
|
-
byEntityId: item.entityId,
|
|
101
|
-
entityType: item.byEntityType,
|
|
102
|
-
entityId: item.byEntityId,
|
|
103
|
-
data: this.byData,
|
|
104
|
-
};
|
|
105
|
-
return {
|
|
106
|
-
...marshall(reversedMutual, { removeUndefinedValues: true }),
|
|
107
|
-
...this.mainKeys(),
|
|
108
|
-
};
|
|
90
|
+
const reversedMutual = Object.assign(Object.assign({}, item), { byEntityType: item.entityType, byEntityId: item.entityId, entityType: item.byEntityType, entityId: item.byEntityId, data: this.byData });
|
|
91
|
+
return Object.assign(Object.assign({}, marshall(reversedMutual, { removeUndefinedValues: true })), this.mainKeys());
|
|
109
92
|
}
|
|
110
93
|
toJSON() {
|
|
111
94
|
return {
|
|
@@ -124,369 +107,334 @@ export class Mutual {
|
|
|
124
107
|
}
|
|
125
108
|
}
|
|
126
109
|
export class MutualRepository extends Repository {
|
|
127
|
-
TABLE_NAME;
|
|
128
|
-
dynamodbClient;
|
|
129
|
-
ddbUtils;
|
|
130
110
|
constructor(TABLE_NAME, dynamodbClient, ddbUtils) {
|
|
131
111
|
super();
|
|
132
112
|
this.TABLE_NAME = TABLE_NAME;
|
|
133
113
|
this.dynamodbClient = dynamodbClient;
|
|
134
114
|
this.ddbUtils = ddbUtils;
|
|
135
115
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
'#
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
':PK': {
|
|
149
|
-
S: mutual.byFullEntityId,
|
|
116
|
+
listEntitiesByEntity(byEntityType_1, byEntityId_1, entityType_1) {
|
|
117
|
+
return __awaiter(this, arguments, void 0, function* (byEntityType, byEntityId, entityType, opts = {}) {
|
|
118
|
+
var _a, _b, _c, _d;
|
|
119
|
+
const mutual = new Mutual(byEntityType, byEntityId, {}, entityType, 'list_by_only', {}, {});
|
|
120
|
+
const listAssociationsQuery = {
|
|
121
|
+
TableName: this.TABLE_NAME,
|
|
122
|
+
KeyConditionExpression: '#PK = :PK and begins_with(#SK, :SK)',
|
|
123
|
+
FilterExpression: 'attribute_not_exists(#expiresAt) or attribute_type(#expiresAt, :nullType)',
|
|
124
|
+
ExpressionAttributeNames: {
|
|
125
|
+
'#PK': 'PK',
|
|
126
|
+
'#SK': 'SK',
|
|
127
|
+
'#expiresAt': 'expiresAt',
|
|
150
128
|
},
|
|
151
|
-
|
|
152
|
-
|
|
129
|
+
ExpressionAttributeValues: {
|
|
130
|
+
':PK': {
|
|
131
|
+
S: mutual.byFullEntityId,
|
|
132
|
+
},
|
|
133
|
+
':SK': {
|
|
134
|
+
S: `${mutual.listEntitySK}#`,
|
|
135
|
+
},
|
|
136
|
+
':nullType': { S: 'NULL' },
|
|
153
137
|
},
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
138
|
+
ProjectionExpression: opts.ProjectionExpression,
|
|
139
|
+
ScanIndexForward: false,
|
|
140
|
+
};
|
|
141
|
+
let lastKey = opts.lastKey;
|
|
142
|
+
let items = [];
|
|
143
|
+
let remainingCount = (_a = opts.limit) !== null && _a !== void 0 ? _a : 0;
|
|
144
|
+
do {
|
|
145
|
+
const resp = yield this.dynamodbClient.query(Object.assign(Object.assign(Object.assign({}, listAssociationsQuery), (remainingCount && { Limit: remainingCount })), (lastKey && {
|
|
146
|
+
ExclusiveStartKey: fromLastKeyQuery(lastKey),
|
|
147
|
+
})));
|
|
148
|
+
items = items.concat(((_b = resp.Items) === null || _b === void 0 ? void 0 : _b.map((item) => Mutual.fromItem(item))) || []);
|
|
149
|
+
lastKey = toLastKeyResponse(resp.LastEvaluatedKey);
|
|
150
|
+
if (opts.limit) {
|
|
151
|
+
remainingCount = remainingCount - ((_d = (_c = resp.Items) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0);
|
|
152
|
+
}
|
|
153
|
+
} while (
|
|
154
|
+
// limit is given, haven't reach limit, and there are still items to retrieve
|
|
155
|
+
(opts.limit && remainingCount && lastKey) ||
|
|
156
|
+
// no limit is given and there are still items to retrieve
|
|
157
|
+
(!opts.limit && lastKey));
|
|
158
|
+
return {
|
|
159
|
+
items,
|
|
160
|
+
lastKey,
|
|
161
|
+
};
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
getMutual(byEntityType, byEntityId, entityType, entityId, opts) {
|
|
165
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
166
|
+
var _a, _b;
|
|
167
|
+
const mutual = new Mutual(byEntityType, byEntityId, {}, entityType, entityId, {}, {});
|
|
168
|
+
const resp = yield this.dynamodbClient.query({
|
|
169
|
+
TableName: this.TABLE_NAME,
|
|
170
|
+
KeyConditionExpression: '#PK = :PK and begins_with(#SK, :SK)',
|
|
171
|
+
FilterExpression: 'attribute_not_exists(#expiresAt) or attribute_type(#expiresAt, :nullType)',
|
|
172
|
+
ExpressionAttributeNames: {
|
|
173
|
+
'#PK': 'PK',
|
|
174
|
+
'#SK': 'SK',
|
|
175
|
+
'#expiresAt': 'expiresAt',
|
|
176
|
+
},
|
|
177
|
+
ExpressionAttributeValues: {
|
|
178
|
+
':PK': { S: mutual.byFullEntityId },
|
|
179
|
+
':SK': { S: mutual.fullEntityId },
|
|
180
|
+
':nullType': { S: 'NULL' },
|
|
181
|
+
},
|
|
182
|
+
Limit: 1,
|
|
168
183
|
});
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
184
|
+
let mutualMetadata = null;
|
|
185
|
+
if (opts === null || opts === void 0 ? void 0 : opts.isFromMetadata) {
|
|
186
|
+
const tempMutual = Mutual.fromItem((_a = resp.Items) === null || _a === void 0 ? void 0 : _a[0]);
|
|
187
|
+
const respMetadataMutual = yield this.dynamodbClient.getItem({
|
|
188
|
+
TableName: this.TABLE_NAME,
|
|
189
|
+
Key: tempMutual.mainKeys(),
|
|
190
|
+
ProjectionExpression: opts === null || opts === void 0 ? void 0 : opts.ProjectionExpression,
|
|
191
|
+
});
|
|
192
|
+
mutualMetadata = Mutual.fromItem(respMetadataMutual.Item);
|
|
173
193
|
}
|
|
174
|
-
|
|
175
|
-
// limit is given, haven't reach limit, and there are still items to retrieve
|
|
176
|
-
(opts.limit && remainingCount && lastKey) ||
|
|
177
|
-
// no limit is given and there are still items to retrieve
|
|
178
|
-
(!opts.limit && lastKey));
|
|
179
|
-
return {
|
|
180
|
-
items,
|
|
181
|
-
lastKey,
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
async getMutual(byEntityType, byEntityId, entityType, entityId, opts) {
|
|
185
|
-
const mutual = new Mutual(byEntityType, byEntityId, {}, entityType, entityId, {}, {});
|
|
186
|
-
const resp = await this.dynamodbClient.getItem({
|
|
187
|
-
TableName: this.TABLE_NAME,
|
|
188
|
-
Key: mutual.subKeys(),
|
|
189
|
-
ProjectionExpression: opts?.ProjectionExpression,
|
|
194
|
+
return mutualMetadata || Mutual.fromItem((_b = resp.Items) === null || _b === void 0 ? void 0 : _b[0]);
|
|
190
195
|
});
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
196
|
+
}
|
|
197
|
+
checkMutualExist(byEntityType, byEntityId, entityType, entityId) {
|
|
198
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
199
|
+
var _a;
|
|
200
|
+
const mutual = new Mutual(byEntityType, byEntityId, {}, entityType, entityId, {}, {});
|
|
201
|
+
const resp = yield this.dynamodbClient.getItem({
|
|
195
202
|
TableName: this.TABLE_NAME,
|
|
196
|
-
Key:
|
|
197
|
-
ProjectionExpression:
|
|
203
|
+
Key: mutual.subKeys(),
|
|
204
|
+
ProjectionExpression: 'PK, SK, expiresAt',
|
|
198
205
|
});
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
async checkMutualExist(byEntityType, byEntityId, entityType, entityId) {
|
|
204
|
-
const mutual = new Mutual(byEntityType, byEntityId, {}, entityType, entityId, {}, {});
|
|
205
|
-
const resp = await this.dynamodbClient.getItem({
|
|
206
|
-
TableName: this.TABLE_NAME,
|
|
207
|
-
Key: mutual.subKeys(),
|
|
208
|
-
ProjectionExpression: 'PK, SK, expiresAt',
|
|
206
|
+
if (resp.Item && !((_a = resp.Item) === null || _a === void 0 ? void 0 : _a.expiresAt)) {
|
|
207
|
+
throw new StandardError(StandardErrorCode.MUTUAL_EXISTS, 'Entities are already linked');
|
|
208
|
+
}
|
|
209
|
+
return;
|
|
209
210
|
});
|
|
210
|
-
if (resp.Item && !resp.Item?.expiresAt) {
|
|
211
|
-
throw new StandardError('MUTUAL_EXISTS', 'Entities are already linked');
|
|
212
|
-
}
|
|
213
|
-
return;
|
|
214
211
|
}
|
|
215
212
|
createMutualTransactItems(mutual, opts) {
|
|
216
213
|
const TransactItems = [
|
|
217
214
|
{
|
|
218
215
|
Put: {
|
|
219
216
|
TableName: this.TABLE_NAME,
|
|
220
|
-
ConditionExpression: opts
|
|
217
|
+
ConditionExpression: (opts === null || opts === void 0 ? void 0 : opts.ConditionExpression) ||
|
|
221
218
|
'attribute_not_exists(PK) OR attribute_exists(expiresAt)',
|
|
222
|
-
ExpressionAttributeNames: opts
|
|
223
|
-
ExpressionAttributeValues: opts
|
|
219
|
+
ExpressionAttributeNames: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames,
|
|
220
|
+
ExpressionAttributeValues: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues,
|
|
224
221
|
Item: mutual.toItem(),
|
|
225
222
|
},
|
|
226
223
|
},
|
|
227
224
|
{
|
|
228
225
|
Put: {
|
|
229
226
|
TableName: this.TABLE_NAME,
|
|
230
|
-
ConditionExpression: opts
|
|
227
|
+
ConditionExpression: (opts === null || opts === void 0 ? void 0 : opts.ConditionExpression) ||
|
|
231
228
|
'attribute_not_exists(PK) OR attribute_exists(expiresAt)',
|
|
232
|
-
ExpressionAttributeNames: opts
|
|
233
|
-
ExpressionAttributeValues: opts
|
|
234
|
-
Item: {
|
|
235
|
-
...mutual.toItem(),
|
|
236
|
-
PK: { S: mutual.byFullEntityId },
|
|
237
|
-
SK: { S: mutual.fullEntityId },
|
|
238
|
-
R1PK: { S: mutual.fullEntityId },
|
|
239
|
-
R1SK: { S: mutual.byFullEntityId },
|
|
240
|
-
R2PK: { S: mutual.mainPk },
|
|
241
|
-
R2SK: { S: mutual.byFullEntityId },
|
|
242
|
-
},
|
|
229
|
+
ExpressionAttributeNames: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames,
|
|
230
|
+
ExpressionAttributeValues: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues,
|
|
231
|
+
Item: Object.assign(Object.assign({}, mutual.toItem()), { PK: { S: mutual.byFullEntityId }, SK: { S: mutual.fullEntityId }, R1PK: { S: mutual.fullEntityId }, R1SK: { S: mutual.byFullEntityId }, R2PK: { S: mutual.mainPk }, R2SK: { S: mutual.byFullEntityId } }),
|
|
243
232
|
},
|
|
244
233
|
},
|
|
245
234
|
{
|
|
246
235
|
Put: {
|
|
247
236
|
TableName: this.TABLE_NAME,
|
|
248
|
-
ConditionExpression: opts
|
|
237
|
+
ConditionExpression: (opts === null || opts === void 0 ? void 0 : opts.ConditionExpression) ||
|
|
249
238
|
'attribute_not_exists(PK) OR attribute_exists(expiresAt)',
|
|
250
|
-
ExpressionAttributeNames: opts
|
|
251
|
-
ExpressionAttributeValues: opts
|
|
252
|
-
Item: {
|
|
253
|
-
...mutual.toReversedItem(),
|
|
254
|
-
PK: { S: mutual.fullEntityId },
|
|
255
|
-
SK: { S: mutual.byFullEntityId },
|
|
256
|
-
R1PK: { S: mutual.byFullEntityId },
|
|
257
|
-
R1SK: { S: mutual.fullEntityId },
|
|
258
|
-
R2PK: { S: mutual.mainPk },
|
|
259
|
-
R2SK: { S: mutual.fullEntityId },
|
|
260
|
-
},
|
|
239
|
+
ExpressionAttributeNames: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames,
|
|
240
|
+
ExpressionAttributeValues: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues,
|
|
241
|
+
Item: Object.assign(Object.assign({}, mutual.toReversedItem()), { PK: { S: mutual.fullEntityId }, SK: { S: mutual.byFullEntityId }, R1PK: { S: mutual.byFullEntityId }, R1SK: { S: mutual.fullEntityId }, R2PK: { S: mutual.mainPk }, R2SK: { S: mutual.fullEntityId } }),
|
|
261
242
|
},
|
|
262
243
|
},
|
|
263
244
|
];
|
|
264
245
|
return TransactItems;
|
|
265
246
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
247
|
+
createMutual(byEntityType_1, byEntityId_1, byData_1, entityType_1, entityId_1, data_1) {
|
|
248
|
+
return __awaiter(this, arguments, void 0, function* (byEntityType, byEntityId, byData, entityType, entityId, data, mutualData = {}, opts) {
|
|
249
|
+
const errorContext = {};
|
|
250
|
+
const currentDatetime = (opts === null || opts === void 0 ? void 0 : opts.createAndUpdateDatetime) || new Date();
|
|
251
|
+
const mutual = new Mutual(byEntityType, byEntityId, byData, entityType, entityId, data, mutualData, ulid(), currentDatetime, currentDatetime, currentDatetime);
|
|
252
|
+
const TransactItems = this.createMutualTransactItems(mutual, {
|
|
253
|
+
ConditionExpression: opts === null || opts === void 0 ? void 0 : opts.ConditionExpression,
|
|
254
|
+
ExpressionAttributeNames: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames,
|
|
255
|
+
ExpressionAttributeValues: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues,
|
|
256
|
+
});
|
|
257
|
+
errorContext.TransactItems = TransactItems;
|
|
258
|
+
yield this.dynamodbClient.transactWriteItems({ TransactItems });
|
|
259
|
+
return mutual;
|
|
274
260
|
});
|
|
275
|
-
errorContext.TransactItems = TransactItems;
|
|
276
|
-
await this.dynamodbClient.transactWriteItems({ TransactItems });
|
|
277
|
-
return mutual;
|
|
278
261
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
...toUpdateExpressions.ExpressionAttributeValues,
|
|
298
|
-
...opts?.ExpressionAttributeValues,
|
|
299
|
-
},
|
|
300
|
-
};
|
|
301
|
-
const TransactItems = [
|
|
302
|
-
{
|
|
303
|
-
Update: {
|
|
304
|
-
TableName: this.TABLE_NAME,
|
|
305
|
-
Key: mutual.mainKeys(),
|
|
306
|
-
...updateExpression,
|
|
262
|
+
updateMutual(byEntityType, byEntityId, entityType, entityId, toUpdate, opts) {
|
|
263
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
264
|
+
var _a;
|
|
265
|
+
const returnUpdatedValue = (_a = opts === null || opts === void 0 ? void 0 : opts.returnUpdatedValue) !== null && _a !== void 0 ? _a : false;
|
|
266
|
+
const errorContext = {};
|
|
267
|
+
try {
|
|
268
|
+
const mutual = yield this.getMutual(byEntityType, byEntityId, entityType, entityId, { ProjectionExpression: PROJECTION_EXPRESSION.NO_DATA });
|
|
269
|
+
const currentDatetime = new Date().toISOString();
|
|
270
|
+
const toUpdateExpressions = this.toUpdate(Object.assign({ mutualUpdatedAt: currentDatetime }, toUpdate), { maxLevel: opts === null || opts === void 0 ? void 0 : opts.maxObjectUpdateLevel });
|
|
271
|
+
const updateExpression = {
|
|
272
|
+
ConditionExpression: (opts === null || opts === void 0 ? void 0 : opts.ConditionExpression) || 'attribute_exists(PK)',
|
|
273
|
+
UpdateExpression: toUpdateExpressions.UpdateExpression,
|
|
274
|
+
ExpressionAttributeNames: Object.assign(Object.assign({}, toUpdateExpressions.ExpressionAttributeNames), opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames),
|
|
275
|
+
ExpressionAttributeValues: Object.assign(Object.assign({}, toUpdateExpressions.ExpressionAttributeValues), opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues),
|
|
276
|
+
};
|
|
277
|
+
const TransactItems = [
|
|
278
|
+
{
|
|
279
|
+
Update: Object.assign({ TableName: this.TABLE_NAME, Key: mutual.mainKeys() }, updateExpression),
|
|
307
280
|
},
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
PK: { S: mutual.byFullEntityId },
|
|
314
|
-
SK: { S: mutual.fullEntityId },
|
|
315
|
-
},
|
|
316
|
-
...updateExpression,
|
|
281
|
+
{
|
|
282
|
+
Update: Object.assign({ TableName: this.TABLE_NAME, Key: {
|
|
283
|
+
PK: { S: mutual.byFullEntityId },
|
|
284
|
+
SK: { S: mutual.fullEntityId },
|
|
285
|
+
} }, updateExpression),
|
|
317
286
|
},
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
PK: { S: mutual.fullEntityId },
|
|
324
|
-
SK: { S: mutual.byFullEntityId },
|
|
325
|
-
},
|
|
326
|
-
...updateExpression,
|
|
287
|
+
{
|
|
288
|
+
Update: Object.assign({ TableName: this.TABLE_NAME, Key: {
|
|
289
|
+
PK: { S: mutual.fullEntityId },
|
|
290
|
+
SK: { S: mutual.byFullEntityId },
|
|
291
|
+
} }, updateExpression),
|
|
327
292
|
},
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
293
|
+
];
|
|
294
|
+
errorContext.TransactItems = TransactItems;
|
|
295
|
+
yield this.ddbUtils.executeTransactWrite({ TransactItems });
|
|
296
|
+
if (!returnUpdatedValue) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
const updatedMutual = yield this.getMutual(byEntityType, byEntityId, entityType, entityId);
|
|
300
|
+
return updatedMutual;
|
|
334
301
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
});
|
|
302
|
+
catch (err) {
|
|
303
|
+
if (err instanceof StandardError &&
|
|
304
|
+
err.code === StandardErrorCode.CONDITIONAL_CHECK_FAILED) {
|
|
305
|
+
throw new StandardError(StandardErrorCode.MUTUAL_NOT_FOUND, 'Mutual not found', err, {
|
|
306
|
+
errorContext,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
throw err;
|
|
344
310
|
}
|
|
345
|
-
|
|
346
|
-
}
|
|
311
|
+
});
|
|
347
312
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const mutual = await this.getMutual(byEntityType, byEntityId, entityType, entityId, { ProjectionExpression: PROJECTION_EXPRESSION.NO_DATA });
|
|
357
|
-
const tenMinsLater = Math.floor(new Date().getTime() / 1000 + 10 * 60);
|
|
358
|
-
const expressions = {
|
|
359
|
-
UpdateExpression: 'SET #expiresAt = :expiresAt, #mutualUpdatedAt = :mutualUpdatedAt, #updatedAt = :mutualUpdatedAt',
|
|
360
|
-
ConditionExpression: opts?.ConditionExpression ||
|
|
361
|
-
'attribute_exists(PK) AND attribute_not_exists(#expiresAt)',
|
|
362
|
-
ExpressionAttributeNames: {
|
|
363
|
-
'#expiresAt': 'expiresAt',
|
|
364
|
-
'#mutualUpdatedAt': 'mutualUpdatedAt',
|
|
365
|
-
'#updatedAt': 'updatedAt',
|
|
366
|
-
...opts?.ExpressionAttributeNames,
|
|
367
|
-
},
|
|
368
|
-
ExpressionAttributeValues: {
|
|
369
|
-
':expiresAt': { N: String(tenMinsLater) },
|
|
370
|
-
':mutualUpdatedAt': { S: new Date().toISOString() },
|
|
371
|
-
...opts?.ExpressionAttributeValues,
|
|
372
|
-
},
|
|
313
|
+
deleteMutual(byEntityType, byEntityId, entityType, entityId, opts) {
|
|
314
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
315
|
+
var _a;
|
|
316
|
+
const errorContext = {
|
|
317
|
+
byEntityType,
|
|
318
|
+
byEntityId,
|
|
319
|
+
entityType,
|
|
320
|
+
entityId,
|
|
373
321
|
};
|
|
374
|
-
|
|
375
|
-
{
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
322
|
+
try {
|
|
323
|
+
const mutual = yield this.getMutual(byEntityType, byEntityId, entityType, entityId, { ProjectionExpression: PROJECTION_EXPRESSION.NO_DATA });
|
|
324
|
+
const tenMinsLater = Math.floor(new Date().getTime() / 1000 + 10 * 60);
|
|
325
|
+
const expressions = {
|
|
326
|
+
UpdateExpression: 'SET #expiresAt = :expiresAt, #mutualUpdatedAt = :mutualUpdatedAt, #updatedAt = :mutualUpdatedAt',
|
|
327
|
+
ConditionExpression: (opts === null || opts === void 0 ? void 0 : opts.ConditionExpression) ||
|
|
328
|
+
'attribute_exists(PK) AND attribute_not_exists(#expiresAt)',
|
|
329
|
+
ExpressionAttributeNames: Object.assign({ '#expiresAt': 'expiresAt', '#mutualUpdatedAt': 'mutualUpdatedAt', '#updatedAt': 'updatedAt' }, opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames),
|
|
330
|
+
ExpressionAttributeValues: Object.assign({ ':expiresAt': { N: String(tenMinsLater) }, ':mutualUpdatedAt': { S: new Date().toISOString() } }, opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues),
|
|
331
|
+
};
|
|
332
|
+
const TransactItems = [
|
|
333
|
+
{
|
|
334
|
+
Update: Object.assign({ TableName: this.TABLE_NAME, Key: mutual.mainKeys() }, expressions),
|
|
380
335
|
},
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
PK: { S: mutual.byFullEntityId },
|
|
387
|
-
SK: { S: mutual.fullEntityId },
|
|
388
|
-
},
|
|
389
|
-
...expressions,
|
|
336
|
+
{
|
|
337
|
+
Update: Object.assign({ TableName: this.TABLE_NAME, Key: {
|
|
338
|
+
PK: { S: mutual.byFullEntityId },
|
|
339
|
+
SK: { S: mutual.fullEntityId },
|
|
340
|
+
} }, expressions),
|
|
390
341
|
},
|
|
342
|
+
{
|
|
343
|
+
Update: Object.assign({ TableName: this.TABLE_NAME, Key: {
|
|
344
|
+
PK: { S: mutual.fullEntityId },
|
|
345
|
+
SK: { S: mutual.byFullEntityId },
|
|
346
|
+
} }, expressions),
|
|
347
|
+
},
|
|
348
|
+
];
|
|
349
|
+
errorContext.TransactItems = TransactItems;
|
|
350
|
+
yield this.dynamodbClient.transactWriteItems({ TransactItems });
|
|
351
|
+
return mutual;
|
|
352
|
+
}
|
|
353
|
+
catch (err) {
|
|
354
|
+
const isConditionalCheckFailed = err instanceof TransactionCanceledException &&
|
|
355
|
+
((_a = err.CancellationReasons) === null || _a === void 0 ? void 0 : _a.some((reason) => reason.Code === BatchStatementErrorCodeEnum.ConditionalCheckFailed));
|
|
356
|
+
const isMutualIsUndefined = err instanceof StandardError &&
|
|
357
|
+
err.code === StandardErrorCode.MUTUAL_IS_UNDEFINED;
|
|
358
|
+
if (isConditionalCheckFailed || isMutualIsUndefined) {
|
|
359
|
+
throw new StandardError(StandardErrorCode.MUTUAL_NOT_FOUND, 'Mutual not found', err, {
|
|
360
|
+
errorContext,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
throw err;
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
createMutualLock(_a) {
|
|
368
|
+
return __awaiter(this, arguments, void 0, function* ({ byEntityType, byEntityId, entityType, version, }) {
|
|
369
|
+
var _b, _c, _d;
|
|
370
|
+
let retryCount = 2;
|
|
371
|
+
const itemKey = {
|
|
372
|
+
PK: {
|
|
373
|
+
S: `MUTUAL#${byEntityType}#${byEntityId}#${entityType}`,
|
|
391
374
|
},
|
|
392
|
-
{
|
|
393
|
-
|
|
375
|
+
SK: { S: '#LOCK#' },
|
|
376
|
+
};
|
|
377
|
+
do {
|
|
378
|
+
try {
|
|
379
|
+
const fiveMinsLater = Math.floor(new Date().getTime() / 1000 + 5 * 60);
|
|
380
|
+
yield this.dynamodbClient.putItem({
|
|
394
381
|
TableName: this.TABLE_NAME,
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
382
|
+
Item: Object.assign(Object.assign({}, itemKey), { version: { S: version }, status: { S: 'LOCK' }, expiresAt: {
|
|
383
|
+
// auto release lock in case the mutual logic gone wrong to prevent dead lock
|
|
384
|
+
N: `${fiveMinsLater}`,
|
|
385
|
+
} }),
|
|
386
|
+
ConditionExpression: 'attribute_not_exists(PK) OR version < :version AND #status <> :status',
|
|
387
|
+
ExpressionAttributeNames: { '#status': 'status' },
|
|
388
|
+
ExpressionAttributeValues: {
|
|
389
|
+
':version': { S: version },
|
|
390
|
+
':status': { S: 'LOCK' },
|
|
398
391
|
},
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
392
|
+
});
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
catch (err) {
|
|
396
|
+
console.log('=====CATCHED_MUTUAL_LOCK_CONFLICT=====');
|
|
397
|
+
const lock = yield this.dynamodbClient.getItem({
|
|
398
|
+
TableName: this.TABLE_NAME,
|
|
399
|
+
Key: itemKey,
|
|
400
|
+
});
|
|
401
|
+
// if version is lower, throw not retryable error to skip
|
|
402
|
+
const existingVersion = (_d = (_c = (_b = lock.Item) === null || _b === void 0 ? void 0 : _b.version) === null || _c === void 0 ? void 0 : _c.S) !== null && _d !== void 0 ? _d : '';
|
|
403
|
+
const isExistingVersionGreaterThanNewVersion = existingVersion >= version;
|
|
404
|
+
if (isExistingVersionGreaterThanNewVersion) {
|
|
405
|
+
throw new StandardError(StandardErrorCode.MUTUAL_LOCK_CONFLICT, 'Lock conflict', err, { lock: lock.Item });
|
|
406
|
+
}
|
|
407
|
+
// default behaviour
|
|
408
|
+
// if version is higher, retry
|
|
409
|
+
// if lock not found, retry
|
|
410
|
+
yield sleep(2000);
|
|
411
|
+
console.log('=====RETRY_MUTUAL_LOCK=====');
|
|
412
|
+
}
|
|
413
|
+
} while (retryCount-- > 0);
|
|
414
|
+
// catch real unhandled error, so it can reach DLQ for inspection
|
|
415
|
+
throw new StandardError(StandardErrorCode.RETRYABLE_MUTUAL_LOCK_CONFLICT, 'Retryable lock conflict');
|
|
416
|
+
});
|
|
418
417
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
const itemKey = {
|
|
422
|
-
PK: {
|
|
423
|
-
S: `MUTUAL#${byEntityType}#${byEntityId}#${entityType}`,
|
|
424
|
-
},
|
|
425
|
-
SK: { S: '#LOCK#' },
|
|
426
|
-
};
|
|
427
|
-
do {
|
|
418
|
+
deleteMutualLock(_a) {
|
|
419
|
+
return __awaiter(this, arguments, void 0, function* ({ byEntityType, byEntityId, entityType, }) {
|
|
428
420
|
try {
|
|
429
|
-
|
|
430
|
-
await this.dynamodbClient.putItem({
|
|
421
|
+
yield this.dynamodbClient.updateItem({
|
|
431
422
|
TableName: this.TABLE_NAME,
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
status: { S: 'LOCK' },
|
|
436
|
-
expiresAt: {
|
|
437
|
-
// auto release lock in case the mutual logic gone wrong to prevent dead lock
|
|
438
|
-
N: `${fiveMinsLater}`,
|
|
423
|
+
Key: {
|
|
424
|
+
PK: {
|
|
425
|
+
S: `MUTUAL#${byEntityType}#${byEntityId}#${entityType}`,
|
|
439
426
|
},
|
|
427
|
+
SK: { S: '#LOCK#' },
|
|
440
428
|
},
|
|
441
|
-
|
|
429
|
+
UpdateExpression: 'REMOVE #status',
|
|
442
430
|
ExpressionAttributeNames: { '#status': 'status' },
|
|
443
|
-
ExpressionAttributeValues: {
|
|
444
|
-
':version': { S: version },
|
|
445
|
-
':status': { S: 'LOCK' },
|
|
446
|
-
},
|
|
447
431
|
});
|
|
448
432
|
return;
|
|
449
433
|
}
|
|
450
|
-
catch (
|
|
451
|
-
|
|
452
|
-
const lock = await this.dynamodbClient.getItem({
|
|
453
|
-
TableName: this.TABLE_NAME,
|
|
454
|
-
Key: itemKey,
|
|
455
|
-
});
|
|
456
|
-
// if version is lower, throw not retryable error to skip
|
|
457
|
-
const existingVersion = lock.Item?.version?.S ?? '';
|
|
458
|
-
const isExistingVersionGreaterThanNewVersion = existingVersion >= version;
|
|
459
|
-
if (isExistingVersionGreaterThanNewVersion) {
|
|
460
|
-
throw new StandardError('MUTUAL_LOCK_CONFLICT', 'Lock conflict', err, { lock: lock.Item });
|
|
461
|
-
}
|
|
462
|
-
// default behaviour
|
|
463
|
-
// if version is higher, retry
|
|
464
|
-
// if lock not found, retry
|
|
465
|
-
await sleep(2000);
|
|
466
|
-
console.log('=====RETRY_MUTUAL_LOCK=====');
|
|
434
|
+
catch (error) {
|
|
435
|
+
// if lock is not found, it's okay
|
|
467
436
|
}
|
|
468
|
-
}
|
|
469
|
-
// catch real unhandled error, so it can reach DLQ for inspection
|
|
470
|
-
throw new StandardError('RETRYABLE_MUTUAL_LOCK_CONFLICT', 'Retryable lock conflict');
|
|
471
|
-
}
|
|
472
|
-
async deleteMutualLock({ byEntityType, byEntityId, entityType, }) {
|
|
473
|
-
try {
|
|
474
|
-
await this.dynamodbClient.updateItem({
|
|
475
|
-
TableName: this.TABLE_NAME,
|
|
476
|
-
Key: {
|
|
477
|
-
PK: {
|
|
478
|
-
S: `MUTUAL#${byEntityType}#${byEntityId}#${entityType}`,
|
|
479
|
-
},
|
|
480
|
-
SK: { S: '#LOCK#' },
|
|
481
|
-
},
|
|
482
|
-
UpdateExpression: 'REMOVE #status',
|
|
483
|
-
ExpressionAttributeNames: { '#status': 'status' },
|
|
484
|
-
});
|
|
485
|
-
return;
|
|
486
|
-
}
|
|
487
|
-
catch (error) {
|
|
488
|
-
// if lock is not found, it's okay
|
|
489
|
-
}
|
|
437
|
+
});
|
|
490
438
|
}
|
|
491
439
|
}
|
|
492
440
|
//# sourceMappingURL=Mutual.js.map
|