google-fli 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/LICENSE +21 -0
- package/README.md +158 -0
- package/dist/core/airports.d.ts +31 -0
- package/dist/core/airports.d.ts.map +1 -0
- package/dist/core/airports.js +168 -0
- package/dist/core/airports.js.map +1 -0
- package/dist/core/builders.d.ts +30 -0
- package/dist/core/builders.d.ts.map +1 -0
- package/dist/core/builders.js +113 -0
- package/dist/core/builders.js.map +1 -0
- package/dist/core/currency.d.ts +21 -0
- package/dist/core/currency.d.ts.map +1 -0
- package/dist/core/currency.js +172 -0
- package/dist/core/currency.js.map +1 -0
- package/dist/core/dates.d.ts +22 -0
- package/dist/core/dates.d.ts.map +1 -0
- package/dist/core/dates.js +41 -0
- package/dist/core/dates.js.map +1 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/links.d.ts +39 -0
- package/dist/core/links.d.ts.map +1 -0
- package/dist/core/links.js +53 -0
- package/dist/core/links.js.map +1 -0
- package/dist/core/parsers.d.ts +34 -0
- package/dist/core/parsers.d.ts.map +1 -0
- package/dist/core/parsers.js +161 -0
- package/dist/core/parsers.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/models/airline.d.ts +1120 -0
- package/dist/models/airline.d.ts.map +1 -0
- package/dist/models/airline.js +2224 -0
- package/dist/models/airline.js.map +1 -0
- package/dist/models/airport.d.ts +7899 -0
- package/dist/models/airport.d.ts.map +1 -0
- package/dist/models/airport.js +15782 -0
- package/dist/models/airport.js.map +1 -0
- package/dist/models/google-flights/base.d.ts +232 -0
- package/dist/models/google-flights/base.d.ts.map +1 -0
- package/dist/models/google-flights/base.js +188 -0
- package/dist/models/google-flights/base.js.map +1 -0
- package/dist/models/google-flights/dates.d.ts +51 -0
- package/dist/models/google-flights/dates.d.ts.map +1 -0
- package/dist/models/google-flights/dates.js +222 -0
- package/dist/models/google-flights/dates.js.map +1 -0
- package/dist/models/google-flights/flights.d.ts +57 -0
- package/dist/models/google-flights/flights.d.ts.map +1 -0
- package/dist/models/google-flights/flights.js +224 -0
- package/dist/models/google-flights/flights.js.map +1 -0
- package/dist/models/google-flights/index.d.ts +4 -0
- package/dist/models/google-flights/index.d.ts.map +1 -0
- package/dist/models/google-flights/index.js +4 -0
- package/dist/models/google-flights/index.js.map +1 -0
- package/dist/models/index.d.ts +4 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +4 -0
- package/dist/models/index.js.map +1 -0
- package/dist/search/client.d.ts +66 -0
- package/dist/search/client.d.ts.map +1 -0
- package/dist/search/client.js +205 -0
- package/dist/search/client.js.map +1 -0
- package/dist/search/concurrency.d.ts +45 -0
- package/dist/search/concurrency.d.ts.map +1 -0
- package/dist/search/concurrency.js +148 -0
- package/dist/search/concurrency.js.map +1 -0
- package/dist/search/dates.d.ts +33 -0
- package/dist/search/dates.d.ts.map +1 -0
- package/dist/search/dates.js +159 -0
- package/dist/search/dates.js.map +1 -0
- package/dist/search/decoders.d.ts +22 -0
- package/dist/search/decoders.d.ts.map +1 -0
- package/dist/search/decoders.js +333 -0
- package/dist/search/decoders.js.map +1 -0
- package/dist/search/exceptions.d.ts +21 -0
- package/dist/search/exceptions.d.ts.map +1 -0
- package/dist/search/exceptions.js +37 -0
- package/dist/search/exceptions.js.map +1 -0
- package/dist/search/flights.d.ts +57 -0
- package/dist/search/flights.d.ts.map +1 -0
- package/dist/search/flights.js +298 -0
- package/dist/search/flights.js.map +1 -0
- package/dist/search/helpers.d.ts +10 -0
- package/dist/search/helpers.d.ts.map +1 -0
- package/dist/search/helpers.js +30 -0
- package/dist/search/helpers.js.map +1 -0
- package/dist/search/index.d.ts +10 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +10 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/proto.d.ts +69 -0
- package/dist/search/proto.d.ts.map +1 -0
- package/dist/search/proto.js +355 -0
- package/dist/search/proto.js.map +1 -0
- package/dist/search/urls.d.ts +9 -0
- package/dist/search/urls.d.ts.map +1 -0
- package/dist/search/urls.js +9 -0
- package/dist/search/urls.js.map +1 -0
- package/dist/search/wire.d.ts +14 -0
- package/dist/search/wire.d.ts.map +1 -0
- package/dist/search/wire.js +120 -0
- package/dist/search/wire.js.map +1 -0
- package/package.json +91 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Currency extraction from Google Flights price tokens.
|
|
3
|
+
*
|
|
4
|
+
* 1:1 port of fli/core/currency.py — varint walk over a base64-urlsafe
|
|
5
|
+
* protobuf payload to extract the nested ISO currency code, cached to
|
|
6
|
+
* avoid repeated decoding for the common one-currency-per-response case.
|
|
7
|
+
*/
|
|
8
|
+
const _decodeCache = new Map();
|
|
9
|
+
const MAX_CACHE = 256;
|
|
10
|
+
function readVarint(data, offset) {
|
|
11
|
+
// `+= chunk * 2**shift` instead of `|= chunk << shift` — JavaScript's
|
|
12
|
+
// bitwise operators coerce to signed 32-bit and would corrupt the
|
|
13
|
+
// result for shifts ≥ 31 (i.e. varint values ≥ 2^31).
|
|
14
|
+
let value = 0;
|
|
15
|
+
let shift = 0;
|
|
16
|
+
let off = offset;
|
|
17
|
+
while (off < data.length) {
|
|
18
|
+
const byte = data[off];
|
|
19
|
+
if (byte === undefined)
|
|
20
|
+
break;
|
|
21
|
+
off += 1;
|
|
22
|
+
value += (byte & 0x7f) * 2 ** shift;
|
|
23
|
+
if ((byte & 0x80) === 0) {
|
|
24
|
+
if (!Number.isSafeInteger(value)) {
|
|
25
|
+
throw new Error("Varint exceeds Number.MAX_SAFE_INTEGER");
|
|
26
|
+
}
|
|
27
|
+
return [value, off];
|
|
28
|
+
}
|
|
29
|
+
shift += 7;
|
|
30
|
+
if (shift >= 64)
|
|
31
|
+
throw new Error("Varint is too large to decode");
|
|
32
|
+
}
|
|
33
|
+
throw new Error("Unexpected end of data while decoding varint");
|
|
34
|
+
}
|
|
35
|
+
function readLengthDelimited(data, offset) {
|
|
36
|
+
const [length, after] = readVarint(data, offset);
|
|
37
|
+
const end = after + length;
|
|
38
|
+
if (end > data.length)
|
|
39
|
+
throw new Error("Length-delimited field exceeds payload size");
|
|
40
|
+
return [data.subarray(after, end), end];
|
|
41
|
+
}
|
|
42
|
+
function skipField(data, offset, wireType) {
|
|
43
|
+
if (wireType === 0)
|
|
44
|
+
return readVarint(data, offset)[1];
|
|
45
|
+
if (wireType === 1) {
|
|
46
|
+
const end = offset + 8;
|
|
47
|
+
if (end > data.length)
|
|
48
|
+
throw new Error("Fixed64 field exceeds payload size");
|
|
49
|
+
return end;
|
|
50
|
+
}
|
|
51
|
+
if (wireType === 2)
|
|
52
|
+
return readLengthDelimited(data, offset)[1];
|
|
53
|
+
if (wireType === 5) {
|
|
54
|
+
const end = offset + 4;
|
|
55
|
+
if (end > data.length)
|
|
56
|
+
throw new Error("Fixed32 field exceeds payload size");
|
|
57
|
+
return end;
|
|
58
|
+
}
|
|
59
|
+
throw new Error(`Unsupported wire type: ${wireType}`);
|
|
60
|
+
}
|
|
61
|
+
function extractCurrencyFromMessage(data) {
|
|
62
|
+
let offset = 0;
|
|
63
|
+
while (offset < data.length) {
|
|
64
|
+
const [tag, afterTag] = readVarint(data, offset);
|
|
65
|
+
offset = afterTag;
|
|
66
|
+
const fieldNumber = tag >> 3;
|
|
67
|
+
const wireType = tag & 0x07;
|
|
68
|
+
if (fieldNumber === 3 && wireType === 2) {
|
|
69
|
+
const [nested, after] = readLengthDelimited(data, offset);
|
|
70
|
+
offset = after;
|
|
71
|
+
let nestedOffset = 0;
|
|
72
|
+
while (nestedOffset < nested.length) {
|
|
73
|
+
const [ntag, na] = readVarint(nested, nestedOffset);
|
|
74
|
+
nestedOffset = na;
|
|
75
|
+
const nfield = ntag >> 3;
|
|
76
|
+
const nwire = ntag & 0x07;
|
|
77
|
+
if (nfield === 3 && nwire === 2) {
|
|
78
|
+
const [bytes, _end] = readLengthDelimited(nested, nestedOffset);
|
|
79
|
+
return new TextDecoder("utf-8").decode(bytes).toUpperCase();
|
|
80
|
+
}
|
|
81
|
+
nestedOffset = skipField(nested, nestedOffset, nwire);
|
|
82
|
+
}
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
offset = skipField(data, offset, wireType);
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
function base64UrlsafeDecode(token) {
|
|
90
|
+
const padLen = (4 - (token.length % 4)) % 4;
|
|
91
|
+
const padded = token + "=".repeat(padLen);
|
|
92
|
+
const standard = padded.replace(/-/g, "+").replace(/_/g, "/");
|
|
93
|
+
if (typeof atob !== "undefined") {
|
|
94
|
+
const binary = atob(standard);
|
|
95
|
+
const out = new Uint8Array(binary.length);
|
|
96
|
+
for (let i = 0; i < binary.length; i++)
|
|
97
|
+
out[i] = binary.charCodeAt(i);
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
return new Uint8Array(Buffer.from(standard, "base64"));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Extract the ISO currency code from a Google Flights price token.
|
|
104
|
+
*
|
|
105
|
+
* Cached so the same token returned for every row in a response decodes
|
|
106
|
+
* the protobuf payload exactly once.
|
|
107
|
+
*/
|
|
108
|
+
export function extractCurrencyFromPriceToken(token) {
|
|
109
|
+
if (!token)
|
|
110
|
+
return null;
|
|
111
|
+
if (_decodeCache.has(token))
|
|
112
|
+
return _decodeCache.get(token) ?? null;
|
|
113
|
+
let result = null;
|
|
114
|
+
try {
|
|
115
|
+
const decoded = base64UrlsafeDecode(token);
|
|
116
|
+
result = extractCurrencyFromMessage(decoded);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
result = null;
|
|
120
|
+
}
|
|
121
|
+
// LRU-ish bound: drop oldest if we hit the cap.
|
|
122
|
+
if (_decodeCache.size >= MAX_CACHE) {
|
|
123
|
+
const firstKey = _decodeCache.keys().next().value;
|
|
124
|
+
if (firstKey !== undefined)
|
|
125
|
+
_decodeCache.delete(firstKey);
|
|
126
|
+
}
|
|
127
|
+
_decodeCache.set(token, result);
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
/** Currency-code-aware formatter built on `Intl.NumberFormat`. */
|
|
131
|
+
export function formatPrice(amount, currencyCode) {
|
|
132
|
+
if (amount == null) {
|
|
133
|
+
return currencyCode ? `${currencyCode.toUpperCase()} —` : "—";
|
|
134
|
+
}
|
|
135
|
+
if (!currencyCode) {
|
|
136
|
+
return amount.toLocaleString("en-US", {
|
|
137
|
+
minimumFractionDigits: 2,
|
|
138
|
+
maximumFractionDigits: 2,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const normalized = currencyCode.toUpperCase();
|
|
142
|
+
try {
|
|
143
|
+
return new Intl.NumberFormat("en-US", {
|
|
144
|
+
style: "currency",
|
|
145
|
+
currency: normalized,
|
|
146
|
+
}).format(amount);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return `${normalized} ${amount.toLocaleString("en-US", {
|
|
150
|
+
minimumFractionDigits: 2,
|
|
151
|
+
maximumFractionDigits: 2,
|
|
152
|
+
})}`;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Build a chart-axis label for one or more result currencies. */
|
|
156
|
+
export function formatPriceAxisLabel(currencies) {
|
|
157
|
+
const set = new Set();
|
|
158
|
+
for (const c of currencies) {
|
|
159
|
+
if (c)
|
|
160
|
+
set.add(c.toUpperCase());
|
|
161
|
+
}
|
|
162
|
+
if (set.size === 1) {
|
|
163
|
+
const [only] = set;
|
|
164
|
+
return `Price (${only})`;
|
|
165
|
+
}
|
|
166
|
+
return "Price";
|
|
167
|
+
}
|
|
168
|
+
/** Clear the in-memory token-decode cache (test helper). */
|
|
169
|
+
export function _clearCurrencyCache() {
|
|
170
|
+
_decodeCache.clear();
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=currency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currency.js","sourceRoot":"","sources":["../../src/core/currency.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared YYYY-MM-DD parsing and formatting helpers.
|
|
3
|
+
*
|
|
4
|
+
* Lives in `core/` so the same canonical implementation backs every part
|
|
5
|
+
* of the package — `models/google-flights/base.ts`, the date-search
|
|
6
|
+
* filters, and `search/dates.ts` — rather than each maintaining its own
|
|
7
|
+
* subtly-different copy.
|
|
8
|
+
*/
|
|
9
|
+
/** Strict YYYY-MM-DD shape (4 digit year, 2 digit month, 2 digit day). */
|
|
10
|
+
export declare const ISO_DATE_RE: RegExp;
|
|
11
|
+
/**
|
|
12
|
+
* Parse a YYYY-MM-DD string into a UTC `Date`.
|
|
13
|
+
*
|
|
14
|
+
* Rejects strings that don't match {@link ISO_DATE_RE} and rejects
|
|
15
|
+
* out-of-range calendar dates (e.g. `2026-02-30` would round-trip to
|
|
16
|
+
* March, so the round-trip check catches it). Throws {@link TypeError}
|
|
17
|
+
* on any malformed input — consistent with the rest of the package.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseIsoDate(s: string): Date;
|
|
20
|
+
/** Format a `Date` as YYYY-MM-DD in UTC. */
|
|
21
|
+
export declare function formatIsoDate(d: Date): string;
|
|
22
|
+
//# sourceMappingURL=dates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dates.d.ts","sourceRoot":"","sources":["../../src/core/dates.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,0EAA0E;AAC1E,eAAO,MAAM,WAAW,QAAwB,CAAC;AAEjD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAc5C;AAED,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAK7C"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared YYYY-MM-DD parsing and formatting helpers.
|
|
3
|
+
*
|
|
4
|
+
* Lives in `core/` so the same canonical implementation backs every part
|
|
5
|
+
* of the package — `models/google-flights/base.ts`, the date-search
|
|
6
|
+
* filters, and `search/dates.ts` — rather than each maintaining its own
|
|
7
|
+
* subtly-different copy.
|
|
8
|
+
*/
|
|
9
|
+
/** Strict YYYY-MM-DD shape (4 digit year, 2 digit month, 2 digit day). */
|
|
10
|
+
export const ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
11
|
+
/**
|
|
12
|
+
* Parse a YYYY-MM-DD string into a UTC `Date`.
|
|
13
|
+
*
|
|
14
|
+
* Rejects strings that don't match {@link ISO_DATE_RE} and rejects
|
|
15
|
+
* out-of-range calendar dates (e.g. `2026-02-30` would round-trip to
|
|
16
|
+
* March, so the round-trip check catches it). Throws {@link TypeError}
|
|
17
|
+
* on any malformed input — consistent with the rest of the package.
|
|
18
|
+
*/
|
|
19
|
+
export function parseIsoDate(s) {
|
|
20
|
+
if (!ISO_DATE_RE.test(s)) {
|
|
21
|
+
throw new TypeError(`Expected YYYY-MM-DD date, got: ${s}`);
|
|
22
|
+
}
|
|
23
|
+
const parts = s.split("-").map((p) => Number.parseInt(p, 10));
|
|
24
|
+
const [year, month, day] = parts;
|
|
25
|
+
if (year == null || month == null || day == null) {
|
|
26
|
+
throw new TypeError(`Expected YYYY-MM-DD date, got: ${s}`);
|
|
27
|
+
}
|
|
28
|
+
const d = new Date(Date.UTC(year, month - 1, day));
|
|
29
|
+
if (d.getUTCFullYear() !== year || d.getUTCMonth() !== month - 1 || d.getUTCDate() !== day) {
|
|
30
|
+
throw new TypeError(`Invalid date: ${s}`);
|
|
31
|
+
}
|
|
32
|
+
return d;
|
|
33
|
+
}
|
|
34
|
+
/** Format a `Date` as YYYY-MM-DD in UTC. */
|
|
35
|
+
export function formatIsoDate(d) {
|
|
36
|
+
const y = d.getUTCFullYear();
|
|
37
|
+
const m = String(d.getUTCMonth() + 1).padStart(2, "0");
|
|
38
|
+
const day = String(d.getUTCDate()).padStart(2, "0");
|
|
39
|
+
return `${y}-${m}-${day}`;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=dates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dates.js","sourceRoot":"","sources":["../../src/core/dates.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC;IACjC,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QACjD,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACnD,IAAI,CAAC,CAAC,cAAc,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,KAAK,GAAG,EAAE,CAAC;QAC3F,MAAM,IAAI,SAAS,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,aAAa,CAAC,CAAO;IACnC,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,CAAC;IAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { type AirportMatch, CITY_AIRPORTS, type MatchType, searchAirports, } from "./airports.ts";
|
|
2
|
+
export { buildDateSearchSegments, buildFlightSegments, buildMultiCitySegments, buildTimeRestrictions, normalizeDate, } from "./builders.ts";
|
|
3
|
+
export { _clearCurrencyCache, extractCurrencyFromPriceToken, formatPrice, formatPriceAxisLabel, } from "./currency.ts";
|
|
4
|
+
export { formatIsoDate, ISO_DATE_RE, parseIsoDate } from "./dates.ts";
|
|
5
|
+
export { type GoogleFlightsUrlOptions, googleFlightsUrl, withLocaleParams, } from "./links.ts";
|
|
6
|
+
export { ParseError, parseAirlines, parseAlliances, parseCabinClass, parseCurrency, parseEmissions, parseMaxStops, parseSortBy, parseTimeRange, resolveAirport, resolveEnum, } from "./parsers.ts";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,aAAa,EACb,KAAK,SAAS,EACd,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,WAAW,EACX,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,KAAK,uBAAuB,EAC5B,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,UAAU,EACV,aAAa,EACb,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,EACX,cAAc,EACd,cAAc,EACd,WAAW,GACZ,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { CITY_AIRPORTS, searchAirports, } from "./airports.js";
|
|
2
|
+
export { buildDateSearchSegments, buildFlightSegments, buildMultiCitySegments, buildTimeRestrictions, normalizeDate, } from "./builders.js";
|
|
3
|
+
export { _clearCurrencyCache, extractCurrencyFromPriceToken, formatPrice, formatPriceAxisLabel, } from "./currency.js";
|
|
4
|
+
export { formatIsoDate, ISO_DATE_RE, parseIsoDate } from "./dates.js";
|
|
5
|
+
export { googleFlightsUrl, withLocaleParams, } from "./links.js";
|
|
6
|
+
export { ParseError, parseAirlines, parseAlliances, parseCabinClass, parseCurrency, parseEmissions, parseMaxStops, parseSortBy, parseTimeRange, resolveAirport, resolveEnum, } from "./parsers.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EAEb,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,WAAW,EACX,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAEL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,UAAU,EACV,aAAa,EACb,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,EACX,cAAc,EACd,cAAc,EACd,WAAW,GACZ,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared URL helpers for Google Flights deep links.
|
|
3
|
+
*
|
|
4
|
+
* Consumers can surface a clickable Google Flights link alongside search
|
|
5
|
+
* results so a user can open the route (and complete a booking) in a
|
|
6
|
+
* browser. The natural-language `q` form used here is the same one Google's
|
|
7
|
+
* own frontend accepts.
|
|
8
|
+
*
|
|
9
|
+
* `withLocaleParams` lives here (rather than in `search/`) so the core layer
|
|
10
|
+
* stays free of any dependency on the search package; `search/urls.ts`
|
|
11
|
+
* re-exports it for backwards compatibility.
|
|
12
|
+
*
|
|
13
|
+
* 1:1 port of fli/core/links.py.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Append optional `curr`/`hl`/`gl` parameters to a URL.
|
|
17
|
+
*
|
|
18
|
+
* - `currency` is uppercased ("usd" → "USD") because Google rejects lowercase
|
|
19
|
+
* codes silently.
|
|
20
|
+
* - `language` is passed through verbatim (BCP-47).
|
|
21
|
+
* - `country` is uppercased (ISO 3166-1 alpha-2).
|
|
22
|
+
*
|
|
23
|
+
* All values are percent-encoded; returns `url` unchanged when all three are null.
|
|
24
|
+
*/
|
|
25
|
+
export declare function withLocaleParams(url: string, currency: string | null | undefined, language: string | null | undefined, country: string | null | undefined): string;
|
|
26
|
+
export interface GoogleFlightsUrlOptions {
|
|
27
|
+
currency?: string | null;
|
|
28
|
+
language?: string | null;
|
|
29
|
+
country?: string | null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build a shareable Google Flights deep link for a route and dates.
|
|
33
|
+
*
|
|
34
|
+
* `origin` and `destination` are bare IATA codes (e.g. `"JFK"`). The returned
|
|
35
|
+
* URL pre-fills the route and outbound date (plus the return date for round
|
|
36
|
+
* trips); locale knobs (`curr`/`hl`/`gl`) are appended when supplied.
|
|
37
|
+
*/
|
|
38
|
+
export declare function googleFlightsUrl(origin: string, destination: string, departureDate: string, returnDate?: string | null, options?: GoogleFlightsUrlOptions): string;
|
|
39
|
+
//# sourceMappingURL=links.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../src/core/links.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACjC,MAAM,CAQR;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,EAC1B,OAAO,GAAE,uBAA4B,GACpC,MAAM,CAUR"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared URL helpers for Google Flights deep links.
|
|
3
|
+
*
|
|
4
|
+
* Consumers can surface a clickable Google Flights link alongside search
|
|
5
|
+
* results so a user can open the route (and complete a booking) in a
|
|
6
|
+
* browser. The natural-language `q` form used here is the same one Google's
|
|
7
|
+
* own frontend accepts.
|
|
8
|
+
*
|
|
9
|
+
* `withLocaleParams` lives here (rather than in `search/`) so the core layer
|
|
10
|
+
* stays free of any dependency on the search package; `search/urls.ts`
|
|
11
|
+
* re-exports it for backwards compatibility.
|
|
12
|
+
*
|
|
13
|
+
* 1:1 port of fli/core/links.py.
|
|
14
|
+
*/
|
|
15
|
+
const GOOGLE_FLIGHTS_URL = "https://www.google.com/travel/flights";
|
|
16
|
+
/**
|
|
17
|
+
* Append optional `curr`/`hl`/`gl` parameters to a URL.
|
|
18
|
+
*
|
|
19
|
+
* - `currency` is uppercased ("usd" → "USD") because Google rejects lowercase
|
|
20
|
+
* codes silently.
|
|
21
|
+
* - `language` is passed through verbatim (BCP-47).
|
|
22
|
+
* - `country` is uppercased (ISO 3166-1 alpha-2).
|
|
23
|
+
*
|
|
24
|
+
* All values are percent-encoded; returns `url` unchanged when all three are null.
|
|
25
|
+
*/
|
|
26
|
+
export function withLocaleParams(url, currency, language, country) {
|
|
27
|
+
const params = [];
|
|
28
|
+
if (currency)
|
|
29
|
+
params.push(`curr=${encodeURIComponent(currency.toUpperCase())}`);
|
|
30
|
+
if (language)
|
|
31
|
+
params.push(`hl=${encodeURIComponent(language)}`);
|
|
32
|
+
if (country)
|
|
33
|
+
params.push(`gl=${encodeURIComponent(country.toUpperCase())}`);
|
|
34
|
+
if (params.length === 0)
|
|
35
|
+
return url;
|
|
36
|
+
const sep = url.includes("?") ? "&" : "?";
|
|
37
|
+
return `${url}${sep}${params.join("&")}`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build a shareable Google Flights deep link for a route and dates.
|
|
41
|
+
*
|
|
42
|
+
* `origin` and `destination` are bare IATA codes (e.g. `"JFK"`). The returned
|
|
43
|
+
* URL pre-fills the route and outbound date (plus the return date for round
|
|
44
|
+
* trips); locale knobs (`curr`/`hl`/`gl`) are appended when supplied.
|
|
45
|
+
*/
|
|
46
|
+
export function googleFlightsUrl(origin, destination, departureDate, returnDate, options = {}) {
|
|
47
|
+
let query = `Flights from ${origin} to ${destination} on ${departureDate}`;
|
|
48
|
+
if (returnDate)
|
|
49
|
+
query += ` through ${returnDate}`;
|
|
50
|
+
const url = `${GOOGLE_FLIGHTS_URL}?q=${encodeURIComponent(query)}`;
|
|
51
|
+
return withLocaleParams(url, options.currency ?? null, options.language ?? null, options.country ?? null);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=links.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/core/links.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,kBAAkB,GAAG,uCAAuC,CAAC;AAEnE;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAW,EACX,QAAmC,EACnC,QAAmC,EACnC,OAAkC;IAElC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,QAAQ;QAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,kBAAkB,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;IAChF,IAAI,QAAQ;QAAE,MAAM,CAAC,IAAI,CAAC,MAAM,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAChE,IAAI,OAAO;QAAE,MAAM,CAAC,IAAI,CAAC,MAAM,kBAAkB,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACpC,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAC1C,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AAC3C,CAAC;AAQD;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAc,EACd,WAAmB,EACnB,aAAqB,EACrB,UAA0B,EAC1B,UAAmC,EAAE;IAErC,IAAI,KAAK,GAAG,gBAAgB,MAAM,OAAO,WAAW,OAAO,aAAa,EAAE,CAAC;IAC3E,IAAI,UAAU;QAAE,KAAK,IAAI,YAAY,UAAU,EAAE,CAAC;IAClD,MAAM,GAAG,GAAG,GAAG,kBAAkB,MAAM,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;IACnE,OAAO,gBAAgB,CACrB,GAAG,EACH,OAAO,CAAC,QAAQ,IAAI,IAAI,EACxB,OAAO,CAAC,QAAQ,IAAI,IAAI,EACxB,OAAO,CAAC,OAAO,IAAI,IAAI,CACxB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared parsing utilities — string inputs from CLI/API callers into
|
|
3
|
+
* domain enum values. 1:1 port of fli/core/parsers.py.
|
|
4
|
+
*/
|
|
5
|
+
import { Airline } from "../models/airline.ts";
|
|
6
|
+
import { Airport } from "../models/airport.ts";
|
|
7
|
+
import { Alliance, EmissionsFilter, MaxStops, SeatType, SortBy } from "../models/google-flights/base.ts";
|
|
8
|
+
export declare class ParseError extends Error {
|
|
9
|
+
constructor(message: string);
|
|
10
|
+
}
|
|
11
|
+
/** Resolve an enum member by case-insensitive name. */
|
|
12
|
+
export declare function resolveEnum<T extends Record<string, unknown>>(enumObj: T, name: string): T[keyof T];
|
|
13
|
+
/** Resolve a string airport IATA code to the `Airport` constant. */
|
|
14
|
+
export declare function resolveAirport(code: string): Airport;
|
|
15
|
+
/**
|
|
16
|
+
* Parse a list of airline tokens into Airline constants.
|
|
17
|
+
* Each item may itself contain multiple codes separated by commas or whitespace.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseAirlines(codes: string[] | null | undefined): Airline[] | null;
|
|
20
|
+
/** Parse a list of alliance identifiers into Alliance constants. */
|
|
21
|
+
export declare function parseAlliances(codes: string[] | null | undefined): Alliance[] | null;
|
|
22
|
+
/** Parse a "stops" parameter into the matching `MaxStops` value. */
|
|
23
|
+
export declare function parseMaxStops(stops: string): MaxStops;
|
|
24
|
+
/** Parse a cabin-class string into a `SeatType` value. */
|
|
25
|
+
export declare function parseCabinClass(cabinClass: string): SeatType;
|
|
26
|
+
/** Parse a sort-by string into a `SortBy` value. */
|
|
27
|
+
export declare function parseSortBy(sortBy: string): SortBy;
|
|
28
|
+
/** Normalise an ISO 4217 currency code; pass through unknown 3-letter codes. */
|
|
29
|
+
export declare function parseCurrency(currency: string | null | undefined): string | null;
|
|
30
|
+
/** Parse an emissions filter string into an `EmissionsFilter` value. */
|
|
31
|
+
export declare function parseEmissions(emissions: string): EmissionsFilter;
|
|
32
|
+
/** Parse a time range string ("HH-HH") into a `[start, end]` tuple of hours. */
|
|
33
|
+
export declare function parseTimeRange(timeRange: string): [number, number];
|
|
34
|
+
//# sourceMappingURL=parsers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsers.d.ts","sourceRoot":"","sources":["../../src/core/parsers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EACL,QAAQ,EAER,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,MAAM,EACP,MAAM,kCAAkC,CAAC;AAE1C,qBAAa,UAAW,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM;CAI5B;AAID,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,OAAO,EAAE,CAAC,EACV,IAAI,EAAE,MAAM,GACX,CAAC,CAAC,MAAM,CAAC,CAAC,CAOZ;AAED,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMpD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,EAAE,GAAG,IAAI,CAuBlF;AAED,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,EAAE,GAAG,IAAI,CAsBpF;AAED,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAqBrD;AAED,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,CAO5D;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAYhF;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,CAEjE;AAED,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAoBlE"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared parsing utilities — string inputs from CLI/API callers into
|
|
3
|
+
* domain enum values. 1:1 port of fli/core/parsers.py.
|
|
4
|
+
*/
|
|
5
|
+
import { Airline } from "../models/airline.js";
|
|
6
|
+
import { Airport } from "../models/airport.js";
|
|
7
|
+
import { Alliance, Currency, EmissionsFilter, MaxStops, SeatType, SortBy, } from "../models/google-flights/base.js";
|
|
8
|
+
export class ParseError extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "ParseError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const AIRLINE_SEPARATORS = /[,\s]+/;
|
|
15
|
+
/** Resolve an enum member by case-insensitive name. */
|
|
16
|
+
export function resolveEnum(enumObj, name) {
|
|
17
|
+
const upper = name.toUpperCase();
|
|
18
|
+
if (Object.hasOwn(enumObj, upper)) {
|
|
19
|
+
return enumObj[upper];
|
|
20
|
+
}
|
|
21
|
+
const valid = Object.keys(enumObj).join(", ");
|
|
22
|
+
throw new ParseError(`Invalid value: '${name}'. Valid values: ${valid}`);
|
|
23
|
+
}
|
|
24
|
+
/** Resolve a string airport IATA code to the `Airport` constant. */
|
|
25
|
+
export function resolveAirport(code) {
|
|
26
|
+
const upper = code.toUpperCase();
|
|
27
|
+
if (Object.hasOwn(Airport, upper)) {
|
|
28
|
+
return Airport[upper];
|
|
29
|
+
}
|
|
30
|
+
throw new ParseError(`Invalid airport code: '${code}'`);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Parse a list of airline tokens into Airline constants.
|
|
34
|
+
* Each item may itself contain multiple codes separated by commas or whitespace.
|
|
35
|
+
*/
|
|
36
|
+
export function parseAirlines(codes) {
|
|
37
|
+
if (!codes || codes.length === 0)
|
|
38
|
+
return null;
|
|
39
|
+
const expanded = [];
|
|
40
|
+
for (const item of codes) {
|
|
41
|
+
for (const token of item.split(AIRLINE_SEPARATORS)) {
|
|
42
|
+
const t = token.trim().toUpperCase();
|
|
43
|
+
if (t)
|
|
44
|
+
expanded.push(t);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (expanded.length === 0) {
|
|
48
|
+
throw new ParseError(`No valid airline codes found in: ${JSON.stringify(codes)}`);
|
|
49
|
+
}
|
|
50
|
+
const result = [];
|
|
51
|
+
for (const code of expanded) {
|
|
52
|
+
const key = /^[0-9]/.test(code) ? `_${code}` : code;
|
|
53
|
+
if (!Object.hasOwn(Airline, key)) {
|
|
54
|
+
throw new ParseError(`Invalid airline code: '${code}'`);
|
|
55
|
+
}
|
|
56
|
+
result.push(Airline[key]);
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
/** Parse a list of alliance identifiers into Alliance constants. */
|
|
61
|
+
export function parseAlliances(codes) {
|
|
62
|
+
if (!codes || codes.length === 0)
|
|
63
|
+
return null;
|
|
64
|
+
const expanded = [];
|
|
65
|
+
for (const item of codes) {
|
|
66
|
+
for (const token of item.split(AIRLINE_SEPARATORS)) {
|
|
67
|
+
const t = token.trim().toUpperCase().replace(/ /g, "_").replace(/-/g, "_");
|
|
68
|
+
if (t)
|
|
69
|
+
expanded.push(t);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (expanded.length === 0) {
|
|
73
|
+
throw new ParseError(`No valid alliance names found in: ${JSON.stringify(codes)}`);
|
|
74
|
+
}
|
|
75
|
+
const result = [];
|
|
76
|
+
for (const name of expanded) {
|
|
77
|
+
if (!Object.hasOwn(Alliance, name)) {
|
|
78
|
+
const valid = Object.keys(Alliance).join(", ");
|
|
79
|
+
throw new ParseError(`Invalid alliance: '${name}'. Valid values: ${valid}`);
|
|
80
|
+
}
|
|
81
|
+
result.push(Alliance[name]);
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
/** Parse a "stops" parameter into the matching `MaxStops` value. */
|
|
86
|
+
export function parseMaxStops(stops) {
|
|
87
|
+
const asInt = Number.parseInt(stops, 10);
|
|
88
|
+
if (Number.isFinite(asInt) && String(asInt) === stops.trim()) {
|
|
89
|
+
if (asInt <= 0)
|
|
90
|
+
return MaxStops.NON_STOP;
|
|
91
|
+
if (asInt === 1)
|
|
92
|
+
return MaxStops.ONE_STOP_OR_FEWER;
|
|
93
|
+
if (asInt >= 2)
|
|
94
|
+
return MaxStops.TWO_OR_FEWER_STOPS;
|
|
95
|
+
}
|
|
96
|
+
const upper = stops.toUpperCase();
|
|
97
|
+
const map = {
|
|
98
|
+
ANY: MaxStops.ANY,
|
|
99
|
+
NON_STOP: MaxStops.NON_STOP,
|
|
100
|
+
NONSTOP: MaxStops.NON_STOP,
|
|
101
|
+
ONE_STOP: MaxStops.ONE_STOP_OR_FEWER,
|
|
102
|
+
ONE_STOP_OR_FEWER: MaxStops.ONE_STOP_OR_FEWER,
|
|
103
|
+
TWO_PLUS_STOPS: MaxStops.TWO_OR_FEWER_STOPS,
|
|
104
|
+
TWO_OR_FEWER_STOPS: MaxStops.TWO_OR_FEWER_STOPS,
|
|
105
|
+
};
|
|
106
|
+
if (Object.hasOwn(map, upper))
|
|
107
|
+
return map[upper];
|
|
108
|
+
throw new ParseError(`Invalid max_stops value: '${stops}'. Valid values: ANY, NON_STOP, ONE_STOP, TWO_PLUS_STOPS, or 0/1/2`);
|
|
109
|
+
}
|
|
110
|
+
/** Parse a cabin-class string into a `SeatType` value. */
|
|
111
|
+
export function parseCabinClass(cabinClass) {
|
|
112
|
+
const upper = cabinClass.toUpperCase();
|
|
113
|
+
if (Object.hasOwn(SeatType, upper)) {
|
|
114
|
+
return SeatType[upper];
|
|
115
|
+
}
|
|
116
|
+
const valid = Object.keys(SeatType).join(", ");
|
|
117
|
+
throw new ParseError(`Invalid cabin_class value: '${cabinClass}'. Valid values: ${valid}`);
|
|
118
|
+
}
|
|
119
|
+
/** Parse a sort-by string into a `SortBy` value. */
|
|
120
|
+
export function parseSortBy(sortBy) {
|
|
121
|
+
const upper = sortBy.toUpperCase();
|
|
122
|
+
if (Object.hasOwn(SortBy, upper)) {
|
|
123
|
+
return SortBy[upper];
|
|
124
|
+
}
|
|
125
|
+
const valid = Object.keys(SortBy).join(", ");
|
|
126
|
+
throw new ParseError(`Invalid sort_by value: '${sortBy}'. Valid values: ${valid}`);
|
|
127
|
+
}
|
|
128
|
+
/** Normalise an ISO 4217 currency code; pass through unknown 3-letter codes. */
|
|
129
|
+
export function parseCurrency(currency) {
|
|
130
|
+
if (currency == null || currency === "")
|
|
131
|
+
return null;
|
|
132
|
+
const normalized = currency.trim().toUpperCase();
|
|
133
|
+
if (normalized.length !== 3 || !/^[A-Z]{3}$/.test(normalized)) {
|
|
134
|
+
throw new ParseError(`Invalid currency code: '${currency}'. Expected a 3-letter ISO 4217 code.`);
|
|
135
|
+
}
|
|
136
|
+
if (Object.hasOwn(Currency, normalized)) {
|
|
137
|
+
return Currency[normalized];
|
|
138
|
+
}
|
|
139
|
+
return normalized;
|
|
140
|
+
}
|
|
141
|
+
/** Parse an emissions filter string into an `EmissionsFilter` value. */
|
|
142
|
+
export function parseEmissions(emissions) {
|
|
143
|
+
return resolveEnum(EmissionsFilter, emissions);
|
|
144
|
+
}
|
|
145
|
+
/** Parse a time range string ("HH-HH") into a `[start, end]` tuple of hours. */
|
|
146
|
+
export function parseTimeRange(timeRange) {
|
|
147
|
+
const parts = timeRange.split("-");
|
|
148
|
+
if (parts.length !== 2) {
|
|
149
|
+
throw new ParseError(`Invalid time range format: '${timeRange}'. Expected 'HH-HH' (e.g., '6-20')`);
|
|
150
|
+
}
|
|
151
|
+
const start = Number.parseInt((parts[0] ?? "").trim(), 10);
|
|
152
|
+
const end = Number.parseInt((parts[1] ?? "").trim(), 10);
|
|
153
|
+
if (!Number.isFinite(start) || !Number.isFinite(end)) {
|
|
154
|
+
throw new ParseError(`Invalid time range format: '${timeRange}'. Expected 'HH-HH' (e.g., '6-20')`);
|
|
155
|
+
}
|
|
156
|
+
if (start < 0 || start > 23 || end < 0 || end > 23) {
|
|
157
|
+
throw new ParseError(`Invalid time range format: '${timeRange}'. Expected 'HH-HH' (e.g., '6-20')`);
|
|
158
|
+
}
|
|
159
|
+
return [start, end];
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=parsers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsers.js","sourceRoot":"","sources":["../../src/core/parsers.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fli — TypeScript port of the Python fli library.
|
|
3
|
+
*
|
|
4
|
+
* Programmatic access to Google Flights data through direct
|
|
5
|
+
* (reverse-engineered) API interaction. No HTML scraping.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { SearchFlights, FlightSearchFilters, PassengerInfo, FlightSegment, Airport, SeatType } from "fli";
|
|
10
|
+
*
|
|
11
|
+
* const filters = new FlightSearchFilters({
|
|
12
|
+
* passenger_info: { adults: 1, children: 0, infants_in_seat: 0, infants_on_lap: 0 },
|
|
13
|
+
* flight_segments: [
|
|
14
|
+
* new FlightSegment({
|
|
15
|
+
* departure_airport: [[[Airport.JFK, 0]]],
|
|
16
|
+
* arrival_airport: [[[Airport.LAX, 0]]],
|
|
17
|
+
* travel_date: "2026-12-25",
|
|
18
|
+
* }),
|
|
19
|
+
* ],
|
|
20
|
+
* seat_type: SeatType.ECONOMY,
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* const search = new SearchFlights();
|
|
24
|
+
* const results = await search.search(filters, { currency: "USD" });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export * from "./core/index.ts";
|
|
28
|
+
export * from "./models/index.ts";
|
|
29
|
+
export * from "./search/index.ts";
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC"}
|