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

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 (129) hide show
  1. package/package.json +1 -1
  2. package/scripts/format-ejs.js +36 -32
  3. package/src/compile/compileProject.js +26 -10
  4. package/src/compile/loadSchemas.js +122 -59
  5. package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +163 -0
  6. package/src/emit/coreFunction/templates/CoreFunction_Yaml.ejs +38 -0
  7. package/src/emit/coreFunction/templates/CoreResource_Yaml.ejs +235 -0
  8. package/src/emit/coreFunction/templates/GenerateSeedDataDynamo_HdrInv.ejs +16 -0
  9. package/src/emit/coreFunction/templates/GenerateSeedDataDynamo_Main.ejs +38 -0
  10. package/src/emit/coreFunction/templates/GenerateSeedDataGraphData_HdrInv.ejs +16 -0
  11. package/src/emit/coreFunction/templates/GenerateSeedDataGraphData_Main.ejs +32 -0
  12. package/src/emit/coreFunction/templates/GenerateSeedDataGraphSchema_HdrInv.ejs +16 -0
  13. package/src/emit/coreFunction/templates/GenerateSeedDataGraphSchema_Main.ejs +71 -0
  14. package/src/emit/coreFunction/templates/GeneratedGraphNodeSchemas.ejs +47 -0
  15. package/src/emit/coreFunction/templates/GeneratedGraphRelSchemas.ejs +27 -0
  16. package/src/emit/coreFunction/templates/GeneratedTableConfigs.ejs +34 -0
  17. package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +108 -0
  18. package/src/emit/coreFunction/templates/InitialSetup_HdrInv.ejs +12 -0
  19. package/src/emit/coreFunction/templates/InitialSetup_Main.ejs +51 -0
  20. package/src/emit/coreFunction/templates/RemoveSeedDataDynamo_HdrInv.ejs +16 -0
  21. package/src/emit/coreFunction/templates/RemoveSeedDataDynamo_Main.ejs +31 -0
  22. package/src/emit/coreFunction/templates/UploadSchema_HdrInv.ejs +37 -0
  23. package/src/emit/coreFunction/templates/UploadSchema_Main.ejs +52 -0
  24. package/src/emit/crud/emitCrudApplicationArtifacts.js +194 -41
  25. package/src/emit/crud/emitDynamicCrudFlowSchemas.js +34 -17
  26. package/src/emit/crud/generateCrudApplicationArtifacts.js +14 -6
  27. package/src/emit/crud/generateDynamicCrudFlowSchemas.js +4 -1
  28. package/src/emit/crud/templates/CreateEndpoint_Main.ejs +1 -1
  29. package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +1 -1
  30. package/src/emit/crud/templates/GetEndpoint_Main.ejs +2 -2
  31. package/src/emit/crud/templates/GetRangeEndpoint_Main.ejs +1 -1
  32. package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +1 -1
  33. package/src/emit/custom/customFlows.js +23 -13
  34. package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +535 -114
  35. package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +28 -8
  36. package/src/emit/custom/templates/FlowEndpoint_Main.ejs +2 -2
  37. package/src/emit/custom/templates/FlowStep_Main.ejs +1 -1
  38. package/src/emit/custom/templates/s3/CreateObject_Main.ejs +1 -1
  39. package/src/emit/custom/templates/s3/FlowHandler_HdrS3.ejs +2 -2
  40. package/src/emit/custom/templates/s3/ReservedLimit_HdrSqs.ejs +1 -1
  41. package/src/emit/custom/templates/s3/ReservedLimit_Main.ejs +1 -1
  42. package/src/emit/custom/templates/triggerCache/CheckTriggerCache_HdrSqs.ejs +4 -4
  43. package/src/emit/function/functionYamlArtifact.js +273 -97
  44. package/src/emit/function/templates/ApiFunction_Yaml.ejs +7 -0
  45. package/src/emit/function/templates/EventBridgeFunction_Yaml.ejs +6 -0
  46. package/src/emit/function/templates/InvFunction_Yaml.ejs +5 -0
  47. package/src/emit/function/templates/S3Function_Yaml.ejs +16 -0
  48. package/src/emit/function/templates/SqsFunction_Yaml.ejs +10 -0
  49. package/src/emit/function/templates/WbsFunction_Yaml.ejs +10 -0
  50. package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +28 -30
  51. package/src/emit/rbac/emitRbacApplicationArtifacts.js +6 -6
  52. package/src/emit/rbac/generateCreateTargetRoleHandler.js +6 -4
  53. package/src/emit/rbac/generateDynamicRbacFlowSchemas.js +8 -2
  54. package/src/emit/rbac/rbacFlowTag.js +3 -1
  55. package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +1 -1
  56. package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +26 -10
  57. package/src/emit/relationship/emitRelationshipApplicationArtifacts.js +189 -37
  58. package/src/emit/relationship/generateDynamicRelationshipFlowSchemas.js +8 -2
  59. package/src/emit/relationship/generateRelationshipApplicationArtifacts.js +15 -6
  60. package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +1 -1
  61. package/src/emit/relationship/templates/CreateRelationship_Main.ejs +1 -1
  62. package/src/emit/relationship/templates/DeleteRelationship_Main.ejs +1 -1
  63. package/src/emit/relationship/templates/GetRelationship_Main.ejs +1 -1
  64. package/src/emit/relationship/templates/MoveRelationship_Main.ejs +1 -1
  65. package/src/emit/relationship/templates/UpdateRelationship_Main.ejs +1 -1
  66. package/src/emit/resource/emitResourceArtifacts.js +249 -123
  67. package/src/emit/resource/generateResourceArtifacts.js +15 -6
  68. package/src/emit/resource/templates/DynamoDBTable_Yaml.ejs +18 -18
  69. package/src/emit/resource/templates/FlowOut_Yaml.ejs +5 -5
  70. package/src/emit/resource/templates/GeneratedLambdaRoleServiceConfig.ejs +10 -9
  71. package/src/emit/resource/templates/ResourceBeforeLogicalYaml.ejs +44 -44
  72. package/src/emit/resource/templates/ResourceSqsYaml.ejs +36 -36
  73. package/src/emit/resource/templates/ResourceYaml.ejs +48 -48
  74. package/src/emit/resource/templates/S3Subscription_Yaml.ejs +7 -0
  75. package/src/emit/resource/templates/SharedResource_Yaml.ejs +11 -11
  76. package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +122 -105
  77. package/src/emit/resource/templates/WebSocketSubscription_Yaml.ejs +7 -0
  78. package/src/emit/shared/templates/FindData_HdrSqs.ejs +120 -0
  79. package/src/emit/shared/templates/FindData_Main.ejs +345 -0
  80. package/src/emit/{crud → shared}/templates/FlowHandler_HdrApi.ejs +1 -1
  81. package/src/emit/{relationship → shared}/templates/FlowHandler_HdrDsq.ejs +4 -4
  82. package/src/emit/{crud → shared}/templates/FlowHandler_HdrInv.ejs +1 -1
  83. package/src/emit/{crud → shared}/templates/FlowHandler_HdrSqs.ejs +4 -4
  84. package/src/emit/shared/templates/PaginateProcessLogical_HdrDsq.ejs +162 -0
  85. package/src/emit/shared/templates/PaginateProcessLogical_HdrSqs.ejs +140 -0
  86. package/src/emit/shared/templates/PaginateProcessLogical_Main.ejs +268 -0
  87. package/src/emit/{relationship/templates/FlowHandler_HdrSqs.ejs → shared/templates/ProcessLogical_HdrSqs.ejs} +40 -55
  88. package/src/emit/shared/templates/ProcessLogical_Main.ejs +448 -0
  89. package/src/emit/system/emitSystemFindDataArtifacts.js +266 -0
  90. package/src/emit/system/emitSystemWebSocketArtifacts.js +61 -165
  91. package/src/emit/system/templates/WebSocketComplete_HdrSqs.ejs +48 -0
  92. package/src/emit/system/templates/WebSocketComplete_Main.ejs +91 -0
  93. package/src/emit/system/templates/WebSocketComplete_Yaml.ejs +19 -0
  94. package/src/emit/system/templates/WebSocketConnect.ejs +45 -0
  95. package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +11 -0
  96. package/src/generate.js +166 -36
  97. package/src/generateIntTest.js +76 -28
  98. package/src/generateResourceIntTest.js +35 -12
  99. package/src/generateResources/IntTest/generateResources/generateResources.js +5 -2
  100. package/src/generateResources/IntTest/generateResources/templateResources.ejs +18 -30
  101. package/src/generateResources/IntTest/generateTests/events/events.js +1 -1
  102. package/src/generateResources/IntTest/generateTests/events/templateEvents.ejs +13 -10
  103. package/src/generateResources/IntTest/generateTests/generateTemplate.js +2 -2
  104. package/src/generateResources/IntTest/generateTests/pathIntTest/pathIntTest.js +2 -1
  105. package/src/generateResources/IntTest/generateTests/pathIntTest/template.ejs +1 -3
  106. package/src/generateResources/IntTest/generateTests/tests/templateTests.ejs +1 -1
  107. package/src/generateResources/IntTest/generateTests/tests/tests.js +7 -3
  108. package/src/generateResources/IntTest/libs/{libs.js → IntTestGenerateLib.js} +34 -23
  109. package/src/generateResources/IntTest/upload/uploadIntTest.js +33 -19
  110. package/src/intTestGeneratorShared.js +15 -10
  111. package/src/output/commitArtifacts.js +99 -39
  112. package/src/output/mergeHooks.js +34 -21
  113. package/src/output/validateArtifacts.js +37 -27
  114. package/src/plan/buildGenerationPlan.js +24 -13
  115. package/test/core.test.js +117 -58
  116. package/test/createTargetRoleHandler.test.js +1 -1
  117. package/test/crudApplicationArtifacts.test.js +132 -31
  118. package/test/customFlowApplicationArtifacts.test.js +353 -71
  119. package/test/dynamicCrudFlowSchemas.test.js +74 -26
  120. package/test/dynamicRbacFlowSchemas.test.js +61 -14
  121. package/test/dynamicRelationshipFlowSchemas.test.js +65 -18
  122. package/test/functionYamlArtifact.test.js +67 -10
  123. package/test/intTestApi.test.js +9 -10
  124. package/test/publicApi.test.js +178 -36
  125. package/test/relationshipApplicationArtifacts.test.js +90 -19
  126. package/test/resourceArtifacts.test.js +173 -33
  127. package/src/emit/relationship/dynamicRelationshipFlowSchemaTemplate.js +0 -11
  128. package/src/emit/relationship/templates/FlowHandler_HdrApi.ejs +0 -59
  129. package/src/emit/relationship/templates/FlowHandler_HdrInv.ejs +0 -47
