@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
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
import ejsLib from 'ejs';
|
|
2
|
-
import { readFile } from 'node:fs/promises';
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
renderApiFunctionYaml,
|
|
6
|
-
renderEventBridgeFunctionYaml,
|
|
7
|
-
renderInvFunctionYaml,
|
|
8
|
-
renderS3FunctionYaml,
|
|
9
|
-
renderSqsFunctionYaml,
|
|
10
|
-
renderWbsFunctionYaml
|
|
11
|
-
} from '../function/functionYamlArtifact.js';
|
|
12
1
|
import {
|
|
13
2
|
customFlowRoleName,
|
|
14
3
|
flowDsqSteps,
|
|
@@ -19,11 +8,33 @@ import {
|
|
|
19
8
|
upperFirst,
|
|
20
9
|
flowHasRbac
|
|
21
10
|
} from './customFlows.js';
|
|
11
|
+
import {
|
|
12
|
+
customFlowApplicationManagedPaths,
|
|
13
|
+
needsProcessMain,
|
|
14
|
+
YAML_PATH
|
|
15
|
+
} from './customFlowPaths.js';
|
|
16
|
+
import { emitS3Flow } from './customFlowS3.js';
|
|
17
|
+
import {
|
|
18
|
+
emitExtTopicStep,
|
|
19
|
+
emitDsqStep,
|
|
20
|
+
emitOwnTopicRoot,
|
|
21
|
+
renderEndpointMain,
|
|
22
|
+
stepConfig,
|
|
23
|
+
_startConfig
|
|
24
|
+
} from './customFlowSteps.js';
|
|
25
|
+
import {
|
|
26
|
+
renderCustom,
|
|
27
|
+
renderShared,
|
|
28
|
+
renderDsq
|
|
29
|
+
} from './customFlowTemplates.js';
|
|
30
|
+
import {
|
|
31
|
+
renderApiFunctionYaml,
|
|
32
|
+
renderEventBridgeFunctionYaml,
|
|
33
|
+
renderInvFunctionYaml,
|
|
34
|
+
renderSqsFunctionYaml
|
|
35
|
+
} from '../function/functionYamlArtifact.js';
|
|
22
36
|
|
|
23
|
-
|
|
24
|
-
const TEMPLATE_URL = new URL('../crud/templates/', import.meta.url);
|
|
25
|
-
const SHARED_TEMPLATE_URL = new URL('../shared/templates/', import.meta.url);
|
|
26
|
-
const CUSTOM_TEMPLATE_URL = new URL('./templates/', import.meta.url);
|
|
37
|
+
export { customFlowApplicationManagedPaths };
|
|
27
38
|
|
|
28
39
|
export async function emitCustomFlowApplicationArtifacts(
|
|
29
40
|
flows,
|
|
@@ -38,8 +49,9 @@ export async function emitCustomFlowApplicationArtifacts(
|
|
|
38
49
|
generatedRoots.length === 0 &&
|
|
39
50
|
steps.length === 0 &&
|
|
40
51
|
dsqSteps.length === 0
|
|
41
|
-
)
|
|
52
|
+
) {
|
|
42
53
|
return [];
|
|
54
|
+
}
|
|
43
55
|
|
|
44
56
|
const emitted = await Promise.all(
|
|
45
57
|
customFlows.map((flow) => emitFlow(flow, objects))
|
|
@@ -68,39 +80,6 @@ export async function emitCustomFlowApplicationArtifacts(
|
|
|
68
80
|
];
|
|
69
81
|
}
|
|
70
82
|
|
|
71
|
-
export function customFlowApplicationManagedPaths(flows, { objects = [] } = {}) {
|
|
72
|
-
return [
|
|
73
|
-
...supportedCustomFlows(flows).flatMap((flow) => flowPaths(flow, objects)),
|
|
74
|
-
...generatedOwnTopicFlows(flows).flatMap((flow) => ownTopicRootPaths(flow, objects)),
|
|
75
|
-
...flowExtTopicSteps(flows).flatMap(({ flowTag, stepName }) => {
|
|
76
|
-
const source = `app/src/generatedCode/FlowSchemas/${flowTag}/source`;
|
|
77
|
-
return [
|
|
78
|
-
`${source}/${flowTag}${stepName}_Main.js`,
|
|
79
|
-
`${source}/${flowTag}${stepName}_HdrSqs.js`
|
|
80
|
-
];
|
|
81
|
-
}),
|
|
82
|
-
...flowDsqSteps(flows).flatMap(({ flowTag, stepName, step }) => {
|
|
83
|
-
const source = `app/src/generatedCode/FlowSchemas/${flowTag}/source`;
|
|
84
|
-
let stepEvents = [];
|
|
85
|
-
if (Array.isArray(step.event)) {
|
|
86
|
-
stepEvents = step.event;
|
|
87
|
-
}
|
|
88
|
-
const files = [`${source}/${flowTag}${stepName}_HdrDsq.js`];
|
|
89
|
-
if (!stepEvents.includes('extTopic')) {
|
|
90
|
-
files.unshift(`${source}/${flowTag}${stepName}_Main.js`);
|
|
91
|
-
}
|
|
92
|
-
return files;
|
|
93
|
-
}),
|
|
94
|
-
...(supportedCustomFlows(flows).length > 0 ||
|
|
95
|
-
generatedOwnTopicFlows(flows).length > 0 ||
|
|
96
|
-
generatedDsqFlows(flows).length > 0 ||
|
|
97
|
-
flowExtTopicSteps(flows).length > 0 ||
|
|
98
|
-
flowDsqSteps(flows).length > 0
|
|
99
|
-
? [YAML_PATH]
|
|
100
|
-
: [])
|
|
101
|
-
];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
83
|
async function emitFlow(flow, objects) {
|
|
105
84
|
const tag = upperFirst(flow.flowTag);
|
|
106
85
|
const process = tag;
|
|
@@ -113,22 +92,26 @@ async function emitFlow(flow, objects) {
|
|
|
113
92
|
functionName: process,
|
|
114
93
|
startConfig: _startConfig(flow)
|
|
115
94
|
};
|
|
116
|
-
const artifacts =
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
: [];
|
|
95
|
+
const artifacts = [];
|
|
96
|
+
if (needsProcessMain(flow)) {
|
|
97
|
+
artifacts.push({
|
|
98
|
+
path: `${source}/${process}_Main.js`,
|
|
99
|
+
content: await renderEndpointMain(flow, process, objects)
|
|
100
|
+
});
|
|
101
|
+
}
|
|
124
102
|
const functions = [];
|
|
125
103
|
|
|
126
104
|
const isRbac = flowHasRbac(flow, objects);
|
|
127
105
|
if (isRbac && !flow.event.includes('ownTopic')) {
|
|
128
106
|
const rbacStep = (flow.flowSteps || []).find(
|
|
129
|
-
(s) =>
|
|
107
|
+
(s) =>
|
|
108
|
+
typeof s?.stepName === 'string' &&
|
|
109
|
+
s.stepName.toLowerCase() === 'rbaccallback'
|
|
130
110
|
);
|
|
131
|
-
|
|
111
|
+
let rbacConfig = null;
|
|
112
|
+
if (rbacStep) {
|
|
113
|
+
rbacConfig = stepConfig(flow, rbacStep);
|
|
114
|
+
}
|
|
132
115
|
artifacts.push(
|
|
133
116
|
{
|
|
134
117
|
path: `${source}/${tag}RbacCallback_Main.js`,
|
|
@@ -200,7 +183,11 @@ async function emitFlow(flow, objects) {
|
|
|
200
183
|
})
|
|
201
184
|
);
|
|
202
185
|
}
|
|
203
|
-
if (
|
|
186
|
+
if (
|
|
187
|
+
flow.event.includes('lambdaSyncInv') ||
|
|
188
|
+
(flow.event.includes('generateCode') &&
|
|
189
|
+
flow.generatedCodeConfig?.invocationType === 'lambdaSyncInv')
|
|
190
|
+
) {
|
|
204
191
|
artifacts.push({
|
|
205
192
|
path: `${source}/${process}_HdrInv.js`,
|
|
206
193
|
content: await renderShared('FlowHandler_HdrInv.ejs', shared)
|
|
@@ -235,6 +222,10 @@ async function emitFlow(flow, objects) {
|
|
|
235
222
|
path: `${source}/${process}_HdrInv.js`,
|
|
236
223
|
content: await renderShared('FlowHandler_HdrInv.ejs', shared)
|
|
237
224
|
});
|
|
225
|
+
let schedules = [];
|
|
226
|
+
if (flow.schedules) {
|
|
227
|
+
schedules = flow.schedules;
|
|
228
|
+
}
|
|
238
229
|
functions.push(
|
|
239
230
|
renderEventBridgeFunctionYaml({
|
|
240
231
|
functionName: `${process}HdrInv`,
|
|
@@ -242,11 +233,15 @@ async function emitFlow(flow, objects) {
|
|
|
242
233
|
roleName: customFlowRoleName(flow.flowTag),
|
|
243
234
|
flowTag: flow.flowTag,
|
|
244
235
|
flowStepName: '',
|
|
245
|
-
schedules
|
|
236
|
+
schedules
|
|
246
237
|
})
|
|
247
238
|
);
|
|
248
239
|
}
|
|
249
|
-
if (
|
|
240
|
+
if (
|
|
241
|
+
flow.event.includes('ownTopic') ||
|
|
242
|
+
(flow.event.includes('generateCode') &&
|
|
243
|
+
flow.generatedCodeConfig?.invocationType === 'ownTopic')
|
|
244
|
+
) {
|
|
250
245
|
const root = await emitOwnTopicRoot(flow, objects);
|
|
251
246
|
artifacts.push(...root.artifacts);
|
|
252
247
|
functions.push(...root.functions);
|
|
@@ -258,633 +253,3 @@ async function emitFlow(flow, objects) {
|
|
|
258
253
|
}
|
|
259
254
|
return { artifacts, functions };
|
|
260
255
|
}
|
|
261
|
-
|
|
262
|
-
function flowPaths(flow, objects = []) {
|
|
263
|
-
const tag = upperFirst(flow.flowTag);
|
|
264
|
-
const process = tag;
|
|
265
|
-
const source = `app/src/generatedCode/FlowSchemas/${tag}/source`;
|
|
266
|
-
const paths = [];
|
|
267
|
-
if (needsProcessMain(flow)) {
|
|
268
|
-
paths.push(`${source}/${process}_Main.js`);
|
|
269
|
-
}
|
|
270
|
-
if (flowHasRbac(flow, objects)) {
|
|
271
|
-
paths.push(
|
|
272
|
-
`${source}/${tag}RbacCallback_Main.js`,
|
|
273
|
-
`${source}/${tag}RbacCallback_HdrSqs.js`
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
if (flow.event.includes('extTopic') && !flow.event.includes('ownTopic')) {
|
|
277
|
-
paths.push(`${source}/${process}_HdrSqs.js`);
|
|
278
|
-
}
|
|
279
|
-
if (flow.event.includes('dsq')) {
|
|
280
|
-
paths.push(`${source}/${process}_HdrDsq.js`);
|
|
281
|
-
}
|
|
282
|
-
if (
|
|
283
|
-
flow.event.includes('lambdaSyncInv') ||
|
|
284
|
-
flow.event.includes('eventBridge')
|
|
285
|
-
) {
|
|
286
|
-
paths.push(`${source}/${process}_HdrInv.js`);
|
|
287
|
-
}
|
|
288
|
-
if (flow.event.includes('lambdaSyncApi')) {
|
|
289
|
-
paths.push(`${source}/${process}_HdrApi.js`);
|
|
290
|
-
}
|
|
291
|
-
if (flow.event.includes('ownTopic')) {
|
|
292
|
-
paths.push(...ownTopicRootPaths(flow));
|
|
293
|
-
}
|
|
294
|
-
if (flow.event.includes('s3')) {
|
|
295
|
-
const s3Actions = [
|
|
296
|
-
'ConfirmAfterUpload',
|
|
297
|
-
'CreateObject',
|
|
298
|
-
'CreatePreSignUrl',
|
|
299
|
-
'ProcessAfterUpload',
|
|
300
|
-
'ReservedLimit'
|
|
301
|
-
];
|
|
302
|
-
for (const action of s3Actions) {
|
|
303
|
-
let handler = 'HdrSqs';
|
|
304
|
-
if (action === 'CreateObject') {
|
|
305
|
-
handler = 'HdrWbs';
|
|
306
|
-
} else if (action === 'ProcessAfterUpload') {
|
|
307
|
-
handler = 'HdrS3';
|
|
308
|
-
}
|
|
309
|
-
paths.push(
|
|
310
|
-
`${source}/${tag}${action}_Main.js`,
|
|
311
|
-
`${source}/${tag}${action}_${handler}.js`
|
|
312
|
-
);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
return paths;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
async function emitExtTopicStep({ flow, step, flowTag, stepName }) {
|
|
319
|
-
const source = `app/src/generatedCode/FlowSchemas/${flowTag}/source`;
|
|
320
|
-
const handlerRoot = `src/generatedCode/FlowSchemas/${flowTag}/source`;
|
|
321
|
-
const functionName = stepName.startsWith(flowTag)
|
|
322
|
-
? stepName
|
|
323
|
-
: `${flowTag}${stepName}`;
|
|
324
|
-
const mainFileName = `${functionName}_Main`;
|
|
325
|
-
const startConfig = stepConfig(flow, step);
|
|
326
|
-
|
|
327
|
-
const hasTriggerFlowTypes =
|
|
328
|
-
Array.isArray(flow.triggerFlowTypes) && flow.triggerFlowTypes.length > 0;
|
|
329
|
-
const isCheckStep = stepName.toLowerCase().includes('checktrigger');
|
|
330
|
-
|
|
331
|
-
if (isCheckStep && hasTriggerFlowTypes) {
|
|
332
|
-
const queueName = `${functionName}HdrSqs`;
|
|
333
|
-
return {
|
|
334
|
-
artifacts: [
|
|
335
|
-
{
|
|
336
|
-
path: `${source}/${mainFileName}.js`,
|
|
337
|
-
content: await renderCustom(
|
|
338
|
-
'triggerCache/CheckTriggerCache_Main.ejs',
|
|
339
|
-
{ functionName, flowTag }
|
|
340
|
-
)
|
|
341
|
-
},
|
|
342
|
-
{
|
|
343
|
-
path: `${source}/${functionName}_HdrSqs.js`,
|
|
344
|
-
content: await renderCustom(
|
|
345
|
-
'triggerCache/CheckTriggerCache_HdrSqs.ejs',
|
|
346
|
-
{ functionName, queueName, startConfig }
|
|
347
|
-
)
|
|
348
|
-
}
|
|
349
|
-
],
|
|
350
|
-
functions: [
|
|
351
|
-
renderSqsFunctionYaml({
|
|
352
|
-
functionName: queueName,
|
|
353
|
-
handlerPath: `${handlerRoot}/${functionName}_HdrSqs.main`,
|
|
354
|
-
roleName: customFlowRoleName(flow.flowTag),
|
|
355
|
-
queueName,
|
|
356
|
-
flowTag,
|
|
357
|
-
flowStepName: step.stepName
|
|
358
|
-
})
|
|
359
|
-
]
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const artifacts = [
|
|
364
|
-
{
|
|
365
|
-
path: `${source}/${mainFileName}.js`,
|
|
366
|
-
content: await renderStepMain(functionName, _startConfig(flow))
|
|
367
|
-
}
|
|
368
|
-
];
|
|
369
|
-
const functions = [];
|
|
370
|
-
|
|
371
|
-
let stepEvents = [];
|
|
372
|
-
if (Array.isArray(step.event)) {
|
|
373
|
-
stepEvents = step.event;
|
|
374
|
-
}
|
|
375
|
-
const hasSqs = stepEvents.includes('extTopic') || stepEvents.includes('sqs');
|
|
376
|
-
|
|
377
|
-
if (hasSqs) {
|
|
378
|
-
const queueName = `${functionName}HdrSqs`;
|
|
379
|
-
artifacts.push({
|
|
380
|
-
path: `${source}/${functionName}_HdrSqs.js`,
|
|
381
|
-
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
382
|
-
flowTag: flow.flowTag,
|
|
383
|
-
flowStepName: step.stepName,
|
|
384
|
-
functionName,
|
|
385
|
-
mainFileName,
|
|
386
|
-
startConfig,
|
|
387
|
-
queueName
|
|
388
|
-
})
|
|
389
|
-
});
|
|
390
|
-
functions.push(
|
|
391
|
-
renderSqsFunctionYaml({
|
|
392
|
-
functionName: queueName,
|
|
393
|
-
handlerPath: `${handlerRoot}/${functionName}_HdrSqs.main`,
|
|
394
|
-
roleName: customFlowRoleName(flow.flowTag),
|
|
395
|
-
queueName,
|
|
396
|
-
flowTag,
|
|
397
|
-
flowStepName: step.stepName
|
|
398
|
-
})
|
|
399
|
-
);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
return { artifacts, functions };
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
async function emitDsqStep({ flow, step, flowTag, stepName }) {
|
|
406
|
-
const source = `app/src/generatedCode/FlowSchemas/${flowTag}/source`;
|
|
407
|
-
const handlerRoot = `src/generatedCode/FlowSchemas/${flowTag}/source`;
|
|
408
|
-
const functionName = `${flowTag}${stepName}`;
|
|
409
|
-
const mainFileName = `${functionName}_Main`;
|
|
410
|
-
const startConfig = stepConfig(flow, step);
|
|
411
|
-
|
|
412
|
-
let stepEvents = [];
|
|
413
|
-
if (Array.isArray(step.event)) {
|
|
414
|
-
stepEvents = step.event;
|
|
415
|
-
}
|
|
416
|
-
const artifacts = [];
|
|
417
|
-
if (!stepEvents.includes('extTopic')) {
|
|
418
|
-
artifacts.push({
|
|
419
|
-
path: `${source}/${mainFileName}.js`,
|
|
420
|
-
content: await renderStepMain(functionName, startConfig)
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
const functions = [];
|
|
424
|
-
|
|
425
|
-
const hasDsq = stepEvents.includes('dsq');
|
|
426
|
-
|
|
427
|
-
if (hasDsq) {
|
|
428
|
-
const queueName = `${functionName}HdrDsq`;
|
|
429
|
-
artifacts.push({
|
|
430
|
-
path: `${source}/${functionName}_HdrDsq.js`,
|
|
431
|
-
content: await renderDsq('FlowHandler_HdrDsq.ejs', {
|
|
432
|
-
flowTag: flow.flowTag,
|
|
433
|
-
flowStepName: step.stepName,
|
|
434
|
-
functionName,
|
|
435
|
-
mainFileName,
|
|
436
|
-
startConfig,
|
|
437
|
-
queueName
|
|
438
|
-
})
|
|
439
|
-
});
|
|
440
|
-
functions.push(
|
|
441
|
-
renderSqsFunctionYaml({
|
|
442
|
-
functionName: queueName,
|
|
443
|
-
handlerPath: `${handlerRoot}/${functionName}_HdrDsq.main`,
|
|
444
|
-
roleName: customFlowRoleName(flow.flowTag),
|
|
445
|
-
queueName,
|
|
446
|
-
flowTag,
|
|
447
|
-
flowStepName: step.stepName
|
|
448
|
-
})
|
|
449
|
-
);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
return { artifacts, functions };
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
async function emitOwnTopicRoot(flow, objects) {
|
|
456
|
-
const tag = upperFirst(flow.flowTag);
|
|
457
|
-
const source = `app/src/generatedCode/FlowSchemas/${tag}/source`;
|
|
458
|
-
const handlerRoot = `src/generatedCode/FlowSchemas/${tag}/source`;
|
|
459
|
-
const mainFileName = `${tag}_Main`;
|
|
460
|
-
const wbsMainFileName = `${tag}_WbsMain`;
|
|
461
|
-
const shared = {
|
|
462
|
-
flowTag: flow.flowTag,
|
|
463
|
-
flowStepName: '',
|
|
464
|
-
upperCaseFlowTag: tag,
|
|
465
|
-
startConfig: _startConfig(flow)
|
|
466
|
-
};
|
|
467
|
-
const isRbac = flowHasRbac(flow, objects);
|
|
468
|
-
const ownArtifacts = [
|
|
469
|
-
{
|
|
470
|
-
path: `${source}/${mainFileName}.js`,
|
|
471
|
-
content: await renderEndpointMain(flow, mainFileName, objects)
|
|
472
|
-
},
|
|
473
|
-
{
|
|
474
|
-
path: `${source}/${tag}_HdrSqs.js`,
|
|
475
|
-
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
476
|
-
...shared,
|
|
477
|
-
functionName: mainFileName,
|
|
478
|
-
mainFileName,
|
|
479
|
-
queueName: `${tag}HdrSqs`
|
|
480
|
-
})
|
|
481
|
-
},
|
|
482
|
-
{
|
|
483
|
-
path: `${source}/${wbsMainFileName}.js`,
|
|
484
|
-
content: await renderCrudTemplate('FlowMain_Wbs.ejs', {
|
|
485
|
-
...shared,
|
|
486
|
-
functionName: wbsMainFileName
|
|
487
|
-
})
|
|
488
|
-
},
|
|
489
|
-
{
|
|
490
|
-
path: `${source}/${tag}_HdrWbs.js`,
|
|
491
|
-
content: await renderCrudTemplate('FlowEndpoint_HdrWbs.ejs', {
|
|
492
|
-
...shared,
|
|
493
|
-
functionName: tag,
|
|
494
|
-
mainFileName: wbsMainFileName,
|
|
495
|
-
route: tag
|
|
496
|
-
})
|
|
497
|
-
}
|
|
498
|
-
];
|
|
499
|
-
|
|
500
|
-
const ownFunctions = [
|
|
501
|
-
renderWbsFunctionYaml({
|
|
502
|
-
functionName: `${tag}HdrWbs`,
|
|
503
|
-
handlerPath: `${handlerRoot}/${tag}_HdrWbs.main`,
|
|
504
|
-
roleName: customFlowRoleName(flow.flowTag),
|
|
505
|
-
routeName: tag,
|
|
506
|
-
flowTag: flow.flowTag,
|
|
507
|
-
flowStepName: ''
|
|
508
|
-
}),
|
|
509
|
-
renderSqsFunctionYaml({
|
|
510
|
-
functionName: `${tag}HdrSqs`,
|
|
511
|
-
handlerPath: `${handlerRoot}/${tag}_HdrSqs.main`,
|
|
512
|
-
roleName: customFlowRoleName(flow.flowTag),
|
|
513
|
-
queueName: `${tag}HdrSqs`,
|
|
514
|
-
flowTag: flow.flowTag,
|
|
515
|
-
flowStepName: ''
|
|
516
|
-
})
|
|
517
|
-
];
|
|
518
|
-
|
|
519
|
-
if (isRbac) {
|
|
520
|
-
const rbacStep = (flow.flowSteps || []).find(
|
|
521
|
-
(s) => typeof s?.stepName === 'string' && s.stepName.toLowerCase() === 'rbaccallback'
|
|
522
|
-
);
|
|
523
|
-
const rbacConfig = rbacStep ? stepConfig(flow, rbacStep) : null;
|
|
524
|
-
ownArtifacts.push(
|
|
525
|
-
{
|
|
526
|
-
path: `${source}/${tag}RbacCallback_Main.js`,
|
|
527
|
-
content: await renderCustom('FlowEndpointRbacCallback_Main.ejs', {
|
|
528
|
-
flowTag: flow.flowTag,
|
|
529
|
-
upperCaseFlowTag: tag,
|
|
530
|
-
functionName: `${tag}RbacCallbackMain`
|
|
531
|
-
})
|
|
532
|
-
},
|
|
533
|
-
{
|
|
534
|
-
path: `${source}/${tag}RbacCallback_HdrSqs.js`,
|
|
535
|
-
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
536
|
-
flowTag: flow.flowTag,
|
|
537
|
-
flowStepName: 'RbacCallback',
|
|
538
|
-
mainFileName: `${tag}RbacCallback_Main`,
|
|
539
|
-
functionName: `${tag}RbacCallbackMain`,
|
|
540
|
-
queueName: `${tag}RbacCallbackHdrSqs`,
|
|
541
|
-
startConfig: rbacConfig
|
|
542
|
-
})
|
|
543
|
-
}
|
|
544
|
-
);
|
|
545
|
-
ownFunctions.push(
|
|
546
|
-
renderSqsFunctionYaml({
|
|
547
|
-
functionName: `${tag}RbacCallbackHdrSqs`,
|
|
548
|
-
handlerPath: `${handlerRoot}/${tag}RbacCallback_HdrSqs.main`,
|
|
549
|
-
roleName: customFlowRoleName(flow.flowTag),
|
|
550
|
-
queueName: `${tag}RbacCallbackHdrSqs`,
|
|
551
|
-
flowTag: flow.flowTag,
|
|
552
|
-
flowStepName: 'RbacCallback'
|
|
553
|
-
})
|
|
554
|
-
);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
return {
|
|
558
|
-
artifacts: ownArtifacts,
|
|
559
|
-
functions: ownFunctions
|
|
560
|
-
};
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
function ownTopicRootPaths(flow, objects = []) {
|
|
564
|
-
const tag = upperFirst(flow.flowTag);
|
|
565
|
-
const source = `app/src/generatedCode/FlowSchemas/${tag}/source`;
|
|
566
|
-
const paths = [
|
|
567
|
-
`${source}/${tag}_Main.js`,
|
|
568
|
-
`${source}/${tag}_HdrSqs.js`,
|
|
569
|
-
`${source}/${tag}_WbsMain.js`,
|
|
570
|
-
`${source}/${tag}_HdrWbs.js`
|
|
571
|
-
];
|
|
572
|
-
if (flowHasRbac(flow, objects)) {
|
|
573
|
-
paths.push(
|
|
574
|
-
`${source}/${tag}RbacCallback_Main.js`,
|
|
575
|
-
`${source}/${tag}RbacCallback_HdrSqs.js`
|
|
576
|
-
);
|
|
577
|
-
}
|
|
578
|
-
return paths;
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
function needsProcessMain(flow) {
|
|
582
|
-
return (
|
|
583
|
-
!isS3Only(flow) &&
|
|
584
|
-
!flow.event.includes('ownTopic') &&
|
|
585
|
-
flow.event.some((event) => event !== 'ownTopic' && event !== 's3')
|
|
586
|
-
);
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
async function emitS3Flow(flow, source, handlerRoot) {
|
|
590
|
-
const tag = upperFirst(flow.flowTag);
|
|
591
|
-
const roleName = customFlowRoleName(flow.flowTag);
|
|
592
|
-
const parts = [
|
|
593
|
-
{
|
|
594
|
-
action: 'CreateObject',
|
|
595
|
-
handler: 'HdrWbs',
|
|
596
|
-
type: 'wbs',
|
|
597
|
-
mainTemplate: 'CreateObject_Main.ejs',
|
|
598
|
-
handlerTemplate: 'CreateObject_HdrWbs.ejs'
|
|
599
|
-
},
|
|
600
|
-
{
|
|
601
|
-
action: 'ReservedLimit',
|
|
602
|
-
handler: 'HdrSqs',
|
|
603
|
-
type: 'sqs',
|
|
604
|
-
mainTemplate: 'ReservedLimit_Main.ejs',
|
|
605
|
-
handlerTemplate: 'ReservedLimit_HdrSqs.ejs'
|
|
606
|
-
},
|
|
607
|
-
{
|
|
608
|
-
action: 'CreatePreSignUrl',
|
|
609
|
-
handler: 'HdrSqs',
|
|
610
|
-
type: 'sqs',
|
|
611
|
-
mainTemplate: 'CreatePreSignUrl_Main.ejs',
|
|
612
|
-
handlerTemplate: 'CreatePreSignUrl_HdrSqs.ejs'
|
|
613
|
-
},
|
|
614
|
-
{
|
|
615
|
-
action: 'ProcessAfterUpload',
|
|
616
|
-
handler: 'HdrS3',
|
|
617
|
-
type: 's3',
|
|
618
|
-
mainTemplate: 'ProcessS3File_Main.ejs',
|
|
619
|
-
handlerTemplate: 'FlowHandler_HdrS3.ejs'
|
|
620
|
-
},
|
|
621
|
-
{
|
|
622
|
-
action: 'ConfirmAfterUpload',
|
|
623
|
-
handler: 'HdrSqs',
|
|
624
|
-
type: 'sqs',
|
|
625
|
-
mainTemplate: 'ConfirmReserved_Main.ejs',
|
|
626
|
-
handlerTemplate: 'ConfirmReserved_HdrSqs.ejs'
|
|
627
|
-
}
|
|
628
|
-
];
|
|
629
|
-
const emitted = await Promise.all(
|
|
630
|
-
parts.map(
|
|
631
|
-
async ({ action, handler, type, mainTemplate, handlerTemplate }) => {
|
|
632
|
-
const functionName = `${tag}${action}`;
|
|
633
|
-
const mainFileName = `${functionName}_Main`;
|
|
634
|
-
const handlerFileName = `${functionName}_${handler}`;
|
|
635
|
-
const mainContent = await renderCustom(
|
|
636
|
-
`s3/${mainTemplate}`,
|
|
637
|
-
_s3TemplateData({ action, flow, functionName })
|
|
638
|
-
);
|
|
639
|
-
const handlerContent = await renderCustom(
|
|
640
|
-
`s3/${handlerTemplate}`,
|
|
641
|
-
_s3HandlerData({ action, flow, functionName, mainFileName, handler })
|
|
642
|
-
);
|
|
643
|
-
const descriptor = {
|
|
644
|
-
functionName: `${functionName}${handler}`,
|
|
645
|
-
handlerPath: `${handlerRoot}/${handlerFileName}.main`,
|
|
646
|
-
roleName
|
|
647
|
-
};
|
|
648
|
-
let functionYaml;
|
|
649
|
-
if (type === 'wbs') {
|
|
650
|
-
functionYaml = renderWbsFunctionYaml({
|
|
651
|
-
...descriptor,
|
|
652
|
-
routeName: tag,
|
|
653
|
-
flowTag: flow.flowTag,
|
|
654
|
-
flowStepName: ''
|
|
655
|
-
});
|
|
656
|
-
} else if (type === 'sqs') {
|
|
657
|
-
let filterPatternFunctionName = descriptor.functionName;
|
|
658
|
-
if (action === 'CreatePreSignUrl') {
|
|
659
|
-
filterPatternFunctionName = 'CreatePresignUrlHdrSqs';
|
|
660
|
-
}
|
|
661
|
-
functionYaml = renderSqsFunctionYaml({
|
|
662
|
-
...descriptor,
|
|
663
|
-
queueName: descriptor.functionName,
|
|
664
|
-
flowTag: flow.flowTag,
|
|
665
|
-
flowStepName: '',
|
|
666
|
-
filterPatternFunctionName
|
|
667
|
-
});
|
|
668
|
-
} else if (type === 's3') {
|
|
669
|
-
let bucketName = '';
|
|
670
|
-
if (flow.bucketName) {
|
|
671
|
-
bucketName = flow.bucketName;
|
|
672
|
-
}
|
|
673
|
-
functionYaml = renderS3FunctionYaml({
|
|
674
|
-
...descriptor,
|
|
675
|
-
bucketName,
|
|
676
|
-
flowTag: flow.flowTag,
|
|
677
|
-
flowStepName: ''
|
|
678
|
-
});
|
|
679
|
-
} else {
|
|
680
|
-
functionYaml = renderInvFunctionYaml({
|
|
681
|
-
...descriptor,
|
|
682
|
-
flowTag: flow.flowTag,
|
|
683
|
-
flowStepName: ''
|
|
684
|
-
});
|
|
685
|
-
}
|
|
686
|
-
return {
|
|
687
|
-
artifacts: [
|
|
688
|
-
{ path: `${source}/${mainFileName}.js`, content: mainContent },
|
|
689
|
-
{ path: `${source}/${handlerFileName}.js`, content: handlerContent }
|
|
690
|
-
],
|
|
691
|
-
functionYaml
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
|
-
)
|
|
695
|
-
);
|
|
696
|
-
return {
|
|
697
|
-
artifacts: emitted.flatMap((item) => item.artifacts),
|
|
698
|
-
functions: emitted.map((item) => item.functionYaml)
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
function _s3TemplateData({ action, flow, functionName }) {
|
|
703
|
-
if (action === 'CreateObject') {
|
|
704
|
-
return {
|
|
705
|
-
flowTag: flow.flowTag,
|
|
706
|
-
objectType: flow.objType?.objectType,
|
|
707
|
-
functionName
|
|
708
|
-
};
|
|
709
|
-
}
|
|
710
|
-
if (action === 'CreatePreSignUrl') {
|
|
711
|
-
return { flowTag: flow.flowTag };
|
|
712
|
-
}
|
|
713
|
-
return { flowTag: flow.flowTag, functionName };
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
function _s3HandlerData({ action, flow, functionName, mainFileName, handler }) {
|
|
717
|
-
if (action === 'CreateObject') {
|
|
718
|
-
return { functionName, handlerType: handler, route: flow.flowTag };
|
|
719
|
-
}
|
|
720
|
-
if (action === 'ProcessAfterUpload') {
|
|
721
|
-
let bucketName = '';
|
|
722
|
-
if (flow.bucketName) {
|
|
723
|
-
bucketName = flow.bucketName;
|
|
724
|
-
}
|
|
725
|
-
return {
|
|
726
|
-
flowTag: flow.flowTag,
|
|
727
|
-
functionName,
|
|
728
|
-
mainFileName,
|
|
729
|
-
s3Bucket: bucketName
|
|
730
|
-
};
|
|
731
|
-
}
|
|
732
|
-
return { functionName, handlerType: handler };
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
function _startConfig(flow) {
|
|
736
|
-
const steps = flow.flowSteps ?? [];
|
|
737
|
-
const start =
|
|
738
|
-
steps.find(
|
|
739
|
-
(s) =>
|
|
740
|
-
typeof s?.stepName === 'string' &&
|
|
741
|
-
s.stepName.toLowerCase() === 'inprocess'
|
|
742
|
-
) ??
|
|
743
|
-
steps.find(
|
|
744
|
-
(s) =>
|
|
745
|
-
typeof s?.stepName === 'string' && s.stepName.toLowerCase() === 'start'
|
|
746
|
-
) ??
|
|
747
|
-
steps[0];
|
|
748
|
-
if (start) {
|
|
749
|
-
return stepConfig(flow, start);
|
|
750
|
-
}
|
|
751
|
-
return null;
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
function stepConfig(flow, step) {
|
|
755
|
-
return {
|
|
756
|
-
...step,
|
|
757
|
-
properties: mapFields(step.properties, flow.stepProperties),
|
|
758
|
-
messageAttributes: mapFields(
|
|
759
|
-
step.messageAttributes,
|
|
760
|
-
flow.stepMessageAttributes
|
|
761
|
-
)
|
|
762
|
-
};
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
function mapFields(items = [], definitions = {}) {
|
|
766
|
-
return items.map((item) => {
|
|
767
|
-
if (typeof item === 'string') {
|
|
768
|
-
const def = definitions?.[item] ?? {};
|
|
769
|
-
return {
|
|
770
|
-
propertyName: item,
|
|
771
|
-
required: def.required ?? false,
|
|
772
|
-
...def
|
|
773
|
-
};
|
|
774
|
-
}
|
|
775
|
-
if (typeof item === 'object' && item !== null) {
|
|
776
|
-
const name = item.key ?? item.propertyName;
|
|
777
|
-
const def = definitions?.[name] ?? {};
|
|
778
|
-
return {
|
|
779
|
-
propertyName: name,
|
|
780
|
-
required: item.required ?? def.required ?? false,
|
|
781
|
-
...def,
|
|
782
|
-
...item
|
|
783
|
-
};
|
|
784
|
-
}
|
|
785
|
-
return item;
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
function isS3Only(flow) {
|
|
790
|
-
return flow.event.length === 1 && flow.event[0] === 's3';
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
async function renderEndpointMain(flow, functionName, objects = []) {
|
|
794
|
-
const isRbac = flowHasRbac(flow, objects);
|
|
795
|
-
const matchedObject = objects.find(
|
|
796
|
-
(o) => o.objectType === flow.objType?.objectType
|
|
797
|
-
);
|
|
798
|
-
let rbacServiceTag = null;
|
|
799
|
-
if (matchedObject) {
|
|
800
|
-
const belongTo = matchedObject.belongTo;
|
|
801
|
-
if (belongTo) {
|
|
802
|
-
rbacServiceTag = Array.isArray(belongTo)
|
|
803
|
-
? belongTo[0]?.serviceTag
|
|
804
|
-
: belongTo?.serviceTag;
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
if (!rbacServiceTag) {
|
|
808
|
-
rbacServiceTag = flow.objType?.serviceTag || flow.serviceTag || 'Rbac';
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
const enrichedFlow = {
|
|
812
|
-
...flow,
|
|
813
|
-
isRbac
|
|
814
|
-
};
|
|
815
|
-
|
|
816
|
-
return renderCustom('FlowEndpoint_Main.ejs', {
|
|
817
|
-
flow: enrichedFlow,
|
|
818
|
-
flowTag: flow.flowTag,
|
|
819
|
-
upperCaseFlowTag: upperFirst(flow.flowTag),
|
|
820
|
-
functionName,
|
|
821
|
-
rbacServiceTag,
|
|
822
|
-
tableName: storedCacheTableName(flow, objects),
|
|
823
|
-
startConfig: _startConfig(flow)
|
|
824
|
-
});
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
function storedCacheTableName(flow, objects) {
|
|
828
|
-
if (flow.statusType !== 'storedCache') return null;
|
|
829
|
-
const candidates = objects.filter(
|
|
830
|
-
(object) => object.objectType === flow.objType?.objectType
|
|
831
|
-
);
|
|
832
|
-
const object = flow.objType?.serviceTag
|
|
833
|
-
? (candidates.find(
|
|
834
|
-
(object) => object.serviceTag === flow.objType.serviceTag
|
|
835
|
-
) ?? candidates.find((object) => object.serviceTag === undefined))
|
|
836
|
-
: candidates[0];
|
|
837
|
-
return (
|
|
838
|
-
Object.values(object?.storageResources ?? {}).find(
|
|
839
|
-
(resource) =>
|
|
840
|
-
resource?.storageType === 'dynamo' ||
|
|
841
|
-
resource?.storageType === 'dynamoDB' ||
|
|
842
|
-
!resource?.storageType
|
|
843
|
-
)?.tableName ?? null
|
|
844
|
-
);
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
async function renderStepMain(functionName, startConfig = null) {
|
|
848
|
-
return renderCustom('FlowStep_Main.ejs', { functionName, startConfig });
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
function renderMain(functionName) {
|
|
852
|
-
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`;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
async function render(templateName, data) {
|
|
856
|
-
return ejsLib.render(
|
|
857
|
-
await readFile(new URL(templateName, TEMPLATE_URL), 'utf8'),
|
|
858
|
-
data
|
|
859
|
-
);
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
async function renderShared(templateName, data) {
|
|
863
|
-
return ejsLib.render(
|
|
864
|
-
await readFile(new URL(templateName, SHARED_TEMPLATE_URL), 'utf8'),
|
|
865
|
-
data
|
|
866
|
-
);
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
async function renderCrudTemplate(templateName, data) {
|
|
870
|
-
return ejsLib.render(
|
|
871
|
-
await readFile(new URL(templateName, TEMPLATE_URL), 'utf8'),
|
|
872
|
-
data
|
|
873
|
-
);
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
async function renderDsq(templateName, data) {
|
|
877
|
-
return ejsLib.render(
|
|
878
|
-
await readFile(new URL(templateName, SHARED_TEMPLATE_URL), 'utf8'),
|
|
879
|
-
data
|
|
880
|
-
);
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
async function renderCustom(templateName, data) {
|
|
884
|
-
return ejsLib
|
|
885
|
-
.render(
|
|
886
|
-
await readFile(new URL(templateName, CUSTOM_TEMPLATE_URL), 'utf8'),
|
|
887
|
-
data
|
|
888
|
-
)
|
|
889
|
-
.replace(/\n$/, '');
|
|
890
|
-
}
|