/**
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ import { AxiosInstance , AxiosRequestConfig , AxiosResponse } from "axios" ; import { DirectionsRoute , GeocodedWaypoint , Language , LatLng , RequestParams , ResponseData , TrafficModel , TransitMode , TransitRoutingPreference , TravelMode , TravelRestriction , UnitSystem , } from "./common" ; import { latLngToString , serializer , toTimestamp } from "./serialize" ; import { defaultAxiosInstance } from "./client" ; export interface DirectionsRequest extends Partial < AxiosRequestConfig > { params : { /**
         * The address, textual latitude/longitude value, or place ID from which you wish to calculate directions.
         *  - If you pass an address, the Directions service geocodes the string and converts it to a latitude/longitude coordinate
         *    to calculate directions. This coordinate may be different from that returned by the Geocoding API, for example a building
         *    entrance rather than its center.
         *
         *    `origin=24+Sussex+Drive+Ottawa+ON`
         *
         *  - If you pass coordinates, they are used unchanged to calculate directions. Ensure that no space exists between the latitude
         *    and longitude values.
         *
         *    `origin=41.43206,-81.38992`
         *
         *  - Place IDs must be prefixed with `place_id:`. The place ID may only be specified if the request includes an API key or a
         *    Google Maps APIs Premium Plan client ID. You can retrieve place IDs from the Geocoding API and the Places SDK
         *    (including Place Autocomplete). For an example using place IDs from Place Autocomplete, see [Place Autocomplete and
         *    Directions](https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-directions).
         *
         *    `origin=place_id:ChIJ3S-JXmauEmsRUcIaWtf4MzE`
         */ origin : LatLng ; /**
         * The address, textual latitude/longitude value, or place ID to which you wish to calculate directions.
         * The options for the `destination` parameter are the same as for the `origin` parameter, described above
         */ destination : LatLng ; default mode ? : TravelMode ; /**
         * Specifies an array of waypoints.
         * Waypoints alter a route by routing it through the specified location(s).
         * A waypoint is specified as a latitude/longitude coordinate, an encoded polyline, a place ID, or an address which will be geocoded.
         * Encoded polylines must be prefixed with `enc:` and followed by a colon (`:`). Place IDs must be prefixed with `place_id:`.
         * The place ID may only be specified if the request includes an API key or a Google Maps APIs Premium Plan client ID.
         * Waypoints are only supported for driving, walking and bicycling directions.
         */ waypoints ? : ( string | LatLng ) [ ] ; /**
         * If set to `true`, specifies that the Directions service may provide more than one route alternative in the response.
         * Note that providing route alternatives may increase the response time from the server.
         */ alternatives ? : boolean ; /** Indicates that the calculated route(s) should avoid the indicated features. */ avoid ? : TravelRestriction [ ] ; /**
         * The language in which to return results.
         *
         *  - If `language` is not supplied, the API attempts to use the preferred language as specified in the `Accept-Language` header,
         *    or the native language of the domain from which the request is sent.
         *  - The API does its best to provide a street address that is readable for both the user and locals. To achieve that goal,
         *    it returns street addresses in the local language, transliterated to a script readable by the user if necessary,
         *    observing the preferred language. All other addresses are returned in the preferred language.
         *    Address components are all returned in the same language, which is chosen from the first component.
         *  - If a name is not available in the preferred language, the API uses the closest match.
         *  - The preferred language has a small influence on the set of results that the API chooses to return,
         *    and the order in which they are returned. The geocoder interprets abbreviations differently depending on language,
         *    such as the abbreviations for street types, or synonyms that may be valid in one language but not in another.
         *    For example, utca and tér are synonyms for street in Hungarian.
         */ language ? : Language ; /** Specifies the unit system to use when displaying results. */ units ? : UnitSystem ; /** Specifies the region code, specified as a ccTLD ("top-level domain") two-character value. */ region ? : string ; /**
         * Specifies the desired time of arrival for transit directions, in seconds since midnight, January 1, 1970 UTC.
         * You can specify either `departure_time` or `arrival_time`, but not both.
         * Note that `arrival_time` must be specified as an integer.
         */ arrival_time ? : Date | number ; /**
         * Specifies the desired time of departure. You can specify the time as an integer in seconds since midnight, January 1, 1970 UTC.
         * Alternatively, you can specify a value of `now`, which sets the departure time to the current time (correct to the nearest second).
         *
         * The departure time may be specified in two cases:
         *  - For requests where the travel mode is transit: You can optionally specify one of `departure_time` or `arrival_time`.
         *    If neither time is specified, the `departure_time` defaults to now (that is, the departure time defaults to the current time).
         *  - For requests where the travel mode is driving: You can specify the `departure_time` to receive a route and trip duration
         *    (response field: `duration_in_traffic`) that take traffic conditions into account.
         *    This option is only available if the request contains a valid API key, or a valid Google Maps APIs Premium Plan client ID
         *    and signature. The `departure_time` must be set to the current time or some time in the future. It cannot be in the past.
         */ departure_time ? : Date | number | "now" ; default traffic_model ? : TrafficModel ; /**
         * Specifies one or more preferred modes of transit.
         * This parameter may only be specified for transit directions, and only if the request includes an API key or
         * a Google Maps APIs Premium Plan client ID.
         */ transit_mode ? : TransitMode [ ] ; /**
         * Specifies preferences for transit routes.
         * Using this parameter, you can bias the options returned, rather than accepting the default best route chosen by the API.
         * This parameter may only be specified for transit directions, and only if the request includes an API key or
         * a Google Maps APIs Premium Plan client ID.
         */ transit_routing_preference ? : TransitRoutingPreference ; /** Wherever to optimize the provided route by rearranging the waypoints in a more efficient order. */ optimize ? : boolean ; } & RequestParams ; } export interface DirectionsResponseData extends ResponseData { /**
     * contains an array with details about the geocoding of origin, destination and waypoints.
     *
     * These details will not be present for waypoints specified as textual latitude/longitude values if the service returns no results.
     * This is because such waypoints are only reverse geocoded to obtain their representative address after a route has been found.
     * An empty JSON object will occupy the corresponding places in the `geocoded_waypoints` array.
     */ geocoded_waypoints : GeocodedWaypoint [ ] ; /**
     * contains an array of routes from the origin to the destination.
     *
     * When the Directions API returns results, it places them within a (JSON) `routes` array. Even if the service returns no results
     * (such as if the origin and/or destination doesn't exist) it still returns an empty `routes` array.
     * (XML responses consist of zero or more `<route>` elements.)
     *
     * Each element of the `routes` array contains a single result from the specified origin and destination.
     * This route may consist of one or more `legs` depending on whether any waypoints were specified.
     * As well, the route also contains copyright and warning information which must be displayed to the user in addition to the
     * routing information.
     */ routes : DirectionsRoute [ ] ; /**
     * contains an array of available travel modes. This field is returned when a request specifies a travel `mode` and gets no results.
     * The array contains the available travel modes in the countries of the given set of waypoints.
     * This field is not returned if one or more of the waypoints are `via:` waypoints.
     */ available_travel_modes : string [ ] ; } export interface DirectionsResponse extends AxiosResponse { data : DirectionsResponseData ; } export const defaultUrl = "https://maps.googleapis.com/maps/api/directions/json" ; export const defaultParamsSerializer = serializer ( { origin : latLngToString , destination : latLngToString , waypoints : ( o ) => o . map ( latLngToString ) , arrival_time : toTimestamp , departure_time : toTimestamp , } , defaultUrl ) ; export function directions ( { params , method = "get" , url = defaultUrl , paramsSerializer = defaultParamsSerializer , ... config } , axiosInstance = defaultAxiosInstance ) { const { optimize } = params ; if ( optimize ) { params . waypoints = [ "optimize:true" , ... params . waypoints ] ; } delete params . optimize ; return axiosInstance ( { params , method , url , paramsSerializer , ... config , } ) as Promise < DirectionsResponse > ; }