blow-data
Version:
Data access layer for Blow.
128 lines (127 loc) • 4.27 kB
JavaScript
'use strict';
const Joi = require('joi');
const inflection_1 = require('inflection');
const util_1 = require('util');
const ModelPropertyMetadata_1 = require('./ModelPropertyMetadata');
const ModelRelationMetadata_1 = require('./ModelRelationMetadata');
const DEFAULT_CONNECTION_NAME = 'default';
const ASYNC_VALIDATORS = ['custom'];
class ModelMetadata {
constructor(options, properties, relations) {
this._raw = {
options: options,
properties: properties,
relations: relations
};
this._name = options.name;
this._pluralName = util_1.isUndefined(options.pluralName) ? inflection_1.pluralize(options.name) : options.pluralName;
this._autoId = util_1.isUndefined(options.autoId) ? true : options.autoId;
this._properties = new Map();
this._relations = new Map();
this._connectionName = util_1.isUndefined(options.connection) ? DEFAULT_CONNECTION_NAME : options.connection;
}
get name() {
return this._name;
}
get pluralName() {
return this._pluralName;
}
get autoId() {
return this._autoId;
}
get properties() {
return this._properties.values();
}
get relations() {
return this._relations.values();
}
get connectionName() {
return this._connectionName;
}
get idProperty() {
for (const property of this.properties) {
if (property.id) {
return property;
}
}
}
get validationSchema() {
const schema = {};
for (const property of this.properties) {
schema[property.name] = Joi;
for (const validation of property.validations) {
if (ASYNC_VALIDATORS.indexOf(validation[0]) === -1 && schema[property.name][validation[0]]) {
schema[property.name] = schema[property.name][validation[0]](validation[1]);
}
}
}
return schema;
}
get asyncValidationSchema() {
const schema = {};
for (const property of this.properties) {
schema[property.name] = [];
for (const validation of property.validations) {
if (ASYNC_VALIDATORS.indexOf(validation[0]) !== -1) {
schema[property.name].push(validation[1]);
}
}
}
return schema;
}
defineProperty(options) {
if (options.id) {
this._autoId = false;
}
const property = new ModelPropertyMetadata_1.ModelPropertyMetadata(options);
this._properties.set(options.name, property);
if (this._model) {
property.apply(this._model);
}
}
buildPropertyId(name, type) {
if (this.autoId && !this.idProperty) {
this.defineProperty({
name: name,
type: type,
id: true
});
}
}
getProperty(name) {
return this._properties.get(name);
}
hasProperty(name) {
return this._properties.has(name);
}
isAllowedProperty(name) {
return this.hasProperty(name);
}
defineRelation(options) {
const relation = new ModelRelationMetadata_1.ModelRelationMetadata(options);
this._relations.set(relation.name, relation);
if (this._model) {
relation.apply(this._model);
}
}
apply(model) {
if (!util_1.isUndefined(this._raw.properties)) {
Object.keys(this._raw.properties).forEach(propertyName => {
this.defineProperty(Object.assign({ name: propertyName }, this._raw.properties[propertyName]));
});
}
if (!util_1.isUndefined(this._raw.relations)) {
Object.keys(this._raw.relations).forEach(relationName => {
this.defineRelation(Object.assign({ name: relationName }, this._raw.relations[relationName]));
});
}
this._model = model;
for (const property of this.properties) {
property.apply(model);
}
for (const relation of this.relations) {
relation.apply(model);
}
}
}
exports.ModelMetadata = ModelMetadata;