Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduces API v2 #952

Merged
merged 4 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@duffel/api",
"version": "2.14.4",
"version": "3.0.0",
"description": "Javascript client library for the Duffel API",
"main": "dist/index.js",
"module": "dist/index.es.js",
Expand Down
4 changes: 3 additions & 1 deletion src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export class DuffelError extends Error {
}
}

const CURRENT_API_VERSION = 'v2'

export class Client {
private token: string
private basePath: string
Expand All @@ -46,7 +48,7 @@ export class Client {
constructor({ token, basePath, apiVersion, debug, source }: Config) {
this.token = token
this.basePath = basePath || 'https://api.duffel.com'
this.apiVersion = apiVersion || 'v1'
this.apiVersion = apiVersion || CURRENT_API_VERSION
this.debug = debug
this.source = source
}
Expand Down
4 changes: 2 additions & 2 deletions src/Stays/Stays.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('Stays', () => {
},
check_in_date: '2023-10-20',
check_out_date: '2023-10-24',
adults: 2,
guests: [{ type: 'adult' }, { type: 'adult' }, { type: 'child', age: 5 }],
rooms: 1,
}

Expand All @@ -44,7 +44,7 @@ describe('Stays', () => {
},
check_in_date: '2023-10-20',
check_out_date: '2023-10-24',
adults: 2,
guests: [{ type: 'adult' }, { type: 'adult' }, { type: 'child', age: 5 }],
rooms: 1,
}

Expand Down
43 changes: 8 additions & 35 deletions src/Stays/StaysTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,6 @@ export interface StaysRate {
*/
total_currency: string

/**
Deprecated. Refer to available_payment_methods instead.
*/
payment_method: StaysPaymentType

/**
* The methods available for payment of this rate.

Expand Down Expand Up @@ -335,20 +330,10 @@ export interface StaysAccommodation {
} | null

/**
* Deprecated: Instructions to access the accommodation in the booking
* The key collection details for the accommodation.
*/
key_collection: StaysBookingKeyCollection | null

/**
* The total currency for the cheapest rate for this accommodation, as an ISO 4217 currency code. If rooms data is available, this is equivalent to the cheapest rate for the cheapest room.
*/
cheapest_rate_currency: string

/**
* The total amount for the cheapest rate for this accommodation. If rooms data is available, this is equivalent to the cheapest rate for the cheapest room.
*/
cheapest_rate_total_amount: string

/**
* The accommodation’s description
*/
Expand Down Expand Up @@ -418,7 +403,7 @@ export interface StaysQuote {
/**
* The id of the stay quote.
*
* Example: "quo_0000AS0NZdKjjnnHZmSUbI"
* @example: "quo_0000AS0NZdKjjnnHZmSUbI"
*/
id: string

Expand Down Expand Up @@ -526,17 +511,6 @@ export interface StaysQuote {
*/
supported_loyalty_programme: StaysLoyaltyProgrammeReference | null

/**
* A client key to authenticate with Duffel's Card Component when creating a tokenised card.
* This value will be `null` if your organisation does not have this feature enabled,
*/
card_component_key: string | null

/*
* The number of adult guests this quote is for.
*/
adults: number

/*
* The number of rooms this quote is for
*/
Expand Down Expand Up @@ -644,14 +618,12 @@ type Child = { type: 'child'; age: number }

export type Guest = Adult | Child

type OccupancyCriteria = {
rooms: number
} & ({ adults: number } | { guests: Array<Guest> })

type CommonStaysSearchParams = {
interface CommonStaysSearchParams {
check_in_date: string
check_out_date: string
} & OccupancyCriteria
rooms: number
guests: Array<Guest>
}

export type LocationParams = {
radius: number
Expand Down Expand Up @@ -679,9 +651,10 @@ export interface StaysSearchResult {
check_in_date: string
check_out_date: string
accommodation: StaysAccommodation
adults: number
rooms: number
guests: Array<Guest>
cheapest_rate_total_amount: string
cheapest_rate_currency: string
}

export interface StaysLoyaltyProgramme {
Expand Down
9 changes: 2 additions & 7 deletions src/Stays/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export const MOCK_ACCOMMODATION: StaysAccommodation = {
fee_amount: '40.00',
cancellation_timeline: [],
board_type: 'room_only',
payment_method: 'balance', // Deprecated. Refer to available_payment_methods instead.
available_payment_methods: ['balance'],
quantity_available: 1,
supported_loyalty_programme: null,
Expand Down Expand Up @@ -83,7 +82,6 @@ export const MOCK_ACCOMMODATION: StaysAccommodation = {
fee_amount: '40.00',
cancellation_timeline: [],
board_type: 'room_only',
payment_method: 'card', // Deprecated. Refer to available_payment_methods instead.
available_payment_methods: ['card'],
quantity_available: 1,
supported_loyalty_programme: 'duffel_hotel_group_rewards',
Expand Down Expand Up @@ -145,8 +143,6 @@ export const MOCK_ACCOMMODATION: StaysAccommodation = {
key_collection: {
instructions: 'Key is at the property. Collect from the lock box.',
},
cheapest_rate_total_amount: '799.00',
cheapest_rate_currency: 'GBP',
chain: {
name: 'The Ritz-Carlton',
},
Expand All @@ -158,9 +154,10 @@ export const MOCK_SEARCH_RESULT: StaysSearchResult = {
id: 'sta_something',
check_in_date: '2023-03-24',
check_out_date: '2023-03-28',
adults: 2,
rooms: 1,
guests: [{ type: 'adult' }, { type: 'adult' }],
cheapest_rate_total_amount: '799.00',
cheapest_rate_currency: 'GBP',
}

export const MOCK_BOOKING: StaysBooking = {
Expand Down Expand Up @@ -221,8 +218,6 @@ export const MOCK_QUOTE: StaysQuote = {
due_at_accommodation_amount: null,
due_at_accommodation_currency: 'USD',
supported_loyalty_programme: 'duffel_hotel_group_rewards',
card_component_key: null,
adults: 2,
rooms: 1,
guests: [{ type: 'adult' }, { type: 'adult' }],
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ export const mockAirlineInitiatedChange: AirlineInitiatedChange = {
city_name: 'Barcelona',
city: null,
},
changeable: null,
},
],
order_id: 'ord_00009hthhsUZ8W4LxQgkjo',
Expand Down Expand Up @@ -250,7 +249,6 @@ export const mockAirlineInitiatedChange: AirlineInitiatedChange = {
city_name: 'Barcelona',
city: null,
},
changeable: false,
},
],
action_taken_at: null,
Expand Down
47 changes: 34 additions & 13 deletions src/booking/Offers/OfferTypes.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
import {
CabinClass,
FlightsConditions,
LoyaltyProgrammeAccount,
PassengerIdentityDocumentType,
Place,
PlaceType,
Aircraft,
Airline,
Airport,
PaginationMeta,
CabinClass,
CreateOfferRequestPassengerFareType,
DuffelPassengerType,
FlightsConditions,
LoyaltyProgrammeAccount,
OfferSliceConditions,
PaginationMeta,
Place,
PlaceType,
} from '../../types'

/**
* Each offer represents flights you can buy from an airline at a particular price that meet your search criteria.
* @link https://duffel.com/docs/api/offers/schema
*/
export interface Offer {
/**
* The types of identity documents that may be provided for the passengers when creating an order based on this offer.
* If this is `[]`, then you must not provide identity documents.
*/
allowed_passenger_identity_document_types: PassengerIdentityDocumentType[]

/**
* The services that can be booked along with the offer but are not included by default, for example an additional checked bag.
* This field is only returned in the Get single offer endpoint.
Expand Down Expand Up @@ -141,8 +135,29 @@ export interface Offer {
* Partial offers are only ever returned through the multi-step search flow.
*/
partial: boolean

/**
* A list of airline IATA codes whose loyalty programmes are supported when booking the offer.
* Loyalty programmes present within the offer passengers that are not present in this field shall be ignored at booking.
* If this is an empty list ([]), no loyalty programmes are supported for the offer and shall be ignored if provided.
* @example: ["AF","KL","DL"]
*/
supported_loyalty_programmes: string[]

/**
* The types of identity documents supported by the airline and may be provided for the
* passengers when creating an order based on this offer. Currently, possible types are `passport`,
* `tax_id`, `known_traveler_number`, and `passenger_redress_number`.
*/
supported_passenger_identity_document_types: OfferSupportedPassengerIdentityDocumentTypes[]
}

export type OfferSupportedPassengerIdentityDocumentTypes =
| 'passport'
| 'tax_id'
| 'known_traveler_number'
| 'passenger_redress_number'

export interface OfferAvailableServiceBaggageMetadata {
/**
* The maximum weight that the baggage can have in kilograms.
Expand Down Expand Up @@ -354,6 +369,12 @@ export interface OfferPassenger {
* Optionally providing one has been deprecated.
*/
id: string

/**
* The fare type of the passenger
* Example: "contract_bulk"
*/
fare_type: CreateOfferRequestPassengerFareType | null
igorp1 marked this conversation as resolved.
Show resolved Hide resolved
}

export interface OfferSlice {
Expand Down
4 changes: 3 additions & 1 deletion src/booking/Offers/mockOffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ export const mockOffer: Offer = {
airline_iata_code: 'BA',
},
],
fare_type: null,
},
],
passenger_identity_documents_required: false,
Expand Down Expand Up @@ -244,7 +245,8 @@ export const mockOffer: Offer = {
type: 'cancel_for_any_reason',
},
],
allowed_passenger_identity_document_types: ['passport'],
supported_passenger_identity_document_types: ['passport'],
supported_loyalty_programmes: [],
}

export const mockUpdatedOffer = {
Expand Down
4 changes: 3 additions & 1 deletion src/booking/Offers/mockPartialOffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ export const mockPartialOffer: Offer = {
airline_iata_code: 'BA',
},
],
fare_type: null,
},
],
passenger_identity_documents_required: false,
Expand Down Expand Up @@ -244,7 +245,8 @@ export const mockPartialOffer: Offer = {
type: 'cancel_for_any_reason',
},
],
allowed_passenger_identity_document_types: ['passport'],
supported_passenger_identity_document_types: ['passport'],
supported_loyalty_programmes: [],
}

