@izara_project/izara-core-generate-service-code 1.0.77 → 1.0.79
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 +2 -2
- package/src/compile/flowValidator.js +163 -0
- package/src/compile/loadSchemas.js +15 -5
- package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +137 -7
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +132 -17
- package/src/emit/crud/crudActionPlan.js +82 -0
- package/src/emit/crud/emitCrudApplicationArtifacts.js +162 -112
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +43 -65
- package/src/emit/crud/generateDynamicCrudFlowSchemas.js +4 -1
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +84 -512
- package/src/emit/crud/templates/CreateLogicalLib.ejs +536 -0
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +87 -202
- package/src/emit/crud/templates/DeleteLogicalLib.ejs +213 -0
- package/src/emit/crud/templates/FlowEndpointRbacCallback_Main.ejs +217 -0
- package/src/emit/crud/templates/GetEndpoint_Main.ejs +1 -1
- package/src/emit/crud/templates/GetRangeEndpoint_Main.ejs +9 -2
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +87 -444
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +472 -0
- package/src/emit/custom/customFlows.js +27 -2
- package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +1 -2
- package/src/emit/custom/templates/FlowEndpoint_Main.ejs +10 -3
- 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/triggerCache/CheckTriggerCache_HdrSqs.ejs +2 -2
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +3 -9
- package/src/emit/rbac/emitRbacApplicationArtifacts.js +21 -16
- package/src/emit/rbac/rbacFlowTag.js +2 -7
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +148 -21
- package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +4 -2
- 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 +85 -70
- package/src/emit/resource/templates/GeneratedLambdaRoleServiceConfig.ejs +31 -5
- package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +21 -0
- package/src/emit/resource/templates/WebSocketSubscription_Yaml.ejs +7 -0
- package/src/emit/shared/templates/FlowHandler_HdrApi.ejs +1 -1
- package/src/emit/shared/templates/FlowHandler_HdrDsq.ejs +2 -2
- package/src/emit/shared/templates/FlowHandler_HdrInv.ejs +1 -1
- package/src/emit/shared/templates/FlowHandler_HdrSqs.ejs +2 -2
- package/src/emit/system/emitSystemWebSocketArtifacts.js +2 -2
- package/src/emit/system/templates/RegisterComplete_Yaml.ejs +4 -4
- package/src/emit/systemText/emitSystemTextSchemas.js +246 -0
- package/src/emit/systemText/templates/SystemTextSchemas.ejs +10 -0
- package/src/generate.js +55 -8
- package/test/crudApplicationArtifacts.test.js +147 -19
- package/test/customFlowApplicationArtifacts.test.js +308 -16
- package/test/dynamicCrudFlowSchemas.test.js +150 -14
- package/test/dynamicRbacFlowSchemas.test.js +2 -2
- package/test/dynamicRelationshipFlowSchemas.test.js +1 -1
- package/test/graphDrivenFlowSchema.test.js +257 -0
- package/test/publicApi.test.js +15 -6
- package/test/resourceArtifacts.test.js +25 -19
- package/test/systemTextSchemas.test.js +154 -0
- package/src/emit/crud/templates/CreateComplete_HdrSqs.ejs +0 -99
- package/src/emit/crud/templates/DeleteComplete_HdrSqs.ejs +0 -99
- package/src/emit/crud/templates/FlowEndpointBeforeLogical_Main.ejs +0 -174
- package/src/emit/crud/templates/FlowEndpointComplete_Main.ejs +0 -187
- package/src/emit/crud/templates/UpdateComplete_HdrSqs.ejs +0 -99
- package/src/emit/resource/templates/ResourceBeforeLogicalYaml.ejs +0 -47
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export const CRUD_ACTIONS = ['Create', 'Update', 'Delete', 'Get'];
|
|
2
|
+
|
|
3
|
+
export function createCrudActionPlans(objects = []) {
|
|
4
|
+
const hasGraph = hasGraphStorageResource(objects);
|
|
5
|
+
const hasRbac = objects.some(
|
|
6
|
+
(object) => isCrudObject(object) && hasRbacObject(object, objects)
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
return Object.fromEntries(
|
|
10
|
+
CRUD_ACTIONS.map((action) => [
|
|
11
|
+
action,
|
|
12
|
+
createCrudActionPlan(action, { hasGraph, hasRbac })
|
|
13
|
+
])
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function createCrudActionPlan(
|
|
18
|
+
action,
|
|
19
|
+
{ hasGraph = false, hasRbac = false } = {}
|
|
20
|
+
) {
|
|
21
|
+
const actionHasRbac = action !== 'Create' && action !== 'Get' && hasRbac;
|
|
22
|
+
const outputTopic = action !== 'Get';
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
action,
|
|
26
|
+
outputTopic,
|
|
27
|
+
hasGraph: outputTopic && hasGraph,
|
|
28
|
+
hasRbac: actionHasRbac,
|
|
29
|
+
hasComplete: outputTopic && (actionHasRbac || hasGraph),
|
|
30
|
+
hasRbacCallback: outputTopic && actionHasRbac && hasGraph
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function isCrudObject(object) {
|
|
35
|
+
return (
|
|
36
|
+
object?.generatedBy === 'userGenerated' ||
|
|
37
|
+
object?.generatedBy === 'systemGenerated'
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function hasGraphStorageResource(objects = []) {
|
|
42
|
+
return objects.some((object) =>
|
|
43
|
+
Object.values(object?.storageResources ?? {}).some(
|
|
44
|
+
(resource) =>
|
|
45
|
+
resource?.storageType === 'graph' ||
|
|
46
|
+
resource?.resourceType === 'graph' ||
|
|
47
|
+
resource?.dbType === 'neo4j' ||
|
|
48
|
+
resource?.storageTag?.toLowerCase().includes('graph')
|
|
49
|
+
)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function hasRbacObject(object, objects = []) {
|
|
54
|
+
return (
|
|
55
|
+
hasSelfRbac(object) ||
|
|
56
|
+
Array.isArray(object?.belongToSchema?.addOnDataStructure) &&
|
|
57
|
+
object.belongToSchema.addOnDataStructure.some(
|
|
58
|
+
(addOn) => addOn?.type === 'rbac'
|
|
59
|
+
) ||
|
|
60
|
+
normalizeBelongTo(object).some((target) => {
|
|
61
|
+
if (target?.serviceTag === 'UserAccount') return true;
|
|
62
|
+
const matched = objects.find(
|
|
63
|
+
(candidate) =>
|
|
64
|
+
candidate?.serviceTag === target?.serviceTag &&
|
|
65
|
+
candidate?.objectType === target?.objectType
|
|
66
|
+
);
|
|
67
|
+
return hasSelfRbac(matched);
|
|
68
|
+
})
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function hasSelfRbac(object) {
|
|
73
|
+
return (
|
|
74
|
+
Array.isArray(object?.addOnDataStructure) &&
|
|
75
|
+
object.addOnDataStructure.some((addOn) => addOn?.type === 'rbac')
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function normalizeBelongTo(object) {
|
|
80
|
+
if (!object?.belongTo) return [];
|
|
81
|
+
return Array.isArray(object.belongTo) ? object.belongTo : [object.belongTo];
|
|
82
|
+
}
|
|
@@ -8,7 +8,13 @@ import {
|
|
|
8
8
|
renderWbsFunctionYaml
|
|
9
9
|
} from '../function/functionYamlArtifact.js';
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
import {
|
|
12
|
+
CRUD_ACTIONS,
|
|
13
|
+
createCrudActionPlans,
|
|
14
|
+
isCrudObject
|
|
15
|
+
} from './crudActionPlan.js';
|
|
16
|
+
|
|
17
|
+
const ACTIONS = CRUD_ACTIONS;
|
|
12
18
|
const YAML_PATH = 'app/sls_yaml/generatedCode/source/flow-objects.yml';
|
|
13
19
|
const TEMPLATE_URL = new URL('./templates/', import.meta.url);
|
|
14
20
|
const SHARED_TEMPLATE_URL = new URL('../shared/templates/', import.meta.url);
|
|
@@ -24,7 +30,7 @@ export async function emitCrudApplicationArtifacts({
|
|
|
24
30
|
if (!objects.some(isCrudObject)) return [];
|
|
25
31
|
|
|
26
32
|
const handlers = await Promise.all(
|
|
27
|
-
ACTIONS.map((action) => emitAction(action, objects,
|
|
33
|
+
ACTIONS.map((action) => emitAction(action, objects, serviceTag))
|
|
28
34
|
);
|
|
29
35
|
return [
|
|
30
36
|
...handlers.flatMap((handler) => handler.artifacts),
|
|
@@ -43,6 +49,9 @@ export function crudApplicationManagedPaths() {
|
|
|
43
49
|
...ACTIONS.flatMap((action) => {
|
|
44
50
|
const source = `app/src/generatedCode/FlowObjects/${action}/source`;
|
|
45
51
|
const paths = [`${source}/${action}_Main.js`];
|
|
52
|
+
if (action !== 'Get') {
|
|
53
|
+
paths.unshift(`${source}/${action}LogicalLib.js`);
|
|
54
|
+
}
|
|
46
55
|
if (action === 'Get') {
|
|
47
56
|
paths.push(`${source}/Get_HdrInv.js`, `${source}/Get_HdrApi.js`);
|
|
48
57
|
paths.push(
|
|
@@ -54,10 +63,8 @@ export function crudApplicationManagedPaths() {
|
|
|
54
63
|
`${source}/${action}_HdrSqs.js`,
|
|
55
64
|
`${source}/${action}_WbsMain.js`,
|
|
56
65
|
`${source}/${action}_HdrWbs.js`,
|
|
57
|
-
`${source}/${action}
|
|
58
|
-
`${source}/${action}
|
|
59
|
-
);
|
|
60
|
-
paths.push(
|
|
66
|
+
`${source}/${action}RbacCallback_Main.js`,
|
|
67
|
+
`${source}/${action}RbacCallback_HdrSqs.js`,
|
|
61
68
|
`${source}/${action}Complete_Main.js`,
|
|
62
69
|
`${source}/${action}Complete_HdrSqs.js`
|
|
63
70
|
);
|
|
@@ -68,25 +75,21 @@ export function crudApplicationManagedPaths() {
|
|
|
68
75
|
];
|
|
69
76
|
}
|
|
70
77
|
|
|
71
|
-
async function emitAction(action, objects,
|
|
78
|
+
async function emitAction(action, objects, serviceTag) {
|
|
72
79
|
const source = `app/src/generatedCode/FlowObjects/${action}/source`;
|
|
73
80
|
const handlerRoot = `src/generatedCode/FlowObjects/${action}/source`;
|
|
74
|
-
const
|
|
75
|
-
.filter(
|
|
76
|
-
(flow) =>
|
|
77
|
-
flow?.generatedCodeConfig?.generatedCodeTag?.toLowerCase() ===
|
|
78
|
-
action.toLowerCase()
|
|
79
|
-
)
|
|
80
|
-
.map((flow) => ({ ...flow.generatedCodeConfig, flowTag: flow.flowTag }));
|
|
81
|
+
const plan = createCrudActionPlans(objects)[action];
|
|
81
82
|
const mainFileName = `${action}_Main`;
|
|
82
83
|
const shared = {
|
|
83
84
|
flowTag: action,
|
|
84
85
|
upperCaseFlowTag: action,
|
|
85
86
|
topicArn: `${action}_In`,
|
|
86
|
-
generateCode,
|
|
87
87
|
flow: null,
|
|
88
88
|
flowStepName: '',
|
|
89
|
-
startConfig: null
|
|
89
|
+
startConfig: null,
|
|
90
|
+
objects: action === 'Create' ? [] : objects,
|
|
91
|
+
isCrudObject,
|
|
92
|
+
hasRbacAddOn: (object) => hasRbacAddOn(object, objects)
|
|
90
93
|
};
|
|
91
94
|
const artifacts = [
|
|
92
95
|
{
|
|
@@ -94,6 +97,12 @@ async function emitAction(action, objects, flows, serviceTag) {
|
|
|
94
97
|
content: await render(`${action}Endpoint_Main.ejs`, shared)
|
|
95
98
|
}
|
|
96
99
|
];
|
|
100
|
+
if (action !== 'Get') {
|
|
101
|
+
artifacts.unshift({
|
|
102
|
+
path: `${source}/${action}LogicalLib.js`,
|
|
103
|
+
content: await render(`${action}LogicalLib.ejs`, shared)
|
|
104
|
+
});
|
|
105
|
+
}
|
|
97
106
|
|
|
98
107
|
let targetServiceTag = '${self:custom.iz_serviceName}';
|
|
99
108
|
if (serviceTag) {
|
|
@@ -118,69 +127,75 @@ async function emitAction(action, objects, flows, serviceTag) {
|
|
|
118
127
|
functionName: 'Get',
|
|
119
128
|
queueName: 'GetHdrApi'
|
|
120
129
|
})
|
|
121
|
-
}
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
const functions = [
|
|
122
133
|
{
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
134
|
+
type: 'inv',
|
|
135
|
+
functionName: 'GetHdrInv',
|
|
136
|
+
handlerPath: `${handlerRoot}/Get_HdrInv.main`,
|
|
137
|
+
roleName: 'FlowObjectsRole',
|
|
138
|
+
flowTag: action,
|
|
139
|
+
flowStepName: ''
|
|
129
140
|
},
|
|
130
141
|
{
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
142
|
+
type: 'api',
|
|
143
|
+
functionName: 'GetHdrApi',
|
|
144
|
+
handlerPath: `${handlerRoot}/Get_HdrApi.main`,
|
|
145
|
+
roleName: 'FlowObjectsRole',
|
|
146
|
+
flowTag: action,
|
|
147
|
+
flowStepName: '',
|
|
148
|
+
routes: objects.filter(isCrudObject).map((object) => ({
|
|
149
|
+
path: `/${targetServiceTag}/${object.objectType}/get`,
|
|
150
|
+
upperName: upperFirst(object.objectType)
|
|
151
|
+
}))
|
|
138
152
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
const getRangeRoutes = objects
|
|
156
|
+
.filter(isCrudObject)
|
|
157
|
+
.filter(
|
|
158
|
+
(object) =>
|
|
159
|
+
object.identifiers &&
|
|
160
|
+
object.identifiers.some((i) => i.type === 'sortKey')
|
|
161
|
+
)
|
|
162
|
+
.map((object) => ({
|
|
163
|
+
path: `/${targetServiceTag}/${object.objectType}/getRange`,
|
|
164
|
+
upperName: upperFirst(object.objectType)
|
|
165
|
+
}));
|
|
166
|
+
|
|
167
|
+
if (getRangeRoutes.length > 0) {
|
|
168
|
+
artifacts.push(
|
|
151
169
|
{
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
routes: objects.filter(isCrudObject).map((object) => ({
|
|
159
|
-
path: `/${targetServiceTag}/${object.objectType}/get`,
|
|
160
|
-
upperName: upperFirst(object.objectType)
|
|
161
|
-
}))
|
|
170
|
+
path: `${source}/GetRange_Main.js`,
|
|
171
|
+
content: await render('GetRangeEndpoint_Main.ejs', {
|
|
172
|
+
...shared,
|
|
173
|
+
mainFileName: 'GetRange_Main',
|
|
174
|
+
functionName: 'GetRange'
|
|
175
|
+
})
|
|
162
176
|
},
|
|
163
177
|
{
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
.filter(isCrudObject)
|
|
172
|
-
.filter(
|
|
173
|
-
(object) =>
|
|
174
|
-
object.identifiers &&
|
|
175
|
-
object.identifiers.some((i) => i.type === 'sortKey')
|
|
176
|
-
)
|
|
177
|
-
.map((object) => ({
|
|
178
|
-
path: `/${targetServiceTag}/${object.objectType}/getRange`,
|
|
179
|
-
upperName: upperFirst(object.objectType)
|
|
180
|
-
}))
|
|
178
|
+
path: `${source}/GetRange_HdrApi.js`,
|
|
179
|
+
content: await renderShared('FlowHandler_HdrApi.ejs', {
|
|
180
|
+
...shared,
|
|
181
|
+
mainFileName: 'GetRange_Main',
|
|
182
|
+
functionName: 'GetRange',
|
|
183
|
+
queueName: 'GetRangeHdrApi'
|
|
184
|
+
})
|
|
181
185
|
}
|
|
182
|
-
|
|
183
|
-
|
|
186
|
+
);
|
|
187
|
+
functions.push({
|
|
188
|
+
type: 'api',
|
|
189
|
+
functionName: 'GetRangeHdrApi',
|
|
190
|
+
handlerPath: `${handlerRoot}/GetRange_HdrApi.main`,
|
|
191
|
+
roleName: 'FlowObjectsRole',
|
|
192
|
+
flowTag: 'GetRange',
|
|
193
|
+
flowStepName: '',
|
|
194
|
+
routes: getRangeRoutes
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return { artifacts, functions };
|
|
184
199
|
}
|
|
185
200
|
|
|
186
201
|
artifacts.push(
|
|
@@ -230,68 +245,100 @@ async function emitAction(action, objects, flows, serviceTag) {
|
|
|
230
245
|
flowStepName: ''
|
|
231
246
|
}
|
|
232
247
|
];
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
{
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
248
|
+
|
|
249
|
+
if (plan.hasRbacCallback) {
|
|
250
|
+
const rbacCallbackMain = `${action}RbacCallback_Main`;
|
|
251
|
+
artifacts.push(
|
|
252
|
+
{
|
|
253
|
+
path: `${source}/${rbacCallbackMain}.js`,
|
|
254
|
+
content: await render('FlowEndpointRbacCallback_Main.ejs', shared)
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
path: `${source}/${rbacCallbackMain.replace('_Main', '_HdrSqs')}.js`,
|
|
258
|
+
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
259
|
+
...shared,
|
|
260
|
+
mainFileName: rbacCallbackMain,
|
|
261
|
+
functionName: `${action}RbacCallbackMain`,
|
|
262
|
+
queueName: `${action}RbacCallbackHdrSqs`
|
|
263
|
+
})
|
|
264
|
+
}
|
|
265
|
+
);
|
|
266
|
+
functions.push({
|
|
267
|
+
type: 'sqs',
|
|
268
|
+
functionName: `${action}RbacCallbackHdrSqs`,
|
|
269
|
+
handlerPath: `${handlerRoot}/${action}RbacCallback_HdrSqs.main`,
|
|
270
|
+
roleName: 'FlowObjectsRole',
|
|
271
|
+
queueName: `${action}RbacCallbackHdrSqs`,
|
|
272
|
+
flowTag: action,
|
|
273
|
+
flowStepName: 'RbacCallback'
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (plan.hasComplete) {
|
|
278
|
+
const completeMain = `${action}Complete_Main`;
|
|
260
279
|
artifacts.push(
|
|
261
280
|
{
|
|
262
|
-
path: `${source}/${
|
|
263
|
-
content: await render(
|
|
281
|
+
path: `${source}/${completeMain}.js`,
|
|
282
|
+
content: await render(
|
|
283
|
+
plan.hasRbac ? 'FlowEndpointRbacCallback_Main.ejs' : `${action}Complete_Main.ejs`,
|
|
284
|
+
plan.hasRbac ? shared : { action }
|
|
285
|
+
)
|
|
264
286
|
},
|
|
265
287
|
{
|
|
266
|
-
path: `${source}/${action}
|
|
288
|
+
path: `${source}/${action}Complete_HdrSqs.js`,
|
|
267
289
|
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
268
290
|
...shared,
|
|
269
|
-
mainFileName:
|
|
270
|
-
functionName: `${action}
|
|
271
|
-
queueName: `${action}
|
|
291
|
+
mainFileName: completeMain,
|
|
292
|
+
functionName: `${action}CompleteMain`,
|
|
293
|
+
queueName: `${action}CompleteHdrSqs`
|
|
272
294
|
})
|
|
273
295
|
}
|
|
274
296
|
);
|
|
275
297
|
functions.push({
|
|
276
298
|
type: 'sqs',
|
|
277
|
-
functionName: `${action}
|
|
278
|
-
handlerPath: `${handlerRoot}/${action}
|
|
299
|
+
functionName: `${action}CompleteHdrSqs`,
|
|
300
|
+
handlerPath: `${handlerRoot}/${action}Complete_HdrSqs.main`,
|
|
279
301
|
roleName: 'FlowObjectsRole',
|
|
280
|
-
queueName: `${action}
|
|
302
|
+
queueName: `${action}CompleteHdrSqs`,
|
|
281
303
|
flowTag: action,
|
|
282
|
-
flowStepName: '
|
|
304
|
+
flowStepName: 'Complete'
|
|
283
305
|
});
|
|
284
306
|
}
|
|
307
|
+
|
|
285
308
|
return { artifacts, functions };
|
|
286
309
|
}
|
|
287
310
|
|
|
288
|
-
function
|
|
311
|
+
function hasSelfRbacAddOn(object) {
|
|
289
312
|
return (
|
|
290
|
-
object?.
|
|
291
|
-
object?.
|
|
313
|
+
Array.isArray(object?.addOnDataStructure) &&
|
|
314
|
+
object.addOnDataStructure.some((addOn) => addOn?.type === 'rbac')
|
|
292
315
|
);
|
|
293
316
|
}
|
|
294
317
|
|
|
318
|
+
function hasRbacAddOn(object, objects = []) {
|
|
319
|
+
const selfHasRbac = hasSelfRbacAddOn(object);
|
|
320
|
+
const belongToTargets = object?.belongTo
|
|
321
|
+
? Array.isArray(object.belongTo)
|
|
322
|
+
? object.belongTo
|
|
323
|
+
: [object.belongTo]
|
|
324
|
+
: [];
|
|
325
|
+
const belongToHasRbac =
|
|
326
|
+
(Array.isArray(object?.belongToSchema?.addOnDataStructure) &&
|
|
327
|
+
object.belongToSchema.addOnDataStructure.some(
|
|
328
|
+
(addOn) => addOn?.type === 'rbac'
|
|
329
|
+
)) ||
|
|
330
|
+
belongToTargets.some((target) => {
|
|
331
|
+
if (target?.serviceTag === 'UserAccount') return true;
|
|
332
|
+
const matched = objects.find(
|
|
333
|
+
(candidate) =>
|
|
334
|
+
candidate?.serviceTag === target?.serviceTag &&
|
|
335
|
+
candidate?.objectType === target?.objectType
|
|
336
|
+
);
|
|
337
|
+
return hasSelfRbacAddOn(matched);
|
|
338
|
+
});
|
|
339
|
+
return selfHasRbac || belongToHasRbac;
|
|
340
|
+
}
|
|
341
|
+
|
|
295
342
|
function upperFirst(value) {
|
|
296
343
|
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
297
344
|
}
|
|
@@ -302,7 +349,10 @@ async function render(templateName, data) {
|
|
|
302
349
|
}
|
|
303
350
|
|
|
304
351
|
async function renderShared(templateName, data) {
|
|
305
|
-
const template = await readFile(
|
|
352
|
+
const template = await readFile(
|
|
353
|
+
new URL(templateName, SHARED_TEMPLATE_URL),
|
|
354
|
+
'utf8'
|
|
355
|
+
);
|
|
306
356
|
return ejsLib.render(template, data);
|
|
307
357
|
}
|
|
308
358
|
|
|
@@ -1,64 +1,52 @@
|
|
|
1
1
|
import { renderDynamicCrudFlowSchema } from './dynamicCrudFlowSchemaTemplate.js';
|
|
2
|
+
import {
|
|
3
|
+
CRUD_ACTIONS,
|
|
4
|
+
createCrudActionPlans,
|
|
5
|
+
hasGraphStorageResource,
|
|
6
|
+
isCrudObject
|
|
7
|
+
} from './crudActionPlan.js';
|
|
2
8
|
|
|
3
|
-
const ACTIONS = ['Create', 'Update', 'Delete', 'Get'];
|
|
4
9
|
const MESSAGE_ATTRIBUTES = ['userId', 'correlationId'];
|
|
5
10
|
|
|
6
|
-
export const dynamicCrudFlowSchemaPaths =
|
|
11
|
+
export const dynamicCrudFlowSchemaPaths = CRUD_ACTIONS.map(
|
|
7
12
|
(action) =>
|
|
8
13
|
`app/src/schemas/FlowSchemas/generateCode/FlowObjects/${action}.js`
|
|
9
14
|
);
|
|
10
15
|
|
|
11
|
-
export function emitDynamicCrudFlowSchemas({ objects, flows = [] }) {
|
|
16
|
+
export function emitDynamicCrudFlowSchemas({ objects, flows = [], serviceTag }) {
|
|
12
17
|
if (!Array.isArray(objects) || !Array.isArray(flows)) {
|
|
13
18
|
throw new TypeError('objects and flows must be arrays');
|
|
14
19
|
}
|
|
15
|
-
if (
|
|
16
|
-
!objects.some(
|
|
17
|
-
(object) =>
|
|
18
|
-
object?.generatedBy === 'userGenerated' ||
|
|
19
|
-
object?.generatedBy === 'systemGenerated'
|
|
20
|
-
)
|
|
21
|
-
) {
|
|
22
|
-
return [];
|
|
23
|
-
}
|
|
20
|
+
if (!objects.some(isCrudObject)) return [];
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
const plans = createCrudActionPlans(objects);
|
|
23
|
+
|
|
24
|
+
return CRUD_ACTIONS.map((action, index) => ({
|
|
25
|
+
path: dynamicCrudFlowSchemaPaths[index],
|
|
26
|
+
content: renderDynamicCrudFlowSchema(
|
|
27
27
|
action,
|
|
28
|
-
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
path: dynamicCrudFlowSchemaPaths[index],
|
|
32
|
-
content: renderDynamicCrudFlowSchema(action, flow)
|
|
33
|
-
};
|
|
34
|
-
});
|
|
28
|
+
_createDynamicFlow(action, plans[action], serviceTag)
|
|
29
|
+
)
|
|
30
|
+
}));
|
|
35
31
|
}
|
|
36
32
|
|
|
37
|
-
function _createDynamicFlow(action,
|
|
38
|
-
const outputTopic = action !== 'Get';
|
|
33
|
+
function _createDynamicFlow(action, plan, serviceTag = '') {
|
|
39
34
|
const flowSteps = [
|
|
40
35
|
{
|
|
41
|
-
stepName: '
|
|
42
|
-
...(
|
|
43
|
-
? {
|
|
44
|
-
nextSteps: [
|
|
45
|
-
{
|
|
46
|
-
stepName: 'BeforeLogical'
|
|
47
|
-
}
|
|
48
|
-
]
|
|
49
|
-
}
|
|
50
|
-
: outputTopic
|
|
36
|
+
stepName: 'Start',
|
|
37
|
+
...(plan.hasRbacCallback || plan.hasComplete
|
|
51
38
|
? {
|
|
52
39
|
nextSteps: [
|
|
53
40
|
{
|
|
54
|
-
|
|
41
|
+
targetType: 'ownTopic',
|
|
42
|
+
stepName: plan.hasRbacCallback ? 'RbacCallback' : 'Complete'
|
|
55
43
|
}
|
|
56
44
|
]
|
|
57
45
|
}
|
|
58
46
|
: {}),
|
|
59
47
|
properties: [],
|
|
60
48
|
messageAttributes: MESSAGE_ATTRIBUTES,
|
|
61
|
-
...(outputTopic
|
|
49
|
+
...(plan.outputTopic
|
|
62
50
|
? {
|
|
63
51
|
returnValues: {
|
|
64
52
|
properties: [],
|
|
@@ -69,17 +57,19 @@ function _createDynamicFlow(action, hasBeforeLogicalStep) {
|
|
|
69
57
|
}
|
|
70
58
|
];
|
|
71
59
|
|
|
72
|
-
if (
|
|
60
|
+
if (plan.hasRbacCallback) {
|
|
73
61
|
flowSteps.push({
|
|
74
|
-
stepName: '
|
|
62
|
+
stepName: 'RbacCallback',
|
|
75
63
|
event: ['extTopic'],
|
|
76
64
|
previousSteps: [
|
|
77
65
|
{
|
|
78
|
-
|
|
66
|
+
sourceType: 'ownTopic',
|
|
67
|
+
stepName: 'Start'
|
|
79
68
|
}
|
|
80
69
|
],
|
|
81
70
|
nextSteps: [
|
|
82
71
|
{
|
|
72
|
+
targetType: 'ownTopic',
|
|
83
73
|
stepName: 'Complete'
|
|
84
74
|
}
|
|
85
75
|
],
|
|
@@ -88,38 +78,36 @@ function _createDynamicFlow(action, hasBeforeLogicalStep) {
|
|
|
88
78
|
});
|
|
89
79
|
}
|
|
90
80
|
|
|
91
|
-
if (
|
|
81
|
+
if (plan.hasComplete) {
|
|
92
82
|
flowSteps.push({
|
|
93
83
|
stepName: 'Complete',
|
|
94
84
|
event: ['extTopic'],
|
|
95
85
|
previousSteps: [
|
|
96
86
|
{
|
|
97
|
-
|
|
87
|
+
sourceType: 'ownTopic',
|
|
88
|
+
stepName: plan.hasRbacCallback ? 'RbacCallback' : 'Start'
|
|
98
89
|
}
|
|
99
90
|
],
|
|
100
|
-
properties:
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
91
|
+
properties: plan.hasGraph
|
|
92
|
+
? [
|
|
93
|
+
'returnValue',
|
|
94
|
+
'parentFlowId',
|
|
95
|
+
'status',
|
|
96
|
+
'errorsFound',
|
|
97
|
+
'graphServiceTag'
|
|
98
|
+
]
|
|
99
|
+
: [],
|
|
107
100
|
messageAttributes: MESSAGE_ATTRIBUTES
|
|
108
101
|
});
|
|
109
102
|
}
|
|
110
103
|
|
|
111
|
-
let eventTypes = ['lambdaSyncInv', 'lambdaSyncApi'];
|
|
112
|
-
if (outputTopic) {
|
|
113
|
-
eventTypes = ['ownTopic'];
|
|
114
|
-
}
|
|
115
|
-
|
|
116
104
|
return {
|
|
117
105
|
flowTag: action,
|
|
118
106
|
initiateBy: 'system',
|
|
119
107
|
handleObj: 'one',
|
|
120
108
|
statusType: 'none',
|
|
121
|
-
event:
|
|
122
|
-
outputTopic,
|
|
109
|
+
event: plan.outputTopic ? ['ownTopic'] : ['lambdaSyncInv', 'lambdaSyncApi'],
|
|
110
|
+
outputTopic: plan.outputTopic,
|
|
123
111
|
stepMessageAttributes: {
|
|
124
112
|
userId: { propertyName: 'x-correlation-base-user-id', type: 'string' },
|
|
125
113
|
correlationId: { propertyName: 'x-correlation-id', type: 'string' }
|
|
@@ -128,14 +116,4 @@ function _createDynamicFlow(action, hasBeforeLogicalStep) {
|
|
|
128
116
|
};
|
|
129
117
|
}
|
|
130
118
|
|
|
131
|
-
|
|
132
|
-
return flows.some((flow) => {
|
|
133
|
-
const config = flow?.generatedCodeConfig;
|
|
134
|
-
return (
|
|
135
|
-
config?.generatedCodeTag === action.toLowerCase() &&
|
|
136
|
-
config.codeHookTag === 'beforeLogical' &&
|
|
137
|
-
Array.isArray(flow.event) &&
|
|
138
|
-
flow.event.includes(config.invocationType)
|
|
139
|
-
);
|
|
140
|
-
});
|
|
141
|
-
}
|
|
119
|
+
export { hasGraphStorageResource };
|
|
@@ -12,7 +12,10 @@ export async function generateDynamicCrudFlowSchemas(rootPath, options = {}) {
|
|
|
12
12
|
const schemaInputs = await loadLocalSchemaArrays(project);
|
|
13
13
|
const plan = buildGenerationPlan(
|
|
14
14
|
project,
|
|
15
|
-
emitDynamicCrudFlowSchemas(
|
|
15
|
+
emitDynamicCrudFlowSchemas({
|
|
16
|
+
...schemaInputs,
|
|
17
|
+
serviceTag: project.serviceTag
|
|
18
|
+
}),
|
|
16
19
|
{
|
|
17
20
|
managedPaths: dynamicCrudFlowSchemaPaths,
|
|
18
21
|
managedScope: 'crud-flow-schemas'
|