@dugjason/front-node 0.1.0-alpha.1
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/LICENSE.md +21 -0
- package/README.md +323 -0
- package/dist/client.d.ts +48 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +218 -0
- package/dist/client.js.map +1 -0
- package/dist/front.d.ts +29 -0
- package/dist/front.d.ts.map +1 -0
- package/dist/front.js +44 -0
- package/dist/front.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/oauth.d.ts +28 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +82 -0
- package/dist/oauth.js.map +1 -0
- package/dist/resources/accounts.d.ts +39 -0
- package/dist/resources/accounts.d.ts.map +1 -0
- package/dist/resources/accounts.js +57 -0
- package/dist/resources/accounts.js.map +1 -0
- package/dist/resources/conversations.d.ts +41 -0
- package/dist/resources/conversations.d.ts.map +1 -0
- package/dist/resources/conversations.js +55 -0
- package/dist/resources/conversations.js.map +1 -0
- package/dist/resources/teammates.d.ts +29 -0
- package/dist/resources/teammates.d.ts.map +1 -0
- package/dist/resources/teammates.js +37 -0
- package/dist/resources/teammates.js.map +1 -0
- package/dist/types.d.ts +147 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 J.Dugdale
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# Front Node.js SDK
|
|
2
|
+
|
|
3
|
+
A modern TypeScript SDK for the [Front.com API](https://dev.frontapp.com/reference/introduction). This SDK provides a clean, intuitive interface for interacting with Front's customer operations platform.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install front-node
|
|
9
|
+
# or
|
|
10
|
+
pnpm install front-node
|
|
11
|
+
# or
|
|
12
|
+
yarn add front-node
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { Front } from 'front-node';
|
|
19
|
+
|
|
20
|
+
// Initialize with API key (required)
|
|
21
|
+
const front = new Front({
|
|
22
|
+
apiKey: process.env.FRONT_API_KEY || 'your-api-key'
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Fetch a conversation
|
|
26
|
+
const conversation = await front.conversations.fetch('cnv_55c8c149');
|
|
27
|
+
|
|
28
|
+
// List teammates
|
|
29
|
+
const teammates = await front.teammates.list();
|
|
30
|
+
|
|
31
|
+
// Update a teammate
|
|
32
|
+
await front.teammates.update(teammates._results[0].id, {
|
|
33
|
+
is_available: true
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Authentication
|
|
38
|
+
|
|
39
|
+
The SDK supports two authentication methods:
|
|
40
|
+
|
|
41
|
+
### 1. OAuth (Recommended for Production)
|
|
42
|
+
|
|
43
|
+
OAuth provides automatic token refresh and is required for public integrations:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
const front = new Front({
|
|
47
|
+
oauth: {
|
|
48
|
+
clientId: 'your-oauth-client-id',
|
|
49
|
+
clientSecret: 'your-oauth-client-secret',
|
|
50
|
+
accessToken: 'your-current-access-token',
|
|
51
|
+
refreshToken: 'your-refresh-token',
|
|
52
|
+
|
|
53
|
+
// Optional: Called when tokens are refreshed
|
|
54
|
+
onTokenRefresh: async (tokens) => {
|
|
55
|
+
// Save new tokens to your database
|
|
56
|
+
await saveTokensToDatabase(tokens);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The SDK automatically refreshes tokens when they expire (every hour) and calls your `onTokenRefresh` callback with the new tokens.
|
|
63
|
+
|
|
64
|
+
### 2. API Key (Simple Setup)
|
|
65
|
+
|
|
66
|
+
For testing or single-instance usage:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// Using environment variable (recommended)
|
|
70
|
+
const front = new Front({
|
|
71
|
+
apiKey: process.env.FRONT_API_KEY || 'your-api-key'
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Or provide directly
|
|
75
|
+
const front = new Front({ apiKey: 'your-api-key' });
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## API Reference
|
|
79
|
+
|
|
80
|
+
### Conversations
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// List conversations
|
|
84
|
+
const conversations = await front.conversations.list({
|
|
85
|
+
limit: 50,
|
|
86
|
+
q: 'status:unassigned'
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Fetch a specific conversation
|
|
90
|
+
const conversation = await front.conversations.fetch('cnv_123');
|
|
91
|
+
|
|
92
|
+
// Update a conversation
|
|
93
|
+
await front.conversations.update('cnv_123', {
|
|
94
|
+
status: 'archived'
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Get conversation messages
|
|
98
|
+
const messages = await front.conversations.getMessages('cnv_123');
|
|
99
|
+
|
|
100
|
+
// Get conversation events
|
|
101
|
+
const events = await front.conversations.getEvents('cnv_123');
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Teammates
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// List all teammates
|
|
108
|
+
const teammates = await front.teammates.list();
|
|
109
|
+
|
|
110
|
+
// Fetch a specific teammate
|
|
111
|
+
const teammate = await front.teammates.fetch('tea_123');
|
|
112
|
+
|
|
113
|
+
// Update a teammate
|
|
114
|
+
await front.teammates.update('tea_123', {
|
|
115
|
+
first_name: 'John',
|
|
116
|
+
last_name: 'Doe',
|
|
117
|
+
is_available: true
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Get teammate's inboxes
|
|
121
|
+
const inboxes = await front.teammates.getInboxes('tea_123');
|
|
122
|
+
|
|
123
|
+
// Get teammate's conversations
|
|
124
|
+
const conversations = await front.teammates.getConversations('tea_123', {
|
|
125
|
+
limit: 10
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## OAuth Token Management
|
|
130
|
+
|
|
131
|
+
When using OAuth, the SDK provides several utilities for token management:
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// Check if using OAuth
|
|
135
|
+
const isOAuth = front.isUsingOAuth();
|
|
136
|
+
|
|
137
|
+
// Get OAuth manager for advanced operations
|
|
138
|
+
const oauthManager = front.getOAuthManager();
|
|
139
|
+
if (oauthManager) {
|
|
140
|
+
// Force token refresh
|
|
141
|
+
const newToken = oauthManager.getAccessToken();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Update OAuth configuration (e.g., after manual token refresh)
|
|
145
|
+
front.updateOAuthConfig({
|
|
146
|
+
accessToken: 'new-access-token',
|
|
147
|
+
refreshToken: 'new-refresh-token',
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Token Refresh Callback
|
|
152
|
+
|
|
153
|
+
The `onTokenRefresh` callback is crucial for OAuth implementations - it allows the SDK to notify your application when tokens are automatically refreshed, so you can save the updated tokens to your database or storage system.
|
|
154
|
+
|
|
155
|
+
**Example with database storage:**
|
|
156
|
+
```typescript
|
|
157
|
+
// Function to save tokens to your database
|
|
158
|
+
async function saveTokensToDatabase(userId: string, tokens: OAuthTokens) {
|
|
159
|
+
await db.users.update(userId, {
|
|
160
|
+
frontAccessToken: tokens.access_token,
|
|
161
|
+
frontRefreshToken: tokens.refresh_token,
|
|
162
|
+
updatedAt: new Date()
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const front = new Front({
|
|
167
|
+
oauth: {
|
|
168
|
+
clientId: 'your-client-id',
|
|
169
|
+
clientSecret: 'your-client-secret',
|
|
170
|
+
accessToken: 'current-access-token',
|
|
171
|
+
refreshToken: 'current-refresh-token',
|
|
172
|
+
|
|
173
|
+
// SDK calls this whenever tokens are refreshed
|
|
174
|
+
onTokenRefresh: async (tokens) => {
|
|
175
|
+
console.log('Front SDK refreshed tokens, saving to database...');
|
|
176
|
+
await saveTokensToDatabase(currentUserId, tokens);
|
|
177
|
+
console.log('Tokens saved successfully');
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// When any API call triggers a token refresh, your callback will be called
|
|
183
|
+
const conversations = await front.conversations.list(); // May trigger refresh + callback
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Concurrent Token Refresh Protection
|
|
187
|
+
|
|
188
|
+
The SDK uses an internal `refreshPromise` mechanism to prevent multiple simultaneous token refresh attempts. This ensures that if multiple API calls happen simultaneously when a token is expired, only one refresh request is made to the OAuth server, and your `onTokenRefresh` callback is only called once.
|
|
189
|
+
|
|
190
|
+
**How it works:**
|
|
191
|
+
- When the first API call detects an expired token, it starts the refresh process
|
|
192
|
+
- Any subsequent API calls that also detect the expired token will wait for the same refresh promise to complete
|
|
193
|
+
- Once the refresh is complete, `onTokenRefresh` is called once with the new tokens
|
|
194
|
+
- All waiting calls then proceed with the refreshed token
|
|
195
|
+
|
|
196
|
+
**Practical Example:**
|
|
197
|
+
```typescript
|
|
198
|
+
let refreshCount = 0;
|
|
199
|
+
|
|
200
|
+
const front = new Front({
|
|
201
|
+
oauth: {
|
|
202
|
+
clientId: 'your-client-id',
|
|
203
|
+
clientSecret: 'your-client-secret',
|
|
204
|
+
accessToken: 'expired-token',
|
|
205
|
+
refreshToken: 'your-refresh-token',
|
|
206
|
+
onTokenRefresh: async (tokens) => {
|
|
207
|
+
refreshCount++;
|
|
208
|
+
console.log(`Token refresh #${refreshCount}:`, tokens);
|
|
209
|
+
await saveTokensToDatabase(currentUserId, tokens);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// These calls happen simultaneously when token is expired
|
|
215
|
+
// Only ONE refresh request will be made, callback called once
|
|
216
|
+
const [conversations, teammates, accounts] = await Promise.all([
|
|
217
|
+
front.conversations.list(), // Triggers token refresh
|
|
218
|
+
front.teammates.list(), // Waits for existing refresh
|
|
219
|
+
front.accounts.list() // Waits for existing refresh
|
|
220
|
+
]);
|
|
221
|
+
|
|
222
|
+
console.log(`Refresh count: ${refreshCount}`); // Will be 1, not 3
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
This prevents rate limiting issues with the OAuth provider and ensures your database isn't hit with duplicate token updates.
|
|
226
|
+
|
|
227
|
+
## Configuration
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
const front = new Front({
|
|
231
|
+
apiKey: 'your-api-key', // For API key auth
|
|
232
|
+
baseUrl: 'https://api2.frontapp.com', // optional, defaults to Front's API
|
|
233
|
+
oauth: { // For OAuth auth
|
|
234
|
+
clientId: 'your-client-id',
|
|
235
|
+
clientSecret: 'your-client-secret',
|
|
236
|
+
accessToken: 'current-access-token',
|
|
237
|
+
refreshToken: 'current-refresh-token',
|
|
238
|
+
onTokenRefresh: async (tokens) => { /* save tokens */ }
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Error Handling
|
|
244
|
+
|
|
245
|
+
The SDK throws structured errors with helpful information:
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
try {
|
|
249
|
+
const conversation = await front.conversations.fetch('invalid-id');
|
|
250
|
+
} catch (error) {
|
|
251
|
+
console.error('Status:', error.status);
|
|
252
|
+
console.error('Message:', error.message);
|
|
253
|
+
console.error('Code:', error.code);
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## TypeScript Support
|
|
258
|
+
|
|
259
|
+
The SDK is built with TypeScript and provides full type definitions:
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
import { Front, Conversation, Teammate } from 'front-node';
|
|
263
|
+
|
|
264
|
+
const front = new Front({ apiKey: 'your-api-key' });
|
|
265
|
+
|
|
266
|
+
// Full type safety
|
|
267
|
+
const conversation: Conversation = await front.conversations.fetch('cnv_123');
|
|
268
|
+
const teammates: Teammate[] = (await front.teammates.list())._results;
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Releases
|
|
272
|
+
|
|
273
|
+
This package uses automated publishing with manual version management. When changes are merged to the main branch, the current version in `package.json` is automatically published to npm.
|
|
274
|
+
|
|
275
|
+
### Release Process
|
|
276
|
+
|
|
277
|
+
1. **Version Management**: Version bumps are handled manually using semantic versioning:
|
|
278
|
+
- **Patch** (`1.0.0` → `1.0.1`): Bug fixes, documentation updates, refactoring
|
|
279
|
+
- **Minor** (`1.0.0` → `1.1.0`): New features, enhancements
|
|
280
|
+
- **Major** (`1.0.0` → `2.0.0`): Breaking changes
|
|
281
|
+
|
|
282
|
+
2. **How to Release**:
|
|
283
|
+
```bash
|
|
284
|
+
# Bump version using pnpm (recommended)
|
|
285
|
+
pnpm version patch # for bug fixes
|
|
286
|
+
pnpm version minor # for new features
|
|
287
|
+
pnpm version major # for breaking changes
|
|
288
|
+
|
|
289
|
+
# Or manually edit package.json and create a git tag
|
|
290
|
+
git tag v1.2.3
|
|
291
|
+
|
|
292
|
+
# Push changes and tags
|
|
293
|
+
git push origin main --tags
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
3. **What Happens on Push to Main**:
|
|
297
|
+
- Tests run on Node.js 20 and 22
|
|
298
|
+
- Code is linted with Biome
|
|
299
|
+
- TypeScript compilation is verified
|
|
300
|
+
- Package is published to npm using the current `package.json` version
|
|
301
|
+
- GitHub release is created with the current version tag
|
|
302
|
+
|
|
303
|
+
### Development Workflow
|
|
304
|
+
|
|
305
|
+
1. Create feature branch from `main`
|
|
306
|
+
2. Make changes and commit
|
|
307
|
+
3. Open Pull Request
|
|
308
|
+
4. After review and merge to `main`:
|
|
309
|
+
- If you want to publish: bump version first, then merge
|
|
310
|
+
- If not ready to publish: merge without version bump
|
|
311
|
+
|
|
312
|
+
## Requirements
|
|
313
|
+
|
|
314
|
+
- Node.js 18.0.0 or higher (for native fetch support)
|
|
315
|
+
- TypeScript 5.0+ (if using TypeScript)
|
|
316
|
+
|
|
317
|
+
## License
|
|
318
|
+
|
|
319
|
+
ISC
|
|
320
|
+
|
|
321
|
+
## Contributing
|
|
322
|
+
|
|
323
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { OAuthTokenManager } from "./oauth";
|
|
2
|
+
import type { FrontConfig, RequestOptions } from "./types";
|
|
3
|
+
export declare class FrontClient {
|
|
4
|
+
private apiKey?;
|
|
5
|
+
private baseUrl;
|
|
6
|
+
private oauthManager?;
|
|
7
|
+
constructor(config: FrontConfig);
|
|
8
|
+
request<T>(options: RequestOptions): Promise<T>;
|
|
9
|
+
private requestWithRetry;
|
|
10
|
+
/**
|
|
11
|
+
* Calculate retry delay based on retry-after header and exponential backoff
|
|
12
|
+
*/
|
|
13
|
+
private getRetryDelay;
|
|
14
|
+
/**
|
|
15
|
+
* Calculate exponential backoff delay with jitter
|
|
16
|
+
*/
|
|
17
|
+
private calculateExponentialBackoff;
|
|
18
|
+
/**
|
|
19
|
+
* Sleep for the specified number of milliseconds
|
|
20
|
+
*/
|
|
21
|
+
private sleep;
|
|
22
|
+
/**
|
|
23
|
+
* Get the appropriate auth token (OAuth access token or API key)
|
|
24
|
+
*/
|
|
25
|
+
private getAuthToken;
|
|
26
|
+
/**
|
|
27
|
+
* Handle the response from the API
|
|
28
|
+
*/
|
|
29
|
+
private handleResponse;
|
|
30
|
+
get<T>(path: string, params?: Record<string, unknown>): Promise<T>;
|
|
31
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
32
|
+
put<T>(path: string, body?: unknown): Promise<T>;
|
|
33
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
34
|
+
delete<T>(path: string): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* Get the OAuth token manager (if using OAuth)
|
|
37
|
+
*/
|
|
38
|
+
getOAuthManager(): OAuthTokenManager | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Check if the client is using OAuth authentication
|
|
41
|
+
*/
|
|
42
|
+
isUsingOAuth(): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Update OAuth configuration (useful for updating tokens)
|
|
45
|
+
*/
|
|
46
|
+
updateOAuthConfig(updates: Partial<import("./types").OAuthConfig>): void;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAc,cAAc,EAAE,MAAM,SAAS,CAAA;AAUtE,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,CAAQ;IACvB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,YAAY,CAAC,CAAmB;gBAE5B,MAAM,EAAE,WAAW;IAiBzB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;YAIvC,gBAAgB;IAwF9B;;OAEG;IACH,OAAO,CAAC,aAAa;IAyBrB;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAgBnC;;OAEG;IACH,OAAO,CAAC,KAAK;IAIb;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB;;OAEG;YACW,cAAc;IAyBtB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIlE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIlD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIzC;;OAEG;IACH,eAAe,IAAI,iBAAiB,GAAG,SAAS;IAIhD;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,SAAS,EAAE,WAAW,CAAC,GAAG,IAAI;CAMzE"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { OAuthTokenManager } from "./oauth";
|
|
2
|
+
// Rate limiting configuration
|
|
3
|
+
const RATE_LIMIT_CONFIG = {
|
|
4
|
+
maxRetries: 3,
|
|
5
|
+
baseDelay: 1_000, // 1 second
|
|
6
|
+
maxDelay: 30_000, // 30 seconds
|
|
7
|
+
jitterFactor: 0.2, // 20% jitter to avoid thundering herd problem
|
|
8
|
+
};
|
|
9
|
+
export class FrontClient {
|
|
10
|
+
apiKey;
|
|
11
|
+
baseUrl;
|
|
12
|
+
oauthManager;
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this.baseUrl = config.baseUrl || "https://api2.frontapp.com";
|
|
15
|
+
if ("oauth" in config && config.oauth) {
|
|
16
|
+
// OAuth configuration provided
|
|
17
|
+
this.oauthManager = new OAuthTokenManager(config.oauth);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
// API key configuration
|
|
21
|
+
this.apiKey = config.apiKey || process.env.FRONT_API_KEY;
|
|
22
|
+
if (!this.apiKey) {
|
|
23
|
+
throw new Error("API key is required when not using OAuth. Provide apiKey via config or FRONT_API_KEY environment variable.");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async request(options) {
|
|
28
|
+
return this.requestWithRetry(options, 0);
|
|
29
|
+
}
|
|
30
|
+
async requestWithRetry(options, retryCount) {
|
|
31
|
+
const { method, path, body, params } = options;
|
|
32
|
+
// Build URL with query parameters
|
|
33
|
+
const url = new URL(path, this.baseUrl);
|
|
34
|
+
if (params) {
|
|
35
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
36
|
+
if (value !== undefined && value !== null) {
|
|
37
|
+
url.searchParams.append(key, String(value));
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
// Get the authorization token (OAuth or API key)
|
|
42
|
+
const authToken = this.getAuthToken();
|
|
43
|
+
// Prepare headers
|
|
44
|
+
const headers = {
|
|
45
|
+
Authorization: `Bearer ${authToken}`,
|
|
46
|
+
Accept: "application/json",
|
|
47
|
+
};
|
|
48
|
+
// Add content-type for requests with body
|
|
49
|
+
if (body) {
|
|
50
|
+
headers["Content-Type"] = "application/json";
|
|
51
|
+
}
|
|
52
|
+
// Prepare fetch options
|
|
53
|
+
const fetchOptions = {
|
|
54
|
+
method,
|
|
55
|
+
headers,
|
|
56
|
+
};
|
|
57
|
+
// Add body for non-GET requests
|
|
58
|
+
if (body) {
|
|
59
|
+
fetchOptions.body = JSON.stringify(body);
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const response = await fetch(url.toString(), fetchOptions);
|
|
63
|
+
// Handle token expiration for OAuth
|
|
64
|
+
if (response.status === 401 && this.oauthManager) {
|
|
65
|
+
// Token might be expired, try to refresh and retry once
|
|
66
|
+
const refreshedToken = await this.oauthManager.refreshToken();
|
|
67
|
+
// Token was refreshed, retry the request
|
|
68
|
+
headers.Authorization = `Bearer ${refreshedToken}`;
|
|
69
|
+
const retryResponse = await fetch(url.toString(), {
|
|
70
|
+
...fetchOptions,
|
|
71
|
+
headers,
|
|
72
|
+
});
|
|
73
|
+
return this.handleResponse(retryResponse);
|
|
74
|
+
}
|
|
75
|
+
// Handle rate limiting (429 status)
|
|
76
|
+
if (response.status === 429) {
|
|
77
|
+
if (retryCount < RATE_LIMIT_CONFIG.maxRetries) {
|
|
78
|
+
const retryAfterMs = this.getRetryDelay(response, retryCount);
|
|
79
|
+
await this.sleep(retryAfterMs);
|
|
80
|
+
return this.requestWithRetry(options, retryCount + 1);
|
|
81
|
+
}
|
|
82
|
+
// Max retries exceeded, handle as normal error response
|
|
83
|
+
}
|
|
84
|
+
return this.handleResponse(response);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
if (error instanceof Error && "status" in error) {
|
|
88
|
+
// Re-throw Front API errors
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
// Handle network or other errors - retry if we haven't exceeded max retries
|
|
92
|
+
if (retryCount < RATE_LIMIT_CONFIG.maxRetries) {
|
|
93
|
+
const retryAfterMs = this.calculateExponentialBackoff(retryCount);
|
|
94
|
+
await this.sleep(retryAfterMs);
|
|
95
|
+
return this.requestWithRetry(options, retryCount + 1);
|
|
96
|
+
}
|
|
97
|
+
// Max retries exceeded for network errors
|
|
98
|
+
throw new Error(`Request failed after ${RATE_LIMIT_CONFIG.maxRetries} retries: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Calculate retry delay based on retry-after header and exponential backoff
|
|
103
|
+
*/
|
|
104
|
+
getRetryDelay(response, retryCount) {
|
|
105
|
+
const retryAfterHeader = response.headers.get("retry-after");
|
|
106
|
+
let retryAfterMs = 0;
|
|
107
|
+
if (retryAfterHeader) {
|
|
108
|
+
// retry-after can be in seconds (integer) or HTTP date
|
|
109
|
+
const retryAfterSeconds = Number.parseInt(retryAfterHeader, 10);
|
|
110
|
+
if (!Number.isNaN(retryAfterSeconds)) {
|
|
111
|
+
retryAfterMs = retryAfterSeconds * 1000;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// Try parsing as HTTP date
|
|
115
|
+
const retryAfterDate = new Date(retryAfterHeader);
|
|
116
|
+
if (!Number.isNaN(retryAfterDate.getTime())) {
|
|
117
|
+
retryAfterMs = Math.max(0, retryAfterDate.getTime() - Date.now());
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Calculate exponential backoff delay
|
|
122
|
+
const exponentialBackoffMs = this.calculateExponentialBackoff(retryCount);
|
|
123
|
+
// Use the maximum of retry-after and exponential backoff to ensure we wait AT LEAST retry-after time
|
|
124
|
+
return Math.max(retryAfterMs, exponentialBackoffMs);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Calculate exponential backoff delay with jitter
|
|
128
|
+
*/
|
|
129
|
+
calculateExponentialBackoff(retryCount) {
|
|
130
|
+
const { baseDelay, maxDelay, jitterFactor } = RATE_LIMIT_CONFIG;
|
|
131
|
+
// Calculate exponential delay: baseDelay * (2 ^ retryCount)
|
|
132
|
+
const exponentialDelay = baseDelay * 2 ** retryCount;
|
|
133
|
+
// Apply maximum delay cap
|
|
134
|
+
const cappedDelay = Math.min(exponentialDelay, maxDelay);
|
|
135
|
+
// Add jitter to avoid thundering herd problem
|
|
136
|
+
// Jitter is a random value between +-jitterFactor of the delay
|
|
137
|
+
const jitter = cappedDelay * jitterFactor * (Math.random() * 2 - 1);
|
|
138
|
+
return Math.max(0, cappedDelay + jitter);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Sleep for the specified number of milliseconds
|
|
142
|
+
*/
|
|
143
|
+
sleep(ms) {
|
|
144
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get the appropriate auth token (OAuth access token or API key)
|
|
148
|
+
*/
|
|
149
|
+
getAuthToken() {
|
|
150
|
+
if (this.oauthManager) {
|
|
151
|
+
return this.oauthManager.getAccessToken();
|
|
152
|
+
}
|
|
153
|
+
if (!this.apiKey) {
|
|
154
|
+
throw new Error("No authentication method available. This should not happen with proper configuration.");
|
|
155
|
+
}
|
|
156
|
+
return this.apiKey;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Handle the response from the API
|
|
160
|
+
*/
|
|
161
|
+
async handleResponse(response) {
|
|
162
|
+
// Handle non-JSON responses (like 204 No Content)
|
|
163
|
+
if (response.status === 204) {
|
|
164
|
+
return {};
|
|
165
|
+
}
|
|
166
|
+
const responseData = await response.json();
|
|
167
|
+
if (!response.ok) {
|
|
168
|
+
// Type guard for error response structure
|
|
169
|
+
const errorData = responseData;
|
|
170
|
+
const error = {
|
|
171
|
+
message: (typeof errorData.message === "string"
|
|
172
|
+
? errorData.message
|
|
173
|
+
: undefined) || `HTTP ${response.status}: ${response.statusText}`,
|
|
174
|
+
status: response.status,
|
|
175
|
+
code: typeof errorData.code === "string" ? errorData.code : undefined,
|
|
176
|
+
};
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
return responseData;
|
|
180
|
+
}
|
|
181
|
+
async get(path, params) {
|
|
182
|
+
return this.request({ method: "GET", path, params });
|
|
183
|
+
}
|
|
184
|
+
async post(path, body) {
|
|
185
|
+
return this.request({ method: "POST", path, body });
|
|
186
|
+
}
|
|
187
|
+
async put(path, body) {
|
|
188
|
+
return this.request({ method: "PUT", path, body });
|
|
189
|
+
}
|
|
190
|
+
async patch(path, body) {
|
|
191
|
+
return this.request({ method: "PATCH", path, body });
|
|
192
|
+
}
|
|
193
|
+
async delete(path) {
|
|
194
|
+
return this.request({ method: "DELETE", path });
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Get the OAuth token manager (if using OAuth)
|
|
198
|
+
*/
|
|
199
|
+
getOAuthManager() {
|
|
200
|
+
return this.oauthManager;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Check if the client is using OAuth authentication
|
|
204
|
+
*/
|
|
205
|
+
isUsingOAuth() {
|
|
206
|
+
return !!this.oauthManager;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Update OAuth configuration (useful for updating tokens)
|
|
210
|
+
*/
|
|
211
|
+
updateOAuthConfig(updates) {
|
|
212
|
+
if (!this.oauthManager) {
|
|
213
|
+
throw new Error("OAuth is not configured for this client");
|
|
214
|
+
}
|
|
215
|
+
this.oauthManager.updateConfig(updates);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/front.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FrontClient } from "./client";
|
|
2
|
+
import { Accounts } from "./resources/accounts";
|
|
3
|
+
import { Conversations } from "./resources/conversations";
|
|
4
|
+
import { Teammates } from "./resources/teammates";
|
|
5
|
+
import type { FrontConfig } from "./types";
|
|
6
|
+
export declare class Front {
|
|
7
|
+
private client;
|
|
8
|
+
readonly teammates: Teammates;
|
|
9
|
+
readonly conversations: Conversations;
|
|
10
|
+
readonly accounts: Accounts;
|
|
11
|
+
constructor(config: FrontConfig);
|
|
12
|
+
/**
|
|
13
|
+
* Get the underlying HTTP client for advanced usage
|
|
14
|
+
*/
|
|
15
|
+
getClient(): FrontClient;
|
|
16
|
+
/**
|
|
17
|
+
* Check if the SDK is using OAuth authentication
|
|
18
|
+
*/
|
|
19
|
+
isUsingOAuth(): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Get the OAuth token manager (if using OAuth)
|
|
22
|
+
*/
|
|
23
|
+
getOAuthManager(): import("./oauth").OAuthTokenManager | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Update OAuth configuration (useful for updating tokens)
|
|
26
|
+
*/
|
|
27
|
+
updateOAuthConfig(updates: Partial<FrontConfig["oauth"]>): void;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=front.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"front.d.ts","sourceRoot":"","sources":["../src/front.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAE1C,qBAAa,KAAK;IAChB,OAAO,CAAC,MAAM,CAAa;IAE3B,SAAgB,SAAS,EAAE,SAAS,CAAA;IACpC,SAAgB,aAAa,EAAE,aAAa,CAAA;IAC5C,SAAgB,QAAQ,EAAE,QAAQ,CAAA;gBAEtB,MAAM,EAAE,WAAW;IAS/B;;OAEG;IACH,SAAS,IAAI,WAAW;IAIxB;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,eAAe;IAIf;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;CAIzD"}
|