@izara_project/izara-core-generate-service-code 1.0.88 → 1.0.90
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/flowValidator.js +25 -0
- package/src/compile/loadSchemas.js +154 -0
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +3 -7
- package/src/emit/crud/crudActionPlan.js +67 -9
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +15 -32
- package/src/emit/crud/templates/CreateComplete_Main.ejs +135 -10
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +33 -27
- package/src/emit/crud/templates/CreateLogicalLib.ejs +282 -95
- package/src/emit/crud/templates/CreateNodeCallback_Main.ejs +38 -21
- package/src/emit/crud/templates/DeleteAfterHookCallback_Main.ejs +118 -0
- package/src/emit/crud/templates/DeleteComplete_Main.ejs +124 -10
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +26 -16
- package/src/emit/crud/templates/DeleteLogicalLib.ejs +113 -4
- package/src/emit/crud/templates/UpdateAfterHookCallback_Main.ejs +120 -0
- package/src/emit/crud/templates/UpdateComplete_Main.ejs +104 -10
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +34 -22
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +121 -4
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +8 -2
- package/src/emit/rbac/templates/CancelUsage_Main.ejs +34 -14
- package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +34 -14
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +20 -13
- package/src/emit/resource/emitResourceArtifacts.js +55 -14
- package/test/createTargetRoleHandler.test.js +11 -8
- package/test/crudApplicationArtifacts.test.js +440 -0
- package/test/dynamicCrudFlowSchemas.test.js +10 -5
- package/test/dynamicRbacFlowSchemas.test.js +24 -2
- package/test/graphDrivenFlowSchema.test.js +36 -0
- package/test/resourceArtifacts.test.js +113 -0
|
@@ -0,0 +1,120 @@
|
|
|
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
|
+
|
|
24
|
+
//(<optionalRequire>)
|
|
25
|
+
//(</optionalRequire>)
|
|
26
|
+
|
|
27
|
+
const { TOPIC_NAME_GENERATE_CODE } = consts;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Handles callback after async AfterHook completion for Update
|
|
31
|
+
* @param {Object} _izContext - Izara context object
|
|
32
|
+
* @param {Object} requestParams - Callback request parameters
|
|
33
|
+
* @param {Object} passBackProperties - Pass-back properties
|
|
34
|
+
* @returns {Promise<Object>} Result object
|
|
35
|
+
*/
|
|
36
|
+
export default async function UpdateAfterHookCallbackMain(
|
|
37
|
+
_izContext,
|
|
38
|
+
requestParams,
|
|
39
|
+
passBackProperties
|
|
40
|
+
//(<additionalParams>)
|
|
41
|
+
//(</additionalParams>)
|
|
42
|
+
) {
|
|
43
|
+
try {
|
|
44
|
+
_izContext.logger.debug('[UpdateAfterHookCallback] started', {
|
|
45
|
+
requestParams,
|
|
46
|
+
passBackProperties
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const {
|
|
50
|
+
status,
|
|
51
|
+
errorsFound = [],
|
|
52
|
+
returnValue,
|
|
53
|
+
parentFlowId
|
|
54
|
+
} = requestParams;
|
|
55
|
+
|
|
56
|
+
const mergedErrors = Array.isArray(errorsFound) ? [...errorsFound] : [];
|
|
57
|
+
if (status === 'error' && mergedErrors.length === 0) {
|
|
58
|
+
mergedErrors.push('AfterHook execution reported error');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const callingFlowConfig =
|
|
62
|
+
passBackProperties?.callingFlowConfig ||
|
|
63
|
+
requestParams?.passBackProperties?.callingFlowConfig ||
|
|
64
|
+
passBackProperties;
|
|
65
|
+
|
|
66
|
+
const actionData =
|
|
67
|
+
passBackProperties?.actionData ||
|
|
68
|
+
requestParams?.passBackProperties?.actionData ||
|
|
69
|
+
{
|
|
70
|
+
objType: returnValue?.objType || requestParams?.objType,
|
|
71
|
+
objInstanceFull:
|
|
72
|
+
returnValue?.objInstanceFull || requestParams?.objInstanceFull,
|
|
73
|
+
relationships:
|
|
74
|
+
returnValue?.relationships || requestParams?.relationships || [],
|
|
75
|
+
targetIdentifiers: requestParams?.targetIdentifiers,
|
|
76
|
+
parentFlowId: parentFlowId || returnValue?.parentFlowId,
|
|
77
|
+
status: mergedErrors.length > 0 ? 'error' : 'complete',
|
|
78
|
+
errorsFound: mergedErrors
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const topicArn = snsSharedLib.snsTopicArnByFlowSchema(
|
|
82
|
+
_izContext,
|
|
83
|
+
TOPIC_NAME_GENERATE_CODE.outUpdateNodeComplete
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const completionPayload =
|
|
87
|
+
callingFlowSharedLib.addParentPassBackPropertiesToSnsResponseMessageObject(
|
|
88
|
+
callingFlowConfig,
|
|
89
|
+
{
|
|
90
|
+
...actionData,
|
|
91
|
+
status: mergedErrors.length > 0 ? 'error' : 'complete',
|
|
92
|
+
errorsFound: mergedErrors
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
await sns.publishAsync(_izContext, {
|
|
97
|
+
TopicArn: topicArn,
|
|
98
|
+
Message: JSON.stringify(completionPayload),
|
|
99
|
+
MessageAttributes: sns.createStringMessageAttributes(
|
|
100
|
+
_izContext,
|
|
101
|
+
callingFlowSharedLib.addParentPassBackCallingFlowToSnsResponseMessageAttributes(
|
|
102
|
+
callingFlowConfig,
|
|
103
|
+
{}
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
//(<afterProcessCallback>)
|
|
109
|
+
//(</afterProcessCallback>)
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
returnValue,
|
|
113
|
+
status: mergedErrors.length > 0 ? 'error' : 'complete',
|
|
114
|
+
errorsFound: mergedErrors
|
|
115
|
+
};
|
|
116
|
+
} catch (error) {
|
|
117
|
+
_izContext.logger.error('[UpdateAfterHookCallback] error:', error);
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import asyncFlowSharedLib from '@izara_project/izara-core-library-asynchronous-flow';
|
|
2
2
|
import callingFlowSharedLib from '@izara_project/izara-core-library-calling-flow';
|
|
3
3
|
import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
|
|
4
|
+
import lambdaSharedLib from '@izara_project/izara-core-library-lambda';
|
|
4
5
|
import snsSharedLib from '@izara_project/izara-core-library-sns';
|
|
5
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
sns,
|
|
8
|
+
lambda
|
|
9
|
+
} from '@izara_project/izara-core-library-external-request';
|
|
6
10
|
import { consts } from '@izara_project/izara-core-library-service-schemas';
|
|
7
11
|
import { NoRetryError } from '@izara_project/izara-core-library-core';
|
|
8
12
|
|
|
@@ -142,18 +146,107 @@ export default async function UpdateComplete(
|
|
|
142
146
|
const callingFlowConfig =
|
|
143
147
|
result?.additionalAttributes?.callingFlowConfig ||
|
|
144
148
|
passBackProperties;
|
|
149
|
+
|
|
150
|
+
const actionData = {
|
|
151
|
+
objType: returnValue.requestParams.objType,
|
|
152
|
+
objInstanceFull: node.objInstanceFull,
|
|
153
|
+
relationships: node.relationships,
|
|
154
|
+
parentFlowId: parentFlowId || returnValue?.parentFlowId,
|
|
155
|
+
existsNode,
|
|
156
|
+
status,
|
|
157
|
+
errorsFound
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
<%_ if (plan?.hasAfterHookSync) { _%>
|
|
161
|
+
// ── Synchronous After Hooks ──
|
|
162
|
+
<%_ plan.afterHooks.filter(h => h?.generatedCodeConfig?.invocationType === 'lambdaSyncInv').forEach(hook => { _%>
|
|
163
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length === 1) { _%>
|
|
164
|
+
if (returnValue.requestParams?.objType?.objectType === '<%= hook.targetObjectTypes[0] %>') {
|
|
165
|
+
<%_ } else if (hook.targetObjectTypes && hook.targetObjectTypes.length > 1) { _%>
|
|
166
|
+
if (<%- JSON.stringify(hook.targetObjectTypes) %>.includes(returnValue.requestParams?.objType?.objectType)) {
|
|
167
|
+
<%_ } _%>
|
|
168
|
+
try {
|
|
169
|
+
let hookPayload_<%= hook.flowTag %> = {
|
|
170
|
+
objType: returnValue.requestParams.objType,
|
|
171
|
+
objInstanceFull: node.objInstanceFull,
|
|
172
|
+
relationships: node.relationships || [],
|
|
173
|
+
targetIdentifiers: requestParams.targetIdentifiers
|
|
174
|
+
};
|
|
175
|
+
//(<beforeSendHook_<%= hook.flowTag %>>)
|
|
176
|
+
//(</beforeSendHook_<%= hook.flowTag %>>)
|
|
177
|
+
const hookResult = await lambda.invokeSync(
|
|
178
|
+
_izContext,
|
|
179
|
+
await lambdaSharedLib.lambdaFunctionName(
|
|
180
|
+
_izContext,
|
|
181
|
+
'<%= hook.flowTag %>'
|
|
182
|
+
),
|
|
183
|
+
{
|
|
184
|
+
requestParams: hookPayload_<%= hook.flowTag %>,
|
|
185
|
+
callingFlowConfig
|
|
186
|
+
}
|
|
187
|
+
);
|
|
188
|
+
if (hookResult?.errorsFound?.length > 0 || hookResult?.status === 'error') {
|
|
189
|
+
errorsFound.push(...(hookResult.errorsFound || ['Hook <%= hook.flowTag %> failed']));
|
|
190
|
+
}
|
|
191
|
+
} catch (hookErr) {
|
|
192
|
+
_izContext.logger.error('[UpdateComplete] Sync hook <%= hook.flowTag %> error:', hookErr);
|
|
193
|
+
errorsFound.push(hookErr.message || 'Hook <%= hook.flowTag %> failed');
|
|
194
|
+
}
|
|
195
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length > 0) { _%>
|
|
196
|
+
}
|
|
197
|
+
<%_ } _%>
|
|
198
|
+
<%_ }) _%>
|
|
199
|
+
<%_ } _%>
|
|
200
|
+
|
|
201
|
+
<%_ if (plan?.hasAfterHookAsync) { _%>
|
|
202
|
+
// ── Asynchronous After Hooks ──
|
|
203
|
+
<%_ plan.afterHooks.filter(h => h?.generatedCodeConfig?.invocationType === 'ownTopic').forEach(hook => { _%>
|
|
204
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length === 1) { _%>
|
|
205
|
+
if (returnValue.requestParams?.objType?.objectType === '<%= hook.targetObjectTypes[0] %>') {
|
|
206
|
+
<%_ } else if (hook.targetObjectTypes && hook.targetObjectTypes.length > 1) { _%>
|
|
207
|
+
if (<%- JSON.stringify(hook.targetObjectTypes) %>.includes(returnValue.requestParams?.objType?.objectType)) {
|
|
208
|
+
<%_ } _%>
|
|
209
|
+
let hookPayload_<%= hook.flowTag %> = {
|
|
210
|
+
objType: returnValue.requestParams.objType,
|
|
211
|
+
objInstanceFull: node.objInstanceFull,
|
|
212
|
+
relationships: node.relationships || [],
|
|
213
|
+
targetIdentifiers: requestParams.targetIdentifiers
|
|
214
|
+
};
|
|
215
|
+
//(<beforeSendHook_<%= hook.flowTag %>>)
|
|
216
|
+
//(</beforeSendHook_<%= hook.flowTag %>>)
|
|
217
|
+
const hookMsg_<%= hook.flowTag %> = callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
|
|
218
|
+
hookPayload_<%= hook.flowTag %>,
|
|
219
|
+
callingFlowSharedLib.addParentCallingFlowConfig(
|
|
220
|
+
callingFlowConfig,
|
|
221
|
+
callingFlowSharedLib.createCallingFlowConfig(
|
|
222
|
+
await lambdaSharedLib.lambdaFunctionName(
|
|
223
|
+
_izContext,
|
|
224
|
+
'UpdateAfterHookCallbackHdrSqs'
|
|
225
|
+
),
|
|
226
|
+
{
|
|
227
|
+
actionData
|
|
228
|
+
}
|
|
229
|
+
)
|
|
230
|
+
)
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
await sns.publishAsync(_izContext, {
|
|
234
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
235
|
+
_izContext,
|
|
236
|
+
'<%= hook.flowTag %>_In'
|
|
237
|
+
),
|
|
238
|
+
Message: JSON.stringify(hookMsg_<%= hook.flowTag %>),
|
|
239
|
+
MessageAttributes: sns.createStringMessageAttributes(_izContext, {})
|
|
240
|
+
});
|
|
241
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length > 0) { _%>
|
|
242
|
+
}
|
|
243
|
+
<%_ } _%>
|
|
244
|
+
<%_ }) _%>
|
|
245
|
+
<%_ } else { _%>
|
|
145
246
|
const message =
|
|
146
247
|
callingFlowSharedLib.addParentPassBackPropertiesToSnsResponseMessageObject(
|
|
147
248
|
callingFlowConfig,
|
|
148
|
-
|
|
149
|
-
objType: returnValue.requestParams.objType,
|
|
150
|
-
objInstanceFull: node.objInstanceFull,
|
|
151
|
-
relationships: node.relationships,
|
|
152
|
-
parentFlowId: parentFlowId || returnValue?.parentFlowId,
|
|
153
|
-
existsNode,
|
|
154
|
-
status,
|
|
155
|
-
errorsFound
|
|
156
|
-
}
|
|
249
|
+
actionData
|
|
157
250
|
);
|
|
158
251
|
const messageAttributes =
|
|
159
252
|
callingFlowSharedLib.addParentPassBackCallingFlowToSnsResponseMessageAttributes(
|
|
@@ -176,6 +269,7 @@ export default async function UpdateComplete(
|
|
|
176
269
|
),
|
|
177
270
|
TopicArn: topicArn
|
|
178
271
|
});
|
|
272
|
+
<%_ } _%>
|
|
179
273
|
//(<afterSendMessage>)
|
|
180
274
|
//(</afterSendMessage>)
|
|
181
275
|
}
|
|
@@ -200,11 +200,15 @@ export default async function <%- flowTag %>(
|
|
|
200
200
|
|
|
201
201
|
// ── Optional phase extension point ────────────────────────────────────────
|
|
202
202
|
<%_
|
|
203
|
+
const allCrudObjectTypes = (objects || []).filter(isCrudObject).map(o => o.objectType);
|
|
203
204
|
const beforeHooksByObjType = (plan?.beforeHooks || []).reduce((acc, hook) => {
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
const targets = (hook?.targetObjectTypes && hook.targetObjectTypes.length > 0)
|
|
206
|
+
? hook.targetObjectTypes
|
|
207
|
+
: allCrudObjectTypes;
|
|
208
|
+
for (const key of targets) {
|
|
209
|
+
if (!acc[key]) acc[key] = [];
|
|
210
|
+
acc[key].push(hook);
|
|
211
|
+
}
|
|
208
212
|
return acc;
|
|
209
213
|
}, {});
|
|
210
214
|
_%>
|
|
@@ -218,6 +222,18 @@ export default async function <%- flowTag %>(
|
|
|
218
222
|
const lambdaSyncInvResults = [];
|
|
219
223
|
<%_ for (const config of configs.filter(c => c?.generatedCodeConfig?.invocationType === 'lambdaSyncInv' || c?.event?.includes('lambdaSyncInv'))) { _%>
|
|
220
224
|
try {
|
|
225
|
+
let hookPayload_<%= config.flowTag %> = {
|
|
226
|
+
objType,
|
|
227
|
+
objInstanceFull: requestParams.objInstanceFull,
|
|
228
|
+
identifiers: requestParams.objInstanceFull?.identifiers,
|
|
229
|
+
fieldNames:
|
|
230
|
+
requestParams.objInstanceFull?.fields || requestParams.fieldNames,
|
|
231
|
+
relationships: requestParams.relationships || [],
|
|
232
|
+
targetIdentifiers,
|
|
233
|
+
submittedByUserId: requestParams.submittedByUserId
|
|
234
|
+
};
|
|
235
|
+
//(<beforeSendHook_<%= config.flowTag %>>)
|
|
236
|
+
//(</beforeSendHook_<%= config.flowTag %>>)
|
|
221
237
|
const returnValue = await lambda.invokeSync(
|
|
222
238
|
_izContext,
|
|
223
239
|
await lambdaSharedLib.lambdaFunctionName(
|
|
@@ -225,15 +241,7 @@ export default async function <%- flowTag %>(
|
|
|
225
241
|
'<%= config.flowTag %>'
|
|
226
242
|
),
|
|
227
243
|
{
|
|
228
|
-
requestParams:
|
|
229
|
-
objType,
|
|
230
|
-
objInstanceFull: requestParams.objInstanceFull,
|
|
231
|
-
identifiers: requestParams.objInstanceFull?.identifiers,
|
|
232
|
-
fieldNames: requestParams.objInstanceFull?.fields || requestParams.fieldNames,
|
|
233
|
-
relationships: requestParams.relationships || [],
|
|
234
|
-
targetIdentifiers,
|
|
235
|
-
submittedByUserId: requestParams.submittedByUserId
|
|
236
|
-
},
|
|
244
|
+
requestParams: hookPayload_<%= config.flowTag %>,
|
|
237
245
|
callingFlowConfig
|
|
238
246
|
}
|
|
239
247
|
);
|
|
@@ -282,17 +290,21 @@ export default async function <%- flowTag %>(
|
|
|
282
290
|
<%_ if (hasOwnTopic) { _%>
|
|
283
291
|
// ── ownTopic (async — dispatch to before-hook and await callback) ──────────
|
|
284
292
|
<%_ configs.filter(c => c?.generatedCodeConfig?.invocationType === 'ownTopic' || c?.event?.includes('ownTopic')).forEach(config => { _%>
|
|
293
|
+
let hookPayload_<%= config.flowTag %> = {
|
|
294
|
+
objType,
|
|
295
|
+
objInstanceFull: requestParams.objInstanceFull,
|
|
296
|
+
identifiers: requestParams.objInstanceFull?.identifiers,
|
|
297
|
+
fieldNames:
|
|
298
|
+
requestParams.objInstanceFull?.fields || requestParams.fieldNames,
|
|
299
|
+
relationships: requestParams.relationships || [],
|
|
300
|
+
targetIdentifiers,
|
|
301
|
+
submittedByUserId: requestParams.submittedByUserId
|
|
302
|
+
};
|
|
303
|
+
//(<beforeSendHook_<%= config.flowTag %>>)
|
|
304
|
+
//(</beforeSendHook_<%= config.flowTag %>>)
|
|
285
305
|
const hookMsg_<%= config.flowTag %> =
|
|
286
306
|
callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
|
|
287
|
-
|
|
288
|
-
objType,
|
|
289
|
-
objInstanceFull: requestParams.objInstanceFull,
|
|
290
|
-
identifiers: requestParams.objInstanceFull?.identifiers,
|
|
291
|
-
fieldNames: requestParams.objInstanceFull?.fields || requestParams.fieldNames,
|
|
292
|
-
relationships: requestParams.relationships || [],
|
|
293
|
-
targetIdentifiers,
|
|
294
|
-
submittedByUserId: requestParams.submittedByUserId
|
|
295
|
-
},
|
|
307
|
+
hookPayload_<%= config.flowTag %>,
|
|
296
308
|
callingFlowSharedLib.addParentCallingFlowConfig(
|
|
297
309
|
callingFlowConfig,
|
|
298
310
|
callingFlowSharedLib.createCallingFlowConfig(
|
|
@@ -105,9 +105,6 @@ export async function resolveSchemaAndIdentity(_izContext, requestParams, errors
|
|
|
105
105
|
|
|
106
106
|
requestParams.submittedByUserId = submittedByUserId;
|
|
107
107
|
if (targetIdentifiers) {
|
|
108
|
-
if (!targetIdentifiers.submittedByUserId && submittedByUserId) {
|
|
109
|
-
targetIdentifiers.submittedByUserId = submittedByUserId;
|
|
110
|
-
}
|
|
111
108
|
// requestParams.targetIdentifiers = targetIdentifiers;
|
|
112
109
|
}
|
|
113
110
|
|
|
@@ -852,12 +849,132 @@ export async function <%- flowTag %>LogicalLib(
|
|
|
852
849
|
|
|
853
850
|
// 5. If no graph storage, complete immediately
|
|
854
851
|
if (!hasGraphStorage) {
|
|
852
|
+
<%_ if (plan?.hasAfterHookSync) { _%>
|
|
853
|
+
// ── Synchronous After Hooks ──
|
|
854
|
+
<%_ plan.afterHooks.filter(h => h?.generatedCodeConfig?.invocationType === 'lambdaSyncInv').forEach(hook => { _%>
|
|
855
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length === 1) { _%>
|
|
856
|
+
if (objType?.objectType === '<%= hook.targetObjectTypes[0] %>') {
|
|
857
|
+
<%_ } else if (hook.targetObjectTypes && hook.targetObjectTypes.length > 1) { _%>
|
|
858
|
+
if (<%- JSON.stringify(hook.targetObjectTypes) %>.includes(objType?.objectType)) {
|
|
859
|
+
<%_ } _%>
|
|
860
|
+
try {
|
|
861
|
+
let hookPayload_<%= hook.flowTag %> = {
|
|
862
|
+
objType,
|
|
863
|
+
objInstanceFull: createObjInstanceFullFromParams(
|
|
864
|
+
updateItem,
|
|
865
|
+
requestParams
|
|
866
|
+
),
|
|
867
|
+
relationships: requestParams.relationships || [],
|
|
868
|
+
targetIdentifiers: requestParams.targetIdentifiers,
|
|
869
|
+
submittedByUserId: requestParams.submittedByUserId
|
|
870
|
+
};
|
|
871
|
+
//(<beforeSendHook_<%= hook.flowTag %>>)
|
|
872
|
+
//(</beforeSendHook_<%= hook.flowTag %>>)
|
|
873
|
+
const hookResult = await lambda.invokeSync(
|
|
874
|
+
_izContext,
|
|
875
|
+
await lambdaSharedLib.lambdaFunctionName(
|
|
876
|
+
_izContext,
|
|
877
|
+
'<%= hook.flowTag %>'
|
|
878
|
+
),
|
|
879
|
+
{
|
|
880
|
+
requestParams: hookPayload_<%= hook.flowTag %>,
|
|
881
|
+
callingFlowConfig
|
|
882
|
+
}
|
|
883
|
+
);
|
|
884
|
+
if (
|
|
885
|
+
hookResult?.errorsFound?.length > 0 ||
|
|
886
|
+
hookResult?.status === 'error'
|
|
887
|
+
) {
|
|
888
|
+
errorsFound.push(
|
|
889
|
+
...(hookResult.errorsFound || ['Hook <%= hook.flowTag %> failed'])
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
} catch (hookErr) {
|
|
893
|
+
_izContext.logger.error(
|
|
894
|
+
'[<%- flowTag %>LogicalLib] Sync hook <%= hook.flowTag %> error:',
|
|
895
|
+
hookErr
|
|
896
|
+
);
|
|
897
|
+
errorsFound.push(hookErr.message || 'Hook <%= hook.flowTag %> failed');
|
|
898
|
+
}
|
|
899
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length > 0) { _%>
|
|
900
|
+
}
|
|
901
|
+
<%_ } _%>
|
|
902
|
+
<%_ }) _%>
|
|
903
|
+
<%_ } _%>
|
|
904
|
+
|
|
905
|
+
<%_ if (plan?.hasAfterHookAsync) { _%>
|
|
906
|
+
// ── Asynchronous After Hooks ──
|
|
907
|
+
<%_ plan.afterHooks.filter(h => h?.generatedCodeConfig?.invocationType === 'ownTopic').forEach(hook => { _%>
|
|
908
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length === 1) { _%>
|
|
909
|
+
if (objType?.objectType === '<%= hook.targetObjectTypes[0] %>') {
|
|
910
|
+
<%_ } else if (hook.targetObjectTypes && hook.targetObjectTypes.length > 1) { _%>
|
|
911
|
+
if (<%- JSON.stringify(hook.targetObjectTypes) %>.includes(objType?.objectType)) {
|
|
912
|
+
<%_ } _%>
|
|
913
|
+
let hookPayload_<%= hook.flowTag %> = {
|
|
914
|
+
objType,
|
|
915
|
+
objInstanceFull: createObjInstanceFullFromParams(
|
|
916
|
+
updateItem,
|
|
917
|
+
requestParams
|
|
918
|
+
),
|
|
919
|
+
relationships: requestParams.relationships || [],
|
|
920
|
+
targetIdentifiers: requestParams.targetIdentifiers,
|
|
921
|
+
submittedByUserId: requestParams.submittedByUserId
|
|
922
|
+
};
|
|
923
|
+
//(<beforeSendHook_<%= hook.flowTag %>>)
|
|
924
|
+
//(</beforeSendHook_<%= hook.flowTag %>>)
|
|
925
|
+
const hookMsg_<%= hook.flowTag %> =
|
|
926
|
+
callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
|
|
927
|
+
hookPayload_<%= hook.flowTag %>,
|
|
928
|
+
callingFlowSharedLib.addParentCallingFlowConfig(
|
|
929
|
+
callingFlowConfig,
|
|
930
|
+
callingFlowSharedLib.createCallingFlowConfig(
|
|
931
|
+
await lambdaSharedLib.lambdaFunctionName(
|
|
932
|
+
_izContext,
|
|
933
|
+
'UpdateAfterHookCallbackHdrSqs'
|
|
934
|
+
),
|
|
935
|
+
{
|
|
936
|
+
actionData: {
|
|
937
|
+
objType,
|
|
938
|
+
objInstanceFull: createObjInstanceFullFromParams(
|
|
939
|
+
updateItem,
|
|
940
|
+
requestParams
|
|
941
|
+
),
|
|
942
|
+
relationships: requestParams.relationships || [],
|
|
943
|
+
targetIdentifiers: requestParams.targetIdentifiers,
|
|
944
|
+
parentFlowId: requestParams.parentFlowId,
|
|
945
|
+
status: 'complete',
|
|
946
|
+
errorsFound
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
)
|
|
950
|
+
)
|
|
951
|
+
);
|
|
952
|
+
|
|
953
|
+
await sns.publishAsync(_izContext, {
|
|
954
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
955
|
+
_izContext,
|
|
956
|
+
'<%= hook.flowTag %>_In'
|
|
957
|
+
),
|
|
958
|
+
Message: JSON.stringify(hookMsg_<%= hook.flowTag %>),
|
|
959
|
+
MessageAttributes: sns.createStringMessageAttributes(_izContext, {})
|
|
960
|
+
});
|
|
961
|
+
<%_ if (hook.targetObjectTypes && hook.targetObjectTypes.length > 0) { _%>
|
|
962
|
+
}
|
|
963
|
+
<%_ } _%>
|
|
964
|
+
<%_ }) _%>
|
|
965
|
+
<%_ } else { _%>
|
|
855
966
|
await handleDynamoDbOnlyComplete(_izContext, {
|
|
856
967
|
objType,
|
|
857
968
|
updateItem,
|
|
858
969
|
requestParams,
|
|
859
970
|
callingFlowConfig
|
|
860
971
|
});
|
|
972
|
+
<%_ } _%>
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
let resultStatus = 'complete';
|
|
976
|
+
if (errorsFound.length > 0) {
|
|
977
|
+
resultStatus = 'error';
|
|
861
978
|
}
|
|
862
979
|
|
|
863
980
|
return {
|
|
@@ -866,7 +983,7 @@ export async function <%- flowTag %>LogicalLib(
|
|
|
866
983
|
objInstanceFull: { identifiers, fields },
|
|
867
984
|
versionedDataIds
|
|
868
985
|
},
|
|
869
|
-
status:
|
|
986
|
+
status: resultStatus,
|
|
870
987
|
errorsFound
|
|
871
988
|
};
|
|
872
989
|
} catch (err) {
|
|
@@ -19,8 +19,14 @@ const RBAC_CORE_FLOW_DEFINITIONS = [
|
|
|
19
19
|
|
|
20
20
|
const LIMIT_FLOW_DEFINITIONS = [
|
|
21
21
|
{ flowTag: 'ReservedDynamicUsage', event: ['ownTopic'] },
|
|
22
|
-
{
|
|
23
|
-
|
|
22
|
+
{
|
|
23
|
+
flowTag: 'ConfirmUsage',
|
|
24
|
+
event: ['ownTopic', 'lambdaSyncInv', 'lambdaSyncApi']
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
flowTag: 'CancelUsage',
|
|
28
|
+
event: ['ownTopic', 'lambdaSyncInv', 'lambdaSyncApi']
|
|
29
|
+
}
|
|
24
30
|
];
|
|
25
31
|
|
|
26
32
|
const RBAC_FLOW_DEFINITIONS = [
|
|
@@ -146,20 +146,40 @@ export default async function CancelUsage(_izContext, requestParams) {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
149
|
+
const returnResult = {
|
|
150
|
+
status: true,
|
|
151
|
+
uniqueIdentify: usedTimestampId,
|
|
152
|
+
usedTimestampId,
|
|
153
|
+
runningTotalReservedId
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const eventSourceTag =
|
|
157
|
+
_izContext.izEventSource?.eventSourceTag ||
|
|
158
|
+
requestParams?.izEventSource?.eventSourceTag;
|
|
159
|
+
|
|
160
|
+
let isSync = false;
|
|
161
|
+
if (
|
|
162
|
+
eventSourceTag === 'DirectInvoke' ||
|
|
163
|
+
eventSourceTag === 'ApiGateway' ||
|
|
164
|
+
eventSourceTag === 'ApiGatewayV2' ||
|
|
165
|
+
requestParams?.hasOwnProperty('__context__')
|
|
166
|
+
) {
|
|
167
|
+
isSync = true;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (!isSync) {
|
|
171
|
+
await sns.publishMessage(_izContext, {
|
|
172
|
+
message: {
|
|
173
|
+
returnResult
|
|
174
|
+
},
|
|
175
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
176
|
+
_izContext,
|
|
177
|
+
'CancelUsage_Out'
|
|
178
|
+
)
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return returnResult;
|
|
163
183
|
} catch (error) {
|
|
164
184
|
_izContext.logger.error(`[${process.env.iz_serviceTag}:CancelUsage] error:`, error);
|
|
165
185
|
throw error;
|
|
@@ -170,20 +170,40 @@ export default async function ConfirmUsage(_izContext, requestParams) {
|
|
|
170
170
|
).catch(() => null);
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
173
|
+
const returnResult = {
|
|
174
|
+
status: true,
|
|
175
|
+
uniqueIdentify: usedTimestampId,
|
|
176
|
+
usedTimestampId,
|
|
177
|
+
runningTotalReservedId
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const eventSourceTag =
|
|
181
|
+
_izContext.izEventSource?.eventSourceTag ||
|
|
182
|
+
requestParams?.izEventSource?.eventSourceTag;
|
|
183
|
+
|
|
184
|
+
let isSync = false;
|
|
185
|
+
if (
|
|
186
|
+
eventSourceTag === 'DirectInvoke' ||
|
|
187
|
+
eventSourceTag === 'ApiGateway' ||
|
|
188
|
+
eventSourceTag === 'ApiGatewayV2' ||
|
|
189
|
+
requestParams?.hasOwnProperty('__context__')
|
|
190
|
+
) {
|
|
191
|
+
isSync = true;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (!isSync) {
|
|
195
|
+
await sns.publishMessage(_izContext, {
|
|
196
|
+
message: {
|
|
197
|
+
returnResult
|
|
198
|
+
},
|
|
199
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
200
|
+
_izContext,
|
|
201
|
+
'ConfirmUsage_Out'
|
|
202
|
+
)
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return returnResult;
|
|
187
207
|
} catch (error) {
|
|
188
208
|
_izContext.logger.error(`[${process.env.iz_serviceTag}:ConfirmUsage] error:`, error);
|
|
189
209
|
throw error;
|