@atzentis/booking-sdk 0.1.4 → 0.1.6
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/dist/index.cjs +538 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +904 -93
- package/dist/index.d.ts +904 -93
- package/dist/index.js +534 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -28,8 +28,12 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
|
|
|
28
28
|
var index_exports = {};
|
|
29
29
|
__export(index_exports, {
|
|
30
30
|
AuthenticationError: () => AuthenticationError,
|
|
31
|
+
AvailabilityService: () => AvailabilityService,
|
|
32
|
+
BOOKING_STATUSES: () => BOOKING_STATUSES,
|
|
33
|
+
BOOKING_TYPES: () => BOOKING_TYPES,
|
|
31
34
|
BookingClient: () => BookingClient,
|
|
32
35
|
BookingError: () => BookingError,
|
|
36
|
+
BookingsService: () => BookingsService,
|
|
33
37
|
CategoriesService: () => CategoriesService,
|
|
34
38
|
ConflictError: () => ConflictError,
|
|
35
39
|
DEFAULT_MODULES: () => DEFAULT_MODULES,
|
|
@@ -523,6 +527,505 @@ var BaseService = class {
|
|
|
523
527
|
}
|
|
524
528
|
};
|
|
525
529
|
|
|
530
|
+
// src/services/availability.ts
|
|
531
|
+
var AvailabilityService = class extends BaseService {
|
|
532
|
+
constructor() {
|
|
533
|
+
super(...arguments);
|
|
534
|
+
this.basePath = "/booking/v1/availability";
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Check availability for a property and date range.
|
|
538
|
+
*
|
|
539
|
+
* @param params - Must include `propertyId`, `checkIn`, `checkOut`; supports optional filters
|
|
540
|
+
*
|
|
541
|
+
* @example
|
|
542
|
+
* ```typescript
|
|
543
|
+
* const result = await booking.availability.check({
|
|
544
|
+
* propertyId: "prop_abc123",
|
|
545
|
+
* checkIn: "2025-06-01",
|
|
546
|
+
* checkOut: "2025-06-05",
|
|
547
|
+
* type: "room",
|
|
548
|
+
* guests: 2,
|
|
549
|
+
* });
|
|
550
|
+
* ```
|
|
551
|
+
*/
|
|
552
|
+
check(params) {
|
|
553
|
+
const { propertyId, checkIn, checkOut, categoryId, spaceId, guests, type } = params;
|
|
554
|
+
return this._get(this.basePath, {
|
|
555
|
+
propertyId,
|
|
556
|
+
checkIn,
|
|
557
|
+
checkOut,
|
|
558
|
+
categoryId,
|
|
559
|
+
spaceId,
|
|
560
|
+
guests,
|
|
561
|
+
type
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Search availability across multiple properties.
|
|
566
|
+
*
|
|
567
|
+
* @param params - Must include `propertyIds`, `checkIn`, `checkOut`; supports filtering and pagination
|
|
568
|
+
*
|
|
569
|
+
* @example
|
|
570
|
+
* ```typescript
|
|
571
|
+
* const results = await booking.availability.search({
|
|
572
|
+
* propertyIds: ["prop_abc", "prop_def"],
|
|
573
|
+
* checkIn: "2025-06-01",
|
|
574
|
+
* checkOut: "2025-06-05",
|
|
575
|
+
* guests: 2,
|
|
576
|
+
* priceRange: { min: 5000, max: 20000 },
|
|
577
|
+
* });
|
|
578
|
+
* ```
|
|
579
|
+
*/
|
|
580
|
+
search(params) {
|
|
581
|
+
return this._post(this.basePath, params);
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Generate a calendar view of daily availability for a property.
|
|
585
|
+
*
|
|
586
|
+
* Client-side helper that calls `check()` internally and transforms the result
|
|
587
|
+
* into a `CalendarDay[]` suitable for calendar UI rendering.
|
|
588
|
+
*
|
|
589
|
+
* @param params - Extends `AvailabilityCheckParams` with optional `months` (default: 1)
|
|
590
|
+
*
|
|
591
|
+
* @example
|
|
592
|
+
* ```typescript
|
|
593
|
+
* const calendar = await booking.availability.getCalendar({
|
|
594
|
+
* propertyId: "prop_abc123",
|
|
595
|
+
* checkIn: "2025-06-01",
|
|
596
|
+
* checkOut: "2025-06-30",
|
|
597
|
+
* });
|
|
598
|
+
* ```
|
|
599
|
+
*/
|
|
600
|
+
async getCalendar(params) {
|
|
601
|
+
const { months, ...checkParams } = params;
|
|
602
|
+
let endDate;
|
|
603
|
+
if (checkParams.checkOut !== checkParams.checkIn) {
|
|
604
|
+
endDate = checkParams.checkOut;
|
|
605
|
+
} else if (months != null) {
|
|
606
|
+
endDate = addDays(checkParams.checkIn, months * 30);
|
|
607
|
+
} else {
|
|
608
|
+
return [];
|
|
609
|
+
}
|
|
610
|
+
const dates = generateDateRange(checkParams.checkIn, endDate, 365);
|
|
611
|
+
if (dates.length === 0) return [];
|
|
612
|
+
const result = await this.check({ ...checkParams, checkOut: endDate });
|
|
613
|
+
const spacesAvailable = result.spaces.filter((s) => s.available).length;
|
|
614
|
+
return dates.map((date) => ({
|
|
615
|
+
date,
|
|
616
|
+
available: result.available,
|
|
617
|
+
price: result.available && result.pricing ? result.pricing.total : null,
|
|
618
|
+
minStay: result.restrictions?.minStay ?? null,
|
|
619
|
+
closedToArrival: result.restrictions?.closedToArrival ?? false,
|
|
620
|
+
closedToDeparture: result.restrictions?.closedToDeparture ?? false,
|
|
621
|
+
spacesAvailable: result.available ? spacesAvailable : 0
|
|
622
|
+
}));
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Get available table reservation time slots for a specific date.
|
|
626
|
+
*
|
|
627
|
+
* Client-side helper for the Tables vertical. Calls `check()` internally
|
|
628
|
+
* with `type: "table"` and reshapes the response into `TimeSlot[]`.
|
|
629
|
+
*
|
|
630
|
+
* @param params - Must include `propertyId` and `date`
|
|
631
|
+
*
|
|
632
|
+
* @example
|
|
633
|
+
* ```typescript
|
|
634
|
+
* const slots = await booking.availability.getTableSlots({
|
|
635
|
+
* propertyId: "prop_abc123",
|
|
636
|
+
* date: "2025-06-15",
|
|
637
|
+
* guests: 4,
|
|
638
|
+
* });
|
|
639
|
+
* ```
|
|
640
|
+
*/
|
|
641
|
+
async getTableSlots(params) {
|
|
642
|
+
const { date, guests, categoryId, duration, ...rest } = params;
|
|
643
|
+
const result = await this.check({
|
|
644
|
+
...rest,
|
|
645
|
+
checkIn: date,
|
|
646
|
+
checkOut: date,
|
|
647
|
+
type: "table",
|
|
648
|
+
guests,
|
|
649
|
+
categoryId
|
|
650
|
+
});
|
|
651
|
+
if (!result.available || result.spaces.length === 0) {
|
|
652
|
+
return [];
|
|
653
|
+
}
|
|
654
|
+
const slotDuration = duration ?? 90;
|
|
655
|
+
const availableSpaces = result.spaces.filter((s) => s.available);
|
|
656
|
+
return availableSpaces.map((space, index) => ({
|
|
657
|
+
startTime: minutesToTime(11 * 60 + index * slotDuration),
|
|
658
|
+
endTime: minutesToTime(11 * 60 + index * slotDuration + slotDuration),
|
|
659
|
+
available: true,
|
|
660
|
+
tablesAvailable: availableSpaces.length,
|
|
661
|
+
price: space.price
|
|
662
|
+
}));
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Get available service appointment slots for a specific date.
|
|
666
|
+
*
|
|
667
|
+
* Client-side helper for the Services vertical. Calls `check()` internally
|
|
668
|
+
* with `type: "service"` and reshapes the response into `ServiceTimeSlot[]`.
|
|
669
|
+
*
|
|
670
|
+
* @param params - Must include `propertyId` and `date`
|
|
671
|
+
*
|
|
672
|
+
* @example
|
|
673
|
+
* ```typescript
|
|
674
|
+
* const slots = await booking.availability.getServiceSlots({
|
|
675
|
+
* propertyId: "prop_abc123",
|
|
676
|
+
* date: "2025-06-15",
|
|
677
|
+
* providerId: "staff_001",
|
|
678
|
+
* duration: 60,
|
|
679
|
+
* });
|
|
680
|
+
* ```
|
|
681
|
+
*/
|
|
682
|
+
async getServiceSlots(params) {
|
|
683
|
+
const { date, providerId, categoryId, duration, ...rest } = params;
|
|
684
|
+
const result = await this.check({
|
|
685
|
+
...rest,
|
|
686
|
+
checkIn: date,
|
|
687
|
+
checkOut: date,
|
|
688
|
+
type: "service",
|
|
689
|
+
categoryId
|
|
690
|
+
});
|
|
691
|
+
if (!result.available || result.spaces.length === 0) {
|
|
692
|
+
return [];
|
|
693
|
+
}
|
|
694
|
+
const slotDuration = duration ?? 60;
|
|
695
|
+
const availableSpaces = result.spaces.filter((s) => s.available);
|
|
696
|
+
return availableSpaces.map((space, index) => ({
|
|
697
|
+
startTime: minutesToTime(9 * 60 + index * slotDuration),
|
|
698
|
+
endTime: minutesToTime(9 * 60 + index * slotDuration + slotDuration),
|
|
699
|
+
available: true,
|
|
700
|
+
tablesAvailable: availableSpaces.length,
|
|
701
|
+
price: space.price,
|
|
702
|
+
providerId: providerId ?? space.spaceId,
|
|
703
|
+
providerName: space.name
|
|
704
|
+
}));
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Get aggregated pricing statistics for a property and date range.
|
|
708
|
+
*
|
|
709
|
+
* Client-side helper that calls `check()` internally and computes
|
|
710
|
+
* min/max/average/total pricing from available spaces.
|
|
711
|
+
*
|
|
712
|
+
* @param params - Extends `AvailabilityCheckParams` with optional `currency`
|
|
713
|
+
*
|
|
714
|
+
* @example
|
|
715
|
+
* ```typescript
|
|
716
|
+
* const pricing = await booking.availability.getPricing({
|
|
717
|
+
* propertyId: "prop_abc123",
|
|
718
|
+
* checkIn: "2025-06-01",
|
|
719
|
+
* checkOut: "2025-06-05",
|
|
720
|
+
* });
|
|
721
|
+
* console.log(`From €${pricing.minPrice / 100} to €${pricing.maxPrice / 100}`);
|
|
722
|
+
* ```
|
|
723
|
+
*/
|
|
724
|
+
async getPricing(params) {
|
|
725
|
+
const { currency: requestedCurrency, ...checkParams } = params;
|
|
726
|
+
const result = await this.check(checkParams);
|
|
727
|
+
const availableSpaces = result.spaces.filter((s) => s.available);
|
|
728
|
+
const nights = dateDiffDays(params.checkIn, params.checkOut);
|
|
729
|
+
const currency = requestedCurrency ?? result.pricing?.currency ?? "EUR";
|
|
730
|
+
if (availableSpaces.length === 0) {
|
|
731
|
+
return {
|
|
732
|
+
minPrice: 0,
|
|
733
|
+
maxPrice: 0,
|
|
734
|
+
averagePrice: 0,
|
|
735
|
+
totalPrice: 0,
|
|
736
|
+
perNight: null,
|
|
737
|
+
nights,
|
|
738
|
+
currency
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
const prices = availableSpaces.map((s) => s.price);
|
|
742
|
+
const minPrice = Math.min(...prices);
|
|
743
|
+
const maxPrice = Math.max(...prices);
|
|
744
|
+
const averagePrice = Math.round(prices.reduce((sum, p) => sum + p, 0) / prices.length);
|
|
745
|
+
const totalPrice = result.pricing?.total ?? averagePrice * Math.max(nights, 1);
|
|
746
|
+
const perNight = nights > 0 ? Math.round(totalPrice / nights) : null;
|
|
747
|
+
return { minPrice, maxPrice, averagePrice, totalPrice, perNight, nights, currency };
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
function parseDateStr(dateStr) {
|
|
751
|
+
const parts = dateStr.split("-");
|
|
752
|
+
return [Number(parts[0]), Number(parts[1]), Number(parts[2])];
|
|
753
|
+
}
|
|
754
|
+
function addDays(dateStr, days) {
|
|
755
|
+
const [year, month, day] = parseDateStr(dateStr);
|
|
756
|
+
return formatDate(new Date(Date.UTC(year, month - 1, day + days)));
|
|
757
|
+
}
|
|
758
|
+
function generateDateRange(start, end, maxDays) {
|
|
759
|
+
const [sy, sm, sd] = parseDateStr(start);
|
|
760
|
+
const [ey, em, ed] = parseDateStr(end);
|
|
761
|
+
const startMs = Date.UTC(sy, sm - 1, sd);
|
|
762
|
+
const endMs = Date.UTC(ey, em - 1, ed);
|
|
763
|
+
if (endMs <= startMs) return [];
|
|
764
|
+
const msPerDay = 864e5;
|
|
765
|
+
const totalDays = Math.min(Math.floor((endMs - startMs) / msPerDay), maxDays);
|
|
766
|
+
const dates = [];
|
|
767
|
+
for (let i = 0; i < totalDays; i++) {
|
|
768
|
+
dates.push(formatDate(new Date(startMs + i * msPerDay)));
|
|
769
|
+
}
|
|
770
|
+
return dates;
|
|
771
|
+
}
|
|
772
|
+
function dateDiffDays(start, end) {
|
|
773
|
+
const [sy, sm, sd] = parseDateStr(start);
|
|
774
|
+
const [ey, em, ed] = parseDateStr(end);
|
|
775
|
+
const startMs = Date.UTC(sy, sm - 1, sd);
|
|
776
|
+
const endMs = Date.UTC(ey, em - 1, ed);
|
|
777
|
+
return Math.max(0, Math.floor((endMs - startMs) / 864e5));
|
|
778
|
+
}
|
|
779
|
+
function formatDate(d) {
|
|
780
|
+
const y = d.getUTCFullYear();
|
|
781
|
+
const m = String(d.getUTCMonth() + 1).padStart(2, "0");
|
|
782
|
+
const day = String(d.getUTCDate()).padStart(2, "0");
|
|
783
|
+
return `${y}-${m}-${day}`;
|
|
784
|
+
}
|
|
785
|
+
function minutesToTime(totalMinutes) {
|
|
786
|
+
const hours = Math.floor(totalMinutes / 60) % 24;
|
|
787
|
+
const minutes = totalMinutes % 60;
|
|
788
|
+
return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// src/services/bookings.ts
|
|
792
|
+
var BookingsService = class extends BaseService {
|
|
793
|
+
constructor() {
|
|
794
|
+
super(...arguments);
|
|
795
|
+
this.basePath = "/booking/v1/bookings";
|
|
796
|
+
}
|
|
797
|
+
// ---------------------------------------------------------------------------
|
|
798
|
+
// CRUD
|
|
799
|
+
// ---------------------------------------------------------------------------
|
|
800
|
+
/**
|
|
801
|
+
* Create a new booking.
|
|
802
|
+
*
|
|
803
|
+
* @example
|
|
804
|
+
* ```typescript
|
|
805
|
+
* const booking = await client.bookings.create({
|
|
806
|
+
* propertyId: "prop_abc123",
|
|
807
|
+
* categoryId: "cat_deluxe",
|
|
808
|
+
* guestId: "guest_42",
|
|
809
|
+
* checkIn: "2025-07-01",
|
|
810
|
+
* checkOut: "2025-07-05",
|
|
811
|
+
* type: "stay",
|
|
812
|
+
* guests: 2,
|
|
813
|
+
* autoConfirm: true,
|
|
814
|
+
* });
|
|
815
|
+
* ```
|
|
816
|
+
*/
|
|
817
|
+
create(input) {
|
|
818
|
+
return this._post(this.basePath, input);
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Get a single booking by ID.
|
|
822
|
+
*
|
|
823
|
+
* @example
|
|
824
|
+
* ```typescript
|
|
825
|
+
* const booking = await client.bookings.get("bk_abc123");
|
|
826
|
+
* ```
|
|
827
|
+
*/
|
|
828
|
+
get(bookingId) {
|
|
829
|
+
return this._get(this._buildPath(bookingId));
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* List bookings for a property with optional filters and cursor-based pagination.
|
|
833
|
+
*
|
|
834
|
+
* Supports filtering by status, type, guest, date ranges, search term,
|
|
835
|
+
* and custom sort order. Array values for `status` and `type` are serialized
|
|
836
|
+
* as comma-separated strings.
|
|
837
|
+
*
|
|
838
|
+
* @example
|
|
839
|
+
* ```typescript
|
|
840
|
+
* // List all confirmed stay bookings
|
|
841
|
+
* const page = await client.bookings.list({
|
|
842
|
+
* propertyId: "prop_abc123",
|
|
843
|
+
* status: "confirmed",
|
|
844
|
+
* type: "stay",
|
|
845
|
+
* });
|
|
846
|
+
*
|
|
847
|
+
* // Multi-status filter with date range
|
|
848
|
+
* const page2 = await client.bookings.list({
|
|
849
|
+
* propertyId: "prop_abc123",
|
|
850
|
+
* status: ["confirmed", "checked_in"],
|
|
851
|
+
* checkInFrom: "2025-07-01",
|
|
852
|
+
* checkInTo: "2025-07-31",
|
|
853
|
+
* sort: { field: "checkIn", direction: "asc" },
|
|
854
|
+
* limit: 20,
|
|
855
|
+
* });
|
|
856
|
+
* ```
|
|
857
|
+
*/
|
|
858
|
+
list(params) {
|
|
859
|
+
const query = {
|
|
860
|
+
propertyId: params.propertyId
|
|
861
|
+
};
|
|
862
|
+
if (params.status !== void 0) {
|
|
863
|
+
query.status = Array.isArray(params.status) ? params.status.join(",") : params.status;
|
|
864
|
+
}
|
|
865
|
+
if (params.type !== void 0) {
|
|
866
|
+
query.type = Array.isArray(params.type) ? params.type.join(",") : params.type;
|
|
867
|
+
}
|
|
868
|
+
if (params.guestId !== void 0) query.guestId = params.guestId;
|
|
869
|
+
if (params.checkInFrom !== void 0) query.checkInFrom = params.checkInFrom;
|
|
870
|
+
if (params.checkInTo !== void 0) query.checkInTo = params.checkInTo;
|
|
871
|
+
if (params.checkOutFrom !== void 0) query.checkOutFrom = params.checkOutFrom;
|
|
872
|
+
if (params.checkOutTo !== void 0) query.checkOutTo = params.checkOutTo;
|
|
873
|
+
if (params.search !== void 0) query.search = params.search;
|
|
874
|
+
if (params.sort !== void 0) {
|
|
875
|
+
query.sort = `${params.sort.field}:${params.sort.direction}`;
|
|
876
|
+
}
|
|
877
|
+
if (params.limit !== void 0) query.limit = params.limit;
|
|
878
|
+
if (params.cursor !== void 0) query.cursor = params.cursor;
|
|
879
|
+
return this._get(this.basePath, query);
|
|
880
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
* Update an existing booking.
|
|
883
|
+
*
|
|
884
|
+
* @example
|
|
885
|
+
* ```typescript
|
|
886
|
+
* const updated = await client.bookings.update("bk_abc123", {
|
|
887
|
+
* guests: 3,
|
|
888
|
+
* notes: "Extra bed requested",
|
|
889
|
+
* });
|
|
890
|
+
* ```
|
|
891
|
+
*/
|
|
892
|
+
update(bookingId, input) {
|
|
893
|
+
return this._patch(this._buildPath(bookingId), input);
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Delete a booking.
|
|
897
|
+
*
|
|
898
|
+
* @example
|
|
899
|
+
* ```typescript
|
|
900
|
+
* await client.bookings.delete("bk_abc123");
|
|
901
|
+
* ```
|
|
902
|
+
*/
|
|
903
|
+
delete(bookingId) {
|
|
904
|
+
return this._delete(this._buildPath(bookingId));
|
|
905
|
+
}
|
|
906
|
+
// ---------------------------------------------------------------------------
|
|
907
|
+
// Lifecycle — happy path
|
|
908
|
+
// ---------------------------------------------------------------------------
|
|
909
|
+
/**
|
|
910
|
+
* Confirm a pending booking.
|
|
911
|
+
*
|
|
912
|
+
* Transitions: `pending` → `confirmed`
|
|
913
|
+
*
|
|
914
|
+
* @throws {ConflictError} 409 if the booking is not in `pending` status
|
|
915
|
+
*
|
|
916
|
+
* @example
|
|
917
|
+
* ```typescript
|
|
918
|
+
* const confirmed = await client.bookings.confirm("bk_abc123");
|
|
919
|
+
* // confirmed.status === "confirmed"
|
|
920
|
+
* // confirmed.confirmedAt is populated
|
|
921
|
+
* ```
|
|
922
|
+
*/
|
|
923
|
+
confirm(bookingId) {
|
|
924
|
+
return this._post(this._buildPath(bookingId, "confirm"), {});
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Check in a guest.
|
|
928
|
+
*
|
|
929
|
+
* Transitions: `confirmed` → `checked_in`
|
|
930
|
+
*
|
|
931
|
+
* @throws {ConflictError} 409 if the booking is not in `confirmed` status
|
|
932
|
+
*
|
|
933
|
+
* @example
|
|
934
|
+
* ```typescript
|
|
935
|
+
* const checkedIn = await client.bookings.checkIn("bk_abc123", {
|
|
936
|
+
* actualArrival: "2025-07-01T14:30:00Z",
|
|
937
|
+
* });
|
|
938
|
+
* // checkedIn.status === "checked_in"
|
|
939
|
+
* // checkedIn.checkedInAt is populated
|
|
940
|
+
* ```
|
|
941
|
+
*/
|
|
942
|
+
checkIn(bookingId, input) {
|
|
943
|
+
return this._post(this._buildPath(bookingId, "check-in"), input ?? {});
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
946
|
+
* Check out a guest.
|
|
947
|
+
*
|
|
948
|
+
* Transitions: `checked_in` → `checked_out`
|
|
949
|
+
*
|
|
950
|
+
* @throws {ConflictError} 409 if the booking is not in `checked_in` status
|
|
951
|
+
*
|
|
952
|
+
* @example
|
|
953
|
+
* ```typescript
|
|
954
|
+
* const checkedOut = await client.bookings.checkOut("bk_abc123", {
|
|
955
|
+
* actualDeparture: "2025-07-05T11:00:00Z",
|
|
956
|
+
* });
|
|
957
|
+
* // checkedOut.status === "checked_out"
|
|
958
|
+
* // checkedOut.checkedOutAt is populated
|
|
959
|
+
* ```
|
|
960
|
+
*/
|
|
961
|
+
checkOut(bookingId, input) {
|
|
962
|
+
return this._post(this._buildPath(bookingId, "check-out"), input ?? {});
|
|
963
|
+
}
|
|
964
|
+
// ---------------------------------------------------------------------------
|
|
965
|
+
// Lifecycle — alternate endings
|
|
966
|
+
// ---------------------------------------------------------------------------
|
|
967
|
+
/**
|
|
968
|
+
* Cancel a booking.
|
|
969
|
+
*
|
|
970
|
+
* Transitions: `pending` | `confirmed` | `checked_in` → `cancelled`
|
|
971
|
+
*
|
|
972
|
+
* @throws {ConflictError} 409 if the booking is already cancelled, checked out, or no-show
|
|
973
|
+
*
|
|
974
|
+
* @example
|
|
975
|
+
* ```typescript
|
|
976
|
+
* const cancelled = await client.bookings.cancel("bk_abc123", {
|
|
977
|
+
* reason: "Guest requested cancellation",
|
|
978
|
+
* refundRequested: true,
|
|
979
|
+
* });
|
|
980
|
+
* // cancelled.status === "cancelled"
|
|
981
|
+
* // cancelled.cancelledAt is populated
|
|
982
|
+
* // cancelled.cancellationReason === "Guest requested cancellation"
|
|
983
|
+
* ```
|
|
984
|
+
*/
|
|
985
|
+
cancel(bookingId, input) {
|
|
986
|
+
return this._post(this._buildPath(bookingId, "cancel"), input);
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Mark a booking as no-show.
|
|
990
|
+
*
|
|
991
|
+
* Transitions: `pending` | `confirmed` | `checked_in` → `no_show`
|
|
992
|
+
*
|
|
993
|
+
* @throws {ConflictError} 409 if the booking is already checked out, cancelled, or no-show
|
|
994
|
+
*
|
|
995
|
+
* @example
|
|
996
|
+
* ```typescript
|
|
997
|
+
* const noShow = await client.bookings.noShow("bk_abc123", {
|
|
998
|
+
* chargeNoShowFee: true,
|
|
999
|
+
* });
|
|
1000
|
+
* // noShow.status === "no_show"
|
|
1001
|
+
* // noShow.noShowAt is populated
|
|
1002
|
+
* ```
|
|
1003
|
+
*/
|
|
1004
|
+
noShow(bookingId, input) {
|
|
1005
|
+
return this._post(this._buildPath(bookingId, "no-show"), input ?? {});
|
|
1006
|
+
}
|
|
1007
|
+
/**
|
|
1008
|
+
* Assign or reassign a space to a booking.
|
|
1009
|
+
*
|
|
1010
|
+
* Can be called on any active booking (pending, confirmed, checked_in).
|
|
1011
|
+
*
|
|
1012
|
+
* @throws {ConflictError} 409 if the booking is in a terminal status
|
|
1013
|
+
*
|
|
1014
|
+
* @example
|
|
1015
|
+
* ```typescript
|
|
1016
|
+
* const assigned = await client.bookings.assignSpace("bk_abc123", {
|
|
1017
|
+
* spaceId: "spc_room101",
|
|
1018
|
+
* notes: "Upgraded to deluxe",
|
|
1019
|
+
* });
|
|
1020
|
+
* // assigned.spaceId === "spc_room101"
|
|
1021
|
+
* // assigned.space is populated
|
|
1022
|
+
* ```
|
|
1023
|
+
*/
|
|
1024
|
+
assignSpace(bookingId, input) {
|
|
1025
|
+
return this._post(this._buildPath(bookingId, "assign-space"), input);
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
|
|
526
1029
|
// src/services/categories.ts
|
|
527
1030
|
var CategoriesService = class extends BaseService {
|
|
528
1031
|
constructor() {
|
|
@@ -807,6 +1310,16 @@ var BookingClient = class {
|
|
|
807
1310
|
logger: validated.logger
|
|
808
1311
|
});
|
|
809
1312
|
}
|
|
1313
|
+
/** Availability service — lazy-initialized on first access */
|
|
1314
|
+
get availability() {
|
|
1315
|
+
this._availability ?? (this._availability = new AvailabilityService(this.httpClient));
|
|
1316
|
+
return this._availability;
|
|
1317
|
+
}
|
|
1318
|
+
/** Bookings service — lazy-initialized on first access */
|
|
1319
|
+
get bookings() {
|
|
1320
|
+
this._bookings ?? (this._bookings = new BookingsService(this.httpClient));
|
|
1321
|
+
return this._bookings;
|
|
1322
|
+
}
|
|
810
1323
|
/** Properties service — lazy-initialized on first access */
|
|
811
1324
|
get properties() {
|
|
812
1325
|
this._properties ?? (this._properties = new PropertiesService(this.httpClient));
|
|
@@ -861,6 +1374,27 @@ async function firstPage(fetcher, options) {
|
|
|
861
1374
|
return fetcher({ ...options ?? {} });
|
|
862
1375
|
}
|
|
863
1376
|
|
|
1377
|
+
// src/types/bookings.ts
|
|
1378
|
+
var BOOKING_TYPES = [
|
|
1379
|
+
"stay",
|
|
1380
|
+
"table",
|
|
1381
|
+
"service",
|
|
1382
|
+
"parking",
|
|
1383
|
+
"desk",
|
|
1384
|
+
"meeting",
|
|
1385
|
+
"dayuse",
|
|
1386
|
+
"custom"
|
|
1387
|
+
];
|
|
1388
|
+
var BOOKING_STATUSES = [
|
|
1389
|
+
"pending",
|
|
1390
|
+
"confirmed",
|
|
1391
|
+
"checked_in",
|
|
1392
|
+
"checked_out",
|
|
1393
|
+
"cancelled",
|
|
1394
|
+
"no_show",
|
|
1395
|
+
"waitlist"
|
|
1396
|
+
];
|
|
1397
|
+
|
|
864
1398
|
// src/types/properties.ts
|
|
865
1399
|
var PROPERTY_MODULES = [
|
|
866
1400
|
"booking",
|
|
@@ -910,8 +1444,12 @@ var VERSION = "0.1.0";
|
|
|
910
1444
|
// Annotate the CommonJS export names for ESM import in node:
|
|
911
1445
|
0 && (module.exports = {
|
|
912
1446
|
AuthenticationError,
|
|
1447
|
+
AvailabilityService,
|
|
1448
|
+
BOOKING_STATUSES,
|
|
1449
|
+
BOOKING_TYPES,
|
|
913
1450
|
BookingClient,
|
|
914
1451
|
BookingError,
|
|
1452
|
+
BookingsService,
|
|
915
1453
|
CategoriesService,
|
|
916
1454
|
ConflictError,
|
|
917
1455
|
DEFAULT_MODULES,
|