@solidxai/core 0.1.13-beta.3 → 0.1.13-beta.5

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 (141) hide show
  1. package/dist/commands/seed.command.d.ts +2 -0
  2. package/dist/commands/seed.command.d.ts.map +1 -1
  3. package/dist/commands/seed.command.js +21 -0
  4. package/dist/commands/seed.command.js.map +1 -1
  5. package/dist/controllers/chatter-message.controller.d.ts +5 -0
  6. package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
  7. package/dist/controllers/chatter-message.controller.js +14 -0
  8. package/dist/controllers/chatter-message.controller.js.map +1 -1
  9. package/dist/entities/workflow-trigger-execution.entity.js +1 -1
  10. package/dist/entities/workflow-trigger-execution.entity.js.map +1 -1
  11. package/dist/index.d.ts +2 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +2 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/interfaces.d.ts +1 -0
  16. package/dist/interfaces.d.ts.map +1 -1
  17. package/dist/interfaces.js.map +1 -1
  18. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  19. package/dist/seeders/module-metadata-seeder.service.js +44 -27
  20. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  21. package/dist/seeders/seed-data/solid-core-metadata.json +84 -70
  22. package/dist/services/chatter-message.service.d.ts +5 -0
  23. package/dist/services/chatter-message.service.d.ts.map +1 -1
  24. package/dist/services/chatter-message.service.js +18 -0
  25. package/dist/services/chatter-message.service.js.map +1 -1
  26. package/dist/services/workflow/nodes/execution-fail.node.d.ts +6 -0
  27. package/dist/services/workflow/nodes/execution-fail.node.d.ts.map +1 -0
  28. package/dist/services/workflow/nodes/execution-fail.node.js +81 -0
  29. package/dist/services/workflow/nodes/execution-fail.node.js.map +1 -0
  30. package/dist/services/workflow/nodes/for-each.node.d.ts +2 -0
  31. package/dist/services/workflow/nodes/for-each.node.d.ts.map +1 -1
  32. package/dist/services/workflow/nodes/for-each.node.js +114 -5
  33. package/dist/services/workflow/nodes/for-each.node.js.map +1 -1
  34. package/dist/services/workflow/nodes/if.node.d.ts.map +1 -1
  35. package/dist/services/workflow/nodes/if.node.js +7 -0
  36. package/dist/services/workflow/nodes/if.node.js.map +1 -1
  37. package/dist/services/workflow/nodes/log-write.node.d.ts.map +1 -1
  38. package/dist/services/workflow/nodes/log-write.node.js +2 -0
  39. package/dist/services/workflow/nodes/log-write.node.js.map +1 -1
  40. package/dist/services/workflow/nodes/loop-until.node.d.ts +12 -0
  41. package/dist/services/workflow/nodes/loop-until.node.d.ts.map +1 -0
  42. package/dist/services/workflow/nodes/loop-until.node.js +281 -0
  43. package/dist/services/workflow/nodes/loop-until.node.js.map +1 -0
  44. package/dist/services/workflow/nodes/parallel.node.d.ts.map +1 -1
  45. package/dist/services/workflow/nodes/parallel.node.js +7 -0
  46. package/dist/services/workflow/nodes/parallel.node.js.map +1 -1
  47. package/dist/services/workflow/nodes/sequential.node.d.ts.map +1 -1
  48. package/dist/services/workflow/nodes/sequential.node.js +7 -0
  49. package/dist/services/workflow/nodes/sequential.node.js.map +1 -1
  50. package/dist/services/workflow/nodes/switch.node.d.ts.map +1 -1
  51. package/dist/services/workflow/nodes/switch.node.js +7 -0
  52. package/dist/services/workflow/nodes/switch.node.js.map +1 -1
  53. package/dist/services/workflow/workflow-definition-validator.service.d.ts.map +1 -1
  54. package/dist/services/workflow/workflow-definition-validator.service.js +5 -2
  55. package/dist/services/workflow/workflow-definition-validator.service.js.map +1 -1
  56. package/dist/services/workflow/workflow-expression.service.d.ts.map +1 -1
  57. package/dist/services/workflow/workflow-expression.service.js +5 -0
  58. package/dist/services/workflow/workflow-expression.service.js.map +1 -1
  59. package/dist/services/workflow/workflow-node-registry.service.d.ts +2 -1
  60. package/dist/services/workflow/workflow-node-registry.service.d.ts.map +1 -1
  61. package/dist/services/workflow/workflow-node-registry.service.js +7 -0
  62. package/dist/services/workflow/workflow-node-registry.service.js.map +1 -1
  63. package/dist/services/workflow/workflow-runtime.service.d.ts +8 -0
  64. package/dist/services/workflow/workflow-runtime.service.d.ts.map +1 -1
  65. package/dist/services/workflow/workflow-runtime.service.js +197 -32
  66. package/dist/services/workflow/workflow-runtime.service.js.map +1 -1
  67. package/dist/solid-core.module.d.ts.map +1 -1
  68. package/dist/solid-core.module.js +4 -0
  69. package/dist/solid-core.module.js.map +1 -1
  70. package/dist/types/workflow-dsl.types.d.ts +14 -0
  71. package/dist/types/workflow-dsl.types.d.ts.map +1 -1
  72. package/dist/types/workflow-dsl.types.js.map +1 -1
  73. package/dist-tests/api/authenticate.spec.js +119 -0
  74. package/dist-tests/api/authenticate.spec.js.map +1 -0
  75. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +97 -0
  76. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +1 -0
  77. package/dist-tests/api/ping.spec.js +21 -0
  78. package/dist-tests/api/ping.spec.js.map +1 -0
  79. package/dist-tests/helpers/auth.js +41 -0
  80. package/dist-tests/helpers/auth.js.map +1 -0
  81. package/dist-tests/helpers/env.js +11 -0
  82. package/dist-tests/helpers/env.js.map +1 -0
  83. package/docs/agent-builder/notebook-lm-prompt-for-agent-builder.md +136 -0
  84. package/docs/agent-builder/team-ready-note-agent-builder.md +305 -0
  85. package/docs/agent-hub-grooming.md +301 -0
  86. package/docs/dashboards/AGENTIC_DASHBOARD_IMPLEMENTATION_PLAN.md +438 -0
  87. package/docs/dashboards/dashboard-curl-smoke-tests.txt +146 -0
  88. package/docs/dashboards/delete-legacy-dashboard-metadata.sql +172 -0
  89. package/docs/datasource-introspection-ddl-analysis.md +326 -0
  90. package/docs/datasource-introspection-implementation-plan.md +306 -0
  91. package/docs/grouping-enhancements.md +89 -0
  92. package/docs/java-spring/README.md +3 -0
  93. package/docs/java-spring/solid-core-module-deep-dive-report.md +1317 -0
  94. package/docs/module-package-import-handoff.md +691 -0
  95. package/docs/seed-changes.md +65 -0
  96. package/docs/test-data-workflow.md +200 -0
  97. package/docs/type-declaration-import-issue.md +24 -0
  98. package/docs/workflow/business-automation-example-notes.md +309 -0
  99. package/docs/workflow/control-flow-node-addition-sop.md +324 -0
  100. package/docs/workflow/data-engineering-pipeline-example-notes.md +330 -0
  101. package/docs/workflow/foreach-example-notes.md +187 -0
  102. package/docs/workflow/hello-world-example-notes.md +271 -0
  103. package/docs/workflow/kestra-concepts-plugins-blueprints.md +315 -0
  104. package/docs/workflow/loop-until-example-notes.md +198 -0
  105. package/docs/workflow/microservices-and-apis-example-notes.md +264 -0
  106. package/docs/workflow/samples.md +25 -0
  107. package/docs/workflow/what-is-kestra.md +79 -0
  108. package/docs/workflow/workflow-core-module-handoff-summary.md +191 -0
  109. package/docs/workflow/workflow-module-brd.md +185 -0
  110. package/docs/workflow/workflow-module-domain-model.md +252 -0
  111. package/docs/workflow/workflow-module-metadata-dsl.md +302 -0
  112. package/docs/workflow/workflow-module-technical-spec.md +293 -0
  113. package/docs/workflow/workflow-node-type-contracts.md +635 -0
  114. package/docs/workflow/workflow-node-ui-metadata-contract.md +1262 -0
  115. package/docs/workflow/workflow-solidx-model-field-spec.md +284 -0
  116. package/package.json +1 -1
  117. package/src/commands/seed.command.ts +19 -0
  118. package/src/controllers/chatter-message.controller.ts +8 -0
  119. package/src/entities/workflow-trigger-execution.entity.ts +1 -1
  120. package/src/index.ts +2 -0
  121. package/src/interfaces.ts +1 -0
  122. package/src/seeders/module-metadata-seeder.service.ts +50 -36
  123. package/src/seeders/seed-data/solid-core-metadata.json +84 -70
  124. package/src/services/chatter-message.service.ts +26 -0
  125. package/src/services/workflow/nodes/execution-fail.node.ts +82 -0
  126. package/src/services/workflow/nodes/for-each.node.ts +140 -6
  127. package/src/services/workflow/nodes/if.node.ts +7 -0
  128. package/src/services/workflow/nodes/log-write.node.ts +2 -0
  129. package/src/services/workflow/nodes/loop-until.node.ts +343 -0
  130. package/src/services/workflow/nodes/parallel.node.ts +7 -0
  131. package/src/services/workflow/nodes/sequential.node.ts +7 -0
  132. package/src/services/workflow/nodes/switch.node.ts +7 -0
  133. package/src/services/workflow/workflow-definition-validator.service.ts +5 -2
  134. package/src/services/workflow/workflow-expression.service.ts +5 -0
  135. package/src/services/workflow/workflow-node-registry.service.ts +11 -0
  136. package/src/services/workflow/workflow-runtime.service.ts +274 -39
  137. package/src/solid-core.module.ts +4 -0
  138. package/src/types/workflow-dsl.types.ts +43 -0
  139. package/.claude/settings.local.json +0 -16
  140. package/CLAUDE.md +0 -26
  141. package/src/services/1.js +0 -6
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop-until.node.js","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/loop-until.node.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAqD;AACrD,2GAA4F;AAmIrF,IAAM,aAAa,GAAnB,MAAM,aAAa;IACxB,KAAK,CAAC,OAAO,CACX,OAAqC;QAErC,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC;QACvD,MAAM,SAAS,GAAG,aAAa,CAAC,SAAS,IAAI,aAAa,CAAC,UAAU,CAAC;QACtE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,4BAAmB,CAAC,6CAA6C,CAAC,CAAC;QAC/E,CAAC;QAED,MAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAC/C,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,cAAc,IAAI,EAAE,EAAE,OAAO,CAAC,CAC5E,CAAC;QACF,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,IAAI,gBAAgB,GAAG,KAAK,CAAC;QAC7B,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,IAAI,kBAAkB,GAAwB,EAAE,CAAC;QAEjD,OAAO,IAAI,EAAE,CAAC;YACZ,cAAc,IAAI,CAAC,CAAC;YACpB,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG;gBACjC,cAAc;gBACd,gBAAgB,EAAE,KAAK;gBACvB,UAAU,EAAE,KAAK;aAClB,CAAC;YAEF,MAAM,gBAAgB,GAAG;gBACvB,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;aAC3B,CAAC;YAEF,kBAAkB,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE;gBACtD,OAAO,EAAE,gBAAgB;aAC1B,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;YAEjD,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,SAAS,EAAE;gBACjE,GAAG,OAAO;gBACV,OAAO,EAAE,OAAO,CAAC,OAAO;aACzB,CAAC,CAAC;YAEH,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG;gBACjC,cAAc;gBACd,gBAAgB;gBAChB,UAAU,EAAE,KAAK;gBACjB,aAAa,EAAE,kBAAkB;aAClC,CAAC;YAEF,MAAM,OAAO,CAAC,OAAO,CAAC;gBACpB,KAAK,EAAE,MAAM;gBACb,SAAS,EAAE,0BAA0B;gBACrC,MAAM,EAAE,WAAW;gBACnB,OAAO,EAAE,mBAAmB,OAAO,CAAC,IAAI,CAAC,EAAE,eAAe,cAAc,iBAAiB,gBAAgB,GAAG;gBAC5G,OAAO,EAAE;oBACP,SAAS;oBACT,cAAc;oBACd,gBAAgB;iBACjB;aACF,CAAC,CAAC;YAEH,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM;YACR,CAAC;YAED,UAAU,GAAG,IAAI,CAAC,mBAAmB,CACnC,cAAc,EACd,SAAS,EACT,cAAc,CACf,CAAC;YACF,IAAI,UAAU,EAAE,CAAC;gBACf,IAAI,cAAc,CAAC,gBAAgB,EAAE,CAAC;oBACpC,MAAM,IAAI,4BAAmB,CAC3B,cAAc,OAAO,CAAC,IAAI,CAAC,EAAE,+EAA+E,CAC7G,CAAC;gBACJ,CAAC;gBACD,MAAM;YACR,CAAC;YAED,IAAI,cAAc,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;gBAClC,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QAED,OAAO;YACL,MAAM,EAAE;gBACN,cAAc;gBACd,gBAAgB;gBAChB,UAAU;gBACV,aAAa,EAAE,kBAAkB;aAClC;SACF,CAAC;IACJ,CAAC;IAEO,qBAAqB,CAAC,KAAU;QACtC,MAAM,cAAc,GAClB,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,MAAM,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAChD,cAAc,CAAC,aAAa,EAC5B,8BAA8B,CAC/B,CAAC;QACF,MAAM,aAAa,GACjB,cAAc,CAAC,WAAW,KAAK,SAAS;YACxC,cAAc,CAAC,WAAW,KAAK,IAAI;YACnC,cAAc,CAAC,WAAW,KAAK,EAAE;YAC/B,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,WAAW,EAAE,4BAA4B,CAAC,CAAC;QAErF,OAAO;YACL,UAAU,EAAE,IAAI,CAAC,eAAe,CAC9B,cAAc,CAAC,QAAQ,IAAI,MAAM,EACjC,yBAAyB,CAC1B;YACD,aAAa;YACb,aAAa;YACb,gBAAgB,EAAE,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,gBAAgB,CAAC;SACvE,CAAC;IACJ,CAAC;IAEO,mBAAmB,CACzB,cAAsB,EACtB,SAAiB,EACjB,cAGC;QAED,OAAO,CACL,CAAC,cAAc,CAAC,aAAa,KAAK,SAAS;YACzC,cAAc,IAAI,cAAc,CAAC,aAAa,CAAC;YACjD,CAAC,cAAc,CAAC,aAAa,KAAK,SAAS;gBACzC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,cAAc,CAAC,aAAa,CAAC,CAC1D,CAAC;IACJ,CAAC;IAEO,uBAAuB,CAAC,KAAU,EAAE,KAAa;QACvD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YAC1D,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,4BAAmB,CAAC,GAAG,KAAK,8BAA8B,CAAC,CAAC;QACxE,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAEO,eAAe,CAAC,KAAU,EAAE,KAAa;QAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACzC,MAAM,IAAI,4BAAmB,CAAC,GAAG,KAAK,mCAAmC,CAAC,CAAC;YAC7E,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,CAAC;QACX,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QAED,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CACxB,kEAAkE,CACnE,CAAC;QACF,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC;YACnD,OAAO,CACL,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;gBACvC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;gBACnC,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI;gBAChC,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,IAAI,CAC5B,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAC9D,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YACpC,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,UAAU,GACd,IAAI,KAAK,IAAI;gBACX,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,IAAI,KAAK,GAAG;oBACZ,CAAC,CAAC,IAAI;oBACN,CAAC,CAAC,IAAI,KAAK,GAAG;wBACZ,CAAC,CAAC,EAAE,GAAG,IAAI;wBACX,CAAC,CAAC,IAAI,KAAK,GAAG;4BACZ,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI;4BAChB,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;YAChC,OAAO,MAAM,GAAG,UAAU,CAAC;QAC7B,CAAC;QAED,MAAM,IAAI,4BAAmB,CAAC,GAAG,KAAK,2DAA2D,CAAC,CAAC;IACrG,CAAC;IAEO,cAAc,CAAC,KAAU;QAC/B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,EAAU;QACtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;CACF,CAAA;AAlNY,sCAAa;wBAAb,aAAa;IArHzB,IAAA,uDAAoB,EAAC;QACpB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,cAAc;QACxB,KAAK,EAAE,YAAY;QACnB,WAAW,EAAE,+DAA+D;QAC5E,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,CAAC;QACnD,SAAS,EAAE;YACT,oBAAoB,EAAE;gBACpB,SAAS,EAAE,yCAAyC;gBACpD,cAAc,EAAE;oBACd,QAAQ,EAAE,MAAM;oBAChB,gBAAgB,EAAE,KAAK;iBACxB;aACF;YACD,mBAAmB,EAAE;gBACnB,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE;oBACJ;wBACE,GAAG,EAAE,WAAW;wBAChB,KAAK,EAAE,WAAW;wBAClB,MAAM,EAAE,CAAC,WAAW,CAAC;qBACtB;oBACD;wBACE,GAAG,EAAE,YAAY;wBACjB,KAAK,EAAE,YAAY;wBACnB,MAAM,EAAE,CAAC,YAAY,CAAC;qBACvB;iBACF;aACF;YACD,mBAAmB,EAAE;gBACnB;oBACE,GAAG,EAAE,WAAW;oBAChB,KAAK,EAAE,WAAW;oBAClB,WAAW,EACT,6GAA6G;oBAC/G,SAAS,EAAE,YAAY;oBACvB,QAAQ,EAAE,IAAI;oBACd,iBAAiB,EAAE,IAAI;oBACvB,UAAU,EAAE,UAAU;oBACtB,KAAK,EAAE,WAAW;oBAClB,QAAQ,EAAE;wBACR,MAAM,EAAE;4BACN,KAAK,EAAE,MAAM;yBACd;qBACF;iBACF;gBACD;oBACE,GAAG,EAAE,gBAAgB;oBACrB,KAAK,EAAE,iBAAiB;oBACxB,WAAW,EACT,uFAAuF;oBACzF,SAAS,EAAE,QAAQ;oBACnB,iBAAiB,EAAE,IAAI;oBACvB,UAAU,EAAE,aAAa;oBACzB,KAAK,EAAE,YAAY;oBACnB,QAAQ,EAAE;wBACR,MAAM,EAAE;4BACN,KAAK,EAAE,MAAM;yBACd;wBACD,MAAM,EAAE;4BACN,MAAM,EAAE,gCAAgC;yBACzC;qBACF;iBACF;aACF;YACD,UAAU,EAAE;gBACV;oBACE,GAAG,EAAE,OAAO;oBACZ,KAAK,EAAE,WAAW;oBAClB,WAAW,EAAE,mDAAmD;oBAChE,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,YAAY;oBACpB,QAAQ,EAAE,IAAI;iBACf;gBACD;oBACE,GAAG,EAAE,QAAQ;oBACb,KAAK,EAAE,QAAQ;oBACf,WAAW,EAAE,iDAAiD;oBAC9D,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,YAAY;iBACrB;aACF;YACD,OAAO,EAAE;gBACP;oBACE,GAAG,EAAE,gBAAgB;oBACrB,KAAK,EAAE,iBAAiB;oBACxB,WAAW,EAAE,0CAA0C;oBACvD,SAAS,EAAE,QAAQ;oBACnB,IAAI,EAAE,gBAAgB;iBACvB;gBACD;oBACE,GAAG,EAAE,kBAAkB;oBACvB,KAAK,EAAE,mBAAmB;oBAC1B,WAAW,EAAE,gEAAgE;oBAC7E,SAAS,EAAE,SAAS;oBACpB,IAAI,EAAE,kBAAkB;iBACzB;aACF;YACD,mBAAmB,EAAE,IAAI;YACzB,YAAY,EAAE,IAAI;SACnB;QACD,aAAa,EAAE;YACb,OAAO,EACL,+IAA+I;SAClJ;QACD,EAAE,EAAE;YACF,IAAI,EAAE,WAAW;YACjB,SAAS,EAAE,SAAS;YACpB,mBAAmB,EAAE,SAAS;YAC9B,eAAe,EAAE,SAAS;YAC1B,SAAS,EAAE,IAAI;YACf,WAAW,EAAE;gBACX,UAAU,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC;aACxC;SACF;KACF,CAAC;GACW,aAAa,CAkNzB","sourcesContent":["import { BadRequestException } from '@nestjs/common';\nimport { WorkflowNodeProvider } from '../../../decorators/workflow-node-provider.decorator';\nimport { WorkflowNodeHandler } from '../../../interfaces/workflow-node-handler.interface';\nimport {\n WorkflowNodeExecutionContext,\n WorkflowNodeHandlerResult,\n} from '../../../types/workflow-dsl.types';\n\ntype LoopUntilCheckFrequency = {\n interval?: string | number;\n maxIterations?: string | number;\n maxDuration?: string | number;\n failOnMaxReached?: boolean | string;\n};\n\n@WorkflowNodeProvider({\n type: 'loopUntil',\n kind: 'control',\n category: 'control-flow',\n label: 'Loop Until',\n description: 'Runs child nodes repeatedly until a condition evaluates true.',\n tags: ['loop', 'iteration', 'condition', 'polling'],\n authoring: {\n defaultConfiguration: {\n condition: '{{ outputs.checkStatus.ready == true }}',\n checkFrequency: {\n interval: 'PT1M',\n failOnMaxReached: false,\n },\n },\n configurationLayout: {\n type: 'tabs',\n tabs: [\n {\n key: 'condition',\n label: 'Condition',\n groups: ['Condition'],\n },\n {\n key: 'guardrails',\n label: 'Guardrails',\n groups: ['Guardrails'],\n },\n ],\n },\n configurationFields: [\n {\n key: 'condition',\n label: 'Condition',\n description:\n 'Boolean expression evaluated after each loop iteration. It can read outputs from the latest child-node run.',\n valueType: 'expression',\n required: true,\n expressionAllowed: true,\n widgetHint: 'textarea',\n group: 'Condition',\n uiSchema: {\n layout: {\n width: 'full',\n },\n },\n },\n {\n key: 'checkFrequency',\n label: 'Check Frequency',\n description:\n 'Optional loop guardrails: interval, maxIterations, maxDuration, and failOnMaxReached.',\n valueType: 'object',\n expressionAllowed: true,\n widgetHint: 'yaml-editor',\n group: 'Guardrails',\n uiSchema: {\n layout: {\n width: 'full',\n },\n editor: {\n height: 'min(320px, calc(90vh - 360px))',\n },\n },\n },\n ],\n childSlots: [\n {\n key: 'tasks',\n label: 'Loop Body',\n description: 'Nodes that run before the condition is evaluated.',\n kind: 'sequence',\n layout: 'sequential',\n required: true,\n },\n {\n key: 'errors',\n label: 'Errors',\n description: 'Nodes that run sequentially if this loop fails.',\n kind: 'sequence',\n layout: 'sequential',\n },\n ],\n outputs: [\n {\n key: 'iterationCount',\n label: 'Iteration Count',\n description: 'Number of loop body iterations that ran.',\n valueType: 'number',\n path: 'iterationCount',\n },\n {\n key: 'conditionMatched',\n label: 'Condition Matched',\n description: 'Whether the loop stopped because the condition evaluated true.',\n valueType: 'boolean',\n path: 'conditionMatched',\n },\n ],\n supportsDescription: true,\n supportsName: true,\n },\n documentation: {\n summary:\n 'Runs the loop body, evaluates the condition, and repeats after the configured interval until the condition is true or a guardrail is reached.',\n },\n ui: {\n icon: 'si-repeat',\n iconColor: '#0f766e',\n iconBackgroundColor: '#ccfbf1',\n iconBorderColor: '#99f6e4',\n modalSize: 'lg',\n layoutHints: {\n groupOrder: ['Condition', 'Guardrails'],\n },\n },\n})\nexport class LoopUntilNode implements WorkflowNodeHandler {\n async execute(\n context: WorkflowNodeExecutionContext,\n ): Promise<WorkflowNodeHandlerResult> {\n const configuration = context.node.configuration ?? {};\n const condition = configuration.condition ?? configuration.expression;\n if (!condition) {\n throw new BadRequestException('loopUntil requires configuration.condition.');\n }\n\n const checkFrequency = this.resolveCheckFrequency(\n context.expression.interpolate(configuration.checkFrequency ?? {}, context),\n );\n const childNodes = context.node.tasks ?? [];\n const startedAt = Date.now();\n let iterationCount = 0;\n let conditionMatched = false;\n let maxReached = false;\n let latestChildOutputs: Record<string, any> = {};\n\n while (true) {\n iterationCount += 1;\n context.outputs[context.node.id] = {\n iterationCount,\n conditionMatched: false,\n maxReached: false,\n };\n\n const iterationOutputs = {\n ...(context.outputs ?? {}),\n };\n\n latestChildOutputs = await context.runNodes(childNodes, {\n outputs: iterationOutputs,\n });\n\n Object.assign(context.outputs, iterationOutputs);\n\n conditionMatched = context.expression.evaluateCondition(condition, {\n ...context,\n outputs: context.outputs,\n });\n\n context.outputs[context.node.id] = {\n iterationCount,\n conditionMatched,\n maxReached: false,\n latestOutputs: latestChildOutputs,\n };\n\n await context.emitLog({\n level: 'info',\n eventType: 'node.loopUntil.evaluated',\n source: 'loopUntil',\n message: `LoopUntil node \"${context.node.id}\" iteration ${iterationCount} evaluated to ${conditionMatched}.`,\n context: {\n condition,\n iterationCount,\n conditionMatched,\n },\n });\n\n if (conditionMatched) {\n break;\n }\n\n maxReached = this.hasReachedGuardrail(\n iterationCount,\n startedAt,\n checkFrequency,\n );\n if (maxReached) {\n if (checkFrequency.failOnMaxReached) {\n throw new BadRequestException(\n `loopUntil \"${context.node.id}\" reached its maximum check frequency guardrail before the condition matched.`,\n );\n }\n break;\n }\n\n if (checkFrequency.intervalMs > 0) {\n await this.delay(checkFrequency.intervalMs);\n }\n }\n\n return {\n output: {\n iterationCount,\n conditionMatched,\n maxReached,\n latestOutputs: latestChildOutputs,\n },\n };\n }\n\n private resolveCheckFrequency(value: any) {\n const checkFrequency: LoopUntilCheckFrequency =\n value && typeof value === 'object' && !Array.isArray(value) ? value : {};\n const maxIterations = this.optionalPositiveInteger(\n checkFrequency.maxIterations,\n 'checkFrequency.maxIterations',\n );\n const maxDurationMs =\n checkFrequency.maxDuration === undefined ||\n checkFrequency.maxDuration === null ||\n checkFrequency.maxDuration === ''\n ? undefined\n : this.parseDurationMs(checkFrequency.maxDuration, 'checkFrequency.maxDuration');\n\n return {\n intervalMs: this.parseDurationMs(\n checkFrequency.interval ?? 'PT1M',\n 'checkFrequency.interval',\n ),\n maxIterations,\n maxDurationMs,\n failOnMaxReached: this.resolveBoolean(checkFrequency.failOnMaxReached),\n };\n }\n\n private hasReachedGuardrail(\n iterationCount: number,\n startedAt: number,\n checkFrequency: {\n maxIterations?: number;\n maxDurationMs?: number;\n },\n ): boolean {\n return (\n (checkFrequency.maxIterations !== undefined &&\n iterationCount >= checkFrequency.maxIterations) ||\n (checkFrequency.maxDurationMs !== undefined &&\n Date.now() - startedAt >= checkFrequency.maxDurationMs)\n );\n }\n\n private optionalPositiveInteger(value: any, label: string): number | undefined {\n if (value === undefined || value === null || value === '') {\n return undefined;\n }\n\n const parsed = Number(value);\n if (!Number.isFinite(parsed) || parsed < 1) {\n throw new BadRequestException(`${label} must be a positive integer.`);\n }\n\n return Math.floor(parsed);\n }\n\n private parseDurationMs(value: any, label: string): number {\n if (typeof value === 'number') {\n if (!Number.isFinite(value) || value < 0) {\n throw new BadRequestException(`${label} must be a non-negative duration.`);\n }\n return value;\n }\n\n const raw = String(value ?? '').trim();\n if (!raw) {\n return 0;\n }\n\n if (/^\\d+$/.test(raw)) {\n return Number(raw);\n }\n\n const isoMatch = raw.match(\n /^P(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+(?:\\.\\d+)?)S)?)?$/i,\n );\n if (isoMatch) {\n const [, days, hours, minutes, seconds] = isoMatch;\n return (\n Number(days ?? 0) * 24 * 60 * 60 * 1000 +\n Number(hours ?? 0) * 60 * 60 * 1000 +\n Number(minutes ?? 0) * 60 * 1000 +\n Number(seconds ?? 0) * 1000\n );\n }\n\n const unitMatch = raw.match(/^(\\d+(?:\\.\\d+)?)(ms|s|m|h|d)$/i);\n if (unitMatch) {\n const amount = Number(unitMatch[1]);\n const unit = unitMatch[2].toLowerCase();\n const multiplier =\n unit === 'ms'\n ? 1\n : unit === 's'\n ? 1000\n : unit === 'm'\n ? 60 * 1000\n : unit === 'h'\n ? 60 * 60 * 1000\n : 24 * 60 * 60 * 1000;\n return amount * multiplier;\n }\n\n throw new BadRequestException(`${label} must be milliseconds, 1s/1m style, or ISO-8601 duration.`);\n }\n\n private resolveBoolean(value: any): boolean {\n if (value === true || value === 'true') {\n return true;\n }\n\n return false;\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"parallel.node.d.ts","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/parallel.node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qDAAqD,CAAC;AAC1F,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EAC1B,MAAM,mCAAmC,CAAC;AAE3C,qBAiCa,YAAa,YAAW,mBAAmB;IAChD,OAAO,CACX,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,yBAAyB,CAAC;CAqCtC"}
1
+ {"version":3,"file":"parallel.node.d.ts","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/parallel.node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qDAAqD,CAAC;AAC1F,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EAC1B,MAAM,mCAAmC,CAAC;AAE3C,qBAwCa,YAAa,YAAW,mBAAmB;IAChD,OAAO,CACX,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,yBAAyB,CAAC;CAqCtC"}
@@ -57,6 +57,13 @@ exports.ParallelNode = ParallelNode = __decorate([
57
57
  layout: 'parallel',
58
58
  required: true,
59
59
  },
60
+ {
61
+ key: 'errors',
62
+ label: 'Errors',
63
+ description: 'Nodes that run sequentially if this parallel branch fails.',
64
+ kind: 'sequence',
65
+ layout: 'sequential',
66
+ },
60
67
  ],
