@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
@@ -2,21 +2,41 @@ import { buildGenerationPlan } from '../../plan/buildGenerationPlan.js';
2
2
  import { commitArtifacts } from '../../output/commitArtifacts.js';
3
3
  import { compileProject } from '../../compile/compileProject.js';
4
4
  import { loadLocalSchemaDirectory } from '../../compile/loadSchemas.js';
5
- import { customFlowApplicationManagedPaths, emitCustomFlowApplicationArtifacts } from './emitCustomFlowApplicationArtifacts.js';
6
- import { emitSystemWebSocketArtifacts, hasSystemWebSocket, systemWebSocketManagedPaths } from '../system/emitSystemWebSocketArtifacts.js';
5
+ import {
6
+ customFlowApplicationManagedPaths,
7
+ emitCustomFlowApplicationArtifacts
8
+ } from './emitCustomFlowApplicationArtifacts.js';
9
+ import {
10
+ emitSystemWebSocketArtifacts,
11
+ hasSystemWebSocket,
12
+ systemWebSocketManagedPaths
13
+ } from '../system/emitSystemWebSocketArtifacts.js';
7
14
 
8
- export async function generateCustomFlowApplicationArtifacts(rootPath, options = {}) {
15
+ export async function generateCustomFlowApplicationArtifacts(
16
+ rootPath,
17
+ options = {}
18
+ ) {
9
19
  const project = compileProject({ ...options, rootPath });
10
20
  const [flows, objects] = await Promise.all([
11
21
  loadLocalSchemaDirectory(project, 'FlowSchemas'),
12
22
  loadLocalSchemaDirectory(project, 'ObjectSchemas')
13
23
  ]);
14
24
  const system = await emitSystemWebSocketArtifacts(flows);
15
- const custom = await emitCustomFlowApplicationArtifacts(flows, { systemFunctions: system.functions, objects });
25
+ const custom = await emitCustomFlowApplicationArtifacts(flows, {
26
+ systemFunctions: system.functions,
27
+ objects
28
+ });
16
29
  const artifacts = [...system.artifacts, ...custom];
17
- const files = await commitArtifacts(buildGenerationPlan(project, artifacts, {
18
- managedPaths: [...systemWebSocketManagedPaths(), ...customFlowApplicationManagedPaths(flows, { includeYaml: hasSystemWebSocket(flows) })],
19
- managedScope: 'custom-flow-application'
20
- }));
30
+ const files = await commitArtifacts(
31
+ buildGenerationPlan(project, artifacts, {
32
+ managedPaths: [
33
+ ...systemWebSocketManagedPaths(),
34
+ ...customFlowApplicationManagedPaths(flows, {
35
+ includeYaml: hasSystemWebSocket(flows)
36
+ })
37
+ ],
38
+ managedScope: 'custom-flow-application'
39
+ })
40
+ );
21
41
  return { project, files };
22
42
  }
@@ -20,12 +20,12 @@ import {
20
20
  response
21
21
  } from '@izara_project/izara-middleware';
22
22
  import Logger from '@izara_project/izara-core-library-logger';
23
- import recordHandlerSharedLib from '@izara_project/izara-core-library-record-handler';
23
+ import { recordHandlerS3SharedLib } from '@izara_project/izara-core-library-record-handler';
24
24
 
25
25
  import <%- functionName %> from './<%- mainFileName %>.js';
26
26
 
27
27
  // S3 event validator (record.body shape differs from SNS/SQS — uses event.Records[0].s3)
28
- middleware.setValidatorSchema(recordHandlerSharedLib.baseValidatorSchemaS3());
28
+ middleware.setValidatorSchema(recordHandlerS3SharedLib.baseValidatorSchemaS3());
29
29
 
30
30
  /**
31
31
  * GENERATED HANDLER: S3 Entry Point (Flow: <%- flowTag %>)
@@ -23,7 +23,7 @@ import Logger from '@izara_project/izara-core-library-logger';
23
23
 
24
24
  import <%= functionName %> from './<%= functionName %>_Main.js';
25
25
 
26
- middleware.setServiceSchema(recordHandlerSharedLib.baseValidatorSchema());
26
+ middleware.setValidatorSchema(recordHandlerSharedLib.baseValidatorSchema());
27
27
 
28
28
  let perRecordsValidatorSchema = {
29
29
  type: 'object',
@@ -1,135 +1,308 @@
1
- export function createSqsFunctionYamlArtifact({ functionName, handlerPath, roleName, queueName, fileName, flowTag, flowStepName, targetCompleteStepName }) {
2
- if (![functionName, handlerPath, roleName, queueName, fileName].every(value => typeof value === 'string' && value !== '')) {
3
- throw new TypeError('Function descriptor must include functionName, handlerPath, roleName, queueName, and fileName');
1
+ import { readFileSync } from 'node:fs';
2
+ import ejsLib from 'ejs';
3
+
4
+ const TEMPLATE_URL = new URL('./templates/', import.meta.url);
5
+
6
+ function _renderFunctionTemplate(templateName, data = {}) {
7
+ const content = readFileSync(new URL(templateName, TEMPLATE_URL), 'utf8');
8
+ return ejsLib.render(content, data);
9
+ }
10
+
11
+ export function createSqsFunctionYamlArtifact({
12
+ functionName,
13
+ handlerPath,
14
+ roleName,
15
+ queueName,
16
+ fileName,
17
+ flowTag,
18
+ flowStepName,
19
+ targetCompleteStepName
20
+ }) {
21
+ if (
22
+ ![functionName, handlerPath, roleName, queueName, fileName].every(
23
+ (value) => typeof value === 'string' && value !== ''
24
+ )
25
+ ) {
26
+ throw new TypeError(
27
+ 'Function descriptor must include functionName, handlerPath, roleName, queueName, and fileName'
28
+ );
4
29
  }
5
30
  return {
6
31
  path: `app/sls_yaml/generatedCode/source/${fileName}`,
7
- content: renderSqsFunctionYaml({ functionName, handlerPath, roleName, queueName, flowTag, flowStepName })
32
+ content: renderSqsFunctionYaml({
33
+ functionName,
34
+ handlerPath,
35
+ roleName,
36
+ queueName,
37
+ flowTag,
38
+ flowStepName,
39
+ targetCompleteStepName
40
+ })
8
41
  };
9
42
  }
10
43
 
11
- export function renderSqsFunctionYaml({ functionName, handlerPath, roleName, queueName, flowTag, flowStepName, targetCompleteStepName }) {
12
- if (![functionName, handlerPath, roleName, queueName].every(value => typeof value === 'string' && value !== '')) {
13
- throw new TypeError('SQS function descriptor must include functionName, handlerPath, roleName, and queueName');
44
+ export function renderSqsFunctionYaml({
45
+ functionName,
46
+ handlerPath,
47
+ roleName,
48
+ queueName,
49
+ flowTag,
50
+ flowStepName,
51
+ targetCompleteStepName
52
+ }) {
53
+ if (
54
+ ![functionName, handlerPath, roleName, queueName].every(
55
+ (value) => typeof value === 'string' && value !== ''
56
+ )
57
+ ) {
58
+ throw new TypeError(
59
+ 'SQS function descriptor must include functionName, handlerPath, roleName, and queueName'
60
+ );
14
61
  }
15
- return `${functionName}:
16
- handler: ${handlerPath}
17
- name: \${self:custom.iz_resourcePrefix}${functionName}
18
- role: ${roleName}
19
- ${environmentSetting(functionName, flowTag, flowStepName, targetCompleteStepName)}${functionSetting(functionName)}
20
- events:
21
- - sqs:
22
- arn: arn:aws:sqs:\${self:custom.iz_region}:\${self:custom.iz_accountId}:\${self:custom.iz_resourcePrefix}${queueName}
23
- batchSize: 10
24
- ${completionFilter(functionName)}`;
62
+ return _renderFunctionTemplate('SqsFunction_Yaml.ejs', {
63
+ functionName,
64
+ handlerPath,
65
+ roleName,
66
+ queueName,
67
+ environmentSetting: _environmentSetting(
68
+ functionName,
69
+ flowTag,
70
+ flowStepName,
71
+ targetCompleteStepName
72
+ ),
73
+ functionSetting: _functionSetting(functionName),
74
+ sqsFilterPatterns: _sqsFilterPatterns(functionName)
75
+ });
25
76
  }
26
77
 
27
- export function renderApiFunctionYaml({ functionName, handlerPath, roleName, routes = [], flowTag, flowStepName }) {
78
+ export function renderApiFunctionYaml({
79
+ functionName,
80
+ handlerPath,
81
+ roleName,
82
+ routes = [],
83
+ flowTag,
84
+ flowStepName
85
+ }) {
28
86
  if (!Array.isArray(routes)) {
29
87
  throw new TypeError('API function routes must be an array');
30
88
  }
31
- const routeEvents = routes.flatMap(({ path, upperName }) => {
32
- if (typeof path !== 'string' || path === '' || typeof upperName !== 'string' || upperName === '') {
33
- throw new TypeError('API function routes must include path and upperName');
34
- }
35
- return [
36
- ` - httpApi:\n path: ${path}\n method: post\n #<#${upperName}AppLevelAuthorizer#>\n # authorizer: authorizerServiceSchema\n #<#/${upperName}AppLevelAuthorizer#>`,
37
- ` - httpApi:\n path: ${path}/{targetUserId}\n method: post\n #<#${upperName}UserLevelAuthorizer#>\n # authorizer: authorizerIdentifiers\n #<#/${upperName}UserLevelAuthorizer#>`
38
- ];
39
- }).join('\n');
40
- return `${functionName}:
41
- handler: ${handlerPath}
42
- name: \${self:custom.iz_resourcePrefix}${functionName}
43
- role: ${roleName}
44
- ${environmentSetting(functionName, flowTag, flowStepName)}${functionSetting(functionName)}
45
- events:
46
- ${routeEvents ? `${routeEvents}\n` : ''}`;
89
+ const routeEvents = routes
90
+ .flatMap(({ path, upperName }) => {
91
+ if (
92
+ typeof path !== 'string' ||
93
+ path === '' ||
94
+ typeof upperName !== 'string' ||
95
+ upperName === ''
96
+ ) {
97
+ throw new TypeError(
98
+ 'API function routes must include path and upperName'
99
+ );
100
+ }
101
+ return [
102
+ ` - httpApi:\n path: ${path}\n method: post\n #<#${upperName}AppLevelAuthorizer#>\n # authorizer: authorizerServiceSchema\n #<#/${upperName}AppLevelAuthorizer#>`,
103
+ ` - httpApi:\n path: ${path}/{targetUserId}\n method: post\n #<#${upperName}UserLevelAuthorizer#>\n # authorizer: authorizerIdentifiers\n #<#/${upperName}UserLevelAuthorizer#>`
104
+ ];
105
+ })
106
+ .join('\n');
107
+ let eventsSection = '';
108
+ if (routeEvents) {
109
+ eventsSection = `${routeEvents}\n`;
110
+ }
111
+ return _renderFunctionTemplate('ApiFunction_Yaml.ejs', {
112
+ functionName,
113
+ handlerPath,
114
+ roleName,
115
+ environmentSetting: _environmentSetting(
116
+ functionName,
117
+ flowTag,
118
+ flowStepName
119
+ ),
120
+ functionSetting: _functionSetting(functionName),
121
+ eventsSection
122
+ });
47
123
  }
48
124
 
49
- export function renderWbsFunctionYaml({ functionName, handlerPath, roleName, routeName, flowTag, flowStepName }) {
50
- if (![functionName, handlerPath, roleName, routeName].every(value => typeof value === 'string' && value !== '')) {
51
- throw new TypeError('WebSocket function descriptor must include functionName, handlerPath, roleName, and routeName');
125
+ export function renderWbsFunctionYaml({
126
+ functionName,
127
+ handlerPath,
128
+ roleName,
129
+ routeName,
130
+ flowTag,
131
+ flowStepName
132
+ }) {
133
+ if (
134
+ ![functionName, handlerPath, roleName, routeName].every(
135
+ (value) => typeof value === 'string' && value !== ''
136
+ )
137
+ ) {
138
+ throw new TypeError(
139
+ 'WebSocket function descriptor must include functionName, handlerPath, roleName, and routeName'
140
+ );
52
141
  }
53
- return `${functionName}:
54
- handler: ${handlerPath}
55
- name: \${self:custom.iz_resourcePrefix}${functionName}
56
- role: ${roleName}
57
- ${environmentSetting(functionName, flowTag, flowStepName)}${functionSetting(functionName)}
58
- events:
59
- - websocket:
60
- route: ${routeName}
61
- # authorizer: \${self:custom.iz_authorizerAppLevel}
62
- # identifierResource: 'route.request.header.Auth'
63
- `;
142
+ return _renderFunctionTemplate('WbsFunction_Yaml.ejs', {
143
+ functionName,
144
+ handlerPath,
145
+ roleName,
146
+ routeName,
147
+ environmentSetting: _environmentSetting(
148
+ functionName,
149
+ flowTag,
150
+ flowStepName
151
+ ),
152
+ functionSetting: _functionSetting(functionName)
153
+ });
64
154
  }
65
155
 
66
- export function renderInvFunctionYaml({ functionName, handlerPath, roleName, flowTag, flowStepName }) {
67
- return `${functionName}:
68
- handler: ${handlerPath}
69
- name: \${self:custom.iz_resourcePrefix}${functionName}
70
- role: ${roleName}
71
- ${environmentSetting(functionName, flowTag, flowStepName)}${functionSetting(functionName)}
72
- `;
156
+ export function renderInvFunctionYaml({
157
+ functionName,
158
+ handlerPath,
159
+ roleName,
160
+ flowTag,
161
+ flowStepName
162
+ }) {
163
+ return _renderFunctionTemplate('InvFunction_Yaml.ejs', {
164
+ functionName,
165
+ handlerPath,
166
+ roleName,
167
+ environmentSetting: _environmentSetting(
168
+ functionName,
169
+ flowTag,
170
+ flowStepName
171
+ ),
172
+ functionSetting: _functionSetting(functionName)
173
+ });
73
174
  }
74
175
 
75
- export function renderS3FunctionYaml({ functionName, handlerPath, roleName, bucketName, flowTag, flowStepName }) {
76
- return `${functionName}:
77
- handler: ${handlerPath}
78
- name: \${self:custom.iz_resourcePrefix}${functionName}
79
- role: ${roleName}
80
- ${environmentSetting(functionName, flowTag, flowStepName)}${functionSetting(functionName)}
81
- events:
82
- - s3:
83
- bucket: ${bucketName}
84
- event: s3:ObjectCreated:*
85
- existing: true
86
- rules:
87
- #<#${functionName}rules#>
88
- #<#/${functionName}rules#>
89
- - prefix: uploads/
90
- - suffix: .csv
91
- forceDeploy: true
92
- `;
176
+ export function renderS3FunctionYaml({
177
+ functionName,
178
+ handlerPath,
179
+ roleName,
180
+ bucketName,
181
+ flowTag,
182
+ flowStepName
183
+ }) {
184
+ return _renderFunctionTemplate('S3Function_Yaml.ejs', {
185
+ functionName,
186
+ handlerPath,
187
+ roleName,
188
+ bucketName,
189
+ environmentSetting: _environmentSetting(
190
+ functionName,
191
+ flowTag,
192
+ flowStepName
193
+ ),
194
+ functionSetting: _functionSetting(functionName)
195
+ });
93
196
  }
94
197
 
95
- export function renderEventBridgeFunctionYaml({ functionName, handlerPath, roleName, flowTag, flowStepName, schedules = [] }) {
96
- if (![functionName, handlerPath, roleName, flowTag].every(value => typeof value === 'string' && value !== '') || !Array.isArray(schedules)) {
97
- throw new TypeError('EventBridge function descriptor must include functionName, handlerPath, roleName, flowTag, and schedules');
198
+ export function renderEventBridgeFunctionYaml({
199
+ functionName,
200
+ handlerPath,
201
+ roleName,
202
+ flowTag,
203
+ flowStepName,
204
+ schedules = []
205
+ }) {
206
+ if (
207
+ ![functionName, handlerPath, roleName, flowTag].every(
208
+ (value) => typeof value === 'string' && value !== ''
209
+ ) ||
210
+ !Array.isArray(schedules)
211
+ ) {
212
+ throw new TypeError(
213
+ 'EventBridge function descriptor must include functionName, handlerPath, roleName, flowTag, and schedules'
214
+ );
98
215
  }
99
- if (!schedules.every(schedule => (
100
- typeof schedule?.name === 'string' && schedule.name !== '' &&
101
- Array.isArray(schedule.rate) && typeof schedule.rate[0] === 'string' && schedule.rate[0] !== ''
102
- ))) {
103
- throw new TypeError('Each EventBridge schedule must include a name and first rate value');
216
+ if (
217
+ !schedules.every(
218
+ (schedule) =>
219
+ typeof schedule?.name === 'string' &&
220
+ schedule.name !== '' &&
221
+ Array.isArray(schedule.rate) &&
222
+ typeof schedule.rate[0] === 'string' &&
223
+ schedule.rate[0] !== ''
224
+ )
225
+ ) {
226
+ throw new TypeError(
227
+ 'Each EventBridge schedule must include a name and first rate value'
228
+ );
104
229
  }
105
- return `\${self:custom.iz_resourcePrefix}${functionName}:
106
- handler: ${handlerPath}
107
- role: ${roleName}
108
- ${environmentSetting(functionName, flowTag, flowStepName)}${functionSetting(functionName)}
109
- description: ${flowTag} (EventBridge Schedule)
110
- ${schedules.length === 0 ? '' : ` events:\n${schedules.map(schedule => ` - schedule:\n name: \${self:custom.iz_resourcePrefix}${schedule.name}\n description: '${schedule.description ?? ''}'\n rate: ${schedule.rate?.[0]}\n enabled: true`).join('\n')}\n`}`;
230
+ let scheduleEventsSection = '';
231
+ if (schedules.length > 0) {
232
+ const renderedSchedules = schedules
233
+ .map((schedule) => {
234
+ let desc = '';
235
+ if (schedule.description) {
236
+ desc = schedule.description;
237
+ }
238
+ return ` - schedule:\n name: \${self:custom.iz_resourcePrefix}${schedule.name}\n description: '${desc}'\n rate: ${schedule.rate[0]}\n enabled: true`;
239
+ })
240
+ .join('\n');
241
+ scheduleEventsSection = ` events:\n${renderedSchedules}\n`;
242
+ }
243
+ return _renderFunctionTemplate('EventBridgeFunction_Yaml.ejs', {
244
+ functionName,
245
+ handlerPath,
246
+ roleName,
247
+ flowTag,
248
+ environmentSetting: _environmentSetting(
249
+ functionName,
250
+ flowTag,
251
+ flowStepName
252
+ ),
253
+ functionSetting: _functionSetting(functionName),
254
+ scheduleEventsSection
255
+ });
111
256
  }
112
257
 
113
- function environmentSetting(functionName, flowTag, flowStepName, targetCompleteStepName) {
114
- if (flowTag === undefined && flowStepName === undefined && targetCompleteStepName === undefined) return '';
258
+ function _environmentSetting(
259
+ functionName,
260
+ flowTag,
261
+ flowStepName,
262
+ targetCompleteStepName
263
+ ) {
264
+ if (
265
+ flowTag === undefined &&
266
+ flowStepName === undefined &&
267
+ targetCompleteStepName === undefined
268
+ ) {
269
+ return '';
270
+ }
115
271
  let envs = [];
116
- if (flowTag !== undefined) envs.push(` iz_flowTag: ${flowTag === '' ? "''" : flowTag}`);
117
- if (flowStepName !== undefined) envs.push(` iz_flowStepName: ${flowStepName === '' ? "''" : flowStepName}`);
118
- if (targetCompleteStepName !== undefined) envs.push(` iz_targetCompleteStepName: ${flowTag}${targetCompleteStepName}`);
119
-
120
- if (envs.length === 0) return '';
272
+ if (flowTag !== undefined) {
273
+ let flowTagVal = "''";
274
+ if (flowTag !== '') {
275
+ flowTagVal = flowTag;
276
+ }
277
+ envs.push(` iz_flowTag: ${flowTagVal}`);
278
+ }
279
+ if (flowStepName !== undefined) {
280
+ let flowStepNameVal = "''";
281
+ if (flowStepName !== '') {
282
+ flowStepNameVal = flowStepName;
283
+ }
284
+ envs.push(` iz_flowStepName: ${flowStepNameVal}`);
285
+ }
286
+ if (targetCompleteStepName !== undefined) {
287
+ envs.push(
288
+ ` iz_targetCompleteStepName: ${flowTag}${targetCompleteStepName}`
289
+ );
290
+ }
291
+
292
+ if (envs.length === 0) {
293
+ return '';
294
+ }
121
295
  return ` environment:
122
296
  ${envs.join('\n')}
123
297
  #<#${functionName}Environment#>
124
298
  #<#/${functionName}Environment#>\n`;
125
299
  }
126
300
 
127
- function functionSetting(functionName) {
301
+ function _functionSetting(functionName) {
128
302
  return ` #<#${functionName}FunctionSetting#>\n #<#/${functionName}FunctionSetting#>`;
129
303
  }
130
304
 
131
- function completionFilter(functionName) {
132
- if (!functionName.endsWith('CompleteHdrSqs')) return '';
305
+ function _sqsFilterPatterns(functionName) {
133
306
  return ` filterPatterns:
134
307
  - body:
135
308
  MessageAttributes:
@@ -0,0 +1,7 @@
1
+ <%= functionName %>:
2
+ handler: <%= handlerPath %>
3
+ name: ${self:custom.iz_resourcePrefix}<%= functionName %>
4
+ role: <%= roleName %>
5
+ <%- environmentSetting %><%- functionSetting %>
6
+ events:
7
+ <%- eventsSection %>
@@ -0,0 +1,6 @@
1
+ ${self:custom.iz_resourcePrefix}<%= functionName %>:
2
+ handler: <%= handlerPath %>
3
+ role: <%= roleName %>
4
+ <%- environmentSetting %><%- functionSetting %>
5
+ description: <%= flowTag %> (EventBridge Schedule)
6
+ <%- scheduleEventsSection %>
@@ -0,0 +1,5 @@
1
+ <%= functionName %>:
2
+ handler: <%= handlerPath %>
3
+ name: ${self:custom.iz_resourcePrefix}<%= functionName %>
4
+ role: <%= roleName %>
5
+ <%- environmentSetting %><%- functionSetting %>
@@ -0,0 +1,16 @@
1
+ <%= functionName %>:
2
+ handler: <%= handlerPath %>
3
+ name: ${self:custom.iz_resourcePrefix}<%= functionName %>
4
+ role: <%= roleName %>
5
+ <%- environmentSetting %><%- functionSetting %>
6
+ events:
7
+ - s3:
8
+ bucket: <%= bucketName %>
9
+ event: s3:ObjectCreated:*
10
+ existing: true
11
+ rules:
12
+ #<#<%= functionName %>rules#>
13
+ #<#/<%= functionName %>rules#>
14
+ - prefix: uploads/
15
+ - suffix: .csv
16
+ forceDeploy: true
@@ -0,0 +1,10 @@
1
+ <%= functionName %>:
2
+ handler: <%= handlerPath %>
3
+ name: ${self:custom.iz_resourcePrefix}<%= functionName %>
4
+ role: <%= roleName %>
5
+ <%- environmentSetting %><%- functionSetting %>
6
+ events:
7
+ - sqs:
8
+ arn: arn:aws:sqs:${self:custom.iz_region}:${self:custom.iz_accountId}:${self:custom.iz_resourcePrefix}<%= queueName %>
9
+ batchSize: 10
10
+ <%- sqsFilterPatterns %>
@@ -0,0 +1,10 @@
1
+ <%= functionName %>:
2
+ handler: <%= handlerPath %>
3
+ name: ${self:custom.iz_resourcePrefix}<%= functionName %>
4
+ role: <%= roleName %>
5
+ <%- environmentSetting %><%- functionSetting %>
6
+ events:
7
+ - websocket:
8
+ route: <%= routeName %>
9
+ # authorizer: \${self:custom.iz_authorizerAppLevel}
10
+ # identifierResource: 'route.request.header.Auth'
@@ -1,4 +1,4 @@
1
- import ejs from 'ejs';
1
+ import ejsLib from 'ejs';
2
2
  import { readFile } from 'node:fs/promises';
3
3
  import { rbacFlowTag } from './rbacFlowTag.js';
4
4
 
@@ -16,22 +16,20 @@ const RBAC_FLOW_DEFINITIONS = [
16
16
  const TEMPLATE_URL = new URL('./templates/', import.meta.url);
17
17
 
18
18
  export const dynamicRbacFlowSchemaPaths = RBAC_FLOW_DEFINITIONS.map(
19
- ({ flowTag }) => `app/src/schemas/FlowSchemas/generateCode/FlowRbac/${flowTag}.js`
19
+ ({ flowTag }) =>
20
+ `app/src/schemas/FlowSchemas/generateCode/FlowRbac/${flowTag}.js`
20
21
  );
21
22
 
22
23
  export function rbacFlowSchemaManagedPaths(objects = []) {
23
24
  if (!Array.isArray(objects)) {
24
25
  throw new TypeError('objects must be an array');
25
26
  }
26
- return [
27
- ...dynamicRbacFlowSchemaPaths,
28
- ...objects
29
- .filter(hasRbacAddOn)
30
- .map(
31
- object =>
32
- `app/src/schemas/FlowSchemas/generateCode/FlowRbac/${rbacFlowTag(object)}.js`
33
- )
34
- ];
27
+ const rbacObjects = objects.filter(_hasRbacAddOn);
28
+ const rbacPaths = rbacObjects.map(
29
+ (object) =>
30
+ `app/src/schemas/FlowSchemas/generateCode/FlowRbac/${rbacFlowTag(object)}.js`
31
+ );
32
+ return [...dynamicRbacFlowSchemaPaths, ...rbacPaths];
35
33
  }
36
34
 
37
35
  export async function emitDynamicRbacFlowSchemas({ objects, serviceTag }) {
@@ -39,7 +37,7 @@ export async function emitDynamicRbacFlowSchemas({ objects, serviceTag }) {
39
37
  throw new TypeError('objects must be an array');
40
38
  }
41
39
 
42
- const rbacObjects = objects.filter(hasRbacAddOn);
40
+ const rbacObjects = objects.filter(_hasRbacAddOn);
43
41
  if (rbacObjects.length === 0) {
44
42
  return [];
45
43
  }
@@ -49,31 +47,31 @@ export async function emitDynamicRbacFlowSchemas({ objects, serviceTag }) {
49
47
  );
50
48
  }
51
49
 
52
- return Promise.all([
53
- ...RBAC_FLOW_DEFINITIONS.map(({ flowTag, event }) =>
54
- artifact(flowTag, createSharedRbacFlow(flowTag, event))
55
- ),
56
- ...rbacObjects.map(object => {
57
- const flowTag = rbacFlowTag(object);
58
- return artifact(
59
- flowTag,
60
- createUserRbacFlow(flowTag, serviceTag, object.objectType)
61
- );
62
- })
63
- ]);
50
+ const sharedArtifacts = RBAC_FLOW_DEFINITIONS.map(({ flowTag, event }) =>
51
+ _artifact(flowTag, _createSharedRbacFlow(flowTag, event))
52
+ );
53
+ const userArtifacts = rbacObjects.map((object) => {
54
+ const flowTag = rbacFlowTag(object);
55
+ return _artifact(
56
+ flowTag,
57
+ _createUserRbacFlow(flowTag, serviceTag, object.objectType)
58
+ );
59
+ });
60
+
61
+ return Promise.all([...sharedArtifacts, ...userArtifacts]);
64
62
  }
65
63
 
66
- function hasRbacAddOn(object) {
64
+ function _hasRbacAddOn(object) {
67
65
  return (
68
66
  Array.isArray(object?.addOnDataStructure) &&
69
- object.addOnDataStructure.some(addOn => addOn?.type === 'rbac')
67
+ object.addOnDataStructure.some((addOn) => addOn?.type === 'rbac')
70
68
  );
71
69
  }
72
70
 
73
- async function artifact(flowTag, flow) {
71
+ async function _artifact(flowTag, flow) {
74
72
  return {
75
73
  path: `app/src/schemas/FlowSchemas/generateCode/FlowRbac/${flowTag}.js`,
76
- content: ejs.render(
74
+ content: ejsLib.render(
77
75
  await readFile(
78
76
  new URL('DynamicRbacFlowSchema.ejs', TEMPLATE_URL),
79
77
  'utf8'
@@ -83,7 +81,7 @@ async function artifact(flowTag, flow) {
83
81
  };
84
82
  }
85
83
 
86
- function createSharedRbacFlow(flowTag, event) {
84
+ function _createSharedRbacFlow(flowTag, event) {
87
85
  return {
88
86
  flowTag,
89
87
  initiateBy: 'system',
@@ -107,7 +105,7 @@ function createSharedRbacFlow(flowTag, event) {
107
105
  };
108
106
  }
109
107
 
110
- function createUserRbacFlow(flowTag, serviceTag, objectType) {
108
+ function _createUserRbacFlow(flowTag, serviceTag, objectType) {
111
109
  return {
112
110
  flowTag,
113
111
  objType: { serviceTag, objectType },