n8n-workflow 2.31.1 → 2.32.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 (408) hide show
  1. package/dist/cjs/augment-object.js +136 -146
  2. package/dist/cjs/augment-object.js.map +1 -1
  3. package/dist/cjs/build.tsbuildinfo +1 -1
  4. package/dist/cjs/common/find-ai-root-node-names.js +36 -46
  5. package/dist/cjs/common/find-ai-root-node-names.js.map +1 -1
  6. package/dist/cjs/common/get-child-nodes.js +8 -18
  7. package/dist/cjs/common/get-child-nodes.js.map +1 -1
  8. package/dist/cjs/common/get-connected-nodes.js +84 -94
  9. package/dist/cjs/common/get-connected-nodes.js.map +1 -1
  10. package/dist/cjs/common/get-node-by-name.js +16 -26
  11. package/dist/cjs/common/get-node-by-name.js.map +1 -1
  12. package/dist/cjs/common/get-parent-nodes.js +14 -24
  13. package/dist/cjs/common/get-parent-nodes.js.map +1 -1
  14. package/dist/cjs/common/index.js +9 -19
  15. package/dist/cjs/common/index.js.map +1 -1
  16. package/dist/cjs/common/map-connections-by-destination.js +31 -41
  17. package/dist/cjs/common/map-connections-by-destination.js.map +1 -1
  18. package/dist/cjs/common/resolve-variables.d.ts +8 -0
  19. package/dist/cjs/common/resolve-variables.d.ts.map +1 -1
  20. package/dist/cjs/common/resolve-variables.js +46 -33
  21. package/dist/cjs/common/resolve-variables.js.map +1 -1
  22. package/dist/cjs/connections-diff.js +58 -68
  23. package/dist/cjs/connections-diff.js.map +1 -1
  24. package/dist/cjs/constants.d.ts +3 -3
  25. package/dist/cjs/constants.d.ts.map +1 -1
  26. package/dist/cjs/constants.js +157 -166
  27. package/dist/cjs/constants.js.map +1 -1
  28. package/dist/cjs/credential-domain-restrictions.js +153 -163
  29. package/dist/cjs/credential-domain-restrictions.js.map +1 -1
  30. package/dist/cjs/cron.d.ts.map +1 -1
  31. package/dist/cjs/cron.js +25 -35
  32. package/dist/cjs/cron.js.map +1 -1
  33. package/dist/cjs/data-table.types.js +10 -20
  34. package/dist/cjs/data-table.types.js.map +1 -1
  35. package/dist/cjs/dynamic-credentials-helpers.js +93 -103
  36. package/dist/cjs/dynamic-credentials-helpers.js.map +1 -1
  37. package/dist/cjs/errors/abstract/execution-base.error.d.ts.map +1 -1
  38. package/dist/cjs/errors/abstract/execution-base.error.js +41 -51
  39. package/dist/cjs/errors/abstract/execution-base.error.js.map +1 -1
  40. package/dist/cjs/errors/abstract/node.error.d.ts.map +1 -1
  41. package/dist/cjs/errors/abstract/node.error.js +142 -152
  42. package/dist/cjs/errors/abstract/node.error.js.map +1 -1
  43. package/dist/cjs/errors/base/base.error.d.ts.map +1 -1
  44. package/dist/cjs/errors/base/base.error.js +35 -45
  45. package/dist/cjs/errors/base/base.error.js.map +1 -1
  46. package/dist/cjs/errors/base/operational.error.d.ts.map +1 -1
  47. package/dist/cjs/errors/base/operational.error.js +17 -27
  48. package/dist/cjs/errors/base/operational.error.js.map +1 -1
  49. package/dist/cjs/errors/base/unexpected.error.d.ts.map +1 -1
  50. package/dist/cjs/errors/base/unexpected.error.js +17 -27
  51. package/dist/cjs/errors/base/unexpected.error.js.map +1 -1
  52. package/dist/cjs/errors/base/user.error.d.ts.map +1 -1
  53. package/dist/cjs/errors/base/user.error.js +17 -27
  54. package/dist/cjs/errors/base/user.error.js.map +1 -1
  55. package/dist/cjs/errors/cli-subworkflow-operation.error.js +7 -17
  56. package/dist/cjs/errors/cli-subworkflow-operation.error.js.map +1 -1
  57. package/dist/cjs/errors/db-connection-timeout-error.d.ts.map +1 -1
  58. package/dist/cjs/errors/db-connection-timeout-error.js +11 -21
  59. package/dist/cjs/errors/db-connection-timeout-error.js.map +1 -1
  60. package/dist/cjs/errors/execution-cancelled.error.d.ts.map +1 -1
  61. package/dist/cjs/errors/execution-cancelled.error.js +33 -43
  62. package/dist/cjs/errors/execution-cancelled.error.js.map +1 -1
  63. package/dist/cjs/errors/expression-class-extension.error.d.ts.map +1 -1
  64. package/dist/cjs/errors/expression-class-extension.error.js +9 -19
  65. package/dist/cjs/errors/expression-class-extension.error.js.map +1 -1
  66. package/dist/cjs/errors/expression-computed-destructuring.error.d.ts.map +1 -1
  67. package/dist/cjs/errors/expression-computed-destructuring.error.js +9 -19
  68. package/dist/cjs/errors/expression-computed-destructuring.error.js.map +1 -1
  69. package/dist/cjs/errors/expression-destructuring.error.d.ts.map +1 -1
  70. package/dist/cjs/errors/expression-destructuring.error.js +9 -19
  71. package/dist/cjs/errors/expression-destructuring.error.js.map +1 -1
  72. package/dist/cjs/errors/expression-extension.error.js +7 -17
  73. package/dist/cjs/errors/expression-extension.error.js.map +1 -1
  74. package/dist/cjs/errors/expression-reserved-variable.error.d.ts.map +1 -1
  75. package/dist/cjs/errors/expression-reserved-variable.error.js +9 -19
  76. package/dist/cjs/errors/expression-reserved-variable.error.js.map +1 -1
  77. package/dist/cjs/errors/expression-with-statement.error.d.ts.map +1 -1
  78. package/dist/cjs/errors/expression-with-statement.error.js +9 -19
  79. package/dist/cjs/errors/expression-with-statement.error.js.map +1 -1
  80. package/dist/cjs/errors/expression.error.d.ts.map +1 -1
  81. package/dist/cjs/errors/expression.error.js +33 -43
  82. package/dist/cjs/errors/expression.error.js.map +1 -1
  83. package/dist/cjs/errors/index.js +62 -72
  84. package/dist/cjs/errors/index.js.map +1 -1
  85. package/dist/cjs/errors/node-api.error.d.ts.map +1 -1
  86. package/dist/cjs/errors/node-api.error.js +227 -237
  87. package/dist/cjs/errors/node-api.error.js.map +1 -1
  88. package/dist/cjs/errors/node-operation.error.d.ts.map +1 -1
  89. package/dist/cjs/errors/node-operation.error.js +43 -53
  90. package/dist/cjs/errors/node-operation.error.js.map +1 -1
  91. package/dist/cjs/errors/node-ssl.error.d.ts.map +1 -1
  92. package/dist/cjs/errors/node-ssl.error.js +9 -19
  93. package/dist/cjs/errors/node-ssl.error.js.map +1 -1
  94. package/dist/cjs/errors/subworkflow-operation.error.d.ts.map +1 -1
  95. package/dist/cjs/errors/subworkflow-operation.error.js +18 -28
  96. package/dist/cjs/errors/subworkflow-operation.error.js.map +1 -1
  97. package/dist/cjs/errors/trigger-close.error.d.ts.map +1 -1
  98. package/dist/cjs/errors/trigger-close.error.js +11 -21
  99. package/dist/cjs/errors/trigger-close.error.js.map +1 -1
  100. package/dist/cjs/errors/webhook-taken.error.d.ts.map +1 -1
  101. package/dist/cjs/errors/webhook-taken.error.js +9 -19
  102. package/dist/cjs/errors/webhook-taken.error.js.map +1 -1
  103. package/dist/cjs/errors/workflow-activation.error.d.ts.map +1 -1
  104. package/dist/cjs/errors/workflow-activation.error.js +54 -64
  105. package/dist/cjs/errors/workflow-activation.error.js.map +1 -1
  106. package/dist/cjs/errors/workflow-configuration.error.js +10 -20
  107. package/dist/cjs/errors/workflow-configuration.error.js.map +1 -1
  108. package/dist/cjs/errors/workflow-deactivation.error.js +7 -17
  109. package/dist/cjs/errors/workflow-deactivation.error.js.map +1 -1
  110. package/dist/cjs/errors/workflow-operation.error.d.ts.map +1 -1
  111. package/dist/cjs/errors/workflow-operation.error.js +20 -30
  112. package/dist/cjs/errors/workflow-operation.error.js.map +1 -1
  113. package/dist/cjs/evaluation-helpers.js +16 -26
  114. package/dist/cjs/evaluation-helpers.js.map +1 -1
  115. package/dist/cjs/execution-context-establishment-hooks.d.ts.map +1 -1
  116. package/dist/cjs/execution-context-establishment-hooks.js +43 -49
  117. package/dist/cjs/execution-context-establishment-hooks.js.map +1 -1
  118. package/dist/cjs/execution-context.d.ts +14 -14
  119. package/dist/cjs/execution-context.d.ts.map +1 -1
  120. package/dist/cjs/execution-context.js +203 -213
  121. package/dist/cjs/execution-context.js.map +1 -1
  122. package/dist/cjs/execution-status.d.ts +2 -2
  123. package/dist/cjs/execution-status.d.ts.map +1 -1
  124. package/dist/cjs/execution-status.js +27 -37
  125. package/dist/cjs/execution-status.js.map +1 -1
  126. package/dist/cjs/expression-evaluator-proxy.d.ts.map +1 -1
  127. package/dist/cjs/expression-evaluator-proxy.js +18 -28
  128. package/dist/cjs/expression-evaluator-proxy.js.map +1 -1
  129. package/dist/cjs/expression-sandboxing.d.ts.map +1 -1
  130. package/dist/cjs/expression-sandboxing.js +447 -457
  131. package/dist/cjs/expression-sandboxing.js.map +1 -1
  132. package/dist/cjs/expression.d.ts.map +1 -1
  133. package/dist/cjs/expression.js +535 -546
  134. package/dist/cjs/expression.js.map +1 -1
  135. package/dist/cjs/expressions/expression-helpers.d.ts.map +1 -1
  136. package/dist/cjs/expressions/expression-helpers.js +13 -23
  137. package/dist/cjs/expressions/expression-helpers.js.map +1 -1
  138. package/dist/cjs/extensions/array-extensions.js +591 -601
  139. package/dist/cjs/extensions/array-extensions.js.map +1 -1
  140. package/dist/cjs/extensions/boolean-extensions.d.ts +1 -1
  141. package/dist/cjs/extensions/boolean-extensions.js +38 -48
  142. package/dist/cjs/extensions/boolean-extensions.js.map +1 -1
  143. package/dist/cjs/extensions/date-extensions.js +507 -517
  144. package/dist/cjs/extensions/date-extensions.js.map +1 -1
  145. package/dist/cjs/extensions/expression-extension.d.ts.map +1 -1
  146. package/dist/cjs/extensions/expression-extension.js +455 -465
  147. package/dist/cjs/extensions/expression-extension.js.map +1 -1
  148. package/dist/cjs/extensions/expression-parser.d.ts.map +1 -1
  149. package/dist/cjs/extensions/expression-parser.js +82 -92
  150. package/dist/cjs/extensions/expression-parser.js.map +1 -1
  151. package/dist/cjs/extensions/extended-functions.d.ts +10 -18
  152. package/dist/cjs/extensions/extended-functions.d.ts.map +1 -1
  153. package/dist/cjs/extensions/extended-functions.js +80 -90
  154. package/dist/cjs/extensions/extended-functions.js.map +1 -1
  155. package/dist/cjs/extensions/extensions.js +2 -12
  156. package/dist/cjs/extensions/index.js +10 -20
  157. package/dist/cjs/extensions/index.js.map +1 -1
  158. package/dist/cjs/extensions/number-extensions.js +226 -236
  159. package/dist/cjs/extensions/number-extensions.js.map +1 -1
  160. package/dist/cjs/extensions/object-extensions.js +274 -284
  161. package/dist/cjs/extensions/object-extensions.js.map +1 -1
  162. package/dist/cjs/extensions/string-extensions.d.ts +1 -1
  163. package/dist/cjs/extensions/string-extensions.d.ts.map +1 -1
  164. package/dist/cjs/extensions/string-extensions.js +769 -779
  165. package/dist/cjs/extensions/string-extensions.js.map +1 -1
  166. package/dist/cjs/extensions/utils.d.ts.map +1 -1
  167. package/dist/cjs/extensions/utils.js +35 -45
  168. package/dist/cjs/extensions/utils.js.map +1 -1
  169. package/dist/cjs/from-ai-parse-utils.js +393 -403
  170. package/dist/cjs/from-ai-parse-utils.js.map +1 -1
  171. package/dist/cjs/global-state.js +12 -22
  172. package/dist/cjs/global-state.js.map +1 -1
  173. package/dist/cjs/graph/graph-utils.js +166 -176
  174. package/dist/cjs/graph/graph-utils.js.map +1 -1
  175. package/dist/cjs/highlighted-data.js +13 -23
  176. package/dist/cjs/highlighted-data.js.map +1 -1
  177. package/dist/cjs/index.js +105 -115
  178. package/dist/cjs/index.js.map +1 -1
  179. package/dist/cjs/interfaces.d.ts +112 -22
  180. package/dist/cjs/interfaces.d.ts.map +1 -1
  181. package/dist/cjs/interfaces.js +62 -72
  182. package/dist/cjs/interfaces.js.map +1 -1
  183. package/dist/cjs/jmespath-query.js +26 -36
  184. package/dist/cjs/jmespath-query.js.map +1 -1
  185. package/dist/cjs/logger-proxy.d.ts.map +1 -1
  186. package/dist/cjs/logger-proxy.js +15 -25
  187. package/dist/cjs/logger-proxy.js.map +1 -1
  188. package/dist/cjs/mcp-helpers.js +10 -20
  189. package/dist/cjs/mcp-helpers.js.map +1 -1
  190. package/dist/cjs/message-event-bus.d.ts +184 -165
  191. package/dist/cjs/message-event-bus.d.ts.map +1 -1
  192. package/dist/cjs/message-event-bus.js +207 -217
  193. package/dist/cjs/message-event-bus.js.map +1 -1
  194. package/dist/cjs/metadata-utils.js +35 -45
  195. package/dist/cjs/metadata-utils.js.map +1 -1
  196. package/dist/cjs/native-methods/array.methods.js +527 -537
  197. package/dist/cjs/native-methods/array.methods.js.map +1 -1
  198. package/dist/cjs/native-methods/boolean.methods.js +18 -28
  199. package/dist/cjs/native-methods/boolean.methods.js.map +1 -1
  200. package/dist/cjs/native-methods/index.js +16 -26
  201. package/dist/cjs/native-methods/index.js.map +1 -1
  202. package/dist/cjs/native-methods/number.methods.js +79 -89
  203. package/dist/cjs/native-methods/number.methods.js.map +1 -1
  204. package/dist/cjs/native-methods/object.methods.js +7 -17
  205. package/dist/cjs/native-methods/object.methods.js.map +1 -1
  206. package/dist/cjs/native-methods/string.methods.js +474 -484
  207. package/dist/cjs/native-methods/string.methods.js.map +1 -1
  208. package/dist/cjs/node-grouping-validation.d.ts +6 -0
  209. package/dist/cjs/node-grouping-validation.d.ts.map +1 -1
  210. package/dist/cjs/node-grouping-validation.js +165 -144
  211. package/dist/cjs/node-grouping-validation.js.map +1 -1
  212. package/dist/cjs/node-helpers.d.ts.map +1 -1
  213. package/dist/cjs/node-helpers.js +1486 -1493
  214. package/dist/cjs/node-helpers.js.map +1 -1
  215. package/dist/cjs/node-parameters/filter-parameter.d.ts.map +1 -1
  216. package/dist/cjs/node-parameters/filter-parameter.js +315 -325
  217. package/dist/cjs/node-parameters/filter-parameter.js.map +1 -1
  218. package/dist/cjs/node-parameters/node-parameter-value-type-guard.js +105 -115
  219. package/dist/cjs/node-parameters/node-parameter-value-type-guard.js.map +1 -1
  220. package/dist/cjs/node-parameters/parameter-type-validation.js +120 -130
  221. package/dist/cjs/node-parameters/parameter-type-validation.js.map +1 -1
  222. package/dist/cjs/node-parameters/path-utils.js +21 -31
  223. package/dist/cjs/node-parameters/path-utils.js.map +1 -1
  224. package/dist/cjs/node-parameters/rename-node-utils.js +22 -32
  225. package/dist/cjs/node-parameters/rename-node-utils.js.map +1 -1
  226. package/dist/cjs/node-reference-parser-utils.js +472 -482
  227. package/dist/cjs/node-reference-parser-utils.js.map +1 -1
  228. package/dist/cjs/node-validation.js +59 -69
  229. package/dist/cjs/node-validation.js.map +1 -1
  230. package/dist/cjs/observable-object.js +56 -66
  231. package/dist/cjs/observable-object.js.map +1 -1
  232. package/dist/cjs/redaction-channels.js +36 -46
  233. package/dist/cjs/redaction-channels.js.map +1 -1
  234. package/dist/cjs/run-execution-data/run-execution-data.js +15 -25
  235. package/dist/cjs/run-execution-data/run-execution-data.js.map +1 -1
  236. package/dist/cjs/run-execution-data/run-execution-data.v0.js +2 -12
  237. package/dist/cjs/run-execution-data/run-execution-data.v1.js +26 -36
  238. package/dist/cjs/run-execution-data/run-execution-data.v1.js.map +1 -1
  239. package/dist/cjs/run-execution-data-factory.js +113 -123
  240. package/dist/cjs/run-execution-data-factory.js.map +1 -1
  241. package/dist/cjs/schemas.d.ts +13 -13
  242. package/dist/cjs/schemas.d.ts.map +1 -1
  243. package/dist/cjs/schemas.js +351 -360
  244. package/dist/cjs/schemas.js.map +1 -1
  245. package/dist/cjs/sub-workflow-output.js +10 -20
  246. package/dist/cjs/sub-workflow-output.js.map +1 -1
  247. package/dist/cjs/telemetry-helpers.d.ts.map +1 -1
  248. package/dist/cjs/telemetry-helpers.js +716 -726
  249. package/dist/cjs/telemetry-helpers.js.map +1 -1
  250. package/dist/cjs/tool-helpers.js +18 -28
  251. package/dist/cjs/tool-helpers.js.map +1 -1
  252. package/dist/cjs/trigger-identity.js +41 -51
  253. package/dist/cjs/trigger-identity.js.map +1 -1
  254. package/dist/cjs/trimmed-task-data.js +21 -31
  255. package/dist/cjs/trimmed-task-data.js.map +1 -1
  256. package/dist/cjs/type-guards.d.ts +3 -3
  257. package/dist/cjs/type-guards.d.ts.map +1 -1
  258. package/dist/cjs/type-guards.js +74 -84
  259. package/dist/cjs/type-guards.js.map +1 -1
  260. package/dist/cjs/type-validation.d.ts.map +1 -1
  261. package/dist/cjs/type-validation.js +383 -393
  262. package/dist/cjs/type-validation.js.map +1 -1
  263. package/dist/cjs/utils.d.ts +2 -2
  264. package/dist/cjs/utils.d.ts.map +1 -1
  265. package/dist/cjs/utils.js +430 -440
  266. package/dist/cjs/utils.js.map +1 -1
  267. package/dist/cjs/versioned-node-type.d.ts.map +1 -1
  268. package/dist/cjs/versioned-node-type.js +20 -30
  269. package/dist/cjs/versioned-node-type.js.map +1 -1
  270. package/dist/cjs/workflow-checksum.js +67 -77
  271. package/dist/cjs/workflow-checksum.js.map +1 -1
  272. package/dist/cjs/workflow-data-proxy-env-provider.js +58 -68
  273. package/dist/cjs/workflow-data-proxy-env-provider.js.map +1 -1
  274. package/dist/cjs/workflow-data-proxy-helpers.js +8 -18
  275. package/dist/cjs/workflow-data-proxy-helpers.js.map +1 -1
  276. package/dist/cjs/workflow-data-proxy.d.ts.map +1 -1
  277. package/dist/cjs/workflow-data-proxy.js +1162 -1172
  278. package/dist/cjs/workflow-data-proxy.js.map +1 -1
  279. package/dist/cjs/workflow-diff.d.ts +2 -1
  280. package/dist/cjs/workflow-diff.d.ts.map +1 -1
  281. package/dist/cjs/workflow-diff.js +292 -300
  282. package/dist/cjs/workflow-diff.js.map +1 -1
  283. package/dist/cjs/workflow-environments-helper.js +23 -33
  284. package/dist/cjs/workflow-environments-helper.js.map +1 -1
  285. package/dist/cjs/workflow-expression.d.ts.map +1 -1
  286. package/dist/cjs/workflow-expression.js +97 -107
  287. package/dist/cjs/workflow-expression.js.map +1 -1
  288. package/dist/cjs/workflow-structure-validation.d.ts.map +1 -1
  289. package/dist/cjs/workflow-structure-validation.js +140 -150
  290. package/dist/cjs/workflow-structure-validation.js.map +1 -1
  291. package/dist/cjs/workflow-validation.js +40 -50
  292. package/dist/cjs/workflow-validation.js.map +1 -1
  293. package/dist/cjs/workflow.d.ts.map +1 -1
  294. package/dist/cjs/workflow.js +612 -622
  295. package/dist/cjs/workflow.js.map +1 -1
  296. package/dist/esm/common/get-child-nodes.js.map +1 -1
  297. package/dist/esm/common/get-connected-nodes.js.map +1 -1
  298. package/dist/esm/common/get-parent-nodes.js.map +1 -1
  299. package/dist/esm/common/resolve-variables.d.ts +8 -0
  300. package/dist/esm/common/resolve-variables.d.ts.map +1 -1
  301. package/dist/esm/common/resolve-variables.js +22 -0
  302. package/dist/esm/common/resolve-variables.js.map +1 -1
  303. package/dist/esm/constants.d.ts +3 -3
  304. package/dist/esm/constants.d.ts.map +1 -1
  305. package/dist/esm/cron.d.ts.map +1 -1
  306. package/dist/esm/errors/abstract/execution-base.error.d.ts.map +1 -1
  307. package/dist/esm/errors/abstract/execution-base.error.js.map +1 -1
  308. package/dist/esm/errors/abstract/node.error.d.ts.map +1 -1
  309. package/dist/esm/errors/abstract/node.error.js.map +1 -1
  310. package/dist/esm/errors/base/base.error.d.ts.map +1 -1
  311. package/dist/esm/errors/base/base.error.js.map +1 -1
  312. package/dist/esm/errors/base/operational.error.d.ts.map +1 -1
  313. package/dist/esm/errors/base/operational.error.js.map +1 -1
  314. package/dist/esm/errors/base/unexpected.error.d.ts.map +1 -1
  315. package/dist/esm/errors/base/unexpected.error.js.map +1 -1
  316. package/dist/esm/errors/base/user.error.d.ts.map +1 -1
  317. package/dist/esm/errors/base/user.error.js.map +1 -1
  318. package/dist/esm/errors/db-connection-timeout-error.d.ts.map +1 -1
  319. package/dist/esm/errors/execution-cancelled.error.d.ts.map +1 -1
  320. package/dist/esm/errors/expression-class-extension.error.d.ts.map +1 -1
  321. package/dist/esm/errors/expression-computed-destructuring.error.d.ts.map +1 -1
  322. package/dist/esm/errors/expression-destructuring.error.d.ts.map +1 -1
  323. package/dist/esm/errors/expression-reserved-variable.error.d.ts.map +1 -1
  324. package/dist/esm/errors/expression-with-statement.error.d.ts.map +1 -1
  325. package/dist/esm/errors/expression.error.d.ts.map +1 -1
  326. package/dist/esm/errors/node-api.error.d.ts.map +1 -1
  327. package/dist/esm/errors/node-api.error.js.map +1 -1
  328. package/dist/esm/errors/node-operation.error.d.ts.map +1 -1
  329. package/dist/esm/errors/node-operation.error.js.map +1 -1
  330. package/dist/esm/errors/node-ssl.error.d.ts.map +1 -1
  331. package/dist/esm/errors/subworkflow-operation.error.d.ts.map +1 -1
  332. package/dist/esm/errors/trigger-close.error.d.ts.map +1 -1
  333. package/dist/esm/errors/trigger-close.error.js.map +1 -1
  334. package/dist/esm/errors/webhook-taken.error.d.ts.map +1 -1
  335. package/dist/esm/errors/workflow-activation.error.d.ts.map +1 -1
  336. package/dist/esm/errors/workflow-activation.error.js.map +1 -1
  337. package/dist/esm/errors/workflow-operation.error.d.ts.map +1 -1
  338. package/dist/esm/execution-context-establishment-hooks.d.ts.map +1 -1
  339. package/dist/esm/execution-context-establishment-hooks.js +7 -3
  340. package/dist/esm/execution-context-establishment-hooks.js.map +1 -1
  341. package/dist/esm/execution-context.d.ts +14 -14
  342. package/dist/esm/execution-context.d.ts.map +1 -1
  343. package/dist/esm/execution-status.d.ts +2 -2
  344. package/dist/esm/execution-status.d.ts.map +1 -1
  345. package/dist/esm/expression-evaluator-proxy.d.ts.map +1 -1
  346. package/dist/esm/expression-sandboxing.d.ts.map +1 -1
  347. package/dist/esm/expression-sandboxing.js.map +1 -1
  348. package/dist/esm/expression.d.ts.map +1 -1
  349. package/dist/esm/expression.js.map +1 -1
  350. package/dist/esm/expressions/expression-helpers.d.ts.map +1 -1
  351. package/dist/esm/extensions/boolean-extensions.d.ts +1 -1
  352. package/dist/esm/extensions/expression-extension.d.ts.map +1 -1
  353. package/dist/esm/extensions/expression-parser.d.ts.map +1 -1
  354. package/dist/esm/extensions/extended-functions.d.ts +10 -18
  355. package/dist/esm/extensions/extended-functions.d.ts.map +1 -1
  356. package/dist/esm/extensions/number-extensions.js.map +1 -1
  357. package/dist/esm/extensions/string-extensions.d.ts +1 -1
  358. package/dist/esm/extensions/string-extensions.d.ts.map +1 -1
  359. package/dist/esm/extensions/string-extensions.js.map +1 -1
  360. package/dist/esm/extensions/utils.d.ts.map +1 -1
  361. package/dist/esm/from-ai-parse-utils.js.map +1 -1
  362. package/dist/esm/interfaces.d.ts +112 -22
  363. package/dist/esm/interfaces.d.ts.map +1 -1
  364. package/dist/esm/interfaces.js.map +1 -1
  365. package/dist/esm/logger-proxy.d.ts.map +1 -1
  366. package/dist/esm/message-event-bus.d.ts +184 -165
  367. package/dist/esm/message-event-bus.d.ts.map +1 -1
  368. package/dist/esm/message-event-bus.js +2 -2
  369. package/dist/esm/message-event-bus.js.map +1 -1
  370. package/dist/esm/node-grouping-validation.d.ts +6 -0
  371. package/dist/esm/node-grouping-validation.d.ts.map +1 -1
  372. package/dist/esm/node-grouping-validation.js +34 -5
  373. package/dist/esm/node-grouping-validation.js.map +1 -1
  374. package/dist/esm/node-helpers.d.ts.map +1 -1
  375. package/dist/esm/node-helpers.js +3 -0
  376. package/dist/esm/node-helpers.js.map +1 -1
  377. package/dist/esm/node-parameters/filter-parameter.d.ts.map +1 -1
  378. package/dist/esm/node-parameters/filter-parameter.js.map +1 -1
  379. package/dist/esm/node-reference-parser-utils.js.map +1 -1
  380. package/dist/esm/run-execution-data-factory.js.map +1 -1
  381. package/dist/esm/schemas.d.ts +13 -13
  382. package/dist/esm/schemas.d.ts.map +1 -1
  383. package/dist/esm/schemas.js +1 -0
  384. package/dist/esm/schemas.js.map +1 -1
  385. package/dist/esm/telemetry-helpers.d.ts.map +1 -1
  386. package/dist/esm/telemetry-helpers.js.map +1 -1
  387. package/dist/esm/type-guards.d.ts +3 -3
  388. package/dist/esm/type-guards.d.ts.map +1 -1
  389. package/dist/esm/type-validation.d.ts.map +1 -1
  390. package/dist/esm/type-validation.js.map +1 -1
  391. package/dist/esm/typecheck.tsbuildinfo +1 -1
  392. package/dist/esm/utils.d.ts +2 -2
  393. package/dist/esm/utils.d.ts.map +1 -1
  394. package/dist/esm/utils.js.map +1 -1
  395. package/dist/esm/versioned-node-type.d.ts.map +1 -1
  396. package/dist/esm/workflow-data-proxy.d.ts.map +1 -1
  397. package/dist/esm/workflow-data-proxy.js.map +1 -1
  398. package/dist/esm/workflow-diff.d.ts +2 -1
  399. package/dist/esm/workflow-diff.d.ts.map +1 -1
  400. package/dist/esm/workflow-diff.js +3 -1
  401. package/dist/esm/workflow-diff.js.map +1 -1
  402. package/dist/esm/workflow-expression.d.ts.map +1 -1
  403. package/dist/esm/workflow-expression.js.map +1 -1
  404. package/dist/esm/workflow-structure-validation.d.ts.map +1 -1
  405. package/dist/esm/workflow-structure-validation.js.map +1 -1
  406. package/dist/esm/workflow.d.ts.map +1 -1
  407. package/dist/esm/workflow.js.map +1 -1
  408. package/package.json +9 -8
