@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.
@@ -0,0 +1,355 @@
1
+ /**
2
+ * Helper function to normalize day names
3
+ * Converts various formats (monday, MO, Monday) to standard weekday names
4
+ */
5
+ function normalizeDayName(day) {
6
+ const normalized = day.toLowerCase().trim();
7
+ const dayMap = {
8
+ 'sunday': 'sunday',
9
+ 'sun': 'sunday',
10
+ 'su': 'sunday',
11
+ 'monday': 'monday',
12
+ 'mon': 'monday',
13
+ 'mo': 'monday',
14
+ 'tuesday': 'tuesday',
15
+ 'tue': 'tuesday',
16
+ 'tu': 'tuesday',
17
+ 'wednesday': 'wednesday',
18
+ 'wed': 'wednesday',
19
+ 'we': 'wednesday',
20
+ 'thursday': 'thursday',
21
+ 'thu': 'thursday',
22
+ 'th': 'thursday',
23
+ 'friday': 'friday',
24
+ 'fri': 'friday',
25
+ 'fr': 'friday',
26
+ 'saturday': 'saturday',
27
+ 'sat': 'saturday',
28
+ 'sa': 'saturday',
29
+ };
30
+ return dayMap[normalized] || normalized;
31
+ }
32
+ /**
33
+ * Helper function to convert day name to repeat_on format (MO, TU, WE, etc.)
34
+ */
35
+ function dayToRepeatOn(day) {
36
+ const normalized = normalizeDayName(day);
37
+ const repeatOnMap = {
38
+ 'sunday': 'SU',
39
+ 'monday': 'MO',
40
+ 'tuesday': 'TU',
41
+ 'wednesday': 'WE',
42
+ 'thursday': 'TH',
43
+ 'friday': 'FR',
44
+ 'saturday': 'SA',
45
+ };
46
+ return repeatOnMap[normalized] || normalized.toUpperCase();
47
+ }
48
+ /**
49
+ * Offerings API methods
50
+ */
51
+ export class OfferingsAPI {
52
+ constructor(client) {
53
+ this.client = client;
54
+ }
55
+ /**
56
+ * List offerings for the organization
57
+ */
58
+ async list(params) {
59
+ const query = {};
60
+ if (params?.eventId) {
61
+ query.eventId = params.eventId;
62
+ }
63
+ if (params?.providerId) {
64
+ query.providerId = params.providerId;
65
+ }
66
+ const response = await this.client.request('GET', '/api/v1/orgs/{orgId}/offerings', { query });
67
+ return response || [];
68
+ }
69
+ /**
70
+ * Get a single offering by ID
71
+ */
72
+ async get(offeringId) {
73
+ const response = await this.client.request('GET', `/api/v1/orgs/{orgId}/offerings/${offeringId}`);
74
+ return response.offering;
75
+ }
76
+ /**
77
+ * Create a new offering
78
+ */
79
+ async create(params) {
80
+ const body = {
81
+ name: params.name,
82
+ };
83
+ if (params.description !== undefined) {
84
+ body.description = params.description;
85
+ }
86
+ if (params.price_cents !== undefined) {
87
+ body.price_cents = params.price_cents;
88
+ }
89
+ if (params.duration_minutes !== undefined) {
90
+ body.duration_minutes = params.duration_minutes;
91
+ }
92
+ if (params.timezone) {
93
+ body.timezone = params.timezone;
94
+ }
95
+ if (params.is_all_day !== undefined) {
96
+ body.is_all_day = params.is_all_day;
97
+ }
98
+ if (params.attendee_mode) {
99
+ body.attendee_mode = params.attendee_mode;
100
+ }
101
+ if (params.attendee_limit !== undefined) {
102
+ body.attendee_limit = params.attendee_limit;
103
+ }
104
+ if (params.customer) {
105
+ body.customer = params.customer;
106
+ }
107
+ if (params.status) {
108
+ body.status = params.status;
109
+ }
110
+ if (params.type) {
111
+ body.type = params.type;
112
+ }
113
+ if (params.time_mode) {
114
+ body.time_mode = params.time_mode;
115
+ }
116
+ if (params.start_time) {
117
+ body.start_time = params.start_time;
118
+ }
119
+ if (params.end_time) {
120
+ body.end_time = params.end_time;
121
+ }
122
+ if (params.session_count !== undefined) {
123
+ body.session_count = params.session_count;
124
+ }
125
+ if (params.recurrence_preset !== undefined) {
126
+ body.recurrence_preset = params.recurrence_preset;
127
+ }
128
+ if (params.recurrence_interval_count !== undefined) {
129
+ body.recurrence_interval_count = params.recurrence_interval_count;
130
+ }
131
+ if (params.recurrence_interval_unit) {
132
+ body.recurrence_interval_unit = params.recurrence_interval_unit;
133
+ }
134
+ if (params.recurrence_repeat_on !== undefined) {
135
+ body.recurrence_repeat_on = params.recurrence_repeat_on;
136
+ }
137
+ if (params.recurrence_end_mode !== undefined) {
138
+ body.recurrence_end_mode = params.recurrence_end_mode;
139
+ }
140
+ if (params.recurrence_end_date) {
141
+ body.recurrence_end_date = params.recurrence_end_date;
142
+ }
143
+ if (params.recurrence_end_count !== undefined) {
144
+ body.recurrence_end_count = params.recurrence_end_count;
145
+ }
146
+ if (params.override_price_cents !== undefined) {
147
+ body.override_price_cents = params.override_price_cents;
148
+ }
149
+ if (params.min_age !== undefined) {
150
+ body.min_age = params.min_age;
151
+ }
152
+ if (params.max_age !== undefined) {
153
+ body.max_age = params.max_age;
154
+ }
155
+ if (params.window_start_time) {
156
+ body.window_start_time = params.window_start_time;
157
+ }
158
+ if (params.window_end_time) {
159
+ body.window_end_time = params.window_end_time;
160
+ }
161
+ if (params.cadence_minutes !== undefined) {
162
+ body.cadence_minutes = params.cadence_minutes;
163
+ }
164
+ if (params.slot_days) {
165
+ body.slot_days = params.slot_days;
166
+ }
167
+ if (params.providerIds && params.providerIds.length > 0) {
168
+ body.providerIds = params.providerIds;
169
+ }
170
+ if (params.hours !== undefined) {
171
+ body.hours = params.hours;
172
+ }
173
+ if (params.weekly_hours !== undefined) {
174
+ body.weekly_hours = params.weekly_hours;
175
+ }
176
+ if (params.monthly_recurrence !== undefined) {
177
+ body.monthly_recurrence = params.monthly_recurrence;
178
+ }
179
+ const response = await this.client.request('POST', '/api/v1/orgs/{orgId}/offerings', { body });
180
+ return response.offering;
181
+ }
182
+ /**
183
+ * Create a simple offering (basic 1:1 offering using provider availability schedules)
184
+ * This is the simplest way to create an offering - it uses provider availability
185
+ * instead of fixed times or recurrence patterns.
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * const offering = await client.offerings.createSimple({
190
+ * name: 'Therapy Session',
191
+ * duration_minutes: 60,
192
+ * price_cents: 15000,
193
+ * description: 'One-on-one therapy session',
194
+ * providerIds: [providerId]
195
+ * });
196
+ * ```
197
+ */
198
+ async createSimple(params) {
199
+ return this.create({
200
+ name: params.name,
201
+ duration_minutes: params.duration_minutes,
202
+ price_cents: params.price_cents,
203
+ description: params.description,
204
+ timezone: params.timezone,
205
+ attendee_mode: '1:1',
206
+ is_all_day: false,
207
+ providerIds: params.providerIds,
208
+ // No recurrence_preset = uses provider availability schedules
209
+ });
210
+ }
211
+ /**
212
+ * Create a weekly recurring offering with specific days and time slots
213
+ *
214
+ * @example
215
+ * ```typescript
216
+ * const offering = await client.offerings.createRecurringWeekly({
217
+ * name: 'Weekly Therapy',
218
+ * duration_minutes: 60,
219
+ * days: ['monday', 'wednesday', 'friday'],
220
+ * timeSlots: [{ start: '09:00', end: '17:00' }],
221
+ * price_cents: 15000,
222
+ * providerIds: [providerId]
223
+ * });
224
+ * ```
225
+ */
226
+ async createRecurringWeekly(params) {
227
+ // Normalize day names and build weekly_hours object
228
+ const weekly_hours = {
229
+ sunday: [],
230
+ monday: [],
231
+ tuesday: [],
232
+ wednesday: [],
233
+ thursday: [],
234
+ friday: [],
235
+ saturday: [],
236
+ };
237
+ // Map days to weekly_hours format
238
+ const normalizedDays = params.days.map(normalizeDayName);
239
+ normalizedDays.forEach((day) => {
240
+ if (weekly_hours[day] !== undefined) {
241
+ weekly_hours[day] = params.timeSlots;
242
+ }
243
+ });
244
+ // Build recurrence_repeat_on string (MO,WE,FR format)
245
+ const repeatOn = normalizedDays
246
+ .map(dayToRepeatOn)
247
+ .filter(Boolean)
248
+ .join(',');
249
+ return this.create({
250
+ name: params.name,
251
+ duration_minutes: params.duration_minutes,
252
+ price_cents: params.price_cents,
253
+ description: params.description,
254
+ timezone: params.timezone,
255
+ attendee_mode: '1:1',
256
+ is_all_day: false,
257
+ recurrence_preset: 'weekly',
258
+ recurrence_repeat_on: repeatOn,
259
+ weekly_hours,
260
+ providerIds: params.providerIds,
261
+ });
262
+ }
263
+ /**
264
+ * Create a daily recurring offering with time slots
265
+ *
266
+ * @example
267
+ * ```typescript
268
+ * const offering = await client.offerings.createRecurringDaily({
269
+ * name: 'Daily Consultation',
270
+ * duration_minutes: 30,
271
+ * timeSlots: [
272
+ * { start: '09:00', end: '12:00' },
273
+ * { start: '14:00', end: '17:00' }
274
+ * ],
275
+ * price_cents: 5000,
276
+ * providerIds: [providerId]
277
+ * });
278
+ * ```
279
+ */
280
+ async createRecurringDaily(params) {
281
+ return this.create({
282
+ name: params.name,
283
+ duration_minutes: params.duration_minutes,
284
+ price_cents: params.price_cents,
285
+ description: params.description,
286
+ timezone: params.timezone,
287
+ attendee_mode: '1:1',
288
+ is_all_day: false,
289
+ recurrence_preset: 'daily',
290
+ hours: params.timeSlots,
291
+ providerIds: params.providerIds,
292
+ });
293
+ }
294
+ /**
295
+ * Create an offering using the simplified endpoint
296
+ * This method calls the /simple endpoint which provides preset-based configuration
297
+ *
298
+ * @example
299
+ * ```typescript
300
+ * // Simple 1:1 offering
301
+ * const offering = await client.offerings.createFromSimple({
302
+ * name: 'Therapy Session',
303
+ * duration_minutes: 60,
304
+ * price_cents: 15000,
305
+ * preset: 'simple_1on1',
306
+ * provider_ids: [providerId]
307
+ * });
308
+ *
309
+ * // Weekly recurring
310
+ * const weeklyOffering = await client.offerings.createFromSimple({
311
+ * name: 'Weekly Therapy',
312
+ * duration_minutes: 60,
313
+ * preset: 'recurring_weekly',
314
+ * weekly_days: ['monday', 'wednesday'],
315
+ * weekly_time_slots: [{ start: '09:00', end: '17:00' }],
316
+ * price_cents: 15000,
317
+ * });
318
+ * ```
319
+ */
320
+ async createFromSimple(params) {
321
+ const body = {
322
+ name: params.name,
323
+ duration_minutes: params.duration_minutes,
324
+ };
325
+ if (params.description !== undefined) {
326
+ body.description = params.description;
327
+ }
328
+ if (params.price_cents !== undefined) {
329
+ body.price_cents = params.price_cents;
330
+ }
331
+ if (params.timezone) {
332
+ body.timezone = params.timezone;
333
+ }
334
+ if (params.provider_ids && params.provider_ids.length > 0) {
335
+ body.provider_ids = params.provider_ids;
336
+ }
337
+ if (params.preset) {
338
+ body.preset = params.preset;
339
+ }
340
+ if (params.weekly_days && params.weekly_days.length > 0) {
341
+ body.weekly_days = params.weekly_days;
342
+ }
343
+ if (params.weekly_time_slots && params.weekly_time_slots.length > 0) {
344
+ body.weekly_time_slots = params.weekly_time_slots;
345
+ }
346
+ if (params.daily_time_slots && params.daily_time_slots.length > 0) {
347
+ body.daily_time_slots = params.daily_time_slots;
348
+ }
349
+ if (params.attendee_limit !== undefined) {
350
+ body.attendee_limit = params.attendee_limit;
351
+ }
352
+ const response = await this.client.request('POST', '/api/v1/orgs/{orgId}/offerings/simple', { body });
353
+ return response.offering;
354
+ }
355
+ }
@@ -0,0 +1,21 @@
1
+ import { AevumClient } from './client';
2
+ import type { Provider, CreateProviderParams, ListProvidersParams } from './types';
3
+ /**
4
+ * Providers API methods
5
+ */
6
+ export declare class ProvidersAPI {
7
+ private client;
8
+ constructor(client: AevumClient);
9
+ /**
10
+ * List providers for the organization
11
+ */
12
+ list(params?: ListProvidersParams): Promise<Provider[]>;
13
+ /**
14
+ * Get a single provider by ID
15
+ */
16
+ get(providerId: string): Promise<Provider>;
17
+ /**
18
+ * Create a new provider
19
+ */
20
+ create(params: CreateProviderParams): Promise<Provider>;
21
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Providers API methods
3
+ */
4
+ export class ProvidersAPI {
5
+ constructor(client) {
6
+ this.client = client;
7
+ }
8
+ /**
9
+ * List providers for the organization
10
+ */
11
+ async list(params) {
12
+ const query = {};
13
+ if (params?.query) {
14
+ query.search = params.query; // API uses 'search' not 'query'
15
+ }
16
+ if (params?.page !== undefined) {
17
+ query.page = params.page;
18
+ }
19
+ if (params?.pageSize !== undefined) {
20
+ query.pageSize = params.pageSize;
21
+ }
22
+ const response = await this.client.request('GET', '/api/v1/orgs/{orgId}/providers', { query });
23
+ return response.providers || [];
24
+ }
25
+ /**
26
+ * Get a single provider by ID
27
+ */
28
+ async get(providerId) {
29
+ const orgId = await this.client.resolveOrgId();
30
+ const response = await this.client.request('GET', `/api/v1/orgs/${orgId}/providers/${providerId}`);
31
+ return response.provider;
32
+ }
33
+ /**
34
+ * Create a new provider
35
+ */
36
+ async create(params) {
37
+ const body = {
38
+ name: params.name,
39
+ };
40
+ if (params.email) {
41
+ body.email = params.email;
42
+ }
43
+ if (params.phone) {
44
+ body.phone = params.phone;
45
+ }
46
+ if (params.userId !== undefined) {
47
+ body.userId = params.userId;
48
+ }
49
+ if (params.bio) {
50
+ body.bio = params.bio;
51
+ }
52
+ if (params.externalId) {
53
+ body.externalId = params.externalId;
54
+ }
55
+ const response = await this.client.request('POST', '/api/v1/orgs/{orgId}/providers', { body });
56
+ return response.provider;
57
+ }
58
+ }