@izara_project/izara-core-generate-service-code 1.0.86 → 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.
Files changed (38) hide show
  1. package/package.json +1 -1
  2. package/src/compile/loadSchemas.js +45 -10
  3. package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +1 -1
  4. package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +22 -15
  5. package/src/emit/crud/crudActionPlan.js +47 -6
  6. package/src/emit/crud/emitCrudApplicationArtifacts.js +63 -3
  7. package/src/emit/crud/emitDynamicCrudFlowSchemas.js +6 -4
  8. package/src/emit/crud/templates/CreateAfterHookCallback_Main.ejs +121 -0
  9. package/src/emit/crud/templates/CreateBeforeHookCallback_Main.ejs +108 -0
  10. package/src/emit/crud/templates/CreateEndpoint_Main.ejs +138 -335
  11. package/src/emit/crud/templates/CreateLogicalLib.ejs +205 -42
  12. package/src/emit/crud/templates/CreateNodeCallback_Main.ejs +80 -0
  13. package/src/emit/crud/templates/DeleteBeforeHookCallback_Main.ejs +99 -0
  14. package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +153 -182
  15. package/src/emit/crud/templates/DeleteLogicalLib.ejs +132 -26
  16. package/src/emit/crud/templates/UpdateBeforeHookCallback_Main.ejs +112 -0
  17. package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +166 -188
  18. package/src/emit/crud/templates/UpdateLogicalLib.ejs +2 -2
  19. package/src/emit/custom/customFlows.js +3 -1
  20. package/src/emit/function/functionYamlArtifact.js +4 -2
  21. package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +0 -3
  22. package/src/emit/rbac/emitRbacApplicationArtifacts.js +1 -116
  23. package/src/emit/rbac/templates/CancelUsage_Main.ejs +14 -10
  24. package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +14 -10
  25. package/src/emit/rbac/templates/CreateTargetRole_Main.ejs +22 -12
  26. package/src/emit/rbac/templates/GetMyPermissions_Main.ejs +14 -10
  27. package/src/emit/rbac/templates/ReservedDynamicUsage_Main.ejs +76 -34
  28. package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +12 -9
  29. package/src/emit/resource/emitResourceArtifacts.js +141 -62
  30. package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +14 -18
  31. package/src/emit/system/templates/WebSocketComplete_Yaml.ejs +4 -2
  32. package/test/createTargetRoleHandler.test.js +1 -15
  33. package/test/crudApplicationArtifacts.test.js +540 -3
  34. package/test/customFlowApplicationArtifacts.test.js +3 -5
  35. package/test/dynamicCrudFlowSchemas.test.js +5 -17
  36. package/test/dynamicRbacFlowSchemas.test.js +0 -3
  37. package/test/functionYamlArtifact.test.js +4 -2
  38. package/test/resourceArtifacts.test.js +203 -14
@@ -42,6 +42,10 @@ test('emits CRUD handlers and function YAML from schema data without reading gen
42
42
  'utf8'
43
43
  );
44
44
  assert.match(createMain, /CreateLogicalLib/);
45
+ assert.match(
46
+ createMain,
47
+ /validateFieldNames\(_izContext, requestParams, objectSchemas, errorsFound\)/
48
+ );
45
49
  assert.doesNotMatch(createMain, /FlowHook|beforeLogical|codeHookTag/);
46
50
  const yaml = await readFile(
47
51
  join(rootPath, 'app/sls_yaml/generatedCode/source/flow-objects.yml'),
@@ -239,7 +243,7 @@ test('emits a single Complete RBAC handler for Update without Graph', async () =
239
243
  );
240
244
  });
241
245
 
