Skip to content

Commit e5f13e5

Browse files
feat: add custom HTTP client support for cross-platform compatibility (#383)
Co-authored-by: Claude <[email protected]>
1 parent 1d5c150 commit e5f13e5

13 files changed

+985
-29
lines changed

README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,78 @@ Key changes in v1 include:
3838
- Object renames (e.g., items → tasks, notes → comments)
3939
- URL renames and endpoint signature changes
4040

41+
## Custom HTTP Clients
42+
43+
The Todoist API client supports custom HTTP implementations to enable usage in environments with specific networking requirements, such as:
44+
45+
- **Obsidian plugins** - Desktop app with strict CORS policies
46+
- **Browser extensions** - Custom HTTP APIs with different security models
47+
- **Electron apps** - Requests routed through IPC layer
48+
- **React Native** - Different networking stack
49+
- **Enterprise environments** - Proxy configuration, custom headers, or certificate handling
50+
51+
### Basic Usage
52+
53+
```typescript
54+
import { TodoistApi } from '@doist/todoist-api-typescript'
55+
56+
// Using the new options-based constructor
57+
const api = new TodoistApi('YOURTOKEN', {
58+
baseUrl: 'https://custom-api.example.com', // optional
59+
customFetch: myCustomFetch, // your custom fetch implementation
60+
})
61+
62+
// Legacy constructor (deprecated but supported)
63+
const apiLegacy = new TodoistApi('YOURTOKEN', 'https://custom-api.example.com')
64+
```
65+
66+
### Custom Fetch Interface
67+
68+
Your custom fetch function must implement this interface:
69+
70+
```typescript
71+
type CustomFetch = (
72+
url: string,
73+
options?: RequestInit & { timeout?: number },
74+
) => Promise<CustomFetchResponse>
75+
76+
type CustomFetchResponse = {
77+
ok: boolean
78+
status: number
79+
statusText: string
80+
headers: Record<string, string>
81+
text(): Promise<string>
82+
json(): Promise<unknown>
83+
}
84+
```
85+
86+
### OAuth with Custom Fetch
87+
88+
OAuth authentication functions (`getAuthToken`, `revokeAuthToken`, `revokeToken`) support custom fetch through an options object:
89+
90+
```typescript
91+
// New options-based usage
92+
const { accessToken } = await getAuthToken(args, {
93+
baseUrl: 'https://custom-auth.example.com',
94+
customFetch: myCustomFetch,
95+
})
96+
97+
await revokeToken(args, {
98+
customFetch: myCustomFetch,
99+
})
100+
101+
// Legacy usage (deprecated)
102+
const { accessToken } = await getAuthToken(args, baseUrl)
103+
```
104+
105+
### Important Notes
106+
107+
- All existing transforms (snake_case ↔ camelCase) work automatically with custom fetch
108+
- Retry logic and error handling are preserved
109+
- File uploads work with custom fetch implementations
110+
- The custom fetch function should handle FormData for multipart uploads
111+
- Timeout parameter is optional and up to your custom implementation
112+
41113
## Development and Testing
42114

43115
Instead of having an example app in the repository to assist development and testing, we have included [ts-node](https://github.com/TypeStrong/ts-node) as a dev dependency. This allows us to have a scratch file locally that can import and utilize the API while developing or reviewing pull requests without having to manage a separate app project.

0 commit comments

Comments
 (0)