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

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 (81) hide show
  1. package/package.json +1 -1
  2. package/scripts/format-ejs.js +1 -2
  3. package/src/compile/compileProject.js +26 -10
  4. package/src/compile/loadSchemas.js +47 -23
  5. package/src/emit/crud/emitCrudApplicationArtifacts.js +188 -41
  6. package/src/emit/crud/emitDynamicCrudFlowSchemas.js +34 -17
  7. package/src/emit/crud/generateCrudApplicationArtifacts.js +14 -6
  8. package/src/emit/crud/generateDynamicCrudFlowSchemas.js +4 -1
  9. package/src/emit/crud/templates/GetEndpoint_Main.ejs +1 -1
  10. package/src/emit/custom/customFlows.js +23 -13
  11. package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +515 -113
  12. package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +28 -8
  13. package/src/emit/custom/templates/s3/FlowHandler_HdrS3.ejs +2 -2
  14. package/src/emit/custom/templates/s3/ReservedLimit_HdrSqs.ejs +1 -1
  15. package/src/emit/function/functionYamlArtifact.js +270 -97
  16. package/src/emit/function/templates/ApiFunction_Yaml.ejs +7 -0
  17. package/src/emit/function/templates/EventBridgeFunction_Yaml.ejs +6 -0
  18. package/src/emit/function/templates/InvFunction_Yaml.ejs +5 -0
  19. package/src/emit/function/templates/S3Function_Yaml.ejs +16 -0
  20. package/src/emit/function/templates/SqsFunction_Yaml.ejs +10 -0
  21. package/src/emit/function/templates/WbsFunction_Yaml.ejs +10 -0
  22. package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +28 -30
  23. package/src/emit/rbac/emitRbacApplicationArtifacts.js +6 -6
  24. package/src/emit/rbac/generateCreateTargetRoleHandler.js +6 -4
  25. package/src/emit/rbac/generateDynamicRbacFlowSchemas.js +8 -2
  26. package/src/emit/rbac/rbacFlowTag.js +3 -1
  27. package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +1 -1
  28. package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +26 -10
  29. package/src/emit/relationship/emitRelationshipApplicationArtifacts.js +179 -37
  30. package/src/emit/relationship/generateDynamicRelationshipFlowSchemas.js +8 -2
  31. package/src/emit/relationship/generateRelationshipApplicationArtifacts.js +15 -6
  32. package/src/emit/resource/emitResourceArtifacts.js +187 -114
  33. package/src/emit/resource/generateResourceArtifacts.js +15 -6
  34. package/src/emit/resource/templates/DynamoDBTable_Yaml.ejs +18 -18
  35. package/src/emit/resource/templates/FlowOut_Yaml.ejs +5 -5
  36. package/src/emit/resource/templates/GeneratedLambdaRoleServiceConfig.ejs +10 -9
  37. package/src/emit/resource/templates/ResourceBeforeLogicalYaml.ejs +44 -44
  38. package/src/emit/resource/templates/ResourceSqsYaml.ejs +36 -36
  39. package/src/emit/resource/templates/ResourceYaml.ejs +48 -48
  40. package/src/emit/resource/templates/S3Subscription_Yaml.ejs +7 -0
  41. package/src/emit/resource/templates/SharedResource_Yaml.ejs +11 -11
  42. package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +105 -105
  43. package/src/emit/resource/templates/WebSocketSubscription_Yaml.ejs +7 -0
  44. package/src/emit/system/emitSystemWebSocketArtifacts.js +61 -165
  45. package/src/emit/system/templates/WebSocketComplete_HdrSqs.ejs +32 -0
  46. package/src/emit/system/templates/WebSocketComplete_Main.ejs +46 -0
  47. package/src/emit/system/templates/WebSocketComplete_Yaml.ejs +19 -0
  48. package/src/emit/system/templates/WebSocketConnect.ejs +25 -0
  49. package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +11 -0
  50. package/src/generate.js +136 -33
  51. package/src/generateIntTest.js +76 -28
  52. package/src/generateResourceIntTest.js +35 -12
  53. package/src/generateResources/IntTest/generateResources/generateResources.js +5 -2
  54. package/src/generateResources/IntTest/generateResources/templateResources.ejs +18 -30
  55. package/src/generateResources/IntTest/generateTests/events/events.js +1 -1
  56. package/src/generateResources/IntTest/generateTests/events/templateEvents.ejs +13 -10
  57. package/src/generateResources/IntTest/generateTests/generateTemplate.js +2 -2
  58. package/src/generateResources/IntTest/generateTests/pathIntTest/pathIntTest.js +2 -1
  59. package/src/generateResources/IntTest/generateTests/pathIntTest/template.ejs +1 -3
  60. package/src/generateResources/IntTest/generateTests/tests/templateTests.ejs +1 -1
  61. package/src/generateResources/IntTest/generateTests/tests/tests.js +7 -3
  62. package/src/generateResources/IntTest/libs/{libs.js → IntTestGenerateLib.js} +34 -23
  63. package/src/generateResources/IntTest/upload/uploadIntTest.js +33 -19
  64. package/src/intTestGeneratorShared.js +15 -10
  65. package/src/output/commitArtifacts.js +99 -39
  66. package/src/output/mergeHooks.js +24 -10
  67. package/src/output/validateArtifacts.js +37 -27
  68. package/src/plan/buildGenerationPlan.js +24 -13
  69. package/test/core.test.js +116 -49
  70. package/test/createTargetRoleHandler.test.js +1 -1
  71. package/test/crudApplicationArtifacts.test.js +128 -23
  72. package/test/customFlowApplicationArtifacts.test.js +353 -71
  73. package/test/dynamicCrudFlowSchemas.test.js +74 -26
  74. package/test/dynamicRbacFlowSchemas.test.js +61 -14
  75. package/test/dynamicRelationshipFlowSchemas.test.js +65 -18
  76. package/test/functionYamlArtifact.test.js +67 -10
  77. package/test/intTestApi.test.js +9 -10
  78. package/test/publicApi.test.js +176 -34
  79. package/test/relationshipApplicationArtifacts.test.js +90 -19
  80. package/test/resourceArtifacts.test.js +172 -32
  81. package/src/emit/relationship/dynamicRelationshipFlowSchemaTemplate.js +0 -11
