@oomol-lab/open-flow 0.1.0-beta.73 → 0.1.0-beta.74

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 (432) hide show
  1. package/LICENSE +36 -0
  2. package/NOTICE +7 -0
  3. package/README.md +40 -0
  4. package/dist/browser/{createResourceDialog-BWJkjiOO.js → createResourceDialog-DI9pL-Yr.js} +2 -2
  5. package/dist/browser/{dialog-CUy_fwx9.js → dialog-BYJGvItc.js} +54 -19
  6. package/dist/browser/{flowChanges-CgSnSqqP.js → flowChanges-RL-H4CjD.js} +306 -48
  7. package/dist/browser/{flowWorkspace-Bf7H-r0t.js → flowWorkspace-BkDsETj0.js} +20745 -20186
  8. package/dist/browser/preview.css +73 -3
  9. package/dist/browser/preview.js +21410 -20607
  10. package/dist/browser/{typeScriptSession-B0hC-C8y.js → typeScriptSession-CSRwWmZm.js} +1 -1
  11. package/dist/browser/ui.css +72 -2
  12. package/dist/browser/workbench.css +73 -3
  13. package/dist/browser/workbench.js +14 -76
  14. package/dist/browser/{workbenchSelect-C3e4J93X.js → workbenchSelect-BcWPWGzw.js} +1 -1
  15. package/dist/command/index.js +34 -34
  16. package/dist/common/authoring.d.ts +1 -1
  17. package/dist/common/authoringFields.d.ts +1 -1
  18. package/dist/common/authoringSchema.d.ts +28 -4
  19. package/dist/common/connector-proxy.d.ts +1 -1
  20. package/dist/common/control-api-conformance.d.ts +1 -1
  21. package/dist/common/control-api-conformance.js +61 -24
  22. package/dist/common/control-api.d.ts +4 -3
  23. package/dist/common/control-api.js +59 -22
  24. package/dist/common/control-requests.d.ts +2 -1
  25. package/dist/common/control-requests.js +204 -42
  26. package/dist/common/cron-trigger.d.ts +1 -1
  27. package/dist/common/decision.d.ts +1 -1
  28. package/dist/common/draftOperations.d.ts +1 -1
  29. package/dist/common/engine-contract.d.ts +3 -2
  30. package/dist/common/event-source-definition.d.ts +1 -1
  31. package/dist/common/flow-agent.d.ts +1 -1
  32. package/dist/{browser → common}/flow-authoring-node.d.ts +3 -3
  33. package/dist/{browser → common}/flow-authoring.js +75 -23
  34. package/dist/{browser → common}/flow-change-schema.d.ts +177 -6
  35. package/dist/{browser → common}/flow-change.d.ts +35 -15
  36. package/dist/{browser → common}/flow-change.js +77 -25
  37. package/dist/common/flow-connectionUsage.d.ts +1 -1
  38. package/dist/common/flow-encoding.d.ts +1 -1
  39. package/dist/common/flow-encoding.js +34 -16
  40. package/dist/common/flow-errorHandling.d.ts +1 -1
  41. package/dist/common/flow-graph.d.ts +1 -1
  42. package/dist/common/flow-modules.d.ts +1 -1
  43. package/dist/common/flow-promptTemplate.d.ts +1 -1
  44. package/dist/common/flow-retry.d.ts +1 -1
  45. package/dist/common/flow-semantics.d.ts +1 -1
  46. package/dist/common/flow-semantics.js +151 -32
  47. package/dist/common/flow-workflowFile.d.ts +1 -1
  48. package/dist/common/flowInspection.d.ts +3 -3
  49. package/dist/common/integration-trigger.d.ts +1 -1
  50. package/dist/common/licenses.md +118 -1
  51. package/dist/common/liveDetails.d.ts +1 -1
  52. package/dist/common/mcp.d.ts +2 -1
  53. package/dist/common/mcp.js +59 -22
  54. package/dist/common/openapi.d.ts +1 -1
  55. package/dist/common/poll-trigger.d.ts +1 -1
  56. package/dist/common/run-results.d.ts +8 -1
  57. package/dist/common/runtime-contract.d.ts +8 -2
  58. package/dist/common/runtime-contract.js +22 -5
  59. package/dist/common/scheduler-checkpoint.d.ts +1 -1
  60. package/dist/common/scheduler-dependencies.d.ts +1 -1
  61. package/dist/common/scheduler-node-execution.d.ts +1 -1
  62. package/dist/common/scheduler.d.ts +2 -2
  63. package/dist/common/scheduler.js +31 -12
  64. package/dist/common/trigger-catalog.d.ts +1 -1
  65. package/dist/common/trigger-config-options.d.ts +1 -1
  66. package/dist/common/trigger-config.d.ts +1 -1
  67. package/dist/common/trigger-contract.d.ts +2 -2
  68. package/dist/common/trigger-localization.d.ts +1 -1
  69. package/dist/common/webhook-response.d.ts +1 -1
  70. package/dist/common/webhook-trigger.d.ts +1 -1
  71. package/dist/common/workflow.d.ts +17 -1
  72. package/dist/common/workflow.js +68 -22
  73. package/dist/index.d.ts +6 -3
  74. package/package.json +7 -6
  75. package/src/base/common/json.ts +90 -0
  76. package/src/canvas/common/commands.ts +15 -0
  77. package/src/connector/common/actionSchema.ts +168 -0
  78. package/src/connector/common/proxy.ts +44 -0
  79. package/src/control/common/api.ts +1505 -0
  80. package/src/control/common/authoring.ts +912 -0
  81. package/src/control/common/authoringCondition.ts +110 -0
  82. package/src/control/common/authoringDiagnosticFields.ts +136 -0
  83. package/src/control/common/authoringExamples.ts +192 -0
  84. package/src/control/common/authoringFields.ts +53 -0
  85. package/src/control/common/authoringLlm.ts +70 -0
  86. package/src/control/common/authoringOpenApi.ts +129 -0
  87. package/src/control/common/authoringSchema.ts +404 -0
  88. package/src/control/common/authoringTools.ts +123 -0
  89. package/src/control/common/authoringTriggers.ts +26 -0
  90. package/src/control/common/checkDecoders.ts +65 -0
  91. package/src/control/common/conformance.ts +1989 -0
  92. package/src/control/common/connectorDecoders.ts +370 -0
  93. package/src/control/common/connectorQueries.ts +61 -0
  94. package/src/control/common/decoding.ts +60 -0
  95. package/src/control/common/draftOperations.ts +61 -0
  96. package/src/control/common/errors.ts +114 -0
  97. package/src/control/common/eventSourceSchemas.ts +13 -0
  98. package/src/control/common/eventSources.ts +186 -0
  99. package/src/control/common/flowDecoders.ts +153 -0
  100. package/src/control/common/flowInspection.ts +181 -0
  101. package/src/control/common/flowNotifications.ts +37 -0
  102. package/src/control/common/liveDetails.ts +124 -0
  103. package/src/control/common/mcp.ts +241 -0
  104. package/src/control/common/mcpConformance.ts +142 -0
  105. package/src/control/common/providerAccess.ts +28 -0
  106. package/src/control/common/providerIconSprite.ts +42 -0
  107. package/src/control/common/publicationDecoders.ts +98 -0
  108. package/src/control/common/random.ts +16 -0
  109. package/src/control/common/requests.ts +112 -0
  110. package/src/control/common/resultQuery.ts +8 -0
  111. package/src/control/common/results.ts +176 -0
  112. package/src/control/common/revisionDecoders.ts +52 -0
  113. package/src/control/common/runDecoders.ts +240 -0
  114. package/src/control/common/triggerCatalog.ts +89 -0
  115. package/src/control/common/triggerDecoders.ts +175 -0
  116. package/src/decision/common/decision.ts +168 -0
  117. package/src/event-source/common/catalog.generated.json +65 -0
  118. package/src/event-source/common/definition.ts +66 -0
  119. package/src/event-source/common/index.ts +99 -0
  120. package/src/execution/common/checkpoint.ts +311 -0
  121. package/src/execution/common/dependencies.ts +440 -0
  122. package/src/execution/common/engineContract.ts +80 -0
  123. package/src/execution/common/events.ts +328 -0
  124. package/src/execution/common/node-execution.ts +467 -0
  125. package/src/execution/common/runLifecycle.ts +250 -0
  126. package/src/execution/common/runtime.ts +563 -0
  127. package/src/execution/common/scheduler.ts +696 -0
  128. package/src/execution/common/wait.ts +36 -0
  129. package/src/flow/common/agent.ts +305 -0
  130. package/src/flow/common/authoring.ts +30 -0
  131. package/src/flow/common/change.ts +1036 -0
  132. package/src/flow/common/changeSchema.ts +783 -0
  133. package/src/flow/common/codePermissions.ts +2 -0
  134. package/src/flow/common/condition.ts +265 -0
  135. package/src/flow/common/connectionUsage.ts +131 -0
  136. package/src/flow/common/edgeChanges.ts +35 -0
  137. package/src/flow/common/encoding.ts +437 -0
  138. package/src/flow/common/errorHandling.ts +34 -0
  139. package/src/flow/common/graph.ts +892 -0
  140. package/src/flow/common/inputValue.ts +16 -0
  141. package/src/flow/common/json.ts +8 -0
  142. package/src/flow/common/moduleChanges.ts +31 -0
  143. package/src/flow/common/modules.ts +292 -0
  144. package/src/flow/common/nodeChanges.ts +762 -0
  145. package/src/flow/common/portChanges.ts +36 -0
  146. package/src/flow/common/promptTemplate.ts +15 -0
  147. package/src/flow/common/retry.ts +20 -0
  148. package/src/flow/common/schema.ts +162 -0
  149. package/src/flow/common/schemaCompare.ts +176 -0
  150. package/src/flow/common/schemaComparer.ts +178 -0
  151. package/src/flow/common/schemaKeywords.ts +53 -0
  152. package/src/flow/common/semantics.ts +474 -0
  153. package/src/flow/common/sourceField.ts +35 -0
  154. package/src/flow/common/triggerScheduleSchema.ts +8 -0
  155. package/src/flow/common/wait.ts +30 -0
  156. package/src/flow/common/webhookMethod.ts +7 -0
  157. package/src/flow/common/webhookResponse.ts +75 -0
  158. package/src/flow/common/workflowFile.ts +97 -0
  159. package/src/json-schema-subset/checker/array.ts +142 -0
  160. package/src/json-schema-subset/checker/cache.ts +57 -0
  161. package/src/json-schema-subset/checker/checker.ts +230 -0
  162. package/src/json-schema-subset/checker/enumAndConst.ts +113 -0
  163. package/src/json-schema-subset/checker/equals.ts +93 -0
  164. package/src/json-schema-subset/checker/numeric/checker.ts +50 -0
  165. package/src/json-schema-subset/checker/numeric/float.ts +121 -0
  166. package/src/json-schema-subset/checker/numeric/index.ts +1 -0
  167. package/src/json-schema-subset/checker/numeric/integer.ts +119 -0
  168. package/src/json-schema-subset/checker/numeric/integerNormalizer.ts +72 -0
  169. package/src/json-schema-subset/checker/object.ts +354 -0
  170. package/src/json-schema-subset/checker/range.ts +91 -0
  171. package/src/json-schema-subset/checker/string.ts +60 -0
  172. package/src/json-schema-subset/checker/tools/index.ts +3 -0
  173. package/src/json-schema-subset/checker/tools/mark.ts +82 -0
  174. package/src/json-schema-subset/checker/tools/quantum.ts +106 -0
  175. package/src/json-schema-subset/checker/tools/range.ts +210 -0
  176. package/src/json-schema-subset/checker/validator.ts +23 -0
  177. package/src/json-schema-subset/compiler/array.ts +163 -0
  178. package/src/json-schema-subset/compiler/combination.ts +109 -0
  179. package/src/json-schema-subset/compiler/common.ts +99 -0
  180. package/src/json-schema-subset/compiler/compiler.ts +188 -0
  181. package/src/json-schema-subset/compiler/enumAndConst.ts +75 -0
  182. package/src/json-schema-subset/compiler/index.ts +11 -0
  183. package/src/json-schema-subset/compiler/object.ts +411 -0
  184. package/src/json-schema-subset/compiler/primitive.ts +144 -0
  185. package/src/json-schema-subset/compiler/utils.ts +24 -0
  186. package/src/json-schema-subset/compiler/wrapper.ts +192 -0
  187. package/src/json-schema-subset/error.ts +55 -0
  188. package/src/json-schema-subset/expression/calculator.ts +442 -0
  189. package/src/json-schema-subset/expression/combination.ts +49 -0
  190. package/src/json-schema-subset/expression/expression.ts +191 -0
  191. package/src/json-schema-subset/expression/index.ts +25 -0
  192. package/src/json-schema-subset/expression/result.ts +88 -0
  193. package/src/json-schema-subset/expression/types.ts +36 -0
  194. package/src/json-schema-subset/extends/extendsContext.ts +89 -0
  195. package/src/json-schema-subset/extends/index.ts +2 -0
  196. package/src/json-schema-subset/extends/types.ts +12 -0
  197. package/src/json-schema-subset/global.ts +60 -0
  198. package/src/json-schema-subset/index.ts +8 -0
  199. package/src/json-schema-subset/preprocessing.ts +74 -0
  200. package/src/json-schema-subset/types.ts +8 -0
  201. package/src/json-schema-subset/utils.ts +95 -0
  202. package/src/localization/common/languages.ts +118 -0
  203. package/src/localization/common/timeZone.ts +25 -0
  204. package/src/openapi/common/authBindings.ts +12 -0
  205. package/src/openapi/common/openapi.ts +459 -0
  206. package/src/trigger/common/config.ts +56 -0
  207. package/src/trigger/common/configOptions.ts +15 -0
  208. package/src/trigger/common/configSchema.ts +8 -0
  209. package/src/trigger/common/contract.ts +132 -0
  210. package/src/trigger/common/cron.ts +151 -0
  211. package/src/trigger/common/integration.ts +498 -0
  212. package/src/trigger/common/poll.ts +187 -0
  213. package/src/trigger/common/webhook.ts +412 -0
  214. package/src/trigger/providers/airtable/locales/fr.json +18 -0
  215. package/src/trigger/providers/airtable/locales/ja.json +18 -0
  216. package/src/trigger/providers/airtable/locales/ko.json +18 -0
  217. package/src/trigger/providers/airtable/locales/ru.json +18 -0
  218. package/src/trigger/providers/airtable/locales/zh-CN.json +18 -0
  219. package/src/trigger/providers/airtable/locales/zh-TW.json +18 -0
  220. package/src/trigger/providers/asana/locales/fr.json +15 -0
  221. package/src/trigger/providers/asana/locales/ja.json +15 -0
  222. package/src/trigger/providers/asana/locales/ko.json +15 -0
  223. package/src/trigger/providers/asana/locales/ru.json +15 -0
  224. package/src/trigger/providers/asana/locales/zh-CN.json +15 -0
  225. package/src/trigger/providers/asana/locales/zh-TW.json +15 -0
  226. package/src/trigger/providers/calendly/locales/fr.json +16 -0
  227. package/src/trigger/providers/calendly/locales/ja.json +16 -0
  228. package/src/trigger/providers/calendly/locales/ko.json +16 -0
  229. package/src/trigger/providers/calendly/locales/ru.json +16 -0
  230. package/src/trigger/providers/calendly/locales/zh-CN.json +16 -0
  231. package/src/trigger/providers/calendly/locales/zh-TW.json +16 -0
  232. package/src/trigger/providers/catalog.generated.json +4996 -0
  233. package/src/trigger/providers/clickup/locales/fr.json +16 -0
  234. package/src/trigger/providers/clickup/locales/ja.json +16 -0
  235. package/src/trigger/providers/clickup/locales/ko.json +16 -0
  236. package/src/trigger/providers/clickup/locales/ru.json +16 -0
  237. package/src/trigger/providers/clickup/locales/zh-CN.json +16 -0
  238. package/src/trigger/providers/clickup/locales/zh-TW.json +16 -0
  239. package/src/trigger/providers/definitions.ts +19 -0
  240. package/src/trigger/providers/feishu/locales/fr.json +20 -0
  241. package/src/trigger/providers/feishu/locales/ja.json +20 -0
  242. package/src/trigger/providers/feishu/locales/ko.json +20 -0
  243. package/src/trigger/providers/feishu/locales/ru.json +20 -0
  244. package/src/trigger/providers/feishu/locales/zh-CN.json +20 -0
  245. package/src/trigger/providers/feishu/locales/zh-TW.json +20 -0
  246. package/src/trigger/providers/fieldDescriptions.ts +392 -0
  247. package/src/trigger/providers/fieldLabels.ts +256 -0
  248. package/src/trigger/providers/fireflies/locales/fr.json +17 -0
  249. package/src/trigger/providers/fireflies/locales/ja.json +17 -0
  250. package/src/trigger/providers/fireflies/locales/ko.json +17 -0
  251. package/src/trigger/providers/fireflies/locales/ru.json +17 -0
  252. package/src/trigger/providers/fireflies/locales/zh-CN.json +17 -0
  253. package/src/trigger/providers/fireflies/locales/zh-TW.json +17 -0
  254. package/src/trigger/providers/github/locales/fr.json +30 -0
  255. package/src/trigger/providers/github/locales/ja.json +30 -0
  256. package/src/trigger/providers/github/locales/ko.json +30 -0
  257. package/src/trigger/providers/github/locales/ru.json +30 -0
  258. package/src/trigger/providers/github/locales/zh-CN.json +30 -0
  259. package/src/trigger/providers/github/locales/zh-TW.json +30 -0
  260. package/src/trigger/providers/gitlab/locales/fr.json +18 -0
  261. package/src/trigger/providers/gitlab/locales/ja.json +18 -0
  262. package/src/trigger/providers/gitlab/locales/ko.json +18 -0
  263. package/src/trigger/providers/gitlab/locales/ru.json +18 -0
  264. package/src/trigger/providers/gitlab/locales/zh-CN.json +18 -0
  265. package/src/trigger/providers/gitlab/locales/zh-TW.json +18 -0
  266. package/src/trigger/providers/gmail/locales/fr.json +18 -0
  267. package/src/trigger/providers/gmail/locales/ja.json +18 -0
  268. package/src/trigger/providers/gmail/locales/ko.json +18 -0
  269. package/src/trigger/providers/gmail/locales/ru.json +18 -0
  270. package/src/trigger/providers/gmail/locales/zh-CN.json +18 -0
  271. package/src/trigger/providers/gmail/locales/zh-TW.json +18 -0
  272. package/src/trigger/providers/google-calendar/locales/fr.json +15 -0
  273. package/src/trigger/providers/google-calendar/locales/ja.json +15 -0
  274. package/src/trigger/providers/google-calendar/locales/ko.json +15 -0
  275. package/src/trigger/providers/google-calendar/locales/ru.json +15 -0
  276. package/src/trigger/providers/google-calendar/locales/zh-CN.json +15 -0
  277. package/src/trigger/providers/google-calendar/locales/zh-TW.json +15 -0
  278. package/src/trigger/providers/google-drive/locales/fr.json +48 -0
  279. package/src/trigger/providers/google-drive/locales/ja.json +48 -0
  280. package/src/trigger/providers/google-drive/locales/ko.json +48 -0
  281. package/src/trigger/providers/google-drive/locales/ru.json +48 -0
  282. package/src/trigger/providers/google-drive/locales/zh-CN.json +48 -0
  283. package/src/trigger/providers/google-drive/locales/zh-TW.json +48 -0
  284. package/src/trigger/providers/google-sheets/locales/fr.json +19 -0
  285. package/src/trigger/providers/google-sheets/locales/ja.json +19 -0
  286. package/src/trigger/providers/google-sheets/locales/ko.json +19 -0
  287. package/src/trigger/providers/google-sheets/locales/ru.json +19 -0
  288. package/src/trigger/providers/google-sheets/locales/zh-CN.json +19 -0
  289. package/src/trigger/providers/google-sheets/locales/zh-TW.json +19 -0
  290. package/src/trigger/providers/intercom/locales/fr.json +17 -0
  291. package/src/trigger/providers/intercom/locales/ja.json +17 -0
  292. package/src/trigger/providers/intercom/locales/ko.json +17 -0
  293. package/src/trigger/providers/intercom/locales/ru.json +17 -0
  294. package/src/trigger/providers/intercom/locales/zh-CN.json +17 -0
  295. package/src/trigger/providers/intercom/locales/zh-TW.json +17 -0
  296. package/src/trigger/providers/jira/locales/fr.json +17 -0
  297. package/src/trigger/providers/jira/locales/ja.json +17 -0
  298. package/src/trigger/providers/jira/locales/ko.json +17 -0
  299. package/src/trigger/providers/jira/locales/ru.json +17 -0
  300. package/src/trigger/providers/jira/locales/zh-CN.json +17 -0
  301. package/src/trigger/providers/jira/locales/zh-TW.json +17 -0
  302. package/src/trigger/providers/linear/locales/fr.json +13 -0
  303. package/src/trigger/providers/linear/locales/ja.json +13 -0
  304. package/src/trigger/providers/linear/locales/ko.json +13 -0
  305. package/src/trigger/providers/linear/locales/ru.json +13 -0
  306. package/src/trigger/providers/linear/locales/zh-CN.json +13 -0
  307. package/src/trigger/providers/linear/locales/zh-TW.json +13 -0
  308. package/src/trigger/providers/locales/fr.ts +71 -0
  309. package/src/trigger/providers/locales/ja.ts +71 -0
  310. package/src/trigger/providers/locales/ko.ts +71 -0
  311. package/src/trigger/providers/locales/ru.ts +71 -0
  312. package/src/trigger/providers/locales/zh-CN.ts +71 -0
  313. package/src/trigger/providers/locales/zh-TW.ts +71 -0
  314. package/src/trigger/providers/localization.ts +59 -0
  315. package/src/trigger/providers/notion/locales/fr.json +16 -0
  316. package/src/trigger/providers/notion/locales/ja.json +16 -0
  317. package/src/trigger/providers/notion/locales/ko.json +16 -0
  318. package/src/trigger/providers/notion/locales/ru.json +16 -0
  319. package/src/trigger/providers/notion/locales/zh-CN.json +16 -0
  320. package/src/trigger/providers/notion/locales/zh-TW.json +16 -0
  321. package/src/trigger/providers/one-drive/locales/fr.json +16 -0
  322. package/src/trigger/providers/one-drive/locales/ja.json +16 -0
  323. package/src/trigger/providers/one-drive/locales/ko.json +16 -0
  324. package/src/trigger/providers/one-drive/locales/ru.json +16 -0
  325. package/src/trigger/providers/one-drive/locales/zh-CN.json +16 -0
  326. package/src/trigger/providers/one-drive/locales/zh-TW.json +16 -0
  327. package/src/trigger/providers/outlook/locales/fr.json +18 -0
  328. package/src/trigger/providers/outlook/locales/ja.json +18 -0
  329. package/src/trigger/providers/outlook/locales/ko.json +18 -0
  330. package/src/trigger/providers/outlook/locales/ru.json +18 -0
  331. package/src/trigger/providers/outlook/locales/zh-CN.json +18 -0
  332. package/src/trigger/providers/outlook/locales/zh-TW.json +18 -0
  333. package/src/trigger/providers/pandadoc/locales/fr.json +12 -0
  334. package/src/trigger/providers/pandadoc/locales/ja.json +12 -0
  335. package/src/trigger/providers/pandadoc/locales/ko.json +12 -0
  336. package/src/trigger/providers/pandadoc/locales/ru.json +12 -0
  337. package/src/trigger/providers/pandadoc/locales/zh-CN.json +12 -0
  338. package/src/trigger/providers/pandadoc/locales/zh-TW.json +12 -0
  339. package/src/trigger/providers/pipedrive/locales/fr.json +15 -0
  340. package/src/trigger/providers/pipedrive/locales/ja.json +15 -0
  341. package/src/trigger/providers/pipedrive/locales/ko.json +15 -0
  342. package/src/trigger/providers/pipedrive/locales/ru.json +15 -0
  343. package/src/trigger/providers/pipedrive/locales/zh-CN.json +15 -0
  344. package/src/trigger/providers/pipedrive/locales/zh-TW.json +15 -0
  345. package/src/trigger/providers/remote.ts +163 -0
  346. package/src/trigger/providers/resend/locales/fr.json +16 -0
  347. package/src/trigger/providers/resend/locales/ja.json +16 -0
  348. package/src/trigger/providers/resend/locales/ko.json +16 -0
  349. package/src/trigger/providers/resend/locales/ru.json +16 -0
  350. package/src/trigger/providers/resend/locales/zh-CN.json +16 -0
  351. package/src/trigger/providers/resend/locales/zh-TW.json +16 -0
  352. package/src/trigger/providers/sentry/locales/fr.json +19 -0
  353. package/src/trigger/providers/sentry/locales/ja.json +19 -0
  354. package/src/trigger/providers/sentry/locales/ko.json +19 -0
  355. package/src/trigger/providers/sentry/locales/ru.json +19 -0
  356. package/src/trigger/providers/sentry/locales/zh-CN.json +19 -0
  357. package/src/trigger/providers/sentry/locales/zh-TW.json +19 -0
  358. package/src/trigger/providers/shopify/locales/fr.json +18 -0
  359. package/src/trigger/providers/shopify/locales/ja.json +18 -0
  360. package/src/trigger/providers/shopify/locales/ko.json +18 -0
  361. package/src/trigger/providers/shopify/locales/ru.json +18 -0
  362. package/src/trigger/providers/shopify/locales/zh-CN.json +18 -0
  363. package/src/trigger/providers/shopify/locales/zh-TW.json +18 -0
  364. package/src/trigger/providers/slack/locales/fr.json +18 -0
  365. package/src/trigger/providers/slack/locales/ja.json +18 -0
  366. package/src/trigger/providers/slack/locales/ko.json +18 -0
  367. package/src/trigger/providers/slack/locales/ru.json +18 -0
  368. package/src/trigger/providers/slack/locales/zh-CN.json +18 -0
  369. package/src/trigger/providers/slack/locales/zh-TW.json +18 -0
  370. package/src/trigger/providers/slackbot/locales/fr.json +23 -0
  371. package/src/trigger/providers/slackbot/locales/ja.json +23 -0
  372. package/src/trigger/providers/slackbot/locales/ko.json +23 -0
  373. package/src/trigger/providers/slackbot/locales/ru.json +23 -0
  374. package/src/trigger/providers/slackbot/locales/zh-CN.json +23 -0
  375. package/src/trigger/providers/slackbot/locales/zh-TW.json +23 -0
  376. package/src/trigger/providers/source-events.ts +25 -0
  377. package/src/trigger/providers/stripe/locales/fr.json +17 -0
  378. package/src/trigger/providers/stripe/locales/ja.json +17 -0
  379. package/src/trigger/providers/stripe/locales/ko.json +17 -0
  380. package/src/trigger/providers/stripe/locales/ru.json +17 -0
  381. package/src/trigger/providers/stripe/locales/zh-CN.json +17 -0
  382. package/src/trigger/providers/stripe/locales/zh-TW.json +17 -0
  383. package/src/trigger/providers/tally/locales/fr.json +12 -0
  384. package/src/trigger/providers/tally/locales/ja.json +12 -0
  385. package/src/trigger/providers/tally/locales/ko.json +12 -0
  386. package/src/trigger/providers/tally/locales/ru.json +12 -0
  387. package/src/trigger/providers/tally/locales/zh-CN.json +12 -0
  388. package/src/trigger/providers/tally/locales/zh-TW.json +12 -0
  389. package/src/trigger/providers/telegram/locales/fr.json +17 -0
  390. package/src/trigger/providers/telegram/locales/ja.json +17 -0
  391. package/src/trigger/providers/telegram/locales/ko.json +17 -0
  392. package/src/trigger/providers/telegram/locales/ru.json +17 -0
  393. package/src/trigger/providers/telegram/locales/zh-CN.json +17 -0
  394. package/src/trigger/providers/telegram/locales/zh-TW.json +17 -0
  395. package/src/trigger/providers/typeform/locales/fr.json +12 -0
  396. package/src/trigger/providers/typeform/locales/ja.json +12 -0
  397. package/src/trigger/providers/typeform/locales/ko.json +12 -0
  398. package/src/trigger/providers/typeform/locales/ru.json +12 -0
  399. package/src/trigger/providers/typeform/locales/zh-CN.json +12 -0
  400. package/src/trigger/providers/typeform/locales/zh-TW.json +12 -0
  401. package/src/trigger/providers/vercel/locales/fr.json +18 -0
  402. package/src/trigger/providers/vercel/locales/ja.json +18 -0
  403. package/src/trigger/providers/vercel/locales/ko.json +18 -0
  404. package/src/trigger/providers/vercel/locales/ru.json +18 -0
  405. package/src/trigger/providers/vercel/locales/zh-CN.json +18 -0
  406. package/src/trigger/providers/vercel/locales/zh-TW.json +18 -0
  407. package/src/trigger/providers/woocommerce/locales/fr.json +19 -0
  408. package/src/trigger/providers/woocommerce/locales/ja.json +19 -0
  409. package/src/trigger/providers/woocommerce/locales/ko.json +19 -0
  410. package/src/trigger/providers/woocommerce/locales/ru.json +19 -0
  411. package/src/trigger/providers/woocommerce/locales/zh-CN.json +19 -0
  412. package/src/trigger/providers/woocommerce/locales/zh-TW.json +19 -0
  413. package/src/trigger/providers/zendesk/locales/fr.json +15 -0
  414. package/src/trigger/providers/zendesk/locales/ja.json +15 -0
  415. package/src/trigger/providers/zendesk/locales/ko.json +15 -0
  416. package/src/trigger/providers/zendesk/locales/ru.json +15 -0
  417. package/src/trigger/providers/zendesk/locales/zh-CN.json +15 -0
  418. package/src/trigger/providers/zendesk/locales/zh-TW.json +15 -0
  419. package/src/trigger/providers/zoom/locales/fr.json +17 -0
  420. package/src/trigger/providers/zoom/locales/ja.json +17 -0
  421. package/src/trigger/providers/zoom/locales/ko.json +17 -0
  422. package/src/trigger/providers/zoom/locales/ru.json +17 -0
  423. package/src/trigger/providers/zoom/locales/zh-CN.json +17 -0
  424. package/src/trigger/providers/zoom/locales/zh-TW.json +17 -0
  425. package/src/types/index.ts +112 -0
  426. package/src/workflow/common/workflow.ts +273 -0
  427. package/dist/browser/lib-DrKav3HG.js +0 -11403
  428. /package/dist/{browser → common}/flow-authoring-edge.d.ts +0 -0
  429. /package/dist/{browser → common}/flow-authoring-module.d.ts +0 -0
  430. /package/dist/{browser → common}/flow-authoring.d.ts +0 -0
  431. /package/dist/{browser → common}/flow-input-value.d.ts +0 -0
  432. /package/dist/{browser → common}/webhook-method.d.ts +0 -0
