@izara_project/izara-core-generate-service-code 1.0.55 → 1.0.57

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 (48) hide show
  1. package/package.json +1 -1
  2. package/src/codeGenerators/app/initial_setup/InitialSetupGenerator.js +223 -123
  3. package/src/codeGenerators/app/initial_setup/templates/InitialSetup_LambdaRole.ejs +6 -6
  4. package/src/codeGenerators/app/sls_yaml/FindDataYamlGenerator.js +1 -1
  5. package/src/codeGenerators/app/sls_yaml/FunctionYamlGenerator.js +299 -197
  6. package/src/codeGenerators/app/sls_yaml/RoleNameConfigGenerator.js +84 -60
  7. package/src/codeGenerators/app/sls_yaml/SharedResourceYamlGenerator.js +304 -271
  8. package/src/codeGenerators/app/sls_yaml/__tests__/SharedResourceYamlGenerator.test.js +91 -32
  9. package/src/codeGenerators/app/sls_yaml/templates/SharedResource_Yaml.ejs +2 -2
  10. package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/EndpointsGenerator.js +1 -1
  11. package/src/codeGenerators/app/src/generatedCode/Flow/FlowRbac/templates/rbac/FlowRbac_Main.ejs +252 -0
  12. package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/RelationshipFlowGenerator.js +19 -3
  13. package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessCreateRelationship_Main.ejs +1 -1
  14. package/src/codeGenerators/app/src/generatedCode/Flow/FlowSchemas/WebSocketGenerator.js +4 -4
  15. package/src/codeGenerators/app/src/generatedCode/Flow/_shared/shared/flowClassifier.js +3 -2
  16. package/src/codeGenerators/app/src/generatedCode/Flow/_shared/shared/flowMainFunctionBase.js +12 -5
  17. package/src/codeGenerators/app/src/generatedCode/Flow/_shared/shared/flowValidator.js +1 -1
  18. package/src/codeGenerators/app/src/generatedCode/libs/templates/Consts.ejs +23 -23
  19. package/src/codeGenerators/resource/sls_yaml/DynamoDBGenerator.js +1 -1
  20. package/src/codeGenerators/resource/sls_yaml/FlowOutGenerator.js +3 -6
  21. package/src/codeGenerators/resource/sls_yaml/FlowResourceYamlGenerator.js +29 -10
  22. package/src/codeGenerators/resource/sls_yaml/templates/SystemDynamoDB_Yaml.ejs +64 -0
  23. package/src/generate.js +1 -1
  24. package/src/generateCode.js +14 -11
  25. package/src/generateSchema.js +1 -1
  26. package/src/schemaGenerators/app/src/schemas/FlowSchemas/FlowSchemaGenerator.js +0 -1
  27. package/src/schemaGenerators/app/src/schemas/FlowSchemas/RbacFlowSchemaGenerator.js +16 -2
  28. package/src/schemaGenerators/app/src/schemas/FlowSchemas/RelationshipFlowSchemaGenerator.js +2 -2
  29. package/src/schemaGenerators/app/src/schemas/FlowSchemas/templates/DynamicFlowSchemaTemplate.ejs +12 -12
  30. package/src/schemaGenerators/app/src/schemas/FlowSchemas/templates/DynamicRbacFlowSchemaTemplate.ejs +1 -0
  31. package/src/schemaGenerators/app/src/schemas/FlowSchemas/templates/UserRbacFlowSchemaTemplate.ejs +22 -0
  32. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/.gitkeep +0 -0
  33. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/templates/FlowEndpointBeforeLogical_Main.ejs +0 -0
  34. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/templates/crud/CreateEndpoint_Main.ejs +0 -0
  35. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/templates/crud/DeleteEndpoint_Main.ejs +0 -0
  36. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/templates/crud/GetEndpoint_Main.ejs +0 -0
  37. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/templates/crud/UpdateEndpoint_Main.ejs +0 -0
  38. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessChangeRelationshipComplete_Main.ejs +0 -0
  39. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessChangeRelationship_Main.ejs +0 -0
  40. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessCreateRelationshipComplete_Main.ejs +0 -0
  41. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessDeleteRelationshipComplete_Main.ejs +0 -0
  42. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessDeleteRelationship_Main.ejs +0 -0
  43. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessGetRelationshipComplete_Main.ejs +0 -0
  44. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessGetRelationship_Main.ejs +0 -0
  45. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessMoveRelationshipComplete_Main.ejs +0 -0
  46. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessMoveRelationship_Main.ejs +0 -0
  47. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessUpdateRelationshipComplete_Main.ejs +0 -0
  48. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessUpdateRelationship_Main.ejs +0 -0
