@voyant-travel/catalog-react 0.117.2

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.
Files changed (220) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +36 -0
  3. package/dist/admin/catalog-vertical-host.d.ts +45 -0
  4. package/dist/admin/catalog-vertical-host.d.ts.map +1 -0
  5. package/dist/admin/catalog-vertical-host.js +230 -0
  6. package/dist/admin/cruise-detail-host.d.ts +11 -0
  7. package/dist/admin/cruise-detail-host.d.ts.map +1 -0
  8. package/dist/admin/cruise-detail-host.js +33 -0
  9. package/dist/admin/dynamic-catalog-host.d.ts +13 -0
  10. package/dist/admin/dynamic-catalog-host.d.ts.map +1 -0
  11. package/dist/admin/dynamic-catalog-host.js +17 -0
  12. package/dist/admin/index.d.ts +133 -0
  13. package/dist/admin/index.d.ts.map +1 -0
  14. package/dist/admin/index.js +144 -0
  15. package/dist/admin/open-in-new-tab.d.ts +7 -0
  16. package/dist/admin/open-in-new-tab.d.ts.map +1 -0
  17. package/dist/admin/open-in-new-tab.js +10 -0
  18. package/dist/admin/pages/catalog-accommodations-detail-page.d.ts +4 -0
  19. package/dist/admin/pages/catalog-accommodations-detail-page.d.ts.map +1 -0
  20. package/dist/admin/pages/catalog-accommodations-detail-page.js +7 -0
  21. package/dist/admin/pages/catalog-accommodations-index-page.d.ts +8 -0
  22. package/dist/admin/pages/catalog-accommodations-index-page.d.ts.map +1 -0
  23. package/dist/admin/pages/catalog-accommodations-index-page.js +17 -0
  24. package/dist/admin/pages/catalog-cruises-detail-page.d.ts +4 -0
  25. package/dist/admin/pages/catalog-cruises-detail-page.d.ts.map +1 -0
  26. package/dist/admin/pages/catalog-cruises-detail-page.js +7 -0
  27. package/dist/admin/pages/catalog-cruises-index-page.d.ts +8 -0
  28. package/dist/admin/pages/catalog-cruises-index-page.d.ts.map +1 -0
  29. package/dist/admin/pages/catalog-cruises-index-page.js +19 -0
  30. package/dist/admin/pages/catalog-excursions-detail-page.d.ts +4 -0
  31. package/dist/admin/pages/catalog-excursions-detail-page.d.ts.map +1 -0
  32. package/dist/admin/pages/catalog-excursions-detail-page.js +7 -0
  33. package/dist/admin/pages/catalog-excursions-index-page.d.ts +8 -0
  34. package/dist/admin/pages/catalog-excursions-index-page.d.ts.map +1 -0
  35. package/dist/admin/pages/catalog-excursions-index-page.js +12 -0
  36. package/dist/admin/pages/catalog-products-detail-page.d.ts +8 -0
  37. package/dist/admin/pages/catalog-products-detail-page.d.ts.map +1 -0
  38. package/dist/admin/pages/catalog-products-detail-page.js +12 -0
  39. package/dist/admin/pages/catalog-products-index-page.d.ts +8 -0
  40. package/dist/admin/pages/catalog-products-index-page.d.ts.map +1 -0
  41. package/dist/admin/pages/catalog-products-index-page.js +12 -0
  42. package/dist/admin/pages/catalog-tours-detail-page.d.ts +4 -0
  43. package/dist/admin/pages/catalog-tours-detail-page.d.ts.map +1 -0
  44. package/dist/admin/pages/catalog-tours-detail-page.js +7 -0
  45. package/dist/admin/pages/catalog-tours-index-page.d.ts +8 -0
  46. package/dist/admin/pages/catalog-tours-index-page.d.ts.map +1 -0
  47. package/dist/admin/pages/catalog-tours-index-page.js +12 -0
  48. package/dist/admin/product-detail-host.d.ts +18 -0
  49. package/dist/admin/product-detail-host.d.ts.map +1 -0
  50. package/dist/admin/product-detail-host.js +40 -0
  51. package/dist/admin/scheduled-catalog-host.d.ts +15 -0
  52. package/dist/admin/scheduled-catalog-host.d.ts.map +1 -0
  53. package/dist/admin/scheduled-catalog-host.js +19 -0
  54. package/dist/admin/vertical-detail-host.d.ts +13 -0
  55. package/dist/admin/vertical-detail-host.d.ts.map +1 -0
  56. package/dist/admin/vertical-detail-host.js +62 -0
  57. package/dist/booking-engine/index.d.ts +26 -0
  58. package/dist/booking-engine/index.d.ts.map +1 -0
  59. package/dist/booking-engine/index.js +25 -0
  60. package/dist/booking-engine/use-booking-commit.d.ts +61 -0
  61. package/dist/booking-engine/use-booking-commit.d.ts.map +1 -0
  62. package/dist/booking-engine/use-booking-commit.js +47 -0
  63. package/dist/booking-engine/use-booking-draft-shape.d.ts +20 -0
  64. package/dist/booking-engine/use-booking-draft-shape.d.ts.map +1 -0
  65. package/dist/booking-engine/use-booking-draft-shape.js +9 -0
  66. package/dist/booking-engine/use-booking-draft.d.ts +102 -0
  67. package/dist/booking-engine/use-booking-draft.d.ts.map +1 -0
  68. package/dist/booking-engine/use-booking-draft.js +93 -0
  69. package/dist/booking-engine/use-booking-hold.d.ts +30 -0
  70. package/dist/booking-engine/use-booking-hold.d.ts.map +1 -0
  71. package/dist/booking-engine/use-booking-hold.js +44 -0
  72. package/dist/booking-engine/use-booking-journey-api.d.ts +23 -0
  73. package/dist/booking-engine/use-booking-journey-api.d.ts.map +1 -0
  74. package/dist/booking-engine/use-booking-journey-api.js +24 -0
  75. package/dist/booking-engine/use-booking-quote.d.ts +711 -0
  76. package/dist/booking-engine/use-booking-quote.d.ts.map +1 -0
  77. package/dist/booking-engine/use-booking-quote.js +122 -0
  78. package/dist/catalog-enrichment-mappers.d.ts +162 -0
  79. package/dist/catalog-enrichment-mappers.d.ts.map +1 -0
  80. package/dist/catalog-enrichment-mappers.js +190 -0
  81. package/dist/catalog-enrichment.d.ts +203 -0
  82. package/dist/catalog-enrichment.d.ts.map +1 -0
  83. package/dist/catalog-enrichment.js +130 -0
  84. package/dist/catalog-offers-client.d.ts +58 -0
  85. package/dist/catalog-offers-client.d.ts.map +1 -0
  86. package/dist/catalog-offers-client.js +61 -0
  87. package/dist/catalog-search-params.d.ts +45 -0
  88. package/dist/catalog-search-params.d.ts.map +1 -0
  89. package/dist/catalog-search-params.js +30 -0
  90. package/dist/catalog-surfaces.d.ts +17 -0
  91. package/dist/catalog-surfaces.d.ts.map +1 -0
  92. package/dist/catalog-surfaces.js +26 -0
  93. package/dist/client.d.ts +20 -0
  94. package/dist/client.d.ts.map +1 -0
  95. package/dist/client.js +65 -0
  96. package/dist/components/availability-calendar.d.ts +33 -0
  97. package/dist/components/availability-calendar.d.ts.map +1 -0
  98. package/dist/components/availability-calendar.js +65 -0
  99. package/dist/components/catalog-browse-page.d.ts +41 -0
  100. package/dist/components/catalog-browse-page.d.ts.map +1 -0
  101. package/dist/components/catalog-browse-page.js +47 -0
  102. package/dist/components/catalog-card.d.ts +68 -0
  103. package/dist/components/catalog-card.d.ts.map +1 -0
  104. package/dist/components/catalog-card.js +52 -0
  105. package/dist/components/catalog-detail-cruise-cards.d.ts +16 -0
  106. package/dist/components/catalog-detail-cruise-cards.d.ts.map +1 -0
  107. package/dist/components/catalog-detail-cruise-cards.js +54 -0
  108. package/dist/components/catalog-detail-departures.d.ts +25 -0
  109. package/dist/components/catalog-detail-departures.d.ts.map +1 -0
  110. package/dist/components/catalog-detail-departures.js +240 -0
  111. package/dist/components/catalog-detail-parts.d.ts +70 -0
  112. package/dist/components/catalog-detail-parts.d.ts.map +1 -0
  113. package/dist/components/catalog-detail-parts.js +282 -0
  114. package/dist/components/catalog-detail-sheet.d.ts +93 -0
  115. package/dist/components/catalog-detail-sheet.d.ts.map +1 -0
  116. package/dist/components/catalog-detail-sheet.js +68 -0
  117. package/dist/components/catalog-detail-view.d.ts +39 -0
  118. package/dist/components/catalog-detail-view.d.ts.map +1 -0
  119. package/dist/components/catalog-detail-view.js +157 -0
  120. package/dist/components/catalog-enrichment-fetchers.d.ts +8 -0
  121. package/dist/components/catalog-enrichment-fetchers.d.ts.map +1 -0
  122. package/dist/components/catalog-enrichment-fetchers.js +7 -0
  123. package/dist/components/catalog-faceted-filter.d.ts +30 -0
  124. package/dist/components/catalog-faceted-filter.d.ts.map +1 -0
  125. package/dist/components/catalog-faceted-filter.js +24 -0
  126. package/dist/components/catalog-filter-rail.d.ts +25 -0
  127. package/dist/components/catalog-filter-rail.d.ts.map +1 -0
  128. package/dist/components/catalog-filter-rail.js +88 -0
  129. package/dist/components/catalog-gallery.d.ts +27 -0
  130. package/dist/components/catalog-gallery.d.ts.map +1 -0
  131. package/dist/components/catalog-gallery.js +66 -0
  132. package/dist/components/catalog-hit.d.ts +27 -0
  133. package/dist/components/catalog-hit.d.ts.map +1 -0
  134. package/dist/components/catalog-hit.js +57 -0
  135. package/dist/components/catalog-page-cards.d.ts +21 -0
  136. package/dist/components/catalog-page-cards.d.ts.map +1 -0
  137. package/dist/components/catalog-page-cards.js +174 -0
  138. package/dist/components/catalog-page-config.d.ts +17 -0
  139. package/dist/components/catalog-page-config.d.ts.map +1 -0
  140. package/dist/components/catalog-page-config.js +369 -0
  141. package/dist/components/catalog-page.d.ts +88 -0
  142. package/dist/components/catalog-page.d.ts.map +1 -0
  143. package/dist/components/catalog-page.js +148 -0
  144. package/dist/components/catalog-range-filter.d.ts +34 -0
  145. package/dist/components/catalog-range-filter.d.ts.map +1 -0
  146. package/dist/components/catalog-range-filter.js +72 -0
  147. package/dist/components/catalog-search-page.d.ts +239 -0
  148. package/dist/components/catalog-search-page.d.ts.map +1 -0
  149. package/dist/components/catalog-search-page.js +63 -0
  150. package/dist/components/catalog-search-tab-panel.d.ts +42 -0
  151. package/dist/components/catalog-search-tab-panel.d.ts.map +1 -0
  152. package/dist/components/catalog-search-tab-panel.js +199 -0
  153. package/dist/components/catalog-vertical-detail-page.d.ts +33 -0
  154. package/dist/components/catalog-vertical-detail-page.d.ts.map +1 -0
  155. package/dist/components/catalog-vertical-detail-page.js +100 -0
  156. package/dist/components/cruise-detail-page-parts.d.ts +72 -0
  157. package/dist/components/cruise-detail-page-parts.d.ts.map +1 -0
  158. package/dist/components/cruise-detail-page-parts.js +146 -0
  159. package/dist/components/cruise-detail-page.d.ts +21 -0
  160. package/dist/components/cruise-detail-page.d.ts.map +1 -0
  161. package/dist/components/cruise-detail-page.js +201 -0
  162. package/dist/components/dynamic-catalog-page-parts.d.ts +40 -0
  163. package/dist/components/dynamic-catalog-page-parts.d.ts.map +1 -0
  164. package/dist/components/dynamic-catalog-page-parts.js +43 -0
  165. package/dist/components/dynamic-catalog-page.d.ts +23 -0
  166. package/dist/components/dynamic-catalog-page.d.ts.map +1 -0
  167. package/dist/components/dynamic-catalog-page.js +270 -0
  168. package/dist/components/media-gallery.d.ts +13 -0
  169. package/dist/components/media-gallery.d.ts.map +1 -0
  170. package/dist/components/media-gallery.js +42 -0
  171. package/dist/components/product-detail-page-parts.d.ts +106 -0
  172. package/dist/components/product-detail-page-parts.d.ts.map +1 -0
  173. package/dist/components/product-detail-page-parts.js +130 -0
  174. package/dist/components/product-detail-page.d.ts +57 -0
  175. package/dist/components/product-detail-page.d.ts.map +1 -0
  176. package/dist/components/product-detail-page.js +175 -0
  177. package/dist/components/scheduled-catalog-page.d.ts +34 -0
  178. package/dist/components/scheduled-catalog-page.d.ts.map +1 -0
  179. package/dist/components/scheduled-catalog-page.js +6 -0
  180. package/dist/hooks/index.d.ts +3 -0
  181. package/dist/hooks/index.d.ts.map +1 -0
  182. package/dist/hooks/index.js +2 -0
  183. package/dist/hooks/use-catalog-offers.d.ts +186 -0
  184. package/dist/hooks/use-catalog-offers.d.ts.map +1 -0
  185. package/dist/hooks/use-catalog-offers.js +105 -0
  186. package/dist/hooks/use-catalog-search.d.ts +109 -0
  187. package/dist/hooks/use-catalog-search.d.ts.map +1 -0
  188. package/dist/hooks/use-catalog-search.js +52 -0
  189. package/dist/i18n/en.d.ts +397 -0
  190. package/dist/i18n/en.d.ts.map +1 -0
  191. package/dist/i18n/en.js +396 -0
  192. package/dist/i18n/index.d.ts +5 -0
  193. package/dist/i18n/index.d.ts.map +1 -0
  194. package/dist/i18n/index.js +3 -0
  195. package/dist/i18n/messages.d.ts +335 -0
  196. package/dist/i18n/messages.d.ts.map +1 -0
  197. package/dist/i18n/messages.js +1 -0
  198. package/dist/i18n/provider.d.ts +816 -0
  199. package/dist/i18n/provider.d.ts.map +1 -0
  200. package/dist/i18n/provider.js +44 -0
  201. package/dist/i18n/ro.d.ts +397 -0
  202. package/dist/i18n/ro.d.ts.map +1 -0
  203. package/dist/i18n/ro.js +396 -0
  204. package/dist/index.d.ts +9 -0
  205. package/dist/index.d.ts.map +1 -0
  206. package/dist/index.js +17 -0
  207. package/dist/provider.d.ts +2 -0
  208. package/dist/provider.d.ts.map +1 -0
  209. package/dist/provider.js +1 -0
  210. package/dist/schemas-catalog-offers.d.ts +290 -0
  211. package/dist/schemas-catalog-offers.d.ts.map +1 -0
  212. package/dist/schemas-catalog-offers.js +155 -0
  213. package/dist/schemas.d.ts +143 -0
  214. package/dist/schemas.d.ts.map +1 -0
  215. package/dist/schemas.js +76 -0
  216. package/dist/ui.d.ts +19 -0
  217. package/dist/ui.d.ts.map +1 -0
  218. package/dist/ui.js +18 -0
  219. package/package.json +150 -0
  220. package/src/styles.css +11 -0
