@izara_project/izara-core-generate-service-code 1.0.78 → 1.0.80

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.
Files changed (70) hide show
  1. package/package.json +2 -2
  2. package/src/compile/flowValidator.js +163 -0
  3. package/src/compile/loadSchemas.js +15 -5
  4. package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +137 -7
  5. package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +137 -17
  6. package/src/emit/crud/crudActionPlan.js +82 -0
  7. package/src/emit/crud/emitCrudApplicationArtifacts.js +169 -112
  8. package/src/emit/crud/emitDynamicCrudFlowSchemas.js +43 -65
  9. package/src/emit/crud/generateDynamicCrudFlowSchemas.js +4 -1
  10. package/src/emit/crud/templates/CreateComplete_Main.ejs +8 -3
  11. package/src/emit/crud/templates/CreateEndpoint_Main.ejs +90 -513
  12. package/src/emit/crud/templates/CreateLogicalLib.ejs +541 -0
  13. package/src/emit/crud/templates/DeleteComplete_Main.ejs +8 -3
  14. package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +93 -203
  15. package/src/emit/crud/templates/DeleteLogicalLib.ejs +213 -0
  16. package/src/emit/crud/templates/FlowEndpointRbacCallback_Main.ejs +217 -0
  17. package/src/emit/crud/templates/GetEndpoint_Main.ejs +1 -1
  18. package/src/emit/crud/templates/GetRangeEndpoint_Main.ejs +118 -37
  19. package/src/emit/crud/templates/UpdateComplete_Main.ejs +8 -3
  20. package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +92 -444
  21. package/src/emit/crud/templates/UpdateLogicalLib.ejs +477 -0
  22. package/src/emit/custom/customFlows.js +27 -2
  23. package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +1 -2
  24. package/src/emit/custom/templates/FlowEndpoint_Main.ejs +10 -3
  25. package/src/emit/custom/templates/FlowStep_Main.ejs +1 -1
  26. package/src/emit/custom/templates/s3/CreateObject_Main.ejs +1 -1
  27. package/src/emit/custom/templates/triggerCache/CheckTriggerCache_HdrSqs.ejs +2 -2
  28. package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +3 -9
  29. package/src/emit/rbac/emitRbacApplicationArtifacts.js +21 -16
  30. package/src/emit/rbac/rbacFlowTag.js +2 -7
  31. package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +148 -21
  32. package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +4 -2
  33. package/src/emit/relationship/templates/ChangeRelationshipComplete_Main.ejs +7 -2
  34. package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +6 -2
  35. package/src/emit/relationship/templates/CreateRelationshipComplete_Main.ejs +7 -2
  36. package/src/emit/relationship/templates/CreateRelationship_Main.ejs +6 -2
  37. package/src/emit/relationship/templates/DeleteRelationshipComplete_Main.ejs +7 -2
  38. package/src/emit/relationship/templates/DeleteRelationship_Main.ejs +6 -2
  39. package/src/emit/relationship/templates/GetRelationship_Main.ejs +1 -1
  40. package/src/emit/relationship/templates/MoveRelationshipComplete_Main.ejs +7 -2
  41. package/src/emit/relationship/templates/MoveRelationship_Main.ejs +6 -2
  42. package/src/emit/relationship/templates/UpdateRelationshipComplete_Main.ejs +7 -2
  43. package/src/emit/relationship/templates/UpdateRelationship_Main.ejs +6 -2
  44. package/src/emit/resource/emitResourceArtifacts.js +149 -79
  45. package/src/emit/resource/templates/DynamoDBTable_Yaml.ejs +4 -4
  46. package/src/emit/resource/templates/GeneratedLambdaRoleServiceConfig.ejs +31 -5
  47. package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +21 -0
  48. package/src/emit/resource/templates/WebSocketSubscription_Yaml.ejs +7 -0
  49. package/src/emit/shared/templates/FlowHandler_HdrApi.ejs +1 -1
  50. package/src/emit/shared/templates/FlowHandler_HdrDsq.ejs +2 -2
  51. package/src/emit/shared/templates/FlowHandler_HdrInv.ejs +1 -1
  52. package/src/emit/shared/templates/FlowHandler_HdrSqs.ejs +2 -2
  53. package/src/emit/systemText/emitSystemTextSchemas.js +246 -0
  54. package/src/emit/systemText/templates/SystemTextSchemas.ejs +10 -0
  55. package/src/generate.js +55 -8
  56. package/test/crudApplicationArtifacts.test.js +158 -19
  57. package/test/customFlowApplicationArtifacts.test.js +307 -16
  58. package/test/dynamicCrudFlowSchemas.test.js +150 -14
  59. package/test/dynamicRbacFlowSchemas.test.js +2 -2
  60. package/test/dynamicRelationshipFlowSchemas.test.js +1 -1
  61. package/test/graphDrivenFlowSchema.test.js +257 -0
  62. package/test/publicApi.test.js +14 -5
  63. package/test/resourceArtifacts.test.js +66 -19
  64. package/test/systemTextSchemas.test.js +154 -0
  65. package/src/emit/crud/templates/CreateComplete_HdrSqs.ejs +0 -99
  66. package/src/emit/crud/templates/DeleteComplete_HdrSqs.ejs +0 -99
  67. package/src/emit/crud/templates/FlowEndpointBeforeLogical_Main.ejs +0 -174
  68. package/src/emit/crud/templates/FlowEndpointComplete_Main.ejs +0 -187
  69. package/src/emit/crud/templates/UpdateComplete_HdrSqs.ejs +0 -99
  70. package/src/emit/resource/templates/ResourceBeforeLogicalYaml.ejs +0 -47
