import { ref, isRef } from 'vue' export function hasValue(target: any) { if(!target) return false; return target['trim'] ? target.trim() !== '' : true } export function hasArray(target: any) { return Array.isArray(target) && target.length > 0 } export function hasLength(target: any) { // @ts-ignore let t = isRef(target) ? target.value : t return t && t.hasOwnProperty(length) && t.length > 0 } export function isObject(obj: any) { var type = typeof obj; return type === 'function' || type === 'object' && !!obj; } export function isString(value: any) { return typeof value === 'string' } // @ts-ignore export function pick(...values) { let result = values.find(val => val) return result ? result : '' } /** * It is common for a prop to accept either a single value or an array of values. * ensureArray() inspects the target to ensure it is an array or wraps the * single value in an array. * * @param target */ export function ensureArray(target:any) { if(target === undefined || target === null || !hasValue(target)) return [] return Array.isArray(target) ? target : [target] } /** * Take a root object and a path string and resolve it to a value. * Example: * * let root = {foo: { bar: 'baz'}} * let value = valueForPath(root, 'foo.bar') * // value = 'baz' * * Invalid paths will return undefined */ export function valueForPath(object:any, path:any) { if(!object) return undefined let pathSegments = pick(path).split('.') return pathSegments.reduce( // Apply path segments, checking for valid keys (currentRoot:any, pathSegment:any) => { return isObject(currentRoot) ? currentRoot[pathSegment] : undefined }, // Start with the object param. object ) } /** * https://developer.mozilla.org/en-US/docs/Glossary/UUID * * I don't understand how to make this work on the server-side * * @returns {string} a generated v4 UUID */ // export function uuid() { // return crypto.randomUUID() // } /** * @returns {string} a 4-digit sub-string out of a generated UUID */ export function shortUuid() { return `${Math.floor(Math.random() * 1000000)}` //return uuid().substring(9, 13) } /** * Transform a string into a form usable as a DOM id. * Label will be lower-cased, spaces will be replaced with '-', and * a short uuid will be appended. * * @param label A descriptive string of the element it will identify * @returns {string} - A value suitable for a DOM id. */ export function labelToId(label:any) { return pick(label) .toLowerCase() .replace(' ', '-') .concat('-', shortUuid()) } /** * pickRef allows developers to set a precedence order * for a series of ref objects and returns the first * ref that has a non-falsy value. Note: false is treated * as a value but the empty string is not. * * See the useInjections composables for examples. * * @param values - Set of ref objects * @returns - The first ref object whose value is not falsy */ // @ts-ignore export function pickRef(...values) { // @ts-ignore const valuesToRefs = val => isRef(val) ? val : ref(val) // @ts-ignore const firstWithValue = val => val && (val.value || val.value === false) let result = values.map(valuesToRefs).find(firstWithValue) return result ? result : ref(undefined) } /** * Use pickRef to pick the first ref with a value and then return * that ref's value. Calls to pickRef will often take place inside * a computed method, so we want to unwrap the selected ref as the * computed will serve as the reactive wrapper. * * @param Array of refs and potential values to select from * @returns The value of the ref selected from values */ // @ts-ignore export function pickRefValue(...values) { return pickRef(...values).value } export function emptyToUndef(val:any) { return (hasValue(val)) ? val : undefined } export function emptyToNull(val:any) { return (hasValue(val)) ? val : null } export function hasBoolean(val:any) { return val === true || val === false } // @ts-ignore export function fallback(...fallbackList) { return fallbackList.find(e => (e && e.trim() !== '')) }