import { FeatureCollection } from 'geojson' ; export const Enum = < T extends string > ( ... keys ) => Object . freeze ( keys . reduce ( ( e , key ) => { return { ... e , [ key ] : key } ; } , { } ) as { [ K in T ] : K ; } ) ; export const isEnum = ( enums , value ) => typeof value === 'string' && typeof enums === 'object' && enums [ value ] === value ; export const VEHICLE_TYPES = Enum ( 'car' , 'bicycle' , 'scooter' , 'moped' , 'recumbent' ) ; export type VEHICLE_TYPE = keyof typeof VEHICLE_TYPES ; export const RULE_TYPES = Enum ( 'count' , 'speed' , 'time' , 'user' ) ; export type RULE_TYPE = keyof typeof RULE_TYPES ; export const RULE_UNIT_MAP = { minutes : 60 , hours : 60 * 60 } ; export const PROPULSION_TYPES = Enum ( 'human' , 'electric' , 'electric_assist' , 'hybrid' , 'combustion' ) ; export type PROPULSION_TYPE = keyof typeof PROPULSION_TYPES ; export const VEHICLE_STATUSES = Enum ( 'available' , 'reserved' , 'unavailable' , 'removed' , 'inactive' , 'trip' , 'elsewhere' ) ; export type VEHICLE_STATUS = keyof typeof VEHICLE_STATUSES ; export const RIGHT_OF_WAY_STATUSES = [ 'available' , 'reserved' , 'unavailable' , 'trip' ] ; export const VEHICLE_EVENTS = Enum ( 'register' , 'service_start' , 'service_end' , 'provider_drop_off' , 'provider_pick_up' , 'agency_pick_up' , 'agency_drop_off' , 'reserve' , 'cancel_reservation' , 'trip_start' , 'trip_enter' , 'trip_leave' , 'trip_end' , 'deregister' ) ; export type VEHICLE_EVENT = keyof typeof VEHICLE_EVENTS ; export const VEHICLE_REASONS = Enum ( 'battery_charged' , 'charge' , 'compliance' , 'decommissioned' , 'low_battery' , 'maintenance' , 'missing' , 'off_hours' , 'rebalance' ) ; export type VEHICLE_REASON = keyof typeof VEHICLE_REASONS ; export const AUDIT_EVENT_TYPES = Enum ( 'start' , 'note' , 'summary' , 'issue' , 'telemetry' , 'end' ) ; export type AUDIT_EVENT_TYPE = keyof typeof AUDIT_EVENT_TYPES ; export const EVENT_STATUS_MAP = { register : VEHICLE_STATUSES . removed , service_start : VEHICLE_STATUSES . available , service_end : VEHICLE_STATUSES . unavailable , provider_drop_off : VEHICLE_STATUSES . available , provider_pick_up : VEHICLE_STATUSES . removed , agency_pick_up : VEHICLE_STATUSES . removed , agency_drop_off : VEHICLE_STATUSES . available , reserve : VEHICLE_STATUSES . reserved , cancel_reservation : VEHICLE_STATUSES . available , trip_start : VEHICLE_STATUSES . trip , trip_enter : VEHICLE_STATUSES . trip , trip_leave : VEHICLE_STATUSES . elsewhere , trip_end : VEHICLE_STATUSES . available , deregister : VEHICLE_STATUSES . inactive } ; const StatusEventMap = < T extends { [ S in VEHICLE_STATUS ] : Partial < typeof VEHICLE_EVENTS > ; } > ( map ) => map ; export const STATUS_EVENT_MAP = StatusEventMap ( { available : Enum ( VEHICLE_EVENTS . service_start , VEHICLE_EVENTS . provider_drop_off , VEHICLE_EVENTS . cancel_reservation , VEHICLE_EVENTS . agency_drop_off ) , reserved : Enum ( VEHICLE_EVENTS . reserve ) , unavailable : Enum ( VEHICLE_EVENTS . service_end , VEHICLE_EVENTS . trip_end ) , trip : Enum ( VEHICLE_EVENTS . trip_start , VEHICLE_EVENTS . trip_enter ) , elsewhere : Enum ( VEHICLE_EVENTS . trip_leave ) , removed : Enum ( VEHICLE_EVENTS . register , VEHICLE_EVENTS . provider_pick_up , VEHICLE_EVENTS . agency_pick_up ) , inactive : Enum ( VEHICLE_EVENTS . deregister ) } ) ; export const DAYS_OF_WEEK = Enum ( 'sun' , 'mon' , 'tue' , 'wed' , 'thu' , 'fri' , 'sat' ) ; export type DAY_OF_WEEK = keyof typeof DAYS_OF_WEEK ; export const TIME_FORMAT = 'HH:mm:ss' ; format title examples pattern export type UUID = string ; export type Timestamp = number ; export type Stringify < T > = { [ P in keyof T ] : string ; } ; export type Nullable < T > = T | null ; export type NullableProperties < T extends object > = { [ P in keyof T ] - ? : T [ P ] extends null ? T [ P ] : Nullable < T [ P ] > ; } ; export type SingleOrArray < T > = T | T [ ] ; export type Optional < T , P extends keyof T > = Omit < T , P > & Partial < Pick < T , P > > ; export interface Device { device_id : UUID ; provider_id : UUID ; vehicle_id : string ; type : VEHICLE_TYPE ; propulsion : PROPULSION_TYPE [ ] ; year ? : number | null ; mfgr ? : string | null ; model ? : string | null ; recorded : Timestamp ; status ? : VEHICLE_STATUS | null ; } export type DeviceID = Pick < Device , 'provider_id' | 'device_id' > ; export interface VehicleEvent { device_id : UUID ; provider_id : UUID ; timestamp : Timestamp ; timestamp_long ? : string | null ; delta ? : Timestamp | null ; event_type : VEHICLE_EVENT ; event_type_reason ? : VEHICLE_REASON | null ; telemetry_timestamp ? : Timestamp | null ; telemetry ? : Telemetry | null ; trip_id ? : UUID | null ; service_area_id ? : UUID | null ; recorded : Timestamp ; } export interface TelemetryData { lat : number ; lng : number ; speed ? : number | null ; heading ? : number | null ; accuracy ? : number | null ; hdop ? : number | null ; altitude ? : number | null ; satellites ? : number | null ; charge ? : number | null ; } export type GpsData = Omit < TelemetryData , 'charge' > ; export type WithGpsProperty < T extends TelemetryData > = Omit < T , keyof Omit < TelemetryData , 'charge' > > & { gps : Omit < TelemetryData , 'charge' > ; } ; export interface Telemetry extends WithGpsProperty < TelemetryData > { provider_id : UUID ; device_id : UUID ; timestamp : Timestamp ; recorded ? : Timestamp ; } export interface Attachment { attachment_filename : string ; attachment_id : UUID ; base_url : string ; mimetype : string ; thumbnail_filename ? : string | null ; thumbnail_mimetype ? : string | null ; recorded ? : Timestamp | null ; } export interface AttachmentSummary { attachment_id : UUID ; attachment_url : string ; thumbnail_url ? : string | null ; } export interface Audit { audit_trip_id : UUID ; audit_device_id : UUID ; audit_subject_id : string ; provider_id : UUID ; provider_name : string ; provider_vehicle_id : string ; provider_device_id : UUID | null ; timestamp : Timestamp ; recorded : Timestamp ; } export interface AuditAttachment { attachment_id : UUID ; audit_trip_id : UUID ; recorded : Timestamp ; } export interface AuditEvent extends TelemetryData { audit_trip_id : UUID ; audit_event_id : UUID ; audit_event_type : AUDIT_EVENT_TYPE | VEHICLE_EVENT ; audit_issue_code ? : string | null ; audit_subject_id : string ; note ? : string | null ; timestamp : Timestamp ; recorded : Timestamp ; } export interface AuditDetails extends Audit { events : WithGpsProperty < AuditEvent > [ ] ; provider_event_type ? : string | null ; provider_event_type_reason ? : string | null ; provider_status ? : string | null ; provider_telemetry ? : Telemetry | null ; provider_event_time ? : Timestamp | null ; attachments : AttachmentSummary [ ] ; provider : null | { device : Device ; events : VehicleEvent [ ] ; telemetry : Telemetry [ ] ; } ; } export interface PolicyMessage { [ key ] : string ; } interface BaseRule < RuleType = 'count' | 'speed' | 'time' > { name : string ; rule_id : UUID ; geographies : UUID [ ] ; statuses : Partial < { [ S in VEHICLE_STATUS ] : ( keyof typeof STATUS_EVENT_MAP [ S ] ) [ ] | [ ] ; } > | null ; rule_type : RuleType ; vehicle_types ? : VEHICLE_TYPE [ ] | null ; maximum ? : number | null ; minimum ? : number | null ; start_time ? : string | null ; end_time ? : string | null ; days ? : DAY_OF_WEEK [ ] | null ; messages ? : PolicyMessage ; value_url ? : URL | null ; } export type CountRule = BaseRule < 'count' > ; export interface TimeRule extends BaseRule < 'time' > { rule_units : 'minutes' | 'hours' ; } export interface SpeedRule extends BaseRule < 'speed' > { rule_units : 'kph' | 'mph' ; } export type UserRule = BaseRule < 'user' > ; export type Rule = CountRule | TimeRule | SpeedRule | UserRule ; export interface Policy { name : string ; description : string ; provider_ids ? : UUID [ ] ; published_date ? : Timestamp ; policy_id : UUID ; start_date : Timestamp ; end_date : Timestamp | null ; prev_policies : UUID [ ] | null ; rules : Rule [ ] ; publish_date ? : Timestamp ; } export interface PolicyMetadata { policy_id : UUID ; policy_metadata : Record < string , any > ; } export interface MatchedVehicle { device_id : UUID ; provider_id : UUID ; vehicle_id : string ; vehicle_type : VEHICLE_TYPE ; vehicle_status : VEHICLE_STATUS ; gps : { lat : number ; lng : number ; } ; } export interface CountMatch { measured : number ; geography_id : UUID ; matched_vehicles : MatchedVehicle [ ] ; } export interface TimeMatch { measured : number ; geography_id : UUID ; matched_vehicle : MatchedVehicle ; } export interface SpeedMatch { measured : number ; geography_id : UUID ; matched_vehicle : MatchedVehicle ; } export interface ReducedMatch { measured : number ; geography_id : UUID ; } export interface Compliance { rule : Rule ; matches : ReducedMatch [ ] | CountMatch [ ] | TimeMatch [ ] | SpeedMatch [ ] ; } export interface ComplianceResponse { policy : Policy ; compliance : Compliance [ ] ; total_violations : number ; vehicles_in_violation : { device_id : UUID ; rule_id : UUID ; } [ ] ; } export interface Geography { geography_id : UUID ; geography_json : FeatureCollection ; prev_geographies ? : UUID [ ] ; name : string ; publish_date ? : Timestamp ; effective_date ? : Timestamp ; description ? : string ; } export type GeographySummary = Omit < Geography , 'geography_json' > ; export interface GeographyMetadata { geography_id : UUID ; geography_metadata : Record < string , any > ; } export interface ErrorObject { error : string ; error_description : string ; } export interface CountMap { [ P ] : number ; } export interface TripsStats { single : number ; singles : CountMap ; mysteries : CountMap ; mystery_examples : { [ key ] : UUID [ ] ; } ; } export type Recorded < T > = Readonly < Required < T & { id : number ; } > > ; export interface BBox { latMin : number ; latMax : number ; lngMin : number ; lngMax : number ; } export type BoundingBox = [ [ number , number ] , [ number , number ] ] ; export interface Provider { provider_id : UUID ; provider_name : string ; url ? : string ; mds_api_url ? : string ; gbfs_api_url ? : string ; } export interface Stop { stop_id : UUID ; stop_name : string ; short_name ? : string ; platform_code ? : string ; geography_id ? : UUID ; lat : number ; lng : number ; zone_id ? : UUID ; address ? : string ; post_code ? : string ; rental_methods ? : string ; capacity : Partial < { [ S in VEHICLE_TYPE ] : number ; } > ; location_type ? : string ; timezone ? : string ; cross_street ? : string ; num_vehicles_available : Partial < { [ S in VEHICLE_TYPE ] : number ; } > ; num_vehicles_disabled ? : Partial < { [ S in VEHICLE_TYPE ] : number ; } > ; num_spots_available : Partial < { [ S in VEHICLE_TYPE ] : number ; } > ; num_spots_disabled ? : Partial < { [ S in VEHICLE_TYPE ] : number ; } > ; wheelchair_boarding ? : boolean ; reservation_cost ? : Partial < { [ S in VEHICLE_TYPE ] : number ; } > ; } export interface JsonArray extends Array < Json > { } export interface JsonObject { [ property ] : Json ; } export type JsonValue = string | number | boolean | JsonArray | JsonObject ; export type Json = Nullable < JsonValue > ; export type AnyFunction < A = any > = ( ... args : any [ ] ) => A ; export type AnyConstructor < A = object > = new ( ... args ) => A ;