@izara_project/izara-core-generate-service-code 1.0.84 → 1.0.86
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/compileProject.js +1 -2
- package/src/compile/loadSchemas.js +29 -17
- package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +6 -0
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +26 -6
- package/src/emit/crud/crudActionPlan.js +3 -1
- package/src/emit/crud/emitCrudApplicationArtifacts.js +47 -8
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +136 -25
- package/src/emit/crud/templates/CreateConfirmComplete_Main.ejs +54 -0
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +248 -181
- package/src/emit/crud/templates/CreateLogicalLib.ejs +1155 -293
- package/src/emit/crud/templates/CreateNodeCallback_Main.ejs +221 -0
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +36 -4
- package/src/emit/crud/templates/FlowEndpointRbacCallback_Main.ejs +20 -120
- package/src/emit/crud/templates/FlowEndpoint_HdrWbs.ejs +76 -14
- package/src/emit/crud/templates/FlowMain_Wbs.ejs +31 -35
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +35 -3
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +754 -353
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +5 -2
- package/src/emit/rbac/emitRbacApplicationArtifacts.js +102 -6
- package/src/emit/rbac/templates/CancelUsage_Main.ejs +82 -22
- package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +130 -14
- package/src/emit/rbac/templates/CreateTargetRole_Main.ejs +61 -12
- package/src/emit/rbac/templates/DeleteTargetRole_Main.ejs +96 -0
- package/src/emit/rbac/templates/GetMyPermissions_Main.ejs +106 -0
- package/src/emit/rbac/templates/GetTargetRole_Main.ejs +62 -0
- package/src/emit/rbac/templates/ReservedDynamicUsage_Main.ejs +30 -11
- package/src/emit/rbac/templates/UpdateTargetRole_Main.ejs +107 -0
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +40 -15
- package/src/emit/rbac/templates/UserRoleMutation_Main.ejs +22 -7
- package/src/emit/resource/emitResourceArtifacts.js +52 -2
- package/src/emit/resource/templates/GeneratedLambdaRoleServiceConfig.ejs +6 -2
- package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +2 -0
- package/src/emit/shared/templates/FlowHandler_HdrSqs.ejs +1 -1
- package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +0 -1
- package/src/emit/systemText/emitSystemTextSchemas.js +5 -2
- package/src/generate.js +18 -12
- package/src/generateResources/IntTest/generateResources/generateResources.js +1 -1
- package/src/generateResources/IntTest/generateTests/generateTemplate.js +1 -1
- package/src/generateResources/IntTest/upload/uploadIntTest.js +8 -2
- package/test/createTargetRoleHandler.test.js +42 -1
- package/test/crudApplicationArtifacts.test.js +53 -0
- package/test/dynamicCrudFlowSchemas.test.js +16 -2
- package/test/dynamicRbacFlowSchemas.test.js +5 -2
- package/test/publicApi.test.js +18 -14
- package/test/resourceArtifacts.test.js +24 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@izara_project/izara-core-generate-service-code",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.86",
|
|
4
4
|
"description": "Code for locally generating per service files",
|
|
5
5
|
"homepage": "https://bitbucket.org/izara-core-support-services/izara-core-support-services-generate-service-code#readme",
|
|
6
6
|
"repository": {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import Logger from '@izara_project/izara-core-library-logger';
|
|
2
1
|
import { join, resolve } from 'node:path';
|
|
3
2
|
import { readFileSync, existsSync } from 'node:fs';
|
|
4
3
|
import { parse as parseYaml } from 'yaml';
|
|
@@ -33,7 +32,7 @@ export function compileProject(request = {}) {
|
|
|
33
32
|
}
|
|
34
33
|
}
|
|
35
34
|
} catch (err) {
|
|
36
|
-
|
|
35
|
+
console.log('Could not read serverless.config.yml', err);
|
|
37
36
|
}
|
|
38
37
|
}
|
|
39
38
|
|
|
@@ -7,9 +7,15 @@ import {
|
|
|
7
7
|
} from '@izara_project/izara-core-library-service-schemas';
|
|
8
8
|
import { basicValidatorSchema } from '@izara_project/izara-shared-service-schemas';
|
|
9
9
|
import { s3 } from '@izara_project/izara-core-library-s3';
|
|
10
|
-
import Logger from '@izara_project/izara-core-library-logger';
|
|
11
10
|
import { validateFlowSchema } from './flowValidator.js';
|
|
12
11
|
|
|
12
|
+
const consoleLogger = {
|
|
13
|
+
debug: console.log,
|
|
14
|
+
info: console.log,
|
|
15
|
+
warn: console.log,
|
|
16
|
+
error: console.error
|
|
17
|
+
};
|
|
18
|
+
|
|
13
19
|
const VALID_INITIATE_BY_ENUM = [
|
|
14
20
|
'user',
|
|
15
21
|
'systemWithUser',
|
|
@@ -66,7 +72,7 @@ export async function loadLocalSchemaDirectory(
|
|
|
66
72
|
options = {}
|
|
67
73
|
) {
|
|
68
74
|
const directoryPath = join(project.schemaRoot, directoryName);
|
|
69
|
-
const logger = options.logger ||
|
|
75
|
+
const logger = options.logger || consoleLogger;
|
|
70
76
|
let entries;
|
|
71
77
|
try {
|
|
72
78
|
entries = await readdir(directoryPath, { withFileTypes: true });
|
|
@@ -229,8 +235,9 @@ export async function resolveExtendedObjectSchemas(
|
|
|
229
235
|
let currentSchema = schema;
|
|
230
236
|
if (currentSchema.hasOwnProperty('extendObjType')) {
|
|
231
237
|
try {
|
|
232
|
-
|
|
233
|
-
`[DEBUG] [resolveExtendedObjectSchemas] Merging extendObjType
|
|
238
|
+
console.log(
|
|
239
|
+
`[DEBUG] [resolveExtendedObjectSchemas] Merging extendObjType ` +
|
|
240
|
+
`for objectType=${currentSchema.objectType}`,
|
|
234
241
|
{ extendObjType: currentSchema.extendObjType }
|
|
235
242
|
);
|
|
236
243
|
const initialResources = currentSchema.storageResources || {};
|
|
@@ -238,7 +245,7 @@ export async function resolveExtendedObjectSchemas(
|
|
|
238
245
|
const parentServiceTag = currentSchema.extendObjType.serviceTag;
|
|
239
246
|
|
|
240
247
|
const mergedSchema = await getObjectSchema.mergeExtendObjSchema(
|
|
241
|
-
{ logger:
|
|
248
|
+
{ logger: consoleLogger },
|
|
242
249
|
currentSchema,
|
|
243
250
|
bucketName
|
|
244
251
|
);
|
|
@@ -270,8 +277,9 @@ export async function resolveExtendedObjectSchemas(
|
|
|
270
277
|
|
|
271
278
|
currentSchema = mergedSchema;
|
|
272
279
|
} catch (error) {
|
|
273
|
-
|
|
274
|
-
`[ERROR] [resolveExtendedObjectSchemas] Failed to merge
|
|
280
|
+
console.log(
|
|
281
|
+
`[ERROR] [resolveExtendedObjectSchemas] Failed to merge ` +
|
|
282
|
+
`extendObjType for objectType=${currentSchema.objectType}`,
|
|
275
283
|
{ error }
|
|
276
284
|
);
|
|
277
285
|
throw error;
|
|
@@ -289,8 +297,9 @@ export async function resolveExtendedObjectSchemas(
|
|
|
289
297
|
belongToTarget.objectType
|
|
290
298
|
) {
|
|
291
299
|
try {
|
|
292
|
-
|
|
293
|
-
`[DEBUG] [resolveExtendedObjectSchemas] Fetching belongTo
|
|
300
|
+
console.log(
|
|
301
|
+
`[DEBUG] [resolveExtendedObjectSchemas] Fetching belongTo ` +
|
|
302
|
+
`schema for objectType=${currentSchema.objectType}`,
|
|
294
303
|
{ belongTo: belongToTarget }
|
|
295
304
|
);
|
|
296
305
|
const belongToObjType = {
|
|
@@ -298,19 +307,21 @@ export async function resolveExtendedObjectSchemas(
|
|
|
298
307
|
objectType: belongToTarget.objectType
|
|
299
308
|
};
|
|
300
309
|
const belongToSchema = await getObjectSchema.getObjSchemaS3(
|
|
301
|
-
{ logger:
|
|
310
|
+
{ logger: consoleLogger },
|
|
302
311
|
belongToObjType,
|
|
303
312
|
false,
|
|
304
313
|
bucketName
|
|
305
314
|
);
|
|
306
315
|
currentSchema.belongToSchema = belongToSchema;
|
|
307
|
-
|
|
308
|
-
`[DEBUG] [resolveExtendedObjectSchemas] Successfully fetched
|
|
316
|
+
console.log(
|
|
317
|
+
`[DEBUG] [resolveExtendedObjectSchemas] Successfully fetched ` +
|
|
318
|
+
`belongTo schema for objectType=${currentSchema.objectType}`,
|
|
309
319
|
{ belongToObjectType: belongToSchema?.objectType }
|
|
310
320
|
);
|
|
311
321
|
} catch (error) {
|
|
312
|
-
|
|
313
|
-
`[WARN] [resolveExtendedObjectSchemas] Failed to fetch
|
|
322
|
+
console.log(
|
|
323
|
+
`[WARN] [resolveExtendedObjectSchemas] Failed to fetch ` +
|
|
324
|
+
`belongTo schema for objectType=${currentSchema.objectType}`,
|
|
314
325
|
{ error }
|
|
315
326
|
);
|
|
316
327
|
}
|
|
@@ -361,7 +372,7 @@ export async function resolveGraphServiceTags(
|
|
|
361
372
|
let graphServerTagsMap = {};
|
|
362
373
|
if (bucketName) {
|
|
363
374
|
try {
|
|
364
|
-
const _izContext = { logger:
|
|
375
|
+
const _izContext = { logger: consoleLogger };
|
|
365
376
|
const s3Data = await s3.getObjectS3(_izContext, {
|
|
366
377
|
Bucket: bucketName,
|
|
367
378
|
Key: 'serviceConfig/GraphServerTags.json'
|
|
@@ -370,8 +381,9 @@ export async function resolveGraphServiceTags(
|
|
|
370
381
|
graphServerTagsMap = s3Data;
|
|
371
382
|
}
|
|
372
383
|
} catch (error) {
|
|
373
|
-
|
|
374
|
-
`[DEBUG] [resolveGraphServiceTags] Could not fetch
|
|
384
|
+
console.log(
|
|
385
|
+
`[DEBUG] [resolveGraphServiceTags] Could not fetch ` +
|
|
386
|
+
`GraphServerTags.json from bucket=${bucketName}`,
|
|
375
387
|
error
|
|
376
388
|
);
|
|
377
389
|
}
|
|
@@ -2,6 +2,7 @@ import ejsLib from 'ejs';
|
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
3
|
|
|
4
4
|
import { customFlowNextSteps, flowHasRbac, upperFirst } from '../custom/customFlows.js';
|
|
5
|
+
import { createCrudActionPlans } from '../crud/crudActionPlan.js';
|
|
5
6
|
|
|
6
7
|
const TEMPLATE_URL = new URL('./templates/', import.meta.url);
|
|
7
8
|
const APP_ROOT = 'app/sls_yaml/generatedCode/source';
|
|
@@ -239,7 +240,11 @@ export async function emitCoreFunctionArtifacts({ project, objects = [], relatio
|
|
|
239
240
|
};
|
|
240
241
|
});
|
|
241
242
|
|
|
243
|
+
const crudPlans = createCrudActionPlans(objects);
|
|
244
|
+
const hasQuotaReservation = crudPlans?.Create?.hasQuotaReservation ?? false;
|
|
245
|
+
|
|
242
246
|
const state = {
|
|
247
|
+
serviceTag: project?.serviceTag || '',
|
|
243
248
|
project,
|
|
244
249
|
objects,
|
|
245
250
|
relationships,
|
|
@@ -252,6 +257,7 @@ export async function emitCoreFunctionArtifacts({ project, objects = [], relatio
|
|
|
252
257
|
crud,
|
|
253
258
|
hasRelationships,
|
|
254
259
|
rbac,
|
|
260
|
+
hasQuotaReservation,
|
|
255
261
|
rbacValidatorServiceTags,
|
|
256
262
|
s3Flows,
|
|
257
263
|
hasGenerateGraph: objects.length > 0 || relationships.length > 0
|
|
@@ -131,7 +131,10 @@ const tableConfigs = {
|
|
|
131
131
|
const nodeSubs = [];
|
|
132
132
|
(objectGraphServiceTags || []).forEach(function(tag) {
|
|
133
133
|
nodeSubs.push({ serviceTag: tag, topicName: 'UpdateNode_Out', sqsEndpoint: 'UpdateCompleteHdrSqs' });
|
|
134
|
-
|
|
134
|
+
const createNodeEndpoint = (typeof hasQuotaReservation !== 'undefined' && hasQuotaReservation)
|
|
135
|
+
? 'CreateNodeCallbackHdrSqs'
|
|
136
|
+
: 'CreateCompleteHdrSqs';
|
|
137
|
+
nodeSubs.push({ serviceTag: tag, topicName: 'CreateNode_Out', sqsEndpoint: createNodeEndpoint });
|
|
135
138
|
});
|
|
136
139
|
|
|
137
140
|
const customSubs = [];
|
|
@@ -176,9 +179,14 @@ const tableConfigs = {
|
|
|
176
179
|
});
|
|
177
180
|
});
|
|
178
181
|
|
|
182
|
+
const currentServiceTag = (typeof serviceTag !== 'undefined' && serviceTag) ? serviceTag : ((typeof project !== 'undefined' && project?.serviceTag) ? project.serviceTag : '');
|
|
179
183
|
const rbacSubs = [];
|
|
180
|
-
if (crud &&
|
|
181
|
-
const allRbacTags = Array.from(new Set([
|
|
184
|
+
if (crud && rbac) {
|
|
185
|
+
const allRbacTags = Array.from(new Set([
|
|
186
|
+
'Rbac',
|
|
187
|
+
currentServiceTag,
|
|
188
|
+
...(typeof rbacValidatorServiceTags !== 'undefined' && rbacValidatorServiceTags ? rbacValidatorServiceTags : [])
|
|
189
|
+
])).filter(Boolean);
|
|
182
190
|
const hasGraph = typeof objectGraphServiceTags !== 'undefined' && objectGraphServiceTags && objectGraphServiceTags.length > 0;
|
|
183
191
|
const createEndpoint = hasGraph ? 'CreateRbacCallbackHdrSqs' : 'CreateCompleteHdrSqs';
|
|
184
192
|
const updateEndpoint = hasGraph ? 'UpdateRbacCallbackHdrSqs' : 'UpdateCompleteHdrSqs';
|
|
@@ -188,10 +196,18 @@ const tableConfigs = {
|
|
|
188
196
|
rbacSubs.push({ serviceTag: tag, topicName: 'ValidatorRbac_Out', sqsEndpoint: updateEndpoint });
|
|
189
197
|
rbacSubs.push({ serviceTag: tag, topicName: 'ValidatorRbac_Out', sqsEndpoint: deleteEndpoint });
|
|
190
198
|
});
|
|
199
|
+
if (typeof hasQuotaReservation !== 'undefined' && hasQuotaReservation) {
|
|
200
|
+
rbacSubs.push({ serviceTag: 'Rbac', topicName: 'ConfirmUsage_Out', sqsEndpoint: 'CreateCompleteHdrSqs' });
|
|
201
|
+
rbacSubs.push({ serviceTag: 'Rbac', topicName: 'CancelUsage_Out', sqsEndpoint: 'CreateCompleteHdrSqs' });
|
|
202
|
+
}
|
|
191
203
|
}
|
|
192
204
|
|
|
193
205
|
if (typeof customRbacFlowTags !== 'undefined' && customRbacFlowTags && customRbacFlowTags.length > 0) {
|
|
194
|
-
const allRbacTags = Array.from(new Set([
|
|
206
|
+
const allRbacTags = Array.from(new Set([
|
|
207
|
+
'Rbac',
|
|
208
|
+
currentServiceTag,
|
|
209
|
+
...(typeof rbacValidatorServiceTags !== 'undefined' ? rbacValidatorServiceTags : [])
|
|
210
|
+
])).filter(Boolean);
|
|
195
211
|
customRbacFlowTags.forEach(function(flowTag) {
|
|
196
212
|
const tagUpper = flowTag[0].toUpperCase() + flowTag.slice(1);
|
|
197
213
|
allRbacTags.forEach(function(tag) {
|
|
@@ -307,7 +323,10 @@ function roleConfigs() {
|
|
|
307
323
|
Effect: 'Allow',
|
|
308
324
|
Action: ['sns:Publish'],
|
|
309
325
|
Resource: [
|
|
310
|
-
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ValidatorRbac_In', 'Rbac')}
|
|
326
|
+
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ValidatorRbac_In', 'Rbac')}`,
|
|
327
|
+
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ConfirmUsage_In', 'Rbac')}`,
|
|
328
|
+
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'CancelUsage_In', 'Rbac')}`<% if (rbac) { %>,
|
|
329
|
+
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ValidatorRbac_In')}`<% } %><% (rbacValidatorServiceTags || []).forEach(function(tag) { %>,
|
|
311
330
|
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ValidatorRbac_In', '<%= tag %>')}`<% }); %>
|
|
312
331
|
]
|
|
313
332
|
},
|
|
@@ -326,7 +345,8 @@ function roleConfigs() {
|
|
|
326
345
|
Effect: 'Allow',
|
|
327
346
|
Action: ['sns:Publish'],
|
|
328
347
|
Resource: [
|
|
329
|
-
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ValidatorRbac_In', 'Rbac')}
|
|
348
|
+
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ValidatorRbac_In', 'Rbac')}`,
|
|
349
|
+
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ValidatorRbac_In')}`<% (rbacValidatorServiceTags || []).forEach(function(tag) { %>,
|
|
330
350
|
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ValidatorRbac_In', '<%= tag %>')}`<% }); %>
|
|
331
351
|
]
|
|
332
352
|
}
|
|
@@ -32,7 +32,9 @@ export function createCrudActionPlan(
|
|
|
32
32
|
hasRbac: actionHasRbac,
|
|
33
33
|
hasQuotaReservation,
|
|
34
34
|
hasComplete: outputTopic && (actionHasRbac || hasGraph),
|
|
35
|
-
hasRbacCallback: outputTopic && actionHasRbac && hasGraph
|
|
35
|
+
hasRbacCallback: outputTopic && actionHasRbac && hasGraph,
|
|
36
|
+
hasCreateNodeCallback:
|
|
37
|
+
outputTopic && action === 'Create' && actionHasRbac && hasGraph && hasQuotaReservation
|
|
36
38
|
};
|
|
37
39
|
}
|
|
38
40
|
|
|
@@ -35,11 +35,17 @@ export async function emitCrudApplicationArtifacts({
|
|
|
35
35
|
objectType: obj?.objectType ?? '(undefined)',
|
|
36
36
|
generatedBy: obj?.generatedBy ?? '(missing)'
|
|
37
37
|
}));
|
|
38
|
-
|
|
39
|
-
`[WARN] [CRUD Application] Skipped FlowObjects application artifacts
|
|
38
|
+
const warnMsg =
|
|
39
|
+
`[WARN] [CRUD Application] Skipped FlowObjects application artifacts ` +
|
|
40
|
+
`generation: No valid CRUD ObjectSchema found. ` +
|
|
40
41
|
`Checked ${objects.length} object(s): ${JSON.stringify(summary)}. ` +
|
|
41
|
-
`Expected "generatedBy" to be one of:
|
|
42
|
-
|
|
42
|
+
`Expected "generatedBy" to be one of: ` +
|
|
43
|
+
`${Array.from(VALID_CRUD_GENERATED_BY).join(', ')}`;
|
|
44
|
+
if (logger?.warn) {
|
|
45
|
+
logger.warn(warnMsg);
|
|
46
|
+
} else {
|
|
47
|
+
console.log(warnMsg);
|
|
48
|
+
}
|
|
43
49
|
}
|
|
44
50
|
return [];
|
|
45
51
|
}
|
|
@@ -80,6 +86,8 @@ export function crudApplicationManagedPaths() {
|
|
|
80
86
|
`${source}/${action}_HdrWbs.js`,
|
|
81
87
|
`${source}/${action}RbacCallback_Main.js`,
|
|
82
88
|
`${source}/${action}RbacCallback_HdrSqs.js`,
|
|
89
|
+
`${source}/${action}NodeCallback_Main.js`,
|
|
90
|
+
`${source}/${action}NodeCallback_HdrSqs.js`,
|
|
83
91
|
`${source}/${action}Complete_Main.js`,
|
|
84
92
|
`${source}/${action}Complete_HdrSqs.js`
|
|
85
93
|
);
|
|
@@ -290,12 +298,43 @@ async function emitAction(action, objects, serviceTag) {
|
|
|
290
298
|
});
|
|
291
299
|
}
|
|
292
300
|
|
|
301
|
+
if (plan.hasCreateNodeCallback) {
|
|
302
|
+
const nodeCallbackMain = `${action}NodeCallback_Main`;
|
|
303
|
+
artifacts.push(
|
|
304
|
+
{
|
|
305
|
+
path: `${source}/${nodeCallbackMain}.js`,
|
|
306
|
+
content: await render(`${action}NodeCallback_Main.ejs`, shared)
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
path: `${source}/${nodeCallbackMain.replace('_Main', '_HdrSqs')}.js`,
|
|
310
|
+
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
311
|
+
...shared,
|
|
312
|
+
mainFileName: nodeCallbackMain,
|
|
313
|
+
functionName: `${action}NodeCallbackMain`,
|
|
314
|
+
queueName: `${action}NodeCallbackHdrSqs`
|
|
315
|
+
})
|
|
316
|
+
}
|
|
317
|
+
);
|
|
318
|
+
functions.push({
|
|
319
|
+
type: 'sqs',
|
|
320
|
+
functionName: `${action}NodeCallbackHdrSqs`,
|
|
321
|
+
handlerPath: `${handlerRoot}/${action}NodeCallback_HdrSqs.main`,
|
|
322
|
+
roleName: 'FlowObjectsRole',
|
|
323
|
+
queueName: `${action}NodeCallbackHdrSqs`,
|
|
324
|
+
flowTag: action,
|
|
325
|
+
flowStepName: 'CreateNodeCallback'
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
|
|
293
329
|
if (plan.hasComplete) {
|
|
294
330
|
const completeMain = `${action}Complete_Main`;
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
331
|
+
let templateName = `${action}Complete_Main.ejs`;
|
|
332
|
+
if (plan.hasRbac && !plan.hasGraph) {
|
|
333
|
+
templateName = 'FlowEndpointRbacCallback_Main.ejs';
|
|
334
|
+
} else if (plan.hasCreateNodeCallback) {
|
|
335
|
+
templateName = 'CreateConfirmComplete_Main.ejs';
|
|
336
|
+
}
|
|
337
|
+
|
|
299
338
|
const templateContext =
|
|
300
339
|
plan.hasRbac && !plan.hasGraph
|
|
301
340
|
? shared
|
|
@@ -29,11 +29,17 @@ export function emitDynamicCrudFlowSchemas({
|
|
|
29
29
|
objectType: obj?.objectType ?? '(undefined)',
|
|
30
30
|
generatedBy: obj?.generatedBy ?? '(missing)'
|
|
31
31
|
}));
|
|
32
|
-
|
|
33
|
-
`[WARN] [CRUD FlowSchemas] Skipped FlowObjects FlowSchemas
|
|
32
|
+
const warnMsg =
|
|
33
|
+
`[WARN] [CRUD FlowSchemas] Skipped FlowObjects FlowSchemas ` +
|
|
34
|
+
`generation: No valid CRUD ObjectSchema found. ` +
|
|
34
35
|
`Checked ${objects.length} object(s): ${JSON.stringify(summary)}. ` +
|
|
35
|
-
`Expected "generatedBy" to be one of:
|
|
36
|
-
|
|
36
|
+
`Expected "generatedBy" to be one of: ` +
|
|
37
|
+
`${Array.from(VALID_CRUD_GENERATED_BY).join(', ')}`;
|
|
38
|
+
if (logger?.warn) {
|
|
39
|
+
logger.warn(warnMsg);
|
|
40
|
+
} else {
|
|
41
|
+
console.log(warnMsg);
|
|
42
|
+
}
|
|
37
43
|
}
|
|
38
44
|
return [];
|
|
39
45
|
}
|
|
@@ -52,19 +58,39 @@ export function emitDynamicCrudFlowSchemas({
|
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
function _createDynamicFlow(action, plan, serviceTag = '', initiateBy = 'user') {
|
|
61
|
+
const startNextSteps = [];
|
|
62
|
+
if (plan.hasRbacCallback) {
|
|
63
|
+
startNextSteps.push(
|
|
64
|
+
{
|
|
65
|
+
targetType: 'ownTopic',
|
|
66
|
+
stepName: 'RbacCallback'
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
targetType: 'extTopic',
|
|
70
|
+
serviceTag: 'Rbac',
|
|
71
|
+
topicName: 'ValidatorRbac_In',
|
|
72
|
+
toStepNames: ['RbacCallback']
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
} else if (plan.hasComplete) {
|
|
76
|
+
startNextSteps.push({
|
|
77
|
+
targetType: 'ownTopic',
|
|
78
|
+
stepName: 'Complete'
|
|
79
|
+
});
|
|
80
|
+
if (plan.hasGraph) {
|
|
81
|
+
startNextSteps.push({
|
|
82
|
+
targetType: 'extTopic',
|
|
83
|
+
serviceTag: 'GraphHandler',
|
|
84
|
+
topicName: `${action}Node_In`,
|
|
85
|
+
toStepNames: ['Complete']
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
55
90
|
const flowSteps = [
|
|
56
91
|
{
|
|
57
92
|
stepName: 'Start',
|
|
58
|
-
...(
|
|
59
|
-
? {
|
|
60
|
-
nextSteps: [
|
|
61
|
-
{
|
|
62
|
-
targetType: 'ownTopic',
|
|
63
|
-
stepName: plan.hasRbacCallback ? 'RbacCallback' : 'Complete'
|
|
64
|
-
}
|
|
65
|
-
]
|
|
66
|
-
}
|
|
67
|
-
: {}),
|
|
93
|
+
...(startNextSteps.length > 0 ? { nextSteps: startNextSteps } : {}),
|
|
68
94
|
properties: [],
|
|
69
95
|
messageAttributes: MESSAGE_ATTRIBUTES,
|
|
70
96
|
...(plan.outputTopic
|
|
@@ -79,6 +105,22 @@ function _createDynamicFlow(action, plan, serviceTag = '', initiateBy = 'user')
|
|
|
79
105
|
];
|
|
80
106
|
|
|
81
107
|
if (plan.hasRbacCallback) {
|
|
108
|
+
const nextStepName = plan.hasCreateNodeCallback ? 'CreateNodeCallback' : 'Complete';
|
|
109
|
+
const rbacNextSteps = [
|
|
110
|
+
{
|
|
111
|
+
targetType: 'ownTopic',
|
|
112
|
+
stepName: nextStepName
|
|
113
|
+
}
|
|
114
|
+
];
|
|
115
|
+
if (plan.hasGraph) {
|
|
116
|
+
rbacNextSteps.push({
|
|
117
|
+
targetType: 'extTopic',
|
|
118
|
+
serviceTag: 'GraphHandler',
|
|
119
|
+
topicName: `${action}Node_In`,
|
|
120
|
+
toStepNames: [nextStepName]
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
82
124
|
flowSteps.push({
|
|
83
125
|
stepName: 'RbacCallback',
|
|
84
126
|
event: ['extTopic'],
|
|
@@ -86,38 +128,107 @@ function _createDynamicFlow(action, plan, serviceTag = '', initiateBy = 'user')
|
|
|
86
128
|
{
|
|
87
129
|
sourceType: 'ownTopic',
|
|
88
130
|
stepName: 'Start'
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
sourceType: 'extTopic',
|
|
134
|
+
serviceTag: 'Rbac',
|
|
135
|
+
topicName: 'ValidatorRbac_Out',
|
|
136
|
+
fromStepNames: ['Start']
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
nextSteps: rbacNextSteps,
|
|
140
|
+
properties: [],
|
|
141
|
+
messageAttributes: MESSAGE_ATTRIBUTES
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (plan.hasCreateNodeCallback) {
|
|
146
|
+
flowSteps.push({
|
|
147
|
+
stepName: 'CreateNodeCallback',
|
|
148
|
+
event: ['extTopic'],
|
|
149
|
+
previousSteps: [
|
|
150
|
+
{
|
|
151
|
+
sourceType: 'ownTopic',
|
|
152
|
+
stepName: 'RbacCallback'
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
sourceType: 'extTopic',
|
|
156
|
+
serviceTag: 'GraphHandler',
|
|
157
|
+
topicName: 'CreateNode_Out',
|
|
158
|
+
fromStepNames: ['RbacCallback']
|
|
89
159
|
}
|
|
90
160
|
],
|
|
91
161
|
nextSteps: [
|
|
92
162
|
{
|
|
93
163
|
targetType: 'ownTopic',
|
|
94
164
|
stepName: 'Complete'
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
targetType: 'extTopic',
|
|
168
|
+
serviceTag: 'Rbac',
|
|
169
|
+
topicName: 'ConfirmUsage_In',
|
|
170
|
+
toStepNames: ['Complete']
|
|
95
171
|
}
|
|
96
172
|
],
|
|
97
|
-
properties: [
|
|
173
|
+
properties: [
|
|
174
|
+
'returnValue',
|
|
175
|
+
'parentFlowId',
|
|
176
|
+
'status',
|
|
177
|
+
'errorsFound',
|
|
178
|
+
'graphServiceTag'
|
|
179
|
+
],
|
|
98
180
|
messageAttributes: MESSAGE_ATTRIBUTES
|
|
99
181
|
});
|
|
100
182
|
}
|
|
101
183
|
|
|
102
184
|
if (plan.hasComplete) {
|
|
185
|
+
const prevStepName = plan.hasCreateNodeCallback
|
|
186
|
+
? 'CreateNodeCallback'
|
|
187
|
+
: (plan.hasRbacCallback ? 'RbacCallback' : 'Start');
|
|
188
|
+
|
|
189
|
+
const completePrevSteps = [
|
|
190
|
+
{
|
|
191
|
+
sourceType: 'ownTopic',
|
|
192
|
+
stepName: prevStepName
|
|
193
|
+
}
|
|
194
|
+
];
|
|
195
|
+
|
|
196
|
+
if (plan.hasCreateNodeCallback) {
|
|
197
|
+
completePrevSteps.push({
|
|
198
|
+
sourceType: 'extTopic',
|
|
199
|
+
serviceTag: 'Rbac',
|
|
200
|
+
topicName: 'ConfirmUsage_Out',
|
|
201
|
+
fromStepNames: ['CreateNodeCallback']
|
|
202
|
+
});
|
|
203
|
+
} else if (plan.hasGraph) {
|
|
204
|
+
completePrevSteps.push({
|
|
205
|
+
sourceType: 'extTopic',
|
|
206
|
+
serviceTag: 'GraphHandler',
|
|
207
|
+
topicName: `${action}Node_Out`,
|
|
208
|
+
fromStepNames: [prevStepName]
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
103
212
|
flowSteps.push({
|
|
104
213
|
stepName: 'Complete',
|
|
105
214
|
event: ['extTopic'],
|
|
106
|
-
previousSteps:
|
|
107
|
-
|
|
108
|
-
sourceType: 'ownTopic',
|
|
109
|
-
stepName: plan.hasRbacCallback ? 'RbacCallback' : 'Start'
|
|
110
|
-
}
|
|
111
|
-
],
|
|
112
|
-
properties: plan.hasGraph
|
|
215
|
+
previousSteps: completePrevSteps,
|
|
216
|
+
properties: plan.hasCreateNodeCallback
|
|
113
217
|
? [
|
|
114
218
|
'returnValue',
|
|
115
219
|
'parentFlowId',
|
|
116
220
|
'status',
|
|
117
|
-
'errorsFound'
|
|
118
|
-
'graphServiceTag'
|
|
221
|
+
'errorsFound'
|
|
119
222
|
]
|
|
120
|
-
:
|
|
223
|
+
: (plan.hasGraph
|
|
224
|
+
? [
|
|
225
|
+
'returnValue',
|
|
226
|
+
'parentFlowId',
|
|
227
|
+
'status',
|
|
228
|
+
'errorsFound',
|
|
229
|
+
'graphServiceTag'
|
|
230
|
+
]
|
|
231
|
+
: []),
|
|
121
232
|
messageAttributes: MESSAGE_ATTRIBUTES
|
|
122
233
|
});
|
|
123
234
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import callingFlowSharedLib from '@izara_project/izara-core-library-calling-flow';
|
|
2
|
+
import snsSharedLib from '@izara_project/izara-core-library-sns';
|
|
3
|
+
import { sns } from '@izara_project/izara-core-library-external-request';
|
|
4
|
+
import { consts } from '@izara_project/izara-core-library-service-schemas';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
buildCompletionPayload,
|
|
8
|
+
publishCompletionMessage
|
|
9
|
+
} from './CreateLogicalLib.js';
|
|
10
|
+
|
|
11
|
+
const { TOPIC_NAME_GENERATE_CODE } = consts;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Handles Create flow completion by publishing final response to Calling Flow
|
|
15
|
+
* @param {Object} _izContext - Izara context object
|
|
16
|
+
* @param {Object} requestParams - Final response parameters
|
|
17
|
+
* @param {Object} passBackProperties - Pass-back properties
|
|
18
|
+
* @returns {Promise<Object>} Parent pass-back result
|
|
19
|
+
*/
|
|
20
|
+
export default async function CreateComplete(
|
|
21
|
+
_izContext,
|
|
22
|
+
requestParams,
|
|
23
|
+
passBackProperties
|
|
24
|
+
) {
|
|
25
|
+
try {
|
|
26
|
+
_izContext.logger.debug(`[${process.env.iz_serviceTag}:CreateComplete] started`, {
|
|
27
|
+
requestParams
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const callingFlowConfig =
|
|
31
|
+
requestParams?.callingFlowProperties ||
|
|
32
|
+
passBackProperties ||
|
|
33
|
+
{};
|
|
34
|
+
|
|
35
|
+
const parentPassBack =
|
|
36
|
+
requestParams?.parentPassBackProperties ||
|
|
37
|
+
requestParams?.returnValue ||
|
|
38
|
+
requestParams;
|
|
39
|
+
|
|
40
|
+
// 1. Build completion response payload and attributes
|
|
41
|
+
const { message, messageAttributes } = buildCompletionPayload(
|
|
42
|
+
callingFlowConfig,
|
|
43
|
+
parentPassBack
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
// 2. Publish completion notification to SNS
|
|
47
|
+
await publishCompletionMessage(_izContext, message, messageAttributes);
|
|
48
|
+
|
|
49
|
+
return parentPassBack;
|
|
50
|
+
} catch (error) {
|
|
51
|
+
_izContext.logger.error('[CreateComplete] error:', error);
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|