duffelhq / duffel-api-javascript Goto Github PK
View Code? Open in Web Editor NEWJavaScript client library for the Duffel API
Home Page: https://duffel.com/docs
License: MIT License
JavaScript client library for the Duffel API
Home Page: https://duffel.com/docs
License: MIT License
Attempting to build my project with @duffel/[email protected] and TSC version 5.2.2 I'm getting the following errors:
node_modules/@duffel/api/dist/typings.d.ts:1288:32 - error TS2307: Cannot find module 'types' or its corresponding type declarations.
1288 import { OrderSlice } from 'types';
~~~~~~~
node_modules/@duffel/api/dist/typings.d.ts:3767:36 - error TS2307: Cannot find module 'types' or its corresponding type declarations.
3767 import { PaginationMeta } from 'types';
~~~~~~~
node_modules/@duffel/api/dist/typings.d.ts:3921:12 - error TS1038: A 'declare' modifier cannot be used in an already ambient context.
3921 export declare class Airlines extends Resource {
~~~~~~~
It looks like a few similar issues were recently fixed: #794
Thanks for your support!
We cannot import @duffel/api, error: Error: Cannot find module 'node:http'. Node version = 14.18.3. OS = windows 10.
I was receiving a 404 when using duffel.paymentIntents.create
on @duffel/api version 1.7.0 and 1.7.1
I looked up the endpoint that was being called here and it was set to 'air/payments/payment_intents'
The documentation says to go directly to /payments/payment_intents
and so I added duffel.paymentIntents.path = "payments/payment_intents";
to my server code right before duffel.paymentIntents.create
and it works now
it looks like some of the other endpoints also have "air/" in them but work properly so I don't know if this is a javascript library issue or an api issue but it was blocking me from taking orders.
import{URL as s,URLSearchParams as e}from"url" error showing when trying to compile the code
Hello!
I hope you are doing well!
We are a security research team. Our tool automatically detected a vulnerability in this repository. We want to disclose it responsibly. GitHub has a feature called Private vulnerability reporting, which enables security research to privately disclose a vulnerability. Unfortunately, it is not enabled for this repository.
Can you enable it, so that we can report it?
Thanks in advance!
PS: you can read about how to enable private vulnerability reporting here: https://docs.github.com/en/code-security/security-advisories/repository-security-advisories/configuring-private-vulnerability-reporting-for-a-repository
If I check the docs I see that "query" deprecated.
https://duffel.com/docs/api/v1/places/get-place-suggestions
Referencing the documentation provided here: https://duffel.com/docs/api/places/get-place-suggestions
I implemented a quick function to test the suggestions function.
Duffel Component
var { Duffel } = require('@duffel/api');
const duffel = new Duffel({
token: "duffel_test_XXX",
debug: { verbose: true }
});
module.exports = duffel;
Router Component
var express = require("express");
var router = express.Router();
var duffel = require('../duffel');
router.get("/", async (req, res, next) => {
const autosuggestion = await duffel.suggestions.list(
{
"query": "heathr"
}
)
res.send(autosuggestion);
});
module.exports = router;
Error Message
TypeError: Cannot read properties of undefined (reading 'list')
It seems as though the suggestions function does not exist.
Please help.
The docs specify 5 possible values for PassengerTitle
, but the typescript types represent 3 of them in upper and lowercase, and miss the other 2:
duffel-api-javascript/src/types/shared.ts
Lines 67 to 70 in c308b4f
Just testing this cool feature :).
Hello,
We have been struggling to get x-request-id header in our Node app. We use Duffel JS to get Api body but we do not get the header information. Please can you help?
It would be very useful to be able to obtain the detailed fare rules such as penalties, seating policies, refund policies etc by providing the fare basis code.
The docs state that some fields on responses can be null, for example penalty_currency
when the change/refund is not allowed,
If refunds aren't allowed, the conditions.refund_before_departure.allowed attribute will be false, and the penalty amount and currency will be null
however the typing for this does not accept this as the case as seen here:
duffel-api-javascript/src/types/shared.ts
Line 143 in bf086f2
/**
* The currency of the `penalty_amount` as an [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code.
* This will be in a currency determined by the airline, which is not necessarily the same as the currency of the order or offer.
* If this is `null` then `penalty_amount` will also be `null`.
* @example "GBP"
*/
penalty_currency: string
It looks as if recently some changes have been made around this, including making penalty_amount
nullable, so perhaps some have been missed.
duffel-api-javascript/src/types/shared.ts
Line 150 in bf086f2
Hi,
it seems that the stops
key is missing in the OfferSliceSegment type.
Can this be added in the next update?
Trying to find instructions on how to use the CLI tool. (how to generate a new app?). Is there a boilerplate or example repo available on Github? Thanks in advance.
Hello!
We are in the services part regarding the JS SDK integration but we are running into a problem. When trying to Create an Order, the response is undefined and the SDK does not return errors.
It had happened before but it turned out to be because of a sum error in the "amount" (which also doesn't return errors when it's wrong as far as we've tested). But now, with several services, for some reason it fails and we believe that this time the sum is correct. The same booking, but with less baggage services, did work.
We also enabled debug mode in the SDK to check more accurately but it didn't help much.
The log and the information with which we tried to create an order, in the test environment:
[2023-03-23T02:26:25.815Z] Endpoint: https://api.duffel.com/air/orders
[2023-03-23T02:26:25.815Z] Method: POST
[2023-03-23T02:26:25.815Z] Body Parameters: {
selected_offers: [ 'off_0000ATtQPgBS0joLrbNcY7' ],
payments: [ { type: 'balance', currency: 'EUR', amount: '253.91' } ],
passengers: [
{
type: 'adult',
loyalty_programme_accounts: [],
id: 'pas_0000ATtQPdvQPLnsrJrnHu',
given_name: 'Leonardo',
family_name: 'Godoy',
age: null,
born_on: '1980-02-02',
email: 'REDACTED',
phone_number: 'REDACTED',
gender: 'm',
title: 'mr'
}
],
type: 'instant',
services: [
{ id: 'ase_0000ATtQPlOz1hvW9V553C', quantity: 1 },
{ id: 'ase_0000ATtQPlOz1hvW9V553A', quantity: 3 },
{ id: 'ase_0000ATtQPlOz1hvW9V553B', quantity: 3 }
]
}
If I give duffel.offerRequests.create
a max_connections
value it works but I get a type error:
const { data } = await duffel.offerRequests.create({
...
max_connections: 0 // <-- this shows a type error
});
I'd make a PR for this but given the problems we had with #653 I thought it would just be easier to make this issue.
Greetings,
I'm unable to find the answer to these two questions in Duffel's documentation:
How long should one wait between creating an OfferRequest (i.e., offerRequests.create
) and reviewing/listing offers (i.e., offers.list
)? I'm asking largely because this part of the documentation mentions response times + the fact that Duffel acts as proxy.
Somewhat linked to the above question -- this documentation mentions a return_offers
argument ... what is the purpose of that argument? If set to true
will offers immediately be returned (eliminating the need to use offers.list
)?
Thank you
Attempting to build my project which uses the Duffel API, but getting the error:
Cannot find module 'Client' or its corresponding type declarations
multiple times in my compilation.
I went through some of the older Issues and found #372 on version 1.7, and after looking around I have a slight suspicion that relative paths have stopped being used since.
Could this be looked into please?
EDIT: Referenced the wrong issue
Hello Team,
The CardPayment component isn't working. I tried both the React and Vanilla JS components and both throw an error.
Component URL
https://duffel.com/docs/guides/collecting-customer-card-payments
Please check the attached screenshot below
Please let me know if there is any other way I can collect the Payments from the customer?
Regards,
Charles
Me again... Really sorry!
interface OfferRequestSlice {
...
/**
* The city or airport the passengers want to travel to
*/
destination: Place | string;
/**
* The city or airport the passengers want to depart from
*/
origin: Place | string;
....
}
Should these just be set to Place
? Is there an example of a time when these might be a string?
OK I promise this is the last one from me today!
Pretty much the same as #653 but for OfferPassenger
Hi!
A part of the implementation that was previously working and is no longer working is the selection of services, specifically baggage.
meta: { status: 422, request_id: 'F1FXLmKy-Q5QFmIAb2yB' },
errors: [
{
type: 'validation_error',
title: 'Linked record(s) not found',
source: [Object],
message: "Field 'id' contains ID(s) of linked record(s) that were not found in your account",
documentation_url: 'https://duffel.com/docs/api/overview/errors',
code: 'not_found'
}
]
Since we call the GetOffer endpoint multiple times to check that the flight is still available, it is understandable and to be expected that the ID of the services will change. The problem is that in this case, when doing the retrieval of selected services, we are using the last Offer received with its corresponding services.
In this case, the services to be added to the booking are:
[{"id":"ase_0000AU9mw1Siuc9ifftYY7","quantity":3}]
Below, in order of extraction, are all the services that we received in the Offers. The last one would be the GetOffer before CreateOrder(), and, consequently, the Offer.services that we use to obtain the ID to use in this flight.
[
[
{
"type": "baggage",
"total_currency": "EUR",
"total_amount": "72.67",
"segment_ids": [
"seg_0000AU9mYFlZSEOU53adhG",
"seg_0000AU9mYFlZSEOU53adhI"
],
"passenger_ids": ["pas_0000AU9mYDWFoCxB6yPNXn"],
"metadata": {
"type": "checked",
"maximum_weight_kg": 23,
"maximum_length_cm": null,
"maximum_height_cm": null,
"maximum_depth_cm": null
},
"maximum_quantity": 3,
"id": "ase_0000AU9mq2Jgp5UJaDobSa"
},
{
"type": "baggage",
"total_currency": "EUR",
"total_amount": "61.31",
"segment_ids": [
"seg_0000AU9mYFlZSEOU53adhG",
"seg_0000AU9mYFlZSEOU53adhI"
],
"passenger_ids": ["pas_0000AU9mYDWFoCxB6yPNXn"],
"metadata": {
"type": "checked",
"maximum_weight_kg": 15,
"maximum_length_cm": null,
"maximum_height_cm": null,
"maximum_depth_cm": null
},
"maximum_quantity": 3,
"id": "ase_0000AU9mq2Jgp5UJaDobSb"
},
{
"type": "baggage",
"total_currency": "EUR",
"total_amount": "36.32",
"segment_ids": [
"seg_0000AU9mYFlZSEOU53adhG",
"seg_0000AU9mYFlZSEOU53adhI"
],
"passenger_ids": ["pas_0000AU9mYDWFoCxB6yPNXn"],
"metadata": {
"type": "carry_on",
"maximum_weight_kg": null,
"maximum_length_cm": null,
"maximum_height_cm": null,
"maximum_depth_cm": null
},
"maximum_quantity": 1,
"id": "ase_0000AU9mq2Jgp5UJaDobSc"
}
],
[
{
"type": "baggage",
"total_currency": "EUR",
"total_amount": "72.67",
"segment_ids": [
"seg_0000AU9mqEdbIBUnebCdsi",
"seg_0000AU9mqEdbIBUnebCdsl"
],
"passenger_ids": ["pas_0000AU9mqCNDi7CkdDWX4N"],
"metadata": {
"type": "checked",
"maximum_weight_kg": 23,
"maximum_length_cm": null,
"maximum_height_cm": null,
"maximum_depth_cm": null
},
"maximum_quantity": 3,
"id": "ase_0000AU9mqOtGGo07agqAN6"
},
{
"type": "baggage",
"total_currency": "EUR",
"total_amount": "61.31",
"segment_ids": [
"seg_0000AU9mqEdbIBUnebCdsi",
"seg_0000AU9mqEdbIBUnebCdsl"
],
"passenger_ids": ["pas_0000AU9mqCNDi7CkdDWX4N"],
"metadata": {
"type": "checked",
"maximum_weight_kg": 15,
"maximum_length_cm": null,
"maximum_height_cm": null,
"maximum_depth_cm": null
},
"maximum_quantity": 3,
"id": "ase_0000AU9mqOtGGo07agqAN7"
},
{
"type": "baggage",
"total_currency": "EUR",
"total_amount": "36.32",
"segment_ids": [
"seg_0000AU9mqEdbIBUnebCdsi",
"seg_0000AU9mqEdbIBUnebCdsl"
],
"passenger_ids": ["pas_0000AU9mqCNDi7CkdDWX4N"],
"metadata": {
"type": "carry_on",
"maximum_weight_kg": null,
"maximum_length_cm": null,
"maximum_height_cm": null,
"maximum_depth_cm": null
},
"maximum_quantity": 1,
"id": "ase_0000AU9mqOtGGo07agqAN8"
}
],
[
{
"type": "baggage",
"total_currency": "EUR",
"total_amount": "72.67",
"segment_ids": [
"seg_0000AU9mqEdbIBUnebCdsi",
"seg_0000AU9mqEdbIBUnebCdsl"
],
"passenger_ids": ["pas_0000AU9mqCNDi7CkdDWX4N"],
"metadata": {
"type": "checked",
"maximum_weight_kg": 23,
"maximum_length_cm": null,
"maximum_height_cm": null,
"maximum_depth_cm": null
},
"maximum_quantity": 3,
"id": "ase_0000AU9mviFwbCawxgkYDM"
},
{
"type": "baggage",
"total_currency": "EUR",
"total_amount": "61.31",
"segment_ids": [
"seg_0000AU9mqEdbIBUnebCdsi",
"seg_0000AU9mqEdbIBUnebCdsl"
],
"passenger_ids": ["pas_0000AU9mqCNDi7CkdDWX4N"],
"metadata": {
"type": "checked",
"maximum_weight_kg": 15,
"maximum_length_cm": null,
"maximum_height_cm": null,
"maximum_depth_cm": null
},
"maximum_quantity": 3,
"id": "ase_0000AU9mviFwbCawxgkYDO"
},
{
"type": "baggage",
"total_currency": "EUR",
"total_amount": "36.32",
"segment_ids": [
"seg_0000AU9mqEdbIBUnebCdsi",
"seg_0000AU9mqEdbIBUnebCdsl"
],
"passenger_ids": ["pas_0000AU9mqCNDi7CkdDWX4N"],
"metadata": {
"type": "carry_on",
"maximum_weight_kg": null,
"maximum_length_cm": null,
"maximum_height_cm": null,
"maximum_depth_cm": null
},
"maximum_quantity": 1,
"id": "ase_0000AU9mviFwbCawxgkYDQ"
}
],
[
{
"type": "baggage",
"total_currency": "EUR",
"total_amount": "72.67",
"segment_ids": [
"seg_0000AU9mqEdbIBUnebCdsi",
"seg_0000AU9mqEdbIBUnebCdsl"
],
"passenger_ids": ["pas_0000AU9mqCNDi7CkdDWX4N"],
"metadata": {
"type": "checked",
"maximum_weight_kg": 23,
"maximum_length_cm": null,
"maximum_height_cm": null,
"maximum_depth_cm": null
},
"maximum_quantity": 3,
"id": "ase_0000AU9mw1Siuc9ifftYY7"
},
{
"type": "baggage",
"total_currency": "EUR",
"total_amount": "61.31",
"segment_ids": [
"seg_0000AU9mqEdbIBUnebCdsi",
"seg_0000AU9mqEdbIBUnebCdsl"
],
"passenger_ids": ["pas_0000AU9mqCNDi7CkdDWX4N"],
"metadata": {
"type": "checked",
"maximum_weight_kg": 15,
"maximum_length_cm": null,
"maximum_height_cm": null,
"maximum_depth_cm": null
},
"maximum_quantity": 3,
"id": "ase_0000AU9mw1Siuc9ifftYY9"
},
{
"type": "baggage",
"total_currency": "EUR",
"total_amount": "36.32",
"segment_ids": [
"seg_0000AU9mqEdbIBUnebCdsi",
"seg_0000AU9mqEdbIBUnebCdsl"
],
"passenger_ids": ["pas_0000AU9mqCNDi7CkdDWX4N"],
"metadata": {
"type": "carry_on",
"maximum_weight_kg": null,
"maximum_length_cm": null,
"maximum_height_cm": null,
"maximum_depth_cm": null
},
"maximum_quantity": 1,
"id": "ase_0000AU9mw1Siuc9ifftYYB"
}
]
]
In the list I concentrated for better readability all the times we received services, and as you can see the user's selection matches the last Array of available services.
It should be noted that as booking token for the Order we are using the ID of the last Offer extracted.
Thanks!
The docs specify a field called conditions_of_carriage_url
on the Airline object, but this is not present in the TypeScript types:
I started reading the documentation here: https://duffel.com/docs/guides/getting-started-with-flights
Looked at the code:
duffel.offerRequests.create({
slices : [
{
origin: "NYC",
destination: "ATL",
departure_date: "2021-06-21"
},
{
origin: "ATL",
destination: "NYC",
departure_date: "2021-07-21"
}
],
passengers: [{ type: "adult" }, { type: "adult" }, { age: 1 }],
cabin_class: "business",
})
But it seems that this way of searching for flights is not available anymore, now you need to pass in a Place
for the origin and destination objects.
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates are awaiting their schedule. Click on a checkbox to get an update now.
@typescript-eslint/eslint-plugin
, @typescript-eslint/parser
)@commitlint/cli
, @commitlint/config-angular
, @commitlint/cz-commitlint
)node
, @types/node
)@typescript-eslint/eslint-plugin
, @typescript-eslint/parser
)These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
.tool-versions
node 18.18.2
.circleci/config.yml
cimg/node 20.8
.github/workflows/autoapprove.yml
hmarr/auto-approve-action v2
.github/workflows/release.yml
actions/checkout v4
actions/setup-node v3
actions/cache v3
peter-evans/create-pull-request v5.0.2
peter-evans/enable-pull-request-automerge v3
package.json
@types/node ^18.0.0
@types/node-fetch ^2.6.2
node-fetch 2.7.0
@babel/core 7.24.3
@babel/preset-env 7.24.3
@babel/preset-typescript 7.24.1
@commitlint/cli 17.8.1
@commitlint/config-angular 17.8.1
@commitlint/cz-commitlint 17.8.1
@rollup/plugin-commonjs 25.0.7
@rollup/plugin-node-resolve 15.2.3
@types/jest 29.5.12
@typescript-eslint/eslint-plugin 6.7.5
@typescript-eslint/parser 6.7.5
colors 1.4.0
commitizen 4.3.0
dotenv 16.3.1
eslint 8.51.0
eslint-config-prettier 9.0.0
eslint-plugin-spellcheck 0.0.20
husky 8.0.3
jest 29.7.0
lint-staged 14.0.1
nock 13.3.4
prettier 3.0.3
rollup 4.0.2
rollup-plugin-dts-bundle ^1.0.0
rollup-plugin-inject-process-env 1.3.1
rollup-plugin-peer-deps-external 2.2.4
rollup-plugin-terser 7.0.2
rollup-plugin-typescript2 0.36.0
semantic-release 22.0.12
ts-jest 29.1.2
ts-node 10.9.2
typescript 5.2.2
node >=18.*
ansi-regex ^5.0.1
set-value ^4.0.1
minimist 1.2.8
semver ^7.5.3
.nvmrc
Hi,
I have been trying to use the SDK with my firebase Cloud Functions,
I have initialized and exported a new instance of Duffel
import { Duffel } from '@duffel/api';
const duffel = new Duffel({
token: 'duffel**********************************4J-o3',
});
export default duffel;
which I was using on an express request handler,
const airports = await duffel.airports.list({
limit: 100,
});
but when building and testing the code,
I am getting this error
node_modules/@duffel/api/dist/types/index.d.ts:1:36 - error TS2307: Cannot find module 'Client' or its corresponding type declarations.
1 import { Client as Client$1 } from 'Client';
Is this a bug with the SDK or something is wrong on my end
The API documents a really useful method of tracking rate limiting. Are there any plans to incorporate that in the library? It would be nice if the library could track that internally, but I see a bunch of potholes with that method. At the very least, it would be great to expose the values of those headers in the response.
Hi Team,
I' am getting the below error, please help. BTW I love your product so much!
const duffel = new Duffel({
// Store your access token in an environment variable, keep it secret and only readable on your server
token: 'My Token,
});
const offerRequestResponse = await duffel.offerRequests.create({
slices : [
{
origin: "NYC",
destination: "ATL",
departure_date: "2022-06-21"
},
{
origin: "ATL",
destination: "NYC",
departure_date: "2022-07-21"
}
],
passengers: [{ type: "adult" }, { type: "adult" }, { age: 1 }],
cabin_class: "business",
return_offers: true
})
console.log(offerRequestResponse.data.id);
Hi,
I am using the return_offers
flag for an offers request. I find the response odd in these cases:
when flag is true
I only usually receive around 20 offers, when setting it as false
and the querying the offers list request with the offer id I get more than 100 offers in total.
Is this something that is done on purpose while using the test data or am I doing something wrong? I would expect to receive all offers if the return_offers
flag is true
Thank you!
Hi,
I understand the need for a different type for the segments on OfferSlice
s and OrderSlice
s, due to some fields being unavailable before placing an order, or others being irrelevant after the order is placed, but I'm interested to know more about why OfferSliceSegment
destination
s/origin
s are Airports
, but on the OrderSlice
segments they are Places
, implying they could be a City
instead.
Looking at the docs it actually seems the destination/origin type is intended to be a Place
, even on the offer. What does it mean for a segment to arrive at or depart from a city?
Finally, many of the fields on City are marked as nullable or even undefined, though the docs specify them as required and not nullable (e.g. latitude
, longitude
, timezone
)
Thanks in advance ๐
Hi there, I am using a test token and I would like to know whether it exists any type of restriction in the number of pages, I am only receive one page in all requests.
Thanks for your time.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.