@hasna/connectors 1.4.1 → 1.4.3
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 +1271 -317
- package/bin/mcp.js +524 -211
- package/bin/serve.js +1208 -256
- package/connectors/adobe/package.json +1 -1
- package/connectors/aitableai/package.json +1 -1
- package/connectors/alchemy/package.json +1 -1
- package/connectors/alerty/package.json +1 -1
- package/connectors/alienvault/package.json +1 -1
- package/connectors/alphamoon/package.json +1 -1
- package/connectors/alttextai/package.json +1 -1
- package/connectors/amadeus/package.json +1 -1
- package/connectors/amadeus/src/api/client.ts +6 -6
- package/connectors/amadeus/src/cli/index.ts +6 -6
- package/connectors/amadeus/src/utils/output.ts +5 -5
- package/connectors/amazon/package.json +1 -1
- package/connectors/amilia/package.json +1 -1
- package/connectors/amqpsender/package.json +1 -1
- package/connectors/announcekit/package.json +1 -1
- package/connectors/anthropic/.env.example +1 -1
- package/connectors/anyscale/package.json +1 -1
- package/connectors/apiary/package.json +1 -1
- package/connectors/apiflash/package.json +1 -1
- package/connectors/apitemplateio/package.json +1 -1
- package/connectors/apptivegrid/package.json +1 -1
- package/connectors/assemblyai/package.json +1 -1
- package/connectors/autom/package.json +1 -1
- package/connectors/automizy/package.json +1 -1
- package/connectors/autopilot/package.json +1 -1
- package/connectors/awscognito/package.json +1 -1
- package/connectors/bamboohr/package.json +1 -1
- package/connectors/bannerbear/package.json +1 -1
- package/connectors/baseten/package.json +1 -1
- package/connectors/box/package.json +1 -1
- package/connectors/brevo/package.json +1 -1
- package/connectors/calendly/package.json +1 -1
- package/connectors/cerebras/package.json +1 -1
- package/connectors/chargebee/package.json +1 -1
- package/connectors/clearbit/package.json +1 -1
- package/connectors/clickbank/README.md +2 -2
- package/connectors/cloudflare-workers/package.json +1 -1
- package/connectors/coda/package.json +1 -1
- package/connectors/coingecko/package.json +1 -1
- package/connectors/convertkit/package.json +1 -1
- package/connectors/customerio/package.json +1 -1
- package/connectors/databricks/package.json +1 -1
- package/connectors/datadog/package.json +1 -1
- package/connectors/datasoap/README.md +2 -2
- package/connectors/datasoap/package.json +1 -1
- package/connectors/datumbox/README.md +2 -2
- package/connectors/datumbox/package.json +1 -1
- package/connectors/dayschedule/README.md +2 -2
- package/connectors/dayschedule/package.json +1 -1
- package/connectors/deepgram/package.json +1 -1
- package/connectors/deepinfra/README.md +2 -2
- package/connectors/deepinfra/package.json +1 -1
- package/connectors/deepl/README.md +2 -2
- package/connectors/deepl/package.json +1 -1
- package/connectors/deepseek/package.json +1 -1
- package/connectors/demio/README.md +2 -2
- package/connectors/demio/package.json +1 -1
- package/connectors/descript/README.md +2 -2
- package/connectors/descript/package.json +1 -1
- package/connectors/detrack/README.md +2 -2
- package/connectors/detrack/package.json +1 -1
- package/connectors/devcycle/README.md +2 -2
- package/connectors/devcycle/package.json +1 -1
- package/connectors/dhl/README.md +2 -2
- package/connectors/dhl/package.json +1 -1
- package/connectors/docusign/package.json +1 -1
- package/connectors/dropbox/package.json +1 -1
- package/connectors/fal/package.json +1 -1
- package/connectors/fathom/package.json +1 -1
- package/connectors/fireworks/package.json +1 -1
- package/connectors/gitlab/package.json +1 -1
- package/connectors/googlechat/README.md +1 -2
- package/connectors/googledrive/src/api/client.ts +5 -5
- package/connectors/googledrive/src/api/files.ts +11 -11
- package/connectors/googledrive/src/api/folders.ts +2 -2
- package/connectors/googledrive/src/cli/index.ts +4 -4
- package/connectors/googledrive/src/utils/output.ts +3 -3
- package/connectors/googleforms/README.md +1 -2
- package/connectors/googleperspective/README.md +1 -2
- package/connectors/grafana/package.json +1 -1
- package/connectors/growbots/README.md +2 -2
- package/connectors/growbots/package.json +1 -1
- package/connectors/gumroad/package.json +1 -1
- package/connectors/gupshup/README.md +2 -2
- package/connectors/gupshup/package.json +1 -1
- package/connectors/guru/README.md +2 -2
- package/connectors/guru/package.json +1 -1
- package/connectors/hackernews/README.md +2 -2
- package/connectors/hackernews/package.json +1 -1
- package/connectors/halopsa/README.md +2 -2
- package/connectors/halopsa/package.json +1 -1
- package/connectors/handwrytten/README.md +2 -2
- package/connectors/handwrytten/package.json +1 -1
- package/connectors/hansei/README.md +2 -2
- package/connectors/hansei/package.json +1 -1
- package/connectors/harrypotterapi/README.md +2 -2
- package/connectors/harrypotterapi/package.json +1 -1
- package/connectors/harvest/README.md +2 -2
- package/connectors/harvest/package.json +1 -1
- package/connectors/headlesstesting/README.md +2 -2
- package/connectors/headlesstesting/package.json +1 -1
- package/connectors/homeassistant/package.json +1 -1
- package/connectors/klaviyo/package.json +1 -1
- package/connectors/lemonsqueezy/package.json +1 -1
- package/connectors/lighthouse/src/api/index.ts +1 -1
- package/connectors/linkedin/package.json +1 -1
- package/connectors/linkish/README.md +2 -2
- package/connectors/linkish/package.json +1 -1
- package/connectors/liveagent/README.md +2 -2
- package/connectors/liveagent/package.json +1 -1
- package/connectors/localazy/README.md +2 -2
- package/connectors/localazy/package.json +1 -1
- package/connectors/loginradius/README.md +2 -2
- package/connectors/loginradius/package.json +1 -1
- package/connectors/lokalise/README.md +2 -2
- package/connectors/lokalise/package.json +1 -1
- package/connectors/lonescale/README.md +2 -2
- package/connectors/lonescale/package.json +1 -1
- package/connectors/lucidchart/README.md +2 -2
- package/connectors/lucidchart/package.json +1 -1
- package/connectors/luma/package.json +1 -1
- package/connectors/magento2/README.md +2 -2
- package/connectors/magento2/package.json +1 -1
- package/connectors/mailcheck/README.md +2 -2
- package/connectors/mailcheck/package.json +1 -1
- package/connectors/mailchimp/package.json +1 -1
- package/connectors/mailerlite/README.md +2 -2
- package/connectors/mailerlite/package.json +1 -1
- package/connectors/mailersend/README.md +2 -2
- package/connectors/mailersend/package.json +1 -1
- package/connectors/mailify/README.md +2 -2
- package/connectors/mailify/package.json +1 -1
- package/connectors/mailjet/README.md +2 -2
- package/connectors/mailjet/package.json +1 -1
- package/connectors/mailmodo/README.md +2 -2
- package/connectors/mailmodo/package.json +1 -1
- package/connectors/malcore/README.md +2 -2
- package/connectors/malcore/package.json +1 -1
- package/connectors/mandrill/README.md +2 -2
- package/connectors/mandrill/package.json +1 -1
- package/connectors/marcomrobot/README.md +2 -2
- package/connectors/marcomrobot/package.json +1 -1
- package/connectors/marketingmasterio/README.md +2 -2
- package/connectors/marketingmasterio/package.json +1 -1
- package/connectors/marketplacer/README.md +2 -2
- package/connectors/marketplacer/package.json +1 -1
- package/connectors/marketstack/README.md +2 -2
- package/connectors/marketstack/package.json +1 -1
- package/connectors/matrix/README.md +1 -1
- package/connectors/matrix/package.json +1 -1
- package/connectors/mattermost/README.md +1 -1
- package/connectors/mattermost/package.json +1 -1
- package/connectors/mautic/README.md +1 -1
- package/connectors/mautic/package.json +1 -1
- package/connectors/mav/README.md +1 -1
- package/connectors/mav/package.json +1 -1
- package/connectors/maverick/README.md +1 -1
- package/connectors/maverick/package.json +1 -1
- package/connectors/mem/README.md +1 -1
- package/connectors/mem/package.json +1 -1
- package/connectors/messagebird/package.json +1 -1
- package/connectors/metabase/README.md +1 -1
- package/connectors/metabase/package.json +1 -1
- package/connectors/miro/package.json +1 -1
- package/connectors/mocean/package.json +1 -1
- package/connectors/modal/package.json +1 -1
- package/connectors/monday/package.json +1 -1
- package/connectors/monicacrm/package.json +1 -1
- package/connectors/moonclerk/package.json +1 -1
- package/connectors/moonmail/package.json +1 -1
- package/connectors/morph/package.json +1 -1
- package/connectors/mqtt/package.json +1 -1
- package/connectors/msg91/package.json +1 -1
- package/connectors/mubert/package.json +1 -1
- package/connectors/murf/package.json +1 -1
- package/connectors/mux/package.json +1 -1
- package/connectors/netlify/package.json +1 -1
- package/connectors/okta/package.json +1 -1
- package/connectors/paddle/package.json +1 -1
- package/connectors/perplexity/package.json +1 -1
- package/connectors/pinterest/package.json +1 -1
- package/connectors/pipedrive/package.json +1 -1
- package/connectors/plaid/package.json +1 -1
- package/connectors/quickchart/README.md +2 -2
- package/connectors/quintadb/README.md +2 -2
- package/connectors/rabbitmq/README.md +2 -2
- package/connectors/radar/README.md +2 -2
- package/connectors/raindrop/README.md +2 -2
- package/connectors/rapid7insightvm/README.md +2 -2
- package/connectors/raventools/README.md +2 -2
- package/connectors/rawgvideogamesdatabase/README.md +2 -2
- package/connectors/rdstationcrm/README.md +2 -2
- package/connectors/readai/README.md +2 -2
- package/connectors/roboflow/package.json +1 -1
- package/connectors/runway/package.json +1 -1
- package/connectors/sendgrid/package.json +1 -1
- package/connectors/shuffler/package.json +1 -1
- package/connectors/sierrainteractive/package.json +1 -1
- package/connectors/sifter/package.json +1 -1
- package/connectors/signaturit/package.json +1 -1
- package/connectors/signl4/package.json +1 -1
- package/connectors/simpleem/package.json +1 -1
- package/connectors/simplehash/package.json +1 -1
- package/connectors/simplekpi/package.json +1 -1
- package/connectors/simplelocalize/package.json +1 -1
- package/connectors/simplero/package.json +1 -1
- package/connectors/smartrecruiters/package.json +1 -1
- package/connectors/smtp2go/package.json +1 -1
- package/connectors/snowflake/package.json +1 -1
- package/connectors/sparkpost/package.json +1 -1
- package/connectors/split-in-batches/CLAUDE.md +1 -1
- package/connectors/split-in-batches/README.md +1 -1
- package/connectors/split-in-batches/src/api/client.test.ts +16 -17
- package/connectors/split-in-batches/src/api/client.ts +4 -3
- package/connectors/split-in-batches/src/cli/index.ts +1 -1
- package/connectors/split-io/package.json +1 -1
- package/connectors/split-io/src/api/client.test.ts +20 -0
- package/connectors/split-io/src/cli/index.ts +9 -9
- package/connectors/spreadsheet-file/.env.example +1 -1
- package/connectors/spreadsheet-file/CLAUDE.md +2 -2
- package/connectors/spreadsheet-file/README.md +3 -3
- package/connectors/spreadsheet-file/src/api/client.test.ts +8 -9
- package/connectors/spreadsheet-file/src/api/client.ts +4 -3
- package/connectors/spreadsheet-file/src/cli/index.ts +1 -1
- package/connectors/sprinklr/package.json +1 -1
- package/connectors/sprout-social/package.json +1 -1
- package/connectors/square/package.json +1 -1
- package/connectors/sse-trigger/.env.example +1 -1
- package/connectors/sse-trigger/CLAUDE.md +2 -2
- package/connectors/sse-trigger/README.md +1 -1
- package/connectors/sse-trigger/package.json +1 -1
- package/connectors/sse-trigger/src/api/client.test.ts +12 -8
- package/connectors/sse-trigger/src/api/client.ts +4 -3
- package/connectors/sse-trigger/src/api/index.ts +1 -1
- package/connectors/sse-trigger/src/cli/index.ts +1 -1
- package/connectors/sse-trigger/src/index.ts +1 -1
- package/connectors/stability-api-platform/AGENTS.md +2 -2
- package/connectors/stability-api-platform/CLAUDE.md +1 -1
- package/connectors/stability-api-platform/README.md +2 -2
- package/connectors/stability-api-platform/src/api/client.test.ts +17 -12
- package/connectors/stability-api-platform/src/api/client.ts +4 -3
- package/connectors/stability-api-platform/src/api/index.ts +0 -1
- package/connectors/stability-api-platform/src/cli/index.ts +1 -1
- package/connectors/stability-api-platform/src/index.ts +0 -1
- package/connectors/standout/package.json +1 -1
- package/connectors/statuspage/package.json +1 -1
- package/connectors/stop-and-error/.env.example +1 -1
- package/connectors/stop-and-error/CLAUDE.md +1 -1
- package/connectors/stop-and-error/README.md +1 -1
- package/connectors/stop-and-error/src/api/client.test.ts +12 -8
- package/connectors/stop-and-error/src/api/client.ts +4 -3
- package/connectors/stop-and-error/src/cli/index.ts +2 -2
- package/connectors/stoplight/package.json +1 -1
- package/connectors/stoplight-api-platform/package.json +1 -1
- package/connectors/strand-ai/CLAUDE.md +1 -1
- package/connectors/stripe-financial-connections/.env.example +1 -1
- package/connectors/stripe-financial-connections/CLAUDE.md +2 -2
- package/connectors/stripe-financial-connections/package.json +1 -1
- package/connectors/stripe-financial-connections/src/api/client.test.ts +34 -0
- package/connectors/stripe-financial-connections/src/api/client.ts +4 -3
- package/connectors/stripe-financial-connections/src/cli/index.ts +1 -1
- package/connectors/stripe-terminal/package.json +1 -1
- package/connectors/stytch/package.json +1 -1
- package/connectors/sucuri-api-platform/.env.example +1 -1
- package/connectors/sucuri-api-platform/CLAUDE.md +1 -1
- package/connectors/sucuri-api-platform/README.md +2 -2
- package/connectors/sucuri-api-platform/src/api/client.test.ts +9 -7
- package/connectors/sucuri-api-platform/src/api/client.ts +4 -3
- package/connectors/sucuri-api-platform/src/api/index.ts +1 -1
- package/connectors/sucuri-api-platform/src/cli/index.ts +1 -1
- package/connectors/sucuri-api-platform/src/index.ts +1 -1
- package/connectors/sumo-logic/package.json +1 -1
- package/connectors/supabase/package.json +1 -1
- package/connectors/supabase-api-platform/package.json +1 -1
- package/connectors/sysdig/package.json +1 -1
- package/connectors/tableau/package.json +1 -1
- package/connectors/takecareos/README.md +2 -2
- package/connectors/takecareos/package.json +1 -1
- package/connectors/telegram/src/api/bot.ts +20 -0
- package/connectors/telegram/src/api/client.ts +32 -0
- package/connectors/telegram/src/api/files.test.ts +103 -0
- package/connectors/telegram/src/api/index.ts +1 -0
- package/connectors/telegram/src/api/messages.test.ts +8 -2
- package/connectors/telegram/src/cli/files.test.ts +40 -0
- package/connectors/telegram/src/cli/files.ts +38 -0
- package/connectors/telegram/src/cli/index.ts +27 -30
- package/connectors/telegram/src/cli/updates.test.ts +176 -0
- package/connectors/telegram/src/cli/updates.ts +95 -0
- package/connectors/telegram/src/index.ts +1 -0
- package/connectors/telegram/src/types/index.ts +13 -0
- package/connectors/terraform-cloud/package.json +1 -1
- package/connectors/tettra-api-platform/CLAUDE.md +1 -1
- package/connectors/tettra-api-platform/README.md +2 -2
- package/connectors/tettra-api-platform/src/api/client.test.ts +7 -8
- package/connectors/tettra-api-platform/src/api/client.ts +4 -3
- package/connectors/tettra-api-platform/src/api/index.ts +1 -1
- package/connectors/tettra-api-platform/src/cli/index.ts +1 -1
- package/connectors/tettra-api-platform/src/index.ts +1 -1
- package/connectors/textit/package.json +1 -1
- package/connectors/thousandeyes/package.json +1 -1
- package/connectors/ticket-tailor/package.json +1 -1
- package/connectors/ticketsource/package.json +1 -1
- package/connectors/tiktokads/README.md +1 -1
- package/connectors/time-saved/package.json +1 -1
- package/connectors/tipalti/package.json +1 -1
- package/connectors/together-api-platform/.env.example +1 -1
- package/connectors/together-api-platform/CLAUDE.md +1 -1
- package/connectors/together-api-platform/README.md +1 -1
- package/connectors/together-api-platform/src/api/client.test.ts +11 -7
- package/connectors/together-api-platform/src/api/client.ts +4 -4
- package/connectors/together-api-platform/src/api/index.ts +1 -1
- package/connectors/together-api-platform/src/cli/index.ts +1 -1
- package/connectors/together-api-platform/src/index.ts +1 -1
- package/connectors/tomtom/AGENTS.md +1 -1
- package/connectors/totp/package.json +1 -1
- package/connectors/traverse/package.json +1 -1
- package/connectors/travo-ai/package.json +1 -1
- package/connectors/travo-real-estate/CLAUDE.md +1 -1
- package/connectors/travo-real-estate/README.md +1 -1
- package/connectors/travo-real-estate/src/api/client.test.ts +20 -16
- package/connectors/travo-real-estate/src/api/client.ts +4 -3
- package/connectors/travo-real-estate/src/utils/config.ts +2 -4
- package/connectors/tray-api-platform/CLAUDE.md +1 -1
- package/connectors/tray-api-platform/src/api/client.test.ts +17 -13
- package/connectors/tray-api-platform/src/api/client.ts +4 -3
- package/connectors/tray-api-platform/src/api/index.ts +1 -1
- package/connectors/tray-api-platform/src/cli/index.ts +1 -1
- package/connectors/tray-api-platform/src/index.ts +0 -1
- package/connectors/trigger-dev/package.json +1 -1
- package/connectors/trigger-dev-api-platform/package.json +1 -1
- package/connectors/turbot-pipes/package.json +1 -1
- package/connectors/turso/package.json +1 -1
- package/connectors/turso-api-platform/CLAUDE.md +1 -1
- package/connectors/turso-api-platform/README.md +2 -2
- package/connectors/turso-api-platform/package.json +1 -1
- package/connectors/turso-api-platform/src/api/client.test.ts +17 -13
- package/connectors/turso-api-platform/src/api/client.ts +4 -3
- package/connectors/turso-api-platform/src/cli/index.ts +2 -2
- package/connectors/twilio-api-platform/CLAUDE.md +1 -1
- package/connectors/twilio-api-platform/src/api/client.test.ts +11 -11
- package/connectors/twilio-api-platform/src/api/client.ts +4 -3
- package/connectors/twilio-api-platform/src/api/index.ts +1 -1
- package/connectors/twilio-api-platform/src/cli/index.ts +1 -1
- package/connectors/twilio-api-platform/src/index.ts +1 -1
- package/connectors/tyk-api-platform/.env.example +1 -1
- package/connectors/tyk-api-platform/CLAUDE.md +2 -2
- package/connectors/tyk-api-platform/README.md +1 -1
- package/connectors/tyk-api-platform/package.json +1 -1
- package/connectors/tyk-api-platform/src/api/client.test.ts +14 -15
- package/connectors/tyk-api-platform/src/api/client.ts +4 -3
- package/connectors/tyk-api-platform/src/api/index.ts +1 -1
- package/connectors/tyk-api-platform/src/cli/index.ts +1 -1
- package/connectors/tyk-api-platform/src/index.ts +1 -1
- package/connectors/umami/package.json +1 -1
- package/connectors/unifold/package.json +1 -1
- package/connectors/unione/package.json +1 -1
- package/connectors/uniprot/README.md +1 -1
- package/connectors/uniswap-api/package.json +1 -1
- package/connectors/ups/package.json +1 -1
- package/connectors/usereframe/package.json +1 -1
- package/connectors/vanta/package.json +1 -1
- package/connectors/vector-legal/.env.example +1 -1
- package/connectors/vector-legal/AGENTS.md +1 -1
- package/connectors/vector-legal/CLAUDE.md +1 -1
- package/connectors/vector-legal/README.md +1 -1
- package/connectors/vector-legal/src/api/client.test.ts +9 -5
- package/connectors/vector-legal/src/api/client.ts +4 -3
- package/connectors/vector-legal/src/api/index.ts +1 -1
- package/connectors/vector-legal/src/cli/index.ts +2 -2
- package/connectors/vector-legal/src/index.ts +0 -1
- package/connectors/vector-legal-api/CLAUDE.md +1 -1
- package/connectors/vector-legal-api/README.md +2 -2
- package/connectors/vector-legal-api/src/api/client.test.ts +12 -7
- package/connectors/vector-legal-api/src/api/client.ts +4 -3
- package/connectors/vector-legal-api/src/api/index.ts +1 -1
- package/connectors/vector-legal-api/src/cli/index.ts +1 -1
- package/connectors/vector-legal-api/src/index.ts +1 -2
- package/connectors/vela/package.json +1 -1
- package/connectors/velum-data-quality/.env.example +1 -1
- package/connectors/velum-data-quality/CLAUDE.md +1 -1
- package/connectors/velum-data-quality/src/api/client.test.ts +15 -16
- package/connectors/velum-data-quality/src/api/client.ts +4 -3
- package/connectors/velum-data-quality/src/api/index.ts +1 -1
- package/connectors/velum-data-quality/src/cli/index.ts +1 -1
- package/connectors/velum-data-quality/src/index.ts +0 -1
- package/connectors/velum-labs/package.json +1 -1
- package/connectors/vercel/package.json +1 -1
- package/connectors/vercel-api-platform/.env.example +1 -1
- package/connectors/vercel-api-platform/CLAUDE.md +2 -2
- package/connectors/vercel-api-platform/README.md +2 -2
- package/connectors/vercel-api-platform/src/api/client.test.ts +27 -6
- package/connectors/vercel-api-platform/src/api/client.ts +4 -3
- package/connectors/vercel-api-platform/src/api/index.ts +1 -1
- package/connectors/vercel-api-platform/src/cli/index.ts +2 -2
- package/connectors/vercel-api-platform/src/index.ts +0 -1
- package/connectors/vercel-blob/package.json +1 -1
- package/connectors/vercel-blob-platform/package.json +1 -1
- package/connectors/vercel-edge-config/package.json +1 -1
- package/connectors/vercel-edge-config-platform/package.json +1 -1
- package/connectors/veriphone/README.md +2 -2
- package/connectors/vertex-ai/package.json +1 -1
- package/connectors/vidyard/package.json +1 -1
- package/connectors/vonage/package.json +1 -1
- package/connectors/voygr/package.json +1 -1
- package/connectors/wait/package.json +1 -1
- package/connectors/walmart-marketplace/package.json +1 -1
- package/connectors/wato/package.json +1 -1
- package/connectors/wave-accounting/CLAUDE.md +1 -1
- package/connectors/wave-accounting/package.json +1 -1
- package/connectors/wave-accounting/src/utils/auth.ts +1 -1
- package/connectors/wayco/package.json +1 -1
- package/connectors/weaviate-api-platform/CLAUDE.md +1 -1
- package/connectors/weaviate-api-platform/src/api/client.test.ts +32 -7
- package/connectors/weaviate-api-platform/src/api/client.ts +4 -3
- package/connectors/weaviate-api-platform/src/api/index.ts +1 -1
- package/connectors/weaviate-api-platform/src/cli/index.ts +1 -1
- package/connectors/weaviate-api-platform/src/index.ts +1 -1
- package/connectors/webpagetest/package.json +1 -1
- package/connectors/weezevent/package.json +1 -1
- package/connectors/wikipedia/src/api/client.ts +1 -1
- package/connectors/wildcard/package.json +1 -1
- package/connectors/windmill/package.json +1 -1
- package/connectors/wise/package.json +1 -1
- package/connectors/withai/package.json +1 -1
- package/connectors/wiz/CLAUDE.md +1 -1
- package/connectors/wiz/package.json +1 -1
- package/connectors/wordfence/package.json +1 -1
- package/connectors/wordfence-api-platform/package.json +1 -1
- package/connectors/workflow-trigger/.env.example +1 -1
- package/connectors/workflow-trigger/CLAUDE.md +1 -1
- package/connectors/workflow-trigger/README.md +1 -1
- package/connectors/workflow-trigger/src/api/client.test.ts +10 -6
- package/connectors/workflow-trigger/src/api/client.ts +4 -3
- package/connectors/workflow-trigger/src/cli/index.ts +1 -1
- package/connectors/workos/package.json +1 -1
- package/connectors/write-binary-file/CLAUDE.md +1 -1
- package/connectors/write-binary-file/README.md +1 -1
- package/connectors/write-binary-file/package.json +1 -1
- package/connectors/write-binary-file/src/api/client.test.ts +16 -12
- package/connectors/write-binary-file/src/api/client.ts +4 -3
- package/connectors/write-binary-file/src/api/index.ts +1 -1
- package/connectors/write-binary-file/src/index.ts +1 -1
- package/connectors/wubookratechecker/src/api/client.test.ts +34 -0
- package/connectors/wubookratechecker/src/api/client.ts +3 -1
- package/connectors/wubookratechecker/src/api/index.ts +1 -1
- package/connectors/wubookratechecker/src/types/index.ts +1 -1
- package/connectors/xai/.env.example +1 -1
- package/connectors/xai-api-platform/.env.example +1 -1
- package/connectors/xai-api-platform/CLAUDE.md +1 -1
- package/connectors/xai-api-platform/README.md +1 -1
- package/connectors/xai-api-platform/src/api/client.test.ts +34 -9
- package/connectors/xai-api-platform/src/api/client.ts +4 -3
- package/connectors/xai-api-platform/src/api/index.ts +1 -1
- package/connectors/xai-api-platform/src/cli/index.ts +1 -1
- package/connectors/xai-api-platform/src/index.ts +1 -1
- package/connectors/xai-api-platform/src/utils/config.ts +3 -4
- package/connectors/xai-grok/.env.example +1 -1
- package/connectors/xai-grok/src/api/client.test.ts +3 -3
- package/connectors/xai-grok/src/cli/index.ts +1 -1
- package/connectors/xai-grok/src/utils/config.ts +1 -1
- package/connectors/ynab/package.json +1 -1
- package/connectors/you-com/README.md +2 -2
- package/connectors/you-com/package.json +1 -1
- package/connectors/yousign/package.json +1 -1
- package/connectors/zapier-api-platform/CLAUDE.md +1 -1
- package/connectors/zapier-api-platform/README.md +1 -1
- package/connectors/zapier-api-platform/src/api/client.test.ts +19 -14
- package/connectors/zapier-api-platform/src/api/client.ts +4 -3
- package/connectors/zapier-api-platform/src/api/index.ts +1 -1
- package/connectors/zapier-api-platform/src/cli/index.ts +1 -1
- package/connectors/zapier-api-platform/src/index.ts +1 -1
- package/connectors/zendesk/.env.example +4 -4
- package/connectors/zendesk/CLAUDE.md +1 -3
- package/connectors/zendesk/Makefile +18 -5
- package/connectors/zendesk/README.md +3 -8
- package/connectors/zendesk/SCAFFOLD.md +6 -5
- package/connectors/zerosettle/package.json +1 -1
- package/connectors/zoho-bigin/CLAUDE.md +1 -1
- package/connectors/zoho-campaigns/package.json +1 -1
- package/connectors/zoho-sign/package.json +1 -1
- package/connectors/zoho-subscriptions/CLAUDE.md +1 -1
- package/connectors/zohoprojects/CLAUDE.md +1 -1
- package/connectors/zolvo/package.json +1 -1
- package/connectors/zoom-api/package.json +1 -1
- package/connectors/zymbly/README.md +2 -2
- package/connectors/zymbly/package.json +1 -1
- package/dashboard/dist/assets/index-8uoGZF7B.js +280 -0
- package/dashboard/dist/index.html +1 -1
- package/dist/db/locks.d.ts +1 -1
- package/dist/index.js +17 -15
- package/dist/lib/connector-resolver.d.ts +1 -1
- package/dist/lib/llm.d.ts +1 -1
- package/dist/lib/open-browser.d.ts +18 -0
- package/dist/lib/open-browser.test.d.ts +1 -0
- package/package.json +6 -4
- package/dashboard/dist/assets/index-DlEljRrW.js +0 -285
|
@@ -51,11 +51,11 @@ afterEach(() => {
|
|
|
51
51
|
describe('StopAndErrorClient', () => {
|
|
52
52
|
const mockConfig = {
|
|
53
53
|
apiKey: 'test-api-key-12345',
|
|
54
|
-
baseUrl: 'https://
|
|
54
|
+
baseUrl: 'https://configured.example.com/v1',
|
|
55
55
|
};
|
|
56
56
|
|
|
57
57
|
test('throws when api key is missing', () => {
|
|
58
|
-
expect(() => new StopAndErrorClient({ apiKey: '' })).toThrow('API key is required');
|
|
58
|
+
expect(() => new StopAndErrorClient({ apiKey: '', baseUrl: 'https://configured.example.com/v1' })).toThrow('API key is required');
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
test('getApiKeyPreview masks long keys', () => {
|
|
@@ -65,7 +65,7 @@ describe('StopAndErrorClient', () => {
|
|
|
65
65
|
|
|
66
66
|
test('listErrors GET /errors with bearer auth', async () => {
|
|
67
67
|
const recorded = installFetch((req) => {
|
|
68
|
-
expect(req.url).toBe('https://
|
|
68
|
+
expect(req.url).toBe('https://configured.example.com/v1/errors?limit=10');
|
|
69
69
|
expect(req.method).toBe('GET');
|
|
70
70
|
expect(req.headers.authorization).toBe('Bearer test-api-key-12345');
|
|
71
71
|
return { data: [{ id: 'err_1', message: 'boom' }] };
|
|
@@ -78,7 +78,7 @@ describe('StopAndErrorClient', () => {
|
|
|
78
78
|
|
|
79
79
|
test('getError GET /errors/{id}', async () => {
|
|
80
80
|
const recorded = installFetch((req) => {
|
|
81
|
-
expect(req.url).toBe('https://
|
|
81
|
+
expect(req.url).toBe('https://configured.example.com/v1/errors/err_42');
|
|
82
82
|
expect(req.method).toBe('GET');
|
|
83
83
|
return { id: 'err_42', message: 'failed node' };
|
|
84
84
|
});
|
|
@@ -90,7 +90,7 @@ describe('StopAndErrorClient', () => {
|
|
|
90
90
|
|
|
91
91
|
test('createError POST /errors with body', async () => {
|
|
92
92
|
const recorded = installFetch((req) => {
|
|
93
|
-
expect(req.url).toBe('https://
|
|
93
|
+
expect(req.url).toBe('https://configured.example.com/v1/errors');
|
|
94
94
|
expect(req.method).toBe('POST');
|
|
95
95
|
expect(req.headers.authorization).toBe('Bearer test-api-key-12345');
|
|
96
96
|
const body = JSON.parse(req.body!);
|
|
@@ -106,7 +106,7 @@ describe('StopAndErrorClient', () => {
|
|
|
106
106
|
|
|
107
107
|
test('listEvents GET /events', async () => {
|
|
108
108
|
const recorded = installFetch((req) => {
|
|
109
|
-
expect(req.url).toBe('https://
|
|
109
|
+
expect(req.url).toBe('https://configured.example.com/v1/events?errorId=err_1');
|
|
110
110
|
expect(req.method).toBe('GET');
|
|
111
111
|
return { data: [{ id: 'evt_1', type: 'error.created' }] };
|
|
112
112
|
});
|
|
@@ -118,7 +118,7 @@ describe('StopAndErrorClient', () => {
|
|
|
118
118
|
|
|
119
119
|
test('search POST /search with query body', async () => {
|
|
120
120
|
const recorded = installFetch((req) => {
|
|
121
|
-
expect(req.url).toBe('https://
|
|
121
|
+
expect(req.url).toBe('https://configured.example.com/v1/search');
|
|
122
122
|
expect(req.method).toBe('POST');
|
|
123
123
|
const body = JSON.parse(req.body!);
|
|
124
124
|
expect(body.query).toBe('timeout');
|
|
@@ -147,7 +147,7 @@ describe('StopAndErrorClient', () => {
|
|
|
147
147
|
|
|
148
148
|
test('rawRequest supports custom path and method', async () => {
|
|
149
149
|
const recorded = installFetch((req) => {
|
|
150
|
-
expect(req.url).toBe('https://
|
|
150
|
+
expect(req.url).toBe('https://configured.example.com/v1/custom?foo=bar');
|
|
151
151
|
expect(req.method).toBe('PUT');
|
|
152
152
|
return { ok: true };
|
|
153
153
|
});
|
|
@@ -155,4 +155,8 @@ describe('StopAndErrorClient', () => {
|
|
|
155
155
|
await connector.rawRequest({ method: 'PUT', path: '/custom', params: { foo: 'bar' } });
|
|
156
156
|
expect(recorded).toHaveLength(1);
|
|
157
157
|
});
|
|
158
|
+
|
|
159
|
+
test('refuses to send without a configured base URL (no default endpoint)', () => {
|
|
160
|
+
expect(() => new StopAndErrorClient({ apiKey: 'test-key' })).toThrow(/baseUrl/);
|
|
161
|
+
});
|
|
158
162
|
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { StopAndErrorConfig } from '../types';
|
|
2
2
|
import { StopAndErrorApiError } from '../types';
|
|
3
3
|
|
|
4
|
-
const DEFAULT_BASE_URL = 'https://api.stop-and-error.com/v1';
|
|
5
|
-
|
|
6
4
|
export interface RequestOptions {
|
|
7
5
|
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
8
6
|
params?: Record<string, string | number | boolean | undefined>;
|
|
@@ -19,7 +17,10 @@ export class StopAndErrorClient {
|
|
|
19
17
|
throw new Error('API key is required');
|
|
20
18
|
}
|
|
21
19
|
this.apiKey = config.apiKey;
|
|
22
|
-
|
|
20
|
+
if (!config.baseUrl) {
|
|
21
|
+
throw new Error('baseUrl is required: no default endpoint is configured; set baseUrl (profile, config, or the connector BASE_URL environment variable)');
|
|
22
|
+
}
|
|
23
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, '');
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {
|
|
@@ -167,7 +167,7 @@ configCmd
|
|
|
167
167
|
console.log(chalk.bold(`Active Profile: ${getCurrentProfile()}`));
|
|
168
168
|
info(`Config directory: ${getConfigDir()}`);
|
|
169
169
|
info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
|
|
170
|
-
info(`Base URL: ${getBaseUrl() || chalk.gray('
|
|
170
|
+
info(`Base URL: ${getBaseUrl() || chalk.gray('none configured')}`);
|
|
171
171
|
});
|
|
172
172
|
|
|
173
173
|
configCmd
|
|
@@ -187,7 +187,7 @@ statusCmd.action(() => {
|
|
|
187
187
|
console.log(chalk.bold('StopAndError Connector Status'));
|
|
188
188
|
info(`Profile: ${getCurrentProfile()}`);
|
|
189
189
|
info(`API Key: ${apiKey ? client!.getApiKeyPreview() : chalk.gray('not set')}`);
|
|
190
|
-
info(`Base URL: ${getBaseUrl() || '
|
|
190
|
+
info(`Base URL: ${getBaseUrl() || 'none configured'}`);
|
|
191
191
|
});
|
|
192
192
|
|
|
193
193
|
const errorsCmd = program.command('errors').description('Workflow error operations');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Stripe Financial Connections API credentials
|
|
2
2
|
STRIPE_FINANCIAL_CONNECTIONS_API_KEY=your-api-key-here
|
|
3
3
|
|
|
4
|
-
# Optional: override API base URL (default
|
|
4
|
+
# Optional: override API base URL (no default - must be configured)
|
|
5
5
|
# STRIPE_FINANCIAL_CONNECTIONS_BASE_URL=https://api.stripefinancialconnections.com/v1
|
|
@@ -54,7 +54,7 @@ connect-stripe-financial-connections raw --path /items --method GET
|
|
|
54
54
|
|
|
55
55
|
## Authentication
|
|
56
56
|
|
|
57
|
-
Bearer Token authentication. API base URL
|
|
57
|
+
Bearer Token authentication. API base URL has no default (must be configured).
|
|
58
58
|
|
|
59
59
|
## Data Storage
|
|
60
60
|
|
|
@@ -70,7 +70,7 @@ Profile JSON structure:
|
|
|
70
70
|
```json
|
|
71
71
|
{
|
|
72
72
|
"apiKey": "your-api-key",
|
|
73
|
-
"baseUrl": "
|
|
73
|
+
"baseUrl": "configured.example.com/v1"
|
|
74
74
|
}
|
|
75
75
|
```
|
|
76
76
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test } from 'bun:test';
|
|
2
|
+
import { StripeFinancialConnectionsClient } from './client';
|
|
3
|
+
|
|
4
|
+
const realFetch = globalThis.fetch;
|
|
5
|
+
|
|
6
|
+
afterEach(() => {
|
|
7
|
+
globalThis.fetch = realFetch;
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
describe('StripeFinancialConnectionsClient transport', () => {
|
|
11
|
+
test('refuses to send without a configured base URL (no default endpoint)', () => {
|
|
12
|
+
expect(() => new StripeFinancialConnectionsClient({ apiKey: 'test-key' })).toThrow(/baseUrl/);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('sends the API key only to the configured base URL', async () => {
|
|
16
|
+
const recorded: string[] = [];
|
|
17
|
+
globalThis.fetch = (async (input: string | URL | Request, init?: RequestInit) => {
|
|
18
|
+
recorded.push(typeof input === 'string' ? input : input.toString());
|
|
19
|
+
return {
|
|
20
|
+
ok: true,
|
|
21
|
+
status: 200,
|
|
22
|
+
statusText: 'OK',
|
|
23
|
+
headers: new Headers({ 'content-type': 'application/json' }),
|
|
24
|
+
async text() { return JSON.stringify({ ok: true }); },
|
|
25
|
+
async json() { return { ok: true }; },
|
|
26
|
+
} as Response;
|
|
27
|
+
}) as typeof fetch;
|
|
28
|
+
const client = new StripeFinancialConnectionsClient({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
|
|
29
|
+
await client.request('/ping');
|
|
30
|
+
expect(recorded).toHaveLength(1);
|
|
31
|
+
expect(recorded[0].startsWith('https://configured.example.com/v1/')).toBe(true);
|
|
32
|
+
expect(recorded[0]).not.toContain('api.stripefinancialconnections.com');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { StripeFinancialConnectionsConfig, OutputFormat } from '../types';
|
|
2
2
|
import { StripeFinancialConnectionsApiError } from '../types';
|
|
3
3
|
|
|
4
|
-
export const DEFAULT_BASE_URL = 'https://api.stripefinancialconnections.com/v1';
|
|
5
|
-
|
|
6
4
|
export interface RequestOptions {
|
|
7
5
|
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
8
6
|
params?: Record<string, string | number | boolean | undefined>;
|
|
@@ -20,7 +18,10 @@ export class StripeFinancialConnectionsClient {
|
|
|
20
18
|
throw new Error('API key is required');
|
|
21
19
|
}
|
|
22
20
|
this.apiKey = config.apiKey;
|
|
23
|
-
|
|
21
|
+
if (!config.baseUrl) {
|
|
22
|
+
throw new Error('baseUrl is required: no default endpoint is configured; set baseUrl (profile, config, or the connector BASE_URL environment variable)');
|
|
23
|
+
}
|
|
24
|
+
this.baseUrl = config.baseUrl;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {
|
|
@@ -178,7 +178,7 @@ configCmd
|
|
|
178
178
|
console.log(chalk.bold(`Active Profile: ${getCurrentProfile()}`));
|
|
179
179
|
info(`Config directory: ${getConfigDir()}`);
|
|
180
180
|
info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
|
|
181
|
-
info(`Base URL: ${baseUrl || chalk.gray('
|
|
181
|
+
info(`Base URL: ${baseUrl || chalk.gray('none configured')}`);
|
|
182
182
|
});
|
|
183
183
|
|
|
184
184
|
configCmd
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Sucuri API Platform credentials (placeholder values only)
|
|
2
2
|
SUCURI_API_PLATFORM_API_KEY=your-api-key-here
|
|
3
3
|
|
|
4
|
-
# Optional: override the API base URL (default
|
|
4
|
+
# Optional: override the API base URL (no default - must be configured)
|
|
5
5
|
# SUCURI_API_PLATFORM_BASE_URL=https://api.sucuriapiplatform.com/v1
|
|
@@ -27,7 +27,7 @@ bun run dev raw request --path /items --method GET
|
|
|
27
27
|
|
|
28
28
|
## API Details
|
|
29
29
|
|
|
30
|
-
- **Base URL**:
|
|
30
|
+
- **Base URL**: no default (must be configured) (override via `SUCURI_API_PLATFORM_BASE_URL` or profile `baseUrl`)
|
|
31
31
|
- **Auth**: Bearer token (`Authorization: Bearer <api_key>`)
|
|
32
32
|
- **Endpoints**:
|
|
33
33
|
- `GET /items` — list items
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hasna/connect-sucuri-api-platform
|
|
2
2
|
|
|
3
|
-
TypeScript connector and CLI for the [Sucuri API Platform](
|
|
3
|
+
TypeScript connector and CLI for the [Sucuri API Platform](configured.example.com/v1).
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@ bun add @hasna/connect-sucuri-api-platform
|
|
|
13
13
|
```bash
|
|
14
14
|
export SUCURI_API_PLATFORM_API_KEY=your-api-key
|
|
15
15
|
# optional
|
|
16
|
-
export SUCURI_API_PLATFORM_BASE_URL=https://
|
|
16
|
+
export SUCURI_API_PLATFORM_BASE_URL=https://configured.example.com/v1
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Or use the CLI profile/config commands:
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { describe, test, expect, mock, beforeEach, afterEach } from 'bun:test';
|
|
2
|
-
import { ConnectorClient
|
|
2
|
+
import { ConnectorClient } from './client';
|
|
3
3
|
import { ConnectorApiError } from '../types';
|
|
4
4
|
|
|
5
5
|
describe('ConnectorClient', () => {
|
|
6
6
|
const mockConfig = {
|
|
7
7
|
apiKey: 'test-api-key-12345',
|
|
8
|
-
baseUrl: 'https://
|
|
8
|
+
baseUrl: 'https://configured.example.com/v1',
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
describe('constructor', () => {
|
|
@@ -18,14 +18,16 @@ describe('ConnectorClient', () => {
|
|
|
18
18
|
expect(client).toBeInstanceOf(ConnectorClient);
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
});
|
|
21
|
+
test('refuses to send without a configured base URL (no default endpoint)', () => {
|
|
22
|
+
expect(() => new ConnectorClient({ apiKey: 'test-key' })).toThrow(/baseUrl/);
|
|
23
|
+
});
|
|
25
24
|
|
|
26
25
|
test('strips trailing slash from base URL', () => {
|
|
27
26
|
const client = new ConnectorClient({
|
|
28
27
|
apiKey: 'token',
|
|
28
|
+
baseUrl: 'https://configured.example.com/v1',
|
|
29
|
+
baseUrl: 'https://configured.example.com/v1',
|
|
30
|
+
baseUrl: 'https://configured.example.com/v1',
|
|
29
31
|
baseUrl: 'https://custom.example.com/v1/',
|
|
30
32
|
});
|
|
31
33
|
expect(client.getBaseUrl()).toBe('https://custom.example.com/v1');
|
|
@@ -72,7 +74,7 @@ describe('ConnectorClient', () => {
|
|
|
72
74
|
|
|
73
75
|
expect(global.fetch).toHaveBeenCalledTimes(1);
|
|
74
76
|
const [url, options] = (global.fetch as ReturnType<typeof mock>).mock.calls[0];
|
|
75
|
-
expect(url).toBe('https://
|
|
77
|
+
expect(url).toBe('https://configured.example.com/v1/items');
|
|
76
78
|
expect(options.method).toBe('GET');
|
|
77
79
|
expect(options.headers.Authorization).toBe('Bearer test-api-key-12345');
|
|
78
80
|
expect(options.headers.Accept).toBe('application/json');
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { ConnectorConfig, OutputFormat } from '../types';
|
|
2
2
|
import { ConnectorApiError, parseApiError } from '../types';
|
|
3
3
|
|
|
4
|
-
export const DEFAULT_BASE_URL = 'https://api.sucuriapiplatform.com/v1';
|
|
5
|
-
|
|
6
4
|
export interface RequestOptions {
|
|
7
5
|
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
8
6
|
params?: Record<string, string | number | boolean | undefined>;
|
|
@@ -23,7 +21,10 @@ export class ConnectorClient {
|
|
|
23
21
|
throw new Error('Sucuri API Platform API key is required');
|
|
24
22
|
}
|
|
25
23
|
this.apiKey = key;
|
|
26
|
-
|
|
24
|
+
if (!config.baseUrl) {
|
|
25
|
+
throw new Error('baseUrl is required: no default endpoint is configured; set baseUrl (profile, config, or the connector BASE_URL environment variable)');
|
|
26
|
+
}
|
|
27
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, '');
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {
|
|
@@ -49,7 +49,7 @@ export class Connector {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export { ConnectorClient
|
|
52
|
+
export { ConnectorClient } from './client';
|
|
53
53
|
export { ItemsApi } from './items';
|
|
54
54
|
export { EventsApi } from './events';
|
|
55
55
|
export { SearchApi } from './search';
|
|
@@ -187,7 +187,7 @@ configCmd
|
|
|
187
187
|
console.log(chalk.bold(`Active Profile: ${profileName}`));
|
|
188
188
|
info(`Config directory: ${getConfigDir()}`);
|
|
189
189
|
info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
|
|
190
|
-
info(`Base URL: ${baseUrl || chalk.gray('
|
|
190
|
+
info(`Base URL: ${baseUrl || chalk.gray('none configured')}`);
|
|
191
191
|
});
|
|
192
192
|
|
|
193
193
|
configCmd
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hasna/connect-takecareos
|
|
2
2
|
|
|
3
|
-
TakeCareOS connector for the [
|
|
3
|
+
TakeCareOS connector for the [connectors](https://github.com/hasna/apps) registry.
|
|
4
4
|
|
|
5
5
|
TakeCareOS is a home-care agency operating system. This connector wraps its public
|
|
6
6
|
REST API to manage clients (care recipients), caregivers, shifts, incident reports,
|
|
@@ -18,7 +18,7 @@ The connector authenticates with a Bearer API key. Provide it via environment
|
|
|
18
18
|
variable, a CLI flag, or a stored profile:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
export TAKECAREOS_API_KEY
|
|
21
|
+
export TAKECAREOS_API_KEY=<your-api-key>
|
|
22
22
|
# optional, for a dedicated/regional host
|
|
23
23
|
export TAKECAREOS_BASE_URL=https://api.takecareos.com/v1
|
|
24
24
|
```
|
|
@@ -59,6 +59,11 @@ export interface GetFileOptions {
|
|
|
59
59
|
fileId: string;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
export interface DownloadFileResult {
|
|
63
|
+
file: TelegramFile;
|
|
64
|
+
data: Uint8Array;
|
|
65
|
+
}
|
|
66
|
+
|
|
62
67
|
export interface BotName {
|
|
63
68
|
name: string;
|
|
64
69
|
}
|
|
@@ -220,4 +225,19 @@ export class BotApi {
|
|
|
220
225
|
},
|
|
221
226
|
});
|
|
222
227
|
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Resolve and download a Telegram file
|
|
231
|
+
*/
|
|
232
|
+
async downloadFile(options: GetFileOptions): Promise<DownloadFileResult> {
|
|
233
|
+
const file = await this.getFile(options);
|
|
234
|
+
if (!file.file_path) {
|
|
235
|
+
throw new Error('Telegram did not return a downloadable file path');
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
file,
|
|
240
|
+
data: await this.client.downloadFile(file.file_path),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
223
243
|
}
|
|
@@ -118,6 +118,38 @@ export class TelegramClient {
|
|
|
118
118
|
return this.request<T>(method, { body: formData });
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Download a file returned by the Telegram Bot API
|
|
123
|
+
*/
|
|
124
|
+
async downloadFile(filePath: string): Promise<Uint8Array> {
|
|
125
|
+
const normalizedPath = filePath.replace(/^\/+/, '');
|
|
126
|
+
if (!normalizedPath) {
|
|
127
|
+
throw new Error('Telegram file path is required');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const encodedPath = normalizedPath
|
|
131
|
+
.split('/')
|
|
132
|
+
.map(segment => encodeURIComponent(segment))
|
|
133
|
+
.join('/');
|
|
134
|
+
const url = `${TELEGRAM_API_BASE}/file/bot${this.botToken}/${encodedPath}`;
|
|
135
|
+
|
|
136
|
+
let response: Response;
|
|
137
|
+
try {
|
|
138
|
+
response = await fetch(url);
|
|
139
|
+
} catch {
|
|
140
|
+
throw new Error('Failed to download Telegram file');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!response.ok) {
|
|
144
|
+
throw new TelegramApiError(
|
|
145
|
+
`Telegram file download failed with HTTP ${response.status}`,
|
|
146
|
+
response.status
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
151
|
+
}
|
|
152
|
+
|
|
121
153
|
/**
|
|
122
154
|
* Get a preview of the bot token (for display/debugging)
|
|
123
155
|
*/
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { afterEach, describe, expect, mock, test } from 'bun:test';
|
|
2
|
+
import { Telegram } from './index';
|
|
3
|
+
|
|
4
|
+
const originalFetch = globalThis.fetch;
|
|
5
|
+
|
|
6
|
+
afterEach(() => {
|
|
7
|
+
globalThis.fetch = originalFetch;
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
describe('Telegram files API', () => {
|
|
11
|
+
test('resolves a file ID and downloads its bytes from the authenticated file URL', async () => {
|
|
12
|
+
const botToken = '123456:test-token';
|
|
13
|
+
const fetchMock = mock(async (
|
|
14
|
+
input: string | URL | Request,
|
|
15
|
+
_init?: RequestInit
|
|
16
|
+
) => {
|
|
17
|
+
const url = String(input);
|
|
18
|
+
if (url.endsWith('/getFile')) {
|
|
19
|
+
return Response.json({
|
|
20
|
+
ok: true,
|
|
21
|
+
result: {
|
|
22
|
+
file_id: 'incoming-file-id',
|
|
23
|
+
file_unique_id: 'unique-file-id',
|
|
24
|
+
file_size: 4,
|
|
25
|
+
file_path: 'documents/report 1.pdf',
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return new Response(new Uint8Array([1, 2, 3, 4]));
|
|
31
|
+
});
|
|
32
|
+
globalThis.fetch = fetchMock as unknown as typeof fetch;
|
|
33
|
+
|
|
34
|
+
const telegram = new Telegram({ botToken });
|
|
35
|
+
const downloaded = await telegram.bot.downloadFile({
|
|
36
|
+
fileId: 'incoming-file-id',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
|
40
|
+
expect(String(fetchMock.mock.calls[0]?.[0])).toBe(
|
|
41
|
+
`https://api.telegram.org/bot${botToken}/getFile`
|
|
42
|
+
);
|
|
43
|
+
expect(JSON.parse(String(fetchMock.mock.calls[0]?.[1]?.body))).toEqual({
|
|
44
|
+
file_id: 'incoming-file-id',
|
|
45
|
+
});
|
|
46
|
+
expect(String(fetchMock.mock.calls[1]?.[0])).toBe(
|
|
47
|
+
`https://api.telegram.org/file/bot${botToken}/documents/report%201.pdf`
|
|
48
|
+
);
|
|
49
|
+
expect(downloaded.file.file_path).toBe('documents/report 1.pdf');
|
|
50
|
+
expect(downloaded.data).toEqual(new Uint8Array([1, 2, 3, 4]));
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('fails explicitly when Telegram does not return a file path', async () => {
|
|
54
|
+
const fetchMock = mock(async () =>
|
|
55
|
+
Response.json({
|
|
56
|
+
ok: true,
|
|
57
|
+
result: {
|
|
58
|
+
file_id: 'incoming-file-id',
|
|
59
|
+
file_unique_id: 'unique-file-id',
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
);
|
|
63
|
+
globalThis.fetch = fetchMock as unknown as typeof fetch;
|
|
64
|
+
|
|
65
|
+
const telegram = new Telegram({ botToken: '123456:test-token' });
|
|
66
|
+
|
|
67
|
+
expect(
|
|
68
|
+
telegram.bot.downloadFile({ fileId: 'incoming-file-id' })
|
|
69
|
+
).rejects.toThrow('Telegram did not return a downloadable file path');
|
|
70
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('does not expose the bot token in download errors', async () => {
|
|
74
|
+
const botToken = '123456:must-not-leak';
|
|
75
|
+
const fetchMock = mock(async (
|
|
76
|
+
input: string | URL | Request,
|
|
77
|
+
_init?: RequestInit
|
|
78
|
+
) => {
|
|
79
|
+
if (String(input).endsWith('/getFile')) {
|
|
80
|
+
return Response.json({
|
|
81
|
+
ok: true,
|
|
82
|
+
result: {
|
|
83
|
+
file_id: 'incoming-file-id',
|
|
84
|
+
file_unique_id: 'unique-file-id',
|
|
85
|
+
file_path: 'photos/file.jpg',
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return new Response('not found', { status: 404 });
|
|
90
|
+
});
|
|
91
|
+
globalThis.fetch = fetchMock as unknown as typeof fetch;
|
|
92
|
+
|
|
93
|
+
const telegram = new Telegram({ botToken });
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
await telegram.bot.downloadFile({ fileId: 'incoming-file-id' });
|
|
97
|
+
throw new Error('Expected download to fail');
|
|
98
|
+
} catch (err) {
|
|
99
|
+
expect(String(err)).toContain('Telegram file download failed');
|
|
100
|
+
expect(String(err)).not.toContain(botToken);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
});
|