"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MetadataStorage = void 0; const enums_1 = require("./enums"); /** * Storage all library metadata. */ class MetadataStorage { constructor() { // ------------------------------------------------------------------------- // Properties // ------------------------------------------------------------------------- this._typeMetadatas = new Map(); this._transformMetadatas = new Map(); this._exposeMetadatas = new Map(); this._excludeMetadatas = new Map(); this._ancestorsMap = new Map(); } // ------------------------------------------------------------------------- // Adder Methods // ------------------------------------------------------------------------- addTypeMetadata(metadata) { if (!this._typeMetadatas.has(metadata.target)) { this._typeMetadatas.set(metadata.target, new Map()); } this._typeMetadatas.get(metadata.target).set(metadata.propertyName, metadata); } addTransformMetadata(metadata) { if (!this._transformMetadatas.has(metadata.target)) { this._transformMetadatas.set(metadata.target, new Map()); } if (!this._transformMetadatas.get(metadata.target).has(metadata.propertyName)) { this._transformMetadatas.get(metadata.target).set(metadata.propertyName, []); } this._transformMetadatas.get(metadata.target).get(metadata.propertyName).push(metadata); } addExposeMetadata(metadata) { if (!this._exposeMetadatas.has(metadata.target)) { this._exposeMetadatas.set(metadata.target, new Map()); } this._exposeMetadatas.get(metadata.target).set(metadata.propertyName, metadata); } addExcludeMetadata(metadata) { if (!this._excludeMetadatas.has(metadata.target)) { this._excludeMetadatas.set(metadata.target, new Map()); } this._excludeMetadatas.get(metadata.target).set(metadata.propertyName, metadata); } // ------------------------------------------------------------------------- // Public Methods // ------------------------------------------------------------------------- findTransformMetadatas(target, propertyName, transformationType) { return this.findMetadatas(this._transformMetadatas, target, propertyName).filter(metadata => { if (!metadata.options) return true; if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true) return true; if (metadata.options.toClassOnly === true) { return (transformationType === enums_1.TransformationType.CLASS_TO_CLASS || transformationType === enums_1.TransformationType.PLAIN_TO_CLASS); } if (metadata.options.toPlainOnly === true) { return transformationType === enums_1.TransformationType.CLASS_TO_PLAIN; } return true; }); } findExcludeMetadata(target, propertyName) { return this.findMetadata(this._excludeMetadatas, target, propertyName); } findExposeMetadata(target, propertyName) { return this.findMetadata(this._exposeMetadatas, target, propertyName); } findExposeMetadataByCustomName(target, name) { return this.getExposedMetadatas(target).find(metadata => { return metadata.options && metadata.options.name === name; }); } findTypeMetadata(target, propertyName) { return this.findMetadata(this._typeMetadatas, target, propertyName); } getStrategy(target) { const excludeMap = this._excludeMetadatas.get(target); const exclude = excludeMap && excludeMap.get(undefined); const exposeMap = this._exposeMetadatas.get(target); const expose = exposeMap && exposeMap.get(undefined); if ((exclude && expose) || (!exclude && !expose)) return 'none'; return exclude ? 'excludeAll' : 'exposeAll'; } getExposedMetadatas(target) { return this.getMetadata(this._exposeMetadatas, target); } getExcludedMetadatas(target) { return this.getMetadata(this._excludeMetadatas, target); } getExposedProperties(target, transformationType) { return this.getExposedMetadatas(target) .filter(metadata => { if (!metadata.options) return true; if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true) return true; if (metadata.options.toClassOnly === true) { return (transformationType === enums_1.TransformationType.CLASS_TO_CLASS || transformationType === enums_1.TransformationType.PLAIN_TO_CLASS); } if (metadata.options.toPlainOnly === true) { return transformationType === enums_1.TransformationType.CLASS_TO_PLAIN; } return true; }) .map(metadata => metadata.propertyName); } getExcludedProperties(target, transformationType) { return this.getExcludedMetadatas(target) .filter(metadata => { if (!metadata.options) return true; if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true) return true; if (metadata.options.toClassOnly === true) { return (transformationType === enums_1.TransformationType.CLASS_TO_CLASS || transformationType === enums_1.TransformationType.PLAIN_TO_CLASS); } if (metadata.options.toPlainOnly === true) { return transformationType === enums_1.TransformationType.CLASS_TO_PLAIN; } return true; }) .map(metadata => metadata.propertyName); } clear() { this._typeMetadatas.clear(); this._exposeMetadatas.clear(); this._excludeMetadatas.clear(); this._ancestorsMap.clear(); } // ------------------------------------------------------------------------- // Private Methods // ------------------------------------------------------------------------- getMetadata(metadatas, target) { const metadataFromTargetMap = metadatas.get(target); let metadataFromTarget; if (metadataFromTargetMap) { metadataFromTarget = Array.from(metadataFromTargetMap.values()).filter(meta => meta.propertyName !== undefined); } const metadataFromAncestors = []; for (const ancestor of this.getAncestors(target)) { const ancestorMetadataMap = metadatas.get(ancestor); if (ancestorMetadataMap) { const metadataFromAncestor = Array.from(ancestorMetadataMap.values()).filter(meta => meta.propertyName !== undefined); metadataFromAncestors.push(...metadataFromAncestor); } } return metadataFromAncestors.concat(metadataFromTarget || []); } findMetadata(metadatas, target, propertyName) { const metadataFromTargetMap = metadatas.get(target); if (metadataFromTargetMap) { const metadataFromTarget = metadataFromTargetMap.get(propertyName); if (metadataFromTarget) { return metadataFromTarget; } } for (const ancestor of this.getAncestors(target)) { const ancestorMetadataMap = metadatas.get(ancestor); if (ancestorMetadataMap) { const ancestorResult = ancestorMetadataMap.get(propertyName); if (ancestorResult) { return ancestorResult; } } } return undefined; } findMetadatas(metadatas, target, propertyName) { const metadataFromTargetMap = metadatas.get(target); let metadataFromTarget; if (metadataFromTargetMap) { metadataFromTarget = metadataFromTargetMap.get(propertyName); } const metadataFromAncestorsTarget = []; for (const ancestor of this.getAncestors(target)) { const ancestorMetadataMap = metadatas.get(ancestor); if (ancestorMetadataMap) { if (ancestorMetadataMap.has(propertyName)) { metadataFromAncestorsTarget.push(...ancestorMetadataMap.get(propertyName)); } } } return metadataFromAncestorsTarget .slice() .reverse() .concat((metadataFromTarget || []).slice().reverse()); } getAncestors(target) { if (!target) return []; if (!this._ancestorsMap.has(target)) { const ancestors = []; for (let baseClass = Object.getPrototypeOf(target.prototype.constructor); typeof baseClass.prototype !== 'undefined'; baseClass = Object.getPrototypeOf(baseClass.prototype.constructor)) { ancestors.push(baseClass); } this._ancestorsMap.set(target, ancestors); } return this._ancestorsMap.get(target); } } exports.MetadataStorage = MetadataStorage; //# sourceMappingURL=MetadataStorage.js.map