@@ -0,0 +1,15 @@
1
+ import { type ScheduledScope } from "../components/scheduled-catalog-page.js";
2
+ import type { CatalogSearchParams } from "../index.js";
3
+ export interface ScheduledCatalogHostProps {
4
+ scope: ScheduledScope;
5
+ search: CatalogSearchParams;
6
+ onSearchChange: (updater: (prev: CatalogSearchParams) => CatalogSearchParams, replace?: boolean) => void;
7
+ }
8
+ /**
9
+ * Packaged admin host for `ScheduledCatalogPage` — supplies the localized
10
+ * title/tagline and renders `CatalogVerticalHost` (markets/suppliers/products
11
+ * wiring) as the embedded browse grid, opening each result's vertical detail
12
+ * page (the `catalog.detail` destination) in a new tab on click.
13
+ */
14
+ export declare function ScheduledCatalogHost({ scope, search, onSearchChange }: ScheduledCatalogHostProps): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=scheduled-catalog-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduled-catalog-host.d.ts","sourceRoot":"","sources":["../../src/admin/scheduled-catalog-host.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,yCAAyC,CAAA;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAItD,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,cAAc,CAAA;IACrB,MAAM,EAAE,mBAAmB,CAAA;IAC3B,cAAc,EAAE,CACd,OAAO,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,mBAAmB,EAC3D,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAA;CACV;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,yBAAyB,2CA0BhG"}
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useAdminHref, useOperatorAdminMessages } from "@voyant-travel/admin";
4
+ import { ScheduledCatalogPage as ScheduledCatalogPageUi, } from "../components/scheduled-catalog-page.js";
5
+ import { CatalogVerticalHost } from "./catalog-vertical-host.js";
6
+ import { openHrefInNewTab } from "./open-in-new-tab.js";
7
+ /**
8
+ * Packaged admin host for `ScheduledCatalogPage` — supplies the localized
9
+ * title/tagline and renders `CatalogVerticalHost` (markets/suppliers/products
10
+ * wiring) as the embedded browse grid, opening each result's vertical detail
11
+ * page (the `catalog.detail` destination) in a new tab on click.
12
+ */
13
+ export function ScheduledCatalogHost({ scope, search, onSearchChange }) {
14
+ const resolveHref = useAdminHref();
15
+ const nav = useOperatorAdminMessages().nav;
16
+ const title = scope === "excursions" ? nav.catalogExcursions : nav.catalogTours;
17
+ const subtitle = scope === "excursions" ? nav.catalogExcursionsTagline : nav.catalogToursTagline;
18
+ return (_jsx(ScheduledCatalogPageUi, { scope: scope, title: title, subtitle: subtitle, renderBrowseGrid: ({ lockedFacets, lockedRanges }) => (_jsx(CatalogVerticalHost, { vertical: "products", search: search, onSearchChange: onSearchChange, embedded: true, lockedFacets: lockedFacets, lockedRanges: lockedRanges, onOpenDetail: (hit) => openHrefInNewTab(resolveHref("catalog.detail", { surface: scope, id: hit.id })) })) }));
19
+ }
@@ -0,0 +1,13 @@
1
+ import { type CatalogDetailSurface } from "../catalog-surfaces.js";
2
+ export interface VerticalDetailHostProps {
3
+ surface: CatalogDetailSurface;
4
+ id: string;
5
+ }
6
+ /**
7
+ * Packaged admin host for `CatalogVerticalDetailPage` — binds the supplier
8
+ * directory, the localized surface label, semantic-destination navigation
9
+ * into the booking journey (packaged-admin RFC §4.7), and breadcrumbs, so
10
+ * host route files stay trivial.
11
+ */
12
+ export declare function VerticalDetailHost({ surface, id }: VerticalDetailHostProps): import("react/jsx-runtime").JSX.Element;
13
+ //# sourceMappingURL=vertical-detail-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vertical-detail-host.d.ts","sourceRoot":"","sources":["../../src/admin/vertical-detail-host.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,oBAAoB,EAA0B,MAAM,wBAAwB,CAAA;AAM1F,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,oBAAoB,CAAA;IAC7B,EAAE,EAAE,MAAM,CAAA;CACX;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,uBAAuB,2CA+C1E"}
@@ -0,0 +1,62 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useAdminBreadcrumbs, useAdminHref, useAdminNavigate, useOperatorAdminMessages, } from "@voyant-travel/admin";
4
+ import { useSuppliers } from "@voyant-travel/distribution-react/suppliers";
5
+ import { useMemo, useState } from "react";
6
+ import { catalogSurfaceVertical } from "../catalog-surfaces.js";
7
+ import { CatalogVerticalDetailPage, } from "../components/catalog-vertical-detail-page.js";
8
+ /**
9
+ * Packaged admin host for `CatalogVerticalDetailPage` — binds the supplier
10
+ * directory, the localized surface label, semantic-destination navigation
11
+ * into the booking journey (packaged-admin RFC §4.7), and breadcrumbs, so
12
+ * host route files stay trivial.
13
+ */
14
+ export function VerticalDetailHost({ surface, id }) {
15
+ const resolveHref = useAdminHref();
16
+ const navigateTo = useAdminNavigate();
17
+ const nav = useOperatorAdminMessages().nav;
18
+ const vertical = catalogSurfaceVertical(surface);
19
+ const surfaceLabel = surfaceTitle(surface, nav);
20
+ const surfaceHref = resolveHref("catalog.browse", { surface });
21
+ const suppliersQuery = useSuppliers({ limit: 100 });
22
+ const formatSupplier = useMemo(() => {
23
+ const m = new Map();
24
+ for (const sup of suppliersQuery.data?.data ?? [])
25
+ m.set(sup.id, sup.name);
26
+ return (sid) => m.get(String(sid)) ?? String(sid);
27
+ }, [suppliersQuery.data]);
28
+ // The packaged page resolves the title from content; mirror its breadcrumbs
29
+ // into the admin breadcrumb bar.
30
+ const [crumbs, setCrumbs] = useState([
31
+ { label: surfaceLabel, href: surfaceHref },
32
+ ]);
33
+ useAdminBreadcrumbs(crumbs);
34
+ return (_jsx(CatalogVerticalDetailPage, { id: id, vertical: vertical, surfaceLabel: surfaceLabel, surfaceHref: surfaceHref, formatSupplier: formatSupplier, onBreadcrumbs: setCrumbs,
35
+ // Connect-sourced vertical (accommodation/excursion/tour) → the unified
36
+ // journey. The picked departure's date locks the departure step; name/hero
37
+ // preview the panel.
38
+ onBook: (entityModule, entityId, opts) => navigateTo("bookingJourney.start", {
39
+ entityModule,
40
+ entityId,
41
+ sourceKind: "voyant-connect",
42
+ ...(opts.departureId ? { departureId: opts.departureId } : {}),
43
+ ...(opts.departureDate ? { departureDate: opts.departureDate.slice(0, 10) } : {}),
44
+ ...(opts.optionId ? { optionId: opts.optionId } : {}),
45
+ ...(opts.name ? { entityName: opts.name } : {}),
46
+ ...(opts.heroImageUrl ? { entityImageUrl: opts.heroImageUrl } : {}),
47
+ }) }));
48
+ }
49
+ function surfaceTitle(surface, nav) {
50
+ switch (surface) {
51
+ case "cruises":
52
+ return nav.catalogCruises;
53
+ case "accommodations":
54
+ return nav.catalogAccommodations;
55
+ case "excursions":
56
+ return nav.catalogExcursions;
57
+ case "tours":
58
+ return nav.catalogTours;
59
+ default:
60
+ return nav.catalogProducts;
61
+ }
62
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `@voyant-travel/catalog-react/booking-engine` — React Query hooks
3
+ * driving the unified booking journey shell.
4
+ *
5
+ * Per `docs/architecture/booking-journey-architecture.md` §8.1.
6
+ *
7
+ * Hooks:
8
+ * - `useBookingDraft` — local draft state with server sync
9
+ * - `useBookingQuote` — debounced live quote on draft change
10
+ * - `useBookingDraftShape` — convenience accessor on the latest quote
11
+ * - `useBookingCommit` — final book mutation, triggers handoff
12
+ *
13
+ * The hooks share a `useBookingJourneyApi()` accessor that derives
14
+ * the API base from the surrounding `VoyantCatalogProvider` and
15
+ * lets callers override the surface (`/v1/admin` vs `/v1/public`).
16
+ *
17
+ * Identical surface for operator and storefront — Phase B's "build
18
+ * once, ship everywhere" rule (§ Rule 4).
19
+ */
20
+ export { type UseBookingCommitOptions, useBookingCommit, } from "./use-booking-commit.js";
21
+ export { type UseBookingDraftOptions, useBookingDraft, } from "./use-booking-draft.js";
22
+ export { type UseBookingDraftShapeOptions, useBookingDraftShape, } from "./use-booking-draft-shape.js";
23
+ export { type PlaceHoldInput, type ReleaseHoldInput, useBookingHold, } from "./use-booking-hold.js";
24
+ export { type BookingJourneyApiOptions, type UseBookingJourneyApi, useBookingJourneyApi, } from "./use-booking-journey-api.js";
25
+ export { type UseBookingQuoteOptions, useBookingQuote, } from "./use-booking-quote.js";
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/booking-engine/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,KAAK,uBAAuB,EAC5B,gBAAgB,GACjB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,KAAK,sBAAsB,EAC3B,eAAe,GAChB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,KAAK,2BAA2B,EAChC,oBAAoB,GACrB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,cAAc,GACf,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,oBAAoB,GACrB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EACL,KAAK,sBAAsB,EAC3B,eAAe,GAChB,MAAM,wBAAwB,CAAA"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `@voyant-travel/catalog-react/booking-engine` — React Query hooks
3
+ * driving the unified booking journey shell.
4
+ *
5
+ * Per `docs/architecture/booking-journey-architecture.md` §8.1.
6
+ *
7
+ * Hooks:
8
+ * - `useBookingDraft` — local draft state with server sync
9
+ * - `useBookingQuote` — debounced live quote on draft change
10
+ * - `useBookingDraftShape` — convenience accessor on the latest quote
11
+ * - `useBookingCommit` — final book mutation, triggers handoff
12
+ *
13
+ * The hooks share a `useBookingJourneyApi()` accessor that derives
14
+ * the API base from the surrounding `VoyantCatalogProvider` and
15
+ * lets callers override the surface (`/v1/admin` vs `/v1/public`).
16
+ *
17
+ * Identical surface for operator and storefront — Phase B's "build
18
+ * once, ship everywhere" rule (§ Rule 4).
19
+ */
20
+ export { useBookingCommit, } from "./use-booking-commit.js";
21
+ export { useBookingDraft, } from "./use-booking-draft.js";
22
+ export { useBookingDraftShape, } from "./use-booking-draft-shape.js";
23
+ export { useBookingHold, } from "./use-booking-hold.js";
24
+ export { useBookingJourneyApi, } from "./use-booking-journey-api.js";
25
+ export { useBookingQuote, } from "./use-booking-quote.js";
@@ -0,0 +1,61 @@
1
+ import { type BookingDraftV1, type BookingPaymentIntent, type BookResponseV1 } from "@voyant-travel/catalog-contracts/booking-engine/contracts";
2
+ import { type BookingJourneyApiOptions } from "./use-booking-journey-api.js";
3
+ export interface UseBookingCommitOptions extends BookingJourneyApiOptions {
4
+ /** Draft id — when set, the engine resolves the quote off the draft
5
+ * and the draft is marked consumed on success. */
6
+ draftId?: string;
7
+ /** Optional callback fired on successful commit. Templates use this
8
+ * for post-commit navigation (operator → /orders, storefront →
9
+ * /confirmation). */
10
+ onCommitted?: (result: BookResponseV1) => void;
11
+ }
12
+ export interface CommitInput {
13
+ /** Either-or: pass the draft for context-aware commit, or just a
14
+ * quoteId when the journey hasn't materialized a draft yet. */
15
+ draft?: BookingDraftV1;
16
+ quoteId?: string;
17
+ party?: Record<string, unknown>;
18
+ paymentIntent?: BookingPaymentIntent;
19
+ /** Initial booking status the owned handler should land on (draft /
20
+ * awaiting_payment / confirmed). When omitted, the create defaults to draft. */
21
+ initialStatus?: string;
22
+ /** Idempotency key — same key in 24h returns the existing booking. */
23
+ idempotencyKey?: string;
24
+ }
25
+ /**
26
+ * Final book mutation — calls `POST /catalog/book` with the chosen
27
+ * quoteId or draftId. The wizard's Review step calls this when the
28
+ * user clicks Confirm. Per booking-journey-architecture §8 + §10
29
+ * Phase B.
30
+ */
31
+ export declare function useBookingCommit(options?: UseBookingCommitOptions): import("@tanstack/react-query").UseMutationResult<{
32
+ bookingId: string;
33
+ orderRef: string;
34
+ status: "failed" | "confirmed" | "held" | "ticketed";
35
+ snapshotId: string;
36
+ pricing?: {
37
+ currency: string;
38
+ lines: {
39
+ kind: "base" | "accommodation" | "fee" | "discount" | "addon" | "supplement";
40
+ label: string;
41
+ unitAmount: number;
42
+ totalAmount: number;
43
+ quantity?: number | undefined;
44
+ taxIncluded?: boolean | undefined;
45
+ }[];
46
+ taxes: {
47
+ code: string;
48
+ label: string;
49
+ rate: number;
50
+ amount: number;
51
+ base: number;
52
+ includedInPrice?: boolean | undefined;
53
+ scope?: "included" | "excluded" | "withheld" | undefined;
54
+ }[];
55
+ subtotal: number;
56
+ taxTotal: number;
57
+ total: number;
58
+ } | undefined;
59
+ upstreamPayload?: Record<string, unknown> | undefined;
60
+ }, Error, CommitInput, unknown>;
61
+ //# sourceMappingURL=use-booking-commit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-booking-commit.d.ts","sourceRoot":"","sources":["../../src/booking-engine/use-booking-commit.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EAEpB,MAAM,2DAA2D,CAAA;AAElE,OAAO,EAAE,KAAK,wBAAwB,EAAwB,MAAM,8BAA8B,CAAA;AAElG,MAAM,WAAW,uBAAwB,SAAQ,wBAAwB;IACvE;uDACmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;0BAEsB;IACtB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAA;CAC/C;AAED,MAAM,WAAW,WAAW;IAC1B;oEACgE;IAChE,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,aAAa,CAAC,EAAE,oBAAoB,CAAA;IACpC;qFACiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCA+BrE"}
@@ -0,0 +1,47 @@
1
+ "use client";
2
+ import { useMutation } from "@tanstack/react-query";
3
+ import { bookResponseV1, } from "@voyant-travel/catalog-contracts/booking-engine/contracts";
4
+ import { useBookingJourneyApi } from "./use-booking-journey-api.js";
5
+ /**
6
+ * Final book mutation — calls `POST /catalog/book` with the chosen
7
+ * quoteId or draftId. The wizard's Review step calls this when the
8
+ * user clicks Confirm. Per booking-journey-architecture §8 + §10
9
+ * Phase B.
10
+ */
11
+ export function useBookingCommit(options = {}) {
12
+ const api = useBookingJourneyApi(options);
13
+ return useMutation({
14
+ mutationFn: async (input) => {
15
+ // Auto-generate an idempotency key when the caller didn't pass
16
+ // one — protects against double-clicks. The key is stable for
17
+ // the lifetime of the mutation function call (one user click =
18
+ // one key); a manual retry from the journey shell uses the same
19
+ // key by passing it explicitly.
20
+ const idempotencyKey = input.idempotencyKey ?? generateIdempotencyKey(input.draft?.entity?.id ?? input.quoteId);
21
+ const body = {
22
+ quoteId: input.quoteId ?? input.draft?.quoteId,
23
+ draftId: options.draftId,
24
+ party: input.party,
25
+ paymentIntent: input.paymentIntent,
26
+ idempotencyKey,
27
+ };
28
+ if (input.draft || input.initialStatus) {
29
+ body.parameters = {
30
+ ...(input.draft ? { draft: input.draft } : {}),
31
+ ...(input.initialStatus ? { initialStatus: input.initialStatus } : {}),
32
+ };
33
+ }
34
+ return api.request("POST", "/book", bookResponseV1, body);
35
+ },
36
+ onSuccess(result) {
37
+ options.onCommitted?.(result);
38
+ },
39
+ });
40
+ }
41
+ function generateIdempotencyKey(seed) {
42
+ const base = seed ?? "anon";
43
+ if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.randomUUID) {
44
+ return `${base.slice(0, 32)}_${globalThis.crypto.randomUUID().replace(/-/g, "")}`;
45
+ }
46
+ return `${base.slice(0, 32)}_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 12)}`;
47
+ }
@@ -0,0 +1,20 @@
1
+ import type { BookingDraftShape } from "@voyant-travel/catalog-contracts/booking-engine/draft-shape";
2
+ import type { BookingJourneyApiOptions } from "./use-booking-journey-api.js";
3
+ export interface UseBookingDraftShapeOptions extends BookingJourneyApiOptions {
4
+ /** Quote response — typically passed in from the wrapping
5
+ * `useBookingQuote()`. */
6
+ quote: {
7
+ shape?: BookingDraftShape;
8
+ } | null;
9
+ /** Fallback shape rendered when the quote hasn't loaded yet — the
10
+ * journey shell uses this so the wizard renders an empty Configure
11
+ * step on first paint. */
12
+ fallback: BookingDraftShape;
13
+ }
14
+ /**
15
+ * Convenience accessor that returns the descriptor a quote response
16
+ * carries — or a caller-supplied fallback while we wait for the
17
+ * first quote. Per booking-journey-architecture §3 + §8.1.
18
+ */
19
+ export declare function useBookingDraftShape(options: UseBookingDraftShapeOptions): BookingDraftShape;
20
+ //# sourceMappingURL=use-booking-draft-shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-booking-draft-shape.d.ts","sourceRoot":"","sources":["../../src/booking-engine/use-booking-draft-shape.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6DAA6D,CAAA;AAEpG,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAA;AAE5E,MAAM,WAAW,2BAA4B,SAAQ,wBAAwB;IAC3E;+BAC2B;IAC3B,KAAK,EAAE;QAAE,KAAK,CAAC,EAAE,iBAAiB,CAAA;KAAE,GAAG,IAAI,CAAA;IAC3C;;+BAE2B;IAC3B,QAAQ,EAAE,iBAAiB,CAAA;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,iBAAiB,CAE5F"}
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ /**
3
+ * Convenience accessor that returns the descriptor a quote response
4
+ * carries — or a caller-supplied fallback while we wait for the
5
+ * first quote. Per booking-journey-architecture §3 + §8.1.
6
+ */
7
+ export function useBookingDraftShape(options) {
8
+ return options.quote?.shape ?? options.fallback;
9
+ }
@@ -0,0 +1,102 @@
1
+ import { type BookingDraftV1 } from "@voyant-travel/catalog-contracts/booking-engine/contracts";
2
+ import { z } from "zod";
3
+ import { type BookingJourneyApiOptions } from "./use-booking-journey-api.js";
4
+ declare const draftRowSchema: z.ZodObject<{
5
+ id: z.ZodString;
6
+ entity_module: z.ZodString;
7
+ entity_id: z.ZodString;
8
+ source_kind: z.ZodString;
9
+ source_connection_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
10
+ source_ref: z.ZodOptional<z.ZodNullable<z.ZodString>>;
11
+ draft_payload: z.ZodUnknown;
12
+ current_step: z.ZodOptional<z.ZodNullable<z.ZodString>>;
13
+ current_quote_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
14
+ hold_expires_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
15
+ consumed_booking_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
16
+ consumed_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
17
+ expires_at: z.ZodString;
18
+ created_at: z.ZodString;
19
+ updated_at: z.ZodString;
20
+ }, z.core.$strip>;
21
+ export type DraftRow = z.infer<typeof draftRowSchema>;
22
+ export interface UseBookingDraftOptions extends BookingJourneyApiOptions {
23
+ /** Stable draft id — caller generates and persists in URL or
24
+ * sessionStorage. */
25
+ draftId: string;
26
+ /** Initial entity pointer, required on first PUT. */
27
+ initialDraft?: BookingDraftV1;
28
+ /** Disable the GET — useful when the draft was just minted client-side. */
29
+ enableLoad?: boolean;
30
+ }
31
+ /**
32
+ * Server-synced booking draft state. Calls GET on mount (when
33
+ * `enableLoad`) and exposes a `save(draft)` mutation that PUTs
34
+ * to `/catalog/drafts/:id`.
35
+ *
36
+ * The mutation is fire-and-forget from the wizard's perspective —
37
+ * the journey root holds the local draft as the source of truth and
38
+ * the server copy is a recovery surface. Per
39
+ * booking-journey-architecture §5.7.
40
+ */
41
+ export declare function useBookingDraft(options: UseBookingDraftOptions): {
42
+ /** Server-side draft row, or null when missing / 404. */
43
+ serverDraft: {
44
+ id: string;
45
+ entity_module: string;
46
+ entity_id: string;
47
+ source_kind: string;
48
+ draft_payload: unknown;
49
+ expires_at: string;
50
+ created_at: string;
51
+ updated_at: string;
52
+ source_connection_id?: string | null | undefined;
53
+ source_ref?: string | null | undefined;
54
+ current_step?: string | null | undefined;
55
+ current_quote_id?: string | null | undefined;
56
+ hold_expires_at?: string | null | undefined;
57
+ consumed_booking_id?: string | null | undefined;
58
+ consumed_at?: string | null | undefined;
59
+ } | null;
60
+ isLoading: boolean;
61
+ save: import("@tanstack/react-query").UseMutationResult<{
62
+ id: string;
63
+ entity_module: string;
64
+ entity_id: string;
65
+ source_kind: string;
66
+ draft_payload: unknown;
67
+ expires_at: string;
68
+ created_at: string;
69
+ updated_at: string;
70
+ source_connection_id?: string | null | undefined;
71
+ source_ref?: string | null | undefined;
72
+ current_step?: string | null | undefined;
73
+ current_quote_id?: string | null | undefined;
74
+ hold_expires_at?: string | null | undefined;
75
+ consumed_booking_id?: string | null | undefined;
76
+ consumed_at?: string | null | undefined;
77
+ }, Error, {
78
+ draft: BookingDraftV1;
79
+ currentStep?: string;
80
+ currentQuoteId?: string;
81
+ }, unknown>;
82
+ remove: import("@tanstack/react-query").UseMutationResult<void, Error, void, unknown>;
83
+ refetch: (options?: import("@tanstack/react-query").RefetchOptions) => Promise<import("@tanstack/react-query").QueryObserverResult<{
84
+ id: string;
85
+ entity_module: string;
86
+ entity_id: string;
87
+ source_kind: string;
88
+ draft_payload: unknown;
89
+ expires_at: string;
90
+ created_at: string;
91
+ updated_at: string;
92
+ source_connection_id?: string | null | undefined;
93
+ source_ref?: string | null | undefined;
94
+ current_step?: string | null | undefined;
95
+ current_quote_id?: string | null | undefined;
96
+ hold_expires_at?: string | null | undefined;
97
+ consumed_booking_id?: string | null | undefined;
98
+ consumed_at?: string | null | undefined;
99
+ } | null, Error>>;
100
+ };
101
+ export {};
102
+ //# sourceMappingURL=use-booking-draft.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-booking-draft.d.ts","sourceRoot":"","sources":["../../src/booking-engine/use-booking-draft.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,cAAc,EAEpB,MAAM,2DAA2D,CAAA;AAClE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,KAAK,wBAAwB,EAAwB,MAAM,8BAA8B,CAAA;AAElG,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;iBAgBlB,CAAA;AAEF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAErD,MAAM,WAAW,sBAAuB,SAAQ,wBAAwB;IACtE;0BACsB;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,qDAAqD;IACrD,YAAY,CAAC,EAAE,cAAc,CAAA;IAC7B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB;IA4D3D,yDAAyD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAtChD,cAAc;sBACP,MAAM;yBACH,MAAM;;;;;;;;;;;;;;;;;;;;EA2C5B"}
@@ -0,0 +1,93 @@
1
+ "use client";
2
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
3
+ import { bookingDraftV1, } from "@voyant-travel/catalog-contracts/booking-engine/contracts";
4
+ import { z } from "zod";
5
+ import { useBookingJourneyApi } from "./use-booking-journey-api.js";
6
+ const draftRowSchema = z.object({
7
+ id: z.string(),
8
+ entity_module: z.string(),
9
+ entity_id: z.string(),
10
+ source_kind: z.string(),
11
+ source_connection_id: z.string().nullable().optional(),
12
+ source_ref: z.string().nullable().optional(),
13
+ draft_payload: z.unknown(),
14
+ current_step: z.string().nullable().optional(),
15
+ current_quote_id: z.string().nullable().optional(),
16
+ hold_expires_at: z.string().nullable().optional(),
17
+ consumed_booking_id: z.string().nullable().optional(),
18
+ consumed_at: z.string().nullable().optional(),
19
+ expires_at: z.string(),
20
+ created_at: z.string(),
21
+ updated_at: z.string(),
22
+ });
23
+ /**
24
+ * Server-synced booking draft state. Calls GET on mount (when
25
+ * `enableLoad`) and exposes a `save(draft)` mutation that PUTs
26
+ * to `/catalog/drafts/:id`.
27
+ *
28
+ * The mutation is fire-and-forget from the wizard's perspective —
29
+ * the journey root holds the local draft as the source of truth and
30
+ * the server copy is a recovery surface. Per
31
+ * booking-journey-architecture §5.7.
32
+ */
33
+ export function useBookingDraft(options) {
34
+ const api = useBookingJourneyApi(options);
35
+ const queryClient = useQueryClient();
36
+ const queryKey = ["booking-draft", options.surface ?? "admin", options.draftId];
37
+ const query = useQuery({
38
+ queryKey,
39
+ queryFn: async () => {
40
+ try {
41
+ return await api.request("GET", `/drafts/${options.draftId}`, draftRowSchema);
42
+ }
43
+ catch (err) {
44
+ if (err instanceof Error && err.message.includes("404"))
45
+ return null;
46
+ throw err;
47
+ }
48
+ },
49
+ enabled: options.enableLoad !== false,
50
+ });
51
+ const save = useMutation({
52
+ mutationFn: async ({ draft, currentStep, currentQuoteId }) => {
53
+ bookingDraftV1.parse(draft);
54
+ const body = {
55
+ entityModule: draft.entity.module,
56
+ entityId: draft.entity.id,
57
+ draftPayload: draft,
58
+ currentStep,
59
+ currentQuoteId,
60
+ };
61
+ // Only send the source pointer fields when present. They're optional but
62
+ // non-empty when set (`z.string().min(1).optional()`); an empty string —
63
+ // which is what a server-resolved-provenance draft carries — would fail
64
+ // validation. Mirrors the quote hook's guarding.
65
+ if (draft.entity.sourceKind)
66
+ body.sourceKind = draft.entity.sourceKind;
67
+ if (draft.entity.sourceConnectionId)
68
+ body.sourceConnectionId = draft.entity.sourceConnectionId;
69
+ if (draft.entity.sourceRef)
70
+ body.sourceRef = draft.entity.sourceRef;
71
+ return api.request("PUT", `/drafts/${options.draftId}`, draftRowSchema, body);
72
+ },
73
+ onSuccess(row) {
74
+ queryClient.setQueryData(queryKey, row);
75
+ },
76
+ });
77
+ const remove = useMutation({
78
+ mutationFn: async () => {
79
+ await api.request("DELETE", `/drafts/${options.draftId}`, z.undefined());
80
+ },
81
+ onSuccess() {
82
+ queryClient.setQueryData(queryKey, null);
83
+ },
84
+ });
85
+ return {
86
+ /** Server-side draft row, or null when missing / 404. */
87
+ serverDraft: query.data ?? null,
88
+ isLoading: query.isLoading,
89
+ save,
90
+ remove,
91
+ refetch: query.refetch,
92
+ };
93
+ }
@@ -0,0 +1,30 @@
1
+ import { type BookingJourneyApiOptions } from "./use-booking-journey-api.js";
2
+ export interface PlaceHoldInput {
3
+ entityModule: string;
4
+ entityId: string;
5
+ draftId: string;
6
+ ttlMs?: number;
7
+ parameters?: Record<string, unknown>;
8
+ }
9
+ export interface ReleaseHoldInput {
10
+ entityModule: string;
11
+ holdToken: string;
12
+ }
13
+ /**
14
+ * Place an inventory soft-hold against the engine. Per
15
+ * booking-journey-architecture §5.7 — the journey calls this once
16
+ * the user has picked a slot + pax in the Configure step so
17
+ * concurrent shoppers can't oversell capacity.
18
+ *
19
+ * The bound mutation also exposes a `release` helper for the cancel
20
+ * path; the reaper covers expiry without explicit calls.
21
+ */
22
+ export declare function useBookingHold(options?: BookingJourneyApiOptions): {
23
+ place: (input: PlaceHoldInput) => Promise<{
24
+ holdToken: string;
25
+ expiresAt: string;
26
+ }>;
27
+ release: (input: ReleaseHoldInput) => Promise<void>;
28
+ isPending: boolean;
29
+ };
30
+ //# sourceMappingURL=use-booking-hold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-booking-hold.d.ts","sourceRoot":"","sources":["../../src/booking-engine/use-booking-hold.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,wBAAwB,EAAwB,MAAM,8BAA8B,CAAA;AAOlG,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,wBAA6B,GAAG;IACtE,KAAK,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACnF,OAAO,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACnD,SAAS,EAAE,OAAO,CAAA;CACnB,CA6BA"}
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { useMutation } from "@tanstack/react-query";
3
+ import { z } from "zod";
4
+ import { useBookingJourneyApi } from "./use-booking-journey-api.js";
5
+ const placeHoldResponseSchema = z.object({
6
+ holdToken: z.string(),
7
+ expiresAt: z.string().datetime(),
8
+ });
9
+ /**
10
+ * Place an inventory soft-hold against the engine. Per
11
+ * booking-journey-architecture §5.7 — the journey calls this once
12
+ * the user has picked a slot + pax in the Configure step so
13
+ * concurrent shoppers can't oversell capacity.
14
+ *
15
+ * The bound mutation also exposes a `release` helper for the cancel
16
+ * path; the reaper covers expiry without explicit calls.
17
+ */
18
+ export function useBookingHold(options = {}) {
19
+ const api = useBookingJourneyApi(options);
20
+ const place = useMutation({
21
+ mutationFn: async (input) => {
22
+ return api.request("POST", "/holds/place", placeHoldResponseSchema, {
23
+ entityModule: input.entityModule,
24
+ entityId: input.entityId,
25
+ draftId: input.draftId,
26
+ ttlMs: input.ttlMs,
27
+ parameters: input.parameters,
28
+ });
29
+ },
30
+ });
31
+ const release = useMutation({
32
+ mutationFn: async (input) => {
33
+ await api.request("POST", "/holds/release", z.undefined(), {
34
+ entityModule: input.entityModule,
35
+ holdToken: input.holdToken,
36
+ });
37
+ },
38
+ });
39
+ return {
40
+ place: (input) => place.mutateAsync(input),
41
+ release: (input) => release.mutateAsync(input),
42
+ isPending: place.isPending || release.isPending,
43
+ };
44
+ }
@@ -0,0 +1,23 @@
1
+ import type { z } from "zod";
2
+ import { type VoyantFetcher } from "../client.js";
3
+ export interface BookingJourneyApiOptions {
4
+ /**
5
+ * Surface to call against. Operator passes `"admin"`; storefront /
6
+ * partner / embedded surfaces pass `"public"`. Switches the base
7
+ * path between `/v1/admin/catalog` and `/v1/public/catalog`.
8
+ */
9
+ surface?: "admin" | "public";
10
+ /** Override the API base URL pulled from VoyantCatalogProvider. */
11
+ baseUrl?: string;
12
+ /** Override the fetcher pulled from VoyantCatalogProvider. */
13
+ fetcher?: VoyantFetcher;
14
+ }
15
+ export interface UseBookingJourneyApi {
16
+ /** Resolved base URL for catalog booking-engine endpoints. */
17
+ apiBase: string;
18
+ fetcher: VoyantFetcher;
19
+ /** GET / POST / PUT / DELETE wrappers with Zod-validated responses. */
20
+ request<TOut>(method: "GET" | "POST" | "PUT" | "DELETE", path: string, schema: z.ZodType<TOut>, body?: unknown): Promise<TOut>;
21
+ }
22
+ export declare function useBookingJourneyApi(options?: BookingJourneyApiOptions): UseBookingJourneyApi;
23
+ //# sourceMappingURL=use-booking-journey-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-booking-journey-api.d.ts","sourceRoot":"","sources":["../../src/booking-engine/use-booking-journey-api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAC5B,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,cAAc,CAAA;AAGrB,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;IAC5B,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,aAAa,CAAA;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,aAAa,CAAA;IACtB,uEAAuE;IACvE,OAAO,CAAC,IAAI,EACV,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,EACzC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EACvB,IAAI,CAAC,EAAE,OAAO,GACb,OAAO,CAAC,IAAI,CAAC,CAAA;CACjB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,wBAA6B,GAAG,oBAAoB,CAuBjG"}