@voyant-travel/inventory 0.1.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.
Files changed (311) hide show
  1. package/LICENSE +201 -0
  2. package/dist/action-ledger-drift.d.ts +29 -0
  3. package/dist/action-ledger-drift.d.ts.map +1 -0
  4. package/dist/action-ledger-drift.js +338 -0
  5. package/dist/action-ledger.d.ts +104 -0
  6. package/dist/action-ledger.d.ts.map +1 -0
  7. package/dist/action-ledger.js +100 -0
  8. package/dist/authoring/builder.d.ts +37 -0
  9. package/dist/authoring/builder.d.ts.map +1 -0
  10. package/dist/authoring/builder.js +248 -0
  11. package/dist/authoring/clone-content.d.ts +38 -0
  12. package/dist/authoring/clone-content.d.ts.map +1 -0
  13. package/dist/authoring/clone-content.js +367 -0
  14. package/dist/authoring/clone-pricing.d.ts +9 -0
  15. package/dist/authoring/clone-pricing.d.ts.map +1 -0
  16. package/dist/authoring/clone-pricing.js +242 -0
  17. package/dist/authoring/clone.d.ts +45 -0
  18. package/dist/authoring/clone.d.ts.map +1 -0
  19. package/dist/authoring/clone.js +142 -0
  20. package/dist/authoring/errors.d.ts +21 -0
  21. package/dist/authoring/errors.d.ts.map +1 -0
  22. package/dist/authoring/errors.js +13 -0
  23. package/dist/authoring/extension.d.ts +248 -0
  24. package/dist/authoring/extension.d.ts.map +1 -0
  25. package/dist/authoring/extension.js +116 -0
  26. package/dist/authoring/index.d.ts +12 -0
  27. package/dist/authoring/index.d.ts.map +1 -0
  28. package/dist/authoring/index.js +11 -0
  29. package/dist/authoring/schema.d.ts +85 -0
  30. package/dist/authoring/schema.d.ts.map +1 -0
  31. package/dist/authoring/schema.js +16 -0
  32. package/dist/authoring/service.d.ts +28 -0
  33. package/dist/authoring/service.d.ts.map +1 -0
  34. package/dist/authoring/service.js +66 -0
  35. package/dist/authoring/spec.d.ts +524 -0
  36. package/dist/authoring/spec.d.ts.map +1 -0
  37. package/dist/authoring/spec.js +167 -0
  38. package/dist/authoring/validate.d.ts +17 -0
  39. package/dist/authoring/validate.d.ts.map +1 -0
  40. package/dist/authoring/validate.js +83 -0
  41. package/dist/authoring.d.ts +2 -0
  42. package/dist/authoring.d.ts.map +1 -0
  43. package/dist/authoring.js +1 -0
  44. package/dist/booking-engine/handler-support.d.ts +91 -0
  45. package/dist/booking-engine/handler-support.d.ts.map +1 -0
  46. package/dist/booking-engine/handler-support.js +355 -0
  47. package/dist/booking-engine/handler.d.ts +404 -0
  48. package/dist/booking-engine/handler.d.ts.map +1 -0
  49. package/dist/booking-engine/handler.js +398 -0
  50. package/dist/booking-engine/index.d.ts +8 -0
  51. package/dist/booking-engine/index.d.ts.map +1 -0
  52. package/dist/booking-engine/index.js +7 -0
  53. package/dist/booking-engine.d.ts +2 -0
  54. package/dist/booking-engine.d.ts.map +1 -0
  55. package/dist/booking-engine.js +1 -0
  56. package/dist/booking-extension.d.ts +278 -0
  57. package/dist/booking-extension.d.ts.map +1 -0
  58. package/dist/booking-extension.js +161 -0
  59. package/dist/catalog-policy-departures.d.ts +52 -0
  60. package/dist/catalog-policy-departures.d.ts.map +1 -0
  61. package/dist/catalog-policy-departures.js +169 -0
  62. package/dist/catalog-policy-destinations.d.ts +43 -0
  63. package/dist/catalog-policy-destinations.d.ts.map +1 -0
  64. package/dist/catalog-policy-destinations.js +165 -0
  65. package/dist/catalog-policy-pricing.d.ts +55 -0
  66. package/dist/catalog-policy-pricing.d.ts.map +1 -0
  67. package/dist/catalog-policy-pricing.js +109 -0
  68. package/dist/catalog-policy-promotions.d.ts +52 -0
  69. package/dist/catalog-policy-promotions.d.ts.map +1 -0
  70. package/dist/catalog-policy-promotions.js +270 -0
  71. package/dist/catalog-policy-taxonomy.d.ts +51 -0
  72. package/dist/catalog-policy-taxonomy.d.ts.map +1 -0
  73. package/dist/catalog-policy-taxonomy.js +191 -0
  74. package/dist/catalog-policy.d.ts +33 -0
  75. package/dist/catalog-policy.d.ts.map +1 -0
  76. package/dist/catalog-policy.js +733 -0
  77. package/dist/content-shape.d.ts +15 -0
  78. package/dist/content-shape.d.ts.map +1 -0
  79. package/dist/content-shape.js +28 -0
  80. package/dist/draft-shape.d.ts +43 -0
  81. package/dist/draft-shape.d.ts.map +1 -0
  82. package/dist/draft-shape.js +48 -0
  83. package/dist/events.d.ts +37 -0
  84. package/dist/events.d.ts.map +1 -0
  85. package/dist/events.js +32 -0
  86. package/dist/extras/catalog-policy.d.ts +30 -0
  87. package/dist/extras/catalog-policy.d.ts.map +1 -0
  88. package/dist/extras/catalog-policy.js +319 -0
  89. package/dist/extras/content-shape.d.ts +5 -0
  90. package/dist/extras/content-shape.d.ts.map +1 -0
  91. package/dist/extras/content-shape.js +13 -0
  92. package/dist/extras/draft-shape.d.ts +34 -0
  93. package/dist/extras/draft-shape.d.ts.map +1 -0
  94. package/dist/extras/draft-shape.js +69 -0
  95. package/dist/extras/routes.d.ts +380 -0
  96. package/dist/extras/routes.d.ts.map +1 -0
  97. package/dist/extras/routes.js +59 -0
  98. package/dist/extras/schema-sourced-content.d.ts +254 -0
  99. package/dist/extras/schema-sourced-content.d.ts.map +1 -0
  100. package/dist/extras/schema-sourced-content.js +45 -0
  101. package/dist/extras/schema.d.ts +628 -0
  102. package/dist/extras/schema.d.ts.map +1 -0
  103. package/dist/extras/schema.js +87 -0
  104. package/dist/extras/service-catalog-plane.d.ts +77 -0
  105. package/dist/extras/service-catalog-plane.d.ts.map +1 -0
  106. package/dist/extras/service-catalog-plane.js +219 -0
  107. package/dist/extras/service-content-synthesizer.d.ts +41 -0
  108. package/dist/extras/service-content-synthesizer.d.ts.map +1 -0
  109. package/dist/extras/service-content-synthesizer.js +138 -0
  110. package/dist/extras/service-content.d.ts +48 -0
  111. package/dist/extras/service-content.d.ts.map +1 -0
  112. package/dist/extras/service-content.js +253 -0
  113. package/dist/extras/service.d.ts +185 -0
  114. package/dist/extras/service.d.ts.map +1 -0
  115. package/dist/extras/service.js +96 -0
  116. package/dist/extras/validation.d.ts +437 -0
  117. package/dist/extras/validation.d.ts.map +1 -0
  118. package/dist/extras/validation.js +149 -0
  119. package/dist/extras.d.ts +267 -0
  120. package/dist/extras.d.ts.map +1 -0
  121. package/dist/extras.js +19 -0
  122. package/dist/index.d.ts +22 -0
  123. package/dist/index.d.ts.map +1 -0
  124. package/dist/index.js +32 -0
  125. package/dist/interface.d.ts +5869 -0
  126. package/dist/interface.d.ts.map +1 -0
  127. package/dist/interface.js +54 -0
  128. package/dist/public-routes.d.ts +2 -0
  129. package/dist/public-routes.d.ts.map +1 -0
  130. package/dist/public-routes.js +1 -0
  131. package/dist/public-validation.d.ts +2 -0
  132. package/dist/public-validation.d.ts.map +1 -0
  133. package/dist/public-validation.js +1 -0
  134. package/dist/read-model.d.ts +25 -0
  135. package/dist/read-model.d.ts.map +1 -0
  136. package/dist/read-model.js +99 -0
  137. package/dist/route-env.d.ts +22 -0
  138. package/dist/route-env.d.ts.map +1 -0
  139. package/dist/route-env.js +1 -0
  140. package/dist/routes-associations.d.ts +164 -0
  141. package/dist/routes-associations.d.ts.map +1 -0
  142. package/dist/routes-associations.js +100 -0
  143. package/dist/routes-catalog.d.ts +436 -0
  144. package/dist/routes-catalog.d.ts.map +1 -0
  145. package/dist/routes-catalog.js +104 -0
  146. package/dist/routes-configuration.d.ts +773 -0
  147. package/dist/routes-configuration.d.ts.map +1 -0
  148. package/dist/routes-configuration.js +364 -0
  149. package/dist/routes-content.d.ts +74 -0
  150. package/dist/routes-content.d.ts.map +1 -0
  151. package/dist/routes-content.js +117 -0
  152. package/dist/routes-core.d.ts +331 -0
  153. package/dist/routes-core.d.ts.map +1 -0
  154. package/dist/routes-core.js +95 -0
  155. package/dist/routes-itinerary.d.ts +759 -0
  156. package/dist/routes-itinerary.d.ts.map +1 -0
  157. package/dist/routes-itinerary.js +387 -0
  158. package/dist/routes-maintenance.d.ts +32 -0
  159. package/dist/routes-maintenance.d.ts.map +1 -0
  160. package/dist/routes-maintenance.js +14 -0
  161. package/dist/routes-media.d.ts +634 -0
  162. package/dist/routes-media.d.ts.map +1 -0
  163. package/dist/routes-media.js +245 -0
  164. package/dist/routes-merchandising.d.ts +1120 -0
  165. package/dist/routes-merchandising.d.ts.map +1 -0
  166. package/dist/routes-merchandising.js +377 -0
  167. package/dist/routes-options.d.ts +363 -0
  168. package/dist/routes-options.d.ts.map +1 -0
  169. package/dist/routes-options.js +173 -0
  170. package/dist/routes-public.d.ts +776 -0
  171. package/dist/routes-public.d.ts.map +1 -0
  172. package/dist/routes-public.js +119 -0
  173. package/dist/routes-translations.d.ts +489 -0
  174. package/dist/routes-translations.d.ts.map +1 -0
  175. package/dist/routes-translations.js +258 -0
  176. package/dist/routes.d.ts +5097 -0
  177. package/dist/routes.d.ts.map +1 -0
  178. package/dist/routes.js +64 -0
  179. package/dist/schema-core.d.ts +1238 -0
  180. package/dist/schema-core.d.ts.map +1 -0
  181. package/dist/schema-core.js +157 -0
  182. package/dist/schema-itinerary.d.ts +1169 -0
  183. package/dist/schema-itinerary.d.ts.map +1 -0
  184. package/dist/schema-itinerary.js +130 -0
  185. package/dist/schema-relations.d.ts +117 -0
  186. package/dist/schema-relations.d.ts.map +1 -0
  187. package/dist/schema-relations.js +192 -0
  188. package/dist/schema-settings.d.ts +1800 -0
  189. package/dist/schema-settings.d.ts.map +1 -0
  190. package/dist/schema-settings.js +220 -0
  191. package/dist/schema-shared.d.ts +15 -0
  192. package/dist/schema-shared.d.ts.map +1 -0
  193. package/dist/schema-shared.js +91 -0
  194. package/dist/schema-sourced-content.d.ts +262 -0
  195. package/dist/schema-sourced-content.d.ts.map +1 -0
  196. package/dist/schema-sourced-content.js +69 -0
  197. package/dist/schema-taxonomy.d.ts +1363 -0
  198. package/dist/schema-taxonomy.d.ts.map +1 -0
  199. package/dist/schema-taxonomy.js +203 -0
  200. package/dist/schema.d.ts +10 -0
  201. package/dist/schema.d.ts.map +1 -0
  202. package/dist/schema.js +9 -0
  203. package/dist/service-aggregates.d.ts +29 -0
  204. package/dist/service-aggregates.d.ts.map +1 -0
  205. package/dist/service-aggregates.js +56 -0
  206. package/dist/service-catalog-plane-destinations.d.ts +30 -0
  207. package/dist/service-catalog-plane-destinations.d.ts.map +1 -0
  208. package/dist/service-catalog-plane-destinations.js +143 -0
  209. package/dist/service-catalog-plane-taxonomy.d.ts +73 -0
  210. package/dist/service-catalog-plane-taxonomy.d.ts.map +1 -0
  211. package/dist/service-catalog-plane-taxonomy.js +242 -0
  212. package/dist/service-catalog-plane.d.ts +179 -0
  213. package/dist/service-catalog-plane.d.ts.map +1 -0
  214. package/dist/service-catalog-plane.js +431 -0
  215. package/dist/service-catalog.d.ts +251 -0
  216. package/dist/service-catalog.d.ts.map +1 -0
  217. package/dist/service-catalog.js +517 -0
  218. package/dist/service-configuration.d.ts +261 -0
  219. package/dist/service-configuration.d.ts.map +1 -0
  220. package/dist/service-configuration.js +343 -0
  221. package/dist/service-content-owned.d.ts +68 -0
  222. package/dist/service-content-owned.d.ts.map +1 -0
  223. package/dist/service-content-owned.js +329 -0
  224. package/dist/service-content-synthesizer.d.ts +90 -0
  225. package/dist/service-content-synthesizer.d.ts.map +1 -0
  226. package/dist/service-content-synthesizer.js +178 -0
  227. package/dist/service-content.d.ts +106 -0
  228. package/dist/service-content.d.ts.map +1 -0
  229. package/dist/service-content.js +388 -0
  230. package/dist/service-core.d.ts +194 -0
  231. package/dist/service-core.d.ts.map +1 -0
  232. package/dist/service-core.js +213 -0
  233. package/dist/service-delivery-formats.d.ts +58 -0
  234. package/dist/service-delivery-formats.d.ts.map +1 -0
  235. package/dist/service-delivery-formats.js +107 -0
  236. package/dist/service-destinations.d.ts +223 -0
  237. package/dist/service-destinations.d.ts.map +1 -0
  238. package/dist/service-destinations.js +310 -0
  239. package/dist/service-itinerary-history.d.ts +457 -0
  240. package/dist/service-itinerary-history.d.ts.map +1 -0
  241. package/dist/service-itinerary-history.js +135 -0
  242. package/dist/service-itinerary.d.ts +1149 -0
  243. package/dist/service-itinerary.d.ts.map +1 -0
  244. package/dist/service-itinerary.js +419 -0
  245. package/dist/service-media.d.ts +272 -0
  246. package/dist/service-media.d.ts.map +1 -0
  247. package/dist/service-media.js +320 -0
  248. package/dist/service-merchandising.d.ts +184 -0
  249. package/dist/service-merchandising.d.ts.map +1 -0
  250. package/dist/service-merchandising.js +181 -0
  251. package/dist/service-option-translations.d.ts +268 -0
  252. package/dist/service-option-translations.d.ts.map +1 -0
  253. package/dist/service-option-translations.js +300 -0
  254. package/dist/service-options.d.ts +181 -0
  255. package/dist/service-options.d.ts.map +1 -0
  256. package/dist/service-options.js +179 -0
  257. package/dist/service-product-destinations.d.ts +37 -0
  258. package/dist/service-product-destinations.d.ts.map +1 -0
  259. package/dist/service-product-destinations.js +94 -0
  260. package/dist/service-public.d.ts +664 -0
  261. package/dist/service-public.d.ts.map +1 -0
  262. package/dist/service-public.js +374 -0
  263. package/dist/service-taxonomy.d.ts +197 -0
  264. package/dist/service-taxonomy.d.ts.map +1 -0
  265. package/dist/service-taxonomy.js +221 -0
  266. package/dist/service.d.ts +3929 -0
  267. package/dist/service.d.ts.map +1 -0
  268. package/dist/service.js +28 -0
  269. package/dist/tasks/brochure-printers.d.ts +31 -0
  270. package/dist/tasks/brochure-printers.d.ts.map +1 -0
  271. package/dist/tasks/brochure-printers.js +149 -0
  272. package/dist/tasks/brochure-templates.d.ts +36 -0
  273. package/dist/tasks/brochure-templates.d.ts.map +1 -0
  274. package/dist/tasks/brochure-templates.js +110 -0
  275. package/dist/tasks/brochures.d.ts +43 -0
  276. package/dist/tasks/brochures.d.ts.map +1 -0
  277. package/dist/tasks/brochures.js +72 -0
  278. package/dist/tasks/generate-pdf.d.ts +8 -0
  279. package/dist/tasks/generate-pdf.d.ts.map +1 -0
  280. package/dist/tasks/generate-pdf.js +106 -0
  281. package/dist/tasks/index.d.ts +5 -0
  282. package/dist/tasks/index.d.ts.map +1 -0
  283. package/dist/tasks/index.js +4 -0
  284. package/dist/tasks/pdf-text.d.ts +2 -0
  285. package/dist/tasks/pdf-text.d.ts.map +1 -0
  286. package/dist/tasks/pdf-text.js +40 -0
  287. package/dist/tasks.d.ts +2 -0
  288. package/dist/tasks.d.ts.map +1 -0
  289. package/dist/tasks.js +1 -0
  290. package/dist/validation-catalog.d.ts +2 -0
  291. package/dist/validation-catalog.d.ts.map +1 -0
  292. package/dist/validation-catalog.js +3 -0
  293. package/dist/validation-config.d.ts +2 -0
  294. package/dist/validation-config.d.ts.map +1 -0
  295. package/dist/validation-config.js +3 -0
  296. package/dist/validation-content.d.ts +2 -0
  297. package/dist/validation-content.d.ts.map +1 -0
  298. package/dist/validation-content.js +3 -0
  299. package/dist/validation-core.d.ts +2 -0
  300. package/dist/validation-core.d.ts.map +1 -0
  301. package/dist/validation-core.js +3 -0
  302. package/dist/validation-public.d.ts +2 -0
  303. package/dist/validation-public.d.ts.map +1 -0
  304. package/dist/validation-public.js +3 -0
  305. package/dist/validation-shared.d.ts +2 -0
  306. package/dist/validation-shared.d.ts.map +1 -0
  307. package/dist/validation-shared.js +3 -0
  308. package/dist/validation.d.ts +2 -0
  309. package/dist/validation.d.ts.map +1 -0
  310. package/dist/validation.js +3 -0
  311. package/package.json +204 -0
