boostedtravel 0.1.0 → 0.2.1
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 +2 -2
- package/dist/{chunk-GIJTJ3JU.mjs → chunk-AVADUS2V.mjs} +59 -2
- package/dist/cli.js +13 -5
- package/dist/cli.mjs +4 -4
- package/dist/index.d.mts +21 -5
- package/dist/index.d.ts +21 -5
- package/dist/index.js +74 -4
- package/dist/index.mjs +6 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# BoostedTravel — Agent-Native Flight Search & Booking (Node.js)
|
|
2
2
|
|
|
3
|
-
Search
|
|
3
|
+
Search 400+ airlines at raw airline prices — **$20-50 cheaper** than Booking.com, Kayak, and other OTAs. Zero dependencies. Built for autonomous AI agents.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -28,7 +28,7 @@ console.log(offerSummary(best));
|
|
|
28
28
|
// Unlock — $1
|
|
29
29
|
const unlock = await bt.unlock(best.id);
|
|
30
30
|
|
|
31
|
-
// Book —
|
|
31
|
+
// Book — FREE after unlock
|
|
32
32
|
const booking = await bt.book(
|
|
33
33
|
best.id,
|
|
34
34
|
[{
|
|
@@ -41,6 +41,54 @@ function cheapestOffer(result) {
|
|
|
41
41
|
if (!result.offers.length) return null;
|
|
42
42
|
return result.offers.reduce((min, o) => o.price < min.price ? o : min, result.offers[0]);
|
|
43
43
|
}
|
|
44
|
+
async function searchLocal(origin, destination, dateFrom, options = {}) {
|
|
45
|
+
const { spawn } = await import("child_process");
|
|
46
|
+
const params = JSON.stringify({
|
|
47
|
+
origin: origin.toUpperCase(),
|
|
48
|
+
destination: destination.toUpperCase(),
|
|
49
|
+
date_from: dateFrom,
|
|
50
|
+
adults: options.adults ?? 1,
|
|
51
|
+
children: options.children ?? 0,
|
|
52
|
+
currency: options.currency ?? "EUR",
|
|
53
|
+
limit: options.limit ?? 50,
|
|
54
|
+
return_date: options.returnDate,
|
|
55
|
+
cabin_class: options.cabinClass
|
|
56
|
+
});
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
const pythonCmd = process.platform === "win32" ? "python" : "python3";
|
|
59
|
+
const child = spawn(pythonCmd, ["-m", "boostedtravel.local"], {
|
|
60
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
61
|
+
});
|
|
62
|
+
let stdout = "";
|
|
63
|
+
let stderr = "";
|
|
64
|
+
child.stdout.on("data", (d) => {
|
|
65
|
+
stdout += d.toString();
|
|
66
|
+
});
|
|
67
|
+
child.stderr.on("data", (d) => {
|
|
68
|
+
stderr += d.toString();
|
|
69
|
+
});
|
|
70
|
+
child.on("close", (code) => {
|
|
71
|
+
try {
|
|
72
|
+
const data = JSON.parse(stdout);
|
|
73
|
+
if (data.error) reject(new BoostedTravelError(data.error));
|
|
74
|
+
else resolve(data);
|
|
75
|
+
} catch {
|
|
76
|
+
reject(new BoostedTravelError(
|
|
77
|
+
`Python search failed (code ${code}): ${stdout || stderr}
|
|
78
|
+
Make sure boostedtravel is installed: pip install boostedtravel && playwright install chromium`
|
|
79
|
+
));
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
child.on("error", (err) => {
|
|
83
|
+
reject(new BoostedTravelError(
|
|
84
|
+
`Cannot start Python: ${err.message}
|
|
85
|
+
Install: pip install boostedtravel && playwright install chromium`
|
|
86
|
+
));
|
|
87
|
+
});
|
|
88
|
+
child.stdin.write(params);
|
|
89
|
+
child.stdin.end();
|
|
90
|
+
});
|
|
91
|
+
}
|
|
44
92
|
var DEFAULT_BASE_URL = "https://api.boostedchat.com";
|
|
45
93
|
var BoostedTravel = class {
|
|
46
94
|
apiKey;
|
|
@@ -50,9 +98,11 @@ var BoostedTravel = class {
|
|
|
50
98
|
this.apiKey = config.apiKey || process.env.BOOSTEDTRAVEL_API_KEY || "";
|
|
51
99
|
this.baseUrl = (config.baseUrl || process.env.BOOSTEDTRAVEL_BASE_URL || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
52
100
|
this.timeout = config.timeout || 3e4;
|
|
101
|
+
}
|
|
102
|
+
requireApiKey() {
|
|
53
103
|
if (!this.apiKey) {
|
|
54
104
|
throw new AuthenticationError(
|
|
55
|
-
"API key required. Set apiKey in config or BOOSTEDTRAVEL_API_KEY env var
|
|
105
|
+
"API key required for this operation. Set apiKey in config or BOOSTEDTRAVEL_API_KEY env var.\nNote: searchLocal() works without an API key."
|
|
56
106
|
);
|
|
57
107
|
}
|
|
58
108
|
}
|
|
@@ -66,6 +116,7 @@ var BoostedTravel = class {
|
|
|
66
116
|
* @param options - Optional search parameters
|
|
67
117
|
*/
|
|
68
118
|
async search(origin, destination, dateFrom, options = {}) {
|
|
119
|
+
this.requireApiKey();
|
|
69
120
|
const body = {
|
|
70
121
|
origin: origin.toUpperCase(),
|
|
71
122
|
destination: destination.toUpperCase(),
|
|
@@ -86,6 +137,7 @@ var BoostedTravel = class {
|
|
|
86
137
|
* Resolve a city/airport name to IATA codes.
|
|
87
138
|
*/
|
|
88
139
|
async resolveLocation(query) {
|
|
140
|
+
this.requireApiKey();
|
|
89
141
|
const data = await this.get(`/api/v1/flights/locations/${encodeURIComponent(query)}`);
|
|
90
142
|
if (Array.isArray(data)) return data;
|
|
91
143
|
if (data && Array.isArray(data.locations)) return data.locations;
|
|
@@ -96,13 +148,15 @@ var BoostedTravel = class {
|
|
|
96
148
|
* Confirms price, reserves for 30 minutes.
|
|
97
149
|
*/
|
|
98
150
|
async unlock(offerId) {
|
|
151
|
+
this.requireApiKey();
|
|
99
152
|
return this.post("/api/v1/bookings/unlock", { offer_id: offerId });
|
|
100
153
|
}
|
|
101
154
|
/**
|
|
102
|
-
* Book a flight —
|
|
155
|
+
* Book a flight — FREE after unlock.
|
|
103
156
|
* Creates a real airline reservation with PNR.
|
|
104
157
|
*/
|
|
105
158
|
async book(offerId, passengers, contactEmail, contactPhone = "") {
|
|
159
|
+
this.requireApiKey();
|
|
106
160
|
return this.post("/api/v1/bookings/book", {
|
|
107
161
|
offer_id: offerId,
|
|
108
162
|
booking_type: "flight",
|
|
@@ -115,12 +169,14 @@ var BoostedTravel = class {
|
|
|
115
169
|
* Set up payment method (payment token).
|
|
116
170
|
*/
|
|
117
171
|
async setupPayment(token = "tok_visa") {
|
|
172
|
+
this.requireApiKey();
|
|
118
173
|
return this.post("/api/v1/agents/setup-payment", { token });
|
|
119
174
|
}
|
|
120
175
|
/**
|
|
121
176
|
* Get current agent profile and usage stats.
|
|
122
177
|
*/
|
|
123
178
|
async me() {
|
|
179
|
+
this.requireApiKey();
|
|
124
180
|
return this.get("/api/v1/agents/me");
|
|
125
181
|
}
|
|
126
182
|
// ── Static methods ───────────────────────────────────────────────────
|
|
@@ -194,6 +250,7 @@ export {
|
|
|
194
250
|
PaymentRequiredError,
|
|
195
251
|
offerSummary,
|
|
196
252
|
cheapestOffer,
|
|
253
|
+
searchLocal,
|
|
197
254
|
BoostedTravel,
|
|
198
255
|
index_default
|
|
199
256
|
};
|
package/dist/cli.js
CHANGED
|
@@ -49,9 +49,11 @@ var BoostedTravel = class {
|
|
|
49
49
|
this.apiKey = config.apiKey || process.env.BOOSTEDTRAVEL_API_KEY || "";
|
|
50
50
|
this.baseUrl = (config.baseUrl || process.env.BOOSTEDTRAVEL_BASE_URL || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
51
51
|
this.timeout = config.timeout || 3e4;
|
|
52
|
+
}
|
|
53
|
+
requireApiKey() {
|
|
52
54
|
if (!this.apiKey) {
|
|
53
55
|
throw new AuthenticationError(
|
|
54
|
-
"API key required. Set apiKey in config or BOOSTEDTRAVEL_API_KEY env var
|
|
56
|
+
"API key required for this operation. Set apiKey in config or BOOSTEDTRAVEL_API_KEY env var.\nNote: searchLocal() works without an API key."
|
|
55
57
|
);
|
|
56
58
|
}
|
|
57
59
|
}
|
|
@@ -65,6 +67,7 @@ var BoostedTravel = class {
|
|
|
65
67
|
* @param options - Optional search parameters
|
|
66
68
|
*/
|
|
67
69
|
async search(origin, destination, dateFrom, options = {}) {
|
|
70
|
+
this.requireApiKey();
|
|
68
71
|
const body = {
|
|
69
72
|
origin: origin.toUpperCase(),
|
|
70
73
|
destination: destination.toUpperCase(),
|
|
@@ -85,6 +88,7 @@ var BoostedTravel = class {
|
|
|
85
88
|
* Resolve a city/airport name to IATA codes.
|
|
86
89
|
*/
|
|
87
90
|
async resolveLocation(query) {
|
|
91
|
+
this.requireApiKey();
|
|
88
92
|
const data = await this.get(`/api/v1/flights/locations/${encodeURIComponent(query)}`);
|
|
89
93
|
if (Array.isArray(data)) return data;
|
|
90
94
|
if (data && Array.isArray(data.locations)) return data.locations;
|
|
@@ -95,13 +99,15 @@ var BoostedTravel = class {
|
|
|
95
99
|
* Confirms price, reserves for 30 minutes.
|
|
96
100
|
*/
|
|
97
101
|
async unlock(offerId) {
|
|
102
|
+
this.requireApiKey();
|
|
98
103
|
return this.post("/api/v1/bookings/unlock", { offer_id: offerId });
|
|
99
104
|
}
|
|
100
105
|
/**
|
|
101
|
-
* Book a flight —
|
|
106
|
+
* Book a flight — FREE after unlock.
|
|
102
107
|
* Creates a real airline reservation with PNR.
|
|
103
108
|
*/
|
|
104
109
|
async book(offerId, passengers, contactEmail, contactPhone = "") {
|
|
110
|
+
this.requireApiKey();
|
|
105
111
|
return this.post("/api/v1/bookings/book", {
|
|
106
112
|
offer_id: offerId,
|
|
107
113
|
booking_type: "flight",
|
|
@@ -114,12 +120,14 @@ var BoostedTravel = class {
|
|
|
114
120
|
* Set up payment method (payment token).
|
|
115
121
|
*/
|
|
116
122
|
async setupPayment(token = "tok_visa") {
|
|
123
|
+
this.requireApiKey();
|
|
117
124
|
return this.post("/api/v1/agents/setup-payment", { token });
|
|
118
125
|
}
|
|
119
126
|
/**
|
|
120
127
|
* Get current agent profile and usage stats.
|
|
121
128
|
*/
|
|
122
129
|
async me() {
|
|
130
|
+
this.requireApiKey();
|
|
123
131
|
return this.get("/api/v1/agents/me");
|
|
124
132
|
}
|
|
125
133
|
// ── Static methods ───────────────────────────────────────────────────
|
|
@@ -449,14 +457,14 @@ async function cmdMe(args) {
|
|
|
449
457
|
var HELP = `
|
|
450
458
|
BoostedTravel \u2014 Agent-native flight search & booking.
|
|
451
459
|
|
|
452
|
-
Search
|
|
453
|
-
Search is FREE. Unlock: $1. Book:
|
|
460
|
+
Search 400+ airlines at raw airline prices \u2014 $20-50 cheaper than OTAs.
|
|
461
|
+
Search is FREE. Unlock: $1. Book: FREE after unlock.
|
|
454
462
|
|
|
455
463
|
Commands:
|
|
456
464
|
search <origin> <dest> <date> Search for flights (FREE)
|
|
457
465
|
locations <query> Resolve city name to IATA codes
|
|
458
466
|
unlock <offer_id> Unlock offer ($1)
|
|
459
|
-
book <offer_id> --passenger ... Book flight (
|
|
467
|
+
book <offer_id> --passenger ... Book flight (FREE after unlock)
|
|
460
468
|
register --name ... --email ... Register new agent
|
|
461
469
|
setup-payment Set up payment card
|
|
462
470
|
me Show agent profile
|
package/dist/cli.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
BoostedTravel,
|
|
4
4
|
BoostedTravelError,
|
|
5
5
|
offerSummary
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AVADUS2V.mjs";
|
|
7
7
|
|
|
8
8
|
// src/cli.ts
|
|
9
9
|
function getFlag(args, flag, alias) {
|
|
@@ -268,14 +268,14 @@ async function cmdMe(args) {
|
|
|
268
268
|
var HELP = `
|
|
269
269
|
BoostedTravel \u2014 Agent-native flight search & booking.
|
|
270
270
|
|
|
271
|
-
Search
|
|
272
|
-
Search is FREE. Unlock: $1. Book:
|
|
271
|
+
Search 400+ airlines at raw airline prices \u2014 $20-50 cheaper than OTAs.
|
|
272
|
+
Search is FREE. Unlock: $1. Book: FREE after unlock.
|
|
273
273
|
|
|
274
274
|
Commands:
|
|
275
275
|
search <origin> <dest> <date> Search for flights (FREE)
|
|
276
276
|
locations <query> Resolve city name to IATA codes
|
|
277
277
|
unlock <offer_id> Unlock offer ($1)
|
|
278
|
-
book <offer_id> --passenger ... Book flight (
|
|
278
|
+
book <offer_id> --passenger ... Book flight (FREE after unlock)
|
|
279
279
|
register --name ... --email ... Register new agent
|
|
280
280
|
setup-payment Set up payment card
|
|
281
281
|
me Show agent profile
|
package/dist/index.d.mts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* BoostedTravel — Agent-native flight search & booking SDK for Node.js/TypeScript.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* 48 LCC scrapers run locally via Python + backend API for premium sources.
|
|
5
|
+
* Zero external JS dependencies. Uses native fetch (Node 18+).
|
|
5
6
|
*
|
|
6
7
|
* @example
|
|
7
8
|
* ```ts
|
|
8
|
-
* import { BoostedTravel } from 'boostedtravel';
|
|
9
|
+
* import { BoostedTravel, searchLocal } from 'boostedtravel';
|
|
9
10
|
*
|
|
11
|
+
* // Local search — FREE, no API key
|
|
12
|
+
* const local = await searchLocal('SHA', 'CTU', '2026-03-20');
|
|
13
|
+
*
|
|
14
|
+
* // Full API — search + unlock + book
|
|
10
15
|
* const bt = new BoostedTravel({ apiKey: 'trav_...' });
|
|
11
16
|
* const flights = await bt.search('GDN', 'BER', '2026-03-03');
|
|
12
|
-
* console.log(flights.offers[0]);
|
|
13
17
|
* ```
|
|
14
18
|
*/
|
|
15
19
|
interface FlightSegment {
|
|
@@ -129,11 +133,23 @@ declare class PaymentRequiredError extends BoostedTravelError {
|
|
|
129
133
|
declare function offerSummary(offer: FlightOffer): string;
|
|
130
134
|
/** Get cheapest offer from search results */
|
|
131
135
|
declare function cheapestOffer(result: FlightSearchResult): FlightOffer | null;
|
|
136
|
+
/**
|
|
137
|
+
* Search flights using 48 local LCC scrapers — FREE, no API key needed.
|
|
138
|
+
*
|
|
139
|
+
* Requires: pip install boostedtravel && playwright install chromium
|
|
140
|
+
*
|
|
141
|
+
* @param origin - IATA code (e.g., "SHA")
|
|
142
|
+
* @param destination - IATA code (e.g., "CTU")
|
|
143
|
+
* @param dateFrom - Departure date "YYYY-MM-DD"
|
|
144
|
+
* @param options - Optional: currency, adults, limit, etc.
|
|
145
|
+
*/
|
|
146
|
+
declare function searchLocal(origin: string, destination: string, dateFrom: string, options?: Partial<SearchOptions>): Promise<FlightSearchResult>;
|
|
132
147
|
declare class BoostedTravel {
|
|
133
148
|
private apiKey;
|
|
134
149
|
private baseUrl;
|
|
135
150
|
private timeout;
|
|
136
151
|
constructor(config?: BoostedTravelConfig);
|
|
152
|
+
private requireApiKey;
|
|
137
153
|
/**
|
|
138
154
|
* Search for flights — FREE, unlimited.
|
|
139
155
|
*
|
|
@@ -153,7 +169,7 @@ declare class BoostedTravel {
|
|
|
153
169
|
*/
|
|
154
170
|
unlock(offerId: string): Promise<UnlockResult>;
|
|
155
171
|
/**
|
|
156
|
-
* Book a flight —
|
|
172
|
+
* Book a flight — FREE after unlock.
|
|
157
173
|
* Creates a real airline reservation with PNR.
|
|
158
174
|
*/
|
|
159
175
|
book(offerId: string, passengers: Passenger[], contactEmail: string, contactPhone?: string): Promise<BookingResult>;
|
|
@@ -174,4 +190,4 @@ declare class BoostedTravel {
|
|
|
174
190
|
private request;
|
|
175
191
|
}
|
|
176
192
|
|
|
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 };
|
|
193
|
+
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, searchLocal as localSearch, offerSummary, searchLocal };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* BoostedTravel — Agent-native flight search & booking SDK for Node.js/TypeScript.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* 48 LCC scrapers run locally via Python + backend API for premium sources.
|
|
5
|
+
* Zero external JS dependencies. Uses native fetch (Node 18+).
|
|
5
6
|
*
|
|
6
7
|
* @example
|
|
7
8
|
* ```ts
|
|
8
|
-
* import { BoostedTravel } from 'boostedtravel';
|
|
9
|
+
* import { BoostedTravel, searchLocal } from 'boostedtravel';
|
|
9
10
|
*
|
|
11
|
+
* // Local search — FREE, no API key
|
|
12
|
+
* const local = await searchLocal('SHA', 'CTU', '2026-03-20');
|
|
13
|
+
*
|
|
14
|
+
* // Full API — search + unlock + book
|
|
10
15
|
* const bt = new BoostedTravel({ apiKey: 'trav_...' });
|
|
11
16
|
* const flights = await bt.search('GDN', 'BER', '2026-03-03');
|
|
12
|
-
* console.log(flights.offers[0]);
|
|
13
17
|
* ```
|
|
14
18
|
*/
|
|
15
19
|
interface FlightSegment {
|
|
@@ -129,11 +133,23 @@ declare class PaymentRequiredError extends BoostedTravelError {
|
|
|
129
133
|
declare function offerSummary(offer: FlightOffer): string;
|
|
130
134
|
/** Get cheapest offer from search results */
|
|
131
135
|
declare function cheapestOffer(result: FlightSearchResult): FlightOffer | null;
|
|
136
|
+
/**
|
|
137
|
+
* Search flights using 48 local LCC scrapers — FREE, no API key needed.
|
|
138
|
+
*
|
|
139
|
+
* Requires: pip install boostedtravel && playwright install chromium
|
|
140
|
+
*
|
|
141
|
+
* @param origin - IATA code (e.g., "SHA")
|
|
142
|
+
* @param destination - IATA code (e.g., "CTU")
|
|
143
|
+
* @param dateFrom - Departure date "YYYY-MM-DD"
|
|
144
|
+
* @param options - Optional: currency, adults, limit, etc.
|
|
145
|
+
*/
|
|
146
|
+
declare function searchLocal(origin: string, destination: string, dateFrom: string, options?: Partial<SearchOptions>): Promise<FlightSearchResult>;
|
|
132
147
|
declare class BoostedTravel {
|
|
133
148
|
private apiKey;
|
|
134
149
|
private baseUrl;
|
|
135
150
|
private timeout;
|
|
136
151
|
constructor(config?: BoostedTravelConfig);
|
|
152
|
+
private requireApiKey;
|
|
137
153
|
/**
|
|
138
154
|
* Search for flights — FREE, unlimited.
|
|
139
155
|
*
|
|
@@ -153,7 +169,7 @@ declare class BoostedTravel {
|
|
|
153
169
|
*/
|
|
154
170
|
unlock(offerId: string): Promise<UnlockResult>;
|
|
155
171
|
/**
|
|
156
|
-
* Book a flight —
|
|
172
|
+
* Book a flight — FREE after unlock.
|
|
157
173
|
* Creates a real airline reservation with PNR.
|
|
158
174
|
*/
|
|
159
175
|
book(offerId: string, passengers: Passenger[], contactEmail: string, contactPhone?: string): Promise<BookingResult>;
|
|
@@ -174,4 +190,4 @@ declare class BoostedTravel {
|
|
|
174
190
|
private request;
|
|
175
191
|
}
|
|
176
192
|
|
|
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 };
|
|
193
|
+
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, searchLocal as localSearch, offerSummary, searchLocal };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -26,7 +36,9 @@ __export(index_exports, {
|
|
|
26
36
|
PaymentRequiredError: () => PaymentRequiredError,
|
|
27
37
|
cheapestOffer: () => cheapestOffer,
|
|
28
38
|
default: () => index_default,
|
|
29
|
-
|
|
39
|
+
localSearch: () => searchLocal,
|
|
40
|
+
offerSummary: () => offerSummary,
|
|
41
|
+
searchLocal: () => searchLocal
|
|
30
42
|
});
|
|
31
43
|
module.exports = __toCommonJS(index_exports);
|
|
32
44
|
var BoostedTravelError = class extends Error {
|
|
@@ -71,6 +83,54 @@ function cheapestOffer(result) {
|
|
|
71
83
|
if (!result.offers.length) return null;
|
|
72
84
|
return result.offers.reduce((min, o) => o.price < min.price ? o : min, result.offers[0]);
|
|
73
85
|
}
|
|
86
|
+
async function searchLocal(origin, destination, dateFrom, options = {}) {
|
|
87
|
+
const { spawn } = await import("child_process");
|
|
88
|
+
const params = JSON.stringify({
|
|
89
|
+
origin: origin.toUpperCase(),
|
|
90
|
+
destination: destination.toUpperCase(),
|
|
91
|
+
date_from: dateFrom,
|
|
92
|
+
adults: options.adults ?? 1,
|
|
93
|
+
children: options.children ?? 0,
|
|
94
|
+
currency: options.currency ?? "EUR",
|
|
95
|
+
limit: options.limit ?? 50,
|
|
96
|
+
return_date: options.returnDate,
|
|
97
|
+
cabin_class: options.cabinClass
|
|
98
|
+
});
|
|
99
|
+
return new Promise((resolve, reject) => {
|
|
100
|
+
const pythonCmd = process.platform === "win32" ? "python" : "python3";
|
|
101
|
+
const child = spawn(pythonCmd, ["-m", "boostedtravel.local"], {
|
|
102
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
103
|
+
});
|
|
104
|
+
let stdout = "";
|
|
105
|
+
let stderr = "";
|
|
106
|
+
child.stdout.on("data", (d) => {
|
|
107
|
+
stdout += d.toString();
|
|
108
|
+
});
|
|
109
|
+
child.stderr.on("data", (d) => {
|
|
110
|
+
stderr += d.toString();
|
|
111
|
+
});
|
|
112
|
+
child.on("close", (code) => {
|
|
113
|
+
try {
|
|
114
|
+
const data = JSON.parse(stdout);
|
|
115
|
+
if (data.error) reject(new BoostedTravelError(data.error));
|
|
116
|
+
else resolve(data);
|
|
117
|
+
} catch {
|
|
118
|
+
reject(new BoostedTravelError(
|
|
119
|
+
`Python search failed (code ${code}): ${stdout || stderr}
|
|
120
|
+
Make sure boostedtravel is installed: pip install boostedtravel && playwright install chromium`
|
|
121
|
+
));
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
child.on("error", (err) => {
|
|
125
|
+
reject(new BoostedTravelError(
|
|
126
|
+
`Cannot start Python: ${err.message}
|
|
127
|
+
Install: pip install boostedtravel && playwright install chromium`
|
|
128
|
+
));
|
|
129
|
+
});
|
|
130
|
+
child.stdin.write(params);
|
|
131
|
+
child.stdin.end();
|
|
132
|
+
});
|
|
133
|
+
}
|
|
74
134
|
var DEFAULT_BASE_URL = "https://api.boostedchat.com";
|
|
75
135
|
var BoostedTravel = class {
|
|
76
136
|
apiKey;
|
|
@@ -80,9 +140,11 @@ var BoostedTravel = class {
|
|
|
80
140
|
this.apiKey = config.apiKey || process.env.BOOSTEDTRAVEL_API_KEY || "";
|
|
81
141
|
this.baseUrl = (config.baseUrl || process.env.BOOSTEDTRAVEL_BASE_URL || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
82
142
|
this.timeout = config.timeout || 3e4;
|
|
143
|
+
}
|
|
144
|
+
requireApiKey() {
|
|
83
145
|
if (!this.apiKey) {
|
|
84
146
|
throw new AuthenticationError(
|
|
85
|
-
"API key required. Set apiKey in config or BOOSTEDTRAVEL_API_KEY env var
|
|
147
|
+
"API key required for this operation. Set apiKey in config or BOOSTEDTRAVEL_API_KEY env var.\nNote: searchLocal() works without an API key."
|
|
86
148
|
);
|
|
87
149
|
}
|
|
88
150
|
}
|
|
@@ -96,6 +158,7 @@ var BoostedTravel = class {
|
|
|
96
158
|
* @param options - Optional search parameters
|
|
97
159
|
*/
|
|
98
160
|
async search(origin, destination, dateFrom, options = {}) {
|
|
161
|
+
this.requireApiKey();
|
|
99
162
|
const body = {
|
|
100
163
|
origin: origin.toUpperCase(),
|
|
101
164
|
destination: destination.toUpperCase(),
|
|
@@ -116,6 +179,7 @@ var BoostedTravel = class {
|
|
|
116
179
|
* Resolve a city/airport name to IATA codes.
|
|
117
180
|
*/
|
|
118
181
|
async resolveLocation(query) {
|
|
182
|
+
this.requireApiKey();
|
|
119
183
|
const data = await this.get(`/api/v1/flights/locations/${encodeURIComponent(query)}`);
|
|
120
184
|
if (Array.isArray(data)) return data;
|
|
121
185
|
if (data && Array.isArray(data.locations)) return data.locations;
|
|
@@ -126,13 +190,15 @@ var BoostedTravel = class {
|
|
|
126
190
|
* Confirms price, reserves for 30 minutes.
|
|
127
191
|
*/
|
|
128
192
|
async unlock(offerId) {
|
|
193
|
+
this.requireApiKey();
|
|
129
194
|
return this.post("/api/v1/bookings/unlock", { offer_id: offerId });
|
|
130
195
|
}
|
|
131
196
|
/**
|
|
132
|
-
* Book a flight —
|
|
197
|
+
* Book a flight — FREE after unlock.
|
|
133
198
|
* Creates a real airline reservation with PNR.
|
|
134
199
|
*/
|
|
135
200
|
async book(offerId, passengers, contactEmail, contactPhone = "") {
|
|
201
|
+
this.requireApiKey();
|
|
136
202
|
return this.post("/api/v1/bookings/book", {
|
|
137
203
|
offer_id: offerId,
|
|
138
204
|
booking_type: "flight",
|
|
@@ -145,12 +211,14 @@ var BoostedTravel = class {
|
|
|
145
211
|
* Set up payment method (payment token).
|
|
146
212
|
*/
|
|
147
213
|
async setupPayment(token = "tok_visa") {
|
|
214
|
+
this.requireApiKey();
|
|
148
215
|
return this.post("/api/v1/agents/setup-payment", { token });
|
|
149
216
|
}
|
|
150
217
|
/**
|
|
151
218
|
* Get current agent profile and usage stats.
|
|
152
219
|
*/
|
|
153
220
|
async me() {
|
|
221
|
+
this.requireApiKey();
|
|
154
222
|
return this.get("/api/v1/agents/me");
|
|
155
223
|
}
|
|
156
224
|
// ── Static methods ───────────────────────────────────────────────────
|
|
@@ -224,5 +292,7 @@ var index_default = BoostedTravel;
|
|
|
224
292
|
BoostedTravelError,
|
|
225
293
|
PaymentRequiredError,
|
|
226
294
|
cheapestOffer,
|
|
227
|
-
|
|
295
|
+
localSearch,
|
|
296
|
+
offerSummary,
|
|
297
|
+
searchLocal
|
|
228
298
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -5,8 +5,9 @@ import {
|
|
|
5
5
|
PaymentRequiredError,
|
|
6
6
|
cheapestOffer,
|
|
7
7
|
index_default,
|
|
8
|
-
offerSummary
|
|
9
|
-
|
|
8
|
+
offerSummary,
|
|
9
|
+
searchLocal
|
|
10
|
+
} from "./chunk-AVADUS2V.mjs";
|
|
10
11
|
export {
|
|
11
12
|
AuthenticationError,
|
|
12
13
|
BoostedTravel,
|
|
@@ -14,5 +15,7 @@ export {
|
|
|
14
15
|
PaymentRequiredError,
|
|
15
16
|
cheapestOffer,
|
|
16
17
|
index_default as default,
|
|
17
|
-
|
|
18
|
+
searchLocal as localSearch,
|
|
19
|
+
offerSummary,
|
|
20
|
+
searchLocal
|
|
18
21
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "boostedtravel",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"description": "Agent-native flight search & booking.
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Agent-native flight search & booking. 48 LCC scrapers run locally + GDS/NDC APIs. Built for autonomous AI agents.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|