Skip to content
Open
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
10 changes: 9 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ import {
AirlineInitiatedChanges,
} from './booking'
import { Client, Config, DuffelError as _DuffelError } from './Client'
import { Aircraft, Airlines, Airports } from './supportingResources'
import {
Aircraft,
Airlines,
Airports,
LoyaltyProgrammes,
} from './supportingResources'
import { Suggestions } from './Places/Suggestions'
import { Refunds } from './DuffelPayments/Refunds'
import { Sessions } from './Links'
Expand All @@ -32,6 +37,7 @@ export interface DuffelAPIClient {
airlines: Airlines
airports: Airports
batchOfferRequests: BatchOfferRequests
loyaltyProgrammes: LoyaltyProgrammes
offers: Offers
offerRequests: OfferRequests
orders: Orders
Expand All @@ -51,6 +57,7 @@ export class Duffel {
public airlines: Airlines
public airports: Airports
public links: Sessions
public loyaltyProgrammes: LoyaltyProgrammes
public batchOfferRequests: BatchOfferRequests
public offerRequests: OfferRequests
public offers: Offers
Expand Down Expand Up @@ -82,6 +89,7 @@ export class Duffel {
this.airports = new Airports(this.client)
this.airlineInitiatedChanges = new AirlineInitiatedChanges(this.client)
this.links = new Sessions(this.client)
this.loyaltyProgrammes = new LoyaltyProgrammes(this.client)
this.batchOfferRequests = new BatchOfferRequests(this.client)
this.offerRequests = new OfferRequests(this.client)
this.offers = new Offers(this.client)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import nock from 'nock'
import { Client } from '../../Client'
import { LoyaltyProgrammes } from './LoyaltyProgrammes'
import { mockLoyaltyProgramme } from './mockLoyaltyProgramme'

describe('loyaltyProgrammes', () => {
afterEach(() => {
nock.cleanAll()
})

test('should get a single loyalty programme', async () => {
nock(/(.*)/)
.get(`/air/loyalty_programmes/${mockLoyaltyProgramme.id}`)
.reply(200, { data: mockLoyaltyProgramme })

const response = await new LoyaltyProgrammes(
new Client({ token: 'mockToken' }),
).get(mockLoyaltyProgramme.id)
expect(response.data?.id).toBe(mockLoyaltyProgramme.id)
})

test('should get a page of loyalty programmes', async () => {
nock(/(.*)/)
.get(`/air/loyalty_programmes?limit=1`)
.reply(200, {
data: [mockLoyaltyProgramme],
meta: { limit: 1, before: null, after: null },
})

const response = await new LoyaltyProgrammes(
new Client({ token: 'mockToken' }),
).list({ limit: 1 })
expect(response.data).toHaveLength(1)
expect(response.data[0].id).toBe(mockLoyaltyProgramme.id)
})

test('should follow the pagination cursor across pages', async () => {
nock(/(.*)/)
.get(`/air/loyalty_programmes?limit=1`)
.reply(200, {
data: [mockLoyaltyProgramme],
meta: { limit: 1, before: null, after: 'cursor' },
})
nock(/(.*)/)
.get(`/air/loyalty_programmes?after=cursor&limit=1`)
.reply(200, {
data: [{ ...mockLoyaltyProgramme, id: 'loy_00001876aqC8c5umZmrRdt' }],
meta: { limit: 1, before: null, after: null },
})

const loyaltyProgrammes = new LoyaltyProgrammes(
new Client({ token: 'mockToken' }),
)
const firstPage = await loyaltyProgrammes.list({ limit: 1 })
expect(firstPage.meta?.after).toBe('cursor')
const secondPage = await loyaltyProgrammes.list({
limit: 1,
after: firstPage.meta?.after,
})
expect(secondPage.data[0].id).toBe('loy_00001876aqC8c5umZmrRdt')
expect(secondPage.meta?.after).toBeNull()
})
})
37 changes: 37 additions & 0 deletions src/supportingResources/LoyaltyProgrammes/LoyaltyProgrammes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Client } from '../../Client'
import { Resource } from '../../Resource'
import { DuffelResponse, LoyaltyProgramme, PaginationMeta } from '../../types'

/** Loyalty programmes are used to identify the frequent flyer programmes offered by airlines
* @class
* @link https://duffel.com/docs/api/loyalty-programmes
*/
export class LoyaltyProgrammes extends Resource {
/**
* Endpoint path
*/
path: string

constructor(client: Client) {
super(client)
this.path = 'air/loyalty_programmes'
}

/**
* Retrieves a loyalty programme by its ID
* @param {string} id - Duffel's unique identifier for the loyalty programme
* @link https://duffel.com/docs/api/loyalty-programmes/get-a-single-loyalty-programme
*/
public get = async (id: string): Promise<DuffelResponse<LoyaltyProgramme>> =>
this.request({ method: 'GET', path: `${this.path}/${id}` })

/**
* Retrieves a page of loyalty programmes. The results may be returned in any order.
* @param {Object} [options] - Pagination options (optional: limit, after, before)
* @link https://duffel.com/docs/api/loyalty-programmes/list-loyalty-programmes
*/
public list = (
options?: PaginationMeta,
): Promise<DuffelResponse<LoyaltyProgramme[]>> =>
this.request({ method: 'GET', path: this.path, params: options })
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Loyalty programmes are used to identify the frequent flyer programmes offered by airlines
* @link https://duffel.com/docs/api/loyalty-programmes/schema
*/
export interface LoyaltyProgramme {
/**
* Duffel's unique identifier for the loyalty programme
*/
id: string
/**
* Name of the loyalty programme
*/
name: string
/**
* The Duffel ID of the airline that corresponds to the loyalty programme
*/
owner_airline_id: string
/*
* The name of the alliance this loyalty programme is part of. This may be `null` if the loyalty programme isn't part of an alliance.
*/
alliance: string | null
/*
* Path to a svg of the loyalty programme logo. This may be `null` if no logo is available.
*/
logo_url: string | null
}
2 changes: 2 additions & 0 deletions src/supportingResources/LoyaltyProgrammes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './LoyaltyProgrammes'
export * as LoyaltyProgrammeType from './LoyaltyProgrammesTypes'
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { LoyaltyProgramme } from '../../types'

export const mockLoyaltyProgramme: LoyaltyProgramme = {
id: 'loy_00001876aqC8c5umZmrRds',
name: 'Miles & More',
owner_airline_id: 'arl_00001876aqC8c5umZmrRds',
alliance: 'Star Alliance',
logo_url:
'https://assets.duffel.com/img/loyalty-programmes/full-color-logo/LH.svg',
}
1 change: 1 addition & 0 deletions src/supportingResources/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './Aircraft'
export * from './Airlines'
export * from './Airports'
export * from './LoyaltyProgrammes'
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export * from '../notifications/Webhooks/WebhooksType'
export * from '../supportingResources/Aircraft/AircraftTypes'
export * from '../supportingResources/Airlines/AirlinesTypes'
export * from '../supportingResources/Airports/AirportsTypes'
export * from '../supportingResources/LoyaltyProgrammes/LoyaltyProgrammesTypes'
export * from './ClientType'
export * from './Identity'
export * from './shared'
Expand Down
Loading