UNPKG

@linaframework/arango-orm

Version:

> Please check out https://github.com/awesome-graphql-space/lina and https://github.com/oknoah/final/packages/arangolize for similar projects that MAY be more up to date

154 lines (132 loc) 3.9 kB
import Field from './field' export default class FieldType extends Field { constructor (basePath, path, type, options, internal = false) { super(basePath, path, options, internal) this.checkType(type) this.type = type } checkType (type) { if (type === Boolean) return if (type === String) return if (type === Number) return if (type === Date) return if (type === Set) return if (!type.prototype.toJSON) { throw Error(`Custom type '${type.name}' must have method 'toJSON'`) } if (!type.fromJSON) { throw Error(`Custom type '${type.name}' must have static method 'fromJSON'`) } } validate (data, basePath) { if (this.internal) return let value = this.getByPath(data) if (this.isOptional(value)) return if (!this.validateValue(value, basePath)) { this.typeError(this.type, value, basePath) } } validateValue (value, basePath) { let type = this.type let options = this.options if ('enum' in options) { this.validateEnum(value, options, basePath) } switch (type) { case String: return this.validateString(value, options, basePath) case Number: return this.validateNumber(value, options, basePath) case Boolean: return typeof value === 'boolean' case Set: return this.validateSet(value, options, basePath) default: return value instanceof type } } validateNumber (value, options, basePath) { if (typeof value !== 'number') return false if (!Number.isFinite(value)) { this.throwError(`must be finite number, but have ${value}`, basePath) } if ('min' in options) if (value < options.min) { this.throwError(`must be more or equal ${options.min}, but have ${value}`, basePath) } if ('max' in options) if (value > options.max) { this.throwError(`must be less or equal ${options.max}, but have ${value}`, basePath) } return true } validateString (value, options, basePath) { if (typeof value !== 'string') return false if ('regExp' in options) if (!options.regExp.test(value)) { this.throwError(`must be match regExp ${options.regExp}, but have '${value}'`, basePath) } if ('min' in options) if (value.length < options.min) { this.throwError(`length must be more or equal ${options.min} symbols, but have '${value}'`, basePath) } if ('max' in options) if (value.length > options.max) { this.throwError(`length must be less or equal ${options.max} symbols, but have '${value}'`, basePath) } return true } validateEnum (value, options, basePath) { let enums = options.enum if (enums.indexOf(value) === -1) { let enumText = JSON.stringify(enums) let valueText = this.valueToString(value) let message = `must be one of enum ${enumText}, but have ${valueText}` this.throwError(message, basePath) } } validateSet (value, options, basePath) { if (!(value instanceof Set)) return false if ('set' in options) { let sets = options.set value.forEach(item => { if (sets.indexOf(item) === -1) { let setText = JSON.stringify(sets) let itemValue = this.valueToString(item) let message = `must contain item only from ${setText}, but have ${itemValue}` this.throwError(message, basePath) } }) } return true } convertToModelValue (value) { if (value == null) return value let type = this.type switch (type) { case String: return String(value) case Number: return Number(value) case Boolean: return Boolean(value) case Date: return new Date(value) case Set: return new Set(value) } return type.fromJSON(value) } convertToDocumentValue (value) { if (value == null) return value switch (this.type) { case String: return value case Number: return value case Boolean: return value case Date: return value.getTime() case Set: return Array.from(value) } // for custom types return value.toJSON() } }