veryfront 0.0.49 → 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.
- package/dist/ai/components.js +260 -56
- package/dist/ai/components.js.map +4 -4
- package/dist/ai/index.d.ts +1 -0
- package/dist/ai/index.js +12 -4
- package/dist/ai/index.js.map +2 -2
- package/dist/ai/primitives.js +55 -10
- package/dist/ai/primitives.js.map +3 -3
- package/dist/ai/react.js +140 -1
- package/dist/ai/react.js.map +3 -3
- package/dist/ai/workflow-react.js +458 -0
- package/dist/ai/workflow-react.js.map +7 -0
- package/dist/ai/workflow.js +5422 -0
- package/dist/ai/workflow.js.map +7 -0
- package/dist/cli.js +957 -221
- package/dist/components.js +12 -4
- package/dist/components.js.map +2 -2
- package/dist/config.js +12 -4
- package/dist/config.js.map +2 -2
- package/dist/data.js +12 -4
- package/dist/data.js.map +2 -2
- package/dist/index.js +12 -6
- package/dist/index.js.map +2 -2
- package/dist/integrations/_base/files/SETUP.md +667 -98
- package/dist/integrations/_base/files/app/api/integrations/token-storage/route.ts +14 -0
- package/dist/integrations/_base/files/app/components/ServiceConnections.tsx +2 -1
- package/dist/integrations/_base/files/app/setup/page.tsx +858 -54
- package/dist/integrations/_base/files/lib/token-store-examples.ts +435 -0
- package/dist/integrations/_base/files/lib/token-store.ts +273 -23
- package/dist/integrations/airtable/connector.json +99 -0
- package/dist/integrations/airtable/files/ai/tools/create-record.ts +25 -0
- package/dist/integrations/airtable/files/ai/tools/get-base.ts +34 -0
- package/dist/integrations/airtable/files/ai/tools/get-record.ts +23 -0
- package/dist/integrations/airtable/files/ai/tools/list-bases.ts +19 -0
- package/dist/integrations/airtable/files/ai/tools/list-records.ts +47 -0
- package/dist/integrations/airtable/files/app/api/auth/airtable/callback/route.ts +11 -0
- package/dist/integrations/airtable/files/app/api/auth/airtable/route.ts +9 -0
- package/dist/integrations/airtable/files/lib/airtable-client.ts +244 -0
- package/dist/integrations/airtable/files/lib/token-store.ts +5 -0
- package/dist/integrations/anthropic/README.md +181 -0
- package/dist/integrations/anthropic/connector.json +88 -0
- package/dist/integrations/anthropic/files/_env.example +4 -0
- package/dist/integrations/anthropic/files/ai/tools/get-organization.ts +36 -0
- package/dist/integrations/anthropic/files/ai/tools/get-usage.ts +100 -0
- package/dist/integrations/anthropic/files/ai/tools/list-api-keys.ts +64 -0
- package/dist/integrations/anthropic/files/ai/tools/list-members.ts +65 -0
- package/dist/integrations/anthropic/files/ai/tools/list-workspaces.ts +35 -0
- package/dist/integrations/anthropic/files/lib/anthropic-admin-client.ts +264 -0
- package/dist/integrations/asana/connector.json +85 -0
- package/dist/integrations/asana/files/_env.example +4 -0
- package/dist/integrations/asana/files/ai/tools/create-task.ts +34 -0
- package/dist/integrations/asana/files/ai/tools/get-task.ts +26 -0
- package/dist/integrations/asana/files/ai/tools/list-projects.ts +26 -0
- package/dist/integrations/asana/files/ai/tools/list-tasks.ts +50 -0
- package/dist/integrations/asana/files/ai/tools/update-task.ts +36 -0
- package/dist/integrations/asana/files/app/api/auth/asana/callback/route.ts +11 -0
- package/dist/integrations/asana/files/app/api/auth/asana/route.ts +7 -0
- package/dist/integrations/asana/files/lib/asana-client.ts +162 -0
- package/dist/integrations/asana/files/lib/token-store.ts +11 -0
- package/dist/integrations/aws/connector.json +72 -0
- package/dist/integrations/aws/files/_env.example +10 -0
- package/dist/integrations/aws/files/ai/tools/get-s3-object.ts +62 -0
- package/dist/integrations/aws/files/ai/tools/list-ec2-instances.ts +56 -0
- package/dist/integrations/aws/files/ai/tools/list-lambda-functions.ts +57 -0
- package/dist/integrations/aws/files/ai/tools/list-s3-buckets.ts +44 -0
- package/dist/integrations/aws/files/ai/tools/list-s3-objects.ts +58 -0
- package/dist/integrations/aws/files/lib/aws-client.ts +255 -0
- package/dist/integrations/bitbucket/connector.json +85 -0
- package/dist/integrations/bitbucket/files/_env.example +9 -0
- package/dist/integrations/bitbucket/files/ai/tools/create-pull-request.ts +83 -0
- package/dist/integrations/bitbucket/files/ai/tools/list-issues.ts +112 -0
- package/dist/integrations/bitbucket/files/ai/tools/list-pull-requests.ts +91 -0
- package/dist/integrations/bitbucket/files/ai/tools/list-repositories.ts +78 -0
- package/dist/integrations/bitbucket/files/app/api/auth/bitbucket/callback/route.ts +11 -0
- package/dist/integrations/bitbucket/files/app/api/auth/bitbucket/route.ts +9 -0
- package/dist/integrations/bitbucket/files/lib/bitbucket-client.ts +316 -0
- package/dist/integrations/bitbucket/files/lib/token-store.ts +5 -0
- package/dist/integrations/box/connector.json +85 -0
- package/dist/integrations/box/files/_env.example +4 -0
- package/dist/integrations/box/files/ai/tools/create-folder.ts +28 -0
- package/dist/integrations/box/files/ai/tools/get-file.ts +29 -0
- package/dist/integrations/box/files/ai/tools/list-files.ts +33 -0
- package/dist/integrations/box/files/ai/tools/search-files.ts +35 -0
- package/dist/integrations/box/files/ai/tools/upload-file.ts +32 -0
- package/dist/integrations/box/files/app/api/auth/box/callback/route.ts +11 -0
- package/dist/integrations/box/files/app/api/auth/box/route.ts +7 -0
- package/dist/integrations/box/files/lib/box-client.ts +280 -0
- package/dist/integrations/box/files/lib/token-store.ts +11 -0
- package/dist/integrations/calendar/files/app/api/auth/calendar/callback/route.ts +7 -110
- package/dist/integrations/calendar/files/app/api/auth/calendar/route.ts +5 -25
- package/dist/integrations/calendar/files/lib/token-store.ts +2 -110
- package/dist/integrations/clickup/connector.json +85 -0
- package/dist/integrations/clickup/files/_env.example +4 -0
- package/dist/integrations/clickup/files/ai/tools/create-task.ts +64 -0
- package/dist/integrations/clickup/files/ai/tools/get-task.ts +59 -0
- package/dist/integrations/clickup/files/ai/tools/list-lists.ts +109 -0
- package/dist/integrations/clickup/files/ai/tools/list-tasks.ts +95 -0
- package/dist/integrations/clickup/files/ai/tools/update-task.ts +85 -0
- package/dist/integrations/clickup/files/app/api/auth/clickup/callback/route.ts +11 -0
- package/dist/integrations/clickup/files/app/api/auth/clickup/route.ts +7 -0
- package/dist/integrations/clickup/files/lib/clickup-client.ts +439 -0
- package/dist/integrations/clickup/files/lib/token-store.ts +11 -0
- package/dist/integrations/confluence/README.md +246 -0
- package/dist/integrations/confluence/connector.json +104 -0
- package/dist/integrations/confluence/files/_env.example +4 -0
- package/dist/integrations/confluence/files/ai/tools/create-page.ts +43 -0
- package/dist/integrations/confluence/files/ai/tools/get-page.ts +30 -0
- package/dist/integrations/confluence/files/ai/tools/list-spaces.ts +31 -0
- package/dist/integrations/confluence/files/ai/tools/search-content.ts +38 -0
- package/dist/integrations/confluence/files/ai/tools/update-page.ts +45 -0
- package/dist/integrations/confluence/files/app/api/auth/confluence/callback/route.ts +11 -0
- package/dist/integrations/confluence/files/app/api/auth/confluence/route.ts +9 -0
- package/dist/integrations/confluence/files/lib/confluence-client.ts +281 -0
- package/dist/integrations/confluence/files/lib/token-store.ts +5 -0
- package/dist/integrations/discord/connector.json +100 -0
- package/dist/integrations/discord/files/_env.example +12 -0
- package/dist/integrations/discord/files/ai/tools/get-messages.ts +55 -0
- package/dist/integrations/discord/files/ai/tools/get-user.ts +32 -0
- package/dist/integrations/discord/files/ai/tools/list-channels.ts +32 -0
- package/dist/integrations/discord/files/ai/tools/list-guilds.ts +24 -0
- package/dist/integrations/discord/files/ai/tools/send-message.ts +33 -0
- package/dist/integrations/discord/files/app/api/auth/discord/callback/route.ts +11 -0
- package/dist/integrations/discord/files/app/api/auth/discord/route.ts +9 -0
- package/dist/integrations/discord/files/lib/discord-client.ts +273 -0
- package/dist/integrations/discord/files/lib/token-store.ts +5 -0
- package/dist/integrations/docs-google/connector.json +101 -0
- package/dist/integrations/docs-google/files/_env.example +8 -0
- package/dist/integrations/docs-google/files/ai/tools/create-document.ts +46 -0
- package/dist/integrations/docs-google/files/ai/tools/get-document.ts +46 -0
- package/dist/integrations/docs-google/files/ai/tools/list-documents.ts +42 -0
- package/dist/integrations/docs-google/files/ai/tools/search-documents.ts +38 -0
- package/dist/integrations/docs-google/files/ai/tools/update-document.ts +131 -0
- package/dist/integrations/docs-google/files/app/api/auth/docs-google/callback/route.ts +11 -0
- package/dist/integrations/docs-google/files/app/api/auth/docs-google/route.ts +9 -0
- package/dist/integrations/docs-google/files/lib/docs-client.ts +582 -0
- package/dist/integrations/docs-google/files/lib/token-store.ts +5 -0
- package/dist/integrations/drive/connector.json +134 -0
- package/dist/integrations/drive/files/_env.example +9 -0
- package/dist/integrations/drive/files/ai/tools/create-folder.ts +47 -0
- package/dist/integrations/drive/files/ai/tools/get-file.ts +55 -0
- package/dist/integrations/drive/files/ai/tools/list-files.ts +78 -0
- package/dist/integrations/drive/files/ai/tools/search-files.ts +79 -0
- package/dist/integrations/drive/files/ai/tools/upload-file.ts +59 -0
- package/dist/integrations/drive/files/app/api/auth/drive/callback/route.ts +11 -0
- package/dist/integrations/drive/files/app/api/auth/drive/route.ts +9 -0
- package/dist/integrations/drive/files/lib/drive-client.ts +359 -0
- package/dist/integrations/drive/files/lib/token-store.ts +113 -0
- package/dist/integrations/dropbox/connector.json +107 -0
- package/dist/integrations/dropbox/files/_env.example +24 -0
- package/dist/integrations/dropbox/files/ai/tools/get-account.ts +58 -0
- package/dist/integrations/dropbox/files/ai/tools/get-file.ts +61 -0
- package/dist/integrations/dropbox/files/ai/tools/list-files.ts +56 -0
- package/dist/integrations/dropbox/files/ai/tools/search-files.ts +70 -0
- package/dist/integrations/dropbox/files/ai/tools/upload-file.ts +48 -0
- package/dist/integrations/dropbox/files/app/api/auth/dropbox/callback/route.ts +11 -0
- package/dist/integrations/dropbox/files/app/api/auth/dropbox/route.ts +9 -0
- package/dist/integrations/dropbox/files/lib/dropbox-client.ts +397 -0
- package/dist/integrations/dropbox/files/lib/token-store.ts +5 -0
- package/dist/integrations/figma/INTEGRATION_SUMMARY.md +436 -0
- package/dist/integrations/figma/README.md +287 -0
- package/dist/integrations/figma/connector.json +100 -0
- package/dist/integrations/figma/files/_env.example +5 -0
- package/dist/integrations/figma/files/ai/tools/get-comments.ts +72 -0
- package/dist/integrations/figma/files/ai/tools/get-file.ts +54 -0
- package/dist/integrations/figma/files/ai/tools/list-files.ts +39 -0
- package/dist/integrations/figma/files/ai/tools/list-projects.ts +69 -0
- package/dist/integrations/figma/files/ai/tools/post-comment.ts +54 -0
- package/dist/integrations/figma/files/app/api/auth/figma/callback/route.ts +11 -0
- package/dist/integrations/figma/files/app/api/auth/figma/route.ts +9 -0
- package/dist/integrations/figma/files/lib/figma-client.ts +355 -0
- package/dist/integrations/figma/files/lib/token-store.ts +5 -0
- package/dist/integrations/figma/files/lib/types.ts +503 -0
- package/dist/integrations/freshdesk/connector.json +85 -0
- package/dist/integrations/freshdesk/files/_env.example +4 -0
- package/dist/integrations/freshdesk/files/ai/tools/create-ticket.ts +60 -0
- package/dist/integrations/freshdesk/files/ai/tools/get-ticket.ts +46 -0
- package/dist/integrations/freshdesk/files/ai/tools/list-contacts.ts +37 -0
- package/dist/integrations/freshdesk/files/ai/tools/list-tickets.ts +59 -0
- package/dist/integrations/freshdesk/files/ai/tools/update-ticket.ts +61 -0
- package/dist/integrations/freshdesk/files/app/api/auth/freshdesk/callback/route.ts +11 -0
- package/dist/integrations/freshdesk/files/app/api/auth/freshdesk/route.ts +7 -0
- package/dist/integrations/freshdesk/files/lib/freshdesk-client.ts +178 -0
- package/dist/integrations/freshdesk/files/lib/token-store.ts +11 -0
- package/dist/integrations/github/files/app/api/auth/github/callback/route.ts +6 -127
- package/dist/integrations/github/files/app/api/auth/github/route.ts +4 -24
- package/dist/integrations/github/files/lib/token-store.ts +2 -110
- package/dist/integrations/gitlab/connector.json +100 -0
- package/dist/integrations/gitlab/files/_env.example +7 -0
- package/dist/integrations/gitlab/files/ai/tools/create-issue.ts +49 -0
- package/dist/integrations/gitlab/files/ai/tools/get-issue.ts +56 -0
- package/dist/integrations/gitlab/files/ai/tools/list-merge-requests.ts +75 -0
- package/dist/integrations/gitlab/files/ai/tools/list-projects.ts +51 -0
- package/dist/integrations/gitlab/files/ai/tools/search-issues.ts +67 -0
- package/dist/integrations/gitlab/files/app/api/auth/gitlab/callback/route.ts +11 -0
- package/dist/integrations/gitlab/files/app/api/auth/gitlab/route.ts +9 -0
- package/dist/integrations/gitlab/files/lib/gitlab-client.ts +366 -0
- package/dist/integrations/gitlab/files/lib/token-store.ts +5 -0
- package/dist/integrations/gmail/files/app/api/auth/gmail/callback/route.ts +7 -108
- package/dist/integrations/gmail/files/app/api/auth/gmail/route.ts +5 -23
- package/dist/integrations/gmail/files/lib/gmail-client.ts +16 -55
- package/dist/integrations/gmail/files/lib/token-store.ts +4 -109
- package/dist/integrations/hubspot/connector.json +98 -0
- package/dist/integrations/hubspot/files/_env.example +5 -0
- package/dist/integrations/hubspot/files/ai/tools/create-contact.ts +41 -0
- package/dist/integrations/hubspot/files/ai/tools/create-deal.ts +41 -0
- package/dist/integrations/hubspot/files/ai/tools/get-contact.ts +39 -0
- package/dist/integrations/hubspot/files/ai/tools/list-contacts.ts +43 -0
- package/dist/integrations/hubspot/files/ai/tools/list-deals.ts +41 -0
- package/dist/integrations/hubspot/files/app/api/auth/hubspot/callback/route.ts +11 -0
- package/dist/integrations/hubspot/files/app/api/auth/hubspot/route.ts +9 -0
- package/dist/integrations/hubspot/files/lib/hubspot-client.ts +393 -0
- package/dist/integrations/hubspot/files/lib/token-store.ts +5 -0
- package/dist/integrations/intercom/connector.json +85 -0
- package/dist/integrations/intercom/files/_env.example +4 -0
- package/dist/integrations/intercom/files/ai/tools/get-contact.ts +35 -0
- package/dist/integrations/intercom/files/ai/tools/get-conversation.ts +55 -0
- package/dist/integrations/intercom/files/ai/tools/list-contacts.ts +35 -0
- package/dist/integrations/intercom/files/ai/tools/list-conversations.ts +49 -0
- package/dist/integrations/intercom/files/ai/tools/send-message.ts +34 -0
- package/dist/integrations/intercom/files/app/api/auth/intercom/callback/route.ts +11 -0
- package/dist/integrations/intercom/files/app/api/auth/intercom/route.ts +7 -0
- package/dist/integrations/intercom/files/lib/intercom-client.ts +308 -0
- package/dist/integrations/intercom/files/lib/token-store.ts +11 -0
- package/dist/integrations/jira/connector.json +109 -0
- package/dist/integrations/jira/files/ai/tools/create-issue.ts +47 -0
- package/dist/integrations/jira/files/ai/tools/get-issue.ts +57 -0
- package/dist/integrations/jira/files/ai/tools/list-projects.ts +30 -0
- package/dist/integrations/jira/files/ai/tools/search-issues.ts +49 -0
- package/dist/integrations/jira/files/ai/tools/update-issue.ts +81 -0
- package/dist/integrations/jira/files/app/api/auth/jira/callback/route.ts +11 -0
- package/dist/integrations/jira/files/app/api/auth/jira/route.ts +9 -0
- package/dist/integrations/jira/files/lib/jira-client.ts +338 -0
- package/dist/integrations/jira/files/lib/token-store.ts +5 -0
- package/dist/integrations/linear/connector.json +100 -0
- package/dist/integrations/linear/files/_env.example +6 -0
- package/dist/integrations/linear/files/ai/tools/create-issue.ts +71 -0
- package/dist/integrations/linear/files/ai/tools/get-issue.ts +55 -0
- package/dist/integrations/linear/files/ai/tools/list-projects.ts +43 -0
- package/dist/integrations/linear/files/ai/tools/search-issues.ts +54 -0
- package/dist/integrations/linear/files/ai/tools/update-issue.ts +71 -0
- package/dist/integrations/linear/files/app/api/auth/linear/callback/route.ts +11 -0
- package/dist/integrations/linear/files/app/api/auth/linear/route.ts +9 -0
- package/dist/integrations/linear/files/lib/linear-client.ts +464 -0
- package/dist/integrations/linear/files/lib/token-store.ts +5 -0
- package/dist/integrations/mailchimp/connector.json +85 -0
- package/dist/integrations/mailchimp/files/_env.example +4 -0
- package/dist/integrations/mailchimp/files/ai/tools/get-campaign.ts +45 -0
- package/dist/integrations/mailchimp/files/ai/tools/get-list.ts +51 -0
- package/dist/integrations/mailchimp/files/ai/tools/list-campaigns.ts +46 -0
- package/dist/integrations/mailchimp/files/ai/tools/list-lists.ts +46 -0
- package/dist/integrations/mailchimp/files/ai/tools/list-members.ts +58 -0
- package/dist/integrations/mailchimp/files/app/api/auth/mailchimp/callback/route.ts +11 -0
- package/dist/integrations/mailchimp/files/app/api/auth/mailchimp/route.ts +7 -0
- package/dist/integrations/mailchimp/files/lib/mailchimp-client.ts +267 -0
- package/dist/integrations/mailchimp/files/lib/token-store.ts +11 -0
- package/dist/integrations/mixpanel/connector.json +96 -0
- package/dist/integrations/mixpanel/files/_env.example +11 -0
- package/dist/integrations/mixpanel/files/ai/tools/get-funnel.ts +46 -0
- package/dist/integrations/mixpanel/files/ai/tools/get-retention.ts +64 -0
- package/dist/integrations/mixpanel/files/ai/tools/list-cohorts.ts +46 -0
- package/dist/integrations/mixpanel/files/ai/tools/query-events.ts +43 -0
- package/dist/integrations/mixpanel/files/ai/tools/track-event.ts +41 -0
- package/dist/integrations/mixpanel/files/lib/mixpanel-client.ts +319 -0
- package/dist/integrations/mixpanel/files/lib/token-store.ts +43 -0
- package/dist/integrations/monday/connector.json +85 -0
- package/dist/integrations/monday/files/_env.example +4 -0
- package/dist/integrations/monday/files/ai/tools/create-item.ts +36 -0
- package/dist/integrations/monday/files/ai/tools/get-item.ts +31 -0
- package/dist/integrations/monday/files/ai/tools/list-boards.ts +29 -0
- package/dist/integrations/monday/files/ai/tools/list-items.ts +36 -0
- package/dist/integrations/monday/files/ai/tools/update-item.ts +36 -0
- package/dist/integrations/monday/files/app/api/auth/monday/callback/route.ts +11 -0
- package/dist/integrations/monday/files/app/api/auth/monday/route.ts +7 -0
- package/dist/integrations/monday/files/lib/monday-client.ts +329 -0
- package/dist/integrations/monday/files/lib/token-store.ts +11 -0
- package/dist/integrations/neon/connector.json +89 -0
- package/dist/integrations/neon/files/_env.example +6 -0
- package/dist/integrations/neon/files/ai/tools/describe-table.ts +38 -0
- package/dist/integrations/neon/files/ai/tools/list-branches.ts +35 -0
- package/dist/integrations/neon/files/ai/tools/list-projects.ts +31 -0
- package/dist/integrations/neon/files/ai/tools/list-tables.ts +49 -0
- package/dist/integrations/neon/files/ai/tools/query-database.ts +33 -0
- package/dist/integrations/neon/files/app/api/auth/neon/route.ts +51 -0
- package/dist/integrations/neon/files/lib/neon-client.ts +294 -0
- package/dist/integrations/neon/files/lib/token-store.ts +29 -0
- package/dist/integrations/notion/connector.json +87 -0
- package/dist/integrations/notion/files/_env.example +6 -0
- package/dist/integrations/notion/files/ai/tools/create-page.ts +32 -0
- package/dist/integrations/notion/files/ai/tools/query-database.ts +44 -0
- package/dist/integrations/notion/files/ai/tools/read-page.ts +34 -0
- package/dist/integrations/notion/files/ai/tools/search-notion.ts +51 -0
- package/dist/integrations/notion/files/app/api/auth/notion/callback/route.ts +11 -0
- package/dist/integrations/notion/files/app/api/auth/notion/route.ts +9 -0
- package/dist/integrations/notion/files/lib/notion-client.ts +218 -0
- package/dist/integrations/notion/files/lib/token-store.ts +5 -0
- package/dist/integrations/onedrive/connector.json +100 -0
- package/dist/integrations/onedrive/files/_env.example +23 -0
- package/dist/integrations/onedrive/files/ai/tools/download-file.ts +38 -0
- package/dist/integrations/onedrive/files/ai/tools/list-files.ts +63 -0
- package/dist/integrations/onedrive/files/ai/tools/search-files.ts +59 -0
- package/dist/integrations/onedrive/files/ai/tools/upload-file.ts +43 -0
- package/dist/integrations/onedrive/files/app/api/auth/onedrive/callback/route.ts +11 -0
- package/dist/integrations/onedrive/files/app/api/auth/onedrive/route.ts +9 -0
- package/dist/integrations/onedrive/files/lib/onedrive-client.ts +314 -0
- package/dist/integrations/onedrive/files/lib/token-store.ts +5 -0
- package/dist/integrations/outlook/README.md +308 -0
- package/dist/integrations/outlook/connector.json +98 -0
- package/dist/integrations/outlook/files/_env.example +8 -0
- package/dist/integrations/outlook/files/ai/tools/get-email.ts +47 -0
- package/dist/integrations/outlook/files/ai/tools/list-emails.ts +46 -0
- package/dist/integrations/outlook/files/ai/tools/list-folders.ts +22 -0
- package/dist/integrations/outlook/files/ai/tools/search-emails.ts +41 -0
- package/dist/integrations/outlook/files/ai/tools/send-email.ts +41 -0
- package/dist/integrations/outlook/files/app/api/auth/outlook/callback/route.ts +11 -0
- package/dist/integrations/outlook/files/app/api/auth/outlook/route.ts +9 -0
- package/dist/integrations/outlook/files/lib/outlook-client.ts +204 -0
- package/dist/integrations/outlook/files/lib/token-store.ts +5 -0
- package/dist/integrations/pipedrive/connector.json +85 -0
- package/dist/integrations/pipedrive/files/_env.example +4 -0
- package/dist/integrations/pipedrive/files/ai/tools/create-deal.ts +44 -0
- package/dist/integrations/pipedrive/files/ai/tools/get-deal.ts +34 -0
- package/dist/integrations/pipedrive/files/ai/tools/list-deals.ts +40 -0
- package/dist/integrations/pipedrive/files/ai/tools/list-persons.ts +33 -0
- package/dist/integrations/pipedrive/files/ai/tools/update-deal.ts +46 -0
- package/dist/integrations/pipedrive/files/app/api/auth/pipedrive/callback/route.ts +11 -0
- package/dist/integrations/pipedrive/files/app/api/auth/pipedrive/route.ts +7 -0
- package/dist/integrations/pipedrive/files/lib/pipedrive-client.ts +259 -0
- package/dist/integrations/pipedrive/files/lib/token-store.ts +11 -0
- package/dist/integrations/posthog/connector.json +84 -0
- package/dist/integrations/posthog/files/_env.example +6 -0
- package/dist/integrations/posthog/files/ai/tools/capture-event.ts +37 -0
- package/dist/integrations/posthog/files/ai/tools/get-trends.ts +44 -0
- package/dist/integrations/posthog/files/ai/tools/list-feature-flags.ts +38 -0
- package/dist/integrations/posthog/files/ai/tools/list-persons.ts +32 -0
- package/dist/integrations/posthog/files/lib/posthog-client.ts +286 -0
- package/dist/integrations/posthog/files/lib/token-store.ts +21 -0
- package/dist/integrations/quickbooks/connector.json +85 -0
- package/dist/integrations/quickbooks/files/_env.example +4 -0
- package/dist/integrations/quickbooks/files/ai/tools/create-invoice.ts +48 -0
- package/dist/integrations/quickbooks/files/ai/tools/get-customer.ts +36 -0
- package/dist/integrations/quickbooks/files/ai/tools/get-invoice.ts +46 -0
- package/dist/integrations/quickbooks/files/ai/tools/list-customers.ts +37 -0
- package/dist/integrations/quickbooks/files/ai/tools/list-invoices.ts +40 -0
- package/dist/integrations/quickbooks/files/app/api/auth/quickbooks/callback/route.ts +11 -0
- package/dist/integrations/quickbooks/files/app/api/auth/quickbooks/route.ts +7 -0
- package/dist/integrations/quickbooks/files/lib/quickbooks-client.ts +252 -0
- package/dist/integrations/quickbooks/files/lib/token-store.ts +11 -0
- package/dist/integrations/salesforce/connector.json +104 -0
- package/dist/integrations/salesforce/files/ai/tools/create-lead.ts +101 -0
- package/dist/integrations/salesforce/files/ai/tools/get-account.ts +53 -0
- package/dist/integrations/salesforce/files/ai/tools/list-accounts.ts +50 -0
- package/dist/integrations/salesforce/files/ai/tools/list-contacts.ts +54 -0
- package/dist/integrations/salesforce/files/ai/tools/list-opportunities.ts +55 -0
- package/dist/integrations/salesforce/files/app/api/auth/salesforce/callback/route.ts +11 -0
- package/dist/integrations/salesforce/files/app/api/auth/salesforce/route.ts +9 -0
- package/dist/integrations/salesforce/files/lib/salesforce-client.ts +539 -0
- package/dist/integrations/salesforce/files/lib/token-store.ts +5 -0
- package/dist/integrations/sentry/connector.json +84 -0
- package/dist/integrations/sentry/files/_env.example +6 -0
- package/dist/integrations/sentry/files/ai/tools/get-issue.ts +66 -0
- package/dist/integrations/sentry/files/ai/tools/list-issues.ts +57 -0
- package/dist/integrations/sentry/files/ai/tools/list-projects.ts +32 -0
- package/dist/integrations/sentry/files/ai/tools/resolve-issue.ts +28 -0
- package/dist/integrations/sentry/files/lib/sentry-client.ts +268 -0
- package/dist/integrations/sentry/files/lib/token-store.ts +29 -0
- package/dist/integrations/servicenow/connector.json +66 -0
- package/dist/integrations/servicenow/files/_env.example +5 -0
- package/dist/integrations/servicenow/files/ai/tools/create-incident.ts +58 -0
- package/dist/integrations/servicenow/files/ai/tools/get-incident.ts +59 -0
- package/dist/integrations/servicenow/files/ai/tools/list-incidents.ts +72 -0
- package/dist/integrations/servicenow/files/ai/tools/search-knowledge.ts +48 -0
- package/dist/integrations/servicenow/files/ai/tools/update-incident.ts +60 -0
- package/dist/integrations/servicenow/files/app/api/auth/servicenow/callback/route.ts +89 -0
- package/dist/integrations/servicenow/files/app/api/auth/servicenow/route.ts +42 -0
- package/dist/integrations/servicenow/files/lib/servicenow-client.ts +239 -0
- package/dist/integrations/servicenow/files/lib/token-store.ts +42 -0
- package/dist/integrations/sharepoint/connector.json +99 -0
- package/dist/integrations/sharepoint/files/ai/tools/get-file.ts +93 -0
- package/dist/integrations/sharepoint/files/ai/tools/get-site.ts +51 -0
- package/dist/integrations/sharepoint/files/ai/tools/list-files.ts +63 -0
- package/dist/integrations/sharepoint/files/ai/tools/list-sites.ts +28 -0
- package/dist/integrations/sharepoint/files/ai/tools/upload-file.ts +72 -0
- package/dist/integrations/sharepoint/files/app/api/auth/sharepoint/callback/route.ts +11 -0
- package/dist/integrations/sharepoint/files/app/api/auth/sharepoint/route.ts +9 -0
- package/dist/integrations/sharepoint/files/lib/sharepoint-client.ts +420 -0
- package/dist/integrations/sharepoint/files/lib/token-store.ts +5 -0
- package/dist/integrations/sheets/README.md +331 -0
- package/dist/integrations/sheets/connector.json +99 -0
- package/dist/integrations/sheets/files/_env.example +8 -0
- package/dist/integrations/sheets/files/ai/tools/create-spreadsheet.ts +85 -0
- package/dist/integrations/sheets/files/ai/tools/get-spreadsheet.ts +39 -0
- package/dist/integrations/sheets/files/ai/tools/list-spreadsheets.ts +41 -0
- package/dist/integrations/sheets/files/ai/tools/read-range.ts +35 -0
- package/dist/integrations/sheets/files/ai/tools/write-range.ts +51 -0
- package/dist/integrations/sheets/files/app/api/auth/sheets/callback/route.ts +11 -0
- package/dist/integrations/sheets/files/app/api/auth/sheets/route.ts +9 -0
- package/dist/integrations/sheets/files/lib/sheets-client.ts +425 -0
- package/dist/integrations/sheets/files/lib/token-store.ts +5 -0
- package/dist/integrations/shopify/connector.json +99 -0
- package/dist/integrations/shopify/files/_env.example +5 -0
- package/dist/integrations/shopify/files/ai/tools/get-order.ts +49 -0
- package/dist/integrations/shopify/files/ai/tools/get-product.ts +39 -0
- package/dist/integrations/shopify/files/ai/tools/list-customers.ts +40 -0
- package/dist/integrations/shopify/files/ai/tools/list-orders.ts +52 -0
- package/dist/integrations/shopify/files/ai/tools/list-products.ts +39 -0
- package/dist/integrations/shopify/files/app/api/auth/shopify/callback/route.ts +11 -0
- package/dist/integrations/shopify/files/app/api/auth/shopify/route.ts +7 -0
- package/dist/integrations/shopify/files/lib/shopify-client.ts +198 -0
- package/dist/integrations/shopify/files/lib/token-store.ts +11 -0
- package/dist/integrations/slack/files/app/api/auth/slack/callback/route.ts +6 -127
- package/dist/integrations/slack/files/app/api/auth/slack/route.ts +4 -24
- package/dist/integrations/slack/files/lib/token-store.ts +2 -110
- package/dist/integrations/snowflake/connector.json +151 -0
- package/dist/integrations/snowflake/files/_env.example +16 -0
- package/dist/integrations/snowflake/files/ai/tools/describe-table.ts +57 -0
- package/dist/integrations/snowflake/files/ai/tools/list-databases.ts +34 -0
- package/dist/integrations/snowflake/files/ai/tools/list-schemas.ts +40 -0
- package/dist/integrations/snowflake/files/ai/tools/list-tables.ts +49 -0
- package/dist/integrations/snowflake/files/ai/tools/run-query.ts +119 -0
- package/dist/integrations/snowflake/files/lib/snowflake-client.ts +389 -0
- package/dist/integrations/snowflake/files/lib/token-store.ts +77 -0
- package/dist/integrations/stripe/connector.json +97 -0
- package/dist/integrations/stripe/files/_env.example +6 -0
- package/dist/integrations/stripe/files/ai/tools/get-balance.ts +28 -0
- package/dist/integrations/stripe/files/ai/tools/get-customer.ts +26 -0
- package/dist/integrations/stripe/files/ai/tools/list-customers.ts +42 -0
- package/dist/integrations/stripe/files/ai/tools/list-payments.ts +45 -0
- package/dist/integrations/stripe/files/ai/tools/list-subscriptions.ts +67 -0
- package/dist/integrations/stripe/files/app/api/auth/stripe/route.ts +71 -0
- package/dist/integrations/stripe/files/lib/stripe-client.ts +376 -0
- package/dist/integrations/stripe/files/lib/token-store.ts +21 -0
- package/dist/integrations/supabase/connector.json +101 -0
- package/dist/integrations/supabase/files/_env.example +6 -0
- package/dist/integrations/supabase/files/ai/tools/delete-row.ts +77 -0
- package/dist/integrations/supabase/files/ai/tools/insert-row.ts +35 -0
- package/dist/integrations/supabase/files/ai/tools/list-tables.ts +60 -0
- package/dist/integrations/supabase/files/ai/tools/query-table.ts +48 -0
- package/dist/integrations/supabase/files/ai/tools/update-row.ts +64 -0
- package/dist/integrations/supabase/files/app/api/auth/supabase/route.ts +91 -0
- package/dist/integrations/supabase/files/lib/supabase-client.ts +296 -0
- package/dist/integrations/supabase/files/lib/token-store.ts +47 -0
- package/dist/integrations/teams/README.md +256 -0
- package/dist/integrations/teams/connector.json +99 -0
- package/dist/integrations/teams/files/ai/tools/get-messages.ts +55 -0
- package/dist/integrations/teams/files/ai/tools/list-channels.ts +28 -0
- package/dist/integrations/teams/files/ai/tools/list-chats.ts +41 -0
- package/dist/integrations/teams/files/ai/tools/list-teams.ts +27 -0
- package/dist/integrations/teams/files/ai/tools/send-message.ts +61 -0
- package/dist/integrations/teams/files/app/api/auth/teams/callback/route.ts +11 -0
- package/dist/integrations/teams/files/app/api/auth/teams/route.ts +9 -0
- package/dist/integrations/teams/files/lib/teams-client.ts +345 -0
- package/dist/integrations/teams/files/lib/token-store.ts +5 -0
- package/dist/integrations/trello/connector.json +85 -0
- package/dist/integrations/trello/files/_env.example +4 -0
- package/dist/integrations/trello/files/ai/tools/create-card.ts +54 -0
- package/dist/integrations/trello/files/ai/tools/get-card.ts +33 -0
- package/dist/integrations/trello/files/ai/tools/list-boards.ts +29 -0
- package/dist/integrations/trello/files/ai/tools/list-cards.ts +52 -0
- package/dist/integrations/trello/files/ai/tools/update-card.ts +65 -0
- package/dist/integrations/trello/files/app/api/auth/trello/callback/route.ts +11 -0
- package/dist/integrations/trello/files/app/api/auth/trello/route.ts +7 -0
- package/dist/integrations/trello/files/lib/token-store.ts +11 -0
- package/dist/integrations/trello/files/lib/trello-client.ts +202 -0
- package/dist/integrations/twilio/connector.json +146 -0
- package/dist/integrations/twilio/files/_env.example +14 -0
- package/dist/integrations/twilio/files/ai/tools/get-message.ts +58 -0
- package/dist/integrations/twilio/files/ai/tools/list-calls.ts +129 -0
- package/dist/integrations/twilio/files/ai/tools/list-messages.ts +97 -0
- package/dist/integrations/twilio/files/ai/tools/send-sms.ts +75 -0
- package/dist/integrations/twilio/files/ai/tools/send-whatsapp.ts +81 -0
- package/dist/integrations/twilio/files/lib/token-store.ts +60 -0
- package/dist/integrations/twilio/files/lib/twilio-client.ts +375 -0
- package/dist/integrations/twitter/connector.json +87 -0
- package/dist/integrations/twitter/files/_env.example +6 -0
- package/dist/integrations/twitter/files/ai/tools/get-timeline.ts +59 -0
- package/dist/integrations/twitter/files/ai/tools/post-tweet.ts +49 -0
- package/dist/integrations/twitter/files/ai/tools/search-tweets.ts +71 -0
- package/dist/integrations/twitter/files/app/api/auth/twitter/callback/route.ts +11 -0
- package/dist/integrations/twitter/files/app/api/auth/twitter/route.ts +9 -0
- package/dist/integrations/twitter/files/lib/token-store.ts +5 -0
- package/dist/integrations/twitter/files/lib/twitter-client.ts +236 -0
- package/dist/integrations/webex/connector.json +85 -0
- package/dist/integrations/webex/files/_env.example +4 -0
- package/dist/integrations/webex/files/ai/tools/create-meeting.ts +69 -0
- package/dist/integrations/webex/files/ai/tools/get-meeting.ts +31 -0
- package/dist/integrations/webex/files/ai/tools/list-meetings.ts +44 -0
- package/dist/integrations/webex/files/ai/tools/list-rooms.ts +35 -0
- package/dist/integrations/webex/files/ai/tools/send-message.ts +51 -0
- package/dist/integrations/webex/files/app/api/auth/webex/callback/route.ts +11 -0
- package/dist/integrations/webex/files/app/api/auth/webex/route.ts +7 -0
- package/dist/integrations/webex/files/lib/token-store.ts +11 -0
- package/dist/integrations/webex/files/lib/webex-client.ts +279 -0
- package/dist/integrations/xero/connector.json +85 -0
- package/dist/integrations/xero/files/_env.example +4 -0
- package/dist/integrations/xero/files/ai/tools/create-invoice.ts +65 -0
- package/dist/integrations/xero/files/ai/tools/get-contact.ts +40 -0
- package/dist/integrations/xero/files/ai/tools/get-invoice.ts +44 -0
- package/dist/integrations/xero/files/ai/tools/list-contacts.ts +54 -0
- package/dist/integrations/xero/files/ai/tools/list-invoices.ts +54 -0
- package/dist/integrations/xero/files/app/api/auth/xero/callback/route.ts +11 -0
- package/dist/integrations/xero/files/app/api/auth/xero/route.ts +7 -0
- package/dist/integrations/xero/files/lib/token-store.ts +11 -0
- package/dist/integrations/xero/files/lib/xero-client.ts +292 -0
- package/dist/integrations/zendesk/connector.json +61 -0
- package/dist/integrations/zendesk/files/_env.example +5 -0
- package/dist/integrations/zendesk/files/ai/tools/create-ticket.ts +82 -0
- package/dist/integrations/zendesk/files/ai/tools/get-ticket.ts +53 -0
- package/dist/integrations/zendesk/files/ai/tools/list-tickets.ts +60 -0
- package/dist/integrations/zendesk/files/ai/tools/search-tickets.ts +56 -0
- package/dist/integrations/zendesk/files/app/api/auth/zendesk/callback/route.ts +91 -0
- package/dist/integrations/zendesk/files/app/api/auth/zendesk/route.ts +41 -0
- package/dist/integrations/zendesk/files/lib/token-store.ts +47 -0
- package/dist/integrations/zendesk/files/lib/zendesk-client.ts +265 -0
- package/dist/integrations/zoom/connector.json +85 -0
- package/dist/integrations/zoom/files/_env.example +4 -0
- package/dist/integrations/zoom/files/ai/tools/create-meeting.ts +106 -0
- package/dist/integrations/zoom/files/ai/tools/delete-meeting.ts +32 -0
- package/dist/integrations/zoom/files/ai/tools/get-meeting.ts +44 -0
- package/dist/integrations/zoom/files/ai/tools/list-meetings.ts +47 -0
- package/dist/integrations/zoom/files/ai/tools/update-meeting.ts +111 -0
- package/dist/integrations/zoom/files/app/api/auth/zoom/callback/route.ts +11 -0
- package/dist/integrations/zoom/files/app/api/auth/zoom/route.ts +7 -0
- package/dist/integrations/zoom/files/lib/token-store.ts +11 -0
- package/dist/integrations/zoom/files/lib/zoom-client.ts +228 -0
- package/dist/oauth/handlers.js +554 -0
- package/dist/oauth/handlers.js.map +7 -0
- package/dist/oauth/index.js +1157 -0
- package/dist/oauth/index.js.map +7 -0
- package/dist/oauth/providers.js +927 -0
- package/dist/oauth/providers.js.map +7 -0
- package/dist/oauth/token-store.js +82 -0
- package/dist/oauth/token-store.js.map +7 -0
- package/package.json +25 -1
- package/dist/integrations/gmail/files/lib/oauth.ts +0 -145
- package/dist/integrations/slack/files/lib/oauth.ts +0 -145
- /package/dist/integrations/{calendar → docs-google}/files/lib/oauth.ts +0 -0
- /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
|
-
*
|
|
5
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
237
|
+
* In-memory token store for development
|
|
36
238
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
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
|
-
|
|
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(
|
|
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
|
|
306
|
+
const data = await config.get(key);
|
|
84
307
|
if (!data) return null;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
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
|
|
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
|
+
});
|