Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion nodejs/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"indent": ["warn", 4],
"brace-style": ["warn", "stroustrup"],
"valid-jsdoc": ["warn"],
"require-jsdoc": ["warn"]
"require-jsdoc": ["warn"],
"object-curly-spacing": ["warn", "always"]
}
}
102 changes: 61 additions & 41 deletions nodejs/FlightRadar24/api.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const Core = require("./core");
const {request} = require("./request");
const { APIClient } = require("./request");
const Airport = require("./entities/airport");
const Flight = require("./entities/flight");
const FlightTrackerConfig = require("./flightTrackerConfig");
const {AirportNotFoundError, LoginError} = require("./errors");
const {isNumeric, radians, rad2deg} = require("./util");
const {parseAirlinesHtml, parseAirportsHtml} = require("./parsers");
const { AirportNotFoundError, LoginError } = require("./errors");
const { isNumeric, radians, rad2deg } = require("./util");
const { parseAirlinesHtml, parseAirportsHtml } = require("./parsers");


/**
Expand All @@ -24,7 +24,7 @@ async function mapConcurrent(items, concurrency, fn) {
await fn(items[i++]);
}
}
await Promise.all(Array.from({length: Math.min(concurrency, items.length)}, worker));
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, worker));
}

/**
Expand All @@ -38,9 +38,10 @@ class FlightRadar24API {
* @param {number} [options.timeout=30000] - Request timeout in milliseconds
* @param {number} [options.maxWorkers=8] - Maximum concurrent requests when fetching flight details
*/
constructor({timeout = 30000, maxWorkers = 8} = {}) {
constructor({ timeout = 30000, maxWorkers = 8 } = {}) {
this.__flightTrackerConfig = new FlightTrackerConfig();
this.__loginData = null;
this.__client = new APIClient();
this.timeout = timeout;
this.maxWorkers = maxWorkers;
}
Expand All @@ -51,7 +52,8 @@ class FlightRadar24API {
* @return {Promise<Array<object>>}
*/
async getAirlines() {
const {content} = await request(Core.airlinesDataUrl, {headers: Core.htmlHeaders, timeout: this.timeout});
const { content } = await this.__client.request(
Core.airlinesDataUrl, { headers: Core.htmlHeaders, timeout: this.timeout });
return parseAirlinesHtml(content);
}

Expand All @@ -70,7 +72,7 @@ class FlightRadar24API {
const notFound = [403, 404];

const firstLogoUrl = Core.airlineLogoUrl(iata, icao);
let {content, statusCode} = await request(firstLogoUrl, {
let { content, statusCode } = await this.__client.request(firstLogoUrl, {
headers: Core.imageHeaders,
allowedErrorCodes: notFound,
timeout: this.timeout,
Expand All @@ -81,7 +83,7 @@ class FlightRadar24API {
}

const secondLogoUrl = Core.alternativeAirlineLogoUrl(icao);
({content, statusCode} = await request(secondLogoUrl, {
({ content, statusCode } = await this.__client.request(secondLogoUrl, {
headers: Core.imageHeaders,
allowedErrorCodes: notFound,
timeout: this.timeout,
Expand Down Expand Up @@ -112,7 +114,9 @@ class FlightRadar24API {
return airport;
}

const {content} = await request(Core.airportDataUrl(code), {headers: Core.jsonHeaders, timeout: this.timeout});
const { content } = await this.__client.request(
Core.airportDataUrl(code), { headers: Core.jsonHeaders, timeout: this.timeout },
);
const info = content["details"];

if (info === undefined) {
Expand All @@ -134,13 +138,13 @@ class FlightRadar24API {
throw new Error("The code '" + code + "' is invalid. It must be the IATA or ICAO of the airport.");
}

const params = {"format": "json", "code": code, "limit": flightLimit, "page": page};
const params = { "format": "json", "code": code, "limit": flightLimit, "page": page };

if (this.__loginData !== null) {
params["token"] = this.__loginData["cookies"]["_frPl"];
if (this.isLoggedIn()) {
params["token"] = this.__client.getCookie("_frPl");
Comment thread
JeanExtreme002 marked this conversation as resolved.
}

const {content, statusCode} = await request(Core.apiAirportDataUrl, {
const { content, statusCode } = await this.__client.request(Core.apiAirportDataUrl, {
params,
headers: Core.jsonHeaders,
allowedErrorCodes: [400],
Expand Down Expand Up @@ -177,7 +181,9 @@ class FlightRadar24API {
* @return {Promise<object>}
*/
async getAirportDisruptions() {
const {content} = await request(Core.airportDisruptionsUrl, {headers: Core.jsonHeaders, timeout: this.timeout});
const { content } = await this.__client.request(
Core.airportDisruptionsUrl, { headers: Core.jsonHeaders, timeout: this.timeout },
);
return content;
}

Expand All @@ -191,7 +197,7 @@ class FlightRadar24API {
const airports = [];
await mapConcurrent(countries, this.maxWorkers, async (countryName) => {
const countryHref = Core.airportsDataUrl + "/" + countryName;
const {content} = await request(countryHref, {headers: Core.htmlHeaders, timeout: this.timeout});
const { content } = await this.__client.request(countryHref, { headers: Core.htmlHeaders, timeout: this.timeout });
airports.push(...parseAirportsHtml(content, countryHref));
});
return airports;
Expand All @@ -207,10 +213,9 @@ class FlightRadar24API {
throw new LoginError("You must log in to your account.");
}

const headers = {...Core.jsonHeaders, "accesstoken": this.getLoginData()["accessToken"]};
const {content} = await request(Core.bookmarksUrl, {
const headers = { ...Core.jsonHeaders, "accesstoken": this.getLoginData()["accessToken"] };
const { content } = await this.__client.request(Core.bookmarksUrl, {
headers,
cookies: this.__loginData["cookies"],
timeout: this.timeout,
});

Expand Down Expand Up @@ -290,10 +295,10 @@ class FlightRadar24API {
async getCountryFlag(country) {
const flagUrl = Core.countryFlagUrl(country.toLowerCase().replaceAll(" ", "-"));

const headers = {...Core.imageHeaders};
const headers = { ...Core.imageHeaders };
delete headers["origin"];

const {content, statusCode} = await request(flagUrl, {
const { content, statusCode } = await this.__client.request(flagUrl, {
headers,
allowedErrorCodes: [403, 404],
timeout: this.timeout,
Expand All @@ -313,7 +318,9 @@ class FlightRadar24API {
* @return {Promise<object>}
*/
async getFlightDetails(flight) {
const {content} = await request(Core.flightDataUrl(flight.id), {headers: Core.jsonHeaders, timeout: this.timeout});
const { content } = await this.__client.request(
Core.flightDataUrl(flight.id), { headers: Core.jsonHeaders, timeout: this.timeout },
);
return content;
}

Expand All @@ -328,17 +335,17 @@ class FlightRadar24API {
* @return {Promise<Array<Flight>>}
*/
async getFlights(airline = null, bounds = null, registration = null, aircraftType = null, details = false) {
const params = {...this.__flightTrackerConfig};
const params = { ...this.__flightTrackerConfig };

if (this.__loginData !== null) {
params["enc"] = this.__loginData["cookies"]["_frPl"];
if (this.isLoggedIn()) {
params["enc"] = this.__client.getCookie("_frPl");
Comment thread
JeanExtreme002 marked this conversation as resolved.
}
if (airline !== null) params["airline"] = airline;
if (bounds !== null) params["bounds"] = bounds;
if (registration !== null) params["reg"] = registration;
if (aircraftType !== null) params["type"] = aircraftType;

const {content} = await request(Core.realTimeFlightTrackerDataUrl, {
const { content } = await this.__client.request(Core.realTimeFlightTrackerDataUrl, {
params,
headers: Core.jsonHeaders,
timeout: this.timeout,
Expand Down Expand Up @@ -371,7 +378,7 @@ class FlightRadar24API {
* @return {FlightTrackerConfig}
*/
getFlightTrackerConfig() {
return new FlightTrackerConfig({...this.__flightTrackerConfig});
return new FlightTrackerConfig({ ...this.__flightTrackerConfig });
}

/**
Expand All @@ -392,10 +399,9 @@ class FlightRadar24API {
throw new Error("File type '" + fileType + "' is not supported. Only CSV and KML are supported.");
}

const headers = {...Core.jsonHeaders, "accesstoken": this.getLoginData()["accessToken"]};
const {content} = await request(Core.historicalDataUrl(flight.id, fileType, timestamp), {
const headers = { ...Core.jsonHeaders, "accesstoken": this.getLoginData()["accessToken"] };
const { content } = await this.__client.request(Core.historicalDataUrl(flight.id, fileType, timestamp), {
headers,
cookies: this.__loginData["cookies"],
timeout: this.timeout,
});

Expand All @@ -411,7 +417,7 @@ class FlightRadar24API {
if (!this.isLoggedIn()) {
throw new LoginError("You must log in to your account.");
}
return {...this.__loginData["userData"]};
return { ...this.__loginData["userData"] };
}

/**
Expand All @@ -420,7 +426,8 @@ class FlightRadar24API {
* @return {Promise<object>}
*/
async getMostTracked() {
const {content} = await request(Core.mostTrackedUrl, {headers: Core.jsonHeaders, timeout: this.timeout});
const { content } = await this.__client.request(
Core.mostTrackedUrl, { headers: Core.jsonHeaders, timeout: this.timeout });
return content;
}

Expand All @@ -430,7 +437,9 @@ class FlightRadar24API {
* @return {Promise<object>}
*/
async getVolcanicEruptions() {
const {content} = await request(Core.volcanicEruptionDataUrl, {headers: Core.jsonHeaders, timeout: this.timeout});
const { content } = await this.__client.request(
Core.volcanicEruptionDataUrl, { headers: Core.jsonHeaders, timeout: this.timeout },
);
return content;
}

Expand All @@ -440,7 +449,7 @@ class FlightRadar24API {
* @return {object}
*/
getZones() {
const zones = {...Core.staticZones};
const zones = { ...Core.staticZones };
delete zones.version;
return zones;
}
Expand All @@ -453,7 +462,9 @@ class FlightRadar24API {
* @return {Promise<object>}
*/
async search(query, limit = 50) {
const {content} = await request(Core.searchDataUrl(query, limit), {headers: Core.jsonHeaders, timeout: this.timeout});
const { content } = await this.__client.request(
Core.searchDataUrl(query, limit), { headers: Core.jsonHeaders, timeout: this.timeout },
);

const results = content["results"] ?? [];
const countDict = content["stats"]?.["count"] ?? {};
Expand Down Expand Up @@ -491,9 +502,12 @@ class FlightRadar24API {
* @return {Promise<undefined>}
*/
async login(user, password) {
const {content, statusCode, cookies} = await request(Core.userLoginUrl, {
this.__loginData = null;
this.__client.clearCookies();

const { content, statusCode } = await this.__client.request(Core.userLoginUrl, {
headers: Core.jsonHeaders,
data: {"email": user, "password": password, "remember": "true", "type": "web"},
data: { "email": user, "password": password, "remember": "true", "type": "web" },
timeout: this.timeout,
});

Expand All @@ -503,7 +517,7 @@ class FlightRadar24API {
);
}

this.__loginData = {"userData": content["userData"], "cookies": cookies};
this.__loginData = { "userData": content["userData"] };
}

/**
Expand All @@ -516,11 +530,17 @@ class FlightRadar24API {
return true;
}

const cookies = this.__loginData["cookies"];
this.__loginData = null;

const {statusCode} = await request(Core.userLogoutUrl, {headers: Core.jsonHeaders, cookies, timeout: this.timeout});
return statusCode >= 200 && statusCode < 300;
try {
const { statusCode } = await this.__client.request(
Core.userLogoutUrl, { headers: Core.jsonHeaders, timeout: this.timeout },
);
return statusCode >= 200 && statusCode < 300;
}
finally {
this.__client.clearCookies();
}
}

/**
Expand Down
6 changes: 3 additions & 3 deletions nodejs/FlightRadar24/core.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const {staticZones} = require("./zones");
const { staticZones } = require("./zones");

const FR24_BASE = "https://www.flightradar24.com";
const API_FR24_BASE = "https://api.flightradar24.com/common/v1";
Expand Down Expand Up @@ -68,8 +68,8 @@ const Core = {
staticZones,

headers: baseHeaders,
jsonHeaders: {accept: "application/json", ...baseHeaders},
imageHeaders: {accept: "image/gif, image/jpg, image/jpeg, image/png", ...baseHeaders},
jsonHeaders: { accept: "application/json", ...baseHeaders },
imageHeaders: { accept: "image/gif, image/jpg, image/jpeg, image/png", ...baseHeaders },
htmlHeaders: {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"accept-encoding": "gzip, deflate, br",
Expand Down
2 changes: 1 addition & 1 deletion nodejs/FlightRadar24/entities/entity.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const {radians} = require("../util");
const { radians } = require("../util");

const DEFAULT_TEXT = "N/A";

Expand Down
2 changes: 1 addition & 1 deletion nodejs/FlightRadar24/entities/flight.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class Flight extends Entity {
* @return {boolean}
*/
checkInfo(info) {
const comparisonFunctions = {"max": Math.max, "min": Math.min};
const comparisonFunctions = { "max": Math.max, "min": Math.min };

for (let key in info) {
if (!Object.prototype.hasOwnProperty.call(info, key)) {
Expand Down
2 changes: 1 addition & 1 deletion nodejs/FlightRadar24/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ class CloudflareError extends FlightRadarError {
/** Thrown when login fails or an authenticated endpoint is accessed without login. */
class LoginError extends FlightRadarError {}

module.exports = {FlightRadarError, AirportNotFoundError, CloudflareError, LoginError};
module.exports = { FlightRadarError, AirportNotFoundError, CloudflareError, LoginError };
2 changes: 1 addition & 1 deletion nodejs/FlightRadar24/flightTrackerConfig.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const {isNumeric} = require("./util");
const { isNumeric } = require("./util");


const proxyHandler = {
Expand Down
6 changes: 3 additions & 3 deletions nodejs/FlightRadar24/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
* https://www.flightradar24.com/terms-and-conditions
*/

const {FlightRadarError, AirportNotFoundError, CloudflareError, LoginError} = require("./errors");
const { FlightRadarError, AirportNotFoundError, CloudflareError, LoginError } = require("./errors");
const FlightRadar24API = require("./api");
const FlightTrackerConfig = require("./flightTrackerConfig");
const Airport = require("./entities/airport");
const Entity = require("./entities/entity");
const Flight = require("./entities/flight");
const {Countries} = require("./core");
const { Countries } = require("./core");

const {version, author} = require("../package.json");
const { version, author } = require("../package.json");

module.exports = {
FlightRadar24API,
Expand Down
6 changes: 3 additions & 3 deletions nodejs/FlightRadar24/parsers.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const {JSDOM} = require("jsdom");
const { JSDOM } = require("jsdom");
const Airport = require("./entities/airport");

/**
Expand Down Expand Up @@ -69,7 +69,7 @@ function parseAirlinesHtml(html) {
}
}

airlines.push({"Name": airlineName, "ICAO": icao, "IATA": iata, "n_aircrafts": nAircrafts});
airlines.push({ "Name": airlineName, "ICAO": icao, "IATA": iata, "n_aircrafts": nAircrafts });
}

return airlines;
Expand Down Expand Up @@ -152,4 +152,4 @@ function parseAirportsHtml(html, countryHref) {
return airports;
}

module.exports = {parseAirlinesHtml, parseAirportsHtml};
module.exports = { parseAirlinesHtml, parseAirportsHtml };
Loading
Loading