@oomol-lab/open-connector 1.7.0 → 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 (288) 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 +916 -76
  4. package/assets/open-connector/catalog/apps/cal.json +24 -6
  5. package/assets/open-connector/catalog/apps/discordbot.json +2 -2
  6. package/assets/open-connector/catalog/apps/enormail.json +411 -0
  7. package/assets/open-connector/catalog/apps/feishu_app_bot.json +158 -0
  8. package/assets/open-connector/catalog/apps/github.json +275 -0
  9. package/assets/open-connector/catalog/apps/gitlab.json +125 -0
  10. package/assets/open-connector/catalog/apps/gmail.json +151 -0
  11. package/assets/open-connector/catalog/apps/googlecalendar.json +206 -0
  12. package/assets/open-connector/catalog/apps/googledrive.json +479 -0
  13. package/assets/open-connector/catalog/apps/googlesheets.json +144 -0
  14. package/assets/open-connector/catalog/apps/hithink_finance.json +6 -3
  15. package/assets/open-connector/catalog/apps/indexed.json +1115 -0
  16. package/assets/open-connector/catalog/apps/linear.json +116 -0
  17. package/assets/open-connector/catalog/apps/notion.json +142 -0
  18. package/assets/open-connector/catalog/apps/one_drive.json +185 -0
  19. package/assets/open-connector/catalog/apps/outlook.json +182 -0
  20. package/assets/open-connector/catalog/apps/shopify.json +282 -0
  21. package/assets/open-connector/catalog/apps/slack.json +182 -0
  22. package/assets/open-connector/catalog/apps/spotify.json +46 -43
  23. package/assets/open-connector/catalog/apps/stripe.json +96 -0
  24. package/assets/open-connector/catalog/apps/telegram.json +138 -0
  25. package/assets/open-connector/catalog/apps/weixin_store.json +543 -2
  26. package/assets/open-connector/catalog/apps/woocommerce.json +127 -0
  27. package/assets/open-connector/catalog/apps/zendesk.json +152 -0
  28. package/assets/open-connector/catalog/apps/zerotier.json +9 -9
  29. package/assets/open-connector/catalog/apps-index.json +1 -1
  30. package/assets/open-connector/migrations/0014_saas_project.sql +55 -0
  31. package/assets/open-connector/migrations/0015_saas_cleanup_runtime.sql +8 -0
  32. package/assets/open-connector/migrations/0016_trigger_policy.sql +1 -0
  33. package/assets/open-connector/migrations/0017_trigger_subscriptions.sql +17 -0
  34. package/assets/open-connector/migrations/postgresql/0014_saas_project.sql +55 -0
  35. package/assets/open-connector/migrations/postgresql/0015_saas_cleanup_runtime.sql +8 -0
  36. package/assets/open-connector/migrations/postgresql/0016_trigger_policy.sql +1 -0
  37. package/assets/open-connector/migrations/postgresql/0017_trigger_subscriptions.sql +17 -0
  38. package/package.json +2 -2
  39. package/src/connection-service.d.ts +40 -7
  40. package/src/connection-service.js +60 -18
  41. package/src/core/action-policy.d.ts +8 -1
  42. package/src/core/action-policy.js +51 -0
  43. package/src/core/cast.d.ts +3 -0
  44. package/src/core/cast.js +4 -1
  45. package/src/core/guarded-fetch.d.ts +5 -0
  46. package/src/core/guarded-fetch.js +13 -4
  47. package/src/core/remote-http.d.ts +33 -0
  48. package/src/core/remote-http.js +104 -0
  49. package/src/core/request.d.ts +1 -0
  50. package/src/core/request.js +7 -0
  51. package/src/core/types.d.ts +4 -0
  52. package/src/marketplace/marketplace-service.d.ts +0 -1
  53. package/src/marketplace/marketplace-service.js +80 -92
  54. package/src/mcp.js +19 -5
  55. package/src/oauth/oauth-flow-service.d.ts +8 -1
  56. package/src/oauth/oauth-flow-service.js +10 -4
  57. package/src/providers/action-contracts.generated.d.ts +4 -2
  58. package/src/providers/airtable/executors.d.ts +3 -0
  59. package/src/providers/airtable/executors.js +2 -0
  60. package/src/providers/airtable/trigger-on-record-changed.d.ts +2 -0
  61. package/src/providers/airtable/trigger-on-record-changed.definition.d.ts +4 -0
  62. package/src/providers/airtable/trigger-on-record-changed.definition.js +54 -0
  63. package/src/providers/airtable/trigger-on-record-changed.js +235 -0
  64. package/src/providers/aisa/executors.js +196 -22
  65. package/src/providers/cal/actions.js +5 -1
  66. package/src/providers/enormail/executors.d.ts +4 -0
  67. package/src/providers/enormail/executors.js +97 -0
  68. package/src/providers/feishu_app_bot/executors.d.ts +3 -0
  69. package/src/providers/feishu_app_bot/executors.js +2 -0
  70. package/src/providers/feishu_app_bot/trigger-config.d.ts +1 -0
  71. package/src/providers/feishu_app_bot/trigger-config.js +10 -0
  72. package/src/providers/feishu_app_bot/trigger-on-event.d.ts +2 -0
  73. package/src/providers/feishu_app_bot/trigger-on-event.definition.d.ts +4 -0
  74. package/src/providers/feishu_app_bot/trigger-on-event.definition.js +63 -0
  75. package/src/providers/feishu_app_bot/trigger-on-event.js +29 -0
  76. package/src/providers/feishu_app_bot/trigger-subscriptions.d.ts +5 -0
  77. package/src/providers/feishu_app_bot/trigger-subscriptions.js +70 -0
  78. package/src/providers/github/executors.d.ts +3 -0
  79. package/src/providers/github/executors.js +6 -0
  80. package/src/providers/github/trigger-on-repo-event.d.ts +2 -0
  81. package/src/providers/github/trigger-on-repo-event.definition.d.ts +4 -0
  82. package/src/providers/github/trigger-on-repo-event.definition.js +94 -0
  83. package/src/providers/github/trigger-on-repo-event.js +168 -0
  84. package/src/providers/github/trigger-watch-pull-request.d.ts +2 -0
  85. package/src/providers/github/trigger-watch-pull-request.definition.d.ts +4 -0
  86. package/src/providers/github/trigger-watch-pull-request.definition.js +49 -0
  87. package/src/providers/github/trigger-watch-pull-request.js +106 -0
  88. package/src/providers/gitlab/executors.d.ts +3 -0
  89. package/src/providers/gitlab/executors.js +2 -0
  90. package/src/providers/gitlab/trigger-on-project-event.d.ts +2 -0
  91. package/src/providers/gitlab/trigger-on-project-event.definition.d.ts +5 -0
  92. package/src/providers/gitlab/trigger-on-project-event.definition.js +63 -0
  93. package/src/providers/gitlab/trigger-on-project-event.js +186 -0
  94. package/src/providers/gmail/executors.d.ts +3 -0
  95. package/src/providers/gmail/executors.js +2 -0
  96. package/src/providers/gmail/trigger-on-message-received.d.ts +2 -0
  97. package/src/providers/gmail/trigger-on-message-received.definition.d.ts +4 -0
  98. package/src/providers/gmail/trigger-on-message-received.definition.js +74 -0
  99. package/src/providers/gmail/trigger-on-message-received.js +232 -0
  100. package/src/providers/googlecalendar/executors.d.ts +3 -0
  101. package/src/providers/googlecalendar/executors.js +2 -0
  102. package/src/providers/googlecalendar/trigger-on-event-changed.d.ts +2 -0
  103. package/src/providers/googlecalendar/trigger-on-event-changed.definition.d.ts +4 -0
  104. package/src/providers/googlecalendar/trigger-on-event-changed.definition.js +74 -0
  105. package/src/providers/googlecalendar/trigger-on-event-changed.js +233 -0
  106. package/src/providers/googledrive/executors.d.ts +3 -0
  107. package/src/providers/googledrive/executors.js +7 -0
  108. package/src/providers/googledrive/trigger-changes.d.ts +12 -0
  109. package/src/providers/googledrive/trigger-changes.definition.d.ts +7 -0
  110. package/src/providers/googledrive/trigger-changes.definition.js +101 -0
  111. package/src/providers/googledrive/trigger-changes.js +452 -0
  112. package/src/providers/googledrive/trigger-on-file-change.d.ts +2 -0
  113. package/src/providers/googledrive/trigger-on-file-change.definition.d.ts +4 -0
  114. package/src/providers/googledrive/trigger-on-file-change.definition.js +77 -0
  115. package/src/providers/googledrive/trigger-on-file-change.js +258 -0
  116. package/src/providers/googlesheets/executors.d.ts +3 -0
  117. package/src/providers/googlesheets/executors.js +2 -0
  118. package/src/providers/googlesheets/trigger-on-row-added.d.ts +2 -0
  119. package/src/providers/googlesheets/trigger-on-row-added.definition.d.ts +4 -0
  120. package/src/providers/googlesheets/trigger-on-row-added.definition.js +54 -0
  121. package/src/providers/googlesheets/trigger-on-row-added.js +234 -0
  122. package/src/providers/hithink_finance/runtime.js +1 -1
  123. package/src/providers/indexed/executors.d.ts +4 -0
  124. package/src/providers/indexed/executors.js +16 -0
  125. package/src/providers/indexed/runtime.d.ts +26 -0
  126. package/src/providers/indexed/runtime.js +129 -0
  127. package/src/providers/linear/executors.d.ts +3 -0
  128. package/src/providers/linear/executors.js +2 -0
  129. package/src/providers/linear/trigger-on-issue-changed.d.ts +2 -0
  130. package/src/providers/linear/trigger-on-issue-changed.definition.d.ts +5 -0
  131. package/src/providers/linear/trigger-on-issue-changed.definition.js +43 -0
  132. package/src/providers/linear/trigger-on-issue-changed.js +215 -0
  133. package/src/providers/notion/executors.d.ts +3 -0
  134. package/src/providers/notion/executors.js +2 -0
  135. package/src/providers/notion/trigger-on-database-page-event.d.ts +2 -0
  136. package/src/providers/notion/trigger-on-database-page-event.definition.d.ts +4 -0
  137. package/src/providers/notion/trigger-on-database-page-event.definition.js +63 -0
  138. package/src/providers/notion/trigger-on-database-page-event.js +293 -0
  139. package/src/providers/one_drive/executors.d.ts +3 -0
  140. package/src/providers/one_drive/executors.js +2 -0
  141. package/src/providers/one_drive/trigger-on-item-changed.d.ts +2 -0
  142. package/src/providers/one_drive/trigger-on-item-changed.definition.d.ts +4 -0
  143. package/src/providers/one_drive/trigger-on-item-changed.definition.js +63 -0
  144. package/src/providers/one_drive/trigger-on-item-changed.js +214 -0
  145. package/src/providers/outlook/executors.d.ts +3 -0
  146. package/src/providers/outlook/executors.js +2 -0
  147. package/src/providers/outlook/trigger-on-message-received.d.ts +2 -0
  148. package/src/providers/outlook/trigger-on-message-received.definition.d.ts +4 -0
  149. package/src/providers/outlook/trigger-on-message-received.definition.js +93 -0
  150. package/src/providers/outlook/trigger-on-message-received.js +226 -0
  151. package/src/providers/outlook_calendar/executors.js +6 -0
  152. package/src/providers/provider-loader.d.ts +5 -0
  153. package/src/providers/provider-loader.js +4 -0
  154. package/src/providers/registry.generated.js +2 -0
  155. package/src/providers/shopify/executors.d.ts +3 -0
  156. package/src/providers/shopify/executors.js +2 -0
  157. package/src/providers/shopify/trigger-on-shop-event.d.ts +2 -0
  158. package/src/providers/shopify/trigger-on-shop-event.definition.d.ts +4 -0
  159. package/src/providers/shopify/trigger-on-shop-event.definition.js +214 -0
  160. package/src/providers/shopify/trigger-on-shop-event.js +165 -0
  161. package/src/providers/slack/executors.d.ts +3 -0
  162. package/src/providers/slack/executors.js +2 -0
  163. package/src/providers/slack/trigger-on-message-posted.d.ts +2 -0
  164. package/src/providers/slack/trigger-on-message-posted.definition.d.ts +4 -0
  165. package/src/providers/slack/trigger-on-message-posted.definition.js +80 -0
  166. package/src/providers/slack/trigger-on-message-posted.js +176 -0
  167. package/src/providers/spotify/runtime.js +15 -4
  168. package/src/providers/stripe/executors.d.ts +3 -0
  169. package/src/providers/stripe/executors.js +2 -0
  170. package/src/providers/stripe/trigger-on-event.d.ts +2 -0
  171. package/src/providers/stripe/trigger-on-event.definition.d.ts +4 -0
  172. package/src/providers/stripe/trigger-on-event.definition.js +43 -0
  173. package/src/providers/stripe/trigger-on-event.js +212 -0
  174. package/src/providers/telegram/executors.d.ts +3 -0
  175. package/src/providers/telegram/executors.js +2 -0
  176. package/src/providers/telegram/trigger-on-update.d.ts +2 -0
  177. package/src/providers/telegram/trigger-on-update.definition.d.ts +5 -0
  178. package/src/providers/telegram/trigger-on-update.definition.js +78 -0
  179. package/src/providers/telegram/trigger-on-update.js +141 -0
  180. package/src/providers/weixin_store/access-token.d.ts +2 -1
  181. package/src/providers/weixin_store/access-token.js +15 -4
  182. package/src/providers/weixin_store/executors.js +97 -12
  183. package/src/providers/woocommerce/executors.d.ts +3 -0
  184. package/src/providers/woocommerce/executors.js +2 -0
  185. package/src/providers/woocommerce/trigger-on-store-event.d.ts +2 -0
  186. package/src/providers/woocommerce/trigger-on-store-event.definition.d.ts +4 -0
  187. package/src/providers/woocommerce/trigger-on-store-event.definition.js +55 -0
  188. package/src/providers/woocommerce/trigger-on-store-event.js +179 -0
  189. package/src/providers/zendesk/executors.d.ts +3 -0
  190. package/src/providers/zendesk/executors.js +2 -0
  191. package/src/providers/zendesk/trigger-on-event.d.ts +2 -0
  192. package/src/providers/zendesk/trigger-on-event.definition.d.ts +5 -0
  193. package/src/providers/zendesk/trigger-on-event.definition.js +101 -0
  194. package/src/providers/zendesk/trigger-on-event.js +188 -0
  195. package/src/saas/saas-cleanup-service.d.ts +26 -0
  196. package/src/saas/saas-cleanup-service.js +124 -0
  197. package/src/saas/saas-client.d.ts +86 -0
  198. package/src/saas/saas-client.js +369 -0
  199. package/src/saas/saas-execution-service.d.ts +15 -0
  200. package/src/saas/saas-execution-service.js +21 -0
  201. package/src/saas/saas-oauth-service.d.ts +25 -0
  202. package/src/saas/saas-oauth-service.js +197 -0
  203. package/src/saas/saas-project-service.d.ts +61 -0
  204. package/src/saas/saas-project-service.js +211 -0
  205. package/src/server/actions/action-idempotency.d.ts +1 -0
  206. package/src/server/actions/action-idempotency.js +1 -0
  207. package/src/server/actions/action-runner.d.ts +7 -0
  208. package/src/server/actions/action-runner.js +43 -7
  209. package/src/server/actions/run-log-summary.js +9 -0
  210. package/src/server/api/auth.d.ts +1 -0
  211. package/src/server/api/auth.js +13 -2
  212. package/src/server/api/cache-policy.js +4 -1
  213. package/src/server/api/connection-input.d.ts +7 -1
  214. package/src/server/api/connection-input.js +7 -1
  215. package/src/server/api/connection-routes.d.ts +3 -1
  216. package/src/server/api/connection-routes.js +21 -3
  217. package/src/server/api/http-utils.d.ts +4 -3
  218. package/src/server/api/oauth-completion-page.d.ts +124 -0
  219. package/src/server/api/oauth-completion-page.js +113 -18
  220. package/src/server/api/openapi.js +112 -14
  221. package/src/server/api/policy-input.js +6 -0
  222. package/src/server/api/runtime-api.d.ts +10 -2
  223. package/src/server/api/runtime-api.js +17 -4
  224. package/src/server/api/saas-completion-page.d.ts +2 -0
  225. package/src/server/api/saas-completion-page.js +103 -0
  226. package/src/server/connect-app.d.ts +5 -0
  227. package/src/server/connect-app.js +50 -0
  228. package/src/server/connect-server.d.ts +12 -0
  229. package/src/server/connect-server.js +147 -13
  230. package/src/server/connector-runtime.d.ts +3 -1
  231. package/src/server/connector-runtime.js +5 -2
  232. package/src/server/files/transit-files.js +16 -7
  233. package/src/server/proxy/proxy-runner.d.ts +5 -1
  234. package/src/server/proxy/proxy-runner.js +72 -26
  235. package/src/server/storage/connection-request-store.d.ts +41 -1
  236. package/src/server/storage/connection-request-store.js +245 -20
  237. package/src/server/storage/connection-store.d.ts +16 -0
  238. package/src/server/storage/connection-store.js +119 -0
  239. package/src/server/storage/node-runtime-database.js +3 -3
  240. package/src/server/storage/{postgres-migrations.d.ts → postgres/migrations.d.ts} +2 -2
  241. package/src/server/storage/{postgres-migrations.js → postgres/migrations.js} +1 -1
  242. package/src/server/storage/postgres/runtime-store.d.ts +43 -0
  243. package/src/server/storage/{postgres-runtime-store.js → postgres/runtime-store.js} +59 -94
  244. package/src/server/storage/runtime-database.d.ts +4 -0
  245. package/src/server/storage/runtime-sql.d.ts +1 -1
  246. package/src/server/storage/runtime-sql.js +2 -1
  247. package/src/server/storage/runtime-store.d.ts +1 -0
  248. package/src/server/storage/runtime-token-service.d.ts +2 -0
  249. package/src/server/storage/runtime-token-service.js +3 -0
  250. package/src/server/storage/saas-project-store.d.ts +77 -0
  251. package/src/server/storage/saas-project-store.js +273 -0
  252. package/src/server/storage/{sqlite-runtime-store.d.ts → sqlite/runtime-store.d.ts} +21 -25
  253. package/src/server/storage/{sqlite-runtime-store.js → sqlite/runtime-store.js} +100 -115
  254. package/src/server/storage/trigger-store.d.ts +16 -0
  255. package/src/server/storage/trigger-store.js +96 -0
  256. package/src/triggers/common/config.d.ts +2 -0
  257. package/src/triggers/common/config.js +17 -0
  258. package/src/triggers/common/configOptions.d.ts +13 -0
  259. package/src/triggers/common/configOptions.js +1 -0
  260. package/src/triggers/common/encoding.d.ts +3 -0
  261. package/src/triggers/common/encoding.js +19 -0
  262. package/src/triggers/common/integration.d.ts +115 -0
  263. package/src/triggers/common/integration.js +31 -0
  264. package/src/triggers/common/json.d.ts +6 -0
  265. package/src/triggers/common/json.js +91 -0
  266. package/src/triggers/common/poll.d.ts +41 -0
  267. package/src/triggers/common/poll.js +15 -0
  268. package/src/triggers/common/proxy.d.ts +14 -0
  269. package/src/triggers/common/proxy.js +1 -0
  270. package/src/triggers/common/types.d.ts +42 -0
  271. package/src/triggers/common/types.js +1 -0
  272. package/src/triggers/maintenance.d.ts +40 -0
  273. package/src/triggers/maintenance.js +120 -0
  274. package/src/triggers/metadata.d.ts +8 -0
  275. package/src/triggers/metadata.js +1 -0
  276. package/src/triggers/request.d.ts +33 -0
  277. package/src/triggers/request.js +52 -0
  278. package/src/triggers/resources.d.ts +12 -0
  279. package/src/triggers/resources.js +121 -0
  280. package/src/triggers/signature.d.ts +4 -0
  281. package/src/triggers/signature.js +48 -0
  282. package/src/triggers/store.d.ts +29 -0
  283. package/src/triggers/store.js +1 -0
  284. package/src/triggers/subscriptions.d.ts +22 -0
  285. package/src/triggers/subscriptions.js +220 -0
  286. package/src/triggers/trigger-runner.d.ts +34 -0
  287. package/src/triggers/trigger-runner.js +169 -0
  288. package/src/server/storage/postgres-runtime-store.d.ts +0 -39
