@paceful/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 +433 -0
- package/dist/index.d.mts +1052 -0
- package/dist/index.d.ts +1052 -0
- package/dist/index.js +1968 -0
- package/dist/index.mjs +1938 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
# @paceful/sdk
|
|
2
|
+
|
|
3
|
+
Official JavaScript/TypeScript SDK for the Paceful Partner API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @paceful/sdk
|
|
9
|
+
# or
|
|
10
|
+
yarn add @paceful/sdk
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @paceful/sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { PacefulClient } from '@paceful/sdk';
|
|
19
|
+
|
|
20
|
+
const paceful = new PacefulClient({
|
|
21
|
+
apiKey: process.env.PACEFUL_API_KEY,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Register a user
|
|
25
|
+
const user = await paceful.users.register({
|
|
26
|
+
externalId: 'user_123',
|
|
27
|
+
email: 'user@example.com',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Log mood data
|
|
31
|
+
await paceful.mood.log({
|
|
32
|
+
externalId: 'user_123',
|
|
33
|
+
mood: 4,
|
|
34
|
+
note: 'Feeling productive today',
|
|
35
|
+
factors: ['work', 'exercise'],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Get ERS score
|
|
39
|
+
const ers = await paceful.ers.get('user_123');
|
|
40
|
+
console.log(`ERS Score: ${ers.ersScore}`);
|
|
41
|
+
console.log(`Stage: ${ers.stage}`);
|
|
42
|
+
console.log(`Trend: ${ers.trend?.direction}`);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Modules
|
|
46
|
+
|
|
47
|
+
### Users
|
|
48
|
+
|
|
49
|
+
Manage partner users in the Paceful system.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// Register a new user
|
|
53
|
+
const user = await paceful.users.register({
|
|
54
|
+
externalId: 'user_123',
|
|
55
|
+
email: 'user@example.com',
|
|
56
|
+
metadata: { plan: 'premium' },
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Get a user
|
|
60
|
+
const user = await paceful.users.get('user_123');
|
|
61
|
+
|
|
62
|
+
// Update user metadata
|
|
63
|
+
await paceful.users.update('user_123', {
|
|
64
|
+
metadata: { plan: 'enterprise' },
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// List all users
|
|
68
|
+
const { items, total, hasMore } = await paceful.users.list({ limit: 50 });
|
|
69
|
+
|
|
70
|
+
// Delete a user
|
|
71
|
+
await paceful.users.delete('user_123');
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Mood
|
|
75
|
+
|
|
76
|
+
Track and retrieve mood data for users.
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// Log a mood entry
|
|
80
|
+
const entry = await paceful.mood.log({
|
|
81
|
+
externalId: 'user_123',
|
|
82
|
+
mood: 4, // 1-5 scale
|
|
83
|
+
note: 'Great day!',
|
|
84
|
+
factors: ['exercise', 'sleep'],
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Get mood history
|
|
88
|
+
const history = await paceful.mood.history({
|
|
89
|
+
externalId: 'user_123',
|
|
90
|
+
startDate: '2024-01-01',
|
|
91
|
+
limit: 30,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Get latest mood
|
|
95
|
+
const latest = await paceful.mood.latest('user_123');
|
|
96
|
+
|
|
97
|
+
// Get mood statistics
|
|
98
|
+
const stats = await paceful.mood.stats('user_123', '30d');
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Journal
|
|
102
|
+
|
|
103
|
+
Create and retrieve journal entries.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
// Create a journal entry
|
|
107
|
+
const entry = await paceful.journal.create({
|
|
108
|
+
externalId: 'user_123',
|
|
109
|
+
content: 'Today I reflected on my progress...',
|
|
110
|
+
mood: 4,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Entry includes AI analysis
|
|
114
|
+
console.log('Themes:', entry.themes);
|
|
115
|
+
console.log('Sentiment:', entry.sentimentScore);
|
|
116
|
+
|
|
117
|
+
// Get journal history
|
|
118
|
+
const entries = await paceful.journal.history({
|
|
119
|
+
externalId: 'user_123',
|
|
120
|
+
limit: 10,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Get available prompts
|
|
124
|
+
const prompts = await paceful.journal.prompts();
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### ERS (Emotional Readiness Score)
|
|
128
|
+
|
|
129
|
+
Calculate and retrieve ERS scores.
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
// Get current ERS score (cached if recent)
|
|
133
|
+
const ers = await paceful.ers.get('user_123');
|
|
134
|
+
|
|
135
|
+
// Force fresh calculation
|
|
136
|
+
const result = await paceful.ers.calculate('user_123');
|
|
137
|
+
|
|
138
|
+
// Batch get scores for multiple users
|
|
139
|
+
const batch = await paceful.ers.batch(['user_1', 'user_2', 'user_3']);
|
|
140
|
+
|
|
141
|
+
// Get score history
|
|
142
|
+
const history = await paceful.ers.history('user_123', {
|
|
143
|
+
period: '30d',
|
|
144
|
+
granularity: 'daily',
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Set up threshold alerts
|
|
148
|
+
await paceful.ers.setThresholdAlert({
|
|
149
|
+
externalId: 'user_123',
|
|
150
|
+
threshold: 40,
|
|
151
|
+
direction: 'below',
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Analytics
|
|
156
|
+
|
|
157
|
+
Get aggregate analytics for your partner account.
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// Get summary analytics
|
|
161
|
+
const summary = await paceful.analytics.summary('30d');
|
|
162
|
+
console.log(`Total users: ${summary.totalUsers}`);
|
|
163
|
+
console.log(`Average ERS: ${summary.averageErs}`);
|
|
164
|
+
|
|
165
|
+
// Get engagement metrics
|
|
166
|
+
const engagement = await paceful.analytics.engagement({
|
|
167
|
+
period: '30d',
|
|
168
|
+
granularity: 'daily',
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Get ERS distribution
|
|
172
|
+
const distribution = await paceful.analytics.ersDistribution('30d');
|
|
173
|
+
|
|
174
|
+
// Get retention metrics
|
|
175
|
+
const retention = await paceful.analytics.retention('30d');
|
|
176
|
+
|
|
177
|
+
// Export data
|
|
178
|
+
const { downloadUrl } = await paceful.analytics.export({
|
|
179
|
+
type: 'user_summary',
|
|
180
|
+
period: '30d',
|
|
181
|
+
format: 'csv',
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Webhooks
|
|
186
|
+
|
|
187
|
+
Manage webhook endpoints for real-time notifications.
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
// Register a webhook
|
|
191
|
+
const webhook = await paceful.webhooks.register({
|
|
192
|
+
url: 'https://yourapp.com/webhooks/paceful',
|
|
193
|
+
events: ['ers.stage_changed', 'mood.critical'],
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Save the secret for signature verification
|
|
197
|
+
console.log('Secret:', webhook.secret);
|
|
198
|
+
|
|
199
|
+
// List webhooks
|
|
200
|
+
const webhooks = await paceful.webhooks.list();
|
|
201
|
+
|
|
202
|
+
// Update a webhook
|
|
203
|
+
await paceful.webhooks.update(webhook.webhookId, {
|
|
204
|
+
events: ['ers.stage_changed', 'mood.critical', 'journal.created'],
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Test a webhook
|
|
208
|
+
const result = await paceful.webhooks.test(webhook.webhookId);
|
|
209
|
+
|
|
210
|
+
// Verify webhook signatures
|
|
211
|
+
import { Webhooks } from '@paceful/sdk';
|
|
212
|
+
|
|
213
|
+
const isValid = Webhooks.verifySignature(
|
|
214
|
+
rawBody,
|
|
215
|
+
request.headers['x-paceful-signature'],
|
|
216
|
+
process.env.PACEFUL_WEBHOOK_SECRET
|
|
217
|
+
);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Webhook Events
|
|
221
|
+
|
|
222
|
+
| Event | Description |
|
|
223
|
+
|-------|-------------|
|
|
224
|
+
| `ers.stage_changed` | User's ERS stage changed (healing, rebuilding, ready) |
|
|
225
|
+
| `ers.score_threshold` | User's ERS crossed a configured threshold |
|
|
226
|
+
| `mood.critical` | User logged a critical mood (1-2) |
|
|
227
|
+
| `mood.logged` | User logged any mood entry |
|
|
228
|
+
| `journal.created` | User created a journal entry |
|
|
229
|
+
|
|
230
|
+
## React Widgets
|
|
231
|
+
|
|
232
|
+
The SDK includes embeddable React widgets for quick integration. Widgets use inline styles and have no external dependencies.
|
|
233
|
+
|
|
234
|
+
### PacefulProvider
|
|
235
|
+
|
|
236
|
+
Wrap your app to provide context to all widgets:
|
|
237
|
+
|
|
238
|
+
```tsx
|
|
239
|
+
import { PacefulProvider } from '@paceful/sdk';
|
|
240
|
+
|
|
241
|
+
function App() {
|
|
242
|
+
return (
|
|
243
|
+
<PacefulProvider
|
|
244
|
+
apiKey={process.env.PACEFUL_API_KEY}
|
|
245
|
+
userId="user_123"
|
|
246
|
+
>
|
|
247
|
+
<YourApp />
|
|
248
|
+
</PacefulProvider>
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### MoodWidget
|
|
254
|
+
|
|
255
|
+
Self-contained mood check-in component:
|
|
256
|
+
|
|
257
|
+
```tsx
|
|
258
|
+
import { MoodWidget } from '@paceful/sdk';
|
|
259
|
+
|
|
260
|
+
// With PacefulProvider context
|
|
261
|
+
<MoodWidget
|
|
262
|
+
theme="light"
|
|
263
|
+
brandColor="#5B8A72"
|
|
264
|
+
showStreak={true}
|
|
265
|
+
onComplete={(mood) => console.log('Logged:', mood)}
|
|
266
|
+
/>
|
|
267
|
+
|
|
268
|
+
// Standalone (without provider)
|
|
269
|
+
<MoodWidget
|
|
270
|
+
apiKey="your_api_key"
|
|
271
|
+
userId="user_123"
|
|
272
|
+
theme="dark"
|
|
273
|
+
compact={true}
|
|
274
|
+
/>
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**Props:**
|
|
278
|
+
| Prop | Type | Default | Description |
|
|
279
|
+
|------|------|---------|-------------|
|
|
280
|
+
| `apiKey` | string | - | API key (optional if using PacefulProvider) |
|
|
281
|
+
| `userId` | string | - | User ID (optional if using PacefulProvider) |
|
|
282
|
+
| `theme` | 'light' \| 'dark' | 'light' | Color theme |
|
|
283
|
+
| `brandColor` | string | '#5B8A72' | Primary accent color |
|
|
284
|
+
| `compact` | boolean | false | Skip emotion selection step |
|
|
285
|
+
| `showStreak` | boolean | false | Show mood logging streak |
|
|
286
|
+
| `onComplete` | function | - | Callback when mood is logged |
|
|
287
|
+
| `onError` | function | - | Callback on error |
|
|
288
|
+
|
|
289
|
+
### JournalWidget
|
|
290
|
+
|
|
291
|
+
Journal entry component with AI reflection:
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
import { JournalWidget } from '@paceful/sdk';
|
|
295
|
+
|
|
296
|
+
<JournalWidget
|
|
297
|
+
theme="light"
|
|
298
|
+
brandColor="#5B8A72"
|
|
299
|
+
showPrompt={true}
|
|
300
|
+
showAIReflection={true}
|
|
301
|
+
maxLength={2000}
|
|
302
|
+
onComplete={(entry) => console.log('Saved:', entry)}
|
|
303
|
+
/>
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Props:**
|
|
307
|
+
| Prop | Type | Default | Description |
|
|
308
|
+
|------|------|---------|-------------|
|
|
309
|
+
| `apiKey` | string | - | API key (optional if using PacefulProvider) |
|
|
310
|
+
| `userId` | string | - | User ID (optional if using PacefulProvider) |
|
|
311
|
+
| `theme` | 'light' \| 'dark' | 'light' | Color theme |
|
|
312
|
+
| `brandColor` | string | '#5B8A72' | Primary accent color |
|
|
313
|
+
| `showPrompt` | boolean | true | Show random journal prompt |
|
|
314
|
+
| `showAIReflection` | boolean | true | Show AI reflection after saving |
|
|
315
|
+
| `maxLength` | number | 2000 | Maximum character length |
|
|
316
|
+
| `placeholder` | string | "What's on your mind?" | Textarea placeholder |
|
|
317
|
+
| `onComplete` | function | - | Callback when entry is saved |
|
|
318
|
+
| `onError` | function | - | Callback on error |
|
|
319
|
+
|
|
320
|
+
### ERSDisplay
|
|
321
|
+
|
|
322
|
+
ERS score visualization component:
|
|
323
|
+
|
|
324
|
+
```tsx
|
|
325
|
+
import { ERSDisplay } from '@paceful/sdk';
|
|
326
|
+
|
|
327
|
+
<ERSDisplay
|
|
328
|
+
theme="light"
|
|
329
|
+
brandColor="#5B8A72"
|
|
330
|
+
showDimensions={true}
|
|
331
|
+
showTrend={true}
|
|
332
|
+
compact={false}
|
|
333
|
+
onLoad={(ers) => console.log('ERS:', ers)}
|
|
334
|
+
/>
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Props:**
|
|
338
|
+
| Prop | Type | Default | Description |
|
|
339
|
+
|------|------|---------|-------------|
|
|
340
|
+
| `apiKey` | string | - | API key (optional if using PacefulProvider) |
|
|
341
|
+
| `userId` | string | - | User ID (optional if using PacefulProvider) |
|
|
342
|
+
| `theme` | 'light' \| 'dark' | 'light' | Color theme |
|
|
343
|
+
| `brandColor` | string | '#5B8A72' | Primary accent color |
|
|
344
|
+
| `showDimensions` | boolean | true | Show 5 ERS dimension bars |
|
|
345
|
+
| `showTrend` | boolean | true | Show weekly trend badge |
|
|
346
|
+
| `compact` | boolean | false | Smaller ring, hide dimensions |
|
|
347
|
+
| `onLoad` | function | - | Callback when ERS loads |
|
|
348
|
+
| `onError` | function | - | Callback on error |
|
|
349
|
+
|
|
350
|
+
## Error Handling
|
|
351
|
+
|
|
352
|
+
The SDK throws typed errors for different failure scenarios:
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
import {
|
|
356
|
+
PacefulError,
|
|
357
|
+
PacefulAuthError,
|
|
358
|
+
PacefulRateLimitError,
|
|
359
|
+
PacefulNotFoundError,
|
|
360
|
+
PacefulValidationError,
|
|
361
|
+
PacefulNetworkError,
|
|
362
|
+
} from '@paceful/sdk';
|
|
363
|
+
|
|
364
|
+
try {
|
|
365
|
+
const ers = await paceful.ers.get('user_123');
|
|
366
|
+
} catch (error) {
|
|
367
|
+
if (error instanceof PacefulAuthError) {
|
|
368
|
+
// Invalid API key
|
|
369
|
+
console.error('Authentication failed');
|
|
370
|
+
} else if (error instanceof PacefulRateLimitError) {
|
|
371
|
+
// Rate limited - retry after error.retryAfter seconds
|
|
372
|
+
console.error(`Rate limited. Retry after ${error.retryAfter}s`);
|
|
373
|
+
} else if (error instanceof PacefulNotFoundError) {
|
|
374
|
+
// User not found
|
|
375
|
+
console.error('User not found');
|
|
376
|
+
} else if (error instanceof PacefulValidationError) {
|
|
377
|
+
// Invalid request parameters
|
|
378
|
+
console.error('Validation error:', error.message);
|
|
379
|
+
} else if (error instanceof PacefulNetworkError) {
|
|
380
|
+
// Network failure
|
|
381
|
+
console.error('Network error:', error.message);
|
|
382
|
+
} else if (error instanceof PacefulError) {
|
|
383
|
+
// Generic API error
|
|
384
|
+
console.error(`Error ${error.code}:`, error.message);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## Configuration
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
const paceful = new PacefulClient({
|
|
393
|
+
// Required: Your API key
|
|
394
|
+
apiKey: process.env.PACEFUL_API_KEY,
|
|
395
|
+
|
|
396
|
+
// Optional: Custom base URL (for testing)
|
|
397
|
+
baseUrl: 'https://api.paceful.app',
|
|
398
|
+
|
|
399
|
+
// Optional: Request timeout in ms (default: 30000)
|
|
400
|
+
timeout: 30000,
|
|
401
|
+
|
|
402
|
+
// Optional: Number of retries for failed requests (default: 3)
|
|
403
|
+
retries: 3,
|
|
404
|
+
});
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
## TypeScript Support
|
|
408
|
+
|
|
409
|
+
The SDK is written in TypeScript and provides full type definitions:
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
import type {
|
|
413
|
+
PacefulConfig,
|
|
414
|
+
PartnerUser,
|
|
415
|
+
MoodEntry,
|
|
416
|
+
JournalEntry,
|
|
417
|
+
ERSScore,
|
|
418
|
+
ERSStage,
|
|
419
|
+
ERSDimensions,
|
|
420
|
+
AnalyticsSummary,
|
|
421
|
+
WebhookEvent,
|
|
422
|
+
} from '@paceful/sdk';
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
## Requirements
|
|
426
|
+
|
|
427
|
+
- Node.js 18.0.0 or higher
|
|
428
|
+
- TypeScript 5.0+ (for TypeScript users)
|
|
429
|
+
- React 17.0.0+ (for widget components, optional)
|
|
430
|
+
|
|
431
|
+
## License
|
|
432
|
+
|
|
433
|
+
MIT
|