@izara_project/izara-core-generate-service-code 1.0.82 → 1.0.84
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 +4 -4
- package/src/compile/flowValidator.js +34 -0
- package/src/compile/loadSchemas.js +121 -7
- package/src/emit/attributeTree/emitAttributeTreeSchemas.js +388 -0
- package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +29 -1
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +16 -3
- package/src/emit/crud/crudActionPlan.js +43 -7
- package/src/emit/crud/emitCrudApplicationArtifacts.js +19 -4
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +27 -6
- package/src/emit/crud/generateCrudApplicationArtifacts.js +3 -2
- package/src/emit/crud/generateDynamicCrudFlowSchemas.js +3 -2
- package/src/emit/crud/loadLocalSchemaArrays.js +3 -3
- package/src/emit/crud/templates/CreateComplete_Main.ejs +1 -1
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +75 -21
- package/src/emit/crud/templates/CreateLogicalLib.ejs +73 -8
- package/src/emit/crud/templates/DeleteComplete_Main.ejs +1 -1
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +39 -11
- package/src/emit/crud/templates/DeleteLogicalLib.ejs +6 -3
- package/src/emit/crud/templates/FlowEndpointRbacCallback_Main.ejs +2 -2
- package/src/emit/crud/templates/FlowEndpoint_HdrWbs.ejs +7 -0
- package/src/emit/crud/templates/FlowMain_Wbs.ejs +5 -2
- package/src/emit/crud/templates/GetEndpoint_Main.ejs +13 -0
- package/src/emit/crud/templates/UpdateComplete_Main.ejs +1 -1
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +53 -4
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +4 -3
- package/src/emit/custom/customFlows.js +49 -0
- package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +168 -49
- package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +1 -1
- package/src/emit/custom/templates/FlowEndpointRbacCallback_Main.ejs +194 -0
- package/src/emit/custom/templates/FlowEndpoint_Main.ejs +14 -22
- package/src/emit/custom/templates/FlowStep_Main.ejs +1 -1
- package/src/emit/function/templates/WbsFunction_Yaml.ejs +0 -2
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +33 -8
- package/src/emit/rbac/emitRbacApplicationArtifacts.js +204 -7
- package/src/emit/rbac/templates/CancelUsage_Main.ejs +103 -0
- package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +71 -0
- package/src/emit/rbac/templates/CreateTargetRole_Main.ejs +49 -6
- package/src/emit/rbac/templates/ListRbac_Main.ejs +9 -3
- package/src/emit/rbac/templates/RbacMutation_Main.ejs +1 -1
- package/src/emit/rbac/templates/ReservedDynamicUsage_Main.ejs +147 -0
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +59 -23
- package/src/emit/rbac/templates/UserRoleMutation_Main.ejs +1 -1
- package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +1 -1
- package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +10 -3
- package/src/emit/resource/emitResourceArtifacts.js +350 -112
- package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +53 -2
- package/src/emit/system/emitSystemWebSocketArtifacts.js +6 -4
- package/src/emit/system/templates/WebSocketConnect.ejs +71 -12
- package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +7 -0
- package/src/emit/systemText/emitSystemTextSchemas.js +3 -2
- package/src/generate.js +41 -10
- package/test/attributeTreeSchemas.test.js +219 -0
- package/test/createTargetRoleHandler.test.js +59 -4
- package/test/crudApplicationArtifacts.test.js +23 -6
- package/test/customFlowApplicationArtifacts.test.js +5 -5
- package/test/dynamicCrudFlowSchemas.test.js +110 -13
- package/test/dynamicRbacFlowSchemas.test.js +15 -2
- package/test/publicApi.test.js +7 -7
- package/test/resourceArtifacts.test.js +70 -29
- package/test/systemTextSchemas.test.js +1 -1
|
@@ -7,7 +7,8 @@ import {
|
|
|
7
7
|
flowExtTopicSteps,
|
|
8
8
|
generatedDsqFlows,
|
|
9
9
|
generatedOwnTopicFlows,
|
|
10
|
-
supportedCustomFlows
|
|
10
|
+
supportedCustomFlows,
|
|
11
|
+
flowHasRbac
|
|
11
12
|
} from '../custom/customFlows.js';
|
|
12
13
|
import { hasSystemWebSocket } from '../system/emitSystemWebSocketArtifacts.js';
|
|
13
14
|
import { rbacFlowTag } from '../rbac/rbacFlowTag.js';
|
|
@@ -38,7 +39,13 @@ const RBAC_ACTIONS = [
|
|
|
38
39
|
'CreateUserRole',
|
|
39
40
|
'ListUserInRoles',
|
|
40
41
|
'DeleteUserFromRole',
|
|
41
|
-
'ValidatorRbac'
|
|
42
|
+
'ValidatorRbac',
|
|
43
|
+
'CreateRoleLimit',
|
|
44
|
+
'ListRoleLimits',
|
|
45
|
+
'DeleteRoleLimit',
|
|
46
|
+
'ReservedDynamicUsage',
|
|
47
|
+
'ConfirmUsage',
|
|
48
|
+
'CancelUsage'
|
|
42
49
|
];
|
|
43
50
|
const SYSTEM_TABLES = [
|
|
44
51
|
'WebSocketTask',
|
|
@@ -57,6 +64,9 @@ const RBAC_TABLES = [
|
|
|
57
64
|
'RoleUsers',
|
|
58
65
|
'UserRoles',
|
|
59
66
|
'RbacPermissionCaches',
|
|
67
|
+
'RoleLimit',
|
|
68
|
+
'RunningTotalUsage',
|
|
69
|
+
'RunningTotalReservedUsage',
|
|
60
70
|
'WebSocketTask'
|
|
61
71
|
];
|
|
62
72
|
const LEGACY_PROCESS_QUEUES = [
|
|
@@ -93,8 +103,23 @@ export async function emitResourceArtifacts({
|
|
|
93
103
|
throw new TypeError('objects, relationships, and flows must be arrays');
|
|
94
104
|
}
|
|
95
105
|
const state = createResourceState({ objects, relationships, flows });
|
|
96
|
-
const [
|
|
97
|
-
|
|
106
|
+
const [
|
|
107
|
+
crudInSqs,
|
|
108
|
+
relationshipInSqs,
|
|
109
|
+
rbacInSqs,
|
|
110
|
+
customFlowInSqs,
|
|
111
|
+
systemInSqs,
|
|
112
|
+
out,
|
|
113
|
+
dynamo,
|
|
114
|
+
iam,
|
|
115
|
+
lambdaRoleConfig,
|
|
116
|
+
s3
|
|
117
|
+
] = await Promise.all([
|
|
118
|
+
renderCrudInSqs(state),
|
|
119
|
+
renderRelationshipInSqs(state),
|
|
120
|
+
renderRbacInSqs(state),
|
|
121
|
+
renderCustomFlowInSqs(state),
|
|
122
|
+
renderSystemInSqs(state),
|
|
98
123
|
renderOut(state),
|
|
99
124
|
renderDynamo(state),
|
|
100
125
|
renderIam(state),
|
|
@@ -102,10 +127,6 @@ export async function emitResourceArtifacts({
|
|
|
102
127
|
renderS3(state)
|
|
103
128
|
]);
|
|
104
129
|
const artifacts = [
|
|
105
|
-
{
|
|
106
|
-
path: `${RESOURCE_ROOT}/generated-sns-in-sqs.yml`,
|
|
107
|
-
content: normalizeYaml(inSqs)
|
|
108
|
-
},
|
|
109
130
|
{
|
|
110
131
|
path: `${RESOURCE_ROOT}/generated-sns-out.yml`,
|
|
111
132
|
content: normalizeYaml(out)
|
|
@@ -123,6 +144,36 @@ export async function emitResourceArtifacts({
|
|
|
123
144
|
content: normalizeYaml(iam.roleNameConfigContent)
|
|
124
145
|
}
|
|
125
146
|
];
|
|
147
|
+
if (crudInSqs) {
|
|
148
|
+
artifacts.push({
|
|
149
|
+
path: `${RESOURCE_ROOT}/generated-sns-sqs-crud.yml`,
|
|
150
|
+
content: normalizeYaml(crudInSqs)
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (relationshipInSqs) {
|
|
154
|
+
artifacts.push({
|
|
155
|
+
path: `${RESOURCE_ROOT}/generated-sns-sqs-relationship.yml`,
|
|
156
|
+
content: normalizeYaml(relationshipInSqs)
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (rbacInSqs) {
|
|
160
|
+
artifacts.push({
|
|
161
|
+
path: `${RESOURCE_ROOT}/generated-sns-sqs-rbac.yml`,
|
|
162
|
+
content: normalizeYaml(rbacInSqs)
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (customFlowInSqs) {
|
|
166
|
+
artifacts.push({
|
|
167
|
+
path: `${RESOURCE_ROOT}/generated-sns-sqs-custom-flows.yml`,
|
|
168
|
+
content: normalizeYaml(customFlowInSqs)
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
if (systemInSqs) {
|
|
172
|
+
artifacts.push({
|
|
173
|
+
path: `${RESOURCE_ROOT}/generated-sns-sqs-system.yml`,
|
|
174
|
+
content: normalizeYaml(systemInSqs)
|
|
175
|
+
});
|
|
176
|
+
}
|
|
126
177
|
if (state.s3Buckets.length > 0) {
|
|
127
178
|
artifacts.push({
|
|
128
179
|
path: `${RESOURCE_ROOT}/generated-s3.yml`,
|
|
@@ -140,6 +191,11 @@ export async function emitResourceArtifacts({
|
|
|
140
191
|
|
|
141
192
|
export const resourceArtifactPaths = [
|
|
142
193
|
`${RESOURCE_ROOT}/generated-sns-in-sqs.yml`,
|
|
194
|
+
`${RESOURCE_ROOT}/generated-sns-sqs-crud.yml`,
|
|
195
|
+
`${RESOURCE_ROOT}/generated-sns-sqs-relationship.yml`,
|
|
196
|
+
`${RESOURCE_ROOT}/generated-sns-sqs-rbac.yml`,
|
|
197
|
+
`${RESOURCE_ROOT}/generated-sns-sqs-custom-flows.yml`,
|
|
198
|
+
`${RESOURCE_ROOT}/generated-sns-sqs-system.yml`,
|
|
143
199
|
`${RESOURCE_ROOT}/generated-sns-out.yml`,
|
|
144
200
|
`${RESOURCE_ROOT}/generated-dynamoDB-table.yml`,
|
|
145
201
|
`${RESOURCE_ROOT}/generated-s3.yml`,
|
|
@@ -153,65 +209,34 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
153
209
|
const selfRbac = objects.some(hasSelfRbacAddOn);
|
|
154
210
|
const rbac = objects.some(hasSelfRbacAddOn);
|
|
155
211
|
const crudActionPlans = createCrudActionPlans(objects);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
...flows
|
|
160
|
-
.filter((flow) => includesEvent(flow, 'ownTopic'))
|
|
161
|
-
.map((flow) => upperFirst(flow.flowTag))
|
|
162
|
-
]);
|
|
163
|
-
const sqsQueues = new Set([
|
|
164
|
-
'PaginateProcessLogicalHdrDsq',
|
|
165
|
-
'PaginateProcessLogicalHdrSqs',
|
|
166
|
-
...flows
|
|
167
|
-
.filter((flow) => includesEvent(flow, 'extTopic'))
|
|
168
|
-
.map((flow) => `Process${upperFirst(flow.flowTag)}HdrSqs`),
|
|
169
|
-
...flows
|
|
170
|
-
.filter((flow) => flow?.outputTopic && !flow?.generatedCodeConfig && upperFirst(flow.flowTag))
|
|
171
|
-
.map((flow) => `${upperFirst(flow.flowTag)}CompleteHdrSqs`)
|
|
172
|
-
]);
|
|
173
|
-
for (const { flowTag, stepName } of flowExtTopicSteps(flows)) {
|
|
174
|
-
sqsQueues.add(`${flowTag}${stepName}HdrSqs`);
|
|
175
|
-
}
|
|
176
|
-
for (const flow of flows.filter((flow) => includesEvent(flow, 's3'))) {
|
|
177
|
-
const tag = upperFirst(flow.flowTag);
|
|
178
|
-
sqsQueues.add(`${tag}CreatePreSignUrlHdrSqs`);
|
|
179
|
-
sqsQueues.add(`${tag}ReservedLimitHdrSqs`);
|
|
180
|
-
sqsQueues.add(`${tag}ConfirmAfterUploadHdrSqs`);
|
|
181
|
-
}
|
|
182
|
-
const dsqQueues = new Set(
|
|
183
|
-
flows
|
|
184
|
-
.filter((flow) => includesEvent(flow, 'dsq'))
|
|
185
|
-
.map((flow) => `${upperFirst(flow.flowTag)}HdrDsq`)
|
|
186
|
-
);
|
|
187
|
-
for (const { flowTag, stepName } of flowDsqSteps(flows)) {
|
|
188
|
-
dsqQueues.add(`${flowTag}${stepName}HdrDsq`);
|
|
189
|
-
}
|
|
212
|
+
|
|
213
|
+
const crudOwnTopics = crud ? [...CRUD_ACTIONS] : [];
|
|
214
|
+
const crudSqsQueues = [];
|
|
190
215
|
if (crud) {
|
|
191
|
-
for (const action of CRUD_ACTIONS) {
|
|
192
|
-
ownTopics.add(action);
|
|
193
|
-
}
|
|
194
216
|
for (const action of ['Create', 'Update', 'Delete']) {
|
|
195
217
|
const plan = crudActionPlans[action];
|
|
196
218
|
if (plan.hasComplete) {
|
|
197
|
-
|
|
198
|
-
}
|
|
199
|
-
if (plan.hasRbacCallback) {
|
|
200
|
-
sqsQueues.add(`${action}RbacCallbackHdrSqs`);
|
|
219
|
+
crudSqsQueues.push(`${action}CompleteHdrSqs`);
|
|
201
220
|
}
|
|
202
221
|
}
|
|
203
222
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
223
|
+
|
|
224
|
+
const relationshipOwnTopics = relationships.length > 0
|
|
225
|
+
? [...RELATIONSHIP_ACTIONS]
|
|
226
|
+
: [];
|
|
227
|
+
const relationshipSqsQueues = relationships.length > 0
|
|
228
|
+
? RELATIONSHIP_ACTIONS.map((action) => `${action}CompleteHdrSqs`)
|
|
229
|
+
: [];
|
|
230
|
+
const relationshipDsqQueues = relationships.length > 0
|
|
231
|
+
? ['GetRelationshipHdrDsq']
|
|
232
|
+
: [];
|
|
233
|
+
|
|
234
|
+
const rbacOwnTopics = [];
|
|
235
|
+
const rbacSqsQueues = [];
|
|
211
236
|
if (selfRbac) {
|
|
212
237
|
for (const action of RBAC_ACTIONS) {
|
|
213
|
-
|
|
214
|
-
|
|
238
|
+
rbacOwnTopics.push(action);
|
|
239
|
+
rbacSqsQueues.push(`Process${action}HdrSqs`);
|
|
215
240
|
}
|
|
216
241
|
}
|
|
217
242
|
if (rbac) {
|
|
@@ -219,9 +244,93 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
219
244
|
...new Set(objects.filter(hasRbacAddOn).map(rbacFlowTag))
|
|
220
245
|
];
|
|
221
246
|
for (const flowTag of flowTags) {
|
|
222
|
-
|
|
247
|
+
rbacOwnTopics.push(flowTag);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (crud) {
|
|
251
|
+
for (const action of ['Create', 'Update', 'Delete']) {
|
|
252
|
+
const plan = crudActionPlans[action];
|
|
253
|
+
if (plan.hasRbacCallback) {
|
|
254
|
+
rbacSqsQueues.push(`${action}RbacCallbackHdrSqs`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const customOwnTopics = flows
|
|
260
|
+
.filter((flow) => includesEvent(flow, 'ownTopic'))
|
|
261
|
+
.map((flow) => upperFirst(flow.flowTag));
|
|
262
|
+
|
|
263
|
+
const customSqsQueues = [
|
|
264
|
+
...flows
|
|
265
|
+
.filter((flow) => includesEvent(flow, 'extTopic'))
|
|
266
|
+
.map((flow) => `Process${upperFirst(flow.flowTag)}HdrSqs`),
|
|
267
|
+
...flows
|
|
268
|
+
.filter(
|
|
269
|
+
(flow) =>
|
|
270
|
+
flow?.outputTopic &&
|
|
271
|
+
!flow?.generatedCodeConfig &&
|
|
272
|
+
upperFirst(flow.flowTag)
|
|
273
|
+
)
|
|
274
|
+
.map((flow) => `${upperFirst(flow.flowTag)}CompleteHdrSqs`)
|
|
275
|
+
];
|
|
276
|
+
for (const { flowTag, stepName } of flowExtTopicSteps(flows)) {
|
|
277
|
+
customSqsQueues.push(`${flowTag}${stepName}HdrSqs`);
|
|
278
|
+
}
|
|
279
|
+
for (const flow of flows) {
|
|
280
|
+
if (flowHasRbac(flow, objects)) {
|
|
281
|
+
const tag = upperFirst(flow.flowTag);
|
|
282
|
+
customSqsQueues.push(`${tag}RbacCallbackHdrSqs`);
|
|
223
283
|
}
|
|
224
284
|
}
|
|
285
|
+
for (const flow of flows.filter((flow) => includesEvent(flow, 's3'))) {
|
|
286
|
+
const tag = upperFirst(flow.flowTag);
|
|
287
|
+
customSqsQueues.push(`${tag}CreatePreSignUrlHdrSqs`);
|
|
288
|
+
customSqsQueues.push(`${tag}ReservedLimitHdrSqs`);
|
|
289
|
+
customSqsQueues.push(`${tag}ConfirmAfterUploadHdrSqs`);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const customDsqQueues = flows
|
|
293
|
+
.filter((flow) => includesEvent(flow, 'dsq'))
|
|
294
|
+
.map((flow) => `${upperFirst(flow.flowTag)}HdrDsq`);
|
|
295
|
+
for (const { flowTag, stepName } of flowDsqSteps(flows)) {
|
|
296
|
+
customDsqQueues.push(`${flowTag}${stepName}HdrDsq`);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const websocket = hasSystemWebSocket(flows, {
|
|
300
|
+
includeRelationshipOwnTopic: true,
|
|
301
|
+
objects,
|
|
302
|
+
relationships
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const systemOwnTopics = ['ProcessLogical', 'FindData'];
|
|
306
|
+
const systemSqsQueues = [
|
|
307
|
+
'PaginateProcessLogicalHdrSqs',
|
|
308
|
+
...(websocket
|
|
309
|
+
? ['WebSocketCompleteHdrSqs', 'RegisterCompleteHdrSqs']
|
|
310
|
+
: [])
|
|
311
|
+
];
|
|
312
|
+
const systemDsqQueues = ['PaginateProcessLogicalHdrDsq'];
|
|
313
|
+
|
|
314
|
+
const ownTopics = new Set([
|
|
315
|
+
...systemOwnTopics,
|
|
316
|
+
...crudOwnTopics,
|
|
317
|
+
...relationshipOwnTopics,
|
|
318
|
+
...rbacOwnTopics,
|
|
319
|
+
...customOwnTopics
|
|
320
|
+
]);
|
|
321
|
+
const sqsQueues = new Set([
|
|
322
|
+
...systemSqsQueues,
|
|
323
|
+
...crudSqsQueues,
|
|
324
|
+
...relationshipSqsQueues,
|
|
325
|
+
...rbacSqsQueues,
|
|
326
|
+
...customSqsQueues
|
|
327
|
+
]);
|
|
328
|
+
const dsqQueues = new Set([
|
|
329
|
+
...systemDsqQueues,
|
|
330
|
+
...relationshipDsqQueues,
|
|
331
|
+
...customDsqQueues
|
|
332
|
+
]);
|
|
333
|
+
|
|
225
334
|
const customRoles = [
|
|
226
335
|
...new Set([
|
|
227
336
|
...supportedCustomFlows(flows).map((flow) =>
|
|
@@ -236,12 +345,11 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
236
345
|
...flowExtTopicSteps(flows).map(({ flow }) =>
|
|
237
346
|
customFlowRoleName(flow.flowTag)
|
|
238
347
|
),
|
|
239
|
-
...flowDsqSteps(flows).map(({ flow }) =>
|
|
348
|
+
...flowDsqSteps(flows).map(({ flow }) =>
|
|
349
|
+
customFlowRoleName(flow.flowTag)
|
|
350
|
+
)
|
|
240
351
|
])
|
|
241
352
|
];
|
|
242
|
-
const websocket = hasSystemWebSocket(flows, {
|
|
243
|
-
includeRelationshipOwnTopic: true
|
|
244
|
-
});
|
|
245
353
|
const webSocketRoles = new Set();
|
|
246
354
|
if (websocket) {
|
|
247
355
|
webSocketRoles.add('WebSocketMainRole');
|
|
@@ -286,7 +394,8 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
286
394
|
.filter((flow) => includesEvent(flow, 's3'))
|
|
287
395
|
.map((flow) => {
|
|
288
396
|
const tag = upperFirst(flow.flowTag);
|
|
289
|
-
const outputTopicStr =
|
|
397
|
+
const outputTopicStr =
|
|
398
|
+
typeof flow.outputTopic === 'string' ? flow.outputTopic : null;
|
|
290
399
|
const topicName = outputTopicStr
|
|
291
400
|
? (outputTopicStr.startsWith('Out')
|
|
292
401
|
? outputTopicStr
|
|
@@ -301,7 +410,16 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
301
410
|
});
|
|
302
411
|
const systemTables = [...SYSTEM_TABLES];
|
|
303
412
|
if (rbac) {
|
|
304
|
-
systemTables.push(
|
|
413
|
+
systemTables.push(
|
|
414
|
+
'TargetRoles',
|
|
415
|
+
'RolePermissions',
|
|
416
|
+
'RoleUsers',
|
|
417
|
+
'UserRoles',
|
|
418
|
+
'RbacPermissionCaches',
|
|
419
|
+
'RoleLimit',
|
|
420
|
+
'RunningTotalUsage',
|
|
421
|
+
'RunningTotalReservedUsage'
|
|
422
|
+
);
|
|
305
423
|
}
|
|
306
424
|
if (s3FlowTags.length > 0) {
|
|
307
425
|
systemTables.push('ReservedDataMain');
|
|
@@ -315,6 +433,25 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
315
433
|
crud,
|
|
316
434
|
rbac,
|
|
317
435
|
crudActionPlans,
|
|
436
|
+
crudOwnTopics: [...new Set(crudOwnTopics)].filter(Boolean).sort(),
|
|
437
|
+
crudSqsQueues: [...new Set(crudSqsQueues)].filter(Boolean).sort(),
|
|
438
|
+
relationshipOwnTopics: [...new Set(relationshipOwnTopics)]
|
|
439
|
+
.filter(Boolean)
|
|
440
|
+
.sort(),
|
|
441
|
+
relationshipSqsQueues: [...new Set(relationshipSqsQueues)]
|
|
442
|
+
.filter(Boolean)
|
|
443
|
+
.sort(),
|
|
444
|
+
relationshipDsqQueues: [...new Set(relationshipDsqQueues)]
|
|
445
|
+
.filter(Boolean)
|
|
446
|
+
.sort(),
|
|
447
|
+
rbacOwnTopics: [...new Set(rbacOwnTopics)].filter(Boolean).sort(),
|
|
448
|
+
rbacSqsQueues: [...new Set(rbacSqsQueues)].filter(Boolean).sort(),
|
|
449
|
+
customOwnTopics: [...new Set(customOwnTopics)].filter(Boolean).sort(),
|
|
450
|
+
customSqsQueues: [...new Set(customSqsQueues)].filter(Boolean).sort(),
|
|
451
|
+
customDsqQueues: [...new Set(customDsqQueues)].filter(Boolean).sort(),
|
|
452
|
+
systemOwnTopics: [...new Set(systemOwnTopics)].filter(Boolean).sort(),
|
|
453
|
+
systemSqsQueues: [...new Set(systemSqsQueues)].filter(Boolean).sort(),
|
|
454
|
+
systemDsqQueues: [...new Set(systemDsqQueues)].filter(Boolean).sort(),
|
|
318
455
|
s3Subscriptions,
|
|
319
456
|
s3FlowTags,
|
|
320
457
|
hasHttpApi,
|
|
@@ -333,7 +470,8 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
333
470
|
(flow) =>
|
|
334
471
|
(flow?.outputTopic ||
|
|
335
472
|
(includesEvent(flow, 'ownTopic') &&
|
|
336
|
-
flow.initiateBy === 'user'
|
|
473
|
+
(flow.initiateBy === 'user' ||
|
|
474
|
+
flow.initiateBy === 'systemWithUser'))) &&
|
|
337
475
|
upperFirst(flow.flowTag) === topic
|
|
338
476
|
) ||
|
|
339
477
|
(relationships.length > 0 &&
|
|
@@ -395,35 +533,39 @@ async function renderS3(state) {
|
|
|
395
533
|
return `Resources:\n${indentYaml(chunks.join('\n'), 2)}`;
|
|
396
534
|
}
|
|
397
535
|
|
|
398
|
-
async function
|
|
536
|
+
async function renderResourceGroup({
|
|
537
|
+
ownTopics = [],
|
|
538
|
+
sqsQueues = [],
|
|
539
|
+
dsqQueues = [],
|
|
540
|
+
webSocketSubscriptions = [],
|
|
541
|
+
s3Subscriptions = []
|
|
542
|
+
}) {
|
|
543
|
+
const hasResources =
|
|
544
|
+
ownTopics.length > 0 ||
|
|
545
|
+
sqsQueues.length > 0 ||
|
|
546
|
+
dsqQueues.length > 0 ||
|
|
547
|
+
webSocketSubscriptions.length > 0 ||
|
|
548
|
+
s3Subscriptions.length > 0;
|
|
549
|
+
if (!hasResources) return '';
|
|
550
|
+
|
|
399
551
|
const chunks = await Promise.all([
|
|
400
|
-
...
|
|
552
|
+
...ownTopics.map((queueName) =>
|
|
401
553
|
render('ResourceYaml.ejs', { queueName })
|
|
402
554
|
),
|
|
403
|
-
...
|
|
555
|
+
...sqsQueues.map((queueName) =>
|
|
404
556
|
render('ResourceSqsYaml.ejs', { queueName })
|
|
405
557
|
),
|
|
406
|
-
...
|
|
558
|
+
...dsqQueues.map((queueName) =>
|
|
407
559
|
render('ResourceSqsYaml.ejs', { queueName })
|
|
408
|
-
)
|
|
409
|
-
...(state.websocket
|
|
410
|
-
? [
|
|
411
|
-
render('ResourceSqsYaml.ejs', {
|
|
412
|
-
queueName: 'WebSocketCompleteHdrSqs'
|
|
413
|
-
}),
|
|
414
|
-
render('ResourceSqsYaml.ejs', {
|
|
415
|
-
queueName: 'RegisterCompleteHdrSqs'
|
|
416
|
-
})
|
|
417
|
-
]
|
|
418
|
-
: [])
|
|
560
|
+
)
|
|
419
561
|
]);
|
|
420
|
-
const
|
|
421
|
-
|
|
562
|
+
const wsSubs = await Promise.all(
|
|
563
|
+
webSocketSubscriptions.map((topicName) =>
|
|
422
564
|
renderWebSocketSubscription(topicName)
|
|
423
565
|
)
|
|
424
566
|
);
|
|
425
|
-
const
|
|
426
|
-
|
|
567
|
+
const s3Subs = await Promise.all(
|
|
568
|
+
s3Subscriptions.map(
|
|
427
569
|
({ subscriptionName, topicName, queueName }) =>
|
|
428
570
|
render('S3Subscription_Yaml.ejs', {
|
|
429
571
|
subscriptionName,
|
|
@@ -433,16 +575,53 @@ async function renderInSqs(state) {
|
|
|
433
575
|
)
|
|
434
576
|
);
|
|
435
577
|
const parts = [chunks.join('\n')];
|
|
436
|
-
if (
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
if (
|
|
440
|
-
parts.push(s3Subscriptions.join('\n'));
|
|
441
|
-
}
|
|
442
|
-
const body = parts.join('\n');
|
|
578
|
+
if (wsSubs.length > 0) parts.push(wsSubs.join('\n'));
|
|
579
|
+
if (s3Subs.length > 0) parts.push(s3Subs.join('\n'));
|
|
580
|
+
const body = parts.filter(Boolean).join('\n');
|
|
581
|
+
if (!body.trim()) return '';
|
|
443
582
|
return `Resources:\n${indentYaml(body, 2)}`;
|
|
444
583
|
}
|
|
445
584
|
|
|
585
|
+
async function renderCrudInSqs(state) {
|
|
586
|
+
return renderResourceGroup({
|
|
587
|
+
ownTopics: state.crudOwnTopics,
|
|
588
|
+
sqsQueues: state.crudSqsQueues
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
async function renderRelationshipInSqs(state) {
|
|
593
|
+
return renderResourceGroup({
|
|
594
|
+
ownTopics: state.relationshipOwnTopics,
|
|
595
|
+
sqsQueues: state.relationshipSqsQueues,
|
|
596
|
+
dsqQueues: state.relationshipDsqQueues
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
async function renderRbacInSqs(state) {
|
|
601
|
+
return renderResourceGroup({
|
|
602
|
+
ownTopics: state.rbacOwnTopics,
|
|
603
|
+
sqsQueues: state.rbacSqsQueues
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
async function renderCustomFlowInSqs(state) {
|
|
608
|
+
return renderResourceGroup({
|
|
609
|
+
ownTopics: state.customOwnTopics,
|
|
610
|
+
sqsQueues: state.customSqsQueues,
|
|
611
|
+
dsqQueues: state.customDsqQueues,
|
|
612
|
+
s3Subscriptions: state.s3Subscriptions
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
async function renderSystemInSqs(state) {
|
|
617
|
+
return renderResourceGroup({
|
|
618
|
+
ownTopics: state.systemOwnTopics,
|
|
619
|
+
sqsQueues: state.systemSqsQueues,
|
|
620
|
+
dsqQueues: state.systemDsqQueues,
|
|
621
|
+
webSocketSubscriptions: state.webSocketSubscriptions
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
|
|
446
625
|
async function renderOut(state) {
|
|
447
626
|
const body = (
|
|
448
627
|
await Promise.all(
|
|
@@ -516,7 +695,13 @@ function roleStatements(state, roleName) {
|
|
|
516
695
|
statements.push({
|
|
517
696
|
action: ['s3:GetObject'],
|
|
518
697
|
resource: [
|
|
519
|
-
'arn:aws:s3:::${self:custom.iz_serviceSchemaBucketName}
|
|
698
|
+
'arn:aws:s3:::${self:custom.iz_serviceSchemaBucketName}/*'
|
|
699
|
+
]
|
|
700
|
+
});
|
|
701
|
+
statements.push({
|
|
702
|
+
action: ['s3:ListBucket'],
|
|
703
|
+
resource: [
|
|
704
|
+
'arn:aws:s3:::${self:custom.iz_serviceSchemaBucketName}'
|
|
520
705
|
]
|
|
521
706
|
});
|
|
522
707
|
}
|
|
@@ -571,7 +756,17 @@ function roleTableNames(state, roleName) {
|
|
|
571
756
|
...state.objectTableNames,
|
|
572
757
|
'AwaitingMultipleSteps',
|
|
573
758
|
'AwaitingMultipleStepByPending',
|
|
574
|
-
'WebSocketTask'
|
|
759
|
+
'WebSocketTask',
|
|
760
|
+
...(state.rbac
|
|
761
|
+
? [
|
|
762
|
+
'TargetRoles',
|
|
763
|
+
'RoleUsers',
|
|
764
|
+
'UserRoles',
|
|
765
|
+
'RoleLimit',
|
|
766
|
+
'RunningTotalUsage',
|
|
767
|
+
'RunningTotalReservedUsage'
|
|
768
|
+
]
|
|
769
|
+
: [])
|
|
575
770
|
];
|
|
576
771
|
if (roleName === 'FlowRelationshipRole')
|
|
577
772
|
return [
|
|
@@ -610,7 +805,7 @@ function dynamoActionsForRole(roleName) {
|
|
|
610
805
|
return ['dynamodb:GetItem', 'dynamodb:Query', 'dynamodb:UpdateItem'];
|
|
611
806
|
if (roleName === 'WebSocketMainRole')
|
|
612
807
|
return ['dynamodb:DeleteItem', 'dynamodb:PutItem', 'dynamodb:Query'];
|
|
613
|
-
if (roleName === 'FlowRbacRole')
|
|
808
|
+
if (roleName === 'FlowRbacRole' || roleName === 'FlowObjectsRole')
|
|
614
809
|
return [...DYNAMO_ACTIONS, 'dynamodb:TransactWriteItems'];
|
|
615
810
|
return DYNAMO_ACTIONS;
|
|
616
811
|
}
|
|
@@ -676,6 +871,9 @@ function roleQueueNames(state, roleName) {
|
|
|
676
871
|
if (includesEvent(flow, 'dsq')) {
|
|
677
872
|
queueList.push(`${tag}HdrDsq`);
|
|
678
873
|
}
|
|
874
|
+
if (flowHasRbac(flow, state.objects)) {
|
|
875
|
+
queueList.push(`${tag}RbacCallbackHdrSqs`);
|
|
876
|
+
}
|
|
679
877
|
queueList.push(
|
|
680
878
|
...flowExtTopicSteps([flow]).map(
|
|
681
879
|
({ flowTag, stepName }) => `${flowTag}${stepName}HdrSqs`
|
|
@@ -707,21 +905,58 @@ function roleDlqQueueNames(state, roleName) {
|
|
|
707
905
|
|
|
708
906
|
function roleTopicNames(state, roleName) {
|
|
709
907
|
if (roleName === 'ProcFindDataRole')
|
|
710
|
-
return state.outTopics.filter((topic) => topic === 'FindData');
|
|
711
|
-
if (roleName === 'FlowObjectsRole')
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
908
|
+
return state.outTopics.filter((topic) => topic === 'FindData').map((t) => `${t}_Out`);
|
|
909
|
+
if (roleName === 'FlowObjectsRole') {
|
|
910
|
+
const actions = state.outTopics.filter((topic) => CRUD_ACTIONS.includes(topic));
|
|
911
|
+
const topics = [];
|
|
912
|
+
for (const action of actions) {
|
|
913
|
+
if (action === 'Get') {
|
|
914
|
+
topics.push(`${action}_Out`);
|
|
915
|
+
} else {
|
|
916
|
+
topics.push(`${action}_In`, `${action}_Out`);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return topics;
|
|
920
|
+
}
|
|
921
|
+
if (roleName === 'FlowRelationshipRole') {
|
|
922
|
+
const actions = state.outTopics.filter((topic) => RELATIONSHIP_ACTIONS.includes(topic));
|
|
923
|
+
const topics = [];
|
|
924
|
+
for (const action of actions) {
|
|
925
|
+
if (action === 'GetRelationship') {
|
|
926
|
+
topics.push(`${action}_Out`);
|
|
927
|
+
} else {
|
|
928
|
+
topics.push(`${action}_In`, `${action}_Out`);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
return topics;
|
|
932
|
+
}
|
|
933
|
+
if (roleName === 'FlowRbacRole') {
|
|
934
|
+
const actions = state.outTopics.filter((topic) => RBAC_ACTIONS.includes(topic));
|
|
935
|
+
const topics = [];
|
|
936
|
+
for (const action of actions) {
|
|
937
|
+
if (action.startsWith('List')) {
|
|
938
|
+
topics.push(`${action}_Out`);
|
|
939
|
+
} else {
|
|
940
|
+
topics.push(`${action}_In`, `${action}_Out`);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
return topics;
|
|
944
|
+
}
|
|
719
945
|
const flow = state.flows.find(
|
|
720
946
|
(candidate) => customFlowRoleName(candidate?.flowTag ?? '') === roleName
|
|
721
947
|
);
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
948
|
+
if (flow && flow.flowTag) {
|
|
949
|
+
const name = upperFirst(flow.flowTag);
|
|
950
|
+
const topics = [];
|
|
951
|
+
if (state.outTopics.includes(name)) {
|
|
952
|
+
topics.push(`${name}_Out`);
|
|
953
|
+
}
|
|
954
|
+
if (includesEvent(flow, 'ownTopic')) {
|
|
955
|
+
topics.push(`${name}_In`);
|
|
956
|
+
}
|
|
957
|
+
return topics;
|
|
958
|
+
}
|
|
959
|
+
return [];
|
|
725
960
|
}
|
|
726
961
|
|
|
727
962
|
function dynamoArns(tableNames) {
|
|
@@ -793,7 +1028,7 @@ function topicArns(topicNames) {
|
|
|
793
1028
|
.sort()
|
|
794
1029
|
.map(
|
|
795
1030
|
(topic) =>
|
|
796
|
-
`arn:aws:sns:${'${self:custom.iz_region}'}:${'${self:custom.iz_accountId}'}:${'${self:custom.iz_serviceTag}'}_${'${self:custom.iz_stage}'}_${topic}
|
|
1031
|
+
`arn:aws:sns:${'${self:custom.iz_region}'}:${'${self:custom.iz_accountId}'}:${'${self:custom.iz_serviceTag}'}_${'${self:custom.iz_stage}'}_${topic}`
|
|
797
1032
|
);
|
|
798
1033
|
}
|
|
799
1034
|
|
|
@@ -899,11 +1134,14 @@ function keyName(identifier) {
|
|
|
899
1134
|
);
|
|
900
1135
|
}
|
|
901
1136
|
|
|
1137
|
+
const VALID_CRUD_GENERATED_BY = new Set([
|
|
1138
|
+
'user',
|
|
1139
|
+
'systemWithUser',
|
|
1140
|
+
'systemNoUser'
|
|
1141
|
+
]);
|
|
1142
|
+
|
|
902
1143
|
function isCrudObject(object) {
|
|
903
|
-
return (
|
|
904
|
-
object?.generatedBy === 'userGenerated' ||
|
|
905
|
-
object?.generatedBy === 'systemGenerated'
|
|
906
|
-
);
|
|
1144
|
+
return VALID_CRUD_GENERATED_BY.has(object?.generatedBy);
|
|
907
1145
|
}
|
|
908
1146
|
function hasSelfRbacAddOn(object) {
|
|
909
1147
|
return (
|