@izara_project/izara-core-generate-service-code 1.0.68 → 1.0.70

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 (129) hide show
  1. package/package.json +1 -1
  2. package/scripts/format-ejs.js +36 -32
  3. package/src/compile/compileProject.js +26 -10
  4. package/src/compile/loadSchemas.js +122 -59
  5. package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +163 -0
  6. package/src/emit/coreFunction/templates/CoreFunction_Yaml.ejs +38 -0
  7. package/src/emit/coreFunction/templates/CoreResource_Yaml.ejs +235 -0
  8. package/src/emit/coreFunction/templates/GenerateSeedDataDynamo_HdrInv.ejs +16 -0
  9. package/src/emit/coreFunction/templates/GenerateSeedDataDynamo_Main.ejs +38 -0
  10. package/src/emit/coreFunction/templates/GenerateSeedDataGraphData_HdrInv.ejs +16 -0
  11. package/src/emit/coreFunction/templates/GenerateSeedDataGraphData_Main.ejs +32 -0
  12. package/src/emit/coreFunction/templates/GenerateSeedDataGraphSchema_HdrInv.ejs +16 -0
  13. package/src/emit/coreFunction/templates/GenerateSeedDataGraphSchema_Main.ejs +71 -0
  14. package/src/emit/coreFunction/templates/GeneratedGraphNodeSchemas.ejs +47 -0
  15. package/src/emit/coreFunction/templates/GeneratedGraphRelSchemas.ejs +27 -0
  16. package/src/emit/coreFunction/templates/GeneratedTableConfigs.ejs +34 -0
  17. package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +108 -0
  18. package/src/emit/coreFunction/templates/InitialSetup_HdrInv.ejs +12 -0
  19. package/src/emit/coreFunction/templates/InitialSetup_Main.ejs +51 -0
  20. package/src/emit/coreFunction/templates/RemoveSeedDataDynamo_HdrInv.ejs +16 -0
  21. package/src/emit/coreFunction/templates/RemoveSeedDataDynamo_Main.ejs +31 -0
  22. package/src/emit/coreFunction/templates/UploadSchema_HdrInv.ejs +37 -0
  23. package/src/emit/coreFunction/templates/UploadSchema_Main.ejs +52 -0
  24. package/src/emit/crud/emitCrudApplicationArtifacts.js +194 -41
  25. package/src/emit/crud/emitDynamicCrudFlowSchemas.js +34 -17
  26. package/src/emit/crud/generateCrudApplicationArtifacts.js +14 -6
  27. package/src/emit/crud/generateDynamicCrudFlowSchemas.js +4 -1
  28. package/src/emit/crud/templates/CreateEndpoint_Main.ejs +1 -1
  29. package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +1 -1
  30. package/src/emit/crud/templates/GetEndpoint_Main.ejs +2 -2
  31. package/src/emit/crud/templates/GetRangeEndpoint_Main.ejs +1 -1
  32. package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +1 -1
  33. package/src/emit/custom/customFlows.js +23 -13
  34. package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +535 -114
  35. package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +28 -8
  36. package/src/emit/custom/templates/FlowEndpoint_Main.ejs +2 -2
  37. package/src/emit/custom/templates/FlowStep_Main.ejs +1 -1
  38. package/src/emit/custom/templates/s3/CreateObject_Main.ejs +1 -1
  39. package/src/emit/custom/templates/s3/FlowHandler_HdrS3.ejs +2 -2
  40. package/src/emit/custom/templates/s3/ReservedLimit_HdrSqs.ejs +1 -1
  41. package/src/emit/custom/templates/s3/ReservedLimit_Main.ejs +1 -1
  42. package/src/emit/custom/templates/triggerCache/CheckTriggerCache_HdrSqs.ejs +4 -4
  43. package/src/emit/function/functionYamlArtifact.js +273 -97
  44. package/src/emit/function/templates/ApiFunction_Yaml.ejs +7 -0
  45. package/src/emit/function/templates/EventBridgeFunction_Yaml.ejs +6 -0
  46. package/src/emit/function/templates/InvFunction_Yaml.ejs +5 -0
  47. package/src/emit/function/templates/S3Function_Yaml.ejs +16 -0
  48. package/src/emit/function/templates/SqsFunction_Yaml.ejs +10 -0
  49. package/src/emit/function/templates/WbsFunction_Yaml.ejs +10 -0
  50. package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +28 -30
  51. package/src/emit/rbac/emitRbacApplicationArtifacts.js +6 -6
  52. package/src/emit/rbac/generateCreateTargetRoleHandler.js +6 -4
  53. package/src/emit/rbac/generateDynamicRbacFlowSchemas.js +8 -2
  54. package/src/emit/rbac/rbacFlowTag.js +3 -1
  55. package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +1 -1
  56. package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +26 -10
  57. package/src/emit/relationship/emitRelationshipApplicationArtifacts.js +189 -37
  58. package/src/emit/relationship/generateDynamicRelationshipFlowSchemas.js +8 -2
  59. package/src/emit/relationship/generateRelationshipApplicationArtifacts.js +15 -6
  60. package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +1 -1
  61. package/src/emit/relationship/templates/CreateRelationship_Main.ejs +1 -1
  62. package/src/emit/relationship/templates/DeleteRelationship_Main.ejs +1 -1
  63. package/src/emit/relationship/templates/GetRelationship_Main.ejs +1 -1
  64. package/src/emit/relationship/templates/MoveRelationship_Main.ejs +1 -1
  65. package/src/emit/relationship/templates/UpdateRelationship_Main.ejs +1 -1
  66. package/src/emit/resource/emitResourceArtifacts.js +249 -123
  67. package/src/emit/resource/generateResourceArtifacts.js +15 -6
  68. package/src/emit/resource/templates/DynamoDBTable_Yaml.ejs +18 -18
  69. package/src/emit/resource/templates/FlowOut_Yaml.ejs +5 -5
  70. package/src/emit/resource/templates/GeneratedLambdaRoleServiceConfig.ejs +10 -9
  71. package/src/emit/resource/templates/ResourceBeforeLogicalYaml.ejs +44 -44
  72. package/src/emit/resource/templates/ResourceSqsYaml.ejs +36 -36
  73. package/src/emit/resource/templates/ResourceYaml.ejs +48 -48
  74. package/src/emit/resource/templates/S3Subscription_Yaml.ejs +7 -0
  75. package/src/emit/resource/templates/SharedResource_Yaml.ejs +11 -11
  76. package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +122 -105
  77. package/src/emit/resource/templates/WebSocketSubscription_Yaml.ejs +7 -0
  78. package/src/emit/shared/templates/FindData_HdrSqs.ejs +120 -0
  79. package/src/emit/shared/templates/FindData_Main.ejs +345 -0
  80. package/src/emit/{crud → shared}/templates/FlowHandler_HdrApi.ejs +1 -1
  81. package/src/emit/{relationship → shared}/templates/FlowHandler_HdrDsq.ejs +4 -4
  82. package/src/emit/{crud → shared}/templates/FlowHandler_HdrInv.ejs +1 -1
  83. package/src/emit/{crud → shared}/templates/FlowHandler_HdrSqs.ejs +4 -4
  84. package/src/emit/shared/templates/PaginateProcessLogical_HdrDsq.ejs +162 -0
  85. package/src/emit/shared/templates/PaginateProcessLogical_HdrSqs.ejs +140 -0
  86. package/src/emit/shared/templates/PaginateProcessLogical_Main.ejs +268 -0
  87. package/src/emit/{relationship/templates/FlowHandler_HdrSqs.ejs → shared/templates/ProcessLogical_HdrSqs.ejs} +40 -55
  88. package/src/emit/shared/templates/ProcessLogical_Main.ejs +448 -0
  89. package/src/emit/system/emitSystemFindDataArtifacts.js +266 -0
  90. package/src/emit/system/emitSystemWebSocketArtifacts.js +61 -165
  91. package/src/emit/system/templates/WebSocketComplete_HdrSqs.ejs +48 -0
  92. package/src/emit/system/templates/WebSocketComplete_Main.ejs +91 -0
  93. package/src/emit/system/templates/WebSocketComplete_Yaml.ejs +19 -0
  94. package/src/emit/system/templates/WebSocketConnect.ejs +45 -0
  95. package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +11 -0
  96. package/src/generate.js +166 -36
  97. package/src/generateIntTest.js +76 -28
  98. package/src/generateResourceIntTest.js +35 -12
  99. package/src/generateResources/IntTest/generateResources/generateResources.js +5 -2
  100. package/src/generateResources/IntTest/generateResources/templateResources.ejs +18 -30
  101. package/src/generateResources/IntTest/generateTests/events/events.js +1 -1
  102. package/src/generateResources/IntTest/generateTests/events/templateEvents.ejs +13 -10
  103. package/src/generateResources/IntTest/generateTests/generateTemplate.js +2 -2
  104. package/src/generateResources/IntTest/generateTests/pathIntTest/pathIntTest.js +2 -1
  105. package/src/generateResources/IntTest/generateTests/pathIntTest/template.ejs +1 -3
  106. package/src/generateResources/IntTest/generateTests/tests/templateTests.ejs +1 -1
  107. package/src/generateResources/IntTest/generateTests/tests/tests.js +7 -3
  108. package/src/generateResources/IntTest/libs/{libs.js → IntTestGenerateLib.js} +34 -23
  109. package/src/generateResources/IntTest/upload/uploadIntTest.js +33 -19
  110. package/src/intTestGeneratorShared.js +15 -10
  111. package/src/output/commitArtifacts.js +99 -39
  112. package/src/output/mergeHooks.js +34 -21
  113. package/src/output/validateArtifacts.js +37 -27
  114. package/src/plan/buildGenerationPlan.js +24 -13
  115. package/test/core.test.js +117 -58
  116. package/test/createTargetRoleHandler.test.js +1 -1
  117. package/test/crudApplicationArtifacts.test.js +132 -31
  118. package/test/customFlowApplicationArtifacts.test.js +353 -71
  119. package/test/dynamicCrudFlowSchemas.test.js +74 -26
  120. package/test/dynamicRbacFlowSchemas.test.js +61 -14
  121. package/test/dynamicRelationshipFlowSchemas.test.js +65 -18
  122. package/test/functionYamlArtifact.test.js +67 -10
  123. package/test/intTestApi.test.js +9 -10
  124. package/test/publicApi.test.js +178 -36
  125. package/test/relationshipApplicationArtifacts.test.js +90 -19
  126. package/test/resourceArtifacts.test.js +173 -33
  127. package/src/emit/relationship/dynamicRelationshipFlowSchemaTemplate.js +0 -11
  128. package/src/emit/relationship/templates/FlowHandler_HdrApi.ejs +0 -59
  129. package/src/emit/relationship/templates/FlowHandler_HdrInv.ejs +0 -47
