@izara_project/izara-core-generate-service-code 1.0.90 → 1.0.92
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 +7 -10
- package/src/compile/flowValidator.js +6 -0
- package/src/compile/loadSchemas.js +177 -69
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +2 -2
- package/src/emit/crud/generateCrudApplicationArtifacts.js +15 -17
- package/src/emit/crud/generateDynamicCrudFlowSchemas.js +16 -21
- package/src/emit/crud/loadLocalSchemaArrays.js +4 -8
- package/src/emit/crud/templates/CreateAfterHookCallback_Main.ejs +6 -6
- package/src/emit/crud/templates/CreateBeforeHookCallback_Main.ejs +3 -3
- package/src/emit/crud/templates/CreateComplete_Main.ejs +22 -22
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +18 -18
- package/src/emit/crud/templates/CreateLogicalLib.ejs +47 -47
- package/src/emit/crud/templates/CreateNodeCallback_Main.ejs +24 -24
- package/src/emit/crud/templates/DeleteAfterHookCallback_Main.ejs +5 -5
- package/src/emit/crud/templates/DeleteBeforeHookCallback_Main.ejs +3 -3
- package/src/emit/crud/templates/DeleteComplete_Main.ejs +23 -23
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +15 -15
- package/src/emit/crud/templates/DeleteLogicalLib.ejs +19 -19
- package/src/emit/crud/templates/FlowEndpointRbacCallback_Main.ejs +3 -3
- package/src/emit/crud/templates/UpdateAfterHookCallback_Main.ejs +5 -5
- package/src/emit/crud/templates/UpdateBeforeHookCallback_Main.ejs +3 -3
- package/src/emit/crud/templates/UpdateComplete_Main.ejs +22 -22
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +15 -15
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +33 -33
- package/src/emit/custom/customFlowPaths.js +149 -0
- package/src/emit/custom/customFlowS3.js +156 -0
- package/src/emit/custom/customFlowSteps.js +385 -0
- package/src/emit/custom/customFlowTemplates.js +28 -0
- package/src/emit/custom/customFlows.js +48 -19
- package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +57 -692
- package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +27 -25
- package/src/emit/custom/templates/FlowEndpointRbacCallback_Main.ejs +7 -7
- package/src/emit/custom/templates/s3/ConfirmReserved_HdrSqs.ejs +3 -3
- package/src/emit/custom/templates/s3/ConfirmReserved_Main.ejs +3 -3
- package/src/emit/custom/templates/s3/CreatePreSignUrl_HdrSqs.ejs +3 -3
- package/src/emit/custom/templates/s3/CreatePreSignUrl_Main.ejs +4 -4
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +26 -6
- package/src/emit/rbac/emitRbacApplicationArtifacts.js +40 -13
- package/src/emit/rbac/generateCreateTargetRoleHandler.js +11 -13
- package/src/emit/rbac/generateDynamicRbacFlowSchemas.js +14 -18
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +13 -7
- package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +1 -1
- package/src/emit/relationship/generateDynamicRelationshipFlowSchemas.js +16 -19
- package/src/emit/relationship/generateRelationshipApplicationArtifacts.js +19 -19
- package/src/emit/relationship/templates/ChangeRelationshipComplete_HdrSqs.ejs +2 -2
- package/src/emit/relationship/templates/ChangeRelationshipComplete_Main.ejs +6 -6
- package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +17 -17
- package/src/emit/relationship/templates/CreateRelationshipComplete_HdrSqs.ejs +2 -2
- package/src/emit/relationship/templates/CreateRelationshipComplete_Main.ejs +6 -6
- package/src/emit/relationship/templates/CreateRelationship_Main.ejs +14 -14
- package/src/emit/relationship/templates/DeleteRelationshipComplete_HdrSqs.ejs +2 -2
- package/src/emit/relationship/templates/DeleteRelationshipComplete_Main.ejs +6 -6
- package/src/emit/relationship/templates/DeleteRelationship_Main.ejs +10 -10
- package/src/emit/relationship/templates/GetRelationshipComplete_HdrSqs.ejs +2 -2
- package/src/emit/relationship/templates/GetRelationshipComplete_Main.ejs +5 -5
- package/src/emit/relationship/templates/GetRelationship_Main.ejs +9 -9
- package/src/emit/relationship/templates/MoveRelationshipComplete_HdrSqs.ejs +2 -2
- package/src/emit/relationship/templates/MoveRelationshipComplete_Main.ejs +6 -6
- package/src/emit/relationship/templates/MoveRelationship_Main.ejs +15 -15
- package/src/emit/relationship/templates/UpdateRelationshipComplete_HdrSqs.ejs +2 -2
- package/src/emit/relationship/templates/UpdateRelationshipComplete_Main.ejs +6 -6
- package/src/emit/relationship/templates/UpdateRelationship_Main.ejs +11 -11
- package/src/emit/resource/dynamoResourceArtifacts.js +18 -0
- package/src/emit/resource/emitResourceArtifacts.js +13 -1251
- package/src/emit/resource/generateResourceArtifacts.js +20 -20
- package/src/emit/resource/iamResourceArtifacts.js +612 -0
- package/src/emit/resource/resourceState.js +564 -0
- package/src/emit/resource/resourceTemplate.js +30 -0
- package/src/emit/resource/s3ResourceArtifacts.js +14 -0
- package/src/emit/resource/sqsResourceArtifacts.js +113 -0
- package/src/emit/shared/runSubsystemGeneration.js +55 -0
- package/src/emit/shared/templates/FindData_Main.ejs +19 -19
- package/src/emit/shared/templates/PaginateProcessLogical_Main.ejs +3 -3
- package/src/emit/shared/templates/ProcessLogical_Main.ejs +15 -15
- package/src/emit/system/emitSystemWebSocketArtifacts.js +2 -1
- package/test/createTargetRoleHandler.test.js +62 -4
- package/test/crudApplicationArtifacts.test.js +75 -3
- package/test/customFlowApplicationArtifacts.test.js +98 -0
- package/test/dynamicCrudFlowSchemas.test.js +2 -2
- package/test/dynamicRbacFlowSchemas.test.js +32 -4
- package/test/relationshipApplicationArtifacts.test.js +1 -1
- package/test/resourceArtifacts.test.js +99 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { renderCustom } from './customFlowTemplates.js';
|
|
2
|
+
import { customFlowRoleName, upperFirst } from './customFlows.js';
|
|
3
|
+
import {
|
|
4
|
+
renderInvFunctionYaml,
|
|
5
|
+
renderS3FunctionYaml,
|
|
6
|
+
renderSqsFunctionYaml,
|
|
7
|
+
renderWbsFunctionYaml
|
|
8
|
+
} from '../function/functionYamlArtifact.js';
|
|
9
|
+
|
|
10
|
+
export async function emitS3Flow(flow, source, handlerRoot) {
|
|
11
|
+
const tag = upperFirst(flow.flowTag);
|
|
12
|
+
const roleName = customFlowRoleName(flow.flowTag);
|
|
13
|
+
const parts = [
|
|
14
|
+
{
|
|
15
|
+
action: 'CreateObject',
|
|
16
|
+
handler: 'HdrWbs',
|
|
17
|
+
type: 'wbs',
|
|
18
|
+
mainTemplate: 'CreateObject_Main.ejs',
|
|
19
|
+
handlerTemplate: 'CreateObject_HdrWbs.ejs'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
action: 'ReservedLimit',
|
|
23
|
+
handler: 'HdrSqs',
|
|
24
|
+
type: 'sqs',
|
|
25
|
+
mainTemplate: 'ReservedLimit_Main.ejs',
|
|
26
|
+
handlerTemplate: 'ReservedLimit_HdrSqs.ejs'
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
action: 'CreatePreSignUrl',
|
|
30
|
+
handler: 'HdrSqs',
|
|
31
|
+
type: 'sqs',
|
|
32
|
+
mainTemplate: 'CreatePreSignUrl_Main.ejs',
|
|
33
|
+
handlerTemplate: 'CreatePreSignUrl_HdrSqs.ejs'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
action: 'ProcessAfterUpload',
|
|
37
|
+
handler: 'HdrS3',
|
|
38
|
+
type: 's3',
|
|
39
|
+
mainTemplate: 'ProcessS3File_Main.ejs',
|
|
40
|
+
handlerTemplate: 'FlowHandler_HdrS3.ejs'
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
action: 'ConfirmAfterUpload',
|
|
44
|
+
handler: 'HdrSqs',
|
|
45
|
+
type: 'sqs',
|
|
46
|
+
mainTemplate: 'ConfirmReserved_Main.ejs',
|
|
47
|
+
handlerTemplate: 'ConfirmReserved_HdrSqs.ejs'
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const emitted = await Promise.all(
|
|
52
|
+
parts.map(
|
|
53
|
+
async ({ action, handler, type, mainTemplate, handlerTemplate }) => {
|
|
54
|
+
const functionName = `${tag}${action}`;
|
|
55
|
+
const mainFileName = `${functionName}_Main`;
|
|
56
|
+
const handlerFileName = `${functionName}_${handler}`;
|
|
57
|
+
const mainContent = await renderCustom(
|
|
58
|
+
`s3/${mainTemplate}`,
|
|
59
|
+
_s3TemplateData({ action, flow, functionName })
|
|
60
|
+
);
|
|
61
|
+
const handlerContent = await renderCustom(
|
|
62
|
+
`s3/${handlerTemplate}`,
|
|
63
|
+
_s3HandlerData({ action, flow, functionName, mainFileName, handler })
|
|
64
|
+
);
|
|
65
|
+
const descriptor = {
|
|
66
|
+
functionName: `${functionName}${handler}`,
|
|
67
|
+
handlerPath: `${handlerRoot}/${handlerFileName}.main`,
|
|
68
|
+
roleName
|
|
69
|
+
};
|
|
70
|
+
let functionYaml;
|
|
71
|
+
if (type === 'wbs') {
|
|
72
|
+
functionYaml = renderWbsFunctionYaml({
|
|
73
|
+
...descriptor,
|
|
74
|
+
routeName: tag,
|
|
75
|
+
flowTag: flow.flowTag,
|
|
76
|
+
flowStepName: ''
|
|
77
|
+
});
|
|
78
|
+
} else if (type === 'sqs') {
|
|
79
|
+
let filterPatternFunctionName = descriptor.functionName;
|
|
80
|
+
if (action === 'CreatePreSignUrl') {
|
|
81
|
+
filterPatternFunctionName = 'CreatePresignUrlHdrSqs';
|
|
82
|
+
}
|
|
83
|
+
functionYaml = renderSqsFunctionYaml({
|
|
84
|
+
...descriptor,
|
|
85
|
+
queueName: descriptor.functionName,
|
|
86
|
+
flowTag: flow.flowTag,
|
|
87
|
+
flowStepName: '',
|
|
88
|
+
filterPatternFunctionName
|
|
89
|
+
});
|
|
90
|
+
} else if (type === 's3') {
|
|
91
|
+
let bucketName = '';
|
|
92
|
+
if (flow.bucketName) {
|
|
93
|
+
bucketName = flow.bucketName;
|
|
94
|
+
}
|
|
95
|
+
functionYaml = renderS3FunctionYaml({
|
|
96
|
+
...descriptor,
|
|
97
|
+
bucketName,
|
|
98
|
+
flowTag: flow.flowTag,
|
|
99
|
+
flowStepName: ''
|
|
100
|
+
});
|
|
101
|
+
} else {
|
|
102
|
+
functionYaml = renderInvFunctionYaml({
|
|
103
|
+
...descriptor,
|
|
104
|
+
flowTag: flow.flowTag,
|
|
105
|
+
flowStepName: ''
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
artifacts: [
|
|
110
|
+
{ path: `${source}/${mainFileName}.js`, content: mainContent },
|
|
111
|
+
{ path: `${source}/${handlerFileName}.js`, content: handlerContent }
|
|
112
|
+
],
|
|
113
|
+
functionYaml
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
)
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
artifacts: emitted.flatMap((item) => item.artifacts),
|
|
121
|
+
functions: emitted.map((item) => item.functionYaml)
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function _s3TemplateData({ action, flow, functionName }) {
|
|
126
|
+
if (action === 'CreateObject') {
|
|
127
|
+
return {
|
|
128
|
+
flowTag: flow.flowTag,
|
|
129
|
+
objectType: flow.objType?.objectType,
|
|
130
|
+
functionName
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
if (action === 'CreatePreSignUrl') {
|
|
134
|
+
return { flowTag: flow.flowTag };
|
|
135
|
+
}
|
|
136
|
+
return { flowTag: flow.flowTag, functionName };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function _s3HandlerData({ action, flow, functionName, mainFileName, handler }) {
|
|
140
|
+
if (action === 'CreateObject') {
|
|
141
|
+
return { functionName, handlerType: handler, route: flow.flowTag };
|
|
142
|
+
}
|
|
143
|
+
if (action === 'ProcessAfterUpload') {
|
|
144
|
+
let bucketName = '';
|
|
145
|
+
if (flow.bucketName) {
|
|
146
|
+
bucketName = flow.bucketName;
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
flowTag: flow.flowTag,
|
|
150
|
+
functionName,
|
|
151
|
+
mainFileName,
|
|
152
|
+
s3Bucket: bucketName
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return { functionName, handlerType: handler };
|
|
156
|
+
}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import {
|
|
2
|
+
renderCrudTemplate,
|
|
3
|
+
renderCustom,
|
|
4
|
+
renderDsq,
|
|
5
|
+
renderShared
|
|
6
|
+
} from './customFlowTemplates.js';
|
|
7
|
+
import { customFlowRoleName, upperFirst, flowHasRbac } from './customFlows.js';
|
|
8
|
+
import {
|
|
9
|
+
renderSqsFunctionYaml,
|
|
10
|
+
renderWbsFunctionYaml
|
|
11
|
+
} from '../function/functionYamlArtifact.js';
|
|
12
|
+
|
|
13
|
+
export async function emitExtTopicStep({ flow, step, flowTag, stepName }) {
|
|
14
|
+
const source = `app/src/generatedCode/FlowSchemas/${flowTag}/source`;
|
|
15
|
+
const handlerRoot = `src/generatedCode/FlowSchemas/${flowTag}/source`;
|
|
16
|
+
let functionName = `${flowTag}${stepName}`;
|
|
17
|
+
if (stepName.startsWith(flowTag)) {
|
|
18
|
+
functionName = stepName;
|
|
19
|
+
}
|
|
20
|
+
const mainFileName = `${functionName}_Main`;
|
|
21
|
+
const startConfig = stepConfig(flow, step);
|
|
22
|
+
|
|
23
|
+
const hasTriggerFlowTypes =
|
|
24
|
+
Array.isArray(flow.triggerFlowTypes) && flow.triggerFlowTypes.length > 0;
|
|
25
|
+
const isCheckStep = stepName.toLowerCase().includes('checktrigger');
|
|
26
|
+
|
|
27
|
+
if (isCheckStep && hasTriggerFlowTypes) {
|
|
28
|
+
const queueName = `${functionName}HdrSqs`;
|
|
29
|
+
return {
|
|
30
|
+
artifacts: [
|
|
31
|
+
{
|
|
32
|
+
path: `${source}/${mainFileName}.js`,
|
|
33
|
+
content: await renderCustom(
|
|
34
|
+
'triggerCache/CheckTriggerCache_Main.ejs',
|
|
35
|
+
{ functionName, flowTag }
|
|
36
|
+
)
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
path: `${source}/${functionName}_HdrSqs.js`,
|
|
40
|
+
content: await renderCustom(
|
|
41
|
+
'triggerCache/CheckTriggerCache_HdrSqs.ejs',
|
|
42
|
+
{ functionName, queueName, startConfig }
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
functions: [
|
|
47
|
+
renderSqsFunctionYaml({
|
|
48
|
+
functionName: queueName,
|
|
49
|
+
handlerPath: `${handlerRoot}/${functionName}_HdrSqs.main`,
|
|
50
|
+
roleName: customFlowRoleName(flow.flowTag),
|
|
51
|
+
queueName,
|
|
52
|
+
flowTag,
|
|
53
|
+
flowStepName: step.stepName
|
|
54
|
+
})
|
|
55
|
+
]
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const artifacts = [
|
|
60
|
+
{
|
|
61
|
+
path: `${source}/${mainFileName}.js`,
|
|
62
|
+
content: await renderStepMain(functionName, _startConfig(flow))
|
|
63
|
+
}
|
|
64
|
+
];
|
|
65
|
+
const functions = [];
|
|
66
|
+
|
|
67
|
+
let stepEvents = [];
|
|
68
|
+
if (Array.isArray(step.event)) {
|
|
69
|
+
stepEvents = step.event;
|
|
70
|
+
}
|
|
71
|
+
const hasSqs = stepEvents.includes('extTopic') || stepEvents.includes('sqs');
|
|
72
|
+
|
|
73
|
+
if (hasSqs) {
|
|
74
|
+
const queueName = `${functionName}HdrSqs`;
|
|
75
|
+
artifacts.push({
|
|
76
|
+
path: `${source}/${functionName}_HdrSqs.js`,
|
|
77
|
+
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
78
|
+
flowTag: flow.flowTag,
|
|
79
|
+
flowStepName: step.stepName,
|
|
80
|
+
functionName,
|
|
81
|
+
mainFileName,
|
|
82
|
+
startConfig,
|
|
83
|
+
queueName
|
|
84
|
+
})
|
|
85
|
+
});
|
|
86
|
+
functions.push(
|
|
87
|
+
renderSqsFunctionYaml({
|
|
88
|
+
functionName: queueName,
|
|
89
|
+
handlerPath: `${handlerRoot}/${functionName}_HdrSqs.main`,
|
|
90
|
+
roleName: customFlowRoleName(flow.flowTag),
|
|
91
|
+
queueName,
|
|
92
|
+
flowTag,
|
|
93
|
+
flowStepName: step.stepName
|
|
94
|
+
})
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return { artifacts, functions };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export async function emitDsqStep({ flow, step, flowTag, stepName }) {
|
|
102
|
+
const source = `app/src/generatedCode/FlowSchemas/${flowTag}/source`;
|
|
103
|
+
const handlerRoot = `src/generatedCode/FlowSchemas/${flowTag}/source`;
|
|
104
|
+
const functionName = `${flowTag}${stepName}`;
|
|
105
|
+
const mainFileName = `${functionName}_Main`;
|
|
106
|
+
const startConfig = stepConfig(flow, step);
|
|
107
|
+
|
|
108
|
+
let stepEvents = [];
|
|
109
|
+
if (Array.isArray(step.event)) {
|
|
110
|
+
stepEvents = step.event;
|
|
111
|
+
}
|
|
112
|
+
const artifacts = [];
|
|
113
|
+
if (!stepEvents.includes('extTopic')) {
|
|
114
|
+
artifacts.push({
|
|
115
|
+
path: `${source}/${mainFileName}.js`,
|
|
116
|
+
content: await renderStepMain(functionName, startConfig)
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
const functions = [];
|
|
120
|
+
|
|
121
|
+
const hasDsq = stepEvents.includes('dsq');
|
|
122
|
+
|
|
123
|
+
if (hasDsq) {
|
|
124
|
+
const queueName = `${functionName}HdrDsq`;
|
|
125
|
+
artifacts.push({
|
|
126
|
+
path: `${source}/${functionName}_HdrDsq.js`,
|
|
127
|
+
content: await renderDsq('FlowHandler_HdrDsq.ejs', {
|
|
128
|
+
flowTag: flow.flowTag,
|
|
129
|
+
flowStepName: step.stepName,
|
|
130
|
+
functionName,
|
|
131
|
+
mainFileName,
|
|
132
|
+
startConfig,
|
|
133
|
+
queueName
|
|
134
|
+
})
|
|
135
|
+
});
|
|
136
|
+
functions.push(
|
|
137
|
+
renderSqsFunctionYaml({
|
|
138
|
+
functionName: queueName,
|
|
139
|
+
handlerPath: `${handlerRoot}/${functionName}_HdrDsq.main`,
|
|
140
|
+
roleName: customFlowRoleName(flow.flowTag),
|
|
141
|
+
queueName,
|
|
142
|
+
flowTag,
|
|
143
|
+
flowStepName: step.stepName
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return { artifacts, functions };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export async function emitOwnTopicRoot(flow, objects) {
|
|
152
|
+
const tag = upperFirst(flow.flowTag);
|
|
153
|
+
const source = `app/src/generatedCode/FlowSchemas/${tag}/source`;
|
|
154
|
+
const handlerRoot = `src/generatedCode/FlowSchemas/${tag}/source`;
|
|
155
|
+
const mainFileName = `${tag}_Main`;
|
|
156
|
+
const wbsMainFileName = `${tag}_WbsMain`;
|
|
157
|
+
const shared = {
|
|
158
|
+
flowTag: flow.flowTag,
|
|
159
|
+
flowStepName: '',
|
|
160
|
+
upperCaseFlowTag: tag,
|
|
161
|
+
startConfig: _startConfig(flow)
|
|
162
|
+
};
|
|
163
|
+
const isRbac = flowHasRbac(flow, objects);
|
|
164
|
+
const ownArtifacts = [
|
|
165
|
+
{
|
|
166
|
+
path: `${source}/${mainFileName}.js`,
|
|
167
|
+
content: await renderEndpointMain(flow, mainFileName, objects)
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
path: `${source}/${tag}_HdrSqs.js`,
|
|
171
|
+
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
172
|
+
...shared,
|
|
173
|
+
functionName: mainFileName,
|
|
174
|
+
mainFileName,
|
|
175
|
+
queueName: `${tag}HdrSqs`
|
|
176
|
+
})
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
path: `${source}/${wbsMainFileName}.js`,
|
|
180
|
+
content: await renderCrudTemplate('FlowMain_Wbs.ejs', {
|
|
181
|
+
...shared,
|
|
182
|
+
functionName: wbsMainFileName
|
|
183
|
+
})
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
path: `${source}/${tag}_HdrWbs.js`,
|
|
187
|
+
content: await renderCrudTemplate('FlowEndpoint_HdrWbs.ejs', {
|
|
188
|
+
...shared,
|
|
189
|
+
functionName: tag,
|
|
190
|
+
mainFileName: wbsMainFileName,
|
|
191
|
+
route: tag
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
];
|
|
195
|
+
|
|
196
|
+
const ownFunctions = [
|
|
197
|
+
renderWbsFunctionYaml({
|
|
198
|
+
functionName: `${tag}HdrWbs`,
|
|
199
|
+
handlerPath: `${handlerRoot}/${tag}_HdrWbs.main`,
|
|
200
|
+
roleName: customFlowRoleName(flow.flowTag),
|
|
201
|
+
routeName: tag,
|
|
202
|
+
flowTag: flow.flowTag,
|
|
203
|
+
flowStepName: ''
|
|
204
|
+
}),
|
|
205
|
+
renderSqsFunctionYaml({
|
|
206
|
+
functionName: `${tag}HdrSqs`,
|
|
207
|
+
handlerPath: `${handlerRoot}/${tag}_HdrSqs.main`,
|
|
208
|
+
roleName: customFlowRoleName(flow.flowTag),
|
|
209
|
+
queueName: `${tag}HdrSqs`,
|
|
210
|
+
flowTag: flow.flowTag,
|
|
211
|
+
flowStepName: ''
|
|
212
|
+
})
|
|
213
|
+
];
|
|
214
|
+
|
|
215
|
+
if (isRbac) {
|
|
216
|
+
const rbacStep = (flow.flowSteps || []).find(
|
|
217
|
+
(s) =>
|
|
218
|
+
typeof s?.stepName === 'string' &&
|
|
219
|
+
s.stepName.toLowerCase() === 'rbaccallback'
|
|
220
|
+
);
|
|
221
|
+
const rbacConfig = rbacStep ? stepConfig(flow, rbacStep) : null;
|
|
222
|
+
ownArtifacts.push(
|
|
223
|
+
{
|
|
224
|
+
path: `${source}/${tag}RbacCallback_Main.js`,
|
|
225
|
+
content: await renderCustom('FlowEndpointRbacCallback_Main.ejs', {
|
|
226
|
+
flowTag: flow.flowTag,
|
|
227
|
+
upperCaseFlowTag: tag,
|
|
228
|
+
functionName: `${tag}RbacCallbackMain`
|
|
229
|
+
})
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
path: `${source}/${tag}RbacCallback_HdrSqs.js`,
|
|
233
|
+
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
234
|
+
flowTag: flow.flowTag,
|
|
235
|
+
flowStepName: 'RbacCallback',
|
|
236
|
+
mainFileName: `${tag}RbacCallback_Main`,
|
|
237
|
+
functionName: `${tag}RbacCallbackMain`,
|
|
238
|
+
queueName: `${tag}RbacCallbackHdrSqs`,
|
|
239
|
+
startConfig: rbacConfig
|
|
240
|
+
})
|
|
241
|
+
}
|
|
242
|
+
);
|
|
243
|
+
ownFunctions.push(
|
|
244
|
+
renderSqsFunctionYaml({
|
|
245
|
+
functionName: `${tag}RbacCallbackHdrSqs`,
|
|
246
|
+
handlerPath: `${handlerRoot}/${tag}RbacCallback_HdrSqs.main`,
|
|
247
|
+
roleName: customFlowRoleName(flow.flowTag),
|
|
248
|
+
queueName: `${tag}RbacCallbackHdrSqs`,
|
|
249
|
+
flowTag: flow.flowTag,
|
|
250
|
+
flowStepName: 'RbacCallback'
|
|
251
|
+
})
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return {
|
|
256
|
+
artifacts: ownArtifacts,
|
|
257
|
+
functions: ownFunctions
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export function _startConfig(flow) {
|
|
262
|
+
const steps = flow.flowSteps ?? [];
|
|
263
|
+
const start =
|
|
264
|
+
steps.find(
|
|
265
|
+
(s) =>
|
|
266
|
+
typeof s?.stepName === 'string' &&
|
|
267
|
+
s.stepName.toLowerCase() === 'inprocess'
|
|
268
|
+
) ??
|
|
269
|
+
steps.find(
|
|
270
|
+
(s) =>
|
|
271
|
+
typeof s?.stepName === 'string' && s.stepName.toLowerCase() === 'start'
|
|
272
|
+
) ??
|
|
273
|
+
steps[0];
|
|
274
|
+
if (start) {
|
|
275
|
+
return stepConfig(flow, start);
|
|
276
|
+
}
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export function stepConfig(flow, step) {
|
|
281
|
+
return {
|
|
282
|
+
...step,
|
|
283
|
+
properties: mapFields(step.properties, flow.stepProperties),
|
|
284
|
+
messageAttributes: mapFields(
|
|
285
|
+
step.messageAttributes,
|
|
286
|
+
flow.stepMessageAttributes
|
|
287
|
+
)
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export function mapFields(items = [], definitions = {}) {
|
|
292
|
+
return items.map((item) => {
|
|
293
|
+
if (typeof item === 'string') {
|
|
294
|
+
const def = definitions?.[item] ?? {};
|
|
295
|
+
return {
|
|
296
|
+
propertyName: item,
|
|
297
|
+
required: def.required ?? false,
|
|
298
|
+
...def
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
if (typeof item === 'object' && item !== null) {
|
|
302
|
+
const name = item.key ?? item.propertyName;
|
|
303
|
+
const def = definitions?.[name] ?? {};
|
|
304
|
+
return {
|
|
305
|
+
propertyName: name,
|
|
306
|
+
required: item.required ?? def.required ?? false,
|
|
307
|
+
...def,
|
|
308
|
+
...item
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
return item;
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export async function renderEndpointMain(flow, functionName, objects = []) {
|
|
316
|
+
const isRbac = flowHasRbac(flow, objects);
|
|
317
|
+
const matchedObject = objects.find(
|
|
318
|
+
(o) => o.objectType === flow.objType?.objectType
|
|
319
|
+
);
|
|
320
|
+
let rbacServiceTag = null;
|
|
321
|
+
if (matchedObject) {
|
|
322
|
+
const belongTo = matchedObject.belongTo;
|
|
323
|
+
if (belongTo) {
|
|
324
|
+
if (Array.isArray(belongTo)) {
|
|
325
|
+
rbacServiceTag = belongTo[0]?.serviceTag;
|
|
326
|
+
} else {
|
|
327
|
+
rbacServiceTag = belongTo?.serviceTag;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (!rbacServiceTag) {
|
|
332
|
+
rbacServiceTag = flow.objType?.serviceTag || flow.serviceTag || 'Rbac';
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const enrichedFlow = {
|
|
336
|
+
...flow,
|
|
337
|
+
isRbac
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
return renderCustom('FlowEndpoint_Main.ejs', {
|
|
341
|
+
flow: enrichedFlow,
|
|
342
|
+
flowTag: flow.flowTag,
|
|
343
|
+
upperCaseFlowTag: upperFirst(flow.flowTag),
|
|
344
|
+
functionName,
|
|
345
|
+
rbacServiceTag,
|
|
346
|
+
tableName: storedCacheTableName(flow, objects),
|
|
347
|
+
startConfig: _startConfig(flow)
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export function storedCacheTableName(flow, objects) {
|
|
352
|
+
if (flow.statusType !== 'storedCache') {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
const candidates = objects.filter(
|
|
356
|
+
(object) => object.objectType === flow.objType?.objectType
|
|
357
|
+
);
|
|
358
|
+
let object;
|
|
359
|
+
if (flow.objType?.serviceTag) {
|
|
360
|
+
object =
|
|
361
|
+
candidates.find(
|
|
362
|
+
(candidate) => candidate.serviceTag === flow.objType.serviceTag
|
|
363
|
+
) ?? candidates.find((candidate) => candidate.serviceTag === undefined);
|
|
364
|
+
} else {
|
|
365
|
+
object = candidates[0];
|
|
366
|
+
}
|
|
367
|
+
const targetResource = Object.values(object?.storageResources ?? {}).find(
|
|
368
|
+
(resource) =>
|
|
369
|
+
resource?.storageType === 'dynamo' ||
|
|
370
|
+
resource?.storageType === 'dynamoDB' ||
|
|
371
|
+
!resource?.storageType
|
|
372
|
+
);
|
|
373
|
+
if (targetResource?.tableName) {
|
|
374
|
+
return targetResource.tableName;
|
|
375
|
+
}
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export async function renderStepMain(functionName, startConfig = null) {
|
|
380
|
+
return renderCustom('FlowStep_Main.ejs', { functionName, startConfig });
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export function renderMain(functionName) {
|
|
384
|
+
return `export default async function ${functionName}(_izContext, requestParams, callingFlowConfig = {}) {\n try {\n _izContext?.logger?.debug('${functionName} requestParams', requestParams);\n //(<endpointHook>)\n //(</endpointHook>)\n } catch (error) {\n _izContext?.logger?.error('${functionName} failed', error);\n throw error;\n }\n}\n`;
|
|
385
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import ejsLib from 'ejs';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
|
|
4
|
+
const SHARED_TEMPLATE_URL = new URL('../shared/templates/', import.meta.url);
|
|
5
|
+
const CRUD_TEMPLATE_URL = new URL('../crud/templates/', import.meta.url);
|
|
6
|
+
const CUSTOM_TEMPLATE_URL = new URL('./templates/', import.meta.url);
|
|
7
|
+
|
|
8
|
+
export async function renderShared(templateName, data) {
|
|
9
|
+
const templatePath = new URL(templateName, SHARED_TEMPLATE_URL);
|
|
10
|
+
const templateContent = await readFile(templatePath, 'utf8');
|
|
11
|
+
return ejsLib.render(templateContent, data);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function renderCrudTemplate(templateName, data) {
|
|
15
|
+
const templatePath = new URL(templateName, CRUD_TEMPLATE_URL);
|
|
16
|
+
const templateContent = await readFile(templatePath, 'utf8');
|
|
17
|
+
return ejsLib.render(templateContent, data);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function renderDsq(templateName, data) {
|
|
21
|
+
return renderShared(templateName, data);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function renderCustom(templateName, data) {
|
|
25
|
+
const templatePath = new URL(templateName, CUSTOM_TEMPLATE_URL);
|
|
26
|
+
const templateContent = await readFile(templatePath, 'utf8');
|
|
27
|
+
return ejsLib.render(templateContent, data).replace(/\n$/, '');
|
|
28
|
+
}
|
|
@@ -5,23 +5,51 @@ const SUPPORTED_EVENTS = new Set([
|
|
|
5
5
|
'lambdaSyncApi',
|
|
6
6
|
'ownTopic',
|
|
7
7
|
's3',
|
|
8
|
-
'dsq'
|
|
8
|
+
'dsq',
|
|
9
|
+
'generateCode'
|
|
9
10
|
]);
|
|
10
11
|
|
|
11
12
|
export function supportedCustomFlows(flows) {
|
|
12
13
|
if (!Array.isArray(flows)) {
|
|
13
14
|
throw new TypeError('flows must be an array');
|
|
14
15
|
}
|
|
15
|
-
return flows.filter(
|
|
16
|
-
(flow)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
return flows.filter((flow) => {
|
|
17
|
+
if (typeof flow?.flowTag !== 'string' || flow.flowTag === '') {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
if (!Array.isArray(flow.event)) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
const hasSupportedEvent = flow.event.some((e) => SUPPORTED_EVENTS.has(e));
|
|
24
|
+
if (!hasSupportedEvent) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
if (flow.generatedCodeConfig) {
|
|
28
|
+
if (flowHasOwnTopic(flow)) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
if (!flow.generatedCodeConfig.codeHookTag) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function flowHasOwnTopic(flow) {
|
|
40
|
+
if (!Array.isArray(flow?.event)) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
if (flow.event.includes('ownTopic')) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
if (
|
|
47
|
+
flow.event.includes('generateCode') &&
|
|
48
|
+
flow?.generatedCodeConfig?.invocationType === 'ownTopic'
|
|
49
|
+
) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
25
53
|
}
|
|
26
54
|
|
|
27
55
|
export function customFlowRoleName(flowTag) {
|
|
@@ -116,14 +144,15 @@ export function generatedOwnTopicFlows(flows) {
|
|
|
116
144
|
if (!Array.isArray(flows)) {
|
|
117
145
|
throw new TypeError('flows must be an array');
|
|
118
146
|
}
|
|
119
|
-
return flows.filter(
|
|
120
|
-
(flow)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
147
|
+
return flows.filter((flow) => {
|
|
148
|
+
if (typeof flow?.flowTag !== 'string' || flow.flowTag === '') {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
if (!flow.generatedCodeConfig) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
return flowHasOwnTopic(flow);
|
|
155
|
+
});
|
|
127
156
|
}
|
|
128
157
|
|
|
129
158
|
export function generatedDsqFlows(flows) {
|