@monorise/core 1.0.4-7 → 3.0.0
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 +288 -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,333 @@ 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
|
+
};
|
|
140
|
+
let lastKey = opts.lastKey;
|
|
141
|
+
let items = [];
|
|
142
|
+
let remainingCount = (_a = opts.limit) !== null && _a !== void 0 ? _a : 0;
|
|
143
|
+
do {
|
|
144
|
+
const resp = yield this.dynamodbClient.query(Object.assign(Object.assign(Object.assign({}, listAssociationsQuery), (remainingCount && { Limit: remainingCount })), (lastKey && {
|
|
145
|
+
ExclusiveStartKey: fromLastKeyQuery(lastKey),
|
|
146
|
+
})));
|
|
147
|
+
items = items.concat(((_b = resp.Items) === null || _b === void 0 ? void 0 : _b.map((item) => Mutual.fromItem(item))) || []);
|
|
148
|
+
lastKey = toLastKeyResponse(resp.LastEvaluatedKey);
|
|
149
|
+
if (opts.limit) {
|
|
150
|
+
remainingCount = remainingCount - ((_d = (_c = resp.Items) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0);
|
|
151
|
+
}
|
|
152
|
+
} while (
|
|
153
|
+
// limit is given, haven't reach limit, and there are still items to retrieve
|
|
154
|
+
(opts.limit && remainingCount && lastKey) ||
|
|
155
|
+
// no limit is given and there are still items to retrieve
|
|
156
|
+
(!opts.limit && lastKey));
|
|
157
|
+
return {
|
|
158
|
+
items,
|
|
159
|
+
lastKey,
|
|
160
|
+
};
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
getMutual(byEntityType, byEntityId, entityType, entityId, opts) {
|
|
164
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
165
|
+
var _a, _b;
|
|
166
|
+
const mutual = new Mutual(byEntityType, byEntityId, {}, entityType, entityId, {}, {});
|
|
167
|
+
const resp = yield this.dynamodbClient.query({
|
|
168
|
+
TableName: this.TABLE_NAME,
|
|
169
|
+
KeyConditionExpression: '#PK = :PK and begins_with(#SK, :SK)',
|
|
170
|
+
FilterExpression: 'attribute_not_exists(#expiresAt) or attribute_type(#expiresAt, :nullType)',
|
|
171
|
+
ExpressionAttributeNames: {
|
|
172
|
+
'#PK': 'PK',
|
|
173
|
+
'#SK': 'SK',
|
|
174
|
+
'#expiresAt': 'expiresAt',
|
|
175
|
+
},
|
|
176
|
+
ExpressionAttributeValues: {
|
|
177
|
+
':PK': { S: mutual.byFullEntityId },
|
|
178
|
+
':SK': { S: mutual.fullEntityId },
|
|
179
|
+
':nullType': { S: 'NULL' },
|
|
180
|
+
},
|
|
181
|
+
Limit: 1,
|
|
168
182
|
});
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
183
|
+
let mutualMetadata = null;
|
|
184
|
+
if (opts === null || opts === void 0 ? void 0 : opts.isFromMetadata) {
|
|
185
|
+
const tempMutual = Mutual.fromItem((_a = resp.Items) === null || _a === void 0 ? void 0 : _a[0]);
|
|
186
|
+
const respMetadataMutual = yield this.dynamodbClient.getItem({
|
|
187
|
+
TableName: this.TABLE_NAME,
|
|
188
|
+
Key: tempMutual.mainKeys(),
|
|
189
|
+
ProjectionExpression: opts === null || opts === void 0 ? void 0 : opts.ProjectionExpression,
|
|
190
|
+
});
|
|
191
|
+
mutualMetadata = Mutual.fromItem(respMetadataMutual.Item);
|
|
173
192
|
}
|
|
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,
|
|
193
|
+
return mutualMetadata || Mutual.fromItem((_b = resp.Items) === null || _b === void 0 ? void 0 : _b[0]);
|
|
190
194
|
});
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
+
}
|
|
196
|
+
checkMutualExist(byEntityType, byEntityId, entityType, entityId) {
|
|
197
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
198
|
+
var _a;
|
|
199
|
+
const mutual = new Mutual(byEntityType, byEntityId, {}, entityType, entityId, {}, {});
|
|
200
|
+
const resp = yield this.dynamodbClient.getItem({
|
|
195
201
|
TableName: this.TABLE_NAME,
|
|
196
|
-
Key:
|
|
197
|
-
ProjectionExpression:
|
|
202
|
+
Key: mutual.subKeys(),
|
|
203
|
+
ProjectionExpression: 'PK, SK, expiresAt',
|
|
198
204
|
});
|
|
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',
|
|
205
|
+
if (resp.Item && !((_a = resp.Item) === null || _a === void 0 ? void 0 : _a.expiresAt)) {
|
|
206
|
+
throw new StandardError(StandardErrorCode.MUTUAL_EXISTS, 'Entities are already linked');
|
|
207
|
+
}
|
|
208
|
+
return;
|
|
209
209
|
});
|
|
210
|
-
if (resp.Item && !resp.Item?.expiresAt) {
|
|
211
|
-
throw new StandardError('MUTUAL_EXISTS', 'Entities are already linked');
|
|
212
|
-
}
|
|
213
|
-
return;
|
|
214
210
|
}
|
|
215
211
|
createMutualTransactItems(mutual, opts) {
|
|
216
212
|
const TransactItems = [
|
|
217
213
|
{
|
|
218
214
|
Put: {
|
|
219
215
|
TableName: this.TABLE_NAME,
|
|
220
|
-
ConditionExpression: opts
|
|
216
|
+
ConditionExpression: (opts === null || opts === void 0 ? void 0 : opts.ConditionExpression) ||
|
|
221
217
|
'attribute_not_exists(PK) OR attribute_exists(expiresAt)',
|
|
222
|
-
ExpressionAttributeNames: opts
|
|
223
|
-
ExpressionAttributeValues: opts
|
|
218
|
+
ExpressionAttributeNames: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames,
|
|
219
|
+
ExpressionAttributeValues: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues,
|
|
224
220
|
Item: mutual.toItem(),
|
|
225
221
|
},
|
|
226
222
|
},
|
|
227
223
|
{
|
|
228
224
|
Put: {
|
|
229
225
|
TableName: this.TABLE_NAME,
|
|
230
|
-
ConditionExpression: opts
|
|
226
|
+
ConditionExpression: (opts === null || opts === void 0 ? void 0 : opts.ConditionExpression) ||
|
|
231
227
|
'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
|
-
},
|
|
228
|
+
ExpressionAttributeNames: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames,
|
|
229
|
+
ExpressionAttributeValues: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues,
|
|
230
|
+
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
231
|
},
|
|
244
232
|
},
|
|
245
233
|
{
|
|
246
234
|
Put: {
|
|
247
235
|
TableName: this.TABLE_NAME,
|
|
248
|
-
ConditionExpression: opts
|
|
236
|
+
ConditionExpression: (opts === null || opts === void 0 ? void 0 : opts.ConditionExpression) ||
|
|
249
237
|
'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
|
-
},
|
|
238
|
+
ExpressionAttributeNames: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames,
|
|
239
|
+
ExpressionAttributeValues: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues,
|
|
240
|
+
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
241
|
},
|
|
262
242
|
},
|
|
263
243
|
];
|
|
264
244
|
return TransactItems;
|
|
265
245
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
246
|
+
createMutual(byEntityType_1, byEntityId_1, byData_1, entityType_1, entityId_1, data_1) {
|
|
247
|
+
return __awaiter(this, arguments, void 0, function* (byEntityType, byEntityId, byData, entityType, entityId, data, mutualData = {}, opts) {
|
|
248
|
+
const errorContext = {};
|
|
249
|
+
const currentDatetime = (opts === null || opts === void 0 ? void 0 : opts.createAndUpdateDatetime) || new Date();
|
|
250
|
+
const mutual = new Mutual(byEntityType, byEntityId, byData, entityType, entityId, data, mutualData, ulid(), currentDatetime, currentDatetime, currentDatetime);
|
|
251
|
+
const TransactItems = this.createMutualTransactItems(mutual, {
|
|
252
|
+
ConditionExpression: opts === null || opts === void 0 ? void 0 : opts.ConditionExpression,
|
|
253
|
+
ExpressionAttributeNames: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames,
|
|
254
|
+
ExpressionAttributeValues: opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues,
|
|
255
|
+
});
|
|
256
|
+
errorContext.TransactItems = TransactItems;
|
|
257
|
+
yield this.dynamodbClient.transactWriteItems({ TransactItems });
|
|
258
|
+
return mutual;
|
|
274
259
|
});
|
|
275
|
-
errorContext.TransactItems = TransactItems;
|
|
276
|
-
await this.dynamodbClient.transactWriteItems({ TransactItems });
|
|
277
|
-
return mutual;
|
|
278
260
|
}
|
|
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,
|
|
261
|
+
updateMutual(byEntityType, byEntityId, entityType, entityId, toUpdate, opts) {
|
|
262
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
263
|
+
var _a;
|
|
264
|
+
const returnUpdatedValue = (_a = opts === null || opts === void 0 ? void 0 : opts.returnUpdatedValue) !== null && _a !== void 0 ? _a : false;
|
|
265
|
+
const errorContext = {};
|
|
266
|
+
try {
|
|
267
|
+
const mutual = yield this.getMutual(byEntityType, byEntityId, entityType, entityId, { ProjectionExpression: PROJECTION_EXPRESSION.NO_DATA });
|
|
268
|
+
const currentDatetime = new Date().toISOString();
|
|
269
|
+
const toUpdateExpressions = this.toUpdate(Object.assign({ mutualUpdatedAt: currentDatetime }, toUpdate), { maxLevel: opts === null || opts === void 0 ? void 0 : opts.maxObjectUpdateLevel });
|
|
270
|
+
const updateExpression = {
|
|
271
|
+
ConditionExpression: (opts === null || opts === void 0 ? void 0 : opts.ConditionExpression) || 'attribute_exists(PK)',
|
|
272
|
+
UpdateExpression: toUpdateExpressions.UpdateExpression,
|
|
273
|
+
ExpressionAttributeNames: Object.assign(Object.assign({}, toUpdateExpressions.ExpressionAttributeNames), opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames),
|
|
274
|
+
ExpressionAttributeValues: Object.assign(Object.assign({}, toUpdateExpressions.ExpressionAttributeValues), opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues),
|
|
275
|
+
};
|
|
276
|
+
const TransactItems = [
|
|
277
|
+
{
|
|
278
|
+
Update: Object.assign({ TableName: this.TABLE_NAME, Key: mutual.mainKeys() }, updateExpression),
|
|
307
279
|
},
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
PK: { S: mutual.byFullEntityId },
|
|
314
|
-
SK: { S: mutual.fullEntityId },
|
|
315
|
-
},
|
|
316
|
-
...updateExpression,
|
|
280
|
+
{
|
|
281
|
+
Update: Object.assign({ TableName: this.TABLE_NAME, Key: {
|
|
282
|
+
PK: { S: mutual.byFullEntityId },
|
|
283
|
+
SK: { S: mutual.fullEntityId },
|
|
284
|
+
} }, updateExpression),
|
|
317
285
|
},
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
PK: { S: mutual.fullEntityId },
|
|
324
|
-
SK: { S: mutual.byFullEntityId },
|
|
325
|
-
},
|
|
326
|
-
...updateExpression,
|
|
286
|
+
{
|
|
287
|
+
Update: Object.assign({ TableName: this.TABLE_NAME, Key: {
|
|
288
|
+
PK: { S: mutual.fullEntityId },
|
|
289
|
+
SK: { S: mutual.byFullEntityId },
|
|
290
|
+
} }, updateExpression),
|
|
327
291
|
},
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
292
|
+
];
|
|
293
|
+
errorContext.TransactItems = TransactItems;
|
|
294
|
+
yield this.ddbUtils.executeTransactWrite({ TransactItems });
|
|
295
|
+
if (!returnUpdatedValue) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
const updatedMutual = yield this.getMutual(byEntityType, byEntityId, entityType, entityId);
|
|
299
|
+
return updatedMutual;
|
|
334
300
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
});
|
|
301
|
+
catch (err) {
|
|
302
|
+
if (err instanceof StandardError &&
|
|
303
|
+
err.code === StandardErrorCode.CONDITIONAL_CHECK_FAILED) {
|
|
304
|
+
throw new StandardError(StandardErrorCode.MUTUAL_NOT_FOUND, 'Mutual not found', err, {
|
|
305
|
+
errorContext,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
throw err;
|
|
344
309
|
}
|
|
345
|
-
|
|
346
|
-
}
|
|
310
|
+
});
|
|
347
311
|
}
|
|
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
|
-
},
|
|
312
|
+
deleteMutual(byEntityType, byEntityId, entityType, entityId, opts) {
|
|
313
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
314
|
+
var _a;
|
|
315
|
+
const errorContext = {
|
|
316
|
+
byEntityType,
|
|
317
|
+
byEntityId,
|
|
318
|
+
entityType,
|
|
319
|
+
entityId,
|
|
373
320
|
};
|
|
374
|
-
|
|
375
|
-
{
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
321
|
+
try {
|
|
322
|
+
const mutual = yield this.getMutual(byEntityType, byEntityId, entityType, entityId, { ProjectionExpression: PROJECTION_EXPRESSION.NO_DATA });
|
|
323
|
+
const tenMinsLater = Math.floor(new Date().getTime() / 1000 + 10 * 60);
|
|
324
|
+
const expressions = {
|
|
325
|
+
UpdateExpression: 'SET #expiresAt = :expiresAt, #mutualUpdatedAt = :mutualUpdatedAt, #updatedAt = :mutualUpdatedAt',
|
|
326
|
+
ConditionExpression: (opts === null || opts === void 0 ? void 0 : opts.ConditionExpression) ||
|
|
327
|
+
'attribute_exists(PK) AND attribute_not_exists(#expiresAt)',
|
|
328
|
+
ExpressionAttributeNames: Object.assign({ '#expiresAt': 'expiresAt', '#mutualUpdatedAt': 'mutualUpdatedAt', '#updatedAt': 'updatedAt' }, opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeNames),
|
|
329
|
+
ExpressionAttributeValues: Object.assign({ ':expiresAt': { N: String(tenMinsLater) }, ':mutualUpdatedAt': { S: new Date().toISOString() } }, opts === null || opts === void 0 ? void 0 : opts.ExpressionAttributeValues),
|
|
330
|
+
};
|
|
331
|
+
const TransactItems = [
|
|
332
|
+
{
|
|
333
|
+
Update: Object.assign({ TableName: this.TABLE_NAME, Key: mutual.mainKeys() }, expressions),
|
|
380
334
|
},
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
PK: { S: mutual.byFullEntityId },
|
|
387
|
-
SK: { S: mutual.fullEntityId },
|
|
388
|
-
},
|
|
389
|
-
...expressions,
|
|
335
|
+
{
|
|
336
|
+
Update: Object.assign({ TableName: this.TABLE_NAME, Key: {
|
|
337
|
+
PK: { S: mutual.byFullEntityId },
|
|
338
|
+
SK: { S: mutual.fullEntityId },
|
|
339
|
+
} }, expressions),
|
|
390
340
|
},
|
|
341
|
+
{
|
|
342
|
+
Update: Object.assign({ TableName: this.TABLE_NAME, Key: {
|
|
343
|
+
PK: { S: mutual.fullEntityId },
|
|
344
|
+
SK: { S: mutual.byFullEntityId },
|
|
345
|
+
} }, expressions),
|
|
346
|
+
},
|
|
347
|
+
];
|
|
348
|
+
errorContext.TransactItems = TransactItems;
|
|
349
|
+
yield this.dynamodbClient.transactWriteItems({ TransactItems });
|
|
350
|
+
return mutual;
|
|
351
|
+
}
|
|
352
|
+
catch (err) {
|
|
353
|
+
const isConditionalCheckFailed = err instanceof TransactionCanceledException &&
|
|
354
|
+
((_a = err.CancellationReasons) === null || _a === void 0 ? void 0 : _a.some((reason) => reason.Code === BatchStatementErrorCodeEnum.ConditionalCheckFailed));
|
|
355
|
+
const isMutualIsUndefined = err instanceof StandardError &&
|
|
356
|
+
err.code === StandardErrorCode.MUTUAL_IS_UNDEFINED;
|
|
357
|
+
if (isConditionalCheckFailed || isMutualIsUndefined) {
|
|
358
|
+
throw new StandardError(StandardErrorCode.MUTUAL_NOT_FOUND, 'Mutual not found', err, {
|
|
359
|
+
errorContext,
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
throw err;
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
createMutualLock(_a) {
|
|
367
|
+
return __awaiter(this, arguments, void 0, function* ({ byEntityType, byEntityId, entityType, version, }) {
|
|
368
|
+
var _b, _c, _d;
|
|
369
|
+
let retryCount = 2;
|
|
370
|
+
const itemKey = {
|
|
371
|
+
PK: {
|
|
372
|
+
S: `MUTUAL#${byEntityType}#${byEntityId}#${entityType}`,
|
|
391
373
|
},
|
|
392
|
-
{
|
|
393
|
-
|
|
374
|
+
SK: { S: '#LOCK#' },
|
|
375
|
+
};
|
|
376
|
+
do {
|
|
377
|
+
try {
|
|
378
|
+
const fiveMinsLater = Math.floor(new Date().getTime() / 1000 + 5 * 60);
|
|
379
|
+
yield this.dynamodbClient.putItem({
|
|
394
380
|
TableName: this.TABLE_NAME,
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
381
|
+
Item: Object.assign(Object.assign({}, itemKey), { version: { S: version }, status: { S: 'LOCK' }, expiresAt: {
|
|
382
|
+
// auto release lock in case the mutual logic gone wrong to prevent dead lock
|
|
383
|
+
N: `${fiveMinsLater}`,
|
|
384
|
+
} }),
|
|
385
|
+
ConditionExpression: 'attribute_not_exists(PK) OR version < :version AND #status <> :status',
|
|
386
|
+
ExpressionAttributeNames: { '#status': 'status' },
|
|
387
|
+
ExpressionAttributeValues: {
|
|
388
|
+
':version': { S: version },
|
|
389
|
+
':status': { S: 'LOCK' },
|
|
398
390
|
},
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
391
|
+
});
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
catch (err) {
|
|
395
|
+
console.log('=====CATCHED_MUTUAL_LOCK_CONFLICT=====');
|
|
396
|
+
const lock = yield this.dynamodbClient.getItem({
|
|
397
|
+
TableName: this.TABLE_NAME,
|
|
398
|
+
Key: itemKey,
|
|
399
|
+
});
|
|
400
|
+
// if version is lower, throw not retryable error to skip
|
|
401
|
+
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 : '';
|
|
402
|
+
const isExistingVersionGreaterThanNewVersion = existingVersion >= version;
|
|
403
|
+
if (isExistingVersionGreaterThanNewVersion) {
|
|
404
|
+
throw new StandardError(StandardErrorCode.MUTUAL_LOCK_CONFLICT, 'Lock conflict', err, { lock: lock.Item });
|
|
405
|
+
}
|
|
406
|
+
// default behaviour
|
|
407
|
+
// if version is higher, retry
|
|
408
|
+
// if lock not found, retry
|
|
409
|
+
yield sleep(2000);
|
|
410
|
+
console.log('=====RETRY_MUTUAL_LOCK=====');
|
|
411
|
+
}
|
|
412
|
+
} while (retryCount-- > 0);
|
|
413
|
+
// catch real unhandled error, so it can reach DLQ for inspection
|
|
414
|
+
throw new StandardError(StandardErrorCode.RETRYABLE_MUTUAL_LOCK_CONFLICT, 'Retryable lock conflict');
|
|
415
|
+
});
|
|
418
416
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
const itemKey = {
|
|
422
|
-
PK: {
|
|
423
|
-
S: `MUTUAL#${byEntityType}#${byEntityId}#${entityType}`,
|
|
424
|
-
},
|
|
425
|
-
SK: { S: '#LOCK#' },
|
|
426
|
-
};
|
|
427
|
-
do {
|
|
417
|
+
deleteMutualLock(_a) {
|
|
418
|
+
return __awaiter(this, arguments, void 0, function* ({ byEntityType, byEntityId, entityType, }) {
|
|
428
419
|
try {
|
|
429
|
-
|
|
430
|
-
await this.dynamodbClient.putItem({
|
|
420
|
+
yield this.dynamodbClient.updateItem({
|
|
431
421
|
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}`,
|
|
422
|
+
Key: {
|
|
423
|
+
PK: {
|
|
424
|
+
S: `MUTUAL#${byEntityType}#${byEntityId}#${entityType}`,
|
|
439
425
|
},
|
|
426
|
+
SK: { S: '#LOCK#' },
|
|
440
427
|
},
|
|
441
|
-
|
|
428
|
+
UpdateExpression: 'REMOVE #status',
|
|
442
429
|
ExpressionAttributeNames: { '#status': 'status' },
|
|
443
|
-
ExpressionAttributeValues: {
|
|
444
|
-
':version': { S: version },
|
|
445
|
-
':status': { S: 'LOCK' },
|
|
446
|
-
},
|
|
447
430
|
});
|
|
448
431
|
return;
|
|
449
432
|
}
|
|
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=====');
|
|
433
|
+
catch (error) {
|
|
434
|
+
// if lock is not found, it's okay
|
|
467
435
|
}
|
|
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
|
-
}
|
|
436
|
+
});
|
|
490
437
|
}
|
|
491
438
|
}
|
|
492
439
|
//# sourceMappingURL=Mutual.js.map
|