@webda/aws 4.0.0-beta.2 → 4.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/README.md +64 -7
  2. package/lib/index.d.ts.map +1 -1
  3. package/lib/index.js.map +1 -1
  4. package/lib/services/aws-parameters.d.ts +33 -0
  5. package/lib/services/aws-parameters.d.ts.map +1 -0
  6. package/lib/services/aws-parameters.js +18 -0
  7. package/lib/services/aws-parameters.js.map +1 -0
  8. package/lib/services/awscommands.service.d.ts +39 -0
  9. package/lib/services/awscommands.service.d.ts.map +1 -0
  10. package/lib/services/awscommands.service.js +127 -0
  11. package/lib/services/awscommands.service.js.map +1 -0
  12. package/lib/services/cloudwatchlogger.service.d.ts +131 -0
  13. package/lib/services/cloudwatchlogger.service.d.ts.map +1 -0
  14. package/lib/services/{cloudwatchlogger.js → cloudwatchlogger.service.js} +60 -28
  15. package/lib/services/cloudwatchlogger.service.js.map +1 -0
  16. package/lib/services/contributors.d.ts +37 -0
  17. package/lib/services/contributors.d.ts.map +1 -0
  18. package/lib/services/contributors.js +2 -0
  19. package/lib/services/contributors.js.map +1 -0
  20. package/lib/services/dynamodb.service.d.ts +297 -0
  21. package/lib/services/dynamodb.service.d.ts.map +1 -0
  22. package/lib/services/dynamodb.service.js +985 -0
  23. package/lib/services/dynamodb.service.js.map +1 -0
  24. package/lib/services/index.d.ts +11 -31
  25. package/lib/services/index.d.ts.map +1 -1
  26. package/lib/services/index.js +11 -8
  27. package/lib/services/index.js.map +1 -1
  28. package/lib/services/lambdacaller.service.d.ts +81 -0
  29. package/lib/services/lambdacaller.service.d.ts.map +1 -0
  30. package/lib/services/lambdacaller.service.js +75 -0
  31. package/lib/services/lambdacaller.service.js.map +1 -0
  32. package/lib/services/lambdaserver.service.d.ts +127 -0
  33. package/lib/services/lambdaserver.service.d.ts.map +1 -0
  34. package/lib/services/lambdaserver.service.js +294 -0
  35. package/lib/services/lambdaserver.service.js.map +1 -0
  36. package/lib/services/{route53.d.ts → route53.service.d.ts} +21 -12
  37. package/lib/services/route53.service.d.ts.map +1 -0
  38. package/lib/services/{route53.js → route53.service.js} +25 -28
  39. package/lib/services/route53.service.js.map +1 -0
  40. package/lib/services/s3binary.service.d.ts +215 -0
  41. package/lib/services/s3binary.service.d.ts.map +1 -0
  42. package/lib/services/{s3binary.js → s3binary.service.js} +93 -55
  43. package/lib/services/s3binary.service.js.map +1 -0
  44. package/lib/services/secretsmanager.service.d.ts +102 -0
  45. package/lib/services/secretsmanager.service.d.ts.map +1 -0
  46. package/lib/services/{secretsmanager.js → secretsmanager.service.js} +40 -22
  47. package/lib/services/secretsmanager.service.js.map +1 -0
  48. package/lib/services/{sqsqueue.d.ts → sqsqueue.service.d.ts} +60 -35
  49. package/lib/services/sqsqueue.service.d.ts.map +1 -0
  50. package/lib/services/{sqsqueue.js → sqsqueue.service.js} +53 -28
  51. package/lib/services/sqsqueue.service.js.map +1 -0
  52. package/package.json +58 -63
  53. package/webda.module.json +743 -280
  54. package/lib/deployers/cloudformation.d.ts +0 -317
  55. package/lib/deployers/cloudformation.d.ts.map +0 -1
  56. package/lib/deployers/cloudformation.js +0 -837
  57. package/lib/deployers/cloudformation.js.map +0 -1
  58. package/lib/deployers/cloudformation.spec.d.ts +0 -2
  59. package/lib/deployers/cloudformation.spec.d.ts.map +0 -1
  60. package/lib/deployers/cloudformation.spec.js +0 -530
  61. package/lib/deployers/cloudformation.spec.js.map +0 -1
  62. package/lib/deployers/index.d.ts +0 -255
  63. package/lib/deployers/index.d.ts.map +0 -1
  64. package/lib/deployers/index.js +0 -543
  65. package/lib/deployers/index.js.map +0 -1
  66. package/lib/deployers/index.spec.d.ts +0 -9
  67. package/lib/deployers/index.spec.d.ts.map +0 -1
  68. package/lib/deployers/index.spec.js +0 -595
  69. package/lib/deployers/index.spec.js.map +0 -1
  70. package/lib/deployers/lambda-entrypoint.d.ts +0 -2
  71. package/lib/deployers/lambda-entrypoint.d.ts.map +0 -1
  72. package/lib/deployers/lambda-entrypoint.js +0 -13
  73. package/lib/deployers/lambda-entrypoint.js.map +0 -1
  74. package/lib/deployers/lambdapackager.d.ts +0 -28
  75. package/lib/deployers/lambdapackager.d.ts.map +0 -1
  76. package/lib/deployers/lambdapackager.js +0 -26
  77. package/lib/deployers/lambdapackager.js.map +0 -1
  78. package/lib/deployers/lambdapackager.spec.d.ts +0 -2
  79. package/lib/deployers/lambdapackager.spec.d.ts.map +0 -1
  80. package/lib/deployers/lambdapackager.spec.js +0 -44
  81. package/lib/deployers/lambdapackager.spec.js.map +0 -1
  82. package/lib/index.spec.d.ts +0 -11
  83. package/lib/index.spec.d.ts.map +0 -1
  84. package/lib/index.spec.js +0 -42
  85. package/lib/index.spec.js.map +0 -1
  86. package/lib/services/aws-mixin.d.ts +0 -25
  87. package/lib/services/aws-mixin.d.ts.map +0 -1
  88. package/lib/services/aws-mixin.js +0 -18
  89. package/lib/services/aws-mixin.js.map +0 -1
  90. package/lib/services/cloudwatchlogger.d.ts +0 -82
  91. package/lib/services/cloudwatchlogger.d.ts.map +0 -1
  92. package/lib/services/cloudwatchlogger.js.map +0 -1
  93. package/lib/services/cloudwatchlogger.spec.d.ts +0 -2
  94. package/lib/services/cloudwatchlogger.spec.d.ts.map +0 -1
  95. package/lib/services/cloudwatchlogger.spec.js +0 -104
  96. package/lib/services/cloudwatchlogger.spec.js.map +0 -1
  97. package/lib/services/dynamodb.d.ts +0 -174
  98. package/lib/services/dynamodb.d.ts.map +0 -1
  99. package/lib/services/dynamodb.js +0 -711
  100. package/lib/services/dynamodb.js.map +0 -1
  101. package/lib/services/dynamodb.spec.d.ts +0 -24
  102. package/lib/services/dynamodb.spec.d.ts.map +0 -1
  103. package/lib/services/dynamodb.spec.js +0 -344
  104. package/lib/services/dynamodb.spec.js.map +0 -1
  105. package/lib/services/lambdacaller.d.ts +0 -69
  106. package/lib/services/lambdacaller.d.ts.map +0 -1
  107. package/lib/services/lambdacaller.js +0 -63
  108. package/lib/services/lambdacaller.js.map +0 -1
  109. package/lib/services/lambdacaller.spec.d.ts +0 -2
  110. package/lib/services/lambdacaller.spec.d.ts.map +0 -1
  111. package/lib/services/lambdacaller.spec.js +0 -70
  112. package/lib/services/lambdacaller.spec.js.map +0 -1
  113. package/lib/services/lambdaserver.d.ts +0 -87
  114. package/lib/services/lambdaserver.d.ts.map +0 -1
  115. package/lib/services/lambdaserver.js +0 -263
  116. package/lib/services/lambdaserver.js.map +0 -1
  117. package/lib/services/lambdaserver.spec.d.ts +0 -2
  118. package/lib/services/lambdaserver.spec.d.ts.map +0 -1
  119. package/lib/services/lambdaserver.spec.js +0 -417
  120. package/lib/services/lambdaserver.spec.js.map +0 -1
  121. package/lib/services/route53.d.ts.map +0 -1
  122. package/lib/services/route53.js.map +0 -1
  123. package/lib/services/route53.spec.d.ts +0 -2
  124. package/lib/services/route53.spec.d.ts.map +0 -1
  125. package/lib/services/route53.spec.js +0 -102
  126. package/lib/services/route53.spec.js.map +0 -1
  127. package/lib/services/s3binary.d.ts +0 -163
  128. package/lib/services/s3binary.d.ts.map +0 -1
  129. package/lib/services/s3binary.js.map +0 -1
  130. package/lib/services/s3binary.spec.d.ts +0 -2
  131. package/lib/services/s3binary.spec.d.ts.map +0 -1
  132. package/lib/services/s3binary.spec.js +0 -284
  133. package/lib/services/s3binary.spec.js.map +0 -1
  134. package/lib/services/secretsmanager.d.ts +0 -81
  135. package/lib/services/secretsmanager.d.ts.map +0 -1
  136. package/lib/services/secretsmanager.js.map +0 -1
  137. package/lib/services/secretsmanager.spec.d.ts +0 -2
  138. package/lib/services/secretsmanager.spec.d.ts.map +0 -1
  139. package/lib/services/secretsmanager.spec.js +0 -66
  140. package/lib/services/secretsmanager.spec.js.map +0 -1
  141. package/lib/services/sqsqueue.d.ts.map +0 -1
  142. package/lib/services/sqsqueue.js.map +0 -1
  143. package/lib/services/sqsqueue.spec.d.ts +0 -2
  144. package/lib/services/sqsqueue.spec.d.ts.map +0 -1
  145. package/lib/services/sqsqueue.spec.js +0 -157
  146. package/lib/services/sqsqueue.spec.js.map +0 -1
  147. package/lib/shell.d.ts +0 -13
  148. package/lib/shell.d.ts.map +0 -1
  149. package/lib/shell.js +0 -42
  150. package/lib/shell.js.map +0 -1
  151. package/webda.shell.json +0 -11
