@voyant-travel/trips 0.110.2

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 (63) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +38 -0
  3. package/dist/catalog-component-adapter.d.ts +16 -0
  4. package/dist/catalog-component-adapter.d.ts.map +1 -0
  5. package/dist/catalog-component-adapter.js +34 -0
  6. package/dist/cruise-extension.d.ts +48 -0
  7. package/dist/cruise-extension.d.ts.map +1 -0
  8. package/dist/cruise-extension.js +66 -0
  9. package/dist/index.d.ts +24 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +31 -0
  12. package/dist/mcp-contract.d.ts +79 -0
  13. package/dist/mcp-contract.d.ts.map +1 -0
  14. package/dist/mcp-contract.js +21 -0
  15. package/dist/mcp-registry.d.ts +48 -0
  16. package/dist/mcp-registry.d.ts.map +1 -0
  17. package/dist/mcp-registry.js +88 -0
  18. package/dist/mcp-tools.d.ts +157 -0
  19. package/dist/mcp-tools.d.ts.map +1 -0
  20. package/dist/mcp-tools.js +109 -0
  21. package/dist/routes.d.ts +2068 -0
  22. package/dist/routes.d.ts.map +1 -0
  23. package/dist/routes.js +280 -0
  24. package/dist/schema.d.ts +1897 -0
  25. package/dist/schema.d.ts.map +1 -0
  26. package/dist/schema.js +255 -0
  27. package/dist/service-cancellation.d.ts +6 -0
  28. package/dist/service-cancellation.d.ts.map +1 -0
  29. package/dist/service-cancellation.js +251 -0
  30. package/dist/service-checkout.d.ts +6 -0
  31. package/dist/service-checkout.d.ts.map +1 -0
  32. package/dist/service-checkout.js +328 -0
  33. package/dist/service-helpers.d.ts +17 -0
  34. package/dist/service-helpers.d.ts.map +1 -0
  35. package/dist/service-helpers.js +161 -0
  36. package/dist/service-internals.d.ts +11 -0
  37. package/dist/service-internals.d.ts.map +1 -0
  38. package/dist/service-internals.js +72 -0
  39. package/dist/service-pricing.d.ts +8 -0
  40. package/dist/service-pricing.d.ts.map +1 -0
  41. package/dist/service-pricing.js +142 -0
  42. package/dist/service-reservation.d.ts +5 -0
  43. package/dist/service-reservation.d.ts.map +1 -0
  44. package/dist/service-reservation.js +493 -0
  45. package/dist/service-snapshots.d.ts +8 -0
  46. package/dist/service-snapshots.d.ts.map +1 -0
  47. package/dist/service-snapshots.js +115 -0
  48. package/dist/service-trips.d.ts +14 -0
  49. package/dist/service-trips.d.ts.map +1 -0
  50. package/dist/service-trips.js +378 -0
  51. package/dist/service-types.d.ts +285 -0
  52. package/dist/service-types.d.ts.map +1 -0
  53. package/dist/service-types.js +6 -0
  54. package/dist/service.d.ts +38 -0
  55. package/dist/service.d.ts.map +1 -0
  56. package/dist/service.js +40 -0
  57. package/dist/traveler-party-validation.d.ts +3 -0
  58. package/dist/traveler-party-validation.d.ts.map +1 -0
  59. package/dist/traveler-party-validation.js +68 -0
  60. package/dist/validation.d.ts +449 -0
  61. package/dist/validation.d.ts.map +1 -0
  62. package/dist/validation.js +261 -0
  63. package/package.json +83 -0
