@izara_project/izara-core-generate-service-code 1.0.87 → 1.0.88
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/loadSchemas.js +45 -10
- package/src/emit/crud/crudActionPlan.js +46 -5
- package/src/emit/crud/emitCrudApplicationArtifacts.js +63 -3
- package/src/emit/crud/templates/CreateAfterHookCallback_Main.ejs +121 -0
- package/src/emit/crud/templates/CreateBeforeHookCallback_Main.ejs +108 -0
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +126 -332
- package/src/emit/crud/templates/CreateLogicalLib.ejs +120 -22
- package/src/emit/crud/templates/CreateNodeCallback_Main.ejs +80 -0
- package/src/emit/crud/templates/DeleteBeforeHookCallback_Main.ejs +99 -0
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +141 -179
- package/src/emit/crud/templates/DeleteLogicalLib.ejs +132 -26
- package/src/emit/crud/templates/UpdateBeforeHookCallback_Main.ejs +112 -0
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +154 -185
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +2 -2
- package/src/emit/custom/customFlows.js +3 -1
- package/src/emit/resource/emitResourceArtifacts.js +110 -57
- package/test/crudApplicationArtifacts.test.js +531 -0
- package/test/resourceArtifacts.test.js +200 -12
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.88",
|
|
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": {
|
|
@@ -22,11 +22,21 @@ const VALID_INITIATE_BY_ENUM = [
|
|
|
22
22
|
'systemNoUser'
|
|
23
23
|
];
|
|
24
24
|
|
|
25
|
+
const VALID_CODE_HOOK_TAG_ENUM = ['before', 'after'];
|
|
26
|
+
|
|
25
27
|
if (basicValidatorSchema?.basicFlowSchema?.properties?.initiateBy) {
|
|
26
28
|
basicValidatorSchema.basicFlowSchema.properties.initiateBy.enum =
|
|
27
29
|
VALID_INITIATE_BY_ENUM;
|
|
28
30
|
}
|
|
29
31
|
|
|
32
|
+
if (
|
|
33
|
+
basicValidatorSchema?.basicFlowSchema?.properties?.generatedCodeConfig
|
|
34
|
+
?.properties?.codeHookTag
|
|
35
|
+
) {
|
|
36
|
+
basicValidatorSchema.basicFlowSchema.properties.generatedCodeConfig.properties.codeHookTag.enum =
|
|
37
|
+
VALID_CODE_HOOK_TAG_ENUM;
|
|
38
|
+
}
|
|
39
|
+
|
|
30
40
|
const VALID_GENERATED_BY_ENUM = [
|
|
31
41
|
'user',
|
|
32
42
|
'systemWithUser',
|
|
@@ -113,9 +123,17 @@ export async function loadLocalSchemaDirectory(
|
|
|
113
123
|
if (directoryName === 'FlowSchemas') {
|
|
114
124
|
for (const schema of loadedSchemas) {
|
|
115
125
|
if (Object.prototype.hasOwnProperty.call(schema?.generatedCodeConfig ?? {}, 'codeHookTag')) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
126
|
+
const hookTag = schema.generatedCodeConfig.codeHookTag;
|
|
127
|
+
if (hookTag === 'beforeLogical') {
|
|
128
|
+
throw new Error(
|
|
129
|
+
`Unsupported FlowHook configuration in ${entry.name}: generatedCodeConfig.codeHookTag is no longer supported`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
if (hookTag !== 'before' && hookTag !== 'after') {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`Unsupported FlowHook configuration in ${entry.name}: generatedCodeConfig.codeHookTag '${hookTag}' is invalid. Must be 'before' or 'after'`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
119
137
|
}
|
|
120
138
|
}
|
|
121
139
|
}
|
|
@@ -177,13 +195,30 @@ export async function loadLocalSchemaDirectory(
|
|
|
177
195
|
{ logger },
|
|
178
196
|
schema
|
|
179
197
|
);
|
|
180
|
-
if (!status && Array.isArray(errors)
|
|
181
|
-
|
|
182
|
-
(
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
198
|
+
if (!status && Array.isArray(errors)) {
|
|
199
|
+
if (VALID_INITIATE_BY_ENUM.includes(schema?.initiateBy)) {
|
|
200
|
+
errors = errors.filter(
|
|
201
|
+
(err) =>
|
|
202
|
+
!err.includes('initiateBy') &&
|
|
203
|
+
!err.includes('must be equal to one of the allowed values (enum)') &&
|
|
204
|
+
!(err.includes('should be one of enum') && err.includes(schema?.initiateBy))
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
if (
|
|
208
|
+
VALID_CODE_HOOK_TAG_ENUM.includes(
|
|
209
|
+
schema?.generatedCodeConfig?.codeHookTag
|
|
210
|
+
)
|
|
211
|
+
) {
|
|
212
|
+
errors = errors.filter(
|
|
213
|
+
(err) =>
|
|
214
|
+
!err.includes('codeHookTag') &&
|
|
215
|
+
!err.includes('must be equal to one of the allowed values (enum)') &&
|
|
216
|
+
!(
|
|
217
|
+
err.includes('should be one of enum') &&
|
|
218
|
+
err.includes(schema?.generatedCodeConfig?.codeHookTag)
|
|
219
|
+
)
|
|
220
|
+
);
|
|
221
|
+
}
|
|
187
222
|
if (errors.length === 0) {
|
|
188
223
|
status = true;
|
|
189
224
|
}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
export const CRUD_ACTIONS = ['Create', 'Update', 'Delete', 'Get'];
|
|
2
2
|
|
|
3
|
-
export function
|
|
3
|
+
export function findHooksForAction(flows = [], action) {
|
|
4
|
+
if (!Array.isArray(flows)) return [];
|
|
5
|
+
return flows.filter((f) => {
|
|
6
|
+
const config = f?.generatedCodeConfig;
|
|
7
|
+
if (!config) return false;
|
|
8
|
+
const tag = config.generateCodeTag || config.generatedCodeTag;
|
|
9
|
+
return Boolean(tag && tag.toLowerCase() === action.toLowerCase());
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function createCrudActionPlans(objects = [], flows = []) {
|
|
4
14
|
const hasGraph = hasGraphStorageResource(objects);
|
|
5
15
|
const hasRbac = objects.some(
|
|
6
16
|
(object) => isCrudObject(object) && hasRbacObject(object, objects)
|
|
@@ -12,29 +22,60 @@ export function createCrudActionPlans(objects = []) {
|
|
|
12
22
|
return Object.fromEntries(
|
|
13
23
|
CRUD_ACTIONS.map((action) => [
|
|
14
24
|
action,
|
|
15
|
-
createCrudActionPlan(action, { hasGraph, hasRbac, isBillable })
|
|
25
|
+
createCrudActionPlan(action, { hasGraph, hasRbac, isBillable, flows })
|
|
16
26
|
])
|
|
17
27
|
);
|
|
18
28
|
}
|
|
19
29
|
|
|
20
30
|
export function createCrudActionPlan(
|
|
21
31
|
action,
|
|
22
|
-
{ hasGraph = false, hasRbac = false, isBillable = true } = {}
|
|
32
|
+
{ hasGraph = false, hasRbac = false, isBillable = true, flows = [] } = {}
|
|
23
33
|
) {
|
|
24
34
|
const actionHasRbac = action !== 'Get' && hasRbac;
|
|
25
35
|
const outputTopic = action !== 'Get';
|
|
26
36
|
const hasQuotaReservation = action === 'Create' && hasRbac && isBillable;
|
|
27
37
|
|
|
38
|
+
const actionHooks = findHooksForAction(flows, action);
|
|
39
|
+
const beforeHooks = actionHooks.filter(
|
|
40
|
+
(h) => h?.generatedCodeConfig?.codeHookTag === 'before'
|
|
41
|
+
);
|
|
42
|
+
const afterHooks = actionHooks.filter(
|
|
43
|
+
(h) => h?.generatedCodeConfig?.codeHookTag === 'after'
|
|
44
|
+
);
|
|
45
|
+
const hasBeforeHookSync = beforeHooks.some(
|
|
46
|
+
(h) => h?.generatedCodeConfig?.invocationType === 'lambdaSyncInv'
|
|
47
|
+
);
|
|
48
|
+
const hasBeforeHookAsync = beforeHooks.some(
|
|
49
|
+
(h) => h?.generatedCodeConfig?.invocationType === 'ownTopic'
|
|
50
|
+
);
|
|
51
|
+
const hasBeforeHookCallback = outputTopic && hasBeforeHookAsync;
|
|
52
|
+
|
|
53
|
+
const hasAfterHookSync = afterHooks.some(
|
|
54
|
+
(h) => h?.generatedCodeConfig?.invocationType === 'lambdaSyncInv'
|
|
55
|
+
);
|
|
56
|
+
const hasAfterHookAsync = afterHooks.some(
|
|
57
|
+
(h) => h?.generatedCodeConfig?.invocationType === 'ownTopic'
|
|
58
|
+
);
|
|
59
|
+
const hasAfterHookCallback = outputTopic && hasAfterHookAsync;
|
|
60
|
+
|
|
28
61
|
return {
|
|
29
62
|
action,
|
|
30
63
|
outputTopic,
|
|
31
64
|
hasGraph: outputTopic && hasGraph,
|
|
32
65
|
hasRbac: actionHasRbac,
|
|
33
66
|
hasQuotaReservation,
|
|
34
|
-
hasComplete: outputTopic && (actionHasRbac || hasGraph),
|
|
67
|
+
hasComplete: outputTopic && (actionHasRbac || hasGraph || hasAfterHookCallback),
|
|
35
68
|
hasRbacCallback: false,
|
|
36
69
|
hasCreateNodeCallback:
|
|
37
|
-
outputTopic && action === 'Create' && actionHasRbac && hasGraph && hasQuotaReservation
|
|
70
|
+
outputTopic && action === 'Create' && actionHasRbac && hasGraph && hasQuotaReservation,
|
|
71
|
+
hasBeforeHookSync,
|
|
72
|
+
hasBeforeHookAsync,
|
|
73
|
+
hasBeforeHookCallback,
|
|
74
|
+
hasAfterHookSync,
|
|
75
|
+
hasAfterHookAsync,
|
|
76
|
+
hasAfterHookCallback,
|
|
77
|
+
beforeHooks,
|
|
78
|
+
afterHooks
|
|
38
79
|
};
|
|
39
80
|
}
|
|
40
81
|
|
|
@@ -51,7 +51,7 @@ export async function emitCrudApplicationArtifacts({
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
const handlers = await Promise.all(
|
|
54
|
-
ACTIONS.map((action) => emitAction(action, objects, serviceTag))
|
|
54
|
+
ACTIONS.map((action) => emitAction(action, objects, serviceTag, flows))
|
|
55
55
|
);
|
|
56
56
|
return [
|
|
57
57
|
...handlers.flatMap((handler) => handler.artifacts),
|
|
@@ -88,6 +88,10 @@ export function crudApplicationManagedPaths() {
|
|
|
88
88
|
`${source}/${action}RbacCallback_HdrSqs.js`,
|
|
89
89
|
`${source}/${action}NodeCallback_Main.js`,
|
|
90
90
|
`${source}/${action}NodeCallback_HdrSqs.js`,
|
|
91
|
+
`${source}/${action}BeforeHookCallback_Main.js`,
|
|
92
|
+
`${source}/${action}BeforeHookCallback_HdrSqs.js`,
|
|
93
|
+
`${source}/${action}AfterHookCallback_Main.js`,
|
|
94
|
+
`${source}/${action}AfterHookCallback_HdrSqs.js`,
|
|
91
95
|
`${source}/${action}Complete_Main.js`,
|
|
92
96
|
`${source}/${action}Complete_HdrSqs.js`
|
|
93
97
|
);
|
|
@@ -98,10 +102,10 @@ export function crudApplicationManagedPaths() {
|
|
|
98
102
|
];
|
|
99
103
|
}
|
|
100
104
|
|
|
101
|
-
async function emitAction(action, objects, serviceTag) {
|
|
105
|
+
async function emitAction(action, objects, serviceTag, flows = []) {
|
|
102
106
|
const source = `app/src/generatedCode/FlowObjects/${action}/source`;
|
|
103
107
|
const handlerRoot = `src/generatedCode/FlowObjects/${action}/source`;
|
|
104
|
-
const plan = createCrudActionPlans(objects)[action];
|
|
108
|
+
const plan = createCrudActionPlans(objects, flows)[action];
|
|
105
109
|
const mainFileName = `${action}_Main`;
|
|
106
110
|
const shared = {
|
|
107
111
|
flowTag: action,
|
|
@@ -326,6 +330,62 @@ async function emitAction(action, objects, serviceTag) {
|
|
|
326
330
|
});
|
|
327
331
|
}
|
|
328
332
|
|
|
333
|
+
if (plan.hasBeforeHookCallback) {
|
|
334
|
+
const beforeHookCallbackMain = `${action}BeforeHookCallback_Main`;
|
|
335
|
+
artifacts.push(
|
|
336
|
+
{
|
|
337
|
+
path: `${source}/${beforeHookCallbackMain}.js`,
|
|
338
|
+
content: await render(`${action}BeforeHookCallback_Main.ejs`, shared)
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
path: `${source}/${action}BeforeHookCallback_HdrSqs.js`,
|
|
342
|
+
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
343
|
+
...shared,
|
|
344
|
+
mainFileName: beforeHookCallbackMain,
|
|
345
|
+
functionName: `${action}BeforeHookCallbackMain`,
|
|
346
|
+
queueName: `${action}BeforeHookCallbackHdrSqs`
|
|
347
|
+
})
|
|
348
|
+
}
|
|
349
|
+
);
|
|
350
|
+
functions.push({
|
|
351
|
+
type: 'sqs',
|
|
352
|
+
functionName: `${action}BeforeHookCallbackHdrSqs`,
|
|
353
|
+
handlerPath: `${handlerRoot}/${action}BeforeHookCallback_HdrSqs.main`,
|
|
354
|
+
roleName: 'FlowObjectsRole',
|
|
355
|
+
queueName: `${action}BeforeHookCallbackHdrSqs`,
|
|
356
|
+
flowTag: action,
|
|
357
|
+
flowStepName: 'BeforeHookCallback'
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (plan.hasAfterHookCallback) {
|
|
362
|
+
const afterHookCallbackMain = `${action}AfterHookCallback_Main`;
|
|
363
|
+
artifacts.push(
|
|
364
|
+
{
|
|
365
|
+
path: `${source}/${afterHookCallbackMain}.js`,
|
|
366
|
+
content: await render(`${action}AfterHookCallback_Main.ejs`, shared)
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
path: `${source}/${action}AfterHookCallback_HdrSqs.js`,
|
|
370
|
+
content: await renderShared('FlowHandler_HdrSqs.ejs', {
|
|
371
|
+
...shared,
|
|
372
|
+
mainFileName: afterHookCallbackMain,
|
|
373
|
+
functionName: `${action}AfterHookCallbackMain`,
|
|
374
|
+
queueName: `${action}AfterHookCallbackHdrSqs`
|
|
375
|
+
})
|
|
376
|
+
}
|
|
377
|
+
);
|
|
378
|
+
functions.push({
|
|
379
|
+
type: 'sqs',
|
|
380
|
+
functionName: `${action}AfterHookCallbackHdrSqs`,
|
|
381
|
+
handlerPath: `${handlerRoot}/${action}AfterHookCallback_HdrSqs.main`,
|
|
382
|
+
roleName: 'FlowObjectsRole',
|
|
383
|
+
queueName: `${action}AfterHookCallbackHdrSqs`,
|
|
384
|
+
flowTag: action,
|
|
385
|
+
flowStepName: 'AfterHookCallback'
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
|
|
329
389
|
if (plan.hasComplete) {
|
|
330
390
|
const completeMain = `${action}Complete_Main`;
|
|
331
391
|
let templateName = `${action}Complete_Main.ejs`;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (C) 2026 Sven Mason <http://izara.io>
|
|
3
|
+
|
|
4
|
+
This program is free software: you can redistribute it and/or modify
|
|
5
|
+
it under the terms of the GNU Affero General Public License as
|
|
6
|
+
published by the Free Software Foundation, either version 3 of the
|
|
7
|
+
License, or (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
This program is distributed in the hope that it will be useful,
|
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
GNU Affero General Public License for more details.
|
|
13
|
+
|
|
14
|
+
You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import asyncFlowSharedLib from '@izara_project/izara-core-library-asynchronous-flow';
|
|
19
|
+
import callingFlowSharedLib from '@izara_project/izara-core-library-calling-flow';
|
|
20
|
+
import snsSharedLib from '@izara_project/izara-core-library-sns';
|
|
21
|
+
import { sns } from '@izara_project/izara-core-library-external-request';
|
|
22
|
+
import { consts } from '@izara_project/izara-core-library-service-schemas';
|
|
23
|
+
import { forwardToQuotaConfirmation } from './CreateLogicalLib.js';
|
|
24
|
+
|
|
25
|
+
//(<optionalRequire>)
|
|
26
|
+
//(</optionalRequire>)
|
|
27
|
+
|
|
28
|
+
const { TOPIC_NAME_GENERATE_CODE } = consts;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Handles callback after async AfterHook completion
|
|
32
|
+
* @param {Object} _izContext - Izara context object
|
|
33
|
+
* @param {Object} requestParams - Callback request parameters
|
|
34
|
+
* @param {Object} passBackProperties - Pass-back properties
|
|
35
|
+
* @returns {Promise<Object>} Result object
|
|
36
|
+
*/
|
|
37
|
+
export default async function CreateAfterHookCallbackMain(
|
|
38
|
+
_izContext,
|
|
39
|
+
requestParams,
|
|
40
|
+
passBackProperties
|
|
41
|
+
//(<additionalParams>)
|
|
42
|
+
//(</additionalParams>)
|
|
43
|
+
) {
|
|
44
|
+
try {
|
|
45
|
+
_izContext.logger.debug('[CreateAfterHookCallback] started', {
|
|
46
|
+
requestParams,
|
|
47
|
+
passBackProperties
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const {
|
|
51
|
+
status,
|
|
52
|
+
errorsFound = [],
|
|
53
|
+
returnValue,
|
|
54
|
+
parentFlowId
|
|
55
|
+
} = requestParams;
|
|
56
|
+
|
|
57
|
+
const mergedErrors = Array.isArray(errorsFound) ? [...errorsFound] : [];
|
|
58
|
+
if (status === 'error' && mergedErrors.length === 0) {
|
|
59
|
+
mergedErrors.push('AfterHook execution reported error');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const callingFlowConfig =
|
|
63
|
+
passBackProperties?.callingFlowConfig ||
|
|
64
|
+
requestParams?.passBackProperties?.callingFlowConfig ||
|
|
65
|
+
passBackProperties;
|
|
66
|
+
|
|
67
|
+
const quotaKeys =
|
|
68
|
+
passBackProperties?.quotaKeys ||
|
|
69
|
+
requestParams?.passBackProperties?.quotaKeys;
|
|
70
|
+
|
|
71
|
+
const actionData =
|
|
72
|
+
passBackProperties?.actionData ||
|
|
73
|
+
requestParams?.passBackProperties?.actionData ||
|
|
74
|
+
{
|
|
75
|
+
objType: returnValue?.objType || requestParams?.objType,
|
|
76
|
+
objInstanceFull: returnValue?.objInstanceFull || requestParams?.objInstanceFull,
|
|
77
|
+
relationships: returnValue?.relationships || requestParams?.relationships || [],
|
|
78
|
+
targetIdentifiers: requestParams?.targetIdentifiers,
|
|
79
|
+
parentFlowId: parentFlowId || returnValue?.parentFlowId,
|
|
80
|
+
status: mergedErrors.length > 0 ? 'error' : 'complete',
|
|
81
|
+
errorsFound: mergedErrors
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
if (quotaKeys) {
|
|
85
|
+
await forwardToQuotaConfirmation(_izContext, {
|
|
86
|
+
status: mergedErrors.length > 0 ? 'error' : 'complete',
|
|
87
|
+
errorsFound: mergedErrors,
|
|
88
|
+
quotaKeys,
|
|
89
|
+
actionData,
|
|
90
|
+
callingFlowConfig
|
|
91
|
+
});
|
|
92
|
+
} else {
|
|
93
|
+
const topicArn = snsSharedLib.snsTopicArnByFlowSchema(
|
|
94
|
+
_izContext,
|
|
95
|
+
TOPIC_NAME_GENERATE_CODE.outCreateNodeComplete
|
|
96
|
+
);
|
|
97
|
+
const completionPayload = {
|
|
98
|
+
...actionData,
|
|
99
|
+
status: mergedErrors.length > 0 ? 'error' : 'complete',
|
|
100
|
+
errorsFound: mergedErrors
|
|
101
|
+
};
|
|
102
|
+
await sns.publishAsync(_izContext, {
|
|
103
|
+
TopicArn: topicArn,
|
|
104
|
+
Message: JSON.stringify(completionPayload),
|
|
105
|
+
MessageAttributes: sns.createStringMessageAttributes(_izContext, {})
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//(<afterProcessCallback>)
|
|
110
|
+
//(</afterProcessCallback>)
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
returnValue,
|
|
114
|
+
status: mergedErrors.length > 0 ? 'error' : 'complete',
|
|
115
|
+
errorsFound: mergedErrors
|
|
116
|
+
};
|
|
117
|
+
} catch (error) {
|
|
118
|
+
_izContext.logger.error('[CreateAfterHookCallback] error:', error);
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (C) 2026 Sven Mason <http://izara.io>
|
|
3
|
+
|
|
4
|
+
This program is free software: you can redistribute it and/or modify
|
|
5
|
+
it under the terms of the GNU Affero General Public License as
|
|
6
|
+
published by the Free Software Foundation, either version 3 of the
|
|
7
|
+
License, or (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
This program is distributed in the hope that it will be useful,
|
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
GNU Affero General Public License for more details.
|
|
13
|
+
|
|
14
|
+
You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
<%- flowTag %>LogicalLib,
|
|
20
|
+
handleCreateError
|
|
21
|
+
} from './<%- upperCaseFlowTag %>LogicalLib.js';
|
|
22
|
+
|
|
23
|
+
//(<optionalRequire>)
|
|
24
|
+
//(</optionalRequire>)
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Handles callback after async BeforeHook completion
|
|
28
|
+
* @param {Object} _izContext - Izara context object
|
|
29
|
+
* @param {Object} requestParams - Callback request parameters
|
|
30
|
+
* @param {Object} passBackProperties - Pass-back properties
|
|
31
|
+
* @returns {Promise<Object>} Result object
|
|
32
|
+
*/
|
|
33
|
+
export default async function <%- upperCaseFlowTag %>BeforeHookCallbackMain(
|
|
34
|
+
_izContext,
|
|
35
|
+
requestParams,
|
|
36
|
+
passBackProperties
|
|
37
|
+
//(<additionalParams>)
|
|
38
|
+
//(</additionalParams>)
|
|
39
|
+
) {
|
|
40
|
+
try {
|
|
41
|
+
_izContext.logger.debug('[<%- upperCaseFlowTag %>BeforeHookCallback] started', {
|
|
42
|
+
requestParams,
|
|
43
|
+
passBackProperties
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const {
|
|
47
|
+
status,
|
|
48
|
+
errorsFound = [],
|
|
49
|
+
returnValue,
|
|
50
|
+
parentFlowId
|
|
51
|
+
} = requestParams;
|
|
52
|
+
|
|
53
|
+
const mergedErrors = Array.isArray(errorsFound) ? [...errorsFound] : [];
|
|
54
|
+
if (status === 'error' && mergedErrors.length === 0) {
|
|
55
|
+
mergedErrors.push('BeforeHook execution reported error');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const callingFlowConfig =
|
|
59
|
+
passBackProperties?.callingFlowConfig ||
|
|
60
|
+
requestParams?.passBackProperties?.callingFlowConfig ||
|
|
61
|
+
{};
|
|
62
|
+
|
|
63
|
+
const originalRequestParams =
|
|
64
|
+
passBackProperties?.originalRequestParams ||
|
|
65
|
+
requestParams?.passBackProperties?.originalRequestParams ||
|
|
66
|
+
passBackProperties?.requestParams ||
|
|
67
|
+
passBackProperties;
|
|
68
|
+
|
|
69
|
+
if (mergedErrors.length > 0) {
|
|
70
|
+
_izContext.logger.warn(
|
|
71
|
+
'[<%- upperCaseFlowTag %>BeforeHookCallback] BeforeHook reported errors:',
|
|
72
|
+
mergedErrors
|
|
73
|
+
);
|
|
74
|
+
return await handleCreateError(_izContext, {
|
|
75
|
+
objType: originalRequestParams?.objType,
|
|
76
|
+
objInstanceFull: {
|
|
77
|
+
identifiers:
|
|
78
|
+
originalRequestParams?.identifiers ||
|
|
79
|
+
originalRequestParams?.targetIdentifiers ||
|
|
80
|
+
{},
|
|
81
|
+
fields: originalRequestParams?.fieldNames || {}
|
|
82
|
+
},
|
|
83
|
+
requestParams: originalRequestParams || {},
|
|
84
|
+
callingFlowConfig,
|
|
85
|
+
errorsFound: mergedErrors
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (returnValue?.fieldNames && originalRequestParams?.fieldNames) {
|
|
90
|
+
Object.assign(originalRequestParams.fieldNames, returnValue.fieldNames);
|
|
91
|
+
}
|
|
92
|
+
if (returnValue?.relationships && originalRequestParams) {
|
|
93
|
+
originalRequestParams.relationships = returnValue.relationships;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
//(<beforeLogicalExecution>)
|
|
97
|
+
//(</beforeLogicalExecution>)
|
|
98
|
+
|
|
99
|
+
return await <%- flowTag %>LogicalLib(
|
|
100
|
+
_izContext,
|
|
101
|
+
originalRequestParams,
|
|
102
|
+
callingFlowConfig
|
|
103
|
+
);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
_izContext.logger.error('[<%- upperCaseFlowTag %>BeforeHookCallback] error:', error);
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
}
|