@atzentis/booking-sdk 0.0.0 → 0.1.1

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 ADDED
@@ -0,0 +1,89 @@
1
+ # @atzentis/booking-sdk
2
+
3
+ [![npm](https://img.shields.io/npm/v/@atzentis/booking-sdk)](https://www.npmjs.com/package/@atzentis/booking-sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](../../LICENCE.md)
5
+
6
+ Core TypeScript client for [atzentis.io](https://atzentis.io) — the Atzentis Hospitality Platform. Framework-agnostic with zero runtime dependencies.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install @atzentis/booking-sdk
12
+ ```
13
+
14
+ ## Quick Start
15
+
16
+ ```typescript
17
+ import { BookingClient } from '@atzentis/booking-sdk';
18
+
19
+ const booking = new BookingClient({
20
+ baseUrl: 'https://api.atzentis.io',
21
+ apiKey: 'your-api-key',
22
+ });
23
+
24
+ // Properties
25
+ const properties = await booking.properties.list();
26
+
27
+ // Availability
28
+ const availability = await booking.availability.check({
29
+ propertyId: 'prop_123',
30
+ checkIn: '2026-06-01',
31
+ checkOut: '2026-06-05',
32
+ });
33
+
34
+ // Bookings
35
+ const result = await booking.bookings.create({
36
+ propertyId: 'prop_123',
37
+ spaceId: 'space_456',
38
+ guestId: 'guest_789',
39
+ checkIn: '2026-06-01',
40
+ checkOut: '2026-06-05',
41
+ });
42
+ ```
43
+
44
+ ## Services
45
+
46
+ Wraps all 205 endpoints of the atzentis.io v4.0 API across 28 services:
47
+
48
+ | Category | Services |
49
+ | --- | --- |
50
+ | Inventory | Properties, Spaces |
51
+ | Booking | Availability, Bookings, Groups |
52
+ | Guest | Profiles, Intelligence, ID Scanning |
53
+ | Finance | Folios, Payments, POS Bridge |
54
+ | Operations | Housekeeping, Night Audit, Staff, Supply, Tasks |
55
+ | Rate | Plans, Periods, Restrictions |
56
+ | Distribution | Channels, Mappings, Sync, iCal |
57
+ | AI | Concierge, Revenue |
58
+ | Compliance | Fiscal (myDATA, TSE) |
59
+ | Platform | Webhooks, Settings, Notifications, SSE |
60
+
61
+ ## Booking Verticals
62
+
63
+ | Vertical | Space Types | Granularity |
64
+ | --- | --- | --- |
65
+ | **Stays** (nights) | room, sunbed, parking | night, day, month |
66
+ | **Tables** (reservations) | table, locker | hour |
67
+ | **Services** (appointments) | service, meeting_room, desk | hour |
68
+
69
+ ## Features
70
+
71
+ - ESM and CJS dual output
72
+ - Strict TypeScript with full type coverage
73
+ - Zod validation schemas for all request/response types
74
+ - Tree-shakeable exports
75
+ - Zero runtime dependencies
76
+
77
+ ## React
78
+
79
+ For React hooks and components, see [`@atzentis/booking-react`](https://www.npmjs.com/package/@atzentis/booking-react).
80
+
81
+ ## Links
82
+
83
+ - [atzentis.io](https://atzentis.io) — Hospitality Platform
84
+ - [API Documentation](https://docs.atzentis.com)
85
+ - [GitHub](https://github.com/atzentis/atzentis-booking-sdk)
86
+
87
+ ## License
88
+
89
+ MIT
package/dist/index.cjs CHANGED
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __typeError = (msg) => {
7
+ throw TypeError(msg);
8
+ };
6
9
  var __export = (target, all) => {
7
10
  for (var name in all)
8
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -16,16 +19,546 @@ var __copyProps = (to, from, except, desc) => {
16
19
  return to;
17
20
  };
18
21
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
23
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
24
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
25
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
19
26
 
20
27
  // src/index.ts
21
28
  var index_exports = {};
22
29
  __export(index_exports, {
23
- VERSION: () => VERSION
30
+ AuthenticationError: () => AuthenticationError,
31
+ BookingClient: () => BookingClient,
32
+ BookingError: () => BookingError,
33
+ ConflictError: () => ConflictError,
34
+ ForbiddenError: () => ForbiddenError,
35
+ HttpClient: () => HttpClient,
36
+ NotFoundError: () => NotFoundError,
37
+ PaymentError: () => PaymentError,
38
+ RateLimitError: () => RateLimitError,
39
+ ServerError: () => ServerError,
40
+ TimeoutError: () => TimeoutError,
41
+ VERSION: () => VERSION,
42
+ ValidationError: () => ValidationError,
43
+ bookingClientConfigSchema: () => bookingClientConfigSchema,
44
+ createErrorFromResponse: () => createErrorFromResponse,
45
+ firstPage: () => firstPage,
46
+ paginate: () => paginate
24
47
  });
25
48
  module.exports = __toCommonJS(index_exports);
26
- var VERSION = "0.0.0";
49
+
50
+ // src/config.ts
51
+ var import_zod = require("zod");
52
+ var bookingClientConfigSchema = import_zod.z.object({
53
+ apiKey: import_zod.z.string().min(1, "apiKey is required"),
54
+ baseUrl: import_zod.z.string().url().default("https://api.atzentis.io"),
55
+ tenantId: import_zod.z.string().min(1).optional(),
56
+ timeout: import_zod.z.number().int().positive().default(3e4),
57
+ retry: import_zod.z.object({
58
+ maxRetries: import_zod.z.number().int().min(0).max(10).default(3),
59
+ baseDelay: import_zod.z.number().int().positive().default(500)
60
+ }).optional(),
61
+ debug: import_zod.z.boolean().default(false),
62
+ logger: import_zod.z.object({
63
+ debug: import_zod.z.custom(
64
+ (val) => typeof val === "function"
65
+ )
66
+ }).optional()
67
+ });
68
+
69
+ // src/errors.ts
70
+ var BookingError = class extends Error {
71
+ constructor(message, options) {
72
+ super(message);
73
+ Object.setPrototypeOf(this, new.target.prototype);
74
+ this.name = "BookingError";
75
+ this.code = options.code;
76
+ this.status = options.status;
77
+ this.details = options.details ?? {};
78
+ }
79
+ };
80
+ var AuthenticationError = class extends BookingError {
81
+ constructor(message = "Authentication failed: invalid or missing API key", details) {
82
+ super(message, { code: "AUTHENTICATION_ERROR", status: 401, details });
83
+ Object.setPrototypeOf(this, new.target.prototype);
84
+ this.name = "AuthenticationError";
85
+ }
86
+ };
87
+ var PaymentError = class extends BookingError {
88
+ constructor(message = "Payment required or payment failed", details) {
89
+ super(message, { code: "PAYMENT_ERROR", status: 402, details });
90
+ Object.setPrototypeOf(this, new.target.prototype);
91
+ this.name = "PaymentError";
92
+ }
93
+ };
94
+ var ForbiddenError = class extends BookingError {
95
+ constructor(message = "Insufficient permissions to perform this action", details) {
96
+ super(message, { code: "FORBIDDEN_ERROR", status: 403, details });
97
+ Object.setPrototypeOf(this, new.target.prototype);
98
+ this.name = "ForbiddenError";
99
+ }
100
+ };
101
+ var NotFoundError = class extends BookingError {
102
+ constructor(message = "The requested resource was not found", details) {
103
+ super(message, { code: "NOT_FOUND_ERROR", status: 404, details });
104
+ Object.setPrototypeOf(this, new.target.prototype);
105
+ this.name = "NotFoundError";
106
+ }
107
+ };
108
+ var ConflictError = class extends BookingError {
109
+ constructor(message = "Resource conflict \u2014 the booking may already exist", details) {
110
+ super(message, { code: "CONFLICT_ERROR", status: 409, details });
111
+ Object.setPrototypeOf(this, new.target.prototype);
112
+ this.name = "ConflictError";
113
+ }
114
+ };
115
+ var ValidationError = class extends BookingError {
116
+ constructor(message = "Request validation failed", fieldErrors = {}, details) {
117
+ super(message, { code: "VALIDATION_ERROR", status: 422, details });
118
+ Object.setPrototypeOf(this, new.target.prototype);
119
+ this.name = "ValidationError";
120
+ this.fieldErrors = fieldErrors;
121
+ }
122
+ };
123
+ var RateLimitError = class extends BookingError {
124
+ constructor(message = "Rate limit exceeded", retryAfter = 60) {
125
+ super(message, { code: "RATE_LIMIT_ERROR", status: 429 });
126
+ Object.setPrototypeOf(this, new.target.prototype);
127
+ this.name = "RateLimitError";
128
+ this.retryAfter = retryAfter;
129
+ }
130
+ };
131
+ var ServerError = class extends BookingError {
132
+ constructor(message = "An unexpected server error occurred", status = 500, details) {
133
+ super(message, { code: "SERVER_ERROR", status, details });
134
+ Object.setPrototypeOf(this, new.target.prototype);
135
+ this.name = "ServerError";
136
+ }
137
+ };
138
+ var TimeoutError = class extends BookingError {
139
+ constructor(message = "The request timed out") {
140
+ super(message, { code: "TIMEOUT_ERROR" });
141
+ Object.setPrototypeOf(this, new.target.prototype);
142
+ this.name = "TimeoutError";
143
+ }
144
+ };
145
+ function parseRetryAfter(header) {
146
+ if (!header) return 60;
147
+ const seconds = Number.parseInt(header, 10);
148
+ if (Number.isFinite(seconds) && seconds > 0) return seconds;
149
+ const date = new Date(header);
150
+ if (!Number.isNaN(date.getTime())) {
151
+ return Math.max(0, Math.round((date.getTime() - Date.now()) / 1e3));
152
+ }
153
+ return 60;
154
+ }
155
+ function extractBody(body) {
156
+ if (typeof body === "object" && body !== null && !Array.isArray(body)) {
157
+ return body;
158
+ }
159
+ return {};
160
+ }
161
+ function extractMessage(body, fallback) {
162
+ if (typeof body.message === "string" && body.message.length > 0) {
163
+ return body.message;
164
+ }
165
+ return fallback;
166
+ }
167
+ function parseFieldErrors(errors) {
168
+ if (typeof errors !== "object" || errors === null || Array.isArray(errors)) {
169
+ return {};
170
+ }
171
+ const result = {};
172
+ for (const [key, value] of Object.entries(errors)) {
173
+ if (Array.isArray(value)) {
174
+ result[key] = value.map(String);
175
+ } else if (typeof value === "string") {
176
+ result[key] = [value];
177
+ }
178
+ }
179
+ return result;
180
+ }
181
+ function createErrorFromResponse(response, body, retryAfterHeader) {
182
+ const bodyObj = extractBody(body);
183
+ const status = response.status;
184
+ switch (status) {
185
+ case 401:
186
+ return new AuthenticationError(
187
+ extractMessage(bodyObj, "Authentication failed: invalid or missing API key"),
188
+ bodyObj
189
+ );
190
+ case 402:
191
+ return new PaymentError(
192
+ extractMessage(bodyObj, "Payment required or payment failed"),
193
+ bodyObj
194
+ );
195
+ case 403:
196
+ return new ForbiddenError(
197
+ extractMessage(bodyObj, "Insufficient permissions to perform this action"),
198
+ bodyObj
199
+ );
200
+ case 404:
201
+ return new NotFoundError(
202
+ extractMessage(bodyObj, "The requested resource was not found"),
203
+ bodyObj
204
+ );
205
+ case 409:
206
+ return new ConflictError(extractMessage(bodyObj, "Resource conflict"), bodyObj);
207
+ case 422:
208
+ return new ValidationError(
209
+ extractMessage(bodyObj, "Request validation failed"),
210
+ parseFieldErrors(bodyObj.errors),
211
+ bodyObj
212
+ );
213
+ case 429:
214
+ return new RateLimitError(
215
+ extractMessage(bodyObj, "Rate limit exceeded"),
216
+ parseRetryAfter(retryAfterHeader ?? null)
217
+ );
218
+ default:
219
+ if (status >= 500) {
220
+ return new ServerError(
221
+ extractMessage(bodyObj, "An unexpected server error occurred"),
222
+ status,
223
+ bodyObj
224
+ );
225
+ }
226
+ return new BookingError(extractMessage(bodyObj, `HTTP ${status} error`), {
227
+ code: "HTTP_ERROR",
228
+ status,
229
+ details: bodyObj
230
+ });
231
+ }
232
+ }
233
+
234
+ // src/http.ts
235
+ var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
236
+ var DEFAULT_RETRY_CONFIG = {
237
+ maxRetries: 3,
238
+ baseDelay: 500,
239
+ retryOnMethods: ["GET", "DELETE"]
240
+ };
241
+ function parseRetryAfterHeader(header) {
242
+ if (!header) return 1;
243
+ const seconds = Number.parseInt(header, 10);
244
+ if (Number.isNaN(seconds) || seconds < 0) return 1;
245
+ return seconds;
246
+ }
247
+ function createDefaultLogger() {
248
+ return {
249
+ debug(message, ...args) {
250
+ console.debug(message, ...args);
251
+ }
252
+ };
253
+ }
254
+ function redactHeaders(headers) {
255
+ const result = { ...headers };
256
+ if (result.Authorization) {
257
+ result.Authorization = "Bearer ***";
258
+ }
259
+ return result;
260
+ }
261
+ var _apiKey, _tenantId, _retryConfig, _timeout, _debug, _logger;
262
+ var HttpClient = class {
263
+ constructor(options) {
264
+ __privateAdd(this, _apiKey);
265
+ __privateAdd(this, _tenantId);
266
+ __privateAdd(this, _retryConfig);
267
+ __privateAdd(this, _timeout);
268
+ __privateAdd(this, _debug);
269
+ __privateAdd(this, _logger);
270
+ this.baseUrl = options.baseUrl;
271
+ this.fetchFn = options.fetch ?? globalThis.fetch;
272
+ this.defaultHeaders = { ...options.defaultHeaders };
273
+ __privateSet(this, _apiKey, options.apiKey);
274
+ __privateSet(this, _tenantId, options.tenantId);
275
+ __privateSet(this, _retryConfig, {
276
+ ...DEFAULT_RETRY_CONFIG,
277
+ ...options.retryConfig
278
+ });
279
+ __privateSet(this, _timeout, options.timeout ?? 3e4);
280
+ __privateSet(this, _debug, options.debug ?? false);
281
+ __privateSet(this, _logger, options.logger ?? createDefaultLogger());
282
+ }
283
+ async request(method, path, options) {
284
+ if (!__privateGet(this, _apiKey)) {
285
+ throw new Error("BookingSDK: apiKey is required but was not provided");
286
+ }
287
+ const url = this.buildUrl(path, options?.query);
288
+ const headers = this.buildHeaders(options?.headers);
289
+ if (options?.body !== void 0) {
290
+ headers["Content-Type"] = "application/json";
291
+ }
292
+ headers.Authorization = `Bearer ${__privateGet(this, _apiKey)}`;
293
+ if (__privateGet(this, _tenantId)) {
294
+ headers["X-Tenant-ID"] = __privateGet(this, _tenantId);
295
+ }
296
+ const init = {
297
+ method,
298
+ headers
299
+ };
300
+ if (options?.body !== void 0) {
301
+ init.body = JSON.stringify(options.body);
302
+ }
303
+ const effectiveRetry = {
304
+ maxRetries: options?.retry?.maxRetries ?? __privateGet(this, _retryConfig).maxRetries,
305
+ baseDelay: options?.retry?.baseDelay ?? __privateGet(this, _retryConfig).baseDelay,
306
+ retryOnMethods: __privateGet(this, _retryConfig).retryOnMethods,
307
+ force: options?.retry?.force ?? false,
308
+ maxRetryAfter: __privateGet(this, _retryConfig).maxRetryAfter ?? 60
309
+ };
310
+ if (__privateGet(this, _debug)) {
311
+ __privateGet(this, _logger).debug(`[BookingSDK] --> ${method} ${url}`, {
312
+ headers: redactHeaders(headers),
313
+ ...options?.body ? { body: JSON.stringify(options.body).slice(0, 200) } : {}
314
+ });
315
+ }
316
+ const timeoutMs = options?.timeout ?? __privateGet(this, _timeout);
317
+ const startTime = Date.now();
318
+ let lastError;
319
+ let wasRateLimited = false;
320
+ for (let attempt = 0; attempt <= effectiveRetry.maxRetries; attempt++) {
321
+ if (attempt > 0 && !wasRateLimited) {
322
+ await this.sleep(this.calculateDelay(attempt - 1, effectiveRetry.baseDelay));
323
+ }
324
+ wasRateLimited = false;
325
+ let timedOut = false;
326
+ const controller = new AbortController();
327
+ const timer = setTimeout(() => {
328
+ timedOut = true;
329
+ controller.abort();
330
+ }, timeoutMs);
331
+ if (options?.signal) {
332
+ if (options.signal.aborted) {
333
+ clearTimeout(timer);
334
+ controller.abort();
335
+ } else {
336
+ options.signal.addEventListener("abort", () => controller.abort(), { once: true });
337
+ }
338
+ }
339
+ try {
340
+ const response = await this.fetchFn(url, {
341
+ ...init,
342
+ signal: controller.signal
343
+ });
344
+ if (__privateGet(this, _debug)) {
345
+ const elapsed = Date.now() - startTime;
346
+ __privateGet(this, _logger).debug(`[BookingSDK] <-- ${response.status} (${elapsed}ms)`);
347
+ }
348
+ if (!response.ok) {
349
+ if (response.status === 429 && this.shouldRetry(method, effectiveRetry, attempt)) {
350
+ const retryAfterHeader2 = response.headers.get("Retry-After");
351
+ const retryAfterSeconds = parseRetryAfterHeader(retryAfterHeader2);
352
+ const cappedSeconds = Math.min(retryAfterSeconds, effectiveRetry.maxRetryAfter);
353
+ if (__privateGet(this, _debug)) {
354
+ __privateGet(this, _logger).debug(
355
+ `[BookingSDK] retry attempt ${attempt + 1}/${effectiveRetry.maxRetries} in ${cappedSeconds * 1e3}ms (reason: 429 Rate Limited)`
356
+ );
357
+ }
358
+ await this.sleep(cappedSeconds * 1e3);
359
+ wasRateLimited = true;
360
+ lastError = response;
361
+ continue;
362
+ }
363
+ if (RETRYABLE_STATUSES.has(response.status) && this.shouldRetry(method, effectiveRetry, attempt)) {
364
+ if (__privateGet(this, _debug)) {
365
+ const delay = this.calculateDelay(attempt, effectiveRetry.baseDelay);
366
+ __privateGet(this, _logger).debug(
367
+ `[BookingSDK] retry attempt ${attempt + 1}/${effectiveRetry.maxRetries} in ${delay}ms (reason: ${response.status})`
368
+ );
369
+ }
370
+ lastError = response;
371
+ continue;
372
+ }
373
+ const body = await response.json().catch(() => ({}));
374
+ const retryAfterHeader = response.headers.get("Retry-After");
375
+ throw createErrorFromResponse(response, body, retryAfterHeader);
376
+ }
377
+ if (__privateGet(this, _debug)) {
378
+ const text = await response.clone().text().catch(() => "");
379
+ if (text) {
380
+ __privateGet(this, _logger).debug(`[BookingSDK] body preview: ${text.slice(0, 500)}`);
381
+ }
382
+ }
383
+ return response.json();
384
+ } catch (error) {
385
+ if (error instanceof Error && error.name === "AbortError") {
386
+ if (timedOut) {
387
+ throw new TimeoutError(`Request timed out after ${timeoutMs}ms`);
388
+ }
389
+ throw error;
390
+ }
391
+ if (!(error instanceof TypeError)) {
392
+ throw error;
393
+ }
394
+ if (!this.shouldRetry(method, effectiveRetry, attempt)) {
395
+ throw error;
396
+ }
397
+ lastError = error;
398
+ } finally {
399
+ clearTimeout(timer);
400
+ }
401
+ }
402
+ if (lastError instanceof Response) {
403
+ const body = await lastError.json().catch(() => ({}));
404
+ const retryAfterHeader = lastError.headers.get("Retry-After");
405
+ throw createErrorFromResponse(lastError, body, retryAfterHeader);
406
+ }
407
+ throw lastError;
408
+ }
409
+ async get(path, options) {
410
+ return this.request("GET", path, options);
411
+ }
412
+ async post(path, options) {
413
+ return this.request("POST", path, options);
414
+ }
415
+ async put(path, options) {
416
+ return this.request("PUT", path, options);
417
+ }
418
+ async patch(path, options) {
419
+ return this.request("PATCH", path, options);
420
+ }
421
+ async delete(path, options) {
422
+ return this.request("DELETE", path, options);
423
+ }
424
+ setApiKey(key) {
425
+ __privateSet(this, _apiKey, key);
426
+ }
427
+ setTenantId(id) {
428
+ __privateSet(this, _tenantId, id);
429
+ }
430
+ setDefaultHeader(key, value) {
431
+ this.defaultHeaders[key] = value;
432
+ }
433
+ removeDefaultHeader(key) {
434
+ delete this.defaultHeaders[key];
435
+ }
436
+ shouldRetry(method, config, attempt) {
437
+ if (attempt >= config.maxRetries) return false;
438
+ if (config.force) return true;
439
+ return config.retryOnMethods.includes(method);
440
+ }
441
+ calculateDelay(attempt, baseDelay) {
442
+ return baseDelay * 2 ** attempt + Math.floor(Math.random() * 100);
443
+ }
444
+ sleep(ms) {
445
+ return new Promise((resolve) => setTimeout(resolve, ms));
446
+ }
447
+ buildUrl(path, query) {
448
+ const cleanPath = path.startsWith("/") ? path.slice(1) : path;
449
+ let url = `${this.baseUrl}/${cleanPath}`;
450
+ if (query) {
451
+ const params = new URLSearchParams();
452
+ for (const [key, value] of Object.entries(query)) {
453
+ if (value === null || value === void 0) {
454
+ continue;
455
+ }
456
+ if (Array.isArray(value)) {
457
+ for (const item of value) {
458
+ params.append(key, item);
459
+ }
460
+ } else {
461
+ params.set(key, String(value));
462
+ }
463
+ }
464
+ const qs = params.toString();
465
+ if (qs) {
466
+ url = `${url}?${qs}`;
467
+ }
468
+ }
469
+ return url;
470
+ }
471
+ buildHeaders(perRequestHeaders) {
472
+ return {
473
+ Accept: "application/json",
474
+ ...this.defaultHeaders,
475
+ ...perRequestHeaders
476
+ };
477
+ }
478
+ };
479
+ _apiKey = new WeakMap();
480
+ _tenantId = new WeakMap();
481
+ _retryConfig = new WeakMap();
482
+ _timeout = new WeakMap();
483
+ _debug = new WeakMap();
484
+ _logger = new WeakMap();
485
+
486
+ // src/client.ts
487
+ var BookingClient = class {
488
+ constructor(config) {
489
+ const validated = bookingClientConfigSchema.parse(config);
490
+ this.httpClient = new HttpClient({
491
+ baseUrl: validated.baseUrl,
492
+ apiKey: validated.apiKey,
493
+ tenantId: validated.tenantId,
494
+ timeout: validated.timeout,
495
+ retryConfig: validated.retry ? {
496
+ maxRetries: validated.retry.maxRetries,
497
+ baseDelay: validated.retry.baseDelay
498
+ } : void 0,
499
+ debug: validated.debug,
500
+ logger: validated.logger
501
+ });
502
+ }
503
+ setApiKey(key) {
504
+ if (!key || key.trim().length === 0) {
505
+ throw new Error("apiKey must be a non-empty string");
506
+ }
507
+ this.httpClient.setApiKey(key);
508
+ }
509
+ setTenantId(id) {
510
+ if (!id || id.trim().length === 0) {
511
+ throw new Error("tenantId must be a non-empty string");
512
+ }
513
+ this.httpClient.setTenantId(id);
514
+ }
515
+ };
516
+
517
+ // src/pagination.ts
518
+ function paginate(fetcher, options) {
519
+ return {
520
+ [Symbol.asyncIterator]() {
521
+ let cursor = options?.cursor;
522
+ let done = false;
523
+ return {
524
+ async next() {
525
+ if (done) return { value: void 0, done: true };
526
+ const result = await fetcher({ ...options ?? {}, cursor });
527
+ if (!result.hasMore || result.cursor === null) {
528
+ done = true;
529
+ } else {
530
+ cursor = result.cursor;
531
+ }
532
+ return { value: result.data, done: false };
533
+ }
534
+ };
535
+ }
536
+ };
537
+ }
538
+ async function firstPage(fetcher, options) {
539
+ return fetcher({ ...options ?? {} });
540
+ }
541
+
542
+ // src/index.ts
543
+ var VERSION = "0.1.0";
27
544
  // Annotate the CommonJS export names for ESM import in node:
28
545
  0 && (module.exports = {
29
- VERSION
546
+ AuthenticationError,
547
+ BookingClient,
548
+ BookingError,
549
+ ConflictError,
550
+ ForbiddenError,
551
+ HttpClient,
552
+ NotFoundError,
553
+ PaymentError,
554
+ RateLimitError,
555
+ ServerError,
556
+ TimeoutError,
557
+ VERSION,
558
+ ValidationError,
559
+ bookingClientConfigSchema,
560
+ createErrorFromResponse,
561
+ firstPage,
562
+ paginate
30
563
  });
31
564
  //# sourceMappingURL=index.cjs.map