@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
@@ -1,18 +1,20 @@
1
- import type { IConnectionStore, StoredConnection } from "../../connection-service.ts";
2
- import type { TokenPolicy } from "../../core/action-policy.ts";
3
- import type { ResolvedCredential, RuntimeLogger } from "../../core/types.ts";
4
- import type { IMarketplaceStore, ProviderPreference, StoredMarketplaceConfig } from "../../marketplace/marketplace-service.ts";
5
- import type { IOAuthClientConfigStore, OAuthClientConfig } from "../../oauth/oauth-client-config-service.ts";
6
- import type { IOAuthStateStore, OAuthAuthorizationState } from "../../oauth/oauth-flow-service.ts";
7
- import type { ISecretCodec } from "../secrets/secret-codec-core.ts";
8
- import type { CompleteIdempotencyInput, IdempotencyClaimInput, IdempotencyClaimResult, IIdempotencyStore } from "./idempotency-store.ts";
9
- import type { MigrationSource } from "./migration-source.ts";
10
- import type { RuntimeDatabase } from "./runtime-database.ts";
11
- import type { IRuntimePolicyStore, RuntimePolicyRecord } from "./runtime-policy-store.ts";
12
- import type { IRunLogStore, RunLog, RunLogListInput, RunLogPage, RunLogWriteResult } from "./runtime-store.ts";
13
- import type { IRuntimeTokenStore, RuntimeTokenRecord } from "./runtime-token-service.ts";
1
+ import type { TokenPolicy } from "../../../core/action-policy.ts";
2
+ import type { RuntimeLogger } from "../../../core/types.ts";
3
+ import type { IMarketplaceStore, ProviderPreference, StoredMarketplaceConfig } from "../../../marketplace/marketplace-service.ts";
4
+ import type { IOAuthClientConfigStore, OAuthClientConfig } from "../../../oauth/oauth-client-config-service.ts";
5
+ import type { IOAuthStateStore, OAuthAuthorizationState } from "../../../oauth/oauth-flow-service.ts";
6
+ import type { ISecretCodec } from "../../secrets/secret-codec-core.ts";
7
+ import type { CompleteIdempotencyInput, IdempotencyClaimInput, IdempotencyClaimResult, IIdempotencyStore } from "../idempotency-store.ts";
8
+ import type { MigrationSource } from "../migration-source.ts";
9
+ import type { RuntimeDatabase } from "../runtime-database.ts";
10
+ import type { IRuntimePolicyStore, RuntimePolicyRecord } from "../runtime-policy-store.ts";
11
+ import type { IRunLogStore, RunLog, RunLogListInput, RunLogPage, RunLogWriteResult } from "../runtime-store.ts";
12
+ import type { IRuntimeTokenStore, RuntimeTokenRecord } from "../runtime-token-service.ts";
14
13
  import { DatabaseSync } from "node:sqlite";
