import { Service } from '../../../../di/src/decorator/Service.ts' import { Logging } from '../logging/Logging.ts' import {uuid} from '../../external/std.ts' /** * Base service with some utility helpers. */ @Service() export default class Utility { constructor( protected logger: Logging ) {} /** * Make a deep copy of an object. * @param target */ deep_copy(target: T): T { if ( target === null ) return target if ( target instanceof Date ) return new Date(target.getTime()) as any if ( target instanceof Array ) { const copy = [] as any[] (target as any[]).forEach(item => { copy.push(item) }) return copy.map((item: any) => this.deep_copy(item)) as any } if ( typeof target === 'object' && target !== {} ) { const copy = { ...(target as {[key: string]: any }) } as { [key: string]: any } Object.keys(copy).forEach(key => { copy[key] = this.deep_copy(copy[key]) }) } return target } // TODO deep_merge /** * Given a string of a value, try to infer the JavaScript type. * @param {string} val */ infer(val: string): any { if ( !val ) return undefined else if ( val.toLowerCase() === 'true' ) return true else if ( val.toLowerCase() === 'false' ) return false else if ( !isNaN(Number(val)) ) return Number(val) else if ( this.is_json(val) ) return JSON.parse(val) else if ( val.toLowerCase() === 'null' ) return null else if ( val.toLowerCase() === 'undefined' ) return undefined else return val } /** * Returns true if the given value is valid JSON. * @param {string} val */ is_json(val: string): boolean { try { JSON.parse(val) return true } catch(e) { this.logger.verbose(`Error encountered while checking is_json. Might be invalid. Error: ${e.message}`) return false } } /** * Get a universally-unique ID string. * @return string */ uuid(): string { return uuid() } }