dotdo 0.0.1 → 0.1.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 (667) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +446 -315
  3. package/cli/README.md +238 -0
  4. package/cli/agent.ts +72 -0
  5. package/cli/bin.js +44 -0
  6. package/cli/bin.ts +38 -0
  7. package/cli/build.ts +157 -0
  8. package/cli/commands/auth/login.ts +14 -0
  9. package/cli/commands/auth/logout.ts +6 -0
  10. package/cli/commands/auth/whoami.ts +16 -0
  11. package/cli/commands/deploy-multi.ts +245 -0
  12. package/cli/commands/dev/deploy.ts +100 -0
  13. package/cli/commands/dev/dev.ts +95 -0
  14. package/cli/commands/dev/logs.ts +91 -0
  15. package/cli/commands/dev-local.ts +88 -0
  16. package/cli/commands/do-ops.ts +314 -0
  17. package/cli/commands/index.ts +100 -0
  18. package/cli/commands/init.ts +247 -0
  19. package/cli/commands/introspect/emitter.ts +315 -0
  20. package/cli/commands/introspect/index.ts +193 -0
  21. package/cli/commands/link.ts +598 -0
  22. package/cli/commands/snippets.ts +415 -0
  23. package/cli/commands/tunnel.ts +239 -0
  24. package/cli/device-auth.ts +289 -0
  25. package/cli/fallback.ts +12 -0
  26. package/cli/index.ts +121 -0
  27. package/cli/main.ts +246 -0
  28. package/cli/mcp-stdio.ts +790 -0
  29. package/cli/package.json +62 -0
  30. package/cli/runtime/do-registry.ts +193 -0
  31. package/cli/runtime/embedded-db.ts +344 -0
  32. package/cli/runtime/index.ts +9 -0
  33. package/cli/runtime/miniflare-adapter.ts +162 -0
  34. package/cli/sandbox.ts +82 -0
  35. package/cli/src/args.ts +174 -0
  36. package/cli/src/auth.ts +55 -0
  37. package/cli/src/commands/call.ts +84 -0
  38. package/cli/src/commands/charge.ts +96 -0
  39. package/cli/src/commands/config.ts +115 -0
  40. package/cli/src/commands/email.ts +112 -0
  41. package/cli/src/commands/llm.ts +115 -0
  42. package/cli/src/commands/queue.ts +134 -0
  43. package/cli/src/commands/text.ts +86 -0
  44. package/cli/src/config.ts +185 -0
  45. package/cli/src/output.ts +246 -0
  46. package/cli/src/rpc.ts +192 -0
  47. package/cli/utils/config.ts +282 -0
  48. package/cli/utils/detect.ts +73 -0
  49. package/cli/utils/index.ts +15 -0
  50. package/cli/utils/logger.ts +232 -0
  51. package/dist/ai/index.js +19 -0
  52. package/dist/ai/index.js.map +1 -0
  53. package/dist/ai/template-literals.js +852 -0
  54. package/dist/ai/template-literals.js.map +1 -0
  55. package/dist/api/middleware/auth-federation.js +573 -0
  56. package/dist/api/middleware/auth-federation.js.map +1 -0
  57. package/dist/api/middleware/auth.js +545 -0
  58. package/dist/api/middleware/auth.js.map +1 -0
  59. package/dist/db/actions.js +212 -0
  60. package/dist/db/actions.js.map +1 -0
  61. package/dist/db/auth.js +506 -0
  62. package/dist/db/auth.js.map +1 -0
  63. package/dist/db/branches.js +65 -0
  64. package/dist/db/branches.js.map +1 -0
  65. package/dist/db/clickhouse.js +1074 -0
  66. package/dist/db/clickhouse.js.map +1 -0
  67. package/dist/db/dlq.js +39 -0
  68. package/dist/db/dlq.js.map +1 -0
  69. package/dist/db/events.js +28 -0
  70. package/dist/db/events.js.map +1 -0
  71. package/dist/db/exec.js +64 -0
  72. package/dist/db/exec.js.map +1 -0
  73. package/dist/db/files.js +85 -0
  74. package/dist/db/files.js.map +1 -0
  75. package/dist/db/flags.js +24 -0
  76. package/dist/db/flags.js.map +1 -0
  77. package/dist/db/git.js +116 -0
  78. package/dist/db/git.js.map +1 -0
  79. package/dist/db/iceberg/inverted-index.js +862 -0
  80. package/dist/db/iceberg/inverted-index.js.map +1 -0
  81. package/dist/db/iceberg/puffin.js +878 -0
  82. package/dist/db/iceberg/puffin.js.map +1 -0
  83. package/dist/db/iceberg/search-manifest.js +422 -0
  84. package/dist/db/iceberg/search-manifest.js.map +1 -0
  85. package/dist/db/iceberg/types.js +8 -0
  86. package/dist/db/iceberg/types.js.map +1 -0
  87. package/dist/db/index.js +121 -0
  88. package/dist/db/index.js.map +1 -0
  89. package/dist/db/integrations.js +368 -0
  90. package/dist/db/integrations.js.map +1 -0
  91. package/dist/db/json-indexes.js +332 -0
  92. package/dist/db/json-indexes.js.map +1 -0
  93. package/dist/db/linked-accounts.js +287 -0
  94. package/dist/db/linked-accounts.js.map +1 -0
  95. package/dist/db/nouns.js +183 -0
  96. package/dist/db/nouns.js.map +1 -0
  97. package/dist/db/objects.js +170 -0
  98. package/dist/db/objects.js.map +1 -0
  99. package/dist/db/primitives/dag-scheduler/index.js +869 -0
  100. package/dist/db/primitives/dag-scheduler/index.js.map +1 -0
  101. package/dist/db/primitives/exactly-once-context.js +237 -0
  102. package/dist/db/primitives/exactly-once-context.js.map +1 -0
  103. package/dist/db/primitives/index.js +62 -0
  104. package/dist/db/primitives/index.js.map +1 -0
  105. package/dist/db/primitives/keyed-router.js +145 -0
  106. package/dist/db/primitives/keyed-router.js.map +1 -0
  107. package/dist/db/primitives/observability.js +162 -0
  108. package/dist/db/primitives/observability.js.map +1 -0
  109. package/dist/db/primitives/schema-evolution.js +643 -0
  110. package/dist/db/primitives/schema-evolution.js.map +1 -0
  111. package/dist/db/primitives/stateful-operator/index.js +770 -0
  112. package/dist/db/primitives/stateful-operator/index.js.map +1 -0
  113. package/dist/db/primitives/temporal-store.js +306 -0
  114. package/dist/db/primitives/temporal-store.js.map +1 -0
  115. package/dist/db/primitives/typed-column-store.js +1229 -0
  116. package/dist/db/primitives/typed-column-store.js.map +1 -0
  117. package/dist/db/primitives/utils/duration.js +162 -0
  118. package/dist/db/primitives/utils/duration.js.map +1 -0
  119. package/dist/db/primitives/utils/murmur3.js +116 -0
  120. package/dist/db/primitives/utils/murmur3.js.map +1 -0
  121. package/dist/db/primitives/watermark-service.js +136 -0
  122. package/dist/db/primitives/watermark-service.js.map +1 -0
  123. package/dist/db/primitives/window-manager.js +764 -0
  124. package/dist/db/primitives/window-manager.js.map +1 -0
  125. package/dist/db/relationships.js +66 -0
  126. package/dist/db/relationships.js.map +1 -0
  127. package/dist/db/schema-minimal.js +61 -0
  128. package/dist/db/schema-minimal.js.map +1 -0
  129. package/dist/db/search.js +28 -0
  130. package/dist/db/search.js.map +1 -0
  131. package/dist/db/stores.js +1665 -0
  132. package/dist/db/stores.js.map +1 -0
  133. package/dist/db/things.js +297 -0
  134. package/dist/db/things.js.map +1 -0
  135. package/dist/db/vault.js +171 -0
  136. package/dist/db/vault.js.map +1 -0
  137. package/dist/db/verbs.js +102 -0
  138. package/dist/db/verbs.js.map +1 -0
  139. package/dist/do/base.js +48 -0
  140. package/dist/do/base.js.map +1 -0
  141. package/dist/do/tiny.js +31 -0
  142. package/dist/do/tiny.js.map +1 -0
  143. package/dist/lib/DOAuth.js +261 -0
  144. package/dist/lib/DOAuth.js.map +1 -0
  145. package/dist/lib/DODispatcher.js +72 -0
  146. package/dist/lib/DODispatcher.js.map +1 -0
  147. package/dist/lib/Modifier.js +189 -0
  148. package/dist/lib/Modifier.js.map +1 -0
  149. package/dist/lib/StateStorage.js +403 -0
  150. package/dist/lib/StateStorage.js.map +1 -0
  151. package/dist/lib/TypeRegistry.js +122 -0
  152. package/dist/lib/TypeRegistry.js.map +1 -0
  153. package/dist/lib/ai/gateway.js +247 -0
  154. package/dist/lib/ai/gateway.js.map +1 -0
  155. package/dist/lib/ai/tool-loop-agent.js +591 -0
  156. package/dist/lib/ai/tool-loop-agent.js.map +1 -0
  157. package/dist/lib/auto-wiring.js +439 -0
  158. package/dist/lib/auto-wiring.js.map +1 -0
  159. package/dist/lib/browse/browserbase.js +163 -0
  160. package/dist/lib/browse/browserbase.js.map +1 -0
  161. package/dist/lib/browse/cloudflare.js +144 -0
  162. package/dist/lib/browse/cloudflare.js.map +1 -0
  163. package/dist/lib/browse/index.js +62 -0
  164. package/dist/lib/browse/index.js.map +1 -0
  165. package/dist/lib/browse/types.js +13 -0
  166. package/dist/lib/browse/types.js.map +1 -0
  167. package/dist/lib/cache/index.js +37 -0
  168. package/dist/lib/cache/index.js.map +1 -0
  169. package/dist/lib/cache/visibility.js +638 -0
  170. package/dist/lib/cache/visibility.js.map +1 -0
  171. package/dist/lib/capabilities.js +268 -0
  172. package/dist/lib/capabilities.js.map +1 -0
  173. package/dist/lib/channels/base.js +106 -0
  174. package/dist/lib/channels/base.js.map +1 -0
  175. package/dist/lib/channels/discord.js +94 -0
  176. package/dist/lib/channels/discord.js.map +1 -0
  177. package/dist/lib/channels/email.js +204 -0
  178. package/dist/lib/channels/email.js.map +1 -0
  179. package/dist/lib/channels/index.js +90 -0
  180. package/dist/lib/channels/index.js.map +1 -0
  181. package/dist/lib/channels/mdxui-chat.js +95 -0
  182. package/dist/lib/channels/mdxui-chat.js.map +1 -0
  183. package/dist/lib/channels/slack-blockkit.js +121 -0
  184. package/dist/lib/channels/slack-blockkit.js.map +1 -0
  185. package/dist/lib/channels/types.js +7 -0
  186. package/dist/lib/channels/types.js.map +1 -0
  187. package/dist/lib/cloudflare/ai.js +654 -0
  188. package/dist/lib/cloudflare/ai.js.map +1 -0
  189. package/dist/lib/cloudflare/index.js +88 -0
  190. package/dist/lib/cloudflare/index.js.map +1 -0
  191. package/dist/lib/cloudflare/kv.js +342 -0
  192. package/dist/lib/cloudflare/kv.js.map +1 -0
  193. package/dist/lib/cloudflare/queues.js +434 -0
  194. package/dist/lib/cloudflare/queues.js.map +1 -0
  195. package/dist/lib/cloudflare/r2.js +604 -0
  196. package/dist/lib/cloudflare/r2.js.map +1 -0
  197. package/dist/lib/cloudflare/vectorize.js +494 -0
  198. package/dist/lib/cloudflare/vectorize.js.map +1 -0
  199. package/dist/lib/cloudflare/workflows.js +569 -0
  200. package/dist/lib/cloudflare/workflows.js.map +1 -0
  201. package/dist/lib/colo/caching.js +196 -0
  202. package/dist/lib/colo/caching.js.map +1 -0
  203. package/dist/lib/colo/detection.js +194 -0
  204. package/dist/lib/colo/detection.js.map +1 -0
  205. package/dist/lib/colo/external-data.js +219 -0
  206. package/dist/lib/colo/external-data.js.map +1 -0
  207. package/dist/lib/colo/globe-data.js +179 -0
  208. package/dist/lib/colo/globe-data.js.map +1 -0
  209. package/dist/lib/colo/index.js +16 -0
  210. package/dist/lib/colo/index.js.map +1 -0
  211. package/dist/lib/decorators.js +37 -0
  212. package/dist/lib/decorators.js.map +1 -0
  213. package/dist/lib/discovery.js +81 -0
  214. package/dist/lib/discovery.js.map +1 -0
  215. package/dist/lib/executors/AgenticFunctionExecutor.js +619 -0
  216. package/dist/lib/executors/AgenticFunctionExecutor.js.map +1 -0
  217. package/dist/lib/executors/BaseFunctionExecutor.js +328 -0
  218. package/dist/lib/executors/BaseFunctionExecutor.js.map +1 -0
  219. package/dist/lib/executors/CascadeExecutor.js +418 -0
  220. package/dist/lib/executors/CascadeExecutor.js.map +1 -0
  221. package/dist/lib/executors/CodeFunctionExecutor.js +904 -0
  222. package/dist/lib/executors/CodeFunctionExecutor.js.map +1 -0
  223. package/dist/lib/executors/GenerativeFunctionExecutor.js +904 -0
  224. package/dist/lib/executors/GenerativeFunctionExecutor.js.map +1 -0
  225. package/dist/lib/executors/HumanFunctionExecutor.js +884 -0
  226. package/dist/lib/executors/HumanFunctionExecutor.js.map +1 -0
  227. package/dist/lib/executors/ParallelStepExecutor.js +308 -0
  228. package/dist/lib/executors/ParallelStepExecutor.js.map +1 -0
  229. package/dist/lib/executors/types.js +12 -0
  230. package/dist/lib/executors/types.js.map +1 -0
  231. package/dist/lib/experiments.js +89 -0
  232. package/dist/lib/experiments.js.map +1 -0
  233. package/dist/lib/flags/store.js +262 -0
  234. package/dist/lib/flags/store.js.map +1 -0
  235. package/dist/lib/functions/FunctionComposition.js +467 -0
  236. package/dist/lib/functions/FunctionComposition.js.map +1 -0
  237. package/dist/lib/functions/FunctionMiddleware.js +457 -0
  238. package/dist/lib/functions/FunctionMiddleware.js.map +1 -0
  239. package/dist/lib/functions/FunctionRegistry.js +426 -0
  240. package/dist/lib/functions/FunctionRegistry.js.map +1 -0
  241. package/dist/lib/functions/createFunction.js +1048 -0
  242. package/dist/lib/functions/createFunction.js.map +1 -0
  243. package/dist/lib/humans/index.js +68 -0
  244. package/dist/lib/humans/index.js.map +1 -0
  245. package/dist/lib/humans/templates.js +117 -0
  246. package/dist/lib/humans/templates.js.map +1 -0
  247. package/dist/lib/identity.js +98 -0
  248. package/dist/lib/identity.js.map +1 -0
  249. package/dist/lib/index.js +9 -0
  250. package/dist/lib/index.js.map +1 -0
  251. package/dist/lib/logging/error-logger.js +163 -0
  252. package/dist/lib/logging/error-logger.js.map +1 -0
  253. package/dist/lib/logging/index.js +160 -0
  254. package/dist/lib/logging/index.js.map +1 -0
  255. package/dist/lib/mixins/bash.js +753 -0
  256. package/dist/lib/mixins/bash.js.map +1 -0
  257. package/dist/lib/mixins/fs.js +648 -0
  258. package/dist/lib/mixins/fs.js.map +1 -0
  259. package/dist/lib/mixins/git.js +1006 -0
  260. package/dist/lib/mixins/git.js.map +1 -0
  261. package/dist/lib/mixins/npm.js +662 -0
  262. package/dist/lib/mixins/npm.js.map +1 -0
  263. package/dist/lib/noun-id.js +278 -0
  264. package/dist/lib/noun-id.js.map +1 -0
  265. package/dist/lib/rate-limit/sliding-window.js +148 -0
  266. package/dist/lib/rate-limit/sliding-window.js.map +1 -0
  267. package/dist/lib/rate-limit.js +110 -0
  268. package/dist/lib/rate-limit.js.map +1 -0
  269. package/dist/lib/rpc/bindings.js +548 -0
  270. package/dist/lib/rpc/bindings.js.map +1 -0
  271. package/dist/lib/rpc/index.js +64 -0
  272. package/dist/lib/rpc/index.js.map +1 -0
  273. package/dist/lib/safe-stringify.js +223 -0
  274. package/dist/lib/safe-stringify.js.map +1 -0
  275. package/dist/lib/sandbox/miniflare-sandbox.js +1007 -0
  276. package/dist/lib/sandbox/miniflare-sandbox.js.map +1 -0
  277. package/dist/lib/sqids.js +110 -0
  278. package/dist/lib/sqids.js.map +1 -0
  279. package/dist/lib/sql/adapters/index.js +10 -0
  280. package/dist/lib/sql/adapters/index.js.map +1 -0
  281. package/dist/lib/sql/adapters/node-sql-parser.js +552 -0
  282. package/dist/lib/sql/adapters/node-sql-parser.js.map +1 -0
  283. package/dist/lib/sql/adapters/pgsql-parser.js +1190 -0
  284. package/dist/lib/sql/adapters/pgsql-parser.js.map +1 -0
  285. package/dist/lib/sql/index.js +277 -0
  286. package/dist/lib/sql/index.js.map +1 -0
  287. package/dist/lib/sql/types.js +56 -0
  288. package/dist/lib/sql/types.js.map +1 -0
  289. package/dist/lib/type-classifier.js +126 -0
  290. package/dist/lib/type-classifier.js.map +1 -0
  291. package/dist/lib/utils/html.js +47 -0
  292. package/dist/lib/utils/html.js.map +1 -0
  293. package/dist/lib/validation.js +48 -0
  294. package/dist/lib/validation.js.map +1 -0
  295. package/dist/lib/vault/store.js +411 -0
  296. package/dist/lib/vault/store.js.map +1 -0
  297. package/dist/metrics/hunch.js +739 -0
  298. package/dist/metrics/hunch.js.map +1 -0
  299. package/dist/objects/API.js +302 -0
  300. package/dist/objects/API.js.map +1 -0
  301. package/dist/objects/Agent.js +179 -0
  302. package/dist/objects/Agent.js.map +1 -0
  303. package/dist/objects/AgenticFunctionExecutor.js +8 -0
  304. package/dist/objects/AgenticFunctionExecutor.js.map +1 -0
  305. package/dist/objects/App.js +83 -0
  306. package/dist/objects/App.js.map +1 -0
  307. package/dist/objects/Browser.js +884 -0
  308. package/dist/objects/Browser.js.map +1 -0
  309. package/dist/objects/Business.js +107 -0
  310. package/dist/objects/Business.js.map +1 -0
  311. package/dist/objects/CLI.js +221 -0
  312. package/dist/objects/CLI.js.map +1 -0
  313. package/dist/objects/CodeFunctionExecutor.js +8 -0
  314. package/dist/objects/CodeFunctionExecutor.js.map +1 -0
  315. package/dist/objects/Collection.js +161 -0
  316. package/dist/objects/Collection.js.map +1 -0
  317. package/dist/objects/DO.js +41 -0
  318. package/dist/objects/DO.js.map +1 -0
  319. package/dist/objects/DOBase.js +2309 -0
  320. package/dist/objects/DOBase.js.map +1 -0
  321. package/dist/objects/DOCache.js +153 -0
  322. package/dist/objects/DOCache.js.map +1 -0
  323. package/dist/objects/DOFull.js +1676 -0
  324. package/dist/objects/DOFull.js.map +1 -0
  325. package/dist/objects/DOTiny.js +207 -0
  326. package/dist/objects/DOTiny.js.map +1 -0
  327. package/dist/objects/Directory.js +199 -0
  328. package/dist/objects/Directory.js.map +1 -0
  329. package/dist/objects/Entity.js +413 -0
  330. package/dist/objects/Entity.js.map +1 -0
  331. package/dist/objects/Function.js +116 -0
  332. package/dist/objects/Function.js.map +1 -0
  333. package/dist/objects/Human.js +231 -0
  334. package/dist/objects/Human.js.map +1 -0
  335. package/dist/objects/HumanFunctionExecutor.js +8 -0
  336. package/dist/objects/HumanFunctionExecutor.js.map +1 -0
  337. package/dist/objects/IcebergMetadataDO.js +938 -0
  338. package/dist/objects/IcebergMetadataDO.js.map +1 -0
  339. package/dist/objects/IntegrationsDO.js +1174 -0
  340. package/dist/objects/IntegrationsDO.js.map +1 -0
  341. package/dist/objects/ObservabilityBroadcaster.js +149 -0
  342. package/dist/objects/ObservabilityBroadcaster.js.map +1 -0
  343. package/dist/objects/Package.js +154 -0
  344. package/dist/objects/Package.js.map +1 -0
  345. package/dist/objects/Product.js +193 -0
  346. package/dist/objects/Product.js.map +1 -0
  347. package/dist/objects/SDK.js +152 -0
  348. package/dist/objects/SDK.js.map +1 -0
  349. package/dist/objects/SaaS.js +235 -0
  350. package/dist/objects/SaaS.js.map +1 -0
  351. package/dist/objects/SandboxDO.js +759 -0
  352. package/dist/objects/SandboxDO.js.map +1 -0
  353. package/dist/objects/Service.js +337 -0
  354. package/dist/objects/Service.js.map +1 -0
  355. package/dist/objects/Site.js +80 -0
  356. package/dist/objects/Site.js.map +1 -0
  357. package/dist/objects/Startup.js +479 -0
  358. package/dist/objects/Startup.js.map +1 -0
  359. package/dist/objects/ThingsDO.js +170 -0
  360. package/dist/objects/ThingsDO.js.map +1 -0
  361. package/dist/objects/VectorShardDO.js +650 -0
  362. package/dist/objects/VectorShardDO.js.map +1 -0
  363. package/dist/objects/Worker.js +144 -0
  364. package/dist/objects/Worker.js.map +1 -0
  365. package/dist/objects/Workflow.js +196 -0
  366. package/dist/objects/Workflow.js.map +1 -0
  367. package/dist/objects/WorkflowFactory.js +313 -0
  368. package/dist/objects/WorkflowFactory.js.map +1 -0
  369. package/dist/objects/WorkflowRuntime.js +863 -0
  370. package/dist/objects/WorkflowRuntime.js.map +1 -0
  371. package/dist/objects/circuit-breaker-bulkhead.js +178 -0
  372. package/dist/objects/circuit-breaker-bulkhead.js.map +1 -0
  373. package/dist/objects/createFunction.js +934 -0
  374. package/dist/objects/createFunction.js.map +1 -0
  375. package/dist/objects/index.js +80 -0
  376. package/dist/objects/index.js.map +1 -0
  377. package/dist/objects/lifecycle/Branch.js +275 -0
  378. package/dist/objects/lifecycle/Branch.js.map +1 -0
  379. package/dist/objects/lifecycle/Clone.js +1499 -0
  380. package/dist/objects/lifecycle/Clone.js.map +1 -0
  381. package/dist/objects/lifecycle/Compact.js +237 -0
  382. package/dist/objects/lifecycle/Compact.js.map +1 -0
  383. package/dist/objects/lifecycle/Promote.js +476 -0
  384. package/dist/objects/lifecycle/Promote.js.map +1 -0
  385. package/dist/objects/lifecycle/Shard.js +560 -0
  386. package/dist/objects/lifecycle/Shard.js.map +1 -0
  387. package/dist/objects/lifecycle/index.js +15 -0
  388. package/dist/objects/lifecycle/index.js.map +1 -0
  389. package/dist/objects/lifecycle/types.js +33 -0
  390. package/dist/objects/lifecycle/types.js.map +1 -0
  391. package/dist/objects/mixins/infrastructure.js +171 -0
  392. package/dist/objects/mixins/infrastructure.js.map +1 -0
  393. package/dist/objects/modules/StoresModule.js +153 -0
  394. package/dist/objects/modules/StoresModule.js.map +1 -0
  395. package/dist/objects/persistence/checkpoint-manager.js +606 -0
  396. package/dist/objects/persistence/checkpoint-manager.js.map +1 -0
  397. package/dist/objects/persistence/index.js +72 -0
  398. package/dist/objects/persistence/index.js.map +1 -0
  399. package/dist/objects/persistence/migration-runner.js +562 -0
  400. package/dist/objects/persistence/migration-runner.js.map +1 -0
  401. package/dist/objects/persistence/replication-manager.js +501 -0
  402. package/dist/objects/persistence/replication-manager.js.map +1 -0
  403. package/dist/objects/persistence/tiered-storage-manager.js +595 -0
  404. package/dist/objects/persistence/tiered-storage-manager.js.map +1 -0
  405. package/dist/objects/persistence/types.js +14 -0
  406. package/dist/objects/persistence/types.js.map +1 -0
  407. package/dist/objects/persistence/wal-manager.js +653 -0
  408. package/dist/objects/persistence/wal-manager.js.map +1 -0
  409. package/dist/objects/presets/index.js +20 -0
  410. package/dist/objects/presets/index.js.map +1 -0
  411. package/dist/objects/presets/primitives.js +188 -0
  412. package/dist/objects/presets/primitives.js.map +1 -0
  413. package/dist/objects/primitives/alarm-adapter.js +141 -0
  414. package/dist/objects/primitives/alarm-adapter.js.map +1 -0
  415. package/dist/objects/primitives/index.js +337 -0
  416. package/dist/objects/primitives/index.js.map +1 -0
  417. package/dist/objects/primitives/storage-adapter.js +182 -0
  418. package/dist/objects/primitives/storage-adapter.js.map +1 -0
  419. package/dist/objects/primitives/with-primitives.js +102 -0
  420. package/dist/objects/primitives/with-primitives.js.map +1 -0
  421. package/dist/objects/services/StoreManager.js +227 -0
  422. package/dist/objects/services/StoreManager.js.map +1 -0
  423. package/dist/objects/services/index.js +13 -0
  424. package/dist/objects/services/index.js.map +1 -0
  425. package/dist/objects/transport/auth-layer.js +1451 -0
  426. package/dist/objects/transport/auth-layer.js.map +1 -0
  427. package/dist/objects/transport/capnweb-target.js +355 -0
  428. package/dist/objects/transport/capnweb-target.js.map +1 -0
  429. package/dist/objects/transport/chain.js +441 -0
  430. package/dist/objects/transport/chain.js.map +1 -0
  431. package/dist/objects/transport/handler.js +58 -0
  432. package/dist/objects/transport/handler.js.map +1 -0
  433. package/dist/objects/transport/index.js +53 -0
  434. package/dist/objects/transport/index.js.map +1 -0
  435. package/dist/objects/transport/mcp-server.js +691 -0
  436. package/dist/objects/transport/mcp-server.js.map +1 -0
  437. package/dist/objects/transport/rest-autowire.js +1508 -0
  438. package/dist/objects/transport/rest-autowire.js.map +1 -0
  439. package/dist/objects/transport/rest-router.js +440 -0
  440. package/dist/objects/transport/rest-router.js.map +1 -0
  441. package/dist/objects/transport/rpc-server.js +1539 -0
  442. package/dist/objects/transport/rpc-server.js.map +1 -0
  443. package/dist/objects/transport/shared.js +576 -0
  444. package/dist/objects/transport/shared.js.map +1 -0
  445. package/dist/objects/transport/sync-engine.js +291 -0
  446. package/dist/objects/transport/sync-engine.js.map +1 -0
  447. package/dist/objects/transport/types.js +8 -0
  448. package/dist/objects/transport/types.js.map +1 -0
  449. package/dist/sandbox/index.js +258 -0
  450. package/dist/sandbox/index.js.map +1 -0
  451. package/dist/snippets/artifacts-config.js +241 -0
  452. package/dist/snippets/artifacts-config.js.map +1 -0
  453. package/dist/snippets/artifacts-ingest.js +832 -0
  454. package/dist/snippets/artifacts-ingest.js.map +1 -0
  455. package/dist/snippets/artifacts-serve.js +1035 -0
  456. package/dist/snippets/artifacts-serve.js.map +1 -0
  457. package/dist/snippets/artifacts-types.js +161 -0
  458. package/dist/snippets/artifacts-types.js.map +1 -0
  459. package/dist/snippets/cache-probe.js +376 -0
  460. package/dist/snippets/cache-probe.js.map +1 -0
  461. package/dist/snippets/cache.js +10 -0
  462. package/dist/snippets/cache.js.map +1 -0
  463. package/dist/snippets/events.js +469 -0
  464. package/dist/snippets/events.js.map +1 -0
  465. package/dist/snippets/index.js +7 -0
  466. package/dist/snippets/index.js.map +1 -0
  467. package/dist/snippets/proxy.js +495 -0
  468. package/dist/snippets/proxy.js.map +1 -0
  469. package/dist/snippets/search.js +1759 -0
  470. package/dist/snippets/search.js.map +1 -0
  471. package/dist/streams/index.js +30 -0
  472. package/dist/streams/index.js.map +1 -0
  473. package/dist/streams/observability.js +68 -0
  474. package/dist/streams/observability.js.map +1 -0
  475. package/dist/types/AI.js +92 -0
  476. package/dist/types/AI.js.map +1 -0
  477. package/dist/types/AIFunction.js +171 -0
  478. package/dist/types/AIFunction.js.map +1 -0
  479. package/dist/types/BrowseVerb.js +89 -0
  480. package/dist/types/BrowseVerb.js.map +1 -0
  481. package/dist/types/Browser.js +31 -0
  482. package/dist/types/Browser.js.map +1 -0
  483. package/dist/types/Chaos.js +15 -0
  484. package/dist/types/Chaos.js.map +1 -0
  485. package/dist/types/CloudflareBindings.js +109 -0
  486. package/dist/types/CloudflareBindings.js.map +1 -0
  487. package/dist/types/Collection.js +50 -0
  488. package/dist/types/Collection.js.map +1 -0
  489. package/dist/types/DO.js +2 -0
  490. package/dist/types/DO.js.map +1 -0
  491. package/dist/types/DOLocation.js +63 -0
  492. package/dist/types/DOLocation.js.map +1 -0
  493. package/dist/types/EventHandler.js +57 -0
  494. package/dist/types/EventHandler.js.map +1 -0
  495. package/dist/types/Experiment.js +33 -0
  496. package/dist/types/Experiment.js.map +1 -0
  497. package/dist/types/Flag.js +57 -0
  498. package/dist/types/Flag.js.map +1 -0
  499. package/dist/types/Lifecycle.js +13 -0
  500. package/dist/types/Lifecycle.js.map +1 -0
  501. package/dist/types/Location.js +169 -0
  502. package/dist/types/Location.js.map +1 -0
  503. package/dist/types/Noun.js +66 -0
  504. package/dist/types/Noun.js.map +1 -0
  505. package/dist/types/SessionEvent.js +194 -0
  506. package/dist/types/SessionEvent.js.map +1 -0
  507. package/dist/types/Thing.js +55 -0
  508. package/dist/types/Thing.js.map +1 -0
  509. package/dist/types/ThingDO.js +153 -0
  510. package/dist/types/ThingDO.js.map +1 -0
  511. package/dist/types/Things.js +2 -0
  512. package/dist/types/Things.js.map +1 -0
  513. package/dist/types/Verb.js +119 -0
  514. package/dist/types/Verb.js.map +1 -0
  515. package/dist/types/WorkflowContext.js +70 -0
  516. package/dist/types/WorkflowContext.js.map +1 -0
  517. package/dist/types/analytics-api.js +13 -0
  518. package/dist/types/analytics-api.js.map +1 -0
  519. package/dist/types/capabilities.js +135 -0
  520. package/dist/types/capabilities.js.map +1 -0
  521. package/dist/types/drizzle.js +12 -0
  522. package/dist/types/drizzle.js.map +1 -0
  523. package/dist/types/event.js +201 -0
  524. package/dist/types/event.js.map +1 -0
  525. package/dist/types/fn.js +12 -0
  526. package/dist/types/fn.js.map +1 -0
  527. package/dist/types/iceberg.js +48 -0
  528. package/dist/types/iceberg.js.map +1 -0
  529. package/dist/types/ids.js +170 -0
  530. package/dist/types/ids.js.map +1 -0
  531. package/dist/types/index.js +41 -0
  532. package/dist/types/index.js.map +1 -0
  533. package/dist/types/introspect.js +54 -0
  534. package/dist/types/introspect.js.map +1 -0
  535. package/dist/types/observability.js +124 -0
  536. package/dist/types/observability.js.map +1 -0
  537. package/dist/types/sync-protocol.js +175 -0
  538. package/dist/types/sync-protocol.js.map +1 -0
  539. package/dist/types/vector.js +13 -0
  540. package/dist/types/vector.js.map +1 -0
  541. package/dist/workflows/ScheduleManager.js +473 -0
  542. package/dist/workflows/ScheduleManager.js.map +1 -0
  543. package/dist/workflows/StepDOBridge.js +149 -0
  544. package/dist/workflows/StepDOBridge.js.map +1 -0
  545. package/dist/workflows/StepResultStorage.js +232 -0
  546. package/dist/workflows/StepResultStorage.js.map +1 -0
  547. package/dist/workflows/WaitForEventManager.js +461 -0
  548. package/dist/workflows/WaitForEventManager.js.map +1 -0
  549. package/dist/workflows/analyzer.js +332 -0
  550. package/dist/workflows/analyzer.js.map +1 -0
  551. package/dist/workflows/compat/activity-router.js +484 -0
  552. package/dist/workflows/compat/activity-router.js.map +1 -0
  553. package/dist/workflows/compat/backends/cloudflare-workflows.js +431 -0
  554. package/dist/workflows/compat/backends/cloudflare-workflows.js.map +1 -0
  555. package/dist/workflows/compat/backends/index.js +14 -0
  556. package/dist/workflows/compat/backends/index.js.map +1 -0
  557. package/dist/workflows/compat/errors/index.js +375 -0
  558. package/dist/workflows/compat/errors/index.js.map +1 -0
  559. package/dist/workflows/compat/index.js +79 -0
  560. package/dist/workflows/compat/index.js.map +1 -0
  561. package/dist/workflows/compat/inngest/index.js +989 -0
  562. package/dist/workflows/compat/inngest/index.js.map +1 -0
  563. package/dist/workflows/compat/qstash/index.js +1263 -0
  564. package/dist/workflows/compat/qstash/index.js.map +1 -0
  565. package/dist/workflows/compat/temporal/activities.js +739 -0
  566. package/dist/workflows/compat/temporal/activities.js.map +1 -0
  567. package/dist/workflows/compat/temporal/child-workflows.js +154 -0
  568. package/dist/workflows/compat/temporal/child-workflows.js.map +1 -0
  569. package/dist/workflows/compat/temporal/client.js +381 -0
  570. package/dist/workflows/compat/temporal/client.js.map +1 -0
  571. package/dist/workflows/compat/temporal/context.js +309 -0
  572. package/dist/workflows/compat/temporal/context.js.map +1 -0
  573. package/dist/workflows/compat/temporal/determinism.js +216 -0
  574. package/dist/workflows/compat/temporal/determinism.js.map +1 -0
  575. package/dist/workflows/compat/temporal/errors.js +128 -0
  576. package/dist/workflows/compat/temporal/errors.js.map +1 -0
  577. package/dist/workflows/compat/temporal/index.js +2464 -0
  578. package/dist/workflows/compat/temporal/index.js.map +1 -0
  579. package/dist/workflows/compat/temporal/saga.js +504 -0
  580. package/dist/workflows/compat/temporal/saga.js.map +1 -0
  581. package/dist/workflows/compat/temporal/signals.js +364 -0
  582. package/dist/workflows/compat/temporal/signals.js.map +1 -0
  583. package/dist/workflows/compat/temporal/storage.js +271 -0
  584. package/dist/workflows/compat/temporal/storage.js.map +1 -0
  585. package/dist/workflows/compat/temporal/timers.js +347 -0
  586. package/dist/workflows/compat/temporal/timers.js.map +1 -0
  587. package/dist/workflows/compat/temporal/types.js +7 -0
  588. package/dist/workflows/compat/temporal/types.js.map +1 -0
  589. package/dist/workflows/compat/temporal/unified-primitives.js +339 -0
  590. package/dist/workflows/compat/temporal/unified-primitives.js.map +1 -0
  591. package/dist/workflows/compat/trigger/index.js +468 -0
  592. package/dist/workflows/compat/trigger/index.js.map +1 -0
  593. package/dist/workflows/compat/utils/index.js +69 -0
  594. package/dist/workflows/compat/utils/index.js.map +1 -0
  595. package/dist/workflows/context/correlation-capability.js +266 -0
  596. package/dist/workflows/context/correlation-capability.js.map +1 -0
  597. package/dist/workflows/context/correlation.js +484 -0
  598. package/dist/workflows/context/correlation.js.map +1 -0
  599. package/dist/workflows/context/experiment.js +289 -0
  600. package/dist/workflows/context/experiment.js.map +1 -0
  601. package/dist/workflows/context/flag.js +244 -0
  602. package/dist/workflows/context/flag.js.map +1 -0
  603. package/dist/workflows/context/foundation.js +648 -0
  604. package/dist/workflows/context/foundation.js.map +1 -0
  605. package/dist/workflows/context/human-base.js +106 -0
  606. package/dist/workflows/context/human-base.js.map +1 -0
  607. package/dist/workflows/context/human.js +368 -0
  608. package/dist/workflows/context/human.js.map +1 -0
  609. package/dist/workflows/context/measure.js +354 -0
  610. package/dist/workflows/context/measure.js.map +1 -0
  611. package/dist/workflows/context/rate-limit.js +358 -0
  612. package/dist/workflows/context/rate-limit.js.map +1 -0
  613. package/dist/workflows/context/user.js +117 -0
  614. package/dist/workflows/context/user.js.map +1 -0
  615. package/dist/workflows/context/vault.js +360 -0
  616. package/dist/workflows/context/vault.js.map +1 -0
  617. package/dist/workflows/data/entity-events/entity-events.js +489 -0
  618. package/dist/workflows/data/entity-events/entity-events.js.map +1 -0
  619. package/dist/workflows/data/experiment/index.js +599 -0
  620. package/dist/workflows/data/experiment/index.js.map +1 -0
  621. package/dist/workflows/data/goal/context.js +558 -0
  622. package/dist/workflows/data/goal/context.js.map +1 -0
  623. package/dist/workflows/data/goal/index.js +32 -0
  624. package/dist/workflows/data/goal/index.js.map +1 -0
  625. package/dist/workflows/data/measure/index.js +840 -0
  626. package/dist/workflows/data/measure/index.js.map +1 -0
  627. package/dist/workflows/data/stream/index.js +1149 -0
  628. package/dist/workflows/data/stream/index.js.map +1 -0
  629. package/dist/workflows/data/track/context.js +883 -0
  630. package/dist/workflows/data/track/context.js.map +1 -0
  631. package/dist/workflows/data/track/index.js +15 -0
  632. package/dist/workflows/data/track/index.js.map +1 -0
  633. package/dist/workflows/data/view/context.js +864 -0
  634. package/dist/workflows/data/view/context.js.map +1 -0
  635. package/dist/workflows/domain.js +93 -0
  636. package/dist/workflows/domain.js.map +1 -0
  637. package/dist/workflows/flag.js +176 -0
  638. package/dist/workflows/flag.js.map +1 -0
  639. package/dist/workflows/flags.js +217 -0
  640. package/dist/workflows/flags.js.map +1 -0
  641. package/dist/workflows/hash.js +209 -0
  642. package/dist/workflows/hash.js.map +1 -0
  643. package/dist/workflows/index.js +50 -0
  644. package/dist/workflows/index.js.map +1 -0
  645. package/dist/workflows/on.js +378 -0
  646. package/dist/workflows/on.js.map +1 -0
  647. package/dist/workflows/pipeline-promise.js +481 -0
  648. package/dist/workflows/pipeline-promise.js.map +1 -0
  649. package/dist/workflows/pipeline-types.js +20 -0
  650. package/dist/workflows/pipeline-types.js.map +1 -0
  651. package/dist/workflows/proxy.js +76 -0
  652. package/dist/workflows/proxy.js.map +1 -0
  653. package/dist/workflows/runtime.js +310 -0
  654. package/dist/workflows/runtime.js.map +1 -0
  655. package/dist/workflows/schedule-builder.js +327 -0
  656. package/dist/workflows/schedule-builder.js.map +1 -0
  657. package/dist/workflows/visibility/index.js +146 -0
  658. package/dist/workflows/visibility/index.js.map +1 -0
  659. package/dist/workflows/visibility/query-parser.js +150 -0
  660. package/dist/workflows/visibility/query-parser.js.map +1 -0
  661. package/dist/workflows/visibility/store.js +223 -0
  662. package/dist/workflows/visibility/store.js.map +1 -0
  663. package/dist/workflows/visibility/types.js +30 -0
  664. package/dist/workflows/visibility/types.js.map +1 -0
  665. package/dist/workflows/workflow.js +53 -0
  666. package/dist/workflows/workflow.js.map +1 -0
  667. package/package.json +294 -46
