callman-core 1.18.0 → 1.20.0

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 (105) hide show
  1. package/dist/host/db/connectionMapping.d.ts +4 -0
  2. package/dist/host/db/connectionMapping.d.ts.map +1 -1
  3. package/dist/host/db/connectionMapping.js +4 -0
  4. package/dist/host/db/connectionMapping.js.map +1 -1
  5. package/dist/host/db/pgClientConfig.d.ts +11 -0
  6. package/dist/host/db/pgClientConfig.d.ts.map +1 -0
  7. package/dist/host/db/pgClientConfig.js +83 -0
  8. package/dist/host/db/pgClientConfig.js.map +1 -0
  9. package/dist/host/db/pgSessionManager.d.ts +18 -0
  10. package/dist/host/db/pgSessionManager.d.ts.map +1 -0
  11. package/dist/host/db/pgSessionManager.js +162 -0
  12. package/dist/host/db/pgSessionManager.js.map +1 -0
  13. package/dist/host/db/postgresAdapter.d.ts.map +1 -1
  14. package/dist/host/db/postgresAdapter.js +7 -36
  15. package/dist/host/db/postgresAdapter.js.map +1 -1
  16. package/dist/host/db/queryExecutor.d.ts +4 -0
  17. package/dist/host/db/queryExecutor.d.ts.map +1 -1
  18. package/dist/host/db/queryExecutor.js +40 -2
  19. package/dist/host/db/queryExecutor.js.map +1 -1
  20. package/dist/host/db/sqlState.d.ts +2 -0
  21. package/dist/host/db/sqlState.d.ts.map +1 -0
  22. package/dist/host/db/sqlState.js +14 -0
  23. package/dist/host/db/sqlState.js.map +1 -0
  24. package/dist/host/db/types.d.ts +13 -0
  25. package/dist/host/db/types.d.ts.map +1 -1
  26. package/dist/host/index.d.ts +3 -0
  27. package/dist/host/index.d.ts.map +1 -1
  28. package/dist/host/index.js +7 -0
  29. package/dist/host/index.js.map +1 -1
  30. package/dist/scenario-runner/adapters/connection-config.d.ts +4 -0
  31. package/dist/scenario-runner/adapters/connection-config.d.ts.map +1 -1
  32. package/dist/scenario-runner/adapters/db-executor.d.ts +7 -1
  33. package/dist/scenario-runner/adapters/db-executor.d.ts.map +1 -1
  34. package/dist/scenario-runner/adapters/db-executor.js +106 -1
  35. package/dist/scenario-runner/adapters/db-executor.js.map +1 -1
  36. package/dist/scenario-runner/adapters/index.d.ts +2 -1
  37. package/dist/scenario-runner/adapters/index.d.ts.map +1 -1
  38. package/dist/scenario-runner/adapters/index.js +11 -1
  39. package/dist/scenario-runner/adapters/index.js.map +1 -1
  40. package/dist/scenario-runner/adapters/types.d.ts +9 -0
  41. package/dist/scenario-runner/adapters/types.d.ts.map +1 -1
  42. package/dist/scenario-runner/adapters/websocket-executor.d.ts +4 -0
  43. package/dist/scenario-runner/adapters/websocket-executor.d.ts.map +1 -0
  44. package/dist/scenario-runner/adapters/websocket-executor.js +20 -0
  45. package/dist/scenario-runner/adapters/websocket-executor.js.map +1 -0
  46. package/dist/scenario-runner/condition.d.ts +1 -0
  47. package/dist/scenario-runner/condition.d.ts.map +1 -1
  48. package/dist/scenario-runner/condition.js +138 -2
  49. package/dist/scenario-runner/condition.js.map +1 -1
  50. package/dist/scenario-runner/conditionTypes.d.ts +1 -1
  51. package/dist/scenario-runner/conditionTypes.d.ts.map +1 -1
  52. package/dist/scenario-runner/graphTraversal.d.ts +8 -0
  53. package/dist/scenario-runner/graphTraversal.d.ts.map +1 -1
  54. package/dist/scenario-runner/graphTraversal.js +9 -0
  55. package/dist/scenario-runner/graphTraversal.js.map +1 -1
  56. package/dist/scenario-runner/index.d.ts +1 -0
  57. package/dist/scenario-runner/index.d.ts.map +1 -1
  58. package/dist/scenario-runner/index.js +1 -0
  59. package/dist/scenario-runner/index.js.map +1 -1
  60. package/dist/scenario-runner/nodePolicy.d.ts +2 -2
  61. package/dist/scenario-runner/nodePolicy.d.ts.map +1 -1
  62. package/dist/scenario-runner/nodePolicy.js +2 -0
  63. package/dist/scenario-runner/nodePolicy.js.map +1 -1
  64. package/dist/scenario-runner/runScenario.d.ts.map +1 -1
  65. package/dist/scenario-runner/runScenario.js +202 -2
  66. package/dist/scenario-runner/runScenario.js.map +1 -1
  67. package/dist/scenario-runner/types.d.ts +142 -3
  68. package/dist/scenario-runner/types.d.ts.map +1 -1
  69. package/dist/scenario-runner/websocket.d.ts +17 -0
  70. package/dist/scenario-runner/websocket.d.ts.map +1 -0
  71. package/dist/scenario-runner/websocket.js +74 -0
  72. package/dist/scenario-runner/websocket.js.map +1 -0
  73. package/dist-cjs/host/db/connectionMapping.js +4 -0
  74. package/dist-cjs/host/db/connectionMapping.js.map +1 -1
  75. package/dist-cjs/host/db/pgClientConfig.js +90 -0
  76. package/dist-cjs/host/db/pgClientConfig.js.map +1 -0
  77. package/dist-cjs/host/db/pgSessionManager.js +170 -0
  78. package/dist-cjs/host/db/pgSessionManager.js.map +1 -0
  79. package/dist-cjs/host/db/postgresAdapter.js +7 -36
  80. package/dist-cjs/host/db/postgresAdapter.js.map +1 -1
  81. package/dist-cjs/host/db/queryExecutor.js +40 -2
  82. package/dist-cjs/host/db/queryExecutor.js.map +1 -1
  83. package/dist-cjs/host/db/sqlState.js +18 -0
  84. package/dist-cjs/host/db/sqlState.js.map +1 -0
  85. package/dist-cjs/host/index.js +16 -1
  86. package/dist-cjs/host/index.js.map +1 -1
  87. package/dist-cjs/scenario-runner/adapters/db-executor.js +108 -2
  88. package/dist-cjs/scenario-runner/adapters/db-executor.js.map +1 -1
  89. package/dist-cjs/scenario-runner/adapters/index.js +14 -1
  90. package/dist-cjs/scenario-runner/adapters/index.js.map +1 -1
  91. package/dist-cjs/scenario-runner/adapters/websocket-executor.js +24 -0
  92. package/dist-cjs/scenario-runner/adapters/websocket-executor.js.map +1 -0
  93. package/dist-cjs/scenario-runner/condition.js +140 -3
  94. package/dist-cjs/scenario-runner/condition.js.map +1 -1
  95. package/dist-cjs/scenario-runner/graphTraversal.js +10 -1
  96. package/dist-cjs/scenario-runner/graphTraversal.js.map +1 -1
  97. package/dist-cjs/scenario-runner/index.js +1 -0
  98. package/dist-cjs/scenario-runner/index.js.map +1 -1
  99. package/dist-cjs/scenario-runner/nodePolicy.js +2 -0
  100. package/dist-cjs/scenario-runner/nodePolicy.js.map +1 -1
  101. package/dist-cjs/scenario-runner/runScenario.js +201 -1
  102. package/dist-cjs/scenario-runner/runScenario.js.map +1 -1
  103. package/dist-cjs/scenario-runner/websocket.js +79 -0
  104. package/dist-cjs/scenario-runner/websocket.js.map +1 -0
  105. package/package.json +1 -1