@@ -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 {
@@ -9,85 +9,204 @@ import {
9
9
  renderSqsFunctionYaml,
10
10
  renderWbsFunctionYaml
11
11
  } from '../function/functionYamlArtifact.js';
12
- import { customFlowRoleName, flowDsqSteps, flowExtTopicSteps, generatedOwnTopicFlows, supportedCustomFlows, upperFirst } from './customFlows.js';
12
+ import {
13
+ customFlowRoleName,
14
+ flowDsqSteps,
15
+ flowExtTopicSteps,
16
+ generatedOwnTopicFlows,
17
+ supportedCustomFlows,
18
+ upperFirst
19
+ } from './customFlows.js';
13
20
 
14
21
  const YAML_PATH = 'app/sls_yaml/generatedCode/source/flow-schema.yml';
15
22
  const TEMPLATE_URL = new URL('../crud/templates/', import.meta.url);
16
23
  const CUSTOM_TEMPLATE_URL = new URL('./templates/', import.meta.url);
17
24
  const DSQ_TEMPLATE_URL = new URL('../relationship/templates/', import.meta.url);
18
25
 
19
- export async function emitCustomFlowApplicationArtifacts(flows, { systemFunctions = [], objects = [] } = {}) {
26
+ export async function emitCustomFlowApplicationArtifacts(
27
+ flows,
28
+ { systemFunctions = [], objects = [] } = {}
29
+ ) {
20
30
  const customFlows = supportedCustomFlows(flows);
21
31
  const generatedRoots = generatedOwnTopicFlows(flows);
22
32
  const steps = flowExtTopicSteps(flows);
23
33
  const dsqSteps = flowDsqSteps(flows);
24
- if (customFlows.length === 0 && generatedRoots.length === 0 && steps.length === 0 && dsqSteps.length === 0 && systemFunctions.length === 0) return [];
25
-
26
- const emitted = await Promise.all(customFlows.map(flow => emitFlow(flow, objects)));
27
- const roots = await Promise.all(generatedRoots.map(flow => emitOwnTopicRoot(flow, objects)));
34
+ if (
35
+ customFlows.length === 0 &&
36
+ generatedRoots.length === 0 &&
37
+ steps.length === 0 &&
38
+ dsqSteps.length === 0 &&
39
+ systemFunctions.length === 0
40
+ )
41
+ return [];
42
+
43
+ const emitted = await Promise.all(
44
+ customFlows.map((flow) => emitFlow(flow, objects))
45
+ );
46
+ const roots = await Promise.all(
47
+ generatedRoots.map((flow) => emitOwnTopicRoot(flow, objects))
48
+ );
28
49
  const stepResults = await Promise.all(steps.map(emitExtTopicStep));
29
50
  const dsqStepResults = await Promise.all(dsqSteps.map(emitDsqStep));
30
51
  return [
31
- ...emitted.flatMap(result => result.artifacts),
32
- ...roots.flatMap(result => result.artifacts),
33
- ...stepResults.flatMap(result => result.artifacts),
34
- ...dsqStepResults.flatMap(result => result.artifacts),
35
- { path: YAML_PATH, content: [...systemFunctions, ...emitted.flatMap(result => result.functions), ...roots.flatMap(result => result.functions), ...stepResults.flatMap(result => result.functions), ...dsqStepResults.flatMap(result => result.functions)].join('\n') }
52
+ ...emitted.flatMap((result) => result.artifacts),
53
+ ...roots.flatMap((result) => result.artifacts),
54
+ ...stepResults.flatMap((result) => result.artifacts),
55
+ ...dsqStepResults.flatMap((result) => result.artifacts),
56
+ {
57
+ path: YAML_PATH,
58
+ content: [
59
+ ...systemFunctions,
60
+ ...emitted.flatMap((result) => result.functions),
61
+ ...roots.flatMap((result) => result.functions),
62
+ ...stepResults.flatMap((result) => result.functions),
63
+ ...dsqStepResults.flatMap((result) => result.functions)
64
+ ].join('\n')
65
+ }
36
66
  ];
37
67
  }
38
68
 
39
- export function customFlowApplicationManagedPaths(flows, { includeYaml = false } = {}) {
69
+ export function customFlowApplicationManagedPaths(
70
+ flows,
71
+ { includeYaml = false } = {}
72
+ ) {
40
73
  return [
41
- ...supportedCustomFlows(flows).flatMap(flow => flowPaths(flow)),
74
+ ...supportedCustomFlows(flows).flatMap((flow) => flowPaths(flow)),
42
75
  ...generatedOwnTopicFlows(flows).flatMap(ownTopicRootPaths),
43
76
  ...flowExtTopicSteps(flows).flatMap(({ flowTag, stepName }) => {
44
77
  const source = `app/src/generatedCode/FlowSchemas/${flowTag}/source`;
45
- return [`${source}/${flowTag}${stepName}_Main.js`, `${source}/${flowTag}${stepName}_HdrSqs.js`];
78
+ return [
79
+ `${source}/${flowTag}${stepName}_Main.js`,
80
+ `${source}/${flowTag}${stepName}_HdrSqs.js`
81
+ ];
46
82
  }),
47
83
  ...flowDsqSteps(flows).flatMap(({ flowTag, stepName, step }) => {
48
84
  const source = `app/src/generatedCode/FlowSchemas/${flowTag}/source`;
49
- const stepEvents = Array.isArray(step.event) ? step.event : [];
50
- return [
51
- ...(stepEvents.includes('extTopic') ? [] : [`${source}/${flowTag}${stepName}_Main.js`]),
52
- `${source}/${flowTag}${stepName}_HdrDsq.js`
53
- ];
85
+ let stepEvents = [];
86
+ if (Array.isArray(step.event)) {
87
+ stepEvents = step.event;
88
+ }
89
+ const files = [`${source}/${flowTag}${stepName}_HdrDsq.js`];
90
+ if (!stepEvents.includes('extTopic')) {
91
+ files.unshift(`${source}/${flowTag}${stepName}_Main.js`);
92
+ }
93
+ return files;
54
94
  }),
55
- ...(supportedCustomFlows(flows).length > 0 || generatedOwnTopicFlows(flows).length > 0 || flowExtTopicSteps(flows).length > 0 || flowDsqSteps(flows).length > 0 || includeYaml ? [YAML_PATH] : [])
95
+ ...(supportedCustomFlows(flows).length > 0 ||
96
+ generatedOwnTopicFlows(flows).length > 0 ||
97
+ flowExtTopicSteps(flows).length > 0 ||
98
+ flowDsqSteps(flows).length > 0 ||
99
+ includeYaml
100
+ ? [YAML_PATH]
101
+ : [])
56
102
  ];
57
103
  }
58
104
 
59
-
60
-
61
105
  async function emitFlow(flow, objects) {
62
106
  const tag = upperFirst(flow.flowTag);
63
107
  const process = tag;
64
108
  const source = `app/src/generatedCode/FlowSchemas/${tag}/source`;
65
109
  const handlerRoot = `src/generatedCode/FlowSchemas/${tag}/source`;
66
- const shared = { flowTag: flow.flowTag, flowStepName: '', mainFileName: `${process}_Main`, functionName: process, startConfig: startConfig(flow) };
110
+ const shared = {
111
+ flowTag: flow.flowTag,
112
+ flowStepName: '',
113
+ mainFileName: `${process}_Main`,
114
+ functionName: process,
115
+ startConfig: startConfig(flow)
116
+ };
67
117
  const artifacts = needsProcessMain(flow)
68
- ? [{ path: `${source}/${process}_Main.js`, content: await renderEndpointMain(flow, process, objects) }]
118
+ ? [
119
+ {
120
+ path: `${source}/${process}_Main.js`,
121
+ content: await renderEndpointMain(flow, process, objects)
122
+ }
123
+ ]
69
124
  : [];
70
125
  const functions = [];
71
126
 
72
127
  if (flow.event.includes('extTopic') && !flow.event.includes('ownTopic')) {
73
- artifacts.push({ path: `${source}/${process}_HdrSqs.js`, content: await render('FlowHandler_HdrSqs.ejs', { ...shared, queueName: `${process}HdrSqs` }) });
74
- functions.push(renderSqsFunctionYaml({ functionName: `${process}HdrSqs`, handlerPath: `${handlerRoot}/${process}_HdrSqs.main`, roleName: customFlowRoleName(flow.flowTag), queueName: `${process}HdrSqs`, flowTag: flow.flowTag, flowStepName: '' }));
128
+ artifacts.push({
129
+ path: `${source}/${process}_HdrSqs.js`,
130
+ content: await render('FlowHandler_HdrSqs.ejs', {
131
+ ...shared,
132
+ queueName: `${process}HdrSqs`
133
+ })
134
+ });
135
+ functions.push(
136
+ renderSqsFunctionYaml({
137
+ functionName: `${process}HdrSqs`,
138
+ handlerPath: `${handlerRoot}/${process}_HdrSqs.main`,
139
+ roleName: customFlowRoleName(flow.flowTag),
140
+ queueName: `${process}HdrSqs`,
141
+ flowTag: flow.flowTag,
142
+ flowStepName: ''
143
+ })
144
+ );
75
145
  }
76
146
  if (flow.event.includes('dsq')) {
77
- artifacts.push({ path: `${source}/${process}_HdrDsq.js`, content: await renderDsq('FlowHandler_HdrDsq.ejs', { ...shared, queueName: `${process}HdrDsq` }) });
78
- functions.push(renderSqsFunctionYaml({ functionName: `${process}HdrDsq`, handlerPath: `${handlerRoot}/${process}_HdrDsq.main`, roleName: customFlowRoleName(flow.flowTag), queueName: `${process}HdrDsq`, flowTag: flow.flowTag, flowStepName: '' }));
147
+ artifacts.push({
148
+ path: `${source}/${process}_HdrDsq.js`,
149
+ content: await renderDsq('FlowHandler_HdrDsq.ejs', {
150
+ ...shared,
151
+ queueName: `${process}HdrDsq`
152
+ })
153
+ });
154
+ functions.push(
155
+ renderSqsFunctionYaml({
156
+ functionName: `${process}HdrDsq`,
157
+ handlerPath: `${handlerRoot}/${process}_HdrDsq.main`,
158
+ roleName: customFlowRoleName(flow.flowTag),
159
+ queueName: `${process}HdrDsq`,
160
+ flowTag: flow.flowTag,
161
+ flowStepName: ''
162
+ })
163
+ );
79
164
  }
80
165
  if (flow.event.includes('lambdaSyncInv')) {
81
- artifacts.push({ path: `${source}/${process}_HdrInv.js`, content: await render('FlowHandler_HdrInv.ejs', shared) });
82
- functions.push(renderInvFunctionYaml({ functionName: `${process}HdrInv`, handlerPath: `${handlerRoot}/${process}_HdrInv.main`, roleName: customFlowRoleName(flow.flowTag), flowTag: flow.flowTag, flowStepName: '' }));
166
+ artifacts.push({
167
+ path: `${source}/${process}_HdrInv.js`,
168
+ content: await render('FlowHandler_HdrInv.ejs', shared)
169
+ });
170
+ functions.push(
171
+ renderInvFunctionYaml({
172
+ functionName: `${process}HdrInv`,
173
+ handlerPath: `${handlerRoot}/${process}_HdrInv.main`,
174
+ roleName: customFlowRoleName(flow.flowTag),
175
+ flowTag: flow.flowTag,
176
+ flowStepName: ''
177
+ })
178
+ );
83
179
  }
84
180
  if (flow.event.includes('lambdaSyncApi')) {
85
- artifacts.push({ path: `${source}/${process}_HdrApi.js`, content: await render('FlowHandler_HdrApi.ejs', shared) });
86
- functions.push(renderApiFunctionYaml({ functionName: `${process}HdrApi`, handlerPath: `${handlerRoot}/${process}_HdrApi.main`, roleName: customFlowRoleName(flow.flowTag), flowTag: flow.flowTag, flowStepName: '' }));
181
+ artifacts.push({
182
+ path: `${source}/${process}_HdrApi.js`,
183
+ content: await render('FlowHandler_HdrApi.ejs', shared)
184
+ });
185
+ functions.push(
186
+ renderApiFunctionYaml({
187
+ functionName: `${process}HdrApi`,
188
+ handlerPath: `${handlerRoot}/${process}_HdrApi.main`,
189
+ roleName: customFlowRoleName(flow.flowTag),
190
+ flowTag: flow.flowTag,
191
+ flowStepName: ''
192
+ })
193
+ );
87
194
  }
88
195
  if (flow.event.includes('eventBridge')) {
89
- artifacts.push({ path: `${source}/${process}_HdrInv.js`, content: await render('FlowHandler_HdrInv.ejs', shared) });
90
- functions.push(renderEventBridgeFunctionYaml({ functionName: `${process}HdrInv`, handlerPath: `${handlerRoot}/${process}_HdrInv.main`, roleName: customFlowRoleName(flow.flowTag), flowTag: flow.flowTag, flowStepName: '', schedules: flow.schedules ?? [] }));
196
+ artifacts.push({
197
+ path: `${source}/${process}_HdrInv.js`,
198
+ content: await render('FlowHandler_HdrInv.ejs', shared)
199
+ });
200
+ functions.push(
201
+ renderEventBridgeFunctionYaml({
202
+ functionName: `${process}HdrInv`,
203
+ handlerPath: `${handlerRoot}/${process}_HdrInv.main`,
204
+ roleName: customFlowRoleName(flow.flowTag),
205
+ flowTag: flow.flowTag,
206
+ flowStepName: '',
207
+ schedules: flow.schedules ?? []
208
+ })
209
+ );
91
210
  }
92
211
  if (flow.event.includes('ownTopic')) {
93
212
  const root = await emitOwnTopicRoot(flow, objects);
@@ -106,17 +225,48 @@ function flowPaths(flow) {
106
225
  const tag = upperFirst(flow.flowTag);
107
226
  const process = tag;
108
227
  const source = `app/src/generatedCode/FlowSchemas/${tag}/source`;
109
- const paths = needsProcessMain(flow) ? [`${source}/${process}_Main.js`] : [];
110
- if (flow.event.includes('extTopic') && !flow.event.includes('ownTopic')) paths.push(`${source}/${process}_HdrSqs.js`);
111
- if (flow.event.includes('dsq')) paths.push(`${source}/${process}_HdrDsq.js`);
112
- if (flow.event.includes('lambdaSyncInv') || flow.event.includes('eventBridge')) paths.push(`${source}/${process}_HdrInv.js`);
113
- if (flow.event.includes('lambdaSyncApi')) paths.push(`${source}/${process}_HdrApi.js`);
114
- if (flow.event.includes('ownTopic')) paths.push(...ownTopicRootPaths(flow));
228
+ const paths = [];
229
+ if (needsProcessMain(flow)) {
230
+ paths.push(`${source}/${process}_Main.js`);
231
+ }
232
+ if (flow.event.includes('extTopic') && !flow.event.includes('ownTopic')) {
233
+ paths.push(`${source}/${process}_HdrSqs.js`);
234
+ }
235
+ if (flow.event.includes('dsq')) {
236
+ paths.push(`${source}/${process}_HdrDsq.js`);
237
+ }
238
+ if (
239
+ flow.event.includes('lambdaSyncInv') ||
240
+ flow.event.includes('eventBridge')
241
+ ) {
242
+ paths.push(`${source}/${process}_HdrInv.js`);
243
+ }
244
+ if (flow.event.includes('lambdaSyncApi')) {
245
+ paths.push(`${source}/${process}_HdrApi.js`);
246
+ }
247
+ if (flow.event.includes('ownTopic')) {
248
+ paths.push(...ownTopicRootPaths(flow));
249
+ }
115
250
  if (flow.event.includes('s3')) {
116
- ['ConfirmAfterUpload', 'CreateObject', 'CreatePreSignUrl', 'ProcessAfterUpload', 'ReservedLimit'].forEach(action => {
117
- const handler = action === 'CreateObject' ? 'HdrWbs' : action === 'ProcessAfterUpload' ? 'HdrS3' : 'HdrSqs';
118
- paths.push(`${source}/${tag}${action}_Main.js`, `${source}/${tag}${action}_${handler}.js`);
119
- });
251
+ const s3Actions = [
252
+ 'ConfirmAfterUpload',
253
+ 'CreateObject',
254
+ 'CreatePreSignUrl',
255
+ 'ProcessAfterUpload',
256
+ 'ReservedLimit'
257
+ ];
258
+ for (const action of s3Actions) {
259
+ let handler = 'HdrSqs';
260
+ if (action === 'CreateObject') {
261
+ handler = 'HdrWbs';
262
+ } else if (action === 'ProcessAfterUpload') {
263
+ handler = 'HdrS3';
264
+ }
265
+ paths.push(
266
+ `${source}/${tag}${action}_Main.js`,
267
+ `${source}/${tag}${action}_${handler}.js`
268
+ );
269
+ }
120
270
  }
121
271
  return paths;
122
272
  }
@@ -124,34 +274,85 @@ function flowPaths(flow) {
124
274
  async function emitExtTopicStep({ flow, step, flowTag, stepName }) {
125
275
  const source = `app/src/generatedCode/FlowSchemas/${flowTag}/source`;
126
276
  const handlerRoot = `src/generatedCode/FlowSchemas/${flowTag}/source`;
127
- const functionName = stepName.startsWith(flowTag) ? stepName : `${flowTag}${stepName}`;
277
+ const functionName = stepName.startsWith(flowTag)
278
+ ? stepName
279
+ : `${flowTag}${stepName}`;
128
280
  const mainFileName = `${functionName}_Main`;
129
281
  const startConfig = stepConfig(flow, step);
130
282
 
131
- const hasTriggerFlowTypes = Array.isArray(flow.triggerFlowTypes) && flow.triggerFlowTypes.length > 0;
283
+ const hasTriggerFlowTypes =
284
+ Array.isArray(flow.triggerFlowTypes) && flow.triggerFlowTypes.length > 0;
132
285
  const isCheckStep = stepName.toLowerCase().includes('checktrigger');
133
286
 
134
287
  if (isCheckStep && hasTriggerFlowTypes) {
135
288
  const queueName = `${functionName}HdrSqs`;
136
289
  return {
137
290
  artifacts: [
138
- { path: `${source}/${mainFileName}.js`, content: await renderCustom('triggerCache/CheckTriggerCache_Main.ejs', { functionName, flowTag }) },
139
- { path: `${source}/${functionName}_HdrSqs.js`, content: await renderCustom('triggerCache/CheckTriggerCache_HdrSqs.ejs', { functionName, queueName, startConfig }) }
291
+ {
292
+ path: `${source}/${mainFileName}.js`,
293
+ content: await renderCustom(
294
+ 'triggerCache/CheckTriggerCache_Main.ejs',
295
+ { functionName, flowTag }
296
+ )
297
+ },
298
+ {
299
+ path: `${source}/${functionName}_HdrSqs.js`,
300
+ content: await renderCustom(
301
+ 'triggerCache/CheckTriggerCache_HdrSqs.ejs',
302
+ { functionName, queueName, startConfig }
303
+ )
304
+ }
140
305
  ],
141
- functions: [renderSqsFunctionYaml({ functionName: queueName, handlerPath: `${handlerRoot}/${functionName}_HdrSqs.main`, roleName: customFlowRoleName(flow.flowTag), queueName, flowTag, flowStepName: step.stepName })]
306
+ functions: [
307
+ renderSqsFunctionYaml({
308
+ functionName: queueName,
309
+ handlerPath: `${handlerRoot}/${functionName}_HdrSqs.main`,
310
+ roleName: customFlowRoleName(flow.flowTag),
311
+ queueName,
312
+ flowTag,
313
+ flowStepName: step.stepName
314
+ })
315
+ ]
142
316
  };
143
317
  }
144
318
 
145
- const artifacts = [{ path: `${source}/${mainFileName}.js`, content: await renderStepMain(functionName) }];
319
+ const artifacts = [
320
+ {
321
+ path: `${source}/${mainFileName}.js`,
322
+ content: await renderStepMain(functionName)
323
+ }
324
+ ];
146
325
  const functions = [];
147
326
 
148
- const stepEvents = Array.isArray(step.event) ? step.event : [];
327
+ let stepEvents = [];
328
+ if (Array.isArray(step.event)) {
329
+ stepEvents = step.event;
330
+ }
149
331
  const hasSqs = stepEvents.includes('extTopic') || stepEvents.includes('sqs');
150
332
 
151
333
  if (hasSqs) {
152
334
  const queueName = `${functionName}HdrSqs`;
153
- artifacts.push({ path: `${source}/${functionName}_HdrSqs.js`, content: await render('FlowHandler_HdrSqs.ejs', { flowTag: flow.flowTag, flowStepName: step.stepName, functionName, mainFileName, startConfig, queueName }) });
154
- functions.push(renderSqsFunctionYaml({ functionName: queueName, handlerPath: `${handlerRoot}/${functionName}_HdrSqs.main`, roleName: customFlowRoleName(flow.flowTag), queueName, flowTag, flowStepName: step.stepName }));
335
+ artifacts.push({
336
+ path: `${source}/${functionName}_HdrSqs.js`,
337
+ content: await render('FlowHandler_HdrSqs.ejs', {
338
+ flowTag: flow.flowTag,
339
+ flowStepName: step.stepName,
340
+ functionName,
341
+ mainFileName,
342
+ startConfig,
343
+ queueName
344
+ })
345
+ });
346
+ functions.push(
347
+ renderSqsFunctionYaml({
348
+ functionName: queueName,
349
+ handlerPath: `${handlerRoot}/${functionName}_HdrSqs.main`,
350
+ roleName: customFlowRoleName(flow.flowTag),
351
+ queueName,
352
+ flowTag,
353
+ flowStepName: step.stepName
354
+ })
355
+ );
155
356
  }
156
357
 
157
358
  return { artifacts, functions };
@@ -164,16 +365,44 @@ async function emitDsqStep({ flow, step, flowTag, stepName }) {
164
365
  const mainFileName = `${functionName}_Main`;
165
366
  const startConfig = stepConfig(flow, step);
166
367
 
167
- const stepEvents = Array.isArray(step.event) ? step.event : [];
168
- const artifacts = stepEvents.includes('extTopic') ? [] : [{ path: `${source}/${mainFileName}.js`, content: await renderStepMain(functionName) }];
368
+ let stepEvents = [];
369
+ if (Array.isArray(step.event)) {
370
+ stepEvents = step.event;
371
+ }
372
+ const artifacts = [];
373
+ if (!stepEvents.includes('extTopic')) {
374
+ artifacts.push({
375
+ path: `${source}/${mainFileName}.js`,
376
+ content: await renderStepMain(functionName)
377
+ });
378
+ }
169
379
  const functions = [];
170
380
 
171
381
  const hasDsq = stepEvents.includes('dsq');
172
382
 
173
383
  if (hasDsq) {
174
384
  const queueName = `${functionName}HdrDsq`;
175
- artifacts.push({ path: `${source}/${functionName}_HdrDsq.js`, content: await renderDsq('FlowHandler_HdrDsq.ejs', { flowTag: flow.flowTag, flowStepName: step.stepName, functionName, mainFileName, startConfig, queueName }) });
176
- functions.push(renderSqsFunctionYaml({ functionName: queueName, handlerPath: `${handlerRoot}/${functionName}_HdrDsq.main`, roleName: customFlowRoleName(flow.flowTag), queueName, flowTag, flowStepName: step.stepName }));
385
+ artifacts.push({
386
+ path: `${source}/${functionName}_HdrDsq.js`,
387
+ content: await renderDsq('FlowHandler_HdrDsq.ejs', {
388
+ flowTag: flow.flowTag,
389
+ flowStepName: step.stepName,
390
+ functionName,
391
+ mainFileName,
392
+ startConfig,
393
+ queueName
394
+ })
395
+ });
396
+ functions.push(
397
+ renderSqsFunctionYaml({
398
+ functionName: queueName,
399
+ handlerPath: `${handlerRoot}/${functionName}_HdrDsq.main`,
400
+ roleName: customFlowRoleName(flow.flowTag),
401
+ queueName,
402
+ flowTag,
403
+ flowStepName: step.stepName
404
+ })
405
+ );
177
406
  }
178
407
 
179
408
  return { artifacts, functions };
@@ -185,17 +414,61 @@ async function emitOwnTopicRoot(flow, objects) {
185
414
  const handlerRoot = `src/generatedCode/FlowSchemas/${tag}/source`;
186
415
  const mainFileName = `${tag}_Main`;
187
416
  const wbsMainFileName = `${tag}_WbsMain`;
188
- const shared = { flowTag: flow.flowTag, flowStepName: '', upperCaseFlowTag: tag, startConfig: startConfig(flow) };
417
+ const shared = {
418
+ flowTag: flow.flowTag,
419
+ flowStepName: '',
420
+ upperCaseFlowTag: tag,
421
+ startConfig: startConfig(flow)
422
+ };
189
423
  return {
190
424
  artifacts: [
191
- { path: `${source}/${mainFileName}.js`, content: await renderEndpointMain(flow, mainFileName, objects) },
192
- { path: `${source}/${tag}_HdrSqs.js`, content: await render('FlowHandler_HdrSqs.ejs', { ...shared, functionName: mainFileName, mainFileName, queueName: `${tag}HdrSqs` }) },
193
- { path: `${source}/${wbsMainFileName}.js`, content: await render('FlowMain_Wbs.ejs', { ...shared, functionName: wbsMainFileName }) },
194
- { path: `${source}/${tag}_HdrWbs.js`, content: await render('FlowEndpoint_HdrWbs.ejs', { ...shared, functionName: tag, mainFileName: wbsMainFileName, route: tag }) }
425
+ {
426
+ path: `${source}/${mainFileName}.js`,
427
+ content: await renderEndpointMain(flow, mainFileName, objects)
428
+ },
429
+ {
430
+ path: `${source}/${tag}_HdrSqs.js`,
431
+ content: await render('FlowHandler_HdrSqs.ejs', {
432
+ ...shared,
433
+ functionName: mainFileName,
434
+ mainFileName,
435
+ queueName: `${tag}HdrSqs`
436
+ })
437
+ },
438
+ {
439
+ path: `${source}/${wbsMainFileName}.js`,
440
+ content: await render('FlowMain_Wbs.ejs', {
441
+ ...shared,
442
+ functionName: wbsMainFileName
443
+ })
444
+ },
445
+ {
446
+ path: `${source}/${tag}_HdrWbs.js`,
447
+ content: await render('FlowEndpoint_HdrWbs.ejs', {
448
+ ...shared,
449
+ functionName: tag,
450
+ mainFileName: wbsMainFileName,
451
+ route: tag
452
+ })
453
+ }
195
454
  ],
196
455
  functions: [
197
- renderWbsFunctionYaml({ functionName: `${tag}HdrWbs`, handlerPath: `${handlerRoot}/${tag}_HdrWbs.main`, roleName: customFlowRoleName(flow.flowTag), routeName: tag, flowTag: flow.flowTag, flowStepName: '' }),
198
- renderSqsFunctionYaml({ functionName: `${tag}HdrSqs`, handlerPath: `${handlerRoot}/${tag}_HdrSqs.main`, roleName: customFlowRoleName(flow.flowTag), queueName: `${tag}HdrSqs`, flowTag: flow.flowTag, flowStepName: '' })
456
+ renderWbsFunctionYaml({
457
+ functionName: `${tag}HdrWbs`,
458
+ handlerPath: `${handlerRoot}/${tag}_HdrWbs.main`,
459
+ roleName: customFlowRoleName(flow.flowTag),
460
+ routeName: tag,
461
+ flowTag: flow.flowTag,
462
+ flowStepName: ''
463
+ }),
464
+ renderSqsFunctionYaml({
465
+ functionName: `${tag}HdrSqs`,
466
+ handlerPath: `${handlerRoot}/${tag}_HdrSqs.main`,
467
+ roleName: customFlowRoleName(flow.flowTag),
468
+ queueName: `${tag}HdrSqs`,
469
+ flowTag: flow.flowTag,
470
+ flowStepName: ''
471
+ })
199
472
  ]
200
473
  };
201
474
  }
@@ -203,77 +476,187 @@ async function emitOwnTopicRoot(flow, objects) {
203
476
  function ownTopicRootPaths(flow) {
204
477
  const tag = upperFirst(flow.flowTag);
205
478
  const source = `app/src/generatedCode/FlowSchemas/${tag}/source`;
206
- return [`${source}/${tag}_Main.js`, `${source}/${tag}_HdrSqs.js`, `${source}/${tag}_WbsMain.js`, `${source}/${tag}_HdrWbs.js`];
479
+ return [
480
+ `${source}/${tag}_Main.js`,
481
+ `${source}/${tag}_HdrSqs.js`,
482
+ `${source}/${tag}_WbsMain.js`,
483
+ `${source}/${tag}_HdrWbs.js`
484
+ ];
207
485
  }
208
486
 
209
487
  function needsProcessMain(flow) {
210
- return !isS3Only(flow) && !flow.event.includes('ownTopic') && flow.event.some(event => event !== 'ownTopic' && event !== 's3');
488
+ return (
489
+ !isS3Only(flow) &&
490
+ !flow.event.includes('ownTopic') &&
491
+ flow.event.some((event) => event !== 'ownTopic' && event !== 's3')
492
+ );
211
493
  }
212
494
 
213
495
  async function emitS3Flow(flow, source, handlerRoot) {
214
496
  const tag = upperFirst(flow.flowTag);
215
497
  const roleName = customFlowRoleName(flow.flowTag);
216
498
  const parts = [
217
- { action: 'CreateObject', handler: 'HdrWbs', type: 'wbs', mainTemplate: 'CreateObject_Main.ejs', handlerTemplate: 'CreateObject_HdrWbs.ejs' },
218
- { action: 'ReservedLimit', handler: 'HdrSqs', type: 'sqs', mainTemplate: 'ReservedLimit_Main.ejs', handlerTemplate: 'ReservedLimit_HdrSqs.ejs' },
219
- { action: 'CreatePreSignUrl', handler: 'HdrSqs', type: 'sqs', mainTemplate: 'CreatePreSignUrl_Main.ejs', handlerTemplate: 'CreatePreSignUrl_HdrSqs.ejs' },
220
- { action: 'ProcessAfterUpload', handler: 'HdrS3', type: 's3', mainTemplate: 'ProcessS3File_Main.ejs', handlerTemplate: 'FlowHandler_HdrS3.ejs' },
221
- { action: 'ConfirmAfterUpload', handler: 'HdrSqs', type: 'sqs', mainTemplate: 'ConfirmReserved_Main.ejs', handlerTemplate: 'ConfirmReserved_HdrSqs.ejs' }
499
+ {
500
+ action: 'CreateObject',
501
+ handler: 'HdrWbs',
502
+ type: 'wbs',
503
+ mainTemplate: 'CreateObject_Main.ejs',
504
+ handlerTemplate: 'CreateObject_HdrWbs.ejs'
505
+ },
506
+ {
507
+ action: 'ReservedLimit',
508
+ handler: 'HdrSqs',
509
+ type: 'sqs',
510
+ mainTemplate: 'ReservedLimit_Main.ejs',
511
+ handlerTemplate: 'ReservedLimit_HdrSqs.ejs'
512
+ },
513
+ {
514
+ action: 'CreatePreSignUrl',
515
+ handler: 'HdrSqs',
516
+ type: 'sqs',
517
+ mainTemplate: 'CreatePreSignUrl_Main.ejs',
518
+ handlerTemplate: 'CreatePreSignUrl_HdrSqs.ejs'
519
+ },
520
+ {
521
+ action: 'ProcessAfterUpload',
522
+ handler: 'HdrS3',
523
+ type: 's3',
524
+ mainTemplate: 'ProcessS3File_Main.ejs',
525
+ handlerTemplate: 'FlowHandler_HdrS3.ejs'
526
+ },
527
+ {
528
+ action: 'ConfirmAfterUpload',
529
+ handler: 'HdrSqs',
530
+ type: 'sqs',
531
+ mainTemplate: 'ConfirmReserved_Main.ejs',
532
+ handlerTemplate: 'ConfirmReserved_HdrSqs.ejs'
533
+ }
222
534
  ];
223
- const emitted = await Promise.all(parts.map(async ({ action, handler, type, mainTemplate, handlerTemplate }) => {
224
- const functionName = `${tag}${action}`;
225
- const mainFileName = `${functionName}_Main`;
226
- const handlerFileName = `${functionName}_${handler}`;
227
- const mainContent = await renderCustom(`s3/${mainTemplate}`, s3TemplateData({ action, flow, functionName }));
228
- const handlerContent = await renderCustom(`s3/${handlerTemplate}`, s3HandlerData({ action, flow, functionName, mainFileName, handler }));
229
- const descriptor = { functionName: `${functionName}${handler}`, handlerPath: `${handlerRoot}/${handlerFileName}.main`, roleName };
230
- const functionYaml = type === 'wbs'
231
- ? renderWbsFunctionYaml({ ...descriptor, routeName: tag, flowTag: flow.flowTag, flowStepName: '' })
232
- : type === 'sqs'
233
- ? renderSqsFunctionYaml({ ...descriptor, queueName: descriptor.functionName, flowTag: flow.flowTag, flowStepName: '' })
234
- : type === 's3'
235
- ? renderS3FunctionYaml({ ...descriptor, bucketName: flow.bucketName ?? '', flowTag: flow.flowTag, flowStepName: '' })
236
- : renderInvFunctionYaml({ ...descriptor, flowTag: flow.flowTag, flowStepName: '' });
237
- return {
238
- artifacts: [
239
- { path: `${source}/${mainFileName}.js`, content: mainContent },
240
- { path: `${source}/${handlerFileName}.js`, content: handlerContent }
241
- ],
242
- functionYaml
243
- };
244
- }));
245
- return { artifacts: emitted.flatMap(item => item.artifacts), functions: emitted.map(item => item.functionYaml) };
535
+ const emitted = await Promise.all(
536
+ parts.map(
537
+ async ({ action, handler, type, mainTemplate, handlerTemplate }) => {
538
+ const functionName = `${tag}${action}`;
539
+ const mainFileName = `${functionName}_Main`;
540
+ const handlerFileName = `${functionName}_${handler}`;
541
+ const mainContent = await renderCustom(
542
+ `s3/${mainTemplate}`,
543
+ _s3TemplateData({ action, flow, functionName })
544
+ );
545
+ const handlerContent = await renderCustom(
546
+ `s3/${handlerTemplate}`,
547
+ _s3HandlerData({ action, flow, functionName, mainFileName, handler })
548
+ );
549
+ const descriptor = {
550
+ functionName: `${functionName}${handler}`,
551
+ handlerPath: `${handlerRoot}/${handlerFileName}.main`,
552
+ roleName
553
+ };
554
+ let functionYaml;
555
+ if (type === 'wbs') {
556
+ functionYaml = renderWbsFunctionYaml({
557
+ ...descriptor,
558
+ routeName: tag,
559
+ flowTag: flow.flowTag,
560
+ flowStepName: ''
561
+ });
562
+ } else if (type === 'sqs') {
563
+ functionYaml = renderSqsFunctionYaml({
564
+ ...descriptor,
565
+ queueName: descriptor.functionName,
566
+ flowTag: flow.flowTag,
567
+ flowStepName: ''
568
+ });
569
+ } else if (type === 's3') {
570
+ let bucketName = '';
571
+ if (flow.bucketName) {
572
+ bucketName = flow.bucketName;
573
+ }
574
+ functionYaml = renderS3FunctionYaml({
575
+ ...descriptor,
576
+ bucketName,
577
+ flowTag: flow.flowTag,
578
+ flowStepName: ''
579
+ });
580
+ } else {
581
+ functionYaml = renderInvFunctionYaml({
582
+ ...descriptor,
583
+ flowTag: flow.flowTag,
584
+ flowStepName: ''
585
+ });
586
+ }
587
+ return {
588
+ artifacts: [
589
+ { path: `${source}/${mainFileName}.js`, content: mainContent },
590
+ { path: `${source}/${handlerFileName}.js`, content: handlerContent }
591
+ ],
592
+ functionYaml
593
+ };
594
+ }
595
+ )
596
+ );
597
+ return {
598
+ artifacts: emitted.flatMap((item) => item.artifacts),
599
+ functions: emitted.map((item) => item.functionYaml)
600
+ };
246
601
  }
247
602
 
248
- function s3TemplateData({ action, flow, functionName }) {
249
- return action === 'CreateObject'
250
- ? { flowTag: flow.flowTag, objectType: flow.objType?.objectType, functionName }
251
- : action === 'CreatePreSignUrl'
252
- ? { flowTag: flow.flowTag }
253
- : { flowTag: flow.flowTag, functionName };
603
+ function _s3TemplateData({ action, flow, functionName }) {
604
+ if (action === 'CreateObject') {
605
+ return {
606
+ flowTag: flow.flowTag,
607
+ objectType: flow.objType?.objectType,
608
+ functionName
609
+ };
610
+ }
611
+ if (action === 'CreatePreSignUrl') {
612
+ return { flowTag: flow.flowTag };
613
+ }
614
+ return { flowTag: flow.flowTag, functionName };
254
615
  }
255
616
 
256
- function s3HandlerData({ action, flow, functionName, mainFileName, handler }) {
257
- if (action === 'CreateObject') return { functionName, handlerType: handler, route: flow.flowTag };
258
- if (action === 'ProcessAfterUpload') return { flowTag: flow.flowTag, functionName, mainFileName, s3Bucket: flow.bucketName ?? '' };
617
+ function _s3HandlerData({ action, flow, functionName, mainFileName, handler }) {
618
+ if (action === 'CreateObject') {
619
+ return { functionName, handlerType: handler, route: flow.flowTag };
620
+ }
621
+ if (action === 'ProcessAfterUpload') {
622
+ let bucketName = '';
623
+ if (flow.bucketName) {
624
+ bucketName = flow.bucketName;
625
+ }
626
+ return {
627
+ flowTag: flow.flowTag,
628
+ functionName,
629
+ mainFileName,
630
+ s3Bucket: bucketName
631
+ };
632
+ }
259
633
  return { functionName, handlerType: handler };
260
634
  }
261
635
 
262
636
  function startConfig(flow) {
263
637
  const start = flow.flowSteps?.[0];
264
- return start ? stepConfig(flow, start) : null;
638
+ if (start) {
639
+ return stepConfig(flow, start);
640
+ }
641
+ return null;
265
642
  }
266
643
 
267
644
  function stepConfig(flow, step) {
268
645
  return {
269
646
  ...step,
270
647
  properties: mapFields(step.properties, flow.stepProperties),
271
- messageAttributes: mapFields(step.messageAttributes, flow.stepMessageAttributes)
648
+ messageAttributes: mapFields(
649
+ step.messageAttributes,
650
+ flow.stepMessageAttributes
651
+ )
272
652
  };
273
653
  }
274
654
 
275
655
  function mapFields(names = [], definitions = {}) {
276
- return names.map(name => ({ propertyName: name, ...(definitions?.[name] ?? {}) }));
656
+ return names.map((name) => ({
657
+ propertyName: name,
658
+ ...(definitions?.[name] ?? {})
659
+ }));
277
660
  }
278
661
 
279
662
  function isS3Only(flow) {
@@ -292,11 +675,19 @@ async function renderEndpointMain(flow, functionName, objects) {
292
675
 
293
676
  function storedCacheTableName(flow, objects) {
294
677
  if (flow.statusType !== 'storedCache') return null;
295
- const candidates = objects.filter(object => object.objectType === flow.objType?.objectType);
678
+ const candidates = objects.filter(
679
+ (object) => object.objectType === flow.objType?.objectType
680
+ );
296
681
  const object = flow.objType?.serviceTag
297
- ? candidates.find(object => object.serviceTag === flow.objType.serviceTag) ?? candidates.find(object => object.serviceTag === undefined)
682
+ ? (candidates.find(
683
+ (object) => object.serviceTag === flow.objType.serviceTag
684
+ ) ?? candidates.find((object) => object.serviceTag === undefined))
298
685
  : candidates[0];
299
- return Object.values(object?.storageResources ?? {}).find(resource => resource?.storageType === 'dynamoDB')?.tableName ?? null;
686
+ return (
687
+ Object.values(object?.storageResources ?? {}).find(
688
+ (resource) => resource?.storageType === 'dynamoDB'
689
+ )?.tableName ?? null
690
+ );
300
691
  }
301
692
 
302
693
  async function renderStepMain(functionName) {
@@ -308,13 +699,24 @@ function renderMain(functionName) {
308
699
  }
309
700
 
310
701
  async function render(templateName, data) {
311
- return ejs.render(await readFile(new URL(templateName, TEMPLATE_URL), 'utf8'), data);
702
+ return ejsLib.render(
703
+ await readFile(new URL(templateName, TEMPLATE_URL), 'utf8'),
704
+ data
705
+ );
312
706
  }
313
707
 
314
708
  async function renderDsq(templateName, data) {
315
- return ejs.render(await readFile(new URL(templateName, DSQ_TEMPLATE_URL), 'utf8'), data);
709
+ return ejsLib.render(
710
+ await readFile(new URL(templateName, DSQ_TEMPLATE_URL), 'utf8'),
711
+ data
712
+ );
316
713
  }
317
714
 
318
715
  async function renderCustom(templateName, data) {
319
- return ejs.render(await readFile(new URL(templateName, CUSTOM_TEMPLATE_URL), 'utf8'), data).replace(/\n$/, '');
716
+ return ejsLib
717
+ .render(
718
+ await readFile(new URL(templateName, CUSTOM_TEMPLATE_URL), 'utf8'),
719
+ data
720
+ )
721
+ .replace(/\n$/, '');
320
722
  }