From ed7360d4bd09f758ee66c62394a3ac7a064c64fc Mon Sep 17 00:00:00 2001 From: isra el Date: Tue, 27 Oct 2026 19:51:18 +0300 Subject: [PATCH 1/2] docs: link the Python SDK Co-Authored-By: Claude Opus 5.5 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 55a26df..00e62f5 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ Official JavaScript SDK for [textbee.dev](https://textbee.dev), the open source Zero dependencies, TypeScript types included, works in Node 18+, Bun, Deno, Cloudflare Workers, and Vercel Edge. +Writing Python? Use the official [Python SDK](https://github.com/textbee/textbee-python): `pip install textbee`. + ## Install ```bash From 1940c039ac0d5b584b640239611224f9aa5e8075 Mon Sep 17 00:00:00 2001 From: isra el Date: Tue, 27 Oct 2026 20:16:40 +0300 Subject: [PATCH 2/2] fix: add /api/v1 after a base URL path prefix, as the MCP server does https://example.com/textbee now reaches https://example.com/textbee/api/v1 instead of being used as given. The SDK and TEXTBEE_BASE_URL in @textbee/mcp now resolve every base URL the same way. Release 0.3.1. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 +- package.json | 2 +- src/client.ts | 6 ++---- src/types.ts | 4 ++-- test/client.test.ts | 8 ++++---- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 00e62f5..85bc066 100644 --- a/README.md +++ b/README.md @@ -231,7 +231,7 @@ new Textbee({ apiKey, baseUrl: 'https://sms.example.com/api/v1' }) new Textbee({ apiKey, baseUrl: 'http://localhost:3001' }) ``` -If the API sits under a path prefix, give the full path, for example `https://example.com/textbee/api/v1`. Any path other than `/api/v1` is used as given, so a proxy that maps `/sms` onto the API keeps working with `https://example.com/sms`. A value with no scheme gets `https://`. An invalid URL, or one with a username or password, throws a `TypeError` instead of falling back to the hosted API, so a typo never sends your key to textbee.dev. +If the API sits under a path prefix, give the prefix: `https://example.com/textbee` reaches `https://example.com/textbee/api/v1`. The SDK adds `/api/v1` unless the path already contains it, the same rule the textbee MCP server uses for `TEXTBEE_BASE_URL`. A value with no scheme gets `https://`. An invalid URL, or one with a username or password, throws a `TypeError` instead of falling back to the hosted API, so a typo never sends your key to textbee.dev. ## What is not covered yet diff --git a/package.json b/package.json index 1305e92..e2d71ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@textbee/sdk", - "version": "0.3.0", + "version": "0.3.1", "description": "Official JavaScript SDK for textbee.dev, the open source SMS gateway", "license": "MIT", "packageManager": "pnpm@9.14.2", diff --git a/src/client.ts b/src/client.ts index 0624445..4b2b324 100644 --- a/src/client.ts +++ b/src/client.ts @@ -252,10 +252,8 @@ function normalizeBaseUrl(raw: string | undefined): string { } let path: string[] - if (segments.length === 0) { - path = ['api', 'v1'] - } else if (cut === -1) { - path = segments + if (cut === -1) { + path = [...segments, 'api', 'v1'] } else { // Anything after /api/v1 is a route, not part of the root, so it is dropped. path = [...segments.slice(0, cut - 2), 'api', 'v1'] diff --git a/src/types.ts b/src/types.ts index 6790fcc..c3b560d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -5,9 +5,9 @@ export interface TextbeeOptions { /** * Your self-hosted textbee API. Defaults to `https://api.textbee.dev/api/v1`. * - * A bare origin such as `https://sms.example.com` gets `/api/v1` added. A URL + * `/api/v1` is added unless the path already contains it, so + * `https://sms.example.com` and `https://example.com/textbee` both work. A URL * that contains `/api/v1` is cut there, so a pasted endpoint URL still works. - * Any other path is used as given, for proxies that map a prefix onto the API. * A value with no scheme gets `https://`. An invalid URL throws a `TypeError` * rather than falling back, so a typo never sends your key to the public API. */ diff --git a/test/client.test.ts b/test/client.test.ts index 8c1009d..78aa086 100644 --- a/test/client.test.ts +++ b/test/client.test.ts @@ -369,9 +369,9 @@ describe('options', () => { ['https://sms.example.com/api/v1', 'https://sms.example.com/api/v1'], ['https://sms.example.com/api/v1/', 'https://sms.example.com/api/v1'], ['https://sms.example.com/textbee/api/v1', 'https://sms.example.com/textbee/api/v1'], - // A prefix without /api/v1 is kept as given, for proxies that rewrite it. - ['https://sms.example.com/textbee', 'https://sms.example.com/textbee'], - ['https://example.com/sms/', 'https://example.com/sms'], + // A subpath deployment gets /api/v1 added after its prefix. + ['https://sms.example.com/textbee', 'https://sms.example.com/textbee/api/v1'], + ['https://example.com/sms/', 'https://example.com/sms/api/v1'], ['https://api.textbee.dev/api/v1/gateway/send-sms', 'https://api.textbee.dev/api/v1'], ['api.textbee.dev', 'https://api.textbee.dev/api/v1'], ['localhost:3001', 'https://localhost:3001/api/v1'], @@ -380,7 +380,7 @@ describe('options', () => { ['http://[::1]:3001', 'http://[::1]:3001/api/v1'], ['http://sms.example.com', 'http://sms.example.com/api/v1'], ['https://sms.example.com/API/V1', 'https://sms.example.com/api/v1'], - ['https://sms.example.com/v1', 'https://sms.example.com/v1'], + ['https://sms.example.com/v1', 'https://sms.example.com/v1/api/v1'], ['https://example.com/my app/api/v1', 'https://example.com/my%20app/api/v1'], ['https://b\u00fccher.example', 'https://xn--bcher-kva.example/api/v1'], ['HTTPS://SMS.Example.com:443/?q=1#top', 'https://sms.example.com/api/v1'],