@@ -0,0 +1,1174 @@
1
+ /**
2
+ * IntegrationsDO - Provider Registry Durable Object
3
+ *
4
+ * Manages integration providers (GitHub, Stripe, Google, etc.) with:
5
+ * - OAuth configuration
6
+ * - Webhook verification
7
+ * - Rate limiting
8
+ * - Action definitions
9
+ */
10
+ export class SDKError extends Error {
11
+ code;
12
+ requestId;
13
+ statusCode;
14
+ retryable;
15
+ constructor(message, code, requestId, statusCode, retryable = false) {
16
+ super(message);
17
+ this.name = 'SDKError';
18
+ this.code = code;
19
+ this.requestId = requestId;
20
+ this.statusCode = statusCode;
21
+ this.retryable = retryable;
22
+ }
23
+ }
24
+ // ============================================================================
25
+ // BUILT-IN PROVIDERS
26
+ // ============================================================================
27
+ const BUILT_IN_PROVIDERS = [
28
+ {
29
+ id: 'github',
30
+ slug: 'github',
31
+ name: 'GitHub',
32
+ accountType: 'devtools',
33
+ icon: 'https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png',
34
+ oauthConfig: {
35
+ authUrl: 'https://github.com/login/oauth/authorize',
36
+ tokenUrl: 'https://github.com/login/oauth/access_token',
37
+ scopes: ['repo', 'user', 'read:org'],
38
+ clientIdEnvVar: 'GITHUB_CLIENT_ID',
39
+ clientSecretEnvVar: 'GITHUB_CLIENT_SECRET',
40
+ },
41
+ webhookConfig: {
42
+ signatureHeader: 'X-Hub-Signature-256',
43
+ algorithm: 'sha256',
44
+ secretEnvVar: 'GITHUB_WEBHOOK_SECRET',
45
+ },
46
+ actions: [
47
+ {
48
+ name: 'listRepos',
49
+ description: 'List repositories for the authenticated user',
50
+ scopes: ['repo'],
51
+ method: 'GET',
52
+ path: '/user/repos',
53
+ },
54
+ {
55
+ name: 'createIssue',
56
+ description: 'Create an issue in a repository',
57
+ scopes: ['repo'],
58
+ method: 'POST',
59
+ path: '/repos/{owner}/{repo}/issues',
60
+ },
61
+ ],
62
+ rateLimit: { max: 5000, windowMs: 3600000 },
63
+ },
64
+ {
65
+ id: 'stripe',
66
+ slug: 'stripe',
67
+ name: 'Stripe',
68
+ accountType: 'payments',
69
+ icon: 'https://stripe.com/img/v3/home/social.png',
70
+ oauthConfig: {
71
+ authUrl: 'https://connect.stripe.com/oauth/authorize',
72
+ tokenUrl: 'https://connect.stripe.com/oauth/token',
73
+ scopes: ['read_write'],
74
+ clientIdEnvVar: 'STRIPE_CLIENT_ID',
75
+ clientSecretEnvVar: 'STRIPE_CLIENT_SECRET',
76
+ },
77
+ webhookConfig: {
78
+ signatureHeader: 'Stripe-Signature',
79
+ algorithm: 'sha256',
80
+ secretEnvVar: 'STRIPE_WEBHOOK_SECRET',
81
+ },
82
+ actions: [
83
+ {
84
+ name: 'createPaymentIntent',
85
+ description: 'Create a payment intent',
86
+ scopes: ['read_write'],
87
+ method: 'POST',
88
+ path: '/v1/payment_intents',
89
+ },
90
+ {
91
+ name: 'listCustomers',
92
+ description: 'List all customers',
93
+ scopes: ['read_write'],
94
+ method: 'GET',
95
+ path: '/v1/customers',
96
+ },
97
+ ],
98
+ rateLimit: { max: 100, windowMs: 1000 },
99
+ },
100
+ {
101
+ id: 'google',
102
+ slug: 'google',
103
+ name: 'Google',
104
+ accountType: 'productivity',
105
+ icon: 'https://www.google.com/favicon.ico',
106
+ oauthConfig: {
107
+ authUrl: 'https://accounts.google.com/o/oauth2/v2/auth',
108
+ tokenUrl: 'https://oauth2.googleapis.com/token',
109
+ scopes: ['openid', 'email', 'profile'],
110
+ clientIdEnvVar: 'GOOGLE_CLIENT_ID',
111
+ clientSecretEnvVar: 'GOOGLE_CLIENT_SECRET',
112
+ },
113
+ actions: [
114
+ {
115
+ name: 'getUserInfo',
116
+ description: 'Get authenticated user info',
117
+ scopes: ['openid', 'email', 'profile'],
118
+ method: 'GET',
119
+ path: '/oauth2/v2/userinfo',
120
+ },
121
+ ],
122
+ },
123
+ ];
124
+ const BUILT_IN_SLUGS = new Set(BUILT_IN_PROVIDERS.map((p) => p.slug));
125
+ // ============================================================================
126
+ // BUILT-IN ACCOUNT TYPES
127
+ // ============================================================================
128
+ const BUILT_IN_ACCOUNT_TYPES = [
129
+ {
130
+ id: 'devtools',
131
+ slug: 'devtools',
132
+ name: 'Developer Tools',
133
+ icon: 'code',
134
+ description: 'Tools for software development, version control, and CI/CD',
135
+ providers: [],
136
+ },
137
+ {
138
+ id: 'crm',
139
+ slug: 'crm',
140
+ name: 'Customer Relationship Management',
141
+ icon: 'users',
142
+ description: 'Customer relationship and sales management tools',
143
+ providers: [],
144
+ },
145
+ {
146
+ id: 'payments',
147
+ slug: 'payments',
148
+ name: 'Payments',
149
+ icon: 'credit-card',
150
+ description: 'Payment processing and financial services',
151
+ providers: [],
152
+ },
153
+ {
154
+ id: 'communication',
155
+ slug: 'communication',
156
+ name: 'Communication',
157
+ icon: 'message-circle',
158
+ description: 'Messaging, email, and communication platforms',
159
+ providers: [],
160
+ },
161
+ {
162
+ id: 'productivity',
163
+ slug: 'productivity',
164
+ name: 'Productivity',
165
+ icon: 'briefcase',
166
+ description: 'Productivity and collaboration tools',
167
+ providers: [],
168
+ },
169
+ {
170
+ id: 'storage',
171
+ slug: 'storage',
172
+ name: 'Storage',
173
+ icon: 'hard-drive',
174
+ description: 'Cloud storage and file management services',
175
+ providers: [],
176
+ },
177
+ ];
178
+ const BUILT_IN_ACCOUNT_TYPE_SLUGS = new Set(BUILT_IN_ACCOUNT_TYPES.map((t) => t.slug));
179
+ // ============================================================================
180
+ // INTEGRATIONS DO
181
+ // ============================================================================
182
+ /**
183
+ * IntegrationsDO - standalone implementation for provider registry
184
+ *
185
+ * This class doesn't extend DO directly to allow for testing in node environment.
186
+ * It uses the same patterns and will be compatible with Cloudflare Workers runtime.
187
+ */
188
+ export class IntegrationsDO {
189
+ ns = 'https://integrations.do';
190
+ ctx;
191
+ env;
192
+ // Registered providers (custom providers + re-registered built-ins)
193
+ registeredProviders = new Map();
194
+ // Track deleted slugs (so we don't fall back to built-ins for deleted providers)
195
+ deletedSlugs = new Set();
196
+ // Registered account types (custom account types + re-registered built-ins)
197
+ registeredAccountTypes = new Map();
198
+ // Track deleted account type slugs (so we don't fall back to built-ins for deleted types)
199
+ deletedAccountTypeSlugs = new Set();
200
+ initialized = false;
201
+ // Providers with extended actions (SDK support)
202
+ providersWithActions = new Map();
203
+ constructor(ctx, env) {
204
+ this.ctx = ctx;
205
+ this.env = env;
206
+ }
207
+ // ═══════════════════════════════════════════════════════════════════════════
208
+ // INITIALIZATION
209
+ // ═══════════════════════════════════════════════════════════════════════════
210
+ async ensureInitialized() {
211
+ if (this.initialized)
212
+ return;
213
+ // Load custom providers from storage (not built-ins)
214
+ const storedProviders = await this.ctx.storage.list({ prefix: 'provider:' });
215
+ for (const [, provider] of storedProviders) {
216
+ this.registeredProviders.set(provider.slug, provider);
217
+ }
218
+ // Load custom account types from storage (not built-ins)
219
+ const storedAccountTypes = await this.ctx.storage.list({ prefix: 'accountType:' });
220
+ for (const [, accountType] of storedAccountTypes) {
221
+ this.registeredAccountTypes.set(accountType.slug, accountType);
222
+ }
223
+ this.initialized = true;
224
+ }
225
+ /**
226
+ * Get a built-in provider by slug (returns a copy)
227
+ */
228
+ getBuiltInProvider(slug) {
229
+ const builtIn = BUILT_IN_PROVIDERS.find((p) => p.slug === slug);
230
+ if (builtIn) {
231
+ return { ...builtIn, actions: [...builtIn.actions] };
232
+ }
233
+ return undefined;
234
+ }
235
+ /**
236
+ * Get a built-in account type by slug (returns a copy with dynamic providers list)
237
+ */
238
+ getBuiltInAccountType(slug) {
239
+ const builtIn = BUILT_IN_ACCOUNT_TYPES.find((t) => t.slug === slug);
240
+ if (builtIn) {
241
+ // Dynamically populate providers list from registered providers
242
+ const providers = this.getProvidersForAccountType(slug);
243
+ return { ...builtIn, providers };
244
+ }
245
+ return undefined;
246
+ }
247
+ /**
248
+ * Get provider slugs for a given account type
249
+ */
250
+ getProvidersForAccountType(accountTypeSlug) {
251
+ const providers = [];
252
+ for (const provider of this.registeredProviders.values()) {
253
+ if (provider.accountType === accountTypeSlug) {
254
+ providers.push(provider.slug);
255
+ }
256
+ }
257
+ return providers;
258
+ }
259
+ // ═══════════════════════════════════════════════════════════════════════════
260
+ // VALIDATION
261
+ // ═══════════════════════════════════════════════════════════════════════════
262
+ validateProvider(provider) {
263
+ // Validate OAuth config
264
+ if (!provider.oauthConfig) {
265
+ throw new Error('Invalid provider: oauthConfig is required');
266
+ }
267
+ const { authUrl, tokenUrl, clientIdEnvVar, clientSecretEnvVar } = provider.oauthConfig;
268
+ if (!authUrl || authUrl.trim() === '') {
269
+ throw new Error('Invalid provider: authUrl is required');
270
+ }
271
+ if (!tokenUrl || tokenUrl.trim() === '') {
272
+ throw new Error('Invalid provider: tokenUrl is required');
273
+ }
274
+ if (!clientIdEnvVar || clientIdEnvVar.trim() === '') {
275
+ throw new Error('Invalid provider: clientIdEnvVar is required');
276
+ }
277
+ if (!clientSecretEnvVar || clientSecretEnvVar.trim() === '') {
278
+ throw new Error('Invalid provider: clientSecretEnvVar is required');
279
+ }
280
+ // Validate URLs
281
+ try {
282
+ new URL(authUrl);
283
+ }
284
+ catch {
285
+ throw new Error('Invalid provider: authUrl is not a valid URL');
286
+ }
287
+ try {
288
+ new URL(tokenUrl);
289
+ }
290
+ catch {
291
+ throw new Error('Invalid provider: tokenUrl is not a valid URL');
292
+ }
293
+ // Validate rate limit if present
294
+ if (provider.rateLimit) {
295
+ if (provider.rateLimit.max <= 0) {
296
+ throw new Error('Invalid provider: rateLimit.max must be positive');
297
+ }
298
+ if (provider.rateLimit.windowMs <= 0) {
299
+ throw new Error('Invalid provider: rateLimit.windowMs must be positive');
300
+ }
301
+ }
302
+ }
303
+ // ═══════════════════════════════════════════════════════════════════════════
304
+ // PROVIDER CRUD
305
+ // ═══════════════════════════════════════════════════════════════════════════
306
+ async registerProvider(provider) {
307
+ await this.ensureInitialized();
308
+ const slug = provider.slug;
309
+ const id = provider.id || slug;
310
+ // Check for duplicates in registered providers
311
+ if (this.registeredProviders.has(slug)) {
312
+ throw new Error(`Provider with slug '${slug}' already exists`);
313
+ }
314
+ // Validate
315
+ this.validateProvider(provider);
316
+ const newProvider = {
317
+ ...provider,
318
+ id,
319
+ actions: provider.actions ? [...provider.actions] : [],
320
+ };
321
+ // Store in registered providers
322
+ this.registeredProviders.set(slug, newProvider);
323
+ // Remove from deleted set (in case it was previously deleted)
324
+ this.deletedSlugs.delete(slug);
325
+ // Persist to storage
326
+ await this.ctx.storage.put(`provider:${slug}`, newProvider);
327
+ return newProvider;
328
+ }
329
+ async getProvider(slug) {
330
+ await this.ensureInitialized();
331
+ // If this slug was explicitly deleted, return null
332
+ if (this.deletedSlugs.has(slug)) {
333
+ return null;
334
+ }
335
+ // First check registered providers
336
+ const registered = this.registeredProviders.get(slug);
337
+ if (registered) {
338
+ return registered;
339
+ }
340
+ // Fall back to built-in providers
341
+ return this.getBuiltInProvider(slug) || null;
342
+ }
343
+ async getProviderById(id) {
344
+ await this.ensureInitialized();
345
+ // Check registered providers first
346
+ for (const provider of this.registeredProviders.values()) {
347
+ if (provider.id === id) {
348
+ return provider;
349
+ }
350
+ }
351
+ // Check built-in providers
352
+ const builtIn = BUILT_IN_PROVIDERS.find((p) => p.id === id);
353
+ if (builtIn) {
354
+ return { ...builtIn, actions: [...builtIn.actions] };
355
+ }
356
+ return null;
357
+ }
358
+ async updateProvider(slug, updates) {
359
+ await this.ensureInitialized();
360
+ // Get existing provider (from registered or built-in)
361
+ const existing = this.registeredProviders.get(slug) || this.getBuiltInProvider(slug);
362
+ if (!existing) {
363
+ return null;
364
+ }
365
+ // Cannot update slug
366
+ if (updates.slug && updates.slug !== slug) {
367
+ throw new Error('Cannot update slug: slug is immutable');
368
+ }
369
+ // Merge updates
370
+ const updated = {
371
+ ...existing,
372
+ ...updates,
373
+ id: existing.id, // Preserve id
374
+ slug: existing.slug, // Preserve slug
375
+ };
376
+ // Validate the updated provider
377
+ this.validateProvider(updated);
378
+ // Store as registered (even for built-ins that get updated)
379
+ this.registeredProviders.set(slug, updated);
380
+ await this.ctx.storage.put(`provider:${slug}`, updated);
381
+ return updated;
382
+ }
383
+ async deleteProvider(slug, options) {
384
+ await this.ensureInitialized();
385
+ const isRegistered = this.registeredProviders.has(slug);
386
+ const isBuiltIn = BUILT_IN_SLUGS.has(slug);
387
+ const wasDeleted = this.deletedSlugs.has(slug);
388
+ // If not registered, not built-in, and not previously deleted, nothing to delete
389
+ if (!isRegistered && !isBuiltIn) {
390
+ return false;
391
+ }
392
+ // If already deleted, return false
393
+ if (wasDeleted && !isRegistered) {
394
+ return false;
395
+ }
396
+ // Protect built-in providers that haven't been re-registered
397
+ if (isBuiltIn && !isRegistered && !options?.force) {
398
+ throw new Error(`Cannot delete built-in provider '${slug}' without force flag`);
399
+ }
400
+ // Remove from registered providers
401
+ this.registeredProviders.delete(slug);
402
+ await this.ctx.storage.delete(`provider:${slug}`);
403
+ // Mark as deleted so getProvider won't return built-in
404
+ this.deletedSlugs.add(slug);
405
+ return true;
406
+ }
407
+ // ═══════════════════════════════════════════════════════════════════════════
408
+ // ACCOUNT TYPE CRUD
409
+ // ═══════════════════════════════════════════════════════════════════════════
410
+ async registerAccountType(type) {
411
+ await this.ensureInitialized();
412
+ const slug = type.slug;
413
+ const id = type.id || slug;
414
+ // Check if slug already exists in registered account types (not built-ins)
415
+ // This allows registering custom types that override built-ins
416
+ if (this.registeredAccountTypes.has(slug)) {
417
+ throw new Error(`Account type with slug '${slug}' already exists`);
418
+ }
419
+ const newType = {
420
+ ...type,
421
+ id,
422
+ providers: type.providers ? [...type.providers] : [],
423
+ };
424
+ // Store in registered account types
425
+ this.registeredAccountTypes.set(slug, newType);
426
+ // Remove from deleted set (in case it was previously deleted)
427
+ this.deletedAccountTypeSlugs.delete(slug);
428
+ // Persist to storage
429
+ await this.ctx.storage.put(`accountType:${slug}`, newType);
430
+ return newType;
431
+ }
432
+ async getAccountType(slug) {
433
+ await this.ensureInitialized();
434
+ // If this slug was explicitly deleted, return null
435
+ if (this.deletedAccountTypeSlugs.has(slug)) {
436
+ return null;
437
+ }
438
+ // First check registered account types
439
+ const registered = this.registeredAccountTypes.get(slug);
440
+ if (registered) {
441
+ // Merge explicitly registered providers with dynamically discovered ones
442
+ const dynamicProviders = this.getProvidersForAccountType(slug);
443
+ const explicitProviders = registered.providers || [];
444
+ const allProviders = new Set([...explicitProviders, ...dynamicProviders]);
445
+ return { ...registered, providers: Array.from(allProviders) };
446
+ }
447
+ // Fall back to built-in account types
448
+ return this.getBuiltInAccountType(slug) || null;
449
+ }
450
+ async updateAccountType(slug, updates) {
451
+ await this.ensureInitialized();
452
+ // Cannot update slug
453
+ if (updates.slug && updates.slug !== slug) {
454
+ throw new Error('Cannot update slug: slug is immutable');
455
+ }
456
+ // Get existing account type (from registered or built-in)
457
+ const existing = this.registeredAccountTypes.get(slug) || this.getBuiltInAccountType(slug);
458
+ if (!existing) {
459
+ return null;
460
+ }
461
+ // Merge updates (but don't allow slug or id to change)
462
+ const { slug: _slug, id: _id, ...safeUpdates } = updates;
463
+ const updated = {
464
+ ...existing,
465
+ ...safeUpdates,
466
+ id: existing.id,
467
+ slug: existing.slug,
468
+ };
469
+ // Store as registered (even for built-ins that get updated)
470
+ this.registeredAccountTypes.set(slug, updated);
471
+ await this.ctx.storage.put(`accountType:${slug}`, updated);
472
+ // Dynamically populate providers list
473
+ const providers = this.getProvidersForAccountType(slug);
474
+ return { ...updated, providers };
475
+ }
476
+ async deleteAccountType(slug, options) {
477
+ await this.ensureInitialized();
478
+ const isRegistered = this.registeredAccountTypes.has(slug);
479
+ const isBuiltIn = BUILT_IN_ACCOUNT_TYPE_SLUGS.has(slug);
480
+ const wasDeleted = this.deletedAccountTypeSlugs.has(slug);
481
+ // If not registered, not built-in, and not previously deleted, nothing to delete
482
+ if (!isRegistered && !isBuiltIn) {
483
+ return false;
484
+ }
485
+ // If already deleted, return false
486
+ if (wasDeleted && !isRegistered) {
487
+ return false;
488
+ }
489
+ // Protect built-in account types that haven't been re-registered
490
+ if (isBuiltIn && !isRegistered && !options?.force) {
491
+ throw new Error(`Cannot delete built-in account type '${slug}' without force flag`);
492
+ }
493
+ // Remove from registered account types
494
+ this.registeredAccountTypes.delete(slug);
495
+ await this.ctx.storage.delete(`accountType:${slug}`);
496
+ // Mark as deleted so getAccountType won't return built-in
497
+ this.deletedAccountTypeSlugs.add(slug);
498
+ return true;
499
+ }
500
+ async listAccountTypes() {
501
+ await this.ensureInitialized();
502
+ const typesMap = new Map();
503
+ // Add built-in account types that haven't been deleted
504
+ for (const builtIn of BUILT_IN_ACCOUNT_TYPES) {
505
+ if (!this.deletedAccountTypeSlugs.has(builtIn.slug)) {
506
+ const providers = this.getProvidersForAccountType(builtIn.slug);
507
+ typesMap.set(builtIn.slug, { ...builtIn, providers });
508
+ }
509
+ }
510
+ // Add/override with registered account types
511
+ for (const [slug, type] of this.registeredAccountTypes) {
512
+ const providers = this.getProvidersForAccountType(slug);
513
+ typesMap.set(slug, { ...type, providers });
514
+ }
515
+ return Array.from(typesMap.values());
516
+ }
517
+ async listBuiltInAccountTypes() {
518
+ await this.ensureInitialized();
519
+ // Return copies of built-in account types with dynamic providers
520
+ return BUILT_IN_ACCOUNT_TYPES.map((t) => {
521
+ const providers = this.getProvidersForAccountType(t.slug);
522
+ return { ...t, providers };
523
+ });
524
+ }
525
+ async isBuiltInAccountType(slug) {
526
+ return BUILT_IN_ACCOUNT_TYPE_SLUGS.has(slug);
527
+ }
528
+ // ═══════════════════════════════════════════════════════════════════════════
529
+ // LISTING
530
+ // ═══════════════════════════════════════════════════════════════════════════
531
+ async listProviders(options) {
532
+ await this.ensureInitialized();
533
+ // Only return registered providers (not built-ins unless they were registered)
534
+ const all = Array.from(this.registeredProviders.values());
535
+ const limit = options?.limit ?? all.length;
536
+ const offset = options?.offset ?? 0;
537
+ return all.slice(offset, offset + limit);
538
+ }
539
+ async listProvidersByAccountType(accountType) {
540
+ await this.ensureInitialized();
541
+ // Search in registered providers only
542
+ return Array.from(this.registeredProviders.values()).filter((p) => p.accountType === accountType);
543
+ }
544
+ async searchProviders(query) {
545
+ await this.ensureInitialized();
546
+ const lowerQuery = query.toLowerCase();
547
+ // Search in registered providers only
548
+ return Array.from(this.registeredProviders.values()).filter((p) => p.name.toLowerCase().includes(lowerQuery) || p.slug.toLowerCase().includes(lowerQuery));
549
+ }
550
+ async getAccountTypes() {
551
+ await this.ensureInitialized();
552
+ const types = new Set();
553
+ // Get types from registered providers only
554
+ for (const provider of this.registeredProviders.values()) {
555
+ types.add(provider.accountType);
556
+ }
557
+ return Array.from(types);
558
+ }
559
+ async listBuiltInProviders() {
560
+ // Return copies of built-in providers
561
+ return BUILT_IN_PROVIDERS.map((p) => ({ ...p, actions: [...p.actions] }));
562
+ }
563
+ async isBuiltIn(slug) {
564
+ return BUILT_IN_SLUGS.has(slug);
565
+ }
566
+ // ═══════════════════════════════════════════════════════════════════════════
567
+ // ACTION MANAGEMENT
568
+ // ═══════════════════════════════════════════════════════════════════════════
569
+ async getActionsByScope(slug, scope) {
570
+ await this.ensureInitialized();
571
+ // Get provider from registered or built-in
572
+ const provider = this.registeredProviders.get(slug) || this.getBuiltInProvider(slug);
573
+ if (!provider) {
574
+ return [];
575
+ }
576
+ return provider.actions.filter((a) => a.scopes.includes(scope));
577
+ }
578
+ async addAction(slug, action) {
579
+ await this.ensureInitialized();
580
+ // Get provider (must be registered to modify)
581
+ const provider = this.registeredProviders.get(slug);
582
+ if (!provider) {
583
+ throw new Error(`Provider '${slug}' not found`);
584
+ }
585
+ provider.actions.push(action);
586
+ this.registeredProviders.set(slug, provider);
587
+ await this.ctx.storage.put(`provider:${slug}`, provider);
588
+ }
589
+ async removeAction(slug, actionName) {
590
+ await this.ensureInitialized();
591
+ // Get provider (must be registered to modify)
592
+ const provider = this.registeredProviders.get(slug);
593
+ if (!provider) {
594
+ throw new Error(`Provider '${slug}' not found`);
595
+ }
596
+ provider.actions = provider.actions.filter((a) => a.name !== actionName);
597
+ this.registeredProviders.set(slug, provider);
598
+ await this.ctx.storage.put(`provider:${slug}`, provider);
599
+ }
600
+ // ═══════════════════════════════════════════════════════════════════════════
601
+ // PROVIDER ACTIONS SDK
602
+ // ═══════════════════════════════════════════════════════════════════════════
603
+ /**
604
+ * Register a provider with extended action definitions (input/output schemas, rate limits)
605
+ */
606
+ async registerProviderWithActions(provider) {
607
+ await this.ensureInitialized();
608
+ const slug = provider.slug;
609
+ // Store in providers with actions map
610
+ this.providersWithActions.set(slug, provider);
611
+ // Persist to storage
612
+ await this.ctx.storage.put(`providerWithActions:${slug}`, provider);
613
+ return provider;
614
+ }
615
+ /**
616
+ * Get a specific action from a provider
617
+ */
618
+ async getAction(providerSlug, actionName) {
619
+ await this.ensureInitialized();
620
+ const provider = this.providersWithActions.get(providerSlug);
621
+ if (!provider) {
622
+ return null;
623
+ }
624
+ const action = provider.actions.find((a) => a.name === actionName);
625
+ return action || null;
626
+ }
627
+ /**
628
+ * Get all actions for a provider
629
+ */
630
+ async getActions(providerSlug) {
631
+ await this.ensureInitialized();
632
+ const provider = this.providersWithActions.get(providerSlug);
633
+ if (!provider) {
634
+ return [];
635
+ }
636
+ return provider.actions;
637
+ }
638
+ /**
639
+ * Get the effective rate limit for an action (action-level or provider-level)
640
+ */
641
+ async getEffectiveRateLimit(providerSlug, actionName) {
642
+ await this.ensureInitialized();
643
+ const provider = this.providersWithActions.get(providerSlug);
644
+ if (!provider) {
645
+ throw new Error(`Provider '${providerSlug}' not found`);
646
+ }
647
+ const action = provider.actions.find((a) => a.name === actionName);
648
+ // Action-level rate limit takes precedence
649
+ if (action?.rateLimit) {
650
+ return action.rateLimit;
651
+ }
652
+ // Fall back to provider-level rate limit
653
+ if (provider.rateLimit) {
654
+ return provider.rateLimit;
655
+ }
656
+ // Default rate limit if none specified
657
+ return { max: 1000, windowMs: 60000 };
658
+ }
659
+ /**
660
+ * Validate input against an action's input schema
661
+ */
662
+ async validateActionInput(providerSlug, actionName, input) {
663
+ await this.ensureInitialized();
664
+ const action = await this.getAction(providerSlug, actionName);
665
+ if (!action) {
666
+ return { valid: false, errors: [`Action '${actionName}' not found`] };
667
+ }
668
+ if (!action.inputSchema) {
669
+ // No schema means any input is valid
670
+ return { valid: true, errors: [] };
671
+ }
672
+ const errors = [];
673
+ // Validate required fields
674
+ if (action.inputSchema.required) {
675
+ for (const field of action.inputSchema.required) {
676
+ if (input[field] === undefined) {
677
+ errors.push(`${field} is required`);
678
+ }
679
+ }
680
+ }
681
+ // Validate type of provided fields
682
+ if (action.inputSchema.properties) {
683
+ for (const [field, value] of Object.entries(input)) {
684
+ const schema = action.inputSchema.properties[field];
685
+ if (schema) {
686
+ const typeValid = this.validateType(value, schema);
687
+ if (!typeValid) {
688
+ errors.push(`${field} has invalid type`);
689
+ }
690
+ }
691
+ }
692
+ }
693
+ return { valid: errors.length === 0, errors };
694
+ }
695
+ /**
696
+ * Helper to validate value against schema type
697
+ */
698
+ validateType(value, schema) {
699
+ switch (schema.type) {
700
+ case 'string':
701
+ return typeof value === 'string';
702
+ case 'number':
703
+ return typeof value === 'number';
704
+ case 'boolean':
705
+ return typeof value === 'boolean';
706
+ case 'array':
707
+ return Array.isArray(value);
708
+ case 'object':
709
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
710
+ default:
711
+ return true;
712
+ }
713
+ }
714
+ /**
715
+ * Fetch token from Vault DO
716
+ */
717
+ async fetchTokenFromVault(linkedAccountId) {
718
+ const vaultDO = this.env.VAULT_DO;
719
+ if (!vaultDO) {
720
+ return null;
721
+ }
722
+ const doId = vaultDO.idFromName ? vaultDO.idFromName(linkedAccountId) : linkedAccountId;
723
+ const stub = vaultDO.get(doId);
724
+ const response = await stub.fetch(new Request(`http://vault/token/${linkedAccountId}`));
725
+ if (!response.ok) {
726
+ return null;
727
+ }
728
+ // Clone response before reading to handle test mocks that reuse same Response object
729
+ try {
730
+ const data = (await response.clone().json());
731
+ return data;
732
+ }
733
+ catch {
734
+ // If clone fails, try reading directly
735
+ const data = (await response.json());
736
+ return data;
737
+ }
738
+ }
739
+ /**
740
+ * Refresh token in Vault DO
741
+ */
742
+ async refreshTokenInVault(linkedAccountId) {
743
+ const vaultDO = this.env.VAULT_DO;
744
+ if (!vaultDO) {
745
+ return null;
746
+ }
747
+ const doId = vaultDO.idFromName ? vaultDO.idFromName(linkedAccountId) : linkedAccountId;
748
+ const stub = vaultDO.get(doId);
749
+ const response = await stub.fetch(new Request(`http://vault/token/${linkedAccountId}/refresh`, { method: 'POST' }));
750
+ if (!response.ok) {
751
+ return null;
752
+ }
753
+ // Clone response before reading to handle test mocks that reuse same Response object
754
+ try {
755
+ const data = (await response.clone().json());
756
+ return data;
757
+ }
758
+ catch {
759
+ // If clone fails, try reading directly
760
+ const data = (await response.json());
761
+ return data;
762
+ }
763
+ }
764
+ /**
765
+ * Create a typed SDK for a provider
766
+ */
767
+ async createSDK(providerSlug, linkedAccountId, options = {}) {
768
+ await this.ensureInitialized();
769
+ const provider = this.providersWithActions.get(providerSlug);
770
+ if (!provider) {
771
+ throw new Error(`Provider '${providerSlug}' not found`);
772
+ }
773
+ // Fetch initial token
774
+ const tokenData = await this.fetchTokenFromVault(linkedAccountId);
775
+ if (!tokenData) {
776
+ throw new Error(`Linked account '${linkedAccountId}' not found - no valid token`);
777
+ }
778
+ // Default options
779
+ const sdkOptions = {
780
+ maxRetries: options.maxRetries ?? 3,
781
+ retryDelayMs: options.retryDelayMs ?? 100,
782
+ timeout: options.timeout ?? 30000,
783
+ };
784
+ // Track rate limits per action
785
+ const rateLimitStates = new Map();
786
+ // Token state (mutable for refresh)
787
+ let currentToken = tokenData;
788
+ // Generate request ID
789
+ const generateRequestId = () => `sdk-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
790
+ // Helper to sleep
791
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
792
+ // Check and update rate limit
793
+ const checkRateLimit = async (actionName) => {
794
+ const rateLimit = await this.getEffectiveRateLimit(providerSlug, actionName);
795
+ const now = Date.now();
796
+ let state = rateLimitStates.get(actionName);
797
+ if (!state || now - state.windowStart > rateLimit.windowMs) {
798
+ // Reset window
799
+ state = { requestCount: 0, windowStart: now };
800
+ rateLimitStates.set(actionName, state);
801
+ }
802
+ if (state.requestCount >= rateLimit.max) {
803
+ return false; // Rate limited
804
+ }
805
+ state.requestCount++;
806
+ return true;
807
+ };
808
+ // Get rate limit state for an action
809
+ const getRateLimitState = (actionName) => {
810
+ return rateLimitStates.get(actionName);
811
+ };
812
+ // Execute action with retry logic
813
+ const executeAction = async (action, params, callOptions) => {
814
+ const requestId = generateRequestId();
815
+ // Validate input
816
+ const validation = await this.validateActionInput(providerSlug, action.name, params);
817
+ if (!validation.valid) {
818
+ throw new SDKError(`Validation failed: ${validation.errors.join(', ')}`, 'VALIDATION_ERROR', requestId, 400, false);
819
+ }
820
+ // Check rate limit
821
+ if (!callOptions?.queue) {
822
+ const allowed = await checkRateLimit(action.name);
823
+ if (!allowed) {
824
+ throw new SDKError('Rate limit exceeded', 'RATE_LIMITED', requestId, 429, true);
825
+ }
826
+ }
827
+ // Build URL with path parameters
828
+ let url = action.endpoint;
829
+ const bodyParams = {};
830
+ for (const [key, value] of Object.entries(params)) {
831
+ const placeholder = `{${key}}`;
832
+ if (url.includes(placeholder)) {
833
+ url = url.replace(placeholder, String(value));
834
+ }
835
+ else {
836
+ bodyParams[key] = value;
837
+ }
838
+ }
839
+ // Retry loop
840
+ let lastError = null;
841
+ let retryCount = 0;
842
+ const maxRetries = sdkOptions.maxRetries;
843
+ while (retryCount <= maxRetries) {
844
+ try {
845
+ // Check if token is expired and refresh
846
+ if (currentToken.expiresAt < Date.now()) {
847
+ const newToken = await this.refreshTokenInVault(linkedAccountId);
848
+ if (newToken) {
849
+ currentToken = newToken;
850
+ }
851
+ }
852
+ const fetchOptions = {
853
+ method: action.method,
854
+ headers: {
855
+ Authorization: `Bearer ${currentToken.accessToken}`,
856
+ 'Content-Type': 'application/json',
857
+ },
858
+ };
859
+ if (action.method !== 'GET' && Object.keys(bodyParams).length > 0) {
860
+ fetchOptions.body = JSON.stringify(bodyParams);
861
+ }
862
+ const response = await fetch(`https://api.example.com.ai${url}`, fetchOptions);
863
+ // Handle response - clone before reading to handle test mocks that reuse Response objects
864
+ if (response.ok) {
865
+ let data;
866
+ try {
867
+ data = await response.clone().json();
868
+ }
869
+ catch {
870
+ data = await response.json();
871
+ }
872
+ if (callOptions?.includeRateLimit) {
873
+ const rateLimitInfo = {
874
+ remaining: parseInt(response.headers.get('X-RateLimit-Remaining') || '0', 10),
875
+ limit: parseInt(response.headers.get('X-RateLimit-Limit') || '0', 10),
876
+ resetAt: new Date(parseInt(response.headers.get('X-RateLimit-Reset') || '0', 10) * 1000),
877
+ };
878
+ return { data, rateLimit: rateLimitInfo };
879
+ }
880
+ return data;
881
+ }
882
+ // Get request ID from response
883
+ const responseRequestId = response.headers.get('X-Request-Id') || requestId;
884
+ // Handle specific status codes
885
+ if (response.status === 401) {
886
+ // Try to refresh token
887
+ const newToken = await this.refreshTokenInVault(linkedAccountId);
888
+ if (newToken && retryCount < maxRetries) {
889
+ currentToken = newToken;
890
+ retryCount++;
891
+ continue;
892
+ }
893
+ throw new SDKError('Unauthorized', 'UNAUTHORIZED', responseRequestId, 401, false);
894
+ }
895
+ if (response.status === 429) {
896
+ if (retryCount < maxRetries) {
897
+ const retryAfter = parseInt(response.headers.get('Retry-After') || '1', 10);
898
+ await sleep(retryAfter * 1000);
899
+ retryCount++;
900
+ continue;
901
+ }
902
+ throw new SDKError('Rate limited', 'RATE_LIMITED', responseRequestId, 429, true);
903
+ }
904
+ if (response.status >= 400 && response.status < 500) {
905
+ // Client errors (except 401, 429) are not retryable
906
+ throw new SDKError(`Client error: ${response.status}`, 'VALIDATION_ERROR', responseRequestId, response.status, false);
907
+ }
908
+ if (response.status >= 500) {
909
+ // Server errors are retryable
910
+ if (retryCount < maxRetries) {
911
+ const delay = sdkOptions.retryDelayMs * Math.pow(2, retryCount);
912
+ await sleep(delay);
913
+ retryCount++;
914
+ continue;
915
+ }
916
+ throw new SDKError(`Server error: ${response.status}`, 'SERVER_ERROR', responseRequestId, response.status, true);
917
+ }
918
+ }
919
+ catch (error) {
920
+ if (error instanceof SDKError) {
921
+ throw error;
922
+ }
923
+ // Network error
924
+ if (retryCount < maxRetries) {
925
+ const delay = sdkOptions.retryDelayMs * Math.pow(2, retryCount);
926
+ await sleep(delay);
927
+ retryCount++;
928
+ lastError = error;
929
+ continue;
930
+ }
931
+ throw new SDKError(`Network error: ${error.message}`, 'NETWORK_ERROR', requestId, undefined, true);
932
+ }
933
+ }
934
+ throw lastError || new SDKError('Max retries exceeded', 'SERVER_ERROR', requestId, undefined, true);
935
+ };
936
+ // Build SDK object with methods for each action
937
+ const sdk = {};
938
+ for (const action of provider.actions) {
939
+ sdk[action.name] = async (params, callOptions) => {
940
+ return executeAction(action, params, callOptions);
941
+ };
942
+ }
943
+ // Add metadata
944
+ sdk._metadata = {
945
+ provider: providerSlug,
946
+ linkedAccountId,
947
+ actions: provider.actions.map((a) => a.name),
948
+ options: sdkOptions,
949
+ };
950
+ // Add rate limit state getter
951
+ sdk.getRateLimitState = getRateLimitState;
952
+ return sdk;
953
+ }
954
+ // ═══════════════════════════════════════════════════════════════════════════
955
+ // WEBHOOK VERIFICATION
956
+ // ═══════════════════════════════════════════════════════════════════════════
957
+ async verifyWebhookSignature(slug, payload, signature) {
958
+ await this.ensureInitialized();
959
+ // Get provider from registered or built-in
960
+ const provider = this.registeredProviders.get(slug) || this.getBuiltInProvider(slug);
961
+ if (!provider || !provider.webhookConfig) {
962
+ return false;
963
+ }
964
+ const { algorithm, secretEnvVar } = provider.webhookConfig;
965
+ const secret = this.env[secretEnvVar];
966
+ if (!secret) {
967
+ return false;
968
+ }
969
+ try {
970
+ // Extract the signature hash part (e.g., "sha256=abc123" -> "abc123")
971
+ const [algo, hash] = signature.split('=');
972
+ if (!hash) {
973
+ return false;
974
+ }
975
+ // Verify algorithm matches
976
+ if (algo !== algorithm) {
977
+ return false;
978
+ }
979
+ // Compute expected signature using Web Crypto API
980
+ const encoder = new TextEncoder();
981
+ const key = await crypto.subtle.importKey('raw', encoder.encode(secret), { name: 'HMAC', hash: algorithm === 'sha256' ? 'SHA-256' : 'SHA-1' }, false, ['sign']);
982
+ const signatureBuffer = await crypto.subtle.sign('HMAC', key, encoder.encode(payload));
983
+ const expectedHash = Array.from(new Uint8Array(signatureBuffer))
984
+ .map((b) => b.toString(16).padStart(2, '0'))
985
+ .join('');
986
+ // Constant-time comparison
987
+ if (hash.length !== expectedHash.length) {
988
+ return false;
989
+ }
990
+ let result = 0;
991
+ for (let i = 0; i < hash.length; i++) {
992
+ result |= hash.charCodeAt(i) ^ expectedHash.charCodeAt(i);
993
+ }
994
+ return result === 0;
995
+ }
996
+ catch {
997
+ return false;
998
+ }
999
+ }
1000
+ // ═══════════════════════════════════════════════════════════════════════════
1001
+ // HTTP API
1002
+ // ═══════════════════════════════════════════════════════════════════════════
1003
+ async fetch(request) {
1004
+ const url = new URL(request.url);
1005
+ const method = request.method;
1006
+ const path = url.pathname;
1007
+ try {
1008
+ // GET /providers
1009
+ if (method === 'GET' && path === '/providers') {
1010
+ const accountType = url.searchParams.get('accountType');
1011
+ const search = url.searchParams.get('search');
1012
+ let providers;
1013
+ if (accountType) {
1014
+ providers = await this.listProvidersByAccountType(accountType);
1015
+ }
1016
+ else if (search) {
1017
+ providers = await this.searchProviders(search);
1018
+ }
1019
+ else {
1020
+ providers = await this.listProviders();
1021
+ }
1022
+ return Response.json(providers);
1023
+ }
1024
+ // GET /providers/:slug
1025
+ const providerMatch = path.match(/^\/providers\/([^/]+)$/);
1026
+ if (method === 'GET' && providerMatch) {
1027
+ const slug = providerMatch[1];
1028
+ const provider = await this.getProvider(slug);
1029
+ if (!provider) {
1030
+ return new Response('Provider not found', { status: 404 });
1031
+ }
1032
+ return Response.json(provider);
1033
+ }
1034
+ // POST /providers
1035
+ if (method === 'POST' && path === '/providers') {
1036
+ const body = (await request.json());
1037
+ const provider = await this.registerProvider(body);
1038
+ return Response.json(provider, { status: 201 });
1039
+ }
1040
+ // PUT /providers/:slug
1041
+ if (method === 'PUT' && providerMatch) {
1042
+ const slug = providerMatch[1];
1043
+ const body = (await request.json());
1044
+ const provider = await this.updateProvider(slug, body);
1045
+ if (!provider) {
1046
+ return new Response('Provider not found', { status: 404 });
1047
+ }
1048
+ return Response.json(provider);
1049
+ }
1050
+ // DELETE /providers/:slug
1051
+ if (method === 'DELETE' && providerMatch) {
1052
+ const slug = providerMatch[1];
1053
+ const deleted = await this.deleteProvider(slug);
1054
+ if (!deleted) {
1055
+ return new Response('Provider not found', { status: 404 });
1056
+ }
1057
+ return Response.json({ success: true });
1058
+ }
1059
+ // POST /providers/:slug/verify-webhook
1060
+ const webhookMatch = path.match(/^\/providers\/([^/]+)\/verify-webhook$/);
1061
+ if (method === 'POST' && webhookMatch) {
1062
+ const slug = webhookMatch[1];
1063
+ const body = (await request.json());
1064
+ const valid = await this.verifyWebhookSignature(slug, body.payload, body.signature);
1065
+ return Response.json({ valid });
1066
+ }
1067
+ // GET /account-types - list all account types as objects
1068
+ if (method === 'GET' && path === '/account-types') {
1069
+ const types = await this.listAccountTypes();
1070
+ return Response.json(types);
1071
+ }
1072
+ // Account type routes
1073
+ const accountTypeMatch = path.match(/^\/account-types\/([^/]+)$/);
1074
+ // GET /account-types/:slug
1075
+ if (method === 'GET' && accountTypeMatch) {
1076
+ const slug = accountTypeMatch[1];
1077
+ const accountType = await this.getAccountType(slug);
1078
+ if (!accountType) {
1079
+ return new Response('Account type not found', { status: 404 });
1080
+ }
1081
+ return Response.json(accountType);
1082
+ }
1083
+ // POST /account-types
1084
+ if (method === 'POST' && path === '/account-types') {
1085
+ const body = (await request.json());
1086
+ // Check if this slug already exists (as built-in or registered)
1087
+ const existing = await this.getAccountType(body.slug);
1088
+ if (existing) {
1089
+ return Response.json({ error: `Account type with slug '${body.slug}' already exists` }, { status: 400 });
1090
+ }
1091
+ const accountType = await this.registerAccountType(body);
1092
+ return Response.json(accountType, { status: 201 });
1093
+ }
1094
+ // PUT /account-types/:slug
1095
+ if (method === 'PUT' && accountTypeMatch) {
1096
+ const slug = accountTypeMatch[1];
1097
+ const body = (await request.json());
1098
+ const accountType = await this.updateAccountType(slug, body);
1099
+ if (!accountType) {
1100
+ return new Response('Account type not found', { status: 404 });
1101
+ }
1102
+ return Response.json(accountType);
1103
+ }
1104
+ // DELETE /account-types/:slug
1105
+ if (method === 'DELETE' && accountTypeMatch) {
1106
+ const slug = accountTypeMatch[1];
1107
+ try {
1108
+ const deleted = await this.deleteAccountType(slug);
1109
+ if (!deleted) {
1110
+ return new Response('Account type not found', { status: 404 });
1111
+ }
1112
+ return Response.json({ success: true });
1113
+ }
1114
+ catch (error) {
1115
+ // Built-in account types can't be deleted without force
1116
+ const message = error instanceof Error ? error.message : 'Unknown error';
1117
+ return Response.json({ error: message }, { status: 400 });
1118
+ }
1119
+ }
1120
+ // GET /providers/:slug/actions - list all actions for a provider
1121
+ const actionsListMatch = path.match(/^\/providers\/([^/]+)\/actions$/);
1122
+ if (method === 'GET' && actionsListMatch) {
1123
+ const slug = actionsListMatch[1];
1124
+ const actions = await this.getActions(slug);
1125
+ return Response.json(actions);
1126
+ }
1127
+ // GET /providers/:slug/actions/:action - get single action
1128
+ const actionMatch = path.match(/^\/providers\/([^/]+)\/actions\/([^/]+)$/);
1129
+ if (method === 'GET' && actionMatch) {
1130
+ const slug = actionMatch[1];
1131
+ const actionName = actionMatch[2];
1132
+ const action = await this.getAction(slug, actionName);
1133
+ if (!action) {
1134
+ return new Response('Action not found', { status: 404 });
1135
+ }
1136
+ return Response.json(action);
1137
+ }
1138
+ // POST /providers/:slug/actions/:action/validate - validate action input
1139
+ const validateMatch = path.match(/^\/providers\/([^/]+)\/actions\/([^/]+)\/validate$/);
1140
+ if (method === 'POST' && validateMatch) {
1141
+ const slug = validateMatch[1];
1142
+ const actionName = validateMatch[2];
1143
+ const body = (await request.json());
1144
+ const validation = await this.validateActionInput(slug, actionName, body);
1145
+ return Response.json(validation);
1146
+ }
1147
+ // POST /providers/:slug/actions/:action/execute - execute action via SDK
1148
+ const executeMatch = path.match(/^\/providers\/([^/]+)\/actions\/([^/]+)\/execute$/);
1149
+ if (method === 'POST' && executeMatch) {
1150
+ const slug = executeMatch[1];
1151
+ const actionName = executeMatch[2];
1152
+ const body = (await request.json());
1153
+ const sdk = await this.createSDK(slug, body.linkedAccountId);
1154
+ const actionFn = sdk[actionName];
1155
+ if (!actionFn) {
1156
+ return new Response('Action not found', { status: 404 });
1157
+ }
1158
+ const result = await actionFn(body.params);
1159
+ return Response.json(result);
1160
+ }
1161
+ // Health check
1162
+ if (path === '/health') {
1163
+ return Response.json({ status: 'ok', ns: this.ns });
1164
+ }
1165
+ return new Response('Not Found', { status: 404 });
1166
+ }
1167
+ catch (error) {
1168
+ const message = error instanceof Error ? error.message : 'Unknown error';
1169
+ return Response.json({ error: message }, { status: 400 });
1170
+ }
1171
+ }
1172
+ }
1173
+ export default IntegrationsDO;
1174
+ //# sourceMappingURL=IntegrationsDO.js.map