import type { IndexerAdapter, IndexerSlice } from "@voyant-travel/catalog-contracts/indexer/contract"; import type { SourceAdapterContext } from "./adapter/contract.js"; import type { QuoteEntityResult, SourceAdapterRegistry } from "./booking-engine/index.js"; import type { CatalogBookingSnapshotExecutionContext, CatalogBookingSnapshotRuntime } from "./booking-snapshot-subscriber-runtime.js"; import type { FieldPolicyRegistry, Visibility } from "./contract.js"; import type { EmbeddingProvider } from "./embeddings/contract.js"; import type { CatalogOffersIndexFields, CatalogOffersSearchDestination } from "./offers/operator-routes.js"; import { type CatalogProjectionRuntime } from "./projection-runtime.js"; import { type DocumentBuilder } from "./services/indexer-service.js"; export declare const DEFAULT_CATALOG_VERTICALS: readonly ["products", "extras", "cruises", "charters", "accommodations"]; export declare const DEFAULT_CATALOG_SLICES: ReadonlyArray; export interface CatalogMarketRow { id: string; defaultLanguageTag: string; } export interface CatalogLocaleRow { marketId: string; languageTag: string; } export declare function buildCatalogSlices(input: { markets: readonly CatalogMarketRow[]; locales: readonly CatalogLocaleRow[]; channelIds: readonly string[]; }): IndexerSlice[]; export declare function withCatalogEmbedding(inner: DocumentBuilder, embeddings: { capabilities: { modelId: string; }; embed(input: string[]): Promise; } | undefined): DocumentBuilder; export interface CatalogOffersSearchScope { locale: string; audience: IndexerSlice["audience"]; market: string; channel?: string; } export declare function withoutCatalogScopeChannel(scope: CatalogOffersSearchScope): CatalogOffersSearchScope; export interface CatalogRuntimeEnv { VOYANT_API_KEY?: string; VOYANT_CLOUD_API_KEY?: string; VOYANT_CLOUD_API_URL?: string; /** * Embedding backend the catalog authenticates through the Voyant Cloud AI * gateway. Both are adapters over the same `/ai/v1/{provider}` proxy shape; * defaults to `gemini` for compatibility. Managed runtimes set `openai`. * * Switching provider switches the embedding MODEL (and its vector * dimensionality), so — like any model change — it is a deliberate * `bulkReindex` operation, not a hot swap. The Postgres indexer is safe to * flip in place: its `search_embedding` column is an unsized `vector` and * rows are keyed by `embedding_model_id`, so old/new dimensions coexist and * search reads only the active model. The Typesense indexer pins `num_dim` * at collection creation and `ensureCollection` does not migrate it, so a * Typesense-backed deployment must recreate/migrate the vector field before * enabling a provider whose model dimension differs. */ CATALOG_EMBEDDING_PROVIDER?: "openai" | "gemini"; } export declare function buildCatalogEmbeddingProvider(env: CatalogRuntimeEnv): EmbeddingProvider | undefined; export declare function createCatalogOffersSearchResolvers(resolveIndexer: (context: unknown) => IndexerAdapter | undefined, resolveScope: (context: unknown) => CatalogOffersSearchScope): { fetchIndexFields(context: unknown, ids: string[]): Promise>; resolveDynamicHotelIds(context: unknown, destination: CatalogOffersSearchDestination, limit: number): Promise; }; export declare function createProductQuoteShapeEnricher(dependencies: { resolveContent(input: { db: unknown; entityId: string; locales: string[]; audience: Visibility; market?: string; currency?: string; registry: SourceAdapterRegistry; adapterContext: SourceAdapterContext; }): Promise<{ content?: unknown; } | null>; buildShape(content: unknown, options: { locale?: string; }): NonNullable; }): (input: { db: unknown; result: QuoteEntityResult; entityModule: string; entityId: string; locale?: string; audience?: string; market?: string; currency?: string; registry: SourceAdapterRegistry; adapterContext?: SourceAdapterContext; }) => Promise; export declare function createCatalogProjectionRuntimeAdapter(options: { bindings: TBindings; withDb(bindings: TBindings, operation: (db: TDb) => Promise): Promise; buildContext(db: TDb): Promise<{ adapter: IndexerAdapter; slices: IndexerSlice[]; registries: ReadonlyMap; builder: DocumentBuilder; } | null>; }): CatalogProjectionRuntime; export declare function createCatalogBookingSnapshotRuntimeAdapter(options: { bindings: TBindings; withDb(bindings: TBindings, operation: (db: TDb) => Promise): Promise; buildContext(db: TDb): Promise; }): CatalogBookingSnapshotRuntime; export declare function resolveCatalogHoldTtlMs(options: { entityModule: string; entityId: string; defaultTtlMs?: number; loadProduct(entityId: string): Promise<{ supplierId?: string | null; reservationTimeoutMinutes?: number | null; } | null>; loadSupplier(supplierId: string): Promise<{ reservationTimeoutMinutes?: number | null; } | null>; }): Promise; export interface CatalogQuoteTaxLine { amountCents: number; includedInPrice: boolean; code?: string | null; name: string; rateBasisPoints?: number | null; scope?: string | null; } export declare function applyCatalogTaxToQuoteResult(input: { result: QuoteEntityResult; entityModule: string; entityId: string; sourceKind: string; ownedSourceKind: string; resolveTaxLine(input: { productId: string | null; taxableCents: number; currency: string; }): Promise; persistPricing(quoteId: string, pricing: NonNullable): Promise; }): Promise;