@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.
- package/package.json +1 -1
- package/scripts/format-ejs.js +36 -32
- package/src/compile/compileProject.js +26 -10
- package/src/compile/loadSchemas.js +122 -59
- package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +163 -0
- package/src/emit/coreFunction/templates/CoreFunction_Yaml.ejs +38 -0
- package/src/emit/coreFunction/templates/CoreResource_Yaml.ejs +235 -0
- package/src/emit/coreFunction/templates/GenerateSeedDataDynamo_HdrInv.ejs +16 -0
- package/src/emit/coreFunction/templates/GenerateSeedDataDynamo_Main.ejs +38 -0
- package/src/emit/coreFunction/templates/GenerateSeedDataGraphData_HdrInv.ejs +16 -0
- package/src/emit/coreFunction/templates/GenerateSeedDataGraphData_Main.ejs +32 -0
- package/src/emit/coreFunction/templates/GenerateSeedDataGraphSchema_HdrInv.ejs +16 -0
- package/src/emit/coreFunction/templates/GenerateSeedDataGraphSchema_Main.ejs +71 -0
- package/src/emit/coreFunction/templates/GeneratedGraphNodeSchemas.ejs +47 -0
- package/src/emit/coreFunction/templates/GeneratedGraphRelSchemas.ejs +27 -0
- package/src/emit/coreFunction/templates/GeneratedTableConfigs.ejs +34 -0
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +108 -0
- package/src/emit/coreFunction/templates/InitialSetup_HdrInv.ejs +12 -0
- package/src/emit/coreFunction/templates/InitialSetup_Main.ejs +51 -0
- package/src/emit/coreFunction/templates/RemoveSeedDataDynamo_HdrInv.ejs +16 -0
- package/src/emit/coreFunction/templates/RemoveSeedDataDynamo_Main.ejs +31 -0
- package/src/emit/coreFunction/templates/UploadSchema_HdrInv.ejs +37 -0
- package/src/emit/coreFunction/templates/UploadSchema_Main.ejs +52 -0
- package/src/emit/crud/emitCrudApplicationArtifacts.js +194 -41
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +34 -17
- package/src/emit/crud/generateCrudApplicationArtifacts.js +14 -6
- package/src/emit/crud/generateDynamicCrudFlowSchemas.js +4 -1
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +1 -1
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +1 -1
- package/src/emit/crud/templates/GetEndpoint_Main.ejs +2 -2
- package/src/emit/crud/templates/GetRangeEndpoint_Main.ejs +1 -1
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +1 -1
- package/src/emit/custom/customFlows.js +23 -13
- package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +535 -114
- package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +28 -8
- package/src/emit/custom/templates/FlowEndpoint_Main.ejs +2 -2
- package/src/emit/custom/templates/FlowStep_Main.ejs +1 -1
- package/src/emit/custom/templates/s3/CreateObject_Main.ejs +1 -1
- package/src/emit/custom/templates/s3/FlowHandler_HdrS3.ejs +2 -2
- package/src/emit/custom/templates/s3/ReservedLimit_HdrSqs.ejs +1 -1
- package/src/emit/custom/templates/s3/ReservedLimit_Main.ejs +1 -1
- package/src/emit/custom/templates/triggerCache/CheckTriggerCache_HdrSqs.ejs +4 -4
- package/src/emit/function/functionYamlArtifact.js +273 -97
- package/src/emit/function/templates/ApiFunction_Yaml.ejs +7 -0
- package/src/emit/function/templates/EventBridgeFunction_Yaml.ejs +6 -0
- package/src/emit/function/templates/InvFunction_Yaml.ejs +5 -0
- package/src/emit/function/templates/S3Function_Yaml.ejs +16 -0
- package/src/emit/function/templates/SqsFunction_Yaml.ejs +10 -0
- package/src/emit/function/templates/WbsFunction_Yaml.ejs +10 -0
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +28 -30
- package/src/emit/rbac/emitRbacApplicationArtifacts.js +6 -6
- package/src/emit/rbac/generateCreateTargetRoleHandler.js +6 -4
- package/src/emit/rbac/generateDynamicRbacFlowSchemas.js +8 -2
- package/src/emit/rbac/rbacFlowTag.js +3 -1
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +1 -1
- package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +26 -10
- package/src/emit/relationship/emitRelationshipApplicationArtifacts.js +189 -37
- package/src/emit/relationship/generateDynamicRelationshipFlowSchemas.js +8 -2
- package/src/emit/relationship/generateRelationshipApplicationArtifacts.js +15 -6
- package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +1 -1
- package/src/emit/relationship/templates/CreateRelationship_Main.ejs +1 -1
- package/src/emit/relationship/templates/DeleteRelationship_Main.ejs +1 -1
- package/src/emit/relationship/templates/GetRelationship_Main.ejs +1 -1
- package/src/emit/relationship/templates/MoveRelationship_Main.ejs +1 -1
- package/src/emit/relationship/templates/UpdateRelationship_Main.ejs +1 -1
- package/src/emit/resource/emitResourceArtifacts.js +249 -123
- package/src/emit/resource/generateResourceArtifacts.js +15 -6
- package/src/emit/resource/templates/DynamoDBTable_Yaml.ejs +18 -18
- package/src/emit/resource/templates/FlowOut_Yaml.ejs +5 -5
- package/src/emit/resource/templates/GeneratedLambdaRoleServiceConfig.ejs +10 -9
- package/src/emit/resource/templates/ResourceBeforeLogicalYaml.ejs +44 -44
- package/src/emit/resource/templates/ResourceSqsYaml.ejs +36 -36
- package/src/emit/resource/templates/ResourceYaml.ejs +48 -48
- package/src/emit/resource/templates/S3Subscription_Yaml.ejs +7 -0
- package/src/emit/resource/templates/SharedResource_Yaml.ejs +11 -11
- package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +122 -105
- package/src/emit/resource/templates/WebSocketSubscription_Yaml.ejs +7 -0
- package/src/emit/shared/templates/FindData_HdrSqs.ejs +120 -0
- package/src/emit/shared/templates/FindData_Main.ejs +345 -0
- package/src/emit/{crud → shared}/templates/FlowHandler_HdrApi.ejs +1 -1
- package/src/emit/{relationship → shared}/templates/FlowHandler_HdrDsq.ejs +4 -4
- package/src/emit/{crud → shared}/templates/FlowHandler_HdrInv.ejs +1 -1
- package/src/emit/{crud → shared}/templates/FlowHandler_HdrSqs.ejs +4 -4
- package/src/emit/shared/templates/PaginateProcessLogical_HdrDsq.ejs +162 -0
- package/src/emit/shared/templates/PaginateProcessLogical_HdrSqs.ejs +140 -0
- package/src/emit/shared/templates/PaginateProcessLogical_Main.ejs +268 -0
- package/src/emit/{relationship/templates/FlowHandler_HdrSqs.ejs → shared/templates/ProcessLogical_HdrSqs.ejs} +40 -55
- package/src/emit/shared/templates/ProcessLogical_Main.ejs +448 -0
- package/src/emit/system/emitSystemFindDataArtifacts.js +266 -0
- package/src/emit/system/emitSystemWebSocketArtifacts.js +61 -165
- package/src/emit/system/templates/WebSocketComplete_HdrSqs.ejs +48 -0
- package/src/emit/system/templates/WebSocketComplete_Main.ejs +91 -0
- package/src/emit/system/templates/WebSocketComplete_Yaml.ejs +19 -0
- package/src/emit/system/templates/WebSocketConnect.ejs +45 -0
- package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +11 -0
- package/src/generate.js +166 -36
- package/src/generateIntTest.js +76 -28
- package/src/generateResourceIntTest.js +35 -12
- package/src/generateResources/IntTest/generateResources/generateResources.js +5 -2
- package/src/generateResources/IntTest/generateResources/templateResources.ejs +18 -30
- package/src/generateResources/IntTest/generateTests/events/events.js +1 -1
- package/src/generateResources/IntTest/generateTests/events/templateEvents.ejs +13 -10
- package/src/generateResources/IntTest/generateTests/generateTemplate.js +2 -2
- package/src/generateResources/IntTest/generateTests/pathIntTest/pathIntTest.js +2 -1
- package/src/generateResources/IntTest/generateTests/pathIntTest/template.ejs +1 -3
- package/src/generateResources/IntTest/generateTests/tests/templateTests.ejs +1 -1
- package/src/generateResources/IntTest/generateTests/tests/tests.js +7 -3
- package/src/generateResources/IntTest/libs/{libs.js → IntTestGenerateLib.js} +34 -23
- package/src/generateResources/IntTest/upload/uploadIntTest.js +33 -19
- package/src/intTestGeneratorShared.js +15 -10
- package/src/output/commitArtifacts.js +99 -39
- package/src/output/mergeHooks.js +34 -21
- package/src/output/validateArtifacts.js +37 -27
- package/src/plan/buildGenerationPlan.js +24 -13
- package/test/core.test.js +117 -58
- package/test/createTargetRoleHandler.test.js +1 -1
- package/test/crudApplicationArtifacts.test.js +132 -31
- package/test/customFlowApplicationArtifacts.test.js +353 -71
- package/test/dynamicCrudFlowSchemas.test.js +74 -26
- package/test/dynamicRbacFlowSchemas.test.js +61 -14
- package/test/dynamicRelationshipFlowSchemas.test.js +65 -18
- package/test/functionYamlArtifact.test.js +67 -10
- package/test/intTestApi.test.js +9 -10
- package/test/publicApi.test.js +178 -36
- package/test/relationshipApplicationArtifacts.test.js +90 -19
- package/test/resourceArtifacts.test.js +173 -33
- package/src/emit/relationship/dynamicRelationshipFlowSchemaTemplate.js +0 -11
- package/src/emit/relationship/templates/FlowHandler_HdrApi.ejs +0 -59
- package/src/emit/relationship/templates/FlowHandler_HdrInv.ejs +0 -47
|
@@ -66,7 +66,7 @@ import { consts as coreConsts } from '@izara_project/izara-core-library-core';
|
|
|
66
66
|
export default async function getRelationship(
|
|
67
67
|
_izContext,
|
|
68
68
|
requestParams,
|
|
69
|
-
callingFlowConfig = {}
|
|
69
|
+
callingFlowConfig = {},
|
|
70
70
|
//(<additionalParams>)
|
|
71
71
|
//(</additionalParams>)
|
|
72
72
|
) {
|
|
@@ -69,7 +69,7 @@ import { consts as coreConsts } from '@izara_project/izara-core-library-core';
|
|
|
69
69
|
export default async function moveRelationship(
|
|
70
70
|
_izContext,
|
|
71
71
|
requestParams,
|
|
72
|
-
callingFlowConfig = {}
|
|
72
|
+
callingFlowConfig = {},
|
|
73
73
|
//(<additionalParams>)
|
|
74
74
|
//(</additionalParams>)
|
|
75
75
|
) {
|
|
@@ -62,7 +62,7 @@ const { PREFIX, TOPIC_NAME_GENERATE_CODE, TOPIC_NAME_GRAPH_HANDLER } = consts;
|
|
|
62
62
|
export default async function updateRelationship(
|
|
63
63
|
_izContext,
|
|
64
64
|
requestParams,
|
|
65
|
-
callingFlowConfig = {}
|
|
65
|
+
callingFlowConfig = {},
|
|
66
66
|
//(<additionalParams>)
|
|
67
67
|
//(</additionalParams>)
|
|
68
68
|
) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ejsLib from 'ejs';
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
3
|
|
|
4
4
|
import {
|
|
@@ -92,7 +92,7 @@ export async function emitResourceArtifacts({
|
|
|
92
92
|
renderLambdaRoleConfig(state),
|
|
93
93
|
renderS3(state)
|
|
94
94
|
]);
|
|
95
|
-
|
|
95
|
+
const artifacts = [
|
|
96
96
|
{
|
|
97
97
|
path: `${RESOURCE_ROOT}/generated-sns-in-sqs.yml`,
|
|
98
98
|
content: normalizeYaml(inSqs)
|
|
@@ -106,18 +106,31 @@ export async function emitResourceArtifacts({
|
|
|
106
106
|
content: normalizeYaml(dynamo)
|
|
107
107
|
},
|
|
108
108
|
{
|
|
109
|
-
path: `${
|
|
110
|
-
content: normalizeYaml(
|
|
109
|
+
path: `${APP_ROOT}/generate-shared-resource.yml`,
|
|
110
|
+
content: normalizeYaml(iam.iamContent)
|
|
111
111
|
},
|
|
112
112
|
{
|
|
113
|
-
path: `${APP_ROOT}/
|
|
114
|
-
content: normalizeYaml(iam)
|
|
113
|
+
path: `${APP_ROOT}/role-name-config.yml`,
|
|
114
|
+
content: normalizeYaml(iam.roleNameConfigContent)
|
|
115
115
|
},
|
|
116
116
|
{
|
|
117
117
|
path: `${INITIAL_SETUP_ROOT}/generatedLambdaRoleServiceConfig.js`,
|
|
118
118
|
content: lambdaRoleConfig
|
|
119
119
|
}
|
|
120
120
|
];
|
|
121
|
+
if (state.s3Buckets.length > 0) {
|
|
122
|
+
artifacts.push({
|
|
123
|
+
path: `${RESOURCE_ROOT}/generated-s3.yml`,
|
|
124
|
+
content: normalizeYaml(s3)
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (state.hasHttpApi) {
|
|
128
|
+
artifacts.push({
|
|
129
|
+
path: `${APP_ROOT}/cors.yml`,
|
|
130
|
+
content: renderCorsYaml()
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return artifacts;
|
|
121
134
|
}
|
|
122
135
|
|
|
123
136
|
export const resourceArtifactPaths = [
|
|
@@ -126,7 +139,9 @@ export const resourceArtifactPaths = [
|
|
|
126
139
|
`${RESOURCE_ROOT}/generated-dynamoDB-table.yml`,
|
|
127
140
|
`${RESOURCE_ROOT}/generated-s3.yml`,
|
|
128
141
|
`${APP_ROOT}/generate-shared-resource.yml`,
|
|
129
|
-
`${
|
|
142
|
+
`${APP_ROOT}/role-name-config.yml`,
|
|
143
|
+
`${INITIAL_SETUP_ROOT}/generatedLambdaRoleServiceConfig.js`,
|
|
144
|
+
`${APP_ROOT}/cors.yml`
|
|
130
145
|
];
|
|
131
146
|
|
|
132
147
|
function createResourceState({ objects, relationships, flows }) {
|
|
@@ -134,62 +149,60 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
134
149
|
const rbac = objects.some(hasRbacAddOn);
|
|
135
150
|
const ownTopics = new Set(
|
|
136
151
|
flows
|
|
137
|
-
.filter(flow => includesEvent(flow, 'ownTopic'))
|
|
138
|
-
.map(flow => upperFirst(flow.flowTag))
|
|
152
|
+
.filter((flow) => includesEvent(flow, 'ownTopic'))
|
|
153
|
+
.map((flow) => upperFirst(flow.flowTag))
|
|
139
154
|
);
|
|
140
155
|
const sqsQueues = new Set([
|
|
141
156
|
...LEGACY_PROCESS_QUEUES,
|
|
142
157
|
...flows
|
|
143
|
-
.filter(flow => includesEvent(flow, 'extTopic'))
|
|
144
|
-
.map(flow => `Process${upperFirst(flow.flowTag)}HdrSqs`)
|
|
158
|
+
.filter((flow) => includesEvent(flow, 'extTopic'))
|
|
159
|
+
.map((flow) => `Process${upperFirst(flow.flowTag)}HdrSqs`)
|
|
145
160
|
]);
|
|
146
|
-
|
|
147
|
-
sqsQueues.add(`${flowTag}${stepName}HdrSqs`)
|
|
148
|
-
|
|
149
|
-
flows
|
|
150
|
-
|
|
151
|
-
.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
sqsQueues.add(`${tag}ConfirmAfterUploadHdrSqs`);
|
|
156
|
-
});
|
|
161
|
+
for (const { flowTag, stepName } of flowExtTopicSteps(flows)) {
|
|
162
|
+
sqsQueues.add(`${flowTag}${stepName}HdrSqs`);
|
|
163
|
+
}
|
|
164
|
+
for (const flow of flows.filter((flow) => includesEvent(flow, 's3'))) {
|
|
165
|
+
const tag = upperFirst(flow.flowTag);
|
|
166
|
+
sqsQueues.add(`${tag}CreatePreSignUrlHdrSqs`);
|
|
167
|
+
sqsQueues.add(`${tag}ReservedLimitHdrSqs`);
|
|
168
|
+
sqsQueues.add(`${tag}ConfirmAfterUploadHdrSqs`);
|
|
169
|
+
}
|
|
157
170
|
const dsqQueues = new Set(
|
|
158
171
|
flows
|
|
159
|
-
.filter(flow => includesEvent(flow, 'dsq'))
|
|
160
|
-
.map(flow => `${upperFirst(flow.flowTag)}HdrDsq`)
|
|
161
|
-
);
|
|
162
|
-
flowDsqSteps(flows).forEach(({ flowTag, stepName }) =>
|
|
163
|
-
dsqQueues.add(`${flowTag}${stepName}HdrDsq`)
|
|
172
|
+
.filter((flow) => includesEvent(flow, 'dsq'))
|
|
173
|
+
.map((flow) => `${upperFirst(flow.flowTag)}HdrDsq`)
|
|
164
174
|
);
|
|
175
|
+
for (const { flowTag, stepName } of flowDsqSteps(flows)) {
|
|
176
|
+
dsqQueues.add(`${flowTag}${stepName}HdrDsq`);
|
|
177
|
+
}
|
|
165
178
|
if (crud) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
)
|
|
179
|
+
for (const action of CRUD_ACTIONS) {
|
|
180
|
+
ownTopics.add(action);
|
|
181
|
+
}
|
|
182
|
+
for (const action of ['Create', 'Update', 'Delete']) {
|
|
183
|
+
sqsQueues.add(`${action}CompleteHdrSqs`);
|
|
184
|
+
}
|
|
170
185
|
}
|
|
171
186
|
if (relationships.length > 0) {
|
|
172
|
-
|
|
187
|
+
for (const action of RELATIONSHIP_ACTIONS) {
|
|
173
188
|
ownTopics.add(action);
|
|
174
189
|
sqsQueues.add(`${action}CompleteHdrSqs`);
|
|
175
|
-
}
|
|
190
|
+
}
|
|
176
191
|
dsqQueues.add('GetRelationshipHdrDsq');
|
|
177
192
|
}
|
|
178
193
|
if (rbac) {
|
|
179
|
-
|
|
194
|
+
for (const action of RBAC_ACTIONS) {
|
|
180
195
|
ownTopics.add(action);
|
|
181
196
|
sqsQueues.add(`Process${action}HdrSqs`);
|
|
182
|
-
}
|
|
183
|
-
objects
|
|
184
|
-
.
|
|
185
|
-
.
|
|
186
|
-
|
|
187
|
-
ownTopics.add(flowTag);
|
|
188
|
-
});
|
|
197
|
+
}
|
|
198
|
+
for (const object of objects.filter(hasRbacAddOn)) {
|
|
199
|
+
const flowTag = upperFirst(object.objectType) + 'RbacFlow';
|
|
200
|
+
ownTopics.add(flowTag);
|
|
201
|
+
}
|
|
189
202
|
}
|
|
190
203
|
const beforeLogicalByAction = new Map();
|
|
191
204
|
for (const flow of flows.filter(
|
|
192
|
-
flow => flow?.generatedCodeConfig?.codeHookTag === 'beforeLogical'
|
|
205
|
+
(flow) => flow?.generatedCodeConfig?.codeHookTag === 'beforeLogical'
|
|
193
206
|
)) {
|
|
194
207
|
const action = upperFirst(flow.generatedCodeConfig.generatedCodeTag);
|
|
195
208
|
if (!action || !flow.flowTag) continue;
|
|
@@ -202,10 +215,10 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
202
215
|
);
|
|
203
216
|
const customRoles = [
|
|
204
217
|
...new Set([
|
|
205
|
-
...supportedCustomFlows(flows).map(flow =>
|
|
218
|
+
...supportedCustomFlows(flows).map((flow) =>
|
|
206
219
|
customFlowRoleName(flow.flowTag)
|
|
207
220
|
),
|
|
208
|
-
...generatedOwnTopicFlows(flows).map(flow =>
|
|
221
|
+
...generatedOwnTopicFlows(flows).map((flow) =>
|
|
209
222
|
customFlowRoleName(flow.flowTag)
|
|
210
223
|
),
|
|
211
224
|
...flowExtTopicSteps(flows).map(({ flow }) =>
|
|
@@ -217,21 +230,28 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
217
230
|
const websocket = hasSystemWebSocket(flows, {
|
|
218
231
|
includeRelationshipOwnTopic: true
|
|
219
232
|
});
|
|
220
|
-
const webSocketRoles = new Set(
|
|
233
|
+
const webSocketRoles = new Set();
|
|
234
|
+
if (websocket) {
|
|
235
|
+
webSocketRoles.add('WebSocketMainRole');
|
|
236
|
+
}
|
|
221
237
|
if (crud) webSocketRoles.add('FlowObjectsRole');
|
|
222
238
|
if (relationships.length > 0) webSocketRoles.add('FlowRelationshipRole');
|
|
223
239
|
if (rbac) webSocketRoles.add('FlowRbacRole');
|
|
224
|
-
[
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
240
|
+
const filteredWsFlows = [
|
|
241
|
+
...supportedCustomFlows(flows),
|
|
242
|
+
...generatedOwnTopicFlows(flows)
|
|
243
|
+
].filter(
|
|
244
|
+
(flow) => includesEvent(flow, 'ownTopic') || includesEvent(flow, 's3')
|
|
245
|
+
);
|
|
246
|
+
for (const flow of filteredWsFlows) {
|
|
247
|
+
webSocketRoles.add(customFlowRoleName(flow.flowTag));
|
|
248
|
+
}
|
|
229
249
|
const outTopics = new Set([
|
|
230
250
|
...ownTopics,
|
|
231
251
|
...beforeLogical.map(({ action }) => action),
|
|
232
252
|
...flows
|
|
233
|
-
.filter(flow => flow?.outputTopic && upperFirst(flow.flowTag))
|
|
234
|
-
.map(flow => upperFirst(flow.flowTag))
|
|
253
|
+
.filter((flow) => flow?.outputTopic && upperFirst(flow.flowTag))
|
|
254
|
+
.map((flow) => upperFirst(flow.flowTag))
|
|
235
255
|
]);
|
|
236
256
|
const objectTableNames = [...collectTables(objects).keys()];
|
|
237
257
|
const relationshipTableNames = [...collectTables(relationships).keys()];
|
|
@@ -240,15 +260,46 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
240
260
|
...collectTables(relationships)
|
|
241
261
|
]);
|
|
242
262
|
const externalDynamoTables = objects.flatMap(
|
|
243
|
-
object => object.externalDynamoResources ?? []
|
|
263
|
+
(object) => object.externalDynamoResources ?? []
|
|
244
264
|
);
|
|
245
265
|
const s3Buckets = flows
|
|
246
|
-
.filter(flow => includesEvent(flow, 's3') && flow.createBucket === true)
|
|
247
|
-
.map(flow => flow.bucketName)
|
|
266
|
+
.filter((flow) => includesEvent(flow, 's3') && flow.createBucket === true)
|
|
267
|
+
.map((flow) => flow.bucketName)
|
|
248
268
|
.filter(Boolean);
|
|
269
|
+
const s3FlowTags = flows
|
|
270
|
+
.filter((flow) => includesEvent(flow, 's3'))
|
|
271
|
+
.map((flow) => upperFirst(flow.flowTag));
|
|
272
|
+
const s3Subscriptions = flows
|
|
273
|
+
.filter((flow) => includesEvent(flow, 's3'))
|
|
274
|
+
.map((flow) => {
|
|
275
|
+
const tag = upperFirst(flow.flowTag);
|
|
276
|
+
const topicName = flow.outputTopic
|
|
277
|
+
? flow.outputTopic.startsWith('Out')
|
|
278
|
+
? flow.outputTopic
|
|
279
|
+
: `Out${upperFirst(flow.outputTopic)}`
|
|
280
|
+
: flow.s3Subscription?.topicName || 'OutCreate';
|
|
281
|
+
const queueName =
|
|
282
|
+
flow.s3Subscription?.queueName || `${tag}ReservedLimitHdrSqs`;
|
|
283
|
+
const subscriptionName =
|
|
284
|
+
flow.s3Subscription?.subscriptionName ||
|
|
285
|
+
`Subscription${topicName}To${queueName}`;
|
|
286
|
+
return { subscriptionName, topicName, queueName };
|
|
287
|
+
});
|
|
288
|
+
const systemTables = [...SYSTEM_TABLES];
|
|
289
|
+
if (s3FlowTags.length > 0) {
|
|
290
|
+
systemTables.push('ReservedDataMain');
|
|
291
|
+
}
|
|
292
|
+
const hasHttpApi =
|
|
293
|
+
crud ||
|
|
294
|
+
relationships.length > 0 ||
|
|
295
|
+
rbac ||
|
|
296
|
+
flows.some((flow) => includesEvent(flow, 'lambdaSyncApi'));
|
|
249
297
|
return {
|
|
250
298
|
crud,
|
|
251
299
|
rbac,
|
|
300
|
+
s3Subscriptions,
|
|
301
|
+
s3FlowTags,
|
|
302
|
+
hasHttpApi,
|
|
252
303
|
relationships: relationships.length > 0,
|
|
253
304
|
ownTopics: [...ownTopics].filter(Boolean).sort(),
|
|
254
305
|
sqsQueues: [...sqsQueues].filter(Boolean).sort(),
|
|
@@ -260,9 +311,9 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
260
311
|
webSocketSubscriptions: websocket
|
|
261
312
|
? [...outTopics]
|
|
262
313
|
.filter(
|
|
263
|
-
topic =>
|
|
314
|
+
(topic) =>
|
|
264
315
|
flows.some(
|
|
265
|
-
flow =>
|
|
316
|
+
(flow) =>
|
|
266
317
|
(flow?.outputTopic ||
|
|
267
318
|
(includesEvent(flow, 'ownTopic') &&
|
|
268
319
|
flow.initiateBy === 'user')) &&
|
|
@@ -279,16 +330,16 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
279
330
|
tableName,
|
|
280
331
|
...keys
|
|
281
332
|
})),
|
|
282
|
-
allTableNames: [...new Set([...
|
|
333
|
+
allTableNames: [...new Set([...systemTables, ...tableMap.keys()])].sort(),
|
|
283
334
|
objectTableNames,
|
|
284
335
|
relationshipTableNames,
|
|
285
336
|
externalDynamoTables,
|
|
286
337
|
objectTablesByType: new Map(
|
|
287
338
|
objects
|
|
288
|
-
.map(object => [
|
|
339
|
+
.map((object) => [
|
|
289
340
|
object.objectType,
|
|
290
341
|
Object.values(object.storageResources ?? {}).find(
|
|
291
|
-
resource => resource?.storageType === 'dynamoDB'
|
|
342
|
+
(resource) => resource?.storageType === 'dynamoDB'
|
|
292
343
|
)?.tableName
|
|
293
344
|
])
|
|
294
345
|
.filter(([, tableName]) => tableName)
|
|
@@ -300,22 +351,25 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
300
351
|
|
|
301
352
|
async function renderS3(state) {
|
|
302
353
|
if (state.s3Buckets.length === 0) return 'Resources:';
|
|
303
|
-
const template = await readFile(
|
|
354
|
+
const template = await readFile(
|
|
355
|
+
new URL('S3Bucket_Yaml.ejs', TEMPLATE_URL),
|
|
356
|
+
'utf8'
|
|
357
|
+
);
|
|
304
358
|
const chunks = await Promise.all(
|
|
305
|
-
state.s3Buckets.map(bucketName =>
|
|
359
|
+
state.s3Buckets.map((bucketName) => ejsLib.render(template, { bucketName }))
|
|
306
360
|
);
|
|
307
361
|
return `Resources:\n${chunks.join('\n')}`;
|
|
308
362
|
}
|
|
309
363
|
|
|
310
364
|
async function renderInSqs(state) {
|
|
311
365
|
const chunks = await Promise.all([
|
|
312
|
-
...state.ownTopics.map(queueName =>
|
|
366
|
+
...state.ownTopics.map((queueName) =>
|
|
313
367
|
render('ResourceYaml.ejs', { queueName })
|
|
314
368
|
),
|
|
315
|
-
...state.sqsQueues.map(queueName =>
|
|
369
|
+
...state.sqsQueues.map((queueName) =>
|
|
316
370
|
render('ResourceSqsYaml.ejs', { queueName })
|
|
317
371
|
),
|
|
318
|
-
...state.dsqQueues.map(queueName =>
|
|
372
|
+
...state.dsqQueues.map((queueName) =>
|
|
319
373
|
render('ResourceSqsYaml.ejs', { queueName })
|
|
320
374
|
),
|
|
321
375
|
...state.beforeLogical.map(({ action, flowTags }) =>
|
|
@@ -332,17 +386,39 @@ async function renderInSqs(state) {
|
|
|
332
386
|
]
|
|
333
387
|
: [])
|
|
334
388
|
]);
|
|
335
|
-
|
|
389
|
+
const webSocketSubscriptions = await Promise.all(
|
|
390
|
+
state.webSocketSubscriptions.map((topicName) =>
|
|
391
|
+
renderWebSocketSubscription(topicName)
|
|
392
|
+
)
|
|
393
|
+
);
|
|
394
|
+
const s3Subscriptions = await Promise.all(
|
|
395
|
+
(state.s3Subscriptions ?? []).map(
|
|
396
|
+
({ subscriptionName, topicName, queueName }) =>
|
|
397
|
+
render('S3Subscription_Yaml.ejs', {
|
|
398
|
+
subscriptionName,
|
|
399
|
+
topicName,
|
|
400
|
+
queueName
|
|
401
|
+
})
|
|
402
|
+
)
|
|
403
|
+
);
|
|
404
|
+
const parts = [chunks.join('\n')];
|
|
405
|
+
if (webSocketSubscriptions.length > 0) {
|
|
406
|
+
parts.push(webSocketSubscriptions.join('\n'));
|
|
407
|
+
}
|
|
408
|
+
if (s3Subscriptions.length > 0) {
|
|
409
|
+
parts.push(s3Subscriptions.join('\n'));
|
|
410
|
+
}
|
|
411
|
+
return `Resources:\n${parts.join('\n')}`;
|
|
336
412
|
}
|
|
337
413
|
|
|
338
414
|
async function renderOut(state) {
|
|
339
|
-
return `Resources:\n${(await Promise.all(state.outTopics.map(topicName => render('FlowOut_Yaml.ejs', { topicName })))).join('\n')}`;
|
|
415
|
+
return `Resources:\n${(await Promise.all(state.outTopics.map((topicName) => render('FlowOut_Yaml.ejs', { topicName })))).join('\n')}`;
|
|
340
416
|
}
|
|
341
417
|
|
|
342
418
|
async function renderDynamo(state) {
|
|
343
419
|
const [system, ...tables] = await Promise.all([
|
|
344
|
-
render('SystemDynamoDB_Yaml.ejs', {}),
|
|
345
|
-
...state.tables.map(table => render('DynamoDBTable_Yaml.ejs', table))
|
|
420
|
+
render('SystemDynamoDB_Yaml.ejs', { hasS3: state.s3FlowTags.length > 0 }),
|
|
421
|
+
...state.tables.map((table) => render('DynamoDBTable_Yaml.ejs', table))
|
|
346
422
|
]);
|
|
347
423
|
return `${system}\n${tables.join('\n')}`;
|
|
348
424
|
}
|
|
@@ -354,18 +430,22 @@ async function renderIam(state) {
|
|
|
354
430
|
if (state.rbac) roles.push('FlowRbacRole');
|
|
355
431
|
if (state.websocket) roles.push('WebSocketMainRole');
|
|
356
432
|
roles.push(...state.customRoles);
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
433
|
+
const sortedRoles = roles.sort();
|
|
434
|
+
return {
|
|
435
|
+
iamContent: await render('SharedResource_Yaml.ejs', {
|
|
436
|
+
roles: sortedRoles.map((roleName) => ({
|
|
437
|
+
roleName,
|
|
438
|
+
statements: roleStatements(state, roleName)
|
|
439
|
+
}))
|
|
440
|
+
}),
|
|
441
|
+
roleNameConfigContent: renderRoleNameConfigYaml(sortedRoles)
|
|
442
|
+
};
|
|
363
443
|
}
|
|
364
444
|
|
|
365
445
|
async function renderLambdaRoleConfig(state) {
|
|
366
446
|
const s3Flows = state.flows
|
|
367
|
-
.filter(flow => includesEvent(flow, 's3'))
|
|
368
|
-
.map(flow => ({
|
|
447
|
+
.filter((flow) => includesEvent(flow, 's3'))
|
|
448
|
+
.map((flow) => ({
|
|
369
449
|
roleName: upperFirst(flow.flowTag)
|
|
370
450
|
}));
|
|
371
451
|
return render('GeneratedLambdaRoleServiceConfig.ejs', {
|
|
@@ -385,14 +465,10 @@ function roleStatements(state, roleName) {
|
|
|
385
465
|
]
|
|
386
466
|
});
|
|
387
467
|
}
|
|
388
|
-
addStatement(
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
...dynamoArns(roleTableNames(state, roleName)),
|
|
393
|
-
...externalDynamoArns(roleExternalDynamoTables(state, roleName))
|
|
394
|
-
]
|
|
395
|
-
);
|
|
468
|
+
addStatement(statements, dynamoActionsForRole(roleName), [
|
|
469
|
+
...dynamoArns(roleTableNames(state, roleName)),
|
|
470
|
+
...externalDynamoArns(roleExternalDynamoTables(state, roleName))
|
|
471
|
+
]);
|
|
396
472
|
addStatement(
|
|
397
473
|
statements,
|
|
398
474
|
SQS_CONSUMER_ACTIONS,
|
|
@@ -452,13 +528,13 @@ function roleTableNames(state, roleName) {
|
|
|
452
528
|
'LogicalResultsData'
|
|
453
529
|
];
|
|
454
530
|
const flow = state.flows.find(
|
|
455
|
-
candidate => customFlowRoleName(candidate?.flowTag ?? '') === roleName
|
|
531
|
+
(candidate) => customFlowRoleName(candidate?.flowTag ?? '') === roleName
|
|
456
532
|
);
|
|
457
533
|
if (!flow) return [];
|
|
458
534
|
const tables = [];
|
|
459
535
|
if (includesEvent(flow, 'ownTopic') || includesEvent(flow, 's3'))
|
|
460
536
|
tables.push('WebSocketTask');
|
|
461
|
-
if (includesEvent(flow, 's3')) tables.push('UserUploadRecords');
|
|
537
|
+
if (includesEvent(flow, 's3')) tables.push('UserUploadRecords', 'ReservedDataMain');
|
|
462
538
|
if (flow.statusType === 'storedCache') {
|
|
463
539
|
const object = state.objectTablesByType.get(flow.objType?.objectType);
|
|
464
540
|
if (object) tables.push(object);
|
|
@@ -477,68 +553,91 @@ function dynamoActionsForRole(roleName) {
|
|
|
477
553
|
}
|
|
478
554
|
|
|
479
555
|
function roleQueueNames(state, roleName) {
|
|
480
|
-
if (roleName === 'ProcFindDataRole')
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
if (roleName === '
|
|
556
|
+
if (roleName === 'ProcFindDataRole') {
|
|
557
|
+
return LEGACY_PROCESS_QUEUES;
|
|
558
|
+
}
|
|
559
|
+
if (roleName === 'WebSocketMainRole') {
|
|
560
|
+
if (state.websocket) {
|
|
561
|
+
return ['WebSocketCompleteHdrSqs'];
|
|
562
|
+
}
|
|
563
|
+
return [];
|
|
564
|
+
}
|
|
565
|
+
if (roleName === 'FlowObjectsRole') {
|
|
484
566
|
return [
|
|
485
|
-
...CRUD_ACTIONS.map(action => `${action}HdrSqs`),
|
|
486
|
-
...CRUD_ACTIONS.filter(action => action !== 'Get').map(
|
|
487
|
-
action => `${action}CompleteHdrSqs`
|
|
567
|
+
...CRUD_ACTIONS.map((action) => `${action}HdrSqs`),
|
|
568
|
+
...CRUD_ACTIONS.filter((action) => action !== 'Get').map(
|
|
569
|
+
(action) => `${action}CompleteHdrSqs`
|
|
488
570
|
),
|
|
489
571
|
...state.beforeLogical
|
|
490
572
|
.filter(({ action }) => CRUD_ACTIONS.includes(action))
|
|
491
573
|
.map(({ action }) => `${action}BeforeLogicalHdrSqs`)
|
|
492
574
|
];
|
|
493
|
-
|
|
575
|
+
}
|
|
576
|
+
if (roleName === 'FlowRelationshipRole') {
|
|
494
577
|
return [
|
|
495
|
-
...RELATIONSHIP_ACTIONS.flatMap(action => [
|
|
578
|
+
...RELATIONSHIP_ACTIONS.flatMap((action) => [
|
|
496
579
|
`${action}HdrSqs`,
|
|
497
580
|
`${action}CompleteHdrSqs`
|
|
498
581
|
]),
|
|
499
582
|
'GetRelationshipHdrDsq'
|
|
500
583
|
];
|
|
501
|
-
|
|
502
|
-
|
|
584
|
+
}
|
|
585
|
+
if (roleName === 'FlowRbacRole') {
|
|
586
|
+
return RBAC_ACTIONS.flatMap((action) => [
|
|
503
587
|
`${action}HdrSqs`,
|
|
504
588
|
`Process${action}HdrSqs`
|
|
505
589
|
]);
|
|
590
|
+
}
|
|
506
591
|
const flow = state.flows.find(
|
|
507
|
-
candidate => customFlowRoleName(candidate?.flowTag ?? '') === roleName
|
|
592
|
+
(candidate) => customFlowRoleName(candidate?.flowTag ?? '') === roleName
|
|
508
593
|
);
|
|
509
|
-
if (!flow)
|
|
594
|
+
if (!flow) {
|
|
595
|
+
return [];
|
|
596
|
+
}
|
|
510
597
|
const tag = upperFirst(flow.flowTag);
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
598
|
+
const queueList = [];
|
|
599
|
+
if (includesEvent(flow, 'extTopic')) {
|
|
600
|
+
queueList.push(`${tag}HdrSqs`);
|
|
601
|
+
}
|
|
602
|
+
if (includesEvent(flow, 'ownTopic')) {
|
|
603
|
+
queueList.push(`${tag}HdrSqs`);
|
|
604
|
+
}
|
|
605
|
+
if (includesEvent(flow, 'dsq')) {
|
|
606
|
+
queueList.push(`${tag}HdrDsq`);
|
|
607
|
+
}
|
|
608
|
+
queueList.push(
|
|
515
609
|
...flowExtTopicSteps([flow]).map(
|
|
516
610
|
({ flowTag, stepName }) => `${flowTag}${stepName}HdrSqs`
|
|
517
|
-
)
|
|
611
|
+
)
|
|
612
|
+
);
|
|
613
|
+
queueList.push(
|
|
518
614
|
...flowDsqSteps([flow]).map(
|
|
519
615
|
({ flowTag, stepName }) => `${flowTag}${stepName}HdrDsq`
|
|
520
|
-
)
|
|
616
|
+
)
|
|
617
|
+
);
|
|
618
|
+
queueList.push(
|
|
521
619
|
...state.sqsQueues.filter(
|
|
522
|
-
queueName => includesEvent(flow, 's3') && queueName.startsWith(tag)
|
|
620
|
+
(queueName) => includesEvent(flow, 's3') && queueName.startsWith(tag)
|
|
523
621
|
)
|
|
524
|
-
|
|
622
|
+
);
|
|
623
|
+
return queueList;
|
|
525
624
|
}
|
|
526
625
|
|
|
527
626
|
function roleTopicNames(state, roleName) {
|
|
528
627
|
if (roleName === 'ProcFindDataRole') return [];
|
|
529
628
|
if (roleName === 'FlowObjectsRole')
|
|
530
|
-
return state.outTopics.filter(topic => CRUD_ACTIONS.includes(topic));
|
|
629
|
+
return state.outTopics.filter((topic) => CRUD_ACTIONS.includes(topic));
|
|
531
630
|
if (roleName === 'FlowRelationshipRole')
|
|
532
|
-
return state.outTopics.filter(topic =>
|
|
631
|
+
return state.outTopics.filter((topic) =>
|
|
533
632
|
RELATIONSHIP_ACTIONS.includes(topic)
|
|
534
633
|
);
|
|
535
634
|
if (roleName === 'FlowRbacRole')
|
|
536
|
-
return state.outTopics.filter(topic => RBAC_ACTIONS.includes(topic));
|
|
635
|
+
return state.outTopics.filter((topic) => RBAC_ACTIONS.includes(topic));
|
|
537
636
|
const flow = state.flows.find(
|
|
538
|
-
candidate => customFlowRoleName(candidate?.flowTag ?? '') === roleName
|
|
637
|
+
(candidate) => customFlowRoleName(candidate?.flowTag ?? '') === roleName
|
|
539
638
|
);
|
|
540
639
|
return flow
|
|
541
|
-
? state.outTopics.filter(topic => topic === upperFirst(flow.flowTag))
|
|
640
|
+
? state.outTopics.filter((topic) => topic === upperFirst(flow.flowTag))
|
|
542
641
|
: [];
|
|
543
642
|
}
|
|
544
643
|
|
|
@@ -546,7 +645,7 @@ function dynamoArns(tableNames) {
|
|
|
546
645
|
return [...new Set(tableNames)]
|
|
547
646
|
.sort()
|
|
548
647
|
.map(
|
|
549
|
-
tableName =>
|
|
648
|
+
(tableName) =>
|
|
550
649
|
`arn:aws:dynamodb:${'${self:custom.iz_region}'}:${'${self:custom.iz_accountId}'}:table/${'${self:custom.iz_resourcePrefix}'}${tableName}`
|
|
551
650
|
);
|
|
552
651
|
}
|
|
@@ -601,7 +700,7 @@ function queueArns(queueNames) {
|
|
|
601
700
|
return [...new Set(queueNames)]
|
|
602
701
|
.sort()
|
|
603
702
|
.map(
|
|
604
|
-
queueName =>
|
|
703
|
+
(queueName) =>
|
|
605
704
|
`arn:aws:sqs:${'${self:custom.iz_region}'}:${'${self:custom.iz_accountId}'}:${'${self:custom.iz_resourcePrefix}'}${queueName}`
|
|
606
705
|
);
|
|
607
706
|
}
|
|
@@ -610,13 +709,13 @@ function topicArns(topicNames) {
|
|
|
610
709
|
return [...new Set(topicNames)]
|
|
611
710
|
.sort()
|
|
612
711
|
.map(
|
|
613
|
-
topic =>
|
|
712
|
+
(topic) =>
|
|
614
713
|
`arn:aws:sns:${'${self:custom.iz_region}'}:${'${self:custom.iz_accountId}'}:${'${self:custom.iz_serviceTag}'}_${'${self:custom.iz_stage}'}_${topic}_Out`
|
|
615
714
|
);
|
|
616
715
|
}
|
|
617
716
|
|
|
618
717
|
function renderWebSocketSubscription(topicName) {
|
|
619
|
-
return
|
|
718
|
+
return render('WebSocketSubscription_Yaml.ejs', { topicName });
|
|
620
719
|
}
|
|
621
720
|
|
|
622
721
|
function collectTables(schemas) {
|
|
@@ -629,13 +728,13 @@ function collectTables(schemas) {
|
|
|
629
728
|
const pk =
|
|
630
729
|
keyName(
|
|
631
730
|
identifiers.find(
|
|
632
|
-
identifier =>
|
|
731
|
+
(identifier) =>
|
|
633
732
|
identifier.type === 'partitionKey' ||
|
|
634
733
|
identifier.type === 'identifier'
|
|
635
734
|
)
|
|
636
735
|
) ?? 'PK';
|
|
637
736
|
const sk = keyName(
|
|
638
|
-
identifiers.find(identifier => identifier.type === 'sortKey')
|
|
737
|
+
identifiers.find((identifier) => identifier.type === 'sortKey')
|
|
639
738
|
);
|
|
640
739
|
for (const resource of Object.values(schema.storageResources)) {
|
|
641
740
|
if (
|
|
@@ -650,13 +749,13 @@ function collectTables(schemas) {
|
|
|
650
749
|
}
|
|
651
750
|
|
|
652
751
|
function keyName(identifier) {
|
|
653
|
-
if (!identifier) return
|
|
752
|
+
if (!identifier) return null;
|
|
654
753
|
return (
|
|
655
754
|
identifier.name ??
|
|
656
755
|
identifier.fieldName ??
|
|
657
756
|
(Array.isArray(identifier.fieldNames)
|
|
658
757
|
? identifier.fieldNames.join(identifier.deliminator ?? '_')
|
|
659
|
-
:
|
|
758
|
+
: null)
|
|
660
759
|
);
|
|
661
760
|
}
|
|
662
761
|
|
|
@@ -669,7 +768,7 @@ function isCrudObject(object) {
|
|
|
669
768
|
function hasRbacAddOn(object) {
|
|
670
769
|
return (
|
|
671
770
|
Array.isArray(object?.addOnDataStructure) &&
|
|
672
|
-
object.addOnDataStructure.some(addOn => addOn?.type === 'rbac')
|
|
771
|
+
object.addOnDataStructure.some((addOn) => addOn?.type === 'rbac')
|
|
673
772
|
);
|
|
674
773
|
}
|
|
675
774
|
function includesEvent(flow, event) {
|
|
@@ -683,8 +782,35 @@ function upperFirst(value) {
|
|
|
683
782
|
function normalizeYaml(content) {
|
|
684
783
|
return `${content.trimEnd()}\n`;
|
|
685
784
|
}
|
|
785
|
+
function renderCorsYaml() {
|
|
786
|
+
return `allowedOrigins:
|
|
787
|
+
- '*'
|
|
788
|
+
allowedHeaders:
|
|
789
|
+
- content-type
|
|
790
|
+
- x-amz-date
|
|
791
|
+
- authorization
|
|
792
|
+
- x-api-key
|
|
793
|
+
- x-amz-security-token
|
|
794
|
+
- x-amz-user-agent
|
|
795
|
+
- x-amzn-trace-id
|
|
796
|
+
allowedMethods:
|
|
797
|
+
- POST
|
|
798
|
+
- OPTIONS
|
|
799
|
+
maxAge: 0
|
|
800
|
+
allowCredentials: false
|
|
801
|
+
`;
|
|
802
|
+
}
|
|
803
|
+
function renderRoleNameConfigYaml(roles) {
|
|
804
|
+
return [
|
|
805
|
+
'# for createIamRole',
|
|
806
|
+
...roles.map(
|
|
807
|
+
(roleName) =>
|
|
808
|
+
`- arn:aws:iam::\${self:custom.iz_accountId}:role/\${self:custom.iz_resourcePrefix}${roleName}`
|
|
809
|
+
)
|
|
810
|
+
].join('\n');
|
|
811
|
+
}
|
|
686
812
|
async function render(templateName, data) {
|
|
687
|
-
return
|
|
813
|
+
return ejsLib.render(
|
|
688
814
|
await readFile(new URL(templateName, TEMPLATE_URL), 'utf8'),
|
|
689
815
|
{ resourceQueueName: data.queueName, ...data }
|
|
690
816
|
);
|