@inneropen/marvin-sdk 2.0.0-next.13 → 2.0.0-next.15
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 +59 -10
- package/dist/{HttpClient-BX5Gqd0w.d.cts → HttpClient-CdF3IHM1.d.cts} +41 -2
- package/dist/{HttpClient-BX5Gqd0w.d.ts → HttpClient-CdF3IHM1.d.ts} +41 -2
- package/dist/chunk-GJNOYXUQ.js +980 -0
- package/dist/{chunk-DYC2BEA4.js → chunk-WJC4X7TB.js} +274 -9
- package/dist/index.cjs +356 -12
- package/dist/index.d.cts +20 -610
- package/dist/index.d.ts +20 -610
- package/dist/index.js +21 -880
- package/dist/marvin-Bx5k6tsF.d.cts +654 -0
- package/dist/marvin-g7dayc83.d.ts +654 -0
- package/dist/platform.cjs +396 -43
- package/dist/platform.d.cts +124 -15
- package/dist/platform.d.ts +124 -15
- package/dist/platform.js +251 -37
- package/dist/publish.cjs +1487 -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 +9 -1
- package/dist/types/index.d.ts +9 -1
- package/package.json +11 -6
package/README.md
CHANGED
|
@@ -24,37 +24,57 @@ The SDK provides:
|
|
|
24
24
|
## Installation
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
|
|
28
|
-
cp -r /path/to/marvin/packages/marvin-sdk src/lib/marvin
|
|
27
|
+
npm install @inneropen/marvin-sdk
|
|
29
28
|
```
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
## Entry Points
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
The SDK provides three distinct entry points for different use cases:
|
|
33
|
+
|
|
34
|
+
### 📖 Publishing API (`/publish`)
|
|
35
|
+
Read-only access to published content (frontends, websites)
|
|
36
|
+
```typescript
|
|
37
|
+
import { createMarvinClient } from '@inneropen/marvin-sdk/publish';
|
|
38
|
+
```
|
|
39
|
+
**Auth:** Site client tokens (`MARVIN_SITE_CLIENT_TOKEN`)
|
|
40
|
+
|
|
41
|
+
### ⚙️ Platform API (`/platform`)
|
|
42
|
+
Full CRUD admin operations (backend, CLI, automation)
|
|
43
|
+
```typescript
|
|
44
|
+
import { createPlatformClient } from '@inneropen/marvin-sdk/platform';
|
|
45
|
+
```
|
|
46
|
+
**Auth:** User tokens (`MARVIN_USER_TOKEN`) or session cookies
|
|
47
|
+
|
|
48
|
+
### 🔐 Auth API (Default export)
|
|
49
|
+
Public registration, login, password reset
|
|
50
|
+
```typescript
|
|
51
|
+
import { createAuthClient } from '@inneropen/marvin-sdk';
|
|
35
52
|
```
|
|
53
|
+
**Auth:** None required (public endpoints)
|
|
36
54
|
|
|
37
|
-
|
|
55
|
+
📚 **[See complete authentication guide →](./AUTHENTICATION.md)**
|
|
56
|
+
|
|
57
|
+
## Quick Start - Publishing API
|
|
38
58
|
|
|
39
59
|
### 1. Configure Environment
|
|
40
60
|
|
|
41
61
|
```env
|
|
42
62
|
MARVIN_API_URL=https://marvin.example.com
|
|
43
|
-
MARVIN_SITE_CLIENT_TOKEN=your-token
|
|
63
|
+
MARVIN_SITE_CLIENT_TOKEN=your-site-client-token
|
|
44
64
|
MARVIN_WORKSPACE_SLUG=your-workspace
|
|
45
65
|
```
|
|
46
66
|
|
|
47
67
|
### 2. Create Client
|
|
48
68
|
|
|
49
|
-
```
|
|
50
|
-
import { createMarvinClient } from '
|
|
69
|
+
```typescript
|
|
70
|
+
import { createMarvinClient } from '@inneropen/marvin-sdk/publish';
|
|
51
71
|
|
|
52
72
|
const marvin = createMarvinClient();
|
|
53
73
|
```
|
|
54
74
|
|
|
55
75
|
### 3. Fetch Content
|
|
56
76
|
|
|
57
|
-
```
|
|
77
|
+
```typescript
|
|
58
78
|
// Get workspace
|
|
59
79
|
const workspace = await marvin.getWorkspace();
|
|
60
80
|
console.log(workspace.site?.title);
|
|
@@ -71,6 +91,35 @@ const projects = await marvin.collection('projects');
|
|
|
71
91
|
const projectEntries = await projects.entries();
|
|
72
92
|
```
|
|
73
93
|
|
|
94
|
+
## Quick Start - Platform API
|
|
95
|
+
|
|
96
|
+
### Programmatic Admin Access
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { createPlatformClient } from '@inneropen/marvin-sdk/platform';
|
|
100
|
+
|
|
101
|
+
// From environment (MARVIN_USER_TOKEN)
|
|
102
|
+
const platform = createPlatformClient();
|
|
103
|
+
|
|
104
|
+
// Or explicit token
|
|
105
|
+
const platform = createPlatformClient({
|
|
106
|
+
userToken: 'your-user-token'
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Full CRUD operations
|
|
110
|
+
await platform.entries.create({
|
|
111
|
+
title: 'New Post',
|
|
112
|
+
content: 'Content here...',
|
|
113
|
+
collection_id: collectionId
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
await platform.entries.update(entryId, {
|
|
117
|
+
title: 'Updated Title'
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
await platform.entries.delete(entryId);
|
|
121
|
+
```
|
|
122
|
+
|
|
74
123
|
## Architecture
|
|
75
124
|
|
|
76
125
|
### Workspace-First Design
|
|
@@ -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,6 +65,16 @@ 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;
|
|
@@ -61,6 +82,7 @@ interface HttpClientConfig {
|
|
|
61
82
|
credentials?: RequestCredentials;
|
|
62
83
|
timeout?: number;
|
|
63
84
|
debug?: boolean;
|
|
85
|
+
retry?: Partial<RetryConfig>;
|
|
64
86
|
logger?: {
|
|
65
87
|
log: (message: string, ...args: unknown[]) => void;
|
|
66
88
|
warn: (message: string, ...args: unknown[]) => void;
|
|
@@ -74,8 +96,13 @@ declare class HttpClient {
|
|
|
74
96
|
private credentials;
|
|
75
97
|
private timeout;
|
|
76
98
|
private debug;
|
|
99
|
+
private retryConfig;
|
|
77
100
|
private logger;
|
|
78
101
|
constructor(config: HttpClientConfig);
|
|
102
|
+
/**
|
|
103
|
+
* Validate path parameter to prevent path traversal attacks
|
|
104
|
+
*/
|
|
105
|
+
validatePathParam(param: string | number, paramName?: string): string;
|
|
79
106
|
/**
|
|
80
107
|
* Build full URL from endpoint
|
|
81
108
|
*/
|
|
@@ -89,13 +116,25 @@ declare class HttpClient {
|
|
|
89
116
|
*/
|
|
90
117
|
buildQueryString(params: Record<string, string | number | boolean | undefined>): string;
|
|
91
118
|
/**
|
|
92
|
-
*
|
|
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
|
|
93
132
|
*/
|
|
94
133
|
request<T>(method: string, endpoint: string, options?: {
|
|
95
134
|
body?: unknown;
|
|
96
135
|
headers?: Record<string, string>;
|
|
97
136
|
params?: Record<string, string | number | boolean | undefined>;
|
|
98
|
-
}): Promise<T>;
|
|
137
|
+
}, retryAttempt?: number): Promise<T>;
|
|
99
138
|
/**
|
|
100
139
|
* GET request
|
|
101
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,6 +65,16 @@ 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;
|
|
@@ -61,6 +82,7 @@ interface HttpClientConfig {
|
|
|
61
82
|
credentials?: RequestCredentials;
|
|
62
83
|
timeout?: number;
|
|
63
84
|
debug?: boolean;
|
|
85
|
+
retry?: Partial<RetryConfig>;
|
|
64
86
|
logger?: {
|
|
65
87
|
log: (message: string, ...args: unknown[]) => void;
|
|
66
88
|
warn: (message: string, ...args: unknown[]) => void;
|
|
@@ -74,8 +96,13 @@ declare class HttpClient {
|
|
|
74
96
|
private credentials;
|
|
75
97
|
private timeout;
|
|
76
98
|
private debug;
|
|
99
|
+
private retryConfig;
|
|
77
100
|
private logger;
|
|
78
101
|
constructor(config: HttpClientConfig);
|
|
102
|
+
/**
|
|
103
|
+
* Validate path parameter to prevent path traversal attacks
|
|
104
|
+
*/
|
|
105
|
+
validatePathParam(param: string | number, paramName?: string): string;
|
|
79
106
|
/**
|
|
80
107
|
* Build full URL from endpoint
|
|
81
108
|
*/
|
|
@@ -89,13 +116,25 @@ declare class HttpClient {
|
|
|
89
116
|
*/
|
|
90
117
|
buildQueryString(params: Record<string, string | number | boolean | undefined>): string;
|
|
91
118
|
/**
|
|
92
|
-
*
|
|
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
|
|
93
132
|
*/
|
|
94
133
|
request<T>(method: string, endpoint: string, options?: {
|
|
95
134
|
body?: unknown;
|
|
96
135
|
headers?: Record<string, string>;
|
|
97
136
|
params?: Record<string, string | number | boolean | undefined>;
|
|
98
|
-
}): Promise<T>;
|
|
137
|
+
}, retryAttempt?: number): Promise<T>;
|
|
99
138
|
/**
|
|
100
139
|
* GET request
|
|
101
140
|
*/
|