@zackbart/connecta 0.34.1 → 0.35.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 (429) hide show
  1. package/CHANGELOG.md +363 -0
  2. package/README.md +62 -106
  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 +2051 -1160
  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 +663 -271
  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 +12 -7
  53. package/dist/connectors/api-connector.js +142 -56
  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 +228 -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 +383 -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/agents.d.ts +5 -4
  109. package/dist/operator-ui/agents.js +17 -7
  110. package/dist/operator-ui/config-summary.js +5 -4
  111. package/dist/operator-ui/connection-map.js +7 -5
  112. package/dist/operator-ui/contract.d.ts +7 -3
  113. package/dist/operator-ui/endpoints.js +4 -13
  114. package/dist/operator-ui/fix-prompts.d.ts +1 -1
  115. package/dist/operator-ui/fix-prompts.js +0 -8
  116. package/dist/operator-ui/generated.js +3 -3
  117. package/dist/operator-ui/model.d.ts +2 -3
  118. package/dist/operator-ui/overview.js +5 -2
  119. package/dist/operator-ui/setup-commands.js +0 -4
  120. package/dist/operator-ui/view.d.ts +2 -25
  121. package/dist/operator-ui/view.js +2 -76
  122. package/dist/program-writes.js +47 -26
  123. package/dist/provider-call-facts.d.ts +115 -0
  124. package/dist/provider-call-facts.js +182 -0
  125. package/dist/provider-call.d.ts +112 -0
  126. package/dist/provider-call.js +271 -0
  127. package/dist/provider.d.ts +65 -31
  128. package/dist/provider.js +116 -39
  129. package/dist/providers/_shared/google/hatch.js +91 -0
  130. package/dist/providers/_shared/google/kit.js +537 -0
  131. package/dist/providers/_shared/google/result-size.js +15 -2
  132. package/dist/providers/_shared/google/service-account.d.ts +2 -1
  133. package/dist/providers/_shared/google/service-account.js +8 -4
  134. package/dist/providers/_shared/google/workspace.d.ts +6 -210
  135. package/dist/providers/_shared/google/workspace.js +6 -425
  136. package/dist/providers/_shared/rest/compact-index.js +86 -0
  137. package/dist/providers/_shared/rest/dispatch.js +3 -23
  138. package/dist/providers/_shared/rest/kit.js +546 -0
  139. package/dist/providers/_shared/rest/operation-index.js +230 -14
  140. package/dist/providers/_shared/rest/response-media.js +11 -0
  141. package/dist/providers/_shared/rest/tools.js +101 -78
  142. package/dist/providers/_shared/rest/value-safety.js +353 -195
  143. package/dist/providers/_shared/sensitive-fields.js +27 -0
  144. package/dist/providers/breeze/api.js +584 -0
  145. package/dist/providers/breeze/index.d.ts +1 -3
  146. package/dist/providers/breeze/index.js +67 -1420
  147. package/dist/providers/breeze/openapi.generated.js +60 -0
  148. package/dist/providers/breeze/skill.generated.js +2 -6
  149. package/dist/providers/breeze/tools.js +696 -0
  150. package/dist/providers/ccb/api.js +496 -0
  151. package/dist/providers/ccb/index.d.ts +15 -37
  152. package/dist/providers/ccb/index.js +77 -1702
  153. package/dist/providers/ccb/lib/constants.d.ts +34 -0
  154. package/dist/providers/ccb/lib/constants.js +74 -0
  155. package/dist/providers/ccb/lib/guide.js +9 -0
  156. package/dist/providers/ccb/lib/verdicts.js +387 -0
  157. package/dist/providers/ccb/openapi.generated.js +397 -0
  158. package/dist/providers/ccb/safety.js +295 -0
  159. package/dist/providers/ccb/skill.generated.js +2 -6
  160. package/dist/providers/ccb/tools.js +853 -0
  161. package/dist/providers/cloudflare/api.js +1066 -0
  162. package/dist/providers/cloudflare/index.d.ts +5 -22
  163. package/dist/providers/cloudflare/index.js +79 -197
  164. package/dist/providers/cloudflare/lib/config.d.ts +16 -0
  165. package/dist/providers/cloudflare/lib/config.js +2 -0
  166. package/dist/providers/cloudflare/lib/discovery.js +29 -0
  167. package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
  168. package/dist/providers/cloudflare/lib/hatch.js +103 -0
  169. package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
  170. package/dist/providers/cloudflare/lib/response-media.js +75 -0
  171. package/dist/providers/cloudflare/openapi.generated.js +4 -3
  172. package/dist/providers/cloudflare/{value-safety.js → safety.js} +487 -0
  173. package/dist/providers/cloudflare/skill.generated.js +2 -10
  174. package/dist/providers/cloudflare/tools.js +360 -0
  175. package/dist/providers/docs/api.js +51 -0
  176. package/dist/providers/docs/index.d.ts +1 -12
  177. package/dist/providers/docs/index.js +53 -1165
  178. package/dist/providers/docs/lib/constants.d.ts +18 -0
  179. package/dist/providers/docs/lib/constants.js +18 -0
  180. package/dist/providers/docs/lib/discovery.js +26 -0
  181. package/dist/providers/docs/lib/requests.js +48 -0
  182. package/dist/providers/docs/lib/schemas.js +168 -0
  183. package/dist/providers/docs/openapi.generated.js +16 -0
  184. package/dist/providers/docs/safety.js +54 -0
  185. package/dist/providers/docs/skill.generated.js +2 -6
  186. package/dist/providers/docs/tools.js +802 -0
  187. package/dist/providers/drive/api.js +177 -0
  188. package/dist/providers/drive/index.d.ts +1 -12
  189. package/dist/providers/drive/index.js +38 -1448
  190. package/dist/providers/drive/lib/constants.d.ts +6 -0
  191. package/dist/providers/drive/lib/constants.js +6 -0
  192. package/dist/providers/drive/lib/contracts.js +532 -0
  193. package/dist/providers/drive/lib/hatch.js +197 -0
  194. package/dist/providers/drive/openapi.generated.js +77 -0
  195. package/dist/providers/drive/safety.js +90 -0
  196. package/dist/providers/drive/skill.generated.js +2 -6
  197. package/dist/providers/drive/tools.js +1290 -0
  198. package/dist/providers/forms/api.js +71 -0
  199. package/dist/providers/forms/index.d.ts +1 -12
  200. package/dist/providers/forms/index.js +49 -1145
  201. package/dist/providers/forms/lib/constants.d.ts +14 -0
  202. package/dist/providers/forms/lib/constants.js +19 -0
  203. package/dist/providers/forms/lib/hatch.js +72 -0
  204. package/dist/providers/forms/openapi.generated.js +23 -0
  205. package/dist/providers/forms/safety.js +34 -0
  206. package/dist/providers/forms/skill.generated.js +2 -8
  207. package/dist/providers/forms/tools.js +1024 -0
  208. package/dist/providers/github/api.js +150 -0
  209. package/dist/providers/github/index.d.ts +4 -5
  210. package/dist/providers/github/index.js +30 -87
  211. package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
  212. package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
  213. package/dist/providers/github/lib/discovery.js +132 -0
  214. package/dist/providers/github/lib/operations.js +58 -0
  215. package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
  216. package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
  217. package/dist/providers/github/openapi.generated.js +1216 -0
  218. package/dist/providers/github/safety.js +216 -0
  219. package/dist/providers/github/skill.generated.js +2 -5
  220. package/dist/providers/github/tools.js +506 -0
  221. package/dist/providers/gmail/api.js +114 -0
  222. package/dist/providers/gmail/index.d.ts +1 -12
  223. package/dist/providers/gmail/index.js +73 -1621
  224. package/dist/providers/gmail/lib/constants.d.ts +13 -0
  225. package/dist/providers/gmail/lib/constants.js +16 -0
  226. package/dist/providers/gmail/lib/index.js +173 -0
  227. package/dist/providers/gmail/lib/schemas.js +176 -0
  228. package/dist/providers/gmail/lib/threading.js +120 -0
  229. package/dist/providers/gmail/openapi.generated.js +92 -0
  230. package/dist/providers/gmail/safety.js +21 -0
  231. package/dist/providers/gmail/skill.generated.js +2 -6
  232. package/dist/providers/gmail/tools.js +1435 -0
  233. package/dist/providers/overflow/api.js +1008 -0
  234. package/dist/providers/overflow/index.d.ts +1 -17
  235. package/dist/providers/overflow/index.js +60 -1488
  236. package/dist/providers/overflow/skill.generated.js +2 -5
  237. package/dist/providers/overflow/tools.js +873 -0
  238. package/dist/providers/planning-center/api.js +467 -0
  239. package/dist/providers/planning-center/index.d.ts +4 -35
  240. package/dist/providers/planning-center/index.js +69 -2445
  241. package/dist/providers/planning-center/lib/constants.d.ts +58 -0
  242. package/dist/providers/planning-center/lib/constants.js +83 -0
  243. package/dist/providers/planning-center/lib/discovery.js +40 -0
  244. package/dist/providers/planning-center/lib/guide.js +39 -0
  245. package/dist/providers/planning-center/lib/json-api.js +83 -0
  246. package/dist/providers/planning-center/lib/verdicts.js +1758 -0
  247. package/dist/providers/planning-center/openapi.generated.js +1764 -0
  248. package/dist/providers/planning-center/safety.js +188 -0
  249. package/dist/providers/planning-center/skill.generated.js +2 -27
  250. package/dist/providers/planning-center/tools.js +1010 -0
  251. package/dist/providers/sheets/api.js +133 -0
  252. package/dist/providers/sheets/index.d.ts +4 -16
  253. package/dist/providers/sheets/index.js +61 -1172
  254. package/dist/providers/sheets/lib/constants.d.ts +14 -0
  255. package/dist/providers/sheets/lib/constants.js +14 -0
  256. package/dist/providers/sheets/lib/hatch.js +163 -0
  257. package/dist/providers/sheets/lib/requests.js +105 -0
  258. package/dist/providers/sheets/lib/schemas.js +138 -0
  259. package/dist/providers/sheets/openapi.generated.js +30 -0
  260. package/dist/providers/sheets/safety.js +27 -0
  261. package/dist/providers/sheets/skill.generated.js +2 -7
  262. package/dist/providers/sheets/tools.js +734 -0
  263. package/dist/providers/slides/api.js +147 -0
  264. package/dist/providers/slides/index.d.ts +2 -10
  265. package/dist/providers/slides/index.js +48 -2555
  266. package/dist/providers/slides/lib/constants.d.ts +11 -0
  267. package/dist/providers/slides/lib/constants.js +11 -0
  268. package/dist/providers/slides/lib/requests.js +60 -0
  269. package/dist/providers/slides/lib/schemas.js +565 -0
  270. package/dist/providers/slides/openapi.generated.js +18 -0
  271. package/dist/providers/slides/skill.generated.js +2 -6
  272. package/dist/providers/slides/tools.js +1968 -0
  273. package/dist/providers/stripe/api.js +401 -0
  274. package/dist/providers/stripe/index.d.ts +5 -27
  275. package/dist/providers/stripe/index.js +74 -210
  276. package/dist/providers/stripe/lib/config.d.ts +4 -0
  277. package/dist/providers/stripe/lib/config.js +2 -0
  278. package/dist/providers/stripe/openapi.generated.js +4 -3
  279. package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
  280. package/dist/providers/stripe/skill.generated.js +2 -11
  281. package/dist/providers/stripe/tools.js +77 -0
  282. package/dist/providers/tithely/api.js +531 -0
  283. package/dist/providers/tithely/index.d.ts +17 -0
  284. package/dist/providers/tithely/index.js +86 -965
  285. package/dist/providers/tithely/skill.generated.js +2 -5
  286. package/dist/providers/tithely/tools.js +426 -0
  287. package/dist/providers/vercel/api.js +551 -0
  288. package/dist/providers/vercel/index.d.ts +9 -25
  289. package/dist/providers/vercel/index.js +66 -260
  290. package/dist/providers/vercel/lib/config.d.ts +2 -0
  291. package/dist/providers/vercel/lib/config.js +2 -0
  292. package/dist/providers/vercel/lib/index.js +117 -0
  293. package/dist/providers/vercel/lib/logs.js +100 -0
  294. package/dist/providers/vercel/lib/pin.js +270 -0
  295. package/dist/providers/vercel/openapi.generated.js +10 -5
  296. package/dist/providers/vercel/{value-safety.js → safety.js} +247 -38
  297. package/dist/providers/vercel/skill.generated.js +2 -7
  298. package/dist/providers/vercel/tools.js +642 -0
  299. package/dist/redaction-identity.js +47 -0
  300. package/dist/redaction-marker.js +125 -0
  301. package/dist/registry.d.ts +21 -15
  302. package/dist/registry.js +409 -376
  303. package/dist/routes/access-tokens.js +1 -1
  304. package/dist/routes/actor-labels.js +1 -1
  305. package/dist/routes/connect.js +1 -1
  306. package/dist/routes/dispatch.js +103 -0
  307. package/dist/routes/mcp.js +170 -79
  308. package/dist/routes/oauth.js +3 -1
  309. package/dist/routes/operator.js +2 -2
  310. package/dist/routes/shared.d.ts +5 -4
  311. package/dist/routes/shared.js +244 -177
  312. package/dist/routes/skills.js +10 -8
  313. package/dist/routes/ui-config.js +27 -3
  314. package/dist/routes/ui-data.js +21 -20
  315. package/dist/routes/ui.js +1 -1
  316. package/dist/runtime/call-admission.js +0 -26
  317. package/dist/runtime/call-entry.js +30 -0
  318. package/dist/runtime/call.js +556 -0
  319. package/dist/runtime/connector-scope.js +7 -0
  320. package/dist/runtime/credential-probe.js +34 -0
  321. package/dist/runtime/executor.js +40 -0
  322. package/dist/runtime/native-storage.js +63 -0
  323. package/dist/runtime/registry.js +27 -0
  324. package/dist/runtime/request-scope.js +72 -0
  325. package/dist/runtime/run.js +15 -7
  326. package/dist/runtime/shared-read.js +34 -5
  327. package/dist/runtime/storage.js +34 -21
  328. package/dist/sent-secrets.d.ts +194 -37
  329. package/dist/sent-secrets.js +1743 -340
  330. package/dist/server.js +5 -56
  331. package/dist/skills.js +322 -222
  332. package/dist/sqlite.js +15 -14
  333. package/dist/storage/d1-copy.js +255 -0
  334. package/dist/storage/d1-driver.js +15 -0
  335. package/dist/storage/keys.js +28 -0
  336. package/dist/storage/sql-driver.js +88 -0
  337. package/dist/storage/sql-native.js +544 -0
  338. package/dist/storage/sql-schema.d.ts +6 -0
  339. package/dist/storage/sql-schema.js +15 -0
  340. package/dist/storage/sql.d.ts +14 -20
  341. package/dist/storage/sql.js +29 -535
  342. package/dist/timeout.js +0 -26
  343. package/dist/tool-safety.js +20 -10
  344. package/dist/types.d.ts +7 -109
  345. package/dist/upward.js +3 -0
  346. package/dist/usage-guide.js +3 -1
  347. package/dist/validate.d.ts +4 -2
  348. package/dist/validate.js +86 -9
  349. package/dist/version.d.ts +1 -1
  350. package/dist/version.js +1 -1
  351. package/dist/worker.js +312 -292
  352. package/dist/workspace-subject.js +5 -1
  353. package/dist/write-outcome.js +454 -34
  354. package/documentation/README.md +27 -7
  355. package/documentation/architecture.md +2547 -226
  356. package/documentation/auth.md +821 -98
  357. package/documentation/code-mode.md +49 -16
  358. package/documentation/deploying.md +164 -20
  359. package/documentation/hosted-mcp-migration.md +460 -0
  360. package/documentation/integrating.md +129 -144
  361. package/documentation/meta-tools.md +409 -32
  362. package/documentation/operating.md +27 -3
  363. package/documentation/operator-tests.md +3 -0
  364. package/documentation/operator-ui.md +68 -45
  365. package/documentation/provider-auth-migration.md +16 -63
  366. package/documentation/provider-migration-0.29.md +10 -5
  367. package/documentation/provider-migration-0.35.md +975 -0
  368. package/documentation/providers.md +965 -0
  369. package/examples/worker/AGENTS.md +23 -9
  370. package/examples/worker/README.md +254 -135
  371. package/examples/worker/alchemy.run.ts +116 -0
  372. package/examples/worker/gitignore +10 -0
  373. package/examples/worker/src/connecta.config.ts +23 -21
  374. package/examples/worker/wrangler.jsonc +14 -5
  375. package/guides/connecting-agents.md +157 -0
  376. package/guides/how-it-works.md +156 -0
  377. package/guides/safety-and-trust.md +153 -0
  378. package/package.json +27 -46
  379. package/templates/node/.env.example +3 -0
  380. package/templates/node/README.md +22 -2
  381. package/templates/node/docker-compose.yml +1 -0
  382. package/templates/node/package.json +3 -2
  383. package/templates/node/src/connecta.config.ts +8 -0
  384. package/dist/catalog-drift.d.ts +0 -138
  385. package/dist/catalog-drift.js +0 -578
  386. package/dist/providers/_shared/request-token.js +0 -83
  387. package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
  388. package/dist/providers/_shared/rest/tools.d.ts +0 -141
  389. package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
  390. package/dist/providers/basecamp/index.d.ts +0 -45
  391. package/dist/providers/basecamp/index.js +0 -997
  392. package/dist/providers/basecamp/skill.generated.js +0 -9
  393. package/dist/providers/cloudflare/rest.d.ts +0 -37
  394. package/dist/providers/cloudflare/rest.js +0 -1097
  395. package/dist/providers/github/hosted.js +0 -218
  396. package/dist/providers/github/rest.js +0 -321
  397. package/dist/providers/infisical/index.d.ts +0 -7
  398. package/dist/providers/infisical/index.js +0 -713
  399. package/dist/providers/infisical/skill.generated.js +0 -8
  400. package/dist/providers/intercom/index.d.ts +0 -24
  401. package/dist/providers/intercom/index.js +0 -121
  402. package/dist/providers/intercom/skill.generated.js +0 -8
  403. package/dist/providers/linear/index.d.ts +0 -55
  404. package/dist/providers/linear/index.js +0 -537
  405. package/dist/providers/linear/skill.generated.js +0 -8
  406. package/dist/providers/mixpanel/index.d.ts +0 -59
  407. package/dist/providers/mixpanel/index.js +0 -472
  408. package/dist/providers/mixpanel/operations.js +0 -20
  409. package/dist/providers/mixpanel/rest.js +0 -603
  410. package/dist/providers/mixpanel/skill.generated.js +0 -10
  411. package/dist/providers/mixpanel/value-safety.js +0 -16
  412. package/dist/providers/notion/index.d.ts +0 -67
  413. package/dist/providers/notion/index.js +0 -368
  414. package/dist/providers/notion/openapi.generated.js +0 -75
  415. package/dist/providers/notion/rest.d.ts +0 -24
  416. package/dist/providers/notion/rest.js +0 -1226
  417. package/dist/providers/notion/skill.generated.js +0 -11
  418. package/dist/providers/notion/value-safety.js +0 -56
  419. package/dist/providers/revenuecat/index.d.ts +0 -51
  420. package/dist/providers/revenuecat/index.js +0 -697
  421. package/dist/providers/revenuecat/skill.generated.js +0 -11
  422. package/dist/providers/stripe/rest.d.ts +0 -14
  423. package/dist/providers/stripe/rest.js +0 -402
  424. package/dist/providers/vercel/rest.d.ts +0 -20
  425. package/dist/providers/vercel/rest.js +0 -1020
  426. package/dist/providers/wispr-flow/index.d.ts +0 -14
  427. package/dist/providers/wispr-flow/index.js +0 -117
  428. package/dist/providers/wispr-flow/skill.generated.js +0 -8
  429. /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 }) });