@gadmin2n/schematics 0.0.143 → 0.0.145

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 (279) hide show
  1. package/dist/lib/application/files/gadmin2-game-angle-demo/config/.types.d.ts +10 -0
  2. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/approval.prisma +2 -0
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +140 -19
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +2 -2
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/data-mngt.seed.ts +0 -2
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +694 -327
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-outbox.ts +57 -0
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +35 -5
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +224 -59
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-executor.spec.ts +23 -0
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-executor.ts +16 -5
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.controller.spec.ts +98 -0
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.controller.ts +26 -6
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/codeRuntime/code-runtime.dto.ts +17 -2
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.controller.spec.ts +1 -0
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.controller.ts +3 -0
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-runtime.dto.ts +0 -2
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-signal-outbox.service.spec.ts +30 -0
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction-signal-outbox.service.ts +28 -6
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction.service.spec.ts +63 -0
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-interaction.service.ts +151 -38
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-wait.handler.ts +4 -1
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/human-approval.handler.spec.ts +16 -5
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/human-approval.handler.ts +23 -6
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.controller.spec.ts +130 -0
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.controller.ts +62 -62
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.dto.ts +15 -1
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.util.spec.ts +70 -9
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/httpRequest/http-request-runtime.util.ts +31 -7
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-signal-outbox.service.spec.ts +30 -0
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-signal-outbox.service.ts +28 -6
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-subject-source.util.spec.ts +50 -3
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/approval-subject-source.util.ts +26 -3
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.dto.ts +53 -47
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.errors.ts +0 -1
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.service.spec.ts +541 -0
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.service.ts +442 -200
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/outbox-retry.util.ts +1 -0
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.controller.spec.ts +150 -0
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.controller.ts +56 -40
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/runtime/human-approval-runtime.dto.ts +16 -60
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.controller.ts +13 -0
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.service.spec.ts +44 -0
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/integrationConnection/integration-connection.service.ts +6 -0
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.spec.ts +258 -12
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.ts +127 -14
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/manual-workflow-execution.spec.ts +85 -0
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/manual-workflow-execution.ts +108 -0
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/parameter-binding.ts +5 -5
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.spec.ts +96 -25
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +77 -34
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-callable.spec.ts +23 -34
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-callable.ts +0 -21
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-cancellation.spec.ts +245 -0
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.spec.ts +639 -188
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.ts +408 -235
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.types.ts +1 -3
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-data-edge.util.spec.ts +279 -95
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-data-edge.util.ts +360 -80
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-event-catalog.spec.ts +323 -0
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution-idempotency.spec.ts +773 -0
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +7 -13
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.dto.ts +0 -16
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.service.spec.ts +184 -0
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.service.ts +69 -138
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-handle-validator.spec.ts +113 -0
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-handle-validator.ts +59 -13
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-runtime.facade.ts +86 -0
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-switch-config.spec.ts +25 -0
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-switch-config.ts +45 -0
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.spec.ts +78 -43
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +103 -40
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.dto.ts +57 -0
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.module.ts +3 -1
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.spec.ts +1000 -240
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +2184 -317
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/node-config-validator.service.spec.ts +279 -2
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/node-config-validator.service.ts +5 -1
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/subject-config-validator.service.spec.ts +4 -1
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/subject-config-validator.service.ts +5 -1
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/widget-catalog.service.spec.ts +12 -3
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/widget-catalog.service.ts +10 -1
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.spec.ts +2 -24
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.ts +3 -70
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +3 -1
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/RowActions.tsx +25 -5
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/WorkflowActionButton.test.tsx +71 -0
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/WorkflowActionButton.tsx +89 -0
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/index.ts +1 -0
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/header.tsx +52 -12
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +12 -0
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/constants/layout.ts +2 -2
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddDataModal.tsx +10 -33
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddPageModal.tsx +13 -37
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DevShell.tsx +55 -7
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/style.css +14 -0
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/http.ts +10 -0
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/list.tsx +1 -0
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/workflowAction.ts +19 -0
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/index.ts +1 -0
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/types.ts +3 -1
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +1 -6
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useReferenceUpload.ts +95 -0
  104. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +2 -2
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/workflow.json +672 -110
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +2 -2
  107. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/workflow.json +676 -114
  108. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/plugins/devShellPlugin.ts +13 -1
  109. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +1 -0
  110. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasEditPage.tsx +38 -4
  111. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +276 -376
  112. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/CanvasAiModal.tsx +126 -6
  113. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/human-approval/DecisionModal.test.tsx +50 -0
  114. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/human-approval/DecisionModal.tsx +48 -11
  115. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/human-approval/inbox.tsx +32 -34
  116. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/RegisterBusinessEventModal.test.tsx +111 -0
  117. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/RegisterBusinessEventModal.tsx +167 -0
  118. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/business-events.css +99 -0
  119. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/detail.test.tsx +106 -0
  120. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/detail.tsx +324 -0
  121. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/index.test.tsx +73 -0
  122. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/business-events/index.tsx +359 -0
  123. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CanvasZoomControls.tsx +46 -0
  124. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CreateNodeInstanceDrawer.tsx +9 -1
  125. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.test.tsx +105 -4
  126. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.tsx +90 -48
  127. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DeletableEdge.tsx +3 -2
  128. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DslView.test.tsx +259 -0
  129. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DslView.tsx +167 -103
  130. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/EnhancedFlowRenderer.tsx +142 -140
  131. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExecutionStatusNode.test.tsx +60 -15
  132. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExecutionStatusNode.tsx +25 -12
  133. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/FlowRenderer.tsx +364 -200
  134. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NewNodeDefaults.test.tsx +220 -52
  135. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeOutputSummary.test.tsx +260 -0
  136. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeOutputSummary.tsx +300 -130
  137. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.test.tsx +507 -33
  138. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +630 -592
  139. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ParameterBindingEditor.tsx +67 -70
  140. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ReadonlyNodePanel.test.tsx +90 -0
  141. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ReadonlyNodePanel.tsx +325 -0
  142. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/RunWorkflowModal.test.tsx +52 -0
  143. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/RunWorkflowModal.tsx +14 -9
  144. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/StatusCards.tsx +2 -1
  145. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/VersionPanel.tsx +2 -1
  146. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/WorkflowCodeEditor.test.tsx +42 -0
  147. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/WorkflowCodeEditor.tsx +76 -0
  148. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/WorkflowWorkspaceHeader.tsx +56 -0
  149. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/parameter-binding-editor.css +46 -0
  150. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/workflow-code-editor.css +34 -0
  151. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/ConnectionModal.test.tsx +53 -7
  152. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/ConnectionModal.tsx +123 -62
  153. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/connections.css +85 -0
  154. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/connectionsApi.ts +29 -0
  155. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/index.test.tsx +75 -0
  156. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/connections/index.tsx +69 -36
  157. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.test.tsx +494 -0
  158. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +665 -194
  159. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useReferencedNodeInstanceConfigs.test.tsx +92 -0
  160. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useReferencedNodeInstanceConfigs.ts +96 -0
  161. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useWorkflowAgent.test.tsx +297 -0
  162. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useWorkflowAgent.ts +135 -65
  163. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/index.tsx +53 -42
  164. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +344 -155
  165. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instances.tsx +79 -58
  166. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/CreateNodeInstanceModal.tsx +123 -144
  167. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +169 -98
  168. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/node-instance-form.css +91 -0
  169. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/index.tsx +54 -31
  170. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/node-config.css +854 -0
  171. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/SchemaField.tsx +41 -14
  172. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/SchemaForm.test.tsx +75 -0
  173. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/SchemaForm.tsx +3 -0
  174. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/default-widgets.tsx +20 -2
  175. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/widget-registry.tsx +2 -1
  176. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/show.tsx +61 -66
  177. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApprovalRuleEditor.test.tsx +33 -1
  178. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApprovalRuleEditor.tsx +47 -15
  179. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/BranchConfigEditors.test.tsx +104 -0
  180. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CallableInputParametersEditor.tsx +22 -52
  181. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CodeConfigEditor.test.tsx +72 -0
  182. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CodeConfigEditor.tsx +78 -70
  183. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/CronTriggerConfigEditor.tsx +569 -0
  184. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/DbExecuteConfigEditor.tsx +130 -0
  185. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/DelayConfigEditor.tsx +100 -0
  186. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/EventTriggerConfigEditor.tsx +620 -0
  187. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalRequestConfigEditor.test.tsx +22 -45
  188. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalRequestConfigEditor.tsx +25 -92
  189. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ExternalWaitConfigEditor.tsx +3 -11
  190. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ForEachConfigEditor.test.tsx +58 -0
  191. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ForEachConfigEditor.tsx +107 -0
  192. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HttpRequestConfigEditor.test.tsx +212 -31
  193. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HttpRequestConfigEditor.tsx +214 -304
  194. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.test.tsx +175 -40
  195. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/HumanApprovalConfigEditor.tsx +693 -293
  196. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/IfElseConfigEditor.tsx +190 -0
  197. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ManualTriggerConfigEditor.test.tsx +152 -0
  198. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ManualTriggerConfigEditor.tsx +286 -0
  199. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ParallelConfigEditor.tsx +101 -0
  200. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ParameterBindingListEditor.tsx +99 -0
  201. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SimplifiedNodeEditors.test.tsx +495 -0
  202. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubWorkflowConfigEditor.test.tsx +124 -0
  203. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubWorkflowConfigEditor.tsx +222 -0
  204. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SubjectPicker.tsx +2 -4
  205. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SwitchConfigEditor.tsx +204 -0
  206. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/UserGroupCreateModal.tsx +3 -1
  207. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/UserGroupEditModal.tsx +9 -6
  208. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/callable-workflow.ts +4 -0
  209. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/code-config.css +96 -0
  210. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/event-catalog.api.ts +117 -0
  211. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/http-request-config.css +242 -0
  212. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/human-approval-config.css +194 -0
  213. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/show.tsx +264 -167
  214. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/temporal-tenant/index.tsx +6 -9
  215. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types/parameter-binding.ts +19 -16
  216. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +28 -4
  217. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/useWorkflowFormValidation.test.tsx +59 -0
  218. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/useWorkflowFormValidation.ts +24 -0
  219. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/forEachConnection.test.ts +311 -0
  220. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/forEachConnection.ts +198 -0
  221. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/mainFlowConnection.test.ts +143 -0
  222. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/mainFlowConnection.ts +19 -0
  223. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/newNodeConfig.ts +103 -5
  224. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/removeWorkflowEdges.test.ts +158 -3
  225. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/removeWorkflowEdges.ts +117 -9
  226. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveEffectiveOutput.test.ts +70 -0
  227. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveEffectiveOutput.ts +48 -0
  228. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveLookupPorts.test.ts +55 -0
  229. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveLookupPorts.ts +95 -22
  230. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveOutputs.test.ts +148 -1
  231. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveOutputs.ts +62 -11
  232. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveWorkflowDisplay.test.ts +19 -0
  233. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/resolveWorkflowDisplay.ts +1 -1
  234. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/subWorkflowChange.test.ts +45 -0
  235. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/subWorkflowChange.ts +26 -0
  236. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/validateWorkflowDsl.test.ts +502 -0
  237. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/validateWorkflowDsl.ts +694 -0
  238. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowDateTime.test.ts +27 -0
  239. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowDateTime.ts +33 -0
  240. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowHistory.test.ts +34 -0
  241. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowHistory.ts +52 -0
  242. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowPublishError.test.ts +99 -0
  243. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowPublishError.ts +91 -0
  244. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowSkillPrompt.test.ts +74 -0
  245. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/workflowSkillPrompt.ts +120 -0
  246. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/workflow-ui.css +481 -0
  247. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/index.css +1 -1
  248. package/package.json +1 -1
  249. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowEventOutbox.ts +0 -62
  250. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/migrate-human-approval-configs.ts +0 -86
  251. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-event-trigger.ts +0 -60
  252. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/human-approval.external-decision.spec.ts +0 -183
  253. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/humanApproval/legacy-approval-config-migration.ts +0 -227
  254. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-http-response.spec.ts +0 -82
  255. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-http-response.ts +0 -111
  256. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.spec.ts +0 -54
  257. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.ts +0 -147
  258. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.module.ts +0 -10
  259. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.spec.ts +0 -350
  260. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.ts +0 -110
  261. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/index.ts +0 -1
  262. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/InstanceRequiredDialog.tsx +0 -106
  263. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/LookupConnectionDialog.test.tsx +0 -45
  264. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/LookupConnectionDialog.tsx +0 -43
  265. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeTypeBadge.tsx +0 -36
  266. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useNodeInstanceLibrary.ts +0 -41
  267. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApproverSourceEditor.test.tsx +0 -47
  268. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ApproverSourceEditor.tsx +0 -182
  269. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ReturnResultConfigEditor.test.tsx +0 -34
  270. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/ReturnResultConfigEditor.tsx +0 -16
  271. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/approver-source.test.ts +0 -25
  272. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/approver-source.ts +0 -42
  273. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/lookupConnection.test.ts +0 -208
  274. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/lookupConnection.ts +0 -246
  275. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/create.tsx +0 -111
  276. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/edit.tsx +0 -127
  277. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/index.tsx +0 -4
  278. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/list.tsx +0 -282
  279. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/show.tsx +0 -74