@@ -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
  }
@@ -58,7 +58,7 @@ const { createFlowTypeConcat } = utils;
58
58
  export default async function <%- typeof functionName !== 'undefined' ? functionName : upperCaseFlowTag %>(
59
59
  _izContext,
60
60
  requestParams,
61
- callingFlowConfig = {}
61
+ callingFlowConfig = {},
62
62
  //(<additionalParams>)
63
63
  //(</additionalParams>)
64
64
  ) {
@@ -88,7 +88,7 @@ export default async function <%- typeof functionName !== 'undefined' ? function
88
88
  createFlowTypeConcat(_izContext, {
89
89
  flowTag: '<%= flowTag %>',
90
90
  serviceTag: process.env.iz_serviceTag
91
- })
91
+ }),
92
92
  //(<storedCacheConfig>)
93
93
  //(</storedCacheConfig>)
94
94
  );
@@ -37,7 +37,7 @@ import { identifierUuid } from '@izara_project/izara-shared-core';
37
37
  export default async function <%= functionName %>(
38
38
  _izContext,
39
39
  requestParams,
40
- callingFlowConfig = {}
40
+ callingFlowConfig = {},
41
41
  //(<additionalParams>)
42
42
  //(</additionalParams>)
43
43
  ) {
@@ -51,7 +51,7 @@ const { TOPIC_NAME_GENERATE_CODE } = schemaConsts;
51
51
  export default async function createObject(
52
52
  _izContext,
53
53
  requestParams,
54
- callingFlowConfig = {}
54
+ callingFlowConfig = {},
55
55
  //(<additionalParams>)
56
56
  //(</additionalParams>)
57
57
  ) {
@@ -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',
@@ -56,7 +56,7 @@ export default async function reservedLimit(
56
56
  objInstanceFull,
57
57
  //(<additionalProperties>)
58
58
  //(</additionalProperties>)
59
- callingFlowConfig = {}
59
+ callingFlowConfig = {},
60
60
  ) {
61
61
  try {
62
62
  _izContext.logger.debug('----- reservedLimit event params ----- ', {
@@ -11,10 +11,10 @@ let perRecordsValidatorSchema = {
11
11
  properties: {
12
12
  <% startConfig.properties.forEach((prop, index) => { %> <%- prop.propertyName %>: {
13
13
  type: '<%- prop.type || 'string' %>'
14
- } /*__EJS_COMMA_6__*/
14
+ },
15
15
  <% }) %>
16
16
  },
17
- required: [<%- startConfig.properties.filter(p => p.required !== false).map(p => `'${p.propertyName}'`).join(', ') %>]
17
+ required: [<%- startConfig.properties.filter(p => p.required === true).map(p => `'${p.propertyName}'`).join(', ') %>]
18
18
  <% } -%>
19
19
  };
20
20
 
@@ -29,10 +29,10 @@ let messageAttributeValidatorSchema = {
29
29
  Value: { type: '<%- prop.type || 'string' %>' }
30
30
  },
31
31
  required: ['Type', 'Value']
32
- } /*__EJS_COMMA_14__*/
32
+ },
33
33
  <% }) %>
