@voyantjs/flights 0.56.0 → 0.58.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.
@@ -0,0 +1,359 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { ancillaryRequestSchema, ancillaryResponseSchema, checkInRequestSchema, checkInResponseSchema, flightAdapterCapabilitiesSchema, flightAdapterContextSchema, flightBookRequestSchema, flightBookResponseSchema, flightCancelResponseSchema, flightGetOrderResponseSchema, flightModifyRequestSchema, flightModifyResponseSchema, flightOrdersListQuerySchema, flightOrdersListResponseSchema, flightPriceRequestSchema, flightPriceResponseSchema, flightRefundRequestSchema, flightRefundResponseSchema, flightSearchRequestSchema, flightSearchResponseSchema, flightVoidResponseSchema, moneySchema, seatMapRequestSchema, seatMapResponseSchema, seatSelectionRequestSchema, seatSelectionResponseSchema, ssrRequestSchema, ssrResponseSchema, } from "./schemas.js";
3
+ const typeChecks = [
4
+ true,
5
+ true,
6
+ true,
7
+ true,
8
+ true,
9
+ true,
10
+ true,
11
+ true,
12
+ true,
13
+ true,
14
+ true,
15
+ true,
16
+ true,
17
+ true,
18
+ true,
19
+ true,
20
+ true,
21
+ true,
22
+ true,
23
+ true,
24
+ true,
25
+ true,
26
+ true,
27
+ true,
28
+ true,
29
+ true,
30
+ true,
31
+ true,
32
+ true,
33
+ true,
34
+ true,
35
+ true,
36
+ true,
37
+ true,
38
+ true,
39
+ true,
40
+ true,
41
+ true,
42
+ true,
43
+ true,
44
+ true,
45
+ true,
46
+ true,
47
+ true,
48
+ true,
49
+ true,
50
+ true,
51
+ true,
52
+ ];
53
+ void typeChecks;
54
+ const money = { amount: "600.00", currency: "USD" };
55
+ const segment = {
56
+ segmentId: "seg_1",
57
+ carrierCode: "BA",
58
+ flightNumber: "177",
59
+ departure: { iataCode: "LHR", terminal: "5", at: "2026-10-15T11:00:00+00:00" },
60
+ arrival: { iataCode: "JFK", terminal: "8", at: "2026-10-15T14:00:00-04:00" },
61
+ aircraft: "777",
62
+ cabin: "economy",
63
+ providerData: { source: "fixture" },
64
+ };
65
+ const offer = {
66
+ offerId: "offer_1",
67
+ source: "test",
68
+ itineraries: [{ segments: [segment], duration: "PT8H" }],
69
+ fareBreakdowns: [
70
+ {
71
+ passengerType: "adult",
72
+ passengerCount: 1,
73
+ baseFare: { amount: "500.00", currency: "USD" },
74
+ taxes: { amount: "100.00", currency: "USD" },
75
+ total: money,
76
+ },
77
+ ],
78
+ totalPrice: money,
79
+ validatingCarrier: "BA",
80
+ expiresAt: "2026-10-01T11:00:00Z",
81
+ lastTicketingDate: "2026-10-02",
82
+ fareBundles: [
83
+ {
84
+ id: "standard",
85
+ label: "Standard",
86
+ tier: "standard",
87
+ priceDelta: { amount: "30.00", currency: "USD" },
88
+ inclusions: {
89
+ cabinBag: { included: true, weightKg: 8 },
90
+ seatSelection: "standard",
91
+ },
92
+ },
93
+ ],
94
+ };
95
+ const passenger = {
96
+ passengerId: "pax_1",
97
+ type: "adult",
98
+ firstName: "Ada",
99
+ lastName: "Lovelace",
100
+ dateOfBirth: "1980-01-01",
101
+ documents: [
102
+ {
103
+ type: "passport",
104
+ number: "123456789",
105
+ countryOfIssue: "GB",
106
+ expiryDate: "2030-01-01",
107
+ },
108
+ ],
109
+ };
110
+ const order = {
111
+ orderId: "order_1",
112
+ pnr: "ABC123",
113
+ status: "ticketed",
114
+ offer,
115
+ passengers: [passenger],
116
+ contact: { email: "ada@example.com" },
117
+ tickets: [{ ticketNumber: "1250000000001", passengerId: "pax_1", segmentIds: ["seg_1"] }],
118
+ totalPrice: money,
119
+ createdAt: "2026-10-01T10:00:00Z",
120
+ providerData: { locator: "ABC123" },
121
+ };
122
+ const ancillarySelection = {
123
+ baggage: [{ passengerId: "pax_1", sliceIndex: 0, optionId: "bag_20kg", quantity: 1 }],
124
+ seats: [{ passengerId: "pax_1", segmentId: "seg_1", seatNumber: "12A" }],
125
+ };
126
+ const seatMap = {
127
+ segmentId: "seg_1",
128
+ aircraft: "777",
129
+ cabin: "economy",
130
+ columnLayout: ["A", "B", "C", null, "D", "E", "F"],
131
+ rows: [
132
+ {
133
+ row: 12,
134
+ seats: [
135
+ {
136
+ seatNumber: "12A",
137
+ row: 12,
138
+ column: "A",
139
+ status: "available",
140
+ category: "standard",
141
+ window: true,
142
+ },
143
+ ],
144
+ },
145
+ ],
146
+ };
147
+ const logger = {
148
+ debug() { },
149
+ info() { },
150
+ warn() { },
151
+ error() { },
152
+ };
153
+ const roundTripCases = [
154
+ [
155
+ "flightSearchRequestSchema",
156
+ flightSearchRequestSchema,
157
+ {
158
+ slices: [{ origin: "LHR", destination: "JFK", departureDate: "2026-10-15" }],
159
+ passengers: { adults: 1 },
160
+ cabin: "economy",
161
+ },
162
+ ],
163
+ ["flightSearchResponseSchema", flightSearchResponseSchema, { offers: [offer] }],
164
+ ["flightPriceRequestSchema", flightPriceRequestSchema, { offerId: "offer_1", offer }],
165
+ ["flightPriceResponseSchema", flightPriceResponseSchema, { offer, valid: true }],
166
+ [
167
+ "flightBookRequestSchema",
168
+ flightBookRequestSchema,
169
+ {
170
+ offerId: "offer_1",
171
+ offer,
172
+ passengers: [passenger],
173
+ paymentIntent: { type: "hold" },
174
+ ancillaries: ancillarySelection,
175
+ },
176
+ ],
177
+ ["flightBookResponseSchema", flightBookResponseSchema, { order }],
178
+ ["flightGetOrderResponseSchema", flightGetOrderResponseSchema, { order }],
179
+ ["flightCancelResponseSchema", flightCancelResponseSchema, { order, refundedAmount: money }],
180
+ [
181
+ "flightOrdersListQuerySchema",
182
+ flightOrdersListQuerySchema,
183
+ { cursor: "next", limit: 20, status: ["ticketed"], search: "ABC" },
184
+ ],
185
+ [
186
+ "flightOrdersListResponseSchema",
187
+ flightOrdersListResponseSchema,
188
+ { orders: [order], pagination: { total: 1, hasMore: false } },
189
+ ],
190
+ ["ancillaryRequestSchema", ancillaryRequestSchema, { offerId: "offer_1", offer }],
191
+ [
192
+ "ancillaryResponseSchema",
193
+ ancillaryResponseSchema,
194
+ {
195
+ catalog: {
196
+ baggage: [{ id: "bag_20kg", label: "20kg bag", category: "checked", price: money }],
197
+ assistance: [{ id: "wchr", label: "Wheelchair", category: "wheelchair" }],
198
+ extras: [{ id: "priority", label: "Priority", category: "boarding", price: money }],
199
+ },
200
+ validUntil: "2026-10-01T11:00:00Z",
201
+ },
202
+ ],
203
+ ["seatMapRequestSchema", seatMapRequestSchema, { offerId: "offer_1", segmentId: "seg_1", offer }],
204
+ ["seatMapResponseSchema", seatMapResponseSchema, { seatMap }],
205
+ [
206
+ "seatSelectionRequestSchema",
207
+ seatSelectionRequestSchema,
208
+ {
209
+ orderId: "order_1",
210
+ selections: [{ passengerId: "pax_1", segmentId: "seg_1", seatNumber: "12A" }],
211
+ },
212
+ ],
213
+ [
214
+ "seatSelectionResponseSchema",
215
+ seatSelectionResponseSchema,
216
+ { order, selections: [{ passengerId: "pax_1", segmentId: "seg_1", seatNumber: "12A" }] },
217
+ ],
218
+ ["checkInRequestSchema", checkInRequestSchema, { orderId: "order_1", passengerIds: ["pax_1"] }],
219
+ [
220
+ "checkInResponseSchema",
221
+ checkInResponseSchema,
222
+ {
223
+ order,
224
+ status: "checked_in",
225
+ boardingPasses: [{ passengerId: "pax_1", segmentId: "seg_1", seatNumber: "12A" }],
226
+ },
227
+ ],
228
+ [
229
+ "flightModifyRequestSchema",
230
+ flightModifyRequestSchema,
231
+ { orderId: "order_1", ancillaries: ancillarySelection },
232
+ ],
233
+ [
234
+ "flightModifyResponseSchema",
235
+ flightModifyResponseSchema,
236
+ { order, priceDifference: { amount: "-25.00", currency: "USD" } },
237
+ ],
238
+ [
239
+ "flightRefundRequestSchema",
240
+ flightRefundRequestSchema,
241
+ { orderId: "order_1", reason: "customer_request" },
242
+ ],
243
+ ["flightRefundResponseSchema", flightRefundResponseSchema, { order, refundedAmount: money }],
244
+ [
245
+ "flightVoidResponseSchema",
246
+ flightVoidResponseSchema,
247
+ { order, voidedAt: "2026-10-01T11:00:00Z" },
248
+ ],
249
+ [
250
+ "ssrRequestSchema",
251
+ ssrRequestSchema,
252
+ { orderId: "order_1", code: "WCHR", passengerIds: ["pax_1"] },
253
+ ],
254
+ ["ssrResponseSchema", ssrResponseSchema, { order, status: "requested" }],
255
+ [
256
+ "flightAdapterContextSchema",
257
+ flightAdapterContextSchema,
258
+ { connectionId: "conn_1", logger, environment: "sandbox" },
259
+ ],
260
+ [
261
+ "flightAdapterCapabilitiesSchema",
262
+ flightAdapterCapabilitiesSchema,
263
+ { provider: "demo", declared: ["flight/holds"], maxSlicesPerSearch: 2 },
264
+ ],
265
+ ];
266
+ const invalidCases = [
267
+ ["moneySchema", moneySchema, { amount: 600, currency: "USD" }],
268
+ [
269
+ "flightSearchRequestSchema",
270
+ flightSearchRequestSchema,
271
+ { slices: [], passengers: { adults: -1 } },
272
+ ],
273
+ ["flightSearchResponseSchema", flightSearchResponseSchema, { offers: [{ totalPrice: money }] }],
274
+ ["flightPriceRequestSchema", flightPriceRequestSchema, { offerId: 123 }],
275
+ ["flightPriceResponseSchema", flightPriceResponseSchema, { offer, valid: "yes" }],
276
+ ["flightBookRequestSchema", flightBookRequestSchema, { offerId: "offer_1", passengers: [{}] }],
277
+ [
278
+ "flightBookResponseSchema",
279
+ flightBookResponseSchema,
280
+ { order: { ...order, status: "unknown" } },
281
+ ],
282
+ [
283
+ "flightGetOrderResponseSchema",
284
+ flightGetOrderResponseSchema,
285
+ { order: { ...order, totalPrice: { amount: "x", currency: "USD" } } },
286
+ ],
287
+ [
288
+ "flightCancelResponseSchema",
289
+ flightCancelResponseSchema,
290
+ { order, refundedAmount: { amount: "1.00", currency: "US" } },
291
+ ],
292
+ ["flightOrdersListQuerySchema", flightOrdersListQuerySchema, { limit: 0 }],
293
+ [
294
+ "flightOrdersListResponseSchema",
295
+ flightOrdersListResponseSchema,
296
+ { orders: [order], pagination: { total: -1, hasMore: false } },
297
+ ],
298
+ ["ancillaryRequestSchema", ancillaryRequestSchema, { offerId: 123 }],
299
+ [
300
+ "ancillaryResponseSchema",
301
+ ancillaryResponseSchema,
302
+ { catalog: { baggage: [], assistance: [] } },
303
+ ],
304
+ ["seatMapRequestSchema", seatMapRequestSchema, { offerId: "offer_1" }],
305
+ ["seatMapResponseSchema", seatMapResponseSchema, { seatMap: { ...seatMap, cabin: "sofa" } }],
306
+ [
307
+ "seatSelectionRequestSchema",
308
+ seatSelectionRequestSchema,
309
+ { orderId: "order_1", selections: [{ seatNumber: "12A" }] },
310
+ ],
311
+ [
312
+ "seatSelectionResponseSchema",
313
+ seatSelectionResponseSchema,
314
+ { order, selections: [{ passengerId: "pax_1" }] },
315
+ ],
316
+ ["checkInRequestSchema", checkInRequestSchema, { passengerIds: ["pax_1"] }],
317
+ ["checkInResponseSchema", checkInResponseSchema, { order, status: "done" }],
318
+ [
319
+ "flightModifyRequestSchema",
320
+ flightModifyRequestSchema,
321
+ { orderId: "order_1", reason: "vacation" },
322
+ ],
323
+ [
324
+ "flightModifyResponseSchema",
325
+ flightModifyResponseSchema,
326
+ { order, penalties: [{ amount: "1.00", currency: "US" }] },
327
+ ],
328
+ [
329
+ "flightRefundRequestSchema",
330
+ flightRefundRequestSchema,
331
+ { orderId: "order_1", reason: "changed_mind" },
332
+ ],
333
+ [
334
+ "flightRefundResponseSchema",
335
+ flightRefundResponseSchema,
336
+ { order, refundedAmount: { amount: "x", currency: "USD" } },
337
+ ],
338
+ ["flightVoidResponseSchema", flightVoidResponseSchema, { order }],
339
+ ["ssrRequestSchema", ssrRequestSchema, { orderId: "order_1", code: "NOPE" }],
340
+ ["ssrResponseSchema", ssrResponseSchema, { order, status: "done" }],
341
+ [
342
+ "flightAdapterCapabilitiesSchema",
343
+ flightAdapterCapabilitiesSchema,
344
+ { provider: "demo", declared: ["flight/nope"] },
345
+ ],
346
+ [
347
+ "flightAdapterContextSchema",
348
+ flightAdapterContextSchema,
349
+ { connectionId: "conn_1", logger: {} },
350
+ ],
351
+ ];
352
+ describe("flight contract schemas", () => {
353
+ it.each(roundTripCases)("parses %s fixtures without changing shape", (_name, schema, value) => {
354
+ expect(schema.parse(value)).toEqual(value);
355
+ });
356
+ it.each(invalidCases)("rejects invalid %s fixtures", (_name, schema, value) => {
357
+ expect(schema.safeParse(value).success).toBe(false);
358
+ });
359
+ });
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { type AdapterLogger, CAPABILITY_NOT_SUPPORTED, type FlightAdapterCapabilities, type FlightAdapterContext, type FlightAdapterEnvironment, type FlightBookResponse, type FlightCancelReason, type FlightCancelResponse, FlightCapabilityNotSupportedError, type FlightConnectorAdapter, type FlightGetOrderResponse, type FlightPriceRequest, type FlightPriceResponse, type FlightSearchResponse, requireCapability, } from "./contract/adapter.js";
2
+ export * from "./contract/schemas.js";
2
3
  export * from "./contract/types.js";