@@ -2,30 +2,37 @@ interface DependencyDsl {
2
2
  nodes: Array<{
3
3
  id: string;
4
4
  type?: string;
5
- config?: {
6
- subjects?: Array<{
7
- source?: string;
8
- provider?: string;
9
- inputKey?: string;
10
- }>;
11
- };
5
+ config?: Record<string, unknown>;
12
6
  }>;
13
7
  edges: Array<{
14
8
  id?: string;
15
9
  pairId?: string;
16
- kind?: 'FLOW' | 'DATA' | 'CALL' | 'RETURN';
10
+ kind?: 'FLOW' | 'CALL' | 'RETURN';
17
11
  source: string;
18
12
  target: string;
19
13
  sourceHandle?: string;
20
14
  targetHandle?: string;
21
15
  sourcePath?: string;
16
+ valueType?: string;
22
17
  }>;
23
18
  }
24
19
 
25
20
  export function validateWorkflowDataEdges(dsl: DependencyDsl): void {
21
+ if (dsl.edges.some((edge) => edge.pairId && edge.kind === undefined))
22
+ throw new Error(
23
+ 'An edge with pairId must explicitly declare kind FLOW, CALL, or RETURN',
24
+ );
26
25
  const nodes = new Map(dsl.nodes.map((node) => [node.id, node]));
27
26
  const calls = dsl.edges.filter((edge) => edge.kind === 'CALL');
28
27
  const returns = dsl.edges.filter((edge) => edge.kind === 'RETURN');
28
+ const pairedFlows = dsl.edges.filter(
29
+ (edge) => edge.kind === 'FLOW' && edge.pairId,
30
+ );
31
+
32
+ for (const flow of pairedFlows) {
33
+ if (calls.filter((call) => call.pairId === flow.pairId).length !== 1)
34
+ throw new Error('Paired FLOW edge must belong to exactly one CALL edge');
35
+ }
29
36
 
30
37
  for (const node of dsl.nodes) {
31
38
  if (
@@ -39,111 +46,384 @@ export function validateWorkflowDataEdges(dsl: DependencyDsl): void {
39
46
 
40
47
  for (const call of calls) {
41
48
  if (!call.pairId) throw new Error('CALL edge must have a pairId');
42
- if (!call.sourceHandle?.startsWith('lookup:'))
43
- throw new Error('CALL edge must start from an AP lookup OUT port');
44
- if (call.targetHandle !== 'request-in')
45
- throw new Error('CALL edge must target HTTP Request Request IN');
46
-
47
- const apNode = nodes.get(call.source);
48
- const httpNode = nodes.get(call.target);
49
- const inputKey = call.sourceHandle.slice('lookup:'.length);
50
- const subject = apNode?.config?.subjects?.find(
51
- (item) => item.source === 'DYNAMIC' && item.inputKey === inputKey,
52
- );
53
- if (!subject)
49
+ const sourceNode = nodes.get(call.source);
50
+ if (sourceNode?.type === 'for_each')
51
+ validateForEachCall(dsl, call, returns, nodes);
52
+ else if (sourceNode?.type === 'parallel')
53
+ validateParallelCall(dsl, call, returns, nodes, sourceNode);
54
+ else
54
55
  throw new Error(
55
- `CALL edge targets unknown AP lookup "${inputKey}" on node "${call.source}"`,
56
+ 'CALL edge can only start from a For Each or Parallel node',
56
57
  );
57
- if (httpNode?.type !== 'http_request')
58
- throw new Error('AP lookup can only call an HTTP Request node');
58
+ }
59
59
 
60
- const pairedReturns = returns.filter((edge) => edge.pairId === call.pairId);
61
- if (pairedReturns.length !== 1)
62
- throw new Error(`CALL pair "${call.pairId}" must have one RETURN edge`);
63
- const result = pairedReturns[0];
60
+ for (const result of returns) {
64
61
  if (
65
- result.target !== call.source ||
66
- result.targetHandle !== `approver:${inputKey}`
62
+ !result.pairId ||
63
+ calls.filter((call) => call.pairId === result.pairId).length !== 1
67
64
  )
68
- throw new Error(
69
- `RETURN edge for "${inputKey}" must target its AP approver IN port`,
70
- );
65
+ throw new Error('RETURN edge must belong to exactly one CALL edge');
66
+ }
71
67
 
72
- const reachable = reachableCallNodes(dsl, call.target, call.pairId);
73
- if (!reachable.has(result.source))
68
+ validateForEachConnections(dsl, calls);
69
+ validateParallelConnections(dsl, calls);
70
+ validatePairOwnership(dsl, calls, returns);
71
+ }
72
+
73
+ function validatePairOwnership(
74
+ dsl: DependencyDsl,
75
+ calls: DependencyDsl['edges'],
76
+ returns: DependencyDsl['edges'],
77
+ ): void {
78
+ const owners = new Map<string, Set<string>>();
79
+ for (const call of calls) {
80
+ if (!call.pairId) continue;
81
+ const bodyIds = new Set<string>([call.target]);
82
+ for (const edge of dsl.edges) {
83
+ if (edge.kind === 'FLOW' && edge.pairId === call.pairId) {
84
+ bodyIds.add(edge.source);
85
+ bodyIds.add(edge.target);
86
+ }
87
+ }
88
+ for (const edge of returns) {
89
+ if (edge.pairId === call.pairId) bodyIds.add(edge.source);
90
+ }
91
+ for (const nodeId of bodyIds) {
92
+ const pairIds = owners.get(nodeId) ?? new Set<string>();
93
+ pairIds.add(call.pairId);
94
+ owners.set(nodeId, pairIds);
95
+ }
96
+ }
97
+ for (const [nodeId, pairIds] of owners) {
98
+ if (pairIds.size > 1)
74
99
  throw new Error(
75
- `RETURN edge for "${inputKey}" must return from the CALL chain`,
100
+ `Node "${nodeId}" cannot belong to more than one CALL pipeline`,
76
101
  );
77
- const resultNode = nodes.get(result.source);
78
- const expectedHandle =
79
- resultNode?.type === 'http_request'
80
- ? 'response-out'
81
- : resultNode?.type === 'code'
82
- ? 'result-out'
83
- : undefined;
84
- if (expectedHandle && result.sourceHandle !== expectedHandle)
102
+ }
103
+ }
104
+
105
+ const FOR_EACH_BODY_NODE_TYPES = new Set([
106
+ 'http_request',
107
+ 'code',
108
+ 'db_execute',
109
+ 'sub_workflow',
110
+ ]);
111
+ const PARALLEL_BODY_NODE_TYPES = new Set([
112
+ ...FOR_EACH_BODY_NODE_TYPES,
113
+ 'delay',
114
+ 'if_else',
115
+ 'switch',
116
+ 'approval',
117
+ 'human_approval',
118
+ 'external_wait',
119
+ ]);
120
+
121
+ function validateForEachCall(
122
+ dsl: DependencyDsl,
123
+ call: DependencyDsl['edges'][number],
124
+ returns: DependencyDsl['edges'],
125
+ nodes: Map<string, DependencyDsl['nodes'][number]>,
126
+ ): void {
127
+ if (call.sourceHandle !== 'start')
128
+ throw new Error('For Each CALL must start from START');
129
+ const result = requireSingleReturn(call, returns);
130
+ if (result.target !== call.source || result.targetHandle !== 'end')
131
+ throw new Error('For Each RETURN must target END');
132
+ if (result.valueType !== 'JSON')
133
+ throw new Error('For Each RETURN must use valueType JSON');
134
+ validatePipelineBoundaryHandles(call, result, nodes, 'For Each');
135
+
136
+ const pairFlows = dsl.edges.filter(
137
+ (edge) => edge.kind === 'FLOW' && edge.pairId === call.pairId,
138
+ );
139
+ const bodyNodeIds = linearPairBody(
140
+ call.target,
141
+ result.source,
142
+ pairFlows,
143
+ 'For Each body',
144
+ );
145
+ for (const nodeId of bodyNodeIds) {
146
+ const nodeType = nodes.get(nodeId)?.type;
147
+ if (!nodeType || !FOR_EACH_BODY_NODE_TYPES.has(nodeType))
148
+ throw new Error(`Node "${nodeId}" cannot be used in a For Each body`);
149
+ const usedByMainFlow = dsl.edges.some(
150
+ (edge) =>
151
+ edge.kind === 'FLOW' &&
152
+ !edge.pairId &&
153
+ (edge.source === nodeId || edge.target === nodeId),
154
+ );
155
+ if (usedByMainFlow)
85
156
  throw new Error(
86
- `RETURN edge for "${inputKey}" must use ${expectedHandle}`,
157
+ `For Each body node "${nodeId}" cannot also belong to the main flow`,
87
158
  );
88
159
  }
160
+ }
89
161
 
90
- for (const result of returns) {
162
+ function validateParallelCall(
163
+ dsl: DependencyDsl,
164
+ call: DependencyDsl['edges'][number],
165
+ returns: DependencyDsl['edges'],
166
+ nodes: Map<string, DependencyDsl['nodes'][number]>,
167
+ owner: DependencyDsl['nodes'][number],
168
+ ): void {
169
+ const branches = parallelBranches(owner);
170
+ const branch = branches.find(
171
+ (item) => `${item.id}-start` === call.sourceHandle,
172
+ );
173
+ if (!branch)
174
+ throw new Error('Parallel CALL must start from a configured START port');
175
+ const branchReturns = returns.filter((edge) => edge.pairId === call.pairId);
176
+ if (branchReturns.length === 0)
177
+ throw new Error('Parallel branch must return every exit to END');
178
+ for (const result of branchReturns) {
91
179
  if (
92
- !result.pairId ||
93
- calls.filter((call) => call.pairId === result.pairId).length !== 1
180
+ result.target !== call.source ||
181
+ result.targetHandle !== `${branch.id}-end`
94
182
  )
95
- throw new Error('RETURN edge must belong to exactly one CALL edge');
183
+ throw new Error('Parallel RETURN must target the matching END port');
184
+ if (result.valueType !== 'JSON')
185
+ throw new Error('Parallel RETURN must use valueType JSON');
186
+ validatePipelineBoundaryHandles(call, result, nodes, 'Parallel');
96
187
  }
97
188
 
98
- validateRequiredApprovalInputs(dsl, calls);
189
+ const pairFlows = dsl.edges.filter(
190
+ (edge) => edge.kind === 'FLOW' && edge.pairId === call.pairId,
191
+ );
192
+ const bodyNodeIds = branchedPairBody(call, pairFlows, branchReturns, nodes);
193
+ validatePipelineBodyNodes(dsl, bodyNodeIds, nodes, 'Parallel branch');
99
194
  }
100
195
 
101
- function reachableCallNodes(
102
- dsl: DependencyDsl,
103
- firstNodeId: string,
104
- pairId: string,
196
+ function validatePipelineBoundaryHandles(
197
+ call: DependencyDsl['edges'][number],
198
+ result: DependencyDsl['edges'][number],
199
+ nodes: Map<string, DependencyDsl['nodes'][number]>,
200
+ label: string,
201
+ ): void {
202
+ const callTargetHandle = namedInputHandle(nodes.get(call.target)?.type);
203
+ if ((call.targetHandle ?? '') !== (callTargetHandle ?? ''))
204
+ throw new Error(
205
+ callTargetHandle
206
+ ? `${label} CALL target must use ${callTargetHandle}`
207
+ : `${label} CALL target must not use a named handle`,
208
+ );
209
+
210
+ const returnSourceHandles = namedOutputHandles(nodes.get(result.source));
211
+ if (returnSourceHandles.length === 0 && (result.sourceHandle ?? '') !== '')
212
+ throw new Error(`${label} RETURN source must not use a named handle`);
213
+ if (
214
+ returnSourceHandles.length > 0 &&
215
+ !returnSourceHandles.includes(result.sourceHandle ?? '')
216
+ )
217
+ throw new Error(
218
+ `${label} RETURN source must use one of ${returnSourceHandles.join(
219
+ ', ',
220
+ )}`,
221
+ );
222
+ }
223
+
224
+ function namedInputHandle(nodeType?: string): string | undefined {
225
+ if (nodeType === 'http_request') return 'request-in';
226
+ if (nodeType === 'code') return 'data-in';
227
+ return undefined;
228
+ }
229
+
230
+ function namedOutputHandles(
231
+ node: DependencyDsl['nodes'][number] | undefined,
232
+ ): string[] {
233
+ if (node?.type === 'http_request') return ['response-out'];
234
+ if (node?.type === 'code') return ['result-out'];
235
+ if (['if_else', 'approval', 'human_approval'].includes(node?.type ?? ''))
236
+ return ['true', 'false'];
237
+ if (node?.type === 'external_wait') return ['RECEIVED', 'TIMEOUT'];
238
+ if (node?.type === 'switch') {
239
+ const cases = Array.isArray(node.config?.cases) ? node.config.cases : [];
240
+ return [
241
+ ...cases
242
+ .map((item) =>
243
+ item && typeof item === 'object' ? (item as any).id : undefined,
244
+ )
245
+ .filter((id): id is string => typeof id === 'string' && id.length > 0),
246
+ 'default',
247
+ ];
248
+ }
249
+ return [];
250
+ }
251
+
252
+ function branchedPairBody(
253
+ call: DependencyDsl['edges'][number],
254
+ flows: DependencyDsl['edges'],
255
+ returns: DependencyDsl['edges'],
256
+ nodes: Map<string, DependencyDsl['nodes'][number]>,
105
257
  ): Set<string> {
106
- const reachable = new Set([firstNodeId]);
258
+ const body = new Set([call.target]);
107
259
  let changed = true;
108
260
  while (changed) {
109
261
  changed = false;
110
- for (const edge of dsl.edges) {
111
- if (
112
- (edge.kind ?? 'FLOW') !== 'FLOW' ||
113
- edge.pairId !== pairId ||
114
- !reachable.has(edge.source) ||
115
- reachable.has(edge.target)
116
- )
117
- continue;
118
- reachable.add(edge.target);
262
+ for (const edge of flows) {
263
+ if (!body.has(edge.source) || body.has(edge.target)) continue;
264
+ body.add(edge.target);
119
265
  changed = true;
120
266
  }
121
267
  }
122
- return reachable;
268
+ if (
269
+ flows.some((edge) => !body.has(edge.source) || !body.has(edge.target)) ||
270
+ returns.some((edge) => !body.has(edge.source))
271
+ )
272
+ throw new Error('Parallel branch contains a disconnected edge');
273
+
274
+ for (const nodeId of body) {
275
+ const incoming = flows.filter((edge) => edge.target === nodeId);
276
+ if (
277
+ (nodeId === call.target && incoming.length > 0) ||
278
+ (nodeId !== call.target && incoming.length !== 1)
279
+ )
280
+ throw new Error('Parallel branch cannot merge paths');
281
+
282
+ const outputHandles = namedOutputHandles(nodes.get(nodeId));
283
+ const outgoing = [
284
+ ...flows.filter((edge) => edge.source === nodeId),
285
+ ...returns.filter((edge) => edge.source === nodeId),
286
+ ];
287
+ if (outputHandles.length <= 1) {
288
+ if (outgoing.length !== 1)
289
+ throw new Error(
290
+ `Parallel branch node "${nodeId}" must connect to one next node or END`,
291
+ );
292
+ continue;
293
+ }
294
+ for (const handle of outputHandles) {
295
+ if (outgoing.filter((edge) => edge.sourceHandle === handle).length !== 1)
296
+ throw new Error(
297
+ `Parallel branch node "${nodeId}" must connect every output to a next node or END`,
298
+ );
299
+ }
300
+ if (outgoing.length !== outputHandles.length)
301
+ throw new Error(
302
+ `Parallel branch node "${nodeId}" has a duplicate or invalid output`,
303
+ );
304
+ }
305
+ return body;
306
+ }
307
+
308
+ function linearPairBody(
309
+ firstNodeId: string,
310
+ returnNodeId: string,
311
+ pairFlows: DependencyDsl['edges'],
312
+ label: string,
313
+ ): Set<string> {
314
+ const bodyNodeIds = new Set<string>([firstNodeId]);
315
+ let current = firstNodeId;
316
+ while (current !== returnNodeId) {
317
+ const next = pairFlows.filter((edge) => edge.source === current);
318
+ if (next.length !== 1) throw new Error(`${label} must be one linear chain`);
319
+ current = next[0].target;
320
+ if (bodyNodeIds.has(current))
321
+ throw new Error(`${label} must not contain a cycle`);
322
+ bodyNodeIds.add(current);
323
+ }
324
+ if (pairFlows.some((edge) => edge.source === returnNodeId))
325
+ throw new Error(`${label} must end at its RETURN edge`);
326
+ if (pairFlows.length !== bodyNodeIds.size - 1)
327
+ throw new Error(`${label} must be one linear chain`);
328
+ if (
329
+ pairFlows.some(
330
+ (edge) => !bodyNodeIds.has(edge.source) || !bodyNodeIds.has(edge.target),
331
+ )
332
+ )
333
+ throw new Error(`${label} contains a disconnected FLOW edge`);
334
+ if (pairFlows.some((edge) => edge.target === firstNodeId))
335
+ throw new Error(`${label} first node cannot have a pair predecessor`);
336
+ return bodyNodeIds;
337
+ }
338
+
339
+ function requireSingleReturn(
340
+ call: DependencyDsl['edges'][number],
341
+ returns: DependencyDsl['edges'],
342
+ ): DependencyDsl['edges'][number] {
343
+ const pairedReturns = returns.filter((edge) => edge.pairId === call.pairId);
344
+ if (pairedReturns.length !== 1)
345
+ throw new Error(`CALL pair "${call.pairId}" must have one RETURN edge`);
346
+ return pairedReturns[0];
123
347
  }
124
348
 
125
- function validateRequiredApprovalInputs(
349
+ function validateForEachConnections(
126
350
  dsl: DependencyDsl,
127
351
  calls: DependencyDsl['edges'],
128
352
  ): void {
129
353
  for (const node of dsl.nodes) {
130
- for (const subject of node.config?.subjects ?? []) {
131
- if (subject.source !== 'DYNAMIC' || !subject.inputKey) continue;
132
- const callCount = calls.filter(
133
- (edge) =>
134
- edge.source === node.id &&
135
- edge.sourceHandle === `lookup:${subject.inputKey}`,
136
- ).length;
137
- const legacyCount = dsl.edges.filter(
138
- (edge) =>
139
- edge.kind === 'DATA' &&
140
- edge.target === node.id &&
141
- edge.targetHandle === subject.inputKey,
142
- ).length;
143
- if (callCount + legacyCount !== 1)
354
+ if (node.type !== 'for_each') continue;
355
+ const ownedCalls = calls.filter((call) => call.source === node.id);
356
+ if (ownedCalls.length !== 1)
357
+ throw new Error(
358
+ `For Each "${node.id}" must have one item processing connection`,
359
+ );
360
+ }
361
+ }
362
+
363
+ function validateParallelConnections(
364
+ dsl: DependencyDsl,
365
+ calls: DependencyDsl['edges'],
366
+ ): void {
367
+ for (const node of dsl.nodes) {
368
+ if (node.type !== 'parallel') continue;
369
+ const branches = parallelBranches(node);
370
+ if (branches.length < 2)
371
+ throw new Error(
372
+ `Parallel "${node.id}" must configure at least two branches`,
373
+ );
374
+ const ownedCalls = calls.filter((call) => call.source === node.id);
375
+ if (ownedCalls.length !== branches.length)
376
+ throw new Error(
377
+ `Parallel "${node.id}" must have one complete START / END pipeline per branch`,
378
+ );
379
+ for (const branch of branches) {
380
+ if (
381
+ ownedCalls.filter((call) => call.sourceHandle === `${branch.id}-start`)
382
+ .length !== 1
383
+ )
144
384
  throw new Error(
145
- `Dynamic input "${subject.inputKey}" on node "${node.id}" must have exactly one lookup connection`,
385
+ `Parallel "${node.id}" branch "${branch.label}" must have one START pipeline`,
146
386
  );
147
387
  }
148
388
  }
149
389
  }
390
+
391
+ function parallelBranches(
392
+ node: DependencyDsl['nodes'][number],
393
+ ): Array<{ id: string; label: string }> {
394
+ const branches = node.config?.branches;
395
+ return (Array.isArray(branches) ? branches : []).filter(
396
+ (item): item is { id: string; label: string } =>
397
+ Boolean(
398
+ item &&
399
+ typeof item === 'object' &&
400
+ typeof item.id === 'string' &&
401
+ item.id.length > 0 &&
402
+ typeof item.label === 'string' &&
403
+ item.label.length > 0,
404
+ ),
405
+ );
406
+ }
407
+
408
+ function validatePipelineBodyNodes(
409
+ dsl: DependencyDsl,
410
+ bodyNodeIds: Set<string>,
411
+ nodes: Map<string, DependencyDsl['nodes'][number]>,
412
+ label: string,
413
+ ): void {
414
+ for (const nodeId of bodyNodeIds) {
415
+ const nodeType = nodes.get(nodeId)?.type;
416
+ if (!nodeType || !PARALLEL_BODY_NODE_TYPES.has(nodeType))
417
+ throw new Error(`Node "${nodeId}" cannot be used in a ${label} body`);
418
+ const usedByMainFlow = dsl.edges.some(
419
+ (edge) =>
420
+ edge.kind === 'FLOW' &&
421
+ !edge.pairId &&
422
+ (edge.source === nodeId || edge.target === nodeId),
423
+ );
424
+ if (usedByMainFlow)
425
+ throw new Error(
426
+ `${label} body node "${nodeId}" cannot also belong to the main flow`,
427
+ );
428
+ }
429
+ }