UNPKG

@zargu/couchdb-designer

Version:

Create and testing couchdb design document form directory structure.

210 lines (203 loc) 5.55 kB
import compileSelector from "../../util/compileSelector"; import compareAny from '../../util/compareAny'; const filters = { "$eq" : (docValue,filterValue) => { if(docValue !== undefined) { if(compareAny(docValue,filterValue) === 0){ return true; } } return false; }, "$and" : (docValue,filterValue) => { let result = true; for(let filter of filterValue){ result = result && mangoFilter(docValue,filter); if(!result){ return false; } } return result; }, "$lt" : (docValue,filterValue) => { if(docValue !== undefined) { if(compareAny(docValue,filterValue) < 0){ return true; } } return false; }, "$lte" : (docValue,filterValue) => { if(docValue !== undefined) { if(compareAny(docValue,filterValue) <= 0){ return true; } } return false; }, "$gt" : (docValue,filterValue) => { if(docValue !== undefined) { if(compareAny(docValue,filterValue) > 0){ return true; } } return false; }, "$gte" : (docValue,filterValue) => { if(docValue !== undefined) { if(compareAny(docValue,filterValue) >= 0){ return true; } } return false; }, "$ne" : (docValue,filterValue) => { if(docValue !== undefined) { if(compareAny(docValue,filterValue) !== 0){ return true; } } return false; }, "$exists" : (docValue,filterValue) => { let exists = docValue !== undefined; return exists === filterValue; }, "$type" : (docValue,filterValue) => { let docType = docValue === null ? 'null' : Array.isArray(docValue) ? 'array' : typeof docValue; return docType === filterValue; }, "$in" : (docValue,filterValue) => { if(docValue !== undefined) { for(let element of filterValue) { if(compareAny(element,docValue) === 0){ return true; } } } return false; }, "$nin" : (docValue,filterValue) => { return !filters['$in'](docValue,filterValue); }, "$size" : (docValue,filterValue) => { if(docValue !== undefined && Array.isArray(docValue)) { return docValue.length === filterValue; } return false; }, "$mod" : (docValue,filterValue) => { if(docValue !== undefined && Number.isInteger(docValue)){ return (docValue % filterValue[0]) === filterValue[1]; } return false; }, /* $regex is not 100% reliable becouse of differencies among PCRE library and node.js regular expression. The usage of $regex for partial_filter_selector not recommended. */ "$regex" : (docValue,filterValue) => { if(docValue !== undefined && typeof docValue === "string"){ let regex = new RegExp(filterValue); return regex.test(docValue); } return false; }, "$or": (docValue,filterValue) => { let result = false; for(let filter of filterValue){ result = result || mangoFilter(docValue, filter); if(result){ break; } } return result; }, "$not": (docValue,filterValue) => { return !mangoFilter(docValue, filterValue); }, "$nor": (docValue,filterValue) => { return !filters["or"](docValue, filterValue); }, "$all": (docValue,filterValue) => { if(docValue !== undefined && Array.isArray(docValue)){ for (let value of filterValue){ let include = false; for (let element of docValue){ include = include || compareAny(element,value) === 0; if(include){ break; } } if(!include){ return false; } } return true; } return false; }, "$elemMatch": (docValue,filterValue) => { if(docValue !== undefined && Array.isArray(docValue)){ for(let value of docValue){ if(mangoFilter(value, filterValue)){ return true; } } } return false; }, "$allMatch": (docValue,filterValue) => { if(docValue !== undefined && Array.isArray(docValue)){ let result = true; for(let value of docValue){ result = result && mangoFilter(value, filterValue); if(!result){ return false; } } return true; } return false; }, "$keyMapMatch": (docValue,filterValue) => { if(docValue !== undefined && typeof docValue === "object" && !Array.isArray(docValue)){ let keys = Object.keys(docValue); for(let key of keys){ if(mangoFilter(docValue[key], filterValue)){ return true; } } } return false; }, } const mangoFilter = (doc,filter) => { let filterKey = Object.keys(filter)[0]; if(filterKey in filters){ return filters[filterKey](doc,filter[filterKey]); }else{ let docTree = doc; let filterPath = filterKey.split('.'); for(let branch of filterPath){ if(branch in docTree){ docTree = docTree[branch]; }else{ docTree = undefined; break; } } return mangoFilter(docTree,filter[filterKey]); } }; const createMangoFilter = selector => { if(selector && Object.keys(selector).length){ let filter = compileSelector(selector); return doc => { return mangoFilter(doc,filter); } }else{ return () => true; } } export default createMangoFilter;