electrodb 2.4.1 → 2.5.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/index.d.ts +218 -2
- package/index.js +3 -0
- package/package.json +1 -1
- package/src/clauses.js +143 -36
- package/src/client.js +137 -4
- package/src/entity.js +105 -23
- package/src/filters.js +3 -3
- package/src/service.js +67 -38
- package/src/transaction.js +179 -0
- package/src/types.js +26 -0
- package/src/where.js +4 -3
- package/notes +0 -8
package/src/client.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
const lib = require('@aws-sdk/lib-dynamodb')
|
|
2
|
+
const util = require('@aws-sdk/lib-dynamodb/dist-cjs/commands/utils')
|
|
2
3
|
const { isFunction } = require('./validations');
|
|
3
4
|
const { ElectroError, ErrorCodes } = require('./errors');
|
|
4
|
-
|
|
5
5
|
const DocumentClientVersions = {
|
|
6
6
|
v2: 'v2',
|
|
7
7
|
v3: 'v3',
|
|
8
8
|
electro: 'electro',
|
|
9
9
|
};
|
|
10
|
+
const unmarshallOutput = util.unmarshallOutput || ((val) => val);
|
|
10
11
|
|
|
11
12
|
const v3Methods = ['send'];
|
|
12
13
|
const v2Methods = ['get', 'put', 'update', 'delete', 'batchWrite', 'batchGet', 'scan', 'query', 'createSet', 'transactWrite', 'transactGet'];
|
|
@@ -15,6 +16,99 @@ const supportedClientVersions = {
|
|
|
15
16
|
[DocumentClientVersions.v3]: v3Methods,
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
class DocumentClientV2Wrapper {
|
|
20
|
+
static init(client) {
|
|
21
|
+
return new DocumentClientV2Wrapper(client, lib);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
constructor(client, lib) {
|
|
25
|
+
this.client = client;
|
|
26
|
+
this.lib = lib;
|
|
27
|
+
this.__v = 'v2';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get(params) {
|
|
31
|
+
return this.client.get(params);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
put(params) {
|
|
35
|
+
return this.client.put(params);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
update(params) {
|
|
39
|
+
return this.client.update(params);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
delete(params) {
|
|
43
|
+
return this.client.delete(params);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
batchWrite(params) {
|
|
47
|
+
return this.client.batchWrite(params);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
batchGet(params) {
|
|
51
|
+
return this.client.batchGet(params);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
scan(params) {
|
|
55
|
+
return this.client.scan(params);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
query(params) {
|
|
59
|
+
return this.client.query(params);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
_transact(transactionRequest) {
|
|
63
|
+
let cancellationReasons;
|
|
64
|
+
transactionRequest.on('extractError', (response) => {
|
|
65
|
+
try {
|
|
66
|
+
cancellationReasons = JSON.parse(response.httpResponse.body.toString()).CancellationReasons;
|
|
67
|
+
} catch (err) {}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
async promise() {
|
|
72
|
+
return transactionRequest.promise()
|
|
73
|
+
.catch((err) => {
|
|
74
|
+
if (err) {
|
|
75
|
+
if (Array.isArray(cancellationReasons)) {
|
|
76
|
+
return {
|
|
77
|
+
canceled: cancellationReasons
|
|
78
|
+
.map(reason => {
|
|
79
|
+
if (reason.Item) {
|
|
80
|
+
return unmarshallOutput(reason, [{ key: "Item" }]);
|
|
81
|
+
}
|
|
82
|
+
return reason;
|
|
83
|
+
})
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
throw err;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
transactWrite(params) {
|
|
94
|
+
const transactionRequest = this.client.transactWrite(params);
|
|
95
|
+
return this._transact(transactionRequest);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
transactGet(params) {
|
|
99
|
+
const transactionRequest = this.client.transactGet(params);
|
|
100
|
+
return this._transact(transactionRequest);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
createSet(value, ...rest) {
|
|
104
|
+
if (Array.isArray(value)) {
|
|
105
|
+
return this.client.createSet(value, ...rest);
|
|
106
|
+
} else {
|
|
107
|
+
return this.client.createSet([value], ...rest);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
18
112
|
class DocumentClientV3Wrapper {
|
|
19
113
|
static init(client) {
|
|
20
114
|
return new DocumentClientV3Wrapper(client, lib);
|
|
@@ -23,6 +117,7 @@ class DocumentClientV3Wrapper {
|
|
|
23
117
|
constructor(client, lib) {
|
|
24
118
|
this.client = client;
|
|
25
119
|
this.lib = lib;
|
|
120
|
+
this.__v = 'v3';
|
|
26
121
|
}
|
|
27
122
|
|
|
28
123
|
promiseWrap(fn) {
|
|
@@ -81,16 +176,49 @@ class DocumentClientV3Wrapper {
|
|
|
81
176
|
return this.client.send(command);
|
|
82
177
|
});
|
|
83
178
|
}
|
|
179
|
+
|
|
84
180
|
transactWrite(params) {
|
|
85
181
|
return this.promiseWrap(async () => {
|
|
86
182
|
const command = new this.lib.TransactWriteCommand(params);
|
|
87
|
-
return this.client.send(command)
|
|
183
|
+
return this.client.send(command)
|
|
184
|
+
.then((result) => {
|
|
185
|
+
return result;
|
|
186
|
+
})
|
|
187
|
+
.catch(err => {
|
|
188
|
+
if (err.CancellationReasons) {
|
|
189
|
+
return {
|
|
190
|
+
canceled: err.CancellationReasons.map(reason => {
|
|
191
|
+
if (reason.Item) {
|
|
192
|
+
return unmarshallOutput(reason, [{ key: "Item" }]);
|
|
193
|
+
}
|
|
194
|
+
return reason;
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
throw err;
|
|
199
|
+
});
|
|
88
200
|
});
|
|
89
201
|
}
|
|
90
202
|
transactGet(params) {
|
|
91
203
|
return this.promiseWrap(async () => {
|
|
92
204
|
const command = new this.lib.TransactGetCommand(params);
|
|
93
|
-
return this.client.send(command)
|
|
205
|
+
return this.client.send(command)
|
|
206
|
+
.then((result) => {
|
|
207
|
+
return result;
|
|
208
|
+
})
|
|
209
|
+
.catch(err => {
|
|
210
|
+
if (err.CancellationReasons) {
|
|
211
|
+
return {
|
|
212
|
+
canceled: err.CancellationReasons.map(reason => {
|
|
213
|
+
if (reason.Item) {
|
|
214
|
+
return unmarshallOutput(reason, [{ key: "Item" }]);
|
|
215
|
+
}
|
|
216
|
+
return reason;
|
|
217
|
+
})
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
throw err;
|
|
221
|
+
});
|
|
94
222
|
});
|
|
95
223
|
}
|
|
96
224
|
createSet(value) {
|
|
@@ -103,7 +231,9 @@ class DocumentClientV3Wrapper {
|
|
|
103
231
|
}
|
|
104
232
|
|
|
105
233
|
function identifyClientVersion(client = {}) {
|
|
106
|
-
if (client instanceof DocumentClientV3Wrapper)
|
|
234
|
+
if (client instanceof DocumentClientV3Wrapper || client instanceof DocumentClientV2Wrapper) {
|
|
235
|
+
return DocumentClientVersions.electro;
|
|
236
|
+
}
|
|
107
237
|
for (const [version, methods] of Object.entries(supportedClientVersions)) {
|
|
108
238
|
const hasMethods = methods.every(method => {
|
|
109
239
|
return method in client && isFunction(client[method]);
|
|
@@ -121,6 +251,7 @@ function normalizeClient(client) {
|
|
|
121
251
|
case DocumentClientVersions.v3:
|
|
122
252
|
return DocumentClientV3Wrapper.init(client);
|
|
123
253
|
case DocumentClientVersions.v2:
|
|
254
|
+
return DocumentClientV2Wrapper.init(client);
|
|
124
255
|
case DocumentClientVersions.electro:
|
|
125
256
|
return client;
|
|
126
257
|
default:
|
|
@@ -136,6 +267,7 @@ function normalizeConfig(config = {}) {
|
|
|
136
267
|
}
|
|
137
268
|
|
|
138
269
|
module.exports = {
|
|
270
|
+
util,
|
|
139
271
|
v2Methods,
|
|
140
272
|
v3Methods,
|
|
141
273
|
normalizeClient,
|
|
@@ -144,4 +276,5 @@ module.exports = {
|
|
|
144
276
|
DocumentClientVersions,
|
|
145
277
|
supportedClientVersions,
|
|
146
278
|
DocumentClientV3Wrapper,
|
|
279
|
+
DocumentClientV2Wrapper,
|
|
147
280
|
};
|
package/src/entity.js
CHANGED
|
@@ -24,6 +24,7 @@ const { AllPages,
|
|
|
24
24
|
IndexTypes,
|
|
25
25
|
PartialComparisons,
|
|
26
26
|
MethodTypeTranslation,
|
|
27
|
+
TransactionCommitSymbol,
|
|
27
28
|
} = require("./types");
|
|
28
29
|
const { FilterFactory } = require("./filters");
|
|
29
30
|
const { FilterOperations } = require("./operations");
|
|
@@ -35,6 +36,7 @@ const c = require('./client');
|
|
|
35
36
|
const u = require("./util");
|
|
36
37
|
const e = require("./errors");
|
|
37
38
|
const { validate } = require("jsonschema");
|
|
39
|
+
const v = require('./validations');
|
|
38
40
|
|
|
39
41
|
class Entity {
|
|
40
42
|
constructor(model, config = {}) {
|
|
@@ -229,6 +231,10 @@ class Entity {
|
|
|
229
231
|
return validations.model(model);
|
|
230
232
|
}
|
|
231
233
|
|
|
234
|
+
check(compositeAttributes = {}) {
|
|
235
|
+
return this._makeChain(TableIndex, this._clausesWithFilters, clauses.index).check(compositeAttributes);
|
|
236
|
+
}
|
|
237
|
+
|
|
232
238
|
get(facets = {}) {
|
|
233
239
|
let index = TableIndex;
|
|
234
240
|
if (Array.isArray(facets)) {
|
|
@@ -285,6 +291,16 @@ class Entity {
|
|
|
285
291
|
return this._makeChain(index, this._clausesWithFilters, clauses.index, options).remove(facets);
|
|
286
292
|
}
|
|
287
293
|
|
|
294
|
+
async transactWrite(parameters, config) {
|
|
295
|
+
let response = await this._exec(MethodTypes.transactWrite, parameters, config);
|
|
296
|
+
return response;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
async transactGet(parameters, config) {
|
|
300
|
+
let response = await this._exec(MethodTypes.transactGet, parameters, config);
|
|
301
|
+
return response;
|
|
302
|
+
}
|
|
303
|
+
|
|
288
304
|
async go(method, parameters = {}, config = {}) {
|
|
289
305
|
let stackTrace;
|
|
290
306
|
if (!config.originalErr) {
|
|
@@ -486,7 +502,7 @@ class Entity {
|
|
|
486
502
|
case FormatToReturnValues.all_old:
|
|
487
503
|
case FormatToReturnValues.updated_new:
|
|
488
504
|
case FormatToReturnValues.updated_old:
|
|
489
|
-
return this.formatResponse(response, config);
|
|
505
|
+
return this.formatResponse(response, TableIndex, config);
|
|
490
506
|
case FormatToReturnValues.default:
|
|
491
507
|
default:
|
|
492
508
|
return this._formatDefaultResponse(method, parameters.IndexName, parameters, config, response);
|
|
@@ -583,7 +599,7 @@ class Entity {
|
|
|
583
599
|
for (let i = 0; i < responses.length; i++) {
|
|
584
600
|
const item = responses[i];
|
|
585
601
|
const slot = orderMaintainer.getOrder(item);
|
|
586
|
-
const formatted = this.formatResponse({Item: item}, index, config);
|
|
602
|
+
const formatted = this.formatResponse({ Item: item }, index, config);
|
|
587
603
|
if (slot !== -1) {
|
|
588
604
|
resultsAll[slot] = formatted.data;
|
|
589
605
|
} else {
|
|
@@ -617,6 +633,8 @@ class Entity {
|
|
|
617
633
|
if (Object.keys(results).length === 0) {
|
|
618
634
|
results = null;
|
|
619
635
|
}
|
|
636
|
+
} else if (!config._objectOnEmpty) {
|
|
637
|
+
results = null;
|
|
620
638
|
}
|
|
621
639
|
} else if (response.Items) {
|
|
622
640
|
results = [];
|
|
@@ -881,7 +899,7 @@ class Entity {
|
|
|
881
899
|
return pager
|
|
882
900
|
}
|
|
883
901
|
|
|
884
|
-
|
|
902
|
+
_normalizeExecutionOptions({ provided = [], context = {} } = {}) {
|
|
885
903
|
let config = {
|
|
886
904
|
includeKeys: false,
|
|
887
905
|
originalErr: false,
|
|
@@ -909,7 +927,7 @@ class Entity {
|
|
|
909
927
|
order: undefined,
|
|
910
928
|
};
|
|
911
929
|
|
|
912
|
-
|
|
930
|
+
return provided.filter(Boolean).reduce((config, option) => {
|
|
913
931
|
if (typeof option.order === 'string') {
|
|
914
932
|
switch (option.order.toLowerCase()) {
|
|
915
933
|
case 'asc':
|
|
@@ -929,11 +947,15 @@ class Entity {
|
|
|
929
947
|
throw new e.ElectroError(e.ErrorCodes.InvalidOptions, `Invalid value for query option "format" provided: "${option.format}". Allowed values include ${u.commaSeparatedString(Object.keys(ReturnValues))}.`);
|
|
930
948
|
}
|
|
931
949
|
config.response = format;
|
|
932
|
-
|
|
950
|
+
if (context.operation === MethodTypes.transactWrite) {
|
|
951
|
+
config.params.ReturnValuesOnConditionCheckFailure = FormatToReturnValues[format];
|
|
952
|
+
} else {
|
|
953
|
+
config.params.ReturnValues = FormatToReturnValues[format];
|
|
954
|
+
}
|
|
933
955
|
}
|
|
934
956
|
|
|
935
957
|
if (option.formatCursor) {
|
|
936
|
-
const isValid = ['serialize', 'deserialize'].every(method =>
|
|
958
|
+
const isValid = ['serialize', 'deserialize'].every(method =>
|
|
937
959
|
method in option.formatCursor &&
|
|
938
960
|
validations.isFunction(option.formatCursor[method])
|
|
939
961
|
);
|
|
@@ -1058,16 +1080,18 @@ class Entity {
|
|
|
1058
1080
|
config.params = Object.assign({}, config.params, option.params);
|
|
1059
1081
|
return config;
|
|
1060
1082
|
}, config);
|
|
1083
|
+
}
|
|
1061
1084
|
|
|
1085
|
+
_applyParameterOptions({ params = {}, options = {} } = {}) {
|
|
1062
1086
|
let parameters = Object.assign({}, params);
|
|
1063
1087
|
|
|
1064
|
-
for (let customParameter of Object.keys(
|
|
1065
|
-
if (
|
|
1066
|
-
parameters[customParameter] =
|
|
1088
|
+
for (let customParameter of Object.keys(options.params || {})) {
|
|
1089
|
+
if (options.params[customParameter] !== undefined) {
|
|
1090
|
+
parameters[customParameter] = options.params[customParameter];
|
|
1067
1091
|
}
|
|
1068
1092
|
}
|
|
1069
1093
|
|
|
1070
|
-
return
|
|
1094
|
+
return parameters;
|
|
1071
1095
|
}
|
|
1072
1096
|
|
|
1073
1097
|
addListeners(logger) {
|
|
@@ -1117,10 +1141,11 @@ class Entity {
|
|
|
1117
1141
|
}
|
|
1118
1142
|
/* istanbul ignore next */
|
|
1119
1143
|
_params(state, config = {}) {
|
|
1120
|
-
|
|
1144
|
+
const { keys = {}, method = "", put = {}, update = {}, filter = {}, upsert } = state.query;
|
|
1121
1145
|
let consolidatedQueryFacets = this._consolidateQueryFacets(keys.sk);
|
|
1122
1146
|
let params = {};
|
|
1123
1147
|
switch (method) {
|
|
1148
|
+
case MethodTypes.check:
|
|
1124
1149
|
case MethodTypes.get:
|
|
1125
1150
|
case MethodTypes.delete:
|
|
1126
1151
|
case MethodTypes.remove:
|
|
@@ -1148,8 +1173,13 @@ class Entity {
|
|
|
1148
1173
|
default:
|
|
1149
1174
|
throw new Error(`Invalid method: ${method}`);
|
|
1150
1175
|
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1176
|
+
|
|
1177
|
+
let appliedParameters = this._applyParameterOptions({
|
|
1178
|
+
params,
|
|
1179
|
+
options: config,
|
|
1180
|
+
});
|
|
1181
|
+
|
|
1182
|
+
return this._applyParameterExpressions(method, appliedParameters, config, filter);
|
|
1153
1183
|
}
|
|
1154
1184
|
|
|
1155
1185
|
_applyParameterExpressions(method, parameters, config, filter) {
|
|
@@ -1251,12 +1281,19 @@ class Entity {
|
|
|
1251
1281
|
_batchGetParams(state, config = {}) {
|
|
1252
1282
|
let table = config.table || this.getTableName();
|
|
1253
1283
|
let userDefinedParams = config.params || {};
|
|
1284
|
+
|
|
1285
|
+
// TableName is added when the config provided includes "table"
|
|
1286
|
+
// this is evaluated upstream so we remove it to avoid forming
|
|
1287
|
+
// bad syntax. Code should reconsider how this is applied to
|
|
1288
|
+
// make this cleaner :(
|
|
1289
|
+
delete userDefinedParams.TableName;
|
|
1290
|
+
|
|
1254
1291
|
let records = [];
|
|
1255
1292
|
for (let itemState of state.subStates) {
|
|
1256
1293
|
let method = itemState.query.method;
|
|
1257
1294
|
let params = this._params(itemState, config);
|
|
1258
1295
|
if (method === MethodTypes.get) {
|
|
1259
|
-
let {Key} = params;
|
|
1296
|
+
let { Key } = params;
|
|
1260
1297
|
records.push(Key);
|
|
1261
1298
|
}
|
|
1262
1299
|
}
|
|
@@ -1356,11 +1393,7 @@ class Entity {
|
|
|
1356
1393
|
),
|
|
1357
1394
|
FilterExpression: `begins_with(#${pkField}, :${pkField})`,
|
|
1358
1395
|
};
|
|
1359
|
-
|
|
1360
|
-
params.ExpressionAttributeNames["#" + this.identifiers.version] = this.identifiers.version;
|
|
1361
|
-
params.ExpressionAttributeValues[":" + this.identifiers.entity] = this.getName();
|
|
1362
|
-
params.ExpressionAttributeValues[":" + this.identifiers.version] = this.getVersion();
|
|
1363
|
-
params.FilterExpression = `${params.FilterExpression} AND #${this.identifiers.entity} = :${this.identifiers.entity} AND #${this.identifiers.version} = :${this.identifiers.version}`;
|
|
1396
|
+
|
|
1364
1397
|
if (hasSortKey) {
|
|
1365
1398
|
let skField = this.model.indexes[accessPattern].sk.field;
|
|
1366
1399
|
params.FilterExpression = `${params.FilterExpression} AND begins_with(#${skField}, :${skField})`;
|
|
@@ -1380,7 +1413,7 @@ class Entity {
|
|
|
1380
1413
|
});
|
|
1381
1414
|
let Key = this._makeParameterKey(index, keys.pk, ...keys.sk);
|
|
1382
1415
|
let TableName = this.getTableName();
|
|
1383
|
-
return {Key, TableName};
|
|
1416
|
+
return { Key, TableName };
|
|
1384
1417
|
}
|
|
1385
1418
|
|
|
1386
1419
|
_removeAttributes(item, keys) {
|
|
@@ -1691,8 +1724,16 @@ class Entity {
|
|
|
1691
1724
|
default:
|
|
1692
1725
|
throw new Error(`Invalid query type: ${state.query.type}`);
|
|
1693
1726
|
}
|
|
1694
|
-
|
|
1695
|
-
|
|
1727
|
+
|
|
1728
|
+
const appliedParameters = this._applyParameterOptions({
|
|
1729
|
+
params: parameters,
|
|
1730
|
+
options,
|
|
1731
|
+
});
|
|
1732
|
+
|
|
1733
|
+
return this._applyProjectionExpressions({
|
|
1734
|
+
parameters: appliedParameters,
|
|
1735
|
+
config: options,
|
|
1736
|
+
});
|
|
1696
1737
|
}
|
|
1697
1738
|
|
|
1698
1739
|
_makeBetweenQueryParams(index, filter, pk, ...sk) {
|
|
@@ -2293,7 +2334,6 @@ class Entity {
|
|
|
2293
2334
|
indexType,
|
|
2294
2335
|
isCollection = false,
|
|
2295
2336
|
}) {
|
|
2296
|
-
|
|
2297
2337
|
this._validateIndex(index);
|
|
2298
2338
|
const excludePostfix = indexType === IndexTypes.clustered && isCollection;
|
|
2299
2339
|
const transforms = this._makeKeyTransforms(queryType);
|
|
@@ -3115,7 +3155,49 @@ class Entity {
|
|
|
3115
3155
|
}
|
|
3116
3156
|
}
|
|
3117
3157
|
|
|
3158
|
+
function getEntityIdentifiers(entities) {
|
|
3159
|
+
let identifiers = [];
|
|
3160
|
+
for (let alias of Object.keys(entities)) {
|
|
3161
|
+
let entity = entities[alias];
|
|
3162
|
+
let name = entity.model.entity;
|
|
3163
|
+
let version = entity.model.version;
|
|
3164
|
+
identifiers.push({
|
|
3165
|
+
name,
|
|
3166
|
+
alias,
|
|
3167
|
+
version,
|
|
3168
|
+
entity,
|
|
3169
|
+
nameField: entity.identifiers.entity,
|
|
3170
|
+
versionField: entity.identifiers.version
|
|
3171
|
+
});
|
|
3172
|
+
}
|
|
3173
|
+
return identifiers;
|
|
3174
|
+
}
|
|
3175
|
+
|
|
3176
|
+
function matchToEntityAlias({ paramItem, identifiers, record } = {}) {
|
|
3177
|
+
let entity;
|
|
3178
|
+
let entityAlias;
|
|
3179
|
+
|
|
3180
|
+
if (paramItem && v.isFunction(paramItem[TransactionCommitSymbol])) {
|
|
3181
|
+
const committed = paramItem[TransactionCommitSymbol]();
|
|
3182
|
+
entity = committed.entity;
|
|
3183
|
+
}
|
|
3184
|
+
|
|
3185
|
+
for (let {name, version, nameField, versionField, alias} of identifiers) {
|
|
3186
|
+
if (entity && entity.model.entity === name && entity.model.version === version) {
|
|
3187
|
+
entityAlias = alias;
|
|
3188
|
+
break;
|
|
3189
|
+
} else if (record[nameField] !== undefined && record[nameField] === name && record[versionField] !== undefined && record[versionField] === version) {
|
|
3190
|
+
entityAlias = alias;
|
|
3191
|
+
break;
|
|
3192
|
+
}
|
|
3193
|
+
}
|
|
3194
|
+
|
|
3195
|
+
return entityAlias;
|
|
3196
|
+
}
|
|
3197
|
+
|
|
3118
3198
|
module.exports = {
|
|
3119
3199
|
Entity,
|
|
3120
3200
|
clauses,
|
|
3201
|
+
getEntityIdentifiers,
|
|
3202
|
+
matchToEntityAlias,
|
|
3121
3203
|
};
|
package/src/filters.js
CHANGED
|
@@ -76,7 +76,7 @@ class FilterFactory {
|
|
|
76
76
|
let filterParents = Object.entries(injected)
|
|
77
77
|
.filter(clause => {
|
|
78
78
|
let [name, { children }] = clause;
|
|
79
|
-
return children.includes(
|
|
79
|
+
return children.find(child => ['go', 'commit'].includes(child));
|
|
80
80
|
})
|
|
81
81
|
.map(([name]) => name);
|
|
82
82
|
let modelFilters = Object.keys(filters);
|
|
@@ -86,7 +86,7 @@ class FilterFactory {
|
|
|
86
86
|
injected[name] = {
|
|
87
87
|
name: name,
|
|
88
88
|
action: this.buildClause(filter),
|
|
89
|
-
children: ["params", "go", "filter", ...modelFilters],
|
|
89
|
+
children: ["params", "go", "commit", "filter", ...modelFilters],
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
92
|
filterChildren.push("filter");
|
|
@@ -95,7 +95,7 @@ class FilterFactory {
|
|
|
95
95
|
action: (entity, state, fn) => {
|
|
96
96
|
return this.buildClause(fn)(entity, state);
|
|
97
97
|
},
|
|
98
|
-
children: ["params", "go", "filter", ...modelFilters],
|
|
98
|
+
children: ["params", "go", "commit", "filter", ...modelFilters],
|
|
99
99
|
};
|
|
100
100
|
for (let parent of filterParents) {
|
|
101
101
|
injected[parent] = { ...injected[parent] };
|
package/src/service.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
const { Entity } = require("./entity");
|
|
1
|
+
const { Entity, getEntityIdentifiers, matchToEntityAlias } = require("./entity");
|
|
2
2
|
const { clauses } = require("./clauses");
|
|
3
|
-
const { KeyCasing, ServiceVersions, Pager, ElectroInstance, ElectroInstanceTypes, ModelVersions, IndexTypes } = require("./types");
|
|
3
|
+
const { TableIndex, TransactionMethods, KeyCasing, ServiceVersions, Pager, ElectroInstance, ElectroInstanceTypes, ModelVersions, IndexTypes } = require("./types");
|
|
4
4
|
const { FilterFactory } = require("./filters");
|
|
5
5
|
const { FilterOperations } = require("./operations");
|
|
6
6
|
const { WhereFactory } = require("./where");
|
|
7
|
-
const { getInstanceType, getModelVersion, applyBetaModelOverrides } = require("./util");
|
|
8
7
|
const v = require("./validations");
|
|
9
8
|
const c = require('./client');
|
|
10
9
|
const e = require("./errors");
|
|
11
10
|
const u = require("./util");
|
|
11
|
+
const txn = require("./transaction");
|
|
12
|
+
const { getInstanceType, getModelVersion, applyBetaModelOverrides } = require("./util");
|
|
12
13
|
|
|
13
14
|
const ConstructorTypes = {
|
|
14
15
|
beta: "beta",
|
|
@@ -68,6 +69,22 @@ class Service {
|
|
|
68
69
|
this.compositeAttributes = {};
|
|
69
70
|
this.collections = {};
|
|
70
71
|
this.identifiers = {};
|
|
72
|
+
this.transaction = {
|
|
73
|
+
get: (fn) => {
|
|
74
|
+
return txn.createTransaction({
|
|
75
|
+
fn,
|
|
76
|
+
getEntities: () => this.entities,
|
|
77
|
+
method: TransactionMethods.transactGet,
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
write: (fn) => {
|
|
81
|
+
return txn.createTransaction({
|
|
82
|
+
fn,
|
|
83
|
+
getEntities: () => this.entities,
|
|
84
|
+
method: TransactionMethods.transactWrite,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
};
|
|
71
88
|
this._instance = ElectroInstance.service;
|
|
72
89
|
this._instanceType = ElectroInstanceTypes.service;
|
|
73
90
|
}
|
|
@@ -94,6 +111,22 @@ class Service {
|
|
|
94
111
|
this.compositeAttributes = {};
|
|
95
112
|
this.collections = {};
|
|
96
113
|
this.identifiers = {};
|
|
114
|
+
this.transaction = {
|
|
115
|
+
get: (fn) => {
|
|
116
|
+
return txn.createTransaction({
|
|
117
|
+
fn,
|
|
118
|
+
getEntities: () => this.entities,
|
|
119
|
+
method: TransactionMethods.transactGet,
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
write: (fn) => {
|
|
123
|
+
return txn.createTransaction({
|
|
124
|
+
fn,
|
|
125
|
+
getEntities: () => this.entities,
|
|
126
|
+
method: TransactionMethods.transactWrite,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
};
|
|
97
130
|
this._instance = ElectroInstance.service;
|
|
98
131
|
this._instanceType = ElectroInstanceTypes.service;
|
|
99
132
|
}
|
|
@@ -270,53 +303,39 @@ class Service {
|
|
|
270
303
|
}
|
|
271
304
|
}
|
|
272
305
|
|
|
273
|
-
|
|
274
|
-
let identifiers = [];
|
|
275
|
-
for (let alias of Object.keys(entities)) {
|
|
276
|
-
let entity = entities[alias];
|
|
277
|
-
let name = entity.model.entity;
|
|
278
|
-
let version = entity.model.version;
|
|
279
|
-
identifiers.push({
|
|
280
|
-
name,
|
|
281
|
-
alias,
|
|
282
|
-
version,
|
|
283
|
-
entity,
|
|
284
|
-
nameField: entity.identifiers.entity,
|
|
285
|
-
versionField: entity.identifiers.version
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
return identifiers;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
cleanseRetrievedData(collection = "", entities, data = {}, config = {}) {
|
|
306
|
+
cleanseRetrievedData(index = TableIndex, entities, data = {}, config = {}) {
|
|
292
307
|
if (config.raw) {
|
|
293
308
|
return data;
|
|
294
309
|
}
|
|
310
|
+
const identifiers = getEntityIdentifiers(entities);
|
|
311
|
+
|
|
295
312
|
data.Items = data.Items || [];
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
let identifiers = this._getEntityIdentifiers(entities);
|
|
313
|
+
|
|
314
|
+
const results = {};
|
|
299
315
|
for (let {alias} of identifiers) {
|
|
300
316
|
results[alias] = [];
|
|
301
317
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
318
|
+
|
|
319
|
+
for (let i = 0; i < data.Items.length; i++) {
|
|
320
|
+
const record = data.Items[i];
|
|
321
|
+
|
|
322
|
+
if (!record) {
|
|
323
|
+
continue;
|
|
309
324
|
}
|
|
325
|
+
|
|
326
|
+
const entityAlias = matchToEntityAlias({identifiers, record});
|
|
327
|
+
|
|
310
328
|
if (!entityAlias) {
|
|
311
329
|
continue;
|
|
312
330
|
}
|
|
313
331
|
// pager=false because we don't want the entity trying to parse the lastEvaluatedKey
|
|
314
|
-
let
|
|
332
|
+
let formatted = entities[entityAlias].formatResponse({Item: record}, index, {
|
|
315
333
|
...config,
|
|
316
334
|
pager: false,
|
|
317
335
|
parse: undefined
|
|
318
336
|
});
|
|
319
|
-
|
|
337
|
+
|
|
338
|
+
results[entityAlias].push(formatted.data);
|
|
320
339
|
}
|
|
321
340
|
return results;
|
|
322
341
|
}
|
|
@@ -364,7 +383,7 @@ class Service {
|
|
|
364
383
|
name = "",
|
|
365
384
|
initialClauses = {},
|
|
366
385
|
}, facets = {}) {
|
|
367
|
-
const { entities, attributes, identifiers, indexType } = this.collectionSchema[name];
|
|
386
|
+
const { entities, attributes, identifiers, indexType, index } = this.collectionSchema[name];
|
|
368
387
|
const compositeAttributes = this.compositeAttributes[name];
|
|
369
388
|
const allEntities = Object.values(entities);
|
|
370
389
|
const entity = allEntities[0];
|
|
@@ -381,7 +400,10 @@ class Service {
|
|
|
381
400
|
let options = {
|
|
382
401
|
// expressions, // DynamoDB doesnt return what I expect it would when provided with these entity filters
|
|
383
402
|
parse: (options, data) => {
|
|
384
|
-
|
|
403
|
+
if (options.raw) {
|
|
404
|
+
return data;
|
|
405
|
+
}
|
|
406
|
+
return this.cleanseRetrievedData(index, entities, data, options);
|
|
385
407
|
},
|
|
386
408
|
formatCursor: {
|
|
387
409
|
serialize: (key) => {
|
|
@@ -391,13 +413,18 @@ class Service {
|
|
|
391
413
|
return this.expectCursorOwner(cursor).deserializeCursor(cursor);
|
|
392
414
|
}
|
|
393
415
|
},
|
|
394
|
-
|
|
416
|
+
identifiers: {
|
|
395
417
|
names: identifiers.names || {},
|
|
396
418
|
values: identifiers.values || {},
|
|
397
419
|
expression: allEntities.length > 1
|
|
398
420
|
? `(${expression})`
|
|
399
421
|
: expression
|
|
400
422
|
},
|
|
423
|
+
expressions: {
|
|
424
|
+
names: {},
|
|
425
|
+
values: {},
|
|
426
|
+
expression: '',
|
|
427
|
+
},
|
|
401
428
|
attributes,
|
|
402
429
|
entities,
|
|
403
430
|
indexType,
|
|
@@ -730,4 +757,6 @@ class Service {
|
|
|
730
757
|
}
|
|
731
758
|
}
|
|
732
759
|
|
|
733
|
-
module.exports = {
|
|
760
|
+
module.exports = {
|
|
761
|
+
Service,
|
|
762
|
+
};
|