@redseat/api 0.0.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/README.md +132 -0
- package/agents.md +275 -0
- package/client.md +288 -0
- package/dist/auth.d.ts +5 -0
- package/dist/auth.js +10 -0
- package/dist/client.d.ts +32 -0
- package/dist/client.js +157 -0
- package/dist/crypto.d.ts +36 -0
- package/dist/crypto.js +164 -0
- package/dist/encryption.d.ts +73 -0
- package/dist/encryption.js +238 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/interfaces.d.ts +311 -0
- package/dist/interfaces.js +38 -0
- package/dist/library.d.ts +231 -0
- package/dist/library.js +589 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.js +33 -0
- package/dist/upload.d.ts +16 -0
- package/dist/upload.js +28 -0
- package/encryption.md +533 -0
- package/libraries.md +1652 -0
- package/package.json +50 -0
- package/server.md +196 -0
- package/test.md +291 -0
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# @redseat/api
|
|
2
|
+
|
|
3
|
+
TypeScript API client library for interacting with Redseat servers. This package provides a comprehensive set of APIs for managing libraries, media, tags, people, series, movies, and more.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `@redseat/api` package is organized into three main API classes:
|
|
8
|
+
|
|
9
|
+
- **RedseatClient**: Low-level HTTP client with automatic token management and local server detection
|
|
10
|
+
- **ServerApi**: Server-level operations (libraries, settings, plugins, credentials)
|
|
11
|
+
- **LibraryApi**: Library-specific operations (media, tags, people, series, movies, encryption)
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { RedseatClient, ServerApi, LibraryApi } from '@redseat/api';
|
|
17
|
+
import { IServer, ILibrary } from '@redseat/api';
|
|
18
|
+
|
|
19
|
+
// Initialize the client
|
|
20
|
+
const client = new RedseatClient({
|
|
21
|
+
server: {
|
|
22
|
+
id: 'server-id',
|
|
23
|
+
url: 'example.com',
|
|
24
|
+
port: 443
|
|
25
|
+
},
|
|
26
|
+
getIdToken: async () => {
|
|
27
|
+
// Return your ID token from your auth provider
|
|
28
|
+
return 'your-id-token';
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Get server API
|
|
33
|
+
const serverApi = new ServerApi(client);
|
|
34
|
+
|
|
35
|
+
// Get libraries
|
|
36
|
+
const libraries = await serverApi.getLibraries();
|
|
37
|
+
|
|
38
|
+
// Get library API for a specific library
|
|
39
|
+
const library = libraries[0];
|
|
40
|
+
const libraryApi = new LibraryApi(client, library.id!, library);
|
|
41
|
+
|
|
42
|
+
// For encrypted libraries, set the encryption key
|
|
43
|
+
if (library.crypt) {
|
|
44
|
+
await libraryApi.setKey('your-passphrase');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Get media
|
|
48
|
+
const medias = await libraryApi.getMedias();
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Documentation
|
|
52
|
+
|
|
53
|
+
- **[client.md](client.md)** - RedseatClient documentation
|
|
54
|
+
- HTTP client configuration
|
|
55
|
+
- Automatic token refresh
|
|
56
|
+
- Local server detection
|
|
57
|
+
- Request/response interceptors
|
|
58
|
+
|
|
59
|
+
- **[server.md](server.md)** - ServerApi documentation
|
|
60
|
+
- Server-level operations
|
|
61
|
+
- Library management
|
|
62
|
+
- Settings and plugins
|
|
63
|
+
- Credentials management
|
|
64
|
+
|
|
65
|
+
- **[libraries.md](libraries.md)** - LibraryApi documentation
|
|
66
|
+
- Media operations (upload, download, update)
|
|
67
|
+
- Tags, people, series, movies management
|
|
68
|
+
- Face recognition operations
|
|
69
|
+
- Encryption support for encrypted libraries
|
|
70
|
+
|
|
71
|
+
- **[encryption.md](encryption.md)** - Encryption module documentation
|
|
72
|
+
- Key derivation (PBKDF2)
|
|
73
|
+
- Text and binary encryption/decryption
|
|
74
|
+
- File encryption with thumbnails
|
|
75
|
+
- Cross-platform compatibility
|
|
76
|
+
|
|
77
|
+
- **[test.md](test.md)** - Testing guide
|
|
78
|
+
- How to run tests
|
|
79
|
+
- Test file descriptions
|
|
80
|
+
- Test coverage information
|
|
81
|
+
|
|
82
|
+
- **[agents.md](agents.md)** - AI agent instructions
|
|
83
|
+
- Documentation maintenance guidelines
|
|
84
|
+
- Code change workflow
|
|
85
|
+
- Best practices for keeping docs updated
|
|
86
|
+
|
|
87
|
+
## Package Exports
|
|
88
|
+
|
|
89
|
+
### Classes
|
|
90
|
+
- `RedseatClient` - HTTP client with authentication
|
|
91
|
+
- `ServerApi` - Server-level API operations
|
|
92
|
+
- `LibraryApi` - Library-level API operations
|
|
93
|
+
|
|
94
|
+
### Interfaces
|
|
95
|
+
- `IFile` - Media file interface
|
|
96
|
+
- `ILibrary` - Library interface
|
|
97
|
+
- `ITag` - Tag interface
|
|
98
|
+
- `IPerson` - Person interface
|
|
99
|
+
- `ISerie` - Series interface
|
|
100
|
+
- `IMovie` - Movie interface
|
|
101
|
+
- `IServer` - Server interface
|
|
102
|
+
- `MediaRequest` - Media query filter
|
|
103
|
+
- And more (see `src/interfaces.ts`)
|
|
104
|
+
|
|
105
|
+
### Encryption Functions
|
|
106
|
+
- `deriveKey()` - Derive encryption key from passphrase
|
|
107
|
+
- `encryptText()` / `decryptText()` - Text encryption
|
|
108
|
+
- `encryptBuffer()` / `decryptBuffer()` - Binary encryption
|
|
109
|
+
- `encryptFile()` / `decryptFile()` - File encryption with metadata
|
|
110
|
+
- `getRandomIV()` - Generate random IV
|
|
111
|
+
|
|
112
|
+
### Utilities
|
|
113
|
+
- `fetchServerToken()` - Fetch server authentication token
|
|
114
|
+
- Base64 encoding/decoding utilities
|
|
115
|
+
- Crypto utilities for cross-platform support
|
|
116
|
+
|
|
117
|
+
## Installation
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npm install @redseat/api
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Requirements
|
|
124
|
+
|
|
125
|
+
- Node.js 15+ (for Web Crypto API support)
|
|
126
|
+
- TypeScript 5.0+
|
|
127
|
+
- Axios 1.11.0+
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
See the main project LICENSE file.
|
|
132
|
+
|
package/agents.md
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# AI Agent Instructions
|
|
2
|
+
|
|
3
|
+
This document provides guidelines for AI agents working with the `@redseat/api` package. Follow these instructions to maintain code quality and keep documentation up to date.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
### Always Read First
|
|
8
|
+
|
|
9
|
+
1. **Start with [README.md](README.md)**
|
|
10
|
+
- Understand the package structure
|
|
11
|
+
- Identify which API classes are relevant to your task
|
|
12
|
+
- Find links to specialized documentation
|
|
13
|
+
|
|
14
|
+
2. **Read Relevant Documentation**
|
|
15
|
+
- [client.md](client.md) - For HTTP client changes
|
|
16
|
+
- [server.md](server.md) - For server API changes
|
|
17
|
+
- [libraries.md](libraries.md) - For library API changes
|
|
18
|
+
- [encryption.md](encryption.md) - For encryption module changes
|
|
19
|
+
- [test.md](test.md) - For testing changes
|
|
20
|
+
|
|
21
|
+
3. **Examine Source Code**
|
|
22
|
+
- Read the actual implementation files in `src/`
|
|
23
|
+
- Understand the current architecture
|
|
24
|
+
- Check existing patterns and conventions
|
|
25
|
+
|
|
26
|
+
## Documentation Maintenance
|
|
27
|
+
|
|
28
|
+
### When Modifying Existing Functionality
|
|
29
|
+
|
|
30
|
+
**Required Actions:**
|
|
31
|
+
|
|
32
|
+
1. **Update the Relevant Documentation File**
|
|
33
|
+
- If changing `RedseatClient`: Update [client.md](client.md)
|
|
34
|
+
- If changing `ServerApi`: Update [server.md](server.md)
|
|
35
|
+
- If changing `LibraryApi`: Update [libraries.md](libraries.md)
|
|
36
|
+
- If changing encryption: Update [encryption.md](encryption.md)
|
|
37
|
+
|
|
38
|
+
2. **Update Method Signatures**
|
|
39
|
+
- Document new parameters
|
|
40
|
+
- Document changed return types
|
|
41
|
+
- Document new error cases
|
|
42
|
+
- Update examples if behavior changed
|
|
43
|
+
|
|
44
|
+
3. **Update README.md if Needed**
|
|
45
|
+
- If API signatures changed significantly
|
|
46
|
+
- If new major features were added
|
|
47
|
+
- If package exports changed
|
|
48
|
+
|
|
49
|
+
4. **Keep Examples Current**
|
|
50
|
+
- Update code examples to reflect new behavior
|
|
51
|
+
- Ensure examples are runnable
|
|
52
|
+
- Fix broken examples
|
|
53
|
+
|
|
54
|
+
**Example Workflow:**
|
|
55
|
+
```
|
|
56
|
+
1. User requests: "Add timeout parameter to getMedia()"
|
|
57
|
+
2. Read libraries.md to see current getMedia() documentation
|
|
58
|
+
3. Modify src/library.ts to add timeout parameter
|
|
59
|
+
4. Update libraries.md with new parameter documentation
|
|
60
|
+
5. Update example code in libraries.md
|
|
61
|
+
6. Check if README.md needs updates (probably not for this change)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### When Adding New Functionality
|
|
65
|
+
|
|
66
|
+
**Required Actions:**
|
|
67
|
+
|
|
68
|
+
1. **Document in Appropriate File**
|
|
69
|
+
- Add new methods to the relevant documentation file
|
|
70
|
+
- Follow existing formatting and structure
|
|
71
|
+
- Include parameters, return types, and examples
|
|
72
|
+
|
|
73
|
+
2. **Update README.md**
|
|
74
|
+
- Add to package exports list if it's a new public export
|
|
75
|
+
- Update overview if it's a major feature
|
|
76
|
+
- Add to quick start if it's commonly used
|
|
77
|
+
|
|
78
|
+
3. **Include Usage Examples**
|
|
79
|
+
- Provide at least one example per new method
|
|
80
|
+
- Show common use cases
|
|
81
|
+
- Include error handling examples
|
|
82
|
+
|
|
83
|
+
4. **Update Related Documentation**
|
|
84
|
+
- If adding new encryption function: Update [encryption.md](encryption.md)
|
|
85
|
+
- If adding new test: Update [test.md](test.md)
|
|
86
|
+
- Cross-reference related functionality
|
|
87
|
+
|
|
88
|
+
**Example Workflow:**
|
|
89
|
+
```
|
|
90
|
+
1. User requests: "Add getMediaStats() method to LibraryApi"
|
|
91
|
+
2. Implement method in src/library.ts
|
|
92
|
+
3. Add documentation to libraries.md in "Media" section
|
|
93
|
+
4. Add example showing usage
|
|
94
|
+
5. Update README.md exports if needed
|
|
95
|
+
6. Add test and update test.md if applicable
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Code Change Workflow
|
|
99
|
+
|
|
100
|
+
### Before Making Changes
|
|
101
|
+
|
|
102
|
+
1. **Understand the Request**
|
|
103
|
+
- What functionality is being added/modified?
|
|
104
|
+
- Which files are affected?
|
|
105
|
+
- Are there breaking changes?
|
|
106
|
+
|
|
107
|
+
2. **Plan the Changes**
|
|
108
|
+
- Identify all files that need modification
|
|
109
|
+
- Identify all documentation that needs updates
|
|
110
|
+
- Consider backward compatibility
|
|
111
|
+
|
|
112
|
+
3. **Check Dependencies**
|
|
113
|
+
- Will this change affect other parts of the codebase?
|
|
114
|
+
- Are there tests that need updating?
|
|
115
|
+
- Are there examples that need updating?
|
|
116
|
+
|
|
117
|
+
### During Implementation
|
|
118
|
+
|
|
119
|
+
1. **Follow Existing Patterns**
|
|
120
|
+
- Match code style and conventions
|
|
121
|
+
- Use similar error handling
|
|
122
|
+
- Follow naming conventions
|
|
123
|
+
|
|
124
|
+
2. **Write Tests**
|
|
125
|
+
- Add tests for new functionality
|
|
126
|
+
- Update tests for modified functionality
|
|
127
|
+
- Ensure tests pass
|
|
128
|
+
|
|
129
|
+
3. **Update Documentation As You Go**
|
|
130
|
+
- Don't wait until the end
|
|
131
|
+
- Update docs as you implement
|
|
132
|
+
- This helps catch documentation issues early
|
|
133
|
+
|
|
134
|
+
### After Implementation
|
|
135
|
+
|
|
136
|
+
1. **Verify Documentation**
|
|
137
|
+
- Read through your documentation changes
|
|
138
|
+
- Ensure examples are correct
|
|
139
|
+
- Check for typos and formatting
|
|
140
|
+
|
|
141
|
+
2. **Check Cross-References**
|
|
142
|
+
- Update links if files moved
|
|
143
|
+
- Update related documentation
|
|
144
|
+
- Ensure consistency across files
|
|
145
|
+
|
|
146
|
+
3. **Test Examples**
|
|
147
|
+
- Verify code examples are syntactically correct
|
|
148
|
+
- Ensure examples demonstrate the feature correctly
|
|
149
|
+
- Check that examples use current API
|
|
150
|
+
|
|
151
|
+
## Documentation Standards
|
|
152
|
+
|
|
153
|
+
### Formatting
|
|
154
|
+
|
|
155
|
+
- Use consistent markdown formatting
|
|
156
|
+
- Use code blocks with language tags for code examples
|
|
157
|
+
- Use proper heading hierarchy (## for sections, ### for subsections)
|
|
158
|
+
- Include parameter tables for complex methods
|
|
159
|
+
|
|
160
|
+
### Code Examples
|
|
161
|
+
|
|
162
|
+
- Always include TypeScript type annotations
|
|
163
|
+
- Show both success and error cases when relevant
|
|
164
|
+
- Include imports when showing complete examples
|
|
165
|
+
- Use realistic variable names
|
|
166
|
+
|
|
167
|
+
### Method Documentation Template
|
|
168
|
+
|
|
169
|
+
```markdown
|
|
170
|
+
### `methodName(param1: Type1, param2: Type2): Promise<ReturnType>`
|
|
171
|
+
|
|
172
|
+
Brief description of what the method does.
|
|
173
|
+
|
|
174
|
+
**Parameters:**
|
|
175
|
+
- `param1`: Description of parameter
|
|
176
|
+
- `param2`: Description of parameter
|
|
177
|
+
|
|
178
|
+
**Returns:** Promise resolving to description
|
|
179
|
+
|
|
180
|
+
**Example:**
|
|
181
|
+
\`\`\`typescript
|
|
182
|
+
const result = await libraryApi.methodName('value1', 'value2');
|
|
183
|
+
\`\`\`
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Common Scenarios
|
|
187
|
+
|
|
188
|
+
### Scenario 1: Adding a New Method to LibraryApi
|
|
189
|
+
|
|
190
|
+
1. Implement method in `src/library.ts`
|
|
191
|
+
2. Add documentation to [libraries.md](libraries.md) in appropriate section
|
|
192
|
+
3. Add example code
|
|
193
|
+
4. Add test to appropriate test file
|
|
194
|
+
5. Update [test.md](test.md) if new test file created
|
|
195
|
+
6. Check if [README.md](README.md) needs updates
|
|
196
|
+
|
|
197
|
+
### Scenario 2: Modifying Encryption Function
|
|
198
|
+
|
|
199
|
+
1. Modify function in `src/encryption.ts`
|
|
200
|
+
2. Update [encryption.md](encryption.md) with changes
|
|
201
|
+
3. Update examples if behavior changed
|
|
202
|
+
4. Update tests in `src/encryption.test.ts`
|
|
203
|
+
5. Check if [libraries.md](libraries.md) needs updates (if LibraryApi uses it)
|
|
204
|
+
|
|
205
|
+
### Scenario 3: Adding New Export
|
|
206
|
+
|
|
207
|
+
1. Add export to `src/index.ts`
|
|
208
|
+
2. Update [README.md](README.md) package exports section
|
|
209
|
+
3. Add documentation to appropriate file
|
|
210
|
+
4. Add example in README or relevant doc file
|
|
211
|
+
|
|
212
|
+
### Scenario 4: Breaking Change
|
|
213
|
+
|
|
214
|
+
1. Document breaking change clearly
|
|
215
|
+
2. Update all affected documentation
|
|
216
|
+
3. Update examples to show new usage
|
|
217
|
+
4. Consider migration guide if significant
|
|
218
|
+
|
|
219
|
+
## Quality Checklist
|
|
220
|
+
|
|
221
|
+
Before completing a task, verify:
|
|
222
|
+
|
|
223
|
+
- [ ] All code changes are implemented
|
|
224
|
+
- [ ] All relevant documentation is updated
|
|
225
|
+
- [ ] Examples are current and correct
|
|
226
|
+
- [ ] Tests are added/updated
|
|
227
|
+
- [ ] README.md is updated if needed
|
|
228
|
+
- [ ] Cross-references are correct
|
|
229
|
+
- [ ] No broken links
|
|
230
|
+
- [ ] Code follows existing patterns
|
|
231
|
+
- [ ] Documentation is clear and complete
|
|
232
|
+
|
|
233
|
+
## Error Prevention
|
|
234
|
+
|
|
235
|
+
### Common Mistakes to Avoid
|
|
236
|
+
|
|
237
|
+
1. **Forgetting to Update Documentation**
|
|
238
|
+
- Always update docs when code changes
|
|
239
|
+
- Don't assume someone else will do it
|
|
240
|
+
|
|
241
|
+
2. **Outdated Examples**
|
|
242
|
+
- Verify examples still work
|
|
243
|
+
- Update examples when API changes
|
|
244
|
+
|
|
245
|
+
3. **Inconsistent Formatting**
|
|
246
|
+
- Follow existing documentation style
|
|
247
|
+
- Use consistent code formatting
|
|
248
|
+
|
|
249
|
+
4. **Missing Error Cases**
|
|
250
|
+
- Document when methods throw errors
|
|
251
|
+
- Show error handling in examples
|
|
252
|
+
|
|
253
|
+
5. **Incomplete Documentation**
|
|
254
|
+
- Document all parameters
|
|
255
|
+
- Document return types
|
|
256
|
+
- Include usage examples
|
|
257
|
+
|
|
258
|
+
## Questions?
|
|
259
|
+
|
|
260
|
+
If you're unsure about:
|
|
261
|
+
- Which documentation file to update
|
|
262
|
+
- How to format documentation
|
|
263
|
+
- Whether a change needs documentation
|
|
264
|
+
|
|
265
|
+
**Default Action:** Update the documentation. It's better to have slightly redundant documentation than missing documentation.
|
|
266
|
+
|
|
267
|
+
## Related Documentation
|
|
268
|
+
|
|
269
|
+
- [README.md](README.md) - Start here for package overview
|
|
270
|
+
- [client.md](client.md) - RedseatClient documentation
|
|
271
|
+
- [server.md](server.md) - ServerApi documentation
|
|
272
|
+
- [libraries.md](libraries.md) - LibraryApi documentation
|
|
273
|
+
- [encryption.md](encryption.md) - Encryption module documentation
|
|
274
|
+
- [test.md](test.md) - Testing guide
|
|
275
|
+
|
package/client.md
ADDED
|
@@ -0,0 +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
|
+
|
package/dist/auth.d.ts
ADDED
package/dist/auth.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
export async function fetchServerToken(serverId, idToken) {
|
|
3
|
+
const headers = {
|
|
4
|
+
headers: {
|
|
5
|
+
Authorization: `Bearer ${idToken}`
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
const req = await axios.get(`/servers/${serverId}/token`, headers);
|
|
9
|
+
return req.data;
|
|
10
|
+
}
|