@voyantjs/travel-composer 0.55.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 (56) hide show
  1. package/README.md +38 -0
  2. package/dist/catalog-component-adapter.d.ts +16 -0
  3. package/dist/catalog-component-adapter.d.ts.map +1 -0
  4. package/dist/catalog-component-adapter.js +34 -0
  5. package/dist/cruise-extension.d.ts +48 -0
  6. package/dist/cruise-extension.d.ts.map +1 -0
  7. package/dist/cruise-extension.js +66 -0
  8. package/dist/index.d.ts +21 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +29 -0
  11. package/dist/mcp-tools.d.ts +157 -0
  12. package/dist/mcp-tools.d.ts.map +1 -0
  13. package/dist/mcp-tools.js +109 -0
  14. package/dist/routes.d.ts +1988 -0
  15. package/dist/routes.d.ts.map +1 -0
  16. package/dist/routes.js +239 -0
  17. package/dist/schema.d.ts +1228 -0
  18. package/dist/schema.d.ts.map +1 -0
  19. package/dist/schema.js +163 -0
  20. package/dist/service-cancellation.d.ts +6 -0
  21. package/dist/service-cancellation.d.ts.map +1 -0
  22. package/dist/service-cancellation.js +251 -0
  23. package/dist/service-checkout.d.ts +6 -0
  24. package/dist/service-checkout.d.ts.map +1 -0
  25. package/dist/service-checkout.js +328 -0
  26. package/dist/service-drafts.d.ts +13 -0
  27. package/dist/service-drafts.d.ts.map +1 -0
  28. package/dist/service-drafts.js +223 -0
  29. package/dist/service-helpers.d.ts +17 -0
  30. package/dist/service-helpers.d.ts.map +1 -0
  31. package/dist/service-helpers.js +161 -0
  32. package/dist/service-internals.d.ts +11 -0
  33. package/dist/service-internals.d.ts.map +1 -0
  34. package/dist/service-internals.js +72 -0
  35. package/dist/service-pricing.d.ts +8 -0
  36. package/dist/service-pricing.d.ts.map +1 -0
  37. package/dist/service-pricing.js +142 -0
  38. package/dist/service-reservation.d.ts +5 -0
  39. package/dist/service-reservation.d.ts.map +1 -0
  40. package/dist/service-reservation.js +447 -0
  41. package/dist/service-trips.d.ts +14 -0
  42. package/dist/service-trips.d.ts.map +1 -0
  43. package/dist/service-trips.js +377 -0
  44. package/dist/service-types.d.ts +252 -0
  45. package/dist/service-types.d.ts.map +1 -0
  46. package/dist/service-types.js +6 -0
  47. package/dist/service.d.ts +33 -0
  48. package/dist/service.d.ts.map +1 -0
  49. package/dist/service.js +35 -0
  50. package/dist/traveler-party-validation.d.ts +3 -0
  51. package/dist/traveler-party-validation.d.ts.map +1 -0
  52. package/dist/traveler-party-validation.js +68 -0
  53. package/dist/validation.d.ts +363 -0
  54. package/dist/validation.d.ts.map +1 -0
  55. package/dist/validation.js +226 -0
  56. package/package.json +88 -0
