@aws-amplify/graphql-api-construct 1.1.4 → 1.2.0-amplify-table-preview.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. package/.jsii +133 -80
  2. package/API.md +4 -0
  3. package/CHANGELOG.md +14 -0
  4. package/lib/amplify-graphql-api.js +1 -1
  5. package/lib/amplify-graphql-definition.js +1 -1
  6. package/lib/internal/construct-exports.js +7 -1
  7. package/lib/internal/default-parameters.js +2 -1
  8. package/lib/types.d.ts +15 -4
  9. package/lib/types.js +1 -1
  10. package/node_modules/@aws-amplify/graphql-auth-transformer/CHANGELOG.md +8 -0
  11. package/node_modules/@aws-amplify/graphql-auth-transformer/package.json +10 -10
  12. package/node_modules/@aws-amplify/graphql-default-value-transformer/CHANGELOG.md +8 -0
  13. package/node_modules/@aws-amplify/graphql-default-value-transformer/package.json +7 -7
  14. package/node_modules/@aws-amplify/graphql-function-transformer/CHANGELOG.md +4 -0
  15. package/node_modules/@aws-amplify/graphql-function-transformer/package.json +6 -7
  16. package/node_modules/@aws-amplify/graphql-http-transformer/CHANGELOG.md +4 -0
  17. package/node_modules/@aws-amplify/graphql-http-transformer/package.json +6 -7
  18. package/node_modules/@aws-amplify/graphql-index-transformer/API.md +3 -0
  19. package/node_modules/@aws-amplify/graphql-index-transformer/CHANGELOG.md +11 -0
  20. package/node_modules/@aws-amplify/graphql-index-transformer/lib/index.d.ts +1 -1
  21. package/node_modules/@aws-amplify/graphql-index-transformer/lib/index.d.ts.map +1 -1
  22. package/node_modules/@aws-amplify/graphql-index-transformer/lib/index.js +2 -1
  23. package/node_modules/@aws-amplify/graphql-index-transformer/lib/index.js.map +1 -1
  24. package/node_modules/@aws-amplify/graphql-index-transformer/lib/resolvers/resolvers.d.ts +1 -0
  25. package/node_modules/@aws-amplify/graphql-index-transformer/lib/resolvers/resolvers.d.ts.map +1 -1
  26. package/node_modules/@aws-amplify/graphql-index-transformer/lib/resolvers/resolvers.js +26 -7
  27. package/node_modules/@aws-amplify/graphql-index-transformer/lib/resolvers/resolvers.js.map +1 -1
  28. package/node_modules/@aws-amplify/graphql-index-transformer/package.json +7 -7
  29. package/node_modules/@aws-amplify/graphql-maps-to-transformer/CHANGELOG.md +8 -0
  30. package/node_modules/@aws-amplify/graphql-maps-to-transformer/lib/assets/mapping-lambda.zip +0 -0
  31. package/node_modules/@aws-amplify/graphql-maps-to-transformer/package.json +10 -10
  32. package/node_modules/@aws-amplify/graphql-model-transformer/CHANGELOG.md +14 -0
  33. package/node_modules/@aws-amplify/graphql-model-transformer/lib/graphql-model-transformer.d.ts.map +1 -1
  34. package/node_modules/@aws-amplify/graphql-model-transformer/lib/graphql-model-transformer.js +4 -0
  35. package/node_modules/@aws-amplify/graphql-model-transformer/lib/graphql-model-transformer.js.map +1 -1
  36. package/node_modules/@aws-amplify/graphql-model-transformer/lib/rds-lambda.zip +0 -0
  37. package/node_modules/@aws-amplify/graphql-model-transformer/lib/rds-notification-lambda.zip +0 -0
  38. package/node_modules/@aws-amplify/graphql-model-transformer/lib/rds-patching-lambda.zip +0 -0
  39. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/amplify-dynamodb-table/amplify-dynamo-model-resource-generator.d.ts +15 -0
  40. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/amplify-dynamodb-table/amplify-dynamo-model-resource-generator.d.ts.map +1 -0
  41. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/amplify-dynamodb-table/amplify-dynamo-model-resource-generator.js +169 -0
  42. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/amplify-dynamodb-table/amplify-dynamo-model-resource-generator.js.map +1 -0
  43. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/amplify-dynamodb-table/amplify-dynamodb-table-construct/index.d.ts +40 -0
  44. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/amplify-dynamodb-table/amplify-dynamodb-table-construct/index.d.ts.map +1 -0
  45. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/amplify-dynamodb-table/amplify-dynamodb-table-construct/index.js +242 -0
  46. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/amplify-dynamodb-table/amplify-dynamodb-table-construct/index.js.map +1 -0
  47. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/amplify-dynamodb-table/amplify-table-manager-lambda/amplify-table-manager-handler.d.ts +13 -0
  48. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/amplify-dynamodb-table/amplify-table-manager-lambda/amplify-table-manager-handler.d.ts.map +1 -0
  49. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/amplify-dynamodb-table/amplify-table-manager-lambda/amplify-table-manager-handler.js +665 -0
  50. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/amplify-dynamodb-table/amplify-table-manager-lambda/amplify-table-manager-handler.js.map +1 -0
  51. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/dynamo-model-resource-generator.d.ts +5 -2
  52. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/dynamo-model-resource-generator.d.ts.map +1 -1
  53. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/dynamo-model-resource-generator.js +46 -60
  54. package/node_modules/@aws-amplify/graphql-model-transformer/lib/resources/dynamo-model-resource-generator.js.map +1 -1
  55. package/node_modules/@aws-amplify/graphql-model-transformer/package.json +7 -6
  56. package/node_modules/@aws-amplify/graphql-predictions-transformer/CHANGELOG.md +4 -0
  57. package/node_modules/@aws-amplify/graphql-predictions-transformer/lib/predictionsLambdaFunction.zip +0 -0
  58. package/node_modules/@aws-amplify/graphql-predictions-transformer/package.json +6 -7
  59. package/node_modules/@aws-amplify/graphql-relational-transformer/CHANGELOG.md +11 -0
  60. package/node_modules/@aws-amplify/graphql-relational-transformer/lib/resolvers.d.ts.map +1 -1
  61. package/node_modules/@aws-amplify/graphql-relational-transformer/lib/resolvers.js +3 -10
  62. package/node_modules/@aws-amplify/graphql-relational-transformer/lib/resolvers.js.map +1 -1
  63. package/node_modules/@aws-amplify/graphql-relational-transformer/package.json +8 -8
  64. package/node_modules/@aws-amplify/graphql-searchable-transformer/CHANGELOG.md +8 -0
  65. package/node_modules/@aws-amplify/graphql-searchable-transformer/lib/streaming-lambda.zip +0 -0
  66. package/node_modules/@aws-amplify/graphql-searchable-transformer/package.json +7 -7
  67. package/node_modules/@aws-amplify/graphql-transformer/CHANGELOG.md +10 -0
  68. package/node_modules/@aws-amplify/graphql-transformer/package.json +14 -14
  69. package/node_modules/@aws-amplify/graphql-transformer-core/CHANGELOG.md +6 -0
  70. package/node_modules/@aws-amplify/graphql-transformer-core/lib/transformer-context/transform-parameters.d.ts.map +1 -1
  71. package/node_modules/@aws-amplify/graphql-transformer-core/lib/transformer-context/transform-parameters.js +1 -0
  72. package/node_modules/@aws-amplify/graphql-transformer-core/lib/transformer-context/transform-parameters.js.map +1 -1
  73. package/node_modules/@aws-amplify/graphql-transformer-core/package.json +4 -5
  74. package/node_modules/@aws-amplify/graphql-transformer-interfaces/API.md +1 -0
  75. package/node_modules/@aws-amplify/graphql-transformer-interfaces/CHANGELOG.md +6 -0
  76. package/node_modules/@aws-amplify/graphql-transformer-interfaces/lib/transformer-context/transform-parameters.d.ts +1 -0
  77. package/node_modules/@aws-amplify/graphql-transformer-interfaces/lib/transformer-context/transform-parameters.d.ts.map +1 -1
  78. package/node_modules/@aws-amplify/graphql-transformer-interfaces/package.json +1 -1
  79. package/node_modules/@aws-amplify/graphql-transformer-interfaces/src/transformer-context/transform-parameters.ts +1 -0
  80. package/node_modules/@aws-amplify/graphql-transformer-interfaces/tsconfig.tsbuildinfo +1 -1
  81. package/node_modules/graphql-transformer-common/API.md +3 -0
  82. package/node_modules/graphql-transformer-common/CHANGELOG.md +6 -0
  83. package/node_modules/graphql-transformer-common/lib/ResourceConstants.d.ts +3 -0
  84. package/node_modules/graphql-transformer-common/lib/ResourceConstants.d.ts.map +1 -1
  85. package/node_modules/graphql-transformer-common/lib/ResourceConstants.js +3 -0
  86. package/node_modules/graphql-transformer-common/lib/ResourceConstants.js.map +1 -1
  87. package/node_modules/graphql-transformer-common/package.json +1 -1
  88. package/package.json +16 -16
  89. package/src/internal/construct-exports.ts +6 -0
  90. package/src/internal/default-parameters.ts +1 -0
  91. package/src/types.ts +18 -4
  92. package/node_modules/@aws-amplify/graphql-function-transformer/LICENSE +0 -201
  93. package/node_modules/@aws-amplify/graphql-http-transformer/LICENSE +0 -201
  94. package/node_modules/@aws-amplify/graphql-predictions-transformer/LICENSE +0 -201
  95. package/node_modules/@aws-amplify/graphql-transformer-core/LICENSE +0 -201