@@ -1,4 +1,4 @@
1
- import ejs from 'ejs';
1
+ import ejsLib from 'ejs';
2
2
  import { readFile } from 'node:fs/promises';
3
3
  import { rbacFlowTag } from './rbacFlowTag.js';
4
4
 
@@ -16,22 +16,20 @@ const RBAC_FLOW_DEFINITIONS = [
16
16
  const TEMPLATE_URL = new URL('./templates/', import.meta.url);
17
17
 
18
18
  export const dynamicRbacFlowSchemaPaths = RBAC_FLOW_DEFINITIONS.map(
19
- ({ flowTag }) => `app/src/schemas/FlowSchemas/generateCode/FlowRbac/${flowTag}.js`
19
+ ({ flowTag }) =>
20
+ `app/src/schemas/FlowSchemas/generateCode/FlowRbac/${flowTag}.js`
20
21
  );
21
22
 
22
23
  export function rbacFlowSchemaManagedPaths(objects = []) {
23
24
  if (!Array.isArray(objects)) {
24
25
  throw new TypeError('objects must be an array');
25
26
  }
26
- return [
27
- ...dynamicRbacFlowSchemaPaths,
28
- ...objects
29
- .filter(hasRbacAddOn)
30
- .map(
31
- object =>
32
- `app/src/schemas/FlowSchemas/generateCode/FlowRbac/${rbacFlowTag(object)}.js`
33
- )
34
- ];
27
+ const rbacObjects = objects.filter(_hasRbacAddOn);
28
+ const rbacPaths = rbacObjects.map(
29
+ (object) =>
30
+ `app/src/schemas/FlowSchemas/generateCode/FlowRbac/${rbacFlowTag(object)}.js`
31
+ );
32
+ return [...dynamicRbacFlowSchemaPaths, ...rbacPaths];
35
33
  }
36
34
 
37
35
  export async function emitDynamicRbacFlowSchemas({ objects, serviceTag }) {
@@ -39,7 +37,7 @@ export async function emitDynamicRbacFlowSchemas({ objects, serviceTag }) {
39
37
  throw new TypeError('objects must be an array');
40
38
  }
41
39
 
42
- const rbacObjects = objects.filter(hasRbacAddOn);
40
+ const rbacObjects = objects.filter(_hasRbacAddOn);
43
41
  if (rbacObjects.length === 0) {
44
42
  return [];
45
43
  }
@@ -49,31 +47,31 @@ export async function emitDynamicRbacFlowSchemas({ objects, serviceTag }) {
49
47
  );
50
48
  }
51
49
 
52
- return Promise.all([
53
- ...RBAC_FLOW_DEFINITIONS.map(({ flowTag, event }) =>
54
- artifact(flowTag, createSharedRbacFlow(flowTag, event))
55
- ),
56
- ...rbacObjects.map(object => {
57
- const flowTag = rbacFlowTag(object);
58
- return artifact(
59
- flowTag,
60
- createUserRbacFlow(flowTag, serviceTag, object.objectType)
61
- );
62
- })
63
- ]);
50
+ const sharedArtifacts = RBAC_FLOW_DEFINITIONS.map(({ flowTag, event }) =>
51
+ _artifact(flowTag, _createSharedRbacFlow(flowTag, event))
52
+ );
53
+ const userArtifacts = rbacObjects.map((object) => {
54
+ const flowTag = rbacFlowTag(object);
55
+ return _artifact(
56
+ flowTag,
57
+ _createUserRbacFlow(flowTag, serviceTag, object.objectType)
58
+ );
59
+ });
60
+
61
+ return Promise.all([...sharedArtifacts, ...userArtifacts]);
64
62
  }
