@izara_project/izara-core-generate-service-code 1.0.78 → 1.0.80
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/package.json +2 -2
- package/src/compile/flowValidator.js +163 -0
- package/src/compile/loadSchemas.js +15 -5
- package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +137 -7
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +137 -17
- package/src/emit/crud/crudActionPlan.js +82 -0
- package/src/emit/crud/emitCrudApplicationArtifacts.js +169 -112
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +43 -65
- package/src/emit/crud/generateDynamicCrudFlowSchemas.js +4 -1
- package/src/emit/crud/templates/CreateComplete_Main.ejs +8 -3
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +90 -513
- package/src/emit/crud/templates/CreateLogicalLib.ejs +541 -0
- package/src/emit/crud/templates/DeleteComplete_Main.ejs +8 -3
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +93 -203
- package/src/emit/crud/templates/DeleteLogicalLib.ejs +213 -0
- package/src/emit/crud/templates/FlowEndpointRbacCallback_Main.ejs +217 -0
- package/src/emit/crud/templates/GetEndpoint_Main.ejs +1 -1
- package/src/emit/crud/templates/GetRangeEndpoint_Main.ejs +118 -37
- package/src/emit/crud/templates/UpdateComplete_Main.ejs +8 -3
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +92 -444
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +477 -0
- package/src/emit/custom/customFlows.js +27 -2
- package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +1 -2
- package/src/emit/custom/templates/FlowEndpoint_Main.ejs +10 -3
- package/src/emit/custom/templates/FlowStep_Main.ejs +1 -1
- package/src/emit/custom/templates/s3/CreateObject_Main.ejs +1 -1
- package/src/emit/custom/templates/triggerCache/CheckTriggerCache_HdrSqs.ejs +2 -2
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +3 -9
- package/src/emit/rbac/emitRbacApplicationArtifacts.js +21 -16
- package/src/emit/rbac/rbacFlowTag.js +2 -7
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +148 -21
- package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +4 -2
- package/src/emit/relationship/templates/ChangeRelationshipComplete_Main.ejs +7 -2
- package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +6 -2
- package/src/emit/relationship/templates/CreateRelationshipComplete_Main.ejs +7 -2
- package/src/emit/relationship/templates/CreateRelationship_Main.ejs +6 -2
- package/src/emit/relationship/templates/DeleteRelationshipComplete_Main.ejs +7 -2
- package/src/emit/relationship/templates/DeleteRelationship_Main.ejs +6 -2
- package/src/emit/relationship/templates/GetRelationship_Main.ejs +1 -1
- package/src/emit/relationship/templates/MoveRelationshipComplete_Main.ejs +7 -2
- package/src/emit/relationship/templates/MoveRelationship_Main.ejs +6 -2
- package/src/emit/relationship/templates/UpdateRelationshipComplete_Main.ejs +7 -2
- package/src/emit/relationship/templates/UpdateRelationship_Main.ejs +6 -2
- package/src/emit/resource/emitResourceArtifacts.js +149 -79
- package/src/emit/resource/templates/DynamoDBTable_Yaml.ejs +4 -4
- package/src/emit/resource/templates/GeneratedLambdaRoleServiceConfig.ejs +31 -5
- package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +21 -0
- package/src/emit/resource/templates/WebSocketSubscription_Yaml.ejs +7 -0
- package/src/emit/shared/templates/FlowHandler_HdrApi.ejs +1 -1
- package/src/emit/shared/templates/FlowHandler_HdrDsq.ejs +2 -2
- package/src/emit/shared/templates/FlowHandler_HdrInv.ejs +1 -1
- package/src/emit/shared/templates/FlowHandler_HdrSqs.ejs +2 -2
- package/src/emit/systemText/emitSystemTextSchemas.js +246 -0
- package/src/emit/systemText/templates/SystemTextSchemas.ejs +10 -0
- package/src/generate.js +55 -8
- package/test/crudApplicationArtifacts.test.js +158 -19
- package/test/customFlowApplicationArtifacts.test.js +307 -16
- package/test/dynamicCrudFlowSchemas.test.js +150 -14
- package/test/dynamicRbacFlowSchemas.test.js +2 -2
- package/test/dynamicRelationshipFlowSchemas.test.js +1 -1
- package/test/graphDrivenFlowSchema.test.js +257 -0
- package/test/publicApi.test.js +14 -5
- package/test/resourceArtifacts.test.js +66 -19
- package/test/systemTextSchemas.test.js +154 -0
- package/src/emit/crud/templates/CreateComplete_HdrSqs.ejs +0 -99
- package/src/emit/crud/templates/DeleteComplete_HdrSqs.ejs +0 -99
- package/src/emit/crud/templates/FlowEndpointBeforeLogical_Main.ejs +0 -174
- package/src/emit/crud/templates/FlowEndpointComplete_Main.ejs +0 -187
- package/src/emit/crud/templates/UpdateComplete_HdrSqs.ejs +0 -99
- package/src/emit/resource/templates/ResourceBeforeLogicalYaml.ejs +0 -47
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (C) 2021 Sven Mason <http://izara.io>
|
|
3
|
+
|
|
4
|
+
This program is free software: you can redistribute it and/or modify
|
|
5
|
+
it under the terms of the GNU Affero General Public License as
|
|
6
|
+
published by the Free Software Foundation, either version 3 of the
|
|
7
|
+
License, or (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
This program is distributed in the hope that it will be useful,
|
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
GNU Affero General Public License for more details.
|
|
13
|
+
|
|
14
|
+
You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
objectHash as hash,
|
|
20
|
+
identifierUuid
|
|
21
|
+
} from '@izara_project/izara-shared-core';
|
|
22
|
+
import asyncFlowSharedLib from '@izara_project/izara-core-library-asynchronous-flow';
|
|
23
|
+
import {
|
|
24
|
+
utils,
|
|
25
|
+
uploadUseCase,
|
|
26
|
+
getObjectSchema
|
|
27
|
+
} from '@izara_project/izara-core-library-service-schemas';
|
|
28
|
+
import snsSharedLib from '@izara_project/izara-core-library-sns';
|
|
29
|
+
import { sns } from '@izara_project/izara-core-library-external-request';
|
|
30
|
+
|
|
31
|
+
const { createObjType } = utils;
|
|
32
|
+
|
|
33
|
+
import { <%- flowTag %>LogicalLib } from './<%- upperCaseFlowTag %>LogicalLib.js';
|
|
34
|
+
|
|
35
|
+
//(<optionalRequire>)
|
|
36
|
+
//(</optionalRequire>)
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Handles callback after RbacCallback phase — verifies awaitingStep then proceeds to next phase
|
|
40
|
+
* @param {Object} _izContext - Context object with logger
|
|
41
|
+
* @param {Object} requestParams - { fieldNames, relationships[] }
|
|
42
|
+
* @param {Object} callingFlowConfig - Calling flow configuration
|
|
43
|
+
* @returns {Promise<Object>}
|
|
44
|
+
*/
|
|
45
|
+
export default async function <%- flowTag %>RbacCallbackMain(
|
|
46
|
+
_izContext,
|
|
47
|
+
requestParams,
|
|
48
|
+
flowTag,
|
|
49
|
+
callingFlowConfig = {}
|
|
50
|
+
) {
|
|
51
|
+
try {
|
|
52
|
+
_izContext.logger.debug('[<%- flowTag %>RbacCallbackMain] Started with params:', {
|
|
53
|
+
requestParams,
|
|
54
|
+
flowTag,
|
|
55
|
+
callingFlowConfig
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const parts = requestParams.parentFlowId.split('_');
|
|
59
|
+
const rbacType = parts.pop();
|
|
60
|
+
const rbacPendingStepId = '<%- flowTag %>RbacCallback_' + parts.join('_');
|
|
61
|
+
const currentAwaitingStepId = requestParams.parentFlowId;
|
|
62
|
+
|
|
63
|
+
_izContext.logger.debug(
|
|
64
|
+
'[<%- flowTag %>RbacCallbackMain] Parsed RBAC pending details:',
|
|
65
|
+
{
|
|
66
|
+
rbacType,
|
|
67
|
+
rbacPendingStepId,
|
|
68
|
+
currentAwaitingStepId,
|
|
69
|
+
parentFlowId: requestParams.parentFlowId
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const rbacAwaitingStepsResult =
|
|
74
|
+
await asyncFlowSharedLib.checkAllAwaitingStepsFinishedWithReturnParams(
|
|
75
|
+
_izContext,
|
|
76
|
+
rbacPendingStepId,
|
|
77
|
+
currentAwaitingStepId,
|
|
78
|
+
requestParams.errorsFound,
|
|
79
|
+
{
|
|
80
|
+
returnValue: requestParams.returnValue,
|
|
81
|
+
rbacType
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
_izContext.logger.debug(
|
|
86
|
+
'[<%- flowTag %>RbacCallbackMain] checkAllAwaitingStepsFinishedWithReturnParams result:',
|
|
87
|
+
{
|
|
88
|
+
rbacAwaitingStepsResult
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const {
|
|
93
|
+
isComplete,
|
|
94
|
+
collectedReturnValueByAwaitingStepId,
|
|
95
|
+
collectedErrors: errorsFound = [],
|
|
96
|
+
additionalAttributes
|
|
97
|
+
} = rbacAwaitingStepsResult;
|
|
98
|
+
|
|
99
|
+
if (isComplete === false) {
|
|
100
|
+
_izContext.logger.debug(
|
|
101
|
+
'[<%- flowTag %>RbacCallbackMain] Awaiting steps still pending completion:',
|
|
102
|
+
{
|
|
103
|
+
rbacPendingStepId,
|
|
104
|
+
isComplete
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
return 'all task not completed';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
_izContext.logger.debug(
|
|
112
|
+
'[<%- flowTag %>RbacCallbackMain] All awaiting steps completed — clearing awaiting steps:',
|
|
113
|
+
{
|
|
114
|
+
rbacPendingStepId
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
await asyncFlowSharedLib.clearAllAwaitingSteps(
|
|
119
|
+
_izContext,
|
|
120
|
+
rbacPendingStepId
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const originalRequestParams = additionalAttributes?.requestParams || {};
|
|
124
|
+
|
|
125
|
+
_izContext.logger.debug(
|
|
126
|
+
'[<%- flowTag %>RbacCallbackMain] Retrieved originalRequestParams:',
|
|
127
|
+
{
|
|
128
|
+
originalRequestParams
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
const rbacResults = Object.fromEntries(
|
|
133
|
+
Object.entries(collectedReturnValueByAwaitingStepId || {}).map(
|
|
134
|
+
([stepId, attrs]) => {
|
|
135
|
+
const type = stepId.split('_').pop();
|
|
136
|
+
return [type, attrs];
|
|
137
|
+
}
|
|
138
|
+
)
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const rbacCallbackResults = {};
|
|
142
|
+
const hasError = Object.entries(rbacResults).some(([type, result]) => {
|
|
143
|
+
if (result && result.error) {
|
|
144
|
+
errorsFound.push(result.error);
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
rbacCallbackResults[type] = result;
|
|
148
|
+
return false;
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const isAllowed = Object.values(rbacCallbackResults).some(
|
|
152
|
+
item => item?.returnValue?.permission === true
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
if (!isAllowed) {
|
|
156
|
+
errorsFound.push('Permission denied');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
_izContext.logger.debug(
|
|
160
|
+
'[<%- flowTag %>RbacCallbackMain] Final rbacCallbackResults before calling <%- flowTag %>MainLogical:',
|
|
161
|
+
{
|
|
162
|
+
rbacCallbackResults,
|
|
163
|
+
isAllowed,
|
|
164
|
+
errorsFound
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
if (hasError || errorsFound.length > 0) {
|
|
169
|
+
const errorResult = {
|
|
170
|
+
errorsFound,
|
|
171
|
+
status: 'rejected',
|
|
172
|
+
requestParams: originalRequestParams
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
_izContext.logger.debug(
|
|
176
|
+
'[<%- flowTag %>RbacCallbackMain] RBAC check failed, publishing rejected status:',
|
|
177
|
+
errorResult
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
await sns.publishAsync(_izContext, {
|
|
181
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
182
|
+
_izContext,
|
|
183
|
+
'<%- upperCaseFlowTag %>_Out',
|
|
184
|
+
process.env.iz_serviceTag
|
|
185
|
+
),
|
|
186
|
+
Message: JSON.stringify(errorResult)
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
return errorResult;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
//(<rbacCallbackMain>)
|
|
193
|
+
//(</rbacCallbackMain>)
|
|
194
|
+
|
|
195
|
+
const logicalResult = await <%- flowTag %>LogicalLib(
|
|
196
|
+
_izContext,
|
|
197
|
+
originalRequestParams,
|
|
198
|
+
callingFlowConfig,
|
|
199
|
+
errorsFound,
|
|
200
|
+
rbacCallbackResults
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
_izContext.logger.debug(
|
|
204
|
+
'[<%- flowTag %>RbacCallbackMain] <%- flowTag %>LogicalLib completed successfully:',
|
|
205
|
+
{
|
|
206
|
+
logicalResult
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
return logicalResult;
|
|
211
|
+
} catch (err) {
|
|
212
|
+
_izContext.logger.error('[<%- flowTag %>RbacCallbackMain] Error caught:', {
|
|
213
|
+
error: err
|
|
214
|
+
});
|
|
215
|
+
throw err;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
@@ -58,7 +58,7 @@ import { sns } from '@izara_project/izara-core-library-external-request';
|
|
|
58
58
|
export default async function <%- flowTag %>(
|
|
59
59
|
_izContext,
|
|
60
60
|
requestParams,
|
|
61
|
-
callingFlowConfig = {}
|
|
61
|
+
callingFlowConfig = {},
|
|
62
62
|
//(<additionalParams>)
|
|
63
63
|
//(</additionalParams>)
|
|
64
64
|
) {
|
|
@@ -36,14 +36,14 @@ import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
|
|
|
36
36
|
/**
|
|
37
37
|
* Gets a range of objects by processing DynamoDB query
|
|
38
38
|
* @param {Object} _izContext - Context object with logger
|
|
39
|
-
* @param {Object} requestParams - { objectType, pk, sk, itemNum, additionalParams }
|
|
39
|
+
* @param {Object} requestParams - { objectType, identifierField, pk, startKey, sk, itemNumber, itemNum, additionalParams }
|
|
40
40
|
* @param {Object} callingFlowConfig - Calling flow configuration
|
|
41
41
|
* @returns {Promise<Object>} DynamoDB query result (Items, LastEvaluatedKey, etc.)
|
|
42
42
|
*/
|
|
43
43
|
export default async function <%- mainFileName %>(
|
|
44
44
|
_izContext,
|
|
45
45
|
requestParams,
|
|
46
|
-
callingFlowConfig = {}
|
|
46
|
+
callingFlowConfig = {},
|
|
47
47
|
//(<additionalParams>)
|
|
48
48
|
//(</additionalParams>)
|
|
49
49
|
) {
|
|
@@ -63,22 +63,50 @@ export default async function <%- mainFileName %>(
|
|
|
63
63
|
const getDataDetails = await createGetDataDetails(_izContext, objectSchema);
|
|
64
64
|
_izContext.logger.debug('getDataDetails:', getDataDetails);
|
|
65
65
|
|
|
66
|
-
const {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
const {
|
|
67
|
+
identifierField,
|
|
68
|
+
pk,
|
|
69
|
+
startKey,
|
|
70
|
+
sk,
|
|
71
|
+
itemNumber,
|
|
72
|
+
itemNum
|
|
73
|
+
} = requestParams;
|
|
74
|
+
|
|
75
|
+
let partitionKeyValue = {};
|
|
76
|
+
if (
|
|
77
|
+
identifierField &&
|
|
78
|
+
typeof identifierField === 'object' &&
|
|
79
|
+
Object.keys(identifierField).length > 0
|
|
80
|
+
) {
|
|
81
|
+
partitionKeyValue = identifierField;
|
|
82
|
+
} else if (pk) {
|
|
83
|
+
const pkIdentifier = objectSchema.identifiers?.find(
|
|
84
|
+
(id) => id.type === 'partitionKey'
|
|
85
|
+
);
|
|
86
|
+
const pkName =
|
|
87
|
+
pkIdentifier?.fieldName ||
|
|
88
|
+
pkIdentifier?.name ||
|
|
89
|
+
'pk';
|
|
90
|
+
partitionKeyValue = { [pkName]: pk };
|
|
91
|
+
} else {
|
|
92
|
+
throw new Error('Partition key (identifierField or pk) is required for getRange');
|
|
70
93
|
}
|
|
71
94
|
|
|
72
95
|
const queryElements = {};
|
|
73
|
-
|
|
74
|
-
|
|
96
|
+
const limitVal = itemNumber || itemNum;
|
|
97
|
+
if (limitVal) {
|
|
98
|
+
queryElements.limit = parseInt(limitVal, 10);
|
|
75
99
|
}
|
|
76
100
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
101
|
+
const effectiveStartKey = startKey || sk;
|
|
102
|
+
if (effectiveStartKey) {
|
|
103
|
+
if (typeof effectiveStartKey === 'object') {
|
|
104
|
+
queryElements.exclusiveStartKey = effectiveStartKey;
|
|
80
105
|
} else {
|
|
81
|
-
queryElements.exclusiveStartKey = {
|
|
106
|
+
queryElements.exclusiveStartKey = {
|
|
107
|
+
...partitionKeyValue,
|
|
108
|
+
sk: effectiveStartKey
|
|
109
|
+
};
|
|
82
110
|
}
|
|
83
111
|
}
|
|
84
112
|
|
|
@@ -86,38 +114,91 @@ export default async function <%- mainFileName %>(
|
|
|
86
114
|
//(</beforeQuery>)
|
|
87
115
|
|
|
88
116
|
// ── Process storage resources (DynamoDB only for getRange) ────────────────
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
117
|
+
const queryResults = [];
|
|
118
|
+
|
|
119
|
+
for (const [, getDataDetail] of Object.entries(getDataDetails)) {
|
|
120
|
+
if (getDataDetail.storageType !== consts.STORAGE_TYPES.graph) {
|
|
121
|
+
const tableName = await dynamodbSharedLib.tableName(
|
|
122
|
+
_izContext,
|
|
123
|
+
getDataDetail.tableName,
|
|
124
|
+
getDataDetail.serviceTag
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
let queryPartitionKeyValue = partitionKeyValue;
|
|
128
|
+
if (
|
|
129
|
+
!identifierField ||
|
|
130
|
+
typeof identifierField !== 'object' ||
|
|
131
|
+
Object.keys(identifierField).length === 0
|
|
132
|
+
) {
|
|
133
|
+
const pkIdentifier = objectSchema.identifiers?.find(
|
|
134
|
+
(id) => id.type === 'partitionKey'
|
|
98
135
|
);
|
|
136
|
+
const pkName =
|
|
137
|
+
getDataDetail.groupByPartitionKeyField ||
|
|
138
|
+
pkIdentifier?.fieldName ||
|
|
139
|
+
pkIdentifier?.name ||
|
|
140
|
+
'pk';
|
|
141
|
+
queryPartitionKeyValue = { [pkName]: pk };
|
|
142
|
+
}
|
|
99
143
|
|
|
100
|
-
|
|
101
|
-
|
|
144
|
+
//(<beforeGetRangeDynamoDb>)
|
|
145
|
+
//(</beforeGetRangeDynamoDb>)
|
|
102
146
|
|
|
103
|
-
|
|
104
|
-
|
|
147
|
+
const dataFromDynamoDb = await dynamodbSharedLib.query(
|
|
148
|
+
_izContext,
|
|
149
|
+
tableName,
|
|
150
|
+
queryPartitionKeyValue,
|
|
151
|
+
queryElements
|
|
152
|
+
);
|
|
153
|
+
_izContext.logger.debug('dataFromDynamoDb:', dataFromDynamoDb);
|
|
105
154
|
|
|
106
|
-
|
|
107
|
-
_izContext,
|
|
108
|
-
tableName,
|
|
109
|
-
partitionKeyValue,
|
|
110
|
-
queryElements
|
|
111
|
-
);
|
|
112
|
-
_izContext.logger.debug('dataFromDynamoDb:', dataFromDynamoDb);
|
|
155
|
+
queryResults.push(dataFromDynamoDb);
|
|
113
156
|
|
|
114
|
-
|
|
157
|
+
//(<afterGetRangeDynamoDb>)
|
|
158
|
+
//(</afterGetRangeDynamoDb>)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
115
161
|
|
|
116
|
-
|
|
117
|
-
|
|
162
|
+
let queryResult = null;
|
|
163
|
+
if (queryResults.length === 1) {
|
|
164
|
+
queryResult = queryResults[0];
|
|
165
|
+
} else if (queryResults.length > 1) {
|
|
166
|
+
const mergedItemsMap = new Map();
|
|
167
|
+
const sortKeyIdentifier = objectSchema.identifiers?.find(
|
|
168
|
+
(id) => id.type === 'sortKey'
|
|
169
|
+
);
|
|
170
|
+
const skField =
|
|
171
|
+
sortKeyIdentifier?.fieldName ||
|
|
172
|
+
sortKeyIdentifier?.name ||
|
|
173
|
+
'sk';
|
|
174
|
+
|
|
175
|
+
for (const res of queryResults) {
|
|
176
|
+
let items = [];
|
|
177
|
+
if (Array.isArray(res)) {
|
|
178
|
+
items = res;
|
|
179
|
+
} else if (res && res.Items) {
|
|
180
|
+
items = res.Items;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
for (const item of items) {
|
|
184
|
+
let key = item[skField];
|
|
185
|
+
if (typeof key === 'undefined' || key === null) {
|
|
186
|
+
key = JSON.stringify(item);
|
|
187
|
+
}
|
|
188
|
+
if (mergedItemsMap.has(key)) {
|
|
189
|
+
mergedItemsMap.set(key, { ...mergedItemsMap.get(key), ...item });
|
|
190
|
+
} else {
|
|
191
|
+
mergedItemsMap.set(key, { ...item });
|
|
192
|
+
}
|
|
118
193
|
}
|
|
119
|
-
}
|
|
120
|
-
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
queryResult = {
|
|
197
|
+
Items: Array.from(mergedItemsMap.values()),
|
|
198
|
+
Count: mergedItemsMap.size,
|
|
199
|
+
queryResults: queryResults
|
|
200
|
+
};
|
|
201
|
+
}
|
|
121
202
|
|
|
122
203
|
return queryResult;
|
|
123
204
|
} catch (err) {
|
|
@@ -118,8 +118,10 @@ export default async function UpdateComplete(
|
|
|
118
118
|
}
|
|
119
119
|
: null;
|
|
120
120
|
if (status === 'complete') {
|
|
121
|
+
const listOfRecords =
|
|
122
|
+
result?.additionalAttributes?.listOfRecords ?? [];
|
|
121
123
|
await Promise.all(
|
|
122
|
-
(
|
|
124
|
+
(listOfRecords ?? []).flatMap((records) =>
|
|
123
125
|
Object.values(records).map(async (record) =>
|
|
124
126
|
dynamodbSharedLib.putItem(
|
|
125
127
|
_izContext,
|
|
@@ -137,9 +139,12 @@ export default async function UpdateComplete(
|
|
|
137
139
|
)
|
|
138
140
|
);
|
|
139
141
|
}
|
|
142
|
+
const callingFlowConfig =
|
|
143
|
+
result?.additionalAttributes?.callingFlowConfig ||
|
|
144
|
+
passBackProperties;
|
|
140
145
|
const message =
|
|
141
146
|
callingFlowSharedLib.addParentPassBackPropertiesToSnsResponseMessageObject(
|
|
142
|
-
|
|
147
|
+
callingFlowConfig,
|
|
143
148
|
{
|
|
144
149
|
objType: returnValue.requestParams.objType,
|
|
145
150
|
objInstanceFull: node.objInstanceFull,
|
|
@@ -152,7 +157,7 @@ export default async function UpdateComplete(
|
|
|
152
157
|
);
|
|
153
158
|
const messageAttributes =
|
|
154
159
|
callingFlowSharedLib.addParentPassBackCallingFlowToSnsResponseMessageAttributes(
|
|
155
|
-
|
|
160
|
+
callingFlowConfig,
|
|
156
161
|
{}
|
|
157
162
|
);
|
|
158
163
|
const topicArn = snsSharedLib.snsTopicArnByFlowSchema(
|