34
34
  },
35
- required: [<%- startConfig.messageAttributes.filter(p => p.required !== false).map(p => `'${p.propertyName}'`).join(', ') %>]
35
+ required: [<%- startConfig.messageAttributes.filter(p => p.required === true).map(p => `'${p.propertyName}'`).join(', ') %>]
36
36
  };
37
37
  <% } else { -%>
38
38
  let messageAttributeValidatorSchema = null;
@@ -1,135 +1,311 @@
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
+ filterPatternFunctionName
53
+ }) {
54
+ if (
55
+ ![functionName, handlerPath, roleName, queueName].every(
56
+ (value) => typeof value === 'string' && value !== ''
57
+ )
58
+ ) {
59
+ throw new TypeError(
60
+ 'SQS function descriptor must include functionName, handlerPath, roleName, and queueName'
61
+ );
14
62
  }
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)}`;
63
+ return _renderFunctionTemplate('SqsFunction_Yaml.ejs', {
64
+ functionName,
65
+ handlerPath,
66
+ roleName,
67
+ queueName,
68
+ environmentSetting: _environmentSetting(
69
+ functionName,
70
+ flowTag,
71
+ flowStepName,
72
+ targetCompleteStepName
73
+ ),
74
+ functionSetting: _functionSetting(functionName),
75
+ sqsFilterPatterns: _sqsFilterPatterns(
76
+ filterPatternFunctionName ?? functionName
77
+ )
78
+ });
25
79
  }
26
80
 
27
- export function renderApiFunctionYaml({ functionName, handlerPath, roleName, routes = [], flowTag, flowStepName }) {
81
+ export function renderApiFunctionYaml({
82
+ functionName,
83
+ handlerPath,
84
+ roleName,
85
+ routes = [],
86
+ flowTag,
87
+ flowStepName
88
+ }) {
28
89
  if (!Array.isArray(routes)) {
29
90
  throw new TypeError('API function routes must be an array');
30
91
  }
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` : ''}`;
92
+ const routeEvents = routes
93
+ .flatMap(({ path, upperName }) => {
94
+ if (
95
+ typeof path !== 'string' ||
96
+ path === '' ||
97
+ typeof upperName !== 'string' ||
98
+ upperName === ''
99
+ ) {
100
+ throw new TypeError(
101
+ 'API function routes must include path and upperName'
102
+ );
103
+ }
104
+ return [
105
+ ` - httpApi:\n path: ${path}\n method: post\n #<#${upperName}AppLevelAuthorizer#>\n # authorizer: authorizerServiceSchema\n #<#/${upperName}AppLevelAuthorizer#>`,
106
+ ` - httpApi:\n path: ${path}/{targetUserId}\n method: post\n #<#${upperName}UserLevelAuthorizer#>\n # authorizer: authorizerIdentifiers\n #<#/${upperName}UserLevelAuthorizer#>`
107
+ ];
108
+ })
109
+ .join('\n');
110
+ let eventsSection = '';
111
+ if (routeEvents) {
112
+ eventsSection = `${routeEvents}\n`;
113
+ }
114
+ return _renderFunctionTemplate('ApiFunction_Yaml.ejs', {
115
+ functionName,
116
+ handlerPath,
117
+ roleName,
118
+ environmentSetting: _environmentSetting(
119
+ functionName,
120
+ flowTag,
121
+ flowStepName
122
+ ),
123
+ functionSetting: _functionSetting(functionName),
124
+ eventsSection
125
+ });
47
126
  }
