/** * Adapt a vertical-shaped `CruiseAdapter` (with its multi-method * `fetchCruise / fetchSailing / fetchShip / fetchSailingItinerary` * surface) into a catalog-plane `SourceAdapter` so the cruises module * can participate in: * * - The catalog plane's discovery / projection-capture pipeline * (`sync.ts` writes a `catalog_sourced_entries` row per emitted * projection), enabling the durable thin-content synthesizer * fallback for cruises (sourced-content §2.5, §3.6). * - The `getCruiseContent` SWR machinery (sourced-content §3.4) — * the shim's `getContent` composes the cruise adapter's per-aspect * fetches into one `CruiseContent` payload. * - Catalog read-side content composition for projection and snapshot * subscribers. Booking creation has no application caller here. * * Per the doc's Phase E note: the cruise adapter retains its internal * multi-call composition; only the public catalog surface narrows. * * Templates wire the shim by registering it into the catalog * `SourceAdapterRegistry` AT PROCESS START, alongside the cruise * adapter's own per-vertical registration. Both registrations are * cheap — they share the same underlying `CruiseAdapter` instance. */ import type { SourceAdapter } from "@voyant-travel/catalog"; import { type CruiseContent } from "../content-shape.js"; import type { CruiseAdapter, ExternalItineraryDay, SourceRef } from "./index.js"; export interface CruiseSourceAdapterShimOptions { /** * The `source_kind` reported on every projection emitted by the * shim. Defaults to `"cruise:" + adapter.name` so multiple cruise * adapters (different agencies) coexist in the catalog registry * without colliding on `source_kind`. */ sourceKind?: string; /** * Optional translator from `SourceRef` → catalog-side `entity_id`. * Catalog `entity_id` is the Voyant-side TypeID; this shim produces * one synthetically by hashing the upstream ref so discovery is * idempotent. Templates can override when they have an external-id * → typeid mapping in their own DB. * * The default produces stable ids that round-trip across re-syncs: * `crus_${slug-of-externalId}`. The catalog plane uses the entity_id * as its primary key into `catalog_sourced_entries`, so stability is * load-bearing — drift on the id maps to a new entity. */ buildEntityId?: (sourceRef: SourceRef) => string; /** * Pagination batch size for `discover`. Defaults to 200 — large * enough to amortize HTTP overhead, small enough to cap memory. */ pageSize?: number; /** * BCP 47 locales the cruise adapter can serve content in. Reported * via `capabilities.supportedContentLocales`. Defaults to undefined * (unknown — caller probes per-call). */ supportedContentLocales?: ReadonlyArray; /** * When false, declares `supportsContentFetch: false` so the catalog * plane skips `getContent` and falls through to the per-vertical * thin-content synthesizer (sourced-content §3.6). Defaults to * true — the shim composes a real `CruiseContent` payload from the * cruise adapter's per-aspect fetches. */ supportsContentFetch?: boolean; } export interface CruiseSourceAdapterShim extends SourceAdapter { /** The wrapped vertical adapter — exposed for diagnostics / tests. */ readonly cruiseAdapter: CruiseAdapter; } /** * Wrap a `CruiseAdapter` as a catalog `SourceAdapter`. The wrapped * adapter is shared by reference — its internal state (HTTP clients, * caches, credentials) is not duplicated. */ export declare function cruiseAdapterToSourceAdapter(cruiseAdapter: CruiseAdapter, options?: CruiseSourceAdapterShimOptions): CruiseSourceAdapterShim; export declare function cruiseItineraryStopFrom(day: ExternalItineraryDay, date?: string | null): CruiseContent["itinerary_stops"][number];