boostedtravel 0.1.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.
- package/README.md +81 -0
- package/dist/chunk-GIJTJ3JU.mjs +199 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +520 -0
- package/dist/cli.mjs +339 -0
- package/dist/index.d.mts +177 -0
- package/dist/index.d.ts +177 -0
- package/dist/index.js +228 -0
- package/dist/index.mjs +18 -0
- package/package.json +50 -0
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
BoostedTravel,
|
|
4
|
+
BoostedTravelError,
|
|
5
|
+
offerSummary
|
|
6
|
+
} from "./chunk-GIJTJ3JU.mjs";
|
|
7
|
+
|
|
8
|
+
// src/cli.ts
|
|
9
|
+
function getFlag(args, flag, alias) {
|
|
10
|
+
for (let i = 0; i < args.length; i++) {
|
|
11
|
+
if (args[i] === flag || alias && args[i] === alias) {
|
|
12
|
+
const val = args[i + 1];
|
|
13
|
+
args.splice(i, 2);
|
|
14
|
+
return val;
|
|
15
|
+
}
|
|
16
|
+
if (args[i].startsWith(`${flag}=`)) {
|
|
17
|
+
const val = args[i].split("=").slice(1).join("=");
|
|
18
|
+
args.splice(i, 1);
|
|
19
|
+
return val;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return void 0;
|
|
23
|
+
}
|
|
24
|
+
function hasFlag(args, flag) {
|
|
25
|
+
const idx = args.indexOf(flag);
|
|
26
|
+
if (idx >= 0) {
|
|
27
|
+
args.splice(idx, 1);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
function getAllFlags(args, flag, alias) {
|
|
33
|
+
const results = [];
|
|
34
|
+
let i = 0;
|
|
35
|
+
while (i < args.length) {
|
|
36
|
+
if (args[i] === flag || alias && args[i] === alias) {
|
|
37
|
+
results.push(args[i + 1]);
|
|
38
|
+
args.splice(i, 2);
|
|
39
|
+
} else {
|
|
40
|
+
i++;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return results;
|
|
44
|
+
}
|
|
45
|
+
async function cmdSearch(args) {
|
|
46
|
+
const jsonOut = hasFlag(args, "--json") || hasFlag(args, "-j");
|
|
47
|
+
const apiKey = getFlag(args, "--api-key", "-k");
|
|
48
|
+
const baseUrl = getFlag(args, "--base-url");
|
|
49
|
+
const returnDate = getFlag(args, "--return", "-r");
|
|
50
|
+
const adults = parseInt(getFlag(args, "--adults", "-a") || "1");
|
|
51
|
+
const cabin = getFlag(args, "--cabin", "-c");
|
|
52
|
+
const stops = parseInt(getFlag(args, "--max-stops", "-s") || "2");
|
|
53
|
+
const currency = getFlag(args, "--currency") || "EUR";
|
|
54
|
+
const limit = parseInt(getFlag(args, "--limit", "-l") || "20");
|
|
55
|
+
const sort = getFlag(args, "--sort") || "price";
|
|
56
|
+
const [origin, destination, date] = args;
|
|
57
|
+
if (!origin || !destination || !date) {
|
|
58
|
+
console.error("Usage: boostedtravel search <origin> <destination> <date> [options]");
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
const bt = new BoostedTravel({ apiKey, baseUrl });
|
|
62
|
+
const result = await bt.search(origin, destination, date, {
|
|
63
|
+
returnDate,
|
|
64
|
+
adults,
|
|
65
|
+
cabinClass: cabin,
|
|
66
|
+
maxStopovers: stops,
|
|
67
|
+
currency,
|
|
68
|
+
limit,
|
|
69
|
+
sort
|
|
70
|
+
});
|
|
71
|
+
if (jsonOut) {
|
|
72
|
+
console.log(JSON.stringify({
|
|
73
|
+
passenger_ids: result.passenger_ids,
|
|
74
|
+
total_results: result.total_results,
|
|
75
|
+
offers: result.offers.map((o) => ({
|
|
76
|
+
id: o.id,
|
|
77
|
+
price: o.price,
|
|
78
|
+
currency: o.currency,
|
|
79
|
+
airlines: o.airlines,
|
|
80
|
+
owner_airline: o.owner_airline,
|
|
81
|
+
route: [o.outbound.segments[0]?.origin, ...o.outbound.segments.map((s) => s.destination)].join(" \u2192 "),
|
|
82
|
+
duration_seconds: o.outbound.total_duration_seconds,
|
|
83
|
+
stopovers: o.outbound.stopovers,
|
|
84
|
+
conditions: o.conditions,
|
|
85
|
+
is_locked: o.is_locked
|
|
86
|
+
}))
|
|
87
|
+
}, null, 2));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (!result.offers.length) {
|
|
91
|
+
console.log(`No flights found for ${origin} \u2192 ${destination} on ${date}`);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
console.log(`
|
|
95
|
+
${result.total_results} offers | ${origin} \u2192 ${destination} | ${date}`);
|
|
96
|
+
console.log(` Passenger IDs: ${JSON.stringify(result.passenger_ids)}
|
|
97
|
+
`);
|
|
98
|
+
result.offers.forEach((o, i) => {
|
|
99
|
+
console.log(` ${(i + 1).toString().padStart(3)}. ${offerSummary(o)}`);
|
|
100
|
+
console.log(` ID: ${o.id}`);
|
|
101
|
+
});
|
|
102
|
+
console.log(`
|
|
103
|
+
To unlock: boostedtravel unlock <offer_id>`);
|
|
104
|
+
console.log(` Passenger IDs needed for booking: ${JSON.stringify(result.passenger_ids)}
|
|
105
|
+
`);
|
|
106
|
+
}
|
|
107
|
+
async function cmdUnlock(args) {
|
|
108
|
+
const jsonOut = hasFlag(args, "--json") || hasFlag(args, "-j");
|
|
109
|
+
const apiKey = getFlag(args, "--api-key", "-k");
|
|
110
|
+
const baseUrl = getFlag(args, "--base-url");
|
|
111
|
+
const offerId = args[0];
|
|
112
|
+
if (!offerId) {
|
|
113
|
+
console.error("Usage: boostedtravel unlock <offer_id>");
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
const bt = new BoostedTravel({ apiKey, baseUrl });
|
|
117
|
+
const result = await bt.unlock(offerId);
|
|
118
|
+
if (jsonOut) {
|
|
119
|
+
console.log(JSON.stringify(result, null, 2));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (result.unlock_status === "unlocked") {
|
|
123
|
+
console.log(`
|
|
124
|
+
\u2713 Offer unlocked!`);
|
|
125
|
+
console.log(` Confirmed price: ${result.confirmed_currency} ${result.confirmed_price?.toFixed(2)}`);
|
|
126
|
+
console.log(` Expires at: ${result.offer_expires_at}`);
|
|
127
|
+
console.log(` $1 unlock fee charged`);
|
|
128
|
+
console.log(`
|
|
129
|
+
Next: boostedtravel book ${offerId} --passenger '{...}' --email you@example.com
|
|
130
|
+
`);
|
|
131
|
+
} else {
|
|
132
|
+
console.error(` \u2717 Unlock failed: ${result.message}`);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async function cmdBook(args) {
|
|
137
|
+
const jsonOut = hasFlag(args, "--json") || hasFlag(args, "-j");
|
|
138
|
+
const apiKey = getFlag(args, "--api-key", "-k");
|
|
139
|
+
const baseUrl = getFlag(args, "--base-url");
|
|
140
|
+
const email = getFlag(args, "--email", "-e") || "";
|
|
141
|
+
const phone = getFlag(args, "--phone") || "";
|
|
142
|
+
const passengerStrs = getAllFlags(args, "--passenger", "-p");
|
|
143
|
+
const offerId = args[0];
|
|
144
|
+
if (!offerId || !passengerStrs.length || !email) {
|
|
145
|
+
console.error(`Usage: boostedtravel book <offer_id> --passenger '{"id":"pas_xxx",...}' --email you@example.com`);
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
const passengers = passengerStrs.map((s) => JSON.parse(s));
|
|
149
|
+
const bt = new BoostedTravel({ apiKey, baseUrl });
|
|
150
|
+
const result = await bt.book(offerId, passengers, email, phone);
|
|
151
|
+
if (jsonOut) {
|
|
152
|
+
console.log(JSON.stringify(result, null, 2));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (result.status === "confirmed") {
|
|
156
|
+
console.log(`
|
|
157
|
+
\u2713 Booking confirmed!`);
|
|
158
|
+
console.log(` PNR: ${result.booking_reference}`);
|
|
159
|
+
console.log(` Flight: ${result.currency} ${result.flight_price.toFixed(2)}`);
|
|
160
|
+
console.log(` Fee: ${result.currency} ${result.service_fee.toFixed(2)} (${result.service_fee_percentage}%)`);
|
|
161
|
+
console.log(` Total: ${result.currency} ${result.total_charged.toFixed(2)}`);
|
|
162
|
+
console.log(` Order: ${result.order_id}
|
|
163
|
+
`);
|
|
164
|
+
} else {
|
|
165
|
+
console.error(` \u2717 Booking failed`);
|
|
166
|
+
console.error(JSON.stringify(result.details, null, 2));
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async function cmdLocations(args) {
|
|
171
|
+
const jsonOut = hasFlag(args, "--json") || hasFlag(args, "-j");
|
|
172
|
+
const apiKey = getFlag(args, "--api-key", "-k");
|
|
173
|
+
const baseUrl = getFlag(args, "--base-url");
|
|
174
|
+
const query = args[0];
|
|
175
|
+
if (!query) {
|
|
176
|
+
console.error("Usage: boostedtravel locations <city-or-airport-name>");
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
const bt = new BoostedTravel({ apiKey, baseUrl });
|
|
180
|
+
const result = await bt.resolveLocation(query);
|
|
181
|
+
if (jsonOut) {
|
|
182
|
+
console.log(JSON.stringify(result, null, 2));
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (!result.length) {
|
|
186
|
+
console.log(`No locations found for '${query}'`);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
for (const loc of result) {
|
|
190
|
+
const iata = (loc.iata_code || "???").padEnd(5);
|
|
191
|
+
const name = loc.name || "";
|
|
192
|
+
const type = loc.type || "";
|
|
193
|
+
const city = loc.city_name || "";
|
|
194
|
+
const country = loc.country || "";
|
|
195
|
+
console.log(` ${iata} ${name} (${type}) \u2014 ${city}, ${country}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
async function cmdRegister(args) {
|
|
199
|
+
const jsonOut = hasFlag(args, "--json") || hasFlag(args, "-j");
|
|
200
|
+
const baseUrl = getFlag(args, "--base-url");
|
|
201
|
+
const name = getFlag(args, "--name", "-n");
|
|
202
|
+
const email = getFlag(args, "--email", "-e");
|
|
203
|
+
const owner = getFlag(args, "--owner") || "";
|
|
204
|
+
const desc = getFlag(args, "--desc") || "";
|
|
205
|
+
if (!name || !email) {
|
|
206
|
+
console.error("Usage: boostedtravel register --name my-agent --email agent@example.com");
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
const result = await BoostedTravel.register(name, email, baseUrl, owner, desc);
|
|
210
|
+
if (jsonOut) {
|
|
211
|
+
console.log(JSON.stringify(result, null, 2));
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
console.log(`
|
|
215
|
+
\u2713 Agent registered!`);
|
|
216
|
+
console.log(` Agent ID: ${result.agent_id}`);
|
|
217
|
+
console.log(` API Key: ${result.api_key}`);
|
|
218
|
+
console.log(`
|
|
219
|
+
Save your API key:`);
|
|
220
|
+
console.log(` export BOOSTEDTRAVEL_API_KEY=${result.api_key}`);
|
|
221
|
+
console.log(`
|
|
222
|
+
Next: boostedtravel setup-payment --token tok_visa
|
|
223
|
+
`);
|
|
224
|
+
}
|
|
225
|
+
async function cmdSetupPayment(args) {
|
|
226
|
+
const jsonOut = hasFlag(args, "--json") || hasFlag(args, "-j");
|
|
227
|
+
const apiKey = getFlag(args, "--api-key", "-k");
|
|
228
|
+
const baseUrl = getFlag(args, "--base-url");
|
|
229
|
+
const token = getFlag(args, "--token", "-t") || "tok_visa";
|
|
230
|
+
const bt = new BoostedTravel({ apiKey, baseUrl });
|
|
231
|
+
const result = await bt.setupPayment(token);
|
|
232
|
+
if (jsonOut) {
|
|
233
|
+
console.log(JSON.stringify(result, null, 2));
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (result.status === "ready") {
|
|
237
|
+
console.log(`
|
|
238
|
+
\u2713 Payment ready! You can now unlock offers and book flights.
|
|
239
|
+
`);
|
|
240
|
+
} else {
|
|
241
|
+
console.error(` \u2717 Payment setup failed: ${result.message || result.status}`);
|
|
242
|
+
process.exit(1);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async function cmdMe(args) {
|
|
246
|
+
const jsonOut = hasFlag(args, "--json") || hasFlag(args, "-j");
|
|
247
|
+
const apiKey = getFlag(args, "--api-key", "-k");
|
|
248
|
+
const baseUrl = getFlag(args, "--base-url");
|
|
249
|
+
const bt = new BoostedTravel({ apiKey, baseUrl });
|
|
250
|
+
const profile = await bt.me();
|
|
251
|
+
if (jsonOut) {
|
|
252
|
+
console.log(JSON.stringify(profile, null, 2));
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const p = profile;
|
|
256
|
+
const u = p.usage || {};
|
|
257
|
+
console.log(`
|
|
258
|
+
Agent: ${p.agent_name} (${p.agent_id})`);
|
|
259
|
+
console.log(` Email: ${p.email}`);
|
|
260
|
+
console.log(` Tier: ${p.tier}`);
|
|
261
|
+
console.log(` Payment: ${p.payment_ready ? "\u2713 Ready" : "\u2717 Not set up"}`);
|
|
262
|
+
console.log(` Searches: ${u.total_searches || 0}`);
|
|
263
|
+
console.log(` Unlocks: ${u.total_unlocks || 0}`);
|
|
264
|
+
console.log(` Bookings: ${u.total_bookings || 0}`);
|
|
265
|
+
console.log(` Total spent: $${((u.total_spent_cents || 0) / 100).toFixed(2)}
|
|
266
|
+
`);
|
|
267
|
+
}
|
|
268
|
+
var HELP = `
|
|
269
|
+
BoostedTravel \u2014 Agent-native flight search & booking.
|
|
270
|
+
|
|
271
|
+
Search 300+ airlines at prices $10-30 cheaper than OTAs.
|
|
272
|
+
Search is FREE. Unlock: $1. Book: 2.5% fee.
|
|
273
|
+
|
|
274
|
+
Commands:
|
|
275
|
+
search <origin> <dest> <date> Search for flights (FREE)
|
|
276
|
+
locations <query> Resolve city name to IATA codes
|
|
277
|
+
unlock <offer_id> Unlock offer ($1)
|
|
278
|
+
book <offer_id> --passenger ... Book flight (2.5% fee)
|
|
279
|
+
register --name ... --email ... Register new agent
|
|
280
|
+
setup-payment Set up payment card
|
|
281
|
+
me Show agent profile
|
|
282
|
+
|
|
283
|
+
Options:
|
|
284
|
+
--json, -j Output raw JSON
|
|
285
|
+
--api-key, -k API key (or set BOOSTEDTRAVEL_API_KEY)
|
|
286
|
+
--base-url API URL (default: https://api.boostedchat.com)
|
|
287
|
+
|
|
288
|
+
Examples:
|
|
289
|
+
boostedtravel search GDN BER 2026-03-03 --sort price
|
|
290
|
+
boostedtravel search LON BCN 2026-04-01 --return 2026-04-08 --json
|
|
291
|
+
boostedtravel unlock off_xxx
|
|
292
|
+
boostedtravel book off_xxx -p '{"id":"pas_xxx","given_name":"John","family_name":"Doe","born_on":"1990-01-15"}' -e john@ex.com
|
|
293
|
+
`;
|
|
294
|
+
async function main() {
|
|
295
|
+
const args = process.argv.slice(2);
|
|
296
|
+
const command = args.shift();
|
|
297
|
+
try {
|
|
298
|
+
switch (command) {
|
|
299
|
+
case "search":
|
|
300
|
+
await cmdSearch(args);
|
|
301
|
+
break;
|
|
302
|
+
case "unlock":
|
|
303
|
+
await cmdUnlock(args);
|
|
304
|
+
break;
|
|
305
|
+
case "book":
|
|
306
|
+
await cmdBook(args);
|
|
307
|
+
break;
|
|
308
|
+
case "locations":
|
|
309
|
+
await cmdLocations(args);
|
|
310
|
+
break;
|
|
311
|
+
case "register":
|
|
312
|
+
await cmdRegister(args);
|
|
313
|
+
break;
|
|
314
|
+
case "setup-payment":
|
|
315
|
+
await cmdSetupPayment(args);
|
|
316
|
+
break;
|
|
317
|
+
case "me":
|
|
318
|
+
await cmdMe(args);
|
|
319
|
+
break;
|
|
320
|
+
case "--help":
|
|
321
|
+
case "-h":
|
|
322
|
+
case "help":
|
|
323
|
+
case void 0:
|
|
324
|
+
console.log(HELP);
|
|
325
|
+
break;
|
|
326
|
+
default:
|
|
327
|
+
console.error(`Unknown command: ${command}`);
|
|
328
|
+
console.log(HELP);
|
|
329
|
+
process.exit(1);
|
|
330
|
+
}
|
|
331
|
+
} catch (e) {
|
|
332
|
+
if (e instanceof BoostedTravelError) {
|
|
333
|
+
console.error(`Error: ${e.message}`);
|
|
334
|
+
process.exit(1);
|
|
335
|
+
}
|
|
336
|
+
throw e;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
main();
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BoostedTravel — Agent-native flight search & booking SDK for Node.js/TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* Zero external dependencies. Uses native fetch (Node 18+).
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { BoostedTravel } from 'boostedtravel';
|
|
9
|
+
*
|
|
10
|
+
* const bt = new BoostedTravel({ apiKey: 'trav_...' });
|
|
11
|
+
* const flights = await bt.search('GDN', 'BER', '2026-03-03');
|
|
12
|
+
* console.log(flights.offers[0]);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
interface FlightSegment {
|
|
16
|
+
airline: string;
|
|
17
|
+
airline_name: string;
|
|
18
|
+
flight_no: string;
|
|
19
|
+
origin: string;
|
|
20
|
+
destination: string;
|
|
21
|
+
origin_city: string;
|
|
22
|
+
destination_city: string;
|
|
23
|
+
departure: string;
|
|
24
|
+
arrival: string;
|
|
25
|
+
duration_seconds: number;
|
|
26
|
+
cabin_class: string;
|
|
27
|
+
aircraft: string;
|
|
28
|
+
}
|
|
29
|
+
interface FlightRoute {
|
|
30
|
+
segments: FlightSegment[];
|
|
31
|
+
total_duration_seconds: number;
|
|
32
|
+
stopovers: number;
|
|
33
|
+
}
|
|
34
|
+
interface FlightOffer {
|
|
35
|
+
id: string;
|
|
36
|
+
price: number;
|
|
37
|
+
currency: string;
|
|
38
|
+
price_formatted: string;
|
|
39
|
+
outbound: FlightRoute;
|
|
40
|
+
inbound: FlightRoute | null;
|
|
41
|
+
airlines: string[];
|
|
42
|
+
owner_airline: string;
|
|
43
|
+
bags_price: Record<string, number>;
|
|
44
|
+
availability_seats: number | null;
|
|
45
|
+
conditions: Record<string, string>;
|
|
46
|
+
is_locked: boolean;
|
|
47
|
+
fetched_at: string;
|
|
48
|
+
booking_url: string;
|
|
49
|
+
}
|
|
50
|
+
interface FlightSearchResult {
|
|
51
|
+
search_id: string;
|
|
52
|
+
offer_request_id: string;
|
|
53
|
+
passenger_ids: string[];
|
|
54
|
+
origin: string;
|
|
55
|
+
destination: string;
|
|
56
|
+
currency: string;
|
|
57
|
+
offers: FlightOffer[];
|
|
58
|
+
total_results: number;
|
|
59
|
+
search_params: Record<string, unknown>;
|
|
60
|
+
pricing_note: string;
|
|
61
|
+
}
|
|
62
|
+
interface UnlockResult {
|
|
63
|
+
offer_id: string;
|
|
64
|
+
unlock_status: string;
|
|
65
|
+
payment_charged: boolean;
|
|
66
|
+
payment_amount_cents: number;
|
|
67
|
+
payment_currency: string;
|
|
68
|
+
payment_intent_id: string;
|
|
69
|
+
confirmed_price: number | null;
|
|
70
|
+
confirmed_currency: string;
|
|
71
|
+
offer_expires_at: string;
|
|
72
|
+
message: string;
|
|
73
|
+
}
|
|
74
|
+
interface Passenger {
|
|
75
|
+
id: string;
|
|
76
|
+
given_name: string;
|
|
77
|
+
family_name: string;
|
|
78
|
+
born_on: string;
|
|
79
|
+
gender?: string;
|
|
80
|
+
title?: string;
|
|
81
|
+
email?: string;
|
|
82
|
+
phone_number?: string;
|
|
83
|
+
}
|
|
84
|
+
interface BookingResult {
|
|
85
|
+
booking_id: string;
|
|
86
|
+
status: string;
|
|
87
|
+
booking_type: string;
|
|
88
|
+
offer_id: string;
|
|
89
|
+
flight_price: number;
|
|
90
|
+
service_fee: number;
|
|
91
|
+
service_fee_percentage: number;
|
|
92
|
+
total_charged: number;
|
|
93
|
+
currency: string;
|
|
94
|
+
order_id: string;
|
|
95
|
+
booking_reference: string;
|
|
96
|
+
unlock_payment_id: string;
|
|
97
|
+
fee_payment_id: string;
|
|
98
|
+
created_at: string;
|
|
99
|
+
details: Record<string, unknown>;
|
|
100
|
+
}
|
|
101
|
+
interface SearchOptions {
|
|
102
|
+
returnDate?: string;
|
|
103
|
+
adults?: number;
|
|
104
|
+
children?: number;
|
|
105
|
+
infants?: number;
|
|
106
|
+
cabinClass?: 'M' | 'W' | 'C' | 'F';
|
|
107
|
+
maxStopovers?: number;
|
|
108
|
+
currency?: string;
|
|
109
|
+
limit?: number;
|
|
110
|
+
sort?: 'price' | 'duration';
|
|
111
|
+
}
|
|
112
|
+
interface BoostedTravelConfig {
|
|
113
|
+
apiKey?: string;
|
|
114
|
+
baseUrl?: string;
|
|
115
|
+
timeout?: number;
|
|
116
|
+
}
|
|
117
|
+
declare class BoostedTravelError extends Error {
|
|
118
|
+
statusCode: number;
|
|
119
|
+
response: Record<string, unknown>;
|
|
120
|
+
constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
|
|
121
|
+
}
|
|
122
|
+
declare class AuthenticationError extends BoostedTravelError {
|
|
123
|
+
constructor(message: string, response?: Record<string, unknown>);
|
|
124
|
+
}
|
|
125
|
+
declare class PaymentRequiredError extends BoostedTravelError {
|
|
126
|
+
constructor(message: string, response?: Record<string, unknown>);
|
|
127
|
+
}
|
|
128
|
+
/** One-line offer summary */
|
|
129
|
+
declare function offerSummary(offer: FlightOffer): string;
|
|
130
|
+
/** Get cheapest offer from search results */
|
|
131
|
+
declare function cheapestOffer(result: FlightSearchResult): FlightOffer | null;
|
|
132
|
+
declare class BoostedTravel {
|
|
133
|
+
private apiKey;
|
|
134
|
+
private baseUrl;
|
|
135
|
+
private timeout;
|
|
136
|
+
constructor(config?: BoostedTravelConfig);
|
|
137
|
+
/**
|
|
138
|
+
* Search for flights — FREE, unlimited.
|
|
139
|
+
*
|
|
140
|
+
* @param origin - IATA code (e.g., "GDN", "LON")
|
|
141
|
+
* @param destination - IATA code (e.g., "BER", "BCN")
|
|
142
|
+
* @param dateFrom - Departure date "YYYY-MM-DD"
|
|
143
|
+
* @param options - Optional search parameters
|
|
144
|
+
*/
|
|
145
|
+
search(origin: string, destination: string, dateFrom: string, options?: SearchOptions): Promise<FlightSearchResult>;
|
|
146
|
+
/**
|
|
147
|
+
* Resolve a city/airport name to IATA codes.
|
|
148
|
+
*/
|
|
149
|
+
resolveLocation(query: string): Promise<Array<Record<string, unknown>>>;
|
|
150
|
+
/**
|
|
151
|
+
* Unlock a flight offer — $1 fee.
|
|
152
|
+
* Confirms price, reserves for 30 minutes.
|
|
153
|
+
*/
|
|
154
|
+
unlock(offerId: string): Promise<UnlockResult>;
|
|
155
|
+
/**
|
|
156
|
+
* Book a flight — 2.5% service fee.
|
|
157
|
+
* Creates a real airline reservation with PNR.
|
|
158
|
+
*/
|
|
159
|
+
book(offerId: string, passengers: Passenger[], contactEmail: string, contactPhone?: string): Promise<BookingResult>;
|
|
160
|
+
/**
|
|
161
|
+
* Set up payment method (payment token).
|
|
162
|
+
*/
|
|
163
|
+
setupPayment(token?: string): Promise<Record<string, unknown>>;
|
|
164
|
+
/**
|
|
165
|
+
* Get current agent profile and usage stats.
|
|
166
|
+
*/
|
|
167
|
+
me(): Promise<Record<string, unknown>>;
|
|
168
|
+
/**
|
|
169
|
+
* Register a new agent — no API key needed.
|
|
170
|
+
*/
|
|
171
|
+
static register(agentName: string, email: string, baseUrl?: string, ownerName?: string, description?: string): Promise<Record<string, unknown>>;
|
|
172
|
+
private post;
|
|
173
|
+
private get;
|
|
174
|
+
private request;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export { AuthenticationError, type BookingResult, BoostedTravel, type BoostedTravelConfig, BoostedTravelError, type FlightOffer, type FlightRoute, type FlightSearchResult, type FlightSegment, type Passenger, PaymentRequiredError, type SearchOptions, type UnlockResult, cheapestOffer, BoostedTravel as default, offerSummary };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BoostedTravel — Agent-native flight search & booking SDK for Node.js/TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* Zero external dependencies. Uses native fetch (Node 18+).
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { BoostedTravel } from 'boostedtravel';
|
|
9
|
+
*
|
|
10
|
+
* const bt = new BoostedTravel({ apiKey: 'trav_...' });
|
|
11
|
+
* const flights = await bt.search('GDN', 'BER', '2026-03-03');
|
|
12
|
+
* console.log(flights.offers[0]);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
interface FlightSegment {
|
|
16
|
+
airline: string;
|
|
17
|
+
airline_name: string;
|
|
18
|
+
flight_no: string;
|
|
19
|
+
origin: string;
|
|
20
|
+
destination: string;
|
|
21
|
+
origin_city: string;
|
|
22
|
+
destination_city: string;
|
|
23
|
+
departure: string;
|
|
24
|
+
arrival: string;
|
|
25
|
+
duration_seconds: number;
|
|
26
|
+
cabin_class: string;
|
|
27
|
+
aircraft: string;
|
|
28
|
+
}
|
|
29
|
+
interface FlightRoute {
|
|
30
|
+
segments: FlightSegment[];
|
|
31
|
+
total_duration_seconds: number;
|
|
32
|
+
stopovers: number;
|
|
33
|
+
}
|
|
34
|
+
interface FlightOffer {
|
|
35
|
+
id: string;
|
|
36
|
+
price: number;
|
|
37
|
+
currency: string;
|
|
38
|
+
price_formatted: string;
|
|
39
|
+
outbound: FlightRoute;
|
|
40
|
+
inbound: FlightRoute | null;
|
|
41
|
+
airlines: string[];
|
|
42
|
+
owner_airline: string;
|
|
43
|
+
bags_price: Record<string, number>;
|
|
44
|
+
availability_seats: number | null;
|
|
45
|
+
conditions: Record<string, string>;
|
|
46
|
+
is_locked: boolean;
|
|
47
|
+
fetched_at: string;
|
|
48
|
+
booking_url: string;
|
|
49
|
+
}
|
|
50
|
+
interface FlightSearchResult {
|
|
51
|
+
search_id: string;
|
|
52
|
+
offer_request_id: string;
|
|
53
|
+
passenger_ids: string[];
|
|
54
|
+
origin: string;
|
|
55
|
+
destination: string;
|
|
56
|
+
currency: string;
|
|
57
|
+
offers: FlightOffer[];
|
|
58
|
+
total_results: number;
|
|
59
|
+
search_params: Record<string, unknown>;
|
|
60
|
+
pricing_note: string;
|
|
61
|
+
}
|
|
62
|
+
interface UnlockResult {
|
|
63
|
+
offer_id: string;
|
|
64
|
+
unlock_status: string;
|
|
65
|
+
payment_charged: boolean;
|
|
66
|
+
payment_amount_cents: number;
|
|
67
|
+
payment_currency: string;
|
|
68
|
+
payment_intent_id: string;
|
|
69
|
+
confirmed_price: number | null;
|
|
70
|
+
confirmed_currency: string;
|
|
71
|
+
offer_expires_at: string;
|
|
72
|
+
message: string;
|
|
73
|
+
}
|
|
74
|
+
interface Passenger {
|
|
75
|
+
id: string;
|
|
76
|
+
given_name: string;
|
|
77
|
+
family_name: string;
|
|
78
|
+
born_on: string;
|
|
79
|
+
gender?: string;
|
|
80
|
+
title?: string;
|
|
81
|
+
email?: string;
|
|
82
|
+
phone_number?: string;
|
|
83
|
+
}
|
|
84
|
+
interface BookingResult {
|
|
85
|
+
booking_id: string;
|
|
86
|
+
status: string;
|
|
87
|
+
booking_type: string;
|
|
88
|
+
offer_id: string;
|
|
89
|
+
flight_price: number;
|
|
90
|
+
service_fee: number;
|
|
91
|
+
service_fee_percentage: number;
|
|
92
|
+
total_charged: number;
|
|
93
|
+
currency: string;
|
|
94
|
+
order_id: string;
|
|
95
|
+
booking_reference: string;
|
|
96
|
+
unlock_payment_id: string;
|
|
97
|
+
fee_payment_id: string;
|
|
98
|
+
created_at: string;
|
|
99
|
+
details: Record<string, unknown>;
|
|
100
|
+
}
|
|
101
|
+
interface SearchOptions {
|
|
102
|
+
returnDate?: string;
|
|
103
|
+
adults?: number;
|
|
104
|
+
children?: number;
|
|
105
|
+
infants?: number;
|
|
106
|
+
cabinClass?: 'M' | 'W' | 'C' | 'F';
|
|
107
|
+
maxStopovers?: number;
|
|
108
|
+
currency?: string;
|
|
109
|
+
limit?: number;
|
|
110
|
+
sort?: 'price' | 'duration';
|
|
111
|
+
}
|
|
112
|
+
interface BoostedTravelConfig {
|
|
113
|
+
apiKey?: string;
|
|
114
|
+
baseUrl?: string;
|
|
115
|
+
timeout?: number;
|
|
116
|
+
}
|
|
117
|
+
declare class BoostedTravelError extends Error {
|
|
118
|
+
statusCode: number;
|
|
119
|
+
response: Record<string, unknown>;
|
|
120
|
+
constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
|
|
121
|
+
}
|
|
122
|
+
declare class AuthenticationError extends BoostedTravelError {
|
|
123
|
+
constructor(message: string, response?: Record<string, unknown>);
|
|
124
|
+
}
|
|
125
|
+
declare class PaymentRequiredError extends BoostedTravelError {
|
|
126
|
+
constructor(message: string, response?: Record<string, unknown>);
|
|
127
|
+
}
|
|
128
|
+
/** One-line offer summary */
|
|
129
|
+
declare function offerSummary(offer: FlightOffer): string;
|
|
130
|
+
/** Get cheapest offer from search results */
|
|
131
|
+
declare function cheapestOffer(result: FlightSearchResult): FlightOffer | null;
|
|
132
|
+
declare class BoostedTravel {
|
|
133
|
+
private apiKey;
|
|
134
|
+
private baseUrl;
|
|
135
|
+
private timeout;
|
|
136
|
+
constructor(config?: BoostedTravelConfig);
|
|
137
|
+
/**
|
|
138
|
+
* Search for flights — FREE, unlimited.
|
|
139
|
+
*
|
|
140
|
+
* @param origin - IATA code (e.g., "GDN", "LON")
|
|
141
|
+
* @param destination - IATA code (e.g., "BER", "BCN")
|
|
142
|
+
* @param dateFrom - Departure date "YYYY-MM-DD"
|
|
143
|
+
* @param options - Optional search parameters
|
|
144
|
+
*/
|
|
145
|
+
search(origin: string, destination: string, dateFrom: string, options?: SearchOptions): Promise<FlightSearchResult>;
|
|
146
|
+
/**
|
|
147
|
+
* Resolve a city/airport name to IATA codes.
|
|
148
|
+
*/
|
|
149
|
+
resolveLocation(query: string): Promise<Array<Record<string, unknown>>>;
|
|
150
|
+
/**
|
|
151
|
+
* Unlock a flight offer — $1 fee.
|
|
152
|
+
* Confirms price, reserves for 30 minutes.
|
|
153
|
+
*/
|
|
154
|
+
unlock(offerId: string): Promise<UnlockResult>;
|
|
155
|
+
/**
|
|
156
|
+
* Book a flight — 2.5% service fee.
|
|
157
|
+
* Creates a real airline reservation with PNR.
|
|
158
|
+
*/
|
|
159
|
+
book(offerId: string, passengers: Passenger[], contactEmail: string, contactPhone?: string): Promise<BookingResult>;
|
|
160
|
+
/**
|
|
161
|
+
* Set up payment method (payment token).
|
|
162
|
+
*/
|
|
163
|
+
setupPayment(token?: string): Promise<Record<string, unknown>>;
|
|
164
|
+
/**
|
|
165
|
+
* Get current agent profile and usage stats.
|
|
166
|
+
*/
|
|
167
|
+
me(): Promise<Record<string, unknown>>;
|
|
168
|
+
/**
|
|
169
|
+
* Register a new agent — no API key needed.
|
|
170
|
+
*/
|
|
171
|
+
static register(agentName: string, email: string, baseUrl?: string, ownerName?: string, description?: string): Promise<Record<string, unknown>>;
|
|
172
|
+
private post;
|
|
173
|
+
private get;
|
|
174
|
+
private request;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export { AuthenticationError, type BookingResult, BoostedTravel, type BoostedTravelConfig, BoostedTravelError, type FlightOffer, type FlightRoute, type FlightSearchResult, type FlightSegment, type Passenger, PaymentRequiredError, type SearchOptions, type UnlockResult, cheapestOffer, BoostedTravel as default, offerSummary };
|