@inneropen/marvin-sdk 2.0.1 → 3.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 +179 -14
- package/dist/{HttpClient-CLtgQGXH.d.cts → HttpClient-CdF3IHM1.d.cts} +49 -2
- package/dist/{HttpClient-CLtgQGXH.d.ts → HttpClient-CdF3IHM1.d.ts} +49 -2
- package/dist/chunk-R3EZI43S.js +855 -0
- package/dist/chunk-WJC4X7TB.js +738 -0
- package/dist/index-D5zkKa4N.d.cts +3394 -0
- package/dist/index-D5zkKa4N.d.ts +3394 -0
- package/dist/index.cjs +599 -213
- package/dist/index.d.cts +20 -544
- package/dist/index.d.ts +20 -544
- package/dist/index.js +27 -791
- package/dist/marvin-B_gJRxHK.d.cts +611 -0
- package/dist/marvin-C5tRQ2nD.d.ts +611 -0
- package/dist/platform.cjs +512 -69
- package/dist/platform.d.cts +141 -3381
- package/dist/platform.d.ts +141 -3381
- package/dist/platform.js +283 -59
- package/dist/publish.cjs +1355 -0
- package/dist/publish.d.cts +49 -0
- package/dist/publish.d.ts +49 -0
- package/dist/publish.js +75 -0
- package/dist/types/index.d.cts +1 -168
- package/dist/types/index.d.ts +1 -168
- package/package.json +11 -6
- package/dist/chunk-25F3IF6S.js +0 -396
package/README.md
CHANGED
|
@@ -1,7 +1,35 @@
|
|
|
1
1
|
# Marvin TypeScript SDK
|
|
2
2
|
|
|
3
|
+
> 🔒 **Enterprise-Grade Security** | ✅ **Zero Vulnerabilities** | 🚀 **Production-Ready**
|
|
4
|
+
|
|
3
5
|
The official TypeScript SDK for Marvin CMS. A modern, workspace-first SDK for building applications that integrate with Marvin.
|
|
4
6
|
|
|
7
|
+
[](./SECURITY_FIXES_SUMMARY.md)
|
|
8
|
+
[](https://github.com/inneropen/marvin-sdk/releases)
|
|
9
|
+
[](https://www.typescriptlang.org/)
|
|
10
|
+
|
|
11
|
+
## Security First
|
|
12
|
+
|
|
13
|
+
**The Marvin SDK has undergone a comprehensive security audit and achieved zero security vulnerabilities.** All 20 identified issues have been fixed, including:
|
|
14
|
+
|
|
15
|
+
- ✅ 8 HIGH priority vulnerabilities eliminated
|
|
16
|
+
- ✅ 7 MEDIUM priority security issues resolved
|
|
17
|
+
- ✅ 5 LOW priority code quality improvements implemented
|
|
18
|
+
|
|
19
|
+
**[View Complete Security Audit →](./COMPLETE_SECURITY_AUDIT.md)**
|
|
20
|
+
|
|
21
|
+
### Key Security Features
|
|
22
|
+
|
|
23
|
+
- 🔐 **Token Sanitization** - Automatic redaction of sensitive data in logs/errors
|
|
24
|
+
- 🛡️ **Input Validation** - Path injection, XSS, and SSRF prevention
|
|
25
|
+
- 📧 **Email Validation** - RFC 5322 compliant validation
|
|
26
|
+
- 📁 **File Upload Security** - Size, type, and filename validation
|
|
27
|
+
- 🔄 **Network Resilience** - Automatic retry with exponential backoff
|
|
28
|
+
- 🔒 **CSRF Protection** - Session authentication security
|
|
29
|
+
- ✅ **Type Safety** - 100% TypeScript with zero `any` types
|
|
30
|
+
|
|
31
|
+
**[View Security Best Practices →](./AUTHENTICATION.md#security-best-practices)**
|
|
32
|
+
|
|
5
33
|
## Why This SDK?
|
|
6
34
|
|
|
7
35
|
Marvin is becoming a platform, not simply a CMS. This SDK is the primary way to integrate with Marvin across:
|
|
@@ -19,42 +47,64 @@ The SDK provides:
|
|
|
19
47
|
- 📘 **Fully Typed** - Complete TypeScript support
|
|
20
48
|
- 🔄 **Backwards Compatible** - Works with existing publishing APIs
|
|
21
49
|
- 🎨 **Object-Oriented** - Rich objects instead of raw JSON
|
|
22
|
-
- 🔒 **
|
|
50
|
+
- 🔒 **Enterprise Security** - Production-ready with comprehensive security features
|
|
23
51
|
|
|
24
52
|
## Installation
|
|
25
53
|
|
|
26
54
|
```bash
|
|
27
|
-
|
|
28
|
-
cp -r /path/to/marvin/packages/marvin-sdk src/lib/marvin
|
|
55
|
+
npm install @inneropen/marvin-sdk@^2.0.1
|
|
29
56
|
```
|
|
30
57
|
|
|
31
|
-
|
|
58
|
+
**Latest stable version:** v2.0.1 with complete security fixes and enterprise-grade quality.
|
|
32
59
|
|
|
33
|
-
|
|
34
|
-
|
|
60
|
+
## Entry Points
|
|
61
|
+
|
|
62
|
+
The SDK provides three distinct entry points for different use cases:
|
|
63
|
+
|
|
64
|
+
### 📖 Publishing API (`/publish`)
|
|
65
|
+
Read-only access to published content (frontends, websites)
|
|
66
|
+
```typescript
|
|
67
|
+
import { createMarvinClient } from '@inneropen/marvin-sdk/publish';
|
|
68
|
+
```
|
|
69
|
+
**Auth:** Site client tokens (`MARVIN_SITE_CLIENT_TOKEN`)
|
|
70
|
+
|
|
71
|
+
### ⚙️ Platform API (`/platform`)
|
|
72
|
+
Full CRUD admin operations (backend, CLI, automation)
|
|
73
|
+
```typescript
|
|
74
|
+
import { createPlatformClient } from '@inneropen/marvin-sdk/platform';
|
|
75
|
+
```
|
|
76
|
+
**Auth:** User tokens (`MARVIN_USER_TOKEN`) or session cookies
|
|
77
|
+
|
|
78
|
+
### 🔐 Auth API (Default export)
|
|
79
|
+
Public registration, login, password reset
|
|
80
|
+
```typescript
|
|
81
|
+
import { createAuthClient } from '@inneropen/marvin-sdk';
|
|
35
82
|
```
|
|
83
|
+
**Auth:** None required (public endpoints)
|
|
84
|
+
|
|
85
|
+
📚 **[See complete authentication guide →](./AUTHENTICATION.md)**
|
|
36
86
|
|
|
37
|
-
## Quick Start
|
|
87
|
+
## Quick Start - Publishing API
|
|
38
88
|
|
|
39
89
|
### 1. Configure Environment
|
|
40
90
|
|
|
41
91
|
```env
|
|
42
92
|
MARVIN_API_URL=https://marvin.example.com
|
|
43
|
-
MARVIN_SITE_CLIENT_TOKEN=your-token
|
|
93
|
+
MARVIN_SITE_CLIENT_TOKEN=your-site-client-token
|
|
44
94
|
MARVIN_WORKSPACE_SLUG=your-workspace
|
|
45
95
|
```
|
|
46
96
|
|
|
47
97
|
### 2. Create Client
|
|
48
98
|
|
|
49
|
-
```
|
|
50
|
-
import { createMarvinClient } from '
|
|
99
|
+
```typescript
|
|
100
|
+
import { createMarvinClient } from '@inneropen/marvin-sdk/publish';
|
|
51
101
|
|
|
52
102
|
const marvin = createMarvinClient();
|
|
53
103
|
```
|
|
54
104
|
|
|
55
105
|
### 3. Fetch Content
|
|
56
106
|
|
|
57
|
-
```
|
|
107
|
+
```typescript
|
|
58
108
|
// Get workspace
|
|
59
109
|
const workspace = await marvin.getWorkspace();
|
|
60
110
|
console.log(workspace.site?.title);
|
|
@@ -71,6 +121,35 @@ const projects = await marvin.collection('projects');
|
|
|
71
121
|
const projectEntries = await projects.entries();
|
|
72
122
|
```
|
|
73
123
|
|
|
124
|
+
## Quick Start - Platform API
|
|
125
|
+
|
|
126
|
+
### Programmatic Admin Access
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { createPlatformClient } from '@inneropen/marvin-sdk/platform';
|
|
130
|
+
|
|
131
|
+
// From environment (MARVIN_USER_TOKEN)
|
|
132
|
+
const platform = createPlatformClient();
|
|
133
|
+
|
|
134
|
+
// Or explicit token
|
|
135
|
+
const platform = createPlatformClient({
|
|
136
|
+
userToken: 'your-user-token'
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Full CRUD operations
|
|
140
|
+
await platform.entries.create({
|
|
141
|
+
title: 'New Post',
|
|
142
|
+
content: 'Content here...',
|
|
143
|
+
collection_id: collectionId
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
await platform.entries.update(entryId, {
|
|
147
|
+
title: 'Updated Title'
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
await platform.entries.delete(entryId);
|
|
151
|
+
```
|
|
152
|
+
|
|
74
153
|
## Architecture
|
|
75
154
|
|
|
76
155
|
### Workspace-First Design
|
|
@@ -81,10 +160,11 @@ Everything starts with the **Workspace**:
|
|
|
81
160
|
const workspace = await marvin.getWorkspace();
|
|
82
161
|
|
|
83
162
|
// Access workspace modules
|
|
84
|
-
workspace.entries
|
|
163
|
+
workspace.entries // Entries module
|
|
85
164
|
workspace.collections // Collections module
|
|
86
|
-
workspace.assets
|
|
87
|
-
workspace.
|
|
165
|
+
workspace.assets // Assets module
|
|
166
|
+
workspace.renderers // Renderers module (entry type rendering metadata)
|
|
167
|
+
workspace.site // Site configuration (cached)
|
|
88
168
|
```
|
|
89
169
|
|
|
90
170
|
### Modular Structure
|
|
@@ -98,6 +178,7 @@ The SDK is organized into focused modules:
|
|
|
98
178
|
├── entries/ → Entries module
|
|
99
179
|
├── collections/ → Collections module
|
|
100
180
|
├── assets/ → Assets module
|
|
181
|
+
├── renderers/ → Renderers module (entry type rendering metadata)
|
|
101
182
|
├── auth/ → Authentication (future)
|
|
102
183
|
├── types/ → TypeScript types
|
|
103
184
|
└── utils/ → Cache & utilities
|
|
@@ -607,6 +688,43 @@ Methods:
|
|
|
607
688
|
- `resource.entries()` - Get entries that reference this resource
|
|
608
689
|
- `resource.toJSON()` - Get raw resource data
|
|
609
690
|
|
|
691
|
+
### Renderers Module
|
|
692
|
+
|
|
693
|
+
#### `renderers.list()`
|
|
694
|
+
|
|
695
|
+
Get all entry types with their rendering and capability metadata.
|
|
696
|
+
|
|
697
|
+
**Returns:** `PublishedEntryType[]`
|
|
698
|
+
|
|
699
|
+
```ts
|
|
700
|
+
interface PublishedEntryType {
|
|
701
|
+
slug: string;
|
|
702
|
+
name: string;
|
|
703
|
+
isRendered: boolean;
|
|
704
|
+
rendering?: {
|
|
705
|
+
renderer?: string;
|
|
706
|
+
package?: string;
|
|
707
|
+
version?: string;
|
|
708
|
+
config?: Record<string, unknown>;
|
|
709
|
+
};
|
|
710
|
+
capabilities?: {
|
|
711
|
+
publishable?: boolean;
|
|
712
|
+
submittable?: boolean;
|
|
713
|
+
routable?: boolean;
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
**Example:**
|
|
719
|
+
|
|
720
|
+
```ts
|
|
721
|
+
const workspace = await marvin.getWorkspace();
|
|
722
|
+
const renderers = await workspace.renderers.list();
|
|
723
|
+
|
|
724
|
+
const rendered = renderers.filter(r => r.isRendered);
|
|
725
|
+
console.log(`${rendered.length} entry types have renderers`);
|
|
726
|
+
```
|
|
727
|
+
|
|
610
728
|
## Backend API Endpoints
|
|
611
729
|
|
|
612
730
|
The SDK uses these Marvin publishing API endpoints:
|
|
@@ -625,6 +743,7 @@ The SDK uses these Marvin publishing API endpoints:
|
|
|
625
743
|
| `/api/publish/{workspace}/resources` | GET | List resources | ✅ Implemented |
|
|
626
744
|
| `/api/publish/{workspace}/resources/{slug}` | GET | Get resource | ✅ Implemented |
|
|
627
745
|
| `/api/publish/{workspace}/resources/{slug}/entries` | GET | Resource entries | ✅ Implemented |
|
|
746
|
+
| `/api/publish/{workspace}/entry-types` | GET | List entry types (renderers) | ✅ Implemented |
|
|
628
747
|
|
|
629
748
|
**Query Parameters:**
|
|
630
749
|
|
|
@@ -634,6 +753,31 @@ The SDK uses these Marvin publishing API endpoints:
|
|
|
634
753
|
|
|
635
754
|
## Security
|
|
636
755
|
|
|
756
|
+
### Security Features
|
|
757
|
+
|
|
758
|
+
The SDK includes comprehensive security protections:
|
|
759
|
+
|
|
760
|
+
#### Input Validation
|
|
761
|
+
- **Path Injection Prevention** - Validates all path parameters to prevent `../` attacks
|
|
762
|
+
- **Email Validation** - RFC 5322 compliant email format checking
|
|
763
|
+
- **Webhook URL Validation** - SSRF prevention for webhook endpoints
|
|
764
|
+
- **File Upload Validation** - Size limits (10MB), type checking, and filename sanitization
|
|
765
|
+
- **Form Submission Validation** - XSS prevention with script tag detection
|
|
766
|
+
|
|
767
|
+
#### Data Protection
|
|
768
|
+
- **Token Sanitization** - Automatic redaction of sensitive data in debug logs and errors
|
|
769
|
+
- Tokens, passwords, secrets, API keys automatically masked
|
|
770
|
+
- Recursive sanitization for nested objects and arrays
|
|
771
|
+
- **Email Password Security** - Passwords never returned in API responses
|
|
772
|
+
- **CSRF Protection** - Session authentication with CSRF token support
|
|
773
|
+
|
|
774
|
+
#### Network Security
|
|
775
|
+
- **Retry Logic** - Automatic exponential backoff for transient failures (3 retries, configurable)
|
|
776
|
+
- **Timeout Limits** - Maximum 2-minute timeout to prevent resource exhaustion
|
|
777
|
+
- **Error Handling** - Comprehensive error types with actionable messages
|
|
778
|
+
|
|
779
|
+
**[Complete Security Documentation →](./SECURITY_FIXES_SUMMARY.md)**
|
|
780
|
+
|
|
637
781
|
### Site Client Tokens
|
|
638
782
|
|
|
639
783
|
Always use **site client tokens**, never user tokens.
|
|
@@ -660,6 +804,17 @@ const marvin = createMarvinClient();
|
|
|
660
804
|
</script>
|
|
661
805
|
```
|
|
662
806
|
|
|
807
|
+
### Security Best Practices
|
|
808
|
+
|
|
809
|
+
1. **Environment Variables** - Never commit tokens to version control
|
|
810
|
+
2. **Token Rotation** - Regenerate user tokens periodically
|
|
811
|
+
3. **Debug Mode** - Tokens are automatically sanitized in logs, but still use caution
|
|
812
|
+
4. **Input Validation** - The SDK validates all inputs, but validate on your side too
|
|
813
|
+
5. **HTTPS Only** - Always use HTTPS in production (enforced by default)
|
|
814
|
+
6. **CSRF Tokens** - Enable CSRF protection for browser-based admin UIs
|
|
815
|
+
|
|
816
|
+
**[Complete Authentication Guide →](./AUTHENTICATION.md)**
|
|
817
|
+
|
|
663
818
|
## Future Modules
|
|
664
819
|
|
|
665
820
|
The SDK architecture supports future expansion:
|
|
@@ -714,8 +869,18 @@ Make sure your `tsconfig.json` includes:
|
|
|
714
869
|
|
|
715
870
|
MIT - Part of the Marvin project.
|
|
716
871
|
|
|
872
|
+
## Documentation
|
|
873
|
+
|
|
874
|
+
- 🔒 [Security Audit Report](./COMPLETE_SECURITY_AUDIT.md) - Complete security fixes (20 issues resolved)
|
|
875
|
+
- 📋 [Security Fixes Summary](./SECURITY_FIXES_SUMMARY.md) - Key improvements and migration guide
|
|
876
|
+
- 🔐 [Authentication Guide](./AUTHENTICATION.md) - Complete auth documentation and security best practices
|
|
877
|
+
- ⚠️ [Error Handling Guide](./ERROR_HANDLING_GUIDE.md) - Comprehensive error handling patterns
|
|
878
|
+
- 🧪 [Testing Guide](./TESTING.md) - Testing strategy and security test examples
|
|
879
|
+
- 🔄 [Migration Guide v2.0](./MIGRATION-v2.md) - Upgrade from v1.x to v2.0
|
|
880
|
+
|
|
717
881
|
## Support
|
|
718
882
|
|
|
719
883
|
- 📖 [Full Documentation](./examples.md)
|
|
720
884
|
- 🚀 [Quick Start Guide](./QUICKSTART.md)
|
|
721
885
|
- 🐛 [Report Issues](https://github.com/jmashburn/Marvin/issues)
|
|
886
|
+
- 🔒 [Security Policy](./SECURITY.md) - Vulnerability reporting and security policy
|
|
@@ -33,11 +33,22 @@ declare class BearerTokenAuth implements AuthStrategy {
|
|
|
33
33
|
/**
|
|
34
34
|
* Session-based authentication (Platform/Admin APIs in browser)
|
|
35
35
|
* Relies on HTTP-only cookies set by the server
|
|
36
|
+
* Optionally supports CSRF token protection
|
|
36
37
|
*/
|
|
37
38
|
declare class SessionAuth implements AuthStrategy {
|
|
38
39
|
private sessionToken?;
|
|
39
40
|
private onUnauthorized?;
|
|
41
|
+
private csrfToken?;
|
|
40
42
|
constructor(sessionToken?: string | undefined, onUnauthorized?: (() => Promise<void>) | undefined);
|
|
43
|
+
/**
|
|
44
|
+
* Set CSRF token for cross-site request forgery protection
|
|
45
|
+
* The token should be obtained from the server after login
|
|
46
|
+
*/
|
|
47
|
+
setCsrfToken(token: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* Get current CSRF token
|
|
50
|
+
*/
|
|
51
|
+
getCsrfToken(): string | undefined;
|
|
41
52
|
injectAuth(headers: Headers): void;
|
|
42
53
|
handleUnauthorized(): Promise<void>;
|
|
43
54
|
getDescription(): string;
|
|
@@ -54,12 +65,29 @@ declare class NoAuth implements AuthStrategy {
|
|
|
54
65
|
* Base HTTP client for Marvin APIs
|
|
55
66
|
*/
|
|
56
67
|
|
|
68
|
+
interface RetryConfig {
|
|
69
|
+
/** Maximum number of retry attempts (default: 3) */
|
|
70
|
+
maxRetries: number;
|
|
71
|
+
/** Initial delay in ms before first retry (default: 1000) */
|
|
72
|
+
initialDelay: number;
|
|
73
|
+
/** Maximum delay in ms between retries (default: 10000) */
|
|
74
|
+
maxDelay: number;
|
|
75
|
+
/** HTTP status codes that should trigger a retry (default: [408, 429, 500, 502, 503, 504]) */
|
|
76
|
+
retryableStatuses: number[];
|
|
77
|
+
}
|
|
57
78
|
interface HttpClientConfig {
|
|
58
79
|
baseUrl: string;
|
|
59
80
|
auth: AuthStrategy;
|
|
60
81
|
defaultHeaders?: Record<string, string>;
|
|
61
82
|
credentials?: RequestCredentials;
|
|
62
83
|
timeout?: number;
|
|
84
|
+
debug?: boolean;
|
|
85
|
+
retry?: Partial<RetryConfig>;
|
|
86
|
+
logger?: {
|
|
87
|
+
log: (message: string, ...args: unknown[]) => void;
|
|
88
|
+
warn: (message: string, ...args: unknown[]) => void;
|
|
89
|
+
error: (message: string, ...args: unknown[]) => void;
|
|
90
|
+
};
|
|
63
91
|
}
|
|
64
92
|
declare class HttpClient {
|
|
65
93
|
private baseUrl;
|
|
@@ -67,7 +95,14 @@ declare class HttpClient {
|
|
|
67
95
|
private defaultHeaders;
|
|
68
96
|
private credentials;
|
|
69
97
|
private timeout;
|
|
98
|
+
private debug;
|
|
99
|
+
private retryConfig;
|
|
100
|
+
private logger;
|
|
70
101
|
constructor(config: HttpClientConfig);
|
|
102
|
+
/**
|
|
103
|
+
* Validate path parameter to prevent path traversal attacks
|
|
104
|
+
*/
|
|
105
|
+
validatePathParam(param: string | number, paramName?: string): string;
|
|
71
106
|
/**
|
|
72
107
|
* Build full URL from endpoint
|
|
73
108
|
*/
|
|
@@ -81,13 +116,25 @@ declare class HttpClient {
|
|
|
81
116
|
*/
|
|
82
117
|
buildQueryString(params: Record<string, string | number | boolean | undefined>): string;
|
|
83
118
|
/**
|
|
84
|
-
*
|
|
119
|
+
* Sanitize data for logging by redacting sensitive fields
|
|
120
|
+
*/
|
|
121
|
+
private sanitizeForLogging;
|
|
122
|
+
/**
|
|
123
|
+
* Calculate delay for retry with exponential backoff
|
|
124
|
+
*/
|
|
125
|
+
private calculateRetryDelay;
|
|
126
|
+
/**
|
|
127
|
+
* Sleep for specified milliseconds
|
|
128
|
+
*/
|
|
129
|
+
private sleep;
|
|
130
|
+
/**
|
|
131
|
+
* Perform HTTP request with automatic retry on transient failures
|
|
85
132
|
*/
|
|
86
133
|
request<T>(method: string, endpoint: string, options?: {
|
|
87
134
|
body?: unknown;
|
|
88
135
|
headers?: Record<string, string>;
|
|
89
136
|
params?: Record<string, string | number | boolean | undefined>;
|
|
90
|
-
}): Promise<T>;
|
|
137
|
+
}, retryAttempt?: number): Promise<T>;
|
|
91
138
|
/**
|
|
92
139
|
* GET request
|
|
93
140
|
*/
|
|
@@ -33,11 +33,22 @@ declare class BearerTokenAuth implements AuthStrategy {
|
|
|
33
33
|
/**
|
|
34
34
|
* Session-based authentication (Platform/Admin APIs in browser)
|
|
35
35
|
* Relies on HTTP-only cookies set by the server
|
|
36
|
+
* Optionally supports CSRF token protection
|
|
36
37
|
*/
|
|
37
38
|
declare class SessionAuth implements AuthStrategy {
|
|
38
39
|
private sessionToken?;
|
|
39
40
|
private onUnauthorized?;
|
|
41
|
+
private csrfToken?;
|
|
40
42
|
constructor(sessionToken?: string | undefined, onUnauthorized?: (() => Promise<void>) | undefined);
|
|
43
|
+
/**
|
|
44
|
+
* Set CSRF token for cross-site request forgery protection
|
|
45
|
+
* The token should be obtained from the server after login
|
|
46
|
+
*/
|
|
47
|
+
setCsrfToken(token: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* Get current CSRF token
|
|
50
|
+
*/
|
|
51
|
+
getCsrfToken(): string | undefined;
|
|
41
52
|
injectAuth(headers: Headers): void;
|
|
42
53
|
handleUnauthorized(): Promise<void>;
|
|
43
54
|
getDescription(): string;
|
|
@@ -54,12 +65,29 @@ declare class NoAuth implements AuthStrategy {
|
|
|
54
65
|
* Base HTTP client for Marvin APIs
|
|
55
66
|
*/
|
|
56
67
|
|
|
68
|
+
interface RetryConfig {
|
|
69
|
+
/** Maximum number of retry attempts (default: 3) */
|
|
70
|
+
maxRetries: number;
|
|
71
|
+
/** Initial delay in ms before first retry (default: 1000) */
|
|
72
|
+
initialDelay: number;
|
|
73
|
+
/** Maximum delay in ms between retries (default: 10000) */
|
|
74
|
+
maxDelay: number;
|
|
75
|
+
/** HTTP status codes that should trigger a retry (default: [408, 429, 500, 502, 503, 504]) */
|
|
76
|
+
retryableStatuses: number[];
|
|
77
|
+
}
|
|
57
78
|
interface HttpClientConfig {
|
|
58
79
|
baseUrl: string;
|
|
59
80
|
auth: AuthStrategy;
|
|
60
81
|
defaultHeaders?: Record<string, string>;
|
|
61
82
|
credentials?: RequestCredentials;
|
|
62
83
|
timeout?: number;
|
|
84
|
+
debug?: boolean;
|
|
85
|
+
retry?: Partial<RetryConfig>;
|
|
86
|
+
logger?: {
|
|
87
|
+
log: (message: string, ...args: unknown[]) => void;
|
|
88
|
+
warn: (message: string, ...args: unknown[]) => void;
|
|
89
|
+
error: (message: string, ...args: unknown[]) => void;
|
|
90
|
+
};
|
|
63
91
|
}
|
|
64
92
|
declare class HttpClient {
|
|
65
93
|
private baseUrl;
|
|
@@ -67,7 +95,14 @@ declare class HttpClient {
|
|
|
67
95
|
private defaultHeaders;
|
|
68
96
|
private credentials;
|
|
69
97
|
private timeout;
|
|
98
|
+
private debug;
|
|
99
|
+
private retryConfig;
|
|
100
|
+
private logger;
|
|
70
101
|
constructor(config: HttpClientConfig);
|
|
102
|
+
/**
|
|
103
|
+
* Validate path parameter to prevent path traversal attacks
|
|
104
|
+
*/
|
|
105
|
+
validatePathParam(param: string | number, paramName?: string): string;
|
|
71
106
|
/**
|
|
72
107
|
* Build full URL from endpoint
|
|
73
108
|
*/
|
|
@@ -81,13 +116,25 @@ declare class HttpClient {
|
|
|
81
116
|
*/
|
|
82
117
|
buildQueryString(params: Record<string, string | number | boolean | undefined>): string;
|
|
83
118
|
/**
|
|
84
|
-
*
|
|
119
|
+
* Sanitize data for logging by redacting sensitive fields
|
|
120
|
+
*/
|
|
121
|
+
private sanitizeForLogging;
|
|
122
|
+
/**
|
|
123
|
+
* Calculate delay for retry with exponential backoff
|
|
124
|
+
*/
|
|
125
|
+
private calculateRetryDelay;
|
|
126
|
+
/**
|
|
127
|
+
* Sleep for specified milliseconds
|
|
128
|
+
*/
|
|
129
|
+
private sleep;
|
|
130
|
+
/**
|
|
131
|
+
* Perform HTTP request with automatic retry on transient failures
|
|
85
132
|
*/
|
|
86
133
|
request<T>(method: string, endpoint: string, options?: {
|
|
87
134
|
body?: unknown;
|
|
88
135
|
headers?: Record<string, string>;
|
|
89
136
|
params?: Record<string, string | number | boolean | undefined>;
|
|
90
|
-
}): Promise<T>;
|
|
137
|
+
}, retryAttempt?: number): Promise<T>;
|
|
91
138
|
/**
|
|
92
139
|
* GET request
|
|
93
140
|
*/
|