3
4
  export { type ConnectionResult, type ConnectionSearchStatus, type FanOutFlightSearchOptions, type FanOutFlightSearchResult, fanOutFlightSearch, type MergedFlightOffer, } from "./orchestration/fan-out.js";
4
5
  export { itineraryFingerprint } from "./orchestration/fingerprint.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,aAAa,EAClB,wBAAwB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,iCAAiC,EACjC,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,iBAAiB,GAClB,MAAM,uBAAuB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,kBAAkB,EAClB,KAAK,iBAAiB,GACvB,MAAM,4BAA4B,CAAA;AAEnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AAErE,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,WAAW,EACX,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,GAC3B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,oCAAoC,EACpC,KAAK,qCAAqC,EAC1C,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EACL,mCAAmC,EACnC,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,GAC/B,MAAM,8BAA8B,CAAA;AAErC,OAAO,EACL,KAAK,+BAA+B,EACpC,wBAAwB,GACzB,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,aAAa,EAClB,wBAAwB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,iCAAiC,EACjC,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,iBAAiB,GAClB,MAAM,uBAAuB,CAAA;AAC9B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,kBAAkB,EAClB,KAAK,iBAAiB,GACvB,MAAM,4BAA4B,CAAA;AAEnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AAErE,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,WAAW,EACX,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,GAC3B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,oCAAoC,EACpC,KAAK,qCAAqC,EAC1C,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EACL,mCAAmC,EACnC,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,GAC/B,MAAM,8BAA8B,CAAA;AAErC,OAAO,EACL,KAAK,+BAA+B,EACpC,wBAAwB,GACzB,MAAM,eAAe,CAAA"}
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // Flight contract types — offers, orders, segments, search, booking.
2
2
  // FlightConnectorAdapter contract.
