Merge pull request #20 from owntracks/clean-up-the-typing-mess

Clean up the typing mess
This commit is contained in:
Linus Groh
2020-03-01 20:59:36 +00:00
committed by GitHub
6 changed files with 231 additions and 91 deletions

View File

@@ -1,23 +1,11 @@
import { log, logLevels } from "@/logging";
import { getApiUrl } from "@/util";
/** @typedef {import("./types").QueryParams} QueryParams */
/** @typedef {import("./types").User} User */
/** @typedef {import("./types").Device} Device */
/** @typedef {import("./types").LastLocation} LastLocation */
/** @typedef {import("./types").LocationHistory} LocationHistory */
/**
* Callback for new WebSocket location messages.
*
* @callback webSocketLocationCallback
*/
/**
* Fetch an API resource.
*
* @param {String} path API resource path
* @param {QueryParams} [params] Query parameters
* @param {Object} [params] Query parameters
* @returns {Promise} Promise returned by the fetch function
*/
const fetchApi = (path, params = {}) => {
@@ -42,7 +30,7 @@ export const getVersion = async () => {
/**
* Get all users.
*
* @returns {Array.<User>} Array of usernames
* @returns {User[]} Array of usernames
*/
export const getUsers = async () => {
const response = await fetchApi("/api/0/list");
@@ -54,8 +42,8 @@ export const getUsers = async () => {
/**
* Get all devices for the provided users.
*
* @param {Array.<User>} users Array of usernames
* @returns {Object.<User, Array.<Device>>}
* @param {User[]} users Array of usernames
* @returns {{User: Device[]}}
* Object mapping each username to an array of device names
*/
export const getDevices = async users => {
@@ -76,7 +64,7 @@ export const getDevices = async users => {
*
* @param {User} [user] Get last locations of all devices from this user
* @param {Device} [device] Get last location of specific device
* @returns {Array.<LastLocation>} Array of last location objects
* @returns {OTLocation[]} Array of last location objects
*/
export const getLastLocations = async (user, device) => {
const params = {};
@@ -98,7 +86,7 @@ export const getLastLocations = async (user, device) => {
* @param {Device} device Device name
* @param {String} start Start date and time in UTC
* @param {String} end End date and time in UTC
* @returns {LocationHistory} Array of location history objects
* @returns {OTLocation[]} Array of location history objects
*/
export const getUserDeviceLocationHistory = async (
user,
@@ -120,12 +108,11 @@ export const getUserDeviceLocationHistory = async (
/**
* Get the location history of multiple devices.
*
* @param {Object.<User, Array.<Device>>} devices
* @param {{User: Device[]}} devices
* Devices of which the history should be fetched
* @param {String} start Start date and time in UTC
* @param {String} end End date and time in UTC
* @returns {Object.<User, Object.<Device, LocationHistory>>}
* Array of location history objects
* @returns {LocationHistory} Location history
*/
export const getLocationHistory = async (devices, start, end) => {
const locationHistory = {};
@@ -151,7 +138,7 @@ export const getLocationHistory = async (devices, start, end) => {
* Connect to the WebSocket API, reconnect when necessary and handle received
* messages.
*
* @param {webSocketLocationCallback} [callback] Callback for location messages
* @param {WebSocketLocationCallback} [callback] Callback for location messages
*/
export const connectWebsocket = async callback => {
let url = getApiUrl("/ws/last");

220
src/index.d.ts vendored Normal file
View File

@@ -0,0 +1,220 @@
/** Configuration object. */
interface Config {
api: {
baseUrl: string;
};
endDateTime: Date;
ignorePingLocation: boolean;
locale: string;
map: {
attribution: string;
circle: {
color: OptionalColor;
fillColor: OptionalColor;
fillOpacity: number;
};
circleMarker: {
color: OptionalColor;
fillColor: OptionalColor;
fillOpacity: number;
radius: number;
};
controls: {
scale: {
display: boolean;
imperial: boolean;
maxWidth: number;
metric: boolean;
position: string;
};
zoom: {
display: boolean;
position: string;
};
};
heatmap: {
blur: number;
gradient: { number: Color } | null;
max: number;
radius: number;
};
layers: {
heatmap: boolean;
last: boolean;
line: boolean;
points: boolean;
};
maxNativeZoom: number;
maxPointDistance: number | null;
maxZoom: number;
polyline: {
color: OptionalColor;
fillColor: OptionalColor;
};
url: string;
};
onLocationChange: {
reloadHistory: boolean;
};
primaryColor: Color;
selectedUser: User| null;
selectedDevice: Device| null;
startDateTime: Date;
verbose: boolean;
}
/** Vuex state. */
interface State {
isLoading: boolean;
frontendVersion: string;
recorderVersion: string;
users: User[];
devices: { User: Device[] };
lastLocations: OTLocation[];
locationHistory: LocationHistory;
selectedUser: User| null;
selectedDevice: Device| null;
startDateTime: string;
endDateTime: string;
map: {
center: {
lat: number;
lng: number;
};
layers: {
heatmap: boolean;
last: boolean;
line: boolean;
points: boolean;
};
zoom: number;
};
}
/**
* A location object as returned by the OwnTracks recorder.
* https://owntracks.org/booklet/tech/json/#_typelocation
*/
interface OTLocation {
_http: boolean;
/**
* In this case always "location"
* https://owntracks.org/booklet/tech/json/#types
*/
_type: string;
/** Accuracy in meters */
acc?: number;
/** Altitude above sea level in meters */
alt?: number;
/** Device battery level in percent */
batt?: number;
/**
* Battery status (iOS only)
*
* - `0` = unknown
* - `1` = unplugged
* - `2` = charging
* - `3` = full
*/
bs?: number;
/** Course over ground in degrees (iOS only) */
cog?: number;
/**
* Internet connectivity status (route to host) when the message is created
*
* - `"w"` = phone is connected to a WiFi connection
* - `"o"` = phone is offline
* - `"m"` = mobile data
*/
conn?: string;
/** Device name */
device?: Device;
/** Timestamp in a readable format */
disptst: string;
/** Base64-encoded face image (device icon) */
face?: string;
/**
* Geohash of the location
* https://en.wikipedia.org/wiki/Geohash
*/
ghash?: string;
/** Regions the device is currently in (e.g. `["Home", "Garage"]`). Might be empty. */
inregions?: string[];
/**
* No idea; some kind of timestamp as well - figure it out yourself. :)
* https://github.com/owntracks/recorder/blob/df009f791a845012e9cce24923e6203a079ca1ed/storage.c#L659
* https://github.com/owntracks/recorder/blob/df009f791a845012e9cce24923e6203a079ca1ed/storage.c#L704
*/
isorcv?: string;
/** ISO 8601 timestamp */
isotst?: string;
/** Latitude in degrees */
lat: number;
/** Longitude in degrees */
lon: number;
/** Friendly device name */
name?: string;
/**
* Trigger for the location report
*
* - `"p"` = ping issued randomly by background task
* - `"c"` = circular region enter/leave event
* - `"b"` = beacon region enter/leave event (iOS only)
* - `"r"` = response to a reportLocation cmd message
* - `"u"` = manual publish requested by the user
* - `"t"` = timer based publish in move move (iOS only)
* - `"v"` = updated by Settings/Privacy/Locations Services/System Services/Frequent Locations monitoring (iOS only)
*/
t?: string;
/** Tracker ID used to display the initials of a user */
tid?: string;
/**
* Original publish topic
* https://owntracks.org/booklet/tech/json/#topics
*/
topic?: string;
/** UNIX epoch timestamp of the location fix in seconds */
tst: number;
/** User */
username?: User;
/** Vertical accuracy of the alt element in meters */
vac?: number;
/** Velocity in km/h */
vel?: number;
}
/** URL query parameters (prior to any parsing so it's all strings). */
interface QueryParams {
/** Map center latitude */
lat?: string;
/** Map center longitude */
lng?: string;
/** Start date and time of selected time range */
start?: string;
/** End date and time of selected time range */
end?: string;
/** Selected user */
user?: string;
/** Selected device */
device?: string;
/** Comma-separated list of active layers */
layers?: string;
}
/** Callback for new WebSocket location messages. */
interface WebSocketLocationCallback { (): void }
/** A CSS color. */
type Color = string;
/** A CSS color that will use `primaryColor` as fallback. */
type OptionalColor = Color | null;
/** A user's name. */
type User = string;
/** A device's name. */
type Device = string;
/** Multiple location histories mapped to user and devices. */
type LocationHistory = { User: { Device: OTLocation[] } };

View File

@@ -3,10 +3,6 @@ import * as api from "@/api";
import config from "@/config";
import { distanceBetweenCoordinates, isIsoDateTime } from "@/util";
/** @typedef {import("./types").QueryParams} QueryParams */
/** @typedef {import("./types").User} User */
/** @typedef {import("./types").Device} Device */
/**
* Populate the state from URL query parameters.
*

View File

@@ -3,10 +3,6 @@ import L from "leaflet";
import config from "@/config";
import { distanceBetweenCoordinates } from "@/util";
/** @typedef {import("./types").State} State */
/** @typedef {import("./types").MultiLocationHistory} MultiLocationHistory */
/** @typedef {import("./types").DatepickerConfig} DatepickerConfig */
/**
* From the selected users' and devices' location histories, create an
* array of all coordinates.
@@ -14,7 +10,7 @@ import { distanceBetweenCoordinates } from "@/util";
* @param {State} state
* @param {MultiLocationHistory} state.locationHistory
* Location history of selected users and devices
* @returns {Array.<L.LatLng>} All coordinates
* @returns {L.LatLng[]} All coordinates
*/
const locationHistoryLatLngs = state => {
const latLngs = [];
@@ -36,7 +32,7 @@ const locationHistoryLatLngs = state => {
* @param {State} state
* @param {MultiLocationHistory} state.locationHistory
* Location history of selected users and devices
* @returns {Array.<Array.<L.LatLng>>} Groups of coherent coordinates
* @returns {L.LatLng[][]} Groups of coherent coordinates
*/
const locationHistoryLatLngGroups = state => {
const groups = [];

View File

@@ -1,57 +0,0 @@
/* eslint max-len: 0 */
/**
* A coordinate with latitude and longitude.
*
* @typedef Coordinate
* @type {(Object|L.LatLng)}
* @property {Number} lat Latitude
* @property {Number} lng Longitude
*/
/**
* Vuex state.
*
* @typedef {Object.<String, *>} State
*/
/**
* URL query parameter object.
*
* @typedef {Object.<String, *>} QueryParams
*/
/**
* @typedef {Object} DatepickerConfig
* @property {Function} DatepickerConfig.customPredictor Custom predictor function
*/
/**
* A user's name.
*
* @typedef {String} User
*/
/**
* A device's name.
*
* @typedef {String} Device
*/
/**
* A last location object.
*
* @typedef {Object.<String, *>} LastLocation
*/
/**
* An array of location history objects
*
* @typedef {Array.<Object.<String, *>>} LocationHistory
*/
/**
* Multiple arrays of location history objects mapped to user and devices.
*
* @typedef {Object.<User, Object.<Device, LocationHistory>>} MultiLocationHistory
*/

View File

@@ -3,8 +3,6 @@ import moment from "moment";
import config from "@/config";
import { DATE_TIME_FORMAT, EARTH_RADIUS_IN_KM } from "@/constants";
/** @typedef {import("./types").Coordinate} Coordinate */
/**
* Get a complete URL for any API resource, taking the
* base URL configuration into account.