@@ -0,0 +1,541 @@
1
+ /*
2
+ Copyright (C) 2021 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
+ objectHash as hash,
20
+ identifierUuid
21
+ } from '@izara_project/izara-shared-core';
22
+ import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
23
+ import snsSharedLib from '@izara_project/izara-core-library-sns';
24
+ import asyncFlowSharedLib from '@izara_project/izara-core-library-asynchronous-flow';
25
+ import callingFlowSharedLib from '@izara_project/izara-core-library-calling-flow';
26
+ import lambdaSharedLib from '@izara_project/izara-core-library-lambda';
27
+ import {
28
+ consts as coreConsts,
29
+ NoRetryError
30
+ } from '@izara_project/izara-core-library-core';
31
+ import { consts as middlewareConsts } from '@izara_project/izara-middleware';
32
+ import {
33
+ sns,
34
+ lambda
35
+ } from '@izara_project/izara-core-library-external-request';
36
+ import {
37
+ utils,
38
+ createNodeLib,
39
+ uploadUseCase,
40
+ consts,
41
+ getObjectSchema,
42
+ identifiersObject,
43
+ dataDetailsLib
44
+ } from '@izara_project/izara-core-library-service-schemas';
45
+ import graphSharedLibs from '@izara_project/izara-core-library-graph-service';
46
+
47
+ //(<optionalRequire>)
48
+ //(</optionalRequire>)
49
+
50
+ const { createObjType, firstLetterUpperCase } = utils;
51
+ const { createDataDetailsLib } = dataDetailsLib;
52
+ const { dynamoDbIdentifiersByStorageResource, createIdentifiersByUseCase } =
53
+ identifiersObject;
54
+ const { TOPIC_NAME_GENERATE_CODE, TOPIC_NAME_GRAPH_HANDLER } = consts;
55
+
56
+ const PREFIX = {
57
+ ONE: 'one',
58
+ MANY: 'many',
59
+ CREATE_OBJECT_ASYNC: 'CreateAsyncEndpoint',
60
+ CREATE_OBJECT_ASYNC_COMPLETE: 'CreateAsyncEndpointComplete',
61
+ CREATE_OBJECT_EXTERNAL_TOPIC: 'CreateExternalTopicEndpoint'
62
+ };
63
+
64
+ /**
65
+ * Core logical processing library
66
+ * @param {Object} _izContext - Context object with logger
67
+ * @param {Object} requestParams - { fieldNames, relationships[] }
68
+ * @param {Object} callingFlowConfig - Calling flow configuration
69
+ * @param {Object} phaseResults - Results from preceding phases
70
+ * @returns {Promise<Object>} Result with objType, objInstanceFull, relationships, status, errorsFound
71
+ */
72
+ export async function <%- flowTag %>LogicalLib(
73
+ _izContext,
74
+ requestParams,
75
+ callingFlowConfig = {},
76
+ errorsFound = [],
77
+ phaseResults = {}
78
+ ) {
79
+ try {
80
+ _izContext.logger.debug('[<%- flowTag %>LogicalLib] started', {
81
+ requestParams,
82
+ callingFlowConfig,
83
+ phaseResults
84
+ });
85
+
86
+ //(<beforeCreateMainLogical>)
87
+ //(</beforeCreateMainLogical>)
88
+
89
+ const objType = createObjType(requestParams.objectType);
90
+
91
+ // ── Load schema ───────────────────────────────────────────────────────────
92
+ const objectSchema = await getObjectSchema.getObjSchemaS3WithHierarchy(
93
+ _izContext,
94
+ objType
95
+ );
96
+ _izContext.logger.debug('objectSchema', objectSchema);
97
+
98
+ const objectSchemas =
99
+ uploadUseCase.generateObjectSchemaForCombineFieldNames(
100
+ _izContext,
101
+ objectSchema
102
+ );
103
+ _izContext.logger.debug('objectSchemas', objectSchemas);
104
+
105
+ // ── Parent object ─────────────────────────────────────────────────────────
106
+ let parentObject;
107
+ if (objectSchemas.hasOwnProperty('extendObjType')) {
108
+ parentObject = await getObjectSchema.getObjSchemaS3WithHierarchy(
109
+ _izContext,
110
+ objectSchema.extendObjType
111
+ );
112
+ }
113
+
114
+ // ── Detect invocation type ────────────────────────────────────────────────
115
+ const directInvoke =
116
+ requestParams.hasOwnProperty('__context__') &&
117
+ requestParams.izEventSource?.eventSourceTag === 'DirectInvoke';
118
+
119
+ // ── Build createDataDetails ───────────────────────────────────────────────
120
+ const createDataDetails = await createDataDetailsLib(
121
+ _izContext,
122
+ objectSchemas
123
+ );
124
+ _izContext.logger.debug('createDataDetails:', createDataDetails);
125
+
126
+ // ── Build objInstanceFull identifiers ─────────────────────────────────────
127
+ const objInstanceFull = { identifiers: {}, fields: {} };
128
+
129
+ for (const fieldName of Object.keys(requestParams.fieldNames)) {
130
+ if (objectSchemas.identifierFieldNames.includes(fieldName)) {
131
+ Object.assign(objInstanceFull.identifiers, {
132
+ [fieldName]: requestParams.fieldNames[fieldName]
133
+ });
134
+ }
135
+ }
136
+
137
+ // ── Helper: extract fields per storageTag ─────────────────────────────────
138
+ function createObjInstanceFullFieldsByStorageTag(
139
+ _izContext,
140
+ storageTag,
141
+ createDataDetail
142
+ ) {
143
+ const fields = {};
144
+ for (const fieldName of Object.keys(requestParams.fieldNames)) {
145
+ if (
146
+ createDataDetails[storageTag].fieldNames.includes(fieldName) &&
147
+ createDataDetail.fieldNames.includes(fieldName) &&
148
+ !objInstanceFull.identifiers.hasOwnProperty(fieldName) &&
149
+ !fields.hasOwnProperty(fieldName)
150
+ ) {
151
+ Object.assign(fields, {
152
+ [fieldName]: requestParams.fieldNames[fieldName]
153
+ });
154
+ }
155
+ }
156
+ return fields;
157
+ }
158
+
159
+ // ── Process storage resources ─────────────────────────────────────────────
160
+ const objInstanceFullForDynamoDb = structuredClone(objInstanceFull);
161
+ const objInstanceFullForGraph = structuredClone(objInstanceFull);
162
+ const objInstanceFullForExternalTopic = structuredClone(objInstanceFull);
163
+ const parentFlowId = identifierUuid();
164
+ const allAwaitingStepsId = [];
165
+ const listOfObjectForCreates = [];
166
+ const listOfRecords = [];
167
+
168
+ if (errorsFound.length === 0) {
169
+ //(<validateBeforeCreate>)
170
+ //(</validateBeforeCreate>)
171
+
172
+ for (const [storageTag, createDataDetail] of Object.entries(
173
+ createDataDetails
174
+ )) {
175
+ //(<beforeCreate>)
176
+ //(</beforeCreate>)
177
+
178
+ // ── DynamoDB ──────────────────────────────────────────────────────────
179
+ if (createDataDetail.storageType === consts.STORAGE_TYPES.dynamoDB) {
180
+ _izContext.logger.debug('::::::DynamoDB::::::', {
181
+ storageTag,
182
+ objInstanceFull
183
+ });
184
+
185
+ if (
186
+ parentObject &&
187
+ createDataDetail.tableName.includes(
188
+ firstLetterUpperCase(`${parentObject.objectType}Records`)
189
+ )
190
+ ) {
191
+ Object.assign(objInstanceFullForDynamoDb.fields, {
192
+ [`${parentObject.objectType}HandlerServiceTag`]:
193
+ process.env.iz_serviceTag
194
+ });
195
+ }
196
+
197
+ Object.assign(
198
+ objInstanceFullForDynamoDb.fields,
199
+ createObjInstanceFullFieldsByStorageTag(
200
+ _izContext,
201
+ storageTag,
202
+ createDataDetail
203
+ )
204
+ );
205
+
206
+ _izContext.logger.debug(
207
+ 'objInstanceFull before create item in dynamoDB',
208
+ objInstanceFullForDynamoDb
209
+ );
210
+
211
+ const identifiersForCreateData =
212
+ await dynamoDbIdentifiersByStorageResource(
213
+ _izContext,
214
+ objectSchema,
215
+ createDataDetails,
216
+ objInstanceFullForDynamoDb.identifiers
217
+ );
218
+ _izContext.logger.debug(
219
+ 'identifiersForCreateData',
220
+ identifiersForCreateData
221
+ );
222
+
223
+ //(<beforeCreateRecordDynamo>)
224
+ //(</beforeCreateRecordDynamo>)
225
+
226
+ if (
227
+ Object.values(createDataDetails).some(
228
+ (createDataDetail) =>
229
+ createDataDetail.storageType === consts.STORAGE_TYPES.graph
230
+ )
231
+ ) {
232
+ _izContext.logger.debug('must process graph first');
233
+ listOfRecords.push({
234
+ [storageTag]: {
235
+ serviceTag: createDataDetail.serviceTag,
236
+ tableName: createDataDetail.tableName,
237
+ objInstanceFull: {
238
+ identifiers: identifiersForCreateData,
239
+ fields: objInstanceFullForDynamoDb.fields
240
+ }
241
+ }
242
+ });
243
+ } else {
244
+ _izContext.logger.debug('can process record dynamo');
245
+ await dynamodbSharedLib.putItem(
246
+ _izContext,
247
+ dynamodbSharedLib.tableName(
248
+ _izContext,
249
+ createDataDetail.tableName,
250
+ createDataDetail.serviceTag
251
+ ),
252
+ {
253
+ ...identifiersForCreateData,
254
+ ...objInstanceFullForDynamoDb.fields
255
+ }
256
+ );
257
+
258
+ objInstanceFullForDynamoDb.fields = {};
259
+ }
260
+
261
+ //(<afterCreateRecordDynamo>)
262
+ //(</afterCreateRecordDynamo>)
263
+
264
+ // ── Graph ─────────────────────────────────────────────────────────────
265
+ } else if (
266
+ createDataDetail.storageType === consts.STORAGE_TYPES.graph
267
+ ) {
268
+ //(<beforeCreateNode>)
269
+ //(</beforeCreateNode>)
270
+ _izContext.logger.debug('::::::Graph::::::', {
271
+ storageTag,
272
+ objInstanceFull
273
+ });
274
+
275
+ Object.assign(
276
+ objInstanceFullForGraph.fields,
277
+ createObjInstanceFullFieldsByStorageTag(
278
+ _izContext,
279
+ storageTag,
280
+ createDataDetail
281
+ )
282
+ );
283
+ _izContext.logger.debug(
284
+ 'objInstanceFull before send to Graph',
285
+ objInstanceFullForGraph
286
+ );
287
+
288
+ //(<additionalAttributeCreateNode>)
289
+ const additionalAttributes = {};
290
+ //(</additionalAttributeCreateNode>)
291
+
292
+ const records = allAwaitingStepsId.length === 0 ? listOfRecords : [];
293
+ allAwaitingStepsId.push({
294
+ awaitingStepId: await asyncFlowSharedLib.createAwaitingStepId(
295
+ parentFlowId,
296
+ PREFIX.CREATE_OBJECT_ASYNC
297
+ ),
298
+ additionalAttributes: {
299
+ listOfRecords: records,
300
+ additionalAttributes: additionalAttributes
301
+ }
302
+ });
303
+
304
+ listOfObjectForCreates.push({
305
+ [storageTag]: {
306
+ objInstanceFull: {
307
+ identifiers: objInstanceFullForGraph.identifiers,
308
+ fields: objInstanceFullForGraph.fields
309
+ },
310
+ allStorageTagComplete: false
311
+ }
312
+ });
313
+
314
+ // ── External Topic ────────────────────────────────────────────────────
315
+ } else if (
316
+ createDataDetail.storageType === consts.STORAGE_TYPES.externalTopic
317
+ ) {
318
+ _izContext.logger.debug('::::::externalTopic::::::', {
319
+ storageTag,
320
+ createDataDetail
321
+ });
322
+ //(<beforeSendMessageToExternalTopic>)
323
+ //(</beforeSendMessageToExternalTopic>)
324
+
325
+ Object.assign(
326
+ objInstanceFullForExternalTopic.fields,
327
+ createObjInstanceFullFieldsByStorageTag(
328
+ _izContext,
329
+ storageTag,
330
+ createDataDetail
331
+ )
332
+ );
333
+ _izContext.logger.debug(
334
+ 'objInstanceFull before send to external topic',
335
+ objInstanceFullForExternalTopic
336
+ );
337
+
338
+ allAwaitingStepsId.push({
339
+ awaitingStepId: await asyncFlowSharedLib.createAwaitingStepId(
340
+ parentFlowId,
341
+ PREFIX.CREATE_OBJECT_EXTERNAL_TOPIC
342
+ ),
343
+ additionalAttributes: {}
344
+ });
345
+
346
+ Object.assign(objInstanceFullForExternalTopic, {
347
+ parentFlowId: parentFlowId
348
+ });
349
+
350
+ await sns.publishAsync(_izContext, {
351
+ Message: JSON.stringify(objInstanceFullForExternalTopic),
352
+ TopicArn: `arn:aws:sns:${createDataDetail.region}:${createDataDetail.accountId}:${createDataDetail.serviceTag}_${createDataDetail.stage}_Create_In`
353
+ });
354
+ }
355
+ }
356
+ }
357
+
358
+ // ── Create awaiting multiple steps ────────────────────────────────────────
359
+ if (allAwaitingStepsId.length > 0) {
360
+ _izContext.logger.debug('not api will create awaitingStep');
361
+ await asyncFlowSharedLib.createAwaitingMultipleSteps(
362
+ _izContext,
363
+ asyncFlowSharedLib.createPendingStepId(
364
+ _izContext.uniqueRequestId,
365
+ PREFIX.CREATE_OBJECT_ASYNC_COMPLETE
366
+ ),
367
+ allAwaitingStepsId,
368
+ {
369
+ additionalAttributes: {
370
+ callingFlowConfig
371
+ }
372
+ }
373
+ );
374
+ }
375
+
376
+ // ── Process graph objects ─────────────────────────────────────────────────
377
+ let messageObject = {};
378
+ for (const objectCreate of listOfObjectForCreates) {
379
+ for (const [graphServiceName, objectForCreate] of Object.entries(
380
+ objectCreate
381
+ )) {
382
+ _izContext.logger.debug('Loop each graph:', {
383
+ [graphServiceName]: objectForCreate
384
+ });
385
+
386
+ if (!objectForCreate.allStorageTagComplete) {
387
+ //(<beforeSendMessageToGraph>)
388
+ //(</beforeSendMessageToGraph>)
389
+ messageObject = {
390
+ objType,
391
+ objInstanceFull: objectForCreate.objInstanceFull,
392
+ deepPathConditional: requestParams.deepPathConditional || [],
393
+ setFieldConditionals: requestParams.setFieldConditionals || [],
394
+ relationships: requestParams.relationships || [],
395
+ parentFlowId: parentFlowId
396
+ };
397
+ }
398
+
399
+ if (errorsFound.length > 0) break;
400
+
401
+ Object.assign(messageObject, {
402
+ settings: { updatePropertiesOnMatch: false },
403
+ originTimestamp: Date.now()
404
+ });
405
+
406
+ messageObject =
407
+ callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
408
+ messageObject,
409
+ callingFlowSharedLib.addParentCallingFlowConfig(
410
+ callingFlowConfig,
411
+ callingFlowSharedLib.createCallingFlowConfig(
412
+ //(<callingFlowProperties>)
413
+ await lambdaSharedLib.lambdaFunctionName(
414
+ _izContext,
415
+ TOPIC_NAME_GENERATE_CODE.createNodeComplete
416
+ ),
417
+ {}
418
+ //(</callingFlowProperties>)
419
+ )
420
+ )
421
+ );
422
+
423
+ await sns.publishAsync(_izContext, {
424
+ Message: JSON.stringify(messageObject),
425
+ TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
426
+ _izContext,
427
+ TOPIC_NAME_GRAPH_HANDLER.inCreateNode,
428
+ graphServiceName
429
+ )
430
+ });
431
+
432
+ //(<afterSendMessageToGraph>)
433
+ //(</afterSendMessageToGraph>)
434
+ return {
435
+ objType,
436
+ objInstanceFull: objInstanceFullForGraph,
437
+ relationships: requestParams.relationships || [],
438
+ status: 'complete',
439
+ errorsFound
440
+ };
441
+ }
442
+ if (errorsFound.length > 0) break;
443
+ }
444
+
445
+ // ── Handle errors ─────────────────────────────────────────────────────────
446
+ if (errorsFound.length > 0) {
447
+ _izContext.logger.debug('Case have errorsFound:::', errorsFound);
448
+
449
+ await asyncFlowSharedLib.clearAllAwaitingSteps(
450
+ _izContext,
451
+ asyncFlowSharedLib.createPendingStepId(
452
+ _izContext.uniqueRequestId,
453
+ PREFIX.CREATE_OBJECT_ASYNC_COMPLETE
454
+ )
455
+ );
456
+
457
+ messageObject =
458
+ callingFlowSharedLib.addPassBackPropertiesToSnsResponseMessageObject(
459
+ callingFlowConfig,
460
+ { objType, identifiers: null, errorsFound }
461
+ );
462
+
463
+ await sns.publishAsync(_izContext, {
464
+ Message: JSON.stringify(messageObject),
465
+ MessageAttributes: sns.createStringMessageAttributes(
466
+ _izContext,
467
+ callingFlowSharedLib.addCallingFlowToSnsResponseMessageAttributes(
468
+ callingFlowConfig,
469
+ {}
470
+ )
471
+ ),
472
+ TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
473
+ _izContext,
474
+ TOPIC_NAME_GENERATE_CODE.outCreateNodeComplete
475
+ )
476
+ });
477
+
478
+ return {
479
+ objType,
480
+ objInstanceFull,
481
+ relationships: requestParams.relationships || [],
482
+ status: 'error',
483
+ errorsFound
484
+ };
485
+ }
486
+
487
+ // ── DynamoDB-only complete path ───────────────────────────────────────────
488
+ if (
489
+ allAwaitingStepsId.length === 0 &&
490
+ listOfObjectForCreates.length === 0
491
+ ) {
492
+ const outMessage =
493
+ callingFlowSharedLib.addPassBackPropertiesToSnsResponseMessageObject(
494
+ callingFlowConfig,
495
+ {
496
+ objType: objType,
497
+ objInstanceFull: {
498
+ identifiers: objInstanceFullForDynamoDb.identifiers,
499
+ fields: objInstanceFullForDynamoDb.fields
500
+ }
501
+ }
502
+ );
503
+
504
+ if (
505
+ callingFlowConfig[callingFlowSharedLib.consts.CALLINGFLOW_PROPERTYNAME]
506
+ ) {
507
+ _izContext.logger.debug('HAVE CallingFlow');
508
+ await sns.publishAsync(_izContext, {
509
+ Message: JSON.stringify(outMessage),
510
+ MessageAttributes: sns.createStringMessageAttributes(
511
+ _izContext,
512
+ callingFlowSharedLib.addCallingFlowToSnsResponseMessageAttributes(
513
+ callingFlowConfig,
514
+ {}
515
+ )
516
+ ),
517
+ TopicArn: snsSharedLib.snsTopicArnByFlowSchema(
518
+ _izContext,
519
+ TOPIC_NAME_GENERATE_CODE.outCreateNodeComplete
520
+ )
521
+ });
522
+ }
523
+ }
524
+
525
+ return {
526
+ objType,
527
+ objInstanceFull: {
528
+ identifiers: objInstanceFullForDynamoDb.identifiers,
529
+ fields: objInstanceFullForDynamoDb.fields
530
+ },
531
+ relationships: requestParams.relationships || [],
532
+ status: 'complete',
533
+ errorsFound
534
+ };
535
+ } catch (err) {
536
+ throw err;
537
+ }
538
+ }
539
+
540
+ export const <%- flowTag %>MainLogical = <%- flowTag %>LogicalLib;
541
+ export default <%- flowTag %>LogicalLib;
@@ -118,8 +118,10 @@ export default async function DeleteComplete(
118
118
  }
