@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/dist/bookings.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bookings API methods
|
|
3
|
+
*/
|
|
4
|
+
export class BookingsAPI {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Create a new booking
|
|
10
|
+
*/
|
|
11
|
+
async create(params) {
|
|
12
|
+
// Map SDK params to API format
|
|
13
|
+
const providerIds = params.providerIds || (params.providerId ? [params.providerId] : []);
|
|
14
|
+
const offeringIds = params.offeringIds || (params.offeringId ? [params.offeringId] : []);
|
|
15
|
+
if (providerIds.length === 0) {
|
|
16
|
+
throw new Error('At least one providerId or providerIds is required');
|
|
17
|
+
}
|
|
18
|
+
if (offeringIds.length === 0) {
|
|
19
|
+
throw new Error('At least one offeringId or offeringIds is required');
|
|
20
|
+
}
|
|
21
|
+
// Calculate endTime if not provided (assuming we can infer from offering duration)
|
|
22
|
+
// For now, require endTime to be provided
|
|
23
|
+
if (!params.endTime) {
|
|
24
|
+
throw new Error('endTime is required');
|
|
25
|
+
}
|
|
26
|
+
// Build request body
|
|
27
|
+
const body = {
|
|
28
|
+
providerIds,
|
|
29
|
+
offeringIds,
|
|
30
|
+
start_time: params.startTime,
|
|
31
|
+
end_time: params.endTime,
|
|
32
|
+
kind: params.kind || 'standard',
|
|
33
|
+
status: params.status || 'pending',
|
|
34
|
+
};
|
|
35
|
+
// Handle customer
|
|
36
|
+
if (params.customerId) {
|
|
37
|
+
body.customerId = params.customerId;
|
|
38
|
+
}
|
|
39
|
+
else if (params.customerEmail || params.customer) {
|
|
40
|
+
body.customer = {
|
|
41
|
+
email: params.customerEmail || params.customer?.email,
|
|
42
|
+
name: params.customer?.name,
|
|
43
|
+
phone: params.customer?.phone,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
throw new Error('Either customerId, customerEmail, or customer object is required');
|
|
48
|
+
}
|
|
49
|
+
// Add optional fields
|
|
50
|
+
if (params.price_cents !== undefined) {
|
|
51
|
+
body.price_cents = params.price_cents;
|
|
52
|
+
}
|
|
53
|
+
if (params.notes) {
|
|
54
|
+
body.notes = params.notes;
|
|
55
|
+
}
|
|
56
|
+
const response = await this.client.request('POST', '/api/v1/orgs/{orgId}/bookings', { body });
|
|
57
|
+
// The API returns a partial booking, so we need to fetch the full booking
|
|
58
|
+
if (response.id) {
|
|
59
|
+
return this.get(response.id);
|
|
60
|
+
}
|
|
61
|
+
return response;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get a booking by ID
|
|
65
|
+
*/
|
|
66
|
+
async get(bookingId) {
|
|
67
|
+
return this.client.request('GET', `/api/v1/orgs/{orgId}/bookings/${bookingId}`);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* List bookings with optional filters
|
|
71
|
+
*/
|
|
72
|
+
async list(params) {
|
|
73
|
+
const query = {};
|
|
74
|
+
if (params?.status) {
|
|
75
|
+
query.status = params.status;
|
|
76
|
+
}
|
|
77
|
+
if (params?.providerId) {
|
|
78
|
+
query.providerId = params.providerId;
|
|
79
|
+
}
|
|
80
|
+
if (params?.customerId) {
|
|
81
|
+
query.customerId = params.customerId;
|
|
82
|
+
}
|
|
83
|
+
if (params?.startDate) {
|
|
84
|
+
query.start = params.startDate;
|
|
85
|
+
}
|
|
86
|
+
if (params?.endDate) {
|
|
87
|
+
query.end = params.endDate;
|
|
88
|
+
}
|
|
89
|
+
if (params?.page !== undefined) {
|
|
90
|
+
query.page = params.page;
|
|
91
|
+
}
|
|
92
|
+
if (params?.pageSize !== undefined) {
|
|
93
|
+
query.pageSize = params.pageSize;
|
|
94
|
+
}
|
|
95
|
+
return this.client.request('GET', '/api/v1/orgs/{orgId}/bookings', { query });
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Cancel a booking
|
|
99
|
+
*/
|
|
100
|
+
async cancel(bookingId, reason) {
|
|
101
|
+
const body = {};
|
|
102
|
+
if (reason) {
|
|
103
|
+
body.reason = reason;
|
|
104
|
+
}
|
|
105
|
+
await this.client.request('PATCH', `/api/v1/orgs/{orgId}/bookings/${bookingId}/cancel`, { body });
|
|
106
|
+
// Return updated booking
|
|
107
|
+
return this.get(bookingId);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Reschedule a booking
|
|
111
|
+
*/
|
|
112
|
+
async reschedule(bookingId, params) {
|
|
113
|
+
const body = {
|
|
114
|
+
start_time: params.start_time,
|
|
115
|
+
end_time: params.end_time,
|
|
116
|
+
sendNotification: params.sendNotification ?? false,
|
|
117
|
+
};
|
|
118
|
+
await this.client.request('PATCH', `/api/v1/orgs/{orgId}/bookings/${bookingId}/reschedule`, { body });
|
|
119
|
+
// Return updated booking
|
|
120
|
+
return this.get(bookingId);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AevumClient } from './client';
|
|
2
|
+
import type { GetCalendarEventsParams, GetCalendarEventsResponse } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Calendar API methods
|
|
5
|
+
*/
|
|
6
|
+
export declare class CalendarAPI {
|
|
7
|
+
private client;
|
|
8
|
+
constructor(client: AevumClient);
|
|
9
|
+
/**
|
|
10
|
+
* Get calendar events (bookings and events) for a date range
|
|
11
|
+
*/
|
|
12
|
+
getEvents(params?: GetCalendarEventsParams): Promise<GetCalendarEventsResponse>;
|
|
13
|
+
}
|
package/dist/calendar.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calendar API methods
|
|
3
|
+
*/
|
|
4
|
+
export class CalendarAPI {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Get calendar events (bookings and events) for a date range
|
|
10
|
+
*/
|
|
11
|
+
async getEvents(params) {
|
|
12
|
+
const orgId = await this.client.resolveOrgId();
|
|
13
|
+
// Get bookings for calendar
|
|
14
|
+
const bookingsQuery = {};
|
|
15
|
+
if (params?.providerId) {
|
|
16
|
+
bookingsQuery.providerId = params.providerId;
|
|
17
|
+
}
|
|
18
|
+
if (params?.start) {
|
|
19
|
+
bookingsQuery.start = params.start;
|
|
20
|
+
}
|
|
21
|
+
if (params?.end) {
|
|
22
|
+
bookingsQuery.end = params.end;
|
|
23
|
+
}
|
|
24
|
+
const bookings = await this.client.request('GET', '/api/v1/orgs/{orgId}/bookings', {
|
|
25
|
+
query: bookingsQuery,
|
|
26
|
+
});
|
|
27
|
+
// Get events for calendar
|
|
28
|
+
const eventsQuery = {};
|
|
29
|
+
if (params?.providerId) {
|
|
30
|
+
eventsQuery.providerId = params.providerId;
|
|
31
|
+
}
|
|
32
|
+
if (params?.start) {
|
|
33
|
+
eventsQuery.start = params.start;
|
|
34
|
+
}
|
|
35
|
+
if (params?.end) {
|
|
36
|
+
eventsQuery.end = params.end;
|
|
37
|
+
}
|
|
38
|
+
let events = [];
|
|
39
|
+
try {
|
|
40
|
+
const eventsResponse = await this.client.request('GET', `/api/v1/orgs/${orgId}/events`, { query: eventsQuery });
|
|
41
|
+
// Handle paginated response - extract events/offerings array
|
|
42
|
+
if (Array.isArray(eventsResponse)) {
|
|
43
|
+
events = eventsResponse;
|
|
44
|
+
}
|
|
45
|
+
else if (eventsResponse?.events) {
|
|
46
|
+
events = eventsResponse.events;
|
|
47
|
+
}
|
|
48
|
+
else if (eventsResponse?.offerings) {
|
|
49
|
+
// Events endpoint returns 'offerings' property
|
|
50
|
+
events = eventsResponse.offerings;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
events = [];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
// Events endpoint might not be available, continue without it
|
|
58
|
+
console.warn('Failed to fetch events:', error);
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
bookings: bookings.bookings || [],
|
|
62
|
+
events: events || [],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { AvailabilityAPI } from './availability';
|
|
2
|
+
import { BookingsAPI } from './bookings';
|
|
3
|
+
import { OfferingsAPI } from './offerings';
|
|
4
|
+
import { CustomersAPI } from './customers';
|
|
5
|
+
import { ProvidersAPI } from './providers';
|
|
6
|
+
import { CalendarAPI } from './calendar';
|
|
7
|
+
import { AnalyticsAPI } from './analytics';
|
|
8
|
+
import type { AevumClientConfig } from './types';
|
|
9
|
+
/**
|
|
10
|
+
* Main client class for interacting with the Aevum API
|
|
11
|
+
*/
|
|
12
|
+
export declare class AevumClient {
|
|
13
|
+
private readonly apiKey;
|
|
14
|
+
private readonly baseUrl;
|
|
15
|
+
private orgId;
|
|
16
|
+
private orgIdPromise;
|
|
17
|
+
readonly bookings: BookingsAPI;
|
|
18
|
+
readonly availability: AvailabilityAPI;
|
|
19
|
+
readonly offerings: OfferingsAPI;
|
|
20
|
+
readonly customers: CustomersAPI;
|
|
21
|
+
readonly providers: ProvidersAPI;
|
|
22
|
+
readonly calendar: CalendarAPI;
|
|
23
|
+
readonly analytics: AnalyticsAPI;
|
|
24
|
+
constructor(config: AevumClientConfig);
|
|
25
|
+
/**
|
|
26
|
+
* Resolve organization ID from API key (cached after first call)
|
|
27
|
+
*/
|
|
28
|
+
resolveOrgId(): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Internal method to fetch orgId from API
|
|
31
|
+
*/
|
|
32
|
+
private _fetchOrgId;
|
|
33
|
+
/**
|
|
34
|
+
* Make an authenticated HTTP request to the API
|
|
35
|
+
*/
|
|
36
|
+
request<T>(method: string, path: string, options?: {
|
|
37
|
+
body?: unknown;
|
|
38
|
+
query?: Record<string, string | number | undefined>;
|
|
39
|
+
}): Promise<T>;
|
|
40
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// packages/sdk/src/client.ts
|
|
2
|
+
import { AvailabilityAPI } from './availability';
|
|
3
|
+
import { BookingsAPI } from './bookings';
|
|
4
|
+
import { OfferingsAPI } from './offerings';
|
|
5
|
+
import { CustomersAPI } from './customers';
|
|
6
|
+
import { ProvidersAPI } from './providers';
|
|
7
|
+
import { CalendarAPI } from './calendar';
|
|
8
|
+
import { AnalyticsAPI } from './analytics';
|
|
9
|
+
import { AevumAPIError, AevumAuthenticationError, AevumNotFoundError, AevumValidationError, } from './errors';
|
|
10
|
+
/**
|
|
11
|
+
* Main client class for interacting with the Aevum API
|
|
12
|
+
*/
|
|
13
|
+
export class AevumClient {
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.orgId = null;
|
|
16
|
+
this.orgIdPromise = null;
|
|
17
|
+
if (!config.apiKey) {
|
|
18
|
+
throw new Error('API key is required');
|
|
19
|
+
}
|
|
20
|
+
this.apiKey = config.apiKey;
|
|
21
|
+
this.baseUrl = config.baseUrl || 'https://api.withaevum.com';
|
|
22
|
+
// Set orgId if provided in config (avoids extra API call)
|
|
23
|
+
if (config.orgId) {
|
|
24
|
+
this.orgId = config.orgId;
|
|
25
|
+
}
|
|
26
|
+
// Initialize API namespaces
|
|
27
|
+
this.bookings = new BookingsAPI(this);
|
|
28
|
+
this.availability = new AvailabilityAPI(this);
|
|
29
|
+
this.offerings = new OfferingsAPI(this);
|
|
30
|
+
this.customers = new CustomersAPI(this);
|
|
31
|
+
this.providers = new ProvidersAPI(this);
|
|
32
|
+
this.calendar = new CalendarAPI(this);
|
|
33
|
+
this.analytics = new AnalyticsAPI(this);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve organization ID from API key (cached after first call)
|
|
37
|
+
*/
|
|
38
|
+
async resolveOrgId() {
|
|
39
|
+
// Return cached orgId if available
|
|
40
|
+
if (this.orgId) {
|
|
41
|
+
return this.orgId;
|
|
42
|
+
}
|
|
43
|
+
// Return existing promise if resolution is in progress
|
|
44
|
+
if (this.orgIdPromise) {
|
|
45
|
+
return this.orgIdPromise;
|
|
46
|
+
}
|
|
47
|
+
// Start resolution
|
|
48
|
+
this.orgIdPromise = this._fetchOrgId();
|
|
49
|
+
this.orgId = await this.orgIdPromise;
|
|
50
|
+
return this.orgId;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Internal method to fetch orgId from API
|
|
54
|
+
*/
|
|
55
|
+
async _fetchOrgId() {
|
|
56
|
+
const response = await fetch(`${this.baseUrl}/api/v1/session/org-from-key`, {
|
|
57
|
+
method: 'GET',
|
|
58
|
+
headers: {
|
|
59
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
60
|
+
'Content-Type': 'application/json',
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
if (!response.ok) {
|
|
64
|
+
if (response.status === 401 || response.status === 403) {
|
|
65
|
+
throw new AevumAuthenticationError('Invalid or missing API key', response.status);
|
|
66
|
+
}
|
|
67
|
+
const errorText = await response.text().catch(() => '');
|
|
68
|
+
throw new AevumAPIError(`Failed to resolve organization ID: ${errorText}`, response.status);
|
|
69
|
+
}
|
|
70
|
+
const data = await response.json();
|
|
71
|
+
if (!data.orgId) {
|
|
72
|
+
throw new AevumAPIError('Invalid response: missing orgId', response.status);
|
|
73
|
+
}
|
|
74
|
+
return data.orgId;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Make an authenticated HTTP request to the API
|
|
78
|
+
*/
|
|
79
|
+
async request(method, path, options = {}) {
|
|
80
|
+
// Ensure orgId is resolved (will use cache if already resolved)
|
|
81
|
+
const orgId = await this.resolveOrgId();
|
|
82
|
+
// Replace {orgId} placeholder in path if present
|
|
83
|
+
const resolvedPath = path.replace('{orgId}', orgId);
|
|
84
|
+
// Build URL with query parameters
|
|
85
|
+
const url = new URL(resolvedPath, this.baseUrl);
|
|
86
|
+
if (options.query) {
|
|
87
|
+
Object.entries(options.query).forEach(([key, value]) => {
|
|
88
|
+
if (value !== undefined && value !== null) {
|
|
89
|
+
url.searchParams.append(key, String(value));
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Prepare headers
|
|
94
|
+
const headers = {
|
|
95
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
96
|
+
'Content-Type': 'application/json',
|
|
97
|
+
};
|
|
98
|
+
// Prepare request options
|
|
99
|
+
const requestOptions = {
|
|
100
|
+
method,
|
|
101
|
+
headers,
|
|
102
|
+
};
|
|
103
|
+
// Add body if present
|
|
104
|
+
if (options.body !== undefined) {
|
|
105
|
+
requestOptions.body = JSON.stringify(options.body);
|
|
106
|
+
}
|
|
107
|
+
// Make the request
|
|
108
|
+
const response = await fetch(url.toString(), requestOptions);
|
|
109
|
+
// Handle empty responses (204 No Content)
|
|
110
|
+
if (response.status === 204 ||
|
|
111
|
+
response.headers.get('content-length') === '0') {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
// Parse response body
|
|
115
|
+
const text = await response.text();
|
|
116
|
+
let data;
|
|
117
|
+
try {
|
|
118
|
+
data = text ? JSON.parse(text) : null;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
throw new AevumAPIError(`Invalid JSON response: ${text}`, response.status);
|
|
122
|
+
}
|
|
123
|
+
// Handle errors
|
|
124
|
+
if (!response.ok) {
|
|
125
|
+
const errorData = data;
|
|
126
|
+
if (response.status === 401 || response.status === 403) {
|
|
127
|
+
throw new AevumAuthenticationError(errorData.error || 'Authentication failed', response.status);
|
|
128
|
+
}
|
|
129
|
+
if (response.status === 404) {
|
|
130
|
+
throw new AevumNotFoundError(errorData.error || 'Resource not found');
|
|
131
|
+
}
|
|
132
|
+
if (response.status === 400) {
|
|
133
|
+
throw new AevumValidationError(errorData.error || 'Validation error', errorData.issues);
|
|
134
|
+
}
|
|
135
|
+
throw new AevumAPIError(errorData.error || `API request failed with status ${response.status}`, response.status, errorData.code, errorData.issues);
|
|
136
|
+
}
|
|
137
|
+
return data;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AevumClient } from './client';
|
|
2
|
+
import type { Customer, CreateCustomerParams, ListCustomersParams, ListCustomersResponse, CustomerHistoryResponse } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Customers API methods
|
|
5
|
+
*/
|
|
6
|
+
export declare class CustomersAPI {
|
|
7
|
+
private client;
|
|
8
|
+
constructor(client: AevumClient);
|
|
9
|
+
/**
|
|
10
|
+
* List customers for the organization
|
|
11
|
+
*/
|
|
12
|
+
list(params?: ListCustomersParams): Promise<ListCustomersResponse>;
|
|
13
|
+
/**
|
|
14
|
+
* Get a single customer by ID
|
|
15
|
+
*/
|
|
16
|
+
get(customerId: string): Promise<Customer>;
|
|
17
|
+
/**
|
|
18
|
+
* Create a new customer (or merge if email exists)
|
|
19
|
+
*/
|
|
20
|
+
create(params: CreateCustomerParams): Promise<Customer>;
|
|
21
|
+
/**
|
|
22
|
+
* Get customer booking history with analytics
|
|
23
|
+
*/
|
|
24
|
+
getHistory(customerId: string): Promise<CustomerHistoryResponse>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customers API methods
|
|
3
|
+
*/
|
|
4
|
+
export class CustomersAPI {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* List customers for the organization
|
|
10
|
+
*/
|
|
11
|
+
async list(params) {
|
|
12
|
+
const query = {};
|
|
13
|
+
if (params?.q) {
|
|
14
|
+
query.q = params.q;
|
|
15
|
+
}
|
|
16
|
+
if (params?.providerId) {
|
|
17
|
+
query.providerId = params.providerId;
|
|
18
|
+
}
|
|
19
|
+
if (params?.page !== undefined) {
|
|
20
|
+
query.page = params.page;
|
|
21
|
+
}
|
|
22
|
+
if (params?.pageSize !== undefined) {
|
|
23
|
+
query.pageSize = params.pageSize;
|
|
24
|
+
}
|
|
25
|
+
return this.client.request('GET', '/api/v1/orgs/{orgId}/customers', { query });
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get a single customer by ID
|
|
29
|
+
*/
|
|
30
|
+
async get(customerId) {
|
|
31
|
+
const response = await this.client.request('GET', `/api/v1/orgs/{orgId}/customers/${customerId}`);
|
|
32
|
+
return response.customer;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a new customer (or merge if email exists)
|
|
36
|
+
*/
|
|
37
|
+
async create(params) {
|
|
38
|
+
const body = {};
|
|
39
|
+
if (params.name !== undefined) {
|
|
40
|
+
body.name = params.name;
|
|
41
|
+
}
|
|
42
|
+
if (params.email !== undefined) {
|
|
43
|
+
body.email = params.email;
|
|
44
|
+
}
|
|
45
|
+
if (params.phone !== undefined) {
|
|
46
|
+
body.phone = params.phone;
|
|
47
|
+
}
|
|
48
|
+
if (params.userId !== undefined) {
|
|
49
|
+
body.userId = params.userId;
|
|
50
|
+
}
|
|
51
|
+
const response = await this.client.request('POST', '/api/v1/orgs/{orgId}/customers', { body });
|
|
52
|
+
return response.customer;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get customer booking history with analytics
|
|
56
|
+
*/
|
|
57
|
+
async getHistory(customerId) {
|
|
58
|
+
return this.client.request('GET', `/api/v1/orgs/{orgId}/customers/${customerId}/history`);
|
|
59
|
+
}
|
|
60
|
+
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all Aevum SDK errors
|
|
3
|
+
*/
|
|
4
|
+
export declare class AevumError extends Error {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Error thrown when an API request fails
|
|
9
|
+
*/
|
|
10
|
+
export declare class AevumAPIError extends AevumError {
|
|
11
|
+
readonly status: number;
|
|
12
|
+
readonly code?: string;
|
|
13
|
+
readonly issues?: Array<{
|
|
14
|
+
path: string[];
|
|
15
|
+
message: string;
|
|
16
|
+
}>;
|
|
17
|
+
constructor(message: string, status: number, code?: string, issues?: Array<{
|
|
18
|
+
path: string[];
|
|
19
|
+
message: string;
|
|
20
|
+
}>);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Error thrown for authentication failures (401, 403)
|
|
24
|
+
*/
|
|
25
|
+
export declare class AevumAuthenticationError extends AevumAPIError {
|
|
26
|
+
constructor(message: string, status?: number);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Error thrown for validation errors (400)
|
|
30
|
+
*/
|
|
31
|
+
export declare class AevumValidationError extends AevumAPIError {
|
|
32
|
+
constructor(message: string, issues?: Array<{
|
|
33
|
+
path: string[];
|
|
34
|
+
message: string;
|
|
35
|
+
}>);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Error thrown when a resource is not found (404)
|
|
39
|
+
*/
|
|
40
|
+
export declare class AevumNotFoundError extends AevumAPIError {
|
|
41
|
+
constructor(message?: string);
|
|
42
|
+
}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// packages/sdk/src/errors.ts
|
|
2
|
+
/**
|
|
3
|
+
* Base error class for all Aevum SDK errors
|
|
4
|
+
*/
|
|
5
|
+
export class AevumError extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'AevumError';
|
|
9
|
+
Object.setPrototypeOf(this, AevumError.prototype);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Error thrown when an API request fails
|
|
14
|
+
*/
|
|
15
|
+
export class AevumAPIError extends AevumError {
|
|
16
|
+
constructor(message, status, code, issues) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = 'AevumAPIError';
|
|
19
|
+
this.status = status;
|
|
20
|
+
this.code = code;
|
|
21
|
+
this.issues = issues;
|
|
22
|
+
Object.setPrototypeOf(this, AevumAPIError.prototype);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Error thrown for authentication failures (401, 403)
|
|
27
|
+
*/
|
|
28
|
+
export class AevumAuthenticationError extends AevumAPIError {
|
|
29
|
+
constructor(message, status = 401) {
|
|
30
|
+
super(message, status);
|
|
31
|
+
this.name = 'AevumAuthenticationError';
|
|
32
|
+
Object.setPrototypeOf(this, AevumAuthenticationError.prototype);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Error thrown for validation errors (400)
|
|
37
|
+
*/
|
|
38
|
+
export class AevumValidationError extends AevumAPIError {
|
|
39
|
+
constructor(message, issues) {
|
|
40
|
+
super(message, 400, 'validation_error', issues);
|
|
41
|
+
this.name = 'AevumValidationError';
|
|
42
|
+
Object.setPrototypeOf(this, AevumValidationError.prototype);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Error thrown when a resource is not found (404)
|
|
47
|
+
*/
|
|
48
|
+
export class AevumNotFoundError extends AevumAPIError {
|
|
49
|
+
constructor(message = 'Resource not found') {
|
|
50
|
+
super(message, 404, 'not_found');
|
|
51
|
+
this.name = 'AevumNotFoundError';
|
|
52
|
+
Object.setPrototypeOf(this, AevumNotFoundError.prototype);
|
|
53
|
+
}
|
|
54
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { AevumClient } from './client';
|
|
2
|
+
export { BookingsAPI } from './bookings';
|
|
3
|
+
export { OfferingsAPI } from './offerings';
|
|
4
|
+
export { CustomersAPI } from './customers';
|
|
5
|
+
export { ProvidersAPI } from './providers';
|
|
6
|
+
export { CalendarAPI } from './calendar';
|
|
7
|
+
export { AnalyticsAPI } from './analytics';
|
|
8
|
+
export { AvailabilityAPI } from './availability';
|
|
9
|
+
export * from './types';
|
|
10
|
+
export * from './errors';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// packages/sdk/src/index.ts
|
|
2
|
+
export { AevumClient } from './client';
|
|
3
|
+
export { BookingsAPI } from './bookings';
|
|
4
|
+
export { OfferingsAPI } from './offerings';
|
|
5
|
+
export { CustomersAPI } from './customers';
|
|
6
|
+
export { ProvidersAPI } from './providers';
|
|
7
|
+
export { CalendarAPI } from './calendar';
|
|
8
|
+
export { AnalyticsAPI } from './analytics';
|
|
9
|
+
export { AvailabilityAPI } from './availability';
|
|
10
|
+
export * from './types';
|
|
11
|
+
export * from './errors';
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { AevumClient } from './client';
|
|
2
|
+
import type { Offering, CreateOfferingParams, ListOfferingsParams, CreateSimpleOfferingParams, CreateRecurringWeeklyOfferingParams, CreateRecurringDailyOfferingParams, CreateSimpleOfferingEndpointParams } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Offerings API methods
|
|
5
|
+
*/
|
|
6
|
+
export declare class OfferingsAPI {
|
|
7
|
+
private client;
|
|
8
|
+
constructor(client: AevumClient);
|
|
9
|
+
/**
|
|
10
|
+
* List offerings for the organization
|
|
11
|
+
*/
|
|
12
|
+
list(params?: ListOfferingsParams): Promise<Offering[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Get a single offering by ID
|
|
15
|
+
*/
|
|
16
|
+
get(offeringId: string): Promise<Offering>;
|
|
17
|
+
/**
|
|
18
|
+
* Create a new offering
|
|
19
|
+
*/
|
|
20
|
+
create(params: CreateOfferingParams): Promise<Offering>;
|
|
21
|
+
/**
|
|
22
|
+
* Create a simple offering (basic 1:1 offering using provider availability schedules)
|
|
23
|
+
* This is the simplest way to create an offering - it uses provider availability
|
|
24
|
+
* instead of fixed times or recurrence patterns.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const offering = await client.offerings.createSimple({
|
|
29
|
+
* name: 'Therapy Session',
|
|
30
|
+
* duration_minutes: 60,
|
|
31
|
+
* price_cents: 15000,
|
|
32
|
+
* description: 'One-on-one therapy session',
|
|
33
|
+
* providerIds: [providerId]
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
createSimple(params: CreateSimpleOfferingParams): Promise<Offering>;
|
|
38
|
+
/**
|
|
39
|
+
* Create a weekly recurring offering with specific days and time slots
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const offering = await client.offerings.createRecurringWeekly({
|
|
44
|
+
* name: 'Weekly Therapy',
|
|
45
|
+
* duration_minutes: 60,
|
|
46
|
+
* days: ['monday', 'wednesday', 'friday'],
|
|
47
|
+
* timeSlots: [{ start: '09:00', end: '17:00' }],
|
|
48
|
+
* price_cents: 15000,
|
|
49
|
+
* providerIds: [providerId]
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
createRecurringWeekly(params: CreateRecurringWeeklyOfferingParams): Promise<Offering>;
|
|
54
|
+
/**
|
|
55
|
+
* Create a daily recurring offering with time slots
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const offering = await client.offerings.createRecurringDaily({
|
|
60
|
+
* name: 'Daily Consultation',
|
|
61
|
+
* duration_minutes: 30,
|
|
62
|
+
* timeSlots: [
|
|
63
|
+
* { start: '09:00', end: '12:00' },
|
|
64
|
+
* { start: '14:00', end: '17:00' }
|
|
65
|
+
* ],
|
|
66
|
+
* price_cents: 5000,
|
|
67
|
+
* providerIds: [providerId]
|
|
68
|
+
* });
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
createRecurringDaily(params: CreateRecurringDailyOfferingParams): Promise<Offering>;
|
|
72
|
+
/**
|
|
73
|
+
* Create an offering using the simplified endpoint
|
|
74
|
+
* This method calls the /simple endpoint which provides preset-based configuration
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* // Simple 1:1 offering
|
|
79
|
+
* const offering = await client.offerings.createFromSimple({
|
|
80
|
+
* name: 'Therapy Session',
|
|
81
|
+
* duration_minutes: 60,
|
|
82
|
+
* price_cents: 15000,
|
|
83
|
+
* preset: 'simple_1on1',
|
|
84
|
+
* provider_ids: [providerId]
|
|
85
|
+
* });
|
|
86
|
+
*
|
|
87
|
+
* // Weekly recurring
|
|
88
|
+
* const weeklyOffering = await client.offerings.createFromSimple({
|
|
89
|
+
* name: 'Weekly Therapy',
|
|
90
|
+
* duration_minutes: 60,
|
|
91
|
+
* preset: 'recurring_weekly',
|
|
92
|
+
* weekly_days: ['monday', 'wednesday'],
|
|
93
|
+
* weekly_time_slots: [{ start: '09:00', end: '17:00' }],
|
|
94
|
+
* price_cents: 15000,
|
|
95
|
+
* });
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
createFromSimple(params: CreateSimpleOfferingEndpointParams): Promise<Offering>;
|
|
99
|
+
}
|