@izara_project/izara-core-generate-service-code 1.0.54 → 1.0.56

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 (52) 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 +303 -201
  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 +1 -1
  13. package/src/codeGenerators/app/src/generatedCode/Flow/FlowSchemas/StatusFieldGenerator.js +1 -8
  14. package/src/codeGenerators/app/src/generatedCode/Flow/FlowSchemas/WebSocketGenerator.js +1 -7
  15. package/src/codeGenerators/app/src/generatedCode/Flow/_shared/events/BaseSqsHandler.js +3 -3
  16. package/src/codeGenerators/app/src/generatedCode/Flow/_shared/shared/flowClassifier.js +3 -2
  17. package/src/codeGenerators/app/src/generatedCode/Flow/_shared/shared/flowMainFunctionBase.js +12 -5
  18. package/src/codeGenerators/app/src/generatedCode/Flow/_shared/shared/triggerCacheBase.js +1 -7
  19. package/src/codeGenerators/app/src/generatedCode/SystemFlowSchemas/RegisterGenerator.js +1 -7
  20. package/src/codeGenerators/app/src/generatedCode/libs/templates/Consts.ejs +23 -23
  21. package/src/codeGenerators/resource/sls_yaml/DynamoDBGenerator.js +8 -8
  22. package/src/codeGenerators/resource/sls_yaml/FlowOutGenerator.js +57 -51
  23. package/src/codeGenerators/resource/sls_yaml/FlowResourceYamlGenerator.js +164 -175
  24. package/src/codeGenerators/resource/sls_yaml/templates/SystemDynamoDB_Yaml.ejs +64 -0
  25. package/src/codeGenerators/resource/sls_yaml/templates/crud/ResourceYaml.ejs +10 -10
  26. package/src/generate.js +1 -1
  27. package/src/generateCode.js +181 -149
  28. package/src/generateSchema.js +1 -1
  29. package/src/schemaGenerators/app/src/schemas/FlowSchemas/FlowSchemaGenerator.js +0 -1
  30. package/src/schemaGenerators/app/src/schemas/FlowSchemas/RbacFlowSchemaGenerator.js +16 -2
  31. package/src/schemaGenerators/app/src/schemas/FlowSchemas/templates/DynamicFlowSchemaTemplate.ejs +3 -1
  32. package/src/schemaGenerators/app/src/schemas/FlowSchemas/templates/DynamicRbacFlowSchemaTemplate.ejs +1 -0
  33. package/src/schemaGenerators/app/src/schemas/FlowSchemas/templates/RelationshipFlowSchemaTemplate.ejs +6 -5
  34. package/src/schemaGenerators/app/src/schemas/FlowSchemas/templates/UserRbacFlowSchemaTemplate.ejs +22 -0
  35. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/.gitkeep +0 -0
  36. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/templates/FlowEndpointBeforeLogical_Main.ejs +0 -0
  37. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/templates/crud/CreateEndpoint_Main.ejs +0 -0
  38. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/templates/crud/DeleteEndpoint_Main.ejs +0 -0
  39. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/templates/crud/GetEndpoint_Main.ejs +0 -0
  40. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowEndpoints → FlowObjects}/templates/crud/UpdateEndpoint_Main.ejs +0 -0
  41. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessChangeRelationshipComplete_Main.ejs +0 -0
  42. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessChangeRelationship_Main.ejs +0 -0
  43. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessCreateRelationshipComplete_Main.ejs +0 -0
  44. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessCreateRelationship_Main.ejs +0 -0
  45. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessDeleteRelationshipComplete_Main.ejs +0 -0
  46. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessDeleteRelationship_Main.ejs +0 -0
  47. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessGetRelationshipComplete_Main.ejs +0 -0
  48. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessGetRelationship_Main.ejs +0 -0
  49. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessMoveRelationshipComplete_Main.ejs +0 -0
  50. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessMoveRelationship_Main.ejs +0 -0
  51. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessUpdateRelationshipComplete_Main.ejs +0 -0
  52. /package/src/codeGenerators/app/src/generatedCode/Flow/{FlowRelationshipEndpoints → FlowRelationships}/templates/relationship/ProcessUpdateRelationship_Main.ejs +0 -0