119
119
  : null;
120
120
  if (status === 'complete') {
121
+ const listOfRecords =
122
+ result?.additionalAttributes?.listOfRecords ?? [];
121
123
  await Promise.all(
122
- (pending.listOfRecords ?? []).flatMap((records) =>
124
+ (listOfRecords ?? []).flatMap((records) =>
123
125
  Object.values(records).map(async (record) =>
124
126
  dynamodbSharedLib.putItem(
125
127
  _izContext,
@@ -137,9 +139,12 @@ export default async function DeleteComplete(
137
139
  )
138
140
  );
139
141
  }
142
+ const callingFlowConfig =
143
+ result?.additionalAttributes?.callingFlowConfig ||
144
+ passBackProperties;
140
145
  const message =
141
146
  callingFlowSharedLib.addParentPassBackPropertiesToSnsResponseMessageObject(
142
- passBackProperties,
147
+ callingFlowConfig,
143
148
  {
144
149
  objType: returnValue.requestParams.objType,
145
150
  objInstanceFull: node.objInstanceFull,
@@ -152,7 +157,7 @@ export default async function DeleteComplete(
152
157
  );
153
158
  const messageAttributes =
154
159
  callingFlowSharedLib.addParentPassBackCallingFlowToSnsResponseMessageAttributes(
155
- passBackProperties,
160
+ callingFlowConfig,
156
161
  {}
157
162
  );
158
163
  const topicArn = snsSharedLib.snsTopicArnByFlowSchema(