@izara_project/izara-core-generate-service-code 1.0.100 → 1.0.102

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.
Files changed (26) hide show
  1. package/package.json +1 -1
  2. package/src/emit/application/crud/templates/CreateLogicalLib.ejs +6 -0
  3. package/src/emit/application/custom/customFlowS3.js +226 -6
  4. package/src/emit/application/custom/customFlows.js +22 -14
  5. package/src/emit/application/custom/emitCustomFlowApplicationArtifacts.js +5 -4
  6. package/src/emit/application/custom/templates/s3/ConfirmComplete_HdrSqs.ejs +1 -0
  7. package/src/emit/application/custom/templates/s3/ConfirmComplete_Main.ejs +28 -17
  8. package/src/emit/application/custom/templates/s3/ProcessS3File_Main.ejs +234 -23
  9. package/src/emit/application/custom/templates/s3/Start_HdrWbs.ejs +65 -0
  10. package/src/emit/application/custom/templates/s3/Start_Main.ejs +40 -17
  11. package/src/emit/application/custom/templates/s3/{ConfirmAfterUpload_HdrSqs.ejs → legacy/ConfirmAfterUpload_HdrSqs.ejs} +1 -0
  12. package/src/emit/application/custom/templates/s3/{ConfirmAfterUpload_Main.ejs → legacy/ConfirmAfterUpload_Main.ejs} +1 -1
  13. package/src/emit/infrastructure/functions/templates/DssFunction_Yaml.ejs +1 -1
  14. package/src/emit/infrastructure/resources/dynamoResourceArtifacts.js +6 -2
  15. package/src/plan/domainRegistry.js +2 -1
  16. package/test/unit/application/createTargetRoleHandler.test.js +1 -1
  17. package/test/unit/application/customFlowS3.test.js +284 -2
  18. package/test/unit/infrastructure/resourceArtifacts.test.js +4 -0
  19. /package/src/emit/application/custom/templates/s3/{ConfirmReserved_HdrSqs.ejs → legacy/ConfirmReserved_HdrSqs.ejs} +0 -0
  20. /package/src/emit/application/custom/templates/s3/{ConfirmReserved_Main.ejs → legacy/ConfirmReserved_Main.ejs} +0 -0
  21. /package/src/emit/application/custom/templates/s3/{CreateObject_HdrWbs.ejs → legacy/CreateObject_HdrWbs.ejs} +0 -0
  22. /package/src/emit/application/custom/templates/s3/{CreateObject_Main.ejs → legacy/CreateObject_Main.ejs} +0 -0
  23. /package/src/emit/application/custom/templates/s3/{CreatePreSignUrl_HdrSqs.ejs → legacy/CreatePreSignUrl_HdrSqs.ejs} +0 -0
  24. /package/src/emit/application/custom/templates/s3/{CreatePreSignUrl_Main.ejs → legacy/CreatePreSignUrl_Main.ejs} +0 -0
  25. /package/src/emit/application/custom/templates/s3/{ReservedLimit_HdrSqs.ejs → legacy/ReservedLimit_HdrSqs.ejs} +0 -0
  26. /package/src/emit/application/custom/templates/s3/{ReservedLimit_Main.ejs → legacy/ReservedLimit_Main.ejs} +0 -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.100",
3
+ "version": "1.0.102",
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": {
@@ -140,6 +140,12 @@ export async function resolveSchemaAndIdentity(_izContext, requestParams, foundE
140
140
  }
141
141
 
142
142
  requestParams.submittedByUserId = submittedByUserId;
143
+ if (submittedByUserId) {
144
+ _izContext.correlationIds?.set(
145
+ coreConsts.SUBMITTED_BY_USER_ID,
146
+ submittedByUserId
147
+ );
148
+ }
143
149
  return { objType, objectSchema, targetIdentifiers };
144
150
  }
145
151
 