@@ -10,4 +10,5 @@ export * from "./conditionTypes.js";
10
10
  export * from "./graphTraversal.js";
11
11
  export * from "./types.js";
12
12
  export * from "./adapters/index.js";
13
+ export * from "./websocket.js";
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scenario-runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,8CAA8C,EAC9C,iCAAiC,EACjC,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAM/B,cAAc,gBAAgB,CAAC;AAE/B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,gCAAgC,EAChC,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scenario-runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,8CAA8C,EAC9C,iCAAiC,EACjC,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAM/B,cAAc,gBAAgB,CAAC;AAE/B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,gCAAgC,EAChC,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
@@ -18,4 +18,5 @@ export * from "./conditionTypes.js";
18
18
  export * from "./graphTraversal.js";
19
19
  export * from "./types.js";
20
20
  export * from "./adapters/index.js";
21
+ export * from "./websocket.js";
21
22
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scenario-runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,8CAA8C,EAC9C,iCAAiC,EACjC,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAC/B,iEAAiE;AACjE,qEAAqE;AACrE,uEAAuE;AACvE,uEAAuE;AACvE,iCAAiC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,2EAA2E;AAC3E,cAAc,iBAAiB,CAAC;AAChC,sEAAsE;AACtE,oEAAoE;AACpE,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,gCAAgC,EAChC,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scenario-runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,8CAA8C,EAC9C,iCAAiC,EACjC,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAC/B,iEAAiE;AACjE,qEAAqE;AACrE,uEAAuE;AACvE,uEAAuE;AACvE,iCAAiC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,2EAA2E;AAC3E,cAAc,iBAAiB,CAAC;AAChC,sEAAsE;AACtE,oEAAoE;AACpE,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,gCAAgC,EAChC,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { AggregatorScenarioNode, DbScenarioNode, EndScenarioNode, KafkaScenarioNode, NotificationScenarioNode, RedisScenarioNode, RequestScenarioNode, ScenarioNode, ScenarioNodeExecutionPolicy, ScenarioPolicyCapableNode, ScenarioPolicyCapableNodeType, ScriptScenarioNode, SubScenarioNode, ForeachScenarioNode, WaitScenarioNode } from "./types.js";
1
+ import { AggregatorScenarioNode, DbScenarioNode, EndScenarioNode, KafkaScenarioNode, NotificationScenarioNode, RedisScenarioNode, RequestScenarioNode, ScenarioNode, ScenarioNodeExecutionPolicy, ScenarioPolicyCapableNode, ScenarioPolicyCapableNodeType, ScriptScenarioNode, SubScenarioNode, ForeachScenarioNode, WebsocketScenarioNode, WaitScenarioNode } from "./types.js";
2
2
  export declare const STRICT_SCENARIO_NODE_EXECUTION_POLICY: ScenarioNodeExecutionPolicy;
