veryfront 0.0.48 → 0.0.50

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 (536) hide show
  1. package/dist/ai/components.js +260 -56
  2. package/dist/ai/components.js.map +4 -4
  3. package/dist/ai/index.d.ts +1 -0
  4. package/dist/ai/index.js +12 -4
  5. package/dist/ai/index.js.map +2 -2
  6. package/dist/ai/primitives.js +55 -10
  7. package/dist/ai/primitives.js.map +3 -3
  8. package/dist/ai/react.js +140 -1
  9. package/dist/ai/react.js.map +3 -3
  10. package/dist/ai/workflow-react.js +458 -0
  11. package/dist/ai/workflow-react.js.map +7 -0
  12. package/dist/ai/workflow.js +5422 -0
  13. package/dist/ai/workflow.js.map +7 -0
  14. package/dist/cli.js +976 -234
  15. package/dist/components.js +12 -4
  16. package/dist/components.js.map +2 -2
  17. package/dist/config.js +12 -4
  18. package/dist/config.js.map +2 -2
  19. package/dist/data.js +12 -4
  20. package/dist/data.js.map +2 -2
  21. package/dist/index.js +12 -8
  22. package/dist/index.js.map +2 -2
  23. package/dist/integrations/_base/files/SETUP.md +667 -98
  24. package/dist/integrations/_base/files/app/api/integrations/token-storage/route.ts +14 -0
  25. package/dist/integrations/_base/files/app/components/ServiceConnections.tsx +2 -1
  26. package/dist/integrations/_base/files/app/setup/page.tsx +858 -54
  27. package/dist/integrations/_base/files/lib/token-store-examples.ts +435 -0
  28. package/dist/integrations/_base/files/lib/token-store.ts +273 -23
  29. package/dist/integrations/airtable/connector.json +99 -0
  30. package/dist/integrations/airtable/files/ai/tools/create-record.ts +25 -0
  31. package/dist/integrations/airtable/files/ai/tools/get-base.ts +34 -0
  32. package/dist/integrations/airtable/files/ai/tools/get-record.ts +23 -0
  33. package/dist/integrations/airtable/files/ai/tools/list-bases.ts +19 -0
  34. package/dist/integrations/airtable/files/ai/tools/list-records.ts +47 -0
  35. package/dist/integrations/airtable/files/app/api/auth/airtable/callback/route.ts +11 -0
  36. package/dist/integrations/airtable/files/app/api/auth/airtable/route.ts +9 -0
  37. package/dist/integrations/airtable/files/lib/airtable-client.ts +244 -0
  38. package/dist/integrations/airtable/files/lib/token-store.ts +5 -0
  39. package/dist/integrations/anthropic/README.md +181 -0
  40. package/dist/integrations/anthropic/connector.json +88 -0
  41. package/dist/integrations/anthropic/files/_env.example +4 -0
  42. package/dist/integrations/anthropic/files/ai/tools/get-organization.ts +36 -0
  43. package/dist/integrations/anthropic/files/ai/tools/get-usage.ts +100 -0
  44. package/dist/integrations/anthropic/files/ai/tools/list-api-keys.ts +64 -0
  45. package/dist/integrations/anthropic/files/ai/tools/list-members.ts +65 -0
  46. package/dist/integrations/anthropic/files/ai/tools/list-workspaces.ts +35 -0
  47. package/dist/integrations/anthropic/files/lib/anthropic-admin-client.ts +264 -0
  48. package/dist/integrations/asana/connector.json +85 -0
  49. package/dist/integrations/asana/files/_env.example +4 -0
  50. package/dist/integrations/asana/files/ai/tools/create-task.ts +34 -0
  51. package/dist/integrations/asana/files/ai/tools/get-task.ts +26 -0
  52. package/dist/integrations/asana/files/ai/tools/list-projects.ts +26 -0
  53. package/dist/integrations/asana/files/ai/tools/list-tasks.ts +50 -0
  54. package/dist/integrations/asana/files/ai/tools/update-task.ts +36 -0
  55. package/dist/integrations/asana/files/app/api/auth/asana/callback/route.ts +11 -0
  56. package/dist/integrations/asana/files/app/api/auth/asana/route.ts +7 -0
  57. package/dist/integrations/asana/files/lib/asana-client.ts +162 -0
  58. package/dist/integrations/asana/files/lib/token-store.ts +11 -0
  59. package/dist/integrations/aws/connector.json +72 -0
  60. package/dist/integrations/aws/files/_env.example +10 -0
  61. package/dist/integrations/aws/files/ai/tools/get-s3-object.ts +62 -0
  62. package/dist/integrations/aws/files/ai/tools/list-ec2-instances.ts +56 -0
  63. package/dist/integrations/aws/files/ai/tools/list-lambda-functions.ts +57 -0
  64. package/dist/integrations/aws/files/ai/tools/list-s3-buckets.ts +44 -0
  65. package/dist/integrations/aws/files/ai/tools/list-s3-objects.ts +58 -0
  66. package/dist/integrations/aws/files/lib/aws-client.ts +255 -0
  67. package/dist/integrations/bitbucket/connector.json +85 -0
  68. package/dist/integrations/bitbucket/files/_env.example +9 -0
  69. package/dist/integrations/bitbucket/files/ai/tools/create-pull-request.ts +83 -0
  70. package/dist/integrations/bitbucket/files/ai/tools/list-issues.ts +112 -0
  71. package/dist/integrations/bitbucket/files/ai/tools/list-pull-requests.ts +91 -0
  72. package/dist/integrations/bitbucket/files/ai/tools/list-repositories.ts +78 -0
  73. package/dist/integrations/bitbucket/files/app/api/auth/bitbucket/callback/route.ts +11 -0
  74. package/dist/integrations/bitbucket/files/app/api/auth/bitbucket/route.ts +9 -0
  75. package/dist/integrations/bitbucket/files/lib/bitbucket-client.ts +316 -0
  76. package/dist/integrations/bitbucket/files/lib/token-store.ts +5 -0
  77. package/dist/integrations/box/connector.json +85 -0
  78. package/dist/integrations/box/files/_env.example +4 -0
  79. package/dist/integrations/box/files/ai/tools/create-folder.ts +28 -0
  80. package/dist/integrations/box/files/ai/tools/get-file.ts +29 -0
  81. package/dist/integrations/box/files/ai/tools/list-files.ts +33 -0
  82. package/dist/integrations/box/files/ai/tools/search-files.ts +35 -0
  83. package/dist/integrations/box/files/ai/tools/upload-file.ts +32 -0
  84. package/dist/integrations/box/files/app/api/auth/box/callback/route.ts +11 -0
  85. package/dist/integrations/box/files/app/api/auth/box/route.ts +7 -0
  86. package/dist/integrations/box/files/lib/box-client.ts +280 -0
  87. package/dist/integrations/box/files/lib/token-store.ts +11 -0
  88. package/dist/integrations/calendar/files/app/api/auth/calendar/callback/route.ts +7 -110
  89. package/dist/integrations/calendar/files/app/api/auth/calendar/route.ts +5 -25
  90. package/dist/integrations/calendar/files/lib/token-store.ts +2 -110
  91. package/dist/integrations/clickup/connector.json +85 -0
  92. package/dist/integrations/clickup/files/_env.example +4 -0
  93. package/dist/integrations/clickup/files/ai/tools/create-task.ts +64 -0
  94. package/dist/integrations/clickup/files/ai/tools/get-task.ts +59 -0
  95. package/dist/integrations/clickup/files/ai/tools/list-lists.ts +109 -0
  96. package/dist/integrations/clickup/files/ai/tools/list-tasks.ts +95 -0
  97. package/dist/integrations/clickup/files/ai/tools/update-task.ts +85 -0
  98. package/dist/integrations/clickup/files/app/api/auth/clickup/callback/route.ts +11 -0
  99. package/dist/integrations/clickup/files/app/api/auth/clickup/route.ts +7 -0
  100. package/dist/integrations/clickup/files/lib/clickup-client.ts +439 -0
  101. package/dist/integrations/clickup/files/lib/token-store.ts +11 -0
  102. package/dist/integrations/confluence/README.md +246 -0
  103. package/dist/integrations/confluence/connector.json +104 -0
  104. package/dist/integrations/confluence/files/_env.example +4 -0
  105. package/dist/integrations/confluence/files/ai/tools/create-page.ts +43 -0
  106. package/dist/integrations/confluence/files/ai/tools/get-page.ts +30 -0
  107. package/dist/integrations/confluence/files/ai/tools/list-spaces.ts +31 -0
  108. package/dist/integrations/confluence/files/ai/tools/search-content.ts +38 -0
  109. package/dist/integrations/confluence/files/ai/tools/update-page.ts +45 -0
  110. package/dist/integrations/confluence/files/app/api/auth/confluence/callback/route.ts +11 -0
  111. package/dist/integrations/confluence/files/app/api/auth/confluence/route.ts +9 -0
  112. package/dist/integrations/confluence/files/lib/confluence-client.ts +281 -0
  113. package/dist/integrations/confluence/files/lib/token-store.ts +5 -0
  114. package/dist/integrations/discord/connector.json +100 -0
  115. package/dist/integrations/discord/files/_env.example +12 -0
  116. package/dist/integrations/discord/files/ai/tools/get-messages.ts +55 -0
  117. package/dist/integrations/discord/files/ai/tools/get-user.ts +32 -0
  118. package/dist/integrations/discord/files/ai/tools/list-channels.ts +32 -0
  119. package/dist/integrations/discord/files/ai/tools/list-guilds.ts +24 -0
  120. package/dist/integrations/discord/files/ai/tools/send-message.ts +33 -0
  121. package/dist/integrations/discord/files/app/api/auth/discord/callback/route.ts +11 -0
  122. package/dist/integrations/discord/files/app/api/auth/discord/route.ts +9 -0
  123. package/dist/integrations/discord/files/lib/discord-client.ts +273 -0
  124. package/dist/integrations/discord/files/lib/token-store.ts +5 -0
  125. package/dist/integrations/docs-google/connector.json +101 -0
  126. package/dist/integrations/docs-google/files/_env.example +8 -0
  127. package/dist/integrations/docs-google/files/ai/tools/create-document.ts +46 -0
  128. package/dist/integrations/docs-google/files/ai/tools/get-document.ts +46 -0
  129. package/dist/integrations/docs-google/files/ai/tools/list-documents.ts +42 -0
  130. package/dist/integrations/docs-google/files/ai/tools/search-documents.ts +38 -0
  131. package/dist/integrations/docs-google/files/ai/tools/update-document.ts +131 -0
  132. package/dist/integrations/docs-google/files/app/api/auth/docs-google/callback/route.ts +11 -0
  133. package/dist/integrations/docs-google/files/app/api/auth/docs-google/route.ts +9 -0
  134. package/dist/integrations/docs-google/files/lib/docs-client.ts +582 -0
  135. package/dist/integrations/docs-google/files/lib/token-store.ts +5 -0
  136. package/dist/integrations/drive/connector.json +134 -0
  137. package/dist/integrations/drive/files/_env.example +9 -0
  138. package/dist/integrations/drive/files/ai/tools/create-folder.ts +47 -0
  139. package/dist/integrations/drive/files/ai/tools/get-file.ts +55 -0
  140. package/dist/integrations/drive/files/ai/tools/list-files.ts +78 -0
  141. package/dist/integrations/drive/files/ai/tools/search-files.ts +79 -0
  142. package/dist/integrations/drive/files/ai/tools/upload-file.ts +59 -0
  143. package/dist/integrations/drive/files/app/api/auth/drive/callback/route.ts +11 -0
  144. package/dist/integrations/drive/files/app/api/auth/drive/route.ts +9 -0
  145. package/dist/integrations/drive/files/lib/drive-client.ts +359 -0
  146. package/dist/integrations/drive/files/lib/token-store.ts +113 -0
  147. package/dist/integrations/dropbox/connector.json +107 -0
  148. package/dist/integrations/dropbox/files/_env.example +24 -0
  149. package/dist/integrations/dropbox/files/ai/tools/get-account.ts +58 -0
  150. package/dist/integrations/dropbox/files/ai/tools/get-file.ts +61 -0
  151. package/dist/integrations/dropbox/files/ai/tools/list-files.ts +56 -0
  152. package/dist/integrations/dropbox/files/ai/tools/search-files.ts +70 -0
  153. package/dist/integrations/dropbox/files/ai/tools/upload-file.ts +48 -0
  154. package/dist/integrations/dropbox/files/app/api/auth/dropbox/callback/route.ts +11 -0
  155. package/dist/integrations/dropbox/files/app/api/auth/dropbox/route.ts +9 -0
  156. package/dist/integrations/dropbox/files/lib/dropbox-client.ts +397 -0
  157. package/dist/integrations/dropbox/files/lib/token-store.ts +5 -0
  158. package/dist/integrations/figma/INTEGRATION_SUMMARY.md +436 -0
  159. package/dist/integrations/figma/README.md +287 -0
  160. package/dist/integrations/figma/connector.json +100 -0
  161. package/dist/integrations/figma/files/_env.example +5 -0
  162. package/dist/integrations/figma/files/ai/tools/get-comments.ts +72 -0
  163. package/dist/integrations/figma/files/ai/tools/get-file.ts +54 -0
  164. package/dist/integrations/figma/files/ai/tools/list-files.ts +39 -0
  165. package/dist/integrations/figma/files/ai/tools/list-projects.ts +69 -0
  166. package/dist/integrations/figma/files/ai/tools/post-comment.ts +54 -0
  167. package/dist/integrations/figma/files/app/api/auth/figma/callback/route.ts +11 -0
  168. package/dist/integrations/figma/files/app/api/auth/figma/route.ts +9 -0
  169. package/dist/integrations/figma/files/lib/figma-client.ts +355 -0
  170. package/dist/integrations/figma/files/lib/token-store.ts +5 -0
  171. package/dist/integrations/figma/files/lib/types.ts +503 -0
  172. package/dist/integrations/freshdesk/connector.json +85 -0
  173. package/dist/integrations/freshdesk/files/_env.example +4 -0
  174. package/dist/integrations/freshdesk/files/ai/tools/create-ticket.ts +60 -0
  175. package/dist/integrations/freshdesk/files/ai/tools/get-ticket.ts +46 -0
  176. package/dist/integrations/freshdesk/files/ai/tools/list-contacts.ts +37 -0
  177. package/dist/integrations/freshdesk/files/ai/tools/list-tickets.ts +59 -0
  178. package/dist/integrations/freshdesk/files/ai/tools/update-ticket.ts +61 -0
  179. package/dist/integrations/freshdesk/files/app/api/auth/freshdesk/callback/route.ts +11 -0
  180. package/dist/integrations/freshdesk/files/app/api/auth/freshdesk/route.ts +7 -0
  181. package/dist/integrations/freshdesk/files/lib/freshdesk-client.ts +178 -0
  182. package/dist/integrations/freshdesk/files/lib/token-store.ts +11 -0
  183. package/dist/integrations/github/files/app/api/auth/github/callback/route.ts +6 -127
  184. package/dist/integrations/github/files/app/api/auth/github/route.ts +4 -24
  185. package/dist/integrations/github/files/lib/token-store.ts +2 -110
  186. package/dist/integrations/gitlab/connector.json +100 -0
  187. package/dist/integrations/gitlab/files/_env.example +7 -0
  188. package/dist/integrations/gitlab/files/ai/tools/create-issue.ts +49 -0
  189. package/dist/integrations/gitlab/files/ai/tools/get-issue.ts +56 -0
  190. package/dist/integrations/gitlab/files/ai/tools/list-merge-requests.ts +75 -0
  191. package/dist/integrations/gitlab/files/ai/tools/list-projects.ts +51 -0
  192. package/dist/integrations/gitlab/files/ai/tools/search-issues.ts +67 -0
  193. package/dist/integrations/gitlab/files/app/api/auth/gitlab/callback/route.ts +11 -0
  194. package/dist/integrations/gitlab/files/app/api/auth/gitlab/route.ts +9 -0
  195. package/dist/integrations/gitlab/files/lib/gitlab-client.ts +366 -0
  196. package/dist/integrations/gitlab/files/lib/token-store.ts +5 -0
  197. package/dist/integrations/gmail/files/app/api/auth/gmail/callback/route.ts +7 -108
  198. package/dist/integrations/gmail/files/app/api/auth/gmail/route.ts +5 -23
  199. package/dist/integrations/gmail/files/lib/gmail-client.ts +16 -55
  200. package/dist/integrations/gmail/files/lib/token-store.ts +4 -109
  201. package/dist/integrations/hubspot/connector.json +98 -0
  202. package/dist/integrations/hubspot/files/_env.example +5 -0
  203. package/dist/integrations/hubspot/files/ai/tools/create-contact.ts +41 -0
  204. package/dist/integrations/hubspot/files/ai/tools/create-deal.ts +41 -0
  205. package/dist/integrations/hubspot/files/ai/tools/get-contact.ts +39 -0
  206. package/dist/integrations/hubspot/files/ai/tools/list-contacts.ts +43 -0
  207. package/dist/integrations/hubspot/files/ai/tools/list-deals.ts +41 -0
  208. package/dist/integrations/hubspot/files/app/api/auth/hubspot/callback/route.ts +11 -0
  209. package/dist/integrations/hubspot/files/app/api/auth/hubspot/route.ts +9 -0
  210. package/dist/integrations/hubspot/files/lib/hubspot-client.ts +393 -0
  211. package/dist/integrations/hubspot/files/lib/token-store.ts +5 -0
  212. package/dist/integrations/intercom/connector.json +85 -0
  213. package/dist/integrations/intercom/files/_env.example +4 -0
  214. package/dist/integrations/intercom/files/ai/tools/get-contact.ts +35 -0
  215. package/dist/integrations/intercom/files/ai/tools/get-conversation.ts +55 -0
  216. package/dist/integrations/intercom/files/ai/tools/list-contacts.ts +35 -0
  217. package/dist/integrations/intercom/files/ai/tools/list-conversations.ts +49 -0
  218. package/dist/integrations/intercom/files/ai/tools/send-message.ts +34 -0
  219. package/dist/integrations/intercom/files/app/api/auth/intercom/callback/route.ts +11 -0
  220. package/dist/integrations/intercom/files/app/api/auth/intercom/route.ts +7 -0
  221. package/dist/integrations/intercom/files/lib/intercom-client.ts +308 -0
  222. package/dist/integrations/intercom/files/lib/token-store.ts +11 -0
  223. package/dist/integrations/jira/connector.json +109 -0
  224. package/dist/integrations/jira/files/ai/tools/create-issue.ts +47 -0
  225. package/dist/integrations/jira/files/ai/tools/get-issue.ts +57 -0
  226. package/dist/integrations/jira/files/ai/tools/list-projects.ts +30 -0
  227. package/dist/integrations/jira/files/ai/tools/search-issues.ts +49 -0
  228. package/dist/integrations/jira/files/ai/tools/update-issue.ts +81 -0
  229. package/dist/integrations/jira/files/app/api/auth/jira/callback/route.ts +11 -0
  230. package/dist/integrations/jira/files/app/api/auth/jira/route.ts +9 -0
  231. package/dist/integrations/jira/files/lib/jira-client.ts +338 -0
  232. package/dist/integrations/jira/files/lib/token-store.ts +5 -0
  233. package/dist/integrations/linear/connector.json +100 -0
  234. package/dist/integrations/linear/files/_env.example +6 -0
  235. package/dist/integrations/linear/files/ai/tools/create-issue.ts +71 -0
  236. package/dist/integrations/linear/files/ai/tools/get-issue.ts +55 -0
  237. package/dist/integrations/linear/files/ai/tools/list-projects.ts +43 -0
  238. package/dist/integrations/linear/files/ai/tools/search-issues.ts +54 -0
  239. package/dist/integrations/linear/files/ai/tools/update-issue.ts +71 -0
  240. package/dist/integrations/linear/files/app/api/auth/linear/callback/route.ts +11 -0
  241. package/dist/integrations/linear/files/app/api/auth/linear/route.ts +9 -0
  242. package/dist/integrations/linear/files/lib/linear-client.ts +464 -0
  243. package/dist/integrations/linear/files/lib/token-store.ts +5 -0
  244. package/dist/integrations/mailchimp/connector.json +85 -0
  245. package/dist/integrations/mailchimp/files/_env.example +4 -0
  246. package/dist/integrations/mailchimp/files/ai/tools/get-campaign.ts +45 -0
  247. package/dist/integrations/mailchimp/files/ai/tools/get-list.ts +51 -0
  248. package/dist/integrations/mailchimp/files/ai/tools/list-campaigns.ts +46 -0
  249. package/dist/integrations/mailchimp/files/ai/tools/list-lists.ts +46 -0
  250. package/dist/integrations/mailchimp/files/ai/tools/list-members.ts +58 -0
  251. package/dist/integrations/mailchimp/files/app/api/auth/mailchimp/callback/route.ts +11 -0
  252. package/dist/integrations/mailchimp/files/app/api/auth/mailchimp/route.ts +7 -0
  253. package/dist/integrations/mailchimp/files/lib/mailchimp-client.ts +267 -0
  254. package/dist/integrations/mailchimp/files/lib/token-store.ts +11 -0
  255. package/dist/integrations/mixpanel/connector.json +96 -0
  256. package/dist/integrations/mixpanel/files/_env.example +11 -0
  257. package/dist/integrations/mixpanel/files/ai/tools/get-funnel.ts +46 -0
  258. package/dist/integrations/mixpanel/files/ai/tools/get-retention.ts +64 -0
  259. package/dist/integrations/mixpanel/files/ai/tools/list-cohorts.ts +46 -0
  260. package/dist/integrations/mixpanel/files/ai/tools/query-events.ts +43 -0
  261. package/dist/integrations/mixpanel/files/ai/tools/track-event.ts +41 -0
  262. package/dist/integrations/mixpanel/files/lib/mixpanel-client.ts +319 -0
  263. package/dist/integrations/mixpanel/files/lib/token-store.ts +43 -0
  264. package/dist/integrations/monday/connector.json +85 -0
  265. package/dist/integrations/monday/files/_env.example +4 -0
  266. package/dist/integrations/monday/files/ai/tools/create-item.ts +36 -0
  267. package/dist/integrations/monday/files/ai/tools/get-item.ts +31 -0
  268. package/dist/integrations/monday/files/ai/tools/list-boards.ts +29 -0
  269. package/dist/integrations/monday/files/ai/tools/list-items.ts +36 -0
  270. package/dist/integrations/monday/files/ai/tools/update-item.ts +36 -0
  271. package/dist/integrations/monday/files/app/api/auth/monday/callback/route.ts +11 -0
  272. package/dist/integrations/monday/files/app/api/auth/monday/route.ts +7 -0
  273. package/dist/integrations/monday/files/lib/monday-client.ts +329 -0
  274. package/dist/integrations/monday/files/lib/token-store.ts +11 -0
  275. package/dist/integrations/neon/connector.json +89 -0
  276. package/dist/integrations/neon/files/_env.example +6 -0
  277. package/dist/integrations/neon/files/ai/tools/describe-table.ts +38 -0
  278. package/dist/integrations/neon/files/ai/tools/list-branches.ts +35 -0
  279. package/dist/integrations/neon/files/ai/tools/list-projects.ts +31 -0
  280. package/dist/integrations/neon/files/ai/tools/list-tables.ts +49 -0
  281. package/dist/integrations/neon/files/ai/tools/query-database.ts +33 -0
  282. package/dist/integrations/neon/files/app/api/auth/neon/route.ts +51 -0
  283. package/dist/integrations/neon/files/lib/neon-client.ts +294 -0
  284. package/dist/integrations/neon/files/lib/token-store.ts +29 -0
  285. package/dist/integrations/notion/connector.json +87 -0
  286. package/dist/integrations/notion/files/_env.example +6 -0
  287. package/dist/integrations/notion/files/ai/tools/create-page.ts +32 -0
  288. package/dist/integrations/notion/files/ai/tools/query-database.ts +44 -0
  289. package/dist/integrations/notion/files/ai/tools/read-page.ts +34 -0
  290. package/dist/integrations/notion/files/ai/tools/search-notion.ts +51 -0
  291. package/dist/integrations/notion/files/app/api/auth/notion/callback/route.ts +11 -0
  292. package/dist/integrations/notion/files/app/api/auth/notion/route.ts +9 -0
  293. package/dist/integrations/notion/files/lib/notion-client.ts +218 -0
  294. package/dist/integrations/notion/files/lib/token-store.ts +5 -0
  295. package/dist/integrations/onedrive/connector.json +100 -0
  296. package/dist/integrations/onedrive/files/_env.example +23 -0
  297. package/dist/integrations/onedrive/files/ai/tools/download-file.ts +38 -0
  298. package/dist/integrations/onedrive/files/ai/tools/list-files.ts +63 -0
  299. package/dist/integrations/onedrive/files/ai/tools/search-files.ts +59 -0
  300. package/dist/integrations/onedrive/files/ai/tools/upload-file.ts +43 -0
  301. package/dist/integrations/onedrive/files/app/api/auth/onedrive/callback/route.ts +11 -0
  302. package/dist/integrations/onedrive/files/app/api/auth/onedrive/route.ts +9 -0
  303. package/dist/integrations/onedrive/files/lib/onedrive-client.ts +314 -0
  304. package/dist/integrations/onedrive/files/lib/token-store.ts +5 -0
  305. package/dist/integrations/outlook/README.md +308 -0
  306. package/dist/integrations/outlook/connector.json +98 -0
  307. package/dist/integrations/outlook/files/_env.example +8 -0
  308. package/dist/integrations/outlook/files/ai/tools/get-email.ts +47 -0
  309. package/dist/integrations/outlook/files/ai/tools/list-emails.ts +46 -0
  310. package/dist/integrations/outlook/files/ai/tools/list-folders.ts +22 -0
  311. package/dist/integrations/outlook/files/ai/tools/search-emails.ts +41 -0
  312. package/dist/integrations/outlook/files/ai/tools/send-email.ts +41 -0
  313. package/dist/integrations/outlook/files/app/api/auth/outlook/callback/route.ts +11 -0
  314. package/dist/integrations/outlook/files/app/api/auth/outlook/route.ts +9 -0
  315. package/dist/integrations/outlook/files/lib/outlook-client.ts +204 -0
  316. package/dist/integrations/outlook/files/lib/token-store.ts +5 -0
  317. package/dist/integrations/pipedrive/connector.json +85 -0
  318. package/dist/integrations/pipedrive/files/_env.example +4 -0
  319. package/dist/integrations/pipedrive/files/ai/tools/create-deal.ts +44 -0
  320. package/dist/integrations/pipedrive/files/ai/tools/get-deal.ts +34 -0
  321. package/dist/integrations/pipedrive/files/ai/tools/list-deals.ts +40 -0
  322. package/dist/integrations/pipedrive/files/ai/tools/list-persons.ts +33 -0
  323. package/dist/integrations/pipedrive/files/ai/tools/update-deal.ts +46 -0
  324. package/dist/integrations/pipedrive/files/app/api/auth/pipedrive/callback/route.ts +11 -0
  325. package/dist/integrations/pipedrive/files/app/api/auth/pipedrive/route.ts +7 -0
  326. package/dist/integrations/pipedrive/files/lib/pipedrive-client.ts +259 -0
  327. package/dist/integrations/pipedrive/files/lib/token-store.ts +11 -0
  328. package/dist/integrations/posthog/connector.json +84 -0
  329. package/dist/integrations/posthog/files/_env.example +6 -0
  330. package/dist/integrations/posthog/files/ai/tools/capture-event.ts +37 -0
  331. package/dist/integrations/posthog/files/ai/tools/get-trends.ts +44 -0
  332. package/dist/integrations/posthog/files/ai/tools/list-feature-flags.ts +38 -0
  333. package/dist/integrations/posthog/files/ai/tools/list-persons.ts +32 -0
  334. package/dist/integrations/posthog/files/lib/posthog-client.ts +286 -0
  335. package/dist/integrations/posthog/files/lib/token-store.ts +21 -0
  336. package/dist/integrations/quickbooks/connector.json +85 -0
  337. package/dist/integrations/quickbooks/files/_env.example +4 -0
  338. package/dist/integrations/quickbooks/files/ai/tools/create-invoice.ts +48 -0
  339. package/dist/integrations/quickbooks/files/ai/tools/get-customer.ts +36 -0
  340. package/dist/integrations/quickbooks/files/ai/tools/get-invoice.ts +46 -0
  341. package/dist/integrations/quickbooks/files/ai/tools/list-customers.ts +37 -0
  342. package/dist/integrations/quickbooks/files/ai/tools/list-invoices.ts +40 -0
  343. package/dist/integrations/quickbooks/files/app/api/auth/quickbooks/callback/route.ts +11 -0
  344. package/dist/integrations/quickbooks/files/app/api/auth/quickbooks/route.ts +7 -0
  345. package/dist/integrations/quickbooks/files/lib/quickbooks-client.ts +252 -0
  346. package/dist/integrations/quickbooks/files/lib/token-store.ts +11 -0
  347. package/dist/integrations/salesforce/connector.json +104 -0
  348. package/dist/integrations/salesforce/files/ai/tools/create-lead.ts +101 -0
  349. package/dist/integrations/salesforce/files/ai/tools/get-account.ts +53 -0
  350. package/dist/integrations/salesforce/files/ai/tools/list-accounts.ts +50 -0
  351. package/dist/integrations/salesforce/files/ai/tools/list-contacts.ts +54 -0
  352. package/dist/integrations/salesforce/files/ai/tools/list-opportunities.ts +55 -0
  353. package/dist/integrations/salesforce/files/app/api/auth/salesforce/callback/route.ts +11 -0
  354. package/dist/integrations/salesforce/files/app/api/auth/salesforce/route.ts +9 -0
  355. package/dist/integrations/salesforce/files/lib/salesforce-client.ts +539 -0
  356. package/dist/integrations/salesforce/files/lib/token-store.ts +5 -0
  357. package/dist/integrations/sentry/connector.json +84 -0
  358. package/dist/integrations/sentry/files/_env.example +6 -0
  359. package/dist/integrations/sentry/files/ai/tools/get-issue.ts +66 -0
  360. package/dist/integrations/sentry/files/ai/tools/list-issues.ts +57 -0
  361. package/dist/integrations/sentry/files/ai/tools/list-projects.ts +32 -0
  362. package/dist/integrations/sentry/files/ai/tools/resolve-issue.ts +28 -0
  363. package/dist/integrations/sentry/files/lib/sentry-client.ts +268 -0
  364. package/dist/integrations/sentry/files/lib/token-store.ts +29 -0
  365. package/dist/integrations/servicenow/connector.json +66 -0
  366. package/dist/integrations/servicenow/files/_env.example +5 -0
  367. package/dist/integrations/servicenow/files/ai/tools/create-incident.ts +58 -0
  368. package/dist/integrations/servicenow/files/ai/tools/get-incident.ts +59 -0
  369. package/dist/integrations/servicenow/files/ai/tools/list-incidents.ts +72 -0
  370. package/dist/integrations/servicenow/files/ai/tools/search-knowledge.ts +48 -0
  371. package/dist/integrations/servicenow/files/ai/tools/update-incident.ts +60 -0
  372. package/dist/integrations/servicenow/files/app/api/auth/servicenow/callback/route.ts +89 -0
  373. package/dist/integrations/servicenow/files/app/api/auth/servicenow/route.ts +42 -0
  374. package/dist/integrations/servicenow/files/lib/servicenow-client.ts +239 -0
  375. package/dist/integrations/servicenow/files/lib/token-store.ts +42 -0
  376. package/dist/integrations/sharepoint/connector.json +99 -0
  377. package/dist/integrations/sharepoint/files/ai/tools/get-file.ts +93 -0
  378. package/dist/integrations/sharepoint/files/ai/tools/get-site.ts +51 -0
  379. package/dist/integrations/sharepoint/files/ai/tools/list-files.ts +63 -0
  380. package/dist/integrations/sharepoint/files/ai/tools/list-sites.ts +28 -0
  381. package/dist/integrations/sharepoint/files/ai/tools/upload-file.ts +72 -0
  382. package/dist/integrations/sharepoint/files/app/api/auth/sharepoint/callback/route.ts +11 -0
  383. package/dist/integrations/sharepoint/files/app/api/auth/sharepoint/route.ts +9 -0
  384. package/dist/integrations/sharepoint/files/lib/sharepoint-client.ts +420 -0
  385. package/dist/integrations/sharepoint/files/lib/token-store.ts +5 -0
  386. package/dist/integrations/sheets/README.md +331 -0
  387. package/dist/integrations/sheets/connector.json +99 -0
  388. package/dist/integrations/sheets/files/_env.example +8 -0
  389. package/dist/integrations/sheets/files/ai/tools/create-spreadsheet.ts +85 -0
  390. package/dist/integrations/sheets/files/ai/tools/get-spreadsheet.ts +39 -0
  391. package/dist/integrations/sheets/files/ai/tools/list-spreadsheets.ts +41 -0
  392. package/dist/integrations/sheets/files/ai/tools/read-range.ts +35 -0
  393. package/dist/integrations/sheets/files/ai/tools/write-range.ts +51 -0
  394. package/dist/integrations/sheets/files/app/api/auth/sheets/callback/route.ts +11 -0
  395. package/dist/integrations/sheets/files/app/api/auth/sheets/route.ts +9 -0
  396. package/dist/integrations/sheets/files/lib/sheets-client.ts +425 -0
  397. package/dist/integrations/sheets/files/lib/token-store.ts +5 -0
  398. package/dist/integrations/shopify/connector.json +99 -0
  399. package/dist/integrations/shopify/files/_env.example +5 -0
  400. package/dist/integrations/shopify/files/ai/tools/get-order.ts +49 -0
  401. package/dist/integrations/shopify/files/ai/tools/get-product.ts +39 -0
  402. package/dist/integrations/shopify/files/ai/tools/list-customers.ts +40 -0
  403. package/dist/integrations/shopify/files/ai/tools/list-orders.ts +52 -0
  404. package/dist/integrations/shopify/files/ai/tools/list-products.ts +39 -0
  405. package/dist/integrations/shopify/files/app/api/auth/shopify/callback/route.ts +11 -0
  406. package/dist/integrations/shopify/files/app/api/auth/shopify/route.ts +7 -0
  407. package/dist/integrations/shopify/files/lib/shopify-client.ts +198 -0
  408. package/dist/integrations/shopify/files/lib/token-store.ts +11 -0
  409. package/dist/integrations/slack/files/app/api/auth/slack/callback/route.ts +6 -127
  410. package/dist/integrations/slack/files/app/api/auth/slack/route.ts +4 -24
  411. package/dist/integrations/slack/files/lib/token-store.ts +2 -110
  412. package/dist/integrations/snowflake/connector.json +151 -0
  413. package/dist/integrations/snowflake/files/_env.example +16 -0
  414. package/dist/integrations/snowflake/files/ai/tools/describe-table.ts +57 -0
  415. package/dist/integrations/snowflake/files/ai/tools/list-databases.ts +34 -0
  416. package/dist/integrations/snowflake/files/ai/tools/list-schemas.ts +40 -0
  417. package/dist/integrations/snowflake/files/ai/tools/list-tables.ts +49 -0
  418. package/dist/integrations/snowflake/files/ai/tools/run-query.ts +119 -0
  419. package/dist/integrations/snowflake/files/lib/snowflake-client.ts +389 -0
  420. package/dist/integrations/snowflake/files/lib/token-store.ts +77 -0
  421. package/dist/integrations/stripe/connector.json +97 -0
  422. package/dist/integrations/stripe/files/_env.example +6 -0
  423. package/dist/integrations/stripe/files/ai/tools/get-balance.ts +28 -0
  424. package/dist/integrations/stripe/files/ai/tools/get-customer.ts +26 -0
  425. package/dist/integrations/stripe/files/ai/tools/list-customers.ts +42 -0
  426. package/dist/integrations/stripe/files/ai/tools/list-payments.ts +45 -0
  427. package/dist/integrations/stripe/files/ai/tools/list-subscriptions.ts +67 -0
  428. package/dist/integrations/stripe/files/app/api/auth/stripe/route.ts +71 -0
  429. package/dist/integrations/stripe/files/lib/stripe-client.ts +376 -0
  430. package/dist/integrations/stripe/files/lib/token-store.ts +21 -0
  431. package/dist/integrations/supabase/connector.json +101 -0
  432. package/dist/integrations/supabase/files/_env.example +6 -0
  433. package/dist/integrations/supabase/files/ai/tools/delete-row.ts +77 -0
  434. package/dist/integrations/supabase/files/ai/tools/insert-row.ts +35 -0
  435. package/dist/integrations/supabase/files/ai/tools/list-tables.ts +60 -0
  436. package/dist/integrations/supabase/files/ai/tools/query-table.ts +48 -0
  437. package/dist/integrations/supabase/files/ai/tools/update-row.ts +64 -0
  438. package/dist/integrations/supabase/files/app/api/auth/supabase/route.ts +91 -0
  439. package/dist/integrations/supabase/files/lib/supabase-client.ts +296 -0
  440. package/dist/integrations/supabase/files/lib/token-store.ts +47 -0
  441. package/dist/integrations/teams/README.md +256 -0
  442. package/dist/integrations/teams/connector.json +99 -0
  443. package/dist/integrations/teams/files/ai/tools/get-messages.ts +55 -0
  444. package/dist/integrations/teams/files/ai/tools/list-channels.ts +28 -0
  445. package/dist/integrations/teams/files/ai/tools/list-chats.ts +41 -0
  446. package/dist/integrations/teams/files/ai/tools/list-teams.ts +27 -0
  447. package/dist/integrations/teams/files/ai/tools/send-message.ts +61 -0
  448. package/dist/integrations/teams/files/app/api/auth/teams/callback/route.ts +11 -0
  449. package/dist/integrations/teams/files/app/api/auth/teams/route.ts +9 -0
  450. package/dist/integrations/teams/files/lib/teams-client.ts +345 -0
  451. package/dist/integrations/teams/files/lib/token-store.ts +5 -0
  452. package/dist/integrations/trello/connector.json +85 -0
  453. package/dist/integrations/trello/files/_env.example +4 -0
  454. package/dist/integrations/trello/files/ai/tools/create-card.ts +54 -0
  455. package/dist/integrations/trello/files/ai/tools/get-card.ts +33 -0
  456. package/dist/integrations/trello/files/ai/tools/list-boards.ts +29 -0
  457. package/dist/integrations/trello/files/ai/tools/list-cards.ts +52 -0
  458. package/dist/integrations/trello/files/ai/tools/update-card.ts +65 -0
  459. package/dist/integrations/trello/files/app/api/auth/trello/callback/route.ts +11 -0
  460. package/dist/integrations/trello/files/app/api/auth/trello/route.ts +7 -0
  461. package/dist/integrations/trello/files/lib/token-store.ts +11 -0
  462. package/dist/integrations/trello/files/lib/trello-client.ts +202 -0
  463. package/dist/integrations/twilio/connector.json +146 -0
  464. package/dist/integrations/twilio/files/_env.example +14 -0
  465. package/dist/integrations/twilio/files/ai/tools/get-message.ts +58 -0
  466. package/dist/integrations/twilio/files/ai/tools/list-calls.ts +129 -0
  467. package/dist/integrations/twilio/files/ai/tools/list-messages.ts +97 -0
  468. package/dist/integrations/twilio/files/ai/tools/send-sms.ts +75 -0
  469. package/dist/integrations/twilio/files/ai/tools/send-whatsapp.ts +81 -0
  470. package/dist/integrations/twilio/files/lib/token-store.ts +60 -0
  471. package/dist/integrations/twilio/files/lib/twilio-client.ts +375 -0
  472. package/dist/integrations/twitter/connector.json +87 -0
  473. package/dist/integrations/twitter/files/_env.example +6 -0
  474. package/dist/integrations/twitter/files/ai/tools/get-timeline.ts +59 -0
  475. package/dist/integrations/twitter/files/ai/tools/post-tweet.ts +49 -0
  476. package/dist/integrations/twitter/files/ai/tools/search-tweets.ts +71 -0
  477. package/dist/integrations/twitter/files/app/api/auth/twitter/callback/route.ts +11 -0
  478. package/dist/integrations/twitter/files/app/api/auth/twitter/route.ts +9 -0
  479. package/dist/integrations/twitter/files/lib/token-store.ts +5 -0
  480. package/dist/integrations/twitter/files/lib/twitter-client.ts +236 -0
  481. package/dist/integrations/webex/connector.json +85 -0
  482. package/dist/integrations/webex/files/_env.example +4 -0
  483. package/dist/integrations/webex/files/ai/tools/create-meeting.ts +69 -0
  484. package/dist/integrations/webex/files/ai/tools/get-meeting.ts +31 -0
  485. package/dist/integrations/webex/files/ai/tools/list-meetings.ts +44 -0
  486. package/dist/integrations/webex/files/ai/tools/list-rooms.ts +35 -0
  487. package/dist/integrations/webex/files/ai/tools/send-message.ts +51 -0
  488. package/dist/integrations/webex/files/app/api/auth/webex/callback/route.ts +11 -0
  489. package/dist/integrations/webex/files/app/api/auth/webex/route.ts +7 -0
  490. package/dist/integrations/webex/files/lib/token-store.ts +11 -0
  491. package/dist/integrations/webex/files/lib/webex-client.ts +279 -0
  492. package/dist/integrations/xero/connector.json +85 -0
  493. package/dist/integrations/xero/files/_env.example +4 -0
  494. package/dist/integrations/xero/files/ai/tools/create-invoice.ts +65 -0
  495. package/dist/integrations/xero/files/ai/tools/get-contact.ts +40 -0
  496. package/dist/integrations/xero/files/ai/tools/get-invoice.ts +44 -0
  497. package/dist/integrations/xero/files/ai/tools/list-contacts.ts +54 -0
  498. package/dist/integrations/xero/files/ai/tools/list-invoices.ts +54 -0
  499. package/dist/integrations/xero/files/app/api/auth/xero/callback/route.ts +11 -0
  500. package/dist/integrations/xero/files/app/api/auth/xero/route.ts +7 -0
  501. package/dist/integrations/xero/files/lib/token-store.ts +11 -0
  502. package/dist/integrations/xero/files/lib/xero-client.ts +292 -0
  503. package/dist/integrations/zendesk/connector.json +61 -0
  504. package/dist/integrations/zendesk/files/_env.example +5 -0
  505. package/dist/integrations/zendesk/files/ai/tools/create-ticket.ts +82 -0
  506. package/dist/integrations/zendesk/files/ai/tools/get-ticket.ts +53 -0
  507. package/dist/integrations/zendesk/files/ai/tools/list-tickets.ts +60 -0
  508. package/dist/integrations/zendesk/files/ai/tools/search-tickets.ts +56 -0
  509. package/dist/integrations/zendesk/files/app/api/auth/zendesk/callback/route.ts +91 -0
  510. package/dist/integrations/zendesk/files/app/api/auth/zendesk/route.ts +41 -0
  511. package/dist/integrations/zendesk/files/lib/token-store.ts +47 -0
  512. package/dist/integrations/zendesk/files/lib/zendesk-client.ts +265 -0
  513. package/dist/integrations/zoom/connector.json +85 -0
  514. package/dist/integrations/zoom/files/_env.example +4 -0
  515. package/dist/integrations/zoom/files/ai/tools/create-meeting.ts +106 -0
  516. package/dist/integrations/zoom/files/ai/tools/delete-meeting.ts +32 -0
  517. package/dist/integrations/zoom/files/ai/tools/get-meeting.ts +44 -0
  518. package/dist/integrations/zoom/files/ai/tools/list-meetings.ts +47 -0
  519. package/dist/integrations/zoom/files/ai/tools/update-meeting.ts +111 -0
  520. package/dist/integrations/zoom/files/app/api/auth/zoom/callback/route.ts +11 -0
  521. package/dist/integrations/zoom/files/app/api/auth/zoom/route.ts +7 -0
  522. package/dist/integrations/zoom/files/lib/token-store.ts +11 -0
  523. package/dist/integrations/zoom/files/lib/zoom-client.ts +228 -0
  524. package/dist/oauth/handlers.js +554 -0
  525. package/dist/oauth/handlers.js.map +7 -0
  526. package/dist/oauth/index.js +1157 -0
  527. package/dist/oauth/index.js.map +7 -0
  528. package/dist/oauth/providers.js +927 -0
  529. package/dist/oauth/providers.js.map +7 -0
  530. package/dist/oauth/token-store.js +82 -0
  531. package/dist/oauth/token-store.js.map +7 -0
  532. package/package.json +25 -1
  533. package/dist/integrations/gmail/files/lib/oauth.ts +0 -145
  534. package/dist/integrations/slack/files/lib/oauth.ts +0 -145
  535. /package/dist/integrations/{calendar → docs-google}/files/lib/oauth.ts +0 -0
  536. /package/dist/integrations/{github → drive}/files/lib/oauth.ts +0 -0