@@ -0,0 +1,665 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toCreateTableInput = exports.extractTableInputFromEvent = exports.getPointInTimeRecoveryUpdate = exports.getTtlUpdate = exports.getDeletionProtectionUpdate = exports.getSseUpdate = exports.getStreamUpdate = exports.getNextGSIUpdate = exports.isComplete = exports.onEvent = void 0;
4
+ const aws_sdk_1 = require("aws-sdk");
5
+ const ddbClient = new aws_sdk_1.DynamoDB();
6
+ const finished = {
7
+ IsComplete: true,
8
+ };
9
+ const notFinished = {
10
+ IsComplete: false,
11
+ };
12
+ const log = (msg, ...other) => {
13
+ console.log(msg, other.map((o) => (typeof o === 'object' ? JSON.stringify(o, undefined, 2) : o)));
14
+ };
15
+ const onEvent = async (event) => {
16
+ var _a;
17
+ console.log(event);
18
+ const tableDef = (0, exports.extractTableInputFromEvent)(event);
19
+ console.log('Input table state: ', tableDef);
20
+ let result;
21
+ switch (event.RequestType) {
22
+ case 'Create':
23
+ console.log('Initiating CREATE event');
24
+ const createTableInput = (0, exports.toCreateTableInput)(tableDef);
25
+ console.log('Create Table Params: ', createTableInput);
26
+ const response = await createNewTable(createTableInput);
27
+ result = {
28
+ PhysicalResourceId: response.tableName,
29
+ Data: {
30
+ TableArn: response.tableArn,
31
+ TableStreamArn: response.streamArn,
32
+ TableName: response.tableName,
33
+ },
34
+ };
35
+ console.log('Returning result: ', result);
36
+ return result;
37
+ case 'Update':
38
+ if (!event.PhysicalResourceId) {
39
+ throw new Error(`Could not find the physical ID for the updated resource`);
40
+ }
41
+ console.log('Fetching current table state');
42
+ const describeTableResult = await ddbClient.describeTable({ TableName: event.PhysicalResourceId }).promise();
43
+ if (!describeTableResult.Table) {
44
+ throw new Error(`Could not find ${event.PhysicalResourceId} to update`);
45
+ }
46
+ log('Current table state: ', describeTableResult);
47
+ if (isKeySchemaModified(describeTableResult.Table.KeySchema, tableDef.keySchema)) {
48
+ console.log('Update requires replacement');
49
+ console.log('Deleting the old table');
50
+ await ddbClient.deleteTable({ TableName: event.PhysicalResourceId }).promise();
51
+ await retry(async () => await doesTableExist(event.PhysicalResourceId), (res) => res === false);
52
+ console.log(`Table '${event.PhysicalResourceId}' does not exist. Deletion is finished.`);
53
+ const createTableInput = (0, exports.toCreateTableInput)(tableDef);
54
+ const response = await createNewTable(createTableInput);
55
+ result = {
56
+ PhysicalResourceId: response.tableName,
57
+ Data: {
58
+ TableArn: response.tableArn,
59
+ TableStreamArn: response.streamArn,
60
+ TableName: response.tableName,
61
+ IsTableReplaced: true,
62
+ },
63
+ };
64
+ log('Returning result', result);
65
+ return result;
66
+ }
67
+ const describePointInTimeRecoveryResult = await ddbClient
68
+ .describeContinuousBackups({ TableName: event.PhysicalResourceId })
69
+ .promise();
70
+ console.log('Current point in time recovery: ', describePointInTimeRecoveryResult);
71
+ const pointInTimeUpdate = (0, exports.getPointInTimeRecoveryUpdate)(describePointInTimeRecoveryResult.ContinuousBackupsDescription, tableDef);
72
+ if (pointInTimeUpdate) {
73
+ log('Computed point in time recovery update', pointInTimeUpdate);
74
+ await ddbClient.updateContinuousBackups(pointInTimeUpdate).promise();
75
+ await retry(async () => await isTableReady(event.PhysicalResourceId), (res) => res === true);
76
+ console.log(`Table '${event.PhysicalResourceId}' is ready after the update of PointInTimeRecovery.`);
77
+ }
78
+ const deletionProtectionUpdate = (0, exports.getDeletionProtectionUpdate)(describeTableResult.Table, tableDef);
79
+ if (deletionProtectionUpdate) {
80
+ log('Computed deletion protection update', deletionProtectionUpdate);
81
+ await ddbClient.updateTable(deletionProtectionUpdate).promise();
82
+ await retry(async () => await isTableReady(event.PhysicalResourceId), (res) => res === true);
83
+ console.log(`Table '${event.PhysicalResourceId}' is ready after the update of deletion protection.`);
84
+ }
85
+ const sseUpdate = (0, exports.getSseUpdate)(describeTableResult.Table, tableDef);
86
+ if (sseUpdate) {
87
+ log('Computed server side encryption update', sseUpdate);
88
+ await ddbClient.updateTable(sseUpdate).promise();
89
+ await retry(async () => await isTableReady(event.PhysicalResourceId), (res) => res === true);
90
+ console.log(`Table '${event.PhysicalResourceId}' is ready after the update of sever side encryption.`);
91
+ }
92
+ const streamUpdate = await (0, exports.getStreamUpdate)(describeTableResult.Table, tableDef);
93
+ if (streamUpdate) {
94
+ log('Computed stream specification update', streamUpdate);
95
+ await ddbClient.updateTable(streamUpdate).promise();
96
+ await retry(async () => await isTableReady(event.PhysicalResourceId), (res) => res === true);
97
+ console.log(`Table '${event.PhysicalResourceId}' is ready after the update of stream specificaion.`);
98
+ }
99
+ const describeTimeToLiveResult = await ddbClient.describeTimeToLive({ TableName: event.PhysicalResourceId }).promise();
100
+ console.log('Current TTL: ', describeTimeToLiveResult);
101
+ const ttlUpdate = (0, exports.getTtlUpdate)(describeTimeToLiveResult.TimeToLiveDescription, tableDef);
102
+ if (ttlUpdate) {
103
+ log('Computed time to live update', ttlUpdate);
104
+ console.log('Initiating TTL update');
105
+ await ddbClient.updateTimeToLive(ttlUpdate).promise();
106
+ result = {
107
+ PhysicalResourceId: event.PhysicalResourceId,
108
+ Data: {
109
+ TableArn: describeTableResult.Table.TableArn,
110
+ TableStreamArn: describeTableResult.Table.LatestStreamArn,
111
+ TableName: describeTableResult.Table.TableName,
112
+ },
113
+ };
114
+ return result;
115
+ }
116
+ const nextGsiUpdate = (0, exports.getNextGSIUpdate)(describeTableResult.Table, tableDef);
117
+ if (nextGsiUpdate) {
118
+ log('Computed next update', nextGsiUpdate);
119
+ console.log('Initiating table GSI update');
120
+ await ddbClient.updateTable(nextGsiUpdate).promise();
121
+ }
122
+ result = {
123
+ PhysicalResourceId: event.PhysicalResourceId,
124
+ Data: {
125
+ TableArn: describeTableResult.Table.TableArn,
126
+ TableStreamArn: describeTableResult.Table.LatestStreamArn,
127
+ TableName: describeTableResult.Table.TableName,
128
+ },
129
+ };
130
+ return result;
131
+ case 'Delete':
132
+ if (!event.PhysicalResourceId) {
133
+ throw new Error(`Could not find the physical ID for the resource`);
134
+ }
135
+ result = {
136
+ PhysicalResourceId: event.PhysicalResourceId,
137
+ };
138
+ console.log('Fetching current table state');
139
+ const describeTableResultBeforeDeletion = await ddbClient.describeTable({ TableName: event.PhysicalResourceId }).promise();
140
+ if ((_a = describeTableResultBeforeDeletion.Table) === null || _a === void 0 ? void 0 : _a.DeletionProtectionEnabled) {
141
+ return result;
142
+ }
143
+ try {
144
+ console.log('Initiating table deletion');
145
+ await ddbClient.deleteTable({ TableName: event.PhysicalResourceId }).promise();
146
+ return result;
147
+ }
148
+ catch (err) {
149
+ if (err.code === 'ResourceNotFoundException') {
150
+ return result;
151
+ }
152
+ throw err;
153
+ }
154
+ default:
155
+ throw new Error(`Event type ${event.RequestType} is not supported`);
156
+ }
157
+ };
158
+ exports.onEvent = onEvent;
159
+ const isComplete = async (event) => {
160
+ var _a, _b, _c;
161
+ log('got event', event);
162
+ if (event.RequestType === 'Delete') {
163
+ console.log('Delete is finished');
164
+ return finished;
165
+ }
166
+ if (!event.PhysicalResourceId) {
167
+ throw new Error('PhysicalResourceId not set in call to isComplete');
168
+ }
169
+ console.log('Fetching current table state');
170
+ const describeTableResult = await retry(async () => await ddbClient.describeTable({ TableName: event.PhysicalResourceId }).promise(), (result) => !!(result === null || result === void 0 ? void 0 : result.Table));
171
+ if (((_a = describeTableResult.Table) === null || _a === void 0 ? void 0 : _a.TableStatus) !== 'ACTIVE') {
172
+ console.log('Table not active yet');
173
+ return notFinished;
174
+ }
175
+ if ((_b = describeTableResult.Table.GlobalSecondaryIndexes) === null || _b === void 0 ? void 0 : _b.some((gsi) => gsi.IndexStatus !== 'ACTIVE' || gsi.Backfilling)) {
176
+ console.log('Some GSI is not active yet');
177
+ return notFinished;
178
+ }
179
+ const endState = (0, exports.extractTableInputFromEvent)(event);
180
+ if (event.RequestType === 'Create' || ((_c = event.Data) === null || _c === void 0 ? void 0 : _c.IsTableReplaced) === true) {
181
+ const describePointInTimeRecoveryResult = await ddbClient.describeContinuousBackups({ TableName: event.PhysicalResourceId }).promise();
182
+ const pointInTimeUpdate = (0, exports.getPointInTimeRecoveryUpdate)(describePointInTimeRecoveryResult.ContinuousBackupsDescription, endState);
183
+ if (pointInTimeUpdate) {
184
+ console.log('Updating table with point in time recovery enabled');
185
+ await ddbClient.updateContinuousBackups(pointInTimeUpdate).promise();
186
+ return notFinished;
187
+ }
188
+ const describeTimeToLiveResult = await ddbClient.describeTimeToLive({ TableName: event.PhysicalResourceId }).promise();
189
+ const ttlUpdate = (0, exports.getTtlUpdate)(describeTimeToLiveResult.TimeToLiveDescription, endState);
190
+ if (ttlUpdate) {
191
+ console.log('Updating table with TTL enabled');
192
+ await ddbClient.updateTimeToLive(ttlUpdate).promise();
193
+ return notFinished;
194
+ }
195
+ console.log('Create is finished');
196
+ return finished;
197
+ }
198
+ const nextUpdate = (0, exports.getNextGSIUpdate)(describeTableResult.Table, endState);
199
+ log('Computed next update', nextUpdate);
200
+ if (!nextUpdate) {
201
+ console.log('No additional updates needed. Update finished');
202
+ return finished;
203
+ }
204
+ console.log('Initiating table update');
205
+ await ddbClient.updateTable(nextUpdate).promise();
206
+ return notFinished;
207
+ };
208
+ exports.isComplete = isComplete;
209
+ const getNextGSIUpdate = (currentState, endState) => {
210
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
211
+ const endStateGSIs = endState.globalSecondaryIndexes || [];
212
+ const endStateGSINames = endStateGSIs.map((gsi) => gsi.indexName);
213
+ const currentStateGSIs = currentState.GlobalSecondaryIndexes || [];
214
+ const currentStateGSINames = currentStateGSIs.map((gsi) => gsi.IndexName);
215
+ const isTableBillingModeModified = (((_a = currentState.BillingModeSummary) === null || _a === void 0 ? void 0 : _a.BillingMode) !== undefined && ((_b = currentState.BillingModeSummary) === null || _b === void 0 ? void 0 : _b.BillingMode) !== endState.billingMode) ||
216
+ (((_c = currentState.BillingModeSummary) === null || _c === void 0 ? void 0 : _c.BillingMode) == undefined && endState.billingMode === 'PAY_PER_REQUEST');
217
+ const isTableProvisionThroughputModified = (((_d = endState.provisionedThroughput) === null || _d === void 0 ? void 0 : _d.readCapacityUnits) !== undefined &&
218
+ ((_e = currentState.ProvisionedThroughput) === null || _e === void 0 ? void 0 : _e.ReadCapacityUnits) !== ((_f = endState.provisionedThroughput) === null || _f === void 0 ? void 0 : _f.readCapacityUnits)) ||
219
+ (((_g = endState.provisionedThroughput) === null || _g === void 0 ? void 0 : _g.writeCapacityUnits) !== undefined &&
220
+ ((_h = currentState.ProvisionedThroughput) === null || _h === void 0 ? void 0 : _h.WriteCapacityUnits) !== ((_j = endState.provisionedThroughput) === null || _j === void 0 ? void 0 : _j.writeCapacityUnits));
221
+ if (isTableBillingModeModified || isTableProvisionThroughputModified) {
222
+ let updateInput = {
223
+ TableName: currentState.TableName,
224
+ BillingMode: isTableBillingModeModified ? endState.billingMode : undefined,
225
+ ProvisionedThroughput: isTableProvisionThroughputModified && endState.billingMode === 'PROVISIONED'
226
+ ? {
227
+ ReadCapacityUnits: (_k = endState.provisionedThroughput) === null || _k === void 0 ? void 0 : _k.readCapacityUnits,
228
+ WriteCapacityUnits: (_l = endState.provisionedThroughput) === null || _l === void 0 ? void 0 : _l.writeCapacityUnits,
229
+ }
230
+ : undefined,
231
+ };
232
+ if (isTableBillingModeModified && endState.billingMode === 'PROVISIONED') {
233
+ const indexToBeUpdated = currentStateGSIs.map((gsiToUpdate) => {
234
+ var _a, _b;
235
+ return {
236
+ Update: {
237
+ IndexName: gsiToUpdate.IndexName,
238
+ ProvisionedThroughput: {
239
+ ReadCapacityUnits: (_a = endState.provisionedThroughput) === null || _a === void 0 ? void 0 : _a.readCapacityUnits,
240
+ WriteCapacityUnits: (_b = endState.provisionedThroughput) === null || _b === void 0 ? void 0 : _b.writeCapacityUnits,
241
+ },
242
+ },
243
+ };
244
+ });
245
+ updateInput = {
246
+ ...updateInput,
247
+ GlobalSecondaryIndexUpdates: indexToBeUpdated.length > 0 ? indexToBeUpdated : undefined,
248
+ };
249
+ }
250
+ return parsePropertiesToDynamoDBInput(updateInput);
251
+ }
252
+ const gsiRequiresReplacementPredicate = (currentGSI) => {
253
+ if (!endStateGSINames.includes(currentGSI.IndexName))
254
+ return true;
255
+ const respectiveEndStateGSI = endStateGSIs.find((endStateGSI) => endStateGSI.indexName === currentGSI.IndexName);
256
+ if (isProjectionModified(currentGSI.Projection, respectiveEndStateGSI.projection))
257
+ return true;
258
+ if (isKeySchemaModified(currentGSI.KeySchema, respectiveEndStateGSI.keySchema))
259
+ return true;
260
+ return false;
261
+ };
262
+ const gsiToRemove = currentStateGSIs.find(gsiRequiresReplacementPredicate);
263
+ if (gsiToRemove) {
264
+ return {
265
+ TableName: currentState.TableName,
266
+ GlobalSecondaryIndexUpdates: [
267
+ {
268
+ Delete: {
269
+ IndexName: gsiToRemove.IndexName,
270
+ },
271
+ },
272
+ ],
273
+ };
274
+ }
275
+ const gsiRequiresCreationPredicate = (endStateGSI) => !currentStateGSINames.includes(endStateGSI.indexName);
276
+ const gsiToAdd = endStateGSIs.find(gsiRequiresCreationPredicate);
277
+ if (gsiToAdd) {
278
+ const attributeNamesToInclude = gsiToAdd.keySchema.map((schema) => schema.attributeName);
279
+ const gsiToAddAction = {
280
+ IndexName: gsiToAdd.indexName,
281
+ KeySchema: gsiToAdd.keySchema,
282
+ Projection: gsiToAdd.projection,
283
+ ProvisionedThroughput: gsiToAdd.provisionedThroughput,
284
+ };
285
+ return {
286
+ TableName: currentState.TableName,
287
+ AttributeDefinitions: (_m = endState.attributeDefinitions) === null || _m === void 0 ? void 0 : _m.filter((def) => attributeNamesToInclude.includes(def.attributeName)).map((def) => usePascalCaseForObjectKeys(def)),
288
+ GlobalSecondaryIndexUpdates: [
289
+ {
290
+ Create: parsePropertiesToDynamoDBInput(gsiToAddAction),
291
+ },
292
+ ],
293
+ };
294
+ }
295
+ const gsiRequiresUpdatePredicate = (endStateGSI) => {
296
+ var _a, _b, _c, _d;
297
+ if (endState.provisionedThroughput &&
298
+ endState.provisionedThroughput.readCapacityUnits &&
299
+ endState.provisionedThroughput.writeCapacityUnits &&
300
+ currentStateGSINames.includes(endStateGSI.indexName)) {
301
+ const currentStateGSI = currentStateGSIs.find((gsi) => gsi.IndexName === endStateGSI.indexName);
302
+ if (currentStateGSI) {
303
+ if (((_a = currentStateGSI.ProvisionedThroughput) === null || _a === void 0 ? void 0 : _a.ReadCapacityUnits) !== ((_b = endStateGSI.provisionedThroughput) === null || _b === void 0 ? void 0 : _b.readCapacityUnits) ||
304
+ ((_c = currentStateGSI.ProvisionedThroughput) === null || _c === void 0 ? void 0 : _c.WriteCapacityUnits) !== ((_d = endStateGSI.provisionedThroughput) === null || _d === void 0 ? void 0 : _d.writeCapacityUnits)) {
305
+ return true;
306
+ }
307
+ }
308
+ }
309
+ return false;
310
+ };
311
+ const gsiToUpdate = endStateGSIs.find(gsiRequiresUpdatePredicate);
312
+ if (gsiToUpdate) {
313
+ return {
314
+ TableName: currentState.TableName,
315
+ GlobalSecondaryIndexUpdates: [
316
+ {
317
+ Update: {
318
+ IndexName: gsiToUpdate.indexName,
319
+ ProvisionedThroughput: {
320
+ ReadCapacityUnits: (_o = gsiToUpdate.provisionedThroughput) === null || _o === void 0 ? void 0 : _o.readCapacityUnits,
321
+ WriteCapacityUnits: (_p = gsiToUpdate.provisionedThroughput) === null || _p === void 0 ? void 0 : _p.writeCapacityUnits,
322
+ },
323
+ },
324
+ },
325
+ ],
326
+ };
327
+ }
328
+ return undefined;
329
+ };
330
+ exports.getNextGSIUpdate = getNextGSIUpdate;
331
+ const getStreamUpdate = async (currentState, endState) => {
332
+ var _a, _b, _c, _d, _e, _f;
333
+ let streamUpdate;
334
+ if (((_a = endState.streamSpecification) === null || _a === void 0 ? void 0 : _a.streamViewType) !== undefined &&
335
+ (currentState.StreamSpecification === undefined || currentState.StreamSpecification.StreamEnabled === false)) {
336
+ streamUpdate = { StreamEnabled: true, StreamViewType: endState.streamSpecification.streamViewType };
337
+ }
338
+ else if (((_b = endState.streamSpecification) === null || _b === void 0 ? void 0 : _b.streamViewType) === undefined && ((_c = currentState.StreamSpecification) === null || _c === void 0 ? void 0 : _c.StreamEnabled) === true) {
339
+ streamUpdate = { StreamEnabled: false };
340
+ }
341
+ else if (((_d = currentState.StreamSpecification) === null || _d === void 0 ? void 0 : _d.StreamEnabled) === true &&
342
+ ((_e = endState.streamSpecification) === null || _e === void 0 ? void 0 : _e.streamViewType) !== undefined &&
343
+ currentState.StreamSpecification.StreamViewType !== ((_f = endState.streamSpecification) === null || _f === void 0 ? void 0 : _f.streamViewType)) {
344
+ console.log('Detect stream view type is changed. Disabling stream before the type change.');
345
+ await ddbClient
346
+ .updateTable({
347
+ TableName: currentState.TableName,
348
+ StreamSpecification: { StreamEnabled: false },
349
+ })
350
+ .promise();
351
+ await retry(async () => await isTableReady(currentState.TableName), (res) => res === true);
352
+ streamUpdate = { StreamEnabled: true, StreamViewType: endState.streamSpecification.streamViewType };
353
+ }
354
+ if (streamUpdate) {
355
+ return {
356
+ TableName: currentState.TableName,
357
+ StreamSpecification: streamUpdate,
358
+ };
359
+ }
360
+ return undefined;
361
+ };
362
+ exports.getStreamUpdate = getStreamUpdate;
363
+ const getSseUpdate = (currentState, endState) => {
364
+ var _a, _b, _c;
365
+ let sseUpdate;
366
+ if (currentState.SSEDescription) {
367
+ if (!((_a = endState.sseSpecification) === null || _a === void 0 ? void 0 : _a.sseEnabled)) {
368
+ sseUpdate = {
369
+ Enabled: false,
370
+ };
371
+ }
372
+ else if (((_b = endState.sseSpecification) === null || _b === void 0 ? void 0 : _b.sseEnabled) === true &&
373
+ endState.sseSpecification.sseType !== undefined &&
374
+ endState.sseSpecification.sseType !== currentState.SSEDescription.SSEType) {
375
+ sseUpdate = {
376
+ Enabled: true,
377
+ SSEType: endState.sseSpecification.sseType,
378
+ KMSMasterKeyId: endState.sseSpecification.kmsMasterKeyId,
379
+ };
380
+ }
381
+ }
382
+ else {
383
+ if ((_c = endState.sseSpecification) === null || _c === void 0 ? void 0 : _c.sseEnabled) {
384
+ sseUpdate = {
385
+ Enabled: true,
386
+ SSEType: endState.sseSpecification.sseType,
387
+ KMSMasterKeyId: endState.sseSpecification.kmsMasterKeyId,
388
+ };
389
+ }
390
+ }
391
+ if (sseUpdate) {
392
+ return parsePropertiesToDynamoDBInput({
393
+ TableName: currentState.TableName,
394
+ SSESpecification: sseUpdate,
395
+ });
396
+ }
397
+ return undefined;
398
+ };
399
+ exports.getSseUpdate = getSseUpdate;
400
+ const getDeletionProtectionUpdate = (currentState, endState) => {
401
+ if (endState.deletionProtectionEnabled !== undefined && currentState.DeletionProtectionEnabled !== endState.deletionProtectionEnabled) {
402
+ return {
403
+ TableName: currentState.TableName,
404
+ DeletionProtectionEnabled: endState.deletionProtectionEnabled,
405
+ };
406
+ }
407
+ else if (endState.deletionProtectionEnabled === undefined && currentState.DeletionProtectionEnabled === true) {
408
+ return {
409
+ TableName: currentState.TableName,
410
+ DeletionProtectionEnabled: false,
411
+ };
412
+ }
413
+ return undefined;
414
+ };
415
+ exports.getDeletionProtectionUpdate = getDeletionProtectionUpdate;
416
+ const getTtlUpdate = (currentTTL, endState) => {
417
+ const endTTL = endState.timeToLiveSpecification;
418
+ if (currentTTL && currentTTL.TimeToLiveStatus) {
419
+ if (currentTTL.TimeToLiveStatus === 'ENABLED' && currentTTL.AttributeName) {
420
+ if (!endTTL || !endTTL.enabled) {
421
+ return {
422
+ TableName: endState.tableName,
423
+ TimeToLiveSpecification: {
424
+ Enabled: false,
425
+ AttributeName: currentTTL.AttributeName,
426
+ },
427
+ };
428
+ }
429
+ else if (currentTTL.AttributeName !== endTTL.attributeName) {
430
+ return {
431
+ TableName: endState.tableName,
432
+ TimeToLiveSpecification: {
433
+ Enabled: true,
434
+ AttributeName: endTTL.attributeName,
435
+ },
436
+ };
437
+ }
438
+ }
439
+ else if (currentTTL.TimeToLiveStatus === 'DISABLED' && endTTL && endTTL.enabled) {
440
+ return {
441
+ TableName: endState.tableName,
442
+ TimeToLiveSpecification: {
443
+ Enabled: true,
444
+ AttributeName: endTTL.attributeName,
445
+ },
446
+ };
447
+ }
448
+ }
449
+ return undefined;
450
+ };
451
+ exports.getTtlUpdate = getTtlUpdate;
452
+ const getPointInTimeRecoveryUpdate = (currentPointInTime, endState) => {
453
+ var _a, _b;
454
+ if (!currentPointInTime) {
455
+ return undefined;
456
+ }
457
+ const currentStatus = (_a = currentPointInTime.PointInTimeRecoveryDescription) === null || _a === void 0 ? void 0 : _a.PointInTimeRecoveryStatus;
458
+ const endStatus = (_b = endState.pointInTimeRecoverySpecification) === null || _b === void 0 ? void 0 : _b.pointInTimeRecoveryEnabled;
459
+ if (endStatus === undefined || endStatus === false) {
460
+ if (currentStatus === 'ENABLED') {
461
+ return {
462
+ TableName: endState.tableName,
463
+ PointInTimeRecoverySpecification: {
464
+ PointInTimeRecoveryEnabled: false,
465
+ },
466
+ };
467
+ }
468
+ }
469
+ else {
470
+ if (currentStatus === 'DISABLED') {
471
+ return {
472
+ TableName: endState.tableName,
473
+ PointInTimeRecoverySpecification: {
474
+ PointInTimeRecoveryEnabled: true,
475
+ },
476
+ };
477
+ }
478
+ }
479
+ return undefined;
480
+ };
481
+ exports.getPointInTimeRecoveryUpdate = getPointInTimeRecoveryUpdate;
482
+ const extractTableInputFromEvent = (event) => {
483
+ const resourceProperties = { ...event.ResourceProperties };
484
+ delete resourceProperties.ServiceToken;
485
+ const tableDef = convertStringToBooleanOrNumber(resourceProperties);
486
+ return tableDef;
487
+ };
488
+ exports.extractTableInputFromEvent = extractTableInputFromEvent;
489
+ const parsePropertiesToDynamoDBInput = (obj) => {
490
+ return usePascalCaseForObjectKeys(removeUndefinedAttributes(obj));
491
+ };
492
+ const usePascalCaseForObjectKeys = (obj) => {
493
+ const result = {};
494
+ for (const key in obj) {
495
+ if (obj.hasOwnProperty(key) && key !== '') {
496
+ const capitalizedKey = key.charAt(0).toUpperCase() + key.slice(1);
497
+ const value = obj[key];
498
+ if (Array.isArray(value)) {
499
+ result[capitalizedKey] = value.map((v) => usePascalCaseForObjectKeys(v));
500
+ }
501
+ else if (typeof value === 'object' && value !== null) {
502
+ result[capitalizedKey] = usePascalCaseForObjectKeys(value);
503
+ }
504
+ else {
505
+ result[capitalizedKey] = value;
506
+ }
507
+ }
508
+ }
509
+ return result;
510
+ };
511
+ const convertStringToBooleanOrNumber = (obj) => {
512
+ for (const key in obj) {
513
+ if (Array.isArray(obj[key])) {
514
+ obj[key] = obj[key].map((o) => convertStringToBooleanOrNumber(o));
515
+ }
516
+ else if (typeof obj[key] === 'object') {
517
+ obj[key] = convertStringToBooleanOrNumber(obj[key]);
518
+ }
519
+ else if (typeof obj[key] === 'string') {
520
+ if (obj[key] === 'true' || obj[key] === 'false') {
521
+ obj[key] = obj[key] === 'true';
522
+ }
523
+ else if (!isNaN(Number(obj[key]))) {
524
+ obj[key] = Number(obj[key]);
525
+ }
526
+ }
527
+ }
528
+ return obj;
529
+ };
530
+ const removeUndefinedAttributes = (obj) => {
531
+ for (const key in obj) {
532
+ if (Array.isArray(obj[key])) {
533
+ obj[key].map((o) => removeUndefinedAttributes(o));
534
+ }
535
+ else if (typeof obj[key] === 'object') {
536
+ removeUndefinedAttributes(obj[key]);
537
+ }
538
+ else if (obj[key] === undefined) {
539
+ delete obj[key];
540
+ }
541
+ }
542
+ return obj;
543
+ };
544
+ const toCreateTableInput = (props) => {
545
+ const createTableInput = {
546
+ TableName: props.tableName,
547
+ AttributeDefinitions: props.attributeDefinitions,
548
+ KeySchema: props.keySchema,
549
+ GlobalSecondaryIndexes: props.globalSecondaryIndexes,
550
+ BillingMode: props.billingMode,
551
+ StreamSpecification: props.streamSpecification
552
+ ? {
553
+ StreamEnabled: true,
554
+ StreamViewType: props.streamSpecification.streamViewType,
555
+ }
556
+ : undefined,
557
+ ProvisionedThroughput: props.provisionedThroughput,
558
+ SSESpecification: props.sseSpecification ? { Enabled: props.sseSpecification.sseEnabled } : undefined,
559
+ };
560
+ return parsePropertiesToDynamoDBInput(createTableInput);
561
+ };
562
+ exports.toCreateTableInput = toCreateTableInput;
563
+ const createNewTable = async (input) => {
564
+ var _a, _b;
565
+ const tableName = input.TableName;
566
+ const createTableInput = input;
567
+ const result = await ddbClient.createTable(createTableInput).promise();
568
+ return { tableName, tableArn: (_a = result.TableDescription) === null || _a === void 0 ? void 0 : _a.TableArn, streamArn: (_b = result.TableDescription) === null || _b === void 0 ? void 0 : _b.LatestStreamArn };
569
+ };
570
+ const doesTableExist = async (tableName) => {
571
+ try {
572
+ await ddbClient.describeTable({ TableName: tableName }).promise();
573
+ return true;
574
+ }
575
+ catch (error) {
576
+ if (error.code === 'ResourceNotFoundException') {
577
+ return false;
578
+ }
579
+ throw error;
580
+ }
581
+ };
582
+ const isTableReady = async (tableName) => {
583
+ var _a, _b;
584
+ const result = await ddbClient.describeTable({ TableName: tableName }).promise();
585
+ if (((_a = result.Table) === null || _a === void 0 ? void 0 : _a.TableStatus) !== 'ACTIVE') {
586
+ console.log('Table not active yet');
587
+ return false;
588
+ }
589
+ if ((_b = result.Table.GlobalSecondaryIndexes) === null || _b === void 0 ? void 0 : _b.some((gsi) => gsi.IndexStatus !== 'ACTIVE' || gsi.Backfilling)) {
590
+ console.log('Some GSI is not active yet');
591
+ return false;
592
+ }
593
+ return true;
594
+ };
595
+ const isProjectionModified = (currentProjection, endProjection) => {
596
+ if (currentProjection.ProjectionType !== endProjection.projectionType)
597
+ return true;
598
+ if (currentProjection.ProjectionType === 'ALL')
599
+ return false;
600
+ const currentNonKeyAttributes = currentProjection.NonKeyAttributes || [];
601
+ const endNonKeyAttributes = endProjection.nonKeyAttributes || [];
602
+ if (currentNonKeyAttributes.length !== endNonKeyAttributes.length)
603
+ return true;
604
+ if (currentNonKeyAttributes.some((currentNonKeyAttribute) => !endNonKeyAttributes.includes(currentNonKeyAttribute)))
605
+ return true;
606
+ return false;
607
+ };
608
+ const isKeySchemaModified = (currentSchema, endSchema) => {
609
+ const currentHashKey = currentSchema.find((schema) => schema.KeyType === 'HASH');
610
+ const endHashKey = endSchema.find((schema) => schema.keyType === 'HASH');
611
+ if ((currentHashKey === null || currentHashKey === void 0 ? void 0 : currentHashKey.AttributeName) !== (endHashKey === null || endHashKey === void 0 ? void 0 : endHashKey.attributeName))
612
+ return true;
613
+ const currentSortKey = currentSchema.find((schema) => schema.KeyType === 'RANGE');
614
+ const endSortKey = endSchema.find((schema) => schema.keyType === 'RANGE');
615
+ if (currentSortKey === undefined && endSortKey === undefined)
616
+ return false;
617
+ if ((currentSortKey === undefined && endSortKey !== undefined) || (currentSortKey !== undefined && endSortKey === undefined))
618
+ return true;
619
+ if ((currentSortKey === null || currentSortKey === void 0 ? void 0 : currentSortKey.AttributeName) !== (endSortKey === null || endSortKey === void 0 ? void 0 : endSortKey.attributeName))
620
+ return true;
621
+ return false;
622
+ };
623
+ const defaultSettings = {
624
+ times: Infinity,
625
+ delayMS: 1000 * 15,
626
+ timeoutMS: 1000 * 60 * 14,
627
+ stopOnError: false,
628
+ };
629
+ const retry = async (func, successPredicate, settings, failurePredicate) => {
630
+ const { times, delayMS, timeoutMS, stopOnError } = {
631
+ ...defaultSettings,
632
+ ...settings,
633
+ };
634
+ let count = 0;
635
+ let result;
636
+ let terminate = false;
637
+ const startTime = Date.now();
638
+ do {
639
+ try {
640
+ result = await func();
641
+ if (successPredicate(result)) {
642
+ return result;
643
+ }
644
+ if (typeof failurePredicate === 'function' && failurePredicate(result)) {
645
+ throw new Error('Retry-able function execution result matched failure predicate. Stopping retries.');
646
+ }
647
+ console.warn(`Retry-able function execution did not match success predicate. Result was [${JSON.stringify(result)}]. Retrying...`);
648
+ }
649
+ catch (err) {
650
+ console.warn(`Retry-able function execution failed with [${err.message || err}]`);
651
+ if (stopOnError) {
652
+ console.log('Stopping retries on error.');
653
+ }
654
+ else {
655
+ console.log('Retrying...');
656
+ }
657
+ terminate = stopOnError;
658
+ }
659
+ count++;
660
+ await sleep(delayMS);
661
+ } while (!terminate && count <= times && Date.now() - startTime < timeoutMS);
662
+ throw new Error('Retry-able function did not match predicate within the given retry constraints');
663
+ };
664
+ const sleep = async (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
665
+ //# sourceMappingURL=amplify-table-manager-handler.js.map