@zackbart/connecta 0.34.1 → 0.36.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 (441) hide show
  1. package/CHANGELOG.md +418 -0
  2. package/README.md +65 -105
  3. package/SECURITY.md +3 -2
  4. package/bin/connecta.mjs +41 -16
  5. package/bin/version.mjs +1 -1
  6. package/dist/access-tokens.d.ts +2 -1
  7. package/dist/access-tokens.js +66 -30
  8. package/dist/activity.d.ts +1 -1
  9. package/dist/activity.js +2 -0
  10. package/dist/agent-config.d.ts +23 -0
  11. package/dist/agent-config.js +59 -0
  12. package/dist/agent-description.js +16 -0
  13. package/dist/agent-identity.js +4 -4
  14. package/dist/agent-observation.js +39 -0
  15. package/dist/auth/clerk-sdk/client.d.ts +2 -0
  16. package/dist/auth/clerk-sdk/generated.js +554 -563
  17. package/dist/auth/clerk-transport.js +70 -3
  18. package/dist/auth/clerk.d.ts +13 -0
  19. package/dist/auth/clerk.js +653 -246
  20. package/dist/auth/cloudflare-access.js +46 -42
  21. package/dist/auth/downstream-client-metadata.js +2 -2
  22. package/dist/auth/downstream-oauth.js +2044 -1161
  23. package/dist/auth/downstream-revocation.js +88 -88
  24. package/dist/auth/native-call.js +20 -0
  25. package/dist/auth/native.js +184 -0
  26. package/dist/auth/oauth-start-reset.js +11 -5
  27. package/dist/auth/oauth-token-response.js +121 -102
  28. package/dist/auth/oauth-v2-migration.js +97 -78
  29. package/dist/auth/renewable-grant.js +10 -0
  30. package/dist/auth/static-oauth.js +751 -281
  31. package/dist/auth/vercel-agent.js +266 -0
  32. package/dist/auth-admission.js +204 -0
  33. package/dist/auth-elicitation.js +350 -241
  34. package/dist/authorization-handoff.js +164 -90
  35. package/dist/call-admission-context.js +3 -10
  36. package/dist/call-admission.js +2 -0
  37. package/dist/call-classification.js +9 -0
  38. package/dist/call-recovery.js +32 -13
  39. package/dist/canonical-json.js +8 -0
  40. package/dist/catalog-cache.js +369 -213
  41. package/dist/catalog-service.js +659 -530
  42. package/dist/catalog.js +5 -1
  43. package/dist/concurrency.js +0 -25
  44. package/dist/config-defaults.d.ts +1 -0
  45. package/dist/config-defaults.js +1 -0
  46. package/dist/config-schema.d.ts +3 -1
  47. package/dist/config-schema.js +13 -3
  48. package/dist/config.d.ts +40 -6
  49. package/dist/config.js +40 -26
  50. package/dist/connector-caller.d.ts +4 -0
  51. package/dist/connector-caller.js +17 -4
  52. package/dist/connectors/api-connector.d.ts +29 -7
  53. package/dist/connectors/api-connector.js +145 -57
  54. package/dist/connectors/guarded-fetch.d.ts +51 -17
  55. package/dist/connectors/guarded-fetch.js +215 -121
  56. package/dist/connectors/negotiation-cache.js +20 -10
  57. package/dist/connectors/remote-mcp.d.ts +10 -30
  58. package/dist/connectors/remote-mcp.js +955 -563
  59. package/dist/d1.js +10 -243
  60. package/dist/derived-context.js +5 -0
  61. package/dist/describe-config.d.ts +3 -1
  62. package/dist/describe-config.js +2 -0
  63. package/dist/downstream-input.js +347 -260
  64. package/dist/errors.d.ts +87 -6
  65. package/dist/errors.js +114 -4
  66. package/dist/execute.js +87 -50
  67. package/dist/executor-admission.js +3 -0
  68. package/dist/executors/quickjs.js +163 -112
  69. package/dist/guarded-transport.js +50 -0
  70. package/dist/guest-runtime.js +1 -1
  71. package/dist/http/client.js +439 -0
  72. package/dist/http/errors.js +558 -0
  73. package/dist/http/fields.js +49 -0
  74. package/dist/http/hatch-paging.js +318 -0
  75. package/dist/http/hatch.js +1279 -0
  76. package/dist/http/json-schema.js +267 -0
  77. package/dist/http/node-transport.js +241 -0
  78. package/dist/http/oauth.js +162 -0
  79. package/dist/http/paging.js +227 -0
  80. package/dist/http/provider.js +221 -0
  81. package/dist/http/safety.js +82 -0
  82. package/dist/http/services.js +79 -0
  83. package/dist/http/tools.js +379 -0
  84. package/dist/http/vendor-index.js +138 -0
  85. package/dist/http/vendor.js +448 -0
  86. package/dist/http/write-request.js +66 -0
  87. package/dist/http-policy.d.ts +11 -0
  88. package/dist/http-policy.js +45 -0
  89. package/dist/inbound-credential.js +1 -1
  90. package/dist/index.d.ts +2 -2
  91. package/dist/index.js +4 -0
  92. package/dist/invocation-auth.js +30 -19
  93. package/dist/invocation.js +218 -85
  94. package/dist/mcp-result.js +0 -4
  95. package/dist/membership.d.ts +4 -0
  96. package/dist/meta-output.js +1 -1
  97. package/dist/meta-tools.js +531 -406
  98. package/dist/native-recovery.js +52 -0
  99. package/dist/native-tools.js +382 -0
  100. package/dist/node.d.ts +4 -3
  101. package/dist/node.js +45 -8
  102. package/dist/oauth-handoff.js +177 -104
  103. package/dist/oauth-partition.js +6 -20
  104. package/dist/oauth-sealing.js +6 -7
  105. package/dist/operation-vocabulary.js +101 -0
  106. package/dist/operator-record.d.ts +2 -2
  107. package/dist/operator-record.js +17 -4
  108. package/dist/operator-ui/contract.d.ts +8 -3
  109. package/dist/operator-ui/generated.js +4 -4
  110. package/dist/operator-ui/model.d.ts +2 -3
  111. package/dist/program-writes.js +47 -26
  112. package/dist/provider-call-facts.d.ts +115 -0
  113. package/dist/provider-call-facts.js +182 -0
  114. package/dist/provider-call.d.ts +112 -0
  115. package/dist/provider-call.js +271 -0
  116. package/dist/provider.d.ts +65 -31
  117. package/dist/provider.js +116 -39
  118. package/dist/providers/_shared/google/hatch.js +91 -0
  119. package/dist/providers/_shared/google/kit.js +427 -0
  120. package/dist/providers/_shared/google/result-size.js +15 -2
  121. package/dist/providers/_shared/google/service-account.d.ts +2 -1
  122. package/dist/providers/_shared/google/service-account.js +8 -4
  123. package/dist/providers/_shared/google/workspace.d.ts +6 -210
  124. package/dist/providers/_shared/google/workspace.js +6 -425
  125. package/dist/providers/_shared/rest/compact-index.js +86 -0
  126. package/dist/providers/_shared/rest/kit.js +146 -0
  127. package/dist/providers/_shared/rest/operation-index.js +230 -14
  128. package/dist/providers/_shared/rest/response-media.js +11 -0
  129. package/dist/providers/_shared/rest/value-safety.js +353 -195
  130. package/dist/providers/_shared/sensitive-fields.js +27 -0
  131. package/dist/providers/breeze/api.js +584 -0
  132. package/dist/providers/breeze/index.d.ts +1 -3
  133. package/dist/providers/breeze/index.js +67 -1420
  134. package/dist/providers/breeze/openapi.generated.js +60 -0
  135. package/dist/providers/breeze/skill.generated.js +2 -6
  136. package/dist/providers/breeze/tools.js +696 -0
  137. package/dist/providers/ccb/api.js +496 -0
  138. package/dist/providers/ccb/index.d.ts +15 -37
  139. package/dist/providers/ccb/index.js +77 -1702
  140. package/dist/providers/ccb/lib/constants.d.ts +34 -0
  141. package/dist/providers/ccb/lib/constants.js +74 -0
  142. package/dist/providers/ccb/lib/guide.js +9 -0
  143. package/dist/providers/ccb/lib/verdicts.js +387 -0
  144. package/dist/providers/ccb/openapi.generated.js +397 -0
  145. package/dist/providers/ccb/safety.js +295 -0
  146. package/dist/providers/ccb/skill.generated.js +2 -6
  147. package/dist/providers/ccb/tools.js +853 -0
  148. package/dist/providers/cloudflare/api.js +1066 -0
  149. package/dist/providers/cloudflare/index.d.ts +5 -22
  150. package/dist/providers/cloudflare/index.js +79 -197
  151. package/dist/providers/cloudflare/lib/config.d.ts +16 -0
  152. package/dist/providers/cloudflare/lib/config.js +2 -0
  153. package/dist/providers/cloudflare/lib/discovery.js +29 -0
  154. package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
  155. package/dist/providers/cloudflare/lib/hatch.js +103 -0
  156. package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
  157. package/dist/providers/cloudflare/lib/response-media.js +75 -0
  158. package/dist/providers/cloudflare/openapi.generated.js +4 -3
  159. package/dist/providers/cloudflare/{value-safety.js → safety.js} +487 -0
  160. package/dist/providers/cloudflare/skill.generated.js +2 -10
  161. package/dist/providers/cloudflare/tools.js +360 -0
  162. package/dist/providers/docs/api.js +51 -0
  163. package/dist/providers/docs/index.d.ts +1 -12
  164. package/dist/providers/docs/index.js +53 -1165
  165. package/dist/providers/docs/lib/constants.d.ts +18 -0
  166. package/dist/providers/docs/lib/constants.js +18 -0
  167. package/dist/providers/docs/lib/discovery.js +26 -0
  168. package/dist/providers/docs/lib/requests.js +48 -0
  169. package/dist/providers/docs/lib/schemas.js +168 -0
  170. package/dist/providers/docs/openapi.generated.js +16 -0
  171. package/dist/providers/docs/safety.js +54 -0
  172. package/dist/providers/docs/skill.generated.js +2 -6
  173. package/dist/providers/docs/tools.js +801 -0
  174. package/dist/providers/drive/api.js +177 -0
  175. package/dist/providers/drive/index.d.ts +1 -12
  176. package/dist/providers/drive/index.js +38 -1448
  177. package/dist/providers/drive/lib/constants.d.ts +6 -0
  178. package/dist/providers/drive/lib/constants.js +6 -0
  179. package/dist/providers/drive/lib/contracts.js +532 -0
  180. package/dist/providers/drive/lib/hatch.js +197 -0
  181. package/dist/providers/drive/openapi.generated.js +77 -0
  182. package/dist/providers/drive/safety.js +90 -0
  183. package/dist/providers/drive/skill.generated.js +2 -6
  184. package/dist/providers/drive/tools.js +1290 -0
  185. package/dist/providers/forms/api.js +71 -0
  186. package/dist/providers/forms/index.d.ts +1 -12
  187. package/dist/providers/forms/index.js +49 -1145
  188. package/dist/providers/forms/lib/constants.d.ts +14 -0
  189. package/dist/providers/forms/lib/constants.js +19 -0
  190. package/dist/providers/forms/lib/hatch.js +72 -0
  191. package/dist/providers/forms/openapi.generated.js +23 -0
  192. package/dist/providers/forms/safety.js +34 -0
  193. package/dist/providers/forms/skill.generated.js +2 -8
  194. package/dist/providers/forms/tools.js +1023 -0
  195. package/dist/providers/github/api.js +150 -0
  196. package/dist/providers/github/index.d.ts +4 -5
  197. package/dist/providers/github/index.js +30 -87
  198. package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
  199. package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
  200. package/dist/providers/github/lib/discovery.js +132 -0
  201. package/dist/providers/github/lib/operations.js +58 -0
  202. package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
  203. package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
  204. package/dist/providers/github/openapi.generated.js +1216 -0
  205. package/dist/providers/github/safety.js +216 -0
  206. package/dist/providers/github/skill.generated.js +2 -5
  207. package/dist/providers/github/tools.js +506 -0
  208. package/dist/providers/gmail/api.js +114 -0
  209. package/dist/providers/gmail/index.d.ts +1 -12
  210. package/dist/providers/gmail/index.js +73 -1621
  211. package/dist/providers/gmail/lib/constants.d.ts +13 -0
  212. package/dist/providers/gmail/lib/constants.js +16 -0
  213. package/dist/providers/gmail/lib/index.js +173 -0
  214. package/dist/providers/gmail/lib/schemas.js +176 -0
  215. package/dist/providers/gmail/lib/threading.js +120 -0
  216. package/dist/providers/gmail/openapi.generated.js +92 -0
  217. package/dist/providers/gmail/safety.js +21 -0
  218. package/dist/providers/gmail/skill.generated.js +2 -6
  219. package/dist/providers/gmail/tools.js +1435 -0
  220. package/dist/providers/overflow/api.js +1008 -0
  221. package/dist/providers/overflow/index.d.ts +1 -17
  222. package/dist/providers/overflow/index.js +60 -1488
  223. package/dist/providers/overflow/skill.generated.js +2 -5
  224. package/dist/providers/overflow/tools.js +873 -0
  225. package/dist/providers/planning-center/api.js +467 -0
  226. package/dist/providers/planning-center/index.d.ts +4 -35
  227. package/dist/providers/planning-center/index.js +69 -2445
  228. package/dist/providers/planning-center/lib/constants.d.ts +58 -0
  229. package/dist/providers/planning-center/lib/constants.js +83 -0
  230. package/dist/providers/planning-center/lib/discovery.js +40 -0
  231. package/dist/providers/planning-center/lib/guide.js +39 -0
  232. package/dist/providers/planning-center/lib/json-api.js +83 -0
  233. package/dist/providers/planning-center/lib/verdicts.js +1758 -0
  234. package/dist/providers/planning-center/openapi.generated.js +1764 -0
  235. package/dist/providers/planning-center/safety.js +188 -0
  236. package/dist/providers/planning-center/skill.generated.js +2 -27
  237. package/dist/providers/planning-center/tools.js +1010 -0
  238. package/dist/providers/quickbooks/api.js +299 -0
  239. package/dist/providers/quickbooks/index.d.ts +13 -0
  240. package/dist/providers/quickbooks/index.js +93 -0
  241. package/dist/providers/quickbooks/lib/query.js +118 -0
  242. package/dist/providers/quickbooks/lib/writes.js +168 -0
  243. package/dist/providers/quickbooks/safety.js +222 -0
  244. package/dist/providers/quickbooks/skill.generated.js +5 -0
  245. package/dist/providers/quickbooks/tools.js +117 -0
  246. package/dist/providers/sheets/api.js +133 -0
  247. package/dist/providers/sheets/index.d.ts +4 -16
  248. package/dist/providers/sheets/index.js +61 -1172
  249. package/dist/providers/sheets/lib/constants.d.ts +14 -0
  250. package/dist/providers/sheets/lib/constants.js +14 -0
  251. package/dist/providers/sheets/lib/hatch.js +163 -0
  252. package/dist/providers/sheets/lib/requests.js +105 -0
  253. package/dist/providers/sheets/lib/schemas.js +138 -0
  254. package/dist/providers/sheets/openapi.generated.js +30 -0
  255. package/dist/providers/sheets/safety.js +27 -0
  256. package/dist/providers/sheets/skill.generated.js +2 -7
  257. package/dist/providers/sheets/tools.js +733 -0
  258. package/dist/providers/slides/api.js +147 -0
  259. package/dist/providers/slides/index.d.ts +2 -10
  260. package/dist/providers/slides/index.js +48 -2555
  261. package/dist/providers/slides/lib/constants.d.ts +11 -0
  262. package/dist/providers/slides/lib/constants.js +11 -0
  263. package/dist/providers/slides/lib/requests.js +60 -0
  264. package/dist/providers/slides/lib/schemas.js +565 -0
  265. package/dist/providers/slides/openapi.generated.js +18 -0
  266. package/dist/providers/slides/skill.generated.js +2 -6
  267. package/dist/providers/slides/tools.js +1968 -0
  268. package/dist/providers/stripe/api.js +401 -0
  269. package/dist/providers/stripe/index.d.ts +5 -27
  270. package/dist/providers/stripe/index.js +74 -210
  271. package/dist/providers/stripe/lib/config.d.ts +4 -0
  272. package/dist/providers/stripe/lib/config.js +2 -0
  273. package/dist/providers/stripe/openapi.generated.js +4 -3
  274. package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
  275. package/dist/providers/stripe/skill.generated.js +2 -11
  276. package/dist/providers/stripe/tools.js +77 -0
  277. package/dist/providers/tithely/api.js +531 -0
  278. package/dist/providers/tithely/index.d.ts +17 -0
  279. package/dist/providers/tithely/index.js +86 -965
  280. package/dist/providers/tithely/skill.generated.js +2 -5
  281. package/dist/providers/tithely/tools.js +426 -0
  282. package/dist/providers/vercel/api.js +551 -0
  283. package/dist/providers/vercel/index.d.ts +9 -25
  284. package/dist/providers/vercel/index.js +65 -260
  285. package/dist/providers/vercel/lib/config.d.ts +2 -0
  286. package/dist/providers/vercel/lib/config.js +2 -0
  287. package/dist/providers/vercel/lib/index.js +117 -0
  288. package/dist/providers/vercel/lib/logs.js +100 -0
  289. package/dist/providers/vercel/lib/pin.js +270 -0
  290. package/dist/providers/vercel/openapi.generated.js +10 -5
  291. package/dist/providers/vercel/{value-safety.js → safety.js} +247 -38
  292. package/dist/providers/vercel/skill.generated.js +2 -7
  293. package/dist/providers/vercel/tools.js +642 -0
  294. package/dist/redaction-identity.js +47 -0
  295. package/dist/redaction-marker.js +125 -0
  296. package/dist/registry.d.ts +21 -15
  297. package/dist/registry.js +409 -376
  298. package/dist/routes/access-tokens.js +1 -1
  299. package/dist/routes/actor-labels.js +1 -1
  300. package/dist/routes/connect.js +1 -1
  301. package/dist/routes/dispatch.js +103 -0
  302. package/dist/routes/mcp.js +170 -79
  303. package/dist/routes/oauth.js +6 -1
  304. package/dist/routes/operator.js +2 -2
  305. package/dist/routes/shared.d.ts +5 -4
  306. package/dist/routes/shared.js +244 -177
  307. package/dist/routes/skills.js +10 -8
  308. package/dist/routes/ui-config.js +27 -3
  309. package/dist/routes/ui-data.js +21 -20
  310. package/dist/routes/ui.js +1 -1
  311. package/dist/runtime/call-admission.js +0 -26
  312. package/dist/runtime/call-entry.js +30 -0
  313. package/dist/runtime/call.js +552 -0
  314. package/dist/runtime/connector-scope.js +7 -0
  315. package/dist/runtime/credential-probe.js +34 -0
  316. package/dist/runtime/executor.js +40 -0
  317. package/dist/runtime/native-storage.js +63 -0
  318. package/dist/runtime/registry.js +27 -0
  319. package/dist/runtime/request-scope.js +72 -0
  320. package/dist/runtime/run.js +15 -7
  321. package/dist/runtime/shared-read.js +34 -5
  322. package/dist/runtime/storage.js +34 -21
  323. package/dist/sent-secrets.d.ts +194 -37
  324. package/dist/sent-secrets.js +1743 -340
  325. package/dist/server.js +5 -56
  326. package/dist/skills.js +322 -223
  327. package/dist/sqlite.js +15 -14
  328. package/dist/storage/d1-copy.js +255 -0
  329. package/dist/storage/d1-driver.js +15 -0
  330. package/dist/storage/keys.js +28 -0
  331. package/dist/storage/sql-driver.js +88 -0
  332. package/dist/storage/sql-native.js +544 -0
  333. package/dist/storage/sql-schema.d.ts +6 -0
  334. package/dist/storage/sql-schema.js +15 -0
  335. package/dist/storage/sql.d.ts +14 -20
  336. package/dist/storage/sql.js +29 -535
  337. package/dist/timeout.js +0 -26
  338. package/dist/tool-safety.js +20 -10
  339. package/dist/types.d.ts +9 -109
  340. package/dist/ui.d.ts +1 -1
  341. package/dist/ui.js +0 -1
  342. package/dist/upward.js +3 -0
  343. package/dist/usage-guide.js +3 -1
  344. package/dist/validate.d.ts +4 -2
  345. package/dist/validate.js +86 -9
  346. package/dist/version.d.ts +1 -1
  347. package/dist/version.js +1 -1
  348. package/dist/worker.js +312 -292
  349. package/dist/workspace-subject.js +5 -1
  350. package/dist/write-outcome.js +454 -34
  351. package/documentation/README.md +28 -7
  352. package/documentation/architecture.md +2409 -255
  353. package/documentation/auth.md +867 -114
  354. package/documentation/code-mode.md +49 -16
  355. package/documentation/deploying.md +164 -20
  356. package/documentation/hosted-mcp-migration.md +460 -0
  357. package/documentation/integrating.md +129 -144
  358. package/documentation/meta-tools.md +409 -32
  359. package/documentation/operating.md +27 -3
  360. package/documentation/operator-tests.md +3 -0
  361. package/documentation/operator-ui.md +84 -48
  362. package/documentation/provider-auth-migration.md +16 -63
  363. package/documentation/provider-migration-0.29.md +10 -5
  364. package/documentation/provider-migration-0.35.md +975 -0
  365. package/documentation/providers.md +1347 -0
  366. package/examples/worker/AGENTS.md +23 -9
  367. package/examples/worker/README.md +254 -135
  368. package/examples/worker/alchemy.run.ts +116 -0
  369. package/examples/worker/gitignore +10 -0
  370. package/examples/worker/src/connecta.config.ts +23 -21
  371. package/examples/worker/wrangler.jsonc +14 -5
  372. package/guides/connecting-agents.md +157 -0
  373. package/guides/how-it-works.md +156 -0
  374. package/guides/safety-and-trust.md +153 -0
  375. package/package.json +30 -50
  376. package/templates/node/.env.example +3 -0
  377. package/templates/node/README.md +22 -2
  378. package/templates/node/docker-compose.yml +1 -0
  379. package/templates/node/package.json +3 -2
  380. package/templates/node/src/connecta.config.ts +8 -0
  381. package/dist/catalog-drift.d.ts +0 -138
  382. package/dist/catalog-drift.js +0 -578
  383. package/dist/operator-ui/agents.d.ts +0 -74
  384. package/dist/operator-ui/agents.js +0 -104
  385. package/dist/operator-ui/config-summary.js +0 -565
  386. package/dist/operator-ui/connection-map.js +0 -376
  387. package/dist/operator-ui/endpoints.js +0 -221
  388. package/dist/operator-ui/fix-prompts.d.ts +0 -18
  389. package/dist/operator-ui/fix-prompts.js +0 -87
  390. package/dist/operator-ui/health.js +0 -52
  391. package/dist/operator-ui/member-page.js +0 -97
  392. package/dist/operator-ui/overview.js +0 -123
  393. package/dist/operator-ui/setup-commands.js +0 -51
  394. package/dist/operator-ui/view.d.ts +0 -401
  395. package/dist/operator-ui/view.js +0 -705
  396. package/dist/providers/_shared/request-token.js +0 -83
  397. package/dist/providers/_shared/rest/dispatch.js +0 -41
  398. package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
  399. package/dist/providers/_shared/rest/tools.d.ts +0 -141
  400. package/dist/providers/_shared/rest/tools.js +0 -569
  401. package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
  402. package/dist/providers/basecamp/index.d.ts +0 -45
  403. package/dist/providers/basecamp/index.js +0 -997
  404. package/dist/providers/basecamp/skill.generated.js +0 -9
  405. package/dist/providers/cloudflare/rest.d.ts +0 -37
  406. package/dist/providers/cloudflare/rest.js +0 -1097
  407. package/dist/providers/github/hosted.js +0 -218
  408. package/dist/providers/github/rest.js +0 -321
  409. package/dist/providers/infisical/index.d.ts +0 -7
  410. package/dist/providers/infisical/index.js +0 -713
  411. package/dist/providers/infisical/skill.generated.js +0 -8
  412. package/dist/providers/intercom/index.d.ts +0 -24
  413. package/dist/providers/intercom/index.js +0 -121
  414. package/dist/providers/intercom/skill.generated.js +0 -8
  415. package/dist/providers/linear/index.d.ts +0 -55
  416. package/dist/providers/linear/index.js +0 -537
  417. package/dist/providers/linear/skill.generated.js +0 -8
  418. package/dist/providers/mixpanel/index.d.ts +0 -59
  419. package/dist/providers/mixpanel/index.js +0 -472
  420. package/dist/providers/mixpanel/operations.js +0 -20
  421. package/dist/providers/mixpanel/rest.js +0 -603
  422. package/dist/providers/mixpanel/skill.generated.js +0 -10
  423. package/dist/providers/mixpanel/value-safety.js +0 -16
  424. package/dist/providers/notion/index.d.ts +0 -67
  425. package/dist/providers/notion/index.js +0 -368
  426. package/dist/providers/notion/openapi.generated.js +0 -75
  427. package/dist/providers/notion/rest.d.ts +0 -24
  428. package/dist/providers/notion/rest.js +0 -1226
  429. package/dist/providers/notion/skill.generated.js +0 -11
  430. package/dist/providers/notion/value-safety.js +0 -56
  431. package/dist/providers/revenuecat/index.d.ts +0 -51
  432. package/dist/providers/revenuecat/index.js +0 -697
  433. package/dist/providers/revenuecat/skill.generated.js +0 -11
  434. package/dist/providers/stripe/rest.d.ts +0 -14
  435. package/dist/providers/stripe/rest.js +0 -402
  436. package/dist/providers/vercel/rest.d.ts +0 -20
  437. package/dist/providers/vercel/rest.js +0 -1020
  438. package/dist/providers/wispr-flow/index.d.ts +0 -14
  439. package/dist/providers/wispr-flow/index.js +0 -117
  440. package/dist/providers/wispr-flow/skill.generated.js +0 -8
  441. /package/dist/providers/github/{key.js → lib/key.js} +0 -0
