@hasna/connectors 0.4.0 → 0.4.2
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/bin/index.js +189 -2
- package/bin/mcp.js +176 -1
- package/bin/serve.js +175 -0
- package/connectors/connect-airtable/.env.example +11 -0
- package/connectors/connect-airtable/CLAUDE.md +121 -0
- package/connectors/connect-airtable/README.md +193 -0
- package/connectors/connect-airtable/package.json +50 -0
- package/connectors/connect-airtable/src/api/client.ts +139 -0
- package/connectors/connect-airtable/src/api/index.ts +405 -0
- package/connectors/connect-airtable/src/cli/index.ts +637 -0
- package/connectors/connect-airtable/src/index.ts +20 -0
- package/connectors/connect-airtable/src/types/index.ts +349 -0
- package/connectors/connect-airtable/src/utils/config.ts +197 -0
- package/connectors/connect-airtable/tsconfig.json +16 -0
- package/connectors/connect-amplitude/.env.example +11 -0
- package/connectors/connect-amplitude/CLAUDE.md +121 -0
- package/connectors/connect-amplitude/README.md +193 -0
- package/connectors/connect-amplitude/package.json +51 -0
- package/connectors/connect-amplitude/src/api/client.ts +144 -0
- package/connectors/connect-amplitude/src/api/index.ts +215 -0
- package/connectors/connect-amplitude/src/cli/index.ts +532 -0
- package/connectors/connect-amplitude/src/index.ts +22 -0
- package/connectors/connect-amplitude/src/types/index.ts +329 -0
- package/connectors/connect-amplitude/src/utils/config.ts +208 -0
- package/connectors/connect-amplitude/tsconfig.json +16 -0
- package/connectors/connect-calendly/.env.example +11 -0
- package/connectors/connect-calendly/CLAUDE.md +272 -0
- package/connectors/connect-calendly/README.md +193 -0
- package/connectors/connect-calendly/package.json +51 -0
- package/connectors/connect-calendly/scripts/release.ts +179 -0
- package/connectors/connect-calendly/src/api/client.ts +213 -0
- package/connectors/connect-calendly/src/api/example.ts +48 -0
- package/connectors/connect-calendly/src/api/index.ts +51 -0
- package/connectors/connect-calendly/src/cli/index.ts +254 -0
- package/connectors/connect-calendly/src/index.ts +103 -0
- package/connectors/connect-calendly/src/types/index.ts +237 -0
- package/connectors/connect-calendly/src/utils/auth.ts +274 -0
- package/connectors/connect-calendly/src/utils/bulk.ts +212 -0
- package/connectors/connect-calendly/src/utils/config.ts +326 -0
- package/connectors/connect-calendly/src/utils/output.ts +175 -0
- package/connectors/connect-calendly/src/utils/settings.ts +114 -0
- package/connectors/connect-calendly/src/utils/storage.ts +198 -0
- package/connectors/connect-calendly/tsconfig.json +16 -0
- package/connectors/connect-convertkit/.env.example +11 -0
- package/connectors/connect-convertkit/CLAUDE.md +272 -0
- package/connectors/connect-convertkit/README.md +193 -0
- package/connectors/connect-convertkit/package.json +51 -0
- package/connectors/connect-convertkit/scripts/release.ts +179 -0
- package/connectors/connect-convertkit/src/api/client.ts +213 -0
- package/connectors/connect-convertkit/src/api/example.ts +48 -0
- package/connectors/connect-convertkit/src/api/index.ts +51 -0
- package/connectors/connect-convertkit/src/cli/index.ts +254 -0
- package/connectors/connect-convertkit/src/index.ts +103 -0
- package/connectors/connect-convertkit/src/types/index.ts +237 -0
- package/connectors/connect-convertkit/src/utils/auth.ts +274 -0
- package/connectors/connect-convertkit/src/utils/bulk.ts +212 -0
- package/connectors/connect-convertkit/src/utils/config.ts +326 -0
- package/connectors/connect-convertkit/src/utils/output.ts +175 -0
- package/connectors/connect-convertkit/src/utils/settings.ts +114 -0
- package/connectors/connect-convertkit/src/utils/storage.ts +198 -0
- package/connectors/connect-convertkit/tsconfig.json +16 -0
- package/connectors/connect-crisp/.env.example +11 -0
- package/connectors/connect-crisp/CLAUDE.md +272 -0
- package/connectors/connect-crisp/README.md +193 -0
- package/connectors/connect-crisp/package.json +51 -0
- package/connectors/connect-crisp/scripts/release.ts +179 -0
- package/connectors/connect-crisp/src/api/client.ts +213 -0
- package/connectors/connect-crisp/src/api/example.ts +48 -0
- package/connectors/connect-crisp/src/api/index.ts +51 -0
- package/connectors/connect-crisp/src/cli/index.ts +254 -0
- package/connectors/connect-crisp/src/index.ts +103 -0
- package/connectors/connect-crisp/src/types/index.ts +237 -0
- package/connectors/connect-crisp/src/utils/auth.ts +274 -0
- package/connectors/connect-crisp/src/utils/bulk.ts +212 -0
- package/connectors/connect-crisp/src/utils/config.ts +326 -0
- package/connectors/connect-crisp/src/utils/output.ts +175 -0
- package/connectors/connect-crisp/src/utils/settings.ts +114 -0
- package/connectors/connect-crisp/src/utils/storage.ts +198 -0
- package/connectors/connect-crisp/tsconfig.json +16 -0
- package/connectors/connect-docusign/.env.example +11 -0
- package/connectors/connect-docusign/CLAUDE.md +128 -0
- package/connectors/connect-docusign/README.md +193 -0
- package/connectors/connect-docusign/package.json +52 -0
- package/connectors/connect-docusign/src/api/client.ts +133 -0
- package/connectors/connect-docusign/src/api/index.ts +178 -0
- package/connectors/connect-docusign/src/cli/index.ts +381 -0
- package/connectors/connect-docusign/src/index.ts +23 -0
- package/connectors/connect-docusign/src/types/index.ts +208 -0
- package/connectors/connect-docusign/src/utils/config.ts +125 -0
- package/connectors/connect-docusign/src/utils/output.ts +119 -0
- package/connectors/connect-docusign/tsconfig.json +16 -0
- package/connectors/connect-drift/.env.example +11 -0
- package/connectors/connect-drift/CLAUDE.md +272 -0
- package/connectors/connect-drift/README.md +193 -0
- package/connectors/connect-drift/package.json +51 -0
- package/connectors/connect-drift/scripts/release.ts +179 -0
- package/connectors/connect-drift/src/api/client.ts +213 -0
- package/connectors/connect-drift/src/api/example.ts +48 -0
- package/connectors/connect-drift/src/api/index.ts +51 -0
- package/connectors/connect-drift/src/cli/index.ts +254 -0
- package/connectors/connect-drift/src/index.ts +103 -0
- package/connectors/connect-drift/src/types/index.ts +237 -0
- package/connectors/connect-drift/src/utils/auth.ts +274 -0
- package/connectors/connect-drift/src/utils/bulk.ts +212 -0
- package/connectors/connect-drift/src/utils/config.ts +326 -0
- package/connectors/connect-drift/src/utils/output.ts +175 -0
- package/connectors/connect-drift/src/utils/settings.ts +114 -0
- package/connectors/connect-drift/src/utils/storage.ts +198 -0
- package/connectors/connect-drift/tsconfig.json +16 -0
- package/connectors/connect-freshdesk/.env.example +11 -0
- package/connectors/connect-freshdesk/CLAUDE.md +272 -0
- package/connectors/connect-freshdesk/README.md +193 -0
- package/connectors/connect-freshdesk/package.json +51 -0
- package/connectors/connect-freshdesk/scripts/release.ts +179 -0
- package/connectors/connect-freshdesk/src/api/client.ts +213 -0
- package/connectors/connect-freshdesk/src/api/example.ts +48 -0
- package/connectors/connect-freshdesk/src/api/index.ts +51 -0
- package/connectors/connect-freshdesk/src/cli/index.ts +254 -0
- package/connectors/connect-freshdesk/src/index.ts +103 -0
- package/connectors/connect-freshdesk/src/types/index.ts +237 -0
- package/connectors/connect-freshdesk/src/utils/auth.ts +274 -0
- package/connectors/connect-freshdesk/src/utils/bulk.ts +212 -0
- package/connectors/connect-freshdesk/src/utils/config.ts +326 -0
- package/connectors/connect-freshdesk/src/utils/output.ts +175 -0
- package/connectors/connect-freshdesk/src/utils/settings.ts +114 -0
- package/connectors/connect-freshdesk/src/utils/storage.ts +198 -0
- package/connectors/connect-freshdesk/tsconfig.json +16 -0
- package/connectors/connect-gumroad/.env.example +11 -0
- package/connectors/connect-gumroad/CLAUDE.md +272 -0
- package/connectors/connect-gumroad/README.md +193 -0
- package/connectors/connect-gumroad/package.json +51 -0
- package/connectors/connect-gumroad/scripts/release.ts +179 -0
- package/connectors/connect-gumroad/src/api/client.ts +213 -0
- package/connectors/connect-gumroad/src/api/example.ts +48 -0
- package/connectors/connect-gumroad/src/api/index.ts +51 -0
- package/connectors/connect-gumroad/src/cli/index.ts +254 -0
- package/connectors/connect-gumroad/src/index.ts +103 -0
- package/connectors/connect-gumroad/src/types/index.ts +237 -0
- package/connectors/connect-gumroad/src/utils/auth.ts +274 -0
- package/connectors/connect-gumroad/src/utils/bulk.ts +212 -0
- package/connectors/connect-gumroad/src/utils/config.ts +326 -0
- package/connectors/connect-gumroad/src/utils/output.ts +175 -0
- package/connectors/connect-gumroad/src/utils/settings.ts +114 -0
- package/connectors/connect-gumroad/src/utils/storage.ts +198 -0
- package/connectors/connect-gumroad/tsconfig.json +16 -0
- package/connectors/connect-hubspot/.env.example +11 -0
- package/connectors/connect-hubspot/CLAUDE.md +128 -0
- package/connectors/connect-hubspot/README.md +193 -0
- package/connectors/connect-hubspot/package.json +52 -0
- package/connectors/connect-hubspot/src/api/client.ts +136 -0
- package/connectors/connect-hubspot/src/api/index.ts +379 -0
- package/connectors/connect-hubspot/src/cli/index.ts +589 -0
- package/connectors/connect-hubspot/src/index.ts +21 -0
- package/connectors/connect-hubspot/src/types/index.ts +285 -0
- package/connectors/connect-hubspot/src/utils/config.ts +205 -0
- package/connectors/connect-hubspot/src/utils/output.ts +119 -0
- package/connectors/connect-hubspot/tsconfig.json +16 -0
- package/connectors/connect-intercom/.env.example +11 -0
- package/connectors/connect-intercom/CLAUDE.md +131 -0
- package/connectors/connect-intercom/README.md +193 -0
- package/connectors/connect-intercom/package.json +52 -0
- package/connectors/connect-intercom/src/api/client.ts +132 -0
- package/connectors/connect-intercom/src/api/index.ts +366 -0
- package/connectors/connect-intercom/src/cli/index.ts +831 -0
- package/connectors/connect-intercom/src/index.ts +21 -0
- package/connectors/connect-intercom/src/types/index.ts +650 -0
- package/connectors/connect-intercom/src/utils/config.ts +157 -0
- package/connectors/connect-intercom/src/utils/output.ts +119 -0
- package/connectors/connect-intercom/tsconfig.json +16 -0
- package/connectors/connect-lemonsqueezy/.env.example +11 -0
- package/connectors/connect-lemonsqueezy/CLAUDE.md +128 -0
- package/connectors/connect-lemonsqueezy/README.md +193 -0
- package/connectors/connect-lemonsqueezy/package.json +52 -0
- package/connectors/connect-lemonsqueezy/src/api/client.ts +133 -0
- package/connectors/connect-lemonsqueezy/src/api/index.ts +502 -0
- package/connectors/connect-lemonsqueezy/src/cli/index.ts +723 -0
- package/connectors/connect-lemonsqueezy/src/index.ts +21 -0
- package/connectors/connect-lemonsqueezy/src/types/index.ts +353 -0
- package/connectors/connect-lemonsqueezy/src/utils/config.ts +205 -0
- package/connectors/connect-lemonsqueezy/src/utils/output.ts +119 -0
- package/connectors/connect-lemonsqueezy/tsconfig.json +16 -0
- package/connectors/connect-linkedin/.env.example +11 -0
- package/connectors/connect-linkedin/CLAUDE.md +124 -0
- package/connectors/connect-linkedin/README.md +193 -0
- package/connectors/connect-linkedin/package.json +52 -0
- package/connectors/connect-linkedin/src/api/client.ts +132 -0
- package/connectors/connect-linkedin/src/api/index.ts +313 -0
- package/connectors/connect-linkedin/src/cli/index.ts +548 -0
- package/connectors/connect-linkedin/src/index.ts +21 -0
- package/connectors/connect-linkedin/src/types/index.ts +472 -0
- package/connectors/connect-linkedin/src/utils/config.ts +157 -0
- package/connectors/connect-linkedin/src/utils/output.ts +119 -0
- package/connectors/connect-linkedin/tsconfig.json +16 -0
- package/connectors/connect-mailchimp/.env.example +11 -0
- package/connectors/connect-mailchimp/CLAUDE.md +127 -0
- package/connectors/connect-mailchimp/README.md +193 -0
- package/connectors/connect-mailchimp/package.json +52 -0
- package/connectors/connect-mailchimp/src/api/client.ts +162 -0
- package/connectors/connect-mailchimp/src/api/index.ts +580 -0
- package/connectors/connect-mailchimp/src/cli/index.ts +822 -0
- package/connectors/connect-mailchimp/src/index.ts +23 -0
- package/connectors/connect-mailchimp/src/types/index.ts +585 -0
- package/connectors/connect-mailchimp/src/utils/config.ts +208 -0
- package/connectors/connect-mailchimp/src/utils/output.ts +119 -0
- package/connectors/connect-mailchimp/tsconfig.json +16 -0
- package/connectors/connect-mongodb/.env.example +11 -0
- package/connectors/connect-mongodb/CLAUDE.md +272 -0
- package/connectors/connect-mongodb/README.md +193 -0
- package/connectors/connect-mongodb/package.json +51 -0
- package/connectors/connect-mongodb/scripts/release.ts +179 -0
- package/connectors/connect-mongodb/src/api/client.ts +213 -0
- package/connectors/connect-mongodb/src/api/example.ts +48 -0
- package/connectors/connect-mongodb/src/api/index.ts +51 -0
- package/connectors/connect-mongodb/src/cli/index.ts +254 -0
- package/connectors/connect-mongodb/src/index.ts +103 -0
- package/connectors/connect-mongodb/src/types/index.ts +237 -0
- package/connectors/connect-mongodb/src/utils/auth.ts +274 -0
- package/connectors/connect-mongodb/src/utils/bulk.ts +212 -0
- package/connectors/connect-mongodb/src/utils/config.ts +326 -0
- package/connectors/connect-mongodb/src/utils/output.ts +175 -0
- package/connectors/connect-mongodb/src/utils/settings.ts +114 -0
- package/connectors/connect-mongodb/src/utils/storage.ts +198 -0
- package/connectors/connect-mongodb/tsconfig.json +16 -0
- package/connectors/connect-netlify/.env.example +11 -0
- package/connectors/connect-netlify/CLAUDE.md +170 -0
- package/connectors/connect-netlify/README.md +193 -0
- package/connectors/connect-netlify/package.json +53 -0
- package/connectors/connect-netlify/src/api/client.ts +132 -0
- package/connectors/connect-netlify/src/api/index.ts +533 -0
- package/connectors/connect-netlify/src/cli/index.ts +985 -0
- package/connectors/connect-netlify/src/index.ts +22 -0
- package/connectors/connect-netlify/src/types/index.ts +423 -0
- package/connectors/connect-netlify/src/utils/config.ts +171 -0
- package/connectors/connect-netlify/src/utils/output.ts +119 -0
- package/connectors/connect-netlify/tsconfig.json +16 -0
- package/connectors/connect-paypal/.env.example +11 -0
- package/connectors/connect-paypal/CLAUDE.md +128 -0
- package/connectors/connect-paypal/README.md +193 -0
- package/connectors/connect-paypal/package.json +51 -0
- package/connectors/connect-paypal/src/api/client.ts +182 -0
- package/connectors/connect-paypal/src/api/index.ts +235 -0
- package/connectors/connect-paypal/src/cli/index.ts +559 -0
- package/connectors/connect-paypal/src/index.ts +23 -0
- package/connectors/connect-paypal/src/types/index.ts +377 -0
- package/connectors/connect-paypal/src/utils/config.ts +125 -0
- package/connectors/connect-paypal/src/utils/output.ts +119 -0
- package/connectors/connect-paypal/tsconfig.json +16 -0
- package/connectors/connect-pinterest/.env.example +11 -0
- package/connectors/connect-pinterest/CLAUDE.md +115 -0
- package/connectors/connect-pinterest/README.md +193 -0
- package/connectors/connect-pinterest/package.json +52 -0
- package/connectors/connect-pinterest/src/api/client.ts +125 -0
- package/connectors/connect-pinterest/src/api/index.ts +203 -0
- package/connectors/connect-pinterest/src/cli/index.ts +653 -0
- package/connectors/connect-pinterest/src/index.ts +21 -0
- package/connectors/connect-pinterest/src/types/index.ts +268 -0
- package/connectors/connect-pinterest/src/utils/config.ts +157 -0
- package/connectors/connect-pinterest/src/utils/output.ts +119 -0
- package/connectors/connect-pinterest/tsconfig.json +16 -0
- package/connectors/connect-posthog/.env.example +11 -0
- package/connectors/connect-posthog/CLAUDE.md +272 -0
- package/connectors/connect-posthog/README.md +193 -0
- package/connectors/connect-posthog/package.json +51 -0
- package/connectors/connect-posthog/scripts/release.ts +179 -0
- package/connectors/connect-posthog/src/api/client.ts +213 -0
- package/connectors/connect-posthog/src/api/example.ts +48 -0
- package/connectors/connect-posthog/src/api/index.ts +51 -0
- package/connectors/connect-posthog/src/cli/index.ts +254 -0
- package/connectors/connect-posthog/src/index.ts +103 -0
- package/connectors/connect-posthog/src/types/index.ts +237 -0
- package/connectors/connect-posthog/src/utils/auth.ts +274 -0
- package/connectors/connect-posthog/src/utils/bulk.ts +212 -0
- package/connectors/connect-posthog/src/utils/config.ts +326 -0
- package/connectors/connect-posthog/src/utils/output.ts +175 -0
- package/connectors/connect-posthog/src/utils/settings.ts +114 -0
- package/connectors/connect-posthog/src/utils/storage.ts +198 -0
- package/connectors/connect-posthog/tsconfig.json +16 -0
- package/connectors/connect-salesforce/.env.example +11 -0
- package/connectors/connect-salesforce/CLAUDE.md +128 -0
- package/connectors/connect-salesforce/README.md +193 -0
- package/connectors/connect-salesforce/package.json +53 -0
- package/connectors/connect-salesforce/src/api/client.ts +150 -0
- package/connectors/connect-salesforce/src/api/index.ts +367 -0
- package/connectors/connect-salesforce/src/cli/index.ts +594 -0
- package/connectors/connect-salesforce/src/index.ts +21 -0
- package/connectors/connect-salesforce/src/types/index.ts +292 -0
- package/connectors/connect-salesforce/src/utils/config.ts +208 -0
- package/connectors/connect-salesforce/src/utils/output.ts +119 -0
- package/connectors/connect-salesforce/tsconfig.json +16 -0
- package/connectors/connect-segment/.env.example +11 -0
- package/connectors/connect-segment/CLAUDE.md +272 -0
- package/connectors/connect-segment/README.md +193 -0
- package/connectors/connect-segment/package.json +51 -0
- package/connectors/connect-segment/scripts/release.ts +179 -0
- package/connectors/connect-segment/src/api/client.ts +213 -0
- package/connectors/connect-segment/src/api/example.ts +48 -0
- package/connectors/connect-segment/src/api/index.ts +51 -0
- package/connectors/connect-segment/src/cli/index.ts +254 -0
- package/connectors/connect-segment/src/index.ts +103 -0
- package/connectors/connect-segment/src/types/index.ts +237 -0
- package/connectors/connect-segment/src/utils/auth.ts +274 -0
- package/connectors/connect-segment/src/utils/bulk.ts +212 -0
- package/connectors/connect-segment/src/utils/config.ts +326 -0
- package/connectors/connect-segment/src/utils/output.ts +175 -0
- package/connectors/connect-segment/src/utils/settings.ts +114 -0
- package/connectors/connect-segment/src/utils/storage.ts +198 -0
- package/connectors/connect-segment/tsconfig.json +16 -0
- package/connectors/connect-sendgrid/.env.example +11 -0
- package/connectors/connect-sendgrid/CLAUDE.md +125 -0
- package/connectors/connect-sendgrid/README.md +193 -0
- package/connectors/connect-sendgrid/package.json +53 -0
- package/connectors/connect-sendgrid/src/api/client.ts +137 -0
- package/connectors/connect-sendgrid/src/api/index.ts +588 -0
- package/connectors/connect-sendgrid/src/cli/index.ts +764 -0
- package/connectors/connect-sendgrid/src/index.ts +21 -0
- package/connectors/connect-sendgrid/src/types/index.ts +403 -0
- package/connectors/connect-sendgrid/src/utils/config.ts +197 -0
- package/connectors/connect-sendgrid/src/utils/output.ts +119 -0
- package/connectors/connect-sendgrid/tsconfig.json +16 -0
- package/connectors/connect-supabase/.env.example +11 -0
- package/connectors/connect-supabase/CLAUDE.md +132 -0
- package/connectors/connect-supabase/README.md +193 -0
- package/connectors/connect-supabase/package.json +52 -0
- package/connectors/connect-supabase/src/api/client.ts +231 -0
- package/connectors/connect-supabase/src/api/index.ts +439 -0
- package/connectors/connect-supabase/src/cli/index.ts +691 -0
- package/connectors/connect-supabase/src/index.ts +24 -0
- package/connectors/connect-supabase/src/types/index.ts +215 -0
- package/connectors/connect-supabase/src/utils/config.ts +219 -0
- package/connectors/connect-supabase/tsconfig.json +16 -0
- package/connectors/connect-vercel/.env.example +11 -0
- package/connectors/connect-vercel/CLAUDE.md +142 -0
- package/connectors/connect-vercel/README.md +193 -0
- package/connectors/connect-vercel/package.json +52 -0
- package/connectors/connect-vercel/src/api/client.ts +139 -0
- package/connectors/connect-vercel/src/api/index.ts +384 -0
- package/connectors/connect-vercel/src/cli/index.ts +740 -0
- package/connectors/connect-vercel/src/index.ts +24 -0
- package/connectors/connect-vercel/src/types/index.ts +350 -0
- package/connectors/connect-vercel/src/utils/config.ts +182 -0
- package/connectors/connect-vercel/src/utils/output.ts +119 -0
- package/connectors/connect-vercel/tsconfig.json +16 -0
- package/connectors/connect-zendesk/.env.example +10 -0
- package/connectors/connect-zendesk/.github/workflows/deploy.yml +51 -0
- package/connectors/connect-zendesk/CLAUDE.md +78 -0
- package/connectors/connect-zendesk/Makefile +129 -0
- package/connectors/connect-zendesk/README.md +295 -0
- package/connectors/connect-zendesk/SCAFFOLD.md +178 -0
- package/connectors/connect-zendesk/nginx-connector.conf +218 -0
- package/connectors/connect-zendesk/nginx.conf +61 -0
- package/connectors/connect-zendesk/package.json +71 -0
- package/connectors/connect-zendesk/scripts/init.sh +62 -0
- package/connectors/connect-zendesk/scripts/publish.ts +210 -0
- package/connectors/connect-zendesk/server/index.js +142 -0
- package/connectors/connect-zendesk/src/api/automations.ts +95 -0
- package/connectors/connect-zendesk/src/api/brands.ts +80 -0
- package/connectors/connect-zendesk/src/api/bulk.ts +838 -0
- package/connectors/connect-zendesk/src/api/client.test.ts +315 -0
- package/connectors/connect-zendesk/src/api/client.ts +173 -0
- package/connectors/connect-zendesk/src/api/example.ts +59 -0
- package/connectors/connect-zendesk/src/api/groups.ts +60 -0
- package/connectors/connect-zendesk/src/api/index.test.ts +111 -0
- package/connectors/connect-zendesk/src/api/index.ts +131 -0
- package/connectors/connect-zendesk/src/api/macros.ts +124 -0
- package/connectors/connect-zendesk/src/api/organizations.ts +85 -0
- package/connectors/connect-zendesk/src/api/slas.ts +80 -0
- package/connectors/connect-zendesk/src/api/ticket-fields.ts +98 -0
- package/connectors/connect-zendesk/src/api/tickets.test.ts +215 -0
- package/connectors/connect-zendesk/src/api/tickets.ts +103 -0
- package/connectors/connect-zendesk/src/api/triggers.test.ts +204 -0
- package/connectors/connect-zendesk/src/api/triggers.ts +125 -0
- package/connectors/connect-zendesk/src/api/users.test.ts +180 -0
- package/connectors/connect-zendesk/src/api/users.ts +108 -0
- package/connectors/connect-zendesk/src/api/views.test.ts +223 -0
- package/connectors/connect-zendesk/src/api/views.ts +145 -0
- package/connectors/connect-zendesk/src/api/webhooks.test.ts +208 -0
- package/connectors/connect-zendesk/src/api/webhooks.ts +118 -0
- package/connectors/connect-zendesk/src/cli/index.ts +1478 -0
- package/connectors/connect-zendesk/src/index.ts +36 -0
- package/connectors/connect-zendesk/src/server/index.ts +204 -0
- package/connectors/connect-zendesk/src/types/index.ts +910 -0
- package/connectors/connect-zendesk/src/utils/config.test.ts +193 -0
- package/connectors/connect-zendesk/src/utils/config.ts +526 -0
- package/connectors/connect-zendesk/src/utils/export.ts +338 -0
- package/connectors/connect-zendesk/src/utils/logger.ts +105 -0
- package/connectors/connect-zendesk/src/utils/output.test.ts +137 -0
- package/connectors/connect-zendesk/src/utils/output.ts +119 -0
- package/connectors/connect-zendesk/tsconfig.json +31 -0
- package/dist/index.js +175 -0
- package/package.json +1 -1
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# scaffold-connector
|
|
2
|
+
|
|
3
|
+
A TypeScript scaffold for building API connector CLIs with multi-profile support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Multi-profile configuration (switch between different API keys/accounts)
|
|
8
|
+
- Bearer token authentication (easily customizable)
|
|
9
|
+
- Clean CLI structure with Commander.js
|
|
10
|
+
- Pretty and JSON output formats
|
|
11
|
+
- TypeScript with strict mode
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Clone and Rename
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Clone for your connector
|
|
19
|
+
git clone https://github.com/hasna/scaffold-connector.git connect-yourapi
|
|
20
|
+
cd connect-yourapi
|
|
21
|
+
|
|
22
|
+
# Update package.json name
|
|
23
|
+
# Change "@hasna/scaffold-connector" to "@hasna/connect-yourapi"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 2. Update Configuration
|
|
27
|
+
|
|
28
|
+
Search for `TODO` comments throughout the codebase and update:
|
|
29
|
+
|
|
30
|
+
- `src/cli/index.ts` - Update `CONNECTOR_NAME` and description
|
|
31
|
+
- `src/utils/config.ts` - Update `CONNECTOR_NAME` and env var names
|
|
32
|
+
- `src/api/client.ts` - Update `DEFAULT_BASE_URL` and authentication method
|
|
33
|
+
- `src/api/index.ts` - Rename `Connector` class to your API name
|
|
34
|
+
- `src/types/index.ts` - Add your API's type definitions
|
|
35
|
+
- `package.json` - Update name, description, bin command
|
|
36
|
+
- `.env.example` - Update environment variable names
|
|
37
|
+
|
|
38
|
+
### 3. Install and Test
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Install dependencies
|
|
42
|
+
bun install
|
|
43
|
+
|
|
44
|
+
# Run CLI
|
|
45
|
+
bun run dev
|
|
46
|
+
|
|
47
|
+
# Or run specific commands
|
|
48
|
+
bun run dev profile list
|
|
49
|
+
bun run dev config show
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## CLI Structure
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
connector [options] [command]
|
|
56
|
+
|
|
57
|
+
Options:
|
|
58
|
+
-k, --api-key <key> API key (overrides config)
|
|
59
|
+
-f, --format <format> Output format (json, pretty)
|
|
60
|
+
-p, --profile <profile> Use a specific profile
|
|
61
|
+
|
|
62
|
+
Commands:
|
|
63
|
+
profile list List all profiles
|
|
64
|
+
profile use <name> Switch to a profile
|
|
65
|
+
profile create <name> Create a new profile
|
|
66
|
+
profile delete <name> Delete a profile
|
|
67
|
+
profile show [name] Show profile configuration
|
|
68
|
+
|
|
69
|
+
config set-key <key> Set API key for active profile
|
|
70
|
+
config show Show current configuration
|
|
71
|
+
config clear Clear configuration
|
|
72
|
+
|
|
73
|
+
example list Example API command (replace)
|
|
74
|
+
example get <id> Example API command (replace)
|
|
75
|
+
example create Example API command (replace)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Project Structure
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
src/
|
|
82
|
+
├── api/
|
|
83
|
+
│ ├── client.ts # HTTP client with authentication
|
|
84
|
+
│ ├── example.ts # Example API module (replace with your API)
|
|
85
|
+
│ └── index.ts # Main connector class
|
|
86
|
+
├── cli/
|
|
87
|
+
│ └── index.ts # CLI commands
|
|
88
|
+
├── types/
|
|
89
|
+
│ └── index.ts # Type definitions
|
|
90
|
+
├── utils/
|
|
91
|
+
│ ├── config.ts # Multi-profile configuration
|
|
92
|
+
│ └── output.ts # CLI output formatting
|
|
93
|
+
└── index.ts # Library exports
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Multi-Profile Configuration
|
|
97
|
+
|
|
98
|
+
Profiles are stored in `~/.connect/{connector-name}/profiles/`:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
~/.connect/connector/
|
|
102
|
+
├── current_profile # Name of active profile
|
|
103
|
+
└── profiles/
|
|
104
|
+
├── default.json # Default profile
|
|
105
|
+
├── work.json # Named profile
|
|
106
|
+
└── personal.json # Named profile
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Profile Commands
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Create profiles
|
|
113
|
+
connector profile create work --api-key sk-xxx --use
|
|
114
|
+
connector profile create personal --api-key sk-yyy
|
|
115
|
+
|
|
116
|
+
# Switch profiles
|
|
117
|
+
connector profile use work
|
|
118
|
+
|
|
119
|
+
# Use profile for single command
|
|
120
|
+
connector -p personal example list
|
|
121
|
+
|
|
122
|
+
# List profiles
|
|
123
|
+
connector profile list
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Customizing Authentication
|
|
127
|
+
|
|
128
|
+
Edit `src/api/client.ts` to change authentication:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
// Bearer token (default)
|
|
132
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
133
|
+
|
|
134
|
+
// API Key header
|
|
135
|
+
'X-API-Key': this.apiKey,
|
|
136
|
+
|
|
137
|
+
// Basic auth
|
|
138
|
+
'Authorization': `Basic ${Buffer.from(`${this.apiKey}:${this.apiSecret}`).toString('base64')}`,
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Adding API Endpoints
|
|
142
|
+
|
|
143
|
+
1. Create a new file in `src/api/` (e.g., `users.ts`)
|
|
144
|
+
2. Export it from `src/api/index.ts`
|
|
145
|
+
3. Add types in `src/types/index.ts`
|
|
146
|
+
4. Add CLI commands in `src/cli/index.ts`
|
|
147
|
+
|
|
148
|
+
Example API module:
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
// src/api/users.ts
|
|
152
|
+
import type { ConnectorClient } from './client';
|
|
153
|
+
|
|
154
|
+
export class UsersApi {
|
|
155
|
+
constructor(private readonly client: ConnectorClient) {}
|
|
156
|
+
|
|
157
|
+
async list(options?: { limit?: number }) {
|
|
158
|
+
return this.client.get('/users', { limit: options?.limit });
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async get(id: string) {
|
|
162
|
+
return this.client.get(`/users/${id}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Environment Variables
|
|
168
|
+
|
|
169
|
+
| Variable | Description |
|
|
170
|
+
|----------|-------------|
|
|
171
|
+
| `CONNECTOR_API_KEY` | API key (overrides profile config) |
|
|
172
|
+
| `CONNECTOR_API_SECRET` | API secret (optional) |
|
|
173
|
+
| `CONNECTOR_BASE_URL` | Override base URL (optional) |
|
|
174
|
+
|
|
175
|
+
## Development
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# Install dependencies
|
|
179
|
+
bun install
|
|
180
|
+
|
|
181
|
+
# Run CLI in development
|
|
182
|
+
bun run dev
|
|
183
|
+
|
|
184
|
+
# Build for distribution
|
|
185
|
+
bun run build
|
|
186
|
+
|
|
187
|
+
# Type check
|
|
188
|
+
bun run typecheck
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
MIT
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hasna/connect-mongodb",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Connector: connect-mongodb",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"connector": "./bin/index.js"
|
|
8
|
+
},
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "bun build ./src/index.ts --outdir ./dist --target bun && bun build ./src/cli/index.ts --outdir ./bin --target bun",
|
|
19
|
+
"dev": "bun run ./src/cli/index.ts",
|
|
20
|
+
"typecheck": "tsc --noEmit",
|
|
21
|
+
"prepublishOnly": "bun run build",
|
|
22
|
+
"release": "bun run scripts/release.ts",
|
|
23
|
+
"release:dry": "bun run scripts/release.ts --dry-run"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"api",
|
|
27
|
+
"connector",
|
|
28
|
+
"scaffold",
|
|
29
|
+
"cli",
|
|
30
|
+
"typescript",
|
|
31
|
+
"bun",
|
|
32
|
+
"template"
|
|
33
|
+
],
|
|
34
|
+
"author": "Hasna",
|
|
35
|
+
"license": "Apache-2.0",
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/bun": "latest",
|
|
38
|
+
"typescript": "^5"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"commander": "^12.1.0",
|
|
42
|
+
"chalk": "^5.3.0"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"bun": ">=1.0.0"
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/hasna/connectors.git"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Release script for publishing to npm
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* bun run release # Build, bump version, and publish
|
|
7
|
+
* bun run release:dry # Dry run (preview only)
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Auto-fetches current npm version
|
|
11
|
+
* - Bumps patch version if needed
|
|
12
|
+
* - Creates git tag
|
|
13
|
+
* - Publishes to npm
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
17
|
+
import { execSync } from 'child_process';
|
|
18
|
+
|
|
19
|
+
const isDryRun = process.argv.includes('--dry-run');
|
|
20
|
+
|
|
21
|
+
interface PackageJson {
|
|
22
|
+
name: string;
|
|
23
|
+
version: string;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function exec(command: string, silent = false): string {
|
|
28
|
+
try {
|
|
29
|
+
const result = execSync(command, {
|
|
30
|
+
encoding: 'utf-8',
|
|
31
|
+
stdio: silent ? 'pipe' : 'inherit',
|
|
32
|
+
});
|
|
33
|
+
return result?.trim() || '';
|
|
34
|
+
} catch (err) {
|
|
35
|
+
if (silent) {
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
38
|
+
throw err;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function log(message: string): void {
|
|
43
|
+
console.log(`\x1b[36m▸\x1b[0m ${message}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function success(message: string): void {
|
|
47
|
+
console.log(`\x1b[32m✓\x1b[0m ${message}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function warn(message: string): void {
|
|
51
|
+
console.log(`\x1b[33m⚠\x1b[0m ${message}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function error(message: string): void {
|
|
55
|
+
console.error(`\x1b[31m✗\x1b[0m ${message}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function parseVersion(version: string): { major: number; minor: number; patch: number } {
|
|
59
|
+
const [major, minor, patch] = version.split('.').map(Number);
|
|
60
|
+
return { major, minor, patch };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function bumpPatch(version: string): string {
|
|
64
|
+
const { major, minor, patch } = parseVersion(version);
|
|
65
|
+
return `${major}.${minor}.${patch + 1}`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function main(): Promise<void> {
|
|
69
|
+
// Read package.json
|
|
70
|
+
const packageJsonPath = 'package.json';
|
|
71
|
+
const packageJson: PackageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
72
|
+
const { name, version: localVersion } = packageJson;
|
|
73
|
+
|
|
74
|
+
log(`Package: ${name}`);
|
|
75
|
+
log(`Local version: ${localVersion}`);
|
|
76
|
+
|
|
77
|
+
// Get current npm version
|
|
78
|
+
let npmVersion = '';
|
|
79
|
+
try {
|
|
80
|
+
npmVersion = exec(`npm view ${name} version 2>/dev/null`, true);
|
|
81
|
+
log(`npm version: ${npmVersion || 'not published'}`);
|
|
82
|
+
} catch {
|
|
83
|
+
log('npm version: not published yet');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Determine new version
|
|
87
|
+
let newVersion = localVersion;
|
|
88
|
+
if (npmVersion) {
|
|
89
|
+
const localParsed = parseVersion(localVersion);
|
|
90
|
+
const npmParsed = parseVersion(npmVersion);
|
|
91
|
+
|
|
92
|
+
// If local version <= npm version, bump from npm version
|
|
93
|
+
if (
|
|
94
|
+
localParsed.major < npmParsed.major ||
|
|
95
|
+
(localParsed.major === npmParsed.major && localParsed.minor < npmParsed.minor) ||
|
|
96
|
+
(localParsed.major === npmParsed.major &&
|
|
97
|
+
localParsed.minor === npmParsed.minor &&
|
|
98
|
+
localParsed.patch <= npmParsed.patch)
|
|
99
|
+
) {
|
|
100
|
+
newVersion = bumpPatch(npmVersion);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (newVersion !== localVersion) {
|
|
105
|
+
log(`Bumping version: ${localVersion} → ${newVersion}`);
|
|
106
|
+
|
|
107
|
+
if (!isDryRun) {
|
|
108
|
+
packageJson.version = newVersion;
|
|
109
|
+
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
log(`Version unchanged: ${newVersion}`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Run typecheck
|
|
116
|
+
log('Running typecheck...');
|
|
117
|
+
if (!isDryRun) {
|
|
118
|
+
exec('bun run typecheck');
|
|
119
|
+
success('Typecheck passed');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Build
|
|
123
|
+
log('Building...');
|
|
124
|
+
if (!isDryRun) {
|
|
125
|
+
exec('bun run build');
|
|
126
|
+
success('Build completed');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Git operations
|
|
130
|
+
const gitStatus = exec('git status --porcelain', true);
|
|
131
|
+
if (gitStatus) {
|
|
132
|
+
log('Staging changes...');
|
|
133
|
+
if (!isDryRun) {
|
|
134
|
+
exec('git add package.json');
|
|
135
|
+
exec(`git commit -m "chore: release v${newVersion}"`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Create git tag
|
|
140
|
+
const tagName = `v${newVersion}`;
|
|
141
|
+
log(`Creating tag: ${tagName}`);
|
|
142
|
+
if (!isDryRun) {
|
|
143
|
+
try {
|
|
144
|
+
exec(`git tag ${tagName}`);
|
|
145
|
+
success(`Tag ${tagName} created`);
|
|
146
|
+
} catch {
|
|
147
|
+
warn(`Tag ${tagName} already exists`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Publish
|
|
152
|
+
log('Publishing to npm...');
|
|
153
|
+
if (isDryRun) {
|
|
154
|
+
warn('Dry run - skipping publish');
|
|
155
|
+
exec('npm publish --dry-run');
|
|
156
|
+
} else {
|
|
157
|
+
exec('npm publish');
|
|
158
|
+
success(`Published ${name}@${newVersion}`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Push tags
|
|
162
|
+
if (!isDryRun) {
|
|
163
|
+
log('Pushing tags...');
|
|
164
|
+
try {
|
|
165
|
+
exec('git push --tags');
|
|
166
|
+
success('Tags pushed');
|
|
167
|
+
} catch {
|
|
168
|
+
warn('Failed to push tags (you may need to push manually)');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
console.log('');
|
|
173
|
+
success(`Release ${isDryRun ? '(dry run) ' : ''}complete: ${name}@${newVersion}`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
main().catch((err) => {
|
|
177
|
+
error(String(err));
|
|
178
|
+
process.exit(1);
|
|
179
|
+
});
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import type { ConnectorConfig, OutputFormat } from '../types';
|
|
2
|
+
import { ConnectorApiError, parseApiError } from '../types';
|
|
3
|
+
|
|
4
|
+
// TODO: Replace with your API's base URL
|
|
5
|
+
const DEFAULT_BASE_URL = 'https://api.example.com';
|
|
6
|
+
|
|
7
|
+
export interface RequestOptions {
|
|
8
|
+
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
9
|
+
params?: Record<string, string | number | boolean | undefined>;
|
|
10
|
+
body?: Record<string, unknown> | unknown[] | string;
|
|
11
|
+
headers?: Record<string, string>;
|
|
12
|
+
format?: OutputFormat;
|
|
13
|
+
/** Number of retries for failed requests (default: 3) */
|
|
14
|
+
retries?: number;
|
|
15
|
+
/** Timeout in milliseconds (default: 30000) */
|
|
16
|
+
timeout?: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class ConnectorClient {
|
|
20
|
+
private readonly apiKey: string;
|
|
21
|
+
private readonly apiSecret?: string;
|
|
22
|
+
private readonly baseUrl: string;
|
|
23
|
+
|
|
24
|
+
constructor(config: ConnectorConfig) {
|
|
25
|
+
// Support both 'apiKey' and 'token' for flexibility
|
|
26
|
+
// Also support 'accessToken' for OAuth2
|
|
27
|
+
const key = config.apiKey || config.token || config.accessToken;
|
|
28
|
+
if (!key) {
|
|
29
|
+
throw new Error('API key, token, or accessToken is required');
|
|
30
|
+
}
|
|
31
|
+
this.apiKey = key;
|
|
32
|
+
this.apiSecret = config.apiSecret;
|
|
33
|
+
this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {
|
|
37
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
38
|
+
|
|
39
|
+
if (params) {
|
|
40
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
41
|
+
if (value !== undefined && value !== null && value !== '') {
|
|
42
|
+
url.searchParams.append(key, String(value));
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return url.toString();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Sleep for a given number of milliseconds
|
|
52
|
+
*/
|
|
53
|
+
private sleep(ms: number): Promise<void> {
|
|
54
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Calculate delay for exponential backoff
|
|
59
|
+
*/
|
|
60
|
+
private getRetryDelay(attempt: number, baseDelay: number = 1000): number {
|
|
61
|
+
// Exponential backoff with jitter: base * 2^attempt + random(0-1000)ms
|
|
62
|
+
return baseDelay * Math.pow(2, attempt) + Math.random() * 1000;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Check if error is retryable
|
|
67
|
+
*/
|
|
68
|
+
private isRetryableStatus(status: number): boolean {
|
|
69
|
+
// Retry on rate limit (429) and server errors (5xx)
|
|
70
|
+
return status === 429 || (status >= 500 && status < 600);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Make an authenticated request to the API
|
|
75
|
+
* TODO: Adjust authentication method for your API:
|
|
76
|
+
* - Bearer token: Authorization: Bearer <token>
|
|
77
|
+
* - API Key header: X-API-Key: <key>
|
|
78
|
+
* - Basic auth: Authorization: Basic <base64(key:secret)>
|
|
79
|
+
*/
|
|
80
|
+
async request<T>(path: string, options: RequestOptions = {}): Promise<T> {
|
|
81
|
+
const { method = 'GET', params, body, headers = {}, retries = 3, timeout = 30000 } = options;
|
|
82
|
+
|
|
83
|
+
const url = this.buildUrl(path, params);
|
|
84
|
+
|
|
85
|
+
// TODO: Adjust authentication header for your API
|
|
86
|
+
const requestHeaders: Record<string, string> = {
|
|
87
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
88
|
+
'Accept': 'application/json',
|
|
89
|
+
...headers,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
if (body && ['POST', 'PUT', 'PATCH'].includes(method)) {
|
|
93
|
+
requestHeaders['Content-Type'] = 'application/json';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const fetchOptions: RequestInit = {
|
|
97
|
+
method,
|
|
98
|
+
headers: requestHeaders,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
if (body && ['POST', 'PUT', 'PATCH'].includes(method)) {
|
|
102
|
+
fetchOptions.body = typeof body === 'string' ? body : JSON.stringify(body);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
let lastError: Error | null = null;
|
|
106
|
+
let lastStatus: number = 0;
|
|
107
|
+
|
|
108
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
109
|
+
try {
|
|
110
|
+
// Create abort controller for timeout
|
|
111
|
+
const controller = new AbortController();
|
|
112
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
113
|
+
|
|
114
|
+
const response = await fetch(url, {
|
|
115
|
+
...fetchOptions,
|
|
116
|
+
signal: controller.signal,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
clearTimeout(timeoutId);
|
|
120
|
+
lastStatus = response.status;
|
|
121
|
+
|
|
122
|
+
// Handle 204 No Content
|
|
123
|
+
if (response.status === 204) {
|
|
124
|
+
return {} as T;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Parse response
|
|
128
|
+
let data: unknown;
|
|
129
|
+
const contentType = response.headers.get('content-type') || '';
|
|
130
|
+
|
|
131
|
+
if (contentType.includes('application/json')) {
|
|
132
|
+
const text = await response.text();
|
|
133
|
+
if (text) {
|
|
134
|
+
try {
|
|
135
|
+
data = JSON.parse(text);
|
|
136
|
+
} catch {
|
|
137
|
+
data = text;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
data = await response.text();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Handle errors
|
|
145
|
+
if (!response.ok) {
|
|
146
|
+
// Check if we should retry
|
|
147
|
+
if (this.isRetryableStatus(response.status) && attempt < retries) {
|
|
148
|
+
// Check for Retry-After header
|
|
149
|
+
const retryAfter = response.headers.get('retry-after');
|
|
150
|
+
const delay = retryAfter
|
|
151
|
+
? parseInt(retryAfter, 10) * 1000
|
|
152
|
+
: this.getRetryDelay(attempt);
|
|
153
|
+
|
|
154
|
+
await this.sleep(delay);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
throw parseApiError(data, response.status);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return data as T;
|
|
162
|
+
} catch (err) {
|
|
163
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
164
|
+
|
|
165
|
+
// Handle timeout errors
|
|
166
|
+
if (lastError.name === 'AbortError') {
|
|
167
|
+
lastError = new Error(`Request timeout after ${timeout}ms`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Retry on network errors
|
|
171
|
+
if (attempt < retries && !(err instanceof ConnectorApiError)) {
|
|
172
|
+
await this.sleep(this.getRetryDelay(attempt));
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
throw err;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Should not reach here, but just in case
|
|
181
|
+
throw lastError || new ConnectorApiError('Request failed', lastStatus);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async get<T>(path: string, params?: Record<string, string | number | boolean | undefined>): Promise<T> {
|
|
185
|
+
return this.request<T>(path, { method: 'GET', params });
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async post<T>(path: string, body?: Record<string, unknown> | unknown[] | string | object, params?: Record<string, string | number | boolean | undefined>): Promise<T> {
|
|
189
|
+
return this.request<T>(path, { method: 'POST', body: body as Record<string, unknown>, params });
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async put<T>(path: string, body?: Record<string, unknown> | object, params?: Record<string, string | number | boolean | undefined>): Promise<T> {
|
|
193
|
+
return this.request<T>(path, { method: 'PUT', body: body as Record<string, unknown>, params });
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async patch<T>(path: string, body?: Record<string, unknown> | object, params?: Record<string, string | number | boolean | undefined>): Promise<T> {
|
|
197
|
+
return this.request<T>(path, { method: 'PATCH', body: body as Record<string, unknown>, params });
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async delete<T>(path: string, params?: Record<string, string | number | boolean | undefined>): Promise<T> {
|
|
201
|
+
return this.request<T>(path, { method: 'DELETE', params });
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Get a preview of the API key (for display/debugging)
|
|
206
|
+
*/
|
|
207
|
+
getApiKeyPreview(): string {
|
|
208
|
+
if (this.apiKey.length > 10) {
|
|
209
|
+
return `${this.apiKey.substring(0, 6)}...${this.apiKey.substring(this.apiKey.length - 4)}`;
|
|
210
|
+
}
|
|
211
|
+
return '***';
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ConnectorClient } from './client';
|
|
2
|
+
import type { ExampleResource, ExampleListResponse, ExampleCreateParams } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Example API module - demonstrates the pattern for API modules
|
|
6
|
+
* TODO: Replace with your actual API endpoints
|
|
7
|
+
*/
|
|
8
|
+
export class ExampleApi {
|
|
9
|
+
constructor(private readonly client: ConnectorClient) {}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* List resources with optional pagination
|
|
13
|
+
*/
|
|
14
|
+
async list(options?: { maxResults?: number; pageToken?: string }): Promise<ExampleListResponse> {
|
|
15
|
+
return this.client.get<ExampleListResponse>('/resources', {
|
|
16
|
+
max_results: options?.maxResults,
|
|
17
|
+
page_token: options?.pageToken,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Get a single resource by ID
|
|
23
|
+
*/
|
|
24
|
+
async get(id: string): Promise<ExampleResource> {
|
|
25
|
+
return this.client.get<ExampleResource>(`/resources/${id}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Create a new resource
|
|
30
|
+
*/
|
|
31
|
+
async create(params: ExampleCreateParams): Promise<ExampleResource> {
|
|
32
|
+
return this.client.post<ExampleResource>('/resources', params);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Update an existing resource
|
|
37
|
+
*/
|
|
38
|
+
async update(id: string, params: Partial<ExampleCreateParams>): Promise<ExampleResource> {
|
|
39
|
+
return this.client.patch<ExampleResource>(`/resources/${id}`, params);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Delete a resource
|
|
44
|
+
*/
|
|
45
|
+
async delete(id: string): Promise<void> {
|
|
46
|
+
await this.client.delete(`/resources/${id}`);
|
|
47
|
+
}
|
|
48
|
+
}
|