UNPKG

@allgemein/schema-api

Version:
200 lines 7.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MetadataRegistry = void 0; const lodash_1 = require("lodash"); /** * Handler for metadata */ const Constants_1 = require("./../Constants"); const base_1 = require("@allgemein/base"); const events_1 = require("events"); const ClassRef_1 = require("../ClassRef"); /** * Registry for metadata of classes and there properties */ class MetadataRegistry extends events_1.EventEmitter { constructor() { super(); this.metadata = []; this.cached = []; this.schemas = []; this.targets = []; this.setMaxListeners(1000); this.targets = []; this.schemas = []; this.metadata = base_1.MetadataStorage.key(Constants_1.METADATA_REGISTRY); } static $() { if (!this.$self) { this.$self = new MetadataRegistry(); } return this.$self; } static reset() { this.$self = null; } /** * Add typed element to the local registry * * @param context * @param options */ add(context, options, trigger = true) { options.metaType = context; // find? const id = MetadataRegistry.INC++; this.metadata.push(options); if (this.targets.indexOf(options.target) === -1) { this.targets.push(options.target); } if (context === Constants_1.METATYPE_SCHEMA) { if (this.schemas.indexOf(options.name) === -1) { this.schemas.push(options.name); } } if (trigger) { Object.defineProperty(options, Constants_1.K_TRIGGERED, { value: true }); this.notify(Constants_1.C_EVENT_ADD, context, options); } return options; } /** * Add cached content mostly for ClassRef instances throw AbstractRef * * @param context * @param options */ addCached(context, options) { options.metaType = context; this.cached.push(options); return options; } notify(eventName, context, options) { this.emit(eventName, context, options); } remove(context, c, trigger = true) { const removed = (0, lodash_1.remove)(this.metadata, x => x.metaType === context && c(x)); if (!(0, lodash_1.isEmpty)(removed) && trigger) { this.notify(Constants_1.C_EVENT_REMOVE, context, removed); } } // private update(context: METADATA_TYPE) { // this.emit(C_EVENT_UPDATE, {}); // } getByContext(context) { return this.metadata.filter(x => x.metaType === context); } getTargets() { return this.targets; } /** * Return the metadata/options for some entry (entity/property/classref/...). A copy of the original will be delivered. * * @param context * @param target * @param attributes * @param propertyName */ getByContextAndTarget(context, target, attributes = null, propertyName) { const data = (0, lodash_1.cloneDeep)(this.metadata.filter(x => x.metaType === context && ((0, lodash_1.isFunction)(target) ? x.target === target : ClassRef_1.ClassRef.getClassName(x.target) === target) && (propertyName ? x.propertyName === propertyName : true))); if (attributes && !(0, lodash_1.isEmpty)(data)) { this.mergeAttributes(context, target, data, attributes); } return data; } mergeAttributes(context, target, data, mode = null) { let attributes = []; if (context === Constants_1.METATYPE_PROPERTY) { // merge with properties attributes = this.getAttributesForTargetProperties(context, target); } else { attributes = this.getAttributesForTarget(context, target); } for (const attribute of attributes) { let toExtend = null; if (attribute.propertyName) { toExtend = data.find((x) => x.metaType === Constants_1.METATYPE_PROPERTY && x.propertyName === attribute.propertyName); } else { toExtend = data.find((x) => x.metaType === context); } if (toExtend) { switch (mode) { case 'assign': (0, lodash_1.assign)(toExtend, attribute.attributes); break; case 'merge': (0, lodash_1.merge)(toExtend, attribute.attributes); break; case 'defaults': (0, lodash_1.defaults)(toExtend, attribute.attributes); break; } } } } getAttributesForTarget(context, target) { return (0, lodash_1.cloneDeep)(this.metadata.filter((x) => x.targetTypes && !x.propertyName && x.attributes && x.targetTypes.includes(context) && x.target === target)); } getAttributesForTargetProperty(context, target, propertyName) { return (0, lodash_1.cloneDeep)(this.metadata.filter((x) => x.targetTypes && x.propertyName === propertyName && x.attributes && x.targetTypes.includes(context) && x.target === target)); } getAttributesForTargetProperties(context, target) { return (0, lodash_1.cloneDeep)(this.metadata.filter((x) => x.targetTypes && x.propertyName && x.attributes && x.targetTypes.includes(context) && x.target === target)); } getByTarget(target) { return (0, lodash_1.cloneDeep)(this.metadata.filter(x => x.target === target)); } createSearchFunction(find) { let lookup = find; if (!(0, lodash_1.isFunction)(find)) { const _keys = (0, lodash_1.keys)(find); lookup = (x) => { return _keys.map(k => find[k] === x[k]).reduce((previousValue, currentValue) => previousValue && currentValue); }; } return lookup; } find(context, find) { const lookup = this.createSearchFunction(find); return this.metadata.find((x => x.metaType === context && lookup(x))); } findCached(context, find) { const lookup = this.createSearchFunction(find); return this.cached.find((x => x.metaType === context && lookup(x))); } filter(context, find) { const lookup = this.createSearchFunction(find); return this.metadata.filter((x => x.context === context && lookup(x))); } getMetadata() { return this.metadata; } getCached() { return this.cached; } getSchemas() { return (0, lodash_1.uniq)(this.metadata.filter((x => x.context === Constants_1.METATYPE_SCHEMA)).map(x => x.name)); } getMetadatasForSchema(schema) { return this.metadata.filter((x => x.context === Constants_1.METATYPE_SCHEMA && x.name === schema)); } } exports.MetadataRegistry = MetadataRegistry; MetadataRegistry.INC = 0; //# sourceMappingURL=MetadataRegistry.js.map