242
- test('emits RbacCallback and Complete handlers for Update with Graph', async () => {
246
+ test('emits Complete handlers and inlines sync RBAC for Update with Graph', async () => {
243
247
  const rootPath = await createRbacProject(false, true);
244
248
  const result = await generateCrudApplicationArtifacts(rootPath, {
245
249
  serviceTag: 'orders'
@@ -248,19 +252,25 @@ test('emits RbacCallback and Complete handlers for Update with Graph', async ()
248
252
  .map((file) => file.path)
249
253
  .filter((path) => path.includes('/FlowObjects/Update/source/'));
250
254
 
251
- assert.ok(updatePaths.includes(
255
+ assert.ok(!updatePaths.includes(
252
256
  'app/src/generatedCode/FlowObjects/Update/source/UpdateRbacCallback_Main.js'
253
257
  ));
254
258
  assert.ok(updatePaths.includes(
255
259
  'app/src/generatedCode/FlowObjects/Update/source/UpdateComplete_Main.js'
256
260
  ));
261
+ const updateMainContent = await readFile(
262
+ join(rootPath, 'app/src/generatedCode/FlowObjects/Update/source/Update_Main.js'),
263
+ 'utf8'
264
+ );
265
+ assert.match(updateMainContent, /checkRbacPermission/);
266
+ assert.match(updateMainContent, /sync: true/);
257
267
  execFileSync(
258
268
  process.execPath,
259
269
  [
260
270
  '--check',
261
271
  join(
262
272
  rootPath,
263
- 'app/src/generatedCode/FlowObjects/Update/source/UpdateRbacCallback_Main.js'
273
+ 'app/src/generatedCode/FlowObjects/Update/source/UpdateComplete_Main.js'
264
274
  )
265
275
  ],
266
276
  { stdio: 'inherit' }
@@ -411,6 +421,533 @@ test('emits targetIdentifiers passed directly to checkRbacPermission options in
411
421
  assert.match(deleteMain, /checkRbacPermission\([\s\S]*targetIdentifiers,[\s\S]*rbacObjType/);
412
422
  });
413
423
 
424
+ test('emits synchronous after-hook invocation in CreateLogicalLib when codeHookTag is after and invocationType is lambdaSyncInv', async () => {
425
+ const rootPath = await createProject(true);
426
+ const schemas = join(rootPath, 'app/src/schemas');
427
+ await writeFile(
428
+ join(schemas, 'FlowSchemas/AuditAfterCreate.js'),
429
+ "export default { flowTag: 'auditAfterCreate', event: ['lambdaSyncInv'], generatedCodeConfig: { generateCodeTag: 'create', codeHookTag: 'after', invocationType: 'lambdaSyncInv', objType: { objectType: 'order' } } };\n"
430
+ );
431
+ const result = await generateCrudApplicationArtifacts(rootPath, {
432
+ serviceTag: 'orders'
433
+ });
434
+
435
+ const createLogicalLib = await readFile(
436
+ join(
437
+ rootPath,
438
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateLogicalLib.js'
439
+ ),
440
+ 'utf8'
441
+ );
442
+ assert.match(
443
+ createLogicalLib,
444
+ /lambda\.invokeSync\(\s*_izContext,\s*await lambdaSharedLib\.lambdaFunctionName\(\s*_izContext,\s*'auditAfterCreate'\s*\)/
445
+ );
446
+ assert.match(createLogicalLib, /Hook auditAfterCreate failed/);
447
+
448
+ execFileSync(
449
+ process.execPath,
450
+ [
451
+ '--check',
452
+ join(
453
+ rootPath,
454
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateLogicalLib.js'
455
+ )
456
+ ],
457
+ { stdio: 'inherit' }
458
+ );
459
+
460
+ assert.ok(result.files.every((f) => !f.path.includes('CreateAfterHookCallback')));
461
+ });
462
+
463
+ test('emits synchronous after-hook invocation in CreateNodeCallback_Main when object has graph and hook is sync', async () => {
464
+ const rootPath = await createRbacProject(false, true);
465
+ const schemas = join(rootPath, 'app/src/schemas');
466
+ await writeFile(
467
+ join(schemas, 'FlowSchemas/AuditAfterCreate.js'),
468
+ "export default { flowTag: 'auditAfterCreate', event: ['lambdaSyncInv'], generatedCodeConfig: { generateCodeTag: 'create', codeHookTag: 'after', invocationType: 'lambdaSyncInv', objType: { objectType: 'order' } } };\n"
469
+ );
470
+ await generateCrudApplicationArtifacts(rootPath, {
471
+ serviceTag: 'orders'
472
+ });
473
+
474
+ const nodeCallbackMain = await readFile(
475
+ join(
476
+ rootPath,
477
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateNodeCallback_Main.js'
478
+ ),
479
+ 'utf8'
480
+ );
481
+ assert.match(
482
+ nodeCallbackMain,
483
+ /lambda\.invokeSync\(\s*_izContext,\s*await lambdaSharedLib\.lambdaFunctionName\(\s*_izContext,\s*'auditAfterCreate'\s*\)/
484
+ );
485
+ assert.match(nodeCallbackMain, /Hook auditAfterCreate failed/);
486
+
487
+ execFileSync(
488
+ process.execPath,
489
+ [
490
+ '--check',
491
+ join(
492
+ rootPath,
493
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateNodeCallback_Main.js'
494
+ )
495
+ ],
496
+ { stdio: 'inherit' }
497
+ );
498
+ });
499
+
500
+ test('emits async after-hook callback and SNS publish in CreateLogicalLib and flow-objects.yml', async () => {
501
+ const rootPath = await createProject(true);
502
+ const schemas = join(rootPath, 'app/src/schemas');
503
+ await writeFile(
504
+ join(schemas, 'FlowSchemas/NotifyAfterCreate.js'),
505
+ "export default { flowTag: 'notifyAfterCreate', event: ['ownTopic'], generatedCodeConfig: { generateCodeTag: 'create', codeHookTag: 'after', invocationType: 'ownTopic', objType: { objectType: 'order' } } };\n"
506
+ );
507
+ const result = await generateCrudApplicationArtifacts(rootPath, {
508
+ serviceTag: 'orders'
509
+ });
510
+
511
+ const createLogicalLib = await readFile(
512
+ join(
513
+ rootPath,
514
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateLogicalLib.js'
515
+ ),
516
+ 'utf8'
517
+ );
518
+ assert.match(createLogicalLib, /sns\.publishAsync\(_izContext,/);
519
+ assert.match(
520
+ createLogicalLib,
521
+ /snsTopicArnByFlowSchema\(\s*_izContext,\s*'notifyAfterCreate_In'\s*\)/
522
+ );
523
+ assert.match(createLogicalLib, /CreateAfterHookCallbackHdrSqs/);
524
+
525
+ const afterHookMain = await readFile(
526
+ join(
527
+ rootPath,
528
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateAfterHookCallback_Main.js'
529
+ ),
530
+ 'utf8'
531
+ );
532
+ assert.match(
533
+ afterHookMain,
534
+ /export default async function CreateAfterHookCallbackMain/
535
+ );
536
+ assert.match(
537
+ afterHookMain,
538
+ /TOPIC_NAME_GENERATE_CODE\.outCreateNodeComplete/
539
+ );
540
+
541
+ const afterHookHdrSqs = await readFile(
542
+ join(
543
+ rootPath,
544
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateAfterHookCallback_HdrSqs.js'
545
+ ),
546
+ 'utf8'
547
+ );
548
+ assert.match(afterHookHdrSqs, /CreateAfterHookCallbackMain/);
549
+
550
+ execFileSync(
551
+ process.execPath,
552
+ [
553
+ '--check',
554
+ join(
555
+ rootPath,
556
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateAfterHookCallback_Main.js'
557
+ )
558
+ ],
559
+ { stdio: 'inherit' }
560
+ );
561
+ execFileSync(
562
+ process.execPath,
563
+ [
564
+ '--check',
565
+ join(
566
+ rootPath,
567
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateAfterHookCallback_HdrSqs.js'
568
+ )
569
+ ],
570
+ { stdio: 'inherit' }
571
+ );
572
+ execFileSync(
573
+ process.execPath,
574
+ [
575
+ '--check',
576
+ join(
577
+ rootPath,
578
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateLogicalLib.js'
579
+ )
580
+ ],
581
+ { stdio: 'inherit' }
582
+ );
583
+
584
+ const yaml = await readFile(
585
+ join(rootPath, 'app/sls_yaml/generatedCode/source/flow-objects.yml'),
586
+ 'utf8'
587
+ );
588
+ assert.match(yaml, /CreateAfterHookCallbackHdrSqs:/);
589
+ assert.match(yaml, /CreateAfterHookCallback_HdrSqs\.main/);
590
+ });
591
+
592
+ test('emits async before-hook callback and SNS publish in Create_Main and flow-objects.yml', async () => {
593
+ const rootPath = await createProject(true);
594
+ const schemas = join(rootPath, 'app/src/schemas');
595
+ await writeFile(
596
+ join(schemas, 'FlowSchemas/ValidateBeforeCreate.js'),
597
+ "export default { flowTag: 'validateBeforeCreate', event: ['ownTopic'], generatedCodeConfig: { generateCodeTag: 'create', codeHookTag: 'before', invocationType: 'ownTopic' }, objType: { objectType: 'order' } };\n"
598
+ );
599
+ await generateCrudApplicationArtifacts(rootPath, {
600
+ serviceTag: 'orders'
601
+ });
602
+
603
+ const createMain = await readFile(
604
+ join(
605
+ rootPath,
606
+ 'app/src/generatedCode/FlowObjects/Create/source/Create_Main.js'
607
+ ),
608
+ 'utf8'
609
+ );
610
+ assert.match(createMain, /sns\.publishAsync\(_izContext,/);
611
+ assert.match(
612
+ createMain,
613
+ /snsTopicArnByFlowSchema\(\s*_izContext,\s*'validateBeforeCreate_In'\s*\)/
614
+ );
615
+ assert.match(createMain, /CreateBeforeHookCallbackHdrSqs/);
616
+
617
+ const beforeHookMain = await readFile(
618
+ join(
619
+ rootPath,
620
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateBeforeHookCallback_Main.js'
621
+ ),
622
+ 'utf8'
623
+ );
624
+ assert.match(
625
+ beforeHookMain,
626
+ /export default async function CreateBeforeHookCallbackMain/
627
+ );
628
+ assert.match(beforeHookMain, /CreateLogicalLib/);
629
+
630
+ const beforeHookHdrSqs = await readFile(
631
+ join(
632
+ rootPath,
633
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateBeforeHookCallback_HdrSqs.js'
634
+ ),
635
+ 'utf8'
636
+ );
637
+ assert.match(beforeHookHdrSqs, /CreateBeforeHookCallbackMain/);
638
+
639
+ execFileSync(
640
+ process.execPath,
641
+ [
642
+ '--check',
643
+ join(
644
+ rootPath,
645
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateBeforeHookCallback_Main.js'
646
+ )
647
+ ],
648
+ { stdio: 'inherit' }
649
+ );
650
+ execFileSync(
651
+ process.execPath,
652
+ [
653
+ '--check',
654
+ join(
655
+ rootPath,
656
+ 'app/src/generatedCode/FlowObjects/Create/source/CreateBeforeHookCallback_HdrSqs.js'
657
+ )
658
+ ],
659
+ { stdio: 'inherit' }
660
+ );
661
+ execFileSync(
662
+ process.execPath,
663
+ [
664
+ '--check',
665
+ join(
666
+ rootPath,
667
+ 'app/src/generatedCode/FlowObjects/Create/source/Create_Main.js'
668
+ )
669
+ ],
670
+ { stdio: 'inherit' }
671
+ );
672
+ });
673
+
674
+ test('emits sync before-hook in Create_Main with abort check', async () => {
675
+ const rootPath = await createProject(true);
676
+ const schemas = join(rootPath, 'app/src/schemas');
677
+ await writeFile(
678
+ join(schemas, 'FlowSchemas/ValidateBeforeCreateSync.js'),
679
+ "export default { flowTag: 'validateBeforeCreateSync', event: ['lambdaSyncInv'], generatedCodeConfig: { generateCodeTag: 'create', codeHookTag: 'before', invocationType: 'lambdaSyncInv' }, objType: { objectType: 'order' } };\n"
680
+ );
681
+ await generateCrudApplicationArtifacts(rootPath, {
682
+ serviceTag: 'orders'
683
+ });
684
+
685
+ const createMain = await readFile(
686
+ join(
687
+ rootPath,
688
+ 'app/src/generatedCode/FlowObjects/Create/source/Create_Main.js'
689
+ ),
690
+ 'utf8'
691
+ );
692
+ assert.match(
693
+ createMain,
694
+ /lambda\.invokeSync\(\s*_izContext,\s*await lambdaSharedLib\.lambdaFunctionName\(\s*_izContext,\s*'validateBeforeCreateSync'\s*\)/
695
+ );
696
+ assert.match(createMain, /Hook validateBeforeCreateSync failed/);
697
+
698
+ execFileSync(
699
+ process.execPath,
700
+ [
701
+ '--check',
702
+ join(
703
+ rootPath,
704
+ 'app/src/generatedCode/FlowObjects/Create/source/Create_Main.js'
705
+ )
706
+ ],
707
+ { stdio: 'inherit' }
708
+ );
709
+ });
710
+
711
+ test('emits async before-hook callback and SNS publish in Update_Main and flow-objects.yml', async () => {
712
+ const rootPath = await createProject(true);
713
+ const schemas = join(rootPath, 'app/src/schemas');
714
+ await writeFile(
715
+ join(schemas, 'FlowSchemas/ValidateBeforeUpdate.js'),
716
+ "export default { flowTag: 'validateBeforeUpdate', event: ['ownTopic'], generatedCodeConfig: { generateCodeTag: 'update', codeHookTag: 'before', invocationType: 'ownTopic' }, objType: { objectType: 'order' } };\n"
717
+ );
718
+ await generateCrudApplicationArtifacts(rootPath, {
719
+ serviceTag: 'orders'
720
+ });
721
+
722
+ const updateMain = await readFile(
723
+ join(
724
+ rootPath,
725
+ 'app/src/generatedCode/FlowObjects/Update/source/Update_Main.js'
726
+ ),
727
+ 'utf8'
728
+ );
729
+ assert.match(updateMain, /sns\.publishAsync\(_izContext,/);
730
+ assert.match(
731
+ updateMain,
732
+ /snsTopicArnByFlowSchema\(\s*_izContext,\s*'validateBeforeUpdate_In'\s*\)/
733
+ );
734
+ assert.match(updateMain, /UpdateBeforeHookCallbackHdrSqs/);
735
+
736
+ const beforeHookMain = await readFile(
737
+ join(
738
+ rootPath,
739
+ 'app/src/generatedCode/FlowObjects/Update/source/UpdateBeforeHookCallback_Main.js'
740
+ ),
741
+ 'utf8'
742
+ );
743
+ assert.match(
744
+ beforeHookMain,
745
+ /export default async function UpdateBeforeHookCallbackMain/
746
+ );
747
+ assert.match(beforeHookMain, /UpdateLogicalLib/);
748
+ assert.match(beforeHookMain, /handleUpdateError/);
749
+
750
+ const beforeHookHdrSqs = await readFile(
751
+ join(
752
+ rootPath,
753
+ 'app/src/generatedCode/FlowObjects/Update/source/UpdateBeforeHookCallback_HdrSqs.js'
754
+ ),
755
+ 'utf8'
756
+ );
757
+ assert.match(beforeHookHdrSqs, /UpdateBeforeHookCallbackMain/);
758
+
759
+ execFileSync(
760
+ process.execPath,
761
+ [
762
+ '--check',
763
+ join(
764
+ rootPath,
765
+ 'app/src/generatedCode/FlowObjects/Update/source/UpdateBeforeHookCallback_Main.js'
766
+ )
767
+ ],
768
+ { stdio: 'inherit' }
769
+ );
770
+ execFileSync(
771
+ process.execPath,
772
+ [
773
+ '--check',
774
+ join(
775
+ rootPath,
776
+ 'app/src/generatedCode/FlowObjects/Update/source/UpdateBeforeHookCallback_HdrSqs.js'
777
+ )
778
+ ],
779
+ { stdio: 'inherit' }
780
+ );
781
+ execFileSync(
782
+ process.execPath,
783
+ [
784
+ '--check',
785
+ join(
786
+ rootPath,
787
+ 'app/src/generatedCode/FlowObjects/Update/source/Update_Main.js'
788
+ )
789
+ ],
790
+ { stdio: 'inherit' }
791
+ );
792
+ });
793
+
794
+ test('emits sync before-hook in Update_Main with abort check', async () => {
795
+ const rootPath = await createProject(true);
796
+ const schemas = join(rootPath, 'app/src/schemas');
797
+ await writeFile(
798
+ join(schemas, 'FlowSchemas/ValidateBeforeUpdateSync.js'),
799
+ "export default { flowTag: 'validateBeforeUpdateSync', event: ['lambdaSyncInv'], generatedCodeConfig: { generateCodeTag: 'update', codeHookTag: 'before', invocationType: 'lambdaSyncInv' }, objType: { objectType: 'order' } };\n"
800
+ );
801
+ await generateCrudApplicationArtifacts(rootPath, {
802
+ serviceTag: 'orders'
803
+ });
804
+
805
+ const updateMain = await readFile(
806
+ join(
807
+ rootPath,
808
+ 'app/src/generatedCode/FlowObjects/Update/source/Update_Main.js'
809
+ ),
810
+ 'utf8'
811
+ );
812
+ assert.match(
813
+ updateMain,
814
+ /lambda\.invokeSync\(\s*_izContext,\s*await lambdaSharedLib\.lambdaFunctionName\(\s*_izContext,\s*'validateBeforeUpdateSync'\s*\)/
815
+ );
816
+ assert.match(updateMain, /Hook validateBeforeUpdateSync failed/);
817
+
818
+ execFileSync(
819
+ process.execPath,
820
+ [
821
+ '--check',
822
+ join(
823
+ rootPath,
824
+ 'app/src/generatedCode/FlowObjects/Update/source/Update_Main.js'
825
+ )
826
+ ],
827
+ { stdio: 'inherit' }
828
+ );
829
+ });
830
+
831
+ test('emits async before-hook callback and SNS publish in Delete_Main and flow-objects.yml', async () => {
832
+ const rootPath = await createProject(true);
833
+ const schemas = join(rootPath, 'app/src/schemas');
834
+ await writeFile(
835
+ join(schemas, 'FlowSchemas/ValidateBeforeDelete.js'),
836
+ "export default { flowTag: 'validateBeforeDelete', event: ['ownTopic'], generatedCodeConfig: { generateCodeTag: 'delete', codeHookTag: 'before', invocationType: 'ownTopic' }, objType: { objectType: 'order' } };\n"
837
+ );
838
+ await generateCrudApplicationArtifacts(rootPath, {
839
+ serviceTag: 'orders'
840
+ });
841
+
842
+ const deleteMain = await readFile(
843
+ join(
844
+ rootPath,
845
+ 'app/src/generatedCode/FlowObjects/Delete/source/Delete_Main.js'
846
+ ),
847
+ 'utf8'
848
+ );
849
+ assert.match(deleteMain, /sns\.publishAsync\(_izContext,/);
850
+ assert.match(
851
+ deleteMain,
852
+ /snsTopicArnByFlowSchema\(\s*_izContext,\s*'validateBeforeDelete_In'\s*\)/
853
+ );
854
+ assert.match(deleteMain, /DeleteBeforeHookCallbackHdrSqs/);
855
+
856
+ const beforeHookMain = await readFile(
857
+ join(
858
+ rootPath,
859
+ 'app/src/generatedCode/FlowObjects/Delete/source/DeleteBeforeHookCallback_Main.js'
860
+ ),
861
+ 'utf8'
862
+ );
863
+ assert.match(
864
+ beforeHookMain,
865
+ /export default async function DeleteBeforeHookCallbackMain/
866
+ );
867
+ assert.match(beforeHookMain, /DeleteLogicalLib/);
868
+ assert.match(beforeHookMain, /handleDeleteError/);
869
+
870
+ const beforeHookHdrSqs = await readFile(
871
+ join(
872
+ rootPath,
873
+ 'app/src/generatedCode/FlowObjects/Delete/source/DeleteBeforeHookCallback_HdrSqs.js'
874
+ ),
875
+ 'utf8'
876
+ );
877
+ assert.match(beforeHookHdrSqs, /DeleteBeforeHookCallbackMain/);
878
+
879
+ execFileSync(
880
+ process.execPath,
881
+ [
882
+ '--check',
883
+ join(
884
+ rootPath,
885
+ 'app/src/generatedCode/FlowObjects/Delete/source/DeleteBeforeHookCallback_Main.js'
886
+ )
887
+ ],
888
+ { stdio: 'inherit' }
889
+ );
890
+ execFileSync(
891
+ process.execPath,
892
+ [
893
+ '--check',
894
+ join(
895
+ rootPath,
896
+ 'app/src/generatedCode/FlowObjects/Delete/source/DeleteBeforeHookCallback_HdrSqs.js'
897
+ )
898
+ ],
899
+ { stdio: 'inherit' }
900
+ );
901
+ execFileSync(
902
+ process.execPath,
903
+ [
904
+ '--check',
905
+ join(
906
+ rootPath,
907
+ 'app/src/generatedCode/FlowObjects/Delete/source/Delete_Main.js'
908
+ )
909
+ ],
910
+ { stdio: 'inherit' }
911
+ );
912
+ });
913
+
914
+ test('emits sync before-hook in Delete_Main with abort check', async () => {
915
+ const rootPath = await createProject(true);
916
+ const schemas = join(rootPath, 'app/src/schemas');
917
+ await writeFile(
918
+ join(schemas, 'FlowSchemas/ValidateBeforeDeleteSync.js'),
919
+ "export default { flowTag: 'validateBeforeDeleteSync', event: ['lambdaSyncInv'], generatedCodeConfig: { generateCodeTag: 'delete', codeHookTag: 'before', invocationType: 'lambdaSyncInv' }, objType: { objectType: 'order' } };\n"
920
+ );
921
+ await generateCrudApplicationArtifacts(rootPath, {
922
+ serviceTag: 'orders'
923
+ });
924
+
925
+ const deleteMain = await readFile(
926
+ join(
927
+ rootPath,
928
+ 'app/src/generatedCode/FlowObjects/Delete/source/Delete_Main.js'
929
+ ),
930
+ 'utf8'
931
+ );
932
+ assert.match(
933
+ deleteMain,
934
+ /lambda\.invokeSync\(\s*_izContext,\s*await lambdaSharedLib\.lambdaFunctionName\(\s*_izContext,\s*'validateBeforeDeleteSync'\s*\)/
935
+ );
936
+ assert.match(deleteMain, /Hook validateBeforeDeleteSync failed/);
937
+
938
+ execFileSync(
939
+ process.execPath,
940
+ [
941
+ '--check',
942
+ join(
943
+ rootPath,
944
+ 'app/src/generatedCode/FlowObjects/Delete/source/Delete_Main.js'
945
+ )
946
+ ],
947
+ { stdio: 'inherit' }
948
+ );
949
+ });
950
+
414
951
  async function createProject(withCrudObject) {
415
952
  const rootPath = await mkdtemp(
416
953
  join(tmpdir(), 'generate-service-code-v2-crud-application-')
@@ -895,7 +895,7 @@ test('registers SQS queue, SNS subscription, and SNS out topic for custom flowSc
895
895
  );
896
896
  });
897
897
 
898
- test('renders RBAC Validator subscriptions in InitialSetupConfig when object has belongTo to external RBAC service', async () => {
898
+ test('uses synchronous RBAC without obsolete callback SQS subscriptions in InitialSetupConfig', async () => {
899
899
  const rootPath = await createProject();
900
900
  await writeFile(
901
901
  join(rootPath, 'app/src/schemas/ObjectSchemas/Member.js'),
@@ -920,10 +920,8 @@ test('renders RBAC Validator subscriptions in InitialSetupConfig when object has
920
920
  ),
921
921
  'utf8'
922
922
  );
923
- assert.match(initialSetupConfigContent, /serviceTag: 'UserAccount'/);
924
- assert.match(initialSetupConfigContent, /topicName: 'ValidatorRbac_Out'/);
925
- assert.match(initialSetupConfigContent, /sqsEndpoint: 'UpdateRbacCallbackHdrSqs'/);
926
- assert.match(initialSetupConfigContent, /sqsEndpoint: 'DeleteRbacCallbackHdrSqs'/);
923
+ assert.doesNotMatch(initialSetupConfigContent, /sqsEndpoint: 'UpdateRbacCallbackHdrSqs'/);
924
+ assert.doesNotMatch(initialSetupConfigContent, /sqsEndpoint: 'DeleteRbacCallbackHdrSqs'/);
927
925
  });
928
926
 
929
927
  test('deduplicates duplicate nextSteps topics across flowSteps in InitialSetupConfig', async () => {
@@ -142,7 +142,7 @@ test('generates a direct Complete step for RBAC-only Update flows', async () =>
142
142
  assert.equal(update.flowSteps[1].properties.length, 0);
143
143
  });
144
144
 
145
- test('generates RbacCallback and Complete for Create when RBAC and Graph are present', async () => {
145
+ test('generates CreateNodeCallback and Complete for Create when RBAC and Graph are present', async () => {
146
146
  const rootPath = await createProject({
147
147
  generatedBy: 'user',
148
148
  });
@@ -160,13 +160,12 @@ test('generates RbacCallback and Complete for Create when RBAC and Graph are pre
160
160
  const create = await readGeneratedFlow(rootPath, 'Create');
161
161
  assert.deepEqual(create.flowSteps.map((step) => step.stepName), [
162
162
  'Start',
163
- 'RbacCallback',
164
163
  'CreateNodeCallback',
165
164
  'Complete'
166
165
  ]);
167
166
  });
168
167
 
169
- test('uses the renamed RBAC callback step when Graph storage is present', async () => {
168
+ test('uses CreateNodeCallback step when Graph storage is present with sync RBAC', async () => {
170
169
  const rootPath = await mkdtemp(
171
170
  join(tmpdir(), 'generate-service-code-v2-crud-rbac-graph-')
172
171
  );
@@ -186,11 +185,10 @@ test('uses the renamed RBAC callback step when Graph storage is present', async
186
185
  const create = await readGeneratedFlow(rootPath, 'Create');
187
186
  assert.deepEqual(create.flowSteps.map((step) => step.stepName), [
188
187
  'Start',
189
- 'RbacCallback',
190
188
  'CreateNodeCallback',
191
189
  'Complete'
192
190
  ]);
193
- assert.deepEqual(create.flowSteps[2].properties, [
191
+ assert.deepEqual(create.flowSteps[1].properties, [
194
192
  'returnValue',
195
193
  'parentFlowId',
196
194
  'status',
@@ -199,7 +197,7 @@ test('uses the renamed RBAC callback step when Graph storage is present', async
199
197
  ]);
200
198
  });
201
199
 
202
- test('chains RbacCallback and Complete for Update with RBAC and Graph', async () => {
200
+ test('chains Start and Complete for Update with RBAC and Graph', async () => {
203
201
  const rootPath = await mkdtemp(
204
202
  join(tmpdir(), 'generate-service-code-v2-crud-update-rbac-graph-')
205
203
  );
@@ -219,19 +217,9 @@ test('chains RbacCallback and Complete for Update with RBAC and Graph', async ()
219
217
  const update = await readGeneratedFlow(rootPath, 'Update');
220
218
  assert.deepEqual(update.flowSteps.map((step) => step.stepName), [
221
219
  'Start',
222
- 'RbacCallback',
223
220
  'Complete'
224
221
  ]);
225
222
  assert.deepEqual(update.flowSteps[0].nextSteps, [
226
- { targetType: 'ownTopic', stepName: 'RbacCallback' },
227
- {
228
- targetType: 'extTopic',
229
- serviceTag: 'Rbac',
230
- topicName: 'ValidatorRbac_In',
231
- toStepNames: ['RbacCallback']
232
- }
233
- ]);
234
- assert.deepEqual(update.flowSteps[1].nextSteps, [
235
223
  { targetType: 'ownTopic', stepName: 'Complete' },
236
224
  {
237
225
  targetType: 'extTopic',
@@ -240,7 +228,7 @@ test('chains RbacCallback and Complete for Update with RBAC and Graph', async ()
240
228
  toStepNames: ['Complete']
241
229
  }
242
230
  ]);
243
- assert.deepEqual(update.flowSteps[2].properties, [
231
+ assert.deepEqual(update.flowSteps[1].properties, [
244
232
  'returnValue',
245
233
  'parentFlowId',
246
234
  'status',
@@ -24,9 +24,6 @@ const STATIC_RBAC_ACTIONS = [
24
24
  ];
25
25
 
26
26
  const STATIC_LIMIT_ACTIONS = [
27
- 'CreateRoleLimit',
28
- 'ListRoleLimits',
29
- 'DeleteRoleLimit',
30
27
  'ReservedDynamicUsage',
31
28
  'ConfirmUsage',
32
29
  'CancelUsage'