@@ -1,711 +0,0 @@
1
- import { ConditionalCheckFailedException, DynamoDB, DynamoDBClient } from "@aws-sdk/client-dynamodb";
2
- import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb";
3
- import { CoreModel, Store, StoreNotFoundError, StoreParameters, UpdateConditionFailError, WebdaError } from "@webda/core";
4
- import * as WebdaQL from "@webda/ql";
5
- import { AWSServiceParameters } from "./index.js";
6
- /**
7
- * Define DynamoDB parameters
8
- */
9
- export class DynamoStoreParameters extends AWSServiceParameters(StoreParameters) {
10
- constructor(params, service) {
11
- super(params, service);
12
- if (this.table === undefined) {
13
- throw new WebdaError.CodeError("DYNAMODB_TABLE_PARAMETER_REQUIRED", "Need to define a table at least");
14
- }
15
- this.globalIndexes ?? (this.globalIndexes = {});
16
- }
17
- }
18
- /**
19
- * DynamoStore handles the DynamoDB
20
- *
21
- * Parameters:
22
- * accessKeyId: '' // try WEBDA_AWS_KEY env variable if not found
23
- * secretAccessKey: '' // try WEBDA_AWS_SECRET env variable if not found
24
- * table: ''
25
- * region: ''
26
- *
27
- * @WebdaModda
28
- */
29
- export default class DynamoStore extends Store {
30
- /**
31
- * Load the parameters
32
- *
33
- * @param params
34
- */
35
- loadParameters(params) {
36
- return new DynamoStoreParameters(params, this);
37
- }
38
- /**
39
- * Create the AWS client
40
- */
41
- resolve() {
42
- super.resolve();
43
- this._client = DynamoDBDocument.from(new DynamoDBClient(this.parameters), {
44
- marshallOptions: {
45
- removeUndefinedValues: true
46
- }
47
- });
48
- return this;
49
- }
50
- /**
51
- * Copy one DynamoDB table to another
52
- *
53
- * @param output
54
- * @param source
55
- * @param target
56
- */
57
- static async copyTable(output, source, target) {
58
- const db = new DynamoDB({});
59
- let ExclusiveStartKey;
60
- const props = await db.describeTable({
61
- TableName: source
62
- });
63
- output.startProgress("copyTable", props.Table.ItemCount, `Copying ${source} to ${target}`);
64
- do {
65
- const info = await db.scan({
66
- TableName: source,
67
- ExclusiveStartKey
68
- });
69
- do {
70
- const items = [];
71
- while (info.Items.length && items.length < 25) {
72
- items.push(info.Items.shift());
73
- }
74
- if (!items.length) {
75
- break;
76
- }
77
- const params = {
78
- RequestItems: {}
79
- };
80
- params.RequestItems[target] = items.map(Item => ({
81
- PutRequest: { Item }
82
- }));
83
- await db.batchWriteItem(params);
84
- output.incrementProgress(items.length, "copyTable");
85
- } while (true);
86
- ExclusiveStartKey = info.LastEvaluatedKey;
87
- } while (ExclusiveStartKey);
88
- }
89
- /**
90
- * @inheritdoc
91
- */
92
- async _exists(uid) {
93
- // Should use find + limit 1
94
- return (await this._get(uid)) !== undefined;
95
- }
96
- /**
97
- * @inheritdoc
98
- */
99
- async _save(object, uid = object.uuid) {
100
- return this._update(object, uid);
101
- }
102
- /**
103
- * @override
104
- *
105
- * @see https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html
106
- * @see https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html
107
- */
108
- async find(query) {
109
- let scan = true;
110
- let IndexName = undefined;
111
- let result;
112
- const primaryKeys = { uuid: null };
113
- Object.keys(this.parameters.globalIndexes).forEach(name => {
114
- primaryKeys[this.parameters.globalIndexes[name].key] = name;
115
- });
116
- // We could use PartQL but localstack is not compatible
117
- const filter = new WebdaQL.AndExpression([]);
118
- let KeyConditionExpression = "";
119
- let ExpressionAttributeValues = {};
120
- const FilterExpression = [];
121
- let ExpressionAttributeNames = {};
122
- let indexNode;
123
- let sortOrder = "ASC";
124
- let processingExpression;
125
- if (!(query.filter instanceof WebdaQL.AndExpression)) {
126
- processingExpression = new WebdaQL.AndExpression([query.filter]);
127
- }
128
- else {
129
- processingExpression = query.filter;
130
- }
131
- // Search for the index
132
- processingExpression.children.some(child => {
133
- if (child instanceof WebdaQL.ComparisonExpression) {
134
- // Primary key requires equal operator
135
- if (child.operator === "=" && primaryKeys[child.attribute[0]] !== undefined) {
136
- // Query not scan
137
- scan = false;
138
- IndexName = primaryKeys[child.attribute[0]];
139
- indexNode = child;
140
- KeyConditionExpression = `#${child.attribute[0]} = :${child.attribute[0]}`;
141
- ExpressionAttributeNames[`#${child.attribute[0]}`] = child.attribute[0];
142
- ExpressionAttributeValues[`:${child.attribute[0]}`] = child.value;
143
- if (primaryKeys[child.attribute[0]] !== null &&
144
- query.orderBy &&
145
- this.parameters.globalIndexes[primaryKeys[child.attribute[0]]].sort) {
146
- const sortKey = this.parameters.globalIndexes[primaryKeys[child.attribute[0]]].sort;
147
- // Might update sort order
148
- query.orderBy.some(order => {
149
- if (order.field === sortKey) {
150
- sortOrder = order.direction;
151
- }
152
- });
153
- }
154
- return true;
155
- }
156
- }
157
- });
158
- let count = 1;
159
- // Build the Query/Filter
160
- processingExpression.children.forEach(child => {
161
- if (child === indexNode) {
162
- return;
163
- }
164
- // Only work on Comparison Node for now
165
- if (child instanceof WebdaQL.ComparisonExpression) {
166
- let operator = child.operator;
167
- // DynamoDB does not manage LIKE
168
- if (child.operator === "LIKE") {
169
- filter.children.push(child);
170
- return;
171
- }
172
- // CONTAINS -> contains (category, :category1)
173
- // != is <> in Dynamo
174
- if (operator === "!=") {
175
- operator = "<>";
176
- }
177
- // DynamoDB does not allow more than 100 items in IN
178
- if (child.operator === "IN" && child.value.length > 100) {
179
- filter.children.push(child);
180
- return;
181
- }
182
- // Subfields like team.id needs to be #a1.#a2
183
- const attr = `a${count++}`;
184
- let fullAttr = `#${attr}`;
185
- child.attribute.slice(1).forEach(v => {
186
- const subAttr = `#a${count++}`;
187
- fullAttr += `.${subAttr}`;
188
- ExpressionAttributeNames[subAttr] = v;
189
- });
190
- ExpressionAttributeNames[`#${attr}`] = child.attribute[0];
191
- let valueExpression = `:${attr}`;
192
- if (child.operator === "IN") {
193
- // Need to follow `a IN (b, c, d)
194
- valueExpression = "(" + valueExpression;
195
- ExpressionAttributeValues[`:${attr}`] = child.value[0];
196
- child.value.splice(1).forEach(v => {
197
- const subAttr = `:a${count++}`;
198
- valueExpression += `, ${subAttr}`;
199
- ExpressionAttributeValues[subAttr] = v;
200
- });
201
- valueExpression += ")";
202
- }
203
- else {
204
- // For all other just give the value
205
- ExpressionAttributeValues[`:${attr}`] = child.value;
206
- }
207
- // Manage CONTAINS
208
- if (child.operator === "CONTAINS") {
209
- FilterExpression.push(`contains(${fullAttr}, :${attr})`);
210
- return;
211
- }
212
- // If this is a sort key
213
- if (IndexName && this.parameters.globalIndexes[IndexName].sort === child.attribute[0]) {
214
- // Sort key
215
- KeyConditionExpression += ` AND ${fullAttr} ${operator} ${valueExpression}`;
216
- return;
217
- }
218
- // Otherwise fallback to normal Filter
219
- FilterExpression.push(`${fullAttr} ${operator} ${valueExpression}`);
220
- }
221
- else {
222
- filter.children.push(child);
223
- }
224
- });
225
- if (!Object.keys(ExpressionAttributeNames).length) {
226
- ExpressionAttributeNames = undefined;
227
- }
228
- if (!Object.keys(ExpressionAttributeValues).length) {
229
- ExpressionAttributeValues = undefined;
230
- }
231
- let ExclusiveStartKey = query.continuationToken
232
- ? JSON.parse(Buffer.from(query.continuationToken, "base64").toString())
233
- : undefined;
234
- // Scan if not primary key was provided
235
- if (scan) {
236
- // SHould log bad query
237
- const Items = [];
238
- do {
239
- result = await this._client.scan({
240
- TableName: this.parameters.table,
241
- FilterExpression: FilterExpression.length ? FilterExpression.join(" AND ") : undefined,
242
- ExclusiveStartKey,
243
- ExpressionAttributeNames,
244
- ExpressionAttributeValues,
245
- Limit: query.limit - Items.length
246
- });
247
- Items.push(...result.Items);
248
- result.Items = Items;
249
- ExclusiveStartKey = result.LastEvaluatedKey;
250
- } while (Items.length < query.limit && result.LastEvaluatedKey);
251
- }
252
- else {
253
- result = await this._client.query({
254
- TableName: this.parameters.table,
255
- IndexName,
256
- ExclusiveStartKey,
257
- KeyConditionExpression,
258
- FilterExpression: FilterExpression.length ? FilterExpression.join(" AND ") : undefined,
259
- ExpressionAttributeNames,
260
- ExpressionAttributeValues,
261
- Limit: query.limit,
262
- ScanIndexForward: sortOrder === "ASC" ? true : false
263
- });
264
- }
265
- return {
266
- results: result.Items.map(c => this.initModel(c)),
267
- filter,
268
- continuationToken: result.Items.length >= query.limit
269
- ? Buffer.from(JSON.stringify(result.LastEvaluatedKey)).toString("base64")
270
- : undefined
271
- };
272
- }
273
- /**
274
- * Serialize a date for DynamoDB
275
- * @param date
276
- * @returns
277
- */
278
- _serializeDate(date) {
279
- return JSON.stringify(date).replace(/"/g, "");
280
- }
281
- /**
282
- * Clean object to store in DynamoDB
283
- *
284
- * @param object
285
- * @returns
286
- */
287
- _cleanObject(object) {
288
- if (typeof object !== "object")
289
- return object;
290
- if (object instanceof Date) {
291
- return this._serializeDate(object);
292
- }
293
- if (object instanceof CoreModel) {
294
- object = object.toStoredJSON();
295
- }
296
- let res;
297
- if (object instanceof Array) {
298
- res = [];
299
- }
300
- else {
301
- res = {};
302
- }
303
- for (const i in object) {
304
- if (object[i] === "" || i.startsWith("__store")) {
305
- continue;
306
- }
307
- res[i] = this._cleanObject(object[i]);
308
- }
309
- return res;
310
- }
311
- /**
312
- * @inheritdoc
313
- */
314
- async _removeAttribute(uuid, attribute, itemWriteCondition, itemWriteConditionField) {
315
- const params = {
316
- TableName: this.parameters.table,
317
- Key: {
318
- uuid
319
- }
320
- };
321
- const attrs = {};
322
- attrs["#attr"] = attribute;
323
- attrs["#lastUpdate"] = "_lastUpdate";
324
- params.ExpressionAttributeNames = attrs;
325
- params.ConditionExpression = "attribute_exists(#uu)";
326
- params.ExpressionAttributeValues = {
327
- ":lastUpdate": this._serializeDate(new Date())
328
- };
329
- params.UpdateExpression = "REMOVE #attr SET #lastUpdate = :lastUpdate";
330
- if (itemWriteCondition) {
331
- this.setWriteCondition(params, itemWriteCondition, itemWriteConditionField);
332
- }
333
- else {
334
- attrs["#uu"] = "uuid";
335
- params.ConditionExpression = "attribute_exists(#uu)";
336
- }
337
- try {
338
- await this._client.update(params);
339
- }
340
- catch (err) {
341
- if (err instanceof ConditionalCheckFailedException) {
342
- if (!itemWriteConditionField) {
343
- throw new StoreNotFoundError(uuid, this.getName());
344
- }
345
- throw new UpdateConditionFailError(uuid, itemWriteConditionField, itemWriteCondition);
346
- }
347
- throw err;
348
- }
349
- }
350
- /**
351
- * @inheritdoc
352
- */
353
- async _deleteItemFromCollection(uid, prop, index, itemWriteCondition, itemWriteConditionField, updateDate) {
354
- const params = {
355
- TableName: this.parameters.table,
356
- Key: {
357
- uuid: uid
358
- }
359
- };
360
- const attrs = {};
361
- attrs["#" + prop] = prop;
362
- attrs["#lastUpdate"] = "_lastUpdate";
363
- params.ExpressionAttributeNames = attrs;
364
- params.ExpressionAttributeValues = {
365
- ":lastUpdate": this._serializeDate(updateDate)
366
- };
367
- params.UpdateExpression = "REMOVE #" + prop + "[" + index + "] SET #lastUpdate = :lastUpdate";
368
- if (itemWriteCondition) {
369
- params.ExpressionAttributeValues[":condValue"] = itemWriteCondition;
370
- attrs["#condName"] = prop;
371
- attrs["#field"] = itemWriteConditionField;
372
- params.ConditionExpression = "#condName[" + index + "].#field = :condValue";
373
- }
374
- try {
375
- await this._client.update(params);
376
- }
377
- catch (err) {
378
- if (err instanceof ConditionalCheckFailedException) {
379
- throw new UpdateConditionFailError(uid, itemWriteConditionField, itemWriteCondition);
380
- }
381
- else if (err.name === "ValidationException") {
382
- throw new StoreNotFoundError(uid, this.getName());
383
- }
384
- throw err;
385
- }
386
- }
387
- /**
388
- * @inheritdoc
389
- */
390
- async _upsertItemToCollection(uuid, prop, item, index, itemWriteCondition, itemWriteConditionField, updateDate) {
391
- const params = {
392
- TableName: this.parameters.table,
393
- Key: {
394
- uuid
395
- }
396
- };
397
- const attrValues = {};
398
- const attrs = {};
399
- attrs["#" + prop] = prop;
400
- attrs["#lastUpdate"] = "_lastUpdate";
401
- attrValues[":" + prop] = this._cleanObject(item);
402
- attrValues[":lastUpdate"] = this._serializeDate(updateDate);
403
- attrValues[":uuid"] = uuid;
404
- attrs["#uuid"] = this._uuidField;
405
- params.ConditionExpression = "#uuid = :uuid";
406
- params.ExpressionAttributeValues = attrValues;
407
- params.ExpressionAttributeNames = attrs;
408
- if (index === undefined) {
409
- params.UpdateExpression =
410
- "SET #" +
411
- prop +
412
- "= list_append(if_not_exists (#" +
413
- prop +
414
- ", :empty_list),:" +
415
- prop +
416
- "), #lastUpdate = :lastUpdate";
417
- attrValues[":" + prop] = [attrValues[":" + prop]];
418
- attrValues[":empty_list"] = [];
419
- }
420
- else {
421
- params.UpdateExpression = "SET #" + prop + "[" + index + "] = :" + prop + ", #lastUpdate = :lastUpdate";
422
- if (itemWriteCondition) {
423
- attrValues[":condValue"] = itemWriteCondition;
424
- attrs["#condName"] = prop;
425
- attrs["#field"] = itemWriteConditionField;
426
- params.ConditionExpression = "#condName[" + index + "].#field = :condValue and #uuid = :uuid";
427
- }
428
- }
429
- try {
430
- await this._client.update(params);
431
- }
432
- catch (err) {
433
- if (err instanceof ConditionalCheckFailedException) {
434
- throw new UpdateConditionFailError(uuid, itemWriteConditionField, itemWriteCondition);
435
- }
436
- else if (err.name === "ValidationException") {
437
- throw new StoreNotFoundError(uuid, this.getName());
438
- }
439
- throw err;
440
- }
441
- }
442
- /**
443
- * REturn the write condition as string
444
- * @param writeCondition
445
- * @param field
446
- * @returns
447
- */
448
- setWriteCondition(params, writeCondition, field = "_lastUpdate") {
449
- params.ExpressionAttributeNames ?? (params.ExpressionAttributeNames = {});
450
- params.ExpressionAttributeValues ?? (params.ExpressionAttributeValues = {});
451
- params.ExpressionAttributeNames["#cf"] = field;
452
- if (writeCondition instanceof Date) {
453
- writeCondition = this._serializeDate(writeCondition);
454
- }
455
- params.ExpressionAttributeValues[":cf"] = writeCondition;
456
- params.ConditionExpression = "#cf = :cf";
457
- }
458
- /**
459
- * @inheritdoc
460
- */
461
- async _delete(uid, writeCondition, itemWriteConditionField) {
462
- const params = {
463
- TableName: this.parameters.table,
464
- Key: {
465
- uuid: uid
466
- }
467
- };
468
- if (writeCondition) {
469
- this.setWriteCondition(params, writeCondition, itemWriteConditionField);
470
- }
471
- try {
472
- await this._client.delete(params);
473
- }
474
- catch (err) {
475
- if (err instanceof ConditionalCheckFailedException) {
476
- throw new UpdateConditionFailError(uid, itemWriteConditionField, writeCondition);
477
- }
478
- throw err;
479
- }
480
- }
481
- /**
482
- * @inheritdoc
483
- */
484
- async _patch(object, uid, itemWriteCondition, itemWriteConditionField) {
485
- object = this._cleanObject(object);
486
- let expr = "SET ";
487
- let sep = "";
488
- const attrValues = {};
489
- const attrs = {};
490
- let skipUpdate = true;
491
- let i = 1;
492
- for (const attr in object) {
493
- if (attr === "uuid" || object[attr] === undefined) {
494
- continue;
495
- }
496
- skipUpdate = false;
497
- expr += sep + "#a" + i + " = :v" + i;
498
- attrValues[":v" + i] = object[attr];
499
- attrs["#a" + i] = attr;
500
- sep = ",";
501
- i++;
502
- }
503
- if (skipUpdate) {
504
- return;
505
- }
506
- const params = {
507
- TableName: this.parameters.table,
508
- Key: {
509
- uuid: uid
510
- },
511
- UpdateExpression: expr,
512
- ExpressionAttributeValues: attrValues,
513
- ExpressionAttributeNames: attrs
514
- };
515
- // The Write Condition checks the value before writing
516
- if (itemWriteCondition) {
517
- this.setWriteCondition(params, itemWriteCondition, itemWriteConditionField);
518
- }
519
- try {
520
- await this._client.update(params);
521
- }
522
- catch (err) {
523
- if (err instanceof ConditionalCheckFailedException) {
524
- throw new UpdateConditionFailError(uid, itemWriteConditionField, itemWriteCondition);
525
- }
526
- throw err;
527
- }
528
- }
529
- /**
530
- * @inheritdoc
531
- */
532
- async _update(object, uid, itemWriteCondition, itemWriteConditionField) {
533
- object = this._cleanObject(object);
534
- object.uuid = uid;
535
- const params = {
536
- TableName: this.parameters.table,
537
- Item: object
538
- };
539
- // The Write Condition checks the value before writing
540
- if (itemWriteCondition) {
541
- this.setWriteCondition(params, itemWriteCondition, itemWriteConditionField);
542
- }
543
- try {
544
- await this._client.put(params);
545
- return object;
546
- }
547
- catch (err) {
548
- if (err instanceof ConditionalCheckFailedException) {
549
- throw new UpdateConditionFailError(uid, itemWriteConditionField, itemWriteCondition);
550
- }
551
- throw err;
552
- }
553
- }
554
- /**
555
- * @inheritdoc
556
- */
557
- async _scan(items = [], paging = undefined) {
558
- const data = await this._client.scan({
559
- TableName: this.parameters.table,
560
- Limit: this.parameters.scanPage,
561
- ExclusiveStartKey: paging
562
- });
563
- for (const i in data.Items) {
564
- items.push(this.initModel(data.Items[i]));
565
- }
566
- if (data.LastEvaluatedKey) {
567
- return this._scan(items, data.LastEvaluatedKey);
568
- }
569
- return items;
570
- }
571
- /**
572
- * @inheritdoc
573
- */
574
- async getAll(uids) {
575
- if (!uids) {
576
- return this._scan([]);
577
- }
578
- const params = {
579
- RequestItems: {}
580
- };
581
- params["RequestItems"][this.parameters.table] = {
582
- Keys: uids.map(value => {
583
- return {
584
- uuid: value
585
- };
586
- })
587
- };
588
- const result = await this._client.batchGet(params);
589
- return result.Responses[this.parameters.table].map(this.initModel, this);
590
- }
591
- /**
592
- * @inheritdoc
593
- */
594
- async _get(uid, raiseIfNotFound = false) {
595
- const params = {
596
- TableName: this.parameters.table,
597
- Key: {
598
- uuid: uid
599
- }
600
- };
601
- const item = (await this._client.get(params)).Item;
602
- if (!item) {
603
- if (raiseIfNotFound) {
604
- throw new StoreNotFoundError(uid, this.getName());
605
- }
606
- return undefined;
607
- }
608
- return this.initModel(item);
609
- }
610
- /**
611
- * @inheritdoc
612
- */
613
- async _incrementAttributes(uid, parameters, updateDate) {
614
- const params = {
615
- TableName: this.parameters.table,
616
- Key: {
617
- uuid: uid
618
- },
619
- UpdateExpression: "SET #ud = :ud ADD ",
620
- ConditionExpression: "attribute_exists(#uu)",
621
- ExpressionAttributeValues: {
622
- ":ud": this._serializeDate(updateDate)
623
- },
624
- ExpressionAttributeNames: {
625
- "#ud": "_lastUpdate",
626
- "#uu": "uuid"
627
- }
628
- };
629
- parameters.forEach((p, i) => {
630
- params.ExpressionAttributeValues[`:v${i}`] = p.value;
631
- params.ExpressionAttributeNames[`#a${i}`] = p.property;
632
- });
633
- params.UpdateExpression += parameters.map((_, i) => `#a${i} :v${i}`).join(",");
634
- try {
635
- return await this._client.update(params);
636
- }
637
- catch (err) {
638
- if (err instanceof ConditionalCheckFailedException) {
639
- throw new StoreNotFoundError(uid, this.getName());
640
- }
641
- throw err;
642
- }
643
- }
644
- /**
645
- * @inheritdoc
646
- */
647
- getARNPolicy(accountId) {
648
- const region = this.parameters.region || "us-east-1";
649
- return {
650
- Sid: this.constructor.name + this._name,
651
- Effect: "Allow",
652
- Action: [
653
- "dynamodb:BatchGetItem",
654
- "dynamodb:BatchWriteItem",
655
- "dynamodb:DeleteItem",
656
- "dynamodb:GetItem",
657
- "dynamodb:GetRecords",
658
- "dynamodb:GetShardIterator",
659
- "dynamodb:PutItem",
660
- "dynamodb:Query",
661
- "dynamodb:Scan",
662
- "dynamodb:UpdateItem"
663
- ],
664
- Resource: ["arn:aws:dynamodb:" + region + ":" + accountId + ":table/" + this.parameters.table]
665
- };
666
- }
667
- /**
668
- * @inheritdoc
669
- */
670
- async __clean() {
671
- const params = {
672
- TableName: this.parameters.table
673
- };
674
- const result = await this._client.scan(params);
675
- const promises = [];
676
- for (const i in result.Items) {
677
- promises.push(this._delete(result.Items[i].uuid));
678
- }
679
- await Promise.all(promises);
680
- }
681
- /**
682
- * @inheritdoc
683
- */
684
- getCloudFormation(deployer) {
685
- if (this.parameters.CloudFormationSkip) {
686
- return {};
687
- }
688
- const resources = {};
689
- this.parameters.CloudFormation = this.parameters.CloudFormation || {};
690
- this.parameters.CloudFormation.Table = this.parameters.CloudFormation.Table || {};
691
- const KeySchema = this.parameters.CloudFormation.KeySchema || [{ KeyType: "HASH", AttributeName: "uuid" }];
692
- const AttributeDefinitions = this.parameters.CloudFormation.AttributeDefinitions || [];
693
- this.parameters.CloudFormation.Table.BillingMode =
694
- this.parameters.CloudFormation.Table.BillingMode || "PAY_PER_REQUEST";
695
- AttributeDefinitions.push({ AttributeName: "uuid", AttributeType: "S" });
696
- resources[this._name + "DynamoTable"] = {
697
- Type: "AWS::DynamoDB::Table",
698
- Properties: {
699
- ...this.parameters.CloudFormation.Table,
700
- TableName: this.parameters.table,
701
- KeySchema,
702
- AttributeDefinitions,
703
- Tags: deployer.getDefaultTags(this.parameters.CloudFormation.Table.Tags)
704
- }
705
- };
706
- // Add any Other resources with prefix of the service
707
- return resources;
708
- }
709
- }
710
- export { DynamoStore };
711
- //# sourceMappingURL=dynamodb.js.map