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
125 lines (100 loc) • 3.27 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _validationError = require('../errors/validation-error');
var _validationError2 = _interopRequireDefault(_validationError);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/** @abstract class */
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 _validationError2.default(`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;
}
}
exports.default = Field;