UNPKG

final-orm

Version:

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

164 lines (139 loc) 4.2 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _field = require('./field'); var _field2 = _interopRequireDefault(_field); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class FieldType extends _field2.default { 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(); } } exports.default = FieldType;