UNPKG

type-r2

Version:

Serializable, validated, and observable data layer for modern JS applications

154 lines 5.78 kB
import { definitionDecorator, EventMap, tools } from '../object-plus'; import { Transactional } from '../transactions'; import { getMetatype, SharedType } from './metatypes'; var assign = tools.assign; var ChainableAttributeSpec = (function () { function ChainableAttributeSpec(options) { this.options = { getHooks: [], transforms: [], changeHandlers: [] }; if (options) assign(this.options, options); } ChainableAttributeSpec.prototype.check = function (check, error) { function validate(model, value, name) { if (!check.call(model, value, name)) { var msg = error || check.error || name + ' is not valid'; return typeof msg === 'function' ? msg.call(model, name) : msg; } } var prev = this.options.validate; return this.metadata({ validate: prev ? (function (model, value, name) { return prev(model, value, name) || validate(model, value, name); }) : validate }); }; Object.defineProperty(ChainableAttributeSpec.prototype, "as", { get: function () { return definitionDecorator('attributes', this); }, enumerable: false, configurable: true }); Object.defineProperty(ChainableAttributeSpec.prototype, "isRequired", { get: function () { return this.required; }, enumerable: false, configurable: true }); Object.defineProperty(ChainableAttributeSpec.prototype, "required", { get: function () { return this.metadata({ isRequired: true }); }, enumerable: false, configurable: true }); ChainableAttributeSpec.prototype.endpoint = function (endpoint) { return this.metadata({ endpoint: endpoint }); }; ChainableAttributeSpec.prototype.watcher = function (ref) { return this.metadata({ _onChange: ref }); }; ChainableAttributeSpec.prototype.parse = function (fun) { return this.metadata({ parse: fun }); }; ChainableAttributeSpec.prototype.toJSON = function (fun) { return this.metadata({ toJSON: typeof fun === 'function' ? fun : (fun ? function (x, k, o) { return x && x.toJSON(o); } : emptyFunction) }); }; ChainableAttributeSpec.prototype.get = function (fun) { return this.metadata({ getHooks: this.options.getHooks.concat(fun) }); }; ChainableAttributeSpec.prototype.set = function (fun) { function handleSetHook(next, prev, record, options) { if (this.isChanged(next, prev)) { var changed = fun.call(record, next, this.name); return changed === void 0 ? prev : this.convert(changed, prev, record, options); } return prev; } return this.metadata({ transforms: this.options.transforms.concat(handleSetHook) }); }; ChainableAttributeSpec.prototype.changeEvents = function (events) { return this.metadata({ changeEvents: events }); }; ChainableAttributeSpec.prototype.events = function (map) { var eventMap = new EventMap(map); function handleEventsSubscribtion(next, prev, record) { prev && prev.trigger && eventMap.unsubscribe(record, prev); next && next.trigger && eventMap.subscribe(record, next); } return this.metadata({ changeHandlers: this.options.changeHandlers.concat(handleEventsSubscribtion) }); }; Object.defineProperty(ChainableAttributeSpec.prototype, "has", { get: function () { return this; }, enumerable: false, configurable: true }); ChainableAttributeSpec.prototype.metadata = function (options) { var cloned = new ChainableAttributeSpec(this.options); assign(cloned.options, options); return cloned; }; ChainableAttributeSpec.prototype.value = function (valOrFunction) { if (typeof valOrFunction === 'function') { return this.metadata({ value: valOrFunction(), hasCustomDefault: true, valueFn: valOrFunction }); } else { return this.metadata({ value: valOrFunction, hasCustomDefault: true }); } }; ChainableAttributeSpec.from = function (spec) { if (spec && spec instanceof ChainableAttributeSpec) { return spec; } return typeof spec === 'function' ? type(spec) : value(spec); }; return ChainableAttributeSpec; }()); export { ChainableAttributeSpec }; function emptyFunction() { } export function type(Type, value) { if (Type instanceof ChainableAttributeSpec) return Type; var attrDef = new ChainableAttributeSpec({ type: Type }), defaultValue = Type && value === void 0 ? getMetatype(Type).defaultValue : value; return defaultValue === void 0 ? attrDef : attrDef.value(defaultValue); } export function shared(Constructor) { return new ChainableAttributeSpec({ value: null, type: Constructor, _metatype: SharedType }); } export function value(x) { var Type = inferType(x), AttrDef = Type && Type.prototype instanceof Transactional ? shared(Type) : type(Type); return AttrDef.value(x); } function inferType(value) { switch (typeof value) { case 'number': return Number; case 'string': return String; case 'boolean': return Boolean; case 'function': return Function; case 'undefined': return void 0; case 'object': return value ? value.constructor : void 0; } } //# sourceMappingURL=attrDef.js.map