15
- import { ConnectionRequestStore } from "./connection-request-store.ts";
14
+ import { ConnectionRequestStore } from "../connection-request-store.ts";
15
+ import { SqlConnectionStore } from "../connection-store.ts";
16
+ import { SaasProjectStore } from "../saas-project-store.ts";
17
+ import { SqlTriggerStore } from "../trigger-store.ts";
16
18
  export interface SqliteRuntimeDatabaseOptions {
17
19
  logger?: RuntimeLogger;
18
20
  runLimit?: number;
@@ -23,8 +25,10 @@ export interface SqliteRuntimeDatabaseOptions {
23
25
  * Shared SQLite connection for local runtime state.
24
26
  */
25
27
  export declare class SqliteRuntimeDatabase implements RuntimeDatabase {
28
+ readonly saasProjectStore: SaasProjectStore;
26
29
  readonly connectionRequestStore: ConnectionRequestStore;
27
- readonly connectionStore: SqliteConnectionStore;
30
+ readonly connectionStore: SqlConnectionStore;
31
+ readonly triggerStore: SqlTriggerStore;
28
32
  readonly oauthClientConfigStore: SqliteOAuthClientConfigStore;
29
33
  readonly oauthStateStore: SqliteOAuthStateStore;
30
34
  readonly runtimeTokenStore: SqliteRuntimeTokenStore;
@@ -49,16 +53,6 @@ export declare class SqliteMarketplaceStore implements IMarketplaceStore {
49
53
  listProviderPreferences(): Promise<ProviderPreference[]>;
50
54
  setProviderPreference(preference: ProviderPreference): Promise<void>;
51
55
  }
52
- export declare class SqliteConnectionStore implements IConnectionStore {
53
- private readonly database;
54
- private readonly secretCodec;
55
- constructor(database: DatabaseSync, secretCodec: ISecretCodec);
56
- get(service: string, connectionName: string): Promise<StoredConnection | undefined>;
57
- set(service: string, connectionName: string, credential: ResolvedCredential): Promise<StoredConnection>;
58
- updateCredential(input: StoredConnection): Promise<boolean>;
59
- delete(service: string, connectionName: string): Promise<void>;
60
- list(): Promise<StoredConnection[]>;
61
- }
62
56
  export declare class SqliteOAuthClientConfigStore implements IOAuthClientConfigStore {
63
57
  private readonly database;
64
58
  private readonly secretCodec;
@@ -78,6 +72,8 @@ export declare class SqliteOAuthStateStore implements IOAuthStateStore {
78
72
  }
79
73
  export declare class SqliteRuntimeTokenStore implements IRuntimeTokenStore {
80
74
  private readonly database;
75
+ private findByHashStatement?;
76
+ private markUsedStatement?;
81
77
  constructor(database: DatabaseSync);
82
78
  add(record: RuntimeTokenRecord): Promise<void>;
83
79
  list(): Promise<RuntimeTokenRecord[]>;
@@ -1,16 +1,21 @@
1
1
  import { DatabaseSync } from "node:sqlite";
2
- import { parseRuntimeActionHttpResult } from "../api/runtime-api.js";
3
- import { PlainTextSecretCodec } from "../secrets/secret-codec-core.js";
4
- import { ConnectionRequestStore } from "./connection-request-store.js";
5
- import { defaultMigrationSource } from "./migration-source.js";
6
- import { listRunLogs, parseJson, readRunLogRow, readRuntimePolicyRow, readRuntimeTokenRow, readString, runtimeTokenColumns, } from "./runtime-sql.js";
7
- import { DEFAULT_RUN_LIMIT } from "./runtime-store.js";
2
+ import { parseRuntimeActionHttpResult } from "../../api/runtime-api.js";
3
+ import { PlainTextSecretCodec } from "../../secrets/secret-codec-core.js";
4
+ import { ConnectionRequestStore } from "../connection-request-store.js";
5
+ import { SqlConnectionStore } from "../connection-store.js";
6
+ import { defaultMigrationSource } from "../migration-source.js";
7
+ import { listRunLogs, parseJson, readRunLogRow, readRuntimePolicyRow, readRuntimeTokenRow, readString, runtimeTokenColumns, } from "../runtime-sql.js";
8
+ import { DEFAULT_RUN_LIMIT } from "../runtime-store.js";
9
+ import { SaasProjectStore } from "../saas-project-store.js";
10
+ import { SqlTriggerStore } from "../trigger-store.js";
8
11
  /**
9
12
  * Shared SQLite connection for local runtime state.
10
13
  */
11
14
  export class SqliteRuntimeDatabase {
15
+ saasProjectStore;
12
16
  connectionRequestStore;
13
17
  connectionStore;
18
+ triggerStore;
14
19
  oauthClientConfigStore;
15
20
  oauthStateStore;
16
21
  runtimeTokenStore;
@@ -24,8 +29,11 @@ export class SqliteRuntimeDatabase {
24
29
  this.database = new DatabaseSync(filename);
25
30
  this.secretCodec = options.secretCodec ?? new PlainTextSecretCodec();
26
31
  this.initialize(options.migrations ?? defaultMigrationSource, options.logger);
27
- this.connectionRequestStore = new ConnectionRequestStore(async (statements) => runInTransaction(this.database, () => statements.map(({ sql, values }) => this.database.prepare(sql).all(...values))), this.secretCodec);
28
- this.connectionStore = new SqliteConnectionStore(this.database, this.secretCodec);
32
+ const transaction = async (statements) => runInTransaction(this.database, () => statements.map(({ sql, values }) => this.database.prepare(sql).all(...values)));
33
+ this.connectionRequestStore = new ConnectionRequestStore(transaction, this.secretCodec);
34
+ this.connectionStore = new SqlConnectionStore(transaction, this.secretCodec);
35
+ this.triggerStore = new SqlTriggerStore(transaction, this.secretCodec);
36
+ this.saasProjectStore = new SaasProjectStore(transaction, this.secretCodec);
29
37
  this.oauthClientConfigStore = new SqliteOAuthClientConfigStore(this.database, this.secretCodec);
30
38
  this.oauthStateStore = new SqliteOAuthStateStore(this.database, this.secretCodec);
31
39
  this.runtimeTokenStore = new SqliteRuntimeTokenStore(this.database);
@@ -38,25 +46,63 @@ export class SqliteRuntimeDatabase {
38
46
  this.database.close();
39
47
  }
40
48
  async rotateSecretCodec(nextSecretCodec) {
41
- const connections = await readRotatedConnectionSecrets(this.database, this.secretCodec, nextSecretCodec);
42
- const oauthConfigs = await readRotatedServiceSecrets(this.database, this.secretCodec, nextSecretCodec, "oauth_client_configs");
43
- const requestSecrets = await Promise.all(this.database
44
- .prepare("select id, value from connection_requests where value is not null")
45
- .all()
46
- .map(async (row) => ({
47
- id: readString(row, "id"),
48
- value: await nextSecretCodec.encode(await this.secretCodec.decode(readString(row, "value"))),
49
- })));
50
- const oauthStates = await readRotatedStateSecrets(this.database, this.secretCodec, nextSecretCodec);
51
- const idempotencyResponses = await readRotatedIdempotencySecrets(this.database, this.secretCodec, nextSecretCodec);
52
- const marketplaceConfig = await this.marketplaceStore.getConfig();
53
- const rotatedMarketplaceConfig = marketplaceConfig
54
- ? {
55
- ...marketplaceConfig,
56
- apiKeyEncrypted: await nextSecretCodec.encode(await this.secretCodec.decode(marketplaceConfig.apiKeyEncrypted)),
57
- }
58
- : undefined;
59
- runInTransaction(this.database, () => {
49
+ this.database.exec("begin immediate");
50
+ try {
51
+ const project = this.database.prepare("select value from managed_project where id = 1").get();
52
+ if (project && !nextSecretCodec.encrypted)
53
+ throw new Error("SaaS project configuration requires encrypted storage.");
54
+ const projectValue = project
55
+ ? await nextSecretCodec.encode(await this.secretCodec.decode(readString(project, "value")))
56
+ : undefined;
57
+ const candidates = await Promise.all(this.database
58
+ .prepare("select id, candidate_value from connection_requests where candidate_value is not null")
59
+ .all()
60
+ .map(async (row) => ({
61
+ id: readString(row, "id"),
62
+ value: await nextSecretCodec.encode(await this.secretCodec.decode(readString(row, "candidate_value"))),
63
+ })));
64
+ const returnUris = await Promise.all(this.database
65
+ .prepare("select id, return_uri from connection_requests where return_uri is not null")
66
+ .all()
67
+ .map(async (row) => ({
68
+ id: readString(row, "id"),
69
+ value: await nextSecretCodec.encode(await this.secretCodec.decode(readString(row, "return_uri"))),
70
+ })));
71
+ const triggerSecrets = await Promise.all(this.database
72
+ .prepare("select id, value from trigger_subscriptions")
73
+ .all()
74
+ .map(async (row) => ({
75
+ id: readString(row, "id"),
76
+ value: await nextSecretCodec.encode(await this.secretCodec.decode(readString(row, "value"))),
77
+ })));
78
+ const connections = await readRotatedConnectionSecrets(this.database, this.secretCodec, nextSecretCodec);
79
+ const oauthConfigs = await readRotatedServiceSecrets(this.database, this.secretCodec, nextSecretCodec, "oauth_client_configs");
80
+ const requestSecrets = await Promise.all(this.database
81
+ .prepare("select id, value from connection_requests where value is not null")
82
+ .all()
83
+ .map(async (row) => ({
84
+ id: readString(row, "id"),
85
+ value: await nextSecretCodec.encode(await this.secretCodec.decode(readString(row, "value"))),
86
+ })));
87
+ const oauthStates = await readRotatedStateSecrets(this.database, this.secretCodec, nextSecretCodec);
88
+ const idempotencyResponses = await readRotatedIdempotencySecrets(this.database, this.secretCodec, nextSecretCodec);
89
+ const marketplaceConfig = await this.marketplaceStore.getConfig();
90
+ const rotatedMarketplaceConfig = marketplaceConfig
91
+ ? {
92
+ ...marketplaceConfig,
93
+ apiKeyEncrypted: await nextSecretCodec.encode(await this.secretCodec.decode(marketplaceConfig.apiKeyEncrypted)),
94
+ }
95
+ : undefined;
96
+ if (projectValue)
97
+ this.database.prepare("update managed_project set value = ? where id = 1").run(projectValue);
98
+ for (const candidate of candidates)
99
+ this.database
100
+ .prepare("update connection_requests set candidate_value = ? where id = ?")
101
+ .run(candidate.value, candidate.id);
102
+ for (const uri of returnUris)
103
+ this.database.prepare("update connection_requests set return_uri = ? where id = ?").run(uri.value, uri.id);
104
+ for (const record of triggerSecrets)
105
+ this.database.prepare("update trigger_subscriptions set value = ? where id = ?").run(record.value, record.id);
60
106
  writeRotatedConnectionSecrets(this.database, connections);
61
107
  writeRotatedServiceSecrets(this.database, "oauth_client_configs", oauthConfigs);
62
108
  writeRotatedStateSecrets(this.database, oauthStates);
@@ -70,10 +116,19 @@ export class SqliteRuntimeDatabase {
70
116
  .prepare("update marketplace_config set value = ? where id = 1")
71
117
  .run(JSON.stringify(rotatedMarketplaceConfig));
72
118
  }
73
- });
119
+ this.database.exec("commit");
120
+ }
121
+ catch (error) {
122
+ this.database.exec("rollback");
123
+ throw error;
124
+ }
74
125
  }
75
126
  resetRuntimeData() {
76
- this.database.exec(`
127
+ runInTransaction(this.database, () => this.database.exec(`
128
+ delete from oauth_sources;
129
+ delete from saas_cleanup;
130
+ delete from managed_project;
131
+ delete from trigger_subscriptions;
77
132
  delete from connections;
78
133
  delete from oauth_client_configs;
79
134
  delete from oauth_states;
@@ -84,7 +139,7 @@ export class SqliteRuntimeDatabase {
84
139
  delete from idempotency_records;
85
140
  delete from marketplace_config;
86
141
  delete from provider_preferences;
87
- `);
142
+ `));
88
143
  }
89
144
  initialize(migrations, logger) {
90
145
  this.database.exec("pragma journal_mode = wal;");
@@ -125,79 +180,6 @@ export class SqliteMarketplaceStore {
125
180
  .run(preference.service, preference.enabled ? 1 : 0, preference.createdAt, preference.updatedAt);
126
181
  }
127
182
  }
128
- export class SqliteConnectionStore {
129
- database;
130
- secretCodec;
131
- constructor(database, secretCodec) {
132
- this.database = database;
133
- this.secretCodec = secretCodec;
134
- }
135
- async get(service, connectionName) {
136
- const row = this.database
137
- .prepare("select id, revision, value from connections where service = ? and connection_name = ?")
138
- .get(service, connectionName);
139
- return row
140
- ? {
141
- id: readString(row, "id"),
142
- revision: readString(row, "revision"),
143
- service,
144
- connectionName,
145
- credential: parseJson(await this.secretCodec.decode(readString(row, "value"))),
146
- }
147
- : undefined;
148
- }
149
- async set(service, connectionName, credential) {
150
- const row = this.database
151
- .prepare(`
152
- insert into connections (id, revision, service, connection_name, value, updated_at)
153
- values (?, ?, ?, ?, ?, ?)
154
- on conflict(service, connection_name) do update set
155
- revision = excluded.revision,
156
- value = excluded.value,
157
- updated_at = excluded.updated_at
158
- returning id, revision
159
- `)
160
- .get(crypto.randomUUID(), crypto.randomUUID(), service, connectionName, await this.secretCodec.encode(JSON.stringify(credential)), new Date().toISOString());
161
- if (!row) {
162
- throw new Error("Connection upsert did not return the stored row.");
163
- }
164
- return {
165
- id: readString(row, "id"),
166
- revision: readString(row, "revision"),
167
- service,
168
- connectionName,
169
- credential,
170
- };
171
- }
172
- async updateCredential(input) {
173
- const row = this.database
174
- .prepare(`
175
- update connections
176
- set revision = ?, value = ?, updated_at = ?
177
- where service = ? and connection_name = ? and id = ? and revision = ?
178
- returning id
179
- `)
180
- .get(crypto.randomUUID(), await this.secretCodec.encode(JSON.stringify(input.credential)), new Date().toISOString(), input.service, input.connectionName, input.id, input.revision);
181
- return row !== undefined;
182
- }
183
- async delete(service, connectionName) {
184
- this.database
185
- .prepare("delete from connections where service = ? and connection_name = ?")
186
- .run(service, connectionName);
187
- }
188
- async list() {
189
- const rows = this.database
190
- .prepare("select id, revision, service, connection_name, value from connections order by service, connection_name")
191
- .all();
192
- return await Promise.all(rows.map(async (row) => ({
193
- id: readString(row, "id"),
194
- revision: readString(row, "revision"),
195
- service: readString(row, "service"),
196
- connectionName: readString(row, "connection_name"),
197
- credential: parseJson(await this.secretCodec.decode(readString(row, "value"))),
198
- })));
199
- }
200
- }
201
183
  export class SqliteOAuthClientConfigStore {
202
184
  database;
203
185
  secretCodec;
@@ -259,6 +241,8 @@ export class SqliteOAuthStateStore {
259
241
  }
260
242
  export class SqliteRuntimeTokenStore {
261
243
  database;
244
+ findByHashStatement;
245
+ markUsedStatement;
262
246
  constructor(database) {
263
247
  this.database = database;
264
248
  }
@@ -268,9 +252,9 @@ export class SqliteRuntimeTokenStore {
268
252
  insert into runtime_tokens (
269
253
  ${runtimeTokenColumns}
270
254
  )
271
- values (?, ?, ?, ?, ?, ?, ?, ?, ?)
255
+ values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
272
256
  `)
273
- .run(record.id, record.name, record.tokenHash, JSON.stringify(record.allowedActions), JSON.stringify(record.blockedActions), JSON.stringify(record.allowedProxies), JSON.stringify(record.allowedConnections ?? []), record.createdAt, record.lastUsedAt ?? null);
257
+ .run(record.id, record.name, record.tokenHash, JSON.stringify(record.allowedActions), JSON.stringify(record.blockedActions), JSON.stringify(record.allowedProxies), JSON.stringify(record.allowedConnections ?? []), JSON.stringify(record.allowedTriggers ?? []), record.createdAt, record.lastUsedAt ?? null);
274
258
  }
275
259
  async list() {
276
260
  return this.database
@@ -283,24 +267,24 @@ export class SqliteRuntimeTokenStore {
283
267
  .map(readRuntimeTokenRow);
284
268
  }
285
269
  async findByHash(tokenHash) {
286
- const row = this.database
287
- .prepare(`
288
- select ${runtimeTokenColumns}
289
- from runtime_tokens
290
- where token_hash = ?
291
- `)
292
- .get(tokenHash);
270
+ // Custom migration sources may omit this table until the store is actually used.
271
+ this.findByHashStatement ??= this.database.prepare(`
272
+ select ${runtimeTokenColumns}
273
+ from runtime_tokens
274
+ where token_hash = ?
275
+ `);
276
+ const row = this.findByHashStatement.get(tokenHash);
293
277
  return row ? readRuntimeTokenRow(row) : undefined;
294
278
  }
295
279
  async updatePolicy(id, policy) {
296
280
  const row = this.database
297
281
  .prepare(`
298
282
  update runtime_tokens
299
- set allowed_actions = ?, blocked_actions = ?, allowed_proxies = ?, allowed_connections = ?
283
+ set allowed_actions = ?, blocked_actions = ?, allowed_proxies = ?, allowed_connections = ?, allowed_triggers = ?
300
284
  where id = ?
301
285
  returning ${runtimeTokenColumns}
302
286
  `)
303
- .get(JSON.stringify(policy.allowedActions), JSON.stringify(policy.blockedActions), JSON.stringify(policy.allowedProxies), JSON.stringify(policy.allowedConnections ?? []), id);
287
+ .get(JSON.stringify(policy.allowedActions), JSON.stringify(policy.blockedActions), JSON.stringify(policy.allowedProxies), JSON.stringify(policy.allowedConnections ?? []), JSON.stringify(policy.allowedTriggers ?? []), id);
304
288
  return row ? readRuntimeTokenRow(row) : undefined;
305
289
  }
306
290
  async revoke(id) {
@@ -308,7 +292,8 @@ export class SqliteRuntimeTokenStore {
308
292
  return result.changes > 0;
309
293
  }
310
294
  async markUsed(id, usedAt) {
311
- this.database.prepare("update runtime_tokens set last_used_at = ? where id = ?").run(usedAt, id);
295
+ this.markUsedStatement ??= this.database.prepare("update runtime_tokens set last_used_at = ? where id = ?");
296
+ this.markUsedStatement.run(usedAt, id);
312
297
  }
313
298
  }
314
299
  export class SqliteRuntimePolicyStore {
@@ -0,0 +1,16 @@
1
+ import type { TriggerSubscription, TriggerStore } from "../../triggers/store.ts";
2
+ import type { ISecretCodec } from "../secrets/secret-codec-core.ts";
3
+ import type { RequestTransaction } from "./connection-request-store.ts";
4
+ export declare class SqlTriggerStore implements TriggerStore {
5
+ private readonly transaction;
6
+ private readonly codec;
7
+ constructor(transaction: RequestTransaction, codec: ISecretCodec);
8
+ private read;
9
+ list(): Promise<TriggerSubscription[]>;
10
+ listFlowTriggersForMaintenance(now: number, limit: number): Promise<TriggerSubscription[]>;
11
+ getFlowTrigger(id: string): Promise<TriggerSubscription | null>;
12
+ insertFlowTrigger(record: TriggerSubscription): Promise<TriggerSubscription>;
13
+ claimFlowTrigger(id: string, owner: string, now: number, until: number): Promise<boolean>;
14
+ saveFlowTrigger(record: TriggerSubscription, owner: string, now: number): Promise<boolean>;
15
+ releaseFlowTrigger(id: string, owner: string): Promise<void>;
16
+ }
@@ -0,0 +1,96 @@
1
+ import { HttpRequestError } from "../api/http-utils.js";
2
+ export class SqlTriggerStore {
3
+ transaction;
4
+ codec;
5
+ constructor(transaction, codec) {
6
+ this.transaction = transaction;
7
+ this.codec = codec;
8
+ }
9
+ async read(row) {
10
+ return JSON.parse(await this.codec.decode(row.value));
11
+ }
12
+ async list() {
13
+ const [rows] = await this.transaction([{ sql: "select value from trigger_subscriptions order by id", values: [] }]);
14
+ return Promise.all(rows.map((row) => this.read(row)));
15
+ }
16
+ async listFlowTriggersForMaintenance(now, limit) {
17
+ const [rows] = await this.transaction([
18
+ {
19
+ sql: `select value from trigger_subscriptions where mode <> 'resource-set'
20
+ and status in ('active', 'deleting') and maintenance_at <= ? and (lease_until is null or lease_until <= ?)
21
+ order by maintenance_at, id limit ?`,
22
+ values: [now, now, limit],
23
+ },
24
+ ]);
25
+ return Promise.all(rows.map((row) => this.read(row)));
26
+ }
27
+ async getFlowTrigger(id) {
28
+ const [[row]] = await this.transaction([
29
+ { sql: "select value from trigger_subscriptions where id = ?", values: [id] },
30
+ ]);
31
+ return row ? this.read(row) : null;
32
+ }
33
+ async insertFlowTrigger(record) {
34
+ const value = await this.codec.encode(JSON.stringify(record));
35
+ const [, , [row]] = await this.transaction([
36
+ {
37
+ sql: "update connections set revision = revision where id = ? and revision = ? and source = 'local' returning id",
38
+ values: [record.connectionId, record.connectionRevision],
39
+ },
40
+ { sql: "update runtime_tokens set name = name where id = ? returning id", values: [record.tokenId] },
41
+ {
42
+ sql: `insert into trigger_subscriptions (id, mode, token_id, connection_id, trigger_id, status, reconcile_at, value)
43
+ select ?, ?, ?, ?, ?, ?, ?, ? where exists (select 1 from connections where id = ? and revision = ? and source = 'local')
44
+ and (? = 'resource-set' or exists (select 1 from runtime_tokens where id = ?))
45
+ on conflict (id) do nothing returning value`,
46
+ values: [
47
+ record.id,
48
+ record.mode,
49
+ record.tokenId,
50
+ record.connectionId,
51
+ record.triggerId,
52
+ record.status,
53
+ record.reconcileAt,
54
+ value,
55
+ record.connectionId,
56
+ record.connectionRevision,
57
+ record.mode,
58
+ record.tokenId,
59
+ ],
60
+ },
61
+ ]);
62
+ const existing = row ? await this.read(row) : await this.getFlowTrigger(record.id);
63
+ if (!existing)
64
+ throw new HttpRequestError("trigger_connection_error", "The connection or runtime token changed while creating the subscription.", 409);
65
+ return existing;
66
+ }
67
+ async claimFlowTrigger(id, owner, now, until) {
68
+ const [[row]] = await this.transaction([
69
+ {
70
+ sql: `update trigger_subscriptions set lease_owner = ?, lease_until = ?
71
+ where id = ? and (lease_until is null or lease_until <= ?) returning id`,
72
+ values: [owner, until, id, now],
73
+ },
74
+ ]);
75
+ return !!row;
76
+ }
77
+ async saveFlowTrigger(record, owner, now) {
78
+ const value = await this.codec.encode(JSON.stringify(record));
79
+ const [[row]] = await this.transaction([
80
+ {
81
+ sql: `update trigger_subscriptions set status = ?, reconcile_at = ?, maintenance_at = ?, value = ?
82
+ where id = ? and lease_owner = ? and lease_until > ? returning id`,
83
+ values: [record.status, record.reconcileAt, now + 60_000, value, record.id, owner, now],
84
+ },
85
+ ]);
86
+ return !!row;
87
+ }
88
+ async releaseFlowTrigger(id, owner) {
89
+ await this.transaction([
90
+ {
91
+ sql: "update trigger_subscriptions set lease_owner = null, lease_until = null where id = ? and lease_owner = ?",
92
+ values: [id, owner],
93
+ },
94
+ ]);
95
+ }
96
+ }
@@ -0,0 +1,2 @@
1
+ import type { Group, InputPort, JsonValue } from "./types.ts";
2
+ export declare function resolveTriggerConfig(inputs: readonly (InputPort | Group)[], config: Readonly<Record<string, JsonValue>>, partial?: boolean): Readonly<Record<string, JsonValue>>;
@@ -0,0 +1,17 @@
1
+ import { Validator } from "@cfworker/json-schema";
2
+ import { HttpRequestError } from "../../server/api/http-utils.js";
3
+ export function resolveTriggerConfig(inputs, config, partial = false) {
4
+ const fields = inputs.filter((input) => "handle" in input);
5
+ const known = new Set(fields.map((field) => field.handle));
6
+ if (Object.keys(config).some((key) => !known.has(key)))
7
+ throw new HttpRequestError("invalid_input", "Unknown Trigger configuration field.", 400);
8
+ return Object.fromEntries(fields
9
+ .filter((field) => !partial || config[field.handle] !== undefined || field.value !== undefined)
10
+ .map((field) => {
11
+ const value = config[field.handle] !== undefined ? config[field.handle] : (field.value ?? null);
12
+ if (!(value === null && field.nullable) &&
13
+ !new Validator(field.jsonSchema, "2020-12").validate(value).valid)
14
+ throw new HttpRequestError("invalid_input", `Invalid Trigger configuration: ${field.handle}`, 400);
15
+ return [field.handle, value];
16
+ }));
17
+ }
@@ -0,0 +1,13 @@
1
+ import type { ConnectorProxy } from "./proxy.ts";
2
+ import type { JsonValue } from "./types.ts";
3
+ export interface TriggerConfigOption {
4
+ readonly value: string;
5
+ readonly label: string;
6
+ readonly color?: string;
7
+ }
8
+ export interface TriggerConfigOptionsContext {
9
+ readonly field: string;
10
+ readonly config: Readonly<Record<string, JsonValue>>;
11
+ readonly connector: ConnectorProxy;
12
+ readonly signal?: AbortSignal;
13
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { JsonValue } from "./types.ts";
2
+ export declare function canonicalJsonBytes(value: JsonValue): Uint8Array;
3
+ export declare function digestBytes(bytes: Uint8Array): Promise<string>;
@@ -0,0 +1,19 @@
1
+ import { sha256Hex } from "../../core/aws-sigv4.js";
2
+ const encoder = new TextEncoder();
3
+ function canonicalText(value) {
4
+ if (value == null || typeof value == "boolean" || typeof value == "string" || typeof value == "number")
5
+ return JSON.stringify(value);
6
+ if (Array.isArray(value))
7
+ return `[${value.map(canonicalText).join(",")}]`;
8
+ const object = value;
9
+ return `{${Object.keys(object)
10
+ .toSorted()
11
+ .map((key) => `${JSON.stringify(key)}:${canonicalText(object[key])}`)
12
+ .join(",")}}`;
13
+ }
14
+ export function canonicalJsonBytes(value) {
15
+ return encoder.encode(canonicalText(value));
16
+ }
17
+ export async function digestBytes(bytes) {
18
+ return `sha256:${sha256Hex(bytes)}`;
19
+ }