@@ -0,0 +1,1036 @@
1
+ import type { JsonValue, Port, PortDefinition } from '../../types/index.ts'
2
+
3
+ import { assertOpenApiAuthBindings } from '../../openapi/common/authBindings.ts'
4
+ export { fixedInputValue, inputValue, inputValues } from './inputValue.ts'
5
+ import type { RetryConfiguration } from './retry.ts'
6
+ import type { WebhookMethod } from './webhookMethod.ts'
7
+
8
+ import { dequal } from 'dequal/lite'
9
+ import { authoringDefinitionSchemas, currentFlowModelVersion, decodeRevisionContent } from './changeSchema.ts'
10
+ import { nodeInputMappings, setConditionInput } from './condition.ts'
11
+ import { supportsNodeErrorHandling } from './errorHandling.ts'
12
+ import { supportsNodeRetry } from './retry.ts'
13
+
14
+ export { changeOperationsSchema, currentFlowModelVersion, decodeChangeOperations } from './changeSchema.ts'
15
+ export type { RetryConfiguration } from './retry.ts'
16
+ export { supportsNodeRetry } from './retry.ts'
17
+ export { nodeSystemOutputPorts, supportsNodeErrorHandling, nodeErrorSchema } from './errorHandling.ts'
18
+ export type { NodeErrorData } from './errorHandling.ts'
19
+ export type { WebhookMethod }
20
+
21
+ export type { JsonValue, Port, PortDefinition } from '../../types/index.ts'
22
+
23
+ export { isSchemaKeyword } from './schemaKeywords.ts'
24
+ export type { SchemaKeyword, SchemaMismatch } from './schemaKeywords.ts'
25
+
26
+ export const resourceNameMaxLength = 80
27
+
28
+ export type ResourceNameIssue = 'controlCharacter' | 'empty' | 'specialCharacter' | 'tooLong'
29
+
30
+ export function resourceNameIssue(value: string): ResourceNameIssue | undefined {
31
+ const name = value.trim()
32
+ if (name.length == 0) return 'empty'
33
+ if (name.length > resourceNameMaxLength) return 'tooLong'
34
+ for (const character of name) {
35
+ const code = character.charCodeAt(0)
36
+ if (code <= 0x1f || (code >= 0x7f && code <= 0x9f)) return 'controlCharacter'
37
+ }
38
+ if (!/^[\p{L}\p{N}](?:[\p{L}\p{N} _-]*[\p{L}\p{N}])?$/u.test(name)) return 'specialCharacter'
39
+ }
40
+
41
+ export function validVariableName(value: string): boolean {
42
+ return value.length <= 256 && /^[A-Za-z_][A-Za-z0-9_]*$/.test(value) && value.slice(0, 3).toUpperCase() != 'OO_'
43
+ }
44
+
45
+ export interface InputPortDefinition extends PortDefinition {
46
+ readonly value?: JsonValue
47
+ }
48
+
49
+ export interface InputPort extends InputPortDefinition {
50
+ readonly handle: string
51
+ }
52
+
53
+ export interface Group {
54
+ readonly collapsed?: boolean
55
+ readonly group: string
56
+ }
57
+
58
+ export function portsByHandle<Value extends Port>(ports: readonly (Value | Group)[]): Readonly<Record<string, Value>> {
59
+ return Object.fromEntries(ports.flatMap((port) => ('handle' in port ? [[port.handle, port]] : [])))
60
+ }
61
+
62
+ export interface NodeSource {
63
+ readonly system?: true
64
+ readonly field?: string
65
+ readonly kind: 'node'
66
+ readonly nodeId: string
67
+ readonly output: string
68
+ }
69
+
70
+ export interface BindingSource {
71
+ readonly bindingId: string
72
+ readonly kind: 'binding'
73
+ }
74
+
75
+ export type FixedInputValue = { readonly kind: 'unset' } | { readonly kind: 'value'; readonly value: JsonValue }
76
+ export type InputValues = Readonly<Record<string, FixedInputValue>>
77
+
78
+ export type InputMapping = FixedInputValue | { readonly kind: 'sources'; readonly sources: readonly (BindingSource | NodeSource)[] }
79
+
80
+ interface GraphNodeBase {
81
+ readonly description?: string
82
+ readonly icon?: string
83
+ readonly inputs: Readonly<Record<string, InputMapping>>
84
+ readonly name?: string
85
+ readonly maxExecutions?: number
86
+ readonly timeoutMs?: number
87
+ readonly retry?: RetryConfiguration
88
+ readonly onError?: 'stop' | 'error'
89
+ }
90
+
91
+ export interface ValueNode extends GraphNodeBase {
92
+ readonly kind: 'value'
93
+ readonly values: readonly InputPort[]
94
+ }
95
+
96
+ export type WaitAction = 'approve' | 'continue' | 'reject'
97
+
98
+ interface ResolutionNodeBase extends GraphNodeBase {
99
+ readonly inputDefinitions: readonly InputPort[]
100
+ readonly prompt: string
101
+ readonly timeoutMs?: never
102
+ }
103
+
104
+ export type WaitAutoContinue =
105
+ | { readonly kind: 'after'; readonly durationMs: number | null }
106
+ | { readonly kind: 'at'; readonly at: string; readonly timezone?: string }
107
+
108
+ export interface WaitNode extends ResolutionNodeBase {
109
+ readonly autoContinue?: WaitAutoContinue
110
+ readonly kind: 'wait'
111
+ }
112
+
113
+ export interface ApprovalNode extends ResolutionNodeBase {
114
+ readonly kind: 'approval'
115
+ }
116
+
117
+ export type ResolutionNode = ApprovalNode | WaitNode
118
+
119
+ export type ConditionOperator =
120
+ | '!='
121
+ | '<'
122
+ | '<='
123
+ | '=='
124
+ | '>'
125
+ | '>='
126
+ | 'contains'
127
+ | 'endsWith'
128
+ | 'hasKey'
129
+ | 'hasValue'
130
+ | 'isEmpty'
131
+ | 'isFalse'
132
+ | 'isNotEmpty'
133
+ | 'isNotNull'
134
+ | 'isNull'
135
+ | 'isTrue'
136
+ | 'notContains'
137
+ | 'notHasKey'
138
+ | 'notHasValue'
139
+ | 'startsWith'
140
+
141
+ export type Source = BindingSource | NodeSource
142
+
143
+ export type ConditionOperand =
144
+ | { readonly kind: 'value'; readonly value?: JsonValue; readonly jsonSchema?: JsonValue }
145
+ | { readonly kind: 'source'; readonly source: Source }
146
+
147
+ export interface ConditionExpression {
148
+ readonly left: ConditionOperand
149
+ readonly operator: ConditionOperator
150
+ readonly right?: ConditionOperand
151
+ }
152
+
153
+ export interface ConditionGroup {
154
+ readonly expressions: readonly ConditionExpression[]
155
+ }
156
+
157
+ export interface ConditionCase {
158
+ readonly description?: string
159
+ readonly groups: readonly ConditionGroup[]
160
+ readonly output: string
161
+ }
162
+
163
+ export interface ConditionNode extends GraphNodeBase {
164
+ readonly cases: readonly ConditionCase[]
165
+ readonly matchMode: 'first' | 'all'
166
+ readonly kind: 'condition'
167
+ }
168
+
169
+ export type ManagedTaskExecutor =
170
+ | import('../../workflow/common/workflow.ts').WorkflowExecutor
171
+ | import('../../decision/common/decision.ts').DecisionExecutor
172
+ | import('../../openapi/common/openapi.ts').OpenApiExecutor
173
+ | { readonly kind: 'connector'; readonly action: string; readonly connectionId?: string; readonly outputMode?: 'value' }
174
+ | { readonly kind: 'llm'; readonly mode: 'chat' | 'json' }
175
+ | {
176
+ readonly kind: 'agent'
177
+ readonly code?: boolean
178
+ readonly model: string
179
+ readonly prompt: string
180
+ readonly maxRounds: number
181
+ readonly tools: readonly AgentTool[]
182
+ readonly notification?: {
183
+ readonly action: string
184
+ readonly connectionId?: string
185
+ readonly inputDefinitions: readonly InputPort[]
186
+ readonly messageHandle: string
187
+ readonly inputs: Readonly<Record<string, Exclude<AgentInput, { readonly kind: 'model' }>>>
188
+ }
189
+ }
190
+
191
+ export type AgentInput = { readonly kind: 'value'; readonly value: JsonValue } | { readonly kind: 'input'; readonly input: string } | { readonly kind: 'model' }
192
+
193
+ interface AgentToolBase {
194
+ readonly id: string
195
+ readonly name: string
196
+ readonly description: string
197
+ readonly approval: boolean
198
+ readonly inputs: readonly (InputPort & { readonly source: AgentInput })[]
199
+ }
200
+
201
+ export interface AgentConnectorTool extends AgentToolBase {
202
+ readonly kind?: 'connector'
203
+ readonly action: string
204
+ readonly connectionId?: string
205
+ }
206
+
207
+ export interface WorkflowCapability {
208
+ readonly kind: 'workflow'
209
+ readonly name: string
210
+ readonly flowId: string
211
+ readonly revisionId: string
212
+ readonly inputs: readonly Port[]
213
+ readonly outputs: readonly Port[] | null
214
+ }
215
+
216
+ export interface AgentWorkflowTool extends AgentToolBase, Omit<WorkflowCapability, 'inputs'> {
217
+ readonly action?: never
218
+ readonly connectionId?: never
219
+ }
220
+
221
+ export type AgentTool = AgentConnectorTool | AgentWorkflowTool
222
+ export type TaskCapability = ConnectorCapability | WorkflowCapability
223
+
224
+ export const workflowToolNamePattern = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/
225
+
226
+ export function workflowToolNameIssue(name: string, otherNames: Iterable<string> = []): 'invalid' | 'duplicate' | undefined {
227
+ if (!workflowToolNamePattern.test(name)) return 'invalid'
228
+ for (const other of otherNames) if (other == name) return 'duplicate'
229
+ }
230
+
231
+ export function decodeTaskCapabilities(value: unknown): readonly TaskCapability[] {
232
+ if (!Array.isArray(value)) throw new TypeError('Task capabilities must be an array.')
233
+ const parsed = authoringDefinitionSchemas.capabilities.parse(value)
234
+ const connectors = decodeConnectorCapabilities(parsed.filter((item) => item.kind == 'connector'))
235
+ const names = new Set<string>()
236
+ for (const item of parsed) {
237
+ if (item.kind != 'workflow') continue
238
+ if (workflowToolNameIssue(item.name, names)) throw new TypeError('Workflow tool names must be unique provider-compatible names.')
239
+ names.add(item.name)
240
+ }
241
+ let connectorIndex = 0
242
+ return parsed.map((item) => (item.kind == 'connector' ? connectors[connectorIndex++]! : item)) as readonly TaskCapability[]
243
+ }
244
+
245
+ export interface ConnectorAccessCapability {
246
+ readonly actionHints?: readonly string[]
247
+ readonly connectionHints?: readonly {
248
+ readonly action: string
249
+ readonly connectionId: string
250
+ readonly alias?: string
251
+ }[]
252
+ readonly kind: 'connector'
253
+ }
254
+
255
+ export interface ConnectorActionCapability {
256
+ readonly action: string
257
+ readonly connections: readonly { readonly connectionId: string; readonly alias?: string }[]
258
+ readonly connectionId?: string
259
+ readonly kind: 'connector'
260
+ }
261
+
262
+ export type ConnectorPermissionCapability =
263
+ | { readonly kind: 'connector'; readonly mode: 'shared' }
264
+ | { readonly kind: 'connector'; readonly mode: 'independent'; readonly actions: readonly { readonly action: string; readonly connectionId?: string }[] }
265
+
266
+ export type ConnectorCapability = ConnectorAccessCapability | ConnectorActionCapability | ConnectorPermissionCapability
267
+
268
+ export function decodeConnectorCapabilities(value: unknown): readonly ConnectorCapability[] {
269
+ if (!Array.isArray(value)) throw new TypeError('Connector capabilities must be an array.')
270
+ if (value.length == 0) return []
271
+ if (value.some((item) => item != null && typeof item == 'object' && !Array.isArray(item) && Object.hasOwn(item, 'mode'))) {
272
+ if (value.length != 1) throw new TypeError('Connector capability is declared more than once.')
273
+ const source = value[0] as Record<string, unknown>
274
+ if (source.mode == 'shared') {
275
+ if (source.kind != 'connector' || Object.keys(source).some((key) => !['kind', 'mode'].includes(key)))
276
+ throw new TypeError('Invalid shared Connector permission capability.')
277
+ return [{ kind: 'connector', mode: 'shared' }]
278
+ }
279
+ if (
280
+ Object.keys(source).some((key) => !['kind', 'mode', 'actions'].includes(key)) ||
281
+ source.kind != 'connector' ||
282
+ source.mode != 'independent' ||
283
+ !Array.isArray(source.actions)
284
+ )
285
+ throw new TypeError('Invalid Connector permission capability.')
286
+ const actions = source.actions.map((entry: unknown) => {
287
+ if (entry == null || typeof entry != 'object' || Array.isArray(entry)) throw new TypeError('Invalid Connector Action.')
288
+ const action = entry as Record<string, unknown>
289
+ if (
290
+ Object.keys(action).some((key) => !['action', 'connectionId'].includes(key)) ||
291
+ typeof action.action != 'string' ||
292
+ !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+$/.test(action.action) ||
293
+ (Object.hasOwn(action, 'connectionId') && typeof action.connectionId != 'string')
294
+ )
295
+ throw new TypeError('Invalid Connector Action permission.')
296
+ return action.connectionId == null ? { action: action.action } : { action: action.action, connectionId: action.connectionId as string }
297
+ })
298
+ if (new Set(actions.map((action) => action.action)).size != actions.length) throw new TypeError('Duplicate Connector Action permission.')
299
+ return [{ kind: 'connector', mode: 'independent', actions }]
300
+ }
301
+ if (value.some((item) => item != null && typeof item == 'object' && !Array.isArray(item) && !Object.hasOwn(item, 'action'))) {
302
+ if (value.length != 1) throw new TypeError('Connector capability is declared more than once.')
303
+ const item = value[0]
304
+ if (item == null || typeof item != 'object' || Array.isArray(item)) throw new TypeError('Invalid Connector capability.')
305
+ const source = item as Record<string, unknown>
306
+ if (
307
+ Object.keys(source).some((key) => !['kind', 'actionHints', 'connectionHints'].includes(key)) ||
308
+ source.kind != 'connector' ||
309
+ (Object.hasOwn(source, 'actionHints') && !Array.isArray(source.actionHints)) ||
310
+ (Object.hasOwn(source, 'connectionHints') && !Array.isArray(source.connectionHints))
311
+ ) {
312
+ throw new TypeError('Invalid Connector capability.')
313
+ }
314
+ const actionHints = ((source.actionHints as readonly unknown[] | undefined) ?? []).map((action: unknown) => {
315
+ if (typeof action != 'string' || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+$/.test(action)) throw new TypeError('Invalid Connector Action hint.')
316
+ return action
317
+ })
318
+ if (new Set(actionHints).size != actionHints.length) throw new TypeError('Duplicate Connector Action hint.')
319
+ const keys = new Set<string>()
320
+ const connectionHints = ((source.connectionHints as readonly unknown[] | undefined) ?? []).map((entry: unknown) => {
321
+ if (entry == null || typeof entry != 'object' || Array.isArray(entry)) throw new TypeError('Invalid Connector Connection hint.')
322
+ const hint = entry as Record<string, unknown>
323
+ if (
324
+ Object.keys(hint).some((key) => !['action', 'connectionId', 'alias'].includes(key)) ||
325
+ typeof hint.action != 'string' ||
326
+ !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+$/.test(hint.action) ||
327
+ typeof hint.connectionId != 'string' ||
328
+ hint.connectionId.length == 0 ||
329
+ (Object.hasOwn(hint, 'alias') && (typeof hint.alias != 'string' || hint.alias.length == 0))
330
+ ) {
331
+ throw new TypeError('Invalid Connector Connection hint.')
332
+ }
333
+ const key = `${hint.action}\0${hint.alias ?? ''}`
334
+ if (keys.has(key)) throw new TypeError('Duplicate Connector Connection hint.')
335
+ keys.add(key)
336
+ return hint.alias == null
337
+ ? { action: hint.action, connectionId: hint.connectionId }
338
+ : { action: hint.action, connectionId: hint.connectionId, alias: hint.alias as string }
339
+ })
340
+ return [
341
+ {
342
+ kind: 'connector',
343
+ ...(actionHints.length == 0 ? {} : { actionHints }),
344
+ ...(connectionHints.length == 0 ? {} : { connectionHints }),
345
+ },
346
+ ]
347
+ }
348
+ const actions = new Set<string>()
349
+ return value.map((item: unknown) => {
350
+ if (item == null || typeof item != 'object' || Array.isArray(item)) throw new TypeError('Invalid Connector capability.')
351
+ const source = item as Record<string, unknown>
352
+ if (
353
+ Object.keys(source).some((key) => !['kind', 'action', 'connections', 'connectionId'].includes(key)) ||
354
+ source.kind != 'connector' ||
355
+ typeof source.action != 'string' ||
356
+ !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+$/.test(source.action) ||
357
+ !Array.isArray(source.connections)
358
+ ) {
359
+ throw new TypeError('Invalid Connector capability.')
360
+ }
361
+ if (actions.has(source.action)) throw new TypeError('Connector Action is declared more than once.')
362
+ actions.add(source.action)
363
+ const ids = new Set<string>()
364
+ const aliases = new Set<string>()
365
+ const connections = source.connections.map((entry: unknown) => {
366
+ if (entry == null || typeof entry != 'object' || Array.isArray(entry)) throw new TypeError('Invalid Connector Connection.')
367
+ const connection = entry as Record<string, unknown>
368
+ if (
369
+ Object.keys(connection).some((key) => !['connectionId', 'alias'].includes(key)) ||
370
+ typeof connection.connectionId != 'string' ||
371
+ connection.connectionId.length == 0 ||
372
+ ids.has(connection.connectionId)
373
+ ) {
374
+ throw new TypeError('Invalid or duplicate Connector Connection ID.')
375
+ }
376
+ ids.add(connection.connectionId)
377
+ if (Object.hasOwn(connection, 'alias')) {
378
+ if (typeof connection.alias != 'string' || connection.alias.length == 0 || aliases.has(connection.alias))
379
+ throw new TypeError('Invalid or duplicate Connector alias.')
380
+ aliases.add(connection.alias)
381
+ }
382
+ return { connectionId: connection.connectionId, ...(connection.alias == null ? {} : { alias: connection.alias as string }) }
383
+ })
384
+ if (Object.hasOwn(source, 'connectionId') && (typeof source.connectionId != 'string' || !ids.has(source.connectionId))) {
385
+ throw new TypeError('The default Connector Connection must be declared.')
386
+ }
387
+ return { kind: 'connector', action: source.action, connections, ...(source.connectionId == null ? {} : { connectionId: source.connectionId as string }) }
388
+ })
389
+ }
390
+
391
+ interface TaskDefinitionBase {
392
+ readonly inputs: readonly (InputPort | Group)[]
393
+ readonly name: string
394
+ readonly outputs: readonly (Port | Group)[]
395
+ }
396
+
397
+ export interface InlineTaskDefinition extends TaskDefinitionBase {
398
+ readonly capabilities?: readonly TaskCapability[]
399
+ readonly moduleId: string
400
+ }
401
+
402
+ export interface ManagedTaskDefinition extends TaskDefinitionBase {
403
+ readonly executor: ManagedTaskExecutor
404
+ }
405
+
406
+ export type TaskDefinition = InlineTaskDefinition | ManagedTaskDefinition
407
+
408
+ export interface TaskNode extends GraphNodeBase {
409
+ readonly kind: 'task'
410
+ readonly additionalInputs?: readonly InputPort[]
411
+ readonly task: TaskDefinition
412
+ }
413
+
414
+ export interface Graph {
415
+ readonly edges: readonly GraphEdge[]
416
+ readonly nodes: Readonly<Record<string, GraphNode>>
417
+ }
418
+
419
+ export type TriggerSchedule =
420
+ | { readonly expression: string; readonly timezone: string; readonly type: 'cron' }
421
+ | { readonly type: 'every'; readonly unit: 'day' | 'hour' | 'minute' | 'month' | 'week'; readonly value: number }
422
+
423
+ interface TriggerKeySnapshotBase {
424
+ readonly configInputs: readonly (InputPort | Group)[]
425
+ readonly definitionVersion: number
426
+ readonly description: string
427
+ readonly displayName: string
428
+ readonly key: string
429
+ readonly name: string
430
+ readonly outputs: readonly Port[]
431
+ readonly provider: string
432
+ }
433
+
434
+ export type IntegrationEndpointMethod = 'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT'
435
+
436
+ export type IntegrationBodyFormat = 'form' | 'json' | 'multipart' | 'text'
437
+
438
+ export interface IntegrationEndpointDeclaration {
439
+ readonly body: {
440
+ readonly allowArray: boolean
441
+ readonly allowEmpty: boolean
442
+ readonly formats: readonly IntegrationBodyFormat[]
443
+ }
444
+ readonly methods: readonly IntegrationEndpointMethod[]
445
+ readonly successStatus: number
446
+ }
447
+
448
+ export type TriggerKeySnapshot =
449
+ | (TriggerKeySnapshotBase & { readonly type: 'poll' })
450
+ | (TriggerKeySnapshotBase & { readonly endpoint: IntegrationEndpointDeclaration; readonly type: 'integration' })
451
+
452
+ export interface WebhookBodyField extends InputPort {}
453
+
454
+ export interface WebhookOptions {
455
+ readonly allowedOrigins?: readonly string[]
456
+ readonly responseBody?:
457
+ | { readonly kind: 'workflow-outputs'; readonly output?: string; readonly timeoutMs?: number }
458
+ | { readonly kind: 'webhook-response'; readonly nodeId?: string; readonly timeoutMs?: number }
459
+ readonly responseData?: string
460
+ readonly responseHeaders?: Readonly<Record<string, string>>
461
+ readonly responseHeadersSource?: {
462
+ readonly kind: 'workflow-outputs'
463
+ readonly output?: string
464
+ }
465
+ readonly responseHeaderOutputs?: Readonly<Record<string, string>>
466
+ readonly responseStatusCode?: number
467
+ readonly responseStatusCodeOutput?: string
468
+ }
469
+
470
+ interface TriggerNodeBase {
471
+ readonly onError?: never
472
+ readonly description?: string
473
+ readonly icon?: string
474
+ readonly name: string
475
+ }
476
+
477
+ export type TriggerNode =
478
+ | (TriggerNodeBase & { readonly kind: 'manual' })
479
+ | (TriggerNodeBase & { readonly kind: 'start'; readonly inputDefs: readonly Port[] })
480
+ | (TriggerNodeBase & { readonly kind: 'error'; readonly sourceFlowIds?: readonly string[] })
481
+ | (TriggerNodeBase & {
482
+ readonly bodyFields: readonly WebhookBodyField[]
483
+ readonly kind: 'webhook'
484
+ readonly method: WebhookMethod
485
+ readonly options?: WebhookOptions
486
+ })
487
+ | (TriggerNodeBase & { readonly cronTimes: readonly TriggerSchedule[]; readonly kind: 'cron' })
488
+ | (TriggerNodeBase & {
489
+ readonly connectionId?: string
490
+ readonly config: InputValues
491
+ readonly definition: TriggerKeySnapshot & { readonly type: 'poll' }
492
+ readonly kind: 'poll'
493
+ readonly pollTimes: readonly TriggerSchedule[]
494
+ })
495
+ | (TriggerNodeBase & {
496
+ readonly connectionId?: string
497
+ readonly config: InputValues
498
+ readonly definition: TriggerKeySnapshot & { readonly type: 'integration' }
499
+ readonly kind: 'integration'
500
+ })
501
+
502
+ export interface OutputsNode extends Omit<GraphNodeBase, 'inputs'> {
503
+ readonly kind: 'outputs'
504
+ readonly outputDefs: readonly Port[]
505
+ readonly outputMappings: Readonly<Record<string, InputMapping>>
506
+ }
507
+
508
+ export function isTriggerNode(node: GraphNode): node is TriggerNode {
509
+ return ['manual', 'start', 'error', 'webhook', 'cron', 'poll', 'integration'].includes(node.kind)
510
+ }
511
+
512
+ export interface WebhookResponseNode extends GraphNodeBase {
513
+ readonly kind: 'webhook-response'
514
+ readonly retry?: never
515
+ readonly onError?: never
516
+ }
517
+
518
+ export type GraphNode = WebhookResponseNode | OutputsNode | ApprovalNode | ConditionNode | TaskNode | TriggerNode | ValueNode | WaitNode
519
+
520
+ export interface FlowDocument {
521
+ readonly bindings: Readonly<Record<string, { readonly kind: 'variable'; readonly target: string }>>
522
+ readonly graph: Graph
523
+ }
524
+
525
+ export interface CodeModule {
526
+ readonly imports: readonly string[]
527
+ readonly name: string
528
+ readonly source: string
529
+ }
530
+
531
+ export interface RevisionContent {
532
+ readonly document: FlowDocument
533
+ readonly modelVersion: 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | typeof currentFlowModelVersion
534
+ readonly modules: Readonly<Record<string, CodeModule>>
535
+ }
536
+
537
+ export interface GraphEdge {
538
+ readonly source: string
539
+ readonly sourceHandle?: string
540
+ readonly target: string
541
+ }
542
+
543
+ /** Lossless upgrade of readable content. Historical content and its encoding stay unchanged. */
544
+ export function upgradeRevisionContent(content: RevisionContent): RevisionContent {
545
+ const upgraded = upgradeDecodedRevisionContent(decodeRevisionContent(content))
546
+ return dequal(content, upgraded) ? content : upgraded
547
+ }
548
+
549
+ function upgradeDecodedRevisionContent(content: RevisionContent): RevisionContent {
550
+ const graph = content.document.graph
551
+ const hasManual = Object.values(graph.nodes).some((node) => node.kind == 'manual')
552
+ if (!hasManual && content.modelVersion == currentFlowModelVersion) return content
553
+ return {
554
+ ...content,
555
+ modelVersion: currentFlowModelVersion,
556
+ document: {
557
+ ...content.document,
558
+ graph: hasManual ? { ...graph, nodes: Object.fromEntries(Object.entries(graph.nodes).map(([id, node]) => [id, upgradeManualTrigger(node)])) } : graph,
559
+ },
560
+ }
561
+ }
562
+
563
+ export function upgradeManualTrigger(node: GraphNode): GraphNode {
564
+ return node.kind == 'manual' ? { ...node, kind: 'start', inputDefs: [] } : node
565
+ }
566
+
567
+ export function normalizeNodeName(value: string): string {
568
+ return value.trim().normalize('NFC')
569
+ }
570
+
571
+ export function nextNodeName(value: string, names: Iterable<string>): string {
572
+ const name = normalizeNodeName(value)
573
+ const used = new Set([...names].map(normalizeNodeName))
574
+ if (!used.has(name)) return name
575
+ const match = /^(.*) \((\d+)\)$/.exec(name)
576
+ const ordinalText = match?.[2]
577
+ const ordinal = ordinalText != null && Number(ordinalText) >= 2 ? Number(ordinalText) : undefined
578
+ const base = ordinal == null ? name : (match?.[1] ?? name)
579
+ let number = ordinal == null ? 2 : ordinal + 1
580
+ while (used.has(`${base} (${number})`)) number += 1
581
+ return `${base} (${number})`
582
+ }
583
+
584
+ export function nodeNameIssue(graph: Graph, nodeId: string, value: string): 'duplicate' | 'empty' | undefined {
585
+ const name = normalizeNodeName(value)
586
+ if (name.length == 0) return 'empty'
587
+ return Object.entries(graph.nodes).some(([candidateId, node]) => candidateId != nodeId && node.name != null && normalizeNodeName(node.name) == name)
588
+ ? 'duplicate'
589
+ : undefined
590
+ }
591
+
592
+ export type ChangeOperation =
593
+ | { readonly kind: 'graph.node.replace'; readonly nodeId: string; readonly before: GraphNode; readonly node: GraphNode }
594
+ | {
595
+ readonly before?: readonly TaskCapability[]
596
+ readonly kind: 'graph.node.task.capabilities.set'
597
+ readonly nodeId: string
598
+
599
+ readonly value?: readonly TaskCapability[]
600
+ }
601
+ | { readonly kind: 'graph.trigger.sources.set'; readonly nodeId: string; readonly before?: readonly string[]; readonly value?: readonly string[] }
602
+ | { readonly binding: FlowDocument['bindings'][string]; readonly bindingId: string; readonly kind: 'binding.create' }
603
+ | { readonly bindingId: string; readonly kind: 'binding.delete' }
604
+ | { readonly before: string; readonly bindingId: string; readonly kind: 'binding.target.set'; readonly value: string }
605
+ | { readonly kind: 'graph.edge.connect'; readonly edge: GraphEdge }
606
+ | { readonly kind: 'graph.edge.disconnect'; readonly edge: GraphEdge }
607
+ | {
608
+ readonly before?: readonly InputPort[]
609
+ readonly kind: 'graph.node.additional-inputs.set'
610
+ readonly nodeId: string
611
+
612
+ readonly value?: readonly InputPort[]
613
+ }
614
+ | {
615
+ readonly before: Pick<ConditionNode, 'cases' | 'matchMode'>
616
+ readonly kind: 'graph.node.condition.set'
617
+ readonly nodeId: string
618
+
619
+ readonly value: Pick<ConditionNode, 'cases' | 'matchMode'>
620
+ }
621
+ | { readonly kind: 'graph.node.create'; readonly node: GraphNode; readonly nodeId: string }
622
+ | { readonly kind: 'graph.node.delete'; readonly nodeId: string }
623
+ | {
624
+ readonly before?: number | string
625
+ readonly field: 'connectionId' | 'description' | 'icon' | 'maxExecutions' | 'name' | 'timeoutMs' | 'onError'
626
+ readonly kind: 'graph.node.field.set'
627
+ readonly nodeId: string
628
+
629
+ readonly value?: number | string
630
+ }
631
+ | {
632
+ readonly before?: RetryConfiguration
633
+ readonly field: 'retry'
634
+ readonly kind: 'graph.node.field.set'
635
+ readonly nodeId: string
636
+ readonly value?: RetryConfiguration
637
+ }
638
+ | {
639
+ readonly before?: InputMapping
640
+ readonly handle: string
641
+ readonly kind: 'graph.node.input.set'
642
+ readonly nodeId: string
643
+
644
+ readonly value?: InputMapping
645
+ }
646
+ | {
647
+ readonly before: Pick<InlineTaskDefinition, 'inputs' | 'outputs'>
648
+ readonly kind: 'graph.node.task.ports.set'
649
+ readonly nodeId: string
650
+
651
+ readonly value: Pick<InlineTaskDefinition, 'inputs' | 'outputs'>
652
+ }
653
+ | {
654
+ readonly before: string
655
+ readonly kind: 'graph.node.task.name.set'
656
+ readonly nodeId: string
657
+
658
+ readonly value: string
659
+ }
660
+ | {
661
+ readonly before: readonly InputPort[]
662
+ readonly kind: 'graph.node.values.set'
663
+ readonly nodeId: string
664
+
665
+ readonly value: readonly InputPort[]
666
+ }
667
+ | {
668
+ readonly before: Pick<WaitNode, 'inputDefinitions' | 'prompt' | 'autoContinue'>
669
+ readonly kind: 'graph.node.resolution.set'
670
+ readonly nodeId: string
671
+
672
+ readonly value: Pick<WaitNode, 'inputDefinitions' | 'prompt' | 'autoContinue'>
673
+ }
674
+ | {
675
+ readonly before: Pick<Extract<TriggerNode, { readonly kind: 'webhook' }>, 'bodyFields' | 'method' | 'options'>
676
+ readonly kind: 'graph.node.webhook.set'
677
+ readonly nodeId: string
678
+
679
+ readonly value: Pick<Extract<TriggerNode, { readonly kind: 'webhook' }>, 'bodyFields' | 'method' | 'options'>
680
+ }
681
+ | {
682
+ readonly before?: FixedInputValue
683
+ readonly kind: 'graph.trigger.config.set'
684
+ readonly name: string
685
+ readonly nodeId: string
686
+ readonly value?: FixedInputValue
687
+ }
688
+ | {
689
+ readonly before: readonly TriggerSchedule[]
690
+ readonly kind: 'graph.trigger.schedule.set'
691
+ readonly nodeId: string
692
+ readonly value: readonly TriggerSchedule[]
693
+ }
694
+ | { readonly kind: 'module.create'; readonly module: CodeModule; readonly moduleId: string }
695
+ | { readonly kind: 'module.delete'; readonly moduleId: string }
696
+ | { readonly before: string; readonly kind: 'module.rename'; readonly moduleId: string; readonly name: string }
697
+ | {
698
+ readonly beforeImports: readonly string[]
699
+ readonly beforeSource: string
700
+ readonly imports: readonly string[]
701
+ readonly kind: 'module.source.replace'
702
+ readonly moduleId: string
703
+ readonly source: string
704
+ }
705
+ | {
706
+ readonly kind: 'graph.node.task.set'
707
+ readonly nodeId: string
708
+
709
+ readonly before: TaskDefinition
710
+ readonly value: TaskDefinition
711
+ }
712
+
713
+ export class FlowChangeError extends Error {
714
+ constructor(message: string) {
715
+ super(message)
716
+ this.name = 'FlowChangeError'
717
+ }
718
+ }
719
+
720
+ function invalid(message: string): never {
721
+ throw new FlowChangeError(message)
722
+ }
723
+
724
+ export function applyFlowChanges(content: RevisionContent, operations: readonly ChangeOperation[]): RevisionContent {
725
+ const source =
726
+ content.modelVersion != currentFlowModelVersion || Object.values(content.document.graph.nodes).some((node) => node.kind == 'manual')
727
+ ? decodeRevisionContent(content)
728
+ : content
729
+ const document = { ...source.document }
730
+ const modules = { ...source.modules }
731
+ for (const operation of operations) {
732
+ switch (operation.kind) {
733
+ case 'graph.trigger.sources.set': {
734
+ const graph = document.graph
735
+ const node = graph.nodes[operation.nodeId]
736
+ if (node?.kind != 'error') invalid('The Flow Error node does not exist.')
737
+ if (!dequal(node.sourceFlowIds, operation.before)) invalid('The Flow Error node’s sources changed before this operation was applied.')
738
+ const { sourceFlowIds: _, ...base } = node
739
+ const updated = operation.value == null ? base : { ...base, sourceFlowIds: operation.value }
740
+ document.graph = { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: updated } }
741
+ break
742
+ }
743
+ case 'binding.create':
744
+ if (document.bindings[operation.bindingId] != null) invalid('A Binding with this ID already exists.')
745
+ document.bindings = { ...document.bindings, [operation.bindingId]: operation.binding }
746
+ break
747
+ case 'binding.delete': {
748
+ if (document.bindings[operation.bindingId] == null) invalid('The Binding does not exist.')
749
+ const bindings = { ...document.bindings }
750
+ delete bindings[operation.bindingId]
751
+ document.bindings = bindings
752
+ break
753
+ }
754
+ case 'binding.target.set': {
755
+ const binding = document.bindings[operation.bindingId]
756
+ if (binding == null) invalid('The Binding does not exist.')
757
+ if (binding.target != operation.before) invalid('The Binding target changed before this operation was applied.')
758
+ document.bindings = { ...document.bindings, [operation.bindingId]: { ...binding, target: operation.value } }
759
+ break
760
+ }
761
+ case 'graph.edge.connect': {
762
+ const graph = document.graph
763
+ if (graph.nodes[operation.edge.source] == null) invalid('The source Node does not exist.')
764
+ if (graph.nodes[operation.edge.source]?.kind == 'outputs') invalid('Outputs cannot have downstream execution edges.')
765
+ const node = graph.nodes[operation.edge.target]
766
+ if (node == null || isTriggerNode(node)) invalid('The target Node does not accept execution dependencies.')
767
+ if (graph.edges.some((edge) => dequal(edge, operation.edge))) invalid('The Nodes are already connected.')
768
+ Object.assign(document, { graph: { ...graph, edges: [...graph.edges, operation.edge] } })
769
+ break
770
+ }
771
+ case 'graph.edge.disconnect': {
772
+ const graph = document.graph
773
+ const edges = graph.edges.filter((edge) => !dequal(edge, operation.edge))
774
+ if (edges.length == graph.edges.length) invalid('The Nodes are not connected.')
775
+ Object.assign(document, { graph: { ...graph, edges } })
776
+ break
777
+ }
778
+ case 'graph.node.additional-inputs.set': {
779
+ const graph = document.graph
780
+ const node = graph.nodes[operation.nodeId]
781
+ if (node?.kind != 'task') invalid('The Task Node does not exist.')
782
+ if (!dequal(node.additionalInputs, operation.before)) invalid('The Task Node inputs changed before this operation was applied.')
783
+ const { additionalInputs: _, ...rest } = node
784
+ const updated: TaskNode = operation.value == null ? rest : { ...rest, additionalInputs: operation.value }
785
+ Object.assign(document, { graph: { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: updated } } })
786
+ break
787
+ }
788
+ case 'graph.node.condition.set': {
789
+ const graph = document.graph
790
+ const node = graph.nodes[operation.nodeId]
791
+ if (node?.kind != 'condition') invalid('The Condition Node does not exist.')
792
+ if (!dequal(node.cases, operation.before.cases) || node.matchMode != operation.before.matchMode) {
793
+ invalid('The Condition Node changed before this operation was applied.')
794
+ }
795
+ const updated: ConditionNode = { ...node, ...operation.value }
796
+ Object.assign(document, { graph: { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: updated } } })
797
+ break
798
+ }
799
+ case 'graph.node.replace': {
800
+ const graph = document.graph
801
+ if (!dequal(graph.nodes[operation.nodeId], operation.before)) invalid('The Node changed before this operation was applied.')
802
+ if (operation.node.kind != operation.before.kind) invalid('Replacing a Node cannot change its kind.')
803
+ if (operation.node.kind == 'task' && 'moduleId' in operation.node.task && operation.node.task.capabilities !== undefined)
804
+ decodeTaskCapabilities(operation.node.task.capabilities)
805
+ const name = normalizeNodeName(operation.node.name ?? '')
806
+ const issue = nodeNameIssue(graph, operation.nodeId, name)
807
+ if (issue != null) invalid(`Node name is ${issue}.`)
808
+ const node = name == operation.node.name ? operation.node : { ...operation.node, name }
809
+ Object.assign(document, { graph: { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: node } } })
810
+ break
811
+ }
812
+ case 'graph.node.create': {
813
+ const graph = document.graph
814
+ if (graph.nodes[operation.nodeId] != null) invalid('A Node with this ID already exists in the target graph.')
815
+ if (operation.node.kind == 'error' && Object.values(graph.nodes).some((node) => node.kind == 'error'))
816
+ invalid('A graph can contain only one Flow Error node.')
817
+ if (
818
+ (operation.node.kind == 'manual' || operation.node.kind == 'start') &&
819
+ Object.values(graph.nodes).some((node) => node.kind == 'manual' || node.kind == 'start')
820
+ ) {
821
+ invalid('A graph can contain only one Start Trigger.')
822
+ }
823
+ if (operation.node.kind == 'task' && 'moduleId' in operation.node.task && operation.node.task.capabilities !== undefined)
824
+ decodeTaskCapabilities(operation.node.task.capabilities)
825
+ if (operation.node.name == null) invalid('A Node name cannot be empty.')
826
+ if (operation.node.kind == 'outputs' && Object.values(graph.nodes).some((node) => node.kind == 'outputs'))
827
+ invalid('A graph can contain only one Outputs node.')
828
+ const name = normalizeNodeName(operation.node.name)
829
+ const issue = nodeNameIssue(graph, operation.nodeId, name)
830
+ if (issue == 'empty') invalid('A Node name cannot be empty.')
831
+ if (issue == 'duplicate') invalid('A Node with this name already exists in the target graph.')
832
+ const node = name == operation.node.name ? operation.node : { ...operation.node, name }
833
+ Object.assign(document, { graph: { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: node } } })
834
+ break
835
+ }
836
+ case 'graph.node.delete': {
837
+ const graph = document.graph
838
+ if (graph.nodes[operation.nodeId] == null) invalid('The Node does not exist in the target graph.')
839
+ const removed = new Set([operation.nodeId])
840
+ const nodes = Object.fromEntries(Object.entries(graph.nodes).filter(([nodeId]) => !removed.has(nodeId)))
841
+ Object.assign(document, {
842
+ graph: {
843
+ ...graph,
844
+ edges: graph.edges.filter((edge) => !removed.has(edge.source) && !removed.has(edge.target)),
845
+ nodes,
846
+ },
847
+ })
848
+ break
849
+ }
850
+ case 'graph.node.field.set': {
851
+ const graph = document.graph
852
+ const node = graph.nodes[operation.nodeId]
853
+ if (node == null) invalid('The Node does not exist in the target graph.')
854
+ if (
855
+ operation.field == 'onError' &&
856
+ operation.value != null &&
857
+ (!supportsNodeErrorHandling(node) || !['stop', 'error'].includes(String(operation.value)))
858
+ )
859
+ invalid('This node does not support this error handling setting.')
860
+ if (operation.field == 'retry' && operation.value != null && !supportsNodeRetry(node)) invalid('This node does not support retries.')
861
+ if (operation.field == 'connectionId' && node.kind != 'poll' && node.kind != 'integration') invalid('Only provider Triggers select a node Connection.')
862
+ if (!dequal(Reflect.get(node, operation.field), operation.before)) invalid('The Node field changed before this operation was applied.')
863
+ const updated = { ...node }
864
+ if (operation.field == 'name') {
865
+ if (typeof operation.value != 'string') invalid('A Node name cannot be empty.')
866
+ const name = normalizeNodeName(operation.value as string)
867
+ const issue = nodeNameIssue(graph, operation.nodeId, name)
868
+ if (issue == 'empty') invalid('A Node name cannot be empty.')
869
+ if (issue == 'duplicate') invalid('A Node with this name already exists in the target graph.')
870
+ Object.assign(updated, { name })
871
+ } else if (operation.value == null) Reflect.deleteProperty(updated, operation.field)
872
+ else Object.assign(updated, { [operation.field]: operation.value })
873
+ Object.assign(document, { graph: { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: updated } } })
874
+ break
875
+ }
876
+ case 'graph.node.input.set': {
877
+ const graph = document.graph
878
+ const node = graph.nodes[operation.nodeId]
879
+ if (node == null || isTriggerNode(node)) invalid('The Node does not accept inputs.')
880
+ if (!dequal(nodeInputMappings(node)[operation.handle], operation.before)) invalid('The Node input changed before this operation was applied.')
881
+ const inputs = { ...nodeInputMappings(node) }
882
+ if (operation.value == null) delete inputs[operation.handle]
883
+ else inputs[operation.handle] = operation.value
884
+ if (node.kind == 'outputs') {
885
+ document.graph = { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: { ...node, outputMappings: inputs } } }
886
+ break
887
+ }
888
+ Object.assign(document, {
889
+ graph: {
890
+ ...graph,
891
+ nodes: {
892
+ ...graph.nodes,
893
+ [operation.nodeId]: node.kind == 'condition' ? setConditionInput(node, operation.handle, operation.value) : { ...node, inputs },
894
+ },
895
+ },
896
+ })
897
+ break
898
+ }
899
+ case 'graph.node.task.capabilities.set': {
900
+ const graph = document.graph
901
+ const node = graph.nodes[operation.nodeId]
902
+ if (node?.kind != 'task' || !('moduleId' in node.task)) invalid('The inline Task Node does not exist.')
903
+ if (!dequal(node.task.capabilities, operation.before)) invalid('The inline Task capabilities changed before this operation was applied.')
904
+ const task = { ...node.task }
905
+ if (operation.value === undefined) delete task.capabilities
906
+ else task.capabilities = decodeTaskCapabilities(operation.value)
907
+ Object.assign(document, { graph: { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: { ...node, task } } } })
908
+ break
909
+ }
910
+ case 'graph.node.task.name.set': {
911
+ const graph = document.graph
912
+ const node = graph.nodes[operation.nodeId]
913
+ if (node?.kind != 'task' || !('moduleId' in node.task)) invalid('The inline Task Node does not exist.')
914
+ if (node.task.name != operation.before) invalid('The inline Task name changed before this operation was applied.')
915
+ const updated = { ...node, task: { ...node.task, name: operation.value } }
916
+ Object.assign(document, { graph: { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: updated } } })
917
+ break
918
+ }
919
+ case 'graph.node.task.ports.set': {
920
+ const graph = document.graph
921
+ const node = graph.nodes[operation.nodeId]
922
+ if (node?.kind != 'task' || !('moduleId' in node.task)) invalid('The inline Task Node does not exist.')
923
+ if (!dequal({ inputs: node.task.inputs, outputs: node.task.outputs }, operation.before)) {
924
+ invalid('The inline Task ports changed before this operation was applied.')
925
+ }
926
+ const updated = { ...node, task: { ...node.task, inputs: operation.value.inputs, outputs: operation.value.outputs } }
927
+ Object.assign(document, { graph: { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: updated } } })
928
+ break
929
+ }
930
+ case 'graph.node.values.set': {
931
+ const graph = document.graph
932
+ const node = graph.nodes[operation.nodeId]
933
+ if (node?.kind != 'value') invalid('The Value Node does not exist.')
934
+ if (!dequal(node.values, operation.before)) invalid('The Value Node changed before this operation was applied.')
935
+ Object.assign(document, { graph: { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: { ...node, values: operation.value } } } })
936
+ break
937
+ }
938
+ case 'graph.node.resolution.set': {
939
+ const graph = document.graph
940
+ const node = graph.nodes[operation.nodeId]
941
+ if (
942
+ (node?.kind != 'wait' && node?.kind != 'approval') ||
943
+ !dequal(
944
+ {
945
+ inputDefinitions: node.inputDefinitions,
946
+ prompt: node.prompt,
947
+ ...(node.kind == 'wait' && node.autoContinue != null ? { autoContinue: node.autoContinue } : {}),
948
+ },
949
+ operation.before,
950
+ )
951
+ ) {
952
+ invalid('The resolution node changed before this operation was applied.')
953
+ }
954
+ if (node.kind == 'approval' && operation.value.autoContinue != null) invalid('Approval does not support automatic continuation.')
955
+ const updated: ResolutionNode = { ...node, ...operation.value }
956
+ if (updated.kind == 'wait' && operation.value.autoContinue == null) Reflect.deleteProperty(updated, 'autoContinue')
957
+ document.graph = { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: updated } }
958
+ break
959
+ }
960
+ case 'graph.node.webhook.set': {
961
+ const graph = document.graph
962
+ const node = graph.nodes[operation.nodeId]
963
+ if (node?.kind != 'webhook') invalid('The Webhook Node does not exist.')
964
+ if (
965
+ node.method != operation.before.method ||
966
+ !dequal(node.bodyFields, operation.before.bodyFields) ||
967
+ !dequal(node.options, operation.before.options)
968
+ ) {
969
+ invalid('The Webhook Node changed before this operation was applied.')
970
+ }
971
+ const { options: _, ...rest } = node
972
+ const updated: TriggerNode =
973
+ operation.value.options == null
974
+ ? { ...rest, bodyFields: operation.value.bodyFields, method: operation.value.method }
975
+ : { ...node, ...operation.value }
976
+ Object.assign(document, { graph: { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: updated } } })
977
+ break
978
+ }
979
+ case 'graph.trigger.config.set': {
980
+ const graph = document.graph
981
+ const node = graph.nodes[operation.nodeId]
982
+ if (node == null || (node.kind != 'integration' && node.kind != 'poll')) invalid('The configurable Trigger Node does not exist.')
983
+ if (!dequal(node.config[operation.name], operation.before)) invalid('The Trigger configuration changed before this operation was applied.')
984
+ const config = { ...node.config }
985
+ if (operation.value === undefined) delete config[operation.name]
986
+ else config[operation.name] = operation.value
987
+ document.graph = { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: { ...node, config } } }
988
+ break
989
+ }
990
+ case 'graph.trigger.schedule.set': {
991
+ const graph = document.graph
992
+ const node = graph.nodes[operation.nodeId]
993
+ if (node == null || (node.kind != 'cron' && node.kind != 'poll')) invalid('The scheduled Trigger Node does not exist.')
994
+ const before = node.kind == 'cron' ? node.cronTimes : node.pollTimes
995
+ if (!dequal(before, operation.before)) invalid('The Trigger schedule changed before this operation was applied.')
996
+ const updated: TriggerNode = node.kind == 'cron' ? { ...node, cronTimes: operation.value } : { ...node, pollTimes: operation.value }
997
+ document.graph = { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: updated } }
998
+ break
999
+ }
1000
+ case 'module.create':
1001
+ if (modules[operation.moduleId] != null) invalid('A CodeModule with this ID already exists.')
1002
+ modules[operation.moduleId] = operation.module
1003
+ break
1004
+ case 'module.delete':
1005
+ if (modules[operation.moduleId] == null) invalid('The CodeModule does not exist.')
1006
+ delete modules[operation.moduleId]
1007
+ break
1008
+ case 'module.rename': {
1009
+ const module = modules[operation.moduleId]
1010
+ if (module == null) invalid('The CodeModule does not exist.')
1011
+ if (module.name != operation.before) invalid('The CodeModule name changed before this operation was applied.')
1012
+ modules[operation.moduleId] = { ...module, name: operation.name }
1013
+ break
1014
+ }
1015
+ case 'module.source.replace': {
1016
+ const module = modules[operation.moduleId]
1017
+ if (module == null) invalid('The CodeModule does not exist.')
1018
+ if (module.source != operation.beforeSource || !dequal(module.imports, operation.beforeImports)) {
1019
+ invalid('The CodeModule source changed before this operation was applied.')
1020
+ }
1021
+ modules[operation.moduleId] = { ...module, imports: operation.imports, source: operation.source }
1022
+ break
1023
+ }
1024
+ case 'graph.node.task.set': {
1025
+ const graph = document.graph
1026
+ const node = graph.nodes[operation.nodeId]
1027
+ if (node?.kind != 'task') invalid('The Task Node does not exist.')
1028
+ if (!dequal(node.task, operation.before)) invalid('The Task configuration changed before this operation was applied.')
1029
+ document.graph = { ...graph, nodes: { ...graph.nodes, [operation.nodeId]: { ...node, task: operation.value } } }
1030
+ break
1031
+ }
1032
+ }
1033
+ }
1034
+ assertOpenApiAuthBindings(document)
1035
+ return upgradeDecodedRevisionContent({ document, modelVersion: currentFlowModelVersion, modules })
1036
+ }