@izara_project/izara-core-generate-service-code 1.0.87 → 1.0.89
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 +1 -1
- package/src/compile/flowValidator.js +25 -0
- package/src/compile/loadSchemas.js +199 -10
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +3 -7
- package/src/emit/crud/crudActionPlan.js +105 -6
- package/src/emit/crud/emitCrudApplicationArtifacts.js +63 -3
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +15 -32
- package/src/emit/crud/templates/CreateAfterHookCallback_Main.ejs +121 -0
- package/src/emit/crud/templates/CreateBeforeHookCallback_Main.ejs +108 -0
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +140 -340
- package/src/emit/crud/templates/CreateLogicalLib.ejs +338 -82
- package/src/emit/crud/templates/CreateNodeCallback_Main.ejs +90 -0
- package/src/emit/crud/templates/DeleteAfterHookCallback_Main.ejs +118 -0
- package/src/emit/crud/templates/DeleteBeforeHookCallback_Main.ejs +99 -0
- package/src/emit/crud/templates/DeleteComplete_Main.ejs +124 -10
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +151 -179
- package/src/emit/crud/templates/DeleteLogicalLib.ejs +244 -27
- package/src/emit/crud/templates/UpdateAfterHookCallback_Main.ejs +120 -0
- package/src/emit/crud/templates/UpdateBeforeHookCallback_Main.ejs +112 -0
- package/src/emit/crud/templates/UpdateComplete_Main.ejs +104 -10
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +166 -185
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +123 -3
- package/src/emit/custom/customFlows.js +3 -1
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +8 -2
- package/src/emit/rbac/templates/CancelUsage_Main.ejs +34 -14
- package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +34 -14
- package/src/emit/resource/emitResourceArtifacts.js +119 -59
- package/test/crudApplicationArtifacts.test.js +876 -0
- package/test/dynamicCrudFlowSchemas.test.js +10 -5
- package/test/dynamicRbacFlowSchemas.test.js +24 -2
- package/test/graphDrivenFlowSchema.test.js +36 -0
- package/test/resourceArtifacts.test.js +271 -12
|
@@ -102,29 +102,33 @@ export async function resolveSchemaAndIdentity(_izContext, requestParams, errors
|
|
|
102
102
|
targetIdentifiers.submittedByUserId = submittedByUserId;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
if (Array.isArray(objectSchema.identifiers)) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
105
|
+
// if (Array.isArray(objectSchema.identifiers)) {
|
|
106
|
+
// for (const identifier of objectSchema.identifiers) {
|
|
107
|
+
// if (identifier.fieldName) {
|
|
108
|
+
// if (targetIdentifiers[identifier.fieldName] === undefined) {
|
|
109
|
+
// targetIdentifiers[identifier.fieldName] = null;
|
|
110
|
+
// }
|
|
111
|
+
// } else if (Array.isArray(identifier.fieldNames)) {
|
|
112
|
+
// for (const fn of identifier.fieldNames) {
|
|
113
|
+
// if (targetIdentifiers[fn] === undefined) {
|
|
114
|
+
// targetIdentifiers[fn] = null;
|
|
115
|
+
// }
|
|
116
|
+
// }
|
|
117
|
+
// } else if (identifier.name) {
|
|
118
|
+
// if (targetIdentifiers[identifier.name] === undefined) {
|
|
119
|
+
// targetIdentifiers[identifier.name] = null;
|
|
120
|
+
// }
|
|
121
|
+
// }
|
|
122
|
+
// }
|
|
123
|
+
// }
|
|
124
124
|
|
|
125
125
|
requestParams.targetIdentifiers = targetIdentifiers;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
if (requestParams.rbacTargetIdentifiers === undefined && targetIdentifiers) {
|
|
129
|
+
requestParams.rbacTargetIdentifiers = targetIdentifiers;
|
|
130
|
+
}
|
|
131
|
+
|
|
128
132
|
_izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] Identity & Target Context Resolved:`, {
|
|
129
133
|
submittedByUserId: requestParams.submittedByUserId,
|
|
130
134
|
targetIdentifiers: requestParams.targetIdentifiers,
|
|
@@ -136,54 +140,165 @@ export async function resolveSchemaAndIdentity(_izContext, requestParams, errors
|
|
|
136
140
|
}
|
|
137
141
|
|
|
138
142
|
requestParams.submittedByUserId = submittedByUserId;
|
|
139
|
-
return { objType, objectSchema };
|
|
143
|
+
return { objType, objectSchema, targetIdentifiers };
|
|
140
144
|
}
|
|
141
145
|
|
|
142
146
|
/**
|
|
143
|
-
* Resolves and generates
|
|
147
|
+
* Resolves fromRequiredOnCreate fields and generates identifiers
|
|
144
148
|
* @param {Object} _izContext - Izara context object
|
|
145
|
-
* @param {Object}
|
|
146
|
-
* @param {Object}
|
|
147
|
-
* @
|
|
149
|
+
* @param {Object} requestParams - Request parameters
|
|
150
|
+
* @param {Object} objectSchema - Base object schema
|
|
151
|
+
* @param {Array<string>} errorsFound - Error list
|
|
152
|
+
* @returns {Promise<{ objectSchemas: Object }>}
|
|
148
153
|
*/
|
|
149
|
-
export async function resolveAndGenerateIdentifiers(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
export async function resolveAndGenerateIdentifiers(
|
|
155
|
+
_izContext,
|
|
156
|
+
requestParams,
|
|
157
|
+
objectSchema,
|
|
158
|
+
errorsFound
|
|
159
|
+
) {
|
|
160
|
+
const objType = createObjType(requestParams.objectType);
|
|
161
|
+
const targetIdentifiers = requestParams.targetIdentifiers;
|
|
162
|
+
|
|
163
|
+
const objectSchemas =
|
|
164
|
+
uploadUseCase.generateObjectSchemaForCombineFieldNames(
|
|
165
|
+
_izContext,
|
|
166
|
+
objectSchema
|
|
167
|
+
);
|
|
168
|
+
_izContext.logger.debug(
|
|
169
|
+
`[${process.env.iz_serviceTag}:<%- flowTag %>] objectSchemas:`,
|
|
170
|
+
objectSchemas
|
|
154
171
|
);
|
|
155
172
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
173
|
+
errorsFound.push(
|
|
174
|
+
...(await createNodeLib.validateRequiredOnCreateLinks(
|
|
175
|
+
_izContext,
|
|
176
|
+
objType,
|
|
177
|
+
requestParams.relationships
|
|
178
|
+
))
|
|
179
|
+
);
|
|
180
|
+
_izContext.logger.debug(
|
|
181
|
+
`[${process.env.iz_serviceTag}:<%- flowTag %>] errorsFound:`,
|
|
182
|
+
errorsFound
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
// ── Resolve fromRequiredOnCreate fields ──────────────────────────────────
|
|
186
|
+
if (objectSchemas.fieldNames) {
|
|
187
|
+
if (!requestParams.fieldNames) {
|
|
188
|
+
requestParams.fieldNames = {};
|
|
189
|
+
}
|
|
190
|
+
for (const [fieldName, val] of Object.entries(objectSchemas.fieldNames)) {
|
|
191
|
+
if (
|
|
192
|
+
val.fromRequiredOnCreate &&
|
|
193
|
+
requestParams.fieldNames[fieldName] === undefined
|
|
194
|
+
) {
|
|
195
|
+
const fromConfig = val.fromRequiredOnCreate;
|
|
196
|
+
const sourceField = fromConfig.fieldName || fieldName;
|
|
197
|
+
if (fromConfig.belongToObjType === true && targetIdentifiers) {
|
|
198
|
+
let targetValue = targetIdentifiers[sourceField];
|
|
199
|
+
if (targetValue === undefined) {
|
|
200
|
+
targetValue = Object.values(targetIdentifiers)[0];
|
|
201
|
+
}
|
|
202
|
+
requestParams.fieldNames[fieldName] = targetValue;
|
|
203
|
+
} else if (
|
|
204
|
+
fromConfig.relType &&
|
|
205
|
+
requestParams.relationships?.length > 0
|
|
206
|
+
) {
|
|
207
|
+
const matchedRel = requestParams.relationships.find(
|
|
208
|
+
(rel) =>
|
|
209
|
+
rel.relType?.serviceTag === fromConfig.relType.serviceTag &&
|
|
210
|
+
rel.relType?.relationshipTag === fromConfig.relType.relationshipTag
|
|
211
|
+
);
|
|
212
|
+
if (matchedRel?.targetIdentifiers?.[sourceField] !== undefined) {
|
|
213
|
+
requestParams.fieldNames[fieldName] =
|
|
214
|
+
matchedRel.targetIdentifiers[sourceField];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// ── Resolve identifiers ───────────────────────────────────────────────────
|
|
222
|
+
let errors;
|
|
223
|
+
const identifiers = objectSchemas.identifiers;
|
|
224
|
+
let optionalOnCreateIdentifiers;
|
|
225
|
+
|
|
226
|
+
if (
|
|
227
|
+
identifiers?.length === 1 &&
|
|
228
|
+
!identifiers[0].hasOwnProperty('fieldNames')
|
|
229
|
+
) {
|
|
230
|
+
[requestParams, errors] = await createIdentifiersByUseCase(
|
|
231
|
+
_izContext,
|
|
232
|
+
requestParams,
|
|
233
|
+
objectSchemas,
|
|
234
|
+
identifiers[0],
|
|
235
|
+
optionalOnCreateIdentifiers
|
|
236
|
+
);
|
|
237
|
+
if (errors?.length > 0) {
|
|
238
|
+
errorsFound.push(...errors);
|
|
239
|
+
}
|
|
240
|
+
} else if (identifiers?.length > 1) {
|
|
241
|
+
for (const identifier of identifiers) {
|
|
242
|
+
[requestParams, errors] = await createIdentifiersByUseCase(
|
|
243
|
+
_izContext,
|
|
244
|
+
requestParams,
|
|
245
|
+
objectSchemas,
|
|
246
|
+
identifier,
|
|
247
|
+
optionalOnCreateIdentifiers
|
|
248
|
+
);
|
|
249
|
+
if (errors?.length > 0) {
|
|
250
|
+
errorsFound.push(...errors);
|
|
251
|
+
}
|
|
159
252
|
}
|
|
160
253
|
}
|
|
161
254
|
|
|
162
|
-
|
|
163
|
-
`[${process.env.iz_serviceTag}:<%- flowTag %>] Identifiers generated:`,
|
|
164
|
-
identifiers
|
|
165
|
-
);
|
|
255
|
+
return { objectSchemas };
|
|
166
256
|
}
|
|
167
257
|
|
|
168
258
|
/**
|
|
169
259
|
* Validates request field names against schema definition
|
|
170
260
|
* @param {Object} _izContext - Izara context object
|
|
171
|
-
* @param {Object} objectSchemas - Combined object schema
|
|
172
261
|
* @param {Object} requestParams - Incoming request parameters
|
|
262
|
+
* @param {Object} objectSchemas - Combined object schema
|
|
173
263
|
* @param {Array<string>} errorsFound - Array to collect validation errors
|
|
174
264
|
*/
|
|
175
|
-
export function validateFieldNames(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
265
|
+
export function validateFieldNames(
|
|
266
|
+
_izContext,
|
|
267
|
+
requestParams,
|
|
268
|
+
objectSchemas,
|
|
269
|
+
errorsFound
|
|
270
|
+
) {
|
|
271
|
+
const listOfRequiredOnCreate = [];
|
|
272
|
+
const listOfOptionalOnCreate = [];
|
|
273
|
+
|
|
274
|
+
for (const [key, val] of Object.entries(objectSchemas?.fieldNames || {})) {
|
|
275
|
+
if (
|
|
276
|
+
val.randomOnCreate === true ||
|
|
277
|
+
val.requiredOnCreate === true ||
|
|
278
|
+
val.fromRequiredOnCreate ||
|
|
279
|
+
val.hashOnCreate?.length
|
|
280
|
+
) {
|
|
281
|
+
listOfRequiredOnCreate.push(key);
|
|
282
|
+
}
|
|
283
|
+
if (val.requiredOnCreate === false && val.optionalOnCreate === true) {
|
|
284
|
+
listOfOptionalOnCreate.push(key);
|
|
180
285
|
}
|
|
181
286
|
}
|
|
182
287
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
288
|
+
for (const fieldName of Object.keys(requestParams.fieldNames || {})) {
|
|
289
|
+
if (
|
|
290
|
+
!listOfRequiredOnCreate.includes(fieldName) &&
|
|
291
|
+
!listOfOptionalOnCreate.includes(fieldName)
|
|
292
|
+
) {
|
|
293
|
+
errorsFound.push('[invalid] over fieldNames create object');
|
|
294
|
+
}
|
|
295
|
+
if (errorsFound.length > 0) {
|
|
296
|
+
_izContext.logger.debug(
|
|
297
|
+
`[${process.env.iz_serviceTag}:<%- flowTag %>] HaveError:`,
|
|
298
|
+
errorsFound
|
|
299
|
+
);
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
187
302
|
}
|
|
188
303
|
}
|
|
189
304
|
|
|
@@ -641,60 +756,93 @@ export function resolveQuotaDeductionKeys(
|
|
|
641
756
|
}
|
|
642
757
|
|
|
643
758
|
/**
|
|
644
|
-
* Forwards quota confirmation
|
|
759
|
+
* Forwards quota confirmation or cancellation to RBAC via synchronous invoke
|
|
760
|
+
* and publishes final completion message to outCreateNodeComplete
|
|
645
761
|
* @param {Object} _izContext - Izara context object
|
|
646
762
|
* @param {Object} options - Message forwarding options
|
|
647
|
-
* @returns {Promise<
|
|
763
|
+
* @returns {Promise<Object>} Quota invocation result
|
|
648
764
|
*/
|
|
649
765
|
export async function forwardToQuotaConfirmation(
|
|
650
766
|
_izContext,
|
|
651
767
|
{
|
|
652
768
|
status,
|
|
653
|
-
errorsFound,
|
|
769
|
+
errorsFound = [],
|
|
654
770
|
quotaKeys,
|
|
655
771
|
actionData,
|
|
656
772
|
callingFlowConfig
|
|
657
773
|
}
|
|
658
774
|
) {
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
775
|
+
let quotaResult = null;
|
|
776
|
+
if (quotaKeys && (quotaKeys.limitTag || quotaKeys.flowTypeConcat)) {
|
|
777
|
+
let targetFunction = 'CancelUsageHdrInv';
|
|
778
|
+
if (status === 'complete' && errorsFound.length === 0) {
|
|
779
|
+
targetFunction = 'ConfirmUsageHdrInv';
|
|
780
|
+
}
|
|
663
781
|
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
parentPassBackProperties: actionData
|
|
669
|
-
},
|
|
670
|
-
callingFlowSharedLib.addParentCallingFlowConfig(
|
|
671
|
-
callingFlowConfig,
|
|
672
|
-
callingFlowSharedLib.createCallingFlowConfig(
|
|
673
|
-
await lambdaSharedLib.lambdaFunctionName(
|
|
674
|
-
_izContext,
|
|
675
|
-
'CreateCompleteHdrSqs'
|
|
676
|
-
),
|
|
677
|
-
{}
|
|
678
|
-
)
|
|
679
|
-
)
|
|
782
|
+
const functionName = await lambdaSharedLib.lambdaFunctionName(
|
|
783
|
+
_izContext,
|
|
784
|
+
targetFunction,
|
|
785
|
+
'Rbac'
|
|
680
786
|
);
|
|
681
787
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
788
|
+
const forwardMessage = {
|
|
789
|
+
...quotaKeys,
|
|
790
|
+
parentPassBackProperties: actionData,
|
|
791
|
+
callingFlowConfig
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
_izContext.logger.debug('[CreateLogicalLib] invoking RBAC quota sync', {
|
|
795
|
+
targetFunction,
|
|
796
|
+
functionName,
|
|
797
|
+
forwardMessage
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
try {
|
|
801
|
+
quotaResult = await lambda.invokeSync(
|
|
802
|
+
_izContext,
|
|
803
|
+
functionName,
|
|
804
|
+
forwardMessage
|
|
805
|
+
);
|
|
806
|
+
} catch (err) {
|
|
807
|
+
_izContext.logger.error(
|
|
808
|
+
`[CreateLogicalLib] error invoking ${targetFunction}:`,
|
|
809
|
+
err
|
|
810
|
+
);
|
|
811
|
+
if (targetFunction === 'ConfirmUsageHdrInv') {
|
|
812
|
+
try {
|
|
813
|
+
const cancelFunctionName = await lambdaSharedLib.lambdaFunctionName(
|
|
814
|
+
_izContext,
|
|
815
|
+
'CancelUsageHdrInv',
|
|
816
|
+
'Rbac'
|
|
817
|
+
);
|
|
818
|
+
await lambda.invokeSync(
|
|
819
|
+
_izContext,
|
|
820
|
+
cancelFunctionName,
|
|
821
|
+
forwardMessage
|
|
822
|
+
);
|
|
823
|
+
} catch (cancelErr) {
|
|
824
|
+
_izContext.logger.error(
|
|
825
|
+
'[CreateLogicalLib] error invoking CancelUsageHdrInv fallback:',
|
|
826
|
+
cancelErr
|
|
827
|
+
);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
errorsFound.push(err.message || 'Quota confirmation failed');
|
|
831
|
+
if (actionData) {
|
|
832
|
+
actionData.status = 'error';
|
|
833
|
+
actionData.errorsFound = errorsFound;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
const { message, messageAttributes } = buildCompletionPayload(
|
|
839
|
+
callingFlowConfig,
|
|
840
|
+
actionData
|
|
686
841
|
);
|
|
687
842
|
|
|
688
|
-
_izContext
|
|
689
|
-
nextTargetTopic,
|
|
690
|
-
TopicArn: topicArn,
|
|
691
|
-
forwardMessage
|
|
692
|
-
});
|
|
843
|
+
await publishCompletionMessage(_izContext, message, messageAttributes);
|
|
693
844
|
|
|
694
|
-
|
|
695
|
-
Message: JSON.stringify(forwardMessage),
|
|
696
|
-
TopicArn: topicArn
|
|
697
|
-
});
|
|
845
|
+
return quotaResult;
|
|
698
846
|
}
|
|
699
847
|
|
|
700
848
|
// ── 4. CreateComplete_Main Helpers ───────────────────────────────────────────
|
|
@@ -1344,6 +1492,7 @@ export async function <%- flowTag %>LogicalLib(
|
|
|
1344
1492
|
}
|
|
1345
1493
|
);
|
|
1346
1494
|
|
|
1495
|
+
const fieldsForHook = { ...objInstanceFullForDynamoDb.fields };
|
|
1347
1496
|
objInstanceFullForDynamoDb.fields = {};
|
|
1348
1497
|
|
|
1349
1498
|
// Auto-provision owner TargetRole for DynamoDB-only
|
|
@@ -1352,6 +1501,111 @@ export async function <%- flowTag %>LogicalLib(
|
|
|
1352
1501
|
identifiersForCreateData,
|
|
1353
1502
|
requestParams
|
|
1354
1503
|
});
|
|
1504
|
+
|
|
1505
|
+
<%_ if (plan?.hasAfterHookSync) { _%>
|
|
1506
|
+
// ── Synchronous After Hooks ──
|
|
1507
|
+
<%_ plan.afterHooks.filter(h => h?.generatedCodeConfig?.invocationType === 'lambdaSyncInv').forEach(hook => { _%>
|
|
1508
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length === 1) { _%>
|
|
1509
|
+
if (objType.objectType === '<%= hook.targetObjectTypes[0] %>') {
|
|
1510
|
+
<%_ } else if (hook.targetObjectTypes && hook.targetObjectTypes.length > 1) { _%>
|
|
1511
|
+
if (<%- JSON.stringify(hook.targetObjectTypes) %>.includes(objType.objectType)) {
|
|
1512
|
+
<%_ } _%>
|
|
1513
|
+
try {
|
|
1514
|
+
let hookPayload_<%= hook.flowTag %> = {
|
|
1515
|
+
objType,
|
|
1516
|
+
objInstanceFull: {
|
|
1517
|
+
identifiers: identifiersForCreateData,
|
|
1518
|
+
fields: fieldsForHook
|
|
1519
|
+
},
|
|
1520
|
+
relationships: requestParams.relationships || [],
|
|
1521
|
+
targetIdentifiers: requestParams.targetIdentifiers,
|
|
1522
|
+
submittedByUserId: requestParams.submittedByUserId
|
|
1523
|
+
};
|
|
1524
|
+
//(<beforeSendHook_<%= hook.flowTag %>>)
|
|
1525
|
+
//(</beforeSendHook_<%= hook.flowTag %>>)
|
|
1526
|
+
const hookResult = await lambda.invokeSync(
|
|
1527
|
+
_izContext,
|
|
1528
|
+
await lambdaSharedLib.lambdaFunctionName(
|
|
1529
|
+
_izContext,
|
|
1530
|
+
'<%= hook.flowTag %>'
|
|
1531
|
+
),
|
|
1532
|
+
{
|
|
1533
|
+
requestParams: hookPayload_<%= hook.flowTag %>,
|
|
1534
|
+
callingFlowConfig
|
|
1535
|
+
}
|
|
1536
|
+
);
|
|
1537
|
+
if (hookResult?.errorsFound?.length > 0 || hookResult?.status === 'error') {
|
|
1538
|
+
errorsFound.push(...(hookResult.errorsFound || ['Hook <%= hook.flowTag %> failed']));
|
|
1539
|
+
}
|
|
1540
|
+
} catch (hookErr) {
|
|
1541
|
+
_izContext.logger.error('[<%- flowTag %>LogicalLib] Sync hook <%= hook.flowTag %> error:', hookErr);
|
|
1542
|
+
errorsFound.push(hookErr.message || 'Hook <%= hook.flowTag %> failed');
|
|
1543
|
+
}
|
|
1544
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length > 0) { _%>
|
|
1545
|
+
}
|
|
1546
|
+
<%_ } _%>
|
|
1547
|
+
<%_ }) _%>
|
|
1548
|
+
<%_ } _%>
|
|
1549
|
+
|
|
1550
|
+
<%_ if (plan?.hasAfterHookAsync) { _%>
|
|
1551
|
+
// ── Asynchronous After Hooks ──
|
|
1552
|
+
<%_ plan.afterHooks.filter(h => h?.generatedCodeConfig?.invocationType === 'ownTopic').forEach(hook => { _%>
|
|
1553
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length === 1) { _%>
|
|
1554
|
+
if (objType.objectType === '<%= hook.targetObjectTypes[0] %>') {
|
|
1555
|
+
<%_ } else if (hook.targetObjectTypes && hook.targetObjectTypes.length > 1) { _%>
|
|
1556
|
+
if (<%- JSON.stringify(hook.targetObjectTypes) %>.includes(objType.objectType)) {
|
|
1557
|
+
<%_ } _%>
|
|
1558
|
+
let hookPayload_<%= hook.flowTag %> = {
|
|
1559
|
+
objType,
|
|
1560
|
+
objInstanceFull: {
|
|
1561
|
+
identifiers: identifiersForCreateData,
|
|
1562
|
+
fields: fieldsForHook
|
|
1563
|
+
},
|
|
1564
|
+
relationships: requestParams.relationships || [],
|
|
1565
|
+
targetIdentifiers: requestParams.targetIdentifiers,
|
|
1566
|
+
submittedByUserId: requestParams.submittedByUserId
|
|
1567
|
+
};
|
|
1568
|
+
//(<beforeSendHook_<%= hook.flowTag %>>)
|
|
1569
|
+
//(</beforeSendHook_<%= hook.flowTag %>>)
|
|
1570
|
+
const hookMsg_<%= hook.flowTag %> = callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
|
|
1571
|
+
hookPayload_<%= hook.flowTag %>,
|
|
1572
|
+
callingFlowSharedLib.addParentCallingFlowConfig(
|
|
1573
|
+
callingFlowConfig,
|
|
1574
|
+
callingFlowSharedLib.createCallingFlowConfig(
|
|
1575
|
+
await lambdaSharedLib.lambdaFunctionName(
|
|
1576
|
+
_izContext,
|
|
1577
|
+
'<%- flowTag %>AfterHookCallbackHdrSqs'
|
|
1578
|
+
),
|
|
1579
|
+
{
|
|
1580
|
+
actionData: {
|
|
1581
|
+
objType,
|
|
1582
|
+
objInstanceFull: {
|
|
1583
|
+
identifiers: identifiersForCreateData,
|
|
1584
|
+
fields: fieldsForHook
|
|
1585
|
+
},
|
|
1586
|
+
relationships: requestParams.relationships || [],
|
|
1587
|
+
targetIdentifiers: requestParams.targetIdentifiers,
|
|
1588
|
+
status: 'complete',
|
|
1589
|
+
errorsFound
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
)
|
|
1593
|
+
)
|
|
1594
|
+
);
|
|
1595
|
+
|
|
1596
|
+
await sns.publishAsync(_izContext, {
|
|
1597
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
1598
|
+
_izContext,
|
|
1599
|
+
'<%= hook.flowTag %>_In'
|
|
1600
|
+
),
|
|
1601
|
+
Message: JSON.stringify(hookMsg_<%= hook.flowTag %>),
|
|
1602
|
+
MessageAttributes: sns.createStringMessageAttributes(_izContext, {})
|
|
1603
|
+
});
|
|
1604
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length > 0) { _%>
|
|
1605
|
+
}
|
|
1606
|
+
<%_ } _%>
|
|
1607
|
+
<%_ }) _%>
|
|
1608
|
+
<%_ } _%>
|
|
1355
1609
|
}
|
|
1356
1610
|
|
|
1357
1611
|
//(<afterCreateRecordDynamo>)
|
|
@@ -1505,11 +1759,13 @@ export async function <%- flowTag %>LogicalLib(
|
|
|
1505
1759
|
|
|
1506
1760
|
// 7. Handle DynamoDB-only Complete Path
|
|
1507
1761
|
if (allAwaitingStepsId.length === 0 && listOfObjectForCreates.length === 0) {
|
|
1762
|
+
<%_ if (!plan?.hasAfterHookAsync) { _%>
|
|
1508
1763
|
await handleDynamoDbOnlyComplete(_izContext, {
|
|
1509
1764
|
objType,
|
|
1510
1765
|
objInstanceFullForDynamoDb,
|
|
1511
1766
|
callingFlowConfig
|
|
1512
1767
|
});
|
|
1768
|
+
<%_ } _%>
|
|
1513
1769
|
}
|
|
1514
1770
|
|
|
1515
1771
|
return {
|
|
@@ -171,6 +171,48 @@ export default async function CreateNodeCallbackMain(
|
|
|
171
171
|
node,
|
|
172
172
|
submittedByUserId
|
|
173
173
|
});
|
|
174
|
+
|
|
175
|
+
<%_ if (plan?.hasAfterHookSync) { _%>
|
|
176
|
+
// ── Synchronous After Hooks ──
|
|
177
|
+
<%_ plan.afterHooks.filter(h => h?.generatedCodeConfig?.invocationType === 'lambdaSyncInv').forEach(hook => { _%>
|
|
178
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length === 1) { _%>
|
|
179
|
+
if (returnValue.requestParams?.objType?.objectType === '<%= hook.targetObjectTypes[0] %>') {
|
|
180
|
+
<%_ } else if (hook.targetObjectTypes && hook.targetObjectTypes.length > 1) { _%>
|
|
181
|
+
if (<%- JSON.stringify(hook.targetObjectTypes) %>.includes(returnValue.requestParams?.objType?.objectType)) {
|
|
182
|
+
<%_ } _%>
|
|
183
|
+
try {
|
|
184
|
+
let hookPayload_<%= hook.flowTag %> = {
|
|
185
|
+
objType: returnValue.requestParams.objType,
|
|
186
|
+
objInstanceFull: node.objInstanceFull,
|
|
187
|
+
relationships: node.relationships || [],
|
|
188
|
+
targetIdentifiers: requestParams.targetIdentifiers,
|
|
189
|
+
submittedByUserId
|
|
190
|
+
};
|
|
191
|
+
//(<beforeSendHook_<%= hook.flowTag %>>)
|
|
192
|
+
//(</beforeSendHook_<%= hook.flowTag %>>)
|
|
193
|
+
const hookResult = await lambda.invokeSync(
|
|
194
|
+
_izContext,
|
|
195
|
+
await lambdaSharedLib.lambdaFunctionName(
|
|
196
|
+
_izContext,
|
|
197
|
+
'<%= hook.flowTag %>'
|
|
198
|
+
),
|
|
199
|
+
{
|
|
200
|
+
requestParams: hookPayload_<%= hook.flowTag %>,
|
|
201
|
+
callingFlowConfig
|
|
202
|
+
}
|
|
203
|
+
);
|
|
204
|
+
if (hookResult?.errorsFound?.length > 0 || hookResult?.status === 'error') {
|
|
205
|
+
errorsFound.push(...(hookResult.errorsFound || ['Hook <%= hook.flowTag %> failed']));
|
|
206
|
+
}
|
|
207
|
+
} catch (hookErr) {
|
|
208
|
+
_izContext.logger.error('[CreateNodeCallback] Sync hook <%= hook.flowTag %> error:', hookErr);
|
|
209
|
+
errorsFound.push(hookErr.message || 'Hook <%= hook.flowTag %> failed');
|
|
210
|
+
}
|
|
211
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length > 0) { _%>
|
|
212
|
+
}
|
|
213
|
+
<%_ } _%>
|
|
214
|
+
<%_ }) _%>
|
|
215
|
+
<%_ } _%>
|
|
174
216
|
}
|
|
175
217
|
|
|
176
218
|
const callingFlowConfig =
|
|
@@ -198,6 +240,53 @@ export default async function CreateNodeCallbackMain(
|
|
|
198
240
|
_izContext
|
|
199
241
|
);
|
|
200
242
|
|
|
243
|
+
<%_ if (plan?.hasAfterHookAsync) { _%>
|
|
244
|
+
// ── Asynchronous After Hooks ──
|
|
245
|
+
<%_ plan.afterHooks.filter(h => h?.generatedCodeConfig?.invocationType === 'ownTopic').forEach(hook => { _%>
|
|
246
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length === 1) { _%>
|
|
247
|
+
if (returnValue.requestParams?.objType?.objectType === '<%= hook.targetObjectTypes[0] %>') {
|
|
248
|
+
<%_ } else if (hook.targetObjectTypes && hook.targetObjectTypes.length > 1) { _%>
|
|
249
|
+
if (<%- JSON.stringify(hook.targetObjectTypes) %>.includes(returnValue.requestParams?.objType?.objectType)) {
|
|
250
|
+
<%_ } _%>
|
|
251
|
+
let hookPayload_<%= hook.flowTag %> = {
|
|
252
|
+
objType: returnValue.requestParams.objType,
|
|
253
|
+
objInstanceFull: node.objInstanceFull,
|
|
254
|
+
relationships: node.relationships || [],
|
|
255
|
+
targetIdentifiers: requestParams.targetIdentifiers,
|
|
256
|
+
submittedByUserId
|
|
257
|
+
};
|
|
258
|
+
//(<beforeSendHook_<%= hook.flowTag %>>)
|
|
259
|
+
//(</beforeSendHook_<%= hook.flowTag %>>)
|
|
260
|
+
const hookMsg_<%= hook.flowTag %> = callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
|
|
261
|
+
hookPayload_<%= hook.flowTag %>,
|
|
262
|
+
callingFlowSharedLib.addParentCallingFlowConfig(
|
|
263
|
+
callingFlowConfig,
|
|
264
|
+
callingFlowSharedLib.createCallingFlowConfig(
|
|
265
|
+
await lambdaSharedLib.lambdaFunctionName(
|
|
266
|
+
_izContext,
|
|
267
|
+
'CreateAfterHookCallbackHdrSqs'
|
|
268
|
+
),
|
|
269
|
+
{
|
|
270
|
+
quotaKeys,
|
|
271
|
+
actionData
|
|
272
|
+
}
|
|
273
|
+
)
|
|
274
|
+
)
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
await sns.publishAsync(_izContext, {
|
|
278
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
279
|
+
_izContext,
|
|
280
|
+
'<%= hook.flowTag %>_In'
|
|
281
|
+
),
|
|
282
|
+
Message: JSON.stringify(hookMsg_<%= hook.flowTag %>),
|
|
283
|
+
MessageAttributes: sns.createStringMessageAttributes(_izContext, {})
|
|
284
|
+
});
|
|
285
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length > 0) { _%>
|
|
286
|
+
}
|
|
287
|
+
<%_ } _%>
|
|
288
|
+
<%_ }) _%>
|
|
289
|
+
<%_ } else { _%>
|
|
201
290
|
await forwardToQuotaConfirmation(_izContext, {
|
|
202
291
|
status,
|
|
203
292
|
errorsFound,
|
|
@@ -205,6 +294,7 @@ export default async function CreateNodeCallbackMain(
|
|
|
205
294
|
actionData,
|
|
206
295
|
callingFlowConfig
|
|
207
296
|
});
|
|
297
|
+
<%_ } _%>
|
|
208
298
|
}
|
|
209
299
|
|
|
210
300
|
await asyncFlowSharedLib.removeAwaitingMultipleStep(
|