@@ -0,0 +1,115 @@
1
+ import type { TriggerConfigOption, TriggerConfigOptionsContext } from "./configOptions.ts";
2
+ import type { ConnectorProxyRequest, ConnectorProxyResult, ConnectorProxy } from "./proxy.ts";
3
+ import type { IntegrationEndpointMethod, JsonValue, TriggerKeySnapshot } from "./types.ts";
4
+ export declare const maximumIntegrationBodyBytes: number;
5
+ export declare const maximumIntegrationDeliveryPages = 5;
6
+ export interface ListenerReadContext {
7
+ readonly checkpoint: JsonValue;
8
+ readonly config: Readonly<Record<string, JsonValue>>;
9
+ readonly connector: ConnectorProxy;
10
+ readonly now: Date;
11
+ readonly signal?: AbortSignal;
12
+ }
13
+ export interface ListenerPage {
14
+ readonly checkpoint: JsonValue;
15
+ readonly dedupeKey: string;
16
+ readonly hasMore: boolean;
17
+ readonly outputs: Readonly<Record<string, JsonValue>> | null;
18
+ }
19
+ export interface ListenerSource {
20
+ readonly intervalMs: number;
21
+ readonly read: (context: ListenerReadContext) => Promise<ListenerPage>;
22
+ }
23
+ export declare function validateListenerPage(value: unknown): asserts value is ListenerPage;
24
+ export type IntegrationReceiveResult = {
25
+ readonly outcome: "wake";
26
+ } | {
27
+ readonly checkpoint?: JsonValue;
28
+ readonly continue?: boolean;
29
+ readonly dedupeKey?: string;
30
+ readonly outcome: "event";
31
+ readonly outputs: Readonly<Record<string, JsonValue>>;
32
+ } | {
33
+ readonly checkpoint?: JsonValue;
34
+ readonly continue?: boolean;
35
+ readonly outcome: "ignored";
36
+ readonly reason: string;
37
+ } | {
38
+ readonly body: string;
39
+ readonly contentType: string;
40
+ readonly headers?: Readonly<Record<string, string>>;
41
+ readonly outcome: "respond";
42
+ readonly status: number;
43
+ };
44
+ export interface IntegrationStateContext {
45
+ readonly checkpoint: JsonValue;
46
+ readonly subscription: Readonly<Record<string, JsonValue>>;
47
+ readonly saveCheckpoint: (checkpoint: JsonValue) => Promise<void>;
48
+ readonly saveSubscription: (subscription: Readonly<Record<string, JsonValue>>, reconcileAt: Date) => Promise<void>;
49
+ }
50
+ export interface IntegrationReceiveContext {
51
+ readonly eventSourceId?: string;
52
+ readonly signal?: AbortSignal;
53
+ readonly admit: boolean;
54
+ readonly allow?: () => Promise<boolean>;
55
+ readonly bindingId: string;
56
+ readonly callbackSecret: string;
57
+ readonly config: Readonly<Record<string, JsonValue>>;
58
+ readonly connector: ConnectorProxy;
59
+ readonly current: boolean;
60
+ readonly header: (name: string) => string | undefined;
61
+ readonly method: IntegrationEndpointMethod;
62
+ readonly now: Date;
63
+ readonly payload: JsonValue;
64
+ readonly query: (name: string) => string | undefined;
65
+ readonly rawBody: Uint8Array;
66
+ readonly state?: IntegrationStateContext;
67
+ }
68
+ export interface IntegrationReconcileContext {
69
+ readonly active: boolean;
70
+ readonly callbackSecret: string;
71
+ readonly config: Readonly<Record<string, JsonValue>>;
72
+ readonly connector: ConnectorProxy;
73
+ readonly endpointUrl: string;
74
+ readonly idempotencyKey: string;
75
+ readonly now: Date;
76
+ readonly signal?: AbortSignal;
77
+ readonly state?: IntegrationStateContext;
78
+ }
79
+ export interface IntegrationReconcileResult {
80
+ readonly outcome: "pending" | "ready";
81
+ }
82
+ export interface ResourceSubscription {
83
+ readonly key: string;
84
+ readonly subscribe: ConnectorProxyRequest;
85
+ readonly unsubscribe: ConnectorProxyRequest;
86
+ readonly inspect?: ConnectorProxyRequest;
87
+ }
88
+ export interface ResourceDefinition {
89
+ readonly subscriptions: (config: Readonly<Record<string, JsonValue>>) => readonly ResourceSubscription[];
90
+ readonly response: (result: ConnectorProxyResult) => Readonly<Record<string, JsonValue>>;
91
+ }
92
+ export interface IntegrationDefinition {
93
+ readonly resources?: ResourceDefinition;
94
+ readonly eventSource?: "feishu";
95
+ readonly configOptions?: (context: TriggerConfigOptionsContext) => Promise<readonly TriggerConfigOption[]>;
96
+ readonly listener?: ListenerSource;
97
+ readonly initialState?: {
98
+ readonly checkpoint: JsonValue;
99
+ readonly subscription: Readonly<Record<string, JsonValue>>;
100
+ };
101
+ readonly receive: (context: IntegrationReceiveContext) => IntegrationReceiveResult | Promise<IntegrationReceiveResult>;
102
+ readonly reconcile: (context: IntegrationReconcileContext) => Promise<IntegrationReconcileResult>;
103
+ readonly snapshot: TriggerKeySnapshot & {
104
+ readonly type: "integration";
105
+ };
106
+ }
107
+ export declare class IntegrationConnectionError extends Error {
108
+ readonly name = "IntegrationConnectionError";
109
+ }
110
+ export declare class PermanentIntegrationError extends Error {
111
+ readonly name = "PermanentIntegrationError";
112
+ }
113
+ export declare class TransientIntegrationError extends Error {
114
+ readonly name = "TransientIntegrationError";
115
+ }
@@ -0,0 +1,31 @@
1
+ import { isJsonObject, isJsonValue } from "./json.js";
2
+ export const maximumIntegrationBodyBytes = 64 * 1024;
3
+ export const maximumIntegrationDeliveryPages = 5;
4
+ const encoder = new TextEncoder();
5
+ export function validateListenerPage(value) {
6
+ if (!isJsonObject(value) ||
7
+ value.checkpoint == null ||
8
+ !isJsonValue(value.checkpoint) ||
9
+ typeof value.hasMore != "boolean") {
10
+ throw new TypeError("Listener page must contain a JSON checkpoint and a boolean hasMore.");
11
+ }
12
+ if (typeof value.dedupeKey != "string" ||
13
+ value.dedupeKey.length == 0 ||
14
+ encoder.encode(value.dedupeKey).byteLength > 1024) {
15
+ throw new TypeError("Listener page identity must contain between 1 and 1024 bytes.");
16
+ }
17
+ if (value.outputs !== null && !isJsonObject(value.outputs))
18
+ throw new TypeError("Listener page outputs must be an object or null.");
19
+ if (encoder.encode(JSON.stringify(value.checkpoint)).byteLength > 64 * 1024) {
20
+ throw new TypeError("Listener checkpoint exceeds 64 KiB.");
21
+ }
22
+ }
23
+ export class IntegrationConnectionError extends Error {
24
+ name = "IntegrationConnectionError";
25
+ }
26
+ export class PermanentIntegrationError extends Error {
27
+ name = "PermanentIntegrationError";
28
+ }
29
+ export class TransientIntegrationError extends Error {
30
+ name = "TransientIntegrationError";
31
+ }
@@ -0,0 +1,6 @@
1
+ export type JsonValue = null | boolean | number | string | readonly JsonValue[] | JsonObject;
2
+ export type JsonObject = {
3
+ readonly [key: string]: JsonValue;
4
+ };
5
+ export declare function isJsonValue(value: unknown): value is JsonValue;
6
+ export declare function isJsonObject(value: unknown): value is JsonObject;
@@ -0,0 +1,91 @@
1
+ function hasJsonShape(root) {
2
+ if (root === null || typeof root == "boolean" || typeof root == "string")
3
+ return true;
4
+ if (typeof root == "number")
5
+ return Number.isFinite(root);
6
+ if (typeof root != "object")
7
+ return false;
8
+ const ancestors = new Set();
9
+ const pending = [];
10
+ let value = root;
11
+ traversal: while (true) {
12
+ let keys;
13
+ let arrayLength;
14
+ if (Array.isArray(value)) {
15
+ arrayLength = value.length;
16
+ keys = Reflect.ownKeys(value);
17
+ if (keys.length != arrayLength + 1)
18
+ return false;
19
+ }
20
+ else {
21
+ const prototype = Reflect.getPrototypeOf(value);
22
+ if (prototype != Object.prototype && prototype != null)
23
+ return false;
24
+ keys = Reflect.ownKeys(value);
25
+ arrayLength = undefined;
26
+ }
27
+ ancestors.add(value);
28
+ let index = 0;
29
+ while (true) {
30
+ if (index >= keys.length) {
31
+ ancestors.delete(value);
32
+ const parent = pending.pop();
33
+ if (parent === undefined)
34
+ return true;
35
+ value = parent.value;
36
+ keys = parent.keys;
37
+ arrayLength = parent.arrayLength;
38
+ index = parent.index;
39
+ continue;
40
+ }
41
+ const key = keys[index++];
42
+ if (arrayLength !== undefined) {
43
+ if (key == "length")
44
+ continue;
45
+ if (typeof key != "string")
46
+ return false;
47
+ const arrayIndex = Number(key);
48
+ if (!Number.isSafeInteger(arrayIndex) ||
49
+ arrayIndex < 0 ||
50
+ arrayIndex >= arrayLength ||
51
+ String(arrayIndex) != key)
52
+ return false;
53
+ }
54
+ else if (typeof key != "string") {
55
+ return false;
56
+ }
57
+ const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
58
+ if (descriptor?.enumerable != true || !Object.hasOwn(descriptor, "value"))
59
+ return false;
60
+ const child = descriptor.value;
61
+ if (child === null || typeof child == "boolean" || typeof child == "string")
62
+ continue;
63
+ if (typeof child == "number") {
64
+ if (!Number.isFinite(child))
65
+ return false;
66
+ continue;
67
+ }
68
+ if (typeof child != "object" || ancestors.has(child))
69
+ return false;
70
+ pending.push({ value, keys, arrayLength, index });
71
+ value = child;
72
+ continue traversal;
73
+ }
74
+ }
75
+ }
76
+ export function isJsonValue(value) {
77
+ try {
78
+ return hasJsonShape(value);
79
+ }
80
+ catch {
81
+ return false;
82
+ }
83
+ }
84
+ export function isJsonObject(value) {
85
+ try {
86
+ return value != null && typeof value == "object" && !Array.isArray(value) && hasJsonShape(value);
87
+ }
88
+ catch {
89
+ return false;
90
+ }
91
+ }
@@ -0,0 +1,41 @@
1
+ import type { TriggerConfigOption, TriggerConfigOptionsContext } from "./configOptions.ts";
2
+ import type { ConnectorProxy } from "./proxy.ts";
3
+ import type { JsonValue, TriggerKeySnapshot } from "./types.ts";
4
+ export declare const maximumPollCheckpointBytes: number;
5
+ export declare const maximumPollDedupeKeyBytes = 1024;
6
+ export declare const maximumPollEventsPerPage = 100;
7
+ export interface PollEvent {
8
+ readonly dedupeKey: string;
9
+ readonly payload: Readonly<Record<string, JsonValue>>;
10
+ }
11
+ export interface PollResult {
12
+ readonly checkpoint: JsonValue;
13
+ readonly events: readonly PollEvent[];
14
+ readonly filtered?: number;
15
+ readonly hasMore?: boolean;
16
+ }
17
+ export interface PollContext {
18
+ readonly checkpoint: JsonValue;
19
+ readonly config: Readonly<Record<string, JsonValue>>;
20
+ readonly connector: ConnectorProxy;
21
+ readonly now: Date;
22
+ readonly signal?: AbortSignal;
23
+ }
24
+ export declare function eventsPollOutputs(events: readonly PollEvent[]): Readonly<Record<string, JsonValue>>;
25
+ export interface PollDefinition {
26
+ readonly buildOutputs: (events: readonly PollEvent[]) => Readonly<Record<string, JsonValue>>;
27
+ readonly configOptions?: (context: TriggerConfigOptionsContext) => Promise<readonly TriggerConfigOption[]>;
28
+ readonly poll: (context: PollContext) => Promise<PollResult>;
29
+ readonly snapshot: TriggerKeySnapshot & {
30
+ readonly type: "poll";
31
+ };
32
+ }
33
+ export declare class PollConnectionError extends Error {
34
+ readonly name = "PollConnectionError";
35
+ }
36
+ export declare class PermanentPollError extends Error {
37
+ readonly name = "PermanentPollError";
38
+ }
39
+ export declare class TransientPollError extends Error {
40
+ readonly name = "TransientPollError";
41
+ }
@@ -0,0 +1,15 @@
1
+ export const maximumPollCheckpointBytes = 64 * 1024;
2
+ export const maximumPollDedupeKeyBytes = 1024;
3
+ export const maximumPollEventsPerPage = 100;
4
+ export function eventsPollOutputs(events) {
5
+ return { events: events.map((event) => event.payload) };
6
+ }
7
+ export class PollConnectionError extends Error {
8
+ name = "PollConnectionError";
9
+ }
10
+ export class PermanentPollError extends Error {
11
+ name = "PermanentPollError";
12
+ }
13
+ export class TransientPollError extends Error {
14
+ name = "TransientPollError";
15
+ }
@@ -0,0 +1,14 @@
1
+ export interface ConnectorProxyRequest {
2
+ readonly body?: unknown;
3
+ readonly endpoint: string;
4
+ readonly headers?: Readonly<Record<string, string>>;
5
+ readonly method: "DELETE" | "GET" | "PATCH" | "POST" | "PUT";
6
+ readonly query?: Readonly<Record<string, boolean | number | string | null>>;
7
+ }
8
+ export interface ConnectorProxyResult {
9
+ readonly data: unknown;
10
+ readonly status: number;
11
+ }
12
+ export interface ConnectorProxy {
13
+ execute(request: ConnectorProxyRequest, signal?: AbortSignal): Promise<ConnectorProxyResult>;
14
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ export type { JsonValue } from "./json.ts";
2
+ import type { JsonValue } from "./json.ts";
3
+ export interface Port {
4
+ readonly handle: string;
5
+ readonly jsonSchema: boolean | Readonly<Record<string, unknown>>;
6
+ readonly nullable: boolean;
7
+ readonly description?: string;
8
+ }
9
+ export interface InputPort extends Port {
10
+ readonly value?: JsonValue;
11
+ }
12
+ export interface Group {
13
+ readonly group: string;
14
+ readonly collapsed?: boolean;
15
+ }
16
+ interface TriggerKeySnapshotBase {
17
+ readonly configInputs: readonly (InputPort | Group)[];
18
+ readonly definitionVersion: number;
19
+ readonly description: string;
20
+ readonly displayName: string;
21
+ readonly key: string;
22
+ readonly name: string;
23
+ readonly outputs: readonly Port[];
24
+ readonly provider: string;
25
+ }
26
+ export type IntegrationEndpointMethod = "DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT";
27
+ export type IntegrationBodyFormat = "form" | "json" | "multipart" | "text";
28
+ export interface IntegrationEndpointDeclaration {
29
+ readonly body: {
30
+ readonly allowArray: boolean;
31
+ readonly allowEmpty: boolean;
32
+ readonly formats: readonly IntegrationBodyFormat[];
33
+ };
34
+ readonly methods: readonly IntegrationEndpointMethod[];
35
+ readonly successStatus: number;
36
+ }
37
+ export type TriggerKeySnapshot = (TriggerKeySnapshotBase & {
38
+ readonly type: "poll";
39
+ }) | (TriggerKeySnapshotBase & {
40
+ readonly endpoint: IntegrationEndpointDeclaration;
41
+ readonly type: "integration";
42
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,40 @@
1
+ import type { ActionPolicyService } from "../core/action-policy.ts";
2
+ import type { RuntimeLogger } from "../core/types.ts";
3
+ import type { IRuntimePolicyStore } from "../server/storage/runtime-policy-store.ts";
4
+ import type { IRuntimeTokenStore } from "../server/storage/runtime-token-service.ts";
5
+ import type { TriggerStore } from "./store.ts";
6
+ import type { TriggerRunner } from "./trigger-runner.ts";
7
+ export interface TriggerSubscriptionSummary {
8
+ id: string;
9
+ mode: "webhook" | "resource" | "resource-set";
10
+ tokenId: string;
11
+ connectionId: string;
12
+ providerAccountId: string;
13
+ triggerId: string;
14
+ requestKey: string;
15
+ status: "active" | "deleting" | "deleted" | "abandoned";
16
+ reconcileAt: number;
17
+ }
18
+ interface TriggerMaintenanceOptions {
19
+ store: TriggerStore;
20
+ runner: TriggerRunner;
21
+ tokens: IRuntimeTokenStore;
22
+ runtimePolicy: IRuntimePolicyStore;
23
+ deploymentPolicy: ActionPolicyService;
24
+ logger?: RuntimeLogger;
25
+ }
26
+ export declare class TriggerMaintenance {
27
+ private readonly options;
28
+ private readonly shutdown;
29
+ private pending?;
30
+ private timer?;
31
+ constructor(options: TriggerMaintenanceOptions);
32
+ list(): Promise<TriggerSubscriptionSummary[]>;
33
+ cancel(id: string, signal: AbortSignal): Promise<void>;
34
+ abandon(id: string, signal: AbortSignal): Promise<void>;
35
+ run(): Promise<void>;
36
+ start(): void;
37
+ close(): Promise<void>;
38
+ private runBatch;
39
+ }
40
+ export {};
@@ -0,0 +1,120 @@
1
+ import { HttpRequestError } from "../server/api/http-utils.js";
2
+ import { withSubscription } from "./subscriptions.js";
3
+ export class TriggerMaintenance {
4
+ options;
5
+ shutdown = new AbortController();
6
+ pending;
7
+ timer;
8
+ constructor(options) {
9
+ this.options = options;
10
+ }
11
+ async list() {
12
+ return (await this.options.store.list())
13
+ .filter((record) => record.mode !== "resource-set")
14
+ .map((record) => ({
15
+ id: record.id,
16
+ mode: record.mode,
17
+ tokenId: record.tokenId,
18
+ connectionId: record.connectionId,
19
+ providerAccountId: record.providerAccountId,
20
+ triggerId: record.triggerId,
21
+ requestKey: record.requestKey,
22
+ status: record.status,
23
+ reconcileAt: record.reconcileAt,
24
+ }));
25
+ }
26
+ async cancel(id, signal) {
27
+ await withSubscription(this.options.store, id, signal, async (record, save) => {
28
+ if (record.mode === "resource-set")
29
+ throw new HttpRequestError("invalid_input", "Cancel the owning resource subscriptions.");
30
+ if (record.status === "deleted" || record.status === "abandoned")
31
+ return;
32
+ record.status = "deleting";
33
+ await save();
34
+ await this.options.runner.cleanup(record, save, signal);
35
+ });
36
+ }
37
+ async abandon(id, signal) {
38
+ await withSubscription(this.options.store, id, signal, async (record, save) => {
39
+ if (record.mode === "resource-set")
40
+ throw new HttpRequestError("invalid_input", "Abandon the owning resource subscriptions.");
41
+ if (record.status === "deleted" || record.status === "abandoned")
42
+ return;
43
+ if (record.mode === "resource")
44
+ await this.options.runner.abandonResource(record, signal);
45
+ record.status = "abandoned";
46
+ await save();
47
+ });
48
+ }
49
+ run() {
50
+ if (this.shutdown.signal.aborted)
51
+ return Promise.resolve();
52
+ this.pending ??= this.runBatch()
53
+ .catch(() => {
54
+ this.options.logger?.warn({ errorCode: "trigger_cleanup_failed" }, "Trigger cleanup batch failed; pending work is retained");
55
+ })
56
+ .finally(() => {
57
+ this.pending = undefined;
58
+ });
59
+ return this.pending;
60
+ }
61
+ start() {
62
+ if (this.timer || this.pending || this.shutdown.signal.aborted)
63
+ return;
64
+ const tick = () => {
65
+ void this.run().finally(() => {
66
+ if (this.shutdown.signal.aborted)
67
+ return;
68
+ this.timer = setTimeout(tick, 60_000);
69
+ this.timer.unref?.();
70
+ });
71
+ };
72
+ tick();
73
+ }
74
+ async close() {
75
+ this.shutdown.abort();
76
+ clearTimeout(this.timer);
77
+ await this.pending;
78
+ }
79
+ async runBatch() {
80
+ const deadline = Date.now() + 50_000;
81
+ const records = await this.options.store.listFlowTriggersForMaintenance(Date.now(), 10);
82
+ for (const candidate of records) {
83
+ if (this.shutdown.signal.aborted || Date.now() >= deadline)
84
+ return;
85
+ const signal = AbortSignal.any([
86
+ this.shutdown.signal,
87
+ AbortSignal.timeout(Math.max(1, Math.min(45_000, deadline - Date.now()))),
88
+ ]);
89
+ try {
90
+ await withSubscription(this.options.store, candidate.id, signal, async (record, save) => {
91
+ if (record.status === "deleted" || record.status === "abandoned")
92
+ return;
93
+ const token = (await this.options.tokens.list()).find((token) => token.id === record.tokenId);
94
+ const runtime = await this.options.runtimePolicy.get();
95
+ const policy = this.options.deploymentPolicy.createSnapshot(runtime?.rules, token, runtime?.updatedAt);
96
+ if (record.status === "active" &&
97
+ token &&
98
+ policy.evaluateTrigger(record.triggerId).allowed &&
99
+ policy.evaluateConnection(record.connectionId).allowed) {
100
+ await save();
101
+ return;
102
+ }
103
+ record.status = "deleting";
104
+ await save();
105
+ try {
106
+ await this.options.runner.cleanup(record, save, signal);
107
+ }
108
+ catch (error) {
109
+ if (!signal.aborted)
110
+ await save();
111
+ throw error;
112
+ }
113
+ });
114
+ }
115
+ catch {
116
+ this.options.logger?.warn({ subscriptionId: candidate.id, errorCode: "trigger_cleanup_failed" }, "Trigger subscription cleanup failed; pending work is retained");
117
+ }
118
+ }
119
+ }
120
+ }
@@ -0,0 +1,8 @@
1
+ export interface TriggerPermission {
2
+ id: string;
3
+ name: string;
4
+ description: string;
5
+ providerPermissions: readonly string[];
6
+ instructions?: string;
7
+ providerScopeAlternatives?: readonly string[];
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,33 @@
1
+ import type { JsonValue } from "./common/types.ts";
2
+ interface ConfigRequest {
3
+ config: Readonly<Record<string, JsonValue>>;
4
+ }
5
+ export type TriggerRequest = (ConfigRequest & {
6
+ operation: "options";
7
+ field: string;
8
+ }) | (ConfigRequest & {
9
+ operation: "read";
10
+ checkpoint: JsonValue;
11
+ }) | (ConfigRequest & {
12
+ operation: "reconcile";
13
+ subscriptionId?: string;
14
+ requestKey: string;
15
+ endpointUrl: string;
16
+ active: boolean;
17
+ }) | {
18
+ operation: "receive";
19
+ subscriptionId: string;
20
+ method: "GET" | "POST" | "HEAD" | "PUT" | "PATCH" | "DELETE";
21
+ headers: Record<string, string>;
22
+ query: Record<string, string>;
23
+ rawBody: string;
24
+ admit: boolean;
25
+ current: boolean;
26
+ } | (ConfigRequest & {
27
+ operation: "resource";
28
+ requestKey: string;
29
+ active: boolean;
30
+ });
31
+ export declare function readTriggerRequest(value: unknown): TriggerRequest;
32
+ export declare function triggerOperationSchema(): Record<string, unknown>;
33
+ export {};
@@ -0,0 +1,52 @@
1
+ import { z } from "zod";
2
+ import { HttpRequestError } from "../server/api/http-utils.js";
3
+ const config = z.record(z.string(), z.json());
4
+ const subscriptionId = z.string().min(1).max(128);
5
+ const requestKey = z.string().min(1).max(512);
6
+ const requestSchema = z.discriminatedUnion("operation", [
7
+ z.strictObject({ operation: z.literal("options"), config, field: z.string().min(1).max(128) }),
8
+ z.strictObject({ operation: z.literal("read"), config, checkpoint: z.json() }),
9
+ z.strictObject({
10
+ operation: z.literal("reconcile"),
11
+ config,
12
+ subscriptionId: subscriptionId.optional(),
13
+ requestKey,
14
+ endpointUrl: z.url().max(4096),
15
+ active: z.boolean(),
16
+ }),
17
+ z.strictObject({
18
+ operation: z.literal("receive"),
19
+ subscriptionId,
20
+ method: z.enum(["GET", "POST", "HEAD", "PUT", "PATCH", "DELETE"]),
21
+ headers: z.record(z.string(), z.string().max(8192)),
22
+ query: z.record(z.string(), z.string().max(8192)),
23
+ rawBody: z
24
+ .string()
25
+ .max(90000)
26
+ .regex(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/),
27
+ admit: z.boolean(),
28
+ current: z.boolean(),
29
+ }),
30
+ z.strictObject({ operation: z.literal("resource"), config, requestKey, active: z.boolean() }),
31
+ ]);
32
+ export function readTriggerRequest(value) {
33
+ const result = requestSchema.safeParse(value);
34
+ if (!result.success)
35
+ throw new HttpRequestError("invalid_input", "Invalid Trigger operation input.");
36
+ if (result.data.operation === "read" && Buffer.byteLength(JSON.stringify(result.data.checkpoint)) > 65536)
37
+ throw new HttpRequestError("invalid_input", "Trigger checkpoint exceeds 64 KiB.");
38
+ if (result.data.operation === "receive") {
39
+ const headers = {};
40
+ for (const [key, value] of Object.entries(result.data.headers)) {
41
+ const name = key.toLowerCase();
42
+ if (name in headers)
43
+ throw new HttpRequestError("invalid_input", "Duplicate webhook header.");
44
+ headers[name] = value;
45
+ }
46
+ result.data.headers = headers;
47
+ }
48
+ return result.data;
49
+ }
50
+ export function triggerOperationSchema() {
51
+ return z.toJSONSchema(requestSchema);
52
+ }
@@ -0,0 +1,12 @@
1
+ import type { IntegrationReconcileResult, ResourceDefinition } from "./common/integration.ts";
2
+ import type { ConnectorProxy } from "./common/proxy.ts";
3
+ import type { TriggerRequest } from "./request.ts";
4
+ import type { TriggerSubscription, TriggerStore } from "./store.ts";
5
+ import type { SubscriptionOwner } from "./subscriptions.ts";
6
+ export declare function executeResourceSubscription(store: TriggerStore, definition: ResourceDefinition, owner: SubscriptionOwner, input: Extract<TriggerRequest, {
7
+ operation: "resource";
8
+ }>, proxy: ConnectorProxy, signal: AbortSignal): Promise<IntegrationReconcileResult>;
9
+ export declare function executeResourceSubscriptionOperation(store: TriggerStore, definition: ResourceDefinition, consumer: TriggerSubscription, saveConsumer: () => Promise<void>, input: Extract<TriggerRequest, {
10
+ operation: "resource";
11
+ }>, proxy: ConnectorProxy, signal: AbortSignal): Promise<IntegrationReconcileResult>;
12
+ export declare function abandonResourceSubscription(store: TriggerStore, definition: ResourceDefinition, consumer: TriggerSubscription, signal: AbortSignal): Promise<void>;