@oomol-lab/open-flow 0.1.0-beta.72 → 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 +90 -42
  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,474 @@
1
+ import { decisionTaskIssues } from '../../decision/common/decision.ts'
2
+ import { openApiIssues, authHandles } from '../../openapi/common/openapi.ts'
3
+ import { nodeWorkflowReferences } from '../../workflow/common/workflow.ts'
4
+ import { isTriggerNode } from './change.ts'
5
+ export { renderPrompt } from './promptTemplate.ts'
6
+ export { connectionUsage, removeConnectionUsage } from './connectionUsage.ts'
7
+ import { matchesTriggerOutputs, normalizeTriggerOutputs } from '../../trigger/common/contract.ts'
8
+ import { nodeInputMappings } from './condition.ts'
9
+ import { connectionUsage } from './connectionUsage.ts'
10
+ export { matchesTriggerOutputs, normalizeTriggerOutputs, triggerOutputDefinitions, triggerOutputPorts } from '../../trigger/common/contract.ts'
11
+ import type { EngineContract } from '../../execution/common/engineContract.ts'
12
+ import type { RuntimeProgram } from '../../execution/common/runtime.ts'
13
+ import type { ConnectorActionCapability, ConnectorCapability, Graph, InputMapping, JsonValue, Port, RevisionContent, SchemaMismatch } from './change.ts'
14
+
15
+ import { findEngineContract } from '../../execution/common/engineContract.ts'
16
+ import { agentConfigIssues } from './agent.ts'
17
+ import { decodeTaskCapabilities } from './change.ts'
18
+ import { canonicalJsonBytes, canonicalModule, canonicalRevisionGraph, digestBytes } from './encoding.ts'
19
+ import { nodeInputPorts, validateFlowGraph } from './graph.ts'
20
+ import { inputValue } from './inputValue.ts'
21
+ import { compareDiagnostics, validateModuleGraph } from './modules.ts'
22
+ import { hasRetiredRef } from './schema.ts'
23
+ export { availableOutputs, graphOrder, nodeInputPorts } from './graph.ts'
24
+ export { validateModules } from './modules.ts'
25
+ export { matchesSchema, schemaValidationErrors, variableInputCompatible } from './schema.ts'
26
+ export { agentInput, agentToolInput, agentToolSchema } from './agent.ts'
27
+
28
+ export interface SemanticClosure {
29
+ readonly dependencies: {
30
+ readonly bindings: ReadonlySet<string>
31
+ readonly nodes: ReadonlySet<string>
32
+ readonly modules: ReadonlySet<string>
33
+ }
34
+ readonly digest: string
35
+ }
36
+
37
+ function entries<T>(value: Readonly<Record<string, T>>): readonly (readonly [string, T])[] {
38
+ return Object.keys(value)
39
+ .toSorted()
40
+ .map((key) => [key, value[key]!] as const)
41
+ }
42
+
43
+ export function flowDependencies(content: RevisionContent, triggerId?: string): SemanticClosure['dependencies'] {
44
+ if (triggerId != null) return flowDependencies(runRevision(content, triggerId))
45
+ const bindings = new Set<string>()
46
+ const modules = new Set<string>()
47
+
48
+ function visitModule(id: string): void {
49
+ if (modules.has(id)) return
50
+ modules.add(id)
51
+ const module = content.modules[id]
52
+ if (module == null) return
53
+ for (const imported of module.imports.toSorted()) visitModule(imported)
54
+ }
55
+
56
+ function visitInputMappings(value: Readonly<Record<string, InputMapping>>): void {
57
+ for (const mapping of Object.values(value)) {
58
+ if (mapping.kind != 'sources') continue
59
+ for (const source of mapping.sources) {
60
+ if (source.kind != 'binding') continue
61
+ bindings.add(source.bindingId)
62
+ }
63
+ }
64
+ }
65
+
66
+ function visitGraph(value: Graph): void {
67
+ for (const [, node] of entries(value.nodes)) {
68
+ if (!isTriggerNode(node)) visitInputMappings(nodeInputMappings(node))
69
+ switch (node.kind) {
70
+ case 'condition':
71
+ break
72
+ case 'task':
73
+ if ('moduleId' in node.task) visitModule(node.task.moduleId)
74
+ break
75
+ case 'outputs':
76
+ case 'value':
77
+ break
78
+ case 'approval':
79
+ case 'wait':
80
+ break
81
+ case 'poll':
82
+ case 'integration':
83
+ case 'cron':
84
+ case 'error':
85
+ case 'manual':
86
+ case 'start':
87
+ case 'webhook':
88
+ break
89
+ }
90
+ }
91
+ }
92
+
93
+ visitGraph(content.document.graph)
94
+
95
+ return { bindings, modules, nodes: new Set(Object.keys(content.document.graph.nodes)) }
96
+ }
97
+
98
+ export async function flowClosure(content: RevisionContent): Promise<SemanticClosure> {
99
+ const dependencies = flowDependencies(content)
100
+ return { dependencies, digest: await digestBytes(closureBytes(content, dependencies)) }
101
+ }
102
+
103
+ /** Canonical semantic bytes, also used by transactional storage upgrades. */
104
+ export function encodeFlowClosure(content: RevisionContent, triggerId?: string): Uint8Array {
105
+ const scoped = triggerId == null ? content : runRevision(content, triggerId)
106
+ return closureBytes(scoped, flowDependencies(scoped))
107
+ }
108
+
109
+ function closureBytes(content: RevisionContent, dependencies: SemanticClosure['dependencies']): Uint8Array {
110
+ const { bindings, modules } = dependencies
111
+ return canonicalJsonBytes({
112
+ bindings: Object.fromEntries([...bindings].toSorted().map((id) => [id, content.document.bindings[id] ?? null])),
113
+ graph: canonicalRevisionGraph(content, content.document.graph),
114
+ kind: 'open-flow-semantic-closure',
115
+ ...(content.modelVersion < 6 ? { subflows: {} } : {}),
116
+ modelVersion: content.modelVersion,
117
+ modules: Object.fromEntries([...modules].toSorted().map((id) => [id, content.modules[id] == null ? null : canonicalModule(content.modules[id])])),
118
+ ...(content.modelVersion < 6 ? { tasks: {} } : {}),
119
+ version: 2,
120
+ })
121
+ }
122
+
123
+ export function variableBindings(revision: RevisionContent, bindingIds: Iterable<string>): Readonly<Record<string, string>> {
124
+ return Object.fromEntries(
125
+ [...bindingIds].flatMap((bindingId) => {
126
+ const binding = revision.document.bindings[bindingId]
127
+ return binding?.kind == 'variable' ? [[bindingId, binding.target]] : []
128
+ }),
129
+ )
130
+ }
131
+
132
+ export interface FlowResourceReferences {
133
+ readonly calledFlowIds?: readonly string[]
134
+ readonly variableNames: readonly string[]
135
+ readonly connections: readonly { readonly providerId: string; readonly connectionId: string }[]
136
+ readonly errorSourceFlowIds: readonly string[]
137
+ }
138
+
139
+ export function flowResourceReferences(content: RevisionContent): FlowResourceReferences {
140
+ const connections = new Map<string, { readonly providerId: string; readonly connectionId: string }>()
141
+ for (const use of connectionUsage(content.document)) {
142
+ if (use.connectionId == null || use.connectionId === '') continue
143
+ connections.set(JSON.stringify([use.providerId, use.connectionId]), { providerId: use.providerId, connectionId: use.connectionId })
144
+ }
145
+ return {
146
+ calledFlowIds: [
147
+ ...new Set(
148
+ Object.values(content.document.graph.nodes).flatMap((node) =>
149
+ nodeWorkflowReferences(node)
150
+ .map(({ target }) => target.flowId)
151
+ .filter(Boolean),
152
+ ),
153
+ ),
154
+ ].toSorted(),
155
+ variableNames: [...new Set(Object.values(variableBindings(content, flowDependencies(content).bindings)))].toSorted(),
156
+ connections: [...connections].toSorted(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0)).map(([, value]) => value),
157
+ errorSourceFlowIds: [
158
+ ...new Set(Object.values(content.document.graph.nodes).flatMap((node) => (node.kind == 'error' ? (node.sourceFlowIds ?? []) : []))),
159
+ ].toSorted(),
160
+ }
161
+ }
162
+
163
+ export interface Diagnostic {
164
+ readonly code: string
165
+ readonly column: number
166
+ readonly fields?: readonly string[]
167
+ readonly line: number
168
+ readonly message: string
169
+ readonly mismatch?: SchemaMismatch
170
+ readonly path: string
171
+ readonly values?: Readonly<Record<string, string | number>>
172
+ }
173
+
174
+ export interface FlowValidation {
175
+ readonly closure: SemanticClosure
176
+ readonly diagnostics: readonly Diagnostic[]
177
+ readonly valid: boolean
178
+ }
179
+
180
+ export type FlowInputsValidation = 'invalid' | 'valid'
181
+
182
+ export function validRunTrigger(revision: RevisionContent, value: unknown): boolean {
183
+ if (value == null || typeof value != 'object' || Array.isArray(value)) return false
184
+ const trigger = value as Readonly<Record<string, unknown>>
185
+ if (Object.keys(trigger).some((key) => key != 'nodeId' && key != 'outputs') || typeof trigger.nodeId != 'string' || !Object.hasOwn(trigger, 'outputs'))
186
+ return false
187
+ const node = revision.document.graph.nodes[trigger.nodeId]
188
+ return node != null && isTriggerNode(node) && matchesTriggerOutputs(node, trigger.outputs)
189
+ }
190
+
191
+ export function normalizeRunTrigger(
192
+ revision: RevisionContent,
193
+ value: unknown,
194
+ ): { readonly nodeId: string; readonly outputs: Readonly<Record<string, JsonValue>> } | undefined {
195
+ if (value == null || typeof value != 'object' || Array.isArray(value)) return
196
+ const trigger = value as Readonly<Record<string, unknown>>
197
+ if (Object.keys(trigger).some((key) => key != 'nodeId' && key != 'outputs') || typeof trigger.nodeId != 'string' || !Object.hasOwn(trigger, 'outputs')) return
198
+ const node = revision.document.graph.nodes[trigger.nodeId]
199
+ if (node == null || !isTriggerNode(node)) return
200
+ const outputs = normalizeTriggerOutputs(node, trigger.outputs)
201
+ return outputs == null ? undefined : { nodeId: trigger.nodeId, outputs }
202
+ }
203
+
204
+ export function validateFlowInputs(revision: RevisionContent, value: unknown): FlowInputsValidation {
205
+ if (value == null || typeof value != 'object' || Array.isArray(value)) return 'invalid'
206
+ const graph = revision.document.graph
207
+ for (const [nodeId, candidate] of Object.entries(value)) {
208
+ const node = graph.nodes[nodeId]
209
+ if (node == null || isTriggerNode(node) || node.kind == 'condition' || candidate == null || typeof candidate != 'object' || Array.isArray(candidate)) {
210
+ return 'invalid'
211
+ }
212
+ const inputs = nodeInputPorts(node)
213
+ for (const handle of Object.keys(candidate)) {
214
+ const port = inputs[handle]
215
+ if (port == null || hasRetiredRef(port.jsonSchema) || nodeInputMappings(node)[handle] != null || Object.hasOwn(port, 'value')) return 'invalid'
216
+ }
217
+ }
218
+ return 'valid'
219
+ }
220
+
221
+ export async function validateFlow(revision: RevisionContent, engine: EngineContract): Promise<FlowValidation> {
222
+ const closure = await flowClosure(revision)
223
+ const checked = validateModuleGraph(revision, [...closure.dependencies.modules], engine)
224
+ checked.diagnostics.push(...validateFlowGraph(revision))
225
+ const missingEntryModules = new Set<string>()
226
+ for (const [nodeId, node] of Object.entries(revision.document.graph.nodes)) {
227
+ if (node.kind != 'task' || !('moduleId' in node.task)) continue
228
+ if (revision.modules[node.task.moduleId] == null) {
229
+ checked.diagnostics.push({
230
+ code: 'task.module-missing',
231
+ column: 0,
232
+ line: 1,
233
+ message: `Inline Task "${nodeId}" references missing CodeModule "${node.task.moduleId}".`,
234
+ path: `/document/graph/nodes/${nodeId}/task/moduleId`,
235
+ values: { moduleId: node.task.moduleId, nodeId },
236
+ })
237
+ } else if (checked.analysis.get(node.task.moduleId)?.exports.has('default') == false && !missingEntryModules.has(node.task.moduleId)) {
238
+ missingEntryModules.add(node.task.moduleId)
239
+ checked.diagnostics.push({
240
+ code: 'task.missing-entry',
241
+ column: 0,
242
+ line: 1,
243
+ message: `CodeModule "${node.task.moduleId}" used by an Inline Task must export a default function.`,
244
+ path: `/modules/${node.task.moduleId}/source`,
245
+ values: { moduleId: node.task.moduleId },
246
+ })
247
+ }
248
+ try {
249
+ decodeTaskCapabilities(node.task.capabilities === undefined ? [] : node.task.capabilities)
250
+ } catch {
251
+ checked.diagnostics.push({
252
+ code: 'task.capability-incomplete',
253
+ column: 0,
254
+ line: 1,
255
+ message: `Inline Task "${nodeId}" has an incomplete Connector Capability.`,
256
+ path: `/document/graph/nodes/${nodeId}/task/capabilities`,
257
+ values: { nodeId },
258
+ })
259
+ }
260
+ }
261
+ for (const [nodeId, node] of Object.entries(revision.document.graph.nodes)) {
262
+ if (node.kind != 'task' || !('executor' in node.task)) continue
263
+ const task = node.task
264
+ for (const issue of decisionTaskIssues(task))
265
+ checked.diagnostics.push({
266
+ code: 'decision.config-invalid',
267
+ column: 0,
268
+ line: 1,
269
+ message: issue.message,
270
+ path: `/document/graph/nodes/${nodeId}/task/executor`,
271
+ })
272
+ for (const message of openApiIssues(task))
273
+ checked.diagnostics.push({ code: 'openapi.config-invalid', column: 0, line: 1, message, path: `/document/graph/nodes/${nodeId}/task/executor` })
274
+ if (task.executor.kind == 'openapi') {
275
+ const handles = authHandles(task.executor.auth)
276
+ for (const handle of handles) {
277
+ const mapping = node.inputs[handle]
278
+ if (mapping?.kind != 'sources' || mapping.sources.length == 0)
279
+ checked.diagnostics.push({
280
+ code: 'openapi.auth-source',
281
+ column: 0,
282
+ line: 1,
283
+ message: 'Authentication requires a deployment variable or upstream output.',
284
+ path: `/document/graph/nodes/${nodeId}/inputs/${handle}`,
285
+ })
286
+ }
287
+ }
288
+ for (const message of agentConfigIssues(task)) {
289
+ checked.diagnostics.push({ code: 'agent.config-invalid', column: 0, line: 1, message, path: `/document/graph/nodes/${nodeId}/task/executor` })
290
+ }
291
+ if (task.executor.kind == 'connector' && task.executor.action == 'leina.send_notification') {
292
+ const mapping = node.inputs.leinaId
293
+ const value = inputValue(mapping, nodeInputPorts(node).leinaId?.value)
294
+ if ((mapping?.kind != 'sources' || mapping.sources.length == 0) && (typeof value != 'string' || value.trim().length == 0)) {
295
+ checked.diagnostics.push({
296
+ code: 'leina.robot-required',
297
+ column: 0,
298
+ line: 1,
299
+ message: 'Select a Leina robot or bind its identifier to an input source.',
300
+ path: `/document/graph/nodes/${nodeId}/inputs/leinaId`,
301
+ })
302
+ }
303
+ }
304
+ if (task.executor.kind == 'connector' && task.executor.action.length == 0) {
305
+ checked.diagnostics.push({
306
+ code: 'task.connector-incomplete',
307
+ column: 0,
308
+ line: 1,
309
+ message: `Connector Task "${nodeId}" requires an action.`,
310
+ path: `/document/graph/nodes/${nodeId}/task/executor`,
311
+ values: { nodeId },
312
+ })
313
+ }
314
+ }
315
+ const diagnostics = checked.diagnostics.toSorted(compareDiagnostics)
316
+ return { closure, diagnostics, valid: diagnostics.length == 0 }
317
+ }
318
+
319
+ export interface PreparedFlow {
320
+ readonly inputDefs: readonly Port[]
321
+ readonly outputDefs: readonly Port[]
322
+ readonly outputMappings: Readonly<Record<string, InputMapping>>
323
+ readonly closureDigest: string
324
+ readonly engineContract: string
325
+ readonly graph: Graph
326
+ readonly modules: RevisionContent['modules']
327
+ }
328
+
329
+ export type PrepareFlowResult =
330
+ | { readonly kind: 'engine-unsupported' }
331
+ | { readonly kind: 'flow-invalid'; readonly validation: FlowValidation }
332
+ | { readonly flow: PreparedFlow; readonly kind: 'prepared'; readonly validation: FlowValidation }
333
+
334
+ function runRevision(revision: RevisionContent, triggerId: string): RevisionContent {
335
+ const graph = revision.document.graph
336
+ const reachable = new Set([triggerId])
337
+ for (const nodeId of reachable) {
338
+ for (const edge of graph.edges) if (edge.source == nodeId) reachable.add(edge.target)
339
+ }
340
+ function inputs(nodeId: string, mappings: Readonly<Record<string, InputMapping>>): Readonly<Record<string, InputMapping>> {
341
+ const ancestors = new Set<string>()
342
+ for (const edge of graph.edges) if (edge.target == nodeId) ancestors.add(edge.source)
343
+ for (const ancestor of ancestors) {
344
+ for (const edge of graph.edges) if (edge.target == ancestor) ancestors.add(edge.source)
345
+ }
346
+ return Object.fromEntries(
347
+ Object.entries(mappings).map(([handle, mapping]) => [
348
+ handle,
349
+ mapping.kind != 'sources'
350
+ ? mapping
351
+ : {
352
+ ...mapping,
353
+ sources: mapping.sources.filter(
354
+ (source) => source.kind != 'node' || graph.nodes[source.nodeId] == null || reachable.has(source.nodeId) || !ancestors.has(source.nodeId),
355
+ ),
356
+ },
357
+ ]),
358
+ )
359
+ }
360
+ const nodes: Record<string, Graph['nodes'][string]> = {}
361
+ for (const nodeId of reachable) {
362
+ const node = graph.nodes[nodeId]
363
+ if (node == null) continue
364
+ nodes[nodeId] =
365
+ node.kind == 'outputs'
366
+ ? { ...node, outputMappings: inputs(nodeId, node.outputMappings) }
367
+ : isTriggerNode(node)
368
+ ? node
369
+ : {
370
+ ...node,
371
+ inputs: inputs(nodeId, node.inputs),
372
+ }
373
+ }
374
+ const content = {
375
+ ...revision,
376
+ document: {
377
+ ...revision.document,
378
+ graph: { nodes, edges: graph.edges.filter((edge) => reachable.has(edge.source)) },
379
+ },
380
+ }
381
+ const { bindings } = flowDependencies(content)
382
+ return {
383
+ ...content,
384
+ document: { ...content.document, bindings: Object.fromEntries(Object.entries(content.document.bindings).filter(([id]) => bindings.has(id))) },
385
+ }
386
+ }
387
+
388
+ export async function prepareFlow(revision: RevisionContent, engineContract: string, triggerId?: string): Promise<PrepareFlowResult> {
389
+ const engine = findEngineContract(engineContract)
390
+ if (engine == null) return { kind: 'engine-unsupported' }
391
+ if (!engine.workflowTools && Object.values(revision.document.graph.nodes).some((node) => nodeWorkflowReferences(node).some((ref) => ref.tool != null)))
392
+ return { kind: 'engine-unsupported' }
393
+ if (triggerId != null) {
394
+ const trigger = revision.document.graph.nodes[triggerId]
395
+ if (trigger == null || !isTriggerNode(trigger))
396
+ return {
397
+ kind: 'flow-invalid',
398
+ validation: {
399
+ closure: await flowClosure(revision),
400
+ diagnostics: [
401
+ {
402
+ code: 'graph.trigger-invalid',
403
+ column: 0,
404
+ line: 1,
405
+ message: 'Select an existing Trigger node.',
406
+ path: '/document/graph',
407
+ values: { nodeId: triggerId },
408
+ },
409
+ ],
410
+ valid: false,
411
+ },
412
+ }
413
+ revision = runRevision(revision, triggerId)
414
+ }
415
+ if (
416
+ !engine.webhookResponses &&
417
+ Object.values(revision.document.graph.nodes).some(
418
+ (node) => node.kind === 'webhook-response' || (node.kind === 'webhook' && node.options?.responseBody?.kind === 'webhook-response'),
419
+ )
420
+ )
421
+ return { kind: 'engine-unsupported' }
422
+ if (!engine.waitAutoContinue && Object.values(revision.document.graph.nodes).some((node) => node.kind == 'wait' && node.autoContinue != null))
423
+ return { kind: 'engine-unsupported' }
424
+ const validation = await validateFlow(revision, engine)
425
+ if (!validation.valid) return { kind: 'flow-invalid', validation }
426
+ const { closure } = validation
427
+ const start = Object.values(revision.document.graph.nodes).find((node) => node.kind == 'start')
428
+ const outputs = Object.values(revision.document.graph.nodes).find((node) => node.kind == 'outputs')
429
+ return {
430
+ flow: {
431
+ closureDigest: closure.digest,
432
+ engineContract,
433
+ inputDefs: start?.inputDefs ?? [],
434
+ outputDefs: outputs?.outputDefs ?? [],
435
+ outputMappings: outputs?.outputMappings ?? {},
436
+ graph: revision.document.graph,
437
+ modules: Object.fromEntries([...closure.dependencies.modules].toSorted().map((id) => [id, revision.modules[id]!])),
438
+ },
439
+ kind: 'prepared',
440
+ validation,
441
+ }
442
+ }
443
+
444
+ export function createRuntimeProgram(prepared: PreparedFlow, entryModuleId: string, engineDigest: string): RuntimeProgram | undefined {
445
+ if (!Object.hasOwn(prepared.modules, entryModuleId)) return
446
+ return {
447
+ engineContract: prepared.engineContract,
448
+ engineDigest,
449
+ entryModuleId,
450
+ modules: prepared.modules,
451
+ }
452
+ }
453
+
454
+ export function agentActions(flow: Pick<PreparedFlow, 'graph'>): readonly ConnectorActionCapability[] {
455
+ return Object.values(flow.graph.nodes).flatMap((node) => {
456
+ if (node.kind != 'task' || !('executor' in node.task)) return []
457
+ const task = node.task
458
+ if (task.executor.kind != 'agent') return []
459
+ const notice = task.executor.notification
460
+ return [...task.executor.tools.filter((tool) => tool.kind != 'workflow'), ...(notice != null ? [notice] : [])]
461
+ .filter((tool) => tool.connectionId !== '')
462
+ .map((tool) => ({
463
+ kind: 'connector' as const,
464
+ action: tool.action,
465
+ connections: tool.connectionId == null ? [] : [{ connectionId: tool.connectionId }],
466
+ }))
467
+ })
468
+ }
469
+
470
+ export function codeActions(flow: Pick<PreparedFlow, 'graph'>): readonly ConnectorCapability[] {
471
+ return Object.values(flow.graph.nodes).flatMap((node) =>
472
+ node.kind == 'task' && 'moduleId' in node.task ? (node.task.capabilities ?? []).filter((item) => item.kind == 'connector') : [],
473
+ )
474
+ }
@@ -0,0 +1,35 @@
1
+ import type { NodeSource, PortDefinition } from './change.ts'
2
+
3
+ import { schemaObject } from './schema.ts'
4
+
5
+ /** Only explicitly declared, first-level object properties are selectable. */
6
+ export function sourceFields(output: PortDefinition): readonly { readonly field: string; readonly port: PortDefinition }[] {
7
+ const schema = schemaObject(output.jsonSchema)
8
+ if (schema == null) return []
9
+ const properties = schemaObject(schema.properties ?? false)
10
+ const types = Array.isArray(schema.type) ? schema.type : [schema.type]
11
+ if (properties == null || (schema.type !== undefined && !types.includes('object'))) return []
12
+ const required = Array.isArray(schema.required) ? schema.required : []
13
+ const missingParent = output.nullable || types.some((type) => type !== 'object')
14
+ return Object.entries(properties).map(([field, jsonSchema]) => {
15
+ const description = schemaObject(jsonSchema)?.description
16
+ return {
17
+ field,
18
+ port: {
19
+ ...(typeof description == 'string' ? { description } : {}),
20
+ jsonSchema,
21
+ nullable: missingParent || !required.includes(field),
22
+ },
23
+ }
24
+ })
25
+ }
26
+
27
+ export function sourcePort(output: PortDefinition, field: string | undefined): PortDefinition | undefined {
28
+ return field === undefined ? output : sourceFields(output).find((candidate) => candidate.field === field)?.port
29
+ }
30
+
31
+ /** Present a selected first-level field as a compact path from its output. */
32
+ export function sourceOutputLabel(source: Pick<NodeSource, 'output' | 'field' | 'system'>): string {
33
+ const output = source.system ? `$system / ${source.output}` : source.output
34
+ return source.field === undefined ? output : `${output} / ${source.field}`
35
+ }
@@ -0,0 +1,8 @@
1
+ import { z } from 'zod'
2
+
3
+ export const triggerScheduleSchema = z.array(
4
+ z.union([
5
+ z.object({ type: z.literal('cron'), expression: z.string(), timezone: z.string() }),
6
+ z.object({ type: z.literal('every'), unit: z.enum(['day', 'hour', 'minute', 'month', 'week']), value: z.number() }),
7
+ ]),
8
+ )
@@ -0,0 +1,30 @@
1
+ import type { WaitAutoContinue } from './change.ts'
2
+
3
+ import { z } from 'zod'
4
+ import { isTimeZone } from '../../localization/common/timeZone.ts'
5
+
6
+ /** Drafts retain incomplete values; semantic validation gates publication and execution. */
7
+ export const waitAutoContinueDraftSchema = z.discriminatedUnion('kind', [
8
+ z.strictObject({ kind: z.literal('after'), durationMs: z.number().nullable() }),
9
+ z.strictObject({
10
+ kind: z.literal('at'),
11
+ at: z.string(),
12
+ timezone: z.string().optional(),
13
+ }),
14
+ ])
15
+
16
+ /** Static business configuration; the deployment owns the allowed wait lifetime. */
17
+ export const waitAutoContinueSchema = z.discriminatedUnion('kind', [
18
+ waitAutoContinueDraftSchema.options[0].extend({ durationMs: z.number().int().positive().max(Number.MAX_SAFE_INTEGER) }),
19
+ waitAutoContinueDraftSchema.options[1].extend({
20
+ at: z.iso.datetime({ offset: true }),
21
+ timezone: z.string().refine(isTimeZone, 'Select a valid IANA timezone.').optional(),
22
+ }),
23
+ ])
24
+
25
+ /** Resolve one registration's intent; the deployment separately enforces its lifetime. */
26
+ export function waitAutoContinueAt(config: WaitAutoContinue, waitingSince: number): number {
27
+ const timing = waitAutoContinueSchema.parse(config)
28
+ const at = timing.kind == 'after' ? waitingSince + timing.durationMs : Date.parse(timing.at)
29
+ return Math.max(waitingSince, at)
30
+ }
@@ -0,0 +1,7 @@
1
+ export const webhookMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'] as const
2
+
3
+ export type WebhookMethod = (typeof webhookMethods)[number]
4
+
5
+ export function webhookSupportsBody(method: WebhookMethod): boolean {
6
+ return method !== 'GET'
7
+ }
@@ -0,0 +1,75 @@
1
+ import type { InputPort, JsonValue, Port, PortDefinition } from './change.ts'
2
+
3
+ export const webhookResponseTimeout = {
4
+ defaultMs: 30_000,
5
+ minMs: 1000,
6
+ maxMs: 60_000,
7
+ } as const
8
+
9
+ export const webhookStatusCodePort = { jsonSchema: { type: 'number' }, nullable: true } as const
10
+
11
+ export function webhookResponseAllowsBody(status: number): boolean {
12
+ return status !== 204 && status !== 205 && status !== 304
13
+ }
14
+
15
+ export const webhookHeaderValuePort = { jsonSchema: { type: ['string', 'number', 'boolean'] }, nullable: true } as const
16
+ export const webhookHeadersPort = {
17
+ jsonSchema: { type: 'object', additionalProperties: { type: ['string', 'number', 'boolean'] } },
18
+ nullable: true,
19
+ } as const
20
+
21
+ export function workflowOutputsPort(outputs: readonly Port[]): PortDefinition {
22
+ return {
23
+ jsonSchema: {
24
+ type: 'object',
25
+ properties: Object.fromEntries(outputs.map((port) => [port.handle, port.jsonSchema])),
26
+ additionalProperties: false,
27
+ required: outputs.map((port) => port.handle),
28
+ },
29
+ nullable: false,
30
+ } as const
31
+ }
32
+
33
+ /** Header names are case-insensitive; never silently combine duplicate business fields. */
34
+ export function webhookHeaderNameIssue(name: string, names: readonly string[]): 'invalid' | 'duplicate' | undefined {
35
+ if (!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(name)) return 'invalid'
36
+ if (names.some((candidate) => candidate.toLowerCase() === name.toLowerCase())) return 'duplicate'
37
+ }
38
+
39
+ /** Fixed inputs belong to the node, not author-supplied definitions. */
40
+ export const webhookResponseInputs: readonly InputPort[] = [
41
+ { handle: 'body', jsonSchema: {}, nullable: true, value: '' },
42
+ { handle: 'statusCode', jsonSchema: { type: 'number' }, nullable: false, value: 200 },
43
+ { handle: 'headers', jsonSchema: webhookHeadersPort.jsonSchema, nullable: false, value: {} },
44
+ ]
45
+
46
+ export interface WebhookResponseSnapshot {
47
+ readonly body: string
48
+ readonly contentType: string
49
+ readonly status: number
50
+ readonly headers: Readonly<Record<string, string>>
51
+ }
52
+
53
+ export function validWebhookStatus(value: unknown): value is number {
54
+ return typeof value === 'number' && Number.isInteger(value) && value >= 200 && value <= 599 && webhookResponseAllowsBody(value)
55
+ }
56
+
57
+ /** Portable validation also runs in the isolated engine, which has no HTTP globals. */
58
+ export function webhookHeaderValues(source: unknown): Readonly<Record<string, string>> | undefined {
59
+ if (source == null || typeof source !== 'object' || Array.isArray(source)) return
60
+ const headers: Record<string, string> = {}
61
+ const names: string[] = []
62
+ for (const [name, value] of Object.entries(source)) {
63
+ if (webhookHeaderNameIssue(name, names) != null) return
64
+ if (typeof value !== 'string' && typeof value !== 'boolean' && !(typeof value === 'number' && Number.isFinite(value))) return
65
+ const text = String(value)
66
+ if ([...text].some((character) => character.charCodeAt(0) > 255 || /[\0\r\n]/.test(character))) return
67
+ names.push(name)
68
+ Object.defineProperty(headers, name, { value: text, enumerable: true, configurable: true })
69
+ }
70
+ return headers
71
+ }
72
+
73
+ export function encodeWebhookBody(value: JsonValue): Pick<WebhookResponseSnapshot, 'body' | 'contentType'> {
74
+ return typeof value === 'string' ? { body: value, contentType: 'text/plain;charset=UTF-8' } : { body: JSON.stringify(value), contentType: 'application/json' }
75
+ }