proofio-sdk 1.0.0
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 +319 -0
- package/dist/cjs/client/api-client.js +284 -0
- package/dist/cjs/index.js +74 -0
- package/dist/cjs/resources/competitors.js +45 -0
- package/dist/cjs/resources/insights.js +101 -0
- package/dist/cjs/resources/reviews.js +69 -0
- package/dist/cjs/resources/widget.js +58 -0
- package/dist/cjs/types/index.js +7 -0
- package/dist/cjs/utils/errors.js +50 -0
- package/dist/client/api-client.d.ts +68 -0
- package/dist/client/api-client.d.ts.map +1 -0
- package/dist/esm/client/api-client.js +280 -0
- package/dist/esm/index.js +68 -0
- package/dist/esm/resources/competitors.js +41 -0
- package/dist/esm/resources/insights.js +97 -0
- package/dist/esm/resources/reviews.js +65 -0
- package/dist/esm/resources/widget.js +54 -0
- package/dist/esm/types/index.js +6 -0
- package/dist/esm/utils/errors.js +46 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/resources/competitors.d.ts +33 -0
- package/dist/resources/competitors.d.ts.map +1 -0
- package/dist/resources/insights.d.ts +46 -0
- package/dist/resources/insights.d.ts.map +1 -0
- package/dist/resources/reviews.d.ts +29 -0
- package/dist/resources/reviews.d.ts.map +1 -0
- package/dist/resources/widget.d.ts +44 -0
- package/dist/resources/widget.d.ts.map +1 -0
- package/dist/types/index.d.ts +217 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/utils/errors.d.ts +32 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# Proofio SDK
|
|
2
|
+
|
|
3
|
+
Official JavaScript/TypeScript SDK for the Proofio API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install proofio-sdk
|
|
9
|
+
# or
|
|
10
|
+
yarn add proofio-sdk
|
|
11
|
+
# or
|
|
12
|
+
pnpm add proofio-sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { Proofio } from 'proofio-sdk';
|
|
19
|
+
|
|
20
|
+
const proofio = new Proofio({ apiKey: 'your-api-key' });
|
|
21
|
+
|
|
22
|
+
// List reviews
|
|
23
|
+
const reviews = await proofio.reviews.list();
|
|
24
|
+
|
|
25
|
+
// Get insights summary
|
|
26
|
+
const summary = await proofio.insights.summary();
|
|
27
|
+
|
|
28
|
+
// Get trends
|
|
29
|
+
const trends = await proofio.insights.trends();
|
|
30
|
+
|
|
31
|
+
// Get widget data
|
|
32
|
+
const widget = await proofio.widget.get();
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Authentication
|
|
36
|
+
|
|
37
|
+
The SDK uses API key authentication. Get your API key from the Proofio dashboard.
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
const proofio = new Proofio({
|
|
41
|
+
apiKey: 'your-api-key-here',
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Usage Examples
|
|
46
|
+
|
|
47
|
+
### Reviews
|
|
48
|
+
|
|
49
|
+
#### List Reviews
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// Get all reviews (default: 10)
|
|
53
|
+
const reviews = await proofio.reviews.list();
|
|
54
|
+
|
|
55
|
+
// With filters and pagination
|
|
56
|
+
const filteredReviews = await proofio.reviews.list({
|
|
57
|
+
limit: 50,
|
|
58
|
+
offset: 0,
|
|
59
|
+
minRating: 4,
|
|
60
|
+
sentiment: 'positive',
|
|
61
|
+
language: 'de',
|
|
62
|
+
sourceId: 'source-id-here',
|
|
63
|
+
since: '2024-01-01T00:00:00Z',
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
#### Get Single Review
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
const review = await proofio.reviews.get('review-id-here');
|
|
71
|
+
if (review) {
|
|
72
|
+
console.log(review.text);
|
|
73
|
+
console.log(review.rating);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Insights
|
|
78
|
+
|
|
79
|
+
#### Get Summary
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
const summary = await proofio.insights.summary();
|
|
83
|
+
|
|
84
|
+
console.log(`Total Reviews: ${summary.totalReviews}`);
|
|
85
|
+
console.log(`Average Rating: ${summary.averageRating}`);
|
|
86
|
+
console.log(`Rating Distribution:`, summary.ratingDistribution);
|
|
87
|
+
console.log(`Sentiment:`, summary.sentimentDistribution);
|
|
88
|
+
|
|
89
|
+
// AI Summary (if available for paid plans)
|
|
90
|
+
if (summary.aiSummary) {
|
|
91
|
+
console.log(`AI Summary: ${summary.aiSummary.summary}`);
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Get Trends
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
const trends = await proofio.insights.trends();
|
|
99
|
+
|
|
100
|
+
console.log(`Trend over time:`, trends.trendOverTime);
|
|
101
|
+
console.log(`Top topics:`, trends.topTopics);
|
|
102
|
+
console.log(`Key takeaways:`, trends.keyTakeaways);
|
|
103
|
+
console.log(`Recent changes:`, trends.recentChanges);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Widget
|
|
107
|
+
|
|
108
|
+
#### Get Widget Data
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
const widget = await proofio.widget.get();
|
|
112
|
+
|
|
113
|
+
console.log(`Stats:`, widget.stats);
|
|
114
|
+
console.log(`Settings:`, widget.settings);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### Get Widget Configuration
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
const config = await proofio.widget.config();
|
|
121
|
+
|
|
122
|
+
console.log(`Language: ${config.language}`);
|
|
123
|
+
console.log(`Theme: ${config.theme}`);
|
|
124
|
+
console.log(`Show AI Badge: ${config.showAiBadge}`);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Competitors
|
|
128
|
+
|
|
129
|
+
#### Compare with Competitor
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
const comparison = await proofio.competitors.compare('competitor-id', {
|
|
133
|
+
force: false, // Set to true to force refresh
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
console.log(`Summary: ${comparison.summary}`);
|
|
137
|
+
console.log(`Strengths:`, comparison.strengths);
|
|
138
|
+
console.log(`Weaknesses:`, comparison.weaknesses);
|
|
139
|
+
console.log(`Recommendations:`, comparison.recommendations);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Error Handling
|
|
143
|
+
|
|
144
|
+
The SDK throws `ProofioError` for all API errors. Always wrap API calls in try-catch blocks.
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import { Proofio, ProofioError } from 'proofio';
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
const reviews = await proofio.reviews.list();
|
|
151
|
+
} catch (error) {
|
|
152
|
+
if (error instanceof ProofioError) {
|
|
153
|
+
console.error(`API Error: ${error.message}`);
|
|
154
|
+
console.error(`Status: ${error.status}`);
|
|
155
|
+
console.error(`Code: ${error.code}`);
|
|
156
|
+
|
|
157
|
+
// Check if retryable
|
|
158
|
+
if (error.isRetryable()) {
|
|
159
|
+
// Implement retry logic
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Rate limit handling
|
|
163
|
+
if (error.status === 429) {
|
|
164
|
+
console.error(`Rate limit exceeded. Retry after: ${error.retryAfter} seconds`);
|
|
165
|
+
}
|
|
166
|
+
} else {
|
|
167
|
+
console.error('Unexpected error:', error);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Error Types
|
|
173
|
+
|
|
174
|
+
- `INVALID_API_KEY`: API key is missing or invalid
|
|
175
|
+
- `RATE_LIMIT_EXCEEDED`: Rate limit exceeded (status 429)
|
|
176
|
+
- `API_ERROR`: General API error
|
|
177
|
+
- `NETWORK_ERROR`: Network/connection error
|
|
178
|
+
- `TIMEOUT`: Request timeout
|
|
179
|
+
|
|
180
|
+
## Pagination
|
|
181
|
+
|
|
182
|
+
The SDK supports pagination for list endpoints:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
let offset = 0;
|
|
186
|
+
const limit = 50;
|
|
187
|
+
let allReviews: Review[] = [];
|
|
188
|
+
|
|
189
|
+
while (true) {
|
|
190
|
+
const reviews = await proofio.reviews.list({ limit, offset });
|
|
191
|
+
|
|
192
|
+
if (reviews.length === 0) {
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
allReviews = allReviews.concat(reviews);
|
|
197
|
+
offset += limit;
|
|
198
|
+
|
|
199
|
+
// Prevent infinite loops
|
|
200
|
+
if (reviews.length < limit) {
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Configuration Options
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
const proofio = new Proofio({
|
|
210
|
+
apiKey: 'your-api-key',
|
|
211
|
+
baseURL: 'https://proofio.app', // Optional, default: https://proofio.app
|
|
212
|
+
timeout: 30000, // Optional, default: 30000ms (30 seconds)
|
|
213
|
+
maxRetries: 3, // Optional, default: 3
|
|
214
|
+
retryDelay: 1000, // Optional, default: 1000ms (1 second)
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## TypeScript Support
|
|
219
|
+
|
|
220
|
+
The SDK is written in TypeScript and provides full type definitions:
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
import { Proofio, Review, InsightSummary } from 'proofio';
|
|
224
|
+
|
|
225
|
+
const proofio = new Proofio({ apiKey: 'your-api-key' });
|
|
226
|
+
|
|
227
|
+
// All types are inferred
|
|
228
|
+
const reviews: Review[] = await proofio.reviews.list();
|
|
229
|
+
const summary: InsightSummary = await proofio.insights.summary();
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## API Reference
|
|
233
|
+
|
|
234
|
+
### Proofio Class
|
|
235
|
+
|
|
236
|
+
Main SDK client class.
|
|
237
|
+
|
|
238
|
+
#### Constructor
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
new Proofio(config: ProofioConfig)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
#### Methods
|
|
245
|
+
|
|
246
|
+
- `reviews`: ReviewsResource - Access to review endpoints
|
|
247
|
+
- `insights`: InsightsResource - Access to insights endpoints
|
|
248
|
+
- `competitors`: CompetitorsResource - Access to competitor endpoints
|
|
249
|
+
- `widget`: WidgetResource - Access to widget endpoints
|
|
250
|
+
|
|
251
|
+
### ReviewsResource
|
|
252
|
+
|
|
253
|
+
#### `list(options?: ReviewFilterOptions): Promise<Review[]>`
|
|
254
|
+
|
|
255
|
+
List reviews with optional filters.
|
|
256
|
+
|
|
257
|
+
#### `get(id: string): Promise<Review | null>`
|
|
258
|
+
|
|
259
|
+
Get a single review by ID.
|
|
260
|
+
|
|
261
|
+
### InsightsResource
|
|
262
|
+
|
|
263
|
+
#### `summary(): Promise<InsightSummary>`
|
|
264
|
+
|
|
265
|
+
Get aggregated insights summary.
|
|
266
|
+
|
|
267
|
+
#### `trends(): Promise<InsightTrends>`
|
|
268
|
+
|
|
269
|
+
Get trend analysis data.
|
|
270
|
+
|
|
271
|
+
### CompetitorsResource
|
|
272
|
+
|
|
273
|
+
#### `compare(competitorId: string, options?: { force?: boolean }): Promise<CompetitorComparison>`
|
|
274
|
+
|
|
275
|
+
Compare your product with a competitor.
|
|
276
|
+
|
|
277
|
+
### WidgetResource
|
|
278
|
+
|
|
279
|
+
#### `get(): Promise<WidgetData>`
|
|
280
|
+
|
|
281
|
+
Get widget data including stats and settings.
|
|
282
|
+
|
|
283
|
+
#### `config(): Promise<WidgetSettings>`
|
|
284
|
+
|
|
285
|
+
Get widget configuration only.
|
|
286
|
+
|
|
287
|
+
## Rate Limits
|
|
288
|
+
|
|
289
|
+
The SDK automatically handles rate limits and includes retry logic. Rate limit information is available in error responses:
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
try {
|
|
293
|
+
await proofio.reviews.list();
|
|
294
|
+
} catch (error) {
|
|
295
|
+
if (error instanceof ProofioError && error.status === 429) {
|
|
296
|
+
console.log(`Remaining: ${error.rateLimitRemaining}`);
|
|
297
|
+
console.log(`Reset at: ${new Date(error.rateLimitReset! * 1000)}`);
|
|
298
|
+
console.log(`Retry after: ${error.retryAfter} seconds`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## Browser Support
|
|
304
|
+
|
|
305
|
+
The SDK uses the Fetch API, which is available in:
|
|
306
|
+
- Modern browsers (Chrome, Firefox, Safari, Edge)
|
|
307
|
+
- Node.js 18+ (with native fetch support)
|
|
308
|
+
- For older Node.js versions, use a fetch polyfill like `node-fetch`
|
|
309
|
+
|
|
310
|
+
## License
|
|
311
|
+
|
|
312
|
+
MIT
|
|
313
|
+
|
|
314
|
+
## Support
|
|
315
|
+
|
|
316
|
+
For issues and questions:
|
|
317
|
+
- GitHub Issues: https://github.com/proofio/proofio-sdk/issues
|
|
318
|
+
- Documentation: https://proofio.app/docs
|
|
319
|
+
- Email: support@proofio.app
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Core API Client für Proofio SDK
|
|
4
|
+
*
|
|
5
|
+
* Handles:
|
|
6
|
+
* - API Key Authentication
|
|
7
|
+
* - Base URL Management
|
|
8
|
+
* - Request/Response Handling
|
|
9
|
+
* - Error Normalization
|
|
10
|
+
* - Rate Limit Handling
|
|
11
|
+
* - Retry Logic
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.ApiClient = void 0;
|
|
15
|
+
const errors_1 = require("../utils/errors");
|
|
16
|
+
class ApiClient {
|
|
17
|
+
constructor(config) {
|
|
18
|
+
if (!config.apiKey || typeof config.apiKey !== 'string' || config.apiKey.trim().length === 0) {
|
|
19
|
+
throw new errors_1.ProofioError({
|
|
20
|
+
message: 'API key is required',
|
|
21
|
+
status: 0,
|
|
22
|
+
code: 'INVALID_API_KEY',
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// Validate API key format (basic validation)
|
|
26
|
+
if (config.apiKey.length < 10) {
|
|
27
|
+
throw new errors_1.ProofioError({
|
|
28
|
+
message: 'API key format is invalid',
|
|
29
|
+
status: 0,
|
|
30
|
+
code: 'INVALID_API_KEY',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
this.apiKey = config.apiKey.trim();
|
|
34
|
+
this.baseURL = config.baseURL || 'https://proofio.app';
|
|
35
|
+
this.timeout = config.timeout || 30000; // 30 seconds
|
|
36
|
+
this.maxRetries = config.maxRetries ?? 3;
|
|
37
|
+
this.retryDelay = config.retryDelay ?? 1000; // 1 second
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Sanitize API key for logging (never log full key)
|
|
41
|
+
*/
|
|
42
|
+
sanitizeApiKey() {
|
|
43
|
+
if (this.apiKey.length <= 8) {
|
|
44
|
+
return '***';
|
|
45
|
+
}
|
|
46
|
+
return `${this.apiKey.substring(0, 4)}...${this.apiKey.substring(this.apiKey.length - 4)}`;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Build headers for requests
|
|
50
|
+
*/
|
|
51
|
+
buildHeaders(customHeaders) {
|
|
52
|
+
const headers = new Headers({
|
|
53
|
+
'Content-Type': 'application/json',
|
|
54
|
+
'x-api-key': this.apiKey,
|
|
55
|
+
'User-Agent': 'proofio-sdk/1.0.0',
|
|
56
|
+
...customHeaders,
|
|
57
|
+
});
|
|
58
|
+
// Make headers immutable by creating new Headers object
|
|
59
|
+
return new Headers(headers);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Build full URL
|
|
63
|
+
*/
|
|
64
|
+
buildURL(path, queryParams) {
|
|
65
|
+
const url = new URL(path, this.baseURL);
|
|
66
|
+
if (queryParams) {
|
|
67
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
68
|
+
if (value !== undefined && value !== null) {
|
|
69
|
+
url.searchParams.append(key, String(value));
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return url.toString();
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Handle rate limit errors
|
|
77
|
+
*/
|
|
78
|
+
async handleRateLimit(response) {
|
|
79
|
+
const retryAfter = response.headers.get('Retry-After');
|
|
80
|
+
const rateLimitRemaining = response.headers.get('X-RateLimit-Remaining');
|
|
81
|
+
const rateLimitReset = response.headers.get('X-RateLimit-Reset');
|
|
82
|
+
const errorData = {
|
|
83
|
+
message: 'Rate limit exceeded',
|
|
84
|
+
status: 429,
|
|
85
|
+
code: 'RATE_LIMIT_EXCEEDED',
|
|
86
|
+
};
|
|
87
|
+
if (retryAfter) {
|
|
88
|
+
errorData.retryAfter = parseInt(retryAfter, 10);
|
|
89
|
+
}
|
|
90
|
+
if (rateLimitRemaining !== null) {
|
|
91
|
+
errorData.rateLimitRemaining = parseInt(rateLimitRemaining, 10);
|
|
92
|
+
}
|
|
93
|
+
if (rateLimitReset) {
|
|
94
|
+
errorData.rateLimitReset = parseInt(rateLimitReset, 10);
|
|
95
|
+
}
|
|
96
|
+
throw new errors_1.ProofioError(errorData);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Parse error response
|
|
100
|
+
*/
|
|
101
|
+
async parseErrorResponse(response) {
|
|
102
|
+
let errorData = {
|
|
103
|
+
message: `API request failed with status ${response.status}`,
|
|
104
|
+
status: response.status,
|
|
105
|
+
code: 'API_ERROR',
|
|
106
|
+
};
|
|
107
|
+
try {
|
|
108
|
+
const contentType = response.headers.get('content-type');
|
|
109
|
+
if (contentType && contentType.includes('application/json')) {
|
|
110
|
+
const data = await response.json();
|
|
111
|
+
errorData = {
|
|
112
|
+
...errorData,
|
|
113
|
+
message: data.error || data.message || errorData.message,
|
|
114
|
+
code: data.code || errorData.code,
|
|
115
|
+
requestId: data.requestId,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// If JSON parsing fails, use default error
|
|
121
|
+
}
|
|
122
|
+
return new errors_1.ProofioError(errorData);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Sleep helper for retries
|
|
126
|
+
*/
|
|
127
|
+
sleep(ms) {
|
|
128
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Check if error is retryable
|
|
132
|
+
*/
|
|
133
|
+
isRetryableError(status, error) {
|
|
134
|
+
// Retry on network errors, timeouts, and 5xx errors
|
|
135
|
+
if (!status)
|
|
136
|
+
return true; // Network error
|
|
137
|
+
if (status >= 500)
|
|
138
|
+
return true; // Server errors
|
|
139
|
+
if (status === 429)
|
|
140
|
+
return true; // Rate limit (with backoff)
|
|
141
|
+
if (status === 408)
|
|
142
|
+
return true; // Request timeout
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Execute request with retry logic
|
|
147
|
+
*/
|
|
148
|
+
async executeWithRetry(requestFn, retryCount = 0) {
|
|
149
|
+
try {
|
|
150
|
+
const response = await requestFn();
|
|
151
|
+
// If rate limited, throw immediately (don't retry immediately)
|
|
152
|
+
if (response.status === 429) {
|
|
153
|
+
await this.handleRateLimit(response);
|
|
154
|
+
}
|
|
155
|
+
// If error is retryable and we haven't exceeded max retries
|
|
156
|
+
if (!response.ok && this.isRetryableError(response.status) && retryCount < this.maxRetries) {
|
|
157
|
+
// Exponential backoff with jitter
|
|
158
|
+
const delay = this.retryDelay * Math.pow(2, retryCount) + Math.random() * 1000;
|
|
159
|
+
await this.sleep(delay);
|
|
160
|
+
return this.executeWithRetry(requestFn, retryCount + 1);
|
|
161
|
+
}
|
|
162
|
+
return response;
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
// Network errors are retryable
|
|
166
|
+
if (retryCount < this.maxRetries && this.isRetryableError(0, error)) {
|
|
167
|
+
const delay = this.retryDelay * Math.pow(2, retryCount) + Math.random() * 1000;
|
|
168
|
+
await this.sleep(delay);
|
|
169
|
+
return this.executeWithRetry(requestFn, retryCount + 1);
|
|
170
|
+
}
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Make GET request
|
|
176
|
+
*/
|
|
177
|
+
async get(path, options) {
|
|
178
|
+
const url = this.buildURL(path, options?.queryParams);
|
|
179
|
+
const headers = this.buildHeaders(options?.headers);
|
|
180
|
+
const controller = new AbortController();
|
|
181
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
182
|
+
try {
|
|
183
|
+
const response = await this.executeWithRetry(async () => {
|
|
184
|
+
return fetch(url, {
|
|
185
|
+
method: 'GET',
|
|
186
|
+
headers,
|
|
187
|
+
signal: controller.signal,
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
clearTimeout(timeoutId);
|
|
191
|
+
if (!response.ok) {
|
|
192
|
+
if (response.status === 429) {
|
|
193
|
+
await this.handleRateLimit(response);
|
|
194
|
+
}
|
|
195
|
+
throw await this.parseErrorResponse(response);
|
|
196
|
+
}
|
|
197
|
+
const data = await response.json();
|
|
198
|
+
// Convert Headers to plain object
|
|
199
|
+
const headers = {};
|
|
200
|
+
response.headers.forEach((value, key) => {
|
|
201
|
+
headers[key] = value;
|
|
202
|
+
});
|
|
203
|
+
return {
|
|
204
|
+
data,
|
|
205
|
+
status: response.status,
|
|
206
|
+
headers,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
clearTimeout(timeoutId);
|
|
211
|
+
if (error instanceof errors_1.ProofioError) {
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
215
|
+
throw new errors_1.ProofioError({
|
|
216
|
+
message: 'Request timeout',
|
|
217
|
+
status: 408,
|
|
218
|
+
code: 'TIMEOUT',
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
throw new errors_1.ProofioError({
|
|
222
|
+
message: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
223
|
+
status: 0,
|
|
224
|
+
code: 'NETWORK_ERROR',
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Make POST request
|
|
230
|
+
*/
|
|
231
|
+
async post(path, body, options) {
|
|
232
|
+
const url = this.buildURL(path, options?.queryParams);
|
|
233
|
+
const headers = this.buildHeaders(options?.headers);
|
|
234
|
+
const controller = new AbortController();
|
|
235
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
236
|
+
try {
|
|
237
|
+
const response = await this.executeWithRetry(async () => {
|
|
238
|
+
return fetch(url, {
|
|
239
|
+
method: 'POST',
|
|
240
|
+
headers,
|
|
241
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
242
|
+
signal: controller.signal,
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
clearTimeout(timeoutId);
|
|
246
|
+
if (!response.ok) {
|
|
247
|
+
if (response.status === 429) {
|
|
248
|
+
await this.handleRateLimit(response);
|
|
249
|
+
}
|
|
250
|
+
throw await this.parseErrorResponse(response);
|
|
251
|
+
}
|
|
252
|
+
const data = await response.json();
|
|
253
|
+
// Convert Headers to plain object
|
|
254
|
+
const headers = {};
|
|
255
|
+
response.headers.forEach((value, key) => {
|
|
256
|
+
headers[key] = value;
|
|
257
|
+
});
|
|
258
|
+
return {
|
|
259
|
+
data,
|
|
260
|
+
status: response.status,
|
|
261
|
+
headers,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
clearTimeout(timeoutId);
|
|
266
|
+
if (error instanceof errors_1.ProofioError) {
|
|
267
|
+
throw error;
|
|
268
|
+
}
|
|
269
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
270
|
+
throw new errors_1.ProofioError({
|
|
271
|
+
message: 'Request timeout',
|
|
272
|
+
status: 408,
|
|
273
|
+
code: 'TIMEOUT',
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
throw new errors_1.ProofioError({
|
|
277
|
+
message: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
278
|
+
status: 0,
|
|
279
|
+
code: 'NETWORK_ERROR',
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
exports.ApiClient = ApiClient;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Proofio SDK
|
|
4
|
+
*
|
|
5
|
+
* Official JavaScript/TypeScript SDK for Proofio API
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { Proofio } from 'proofio-sdk';
|
|
10
|
+
*
|
|
11
|
+
* const proofio = new Proofio({ apiKey: 'your-api-key' });
|
|
12
|
+
*
|
|
13
|
+
* const reviews = await proofio.reviews.list();
|
|
14
|
+
* const summary = await proofio.insights.summary();
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.Proofio = exports.ApiClient = exports.ProofioError = void 0;
|
|
19
|
+
const api_client_1 = require("./client/api-client");
|
|
20
|
+
const reviews_1 = require("./resources/reviews");
|
|
21
|
+
const insights_1 = require("./resources/insights");
|
|
22
|
+
const competitors_1 = require("./resources/competitors");
|
|
23
|
+
const widget_1 = require("./resources/widget");
|
|
24
|
+
var errors_1 = require("./utils/errors");
|
|
25
|
+
Object.defineProperty(exports, "ProofioError", { enumerable: true, get: function () { return errors_1.ProofioError; } });
|
|
26
|
+
var api_client_2 = require("./client/api-client");
|
|
27
|
+
Object.defineProperty(exports, "ApiClient", { enumerable: true, get: function () { return api_client_2.ApiClient; } });
|
|
28
|
+
/**
|
|
29
|
+
* Main Proofio SDK Client
|
|
30
|
+
*
|
|
31
|
+
* Provides access to all Proofio API resources:
|
|
32
|
+
* - reviews: List and get reviews
|
|
33
|
+
* - insights: Get summaries and trends
|
|
34
|
+
* - competitors: Compare with competitors
|
|
35
|
+
* - widget: Get widget data and configuration
|
|
36
|
+
*/
|
|
37
|
+
class Proofio {
|
|
38
|
+
/**
|
|
39
|
+
* Create a new Proofio SDK instance
|
|
40
|
+
*
|
|
41
|
+
* @param config - SDK configuration
|
|
42
|
+
* @param config.apiKey - Your Proofio API key (required)
|
|
43
|
+
* @param config.baseURL - Base URL for API (default: https://proofio.app)
|
|
44
|
+
* @param config.timeout - Request timeout in milliseconds (default: 30000)
|
|
45
|
+
* @param config.maxRetries - Maximum number of retries (default: 3)
|
|
46
|
+
* @param config.retryDelay - Delay between retries in milliseconds (default: 1000)
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const proofio = new Proofio({
|
|
51
|
+
* apiKey: 'your-api-key-here',
|
|
52
|
+
* baseURL: 'https://proofio.app', // optional
|
|
53
|
+
* timeout: 30000, // optional
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
constructor(config) {
|
|
58
|
+
this.client = new api_client_1.ApiClient(config);
|
|
59
|
+
// Initialize resources
|
|
60
|
+
this.reviews = new reviews_1.ReviewsResource(this.client);
|
|
61
|
+
this.insights = new insights_1.InsightsResource(this.client);
|
|
62
|
+
this.competitors = new competitors_1.CompetitorsResource(this.client);
|
|
63
|
+
this.widget = new widget_1.WidgetResource(this.client);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get the underlying API client (for advanced usage)
|
|
67
|
+
*/
|
|
68
|
+
getClient() {
|
|
69
|
+
return this.client;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.Proofio = Proofio;
|
|
73
|
+
// Default export
|
|
74
|
+
exports.default = Proofio;
|