@withaevum/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 +436 -0
- package/dist/analytics.d.ts +17 -0
- package/dist/analytics.js +46 -0
- package/dist/availability.d.ts +23 -0
- package/dist/availability.js +114 -0
- package/dist/bookings.d.ts +29 -0
- package/dist/bookings.js +122 -0
- package/dist/calendar.d.ts +13 -0
- package/dist/calendar.js +65 -0
- package/dist/client.d.ts +40 -0
- package/dist/client.js +139 -0
- package/dist/customers.d.ts +25 -0
- package/dist/customers.js +60 -0
- package/dist/errors.d.ts +42 -0
- package/dist/errors.js +54 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +11 -0
- package/dist/offerings.d.ts +99 -0
- package/dist/offerings.js +355 -0
- package/dist/providers.d.ts +21 -0
- package/dist/providers.js +58 -0
- package/dist/types.d.ts +593 -0
- package/dist/types.js +2 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
# @aevum/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for the Aevum API - a comprehensive scheduling and booking management platform.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @aevum/sdk
|
|
9
|
+
# or
|
|
10
|
+
yarn add @aevum/sdk
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @aevum/sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Initialization
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { AevumClient } from '@aevum/sdk';
|
|
21
|
+
|
|
22
|
+
const client = new AevumClient({
|
|
23
|
+
apiKey: process.env.AEVUM_API_KEY,
|
|
24
|
+
// Optional: customize base URL (default: https://api.withaevum.com)
|
|
25
|
+
baseUrl: 'https://api.withaevum.com',
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The SDK automatically resolves your organization ID from the API key, so you don't need to provide it manually.
|
|
30
|
+
|
|
31
|
+
## API Reference
|
|
32
|
+
|
|
33
|
+
### Bookings
|
|
34
|
+
|
|
35
|
+
#### Create a booking
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
const booking = await client.bookings.create({
|
|
39
|
+
providerIds: ['provider_123'],
|
|
40
|
+
offeringIds: ['offering_456'],
|
|
41
|
+
startTime: '2024-01-15T10:00:00Z',
|
|
42
|
+
endTime: '2024-01-15T10:30:00Z',
|
|
43
|
+
customerEmail: 'customer@example.com',
|
|
44
|
+
// Optional:
|
|
45
|
+
// customerId: 'customer_789',
|
|
46
|
+
// customer: { name: 'John Doe', email: 'john@example.com', phone: '+1234567890' },
|
|
47
|
+
// price_cents: 5000,
|
|
48
|
+
// notes: 'Special request',
|
|
49
|
+
// status: 'pending',
|
|
50
|
+
// kind: 'standard',
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### Get a booking
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
const booking = await client.bookings.get('booking_123');
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
#### List bookings
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
const bookings = await client.bookings.list({
|
|
64
|
+
providerId: 'provider_123',
|
|
65
|
+
startDate: '2024-01-01T00:00:00Z',
|
|
66
|
+
endDate: '2024-01-31T23:59:59Z',
|
|
67
|
+
status: 'confirmed',
|
|
68
|
+
page: 1,
|
|
69
|
+
pageSize: 20,
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### Reschedule a booking
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
const updatedBooking = await client.bookings.reschedule('booking_123', {
|
|
77
|
+
start_time: '2024-01-15T11:00:00Z',
|
|
78
|
+
end_time: '2024-01-15T11:30:00Z',
|
|
79
|
+
sendNotification: true, // Optional, default: false
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### Cancel a booking
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
const cancelledBooking = await client.bookings.cancel(
|
|
87
|
+
'booking_123',
|
|
88
|
+
'Customer requested cancellation', // Optional reason
|
|
89
|
+
);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Offerings
|
|
93
|
+
|
|
94
|
+
#### List offerings
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
const offerings = await client.offerings.list({
|
|
98
|
+
eventId: 'event_123', // Optional: filter by event
|
|
99
|
+
providerId: 'provider_123', // Optional: filter by provider
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### Get an offering
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
const offering = await client.offerings.get('offering_123');
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### Create an offering
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
const offering = await client.offerings.create({
|
|
113
|
+
name: '60-minute Therapy Session',
|
|
114
|
+
description: 'One-on-one therapy session',
|
|
115
|
+
price_cents: 15000, // $150.00
|
|
116
|
+
duration_minutes: 60,
|
|
117
|
+
timezone: 'America/New_York',
|
|
118
|
+
attendee_mode: '1:1',
|
|
119
|
+
providerIds: ['provider_123'], // Optional: associate with providers
|
|
120
|
+
// Many more optional fields available for recurrence, scheduling windows, etc.
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
#### Simple Offering Creation (Recommended for most use cases)
|
|
125
|
+
|
|
126
|
+
For most clients, the helper methods below provide a simpler way to create offerings without dealing with complex recurrence patterns and availability windows.
|
|
127
|
+
|
|
128
|
+
##### Create a Simple Offering
|
|
129
|
+
|
|
130
|
+
Creates a basic 1:1 offering that uses provider availability schedules (no fixed times or recurrence):
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
const offering = await client.offerings.createSimple({
|
|
134
|
+
name: 'Therapy Session',
|
|
135
|
+
duration_minutes: 60,
|
|
136
|
+
price_cents: 15000, // $150.00
|
|
137
|
+
description: 'One-on-one therapy session',
|
|
138
|
+
timezone: 'America/New_York', // Optional, defaults to organization timezone
|
|
139
|
+
providerIds: ['provider_123'], // Optional: associate with providers
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
##### Create a Weekly Recurring Offering
|
|
144
|
+
|
|
145
|
+
Creates a weekly recurring offering with specific days and time slots:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const offering = await client.offerings.createRecurringWeekly({
|
|
149
|
+
name: 'Weekly Therapy',
|
|
150
|
+
duration_minutes: 60,
|
|
151
|
+
days: ['monday', 'wednesday', 'friday'], // Can also use ['MO', 'WE', 'FR']
|
|
152
|
+
timeSlots: [
|
|
153
|
+
{ start: '09:00', end: '12:00' },
|
|
154
|
+
{ start: '14:00', end: '17:00' }
|
|
155
|
+
],
|
|
156
|
+
price_cents: 15000,
|
|
157
|
+
description: 'Weekly therapy sessions',
|
|
158
|
+
timezone: 'America/New_York',
|
|
159
|
+
providerIds: ['provider_123'],
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
##### Create a Daily Recurring Offering
|
|
164
|
+
|
|
165
|
+
Creates a daily recurring offering with time slots:
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
const offering = await client.offerings.createRecurringDaily({
|
|
169
|
+
name: 'Daily Consultation',
|
|
170
|
+
duration_minutes: 30,
|
|
171
|
+
timeSlots: [
|
|
172
|
+
{ start: '09:00', end: '12:00' },
|
|
173
|
+
{ start: '14:00', end: '17:00' }
|
|
174
|
+
],
|
|
175
|
+
price_cents: 5000,
|
|
176
|
+
description: 'Daily consultation slots',
|
|
177
|
+
timezone: 'America/New_York',
|
|
178
|
+
providerIds: ['provider_123'],
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**When to use helper methods vs. full API:**
|
|
183
|
+
- Use `createSimple()` for basic offerings that rely on provider availability schedules
|
|
184
|
+
- Use `createRecurringWeekly()` or `createRecurringDaily()` for recurring offerings with fixed time slots
|
|
185
|
+
- Use `create()` directly when you need advanced features like custom recurrence intervals, monthly/yearly patterns, windowed modes, or other complex configurations
|
|
186
|
+
|
|
187
|
+
### Customers
|
|
188
|
+
|
|
189
|
+
#### List customers
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
const customers = await client.customers.list({
|
|
193
|
+
q: 'john@example.com', // Optional: search by name/email/phone
|
|
194
|
+
providerId: 'provider_123', // Optional: filter by provider
|
|
195
|
+
page: 1,
|
|
196
|
+
pageSize: 50,
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### Get a customer
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
const customer = await client.customers.get('customer_123');
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### Create a customer
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
const customer = await client.customers.create({
|
|
210
|
+
name: 'John Doe',
|
|
211
|
+
email: 'john@example.com',
|
|
212
|
+
phone: '+1234567890', // Optional
|
|
213
|
+
userId: 'user_123', // Optional: link to internal user
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Note: If a customer with the same email already exists, they will be merged/updated.
|
|
218
|
+
|
|
219
|
+
#### Get customer history
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
const history = await client.customers.getHistory('customer_123');
|
|
223
|
+
// Returns analytics, booking history, favorite providers, etc.
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Providers
|
|
227
|
+
|
|
228
|
+
#### List providers
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
const providers = await client.providers.list({
|
|
232
|
+
query: 'Dr. Smith', // Optional: search term
|
|
233
|
+
page: 1,
|
|
234
|
+
pageSize: 20,
|
|
235
|
+
});
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
#### Get a provider
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
const provider = await client.providers.get('provider_123');
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
#### Create a provider
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
const provider = await client.providers.create({
|
|
248
|
+
name: 'Dr. Jane Smith',
|
|
249
|
+
email: 'jane@example.com',
|
|
250
|
+
phone: '+1234567890', // Optional
|
|
251
|
+
bio: 'Licensed therapist with 10 years of experience', // Optional
|
|
252
|
+
userId: 'user_123', // Optional: link to internal user
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Calendar
|
|
257
|
+
|
|
258
|
+
#### Get calendar events
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
const events = await client.calendar.getEvents({
|
|
262
|
+
providerId: 'provider_123', // Optional
|
|
263
|
+
start: '2024-01-01T00:00:00Z', // Optional: start date
|
|
264
|
+
end: '2024-01-31T23:59:59Z', // Optional: end date
|
|
265
|
+
});
|
|
266
|
+
// Returns both bookings and events combined
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Analytics
|
|
270
|
+
|
|
271
|
+
#### Get revenue analytics
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
const revenue = await client.analytics.getRevenue({
|
|
275
|
+
providerId: 'provider_123', // Optional
|
|
276
|
+
startDate: '2024-01-01T00:00:00Z', // Optional
|
|
277
|
+
endDate: '2024-01-31T23:59:59Z', // Optional
|
|
278
|
+
groupBy: 'day', // Optional: 'day' | 'week' | 'month' | 'offering' | 'provider'
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### Get payouts
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
const payouts = await client.analytics.getPayouts({
|
|
286
|
+
providerId: 'provider_123', // Optional
|
|
287
|
+
startDate: '2024-01-01T00:00:00Z', // Optional
|
|
288
|
+
endDate: '2024-01-31T23:59:59Z', // Optional
|
|
289
|
+
customerId: 'customer_123', // Optional
|
|
290
|
+
});
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Availability
|
|
294
|
+
|
|
295
|
+
#### Get available slots
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// Enhanced version with offeringId and limit support
|
|
299
|
+
const availability = await client.availability.getSlots({
|
|
300
|
+
providerId: 'provider_123', // Optional if offeringId provided
|
|
301
|
+
offeringId: 'offering_123', // Optional
|
|
302
|
+
start: '2024-01-15T00:00:00Z',
|
|
303
|
+
end: '2024-01-22T23:59:59Z',
|
|
304
|
+
limit: 50, // Optional: max number of slots
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// Or use the original format for backward compatibility
|
|
308
|
+
const availability2 = await client.availability.getSlots({
|
|
309
|
+
providerId: 'provider_123',
|
|
310
|
+
startDate: '2024-01-15T00:00:00Z',
|
|
311
|
+
endDate: '2024-01-22T23:59:59Z',
|
|
312
|
+
});
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### Get availability schedules
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
const schedules = await client.availability.getSchedules({
|
|
319
|
+
providerId: 'provider_123', // Optional
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
#### Check specific time availability
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
const isAvailable = await client.availability.check({
|
|
327
|
+
providerId: 'provider_123',
|
|
328
|
+
startTime: '2024-01-15T10:00:00Z',
|
|
329
|
+
duration: 30, // minutes
|
|
330
|
+
});
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Error Handling
|
|
334
|
+
|
|
335
|
+
The SDK throws typed errors for different scenarios:
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
import {
|
|
339
|
+
AevumError,
|
|
340
|
+
AevumAPIError,
|
|
341
|
+
AevumAuthenticationError,
|
|
342
|
+
AevumValidationError,
|
|
343
|
+
AevumNotFoundError,
|
|
344
|
+
} from '@aevum/sdk';
|
|
345
|
+
|
|
346
|
+
try {
|
|
347
|
+
const booking = await client.bookings.get('invalid_id');
|
|
348
|
+
} catch (error) {
|
|
349
|
+
if (error instanceof AevumNotFoundError) {
|
|
350
|
+
console.log('Booking not found');
|
|
351
|
+
} else if (error instanceof AevumAuthenticationError) {
|
|
352
|
+
console.log('Invalid API key');
|
|
353
|
+
} else if (error instanceof AevumValidationError) {
|
|
354
|
+
console.log('Validation error:', error.issues);
|
|
355
|
+
} else if (error instanceof AevumAPIError) {
|
|
356
|
+
console.log('API error:', error.message, error.status);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## TypeScript Support
|
|
362
|
+
|
|
363
|
+
The SDK is fully typed with TypeScript. All methods include type definitions for parameters and return values, providing autocomplete and type checking.
|
|
364
|
+
|
|
365
|
+
All types are exported for your convenience:
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
import type {
|
|
369
|
+
Booking,
|
|
370
|
+
Offering,
|
|
371
|
+
Customer,
|
|
372
|
+
Provider,
|
|
373
|
+
CalendarEvent,
|
|
374
|
+
RevenueResponse,
|
|
375
|
+
PayoutsResponse,
|
|
376
|
+
// ... and many more
|
|
377
|
+
} from '@aevum/sdk';
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## Migration Guide (from Custom Client)
|
|
381
|
+
|
|
382
|
+
If you're migrating from a custom Aevum client implementation (like mendbloom's), here's how to update:
|
|
383
|
+
|
|
384
|
+
### Before (Custom Client)
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
import { AevumClient } from '@/lib/aevum/client';
|
|
388
|
+
|
|
389
|
+
const client = new AevumClient(apiKey, orgId);
|
|
390
|
+
const offerings = await client.getOfferings({ eventId: 'event_123' });
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### After (SDK)
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
import { AevumClient } from '@aevum/sdk';
|
|
397
|
+
|
|
398
|
+
const client = new AevumClient({ apiKey });
|
|
399
|
+
const offerings = await client.offerings.list({ eventId: 'event_123' });
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### Key Changes
|
|
403
|
+
|
|
404
|
+
1. **Installation**: `npm install @aevum/sdk`
|
|
405
|
+
2. **Initialization**: No need to pass `orgId` - it's resolved automatically
|
|
406
|
+
3. **Method Names**: Use namespaced methods (e.g., `client.offerings.list()` instead of `client.getOfferings()`)
|
|
407
|
+
4. **Error Handling**: Use SDK error classes instead of generic errors
|
|
408
|
+
5. **Types**: Import types from SDK instead of defining your own
|
|
409
|
+
|
|
410
|
+
### Method Mapping
|
|
411
|
+
|
|
412
|
+
| Custom Client | SDK |
|
|
413
|
+
|--------------|-----|
|
|
414
|
+
| `client.getOfferings()` | `client.offerings.list()` |
|
|
415
|
+
| `client.getOffering(id)` | `client.offerings.get(id)` |
|
|
416
|
+
| `client.createOffering()` | `client.offerings.create()` |
|
|
417
|
+
| `client.getCustomers()` | `client.customers.list()` |
|
|
418
|
+
| `client.getCustomer(id)` | `client.customers.get(id)` |
|
|
419
|
+
| `client.createCustomer()` | `client.customers.create()` |
|
|
420
|
+
| `client.getProviders()` | `client.providers.list()` |
|
|
421
|
+
| `client.createProvider()` | `client.providers.create()` |
|
|
422
|
+
| `client.getCalendarEvents()` | `client.calendar.getEvents()` |
|
|
423
|
+
| `client.getRevenue()` | `client.analytics.getRevenue()` |
|
|
424
|
+
| `client.getPayouts()` | `client.analytics.getPayouts()` |
|
|
425
|
+
| `client.getAvailabilitySchedules()` | `client.availability.getSchedules()` |
|
|
426
|
+
| `client.getAvailabilitySlots()` | `client.availability.getSlots()` |
|
|
427
|
+
| `client.rescheduleBooking()` | `client.bookings.reschedule()` |
|
|
428
|
+
|
|
429
|
+
## Requirements
|
|
430
|
+
|
|
431
|
+
- Node.js 18+ or modern browser with fetch support
|
|
432
|
+
- Valid Aevum API key
|
|
433
|
+
|
|
434
|
+
## License
|
|
435
|
+
|
|
436
|
+
ISC
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AevumClient } from './client';
|
|
2
|
+
import type { GetRevenueParams, RevenueResponse, GetPayoutsParams, PayoutsResponse } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Analytics API methods
|
|
5
|
+
*/
|
|
6
|
+
export declare class AnalyticsAPI {
|
|
7
|
+
private client;
|
|
8
|
+
constructor(client: AevumClient);
|
|
9
|
+
/**
|
|
10
|
+
* Get revenue analytics
|
|
11
|
+
*/
|
|
12
|
+
getRevenue(params?: GetRevenueParams): Promise<RevenueResponse>;
|
|
13
|
+
/**
|
|
14
|
+
* Get payouts (revenue from confirmed bookings)
|
|
15
|
+
*/
|
|
16
|
+
getPayouts(params?: GetPayoutsParams): Promise<PayoutsResponse>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics API methods
|
|
3
|
+
*/
|
|
4
|
+
export class AnalyticsAPI {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Get revenue analytics
|
|
10
|
+
*/
|
|
11
|
+
async getRevenue(params) {
|
|
12
|
+
const query = {};
|
|
13
|
+
if (params?.providerId) {
|
|
14
|
+
query.providerId = params.providerId;
|
|
15
|
+
}
|
|
16
|
+
if (params?.startDate) {
|
|
17
|
+
query.startDate = params.startDate;
|
|
18
|
+
}
|
|
19
|
+
if (params?.endDate) {
|
|
20
|
+
query.endDate = params.endDate;
|
|
21
|
+
}
|
|
22
|
+
if (params?.groupBy) {
|
|
23
|
+
query.groupBy = params.groupBy;
|
|
24
|
+
}
|
|
25
|
+
return this.client.request('GET', '/api/v1/orgs/{orgId}/analytics/revenue', { query });
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get payouts (revenue from confirmed bookings)
|
|
29
|
+
*/
|
|
30
|
+
async getPayouts(params) {
|
|
31
|
+
const query = {};
|
|
32
|
+
if (params?.providerId) {
|
|
33
|
+
query.providerId = params.providerId;
|
|
34
|
+
}
|
|
35
|
+
if (params?.startDate) {
|
|
36
|
+
query.startDate = params.startDate;
|
|
37
|
+
}
|
|
38
|
+
if (params?.endDate) {
|
|
39
|
+
query.endDate = params.endDate;
|
|
40
|
+
}
|
|
41
|
+
if (params?.customerId) {
|
|
42
|
+
query.customerId = params.customerId;
|
|
43
|
+
}
|
|
44
|
+
return this.client.request('GET', '/api/v1/orgs/{orgId}/payouts', { query });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AevumClient } from './client';
|
|
2
|
+
import type { GetSlotsParams, GetSlotsResponse, CheckAvailabilityParams, CheckAvailabilityResponse, GetAvailabilitySchedulesParams, AvailabilitySchedule, GetAvailabilitySlotsParams } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Availability API methods
|
|
5
|
+
*/
|
|
6
|
+
export declare class AvailabilityAPI {
|
|
7
|
+
private client;
|
|
8
|
+
constructor(client: AevumClient);
|
|
9
|
+
/**
|
|
10
|
+
* Get available time slots for a provider within a date range
|
|
11
|
+
* Enhanced version that supports offeringId and limit
|
|
12
|
+
*/
|
|
13
|
+
getSlots(params: GetSlotsParams | GetAvailabilitySlotsParams): Promise<GetSlotsResponse>;
|
|
14
|
+
/**
|
|
15
|
+
* Get availability schedules
|
|
16
|
+
*/
|
|
17
|
+
getSchedules(params?: GetAvailabilitySchedulesParams): Promise<AvailabilitySchedule[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a specific time slot is available
|
|
20
|
+
* This is a client-side implementation that uses getSlots()
|
|
21
|
+
*/
|
|
22
|
+
check(params: CheckAvailabilityParams): Promise<CheckAvailabilityResponse>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Availability API methods
|
|
3
|
+
*/
|
|
4
|
+
export class AvailabilityAPI {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Get available time slots for a provider within a date range
|
|
10
|
+
* Enhanced version that supports offeringId and limit
|
|
11
|
+
*/
|
|
12
|
+
async getSlots(params) {
|
|
13
|
+
const query = {};
|
|
14
|
+
// Support both old and new parameter formats
|
|
15
|
+
if ('providerId' in params && params.providerId) {
|
|
16
|
+
query.providerId = params.providerId;
|
|
17
|
+
}
|
|
18
|
+
if ('offeringId' in params && params.offeringId) {
|
|
19
|
+
query.offeringId = params.offeringId;
|
|
20
|
+
}
|
|
21
|
+
if ('start' in params && params.start) {
|
|
22
|
+
query.start = params.start;
|
|
23
|
+
}
|
|
24
|
+
else if ('startDate' in params && params.startDate) {
|
|
25
|
+
query.start = params.startDate;
|
|
26
|
+
}
|
|
27
|
+
if ('end' in params && params.end) {
|
|
28
|
+
query.end = params.end;
|
|
29
|
+
}
|
|
30
|
+
else if ('endDate' in params && params.endDate) {
|
|
31
|
+
query.end = params.endDate;
|
|
32
|
+
}
|
|
33
|
+
if ('limit' in params && params.limit !== undefined) {
|
|
34
|
+
query.limit = params.limit;
|
|
35
|
+
}
|
|
36
|
+
// For backward compatibility with GetSlotsParams
|
|
37
|
+
if ('startDate' in params && 'endDate' in params) {
|
|
38
|
+
if (!params.startDate || !params.endDate) {
|
|
39
|
+
throw new Error('startDate and endDate are required');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (!query.start || !query.end) {
|
|
43
|
+
throw new Error('start/startDate and end/endDate are required');
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
return await this.client.request('GET', '/api/v1/orgs/{orgId}/availability/slots', { query });
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
// Handle 404 gracefully - endpoint might not exist yet
|
|
50
|
+
if (error?.status === 404 || error?.message?.includes('404')) {
|
|
51
|
+
console.warn('Availability slots endpoint not found, returning empty slots');
|
|
52
|
+
return { slots: [] };
|
|
53
|
+
}
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get availability schedules
|
|
59
|
+
*/
|
|
60
|
+
async getSchedules(params) {
|
|
61
|
+
const query = {};
|
|
62
|
+
if (params?.providerId) {
|
|
63
|
+
query.providerId = params.providerId;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
const response = await this.client.request('GET', '/api/v1/orgs/{orgId}/availability/schedules', { query });
|
|
67
|
+
return response || [];
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
// Handle 404 gracefully - endpoint might not exist yet
|
|
71
|
+
if (error?.status === 404 || error?.message?.includes('404')) {
|
|
72
|
+
console.warn('Availability schedules endpoint not found, returning empty array');
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Check if a specific time slot is available
|
|
80
|
+
* This is a client-side implementation that uses getSlots()
|
|
81
|
+
*/
|
|
82
|
+
async check(params) {
|
|
83
|
+
const { providerId, startTime, duration } = params;
|
|
84
|
+
// Parse start time
|
|
85
|
+
const start = new Date(startTime);
|
|
86
|
+
if (isNaN(start.getTime())) {
|
|
87
|
+
throw new Error('Invalid startTime format. Expected ISO 8601 datetime with timezone');
|
|
88
|
+
}
|
|
89
|
+
// Calculate end time
|
|
90
|
+
const end = new Date(start.getTime() + duration * 60 * 1000);
|
|
91
|
+
// Get slots for a window around the requested time (1 day before and after)
|
|
92
|
+
const windowStart = new Date(start.getTime() - 24 * 60 * 60 * 1000);
|
|
93
|
+
const windowEnd = new Date(end.getTime() + 24 * 60 * 60 * 1000);
|
|
94
|
+
// Format as ISO strings with timezone
|
|
95
|
+
const startDate = windowStart.toISOString();
|
|
96
|
+
const endDate = windowEnd.toISOString();
|
|
97
|
+
// Get available slots
|
|
98
|
+
const { slots } = await this.getSlots({
|
|
99
|
+
providerId,
|
|
100
|
+
startDate,
|
|
101
|
+
endDate,
|
|
102
|
+
});
|
|
103
|
+
// Check if requested time falls within any available slot
|
|
104
|
+
const requestedStart = start.getTime();
|
|
105
|
+
const requestedEnd = end.getTime();
|
|
106
|
+
const isAvailable = slots.some((slot) => {
|
|
107
|
+
const slotStart = new Date(slot.start_time_utc).getTime();
|
|
108
|
+
const slotEnd = new Date(slot.end_time_utc).getTime();
|
|
109
|
+
// Check if requested time is completely within the slot
|
|
110
|
+
return requestedStart >= slotStart && requestedEnd <= slotEnd;
|
|
111
|
+
});
|
|
112
|
+
return { available: isAvailable };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AevumClient } from './client';
|
|
2
|
+
import type { Booking, CreateBookingParams, ListBookingsParams, ListBookingsResponse, RescheduleBookingParams } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Bookings API methods
|
|
5
|
+
*/
|
|
6
|
+
export declare class BookingsAPI {
|
|
7
|
+
private client;
|
|
8
|
+
constructor(client: AevumClient);
|
|
9
|
+
/**
|
|
10
|
+
* Create a new booking
|
|
11
|
+
*/
|
|
12
|
+
create(params: CreateBookingParams): Promise<Booking>;
|
|
13
|
+
/**
|
|
14
|
+
* Get a booking by ID
|
|
15
|
+
*/
|
|
16
|
+
get(bookingId: string): Promise<Booking>;
|
|
17
|
+
/**
|
|
18
|
+
* List bookings with optional filters
|
|
19
|
+
*/
|
|
20
|
+
list(params?: ListBookingsParams): Promise<ListBookingsResponse>;
|
|
21
|
+
/**
|
|
22
|
+
* Cancel a booking
|
|
23
|
+
*/
|
|
24
|
+
cancel(bookingId: string, reason?: string): Promise<Booking>;
|
|
25
|
+
/**
|
|
26
|
+
* Reschedule a booking
|
|
27
|
+
*/
|
|
28
|
+
reschedule(bookingId: string, params: RescheduleBookingParams): Promise<Booking>;
|
|
29
|
+
}
|