@@ -1,8 +1,41 @@
1
1
  /**
2
2
  * OAuth Token Store
3
3
  *
4
- * Simple in-memory token store for development.
5
- * Replace with a database or KV store for production.
4
+ * Manages OAuth tokens for connected services.
5
+ *
6
+ * ## Storage Modes
7
+ *
8
+ * **Development (default)**: In-memory storage - tokens are lost on restart.
9
+ * **Production**: Configure via environment variables:
10
+ * - DATABASE_URL: Uses database storage (Postgres, SQLite, MySQL)
11
+ * - KV_REST_API_URL + KV_REST_API_TOKEN: Uses Vercel KV
12
+ * - REDIS_URL: Uses Redis
13
+ * - TOKEN_ENCRYPTION_KEY: Enables AES-256-GCM encryption (recommended)
14
+ *
15
+ * ## Security
16
+ *
17
+ * Tokens contain sensitive OAuth credentials. In production:
18
+ * 1. Always use encrypted storage (set TOKEN_ENCRYPTION_KEY)
19
+ * 2. Use HTTPS for all connections
20
+ * 3. Implement proper access control
21
+ * 4. Rotate encryption keys periodically
22
+ *
23
+ * @example Production setup with Vercel KV
24
+ * ```bash
25
+ * # .env
26
+ * KV_REST_API_URL=https://your-kv.vercel-storage.com
27
+ * KV_REST_API_TOKEN=your-token
28
+ * TOKEN_ENCRYPTION_KEY=your-32-byte-hex-key # Generate: openssl rand -hex 32
29
+ * ```
30
+ *
31
+ * @example Production setup with Postgres
32
+ * ```bash
33
+ * # .env
34
+ * DATABASE_URL=postgres://user:pass@host:5432/db
35
+ * TOKEN_ENCRYPTION_KEY=your-32-byte-hex-key
36
+ * ```
37
+ *
38
+ * @see lib/token-store-examples.ts for complete production implementations
6
39
  */
