2020-01-07 13:14:51 -05:00
|
|
|
import isEqual from 'lodash.isequal';
|
2019-08-06 17:11:17 -04:00
|
|
|
import urlapi from 'url';
|
|
|
|
|
|
|
|
function sanitiseURL(string){
|
2019-11-07 03:13:30 -05:00
|
|
|
let url_;
|
2019-08-06 17:11:17 -04:00
|
|
|
|
|
|
|
// http or https
|
|
|
|
if (!(string.substring(0, 7) === 'http://' || string.substring(0, 8) === 'https://')){
|
2019-11-07 03:13:30 -05:00
|
|
|
return null;
|
2019-08-06 17:11:17 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2019-11-07 03:13:30 -05:00
|
|
|
url_ = document.createElement('a');
|
|
|
|
url_.href = string;
|
2019-08-06 17:11:17 -04:00
|
|
|
} catch (error) {
|
|
|
|
try {
|
2019-11-07 03:13:30 -05:00
|
|
|
url_ = urlapi.parse(string);
|
2019-08-06 17:11:17 -04:00
|
|
|
} catch (error) {
|
2019-11-07 03:13:30 -05:00
|
|
|
return null;
|
2019-08-06 17:11:17 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// required (www.example.com)
|
|
|
|
if (!url_.hostname || url_.hostname === '' || url_.hostname === 'localhost'){
|
2019-11-07 03:13:30 -05:00
|
|
|
return null;
|
2019-08-06 17:11:17 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// optional (/some/path)
|
|
|
|
// url_.pathname;
|
|
|
|
|
|
|
|
// optional (?name=value)
|
|
|
|
// url_.search;
|
|
|
|
|
|
|
|
// optional (#anchor)
|
|
|
|
// url_.hash;
|
|
|
|
|
2019-11-07 03:13:30 -05:00
|
|
|
return `${url_.protocol}//${url_.hostname}${url_.pathname || ''}${url_.search || ''}${url_.hash || ''}`;
|
2019-08-06 17:11:17 -04:00
|
|
|
}
|
|
|
|
|
2019-10-24 10:57:09 -04:00
|
|
|
/**
|
|
|
|
* Transform an array of objects into a dictionary of arrays of objects,
|
|
|
|
* where the objects are grouped into arrays given an arbitrary key function
|
|
|
|
* that gives a key for each object.
|
|
|
|
* @param arr array of objects to group
|
|
|
|
* @param keyAccessor function returning the grouping key for each object in the original array
|
|
|
|
*/
|
2019-10-24 07:19:54 -04:00
|
|
|
function arrayToDictionary<T>(arr: T[], keyAccessor: (obj: T) => string): {[key: string]: T[]} {
|
|
|
|
return arr.reduce((obj, item) => {
|
|
|
|
(obj[keyAccessor(item)] = obj[keyAccessor(item)] || []).push(item);
|
|
|
|
return obj;
|
|
|
|
}, {});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-10-24 10:57:09 -04:00
|
|
|
* Parse a string containing an ISO8601 formatted date
|
|
|
|
* @param isoUtcDate a date string in ISO8601 format, assuming UTC
|
|
|
|
* @returns a JS Date object with the UTC time encoded
|
2019-10-24 07:19:54 -04:00
|
|
|
*/
|
|
|
|
function parseDate(isoUtcDate: string): Date {
|
|
|
|
const [year, month, day, hour, minute, second, millisecond] = isoUtcDate.match(/^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d).(\d{3})Z$/)
|
|
|
|
.splice(1)
|
|
|
|
.map(x => parseInt(x, 10));
|
|
|
|
return new Date(Date.UTC(year, month-1, day, hour, minute, second, millisecond));
|
|
|
|
}
|
|
|
|
|
2019-10-15 14:16:48 -04:00
|
|
|
function compareObjects(objA: object, objB: object): [object, object] {
|
2019-11-07 03:13:30 -05:00
|
|
|
const reverse = {};
|
|
|
|
const forward = {};
|
2019-10-15 14:16:48 -04:00
|
|
|
for (const [key, value] of Object.entries(objB)) {
|
2020-01-07 13:14:51 -05:00
|
|
|
if (!isEqual(objA[key], value)) {
|
2019-10-15 14:16:48 -04:00
|
|
|
reverse[key] = objA[key];
|
|
|
|
forward[key] = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return [forward, reverse];
|
|
|
|
}
|
|
|
|
|
2019-10-24 07:19:54 -04:00
|
|
|
export {
|
2019-10-29 13:58:01 -04:00
|
|
|
sanitiseURL,
|
|
|
|
arrayToDictionary,
|
|
|
|
parseDate,
|
|
|
|
compareObjects
|
2019-10-24 07:19:54 -04:00
|
|
|
};
|