@oomol-lab/open-connector 1.6.5 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (495) hide show
  1. package/README.md +4 -0
  2. package/assets/open-connector/catalog/apps/airtable.json +134 -0
  3. package/assets/open-connector/catalog/apps/aisa.json +6985 -319
  4. package/assets/open-connector/catalog/apps/baizhi_mcp.json +135 -0
  5. package/assets/open-connector/catalog/apps/cal.json +24 -6
  6. package/assets/open-connector/catalog/apps/discordbot.json +2888 -248
  7. package/assets/open-connector/catalog/apps/drawio_mcp.json +192 -0
  8. package/assets/open-connector/catalog/apps/enormail.json +411 -0
  9. package/assets/open-connector/catalog/apps/feishu_app_bot.json +158 -0
  10. package/assets/open-connector/catalog/apps/firecrawl.json +176 -32
  11. package/assets/open-connector/catalog/apps/framejet.json +273 -0
  12. package/assets/open-connector/catalog/apps/futunn.json +2967 -0
  13. package/assets/open-connector/catalog/apps/github.json +275 -0
  14. package/assets/open-connector/catalog/apps/gitlab.json +125 -0
  15. package/assets/open-connector/catalog/apps/gmail.json +376 -0
  16. package/assets/open-connector/catalog/apps/google_analytics.json +4 -1
  17. package/assets/open-connector/catalog/apps/google_bigquery.json +4 -1
  18. package/assets/open-connector/catalog/apps/google_search_console.json +4 -1
  19. package/assets/open-connector/catalog/apps/googlecalendar.json +210 -1
  20. package/assets/open-connector/catalog/apps/googlechat.json +694 -7
  21. package/assets/open-connector/catalog/apps/googledocs.json +4 -1
  22. package/assets/open-connector/catalog/apps/googledrive.json +479 -0
  23. package/assets/open-connector/catalog/apps/googlesheets.json +148 -1
  24. package/assets/open-connector/catalog/apps/granola.json +23 -0
  25. package/assets/open-connector/catalog/apps/hithink_finance.json +6 -3
  26. package/assets/open-connector/catalog/apps/indexed.json +1115 -0
  27. package/assets/open-connector/catalog/apps/keepa.json +3534 -987
  28. package/assets/open-connector/catalog/apps/linear.json +133 -0
  29. package/assets/open-connector/catalog/apps/linear_mcp.json +510 -0
  30. package/assets/open-connector/catalog/apps/moneyforward_mcp.json +1432 -0
  31. package/assets/open-connector/catalog/apps/notion.json +588 -1
  32. package/assets/open-connector/catalog/apps/notion_mcp.json +490 -0
  33. package/assets/open-connector/catalog/apps/odoo.json +619 -0
  34. package/assets/open-connector/catalog/apps/one_drive.json +185 -0
  35. package/assets/open-connector/catalog/apps/outlook.json +212 -8
  36. package/assets/open-connector/catalog/apps/outlook_calendar.json +23 -2
  37. package/assets/open-connector/catalog/apps/postiz.json +334 -0
  38. package/assets/open-connector/catalog/apps/proworkflow.json +529 -0
  39. package/assets/open-connector/catalog/apps/sellersprite_mcp.json +2 -1
  40. package/assets/open-connector/catalog/apps/shopify.json +282 -0
  41. package/assets/open-connector/catalog/apps/slack.json +405 -0
  42. package/assets/open-connector/catalog/apps/slackbot.json +214 -0
  43. package/assets/open-connector/catalog/apps/spotify.json +46 -43
  44. package/assets/open-connector/catalog/apps/stripe.json +96 -0
  45. package/assets/open-connector/catalog/apps/telegram.json +138 -0
  46. package/assets/open-connector/catalog/apps/tencent_docs.json +3 -0
  47. package/assets/open-connector/catalog/apps/weixin_store.json +543 -2
  48. package/assets/open-connector/catalog/apps/wisburg.json +1528 -0
  49. package/assets/open-connector/catalog/apps/woocommerce.json +127 -0
  50. package/assets/open-connector/catalog/apps/youtube.json +4 -1
  51. package/assets/open-connector/catalog/apps/zendesk.json +152 -0
  52. package/assets/open-connector/catalog/apps/zerotier.json +3319 -0
  53. package/assets/open-connector/catalog/apps-index.json +1 -1
  54. package/assets/open-connector/migrations/0014_saas_project.sql +55 -0
  55. package/assets/open-connector/migrations/0015_saas_cleanup_runtime.sql +8 -0
  56. package/assets/open-connector/migrations/0016_trigger_policy.sql +1 -0
  57. package/assets/open-connector/migrations/0017_trigger_subscriptions.sql +17 -0
  58. package/assets/open-connector/migrations/postgresql/0014_saas_project.sql +55 -0
  59. package/assets/open-connector/migrations/postgresql/0015_saas_cleanup_runtime.sql +8 -0
  60. package/assets/open-connector/migrations/postgresql/0016_trigger_policy.sql +1 -0
  61. package/assets/open-connector/migrations/postgresql/0017_trigger_subscriptions.sql +17 -0
  62. package/package.json +2 -2
  63. package/src/connection-service.d.ts +40 -7
  64. package/src/connection-service.js +60 -18
  65. package/src/core/action-policy.d.ts +8 -1
  66. package/src/core/action-policy.js +51 -0
  67. package/src/core/cast.d.ts +13 -0
  68. package/src/core/cast.js +18 -1
  69. package/src/core/guarded-fetch.d.ts +11 -3
  70. package/src/core/guarded-fetch.js +19 -7
  71. package/src/core/provider-scenarios.js +67 -13
  72. package/src/core/remote-http.d.ts +33 -0
  73. package/src/core/remote-http.js +104 -0
  74. package/src/core/request.d.ts +1 -0
  75. package/src/core/request.js +11 -1
  76. package/src/core/types.d.ts +5 -1
  77. package/src/marketplace/marketplace-service.d.ts +0 -1
  78. package/src/marketplace/marketplace-service.js +80 -92
  79. package/src/mcp.js +26 -9
  80. package/src/oauth/oauth-client-config-service.d.ts +16 -1
  81. package/src/oauth/oauth-client-config-service.js +59 -3
  82. package/src/oauth/oauth-flow-service.d.ts +14 -1
  83. package/src/oauth/oauth-flow-service.js +14 -6
  84. package/src/providers/17track/runtime.js +1 -1
  85. package/src/providers/action-contracts.generated.d.ts +20 -6
  86. package/src/providers/aifinmarket/runtime.js +1 -1
  87. package/src/providers/airtable/executors.d.ts +3 -0
  88. package/src/providers/airtable/executors.js +2 -0
  89. package/src/providers/airtable/trigger-on-record-changed.d.ts +2 -0
  90. package/src/providers/airtable/trigger-on-record-changed.definition.d.ts +4 -0
  91. package/src/providers/airtable/trigger-on-record-changed.definition.js +54 -0
  92. package/src/providers/airtable/trigger-on-record-changed.js +235 -0
  93. package/src/providers/aisa/executors.js +912 -50
  94. package/src/providers/aliyun_ack/runtime.js +1 -1
  95. package/src/providers/aliyun_sls/runtime.js +1 -1
  96. package/src/providers/app_store_server/runtime-helpers.js +1 -1
  97. package/src/providers/baizhi_mcp/actions.d.ts +2 -0
  98. package/src/providers/baizhi_mcp/actions.js +40 -0
  99. package/src/providers/baizhi_mcp/executors.d.ts +3 -0
  100. package/src/providers/baizhi_mcp/executors.js +102 -0
  101. package/src/providers/bazhuayu/runtime.js +2 -2
  102. package/src/providers/bilibili/runtime.js +2 -4
  103. package/src/providers/bilibili/upload.js +9 -7
  104. package/src/providers/cal/actions.js +5 -1
  105. package/src/providers/cloudflare_browser_rendering/executors.js +1 -1
  106. package/src/providers/cloudflare_dns/executors.js +1 -1
  107. package/src/providers/{cloudflare-current-user.js → cloudflare_dns/runtime-user.js} +2 -2
  108. package/src/providers/cloudflare_dns/runtime.d.ts +1 -1
  109. package/src/providers/cloudflare_dns/runtime.js +1 -1
  110. package/src/providers/cloudflare_r2/executors.js +1 -1
  111. package/src/providers/cloudflare_r2/runtime.d.ts +1 -1
  112. package/src/providers/cloudflare_r2/runtime.js +1 -1
  113. package/src/providers/cloudflare_worker/executors.js +1 -1
  114. package/src/providers/cloudflare_worker/runtime.d.ts +1 -1
  115. package/src/providers/cloudflare_worker/runtime.js +1 -1
  116. package/src/providers/dingtalk_mcp/runtime.js +1 -1
  117. package/src/providers/discordbot/executors.d.ts +0 -9
  118. package/src/providers/discordbot/executors.js +9 -101
  119. package/src/providers/discordbot/runtime-guilds.d.ts +3 -0
  120. package/src/providers/discordbot/runtime-guilds.js +464 -0
  121. package/src/providers/discordbot/runtime.d.ts +42 -0
  122. package/src/providers/discordbot/runtime.js +124 -0
  123. package/src/providers/drawio_mcp/executors.d.ts +3 -0
  124. package/src/providers/drawio_mcp/executors.js +19 -0
  125. package/src/providers/drawio_mcp/runtime.d.ts +8 -0
  126. package/src/providers/drawio_mcp/runtime.js +175 -0
  127. package/src/providers/enormail/executors.d.ts +4 -0
  128. package/src/providers/enormail/executors.js +97 -0
  129. package/src/providers/fastmoss_mcp/executors.js +2 -2
  130. package/src/providers/feishu_app_bot/executors.d.ts +3 -0
  131. package/src/providers/feishu_app_bot/executors.js +2 -0
  132. package/src/providers/feishu_app_bot/trigger-config.d.ts +1 -0
  133. package/src/providers/feishu_app_bot/trigger-config.js +10 -0
  134. package/src/providers/feishu_app_bot/trigger-on-event.d.ts +2 -0
  135. package/src/providers/feishu_app_bot/trigger-on-event.definition.d.ts +4 -0
  136. package/src/providers/feishu_app_bot/trigger-on-event.definition.js +63 -0
  137. package/src/providers/feishu_app_bot/trigger-on-event.js +29 -0
  138. package/src/providers/feishu_app_bot/trigger-subscriptions.d.ts +5 -0
  139. package/src/providers/feishu_app_bot/trigger-subscriptions.js +70 -0
  140. package/src/providers/finchina/executors.js +1 -1
  141. package/src/providers/framejet/executors.d.ts +4 -0
  142. package/src/providers/framejet/executors.js +19 -0
  143. package/src/providers/framejet/runtime.d.ts +16 -0
  144. package/src/providers/framejet/runtime.js +148 -0
  145. package/src/providers/futunn/actions.d.ts +2 -0
  146. package/src/providers/futunn/actions.js +152 -0
  147. package/src/providers/futunn/actions.research.d.ts +2 -0
  148. package/src/providers/futunn/actions.research.js +423 -0
  149. package/src/providers/futunn/actions.trading.d.ts +2 -0
  150. package/src/providers/futunn/actions.trading.js +204 -0
  151. package/src/providers/futunn/executors.d.ts +3 -0
  152. package/src/providers/futunn/executors.js +24 -0
  153. package/src/providers/futunn/runtime-research.d.ts +3 -0
  154. package/src/providers/futunn/runtime-research.js +133 -0
  155. package/src/providers/futunn/runtime-trading.d.ts +3 -0
  156. package/src/providers/futunn/runtime-trading.js +39 -0
  157. package/src/providers/futunn/runtime.d.ts +2 -0
  158. package/src/providers/futunn/runtime.js +50 -0
  159. package/src/providers/futunn/transport.d.ts +11 -0
  160. package/src/providers/futunn/transport.js +76 -0
  161. package/src/providers/gildata/executors.js +1 -1
  162. package/src/providers/github/executors.d.ts +3 -0
  163. package/src/providers/github/executors.js +6 -0
  164. package/src/providers/github/trigger-on-repo-event.d.ts +2 -0
  165. package/src/providers/github/trigger-on-repo-event.definition.d.ts +4 -0
  166. package/src/providers/github/trigger-on-repo-event.definition.js +94 -0
  167. package/src/providers/github/trigger-on-repo-event.js +168 -0
  168. package/src/providers/github/trigger-watch-pull-request.d.ts +2 -0
  169. package/src/providers/github/trigger-watch-pull-request.definition.d.ts +4 -0
  170. package/src/providers/github/trigger-watch-pull-request.definition.js +49 -0
  171. package/src/providers/github/trigger-watch-pull-request.js +106 -0
  172. package/src/providers/gitlab/executors.d.ts +3 -0
  173. package/src/providers/gitlab/executors.js +2 -0
  174. package/src/providers/gitlab/trigger-on-project-event.d.ts +2 -0
  175. package/src/providers/gitlab/trigger-on-project-event.definition.d.ts +5 -0
  176. package/src/providers/gitlab/trigger-on-project-event.definition.js +63 -0
  177. package/src/providers/gitlab/trigger-on-project-event.js +186 -0
  178. package/src/providers/gmail/executors.d.ts +3 -0
  179. package/src/providers/gmail/executors.js +5 -3
  180. package/src/providers/gmail/message.d.ts +6 -8
  181. package/src/providers/gmail/message.js +4 -0
  182. package/src/providers/gmail/scopes.d.ts +32 -0
  183. package/src/providers/gmail/scopes.js +37 -0
  184. package/src/providers/gmail/trigger-on-message-received.d.ts +2 -0
  185. package/src/providers/gmail/trigger-on-message-received.definition.d.ts +4 -0
  186. package/src/providers/gmail/trigger-on-message-received.definition.js +74 -0
  187. package/src/providers/gmail/trigger-on-message-received.js +232 -0
  188. package/src/providers/google_analytics/executors.js +2 -2
  189. package/src/providers/google_analytics/scopes.js +6 -1
  190. package/src/providers/google_bigquery/executors.js +2 -2
  191. package/src/providers/google_bigquery/scopes.js +2 -0
  192. package/src/providers/google_search_console/executors.js +2 -2
  193. package/src/providers/google_search_console/scopes.js +2 -0
  194. package/src/providers/googleads/executors.js +1 -1
  195. package/src/providers/googleads/scopes.d.ts +1 -3
  196. package/src/providers/googleads/scopes.js +2 -4
  197. package/src/providers/googlecalendar/executors.d.ts +3 -0
  198. package/src/providers/googlecalendar/executors.js +3 -1
  199. package/src/providers/googlecalendar/runtime-shared.js +2 -2
  200. package/src/providers/googlecalendar/scopes.js +2 -0
  201. package/src/providers/googlecalendar/trigger-on-event-changed.d.ts +2 -0
  202. package/src/providers/googlecalendar/trigger-on-event-changed.definition.d.ts +4 -0
  203. package/src/providers/googlecalendar/trigger-on-event-changed.definition.js +74 -0
  204. package/src/providers/googlecalendar/trigger-on-event-changed.js +233 -0
  205. package/src/providers/googlechat/executors.d.ts +1 -3
  206. package/src/providers/googlechat/executors.js +219 -28
  207. package/src/providers/googlechat/members.d.ts +55 -0
  208. package/src/providers/googlechat/members.js +293 -0
  209. package/src/providers/googlechat/runtime.d.ts +16 -0
  210. package/src/providers/googlechat/runtime.js +25 -0
  211. package/src/providers/googlechat/scopes.d.ts +22 -3
  212. package/src/providers/googlechat/scopes.js +30 -7
  213. package/src/providers/googledocs/executors.js +1 -1
  214. package/src/providers/googledrive/executors.d.ts +3 -0
  215. package/src/providers/googledrive/executors.js +9 -2
  216. package/src/providers/{google-auth.d.ts → googledrive/runtime-auth.d.ts} +2 -2
  217. package/src/providers/{google-auth.js → googledrive/runtime-auth.js} +3 -3
  218. package/src/providers/googledrive/runtime-collaboration.js +1 -1
  219. package/src/providers/{google-runtime.d.ts → googledrive/runtime-request.d.ts} +1 -1
  220. package/src/providers/{google-runtime.js → googledrive/runtime-request.js} +2 -2
  221. package/src/providers/googledrive/trigger-changes.d.ts +12 -0
  222. package/src/providers/googledrive/trigger-changes.definition.d.ts +7 -0
  223. package/src/providers/googledrive/trigger-changes.definition.js +101 -0
  224. package/src/providers/googledrive/trigger-changes.js +452 -0
  225. package/src/providers/googledrive/trigger-on-file-change.d.ts +2 -0
  226. package/src/providers/googledrive/trigger-on-file-change.definition.d.ts +4 -0
  227. package/src/providers/googledrive/trigger-on-file-change.definition.js +77 -0
  228. package/src/providers/googledrive/trigger-on-file-change.js +258 -0
  229. package/src/providers/googleforms/executors.js +2 -2
  230. package/src/providers/googleforms/scopes.d.ts +0 -3
  231. package/src/providers/googleforms/scopes.js +2 -6
  232. package/src/providers/googlemeet/executors.js +2 -2
  233. package/src/providers/googlemeet/scopes.d.ts +0 -3
  234. package/src/providers/googlemeet/scopes.js +2 -6
  235. package/src/providers/googlesheets/executors.d.ts +3 -0
  236. package/src/providers/googlesheets/executors.js +3 -1
  237. package/src/providers/googlesheets/scopes.js +2 -0
  238. package/src/providers/googlesheets/trigger-on-row-added.d.ts +2 -0
  239. package/src/providers/googlesheets/trigger-on-row-added.definition.d.ts +4 -0
  240. package/src/providers/googlesheets/trigger-on-row-added.definition.js +54 -0
  241. package/src/providers/googlesheets/trigger-on-row-added.js +234 -0
  242. package/src/providers/googleslides/executors.js +2 -2
  243. package/src/providers/googleslides/scopes.d.ts +0 -3
  244. package/src/providers/googleslides/scopes.js +2 -6
  245. package/src/providers/googletasks/executors.js +2 -2
  246. package/src/providers/googletasks/scopes.d.ts +0 -3
  247. package/src/providers/googletasks/scopes.js +2 -6
  248. package/src/providers/granola/actions.js +2 -0
  249. package/src/providers/granola/runtime-mcp.js +2 -0
  250. package/src/providers/granola/runtime.js +2 -2
  251. package/src/providers/hithink_finance/runtime.js +1 -1
  252. package/src/providers/indexed/executors.d.ts +4 -0
  253. package/src/providers/indexed/executors.js +16 -0
  254. package/src/providers/indexed/runtime.d.ts +26 -0
  255. package/src/providers/indexed/runtime.js +129 -0
  256. package/src/providers/indiegogo/executors.js +1 -1
  257. package/src/providers/investoday_mcp/executors.js +2 -2
  258. package/src/providers/iyunbiao/runtime.js +2 -2
  259. package/src/providers/keepa/actions.d.ts +1 -1
  260. package/src/providers/keepa/actions.js +371 -149
  261. package/src/providers/keepa/deal-attributes.d.ts +1 -0
  262. package/src/providers/keepa/deal-attributes.js +26 -0
  263. package/src/providers/keepa/runtime.js +212 -18
  264. package/src/providers/kingdee/executors.js +1 -1
  265. package/src/providers/kingdee/runtime.js +2 -2
  266. package/src/providers/kuaidi100/runtime.js +1 -1
  267. package/src/providers/linear/executors.d.ts +3 -0
  268. package/src/providers/linear/executors.js +14 -9
  269. package/src/providers/linear/trigger-on-issue-changed.d.ts +2 -0
  270. package/src/providers/linear/trigger-on-issue-changed.definition.d.ts +5 -0
  271. package/src/providers/linear/trigger-on-issue-changed.definition.js +43 -0
  272. package/src/providers/linear/trigger-on-issue-changed.js +215 -0
  273. package/src/providers/linear_mcp/actions.d.ts +47 -0
  274. package/src/providers/linear_mcp/actions.js +102 -0
  275. package/src/providers/linear_mcp/endpoints.d.ts +3 -0
  276. package/src/providers/linear_mcp/endpoints.js +3 -0
  277. package/src/providers/linear_mcp/executors.d.ts +3 -0
  278. package/src/providers/linear_mcp/executors.js +9 -0
  279. package/src/providers/linear_mcp/runtime-mcp.d.ts +15 -0
  280. package/src/providers/linear_mcp/runtime-mcp.js +238 -0
  281. package/src/providers/lingxing_mcp/runtime.js +1 -1
  282. package/src/providers/mcdonalds_cn_mcp/runtime.js +1 -1
  283. package/src/providers/metabase/mcp-runtime.js +1 -1
  284. package/src/providers/moneyforward_mcp/executors.d.ts +3 -0
  285. package/src/providers/moneyforward_mcp/executors.js +11 -0
  286. package/src/providers/moneyforward_mcp/manifest.d.ts +31 -0
  287. package/src/providers/moneyforward_mcp/manifest.js +204 -0
  288. package/src/providers/moneyforward_mcp/runtime.d.ts +18 -0
  289. package/src/providers/moneyforward_mcp/runtime.js +296 -0
  290. package/src/providers/notion/executors.d.ts +3 -0
  291. package/src/providers/notion/executors.js +41 -3
  292. package/src/providers/notion/trigger-on-database-page-event.d.ts +2 -0
  293. package/src/providers/notion/trigger-on-database-page-event.definition.d.ts +4 -0
  294. package/src/providers/notion/trigger-on-database-page-event.definition.js +63 -0
  295. package/src/providers/notion/trigger-on-database-page-event.js +293 -0
  296. package/src/providers/notion_mcp/endpoints.d.ts +3 -0
  297. package/src/providers/notion_mcp/endpoints.js +3 -0
  298. package/src/providers/notion_mcp/executors.d.ts +3 -0
  299. package/src/providers/notion_mcp/executors.js +176 -0
  300. package/src/providers/notion_mcp/mcp-response.d.ts +86 -0
  301. package/src/providers/notion_mcp/mcp-response.js +314 -0
  302. package/src/providers/odoo/executors.d.ts +3 -0
  303. package/src/providers/odoo/executors.js +32 -0
  304. package/src/providers/odoo/runtime.d.ts +16 -0
  305. package/src/providers/odoo/runtime.js +140 -0
  306. package/src/providers/one_drive/executors.d.ts +3 -0
  307. package/src/providers/one_drive/executors.js +2 -0
  308. package/src/providers/one_drive/trigger-on-item-changed.d.ts +2 -0
  309. package/src/providers/one_drive/trigger-on-item-changed.definition.d.ts +4 -0
  310. package/src/providers/one_drive/trigger-on-item-changed.definition.js +63 -0
  311. package/src/providers/one_drive/trigger-on-item-changed.js +214 -0
  312. package/src/providers/outlook/executors.d.ts +3 -0
  313. package/src/providers/outlook/executors.js +29 -6
  314. package/src/providers/outlook/microsoft-graph.js +17 -6
  315. package/src/providers/outlook/trigger-on-message-received.d.ts +2 -0
  316. package/src/providers/outlook/trigger-on-message-received.definition.d.ts +4 -0
  317. package/src/providers/outlook/trigger-on-message-received.definition.js +93 -0
  318. package/src/providers/outlook/trigger-on-message-received.js +226 -0
  319. package/src/providers/outlook_calendar/executors.js +30 -7
  320. package/src/providers/patsnap_mcp/executors.js +2 -2
  321. package/src/providers/postiz/executors.d.ts +4 -0
  322. package/src/providers/postiz/executors.js +83 -0
  323. package/src/providers/provider-loader.d.ts +5 -0
  324. package/src/providers/provider-loader.js +4 -0
  325. package/src/providers/provider-runtime.d.ts +15 -0
  326. package/src/providers/provider-runtime.js +57 -4
  327. package/src/providers/proworkflow/executors.d.ts +4 -0
  328. package/src/providers/proworkflow/executors.js +135 -0
  329. package/src/providers/registry.generated.js +14 -0
  330. package/src/providers/scrape_creators/catalog.js +1 -1
  331. package/src/providers/scrape_creators/runtime.js +1 -1
  332. package/src/providers/sellersprite_mcp/executors.js +2 -2
  333. package/src/providers/sellersprite_mcp/official-actions.js +3 -2
  334. package/src/providers/sentry/runtime.js +6 -7
  335. package/src/providers/shopify/executors.d.ts +3 -0
  336. package/src/providers/shopify/executors.js +2 -0
  337. package/src/providers/shopify/trigger-on-shop-event.d.ts +2 -0
  338. package/src/providers/shopify/trigger-on-shop-event.definition.d.ts +4 -0
  339. package/src/providers/shopify/trigger-on-shop-event.definition.js +214 -0
  340. package/src/providers/shopify/trigger-on-shop-event.js +165 -0
  341. package/src/providers/slack/actions.js +52 -3
  342. package/src/providers/slack/executors.d.ts +3 -0
  343. package/src/providers/slack/executors.js +2 -0
  344. package/src/providers/slack/runtime.js +58 -21
  345. package/src/providers/slack/trigger-on-message-posted.d.ts +2 -0
  346. package/src/providers/slack/trigger-on-message-posted.definition.d.ts +4 -0
  347. package/src/providers/slack/trigger-on-message-posted.definition.js +80 -0
  348. package/src/providers/slack/trigger-on-message-posted.js +176 -0
  349. package/src/providers/slickdeals/runtime.js +1 -1
  350. package/src/providers/sorftime_mcp/executors.js +2 -2
  351. package/src/providers/spotify/runtime.js +15 -4
  352. package/src/providers/stripe/executors.d.ts +3 -0
  353. package/src/providers/stripe/executors.js +2 -0
  354. package/src/providers/stripe/trigger-on-event.d.ts +2 -0
  355. package/src/providers/stripe/trigger-on-event.definition.d.ts +4 -0
  356. package/src/providers/stripe/trigger-on-event.definition.js +43 -0
  357. package/src/providers/stripe/trigger-on-event.js +212 -0
  358. package/src/providers/telegram/executors.d.ts +3 -0
  359. package/src/providers/telegram/executors.js +2 -0
  360. package/src/providers/telegram/trigger-on-update.d.ts +2 -0
  361. package/src/providers/telegram/trigger-on-update.definition.d.ts +5 -0
  362. package/src/providers/telegram/trigger-on-update.definition.js +78 -0
  363. package/src/providers/telegram/trigger-on-update.js +141 -0
  364. package/src/providers/tikhub/bounded-response.d.ts +1 -1
  365. package/src/providers/tikhub/bounded-response.js +8 -34
  366. package/src/providers/tikhub/endpoint-catalog.js +1 -1
  367. package/src/providers/tikhub/runtime.js +2 -2
  368. package/src/providers/tongdaxin/executors.js +79 -15
  369. package/src/providers/uspto/executors.js +1 -1
  370. package/src/providers/waffo/executors.js +1 -1
  371. package/src/providers/waffo/runtime.js +1 -1
  372. package/src/providers/wecom_mcp/runtime.js +1 -1
  373. package/src/providers/weixin_store/access-token.d.ts +2 -1
  374. package/src/providers/weixin_store/access-token.js +15 -4
  375. package/src/providers/weixin_store/executors.js +97 -12
  376. package/src/providers/wisburg/executors.d.ts +4 -0
  377. package/src/providers/wisburg/executors.js +13 -0
  378. package/src/providers/wisburg/runtime.d.ts +12 -0
  379. package/src/providers/wisburg/runtime.js +133 -0
  380. package/src/providers/woocommerce/executors.d.ts +3 -0
  381. package/src/providers/woocommerce/executors.js +2 -0
  382. package/src/providers/woocommerce/trigger-on-store-event.d.ts +2 -0
  383. package/src/providers/woocommerce/trigger-on-store-event.definition.d.ts +4 -0
  384. package/src/providers/woocommerce/trigger-on-store-event.definition.js +55 -0
  385. package/src/providers/woocommerce/trigger-on-store-event.js +179 -0
  386. package/src/providers/xydc_mcp/executors.js +2 -2
  387. package/src/providers/youtube/executors.js +1 -1
  388. package/src/providers/youtube/runtime.js +1 -1
  389. package/src/providers/zendesk/executors.d.ts +3 -0
  390. package/src/providers/zendesk/executors.js +2 -0
  391. package/src/providers/zendesk/trigger-on-event.d.ts +2 -0
  392. package/src/providers/zendesk/trigger-on-event.definition.d.ts +5 -0
  393. package/src/providers/zendesk/trigger-on-event.definition.js +101 -0
  394. package/src/providers/zendesk/trigger-on-event.js +188 -0
  395. package/src/providers/zerotier/executors.d.ts +9 -0
  396. package/src/providers/zerotier/executors.js +629 -0
  397. package/src/providers/zerotier/runtime.d.ts +54 -0
  398. package/src/providers/zerotier/runtime.js +207 -0
  399. package/src/saas/saas-cleanup-service.d.ts +26 -0
  400. package/src/saas/saas-cleanup-service.js +124 -0
  401. package/src/saas/saas-client.d.ts +86 -0
  402. package/src/saas/saas-client.js +369 -0
  403. package/src/saas/saas-execution-service.d.ts +15 -0
  404. package/src/saas/saas-execution-service.js +21 -0
  405. package/src/saas/saas-oauth-service.d.ts +25 -0
  406. package/src/saas/saas-oauth-service.js +197 -0
  407. package/src/saas/saas-project-service.d.ts +61 -0
  408. package/src/saas/saas-project-service.js +211 -0
  409. package/src/server/actions/action-idempotency.d.ts +1 -0
  410. package/src/server/actions/action-idempotency.js +1 -0
  411. package/src/server/actions/action-runner.d.ts +7 -0
  412. package/src/server/actions/action-runner.js +43 -7
  413. package/src/server/actions/run-log-summary.js +9 -0
  414. package/src/server/api/auth.d.ts +1 -0
  415. package/src/server/api/auth.js +13 -2
  416. package/src/server/api/cache-policy.js +4 -1
  417. package/src/server/api/connection-input.d.ts +7 -1
  418. package/src/server/api/connection-input.js +7 -1
  419. package/src/server/api/connection-routes.d.ts +3 -1
  420. package/src/server/api/connection-routes.js +21 -3
  421. package/src/server/api/http-utils.d.ts +4 -3
  422. package/src/server/api/oauth-completion-page.d.ts +124 -0
  423. package/src/server/api/oauth-completion-page.js +113 -18
  424. package/src/server/api/openapi.js +123 -15
  425. package/src/server/api/policy-input.js +6 -0
  426. package/src/server/api/runtime-api.d.ts +18 -3
  427. package/src/server/api/runtime-api.js +36 -5
  428. package/src/server/api/saas-completion-page.d.ts +2 -0
  429. package/src/server/api/saas-completion-page.js +103 -0
  430. package/src/server/connect-app.d.ts +5 -0
  431. package/src/server/connect-app.js +50 -0
  432. package/src/server/connect-server.d.ts +12 -0
  433. package/src/server/connect-server.js +157 -15
  434. package/src/server/connector-runtime.d.ts +3 -1
  435. package/src/server/connector-runtime.js +5 -2
  436. package/src/server/files/transit-files.js +16 -7
  437. package/src/server/proxy/proxy-runner.d.ts +5 -1
  438. package/src/server/proxy/proxy-runner.js +72 -26
  439. package/src/server/storage/connection-request-store.d.ts +41 -1
  440. package/src/server/storage/connection-request-store.js +245 -20
  441. package/src/server/storage/connection-store.d.ts +16 -0
  442. package/src/server/storage/connection-store.js +119 -0
  443. package/src/server/storage/node-runtime-database.js +3 -3
  444. package/src/server/storage/{postgres-migrations.d.ts → postgres/migrations.d.ts} +2 -2
  445. package/src/server/storage/{postgres-migrations.js → postgres/migrations.js} +1 -1
  446. package/src/server/storage/postgres/runtime-store.d.ts +43 -0
  447. package/src/server/storage/{postgres-runtime-store.js → postgres/runtime-store.js} +59 -94
  448. package/src/server/storage/runtime-database.d.ts +4 -0
  449. package/src/server/storage/runtime-sql.d.ts +1 -1
  450. package/src/server/storage/runtime-sql.js +2 -1
  451. package/src/server/storage/runtime-store.d.ts +1 -0
  452. package/src/server/storage/runtime-token-service.d.ts +2 -0
  453. package/src/server/storage/runtime-token-service.js +3 -0
  454. package/src/server/storage/saas-project-store.d.ts +77 -0
  455. package/src/server/storage/saas-project-store.js +273 -0
  456. package/src/server/storage/{sqlite-runtime-store.d.ts → sqlite/runtime-store.d.ts} +21 -25
  457. package/src/server/storage/{sqlite-runtime-store.js → sqlite/runtime-store.js} +100 -115
  458. package/src/server/storage/trigger-store.d.ts +16 -0
  459. package/src/server/storage/trigger-store.js +96 -0
  460. package/src/triggers/common/config.d.ts +2 -0
  461. package/src/triggers/common/config.js +17 -0
  462. package/src/triggers/common/configOptions.d.ts +13 -0
  463. package/src/triggers/common/configOptions.js +1 -0
  464. package/src/triggers/common/encoding.d.ts +3 -0
  465. package/src/triggers/common/encoding.js +19 -0
  466. package/src/triggers/common/integration.d.ts +115 -0
  467. package/src/triggers/common/integration.js +31 -0
  468. package/src/triggers/common/json.d.ts +6 -0
  469. package/src/triggers/common/json.js +91 -0
  470. package/src/triggers/common/poll.d.ts +41 -0
  471. package/src/triggers/common/poll.js +15 -0
  472. package/src/triggers/common/proxy.d.ts +14 -0
  473. package/src/triggers/common/proxy.js +1 -0
  474. package/src/triggers/common/types.d.ts +42 -0
  475. package/src/triggers/common/types.js +1 -0
  476. package/src/triggers/maintenance.d.ts +40 -0
  477. package/src/triggers/maintenance.js +120 -0
  478. package/src/triggers/metadata.d.ts +8 -0
  479. package/src/triggers/metadata.js +1 -0
  480. package/src/triggers/request.d.ts +33 -0
  481. package/src/triggers/request.js +52 -0
  482. package/src/triggers/resources.d.ts +12 -0
  483. package/src/triggers/resources.js +121 -0
  484. package/src/triggers/signature.d.ts +4 -0
  485. package/src/triggers/signature.js +48 -0
  486. package/src/triggers/store.d.ts +29 -0
  487. package/src/triggers/store.js +1 -0
  488. package/src/triggers/subscriptions.d.ts +22 -0
  489. package/src/triggers/subscriptions.js +220 -0
  490. package/src/triggers/trigger-runner.d.ts +34 -0
  491. package/src/triggers/trigger-runner.js +169 -0
  492. package/src/providers/sentry/scopes.d.ts +0 -1
  493. package/src/providers/sentry/scopes.js +0 -7
  494. package/src/server/storage/postgres-runtime-store.d.ts +0 -39
  495. /package/src/providers/{cloudflare-current-user.d.ts → cloudflare_dns/runtime-user.d.ts} +0 -0
