/** * `BookingRequirements` — the server-published description of what a * booking of this target requires: steps + sub-steps, passenger bands, * and per-traveler + lead-only field requirements. It is returned * alongside a quote and tells the journey wizard which steps + * sub-steps to render. * * It is **server-owned** — hosts render it and never invent one. * Concretely, `BookingRequirementsV1` encodes: * - **Step visibility flags** (`showsConfigure`, `showsAccommodation`, * `showsAddons`, etc.) — whether each top-level wizard step is * relevant to this product. * - **Sub-step descriptors** inside Configure / Accommodation / * Add-ons — which controls to render and what options to show. * - **Passenger bands** (`paxBands`) — adult / child / infant * constraints, drives the count steppers. * - **Per-traveler + lead-only field requirements** — drives the * PassengersSection / billing-step columns. * * `BookingRequirementsV1` is per-product / per-quote; the engine populates * it for owned rows, the adapter (or per-vertical builder) populates it * for sourced rows. It is **immutable per quote** — clients use it to * decide rendering; they never mutate it. * * Catalog plane stays neutral about per-vertical requirements * derivation. Each vertical exports a `build*Requirements(content, scope)` * function that projects its content payload into a * `BookingRequirementsV1`. The Booking Session lifecycle composes these * through the owned handler's `computeRequirements`, which the stateless * Offer Preview reuses; the beta `contentEnricher` hook that used to do it is * deleted (voyant#4188). * * The Zod schemas below are the **single source of truth** for these * shapes — every exported type is inferred from one of them. Runtime * defaults and helpers live in `requirements-defaults.ts`. */ import { z } from "zod"; /** * Versioned checkout choices shared by quote capability discovery, Commit, * and Commit outcomes. A host selects one of the intents advertised by the * active Quote; it never invents an integration-specific payment method. */ export declare const bookingCheckoutIntentV1: z.ZodEnum<{ hold: "hold"; card: "card"; ticket_on_credit: "ticket_on_credit"; bank_transfer: "bank_transfer"; inquiry: "inquiry"; }>; export type BookingCheckoutIntentV1 = z.infer; /** * A single occupancy band — adult / child / infant or vertical-specific. * * `code` is stable; `"adult" | "child" | "infant"` are the canonical * three and verticals may add senior / student / etc. A product that * sells several tiers of one category ("Child 6-12" and "Child 0-5") * qualifies the second and later tiers as `child:` so each is * separately countable and separately priced — see `paxBandBaseCode`. * * `minAge` / `maxAge` describe an optional age window (closed-open * lower, closed upper); verticals enforce it in their own validation. * `minCount` / `maxCount` are the count window for this band on this * product. */ export declare const paxBandSpecV1: z.ZodObject<{ code: z.ZodString; label: z.ZodString; minAge: z.ZodOptional; maxAge: z.ZodOptional; minCount: z.ZodNumber; maxCount: z.ZodNumber; }, z.core.$strip>; export type PaxBandSpecV1 = z.infer; /** * A cross-band occupancy rule (e.g. "Child under 6 requires an Adult"), * derived from the product's pricing-category dependencies. Both * `dependentCode` and `masterCode` are pax band codes. * * - `requires` — at least one `master` must be present when any * `dependent` is added. * - `limits_per_master` — `dependent` count ≤ `master` count × * `maxPerMaster`. * - `limits_sum` — `dependent` count ≤ `maxDependentSum`. * - `excludes` — `dependent` and `master` cannot both be present. */ export declare const paxBandDependencyV1: z.ZodObject<{ dependentCode: z.ZodString; masterCode: z.ZodString; type: z.ZodEnum<{ requires: "requires"; limits_per_master: "limits_per_master"; limits_sum: "limits_sum"; excludes: "excludes"; }>; maxPerMaster: z.ZodOptional; maxDependentSum: z.ZodOptional; }, z.core.$strip>; export type PaxBandDependencyV1 = z.infer; /** A cabin category sub-step option (cruises). */ export declare const cabinCategoryOptionV1: z.ZodObject<{ id: z.ZodString; code: z.ZodOptional; name: z.ZodString; type: z.ZodOptional; capacityMin: z.ZodOptional; capacityMax: z.ZodOptional; description: z.ZodOptional; }, z.core.$strip>; export type CabinCategoryOptionV1 = z.infer; /** A specific cabin / unit within a category. */ export declare const cabinNumberOptionV1: z.ZodObject<{ id: z.ZodString; code: z.ZodOptional; label: z.ZodString; capacity: z.ZodOptional; hasAccessibilityFeatures: z.ZodOptional; }, z.core.$strip>; export type CabinNumberOptionV1 = z.infer; /** A bookable unit under a product option / variant. */ export declare const productVariantUnitOptionV1: z.ZodObject<{ id: z.ZodString; name: z.ZodString; description: z.ZodOptional>; unitType: z.ZodOptional>; minQuantity: z.ZodOptional>; maxQuantity: z.ZodOptional>; }, z.core.$strip>; export type ProductVariantUnitOptionV1 = z.infer; /** A product option / variant selectable before pricing and booking. */ export declare const productVariantOptionV1: z.ZodObject<{ id: z.ZodString; code: z.ZodOptional>; name: z.ZodString; description: z.ZodOptional>; isDefault: z.ZodOptional; units: z.ZodOptional>; unitType: z.ZodOptional>; minQuantity: z.ZodOptional>; maxQuantity: z.ZodOptional>; }, z.core.$strip>>>; }, z.core.$strip>; export type ProductVariantOptionV1 = z.infer; /** * A rate-plan option attached to a `RoomOptionV1` (accommodations only, * today). `cancellationPolicy` is a display string ("free until 7 days * before", "non-refundable", …); `inclusions` is free-form * ("breakfast", "wifi", "spa credit"). */ export declare const ratePlanOptionV1: z.ZodObject<{ id: z.ZodString; name: z.ZodString; description: z.ZodOptional>; chargeFrequency: z.ZodOptional>; cancellationPolicy: z.ZodOptional>; inclusions: z.ZodOptional>; currency: z.ZodOptional; }, z.core.$strip>; export type RatePlanOptionV1 = z.infer; /** * A room option (accommodations + multi-day tours w/ rooms). * * `baseRateHint` is a per-night price hint when the upstream surfaced * one — pricing is volatile-live, so this is a rendering hint only. * `ratePlans` empty = no plan picker needed (e.g. simple multi-day-tour * rooms); when non-empty the journey's Accommodation step renders a * rate-plan dropdown per picked room. */ export declare const roomOptionV1: z.ZodObject<{ id: z.ZodString; name: z.ZodString; description: z.ZodOptional>; capacity: z.ZodOptional>; baseRateHint: z.ZodOptional>; ratePlans: z.ZodOptional>; chargeFrequency: z.ZodOptional>; cancellationPolicy: z.ZodOptional>; inclusions: z.ZodOptional>; currency: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>; export type RoomOptionV1 = z.infer; /** A pre/post extension option (cruises only, today). */ export declare const extensionOptionV1: z.ZodObject<{ id: z.ZodString; name: z.ZodString; city: z.ZodOptional>; side: z.ZodEnum<{ pre: "pre"; post: "post"; }>; nights: z.ZodOptional>; pricePerPersonHint: z.ZodOptional>; }, z.core.$strip>; export type ExtensionOptionV1 = z.infer; /** An add-on offer item (excursions, insurance, generic extras). */ export declare const addonOfferV1: z.ZodObject<{ id: z.ZodString; name: z.ZodString; description: z.ZodOptional>; kind: z.ZodEnum<{ extras: "extras"; excursions: "excursions"; insurance: "insurance"; }>; groupKey: z.ZodOptional>; pricingMode: z.ZodOptional>; unitAmountCents: z.ZodOptional>; currency: z.ZodOptional>; pricedPerPerson: z.ZodOptional>; selectionType: z.ZodOptional>>; minQuantity: z.ZodOptional>; maxQuantity: z.ZodOptional>; defaultQuantity: z.ZodOptional>; }, z.core.$strip>; export type AddonOfferV1 = z.infer; /** Configure step sub-step union. */ export declare const configureSubStepV1: z.ZodDiscriminatedUnion<[z.ZodObject<{ kind: z.ZodLiteral<"departure">; required: z.ZodLiteral; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"product-option">; options: z.ZodArray>; name: z.ZodString; description: z.ZodOptional>; isDefault: z.ZodOptional; units: z.ZodOptional>; unitType: z.ZodOptional>; minQuantity: z.ZodOptional>; maxQuantity: z.ZodOptional>; }, z.core.$strip>>>; }, z.core.$strip>>; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"option-units">; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"cabin-category">; categories: z.ZodArray; name: z.ZodString; type: z.ZodOptional; capacityMin: z.ZodOptional; capacityMax: z.ZodOptional; description: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"cabin-number">; perCategory: z.ZodRecord; label: z.ZodString; capacity: z.ZodOptional; hasAccessibilityFeatures: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"date-range">; minNights: z.ZodNumber; maxNights: z.ZodNumber; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"occupancy">; bands: z.ZodArray; maxAge: z.ZodOptional; minCount: z.ZodNumber; maxCount: z.ZodNumber; }, z.core.$strip>>; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"air-arrangement">; required: z.ZodOptional; }, z.core.$strip>], "kind">; export type ConfigureSubStepV1 = z.infer; /** Accommodation step sub-step union. */ export declare const accommodationSubStepV1: z.ZodDiscriminatedUnion<[z.ZodObject<{ kind: z.ZodLiteral<"rooms">; options: z.ZodArray>; capacity: z.ZodOptional>; baseRateHint: z.ZodOptional>; ratePlans: z.ZodOptional>; chargeFrequency: z.ZodOptional>; cancellationPolicy: z.ZodOptional>; inclusions: z.ZodOptional>; currency: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; sharedRoomAllowed: z.ZodBoolean; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"extensions">; options: z.ZodArray>; side: z.ZodEnum<{ pre: "pre"; post: "post"; }>; nights: z.ZodOptional>; pricePerPersonHint: z.ZodOptional>; }, z.core.$strip>>; allowsPre: z.ZodBoolean; allowsPost: z.ZodBoolean; }, z.core.$strip>], "kind">; export type AccommodationSubStepV1 = z.infer; /** Add-on group descriptor. */ export declare const addonGroupV1: z.ZodObject<{ kind: z.ZodEnum<{ extras: "extras"; excursions: "excursions"; insurance: "insurance"; }>; label: z.ZodString; groupBy: z.ZodOptional>; perGuestSelection: z.ZodBoolean; items: z.ZodArray>; kind: z.ZodEnum<{ extras: "extras"; excursions: "excursions"; insurance: "insurance"; }>; groupKey: z.ZodOptional>; pricingMode: z.ZodOptional>; unitAmountCents: z.ZodOptional>; currency: z.ZodOptional>; pricedPerPerson: z.ZodOptional>; selectionType: z.ZodOptional>>; minQuantity: z.ZodOptional>; maxQuantity: z.ZodOptional>; defaultQuantity: z.ZodOptional>; }, z.core.$strip>>; }, z.core.$strip>; export type AddonGroupV1 = z.infer; /** * Per-traveler field requirement (PassengersSection columns). * * `key` is a stable field key — e.g. "passport", "national_id", * "dietary", "accessibility", "preferredLanguage". `type` is one of * "text" | "date" | "country" | "boolean" | "select" | … `options` are * for "select"-type fields. `appliesToBands` empty / undefined = all * bands. */ export declare const travelerFieldRequirementV1: z.ZodObject<{ key: z.ZodString; label: z.ZodString; type: z.ZodString; required: z.ZodBoolean; options: z.ZodOptional>>; appliesToBands: z.ZodOptional>; maxLength: z.ZodOptional; }, z.core.$strip>; export type TravelerFieldRequirementV1 = z.infer; /** Lead-only / billing-step field requirement. `group` is the render bucket. */ export declare const bookingFieldRequirementV1: z.ZodObject<{ key: z.ZodString; label: z.ZodString; type: z.ZodString; required: z.ZodBoolean; group: z.ZodEnum<{ billing: "billing"; company: "company"; preferences: "preferences"; }>; maxLength: z.ZodOptional; }, z.core.$strip>; export type BookingFieldRequirementV1 = z.infer; export declare const bookingRequirementsV1: z.ZodObject<{ showsConfigure: z.ZodBoolean; showsBilling: z.ZodBoolean; showsTravelers: z.ZodBoolean; showsAccommodation: z.ZodBoolean; showsAddons: z.ZodBoolean; showsAncillaries: z.ZodDefault; showsPayment: z.ZodBoolean; showsReview: z.ZodLiteral; configureSubSteps: z.ZodOptional; required: z.ZodLiteral; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"product-option">; options: z.ZodArray>; name: z.ZodString; description: z.ZodOptional>; isDefault: z.ZodOptional; units: z.ZodOptional>; unitType: z.ZodOptional>; minQuantity: z.ZodOptional>; maxQuantity: z.ZodOptional>; }, z.core.$strip>>>; }, z.core.$strip>>; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"option-units">; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"cabin-category">; categories: z.ZodArray; name: z.ZodString; type: z.ZodOptional; capacityMin: z.ZodOptional; capacityMax: z.ZodOptional; description: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"cabin-number">; perCategory: z.ZodRecord; label: z.ZodString; capacity: z.ZodOptional; hasAccessibilityFeatures: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"date-range">; minNights: z.ZodNumber; maxNights: z.ZodNumber; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"occupancy">; bands: z.ZodArray; maxAge: z.ZodOptional; minCount: z.ZodNumber; maxCount: z.ZodNumber; }, z.core.$strip>>; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"air-arrangement">; required: z.ZodOptional; }, z.core.$strip>], "kind">>>; paxBands: z.ZodArray; maxAge: z.ZodOptional; minCount: z.ZodNumber; maxCount: z.ZodNumber; }, z.core.$strip>>; paxBandsAllowedTotal: z.ZodObject<{ min: z.ZodNumber; max: z.ZodNumber; }, z.core.$strip>; paxBandDependencies: z.ZodOptional; maxPerMaster: z.ZodOptional; maxDependentSum: z.ZodOptional; }, z.core.$strip>>>; travelerFields: z.ZodArray>>; appliesToBands: z.ZodOptional>; maxLength: z.ZodOptional; }, z.core.$strip>>; bookingFields: z.ZodArray; maxLength: z.ZodOptional; }, z.core.$strip>>; accommodation: z.ZodOptional>; capacity: z.ZodOptional>; baseRateHint: z.ZodOptional>; ratePlans: z.ZodOptional>; chargeFrequency: z.ZodOptional>; cancellationPolicy: z.ZodOptional>; inclusions: z.ZodOptional>; currency: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>>; sharedRoomAllowed: z.ZodBoolean; subSteps: z.ZodOptional; options: z.ZodArray>; capacity: z.ZodOptional>; baseRateHint: z.ZodOptional>; ratePlans: z.ZodOptional>; chargeFrequency: z.ZodOptional>; cancellationPolicy: z.ZodOptional>; inclusions: z.ZodOptional>; currency: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; sharedRoomAllowed: z.ZodBoolean; }, z.core.$strip>, z.ZodObject<{ kind: z.ZodLiteral<"extensions">; options: z.ZodArray>; side: z.ZodEnum<{ pre: "pre"; post: "post"; }>; nights: z.ZodOptional>; pricePerPersonHint: z.ZodOptional>; }, z.core.$strip>>; allowsPre: z.ZodBoolean; allowsPost: z.ZodBoolean; }, z.core.$strip>], "kind">>>; }, z.core.$strip>>; addons: z.ZodOptional>; kind: z.ZodEnum<{ extras: "extras"; excursions: "excursions"; insurance: "insurance"; }>; groupKey: z.ZodOptional>; pricingMode: z.ZodOptional>; unitAmountCents: z.ZodOptional>; currency: z.ZodOptional>; pricedPerPerson: z.ZodOptional>; selectionType: z.ZodOptional>>; minQuantity: z.ZodOptional>; maxQuantity: z.ZodOptional>; defaultQuantity: z.ZodOptional>; }, z.core.$strip>>>; groups: z.ZodOptional; label: z.ZodString; groupBy: z.ZodOptional>; perGuestSelection: z.ZodBoolean; items: z.ZodArray>; kind: z.ZodEnum<{ extras: "extras"; excursions: "excursions"; insurance: "insurance"; }>; groupKey: z.ZodOptional>; pricingMode: z.ZodOptional>; unitAmountCents: z.ZodOptional>; currency: z.ZodOptional>; pricedPerPerson: z.ZodOptional>; selectionType: z.ZodOptional>>; minQuantity: z.ZodOptional>; maxQuantity: z.ZodOptional>; defaultQuantity: z.ZodOptional>; }, z.core.$strip>>; }, z.core.$strip>>>; }, z.core.$strip>>; ancillaries: z.ZodOptional>; planLabel: z.ZodOptional>; price: z.ZodObject<{ amountMinor: z.ZodNumber; currency: z.ZodString; }, z.core.$strict>; pricedPerPerson: z.ZodDefault; highlights: z.ZodDefault; }, z.core.$strict>>>; eligibility: z.ZodObject<{ status: z.ZodEnum<{ eligible: "eligible"; ineligible: "ineligible"; referral: "referral"; }>; reasons: z.ZodDefault>>; }, z.core.$strict>; disclosures: z.ZodDefault; required: z.ZodBoolean; }, z.core.$strict>>>; requiredTravelerFields: z.ZodDefault; options: z.ZodOptional>>; helpText: z.ZodOptional; }, z.core.$strict>>>; validUntil: z.ZodString; quoteRef: z.ZodString; metadata: z.ZodOptional>; }, z.core.$strict>>>; diagnostics: z.ZodDefault; status: z.ZodEnum<{ timeout: "timeout"; ok: "ok"; unavailable: "unavailable"; error: "error"; }>; message: z.ZodOptional; latencyMs: z.ZodOptional; }, z.core.$strict>>>; }, z.core.$strict>>>; }, z.core.$strip>>; paymentIntents: z.ZodArray>; }, z.core.$strip>; export type BookingRequirementsV1 = z.infer; /** * The requirements a fingerprint is taken over — everything except the live * ancillary offers. * * The descriptor is fingerprinted at Quote and re-derived at Commit, and a * difference supersedes the quote. That is right for everything the descriptor * normally carries, because those things describe what a booking *needs* and * only change when the operator changes something. * * Ancillary offers do not behave like that. They are priced live by a third * party, they carry a `validUntil` that moves on every call, and two identical * fan-outs a second apart legitimately differ. Including them would supersede * every quote the moment a traveller reached the payment step, which is not a * price change anyone made — it is the clock. * * `showsAncillaries` stays in the fingerprint: whether the step exists at all * is a stable fact about the deployment, and it changing genuinely is a * different booking. What the offers cost is re-confirmed at selection time * against the offer's own window instead. * * Mirrors `priceFingerprintInput` in `./pricing-contracts.js`. */ export declare function requirementsFingerprintInput(requirements: T): T;