// Copyright 2022 Luca Casonato. All rights reserved. MIT license. /** * Travel Impact Model API Client for Deno * ======================================= * * Travel Impact Model API lets you query travel carbon emission estimates. * * Docs: https://developers.google.com/travel/impact-model * Source: https://googleapis.deno.dev/v1/travelimpactmodel:v1.ts */ import { auth, CredentialsClient, GoogleAuth, request } from "/_/base@v1/mod.ts"; export { auth, GoogleAuth }; export type { CredentialsClient }; /** * Travel Impact Model API lets you query travel carbon emission estimates. */ export class TravelImpactModel { #client: CredentialsClient | undefined; #baseUrl: string; constructor(client?: CredentialsClient, baseUrl: string = "https://travelimpactmodel.googleapis.com/") { this.#client = client; this.#baseUrl = baseUrl; } /** * Stateless method to retrieve emission estimates. Details on how emission * estimates are computed are in * [GitHub](https://github.com/google/travel-impact-model) The response will * contain all entries that match the input flight legs, in the same order. If * there are no estimates available for a certain flight leg, the response * will return the flight leg object with empty emission fields. The request * will still be considered successful. Reasons for missing emission estimates * include: * The flight is unknown to the server. * The input flight leg is * missing one or more identifiers. * The flight date is in the past. * The * aircraft type is not supported by the model. * Missing seat configuration. * The request can contain up to 1000 flight legs. If the request has more * than 1000 direct flights, if will fail with an INVALID_ARGUMENT error. * */ async flightsComputeFlightEmissions(req: ComputeFlightEmissionsRequest): Promise { const url = new URL(`${this.#baseUrl}v1/flights:computeFlightEmissions`); const body = JSON.stringify(req); const data = await request(url.href, { client: this.#client, method: "POST", body, }); return data as ComputeFlightEmissionsResponse; } /** * Stateless method to retrieve GHG emissions estimates for a set of flight * segments for Scope 3 reporting. The response will contain all entries that * match the input Scope3FlightSegment flight segments, in the same order * provided. The estimates will be computed using the following cascading * logic (using the first one that is available): 1. TIM-based emissions given * origin, destination, carrier, flightNumber, departureDate, and cabinClass. * 2. Typical flight emissions given origin, destination, year in * departureDate, and cabinClass. 3. Distance-based emissions calculated using * distanceKm, year in departureDate, and cabinClass. If there is a future * flight requested in this calendar year, we do not support Tier 1 emissions * and will fallback to Tier 2 or 3 emissions. If the requested future flight * is in not in this calendar year, we will return an empty response. We * recommend that for future flights, computeFlightEmissions API is used * instead. If there are no estimates available for a certain flight with any * of the three methods, the response will return a Scope3FlightEmissions * object with empty emission fields. The request will still be considered * successful. Generally, missing emissions estimates occur when the flight is * unknown to the server (e.g. no specific flight exists, or typical flight * emissions are not available for the requested pair). The request will fail * with an `INVALID_ARGUMENT` error if: * The request contains more than 1,000 * flight legs. * The input flight leg is missing one or more identifiers. For * example, missing origin/destination without a valid distance for * TIM_EMISSIONS or TYPICAL_FLIGHT_EMISSIONS type matching, or missing * distance for a DISTANCE_BASED_EMISSIONS type matching (if you want to * fallback to distance-based emissions or want a distance-based emissions * estimate, you need to specify a distance). * The flight date is before 2019 * (Scope 3 data is only available for 2019 and after). * The flight distance * is 0 or lower. * Missing cabin class. Because the request is processed with * fallback logic, it is possible that misconfigured requests return valid * emissions estimates using fallback methods. For example, if a request has * the wrong flight number but specifies the origin and destination, the * request will still succeed, but the returned emissions will be based solely * on the typical flight emissions. Similarly, if a request is missing the * origin for a typical flight emissions request, but specifies a valid * distance, the request could succeed based solely on the distance-based * emissions. Consequently, one should check the source of the returned * emissions (source) to confirm the results are as expected. * */ async flightsComputeScope3FlightEmissions(req: ComputeScope3FlightEmissionsRequest): Promise { req = serializeComputeScope3FlightEmissionsRequest(req); const url = new URL(`${this.#baseUrl}v1/flights:computeScope3FlightEmissions`); const body = JSON.stringify(req); const data = await request(url.href, { client: this.#client, method: "POST", body, }); return deserializeComputeScope3FlightEmissionsResponse(data); } /** * Retrieves typical flight emissions estimates between two airports, also * known as a market. If there are no estimates available for a certain * market, the response will return the market object with empty emission * fields. The request will still be considered successful. Details on how the * typical emissions estimates are computed are on * [GitHub](https://github.com/google/travel-impact-model/blob/main/projects/typical_flight_emissions.md). * The request can contain up to 1000 markets. If the request has more than * 1000 markets, it will fail with an INVALID_ARGUMENT error. * */ async flightsComputeTypicalFlightEmissions(req: ComputeTypicalFlightEmissionsRequest): Promise { const url = new URL(`${this.#baseUrl}v1/flights:computeTypicalFlightEmissions`); const body = JSON.stringify(req); const data = await request(url.href, { client: this.#client, method: "POST", body, }); return data as ComputeTypicalFlightEmissionsResponse; } } /** * Input definition for the ComputeFlightEmissions request. */ export interface ComputeFlightEmissionsRequest { /** * Required. Direct flights to return emission estimates for. */ flights?: Flight[]; } /** * Output definition for the ComputeFlightEmissions response. */ export interface ComputeFlightEmissionsResponse { /** * List of flight legs with emission estimates. */ flightEmissions?: FlightWithEmissions[]; /** * The model version under which emission estimates for all flights in this * response were computed. */ modelVersion?: ModelVersion; } /** * A list of flight segments to request the Scope 3 emissions for. */ export interface ComputeScope3FlightEmissionsRequest { /** * Required. Flights to return emission estimates for. */ flights?: Scope3FlightSegment[]; /** * Optional. The model version under which emission estimates for all flights * in this request were computed. */ modelVersion?: ModelVersion; } function serializeComputeScope3FlightEmissionsRequest(data: any): ComputeScope3FlightEmissionsRequest { return { ...data, flights: data["flights"] !== undefined ? data["flights"].map((item: any) => (serializeScope3FlightSegment(item))) : undefined, }; } function deserializeComputeScope3FlightEmissionsRequest(data: any): ComputeScope3FlightEmissionsRequest { return { ...data, flights: data["flights"] !== undefined ? data["flights"].map((item: any) => (deserializeScope3FlightSegment(item))) : undefined, }; } /** * A list of flights with Scope 3 emission estimates. */ export interface ComputeScope3FlightEmissionsResponse { /** * List of flight segments with emission estimates. */ flightEmissions?: Scope3FlightEmissions[]; /** * The model version under which emission estimates for all flights in this * response were computed. */ modelVersion?: ModelVersion; } function serializeComputeScope3FlightEmissionsResponse(data: any): ComputeScope3FlightEmissionsResponse { return { ...data, flightEmissions: data["flightEmissions"] !== undefined ? data["flightEmissions"].map((item: any) => (serializeScope3FlightEmissions(item))) : undefined, }; } function deserializeComputeScope3FlightEmissionsResponse(data: any): ComputeScope3FlightEmissionsResponse { return { ...data, flightEmissions: data["flightEmissions"] !== undefined ? data["flightEmissions"].map((item: any) => (deserializeScope3FlightEmissions(item))) : undefined, }; } /** * A list of pair of airports (markets) to request the typical emissions for. */ export interface ComputeTypicalFlightEmissionsRequest { /** * Required. Request the typical flight emissions estimates for this market * pair. A maximum of 1000 markets can be requested. */ markets?: Market[]; } /** * The response includes the emissions but also the model version. */ export interface ComputeTypicalFlightEmissionsResponse { /** * The model version under which typical flight emission estimates for all * flights in this response were computed. */ modelVersion?: ModelVersion; /** * Market's Typical Flight Emissions requested. */ typicalFlightEmissions?: TypicalFlightEmissions[]; } /** * Represents a whole or partial calendar date, such as a birthday. The time of * day and time zone are either specified elsewhere or are insignificant. The * date is relative to the Gregorian Calendar. This can represent one of the * following: * A full date, with non-zero year, month, and day values. * A * month and day, with a zero year (for example, an anniversary). * A year on * its own, with a zero month and a zero day. * A year and month, with a zero * day (for example, a credit card expiration date). Related types: * * google.type.TimeOfDay * google.type.DateTime * google.protobuf.Timestamp */ export interface Date { /** * Day of a month. Must be from 1 to 31 and valid for the year and month, or * 0 to specify a year by itself or a year and month where the day isn't * significant. */ day?: number; /** * Month of a year. Must be from 1 to 12, or 0 to specify a year without a * month and day. */ month?: number; /** * Year of the date. Must be from 1 to 9999, or 0 to specify a date without a * year. */ year?: number; } /** * Metadata about the EASA Flight Emissions Label. */ export interface EasaLabelMetadata { /** * The date when the label expires. The label can be displayed until the end * of this date. */ labelExpiryDate?: Date; /** * The date when the label was issued. */ labelIssueDate?: Date; /** * Version of the label. */ labelVersion?: string; /** * Sustainable Aviation Fuel (SAF) emissions discount percentage applied to * the label. It is a percentage as a decimal. The values are in the interval * [0,1]. For example, 0.0021 means 0.21%. This discount and reduction in * emissions are reported by the EASA label but they are not included in the * CO2e estimates distributed by this API. */ safDiscountPercentage?: number; } /** * Grouped emissions per seating class results. */ export interface EmissionsGramsPerPax { /** * Emissions for one passenger in business class in grams. This field is * always computed and populated, regardless of whether the aircraft has * business class seats or not. */ business?: number; /** * Emissions for one passenger in economy class in grams. This field is * always computed and populated, regardless of whether the aircraft has * economy class seats or not. */ economy?: number; /** * Emissions for one passenger in first class in grams. This field is always * computed and populated, regardless of whether the aircraft has first class * seats or not. */ first?: number; /** * Emissions for one passenger in premium economy class in grams. This field * is always computed and populated, regardless of whether the aircraft has * premium economy class seats or not. */ premiumEconomy?: number; } /** * All details related to a single request item for a direct flight emission * estimates. */ export interface Flight { /** * Required. Date of the flight in the time zone of the origin airport. Must * be a date in the present or future. */ departureDate?: Date; /** * Required. IATA airport code for flight destination, e.g. "JFK". */ destination?: string; /** * Required. Flight number, e.g. 324. */ flightNumber?: number; /** * Required. IATA carrier code, e.g. "AA". */ operatingCarrierCode?: string; /** * Required. IATA airport code for flight origin, e.g. "LHR". */ origin?: string; } /** * Direct flight with emission estimates. */ export interface FlightWithEmissions { /** * Optional. The significance of contrails warming impact compared to the * total CO2e emissions impact. */ contrailsImpactBucket?: | "CONTRAILS_IMPACT_UNSPECIFIED" | "CONTRAILS_IMPACT_NEGLIGIBLE" | "CONTRAILS_IMPACT_MODERATE" | "CONTRAILS_IMPACT_SEVERE"; /** * Optional. Metadata about the EASA Flight Emissions Label. Only set when * the emissions data source is EASA. */ easaLabelMetadata?: EasaLabelMetadata; /** * Optional. Per-passenger emission estimate numbers. Will not be present if * emissions could not be computed. For the list of reasons why emissions * could not be computed, see ComputeFlightEmissions. */ emissionsGramsPerPax?: EmissionsGramsPerPax; /** * Required. Matches the flight identifiers in the request. Note: all IATA * codes are capitalized. */ flight?: Flight; /** * Optional. The source of the emissions data. */ source?: | "SOURCE_UNSPECIFIED" | "TIM" | "EASA"; } /** * A pair of airports. */ export interface Market { /** * Required. IATA airport code for flight destination, e.g. "JFK". */ destination?: string; /** * Required. IATA airport code for flight origin, e.g. "LHR". */ origin?: string; } /** * Travel Impact Model version. For more information about the model versioning * see [GitHub](https://github.com/google/travel-impact-model/#versioning). */ export interface ModelVersion { /** * Dated versions: Model datasets are recreated with refreshed input data but * no change to the algorithms regularly. */ dated?: string; /** * Major versions: Major changes to methodology (e.g. adding new data sources * to the model that lead to major output changes). Such changes will be * infrequent and announced well in advance. Might involve API version * changes, which will respect [Google Cloud API * guidelines](https://cloud.google.com/endpoints/docs/openapi/versioning-an-api#backwards-incompatible) */ major?: number; /** * Minor versions: Changes to the model that, while being consistent across * schema versions, change the model parameters or implementation. */ minor?: number; /** * Patch versions: Implementation changes meant to address bugs or * inaccuracies in the model implementation. */ patch?: number; } /** * Scope 3 flight with emission estimates. */ export interface Scope3FlightEmissions { /** * Required. Matches the flight identifiers in the request. */ flight?: Scope3FlightSegment; /** * Optional. The source of the emissions data. */ source?: | "SCOPE3_DATA_TYPE_UNSPECIFIED" | "TIM_EMISSIONS" | "TYPICAL_FLIGHT_EMISSIONS" | "DISTANCE_BASED_EMISSIONS"; /** * Optional. Tank-to-wake flight emissions per passenger based on the * requested info. */ ttwEmissionsGramsPerPax?: bigint; /** * Optional. Well-to-tank flight emissions per passenger based on the * requested info. */ wttEmissionsGramsPerPax?: bigint; /** * Optional. Total flight emissions (sum of well-to-tank and tank-to-wake) * per passenger based on the requested info. This is the total emissions and * unless you have specific reasons for using TTW or WTT emissions, you should * use this number. */ wtwEmissionsGramsPerPax?: bigint; } function serializeScope3FlightEmissions(data: any): Scope3FlightEmissions { return { ...data, flight: data["flight"] !== undefined ? serializeScope3FlightSegment(data["flight"]) : undefined, ttwEmissionsGramsPerPax: data["ttwEmissionsGramsPerPax"] !== undefined ? String(data["ttwEmissionsGramsPerPax"]) : undefined, wttEmissionsGramsPerPax: data["wttEmissionsGramsPerPax"] !== undefined ? String(data["wttEmissionsGramsPerPax"]) : undefined, wtwEmissionsGramsPerPax: data["wtwEmissionsGramsPerPax"] !== undefined ? String(data["wtwEmissionsGramsPerPax"]) : undefined, }; } function deserializeScope3FlightEmissions(data: any): Scope3FlightEmissions { return { ...data, flight: data["flight"] !== undefined ? deserializeScope3FlightSegment(data["flight"]) : undefined, ttwEmissionsGramsPerPax: data["ttwEmissionsGramsPerPax"] !== undefined ? BigInt(data["ttwEmissionsGramsPerPax"]) : undefined, wttEmissionsGramsPerPax: data["wttEmissionsGramsPerPax"] !== undefined ? BigInt(data["wttEmissionsGramsPerPax"]) : undefined, wtwEmissionsGramsPerPax: data["wtwEmissionsGramsPerPax"] !== undefined ? BigInt(data["wtwEmissionsGramsPerPax"]) : undefined, }; } /** * Flight parameters with which the Scope 3 emissions are fetched. */ export interface Scope3FlightSegment { /** * Required. The cabin class of the flight. */ cabinClass?: | "CABIN_CLASS_UNSPECIFIED" | "ECONOMY" | "PREMIUM_ECONOMY" | "BUSINESS" | "FIRST"; /** * Optional. 2-character [IATA carrier * code](https://www.iata.org/en/publications/directories/code-search/), e.g. * `KE`. This is required if specific flight matching is desired. Otherwise, * this is unused for typical flight and distance-based emissions models. This * could be both operating and marketing carrier code (i.e. codeshare is * covered). */ carrierCode?: string; /** * Required. Date of the flight in the time zone of the origin airport. Only * year is required for typical flight and distance-based emissions models * (month and day values are ignored and therefore, can be either omitted, set * to 0, or set to a valid date for those cases). Correspondingly, if a * specific date is not provided for TIM emissions, we will fallback to * typical flight (or distance-based) emissions. */ departureDate?: Date; /** * Optional. 3-character [IATA airport * code](https://www.iata.org/en/publications/directories/code-search/) for * flight destination, e.g. `ICN`. This is used to match specific flight if * provided alongside origin, carrier, and flight number. If there is no * match, we will first try to match the flight to a typical flight between * the provided origin and destination airports. Otherwise, we will use the * distance-based emissions model if the flight distance is provided. */ destination?: string; /** * Optional. Distance in kilometers, e.g. `2423`, from [1, 2.5e16) km. This * is used to match a flight to distance-based emissions when origin and * destination are not provided or there are no matching typical flights. */ distanceKm?: bigint; /** * Optional. Up to 4-digit [flight * number](https://en.wikipedia.org/wiki/Flight_number), e.g. `71`, from [1, * 9999]. This is first used to match a specific flight if a flight number is * specified alongside origin, destination, and carrier. If a flight number is * not specified, we will first try to match the flight to a typical flight * between the provided origin and destination airports. If that fails and/or * origin & destination are not provided, we will use the distance-based * emissions model based on the flight distance provided. */ flightNumber?: number; /** * Optional. 3-character [IATA airport * code](https://www.iata.org/en/publications/directories/code-search/) for * flight origin, e.g. `YVR`. This is used to match specific flight if * provided alongside destination, carrier, and flight number. If there is no * match, we will first try to match the flight to a typical flight between * the provided origin and destination airports. Otherwise, we will use the * distance-based emissions model if the flight distance is provided. */ origin?: string; } function serializeScope3FlightSegment(data: any): Scope3FlightSegment { return { ...data, distanceKm: data["distanceKm"] !== undefined ? String(data["distanceKm"]) : undefined, }; } function deserializeScope3FlightSegment(data: any): Scope3FlightSegment { return { ...data, distanceKm: data["distanceKm"] !== undefined ? BigInt(data["distanceKm"]) : undefined, }; } /** * Typical flight emission estimates for a certain market */ export interface TypicalFlightEmissions { /** * Optional. Typical flight emissions per passenger for requested market. * Will not be present if a typical emissions could not be computed. For the * list of reasons why typical flight emissions could not be computed, see * [GitHub](https://github.com/google/travel-impact-model/blob/main/projects/typical_flight_emissions.md#step-7-validate-dataset). */ emissionsGramsPerPax?: EmissionsGramsPerPax; /** * Required. Matches the flight identifiers in the request. Note: all IATA * codes are capitalized. */ market?: Market; }