3
3
  export { CAPABILITY_NOT_SUPPORTED, FlightCapabilityNotSupportedError, requireCapability, } from "./contract/adapter.js";
4
+ export * from "./contract/schemas.js";
4
5
  export * from "./contract/types.js";
5
6
  export { fanOutFlightSearch, } from "./orchestration/fan-out.js";
6
7
  // Orchestration — fingerprinting + multi-connection fan-out.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/flights",
3
- "version": "0.56.0",
3
+ "version": "0.58.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -19,6 +19,11 @@
19
19
  "import": "./dist/contract/adapter.js",
20
20
  "default": "./dist/contract/adapter.js"
21
21
  },
22
+ "./contract/schemas": {
23
+ "types": "./dist/contract/schemas.d.ts",
24
+ "import": "./dist/contract/schemas.js",
25
+ "default": "./dist/contract/schemas.js"
26
+ },
22
27
  "./orchestration/fingerprint": {
23
28
  "types": "./dist/orchestration/fingerprint.d.ts",
24
29
  "import": "./dist/orchestration/fingerprint.js",
@@ -58,8 +63,9 @@
58
63
  },
59
64
  "dependencies": {
60
65
  "drizzle-orm": "^0.45.2",
61
- "@voyantjs/db": "0.56.0",
62
- "@voyantjs/catalog": "0.56.0"
66
+ "zod": "^4.3.6",
67
+ "@voyantjs/db": "0.58.0",
68
+ "@voyantjs/catalog": "0.58.0"
63
69
  },
64
70
  "devDependencies": {
65
71
  "typescript": "^6.0.2",