@@ -0,0 +1,214 @@
1
+ import { canonicalJsonBytes, digestBytes } from "../../triggers/common/encoding.js";
2
+ import { eventsPollOutputs, maximumPollEventsPerPage, PermanentPollError, PollConnectionError, TransientPollError, } from "../../triggers/common/poll.js";
3
+ import { snapshot } from "./trigger-on-item-changed.definition.js";
4
+ export const oneDriveItemChanged = {
5
+ buildOutputs: eventsPollOutputs,
6
+ snapshot,
7
+ async poll(context) {
8
+ const config = resolveConfig(context.config);
9
+ if (context.checkpoint === null)
10
+ return { checkpoint: (await seed(context, config)), events: [] };
11
+ const checkpoint = readCheckpoint(context.checkpoint);
12
+ const { items, next } = await changedItems(context, checkpoint, config.maxItemsPerPoll);
13
+ const events = [];
14
+ let filtered = 0;
15
+ for (const [id, item] of items) {
16
+ const result = await evaluate(id, item, config, checkpoint);
17
+ if (result == "structural")
18
+ continue;
19
+ if (result == "filtered")
20
+ filtered += 1;
21
+ else
22
+ events.push(result);
23
+ }
24
+ return {
25
+ checkpoint: next.checkpoint,
26
+ events,
27
+ filtered,
28
+ ...(next.hasMore ? { hasMore: true } : {}),
29
+ };
30
+ },
31
+ };
32
+ function resolveConfig(value) {
33
+ return {
34
+ events: value.events,
35
+ itemId: value.itemId.trim(),
36
+ itemTypes: value.itemTypes,
37
+ maxItemsPerPoll: value.maxItemsPerPoll,
38
+ parentFolderId: value.parentFolderId.trim(),
39
+ };
40
+ }
41
+ async function seed(context, config) {
42
+ const result = await get(context, "/me/drive/root/delta", { token: "latest" });
43
+ if (result.status == 404)
44
+ throw new PermanentPollError("OneDrive is not provisioned for this account.");
45
+ success(result, "delta seeding");
46
+ const link = record(result.data)?.["@odata.deltaLink"];
47
+ const token = link == null ? null : parseToken(link);
48
+ if (token == null)
49
+ throw new TransientPollError("OneDrive delta seeding response has no delta token.");
50
+ await validateItem(context, "parentFolderId", config.parentFolderId);
51
+ await validateItem(context, "itemId", config.itemId);
52
+ return { deltaToken: token, lastPolledAt: context.now.toISOString() };
53
+ }
54
+ async function validateItem(context, field, id) {
55
+ if (id.length == 0)
56
+ return;
57
+ const result = await get(context, `/me/drive/items/${encodeURIComponent(id)}`, {});
58
+ if (result.status == 400 || result.status == 404)
59
+ throw new PermanentPollError(`OneDrive ${field} does not identify an item in this drive.`);
60
+ success(result, `${field} validation`);
61
+ }
62
+ function readCheckpoint(value) {
63
+ const checkpoint = record(value);
64
+ if (typeof checkpoint?.deltaToken != "string" ||
65
+ checkpoint.deltaToken.length == 0 ||
66
+ typeof checkpoint.lastPolledAt != "string" ||
67
+ Number.isNaN(Date.parse(checkpoint.lastPolledAt))) {
68
+ throw new PermanentPollError("OneDrive checkpoint is invalid; recreate the Trigger.");
69
+ }
70
+ return {
71
+ deltaToken: checkpoint.deltaToken,
72
+ lastPolledAt: checkpoint.lastPolledAt,
73
+ ...(typeof checkpoint.pageToken == "string" && checkpoint.pageToken.length > 0
74
+ ? { pageToken: checkpoint.pageToken }
75
+ : {}),
76
+ };
77
+ }
78
+ async function changedItems(context, checkpoint, pageSize) {
79
+ const items = new Map();
80
+ const result = await get(context, "/me/drive/root/delta", {
81
+ $top: Math.min(pageSize, maximumPollEventsPerPage),
82
+ token: checkpoint.pageToken ?? checkpoint.deltaToken,
83
+ });
84
+ deltaSuccess(result);
85
+ const parsed = (record(result.data) ?? {});
86
+ for (const item of parsed.value ?? [])
87
+ if (item.id != null && item.id.length > 0)
88
+ items.set(item.id, item);
89
+ if (parsed["@odata.deltaLink"]) {
90
+ return {
91
+ items,
92
+ next: {
93
+ checkpoint: {
94
+ deltaToken: requireToken(parsed["@odata.deltaLink"]),
95
+ lastPolledAt: context.now.toISOString(),
96
+ },
97
+ hasMore: false,
98
+ },
99
+ };
100
+ }
101
+ if (!parsed["@odata.nextLink"])
102
+ throw new TransientPollError("OneDrive delta response has no continuation link.");
103
+ return {
104
+ items,
105
+ next: {
106
+ checkpoint: {
107
+ deltaToken: checkpoint.deltaToken,
108
+ lastPolledAt: checkpoint.lastPolledAt,
109
+ pageToken: requireToken(parsed["@odata.nextLink"]),
110
+ },
111
+ hasMore: true,
112
+ },
113
+ };
114
+ }
115
+ async function evaluate(id, item, config, checkpoint) {
116
+ if (item.root != null)
117
+ return "structural";
118
+ const itemType = type(item);
119
+ if (itemType == null)
120
+ return "structural";
121
+ const change = item.deleted != null
122
+ ? "deleted"
123
+ : createdAfter(item.createdDateTime, new Date(checkpoint.lastPolledAt))
124
+ ? "created"
125
+ : "updated";
126
+ if (!config.events.includes(change) || !config.itemTypes.includes(itemType))
127
+ return "filtered";
128
+ if (config.parentFolderId.length > 0 && item.parentReference?.id !== config.parentFolderId)
129
+ return "filtered";
130
+ if (config.itemId.length > 0 && id !== config.itemId)
131
+ return "filtered";
132
+ return await event(id, item, change, itemType, checkpoint.deltaToken);
133
+ }
134
+ function type(item) {
135
+ if (item.file != null)
136
+ return "file";
137
+ if (item.folder != null)
138
+ return "folder";
139
+ return item.deleted != null ? "file" : null;
140
+ }
141
+ async function event(id, item, change, itemType, deltaToken) {
142
+ // 同一轮分页共用删除事件标识,后续 delta 周期必须使用新标识。
143
+ return {
144
+ dedupeKey: item.deleted != null
145
+ ? await digestBytes(canonicalJsonBytes(["one-drive-deleted", deltaToken, id]))
146
+ : `${id}:${item.eTag ?? item.lastModifiedDateTime}`,
147
+ payload: {
148
+ changeType: change,
149
+ createdDateTime: item.createdDateTime ?? item.fileSystemInfo?.createdDateTime ?? null,
150
+ driveId: item.parentReference?.driveId ?? null,
151
+ eTag: item.eTag ?? null,
152
+ itemId: id,
153
+ itemType,
154
+ lastModifiedDateTime: item.lastModifiedDateTime ?? item.fileSystemInfo?.lastModifiedDateTime ?? null,
155
+ mimeType: item.file?.mimeType ?? null,
156
+ name: item.name ?? "",
157
+ parentFolderId: item.parentReference?.id ?? null,
158
+ size: item.size ?? null,
159
+ webUrl: item.webUrl ?? "",
160
+ },
161
+ };
162
+ }
163
+ async function get(context, endpoint, query) {
164
+ try {
165
+ return await context.connector.execute({ endpoint, method: "GET", query }, context.signal);
166
+ }
167
+ catch (cause) {
168
+ throw new TransientPollError(`OneDrive proxy request to ${endpoint} failed.`, { cause });
169
+ }
170
+ }
171
+ function deltaSuccess(result) {
172
+ if (result.status == 410)
173
+ throw new PermanentPollError("OneDrive delta token expired; recreate the Trigger.");
174
+ if (result.status == 404)
175
+ throw new PermanentPollError("OneDrive is not provisioned for this account.");
176
+ if (result.status == 400)
177
+ throw new PermanentPollError("OneDrive rejected the delta token; recreate the Trigger.");
178
+ success(result, "delta list");
179
+ }
180
+ function success(result, operation) {
181
+ if (result.status >= 200 && result.status < 300)
182
+ return;
183
+ if (result.status == 401 || result.status == 403)
184
+ throw new PollConnectionError(`OneDrive ${operation} rejected the Connection.`);
185
+ throw new TransientPollError(`OneDrive ${operation} failed with status ${result.status}.`);
186
+ }
187
+ function requireToken(link) {
188
+ const token = parseToken(link);
189
+ if (token == null)
190
+ throw new TransientPollError("OneDrive delta link has no token.");
191
+ return token;
192
+ }
193
+ function parseToken(link) {
194
+ const raw = /[?&]token=([^&#]+)/.exec(link)?.[1] ?? /\(token='([^']+)'\)/.exec(link)?.[1];
195
+ if (raw == null)
196
+ return null;
197
+ try {
198
+ return decodeURIComponent(raw);
199
+ }
200
+ catch {
201
+ return raw;
202
+ }
203
+ }
204
+ function createdAfter(value, boundary) {
205
+ if (value == null || value.length == 0)
206
+ return false;
207
+ const date = new Date(value);
208
+ return !Number.isNaN(date.getTime()) && date >= boundary;
209
+ }
210
+ function record(value) {
211
+ return value != null && typeof value == "object" && !Array.isArray(value)
212
+ ? value
213
+ : undefined;
214
+ }
@@ -1,4 +1,6 @@
1
1
  import type { CredentialValidators, ProviderExecutors, ProviderProxyExecutor } from "../../core/types.ts";
2
+ import type { IntegrationDefinition } from "../../triggers/common/integration.ts";
3
+ import type { PollDefinition } from "../../triggers/common/poll.ts";
2
4
  export declare const proxy: ProviderProxyExecutor;
3
5
  interface OutlookRequestInput {
4
6
  accessToken: string;
@@ -13,4 +15,5 @@ interface OutlookRequestInput {
13
15
  export declare const executors: ProviderExecutors;
14
16
  export declare const credentialValidators: CredentialValidators;
15
17
  export declare function outlookJsonRequest<T>(pathOrUrl: string, input: OutlookRequestInput): Promise<T>;
18
+ export declare const triggers: readonly (IntegrationDefinition | PollDefinition)[];
16
19
  export {};
@@ -1,6 +1,7 @@
1
1
  import { compactObject, requiredRecord } from "../../core/cast.js";
2
- import { defineOAuthProviderExecutors, defineProviderProxy, ProviderRequestError } from "../provider-runtime.js";
2
+ import { defineOAuthProviderExecutors, defineProviderProxy, providerInputError, ProviderRequestError, } from "../provider-runtime.js";
3
3
  import { microsoftGraphJson, microsoftGraphRequest } from "./microsoft-graph.js";
4
+ import { outlookMessageReceived } from "./trigger-on-message-received.js";
4
5
  const outlookGraphBaseUrl = "https://graph.microsoft.com/v1.0";
5
6
  export const proxy = defineProviderProxy({
6
7
  service: "outlook",
@@ -93,6 +94,13 @@ function graphRequestOptions(input) {
93
94
  function isAllowedOutlookMessageNextLinkPath(pathname) {
94
95
  const normalizedPath = trimTrailingSlash(pathname);
95
96
  const segments = normalizedPath.split("/").filter(Boolean);
97
+ // Delta continuation links (@odata.nextLink inside a delta round and
98
+ // @odata.deltaLink) end in a trailing `delta` segment on the two
99
+ // folder-scoped message-collection shapes. Graph tracks message changes per
100
+ // folder, so `/v1.0/me/messages/delta` is not admitted.
101
+ if (segments.length > 4 && segments[segments.length - 1] === "delta") {
102
+ segments.pop();
103
+ }
96
104
  if (segments[0] !== "v1.0") {
97
105
  return false;
98
106
  }
@@ -162,12 +170,24 @@ async function listMailFolders(input, { accessToken, fetcher }) {
162
170
  };
163
171
  }
164
172
  async function listMessages(input, { accessToken, fetcher }) {
165
- const pathOrUrl = typeof input.nextLink === "string"
173
+ // A nextLink continues the current page sequence; a deltaLink starts the
174
+ // next delta round. Both are opaque Graph URLs checked by the allowlist.
175
+ const followUpLink = typeof input.nextLink === "string"
166
176
  ? input.nextLink
167
- : typeof input.mailFolderId === "string"
168
- ? `me/mailFolders/${encodeURIComponent(input.mailFolderId)}/messages`
169
- : "me/messages";
170
- const query = typeof input.nextLink === "string"
177
+ : typeof input.deltaLink === "string"
178
+ ? input.deltaLink
179
+ : undefined;
180
+ const folderPath = typeof input.mailFolderId === "string"
181
+ ? `me/mailFolders/${encodeURIComponent(input.mailFolderId)}/messages`
182
+ : undefined;
183
+ // Graph tracks message changes per folder: there is no mailbox-wide
184
+ // messages/delta, so a delta listing needs a folder.
185
+ if (followUpLink === undefined && input.delta === true && folderPath === undefined) {
186
+ throw providerInputError("mailFolderId is required when delta is true.");
187
+ }
188
+ const collectionPath = folderPath ?? "me/messages";
189
+ const pathOrUrl = followUpLink ?? (input.delta === true ? `${collectionPath}/delta` : collectionPath);
190
+ const query = followUpLink !== undefined
171
191
  ? undefined
172
192
  : compactObject({
173
193
  $top: typeof input.top === "number" ? String(input.top) : undefined,
@@ -186,9 +206,11 @@ async function listMessages(input, { accessToken, fetcher }) {
186
206
  query,
187
207
  headers,
188
208
  });
209
+ // Rows stay raw: a delta round reports removals as `{ id, "@removed": {...} }`.
189
210
  return {
190
211
  messages: Array.isArray(payload.value) ? payload.value : [],
191
212
  nextLink: typeof payload["@odata.nextLink"] === "string" ? payload["@odata.nextLink"] : null,
213
+ deltaLink: typeof payload["@odata.deltaLink"] === "string" ? payload["@odata.deltaLink"] : null,
192
214
  };
193
215
  }
194
216
  async function getMessage(input, { accessToken, fetcher }) {
@@ -413,3 +435,4 @@ function requiredString(value, field) {
413
435
  function asObject(value) {
414
436
  return requiredRecord(value, "object input", (message) => new ProviderRequestError(400, message));
415
437
  }
438
+ export const triggers = [outlookMessageReceived];
@@ -1,5 +1,5 @@
1
1
  import { optionalRecord, optionalString } from "../../core/cast.js";
2
- import { ProviderRequestError, readProviderErrorTextBody, readProviderJsonBody, runProviderRequest, setSearchParams, } from "../provider-runtime.js";
2
+ import { ProviderRequestError, readProviderErrorTextBody, readProviderJsonBody, runProviderRequest, setSearchParams, withRetryAfterSeconds, } from "../provider-runtime.js";
3
3
  const graphBaseUrl = "https://graph.microsoft.com/v1.0/";
4
4
  const graphOrigin = "https://graph.microsoft.com";
5
5
  /**
@@ -41,10 +41,13 @@ export async function microsoftGraphJson(pathOrUrl, options) {
41
41
  }));
42
42
  }
43
43
  function buildMicrosoftGraphUrl(pathOrUrl, query, allowNextLink) {
44
- const normalizedPathOrUrl = pathOrUrl.toLowerCase();
45
- const absolute = normalizedPathOrUrl.startsWith("https://") || normalizedPathOrUrl.startsWith("http://");
46
- const requiresNextLinkValidation = absolute || pathOrUrl.startsWith("/");
47
- const url = absolute ? new URL(pathOrUrl) : new URL(pathOrUrl, graphBaseUrl);
44
+ // Code passes plain relative paths such as `me/messages`; anything else is a
45
+ // caller-supplied link that must pass the allowlist. A value with any scheme
46
+ // is parsed on its own: resolved against the base, `https:me/drive` would
47
+ // turn into a same-origin path that never reaches the allowlist.
48
+ const absolute = /^[a-z][a-z\d+.-]*:/i.test(pathOrUrl);
49
+ const requiresNextLinkValidation = absolute || !/^[a-z\d]/i.test(pathOrUrl);
50
+ const url = parseMicrosoftGraphUrl(pathOrUrl, absolute ? undefined : graphBaseUrl);
48
51
  if (url.origin !== graphOrigin || url.protocol !== "https:") {
49
52
  throw new ProviderRequestError(400, "Microsoft Graph URL must target https://graph.microsoft.com");
50
53
  }
@@ -54,6 +57,14 @@ function buildMicrosoftGraphUrl(pathOrUrl, query, allowNextLink) {
54
57
  setSearchParams(url, query ?? {});
55
58
  return url;
56
59
  }
60
+ function parseMicrosoftGraphUrl(pathOrUrl, base) {
61
+ try {
62
+ return new URL(pathOrUrl, base);
63
+ }
64
+ catch {
65
+ throw new ProviderRequestError(400, "Microsoft Graph URL must target https://graph.microsoft.com");
66
+ }
67
+ }
57
68
  async function microsoftGraphResponseError(response, options) {
58
69
  const text = await readProviderErrorTextBody(response, `${options.label} error response`);
59
70
  let code = "";
@@ -69,5 +80,5 @@ async function microsoftGraphResponseError(response, options) {
69
80
  // Keep the upstream text when it is not JSON.
70
81
  }
71
82
  }
72
- return new ProviderRequestError(response.status, options.refineErrorMessage?.(code, message) ?? message);
83
+ return new ProviderRequestError(response.status, options.refineErrorMessage?.(code, message) ?? message, withRetryAfterSeconds(response));
73
84
  }
@@ -0,0 +1,2 @@
1
+ import type { PollDefinition } from "../../triggers/common/poll.ts";
2
+ export declare const outlookMessageReceived: PollDefinition;
@@ -0,0 +1,4 @@
1
+ import type { TriggerKeySnapshot } from "../../triggers/common/types.ts";
2
+ export declare const snapshot: TriggerKeySnapshot & {
3
+ readonly type: "poll";
4
+ };
@@ -0,0 +1,93 @@
1
+ import { jsonSchema as s } from "../../core/json-schema.js";
2
+ const defaultFolder = "inbox";
3
+ const defaultPageSize = 25;
4
+ const eventSchema = s.object({
5
+ bodyPreview: s.string(),
6
+ categories: s.array(s.string()),
7
+ conversationId: s.string(),
8
+ from: s.string(),
9
+ fromName: s.string(),
10
+ hasAttachments: s.boolean(),
11
+ importance: s.string(),
12
+ internetMessageId: s.string(),
13
+ isDraft: s.boolean(),
14
+ isRead: s.boolean(),
15
+ messageId: s.string(),
16
+ parentFolderId: s.string(),
17
+ receivedDateTime: s.string(),
18
+ subject: s.string(),
19
+ to: s.array(s.string()),
20
+ webLink: s.string(),
21
+ }, {
22
+ additionalProperties: false,
23
+ required: [
24
+ "messageId",
25
+ "internetMessageId",
26
+ "conversationId",
27
+ "subject",
28
+ "bodyPreview",
29
+ "from",
30
+ "fromName",
31
+ "to",
32
+ "receivedDateTime",
33
+ "hasAttachments",
34
+ "isRead",
35
+ "isDraft",
36
+ "importance",
37
+ "categories",
38
+ "parentFolderId",
39
+ "webLink",
40
+ ],
41
+ });
42
+ export const snapshot = {
43
+ configInputs: [
44
+ {
45
+ handle: "folder",
46
+ jsonSchema: s.string({ pattern: "^[A-Za-z0-9_=-]*$" }),
47
+ nullable: false,
48
+ value: defaultFolder,
49
+ description: "A well-known mail folder name, folder ID, or an empty string for the whole mailbox.",
50
+ },
51
+ { handle: "includeDrafts", jsonSchema: s.boolean(), nullable: false, value: false },
52
+ {
53
+ handle: "maxMessagesPerPoll",
54
+ jsonSchema: s.integer({ maximum: 100, minimum: 1 }),
55
+ nullable: false,
56
+ value: defaultPageSize,
57
+ },
58
+ {
59
+ handle: "readStatus",
60
+ jsonSchema: s.stringEnum(["All", "Read", "Unread"]),
61
+ nullable: false,
62
+ value: "All",
63
+ },
64
+ {
65
+ handle: "senderAddress",
66
+ jsonSchema: s.string(),
67
+ nullable: false,
68
+ value: "",
69
+ description: "Exact sender address, or empty for any sender.",
70
+ },
71
+ {
72
+ handle: "subjectContains",
73
+ jsonSchema: s.string(),
74
+ nullable: false,
75
+ value: "",
76
+ description: "Case-insensitive subject text.",
77
+ },
78
+ {
79
+ handle: "withAttachmentsOnly",
80
+ jsonSchema: s.boolean(),
81
+ nullable: false,
82
+ value: false,
83
+ },
84
+ ],
85
+ definitionVersion: 2,
86
+ description: "Polls a Microsoft Outlook mail folder and triggers when a new message arrives.",
87
+ displayName: "New Message Received",
88
+ key: "outlook.on_message_received",
89
+ name: "on_message_received",
90
+ outputs: [{ handle: "events", jsonSchema: s.array(eventSchema), nullable: false }],
91
+ provider: "outlook",
92
+ type: "poll",
93
+ };
@@ -0,0 +1,226 @@
1
+ import { eventsPollOutputs, PermanentPollError, PollConnectionError, TransientPollError, } from "../../triggers/common/poll.js";
2
+ import { snapshot } from "./trigger-on-message-received.definition.js";
3
+ const markerPageSize = 100;
4
+ const seedAnchor = "1970-01-01T00:00:00Z";
5
+ const select = "id,internetMessageId,conversationId,subject,bodyPreview,from,toRecipients,receivedDateTime,hasAttachments,isRead,isDraft,importance,categories,parentFolderId,webLink";
6
+ export const outlookMessageReceived = {
7
+ buildOutputs: eventsPollOutputs,
8
+ snapshot,
9
+ async poll(context) {
10
+ const config = resolveConfig(context.config);
11
+ if (context.checkpoint === null)
12
+ return { checkpoint: (await seed(context, config)), events: [] };
13
+ const checkpoint = readCheckpoint(context.checkpoint);
14
+ const result = await get(context, endpoint(config.folder), {
15
+ $filter: filter(config, checkpoint.lastReceivedDateTime),
16
+ $orderby: "receivedDateTime asc",
17
+ $select: select,
18
+ $top: config.maxMessagesPerPoll,
19
+ });
20
+ success(result, "message list");
21
+ const rows = messages(result.data);
22
+ if (rows.length == 0)
23
+ return { checkpoint: checkpoint, events: [] };
24
+ const previousMs = Date.parse(checkpoint.lastReceivedDateTime);
25
+ let watermarkMs = previousMs;
26
+ let watermark = checkpoint.lastReceivedDateTime;
27
+ for (const row of rows) {
28
+ const ms = isoMs(row.receivedDateTime);
29
+ if (row.receivedDateTime != null && ms != null && ms > watermarkMs) {
30
+ watermarkMs = ms;
31
+ watermark = row.receivedDateTime;
32
+ }
33
+ }
34
+ const moved = watermarkMs > previousMs;
35
+ const processed = new Set(checkpoint.boundaryMessageIds);
36
+ const full = rows.length >= config.maxMessagesPerPoll;
37
+ if (full && !moved && rows.every((row) => typeof row.id == "string" && processed.has(row.id))) {
38
+ throw new PermanentPollError("Outlook cursor is stuck on a full timestamp boundary; increase maxMessagesPerPoll and resume the Trigger.");
39
+ }
40
+ const boundary = new Set(moved ? [] : checkpoint.boundaryMessageIds);
41
+ const events = [];
42
+ let filtered = 0;
43
+ for (const row of rows) {
44
+ if (row.id == null || row.id.length == 0)
45
+ continue;
46
+ if (isoMs(row.receivedDateTime) == watermarkMs)
47
+ boundary.add(row.id);
48
+ if (processed.has(row.id))
49
+ continue;
50
+ if (!matches(row, config)) {
51
+ filtered += 1;
52
+ continue;
53
+ }
54
+ events.push(event(row, row.id));
55
+ }
56
+ const hasMore = full && (moved || events.length > 0);
57
+ return {
58
+ checkpoint: { boundaryMessageIds: [...boundary], lastReceivedDateTime: watermark },
59
+ events,
60
+ filtered,
61
+ ...(hasMore ? { hasMore: true } : {}),
62
+ };
63
+ },
64
+ };
65
+ function resolveConfig(value) {
66
+ return {
67
+ folder: value.folder,
68
+ includeDrafts: value.includeDrafts,
69
+ maxMessagesPerPoll: value.maxMessagesPerPoll,
70
+ readStatus: value.readStatus,
71
+ senderAddress: value.senderAddress.trim(),
72
+ subjectContains: value.subjectContains.trim(),
73
+ withAttachmentsOnly: value.withAttachmentsOnly,
74
+ };
75
+ }
76
+ async function seed(context, config) {
77
+ const marker = await get(context, endpoint(config.folder), {
78
+ $orderby: "receivedDateTime desc",
79
+ $select: "id,receivedDateTime",
80
+ $top: markerPageSize,
81
+ });
82
+ success(marker, "seed marker fetch");
83
+ const shape = await get(context, endpoint(config.folder), {
84
+ $filter: filter(config, seedAnchor),
85
+ $orderby: "receivedDateTime desc",
86
+ $top: 1,
87
+ });
88
+ success(shape, "seed filter shape check");
89
+ const newest = newestMessage(messages(marker.data));
90
+ if (newest == null)
91
+ return { boundaryMessageIds: [], lastReceivedDateTime: context.now.toISOString() };
92
+ const boundary = messages(marker.data).filter((row) => isoMs(row.receivedDateTime) == newest.ms);
93
+ if (boundary.length >= config.maxMessagesPerPoll) {
94
+ return {
95
+ boundaryMessageIds: [],
96
+ lastReceivedDateTime: new Date(newest.ms + 1_000).toISOString(),
97
+ };
98
+ }
99
+ return {
100
+ boundaryMessageIds: boundary.flatMap((row) => (row.id == null || row.id.length == 0 ? [] : [row.id])),
101
+ lastReceivedDateTime: newest.iso,
102
+ };
103
+ }
104
+ function readCheckpoint(value) {
105
+ const checkpoint = record(value);
106
+ const watermark = checkpoint?.lastReceivedDateTime;
107
+ if (typeof watermark != "string" || isoMs(watermark) == null) {
108
+ throw new PermanentPollError("Outlook checkpoint is invalid; recreate the Trigger.");
109
+ }
110
+ const boundary = checkpoint?.boundaryMessageIds;
111
+ return {
112
+ boundaryMessageIds: Array.isArray(boundary)
113
+ ? boundary.filter((id) => typeof id == "string" && id.length > 0)
114
+ : [],
115
+ lastReceivedDateTime: watermark,
116
+ };
117
+ }
118
+ function endpoint(folder) {
119
+ return folder.length == 0 ? "/me/messages" : `/me/mailFolders/${encodeURIComponent(folder)}/messages`;
120
+ }
121
+ function filter(config, watermark) {
122
+ const clauses = [`receivedDateTime ge ${watermark}`];
123
+ if (config.readStatus == "Unread")
124
+ clauses.push("isRead eq false");
125
+ if (config.readStatus == "Read")
126
+ clauses.push("isRead eq true");
127
+ if (config.withAttachmentsOnly)
128
+ clauses.push("hasAttachments eq true");
129
+ if (config.senderAddress.length > 0)
130
+ clauses.push(`from/emailAddress/address eq '${config.senderAddress.replaceAll("'", "''")}'`);
131
+ return clauses.join(" and ");
132
+ }
133
+ function matches(message, config) {
134
+ if (message.isDraft === true && !config.includeDrafts)
135
+ return false;
136
+ return (config.subjectContains.length == 0 ||
137
+ (message.subject ?? "").toLowerCase().includes(config.subjectContains.toLowerCase()));
138
+ }
139
+ function event(message, id) {
140
+ return {
141
+ dedupeKey: id,
142
+ payload: {
143
+ bodyPreview: message.bodyPreview ?? "",
144
+ categories: message.categories ?? [],
145
+ conversationId: message.conversationId ?? "",
146
+ from: message.from?.emailAddress?.address ?? "",
147
+ fromName: message.from?.emailAddress?.name ?? "",
148
+ hasAttachments: message.hasAttachments ?? false,
149
+ importance: message.importance ?? "",
150
+ internetMessageId: message.internetMessageId ?? "",
151
+ isDraft: message.isDraft ?? false,
152
+ isRead: message.isRead ?? false,
153
+ messageId: id,
154
+ parentFolderId: message.parentFolderId ?? "",
155
+ receivedDateTime: message.receivedDateTime ?? "",
156
+ subject: message.subject ?? "",
157
+ to: (message.toRecipients ?? []).flatMap(({ emailAddress }) => emailAddress?.address == null ? [] : [emailAddress.address]),
158
+ webLink: message.webLink ?? "",
159
+ },
160
+ };
161
+ }
162
+ async function get(context, path, query) {
163
+ try {
164
+ return await context.connector.execute({ endpoint: path, headers: { Prefer: 'IdType="ImmutableId"' }, method: "GET", query }, context.signal);
165
+ }
166
+ catch (cause) {
167
+ throw new TransientPollError(`Outlook proxy request to ${path} failed.`, { cause });
168
+ }
169
+ }
170
+ function success(result, operation) {
171
+ if (result.status >= 200 && result.status < 300)
172
+ return;
173
+ const codes = errorCodes(result.data);
174
+ if (result.status == 401)
175
+ throw new PollConnectionError(`Outlook ${operation} rejected the Connection.`);
176
+ if (result.status == 403 && codes.has("mailboxnotenabledforrestapi")) {
177
+ throw new PermanentPollError("The Outlook mailbox is not reachable through the Graph mail APIs.");
178
+ }
179
+ if (result.status == 403 && (codes.has("accessdenied") || codes.has("erroraccessdenied"))) {
180
+ throw new PollConnectionError(`Outlook ${operation} rejected the Connection.`);
181
+ }
182
+ if (result.status == 404 && (codes.has("erroritemnotfound") || codes.has("itemnotfound"))) {
183
+ throw new PermanentPollError("The configured Outlook folder does not exist.");
184
+ }
185
+ if (result.status == 400 && (codes.has("errorinvalididmalformed") || codes.has("inefficientfilter"))) {
186
+ throw new PermanentPollError("Outlook rejected the configured folder or filters.");
187
+ }
188
+ throw new TransientPollError(`Outlook ${operation} failed with status ${result.status}.`);
189
+ }
190
+ function errorCodes(data) {
191
+ const codes = new Set();
192
+ let value = record(data)?.error;
193
+ for (let depth = 0; depth < 4; depth += 1) {
194
+ const error = record(value);
195
+ if (error == null)
196
+ break;
197
+ if (typeof error.code == "string" && error.code.length > 0)
198
+ codes.add(error.code.toLowerCase());
199
+ value = error.innerError ?? error.innererror;
200
+ }
201
+ return codes;
202
+ }
203
+ function messages(data) {
204
+ const value = record(data)?.value;
205
+ return Array.isArray(value) ? value : [];
206
+ }
207
+ function newestMessage(rows) {
208
+ let newest = null;
209
+ for (const row of rows) {
210
+ const ms = isoMs(row.receivedDateTime);
211
+ if (row.receivedDateTime != null && ms != null && (newest == null || ms > newest.ms))
212
+ newest = { iso: row.receivedDateTime, ms };
213
+ }
214
+ return newest;
215
+ }
216
+ function isoMs(value) {
217
+ if (value == null || value.length == 0)
218
+ return null;
219
+ const milliseconds = Date.parse(value);
220
+ return Number.isNaN(milliseconds) ? null : milliseconds;
221
+ }
222
+ function record(value) {
223
+ return value != null && typeof value == "object" && !Array.isArray(value)
224
+ ? value
225
+ : undefined;
226
+ }