/** * Add a filter before save the storage. * You should give a value to the options : includes & excludes. * (Via to JSON hook) * @param {*} Lycabinet */ import { DEBUG, deepClone, deepSupplement, is_Defined } from '../utils/util'; export function addFilter(Lycabinet){ const Proto = Lycabinet.prototype; /** * Set a filter by options * Support dot `.` selection expression * @param {Object} cabinetIns {includes: [], excludes:[] } */ Lycabinet.mixin(function(cabinetIns){ const opt = cabinetIns.options; if(opt.includes || opt.excludes){ cabinetIns._once("mounted", ()=>{ cabinetIns.setFilter(); // auto set. }); } deepSupplement(opt, { includes: [], // vacant equals to all! excludes: [], // vacant equals to none. }); }); Proto.setFilter = function(){ const _this = this; Object.defineProperty(this.getCabinet(), 'toJSON', { configurable: true, enumerable: false, // hide in enumeration. value: function(){ const cabinet = _this.getCabinet(); // set the basement includes. const Includes = _this.options.includes; const Excludes = _this.options.excludes; return CustomFilter(cabinet, Includes, Excludes); }, }); }; /** * Allow you appointed the specific Storage Object and * temporary Includes/Excludes options. */ Lycabinet.$filter = CustomFilter; } /** * Helper Function. */ function CustomFilter(cabinet, Includes, Excludes){ let filtered = Object.create(null); if(Includes.length>0){ let includesKeyMap: number[]= []; Includes.forEach( (associatedKey,index)=>{ let current = includesKeyMap[index] = associatedKey.split("."); let currentStore = cabinet; let targetStore = filtered; current.forEach((item, i )=>{ currentStore = currentStore[item]; // Compliment the non-final selection. if( i +1 < current.length && is_Defined( currentStore )){ if(!is_Defined(targetStore[item]) ) targetStore[item] = {}; // else // targetStore[item] = currentStore; }else targetStore[item] = currentStore; targetStore = targetStore[item]; }); }); // if the configuration of `includes` option is not designed, it will mean exactly includes all by default. }else Object.assign(filtered, cabinet); // caculating the exclude filtering. let excludesKeyMap: Array= []; let currentStore = deepClone(filtered); Excludes.forEach( (associatedKey, index, arr)=>{ let current = excludesKeyMap[index] = associatedKey.split("."); let pointer = currentStore; for(let i=0; i