@izara_project/izara-core-generate-service-code 1.0.88 → 1.0.90
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 +154 -0
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +3 -7
- package/src/emit/crud/crudActionPlan.js +67 -9
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +15 -32
- package/src/emit/crud/templates/CreateComplete_Main.ejs +135 -10
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +33 -27
- package/src/emit/crud/templates/CreateLogicalLib.ejs +282 -95
- package/src/emit/crud/templates/CreateNodeCallback_Main.ejs +38 -21
- package/src/emit/crud/templates/DeleteAfterHookCallback_Main.ejs +118 -0
- package/src/emit/crud/templates/DeleteComplete_Main.ejs +124 -10
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +26 -16
- package/src/emit/crud/templates/DeleteLogicalLib.ejs +113 -4
- package/src/emit/crud/templates/UpdateAfterHookCallback_Main.ejs +120 -0
- package/src/emit/crud/templates/UpdateComplete_Main.ejs +104 -10
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +34 -22
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +121 -4
- 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/rbac/templates/UserRbacFlow_Main.ejs +20 -13
- package/src/emit/resource/emitResourceArtifacts.js +55 -14
- package/test/createTargetRoleHandler.test.js +11 -8
- package/test/crudApplicationArtifacts.test.js +440 -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 +113 -0
|
@@ -51,10 +51,6 @@ import {
|
|
|
51
51
|
//(<optionalRequire>)
|
|
52
52
|
//(</optionalRequire>)
|
|
53
53
|
|
|
54
|
-
const { createObjType, firstLetterUpperCase } = utils;
|
|
55
|
-
const { createDataDetailsLib } = dataDetailsLib;
|
|
56
|
-
const { createIdentifiersByUseCase } = identifiersObject;
|
|
57
|
-
|
|
58
54
|
// ── Main Entry Function ───────────────────────────────────────────────────────
|
|
59
55
|
|
|
60
56
|
/**
|
|
@@ -83,7 +79,7 @@ export default async function <%- flowTag %>(
|
|
|
83
79
|
const errorsFound = [];
|
|
84
80
|
|
|
85
81
|
// Step 1: Resolve Schema & Identity
|
|
86
|
-
const { objType, objectSchema
|
|
82
|
+
const { objType, objectSchema } =
|
|
87
83
|
await resolveSchemaAndIdentity(_izContext, requestParams, errorsFound);
|
|
88
84
|
|
|
89
85
|
//(<beforeQuery>)
|
|
@@ -94,8 +90,6 @@ export default async function <%- flowTag %>(
|
|
|
94
90
|
_izContext,
|
|
95
91
|
requestParams,
|
|
96
92
|
objectSchema,
|
|
97
|
-
objType,
|
|
98
|
-
targetIdentifiers,
|
|
99
93
|
errorsFound
|
|
100
94
|
);
|
|
101
95
|
|
|
@@ -167,7 +161,9 @@ export default async function <%- flowTag %>(
|
|
|
167
161
|
},
|
|
168
162
|
parameterGroups,
|
|
169
163
|
{
|
|
170
|
-
targetIdentifiers
|
|
164
|
+
targetIdentifiers:
|
|
165
|
+
requestParams.rbacTargetIdentifiers ||
|
|
166
|
+
requestParams.targetIdentifiers,
|
|
171
167
|
rbacObjType: {
|
|
172
168
|
serviceTag: <%- rbacServiceTags.length === 1 ? rbacServiceTags[0] : `{ ${Object.entries(rbacServiceTagMap).map(([k, v]) => `'${k}': ${v}`).join(', ')} }[requestParams.objectType] || process.env.iz_serviceTag` %>
|
|
173
169
|
},
|
|
@@ -198,11 +194,15 @@ export default async function <%- flowTag %>(
|
|
|
198
194
|
|
|
199
195
|
// ── Optional phase extension point ────────────────────────────────────────
|
|
200
196
|
<%_
|
|
197
|
+
const allCrudObjectTypes = (objects || []).filter(isCrudObject).map(o => o.objectType);
|
|
201
198
|
const beforeHooksByObjType = (plan?.beforeHooks || []).reduce((acc, hook) => {
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
199
|
+
const targets = (hook?.targetObjectTypes && hook.targetObjectTypes.length > 0)
|
|
200
|
+
? hook.targetObjectTypes
|
|
201
|
+
: allCrudObjectTypes;
|
|
202
|
+
for (const key of targets) {
|
|
203
|
+
if (!acc[key]) acc[key] = [];
|
|
204
|
+
acc[key].push(hook);
|
|
205
|
+
}
|
|
206
206
|
return acc;
|
|
207
207
|
}, {});
|
|
208
208
|
_%>
|
|
@@ -216,6 +216,15 @@ export default async function <%- flowTag %>(
|
|
|
216
216
|
const lambdaSyncInvResults = [];
|
|
217
217
|
<%_ for (const config of configs.filter(c => c?.generatedCodeConfig?.invocationType === 'lambdaSyncInv' || c?.event?.includes('lambdaSyncInv'))) { _%>
|
|
218
218
|
try {
|
|
219
|
+
let hookPayload_<%= config.flowTag %> = {
|
|
220
|
+
objType,
|
|
221
|
+
fieldNames: requestParams.fieldNames,
|
|
222
|
+
relationships: requestParams.relationships || [],
|
|
223
|
+
targetIdentifiers: requestParams.targetIdentifiers,
|
|
224
|
+
submittedByUserId: requestParams.submittedByUserId
|
|
225
|
+
};
|
|
226
|
+
//(<beforeSendHook_<%= config.flowTag %>>)
|
|
227
|
+
//(</beforeSendHook_<%= config.flowTag %>>)
|
|
219
228
|
const returnValue = await lambda.invokeSync(
|
|
220
229
|
_izContext,
|
|
221
230
|
await lambdaSharedLib.lambdaFunctionName(
|
|
@@ -223,13 +232,7 @@ export default async function <%- flowTag %>(
|
|
|
223
232
|
'<%= config.flowTag %>'
|
|
224
233
|
),
|
|
225
234
|
{
|
|
226
|
-
requestParams:
|
|
227
|
-
objType,
|
|
228
|
-
fieldNames: requestParams.fieldNames,
|
|
229
|
-
relationships: requestParams.relationships || [],
|
|
230
|
-
targetIdentifiers,
|
|
231
|
-
submittedByUserId: requestParams.submittedByUserId
|
|
232
|
-
},
|
|
235
|
+
requestParams: hookPayload_<%= config.flowTag %>,
|
|
233
236
|
callingFlowConfig
|
|
234
237
|
}
|
|
235
238
|
);
|
|
@@ -274,15 +277,18 @@ export default async function <%- flowTag %>(
|
|
|
274
277
|
<%_ if (hasOwnTopic) { _%>
|
|
275
278
|
// ── ownTopic (async — dispatch to before-hook and await callback) ──────────
|
|
276
279
|
<%_ configs.filter(c => c?.generatedCodeConfig?.invocationType === 'ownTopic' || c?.event?.includes('ownTopic')).forEach(config => { _%>
|
|
280
|
+
let hookPayload_<%= config.flowTag %> = {
|
|
281
|
+
objType,
|
|
282
|
+
fieldNames: requestParams.fieldNames,
|
|
283
|
+
relationships: requestParams.relationships || [],
|
|
284
|
+
targetIdentifiers: requestParams.targetIdentifiers,
|
|
285
|
+
submittedByUserId: requestParams.submittedByUserId
|
|
286
|
+
};
|
|
287
|
+
//(<beforeSendHook_<%= config.flowTag %>>)
|
|
288
|
+
//(</beforeSendHook_<%= config.flowTag %>>)
|
|
277
289
|
const hookMsg_<%= config.flowTag %> =
|
|
278
290
|
callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
|
|
279
|
-
|
|
280
|
-
objType,
|
|
281
|
-
fieldNames: requestParams.fieldNames,
|
|
282
|
-
relationships: requestParams.relationships || [],
|
|
283
|
-
targetIdentifiers,
|
|
284
|
-
submittedByUserId: requestParams.submittedByUserId
|
|
285
|
-
},
|
|
291
|
+
hookPayload_<%= config.flowTag %>,
|
|
286
292
|
callingFlowSharedLib.addParentCallingFlowConfig(
|
|
287
293
|
callingFlowConfig,
|
|
288
294
|
callingFlowSharedLib.createCallingFlowConfig(
|
|
@@ -294,7 +300,7 @@ export default async function <%- flowTag %>(
|
|
|
294
300
|
originalRequestParams: {
|
|
295
301
|
...requestParams,
|
|
296
302
|
objType,
|
|
297
|
-
targetIdentifiers
|
|
303
|
+
targetIdentifiers: requestParams.targetIdentifiers
|
|
298
304
|
},
|
|
299
305
|
callingFlowConfig
|
|
300
306
|
}
|
|
@@ -89,7 +89,11 @@ export async function resolveSchemaAndIdentity(_izContext, requestParams, errors
|
|
|
89
89
|
|
|
90
90
|
targetIdentifiers = requestParams.targetIdentifiers;
|
|
91
91
|
|
|
92
|
-
if (
|
|
92
|
+
if (
|
|
93
|
+
!targetIdentifiers &&
|
|
94
|
+
objectSchema.belongTo?.objectType === 'user' &&
|
|
95
|
+
submittedByUserId
|
|
96
|
+
) {
|
|
93
97
|
targetIdentifiers = { submittedByUserId };
|
|
94
98
|
}
|
|
95
99
|
|
|
@@ -98,10 +102,6 @@ export async function resolveSchemaAndIdentity(_izContext, requestParams, errors
|
|
|
98
102
|
errorsFound.push('not have targetIdentifiers');
|
|
99
103
|
|
|
100
104
|
if (targetIdentifiers) {
|
|
101
|
-
if (!targetIdentifiers.submittedByUserId && submittedByUserId) {
|
|
102
|
-
targetIdentifiers.submittedByUserId = submittedByUserId;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
105
|
// if (Array.isArray(objectSchema.identifiers)) {
|
|
106
106
|
// for (const identifier of objectSchema.identifiers) {
|
|
107
107
|
// if (identifier.fieldName) {
|
|
@@ -122,7 +122,11 @@ export async function resolveSchemaAndIdentity(_izContext, requestParams, errors
|
|
|
122
122
|
// }
|
|
123
123
|
// }
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
requestParams.targetIdentifiers = targetIdentifiers;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (requestParams.rbacTargetIdentifiers === undefined && targetIdentifiers) {
|
|
129
|
+
requestParams.rbacTargetIdentifiers = { ...targetIdentifiers };
|
|
126
130
|
}
|
|
127
131
|
|
|
128
132
|
_izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] Identity & Target Context Resolved:`, {
|
|
@@ -140,50 +144,161 @@ export async function resolveSchemaAndIdentity(_izContext, requestParams, errors
|
|
|
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
|
+
}
|
|
159
218
|
}
|
|
160
219
|
}
|
|
161
220
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
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
|
|
|
@@ -372,14 +487,43 @@ export async function saveDynamoDbRecords(_izContext, listOfRecords) {
|
|
|
372
487
|
);
|
|
373
488
|
}
|
|
374
489
|
|
|
490
|
+
<%_
|
|
491
|
+
const rootRbacObjects = (objects || []).filter(obj => {
|
|
492
|
+
const hasSelfRbac = Array.isArray(obj?.addOnDataStructure) && obj.addOnDataStructure.some(addOn => addOn?.type === 'rbac');
|
|
493
|
+
return hasSelfRbac && !obj?.belongTo && obj?.objectType !== 'user' && obj?.generatedBy !== 'systemNoUser';
|
|
494
|
+
});
|
|
495
|
+
_%>
|
|
496
|
+
const ROOT_RBAC_OBJECT_TYPES = new Set([
|
|
497
|
+
<%_ for (const obj of rootRbacObjects) { _%>
|
|
498
|
+
'<%- obj.objectType %>',
|
|
499
|
+
<%_ } _%>
|
|
500
|
+
]);
|
|
501
|
+
|
|
375
502
|
/**
|
|
376
503
|
* Auto-provisions owner TargetRole for Root RBAC object after Graph and DynamoDB write
|
|
377
504
|
* @param {Object} _izContext - Izara context object
|
|
378
505
|
* @param {Object} options - Target node and submitter details
|
|
379
506
|
* @returns {Promise<void>}
|
|
380
507
|
*/
|
|
381
|
-
export async function autoProvisionOwnerTargetRole(_izContext, { node, submittedByUserId }) {
|
|
508
|
+
export async function autoProvisionOwnerTargetRole(_izContext, { node, submittedByUserId, objType }) {
|
|
382
509
|
try {
|
|
510
|
+
let objectType = null;
|
|
511
|
+
if (typeof objType === 'string') {
|
|
512
|
+
objectType = objType;
|
|
513
|
+
} else if (objType && objType.objectType) {
|
|
514
|
+
objectType = objType.objectType;
|
|
515
|
+
} else if (typeof node?.objType === 'string') {
|
|
516
|
+
objectType = node.objType;
|
|
517
|
+
} else if (node?.objType?.objectType) {
|
|
518
|
+
objectType = node.objType.objectType;
|
|
519
|
+
} else if (node?.objectType) {
|
|
520
|
+
objectType = node.objectType;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
if (!objectType || !ROOT_RBAC_OBJECT_TYPES.has(objectType)) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
|
|
383
527
|
if (!submittedByUserId || !node?.objInstanceFull?.identifiers) {
|
|
384
528
|
return;
|
|
385
529
|
}
|
|
@@ -641,60 +785,93 @@ export function resolveQuotaDeductionKeys(
|
|
|
641
785
|
}
|
|
642
786
|
|
|
643
787
|
/**
|
|
644
|
-
* Forwards quota confirmation
|
|
788
|
+
* Forwards quota confirmation or cancellation to RBAC via synchronous invoke
|
|
789
|
+
* and publishes final completion message to outCreateNodeComplete
|
|
645
790
|
* @param {Object} _izContext - Izara context object
|
|
646
791
|
* @param {Object} options - Message forwarding options
|
|
647
|
-
* @returns {Promise<
|
|
792
|
+
* @returns {Promise<Object>} Quota invocation result
|
|
648
793
|
*/
|
|
649
794
|
export async function forwardToQuotaConfirmation(
|
|
650
795
|
_izContext,
|
|
651
796
|
{
|
|
652
797
|
status,
|
|
653
|
-
errorsFound,
|
|
798
|
+
errorsFound = [],
|
|
654
799
|
quotaKeys,
|
|
655
800
|
actionData,
|
|
656
801
|
callingFlowConfig
|
|
657
802
|
}
|
|
658
803
|
) {
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
804
|
+
let quotaResult = null;
|
|
805
|
+
if (quotaKeys && (quotaKeys.limitTag || quotaKeys.flowTypeConcat)) {
|
|
806
|
+
let targetFunction = 'CancelUsageHdrInv';
|
|
807
|
+
if (status === 'complete' && errorsFound.length === 0) {
|
|
808
|
+
targetFunction = 'ConfirmUsageHdrInv';
|
|
809
|
+
}
|
|
663
810
|
|
|
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
|
-
)
|
|
811
|
+
const functionName = await lambdaSharedLib.lambdaFunctionName(
|
|
812
|
+
_izContext,
|
|
813
|
+
targetFunction,
|
|
814
|
+
'Rbac'
|
|
680
815
|
);
|
|
681
816
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
817
|
+
const forwardMessage = {
|
|
818
|
+
...quotaKeys,
|
|
819
|
+
parentPassBackProperties: actionData,
|
|
820
|
+
callingFlowConfig
|
|
821
|
+
};
|
|
822
|
+
|
|
823
|
+
_izContext.logger.debug('[CreateLogicalLib] invoking RBAC quota sync', {
|
|
824
|
+
targetFunction,
|
|
825
|
+
functionName,
|
|
826
|
+
forwardMessage
|
|
827
|
+
});
|
|
828
|
+
|
|
829
|
+
try {
|
|
830
|
+
quotaResult = await lambda.invokeSync(
|
|
831
|
+
_izContext,
|
|
832
|
+
functionName,
|
|
833
|
+
forwardMessage
|
|
834
|
+
);
|
|
835
|
+
} catch (err) {
|
|
836
|
+
_izContext.logger.error(
|
|
837
|
+
`[CreateLogicalLib] error invoking ${targetFunction}:`,
|
|
838
|
+
err
|
|
839
|
+
);
|
|
840
|
+
if (targetFunction === 'ConfirmUsageHdrInv') {
|
|
841
|
+
try {
|
|
842
|
+
const cancelFunctionName = await lambdaSharedLib.lambdaFunctionName(
|
|
843
|
+
_izContext,
|
|
844
|
+
'CancelUsageHdrInv',
|
|
845
|
+
'Rbac'
|
|
846
|
+
);
|
|
847
|
+
await lambda.invokeSync(
|
|
848
|
+
_izContext,
|
|
849
|
+
cancelFunctionName,
|
|
850
|
+
forwardMessage
|
|
851
|
+
);
|
|
852
|
+
} catch (cancelErr) {
|
|
853
|
+
_izContext.logger.error(
|
|
854
|
+
'[CreateLogicalLib] error invoking CancelUsageHdrInv fallback:',
|
|
855
|
+
cancelErr
|
|
856
|
+
);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
errorsFound.push(err.message || 'Quota confirmation failed');
|
|
860
|
+
if (actionData) {
|
|
861
|
+
actionData.status = 'error';
|
|
862
|
+
actionData.errorsFound = errorsFound;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
const { message, messageAttributes } = buildCompletionPayload(
|
|
868
|
+
callingFlowConfig,
|
|
869
|
+
actionData
|
|
686
870
|
);
|
|
687
871
|
|
|
688
|
-
_izContext
|
|
689
|
-
nextTargetTopic,
|
|
690
|
-
TopicArn: topicArn,
|
|
691
|
-
forwardMessage
|
|
692
|
-
});
|
|
872
|
+
await publishCompletionMessage(_izContext, message, messageAttributes);
|
|
693
873
|
|
|
694
|
-
|
|
695
|
-
Message: JSON.stringify(forwardMessage),
|
|
696
|
-
TopicArn: topicArn
|
|
697
|
-
});
|
|
874
|
+
return quotaResult;
|
|
698
875
|
}
|
|
699
876
|
|
|
700
877
|
// ── 4. CreateComplete_Main Helpers ───────────────────────────────────────────
|
|
@@ -1357,10 +1534,24 @@ export async function <%- flowTag %>LogicalLib(
|
|
|
1357
1534
|
<%_ if (plan?.hasAfterHookSync) { _%>
|
|
1358
1535
|
// ── Synchronous After Hooks ──
|
|
1359
1536
|
<%_ plan.afterHooks.filter(h => h?.generatedCodeConfig?.invocationType === 'lambdaSyncInv').forEach(hook => { _%>
|
|
1360
|
-
<%_ if (hook.
|
|
1361
|
-
if (objType.objectType === '<%= hook.
|
|
1537
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length === 1) { _%>
|
|
1538
|
+
if (objType.objectType === '<%= hook.targetObjectTypes[0] %>') {
|
|
1539
|
+
<%_ } else if (hook.targetObjectTypes && hook.targetObjectTypes.length > 1) { _%>
|
|
1540
|
+
if (<%- JSON.stringify(hook.targetObjectTypes) %>.includes(objType.objectType)) {
|
|
1362
1541
|
<%_ } _%>
|
|
1363
1542
|
try {
|
|
1543
|
+
let hookPayload_<%= hook.flowTag %> = {
|
|
1544
|
+
objType,
|
|
1545
|
+
objInstanceFull: {
|
|
1546
|
+
identifiers: identifiersForCreateData,
|
|
1547
|
+
fields: fieldsForHook
|
|
1548
|
+
},
|
|
1549
|
+
relationships: requestParams.relationships || [],
|
|
1550
|
+
targetIdentifiers: requestParams.targetIdentifiers,
|
|
1551
|
+
submittedByUserId: requestParams.submittedByUserId
|
|
1552
|
+
};
|
|
1553
|
+
//(<beforeSendHook_<%= hook.flowTag %>>)
|
|
1554
|
+
//(</beforeSendHook_<%= hook.flowTag %>>)
|
|
1364
1555
|
const hookResult = await lambda.invokeSync(
|
|
1365
1556
|
_izContext,
|
|
1366
1557
|
await lambdaSharedLib.lambdaFunctionName(
|
|
@@ -1368,16 +1559,7 @@ export async function <%- flowTag %>LogicalLib(
|
|
|
1368
1559
|
'<%= hook.flowTag %>'
|
|
1369
1560
|
),
|
|
1370
1561
|
{
|
|
1371
|
-
requestParams:
|
|
1372
|
-
objType,
|
|
1373
|
-
objInstanceFull: {
|
|
1374
|
-
identifiers: identifiersForCreateData,
|
|
1375
|
-
fields: fieldsForHook
|
|
1376
|
-
},
|
|
1377
|
-
relationships: requestParams.relationships || [],
|
|
1378
|
-
targetIdentifiers: requestParams.targetIdentifiers,
|
|
1379
|
-
submittedByUserId: requestParams.submittedByUserId
|
|
1380
|
-
},
|
|
1562
|
+
requestParams: hookPayload_<%= hook.flowTag %>,
|
|
1381
1563
|
callingFlowConfig
|
|
1382
1564
|
}
|
|
1383
1565
|
);
|
|
@@ -1388,7 +1570,7 @@ export async function <%- flowTag %>LogicalLib(
|
|
|
1388
1570
|
_izContext.logger.error('[<%- flowTag %>LogicalLib] Sync hook <%= hook.flowTag %> error:', hookErr);
|
|
1389
1571
|
errorsFound.push(hookErr.message || 'Hook <%= hook.flowTag %> failed');
|
|
1390
1572
|
}
|
|
1391
|
-
<%_ if (hook.
|
|
1573
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length > 0) { _%>
|
|
1392
1574
|
}
|
|
1393
1575
|
<%_ } _%>
|
|
1394
1576
|
<%_ }) _%>
|
|
@@ -1397,20 +1579,25 @@ export async function <%- flowTag %>LogicalLib(
|
|
|
1397
1579
|
<%_ if (plan?.hasAfterHookAsync) { _%>
|
|
1398
1580
|
// ── Asynchronous After Hooks ──
|
|
1399
1581
|
<%_ plan.afterHooks.filter(h => h?.generatedCodeConfig?.invocationType === 'ownTopic').forEach(hook => { _%>
|
|
1400
|
-
<%_ if (hook.
|
|
1401
|
-
if (objType.objectType === '<%= hook.
|
|
1582
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length === 1) { _%>
|
|
1583
|
+
if (objType.objectType === '<%= hook.targetObjectTypes[0] %>') {
|
|
1584
|
+
<%_ } else if (hook.targetObjectTypes && hook.targetObjectTypes.length > 1) { _%>
|
|
1585
|
+
if (<%- JSON.stringify(hook.targetObjectTypes) %>.includes(objType.objectType)) {
|
|
1402
1586
|
<%_ } _%>
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
fields: fieldsForHook
|
|
1409
|
-
},
|
|
1410
|
-
relationships: requestParams.relationships || [],
|
|
1411
|
-
targetIdentifiers: requestParams.targetIdentifiers,
|
|
1412
|
-
submittedByUserId: requestParams.submittedByUserId
|
|
1587
|
+
let hookPayload_<%= hook.flowTag %> = {
|
|
1588
|
+
objType,
|
|
1589
|
+
objInstanceFull: {
|
|
1590
|
+
identifiers: identifiersForCreateData,
|
|
1591
|
+
fields: fieldsForHook
|
|
1413
1592
|
},
|
|
1593
|
+
relationships: requestParams.relationships || [],
|
|
1594
|
+
targetIdentifiers: requestParams.targetIdentifiers,
|
|
1595
|
+
submittedByUserId: requestParams.submittedByUserId
|
|
1596
|
+
};
|
|
1597
|
+
//(<beforeSendHook_<%= hook.flowTag %>>)
|
|
1598
|
+
//(</beforeSendHook_<%= hook.flowTag %>>)
|
|
1599
|
+
const hookMsg_<%= hook.flowTag %> = callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
|
|
1600
|
+
hookPayload_<%= hook.flowTag %>,
|
|
1414
1601
|
callingFlowSharedLib.addParentCallingFlowConfig(
|
|
1415
1602
|
callingFlowConfig,
|
|
1416
1603
|
callingFlowSharedLib.createCallingFlowConfig(
|
|
@@ -1443,7 +1630,7 @@ export async function <%- flowTag %>LogicalLib(
|
|
|
1443
1630
|
Message: JSON.stringify(hookMsg_<%= hook.flowTag %>),
|
|
1444
1631
|
MessageAttributes: sns.createStringMessageAttributes(_izContext, {})
|
|
1445
1632
|
});
|
|
1446
|
-
<%_ if (hook.
|
|
1633
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length > 0) { _%>
|
|
1447
1634
|
}
|
|
1448
1635
|
<%_ } _%>
|
|
1449
1636
|
<%_ }) _%>
|