object-scan
Advanced tools
Comparing version 18.2.1 to 18.3.0
@@ -47,3 +47,3 @@ import assert from '../generic/assert.js'; | ||
'traversedBy', 'isCircular', 'isLeaf', 'depth', | ||
'bool', 'count' | ||
'bool', 'count', 'sum' | ||
].includes(ctx.rtn) | ||
@@ -50,0 +50,0 @@ || ( |
@@ -26,2 +26,11 @@ export default (kwargs, ctx) => { | ||
} | ||
if (ctx.rtn === 'sum') { | ||
let result = 0; | ||
return { | ||
onMatch: ({ value }) => { | ||
result += value; | ||
}, | ||
get: () => result | ||
}; | ||
} | ||
@@ -28,0 +37,0 @@ const result = []; |
@@ -131,3 +131,3 @@ import { | ||
if (ctx.filterFn === undefined || ctx.filterFn(kwargs) !== false) { | ||
result.onMatch(); | ||
result.onMatch(kwargs); | ||
if (ctx.abort) { | ||
@@ -134,0 +134,0 @@ stack.length = 0; |
@@ -1,1 +0,1 @@ | ||
var e={};(()=>{e.d=(t,r)=>{for(var n in r){if(e.o(r,n)&&!e.o(t,n)){Object.defineProperty(t,n,{enumerable:true,get:r[n]})}}}})();(()=>{e.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t)})();if(typeof e!=="undefined")e.ab=new URL(".",import.meta.url).pathname.slice(import.meta.url.match(/^file:\/\/\/\w:/)?1:0,-1)+"/";var t={};e.d(t,{Z:()=>lib});const assert=(e,t="Internal Logic Error")=>{if(!e){throw new Error(typeof t==="function"?t():t)}};const defineProperty=(e,t,r,n=true)=>Object.defineProperty(e,t,{value:r,writable:!n});const r=/[?!,.*+[\](){}\\]/g;const helper_escape=e=>e.replace(r,"\\$&");const escapeRegex=e=>e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&");const asRegex=e=>{try{return new RegExp(e)}catch(t){throw new Error(`Invalid Regex: "${e}"`)}};const toPath=e=>e.reduce(((e,t)=>`${e}${typeof t==="number"?`[${t}]`:`${e?".":""}${helper_escape(t)}`}`),"");const parseWildcard=e=>{let t="";let r=false;for(let n=0;n<e.length;n+=1){const s=e[n];if(!r&&s==="\\"){r=true}else if(!r&&s==="*"){t+=".*"}else if(!r&&s==="+"){t+=".+"}else if(!r&&s==="?"){t+="."}else{t+=escapeRegex(s);r=false}}return new RegExp(`^${t}$`)};const compileWildcard=e=>{if(["**","++"].includes(e)){return asRegex(".*")}if((e.startsWith("**(")||e.startsWith("++("))&&e.endsWith(")")){return asRegex(e.slice(3,-1))}if(e.startsWith("[(")&&e.endsWith(")]")){return asRegex(e.slice(2,-2))}if(e.startsWith("(")&&e.endsWith(")")){return asRegex(e.slice(1,-1))}if(e.startsWith("[")&&e.endsWith("]")){return parseWildcard(e.slice(1,-1))}return parseWildcard(e)};class Wildcard{constructor(e,t){this.value=e;this.excluded=t;this.regex=compileWildcard(e);this.isArrayTarget=e.startsWith("[")&&e.endsWith("]");this.isSimpleStarRec=e==="**";this.isSimplePlusRec=e==="++";this.isSimpleRec=this.isSimpleStarRec||this.isSimplePlusRec;this.isRegexStarRec=e.startsWith("**(")&&e.endsWith(")");this.isRegexPlusRec=e.startsWith("++(")&&e.endsWith(")");this.isRegexRec=this.isRegexStarRec||this.isRegexPlusRec;this.isStarRec=this.isSimpleStarRec||this.isRegexStarRec;this.isPlusRec=this.isSimplePlusRec||this.isRegexPlusRec;this.isRec=this.isStarRec||this.isPlusRec;this.isAnyArrayTarget=e==="[*]";this.isAnyObjTarget=e==="*"}recMatch(e){if(!this.isRec){return false}if(this.isSimpleRec){return true}return this.regex.test(e)}typeMatch(e,t){if(this.isSimpleRec){return true}if(t&&this.isAnyArrayTarget){return true}if(!t&&this.isAnyObjTarget){return true}if(t!==this.isArrayTarget&&!this.isRec){return false}return this.regex.test(e)}}class Ref{constructor(e,t=null){this.left=t===null;this.link=t===null?new Ref(e,this):t;this.type=e;this.isStarRec=this.type==="**";this.node=null;this.pointer=null}setPointer(e){this.pointer=e;this.link.pointer=e}setNode(e){this.node=e;this.link.node=e}}const n=Symbol("is-excluded");const markExcluded=e=>defineProperty(e,n,true);const isExcluded=e=>e[n]===true;const throwError=(e,t,r={})=>{throw new Error(Object.entries(r).reduce(((e,[t,r])=>`${e}, ${t} ${r}`),`${e}: ${t}`))};const getSimple=e=>{if(Array.isArray(e)){return e.length===1?e[0]:e}return e.size===1?e.values().next().value:e};const parser_result=e=>{let t=new Set;let r=false;let n=false;let s=0;const i=[];const newChild=e=>{if(isExcluded(t)){assert(n===false);n=true}i.push(t);t=e?new Set:[]};const finishChild=()=>{const e=i.pop();const r=Array.isArray(e);const n=getSimple(t);if(!r&&n instanceof Set){n.forEach((t=>e.add(t)))}else{e[r?"push":"add"](n)}t=e};newChild(false);return{setInArray:(t,n)=>{if(r===t){throwError(r?"Bad Array Start":"Bad Array Terminator",e,{char:n})}r=t},finishElement:(i,o,a,{finReq:l=false,group:c=false}={})=>{const u=s===i;if(u){if(!a.includes(e[i-1]||null)){throwError(o,e,{char:i})}s+=1}else{if(l){throwError(o,e,{char:i})}const a=e.slice(s,i);if(c&&!["**","++"].includes(a)){throwError("Bad Group Start",e,{char:i})}if(r&&!(/^[?*+\d]+$/.test(a)||a.startsWith("(")&&a.endsWith(")"))){throwError("Bad Array Selector",e,{selector:a})}if(c){t.push(new Ref(a))}else{t.push(new Wildcard(r?`[${a}]`:a,n));n=false}s=i+1}},startExclusion:t=>{if(n!==false){throwError("Redundant Exclusion",e,{char:t})}n=true},startGroup:()=>{newChild(true);if(n){markExcluded(t);n=false}newChild(false)},newGroupElement:()=>{finishChild();newChild(false)},finishGroup:r=>{if(i.length<2){throwError("Unexpected Group Terminator",e,{char:r})}finishChild();finishChild();assert(Array.isArray(t));const n=t[t.length-2];if(n instanceof Ref&&n.left===true){t.push(n.link)}},finalizeResult:()=>{finishChild();assert(n===false);if(i.length!==0){throwError("Non Terminated Group",e)}if(r){throwError("Non Terminated Array",e)}return getSimple(t)}}};const parser_throwError=(e,t,r={})=>{throw new Error(Object.entries(r).reduce(((e,[t,r])=>`${e}, ${t} ${r}`),`${e}: ${t}`))};const parse=(e,t)=>{if(e===""){return new Wildcard("",false)}const r=parser_result(e);const n=e.length;let s=false;let i=0;for(let o=0;o<n;o+=1){const n=e[o];if(s===false){if(i===0){switch(n){case".":r.finishElement(o,"Bad Path Separator",["]","}"]);break;case"[":if(!t.useArraySelector){parser_throwError("Forbidden Array Selector",e,{char:o})}r.finishElement(o,"Bad Array Start",[null,"!","{",",","}","]"]);r.setInArray(true,o);break;case"]":r.finishElement(o,"Bad Array Terminator",["}"]);r.setInArray(false,o);break;case"{":r.finishElement(o,"Bad Group Start",[null,"!",".","[","{",","],{group:true});r.startGroup();break;case",":r.finishElement(o,"Bad Group Separator",["]","}"]);r.newGroupElement();break;case"}":r.finishElement(o,"Bad Group Terminator",["]","}"]);r.finishGroup(o);break;case"!":r.finishElement(o,"Bad Exclusion",[null,".",",","{","["],{finReq:true});r.startExclusion(o);break;default:break}}switch(n){case"(":i+=1;break;case")":if(i===0){parser_throwError("Unexpected Parentheses",e,{char:o})}i-=1;break;default:break}}s=n==="\\"?!s:false}if(s!==false){parser_throwError("Dangling Escape",e,{char:n-1})}if(i!==0){parser_throwError("Unterminated Parentheses",e)}r.finishElement(n,"Bad Terminator",["]","}"]);return r.finalizeResult()};const s={parse:parse};const iterator=(e,t)=>{const r=[e];const n=[null];const s=[];const i=[];const o=[];let a=0;let l=true;while(a!==-1){const e=r[a];if(e instanceof Set){r[a]=[...e];r[a].or=true}else if(Array.isArray(e)){if(e.or!==true){r.splice(a,1,...e);n.splice(a,1,...new Array(e.length).fill(n[a]));if(n[a]!==null){i[n[a]]+=e.length-1}}else{if(s[a]===undefined){s[a]=0;i[a]=0}else if(i[a]!==0){r.splice(a+1,i[a]);n.splice(a+1,i[a]);i[a]=0}if(s[a]<e.length){r.splice(a+1,0,e[s[a]]);n.splice(a+1,0,a);s[a]=(s[a]||0)+1;i[a]+=1;l=true;a+=1}else{s[a]=0;a-=1}}}else if(l===true){o.push(e);t("ADD",e);if(a===r.length-1){t("FIN",o);l=false}else{a+=1}}else{t("RM",o.pop());a-=1}}};const compiler_iterator=(e,t,r,{onAdd:n,onFin:s})=>{const i=[[[e,null]]];let o=false;iterator(r,((r,a)=>{if(r==="RM"){if(a.excluded===true){o=false}i.length-=2}else if(r==="ADD"){if(a.excluded===true){if(o){throw new Error(`Redundant Exclusion: "${t}"`)}o=true}const e=[];const r=i[i.length-2];i[i.length-1].forEach((([t,s])=>n(t,s,a,r,(r=>e.push([r,t])))));i.push(a,e)}else{i[i.length-1].filter((([t])=>t!==e)).forEach((([e,t])=>s(e,t,a[a.length-1],o)))}}))};const i=Symbol("leaf");const markLeaf=(e,t,r)=>defineProperty(e,i,t,r);const isLeaf=e=>i in e;const isMatch=e=>e!==undefined&&e[i]===true;const o=Symbol("roots");const setRoots=(e,t)=>defineProperty(e,o,t);const getRoots=e=>e[o];const a=Symbol("has-matches");const setHasMatches=e=>defineProperty(e,a,true);const hasMatches=e=>e[a]===true;const merge=(e,t,...r)=>{const n=e[t];if(n===undefined){defineProperty(e,t,r)}else{n.push(...r.filter((e=>!n.includes(e))))}};const l=Symbol("leaf-needles");const addLeafNeedle=(e,t)=>merge(e,l,t);const getLeafNeedles=e=>e[l]||[];const c=Symbol("leaf-needles-exclude");const addLeafNeedleExclude=(e,t)=>merge(e,c,t);const getLeafNeedlesExclude=e=>e[c]||[];const u=Symbol("leaf-needles-match");const addLeafNeedleMatch=(e,t)=>merge(e,u,t);const getLeafNeedlesMatch=e=>e[u]||[];const f=Symbol("needles");const addNeedle=(e,t)=>merge(e,f,t);const getNeedles=e=>e[f];const h=Symbol("index");const setIndex=(e,t,r)=>defineProperty(e,h,t,r);const getIndex=e=>e[h];const d=Symbol("order");const setOrder=(e,t)=>defineProperty(e,d,t);const getOrder=e=>e[d];const p=Symbol("wildcard");const setWildcard=(e,t)=>defineProperty(e,p,t);const getWildcard=e=>e[p];const g=Symbol("values");const setValues=(e,t)=>defineProperty(e,g,t);const addValues=(e,t)=>merge(e,g,...t);const getValues=e=>e[g];const matchedBy=e=>Array.from(new Set(e.flatMap((e=>getLeafNeedlesMatch(e)))));const excludedBy=e=>Array.from(new Set(e.flatMap((e=>getLeafNeedlesExclude(e)))));const traversedBy=e=>Array.from(new Set(e.flatMap((e=>getNeedles(e)))));const isLastLeafMatch=e=>{let t=Number.MIN_SAFE_INTEGER;let r=null;for(let n=0,s=e.length;n<s;n+=1){const s=e[n];const i=getIndex(s);if(i!==undefined&&i>t){t=i;r=s}}return r!==null&&isMatch(r)};const applyNeedle=(e,t,r,n)=>{compiler_iterator(e,t,r,{onAdd:(e,r,s,i,o)=>{addNeedle(e,t);if(s instanceof Ref){if(s.left===true){if(s.isStarRec){s.setPointer(e)}s.setNode({});n.stack.push(e,s.node,true);o(s.node)}else{s.target="target"in i?i.target:r[i.value];n.stack.push(s.target,s.node,true);if(s.pointer!==null){o(s.pointer);s.setPointer(null)}o(e)}return}const a=i!==undefined&&s.isStarRec&&s.value===i.value;if(a&&n.strict){throw new Error(`Redundant Recursion: "${t}"`)}if(!a){if(!(s.value in e)){const t={};e[s.value]=t;n.stack.push(e,t,false);if(n.orderByNeedles){setOrder(t,n.counter)}setWildcard(t,s)}o(e[s.value])}else{s.target=e}if(s.isStarRec){o(e)}},onFin:(e,r,s,i)=>{if(n.strict&&s.isSimpleStarRec){const e=Object.keys(r).filter((e=>!["**",""].includes(e)));if(e.length!==0){throw new Error(`Needle Target Invalidated: "${r[e[0]][f][0]}" by "${t}"`)}}addNeedle(e,t);if(n.strict&&l in e){throw new Error(`Redundant Needle Target: "${e[l][0]}" vs "${t}"`)}addLeafNeedle(e,t,n.strict);if(i){addLeafNeedleExclude(e,t)}else{addLeafNeedleMatch(e,t)}markLeaf(e,!i,n.strict);setIndex(e,n.counter,n.strict);n.counter+=1}})};const finalizeTower=(e,t)=>{const{stack:r}=t;const n=[];while(r.length!==0){const e=r.pop();const t=r.pop();const s=r.pop();if(!(g in t)){setValues(t,Object.values(t).reverse())}if(e){n.push(s,t)}if(isMatch(t)){setHasMatches(t)}if(hasMatches(t)&&!hasMatches(s)){setHasMatches(s)}}setValues(e,Object.values(e).reverse());for(let e=0,t=n.length;e<t;e+=2){const t=n[e];const r=n[e+1];addValues(t,getValues(r))}if(t.useArraySelector===false){const t=[];if(""in e){t.push(e[""])}t.push(...getValues(e).filter((e=>getWildcard(e).isStarRec)));setRoots(e,t)}};const compile=(e,t)=>{const r={};t.counter=0;t.stack=[];for(let n=0;n<e.length;n+=1){const i=e[n];const o=[s.parse(i,t)];applyNeedle(r,i,o,t)}setWildcard(r,new Wildcard("*",false));finalizeTower(r,t);return r};const find_result=(e,t)=>{if(t.rtn==="context"){return{onMatch:()=>{},get:()=>e.context}}if(t.rtn==="bool"){let e=false;return{onMatch:()=>{e=true},get:()=>e}}if(t.rtn==="count"){let e=0;return{onMatch:()=>{e+=1},get:()=>e}}const r=[];return{onMatch:(()=>{if(typeof t.rtn==="function"){return()=>r.push(t.rtn(e))}if(Array.isArray(t.rtn)){return()=>r.push(t.rtn.map((t=>e[t])))}return()=>r.push(e[t.rtn])})(),get:()=>t.abort?r[0]:r}};const formatPath=(e,t)=>t.joined?toPath(e):[...e];const find=(e,t,r)=>{const n={haystack:e,context:r.context};if(r.beforeFn!==undefined){const e=r.beforeFn(n);if(e!==undefined){n.haystack=e}}const s=[false,t,null,0];const i=[];const o=[];let a;let l;let c;let u;let f=n.haystack;const h={getKey:()=>formatPath(i,r),get key(){return h.getKey()},getValue:()=>f,get value(){return h.getValue()},getEntry:()=>[formatPath(i,r),f],get entry(){return h.getEntry()},getIsMatch:()=>u,get isMatch(){return h.getIsMatch()},getMatchedBy:()=>matchedBy(c),get matchedBy(){return h.getMatchedBy()},getExcludedBy:()=>excludedBy(c),get excludedBy(){return h.getExcludedBy()},getTraversedBy:()=>traversedBy(c),get traversedBy(){return h.getTraversedBy()},getGproperty:()=>i[i.length-2],get gproperty(){return h.getGproperty()},getProperty:()=>i[i.length-1],get property(){return h.getProperty()},getGparent:()=>o[o.length-2],get gparent(){return h.getGparent()},getParent:()=>o[o.length-1],get parent(){return h.getParent()},getParents:()=>[...o].reverse(),get parents(){return h.getParents()},getIsCircular:()=>o.includes(f),get isCircular(){return h.getIsCircular()},getIsLeaf:()=>!(f instanceof Object),get isLeaf(){return h.getIsLeaf()},getDepth:()=>i.length,get depth(){return h.getDepth()},get result(){return h.getResult()},context:n.context};const d=find_result(h,r);h.getResult=()=>d.get();if(""in t[0]&&(r.useArraySelector||!Array.isArray(n.haystack))){s[1]=[...s[1],t[0][""]]}do{a=s.pop();l=s.pop();c=s.pop();u=s.pop();const e=i.length-a;for(let t=0;t<e;t+=1){o.pop();i.pop()}if(e===-1){o.push(f);i.push(l);f=f[l]}else if(l!==null){i[i.length-1]=l;f=o[o.length-1][l]}else{f=n.haystack}if(u){if(r.filterFn===undefined||r.filterFn(h)!==false){d.onMatch();if(r.abort){s.length=0}}continue}if(!c.some((e=>hasMatches(e)))){continue}const t=r.useArraySelector===false&&Array.isArray(f);if(!t&&isLastLeafMatch(c)){s.push(true,c,l,a);u=true}if((r.breakFn===undefined||r.breakFn(h)!==true)&&f instanceof Object){const e=Array.isArray(f);const n=Object.keys(f);if(!e&&r.compareFn){n.sort(r.compareFn(h))}if(!r.reverse){n.reverse()}for(let i=0,o=n.length;i<o;i+=1){const o=n[i];const l=[];if(t){l.push(...c);if(a===0){l.push(...getRoots(c[0]))}}else{for(let t=0,r=c.length;t!==r;t+=1){const r=c[t];if(getWildcard(r).recMatch(o)){l.push(r)}const n=getValues(r);let s=n.length;while(s--){const t=n[s];if(getWildcard(t).typeMatch(o,e)){l.push(t)}}}}if(r.orderByNeedles){l.index=Buffer.from(l.map((e=>getOrder(e))).sort());let t=s.length-3;const r=t-i*4;while(t!==r&&Buffer.compare(l.index,s[t].index)===1){t-=4}s.splice(t+3,0,false,l,e?Number(o):o,a+1)}else{s.push(false,l,e?Number(o):o,a+1)}}}}while(s.length!==0);n.result=d.get();if(r.afterFn!==undefined){const e=r.afterFn(n);if(e!==undefined){n.result=e}}return n.result};const expect=(e,t,r)=>{assert(r.includes(typeof e[t]),(()=>`Option "${t}" not one of [${r.join(", ")}]`))};const context=e=>{const t={filterFn:undefined,breakFn:undefined,beforeFn:undefined,afterFn:undefined,compareFn:undefined,reverse:true,orderByNeedles:false,abort:false,rtn:undefined,joined:false,useArraySelector:true,strict:true,...e};assert(Object.keys(t).length===12,"Unexpected Option provided");expect(t,"filterFn",["function","undefined"]);expect(t,"breakFn",["function","undefined"]);expect(t,"beforeFn",["function","undefined"]);expect(t,"afterFn",["function","undefined"]);expect(t,"compareFn",["function","undefined"]);expect(t,"reverse",["boolean"]);expect(t,"orderByNeedles",["boolean"]);expect(t,"abort",["boolean"]);assert(typeof t.rtn==="function"&&t.rtn.length===1||[undefined,"context","key","value","entry","property","gproperty","parent","gparent","parents","isMatch","matchedBy","excludedBy","traversedBy","isCircular","isLeaf","depth","bool","count"].includes(t.rtn)||Array.isArray(t.rtn)&&t.rtn.every((e=>["key","value","entry","property","gproperty","parent","gparent","parents","isMatch","matchedBy","excludedBy","traversedBy","isCircular","isLeaf","depth"].includes(e))),'Option "rtn" is malformed');expect(t,"joined",["boolean"]);expect(t,"useArraySelector",["boolean"]);expect(t,"strict",["boolean"]);return t};const lib=(e,t={})=>{assert(Array.isArray(e),'Argument "needles" expected to be Array');assert(t instanceof Object&&!Array.isArray(t),'Argument "opts" expected to be Object');if(e.length===0){return(e,t)=>t===undefined?[]:t}const r=context(t);const n=compile(e,r);return(e,t)=>find(e,[n],{context:t,...r,rtn:r.rtn||(t===undefined?"key":"context")})};var y=t.Z;export{y as default}; | ||
var e={};(()=>{e.d=(t,r)=>{for(var n in r){if(e.o(r,n)&&!e.o(t,n)){Object.defineProperty(t,n,{enumerable:true,get:r[n]})}}}})();(()=>{e.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t)})();if(typeof e!=="undefined")e.ab=new URL(".",import.meta.url).pathname.slice(import.meta.url.match(/^file:\/\/\/\w:/)?1:0,-1)+"/";var t={};e.d(t,{Z:()=>lib});const assert=(e,t="Internal Logic Error")=>{if(!e){throw new Error(typeof t==="function"?t():t)}};const defineProperty=(e,t,r,n=true)=>Object.defineProperty(e,t,{value:r,writable:!n});const r=/[?!,.*+[\](){}\\]/g;const helper_escape=e=>e.replace(r,"\\$&");const escapeRegex=e=>e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&");const asRegex=e=>{try{return new RegExp(e)}catch(t){throw new Error(`Invalid Regex: "${e}"`)}};const toPath=e=>e.reduce(((e,t)=>`${e}${typeof t==="number"?`[${t}]`:`${e?".":""}${helper_escape(t)}`}`),"");const parseWildcard=e=>{let t="";let r=false;for(let n=0;n<e.length;n+=1){const s=e[n];if(!r&&s==="\\"){r=true}else if(!r&&s==="*"){t+=".*"}else if(!r&&s==="+"){t+=".+"}else if(!r&&s==="?"){t+="."}else{t+=escapeRegex(s);r=false}}return new RegExp(`^${t}$`)};const compileWildcard=e=>{if(["**","++"].includes(e)){return asRegex(".*")}if((e.startsWith("**(")||e.startsWith("++("))&&e.endsWith(")")){return asRegex(e.slice(3,-1))}if(e.startsWith("[(")&&e.endsWith(")]")){return asRegex(e.slice(2,-2))}if(e.startsWith("(")&&e.endsWith(")")){return asRegex(e.slice(1,-1))}if(e.startsWith("[")&&e.endsWith("]")){return parseWildcard(e.slice(1,-1))}return parseWildcard(e)};class Wildcard{constructor(e,t){this.value=e;this.excluded=t;this.regex=compileWildcard(e);this.isArrayTarget=e.startsWith("[")&&e.endsWith("]");this.isSimpleStarRec=e==="**";this.isSimplePlusRec=e==="++";this.isSimpleRec=this.isSimpleStarRec||this.isSimplePlusRec;this.isRegexStarRec=e.startsWith("**(")&&e.endsWith(")");this.isRegexPlusRec=e.startsWith("++(")&&e.endsWith(")");this.isRegexRec=this.isRegexStarRec||this.isRegexPlusRec;this.isStarRec=this.isSimpleStarRec||this.isRegexStarRec;this.isPlusRec=this.isSimplePlusRec||this.isRegexPlusRec;this.isRec=this.isStarRec||this.isPlusRec;this.isAnyArrayTarget=e==="[*]";this.isAnyObjTarget=e==="*"}recMatch(e){if(!this.isRec){return false}if(this.isSimpleRec){return true}return this.regex.test(e)}typeMatch(e,t){if(this.isSimpleRec){return true}if(t&&this.isAnyArrayTarget){return true}if(!t&&this.isAnyObjTarget){return true}if(t!==this.isArrayTarget&&!this.isRec){return false}return this.regex.test(e)}}class Ref{constructor(e,t=null){this.left=t===null;this.link=t===null?new Ref(e,this):t;this.type=e;this.isStarRec=this.type==="**";this.node=null;this.pointer=null}setPointer(e){this.pointer=e;this.link.pointer=e}setNode(e){this.node=e;this.link.node=e}}const n=Symbol("is-excluded");const markExcluded=e=>defineProperty(e,n,true);const isExcluded=e=>e[n]===true;const throwError=(e,t,r={})=>{throw new Error(Object.entries(r).reduce(((e,[t,r])=>`${e}, ${t} ${r}`),`${e}: ${t}`))};const getSimple=e=>{if(Array.isArray(e)){return e.length===1?e[0]:e}return e.size===1?e.values().next().value:e};const parser_result=e=>{let t=new Set;let r=false;let n=false;let s=0;const i=[];const newChild=e=>{if(isExcluded(t)){assert(n===false);n=true}i.push(t);t=e?new Set:[]};const finishChild=()=>{const e=i.pop();const r=Array.isArray(e);const n=getSimple(t);if(!r&&n instanceof Set){n.forEach((t=>e.add(t)))}else{e[r?"push":"add"](n)}t=e};newChild(false);return{setInArray:(t,n)=>{if(r===t){throwError(r?"Bad Array Start":"Bad Array Terminator",e,{char:n})}r=t},finishElement:(i,o,a,{finReq:l=false,group:c=false}={})=>{const u=s===i;if(u){if(!a.includes(e[i-1]||null)){throwError(o,e,{char:i})}s+=1}else{if(l){throwError(o,e,{char:i})}const a=e.slice(s,i);if(c&&!["**","++"].includes(a)){throwError("Bad Group Start",e,{char:i})}if(r&&!(/^[?*+\d]+$/.test(a)||a.startsWith("(")&&a.endsWith(")"))){throwError("Bad Array Selector",e,{selector:a})}if(c){t.push(new Ref(a))}else{t.push(new Wildcard(r?`[${a}]`:a,n));n=false}s=i+1}},startExclusion:t=>{if(n!==false){throwError("Redundant Exclusion",e,{char:t})}n=true},startGroup:()=>{newChild(true);if(n){markExcluded(t);n=false}newChild(false)},newGroupElement:()=>{finishChild();newChild(false)},finishGroup:r=>{if(i.length<2){throwError("Unexpected Group Terminator",e,{char:r})}finishChild();finishChild();assert(Array.isArray(t));const n=t[t.length-2];if(n instanceof Ref&&n.left===true){t.push(n.link)}},finalizeResult:()=>{finishChild();assert(n===false);if(i.length!==0){throwError("Non Terminated Group",e)}if(r){throwError("Non Terminated Array",e)}return getSimple(t)}}};const parser_throwError=(e,t,r={})=>{throw new Error(Object.entries(r).reduce(((e,[t,r])=>`${e}, ${t} ${r}`),`${e}: ${t}`))};const parse=(e,t)=>{if(e===""){return new Wildcard("",false)}const r=parser_result(e);const n=e.length;let s=false;let i=0;for(let o=0;o<n;o+=1){const n=e[o];if(s===false){if(i===0){switch(n){case".":r.finishElement(o,"Bad Path Separator",["]","}"]);break;case"[":if(!t.useArraySelector){parser_throwError("Forbidden Array Selector",e,{char:o})}r.finishElement(o,"Bad Array Start",[null,"!","{",",","}","]"]);r.setInArray(true,o);break;case"]":r.finishElement(o,"Bad Array Terminator",["}"]);r.setInArray(false,o);break;case"{":r.finishElement(o,"Bad Group Start",[null,"!",".","[","{",","],{group:true});r.startGroup();break;case",":r.finishElement(o,"Bad Group Separator",["]","}"]);r.newGroupElement();break;case"}":r.finishElement(o,"Bad Group Terminator",["]","}"]);r.finishGroup(o);break;case"!":r.finishElement(o,"Bad Exclusion",[null,".",",","{","["],{finReq:true});r.startExclusion(o);break;default:break}}switch(n){case"(":i+=1;break;case")":if(i===0){parser_throwError("Unexpected Parentheses",e,{char:o})}i-=1;break;default:break}}s=n==="\\"?!s:false}if(s!==false){parser_throwError("Dangling Escape",e,{char:n-1})}if(i!==0){parser_throwError("Unterminated Parentheses",e)}r.finishElement(n,"Bad Terminator",["]","}"]);return r.finalizeResult()};const s={parse:parse};const iterator=(e,t)=>{const r=[e];const n=[null];const s=[];const i=[];const o=[];let a=0;let l=true;while(a!==-1){const e=r[a];if(e instanceof Set){r[a]=[...e];r[a].or=true}else if(Array.isArray(e)){if(e.or!==true){r.splice(a,1,...e);n.splice(a,1,...new Array(e.length).fill(n[a]));if(n[a]!==null){i[n[a]]+=e.length-1}}else{if(s[a]===undefined){s[a]=0;i[a]=0}else if(i[a]!==0){r.splice(a+1,i[a]);n.splice(a+1,i[a]);i[a]=0}if(s[a]<e.length){r.splice(a+1,0,e[s[a]]);n.splice(a+1,0,a);s[a]=(s[a]||0)+1;i[a]+=1;l=true;a+=1}else{s[a]=0;a-=1}}}else if(l===true){o.push(e);t("ADD",e);if(a===r.length-1){t("FIN",o);l=false}else{a+=1}}else{t("RM",o.pop());a-=1}}};const compiler_iterator=(e,t,r,{onAdd:n,onFin:s})=>{const i=[[[e,null]]];let o=false;iterator(r,((r,a)=>{if(r==="RM"){if(a.excluded===true){o=false}i.length-=2}else if(r==="ADD"){if(a.excluded===true){if(o){throw new Error(`Redundant Exclusion: "${t}"`)}o=true}const e=[];const r=i[i.length-2];i[i.length-1].forEach((([t,s])=>n(t,s,a,r,(r=>e.push([r,t])))));i.push(a,e)}else{i[i.length-1].filter((([t])=>t!==e)).forEach((([e,t])=>s(e,t,a[a.length-1],o)))}}))};const i=Symbol("leaf");const markLeaf=(e,t,r)=>defineProperty(e,i,t,r);const isLeaf=e=>i in e;const isMatch=e=>e!==undefined&&e[i]===true;const o=Symbol("roots");const setRoots=(e,t)=>defineProperty(e,o,t);const getRoots=e=>e[o];const a=Symbol("has-matches");const setHasMatches=e=>defineProperty(e,a,true);const hasMatches=e=>e[a]===true;const merge=(e,t,...r)=>{const n=e[t];if(n===undefined){defineProperty(e,t,r)}else{n.push(...r.filter((e=>!n.includes(e))))}};const l=Symbol("leaf-needles");const addLeafNeedle=(e,t)=>merge(e,l,t);const getLeafNeedles=e=>e[l]||[];const c=Symbol("leaf-needles-exclude");const addLeafNeedleExclude=(e,t)=>merge(e,c,t);const getLeafNeedlesExclude=e=>e[c]||[];const u=Symbol("leaf-needles-match");const addLeafNeedleMatch=(e,t)=>merge(e,u,t);const getLeafNeedlesMatch=e=>e[u]||[];const f=Symbol("needles");const addNeedle=(e,t)=>merge(e,f,t);const getNeedles=e=>e[f];const h=Symbol("index");const setIndex=(e,t,r)=>defineProperty(e,h,t,r);const getIndex=e=>e[h];const d=Symbol("order");const setOrder=(e,t)=>defineProperty(e,d,t);const getOrder=e=>e[d];const p=Symbol("wildcard");const setWildcard=(e,t)=>defineProperty(e,p,t);const getWildcard=e=>e[p];const g=Symbol("values");const setValues=(e,t)=>defineProperty(e,g,t);const addValues=(e,t)=>merge(e,g,...t);const getValues=e=>e[g];const matchedBy=e=>Array.from(new Set(e.flatMap((e=>getLeafNeedlesMatch(e)))));const excludedBy=e=>Array.from(new Set(e.flatMap((e=>getLeafNeedlesExclude(e)))));const traversedBy=e=>Array.from(new Set(e.flatMap((e=>getNeedles(e)))));const isLastLeafMatch=e=>{let t=Number.MIN_SAFE_INTEGER;let r=null;for(let n=0,s=e.length;n<s;n+=1){const s=e[n];const i=getIndex(s);if(i!==undefined&&i>t){t=i;r=s}}return r!==null&&isMatch(r)};const applyNeedle=(e,t,r,n)=>{compiler_iterator(e,t,r,{onAdd:(e,r,s,i,o)=>{addNeedle(e,t);if(s instanceof Ref){if(s.left===true){if(s.isStarRec){s.setPointer(e)}s.setNode({});n.stack.push(e,s.node,true);o(s.node)}else{s.target="target"in i?i.target:r[i.value];n.stack.push(s.target,s.node,true);if(s.pointer!==null){o(s.pointer);s.setPointer(null)}o(e)}return}const a=i!==undefined&&s.isStarRec&&s.value===i.value;if(a&&n.strict){throw new Error(`Redundant Recursion: "${t}"`)}if(!a){if(!(s.value in e)){const t={};e[s.value]=t;n.stack.push(e,t,false);if(n.orderByNeedles){setOrder(t,n.counter)}setWildcard(t,s)}o(e[s.value])}else{s.target=e}if(s.isStarRec){o(e)}},onFin:(e,r,s,i)=>{if(n.strict&&s.isSimpleStarRec){const e=Object.keys(r).filter((e=>!["**",""].includes(e)));if(e.length!==0){throw new Error(`Needle Target Invalidated: "${r[e[0]][f][0]}" by "${t}"`)}}addNeedle(e,t);if(n.strict&&l in e){throw new Error(`Redundant Needle Target: "${e[l][0]}" vs "${t}"`)}addLeafNeedle(e,t,n.strict);if(i){addLeafNeedleExclude(e,t)}else{addLeafNeedleMatch(e,t)}markLeaf(e,!i,n.strict);setIndex(e,n.counter,n.strict);n.counter+=1}})};const finalizeTower=(e,t)=>{const{stack:r}=t;const n=[];while(r.length!==0){const e=r.pop();const t=r.pop();const s=r.pop();if(!(g in t)){setValues(t,Object.values(t).reverse())}if(e){n.push(s,t)}if(isMatch(t)){setHasMatches(t)}if(hasMatches(t)&&!hasMatches(s)){setHasMatches(s)}}setValues(e,Object.values(e).reverse());for(let e=0,t=n.length;e<t;e+=2){const t=n[e];const r=n[e+1];addValues(t,getValues(r))}if(t.useArraySelector===false){const t=[];if(""in e){t.push(e[""])}t.push(...getValues(e).filter((e=>getWildcard(e).isStarRec)));setRoots(e,t)}};const compile=(e,t)=>{const r={};t.counter=0;t.stack=[];for(let n=0;n<e.length;n+=1){const i=e[n];const o=[s.parse(i,t)];applyNeedle(r,i,o,t)}setWildcard(r,new Wildcard("*",false));finalizeTower(r,t);return r};const find_result=(e,t)=>{if(t.rtn==="context"){return{onMatch:()=>{},get:()=>e.context}}if(t.rtn==="bool"){let e=false;return{onMatch:()=>{e=true},get:()=>e}}if(t.rtn==="count"){let e=0;return{onMatch:()=>{e+=1},get:()=>e}}if(t.rtn==="sum"){let e=0;return{onMatch:({value:t})=>{e+=t},get:()=>e}}const r=[];return{onMatch:(()=>{if(typeof t.rtn==="function"){return()=>r.push(t.rtn(e))}if(Array.isArray(t.rtn)){return()=>r.push(t.rtn.map((t=>e[t])))}return()=>r.push(e[t.rtn])})(),get:()=>t.abort?r[0]:r}};const formatPath=(e,t)=>t.joined?toPath(e):[...e];const find=(e,t,r)=>{const n={haystack:e,context:r.context};if(r.beforeFn!==undefined){const e=r.beforeFn(n);if(e!==undefined){n.haystack=e}}const s=[false,t,null,0];const i=[];const o=[];let a;let l;let c;let u;let f=n.haystack;const h={getKey:()=>formatPath(i,r),get key(){return h.getKey()},getValue:()=>f,get value(){return h.getValue()},getEntry:()=>[formatPath(i,r),f],get entry(){return h.getEntry()},getIsMatch:()=>u,get isMatch(){return h.getIsMatch()},getMatchedBy:()=>matchedBy(c),get matchedBy(){return h.getMatchedBy()},getExcludedBy:()=>excludedBy(c),get excludedBy(){return h.getExcludedBy()},getTraversedBy:()=>traversedBy(c),get traversedBy(){return h.getTraversedBy()},getGproperty:()=>i[i.length-2],get gproperty(){return h.getGproperty()},getProperty:()=>i[i.length-1],get property(){return h.getProperty()},getGparent:()=>o[o.length-2],get gparent(){return h.getGparent()},getParent:()=>o[o.length-1],get parent(){return h.getParent()},getParents:()=>[...o].reverse(),get parents(){return h.getParents()},getIsCircular:()=>o.includes(f),get isCircular(){return h.getIsCircular()},getIsLeaf:()=>!(f instanceof Object),get isLeaf(){return h.getIsLeaf()},getDepth:()=>i.length,get depth(){return h.getDepth()},get result(){return h.getResult()},context:n.context};const d=find_result(h,r);h.getResult=()=>d.get();if(""in t[0]&&(r.useArraySelector||!Array.isArray(n.haystack))){s[1]=[...s[1],t[0][""]]}do{a=s.pop();l=s.pop();c=s.pop();u=s.pop();const e=i.length-a;for(let t=0;t<e;t+=1){o.pop();i.pop()}if(e===-1){o.push(f);i.push(l);f=f[l]}else if(l!==null){i[i.length-1]=l;f=o[o.length-1][l]}else{f=n.haystack}if(u){if(r.filterFn===undefined||r.filterFn(h)!==false){d.onMatch(h);if(r.abort){s.length=0}}continue}if(!c.some((e=>hasMatches(e)))){continue}const t=r.useArraySelector===false&&Array.isArray(f);if(!t&&isLastLeafMatch(c)){s.push(true,c,l,a);u=true}if((r.breakFn===undefined||r.breakFn(h)!==true)&&f instanceof Object){const e=Array.isArray(f);const n=Object.keys(f);if(!e&&r.compareFn){n.sort(r.compareFn(h))}if(!r.reverse){n.reverse()}for(let i=0,o=n.length;i<o;i+=1){const o=n[i];const l=[];if(t){l.push(...c);if(a===0){l.push(...getRoots(c[0]))}}else{for(let t=0,r=c.length;t!==r;t+=1){const r=c[t];if(getWildcard(r).recMatch(o)){l.push(r)}const n=getValues(r);let s=n.length;while(s--){const t=n[s];if(getWildcard(t).typeMatch(o,e)){l.push(t)}}}}if(r.orderByNeedles){l.index=Buffer.from(l.map((e=>getOrder(e))).sort());let t=s.length-3;const r=t-i*4;while(t!==r&&Buffer.compare(l.index,s[t].index)===1){t-=4}s.splice(t+3,0,false,l,e?Number(o):o,a+1)}else{s.push(false,l,e?Number(o):o,a+1)}}}}while(s.length!==0);n.result=d.get();if(r.afterFn!==undefined){const e=r.afterFn(n);if(e!==undefined){n.result=e}}return n.result};const expect=(e,t,r)=>{assert(r.includes(typeof e[t]),(()=>`Option "${t}" not one of [${r.join(", ")}]`))};const context=e=>{const t={filterFn:undefined,breakFn:undefined,beforeFn:undefined,afterFn:undefined,compareFn:undefined,reverse:true,orderByNeedles:false,abort:false,rtn:undefined,joined:false,useArraySelector:true,strict:true,...e};assert(Object.keys(t).length===12,"Unexpected Option provided");expect(t,"filterFn",["function","undefined"]);expect(t,"breakFn",["function","undefined"]);expect(t,"beforeFn",["function","undefined"]);expect(t,"afterFn",["function","undefined"]);expect(t,"compareFn",["function","undefined"]);expect(t,"reverse",["boolean"]);expect(t,"orderByNeedles",["boolean"]);expect(t,"abort",["boolean"]);assert(typeof t.rtn==="function"&&t.rtn.length===1||[undefined,"context","key","value","entry","property","gproperty","parent","gparent","parents","isMatch","matchedBy","excludedBy","traversedBy","isCircular","isLeaf","depth","bool","count","sum"].includes(t.rtn)||Array.isArray(t.rtn)&&t.rtn.every((e=>["key","value","entry","property","gproperty","parent","gparent","parents","isMatch","matchedBy","excludedBy","traversedBy","isCircular","isLeaf","depth"].includes(e))),'Option "rtn" is malformed');expect(t,"joined",["boolean"]);expect(t,"useArraySelector",["boolean"]);expect(t,"strict",["boolean"]);return t};const lib=(e,t={})=>{assert(Array.isArray(e),'Argument "needles" expected to be Array');assert(t instanceof Object&&!Array.isArray(t),'Argument "opts" expected to be Object');if(e.length===0){return(e,t)=>t===undefined?[]:t}const r=context(t);const n=compile(e,r);return(e,t)=>find(e,[n],{context:t,...r,rtn:r.rtn||(t===undefined?"key":"context")})};var y=t.Z;export{y as default}; |
{ | ||
"name": "object-scan", | ||
"type": "module", | ||
"version": "18.2.1", | ||
"version": "18.3.0", | ||
"description": "Traverse object hierarchies using matching and callbacks.", | ||
@@ -75,3 +75,3 @@ "main": "lib/index.js", | ||
"node-tdd": "3.4.1", | ||
"object-scan": "18.1.3", | ||
"object-scan": "18.2.1", | ||
"smart-fs": "3.0.1", | ||
@@ -78,0 +78,0 @@ "stringify-object": "4.0.1", |
@@ -800,8 +800,9 @@ # Object-Scan | ||
- `count`: returns the match count | ||
- `sum`: returns the match sum | ||
When set to `array`, can contain any of the above except `context`, `bool` and `count`. | ||
When set to `array`, can contain any of the above except `context`, `bool`, `count` and `sum`. | ||
When set to `function`, called with _callback_ signature for every match. Returned value is added to the result. | ||
When **abort** is set to `true` and _rtn_ is not `context`, `bool` or `count`, | ||
When **abort** is set to `true` and _rtn_ is not `context`, `bool`, `count` or `sum`, | ||
the first entry of the result or _undefined_ is returned. | ||
@@ -885,3 +886,15 @@ | ||
</details> | ||
<details><summary> <code>['**']</code> <em>(return sum)</em> </summary> | ||
<!-- eslint-disable no-undef --> | ||
```js | ||
const haystack = { a: { b: { c: -2, d: 1 }, e: [3, 7] } }; | ||
objectScan(['**'], { | ||
filterFn: ({ value }) => typeof value === 'number', | ||
rtn: 'sum' | ||
})(haystack); | ||
// => 9 | ||
``` | ||
</details> | ||
#### joined | ||
@@ -888,0 +901,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
84736
932
1224