61
68
  supportsDescription: true,
62
69
  supportsName: true,
@@ -1 +1 @@
1
- {"version":3,"file":"parallel.node.js","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/parallel.node.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2GAA4F;AAwCrF,IAAM,YAAY,GAAlB,MAAM,YAAY;IACvB,KAAK,CAAC,OAAO,CACX,OAAqC;QAErC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAE5C,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,CACnC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC5B,MAAM,gBAAgB,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;YAC/C,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACnE,MAAM,OAAO,GAAG,EAAE,GAAG,gBAAgB,EAAE,CAAC;YAExC,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE;gBAC7B,OAAO;aACR,CAAC,CAAC;YAEH,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAClD,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;gBACpB,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBAClC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBACnB,CAAC;gBACD,OAAO,GAAG,CAAC;YACb,CAAC,EACD,EAAyB,CAC1B,CAAC;YAEF,OAAO;gBACL,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,aAAa;aACvB,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;QAEF,OAAO;YACL,MAAM,EAAE;gBACN,KAAK,EAAE,WAAW;aACnB;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAxCY,oCAAY;uBAAZ,YAAY;IAjCxB,IAAA,uDAAoB,EAAC;QACpB,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,cAAc;QACxB,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,yDAAyD;QACtE,IAAI,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC;QACjC,SAAS,EAAE;YACT,oBAAoB,EAAE,EAAE;YACxB,UAAU,EAAE;gBACV;oBACE,GAAG,EAAE,OAAO;oBACZ,KAAK,EAAE,OAAO;oBACd,WAAW,EAAE,oCAAoC;oBACjD,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,UAAU;oBAClB,QAAQ,EAAE,IAAI;iBACf;aACF;YACD,mBAAmB,EAAE,IAAI;YACzB,YAAY,EAAE,IAAI;SACnB;QACD,aAAa,EAAE;YACb,OAAO,EAAE,0DAA0D;SACpE;QACD,EAAE,EAAE;YACF,IAAI,EAAE,mBAAmB;YACzB,SAAS,EAAE,SAAS;YACpB,mBAAmB,EAAE,SAAS;YAC9B,eAAe,EAAE,SAAS;YAC1B,SAAS,EAAE,IAAI;SAChB;KACF,CAAC;GACW,YAAY,CAwCxB","sourcesContent":["import { WorkflowNodeProvider } from '../../../decorators/workflow-node-provider.decorator';\nimport { WorkflowNodeHandler } from '../../../interfaces/workflow-node-handler.interface';\nimport {\n WorkflowNodeExecutionContext,\n WorkflowNodeHandlerResult,\n} from '../../../types/workflow-dsl.types';\n\n@WorkflowNodeProvider({\n type: 'parallel',\n kind: 'control',\n category: 'control-flow',\n label: 'Parallel',\n description: 'Runs child tasks concurrently and returns task outputs.',\n tags: ['parallel', 'concurrency'],\n authoring: {\n defaultConfiguration: {},\n childSlots: [\n {\n key: 'tasks',\n label: 'Tasks',\n description: 'Child tasks that run concurrently.',\n kind: 'sequence',\n layout: 'parallel',\n required: true,\n },\n ],\n supportsDescription: true,\n supportsName: true,\n },\n documentation: {\n summary: 'Runs child tasks concurrently and returns their outputs.',\n },\n ui: {\n icon: 'si-objects-column',\n iconColor: '#2563eb',\n iconBackgroundColor: '#dbeafe',\n iconBorderColor: '#bfdbfe',\n modalSize: 'lg',\n },\n})\nexport class ParallelNode implements WorkflowNodeHandler {\n async execute(\n context: WorkflowNodeExecutionContext,\n ): Promise<WorkflowNodeHandlerResult> {\n const childTasks = context.node.tasks ?? [];\n\n const taskResults = await Promise.all(\n childTasks.map(async (task) => {\n const inheritedOutputs = context.outputs ?? {};\n const inheritedOutputKeys = new Set(Object.keys(inheritedOutputs));\n const outputs = { ...inheritedOutputs };\n\n await context.runNodes([task], {\n outputs,\n });\n\n const branchOutputs = Object.entries(outputs).reduce(\n (acc, [key, value]) => {\n if (!inheritedOutputKeys.has(key)) {\n acc[key] = value;\n }\n return acc;\n },\n {} as Record<string, any>,\n );\n\n return {\n id: task.id,\n name: task.name,\n outputs: branchOutputs,\n };\n }),\n );\n\n return {\n output: {\n tasks: taskResults,\n },\n };\n }\n}\n"]}
1
+ {"version":3,"file":"parallel.node.js","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/parallel.node.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2GAA4F;AA+CrF,IAAM,YAAY,GAAlB,MAAM,YAAY;IACvB,KAAK,CAAC,OAAO,CACX,OAAqC;QAErC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAE5C,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,CACnC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC5B,MAAM,gBAAgB,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;YAC/C,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACnE,MAAM,OAAO,GAAG,EAAE,GAAG,gBAAgB,EAAE,CAAC;YAExC,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE;gBAC7B,OAAO;aACR,CAAC,CAAC;YAEH,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAClD,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;gBACpB,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBAClC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBACnB,CAAC;gBACD,OAAO,GAAG,CAAC;YACb,CAAC,EACD,EAAyB,CAC1B,CAAC;YAEF,OAAO;gBACL,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,aAAa;aACvB,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;QAEF,OAAO;YACL,MAAM,EAAE;gBACN,KAAK,EAAE,WAAW;aACnB;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAxCY,oCAAY;uBAAZ,YAAY;IAxCxB,IAAA,uDAAoB,EAAC;QACpB,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,cAAc;QACxB,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,yDAAyD;QACtE,IAAI,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC;QACjC,SAAS,EAAE;YACT,oBAAoB,EAAE,EAAE;YACxB,UAAU,EAAE;gBACV;oBACE,GAAG,EAAE,OAAO;oBACZ,KAAK,EAAE,OAAO;oBACd,WAAW,EAAE,oCAAoC;oBACjD,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,UAAU;oBAClB,QAAQ,EAAE,IAAI;iBACf;gBACD;oBACE,GAAG,EAAE,QAAQ;oBACb,KAAK,EAAE,QAAQ;oBACf,WAAW,EAAE,4DAA4D;oBACzE,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,YAAY;iBACrB;aACF;YACD,mBAAmB,EAAE,IAAI;YACzB,YAAY,EAAE,IAAI;SACnB;QACD,aAAa,EAAE;YACb,OAAO,EAAE,0DAA0D;SACpE;QACD,EAAE,EAAE;YACF,IAAI,EAAE,mBAAmB;YACzB,SAAS,EAAE,SAAS;YACpB,mBAAmB,EAAE,SAAS;YAC9B,eAAe,EAAE,SAAS;YAC1B,SAAS,EAAE,IAAI;SAChB;KACF,CAAC;GACW,YAAY,CAwCxB","sourcesContent":["import { WorkflowNodeProvider } from '../../../decorators/workflow-node-provider.decorator';\nimport { WorkflowNodeHandler } from '../../../interfaces/workflow-node-handler.interface';\nimport {\n WorkflowNodeExecutionContext,\n WorkflowNodeHandlerResult,\n} from '../../../types/workflow-dsl.types';\n\n@WorkflowNodeProvider({\n type: 'parallel',\n kind: 'control',\n category: 'control-flow',\n label: 'Parallel',\n description: 'Runs child tasks concurrently and returns task outputs.',\n tags: ['parallel', 'concurrency'],\n authoring: {\n defaultConfiguration: {},\n childSlots: [\n {\n key: 'tasks',\n label: 'Tasks',\n description: 'Child tasks that run concurrently.',\n kind: 'sequence',\n layout: 'parallel',\n required: true,\n },\n {\n key: 'errors',\n label: 'Errors',\n description: 'Nodes that run sequentially if this parallel branch fails.',\n kind: 'sequence',\n layout: 'sequential',\n },\n ],\n supportsDescription: true,\n supportsName: true,\n },\n documentation: {\n summary: 'Runs child tasks concurrently and returns their outputs.',\n },\n ui: {\n icon: 'si-objects-column',\n iconColor: '#2563eb',\n iconBackgroundColor: '#dbeafe',\n iconBorderColor: '#bfdbfe',\n modalSize: 'lg',\n },\n})\nexport class ParallelNode implements WorkflowNodeHandler {\n async execute(\n context: WorkflowNodeExecutionContext,\n ): Promise<WorkflowNodeHandlerResult> {\n const childTasks = context.node.tasks ?? [];\n\n const taskResults = await Promise.all(\n childTasks.map(async (task) => {\n const inheritedOutputs = context.outputs ?? {};\n const inheritedOutputKeys = new Set(Object.keys(inheritedOutputs));\n const outputs = { ...inheritedOutputs };\n\n await context.runNodes([task], {\n outputs,\n });\n\n const branchOutputs = Object.entries(outputs).reduce(\n (acc, [key, value]) => {\n if (!inheritedOutputKeys.has(key)) {\n acc[key] = value;\n }\n return acc;\n },\n {} as Record<string, any>,\n );\n\n return {\n id: task.id,\n name: task.name,\n outputs: branchOutputs,\n };\n }),\n );\n\n return {\n output: {\n tasks: taskResults,\n },\n };\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"sequential.node.d.ts","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/sequential.node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qDAAqD,CAAC;AAC1F,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EAC1B,MAAM,mCAAmC,CAAC;AAE3C,qBAiCa,cAAe,YAAW,mBAAmB;IAClD,OAAO,CACX,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,yBAAyB,CAAC;CActC"}
1
+ {"version":3,"file":"sequential.node.d.ts","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/sequential.node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qDAAqD,CAAC;AAC1F,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EAC1B,MAAM,mCAAmC,CAAC;AAE3C,qBAwCa,cAAe,YAAW,mBAAmB;IAClD,OAAO,CACX,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,yBAAyB,CAAC;CActC"}
@@ -42,6 +42,13 @@ exports.SequentialNode = SequentialNode = __decorate([
42
42
  layout: 'sequential',
43
43
  required: true,
44
44
  },
45
+ {
46
+ key: 'errors',
47
+ label: 'Errors',
48
+ description: 'Nodes that run sequentially if this sequence fails.',
49
+ kind: 'sequence',
50
+ layout: 'sequential',
51
+ },
45
52
  ],
46
53
  supportsDescription: true,
47
54
  supportsName: true,
@@ -1 +1 @@
1
- {"version":3,"file":"sequential.node.js","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/sequential.node.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2GAA4F;AAwCrF,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,KAAK,CAAC,OAAO,CACX,OAAqC;QAErC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,EAAE,CAAC;QAEnB,MAAM,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE;YACjC,OAAO;SACR,CAAC,CAAC;QAEH,OAAO;YACL,MAAM,EAAE;gBACN,KAAK,EAAE,OAAO;aACf;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAjBY,wCAAc;yBAAd,cAAc;IAjC1B,IAAA,uDAAoB,EAAC;QACpB,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,cAAc;QACxB,KAAK,EAAE,YAAY;QACnB,WAAW,EAAE,sDAAsD;QACnE,IAAI,EAAE,CAAC,YAAY,EAAE,UAAU,EAAE,SAAS,CAAC;QAC3C,SAAS,EAAE;YACT,oBAAoB,EAAE,EAAE;YACxB,UAAU,EAAE;gBACV;oBACE,GAAG,EAAE,OAAO;oBACZ,KAAK,EAAE,OAAO;oBACd,WAAW,EAAE,yCAAyC;oBACtD,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,YAAY;oBACpB,QAAQ,EAAE,IAAI;iBACf;aACF;YACD,mBAAmB,EAAE,IAAI;YACzB,YAAY,EAAE,IAAI;SACnB;QACD,aAAa,EAAE;YACb,OAAO,EAAE,mEAAmE;SAC7E;QACD,EAAE,EAAE;YACF,IAAI,EAAE,iBAAiB;YACvB,SAAS,EAAE,SAAS;YACpB,mBAAmB,EAAE,SAAS;YAC9B,eAAe,EAAE,SAAS;YAC1B,SAAS,EAAE,IAAI;SAChB;KACF,CAAC;GACW,cAAc,CAiB1B","sourcesContent":["import { WorkflowNodeProvider } from '../../../decorators/workflow-node-provider.decorator';\nimport { WorkflowNodeHandler } from '../../../interfaces/workflow-node-handler.interface';\nimport {\n WorkflowNodeExecutionContext,\n WorkflowNodeHandlerResult,\n} from '../../../types/workflow-dsl.types';\n\n@WorkflowNodeProvider({\n type: 'sequential',\n kind: 'control',\n category: 'control-flow',\n label: 'Sequential',\n description: 'Runs child tasks in order and returns their outputs.',\n tags: ['sequential', 'flowable', 'ordered'],\n authoring: {\n defaultConfiguration: {},\n childSlots: [\n {\n key: 'tasks',\n label: 'Tasks',\n description: 'Child tasks that run one after another.',\n kind: 'sequence',\n layout: 'sequential',\n required: true,\n },\n ],\n supportsDescription: true,\n supportsName: true,\n },\n documentation: {\n summary: 'Runs child tasks one after another in the order they are defined.',\n },\n ui: {\n icon: 'si-list-numbers',\n iconColor: '#0891b2',\n iconBackgroundColor: '#cffafe',\n iconBorderColor: '#a5f3fc',\n modalSize: 'lg',\n },\n})\nexport class SequentialNode implements WorkflowNodeHandler {\n async execute(\n context: WorkflowNodeExecutionContext,\n ): Promise<WorkflowNodeHandlerResult> {\n const childTasks = context.node.tasks ?? [];\n const outputs = {};\n\n await context.runNodes(childTasks, {\n outputs,\n });\n\n return {\n output: {\n tasks: outputs,\n },\n };\n }\n}\n"]}
1
+ {"version":3,"file":"sequential.node.js","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/sequential.node.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2GAA4F;AA+CrF,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,KAAK,CAAC,OAAO,CACX,OAAqC;QAErC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,EAAE,CAAC;QAEnB,MAAM,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE;YACjC,OAAO;SACR,CAAC,CAAC;QAEH,OAAO;YACL,MAAM,EAAE;gBACN,KAAK,EAAE,OAAO;aACf;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAjBY,wCAAc;yBAAd,cAAc;IAxC1B,IAAA,uDAAoB,EAAC;QACpB,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,cAAc;QACxB,KAAK,EAAE,YAAY;QACnB,WAAW,EAAE,sDAAsD;QACnE,IAAI,EAAE,CAAC,YAAY,EAAE,UAAU,EAAE,SAAS,CAAC;QAC3C,SAAS,EAAE;YACT,oBAAoB,EAAE,EAAE;YACxB,UAAU,EAAE;gBACV;oBACE,GAAG,EAAE,OAAO;oBACZ,KAAK,EAAE,OAAO;oBACd,WAAW,EAAE,yCAAyC;oBACtD,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,YAAY;oBACpB,QAAQ,EAAE,IAAI;iBACf;gBACD;oBACE,GAAG,EAAE,QAAQ;oBACb,KAAK,EAAE,QAAQ;oBACf,WAAW,EAAE,qDAAqD;oBAClE,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,YAAY;iBACrB;aACF;YACD,mBAAmB,EAAE,IAAI;YACzB,YAAY,EAAE,IAAI;SACnB;QACD,aAAa,EAAE;YACb,OAAO,EAAE,mEAAmE;SAC7E;QACD,EAAE,EAAE;YACF,IAAI,EAAE,iBAAiB;YACvB,SAAS,EAAE,SAAS;YACpB,mBAAmB,EAAE,SAAS;YAC9B,eAAe,EAAE,SAAS;YAC1B,SAAS,EAAE,IAAI;SAChB;KACF,CAAC;GACW,cAAc,CAiB1B","sourcesContent":["import { WorkflowNodeProvider } from '../../../decorators/workflow-node-provider.decorator';\nimport { WorkflowNodeHandler } from '../../../interfaces/workflow-node-handler.interface';\nimport {\n WorkflowNodeExecutionContext,\n WorkflowNodeHandlerResult,\n} from '../../../types/workflow-dsl.types';\n\n@WorkflowNodeProvider({\n type: 'sequential',\n kind: 'control',\n category: 'control-flow',\n label: 'Sequential',\n description: 'Runs child tasks in order and returns their outputs.',\n tags: ['sequential', 'flowable', 'ordered'],\n authoring: {\n defaultConfiguration: {},\n childSlots: [\n {\n key: 'tasks',\n label: 'Tasks',\n description: 'Child tasks that run one after another.',\n kind: 'sequence',\n layout: 'sequential',\n required: true,\n },\n {\n key: 'errors',\n label: 'Errors',\n description: 'Nodes that run sequentially if this sequence fails.',\n kind: 'sequence',\n layout: 'sequential',\n },\n ],\n supportsDescription: true,\n supportsName: true,\n },\n documentation: {\n summary: 'Runs child tasks one after another in the order they are defined.',\n },\n ui: {\n icon: 'si-list-numbers',\n iconColor: '#0891b2',\n iconBackgroundColor: '#cffafe',\n iconBorderColor: '#a5f3fc',\n modalSize: 'lg',\n },\n})\nexport class SequentialNode implements WorkflowNodeHandler {\n async execute(\n context: WorkflowNodeExecutionContext,\n ): Promise<WorkflowNodeHandlerResult> {\n const childTasks = context.node.tasks ?? [];\n const outputs = {};\n\n await context.runNodes(childTasks, {\n outputs,\n });\n\n return {\n output: {\n tasks: outputs,\n },\n };\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"switch.node.d.ts","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/switch.node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qDAAqD,CAAC;AAC1F,OAAO,EAEL,4BAA4B,EAC5B,yBAAyB,EAC1B,MAAM,mCAAmC,CAAC;AAE3C,qBA4Da,UAAW,YAAW,mBAAmB;IAC9C,OAAO,CACX,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,yBAAyB,CAAC;IAmCrC,OAAO,CAAC,cAAc;CAkBvB"}
1
+ {"version":3,"file":"switch.node.d.ts","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/switch.node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qDAAqD,CAAC;AAC1F,OAAO,EAEL,4BAA4B,EAC5B,yBAAyB,EAC1B,MAAM,mCAAmC,CAAC;AAE3C,qBAmEa,UAAW,YAAW,mBAAmB;IAC9C,OAAO,CACX,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,yBAAyB,CAAC;IAmCrC,OAAO,CAAC,cAAc;CAkBvB"}
@@ -91,6 +91,13 @@ exports.SwitchNode = SwitchNode = __decorate([
91
91
  description: 'Fallback sequence that runs when no case key matches the resolved value.',
92
92
  kind: 'sequence',
93
93
  },
94
+ {
95
+ key: 'errors',
96
+ label: 'Errors',
97
+ description: 'Nodes that run sequentially if the selected case fails.',
98
+ kind: 'sequence',
99
+ layout: 'sequential',
100
+ },
94
101
  ],
95
102
  supportsDescription: true,
96
103
  supportsName: true,
@@ -1 +1 @@
1
- {"version":3,"file":"switch.node.js","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/switch.node.ts"],"names":[],"mappings":"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","sourcesContent":["import { WorkflowNodeProvider } from '../../../decorators/workflow-node-provider.decorator';\nimport { WorkflowNodeHandler } from '../../../interfaces/workflow-node-handler.interface';\nimport {\n WorkflowNodeDefinition,\n WorkflowNodeExecutionContext,\n WorkflowNodeHandlerResult,\n} from '../../../types/workflow-dsl.types';\n\n@WorkflowNodeProvider({\n type: 'switch',\n kind: 'control',\n category: 'control-flow',\n label: 'Switch',\n description:\n 'Runs one case sequence based on a contextual value, with an optional default sequence.',\n tags: ['switch', 'case', 'branching', 'condition'],\n authoring: {\n defaultConfiguration: {\n value: '{{ input.value }}',\n },\n configurationFields: [\n {\n key: 'value',\n label: 'Value',\n description:\n 'Expression or literal value used to choose the matching case key.',\n valueType: 'expression',\n required: true,\n expressionAllowed: true,\n widgetHint: 'textarea',\n group: 'General',\n },\n ],\n childSlots: [\n {\n key: 'cases',\n label: 'Cases',\n description: 'Named case sequences. The matching case key is executed.',\n kind: 'case-collection',\n required: true,\n minItems: 1,\n },\n {\n key: 'defaults',\n label: 'Default',\n description:\n 'Fallback sequence that runs when no case key matches the resolved value.',\n kind: 'sequence',\n },\n ],\n supportsDescription: true,\n supportsName: true,\n },\n documentation: {\n summary:\n 'Evaluates a contextual value and runs the child node sequence under the matching case key. If no case matches, the optional default sequence runs.',\n },\n ui: {\n icon: 'si-git-branch',\n iconColor: '#db2777',\n iconBackgroundColor: '#fce7f3',\n iconBorderColor: '#f9a8d4',\n modalSize: 'lg',\n layoutHints: {\n groupOrder: ['General'],\n },\n },\n})\nexport class SwitchNode implements WorkflowNodeHandler {\n async execute(\n context: WorkflowNodeExecutionContext,\n ): Promise<WorkflowNodeHandlerResult> {\n const configuration = context.node.configuration ?? {};\n const resolvedValue = context.expression.interpolate(\n configuration.value,\n context,\n );\n const caseKey = this.resolveCaseKey(resolvedValue, context.node.cases ?? {});\n const selectedNodes = caseKey\n ? context.node.cases?.[caseKey] ?? []\n : context.node.defaults ?? [];\n\n await context.emitLog({\n level: 'info',\n eventType: 'node.switch.evaluated',\n source: 'switch',\n message: caseKey\n ? `Switch node \"${context.node.id}\" matched case \"${caseKey}\".`\n : `Switch node \"${context.node.id}\" did not match a case and will run defaults.`,\n context: {\n value: resolvedValue,\n caseKey,\n },\n });\n\n await context.runNodes(selectedNodes);\n\n return {\n output: {\n value: resolvedValue,\n case: caseKey,\n matched: Boolean(caseKey),\n },\n };\n }\n\n private resolveCaseKey(\n value: any,\n cases: Record<string, WorkflowNodeDefinition[]>,\n ): string | undefined {\n const exactKey = String(value);\n if (Object.prototype.hasOwnProperty.call(cases, exactKey)) {\n return exactKey;\n }\n\n if (typeof value === 'boolean') {\n const booleanKey = value ? 'true' : 'false';\n if (Object.prototype.hasOwnProperty.call(cases, booleanKey)) {\n return booleanKey;\n }\n }\n\n return undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"switch.node.js","sourceRoot":"","sources":["../../../../src/services/workflow/nodes/switch.node.ts"],"names":[],"mappings":"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","sourcesContent":["import { WorkflowNodeProvider } from '../../../decorators/workflow-node-provider.decorator';\nimport { WorkflowNodeHandler } from '../../../interfaces/workflow-node-handler.interface';\nimport {\n WorkflowNodeDefinition,\n WorkflowNodeExecutionContext,\n WorkflowNodeHandlerResult,\n} from '../../../types/workflow-dsl.types';\n\n@WorkflowNodeProvider({\n type: 'switch',\n kind: 'control',\n category: 'control-flow',\n label: 'Switch',\n description:\n 'Runs one case sequence based on a contextual value, with an optional default sequence.',\n tags: ['switch', 'case', 'branching', 'condition'],\n authoring: {\n defaultConfiguration: {\n value: '{{ input.value }}',\n },\n configurationFields: [\n {\n key: 'value',\n label: 'Value',\n description:\n 'Expression or literal value used to choose the matching case key.',\n valueType: 'expression',\n required: true,\n expressionAllowed: true,\n widgetHint: 'textarea',\n group: 'General',\n },\n ],\n childSlots: [\n {\n key: 'cases',\n label: 'Cases',\n description: 'Named case sequences. The matching case key is executed.',\n kind: 'case-collection',\n required: true,\n minItems: 1,\n },\n {\n key: 'defaults',\n label: 'Default',\n description:\n 'Fallback sequence that runs when no case key matches the resolved value.',\n kind: 'sequence',\n },\n {\n key: 'errors',\n label: 'Errors',\n description: 'Nodes that run sequentially if the selected case fails.',\n kind: 'sequence',\n layout: 'sequential',\n },\n ],\n supportsDescription: true,\n supportsName: true,\n },\n documentation: {\n summary:\n 'Evaluates a contextual value and runs the child node sequence under the matching case key. If no case matches, the optional default sequence runs.',\n },\n ui: {\n icon: 'si-git-branch',\n iconColor: '#db2777',\n iconBackgroundColor: '#fce7f3',\n iconBorderColor: '#f9a8d4',\n modalSize: 'lg',\n layoutHints: {\n groupOrder: ['General'],\n },\n },\n})\nexport class SwitchNode implements WorkflowNodeHandler {\n async execute(\n context: WorkflowNodeExecutionContext,\n ): Promise<WorkflowNodeHandlerResult> {\n const configuration = context.node.configuration ?? {};\n const resolvedValue = context.expression.interpolate(\n configuration.value,\n context,\n );\n const caseKey = this.resolveCaseKey(resolvedValue, context.node.cases ?? {});\n const selectedNodes = caseKey\n ? context.node.cases?.[caseKey] ?? []\n : context.node.defaults ?? [];\n\n await context.emitLog({\n level: 'info',\n eventType: 'node.switch.evaluated',\n source: 'switch',\n message: caseKey\n ? `Switch node \"${context.node.id}\" matched case \"${caseKey}\".`\n : `Switch node \"${context.node.id}\" did not match a case and will run defaults.`,\n context: {\n value: resolvedValue,\n caseKey,\n },\n });\n\n await context.runNodes(selectedNodes);\n\n return {\n output: {\n value: resolvedValue,\n case: caseKey,\n matched: Boolean(caseKey),\n },\n };\n }\n\n private resolveCaseKey(\n value: any,\n cases: Record<string, WorkflowNodeDefinition[]>,\n ): string | undefined {\n const exactKey = String(value);\n if (Object.prototype.hasOwnProperty.call(cases, exactKey)) {\n return exactKey;\n }\n\n if (typeof value === 'boolean') {\n const booleanKey = value ? 'true' : 'false';\n if (Object.prototype.hasOwnProperty.call(cases, booleanKey)) {\n return booleanKey;\n }\n }\n\n return undefined;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-definition-validator.service.d.ts","sourceRoot":"","sources":["../../../src/services/workflow/workflow-definition-validator.service.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EAGtB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAG/E,qBACa,kCAAkC;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,2BAA2B;IAElE,QAAQ,CAAC,UAAU,EAAE,qBAAqB;IAsB1C,OAAO,CAAC,gBAAgB;IAyBxB,OAAO,CAAC,eAAe;IAwDvB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,YAAY;CAoFrB"}
1
+ {"version":3,"file":"workflow-definition-validator.service.d.ts","sourceRoot":"","sources":["../../../src/services/workflow/workflow-definition-validator.service.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EAGtB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAG/E,qBACa,kCAAkC;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,2BAA2B;IAElE,QAAQ,CAAC,UAAU,EAAE,qBAAqB;IAwB1C,OAAO,CAAC,gBAAgB;IAyBxB,OAAO,CAAC,eAAe;IAwDvB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,YAAY;CAqFrB"}
@@ -28,6 +28,8 @@ let WorkflowDefinitionValidatorService = class WorkflowDefinitionValidatorServic
28
28
  }
29
29
  const nodeIds = new Set();
30
30
  this.validateNodes(definition.nodes, nodeIds);
31
+ this.validateNodes(definition.errors ?? [], nodeIds);
32
+ this.validateNodes(definition.finally ?? [], nodeIds);
31
33
  this.validateTriggers(definition);
32
34
  }
33
35
  validateTriggers(definition) {
@@ -104,10 +106,10 @@ let WorkflowDefinitionValidatorService = class WorkflowDefinitionValidatorServic
104
106
  }
105
107
  for (const unsupportedKey of ['children', 'branches', 'nodes']) {
106
108
  if (Object.prototype.hasOwnProperty.call(node, unsupportedKey)) {
107
- throw new common_1.BadRequestException(`Workflow node "${node.id ?? 'unknown'}" uses unsupported child key "${unsupportedKey}". Use "tasks", "then", "else", "defaults", or "cases" instead.`);
109
+ throw new common_1.BadRequestException(`Workflow node "${node.id ?? 'unknown'}" uses unsupported child key "${unsupportedKey}". Use "tasks", "then", "else", "defaults", "errors", or "cases" instead.`);
108
110
  }
109
111
  }
110
- for (const childKey of ['tasks', 'then', 'else', 'defaults']) {
112
+ for (const childKey of ['tasks', 'then', 'else', 'defaults', 'errors']) {
111
113
  const childValue = node[childKey];
112
114
  if (childValue !== undefined &&
113
115
  childValue !== null &&
@@ -150,6 +152,7 @@ let WorkflowDefinitionValidatorService = class WorkflowDefinitionValidatorServic
150
152
  this.validateNodes(node.then ?? [], nodeIds);
151
153
  this.validateNodes(node.else ?? [], nodeIds);
152
154
  this.validateNodes(node.defaults ?? [], nodeIds);
155
+ this.validateNodes(node.errors ?? [], nodeIds);
153
156
  Object.values(node.cases ?? {}).forEach((caseNodes) => {
154
157
  this.validateNodes(caseNodes, nodeIds);
155
158
  });
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-definition-validator.service.js","sourceRoot":"","sources":["../../../src/services/workflow/workflow-definition-validator.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAiE;AAMjE,qFAA+E;AAC/E,6CAAmD;AAG5C,IAAM,kCAAkC,GAAxC,MAAM,kCAAkC;IAC7C,YAA6B,QAAqC;QAArC,aAAQ,GAAR,QAAQ,CAA6B;IAAG,CAAC;IAEtE,QAAQ,CAAC,UAAiC;QACxC,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,4BAAmB,CAC3B,sDAAsD,CACvD,CAAC;QACJ,CAAC;QAED,IACE,UAAU,CAAC,QAAQ,KAAK,SAAS;YACjC,UAAU,CAAC,QAAQ,KAAK,IAAI;YAC5B,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EACnC,CAAC;YACD,MAAM,IAAI,4BAAmB,CAC3B,8DAA8D,CAC/D,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IAEO,gBAAgB,CAAC,UAAiC;QACxD,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC3C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QACrC,MAAM,sBAAsB,GAAG,QAAQ,CAAC,MAAM,CAC5C,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,UAAU,IAAI,CAAC,OAAO,CAAC,QAAQ,CAC/D,CAAC;QAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,EAAE,CAAC;QACvC,KAAK,MAAM,CAAC,QAAQ,EAAE,eAAe,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACjE,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,CAAC;gBAC3C,MAAM,IAAI,4BAAmB,CAC3B,mBAAmB,QAAQ,iEAAiE,CAC7F,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAEO,eAAe,CACrB,OAAkC,EAClC,UAAuB;QAEvB,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,4BAAmB,CAAC,2CAA2C,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YAChB,MAAM,IAAI,4BAAmB,CAAC,wCAAwC,CAAC,CAAC;QAC1E,CAAC;QAED,IAAI,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,4BAAmB,CAC3B,kCAAkC,OAAO,CAAC,EAAE,IAAI,CACjD,CAAC;QACJ,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAE3B,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,4BAAmB,CAC3B,qBAAqB,OAAO,CAAC,EAAE,2BAA2B,OAAO,CAAC,IAAI,IAAI,CAC3E,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAChC,MAAM,cAAc,GAClB,OAAO,CAAC,aAAa,EAAE,cAAc,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC;YACvE,IAAI,CAAC,cAAc,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;gBAC1D,MAAM,IAAI,4BAAmB,CAC3B,qBAAqB,OAAO,CAAC,EAAE,+BAA+B,CAC/D,CAAC;YACJ,CAAC;YAED,IAAI,CAAC;gBACH,kCAAoB,CAAC,KAAK,CAAC,cAAc,EAAE;oBACzC,WAAW,EAAE,IAAI,IAAI,EAAE;oBACvB,EAAE,EAAE,OAAO,CAAC,aAAa,EAAE,QAAQ,IAAI,KAAK;iBAC7C,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,IAAI,4BAAmB,CAC3B,qBAAqB,OAAO,CAAC,EAAE,qCAAqC,KAAK,EAAE,OAAO,IAAI,cAAc,EAAE,CACvG,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7E,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChE,MAAM,IAAI,4BAAmB,CAC3B,qBAAqB,OAAO,CAAC,EAAE,qCAAqC,MAAM,IAAI,CAC/E,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,eAAoB;QAC1C,IACE,eAAe;YACf,OAAO,eAAe,KAAK,QAAQ;YACnC,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,EAC/B,CAAC;YACD,OAAO,CACL,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC;gBAChE,eAAe,CAAC,OAAO,KAAK,SAAS;gBACrC,eAAe,CAAC,OAAO,KAAK,IAAI,CACjC,CAAC;QACJ,CAAC;QAED,OAAO,eAAe,KAAK,SAAS,IAAI,eAAe,KAAK,IAAI,CAAC;IACnE,CAAC;IAEO,aAAa,CAAC,KAA+B,EAAE,OAAoB;QACzE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,IAA4B,EAAE,OAAoB;QACrE,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,4BAAmB,CAAC,wCAAwC,CAAC,CAAC;QAC1E,CAAC;QAED,KAAK,MAAM,cAAc,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;YAC/D,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC/D,MAAM,IAAI,4BAAmB,CAC3B,kBAAkB,IAAI,CAAC,EAAE,IAAI,SAAS,iCAAiC,cAAc,iEAAiE,CACvJ,CAAC;YACJ,CAAC;QACH,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAU,EAAE,CAAC;YACtE,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClC,IACE,UAAU,KAAK,SAAS;gBACxB,UAAU,KAAK,IAAI;gBACnB,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAC1B,CAAC;gBACD,MAAM,IAAI,4BAAmB,CAC3B,kBAAkB,IAAI,CAAC,EAAE,IAAI,SAAS,YAAY,QAAQ,mCAAmC,CAC9F,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IACE,IAAI,CAAC,KAAK,KAAK,SAAS;YACxB,IAAI,CAAC,KAAK,KAAK,IAAI;YACnB,CAAC,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAC7D,CAAC;YACD,MAAM,IAAI,4BAAmB,CAC3B,kBAAkB,IAAI,CAAC,EAAE,IAAI,SAAS,4DAA4D,CACnG,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACjD,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC9B,MAAM,IAAI,4BAAmB,CAC3B,kBAAkB,IAAI,CAAC,EAAE,IAAI,SAAS,WAAW,OAAO,qBAAqB,CAC9E,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,4BAAmB,CAAC,qCAAqC,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,4BAAmB,CAAC,+BAA+B,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5E,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAErB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,4BAAmB,CAAC,kBAAkB,IAAI,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,4BAAmB,CAC3B,kBAAkB,IAAI,CAAC,EAAE,2BAA2B,IAAI,CAAC,IAAI,IAAI,CAClE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,4BAAmB,CAAC,kBAAkB,IAAI,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,4BAAmB,CAC3B,kBAAkB,IAAI,CAAC,EAAE,6BAA6B,IAAI,CAAC,IAAI,IAAI,CACpE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YACpD,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AApNY,gFAAkC;6CAAlC,kCAAkC;IAD9C,IAAA,mBAAU,GAAE;qCAE4B,4DAA2B;GADvD,kCAAkC,CAoN9C","sourcesContent":["import { BadRequestException, Injectable } from '@nestjs/common';\nimport {\n WorkflowDefinitionDsl,\n WorkflowNodeDefinition,\n WorkflowTriggerDefinition,\n} from '../../types/workflow-dsl.types';\nimport { WorkflowNodeRegistryService } from './workflow-node-registry.service';\nimport { CronExpressionParser } from 'cron-parser';\n\n@Injectable()\nexport class WorkflowDefinitionValidatorService {\n constructor(private readonly registry: WorkflowNodeRegistryService) {}\n\n validate(definition: WorkflowDefinitionDsl) {\n if (!definition || !Array.isArray(definition.nodes)) {\n throw new BadRequestException(\n 'Workflow definition YAML must include a nodes array.',\n );\n }\n\n if (\n definition.triggers !== undefined &&\n definition.triggers !== null &&\n !Array.isArray(definition.triggers)\n ) {\n throw new BadRequestException(\n 'Workflow definition triggers must be an array when provided.',\n );\n }\n\n const nodeIds = new Set<string>();\n this.validateNodes(definition.nodes, nodeIds);\n this.validateTriggers(definition);\n }\n\n private validateTriggers(definition: WorkflowDefinitionDsl) {\n const triggers = definition.triggers ?? [];\n const triggerIds = new Set<string>();\n const activeScheduleTriggers = triggers.filter(\n (trigger) => trigger?.type === 'schedule' && !trigger.disabled,\n );\n\n for (const trigger of triggers) {\n this.validateTrigger(trigger, triggerIds);\n }\n\n if (!activeScheduleTriggers.length) {\n return;\n }\n\n const inputs = definition.inputs ?? {};\n for (const [inputKey, inputDefinition] of Object.entries(inputs)) {\n if (!this.inputHasDefault(inputDefinition)) {\n throw new BadRequestException(\n `Workflow input \"${inputKey}\" requires a default value before enabling a scheduled trigger.`,\n );\n }\n }\n }\n\n private validateTrigger(\n trigger: WorkflowTriggerDefinition,\n triggerIds: Set<string>,\n ) {\n if (!trigger || typeof trigger !== 'object' || Array.isArray(trigger)) {\n throw new BadRequestException('Every workflow trigger must be an object.');\n }\n\n if (!trigger.id) {\n throw new BadRequestException('Every workflow trigger requires an id.');\n }\n\n if (triggerIds.has(trigger.id)) {\n throw new BadRequestException(\n `Duplicate workflow trigger id \"${trigger.id}\".`,\n );\n }\n triggerIds.add(trigger.id);\n\n if (!['schedule', 'webhook'].includes(trigger.type)) {\n throw new BadRequestException(\n `Workflow trigger \"${trigger.id}\" has unsupported type \"${trigger.type}\".`,\n );\n }\n\n if (trigger.type === 'schedule') {\n const cronExpression =\n trigger.configuration?.cronExpression ?? trigger.configuration?.cron;\n if (!cronExpression || typeof cronExpression !== 'string') {\n throw new BadRequestException(\n `Workflow trigger \"${trigger.id}\" requires a cron expression.`,\n );\n }\n\n try {\n CronExpressionParser.parse(cronExpression, {\n currentDate: new Date(),\n tz: trigger.configuration?.timezone ?? 'UTC',\n });\n } catch (error: any) {\n throw new BadRequestException(\n `Workflow trigger \"${trigger.id}\" has an invalid cron expression: ${error?.message ?? cronExpression}`,\n );\n }\n }\n\n if (trigger.type === 'webhook') {\n const method = String(trigger.configuration?.method ?? 'POST').toUpperCase();\n if (!['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(method)) {\n throw new BadRequestException(\n `Workflow trigger \"${trigger.id}\" has unsupported webhook method \"${method}\".`,\n );\n }\n }\n }\n\n private inputHasDefault(inputDefinition: any): boolean {\n if (\n inputDefinition &&\n typeof inputDefinition === 'object' &&\n !Array.isArray(inputDefinition)\n ) {\n return (\n Object.prototype.hasOwnProperty.call(inputDefinition, 'default') &&\n inputDefinition.default !== undefined &&\n inputDefinition.default !== null\n );\n }\n\n return inputDefinition !== undefined && inputDefinition !== null;\n }\n\n private validateNodes(nodes: WorkflowNodeDefinition[], nodeIds: Set<string>) {\n for (const node of nodes) {\n this.validateNode(node, nodeIds);\n }\n }\n\n private validateNode(node: WorkflowNodeDefinition, nodeIds: Set<string>) {\n if (!node || typeof node !== 'object' || Array.isArray(node)) {\n throw new BadRequestException('Every workflow node must be an object.');\n }\n\n for (const unsupportedKey of ['children', 'branches', 'nodes']) {\n if (Object.prototype.hasOwnProperty.call(node, unsupportedKey)) {\n throw new BadRequestException(\n `Workflow node \"${node.id ?? 'unknown'}\" uses unsupported child key \"${unsupportedKey}\". Use \"tasks\", \"then\", \"else\", \"defaults\", or \"cases\" instead.`,\n );\n }\n }\n\n for (const childKey of ['tasks', 'then', 'else', 'defaults'] as const) {\n const childValue = node[childKey];\n if (\n childValue !== undefined &&\n childValue !== null &&\n !Array.isArray(childValue)\n ) {\n throw new BadRequestException(\n `Workflow node \"${node.id ?? 'unknown'}\" field \"${childKey}\" must be an array when provided.`,\n );\n }\n }\n\n if (\n node.cases !== undefined &&\n node.cases !== null &&\n (typeof node.cases !== 'object' || Array.isArray(node.cases))\n ) {\n throw new BadRequestException(\n `Workflow node \"${node.id ?? 'unknown'}\" field \"cases\" must be an object of arrays when provided.`,\n );\n }\n\n if (node.cases && typeof node.cases === 'object') {\n for (const [caseKey, caseNodes] of Object.entries(node.cases)) {\n if (!Array.isArray(caseNodes)) {\n throw new BadRequestException(\n `Workflow node \"${node.id ?? 'unknown'}\" case \"${caseKey}\" must be an array.`,\n );\n }\n }\n }\n\n if (!node.id) {\n throw new BadRequestException('Every workflow node requires an id.');\n }\n\n if (nodeIds.has(node.id)) {\n throw new BadRequestException(`Duplicate workflow node id \"${node.id}\".`);\n }\n\n nodeIds.add(node.id);\n\n if (!node.kind) {\n throw new BadRequestException(`Workflow node \"${node.id}\" requires kind.`);\n }\n\n if (!['task', 'control', 'subflow'].includes(node.kind)) {\n throw new BadRequestException(\n `Workflow node \"${node.id}\" has unsupported kind \"${node.kind}\".`,\n );\n }\n\n if (!node.type) {\n throw new BadRequestException(`Workflow node \"${node.id}\" requires type.`);\n }\n\n if (!this.registry.has(node.type)) {\n throw new BadRequestException(\n `Workflow node \"${node.id}\" uses unregistered type \"${node.type}\".`,\n );\n }\n\n this.validateNodes(node.tasks ?? [], nodeIds);\n this.validateNodes(node.then ?? [], nodeIds);\n this.validateNodes(node.else ?? [], nodeIds);\n this.validateNodes(node.defaults ?? [], nodeIds);\n Object.values(node.cases ?? {}).forEach((caseNodes) => {\n this.validateNodes(caseNodes, nodeIds);\n });\n }\n}\n"]}
1
+ {"version":3,"file":"workflow-definition-validator.service.js","sourceRoot":"","sources":["../../../src/services/workflow/workflow-definition-validator.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAiE;AAMjE,qFAA+E;AAC/E,6CAAmD;AAG5C,IAAM,kCAAkC,GAAxC,MAAM,kCAAkC;IAC7C,YAA6B,QAAqC;QAArC,aAAQ,GAAR,QAAQ,CAA6B;IAAG,CAAC;IAEtE,QAAQ,CAAC,UAAiC;QACxC,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,4BAAmB,CAC3B,sDAAsD,CACvD,CAAC;QACJ,CAAC;QAED,IACE,UAAU,CAAC,QAAQ,KAAK,SAAS;YACjC,UAAU,CAAC,QAAQ,KAAK,IAAI;YAC5B,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EACnC,CAAC;YACD,MAAM,IAAI,4BAAmB,CAC3B,8DAA8D,CAC/D,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,MAAM,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QACrD,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,OAAO,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IAEO,gBAAgB,CAAC,UAAiC;QACxD,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC3C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QACrC,MAAM,sBAAsB,GAAG,QAAQ,CAAC,MAAM,CAC5C,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,UAAU,IAAI,CAAC,OAAO,CAAC,QAAQ,CAC/D,CAAC;QAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,EAAE,CAAC;QACvC,KAAK,MAAM,CAAC,QAAQ,EAAE,eAAe,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACjE,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,CAAC;gBAC3C,MAAM,IAAI,4BAAmB,CAC3B,mBAAmB,QAAQ,iEAAiE,CAC7F,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAEO,eAAe,CACrB,OAAkC,EAClC,UAAuB;QAEvB,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,4BAAmB,CAAC,2CAA2C,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YAChB,MAAM,IAAI,4BAAmB,CAAC,wCAAwC,CAAC,CAAC;QAC1E,CAAC;QAED,IAAI,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,4BAAmB,CAC3B,kCAAkC,OAAO,CAAC,EAAE,IAAI,CACjD,CAAC;QACJ,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAE3B,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,4BAAmB,CAC3B,qBAAqB,OAAO,CAAC,EAAE,2BAA2B,OAAO,CAAC,IAAI,IAAI,CAC3E,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAChC,MAAM,cAAc,GAClB,OAAO,CAAC,aAAa,EAAE,cAAc,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC;YACvE,IAAI,CAAC,cAAc,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;gBAC1D,MAAM,IAAI,4BAAmB,CAC3B,qBAAqB,OAAO,CAAC,EAAE,+BAA+B,CAC/D,CAAC;YACJ,CAAC;YAED,IAAI,CAAC;gBACH,kCAAoB,CAAC,KAAK,CAAC,cAAc,EAAE;oBACzC,WAAW,EAAE,IAAI,IAAI,EAAE;oBACvB,EAAE,EAAE,OAAO,CAAC,aAAa,EAAE,QAAQ,IAAI,KAAK;iBAC7C,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,IAAI,4BAAmB,CAC3B,qBAAqB,OAAO,CAAC,EAAE,qCAAqC,KAAK,EAAE,OAAO,IAAI,cAAc,EAAE,CACvG,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7E,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChE,MAAM,IAAI,4BAAmB,CAC3B,qBAAqB,OAAO,CAAC,EAAE,qCAAqC,MAAM,IAAI,CAC/E,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,eAAoB;QAC1C,IACE,eAAe;YACf,OAAO,eAAe,KAAK,QAAQ;YACnC,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,EAC/B,CAAC;YACD,OAAO,CACL,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC;gBAChE,eAAe,CAAC,OAAO,KAAK,SAAS;gBACrC,eAAe,CAAC,OAAO,KAAK,IAAI,CACjC,CAAC;QACJ,CAAC;QAED,OAAO,eAAe,KAAK,SAAS,IAAI,eAAe,KAAK,IAAI,CAAC;IACnE,CAAC;IAEO,aAAa,CAAC,KAA+B,EAAE,OAAoB;QACzE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,IAA4B,EAAE,OAAoB;QACrE,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,4BAAmB,CAAC,wCAAwC,CAAC,CAAC;QAC1E,CAAC;QAED,KAAK,MAAM,cAAc,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;YAC/D,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC/D,MAAM,IAAI,4BAAmB,CAC3B,kBAAkB,IAAI,CAAC,EAAE,IAAI,SAAS,iCAAiC,cAAc,2EAA2E,CACjK,CAAC;YACJ,CAAC;QACH,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAU,EAAE,CAAC;YAChF,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClC,IACE,UAAU,KAAK,SAAS;gBACxB,UAAU,KAAK,IAAI;gBACnB,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAC1B,CAAC;gBACD,MAAM,IAAI,4BAAmB,CAC3B,kBAAkB,IAAI,CAAC,EAAE,IAAI,SAAS,YAAY,QAAQ,mCAAmC,CAC9F,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IACE,IAAI,CAAC,KAAK,KAAK,SAAS;YACxB,IAAI,CAAC,KAAK,KAAK,IAAI;YACnB,CAAC,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAC7D,CAAC;YACD,MAAM,IAAI,4BAAmB,CAC3B,kBAAkB,IAAI,CAAC,EAAE,IAAI,SAAS,4DAA4D,CACnG,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACjD,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC9B,MAAM,IAAI,4BAAmB,CAC3B,kBAAkB,IAAI,CAAC,EAAE,IAAI,SAAS,WAAW,OAAO,qBAAqB,CAC9E,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,4BAAmB,CAAC,qCAAqC,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,4BAAmB,CAAC,+BAA+B,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5E,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAErB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,4BAAmB,CAAC,kBAAkB,IAAI,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,4BAAmB,CAC3B,kBAAkB,IAAI,CAAC,EAAE,2BAA2B,IAAI,CAAC,IAAI,IAAI,CAClE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,4BAAmB,CAAC,kBAAkB,IAAI,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,4BAAmB,CAC3B,kBAAkB,IAAI,CAAC,EAAE,6BAA6B,IAAI,CAAC,IAAI,IAAI,CACpE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YACpD,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AAvNY,gFAAkC;6CAAlC,kCAAkC;IAD9C,IAAA,mBAAU,GAAE;qCAE4B,4DAA2B;GADvD,kCAAkC,CAuN9C","sourcesContent":["import { BadRequestException, Injectable } from '@nestjs/common';\nimport {\n WorkflowDefinitionDsl,\n WorkflowNodeDefinition,\n WorkflowTriggerDefinition,\n} from '../../types/workflow-dsl.types';\nimport { WorkflowNodeRegistryService } from './workflow-node-registry.service';\nimport { CronExpressionParser } from 'cron-parser';\n\n@Injectable()\nexport class WorkflowDefinitionValidatorService {\n constructor(private readonly registry: WorkflowNodeRegistryService) {}\n\n validate(definition: WorkflowDefinitionDsl) {\n if (!definition || !Array.isArray(definition.nodes)) {\n throw new BadRequestException(\n 'Workflow definition YAML must include a nodes array.',\n );\n }\n\n if (\n definition.triggers !== undefined &&\n definition.triggers !== null &&\n !Array.isArray(definition.triggers)\n ) {\n throw new BadRequestException(\n 'Workflow definition triggers must be an array when provided.',\n );\n }\n\n const nodeIds = new Set<string>();\n this.validateNodes(definition.nodes, nodeIds);\n this.validateNodes(definition.errors ?? [], nodeIds);\n this.validateNodes(definition.finally ?? [], nodeIds);\n this.validateTriggers(definition);\n }\n\n private validateTriggers(definition: WorkflowDefinitionDsl) {\n const triggers = definition.triggers ?? [];\n const triggerIds = new Set<string>();\n const activeScheduleTriggers = triggers.filter(\n (trigger) => trigger?.type === 'schedule' && !trigger.disabled,\n );\n\n for (const trigger of triggers) {\n this.validateTrigger(trigger, triggerIds);\n }\n\n if (!activeScheduleTriggers.length) {\n return;\n }\n\n const inputs = definition.inputs ?? {};\n for (const [inputKey, inputDefinition] of Object.entries(inputs)) {\n if (!this.inputHasDefault(inputDefinition)) {\n throw new BadRequestException(\n `Workflow input \"${inputKey}\" requires a default value before enabling a scheduled trigger.`,\n );\n }\n }\n }\n\n private validateTrigger(\n trigger: WorkflowTriggerDefinition,\n triggerIds: Set<string>,\n ) {\n if (!trigger || typeof trigger !== 'object' || Array.isArray(trigger)) {\n throw new BadRequestException('Every workflow trigger must be an object.');\n }\n\n if (!trigger.id) {\n throw new BadRequestException('Every workflow trigger requires an id.');\n }\n\n if (triggerIds.has(trigger.id)) {\n throw new BadRequestException(\n `Duplicate workflow trigger id \"${trigger.id}\".`,\n );\n }\n triggerIds.add(trigger.id);\n\n if (!['schedule', 'webhook'].includes(trigger.type)) {\n throw new BadRequestException(\n `Workflow trigger \"${trigger.id}\" has unsupported type \"${trigger.type}\".`,\n );\n }\n\n if (trigger.type === 'schedule') {\n const cronExpression =\n trigger.configuration?.cronExpression ?? trigger.configuration?.cron;\n if (!cronExpression || typeof cronExpression !== 'string') {\n throw new BadRequestException(\n `Workflow trigger \"${trigger.id}\" requires a cron expression.`,\n );\n }\n\n try {\n CronExpressionParser.parse(cronExpression, {\n currentDate: new Date(),\n tz: trigger.configuration?.timezone ?? 'UTC',\n });\n } catch (error: any) {\n throw new BadRequestException(\n `Workflow trigger \"${trigger.id}\" has an invalid cron expression: ${error?.message ?? cronExpression}`,\n );\n }\n }\n\n if (trigger.type === 'webhook') {\n const method = String(trigger.configuration?.method ?? 'POST').toUpperCase();\n if (!['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(method)) {\n throw new BadRequestException(\n `Workflow trigger \"${trigger.id}\" has unsupported webhook method \"${method}\".`,\n );\n }\n }\n }\n\n private inputHasDefault(inputDefinition: any): boolean {\n if (\n inputDefinition &&\n typeof inputDefinition === 'object' &&\n !Array.isArray(inputDefinition)\n ) {\n return (\n Object.prototype.hasOwnProperty.call(inputDefinition, 'default') &&\n inputDefinition.default !== undefined &&\n inputDefinition.default !== null\n );\n }\n\n return inputDefinition !== undefined && inputDefinition !== null;\n }\n\n private validateNodes(nodes: WorkflowNodeDefinition[], nodeIds: Set<string>) {\n for (const node of nodes) {\n this.validateNode(node, nodeIds);\n }\n }\n\n private validateNode(node: WorkflowNodeDefinition, nodeIds: Set<string>) {\n if (!node || typeof node !== 'object' || Array.isArray(node)) {\n throw new BadRequestException('Every workflow node must be an object.');\n }\n\n for (const unsupportedKey of ['children', 'branches', 'nodes']) {\n if (Object.prototype.hasOwnProperty.call(node, unsupportedKey)) {\n throw new BadRequestException(\n `Workflow node \"${node.id ?? 'unknown'}\" uses unsupported child key \"${unsupportedKey}\". Use \"tasks\", \"then\", \"else\", \"defaults\", \"errors\", or \"cases\" instead.`,\n );\n }\n }\n\n for (const childKey of ['tasks', 'then', 'else', 'defaults', 'errors'] as const) {\n const childValue = node[childKey];\n if (\n childValue !== undefined &&\n childValue !== null &&\n !Array.isArray(childValue)\n ) {\n throw new BadRequestException(\n `Workflow node \"${node.id ?? 'unknown'}\" field \"${childKey}\" must be an array when provided.`,\n );\n }\n }\n\n if (\n node.cases !== undefined &&\n node.cases !== null &&\n (typeof node.cases !== 'object' || Array.isArray(node.cases))\n ) {\n throw new BadRequestException(\n `Workflow node \"${node.id ?? 'unknown'}\" field \"cases\" must be an object of arrays when provided.`,\n );\n }\n\n if (node.cases && typeof node.cases === 'object') {\n for (const [caseKey, caseNodes] of Object.entries(node.cases)) {\n if (!Array.isArray(caseNodes)) {\n throw new BadRequestException(\n `Workflow node \"${node.id ?? 'unknown'}\" case \"${caseKey}\" must be an array.`,\n );\n }\n }\n }\n\n if (!node.id) {\n throw new BadRequestException('Every workflow node requires an id.');\n }\n\n if (nodeIds.has(node.id)) {\n throw new BadRequestException(`Duplicate workflow node id \"${node.id}\".`);\n }\n\n nodeIds.add(node.id);\n\n if (!node.kind) {\n throw new BadRequestException(`Workflow node \"${node.id}\" requires kind.`);\n }\n\n if (!['task', 'control', 'subflow'].includes(node.kind)) {\n throw new BadRequestException(\n `Workflow node \"${node.id}\" has unsupported kind \"${node.kind}\".`,\n );\n }\n\n if (!node.type) {\n throw new BadRequestException(`Workflow node \"${node.id}\" requires type.`);\n }\n\n if (!this.registry.has(node.type)) {\n throw new BadRequestException(\n `Workflow node \"${node.id}\" uses unregistered type \"${node.type}\".`,\n );\n }\n\n this.validateNodes(node.tasks ?? [], nodeIds);\n this.validateNodes(node.then ?? [], nodeIds);\n this.validateNodes(node.else ?? [], nodeIds);\n this.validateNodes(node.defaults ?? [], nodeIds);\n this.validateNodes(node.errors ?? [], nodeIds);\n Object.values(node.cases ?? {}).forEach((caseNodes) => {\n this.validateNodes(caseNodes, nodeIds);\n });\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-expression.service.d.ts","sourceRoot":"","sources":["../../../src/services/workflow/workflow-expression.service.ts"],"names":[],"mappings":"AACA,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,EACvB,MAAM,gCAAgC,CAAC;AAExC,qBACa,yBAA0B,YAAW,0BAA0B;IAC1E,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,sBAAsB,GAAG,CAAC;IA2BlE,iBAAiB,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO;IAa5E,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,GAAG;IAkB3E,OAAO,CAAC,yBAAyB;IAsBjC,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,QAAQ;CAMjB"}
1
+ {"version":3,"file":"workflow-expression.service.d.ts","sourceRoot":"","sources":["../../../src/services/workflow/workflow-expression.service.ts"],"names":[],"mappings":"AACA,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,EACvB,MAAM,gCAAgC,CAAC;AAExC,qBACa,yBAA0B,YAAW,0BAA0B;IAC1E,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,sBAAsB,GAAG,CAAC;IA2BlE,iBAAiB,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO;IAa5E,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,GAAG;IAkB3E,OAAO,CAAC,yBAAyB;IAsBjC,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,WAAW;IA+BnB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,QAAQ;CAMjB"}
@@ -118,9 +118,14 @@ let WorkflowExpressionService = class WorkflowExpressionService {
118
118
  node: context.node,
119
119
  item: context.item,
120
120
  index: context.index,
121
+ parent: context.parent,
122
+ parents: context.parents,
123
+ loops: context.loops,
124
+ error: context.error,
121
125
  };
122
126
  const parts = path
123
127
  .replace(/\[(?:'|")([^'"]+)(?:'|")\]/g, '.$1')
128
+ .replace(/\[(\d+)\]/g, '.$1')
124
129
  .split('.')
125
130
  .filter(Boolean);
126
131
  return parts.reduce((current, key) => {
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-expression.service.js","sourceRoot":"","sources":["../../../src/services/workflow/workflow-expression.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@nestjs/common';\nimport {\n WorkflowExpressionResolver,\n WorkflowRuntimeContext,\n} from '../../types/workflow-dsl.types';\n\n@Injectable()\nexport class WorkflowExpressionService implements WorkflowExpressionResolver {\n interpolate<T = any>(value: T, context: WorkflowRuntimeContext): T {\n if (Array.isArray(value)) {\n return value.map((entry) => this.interpolate(entry, context)) as T;\n }\n\n if (value && typeof value === 'object') {\n return Object.entries(value).reduce((acc, [key, entry]) => {\n acc[key] = this.interpolate(entry, context);\n return acc;\n }, {} as Record<string, any>) as T;\n }\n\n if (typeof value !== 'string') {\n return value;\n }\n\n const exactExpression = value.match(/^\\s*\\{\\{\\s*(.*?)\\s*\\}\\}\\s*$/);\n if (exactExpression) {\n return this.resolveExpression(exactExpression[1], context);\n }\n\n return value.replace(/\\{\\{\\s*(.*?)\\s*\\}\\}/g, (_match, expression) => {\n const resolved = this.resolveExpression(expression, context);\n return resolved === null || resolved === undefined ? '' : String(resolved);\n }) as T;\n }\n\n evaluateCondition(expression: any, context: WorkflowRuntimeContext): boolean {\n const resolved =\n typeof expression === 'string'\n ? this.resolveExpression(this.unwrapExpression(expression), context)\n : expression;\n\n if (typeof resolved === 'string') {\n return this.evaluateBooleanExpression(resolved, context);\n }\n\n return Boolean(resolved);\n }\n\n resolveExpression(expression: string, context: WorkflowRuntimeContext): any {\n const trimmed = expression.trim();\n\n if (trimmed === 'true') return true;\n if (trimmed === 'false') return false;\n if (trimmed === 'null') return null;\n if (trimmed === 'undefined') return undefined;\n if (/^-?\\d+(\\.\\d+)?$/.test(trimmed)) return Number(trimmed);\n if (this.isQuoted(trimmed)) return trimmed.slice(1, -1);\n\n const comparison = this.evaluateComparison(trimmed, context);\n if (comparison !== undefined) {\n return comparison;\n }\n\n return this.resolvePath(trimmed, context);\n }\n\n private evaluateBooleanExpression(\n expression: string,\n context: WorkflowRuntimeContext,\n ): boolean {\n const orParts = this.splitTopLevel(expression, '||');\n if (orParts.length > 1) {\n return orParts.some((part) => this.evaluateCondition(part, context));\n }\n\n const andParts = this.splitTopLevel(expression, '&&');\n if (andParts.length > 1) {\n return andParts.every((part) => this.evaluateCondition(part, context));\n }\n\n const comparison = this.evaluateComparison(expression, context);\n if (comparison !== undefined) {\n return comparison;\n }\n\n return Boolean(this.resolveExpression(expression, context));\n }\n\n private evaluateComparison(\n expression: string,\n context: WorkflowRuntimeContext,\n ): boolean | undefined {\n const match = expression.match(/^(.+?)\\s*(===|!==|==|!=|>=|<=|>|<)\\s*(.+)$/);\n if (!match) {\n return undefined;\n }\n\n const left = this.resolveOperand(match[1], context);\n const operator = match[2];\n const right = this.resolveOperand(match[3], context);\n\n switch (operator) {\n case '===':\n return left === right;\n case '!==':\n return left !== right;\n case '==':\n return left == right;\n case '!=':\n return left != right;\n case '>=':\n return Number(left) >= Number(right);\n case '<=':\n return Number(left) <= Number(right);\n case '>':\n return Number(left) > Number(right);\n case '<':\n return Number(left) < Number(right);\n default:\n return undefined;\n }\n }\n\n private resolveOperand(\n operand: string,\n context: WorkflowRuntimeContext,\n ): any {\n return this.resolveExpression(this.unwrapExpression(operand), context);\n }\n\n private resolvePath(path: string, context: WorkflowRuntimeContext): any {\n const root = {\n inputs: context.input,\n input: context.input,\n variables: context.variables,\n secrets: context.secrets,\n outputs: context.outputs,\n execution: context.execution,\n node: context.node,\n item: context.item,\n index: context.index,\n };\n\n const parts = path\n .replace(/\\[(?:'|\")([^'\"]+)(?:'|\")\\]/g, '.$1')\n .split('.')\n .filter(Boolean);\n\n return parts.reduce((current, key) => {\n if (current === null || current === undefined) {\n return undefined;\n }\n return current[key];\n }, root as any);\n }\n\n private unwrapExpression(expression: string): string {\n const match = expression.trim().match(/^\\{\\{\\s*(.*?)\\s*\\}\\}$/);\n return match ? match[1] : expression.trim();\n }\n\n private splitTopLevel(expression: string, token: string): string[] {\n return expression\n .split(token)\n .map((part) => part.trim())\n .filter(Boolean);\n }\n\n private isQuoted(value: string): boolean {\n return (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n );\n }\n}\n"]}
1
+ {"version":3,"file":"workflow-expression.service.js","sourceRoot":"","sources":["../../../src/services/workflow/workflow-expression.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@nestjs/common';\nimport {\n WorkflowExpressionResolver,\n WorkflowRuntimeContext,\n} from '../../types/workflow-dsl.types';\n\n@Injectable()\nexport class WorkflowExpressionService implements WorkflowExpressionResolver {\n interpolate<T = any>(value: T, context: WorkflowRuntimeContext): T {\n if (Array.isArray(value)) {\n return value.map((entry) => this.interpolate(entry, context)) as T;\n }\n\n if (value && typeof value === 'object') {\n return Object.entries(value).reduce((acc, [key, entry]) => {\n acc[key] = this.interpolate(entry, context);\n return acc;\n }, {} as Record<string, any>) as T;\n }\n\n if (typeof value !== 'string') {\n return value;\n }\n\n const exactExpression = value.match(/^\\s*\\{\\{\\s*(.*?)\\s*\\}\\}\\s*$/);\n if (exactExpression) {\n return this.resolveExpression(exactExpression[1], context);\n }\n\n return value.replace(/\\{\\{\\s*(.*?)\\s*\\}\\}/g, (_match, expression) => {\n const resolved = this.resolveExpression(expression, context);\n return resolved === null || resolved === undefined ? '' : String(resolved);\n }) as T;\n }\n\n evaluateCondition(expression: any, context: WorkflowRuntimeContext): boolean {\n const resolved =\n typeof expression === 'string'\n ? this.resolveExpression(this.unwrapExpression(expression), context)\n : expression;\n\n if (typeof resolved === 'string') {\n return this.evaluateBooleanExpression(resolved, context);\n }\n\n return Boolean(resolved);\n }\n\n resolveExpression(expression: string, context: WorkflowRuntimeContext): any {\n const trimmed = expression.trim();\n\n if (trimmed === 'true') return true;\n if (trimmed === 'false') return false;\n if (trimmed === 'null') return null;\n if (trimmed === 'undefined') return undefined;\n if (/^-?\\d+(\\.\\d+)?$/.test(trimmed)) return Number(trimmed);\n if (this.isQuoted(trimmed)) return trimmed.slice(1, -1);\n\n const comparison = this.evaluateComparison(trimmed, context);\n if (comparison !== undefined) {\n return comparison;\n }\n\n return this.resolvePath(trimmed, context);\n }\n\n private evaluateBooleanExpression(\n expression: string,\n context: WorkflowRuntimeContext,\n ): boolean {\n const orParts = this.splitTopLevel(expression, '||');\n if (orParts.length > 1) {\n return orParts.some((part) => this.evaluateCondition(part, context));\n }\n\n const andParts = this.splitTopLevel(expression, '&&');\n if (andParts.length > 1) {\n return andParts.every((part) => this.evaluateCondition(part, context));\n }\n\n const comparison = this.evaluateComparison(expression, context);\n if (comparison !== undefined) {\n return comparison;\n }\n\n return Boolean(this.resolveExpression(expression, context));\n }\n\n private evaluateComparison(\n expression: string,\n context: WorkflowRuntimeContext,\n ): boolean | undefined {\n const match = expression.match(/^(.+?)\\s*(===|!==|==|!=|>=|<=|>|<)\\s*(.+)$/);\n if (!match) {\n return undefined;\n }\n\n const left = this.resolveOperand(match[1], context);\n const operator = match[2];\n const right = this.resolveOperand(match[3], context);\n\n switch (operator) {\n case '===':\n return left === right;\n case '!==':\n return left !== right;\n case '==':\n return left == right;\n case '!=':\n return left != right;\n case '>=':\n return Number(left) >= Number(right);\n case '<=':\n return Number(left) <= Number(right);\n case '>':\n return Number(left) > Number(right);\n case '<':\n return Number(left) < Number(right);\n default:\n return undefined;\n }\n }\n\n private resolveOperand(\n operand: string,\n context: WorkflowRuntimeContext,\n ): any {\n return this.resolveExpression(this.unwrapExpression(operand), context);\n }\n\n private resolvePath(path: string, context: WorkflowRuntimeContext): any {\n const root = {\n inputs: context.input,\n input: context.input,\n variables: context.variables,\n secrets: context.secrets,\n outputs: context.outputs,\n execution: context.execution,\n node: context.node,\n item: context.item,\n index: context.index,\n parent: context.parent,\n parents: context.parents,\n loops: context.loops,\n error: context.error,\n };\n\n const parts = path\n .replace(/\\[(?:'|\")([^'\"]+)(?:'|\")\\]/g, '.$1')\n .replace(/\\[(\\d+)\\]/g, '.$1')\n .split('.')\n .filter(Boolean);\n\n return parts.reduce((current, key) => {\n if (current === null || current === undefined) {\n return undefined;\n }\n return current[key];\n }, root as any);\n }\n\n private unwrapExpression(expression: string): string {\n const match = expression.trim().match(/^\\{\\{\\s*(.*?)\\s*\\}\\}$/);\n return match ? match[1] : expression.trim();\n }\n\n private splitTopLevel(expression: string, token: string): string[] {\n return expression\n .split(token)\n .map((part) => part.trim())\n .filter(Boolean);\n }\n\n private isQuoted(value: string): boolean {\n return (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n );\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { OnModuleInit } from '@nestjs/common';
2
2
  import { DiscoveryService, Reflector } from '@nestjs/core';
3
3
  import { WorkflowNodeHandler } from '../../interfaces/workflow-node-handler.interface';
4
- import { WorkflowNodeMetadataResponse } from '../../types/workflow-dsl.types';
4
+ import { WorkflowNodeMetadataResponse, WorkflowNodeProviderMetadata } from '../../types/workflow-dsl.types';
5
5
  export declare class WorkflowNodeRegistryService implements OnModuleInit {
6
6
  private readonly discoveryService;
7
7
  private readonly reflector;
@@ -10,6 +10,7 @@ export declare class WorkflowNodeRegistryService implements OnModuleInit {
10
10
  constructor(discoveryService: DiscoveryService, reflector: Reflector);
11
11
  onModuleInit(): void;
12
12
  get(type: string): WorkflowNodeHandler;
13
+ getMetadata(type: string): WorkflowNodeProviderMetadata;
13
14
  list(): WorkflowNodeMetadataResponse[];
14
15
  has(type: string): boolean;
15
16
  private registerProvider;
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-node-registry.service.d.ts","sourceRoot":"","sources":["../../../src/services/workflow/workflow-node-registry.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAK3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kDAAkD,CAAC;AACvF,OAAO,EACL,4BAA4B,EAE7B,MAAM,gCAAgC,CAAC;AAOxC,qBACa,2BAA4B,YAAW,YAAY;IAK5D,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgD;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqD;gBAG5D,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,SAAS;IAGvC,YAAY;IAYZ,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB;IAWtC,IAAI,IAAI,4BAA4B,EAAE;IActC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,OAAO,CAAC,gBAAgB;IAiCxB,OAAO,CAAC,kBAAkB;CAkC3B"}
1
+ {"version":3,"file":"workflow-node-registry.service.d.ts","sourceRoot":"","sources":["../../../src/services/workflow/workflow-node-registry.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAK3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kDAAkD,CAAC;AACvF,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,EAC7B,MAAM,gCAAgC,CAAC;AAOxC,qBACa,2BAA4B,YAAW,YAAY;IAK5D,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgD;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqD;gBAG5D,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,SAAS;IAGvC,YAAY;IAYZ,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB;IAWtC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,4BAA4B;IAWvD,IAAI,IAAI,4BAA4B,EAAE;IActC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,OAAO,CAAC,gBAAgB;IAiCxB,OAAO,CAAC,kBAAkB;CAkC3B"}
@@ -34,6 +34,13 @@ let WorkflowNodeRegistryService = WorkflowNodeRegistryService_1 = class Workflow
34
34
  }
35
35
  return provider.handler;
36
36
  }
37
+ getMetadata(type) {
38
+ const provider = this.providers.get(type);
39
+ if (!provider) {
40
+ throw new common_1.BadRequestException(`No workflow node provider registered for type "${type}".`);
41
+ }
42
+ return provider.metadata;
43
+ }
37
44
  list() {
38
45
  return Array.from(this.providers.values())
39
46
  .map(({ metadata }) => this.toMetadataResponse(metadata))
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-node-registry.service.js","sourceRoot":"","sources":["../../../src/services/workflow/workflow-node-registry.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BadRequestException,\n Injectable,\n Logger,\n OnModuleInit,\n} from '@nestjs/common';\nimport { DiscoveryService, Reflector } from '@nestjs/core';\nimport { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';\nimport {\n WORKFLOW_NODE_PROVIDER_METADATA,\n} from '../../decorators/workflow-node-provider.decorator';\nimport { WorkflowNodeHandler } from '../../interfaces/workflow-node-handler.interface';\nimport {\n WorkflowNodeMetadataResponse,\n WorkflowNodeProviderMetadata,\n} from '../../types/workflow-dsl.types';\n\ninterface RegisteredWorkflowNodeProvider {\n metadata: WorkflowNodeProviderMetadata;\n handler: WorkflowNodeHandler;\n}\n\n@Injectable()\nexport class WorkflowNodeRegistryService implements OnModuleInit {\n private readonly logger = new Logger(WorkflowNodeRegistryService.name);\n private readonly providers = new Map<string, RegisteredWorkflowNodeProvider>();\n\n constructor(\n private readonly discoveryService: DiscoveryService,\n private readonly reflector: Reflector,\n ) {}\n\n onModuleInit() {\n for (const provider of this.discoveryService.getProviders()) {\n this.registerProvider(provider);\n }\n\n this.logger.log(\n `Registered workflow node providers: ${Array.from(\n this.providers.keys(),\n ).join(', ')}`,\n );\n }\n\n get(type: string): WorkflowNodeHandler {\n const provider = this.providers.get(type);\n if (!provider) {\n throw new BadRequestException(\n `No workflow node provider registered for type \"${type}\".`,\n );\n }\n\n return provider.handler;\n }\n\n list(): WorkflowNodeMetadataResponse[] {\n return Array.from(this.providers.values())\n .map(({ metadata }) => this.toMetadataResponse(metadata))\n .sort((left, right) => {\n const leftCategory = left.category ?? '';\n const rightCategory = right.category ?? '';\n if (leftCategory !== rightCategory) {\n return leftCategory.localeCompare(rightCategory);\n }\n\n return (left.label ?? left.type).localeCompare(right.label ?? right.type);\n });\n }\n\n has(type: string): boolean {\n return this.providers.has(type);\n }\n\n private registerProvider(provider: InstanceWrapper) {\n const metatype = provider.metatype;\n if (!metatype || typeof metatype !== 'function') {\n return;\n }\n\n const metadata = this.reflector.get<WorkflowNodeProviderMetadata>(\n WORKFLOW_NODE_PROVIDER_METADATA,\n metatype,\n );\n\n if (!metadata?.type) {\n return;\n }\n\n const instance = provider.instance as WorkflowNodeHandler | undefined;\n if (!instance || typeof instance.execute !== 'function') {\n this.logger.warn(\n `Workflow node provider \"${metadata.type}\" has no executable instance.`,\n );\n return;\n }\n\n if (this.providers.has(metadata.type)) {\n this.logger.warn(\n `Duplicate workflow node provider type \"${metadata.type}\" ignored.`,\n );\n return;\n }\n\n this.providers.set(metadata.type, { metadata, handler: instance });\n }\n\n private toMetadataResponse(\n metadata: WorkflowNodeProviderMetadata,\n ): WorkflowNodeMetadataResponse {\n const resolvedIcon = metadata.ui?.icon ?? metadata.icon;\n\n return {\n type: metadata.type,\n kind: metadata.kind,\n version: metadata.version,\n category: metadata.category,\n subcategory: metadata.subcategory,\n label: metadata.label,\n description: metadata.description,\n icon: resolvedIcon,\n tags: metadata.tags,\n configSchema: metadata.configSchema,\n uiSchema: metadata.uiSchema,\n outputSchema: metadata.outputSchema,\n examples: metadata.examples,\n metrics: metadata.metrics,\n definitions: metadata.definitions,\n authoring: metadata.authoring,\n runtime: metadata.runtime,\n documentation: metadata.documentation,\n ui: metadata.ui\n ? {\n ...metadata.ui,\n icon: metadata.ui.icon ?? resolvedIcon,\n }\n : resolvedIcon\n ? { icon: resolvedIcon }\n : undefined,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"workflow-node-registry.service.js","sourceRoot":"","sources":["../../../src/services/workflow/workflow-node-registry.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BadRequestException,\n Injectable,\n Logger,\n OnModuleInit,\n} from '@nestjs/common';\nimport { DiscoveryService, Reflector } from '@nestjs/core';\nimport { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';\nimport {\n WORKFLOW_NODE_PROVIDER_METADATA,\n} from '../../decorators/workflow-node-provider.decorator';\nimport { WorkflowNodeHandler } from '../../interfaces/workflow-node-handler.interface';\nimport {\n WorkflowNodeMetadataResponse,\n WorkflowNodeProviderMetadata,\n} from '../../types/workflow-dsl.types';\n\ninterface RegisteredWorkflowNodeProvider {\n metadata: WorkflowNodeProviderMetadata;\n handler: WorkflowNodeHandler;\n}\n\n@Injectable()\nexport class WorkflowNodeRegistryService implements OnModuleInit {\n private readonly logger = new Logger(WorkflowNodeRegistryService.name);\n private readonly providers = new Map<string, RegisteredWorkflowNodeProvider>();\n\n constructor(\n private readonly discoveryService: DiscoveryService,\n private readonly reflector: Reflector,\n ) {}\n\n onModuleInit() {\n for (const provider of this.discoveryService.getProviders()) {\n this.registerProvider(provider);\n }\n\n this.logger.log(\n `Registered workflow node providers: ${Array.from(\n this.providers.keys(),\n ).join(', ')}`,\n );\n }\n\n get(type: string): WorkflowNodeHandler {\n const provider = this.providers.get(type);\n if (!provider) {\n throw new BadRequestException(\n `No workflow node provider registered for type \"${type}\".`,\n );\n }\n\n return provider.handler;\n }\n\n getMetadata(type: string): WorkflowNodeProviderMetadata {\n const provider = this.providers.get(type);\n if (!provider) {\n throw new BadRequestException(\n `No workflow node provider registered for type \"${type}\".`,\n );\n }\n\n return provider.metadata;\n }\n\n list(): WorkflowNodeMetadataResponse[] {\n return Array.from(this.providers.values())\n .map(({ metadata }) => this.toMetadataResponse(metadata))\n .sort((left, right) => {\n const leftCategory = left.category ?? '';\n const rightCategory = right.category ?? '';\n if (leftCategory !== rightCategory) {\n return leftCategory.localeCompare(rightCategory);\n }\n\n return (left.label ?? left.type).localeCompare(right.label ?? right.type);\n });\n }\n\n has(type: string): boolean {\n return this.providers.has(type);\n }\n\n private registerProvider(provider: InstanceWrapper) {\n const metatype = provider.metatype;\n if (!metatype || typeof metatype !== 'function') {\n return;\n }\n\n const metadata = this.reflector.get<WorkflowNodeProviderMetadata>(\n WORKFLOW_NODE_PROVIDER_METADATA,\n metatype,\n );\n\n if (!metadata?.type) {\n return;\n }\n\n const instance = provider.instance as WorkflowNodeHandler | undefined;\n if (!instance || typeof instance.execute !== 'function') {\n this.logger.warn(\n `Workflow node provider \"${metadata.type}\" has no executable instance.`,\n );\n return;\n }\n\n if (this.providers.has(metadata.type)) {\n this.logger.warn(\n `Duplicate workflow node provider type \"${metadata.type}\" ignored.`,\n );\n return;\n }\n\n this.providers.set(metadata.type, { metadata, handler: instance });\n }\n\n private toMetadataResponse(\n metadata: WorkflowNodeProviderMetadata,\n ): WorkflowNodeMetadataResponse {\n const resolvedIcon = metadata.ui?.icon ?? metadata.icon;\n\n return {\n type: metadata.type,\n kind: metadata.kind,\n version: metadata.version,\n category: metadata.category,\n subcategory: metadata.subcategory,\n label: metadata.label,\n description: metadata.description,\n icon: resolvedIcon,\n tags: metadata.tags,\n configSchema: metadata.configSchema,\n uiSchema: metadata.uiSchema,\n outputSchema: metadata.outputSchema,\n examples: metadata.examples,\n metrics: metadata.metrics,\n definitions: metadata.definitions,\n authoring: metadata.authoring,\n runtime: metadata.runtime,\n documentation: metadata.documentation,\n ui: metadata.ui\n ? {\n ...metadata.ui,\n icon: metadata.ui.icon ?? resolvedIcon,\n }\n : resolvedIcon\n ? { icon: resolvedIcon }\n : undefined,\n };\n }\n}\n"]}
@@ -36,6 +36,11 @@ export declare class WorkflowRuntimeService {
36
36
  private resolveWorkflowVariables;
37
37
  private runNodes;
38
38
  private runNode;
39
+ private runGlobalErrorHandlers;
40
+ private runFinallyHandlers;
41
+ private runLocalErrorHandlers;
42
+ private runErrorHandlers;
43
+ private buildErrorContext;
39
44
  private assertDefinitionYaml;
40
45
  private readEnqueuedExecutionRequest;
41
46
  private findExecutionOrThrow;
@@ -46,6 +51,9 @@ export declare class WorkflowRuntimeService {
46
51
  private nextLogSequence;
47
52
  private countNodes;
48
53
  private nodeLogMetadata;
54
+ private getRuntimeContextOutput;
55
+ private cloneOutput;
56
+ private deletePath;
49
57
  private summarizeValue;
50
58
  private errorMessage;
51
59
  private summarizeError;
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-runtime.service.d.ts","sourceRoot":"","sources":["../../../src/services/workflow/workflow-runtime.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIxC,OAAO,EAEL,wBAAwB,EACxB,yBAAyB,EAG1B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,kCAAkC,EAAE,MAAM,yCAAyC,CAAC;AAC7F,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,6BAA6B,EAAE,MAAM,4CAA4C,CAAC;AAG3F,qBACa,sBAAsB;IAK/B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IACtC,OAAO,CAAC,QAAQ,CAAC,iCAAiC;IAVpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;gBAI/C,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,2BAA2B,EACrC,UAAU,EAAE,yBAAyB,EACrC,MAAM,EAAE,8BAA8B,EACtC,SAAS,EAAE,kCAAkC,EAC7C,qBAAqB,EAAE,qBAAqB,EAC5C,iCAAiC,EAAE,gBAAgB,CAAC,6BAA6B,CAAC;IAG/F,qBAAqB,CACzB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,yBAAyB,CAAC;IAQ/B,0BAA0B,CAC9B,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,yBAAyB,CAAC;IAQ/B,sBAAsB,CAC1B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,yBAAyB,CAAC;IAQ/B,2BAA2B,CAC/B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,yBAAyB,CAAC;YAQvB,sBAAsB;YAqBtB,iBAAiB;IAiBzB,wBAAwB,CAC5B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,yBAAyB,CAAC;YAoBvB,iBAAiB;IA+FzB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAK3E,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAiBpD,aAAa,CACjB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAClE,OAAO,CAAC,GAAG,CAAC;IAkCf,OAAO,CAAC,oBAAoB;IA6C5B,OAAO,CAAC,wBAAwB;YAoBlB,QAAQ;YAWR,OAAO;IAkIrB,OAAO,CAAC,oBAAoB;IA+B5B,OAAO,CAAC,4BAA4B;YAkBtB,oBAAoB;IAYlC,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,eAAe;IA0BvB,OAAO,CAAC,cAAc;IAqBtB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,cAAc;CAWvB"}
1
+ {"version":3,"file":"workflow-runtime.service.d.ts","sourceRoot":"","sources":["../../../src/services/workflow/workflow-runtime.service.ts"],"names":[],"mappings":"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"}