@@ -0,0 +1,285 @@
1
+ import type { BookingDraftV1, QuoteResponseV1 } from "@voyant-travel/catalog/booking-engine";
2
+ import type { CatalogComponentBookingDraftOverrides } from "./catalog-component-adapter.js";
3
+ import type { TripComponent, TripEnvelope, TripReservationPlan } from "./schema.js";
4
+ import type { PriceTripInput, StartTripCheckoutInput, TripComponentStatus } from "./validation.js";
5
+ export interface Trip {
6
+ envelope: TripEnvelope;
7
+ components: TripComponent[];
8
+ }
9
+ export interface TripListResult {
10
+ data: Trip[];
11
+ total: number;
12
+ limit: number;
13
+ offset: number;
14
+ }
15
+ export interface PriceTripResult {
16
+ envelope: TripEnvelope;
17
+ components: TripComponent[];
18
+ pricing: {
19
+ currency: string;
20
+ subtotalAmountCents: number;
21
+ taxAmountCents: number;
22
+ totalAmountCents: number;
23
+ componentCount: number;
24
+ pricedComponentCount: number;
25
+ warnings?: string[];
26
+ };
27
+ warnings: string[];
28
+ failures: Array<{
29
+ componentId: string;
30
+ reason: string;
31
+ }>;
32
+ }
33
+ export interface CatalogComponentQuoteInput {
34
+ component: TripComponent;
35
+ bookingDraft: BookingDraftV1;
36
+ scope: PriceTripInput["scope"];
37
+ ttlMs?: number;
38
+ }
39
+ export interface PriceTripDeps {
40
+ quoteCatalogComponent: (input: CatalogComponentQuoteInput) => Promise<QuoteResponseV1>;
41
+ componentBookingDraftOverrides?: Record<string, CatalogComponentBookingDraftOverrides>;
42
+ }
43
+ export interface ReserveComponentInput {
44
+ envelope: TripEnvelope;
45
+ component: TripComponent;
46
+ reservationPlanId?: string | null;
47
+ }
48
+ export interface ReserveComponentResult {
49
+ status: "held" | "booked";
50
+ bookingId?: string;
51
+ bookingGroupId?: string;
52
+ orderId?: string;
53
+ paymentSessionId?: string;
54
+ providerRef?: string;
55
+ supplierRef?: string;
56
+ holdToken?: string;
57
+ holdExpiresAt?: string;
58
+ warnings?: string[];
59
+ }
60
+ export type ReserveComponentPreflightStatus = "ok" | "price_changed" | "unavailable" | "expired";
61
+ export interface ReserveComponentPreflightResult {
62
+ status: ReserveComponentPreflightStatus;
63
+ reason?: string;
64
+ warnings?: string[];
65
+ details?: Record<string, unknown>;
66
+ }
67
+ export interface ReleaseReservedComponentInput {
68
+ component: TripComponent;
69
+ reserveResult: ReserveComponentResult;
70
+ }
71
+ export interface ReleaseReservedComponentResult {
72
+ released: boolean;
73
+ reason?: string;
74
+ }
75
+ export type TripReservationPlanComponentKind = "catalog_backed" | "non_catalog";
76
+ export interface SubmitTripReservationPlanComponent {
77
+ componentId: string;
78
+ reservationKind: TripReservationPlanComponentKind;
79
+ component: TripComponent;
80
+ }
81
+ export interface SubmitTripReservationPlanInput {
82
+ reservationPlan: TripReservationPlan;
83
+ envelope: TripEnvelope;
84
+ components: SubmitTripReservationPlanComponent[];
85
+ idempotencyKey?: string | null;
86
+ }
87
+ export interface SubmitTripReservationPlanResult {
88
+ reservationPlanId: string;
89
+ status: "reserved" | "failed";
90
+ reserved: Array<{
91
+ componentId: string;
92
+ status: "held" | "booked";
93
+ result: ReserveComponentResult;
94
+ }>;
95
+ failures: Array<{
96
+ componentId: string;
97
+ reason: string;
98
+ code?: string;
99
+ details?: Record<string, unknown>;
100
+ }>;
101
+ compensations: Array<{
102
+ componentId: string;
103
+ status: "released" | "release_failed" | "release_not_configured";
104
+ reason?: string;
105
+ }>;
106
+ warnings: string[];
107
+ }
108
+ export interface ReserveTripDeps {
109
+ quoteCatalogComponentBeforeReserve?: (input: CatalogComponentQuoteInput) => Promise<QuoteResponseV1>;
110
+ validateNonCatalogComponentBeforeReserve?: (input: ReserveComponentInput) => Promise<ReserveComponentPreflightResult | null | undefined>;
111
+ submitReservationPlan: (input: SubmitTripReservationPlanInput) => Promise<SubmitTripReservationPlanResult>;
112
+ }
113
+ export interface ReserveTripResult {
114
+ envelope: TripEnvelope;
115
+ components: TripComponent[];
116
+ reservationPlanId?: string | null;
117
+ reserved: Array<{
118
+ componentId: string;
119
+ status: "held" | "booked";
120
+ }>;
121
+ failures: Array<{
122
+ componentId: string;
123
+ reason: string;
124
+ code?: string;
125
+ details?: Record<string, unknown>;
126
+ }>;
127
+ compensations: Array<{
128
+ componentId: string;
129
+ status: "released" | "release_failed" | "release_not_configured";
130
+ reason?: string;
131
+ }>;
132
+ warnings: string[];
133
+ }
134
+ export type CheckoutHandoffKind = "card_redirect" | "payment_session" | "bank_transfer_instructions" | "hold_placed" | "inquiry_received";
135
+ export interface ComponentCheckoutInput {
136
+ envelope: TripEnvelope;
137
+ component: TripComponent;
138
+ intent: StartTripCheckoutInput["intent"];
139
+ request: StartTripCheckoutInput["request"];
140
+ }
141
+ export interface ComponentCheckoutResult {
142
+ kind: CheckoutHandoffKind;
143
+ status?: "checkout_started" | "booked";
144
+ bookingId?: string;
145
+ bookingGroupId?: string;
146
+ orderId?: string;
147
+ paymentSessionId?: string;
148
+ providerRef?: string;
149
+ supplierRef?: string;
150
+ checkoutUrl?: string | null;
151
+ externalReference?: string | null;
152
+ bankTransferInstructions?: Record<string, unknown> | null;
153
+ expiresAt?: string | null;
154
+ warnings?: string[];
155
+ }
156
+ export interface TripCheckoutInput {
157
+ trip: Trip;
158
+ intent: StartTripCheckoutInput["intent"];
159
+ request: StartTripCheckoutInput["request"];
160
+ }
161
+ export interface TripCheckoutResult {
162
+ kind: CheckoutHandoffKind;
163
+ status?: "checkout_started" | "booked";
164
+ paymentSessionId?: string;
165
+ checkoutUrl?: string | null;
166
+ bankTransferInstructions?: Record<string, unknown> | null;
167
+ expiresAt?: string | null;
168
+ warnings?: string[];
169
+ }
170
+ export interface StartCheckoutDeps {
171
+ startTripCheckout?: (input: TripCheckoutInput) => Promise<TripCheckoutResult>;
172
+ startComponentCheckout: (input: ComponentCheckoutInput) => Promise<ComponentCheckoutResult>;
173
+ }
174
+ export interface StartedTripComponentCheckout {
175
+ componentId: string;
176
+ kind: CheckoutHandoffKind;
177
+ bookingId: string | null;
178
+ orderId: string | null;
179
+ paymentSessionId: string | null;
180
+ checkoutUrl: string | null;
181
+ bankTransferInstructions: Record<string, unknown> | null;
182
+ expiresAt: string | null;
183
+ }
184
+ export interface StartCheckoutTarget {
185
+ envelopeId: string;
186
+ status: "checkout_started";
187
+ currency: string;
188
+ totalAmountCents: number;
189
+ paymentSessionId: string | null;
190
+ checkoutUrl: string | null;
191
+ holdExpiresAt: string | null;
192
+ }
193
+ export interface StartCheckoutResult {
194
+ envelope: TripEnvelope;
195
+ components: TripComponent[];
196
+ target: StartCheckoutTarget;
197
+ componentCheckouts: StartedTripComponentCheckout[];
198
+ failures: Array<{
199
+ componentId: string;
200
+ reason: string;
201
+ }>;
202
+ warnings: string[];
203
+ }
204
+ export interface CompleteTripCheckoutInput {
205
+ envelopeId?: string;
206
+ paymentSessionId?: string;
207
+ paidAt?: string;
208
+ actorId?: string | null;
209
+ payload?: Record<string, unknown>;
210
+ }
211
+ export interface CompleteTripCheckoutResult {
212
+ envelope: TripEnvelope;
213
+ components: TripComponent[];
214
+ updatedComponentIds: string[];
215
+ alreadyCompleted: boolean;
216
+ }
217
+ export type ComponentCancellationAction = "cancel" | "no_op" | "staff_remediation";
218
+ export interface ComponentCancellationPreviewInput {
219
+ envelope: TripEnvelope;
220
+ component: TripComponent;
221
+ reason?: string;
222
+ requestedAt: Date;
223
+ request: Record<string, unknown>;
224
+ }
225
+ export interface ComponentCancellationPreview {
226
+ componentId: string;
227
+ action: ComponentCancellationAction;
228
+ currentStatus: TripComponentStatus;
229
+ staffActionRequired: boolean;
230
+ reason?: string;
231
+ refundAmountCents?: number;
232
+ refundCurrency?: string;
233
+ penaltyAmountCents?: number;
234
+ supplierCancellationDeadline?: string | null;
235
+ policySummary?: string | null;
236
+ snapshot?: Record<string, unknown>;
237
+ }
238
+ export interface PreviewTripCancellationDeps {
239
+ previewComponentCancellation?: (input: ComponentCancellationPreviewInput) => Promise<ComponentCancellationPreview>;
240
+ }
241
+ export interface TripCancellationPreviewResult {
242
+ envelope: TripEnvelope;
243
+ components: TripComponent[];
244
+ preview: {
245
+ envelopeId: string;
246
+ selectedComponentIds: string[];
247
+ currency: string | null;
248
+ estimatedRefundAmountCents: number;
249
+ estimatedPenaltyAmountCents: number;
250
+ staffActionRequired: boolean;
251
+ components: ComponentCancellationPreview[];
252
+ warnings: string[];
253
+ };
254
+ }
255
+ export interface CancelComponentInput extends ComponentCancellationPreviewInput {
256
+ preview: ComponentCancellationPreview;
257
+ }
258
+ export interface CancelComponentResult {
259
+ status: "cancelled" | "refused" | "failed";
260
+ refundAmountCents?: number;
261
+ refundCurrency?: string;
262
+ reason?: string;
263
+ snapshot?: Record<string, unknown>;
264
+ }
265
+ export interface CancelTripComponentsDeps extends PreviewTripCancellationDeps {
266
+ cancelComponent?: (input: CancelComponentInput) => Promise<CancelComponentResult>;
267
+ }
268
+ export interface CancelTripComponentsResult extends TripCancellationPreviewResult {
269
+ cancelled: Array<{
270
+ componentId: string;
271
+ status: "cancelled";
272
+ }>;
273
+ remediation: Array<{
274
+ componentId: string;
275
+ reason: string;
276
+ }>;
277
+ skipped: Array<{
278
+ componentId: string;
279
+ reason: string;
280
+ }>;
281
+ }
282
+ export declare class TripsInvariantError extends Error {
283
+ constructor(message: string);
284
+ }
285
+ //# sourceMappingURL=service-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-types.d.ts","sourceRoot":"","sources":["../src/service-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export class TripsInvariantError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = "TripsInvariantError";
5
+ }
6
+ }
@@ -0,0 +1,38 @@
1
+ import type { TripsStatus } from "./validation.js";
2
+ export { cancelComponents, previewCancellation } from "./service-cancellation.js";
3
+ export { completeTripCheckout, startCheckout } from "./service-checkout.js";
4
+ export { aggregateComponentPricing, assertTripComponentCanBeReserved, assertTripComponentCanBeUpdated, assertTripComponentCanReceiveRefs, assertTripComponentCanStartCheckout, checkoutResultToComponentPatch, hasCommittedComponentReference, pricingSnapshotFromBreakdown, reserveResultToComponentPatch, shouldReplayCheckout, shouldReplayReserve, taxLinesFromBreakdown, } from "./service-helpers.js";
5
+ export { applyQuoteToComponent, priceTrip } from "./service-pricing.js";
6
+ export { reserveTrip } from "./service-reservation.js";
7
+ export { buildTripSnapshotProposal, freezeTripSnapshot, getTripSnapshotById, listTripSnapshots, } from "./service-snapshots.js";
8
+ export { addComponent, createTrip, getTrip, listTrips, removeComponent, reorderComponents, updateComponent, updateComponentRefs, updateTrip, } from "./service-trips.js";
9
+ export type { CancelComponentInput, CancelComponentResult, CancelTripComponentsDeps, CancelTripComponentsResult, CatalogComponentQuoteInput, CheckoutHandoffKind, CompleteTripCheckoutInput, CompleteTripCheckoutResult, ComponentCancellationAction, ComponentCancellationPreview, ComponentCancellationPreviewInput, ComponentCheckoutInput, ComponentCheckoutResult, PreviewTripCancellationDeps, PriceTripDeps, PriceTripResult, ReleaseReservedComponentInput, ReleaseReservedComponentResult, ReserveComponentInput, ReserveComponentPreflightResult, ReserveComponentPreflightStatus, ReserveComponentResult, ReserveTripDeps, ReserveTripResult, StartCheckoutDeps, StartCheckoutResult, StartCheckoutTarget, StartedTripComponentCheckout, SubmitTripReservationPlanComponent, SubmitTripReservationPlanInput, SubmitTripReservationPlanResult, Trip, TripCancellationPreviewResult, TripCheckoutInput, TripCheckoutResult, TripListResult, TripReservationPlanComponentKind, } from "./service-types.js";
10
+ export { TripsInvariantError } from "./service-types.js";
11
+ import { cancelComponents, previewCancellation } from "./service-cancellation.js";
12
+ import { completeTripCheckout, startCheckout } from "./service-checkout.js";
13
+ import { priceTrip } from "./service-pricing.js";
14
+ import { reserveTrip } from "./service-reservation.js";
15
+ import { freezeTripSnapshot, getTripSnapshotById, listTripSnapshots } from "./service-snapshots.js";
16
+ import { addComponent, createTrip, getTrip, listTrips, removeComponent, reorderComponents, updateComponent, updateComponentRefs, updateTrip } from "./service-trips.js";
17
+ export declare const tripsService: {
18
+ getStatus(): TripsStatus;
19
+ createTrip: typeof createTrip;
20
+ getTrip: typeof getTrip;
21
+ listTrips: typeof listTrips;
22
+ updateTrip: typeof updateTrip;
23
+ addComponent: typeof addComponent;
24
+ updateComponent: typeof updateComponent;
25
+ updateComponentRefs: typeof updateComponentRefs;
26
+ removeComponent: typeof removeComponent;
27
+ reorderComponents: typeof reorderComponents;
28
+ priceTrip: typeof priceTrip;
29
+ reserveTrip: typeof reserveTrip;
30
+ freezeTripSnapshot: typeof freezeTripSnapshot;
31
+ getTripSnapshotById: typeof getTripSnapshotById;
32
+ listTripSnapshots: typeof listTripSnapshots;
33
+ startCheckout: typeof startCheckout;
34
+ completeTripCheckout: typeof completeTripCheckout;
35
+ previewCancellation: typeof previewCancellation;
36
+ cancelComponents: typeof cancelComponents;
37
+ };
38
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAElD,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AACjF,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,EACL,yBAAyB,EACzB,gCAAgC,EAChC,+BAA+B,EAC/B,iCAAiC,EACjC,mCAAmC,EACnC,8BAA8B,EAC9B,8BAA8B,EAC9B,4BAA4B,EAC5B,6BAA6B,EAC7B,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,YAAY,EACZ,UAAU,EACV,OAAO,EACP,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,UAAU,GACX,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EACV,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC1B,0BAA0B,EAC1B,mBAAmB,EACnB,yBAAyB,EACzB,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC5B,iCAAiC,EACjC,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,EAC3B,aAAa,EACb,eAAe,EACf,6BAA6B,EAC7B,8BAA8B,EAC9B,qBAAqB,EACrB,+BAA+B,EAC/B,+BAA+B,EAC/B,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,4BAA4B,EAC5B,kCAAkC,EAClC,8BAA8B,EAC9B,+BAA+B,EAC/B,IAAI,EACJ,6BAA6B,EAC7B,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,gCAAgC,GACjC,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAExD,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AACjF,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AACnG,OAAO,EACL,YAAY,EACZ,UAAU,EACV,OAAO,EACP,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,UAAU,EACX,MAAM,oBAAoB,CAAA;AAE3B,eAAO,MAAM,YAAY;iBACV,WAAW;;;;;;;;;;;;;;;;;;;CAwBzB,CAAA"}
@@ -0,0 +1,40 @@
1
+ export { cancelComponents, previewCancellation } from "./service-cancellation.js";
2
+ export { completeTripCheckout, startCheckout } from "./service-checkout.js";
3
+ export { aggregateComponentPricing, assertTripComponentCanBeReserved, assertTripComponentCanBeUpdated, assertTripComponentCanReceiveRefs, assertTripComponentCanStartCheckout, checkoutResultToComponentPatch, hasCommittedComponentReference, pricingSnapshotFromBreakdown, reserveResultToComponentPatch, shouldReplayCheckout, shouldReplayReserve, taxLinesFromBreakdown, } from "./service-helpers.js";
4
+ export { applyQuoteToComponent, priceTrip } from "./service-pricing.js";
5
+ export { reserveTrip } from "./service-reservation.js";
6
+ export { buildTripSnapshotProposal, freezeTripSnapshot, getTripSnapshotById, listTripSnapshots, } from "./service-snapshots.js";
7
+ export { addComponent, createTrip, getTrip, listTrips, removeComponent, reorderComponents, updateComponent, updateComponentRefs, updateTrip, } from "./service-trips.js";
8
+ export { TripsInvariantError } from "./service-types.js";
9
+ import { cancelComponents, previewCancellation } from "./service-cancellation.js";
10
+ import { completeTripCheckout, startCheckout } from "./service-checkout.js";
11
+ import { priceTrip } from "./service-pricing.js";
12
+ import { reserveTrip } from "./service-reservation.js";
13
+ import { freezeTripSnapshot, getTripSnapshotById, listTripSnapshots } from "./service-snapshots.js";
14
+ import { addComponent, createTrip, getTrip, listTrips, removeComponent, reorderComponents, updateComponent, updateComponentRefs, updateTrip, } from "./service-trips.js";
15
+ export const tripsService = {
16
+ getStatus() {
17
+ return {
18
+ module: "trips",
19
+ status: "scaffolded",
20
+ };
21
+ },
22
+ createTrip,
23
+ getTrip,
24
+ listTrips,
25
+ updateTrip,
26
+ addComponent,
27
+ updateComponent,
28
+ updateComponentRefs,
29
+ removeComponent,
30
+ reorderComponents,
31
+ priceTrip,
32
+ reserveTrip,
33
+ freezeTripSnapshot,
34
+ getTripSnapshotById,
35
+ listTripSnapshots,
36
+ startCheckout,
37
+ completeTripCheckout,
38
+ previewCancellation,
39
+ cancelComponents,
40
+ };
@@ -0,0 +1,3 @@
1
+ export declare function assertTripTravelerPartyComplete(travelerParty: Record<string, unknown>, context?: string): void;
2
+ export declare function validateTripTravelerParty(travelerParty: Record<string, unknown>): string[];
3
+ //# sourceMappingURL=traveler-party-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traveler-party-validation.d.ts","sourceRoot":"","sources":["../src/traveler-party-validation.ts"],"names":[],"mappings":"AAQA,wBAAgB,+BAA+B,CAC7C,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,OAAO,SAAS,GACf,IAAI,CAIN;AAED,wBAAgB,yBAAyB,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CA6C1F"}
@@ -0,0 +1,68 @@
1
+ import { TripsInvariantError } from "./service-types.js";
2
+ const placeholderEmails = new Set([
3
+ "noreply@example.com",
4
+ "tbd@example.com",
5
+ "traveler@example.com",
6
+ ]);
7
+ export function assertTripTravelerPartyComplete(travelerParty, context = "Trip") {
8
+ const errors = validateTripTravelerParty(travelerParty);
9
+ if (errors.length === 0)
10
+ return;
11
+ throw new TripsInvariantError(`${context} requires ${errors.join(", ")}`);
12
+ }
13
+ export function validateTripTravelerParty(travelerParty) {
14
+ const errors = [];
15
+ const billing = asRecord(travelerParty.billing);
16
+ const contact = asRecord(billing?.contact);
17
+ const billingEmail = stringValue(contact?.email);
18
+ const billingFirstName = stringValue(contact?.firstName);
19
+ const billingLastName = stringValue(contact?.lastName);
20
+ const billingPersonId = stringValue(billing?.personId);
21
+ const billingOrganizationId = stringValue(billing?.organizationId);
22
+ if (!billing) {
23
+ errors.push("billing information");
24
+ }
25
+ else {
26
+ if (!billingPersonId && !billingOrganizationId && (!billingFirstName || !billingLastName)) {
27
+ errors.push("a billing person, organization, or full billing contact name");
28
+ }
29
+ if (!isRealEmail(billingEmail)) {
30
+ errors.push("a real billing email");
31
+ }
32
+ }
33
+ const travelers = Array.isArray(travelerParty.travelers)
34
+ ? travelerParty.travelers
35
+ .map(asRecord)
36
+ .filter((traveler) => Boolean(traveler))
37
+ : [];
38
+ if (travelers.length === 0) {
39
+ errors.push("at least one traveler");
40
+ }
41
+ travelers.forEach((traveler, index) => {
42
+ const personId = stringValue(traveler.personId);
43
+ const firstName = stringValue(traveler.firstName);
44
+ const lastName = stringValue(traveler.lastName);
45
+ const email = stringValue(traveler.email);
46
+ if (!personId && (!firstName || !lastName)) {
47
+ errors.push(`traveler ${index + 1} name or person record`);
48
+ }
49
+ if (email && !isRealEmail(email)) {
50
+ errors.push(`traveler ${index + 1} real email`);
51
+ }
52
+ });
53
+ return errors;
54
+ }
55
+ function isRealEmail(value) {
56
+ if (!value)
57
+ return false;
58
+ const normalized = value.trim().toLowerCase();
59
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(normalized) && !placeholderEmails.has(normalized);
60
+ }
61
+ function asRecord(value) {
62
+ return value && typeof value === "object" && !Array.isArray(value)
63
+ ? value
64
+ : null;
65
+ }
66
+ function stringValue(value) {
67
+ return typeof value === "string" && value.trim() ? value.trim() : null;
68
+ }