48
127
 
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');
128
+ export function renderWbsFunctionYaml({
129
+ functionName,
130
+ handlerPath,
131
+ roleName,
132
+ routeName,
133
+ flowTag,
134
+ flowStepName
135
+ }) {
136
+ if (
137
+ ![functionName, handlerPath, roleName, routeName].every(
138
+ (value) => typeof value === 'string' && value !== ''
139
+ )
140
+ ) {
141
+ throw new TypeError(
142
+ 'WebSocket function descriptor must include functionName, handlerPath, roleName, and routeName'
143
+ );
52
144
  }
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
- `;
145
+ return _renderFunctionTemplate('WbsFunction_Yaml.ejs', {
146
+ functionName,
147
+ handlerPath,
148
+ roleName,
149
+ routeName,
150
+ environmentSetting: _environmentSetting(
151
+ functionName,
152
+ flowTag,
153
+ flowStepName
154
+ ),
155
+ functionSetting: _functionSetting(functionName)
156
+ });
64
157
  }
65
158
 
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
- `;
159
+ export function renderInvFunctionYaml({
160
+ functionName,
161
+ handlerPath,
162
+ roleName,
163
+ flowTag,
164
+ flowStepName
165
+ }) {
166
+ return _renderFunctionTemplate('InvFunction_Yaml.ejs', {
167
+ functionName,
168
+ handlerPath,
169
+ roleName,
170
+ environmentSetting: _environmentSetting(
171
+ functionName,
172
+ flowTag,
173
+ flowStepName
174
+ ),
175
+ functionSetting: _functionSetting(functionName)
176
+ });
73
177
  }
74
178
 
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
- `;
179
+ export function renderS3FunctionYaml({
180
+ functionName,
181
+ handlerPath,
182
+ roleName,
183
+ bucketName,
184
+ flowTag,
185
+ flowStepName
186
+ }) {
187
+ return _renderFunctionTemplate('S3Function_Yaml.ejs', {
188
+ functionName,
189
+ handlerPath,
190
+ roleName,
191
+ bucketName,
192
+ environmentSetting: _environmentSetting(
193
+ functionName,
194
+ flowTag,
195
+ flowStepName
196
+ ),
197
+ functionSetting: _functionSetting(functionName)
198
+ });
93
199
  }
94
200
 
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');
201
+ export function renderEventBridgeFunctionYaml({
202
+ functionName,
203
+ handlerPath,
204
+ roleName,
205
+ flowTag,
206
+ flowStepName,
207
+ schedules = []
208
+ }) {
209
+ if (
210
+ ![functionName, handlerPath, roleName, flowTag].every(
211
+ (value) => typeof value === 'string' && value !== ''
212
+ ) ||
213
+ !Array.isArray(schedules)
214
+ ) {
215
+ throw new TypeError(
216
+ 'EventBridge function descriptor must include functionName, handlerPath, roleName, flowTag, and schedules'
217
+ );
98
218
  }
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');
219
+ if (
220
+ !schedules.every(
221
+ (schedule) =>
222
+ typeof schedule?.name === 'string' &&
223
+ schedule.name !== '' &&
224
+ Array.isArray(schedule.rate) &&
225
+ typeof schedule.rate[0] === 'string' &&
226
+ schedule.rate[0] !== ''
227
+ )
228
+ ) {
229
+ throw new TypeError(
230
+ 'Each EventBridge schedule must include a name and first rate value'
231
+ );
104
232
  }
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`}`;
233
+ let scheduleEventsSection = '';
234
+ if (schedules.length > 0) {
235
+ const renderedSchedules = schedules
236
+ .map((schedule) => {
237
+ let desc = '';
238
+ if (schedule.description) {
239
+ desc = schedule.description;
240
+ }
241
+ return ` - schedule:\n name: \${self:custom.iz_resourcePrefix}${schedule.name}\n description: '${desc}'\n rate: ${schedule.rate[0]}\n enabled: true`;
242
+ })
243
+ .join('\n');
244
+ scheduleEventsSection = ` events:\n${renderedSchedules}\n`;
245
+ }
246
+ return _renderFunctionTemplate('EventBridgeFunction_Yaml.ejs', {
247
+ functionName,
248
+ handlerPath,
249
+ roleName,
250
+ flowTag,
251
+ environmentSetting: _environmentSetting(
252
+ functionName,
253
+ flowTag,
254
+ flowStepName
255
+ ),
256
+ functionSetting: _functionSetting(functionName),
257
+ scheduleEventsSection
258
+ });
111
259
  }
112
260
 
113
- function environmentSetting(functionName, flowTag, flowStepName, targetCompleteStepName) {
114
- if (flowTag === undefined && flowStepName === undefined && targetCompleteStepName === undefined) return '';
261
+ function _environmentSetting(
262
+ functionName,
263
+ flowTag,
264
+ flowStepName,
265
+ targetCompleteStepName
266
+ ) {
267
+ if (
268
+ flowTag === undefined &&
269
+ flowStepName === undefined &&
270
+ targetCompleteStepName === undefined
271
+ ) {
272
+ return '';
273
+ }
115
274
  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 '';
275
+ if (flowTag !== undefined) {
276
+ let flowTagVal = "''";
277
+ if (flowTag !== '') {
278
+ flowTagVal = flowTag;
279
+ }
280
+ envs.push(` iz_flowTag: ${flowTagVal}`);
281
+ }
282
+ if (flowStepName !== undefined) {
283
+ let flowStepNameVal = "''";
284
+ if (flowStepName !== '') {
285
+ flowStepNameVal = flowStepName;
286
+ }
287
+ envs.push(` iz_flowStepName: ${flowStepNameVal}`);
288
+ }
289
+ if (targetCompleteStepName !== undefined) {
290
+ envs.push(
291
+ ` iz_targetCompleteStepName: ${flowTag}${targetCompleteStepName}`
292
+ );
293
+ }
294
+
295
+ if (envs.length === 0) {
296
+ return '';
297
+ }
121
298
  return ` environment:
122
299
  ${envs.join('\n')}
123
300
  #<#${functionName}Environment#>
124
301
  #<#/${functionName}Environment#>\n`;
125
302
  }
126
303
 
127
- function functionSetting(functionName) {
304
+ function _functionSetting(functionName) {
128
305
  return ` #<#${functionName}FunctionSetting#>\n #<#/${functionName}FunctionSetting#>`;
129
306
  }
130
307
 
131
- function completionFilter(functionName) {
132
- if (!functionName.endsWith('CompleteHdrSqs')) return '';
308
+ function _sqsFilterPatterns(functionName) {
133
309
  return ` filterPatterns:
134
310
  - body:
135
311
  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'