@@ -166,12 +166,12 @@ const FUNCTION_NAME = {
166
166
  outTranslateIds: 'processTranslateIdsComplete',
167
167
  findData: 'findData',
168
168
  processLogical: 'processLogical',
169
- updateNodeComplete: 'updateNodeComplete',
170
- createObjectComplete: 'createObjectComplete',
171
- getNodeComplete: 'getNodeComplete',
169
+ updateNodeComplete: 'updateComplete',
170
+ createObjectComplete: 'createComplete',
171
+ getNodeComplete: 'getComplete',
172
172
  paginateProcessLogical: 'paginateProcessLogical',
173
173
  deleteNode: 'deleteNode',
174
- deleteNodeComplete: 'deleteNodeComplete',
174
+ deleteNodeComplete: 'deleteComplete',
175
175
  createObjectS3: 'createObjectS3',
176
176
  createObjectS3Complete: 'webSocketTaskComplete',
177
177
  processAfterUploadS3: 'processAfterUploadS3',
@@ -203,12 +203,12 @@ const SHORT_FUNCTION_NAME = functionName => {
203
203
  [FUNCTION_NAME.deleteRelComplete]: 'deleteRelComp',
204
204
  [FUNCTION_NAME.findData]: 'findData',
205
205
  [FUNCTION_NAME.processLogical]: 'processLogical',
206
- [FUNCTION_NAME.updateNodeComplete]: 'updateNodeComp',
207
- [FUNCTION_NAME.createObjectComplete]: 'createObjectComp',
208
- [FUNCTION_NAME.getNodeComplete]: 'getNodeComp',
206
+ [FUNCTION_NAME.updateNodeComplete]: 'updateComp',
207
+ [FUNCTION_NAME.createObjectComplete]: 'createComp',
208
+ [FUNCTION_NAME.getNodeComplete]: 'getComp',
209
209
  [FUNCTION_NAME.paginateProcessLogical]: 'paginateProLogical',
210
210
  [FUNCTION_NAME.deleteNode]: 'deleteNode',
211
- [FUNCTION_NAME.deleteNodeComplete]: 'deleteNodeComp',
211
+ [FUNCTION_NAME.deleteNodeComplete]: 'deleteComp',
212
212
  [FUNCTION_NAME.createObjectS3Complete]: 'webSocketTaskComp',
213
213
  [FUNCTION_NAME.getRel]: 'getRel',
214
214
  [FUNCTION_NAME.getRelComplete]: 'getRelComp',
@@ -238,7 +238,7 @@ const SOURCE_GENERATE_IAM_ROLE = {
238
238
  ProcessFindDataRole: 'ProcFindData',
239
239
  ObjectCompleteRole: 'ObjectCom',
240
240
  NodeCompleteRole: 'NodeCom',
241
- RelationshipRole: 'Relationship',
241
+ FlowRelationshipRole: 'Relationship',
242
242
  RelationshipCompleteRole: 'RelationshipCom',
243
243
  FlowSchemaUploadS3Role: 'FlowSchemaUploadS3',
244
244
  FlowSchemaOwnTopic: 'FlowSchemaOwnTopic',
@@ -320,27 +320,27 @@ const TOPIC_NAME_GENERATE_CODE = {
320
320
  createRelComplete: 'CreateRelationshipComplete',
321
321
  deleteRelComplete: 'DeleteRelationshipComplete',
322
322
  getRelComplete: 'GetRelationshipComplete',
323
- outUpdateRelComplete: 'UpdateRelationshipComplete_Out',
324
- outCreateRelComplete: 'CreateRelationshipComplete_Out',
325
- outDeleteRelComplete: 'DeleteRelationshipComplete_Out',
326
- outGetRelComplete: 'GetRelationshipComplete_Out',
327
- updateNodeComplete: 'UpdateNodeComplete',
328
- outUpdateNodeComplete: 'UpdateNodeComplete_Out',
329
- createNodeComplete: 'CreateObjectComplete',
330
- outCreateNodeComplete: 'CreateObjectComplete_Out',
331
- deleteNodeComplete: 'DeleteNodeComplete',
332
- outDeleteNodeComplete: 'DeleteNodeComplete_Out',
333
- getNodeComplete: 'GetNodeComplete',
334
- outGetNodeComplete: 'GetNodeComplete_Out',
323
+ outUpdateRelComplete: 'UpdateRelationship_Out',
324
+ outCreateRelComplete: 'CreateRelationship_Out',
325
+ outDeleteRelComplete: 'DeleteRelationship_Out',
326
+ outGetRelComplete: 'GetRelationship_Out',
327
+ updateNodeComplete: 'UpdateComplete',
328
+ outUpdateNodeComplete: 'Update_Out',
329
+ createNodeComplete: 'CreateComplete',
330
+ outCreateNodeComplete: 'Create_Out',
331
+ deleteNodeComplete: 'DeleteComplete',
332
+ outDeleteNodeComplete: 'Delete_Out',
333
+ getNodeComplete: 'GetComplete',
334
+ outGetNodeComplete: 'Get_Out',
335
335
  reservedLimitComplete: 'ReservedLimitComplete',
336
336
  createPreSignUrl: 'CreatePreSignUrl',
337
337
  flowSchemaOwnTopicComplete: 'FlowSchemaOwnTopicComplete',
338
338
  flowSchemaOwnTopicEndpointComplete: 'FlowSchemaOwnTopicEndpointComplete',
339
339
  createRecordComplete: 'CreateRecordComplete',
340
340
  changeRelationshipComplete: 'ChangeRelationshipComplete',
341
- outChangeRelationshipComplete: 'ChangeRelationshipComplete_Out',
341
+ outChangeRelationshipComplete: 'ChangeRelationship_Out',
342
342
  moveRelationshipComplete: 'MoveRelationshipComplete',
343
- outMoveRelationshipComplete: 'MoveRelationshipComplete_Out'
343
+ outMoveRelationshipComplete: 'MoveRelationship_Out'
344
344
  };
345
345
 
346
346
  const GRAPH_HANDLER_SERVICE_NAME = {
@@ -72,15 +72,15 @@ export async function generateDynamoDBTables(allSchemas, options) {
72
72
  }
73
73
  }
74
74
 
75
- let generatedCount = 0;
76
- const yamlOutputPath = path.join(resourceYamlDir, 'generated-dynamoDB-table.yml');
75
+ let generatedCount = 0;
76
+ const yamlOutputPath = path.join(resourceYamlDir, 'generated-dynamoDB-table.yml');
77
77
 
78
- // Generate system tables first
79
- const systemYamlTplPath = path.join(__dirname, 'templates', 'SystemDynamoDB_Yaml.ejs');
80
- const systemYamlTpl = await fs.readFile(systemYamlTplPath, 'utf-8');
81
- const systemYamlContent = ejs.render(systemYamlTpl, {});
82
- await appendToFile(yamlOutputPath, systemYamlContent);
83
- generatedCount += 8; // 8 system tables
78
+ // Generate system tables first
79
+ const systemYamlTplPath = path.join(__dirname, 'templates', 'SystemDynamoDB_Yaml.ejs');
80
+ const systemYamlTpl = await fs.readFile(systemYamlTplPath, 'utf-8');
81
+ const systemYamlContent = ejs.render(systemYamlTpl, {});
82
+ await fs.writeFile(yamlOutputPath, `${systemYamlContent}\n`, 'utf-8');
83
+ generatedCount += 12; // 12 system tables
84
84
 
85
85
  for (const [tableName, keys] of tables.entries()) {
86
86
  const yamlContent = ejs.render(yamlTpl, {
@@ -2,72 +2,78 @@ import path from 'path';
2
2
  import fs from 'fs/promises';
3
3
  import { fileURLToPath } from 'url';
4
4
  import ejs from 'ejs';
5
+
5
6
  import { getFlowsForGeneration } from '../../app/src/generatedCode/Flow/_shared/shared/flowSelection.js';
6
7
 
7
8
  const __filename = fileURLToPath(import.meta.url);
8
9
  const __dirname = path.dirname(__filename);
9
10
 
10
11
  async function appendToFile(filePath, content) {
11
- try {
12
- await fs.mkdir(path.dirname(filePath), { recursive: true });
13
- await fs.appendFile(filePath, content + '\n', 'utf-8');
14
- } catch (error) {
15
- console.error(`[Error] Failed to append to file: ${filePath}`, error);
16
- }
12
+ try {
13
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
14
+ await fs.appendFile(filePath, `${content}\n`, 'utf-8');
15
+ } catch (error) {
16
+ console.error(`[Error] Failed to append file: ${filePath}`, error);
17
+ }
17
18
  }
18
19
 
19
20
  export async function generateFlowOut(allSchemas, options) {
20
- console.log(' [FlowOutGenerator] Generating Flow Out nodes (SNS Topics)...');
21
-
22
- const resourceYamlDir = path.join(options.outputPath, 'resource', 'sls_yaml', 'generatedCode', 'source');
23
- await fs.mkdir(resourceYamlDir, { recursive: true });
21
+ console.log(' [FlowOutGenerator] Generating Flow Out nodes (SNS Topics)...');
22
+
23
+ const resourceYamlDir = path.join(options.outputPath, 'resource', 'sls_yaml', 'generatedCode', 'source');
24
+ await fs.mkdir(resourceYamlDir, { recursive: true });
25
+
26
+ const yamlTplPath = path.join(__dirname, 'templates', 'FlowOut_Yaml.ejs');
27
+ const yamlTpl = await fs.readFile(yamlTplPath, 'utf-8');
24
28
 
25
- const yamlTplPath = path.join(__dirname, 'templates', 'FlowOut_Yaml.ejs');
26
- const yamlTpl = await fs.readFile(yamlTplPath, 'utf-8');
29
+ let generatedCount = 0;
30
+ const yamlOutputPath = path.join(resourceYamlDir, 'generated-sns-out.yml');
31
+ await fs.writeFile(yamlOutputPath, 'Resources:\n', 'utf-8'); // ponytail: simplest one-line fix
27
32
 
28
- let generatedCount = 0;
29
- const yamlOutputPath = path.join(resourceYamlDir, 'generated-sns-out.yml');
33
+ const generatedTopics = new Set();
30
34
 
31
- const flows = getFlowsForGeneration(allSchemas);
32
- for (const flow of flows) {
33
- if (flow.outputTopic === true) {
34
- const upperCase = (str) => str.charAt(0).toUpperCase() + str.slice(1);
35
- const topicName = upperCase(flow.flowTag);
35
+ async function appendTopic(topicName) {
36
+ if (generatedTopics.has(topicName)) return;
36
37
 
37
- const yamlContent = ejs.render(yamlTpl, {
38
- topicName: topicName
39
- });
38
+ generatedTopics.add(topicName);
39
+ const yamlContent = ejs.render(yamlTpl, { topicName });
40
+ await appendToFile(yamlOutputPath, yamlContent);
41
+ generatedCount++;
42
+ }
40
43
 
41
- await appendToFile(yamlOutputPath, yamlContent);
42
- generatedCount++;
43
- }
44
- }
44
+ const flows = getFlowsForGeneration(allSchemas);
45
+ for (const flow of flows) {
46
+ if (flow.outputTopic !== true) continue;
47
+ await appendTopic(flow.flowTag.charAt(0).toUpperCase() + flow.flowTag.slice(1));
48
+ }
45
49
 
46
- const systemTopics = [
47
- 'CreateObjectComplete',
48
- 'DeleteNodeComplete',
49
- 'UpdateNodeComplete',
50
- 'GetNodeComplete',
51
- 'ProcessLogicalComplete',
52
- 'FindDataComplete',
53
- // CRUD Async Topics
54
- 'Create', 'Update', 'Delete',
55
- // Relationship Topics
56
- 'CreateRelationship', 'UpdateRelationship', 'DeleteRelationship',
57
- 'GetRelationship', 'ChangeRelationship', 'MoveRelationship',
58
- // RBAC Topics
59
- 'CreateTargetRole', 'ListTargetRole', 'DeleteTargetRole',
60
- 'CreateRolePermissions', 'ListRolePermissions', 'DeleteRolePermissions',
61
- 'CreateUserRole', 'ListUserInRoles', 'DeleteUserFromRole'
62
- ];
50
+ const systemTopics = [
51
+ 'ProcessLogical',
52
+ 'PaginateProcessLogical',
53
+ 'FindData',
54
+ 'Create',
55
+ 'Update',
56
+ 'Delete',
57
+ 'CreateRelationship',
58
+ 'UpdateRelationship',
59
+ 'DeleteRelationship',
60
+ 'GetRelationship',
61
+ 'ChangeRelationship',
62
+ 'MoveRelationship',
63
+ 'CreateTargetRole',
64
+ 'ListTargetRole',
65
+ 'DeleteTargetRole',
66
+ 'CreateRolePermissions',
67
+ 'ListRolePermissions',
68
+ 'DeleteRolePermissions',
69
+ 'CreateUserRole',
70
+ 'ListUserInRoles',
71
+ 'DeleteUserFromRole'
72
+ ];
63
73
 
64
- for (const topic of systemTopics) {
65
- const yamlContent = ejs.render(yamlTpl, {
66
- topicName: topic
67
- });
68
- await appendToFile(yamlOutputPath, yamlContent);
69
- generatedCount++;
70
- }
74
+ for (const topic of systemTopics) {
75
+ await appendTopic(topic);
76
+ }
71
77
 
72
- console.log(` [FlowOutGenerator] Generated ${generatedCount} SNS Topics for Flow Out nodes.`);
78
+ console.log(` [FlowOutGenerator] Generated ${generatedCount} SNS Topics for Flow Out nodes.`);
73
79
  }
@@ -2,198 +2,187 @@ import path from 'path';
2
2
  import fs from 'fs/promises';
3
3
  import { fileURLToPath } from 'url';
4
4
  import ejs from 'ejs';
5
+
5
6
  import { getFlowsForGeneration } from '../../app/src/generatedCode/Flow/_shared/shared/flowSelection.js';
6
7
 
7
8
  const __filename = fileURLToPath(import.meta.url);
8
9
  const __dirname = path.dirname(__filename);
9
10
 
10
11
  async function appendToFile(filePath, content) {
11
- try {
12
- await fs.mkdir(path.dirname(filePath), { recursive: true });
13
- await fs.appendFile(filePath, content + '\n', 'utf-8');
14
- } catch (error) {
15
- console.error(`[Error] Failed to append to file: ${filePath}`, error);
16
- }
12
+ try {
13
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
14
+ await fs.appendFile(filePath, `${content}\n`, 'utf-8');
15
+ } catch (error) {
16
+ console.error(`[Error] Failed to append file: ${filePath}`, error);
17
+ }
17
18
  }
18
19
 
19
20
  export async function generateFlowResourceYaml(allSchemas, options) {
20
- console.log(' [FlowResourceYamlGenerator] Generating SQS/SNS YAML resources for flows...');
21
-
22
- const resourceYamlDir = path.join(options.outputPath, 'resource', 'sls_yaml', 'generatedCode', 'source');
23
- await fs.mkdir(resourceYamlDir, { recursive: true });
24
-
25
- const resourceYamlTplPath = path.join(__dirname, 'templates', 'crud', 'ResourceYaml.ejs');
26
- const resourceBeforeLogicalYamlTplPath = path.join(__dirname, 'templates', 'crud', 'ResourceBeforeLogicalYaml.ejs');
27
-
28
- const resourceYamlTpl = await fs.readFile(resourceYamlTplPath, 'utf-8');
29
- const resourceBeforeLogicalYamlTpl = await fs.readFile(resourceBeforeLogicalYamlTplPath, 'utf-8');
30
-
31
- let generatedCount = 0;
32
- const yamlOutputPath = path.join(resourceYamlDir, 'generated-sns-in-sqs.yml');
33
-
34
- const flows = getFlowsForGeneration(allSchemas);
35
- for (const flow of flows) {
36
- const flowTag = flow.flowTag;
37
-
38
- // Generate In-Queue resources for any flow that listens on its own topic
39
- if (flow.event && flow.event.includes('ownTopic')) {
40
- // Render main ResourceYaml.ejs (e.g., InCreate, CreateHdrSqs)
41
- const yamlContent = ejs.render(resourceYamlTpl, {
42
- queueName: flowTag
43
- });
44
- await appendToFile(yamlOutputPath, yamlContent);
45
- generatedCount++;
46
-
47
- // Check if there are beforeLogical configs for this flow
48
- const generateCodeConfigs = flows
49
- .filter(f => f.generatedCodeConfig && f.generatedCodeConfig.generatedCodeTag.toLowerCase() === flowTag.toLowerCase())
50
- .map(f => ({
51
- ...f.generatedCodeConfig,
52
- flowTag: f.flowTag
53
- }));
54
-
55
- const beforeLogicalConfigs = generateCodeConfigs.filter(c => c.codeHookTag === 'beforeLogical');
56
-
57
- if (beforeLogicalConfigs.length > 0) {
58
- // Collect unique flowTags (like ValidateUnitTrackedProperty) from the beforeLogical configs
59
- const uniqueFlowTags = [...new Set(beforeLogicalConfigs.map(c => c.flowTag))];
60
-
61
- const beforeLogicalYamlContent = ejs.render(resourceBeforeLogicalYamlTpl, {
62
- queueName: `${flowTag}BeforeLogical`,
63
- flowTags: uniqueFlowTags
64
- });
65
-
66
- await appendToFile(yamlOutputPath, beforeLogicalYamlContent);
67
- generatedCount++;
68
- }
69
- } else if (flow.event && flow.event.includes('extTopic')) {
70
- // Custom flows using extTopic do not have ownTopic, but need an entry queue
71
- const resourceSqsYamlTplPath = path.join(__dirname, 'templates', 'crud', 'ResourceSqsYaml.ejs');
72
- const resourceSqsYamlTpl = await fs.readFile(resourceSqsYamlTplPath, 'utf-8');
73
- const yamlContent = ejs.render(resourceSqsYamlTpl, {
74
- queueName: `Process${flowTag}Sqs`
75
- });
76
- await appendToFile(yamlOutputPath, yamlContent);
77
- generatedCount++;
78
- }
79
-
80
- // Generate Complete queues for custom FlowSchema
81
- // Also generate queues for any flowStep that uses sqs, dsq, or extTopic
82
- if (flow.flowSteps && Array.isArray(flow.flowSteps)) {
83
- for (const stepConfig of flow.flowSteps) {
84
- const stepName = stepConfig.stepName;
85
- if (stepName === 'InTag') continue;
86
-
87
- const events = stepConfig.event || ['sqs'];
88
- for (const ev of events) {
89
- let queueName = flowTag + stepName;
90
- if (stepName === 'Complete') {
91
- queueName = flowTag + 'Complete';
92
- }
93
-
94
- if (ev === 'sqs' || ev === 'ownTopic') {
95
- // sqs and ownTopic create SNS Topic + Subscription + SQS Queue
96
- const yamlContent = ejs.render(resourceYamlTpl, {
97
- queueName: queueName
98
- });
99
- await appendToFile(yamlOutputPath, yamlContent);
100
- generatedCount++;
101
- } else if (ev === 'dsq' || ev === 'extTopic') {
102
- // extTopic and dsq create ONLY SQS Queue
103
- const resourceSqsYamlTplPath = path.join(__dirname, 'templates', 'crud', 'ResourceSqsYaml.ejs');
104
- const resourceSqsYamlTpl = await fs.readFile(resourceSqsYamlTplPath, 'utf-8');
105
- const yamlContent = ejs.render(resourceSqsYamlTpl, {
106
- queueName: queueName
107
- });
108
- await appendToFile(yamlOutputPath, yamlContent);
109
- generatedCount++;
110
- }
111
- }
112
- }
113
- }
21
+ console.log(' [FlowResourceYamlGenerator] Generating SQS/SNS YAML resources for flows...');
114
22
 
115
- // Generate SQS queues for S3 Event flows
116
- if (flow.event && flow.event.includes('s3')) {
117
- const queueNames = [
118
- `${flowTag}CreatePreSignUrlSqs`,
119
- `${flowTag}ReservedLimitSqs`
120
- ];
121
-
122
- for (const qName of queueNames) {
123
- const resourceSqsYamlTplPath = path.join(__dirname, 'templates', 'crud', 'ResourceSqsYaml.ejs');
124
- const resourceSqsYamlTpl = await fs.readFile(resourceSqsYamlTplPath, 'utf-8');
125
- const yamlContent = ejs.render(resourceSqsYamlTpl, {
126
- queueName: qName
127
- });
128
- await appendToFile(yamlOutputPath, yamlContent);
129
- generatedCount++;
130
- }
131
- }
23
+ const resourceYamlDir = path.join(options.outputPath, 'resource', 'sls_yaml', 'generatedCode', 'source');
24
+ await fs.mkdir(resourceYamlDir, { recursive: true });
132
25
 
133
- // Generate Dsq queues for Relationship
134
- if (flow.isDynamicRelationshipType) {
135
- // Usually Relationship has dead-letter queue processing
136
- const resourceSqsYamlTplPath = path.join(__dirname, 'templates', 'crud', 'ResourceSqsYaml.ejs');
137
- const resourceSqsYamlTpl = await fs.readFile(resourceSqsYamlTplPath, 'utf-8');
138
- const queueName = flowTag + 'Dsq';
139
- const yamlContent = ejs.render(resourceSqsYamlTpl, {
140
- queueName: queueName
141
- });
142
- await appendToFile(yamlOutputPath, yamlContent);
143
- generatedCount++;
144
- }
26
+ const resourceYamlTplPath = path.join(__dirname, 'templates', 'crud', 'ResourceYaml.ejs');
27
+ const resourceBeforeLogicalYamlTplPath = path.join(__dirname, 'templates', 'crud', 'ResourceBeforeLogicalYaml.ejs');
28
+ const resourceSqsYamlTplPath = path.join(__dirname, 'templates', 'crud', 'ResourceSqsYaml.ejs');
29
+
30
+ const resourceYamlTpl = await fs.readFile(resourceYamlTplPath, 'utf-8');
31
+ const resourceBeforeLogicalYamlTpl = await fs.readFile(resourceBeforeLogicalYamlTplPath, 'utf-8');
32
+ const resourceSqsYamlTpl = await fs.readFile(resourceSqsYamlTplPath, 'utf-8');
33
+
34
+ let generatedCount = 0;
35
+ const yamlOutputPath = path.join(resourceYamlDir, 'generated-sns-in-sqs.yml');
36
+ await fs.writeFile(yamlOutputPath, 'Resources:\n', 'utf-8'); // ponytail: build minimum that works, one-line initialization fix
37
+
38
+ const generatedResources = new Set();
39
+
40
+ async function appendUnique(resourceKey, template, templateData) {
41
+ if (generatedResources.has(resourceKey)) return;
42
+
43
+ generatedResources.add(resourceKey);
44
+ const yamlContent = ejs.render(template, templateData);
45
+ await appendToFile(yamlOutputPath, yamlContent);
46
+ generatedCount++;
47
+ }
48
+
49
+ const flows = getFlowsForGeneration(allSchemas);
50
+
51
+ for (const flow of flows) {
52
+ const flowTag = flow.flowTag;
53
+
54
+ if (flow.event && flow.event.includes('ownTopic')) {
55
+ await appendUnique(flowTag, resourceYamlTpl, { queueName: flowTag });
56
+
57
+ const generateCodeConfigs = flows
58
+ .filter((candidate) => candidate.generatedCodeConfig
59
+ && candidate.generatedCodeConfig.generatedCodeTag?.toLowerCase() === flowTag.toLowerCase())
60
+ .map((candidate) => ({
61
+ ...candidate.generatedCodeConfig,
62
+ flowTag: candidate.flowTag
63
+ }));
64
+
65
+ const beforeLogicalConfigs = generateCodeConfigs.filter((config) => config.codeHookTag === 'beforeLogical');
66
+ if (beforeLogicalConfigs.length > 0) {
67
+ const uniqueFlowTags = [...new Set(beforeLogicalConfigs.map((config) => config.flowTag))];
68
+ await appendUnique(`${flowTag}BeforeLogical`, resourceBeforeLogicalYamlTpl, {
69
+ queueName: `${flowTag}BeforeLogical`,
70
+ flowTags: uniqueFlowTags
71
+ });
72
+ }
73
+ } else if (flow.event && flow.event.includes('extTopic')) {
74
+ await appendUnique(`Process${flowTag}HdrSqs`, resourceSqsYamlTpl, {
75
+ queueName: `Process${flowTag}HdrSqs`
76
+ });
145
77
  }
146
78
 
147
- // Add hardcoded ownTopic flows for CRUD, RBAC, Relationship
148
- const systemOwnTopicFlows = [
149
- 'Create', 'Update', 'Delete', // CRUD
150
- 'CreateRelationship', 'UpdateRelationship', 'DeleteRelationship', 'ChangeRelationship', 'MoveRelationship', // Relationship
151
- 'CreateTargetRole', 'DeleteTargetRole', 'CreateRolePermissions', 'DeleteRolePermissions', 'CreateUserRole', 'DeleteUserFromRole' // RBAC
152
- ];
153
- for (const flowTag of systemOwnTopicFlows) {
154
- const yamlContent = ejs.render(resourceYamlTpl, { queueName: flowTag });
155
- await appendToFile(yamlOutputPath, yamlContent);
156
- generatedCount++;
157
-
158
- // BeforeLogical queues for CRUD
159
- if (['Create', 'Update', 'Delete'].includes(flowTag)) {
160
- // Since we don't have beforeLogical configs here, we assume we might need them or we can just generate a generic one?
161
- // For now, only custom flows generate beforeLogical dynamically above.
79
+ if (Array.isArray(flow.flowSteps)) {
80
+ for (const stepConfig of flow.flowSteps) {
81
+ const stepName = stepConfig.stepName;
82
+ if (stepName === 'InTag') continue;
83
+
84
+ const events = stepConfig.event || ['sqs'];
85
+ for (const ev of events) {
86
+ let queueName = `${flowTag}${stepName}`;
87
+ if (stepName === 'Complete') {
88
+ queueName = `${flowTag}Complete`;
89
+ }
90
+
91
+ if (ev === 'ownTopic') {
92
+ await appendUnique(queueName, resourceYamlTpl, { queueName });
93
+ } else if (ev === 'sqs') {
94
+ // ponytail: purely SQS events don't need SNS topics, use resourceSqsYamlTpl
95
+ await appendUnique(`${queueName}HdrSqs`, resourceSqsYamlTpl, {
96
+ queueName: `${queueName}HdrSqs`
97
+ });
98
+ } else if (ev === 'dsq') {
99
+ await appendUnique(`${queueName}HdrDsq`, resourceSqsYamlTpl, {
100
+ queueName: `${queueName}HdrDsq`
101
+ });
102
+ } else if (ev === 'extTopic') {
103
+ await appendUnique(`${queueName}HdrSqs`, resourceSqsYamlTpl, {
104
+ queueName: `${queueName}HdrSqs`
105
+ });
106
+ }
162
107
  }
108
+ }
163
109
  }
164
110
 
165
- // Generate Dsq queues for Relationship
166
- const relationshipActions = ['CreateRelationship', 'UpdateRelationship', 'DeleteRelationship', 'GetRelationship', 'ChangeRelationship', 'MoveRelationship'];
167
- const resourceSqsYamlTplPath = path.join(__dirname, 'templates', 'crud', 'ResourceSqsYaml.ejs');
168
- const resourceSqsYamlTpl = await fs.readFile(resourceSqsYamlTplPath, 'utf-8');
169
- for (const action of relationshipActions) {
170
- const yamlContent = ejs.render(resourceSqsYamlTpl, { queueName: action + 'Dsq' });
171
- await appendToFile(yamlOutputPath, yamlContent);
172
- generatedCount++;
173
- }
111
+ if (flow.event && flow.event.includes('s3')) {
112
+ const queueNames = [
113
+ `${flowTag}CreatePreSignUrlHdrSqs`,
114
+ `${flowTag}ReservedLimitHdrSqs`
115
+ ];
174
116
 
175
- // Add System Queues
176
- const systemQueues = [
177
- 'ProcessLogical',
178
- 'PaginateProcessLogical',
179
- 'FindData',
180
- 'Register',
181
- 'WebSocket',
182
- 'CreateObjectComplete',
183
- 'UpdateNodeComplete',
184
- 'DeleteNodeComplete',
185
- 'GetNodeComplete'
186
- ];
187
-
188
- const resourceSqsYamlTplGlobal = await fs.readFile(resourceSqsYamlTplPath, 'utf-8');
189
-
190
- for (const sysQueue of systemQueues) {
191
- const yamlContent = ejs.render(resourceSqsYamlTplGlobal, {
192
- queueName: sysQueue
193
- });
194
- await appendToFile(yamlOutputPath, yamlContent);
195
- generatedCount++;
117
+ for (const queueName of queueNames) {
118
+ await appendUnique(queueName, resourceSqsYamlTpl, { queueName });
119
+ }
196
120
  }
197
121
 
198
- console.log(` [FlowResourceYamlGenerator] Appended ${generatedCount} sections to generated-sns-in-sqs.yml.`);
122
+ if (flow.isDynamicRelationshipType) {
123
+ const queueName = `${flowTag}HdrDsq`;
124
+ await appendUnique(queueName, resourceSqsYamlTpl, { queueName });
125
+ }
126
+ }
127
+
128
+ const systemOwnTopicFlows = [
129
+ 'ProcessLogical',
130
+ 'PaginateProcessLogical',
131
+ 'FindData',
132
+ 'Create',
133
+ 'Update',
134
+ 'Delete',
135
+ 'CreateRelationship',
136
+ 'UpdateRelationship',
137
+ 'DeleteRelationship',
138
+ 'ChangeRelationship',
139
+ 'MoveRelationship',
140
+ 'CreateTargetRole',
141
+ 'DeleteTargetRole',
142
+ 'CreateRolePermissions',
143
+ 'DeleteRolePermissions',
144
+ 'CreateUserRole',
145
+ 'DeleteUserFromRole'
146
+ ];
147
+
148
+ for (const flowTag of systemOwnTopicFlows) {
149
+ await appendUnique(flowTag, resourceYamlTpl, { queueName: flowTag });
150
+ }
151
+
152
+ const relationshipActions = [
153
+ 'CreateRelationship',
154
+ 'UpdateRelationship',
155
+ 'DeleteRelationship',
156
+ 'GetRelationship',
157
+ 'ChangeRelationship',
158
+ 'MoveRelationship'
159
+ ];
160
+
161
+ for (const action of relationshipActions) {
162
+ const queueName = `${action}HdrDsq`;
163
+ await appendUnique(queueName, resourceSqsYamlTpl, { queueName });
164
+ }
165
+
166
+ const systemQueues = [
167
+ 'Register',
168
+ 'WebSocket',
169
+ 'CreateComplete',
170
+ 'UpdateComplete',
171
+ 'DeleteComplete',
172
+ 'GetComplete',
173
+ 'GetRelationship',
174
+ 'CreateRelationshipComplete',
175
+ 'UpdateRelationshipComplete',
176
+ 'DeleteRelationshipComplete',
177
+ 'GetRelationshipComplete',
178
+ 'ChangeRelationshipComplete',
179
+ 'MoveRelationshipComplete'
180
+ ];
181
+
182
+ for (const sysQueue of systemQueues) {
183
+ const queueName = `${sysQueue}HdrSqs`;
184
+ await appendUnique(queueName, resourceSqsYamlTpl, { queueName });
185
+ }
186
+
187
+ console.log(` [FlowResourceYamlGenerator] Appended ${generatedCount} sections to generated-sns-in-sqs.yml.`);
199
188
  }