@@ -0,0 +1,853 @@
1
+ // CCB v2 curated projections, bound numbered pages and reviewed POST data search.
2
+ import { Effect, Schema } from "effect";
3
+ import { ConnectorCallError } from "../../errors.js";
4
+ import { checked } from "../_shared/rest/kit.js";
5
+ import { refuseWithheldValues } from "../_shared/rest/value-safety.js";
6
+ import { Refusal } from "../../http/errors.js";
7
+ import { Integer, isMinChars, isMaxChars } from "../../http/json-schema.js";
8
+ import { read, list } from "../../http/tools.js";
9
+ import { callCcb, DEFAULT_PER_PAGE, SEARCH_DOMAINS, CCB_INDEX, ccbPageInfo, } from "./api.js";
10
+ function asRecord(value) {
11
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
12
+ }
13
+ function asArray(value) {
14
+ return Array.isArray(value) ? value : [];
15
+ }
16
+ function compact(value) {
17
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined && entry !== null));
18
+ }
19
+ /** An object that is empty after compaction reads as absent. */
20
+ function present(value) {
21
+ return Object.keys(value).length > 0 ? value : undefined;
22
+ }
23
+ function phones(value) {
24
+ const phone = asRecord(value);
25
+ return present(compact({
26
+ mobile: phone["mobile"] || undefined,
27
+ home: phone["home"] || undefined,
28
+ work: phone["work"] || undefined,
29
+ }));
30
+ }
31
+ function address(value) {
32
+ const row = asRecord(value);
33
+ return present(compact({
34
+ street: row["street"] || undefined,
35
+ city: row["city"] || undefined,
36
+ state: row["state"] || undefined,
37
+ zip: row["zip"] || undefined,
38
+ country: row["country_iso"] || undefined,
39
+ }));
40
+ }
41
+ function projectPerson(value) {
42
+ const row = asRecord(value);
43
+ return compact({
44
+ id: row["id"],
45
+ name: row["name"],
46
+ firstName: row["first_name"],
47
+ lastName: row["last_name"],
48
+ email: row["email"] || undefined,
49
+ phones: phones(row["phone"]),
50
+ birthday: row["birthday"],
51
+ familyId: row["family_id"],
52
+ familyPosition: row["family_position"],
53
+ campusId: row["campus_id"],
54
+ membershipTypeId: row["membership_type_id"],
55
+ active: row["active"],
56
+ deceased: row["deceased"],
57
+ });
58
+ }
59
+ function projectIndividual(value) {
60
+ const row = asRecord(value);
61
+ const addresses = asRecord(row["addresses"]);
62
+ return compact({
63
+ ...projectPerson(row),
64
+ gender: row["gender"],
65
+ maritalStatus: row["marital_status"],
66
+ homeAddress: address(addresses["home"]),
67
+ mailingAddress: address(addresses["mailing"]),
68
+ campusName: row["campus_name"],
69
+ membershipTypeName: row["membership_type_name"],
70
+ membershipDate: row["membership_date"],
71
+ schoolGrade: row["school_grade"],
72
+ baptized: row["baptized"],
73
+ baptizedDate: row["baptized_date"],
74
+ lastAttendedDate: row["last_attended_date"],
75
+ limitedAccessUser: row["limited_access_user"],
76
+ listed: row["listed"],
77
+ created: row["created"],
78
+ modified: row["modified"],
79
+ customFields: present(Object.fromEntries(asArray(row["custom_fields"])
80
+ .map(asRecord)
81
+ .filter((field) => field["id"] !== undefined)
82
+ .map((field) => [String(field["id"]), field["value"]]))),
83
+ });
84
+ }
85
+ function projectFamily(value) {
86
+ const row = asRecord(value);
87
+ return compact({
88
+ id: row["id"],
89
+ lastName: row["last_name"],
90
+ address: address(row["address"]),
91
+ members: Array.isArray(row["members"]) ? row["members"].map(projectPerson) : undefined,
92
+ });
93
+ }
94
+ function ref(value) {
95
+ const row = asRecord(value);
96
+ return row["id"] === undefined && row["name"] === undefined
97
+ ? undefined
98
+ : compact({ id: row["id"], name: row["name"] });
99
+ }
100
+ function projectGroup(value) {
101
+ const row = asRecord(value);
102
+ return compact({
103
+ id: row["id"],
104
+ name: row["name"],
105
+ campusId: row["campus_id"],
106
+ inactive: row["inactive"],
107
+ groupType: asRecord(row["group_type"])["name"],
108
+ interactionType: row["interaction_type"],
109
+ membershipType: row["membership_type"],
110
+ mainLeader: ref(row["main_leader"]),
111
+ departmentId: asRecord(row["department"])["id"],
112
+ description: row["description"],
113
+ memberCount: row["member_count"],
114
+ childcare: row["childcare"],
115
+ listed: row["listed"],
116
+ full: row["full"],
117
+ meetDay: asRecord(row["meet_day"])["name"],
118
+ meetTime: asRecord(row["meet_time"])["name"],
119
+ area: asRecord(row["area"])["name"],
120
+ address: address(row["address"]),
121
+ });
122
+ }
123
+ function projectMembership(value) {
124
+ const row = asRecord(value);
125
+ const person = asRecord(row["individual"]);
126
+ const group = asRecord(row["group"]);
127
+ return compact({
128
+ groupId: row["group_id"],
129
+ individualId: row["individual_id"],
130
+ status: row["status"],
131
+ dateAdded: row["date_added"],
132
+ name: person["name"],
133
+ email: person["email"] || undefined,
134
+ phones: phones(person["phone"]),
135
+ groupName: group["name"],
136
+ groupType: asRecord(group["group_type"])["name"],
137
+ groupInactive: group["inactive"],
138
+ });
139
+ }
140
+ function projectOccurrence(value) {
141
+ const row = asRecord(value);
142
+ const event = asRecord(row["event"]);
143
+ const group = asRecord(event["group"]);
144
+ return compact({
145
+ eventId: row["event_id"] ?? event["id"],
146
+ occurrence: row["occurrence"],
147
+ start: row["start"],
148
+ end: row["end"],
149
+ name: event["name"],
150
+ campusId: event["campus_id"],
151
+ recurs: event["recurs"],
152
+ groupId: group["id"] === undefined ? undefined : Number(group["id"]),
153
+ groupName: group["name"],
154
+ });
155
+ }
156
+ function projectEvent(value) {
157
+ const row = asRecord(value);
158
+ const attendance = asRecord(row["attendance"]);
159
+ return compact({
160
+ id: row["id"],
161
+ name: row["name"],
162
+ description: row["description"],
163
+ campusId: row["campus_id"],
164
+ start: row["start"],
165
+ end: row["end"],
166
+ recurs: row["recurs"],
167
+ recurEndDate: row["recur_end_date"],
168
+ approvalStatus: row["approval_status"],
169
+ address: address(row["address"]),
170
+ guestCounts: present(compact({ ...asRecord(row["guest_counts"]) })),
171
+ group: ref(row["group"]),
172
+ attendance: present(compact({
173
+ status: attendance["status"],
174
+ totalAttendance: attendance["total_attendance"],
175
+ visitors: attendance["visitors"],
176
+ })),
177
+ });
178
+ }
179
+ function projectAttendance(value) {
180
+ const row = asRecord(value);
181
+ return compact({
182
+ eventId: row["event_id"],
183
+ occurrence: row["occurrence"],
184
+ status: row["status"],
185
+ totalAttendance: row["total_attendance"],
186
+ visitors: row["visitors"],
187
+ topic: row["topic"],
188
+ });
189
+ }
190
+ function projectAttendee(value) {
191
+ const row = asRecord(value);
192
+ const person = asRecord(row["individual"]);
193
+ return compact({
194
+ individualId: row["individual_id"] ?? person["id"],
195
+ name: person["name"],
196
+ familyId: person["family_id"],
197
+ occurrenceDate: row["occurrence_date"],
198
+ });
199
+ }
200
+ function projectNote(value) {
201
+ const row = asRecord(value);
202
+ return compact({
203
+ id: row["id"],
204
+ individualId: row["individual_id"],
205
+ note: row["note"],
206
+ date: row["date"],
207
+ sharingLevel: row["sharing_level"],
208
+ context: row["context"],
209
+ contextId: row["context_id"],
210
+ creator: ref(row["creator"]),
211
+ });
212
+ }
213
+ const PERSON_SCHEMA = Schema.Struct({
214
+ "id": Schema.optionalKey(Integer),
215
+ "name": Schema.optionalKey(Schema.String),
216
+ "firstName": Schema.optionalKey(Schema.String),
217
+ "lastName": Schema.optionalKey(Schema.String),
218
+ "email": Schema.optionalKey(Schema.String),
219
+ "phones": Schema.optionalKey(Schema.Struct({
220
+ "mobile": Schema.optionalKey(Schema.String),
221
+ "home": Schema.optionalKey(Schema.String),
222
+ "work": Schema.optionalKey(Schema.String),
223
+ })),
224
+ "birthday": Schema.optionalKey(Schema.String),
225
+ "familyId": Schema.optionalKey(Integer),
226
+ "familyPosition": Schema.optionalKey(Schema.String),
227
+ "campusId": Schema.optionalKey(Integer),
228
+ "membershipTypeId": Schema.optionalKey(Integer),
229
+ "active": Schema.optionalKey(Schema.Boolean),
230
+ "deceased": Schema.optionalKey(Schema.String),
231
+ });
232
+ const INDIVIDUAL_SCHEMA = Schema.Struct({
233
+ "id": Schema.optionalKey(Integer),
234
+ "name": Schema.optionalKey(Schema.String),
235
+ "firstName": Schema.optionalKey(Schema.String),
236
+ "lastName": Schema.optionalKey(Schema.String),
237
+ "email": Schema.optionalKey(Schema.String),
238
+ "phones": Schema.optionalKey(Schema.Struct({
239
+ "mobile": Schema.optionalKey(Schema.String),
240
+ "home": Schema.optionalKey(Schema.String),
241
+ "work": Schema.optionalKey(Schema.String),
242
+ })),
243
+ "birthday": Schema.optionalKey(Schema.String),
244
+ "familyId": Schema.optionalKey(Integer),
245
+ "familyPosition": Schema.optionalKey(Schema.String),
246
+ "campusId": Schema.optionalKey(Integer),
247
+ "membershipTypeId": Schema.optionalKey(Integer),
248
+ "active": Schema.optionalKey(Schema.Boolean),
249
+ "deceased": Schema.optionalKey(Schema.String),
250
+ "gender": Schema.optionalKey(Schema.String),
251
+ "maritalStatus": Schema.optionalKey(Schema.String),
252
+ "homeAddress": Schema.optionalKey(Schema.Struct({
253
+ "street": Schema.optionalKey(Schema.String),
254
+ "city": Schema.optionalKey(Schema.String),
255
+ "state": Schema.optionalKey(Schema.String),
256
+ "zip": Schema.optionalKey(Schema.String),
257
+ "country": Schema.optionalKey(Schema.String),
258
+ })),
259
+ "mailingAddress": Schema.optionalKey(Schema.Struct({
260
+ "street": Schema.optionalKey(Schema.String),
261
+ "city": Schema.optionalKey(Schema.String),
262
+ "state": Schema.optionalKey(Schema.String),
263
+ "zip": Schema.optionalKey(Schema.String),
264
+ "country": Schema.optionalKey(Schema.String),
265
+ })),
266
+ "campusName": Schema.optionalKey(Schema.String),
267
+ "membershipTypeName": Schema.optionalKey(Schema.String),
268
+ "membershipDate": Schema.optionalKey(Schema.String),
269
+ "schoolGrade": Schema.optionalKey(Schema.String),
270
+ "baptized": Schema.optionalKey(Schema.Boolean),
271
+ "baptizedDate": Schema.optionalKey(Schema.String),
272
+ "lastAttendedDate": Schema.optionalKey(Schema.String),
273
+ "limitedAccessUser": Schema.optionalKey(Schema.Boolean),
274
+ "listed": Schema.optionalKey(Schema.Boolean),
275
+ "created": Schema.optionalKey(Schema.String),
276
+ "modified": Schema.optionalKey(Schema.String),
277
+ "customFields": Schema.optionalKey(Schema.Record(Schema.String, Schema.Unknown)),
278
+ });
279
+ const FAMILY_SCHEMA = Schema.Struct({
280
+ "id": Schema.optionalKey(Integer),
281
+ "lastName": Schema.optionalKey(Schema.String),
282
+ "address": Schema.optionalKey(Schema.Struct({
283
+ "street": Schema.optionalKey(Schema.String),
284
+ "city": Schema.optionalKey(Schema.String),
285
+ "state": Schema.optionalKey(Schema.String),
286
+ "zip": Schema.optionalKey(Schema.String),
287
+ "country": Schema.optionalKey(Schema.String),
288
+ })),
289
+ "members": Schema.optionalKey(Schema.Array(PERSON_SCHEMA)),
290
+ });
291
+ const GROUP_DETAIL_SCHEMA = Schema.Struct({
292
+ "id": Schema.optionalKey(Integer),
293
+ "name": Schema.optionalKey(Schema.String),
294
+ "campusId": Schema.optionalKey(Integer),
295
+ "inactive": Schema.optionalKey(Schema.Boolean),
296
+ "groupType": Schema.optionalKey(Schema.String),
297
+ "interactionType": Schema.optionalKey(Schema.String),
298
+ "membershipType": Schema.optionalKey(Schema.String),
299
+ "mainLeader": Schema.optionalKey(Schema.Struct({ "id": Schema.optionalKey(Integer), "name": Schema.optionalKey(Schema.String) })),
300
+ "departmentId": Schema.optionalKey(Integer),
301
+ "description": Schema.optionalKey(Schema.String),
302
+ "memberCount": Schema.optionalKey(Integer),
303
+ "childcare": Schema.optionalKey(Schema.Boolean),
304
+ "listed": Schema.optionalKey(Schema.Boolean),
305
+ "full": Schema.optionalKey(Schema.Boolean),
306
+ "meetDay": Schema.optionalKey(Schema.String),
307
+ "meetTime": Schema.optionalKey(Schema.String),
308
+ "area": Schema.optionalKey(Schema.String),
309
+ "address": Schema.optionalKey(Schema.Struct({
310
+ "street": Schema.optionalKey(Schema.String),
311
+ "city": Schema.optionalKey(Schema.String),
312
+ "state": Schema.optionalKey(Schema.String),
313
+ "zip": Schema.optionalKey(Schema.String),
314
+ "country": Schema.optionalKey(Schema.String),
315
+ })),
316
+ });
317
+ const MEMBERSHIP_SCHEMA = Schema.Struct({
318
+ "groupId": Schema.optionalKey(Integer),
319
+ "individualId": Schema.optionalKey(Integer),
320
+ "status": Schema.optionalKey(Schema.String),
321
+ "dateAdded": Schema.optionalKey(Schema.String),
322
+ "name": Schema.optionalKey(Schema.String),
323
+ "email": Schema.optionalKey(Schema.String),
324
+ "phones": Schema.optionalKey(Schema.Struct({
325
+ "mobile": Schema.optionalKey(Schema.String),
326
+ "home": Schema.optionalKey(Schema.String),
327
+ "work": Schema.optionalKey(Schema.String),
328
+ })),
329
+ "groupName": Schema.optionalKey(Schema.String),
330
+ "groupType": Schema.optionalKey(Schema.String),
331
+ "groupInactive": Schema.optionalKey(Schema.Boolean),
332
+ });
333
+ const OCCURRENCE_SCHEMA = Schema.Struct({
334
+ "eventId": Schema.optionalKey(Integer),
335
+ "occurrence": Schema.optionalKey(Schema.String),
336
+ "start": Schema.optionalKey(Schema.String),
337
+ "end": Schema.optionalKey(Schema.String),
338
+ "name": Schema.optionalKey(Schema.String),
339
+ "campusId": Schema.optionalKey(Integer),
340
+ "recurs": Schema.optionalKey(Schema.Boolean),
341
+ "groupId": Schema.optionalKey(Integer),
342
+ "groupName": Schema.optionalKey(Schema.String),
343
+ });
344
+ const EVENT_SCHEMA = Schema.Struct({
345
+ "id": Schema.optionalKey(Integer),
346
+ "name": Schema.optionalKey(Schema.String),
347
+ "description": Schema.optionalKey(Schema.String),
348
+ "campusId": Schema.optionalKey(Integer),
349
+ "start": Schema.optionalKey(Schema.String),
350
+ "end": Schema.optionalKey(Schema.String),
351
+ "recurs": Schema.optionalKey(Schema.Boolean),
352
+ "recurEndDate": Schema.optionalKey(Schema.String),
353
+ "approvalStatus": Schema.optionalKey(Schema.String),
354
+ "address": Schema.optionalKey(Schema.Struct({
355
+ "street": Schema.optionalKey(Schema.String),
356
+ "city": Schema.optionalKey(Schema.String),
357
+ "state": Schema.optionalKey(Schema.String),
358
+ "zip": Schema.optionalKey(Schema.String),
359
+ "country": Schema.optionalKey(Schema.String),
360
+ })),
361
+ "guestCounts": Schema.optionalKey(Schema.Record(Schema.String, Schema.Unknown)),
362
+ "group": Schema.optionalKey(Schema.Struct({ "id": Schema.optionalKey(Integer), "name": Schema.optionalKey(Schema.String) })),
363
+ "attendance": Schema.optionalKey(Schema.Struct({
364
+ "status": Schema.optionalKey(Schema.String),
365
+ "totalAttendance": Schema.optionalKey(Integer),
366
+ "visitors": Schema.optionalKey(Integer),
367
+ })),
368
+ });
369
+ const ATTENDANCE_SCHEMA = Schema.Struct({
370
+ "eventId": Schema.optionalKey(Integer),
371
+ "occurrence": Schema.optionalKey(Schema.String),
372
+ "status": Schema.optionalKey(Schema.String),
373
+ "totalAttendance": Schema.optionalKey(Integer),
374
+ "visitors": Schema.optionalKey(Integer),
375
+ "topic": Schema.optionalKey(Schema.String),
376
+ });
377
+ const ATTENDEE_SCHEMA = Schema.Struct({
378
+ "individualId": Schema.optionalKey(Integer),
379
+ "name": Schema.optionalKey(Schema.String),
380
+ "familyId": Schema.optionalKey(Integer),
381
+ "occurrenceDate": Schema.optionalKey(Schema.String),
382
+ });
383
+ const NOTE_SCHEMA = Schema.Struct({
384
+ "id": Schema.optionalKey(Integer),
385
+ "individualId": Schema.optionalKey(Integer),
386
+ "note": Schema.optionalKey(Schema.String),
387
+ "date": Schema.optionalKey(Schema.String),
388
+ "sharingLevel": Schema.optionalKey(Schema.String),
389
+ "context": Schema.optionalKey(Schema.String),
390
+ "contextId": Schema.optionalKey(Integer),
391
+ "creator": Schema.optionalKey(Schema.Struct({ "id": Schema.optionalKey(Integer), "name": Schema.optionalKey(Schema.String) })),
392
+ });
393
+ const ME_SCHEMA = Schema.Struct({
394
+ "id": Schema.optionalKey(Integer),
395
+ "name": Schema.optionalKey(Schema.String),
396
+ "email": Schema.optionalKey(Schema.String),
397
+ "username": Schema.optionalKey(Schema.String),
398
+ "familyId": Schema.optionalKey(Integer),
399
+ "campusId": Schema.optionalKey(Integer),
400
+ "userTypes": Schema.optionalKey(Schema.Array(Schema.String)),
401
+ });
402
+ function compactDate(value) {
403
+ return typeof value === "string" ? value.replace(/-/g, "") : undefined;
404
+ }
405
+ export function ccbTools({ connection, options, }) {
406
+ const limit = {
407
+ default: options.defaultPerPage ?? DEFAULT_PER_PAGE,
408
+ max: 100,
409
+ values: [25, 50, 75, 100],
410
+ description: "Allowed page sizes are 25, 50, 75, and 100. The vendor default is 25.",
411
+ };
412
+ const request = (req) => callCcb(connection, req);
413
+ const id = (value) => encodeURIComponent(String(value));
414
+ const one = (path, project, query = {}) => request({ method: "GET", path, query }).pipe(Effect.map(({ body }) => project(body)));
415
+ const fetchPage = (path, args, project, query = {}, cursor, body) => Effect.gen(function* () {
416
+ const size = Number(args.limit ?? limit.default);
417
+ let page = 1;
418
+ if (cursor) {
419
+ const saved = JSON.parse(cursor);
420
+ if (saved.revision !== CCB_INDEX.revision)
421
+ return yield* fail(new ConnectorCallError("invalid_args", "This CCB cursor belongs to a different API revision; start a new list."));
422
+ if (!Number.isSafeInteger(saved.page) || saved.page < 1)
423
+ return yield* fail(new ConnectorCallError("invalid_args", "This CCB cursor contains no valid page number."));
424
+ if (saved.limit !== size)
425
+ return yield* fail(new ConnectorCallError("invalid_args", "Keep the same limit when continuing this CCB page."));
426
+ page = saved.page;
427
+ }
428
+ const answer = yield* request({
429
+ method: body === undefined ? "GET" : "POST",
430
+ path,
431
+ query: { ...query, page, per_page: size },
432
+ ...(body === undefined ? {} : { body }),
433
+ });
434
+ if (path === "/search/schedules_totals/results" &&
435
+ answer.body &&
436
+ typeof answer.body === "object" &&
437
+ !Array.isArray(answer.body))
438
+ return { rows: [project(answer.body)], page: { hasMore: false, nextCursor: null } };
439
+ if (!Array.isArray(answer.body))
440
+ return yield* fail(new ConnectorCallError("connector_call_failed", "CCB returned a list without an array.", {
441
+ retryable: false,
442
+ }));
443
+ const rows = answer.body;
444
+ const totalText = answer.headers.get("x-total");
445
+ const total = yield* checked(() => {
446
+ if (totalText === null || totalText === "")
447
+ return undefined;
448
+ if (!/^(0|[1-9]\d*)$/.test(totalText) || !Number.isSafeInteger(Number(totalText)))
449
+ throw new ConnectorCallError("connector_call_failed", "CCB returned an invalid exact total.", {
450
+ retryable: false,
451
+ });
452
+ return Number(totalText);
453
+ });
454
+ const next = yield* checked(() => ccbPageInfo(Object.fromEntries(answer.headers), page, size, rows.length));
455
+ return {
456
+ rows: rows.map(project),
457
+ page: {
458
+ ...(total === undefined ? {} : { total }),
459
+ hasMore: next !== null,
460
+ nextCursor: next === null ? null : JSON.stringify({ page: next, limit: size, revision: CCB_INDEX.revision }),
461
+ },
462
+ };
463
+ });
464
+ return [
465
+ read(connection, {
466
+ name: "get_me",
467
+ description: "Get the CCB individual the access token belongs to. Under Identity Auth that is the signed-in person whose permissions every call carries.",
468
+ input: Schema.Struct({}),
469
+ output: ME_SCHEMA,
470
+ fields: true,
471
+ run: () => Effect.gen(function* () {
472
+ const { body } = yield* request({ method: "GET", path: "/me" });
473
+ const row = asRecord(body);
474
+ return compact({
475
+ id: row["id"],
476
+ name: row["name"],
477
+ email: row["email"] || undefined,
478
+ username: row["username"],
479
+ familyId: row["family_id"],
480
+ campusId: row["campus_id"],
481
+ userTypes: Array.isArray(row["user_types"]) ? row["user_types"] : undefined,
482
+ });
483
+ }),
484
+ }),
485
+ list(connection, {
486
+ name: "list_individuals",
487
+ description: "Find CCB individuals by partial name, phone, or email. Returns lean profiles with family and campus ids; not the advanced search.",
488
+ filters: {
489
+ "query": Schema.optionalKey(Schema.String.check(isMinChars(1), isMaxChars(200)).annotate({
490
+ description: "Partial name, phone number, or email. Omit to page everyone.",
491
+ })),
492
+ "includeInactive": Schema.optionalKey(Schema.Boolean.annotate({ description: "Include inactive individuals." })),
493
+ "includeDeceased": Schema.optionalKey(Schema.Boolean.annotate({ description: "Include deceased individuals." })),
494
+ "campusScope": Schema.optionalKey(Schema.Literals(["all", "current", "other"]).annotate({
495
+ description: "Campuses to search relative to the connection's own.",
496
+ })),
497
+ },
498
+ row: PERSON_SCHEMA,
499
+ limit,
500
+ total: true,
501
+ cursor: "bound",
502
+ page: (args, cursor) => Effect.gen(function* () {
503
+ return yield* fetchPage("/individuals", args, projectPerson, {
504
+ name: args["query"],
505
+ include_inactive: args["includeInactive"],
506
+ include_deceased: args["includeDeceased"],
507
+ campus_scope: args["campusScope"],
508
+ }, cursor);
509
+ }),
510
+ }),
511
+ read(connection, {
512
+ name: "get_individual",
513
+ description: "Get one CCB individual's profile: contact, addresses, membership, and custom fields. CCB allows one call a second; prefer list_individuals for many people.",
514
+ input: Schema.Struct({
515
+ "individualId": Integer.check(Schema.isGreaterThanOrEqualTo(1)).annotate({
516
+ description: "Individual id from list_individuals.",
517
+ }),
518
+ }),
519
+ output: INDIVIDUAL_SCHEMA,
520
+ fields: true,
521
+ run: (args) => Effect.gen(function* () {
522
+ return yield* one(`/individuals/${id(args["individualId"])}`, projectIndividual, {});
523
+ }),
524
+ }),
525
+ list(connection, {
526
+ name: "list_families",
527
+ description: "Find CCB families by partial last name, email, or mobile phone. Returns family ids and addresses; get_family lists the members.",
528
+ filters: {
529
+ "lastName": Schema.optionalKey(Schema.String.check(isMinChars(1), isMaxChars(200)).annotate({ description: "Partial last name." })),
530
+ "email": Schema.optionalKey(Schema.String.check(isMinChars(1), isMaxChars(200)).annotate({ description: "Partial email." })),
531
+ "phone": Schema.optionalKey(Schema.String.check(isMinChars(1), isMaxChars(50)).annotate({ description: "Partial mobile phone." })),
532
+ },
533
+ row: FAMILY_SCHEMA,
534
+ limit,
535
+ total: true,
536
+ cursor: "bound",
537
+ page: (args, cursor) => Effect.gen(function* () {
538
+ return yield* fetchPage("/families", args, projectFamily, {
539
+ last_name: args["lastName"],
540
+ email: args["email"],
541
+ phone: args["phone"],
542
+ }, cursor);
543
+ }),
544
+ }),
545
+ read(connection, {
546
+ name: "get_family",
547
+ description: "Get one CCB family with every member's lean profile and family position.",
548
+ input: Schema.Struct({
549
+ "familyId": Integer.check(Schema.isGreaterThanOrEqualTo(1)).annotate({
550
+ description: "Family id from an individual's familyId or list_families.",
551
+ }),
552
+ "includeInactive": Schema.optionalKey(Schema.Boolean.annotate({ description: "Include inactive members." })),
553
+ "includeDeceased": Schema.optionalKey(Schema.Boolean.annotate({ description: "Include deceased members." })),
554
+ }),
555
+ output: FAMILY_SCHEMA,
556
+ fields: true,
557
+ run: (args) => Effect.gen(function* () {
558
+ return yield* one(`/families/${id(args["familyId"])}`, projectFamily, {
559
+ include_inactive: args["includeInactive"],
560
+ include_deceased: args["includeDeceased"],
561
+ });
562
+ }),
563
+ }),
564
+ list(connection, {
565
+ name: "list_groups",
566
+ description: "List or search CCB groups by partial name, optionally for one campus. Returns group type, leader, and membership mode.",
567
+ filters: {
568
+ "name": Schema.optionalKey(Schema.String.check(isMinChars(1), isMaxChars(200)).annotate({ description: "Partial group name." })),
569
+ "campusId": Schema.optionalKey(Integer.check(Schema.isGreaterThanOrEqualTo(1)).annotate({ description: "Only groups at this campus." })),
570
+ },
571
+ row: GROUP_DETAIL_SCHEMA,
572
+ limit,
573
+ total: true,
574
+ cursor: "bound",
575
+ page: (args, cursor) => Effect.gen(function* () {
576
+ return yield* fetchPage("/groups", args, projectGroup, {
577
+ name: args["name"],
578
+ campus_ids: args["campusId"] === undefined ? undefined : [args["campusId"]],
579
+ }, cursor);
580
+ }),
581
+ }),
582
+ read(connection, {
583
+ name: "get_group",
584
+ description: "Get one CCB group: description, member count, meeting day, time, area, and address.",
585
+ input: Schema.Struct({
586
+ "groupId": Integer.check(Schema.isGreaterThanOrEqualTo(1)).annotate({
587
+ description: "Group id from list_groups.",
588
+ }),
589
+ }),
590
+ output: GROUP_DETAIL_SCHEMA,
591
+ fields: true,
592
+ run: (args) => Effect.gen(function* () {
593
+ return yield* one(`/groups/${id(args["groupId"])}`, projectGroup, {});
594
+ }),
595
+ }),
596
+ list(connection, {
597
+ name: "list_group_members",
598
+ description: "List one CCB group's participants with role and date added. Filter by leader or member status, or partial name.",
599
+ filters: {
600
+ "groupId": Integer.check(Schema.isGreaterThanOrEqualTo(1)).annotate({
601
+ description: "Group id from list_groups.",
602
+ }),
603
+ "status": Schema.optionalKey(Schema.Literals(["all", "leader", "member"]).annotate({ description: "Participant role filter." })),
604
+ "name": Schema.optionalKey(Schema.String.check(isMinChars(1), isMaxChars(200)).annotate({ description: "Partial participant name." })),
605
+ },
606
+ row: MEMBERSHIP_SCHEMA,
607
+ limit,
608
+ total: true,
609
+ cursor: "bound",
610
+ page: (args, cursor) => Effect.gen(function* () {
611
+ return yield* fetchPage(`/groups/${id(args["groupId"])}/members`, args, projectMembership, {
612
+ status: args["status"],
613
+ name: args["name"],
614
+ }, cursor);
615
+ }),
616
+ }),
617
+ list(connection, {
618
+ name: "list_individual_groups",
619
+ description: "List the CCB groups one individual belongs to, with their role. Defaults to member and leader roles.",
620
+ filters: {
621
+ "individualId": Integer.check(Schema.isGreaterThanOrEqualTo(1)).annotate({ description: "Individual id." }),
622
+ "includeInactive": Schema.optionalKey(Schema.Boolean.annotate({ description: "List inactive groups instead of active ones." })),
623
+ },
624
+ row: MEMBERSHIP_SCHEMA,
625
+ limit,
626
+ total: true,
627
+ cursor: "bound",
628
+ page: (args, cursor) => Effect.gen(function* () {
629
+ return yield* fetchPage(`/individuals/${id(args["individualId"])}/groups`, args, projectMembership, {
630
+ inactive: args["includeInactive"],
631
+ }, cursor);
632
+ }),
633
+ }),
634
+ list(connection, {
635
+ name: "list_events",
636
+ description: "List CCB event occurrences by name and time range. Each row's eventId and occurrence feed the attendance tools.",
637
+ filters: {
638
+ "name": Schema.optionalKey(Schema.String.check(isMinChars(1), isMaxChars(200)).annotate({ description: "Partial event name." })),
639
+ "range": Schema.optionalKey(Schema.Literals(["ALL", "PAST", "CURRENT", "FUTURE"]).annotate({
640
+ description: "Time range relative to now.",
641
+ })),
642
+ },
643
+ row: OCCURRENCE_SCHEMA,
644
+ limit,
645
+ total: true,
646
+ cursor: "bound",
647
+ page: (args, cursor) => Effect.gen(function* () {
648
+ return yield* fetchPage("/events", args, projectOccurrence, {
649
+ name: args["name"],
650
+ range_type: args["range"],
651
+ }, cursor);
652
+ }),
653
+ }),
654
+ read(connection, {
655
+ name: "get_event",
656
+ description: "Get one CCB event's details, optionally for one occurrence with its attendance totals.",
657
+ input: Schema.Struct({
658
+ "eventId": Integer.check(Schema.isGreaterThanOrEqualTo(1)).annotate({
659
+ description: "Event id from list_events.",
660
+ }),
661
+ "occurrence": Schema.optionalKey(Schema.String.check(pattern("^\\d{4}-?\\d{2}-?\\d{2}$")).annotate({
662
+ description: "Occurrence date, YYYYMMDD or YYYY-MM-DD. Omit for the series.",
663
+ })),
664
+ "withAttendance": Schema.optionalKey(Schema.Boolean.annotate({ description: "Add attendance totals for the occurrence." })),
665
+ }),
666
+ output: EVENT_SCHEMA,
667
+ fields: true,
668
+ run: (args) => Effect.gen(function* () {
669
+ return yield* one(`/events/${id(args["eventId"])}`, projectEvent, {
670
+ occurrence: compactDate(args["occurrence"]),
671
+ attendance_info: args["withAttendance"],
672
+ });
673
+ }),
674
+ }),
675
+ read(connection, {
676
+ name: "get_event_attendance",
677
+ description: "Get one CCB event occurrence's attendance summary: met or not, totals, visitors, topic. Drops leader notes and prayer requests from the named projection.",
678
+ input: Schema.Struct({
679
+ "eventId": Integer.check(Schema.isGreaterThanOrEqualTo(1)).annotate({
680
+ description: "Event id from list_events.",
681
+ }),
682
+ "occurrence": Schema.String.check(pattern("^\\d{4}-?\\d{2}-?\\d{2}$")).annotate({
683
+ description: "Occurrence date, YYYYMMDD or YYYY-MM-DD, from list_events.",
684
+ }),
685
+ }),
686
+ output: ATTENDANCE_SCHEMA,
687
+ fields: true,
688
+ run: (args) => Effect.gen(function* () {
689
+ return yield* one(`/events/${id(args["eventId"])}/attendance/${compactDate(args["occurrence"])}`, projectAttendance, {});
690
+ }),
691
+ }),
692
+ list(connection, {
693
+ name: "list_event_attendees",
694
+ description: "List who attended one CCB event occurrence. Returns individual ids and names.",
695
+ filters: {
696
+ "eventId": Integer.check(Schema.isGreaterThanOrEqualTo(1)).annotate({
697
+ description: "Event id from list_events.",
698
+ }),
699
+ "occurrence": Schema.String.check(pattern("^\\d{4}-?\\d{2}-?\\d{2}$")).annotate({
700
+ description: "Occurrence date, YYYYMMDD or YYYY-MM-DD, from list_events.",
701
+ }),
702
+ },
703
+ row: ATTENDEE_SCHEMA,
704
+ limit,
705
+ total: true,
706
+ cursor: "bound",
707
+ page: (args, cursor) => Effect.gen(function* () {
708
+ return yield* fetchPage(`/events/${id(args["eventId"])}/attendance/${compactDate(args["occurrence"])}/attendees`, args, projectAttendee, {}, cursor);
709
+ }),
710
+ }),
711
+ list(connection, {
712
+ name: "list_individual_notes",
713
+ description: "List the notes on one CCB individual that the connection may read, with sharing level and context. Pastoral content; reduce before returning.",
714
+ filters: {
715
+ "individualId": Integer.check(Schema.isGreaterThanOrEqualTo(1)).annotate({ description: "Individual id." }),
716
+ "context": Schema.optionalKey(Schema.Literals(["GROUP", "DEPARTMENT", "PROCESS_QUEUE", "GENERAL"]).annotate({
717
+ description: "Only notes in this context.",
718
+ })),
719
+ },
720
+ row: NOTE_SCHEMA,
721
+ limit,
722
+ total: true,
723
+ cursor: "bound",
724
+ page: (args, cursor) => Effect.gen(function* () {
725
+ return yield* fetchPage(`/individuals/${id(args["individualId"])}/notes`, args, projectNote, {
726
+ context: args["context"] === undefined ? undefined : [args["context"]],
727
+ include_creator: true,
728
+ }, cursor);
729
+ }),
730
+ }),
731
+ read(connection, {
732
+ name: "get_giving_metrics",
733
+ description: "Get gift counts by period for one CCB individual or family, over at most 12 months. No per-gift amounts or transactions; pledges and scheduled gifts are available through indexed reads.",
734
+ input: Schema.Struct({
735
+ "individualId": Schema.optionalKey(Integer.check(Schema.isGreaterThanOrEqualTo(1)).annotate({
736
+ description: "Individual id. Exactly one of individualId or familyId.",
737
+ })),
738
+ "familyId": Schema.optionalKey(Integer.check(Schema.isGreaterThanOrEqualTo(1)).annotate({
739
+ description: "Family id. Exactly one of individualId or familyId.",
740
+ })),
741
+ "start": Schema.optionalKey(Schema.String.check(pattern("^\\d{4}-\\d{2}-\\d{2}$")).annotate({
742
+ description: "Start date, YYYY-MM-DD. CCB caps the range at 12 months.",
743
+ })),
744
+ "end": Schema.optionalKey(Schema.String.check(pattern("^\\d{4}-\\d{2}-\\d{2}$")).annotate({
745
+ description: "End date, YYYY-MM-DD.",
746
+ })),
747
+ }),
748
+ output: Schema.Struct({
749
+ "periods": Schema.optionalKey(Schema.Array(Schema.Struct({
750
+ "start": Schema.optionalKey(Schema.String),
751
+ "count": Schema.optionalKey(Integer),
752
+ "members": Schema.optionalKey(Schema.Array(Schema.Struct({ "individualId": Schema.optionalKey(Integer), "count": Schema.optionalKey(Integer) }))),
753
+ }))),
754
+ }),
755
+ fields: true,
756
+ run: (args) => Effect.gen(function* () {
757
+ const individual = args["individualId"] !== undefined;
758
+ if (individual === (args["familyId"] !== undefined)) {
759
+ return yield* fail(new ConnectorCallError("invalid_args", "Pass exactly one of individualId or familyId."));
760
+ }
761
+ if (typeof args["start"] === "string" &&
762
+ typeof args["end"] === "string" &&
763
+ Date.parse(args["end"]) - Date.parse(args["start"]) > 366 * DAY_MS) {
764
+ return yield* fail(new ConnectorCallError("invalid_args", "CCB caps giving metrics at a 12-month range; narrow start and end."));
765
+ }
766
+ const path = individual
767
+ ? `/individuals/${id(args["individualId"])}/metrics/giving`
768
+ : `/families/${id(args["familyId"])}/metrics/giving`;
769
+ const { body } = yield* request({ method: "GET", path, query: { start: args["start"], end: args["end"] } });
770
+ const rows = asArray(body);
771
+ return {
772
+ periods: rows.map((value) => {
773
+ const row = asRecord(value);
774
+ return compact({
775
+ start: row["start"] ?? row["date"],
776
+ count: row["count"],
777
+ members: Array.isArray(row["members"])
778
+ ? row["members"].map((member) => {
779
+ const item = asRecord(member);
780
+ return compact({ individualId: item["id"], count: item["count"] });
781
+ })
782
+ : undefined,
783
+ });
784
+ }),
785
+ };
786
+ }),
787
+ }),
788
+ list(connection, {
789
+ name: "search_records",
790
+ review: "CCB documents the indexed advanced-search result POSTs as read-only data searches.",
791
+ description: "Search CCB church records with a reviewed read-only POST. Returns common identifiers, name, status and contact summaries; use the indexed read hatch for domain-specific response fields.",
792
+ filters: {
793
+ domain: Schema.String.check(pattern(`^(${SEARCH_DOMAINS.join("|")})$`)).annotate({
794
+ description: "Reviewed advanced-search domain; the pattern lists every allowed value.",
795
+ }),
796
+ body: Schema.Record(Schema.String, Schema.Unknown).annotate({
797
+ description: "Vendor search configuration and filters; get the operation details before choosing them.",
798
+ }),
799
+ },
800
+ row: Schema.Struct({
801
+ id: Schema.optionalKey(Integer),
802
+ name: Schema.optionalKey(Schema.String),
803
+ individualId: Schema.optionalKey(Integer),
804
+ groupId: Schema.optionalKey(Integer),
805
+ status: Schema.optionalKey(Schema.String),
806
+ active: Schema.optionalKey(Schema.Boolean),
807
+ campusId: Schema.optionalKey(Integer),
808
+ familyId: Schema.optionalKey(Integer),
809
+ membershipTypeId: Schema.optionalKey(Integer),
810
+ email: Schema.optionalKey(Schema.String),
811
+ counts: Schema.optionalKey(Schema.Struct({
812
+ stillNeeded: Schema.optionalKey(Integer),
813
+ needed: Schema.optionalKey(Integer),
814
+ accepted: Schema.optionalKey(Integer),
815
+ checkedIn: Schema.optionalKey(Integer),
816
+ declined: Schema.optionalKey(Integer),
817
+ pending: Schema.optionalKey(Integer),
818
+ })),
819
+ }),
820
+ limit,
821
+ total: true,
822
+ cursor: "bound",
823
+ page: (args, cursor) => checked(() => refuseWithheldValues(args.body, "search_records")).pipe(Effect.andThen(fetchPage("/search/" + args.domain + "/results", args, (value) => {
824
+ const row = asRecord(value);
825
+ return compact({
826
+ id: row.id,
827
+ name: row.name ?? row.title,
828
+ individualId: row.individual_id,
829
+ groupId: row.group_id,
830
+ status: row.status,
831
+ active: row.active,
832
+ campusId: row.campus_id,
833
+ familyId: row.family_id,
834
+ membershipTypeId: row.membership_type_id,
835
+ email: row.email,
836
+ counts: args.domain === "schedules_totals"
837
+ ? compact({
838
+ stillNeeded: row.still_needed,
839
+ needed: row.needed,
840
+ accepted: row.accepted,
841
+ checkedIn: row.checked_in,
842
+ declined: row.declined,
843
+ pending: row.pending,
844
+ })
845
+ : undefined,
846
+ });
847
+ }, {}, cursor, args.body))),
848
+ }),
849
+ ];
850
+ }
851
+ const DAY_MS = 86400000;
852
+ const fail = (error) => Effect.fail(new Refusal({ error }));
853
+ const pattern = (source) => Schema.makeFilter((value) => new RegExp(source).test(value), { toJsonSchema: () => ({ pattern: source }) });