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

115 lines (93 loc) 2.97 kB
import ValidationError from "../errors/validation-error" /** @abstract class */ export default class Field { constructor (basePath = [], path, options = {}, internal = false) { if (!internal) this.checkPath(path, basePath) this.options = this.normalizeOptions(options) this.basePath = basePath this.internal = internal this.path = path } isOptional (value) { return (!value) && this.options.optional } normalizeOptions (options) { const normalOptions = {} for (const key in options) if (options.hasOwnProperty(key)) { const value = options[key] const normalKey = key.match(/^\$?(.*)/)[1] normalOptions[normalKey] = value } if (normalOptions.unique) { normalOptions.index = true } return normalOptions } checkPath (path, basePath) { for (const prop of path) { const match = prop.match(/^([_$])/) if (match) { const stringPath = this.pathsToString([basePath, path]) throw Error(`Field names can not begin with a '${match[1]}' symbol, but have '${stringPath}'`) } } } pathsToString (subPaths) { const props = [].concat(...subPaths) const prettyPath = props.map((prop, index)=> { if (!/^[A-Za-z$_]+$/.test(prop)) return `[${prop}]` if (index === 0) return prop return `.${prop}` }).join('') return prettyPath } valueToString (value) { if (Object(value) === value) return value.constructor.name if (typeof value === 'string') return `'${value}'` return value } typeError (type, value, basePath, subPath) { var valueText = this.valueToString(value) const message = `must be ${type.name}, but have ${valueText}` this.throwError(message, basePath, subPath) } throwError (message, basePath = this.basePath, subPath = []) { const subPaths = [basePath, this.path, subPath] const pathString = this.pathsToString(subPaths) throw new ValidationError(`Field '${pathString}' ${message}`) } documentToModel (model, document) { let value = this.getByPath(document) value = this.convertToModelValue(value) this.setByPath(model, value) } modelToDocument (model, document) { let value = this.getByPath(model) value = this.convertToDocumentValue(value) this.setByPath(document, value) } validate () { throw 'validate is just virtual method' } convertToModelValue () { throw 'convertToModelValue is just virtual method' } convertToDocumentValue () { throw 'convertToDocumentValue is just virtual method' } getByPath (context) { for (const prop of this.path) { context = context ? context[prop] : undefined } return context } setByPath (context, value) { const path = this.path.slice() const lastProp = path.pop() for (const prop of path) { if (!context[prop]) context[prop] = {} context = context[prop] } return context[lastProp] = value } }