@izara_project/izara-core-generate-service-code 1.0.68 → 1.0.69
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/scripts/format-ejs.js +1 -2
- package/src/compile/compileProject.js +26 -10
- package/src/compile/loadSchemas.js +47 -23
- package/src/emit/crud/emitCrudApplicationArtifacts.js +188 -41
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +34 -17
- package/src/emit/crud/generateCrudApplicationArtifacts.js +14 -6
- package/src/emit/crud/generateDynamicCrudFlowSchemas.js +4 -1
- package/src/emit/crud/templates/GetEndpoint_Main.ejs +1 -1
- package/src/emit/custom/customFlows.js +23 -13
- package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +515 -113
- package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +28 -8
- package/src/emit/custom/templates/s3/FlowHandler_HdrS3.ejs +2 -2
- package/src/emit/custom/templates/s3/ReservedLimit_HdrSqs.ejs +1 -1
- package/src/emit/function/functionYamlArtifact.js +270 -97
- package/src/emit/function/templates/ApiFunction_Yaml.ejs +7 -0
- package/src/emit/function/templates/EventBridgeFunction_Yaml.ejs +6 -0
- package/src/emit/function/templates/InvFunction_Yaml.ejs +5 -0
- package/src/emit/function/templates/S3Function_Yaml.ejs +16 -0
- package/src/emit/function/templates/SqsFunction_Yaml.ejs +10 -0
- package/src/emit/function/templates/WbsFunction_Yaml.ejs +10 -0
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +28 -30
- package/src/emit/rbac/emitRbacApplicationArtifacts.js +6 -6
- package/src/emit/rbac/generateCreateTargetRoleHandler.js +6 -4
- package/src/emit/rbac/generateDynamicRbacFlowSchemas.js +8 -2
- package/src/emit/rbac/rbacFlowTag.js +3 -1
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +1 -1
- package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +26 -10
- package/src/emit/relationship/emitRelationshipApplicationArtifacts.js +179 -37
- package/src/emit/relationship/generateDynamicRelationshipFlowSchemas.js +8 -2
- package/src/emit/relationship/generateRelationshipApplicationArtifacts.js +15 -6
- package/src/emit/resource/emitResourceArtifacts.js +187 -114
- package/src/emit/resource/generateResourceArtifacts.js +15 -6
- package/src/emit/resource/templates/DynamoDBTable_Yaml.ejs +18 -18
- package/src/emit/resource/templates/FlowOut_Yaml.ejs +5 -5
- package/src/emit/resource/templates/GeneratedLambdaRoleServiceConfig.ejs +10 -9
- package/src/emit/resource/templates/ResourceBeforeLogicalYaml.ejs +44 -44
- package/src/emit/resource/templates/ResourceSqsYaml.ejs +36 -36
- package/src/emit/resource/templates/ResourceYaml.ejs +48 -48
- package/src/emit/resource/templates/S3Subscription_Yaml.ejs +7 -0
- package/src/emit/resource/templates/SharedResource_Yaml.ejs +11 -11
- package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +105 -105
- package/src/emit/resource/templates/WebSocketSubscription_Yaml.ejs +7 -0
- package/src/emit/system/emitSystemWebSocketArtifacts.js +61 -165
- package/src/emit/system/templates/WebSocketComplete_HdrSqs.ejs +32 -0
- package/src/emit/system/templates/WebSocketComplete_Main.ejs +46 -0
- package/src/emit/system/templates/WebSocketComplete_Yaml.ejs +19 -0
- package/src/emit/system/templates/WebSocketConnect.ejs +25 -0
- package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +11 -0
- package/src/generate.js +136 -33
- package/src/generateIntTest.js +76 -28
- package/src/generateResourceIntTest.js +35 -12
- package/src/generateResources/IntTest/generateResources/generateResources.js +5 -2
- package/src/generateResources/IntTest/generateResources/templateResources.ejs +18 -30
- package/src/generateResources/IntTest/generateTests/events/events.js +1 -1
- package/src/generateResources/IntTest/generateTests/events/templateEvents.ejs +13 -10
- package/src/generateResources/IntTest/generateTests/generateTemplate.js +2 -2
- package/src/generateResources/IntTest/generateTests/pathIntTest/pathIntTest.js +2 -1
- package/src/generateResources/IntTest/generateTests/pathIntTest/template.ejs +1 -3
- package/src/generateResources/IntTest/generateTests/tests/templateTests.ejs +1 -1
- package/src/generateResources/IntTest/generateTests/tests/tests.js +7 -3
- package/src/generateResources/IntTest/libs/{libs.js → IntTestGenerateLib.js} +34 -23
- package/src/generateResources/IntTest/upload/uploadIntTest.js +33 -19
- package/src/intTestGeneratorShared.js +15 -10
- package/src/output/commitArtifacts.js +99 -39
- package/src/output/mergeHooks.js +24 -10
- package/src/output/validateArtifacts.js +37 -27
- package/src/plan/buildGenerationPlan.js +24 -13
- package/test/core.test.js +116 -49
- package/test/createTargetRoleHandler.test.js +1 -1
- package/test/crudApplicationArtifacts.test.js +128 -23
- package/test/customFlowApplicationArtifacts.test.js +353 -71
- package/test/dynamicCrudFlowSchemas.test.js +74 -26
- package/test/dynamicRbacFlowSchemas.test.js +61 -14
- package/test/dynamicRelationshipFlowSchemas.test.js +65 -18
- package/test/functionYamlArtifact.test.js +67 -10
- package/test/intTestApi.test.js +9 -10
- package/test/publicApi.test.js +176 -34
- package/test/relationshipApplicationArtifacts.test.js +90 -19
- package/test/resourceArtifacts.test.js +172 -32
- package/src/emit/relationship/dynamicRelationshipFlowSchemaTemplate.js +0 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@izara_project/izara-core-generate-service-code",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.69",
|
|
4
4
|
"description": "Code for locally generating per service files",
|
|
5
5
|
"homepage": "https://bitbucket.org/izara-core-support-services/izara-core-support-services-generate-service-code#readme",
|
|
6
6
|
"repository": {
|
package/scripts/format-ejs.js
CHANGED
|
@@ -34,8 +34,7 @@ export async function formatEjsFiles(targetDir = 'src/emit') {
|
|
|
34
34
|
const id = placeholders.length;
|
|
35
35
|
const isExpr = match.startsWith('<%=') || match.startsWith('<%-');
|
|
36
36
|
const isConditionalComma =
|
|
37
|
-
match.includes('?') &&
|
|
38
|
-
(match.includes("','") || match.includes('","'));
|
|
37
|
+
match.includes('?') && (match.includes("','") || match.includes('","'));
|
|
39
38
|
|
|
40
39
|
let replacement;
|
|
41
40
|
if (isYaml) {
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
+
import Logger from '@izara_project/izara-core-library-logger';
|
|
1
2
|
import { join, resolve } from 'node:path';
|
|
2
3
|
import { readFileSync, existsSync } from 'node:fs';
|
|
3
4
|
import { parse as parseYaml } from 'yaml';
|
|
4
5
|
|
|
5
6
|
export function compileProject(request = {}) {
|
|
6
|
-
if (!
|
|
7
|
-
throw new TypeError(
|
|
7
|
+
if (!_isNonEmptyString(request.rootPath)) {
|
|
8
|
+
throw new TypeError(
|
|
9
|
+
'GenerationRequest.rootPath must be a non-empty string'
|
|
10
|
+
);
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
const rootPath = resolve(request.rootPath);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
let outputPath = rootPath;
|
|
15
|
+
if (request.outputPath) {
|
|
16
|
+
outputPath = resolve(request.outputPath);
|
|
17
|
+
}
|
|
18
|
+
let configPath = join(rootPath, 'config', 'serverless.config.yml');
|
|
19
|
+
if (request.configPath) {
|
|
20
|
+
configPath = resolve(request.configPath);
|
|
21
|
+
}
|
|
15
22
|
|
|
16
23
|
let serviceTag = request.serviceTag;
|
|
17
24
|
if (!serviceTag && existsSync(configPath)) {
|
|
@@ -19,23 +26,32 @@ export function compileProject(request = {}) {
|
|
|
19
26
|
const configContent = readFileSync(configPath, 'utf8');
|
|
20
27
|
const parsedConfig = parseYaml(configContent);
|
|
21
28
|
if (parsedConfig && parsedConfig.main_config) {
|
|
22
|
-
|
|
29
|
+
if (parsedConfig.main_config.iz_serviceTag) {
|
|
30
|
+
serviceTag = parsedConfig.main_config.iz_serviceTag;
|
|
31
|
+
} else if (parsedConfig.main_config.iz_serviceName) {
|
|
32
|
+
serviceTag = parsedConfig.main_config.iz_serviceName;
|
|
33
|
+
}
|
|
23
34
|
}
|
|
24
35
|
} catch (err) {
|
|
25
|
-
|
|
36
|
+
Logger?.debug?.('Could not read serverless.config.yml', err);
|
|
26
37
|
}
|
|
27
38
|
}
|
|
28
39
|
|
|
40
|
+
let schemaTemplateConfig = [];
|
|
41
|
+
if (request.schemaTemplateConfig) {
|
|
42
|
+
schemaTemplateConfig = request.schemaTemplateConfig;
|
|
43
|
+
}
|
|
44
|
+
|
|
29
45
|
return Object.freeze({
|
|
30
46
|
rootPath,
|
|
31
47
|
outputPath,
|
|
32
48
|
configPath,
|
|
33
49
|
schemaRoot: join(rootPath, 'app', 'src', 'schemas'),
|
|
34
50
|
serviceTag,
|
|
35
|
-
schemaTemplateConfig
|
|
51
|
+
schemaTemplateConfig
|
|
36
52
|
});
|
|
37
53
|
}
|
|
38
54
|
|
|
39
|
-
function
|
|
55
|
+
function _isNonEmptyString(value) {
|
|
40
56
|
return typeof value === 'string' && value.trim() !== '';
|
|
41
57
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { readdir, stat } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
getObjectSchema,
|
|
6
|
+
utils
|
|
7
|
+
} from '@izara_project/izara-core-library-service-schemas';
|
|
5
8
|
import Logger from '@izara_project/izara-core-library-logger';
|
|
6
9
|
|
|
7
10
|
export async function loadLocalSchemaDirectory(project, directoryName) {
|
|
@@ -16,35 +19,61 @@ export async function loadLocalSchemaDirectory(project, directoryName) {
|
|
|
16
19
|
throw error;
|
|
17
20
|
}
|
|
18
21
|
|
|
22
|
+
const validEntries = entries.filter(
|
|
23
|
+
(entry) => entry.isFile() && entry.name.endsWith('.js')
|
|
24
|
+
);
|
|
25
|
+
validEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
26
|
+
|
|
19
27
|
const schemas = [];
|
|
20
|
-
for (const entry of
|
|
28
|
+
for (const entry of validEntries) {
|
|
21
29
|
const filePath = join(directoryPath, entry.name);
|
|
22
30
|
const details = await stat(filePath);
|
|
23
|
-
const module = await import(
|
|
31
|
+
const module = await import(
|
|
32
|
+
`${pathToFileURL(filePath).href}?schemaVersion=${details.mtimeMs}-${details.size}`
|
|
33
|
+
);
|
|
24
34
|
if (!module.default || typeof module.default !== 'object') {
|
|
25
|
-
throw new TypeError(
|
|
35
|
+
throw new TypeError(
|
|
36
|
+
`Schema module must default-export an object or array: ${filePath}`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
let loadedSchemas = [module.default];
|
|
40
|
+
if (Array.isArray(module.default)) {
|
|
41
|
+
loadedSchemas = module.default;
|
|
26
42
|
}
|
|
27
|
-
const loadedSchemas = Array.isArray(module.default) ? module.default : [module.default];
|
|
28
43
|
|
|
29
|
-
if (process.env.NODE_ENV !== 'test') {
|
|
44
|
+
if (process.env.NODE_ENV && process.env.NODE_ENV !== 'test') {
|
|
30
45
|
for (const schema of loadedSchemas) {
|
|
31
46
|
let status = true;
|
|
32
47
|
let errors = [];
|
|
33
|
-
|
|
48
|
+
|
|
34
49
|
if (directoryName === 'ObjectSchemas') {
|
|
35
|
-
[status, errors] = utils.validateObjectSchema(
|
|
50
|
+
[status, errors] = utils.validateObjectSchema(
|
|
51
|
+
{ logger: Logger },
|
|
52
|
+
schema
|
|
53
|
+
);
|
|
36
54
|
} else if (directoryName === 'RelationshipSchemas') {
|
|
37
55
|
if (entry.name.toLowerCase() === 'refobjectrelationships.js') {
|
|
38
|
-
[status, errors] = utils.validateRefRelationshipSchema(
|
|
56
|
+
[status, errors] = utils.validateRefRelationshipSchema(
|
|
57
|
+
{ logger: Logger },
|
|
58
|
+
schema
|
|
59
|
+
);
|
|
39
60
|
} else {
|
|
40
|
-
[status, errors] = utils.validateRelationshipSchema(
|
|
61
|
+
[status, errors] = utils.validateRelationshipSchema(
|
|
62
|
+
{ logger: Logger },
|
|
63
|
+
schema
|
|
64
|
+
);
|
|
41
65
|
}
|
|
42
66
|
} else if (directoryName === 'FlowSchemas') {
|
|
43
|
-
[status, errors] = utils.validateBasicFlowSchema(
|
|
67
|
+
[status, errors] = utils.validateBasicFlowSchema(
|
|
68
|
+
{ logger: Logger },
|
|
69
|
+
schema
|
|
70
|
+
);
|
|
44
71
|
}
|
|
45
72
|
|
|
46
73
|
if (!status) {
|
|
47
|
-
throw new Error(
|
|
74
|
+
throw new Error(
|
|
75
|
+
`Schema validation failed for ${entry.name}:\n${errors.join('\n')}`
|
|
76
|
+
);
|
|
48
77
|
}
|
|
49
78
|
}
|
|
50
79
|
}
|
|
@@ -68,10 +97,7 @@ export async function loadLocalSchemaDirectory(project, directoryName) {
|
|
|
68
97
|
* @returns {Promise<Object[]>} The same array with extended storageResources
|
|
69
98
|
* merged in.
|
|
70
99
|
*/
|
|
71
|
-
export async function resolveExtendedObjectSchemas(
|
|
72
|
-
objectSchemas,
|
|
73
|
-
bucketName
|
|
74
|
-
) {
|
|
100
|
+
export async function resolveExtendedObjectSchemas(objectSchemas, bucketName) {
|
|
75
101
|
if (!Array.isArray(objectSchemas)) {
|
|
76
102
|
throw new TypeError('objectSchemas must be an array');
|
|
77
103
|
}
|
|
@@ -83,9 +109,8 @@ export async function resolveExtendedObjectSchemas(
|
|
|
83
109
|
}
|
|
84
110
|
try {
|
|
85
111
|
// Track which storageResource keys existed in the child before merge
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
);
|
|
112
|
+
const initialResources = schema.storageResources || {};
|
|
113
|
+
const childStorageResourceKeys = new Set(Object.keys(initialResources));
|
|
89
114
|
const parentServiceTag = schema.extendObjType.serviceTag;
|
|
90
115
|
|
|
91
116
|
const mergedSchema = await getObjectSchema.mergeExtendObjSchema(
|
|
@@ -100,9 +125,8 @@ export async function resolveExtendedObjectSchemas(
|
|
|
100
125
|
// emitResourceArtifacts can add cross-service ARNs to IAM roles.
|
|
101
126
|
const externalDynamoResources = [];
|
|
102
127
|
const ownStorageResources = {};
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
)) {
|
|
128
|
+
const mergedStorageResources = mergedSchema.storageResources || {};
|
|
129
|
+
for (const [key, resource] of Object.entries(mergedStorageResources)) {
|
|
106
130
|
if (
|
|
107
131
|
resource?.storageType === 'dynamoDB' &&
|
|
108
132
|
!childStorageResourceKeys.has(key)
|
|
@@ -125,7 +149,7 @@ export async function resolveExtendedObjectSchemas(
|
|
|
125
149
|
} catch (error) {
|
|
126
150
|
Logger.error(
|
|
127
151
|
`resolveExtendedObjectSchemas: failed to merge extendObjType` +
|
|
128
|
-
|
|
152
|
+
` for objectType=${schema.objectType}`,
|
|
129
153
|
{ error }
|
|
130
154
|
);
|
|
131
155
|
throw error;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ejsLib from 'ejs';
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
3
|
|
|
4
4
|
import {
|
|
@@ -12,30 +12,42 @@ const ACTIONS = ['Create', 'Update', 'Delete', 'Get'];
|
|
|
12
12
|
const YAML_PATH = 'app/sls_yaml/generatedCode/source/flow-objects.yml';
|
|
13
13
|
const TEMPLATE_URL = new URL('./templates/', import.meta.url);
|
|
14
14
|
|
|
15
|
-
export async function emitCrudApplicationArtifacts({
|
|
15
|
+
export async function emitCrudApplicationArtifacts({
|
|
16
|
+
objects,
|
|
17
|
+
flows = [],
|
|
18
|
+
serviceTag
|
|
19
|
+
}) {
|
|
16
20
|
if (!Array.isArray(objects) || !Array.isArray(flows)) {
|
|
17
21
|
throw new TypeError('objects and flows must be arrays');
|
|
18
22
|
}
|
|
19
23
|
if (!objects.some(isCrudObject)) return [];
|
|
20
24
|
|
|
21
|
-
const handlers = await Promise.all(
|
|
25
|
+
const handlers = await Promise.all(
|
|
26
|
+
ACTIONS.map((action) => emitAction(action, objects, flows, serviceTag))
|
|
27
|
+
);
|
|
22
28
|
return [
|
|
23
|
-
...handlers.flatMap(handler => handler.artifacts),
|
|
29
|
+
...handlers.flatMap((handler) => handler.artifacts),
|
|
24
30
|
{
|
|
25
31
|
path: YAML_PATH,
|
|
26
|
-
content: handlers
|
|
32
|
+
content: handlers
|
|
33
|
+
.flatMap((handler) => handler.functions)
|
|
34
|
+
.map(renderFunction)
|
|
35
|
+
.join('\n')
|
|
27
36
|
}
|
|
28
37
|
];
|
|
29
38
|
}
|
|
30
39
|
|
|
31
40
|
export function crudApplicationManagedPaths() {
|
|
32
41
|
return [
|
|
33
|
-
...ACTIONS.flatMap(action => {
|
|
42
|
+
...ACTIONS.flatMap((action) => {
|
|
34
43
|
const source = `app/src/generatedCode/FlowObjects/${action}/source`;
|
|
35
44
|
const paths = [`${source}/${action}_Main.js`];
|
|
36
45
|
if (action === 'Get') {
|
|
37
46
|
paths.push(`${source}/Get_HdrInv.js`, `${source}/Get_HdrApi.js`);
|
|
38
|
-
paths.push(
|
|
47
|
+
paths.push(
|
|
48
|
+
`${source}/GetRange_Main.js`,
|
|
49
|
+
`${source}/GetRange_HdrApi.js`
|
|
50
|
+
);
|
|
39
51
|
} else {
|
|
40
52
|
paths.push(
|
|
41
53
|
`${source}/${action}_HdrSqs.js`,
|
|
@@ -44,7 +56,10 @@ export function crudApplicationManagedPaths() {
|
|
|
44
56
|
`${source}/${action}BeforeLogical_Main.js`,
|
|
45
57
|
`${source}/${action}BeforeLogical_HdrSqs.js`
|
|
46
58
|
);
|
|
47
|
-
paths.push(
|
|
59
|
+
paths.push(
|
|
60
|
+
`${source}/${action}Complete_Main.js`,
|
|
61
|
+
`${source}/${action}Complete_HdrSqs.js`
|
|
62
|
+
);
|
|
48
63
|
}
|
|
49
64
|
return paths;
|
|
50
65
|
}),
|
|
@@ -56,8 +71,12 @@ async function emitAction(action, objects, flows, serviceTag) {
|
|
|
56
71
|
const source = `app/src/generatedCode/FlowObjects/${action}/source`;
|
|
57
72
|
const handlerRoot = `src/generatedCode/FlowObjects/${action}/source`;
|
|
58
73
|
const generateCode = flows
|
|
59
|
-
.filter(
|
|
60
|
-
|
|
74
|
+
.filter(
|
|
75
|
+
(flow) =>
|
|
76
|
+
flow?.generatedCodeConfig?.generatedCodeTag?.toLowerCase() ===
|
|
77
|
+
action.toLowerCase()
|
|
78
|
+
)
|
|
79
|
+
.map((flow) => ({ ...flow.generatedCodeConfig, flowTag: flow.flowTag }));
|
|
61
80
|
const mainFileName = `${action}_Main`;
|
|
62
81
|
const shared = {
|
|
63
82
|
flowTag: action,
|
|
@@ -68,22 +87,66 @@ async function emitAction(action, objects, flows, serviceTag) {
|
|
|
68
87
|
flowStepName: '',
|
|
69
88
|
startConfig: null
|
|
70
89
|
};
|
|
71
|
-
const artifacts = [
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
90
|
+
const artifacts = [
|
|
91
|
+
{
|
|
92
|
+
path: `${source}/${mainFileName}.js`,
|
|
93
|
+
content: await render(`${action}Endpoint_Main.ejs`, shared)
|
|
94
|
+
}
|
|
95
|
+
];
|
|
75
96
|
|
|
97
|
+
let targetServiceTag = '${self:custom.iz_serviceName}';
|
|
98
|
+
if (serviceTag) {
|
|
99
|
+
targetServiceTag = serviceTag;
|
|
100
|
+
}
|
|
76
101
|
if (action === 'Get') {
|
|
77
102
|
artifacts.push(
|
|
78
|
-
{
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
103
|
+
{
|
|
104
|
+
path: `${source}/Get_HdrInv.js`,
|
|
105
|
+
content: await render('FlowHandler_HdrInv.ejs', {
|
|
106
|
+
...shared,
|
|
107
|
+
mainFileName,
|
|
108
|
+
functionName: 'Get',
|
|
109
|
+
queueName: 'GetHdrInv'
|
|
110
|
+
})
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
path: `${source}/Get_HdrApi.js`,
|
|
114
|
+
content: await render('FlowHandler_HdrApi.ejs', {
|
|
115
|
+
...shared,
|
|
116
|
+
mainFileName,
|
|
117
|
+
functionName: 'Get',
|
|
118
|
+
queueName: 'GetHdrApi'
|
|
119
|
+
})
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
path: `${source}/GetRange_Main.js`,
|
|
123
|
+
content: await render('GetRangeEndpoint_Main.ejs', {
|
|
124
|
+
...shared,
|
|
125
|
+
mainFileName: 'GetRange_Main',
|
|
126
|
+
functionName: 'GetRange'
|
|
127
|
+
})
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
path: `${source}/GetRange_HdrApi.js`,
|
|
131
|
+
content: await render('FlowHandler_HdrApi.ejs', {
|
|
132
|
+
...shared,
|
|
133
|
+
mainFileName: 'GetRange_Main',
|
|
134
|
+
functionName: 'GetRange',
|
|
135
|
+
queueName: 'GetRangeHdrApi'
|
|
136
|
+
})
|
|
137
|
+
}
|
|
82
138
|
);
|
|
83
139
|
return {
|
|
84
140
|
artifacts,
|
|
85
141
|
functions: [
|
|
86
|
-
{
|
|
142
|
+
{
|
|
143
|
+
type: 'inv',
|
|
144
|
+
functionName: 'GetHdrInv',
|
|
145
|
+
handlerPath: `${handlerRoot}/Get_HdrInv.main`,
|
|
146
|
+
roleName: 'FlowObjectsRole',
|
|
147
|
+
flowTag: action,
|
|
148
|
+
flowStepName: ''
|
|
149
|
+
},
|
|
87
150
|
{
|
|
88
151
|
type: 'api',
|
|
89
152
|
functionName: 'GetHdrApi',
|
|
@@ -91,8 +154,8 @@ async function emitAction(action, objects, flows, serviceTag) {
|
|
|
91
154
|
roleName: 'FlowObjectsRole',
|
|
92
155
|
flowTag: action,
|
|
93
156
|
flowStepName: '',
|
|
94
|
-
routes: objects.filter(isCrudObject).map(object => ({
|
|
95
|
-
path: `/${
|
|
157
|
+
routes: objects.filter(isCrudObject).map((object) => ({
|
|
158
|
+
path: `/${targetServiceTag}/${object.objectType}/get`,
|
|
96
159
|
upperName: upperFirst(object.objectType)
|
|
97
160
|
}))
|
|
98
161
|
},
|
|
@@ -103,45 +166,129 @@ async function emitAction(action, objects, flows, serviceTag) {
|
|
|
103
166
|
roleName: 'FlowObjectsRole',
|
|
104
167
|
flowTag: 'GetRange',
|
|
105
168
|
flowStepName: '',
|
|
106
|
-
routes: objects
|
|
107
|
-
.filter(
|
|
108
|
-
.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
169
|
+
routes: objects
|
|
170
|
+
.filter(isCrudObject)
|
|
171
|
+
.filter(
|
|
172
|
+
(object) =>
|
|
173
|
+
object.identifiers &&
|
|
174
|
+
object.identifiers.some((i) => i.type === 'sortKey')
|
|
175
|
+
)
|
|
176
|
+
.map((object) => ({
|
|
177
|
+
path: `/${targetServiceTag}/${object.objectType}/getRange`,
|
|
178
|
+
upperName: upperFirst(object.objectType)
|
|
179
|
+
}))
|
|
112
180
|
}
|
|
113
181
|
]
|
|
114
182
|
};
|
|
115
183
|
}
|
|
116
184
|
|
|
117
185
|
artifacts.push(
|
|
118
|
-
{
|
|
119
|
-
|
|
120
|
-
|
|
186
|
+
{
|
|
187
|
+
path: `${source}/${action}_HdrSqs.js`,
|
|
188
|
+
content: await render('FlowHandler_HdrSqs.ejs', {
|
|
189
|
+
...shared,
|
|
190
|
+
mainFileName,
|
|
191
|
+
functionName: action,
|
|
192
|
+
queueName: `${action}HdrSqs`
|
|
193
|
+
})
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
path: `${source}/${action}_WbsMain.js`,
|
|
197
|
+
content: await render('FlowMain_Wbs.ejs', {
|
|
198
|
+
...shared,
|
|
199
|
+
functionName: action
|
|
200
|
+
})
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
path: `${source}/${action}_HdrWbs.js`,
|
|
204
|
+
content: await render('FlowEndpoint_HdrWbs.ejs', {
|
|
205
|
+
...shared,
|
|
206
|
+
mainFileName: `${action}_WbsMain`,
|
|
207
|
+
functionName: action,
|
|
208
|
+
route: action
|
|
209
|
+
})
|
|
210
|
+
}
|
|
121
211
|
);
|
|
122
212
|
const functions = [
|
|
123
|
-
{
|
|
124
|
-
|
|
213
|
+
{
|
|
214
|
+
type: 'wbs',
|
|
215
|
+
functionName: `${action}HdrWbs`,
|
|
216
|
+
handlerPath: `${handlerRoot}/${action}_HdrWbs.main`,
|
|
217
|
+
roleName: 'FlowObjectsRole',
|
|
218
|
+
routeName: action,
|
|
219
|
+
flowTag: action,
|
|
220
|
+
flowStepName: ''
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
type: 'sqs',
|
|
224
|
+
functionName: `${action}HdrSqs`,
|
|
225
|
+
handlerPath: `${handlerRoot}/${action}_HdrSqs.main`,
|
|
226
|
+
roleName: 'FlowObjectsRole',
|
|
227
|
+
queueName: `${action}HdrSqs`,
|
|
228
|
+
flowTag: action,
|
|
229
|
+
flowStepName: ''
|
|
230
|
+
}
|
|
125
231
|
];
|
|
126
232
|
const complete = `${action}Complete`;
|
|
127
233
|
artifacts.push(
|
|
128
|
-
{
|
|
129
|
-
|
|
234
|
+
{
|
|
235
|
+
path: `${source}/${complete}_Main.js`,
|
|
236
|
+
content: await render('FlowEndpointComplete_Main.ejs', { action })
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
path: `${source}/${complete}_HdrSqs.js`,
|
|
240
|
+
content: await render('FlowHandler_HdrSqs.ejs', {
|
|
241
|
+
...shared,
|
|
242
|
+
mainFileName: `${complete}_Main`,
|
|
243
|
+
functionName: complete,
|
|
244
|
+
queueName: `${action}CompleteHdrSqs`
|
|
245
|
+
})
|
|
246
|
+
}
|
|
130
247
|
);
|
|
131
|
-
functions.push({
|
|
132
|
-
|
|
248
|
+
functions.push({
|
|
249
|
+
type: 'sqs',
|
|
250
|
+
functionName: `${action}CompleteHdrSqs`,
|
|
251
|
+
handlerPath: `${handlerRoot}/${complete}_HdrSqs.main`,
|
|
252
|
+
roleName: 'FlowObjectsRole',
|
|
253
|
+
queueName: `${action}CompleteHdrSqs`,
|
|
254
|
+
flowTag: action,
|
|
255
|
+
flowStepName: 'Complete'
|
|
256
|
+
});
|
|
257
|
+
if (generateCode.some((config) => config.codeHookTag === 'beforeLogical')) {
|
|
133
258
|
const beforeMain = `${action}BeforeLogical_Main`;
|
|
134
259
|
artifacts.push(
|
|
135
|
-
{
|
|
136
|
-
|
|
260
|
+
{
|
|
261
|
+
path: `${source}/${beforeMain}.js`,
|
|
262
|
+
content: await render('FlowEndpointBeforeLogical_Main.ejs', shared)
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
path: `${source}/${action}BeforeLogical_HdrSqs.js`,
|
|
266
|
+
content: await render('FlowHandler_HdrSqs.ejs', {
|
|
267
|
+
...shared,
|
|
268
|
+
mainFileName: beforeMain,
|
|
269
|
+
functionName: `${action}BeforeLogicalMain`,
|
|
270
|
+
queueName: `${action}BeforeLogicalHdrSqs`
|
|
271
|
+
})
|
|
272
|
+
}
|
|
137
273
|
);
|
|
138
|
-
functions.push({
|
|
274
|
+
functions.push({
|
|
275
|
+
type: 'sqs',
|
|
276
|
+
functionName: `${action}BeforeLogicalHdrSqs`,
|
|
277
|
+
handlerPath: `${handlerRoot}/${action}BeforeLogical_HdrSqs.main`,
|
|
278
|
+
roleName: 'FlowObjectsRole',
|
|
279
|
+
queueName: `${action}BeforeLogicalHdrSqs`,
|
|
280
|
+
flowTag: action,
|
|
281
|
+
flowStepName: 'BeforeLogical'
|
|
282
|
+
});
|
|
139
283
|
}
|
|
140
284
|
return { artifacts, functions };
|
|
141
285
|
}
|
|
142
286
|
|
|
143
287
|
function isCrudObject(object) {
|
|
144
|
-
return
|
|
288
|
+
return (
|
|
289
|
+
object?.generatedBy === 'userGenerated' ||
|
|
290
|
+
object?.generatedBy === 'systemGenerated'
|
|
291
|
+
);
|
|
145
292
|
}
|
|
146
293
|
|
|
147
294
|
function upperFirst(value) {
|
|
@@ -150,7 +297,7 @@ function upperFirst(value) {
|
|
|
150
297
|
|
|
151
298
|
async function render(templateName, data) {
|
|
152
299
|
const template = await readFile(new URL(templateName, TEMPLATE_URL), 'utf8');
|
|
153
|
-
return
|
|
300
|
+
return ejsLib.render(template, data);
|
|
154
301
|
}
|
|
155
302
|
|
|
156
303
|
function renderFunction(descriptor) {
|
|
@@ -4,19 +4,26 @@ const ACTIONS = ['Create', 'Update', 'Delete', 'Get'];
|
|
|
4
4
|
const MESSAGE_ATTRIBUTES = ['userId', 'correlationId'];
|
|
5
5
|
|
|
6
6
|
export const dynamicCrudFlowSchemaPaths = ACTIONS.map(
|
|
7
|
-
action =>
|
|
7
|
+
(action) =>
|
|
8
|
+
`app/src/schemas/FlowSchemas/generateCode/FlowObjects/${action}.js`
|
|
8
9
|
);
|
|
9
10
|
|
|
10
11
|
export function emitDynamicCrudFlowSchemas({ objects, flows = [] }) {
|
|
11
12
|
if (!Array.isArray(objects) || !Array.isArray(flows)) {
|
|
12
13
|
throw new TypeError('objects and flows must be arrays');
|
|
13
14
|
}
|
|
14
|
-
if (
|
|
15
|
+
if (
|
|
16
|
+
!objects.some(
|
|
17
|
+
(object) =>
|
|
18
|
+
object?.generatedBy === 'userGenerated' ||
|
|
19
|
+
object?.generatedBy === 'systemGenerated'
|
|
20
|
+
)
|
|
21
|
+
) {
|
|
15
22
|
return [];
|
|
16
23
|
}
|
|
17
24
|
|
|
18
25
|
return ACTIONS.map((action, index) => {
|
|
19
|
-
const flow =
|
|
26
|
+
const flow = _createDynamicFlow(action, _hasBeforeLogicalStep(flows, action));
|
|
20
27
|
return {
|
|
21
28
|
path: dynamicCrudFlowSchemaPaths[index],
|
|
22
29
|
content: renderDynamicCrudFlowSchema(action, flow)
|
|
@@ -24,19 +31,21 @@ export function emitDynamicCrudFlowSchemas({ objects, flows = [] }) {
|
|
|
24
31
|
});
|
|
25
32
|
}
|
|
26
33
|
|
|
27
|
-
function
|
|
34
|
+
function _createDynamicFlow(action, hasBeforeLogicalStep) {
|
|
28
35
|
const outputTopic = action !== 'Get';
|
|
29
36
|
const flowSteps = [
|
|
30
37
|
{
|
|
31
38
|
stepName: 'start',
|
|
32
39
|
properties: [],
|
|
33
40
|
messageAttributes: MESSAGE_ATTRIBUTES,
|
|
34
|
-
...(outputTopic
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
...(outputTopic
|
|
42
|
+
? {
|
|
43
|
+
returnValues: {
|
|
44
|
+
properties: [],
|
|
45
|
+
messageAttributes: MESSAGE_ATTRIBUTES
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
: {})
|
|
40
49
|
}
|
|
41
50
|
];
|
|
42
51
|
|
|
@@ -48,6 +57,7 @@ function createDynamicFlow(action, hasBeforeLogicalStep) {
|
|
|
48
57
|
messageAttributes: MESSAGE_ATTRIBUTES
|
|
49
58
|
});
|
|
50
59
|
}
|
|
60
|
+
|
|
51
61
|
if (action !== 'Get') {
|
|
52
62
|
flowSteps.push({
|
|
53
63
|
stepName: 'Complete',
|
|
@@ -57,12 +67,17 @@ function createDynamicFlow(action, hasBeforeLogicalStep) {
|
|
|
57
67
|
});
|
|
58
68
|
}
|
|
59
69
|
|
|
70
|
+
let eventTypes = ['lambdaSyncInv', 'lambdaSyncApi'];
|
|
71
|
+
if (outputTopic) {
|
|
72
|
+
eventTypes = ['ownTopic'];
|
|
73
|
+
}
|
|
74
|
+
|
|
60
75
|
return {
|
|
61
76
|
flowTag: action,
|
|
62
77
|
initiateBy: 'system',
|
|
63
78
|
handleObj: 'one',
|
|
64
79
|
statusType: 'none',
|
|
65
|
-
event:
|
|
80
|
+
event: eventTypes,
|
|
66
81
|
outputTopic,
|
|
67
82
|
stepMessageAttributes: {
|
|
68
83
|
userId: { propertyName: 'x-correlation-base-user-id', type: 'string' },
|
|
@@ -72,12 +87,14 @@ function createDynamicFlow(action, hasBeforeLogicalStep) {
|
|
|
72
87
|
};
|
|
73
88
|
}
|
|
74
89
|
|
|
75
|
-
function
|
|
76
|
-
return flows.some(flow => {
|
|
90
|
+
function _hasBeforeLogicalStep(flows, action) {
|
|
91
|
+
return flows.some((flow) => {
|
|
77
92
|
const config = flow?.generatedCodeConfig;
|
|
78
|
-
return
|
|
79
|
-
|
|
80
|
-
&&
|
|
81
|
-
|
|
93
|
+
return (
|
|
94
|
+
config?.generatedCodeTag === action.toLowerCase() &&
|
|
95
|
+
config.codeHookTag === 'beforeLogical' &&
|
|
96
|
+
Array.isArray(flow.event) &&
|
|
97
|
+
flow.event.includes(config.invocationType)
|
|
98
|
+
);
|
|
82
99
|
});
|
|
83
100
|
}
|