65
63
 
66
- function hasRbacAddOn(object) {
64
+ function _hasRbacAddOn(object) {
67
65
  return (
68
66
  Array.isArray(object?.addOnDataStructure) &&
69
- object.addOnDataStructure.some(addOn => addOn?.type === 'rbac')
67
+ object.addOnDataStructure.some((addOn) => addOn?.type === 'rbac')
70
68
  );
71
69
  }
72
70
 
73
- async function artifact(flowTag, flow) {
71
+ async function _artifact(flowTag, flow) {
74
72
  return {
75
73
  path: `app/src/schemas/FlowSchemas/generateCode/FlowRbac/${flowTag}.js`,
76
- content: ejs.render(
74
+ content: ejsLib.render(
77
75
  await readFile(
78
76
  new URL('DynamicRbacFlowSchema.ejs', TEMPLATE_URL),
79
77
  'utf8'
@@ -83,7 +81,7 @@ async function artifact(flowTag, flow) {
83
81
  };
84
82
  }
85
83
 
86
- function createSharedRbacFlow(flowTag, event) {
84
+ function _createSharedRbacFlow(flowTag, event) {
87
85
  return {
88
86
  flowTag,
89
87
  initiateBy: 'system',
@@ -107,7 +105,7 @@ function createSharedRbacFlow(flowTag, event) {
107
105
  };
108
106
  }
109
107
 
110
- function createUserRbacFlow(flowTag, serviceTag, objectType) {
108
+ function _createUserRbacFlow(flowTag, serviceTag, objectType) {
111
109
  return {
112
110
  flowTag,
113
111
  objType: { serviceTag, objectType },
@@ -1,4 +1,4 @@
1
- import ejs from 'ejs';
1
+ import ejsLib from 'ejs';
2
2
  import { readFile } from 'node:fs/promises';
3
3
 
4
4
  import {
@@ -29,11 +29,11 @@ export async function emitRbacApplicationArtifacts(objects) {
29
29
  ...objects.filter(hasRbacAddOn).map(createUserRbacFlowHandler)
30
30
  ]);
31
31
  return [
32
- ...handlers.flatMap(handler => handler.artifacts),
32
+ ...handlers.flatMap((handler) => handler.artifacts),
33
33
  {
34
34
  path: FLOW_RBAC_YAML_PATH,
35
35
  content: handlers
36
- .flatMap(handler => handler.functions)
36
+ .flatMap((handler) => handler.functions)
37
37
  .map(renderFunctionYaml)
38
38
  .join('\n')
39
39
  }
@@ -109,7 +109,7 @@ export function rbacApplicationManagedPaths(objects = []) {
109
109
  `app/src/generatedCode/FlowRbac/${flowTag}/source/${flowTag}_WbsMain.js`,
110
110
  `app/src/generatedCode/FlowRbac/${flowTag}/source/${flowTag}_HdrWbs.js`
111
111
  ]),
112
- ...objects.filter(hasRbacAddOn).flatMap(object => {
112
+ ...objects.filter(hasRbacAddOn).flatMap((object) => {
113
113
  const flowTag = rbacFlowTag(object);
114
114
  const sourcePath = `app/src/generatedCode/FlowRbac/${flowTag}/source`;
115
115
  return [
@@ -124,7 +124,7 @@ export function rbacApplicationManagedPaths(objects = []) {
124
124
  function hasRbacAddOn(object) {
125
125
  return (
126
126
  Array.isArray(object?.addOnDataStructure) &&
127
- object.addOnDataStructure.some(addOn => addOn?.type === 'rbac')
127
+ object.addOnDataStructure.some((addOn) => addOn?.type === 'rbac')
128
128
  );
129
129
  }
130
130
 
@@ -362,7 +362,7 @@ function renderRbacTemplate(templateName, data = {}) {
362
362
  }
363
363
 
364
364
  async function renderTemplate(templateUrl, templateName, data) {
365
- return ejs.render(
365
+ return ejsLib.render(
366
366
  await readFile(new URL(templateName, templateUrl), 'utf8'),
367
367
  data
368
368
  );
@@ -11,9 +11,11 @@ export async function generateCreateTargetRoleHandler(rootPath, options = {}) {
11
11
  const project = compileProject({ ...options, rootPath });
12
12
  const objects = await loadLocalSchemaDirectory(project, 'ObjectSchemas');
13
13
  const artifacts = await emitRbacApplicationArtifacts(objects);
14
- const files = await commitArtifacts(buildGenerationPlan(project, artifacts, {
15
- managedPaths: rbacApplicationManagedPaths(),
16
- managedScope: 'rbac-application'
17
- }));
14
+ const files = await commitArtifacts(
15
+ buildGenerationPlan(project, artifacts, {
16
+ managedPaths: rbacApplicationManagedPaths(),
17
+ managedScope: 'rbac-application'
18
+ })
19
+ );
18
20
  return { project, files };
19
21
  }
@@ -12,8 +12,14 @@ export async function generateDynamicRbacFlowSchemas(rootPath, options = {}) {
12
12
  const objects = await loadLocalSchemaDirectory(project, 'ObjectSchemas');
13
13
  const plan = buildGenerationPlan(
14
14
  project,
15
- await emitDynamicRbacFlowSchemas({ objects, serviceTag: project.serviceTag }),
16
- { managedPaths: rbacFlowSchemaManagedPaths(objects), managedScope: 'rbac-flow-schemas' }
15
+ await emitDynamicRbacFlowSchemas({
16
+ objects,
17
+ serviceTag: project.serviceTag
18
+ }),
19
+ {
20
+ managedPaths: rbacFlowSchemaManagedPaths(objects),
21
+ managedScope: 'rbac-flow-schemas'
22
+ }
17
23
  );
18
24
  const files = await commitArtifacts(plan);
19
25
 
@@ -1,7 +1,9 @@
1
1
  export function rbacFlowTag(object) {
2
2
  const objectType = object?.objectType;
3
3
  if (typeof objectType !== 'string' || objectType.trim() === '') {
4
- throw new TypeError('RBAC ObjectSchema.objectType must be a non-empty string');
4
+ throw new TypeError(
5
+ 'RBAC ObjectSchema.objectType must be a non-empty string'
6
+ );
5
7
  }
6
8
  return `${objectType[0].toUpperCase()}${objectType.slice(1)}RbacFlow`;
7
9
  }
@@ -143,7 +143,7 @@ function _matchesParameterGroups(groups, input) {
143
143
  if (val && typeof val === 'object') {
144
144
  val = val[key];
145
145
  } else {
146
- val = undefined;
146
+ val = null;
147
147
  break;
148
148
  }
149
149
  }
@@ -1,5 +1,3 @@
1
- import { renderDynamicRelationshipFlowSchema } from './dynamicRelationshipFlowSchemaTemplate.js';
2
-
3
1
  const ACTIONS = [
4
2
  'CreateRelationship',
5
3
  'UpdateRelationship',
@@ -11,17 +9,33 @@ const ACTIONS = [
11
9
  const MESSAGE_ATTRIBUTES = ['userId', 'correlationId'];
12
10
 
13
11
  export const dynamicRelationshipFlowSchemaPaths = ACTIONS.map(
14
- action => `app/src/schemas/FlowSchemas/generateCode/FlowRelationship/${action}.js`
12
+ (action) =>
13
+ `app/src/schemas/FlowSchemas/generateCode/FlowRelationship/${action}.js`
15
14
  );
16
15
 
17
16
  export function emitDynamicRelationshipFlowSchemas() {
18
17
  // Keep legacy compatibility: relationship flow endpoints exist even before a relationship is declared.
19
18
  return ACTIONS.map((action, index) => ({
20
19
  path: dynamicRelationshipFlowSchemaPaths[index],
21
- content: renderDynamicRelationshipFlowSchema(action, createDynamicRelationshipFlow(action))
20
+ content: _renderDynamicRelationshipFlowSchema(
21
+ action,
22
+ createDynamicRelationshipFlow(action)
23
+ )
22
24
  }));
23
25
  }
24
26
 
27
+ function _renderDynamicRelationshipFlowSchema(action, flow) {
28
+ return [
29
+ '/**',
30
+ ' * GENERATED DYNAMIC RELATIONSHIP FLOW SCHEMA',
31
+ ` * Action: ${action}`,
32
+ ' * Description: Handles dynamic relationship actions for all allowed RelationshipTypes via SQS/DSQ',
33
+ ' */',
34
+ `export default ${JSON.stringify(flow, null, 2)};`,
35
+ ''
36
+ ].join('\n');
37
+ }
38
+
25
39
  function createDynamicRelationshipFlow(action) {
26
40
  const outputTopic = action !== 'GetRelationship';
27
41
  const flowSteps = [
@@ -29,12 +43,14 @@ function createDynamicRelationshipFlow(action) {
29
43
  stepName: 'start',
30
44
  properties: [],
31
45
  messageAttributes: MESSAGE_ATTRIBUTES,
32
- ...(outputTopic ? {
33
- returnValues: {
34
- properties: [],
35
- messageAttributes: MESSAGE_ATTRIBUTES
36
- }
37
- } : {})
46
+ ...(outputTopic
47
+ ? {
48
+ returnValues: {
49
+ properties: [],
50
+ messageAttributes: MESSAGE_ATTRIBUTES
51
+ }
52
+ }
53
+ : {})
38
54
  }
39
55
  ];
40
56
 
@@ -1,4 +1,4 @@
1
- import ejs from 'ejs';
1
+ import ejsLib from 'ejs';
2
2
  import { readFile } from 'node:fs/promises';
3
3
 
4
4
  import {
@@ -18,23 +18,39 @@ const ACTIONS = [
18
18
  ];
19
19
  const YAML_PATH = 'app/sls_yaml/generatedCode/source/flow-relationships.yml';
20
20
  const TEMPLATE_URL = new URL('./templates/', import.meta.url);
21
+ const SHARED_TEMPLATE_URL = new URL('../shared/templates/', import.meta.url);
22
+ const CRUD_TEMPLATE_URL = new URL('../crud/templates/', import.meta.url);
21
23
 
22
- export async function emitRelationshipApplicationArtifacts({ relationships, flows = [], serviceTag }) {
24
+ export async function emitRelationshipApplicationArtifacts({
25
+ relationships,
26
+ flows = [],
27
+ serviceTag
28
+ }) {
23
29
  if (!Array.isArray(relationships) || !Array.isArray(flows)) {
24
30
  throw new TypeError('relationships and flows must be arrays');
25
31
  }
26
32
  if (relationships.length === 0) return [];
27
33
 
28
- const handlers = await Promise.all(ACTIONS.map(action => emitAction(action, relationships, flows, serviceTag)));
34
+ const handlers = await Promise.all(
35
+ ACTIONS.map((action) =>
36
+ emitAction(action, relationships, flows, serviceTag)
37
+ )
38
+ );
29
39
  return [
30
- ...handlers.flatMap(handler => handler.artifacts),
31
- { path: YAML_PATH, content: handlers.flatMap(handler => handler.functions).map(renderFunction).join('\n') }
40
+ ...handlers.flatMap((handler) => handler.artifacts),
41
+ {
42
+ path: YAML_PATH,
43
+ content: handlers
44
+ .flatMap((handler) => handler.functions)
45
+ .map(renderFunction)
46
+ .join('\n')
47
+ }
32
48
  ];
33
49
  }
34
50
 
35
51
  export function relationshipApplicationManagedPaths() {
36
52
  return [
37
- ...ACTIONS.flatMap(action => {
53
+ ...ACTIONS.flatMap((action) => {
38
54
  const source = `app/src/generatedCode/FlowRelationships/${action}/source`;
39
55
  return [
40
56
  `${source}/${action}_Main.js`,
@@ -55,75 +71,200 @@ export function relationshipApplicationManagedPaths() {
55
71
  async function emitAction(action, relationships, flows, serviceTag) {
56
72
  const source = `app/src/generatedCode/FlowRelationships/${action}/source`;
57
73
  const handlerRoot = `src/generatedCode/FlowRelationships/${action}/source`;
58
- const flow = flows.find(candidate => candidate?.flowTag === action);
59
- const events = normalizeEvents(flow?.event, action === 'GetRelationship'
60
- ? ['lambdaSyncInv', 'lambdaSyncApi', 'dsq', 'ownTopic']
61
- : ['ownTopic']);
62
- const shared = { flowTag: action, flowStepName: '', mainFileName: `${action}_Main`, functionName: action, startConfig: null };
63
- const artifacts = [{ path: `${source}/${action}_Main.js`, content: await render(`${action}_Main.ejs`, { functionName: action, upperFunctionName: action }) }];
74
+ const flow = flows.find((candidate) => candidate?.flowTag === action);
75
+ const events = normalizeEvents(
76
+ flow?.event,
77
+ action === 'GetRelationship'
78
+ ? ['lambdaSyncInv', 'lambdaSyncApi', 'dsq', 'ownTopic']
79
+ : ['ownTopic']
80
+ );
81
+ const shared = {
82
+ flowTag: action,
83
+ flowStepName: '',
84
+ mainFileName: `${action}_Main`,
85
+ functionName: action,
86
+ startConfig: null
87
+ };
88
+ const artifacts = [
89
+ {
90
+ path: `${source}/${action}_Main.js`,
91
+ content: await render(`${action}_Main.ejs`, {
92
+ functionName: action,
93
+ upperFunctionName: action
94
+ })
95
+ }
96
+ ];
64
97
  const functions = [];
65
98
 
66
99
  if (events.includes('ownTopic')) {
67
100
  artifacts.push(
68
- { path: `${source}/${action}_WbsMain.js`, content: await renderShared('FlowMain_Wbs.ejs', { flowTag: action, upperCaseFlowTag: action, functionName: action }) },
69
- { path: `${source}/${action}_HdrWbs.js`, content: await renderShared('FlowEndpoint_HdrWbs.ejs', { flowTag: action, upperCaseFlowTag: action, functionName: action, mainFileName: `${action}_WbsMain`, route: action }) }
101
+ {
102
+ path: `${source}/${action}_WbsMain.js`,
103
+ content: await renderCrudTemplate('FlowMain_Wbs.ejs', {
104
+ flowTag: action,
105
+ upperCaseFlowTag: action,
106
+ functionName: action
107
+ })
108
+ },
109
+ {
110
+ path: `${source}/${action}_HdrWbs.js`,
111
+ content: await renderCrudTemplate('FlowEndpoint_HdrWbs.ejs', {
112
+ flowTag: action,
113
+ upperCaseFlowTag: action,
114
+ functionName: action,
115
+ mainFileName: `${action}_WbsMain`,
116
+ route: action
117
+ })
118
+ }
70
119
  );
71
- functions.push({ type: 'wbs', functionName: `${action}HdrWbs`, handlerPath: `${handlerRoot}/${action}_HdrWbs.main`, roleName: 'FlowRelationshipRole', routeName: action, flowTag: action, flowStepName: '' });
120
+ functions.push({
121
+ type: 'wbs',
122
+ functionName: `${action}HdrWbs`,
123
+ handlerPath: `${handlerRoot}/${action}_HdrWbs.main`,
124
+ roleName: 'FlowRelationshipRole',
125
+ routeName: action,
126
+ flowTag: action,
127
+ flowStepName: ''
128
+ });
72
129
  }
73
130
 
74
131
  for (const event of events) {
75
- const handler = eventHandler(event, action, handlerRoot, relationships, serviceTag);
132
+ const handler = eventHandler(
133
+ event,
134
+ action,
135
+ handlerRoot,
136
+ relationships,
137
+ serviceTag
138
+ );
76
139
  if (!handler) continue;
77
- artifacts.push({ path: `${source}/${handler.fileName}.js`, content: await render(handler.template, { ...shared, queueName: handler.queueName }) });
140
+ artifacts.push({
141
+ path: `${source}/${handler.fileName}.js`,
142
+ content: await renderShared(handler.template, {
143
+ ...shared,
144
+ queueName: handler.queueName
145
+ })
146
+ });
78
147
  functions.push(handler.descriptor);
79
148
  }
80
149
 
81
150
  const complete = `${action}Complete`;
82
151
  artifacts.push(
83
- { path: `${source}/${complete}_Main.js`, content: await render(`${action}Complete_Main.ejs`, { functionName: complete, upperFunctionName: complete }) },
84
- { path: `${source}/${complete}_HdrSqs.js`, content: await renderShared('FlowHandler_HdrSqs.ejs', { ...shared, flowStepName: 'Complete', mainFileName: `${complete}_Main`, functionName: complete, queueName: `${complete}HdrSqs` }) }
152
+ {
153
+ path: `${source}/${complete}_Main.js`,
154
+ content: await render(`${action}Complete_Main.ejs`, {
155
+ functionName: complete,
156
+ upperFunctionName: complete
157
+ })
158
+ },
159
+ {
160
+ path: `${source}/${complete}_HdrSqs.js`,
161
+ content: await renderShared('FlowHandler_HdrSqs.ejs', {
162
+ ...shared,
163
+ flowStepName: 'Complete',
164
+ mainFileName: `${complete}_Main`,
165
+ functionName: complete,
166
+ queueName: `${complete}HdrSqs`
167
+ })
168
+ }
85
169
  );
86
- functions.push({ type: 'sqs', functionName: `${action}CompleteHdrSqs`, handlerPath: `${handlerRoot}/${complete}_HdrSqs.main`, roleName: 'FlowRelationshipRole', queueName: `${complete}HdrSqs`, flowTag: action, flowStepName: 'Complete' });
170
+ functions.push({
171
+ type: 'sqs',
172
+ functionName: `${action}CompleteHdrSqs`,
173
+ handlerPath: `${handlerRoot}/${complete}_HdrSqs.main`,
174
+ roleName: 'FlowRelationshipRole',
175
+ queueName: `${complete}HdrSqs`,
176
+ flowTag: action,
177
+ flowStepName: 'Complete'
178
+ });
87
179
  return { artifacts, functions };
88
180
  }
89
181
 
90
182
  function eventHandler(event, action, handlerRoot, relationships, serviceTag) {
91
183
  if (event === 'ownTopic' || event === 'extTopic') {
92
184
  return {
93
- fileName: `${action}_HdrSqs`, template: 'FlowHandler_HdrSqs.ejs', queueName: `${action}HdrSqs`,
94
- descriptor: { type: 'sqs', functionName: `${action.replace('Relationship', 'Rel')}HdrSqs`, handlerPath: `${handlerRoot}/${action}_HdrSqs.main`, roleName: 'FlowRelationshipRole', queueName: `${action}HdrSqs`, flowTag: action, flowStepName: '' }
185
+ fileName: `${action}_HdrSqs`,
186
+ template: 'FlowHandler_HdrSqs.ejs',
187
+ queueName: `${action}HdrSqs`,
188
+ descriptor: {
189
+ type: 'sqs',
190
+ functionName: `${action.replace('Relationship', 'Rel')}HdrSqs`,
191
+ handlerPath: `${handlerRoot}/${action}_HdrSqs.main`,
192
+ roleName: 'FlowRelationshipRole',
193
+ queueName: `${action}HdrSqs`,
194
+ flowTag: action,
195
+ flowStepName: ''
196
+ }
95
197
  };
96
198
  }
97
199
  if (event === 'dsq') {
98
200
  return {
99
- fileName: `${action}_HdrDsq`, template: 'FlowHandler_HdrDsq.ejs', queueName: `${action}HdrDsq`,
100
- descriptor: { type: 'sqs', functionName: `${action.replace('Relationship', 'Rel')}HdrDsq`, handlerPath: `${handlerRoot}/${action}_HdrDsq.main`, roleName: 'FlowRelationshipRole', queueName: `${action}HdrDsq`, flowTag: action, flowStepName: '' }
201
+ fileName: `${action}_HdrDsq`,
202
+ template: 'FlowHandler_HdrDsq.ejs',
203
+ queueName: `${action}HdrDsq`,
204
+ descriptor: {
205
+ type: 'sqs',
206
+ functionName: `${action.replace('Relationship', 'Rel')}HdrDsq`,
207
+ handlerPath: `${handlerRoot}/${action}_HdrDsq.main`,
208
+ roleName: 'FlowRelationshipRole',
209
+ queueName: `${action}HdrDsq`,
210
+ flowTag: action,
211
+ flowStepName: ''
212
+ }
101
213
  };
102
214
  }
103
215
  if (event === 'lambdaSyncInv') {
104
216
  return {
105
- fileName: `${action}_HdrInv`, template: 'FlowHandler_HdrInv.ejs',
106
- descriptor: { type: 'inv', functionName: `${action.replace('Relationship', 'Rel')}HdrInv`, handlerPath: `${handlerRoot}/${action}_HdrInv.main`, roleName: 'FlowRelationshipRole', flowTag: action, flowStepName: '' }
217
+ fileName: `${action}_HdrInv`,
218
+ template: 'FlowHandler_HdrInv.ejs',
219
+ descriptor: {
220
+ type: 'inv',
221
+ functionName: `${action.replace('Relationship', 'Rel')}HdrInv`,
222
+ handlerPath: `${handlerRoot}/${action}_HdrInv.main`,
223
+ roleName: 'FlowRelationshipRole',
224
+ flowTag: action,
225
+ flowStepName: ''
226
+ }
107
227
  };
108
228
  }
109
229
  if (event === 'lambdaSyncApi') {
110
230
  return {
111
- fileName: `${action}_HdrApi`, template: 'FlowHandler_HdrApi.ejs',
231
+ fileName: `${action}_HdrApi`,
232
+ template: 'FlowHandler_HdrApi.ejs',
112
233
  descriptor: {
113
- type: 'api', functionName: `${action.replace('Relationship', 'Rel')}HdrApi`, handlerPath: `${handlerRoot}/${action}_HdrApi.main`, roleName: 'FlowRelationshipRole',
114
- flowTag: action, flowStepName: '',
115
- routes: relationships.map(relationship => {
116
- const name = relationship.relationshipTag ?? Object.keys(relationship)[0];
117
- return { path: `/${serviceTag ?? '${self:custom.iz_serviceName}'}/${name}/${action.toLowerCase().replace('relationship', '')}`, upperName: upperFirst(name) };
234
+ type: 'api',
235
+ functionName: `${action.replace('Relationship', 'Rel')}HdrApi`,
236
+ handlerPath: `${handlerRoot}/${action}_HdrApi.main`,
237
+ roleName: 'FlowRelationshipRole',
238
+ flowTag: action,
239
+ flowStepName: '',
240
+ routes: relationships.map((relationship) => {
241
+ let name = Object.keys(relationship)[0];
242
+ if (relationship.relationshipTag) {
243
+ name = relationship.relationshipTag;
244
+ }
245
+ let targetServiceTag = '${self:custom.iz_serviceName}';
246
+ if (serviceTag) {
247
+ targetServiceTag = serviceTag;
248
+ }
249
+ return {
250
+ path: `/${targetServiceTag}/${name}/${action.toLowerCase().replace('relationship', '')}`,
251
+ upperName: upperFirst(name)
252
+ };
118
253
  })
119
254
  }
120
255
  };
121
256
  }
122
- return undefined;
257
+ return null;
123
258
  }
124
259
 
125
260
  function normalizeEvents(events, fallback) {
126
- return events === undefined ? fallback : (Array.isArray(events) ? events : [events]);
261
+ if (events === undefined) {
262
+ return fallback;
263
+ }
264
+ if (Array.isArray(events)) {
265
+ return events;
266
+ }
267
+ return [events];
127
268
  }
128
269
 
129
270
  function upperFirst(value) {
@@ -132,12 +273,23 @@ function upperFirst(value) {
132
273
 
133
274
  async function render(templateName, data) {
134
275
  const template = await readFile(new URL(templateName, TEMPLATE_URL), 'utf8');
135
- return ejs.render(template, data);
276
+ return ejsLib.render(template, data);
136
277
  }
137
278
 
138
279
  async function renderShared(templateName, data) {
139
- const template = await readFile(new URL(`../crud/templates/${templateName}`, import.meta.url), 'utf8');
140
- return ejs.render(template, data);
280
+ const template = await readFile(
281
+ new URL(`../shared/templates/${templateName}`, import.meta.url),
282
+ 'utf8'
283
+ );
284
+ return ejsLib.render(template, data);
285
+ }
286
+
287
+ async function renderCrudTemplate(templateName, data) {
288
+ const template = await readFile(
289
+ new URL(`../crud/templates/${templateName}`, import.meta.url),
290
+ 'utf8'
291
+ );
292
+ return ejsLib.render(template, data);
141
293
  }
142
294
 
143
295
  function renderFunction(descriptor) {
@@ -7,7 +7,10 @@ import {
7
7
  emitDynamicRelationshipFlowSchemas
8
8
  } from './emitDynamicRelationshipFlowSchemas.js';
9
9
 
10
- export async function generateDynamicRelationshipFlowSchemas(rootPath, options = {}) {
10
+ export async function generateDynamicRelationshipFlowSchemas(
11
+ rootPath,
12
+ options = {}
13
+ ) {
11
14
  const project = compileProject({ ...options, rootPath });
12
15
  // The legacy generator creates these endpoints even with no relationships. Load now to
13
16
  // validate the V2 source-module contract before later slices consume relationship data.
@@ -15,7 +18,10 @@ export async function generateDynamicRelationshipFlowSchemas(rootPath, options =
15
18
  const plan = buildGenerationPlan(
16
19
  project,
17
20
  emitDynamicRelationshipFlowSchemas(),
18
- { managedPaths: dynamicRelationshipFlowSchemaPaths, managedScope: 'relationship-flow-schemas' }
21
+ {
22
+ managedPaths: dynamicRelationshipFlowSchemaPaths,
23
+ managedScope: 'relationship-flow-schemas'
24
+ }
19
25
  );
20
26
  const files = await commitArtifacts(plan);
21
27
 
@@ -7,16 +7,25 @@ import {
7
7
  relationshipApplicationManagedPaths
8
8
  } from './emitRelationshipApplicationArtifacts.js';
9
9
 
10
- export async function generateRelationshipApplicationArtifacts(rootPath, options = {}) {
10
+ export async function generateRelationshipApplicationArtifacts(
11
+ rootPath,
12
+ options = {}
13
+ ) {
11
14
  const project = compileProject({ ...options, rootPath });
12
15
  const [relationships, flows] = await Promise.all([
13
16
  loadLocalSchemaDirectory(project, 'RelationshipSchemas'),
14
17
  loadLocalSchemaDirectory(project, 'FlowSchemas')
15
18
  ]);
16
- const artifacts = await emitRelationshipApplicationArtifacts({ relationships, flows, serviceTag: project.serviceTag });
17
- const files = await commitArtifacts(buildGenerationPlan(project, artifacts, {
18
- managedPaths: relationshipApplicationManagedPaths(),
19
- managedScope: 'relationship-application'
20
- }));
19
+ const artifacts = await emitRelationshipApplicationArtifacts({
20
+ relationships,
21
+ flows,
22
+ serviceTag: project.serviceTag
23
+ });
24
+ const files = await commitArtifacts(
25
+ buildGenerationPlan(project, artifacts, {
26
+ managedPaths: relationshipApplicationManagedPaths(),
27
+ managedScope: 'relationship-application'
28
+ })
29
+ );
21
30
  return { project, files };
22
31
  }
@@ -64,7 +64,7 @@ import { consts as coreConsts } from '@izara_project/izara-core-library-core';
64
64
  export default async function <%- functionName %>(
65
65
  _izContext,
66
66
  requestParams,
67
- callingFlowConfig = {}
67
+ callingFlowConfig = {},
68
68
  //(<additionalParams>)
69
69
  //(</additionalParams>)
70
70
  ) {
@@ -61,7 +61,7 @@ const { PREFIX, TOPIC_NAME_GENERATE_CODE, TOPIC_NAME_GRAPH_HANDLER } = consts;
61
61
  export default async function createRelationship(
62
62
  _izContext,
63
63
  requestParams,
64
- callingFlowConfig = {}
64
+ callingFlowConfig = {},
65
65
  //(<additionalParams>)
66
66
  //(</additionalParams>)
67
67
  ) {
@@ -61,7 +61,7 @@ const { PREFIX, TOPIC_NAME_GENERATE_CODE, TOPIC_NAME_GRAPH_HANDLER } = consts;
61
61
  export default async function deleteRelationship(
62
62
  _izContext,
63
63
  requestParams,
64
- callingFlowConfig = {}
64
+ callingFlowConfig = {},
65
65
  //(<additionalParams>)
66
66
  //(</additionalParams>)
67
67
  ) {