UNPKG

universal-geocoder

Version:

Universal geocoding abstraction server-side and client-side with multiple built-in providers

96 lines (77 loc) 3.17 kB
export const isBrowser = (): boolean => typeof window !== "undefined"; export const filterUndefinedObjectValues = <V>( object: Record<string, V | undefined> ): Record<string, V> => Object.keys(object).reduce((acc: Record<string, V>, key) => { const filtered = acc; const value = object[key]; if (value !== undefined) { filtered[key] = value; } return filtered; }, {}); type NestedObject<V> = { [key: string]: V | NestedObject<V> | undefined; }; export const flattenObject = <S>( object: NestedObject<S> ): { [key: string]: S } => { const flattened: { [key: string]: S } = {}; const isNested = (value: NestedObject<S> | S): value is NestedObject<S> => { const isArray = Array.isArray(value); const type = Object.prototype.toString.call(value); const isObject = type === "[object Object]" || type === "[object Array]"; if (!isArray && isObject && Object.keys(value).length) { return true; } return false; }; const step = (nestedObject: NestedObject<S>): void => { Object.keys(nestedObject).forEach((key) => { const value = nestedObject[key]; if (undefined === value) { return; } if (isNested(value)) { step(value); return; } flattened[key] = value; }); }; step(object); return flattened; }; /** * Decode from URL-safe base64 to true base64. */ export const decodeUrlSafeBase64 = (safe: string): string => safe.replace(/-/g, "+").replace(/_/g, "/"); /** * Encode from true base64 to URL-safe base64. */ export const encodeUrlSafeBase64 = (base64: string): string => base64.replace(/\+/g, "-").replace(/\//g, "_"); export const decodeBase64 = (base64: string): string => { if (isBrowser()) { throw new Error("decodeBase64 can only be used in a Node environment."); } return Buffer.from(base64, "base64").toString(); }; // From https://github.com/sindresorhus/ip-regex const ipv4RegExp = "(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}"; export const isIpv4 = (ip: string): boolean => new RegExp(`^${ipv4RegExp}$`).test(ip); // From https://github.com/sindresorhus/ip-regex const ipv6Seg = "[a-fA-F\\d]{1,4}"; const ipv6RegExp = `((?:${ipv6Seg}:){7}(?:${ipv6Seg}|:)|(?:${ipv6Seg}:){6}(?:${ipv4RegExp}|:${ipv6Seg}|:)|(?:${ipv6Seg}:){5}(?::${ipv4RegExp}|(:${ipv6Seg}){1,2}|:)|(?:${ipv6Seg}:){4}(?:(:${ipv6Seg}){0,1}:${ipv4RegExp}|(:${ipv6Seg}){1,3}|:)|(?:${ipv6Seg}:){3}(?:(:${ipv6Seg}){0,2}:${ipv4RegExp}|(:${ipv6Seg}){1,4}|:)|(?:${ipv6Seg}:){2}(?:(:${ipv6Seg}){0,3}:${ipv4RegExp}|(:${ipv6Seg}){1,5}|:)|(?:${ipv6Seg}:){1}(?:(:${ipv6Seg}){0,4}:${ipv4RegExp}|(:${ipv6Seg}){1,6}|:)|(?::((?::${ipv6Seg}){0,5}:${ipv4RegExp}|(?::${ipv6Seg}){1,7}|:)))(%[0-9a-zA-Z]{1,})?`; export const isIpv6 = (ip: string): boolean => new RegExp(`^${ipv6RegExp}$`).test(ip); // eslint-disable-next-line @typescript-eslint/ban-types export const getRequireFunc = (): Function => // eslint-disable-next-line camelcase typeof __non_webpack_require__ === "function" ? // eslint-disable-next-line camelcase __non_webpack_require__ : require;