@@ -27,7 +27,7 @@ export async function emitS3Flow(
27
27
  flow,
28
28
  source,
29
29
  handlerRoot,
30
- { objects = [] } = {}
30
+ { objects = [], relationships = [] } = {}
31
31
  ) {
32
32
  const tag = upperFirst(flow.flowTag);
33
33
  const roleName = customFlowRoleName(flow.flowTag);
@@ -71,7 +71,8 @@ export async function emitS3Flow(
71
71
  functionName,
72
72
  nextStepFunctionName,
73
73
  isSimplifiedS3,
74
- objects
74
+ objects,
75
+ relationships
75
76
  })
76
77
  );
77
78
  const handlerContent = await renderCustom(
@@ -260,13 +261,216 @@ export function resolveParentIdentifierInfo(flow, objects = []) {
260
261
  };
261
262
  }
262
263
 
264
+ export function resolveTargetIdentifierInfo(flow, objects = []) {
265
+ const targetObjType =
266
+ typeof flow.objType === 'string'
267
+ ? flow.objType
268
+ : flow.objType?.objectType || flow.objectType;
269
+ const matchedObject = (objects || []).find(
270
+ (o) => o.objectType === targetObjType
271
+ );
272
+
273
+ let identifierKeys = [];
274
+ if (Array.isArray(flow.identifierKeys) && flow.identifierKeys.length > 0) {
275
+ identifierKeys = [...flow.identifierKeys];
276
+ } else if (flow.identifierKey) {
277
+ identifierKeys = [flow.identifierKey];
278
+ } else if (
279
+ Array.isArray(matchedObject?.identifiers) &&
280
+ matchedObject.identifiers.length > 0
281
+ ) {
282
+ identifierKeys = extractIdentifierFieldNames(matchedObject.identifiers);
283
+ }
284
+
285
+ if (identifierKeys.length === 0 && targetObjType) {
286
+ identifierKeys = [`${targetObjType}Id`];
287
+ }
288
+
289
+ let identifierKey =
290
+ identifierKeys.length > 0 ? identifierKeys[0] : `${targetObjType}Id`;
291
+
292
+ return {
293
+ identifierKey,
294
+ identifierKeys
295
+ };
296
+ }
297
+
298
+ export function resolveFlowRelationships(
299
+ flow,
300
+ { objects = [], relationships = [] } = {}
301
+ ) {
302
+ if (Array.isArray(flow.relationships) && flow.relationships.length > 0) {
303
+ const list = [];
304
+ for (const rel of flow.relationships) {
305
+ let targetObj = {
306
+ objectType: '',
307
+ serviceTag: ''
308
+ };
309
+ if (rel.targetObjType) {
310
+ targetObj = {
311
+ objectType: rel.targetObjType.objectType || '',
312
+ serviceTag: rel.targetObjType.serviceTag || ''
313
+ };
314
+ } else if (rel.objectType) {
315
+ targetObj = {
316
+ objectType: rel.objectType,
317
+ serviceTag: rel.serviceTag || ''
318
+ };
319
+ }
320
+
321
+ let relType = {
322
+ relationshipTag: '',
323
+ serviceTag: targetObj.serviceTag
324
+ };
325
+ if (rel.relType) {
326
+ relType = {
327
+ relationshipTag: rel.relType.relationshipTag || '',
328
+ serviceTag: rel.relType.serviceTag || targetObj.serviceTag
329
+ };
330
+ } else if (rel.relationshipTag) {
331
+ relType = {
332
+ relationshipTag: rel.relationshipTag,
333
+ serviceTag: rel.serviceTag || targetObj.serviceTag
334
+ };
335
+ }
336
+
337
+ let targetIdentifierKey = '';
338
+ if (rel.targetIdentifierKey) {
339
+ targetIdentifierKey = rel.targetIdentifierKey;
340
+ } else if (rel.targetIdentifiers) {
341
+ const idKeys = Object.keys(rel.targetIdentifiers);
342
+ if (idKeys.length > 0) {
343
+ targetIdentifierKey = idKeys[0];
344
+ }
345
+ }
346
+ if (!targetIdentifierKey && targetObj.objectType) {
347
+ targetIdentifierKey = `${targetObj.objectType}Id`;
348
+ }
349
+
350
+ let direction = 'to';
351
+ if (rel.relationshipDirection) {
352
+ direction = rel.relationshipDirection;
353
+ }
354
+
355
+ list.push({
356
+ targetObjType: targetObj,
357
+ relType,
358
+ targetIdentifierKey,
359
+ relationshipProperties: rel.relationshipProperties || {},
360
+ relationshipDirection: direction
361
+ });
362
+ }
363
+ return list;
364
+ }
365
+
366
+ let targetObjType = '';
367
+ if (typeof flow.objType === 'string') {
368
+ targetObjType = flow.objType;
369
+ } else if (flow.objType?.objectType) {
370
+ targetObjType = flow.objType.objectType;
371
+ } else if (flow.objectType) {
372
+ targetObjType = flow.objectType;
373
+ }
374
+
375
+ if (
376
+ !targetObjType ||
377
+ !Array.isArray(relationships) ||
378
+ relationships.length === 0
379
+ ) {
380
+ return [];
381
+ }
382
+
383
+ const resolved = [];
384
+ for (const relItem of relationships) {
385
+ if (!relItem || typeof relItem !== 'object') {
386
+ continue;
387
+ }
388
+
389
+ if (
390
+ relItem.objectType &&
391
+ relItem.objectType.toLowerCase() === targetObjType.toLowerCase() &&
392
+ relItem.relationshipTag &&
393
+ relItem.relationshipServiceTag
394
+ ) {
395
+ const parentService = relItem.relationshipServiceTag;
396
+ let parentObjType = '';
397
+ if (relItem.targetObjectType) {
398
+ parentObjType = relItem.targetObjectType;
399
+ } else if (parentService.length > 0) {
400
+ parentObjType =
401
+ parentService[0].toLowerCase() + parentService.slice(1);
402
+ }
403
+ let targetIdentifierKey = `${parentObjType}Id`;
404
+ if (relItem.targetIdentifierKey) {
405
+ targetIdentifierKey = relItem.targetIdentifierKey;
406
+ }
407
+ let direction = 'to';
408
+ if (relItem.relationshipDirection) {
409
+ direction = relItem.relationshipDirection;
410
+ }
411
+ resolved.push({
412
+ targetObjType: {
413
+ objectType: parentObjType,
414
+ serviceTag: parentService
415
+ },
416
+ relType: {
417
+ relationshipTag: relItem.relationshipTag,
418
+ serviceTag: parentService
419
+ },
420
+ targetIdentifierKey,
421
+ relationshipProperties: {},
422
+ relationshipDirection: direction
423
+ });
424
+ continue;
425
+ }
426
+
427
+ const relKeys = Object.keys(relItem);
428
+ for (const relTag of relKeys) {
429
+ const relDef = relItem[relTag];
430
+ if (!relDef || !Array.isArray(relDef.links)) {
431
+ continue;
432
+ }
433
+ for (const link of relDef.links) {
434
+ if (!link || !link.from || !link.to) {
435
+ continue;
436
+ }
437
+
438
+ const isToTarget =
439
+ link.to.objType?.objectType?.toLowerCase() ===
440
+ targetObjType.toLowerCase();
441
+ if (isToTarget && link.to.requiredOnCreate) {
442
+ const fromObj = link.from.objType || {};
443
+ const fromObjType = fromObj.objectType || '';
444
+ const targetIdentifierKey = `${fromObjType}Id`;
445
+ resolved.push({
446
+ targetObjType: {
447
+ objectType: fromObjType,
448
+ serviceTag: fromObj.serviceTag || ''
449
+ },
450
+ relType: {
451
+ relationshipTag: relTag,
452
+ serviceTag: fromObj.serviceTag || ''
453
+ },
454
+ targetIdentifierKey,
455
+ relationshipProperties: {},
456
+ relationshipDirection: 'to'
457
+ });
458
+ }
459
+ }
460
+ }
461
+ }
462
+
463
+ return resolved;
464
+ }
465
+
263
466
  function _s3TemplateData({
264
467
  action,
265
468
  flow,
266
469
  functionName,
267
470
  nextStepFunctionName,
268
471
  isSimplifiedS3,
269
- objects = []
472
+ objects = [],
473
+ relationships = []
270
474
  }) {
271
475
  let maxFileSizeMb = 50;
272
476
  if (flow.maxFileSizeMb) {
@@ -284,6 +488,8 @@ function _s3TemplateData({
284
488
  }
285
489
  const { parentObjectType, parentServiceTag, parentIdKey, parentIdKeys } =
286
490
  resolveParentIdentifierInfo(flow, objects);
491
+ const { identifierKey, identifierKeys } =
492
+ resolveTargetIdentifierInfo(flow, objects);
287
493
  let s3KeyPrefix = 'uploads/';
288
494
  if (flow.s3KeyPrefix) {
289
495
  s3KeyPrefix = flow.s3KeyPrefix;
@@ -293,9 +499,15 @@ function _s3TemplateData({
293
499
  defaultImportType = flow.defaultImportType;
294
500
  } else if (flow.importType) {
295
501
  defaultImportType = flow.importType;
296
- } else if (typeof contentTypePrefix === 'string' && contentTypePrefix.startsWith('video/')) {
502
+ } else if (
503
+ typeof contentTypePrefix === 'string' &&
504
+ contentTypePrefix.startsWith('video/')
505
+ ) {
297
506
  defaultImportType = 'mp4';
298
- } else if (typeof contentTypePrefix === 'string' && contentTypePrefix.startsWith('image/')) {
507
+ } else if (
508
+ typeof contentTypePrefix === 'string' &&
509
+ contentTypePrefix.startsWith('image/')
510
+ ) {
299
511
  defaultImportType = 'jpg';
300
512
  }
301
513
 
@@ -313,10 +525,17 @@ function _s3TemplateData({
313
525
  rbacServiceTag = flow.objType?.serviceTag || flow.serviceTag || 'Rbac';
314
526
  }
315
527
 
528
+ const flowRelationships = resolveFlowRelationships(flow, {
529
+ objects,
530
+ relationships
531
+ });
532
+
316
533
  return {
317
534
  action,
318
535
  flowTag: flow.flowTag,
319
536
  objectType: flow.objType?.objectType,
537
+ identifierKey,
538
+ identifierKeys,
320
539
  functionName,
321
540
  nextStepFunctionName,
322
541
  isSimplifiedS3,
@@ -331,7 +550,8 @@ function _s3TemplateData({
331
550
  parentIdKeys,
332
551
  defaultImportType,
333
552
  isRbac,
334
- rbacServiceTag
553
+ rbacServiceTag,
554
+ flowRelationships
335
555
  };
336
556
  }
337
557
 
@@ -350,22 +350,22 @@ export const LEGACY_S3_PARTS = [
350
350
  action: 'CreateObject',
351
351
  handler: 'HdrWbs',
352
352
  type: 'wbs',
353
- mainTemplate: 'CreateObject_Main.ejs',
354
- handlerTemplate: 'CreateObject_HdrWbs.ejs'
353
+ mainTemplate: 'legacy/CreateObject_Main.ejs',
354
+ handlerTemplate: 'legacy/CreateObject_HdrWbs.ejs'
355
355
  },
356
356
  {
357
357
  action: 'ReservedLimit',
358
358
  handler: 'HdrSqs',
359
359
  type: 'sqs',
360
- mainTemplate: 'ReservedLimit_Main.ejs',
361
- handlerTemplate: 'ReservedLimit_HdrSqs.ejs'
360
+ mainTemplate: 'legacy/ReservedLimit_Main.ejs',
361
+ handlerTemplate: 'legacy/ReservedLimit_HdrSqs.ejs'
362
362
  },
363
363
  {
364
364
  action: 'CreatePreSignUrl',
365
365
  handler: 'HdrSqs',
366
366
  type: 'sqs',
367
- mainTemplate: 'CreatePreSignUrl_Main.ejs',
368
- handlerTemplate: 'CreatePreSignUrl_HdrSqs.ejs'
367
+ mainTemplate: 'legacy/CreatePreSignUrl_Main.ejs',
368
+ handlerTemplate: 'legacy/CreatePreSignUrl_HdrSqs.ejs'
369
369
  },
370
370
  {
371
371
  action: 'ProcessAfterUpload',
@@ -378,8 +378,8 @@ export const LEGACY_S3_PARTS = [
378
378
  action: 'ConfirmAfterUpload',
379
379
  handler: 'HdrSqs',
380
380
  type: 'sqs',
381
- mainTemplate: 'ConfirmReserved_Main.ejs',
382
- handlerTemplate: 'ConfirmReserved_HdrSqs.ejs'
381
+ mainTemplate: 'legacy/ConfirmReserved_Main.ejs',
382
+ handlerTemplate: 'legacy/ConfirmReserved_HdrSqs.ejs'
383
383
  }
384
384
  ];
385
385
 
@@ -419,16 +419,18 @@ export function resolveS3Parts(flow) {
419
419
  const eventType = Array.isArray(step.event) ? step.event[0] : 'sqs';
420
420
 
421
421
  if (eventType === 'wbs' || action === 'Start' || action === 'CreateObject') {
422
- let mainTemplate = 'CreateObject_Main.ejs';
422
+ let mainTemplate = 'legacy/CreateObject_Main.ejs';
423
+ let handlerTemplate = 'legacy/CreateObject_HdrWbs.ejs';
423
424
  if (isDeferredNodeFlow) {
424
425
  mainTemplate = 'Start_Main.ejs';
426
+ handlerTemplate = 'Start_HdrWbs.ejs';
425
427
  }
426
428
  return {
427
429
  action,
428
430
  handler: 'HdrWbs',
429
431
  type: 'wbs',
430
432
  mainTemplate,
431
- handlerTemplate: 'CreateObject_HdrWbs.ejs'
433
+ handlerTemplate
432
434
  };
433
435
  }
434
436
 
@@ -453,12 +455,18 @@ export function resolveS3Parts(flow) {
453
455
  }
454
456
 
455
457
  if (action === 'ConfirmAfterUpload') {
458
+ let mainTemplate = 'legacy/ConfirmAfterUpload_Main.ejs';
459
+ let handlerTemplate = 'legacy/ConfirmAfterUpload_HdrSqs.ejs';
460
+ if (isDeferredNodeFlow) {
461
+ mainTemplate = 'ConfirmComplete_Main.ejs';
462
+ handlerTemplate = 'ConfirmComplete_HdrSqs.ejs';
463
+ }
456
464
  return {
457
465
  action,
458
466
  handler: 'HdrSqs',
459
467
  type: 'sqs',
460
- mainTemplate: 'ConfirmAfterUpload_Main.ejs',
461
- handlerTemplate: 'ConfirmAfterUpload_HdrSqs.ejs'
468
+ mainTemplate,
469
+ handlerTemplate
462
470
  };
463
471
  }
464
472
 
@@ -466,8 +474,8 @@ export function resolveS3Parts(flow) {
466
474
  action,
467
475
  handler: 'HdrSqs',
468
476
  type: 'sqs',
469
- mainTemplate: 'CreatePreSignUrl_Main.ejs',
470
- handlerTemplate: 'CreatePreSignUrl_HdrSqs.ejs'
477
+ mainTemplate: 'legacy/CreatePreSignUrl_Main.ejs',
478
+ handlerTemplate: 'legacy/CreatePreSignUrl_HdrSqs.ejs'
471
479
  };
472
480
  });
473
481
  }
@@ -35,7 +35,7 @@ export { customFlowApplicationManagedPaths };
35
35
 
36
36
  export async function emitCustomFlowApplicationArtifacts(
37
37
  flows,
38
- { objects = [] } = {}
38
+ { objects = [], relationships = [] } = {}
39
39
  ) {
40
40
  const customFlows = supportedCustomFlows(flows);
41
41
  const generatedRoots = generatedOwnTopicFlows(flows);
@@ -51,7 +51,7 @@ export async function emitCustomFlowApplicationArtifacts(
51
51
  }
52
52
 
53
53
  const emitted = await Promise.all(
54
- customFlows.map((flow) => emitFlow(flow, objects))
54
+ customFlows.map((flow) => emitFlow(flow, objects, relationships))
55
55
  );
56
56
  const roots = await Promise.all(
57
57
  generatedRoots.map((flow) => emitOwnTopicRoot(flow, objects))
@@ -77,7 +77,7 @@ export async function emitCustomFlowApplicationArtifacts(
77
77
  ];
78
78
  }
79
79
 
80
- async function emitFlow(flow, objects) {
80
+ async function emitFlow(flow, objects, relationships = []) {
81
81
  const tag = upperFirst(flow.flowTag);
82
82
  const process = tag;
83
83
  const source = `app/src/generatedCode/FlowSchemas/${tag}/source`;
@@ -202,7 +202,8 @@ async function emitFlow(flow, objects) {
202
202
  }
203
203
  if (flow.event.includes('s3')) {
204
204
  const s3Artifacts = await emitS3Flow(flow, source, handlerRoot, {
205
- objects
205
+ objects,
206
+ relationships
206
207
  });
207
208
  artifacts.push(...s3Artifacts.artifacts);
208
209
  functions.push(...s3Artifacts.functions);
@@ -95,6 +95,7 @@ export const main = middleware.wrap(async (event, context) => {
95
95
  let returnPromise = await recordHandlerSharedLib.recordHandler(
96
96
  record,
97
97
  <%= functionName %>,
98
+ '<%= functionName %><%= handlerType %>',
98
99
  passOnProperties
99
100
  );
100
101
 
@@ -50,32 +50,43 @@ export default async function <%- functionName %>(
50
50
  passBackProperties
51
51
  });
52
52
 
53
- const targetId =
54
- objInstanceFull.identifiers?.<%- objectType %>Id ||
55
- Object.values(objInstanceFull.identifiers || {})[0];
53
+ let targetId =
54
+ passBackProperties.rawId ||
55
+ passBackProperties.<%- (typeof identifierKey !== 'undefined' && identifierKey) ? identifierKey : `${objectType}Id` %> ||
56
+ passBackProperties.parentPassBackProperties?.rawId ||
57
+ passBackProperties.parentPassBackProperties?.<%- (typeof identifierKey !== 'undefined' && identifierKey) ? identifierKey : `${objectType}Id` %> ||
58
+ objInstanceFull?.identifiers?.<%- (typeof identifierKey !== 'undefined' && identifierKey) ? identifierKey : `${objectType}Id` %>;
59
+
60
+ if (!targetId && objInstanceFull?.identifiers) {
61
+ targetId = Object.values(objInstanceFull.identifiers)[0];
62
+ }
56
63
 
57
64
  //(<confirmUsageHook>)
58
65
  //(</confirmUsageHook>)
59
66
 
60
67
  const taskKey = `${createFlowTypeConcat(_izContext, { flowTag: '<%- flowTag %>', serviceTag: process.env.iz_serviceTag })}${targetId}`;
61
- const taskRecord = await dynamodbSharedLib.getItem(
68
+ const tasks = await dynamodbSharedLib.query(
62
69
  _izContext,
63
70
  await dynamodbSharedLib.tableName(_izContext, 'WebSocketTask'),
64
- { taskKey: taskKey }
71
+ { taskKey }
65
72
  );
66
73
 
67
- if (taskRecord && taskRecord.connectionId) {
68
- await postToConnection(
69
- _izContext,
70
- {
71
- status: 'completed',
72
- data: {
73
- <%- objectType %>Id: targetId,
74
- objInstanceFull: objInstanceFull
75
- }
76
- },
77
- taskRecord.connectionId
78
- );
74
+ if (tasks && tasks.Items && tasks.Items.length > 0) {
75
+ for (const taskRecord of tasks.Items) {
76
+ if (taskRecord.connectionId && taskRecord.connectionId !== 'NONE') {
77
+ await postToConnection(
78
+ _izContext,
79
+ {
80
+ status: 'completed',
81
+ data: {
82
+ <%- (typeof identifierKey !== 'undefined' && identifierKey) ? identifierKey : `${objectType}Id` %>: targetId,
83
+ objInstanceFull: objInstanceFull
84
+ }
85
+ },
86
+ taskRecord.connectionId
87
+ );
88
+ }
89
+ }
79
90
  }
80
91
 
81
92
  return {