js-utils.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. export interface Map<T> {
  2. [key: string]: T;
  3. }
  4. export function flat<T>(a: T[][]): T[] { return a.reduce((x, y) => x.concat(y), []); }
  5. export function uuid(prefix?: string): string { // TODO: use proper UUID generation
  6. return !!prefix ? `${prefix}-${Math.random()}` : `${Math.random()}`;
  7. }
  8. export function mapToArray<T>(m: Map<T>) {
  9. return Object.keys(m).map((id) => m[id]);
  10. }
  11. export function arrayToMap<T, K extends keyof T>(arr: T[], key: K): Map<T> {
  12. const map: Map<T> = {};
  13. arr.forEach((x) => map[x[`${key}`]] = x);
  14. return map;
  15. }
  16. export function uniqueObjCharKeys<T>(m: Map<T>) {
  17. const keys = [];
  18. Object.keys(m).forEach(key => {
  19. if (keys.indexOf(key[0].toLowerCase()) < 0) {
  20. keys.push(key[0].toLowerCase());
  21. }
  22. });
  23. keys.sort();
  24. return keys;
  25. }
  26. export function uniqueArrayCharKeys(a: string[]) {
  27. const keys = [];
  28. a.forEach(key => {
  29. if (keys.indexOf(key[0].toLowerCase()) < 0) {
  30. keys.push(key[0].toLowerCase());
  31. }
  32. });
  33. keys.sort((strA, strB) => strA.toLowerCase().localeCompare(strB.toLowerCase()));
  34. return keys;
  35. }
  36. /**
  37. * Performs a deep merge of objects and returns new object. Does not modify
  38. * objects (immutable) and merges arrays via concatenation.
  39. *
  40. * @param objects - Objects to merge
  41. * @returns New object with merged key/values
  42. */
  43. export function mergeDeep<T>(...objects: T[]) { // TODO: never used, remove?
  44. const isObject = (obj: T) => obj && typeof obj === 'object';
  45. const cb = (prev: T, obj: T) => {
  46. Object.keys(obj).forEach(key => {
  47. const pVal = prev[key];
  48. const oVal = obj[key];
  49. if (Array.isArray(pVal) && Array.isArray(oVal)) {
  50. prev[key] = [...pVal, ...oVal].filter((element, index, array) => array.indexOf(element) === index);
  51. } else if (isObject(pVal) && isObject(oVal)) {
  52. prev[key] = mergeDeep(pVal, oVal);
  53. } else {
  54. prev[key] = oVal;
  55. }
  56. });
  57. return prev;
  58. };
  59. return objects.reduce(cb, {});
  60. }
  61. export function getEventKeyCode(event) {
  62. let code: number | string;
  63. if (event.key !== undefined) {
  64. code = event.key;
  65. } else if (event.keyIdentifier !== undefined) {
  66. code = event.keyIdentifier;
  67. } else if (event.keyCode !== undefined) {
  68. code = event.keyCode;
  69. }
  70. return code;
  71. }
  72. export function normalizeUrl(url) {
  73. return url && url.indexOf('http') < 0 ? 'http://' + url : url;
  74. }
  75. export function isBoolString(s: string) {
  76. return s === 'true';
  77. }
  78. export function snakeToCamelCased(str) {
  79. return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
  80. }
  81. export function isUrl(path: string) {
  82. return /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(path);
  83. }