@izara_project/izara-core-generate-service-code 1.0.99 → 1.0.101
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/compile/compileProject.js +16 -5
- package/src/compile/flowValidator.js +3 -1
- package/src/compile/loadSchemas.js +18 -4
- package/src/compile/schemaValidatorSetup.js +16 -0
- package/src/emit/application/coreFunction/emitCoreFunctionArtifacts.js +108 -108
- package/src/emit/application/coreFunction/templates/InitialSetupRunner.ejs +2 -2
- package/src/emit/application/crud/templates/CreateComplete_Main.ejs +2 -0
- package/src/emit/application/crud/templates/CreateLogicalLib.ejs +20 -7
- package/src/emit/application/crud/templates/DeleteComplete_Main.ejs +2 -0
- package/src/emit/application/crud/templates/FlowEndpoint_HdrWbs.ejs +7 -5
- package/src/emit/application/crud/templates/UpdateComplete_Main.ejs +2 -0
- package/src/emit/application/custom/customFlowPaths.js +13 -16
- package/src/emit/application/custom/customFlowS3.js +456 -63
- package/src/emit/application/custom/customFlows.js +131 -0
- package/src/emit/application/custom/emitCustomFlowApplicationArtifacts.js +7 -4
- package/src/emit/application/custom/templates/s3/ConfirmAfterUpload_HdrSqs.ejs +111 -0
- package/src/emit/application/custom/templates/s3/ConfirmAfterUpload_Main.ejs +89 -0
- package/src/emit/application/custom/templates/s3/ConfirmComplete_HdrSqs.ejs +111 -0
- package/src/emit/application/custom/templates/s3/ConfirmComplete_Main.ejs +100 -0
- package/src/emit/application/custom/templates/s3/CreateObject_HdrWbs.ejs +2 -1
- package/src/emit/application/custom/templates/s3/CreateObject_Main.ejs +4 -0
- package/src/emit/application/custom/templates/s3/CreatePreSignUrl_HdrSqs.ejs +42 -0
- package/src/emit/application/custom/templates/s3/CreatePreSignUrl_Main.ejs +23 -0
- package/src/emit/application/custom/templates/s3/ProcessS3File_Main.ejs +240 -27
- package/src/emit/application/custom/templates/s3/Start_Main.ejs +216 -0
- package/src/emit/application/rbac/emitDynamicRbacFlowSchemas.js +5 -1
- package/src/emit/application/rbac/emitRbacApplicationArtifacts.js +67 -60
- package/src/emit/application/rbac/templates/ReservedDynamicUsage_Main.ejs +27 -9
- package/src/emit/application/rbac/templates/UserRbacFlow_Main.ejs +4 -3
- package/src/emit/application/system/templates/Register_HdrWbs.ejs +2 -1
- package/src/emit/infrastructure/functions/functionYamlArtifact.js +3 -8
- package/src/emit/infrastructure/functions/templates/S3Function_Yaml.ejs +2 -3
- package/src/emit/infrastructure/resources/iamResourceArtifacts.js +22 -0
- package/src/emit/infrastructure/resources/resourceState.js +15 -5
- package/src/emit/infrastructure/resources/s3ResourceArtifacts.js +19 -3
- package/src/emit/infrastructure/resources/templates/S3Bucket_Yaml.ejs +1 -1
- package/src/emit/infrastructure/resources/templates/SystemDynamoDB_Yaml.ejs +2 -2
- package/src/emit/schemas/error/emitErrorSchemas.js +120 -10
- package/src/emit/schemas/error/templates/errorConsts.ejs +12 -0
- package/src/generate.js +32 -30
- package/src/plan/domainRegistry.js +2 -1
- package/test/integration/publicApi.test.js +33 -24
- package/test/unit/application/createTargetRoleHandler.test.js +33 -10
- package/test/unit/application/customFlowApplicationArtifacts.test.js +6 -6
- package/test/unit/application/customFlowS3.test.js +858 -0
- package/test/unit/infrastructure/functionYamlArtifact.test.js +6 -4
- package/test/unit/infrastructure/resourceArtifacts.test.js +51 -0
- package/test/unit/schemas/dynamicRbacFlowSchemas.test.js +8 -6
- package/test/unit/schemas/dynamicRelationshipFlowSchemas.test.js +51 -0
- package/test/unit/schemas/errorSchemas.test.js +84 -5
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { renderCustom } from './customFlowTemplates.js';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
customFlowRoleName,
|
|
4
|
+
upperFirst,
|
|
5
|
+
resolveS3Parts,
|
|
6
|
+
flowHasRbac
|
|
7
|
+
} from './customFlows.js';
|
|
3
8
|
import {
|
|
4
9
|
renderInvFunctionYaml,
|
|
5
10
|
renderS3FunctionYaml,
|
|
@@ -7,63 +12,82 @@ import {
|
|
|
7
12
|
renderWbsFunctionYaml
|
|
8
13
|
} from '../../infrastructure/functions/functionYamlArtifact.js';
|
|
9
14
|
|
|
10
|
-
export
|
|
15
|
+
export function isSimplifiedS3Flow(flow) {
|
|
16
|
+
if (!Array.isArray(flow?.flowSteps) || flow.flowSteps.length === 0) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const stepNames = flow.flowSteps.map((s) => s.stepName);
|
|
20
|
+
if (stepNames.includes('ReservedLimit')) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function emitS3Flow(
|
|
27
|
+
flow,
|
|
28
|
+
source,
|
|
29
|
+
handlerRoot,
|
|
30
|
+
{ objects = [], relationships = [] } = {}
|
|
31
|
+
) {
|
|
11
32
|
const tag = upperFirst(flow.flowTag);
|
|
12
33
|
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
|
-
];
|
|
34
|
+
const parts = resolveS3Parts(flow);
|
|
35
|
+
const isSimplifiedS3 = isSimplifiedS3Flow(flow);
|
|
50
36
|
|
|
51
37
|
const emitted = await Promise.all(
|
|
52
38
|
parts.map(
|
|
53
|
-
async (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
39
|
+
async (
|
|
40
|
+
{ action, handler, type, mainTemplate, handlerTemplate },
|
|
41
|
+
index
|
|
42
|
+
) => {
|
|
43
|
+
let isStart = false;
|
|
44
|
+
if (typeof action === 'string' && action.toLowerCase() === 'start') {
|
|
45
|
+
isStart = true;
|
|
46
|
+
}
|
|
47
|
+
let functionName = `${tag}${action}`;
|
|
48
|
+
let mainFileName = `${functionName}_Main`;
|
|
49
|
+
let handlerFileName = `${functionName}_${handler}`;
|
|
50
|
+
let slsFunctionName = `${functionName}${handler}`;
|
|
51
|
+
let flowStepName = action;
|
|
52
|
+
if (isStart) {
|
|
53
|
+
functionName = tag;
|
|
54
|
+
mainFileName = `${tag}_Main`;
|
|
55
|
+
handlerFileName = `${tag}_${handler}`;
|
|
56
|
+
slsFunctionName = `${tag}${handler}`;
|
|
57
|
+
flowStepName = '';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const nextPart = parts.find((p, i) => i > index && p.type === 'sqs');
|
|
61
|
+
let nextStepFunctionName = null;
|
|
62
|
+
if (nextPart) {
|
|
63
|
+
nextStepFunctionName = `${tag}${nextPart.action}${nextPart.handler}`;
|
|
64
|
+
}
|
|
65
|
+
|
|
57
66
|
const mainContent = await renderCustom(
|
|
58
67
|
`s3/${mainTemplate}`,
|
|
59
|
-
_s3TemplateData({
|
|
68
|
+
_s3TemplateData({
|
|
69
|
+
action,
|
|
70
|
+
flow,
|
|
71
|
+
functionName,
|
|
72
|
+
nextStepFunctionName,
|
|
73
|
+
isSimplifiedS3,
|
|
74
|
+
objects,
|
|
75
|
+
relationships
|
|
76
|
+
})
|
|
60
77
|
);
|
|
61
78
|
const handlerContent = await renderCustom(
|
|
62
79
|
`s3/${handlerTemplate}`,
|
|
63
|
-
_s3HandlerData({
|
|
80
|
+
_s3HandlerData({
|
|
81
|
+
action,
|
|
82
|
+
flow,
|
|
83
|
+
functionName,
|
|
84
|
+
mainFileName,
|
|
85
|
+
handler,
|
|
86
|
+
isSimplifiedS3
|
|
87
|
+
})
|
|
64
88
|
);
|
|
65
89
|
const descriptor = {
|
|
66
|
-
functionName:
|
|
90
|
+
functionName: slsFunctionName,
|
|
67
91
|
handlerPath: `${handlerRoot}/${handlerFileName}.main`,
|
|
68
92
|
roleName
|
|
69
93
|
};
|
|
@@ -73,11 +97,11 @@ export async function emitS3Flow(flow, source, handlerRoot) {
|
|
|
73
97
|
...descriptor,
|
|
74
98
|
routeName: tag,
|
|
75
99
|
flowTag: flow.flowTag,
|
|
76
|
-
flowStepName
|
|
100
|
+
flowStepName
|
|
77
101
|
});
|
|
78
102
|
} else if (type === 'sqs') {
|
|
79
103
|
let filterPatternFunctionName = descriptor.functionName;
|
|
80
|
-
if (action === 'CreatePreSignUrl') {
|
|
104
|
+
if (!isSimplifiedS3 && action === 'CreatePreSignUrl') {
|
|
81
105
|
filterPatternFunctionName = 'CreatePresignUrlHdrSqs';
|
|
82
106
|
}
|
|
83
107
|
functionYaml = renderSqsFunctionYaml({
|
|
@@ -100,6 +124,7 @@ export async function emitS3Flow(flow, source, handlerRoot) {
|
|
|
100
124
|
functionYaml = renderS3FunctionYaml({
|
|
101
125
|
...descriptor,
|
|
102
126
|
bucketName: flow.bucketName,
|
|
127
|
+
s3KeyPrefix: flow.s3KeyPrefix,
|
|
103
128
|
flowTag: flow.flowTag,
|
|
104
129
|
flowStepName: action
|
|
105
130
|
});
|
|
@@ -127,23 +152,390 @@ export async function emitS3Flow(flow, source, handlerRoot) {
|
|
|
127
152
|
};
|
|
128
153
|
}
|
|
129
154
|
|
|
130
|
-
function
|
|
131
|
-
if (
|
|
132
|
-
return
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
155
|
+
export function extractIdentifierFieldNames(identifiers) {
|
|
156
|
+
if (!Array.isArray(identifiers) || identifiers.length === 0) {
|
|
157
|
+
return [];
|
|
158
|
+
}
|
|
159
|
+
const keys = [];
|
|
160
|
+
for (const item of identifiers) {
|
|
161
|
+
if (typeof item === 'string') {
|
|
162
|
+
if (item && !keys.includes(item)) {
|
|
163
|
+
keys.push(item);
|
|
164
|
+
}
|
|
165
|
+
} else if (item && typeof item === 'object') {
|
|
166
|
+
if (Array.isArray(item.fieldNames) && item.fieldNames.length > 0) {
|
|
167
|
+
for (const fn of item.fieldNames) {
|
|
168
|
+
if (typeof fn === 'string' && fn && !keys.includes(fn)) {
|
|
169
|
+
keys.push(fn);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
} else if (typeof item.fieldName === 'string' && item.fieldName) {
|
|
173
|
+
if (!keys.includes(item.fieldName)) {
|
|
174
|
+
keys.push(item.fieldName);
|
|
175
|
+
}
|
|
176
|
+
} else if (typeof item.name === 'string' && item.name) {
|
|
177
|
+
if (!keys.includes(item.name)) {
|
|
178
|
+
keys.push(item.name);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return keys;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function resolveParentIdentifierInfo(flow, objects = []) {
|
|
187
|
+
let parentObjectType = null;
|
|
188
|
+
let parentServiceTag = null;
|
|
189
|
+
const targetObjType =
|
|
190
|
+
typeof flow.objType === 'string'
|
|
191
|
+
? flow.objType
|
|
192
|
+
: flow.objType?.objectType || flow.objectType;
|
|
193
|
+
const matchedObject = (objects || []).find(
|
|
194
|
+
(o) => o.objectType === targetObjType
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
if (flow.parentObjectType) {
|
|
198
|
+
parentObjectType = flow.parentObjectType;
|
|
199
|
+
} else if (flow.belongTo?.objectType) {
|
|
200
|
+
parentObjectType = flow.belongTo.objectType;
|
|
201
|
+
parentServiceTag = flow.belongTo.serviceTag;
|
|
202
|
+
} else if (Array.isArray(flow.belongTo) && flow.belongTo[0]?.objectType) {
|
|
203
|
+
parentObjectType = flow.belongTo[0].objectType;
|
|
204
|
+
parentServiceTag = flow.belongTo[0].serviceTag;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (!parentObjectType && matchedObject?.belongTo) {
|
|
208
|
+
const belongTo = matchedObject.belongTo;
|
|
209
|
+
if (Array.isArray(belongTo) && belongTo[0]?.objectType) {
|
|
210
|
+
parentObjectType = belongTo[0].objectType;
|
|
211
|
+
parentServiceTag = belongTo[0].serviceTag;
|
|
212
|
+
} else if (belongTo.objectType) {
|
|
213
|
+
parentObjectType = belongTo.objectType;
|
|
214
|
+
parentServiceTag = belongTo.serviceTag;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const belongToDef = flow.belongTo || matchedObject?.belongTo;
|
|
219
|
+
const singleBelongTo = Array.isArray(belongToDef) ? belongToDef[0] : belongToDef;
|
|
220
|
+
|
|
221
|
+
let parentIdKeys = [];
|
|
222
|
+
if (Array.isArray(flow.parentIdentifierKeys) && flow.parentIdentifierKeys.length > 0) {
|
|
223
|
+
parentIdKeys = [...flow.parentIdentifierKeys];
|
|
224
|
+
} else if (flow.parentIdentifierKey) {
|
|
225
|
+
parentIdKeys = [flow.parentIdentifierKey];
|
|
226
|
+
} else if (
|
|
227
|
+
Array.isArray(singleBelongTo?.parentIdentifierKeys) &&
|
|
228
|
+
singleBelongTo.parentIdentifierKeys.length > 0
|
|
229
|
+
) {
|
|
230
|
+
parentIdKeys = [...singleBelongTo.parentIdentifierKeys];
|
|
231
|
+
} else if (
|
|
232
|
+
Array.isArray(singleBelongTo?.identifiers) &&
|
|
233
|
+
singleBelongTo.identifiers.length > 0
|
|
234
|
+
) {
|
|
235
|
+
parentIdKeys = extractIdentifierFieldNames(singleBelongTo.identifiers);
|
|
236
|
+
} else {
|
|
237
|
+
const parentObj =
|
|
238
|
+
Array.isArray(objects) && parentObjectType
|
|
239
|
+
? objects.find((o) => o.objectType === parentObjectType)
|
|
240
|
+
: null;
|
|
241
|
+
const parentIdentifiers =
|
|
242
|
+
parentObj?.identifiers || matchedObject?.belongToSchema?.identifiers;
|
|
243
|
+
if (Array.isArray(parentIdentifiers) && parentIdentifiers.length > 0) {
|
|
244
|
+
parentIdKeys = extractIdentifierFieldNames(parentIdentifiers);
|
|
245
|
+
}
|
|
246
|
+
if (parentIdKeys.length === 0 && parentObjectType) {
|
|
247
|
+
parentIdKeys = [`${parentObjectType}Id`];
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
let parentIdKey = null;
|
|
252
|
+
if (parentIdKeys.length > 0) {
|
|
253
|
+
parentIdKey = parentIdKeys[0];
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
parentObjectType,
|
|
258
|
+
parentServiceTag,
|
|
259
|
+
parentIdKey,
|
|
260
|
+
parentIdKeys
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export function resolveFlowRelationships(
|
|
265
|
+
flow,
|
|
266
|
+
{ objects = [], relationships = [] } = {}
|
|
267
|
+
) {
|
|
268
|
+
if (Array.isArray(flow.relationships) && flow.relationships.length > 0) {
|
|
269
|
+
const list = [];
|
|
270
|
+
for (const rel of flow.relationships) {
|
|
271
|
+
let targetObj = {
|
|
272
|
+
objectType: '',
|
|
273
|
+
serviceTag: ''
|
|
274
|
+
};
|
|
275
|
+
if (rel.targetObjType) {
|
|
276
|
+
targetObj = {
|
|
277
|
+
objectType: rel.targetObjType.objectType || '',
|
|
278
|
+
serviceTag: rel.targetObjType.serviceTag || ''
|
|
279
|
+
};
|
|
280
|
+
} else if (rel.objectType) {
|
|
281
|
+
targetObj = {
|
|
282
|
+
objectType: rel.objectType,
|
|
283
|
+
serviceTag: rel.serviceTag || ''
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
let relType = {
|
|
288
|
+
relationshipTag: '',
|
|
289
|
+
serviceTag: targetObj.serviceTag
|
|
290
|
+
};
|
|
291
|
+
if (rel.relType) {
|
|
292
|
+
relType = {
|
|
293
|
+
relationshipTag: rel.relType.relationshipTag || '',
|
|
294
|
+
serviceTag: rel.relType.serviceTag || targetObj.serviceTag
|
|
295
|
+
};
|
|
296
|
+
} else if (rel.relationshipTag) {
|
|
297
|
+
relType = {
|
|
298
|
+
relationshipTag: rel.relationshipTag,
|
|
299
|
+
serviceTag: rel.serviceTag || targetObj.serviceTag
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
let targetIdentifierKey = '';
|
|
304
|
+
if (rel.targetIdentifierKey) {
|
|
305
|
+
targetIdentifierKey = rel.targetIdentifierKey;
|
|
306
|
+
} else if (rel.targetIdentifiers) {
|
|
307
|
+
const idKeys = Object.keys(rel.targetIdentifiers);
|
|
308
|
+
if (idKeys.length > 0) {
|
|
309
|
+
targetIdentifierKey = idKeys[0];
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (!targetIdentifierKey && targetObj.objectType) {
|
|
313
|
+
targetIdentifierKey = `${targetObj.objectType}Id`;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
let direction = 'to';
|
|
317
|
+
if (rel.relationshipDirection) {
|
|
318
|
+
direction = rel.relationshipDirection;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
list.push({
|
|
322
|
+
targetObjType: targetObj,
|
|
323
|
+
relType,
|
|
324
|
+
targetIdentifierKey,
|
|
325
|
+
relationshipProperties: rel.relationshipProperties || {},
|
|
326
|
+
relationshipDirection: direction
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
return list;
|
|
137
330
|
}
|
|
138
|
-
|
|
139
|
-
|
|
331
|
+
|
|
332
|
+
let targetObjType = '';
|
|
333
|
+
if (typeof flow.objType === 'string') {
|
|
334
|
+
targetObjType = flow.objType;
|
|
335
|
+
} else if (flow.objType?.objectType) {
|
|
336
|
+
targetObjType = flow.objType.objectType;
|
|
337
|
+
} else if (flow.objectType) {
|
|
338
|
+
targetObjType = flow.objectType;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (
|
|
342
|
+
!targetObjType ||
|
|
343
|
+
!Array.isArray(relationships) ||
|
|
344
|
+
relationships.length === 0
|
|
345
|
+
) {
|
|
346
|
+
return [];
|
|
140
347
|
}
|
|
141
|
-
|
|
348
|
+
|
|
349
|
+
const resolved = [];
|
|
350
|
+
for (const relItem of relationships) {
|
|
351
|
+
if (!relItem || typeof relItem !== 'object') {
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (
|
|
356
|
+
relItem.objectType &&
|
|
357
|
+
relItem.objectType.toLowerCase() === targetObjType.toLowerCase() &&
|
|
358
|
+
relItem.relationshipTag &&
|
|
359
|
+
relItem.relationshipServiceTag
|
|
360
|
+
) {
|
|
361
|
+
const parentService = relItem.relationshipServiceTag;
|
|
362
|
+
let parentObjType = '';
|
|
363
|
+
if (relItem.targetObjectType) {
|
|
364
|
+
parentObjType = relItem.targetObjectType;
|
|
365
|
+
} else if (parentService.length > 0) {
|
|
366
|
+
parentObjType =
|
|
367
|
+
parentService[0].toLowerCase() + parentService.slice(1);
|
|
368
|
+
}
|
|
369
|
+
let targetIdentifierKey = `${parentObjType}Id`;
|
|
370
|
+
if (relItem.targetIdentifierKey) {
|
|
371
|
+
targetIdentifierKey = relItem.targetIdentifierKey;
|
|
372
|
+
}
|
|
373
|
+
let direction = 'to';
|
|
374
|
+
if (relItem.relationshipDirection) {
|
|
375
|
+
direction = relItem.relationshipDirection;
|
|
376
|
+
}
|
|
377
|
+
resolved.push({
|
|
378
|
+
targetObjType: {
|
|
379
|
+
objectType: parentObjType,
|
|
380
|
+
serviceTag: parentService
|
|
381
|
+
},
|
|
382
|
+
relType: {
|
|
383
|
+
relationshipTag: relItem.relationshipTag,
|
|
384
|
+
serviceTag: parentService
|
|
385
|
+
},
|
|
386
|
+
targetIdentifierKey,
|
|
387
|
+
relationshipProperties: {},
|
|
388
|
+
relationshipDirection: direction
|
|
389
|
+
});
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const relKeys = Object.keys(relItem);
|
|
394
|
+
for (const relTag of relKeys) {
|
|
395
|
+
const relDef = relItem[relTag];
|
|
396
|
+
if (!relDef || !Array.isArray(relDef.links)) {
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
for (const link of relDef.links) {
|
|
400
|
+
if (!link || !link.from || !link.to) {
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const isToTarget =
|
|
405
|
+
link.to.objType?.objectType?.toLowerCase() ===
|
|
406
|
+
targetObjType.toLowerCase();
|
|
407
|
+
if (isToTarget && link.to.requiredOnCreate) {
|
|
408
|
+
const fromObj = link.from.objType || {};
|
|
409
|
+
const fromObjType = fromObj.objectType || '';
|
|
410
|
+
const targetIdentifierKey = `${fromObjType}Id`;
|
|
411
|
+
resolved.push({
|
|
412
|
+
targetObjType: {
|
|
413
|
+
objectType: fromObjType,
|
|
414
|
+
serviceTag: fromObj.serviceTag || ''
|
|
415
|
+
},
|
|
416
|
+
relType: {
|
|
417
|
+
relationshipTag: relTag,
|
|
418
|
+
serviceTag: fromObj.serviceTag || ''
|
|
419
|
+
},
|
|
420
|
+
targetIdentifierKey,
|
|
421
|
+
relationshipProperties: {},
|
|
422
|
+
relationshipDirection: 'to'
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return resolved;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
function _s3TemplateData({
|
|
433
|
+
action,
|
|
434
|
+
flow,
|
|
435
|
+
functionName,
|
|
436
|
+
nextStepFunctionName,
|
|
437
|
+
isSimplifiedS3,
|
|
438
|
+
objects = [],
|
|
439
|
+
relationships = []
|
|
440
|
+
}) {
|
|
441
|
+
let maxFileSizeMb = 50;
|
|
442
|
+
if (flow.maxFileSizeMb) {
|
|
443
|
+
maxFileSizeMb = flow.maxFileSizeMb;
|
|
444
|
+
}
|
|
445
|
+
let expires = 86400;
|
|
446
|
+
if (flow.expires) {
|
|
447
|
+
expires = flow.expires;
|
|
448
|
+
}
|
|
449
|
+
let contentTypePrefix = 'video/';
|
|
450
|
+
if (flow.contentTypePrefix) {
|
|
451
|
+
contentTypePrefix = flow.contentTypePrefix;
|
|
452
|
+
} else if (flow.contentType) {
|
|
453
|
+
contentTypePrefix = flow.contentType;
|
|
454
|
+
}
|
|
455
|
+
const { parentObjectType, parentServiceTag, parentIdKey, parentIdKeys } =
|
|
456
|
+
resolveParentIdentifierInfo(flow, objects);
|
|
457
|
+
let s3KeyPrefix = 'uploads/';
|
|
458
|
+
if (flow.s3KeyPrefix) {
|
|
459
|
+
s3KeyPrefix = flow.s3KeyPrefix;
|
|
460
|
+
}
|
|
461
|
+
let defaultImportType = 'bin';
|
|
462
|
+
if (flow.defaultImportType) {
|
|
463
|
+
defaultImportType = flow.defaultImportType;
|
|
464
|
+
} else if (flow.importType) {
|
|
465
|
+
defaultImportType = flow.importType;
|
|
466
|
+
} else if (
|
|
467
|
+
typeof contentTypePrefix === 'string' &&
|
|
468
|
+
contentTypePrefix.startsWith('video/')
|
|
469
|
+
) {
|
|
470
|
+
defaultImportType = 'mp4';
|
|
471
|
+
} else if (
|
|
472
|
+
typeof contentTypePrefix === 'string' &&
|
|
473
|
+
contentTypePrefix.startsWith('image/')
|
|
474
|
+
) {
|
|
475
|
+
defaultImportType = 'jpg';
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
let isRbac = false;
|
|
479
|
+
if (typeof flow.isRbac === 'boolean') {
|
|
480
|
+
isRbac = flow.isRbac;
|
|
481
|
+
} else if (flowHasRbac(flow, objects)) {
|
|
482
|
+
isRbac = true;
|
|
483
|
+
} else if (parentObjectType && parentServiceTag) {
|
|
484
|
+
isRbac = true;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
let rbacServiceTag = parentServiceTag;
|
|
488
|
+
if (!rbacServiceTag) {
|
|
489
|
+
rbacServiceTag = flow.objType?.serviceTag || flow.serviceTag || 'Rbac';
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
const flowRelationships = resolveFlowRelationships(flow, {
|
|
493
|
+
objects,
|
|
494
|
+
relationships
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
return {
|
|
498
|
+
action,
|
|
499
|
+
flowTag: flow.flowTag,
|
|
500
|
+
objectType: flow.objType?.objectType,
|
|
501
|
+
functionName,
|
|
502
|
+
nextStepFunctionName,
|
|
503
|
+
isSimplifiedS3,
|
|
504
|
+
bucketName: flow.bucketName,
|
|
505
|
+
s3KeyPrefix,
|
|
506
|
+
maxFileSizeMb,
|
|
507
|
+
expires,
|
|
508
|
+
contentTypePrefix,
|
|
509
|
+
parentObjectType,
|
|
510
|
+
parentServiceTag,
|
|
511
|
+
parentIdKey,
|
|
512
|
+
parentIdKeys,
|
|
513
|
+
defaultImportType,
|
|
514
|
+
isRbac,
|
|
515
|
+
rbacServiceTag,
|
|
516
|
+
flowRelationships
|
|
517
|
+
};
|
|
142
518
|
}
|
|
143
519
|
|
|
144
|
-
function _s3HandlerData({
|
|
145
|
-
|
|
146
|
-
|
|
520
|
+
function _s3HandlerData({
|
|
521
|
+
action,
|
|
522
|
+
flow,
|
|
523
|
+
functionName,
|
|
524
|
+
mainFileName,
|
|
525
|
+
handler,
|
|
526
|
+
isSimplifiedS3
|
|
527
|
+
}) {
|
|
528
|
+
const isStartOrCreate =
|
|
529
|
+
action === 'CreateObject' ||
|
|
530
|
+
(typeof action === 'string' && action.toLowerCase() === 'start');
|
|
531
|
+
if (isStartOrCreate) {
|
|
532
|
+
return {
|
|
533
|
+
functionName,
|
|
534
|
+
mainFileName,
|
|
535
|
+
handlerType: handler,
|
|
536
|
+
route: flow.flowTag,
|
|
537
|
+
isSimplifiedS3
|
|
538
|
+
};
|
|
147
539
|
}
|
|
148
540
|
if (action === 'ProcessAfterUpload') {
|
|
149
541
|
let bucketName = '';
|
|
@@ -154,8 +546,9 @@ function _s3HandlerData({ action, flow, functionName, mainFileName, handler }) {
|
|
|
154
546
|
flowTag: flow.flowTag,
|
|
155
547
|
functionName,
|
|
156
548
|
mainFileName,
|
|
157
|
-
s3Bucket: bucketName
|
|
549
|
+
s3Bucket: bucketName,
|
|
550
|
+
isSimplifiedS3
|
|
158
551
|
};
|
|
159
552
|
}
|
|
160
|
-
return { functionName, handlerType: handler };
|
|
553
|
+
return { functionName, mainFileName, handlerType: handler, isSimplifiedS3 };
|
|
161
554
|
}
|
|
@@ -79,6 +79,9 @@ export function flowExtTopicSteps(flows) {
|
|
|
79
79
|
if (typeof flow?.flowTag !== 'string' || flow.flowTag === '') {
|
|
80
80
|
return [];
|
|
81
81
|
}
|
|
82
|
+
if (Array.isArray(flow.event) && flow.event.includes('s3')) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
82
85
|
const hasTriggerFlowTypes =
|
|
83
86
|
Array.isArray(flow.triggerFlowTypes) && flow.triggerFlowTypes.length > 0;
|
|
84
87
|
if (flow.statusType === 'triggerCache' && !hasTriggerFlowTypes) {
|
|
@@ -341,3 +344,131 @@ function normalizeBelongTo(object) {
|
|
|
341
344
|
if (!belongTo) return [];
|
|
342
345
|
return Array.isArray(belongTo) ? belongTo : [belongTo];
|
|
343
346
|
}
|
|
347
|
+
|
|
348
|
+
export const LEGACY_S3_PARTS = [
|
|
349
|
+
{
|
|
350
|
+
action: 'CreateObject',
|
|
351
|
+
handler: 'HdrWbs',
|
|
352
|
+
type: 'wbs',
|
|
353
|
+
mainTemplate: 'CreateObject_Main.ejs',
|
|
354
|
+
handlerTemplate: 'CreateObject_HdrWbs.ejs'
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
action: 'ReservedLimit',
|
|
358
|
+
handler: 'HdrSqs',
|
|
359
|
+
type: 'sqs',
|
|
360
|
+
mainTemplate: 'ReservedLimit_Main.ejs',
|
|
361
|
+
handlerTemplate: 'ReservedLimit_HdrSqs.ejs'
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
action: 'CreatePreSignUrl',
|
|
365
|
+
handler: 'HdrSqs',
|
|
366
|
+
type: 'sqs',
|
|
367
|
+
mainTemplate: 'CreatePreSignUrl_Main.ejs',
|
|
368
|
+
handlerTemplate: 'CreatePreSignUrl_HdrSqs.ejs'
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
action: 'ProcessAfterUpload',
|
|
372
|
+
handler: 'HdrS3',
|
|
373
|
+
type: 's3',
|
|
374
|
+
mainTemplate: 'ProcessS3File_Main.ejs',
|
|
375
|
+
handlerTemplate: 'FlowHandler_HdrS3.ejs'
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
action: 'ConfirmAfterUpload',
|
|
379
|
+
handler: 'HdrSqs',
|
|
380
|
+
type: 'sqs',
|
|
381
|
+
mainTemplate: 'ConfirmReserved_Main.ejs',
|
|
382
|
+
handlerTemplate: 'ConfirmReserved_HdrSqs.ejs'
|
|
383
|
+
}
|
|
384
|
+
];
|
|
385
|
+
|
|
386
|
+
export function resolveS3Parts(flow) {
|
|
387
|
+
if (!Array.isArray(flow?.flowSteps) || flow.flowSteps.length === 0) {
|
|
388
|
+
return LEGACY_S3_PARTS;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const stepNames = flow.flowSteps.map((s) => s.stepName);
|
|
392
|
+
if (
|
|
393
|
+
stepNames.includes('CreateObject') &&
|
|
394
|
+
stepNames.includes('ReservedLimit') &&
|
|
395
|
+
stepNames.includes('ConfirmAfterUpload')
|
|
396
|
+
) {
|
|
397
|
+
return LEGACY_S3_PARTS;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const hasS3Step = flow.flowSteps.some(
|
|
401
|
+
(step) =>
|
|
402
|
+
(Array.isArray(step.event) && step.event.includes('s3')) ||
|
|
403
|
+
(typeof step.stepName === 'string' &&
|
|
404
|
+
step.stepName.toLowerCase().includes('afterupload'))
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
if (!hasS3Step) {
|
|
408
|
+
return LEGACY_S3_PARTS;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const isDeferredNodeFlow =
|
|
412
|
+
!stepNames.includes('CreatePreSignUrl') &&
|
|
413
|
+
(stepNames.includes('ConfirmComplete') ||
|
|
414
|
+
stepNames.includes('ConfirmAfterUpload') ||
|
|
415
|
+
stepNames.length <= 3);
|
|
416
|
+
|
|
417
|
+
return flow.flowSteps.map((step) => {
|
|
418
|
+
const action = upperFirst(step.stepName);
|
|
419
|
+
const eventType = Array.isArray(step.event) ? step.event[0] : 'sqs';
|
|
420
|
+
|
|
421
|
+
if (eventType === 'wbs' || action === 'Start' || action === 'CreateObject') {
|
|
422
|
+
let mainTemplate = 'CreateObject_Main.ejs';
|
|
423
|
+
if (isDeferredNodeFlow) {
|
|
424
|
+
mainTemplate = 'Start_Main.ejs';
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
action,
|
|
428
|
+
handler: 'HdrWbs',
|
|
429
|
+
type: 'wbs',
|
|
430
|
+
mainTemplate,
|
|
431
|
+
handlerTemplate: 'CreateObject_HdrWbs.ejs'
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
if (eventType === 's3' || action === 'ProcessAfterUpload') {
|
|
436
|
+
return {
|
|
437
|
+
action,
|
|
438
|
+
handler: 'HdrS3',
|
|
439
|
+
type: 's3',
|
|
440
|
+
mainTemplate: 'ProcessS3File_Main.ejs',
|
|
441
|
+
handlerTemplate: 'FlowHandler_HdrS3.ejs'
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if (action === 'ConfirmComplete') {
|
|
446
|
+
return {
|
|
447
|
+
action,
|
|
448
|
+
handler: 'HdrSqs',
|
|
449
|
+
type: 'sqs',
|
|
450
|
+
mainTemplate: 'ConfirmComplete_Main.ejs',
|
|
451
|
+
handlerTemplate: 'ConfirmComplete_HdrSqs.ejs'
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (action === 'ConfirmAfterUpload') {
|
|
456
|
+
return {
|
|
457
|
+
action,
|
|
458
|
+
handler: 'HdrSqs',
|
|
459
|
+
type: 'sqs',
|
|
460
|
+
mainTemplate: 'ConfirmAfterUpload_Main.ejs',
|
|
461
|
+
handlerTemplate: 'ConfirmAfterUpload_HdrSqs.ejs'
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
return {
|
|
466
|
+
action,
|
|
467
|
+
handler: 'HdrSqs',
|
|
468
|
+
type: 'sqs',
|
|
469
|
+
mainTemplate: 'CreatePreSignUrl_Main.ejs',
|
|
470
|
+
handlerTemplate: 'CreatePreSignUrl_HdrSqs.ejs'
|
|
471
|
+
};
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
|