|
@@ -0,0 +1,502 @@
|
|
|
|
|
+const {
|
|
|
|
|
+ isEmpty: _isEmpty,
|
|
|
|
|
+ isEqual: _isEqual,
|
|
|
|
|
+ isNaN: _isNaN,
|
|
|
|
|
+ isNumber: _isNumber,
|
|
|
|
|
+ merge,
|
|
|
|
|
+ omit,
|
|
|
|
|
+ omitBy,
|
|
|
|
|
+ parseInt: _parseInt,
|
|
|
|
|
+ pick
|
|
|
|
|
+} = require("lodash");
|
|
|
|
|
+
|
|
|
|
|
+const parse = (value) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ return JSON.parse(value);
|
|
|
|
|
+ } catch (_) {
|
|
|
|
|
+ return value;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const stringify = (value, opts) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ return opts ? JSON.stringify(value, null, opts) : JSON.stringify(value);
|
|
|
|
|
+ } catch (_) {
|
|
|
|
|
+ return value;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const btoa = (value, options = {}) => {
|
|
|
|
|
+ const { urlsafe = true } = options;
|
|
|
|
|
+ let result = Buffer.from(value, "binary").toString("base64");
|
|
|
|
|
+ if (urlsafe)
|
|
|
|
|
+ result = result.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
|
|
|
+ return result;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const atob = (value, options = {}) => {
|
|
|
|
|
+ const { urlsafe = true } = options;
|
|
|
|
|
+ if (urlsafe) value = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
|
|
|
+ if (urlsafe && value && value.toString().length % 4 !== 0)
|
|
|
|
|
+ value += "===".slice(0, 4 - (value.toString().length % 4));
|
|
|
|
|
+ let result = Buffer.from(value, "base64").toString("binary");
|
|
|
|
|
+ return result.toString();
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const querystring = (params = {}, options = {}) => {
|
|
|
|
|
+ if (!isObject(params)) return;
|
|
|
|
|
+ const { exclude = [], compress = false } = options;
|
|
|
|
|
+ const encodeAndCompress = (param) => {
|
|
|
|
|
+ const json = stringify(param);
|
|
|
|
|
+ return compress ? pako.deflate(json, { to: "string" }) : json;
|
|
|
|
|
+ // return compress ? encodeURI(pako.deflate(json, { to: "string" })) : encodeURI(json);
|
|
|
|
|
+ };
|
|
|
|
|
+ const props = {};
|
|
|
|
|
+ for (let key of Object.keys(params)) {
|
|
|
|
|
+ props[key] = isObject(params[key])
|
|
|
|
|
+ ? encodeAndCompress(params[key])
|
|
|
|
|
+ : params[key];
|
|
|
|
|
+ }
|
|
|
|
|
+ return new URLSearchParams(omit(props, exclude)).toString();
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const safeEncodeURIComponent = (v) => {
|
|
|
|
|
+ v = parse(v); // try to parse the value
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (v && (Array.isArray(v) || isObject(v))) v = stringify(v); // is it an array? or object? stringify
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ // do nothing use valu v
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ return encodeURIComponent(v); // encodeURIComponent the value and resurn it
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ return v; // fail and return v
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const language = () => {
|
|
|
|
|
+ return (
|
|
|
|
|
+ (navigator.languages && navigator.languages[0]) ||
|
|
|
|
|
+ navigator.language ||
|
|
|
|
|
+ navigator.userLanguage
|
|
|
|
|
+ );
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const uuid = () => Math.random().toString(36).substr(2, 9);
|
|
|
|
|
+const uniqueId = (x = 4, j = "-") =>
|
|
|
|
|
+ [...Array(x).keys()].map(() => uuid()).join(j);
|
|
|
|
|
+
|
|
|
|
|
+const normalizeUrl = (url) => {
|
|
|
|
|
+ let pattern = /^((http|https|ftp):\/\/)/;
|
|
|
|
|
+ if (url && url !== "") {
|
|
|
|
|
+ url = url.toString();
|
|
|
|
|
+ if (!pattern.test(url) && !url.startsWith("/")) url = "http://" + url;
|
|
|
|
|
+ }
|
|
|
|
|
+ return url;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const normalizeJSON = (value, fallback = null) => {
|
|
|
|
|
+ if (isString(value)) return parse(value) || fallback;
|
|
|
|
|
+ else if (isObject(value)) return value || fallback;
|
|
|
|
|
+ else return fallback;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const safeSearchName = (text = "") =>
|
|
|
|
|
+ encodeURIComponent(text || "")
|
|
|
|
|
+ .toString()
|
|
|
|
|
+ .trim()
|
|
|
|
|
+ .replace(/%20/g, "+");
|
|
|
|
|
+
|
|
|
|
|
+const kebabCase = (text = "") =>
|
|
|
|
|
+ (text || "")
|
|
|
|
|
+ .toString() // convert to string to avoid issues
|
|
|
|
|
+ .replace(/\s+/, "-") // spaces to dash
|
|
|
|
|
+ .replace(/([a-z])([A-Z])/g, "$1-$2") // kebab the string
|
|
|
|
|
+ .replace(/[\s_]+/g, "-")
|
|
|
|
|
+ .replace(/-+/g, "-") // only one dash per kebab
|
|
|
|
|
+ .replace(/^-/g, "") // no starting dash
|
|
|
|
|
+ .replace(/-$/g, "") // no ending dash
|
|
|
|
|
+ .replace(/[^0-9a-z-_]/gi, "") // only alpha numeric
|
|
|
|
|
+ .toLowerCase(); // lowercase only
|
|
|
|
|
+
|
|
|
|
|
+const safeIdName = (text = "") =>
|
|
|
|
|
+ kebabCase((text || "").toString().replace(/\s\s+/g, " "));
|
|
|
|
|
+
|
|
|
|
|
+const slugify = (text = "") => kebabCase(text || "");
|
|
|
|
|
+
|
|
|
|
|
+const baseUrl = (path) => {
|
|
|
|
|
+ if (!hasWindow()) return `${BASE_URL}${path}`;
|
|
|
|
|
+ const { location: { origin } = {} } = window;
|
|
|
|
|
+ return `${origin || BASE_URL}${path || ""}`;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const toBoolean = (value) => {
|
|
|
|
|
+ switch (value) {
|
|
|
|
|
+ case true:
|
|
|
|
|
+ case "true":
|
|
|
|
|
+ case "True":
|
|
|
|
|
+ case "TRUE":
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ case "1":
|
|
|
|
|
+ case "on":
|
|
|
|
|
+ case "On":
|
|
|
|
|
+ case "ON":
|
|
|
|
|
+ case "yes":
|
|
|
|
|
+ case "Yes":
|
|
|
|
|
+ case "YES":
|
|
|
|
|
+ return true;
|
|
|
|
|
+ default:
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isBlank = (value) =>
|
|
|
|
|
+ (_isEmpty(value) && !_isNumber(value)) || _isNaN(value);
|
|
|
|
|
+
|
|
|
|
|
+const isEqual = (v1, v2) => _isEqual(v1, v2);
|
|
|
|
|
+
|
|
|
|
|
+const isEmpty = (value) => {
|
|
|
|
|
+ let result,
|
|
|
|
|
+ type = typeof value;
|
|
|
|
|
+ switch (type.toLowerCase()) {
|
|
|
|
|
+ case "null":
|
|
|
|
|
+ case "undefined":
|
|
|
|
|
+ result = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case "boolean":
|
|
|
|
|
+ case "number":
|
|
|
|
|
+ case "bigint":
|
|
|
|
|
+ result = value === undefined || value === null ? true : false;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case "symbol":
|
|
|
|
|
+ case "object":
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (typeofDate(value)) {
|
|
|
|
|
+ result = false;
|
|
|
|
|
+ } else if (isArray(value)) {
|
|
|
|
|
+ result = !value || value.length === 0 ? true : false;
|
|
|
|
|
+ } else if (value) {
|
|
|
|
|
+ let entries = Object.entries(value);
|
|
|
|
|
+ result = !entries || entries.length === 0 ? true : false;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ result = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ log.error("isEmpty", type, err.message || err);
|
|
|
|
|
+ result = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case "date":
|
|
|
|
|
+ result = false;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case "string":
|
|
|
|
|
+ default:
|
|
|
|
|
+ result =
|
|
|
|
|
+ !value || value.trim() === "" || value === undefined || value === null
|
|
|
|
|
+ ? true
|
|
|
|
|
+ : false;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isFunction = (o) => {
|
|
|
|
|
+ return o && typeof o === "function" ? true : false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isJson = (o) => {
|
|
|
|
|
+ return isArray(o) || isObject(o) ? true : hasJsonStructure(o);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isReactElement = (o) => {
|
|
|
|
|
+ return o?.["$$typeof"] && o["$$typeof"] === Symbol.for("react.element");
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const hasJsonStructure = (o) => {
|
|
|
|
|
+ if (typeof o !== "string") return false;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = JSON.parse(o);
|
|
|
|
|
+ const type = Object.prototype.toString.call(result);
|
|
|
|
|
+ return type === "[object Object]" || type === "[object Array]";
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isString = (o) => {
|
|
|
|
|
+ return o && typeof o === "string" ? true : false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isArray = (o) => {
|
|
|
|
|
+ return o && Array.isArray(o) ? true : false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isObject = (o) => {
|
|
|
|
|
+ return o && typeof o === "object" ? true : false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isUndefined = (o) => {
|
|
|
|
|
+ return typeof o === "undefined" ? true : false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const hasWindow = () => {
|
|
|
|
|
+ return typeof window !== "undefined" && window ? true : false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const hasNavigator = () => {
|
|
|
|
|
+ return typeof navigator !== "undefined" && navigator ? true : false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const hasDocument = () => {
|
|
|
|
|
+ return typeof document !== "undefined" && document ? true : false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const typeofDate = (value) => {
|
|
|
|
|
+ return (
|
|
|
|
|
+ value &&
|
|
|
|
|
+ Object.prototype.toString.call(value) === "[object Date]" &&
|
|
|
|
|
+ !isNaN(value)
|
|
|
|
|
+ );
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isDate = (value) => {
|
|
|
|
|
+ const regex = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
|
|
|
|
|
+ return value && regex.test(value) ? true : false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isHex = (h) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ return /^#[0-9A-F]{6}$/i.test(h);
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isNullOrFalse = (value) => {
|
|
|
|
|
+ return value === null || value === undefined || value === false
|
|
|
|
|
+ ? true
|
|
|
|
|
+ : false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isNullOrZero = (value) => {
|
|
|
|
|
+ return value === null || value === undefined || value == 0 ? true : false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const formatCurrency = (
|
|
|
|
|
+ value,
|
|
|
|
|
+ formatter = new Intl.NumberFormat("en-US", {
|
|
|
|
|
+ style: "currency",
|
|
|
|
|
+ currency: "USD"
|
|
|
|
|
+ })
|
|
|
|
|
+) => {
|
|
|
|
|
+ return (formatter && value && formatter.format(value)) || 0;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isInt = (value) => {
|
|
|
|
|
+ if (value === null || value === undefined || value === "") return false;
|
|
|
|
|
+ return /^-?[0-9]+$/.test(value);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isNumber = (value) => {
|
|
|
|
|
+ return value % 1 === 0 ? true : false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isUrl = (value) => {
|
|
|
|
|
+ let url;
|
|
|
|
|
+ try {
|
|
|
|
|
+ url = new URL(value);
|
|
|
|
|
+ } catch (_) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return (
|
|
|
|
|
+ url &&
|
|
|
|
|
+ url.protocol &&
|
|
|
|
|
+ ["http:", "https:", "ftp:", "ftps:"].includes(url.protocol)
|
|
|
|
|
+ );
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const clone = (obj = {}) => {
|
|
|
|
|
+ let result = {};
|
|
|
|
|
+ try {
|
|
|
|
|
+ result = JSON.parse(JSON.stringify(obj));
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ log.error("clone error", err.message || err);
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isValidUrl = (str) => {
|
|
|
|
|
+ let url;
|
|
|
|
|
+ try {
|
|
|
|
|
+ url = new URL(str);
|
|
|
|
|
+ } catch (_) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return url.protocol === "http:" || url.protocol === "https:";
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const asyncSome = async (arr, predicate) => {
|
|
|
|
|
+ for (let a of arr) {
|
|
|
|
|
+ if (await predicate(a)) return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const asyncEvery = async (arr, predicate) => {
|
|
|
|
|
+ for (let a of arr) {
|
|
|
|
|
+ if (!(await predicate(a))) return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const objectToString = (value, delim = ",") => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (!value) return null;
|
|
|
|
|
+ if (isString(value)) return value;
|
|
|
|
|
+ else if (isArray(value)) return value.join(delim);
|
|
|
|
|
+ else return stringify(value, null, 2);
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const stringToArray = (value, delim = ",", clean = true) => {
|
|
|
|
|
+ if (!value) return [];
|
|
|
|
|
+ if (value && Array.isArray(value)) return value;
|
|
|
|
|
+ let result = [];
|
|
|
|
|
+ try {
|
|
|
|
|
+ result = (value && value.toString().split(delim)) || [];
|
|
|
|
|
+ if (clean)
|
|
|
|
|
+ result =
|
|
|
|
|
+ (result &&
|
|
|
|
|
+ result.map((v) => v.trim()).filter((v) => v && !isEmpty(v))) ||
|
|
|
|
|
+ [];
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ result = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const stringToObject = (value, delim = ",", clean = true) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // if (!value) return {};
|
|
|
|
|
+ if (isObject(value)) return value;
|
|
|
|
|
+ else if (value.includes("[") && value.includes("]")) return parse(value);
|
|
|
|
|
+ else if (value.includes("{") && value.includes("}")) return parse(value);
|
|
|
|
|
+ else {
|
|
|
|
|
+ if (clean) value = stripNewlines(value, delim) || "";
|
|
|
|
|
+ return (
|
|
|
|
|
+ value &&
|
|
|
|
|
+ value
|
|
|
|
|
+ .toString()
|
|
|
|
|
+ .split(delim)
|
|
|
|
|
+ .map((v) => v.trim())
|
|
|
|
|
+ .filter((v) => !isEmpty(v))
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ return {};
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const stripNewlines = (value, subs = "") => {
|
|
|
|
|
+ if (!value) return;
|
|
|
|
|
+ let result;
|
|
|
|
|
+ try {
|
|
|
|
|
+ result = value.toString().replace(/(\r\n|\r|\n)/g, subs);
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ // do nothing
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const capitalizeFirstLetter = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
|
|
|
+
|
|
|
|
|
+const reload = () => {
|
|
|
|
|
+ if (hasWindow() && window.location) window.location.reload(false);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const hasOwnProperty = (obj, key) => {
|
|
|
|
|
+ return obj && key && Object.prototype.hasOwnProperty.call(obj, key);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const hasKey = (needle = "", haystack = {}) => {
|
|
|
|
|
+ if (!needle || isEmpty(haystack)) return false;
|
|
|
|
|
+ let keys = Object.keys(haystack) || [];
|
|
|
|
|
+ return needle instanceof RegExp
|
|
|
|
|
+ ? keys.some((o) => o && needle.test(o))
|
|
|
|
|
+ : keys.some((o) => o && ciEquals(needle, o));
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isIterable = (obj) => {
|
|
|
|
|
+ if (obj) return typeof obj[Symbol.iterator] === "function";
|
|
|
|
|
+ return false;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const hasHtml = (value) => value && /<\/?[^>]*>/.test(value);
|
|
|
|
|
+
|
|
|
|
|
+const firstOfList = (value) => (isArray(value) ? value[0] : value);
|
|
|
|
|
+const truncateArray = (list = [], max = 7) => {
|
|
|
|
|
+ if (list.length < max) return list;
|
|
|
|
|
+ return [...list.slice(0, max), "..."];
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+module.exports = {
|
|
|
|
|
+ atob,
|
|
|
|
|
+ baseUrl,
|
|
|
|
|
+ btoa,
|
|
|
|
|
+ capitalizeFirstLetter,
|
|
|
|
|
+ clone,
|
|
|
|
|
+ firstOfList,
|
|
|
|
|
+ formatCurrency,
|
|
|
|
|
+ hasDocument,
|
|
|
|
|
+ hasJsonStructure,
|
|
|
|
|
+ hasHtml,
|
|
|
|
|
+ hasKey,
|
|
|
|
|
+ hasNavigator,
|
|
|
|
|
+ hasOwnProperty,
|
|
|
|
|
+ hasWindow,
|
|
|
|
|
+ isArray,
|
|
|
|
|
+ isBlank,
|
|
|
|
|
+ isDate,
|
|
|
|
|
+ isEqual,
|
|
|
|
|
+ isEmpty,
|
|
|
|
|
+ isFunction,
|
|
|
|
|
+ isHex,
|
|
|
|
|
+ isInt,
|
|
|
|
|
+ isIterable,
|
|
|
|
|
+ isJson,
|
|
|
|
|
+ isNumber,
|
|
|
|
|
+ isNullOrFalse,
|
|
|
|
|
+ isNullOrZero,
|
|
|
|
|
+ isObject,
|
|
|
|
|
+ isReactElement,
|
|
|
|
|
+ isValidUrl,
|
|
|
|
|
+ isUrl,
|
|
|
|
|
+ isUndefined,
|
|
|
|
|
+ isString,
|
|
|
|
|
+ language,
|
|
|
|
|
+ merge,
|
|
|
|
|
+ normalizeUrl,
|
|
|
|
|
+ normalizeJSON,
|
|
|
|
|
+ objectToString,
|
|
|
|
|
+ omit,
|
|
|
|
|
+ omitBy,
|
|
|
|
|
+ parse,
|
|
|
|
|
+ pick,
|
|
|
|
|
+ querystring,
|
|
|
|
|
+ reload,
|
|
|
|
|
+ safeIdName,
|
|
|
|
|
+ safeEncodeURIComponent,
|
|
|
|
|
+ safeSearchName,
|
|
|
|
|
+ slugify,
|
|
|
|
|
+ stringify,
|
|
|
|
|
+ stringToArray,
|
|
|
|
|
+ stringToObject,
|
|
|
|
|
+ stripNewlines,
|
|
|
|
|
+ toBoolean,
|
|
|
|
|
+ truncateArray,
|
|
|
|
|
+ typeofDate,
|
|
|
|
|
+ uuid,
|
|
|
|
|
+ uniqueId
|
|
|
|
|
+};
|