UNPKG

type-arango

Version:

ArangoDB Foxx decorators and utilities for TypeScript

118 lines (93 loc) 3.01 kB
import {Joi} from '../joi' import {Schema} from 'joi' import {findDocumentForContainer, getDocumentForContainer} from '../models' import {isObject} from '.' type Presence = 'required' | 'optional' /** * Convert type or alias to joi */ export function toJoi(inp: any, presence: Presence = 'optional'){ if(inp){ if(inp.isJoi) return inp if(inp.schema) return inp.schema } let j: Schema = Joi.any() switch(inp){ case String: case 'string': j = Joi.string(); break case Number: case 'number': j = Joi.number(); break case Array: case 'array': j = Joi.array(); break case Boolean: case 'boolean': j = Joi.boolean(); break case 'binary': j = Joi.binary(); break case Date: case 'date': j = Joi.date(); break case Function: case 'func': case 'function': j = Joi.func(); break case Object: case 'object': j = Joi.object(); break case null: case 'any': j = Joi.any(); break case 'alternatives': j = Joi.alternatives(); break default: if(!inp) break if(Array.isArray(inp)){ j = Joi.any().valid(...inp) } else if(isObject(inp)){ if(inp.prototype){ const doc = getDocumentForContainer(inp) if(doc) j = Joi.object().keys(doc.schema); break } else { Object.keys(inp).forEach(k => inp[k] = toJoi(inp[k])) j = Joi.object().keys(inp) } } // @Nested else if(typeof inp === 'function' && findDocumentForContainer(inp)){ j = findDocumentForContainer(inp)!.joi } break } if(!j){ j = Joi.any() } if(presence === 'required'){ j = j.required() } return j } /** * Enhance joi a little */ export function enjoi(inp?: string | any, presence: Presence = 'optional') { if(inp === undefined) return Joi // return document schema for entity references if(typeof inp === 'function'){ const doc = findDocumentForContainer(inp) return doc ? doc.schema : toJoi(inp, presence) } return toJoi(inp, presence) } export function joiDefaults(obj: any, override: any = {}){ return Array.isArray(obj._inner.children) ? obj._inner.children.reduce((res: any, child: any) => { const key = child.key if(child.schema._type == 'object'){ res[key] = joiDefaults(child.schema, override[key]) } else { // convert strings to integer / floats when the attribute type is a number (this should be done by joi's .validate, inside ArangoDB Foxx) if(override[key] && child.schema._type === 'number'){ override[key] = child.schema._tests.find((t:any) => t.name === 'integer') ? parseInt(override[key], 10) : parseFloat(override[key]) } if(override[key] || child.schema._flags.default) res[key] = override[key] || child.schema._flags.default } return res }, {}) : undefined }