@@ -0,0 +1,15 @@
1
+ import { type ContentOverlay, type MergeOverlaysOptions } from "@voyant-travel/catalog";
2
+ import { type ProductContent } from "@voyant-travel/products-contracts/content-shape";
3
+ export { BOARD_BASIS_FROM_SHORT_CODE, BOARD_BASIS_SHORT_CODES, BOARD_BASIS_VALUES, type BoardBasis, type BoardBasisShortCode, boardBasisSchema, PRODUCTS_CONTENT_SCHEMA_VERSION, type ProductContent, type ProductDay, type ProductDeparture, type ProductMediaItem, type ProductOption, type ProductPolicy, type ProductSummary, productContentSchema, productDaySchema, productDepartureSchema, productMediaItemSchema, productOptionSchema, productOptionUnitSchema, productPolicySchema, productSummarySchema, validateProductContent, } from "@voyant-travel/products-contracts/content-shape";
4
+ /**
5
+ * Apply a list of editorial overlays to a product content payload via
6
+ * RFC 6901 JSON pointers. Validates the merged result against the
7
+ * vertical's Zod schema; overlays that produce an invalid payload are
8
+ * rolled back and reported via `onOverlayError`.
9
+ *
10
+ * Per sourced-content §3.5.4, this is the "content-shape-aware merger"
11
+ * — the catalog plane stays neutral about the content shape; the
12
+ * vertical plugs in its validator here.
13
+ */
14
+ export declare function mergeOverlaysIntoProductContent(payload: ProductContent, overlays: ReadonlyArray<ContentOverlay>, options?: Pick<MergeOverlaysOptions, "onOverlayError">): ProductContent;
15
+ //# sourceMappingURL=content-shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-shape.d.ts","sourceRoot":"","sources":["../src/content-shape.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAE1B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,iDAAiD,CAAA;AAExD,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,kBAAkB,EAClB,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,gBAAgB,EAChB,+BAA+B,EAC/B,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,iDAAiD,CAAA;AAExD;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,aAAa,CAAC,cAAc,CAAC,EACvC,OAAO,GAAE,IAAI,CAAC,oBAAoB,EAAE,gBAAgB,CAAM,GACzD,cAAc,CAchB"}
@@ -0,0 +1,28 @@
1
+ import { mergeOverlaysIntoContent, } from "@voyant-travel/catalog";
2
+ import { productContentSchema, validateProductContent, } from "@voyant-travel/products-contracts/content-shape";
3
+ export { BOARD_BASIS_FROM_SHORT_CODE, BOARD_BASIS_SHORT_CODES, BOARD_BASIS_VALUES, boardBasisSchema, PRODUCTS_CONTENT_SCHEMA_VERSION, productContentSchema, productDaySchema, productDepartureSchema, productMediaItemSchema, productOptionSchema, productOptionUnitSchema, productPolicySchema, productSummarySchema, validateProductContent, } from "@voyant-travel/products-contracts/content-shape";
4
+ /**
5
+ * Apply a list of editorial overlays to a product content payload via
6
+ * RFC 6901 JSON pointers. Validates the merged result against the
7
+ * vertical's Zod schema; overlays that produce an invalid payload are
8
+ * rolled back and reported via `onOverlayError`.
9
+ *
10
+ * Per sourced-content §3.5.4, this is the "content-shape-aware merger"
11
+ * — the catalog plane stays neutral about the content shape; the
12
+ * vertical plugs in its validator here.
13
+ */
14
+ export function mergeOverlaysIntoProductContent(payload, overlays, options = {}) {
15
+ const merged = mergeOverlaysIntoContent(payload, overlays, {
16
+ validate(p) {
17
+ const result = validateProductContent(p);
18
+ if (result.valid) {
19
+ return { valid: true };
20
+ }
21
+ return { valid: false, reason: result.reason };
22
+ },
23
+ onOverlayError: options.onOverlayError,
24
+ });
25
+ // The validator gates merges, so a successful merge always parses —
26
+ // re-parse here to satisfy the return type without an unsafe cast.
27
+ return productContentSchema.parse(merged);
28
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Project a `ProductContent` payload into a `BookingDraftShape` so
3
+ * the journey wizard can render the correct sub-steps for a sourced
4
+ * product.
5
+ *
6
+ * Tour-style products typically need:
7
+ * - Configure: occupancy band selection (adult / child / infant)
8
+ * and optionally a date / departure picker if `days[]` carries
9
+ * scheduled departures.
10
+ * - Travelers: per-pax fields (first / last / email; passport when
11
+ * the supplier requires it — surfaced via overlay when known).
12
+ * - Product options: the product's own `options[]` projected as a
13
+ * configure sub-step, setting `draft.configure.variantId`.
14
+ *
15
+ * No accommodation sub-step today (multi-day tours w/ rooms route
16
+ * through accommodations, not products). Pricing flows through
17
+ * liveResolve at quote time, not the descriptor.
18
+ *
19
+ * See `docs/architecture/booking-journey-architecture.md` §3 + §F.
20
+ */
21
+ import { type BookingDraftShape, type PaxBandSpec } from "@voyant-travel/catalog/booking-engine";
22
+ import type { ProductContent } from "./content-shape.js";
23
+ export interface BuildProductDraftShapeOptions {
24
+ /** Locale — used for option-label fallback. Defaults to `"en-GB"`. */
25
+ locale?: string;
26
+ /**
27
+ * Override the default pax bands. Use when the supplier mandates
28
+ * specific age cutoffs (rare for tour products; common for cruises
29
+ * and family-oriented packages).
30
+ */
31
+ paxBands?: ReadonlyArray<PaxBandSpec>;
32
+ /**
33
+ * Override the maximum total pax. Defaults to `paxBands` sum.
34
+ * Useful when supplier capacity is < combined band max (e.g. a
35
+ * 6-pax max party on a private tour).
36
+ */
37
+ paxBandsAllowedTotal?: {
38
+ min: number;
39
+ max: number;
40
+ };
41
+ }
42
+ export declare function buildProductDraftShape(content: ProductContent, options?: BuildProductDraftShapeOptions): BookingDraftShape;
43
+ //# sourceMappingURL=draft-shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft-shape.d.ts","sourceRoot":"","sources":["../src/draft-shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EACL,KAAK,iBAAiB,EAKtB,KAAK,WAAW,EAEjB,MAAM,uCAAuC,CAAA;AAE9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAExD,MAAM,WAAW,6BAA6B;IAC5C,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAA;IACrC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CACpD;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,cAAc,EACvB,OAAO,GAAE,6BAAkC,GAC1C,iBAAiB,CA4BnB"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Project a `ProductContent` payload into a `BookingDraftShape` so
3
+ * the journey wizard can render the correct sub-steps for a sourced
4
+ * product.
5
+ *
6
+ * Tour-style products typically need:
7
+ * - Configure: occupancy band selection (adult / child / infant)
8
+ * and optionally a date / departure picker if `days[]` carries
9
+ * scheduled departures.
10
+ * - Travelers: per-pax fields (first / last / email; passport when
11
+ * the supplier requires it — surfaced via overlay when known).
12
+ * - Product options: the product's own `options[]` projected as a
13
+ * configure sub-step, setting `draft.configure.variantId`.
14
+ *
15
+ * No accommodation sub-step today (multi-day tours w/ rooms route
16
+ * through accommodations, not products). Pricing flows through
17
+ * liveResolve at quote time, not the descriptor.
18
+ *
19
+ * See `docs/architecture/booking-journey-architecture.md` §3 + §F.
20
+ */
21
+ import { DEFAULT_PAX_BANDS, defaultBookingFields, defaultDraftShapeFlags, defaultTravelerFields, paxBandsAllowedTotalFrom, } from "@voyant-travel/catalog/booking-engine";
22
+ export function buildProductDraftShape(content, options = {}) {
23
+ const paxBands = options.paxBands ?? DEFAULT_PAX_BANDS;
24
+ const total = options.paxBandsAllowedTotal ?? paxBandsAllowedTotalFrom(paxBands);
25
+ const productOptions = content.options.map((opt) => ({
26
+ id: opt.id,
27
+ name: opt.name,
28
+ description: opt.description ?? null,
29
+ }));
30
+ return {
31
+ ...defaultDraftShapeFlags(),
32
+ paxBands,
33
+ paxBandsAllowedTotal: total,
34
+ travelerFields: defaultTravelerFields(),
35
+ bookingFields: defaultBookingFields(),
36
+ paymentIntents: ["hold", "card"],
37
+ configureSubSteps: [
38
+ ...(productOptions.length > 0
39
+ ? [{ kind: "product-option", options: productOptions }]
40
+ : []),
41
+ // Owned products are scheduled — the operator picks a real departure.
42
+ // The journey renders an injected slot picker for this kind, falling
43
+ // back to a free date when the product has no scheduled departures.
44
+ { kind: "departure", required: true },
45
+ { kind: "occupancy", bands: paxBands },
46
+ ],
47
+ };
48
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Product domain events.
3
+ *
4
+ * Emitted by the products module on lifecycle and content changes.
5
+ * `product.content.changed` is the load-bearing channel-push signal —
6
+ * fired when ANY content axis (description, itinerary, media, options,
7
+ * days) changes.
8
+ *
9
+ * Per docs/architecture/channel-push-architecture.md §6.
10
+ */
11
+ import type { EventBus } from "@voyant-travel/core";
12
+ /** Stable event identifier. */
13
+ export declare const PRODUCT_CONTENT_CHANGED_EVENT: "product.content.changed";
14
+ export interface ProductContentChangedEvent {
15
+ /** Product id whose content changed. */
16
+ id: string;
17
+ /**
18
+ * The content axis that changed, when known. Diagnostic only — channel
19
+ * push hashes the full current content at push time so this field is
20
+ * not load-bearing for correctness.
21
+ */
22
+ axis?: "product" | "itinerary" | "option" | "day" | "media" | "feature" | "faq" | "location" | "destination" | "category" | "tag" | "translation";
23
+ }
24
+ /**
25
+ * Helper for route handlers / services to fire `product.content.changed`
26
+ * with a stable shape. Fire-and-forget per the EventBus contract; the
27
+ * caller does not await this if it's already on a hot path.
28
+ *
29
+ * v1 wiring: every product service/route mutation that touches a
30
+ * content-affecting field should call this helper. The top-level PATCH
31
+ * route already calls it (alongside the legacy `product.updated`); child
32
+ * routes can be wired incrementally. Until full coverage exists, the
33
+ * channel-push reconciler (§13) catches missed events by hashing
34
+ * current content per (product, channel).
35
+ */
36
+ export declare function emitProductContentChanged(eventBus: EventBus | undefined, payload: ProductContentChangedEvent): Promise<void>;
37
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEnD,+BAA+B;AAC/B,eAAO,MAAM,6BAA6B,EAAG,yBAAkC,CAAA;AAE/E,MAAM,WAAW,0BAA0B;IACzC,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAA;IACV;;;;OAIG;IACH,IAAI,CAAC,EACD,SAAS,GACT,WAAW,GACX,QAAQ,GACR,KAAK,GACL,OAAO,GACP,SAAS,GACT,KAAK,GACL,UAAU,GACV,aAAa,GACb,UAAU,GACV,KAAK,GACL,aAAa,CAAA;CAClB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,IAAI,CAAC,CAMf"}
package/dist/events.js ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Product domain events.
3
+ *
4
+ * Emitted by the products module on lifecycle and content changes.
5
+ * `product.content.changed` is the load-bearing channel-push signal —
6
+ * fired when ANY content axis (description, itinerary, media, options,
7
+ * days) changes.
8
+ *
9
+ * Per docs/architecture/channel-push-architecture.md §6.
10
+ */
11
+ /** Stable event identifier. */
12
+ export const PRODUCT_CONTENT_CHANGED_EVENT = "product.content.changed";
13
+ /**
14
+ * Helper for route handlers / services to fire `product.content.changed`
15
+ * with a stable shape. Fire-and-forget per the EventBus contract; the
16
+ * caller does not await this if it's already on a hot path.
17
+ *
18
+ * v1 wiring: every product service/route mutation that touches a
19
+ * content-affecting field should call this helper. The top-level PATCH
20
+ * route already calls it (alongside the legacy `product.updated`); child
21
+ * routes can be wired incrementally. Until full coverage exists, the
22
+ * channel-push reconciler (§13) catches missed events by hashing
23
+ * current content per (product, channel).
24
+ */
25
+ export async function emitProductContentChanged(eventBus, payload) {
26
+ if (!eventBus)
27
+ return;
28
+ await eventBus.emit(PRODUCT_CONTENT_CHANGED_EVENT, payload, {
29
+ category: "domain",
30
+ source: "service",
31
+ });
32
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Catalog plane field policy for `packages/extras`.
3
+ *
4
+ * Extras are booking add-ons (optional line items layered on a booked
5
+ * parent product) — **not independently sellable inventory**. Per
6
+ * architecture §3.3.1, extras are a partial-adoption vertical:
7
+ *
8
+ * - **Adopt:** provenance shape (§5.1), booking snapshot graph (§5.3),
9
+ * catalog event taxonomy for the cancellation/fulfillment lifecycle.
10
+ * - **Skip:** search index projection (§5.4), editorial overlay store
11
+ * (§5.2), embeddings / RAG (Phase 2). Extras are discovered through
12
+ * the parent's surface, not via standalone catalog browse.
13
+ *
14
+ * Most fields below have `reindex: "none"` because extras are primarily
15
+ * discovered through their parent product. The `thumbnailUrl` card-image
16
+ * projection is indexed for operator catalog search surfaces that opt
17
+ * extras into the shared catalog index.
18
+ *
19
+ * Scope of this file:
20
+ * - The `product_extras` table (extra catalog definitions).
21
+ *
22
+ * Out of scope:
23
+ * - `option_extra_configs` — option-level overrides; promoted child.
24
+ * - `booking_extras` — runtime line items on a booking; not catalog data.
25
+ */
26
+ import { type FieldPolicyInput } from "@voyant-travel/catalog/contract";
27
+ declare const EXTRAS_FIELD_POLICY: FieldPolicyInput[];
28
+ export declare const extrasCatalogPolicy: import("@voyant-travel/catalog").FieldPolicy[];
29
+ export { EXTRAS_FIELD_POLICY };
30
+ //# sourceMappingURL=catalog-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-policy.d.ts","sourceRoot":"","sources":["../../src/extras/catalog-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AAE1F,QAAA,MAAM,mBAAmB,EAAE,gBAAgB,EAsS1C,CAAA;AAED,eAAO,MAAM,mBAAmB,gDAAyC,CAAA;AAEzE,OAAO,EAAE,mBAAmB,EAAE,CAAA"}
@@ -0,0 +1,319 @@
1
+ /**
2
+ * Catalog plane field policy for `packages/extras`.
3
+ *
4
+ * Extras are booking add-ons (optional line items layered on a booked
5
+ * parent product) — **not independently sellable inventory**. Per
6
+ * architecture §3.3.1, extras are a partial-adoption vertical:
7
+ *
8
+ * - **Adopt:** provenance shape (§5.1), booking snapshot graph (§5.3),
9
+ * catalog event taxonomy for the cancellation/fulfillment lifecycle.
10
+ * - **Skip:** search index projection (§5.4), editorial overlay store
11
+ * (§5.2), embeddings / RAG (Phase 2). Extras are discovered through
12
+ * the parent's surface, not via standalone catalog browse.
13
+ *
14
+ * Most fields below have `reindex: "none"` because extras are primarily
15
+ * discovered through their parent product. The `thumbnailUrl` card-image
16
+ * projection is indexed for operator catalog search surfaces that opt
17
+ * extras into the shared catalog index.
18
+ *
19
+ * Scope of this file:
20
+ * - The `product_extras` table (extra catalog definitions).
21
+ *
22
+ * Out of scope:
23
+ * - `option_extra_configs` — option-level overrides; promoted child.
24
+ * - `booking_extras` — runtime line items on a booking; not catalog data.
25
+ */
26
+ import { defineFieldPolicy } from "@voyant-travel/catalog/contract";
27
+ const EXTRAS_FIELD_POLICY = [
28
+ // ── Source pointer / provenance ─────────────────────────────────────────
29
+ {
30
+ path: "source.kind",
31
+ class: "managed",
32
+ merge: "source-only",
33
+ drift: "critical",
34
+ reindex: "facet-affecting",
35
+ snapshot: "on-book",
36
+ query: "indexed-column",
37
+ localized: false,
38
+ visibility: ["staff"],
39
+ editRole: "none",
40
+ overrideFriction: "none",
41
+ sourceFreshness: "sync",
42
+ },
43
+ {
44
+ path: "source.ref",
45
+ class: "managed",
46
+ merge: "source-only",
47
+ drift: "critical",
48
+ reindex: "none",
49
+ snapshot: "on-book",
50
+ query: "indexed-column",
51
+ localized: false,
52
+ visibility: ["staff"],
53
+ editRole: "none",
54
+ overrideFriction: "none",
55
+ sourceFreshness: "sync",
56
+ },
57
+ {
58
+ path: "seller.operator_id",
59
+ class: "managed",
60
+ merge: "source-only",
61
+ drift: "critical",
62
+ reindex: "none",
63
+ snapshot: "on-book",
64
+ query: "indexed-column",
65
+ localized: false,
66
+ visibility: ["staff"],
67
+ editRole: "none",
68
+ overrideFriction: "none",
69
+ sourceFreshness: "static",
70
+ },
71
+ // ── Identity / lifecycle ────────────────────────────────────────────────
72
+ {
73
+ path: "id",
74
+ class: "managed",
75
+ merge: "source-only",
76
+ drift: "critical",
77
+ reindex: "none",
78
+ snapshot: "on-book",
79
+ query: "first-class-table",
80
+ localized: false,
81
+ visibility: ["staff", "customer", "partner"],
82
+ editRole: "none",
83
+ overrideFriction: "none",
84
+ sourceFreshness: "static",
85
+ },
86
+ {
87
+ path: "code",
88
+ class: "managed",
89
+ merge: "source-only",
90
+ drift: "high",
91
+ reindex: "none",
92
+ snapshot: "on-book",
93
+ query: "indexed-column",
94
+ localized: false,
95
+ visibility: ["staff"],
96
+ editRole: "none",
97
+ overrideFriction: "none",
98
+ sourceFreshness: "sync",
99
+ },
100
+ {
101
+ path: "createdAt",
102
+ class: "managed",
103
+ merge: "source-only",
104
+ drift: "none",
105
+ reindex: "none",
106
+ snapshot: "on-book",
107
+ query: "indexed-column",
108
+ localized: false,
109
+ visibility: ["staff"],
110
+ editRole: "none",
111
+ overrideFriction: "none",
112
+ sourceFreshness: "static",
113
+ },
114
+ {
115
+ path: "updatedAt",
116
+ class: "managed",
117
+ merge: "source-only",
118
+ drift: "none",
119
+ reindex: "none",
120
+ snapshot: "never",
121
+ query: "indexed-column",
122
+ localized: false,
123
+ visibility: ["staff"],
124
+ editRole: "none",
125
+ overrideFriction: "none",
126
+ sourceFreshness: "sync",
127
+ },
128
+ // ── Cross-module reference (the parent product the extra attaches to) ──
129
+ {
130
+ path: "productId",
131
+ class: "managed",
132
+ merge: "source-only",
133
+ drift: "critical",
134
+ reindex: "none",
135
+ snapshot: "on-book",
136
+ query: "indexed-column",
137
+ localized: false,
138
+ visibility: ["staff"],
139
+ editRole: "none",
140
+ overrideFriction: "none",
141
+ sourceFreshness: "sync",
142
+ },
143
+ {
144
+ path: "supplierId",
145
+ class: "structural",
146
+ merge: "source-only",
147
+ drift: "high",
148
+ reindex: "none",
149
+ snapshot: "on-book",
150
+ query: "indexed-column",
151
+ localized: false,
152
+ visibility: ["staff"],
153
+ editRole: "none",
154
+ overrideFriction: "none",
155
+ sourceFreshness: "sync",
156
+ },
157
+ // ── Snapshot-relevant managed fields ────────────────────────────────────
158
+ // Extras' name/description aren't merchandised standalone — they're
159
+ // shown inside the parent product's add-on UI. Marked as managed for
160
+ // simplicity; if a future case requires marketing overrides on extras'
161
+ // names, this can be promoted to merchandisable.
162
+ {
163
+ path: "name",
164
+ class: "managed",
165
+ merge: "source-only",
166
+ drift: "medium",
167
+ reindex: "none",
168
+ snapshot: "on-book",
169
+ query: "indexed-column",
170
+ localized: false,
171
+ visibility: ["staff", "customer", "partner"],
172
+ editRole: "none",
173
+ overrideFriction: "none",
174
+ sourceFreshness: "sync",
175
+ },
176
+ {
177
+ path: "description",
178
+ class: "managed",
179
+ merge: "source-only",
180
+ drift: "low",
181
+ reindex: "none",
182
+ snapshot: "on-book",
183
+ query: "blob-only",
184
+ localized: false,
185
+ visibility: ["staff", "customer", "partner"],
186
+ editRole: "none",
187
+ overrideFriction: "none",
188
+ sourceFreshness: "sync",
189
+ },
190
+ {
191
+ path: "thumbnailUrl",
192
+ class: "merchandisable",
193
+ merge: "source-only",
194
+ drift: "low",
195
+ reindex: "entry",
196
+ snapshot: "on-book",
197
+ query: "indexed-column",
198
+ localized: false,
199
+ visibility: ["staff", "customer", "partner"],
200
+ editRole: "none",
201
+ overrideFriction: "none",
202
+ sourceFreshness: "sync",
203
+ },
204
+ // ── Selection / pricing structure (snapshotted at book time) ───────────
205
+ {
206
+ path: "selectionType",
207
+ class: "structural",
208
+ merge: "source-only",
209
+ drift: "high",
210
+ reindex: "none",
211
+ snapshot: "on-book",
212
+ query: "indexed-column",
213
+ localized: false,
214
+ visibility: ["staff", "customer", "partner"],
215
+ editRole: "none",
216
+ overrideFriction: "none",
217
+ sourceFreshness: "sync",
218
+ },
219
+ {
220
+ path: "pricingMode",
221
+ class: "structural",
222
+ merge: "source-only",
223
+ drift: "high",
224
+ reindex: "none",
225
+ snapshot: "on-quote-and-book",
226
+ query: "indexed-column",
227
+ localized: false,
228
+ visibility: ["staff", "customer", "partner"],
229
+ editRole: "none",
230
+ overrideFriction: "none",
231
+ sourceFreshness: "sync",
232
+ },
233
+ {
234
+ path: "pricedPerPerson",
235
+ class: "structural",
236
+ merge: "source-only",
237
+ drift: "high",
238
+ reindex: "none",
239
+ snapshot: "on-quote-and-book",
240
+ query: "indexed-column",
241
+ localized: false,
242
+ visibility: ["staff", "customer", "partner"],
243
+ editRole: "none",
244
+ overrideFriction: "none",
245
+ sourceFreshness: "sync",
246
+ },
247
+ {
248
+ path: "minQuantity",
249
+ class: "structural",
250
+ merge: "source-only",
251
+ drift: "medium",
252
+ reindex: "none",
253
+ snapshot: "on-book",
254
+ query: "indexed-column",
255
+ localized: false,
256
+ visibility: ["staff", "customer", "partner"],
257
+ editRole: "none",
258
+ overrideFriction: "none",
259
+ sourceFreshness: "sync",
260
+ },
261
+ {
262
+ path: "maxQuantity",
263
+ class: "structural",
264
+ merge: "source-only",
265
+ drift: "medium",
266
+ reindex: "none",
267
+ snapshot: "on-book",
268
+ query: "indexed-column",
269
+ localized: false,
270
+ visibility: ["staff", "customer", "partner"],
271
+ editRole: "none",
272
+ overrideFriction: "none",
273
+ sourceFreshness: "sync",
274
+ },
275
+ {
276
+ path: "defaultQuantity",
277
+ class: "structural",
278
+ merge: "source-only",
279
+ drift: "low",
280
+ reindex: "none",
281
+ snapshot: "on-book",
282
+ query: "indexed-column",
283
+ localized: false,
284
+ visibility: ["staff", "customer", "partner"],
285
+ editRole: "none",
286
+ overrideFriction: "none",
287
+ sourceFreshness: "sync",
288
+ },
289
+ {
290
+ path: "active",
291
+ class: "structural",
292
+ merge: "source-only",
293
+ drift: "high",
294
+ reindex: "none",
295
+ snapshot: "on-book",
296
+ query: "indexed-column",
297
+ localized: false,
298
+ visibility: ["staff"],
299
+ editRole: "none",
300
+ overrideFriction: "none",
301
+ sourceFreshness: "sync",
302
+ },
303
+ {
304
+ path: "sortOrder",
305
+ class: "structural",
306
+ merge: "source-only",
307
+ drift: "none",
308
+ reindex: "none",
309
+ snapshot: "never",
310
+ query: "indexed-column",
311
+ localized: false,
312
+ visibility: ["staff"],
313
+ editRole: "ops",
314
+ overrideFriction: "none",
315
+ sourceFreshness: "sync",
316
+ },
317
+ ];
318
+ export const extrasCatalogPolicy = defineFieldPolicy(EXTRAS_FIELD_POLICY);
319
+ export { EXTRAS_FIELD_POLICY };
@@ -0,0 +1,5 @@
1
+ import { type ContentOverlay, type MergeOverlaysOptions } from "@voyant-travel/catalog";
2
+ import { type ExtraContent } from "@voyant-travel/extras-contracts/content-shape";
3
+ export { EXTRAS_CONTENT_SCHEMA_VERSION, type ExtraContent, type ExtraMediaItem, type ExtraOption, type ExtraPolicy, type ExtraSummary, extraContentSchema, extraMediaItemSchema, extraOptionSchema, extraPolicySchema, extraSummarySchema, validateExtraContent, } from "@voyant-travel/extras-contracts/content-shape";
4
+ export declare function mergeOverlaysIntoExtraContent(payload: ExtraContent, overlays: ReadonlyArray<ContentOverlay>, options?: Pick<MergeOverlaysOptions, "onOverlayError">): ExtraContent;
5
+ //# sourceMappingURL=content-shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-shape.d.ts","sourceRoot":"","sources":["../../src/extras/content-shape.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAE1B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,+CAA+C,CAAA;AAEtD,OAAO,EACL,6BAA6B,EAC7B,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,+CAA+C,CAAA;AAEtD,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,aAAa,CAAC,cAAc,CAAC,EACvC,OAAO,GAAE,IAAI,CAAC,oBAAoB,EAAE,gBAAgB,CAAM,GACzD,YAAY,CASd"}
@@ -0,0 +1,13 @@
1
+ import { mergeOverlaysIntoContent, } from "@voyant-travel/catalog";
2
+ import { extraContentSchema, validateExtraContent, } from "@voyant-travel/extras-contracts/content-shape";
3
+ export { EXTRAS_CONTENT_SCHEMA_VERSION, extraContentSchema, extraMediaItemSchema, extraOptionSchema, extraPolicySchema, extraSummarySchema, validateExtraContent, } from "@voyant-travel/extras-contracts/content-shape";
4
+ export function mergeOverlaysIntoExtraContent(payload, overlays, options = {}) {
5
+ const merged = mergeOverlaysIntoContent(payload, overlays, {
6
+ validate(p) {
7
+ const r = validateExtraContent(p);
8
+ return r.valid ? { valid: true } : { valid: false, reason: r.reason };
9
+ },
10
+ onOverlayError: options.onOverlayError,
11
+ });
12
+ return extraContentSchema.parse(merged);
13
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Project an `ExtraContent` payload into a `BookingDraftShape`.
3
+ *
4
+ * Extras are booking add-ons (excursions, transfers, insurance) —
5
+ * they're never standalone bookable on their own; they always layer
6
+ * onto a parent product. So the descriptor here is **degenerate**:
7
+ *
8
+ * - `showsConfigure: false` (no configure step — extras are picked
9
+ * during the parent product's add-on step).
10
+ * - `showsTravelers: false` (extras don't have their own pax flow).
11
+ * - `showsPayment: false` (extras roll up into the parent's pricing).
12
+ * - `addons.catalog`: the extra itself + its sub-options projected
13
+ * as a small catalog. Useful for journey contexts that want to
14
+ * render an add-on detail view (e.g. ops admin reviewing a
15
+ * supplier's extras).
16
+ *
17
+ * In practice templates rarely call this directly — the parent
18
+ * product's `BookingDraftShape` aggregates extras via the journey's
19
+ * cross-product composer. This function is the building block.
20
+ */
21
+ import { type BookingDraftShape } from "@voyant-travel/catalog/booking-engine";
22
+ import type { ExtraContent } from "./content-shape.js";
23
+ export interface BuildExtraDraftShapeOptions {
24
+ locale?: string;
25
+ /**
26
+ * When true, returns the full descriptor surface (configure +
27
+ * travelers + payment all visible). Useful for tests or admin
28
+ * surfaces that render extras standalone. Defaults to false (the
29
+ * normal "extras-as-addon" mode).
30
+ */
31
+ standalone?: boolean;
32
+ }
33
+ export declare function buildExtraDraftShape(content: ExtraContent, options?: BuildExtraDraftShapeOptions): BookingDraftShape;
34
+ //# sourceMappingURL=draft-shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft-shape.d.ts","sourceRoot":"","sources":["../../src/extras/draft-shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAEL,KAAK,iBAAiB,EAMvB,MAAM,uCAAuC,CAAA;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAMtD,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,2BAAgC,GACxC,iBAAiB,CAsCnB"}