blow-data
Version:
Data access layer for Blow.
112 lines (92 loc) • 2.93 kB
text/typescript
'use strict';
import * as types from 'blow-types';
import {isUndefined, isObject, isFunction, isNull, isString} from 'util';
import {manager} from './manager';
import {IModelPropertyMetadataOptions, IBaseModelConstructor} from './interfaces';
export class ModelPropertyMetadata {
protected _name: string;
protected _type: types.Type;
protected _default: () => any;
protected _id: boolean;
protected _columnName: string;
protected _hidden: boolean;
protected _index: boolean;
protected _validations: Map<string, any>;
constructor(options: IModelPropertyMetadataOptions) {
this._name = options.name;
this._columnName = isUndefined(options.columnName) ? options.name : options.columnName;
this._index = isUndefined(options.index) ? false : options.index;
this._id = isUndefined(options.id) ? false : options.id;
this._hidden = isUndefined(options.hidden) ? false : options.hidden;
this._validations = new Map();
const type = (isString(options.type) ? {name: options.type} : options.type);
this._type = types.get(type);
this._validations.set(type.name.toLowerCase(), true);
if (!this._type) {
this._type = types.build(manager.getModel(type.name ? type.name : type));
}
if(isObject(options.validations)) {
Object.keys(options.validations).forEach(key => {
this._validations.set(key, options.validations[key]);
});
}
if (!isUndefined(options.default)) {
if (isFunction(options.default)) {
this._default = options.default;
} else {
this._default = () => options.default;
}
} else {
this._default = undefined;
}
}
get name(): string {
return this._name;
}
get columnName(): string {
return this._columnName;
}
get type(): types.Type {
return this._type;
}
get default(): () => any {
return this._default;
}
get id(): boolean {
return this._id;
}
get index(): boolean {
return this._index;
}
get hidden(): boolean {
return this._hidden;
}
get validations(): IterableIterator<[string, any]> {
return this._validations.entries();
}
apply(model: IBaseModelConstructor): void {
const property = this;
const getter = function(): any {
let value = this._data.get(property.name);
if (isUndefined(value) && property.default) {
value = property.default.bind(this)();
this._data.set(property.name, value);
}
return value;
};
const setter = function(value: any): void {
value = property.type.parse(value);
this._data.set(property.name, value);
};
Object.defineProperty(model.prototype, this.name, {
configurable: false,
enumerable: true,
get: getter,
set: setter
});
}
static inspect(value: any): {[key: string]: any} {
const type = types.inspect(value);
return { type };
}
}