@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/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;