export const mockUpdatedOffer = {
Expand Down
16 changes: 10 additions & 6 deletions src/booking/OrderCancellations/OrderCancellationsTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,19 @@ export interface OrderCancellation {
*/
order_id: string
/**
* The amount that will be returned to the original payment method if the order is cancelled, determined according to the fare conditions. This may be `0.00` if the fare is non-refundable. It will include the refund amount of the flights and the services booked.
* The amount that will be returned to the original payment method if the order is cancelled, determined according
* to the fare conditions. This may be 0.00 if the fare is non-refundable. It will include the refund amount
* of the flights and the services booked. This may be null in cases where the refund amount is unknown.
* This only applies in cases where we are unable to get a refund quote from the carrier.
*/
refund_amount: string
refund_amount: string | null
/**
* The currency of the `refund_amount`, as an [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code.
* It will match your organisation's billing currency unless you're using Duffel as an accredited IATA agent, in which case it will be in the currency provided by the airline (which will usually be based on the country where your IATA agency is registered).
* For pay later orders that are awaiting payment, the refund amount will always be 0.00.
* The currency of the refund_amount, as an ISO 4217 currency code.
* It will match your organisation's billing currency unless you’re using Duffel as an accredited IATA agent,
* in which case it will be in the currency provided by the airline (which will usually be based on the
* country where your IATA agency is registered). For hold orders that are awaiting payment, the refund amount will always be 0.00.
*/
refund_currency: string
refund_currency: string | null
/**
* Where the refund, once confirmed, will be sent. `card` is currently a restricted feature. `awaiting_payment` is for pay later orders where no payment has been made yet.
*/
Expand Down
26 changes: 14 additions & 12 deletions src/booking/Orders/OrdersTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,6 @@ export interface CreateOrderPassenger extends Omit<OrderPassenger, 'type'> {
* @example "+442080160509"
*/
phone_number: string

/**
* @deprecated This type is here just for the backward-compatibility until the field is officially removed from the API
*
* The type of the passenger
* @example "adult", "child", or "infant_without_seat"
*/
type?: DuffelPassengerType
}

export interface OrderSliceSegment {
Expand Down Expand Up @@ -289,10 +281,6 @@ export interface OrderSliceSegment {
}

export interface OrderSlice {
/**
* Whether this slice can be changed. This can only be true for paid orders.
*/
changeable: boolean | null
/**
* The conditions associated with this slice, describing the kinds of modifications you can make and any penalties that will apply to those modifications.
* This condition is applied only to this slice and to all the passengers associated with this order - for information at the order level (e.g. "what happens if I want to change all the slices?") refer to the `conditions` at the top level. If a particular kind of modification is allowed, you may not always be able to take action through the Duffel API. In some cases, you may need to contact the Duffel support team or the airline directly.
Expand Down Expand Up @@ -520,8 +508,22 @@ export interface Order {
* The airline-initiated changes for this order.
*/
airline_initiated_changes?: AirlineInitiatedChange[]

/**
* The available actions you can take on this order through our API.
* It's a list of zero or more of the following values:
*
* "cancel": You can cancel the order.
* "change": You can can change the order's slices.
* "update": You can update some of the order's fields.
*
* @example: ["cancel","update"]
*/
available_actions: OrderAvailableAction[]
}

export type OrderAvailableAction = 'cancel' | 'change' | 'update'

export interface CreateOrder {
/**
* The `id`s of the offers you want to book. You must specify an array containing exactly one selected offer.
Expand Down
Loading