@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
@@ -136,3 +136,67 @@ Resources:
136
136
  KeyType: HASH
137
137
  - AttributeName: pendingStepId
138
138
  KeyType: RANGE
139
+
140
+ TargetRolesTable:
141
+ Type: "AWS::DynamoDB::Table"
142
+ Properties:
143
+ TableName: ${self:custom.iz_resourcePrefix}TargetRoles
144
+ BillingMode: PAY_PER_REQUEST
145
+ AttributeDefinitions:
146
+ - AttributeName: targetId
147
+ AttributeType: S
148
+ - AttributeName: roleIdKey
149
+ AttributeType: S
150
+ KeySchema:
151
+ - AttributeName: targetId
152
+ KeyType: HASH
153
+ - AttributeName: roleIdKey
154
+ KeyType: RANGE
155
+
156
+ RolePermissionsTable:
157
+ Type: "AWS::DynamoDB::Table"
158
+ Properties:
159
+ TableName: ${self:custom.iz_resourcePrefix}RolePermissions
160
+ BillingMode: PAY_PER_REQUEST
161
+ AttributeDefinitions:
162
+ - AttributeName: roleIdKey
163
+ AttributeType: S
164
+ - AttributeName: flowTypeConcat
165
+ AttributeType: S
166
+ KeySchema:
167
+ - AttributeName: roleIdKey
168
+ KeyType: HASH
169
+ - AttributeName: flowTypeConcat
170
+ KeyType: RANGE
171
+
172
+ RoleUsersTable:
173
+ Type: "AWS::DynamoDB::Table"
174
+ Properties:
175
+ TableName: ${self:custom.iz_resourcePrefix}RoleUsers
176
+ BillingMode: PAY_PER_REQUEST
177
+ AttributeDefinitions:
178
+ - AttributeName: roleIdKey
179
+ AttributeType: S
180
+ - AttributeName: userId
181
+ AttributeType: S
182
+ KeySchema:
183
+ - AttributeName: roleIdKey
184
+ KeyType: HASH
185
+ - AttributeName: userId
186
+ KeyType: RANGE
187
+
188
+ UserRolesTable:
189
+ Type: "AWS::DynamoDB::Table"
190
+ Properties:
191
+ TableName: ${self:custom.iz_resourcePrefix}UserRoles
192
+ BillingMode: PAY_PER_REQUEST
193
+ AttributeDefinitions:
194
+ - AttributeName: userId
195
+ AttributeType: S
196
+ - AttributeName: roleIdKey
197
+ AttributeType: S
198
+ KeySchema:
199
+ - AttributeName: userId
200
+ KeyType: HASH
201
+ - AttributeName: roleIdKey
202
+ KeyType: RANGE
@@ -10,30 +10,30 @@
10
10
  Type: AWS::SNS::Subscription
11
11
  Properties:
12
12
  TopicArn: !Ref In<%- queueName %>
13
- Endpoint: "arn:aws:sqs:${self:custom.iz_region}:${self:custom.iz_accountId}:${self:custom.iz_resourcePrefix}<%- queueName %>Sqs"
13
+ Endpoint: "arn:aws:sqs:${self:custom.iz_region}:${self:custom.iz_accountId}:${self:custom.iz_resourcePrefix}<%- queueName %>HdrSqs"
14
14
  Protocol: "sqs"
15
15
 
16
16
  ##===== [Queue]
17
- <%- queueName %>Sqs:
17
+ <%- queueName %>HdrSqs:
18
18
  Type: "AWS::SQS::Queue"
19
19
  Properties:
20
- QueueName: ${self:custom.iz_resourcePrefix}<%- queueName %>Sqs
20
+ QueueName: ${self:custom.iz_resourcePrefix}<%- queueName %>HdrSqs
21
21
  RedrivePolicy:
22
22
  deadLetterTargetArn:
23
23
  Fn::GetAtt:
24
- - <%- queueName %>SqsDLQ
24
+ - <%- queueName %>HdrSqsDLQ
25
25
  - Arn
26
26
  maxReceiveCount: 3
27
27
  VisibilityTimeout: 120
28
28
 
29
29
  ##===== [Queue DLQ]
30
- <%- queueName %>SqsDLQ:
30
+ <%- queueName %>HdrSqsDLQ:
31
31
  Type: AWS::SQS::Queue