7
40
 
8
41
  export interface OAuthToken {
@@ -20,7 +53,176 @@ export interface TokenStore {
20
53
  isConnected(userId: string, service: string): Promise<boolean>;
21
54
  }
22
55
 
23
- // In-memory storage for development
56
+ /** Token store configuration for production backends */
57
+ export interface TokenStoreConfig {
58
+ /** Get value by key */
59
+ get: (key: string) => Promise<string | null>;
60
+ /** Set value by key */
61
+ set: (key: string, value: string) => Promise<void>;
62
+ /** Delete value by key */
63
+ delete: (key: string) => Promise<void>;
64
+ }
65
+
66
+ // ============================================================================
67
+ // Encryption Utilities
68
+ // ============================================================================
69
+
70
+ /**
71
+ * Encrypts a token using AES-256-GCM
72
+ * Requires TOKEN_ENCRYPTION_KEY environment variable (32-byte hex string)
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const encrypted = await encryptToken(token);
77
+ * // Store encrypted string in database
78
+ * ```
79
+ */
80
+ export async function encryptToken(token: OAuthToken): Promise<string> {
81
+ const key = getEncryptionKey();
82
+ if (!key) {
83
+ // No encryption key - store as plain JSON (development mode)
84
+ return JSON.stringify(token);
85
+ }
86
+
87
+ const encoder = new TextEncoder();
88
+ const data = encoder.encode(JSON.stringify(token));
89
+
90
+ // Generate random IV (12 bytes for GCM)
91
+ const iv = crypto.getRandomValues(new Uint8Array(12));
92
+
93
+ // Import the key
94
+ const cryptoKey = await crypto.subtle.importKey(
95
+ "raw",
96
+ key,
97
+ { name: "AES-GCM" },
98
+ false,
99
+ ["encrypt"],
100
+ );
101
+
102
+ // Encrypt
103
+ const encrypted = await crypto.subtle.encrypt(
104
+ { name: "AES-GCM", iv },
105
+ cryptoKey,
106
+ data,
107
+ );
108
+
109
+ // Combine IV + ciphertext and encode as base64
110
+ const combined = new Uint8Array(iv.length + encrypted.byteLength);
111
+ combined.set(iv);
112
+ combined.set(new Uint8Array(encrypted), iv.length);
113
+
114
+ return `encrypted:${btoa(String.fromCharCode(...combined))}`;
115
+ }
116
+
117
+ /**
118
+ * Decrypts a token encrypted with encryptToken()
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * const token = await decryptToken(encryptedString);
123
+ * // Use token.accessToken, token.refreshToken, etc.
124
+ * ```
125
+ */
126
+ export async function decryptToken(encrypted: string): Promise<OAuthToken | null> {
127
+ // Check if it's encrypted or plain JSON
128
+ if (!encrypted.startsWith("encrypted:")) {
129
+ try {
130
+ return JSON.parse(encrypted) as OAuthToken;
131
+ } catch {
132
+ return null;
133
+ }
134
+ }
135
+
136
+ const key = getEncryptionKey();
137
+ if (!key) {
138
+ console.error("[Token Store] Cannot decrypt: TOKEN_ENCRYPTION_KEY not set");
139
+ return null;
140
+ }
141
+
142
+ try {
143
+ // Decode base64
144
+ const base64 = encrypted.slice("encrypted:".length);
145
+ const combined = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
146
+
147
+ // Extract IV and ciphertext
148
+ const iv = combined.slice(0, 12);
149
+ const ciphertext = combined.slice(12);
150
+
151
+ // Import the key
152
+ const cryptoKey = await crypto.subtle.importKey(
153
+ "raw",
154
+ key,
155
+ { name: "AES-GCM" },
156
+ false,
157
+ ["decrypt"],
158
+ );
159
+
160
+ // Decrypt
161
+ const decrypted = await crypto.subtle.decrypt(
162
+ { name: "AES-GCM", iv },
163
+ cryptoKey,
164
+ ciphertext,
165
+ );
166
+
167
+ const decoder = new TextDecoder();
168
+ return JSON.parse(decoder.decode(decrypted)) as OAuthToken;
169
+ } catch (error) {
170
+ console.error("[Token Store] Decryption failed:", error);
171
+ return null;
172
+ }
173
+ }
174
+
175
+ /** Get encryption key from environment */
176
+ function getEncryptionKey(): Uint8Array | null {
177
+ const keyHex = typeof process !== "undefined"
178
+ ? process.env?.TOKEN_ENCRYPTION_KEY
179
+ // deno-lint-ignore no-explicit-any
180
+ : (globalThis as any).Deno?.env?.get("TOKEN_ENCRYPTION_KEY");
181
+
182
+ if (!keyHex) return null;
183
+
184
+ // Convert hex string to Uint8Array (32 bytes = 64 hex chars)
185
+ if (keyHex.length !== 64) {
186
+ console.error("[Token Store] TOKEN_ENCRYPTION_KEY must be 64 hex characters (32 bytes)");
187
+ return null;
188
+ }
189
+
190
+ const key = new Uint8Array(32);
191
+ for (let i = 0; i < 32; i++) {
192
+ key[i] = parseInt(keyHex.slice(i * 2, i * 2 + 2), 16);
193
+ }
194
+ return key;
195
+ }
196
+
197
+ // ============================================================================
198
+ // Storage Mode Detection
199
+ // ============================================================================
200
+
201
+ /** Current storage mode for diagnostics */
202
+ export type StorageMode = "memory" | "database" | "kv" | "redis" | "custom";
203
+
204
+ /** Get current storage mode based on environment */
205
+ export function getStorageMode(): StorageMode {
206
+ const env = typeof process !== "undefined"
207
+ ? process.env
208
+ // deno-lint-ignore no-explicit-any
209
+ : (globalThis as any).Deno?.env?.toObject() || {};
210
+
211
+ if (env.DATABASE_URL) return "database";
212
+ if (env.KV_REST_API_URL) return "kv";
213
+ if (env.REDIS_URL) return "redis";
214
+ return "memory";
215
+ }
216
+
217
+ /** Check if encryption is enabled */
218
+ export function isEncryptionEnabled(): boolean {
219
+ return getEncryptionKey() !== null;
220
+ }
221
+
222
+ // ============================================================================
223
+ // In-Memory Store (Development)
224
+ // ============================================================================
225
+
24
226
  // Use globalThis to share across esbuild bundles (each API route is bundled separately)
25
227
  const TOKENS_KEY = "__veryfront_oauth_tokens__";
26
228
  // deno-lint-ignore no-explicit-any
@@ -32,14 +234,12 @@ function getKey(userId: string, service: string): string {
32
234
  }
33
235
 
34
236
  /**
35
- * Simple in-memory token store
237
+ * In-memory token store for development
36
238
  *
37
- * NOTE: This is for development only. In production, use:
38
- * - Database (Postgres, SQLite, etc.)
39
- * - KV store (Cloudflare Workers KV, Vercel KV, etc.)
40
- * - Encrypted file storage
239
+ * WARNING: Tokens are lost when the server restarts.
240
+ * For production, configure DATABASE_URL, KV_REST_API_URL, or REDIS_URL.
41
241
  */
42
- export const tokenStore: TokenStore = {
242
+ const inMemoryStore: TokenStore = {
43
243
  getToken(userId: string, service: string): Promise<OAuthToken | null> {
44
244
  const key = getKey(userId, service);
45
245
  return Promise.resolve(tokens.get(key) || null);
@@ -69,24 +269,45 @@ export const tokenStore: TokenStore = {
69
269
  },
70
270
  };
71
271
 
272
+ // ============================================================================
273
+ // Token Store Factory
274
+ // ============================================================================
275
+
72
276
  /**
73
- * Factory function to create a custom token store
277
+ * Factory function to create a custom token store with encryption support
278
+ *
279
+ * @example With Vercel KV
280
+ * ```typescript
281
+ * import { kv } from '@vercel/kv';
282
+ *
283
+ * const kvStore = createTokenStore({
284
+ * get: (key) => kv.get(key),
285
+ * set: (key, value) => kv.set(key, value),
286
+ * delete: (key) => kv.del(key),
287
+ * });
288
+ * ```
289
+ *
290
+ * @example With Redis
291
+ * ```typescript
292
+ * import { createClient } from 'redis';
293
+ * const redis = createClient({ url: process.env.REDIS_URL });
294
+ *
295
+ * const redisStore = createTokenStore({
296
+ * get: (key) => redis.get(key),
297
+ * set: (key, value) => redis.set(key, value),
298
+ * delete: (key) => redis.del(key),
299
+ * });
300
+ * ```
74
301
  */
75
- export function createTokenStore(options: {
76
- get: (key: string) => Promise<string | null>;
77
- set: (key: string, value: string) => Promise<void>;
78
- delete: (key: string) => Promise<void>;
79
- }): TokenStore {
302
+ export function createTokenStore(config: TokenStoreConfig): TokenStore {
80
303
  return {
81
304
  async getToken(userId: string, service: string): Promise<OAuthToken | null> {
82
305
  const key = getKey(userId, service);
83
- const data = await options.get(key);
306
+ const data = await config.get(key);
84
307
  if (!data) return null;
85
- try {
86
- return JSON.parse(data) as OAuthToken;
87
- } catch {
88
- return null;
89
- }
308
+
309
+ // Decrypt if encrypted, otherwise parse as JSON
310
+ return decryptToken(data);
90
311
  },
91
312
 
92
313
  async setToken(
@@ -95,12 +316,14 @@ export function createTokenStore(options: {
95
316
  token: OAuthToken,
96
317
  ): Promise<void> {
97
318
  const key = getKey(userId, service);
98
- await options.set(key, JSON.stringify(token));
319
+ // Encrypt if TOKEN_ENCRYPTION_KEY is set, otherwise store as JSON
320
+ const encrypted = await encryptToken(token);
321
+ await config.set(key, encrypted);
99
322
  },
100
323
 
101
324
  async revokeToken(userId: string, service: string): Promise<void> {
102
325
  const key = getKey(userId, service);
103
- await options.delete(key);
326
+ await config.delete(key);
104
327
  },
105
328
 
106
329
  async isConnected(userId: string, service: string): Promise<boolean> {
@@ -111,3 +334,30 @@ export function createTokenStore(options: {
111
334
  },
112
335
  };
113
336
  }
337
+
338
+ // ============================================================================
339
+ // Default Export (Auto-detects environment)
340
+ // ============================================================================
341
+
342
+ /**
343
+ * Default token store - auto-selects based on environment
344
+ *
345
+ * In development: Uses in-memory storage (tokens lost on restart)
346
+ * In production: Configure via environment variables for persistent storage
347
+ *
348
+ * @see getStorageMode() to check current mode
349
+ * @see lib/token-store-examples.ts for production implementations
350
+ */
351
+ export const tokenStore: TokenStore = inMemoryStore;
352
+
353
+ // Log storage mode in development
354
+ if (typeof process !== "undefined" && process.env?.NODE_ENV !== "production") {
355
+ const mode = getStorageMode();
356
+ if (mode === "memory") {
357
+ console.warn(
358
+ "[Token Store] Using in-memory storage (development mode). " +
359
+ "Tokens will be lost on restart. " +
360
+ "Set DATABASE_URL, KV_REST_API_URL, or REDIS_URL for production."
361
+ );
362
+ }
363
+ }
@@ -0,0 +1,99 @@
1
+ {
2
+ "name": "airtable",
3
+ "displayName": "Airtable",
4
+ "icon": "airtable.svg",
5
+ "description": "Read and write records in Airtable bases and tables",
6
+ "auth": {
7
+ "type": "oauth2",
8
+ "provider": "airtable",
9
+ "authorizationUrl": "https://airtable.com/oauth2/v1/authorize",
10
+ "tokenUrl": "https://airtable.com/oauth2/v1/token",
11
+ "scopes": [
12
+ "data.records:read",
13
+ "data.records:write",
14
+ "schema.bases:read",
15
+ "schema.bases:write"
16
+ ],
17
+ "callbackPath": "/api/auth/airtable/callback",
18
+ "tokenAuthMethod": "basic",
19
+ "pkce": true,
20
+ "requiredApis": [
21
+ {
22
+ "name": "Airtable OAuth Integration",
23
+ "enableUrl": "https://airtable.com/create/oauth"
24
+ }
25
+ ]
26
+ },
27
+ "envVars": [
28
+ {
29
+ "name": "AIRTABLE_CLIENT_ID",
30
+ "description": "Airtable OAuth Client ID (from your OAuth integration)",
31
+ "required": true,
32
+ "sensitive": false,
33
+ "docsUrl": "https://airtable.com/create/oauth"
34
+ },
35
+ {
36
+ "name": "AIRTABLE_CLIENT_SECRET",
37
+ "description": "Airtable OAuth Client Secret",
38
+ "required": true,
39
+ "sensitive": true,
40
+ "docsUrl": "https://airtable.com/create/oauth"
41
+ }
42
+ ],
43
+ "tools": [
44
+ {
45
+ "id": "list-bases",
46
+ "name": "List Bases",
47
+ "description": "List all accessible Airtable bases",
48
+ "requiresWrite": false
49
+ },
50
+ {
51
+ "id": "get-base",
52
+ "name": "Get Base",
53
+ "description": "Get schema information for a specific base",
54
+ "requiresWrite": false
55
+ },
56
+ {
57
+ "id": "list-records",
58
+ "name": "List Records",
59
+ "description": "List records from a table with optional filtering",
60
+ "requiresWrite": false
61
+ },
62
+ {
63
+ "id": "get-record",
64
+ "name": "Get Record",
65
+ "description": "Get a specific record by ID",
66
+ "requiresWrite": false
67
+ },
68
+ {
69
+ "id": "create-record",
70
+ "name": "Create Record",
71
+ "description": "Create a new record in a table",
72
+ "requiresWrite": true
73
+ }
74
+ ],
75
+ "prompts": [
76
+ {
77
+ "id": "query-data",
78
+ "title": "Query my data",
79
+ "prompt": "Search and query records from my Airtable bases. Find specific information across tables.",
80
+ "category": "productivity",
81
+ "icon": "search"
82
+ },
83
+ {
84
+ "id": "add-record",
85
+ "title": "Add a record",
86
+ "prompt": "Create a new record in an Airtable table with the specified field values.",
87
+ "category": "productivity",
88
+ "icon": "plus"
89
+ },
90
+ {
91
+ "id": "analyze-base",
92
+ "title": "Analyze base structure",
93
+ "prompt": "Analyze the structure and schema of an Airtable base, including all tables and their fields.",
94
+ "category": "productivity",
95
+ "icon": "document"
96
+ }
97
+ ],
98
+ "suggestedWith": ["gmail", "slack", "notion"]
99
+ }
@@ -0,0 +1,25 @@
1
+ import { tool } from "veryfront/ai";
2
+ import { z } from "zod";
3
+ import { createRecord } from "../../lib/airtable-client.ts";
4
+
5
+ export default tool({
6
+ id: "create-record",
7
+ description:
8
+ "Create a new record in an Airtable table. Provide field names and values as an object. Returns the created record with its ID.",
9
+ inputSchema: z.object({
10
+ baseId: z.string().describe('The ID of the Airtable base (starts with "app")'),
11
+ tableIdOrName: z.string().describe("The ID or name of the table"),
12
+ fields: z.record(z.unknown()).describe(
13
+ 'Object with field names as keys and their values. Field names must match exactly. Example: { "Name": "John Doe", "Email": "john@example.com", "Status": "Active" }',
14
+ ),
15
+ }),
16
+ async execute({ baseId, tableIdOrName, fields }) {
17
+ const record = await createRecord(baseId, tableIdOrName, fields);
18
+
19
+ return {
20
+ id: record.id,
21
+ createdTime: record.createdTime,
22
+ fields: record.fields,
23
+ };
24
+ },
25
+ });
@@ -0,0 +1,34 @@
1
+ import { tool } from "veryfront/ai";
2
+ import { z } from "zod";
3
+ import { getBase } from "../../lib/airtable-client.ts";
4
+
5
+ export default tool({
6
+ id: "get-base",
7
+ description:
8
+ "Get the schema and structure of an Airtable base, including all tables, fields, and views. Useful for understanding the data model before querying or creating records.",
9
+ inputSchema: z.object({
10
+ baseId: z.string().describe('The ID of the Airtable base (starts with "app")'),
11
+ }),
12
+ async execute({ baseId }) {
13
+ const schema = await getBase(baseId);
14
+
15
+ return {
16
+ tables: schema.tables.map((table) => ({
17
+ id: table.id,
18
+ name: table.name,
19
+ primaryFieldId: table.primaryFieldId,
20
+ fields: table.fields.map((field) => ({
21
+ id: field.id,
22
+ name: field.name,
23
+ type: field.type,
24
+ options: field.options,
25
+ })),
26
+ views: table.views.map((view) => ({
27
+ id: view.id,
28
+ name: view.name,
29
+ type: view.type,
30
+ })),
31
+ })),
32
+ };
33
+ },
34
+ });
@@ -0,0 +1,23 @@
1
+ import { tool } from "veryfront/ai";
2
+ import { z } from "zod";
3
+ import { getRecord } from "../../lib/airtable-client.ts";
4
+
5
+ export default tool({
6
+ id: "get-record",
7
+ description:
8
+ "Get a specific record from an Airtable table by its ID. Returns the full record with all field values.",
9
+ inputSchema: z.object({
10
+ baseId: z.string().describe('The ID of the Airtable base (starts with "app")'),
11
+ tableIdOrName: z.string().describe("The ID or name of the table"),
12
+ recordId: z.string().describe('The ID of the record to retrieve (starts with "rec")'),
13
+ }),
14
+ async execute({ baseId, tableIdOrName, recordId }) {
15
+ const record = await getRecord(baseId, tableIdOrName, recordId);
16
+
17
+ return {
18
+ id: record.id,
19
+ createdTime: record.createdTime,
20
+ fields: record.fields,
21
+ };
22
+ },
23
+ });
@@ -0,0 +1,19 @@
1
+ import { tool } from "veryfront/ai";
2
+ import { z } from "zod";
3
+ import { listBases } from "../../lib/airtable-client.ts";
4
+
5
+ export default tool({
6
+ id: "list-bases",
7
+ description:
8
+ "List all accessible Airtable bases in the connected account. Returns base IDs, names, and permission levels.",
9
+ inputSchema: z.object({}),
10
+ async execute() {
11
+ const bases = await listBases();
12
+
13
+ return bases.map((base) => ({
14
+ id: base.id,
15
+ name: base.name,
16
+ permissionLevel: base.permissionLevel,
17
+ }));
18
+ },
19
+ });
@@ -0,0 +1,47 @@
1
+ import { tool } from "veryfront/ai";
2
+ import { z } from "zod";
3
+ import { listRecords } from "../../lib/airtable-client.ts";
4
+
5
+ export default tool({
6
+ id: "list-records",
7
+ description:
8
+ "List records from an Airtable table. Supports filtering with formulas, sorting, and limiting results. Returns record IDs, creation times, and all field values.",
9
+ inputSchema: z.object({
10
+ baseId: z.string().describe('The ID of the Airtable base (starts with "app")'),
11
+ tableIdOrName: z.string().describe("The ID or name of the table"),
12
+ fields: z.array(z.string()).optional().describe(
13
+ "Specific field names to return (returns all fields if not specified)",
14
+ ),
15
+ filterByFormula: z.string().optional().describe(
16
+ "Airtable formula to filter records (e.g., \"{Status} = 'Done'\")",
17
+ ),
18
+ maxRecords: z.number().min(1).max(100).optional().describe(
19
+ "Maximum number of records to return",
20
+ ),
21
+ sort: z.array(z.object({
22
+ field: z.string().describe("Field name to sort by"),
23
+ direction: z.enum(["asc", "desc"]).describe("Sort direction"),
24
+ })).optional().describe("Array of sort specifications"),
25
+ view: z.string().optional().describe("Name of a view to use for filtering and sorting"),
26
+ }),
27
+ async execute({ baseId, tableIdOrName, fields, filterByFormula, maxRecords, sort, view }) {
28
+ const result = await listRecords(baseId, tableIdOrName, {
29
+ fields,
30
+ filterByFormula,
31
+ maxRecords,
32
+ pageSize: maxRecords,
33
+ sort,
34
+ view,
35
+ });
36
+
37
+ return {
38
+ records: result.records.map((record) => ({
39
+ id: record.id,
40
+ createdTime: record.createdTime,
41
+ fields: record.fields,
42
+ })),
43
+ count: result.records.length,
44
+ hasMore: !!result.offset,
45
+ };
46
+ },
47
+ });
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Airtable OAuth Callback
3
+ */
4
+
5
+ import { airtableConfig, createOAuthCallbackHandler, memoryTokenStore } from "veryfront/oauth";
6
+
7
+ export const GET = createOAuthCallbackHandler(airtableConfig, {
8
+ tokenStore: memoryTokenStore,
9
+ onSuccess: () => "/",
10
+ onError: () => "/",
11
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Airtable OAuth Initiation
3
+ */
4
+
5
+ import { airtableConfig, createOAuthInitHandler, memoryTokenStore } from "veryfront/oauth";
6
+
7
+ export const GET = createOAuthInitHandler(airtableConfig, {
8
+ tokenStore: memoryTokenStore,
9
+ });