@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
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
objectHash as hash,
|
|
20
20
|
identifierUuid
|
|
21
21
|
} from '@izara_project/izara-shared-core';
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
import {
|
|
24
24
|
sns,
|
|
25
25
|
lambda
|
|
@@ -29,17 +29,18 @@ import callingFlowSharedLib from '@izara_project/izara-core-library-calling-flow
|
|
|
29
29
|
import lambdaSharedLib from '@izara_project/izara-core-library-lambda';
|
|
30
30
|
import {
|
|
31
31
|
consts,
|
|
32
|
-
getObjectSchema,
|
|
33
32
|
utils
|
|
34
33
|
} from '@izara_project/izara-core-library-service-schemas';
|
|
35
34
|
import snsSharedLib from '@izara_project/izara-core-library-sns';
|
|
36
35
|
|
|
37
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
<%- flowTag %>LogicalLib,
|
|
38
|
+
resolveSchemaAndIdentity
|
|
39
|
+
} from './<%- upperCaseFlowTag %>LogicalLib.js';
|
|
38
40
|
|
|
39
41
|
//(<optionalRequire>)
|
|
40
42
|
//(</optionalRequire>)
|
|
41
43
|
|
|
42
|
-
const { createObjType } = utils;
|
|
43
44
|
|
|
44
45
|
/**
|
|
45
46
|
* Deletes an object instance with optional RBAC routing
|
|
@@ -62,53 +63,13 @@ export default async function <%- flowTag %>(
|
|
|
62
63
|
});
|
|
63
64
|
|
|
64
65
|
const errorsFound = [];
|
|
65
|
-
const objType = createObjType(requestParams.objectType);
|
|
66
66
|
|
|
67
67
|
//(<beforeDelete>)
|
|
68
68
|
//(</beforeDelete>)
|
|
69
69
|
|
|
70
|
-
// ──
|
|
71
|
-
const objectSchema
|
|
72
|
-
_izContext,
|
|
73
|
-
objType
|
|
74
|
-
);
|
|
75
|
-
_izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] objectSchema:`, objectSchema);
|
|
76
|
-
|
|
77
|
-
// ── Resolve submittedByUserId / targetIdentifiers ─────────────────────────
|
|
78
|
-
let submittedByUserId, targetIdentifiers;
|
|
79
|
-
if (
|
|
80
|
-
objectSchema.generatedBy === 'user' ||
|
|
81
|
-
objectSchema.generatedBy === 'systemWithUser'
|
|
82
|
-
) {
|
|
83
|
-
submittedByUserId =
|
|
84
|
-
requestParams.submittedByUserId ||
|
|
85
|
-
_izContext.correlationIds.get(coreConsts.SUBMITTED_BY_USER_ID);
|
|
86
|
-
|
|
87
|
-
targetIdentifiers = requestParams.targetIdentifiers;
|
|
88
|
-
delete requestParams.targetIdentifiers;
|
|
89
|
-
|
|
90
|
-
if (!targetIdentifiers && objectSchema.belongTo?.objectType === 'user' && submittedByUserId) {
|
|
91
|
-
targetIdentifiers = { submittedByUserId };
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (!submittedByUserId) errorsFound.push('Not have submittedByUserId');
|
|
95
|
-
if (objectSchema.hasOwnProperty('belongTo') && !targetIdentifiers)
|
|
96
|
-
errorsFound.push('not have targetIdentifiers');
|
|
97
|
-
|
|
98
|
-
requestParams.submittedByUserId = submittedByUserId;
|
|
99
|
-
if (targetIdentifiers) {
|
|
100
|
-
if (!targetIdentifiers.submittedByUserId && submittedByUserId) {
|
|
101
|
-
targetIdentifiers.submittedByUserId = submittedByUserId;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
_izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] Identity & Target Context Resolved:`, {
|
|
106
|
-
submittedByUserId: requestParams.submittedByUserId,
|
|
107
|
-
targetIdentifiers,
|
|
108
|
-
belongTo: objectSchema.belongTo,
|
|
109
|
-
generatedBy: objectSchema.generatedBy
|
|
110
|
-
});
|
|
111
|
-
}
|
|
70
|
+
// ── Resolve Schema & Identity ─────────────────────────────────────────────
|
|
71
|
+
const { objType, objectSchema, targetIdentifiers } =
|
|
72
|
+
await resolveSchemaAndIdentity(_izContext, requestParams, errorsFound);
|
|
112
73
|
|
|
113
74
|
//(<beforeQuery>)
|
|
114
75
|
//(</beforeQuery>)
|
|
@@ -116,36 +77,36 @@ export default async function <%- flowTag %>(
|
|
|
116
77
|
// ── Build identifiers used by asynchronous processing ────────────────────
|
|
117
78
|
const identifiers = requestParams.identifiers;
|
|
118
79
|
|
|
119
|
-
if (!objectSchema.hasOwnProperty('belongTo')) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (targetIdentifiers && identifiers) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
80
|
+
// if (!objectSchema.hasOwnProperty('belongTo')) {
|
|
81
|
+
// if (!targetIdentifiers && identifiers) {
|
|
82
|
+
// targetIdentifiers = { ...identifiers };
|
|
83
|
+
// } else if (targetIdentifiers && identifiers) {
|
|
84
|
+
// for (const [key, value] of Object.entries(identifiers)) {
|
|
85
|
+
// if (targetIdentifiers[key] === undefined && value !== undefined) {
|
|
86
|
+
// targetIdentifiers[key] = value;
|
|
87
|
+
// }
|
|
88
|
+
// }
|
|
89
|
+
// }
|
|
90
|
+
// if (targetIdentifiers) {
|
|
91
|
+
// if (!targetIdentifiers.submittedByUserId && submittedByUserId) {
|
|
92
|
+
// targetIdentifiers.submittedByUserId = submittedByUserId;
|
|
93
|
+
// }
|
|
94
|
+
// }
|
|
95
|
+
// }
|
|
96
|
+
|
|
97
|
+
// if (targetIdentifiers && identifiers) {
|
|
98
|
+
// for (const [key, value] of Object.entries(identifiers)) {
|
|
99
|
+
// if (
|
|
100
|
+
// targetIdentifiers[key] !== undefined &&
|
|
101
|
+
// value !== undefined &&
|
|
102
|
+
// targetIdentifiers[key] !== value
|
|
103
|
+
// ) {
|
|
104
|
+
// errorsFound.push(
|
|
105
|
+
// `targetIdentifiers.${key} must match identifiers.${key}`
|
|
106
|
+
// );
|
|
107
|
+
// }
|
|
108
|
+
// }
|
|
109
|
+
// }
|
|
149
110
|
|
|
150
111
|
if (errorsFound.length > 0)
|
|
151
112
|
return await <%- flowTag %>LogicalLib(
|
|
@@ -227,110 +188,107 @@ export default async function <%- flowTag %>(
|
|
|
227
188
|
|
|
228
189
|
// ── Optional phase extension point ────────────────────────────────────────
|
|
229
190
|
<%_
|
|
230
|
-
const
|
|
191
|
+
const beforeHooksByObjType = (plan?.beforeHooks || []).reduce((acc, hook) => {
|
|
192
|
+
const key = hook?.objType?.objectType;
|
|
193
|
+
if (!key) return acc;
|
|
194
|
+
if (!acc[key]) acc[key] = [];
|
|
195
|
+
acc[key].push(hook);
|
|
196
|
+
return acc;
|
|
197
|
+
}, {});
|
|
231
198
|
_%>
|
|
232
|
-
<%_ Object.entries(
|
|
199
|
+
<%_ Object.entries(beforeHooksByObjType).forEach(([objectType, configs]) => { _%>
|
|
233
200
|
<%_
|
|
234
|
-
const hasOwnTopic
|
|
235
|
-
const hasLambdaSyncInv = configs.some(c => c
|
|
236
|
-
|
|
201
|
+
const hasOwnTopic = configs.some(c => c?.generatedCodeConfig?.invocationType === 'ownTopic' || c?.event?.includes('ownTopic'));
|
|
202
|
+
const hasLambdaSyncInv = configs.some(c => c?.generatedCodeConfig?.invocationType === 'lambdaSyncInv' || c?.event?.includes('lambdaSyncInv'));
|
|
203
|
+
_%>
|
|
237
204
|
if (requestParams.objectType === '<%= objectType %>') {
|
|
238
205
|
<%_ if (hasLambdaSyncInv) { _%>
|
|
239
|
-
const lambdaSyncInvResults =
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
lambda
|
|
243
|
-
|
|
206
|
+
const lambdaSyncInvResults = [];
|
|
207
|
+
<%_ for (const config of configs.filter(c => c?.generatedCodeConfig?.invocationType === 'lambdaSyncInv' || c?.event?.includes('lambdaSyncInv'))) { _%>
|
|
208
|
+
try {
|
|
209
|
+
const returnValue = await lambda.invokeSync(
|
|
210
|
+
_izContext,
|
|
211
|
+
await lambdaSharedLib.lambdaFunctionName(
|
|
244
212
|
_izContext,
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
213
|
+
'<%= config.flowTag %>'
|
|
214
|
+
),
|
|
215
|
+
{
|
|
216
|
+
requestParams: {
|
|
217
|
+
objType,
|
|
218
|
+
identifiers: requestParams.identifiers,
|
|
219
|
+
targetIdentifiers,
|
|
220
|
+
submittedByUserId: requestParams.submittedByUserId
|
|
221
|
+
},
|
|
222
|
+
callingFlowConfig
|
|
223
|
+
}
|
|
224
|
+
);
|
|
225
|
+
lambdaSyncInvResults.push({
|
|
226
|
+
flowTag: '<%= config.flowTag %>',
|
|
227
|
+
returnValue
|
|
228
|
+
});
|
|
229
|
+
if (returnValue?.errorsFound?.length > 0) {
|
|
230
|
+
errorsFound.push(...returnValue.errorsFound);
|
|
231
|
+
} else if (returnValue?.status === 'error') {
|
|
232
|
+
errorsFound.push('Error from <%= config.flowTag %>');
|
|
233
|
+
} else {
|
|
234
|
+
if (returnValue?.identifiers && requestParams?.identifiers) {
|
|
235
|
+
Object.assign(requestParams.identifiers, returnValue.identifiers);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
} catch (hookErr) {
|
|
239
|
+
_izContext.logger.error(
|
|
240
|
+
'[<%- flowTag %>] Sync hook <%= config.flowTag %> error:',
|
|
241
|
+
hookErr
|
|
242
|
+
);
|
|
243
|
+
errorsFound.push(hookErr.message || 'Hook <%= config.flowTag %> failed');
|
|
244
|
+
}
|
|
245
|
+
<%_ } _%>
|
|
246
|
+
|
|
247
|
+
if (errorsFound.length > 0) {
|
|
248
|
+
return await <%- flowTag %>LogicalLib(
|
|
249
|
+
_izContext,
|
|
250
|
+
requestParams,
|
|
251
|
+
callingFlowConfig,
|
|
252
|
+
errorsFound
|
|
253
|
+
);
|
|
254
|
+
}
|
|
258
255
|
<%_ } _%>
|
|
259
256
|
|
|
260
257
|
//(<afterBeforeLogical_<%= objectType %>>)
|
|
261
258
|
//(</afterBeforeLogical_<%= objectType %>>)
|
|
262
259
|
|
|
263
260
|
<%_ if (hasOwnTopic) { _%>
|
|
264
|
-
// ── ownTopic (async —
|
|
265
|
-
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
),
|
|
275
|
-
additionalAttributes: {}
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
recordMsgs.push({
|
|
279
|
-
msg: callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
|
|
280
|
-
requestParams,
|
|
261
|
+
// ── ownTopic (async — dispatch to before-hook and await callback) ──────────
|
|
262
|
+
<%_ configs.filter(c => c?.generatedCodeConfig?.invocationType === 'ownTopic' || c?.event?.includes('ownTopic')).forEach(config => { _%>
|
|
263
|
+
const hookMsg_<%= config.flowTag %> =
|
|
264
|
+
callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
|
|
265
|
+
{
|
|
266
|
+
objType,
|
|
267
|
+
identifiers: requestParams.identifiers,
|
|
268
|
+
targetIdentifiers,
|
|
269
|
+
submittedByUserId: requestParams.submittedByUserId
|
|
270
|
+
},
|
|
281
271
|
callingFlowSharedLib.addParentCallingFlowConfig(
|
|
282
272
|
callingFlowConfig,
|
|
283
273
|
callingFlowSharedLib.createCallingFlowConfig(
|
|
284
|
-
//(<callingFlowProperties_<%= config.flowTag %>>)
|
|
285
274
|
await lambdaSharedLib.lambdaFunctionName(
|
|
286
275
|
_izContext,
|
|
287
|
-
'
|
|
276
|
+
'<%- flowTag %>BeforeHookCallbackHdrSqs'
|
|
288
277
|
),
|
|
289
|
-
{
|
|
290
|
-
|
|
278
|
+
{
|
|
279
|
+
originalRequestParams: {
|
|
280
|
+
...requestParams,
|
|
281
|
+
objType,
|
|
282
|
+
targetIdentifiers
|
|
283
|
+
},
|
|
284
|
+
callingFlowConfig
|
|
285
|
+
}
|
|
291
286
|
)
|
|
292
287
|
)
|
|
293
|
-
)
|
|
294
|
-
flowTag: '<%= config.flowTag.charAt(0).toUpperCase() + config.flowTag.slice(1) %>'
|
|
295
|
-
});
|
|
296
|
-
<%_ }) _%>
|
|
297
|
-
|
|
298
|
-
<%_ if (hasLambdaSyncInv) { _%>
|
|
299
|
-
// ── Add lambdaSyncInv results to awaitingSteps ────────────────────────
|
|
300
|
-
for (const syncResult of lambdaSyncInvResults) {
|
|
301
|
-
awaitingMultipleStepIds.push({
|
|
302
|
-
awaitingStepId: await asyncFlowSharedLib.createAwaitingStepId(
|
|
303
|
-
hash(identifiers),
|
|
304
|
-
'logical_<%= objectType %>_' + syncResult.flowTag
|
|
305
|
-
),
|
|
306
|
-
additionalAttributes: {
|
|
307
|
-
complete: true,
|
|
308
|
-
errorsFound: [],
|
|
309
|
-
returnValue: syncResult.returnValue
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
<%_ } _%>
|
|
314
|
-
|
|
315
|
-
await asyncFlowSharedLib.createAwaitingMultipleSteps(
|
|
316
|
-
_izContext,
|
|
317
|
-
asyncFlowSharedLib.createPendingStepId(
|
|
318
|
-
_izContext.uniqueRequestId,
|
|
319
|
-
'logical_<%= objectType %>'
|
|
320
|
-
),
|
|
321
|
-
awaitingMultipleStepIds,
|
|
322
|
-
{
|
|
323
|
-
additionalAttributes: {
|
|
324
|
-
callingFlowConfig
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
);
|
|
328
|
-
|
|
329
|
-
//(<beforePublish_<%= objectType %>>)
|
|
330
|
-
//(</beforePublish_<%= objectType %>>)
|
|
288
|
+
);
|
|
331
289
|
|
|
332
|
-
|
|
333
|
-
|
|
290
|
+
const messageAttributes_<%= config.flowTag %> =
|
|
291
|
+
sns.createStringMessageAttributes(
|
|
334
292
|
_izContext,
|
|
335
293
|
callingFlowSharedLib.addCallingFlowToSnsResponseMessageAttributes(
|
|
336
294
|
callingFlowConfig,
|
|
@@ -338,32 +296,36 @@ export default async function <%- flowTag %>(
|
|
|
338
296
|
)
|
|
339
297
|
);
|
|
340
298
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
299
|
+
const topicArn_<%= config.flowTag %> = snsSharedLib.snsTopicArnByFlowSchema(
|
|
300
|
+
_izContext,
|
|
301
|
+
'<%= config.flowTag %>_In'
|
|
302
|
+
);
|
|
345
303
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
304
|
+
_izContext.logger.debug(
|
|
305
|
+
`[${process.env.iz_serviceTag}:<%- flowTag %>] Dispatching to BeforeHook:`,
|
|
306
|
+
{
|
|
307
|
+
topicArn: topicArn_<%= config.flowTag %>,
|
|
308
|
+
flowTag: '<%= config.flowTag %>'
|
|
309
|
+
}
|
|
310
|
+
);
|
|
352
311
|
|
|
353
|
-
|
|
312
|
+
await sns.publishAsync(_izContext, {
|
|
313
|
+
Message: JSON.stringify(hookMsg_<%= config.flowTag %>),
|
|
314
|
+
MessageAttributes: messageAttributes_<%= config.flowTag %>,
|
|
315
|
+
TopicArn: topicArn_<%= config.flowTag %>
|
|
316
|
+
});
|
|
317
|
+
<%_ }) _%>
|
|
354
318
|
|
|
319
|
+
return {
|
|
320
|
+
status: 'pending',
|
|
321
|
+
message: 'Dispatched to BeforeHook'
|
|
322
|
+
};
|
|
355
323
|
<%_ } else { _%>
|
|
356
|
-
// ── lambdaSyncInv only — collect results and proceed to deleteLogicalLib
|
|
357
|
-
const phaseResults = Object.fromEntries(
|
|
358
|
-
lambdaSyncInvResults.map(({ flowTag: tag, returnValue }) => [tag, returnValue])
|
|
359
|
-
);
|
|
360
|
-
|
|
361
324
|
return await <%- flowTag %>LogicalLib(
|
|
362
325
|
_izContext,
|
|
363
326
|
requestParams,
|
|
364
327
|
callingFlowConfig,
|
|
365
|
-
errorsFound
|
|
366
|
-
phaseResults
|
|
328
|
+
errorsFound
|
|
367
329
|
);
|
|
368
330
|
<%_ } _%>
|
|
369
331
|
}
|
|
@@ -46,6 +46,135 @@ const { TOPIC_NAME_GENERATE_CODE } = consts;
|
|
|
46
46
|
//(<optionalRequire>)
|
|
47
47
|
//(</optionalRequire>)
|
|
48
48
|
|
|
49
|
+
// ── 1. Delete_Main Helpers ───────────────────────────────────────────────────
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Loads ObjectSchema and resolves submittedByUserId and targetIdentifiers
|
|
53
|
+
* @param {Object} _izContext - Izara context object
|
|
54
|
+
* @param {Object} requestParams - Incoming request parameters
|
|
55
|
+
* @param {Array<string>} errorsFound - Array to collect validation errors
|
|
56
|
+
* @returns {Promise<{ objType: string, objectSchema: Object, targetIdentifiers?: Object }>}
|
|
57
|
+
*/
|
|
58
|
+
export async function resolveSchemaAndIdentity(
|
|
59
|
+
_izContext,
|
|
60
|
+
requestParams,
|
|
61
|
+
errorsFound
|
|
62
|
+
) {
|
|
63
|
+
const objType = createObjType(requestParams.objectType);
|
|
64
|
+
const objectSchema = await getObjectSchema.getObjSchemaS3WithHierarchy(
|
|
65
|
+
_izContext,
|
|
66
|
+
objType
|
|
67
|
+
);
|
|
68
|
+
_izContext.logger.debug(
|
|
69
|
+
`[${process.env.iz_serviceTag}:<%- flowTag %>] objectSchema:`,
|
|
70
|
+
objectSchema
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
let submittedByUserId;
|
|
74
|
+
let targetIdentifiers;
|
|
75
|
+
if (
|
|
76
|
+
objectSchema.generatedBy === 'user' ||
|
|
77
|
+
objectSchema.generatedBy === 'systemWithUser'
|
|
78
|
+
) {
|
|
79
|
+
submittedByUserId =
|
|
80
|
+
requestParams.submittedByUserId ||
|
|
81
|
+
_izContext.correlationIds.get(coreConsts.SUBMITTED_BY_USER_ID);
|
|
82
|
+
|
|
83
|
+
targetIdentifiers = requestParams.targetIdentifiers;
|
|
84
|
+
delete requestParams.targetIdentifiers;
|
|
85
|
+
|
|
86
|
+
if (
|
|
87
|
+
!targetIdentifiers &&
|
|
88
|
+
objectSchema.belongTo?.objectType === 'user' &&
|
|
89
|
+
submittedByUserId
|
|
90
|
+
) {
|
|
91
|
+
targetIdentifiers = { submittedByUserId };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!submittedByUserId) {
|
|
95
|
+
errorsFound.push('Not have submittedByUserId');
|
|
96
|
+
}
|
|
97
|
+
if (objectSchema.hasOwnProperty('belongTo') && !targetIdentifiers) {
|
|
98
|
+
errorsFound.push('not have targetIdentifiers');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
requestParams.submittedByUserId = submittedByUserId;
|
|
102
|
+
if (targetIdentifiers) {
|
|
103
|
+
if (!targetIdentifiers.submittedByUserId && submittedByUserId) {
|
|
104
|
+
targetIdentifiers.submittedByUserId = submittedByUserId;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
_izContext.logger.debug(
|
|
109
|
+
`[${process.env.iz_serviceTag}:<%- flowTag %>] Identity & Target Context Resolved:`,
|
|
110
|
+
{
|
|
111
|
+
submittedByUserId: requestParams.submittedByUserId,
|
|
112
|
+
targetIdentifiers,
|
|
113
|
+
belongTo: objectSchema.belongTo,
|
|
114
|
+
generatedBy: objectSchema.generatedBy
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return { objType, objectSchema, targetIdentifiers };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Handles delete errors and publishes error response
|
|
124
|
+
* @param {Object} _izContext - Izara context object
|
|
125
|
+
* @param {Object} options - Error context details
|
|
126
|
+
* @returns {Promise<Object>} Error status result
|
|
127
|
+
*/
|
|
128
|
+
export async function handleDeleteError(
|
|
129
|
+
_izContext,
|
|
130
|
+
{
|
|
131
|
+
objType,
|
|
132
|
+
identifiers,
|
|
133
|
+
targetIdentifiers,
|
|
134
|
+
callingFlowConfig,
|
|
135
|
+
errorsFound
|
|
136
|
+
}
|
|
137
|
+
) {
|
|
138
|
+
const deleteNodeCompleteMessage =
|
|
139
|
+
callingFlowSharedLib.addPassBackPropertiesToSnsResponseMessageObject(
|
|
140
|
+
callingFlowConfig,
|
|
141
|
+
{
|
|
142
|
+
objType,
|
|
143
|
+
identifiers,
|
|
144
|
+
targetIdentifiers,
|
|
145
|
+
status: 'error',
|
|
146
|
+
errorsFound
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
_izContext.logger.debug(
|
|
151
|
+
'messageParams OutDeleteNodeComplete::',
|
|
152
|
+
deleteNodeCompleteMessage
|
|
153
|
+
);
|
|
154
|
+
await sns.publishAsync(_izContext, {
|
|
155
|
+
Message: JSON.stringify(deleteNodeCompleteMessage),
|
|
156
|
+
MessageAttributes: sns.createStringMessageAttributes(
|
|
157
|
+
_izContext,
|
|
158
|
+
callingFlowSharedLib.addCallingFlowToSnsResponseMessageAttributes(
|
|
159
|
+
callingFlowConfig,
|
|
160
|
+
{}
|
|
161
|
+
)
|
|
162
|
+
),
|
|
163
|
+
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
164
|
+
_izContext,
|
|
165
|
+
TOPIC_NAME_GENERATE_CODE.outDeleteNodeComplete
|
|
166
|
+
)
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
objType,
|
|
171
|
+
identifiers,
|
|
172
|
+
targetIdentifiers,
|
|
173
|
+
status: 'error',
|
|
174
|
+
errorsFound
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
49
178
|
/**
|
|
50
179
|
* Core logical processing library
|
|
51
180
|
* @param {Object} _izContext - Context object with logger
|
|
@@ -93,36 +222,13 @@ export async function <%- flowTag %>LogicalLib(
|
|
|
93
222
|
|
|
94
223
|
// ── Early exit on errors ──────────────────────────────────────────────────
|
|
95
224
|
if (errorsFound.length) {
|
|
96
|
-
|
|
97
|
-
callingFlowSharedLib.addPassBackPropertiesToSnsResponseMessageObject(
|
|
98
|
-
callingFlowConfig,
|
|
99
|
-
{
|
|
100
|
-
objType,
|
|
101
|
-
identifiers: requestParams.identifiers,
|
|
102
|
-
status: 'error',
|
|
103
|
-
errorsFound
|
|
104
|
-
}
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
_izContext.logger.debug(
|
|
108
|
-
'messageParams OutDeleteNodeComplete::',
|
|
109
|
-
deleteNodeCompleteMessage
|
|
110
|
-
);
|
|
111
|
-
await sns.publishAsync(_izContext, {
|
|
112
|
-
Message: JSON.stringify(deleteNodeCompleteMessage),
|
|
113
|
-
TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
|
|
114
|
-
_izContext,
|
|
115
|
-
TOPIC_NAME_GENERATE_CODE.outDeleteNodeComplete
|
|
116
|
-
)
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
return {
|
|
225
|
+
return await handleDeleteError(_izContext, {
|
|
120
226
|
objType,
|
|
121
227
|
identifiers: requestParams.identifiers,
|
|
122
228
|
targetIdentifiers: requestParams.targetIdentifiers,
|
|
123
|
-
|
|
229
|
+
callingFlowConfig,
|
|
124
230
|
errorsFound
|
|
125
|
-
};
|
|
231
|
+
});
|
|
126
232
|
}
|
|
127
233
|
|
|
128
234
|
//(<validateBeforeDelete>)
|
|
@@ -0,0 +1,112 @@
|
|
|
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
|
+
handleUpdateError
|
|
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 handleUpdateError(_izContext, {
|
|
75
|
+
objType: originalRequestParams?.objType,
|
|
76
|
+
identifiers:
|
|
77
|
+
originalRequestParams?.objInstanceFull?.identifiers ||
|
|
78
|
+
originalRequestParams?.identifiers ||
|
|
79
|
+
{},
|
|
80
|
+
fields:
|
|
81
|
+
originalRequestParams?.objInstanceFull?.fields ||
|
|
82
|
+
{},
|
|
83
|
+
versionedDataIds: originalRequestParams?.versionedDataIds,
|
|
84
|
+
callingFlowConfig,
|
|
85
|
+
errorsFound: mergedErrors
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (returnValue?.fields && originalRequestParams?.objInstanceFull?.fields) {
|
|
90
|
+
Object.assign(originalRequestParams.objInstanceFull.fields, returnValue.fields);
|
|
91
|
+
} else if (returnValue?.fieldNames && originalRequestParams?.objInstanceFull?.fields) {
|
|
92
|
+
Object.assign(originalRequestParams.objInstanceFull.fields, returnValue.fieldNames);
|
|
93
|
+
} else if (returnValue?.fieldNames && originalRequestParams?.fieldNames) {
|
|
94
|
+
Object.assign(originalRequestParams.fieldNames, returnValue.fieldNames);
|
|
95
|
+
}
|
|
96
|
+
if (returnValue?.relationships && originalRequestParams) {
|
|
97
|
+
originalRequestParams.relationships = returnValue.relationships;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
//(<beforeLogicalExecution>)
|
|
101
|
+
//(</beforeLogicalExecution>)
|
|
102
|
+
|
|
103
|
+
return await <%- flowTag %>LogicalLib(
|
|
104
|
+
_izContext,
|
|
105
|
+
originalRequestParams,
|
|
106
|
+
callingFlowConfig
|
|
107
|
+
);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
_izContext.logger.error('[<%- upperCaseFlowTag %>BeforeHookCallback] error:', error);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|