32
32
  Properties:
33
- QueueName: ${self:custom.iz_resourcePrefix}<%- queueName %>SqsDLQ
33
+ QueueName: ${self:custom.iz_resourcePrefix}<%- queueName %>HdrSqsDLQ
34
34
 
35
35
  ##===== [Queue Policy]
36
- <%- queueName %>SqsPolicy:
36
+ <%- queueName %>HdrSqsPolicy:
37
37
  Type: AWS::SQS::QueuePolicy
38
38
  Properties:
39
39
  PolicyDocument:
@@ -44,11 +44,11 @@
44
44
  Principal: "*"
45
45
  Resource:
46
46
  Fn::GetAtt:
47
- - <%- queueName %>Sqs
47
+ - <%- queueName %>HdrSqs
48
48
  - Arn
49
49
  Action: "SQS:SendMessage"
50
50
  Queues:
51
- - Ref: <%- queueName %>Sqs
51
+ - Ref: <%- queueName %>HdrSqs
52
52
 
53
53
  #<#<%- queueName %>QueueSetting#>
54
- #<#/<%- queueName %>QueueSetting#>
54
+ #<#/<%- queueName %>QueueSetting#>
package/src/generate.js CHANGED
@@ -52,7 +52,7 @@ async function generate(rootPath, options = {}) {
52
52
 
53
53
  // Auto-generate dynamic schemas before validation (unless skipped)
54
54
  if (!skipGenerateSchema) {
55
- await generateSchema(rootPath, { outputPath });
55
+ await generateSchema(rootPath, { outputPath, configPath });
56
56
  }
57
57
 
58
58
  // Validate schemas before generating (unless skipped)
@@ -5,17 +5,15 @@ import { parseObjectSchemas } from './parsers/objectSchemaParser.js';
5
5
  import { parseRelationshipSchemas } from './parsers/relationshipSchemaParser.js';
6
6
  import { parseFlowSchemas } from './parsers/flowSchemaParser.js';
7
7
 
8
-
9
-
10
8
  import { generateFlowEntryPoint } from './codeGenerators/app/src/generatedCode/Flow/_shared/shared/flowEntryPointBase.js';
11
9
  import { generateFlowMainFunction } from './codeGenerators/app/src/generatedCode/Flow/_shared/shared/flowMainFunctionBase.js';
12
10
  import { generateFlowSteps } from './codeGenerators/app/src/generatedCode/Flow/_shared/shared/flowStepBase.js';
13
11
 
14
- import { generateEndpointsFlow } from './codeGenerators/app/src/generatedCode/Flow/FlowEndpoints/EndpointsGenerator.js';
12
+ import { generateEndpointsFlow } from './codeGenerators/app/src/generatedCode/Flow/FlowObjects/EndpointsGenerator.js';
15
13
  import { generateFlowOut } from './codeGenerators/resource/sls_yaml/FlowOutGenerator.js';
16
14
  import { generateFlowResourceYaml } from './codeGenerators/resource/sls_yaml/FlowResourceYamlGenerator.js';
17
15
  import { generateRbacFlows } from './codeGenerators/app/src/generatedCode/Flow/FlowRbac/RbacFlowGenerator.js';
18
- import { generateRelationshipFlows } from './codeGenerators/app/src/generatedCode/Flow/FlowRelationshipEndpoints/RelationshipFlowGenerator.js';
16
+ import { generateRelationshipFlows } from './codeGenerators/app/src/generatedCode/Flow/FlowRelationships/RelationshipFlowGenerator.js';
19
17
  import { generateWebSocket } from './codeGenerators/app/src/generatedCode/Flow/FlowSchemas/WebSocketGenerator.js';
20
18
  import { validateFlowsForGeneration } from './codeGenerators/app/src/generatedCode/Flow/_shared/shared/flowValidator.js';
21
19
  import { generateRegisterFlow } from './codeGenerators/app/src/generatedCode/SystemFlowSchemas/RegisterGenerator.js';
@@ -33,86 +31,107 @@ import { generateFindDataYaml } from './codeGenerators/app/sls_yaml/FindDataYaml
33
31
  import { policyRegistry } from './codeGenerators/app/sls_yaml/_policy/PolicyRegistry.js';
34
32
  import { emitManagedPolicies } from './codeGenerators/app/sls_yaml/_policy/PolicyEmitter.js';
35
33
 
36
- export async function generateCode(rootPath, options) {
34
+ function createGeneratorOptions(rootPath, options = {}) {
35
+ return {
36
+ outputPath: options.outputPath || rootPath
37
+ };
38
+ }
39
+
40
+ export async function generateCode(rootPath, options = {}) {
37
41
  console.log(
38
42
  '[INFO] [generateCode] STATUS=STARTING | Generating code files from all schemas...'
39
43
  );
40
44
 
45
+ const generatorOptions = createGeneratorOptions(rootPath, options);
46
+ const { outputPath } = generatorOptions;
47
+
41
48
  // Clean workspace
42
- const outputPath = options.outputPath || rootPath;
43
- const generatedCodePath = path.join(outputPath, 'app', 'src', 'generatedCode');
49
+ const generatedCodePath = path.join(
50
+ outputPath,
51
+ 'app',
52
+ 'src',
53
+ 'generatedCode'
54
+ );
44
55
 
45
56
  // Backup existing hook files to prevent them from being wiped out
46
- const hookBackups = [];
47
- const hookDirs = new Set();
48
-
49
- function getHookTagMatchers(filePath) {
50
- if (filePath.endsWith('.js')) {
51
- return {
52
- anyTag: /\/\/\(<(\w+)>\)([\s\S]*?)\/\/\(<\/\1>\)/gm,
53
- tagPattern: (name) => new RegExp(
54
- `\\/\\/\\(<${name}>\\)([\\s\\S]*?)\\/\\/\\(<\\/${name}>\\)`,
55
- 'gm'
56
- )
57
- };
58
- }
59
-
60
- if (filePath.endsWith('.yml') || filePath.endsWith('.yaml')) {
61
- return {
62
- anyTag: /#<#(\w+)#>([\s\S]*?)#<#\/\1#>/gm,
63
- tagPattern: (name) => new RegExp(
64
- `#<#${name}#>([\\s\\S]*?)#<#\\/${name}#>`,
65
- 'gm'
66
- )
67
- };
68
- }
69
-
70
- return null;
71
- }
72
-
73
- function mergeHookIntoSource(sourceContent, hookContent, filePath) {
74
- const matchers = getHookTagMatchers(filePath);
75
- if (!matchers) return hookContent;
76
-
77
- return sourceContent.replace(matchers.anyTag, (match, tagName) => (
78
- hookContent.match(matchers.tagPattern(tagName))?.[0] ?? match
79
- ));
80
- }
81
-
82
- function collectHookBackups(currentDir) {
83
- if (!fs.existsSync(currentDir)) return;
84
-
85
- const items = fs.readdirSync(currentDir, { withFileTypes: true });
86
- const hasSource = items.some((item) => item.isDirectory() && item.name === 'source');
87
- const hasHook = items.some((item) => item.isDirectory() && item.name === 'hook');
88
-
89
- if (hasSource && hasHook) {
90
- const hookPath = path.join(currentDir, 'hook');
91
- hookDirs.add(path.relative(outputPath, hookPath));
92
- const hookItems = fs.readdirSync(hookPath, { withFileTypes: true });
93
-
94
- for (const hookItem of hookItems) {
95
- if (!hookItem.isFile()) continue;
96
- const hookFilePath = path.join(hookPath, hookItem.name);
97
- hookBackups.push({
98
- relativePath: path.relative(outputPath, hookPath),
99
- name: hookItem.name,
100
- content: fs.readFileSync(hookFilePath)
101
- });
102
- }
103
- }
104
-
105
- for (const item of items) {
106
- if (!item.isDirectory() || item.name === 'source' || item.name === 'hook') continue;
107
- collectHookBackups(path.join(currentDir, item.name));
108
- }
109
- }
110
-
111
- console.log('[INFO] [generateCode] STATUS=BACKUP | Backing up existing hook files...');
112
- collectHookBackups(outputPath);
113
-
114
- console.log(
115
- '[INFO] [generateCode] STATUS=CLEANUP | Removing old generatedCode and resource directories...'
57
+ const hookBackups = [];
58
+ const hookDirs = new Set();
59
+
60
+ function getHookTagMatchers(filePath) {
61
+ if (filePath.endsWith('.js')) {
62
+ return {
63
+ anyTag: /\/\/\(<(\w+)>\)([\s\S]*?)\/\/\(<\/\1>\)/gm,
64
+ tagPattern: name =>
65
+ new RegExp(
66
+ `\\/\\/\\(<${name}>\\)([\\s\\S]*?)\\/\\/\\(<\\/${name}>\\)`,
67
+ 'gm'
68
+ )
69
+ };
70
+ }
71
+
72
+ if (filePath.endsWith('.yml') || filePath.endsWith('.yaml')) {
73
+ return {
74
+ anyTag: /#<#(\w+)#>([\s\S]*?)#<#\/\1#>/gm,
75
+ tagPattern: name =>
76
+ new RegExp(`#<#${name}#>([\\s\\S]*?)#<#\\/${name}#>`, 'gm')
77
+ };
78
+ }
79
+
80
+ return null;
81
+ }
82
+
83
+ function mergeHookIntoSource(sourceContent, hookContent, filePath) {
84
+ const matchers = getHookTagMatchers(filePath);
85
+ if (!matchers) return hookContent;
86
+
87
+ return sourceContent.replace(
88
+ matchers.anyTag,
89
+ (match, tagName) =>
90
+ hookContent.match(matchers.tagPattern(tagName))?.[0] ?? match
91
+ );
92
+ }
93
+
94
+ function collectHookBackups(currentDir) {
95
+ if (!fs.existsSync(currentDir)) return;
96
+
97
+ const items = fs.readdirSync(currentDir, { withFileTypes: true });
98
+ const hasSource = items.some(
99
+ item => item.isDirectory() && item.name === 'source'
100
+ );
101
+ const hasHook = items.some(
102
+ item => item.isDirectory() && item.name === 'hook'
103
+ );
104
+
105
+ if (hasSource && hasHook) {
106
+ const hookPath = path.join(currentDir, 'hook');
107
+ hookDirs.add(path.relative(outputPath, hookPath));
108
+ const hookItems = fs.readdirSync(hookPath, { withFileTypes: true });
109
+
110
+ for (const hookItem of hookItems) {
111
+ if (!hookItem.isFile()) continue;
112
+ const hookFilePath = path.join(hookPath, hookItem.name);
113
+ hookBackups.push({
114
+ relativePath: path.relative(outputPath, hookPath),
115
+ name: hookItem.name,
116
+ content: fs.readFileSync(hookFilePath)
117
+ });
118
+ }
119
+ }
120
+
121
+ for (const item of items) {
122
+ if (!item.isDirectory() || item.name === 'source' || item.name === 'hook')
123
+ continue;
124
+ collectHookBackups(path.join(currentDir, item.name));
125
+ }
126
+ }
127
+
128
+ console.log(
129
+ '[INFO] [generateCode] STATUS=BACKUP | Backing up existing hook files...'
130
+ );
131
+ collectHookBackups(outputPath);
132
+
133
+ console.log(
134
+ '[INFO] [generateCode] STATUS=CLEANUP | Removing old generatedCode directories...'
116
135
  );
117
136
  await fs.promises.rm(generatedCodePath, {
118
137
  recursive: true,
@@ -122,10 +141,10 @@ console.log(
122
141
  path.join(outputPath, 'app', 'sls_yaml', 'generatedCode'),
123
142
  { recursive: true, force: true }
124
143
  );
125
- await fs.promises.rm(path.join(outputPath, 'resource'), {
126
- recursive: true,
127
- force: true
128
- });
144
+ await fs.promises.rm(
145
+ path.join(outputPath, 'resource', 'sls_yaml', 'generatedCode'),
146
+ { recursive: true, force: true }
147
+ );
129
148
 
130
149
  policyRegistry.clear();
131
150
 
@@ -150,8 +169,6 @@ console.log(
150
169
  console.log('[INFO] [generateCode] STATUS=VALIDATING | Validating Flows...');
151
170
  validateFlowsForGeneration(allSchemas.flowsForGeneration);
152
171
 
153
- const generatorOptions = { outputPath: options.outputPath || rootPath };
154
-
155
172
  // 2. Generation Pipeline
156
173
  await generateEndpointsFlow(allSchemas, generatorOptions);
157
174
  await generateFlowMainFunction(allSchemas, generatorOptions);
@@ -161,11 +178,19 @@ console.log(
161
178
  await generateFlowResourceYaml(allSchemas, generatorOptions);
162
179
  await generateRbacFlows(allSchemas, generatorOptions);
163
180
  await generateRelationshipFlows(allSchemas, generatorOptions);
164
- await generateWebSocket(allSchemas.flowsForGeneration, '', generatorOptions.outputPath);
165
- await generateRegisterFlow(allSchemas.flowsForGeneration, '', generatorOptions.outputPath);
181
+ await generateWebSocket(
182
+ allSchemas.flowsForGeneration,
183
+ '',
184
+ generatorOptions.outputPath
185
+ );
186
+ await generateRegisterFlow(
187
+ allSchemas.flowsForGeneration,
188
+ '',
189
+ generatorOptions.outputPath
190
+ );
166
191
 
167
192
  // Call FunctionYamlGenerator after all Handlers have been generated
168
- await generateFunctionYaml(allSchemas, options);
193
+ await generateFunctionYaml(allSchemas, generatorOptions);
169
194
  await generateDynamoDBTables(allSchemas, generatorOptions);
170
195
  await generateFindData(allSchemas, generatorOptions);
171
196
  await generateCodeLibs(generatorOptions);
@@ -178,69 +203,76 @@ console.log(
178
203
  await generateInitialSetup(allSchemas, generatorOptions);
179
204
 
180
205
  // 3. Hook Integration
181
- console.log(
182
- '[INFO] [generateCode] STATUS=HOOKS | Processing hook folders beside source folders...'
183
- );
184
-
185
- function processSourceHooks(currentDir) {
186
- if (!fs.existsSync(currentDir)) return;
187
-
188
- const items = fs.readdirSync(currentDir, { withFileTypes: true });
189
- const hasSource = items.some((item) => item.isDirectory() && item.name === 'source');
190
- const hasHook = items.some((item) => item.isDirectory() && item.name === 'hook');
191
-
192
- if (hasSource && hasHook) {
193
- const sourcePath = path.join(currentDir, 'source');
194
- const hookPath = path.join(currentDir, 'hook');
195
- const hookItems = fs.readdirSync(hookPath, { withFileTypes: true });
196
-
197
- for (const hookItem of hookItems) {
198
- if (!hookItem.isFile()) continue;
199
-
200
- const hookFile = path.join(hookPath, hookItem.name);
201
- const sourceFile = path.join(sourcePath, hookItem.name);
202
-
203
- if (!fs.existsSync(sourceFile)) {
204
- fs.copyFileSync(hookFile, sourceFile);
205
- console.log(
206
- `[INFO] [generateCode] HOOK APPLIED: Created ${hookItem.name} from hook.`
207
- );
208
- continue;
209
- }
210
-
211
- const mergedContent = mergeHookIntoSource(
212
- fs.readFileSync(sourceFile, 'utf8'),
213
- fs.readFileSync(hookFile, 'utf8'),
214
- sourceFile
215
- );
216
- fs.writeFileSync(sourceFile, mergedContent);
217
- console.log(
218
- `[INFO] [generateCode] HOOK APPLIED: Merged ${hookItem.name} into source.`
219
- );
220
- }
221
- } else if (hasSource) {
222
- fs.mkdirSync(path.join(currentDir, 'hook'), { recursive: true });
223
- }
224
-
225
- for (const item of items) {
226
- if (!item.isDirectory() || item.name === 'source' || item.name === 'hook') continue;
227
- processSourceHooks(path.join(currentDir, item.name));
228
- }
229
- }
230
-
231
- // Restore backed-up hooks
232
- if (hookDirs.size > 0 || hookBackups.length > 0) {
233
- console.log(`[INFO] [generateCode] STATUS=RESTORE | Restoring ${hookBackups.length} hook files...`);
234
- for (const relativeHookDir of hookDirs) {
235
- fs.mkdirSync(path.join(outputPath, relativeHookDir), { recursive: true });
236
- }
237
- for (const backup of hookBackups) {
238
- const hookDir = path.join(outputPath, backup.relativePath);
239
- fs.writeFileSync(path.join(hookDir, backup.name), backup.content);
240
- }
241
- }
242
-
243
- processSourceHooks(generatorOptions.outputPath);
206
+ console.log(
207
+ '[INFO] [generateCode] STATUS=HOOKS | Processing hook folders beside source folders...'
208
+ );
209
+
210
+ function processSourceHooks(currentDir) {
211
+ if (!fs.existsSync(currentDir)) return;
212
+
213
+ const items = fs.readdirSync(currentDir, { withFileTypes: true });
214
+ const hasSource = items.some(
215
+ item => item.isDirectory() && item.name === 'source'
216
+ );
217
+ const hasHook = items.some(
218
+ item => item.isDirectory() && item.name === 'hook'
219
+ );
220
+
221
+ if (hasSource && hasHook) {
222
+ const sourcePath = path.join(currentDir, 'source');
223
+ const hookPath = path.join(currentDir, 'hook');
224
+ const hookItems = fs.readdirSync(hookPath, { withFileTypes: true });
225
+
226
+ for (const hookItem of hookItems) {
227
+ if (!hookItem.isFile()) continue;
228
+
229
+ const hookFile = path.join(hookPath, hookItem.name);
230
+ const sourceFile = path.join(sourcePath, hookItem.name);
231
+
232
+ if (!fs.existsSync(sourceFile)) {
233
+ fs.copyFileSync(hookFile, sourceFile);
234
+ console.log(
235
+ `[INFO] [generateCode] HOOK APPLIED: Created ${hookItem.name} from hook.`
236
+ );
237
+ continue;
238
+ }
239
+
240
+ const mergedContent = mergeHookIntoSource(
241
+ fs.readFileSync(sourceFile, 'utf8'),
242
+ fs.readFileSync(hookFile, 'utf8'),
243
+ sourceFile
244
+ );
245
+ fs.writeFileSync(sourceFile, mergedContent);
246
+ console.log(
247
+ `[INFO] [generateCode] HOOK APPLIED: Merged ${hookItem.name} into source.`
248
+ );
249
+ }
250
+ } else if (hasSource) {
251
+ fs.mkdirSync(path.join(currentDir, 'hook'), { recursive: true });
252
+ }
253
+
254
+ for (const item of items) {
255
+ if (!item.isDirectory() || item.name === 'source' || item.name === 'hook')
256
+ continue;
257
+ processSourceHooks(path.join(currentDir, item.name));
258
+ }
259
+ }
260
+
261
+ // Restore backed-up hooks
262
+ if (hookDirs.size > 0 || hookBackups.length > 0) {
263
+ console.log(
264
+ `[INFO] [generateCode] STATUS=RESTORE | Restoring ${hookBackups.length} hook files...`
265
+ );
266
+ for (const relativeHookDir of hookDirs) {
267
+ fs.mkdirSync(path.join(outputPath, relativeHookDir), { recursive: true });
268
+ }
269
+ for (const backup of hookBackups) {
270
+ const hookDir = path.join(outputPath, backup.relativePath);
271
+ fs.writeFileSync(path.join(hookDir, backup.name), backup.content);
272
+ }
273
+ }
274
+
275
+ processSourceHooks(generatorOptions.outputPath);
244
276
 
245
277
  console.log(
246
278
  '[INFO] [generateCode] STATUS=FINISHED | Code generation complete.'
@@ -21,7 +21,7 @@ export async function generateSchema(rootPath, options) {
21
21
  );
22
22
 
23
23
  // Parse service config to get serviceTag
24
- const configPath = path.join(rootPath, 'config', 'serverless.config.yml');
24
+ const configPath = options?.configPath || path.join(rootPath, 'config', 'serverless.config.yml');
25
25
  let serviceTag = 'unknownService';
26
26
  try {
27
27
  const serviceConfigStr = fs.readFileSync(configPath, 'utf8');
@@ -41,7 +41,6 @@ export async function generateDynamicFlowSchemas(
41
41
  return;
42
42
  }
43
43
 
44
- // Validate event types in custom flow schemas
45
44
  const validMainEvents = [
46
45
  'ownTopic',
47
46
  'extTopic',
@@ -61,8 +61,8 @@ export async function generateRbacFlowSchemas(hydratedObjectData, options) {
61
61
 
62
62
  for (const def of rbacFlowDefinitions) {
63
63
  const flowTag = def.flowTag;
64
- // Use the old naming convention: {objectType}{flowTag}Flow.js
65
- const filePath = path.join(schemasOutputDir, `${objectType}${flowTag}Flow.js`);
64
+ // Use flowTag as filename directly
65
+ const filePath = path.join(schemasOutputDir, `${flowTag}.js`);
66
66
 
67
67
  const eventsArrayStr = JSON.stringify(def.eventNames).replace(/"/g, "'");
68
68
 
@@ -76,6 +76,20 @@ export async function generateRbacFlowSchemas(hydratedObjectData, options) {
76
76
  await fs.writeFile(filePath, fileContent, 'utf-8');
77
77
  generatedCount++;
78
78
  }
79
+
80
+ // Generate specific UserRbacFlow
81
+ const userRbacFlowTag = `${objectType.charAt(0).toUpperCase() + objectType.slice(1)}RbacFlow`;
82
+ const userRbacFilePath = path.join(schemasOutputDir, `${userRbacFlowTag}.js`);
83
+ const userRbacTemplatePath = path.join(__dirname, 'templates', 'UserRbacFlowSchemaTemplate.ejs');
84
+ const userRbacTemplateString = await fs.readFile(userRbacTemplatePath, 'utf-8');
85
+ const userRbacContent = ejs.render(userRbacTemplateString, {
86
+ flowTag: userRbacFlowTag,
87
+ serviceTag: options.serviceTag,
88
+ objectType: objectType
89
+ });
90
+
91
+ await fs.writeFile(userRbacFilePath, userRbacContent, 'utf-8');
92
+ generatedCount++;
79
93
  }
80
94
 
81
95
  console.log(
@@ -23,7 +23,8 @@ export default {
23
23
  },
24
24
  <% if (hasBeforeLogicalStep) { %>
25
25
  {
26
- stepName: 'beforeLogical',
26
+ stepName: 'BeforeLogical',
27
+ event: ['sqs'],
27
28
  properties: [],
28
29
  messageAttributes: ['userId', 'correlationId']
29
30
  },
@@ -31,6 +32,7 @@ export default {
31
32
  <% if (['Create', 'Update', 'Delete'].includes(action)) { %>
32
33
  {
33
34
  stepName: 'Complete',
35
+ event: ['sqs'],
34
36
  properties: [],
35
37
  messageAttributes: ['userId', 'correlationId']
36
38
  }
@@ -5,6 +5,7 @@
5
5
  */
6
6
  export default {
7
7
  flowTag: '<%= flowTag %>',
8
+ fileName: 'flow-rbac',
8
9
  initiateBy: 'system',
9
10
  statusType: 'none',
10
11
  event: <%- events %>,
@@ -22,11 +22,12 @@ export default {
22
22
  messageAttributes: ['userId', 'correlationId']
23
23
  }
24
24
  <% if (hasCompleteStep) { %>,
25
- {
26
- stepName: 'Complete',
27
- properties: [],
28
- messageAttributes: ['userId', 'correlationId']
29
- }
25
+ {
26
+ stepName: 'Complete',
27
+ event: ['sqs'],
28
+ properties: [],
29
+ messageAttributes: ['userId', 'correlationId']
30
+ }
30
31
  <% } %>
31
32
  ]
32
33
  };
@@ -0,0 +1,22 @@
1
+ export default {
2
+ flowTag: '<%= flowTag %>',
3
+ fileName: 'flow-rbac',
4
+ objType: {
5
+ serviceTag: '<%= serviceTag %>',
6
+ objectType: '<%= objectType %>'
7
+ },
8
+ event: ['lambdaSyncInv'],
9
+ initiateBy: 'system',
10
+ handleObj: 'one',
11
+ statusType: 'none',
12
+ stepMessageAttributes: {
13
+ userId: { propertyName: 'x-correlation-base-user-id', type: 'string' },
14
+ correlationId: { propertyName: 'x-correlation-id', type: 'string' }
15
+ },
16
+ steps: [
17
+ {
18
+ stepName: 'InTag',
19
+ messageAttributes: ['userId', 'correlationId']
20
+ }
21
+ ]
22
+ };