Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -229,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

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
6 changes: 2 additions & 4 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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']
Expand Down
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
8 changes: 4 additions & 4 deletions test/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
Expand All @@ -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'],
Expand Down
Loading