@@ -1,1667 +1,1660 @@
1
+ "use strict";
1
2
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
3
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
5
  };
5
- (function (factory) {
6
- if (typeof module === "object" && typeof module.exports === "object") {
7
- var v = factory(require, exports);
8
- if (v !== undefined) module.exports = v;
9
- }
10
- else if (typeof define === "function" && define.amd) {
11
- define(["require", "exports", "lodash/get", "lodash/isEqual", "uuid", "./constants", "./errors", "./expressions/expression-helpers", "./from-ai-parse-utils", "./interfaces", "./node-parameters/filter-parameter", "./type-guards", "./type-validation", "./utils"], factory);
12
- }
13
- })(function (require, exports) {
14
- "use strict";
15
- Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.getUpdatedToolDescription = exports.checkConditions = exports.cronNodeOptions = void 0;
17
- exports.isSubNodeType = isSubNodeType;
18
- exports.getNodeFeatures = getNodeFeatures;
19
- exports.displayParameter = displayParameter;
20
- exports.displayParameterPath = displayParameterPath;
21
- exports.getContext = getContext;
22
- exports.getNodeParameters = getNodeParameters;
23
- exports.getNodeWebhookPath = getNodeWebhookPath;
24
- exports.getNodeWebhookUrl = getNodeWebhookUrl;
25
- exports.resolveNodeWebhookId = resolveNodeWebhookId;
26
- exports.getConnectionTypes = getConnectionTypes;
27
- exports.getNodeInputs = getNodeInputs;
28
- exports.getNodeOutputs = getNodeOutputs;
29
- exports.getNodeParametersIssues = getNodeParametersIssues;
30
- exports.nodeIssuesToString = nodeIssuesToString;
31
- exports.getParameterValueByPath = getParameterValueByPath;
32
- exports.findDisplayedProperty = findDisplayedProperty;
33
- exports.getParameterIssues = getParameterIssues;
34
- exports.mergeIssues = mergeIssues;
35
- exports.mergeNodeProperties = mergeNodeProperties;
36
- exports.getVersionedNodeType = getVersionedNodeType;
37
- exports.isTriggerNode = isTriggerNode;
38
- exports.isExecutable = isExecutable;
39
- exports.isNodeWithWorkflowSelector = isNodeWithWorkflowSelector;
40
- exports.makeDescription = makeDescription;
41
- exports.isTriggerNodeType = isTriggerNodeType;
42
- exports.isToolType = isToolType;
43
- exports.isHitlToolType = isHitlToolType;
44
- exports.isTool = isTool;
45
- exports.makeNodeName = makeNodeName;
46
- exports.isDefaultNodeName = isDefaultNodeName;
47
- exports.getToolDescriptionForNode = getToolDescriptionForNode;
48
- exports.getSubworkflowId = getSubworkflowId;
49
- exports.nodeAcceptsInputType = nodeAcceptsInputType;
50
- exports.nodeHasOutputType = nodeHasOutputType;
51
- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
52
- /* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
53
- const get_1 = __importDefault(require("lodash/get"));
54
- const isEqual_1 = __importDefault(require("lodash/isEqual"));
55
- const uuid_1 = require("uuid");
56
- const constants_1 = require("./constants");
57
- const errors_1 = require("./errors");
58
- const expression_helpers_1 = require("./expressions/expression-helpers");
59
- const from_ai_parse_utils_1 = require("./from-ai-parse-utils");
60
- const interfaces_1 = require("./interfaces");
61
- const filter_parameter_1 = require("./node-parameters/filter-parameter");
62
- const type_guards_1 = require("./type-guards");
63
- const type_validation_1 = require("./type-validation");
64
- const utils_1 = require("./utils");
65
- exports.cronNodeOptions = [
66
- {
67
- name: 'item',
68
- displayName: 'Item',
69
- values: [
70
- {
71
- displayName: 'Mode',
72
- name: 'mode',
73
- type: 'options',
74
- options: [
75
- {
76
- name: 'Every Minute',
77
- value: 'everyMinute',
78
- },
79
- {
80
- name: 'Every Hour',
81
- value: 'everyHour',
82
- },
83
- {
84
- name: 'Every Day',
85
- value: 'everyDay',
86
- },
87
- {
88
- name: 'Every Week',
89
- value: 'everyWeek',
90
- },
91
- {
92
- name: 'Every Month',
93
- value: 'everyMonth',
94
- },
95
- {
96
- name: 'Every X',
97
- value: 'everyX',
98
- },
99
- {
100
- name: 'Custom',
101
- value: 'custom',
102
- },
103
- ],
104
- default: 'everyDay',
105
- description: 'How often to trigger.',
106
- },
107
- {
108
- displayName: 'Hour',
109
- name: 'hour',
110
- type: 'number',
111
- typeOptions: {
112
- minValue: 0,
113
- maxValue: 23,
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.getUpdatedToolDescription = exports.checkConditions = exports.cronNodeOptions = void 0;
8
+ exports.isSubNodeType = isSubNodeType;
9
+ exports.getNodeFeatures = getNodeFeatures;
10
+ exports.displayParameter = displayParameter;
11
+ exports.displayParameterPath = displayParameterPath;
12
+ exports.getContext = getContext;
13
+ exports.getNodeParameters = getNodeParameters;
14
+ exports.getNodeWebhookPath = getNodeWebhookPath;
15
+ exports.getNodeWebhookUrl = getNodeWebhookUrl;
16
+ exports.resolveNodeWebhookId = resolveNodeWebhookId;
17
+ exports.getConnectionTypes = getConnectionTypes;
18
+ exports.getNodeInputs = getNodeInputs;
19
+ exports.getNodeOutputs = getNodeOutputs;
20
+ exports.getNodeParametersIssues = getNodeParametersIssues;
21
+ exports.nodeIssuesToString = nodeIssuesToString;
22
+ exports.getParameterValueByPath = getParameterValueByPath;
23
+ exports.findDisplayedProperty = findDisplayedProperty;
24
+ exports.getParameterIssues = getParameterIssues;
25
+ exports.mergeIssues = mergeIssues;
26
+ exports.mergeNodeProperties = mergeNodeProperties;
27
+ exports.getVersionedNodeType = getVersionedNodeType;
28
+ exports.isTriggerNode = isTriggerNode;
29
+ exports.isExecutable = isExecutable;
30
+ exports.isNodeWithWorkflowSelector = isNodeWithWorkflowSelector;
31
+ exports.makeDescription = makeDescription;
32
+ exports.isTriggerNodeType = isTriggerNodeType;
33
+ exports.isToolType = isToolType;
34
+ exports.isHitlToolType = isHitlToolType;
35
+ exports.isTool = isTool;
36
+ exports.makeNodeName = makeNodeName;
37
+ exports.isDefaultNodeName = isDefaultNodeName;
38
+ exports.getToolDescriptionForNode = getToolDescriptionForNode;
39
+ exports.getSubworkflowId = getSubworkflowId;
40
+ exports.nodeAcceptsInputType = nodeAcceptsInputType;
41
+ exports.nodeHasOutputType = nodeHasOutputType;
42
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
43
+ /* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
44
+ const get_1 = __importDefault(require("lodash/get"));
45
+ const isEqual_1 = __importDefault(require("lodash/isEqual"));
46
+ const uuid_1 = require("uuid");
47
+ const constants_1 = require("./constants");
48
+ const errors_1 = require("./errors");
49
+ const expression_helpers_1 = require("./expressions/expression-helpers");
50
+ const from_ai_parse_utils_1 = require("./from-ai-parse-utils");
51
+ const interfaces_1 = require("./interfaces");
52
+ const filter_parameter_1 = require("./node-parameters/filter-parameter");
53
+ const type_guards_1 = require("./type-guards");
54
+ const type_validation_1 = require("./type-validation");
55
+ const utils_1 = require("./utils");
56
+ exports.cronNodeOptions = [
57
+ {
58
+ name: 'item',
59
+ displayName: 'Item',
60
+ values: [
61
+ {
62
+ displayName: 'Mode',
63
+ name: 'mode',
64
+ type: 'options',
65
+ options: [
66
+ {
67
+ name: 'Every Minute',
68
+ value: 'everyMinute',
114
69
  },
115
- displayOptions: {
116
- hide: {
117
- mode: ['custom', 'everyHour', 'everyMinute', 'everyX'],
118
- },
70
+ {
71
+ name: 'Every Hour',
72
+ value: 'everyHour',
119
73
  },
120
- default: 14,
121
- description: 'The hour of the day to trigger (24h format)',
122
- },
123
- {
124
- displayName: 'Minute',
125
- name: 'minute',
126
- type: 'number',
127
- typeOptions: {
128
- minValue: 0,
129
- maxValue: 59,
74
+ {
75
+ name: 'Every Day',
76
+ value: 'everyDay',
77
+ },
78
+ {
79
+ name: 'Every Week',
80
+ value: 'everyWeek',
81
+ },
82
+ {
83
+ name: 'Every Month',
84
+ value: 'everyMonth',
130
85
  },
131
- displayOptions: {
132
- hide: {
133
- mode: ['custom', 'everyMinute', 'everyX'],
134
- },
86
+ {
87
+ name: 'Every X',
88
+ value: 'everyX',
135
89
  },
136
- default: 0,
137
- description: 'The minute past the hour to trigger (0-59)',
90
+ {
91
+ name: 'Custom',
92
+ value: 'custom',
93
+ },
94
+ ],
95
+ default: 'everyDay',
96
+ description: 'How often to trigger.',
97
+ },
98
+ {
99
+ displayName: 'Hour',
100
+ name: 'hour',
101
+ type: 'number',
102
+ typeOptions: {
103
+ minValue: 0,
104
+ maxValue: 23,
138
105
  },
139
- {
140
- displayName: 'Day of Month',
141
- name: 'dayOfMonth',
142
- type: 'number',
143
- displayOptions: {
144
- show: {
145
- mode: ['everyMonth'],
146
- },
106
+ displayOptions: {
107
+ hide: {
108
+ mode: ['custom', 'everyHour', 'everyMinute', 'everyX'],
147
109
  },
148
- typeOptions: {
149
- minValue: 1,
150
- maxValue: 31,
110
+ },
111
+ default: 14,
112
+ description: 'The hour of the day to trigger (24h format)',
113
+ },
114
+ {
115
+ displayName: 'Minute',
116
+ name: 'minute',
117
+ type: 'number',
118
+ typeOptions: {
119
+ minValue: 0,
120
+ maxValue: 59,
121
+ },
122
+ displayOptions: {
123
+ hide: {
124
+ mode: ['custom', 'everyMinute', 'everyX'],
151
125
  },
152
- default: 1,
153
- description: 'The day of the month to trigger',
154
126
  },
155
- {
156
- displayName: 'Weekday',
157
- name: 'weekday',
158
- type: 'options',
159
- displayOptions: {
160
- show: {
161
- mode: ['everyWeek'],
162
- },
127
+ default: 0,
128
+ description: 'The minute past the hour to trigger (0-59)',
129
+ },
130
+ {
131
+ displayName: 'Day of Month',
132
+ name: 'dayOfMonth',
133
+ type: 'number',
134
+ displayOptions: {
135
+ show: {
136
+ mode: ['everyMonth'],
163
137
  },
164
- options: [
165
- {
166
- name: 'Monday',
167
- value: '1',
168
- },
169
- {
170
- name: 'Tuesday',
171
- value: '2',
172
- },
173
- {
174
- name: 'Wednesday',
175
- value: '3',
176
- },
177
- {
178
- name: 'Thursday',
179
- value: '4',
180
- },
181
- {
182
- name: 'Friday',
183
- value: '5',
184
- },
185
- {
186
- name: 'Saturday',
187
- value: '6',
188
- },
189
- {
190
- name: 'Sunday',
191
- value: '0',
192
- },
193
- ],
194
- default: '1',
195
- description: 'The weekday to trigger',
196
138
  },
197
- {
198
- displayName: 'Cron Expression',
199
- name: 'cronExpression',
200
- type: 'string',
201
- displayOptions: {
202
- show: {
203
- mode: ['custom'],
204
- },
139
+ typeOptions: {
140
+ minValue: 1,
141
+ maxValue: 31,
142
+ },
143
+ default: 1,
144
+ description: 'The day of the month to trigger',
145
+ },
146
+ {
147
+ displayName: 'Weekday',
148
+ name: 'weekday',
149
+ type: 'options',
150
+ displayOptions: {
151
+ show: {
152
+ mode: ['everyWeek'],
205
153
  },
206
- default: '* * * * * *',
207
- description: 'Use custom cron expression. Values and ranges as follows:<ul><li>Seconds: 0-59</li><li>Minutes: 0 - 59</li><li>Hours: 0 - 23</li><li>Day of Month: 1 - 31</li><li>Months: 0 - 11 (Jan - Dec)</li><li>Day of Week: 0 - 6 (Sun - Sat)</li></ul>',
208
154
  },
209
- {
210
- displayName: 'Value',
211
- name: 'value',
212
- type: 'number',
213
- typeOptions: {
214
- minValue: 0,
215
- maxValue: 1000,
155
+ options: [
156
+ {
157
+ name: 'Monday',
158
+ value: '1',
159
+ },
160
+ {
161
+ name: 'Tuesday',
162
+ value: '2',
163
+ },
164
+ {
165
+ name: 'Wednesday',
166
+ value: '3',
167
+ },
168
+ {
169
+ name: 'Thursday',
170
+ value: '4',
171
+ },
172
+ {
173
+ name: 'Friday',
174
+ value: '5',
175
+ },
176
+ {
177
+ name: 'Saturday',
178
+ value: '6',
179
+ },
180
+ {
181
+ name: 'Sunday',
182
+ value: '0',
216
183
  },
217
- displayOptions: {
218
- show: {
219
- mode: ['everyX'],
220
- },
184
+ ],
185
+ default: '1',
186
+ description: 'The weekday to trigger',
187
+ },
188
+ {
189
+ displayName: 'Cron Expression',
190
+ name: 'cronExpression',
191
+ type: 'string',
192
+ displayOptions: {
193
+ show: {
194
+ mode: ['custom'],
221
195
  },
222
- default: 2,
223
- description: 'All how many X minutes/hours it should trigger',
224
196
  },
225
- {
226
- displayName: 'Unit',
227
- name: 'unit',
228
- type: 'options',
229
- displayOptions: {
230
- show: {
231
- mode: ['everyX'],
232
- },
197
+ default: '* * * * * *',
198
+ description: 'Use custom cron expression. Values and ranges as follows:<ul><li>Seconds: 0-59</li><li>Minutes: 0 - 59</li><li>Hours: 0 - 23</li><li>Day of Month: 1 - 31</li><li>Months: 0 - 11 (Jan - Dec)</li><li>Day of Week: 0 - 6 (Sun - Sat)</li></ul>',
199
+ },
200
+ {
201
+ displayName: 'Value',
202
+ name: 'value',
203
+ type: 'number',
204
+ typeOptions: {
205
+ minValue: 0,
206
+ maxValue: 1000,
207
+ },
208
+ displayOptions: {
209
+ show: {
210
+ mode: ['everyX'],
233
211
  },
234
- options: [
235
- {
236
- name: 'Minutes',
237
- value: 'minutes',
238
- },
239
- {
240
- name: 'Hours',
241
- value: 'hours',
242
- },
243
- ],
244
- default: 'hours',
245
- description: 'If it should trigger all X minutes or hours',
246
212
  },
247
- ],
248
- },
249
- ];
250
- /**
251
- * Determines if the provided node type has any output types other than the main connection type.
252
- * @param typeDescription The node's type description to check.
253
- */
254
- function isSubNodeType(typeDescription) {
255
- if (!typeDescription?.outputs || typeof typeDescription.outputs === 'string') {
256
- return false;
257
- }
258
- const outputTypes = getConnectionTypes(typeDescription.outputs);
259
- return outputTypes
260
- ? outputTypes.filter((output) => output !== interfaces_1.NodeConnectionTypes.Main).length > 0
261
- : false;
262
- }
263
- /**
264
- * Evaluates a feature condition against a node version.
265
- * @param featureDef The feature condition definition
266
- * @param nodeVersion The node version to evaluate against
267
- * @returns true if the feature is enabled, false otherwise
268
- */
269
- function evaluateFeature(featureDef, nodeVersion) {
270
- return (0, exports.checkConditions)(featureDef['@version'], [nodeVersion]);
271
- }
272
- /**
273
- * Evaluates all feature definitions for a node type and returns the computed features.
274
- * @param featuresDef The feature definitions from the node type description
275
- * @param nodeVersion The node version to evaluate against
276
- * @returns A record of feature names to their enabled state
277
- */
278
- function getNodeFeatures(featuresDef, nodeVersion) {
279
- if (!featuresDef) {
280
- return {};
281
- }
282
- const features = {};
283
- for (const [featureName, condition] of Object.entries(featuresDef)) {
284
- features[featureName] = evaluateFeature(condition, nodeVersion);
285
- }
286
- return features;
213
+ default: 2,
214
+ description: 'All how many X minutes/hours it should trigger',
215
+ },
216
+ {
217
+ displayName: 'Unit',
218
+ name: 'unit',
219
+ type: 'options',
220
+ displayOptions: {
221
+ show: {
222
+ mode: ['everyX'],
223
+ },
224
+ },
225
+ options: [
226
+ {
227
+ name: 'Minutes',
228
+ value: 'minutes',
229
+ },
230
+ {
231
+ name: 'Hours',
232
+ value: 'hours',
233
+ },
234
+ ],
235
+ default: 'hours',
236
+ description: 'If it should trigger all X minutes or hours',
237
+ },
238
+ ],
239
+ },
240
+ ];
241
+ /**
242
+ * Determines if the provided node type has any output types other than the main connection type.
243
+ * @param typeDescription The node's type description to check.
244
+ */
245
+ function isSubNodeType(typeDescription) {
246
+ if (!typeDescription?.outputs || typeof typeDescription.outputs === 'string') {
247
+ return false;
287
248
  }
288
- const getPropertyValues = (nodeValues, propertyName, node, nodeTypeDescription, nodeValuesRoot) => {
289
- let value;
290
- if (propertyName.charAt(0) === '/') {
291
- // Get the value from the root of the node
292
- value = (0, get_1.default)(nodeValuesRoot, propertyName.slice(1));
293
- }
294
- else if (propertyName === '@version') {
295
- value = node?.typeVersion || 0;
296
- }
297
- else if (propertyName === '@tool') {
298
- value = nodeTypeDescription?.name.endsWith('Tool') ?? false;
249
+ const outputTypes = getConnectionTypes(typeDescription.outputs);
250
+ return outputTypes
251
+ ? outputTypes.filter((output) => output !== interfaces_1.NodeConnectionTypes.Main).length > 0
252
+ : false;
253
+ }
254
+ /**
255
+ * Evaluates a feature condition against a node version.
256
+ * @param featureDef The feature condition definition
257
+ * @param nodeVersion The node version to evaluate against
258
+ * @returns true if the feature is enabled, false otherwise
259
+ */
260
+ function evaluateFeature(featureDef, nodeVersion) {
261
+ return (0, exports.checkConditions)(featureDef['@version'], [nodeVersion]);
262
+ }
263
+ /**
264
+ * Evaluates all feature definitions for a node type and returns the computed features.
265
+ * @param featuresDef The feature definitions from the node type description
266
+ * @param nodeVersion The node version to evaluate against
267
+ * @returns A record of feature names to their enabled state
268
+ */
269
+ function getNodeFeatures(featuresDef, nodeVersion) {
270
+ if (!featuresDef) {
271
+ return {};
272
+ }
273
+ const features = {};
274
+ for (const [featureName, condition] of Object.entries(featuresDef)) {
275
+ features[featureName] = evaluateFeature(condition, nodeVersion);
276
+ }
277
+ return features;
278
+ }
279
+ const getPropertyValues = (nodeValues, propertyName, node, nodeTypeDescription, nodeValuesRoot) => {
280
+ let value;
281
+ if (propertyName.charAt(0) === '/') {
282
+ // Get the value from the root of the node
283
+ value = (0, get_1.default)(nodeValuesRoot, propertyName.slice(1));
284
+ }
285
+ else if (propertyName === '@version') {
286
+ value = node?.typeVersion || 0;
287
+ }
288
+ else if (propertyName === '@tool') {
289
+ value = nodeTypeDescription?.name.endsWith('Tool') ?? false;
290
+ }
291
+ else if (propertyName === '@feature') {
292
+ if (!nodeTypeDescription?.features || !node?.typeVersion) {
293
+ return [];
299
294
  }
300
- else if (propertyName === '@feature') {
301
- if (!nodeTypeDescription?.features || !node?.typeVersion) {
302
- return [];
295
+ const features = getNodeFeatures(nodeTypeDescription.features, node.typeVersion);
296
+ return Object.entries(features)
297
+ .filter(([_, enabled]) => enabled)
298
+ .map(([name]) => name);
299
+ }
300
+ else {
301
+ // Get the value from current level
302
+ value = (0, get_1.default)(nodeValues, propertyName);
303
+ }
304
+ if (value && typeof value === 'object' && '__rl' in value && value.__rl) {
305
+ value = value.value;
306
+ }
307
+ if (!Array.isArray(value)) {
308
+ return [value];
309
+ }
310
+ else {
311
+ return value;
312
+ }
313
+ };
314
+ const checkConditions = (conditions, actualValues) => {
315
+ return conditions.some((condition) => {
316
+ if (condition &&
317
+ typeof condition === 'object' &&
318
+ condition._cnd &&
319
+ Object.keys(condition).length === 1) {
320
+ const [key, targetValue] = Object.entries(condition._cnd)[0];
321
+ // Special case: empty array handling
322
+ if (actualValues.length === 0) {
323
+ if (key === 'not')
324
+ return true; // Value is not present, so 'not' is true
325
+ return false; // For all other keys, empty array means condition is not met
303
326
  }
304
- const features = getNodeFeatures(nodeTypeDescription.features, node.typeVersion);
305
- return Object.entries(features)
306
- .filter(([_, enabled]) => enabled)
307
- .map(([name]) => name);
308
- }
309
- else {
310
- // Get the value from current level
311
- value = (0, get_1.default)(nodeValues, propertyName);
312
- }
313
- if (value && typeof value === 'object' && '__rl' in value && value.__rl) {
314
- value = value.value;
315
- }
316
- if (!Array.isArray(value)) {
317
- return [value];
318
- }
319
- else {
320
- return value;
321
- }
322
- };
323
- const checkConditions = (conditions, actualValues) => {
324
- return conditions.some((condition) => {
325
- if (condition &&
326
- typeof condition === 'object' &&
327
- condition._cnd &&
328
- Object.keys(condition).length === 1) {
329
- const [key, targetValue] = Object.entries(condition._cnd)[0];
330
- // Special case: empty array handling
331
- if (actualValues.length === 0) {
332
- if (key === 'not')
333
- return true; // Value is not present, so 'not' is true
334
- return false; // For all other keys, empty array means condition is not met
327
+ return actualValues.every((propertyValue) => {
328
+ if (key === 'eq') {
329
+ return (0, isEqual_1.default)(propertyValue, targetValue);
335
330
  }
336
- return actualValues.every((propertyValue) => {
337
- if (key === 'eq') {
338
- return (0, isEqual_1.default)(propertyValue, targetValue);
339
- }
340
- if (key === 'not') {
341
- return !(0, isEqual_1.default)(propertyValue, targetValue);
342
- }
343
- if (key === 'gte') {
344
- return propertyValue >= targetValue;
345
- }
346
- if (key === 'lte') {
347
- return propertyValue <= targetValue;
348
- }
349
- if (key === 'gt') {
350
- return propertyValue > targetValue;
351
- }
352
- if (key === 'lt') {
353
- return propertyValue < targetValue;
354
- }
355
- if (key === 'between') {
356
- const { from, to } = targetValue;
357
- return propertyValue >= from && propertyValue <= to;
358
- }
359
- if (key === 'includes') {
360
- return typeof propertyValue === 'string' && propertyValue.includes(targetValue);
361
- }
362
- if (key === 'startsWith') {
363
- return (typeof propertyValue === 'string' && propertyValue.startsWith(targetValue));
364
- }
365
- if (key === 'endsWith') {
366
- return typeof propertyValue === 'string' && propertyValue.endsWith(targetValue);
367
- }
368
- if (key === 'regex') {
369
- return (typeof propertyValue === 'string' &&
370
- new RegExp(targetValue).test(propertyValue));
371
- }
372
- if (key === 'exists') {
373
- return propertyValue !== null && propertyValue !== undefined && propertyValue !== '';
374
- }
375
- return false;
376
- });
377
- }
378
- return actualValues.includes(condition);
379
- });
380
- };
381
- exports.checkConditions = checkConditions;
382
- /**
383
- * Returns if the parameter should be displayed or not
384
- *
385
- * @param {INodeParameters} nodeValues The data on the node which decides if the parameter
386
- * should be displayed
387
- * @param {(INodeProperties | INodeCredentialDescription)} parameter The parameter to check if it should be displayed
388
- * @param {INodeParameters} [nodeValuesRoot] The root node-parameter-data
389
- */
390
- function displayParameter(nodeValues, parameter, node, // Allow null as it does also get used by credentials and they do not have versioning yet
391
- nodeTypeDescription, nodeValuesRoot, displayKey = 'displayOptions') {
392
- if (!parameter[displayKey]) {
393
- return true;
394
- }
395
- const { show, hide } = parameter[displayKey];
396
- nodeValuesRoot = nodeValuesRoot || nodeValues;
397
- if (show) {
398
- // All the defined rules have to match to display parameter
399
- for (const propertyName of Object.keys(show)) {
400
- const values = getPropertyValues(nodeValues, propertyName, node, nodeTypeDescription, nodeValuesRoot);
401
- if (values.some((v) => typeof v === 'string' && v.charAt(0) === '=')) {
402
- return true;
331
+ if (key === 'not') {
332
+ return !(0, isEqual_1.default)(propertyValue, targetValue);
403
333
  }
404
- if (!(0, exports.checkConditions)(show[propertyName], values)) {
405
- return false;
334
+ if (key === 'gte') {
335
+ return propertyValue >= targetValue;
406
336
  }
407
- }
408
- }
409
- if (hide) {
410
- // Any of the defined hide rules have to match to hide the parameter
411
- for (const propertyName of Object.keys(hide)) {
412
- const values = getPropertyValues(nodeValues, propertyName, node, nodeTypeDescription, nodeValuesRoot);
413
- if (values.length !== 0 && (0, exports.checkConditions)(hide[propertyName], values)) {
414
- return false;
337
+ if (key === 'lte') {
338
+ return propertyValue <= targetValue;
415
339
  }
416
- }
340
+ if (key === 'gt') {
341
+ return propertyValue > targetValue;
342
+ }
343
+ if (key === 'lt') {
344
+ return propertyValue < targetValue;
345
+ }
346
+ if (key === 'between') {
347
+ const { from, to } = targetValue;
348
+ return propertyValue >= from && propertyValue <= to;
349
+ }
350
+ if (key === 'includes') {
351
+ return typeof propertyValue === 'string' && propertyValue.includes(targetValue);
352
+ }
353
+ if (key === 'startsWith') {
354
+ return (typeof propertyValue === 'string' && propertyValue.startsWith(targetValue));
355
+ }
356
+ if (key === 'endsWith') {
357
+ return typeof propertyValue === 'string' && propertyValue.endsWith(targetValue);
358
+ }
359
+ if (key === 'regex') {
360
+ return (typeof propertyValue === 'string' &&
361
+ new RegExp(targetValue).test(propertyValue));
362
+ }
363
+ if (key === 'exists') {
364
+ return propertyValue !== null && propertyValue !== undefined && propertyValue !== '';
365
+ }
366
+ return false;
367
+ });
417
368
  }
369
+ return actualValues.includes(condition);
370
+ });
371
+ };
372
+ exports.checkConditions = checkConditions;
373
+ /**
374
+ * Returns if the parameter should be displayed or not
375
+ *
376
+ * @param {INodeParameters} nodeValues The data on the node which decides if the parameter
377
+ * should be displayed
378
+ * @param {(INodeProperties | INodeCredentialDescription)} parameter The parameter to check if it should be displayed
379
+ * @param {INodeParameters} [nodeValuesRoot] The root node-parameter-data
380
+ */
381
+ function displayParameter(nodeValues, parameter, node, // Allow null as it does also get used by credentials and they do not have versioning yet
382
+ nodeTypeDescription, nodeValuesRoot, displayKey = 'displayOptions') {
383
+ if (!parameter[displayKey]) {
418
384
  return true;
419
385
  }
420
- /**
421
- * Returns if the given parameter should be displayed or not considering the path
422
- * to the properties
423
- *
424
- * @param {INodeParameters} nodeValues The data on the node which decides if the parameter
425
- * should be displayed
426
- * @param {(INodeProperties | INodeCredentialDescription)} parameter The parameter to check if it should be displayed
427
- * @param {string} path The path to the property
428
- */
429
- function displayParameterPath(nodeValues, parameter, path, node, nodeTypeDescription, displayKey = 'displayOptions') {
430
- let resolvedNodeValues = nodeValues;
431
- if (path !== '') {
432
- resolvedNodeValues = (0, get_1.default)(nodeValues, path);
433
- }
434
- // Get the root parameter data
435
- let nodeValuesRoot = nodeValues;
436
- if (path && path.split('.').indexOf('parameters') === 0) {
437
- nodeValuesRoot = (0, get_1.default)(nodeValues, 'parameters');
438
- }
439
- return displayParameter(resolvedNodeValues, parameter, node, nodeTypeDescription, nodeValuesRoot, displayKey);
440
- }
441
- /**
442
- * Returns the context data
443
- *
444
- * @param {IRunExecutionData} runExecutionData The run execution data
445
- * @param {string} type The data type. "node"/"flow"
446
- * @param {INode} [node] If type "node" is set the node to return the context of has to be supplied
447
- */
448
- function getContext(runExecutionData, type, node) {
449
- if (runExecutionData.executionData === undefined) {
450
- // TODO: Should not happen leave it for test now
451
- throw new errors_1.UnexpectedError('`executionData` is not initialized');
452
- }
453
- let key;
454
- if (type === 'flow') {
455
- key = 'flow';
456
- }
457
- else if (type === 'node') {
458
- if (node === undefined) {
459
- // @TODO: What does this mean?
460
- throw new errors_1.UnexpectedError('The request data of context type "node" the node parameter has to be set!');
461
- }
462
- key = `node:${node.name}`;
463
- }
464
- else {
465
- throw new errors_1.UnexpectedError('Unknown context type. Only `flow` and `node` are supported.', {
466
- extra: { contextType: type },
467
- });
468
- }
469
- if (runExecutionData.executionData.contextData[key] === undefined) {
470
- runExecutionData.executionData.contextData[key] = {};
471
- }
472
- return runExecutionData.executionData.contextData[key];
473
- }
474
- /**
475
- * Returns which parameters are dependent on which
476
- */
477
- function getParameterDependencies(nodePropertiesArray) {
478
- const dependencies = {};
479
- for (const nodeProperties of nodePropertiesArray) {
480
- const { name, displayOptions } = nodeProperties;
481
- if (!dependencies[name]) {
482
- dependencies[name] = [];
386
+ const { show, hide } = parameter[displayKey];
387
+ nodeValuesRoot = nodeValuesRoot || nodeValues;
388
+ if (show) {
389
+ // All the defined rules have to match to display parameter
390
+ for (const propertyName of Object.keys(show)) {
391
+ const values = getPropertyValues(nodeValues, propertyName, node, nodeTypeDescription, nodeValuesRoot);
392
+ if (values.some((v) => typeof v === 'string' && v.charAt(0) === '=')) {
393
+ return true;
483
394
  }
484
- if (!displayOptions) {
485
- // Does not have any dependencies
486
- continue;
395
+ if (!(0, exports.checkConditions)(show[propertyName], values)) {
396
+ return false;
487
397
  }
488
- for (const displayRule of Object.values(displayOptions)) {
489
- for (const parameterName of Object.keys(displayRule)) {
490
- if (!dependencies[name].includes(parameterName)) {
491
- if (parameterName.charAt(0) === '@') {
492
- // Is a special parameter so can be skipped
493
- continue;
494
- }
495
- dependencies[name].push(parameterName);
496
- }
497
- }
398
+ }
399
+ }
400
+ if (hide) {
401
+ // Any of the defined hide rules have to match to hide the parameter
402
+ for (const propertyName of Object.keys(hide)) {
403
+ const values = getPropertyValues(nodeValues, propertyName, node, nodeTypeDescription, nodeValuesRoot);
404
+ if (values.length !== 0 && (0, exports.checkConditions)(hide[propertyName], values)) {
405
+ return false;
498
406
  }
499
407
  }
500
- return dependencies;
501
- }
502
- /**
503
- * Returns in which order the parameters should be resolved
504
- * to have the parameters available they depend on
505
- */
506
- function getParameterResolveOrder(nodePropertiesArray, parameterDependencies) {
507
- const executionOrder = [];
508
- const indexToResolve = Array.from({ length: nodePropertiesArray.length }, (_, k) => k);
509
- const resolvedParameters = [];
510
- let index;
511
- let property;
512
- let lastIndexLength = indexToResolve.length;
513
- let lastIndexReduction = -1;
514
- let iterations = 0;
515
- while (indexToResolve.length !== 0) {
516
- iterations += 1;
517
- index = indexToResolve.shift();
518
- property = nodePropertiesArray[index];
519
- if (parameterDependencies[property.name].length === 0) {
520
- // Does not have any dependencies so simply add
521
- executionOrder.push(index);
522
- resolvedParameters.push(property.name);
408
+ }
409
+ return true;
410
+ }
411
+ /**
412
+ * Returns if the given parameter should be displayed or not considering the path
413
+ * to the properties
414
+ *
415
+ * @param {INodeParameters} nodeValues The data on the node which decides if the parameter
416
+ * should be displayed
417
+ * @param {(INodeProperties | INodeCredentialDescription)} parameter The parameter to check if it should be displayed
418
+ * @param {string} path The path to the property
419
+ */
420
+ function displayParameterPath(nodeValues, parameter, path, node, nodeTypeDescription, displayKey = 'displayOptions') {
421
+ let resolvedNodeValues = nodeValues;
422
+ if (path !== '') {
423
+ resolvedNodeValues = (0, get_1.default)(nodeValues, path);
424
+ }
425
+ // Get the root parameter data
426
+ let nodeValuesRoot = nodeValues;
427
+ if (path && path.split('.').indexOf('parameters') === 0) {
428
+ nodeValuesRoot = (0, get_1.default)(nodeValues, 'parameters');
429
+ }
430
+ return displayParameter(resolvedNodeValues, parameter, node, nodeTypeDescription, nodeValuesRoot, displayKey);
431
+ }
432
+ /**
433
+ * Returns the context data
434
+ *
435
+ * @param {IRunExecutionData} runExecutionData The run execution data
436
+ * @param {string} type The data type. "node"/"flow"
437
+ * @param {INode} [node] If type "node" is set the node to return the context of has to be supplied
438
+ */
439
+ function getContext(runExecutionData, type, node) {
440
+ if (runExecutionData.executionData === undefined) {
441
+ // TODO: Should not happen leave it for test now
442
+ throw new errors_1.UnexpectedError('`executionData` is not initialized');
443
+ }
444
+ let key;
445
+ if (type === 'flow') {
446
+ key = 'flow';
447
+ }
448
+ else if (type === 'node') {
449
+ if (node === undefined) {
450
+ // @TODO: What does this mean?
451
+ throw new errors_1.UnexpectedError('The request data of context type "node" the node parameter has to be set!');
452
+ }
453
+ key = `node:${node.name}`;
454
+ }
455
+ else {
456
+ throw new errors_1.UnexpectedError('Unknown context type. Only `flow` and `node` are supported.', {
457
+ extra: { contextType: type },
458
+ });
459
+ }
460
+ if (runExecutionData.executionData.contextData[key] === undefined) {
461
+ runExecutionData.executionData.contextData[key] = {};
462
+ }
463
+ return runExecutionData.executionData.contextData[key];
464
+ }
465
+ /**
466
+ * Returns which parameters are dependent on which
467
+ */
468
+ function getParameterDependencies(nodePropertiesArray) {
469
+ const dependencies = {};
470
+ for (const nodeProperties of nodePropertiesArray) {
471
+ const { name, displayOptions } = nodeProperties;
472
+ if (!dependencies[name]) {
473
+ dependencies[name] = [];
474
+ }
475
+ if (!displayOptions) {
476
+ // Does not have any dependencies
477
+ continue;
478
+ }
479
+ for (const displayRule of Object.values(displayOptions)) {
480
+ if (typeof displayRule !== 'object' || displayRule === null) {
523
481
  continue;
524
482
  }
525
- // Parameter has dependencies
526
- for (const dependency of parameterDependencies[property.name]) {
527
- if (!resolvedParameters.includes(dependency)) {
528
- if (dependency.charAt(0) === '/') {
529
- // Assume that root level dependencies are resolved
483
+ for (const parameterName of Object.keys(displayRule)) {
484
+ if (!dependencies[name].includes(parameterName)) {
485
+ if (parameterName.charAt(0) === '@') {
486
+ // Is a special parameter so can be skipped
530
487
  continue;
531
488
  }
532
- // Dependencies for that parameter are still missing so
533
- // try to add again later
534
- indexToResolve.push(index);
535
- continue;
489
+ dependencies[name].push(parameterName);
536
490
  }
537
491
  }
538
- // All dependencies got found so add
492
+ }
493
+ }
494
+ return dependencies;
495
+ }
496
+ /**
497
+ * Returns in which order the parameters should be resolved
498
+ * to have the parameters available they depend on
499
+ */
500
+ function getParameterResolveOrder(nodePropertiesArray, parameterDependencies) {
501
+ const executionOrder = [];
502
+ const indexToResolve = Array.from({ length: nodePropertiesArray.length }, (_, k) => k);
503
+ const resolvedParameters = [];
504
+ let index;
505
+ let property;
506
+ let lastIndexLength = indexToResolve.length;
507
+ let lastIndexReduction = -1;
508
+ let iterations = 0;
509
+ while (indexToResolve.length !== 0) {
510
+ iterations += 1;
511
+ index = indexToResolve.shift();
512
+ property = nodePropertiesArray[index];
513
+ if (parameterDependencies[property.name].length === 0) {
514
+ // Does not have any dependencies so simply add
539
515
  executionOrder.push(index);
540
516
  resolvedParameters.push(property.name);
541
- if (indexToResolve.length < lastIndexLength) {
542
- lastIndexReduction = iterations;
543
- }
544
- if (iterations > lastIndexReduction + nodePropertiesArray.length) {
545
- throw new errors_1.UserError('Could not resolve parameter dependencies. Max iterations reached! Hint: If `displayOptions` are specified in any child parameter of a parent `collection` or `fixedCollection`, remove the `displayOptions` from the child parameter.');
546
- }
547
- lastIndexLength = indexToResolve.length;
548
- }
549
- return executionOrder;
550
- }
551
- /**
552
- * Returns the node parameter values. Depending on the settings it either just returns the none
553
- * default values or it applies all the default values.
554
- *
555
- * @param {INodeProperties[]} nodePropertiesArray The properties which exist and their settings
556
- * @param {INodeParameters} nodeValues The node parameter data
557
- * @param {boolean} returnDefaults If default values get added or only none default values returned
558
- * @param {boolean} returnNoneDisplayed If also values which should not be displayed should be returned
559
- * @param {GetNodeParametersOptions} options Optional properties
560
- */
561
- // eslint-disable-next-line complexity
562
- function getNodeParameters(nodePropertiesArray, nodeValues, returnDefaults, returnNoneDisplayed, node, nodeTypeDescription, options) {
563
- let { nodeValuesRoot, parameterDependencies } = options ?? {};
564
- const { onlySimpleTypes = false, dataIsResolved = false, parentType } = options ?? {};
565
- if (parameterDependencies === undefined) {
566
- parameterDependencies = getParameterDependencies(nodePropertiesArray);
517
+ continue;
567
518
  }
568
- // Get the parameter names which get used multiple times as for this
569
- // ones we have to always check which ones get displayed and which ones not
570
- const duplicateParameterNames = [];
571
- const parameterNames = [];
572
- for (const nodeProperties of nodePropertiesArray) {
573
- if (parameterNames.includes(nodeProperties.name)) {
574
- if (!duplicateParameterNames.includes(nodeProperties.name)) {
575
- duplicateParameterNames.push(nodeProperties.name);
519
+ // Parameter has dependencies
520
+ for (const dependency of parameterDependencies[property.name]) {
521
+ if (!resolvedParameters.includes(dependency)) {
522
+ if (dependency.charAt(0) === '/') {
523
+ // Assume that root level dependencies are resolved
524
+ continue;
576
525
  }
526
+ // Dependencies for that parameter are still missing so
527
+ // try to add again later
528
+ indexToResolve.push(index);
529
+ continue;
577
530
  }
578
- else {
579
- parameterNames.push(nodeProperties.name);
531
+ }
532
+ // All dependencies got found so add
533
+ executionOrder.push(index);
534
+ resolvedParameters.push(property.name);
535
+ if (indexToResolve.length < lastIndexLength) {
536
+ lastIndexReduction = iterations;
537
+ }
538
+ if (iterations > lastIndexReduction + nodePropertiesArray.length) {
539
+ throw new errors_1.UserError('Could not resolve parameter dependencies. Max iterations reached! Hint: If `displayOptions` are specified in any child parameter of a parent `collection` or `fixedCollection`, remove the `displayOptions` from the child parameter.');
540
+ }
541
+ lastIndexLength = indexToResolve.length;
542
+ }
543
+ return executionOrder;
544
+ }
545
+ /**
546
+ * Returns the node parameter values. Depending on the settings it either just returns the none
547
+ * default values or it applies all the default values.
548
+ *
549
+ * @param {INodeProperties[]} nodePropertiesArray The properties which exist and their settings
550
+ * @param {INodeParameters} nodeValues The node parameter data
551
+ * @param {boolean} returnDefaults If default values get added or only none default values returned
552
+ * @param {boolean} returnNoneDisplayed If also values which should not be displayed should be returned
553
+ * @param {GetNodeParametersOptions} options Optional properties
554
+ */
555
+ // eslint-disable-next-line complexity
556
+ function getNodeParameters(nodePropertiesArray, nodeValues, returnDefaults, returnNoneDisplayed, node, nodeTypeDescription, options) {
557
+ let { nodeValuesRoot, parameterDependencies } = options ?? {};
558
+ const { onlySimpleTypes = false, dataIsResolved = false, parentType } = options ?? {};
559
+ if (parameterDependencies === undefined) {
560
+ parameterDependencies = getParameterDependencies(nodePropertiesArray);
561
+ }
562
+ // Get the parameter names which get used multiple times as for this
563
+ // ones we have to always check which ones get displayed and which ones not
564
+ const duplicateParameterNames = [];
565
+ const parameterNames = [];
566
+ for (const nodeProperties of nodePropertiesArray) {
567
+ if (parameterNames.includes(nodeProperties.name)) {
568
+ if (!duplicateParameterNames.includes(nodeProperties.name)) {
569
+ duplicateParameterNames.push(nodeProperties.name);
580
570
  }
581
571
  }
582
- const nodeParameters = {};
583
- const nodeParametersFull = {};
584
- let nodeValuesDisplayCheck = nodeParametersFull;
585
- if (!dataIsResolved && !returnNoneDisplayed) {
586
- nodeValuesDisplayCheck = getNodeParameters(nodePropertiesArray, nodeValues, true, true, node, nodeTypeDescription, {
587
- onlySimpleTypes: true,
588
- dataIsResolved: true,
589
- nodeValuesRoot,
590
- parentType,
591
- parameterDependencies,
592
- });
572
+ else {
573
+ parameterNames.push(nodeProperties.name);
593
574
  }
594
- nodeValuesRoot = nodeValuesRoot || nodeValuesDisplayCheck;
595
- // Go through the parameters in order of their dependencies
596
- const parameterIterationOrderIndex = getParameterResolveOrder(nodePropertiesArray, parameterDependencies);
597
- for (const parameterIndex of parameterIterationOrderIndex) {
598
- const nodeProperties = nodePropertiesArray[parameterIndex];
599
- if (!nodeValues ||
600
- (nodeValues[nodeProperties.name] === undefined &&
601
- (!returnDefaults || parentType === 'collection'))) {
602
- // The value is not defined so go to the next
575
+ }
576
+ const nodeParameters = {};
577
+ const nodeParametersFull = {};
578
+ let nodeValuesDisplayCheck = nodeParametersFull;
579
+ if (!dataIsResolved && !returnNoneDisplayed) {
580
+ nodeValuesDisplayCheck = getNodeParameters(nodePropertiesArray, nodeValues, true, true, node, nodeTypeDescription, {
581
+ onlySimpleTypes: true,
582
+ dataIsResolved: true,
583
+ nodeValuesRoot,
584
+ parentType,
585
+ parameterDependencies,
586
+ });
587
+ }
588
+ nodeValuesRoot = nodeValuesRoot || nodeValuesDisplayCheck;
589
+ // Go through the parameters in order of their dependencies
590
+ const parameterIterationOrderIndex = getParameterResolveOrder(nodePropertiesArray, parameterDependencies);
591
+ for (const parameterIndex of parameterIterationOrderIndex) {
592
+ const nodeProperties = nodePropertiesArray[parameterIndex];
593
+ if (!nodeValues ||
594
+ (nodeValues[nodeProperties.name] === undefined &&
595
+ (!returnDefaults || parentType === 'collection'))) {
596
+ // The value is not defined so go to the next
597
+ continue;
598
+ }
599
+ if (!returnNoneDisplayed &&
600
+ !displayParameter(nodeValuesDisplayCheck, nodeProperties, node, nodeTypeDescription, nodeValuesRoot)) {
601
+ if (!returnNoneDisplayed || !returnDefaults) {
603
602
  continue;
604
603
  }
605
- if (!returnNoneDisplayed &&
606
- !displayParameter(nodeValuesDisplayCheck, nodeProperties, node, nodeTypeDescription, nodeValuesRoot)) {
607
- if (!returnNoneDisplayed || !returnDefaults) {
604
+ }
605
+ if (!['collection', 'fixedCollection'].includes(nodeProperties.type)) {
606
+ // Is a simple property so can be set as it is
607
+ if (duplicateParameterNames.includes(nodeProperties.name)) {
608
+ if (!displayParameter(nodeValuesDisplayCheck, nodeProperties, node, nodeTypeDescription, nodeValuesRoot)) {
608
609
  continue;
609
610
  }
610
611
  }
611
- if (!['collection', 'fixedCollection'].includes(nodeProperties.type)) {
612
- // Is a simple property so can be set as it is
613
- if (duplicateParameterNames.includes(nodeProperties.name)) {
614
- if (!displayParameter(nodeValuesDisplayCheck, nodeProperties, node, nodeTypeDescription, nodeValuesRoot)) {
615
- continue;
616
- }
612
+ if (returnDefaults) {
613
+ // Set also when it has the default value
614
+ if (['boolean', 'number', 'options'].includes(nodeProperties.type)) {
615
+ // Boolean, numbers and options are special as false and 0 are valid values
616
+ // and should not be replaced with default value
617
+ nodeParameters[nodeProperties.name] =
618
+ nodeValues[nodeProperties.name] !== undefined
619
+ ? (0, utils_1.deepCopy)(nodeValues[nodeProperties.name])
620
+ : nodeProperties.default;
617
621
  }
618
- if (returnDefaults) {
619
- // Set also when it has the default value
620
- if (['boolean', 'number', 'options'].includes(nodeProperties.type)) {
621
- // Boolean, numbers and options are special as false and 0 are valid values
622
- // and should not be replaced with default value
623
- nodeParameters[nodeProperties.name] =
624
- nodeValues[nodeProperties.name] !== undefined
625
- ? (0, utils_1.deepCopy)(nodeValues[nodeProperties.name])
626
- : nodeProperties.default;
627
- }
628
- else if (nodeProperties.type === 'resourceLocator' &&
629
- typeof nodeProperties.default === 'object') {
630
- nodeParameters[nodeProperties.name] =
631
- nodeValues[nodeProperties.name] !== undefined
632
- ? (0, utils_1.deepCopy)(nodeValues[nodeProperties.name])
633
- : { __rl: true, ...nodeProperties.default };
634
- }
635
- else if (
636
- // Filter parameters may be missing "combinator" or "options" and
637
- // still be considered valid (e.g. happens when generated by AI).
638
- // this patches in the same way the UI does in FilterConditions.vue
639
- nodeProperties.type === 'filter' &&
640
- nodeValues[nodeProperties.name] !== undefined &&
641
- typeof nodeValues[nodeProperties.name] === 'object' &&
642
- nodeValues[nodeProperties.name] !== null) {
643
- const defaultOptions = {
644
- caseSensitive: true,
645
- leftValue: '',
646
- typeValidation: 'strict',
647
- version: 1,
648
- };
649
- const filter = (0, utils_1.deepCopy)(nodeValues[nodeProperties.name]);
650
- filter.combinator ??= 'and';
651
- filter.options = { ...defaultOptions, ...filter.options };
652
- nodeParameters[nodeProperties.name] = filter;
653
- }
654
- else {
655
- nodeParameters[nodeProperties.name] =
656
- (0, utils_1.deepCopy)(nodeValues[nodeProperties.name]) ?? nodeProperties.default;
657
- }
658
- nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
622
+ else if (nodeProperties.type === 'resourceLocator' &&
623
+ typeof nodeProperties.default === 'object') {
624
+ nodeParameters[nodeProperties.name] =
625
+ nodeValues[nodeProperties.name] !== undefined
626
+ ? (0, utils_1.deepCopy)(nodeValues[nodeProperties.name])
627
+ : { __rl: true, ...nodeProperties.default };
659
628
  }
660
- else if ((nodeValues[nodeProperties.name] !== nodeProperties.default &&
661
- typeof nodeValues[nodeProperties.name] !== 'object') ||
662
- (typeof nodeValues[nodeProperties.name] === 'object' &&
663
- !(0, isEqual_1.default)(nodeValues[nodeProperties.name], nodeProperties.default)) ||
664
- (nodeValues[nodeProperties.name] !== undefined && parentType === 'collection')) {
665
- // Set only if it is different to the default value
666
- nodeParameters[nodeProperties.name] = (0, utils_1.deepCopy)(nodeValues[nodeProperties.name]);
667
- nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
668
- continue;
629
+ else if (
630
+ // Filter parameters may be missing "combinator" or "options" and
631
+ // still be considered valid (e.g. happens when generated by AI).
632
+ // this patches in the same way the UI does in FilterConditions.vue
633
+ nodeProperties.type === 'filter' &&
634
+ nodeValues[nodeProperties.name] !== undefined &&
635
+ typeof nodeValues[nodeProperties.name] === 'object' &&
636
+ nodeValues[nodeProperties.name] !== null) {
637
+ const defaultOptions = {
638
+ caseSensitive: true,
639
+ leftValue: '',
640
+ typeValidation: 'strict',
641
+ version: 1,
642
+ };
643
+ const filter = (0, utils_1.deepCopy)(nodeValues[nodeProperties.name]);
644
+ filter.combinator ??= 'and';
645
+ filter.options = { ...defaultOptions, ...filter.options };
646
+ nodeParameters[nodeProperties.name] = filter;
669
647
  }
670
- // Strip expression prefix if noDataExpression is true
671
- if (nodeProperties.noDataExpression && nodeParameters[nodeProperties.name] !== undefined) {
672
- const value = nodeParameters[nodeProperties.name];
673
- // A lone $fromAI() placeholder must keep its "=" or the AI tool call never resolves it (#30531)
674
- if ((0, expression_helpers_1.isExpression)(value) && !(0, from_ai_parse_utils_1.isFromAIOnlyExpression)(value)) {
675
- nodeParameters[nodeProperties.name] = value.slice(1);
676
- nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
677
- }
648
+ else {
649
+ nodeParameters[nodeProperties.name] =
650
+ (0, utils_1.deepCopy)(nodeValues[nodeProperties.name]) ?? nodeProperties.default;
678
651
  }
652
+ nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
679
653
  }
680
- if (onlySimpleTypes) {
681
- // It is only supposed to resolve the simple types. So continue.
654
+ else if ((nodeValues[nodeProperties.name] !== nodeProperties.default &&
655
+ typeof nodeValues[nodeProperties.name] !== 'object') ||
656
+ (typeof nodeValues[nodeProperties.name] === 'object' &&
657
+ !(0, isEqual_1.default)(nodeValues[nodeProperties.name], nodeProperties.default)) ||
658
+ (nodeValues[nodeProperties.name] !== undefined && parentType === 'collection')) {
659
+ // Set only if it is different to the default value
660
+ nodeParameters[nodeProperties.name] = (0, utils_1.deepCopy)(nodeValues[nodeProperties.name]);
661
+ nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
682
662
  continue;
683
663
  }
684
- // Is a complex property so check lower levels
685
- let tempValue;
686
- if (nodeProperties.type === 'collection') {
687
- // Is collection
688
- if (nodeProperties.typeOptions !== undefined &&
689
- nodeProperties.typeOptions.multipleValues === true) {
690
- // Multiple can be set so will be an array
691
- // Return directly the values like they are
692
- if (nodeValues[nodeProperties.name] !== undefined) {
693
- nodeParameters[nodeProperties.name] = (0, utils_1.deepCopy)(nodeValues[nodeProperties.name]);
694
- }
695
- else if (returnDefaults) {
696
- // Does not have values defined but defaults should be returned
697
- if (Array.isArray(nodeProperties.default)) {
698
- nodeParameters[nodeProperties.name] = (0, utils_1.deepCopy)(nodeProperties.default);
699
- }
700
- else {
701
- // As it is probably wrong for many nodes, do we keep on returning an empty array if
702
- // anything else than an array is set as default
703
- nodeParameters[nodeProperties.name] = [];
704
- }
705
- }
664
+ // Strip expression prefix if noDataExpression is true
665
+ if (nodeProperties.noDataExpression && nodeParameters[nodeProperties.name] !== undefined) {
666
+ const value = nodeParameters[nodeProperties.name];
667
+ // A lone $fromAI() placeholder must keep its "=" or the AI tool call never resolves it (#30531)
668
+ if ((0, expression_helpers_1.isExpression)(value) && !(0, from_ai_parse_utils_1.isFromAIOnlyExpression)(value)) {
669
+ nodeParameters[nodeProperties.name] = value.slice(1);
706
670
  nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
707
671
  }
708
- else if (nodeValues[nodeProperties.name] !== undefined) {
709
- // Has values defined so get them
710
- const tempNodeParameters = getNodeParameters(nodeProperties.options, nodeValues[nodeProperties.name], returnDefaults, returnNoneDisplayed, node, nodeTypeDescription, {
711
- onlySimpleTypes: false,
712
- dataIsResolved: false,
713
- nodeValuesRoot,
714
- parentType: nodeProperties.type,
715
- });
716
- if (tempNodeParameters !== null) {
717
- nodeParameters[nodeProperties.name] = tempNodeParameters;
718
- nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
719
- }
672
+ }
673
+ }
674
+ if (onlySimpleTypes) {
675
+ // It is only supposed to resolve the simple types. So continue.
676
+ continue;
677
+ }
678
+ // Is a complex property so check lower levels
679
+ let tempValue;
680
+ if (nodeProperties.type === 'collection') {
681
+ // Is collection
682
+ if (nodeProperties.typeOptions !== undefined &&
683
+ nodeProperties.typeOptions.multipleValues === true) {
684
+ // Multiple can be set so will be an array
685
+ // Return directly the values like they are
686
+ if (nodeValues[nodeProperties.name] !== undefined) {
687
+ nodeParameters[nodeProperties.name] = (0, utils_1.deepCopy)(nodeValues[nodeProperties.name]);
720
688
  }
721
689
  else if (returnDefaults) {
722
690
  // Does not have values defined but defaults should be returned
723
- nodeParameters[nodeProperties.name] = (0, utils_1.deepCopy)(nodeProperties.default);
724
- nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
691
+ if (Array.isArray(nodeProperties.default)) {
692
+ nodeParameters[nodeProperties.name] = (0, utils_1.deepCopy)(nodeProperties.default);
693
+ }
694
+ else {
695
+ // As it is probably wrong for many nodes, do we keep on returning an empty array if
696
+ // anything else than an array is set as default
697
+ nodeParameters[nodeProperties.name] = [];
698
+ }
725
699
  }
700
+ nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
726
701
  }
727
- else if (nodeProperties.type === 'fixedCollection') {
728
- // Is fixedCollection
729
- const collectionValues = {};
730
- let tempNodeParameters;
731
- let tempNodePropertiesArray;
732
- let nodePropertyOptions;
733
- let propertyValues = (0, utils_1.deepCopy)(nodeValues[nodeProperties.name]);
734
- if (returnDefaults) {
735
- if (propertyValues === undefined) {
736
- propertyValues = (0, utils_1.deepCopy)(nodeProperties.default);
737
- }
702
+ else if (nodeValues[nodeProperties.name] !== undefined) {
703
+ // Has values defined so get them
704
+ const tempNodeParameters = getNodeParameters(nodeProperties.options, nodeValues[nodeProperties.name], returnDefaults, returnNoneDisplayed, node, nodeTypeDescription, {
705
+ onlySimpleTypes: false,
706
+ dataIsResolved: false,
707
+ nodeValuesRoot,
708
+ parentType: nodeProperties.type,
709
+ });
710
+ if (tempNodeParameters !== null) {
711
+ nodeParameters[nodeProperties.name] = tempNodeParameters;
712
+ nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
738
713
  }
739
- if (!returnDefaults &&
740
- nodeProperties.typeOptions?.multipleValues === false &&
741
- propertyValues &&
742
- Object.keys(propertyValues).length === 0) {
743
- // For fixedCollections, which only allow one value, it is important to still return
744
- // the empty object which indicates that a value got added, even if it does not have
745
- // anything set. If that is not done, the value would get lost.
746
- return (0, utils_1.deepCopy)(nodeValues);
714
+ }
715
+ else if (returnDefaults) {
716
+ // Does not have values defined but defaults should be returned
717
+ nodeParameters[nodeProperties.name] = (0, utils_1.deepCopy)(nodeProperties.default);
718
+ nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
719
+ }
720
+ }
721
+ else if (nodeProperties.type === 'fixedCollection') {
722
+ // Is fixedCollection
723
+ const collectionValues = {};
724
+ let tempNodeParameters;
725
+ let tempNodePropertiesArray;
726
+ let nodePropertyOptions;
727
+ let propertyValues = (0, utils_1.deepCopy)(nodeValues[nodeProperties.name]);
728
+ if (returnDefaults) {
729
+ if (propertyValues === undefined) {
730
+ propertyValues = (0, utils_1.deepCopy)(nodeProperties.default);
747
731
  }
748
- // Track if any visible fields were processed across all collection items
749
- let hadAnyVisibleFields = false;
750
- // Iterate over all collections
751
- for (const itemName of Object.keys(propertyValues || {})) {
752
- if (nodeProperties.typeOptions !== undefined &&
753
- nodeProperties.typeOptions.multipleValues === true) {
754
- // Multiple can be set so will be an array
755
- const tempArrayValue = [];
756
- // Collection values should always be an object
757
- if (typeof propertyValues !== 'object' || Array.isArray(propertyValues)) {
758
- continue;
759
- }
760
- nodePropertyOptions = nodeProperties.options.find((nodePropertyOptions) => nodePropertyOptions.name === itemName);
761
- if (nodePropertyOptions === undefined) {
762
- continue;
763
- }
764
- // Iterate over all items as it contains multiple ones
765
- for (const nodeValue of propertyValues[itemName]) {
766
- tempNodePropertiesArray = nodePropertyOptions.values;
767
- tempValue = getNodeParameters(tempNodePropertiesArray, nodeValue, returnDefaults, returnNoneDisplayed, node, nodeTypeDescription, {
768
- onlySimpleTypes: false,
769
- dataIsResolved: false,
770
- nodeValuesRoot,
771
- parentType: nodeProperties.type,
772
- });
773
- if (tempValue !== null) {
774
- tempArrayValue.push(tempValue);
775
- }
732
+ }
733
+ if (!returnDefaults &&
734
+ nodeProperties.typeOptions?.multipleValues === false &&
735
+ propertyValues &&
736
+ Object.keys(propertyValues).length === 0) {
737
+ // For fixedCollections, which only allow one value, it is important to still return
738
+ // the empty object which indicates that a value got added, even if it does not have
739
+ // anything set. If that is not done, the value would get lost.
740
+ return (0, utils_1.deepCopy)(nodeValues);
741
+ }
742
+ // Track if any visible fields were processed across all collection items
743
+ let hadAnyVisibleFields = false;
744
+ // Iterate over all collections
745
+ for (const itemName of Object.keys(propertyValues || {})) {
746
+ if (nodeProperties.typeOptions !== undefined &&
747
+ nodeProperties.typeOptions.multipleValues === true) {
748
+ // Multiple can be set so will be an array
749
+ const tempArrayValue = [];
750
+ // Collection values should always be an object
751
+ if (typeof propertyValues !== 'object' || Array.isArray(propertyValues)) {
752
+ continue;
753
+ }
754
+ nodePropertyOptions = nodeProperties.options.find((nodePropertyOptions) => nodePropertyOptions.name === itemName);
755
+ if (nodePropertyOptions === undefined) {
756
+ continue;
757
+ }
758
+ // Iterate over all items as it contains multiple ones
759
+ for (const nodeValue of propertyValues[itemName]) {
760
+ tempNodePropertiesArray = nodePropertyOptions.values;
761
+ tempValue = getNodeParameters(tempNodePropertiesArray, nodeValue, returnDefaults, returnNoneDisplayed, node, nodeTypeDescription, {
762
+ onlySimpleTypes: false,
763
+ dataIsResolved: false,
764
+ nodeValuesRoot,
765
+ parentType: nodeProperties.type,
766
+ });
767
+ if (tempValue !== null) {
768
+ tempArrayValue.push(tempValue);
776
769
  }
777
- collectionValues[itemName] = tempArrayValue;
778
770
  }
779
- else {
780
- // Only one can be set so is an object of objects
781
- tempNodeParameters = {};
782
- let hadVisibleFields = false;
783
- // Get the options of the current item
784
- const nodePropertyOptions = nodeProperties.options.find((data) => data.name === itemName);
785
- if (nodePropertyOptions !== undefined) {
786
- tempNodePropertiesArray = nodePropertyOptions.values;
787
- const itemNodeValues = nodeValues[nodeProperties.name][itemName];
788
- tempValue = getNodeParameters(tempNodePropertiesArray, itemNodeValues, returnDefaults, returnNoneDisplayed, node, nodeTypeDescription, {
789
- onlySimpleTypes: false,
790
- dataIsResolved: false,
791
- nodeValuesRoot,
792
- parentType: nodeProperties.type,
793
- });
794
- if (tempValue !== null) {
795
- Object.assign(tempNodeParameters, tempValue);
796
- if (Object.keys(tempValue).length > 0) {
797
- // tempValue has content, so fields are visible
771
+ collectionValues[itemName] = tempArrayValue;
772
+ }
773
+ else {
774
+ // Only one can be set so is an object of objects
775
+ tempNodeParameters = {};
776
+ let hadVisibleFields = false;
777
+ // Get the options of the current item
778
+ const nodePropertyOptions = nodeProperties.options.find((data) => data.name === itemName);
779
+ if (nodePropertyOptions !== undefined) {
780
+ tempNodePropertiesArray = nodePropertyOptions.values;
781
+ const itemNodeValues = nodeValues[nodeProperties.name][itemName];
782
+ tempValue = getNodeParameters(tempNodePropertiesArray, itemNodeValues, returnDefaults, returnNoneDisplayed, node, nodeTypeDescription, {
783
+ onlySimpleTypes: false,
784
+ dataIsResolved: false,
785
+ nodeValuesRoot,
786
+ parentType: nodeProperties.type,
787
+ });
788
+ if (tempValue !== null) {
789
+ Object.assign(tempNodeParameters, tempValue);
790
+ if (Object.keys(tempValue).length > 0) {
791
+ // tempValue has content, so fields are visible
792
+ hadVisibleFields = true;
793
+ hadAnyVisibleFields = true;
794
+ }
795
+ else {
796
+ // tempValue is empty. Check if user provided non-default values that got filtered
797
+ const hasNonDefaultValues = itemNodeValues &&
798
+ Object.keys(itemNodeValues).some((key) => {
799
+ const field = tempNodePropertiesArray.find((f) => f.name === key);
800
+ return field && !(0, isEqual_1.default)(itemNodeValues[key], field.default);
801
+ });
802
+ if (!hasNonDefaultValues) {
803
+ // All values are defaults, so the collection is explicitly added with default values
804
+ // We should preserve this (GitHub case)
798
805
  hadVisibleFields = true;
799
806
  hadAnyVisibleFields = true;
800
807
  }
801
- else {
802
- // tempValue is empty. Check if user provided non-default values that got filtered
803
- const hasNonDefaultValues = itemNodeValues &&
804
- Object.keys(itemNodeValues).some((key) => {
805
- const field = tempNodePropertiesArray.find((f) => f.name === key);
806
- return field && !(0, isEqual_1.default)(itemNodeValues[key], field.default);
807
- });
808
- if (!hasNonDefaultValues) {
809
- // All values are defaults, so the collection is explicitly added with default values
810
- // We should preserve this (GitHub case)
811
- hadVisibleFields = true;
812
- hadAnyVisibleFields = true;
813
- }
814
- // If hasNonDefaultValues is true, values were filtered by displayOptions (test case)
815
- // So we don't set hadVisibleFields
816
- }
808
+ // If hasNonDefaultValues is true, values were filtered by displayOptions (test case)
809
+ // So we don't set hadVisibleFields
817
810
  }
818
811
  }
819
- if (Object.keys(tempNodeParameters).length !== 0) {
820
- collectionValues[itemName] = tempNodeParameters;
821
- }
822
- else if (!returnDefaults &&
823
- hadVisibleFields &&
824
- propertyValues &&
825
- propertyValues[itemName] !== undefined) {
826
- // Preserve explicitly set empty collections when the user added an option
827
- // that contains only default values. Only preserve if there were visible fields
828
- // (hadVisibleFields), otherwise the collection is empty because all fields
829
- // are hidden by displayOptions.
830
- collectionValues[itemName] = tempNodeParameters;
831
- }
812
+ }
813
+ if (Object.keys(tempNodeParameters).length !== 0) {
814
+ collectionValues[itemName] = tempNodeParameters;
815
+ }
816
+ else if (!returnDefaults &&
817
+ hadVisibleFields &&
818
+ propertyValues &&
819
+ propertyValues[itemName] !== undefined) {
820
+ // Preserve explicitly set empty collections when the user added an option
821
+ // that contains only default values. Only preserve if there were visible fields
822
+ // (hadVisibleFields), otherwise the collection is empty because all fields
823
+ // are hidden by displayOptions.
824
+ collectionValues[itemName] = tempNodeParameters;
832
825
  }
833
826
  }
834
- if (!returnDefaults &&
835
- hadAnyVisibleFields &&
836
- nodeProperties.typeOptions?.multipleValues === false &&
837
- collectionValues &&
838
- Object.keys(collectionValues).length === 0 &&
839
- propertyValues &&
840
- propertyValues?.constructor.name === 'Object' &&
841
- Object.keys(propertyValues).length !== 0) {
842
- // For fixedCollections, which only allow one value, it is important to still return
843
- // the object with an empty collection property which indicates that a value got added
844
- // which contains all default values. Only preserve if there were visible fields,
845
- // otherwise the collection is empty because all fields are hidden by displayOptions.
846
- const returnValue = {};
847
- Object.keys(propertyValues || {}).forEach((value) => {
848
- returnValue[value] = {};
849
- });
850
- nodeParameters[nodeProperties.name] = returnValue;
851
- }
852
- if (Object.keys(collectionValues).length !== 0 || returnDefaults) {
853
- // Set only if value got found
854
- if (returnDefaults) {
855
- // Set also when it has the default value
856
- if (collectionValues === undefined) {
857
- nodeParameters[nodeProperties.name] = (0, utils_1.deepCopy)(nodeProperties.default);
858
- }
859
- else {
860
- nodeParameters[nodeProperties.name] = collectionValues;
861
- }
862
- nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
827
+ }
828
+ if (!returnDefaults &&
829
+ hadAnyVisibleFields &&
830
+ nodeProperties.typeOptions?.multipleValues === false &&
831
+ collectionValues &&
832
+ Object.keys(collectionValues).length === 0 &&
833
+ propertyValues &&
834
+ propertyValues?.constructor.name === 'Object' &&
835
+ Object.keys(propertyValues).length !== 0) {
836
+ // For fixedCollections, which only allow one value, it is important to still return
837
+ // the object with an empty collection property which indicates that a value got added
838
+ // which contains all default values. Only preserve if there were visible fields,
839
+ // otherwise the collection is empty because all fields are hidden by displayOptions.
840
+ const returnValue = {};
841
+ Object.keys(propertyValues || {}).forEach((value) => {
842
+ returnValue[value] = {};
843
+ });
844
+ nodeParameters[nodeProperties.name] = returnValue;
845
+ }
846
+ if (Object.keys(collectionValues).length !== 0 || returnDefaults) {
847
+ // Set only if value got found
848
+ if (returnDefaults) {
849
+ // Set also when it has the default value
850
+ if (collectionValues === undefined) {
851
+ nodeParameters[nodeProperties.name] = (0, utils_1.deepCopy)(nodeProperties.default);
863
852
  }
864
- else if (collectionValues !== nodeProperties.default) {
865
- // Set only if values got found and it is not the default
853
+ else {
866
854
  nodeParameters[nodeProperties.name] = collectionValues;
867
- nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
868
855
  }
856
+ nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
857
+ }
858
+ else if (collectionValues !== nodeProperties.default) {
859
+ // Set only if values got found and it is not the default
860
+ nodeParameters[nodeProperties.name] = collectionValues;
861
+ nodeParametersFull[nodeProperties.name] = nodeParameters[nodeProperties.name];
869
862
  }
870
863
  }
871
864
  }
872
- return nodeParameters;
873
- }
874
- /**
875
- * Returns the webhook path
876
- */
877
- function getNodeWebhookPath(workflowId, node, path, isFullPath, restartWebhook) {
878
- let webhookPath = '';
879
- if (restartWebhook === true) {
880
- return path;
881
- }
882
- if (node.webhookId === undefined) {
883
- const nodeName = encodeURIComponent(node.name.toLowerCase());
884
- webhookPath = `${workflowId}/${nodeName}/${path}`;
885
- }
886
- else {
887
- if (isFullPath === true) {
888
- return path || node.webhookId;
889
- }
890
- webhookPath = `${node.webhookId}/${path}`;
891
- }
892
- return webhookPath;
893
- }
894
- /**
895
- * Returns the webhook URL
896
- */
897
- function getNodeWebhookUrl(baseUrl, workflowId, node, path, isFullPath) {
898
- if ((path.startsWith(':') || path.includes('/:')) && node.webhookId) {
899
- // setting this to false to prefix the webhookId
900
- isFullPath = false;
901
- }
902
- if (path.startsWith('/')) {
903
- path = path.slice(1);
904
- }
905
- return `${baseUrl}/${getNodeWebhookPath(workflowId, node, path, isFullPath)}`;
906
- }
907
- /**
908
- * Assigns a webhookId to a node if its type has webhook definitions
909
- * and the node doesn't already have one.
910
- */
911
- function resolveNodeWebhookId(node, nodeTypeDescription) {
912
- if (nodeTypeDescription.webhooks?.length && !node.webhookId) {
913
- node.webhookId = (0, uuid_1.v4)();
914
- }
915
865
  }
916
- function getConnectionTypes(connections) {
917
- return connections
918
- .map((connection) => {
919
- if (typeof connection === 'string') {
920
- return connection;
921
- }
922
- return connection.type;
923
- })
924
- .filter((connection) => connection !== undefined);
866
+ return nodeParameters;
867
+ }
868
+ /**
869
+ * Returns the webhook path
870
+ */
871
+ function getNodeWebhookPath(workflowId, node, path, isFullPath, restartWebhook) {
872
+ let webhookPath = '';
873
+ if (restartWebhook === true) {
874
+ return path;
875
+ }
876
+ if (node.webhookId === undefined) {
877
+ const nodeName = encodeURIComponent(node.name.toLowerCase());
878
+ webhookPath = `${workflowId}/${nodeName}/${path}`;
925
879
  }
926
- function getNodeInputs(workflow, node, nodeTypeData) {
927
- if (Array.isArray(nodeTypeData?.inputs)) {
928
- return nodeTypeData.inputs;
880
+ else {
881
+ if (isFullPath === true) {
882
+ return path || node.webhookId;
929
883
  }
884
+ webhookPath = `${node.webhookId}/${path}`;
885
+ }
886
+ return webhookPath;
887
+ }
888
+ /**
889
+ * Returns the webhook URL
890
+ */
891
+ function getNodeWebhookUrl(baseUrl, workflowId, node, path, isFullPath) {
892
+ if ((path.startsWith(':') || path.includes('/:')) && node.webhookId) {
893
+ // setting this to false to prefix the webhookId
894
+ isFullPath = false;
895
+ }
896
+ if (path.startsWith('/')) {
897
+ path = path.slice(1);
898
+ }
899
+ return `${baseUrl}/${getNodeWebhookPath(workflowId, node, path, isFullPath)}`;
900
+ }
901
+ /**
902
+ * Assigns a webhookId to a node if its type has webhook definitions
903
+ * and the node doesn't already have one.
904
+ */
905
+ function resolveNodeWebhookId(node, nodeTypeDescription) {
906
+ if (nodeTypeDescription.webhooks?.length && !node.webhookId) {
907
+ node.webhookId = (0, uuid_1.v4)();
908
+ }
909
+ }
910
+ function getConnectionTypes(connections) {
911
+ return connections
912
+ .map((connection) => {
913
+ if (typeof connection === 'string') {
914
+ return connection;
915
+ }
916
+ return connection.type;
917
+ })
918
+ .filter((connection) => connection !== undefined);
919
+ }
920
+ function getNodeInputs(workflow, node, nodeTypeData) {
921
+ if (Array.isArray(nodeTypeData?.inputs)) {
922
+ return nodeTypeData.inputs;
923
+ }
924
+ // Calculate the outputs dynamically
925
+ try {
926
+ return (workflow.expression.getSimpleParameterValue(node, nodeTypeData.inputs, 'internal', {}) || []);
927
+ }
928
+ catch (e) {
929
+ console.warn('Could not calculate inputs dynamically for node: ', node.name);
930
+ return [];
931
+ }
932
+ }
933
+ function getNodeOutputs(workflow, node, nodeTypeData) {
934
+ let outputs = [];
935
+ if (!nodeTypeData) {
936
+ return [];
937
+ }
938
+ if (Array.isArray(nodeTypeData.outputs)) {
939
+ outputs = nodeTypeData.outputs;
940
+ }
941
+ else {
930
942
  // Calculate the outputs dynamically
931
943
  try {
932
- return (workflow.expression.getSimpleParameterValue(node, nodeTypeData.inputs, 'internal', {}) || []);
944
+ const result = workflow.expression.getSimpleParameterValue(node, nodeTypeData.outputs, 'internal', {});
945
+ outputs = Array.isArray(result)
946
+ ? result
947
+ : [];
933
948
  }
934
949
  catch (e) {
935
- console.warn('Could not calculate inputs dynamically for node: ', node.name);
936
- return [];
950
+ console.warn('Could not calculate outputs dynamically for node: ', node.name);
937
951
  }
938
952
  }
939
- function getNodeOutputs(workflow, node, nodeTypeData) {
940
- let outputs = [];
941
- if (!nodeTypeData) {
942
- return [];
943
- }
944
- if (Array.isArray(nodeTypeData.outputs)) {
945
- outputs = nodeTypeData.outputs;
946
- }
947
- else {
948
- // Calculate the outputs dynamically
949
- try {
950
- const result = workflow.expression.getSimpleParameterValue(node, nodeTypeData.outputs, 'internal', {});
951
- outputs = Array.isArray(result)
952
- ? result
953
- : [];
954
- }
955
- catch (e) {
956
- console.warn('Could not calculate outputs dynamically for node: ', node.name);
953
+ if (node.onError === 'continueErrorOutput') {
954
+ // Copy the data to make sure that we do not change the data of the
955
+ // node type and so change the displayNames for all nodes in the flow
956
+ outputs = (0, utils_1.deepCopy)(outputs);
957
+ if (outputs.length === 1) {
958
+ // Set the displayName to "Success"
959
+ if (typeof outputs[0] === 'string') {
960
+ outputs[0] = {
961
+ type: outputs[0],
962
+ };
957
963
  }
964
+ outputs[0].displayName = 'Success';
965
+ }
966
+ return [
967
+ ...outputs,
968
+ {
969
+ category: 'error',
970
+ type: interfaces_1.NodeConnectionTypes.Main,
971
+ displayName: 'Error',
972
+ },
973
+ ];
974
+ }
975
+ return outputs;
976
+ }
977
+ /**
978
+ * Returns all the parameter-issues of the node
979
+ *
980
+ * @param {INodeProperties[]} nodePropertiesArray The properties of the node
981
+ * @param {INode} node The data of the node
982
+ */
983
+ function getNodeParametersIssues(nodePropertiesArray, node, nodeTypeDescription, pinDataNodeNames) {
984
+ const foundIssues = {};
985
+ let propertyIssues;
986
+ if (node.disabled === true || pinDataNodeNames?.includes(node.name)) {
987
+ // Ignore issues on disabled and pindata nodes
988
+ return null;
989
+ }
990
+ for (const nodeProperty of nodePropertiesArray) {
991
+ propertyIssues = getParameterIssues(nodeProperty, node.parameters, '', node, nodeTypeDescription);
992
+ mergeIssues(foundIssues, propertyIssues);
993
+ }
994
+ if (Object.keys(foundIssues).length === 0) {
995
+ return null;
996
+ }
997
+ return foundIssues;
998
+ }
999
+ /**
1000
+ * Returns the node's issues as a flat list of human-readable strings,
1001
+ * covering execution errors, parameter/credential/input issues, and unknown node types.
1002
+ */
1003
+ function nodeIssuesToString(issues, node) {
1004
+ const messages = [];
1005
+ if (issues.execution !== undefined) {
1006
+ messages.push('Execution Error.');
1007
+ }
1008
+ for (const propertyIssues of [issues.parameters, issues.credentials, issues.input]) {
1009
+ if (propertyIssues === undefined)
1010
+ continue;
1011
+ for (const parameterName of Object.keys(propertyIssues)) {
1012
+ messages.push(...propertyIssues[parameterName]);
958
1013
  }
959
- if (node.onError === 'continueErrorOutput') {
960
- // Copy the data to make sure that we do not change the data of the
961
- // node type and so change the displayNames for all nodes in the flow
962
- outputs = (0, utils_1.deepCopy)(outputs);
963
- if (outputs.length === 1) {
964
- // Set the displayName to "Success"
965
- if (typeof outputs[0] === 'string') {
966
- outputs[0] = {
967
- type: outputs[0],
968
- };
1014
+ }
1015
+ if (issues.typeUnknown !== undefined) {
1016
+ messages.push(node !== undefined ? `Node Type "${node.type}" is not known.` : 'Node Type is not known.');
1017
+ }
1018
+ return messages;
1019
+ }
1020
+ /*
1021
+ * Validates resource locator node parameters based on validation ruled defined in each parameter mode
1022
+ */
1023
+ const validateResourceLocatorParameter = (value, parameterMode) => {
1024
+ const valueToValidate = value?.value?.toString() || '';
1025
+ if (valueToValidate.startsWith('=')) {
1026
+ return [];
1027
+ }
1028
+ const validationErrors = [];
1029
+ // Each mode can have multiple validations specified
1030
+ if (parameterMode.validation) {
1031
+ for (const validation of parameterMode.validation) {
1032
+ if (validation && validation.type === 'regex') {
1033
+ const regexValidation = validation;
1034
+ const regex = new RegExp(`^${regexValidation.properties.regex}$`);
1035
+ if (!regex.test(valueToValidate)) {
1036
+ validationErrors.push(regexValidation.properties.errorMessage);
969
1037
  }
970
- outputs[0].displayName = 'Success';
971
1038
  }
972
- return [
973
- ...outputs,
974
- {
975
- category: 'error',
976
- type: interfaces_1.NodeConnectionTypes.Main,
977
- displayName: 'Error',
978
- },
979
- ];
980
- }
981
- return outputs;
982
- }
983
- /**
984
- * Returns all the parameter-issues of the node
985
- *
986
- * @param {INodeProperties[]} nodePropertiesArray The properties of the node
987
- * @param {INode} node The data of the node
988
- */
989
- function getNodeParametersIssues(nodePropertiesArray, node, nodeTypeDescription, pinDataNodeNames) {
990
- const foundIssues = {};
991
- let propertyIssues;
992
- if (node.disabled === true || pinDataNodeNames?.includes(node.name)) {
993
- // Ignore issues on disabled and pindata nodes
994
- return null;
995
- }
996
- for (const nodeProperty of nodePropertiesArray) {
997
- propertyIssues = getParameterIssues(nodeProperty, node.parameters, '', node, nodeTypeDescription);
998
- mergeIssues(foundIssues, propertyIssues);
999
1039
  }
1000
- if (Object.keys(foundIssues).length === 0) {
1001
- return null;
1002
- }
1003
- return foundIssues;
1004
1040
  }
1005
- /**
1006
- * Returns the node's issues as a flat list of human-readable strings,
1007
- * covering execution errors, parameter/credential/input issues, and unknown node types.
1008
- */
1009
- function nodeIssuesToString(issues, node) {
1010
- const messages = [];
1011
- if (issues.execution !== undefined) {
1012
- messages.push('Execution Error.');
1013
- }
1014
- for (const propertyIssues of [issues.parameters, issues.credentials, issues.input]) {
1015
- if (propertyIssues === undefined)
1016
- continue;
1017
- for (const parameterName of Object.keys(propertyIssues)) {
1018
- messages.push(...propertyIssues[parameterName]);
1041
+ return validationErrors;
1042
+ };
1043
+ /*
1044
+ * Validates resource mapper values based on service schema
1045
+ */
1046
+ const validateResourceMapperParameter = (nodeProperties, value, skipRequiredCheck = false) => {
1047
+ // No issues to raise in automatic mapping mode, no user input to validate
1048
+ if (value.mappingMode === 'autoMapInputData') {
1049
+ return {};
1050
+ }
1051
+ const issues = {};
1052
+ let fieldWordSingular = nodeProperties.typeOptions?.resourceMapper?.fieldWords?.singular || 'Field';
1053
+ fieldWordSingular = fieldWordSingular.charAt(0).toUpperCase() + fieldWordSingular.slice(1);
1054
+ value.schema.forEach((field) => {
1055
+ const fieldValue = value.value ? value.value[field.id] : null;
1056
+ const key = `${nodeProperties.name}.${field.id}`;
1057
+ const fieldErrors = [];
1058
+ if (field.required && !skipRequiredCheck) {
1059
+ if (value.value === null || fieldValue === undefined) {
1060
+ const error = `${fieldWordSingular} "${field.id}" is required`;
1061
+ fieldErrors.push(error);
1019
1062
  }
1020
1063
  }
1021
- if (issues.typeUnknown !== undefined) {
1022
- messages.push(node !== undefined ? `Node Type "${node.type}" is not known.` : 'Node Type is not known.');
1023
- }
1024
- return messages;
1025
- }
1026
- /*
1027
- * Validates resource locator node parameters based on validation ruled defined in each parameter mode
1028
- */
1029
- const validateResourceLocatorParameter = (value, parameterMode) => {
1030
- const valueToValidate = value?.value?.toString() || '';
1031
- if (valueToValidate.startsWith('=')) {
1032
- return [];
1033
- }
1034
- const validationErrors = [];
1035
- // Each mode can have multiple validations specified
1036
- if (parameterMode.validation) {
1037
- for (const validation of parameterMode.validation) {
1038
- if (validation && validation.type === 'regex') {
1039
- const regexValidation = validation;
1040
- const regex = new RegExp(`^${regexValidation.properties.regex}$`);
1041
- if (!regex.test(valueToValidate)) {
1042
- validationErrors.push(regexValidation.properties.errorMessage);
1043
- }
1044
- }
1064
+ if (!fieldValue?.toString().startsWith('=') && field.type) {
1065
+ const validationResult = (0, type_validation_1.validateFieldType)(field.id, fieldValue, field.type, {
1066
+ valueOptions: field.options,
1067
+ });
1068
+ if (!validationResult.valid && validationResult.errorMessage) {
1069
+ fieldErrors.push(validationResult.errorMessage);
1045
1070
  }
1046
1071
  }
1047
- return validationErrors;
1048
- };
1049
- /*
1050
- * Validates resource mapper values based on service schema
1051
- */
1052
- const validateResourceMapperParameter = (nodeProperties, value, skipRequiredCheck = false) => {
1053
- // No issues to raise in automatic mapping mode, no user input to validate
1054
- if (value.mappingMode === 'autoMapInputData') {
1055
- return {};
1072
+ if (fieldErrors.length > 0) {
1073
+ issues[key] = fieldErrors;
1056
1074
  }
1057
- const issues = {};
1058
- let fieldWordSingular = nodeProperties.typeOptions?.resourceMapper?.fieldWords?.singular || 'Field';
1059
- fieldWordSingular = fieldWordSingular.charAt(0).toUpperCase() + fieldWordSingular.slice(1);
1060
- value.schema.forEach((field) => {
1061
- const fieldValue = value.value ? value.value[field.id] : null;
1062
- const key = `${nodeProperties.name}.${field.id}`;
1063
- const fieldErrors = [];
1064
- if (field.required && !skipRequiredCheck) {
1065
- if (value.value === null || fieldValue === undefined) {
1066
- const error = `${fieldWordSingular} "${field.id}" is required`;
1067
- fieldErrors.push(error);
1068
- }
1069
- }
1070
- if (!fieldValue?.toString().startsWith('=') && field.type) {
1071
- const validationResult = (0, type_validation_1.validateFieldType)(field.id, fieldValue, field.type, {
1072
- valueOptions: field.options,
1073
- });
1074
- if (!validationResult.valid && validationResult.errorMessage) {
1075
- fieldErrors.push(validationResult.errorMessage);
1076
- }
1077
- }
1078
- if (fieldErrors.length > 0) {
1079
- issues[key] = fieldErrors;
1080
- }
1075
+ });
1076
+ return issues;
1077
+ };
1078
+ const validateParameter = (nodeProperties, value, type) => {
1079
+ const nodeName = nodeProperties.name;
1080
+ const options = type === 'options' ? nodeProperties.options : undefined;
1081
+ if (!value?.toString().startsWith('=')) {
1082
+ const validationResult = (0, type_validation_1.validateFieldType)(nodeName, value, type, {
1083
+ valueOptions: options,
1081
1084
  });
1082
- return issues;
1083
- };
1084
- const validateParameter = (nodeProperties, value, type) => {
1085
- const nodeName = nodeProperties.name;
1086
- const options = type === 'options' ? nodeProperties.options : undefined;
1087
- if (!value?.toString().startsWith('=')) {
1088
- const validationResult = (0, type_validation_1.validateFieldType)(nodeName, value, type, {
1089
- valueOptions: options,
1090
- });
1091
- if (!validationResult.valid && validationResult.errorMessage) {
1092
- return validationResult.errorMessage;
1093
- }
1085
+ if (!validationResult.valid && validationResult.errorMessage) {
1086
+ return validationResult.errorMessage;
1094
1087
  }
1095
- return undefined;
1096
- };
1097
- /**
1098
- * Adds an issue if the parameter is not defined
1099
- *
1100
- * @param {INodeIssues} foundIssues The already found issues
1101
- * @param {INodeProperties} nodeProperties The properties of the node
1102
- * @param {NodeParameterValue} value The value of the parameter
1103
- */
1104
- function addToIssuesIfMissing(foundIssues, nodeProperties, value) {
1105
- // TODO: Check what it really has when undefined
1106
- if ((nodeProperties.type === 'string' && (value === '' || value === undefined)) ||
1107
- (nodeProperties.type === 'multiOptions' && Array.isArray(value) && value.length === 0) ||
1108
- (nodeProperties.type === 'dateTime' && (value === '' || value === undefined)) ||
1109
- (nodeProperties.type === 'options' && (value === '' || value === undefined)) ||
1110
- ((nodeProperties.type === 'resourceLocator' ||
1111
- nodeProperties.type === 'workflowSelector' ||
1112
- nodeProperties.type === 'agentSelector') &&
1113
- !(0, type_guards_1.isValidResourceLocatorParameterValue)(value))) {
1114
- // Parameter is required but empty
1115
- if (foundIssues.parameters === undefined) {
1116
- foundIssues.parameters = {};
1117
- }
1118
- if (foundIssues.parameters[nodeProperties.name] === undefined) {
1119
- foundIssues.parameters[nodeProperties.name] = [];
1120
- }
1121
- foundIssues.parameters[nodeProperties.name].push(`Parameter "${nodeProperties.displayName}" is required.`);
1088
+ }
1089
+ return undefined;
1090
+ };
1091
+ /**
1092
+ * Adds an issue if the parameter is not defined
1093
+ *
1094
+ * @param {INodeIssues} foundIssues The already found issues
1095
+ * @param {INodeProperties} nodeProperties The properties of the node
1096
+ * @param {NodeParameterValue} value The value of the parameter
1097
+ */
1098
+ function addToIssuesIfMissing(foundIssues, nodeProperties, value) {
1099
+ // TODO: Check what it really has when undefined
1100
+ if ((nodeProperties.type === 'string' && (value === '' || value === undefined)) ||
1101
+ (nodeProperties.type === 'multiOptions' && Array.isArray(value) && value.length === 0) ||
1102
+ (nodeProperties.type === 'dateTime' && (value === '' || value === undefined)) ||
1103
+ (nodeProperties.type === 'options' && (value === '' || value === undefined)) ||
1104
+ ((nodeProperties.type === 'resourceLocator' ||
1105
+ nodeProperties.type === 'workflowSelector' ||
1106
+ nodeProperties.type === 'agentSelector') &&
1107
+ !(0, type_guards_1.isValidResourceLocatorParameterValue)(value))) {
1108
+ // Parameter is required but empty
1109
+ if (foundIssues.parameters === undefined) {
1110
+ foundIssues.parameters = {};
1122
1111
  }
1112
+ if (foundIssues.parameters[nodeProperties.name] === undefined) {
1113
+ foundIssues.parameters[nodeProperties.name] = [];
1114
+ }
1115
+ foundIssues.parameters[nodeProperties.name].push(`Parameter "${nodeProperties.displayName}" is required.`);
1123
1116
  }
1124
- /**
1125
- * Returns the parameter value
1126
- *
1127
- * @param {INodeParameters} nodeValues The values of the node
1128
- * @param {string} parameterName The name of the parameter to return the value of
1129
- * @param {string} path The path to the properties
1130
- */
1131
- function getParameterValueByPath(nodeValues, parameterName, path) {
1132
- return (0, get_1.default)(nodeValues, path ? `${path}.${parameterName}` : parameterName);
1133
- }
1134
- /**
1135
- * Resolves the property definition for a parameter path, honoring `displayOptions` so that
1136
- * duplicate-named variants resolve to the one shown for the given node values (e.g. version- or
1137
- * source-gated parameters). Descends into `collection`/`fixedCollection`; the leading
1138
- * `parameters.` prefix and array indices in the path are ignored. Returns `undefined` when the
1139
- * path resolves to no displayed property.
1140
- */
1141
- function findDisplayedProperty(parameterPath, properties, nodeValues, node, nodeTypeDescription) {
1142
- const parts = parameterPath.replace(/^parameters\./, '').split('.');
1143
- let currentPath = '';
1144
- let property;
1145
- const findProp = (name, options) => options.find((option) => option.name === name &&
1146
- displayParameterPath(nodeValues, option, currentPath, node, nodeTypeDescription));
1147
- for (const part of parts) {
1148
- const name = part.split('[')[0];
1149
- if (!property) {
1150
- property = findProp(name, properties);
1151
- }
1152
- else if ('options' in property && property.options) {
1153
- property = findProp(name, property.options);
1154
- currentPath += `.${name}`;
1155
- }
1156
- else if ('values' in property) {
1157
- property = findProp(name, property.values);
1158
- currentPath += `.${name}`;
1159
- }
1160
- else {
1161
- return undefined;
1162
- }
1163
- if (!property)
1164
- return undefined;
1117
+ }
1118
+ /**
1119
+ * Returns the parameter value
1120
+ *
1121
+ * @param {INodeParameters} nodeValues The values of the node
1122
+ * @param {string} parameterName The name of the parameter to return the value of
1123
+ * @param {string} path The path to the properties
1124
+ */
1125
+ function getParameterValueByPath(nodeValues, parameterName, path) {
1126
+ return (0, get_1.default)(nodeValues, path ? `${path}.${parameterName}` : parameterName);
1127
+ }
1128
+ /**
1129
+ * Resolves the property definition for a parameter path, honoring `displayOptions` so that
1130
+ * duplicate-named variants resolve to the one shown for the given node values (e.g. version- or
1131
+ * source-gated parameters). Descends into `collection`/`fixedCollection`; the leading
1132
+ * `parameters.` prefix and array indices in the path are ignored. Returns `undefined` when the
1133
+ * path resolves to no displayed property.
1134
+ */
1135
+ function findDisplayedProperty(parameterPath, properties, nodeValues, node, nodeTypeDescription) {
1136
+ const parts = parameterPath.replace(/^parameters\./, '').split('.');
1137
+ let currentPath = '';
1138
+ let property;
1139
+ const findProp = (name, options) => options.find((option) => option.name === name &&
1140
+ displayParameterPath(nodeValues, option, currentPath, node, nodeTypeDescription));
1141
+ for (const part of parts) {
1142
+ const name = part.split('[')[0];
1143
+ if (!property) {
1144
+ property = findProp(name, properties);
1145
+ }
1146
+ else if ('options' in property && property.options) {
1147
+ property = findProp(name, property.options);
1148
+ currentPath += `.${name}`;
1149
+ }
1150
+ else if ('values' in property) {
1151
+ property = findProp(name, property.values);
1152
+ currentPath += `.${name}`;
1165
1153
  }
1166
- return property;
1167
- }
1168
- function isINodeParameterResourceLocator(value) {
1169
- return typeof value === 'object' && value !== null && 'value' in value && 'mode' in value;
1170
- }
1171
- /**
1172
- * Returns all the issues with the given node-values
1173
- *
1174
- * @param {INodeProperties} nodeProperties The properties of the node
1175
- * @param {INodeParameters} nodeValues The values of the node
1176
- * @param {string} path The path to the properties
1177
- */
1178
- // eslint-disable-next-line complexity
1179
- function getParameterIssues(nodeProperties, nodeValues, path, node, nodeTypeDescription) {
1180
- const foundIssues = {};
1181
- const isDisplayed = displayParameterPath(nodeValues, nodeProperties, path, node, nodeTypeDescription);
1182
- if (nodeProperties.required === true) {
1183
- if (isDisplayed) {
1184
- const value = getParameterValueByPath(nodeValues, nodeProperties.name, path);
1185
- if (
1186
- // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
1187
- nodeProperties.typeOptions !== undefined &&
1188
- nodeProperties.typeOptions.multipleValues !== undefined) {
1189
- // Multiple can be set so will be an array
1190
- if (Array.isArray(value)) {
1191
- for (const singleValue of value) {
1192
- addToIssuesIfMissing(foundIssues, nodeProperties, singleValue);
1193
- }
1194
- }
1195
- }
1196
- else {
1197
- // Only one can be set so will be a single value
1198
- addToIssuesIfMissing(foundIssues, nodeProperties, value);
1199
- }
1200
- }
1154
+ else {
1155
+ return undefined;
1201
1156
  }
1202
- if ((nodeProperties.type === 'resourceLocator' ||
1203
- nodeProperties.type === 'workflowSelector' ||
1204
- nodeProperties.type === 'agentSelector') &&
1205
- isDisplayed) {
1157
+ if (!property)
1158
+ return undefined;
1159
+ }
1160
+ return property;
1161
+ }
1162
+ function isINodeParameterResourceLocator(value) {
1163
+ return typeof value === 'object' && value !== null && 'value' in value && 'mode' in value;
1164
+ }
1165
+ /**
1166
+ * Returns all the issues with the given node-values
1167
+ *
1168
+ * @param {INodeProperties} nodeProperties The properties of the node
1169
+ * @param {INodeParameters} nodeValues The values of the node
1170
+ * @param {string} path The path to the properties
1171
+ */
1172
+ // eslint-disable-next-line complexity
1173
+ function getParameterIssues(nodeProperties, nodeValues, path, node, nodeTypeDescription) {
1174
+ const foundIssues = {};
1175
+ const isDisplayed = displayParameterPath(nodeValues, nodeProperties, path, node, nodeTypeDescription);
1176
+ if (nodeProperties.required === true) {
1177
+ if (isDisplayed) {
1206
1178
  const value = getParameterValueByPath(nodeValues, nodeProperties.name, path);
1207
- if (isINodeParameterResourceLocator(value)) {
1208
- const mode = nodeProperties.modes?.find((option) => option.name === value.mode);
1209
- if (mode) {
1210
- const errors = validateResourceLocatorParameter(value, mode);
1211
- errors.forEach((error) => {
1212
- if (foundIssues.parameters === undefined) {
1213
- foundIssues.parameters = {};
1214
- }
1215
- if (foundIssues.parameters[nodeProperties.name] === undefined) {
1216
- foundIssues.parameters[nodeProperties.name] = [];
1217
- }
1218
- foundIssues.parameters[nodeProperties.name].push(error);
1219
- });
1179
+ if (
1180
+ // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
1181
+ nodeProperties.typeOptions !== undefined &&
1182
+ nodeProperties.typeOptions.multipleValues !== undefined) {
1183
+ // Multiple can be set so will be an array
1184
+ if (Array.isArray(value)) {
1185
+ for (const singleValue of value) {
1186
+ addToIssuesIfMissing(foundIssues, nodeProperties, singleValue);
1187
+ }
1220
1188
  }
1221
1189
  }
1190
+ else {
1191
+ // Only one can be set so will be a single value
1192
+ addToIssuesIfMissing(foundIssues, nodeProperties, value);
1193
+ }
1222
1194
  }
1223
- else if (nodeProperties.type === 'resourceMapper' && isDisplayed) {
1224
- const skipRequiredCheck = nodeProperties.typeOptions?.resourceMapper?.mode !== 'add';
1225
- const value = getParameterValueByPath(nodeValues, nodeProperties.name, path);
1226
- if ((0, type_guards_1.isResourceMapperValue)(value)) {
1227
- const issues = validateResourceMapperParameter(nodeProperties, value, skipRequiredCheck);
1228
- if (Object.keys(issues).length > 0) {
1195
+ }
1196
+ if ((nodeProperties.type === 'resourceLocator' ||
1197
+ nodeProperties.type === 'workflowSelector' ||
1198
+ nodeProperties.type === 'agentSelector') &&
1199
+ isDisplayed) {
1200
+ const value = getParameterValueByPath(nodeValues, nodeProperties.name, path);
1201
+ if (isINodeParameterResourceLocator(value)) {
1202
+ const mode = nodeProperties.modes?.find((option) => option.name === value.mode);
1203
+ if (mode) {
1204
+ const errors = validateResourceLocatorParameter(value, mode);
1205
+ errors.forEach((error) => {
1229
1206
  if (foundIssues.parameters === undefined) {
1230
1207
  foundIssues.parameters = {};
1231
1208
  }
1232
1209
  if (foundIssues.parameters[nodeProperties.name] === undefined) {
1233
1210
  foundIssues.parameters[nodeProperties.name] = [];
1234
1211
  }
1235
- foundIssues.parameters = { ...foundIssues.parameters, ...issues };
1236
- }
1237
- }
1238
- }
1239
- else if (nodeProperties.type === 'filter' && isDisplayed) {
1240
- const value = getParameterValueByPath(nodeValues, nodeProperties.name, path);
1241
- if ((0, type_guards_1.isFilterValue)(value)) {
1242
- const issues = (0, filter_parameter_1.validateFilterParameter)(nodeProperties, value);
1243
- if (Object.keys(issues).length > 0) {
1244
- foundIssues.parameters = { ...foundIssues.parameters, ...issues };
1245
- }
1212
+ foundIssues.parameters[nodeProperties.name].push(error);
1213
+ });
1246
1214
  }
1247
1215
  }
1248
- else if (nodeProperties.validateType) {
1249
- const value = getParameterValueByPath(nodeValues, nodeProperties.name, path);
1250
- const error = validateParameter(nodeProperties, value, nodeProperties.validateType);
1251
- if (error) {
1216
+ }
1217
+ else if (nodeProperties.type === 'resourceMapper' && isDisplayed) {
1218
+ const skipRequiredCheck = nodeProperties.typeOptions?.resourceMapper?.mode !== 'add';
1219
+ const value = getParameterValueByPath(nodeValues, nodeProperties.name, path);
1220
+ if ((0, type_guards_1.isResourceMapperValue)(value)) {
1221
+ const issues = validateResourceMapperParameter(nodeProperties, value, skipRequiredCheck);
1222
+ if (Object.keys(issues).length > 0) {
1252
1223
  if (foundIssues.parameters === undefined) {
1253
1224
  foundIssues.parameters = {};
1254
1225
  }
1255
1226
  if (foundIssues.parameters[nodeProperties.name] === undefined) {
1256
1227
  foundIssues.parameters[nodeProperties.name] = [];
1257
1228
  }
1258
- foundIssues.parameters[nodeProperties.name].push(error);
1229
+ foundIssues.parameters = { ...foundIssues.parameters, ...issues };
1259
1230
  }
1260
1231
  }
1261
- // Check if there are any child parameters
1262
- if (nodeProperties.options === undefined) {
1263
- // There are none so nothing else to check
1264
- return foundIssues;
1265
- }
1266
- // Check the child parameters
1267
- // Important:
1268
- // Checks the child properties only if the property is defined on current level.
1269
- // That means that the required flag works only for the current level only. If
1270
- // it is set on a lower level it means that the property is only required in case
1271
- // the parent property got set.
1272
- let basePath = path ? `${path}.` : '';
1273
- const checkChildNodeProperties = [];
1274
- // Collect all the properties to check
1275
- if (nodeProperties.type === 'collection') {
1276
- for (const option of nodeProperties.options) {
1277
- checkChildNodeProperties.push({
1278
- basePath,
1279
- data: option,
1280
- });
1232
+ }
1233
+ else if (nodeProperties.type === 'filter' && isDisplayed) {
1234
+ const value = getParameterValueByPath(nodeValues, nodeProperties.name, path);
1235
+ if ((0, type_guards_1.isFilterValue)(value)) {
1236
+ const issues = (0, filter_parameter_1.validateFilterParameter)(nodeProperties, value);
1237
+ if (Object.keys(issues).length > 0) {
1238
+ foundIssues.parameters = { ...foundIssues.parameters, ...issues };
1281
1239
  }
1282
1240
  }
1283
- else if (nodeProperties.type === 'fixedCollection' && isDisplayed) {
1284
- basePath = basePath ? `${basePath}.` : `${nodeProperties.name}.`;
1285
- let propertyOptions;
1286
- for (propertyOptions of nodeProperties.options) {
1287
- // Check if the option got set and if not skip it
1288
- const value = getParameterValueByPath(nodeValues, propertyOptions.name, basePath.slice(0, -1));
1289
- // Validate allowed field counts
1290
- const valueArray = Array.isArray(value) ? value : [];
1291
- const { minRequiredFields, maxAllowedFields } = nodeProperties.typeOptions ?? {};
1292
- let error = '';
1293
- if (minRequiredFields && valueArray.length < minRequiredFields) {
1294
- error = `At least ${minRequiredFields} ${minRequiredFields === 1 ? 'field is' : 'fields are'} required.`;
1295
- }
1296
- if (maxAllowedFields && valueArray.length > maxAllowedFields) {
1297
- error = `At most ${maxAllowedFields} ${maxAllowedFields === 1 ? 'field is' : 'fields are'} allowed.`;
1298
- }
1299
- if (error) {
1300
- foundIssues.parameters ??= {};
1301
- foundIssues.parameters[nodeProperties.name] ??= [];
1302
- foundIssues.parameters[nodeProperties.name].push(error);
1303
- }
1304
- if (value === undefined) {
1305
- continue;
1306
- }
1307
- if (
1308
- // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
1309
- nodeProperties.typeOptions !== undefined &&
1310
- nodeProperties.typeOptions.multipleValues !== undefined) {
1311
- // Multiple can be set so will be an array of objects
1312
- if (Array.isArray(value)) {
1313
- for (let i = 0; i < value.length; i++) {
1314
- for (const option of propertyOptions.values) {
1315
- checkChildNodeProperties.push({
1316
- basePath: `${basePath}${propertyOptions.name}[${i}]`,
1317
- data: option,
1318
- });
1319
- }
1320
- }
1321
- }
1322
- }
1323
- else {
1324
- // Only one can be set so will be an object
1325
- for (const option of propertyOptions.values) {
1326
- checkChildNodeProperties.push({
1327
- basePath: basePath + propertyOptions.name,
1328
- data: option,
1329
- });
1330
- }
1331
- }
1241
+ }
1242
+ else if (nodeProperties.validateType) {
1243
+ const value = getParameterValueByPath(nodeValues, nodeProperties.name, path);
1244
+ const error = validateParameter(nodeProperties, value, nodeProperties.validateType);
1245
+ if (error) {
1246
+ if (foundIssues.parameters === undefined) {
1247
+ foundIssues.parameters = {};
1332
1248
  }
1249
+ if (foundIssues.parameters[nodeProperties.name] === undefined) {
1250
+ foundIssues.parameters[nodeProperties.name] = [];
1251
+ }
1252
+ foundIssues.parameters[nodeProperties.name].push(error);
1333
1253
  }
1334
- else {
1335
- // For all other types there is nothing to check so return
1336
- return foundIssues;
1337
- }
1338
- let propertyIssues;
1339
- for (const optionData of checkChildNodeProperties) {
1340
- propertyIssues = getParameterIssues(optionData.data, nodeValues, optionData.basePath, node, nodeTypeDescription);
1341
- mergeIssues(foundIssues, propertyIssues);
1342
- }
1254
+ }
1255
+ // Check if there are any child parameters
1256
+ if (nodeProperties.options === undefined) {
1257
+ // There are none so nothing else to check
1343
1258
  return foundIssues;
1344
1259
  }
1345
- /**
1346
- * Merges multiple NodeIssues together
1347
- *
1348
- * @param {INodeIssues} destination The issues to merge into
1349
- * @param {(INodeIssues | null)} source The issues to merge
1350
- */
1351
- function mergeIssues(destination, source) {
1352
- if (source === null) {
1353
- // Nothing to merge
1354
- return;
1355
- }
1356
- if (source.execution === true) {
1357
- destination.execution = true;
1358
- }
1359
- const objectProperties = ['parameters', 'credentials'];
1360
- let destinationProperty;
1361
- for (const propertyName of objectProperties) {
1362
- if (source[propertyName] !== undefined) {
1363
- if (destination[propertyName] === undefined) {
1364
- destination[propertyName] = {};
1365
- }
1366
- let parameterName;
1367
- for (parameterName of Object.keys(source[propertyName])) {
1368
- destinationProperty = destination[propertyName];
1369
- if (destinationProperty[parameterName] === undefined) {
1370
- destinationProperty[parameterName] = [];
1371
- }
1372
- destinationProperty[parameterName].push.apply(destinationProperty[parameterName], source[propertyName][parameterName]);
1373
- }
1374
- }
1375
- }
1376
- if (source.typeUnknown === true) {
1377
- destination.typeUnknown = true;
1260
+ // Check the child parameters
1261
+ // Important:
1262
+ // Checks the child properties only if the property is defined on current level.
1263
+ // That means that the required flag works only for the current level only. If
1264
+ // it is set on a lower level it means that the property is only required in case
1265
+ // the parent property got set.
1266
+ let basePath = path ? `${path}.` : '';
1267
+ const checkChildNodeProperties = [];
1268
+ // Collect all the properties to check
1269
+ if (nodeProperties.type === 'collection') {
1270
+ for (const option of nodeProperties.options) {
1271
+ checkChildNodeProperties.push({
1272
+ basePath,
1273
+ data: option,
1274
+ });
1378
1275
  }
1379
1276
  }
1380
- /**
1381
- * Merges the given node properties
1382
- */
1383
- function mergeNodeProperties(mainProperties, addProperties) {
1384
- let existingIndex;
1385
- for (const property of addProperties) {
1386
- if (property.doNotInherit)
1277
+ else if (nodeProperties.type === 'fixedCollection' && isDisplayed) {
1278
+ basePath = basePath ? `${basePath}.` : `${nodeProperties.name}.`;
1279
+ let propertyOptions;
1280
+ for (propertyOptions of nodeProperties.options) {
1281
+ // Check if the option got set and if not skip it
1282
+ const value = getParameterValueByPath(nodeValues, propertyOptions.name, basePath.slice(0, -1));
1283
+ // Validate allowed field counts
1284
+ const valueArray = Array.isArray(value) ? value : [];
1285
+ const { minRequiredFields, maxAllowedFields } = nodeProperties.typeOptions ?? {};
1286
+ let error = '';
1287
+ if (minRequiredFields && valueArray.length < minRequiredFields) {
1288
+ error = `At least ${minRequiredFields} ${minRequiredFields === 1 ? 'field is' : 'fields are'} required.`;
1289
+ }
1290
+ if (maxAllowedFields && valueArray.length > maxAllowedFields) {
1291
+ error = `At most ${maxAllowedFields} ${maxAllowedFields === 1 ? 'field is' : 'fields are'} allowed.`;
1292
+ }
1293
+ if (error) {
1294
+ foundIssues.parameters ??= {};
1295
+ foundIssues.parameters[nodeProperties.name] ??= [];
1296
+ foundIssues.parameters[nodeProperties.name].push(error);
1297
+ }
1298
+ if (value === undefined) {
1387
1299
  continue;
1388
- existingIndex = mainProperties.findIndex((element) => element.name === property.name);
1389
- if (existingIndex === -1) {
1390
- // Property does not exist yet, so add
1391
- mainProperties.push(property);
1300
+ }
1301
+ if (
1302
+ // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
1303
+ nodeProperties.typeOptions !== undefined &&
1304
+ nodeProperties.typeOptions.multipleValues !== undefined) {
1305
+ // Multiple can be set so will be an array of objects
1306
+ if (Array.isArray(value)) {
1307
+ for (let i = 0; i < value.length; i++) {
1308
+ for (const option of propertyOptions.values) {
1309
+ checkChildNodeProperties.push({
1310
+ basePath: `${basePath}${propertyOptions.name}[${i}]`,
1311
+ data: option,
1312
+ });
1313
+ }
1314
+ }
1315
+ }
1392
1316
  }
1393
1317
  else {
1394
- // Property exists already, so overwrite
1395
- mainProperties[existingIndex] = property;
1318
+ // Only one can be set so will be an object
1319
+ for (const option of propertyOptions.values) {
1320
+ checkChildNodeProperties.push({
1321
+ basePath: basePath + propertyOptions.name,
1322
+ data: option,
1323
+ });
1324
+ }
1396
1325
  }
1397
1326
  }
1398
1327
  }
1399
- function getVersionedNodeType(object, version) {
1400
- if ('nodeVersions' in object) {
1401
- return object.getNodeType(version);
1402
- }
1403
- return object;
1328
+ else {
1329
+ // For all other types there is nothing to check so return
1330
+ return foundIssues;
1404
1331
  }
1405
- function isTriggerNode(nodeTypeData) {
1406
- return nodeTypeData.group.includes('trigger');
1332
+ let propertyIssues;
1333
+ for (const optionData of checkChildNodeProperties) {
1334
+ propertyIssues = getParameterIssues(optionData.data, nodeValues, optionData.basePath, node, nodeTypeDescription);
1335
+ mergeIssues(foundIssues, propertyIssues);
1407
1336
  }
1408
- function isExecutable(workflow, node, nodeTypeData) {
1409
- if (!nodeTypeData) {
1410
- return false;
1411
- }
1412
- const outputs = getNodeOutputs(workflow, node, nodeTypeData);
1413
- const outputNames = getConnectionTypes(outputs);
1414
- return (outputNames.includes(interfaces_1.NodeConnectionTypes.Main) ||
1415
- outputNames.includes(interfaces_1.NodeConnectionTypes.AiTool) ||
1416
- isTriggerNode(nodeTypeData));
1417
- }
1418
- function isNodeWithWorkflowSelector(node) {
1419
- return [constants_1.EXECUTE_WORKFLOW_NODE_TYPE, constants_1.WORKFLOW_TOOL_LANGCHAIN_NODE_TYPE].includes(node.type);
1420
- }
1421
- /**
1422
- * @returns An object containing either the resolved operation's action if available,
1423
- * else the resource and operation if both exist.
1424
- * If neither can be resolved, returns an empty object.
1425
- */
1426
- function resolveResourceAndOperation(nodeParameters, nodeTypeDescription) {
1427
- if (nodeTypeDescription.name === 'n8n-nodes-base.code') {
1428
- const language = nodeParameters.language;
1429
- const langProp = nodeTypeDescription.properties.find((p) => p.name === 'language');
1430
- if (langProp?.options && (0, type_guards_1.isINodePropertyOptionsList)(langProp.options)) {
1431
- const found = langProp.options.find((o) => o.value === language);
1432
- if (found?.action)
1433
- return { action: found.action };
1337
+ return foundIssues;
1338
+ }
1339
+ /**
1340
+ * Merges multiple NodeIssues together
1341
+ *
1342
+ * @param {INodeIssues} destination The issues to merge into
1343
+ * @param {(INodeIssues | null)} source The issues to merge
1344
+ */
1345
+ function mergeIssues(destination, source) {
1346
+ if (source === null) {
1347
+ // Nothing to merge
1348
+ return;
1349
+ }
1350
+ if (source.execution === true) {
1351
+ destination.execution = true;
1352
+ }
1353
+ const objectProperties = ['parameters', 'credentials'];
1354
+ let destinationProperty;
1355
+ for (const propertyName of objectProperties) {
1356
+ if (source[propertyName] !== undefined) {
1357
+ if (destination[propertyName] === undefined) {
1358
+ destination[propertyName] = {};
1434
1359
  }
1435
- }
1436
- const resource = nodeParameters.resource;
1437
- const operation = nodeParameters.operation;
1438
- const nodeTypeOperation = nodeTypeDescription.properties.find((p) => p.name === 'operation' && p.displayOptions?.show?.resource?.includes(resource));
1439
- if (nodeTypeOperation?.options && (0, type_guards_1.isINodePropertyOptionsList)(nodeTypeOperation.options)) {
1440
- const foundOperation = nodeTypeOperation.options.find((option) => option.value === operation);
1441
- if (foundOperation?.action) {
1442
- return { action: foundOperation.action };
1360
+ let parameterName;
1361
+ for (parameterName of Object.keys(source[propertyName])) {
1362
+ destinationProperty = destination[propertyName];
1363
+ if (destinationProperty[parameterName] === undefined) {
1364
+ destinationProperty[parameterName] = [];
1365
+ }
1366
+ destinationProperty[parameterName].push.apply(destinationProperty[parameterName], source[propertyName][parameterName]);
1443
1367
  }
1444
1368
  }
1445
- if (resource && operation) {
1446
- return { operation, resource };
1369
+ }
1370
+ if (source.typeUnknown === true) {
1371
+ destination.typeUnknown = true;
1372
+ }
1373
+ }
1374
+ /**
1375
+ * Merges the given node properties
1376
+ */
1377
+ function mergeNodeProperties(mainProperties, addProperties) {
1378
+ let existingIndex;
1379
+ for (const property of addProperties) {
1380
+ if (property.doNotInherit)
1381
+ continue;
1382
+ existingIndex = mainProperties.findIndex((element) => element.name === property.name);
1383
+ if (existingIndex === -1) {
1384
+ // Property does not exist yet, so add
1385
+ mainProperties.push(property);
1447
1386
  }
1448
1387
  else {
1449
- return {};
1388
+ // Property exists already, so overwrite
1389
+ mainProperties[existingIndex] = property;
1450
1390
  }
1451
1391
  }
1452
- /**
1453
- * Generates a human-readable description for a node based on its parameters and type definition.
1454
- *
1455
- * This function creates a descriptive string that represents what the node does,
1456
- * based on its resource, operation, and node type information. The description is
1457
- * formatted in one of the following ways:
1458
- *
1459
- * 1. "{action} in {displayName}" if the operation has a defined action
1460
- * 2. "{operation} {resource} in {displayName}" if resource and operation exist
1461
- * 3. The node type's description field as a fallback
1462
- */
1463
- function makeDescription(nodeParameters, nodeTypeDescription) {
1464
- const { action, operation, resource } = resolveResourceAndOperation(nodeParameters, nodeTypeDescription);
1465
- if (action) {
1466
- return `${action} in ${nodeTypeDescription.defaults.name}`;
1392
+ }
1393
+ function getVersionedNodeType(object, version) {
1394
+ if ('nodeVersions' in object) {
1395
+ return object.getNodeType(version);
1396
+ }
1397
+ return object;
1398
+ }
1399
+ function isTriggerNode(nodeTypeData) {
1400
+ return nodeTypeData.group.includes('trigger');
1401
+ }
1402
+ function isExecutable(workflow, node, nodeTypeData) {
1403
+ if (!nodeTypeData) {
1404
+ return false;
1405
+ }
1406
+ const outputs = getNodeOutputs(workflow, node, nodeTypeData);
1407
+ const outputNames = getConnectionTypes(outputs);
1408
+ return (outputNames.includes(interfaces_1.NodeConnectionTypes.Main) ||
1409
+ outputNames.includes(interfaces_1.NodeConnectionTypes.AiTool) ||
1410
+ isTriggerNode(nodeTypeData));
1411
+ }
1412
+ function isNodeWithWorkflowSelector(node) {
1413
+ return [constants_1.EXECUTE_WORKFLOW_NODE_TYPE, constants_1.WORKFLOW_TOOL_LANGCHAIN_NODE_TYPE].includes(node.type);
1414
+ }
1415
+ /**
1416
+ * @returns An object containing either the resolved operation's action if available,
1417
+ * else the resource and operation if both exist.
1418
+ * If neither can be resolved, returns an empty object.
1419
+ */
1420
+ function resolveResourceAndOperation(nodeParameters, nodeTypeDescription) {
1421
+ if (nodeTypeDescription.name === 'n8n-nodes-base.code') {
1422
+ const language = nodeParameters.language;
1423
+ const langProp = nodeTypeDescription.properties.find((p) => p.name === 'language');
1424
+ if (langProp?.options && (0, type_guards_1.isINodePropertyOptionsList)(langProp.options)) {
1425
+ const found = langProp.options.find((o) => o.value === language);
1426
+ if (found?.action)
1427
+ return { action: found.action };
1467
1428
  }
1468
- if (resource && operation) {
1469
- return `${operation} ${resource} in ${nodeTypeDescription.defaults.name}`;
1429
+ }
1430
+ const resource = nodeParameters.resource;
1431
+ const operation = nodeParameters.operation;
1432
+ const nodeTypeOperation = nodeTypeDescription.properties.find((p) => p.name === 'operation' && p.displayOptions?.show?.resource?.includes(resource));
1433
+ if (nodeTypeOperation?.options && (0, type_guards_1.isINodePropertyOptionsList)(nodeTypeOperation.options)) {
1434
+ const foundOperation = nodeTypeOperation.options.find((option) => option.value === operation);
1435
+ if (foundOperation?.action) {
1436
+ return { action: foundOperation.action };
1470
1437
  }
1471
- return nodeTypeDescription.description;
1472
- }
1473
- /**
1474
- * Trigger node types that don't have "trigger" in their name
1475
- * but still function as workflow entry points
1476
- */
1477
- const TRIGGER_NODE_TYPES = new Set([
1478
- 'n8n-nodes-base.webhook',
1479
- 'n8n-nodes-base.cron', // Legacy schedule trigger
1480
- 'n8n-nodes-base.emailReadImap', // Email polling trigger
1481
- 'n8n-nodes-base.telegramBot', // Can act as webhook trigger
1482
- 'n8n-nodes-base.start', // Legacy trigger
1483
- ]);
1484
- /**
1485
- * Check if a node type is a trigger
1486
- */
1487
- function isTriggerNodeType(type) {
1488
- if (TRIGGER_NODE_TYPES.has(type)) {
1438
+ }
1439
+ if (resource && operation) {
1440
+ return { operation, resource };
1441
+ }
1442
+ else {
1443
+ return {};
1444
+ }
1445
+ }
1446
+ /**
1447
+ * Generates a human-readable description for a node based on its parameters and type definition.
1448
+ *
1449
+ * This function creates a descriptive string that represents what the node does,
1450
+ * based on its resource, operation, and node type information. The description is
1451
+ * formatted in one of the following ways:
1452
+ *
1453
+ * 1. "{action} in {displayName}" if the operation has a defined action
1454
+ * 2. "{operation} {resource} in {displayName}" if resource and operation exist
1455
+ * 3. The node type's description field as a fallback
1456
+ */
1457
+ function makeDescription(nodeParameters, nodeTypeDescription) {
1458
+ const { action, operation, resource } = resolveResourceAndOperation(nodeParameters, nodeTypeDescription);
1459
+ if (action) {
1460
+ return `${action} in ${nodeTypeDescription.defaults.name}`;
1461
+ }
1462
+ if (resource && operation) {
1463
+ return `${operation} ${resource} in ${nodeTypeDescription.defaults.name}`;
1464
+ }
1465
+ return nodeTypeDescription.description;
1466
+ }
1467
+ /**
1468
+ * Trigger node types that don't have "trigger" in their name
1469
+ * but still function as workflow entry points
1470
+ */
1471
+ const TRIGGER_NODE_TYPES = new Set([
1472
+ 'n8n-nodes-base.webhook',
1473
+ 'n8n-nodes-base.cron', // Legacy schedule trigger
1474
+ 'n8n-nodes-base.emailReadImap', // Email polling trigger
1475
+ 'n8n-nodes-base.telegramBot', // Can act as webhook trigger
1476
+ 'n8n-nodes-base.start', // Legacy trigger
1477
+ ]);
1478
+ /**
1479
+ * Check if a node type is a trigger
1480
+ */
1481
+ function isTriggerNodeType(type) {
1482
+ if (TRIGGER_NODE_TYPES.has(type)) {
1483
+ return true;
1484
+ }
1485
+ return type.toLowerCase().includes('trigger');
1486
+ }
1487
+ function isToolType(nodeType, { includeHitl = true } = {}) {
1488
+ if (!nodeType)
1489
+ return false;
1490
+ const node = nodeType.split('.').pop();
1491
+ if (node?.endsWith('Tool') || node?.startsWith('tool')) {
1492
+ // don't check if it's hitl
1493
+ if (includeHitl) {
1489
1494
  return true;
1490
1495
  }
1491
- return type.toLowerCase().includes('trigger');
1492
- }
1493
- function isToolType(nodeType, { includeHitl = true } = {}) {
1494
- if (!nodeType)
1495
- return false;
1496
- const node = nodeType.split('.').pop();
1497
- if (node?.endsWith('Tool') || node?.startsWith('tool')) {
1498
- // don't check if it's hitl
1499
- if (includeHitl) {
1500
- return true;
1501
- }
1502
- return !isHitlToolType(nodeType);
1503
- }
1504
- return false;
1496
+ return !isHitlToolType(nodeType);
1505
1497
  }
1506
- function isHitlToolType(nodeType) {
1507
- if (!nodeType)
1508
- return false;
1509
- return nodeType.endsWith('HitlTool');
1498
+ return false;
1499
+ }
1500
+ function isHitlToolType(nodeType) {
1501
+ if (!nodeType)
1502
+ return false;
1503
+ return nodeType.endsWith('HitlTool');
1504
+ }
1505
+ function isTool(nodeTypeDescription, parameters) {
1506
+ // Check if node is a vector store in retrieve-as-tool mode
1507
+ if (nodeTypeDescription.name.includes('vectorStore')) {
1508
+ const mode = parameters.mode;
1509
+ return mode === 'retrieve-as-tool';
1510
1510
  }
1511
- function isTool(nodeTypeDescription, parameters) {
1512
- // Check if node is a vector store in retrieve-as-tool mode
1513
- if (nodeTypeDescription.name.includes('vectorStore')) {
1514
- const mode = parameters.mode;
1515
- return mode === 'retrieve-as-tool';
1516
- }
1517
- // Check for other tool nodes
1518
- if (Array.isArray(nodeTypeDescription.outputs)) {
1519
- // Handle static outputs (array case)
1520
- for (const output of nodeTypeDescription.outputs) {
1521
- if (typeof output === 'string') {
1522
- return output === interfaces_1.NodeConnectionTypes.AiTool;
1523
- }
1524
- else if (output?.type && output.type === interfaces_1.NodeConnectionTypes.AiTool) {
1525
- return true;
1526
- }
1511
+ // Check for other tool nodes
1512
+ if (Array.isArray(nodeTypeDescription.outputs)) {
1513
+ // Handle static outputs (array case)
1514
+ for (const output of nodeTypeDescription.outputs) {
1515
+ if (typeof output === 'string') {
1516
+ return output === interfaces_1.NodeConnectionTypes.AiTool;
1517
+ }
1518
+ else if (output?.type && output.type === interfaces_1.NodeConnectionTypes.AiTool) {
1519
+ return true;
1527
1520
  }
1528
1521
  }
1529
- return false;
1530
1522
  }
1531
- /**
1532
- * Generates a resource and operation aware node name.
1533
- *
1534
- * Appends `in {nodeTypeDisplayName}` if nodeType is a tool
1535
- *
1536
- * 1. "{action}" if the operation has a defined action
1537
- * 2. "{operation} {resource}" if resource and operation exist
1538
- * 3. The node type's defaults.name field or displayName as a fallback
1539
- */
1540
- function makeNodeName(nodeParameters, nodeTypeDescription) {
1541
- // If skipNameGeneration is set, skip resource/operation resolution
1542
- if (nodeTypeDescription.skipNameGeneration) {
1543
- return nodeTypeDescription.defaults.name ?? nodeTypeDescription.displayName;
1544
- }
1545
- const { action, operation, resource } = resolveResourceAndOperation(nodeParameters, nodeTypeDescription);
1546
- const postfix = isTool(nodeTypeDescription, nodeParameters)
1547
- ? ` in ${nodeTypeDescription.defaults.name}`
1548
- : '';
1549
- if (action) {
1550
- return `${action}${postfix}`;
1551
- }
1552
- if (resource && operation) {
1553
- const operationProper = operation[0].toUpperCase() + operation.slice(1);
1554
- return `${operationProper} ${resource}${postfix}`;
1555
- }
1523
+ return false;
1524
+ }
1525
+ /**
1526
+ * Generates a resource and operation aware node name.
1527
+ *
1528
+ * Appends `in {nodeTypeDisplayName}` if nodeType is a tool
1529
+ *
1530
+ * 1. "{action}" if the operation has a defined action
1531
+ * 2. "{operation} {resource}" if resource and operation exist
1532
+ * 3. The node type's defaults.name field or displayName as a fallback
1533
+ */
1534
+ function makeNodeName(nodeParameters, nodeTypeDescription) {
1535
+ // If skipNameGeneration is set, skip resource/operation resolution
1536
+ if (nodeTypeDescription.skipNameGeneration) {
1556
1537
  return nodeTypeDescription.defaults.name ?? nodeTypeDescription.displayName;
1557
1538
  }
1558
- /**
1559
- * Returns true if the node name is of format `<defaultNodeName>\d*` , which includes auto-renamed nodes
1560
- */
1561
- function isDefaultNodeName(name, nodeType, parameters) {
1562
- const currentDefaultName = makeNodeName(parameters, nodeType);
1563
- return name.startsWith(currentDefaultName) && /^\d*$/.test(name.slice(currentDefaultName.length));
1564
- }
1565
- /**
1566
- * Determines whether a tool description should be updated and returns the new description if needed.
1567
- * Returns undefined if no update is needed.
1568
- */
1569
- const getUpdatedToolDescription = (currentNodeType, newParameters, currentParameters) => {
1570
- if (!currentNodeType)
1571
- return;
1572
- if (newParameters?.descriptionType === 'manual' && currentParameters) {
1573
- const previousDescription = makeDescription(currentParameters, currentNodeType);
1574
- const newDescription = makeDescription(newParameters, currentNodeType);
1575
- if (newParameters.toolDescription === previousDescription ||
1576
- !newParameters.toolDescription?.toString().trim() ||
1577
- newParameters.toolDescription === currentNodeType.description) {
1578
- return newDescription;
1579
- }
1580
- }
1539
+ const { action, operation, resource } = resolveResourceAndOperation(nodeParameters, nodeTypeDescription);
1540
+ const postfix = isTool(nodeTypeDescription, nodeParameters)
1541
+ ? ` in ${nodeTypeDescription.defaults.name}`
1542
+ : '';
1543
+ if (action) {
1544
+ return `${action}${postfix}`;
1545
+ }
1546
+ if (resource && operation) {
1547
+ const operationProper = operation[0].toUpperCase() + operation.slice(1);
1548
+ return `${operationProper} ${resource}${postfix}`;
1549
+ }
1550
+ return nodeTypeDescription.defaults.name ?? nodeTypeDescription.displayName;
1551
+ }
1552
+ /**
1553
+ * Returns true if the node name is of format `<defaultNodeName>\d*` , which includes auto-renamed nodes
1554
+ */
1555
+ function isDefaultNodeName(name, nodeType, parameters) {
1556
+ const currentDefaultName = makeNodeName(parameters, nodeType);
1557
+ return name.startsWith(currentDefaultName) && /^\d*$/.test(name.slice(currentDefaultName.length));
1558
+ }
1559
+ /**
1560
+ * Determines whether a tool description should be updated and returns the new description if needed.
1561
+ * Returns undefined if no update is needed.
1562
+ */
1563
+ const getUpdatedToolDescription = (currentNodeType, newParameters, currentParameters) => {
1564
+ if (!currentNodeType)
1581
1565
  return;
1582
- };
1583
- exports.getUpdatedToolDescription = getUpdatedToolDescription;
1584
- /**
1585
- * Generates a tool description for a given node based on its parameters and type.
1586
- *
1587
- * When the user-provided `toolDescription` is an n8n expression (starts with `=`),
1588
- * the optional `resolveToolDescription` callback is used to evaluate it against
1589
- * the upstream input data — matching how other tool nodes (e.g. `toolWorkflow`)
1590
- * resolve their description parameter via `getNodeParameter`. Without a resolver,
1591
- * the raw value is returned unchanged for backward compatibility.
1592
- */
1593
- function getToolDescriptionForNode(node, nodeType, resolveToolDescription) {
1594
- let toolDescription;
1595
- if (node.parameters.descriptionType === 'auto' ||
1596
- !node?.parameters.toolDescription?.toString().trim()) {
1597
- toolDescription = makeDescription(node.parameters, nodeType.description);
1566
+ if (newParameters?.descriptionType === 'manual' && currentParameters) {
1567
+ const previousDescription = makeDescription(currentParameters, currentNodeType);
1568
+ const newDescription = makeDescription(newParameters, currentNodeType);
1569
+ if (newParameters.toolDescription === previousDescription ||
1570
+ !newParameters.toolDescription?.toString().trim() ||
1571
+ newParameters.toolDescription === currentNodeType.description) {
1572
+ return newDescription;
1598
1573
  }
1599
- else if (node?.parameters.toolDescription) {
1600
- const raw = node.parameters.toolDescription;
1601
- if (resolveToolDescription && typeof raw === 'string' && raw.startsWith('=')) {
1602
- toolDescription = resolveToolDescription();
1603
- }
1604
- else {
1605
- toolDescription = raw;
1606
- }
1574
+ }
1575
+ return;
1576
+ };
1577
+ exports.getUpdatedToolDescription = getUpdatedToolDescription;
1578
+ /**
1579
+ * Generates a tool description for a given node based on its parameters and type.
1580
+ *
1581
+ * When the user-provided `toolDescription` is an n8n expression (starts with `=`),
1582
+ * the optional `resolveToolDescription` callback is used to evaluate it against
1583
+ * the upstream input data — matching how other tool nodes (e.g. `toolWorkflow`)
1584
+ * resolve their description parameter via `getNodeParameter`. Without a resolver,
1585
+ * the raw value is returned unchanged for backward compatibility.
1586
+ */
1587
+ function getToolDescriptionForNode(node, nodeType, resolveToolDescription) {
1588
+ let toolDescription;
1589
+ if (node.parameters.descriptionType === 'auto' ||
1590
+ !node?.parameters.toolDescription?.toString().trim()) {
1591
+ toolDescription = makeDescription(node.parameters, nodeType.description);
1592
+ }
1593
+ else if (node?.parameters.toolDescription) {
1594
+ const raw = node.parameters.toolDescription;
1595
+ if (resolveToolDescription && typeof raw === 'string' && raw.startsWith('=')) {
1596
+ toolDescription = resolveToolDescription();
1607
1597
  }
1608
1598
  else {
1609
- toolDescription = nodeType.description.description;
1610
- }
1611
- return toolDescription;
1612
- }
1613
- /**
1614
- * Attempts to retrieve the ID of a subworkflow from a execute workflow node.
1615
- */
1616
- function getSubworkflowId(node) {
1617
- if (isNodeWithWorkflowSelector(node) && (0, type_guards_1.isResourceLocatorValue)(node.parameters.workflowId)) {
1618
- return node.parameters.workflowId.value;
1599
+ toolDescription = raw;
1619
1600
  }
1620
- return;
1621
1601
  }
1622
- /**
1623
- * Check if a node type accepts a specific input connection type
1624
- * @param nodeType - The node type description
1625
- * @param connectionType - The connection type to check (e.g., 'main', 'ai_tool')
1626
- * @returns True if the node accepts the input type
1627
- */
1628
- function nodeAcceptsInputType(nodeType, connectionType) {
1629
- // Handle string-based inputs (expression or simple string)
1630
- if (typeof nodeType.inputs === 'string') {
1631
- return nodeType.inputs === connectionType || nodeType.inputs.includes(connectionType);
1632
- }
1633
- // Handle array-based inputs
1634
- if (!nodeType.inputs || !Array.isArray(nodeType.inputs)) {
1635
- return false;
1636
- }
1637
- return nodeType.inputs.some((input) => {
1638
- if (typeof input === 'string') {
1639
- return input === connectionType || input.includes(connectionType);
1640
- }
1641
- return input.type === connectionType;
1642
- });
1602
+ else {
1603
+ toolDescription = nodeType.description.description;
1643
1604
  }
1644
- /**
1645
- * Check if a node type has a specific output connection type
1646
- * @param nodeType - The node type description
1647
- * @param connectionType - The connection type to check (e.g., 'main', 'ai_tool')
1648
- * @returns True if the node supports the output type
1649
- */
1650
- function nodeHasOutputType(nodeType, connectionType) {
1651
- // Handle string-based outputs (expression or simple string)
1652
- if (typeof nodeType.outputs === 'string') {
1653
- return nodeType.outputs === connectionType || nodeType.outputs.includes(connectionType);
1654
- }
1655
- // Handle array-based outputs
1656
- if (!nodeType.outputs || !Array.isArray(nodeType.outputs)) {
1657
- return false;
1658
- }
1659
- return nodeType.outputs.some((output) => {
1660
- if (typeof output === 'string') {
1661
- return output === connectionType || output.includes(connectionType);
1662
- }
1663
- return output.type === connectionType;
1664
- });
1605
+ return toolDescription;
1606
+ }
1607
+ /**
1608
+ * Attempts to retrieve the ID of a subworkflow from a execute workflow node.
1609
+ */
1610
+ function getSubworkflowId(node) {
1611
+ if (isNodeWithWorkflowSelector(node) && (0, type_guards_1.isResourceLocatorValue)(node.parameters.workflowId)) {
1612
+ return node.parameters.workflowId.value;
1613
+ }
1614
+ return;
1615
+ }
1616
+ /**
1617
+ * Check if a node type accepts a specific input connection type
1618
+ * @param nodeType - The node type description
1619
+ * @param connectionType - The connection type to check (e.g., 'main', 'ai_tool')
1620
+ * @returns True if the node accepts the input type
1621
+ */
1622
+ function nodeAcceptsInputType(nodeType, connectionType) {
1623
+ // Handle string-based inputs (expression or simple string)
1624
+ if (typeof nodeType.inputs === 'string') {
1625
+ return nodeType.inputs === connectionType || nodeType.inputs.includes(connectionType);
1665
1626
  }
1666
- });
1627
+ // Handle array-based inputs
1628
+ if (!nodeType.inputs || !Array.isArray(nodeType.inputs)) {
1629
+ return false;
1630
+ }
1631
+ return nodeType.inputs.some((input) => {
1632
+ if (typeof input === 'string') {
1633
+ return input === connectionType || input.includes(connectionType);
1634
+ }
1635
+ return input.type === connectionType;
1636
+ });
1637
+ }
1638
+ /**
1639
+ * Check if a node type has a specific output connection type
1640
+ * @param nodeType - The node type description
1641
+ * @param connectionType - The connection type to check (e.g., 'main', 'ai_tool')
1642
+ * @returns True if the node supports the output type
1643
+ */
1644
+ function nodeHasOutputType(nodeType, connectionType) {
1645
+ // Handle string-based outputs (expression or simple string)
1646
+ if (typeof nodeType.outputs === 'string') {
1647
+ return nodeType.outputs === connectionType || nodeType.outputs.includes(connectionType);
1648
+ }
1649
+ // Handle array-based outputs
1650
+ if (!nodeType.outputs || !Array.isArray(nodeType.outputs)) {
1651
+ return false;
1652
+ }
1653
+ return nodeType.outputs.some((output) => {
1654
+ if (typeof output === 'string') {
1655
+ return output === connectionType || output.includes(connectionType);
1656
+ }
1657
+ return output.type === connectionType;
1658
+ });
1659
+ }
1667
1660
  //# sourceMappingURL=node-helpers.js.map