@redseat/api 0.0.7 → 0.0.8
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/README.md +132 -132
- package/agents.md +275 -275
- package/client.md +288 -288
- package/dist/library.d.ts +0 -1
- package/dist/library.js +1 -5
- package/encryption.md +533 -533
- package/firebase.md +602 -602
- package/libraries.md +1652 -1652
- package/package.json +49 -49
- package/server.md +196 -196
- package/test.md +291 -291
package/client.md
CHANGED
|
@@ -1,288 +1,288 @@
|
|
|
1
|
-
# RedseatClient
|
|
2
|
-
|
|
3
|
-
The `RedseatClient` class is the low-level HTTP client that handles all communication with Redseat servers. It provides automatic token management, local server detection, and request/response interceptors.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
`RedseatClient` wraps Axios and adds:
|
|
8
|
-
- Automatic token refresh before expiration
|
|
9
|
-
- Local server detection (for development)
|
|
10
|
-
- 401 error handling with automatic retry
|
|
11
|
-
- Request/response interceptors for authentication
|
|
12
|
-
|
|
13
|
-
## Constructor
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
new RedseatClient(options: ClientOptions)
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
### ClientOptions Interface
|
|
20
|
-
|
|
21
|
-
```typescript
|
|
22
|
-
interface ClientOptions {
|
|
23
|
-
server: IServer;
|
|
24
|
-
getIdToken: () => Promise<string>;
|
|
25
|
-
refreshThreshold?: number; // milliseconds before expiration to refresh (default: 5 minutes)
|
|
26
|
-
}
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
**Parameters:**
|
|
30
|
-
- `server`: Server configuration object with `id`, `url`, and optional `port`
|
|
31
|
-
- `getIdToken`: Async function that returns the current ID token from your auth provider
|
|
32
|
-
- `refreshThreshold`: Optional. Milliseconds before token expiration to trigger refresh (default: 300000 = 5 minutes)
|
|
33
|
-
|
|
34
|
-
**Example:**
|
|
35
|
-
```typescript
|
|
36
|
-
const client = new RedseatClient({
|
|
37
|
-
server: {
|
|
38
|
-
id: 'server-123',
|
|
39
|
-
url: 'example.com',
|
|
40
|
-
port: 443
|
|
41
|
-
},
|
|
42
|
-
getIdToken: async () => {
|
|
43
|
-
// Get ID token from your auth provider (Firebase, Auth0, etc.)
|
|
44
|
-
return await getCurrentUserToken();
|
|
45
|
-
},
|
|
46
|
-
refreshThreshold: 5 * 60 * 1000 // 5 minutes
|
|
47
|
-
});
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## Features
|
|
51
|
-
|
|
52
|
-
### Automatic Token Refresh
|
|
53
|
-
|
|
54
|
-
The client automatically refreshes tokens before they expire. The refresh happens:
|
|
55
|
-
- Before each request if the token is expired or expiring soon
|
|
56
|
-
- When a 401 error is received (with automatic retry)
|
|
57
|
-
|
|
58
|
-
### Local Server Detection
|
|
59
|
-
|
|
60
|
-
The client automatically detects if a local development server is available by checking `local.{server.url}`. If detected, it uses the local URL instead of the production URL.
|
|
61
|
-
|
|
62
|
-
### Request Interceptor
|
|
63
|
-
|
|
64
|
-
All requests are intercepted to:
|
|
65
|
-
1. Check if token needs refresh
|
|
66
|
-
2. Add `Authorization: Bearer {token}` header
|
|
67
|
-
|
|
68
|
-
### Response Interceptor
|
|
69
|
-
|
|
70
|
-
All responses are intercepted to:
|
|
71
|
-
1. Handle 401 errors by refreshing token and retrying the request
|
|
72
|
-
2. Prevent infinite retry loops with `_retry` flag
|
|
73
|
-
|
|
74
|
-
## Methods
|
|
75
|
-
|
|
76
|
-
### `get<T>(url: string, config?: AxiosRequestConfig)`
|
|
77
|
-
|
|
78
|
-
Performs a GET request.
|
|
79
|
-
|
|
80
|
-
**Parameters:**
|
|
81
|
-
- `url`: The endpoint URL (relative to base URL)
|
|
82
|
-
- `config`: Optional Axios request configuration
|
|
83
|
-
|
|
84
|
-
**Returns:** `Promise<AxiosResponse<T>>`
|
|
85
|
-
|
|
86
|
-
**Example:**
|
|
87
|
-
```typescript
|
|
88
|
-
const response = await client.get<IFile[]>('/libraries/123/medias');
|
|
89
|
-
const medias = response.data;
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### `post<T>(url: string, data?: unknown, config?: AxiosRequestConfig)`
|
|
93
|
-
|
|
94
|
-
Performs a POST request.
|
|
95
|
-
|
|
96
|
-
**Parameters:**
|
|
97
|
-
- `url`: The endpoint URL
|
|
98
|
-
- `data`: Request body data
|
|
99
|
-
- `config`: Optional Axios request configuration
|
|
100
|
-
|
|
101
|
-
**Returns:** `Promise<AxiosResponse<T>>`
|
|
102
|
-
|
|
103
|
-
**Example:**
|
|
104
|
-
```typescript
|
|
105
|
-
const response = await client.post<ITag>('/libraries/123/tags', {
|
|
106
|
-
name: 'Vacation'
|
|
107
|
-
});
|
|
108
|
-
const tag = response.data;
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### `put<T>(url: string, data?: unknown, config?: AxiosRequestConfig)`
|
|
112
|
-
|
|
113
|
-
Performs a PUT request.
|
|
114
|
-
|
|
115
|
-
**Parameters:**
|
|
116
|
-
- `url`: The endpoint URL
|
|
117
|
-
- `data`: Request body data
|
|
118
|
-
- `config`: Optional Axios request configuration
|
|
119
|
-
|
|
120
|
-
**Returns:** `Promise<AxiosResponse<T>>`
|
|
121
|
-
|
|
122
|
-
**Example:**
|
|
123
|
-
```typescript
|
|
124
|
-
const formData = new FormData();
|
|
125
|
-
formData.append('file', fileBlob);
|
|
126
|
-
const response = await client.put('/libraries/123/medias/transfert', formData);
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
### `patch<T>(url: string, data?: unknown, config?: AxiosRequestConfig)`
|
|
130
|
-
|
|
131
|
-
Performs a PATCH request.
|
|
132
|
-
|
|
133
|
-
**Parameters:**
|
|
134
|
-
- `url`: The endpoint URL
|
|
135
|
-
- `data`: Request body data
|
|
136
|
-
- `config`: Optional Axios request configuration
|
|
137
|
-
|
|
138
|
-
**Returns:** `Promise<AxiosResponse<T>>`
|
|
139
|
-
|
|
140
|
-
**Example:**
|
|
141
|
-
```typescript
|
|
142
|
-
const response = await client.patch<ITag>('/libraries/123/tags/tag-id', {
|
|
143
|
-
rename: 'New Tag Name'
|
|
144
|
-
});
|
|
145
|
-
const updatedTag = response.data;
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### `delete<T>(url: string, config?: AxiosRequestConfig)`
|
|
149
|
-
|
|
150
|
-
Performs a DELETE request.
|
|
151
|
-
|
|
152
|
-
**Parameters:**
|
|
153
|
-
- `url`: The endpoint URL
|
|
154
|
-
- `config`: Optional Axios request configuration (can include `data` for request body)
|
|
155
|
-
|
|
156
|
-
**Returns:** `Promise<AxiosResponse<T>>`
|
|
157
|
-
|
|
158
|
-
**Example:**
|
|
159
|
-
```typescript
|
|
160
|
-
// Simple delete
|
|
161
|
-
await client.delete('/libraries/123/tags/tag-id');
|
|
162
|
-
|
|
163
|
-
// Delete with body
|
|
164
|
-
await client.delete('/libraries/123/medias', {
|
|
165
|
-
data: { ids: ['media-1', 'media-2'] }
|
|
166
|
-
});
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### `request<T>(method: Method, url: string, data?: unknown, config?: AxiosRequestConfig)`
|
|
170
|
-
|
|
171
|
-
Performs a custom HTTP request.
|
|
172
|
-
|
|
173
|
-
**Parameters:**
|
|
174
|
-
- `method`: HTTP method ('GET', 'POST', 'PUT', 'PATCH', 'DELETE', etc.)
|
|
175
|
-
- `url`: The endpoint URL
|
|
176
|
-
- `data`: Request body data
|
|
177
|
-
- `config`: Optional Axios request configuration
|
|
178
|
-
|
|
179
|
-
**Returns:** `Promise<AxiosResponse<T>>`
|
|
180
|
-
|
|
181
|
-
**Example:**
|
|
182
|
-
```typescript
|
|
183
|
-
const response = await client.request<IFile>(
|
|
184
|
-
'GET',
|
|
185
|
-
'/libraries/123/medias/media-id',
|
|
186
|
-
undefined,
|
|
187
|
-
{ responseType: 'blob' }
|
|
188
|
-
);
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### `setToken(token: string | IToken)`
|
|
192
|
-
|
|
193
|
-
Manually set the authentication token. Useful when you already have a valid token.
|
|
194
|
-
|
|
195
|
-
**Parameters:**
|
|
196
|
-
- `token`: Either a token string or an `IToken` object with `token` and `expires` properties
|
|
197
|
-
|
|
198
|
-
**Example:**
|
|
199
|
-
```typescript
|
|
200
|
-
// Set as string (will be treated as expiring soon)
|
|
201
|
-
client.setToken('your-token-string');
|
|
202
|
-
|
|
203
|
-
// Set as IToken object with expiration
|
|
204
|
-
client.setToken({
|
|
205
|
-
token: 'your-token-string',
|
|
206
|
-
expires: Date.now() + 3600000 // 1 hour from now
|
|
207
|
-
});
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
## Error Handling
|
|
211
|
-
|
|
212
|
-
The client automatically handles:
|
|
213
|
-
- **401 Unauthorized**: Refreshes token and retries the request once
|
|
214
|
-
- **Token expiration**: Refreshes token before making requests
|
|
215
|
-
- **Network errors**: Passes through to caller
|
|
216
|
-
|
|
217
|
-
**Example error handling:**
|
|
218
|
-
```typescript
|
|
219
|
-
try {
|
|
220
|
-
const response = await client.get('/libraries/123/medias');
|
|
221
|
-
} catch (error) {
|
|
222
|
-
if (error.response?.status === 401) {
|
|
223
|
-
// Token refresh failed or invalid credentials
|
|
224
|
-
console.error('Authentication failed');
|
|
225
|
-
} else if (error.response?.status === 404) {
|
|
226
|
-
// Resource not found
|
|
227
|
-
console.error('Resource not found');
|
|
228
|
-
} else {
|
|
229
|
-
// Other error
|
|
230
|
-
console.error('Request failed:', error.message);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
## Usage with Response Types
|
|
236
|
-
|
|
237
|
-
The client supports specifying response types for binary data:
|
|
238
|
-
|
|
239
|
-
```typescript
|
|
240
|
-
// Get as stream
|
|
241
|
-
const stream = await client.get('/libraries/123/medias/media-id', {
|
|
242
|
-
responseType: 'stream'
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
// Get as ArrayBuffer
|
|
246
|
-
const buffer = await client.get('/libraries/123/medias/media-id', {
|
|
247
|
-
responseType: 'arraybuffer'
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
// Get as Blob
|
|
251
|
-
const blob = await client.get('/libraries/123/medias/media-id', {
|
|
252
|
-
responseType: 'blob'
|
|
253
|
-
});
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
## Progress Tracking
|
|
257
|
-
|
|
258
|
-
For file uploads, you can track progress:
|
|
259
|
-
|
|
260
|
-
```typescript
|
|
261
|
-
const formData = new FormData();
|
|
262
|
-
formData.append('file', fileBlob);
|
|
263
|
-
|
|
264
|
-
await client.post('/libraries/123/medias', formData, {
|
|
265
|
-
onUploadProgress: (progressEvent) => {
|
|
266
|
-
if (progressEvent.total) {
|
|
267
|
-
const percent = (progressEvent.loaded / progressEvent.total) * 100;
|
|
268
|
-
console.log(`Upload progress: ${percent}%`);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
## Internal Methods (Private)
|
|
275
|
-
|
|
276
|
-
The following methods are used internally and should not be called directly:
|
|
277
|
-
- `refreshToken()` - Refreshes the authentication token
|
|
278
|
-
- `ensureValidToken()` - Ensures token is valid before requests
|
|
279
|
-
- `isTokenExpiredOrExpiringSoon()` - Checks if token needs refresh
|
|
280
|
-
- `detectLocalUrl()` - Detects local development server
|
|
281
|
-
- `getRegularServerUrl()` - Gets production server URL
|
|
282
|
-
|
|
283
|
-
## See Also
|
|
284
|
-
|
|
285
|
-
- [ServerApi Documentation](server.md) - Uses RedseatClient for server operations
|
|
286
|
-
- [LibraryApi Documentation](libraries.md) - Uses RedseatClient for library operations
|
|
287
|
-
- [README](README.md) - Package overview
|
|
288
|
-
|
|
1
|
+
# RedseatClient
|
|
2
|
+
|
|
3
|
+
The `RedseatClient` class is the low-level HTTP client that handles all communication with Redseat servers. It provides automatic token management, local server detection, and request/response interceptors.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`RedseatClient` wraps Axios and adds:
|
|
8
|
+
- Automatic token refresh before expiration
|
|
9
|
+
- Local server detection (for development)
|
|
10
|
+
- 401 error handling with automatic retry
|
|
11
|
+
- Request/response interceptors for authentication
|
|
12
|
+
|
|
13
|
+
## Constructor
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
new RedseatClient(options: ClientOptions)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### ClientOptions Interface
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
interface ClientOptions {
|
|
23
|
+
server: IServer;
|
|
24
|
+
getIdToken: () => Promise<string>;
|
|
25
|
+
refreshThreshold?: number; // milliseconds before expiration to refresh (default: 5 minutes)
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Parameters:**
|
|
30
|
+
- `server`: Server configuration object with `id`, `url`, and optional `port`
|
|
31
|
+
- `getIdToken`: Async function that returns the current ID token from your auth provider
|
|
32
|
+
- `refreshThreshold`: Optional. Milliseconds before token expiration to trigger refresh (default: 300000 = 5 minutes)
|
|
33
|
+
|
|
34
|
+
**Example:**
|
|
35
|
+
```typescript
|
|
36
|
+
const client = new RedseatClient({
|
|
37
|
+
server: {
|
|
38
|
+
id: 'server-123',
|
|
39
|
+
url: 'example.com',
|
|
40
|
+
port: 443
|
|
41
|
+
},
|
|
42
|
+
getIdToken: async () => {
|
|
43
|
+
// Get ID token from your auth provider (Firebase, Auth0, etc.)
|
|
44
|
+
return await getCurrentUserToken();
|
|
45
|
+
},
|
|
46
|
+
refreshThreshold: 5 * 60 * 1000 // 5 minutes
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Features
|
|
51
|
+
|
|
52
|
+
### Automatic Token Refresh
|
|
53
|
+
|
|
54
|
+
The client automatically refreshes tokens before they expire. The refresh happens:
|
|
55
|
+
- Before each request if the token is expired or expiring soon
|
|
56
|
+
- When a 401 error is received (with automatic retry)
|
|
57
|
+
|
|
58
|
+
### Local Server Detection
|
|
59
|
+
|
|
60
|
+
The client automatically detects if a local development server is available by checking `local.{server.url}`. If detected, it uses the local URL instead of the production URL.
|
|
61
|
+
|
|
62
|
+
### Request Interceptor
|
|
63
|
+
|
|
64
|
+
All requests are intercepted to:
|
|
65
|
+
1. Check if token needs refresh
|
|
66
|
+
2. Add `Authorization: Bearer {token}` header
|
|
67
|
+
|
|
68
|
+
### Response Interceptor
|
|
69
|
+
|
|
70
|
+
All responses are intercepted to:
|
|
71
|
+
1. Handle 401 errors by refreshing token and retrying the request
|
|
72
|
+
2. Prevent infinite retry loops with `_retry` flag
|
|
73
|
+
|
|
74
|
+
## Methods
|
|
75
|
+
|
|
76
|
+
### `get<T>(url: string, config?: AxiosRequestConfig)`
|
|
77
|
+
|
|
78
|
+
Performs a GET request.
|
|
79
|
+
|
|
80
|
+
**Parameters:**
|
|
81
|
+
- `url`: The endpoint URL (relative to base URL)
|
|
82
|
+
- `config`: Optional Axios request configuration
|
|
83
|
+
|
|
84
|
+
**Returns:** `Promise<AxiosResponse<T>>`
|
|
85
|
+
|
|
86
|
+
**Example:**
|
|
87
|
+
```typescript
|
|
88
|
+
const response = await client.get<IFile[]>('/libraries/123/medias');
|
|
89
|
+
const medias = response.data;
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### `post<T>(url: string, data?: unknown, config?: AxiosRequestConfig)`
|
|
93
|
+
|
|
94
|
+
Performs a POST request.
|
|
95
|
+
|
|
96
|
+
**Parameters:**
|
|
97
|
+
- `url`: The endpoint URL
|
|
98
|
+
- `data`: Request body data
|
|
99
|
+
- `config`: Optional Axios request configuration
|
|
100
|
+
|
|
101
|
+
**Returns:** `Promise<AxiosResponse<T>>`
|
|
102
|
+
|
|
103
|
+
**Example:**
|
|
104
|
+
```typescript
|
|
105
|
+
const response = await client.post<ITag>('/libraries/123/tags', {
|
|
106
|
+
name: 'Vacation'
|
|
107
|
+
});
|
|
108
|
+
const tag = response.data;
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### `put<T>(url: string, data?: unknown, config?: AxiosRequestConfig)`
|
|
112
|
+
|
|
113
|
+
Performs a PUT request.
|
|
114
|
+
|
|
115
|
+
**Parameters:**
|
|
116
|
+
- `url`: The endpoint URL
|
|
117
|
+
- `data`: Request body data
|
|
118
|
+
- `config`: Optional Axios request configuration
|
|
119
|
+
|
|
120
|
+
**Returns:** `Promise<AxiosResponse<T>>`
|
|
121
|
+
|
|
122
|
+
**Example:**
|
|
123
|
+
```typescript
|
|
124
|
+
const formData = new FormData();
|
|
125
|
+
formData.append('file', fileBlob);
|
|
126
|
+
const response = await client.put('/libraries/123/medias/transfert', formData);
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### `patch<T>(url: string, data?: unknown, config?: AxiosRequestConfig)`
|
|
130
|
+
|
|
131
|
+
Performs a PATCH request.
|
|
132
|
+
|
|
133
|
+
**Parameters:**
|
|
134
|
+
- `url`: The endpoint URL
|
|
135
|
+
- `data`: Request body data
|
|
136
|
+
- `config`: Optional Axios request configuration
|
|
137
|
+
|
|
138
|
+
**Returns:** `Promise<AxiosResponse<T>>`
|
|
139
|
+
|
|
140
|
+
**Example:**
|
|
141
|
+
```typescript
|
|
142
|
+
const response = await client.patch<ITag>('/libraries/123/tags/tag-id', {
|
|
143
|
+
rename: 'New Tag Name'
|
|
144
|
+
});
|
|
145
|
+
const updatedTag = response.data;
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### `delete<T>(url: string, config?: AxiosRequestConfig)`
|
|
149
|
+
|
|
150
|
+
Performs a DELETE request.
|
|
151
|
+
|
|
152
|
+
**Parameters:**
|
|
153
|
+
- `url`: The endpoint URL
|
|
154
|
+
- `config`: Optional Axios request configuration (can include `data` for request body)
|
|
155
|
+
|
|
156
|
+
**Returns:** `Promise<AxiosResponse<T>>`
|
|
157
|
+
|
|
158
|
+
**Example:**
|
|
159
|
+
```typescript
|
|
160
|
+
// Simple delete
|
|
161
|
+
await client.delete('/libraries/123/tags/tag-id');
|
|
162
|
+
|
|
163
|
+
// Delete with body
|
|
164
|
+
await client.delete('/libraries/123/medias', {
|
|
165
|
+
data: { ids: ['media-1', 'media-2'] }
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### `request<T>(method: Method, url: string, data?: unknown, config?: AxiosRequestConfig)`
|
|
170
|
+
|
|
171
|
+
Performs a custom HTTP request.
|
|
172
|
+
|
|
173
|
+
**Parameters:**
|
|
174
|
+
- `method`: HTTP method ('GET', 'POST', 'PUT', 'PATCH', 'DELETE', etc.)
|
|
175
|
+
- `url`: The endpoint URL
|
|
176
|
+
- `data`: Request body data
|
|
177
|
+
- `config`: Optional Axios request configuration
|
|
178
|
+
|
|
179
|
+
**Returns:** `Promise<AxiosResponse<T>>`
|
|
180
|
+
|
|
181
|
+
**Example:**
|
|
182
|
+
```typescript
|
|
183
|
+
const response = await client.request<IFile>(
|
|
184
|
+
'GET',
|
|
185
|
+
'/libraries/123/medias/media-id',
|
|
186
|
+
undefined,
|
|
187
|
+
{ responseType: 'blob' }
|
|
188
|
+
);
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### `setToken(token: string | IToken)`
|
|
192
|
+
|
|
193
|
+
Manually set the authentication token. Useful when you already have a valid token.
|
|
194
|
+
|
|
195
|
+
**Parameters:**
|
|
196
|
+
- `token`: Either a token string or an `IToken` object with `token` and `expires` properties
|
|
197
|
+
|
|
198
|
+
**Example:**
|
|
199
|
+
```typescript
|
|
200
|
+
// Set as string (will be treated as expiring soon)
|
|
201
|
+
client.setToken('your-token-string');
|
|
202
|
+
|
|
203
|
+
// Set as IToken object with expiration
|
|
204
|
+
client.setToken({
|
|
205
|
+
token: 'your-token-string',
|
|
206
|
+
expires: Date.now() + 3600000 // 1 hour from now
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Error Handling
|
|
211
|
+
|
|
212
|
+
The client automatically handles:
|
|
213
|
+
- **401 Unauthorized**: Refreshes token and retries the request once
|
|
214
|
+
- **Token expiration**: Refreshes token before making requests
|
|
215
|
+
- **Network errors**: Passes through to caller
|
|
216
|
+
|
|
217
|
+
**Example error handling:**
|
|
218
|
+
```typescript
|
|
219
|
+
try {
|
|
220
|
+
const response = await client.get('/libraries/123/medias');
|
|
221
|
+
} catch (error) {
|
|
222
|
+
if (error.response?.status === 401) {
|
|
223
|
+
// Token refresh failed or invalid credentials
|
|
224
|
+
console.error('Authentication failed');
|
|
225
|
+
} else if (error.response?.status === 404) {
|
|
226
|
+
// Resource not found
|
|
227
|
+
console.error('Resource not found');
|
|
228
|
+
} else {
|
|
229
|
+
// Other error
|
|
230
|
+
console.error('Request failed:', error.message);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Usage with Response Types
|
|
236
|
+
|
|
237
|
+
The client supports specifying response types for binary data:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
// Get as stream
|
|
241
|
+
const stream = await client.get('/libraries/123/medias/media-id', {
|
|
242
|
+
responseType: 'stream'
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// Get as ArrayBuffer
|
|
246
|
+
const buffer = await client.get('/libraries/123/medias/media-id', {
|
|
247
|
+
responseType: 'arraybuffer'
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// Get as Blob
|
|
251
|
+
const blob = await client.get('/libraries/123/medias/media-id', {
|
|
252
|
+
responseType: 'blob'
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Progress Tracking
|
|
257
|
+
|
|
258
|
+
For file uploads, you can track progress:
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
const formData = new FormData();
|
|
262
|
+
formData.append('file', fileBlob);
|
|
263
|
+
|
|
264
|
+
await client.post('/libraries/123/medias', formData, {
|
|
265
|
+
onUploadProgress: (progressEvent) => {
|
|
266
|
+
if (progressEvent.total) {
|
|
267
|
+
const percent = (progressEvent.loaded / progressEvent.total) * 100;
|
|
268
|
+
console.log(`Upload progress: ${percent}%`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Internal Methods (Private)
|
|
275
|
+
|
|
276
|
+
The following methods are used internally and should not be called directly:
|
|
277
|
+
- `refreshToken()` - Refreshes the authentication token
|
|
278
|
+
- `ensureValidToken()` - Ensures token is valid before requests
|
|
279
|
+
- `isTokenExpiredOrExpiringSoon()` - Checks if token needs refresh
|
|
280
|
+
- `detectLocalUrl()` - Detects local development server
|
|
281
|
+
- `getRegularServerUrl()` - Gets production server URL
|
|
282
|
+
|
|
283
|
+
## See Also
|
|
284
|
+
|
|
285
|
+
- [ServerApi Documentation](server.md) - Uses RedseatClient for server operations
|
|
286
|
+
- [LibraryApi Documentation](libraries.md) - Uses RedseatClient for library operations
|
|
287
|
+
- [README](README.md) - Package overview
|
|
288
|
+
|
package/dist/library.d.ts
CHANGED
|
@@ -151,7 +151,6 @@ export declare class LibraryApi {
|
|
|
151
151
|
faceClusterPerson(personId: string): Promise<void>;
|
|
152
152
|
mergePeople(request: any): Promise<any>;
|
|
153
153
|
clusterFaces(personId: string): Promise<any>;
|
|
154
|
-
getMediaPureMetadata(mediaId: string): Promise<IFile>;
|
|
155
154
|
mergeMedias(request: any): Promise<IFile>;
|
|
156
155
|
mediaUpdateMany(update: any, ids: string[]): Promise<IFile[]>;
|
|
157
156
|
mediaUpdateProgress(mediaId: string, progress: number): Promise<{
|
package/dist/library.js
CHANGED
|
@@ -143,7 +143,7 @@ export class LibraryApi {
|
|
|
143
143
|
await this.client.delete(this.getUrl('/medias'), { data: { ids: mediaIds } });
|
|
144
144
|
}
|
|
145
145
|
async getMediaMetadata(mediaId) {
|
|
146
|
-
const res = await this.client.get(this.getUrl(`/medias/${mediaId}`));
|
|
146
|
+
const res = await this.client.get(this.getUrl(`/medias/${mediaId}/metadata`));
|
|
147
147
|
return res.data;
|
|
148
148
|
}
|
|
149
149
|
async getMediaBackupMetadatas(mediaId) {
|
|
@@ -345,10 +345,6 @@ export class LibraryApi {
|
|
|
345
345
|
const res = await this.client.post(this.getUrl(`/people/${personId}/faces/cluster`), {});
|
|
346
346
|
return res.data;
|
|
347
347
|
}
|
|
348
|
-
async getMediaPureMetadata(mediaId) {
|
|
349
|
-
const res = await this.client.get(this.getUrl(`/medias/${mediaId}`));
|
|
350
|
-
return res.data;
|
|
351
|
-
}
|
|
352
348
|
async mergeMedias(request) {
|
|
353
349
|
const res = await this.client.post(this.getUrl('/medias/merge'), request);
|
|
354
350
|
return res.data;
|