@@ -3,228 +3,330 @@ import path from 'path';
3
3
  import ejs from 'ejs';
4
4
  import { fileURLToPath } from 'url';
5
5
  import { getFlowsForGeneration } from '../src/generatedCode/Flow/_shared/shared/flowSelection.js';
6
+ import { isRbacFlow } from '../src/generatedCode/Flow/_shared/shared/flowClassifier.js';
6
7
 
7
8
  const __filename = fileURLToPath(import.meta.url);
8
9
  const __dirname = path.dirname(__filename);
9
10
 
10
11
  export async function generateFunctionYaml(allSchemas, options) {
11
- console.log(' [FunctionYamlGenerator] Generating Function YAMLs...');
12
-
13
- const slsYamlDir = path.join(options.outputPath, 'app', 'sls_yaml', 'generatedCode', 'source');
14
- await fs.mkdir(slsYamlDir, { recursive: true });
15
-
16
- const templates = {
17
- sqs: await fs.readFile(path.join(__dirname, 'templates', 'FunctionYaml_Sqs.ejs'), 'utf-8'),
18
- inv: await fs.readFile(path.join(__dirname, 'templates', 'FunctionYaml_Inv.ejs'), 'utf-8'),
19
- api: await fs.readFile(path.join(__dirname, 'templates', 'FunctionYaml_Api.ejs'), 'utf-8'),
20
- wbs: await fs.readFile(path.join(__dirname, 'templates', 'FunctionYaml_Wbs.ejs'), 'utf-8'),
21
- eventBridge: await fs.readFile(path.join(__dirname, 'templates', 'FunctionYaml_EventBridge.ejs'), 'utf-8')
22
- };
23
- const flows = getFlowsForGeneration(allSchemas);
24
-
25
- const CRUD_FLOW_TAGS = ['Create', 'Update', 'Delete', 'Get'];
26
- const REL_FLOW_TAGS = [
27
- 'createRelationship', 'updateRelationship', 'deleteRelationship',
28
- 'getRelationship', 'changeRelationship', 'moveRelationship'
29
- ];
30
-
31
- let perActionYaml = '';
32
- let relActionYaml = '';
33
- let flowSchemaYaml = '';
34
-
35
- const upperCase = (str) => str.charAt(0).toUpperCase() + str.slice(1);
36
-
37
- // 1. Find all generated Handlers
38
- const generatedCodeDir = path.join(options.outputPath, 'app', 'src', 'generatedCode');
39
- const handlerFiles = [];
40
- async function getHandlerFiles(dir) {
41
- try {
42
- const dirents = await fs.readdir(dir, { withFileTypes: true });
43
- for (const dirent of dirents) {
44
- const res = path.resolve(dir, dirent.name);
45
- if (dirent.isDirectory()) {
46
- await getHandlerFiles(res);
47
- } else if (dirent.name.includes('_Hdr') && dirent.name.endsWith('.js')) {
48
- // Extract relative path from generatedCodeDir
49
- const relativePath = path.relative(generatedCodeDir, res);
50
- // normalize to forward slashes
51
- handlerFiles.push(relativePath.replace(/\\/g, '/'));
52
- }
53
- }
54
- } catch (e) {
55
- // directory might not exist if no flows generated
12
+ console.log(' [FunctionYamlGenerator] Generating Function YAMLs...');
13
+
14
+ const slsYamlDir = path.join(
15
+ options.outputPath,
16
+ 'app',
17
+ 'sls_yaml',
18
+ 'generatedCode',
19
+ 'source'
20
+ );
21
+ await fs.mkdir(slsYamlDir, { recursive: true });
22
+
23
+ const templates = {
24
+ sqs: await fs.readFile(
25
+ path.join(__dirname, 'templates', 'FunctionYaml_Sqs.ejs'),
26
+ 'utf-8'
27
+ ),
28
+ inv: await fs.readFile(
29
+ path.join(__dirname, 'templates', 'FunctionYaml_Inv.ejs'),
30
+ 'utf-8'
31
+ ),
32
+ api: await fs.readFile(
33
+ path.join(__dirname, 'templates', 'FunctionYaml_Api.ejs'),
34
+ 'utf-8'
35
+ ),
36
+ wbs: await fs.readFile(
37
+ path.join(__dirname, 'templates', 'FunctionYaml_Wbs.ejs'),
38
+ 'utf-8'
39
+ ),
40
+ eventBridge: await fs.readFile(
41
+ path.join(__dirname, 'templates', 'FunctionYaml_EventBridge.ejs'),
42
+ 'utf-8'
43
+ )
44
+ };
45
+ const flows = getFlowsForGeneration(allSchemas);
46
+
47
+ const CRUD_FLOW_TAGS = ['Create', 'Update', 'Delete', 'Get'];
48
+ const REL_FLOW_TAGS = [
49
+ 'createRelationship',
50
+ 'updateRelationship',
51
+ 'deleteRelationship',
52
+ 'getRelationship',
53
+ 'changeRelationship',
54
+ 'moveRelationship'
55
+ ];
56
+
57
+ let perActionYaml = '';
58
+ let relActionYaml = '';
59
+ let rbacYaml = '';
60
+ let flowSchemaYaml = '';
61
+ const customYmls = {};
62
+
63
+ const upperCase = str => str.charAt(0).toUpperCase() + str.slice(1);
64
+
65
+ // 1. Find all generated Handlers
66
+ const generatedCodeDir = path.join(
67
+ options.outputPath,
68
+ 'app',
69
+ 'src',
70
+ 'generatedCode'
71
+ );
72
+ const handlerFiles = [];
73
+ async function getHandlerFiles(dir) {
74
+ try {
75
+ const dirents = await fs.readdir(dir, { withFileTypes: true });
76
+ for (const dirent of dirents) {
77
+ const res = path.resolve(dir, dirent.name);
78
+ if (dirent.isDirectory()) {
79
+ await getHandlerFiles(res);
80
+ } else if (
81
+ dirent.name.includes('_Hdr') &&
82
+ dirent.name.endsWith('.js')
83
+ ) {
84
+ // Extract relative path from generatedCodeDir
85
+ const relativePath = path.relative(generatedCodeDir, res);
86
+ // normalize to forward slashes
87
+ handlerFiles.push(relativePath.replace(/\\/g, '/'));
56
88
  }
89
+ }
90
+ } catch (e) {
91
+ // directory might not exist if no flows generated
57
92
  }
58
- await getHandlerFiles(generatedCodeDir);
59
-
60
- // Prepare API routes
61
- const crudApiRoutes = allSchemas.objects.map(obj => ({
62
- objectName: obj.objectType,
63
- upperName: upperCase(obj.objectType)
64
- }));
65
- const relApiRoutes = allSchemas.relationships.map(rel => {
66
- const relName = Object.keys(rel)[0];
67
- return {
68
- objectName: relName,
69
- upperName: upperCase(relName)
70
- };
71
- });
72
-
73
- for (const handlerFile of handlerFiles) {
74
- // e.g. "Endpoints/Create/source/ProcessCreate_HdrSqs.js"
75
- const parts = handlerFile.split('/');
76
- if (parts.length < 4) continue;
77
-
78
- const subDir = parts[0]; // e.g. FlowEndpoints, FlowSchemas, SystemFlowSchemas
79
- if (subDir === 'SystemFlowSchemas') continue;
80
-
81
- const flowTag = parts[1];
82
- const fileName = parts[3]; // e.g. ProcessCreate_HdrSqs.js
83
-
84
- const fileNameWithoutExt = fileName.replace('.js', '');
85
- // e.g. ProcessCreate_HdrSqs
86
- const splitFileName = fileNameWithoutExt.split('_');
87
- const handlerBaseName = splitFileName[0]; // e.g. ProcessCreate or CreateComplete
88
- const handlerSuffix = splitFileName[1]; // e.g. HdrSqs, HdrApi, HdrInv
89
-
90
- const isCrud = CRUD_FLOW_TAGS.map(t => t.toLowerCase()).includes(flowTag.toLowerCase());
91
- const isRel = REL_FLOW_TAGS.map(t => t.toLowerCase()).includes(flowTag.toLowerCase());
92
- const isCustom = !isCrud && !isRel;
93
-
94
- // Role mapping
95
- let roleName = '';
96
- if (isCrud) {
97
- roleName = 'PerActionEndpointRole';
98
- } else if (isRel) {
99
- roleName = 'RelationshipRole';
100
- } else {
101
- roleName = `${upperCase(flowTag)}Role`;
102
- }
93
+ }
94
+ await getHandlerFiles(generatedCodeDir);
103
95
 
104
- // Function Name Config
105
- // e.g. ProcessCreateSqs or CreateCompleteSqs or GetApi
106
- let suffixType = handlerSuffix.startsWith('Hdr') ? handlerSuffix : handlerSuffix.replace('Hdr', '');
107
- let functionNameConfig = `${handlerBaseName}${suffixType}`;
108
- if (isCrud && handlerBaseName === `Process${upperCase(flowTag)}`) {
109
- // Legacy matches: CreateSqs, GetApi instead of ProcessCreateSqs
110
- functionNameConfig = `${upperCase(flowTag)}${suffixType}`;
111
- }
112
- if (isRel && handlerBaseName === `Process${upperCase(flowTag)}`) {
113
- // Legacy matches: CreateRelSqs
114
- functionNameConfig = `${upperCase(flowTag).replace('Relationship', 'Rel')}${suffixType}`;
115
- }
116
- if (handlerBaseName.endsWith('Complete')) {
117
- // e.g. CreateObjectComp or CreateCompleteSqs
118
- if (isCrud) {
119
- // Legacy: DeleteNodeComp, UpdateNodeComp, CreateObjectComp
120
- const crudType = upperCase(flowTag);
121
- if (crudType === 'Create') functionNameConfig = `CreateObjectComp`;
122
- else functionNameConfig = `${crudType}NodeComp`;
123
- } else if (isRel) {
124
- // Legacy: UpdateRelComp
125
- functionNameConfig = `${upperCase(flowTag).replace('Relationship', 'Rel')}Comp`;
126
- } else {
127
- functionNameConfig = `${handlerBaseName}${suffixType}`;
128
- }
129
- }
96
+ // Prepare API routes
97
+ const crudApiRoutes = allSchemas.objects.map(obj => ({
98
+ objectName: obj.objectType,
99
+ upperName: upperCase(obj.objectType)
100
+ }));
101
+ const relApiRoutes = allSchemas.relationships.map(rel => {
102
+ const relName = Object.keys(rel)[0];
103
+ return {
104
+ objectName: relName,
105
+ upperName: upperCase(relName)
106
+ };
107
+ });
108
+
109
+ for (const handlerFile of handlerFiles) {
110
+ // e.g. "Endpoints/Create/source/ProcessCreate_HdrSqs.js"
111
+ const parts = handlerFile.split('/');
112
+ if (parts.length < 4) continue;
113
+
114
+ const subDir = parts[0]; // e.g. FlowObjects, FlowSchemas, SystemFlowSchemas
115
+ if (subDir === 'SystemFlowSchemas') continue;
116
+
117
+ const flowTag = parts[1];
118
+ const fileName = parts[3]; // e.g. ProcessCreate_HdrSqs.js
119
+
120
+ const fileNameWithoutExt = fileName.replace('.js', '');
121
+ // e.g. ProcessCreate_HdrSqs
122
+ const splitFileName = fileNameWithoutExt.split('_');
123
+ const handlerBaseName = splitFileName[0]; // e.g. ProcessCreate or CreateComplete
124
+ const handlerSuffix = splitFileName[1]; // e.g. HdrSqs, HdrApi, HdrInv
125
+
126
+ const isCrud = CRUD_FLOW_TAGS.map(t => t.toLowerCase()).includes(
127
+ flowTag.toLowerCase()
128
+ );
129
+ const isRel = REL_FLOW_TAGS.map(t => t.toLowerCase()).includes(
130
+ flowTag.toLowerCase()
131
+ );
132
+ const isRbac =
133
+ isRbacFlow(flowTag) ||
134
+ String(flowTag || '')
135
+ .toLowerCase()
136
+ .endsWith('rbacflow');
137
+ const isCustom = !isCrud && !isRel && !isRbac;
138
+
139
+ // Role mapping
140
+ let roleName = '';
141
+ if (isCrud) {
142
+ roleName = 'FlowObjectsRole';
143
+ } else if (isRbac) {
144
+ roleName = 'FlowRbacRole';
145
+ } else if (isRel) {
146
+ roleName = 'FlowRelationshipRole';
147
+ } else {
148
+ roleName = `${upperCase(flowTag)}Role`;
149
+ }
150
+
151
+ // Function Name Config
152
+ // e.g. ProcessCreateSqs or CreateCompleteSqs or GetApi
153
+ let suffixType = handlerSuffix.startsWith('Hdr')
154
+ ? handlerSuffix
155
+ : handlerSuffix.replace('Hdr', '');
156
+ let functionNameConfig = `${handlerBaseName}${suffixType}`;
157
+ if (isCrud && handlerBaseName === `Process${upperCase(flowTag)}`) {
158
+ // Legacy matches: CreateSqs, GetApi instead of ProcessCreateSqs
159
+ functionNameConfig = `${upperCase(flowTag)}${suffixType}`;
160
+ }
161
+ if (isRel && handlerBaseName === `Process${upperCase(flowTag)}`) {
162
+ // Legacy matches: CreateRelSqs
163
+ functionNameConfig = `${upperCase(flowTag).replace('Relationship', 'Rel')}${suffixType}`;
164
+ }
165
+ if (handlerBaseName.endsWith('Complete')) {
166
+ // e.g. CreateObjectComp or CreateCompleteSqs
167
+ if (isCrud) {
168
+ // Legacy: DeleteNodeComp, UpdateNodeComp, CreateObjectComp
169
+ const crudType = upperCase(flowTag);
170
+ if (crudType === 'Create') functionNameConfig = `CreateObjectComp`;
171
+ else functionNameConfig = `${crudType}NodeComp`;
172
+ } else if (isRel) {
173
+ // Legacy: UpdateRelComp
174
+ functionNameConfig = `${upperCase(flowTag).replace('Relationship', 'Rel')}Comp`;
175
+ } else {
176
+ functionNameConfig = `${handlerBaseName}${suffixType}`;
177
+ }
178
+ }
130
179
 
131
- let queueName = '';
132
- const flowDefForQueue = flows.find(f => f.flowTag === flowTag);
133
-
134
- if (isCrud || isRel) {
135
- queueName = handlerBaseName.replace('Process', '');
180
+ let queueName = '';
181
+ const flowDefForQueue = flows.find(f => f.flowTag === flowTag);
182
+
183
+ if (isCrud || isRel) {
184
+ queueName = handlerBaseName.replace('Process', '');
136
185
  if (handlerSuffix === 'HdrSqs' || handlerSuffix === 'HdrDsq') {
137
186
  queueName += handlerSuffix;
138
187
  }
188
+ } else {
189
+ // For Custom Flows (e.g. OwnTopicFlowProcess, ProcessExtTopicFlow)
190
+ // The queue name exactly matches the handler name without the underscore.
191
+ if (handlerSuffix === 'HdrSqs' || handlerSuffix === 'HdrDsq') {
192
+ if (
193
+ handlerBaseName === `Process${upperCase(flowTag)}` &&
194
+ flowDefForQueue &&
195
+ flowDefForQueue.event &&
196
+ flowDefForQueue.event.includes('ownTopic')
197
+ ) {
198
+ // ownTopic flows in FlowResourceYamlGenerator omit 'Process' for the queue
199
+ queueName = flowTag + handlerSuffix;
139
200
  } else {
140
- // For Custom Flows (e.g. OwnTopicFlowProcess, ProcessExtTopicFlow)
141
- // The queue name exactly matches the handler name without the underscore.
142
- if (handlerSuffix === 'HdrSqs' || handlerSuffix === 'HdrDsq') {
143
- if (handlerBaseName === `Process${upperCase(flowTag)}` && flowDefForQueue && flowDefForQueue.event && flowDefForQueue.event.includes('ownTopic')) {
144
- // ownTopic flows in FlowResourceYamlGenerator omit 'Process' for the queue
145
- queueName = flowTag + handlerSuffix;
201
+ queueName = handlerBaseName + handlerSuffix;
202
+ }
146
203
  } else {
147
- queueName = handlerBaseName + handlerSuffix;
204
+ queueName = handlerBaseName;
148
205
  }
149
- } else {
150
- queueName = handlerBaseName;
151
- }
152
- }
206
+ }
153
207
 
154
- // Api routes
155
- let apiRoutes = [];
156
- if (suffixType === 'HdrApi' || suffixType === 'Api') {
157
- const routesList = isCrud ? crudApiRoutes : (isRel ? relApiRoutes : []);
158
- const actionPath = flowTag.toLowerCase().replace('relationship', '');
159
- apiRoutes = routesList.map(r => ({
160
- path: `/TST/${r.objectName}/${actionPath}`,
161
- upperName: r.upperName
162
- }));
163
- }
208
+ // Api routes
209
+ let apiRoutes = [];
210
+ if (suffixType === 'HdrApi' || suffixType === 'Api') {
211
+ const routesList = isCrud ? crudApiRoutes : isRel ? relApiRoutes : [];
212
+ const actionPath = flowTag.toLowerCase().replace('relationship', '');
213
+ apiRoutes = routesList.map(r => ({
214
+ path: `/TST/${r.objectName}/${actionPath}`,
215
+ upperName: r.upperName
216
+ }));
217
+ }
164
218
 
165
- // Handler Path
166
- const handlerPath = `src/generatedCode/${subDir}/${flowTag}/source/${fileNameWithoutExt}.main`;
219
+ // Handler Path
220
+ const handlerPath = `src/generatedCode/${subDir}/${flowTag}/source/${fileNameWithoutExt}.main`;
167
221
 
168
- let filterPatterns = '';
169
- if (handlerBaseName.endsWith('Complete') && (suffixType === 'HdrSqs' || suffixType === 'HdrDsq' || suffixType === 'Sqs' || suffixType === 'Dsq')) {
170
- filterPatterns = ` filterPatterns: #**** need to update serverless framework upper v.2.69.1
222
+ let filterPatterns = '';
223
+ if (
224
+ handlerBaseName.endsWith('Complete') &&
225
+ (suffixType === 'HdrSqs' ||
226
+ suffixType === 'HdrDsq' ||
227
+ suffixType === 'Sqs' ||
228
+ suffixType === 'Dsq')
229
+ ) {
230
+ filterPatterns = ` filterPatterns: #**** need to update serverless framework upper v.2.69.1
171
231
  - body: {"MessageAttributes":{"callingFlow":{"Value":["\${self:custom.iz_resourcePrefix}${functionNameConfig}"]}}} # functionName of callingFlow
172
232
  - body: {"MessageAttributes":{"callingFlow":{"Value":[{"exists":false}]}}}`;
173
- }
233
+ }
174
234
 
175
- const flowDef = flows.find(f => f.flowTag === flowTag);
176
- let schedules = [];
177
- if (flowDef && flowDef.schedules) {
178
- schedules = flowDef.schedules;
179
- }
235
+ const flowDef = flows.find(f => f.flowTag === flowTag);
236
+ let schedules = [];
237
+ if (flowDef && flowDef.schedules) {
238
+ schedules = flowDef.schedules;
239
+ }
180
240
 
181
- const renderVars = {
182
- functionNameConfig,
183
- handlerPath,
184
- roleName,
185
- queueName,
186
- apiRoutes,
187
- filterPatterns,
188
- schedules,
189
- flowTag
190
- };
191
-
192
- let yamlBlock = '';
193
- if (schedules.length > 0 && (suffixType === 'HdrInv' || suffixType === 'Inv')) {
194
- yamlBlock = ejs.render(templates.eventBridge, renderVars);
195
- } else if (suffixType === 'HdrSqs' || suffixType === 'HdrDsq' || suffixType === 'Sqs' || suffixType === 'Dsq') {
196
- yamlBlock = ejs.render(templates.sqs, renderVars);
197
- } else if (suffixType === 'HdrInv' || suffixType === 'Inv') {
198
- yamlBlock = ejs.render(templates.inv, renderVars);
199
- } else if (suffixType === 'HdrApi' || suffixType === 'Api') {
200
- yamlBlock = ejs.render(templates.api, renderVars);
201
- } else if (suffixType === 'HdrWbs' || suffixType === 'Wbs') {
202
- renderVars.routeName = flowTag;
203
- yamlBlock = ejs.render(templates.wbs, renderVars);
204
- } else {
205
- // Fallback for others
206
- yamlBlock = ejs.render(templates.inv, renderVars); // Simple no-events template
207
- }
241
+ const renderVars = {
242
+ functionNameConfig,
243
+ handlerPath,
244
+ roleName,
245
+ queueName,
246
+ apiRoutes,
247
+ filterPatterns,
248
+ schedules,
249
+ flowTag
250
+ };
208
251
 
209
- if (isCrud) {
210
- perActionYaml += yamlBlock + '\n\n';
211
- } else if (isRel) {
212
- relActionYaml += yamlBlock + '\n\n';
213
- } else {
214
- flowSchemaYaml += yamlBlock + '\n\n';
215
- }
252
+ let yamlBlock = '';
253
+ if (
254
+ schedules.length > 0 &&
255
+ (suffixType === 'HdrInv' || suffixType === 'Inv')
256
+ ) {
257
+ yamlBlock = ejs.render(templates.eventBridge, renderVars);
258
+ } else if (
259
+ suffixType === 'HdrSqs' ||
260
+ suffixType === 'HdrDsq' ||
261
+ suffixType === 'Sqs' ||
262
+ suffixType === 'Dsq'
263
+ ) {
264
+ yamlBlock = ejs.render(templates.sqs, renderVars);
265
+ } else if (suffixType === 'HdrInv' || suffixType === 'Inv') {
266
+ yamlBlock = ejs.render(templates.inv, renderVars);
267
+ } else if (suffixType === 'HdrApi' || suffixType === 'Api') {
268
+ yamlBlock = ejs.render(templates.api, renderVars);
269
+ } else if (suffixType === 'HdrWbs' || suffixType === 'Wbs') {
270
+ renderVars.routeName = flowTag;
271
+ yamlBlock = ejs.render(templates.wbs, renderVars);
272
+ } else {
273
+ // Fallback for others
274
+ yamlBlock = ejs.render(templates.inv, renderVars); // Simple no-events template
216
275
  }
217
276
 
218
- if (perActionYaml) {
219
- await fs.writeFile(path.join(slsYamlDir, 'per-action-function.yml'), perActionYaml, 'utf-8');
220
- }
221
- if (relActionYaml) {
222
- await fs.writeFile(path.join(slsYamlDir, 'relationship-per-action.yml'), relActionYaml, 'utf-8');
223
- }
224
- if (flowSchemaYaml) {
225
- // Append to flow-schema.yml just in case WebSocket/TriggerCache already created it, or create new.
226
- await fs.appendFile(path.join(slsYamlDir, 'flow-schema.yml'), flowSchemaYaml, 'utf-8');
277
+ const customYamlFile =
278
+ flowDef && flowDef.fileName ? flowDef.fileName : null;
279
+
280
+ if (customYamlFile) {
281
+ if (!customYmls[customYamlFile]) customYmls[customYamlFile] = '';
282
+ customYmls[customYamlFile] += yamlBlock + '\n\n';
283
+ } else if (isCrud) {
284
+ perActionYaml += yamlBlock + '\n\n';
285
+ } else if (isRel) {
286
+ relActionYaml += yamlBlock + '\n\n';
287
+ } else if (isRbac) {
288
+ rbacYaml += yamlBlock + '\n\n';
289
+ } else {
290
+ flowSchemaYaml += yamlBlock + '\n\n';
227
291
  }
292
+ }
293
+
294
+ if (perActionYaml) {
295
+ await fs.writeFile(
296
+ path.join(slsYamlDir, 'flow-objects.yml'),
297
+ perActionYaml,
298
+ 'utf-8'
299
+ );
300
+ }
301
+ if (relActionYaml) {
302
+ await fs.writeFile(
303
+ path.join(slsYamlDir, 'flow-relationships.yml'),
304
+ relActionYaml,
305
+ 'utf-8'
306
+ );
307
+ }
308
+ if (rbacYaml) {
309
+ await fs.writeFile(
310
+ path.join(slsYamlDir, 'flow-rbac.yml'),
311
+ rbacYaml,
312
+ 'utf-8'
313
+ );
314
+ }
315
+ if (flowSchemaYaml) {
316
+ // Append to flow-schema.yml just in case WebSocket/TriggerCache already created it, or create new.
317
+ await fs.appendFile(
318
+ path.join(slsYamlDir, 'flow-schema.yml'),
319
+ flowSchemaYaml,
320
+ 'utf-8'
321
+ );
322
+ }
323
+
324
+ for (const [fName, content] of Object.entries(customYmls)) {
325
+ const fullFileName = fName.endsWith('.yml') ? fName : `${fName}.yml`;
326
+ await fs.writeFile(path.join(slsYamlDir, fullFileName), content, 'utf-8');
327
+ }
228
328
 
229
- console.log(` [FunctionYamlGenerator] Wrote YAML functions for CRUD, Relationships, and Custom Flows.`);
329
+ console.log(
330
+ ` [FunctionYamlGenerator] Wrote YAML functions for CRUD, Relationships, and Custom Flows.`
331
+ );
230
332
  }