3
3
  export declare const supportsScenarioNodeExecutionPolicy: (nodeOrType: ScenarioNode | ScenarioPolicyCapableNodeType) => nodeOrType is ScenarioPolicyCapableNode | ScenarioPolicyCapableNodeType;
4
4
  export declare const normalizeScenarioNodeExecutionPolicy: (value: unknown, fallback?: ScenarioNodeExecutionPolicy) => ScenarioNodeExecutionPolicy;
@@ -7,5 +7,5 @@ export declare const getNewScenarioNodeExecutionPolicyPreset: (type: ScenarioPol
7
7
  export declare const getScenarioNodeExecutionPolicy: (node: ScenarioPolicyCapableNode) => ScenarioNodeExecutionPolicy;
8
8
  export declare const getScenarioNodeMaxAttempts: (policy: ScenarioNodeExecutionPolicy) => number;
9
9
  export declare const getScenarioNodePolicyBadges: (node: ScenarioPolicyCapableNode) => string[];
10
- export declare const patchScenarioNodeExecutionPolicy: <TNode extends RequestScenarioNode | DbScenarioNode | WaitScenarioNode | ScriptScenarioNode | KafkaScenarioNode | RedisScenarioNode | NotificationScenarioNode | EndScenarioNode | AggregatorScenarioNode | SubScenarioNode | ForeachScenarioNode>(node: TNode, executionPolicy: ScenarioNodeExecutionPolicy) => TNode;
10
+ export declare const patchScenarioNodeExecutionPolicy: <TNode extends RequestScenarioNode | DbScenarioNode | WaitScenarioNode | ScriptScenarioNode | KafkaScenarioNode | RedisScenarioNode | NotificationScenarioNode | EndScenarioNode | AggregatorScenarioNode | SubScenarioNode | ForeachScenarioNode | WebsocketScenarioNode>(node: TNode, executionPolicy: ScenarioNodeExecutionPolicy) => TNode;
11
11
  //# sourceMappingURL=nodePolicy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nodePolicy.d.ts","sourceRoot":"","sources":["../../src/scenario-runner/nodePolicy.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,qCAAqC,EAAE,2BAOnD,CAAC;AA4DF,eAAO,MAAM,mCAAmC,GAC9C,YAAY,YAAY,GAAG,6BAA6B,KACvD,UAAU,IAAI,yBAAyB,GAAG,6BAI5C,CAAC;AAEF,eAAO,MAAM,oCAAoC,GAC/C,OAAO,OAAO,EACd,WAAU,2BAAmE,KAC5E,2BA+DF,CAAC;AAEF,eAAO,MAAM,oCAAoC,QAAO,2BACJ,CAAC;AAErD,eAAO,MAAM,uCAAuC,GAClD,MAAM,6BAA6B,KAClC,2BAAqF,CAAC;AAEzF,eAAO,MAAM,8BAA8B,GACzC,MAAM,yBAAyB,KAC9B,2BAIA,CAAC;AAEJ,eAAO,MAAM,0BAA0B,GACrC,QAAQ,2BAA2B,KAClC,MAA4E,CAAC;AAEhF,eAAO,MAAM,2BAA2B,GACtC,MAAM,yBAAyB,KAC9B,MAAM,EAeR,CAAC;AAEF,eAAO,MAAM,gCAAgC,GAC3C,KAAK,SACD,mBAAmB,GACnB,cAAc,GACd,gBAAgB,GAChB,kBAAkB,GAClB,iBAAiB,GACjB,iBAAiB,GACjB,wBAAwB,GACxB,eAAe,GACf,sBAAsB,GACtB,eAAe,GACf,mBAAmB,EAEvB,MAAM,KAAK,EACX,iBAAiB,2BAA2B,KAC3C,KASD,CAAC"}
1
+ {"version":3,"file":"nodePolicy.d.ts","sourceRoot":"","sources":["../../src/scenario-runner/nodePolicy.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,qCAAqC,EAAE,2BAOnD,CAAC;AA8DF,eAAO,MAAM,mCAAmC,GAC9C,YAAY,YAAY,GAAG,6BAA6B,KACvD,UAAU,IAAI,yBAAyB,GAAG,6BAI5C,CAAC;AAEF,eAAO,MAAM,oCAAoC,GAC/C,OAAO,OAAO,EACd,WAAU,2BAAmE,KAC5E,2BA+DF,CAAC;AAEF,eAAO,MAAM,oCAAoC,QAAO,2BACJ,CAAC;AAErD,eAAO,MAAM,uCAAuC,GAClD,MAAM,6BAA6B,KAClC,2BAAqF,CAAC;AAEzF,eAAO,MAAM,8BAA8B,GACzC,MAAM,yBAAyB,KAC9B,2BAIA,CAAC;AAEJ,eAAO,MAAM,0BAA0B,GACrC,QAAQ,2BAA2B,KAClC,MAA4E,CAAC;AAEhF,eAAO,MAAM,2BAA2B,GACtC,MAAM,yBAAyB,KAC9B,MAAM,EAeR,CAAC;AAEF,eAAO,MAAM,gCAAgC,GAC3C,KAAK,SACD,mBAAmB,GACnB,cAAc,GACd,gBAAgB,GAChB,kBAAkB,GAClB,iBAAiB,GACjB,iBAAiB,GACjB,wBAAwB,GACxB,eAAe,GACf,sBAAsB,GACtB,eAAe,GACf,mBAAmB,GACnB,qBAAqB,EAEzB,MAAM,KAAK,EACX,iBAAiB,2BAA2B,KAC3C,KASD,CAAC"}
@@ -48,6 +48,8 @@ const RECOMMENDED_NEW_NODE_POLICY_PRESETS = {
48
48
  // The item loop IS the repeat mechanism for this node type — retry stays
49
49
  // off (and is force-disabled at execution time in runScenario).
50
50
  foreach: STRICT_SCENARIO_NODE_EXECUTION_POLICY,
51
+ // Retry re-runs the WHOLE conversation (connect -> steps -> close).
52
+ websocket: STRICT_SCENARIO_NODE_EXECUTION_POLICY,
51
53
  };
52
54
  const clonePolicy = (policy) => ({
53
55
  onFailure: policy.onFailure,
@@ -1 +1 @@
1
- {"version":3,"file":"nodePolicy.js","sourceRoot":"","sources":["../../src/scenario-runner/nodePolicy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nodePolicy.js","sourceRoot":"","sources":["../../src/scenario-runner/nodePolicy.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"runScenario.d.ts","sourceRoot":"","sources":["../../src/scenario-runner/runScenario.ts"],"names":[],"mappings":"AAiDA,OAAO,KAAK,EAKV,kBAAkB,EAUlB,iBAAiB,EAKlB,MAAM,YAAY,CAAC;AAwuBpB,eAAO,MAAM,WAAW,GAAU,mGAQ/B,kBAAkB,KAAG,OAAO,CAAC,iBAAiB,CAquEhD,CAAC"}
1
+ {"version":3,"file":"runScenario.d.ts","sourceRoot":"","sources":["../../src/scenario-runner/runScenario.ts"],"names":[],"mappings":"AAyDA,OAAO,KAAK,EAKV,kBAAkB,EAUlB,iBAAiB,EAKlB,MAAM,YAAY,CAAC;AAyuBpB,eAAO,MAAM,WAAW,GAAU,mGAQ/B,kBAAkB,KAAG,OAAO,CAAC,iBAAiB,CAs9EhD,CAAC"}
@@ -1,7 +1,8 @@
1
1
  import { buildConditionOutputPayload, evaluateConditionConfig, evaluateConditionRule, resolveConditionRuntimeValue, validateConditionConfig, } from "./condition.js";
2
2
  import { applyExtract } from "./extraction.js";
3
3
  import { evaluateAssertionConfig, validateAssertionConfig, } from "./assertion.js";
4
- import { createSubScenarioStepId, buildRuntimeStepDescriptors, DEFAULT_END_LOOP_DELAY_MS, DEFAULT_END_LOOP_ITERATIONS, flattenScenarioNodesForContext, MAX_END_LOOP_ITERATIONS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_POLL_MAX_ATTEMPTS, MAX_POLL_ATTEMPTS, DEFAULT_FOREACH_MAX_ITERATIONS, MAX_FOREACH_ITERATIONS, } from "./graphTraversal.js";
4
+ import { createSubScenarioStepId, buildRuntimeStepDescriptors, DEFAULT_END_LOOP_DELAY_MS, DEFAULT_END_LOOP_ITERATIONS, flattenScenarioNodesForContext, MAX_END_LOOP_ITERATIONS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_POLL_MAX_ATTEMPTS, MAX_POLL_ATTEMPTS, DEFAULT_FOREACH_MAX_ITERATIONS, MAX_FOREACH_ITERATIONS, DEFAULT_WS_CONNECT_TIMEOUT_MS, MAX_WS_CONNECT_TIMEOUT_MS, DEFAULT_WS_EXPECT_TIMEOUT_MS, MAX_WS_EXPECT_TIMEOUT_MS, MAX_WS_WAIT_DURATION_MS, MAX_WS_STEPS, DEFAULT_WS_CLOSE_CODE, } from "./graphTraversal.js";
5
+ import { evaluateWebsocketExpect } from "./websocket.js";
5
6
  import { executeWithScenarioNodePolicy } from "./executionPolicyRunner.js";
6
7
  import { getLegacyScenarioNodeExecutionPolicy, getScenarioNodeExecutionPolicy, supportsScenarioNodeExecutionPolicy, } from "./nodePolicy.js";
7
8
  import { buildScenarioExecutionGraph, buildScenarioTemplateValues, collectExclusiveBranchNodeIds, evaluateScenarioExpression, resolveScenarioJsonTemplateString, resolveScenarioTemplateString, } from "./templateResolver.js";
@@ -44,6 +45,7 @@ const RESERVED_WORKFLOW_ROOT_LABELS = new Set([
44
45
  "item",
45
46
  "each",
46
47
  "eaches",
48
+ "ws",
47
49
  ]);
48
50
  const cloneNodeExecutionMeta = (meta) => ({
49
51
  ...meta,
@@ -998,13 +1000,36 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
998
1000
  }
999
1001
  if (node.type === "db") {
1000
1002
  const resolvedQuery = resolveScenarioTemplateString(node.data.config.query, templateValues);
1001
- const resolvedParams = (node.data.config.params ?? []).map((param) => resolveScenarioTemplateString(param, templateValues));
1003
+ // Typed params win over legacy `params`. Types encode into the
1004
+ // wire value here so drivers stay oblivious: `null` → SQL NULL,
1005
+ // `boolean` → real boolean; everything else stays a string and
1006
+ // relies on server-side casts (see DbScenarioParamType docs).
1007
+ const typedParams = node.data.config.typedParams;
1008
+ const resolvedParams = typedParams
1009
+ ? typedParams.map((param) => {
1010
+ if (param.type === "null")
1011
+ return null;
1012
+ const resolved = resolveScenarioTemplateString(param.value ?? "", templateValues);
1013
+ if (param.type === "boolean") {
1014
+ return ["true", "1", "t", "yes"].includes(resolved.trim().toLowerCase());
1015
+ }
1016
+ return resolved;
1017
+ })
1018
+ : (node.data.config.params ?? []).map((param) => resolveScenarioTemplateString(param, templateValues));
1002
1019
  const dbResult = await runtimeAdapters.dbExecutor({
1003
1020
  runId,
1004
1021
  stepId,
1005
1022
  node,
1006
1023
  resolvedQuery,
1007
1024
  resolvedParams,
1025
+ ...(node.data.config.useSession
1026
+ ? {
1027
+ session: {
1028
+ runId,
1029
+ transactionMode: scenario.dbSettings?.transactionMode ?? "none",
1030
+ },
1031
+ }
1032
+ : {}),
1008
1033
  context: createContextSnapshot(runtimeContext),
1009
1034
  signal,
1010
1035
  });
@@ -1445,6 +1470,163 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
1445
1470
  outputData = runtimeContext.kafkaEvent;
1446
1471
  }
1447
1472
  }
1473
+ if (node.type === "websocket") {
1474
+ const wsConfig = node.data.config;
1475
+ const resolvedUrl = resolveScenarioTemplateString(wsConfig.url ?? "", templateValues).trim();
1476
+ if (!resolvedUrl) {
1477
+ throw new ScenarioNodeFailureError("WebSocket URL is required.");
1478
+ }
1479
+ const configuredSteps = wsConfig.steps ?? [];
1480
+ if (configuredSteps.length > MAX_WS_STEPS) {
1481
+ throw new ScenarioNodeFailureError(`WebSocket conversations are capped at ${MAX_WS_STEPS} steps.`);
1482
+ }
1483
+ for (const [stepIndex, step] of configuredSteps.entries()) {
1484
+ if (step.kind === "expect" && (!step.rules || step.rules.length === 0)) {
1485
+ throw new ScenarioNodeFailureError(`WebSocket expect step ${stepIndex + 1} has no rules.`);
1486
+ }
1487
+ }
1488
+ const resolvedHeaders = (wsConfig.headers ?? [])
1489
+ .filter((header) => header.enabled !== false && header.key.trim())
1490
+ .map((header) => ({
1491
+ key: resolveScenarioTemplateString(header.key, templateValues).trim(),
1492
+ value: resolveScenarioTemplateString(header.value ?? "", templateValues),
1493
+ }));
1494
+ const resolvedSubprotocols = (wsConfig.subprotocols ?? [])
1495
+ .map((protocol) => resolveScenarioTemplateString(protocol, templateValues).trim())
1496
+ .filter((protocol) => protocol.length > 0);
1497
+ const connectTimeoutMs = Math.min(MAX_WS_CONNECT_TIMEOUT_MS, Math.max(100, Math.round(wsConfig.connectTimeoutMs ?? DEFAULT_WS_CONNECT_TIMEOUT_MS)));
1498
+ const resolvedSteps = configuredSteps.map((step) => {
1499
+ if (step.kind === "send") {
1500
+ return {
1501
+ id: step.id,
1502
+ kind: "send",
1503
+ payload: resolveScenarioJsonTemplateString(step.payload ?? "", templateValues),
1504
+ };
1505
+ }
1506
+ if (step.kind === "wait") {
1507
+ return {
1508
+ id: step.id,
1509
+ kind: "wait",
1510
+ durationMs: Math.min(MAX_WS_WAIT_DURATION_MS, Math.max(0, Math.round(step.durationMs ?? 0))),
1511
+ };
1512
+ }
1513
+ return {
1514
+ id: step.id,
1515
+ kind: "expect",
1516
+ timeoutMs: Math.min(MAX_WS_EXPECT_TIMEOUT_MS, Math.max(100, Math.round(step.timeoutMs ?? DEFAULT_WS_EXPECT_TIMEOUT_MS))),
1517
+ matchMode: step.matchMode === "any" ? "any" : "all",
1518
+ rules: step.rules,
1519
+ };
1520
+ });
1521
+ const wsExecution = await runtimeAdapters.websocketExecutor({
1522
+ runId,
1523
+ stepId,
1524
+ node,
1525
+ resolvedUrl,
1526
+ resolvedHeaders,
1527
+ subprotocols: resolvedSubprotocols,
1528
+ connectTimeoutMs,
1529
+ steps: resolvedSteps,
1530
+ closeCode: wsConfig.closeCode ?? DEFAULT_WS_CLOSE_CODE,
1531
+ rejectUnauthorized: wsConfig.rejectUnauthorized !== false,
1532
+ environment: { ...runtimeContext.environment },
1533
+ globals: { ...runtimeContext.globals },
1534
+ signal,
1535
+ });
1536
+ throwIfStopped(signal);
1537
+ // Authoritative expect evaluation over the recorded frames — the
1538
+ // host's early-stop is advisory only (kafka consume precedent).
1539
+ const evaluationScope = {
1540
+ environment: runtimeContext.environment,
1541
+ globals: runtimeContext.globals,
1542
+ workflowContext: runtimeContext.workflowContext,
1543
+ nodeMetaByLabel: runtimeContext.nodeMetaByLabel,
1544
+ responseRoot: runtimeContext.responseRoot,
1545
+ dbResult: runtimeContext.dbResult,
1546
+ kafkaEvent: runtimeContext.kafkaEvent,
1547
+ redisResult: runtimeContext.redisResult,
1548
+ };
1549
+ const outcomesByIndex = new Map(wsExecution.stepOutcomes.map((outcome) => [outcome.index, outcome]));
1550
+ let conversationBroken = !wsExecution.connected;
1551
+ const stepResults = resolvedSteps.map((step, index) => {
1552
+ const outcome = outcomesByIndex.get(index);
1553
+ const durationMs = outcome && outcome.startedAt && outcome.endedAt
1554
+ ? Math.max(0, new Date(outcome.endedAt).getTime() - new Date(outcome.startedAt).getTime())
1555
+ : 0;
1556
+ if (!outcome) {
1557
+ return {
1558
+ index,
1559
+ kind: step.kind,
1560
+ status: "failed",
1561
+ durationMs: 0,
1562
+ error: conversationBroken
1563
+ ? "Step not reached — the conversation ended early."
1564
+ : "Step was not executed by the host.",
1565
+ matchedMessageIndex: null,
1566
+ };
1567
+ }
1568
+ if (step.kind !== "expect") {
1569
+ const failed = Boolean(outcome.error);
1570
+ if (failed)
1571
+ conversationBroken = true;
1572
+ return {
1573
+ index,
1574
+ kind: step.kind,
1575
+ status: failed ? "failed" : "passed",
1576
+ durationMs,
1577
+ error: outcome.error ?? null,
1578
+ matchedMessageIndex: null,
1579
+ };
1580
+ }
1581
+ const candidates = wsExecution.messages.filter((message) => message.direction === "received" && message.stepIndex === index);
1582
+ let matchedMessageIndex = null;
1583
+ for (const candidate of candidates) {
1584
+ const evaluation = evaluateWebsocketExpect(step.rules ?? [], step.matchMode ?? "all", evaluationScope, candidate);
1585
+ if (evaluation.passed) {
1586
+ matchedMessageIndex = candidate.index;
1587
+ break;
1588
+ }
1589
+ }
1590
+ const failed = matchedMessageIndex === null;
1591
+ if (failed)
1592
+ conversationBroken = true;
1593
+ return {
1594
+ index,
1595
+ kind: step.kind,
1596
+ status: failed ? "failed" : "passed",
1597
+ durationMs,
1598
+ error: failed
1599
+ ? (outcome.error ??
1600
+ `No message matched within ${step.timeoutMs}ms (${candidates.length} received).`)
1601
+ : null,
1602
+ matchedMessageIndex,
1603
+ };
1604
+ });
1605
+ const failedSteps = stepResults.filter((entry) => entry.status === "failed").length;
1606
+ const wsErrorMessage = !wsExecution.connected
1607
+ ? (wsExecution.connectError ?? "WebSocket connection failed.")
1608
+ : failedSteps > 0
1609
+ ? (() => {
1610
+ const firstFailed = stepResults.find((entry) => entry.status === "failed");
1611
+ return `WebSocket step ${(firstFailed?.index ?? 0) + 1} (${firstFailed?.kind}) failed: ${firstFailed?.error}`;
1612
+ })()
1613
+ : null;
1614
+ outputData = {
1615
+ url: resolvedUrl,
1616
+ connected: wsExecution.connected,
1617
+ closeCode: wsExecution.closeCode,
1618
+ closeReason: wsExecution.closeReason ?? null,
1619
+ durationMs: wsExecution.durationMs,
1620
+ messageCount: wsExecution.messages.length,
1621
+ messages: wsExecution.messages,
1622
+ steps: stepResults,
1623
+ failedSteps,
1624
+ errorMessage: wsErrorMessage,
1625
+ };
1626
+ if (wsErrorMessage) {
1627
+ throw new ScenarioNodeFailureError(wsErrorMessage);
1628
+ }
1629
+ }
1448
1630
  if (node.type === "condition") {
1449
1631
  const conditionIssues = validateConditionConfig(node.data.config);
1450
1632
  const blockingConditionIssue = conditionIssues.find((issue) => issue.severity === "error");
@@ -2384,6 +2566,24 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
2384
2566
  workflowMeta,
2385
2567
  });
2386
2568
  }
2569
+ // Release the run's DB sessions (COMMIT/ROLLBACK + connection teardown).
2570
+ // Runs after BOTH outcome paths so `rollback` mode is honored even when
2571
+ // the scenario failed or was stopped mid-transaction. Cleanup must never
2572
+ // mask the run result, hence the swallow-with-log catch.
2573
+ if (runtimeAdapters.dbSessionRelease) {
2574
+ const commitAllowed = scenario.dbSettings?.transactionMode === "commit" &&
2575
+ finalStatus !== "failed" &&
2576
+ finalStatus !== "stopped";
2577
+ try {
2578
+ await runtimeAdapters.dbSessionRelease({
2579
+ runId,
2580
+ outcome: commitAllowed ? "commit" : "rollback",
2581
+ });
2582
+ }
2583
+ catch {
2584
+ // Session teardown failure is not allowed to change the run outcome.
2585
+ }
2586
+ }
2387
2587
  const endedAt = new Date().toISOString();
2388
2588
  const finalWorkflowMeta = updateWorkflowMetaState({
2389
2589
  context: runtimeContext,