package/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # @voyantjs/travel-composer
2
+
3
+ Deterministic composition layer for customer-facing trips that group multiple
4
+ component bookings/orders into one itinerary, pricing, reserve, checkout, and
5
+ support experience.
6
+
7
+ This package is landing on the travel-composer integration branch. It currently
8
+ includes the durable schema, Zod contracts, deterministic trip service,
9
+ catalog component adapter, price aggregation, reserve workflow, checkout
10
+ handoff, component-level cancellation preview/cancel operations, Cruise
11
+ Extension representation helpers, Hono routes, and MCP tools. Checkout and
12
+ cancellation are dependency-injected so app/runtime packages keep owning
13
+ payment-provider, bank-transfer, storefront URL, supplier, and staff-remediation
14
+ policy. See
15
+ `docs/architecture/travel-composer-implementation-plan.md` for the full PR
16
+ sequence and remaining slices.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pnpm add @voyantjs/travel-composer
22
+ ```
23
+
24
+ ## Exports
25
+
26
+ | Entry | Description |
27
+ | --- | --- |
28
+ | `.` | Module export |
29
+ | `./schema` | Drizzle tables, added in the schema slice |
30
+ | `./validation` | Zod contracts |
31
+ | `./service` | Deterministic composer services |
32
+ | `./mcp-tools` | AI-safe trip planning, revision, price, and reserve tools |
33
+ | `./cruise-extension` | Cruise Extension link and selection helpers |
34
+ | `./routes` | Hono route factory/module routes |
35
+
36
+ ## License
37
+
38
+ Apache-2.0
@@ -0,0 +1,16 @@
1
+ import { type BookingDraftV1, type TravelerEntryV1 } from "@voyantjs/catalog/booking-engine/contracts";
2
+ import type { TripComponent } from "./schema.js";
3
+ export interface CatalogComponentBookingDraftOverrides {
4
+ configure?: Partial<BookingDraftV1["configure"]>;
5
+ billing?: Partial<BookingDraftV1["billing"]>;
6
+ travelers?: TravelerEntryV1[];
7
+ accommodation?: BookingDraftV1["accommodation"];
8
+ addons?: BookingDraftV1["addons"];
9
+ payment?: Partial<BookingDraftV1["payment"]>;
10
+ promotionCode?: string;
11
+ internalNotes?: string;
12
+ customerNotes?: string;
13
+ }
14
+ export declare function isCatalogBackedTripComponent(component: Pick<TripComponent, "kind" | "entityModule" | "entityId" | "sourceKind">): boolean;
15
+ export declare function toBookingDraftV1(component: Pick<TripComponent, "kind" | "entityModule" | "entityId" | "sourceKind" | "sourceConnectionId" | "sourceRef">, overrides?: CatalogComponentBookingDraftOverrides): BookingDraftV1;
16
+ //# sourceMappingURL=catalog-component-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-component-adapter.d.ts","sourceRoot":"","sources":["../src/catalog-component-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,eAAe,EACrB,MAAM,4CAA4C,CAAA;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAGhD,MAAM,WAAW,qCAAqC;IACpD,SAAS,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAA;IAC5C,SAAS,CAAC,EAAE,eAAe,EAAE,CAAA;IAC7B,aAAa,CAAC,EAAE,cAAc,CAAC,eAAe,CAAC,CAAA;IAC/C,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAA;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC,GAClF,OAAO,CAOT;AAED,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,IAAI,CACb,aAAa,EACb,MAAM,GAAG,cAAc,GAAG,UAAU,GAAG,YAAY,GAAG,oBAAoB,GAAG,WAAW,CACzF,EACD,SAAS,GAAE,qCAA0C,GACpD,cAAc,CA4BhB"}
@@ -0,0 +1,34 @@
1
+ import { bookingDraftV1, } from "@voyantjs/catalog/booking-engine/contracts";
2
+ import { TravelComposerInvariantError } from "./service.js";
3
+ export function isCatalogBackedTripComponent(component) {
4
+ return Boolean(component.kind === "catalog_booking" &&
5
+ component.entityModule &&
6
+ component.entityId &&
7
+ component.sourceKind);
8
+ }
9
+ export function toBookingDraftV1(component, overrides = {}) {
10
+ if (!isCatalogBackedTripComponent(component)) {
11
+ throw new TravelComposerInvariantError("Trip component cannot be mapped to a booking draft without catalog entity refs");
12
+ }
13
+ return bookingDraftV1.parse({
14
+ entity: {
15
+ module: component.entityModule,
16
+ id: component.entityId,
17
+ sourceKind: component.sourceKind,
18
+ sourceConnectionId: component.sourceConnectionId ?? undefined,
19
+ sourceRef: component.sourceRef ?? undefined,
20
+ },
21
+ configure: {
22
+ pax: {},
23
+ ...overrides.configure,
24
+ },
25
+ billing: overrides.billing,
26
+ travelers: overrides.travelers,
27
+ accommodation: overrides.accommodation,
28
+ addons: overrides.addons,
29
+ payment: overrides.payment,
30
+ promotionCode: overrides.promotionCode,
31
+ internalNotes: overrides.internalNotes,
32
+ customerNotes: overrides.customerNotes,
33
+ });
34
+ }
@@ -0,0 +1,48 @@
1
+ import type { CreateTripComponentInput } from "./validation.js";
2
+ export declare const CRUISE_EXTENSION_METADATA_KIND = "cruise_extension";
3
+ export type CruiseExtensionTargetKind = "cruise" | "cruise_sailing";
4
+ export type CruiseExtensionPlacement = "pre" | "post" | "either";
5
+ export type CruiseExtensionLifecycle = "dependent_extra" | "independent_component";
6
+ export interface CruiseExtensionLinkInput {
7
+ extensionProductId: string;
8
+ targetKind: CruiseExtensionTargetKind;
9
+ targetId: string;
10
+ linkKey?: string;
11
+ }
12
+ export interface CruiseExtensionLinkCommand {
13
+ linkKey: string;
14
+ leftId: string;
15
+ rightId: string;
16
+ }
17
+ export interface CruiseExtensionSelection {
18
+ extensionProductId: string;
19
+ targetKind: CruiseExtensionTargetKind;
20
+ targetId: string;
21
+ placement: CruiseExtensionPlacement;
22
+ lifecycle: CruiseExtensionLifecycle;
23
+ quantity?: number;
24
+ metadata?: Record<string, unknown>;
25
+ }
26
+ export interface CruiseExtensionExtra {
27
+ kind: typeof CRUISE_EXTENSION_METADATA_KIND;
28
+ productId: string;
29
+ targetKind: CruiseExtensionTargetKind;
30
+ targetId: string;
31
+ placement: CruiseExtensionPlacement;
32
+ quantity: number;
33
+ metadata: Record<string, unknown>;
34
+ }
35
+ export type CruiseExtensionRepresentation = {
36
+ mode: "nested_extra";
37
+ extra: CruiseExtensionExtra;
38
+ } | {
39
+ mode: "sibling_component";
40
+ component: CreateTripComponentInput;
41
+ };
42
+ export declare function cruiseExtensionLinkKey(targetKind: CruiseExtensionTargetKind): string;
43
+ export declare function createCruiseExtensionLinkCommand(input: CruiseExtensionLinkInput): CruiseExtensionLinkCommand;
44
+ export declare function createCruiseExtensionExtra(selection: CruiseExtensionSelection): CruiseExtensionExtra;
45
+ export declare function createCruiseExtensionComponent(envelopeId: string, selection: CruiseExtensionSelection, sequence?: number): CreateTripComponentInput;
46
+ export declare function representCruiseExtensionSelection(envelopeId: string, selection: CruiseExtensionSelection, sequence?: number): CruiseExtensionRepresentation;
47
+ export declare function groupCruiseExtensionLinksByProduct(links: CruiseExtensionLinkInput[]): Map<string, CruiseExtensionLinkInput[]>;
48
+ //# sourceMappingURL=cruise-extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cruise-extension.d.ts","sourceRoot":"","sources":["../src/cruise-extension.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AAE/D,eAAO,MAAM,8BAA8B,qBAAqB,CAAA;AAEhE,MAAM,MAAM,yBAAyB,GAAG,QAAQ,GAAG,gBAAgB,CAAA;AACnE,MAAM,MAAM,wBAAwB,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;AAChE,MAAM,MAAM,wBAAwB,GAAG,iBAAiB,GAAG,uBAAuB,CAAA;AAElF,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,EAAE,MAAM,CAAA;IAC1B,UAAU,EAAE,yBAAyB,CAAA;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,EAAE,MAAM,CAAA;IAC1B,UAAU,EAAE,yBAAyB,CAAA;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,wBAAwB,CAAA;IACnC,SAAS,EAAE,wBAAwB,CAAA;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,OAAO,8BAA8B,CAAA;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,yBAAyB,CAAA;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,wBAAwB,CAAA;IACnC,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAClC;AAED,MAAM,MAAM,6BAA6B,GACrC;IACE,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,EAAE,oBAAoB,CAAA;CAC5B,GACD;IACE,IAAI,EAAE,mBAAmB,CAAA;IACzB,SAAS,EAAE,wBAAwB,CAAA;CACpC,CAAA;AAEL,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,yBAAyB,GAAG,MAAM,CAIpF;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,wBAAwB,GAC9B,0BAA0B,CAM5B;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,wBAAwB,GAClC,oBAAoB,CAUtB;AAED,wBAAgB,8BAA8B,CAC5C,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,wBAAwB,EACnC,QAAQ,SAAI,GACX,wBAAwB,CAoB1B;AAED,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,wBAAwB,EACnC,QAAQ,SAAI,GACX,6BAA6B,CAY/B;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,wBAAwB,EAAE,GAChC,GAAG,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAQzC"}
@@ -0,0 +1,66 @@
1
+ export const CRUISE_EXTENSION_METADATA_KIND = "cruise_extension";
2
+ export function cruiseExtensionLinkKey(targetKind) {
3
+ return targetKind === "cruise"
4
+ ? "cruiseProductExtensionLink"
5
+ : "cruiseSailingProductExtensionLink";
6
+ }
7
+ export function createCruiseExtensionLinkCommand(input) {
8
+ return {
9
+ linkKey: input.linkKey ?? cruiseExtensionLinkKey(input.targetKind),
10
+ leftId: input.targetId,
11
+ rightId: input.extensionProductId,
12
+ };
13
+ }
14
+ export function createCruiseExtensionExtra(selection) {
15
+ return {
16
+ kind: CRUISE_EXTENSION_METADATA_KIND,
17
+ productId: selection.extensionProductId,
18
+ targetKind: selection.targetKind,
19
+ targetId: selection.targetId,
20
+ placement: selection.placement,
21
+ quantity: selection.quantity ?? 1,
22
+ metadata: selection.metadata ?? {},
23
+ };
24
+ }
25
+ export function createCruiseExtensionComponent(envelopeId, selection, sequence = 0) {
26
+ return {
27
+ envelopeId,
28
+ sequence,
29
+ kind: "catalog_booking",
30
+ catalogRef: {
31
+ entityModule: "products",
32
+ entityId: selection.extensionProductId,
33
+ sourceKind: "owned",
34
+ },
35
+ metadata: {
36
+ kind: CRUISE_EXTENSION_METADATA_KIND,
37
+ targetKind: selection.targetKind,
38
+ targetId: selection.targetId,
39
+ placement: selection.placement,
40
+ lifecycle: selection.lifecycle,
41
+ quantity: selection.quantity ?? 1,
42
+ ...(selection.metadata ?? {}),
43
+ },
44
+ };
45
+ }
46
+ export function representCruiseExtensionSelection(envelopeId, selection, sequence = 0) {
47
+ if (selection.lifecycle === "dependent_extra") {
48
+ return {
49
+ mode: "nested_extra",
50
+ extra: createCruiseExtensionExtra(selection),
51
+ };
52
+ }
53
+ return {
54
+ mode: "sibling_component",
55
+ component: createCruiseExtensionComponent(envelopeId, selection, sequence),
56
+ };
57
+ }
58
+ export function groupCruiseExtensionLinksByProduct(links) {
59
+ const grouped = new Map();
60
+ for (const link of links) {
61
+ const existing = grouped.get(link.extensionProductId) ?? [];
62
+ existing.push(link);
63
+ grouped.set(link.extensionProductId, existing);
64
+ }
65
+ return grouped;
66
+ }
@@ -0,0 +1,21 @@
1
+ import type { Module } from "@voyantjs/core";
2
+ import type { HonoModule } from "@voyantjs/hono/module";
3
+ import { type TravelComposerRoutesOptions } from "./routes.js";
4
+ export { type CatalogComponentBookingDraftOverrides, isCatalogBackedTripComponent, toBookingDraftV1, } from "./catalog-component-adapter.js";
5
+ export { CRUISE_EXTENSION_METADATA_KIND, type CruiseExtensionExtra, type CruiseExtensionLifecycle, type CruiseExtensionLinkCommand, type CruiseExtensionLinkInput, type CruiseExtensionPlacement, type CruiseExtensionRepresentation, type CruiseExtensionSelection, type CruiseExtensionTargetKind, createCruiseExtensionComponent, createCruiseExtensionExtra, createCruiseExtensionLinkCommand, cruiseExtensionLinkKey, groupCruiseExtensionLinksByProduct, representCruiseExtensionSelection, } from "./cruise-extension.js";
6
+ export type { TravelComposerRoutes, TravelComposerRoutesOptions } from "./routes.js";
7
+ export { createTravelComposerRoutes } from "./routes.js";
8
+ export declare const travelComposerModule: Module;
9
+ export declare const travelComposerHonoModule: HonoModule;
10
+ export interface TravelComposerHonoModuleOptions extends TravelComposerRoutesOptions {
11
+ publicRoutes?: boolean;
12
+ }
13
+ export declare function createTravelComposerHonoModule(options?: TravelComposerHonoModuleOptions): HonoModule;
14
+ export { type CreateTripArgs, createTripTool, type PriceTripArgs, priceTripTool, type ReserveTripArgs, type ReviseTripArgs, reserveTripTool, reviseTripTool, type TravelComposerMcpServices, travelComposerMcpTools, } from "./mcp-tools.js";
15
+ export { travelComposerRoutes } from "./routes.js";
16
+ export type { NewTripComponent, NewTripComponentEvent, NewTripEnvelope, TripComponent, TripComponentEvent, TripComponentPricingSnapshot, TripComponentTaxLineSnapshot, TripEnvelope, TripEnvelopePricingSnapshot, } from "./schema.js";
17
+ export { tripComponentEvents, tripComponentEventTypeEnum, tripComponentKindEnum, tripComponentStatusEnum, tripComponents, tripEnvelopeStatusEnum, tripEnvelopes, } from "./schema.js";
18
+ export { aggregateComponentPricing, applyQuoteToComponent, assertTripComponentCanBeReserved, assertTripComponentCanBeUpdated, assertTripComponentCanReceiveRefs, assertTripComponentCanStartCheckout, type CancelComponentInput, type CancelComponentResult, type CancelTripComponentsDeps, type CancelTripComponentsResult, type CatalogComponentQuoteInput, type CheckoutHandoffKind, type CompleteTripCheckoutInput, type CompleteTripCheckoutResult, type ComponentCancellationAction, type ComponentCancellationPreview, type ComponentCancellationPreviewInput, type ComponentCheckoutInput, type ComponentCheckoutResult, checkoutResultToComponentPatch, completeTripCheckout, hasCommittedComponentReference, type PreviewTripCancellationDeps, type PriceTripDeps, type PriceTripResult, pricingSnapshotFromBreakdown, type ReleaseReservedComponentInput, type ReleaseReservedComponentResult, type ReserveComponentInput, type ReserveComponentPreflightResult, type ReserveComponentPreflightStatus, type ReserveComponentResult, type ReserveTripDeps, type ReserveTripResult, reserveResultToComponentPatch, type StartCheckoutDeps, type StartCheckoutResult, type StartCheckoutTarget, type StartedTripComponentCheckout, shouldReplayCheckout, shouldReplayReserve, TravelComposerInvariantError, type Trip, type TripCancellationPreviewResult, type TripCheckoutInput, type TripCheckoutResult, type TripListResult, taxLinesFromBreakdown, travelComposerService, } from "./service.js";
19
+ export { assertTripTravelerPartyComplete, validateTripTravelerParty, } from "./traveler-party-validation.js";
20
+ export { type CancelTripComponentsInput, type CreateTripComponentBodyInput, type CreateTripComponentInput, type CreateTripEnvelopeInput, cancelTripComponentsSchema, catalogComponentReferenceSchema, committedComponentReferenceSchema, createTripComponentBodySchema, createTripComponentSchema, createTripEnvelopeSchema, isAllowedTripComponentStatusTransition, isTerminalTripComponentStatus, type ListTripsQuery, listTripsQuerySchema, type PreviewTripCancellationInput, type PriceTripInput, previewTripCancellationSchema, priceTripSchema, type ReserveTripInput, reorderTripComponentsSchema, reserveTripSchema, type StartTripCheckoutInput, startTripCheckoutSchema, type TravelComposerHealthCheck, type TravelComposerStatus, type TripComponentEventType, type TripComponentKind, type TripComponentStatus, type TripEnvelopeStatus, type TripsListSortDir, type TripsListSortField, travelComposerHealthCheckSchema, travelComposerStatusSchema, tripComponentEventTypeSchema, tripComponentKindSchema, tripComponentPricingSnapshotSchema, tripComponentStatusSchema, tripComponentStatusTransitionSchema, tripComponentTaxLineSchema, tripEnvelopePricingSnapshotSchema, tripEnvelopeStatusSchema, tripsListSortDirSchema, tripsListSortFieldSchema, type UpdateTripComponentInput, updateTripComponentRefsSchema, updateTripComponentSchema, updateTripEnvelopeSchema, } from "./validation.js";
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ import { createTravelComposerRoutes, travelComposerRoutes, } from "./routes.js";
2
+ export { isCatalogBackedTripComponent, toBookingDraftV1, } from "./catalog-component-adapter.js";
3
+ export { CRUISE_EXTENSION_METADATA_KIND, createCruiseExtensionComponent, createCruiseExtensionExtra, createCruiseExtensionLinkCommand, cruiseExtensionLinkKey, groupCruiseExtensionLinksByProduct, representCruiseExtensionSelection, } from "./cruise-extension.js";
4
+ export { createTravelComposerRoutes } from "./routes.js";
5
+ export const travelComposerModule = {
6
+ name: "travel-composer",
7
+ };
8
+ export const travelComposerHonoModule = {
9
+ module: travelComposerModule,
10
+ adminRoutes: travelComposerRoutes,
11
+ };
12
+ export function createTravelComposerHonoModule(options = {}) {
13
+ const { publicRoutes = false, ...routeOptions } = options;
14
+ const routes = createTravelComposerRoutes({ ...routeOptions, surface: "admin" });
15
+ const honoModule = {
16
+ module: travelComposerModule,
17
+ adminRoutes: routes,
18
+ };
19
+ if (publicRoutes) {
20
+ honoModule.publicRoutes = createTravelComposerRoutes({ ...routeOptions, surface: "public" });
21
+ }
22
+ return honoModule;
23
+ }
24
+ export { createTripTool, priceTripTool, reserveTripTool, reviseTripTool, travelComposerMcpTools, } from "./mcp-tools.js";
25
+ export { travelComposerRoutes } from "./routes.js";
26
+ export { tripComponentEvents, tripComponentEventTypeEnum, tripComponentKindEnum, tripComponentStatusEnum, tripComponents, tripEnvelopeStatusEnum, tripEnvelopes, } from "./schema.js";
27
+ export { aggregateComponentPricing, applyQuoteToComponent, assertTripComponentCanBeReserved, assertTripComponentCanBeUpdated, assertTripComponentCanReceiveRefs, assertTripComponentCanStartCheckout, checkoutResultToComponentPatch, completeTripCheckout, hasCommittedComponentReference, pricingSnapshotFromBreakdown, reserveResultToComponentPatch, shouldReplayCheckout, shouldReplayReserve, TravelComposerInvariantError, taxLinesFromBreakdown, travelComposerService, } from "./service.js";
28
+ export { assertTripTravelerPartyComplete, validateTripTravelerParty, } from "./traveler-party-validation.js";
29
+ export { cancelTripComponentsSchema, catalogComponentReferenceSchema, committedComponentReferenceSchema, createTripComponentBodySchema, createTripComponentSchema, createTripEnvelopeSchema, isAllowedTripComponentStatusTransition, isTerminalTripComponentStatus, listTripsQuerySchema, previewTripCancellationSchema, priceTripSchema, reorderTripComponentsSchema, reserveTripSchema, startTripCheckoutSchema, travelComposerHealthCheckSchema, travelComposerStatusSchema, tripComponentEventTypeSchema, tripComponentKindSchema, tripComponentPricingSnapshotSchema, tripComponentStatusSchema, tripComponentStatusTransitionSchema, tripComponentTaxLineSchema, tripEnvelopePricingSnapshotSchema, tripEnvelopeStatusSchema, tripsListSortDirSchema, tripsListSortFieldSchema, updateTripComponentRefsSchema, updateTripComponentSchema, updateTripEnvelopeSchema, } from "./validation.js";
@@ -0,0 +1,157 @@
1
+ import type { McpToolDefinition, McpToolResult } from "@voyantjs/catalog-mcp";
2
+ import { z } from "zod";
3
+ import type { TripComponent } from "./schema.js";
4
+ import type { PriceTripResult, ReserveTripResult, Trip } from "./service.js";
5
+ import { type createTripComponentSchema, createTripEnvelopeSchema, priceTripSchema, reserveTripSchema } from "./validation.js";
6
+ export interface TravelComposerMcpServices {
7
+ createTrip(input: z.infer<typeof createTripEnvelopeSchema>): Promise<Trip>;
8
+ addComponent(input: z.infer<typeof createTripComponentSchema>): Promise<TripComponent>;
9
+ removeComponent?(componentId: string): Promise<TripComponent | null>;
10
+ priceTrip(input: z.infer<typeof priceTripSchema>): Promise<PriceTripResult>;
11
+ reserveTrip(input: z.infer<typeof reserveTripSchema>): Promise<ReserveTripResult>;
12
+ }
13
+ declare const createTripArgs: z.ZodObject<{
14
+ title: z.ZodOptional<z.ZodString>;
15
+ description: z.ZodOptional<z.ZodString>;
16
+ travelerParty: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
17
+ constraints: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
18
+ createdBy: z.ZodOptional<z.ZodString>;
19
+ components: z.ZodDefault<z.ZodArray<z.ZodObject<{
20
+ description: z.ZodOptional<z.ZodString>;
21
+ sequence: z.ZodDefault<z.ZodNumber>;
22
+ kind: z.ZodEnum<{
23
+ catalog_booking: "catalog_booking";
24
+ manual_placeholder: "manual_placeholder";
25
+ flight_placeholder: "flight_placeholder";
26
+ flight_order: "flight_order";
27
+ external_order: "external_order";
28
+ }>;
29
+ metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
30
+ catalogRef: z.ZodOptional<z.ZodObject<{
31
+ entityModule: z.ZodString;
32
+ entityId: z.ZodString;
33
+ sourceKind: z.ZodString;
34
+ sourceConnectionId: z.ZodOptional<z.ZodString>;
35
+ sourceRef: z.ZodOptional<z.ZodString>;
36
+ }, z.core.$strip>>;
37
+ estimatedPricing: z.ZodOptional<z.ZodObject<{
38
+ currency: z.ZodString;
39
+ subtotalAmountCents: z.ZodNumber;
40
+ taxAmountCents: z.ZodNumber;
41
+ totalAmountCents: z.ZodNumber;
42
+ priceExpiresAt: z.ZodOptional<z.ZodString>;
43
+ warnings: z.ZodOptional<z.ZodArray<z.ZodString>>;
44
+ }, z.core.$strip>>;
45
+ }, z.core.$strict>>>;
46
+ }, z.core.$strip>;
47
+ export type CreateTripArgs = z.infer<typeof createTripArgs>;
48
+ export declare const createTripTool: McpToolDefinition<CreateTripArgs, McpToolResult>;
49
+ declare const reviseTripArgs: z.ZodObject<{
50
+ envelopeId: z.ZodString;
51
+ addComponents: z.ZodDefault<z.ZodArray<z.ZodObject<{
52
+ description: z.ZodOptional<z.ZodString>;
53
+ sequence: z.ZodDefault<z.ZodNumber>;
54
+ kind: z.ZodEnum<{
55
+ catalog_booking: "catalog_booking";
56
+ manual_placeholder: "manual_placeholder";
57
+ flight_placeholder: "flight_placeholder";
58
+ flight_order: "flight_order";
59
+ external_order: "external_order";
60
+ }>;
61
+ metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
62
+ catalogRef: z.ZodOptional<z.ZodObject<{
63
+ entityModule: z.ZodString;
64
+ entityId: z.ZodString;
65
+ sourceKind: z.ZodString;
66
+ sourceConnectionId: z.ZodOptional<z.ZodString>;
67
+ sourceRef: z.ZodOptional<z.ZodString>;
68
+ }, z.core.$strip>>;
69
+ estimatedPricing: z.ZodOptional<z.ZodObject<{
70
+ currency: z.ZodString;
71
+ subtotalAmountCents: z.ZodNumber;
72
+ taxAmountCents: z.ZodNumber;
73
+ totalAmountCents: z.ZodNumber;
74
+ priceExpiresAt: z.ZodOptional<z.ZodString>;
75
+ warnings: z.ZodOptional<z.ZodArray<z.ZodString>>;
76
+ }, z.core.$strip>>;
77
+ }, z.core.$strict>>>;
78
+ removeComponentIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
79
+ }, z.core.$strip>;
80
+ export type ReviseTripArgs = z.infer<typeof reviseTripArgs>;
81
+ export declare const reviseTripTool: McpToolDefinition<ReviseTripArgs, McpToolResult>;
82
+ export type PriceTripArgs = z.infer<typeof priceTripSchema>;
83
+ export declare const priceTripTool: McpToolDefinition<PriceTripArgs, McpToolResult>;
84
+ export type ReserveTripArgs = z.infer<typeof reserveTripSchema>;
85
+ export declare const reserveTripTool: McpToolDefinition<ReserveTripArgs, McpToolResult>;
86
+ export declare const travelComposerMcpTools: readonly [McpToolDefinition<{
87
+ travelerParty: Record<string, unknown>;
88
+ constraints: Record<string, unknown>;
89
+ components: {
90
+ sequence: number;
91
+ kind: "catalog_booking" | "manual_placeholder" | "flight_placeholder" | "flight_order" | "external_order";
92
+ metadata: Record<string, unknown>;
93
+ description?: string | undefined;
94
+ catalogRef?: {
95
+ entityModule: string;
96
+ entityId: string;
97
+ sourceKind: string;
98
+ sourceConnectionId?: string | undefined;
99
+ sourceRef?: string | undefined;
100
+ } | undefined;
101
+ estimatedPricing?: {
102
+ currency: string;
103
+ subtotalAmountCents: number;
104
+ taxAmountCents: number;
105
+ totalAmountCents: number;
106
+ priceExpiresAt?: string | undefined;
107
+ warnings?: string[] | undefined;
108
+ } | undefined;
109
+ }[];
110
+ title?: string | undefined;
111
+ description?: string | undefined;
112
+ createdBy?: string | undefined;
113
+ }, McpToolResult>, McpToolDefinition<{
114
+ envelopeId: string;
115
+ addComponents: {
116
+ sequence: number;
117
+ kind: "catalog_booking" | "manual_placeholder" | "flight_placeholder" | "flight_order" | "external_order";
118
+ metadata: Record<string, unknown>;
119
+ description?: string | undefined;
120
+ catalogRef?: {
121
+ entityModule: string;
122
+ entityId: string;
123
+ sourceKind: string;
124
+ sourceConnectionId?: string | undefined;
125
+ sourceRef?: string | undefined;
126
+ } | undefined;
127
+ estimatedPricing?: {
128
+ currency: string;
129
+ subtotalAmountCents: number;
130
+ taxAmountCents: number;
131
+ totalAmountCents: number;
132
+ priceExpiresAt?: string | undefined;
133
+ warnings?: string[] | undefined;
134
+ } | undefined;
135
+ }[];
136
+ removeComponentIds: string[];
137
+ }, McpToolResult>, McpToolDefinition<{
138
+ envelopeId: string;
139
+ scope: {
140
+ locale: string;
141
+ audience: "staff" | "customer" | "partner" | "supplier";
142
+ market: string;
143
+ currency?: string | undefined;
144
+ };
145
+ ttlMs?: number | undefined;
146
+ }, McpToolResult>, McpToolDefinition<{
147
+ envelopeId: string;
148
+ idempotencyKey?: string | undefined;
149
+ refreshScope?: {
150
+ locale: string;
151
+ audience: "staff" | "customer" | "partner" | "supplier";
152
+ market: string;
153
+ currency?: string | undefined;
154
+ } | undefined;
155
+ }, McpToolResult>];
156
+ export {};
157
+ //# sourceMappingURL=mcp-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tools.d.ts","sourceRoot":"","sources":["../src/mcp-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,iBAAiB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE7F,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC5E,OAAO,EAEL,KAAK,yBAAyB,EAC9B,wBAAwB,EACxB,eAAe,EACf,iBAAiB,EAClB,MAAM,iBAAiB,CAAA;AAExB,MAAM,WAAW,yBAAyB;IACxC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1E,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;IACtF,eAAe,CAAC,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAA;IACpE,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAC3E,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;CAClF;AAMD,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAElB,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D,eAAO,MAAM,cAAc,EAAE,iBAAiB,CAAC,cAAc,EAAE,aAAa,CAgC3E,CAAA;AAED,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIlB,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D,eAAO,MAAM,cAAc,EAAE,iBAAiB,CAAC,cAAc,EAAE,aAAa,CAmC3E,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAE3D,eAAO,MAAM,aAAa,EAAE,iBAAiB,CAAC,aAAa,EAAE,aAAa,CAYzE,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE/D,eAAO,MAAM,eAAe,EAAE,iBAAiB,CAAC,eAAe,EAAE,aAAa,CAY7E,CAAA;AAED,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAKzB,CAAA"}
@@ -0,0 +1,109 @@
1
+ import { McpToolError } from "@voyantjs/catalog-mcp";
2
+ import { z } from "zod";
3
+ import { createTripComponentBodySchema, createTripEnvelopeSchema, priceTripSchema, reserveTripSchema, } from "./validation.js";
4
+ const createTripArgs = createTripEnvelopeSchema.extend({
5
+ components: z.array(createTripComponentBodySchema).default([]),
6
+ });
7
+ export const createTripTool = {
8
+ name: "create_trip",
9
+ description: "Create a deterministic trip envelope and optional components for a composed itinerary. " +
10
+ "Use this before pricing or reserving a cross-vertical trip.",
11
+ inputSchema: createTripArgs,
12
+ async handler(args, rawContext) {
13
+ const context = rawContext;
14
+ const composer = requireTravelComposer(context);
15
+ const trip = await composer.createTrip({
16
+ title: args.title,
17
+ description: args.description,
18
+ travelerParty: args.travelerParty,
19
+ constraints: args.constraints,
20
+ createdBy: args.createdBy,
21
+ });
22
+ const components = [];
23
+ for (const component of args.components) {
24
+ components.push(await composer.addComponent({
25
+ ...component,
26
+ envelopeId: trip.envelope.id,
27
+ }));
28
+ }
29
+ return tripResult("Created trip", {
30
+ envelope: trip.envelope,
31
+ components,
32
+ });
33
+ },
34
+ };
35
+ const reviseTripArgs = z.object({
36
+ envelopeId: z.string().min(1),
37
+ addComponents: z.array(createTripComponentBodySchema).default([]),
38
+ removeComponentIds: z.array(z.string().min(1)).default([]),
39
+ });
40
+ export const reviseTripTool = {
41
+ name: "revise_trip",
42
+ description: "Revise a deterministic trip envelope by adding components or removing uncommitted components. " +
43
+ "This does not mutate committed bookings directly.",
44
+ inputSchema: reviseTripArgs,
45
+ async handler(args, rawContext) {
46
+ const context = rawContext;
47
+ const composer = requireTravelComposer(context);
48
+ const added = [];
49
+ const removed = [];
50
+ for (const component of args.addComponents) {
51
+ added.push(await composer.addComponent({ ...component, envelopeId: args.envelopeId }));
52
+ }
53
+ if (args.removeComponentIds.length > 0 && !composer.removeComponent) {
54
+ throw new McpToolError("Travel composer MCP service removeComponent is not configured.", "MISSING_SERVICE", { service: "travelComposer.removeComponent" });
55
+ }
56
+ for (const componentId of args.removeComponentIds) {
57
+ const result = await composer.removeComponent?.(componentId);
58
+ if (result)
59
+ removed.push(result);
60
+ }
61
+ return tripResult("Revised trip", {
62
+ envelopeId: args.envelopeId,
63
+ added,
64
+ removed,
65
+ });
66
+ },
67
+ };
68
+ export const priceTripTool = {
69
+ name: "price_trip",
70
+ description: "Price a deterministic trip through the travel composer. Returns aggregate totals, " +
71
+ "component statuses, warnings, failures, and quote expiry data.",
72
+ inputSchema: priceTripSchema,
73
+ async handler(args, rawContext) {
74
+ const context = rawContext;
75
+ const composer = requireTravelComposer(context);
76
+ const result = await composer.priceTrip(args);
77
+ return tripResult("Priced trip", result);
78
+ },
79
+ };
80
+ export const reserveTripTool = {
81
+ name: "reserve_trip",
82
+ description: "Reserve a priced trip through deterministic travel composer services. " +
83
+ "Partial failures return explicit compensation and staff-remediation state.",
84
+ inputSchema: reserveTripSchema,
85
+ async handler(args, rawContext) {
86
+ const context = rawContext;
87
+ const composer = requireTravelComposer(context);
88
+ const result = await composer.reserveTrip(args);
89
+ return tripResult("Reserved trip", result);
90
+ },
91
+ };
92
+ export const travelComposerMcpTools = [
93
+ createTripTool,
94
+ reviseTripTool,
95
+ priceTripTool,
96
+ reserveTripTool,
97
+ ];
98
+ function requireTravelComposer(context) {
99
+ if (!context.travelComposer) {
100
+ throw new McpToolError("MCP tool requires travel composer services to be wired into the context.", "MISSING_SERVICE", { service: "travelComposer" });
101
+ }
102
+ return context.travelComposer;
103
+ }
104
+ function tripResult(message, structuredContent) {
105
+ return {
106
+ content: [{ type: "text", text: message }],
107
+ structuredContent: structuredContent,
108
+ };
109
+ }