@stackone/expressions 0.28.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- var e=Object.create,t=Object.defineProperty,__name=(e,n)=>t(e,`name`,{value:n,configurable:!0}),n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,__copyProps=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},__toESM=(n,r,a)=>(a=n==null?{}:e(i(n)),__copyProps(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let o=require(`@stackone/utils`),s=require(`jexl`);s=__toESM(s);let c=require(`crypto`),l=require(`jsonpath-plus`);const u=`capitalize`,capitalize=(e,t=`first`)=>(0,o.isMissing)(e)||typeof e!=`string`?``:(t===`each`?`each`:`first`)==`each`?e.split(/(\s+)/).map(e=>e.trim()?e.charAt(0).toUpperCase()+e.slice(1):e).join(``):e.charAt(0).toUpperCase()+e.slice(1),d=`decodeUri`,decodeUri=e=>{if((0,o.isMissing)(e)||typeof e!=`string`)return``;try{return decodeURIComponent(e)}catch{return e}},f=`dedupe`,toCanonicalKey=e=>{if(e===null)return`null:null`;if(e===void 0)return`undefined:undefined`;if(typeof e!=`object`)return`${typeof e}:${String(e)}`;try{return`object:${stableStringify(e)}`}catch{return`unserializable:${Math.random()}`}},stableStringify=e=>typeof e!=`object`||!e?JSON.stringify(e):Array.isArray(e)?`[${e.map(stableStringify).join(`,`)}]`:`{${Object.keys(e).sort().map(t=>{let n=e[t];return`${JSON.stringify(t)}:${stableStringify(n)}`}).join(`,`)}}`,dedupe=e=>{if((0,o.isMissing)(e)||!Array.isArray(e))return[];let t=new Set,n=[];for(let r of e){let e=toCanonicalKey(r);t.has(e)||(t.add(e),n.push(r))}return n},p=`groupBy`,groupBy=(e,t)=>{if((0,o.isMissing)(e)||!Array.isArray(e)||(0,o.isMissing)(t)||typeof t!=`string`)return{};let n=Object.create(null);for(let r of e){if((0,o.isMissing)(r)||typeof r!=`object`||Array.isArray(r))continue;let e=r[t],i=(0,o.isMissing)(e)?`__missing__`:String(e);Object.prototype.hasOwnProperty.call(n,i)||(n[i]=[]),n[i].push(r)}return n},m=`hmacSha256`,hmacSha256=(e,t,n=`hex`)=>{if(e==null||typeof e!=`string`||t==null||typeof t!=`string`)return``;let r=n===`base64`?`base64`:`hex`;try{return(0,c.createHmac)(`sha256`,t).update(e).digest(r)}catch{return``}},h=`join`,join=(e,t=`,`)=>{if(!(0,o.notMissing)(e)||!Array.isArray(e)||e.length===0)return``;let n=typeof t==`string`?t:`,`;return e.filter(e=>(0,o.notMissing)(e)).map(e=>String(e)).join(n)},g=`md5`,md5=(e,t=`hex`)=>{if(e==null||typeof e!=`string`)return``;let n=t===`base64`?`base64`:`hex`;try{return(0,c.createHash)(`md5`).update(e).digest(n)}catch{return``}},_=`min`,min=(...e)=>{let t=e.length===1&&Array.isArray(e[0])?e[0]:e,n=[];for(let e of t)if(!(0,o.isMissing)(e)){if(typeof e==`number`&&!Number.isNaN(e))n.push(e);else if(typeof e==`string`){let t=Number(e);Number.isNaN(t)||n.push(t)}}return n.length===0?null:Math.min(...n)},v=`padStart`,padStart=(e,t,n=` `)=>{if(e==null)return``;let r=String(e);if((0,o.isMissing)(t)||typeof t!=`number`||t<0)return r;let i=typeof n==`string`?n:` `;return r.padStart(t,i)},y=`reduce`,b=[`sum`,`avg`,`count`,`min`,`max`,`concat`,`flatten`],reduce=(e,t,n)=>{if((0,o.isMissing)(e)||!Array.isArray(e)||(0,o.isMissing)(t)||typeof t!=`string`)return null;let r=t;if(!b.includes(r))return null;if(r===`count`)return e.length;let i=extractValues(e,n);switch(r){case`sum`:return numericReduce(i,e=>e.reduce((e,t)=>e+t,0));case`avg`:return numericReduce(i,e=>e.length>0?e.reduce((e,t)=>e+t,0)/e.length:null);case`min`:return numericReduce(i,e=>e.length>0?Math.min(...e):null);case`max`:return numericReduce(i,e=>e.length>0?Math.max(...e):null);case`concat`:case`flatten`:return i.reduce((e,t)=>Array.isArray(t)?e.concat(t):(e.push(t),e),[]);default:return null}},extractValues=(e,t)=>(0,o.isMissing)(t)||typeof t!=`string`?e:e.filter(e=>!(0,o.isMissing)(e)&&typeof e==`object`&&!Array.isArray(e)).map(e=>e[t]),numericReduce=(e,t)=>t(e.filter(e=>typeof e==`number`&&!Number.isNaN(e))),x=`regexMatch`,regexMatch=(e,t,n=1)=>{if((0,o.isMissing)(e)||typeof e!=`string`||(0,o.isMissing)(t)||typeof t!=`string`||t.length===0)return null;let r=typeof n==`number`?n:1;if(r<0)return null;try{let n=new RegExp(t),i=e.match(n);if(!i)return null;let a=i[r];return a===void 0?null:a}catch{return null}},S=`replace`,replace=(e,t,n,r=!1)=>{if((0,o.isMissing)(e)||typeof e!=`string`)return``;if(typeof t!=`string`)return e;let i=typeof n==`string`?n:``;return r===!0?e.replaceAll(t,i):e.replace(t,i)},C=`sha256`,sha256=(e,t=`hex`)=>{if(e==null||typeof e!=`string`)return``;let n=t===`base64`?`base64`:`hex`;try{return(0,c.createHash)(`sha256`).update(e).digest(n)}catch{return``}},w=`truncate`,truncate=(e,t,n=`...`)=>{if((0,o.isMissing)(e)||typeof e!=`string`)return``;if((0,o.isMissing)(t)||typeof t!=`number`||t<0)return e;let r=typeof n==`string`?n:`...`;if(e.length<=t)return e;let i=Math.max(0,t-r.length);return i<=0?e.slice(0,t):e.slice(0,i)+r},T=`urlParam`,urlParam=(e,t)=>{if((0,o.isMissing)(e)||typeof e!=`string`||(0,o.isMissing)(t)||typeof t!=`string`)return null;try{return new URL(e).searchParams.get(t)}catch{return null}},E=`zipObject`,zipObject=(e,t)=>{if((0,o.isMissing)(e)||!Array.isArray(e)||(0,o.isMissing)(t)||!Array.isArray(t))return{};let n=Math.min(e.length,t.length),r=[];for(let i=0;i<n;i++){let n=e[i];typeof n==`string`&&r.push([n,t[i]])}return Object.fromEntries(r)},createExpressionHandler=(e=()=>new s.Jexl)=>{let t=e();return t.addFunction(`nextAnniversary`,(e,t)=>(0,o.calculateNextAnniversary)({initialDate:e,format:t})),t.addFunction(`yearsElapsed`,(e,t,n)=>(0,o.calculateYearsElapsed)({startDate:e,endDate:n,format:t})),t.addFunction(`hasPassed`,(e,t,n)=>(0,o.dateHasPassed)({date:e,yearsToAdd:n,format:t})),t.addFunction(`now`,()=>new Date().toISOString()),t.addFunction(`includes`,(e,t)=>(0,o.isMissing)(e)||!Array.isArray(e)||e.length===0||(0,o.isMissing)(t)?!1:Array.isArray(t)?t.every(t=>e.includes(t)):e.includes(t)),t.addFunction(`includesSome`,(e,t)=>(0,o.isMissing)(e)||!Array.isArray(e)||e.length===0||(0,o.isMissing)(t)?!1:Array.isArray(t)?t.some(t=>e.includes(t)):e.includes(t)),t.addFunction(`present`,e=>(0,o.notMissing)(e)),t.addFunction(`missing`,e=>(0,o.isMissing)(e)),t.addFunction(`keys`,e=>(0,o.isMissing)(e)?[]:typeof e==`object`&&!Array.isArray(e)?Object.keys(e):[]),t.addFunction(`values`,e=>(0,o.isMissing)(e)?[]:typeof e==`object`&&!Array.isArray(e)?Object.values(e):[]),t.addFunction(`decodeBase64`,e=>{if((0,o.isMissing)(e)||typeof e!=`string`)return``;try{return(0,o.decodeFromBase64)(e)}catch{return``}}),t.addFunction(`encodeBase64`,e=>{if((0,o.isMissing)(e)||typeof e!=`string`)return``;try{return(0,o.encodeToBase64)(e)}catch{return``}}),t.addFunction(`deltaFromNowMs`,(e,t)=>{let n=Date.now(),r;if(typeof e==`number`)r=t===`seconds`?e*1e3:e;else if(typeof e==`string`)r=t===`timestamp`?parseInt(e,10):t===`seconds`?parseFloat(e)*1e3:new Date(e).getTime();else throw Error(`Unsupported date input type`);return r-n}),t.addBinaryOp(`??`,0,(e,t)=>(0,o.isMissing)(e)?t:(0,o.isMissing)(t)?e:e??t),t.addFunction(`capitalize`,capitalize),t.addFunction(`hmacSha256`,hmacSha256),t.addFunction(`md5`,md5),t.addFunction(`sha256`,sha256),t.addFunction(`decodeUri`,decodeUri),t.addFunction(`dedupe`,dedupe),t.addFunction(`groupBy`,groupBy),t.addFunction(`join`,join),t.addFunction(`min`,min),t.addFunction(`padStart`,padStart),t.addFunction(`zipObject`,zipObject),t.addFunction(`reduce`,reduce),t.addFunction(`regexMatch`,regexMatch),t.addFunction(`replace`,replace),t.addFunction(`truncate`,truncate),t.addFunction(`urlParam`,urlParam),t},D=/\${([^}]+)}/g,cleanExpression=e=>e.replace(/\$\./g,``).trim(),extractLeadingFunctionCall=e=>{let t=e.match(/^\w+\(/);if(!t)return null;let n=0;for(let r=t[0].length-1;r<e.length;r++)if(e[r]===`(`?n++:e[r]===`)`&&n--,n===0)return e.slice(r+1).trimStart().startsWith(`?`)?e.slice(0,r+1):null;return null},tryCompile=(e,t)=>{try{return e.compile(t)}catch{return null}},compileExpression=(e,t)=>{let n=tryCompile(e,t);if(n)return n;let r=extractLeadingFunctionCall(t);return r?tryCompile(e,`(${r})${t.slice(r.length)}`):null},extractExpressionBetweenDoubleCurlyBraces=e=>{if(e.startsWith(`{{`)&&e.endsWith(`}}`))return e.slice(2,-2)},evaluateJsonPath=(e,t)=>{try{if(!e.startsWith(`$`))throw Error(`JSONPath expression must start with '$': ${e}`);if(e.includes(`$_`)||e.match(/\$[^.[]/g)||e.includes(`[`)&&!e.includes(`]`)||e.includes(` `)&&!e.includes(`[`))throw Error(`Invalid JSONPath expression: ${e}`);let n=(0,l.JSONPath)({path:e,json:t});return n.length===0?void 0:n.length===1?n[0]:n}catch{throw Error(`Invalid JSONPath expression: ${e}`)}},replaceInterpolation=(e,t,n)=>e.replace(t,String(n)),handleSingleInterpolation=(e,t,n,r)=>{let i=e.path.trim();if(!i)return r;try{let a=compileExpression(t,i);if(a){let t=a.evalSync(n);if(t!==void 0)return replaceInterpolation(r,e.toReplace,t)}let s=evaluateJsonPathIncremental(`$.${i}`,n).value;return(0,o.notMissing)(s)?replaceInterpolation(r,e.toReplace,s):r}catch{return r}},evaluateStringInterpolations=(e,t,n)=>{let r=e.match(D);if(!r)return;let i=r.length,a=Array(i);for(let e=0;e<i;e++)a[e]={toReplace:r[e],path:r[e].slice(2,-1)};return a.reduce((e,r)=>handleSingleInterpolation(r,n,t,e),String(e))},handleSegmentPathError=(e,t,n,r)=>{if(Array.isArray(t)){let e=parseInt(n,10);if(!isNaN(e)&&(e<0||e>=t.length))return{value:void 0,error:`Invalid array index '${n}' at '${r}'`,availableKeys:t.map((e,t)=>t.toString())}}return(0,o.isObject)(t)?{value:void 0,error:`Key '${n}' not found at '${r}'`,availableKeys:Object.keys(t)}:{value:void 0,error:`${e} at '${r}'`,availableKeys:[]}},handleJsonPathSegments=(e,t)=>{if(e[0]!==`$`)return{value:void 0,error:`JSON path must start with $`};let n=t,r=`$`;for(let t=1;t<e.length;t++){let i=e[t],a=i.startsWith(`[`)?`${r}${i}`:`${r}.${i}`;if(Array.isArray(n)){let e=parseInt(i,10);if(isNaN(e)||e<0||e>=n.length)return handleSegmentPathError(`Invalid array index`,n,i,r);n=n[e],r=a}else if((0,o.isObject)(n)){if(!Object.prototype.hasOwnProperty.call(n,i))return handleSegmentPathError(`Key not found`,n,i,r);n=n[i],r=a}else return{value:void 0,error:`Cannot access '${i}' at '${r}' - parent is not an object`,availableKeys:[]}}return{value:n}},evaluateJsonPathIncremental=(e,t)=>{let n=/(\.\.)|(\[\*\])|(\[\?\()|(\[\d+:\d+\])/;try{if(n.test(e)){let n=evaluateJsonPath(e,t);return n===void 0?{value:void 0,error:`Invalid or empty JSONPath: '${e}'`}:{value:n}}return handleJsonPathSegments((e.match(/\$|(?:\['([^']+)'\])|(?:\["([^"]+)"\])|\[\d+\]|[^[\].]+/g)||[]).map(e=>e.replace(/^\['([^']+)'\]$/,`$1`).replace(/^\["([^"]+)"\]$/,`$1`).replace(/^\[(\d+)\]$/,`$1`)),t)}catch(e){return{value:void 0,error:`Something went wrong with evaluation of JSON path: ${String(e)}`}}},handleIncrementalJsonPath=(e,t)=>{let n=evaluateJsonPathIncremental(e,t);if(n.error)throw Error(`${n.error}${n.availableKeys?.length?`. Available keys: ${n.availableKeys.join(`, `)}`:``}`);return n.value},handleNormalJsonPath=(e,t)=>{try{return evaluateJsonPath(e,t)}catch{throw Error(`Invalid JSON path: "${e}"`)}},evaluateExpression=(e,t,n)=>{let r=e?.trim();if(r==null||r===``)throw Error(`Empty expression`);let i=(0,o.isObject)(t)?t:{},a=createExpressionHandler();a.addTransform(`key`,e=>typeof e!=`string`||!Object.prototype.hasOwnProperty.call(i,e)?null:i[e]);let s=extractExpressionBetweenDoubleCurlyBraces(r),c=cleanExpression(s??r),l=evaluateStringInterpolations(c,i,a);if(l)return l;if(!s&&r.startsWith(`$`))return n?.incrementalJsonPath?handleIncrementalJsonPath(r,i):handleNormalJsonPath(r,i);if(!l&&!s)return e;let u=compileExpression(a,c);if(!u||c===`.`)throw Error(`Invalid expression: "${r}"`);try{return u.evalSync(i)}catch{return}},safeEvaluateExpression=(e,t)=>{try{return evaluateExpression(e,t)}catch{return null}},safeEvaluateRecord=(e,t)=>{let evaluateValue=e=>Array.isArray(e)?e.map(evaluateValue):typeof e==`object`&&e?safeEvaluateRecord(e,t):typeof e==`string`?safeEvaluateExpression(e,t):e;return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,evaluateValue(t)]))},isValidExpression=e=>{try{return evaluateExpression(e),!0}catch{return!1}};exports.evaluate=evaluateExpression,exports.isValidExpression=isValidExpression,exports.safeEvaluate=safeEvaluateExpression,exports.safeEvaluateRecord=safeEvaluateRecord;
1
+ var e=Object.create,t=Object.defineProperty,__name=(e,n)=>t(e,`name`,{value:n,configurable:!0}),n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,__copyProps=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},__toESM=(n,r,a)=>(a=n==null?{}:e(i(n)),__copyProps(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let o=require(`@stackone/utils`),s=require(`jexl`);s=__toESM(s);let c=require(`crypto`),l=require(`jsonpath-plus`);const u=`capitalize`,capitalize=(e,t=`first`)=>(0,o.isMissing)(e)||typeof e!=`string`?``:(t===`each`?`each`:`first`)==`each`?e.split(/(\s+)/).map(e=>e.trim()?e.charAt(0).toUpperCase()+e.slice(1):e).join(``):e.charAt(0).toUpperCase()+e.slice(1),d=`decodeBase64`,decodeBase64=(e,t=`base64url`)=>{if((0,o.isMissing)(e)||typeof e!=`string`)return``;try{return Buffer.from(e,t).toString(`utf-8`)}catch{return``}},f=`decodeUri`,decodeUri=e=>{if((0,o.isMissing)(e)||typeof e!=`string`)return``;try{return decodeURIComponent(e)}catch{return e}},p=`dedupe`,toCanonicalKey=e=>{if(e===null)return`null:null`;if(e===void 0)return`undefined:undefined`;if(typeof e!=`object`)return`${typeof e}:${String(e)}`;try{return`object:${stableStringify(e)}`}catch{return`unserializable:${Math.random()}`}},stableStringify=e=>typeof e!=`object`||!e?JSON.stringify(e):Array.isArray(e)?`[${e.map(stableStringify).join(`,`)}]`:`{${Object.keys(e).sort().map(t=>{let n=e[t];return`${JSON.stringify(t)}:${stableStringify(n)}`}).join(`,`)}}`,dedupe=e=>{if((0,o.isMissing)(e)||!Array.isArray(e))return[];let t=new Set,n=[];for(let r of e){let e=toCanonicalKey(r);t.has(e)||(t.add(e),n.push(r))}return n},m=`encodeBase64`,encodeBase64=(e,t=`base64url`)=>{if((0,o.isMissing)(e)||typeof e!=`string`)return``;try{return Buffer.from(e).toString(t)}catch{return``}},h=`groupBy`,groupBy=(e,t)=>{if((0,o.isMissing)(e)||!Array.isArray(e)||(0,o.isMissing)(t)||typeof t!=`string`)return{};let n=Object.create(null);for(let r of e){if((0,o.isMissing)(r)||typeof r!=`object`||Array.isArray(r))continue;let e=r[t],i=(0,o.isMissing)(e)?`__missing__`:String(e);Object.prototype.hasOwnProperty.call(n,i)||(n[i]=[]),n[i].push(r)}return n},g=`hmacSha256`,hmacSha256=(e,t,n=`hex`)=>{if(e==null||typeof e!=`string`||t==null||typeof t!=`string`)return``;let r=n===`base64`?`base64`:`hex`;try{return(0,c.createHmac)(`sha256`,t).update(e).digest(r)}catch{return``}},_=`join`,join=(e,t=`,`)=>{if(!(0,o.notMissing)(e)||!Array.isArray(e)||e.length===0)return``;let n=typeof t==`string`?t:`,`;return e.filter(e=>(0,o.notMissing)(e)).map(e=>String(e)).join(n)},v=`md5`,md5=(e,t=`hex`)=>{if(e==null||typeof e!=`string`)return``;let n=t===`base64`?`base64`:`hex`;try{return(0,c.createHash)(`md5`).update(e).digest(n)}catch{return``}},y=`min`,min=(...e)=>{let t=e.length===1&&Array.isArray(e[0])?e[0]:e,n=[];for(let e of t)if(!(0,o.isMissing)(e)){if(typeof e==`number`&&!Number.isNaN(e))n.push(e);else if(typeof e==`string`){let t=Number(e);Number.isNaN(t)||n.push(t)}}return n.length===0?null:Math.min(...n)},b=`padStart`,padStart=(e,t,n=` `)=>{if(e==null)return``;let r=String(e);if((0,o.isMissing)(t)||typeof t!=`number`||t<0)return r;let i=typeof n==`string`?n:` `;return r.padStart(t,i)},x=`reduce`,S=[`sum`,`avg`,`count`,`min`,`max`,`concat`,`flatten`],reduce=(e,t,n)=>{if((0,o.isMissing)(e)||!Array.isArray(e)||(0,o.isMissing)(t)||typeof t!=`string`)return null;let r=t;if(!S.includes(r))return null;if(r===`count`)return e.length;let i=extractValues(e,n);switch(r){case`sum`:return numericReduce(i,e=>e.reduce((e,t)=>e+t,0));case`avg`:return numericReduce(i,e=>e.length>0?e.reduce((e,t)=>e+t,0)/e.length:null);case`min`:return numericReduce(i,e=>e.length>0?Math.min(...e):null);case`max`:return numericReduce(i,e=>e.length>0?Math.max(...e):null);case`concat`:case`flatten`:return i.reduce((e,t)=>Array.isArray(t)?e.concat(t):(e.push(t),e),[]);default:return null}},extractValues=(e,t)=>(0,o.isMissing)(t)||typeof t!=`string`?e:e.filter(e=>!(0,o.isMissing)(e)&&typeof e==`object`&&!Array.isArray(e)).map(e=>e[t]),numericReduce=(e,t)=>t(e.filter(e=>typeof e==`number`&&!Number.isNaN(e))),C=`regexMatch`,regexMatch=(e,t,n=1)=>{if((0,o.isMissing)(e)||typeof e!=`string`||(0,o.isMissing)(t)||typeof t!=`string`||t.length===0)return null;let r=typeof n==`number`?n:1;if(r<0)return null;try{let n=new RegExp(t),i=e.match(n);if(!i)return null;let a=i[r];return a===void 0?null:a}catch{return null}},w=`replace`,replace=(e,t,n,r=!1)=>{if((0,o.isMissing)(e)||typeof e!=`string`)return``;if(typeof t!=`string`)return e;let i=typeof n==`string`?n:``;return r===!0?e.replaceAll(t,i):e.replace(t,i)},T=`sha256`,sha256=(e,t=`hex`)=>{if(e==null||typeof e!=`string`)return``;let n=t===`base64`?`base64`:`hex`;try{return(0,c.createHash)(`sha256`).update(e).digest(n)}catch{return``}},E=`truncate`,truncate=(e,t,n=`...`)=>{if((0,o.isMissing)(e)||typeof e!=`string`)return``;if((0,o.isMissing)(t)||typeof t!=`number`||t<0)return e;let r=typeof n==`string`?n:`...`;if(e.length<=t)return e;let i=Math.max(0,t-r.length);return i<=0?e.slice(0,t):e.slice(0,i)+r},D=`urlParam`,urlParam=(e,t)=>{if((0,o.isMissing)(e)||typeof e!=`string`||(0,o.isMissing)(t)||typeof t!=`string`)return null;try{return new URL(e).searchParams.get(t)}catch{return null}},O=`zipObject`,zipObject=(e,t)=>{if((0,o.isMissing)(e)||!Array.isArray(e)||(0,o.isMissing)(t)||!Array.isArray(t))return{};let n=Math.min(e.length,t.length),r=[];for(let i=0;i<n;i++){let n=e[i];typeof n==`string`&&r.push([n,t[i]])}return Object.fromEntries(r)},createExpressionHandler=(e=()=>new s.Jexl)=>{let t=e();return t.addFunction(`nextAnniversary`,(e,t)=>(0,o.calculateNextAnniversary)({initialDate:e,format:t})),t.addFunction(`yearsElapsed`,(e,t,n)=>(0,o.calculateYearsElapsed)({startDate:e,endDate:n,format:t})),t.addFunction(`hasPassed`,(e,t,n)=>(0,o.dateHasPassed)({date:e,yearsToAdd:n,format:t})),t.addFunction(`now`,()=>new Date().toISOString()),t.addFunction(`includes`,(e,t)=>(0,o.isMissing)(e)||!Array.isArray(e)||e.length===0||(0,o.isMissing)(t)?!1:Array.isArray(t)?t.every(t=>e.includes(t)):e.includes(t)),t.addFunction(`includesSome`,(e,t)=>(0,o.isMissing)(e)||!Array.isArray(e)||e.length===0||(0,o.isMissing)(t)?!1:Array.isArray(t)?t.some(t=>e.includes(t)):e.includes(t)),t.addFunction(`present`,e=>(0,o.notMissing)(e)),t.addFunction(`missing`,e=>(0,o.isMissing)(e)),t.addFunction(`keys`,e=>(0,o.isMissing)(e)?[]:typeof e==`object`&&!Array.isArray(e)?Object.keys(e):[]),t.addFunction(`values`,e=>(0,o.isMissing)(e)?[]:typeof e==`object`&&!Array.isArray(e)?Object.values(e):[]),t.addFunction(`deltaFromNowMs`,(e,t)=>{let n=Date.now(),r;if(typeof e==`number`)r=t===`seconds`?e*1e3:e;else if(typeof e==`string`)r=t===`timestamp`?parseInt(e,10):t===`seconds`?parseFloat(e)*1e3:new Date(e).getTime();else throw Error(`Unsupported date input type`);return r-n}),t.addBinaryOp(`??`,0,(e,t)=>(0,o.isMissing)(e)?t:(0,o.isMissing)(t)?e:e??t),t.addFunction(`capitalize`,capitalize),t.addFunction(`decodeBase64`,decodeBase64),t.addFunction(`encodeBase64`,encodeBase64),t.addFunction(`hmacSha256`,hmacSha256),t.addFunction(`md5`,md5),t.addFunction(`sha256`,sha256),t.addFunction(`decodeUri`,decodeUri),t.addFunction(`dedupe`,dedupe),t.addFunction(`groupBy`,groupBy),t.addFunction(`join`,join),t.addFunction(`min`,min),t.addFunction(`padStart`,padStart),t.addFunction(`zipObject`,zipObject),t.addFunction(`reduce`,reduce),t.addFunction(`regexMatch`,regexMatch),t.addFunction(`replace`,replace),t.addFunction(`truncate`,truncate),t.addFunction(`urlParam`,urlParam),t},k=/\${([^}]+)}/g,cleanExpression=e=>e.replace(/\$\./g,``).trim(),extractLeadingFunctionCall=e=>{let t=e.match(/^\w+\(/);if(!t)return null;let n=0;for(let r=t[0].length-1;r<e.length;r++)if(e[r]===`(`?n++:e[r]===`)`&&n--,n===0)return e.slice(r+1).trimStart().startsWith(`?`)?e.slice(0,r+1):null;return null},tryCompile=(e,t)=>{try{return e.compile(t)}catch{return null}},compileExpression=(e,t)=>{let n=tryCompile(e,t);if(n)return n;let r=extractLeadingFunctionCall(t);return r?tryCompile(e,`(${r})${t.slice(r.length)}`):null},extractExpressionBetweenDoubleCurlyBraces=e=>{if(e.startsWith(`{{`)&&e.endsWith(`}}`))return e.slice(2,-2)},evaluateJsonPath=(e,t)=>{try{if(!e.startsWith(`$`))throw Error(`JSONPath expression must start with '$': ${e}`);if(e.includes(`$_`)||e.match(/\$[^.[]/g)||e.includes(`[`)&&!e.includes(`]`)||e.includes(` `)&&!e.includes(`[`))throw Error(`Invalid JSONPath expression: ${e}`);let n=(0,l.JSONPath)({path:e,json:t});return n.length===0?void 0:n.length===1?n[0]:n}catch{throw Error(`Invalid JSONPath expression: ${e}`)}},replaceInterpolation=(e,t,n)=>e.replace(t,String(n)),handleSingleInterpolation=(e,t,n,r)=>{let i=e.path.trim();if(!i)return r;try{let a=compileExpression(t,i);if(a){let t=a.evalSync(n);if(t!==void 0)return replaceInterpolation(r,e.toReplace,t)}let s=evaluateJsonPathIncremental(`$.${i}`,n).value;return(0,o.notMissing)(s)?replaceInterpolation(r,e.toReplace,s):r}catch{return r}},evaluateStringInterpolations=(e,t,n)=>{let r=e.match(k);if(!r)return;let i=r.length,a=Array(i);for(let e=0;e<i;e++)a[e]={toReplace:r[e],path:r[e].slice(2,-1)};return a.reduce((e,r)=>handleSingleInterpolation(r,n,t,e),String(e))},handleSegmentPathError=(e,t,n,r)=>{if(Array.isArray(t)){let e=parseInt(n,10);if(!isNaN(e)&&(e<0||e>=t.length))return{value:void 0,error:`Invalid array index '${n}' at '${r}'`,availableKeys:t.map((e,t)=>t.toString())}}return(0,o.isObject)(t)?{value:void 0,error:`Key '${n}' not found at '${r}'`,availableKeys:Object.keys(t)}:{value:void 0,error:`${e} at '${r}'`,availableKeys:[]}},handleJsonPathSegments=(e,t)=>{if(e[0]!==`$`)return{value:void 0,error:`JSON path must start with $`};let n=t,r=`$`;for(let t=1;t<e.length;t++){let i=e[t],a=i.startsWith(`[`)?`${r}${i}`:`${r}.${i}`;if(Array.isArray(n)){let e=parseInt(i,10);if(isNaN(e)||e<0||e>=n.length)return handleSegmentPathError(`Invalid array index`,n,i,r);n=n[e],r=a}else if((0,o.isObject)(n)){if(!Object.prototype.hasOwnProperty.call(n,i))return handleSegmentPathError(`Key not found`,n,i,r);n=n[i],r=a}else return{value:void 0,error:`Cannot access '${i}' at '${r}' - parent is not an object`,availableKeys:[]}}return{value:n}},evaluateJsonPathIncremental=(e,t)=>{let n=/(\.\.)|(\[\*\])|(\[\?\()|(\[\d+:\d+\])/;try{if(n.test(e)){let n=evaluateJsonPath(e,t);return n===void 0?{value:void 0,error:`Invalid or empty JSONPath: '${e}'`}:{value:n}}return handleJsonPathSegments((e.match(/\$|(?:\['([^']+)'\])|(?:\["([^"]+)"\])|\[\d+\]|[^[\].]+/g)||[]).map(e=>e.replace(/^\['([^']+)'\]$/,`$1`).replace(/^\["([^"]+)"\]$/,`$1`).replace(/^\[(\d+)\]$/,`$1`)),t)}catch(e){return{value:void 0,error:`Something went wrong with evaluation of JSON path: ${String(e)}`}}},handleIncrementalJsonPath=(e,t)=>{let n=evaluateJsonPathIncremental(e,t);if(n.error)throw Error(`${n.error}${n.availableKeys?.length?`. Available keys: ${n.availableKeys.join(`, `)}`:``}`);return n.value},handleNormalJsonPath=(e,t)=>{try{return evaluateJsonPath(e,t)}catch{throw Error(`Invalid JSON path: "${e}"`)}},evaluateExpression=(e,t,n)=>{let r=e?.trim();if(r==null||r===``)throw Error(`Empty expression`);let i=(0,o.isObject)(t)?t:{},a=createExpressionHandler();a.addTransform(`key`,e=>typeof e!=`string`||!Object.prototype.hasOwnProperty.call(i,e)?null:i[e]);let s=extractExpressionBetweenDoubleCurlyBraces(r),c=cleanExpression(s??r),l=evaluateStringInterpolations(c,i,a);if(l)return l;if(!s&&r.startsWith(`$`))return n?.incrementalJsonPath?handleIncrementalJsonPath(r,i):handleNormalJsonPath(r,i);if(!l&&!s)return e;let u=compileExpression(a,c);if(!u||c===`.`)throw Error(`Invalid expression: "${r}"`);try{return u.evalSync(i)}catch{return}},safeEvaluateExpression=(e,t)=>{try{return evaluateExpression(e,t)}catch{return null}},safeEvaluateRecord=(e,t)=>{let evaluateValue=e=>Array.isArray(e)?e.map(evaluateValue):typeof e==`object`&&e?safeEvaluateRecord(e,t):typeof e==`string`?safeEvaluateExpression(e,t):e;return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,evaluateValue(t)]))},isValidExpression=e=>{try{return evaluateExpression(e),!0}catch{return!1}};exports.evaluate=evaluateExpression,exports.isValidExpression=isValidExpression,exports.safeEvaluate=safeEvaluateExpression,exports.safeEvaluateRecord=safeEvaluateRecord;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{t as e}from"./chunk-Cfxk5zVN.mjs";import{calculateNextAnniversary as t,calculateYearsElapsed as n,dateHasPassed as r,decodeFromBase64 as i,encodeToBase64 as a,isMissing as o,isObject as s,notMissing as c}from"@stackone/utils";import*as l from"jexl";import{createHash as u,createHmac as d}from"crypto";import{JSONPath as f}from"jsonpath-plus";const capitalize=(e,t=`first`)=>o(e)||typeof e!=`string`?``:(t===`each`?`each`:`first`)==`each`?e.split(/(\s+)/).map(e=>e.trim()?e.charAt(0).toUpperCase()+e.slice(1):e).join(``):e.charAt(0).toUpperCase()+e.slice(1),decodeUri=e=>{if(o(e)||typeof e!=`string`)return``;try{return decodeURIComponent(e)}catch{return e}},toCanonicalKey=e=>{if(e===null)return`null:null`;if(e===void 0)return`undefined:undefined`;if(typeof e!=`object`)return`${typeof e}:${String(e)}`;try{return`object:${stableStringify(e)}`}catch{return`unserializable:${Math.random()}`}},stableStringify=e=>typeof e!=`object`||!e?JSON.stringify(e):Array.isArray(e)?`[${e.map(stableStringify).join(`,`)}]`:`{${Object.keys(e).sort().map(t=>{let n=e[t];return`${JSON.stringify(t)}:${stableStringify(n)}`}).join(`,`)}}`,dedupe=e=>{if(o(e)||!Array.isArray(e))return[];let t=new Set,n=[];for(let r of e){let e=toCanonicalKey(r);t.has(e)||(t.add(e),n.push(r))}return n},groupBy=(e,t)=>{if(o(e)||!Array.isArray(e)||o(t)||typeof t!=`string`)return{};let n=Object.create(null);for(let r of e){if(o(r)||typeof r!=`object`||Array.isArray(r))continue;let e=r[t],i=o(e)?`__missing__`:String(e);Object.prototype.hasOwnProperty.call(n,i)||(n[i]=[]),n[i].push(r)}return n},hmacSha256=(e,t,n=`hex`)=>{if(e==null||typeof e!=`string`||t==null||typeof t!=`string`)return``;let r=n===`base64`?`base64`:`hex`;try{return d(`sha256`,t).update(e).digest(r)}catch{return``}},join=(e,t=`,`)=>{if(!c(e)||!Array.isArray(e)||e.length===0)return``;let n=typeof t==`string`?t:`,`;return e.filter(e=>c(e)).map(e=>String(e)).join(n)},md5=(e,t=`hex`)=>{if(e==null||typeof e!=`string`)return``;let n=t===`base64`?`base64`:`hex`;try{return u(`md5`).update(e).digest(n)}catch{return``}},min=(...e)=>{let t=e.length===1&&Array.isArray(e[0])?e[0]:e,n=[];for(let e of t)if(!o(e)){if(typeof e==`number`&&!Number.isNaN(e))n.push(e);else if(typeof e==`string`){let t=Number(e);Number.isNaN(t)||n.push(t)}}return n.length===0?null:Math.min(...n)},padStart=(e,t,n=` `)=>{if(e==null)return``;let r=String(e);if(o(t)||typeof t!=`number`||t<0)return r;let i=typeof n==`string`?n:` `;return r.padStart(t,i)},p=[`sum`,`avg`,`count`,`min`,`max`,`concat`,`flatten`],reduce=(e,t,n)=>{if(o(e)||!Array.isArray(e)||o(t)||typeof t!=`string`)return null;let r=t;if(!p.includes(r))return null;if(r===`count`)return e.length;let i=extractValues(e,n);switch(r){case`sum`:return numericReduce(i,e=>e.reduce((e,t)=>e+t,0));case`avg`:return numericReduce(i,e=>e.length>0?e.reduce((e,t)=>e+t,0)/e.length:null);case`min`:return numericReduce(i,e=>e.length>0?Math.min(...e):null);case`max`:return numericReduce(i,e=>e.length>0?Math.max(...e):null);case`concat`:case`flatten`:return i.reduce((e,t)=>Array.isArray(t)?e.concat(t):(e.push(t),e),[]);default:return null}},extractValues=(e,t)=>o(t)||typeof t!=`string`?e:e.filter(e=>!o(e)&&typeof e==`object`&&!Array.isArray(e)).map(e=>e[t]),numericReduce=(e,t)=>t(e.filter(e=>typeof e==`number`&&!Number.isNaN(e))),regexMatch=(e,t,n=1)=>{if(o(e)||typeof e!=`string`||o(t)||typeof t!=`string`||t.length===0)return null;let r=typeof n==`number`?n:1;if(r<0)return null;try{let n=new RegExp(t),i=e.match(n);if(!i)return null;let a=i[r];return a===void 0?null:a}catch{return null}},replace=(e,t,n,r=!1)=>{if(o(e)||typeof e!=`string`)return``;if(typeof t!=`string`)return e;let i=typeof n==`string`?n:``;return r===!0?e.replaceAll(t,i):e.replace(t,i)},sha256=(e,t=`hex`)=>{if(e==null||typeof e!=`string`)return``;let n=t===`base64`?`base64`:`hex`;try{return u(`sha256`).update(e).digest(n)}catch{return``}},truncate=(e,t,n=`...`)=>{if(o(e)||typeof e!=`string`)return``;if(o(t)||typeof t!=`number`||t<0)return e;let r=typeof n==`string`?n:`...`;if(e.length<=t)return e;let i=Math.max(0,t-r.length);return i<=0?e.slice(0,t):e.slice(0,i)+r},urlParam=(e,t)=>{if(o(e)||typeof e!=`string`||o(t)||typeof t!=`string`)return null;try{return new URL(e).searchParams.get(t)}catch{return null}},zipObject=(e,t)=>{if(o(e)||!Array.isArray(e)||o(t)||!Array.isArray(t))return{};let n=Math.min(e.length,t.length),r=[];for(let i=0;i<n;i++){let n=e[i];typeof n==`string`&&r.push([n,t[i]])}return Object.fromEntries(r)},createExpressionHandler=(e=()=>new l.Jexl)=>{let s=e();return s.addFunction(`nextAnniversary`,(e,n)=>t({initialDate:e,format:n})),s.addFunction(`yearsElapsed`,(e,t,r)=>n({startDate:e,endDate:r,format:t})),s.addFunction(`hasPassed`,(e,t,n)=>r({date:e,yearsToAdd:n,format:t})),s.addFunction(`now`,()=>new Date().toISOString()),s.addFunction(`includes`,(e,t)=>o(e)||!Array.isArray(e)||e.length===0||o(t)?!1:Array.isArray(t)?t.every(t=>e.includes(t)):e.includes(t)),s.addFunction(`includesSome`,(e,t)=>o(e)||!Array.isArray(e)||e.length===0||o(t)?!1:Array.isArray(t)?t.some(t=>e.includes(t)):e.includes(t)),s.addFunction(`present`,e=>c(e)),s.addFunction(`missing`,e=>o(e)),s.addFunction(`keys`,e=>o(e)?[]:typeof e==`object`&&!Array.isArray(e)?Object.keys(e):[]),s.addFunction(`values`,e=>o(e)?[]:typeof e==`object`&&!Array.isArray(e)?Object.values(e):[]),s.addFunction(`decodeBase64`,e=>{if(o(e)||typeof e!=`string`)return``;try{return i(e)}catch{return``}}),s.addFunction(`encodeBase64`,e=>{if(o(e)||typeof e!=`string`)return``;try{return a(e)}catch{return``}}),s.addFunction(`deltaFromNowMs`,(e,t)=>{let n=Date.now(),r;if(typeof e==`number`)r=t===`seconds`?e*1e3:e;else if(typeof e==`string`)r=t===`timestamp`?parseInt(e,10):t===`seconds`?parseFloat(e)*1e3:new Date(e).getTime();else throw Error(`Unsupported date input type`);return r-n}),s.addBinaryOp(`??`,0,(e,t)=>o(e)?t:o(t)?e:e??t),s.addFunction(`capitalize`,capitalize),s.addFunction(`hmacSha256`,hmacSha256),s.addFunction(`md5`,md5),s.addFunction(`sha256`,sha256),s.addFunction(`decodeUri`,decodeUri),s.addFunction(`dedupe`,dedupe),s.addFunction(`groupBy`,groupBy),s.addFunction(`join`,join),s.addFunction(`min`,min),s.addFunction(`padStart`,padStart),s.addFunction(`zipObject`,zipObject),s.addFunction(`reduce`,reduce),s.addFunction(`regexMatch`,regexMatch),s.addFunction(`replace`,replace),s.addFunction(`truncate`,truncate),s.addFunction(`urlParam`,urlParam),s},m=/\${([^}]+)}/g,cleanExpression=e=>e.replace(/\$\./g,``).trim(),extractLeadingFunctionCall=e=>{let t=e.match(/^\w+\(/);if(!t)return null;let n=0;for(let r=t[0].length-1;r<e.length;r++)if(e[r]===`(`?n++:e[r]===`)`&&n--,n===0)return e.slice(r+1).trimStart().startsWith(`?`)?e.slice(0,r+1):null;return null},tryCompile=(e,t)=>{try{return e.compile(t)}catch{return null}},compileExpression=(e,t)=>{let n=tryCompile(e,t);if(n)return n;let r=extractLeadingFunctionCall(t);return r?tryCompile(e,`(${r})${t.slice(r.length)}`):null},extractExpressionBetweenDoubleCurlyBraces=e=>{if(e.startsWith(`{{`)&&e.endsWith(`}}`))return e.slice(2,-2)},evaluateJsonPath=(e,t)=>{try{if(!e.startsWith(`$`))throw Error(`JSONPath expression must start with '$': ${e}`);if(e.includes(`$_`)||e.match(/\$[^.[]/g)||e.includes(`[`)&&!e.includes(`]`)||e.includes(` `)&&!e.includes(`[`))throw Error(`Invalid JSONPath expression: ${e}`);let n=f({path:e,json:t});return n.length===0?void 0:n.length===1?n[0]:n}catch{throw Error(`Invalid JSONPath expression: ${e}`)}},replaceInterpolation=(e,t,n)=>e.replace(t,String(n)),handleSingleInterpolation=(e,t,n,r)=>{let i=e.path.trim();if(!i)return r;try{let a=compileExpression(t,i);if(a){let t=a.evalSync(n);if(t!==void 0)return replaceInterpolation(r,e.toReplace,t)}let o=evaluateJsonPathIncremental(`$.${i}`,n).value;return c(o)?replaceInterpolation(r,e.toReplace,o):r}catch{return r}},evaluateStringInterpolations=(e,t,n)=>{let r=e.match(m);if(!r)return;let i=r.length,a=Array(i);for(let e=0;e<i;e++)a[e]={toReplace:r[e],path:r[e].slice(2,-1)};return a.reduce((e,r)=>handleSingleInterpolation(r,n,t,e),String(e))},handleSegmentPathError=(e,t,n,r)=>{if(Array.isArray(t)){let e=parseInt(n,10);if(!isNaN(e)&&(e<0||e>=t.length))return{value:void 0,error:`Invalid array index '${n}' at '${r}'`,availableKeys:t.map((e,t)=>t.toString())}}return s(t)?{value:void 0,error:`Key '${n}' not found at '${r}'`,availableKeys:Object.keys(t)}:{value:void 0,error:`${e} at '${r}'`,availableKeys:[]}},handleJsonPathSegments=(e,t)=>{if(e[0]!==`$`)return{value:void 0,error:`JSON path must start with $`};let n=t,r=`$`;for(let t=1;t<e.length;t++){let i=e[t],a=i.startsWith(`[`)?`${r}${i}`:`${r}.${i}`;if(Array.isArray(n)){let e=parseInt(i,10);if(isNaN(e)||e<0||e>=n.length)return handleSegmentPathError(`Invalid array index`,n,i,r);n=n[e],r=a}else if(s(n)){if(!Object.prototype.hasOwnProperty.call(n,i))return handleSegmentPathError(`Key not found`,n,i,r);n=n[i],r=a}else return{value:void 0,error:`Cannot access '${i}' at '${r}' - parent is not an object`,availableKeys:[]}}return{value:n}},evaluateJsonPathIncremental=(e,t)=>{let n=/(\.\.)|(\[\*\])|(\[\?\()|(\[\d+:\d+\])/;try{if(n.test(e)){let n=evaluateJsonPath(e,t);return n===void 0?{value:void 0,error:`Invalid or empty JSONPath: '${e}'`}:{value:n}}return handleJsonPathSegments((e.match(/\$|(?:\['([^']+)'\])|(?:\["([^"]+)"\])|\[\d+\]|[^[\].]+/g)||[]).map(e=>e.replace(/^\['([^']+)'\]$/,`$1`).replace(/^\["([^"]+)"\]$/,`$1`).replace(/^\[(\d+)\]$/,`$1`)),t)}catch(e){return{value:void 0,error:`Something went wrong with evaluation of JSON path: ${String(e)}`}}},handleIncrementalJsonPath=(e,t)=>{let n=evaluateJsonPathIncremental(e,t);if(n.error)throw Error(`${n.error}${n.availableKeys?.length?`. Available keys: ${n.availableKeys.join(`, `)}`:``}`);return n.value},handleNormalJsonPath=(e,t)=>{try{return evaluateJsonPath(e,t)}catch{throw Error(`Invalid JSON path: "${e}"`)}},evaluateExpression=(e,t,n)=>{let r=e?.trim();if(r==null||r===``)throw Error(`Empty expression`);let i=s(t)?t:{},a=createExpressionHandler();a.addTransform(`key`,e=>typeof e!=`string`||!Object.prototype.hasOwnProperty.call(i,e)?null:i[e]);let o=extractExpressionBetweenDoubleCurlyBraces(r),c=cleanExpression(o??r),l=evaluateStringInterpolations(c,i,a);if(l)return l;if(!o&&r.startsWith(`$`))return n?.incrementalJsonPath?handleIncrementalJsonPath(r,i):handleNormalJsonPath(r,i);if(!l&&!o)return e;let u=compileExpression(a,c);if(!u||c===`.`)throw Error(`Invalid expression: "${r}"`);try{return u.evalSync(i)}catch{return}},safeEvaluateExpression=(e,t)=>{try{return evaluateExpression(e,t)}catch{return null}},safeEvaluateRecord=(e,t)=>{let evaluateValue=e=>Array.isArray(e)?e.map(evaluateValue):typeof e==`object`&&e?safeEvaluateRecord(e,t):typeof e==`string`?safeEvaluateExpression(e,t):e;return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,evaluateValue(t)]))},isValidExpression=e=>{try{return evaluateExpression(e),!0}catch{return!1}};export{evaluateExpression as evaluate,isValidExpression,safeEvaluateExpression as safeEvaluate,safeEvaluateRecord};
1
+ import{t as e}from"./chunk-Cfxk5zVN.mjs";import{calculateNextAnniversary as t,calculateYearsElapsed as n,dateHasPassed as r,isMissing as i,isObject as a,notMissing as o}from"@stackone/utils";import*as s from"jexl";import{createHash as c,createHmac as l}from"crypto";import{JSONPath as u}from"jsonpath-plus";const capitalize=(e,t=`first`)=>i(e)||typeof e!=`string`?``:(t===`each`?`each`:`first`)==`each`?e.split(/(\s+)/).map(e=>e.trim()?e.charAt(0).toUpperCase()+e.slice(1):e).join(``):e.charAt(0).toUpperCase()+e.slice(1),decodeBase64=(e,t=`base64url`)=>{if(i(e)||typeof e!=`string`)return``;try{return Buffer.from(e,t).toString(`utf-8`)}catch{return``}},decodeUri=e=>{if(i(e)||typeof e!=`string`)return``;try{return decodeURIComponent(e)}catch{return e}},toCanonicalKey=e=>{if(e===null)return`null:null`;if(e===void 0)return`undefined:undefined`;if(typeof e!=`object`)return`${typeof e}:${String(e)}`;try{return`object:${stableStringify(e)}`}catch{return`unserializable:${Math.random()}`}},stableStringify=e=>typeof e!=`object`||!e?JSON.stringify(e):Array.isArray(e)?`[${e.map(stableStringify).join(`,`)}]`:`{${Object.keys(e).sort().map(t=>{let n=e[t];return`${JSON.stringify(t)}:${stableStringify(n)}`}).join(`,`)}}`,dedupe=e=>{if(i(e)||!Array.isArray(e))return[];let t=new Set,n=[];for(let r of e){let e=toCanonicalKey(r);t.has(e)||(t.add(e),n.push(r))}return n},encodeBase64=(e,t=`base64url`)=>{if(i(e)||typeof e!=`string`)return``;try{return Buffer.from(e).toString(t)}catch{return``}},groupBy=(e,t)=>{if(i(e)||!Array.isArray(e)||i(t)||typeof t!=`string`)return{};let n=Object.create(null);for(let r of e){if(i(r)||typeof r!=`object`||Array.isArray(r))continue;let e=r[t],a=i(e)?`__missing__`:String(e);Object.prototype.hasOwnProperty.call(n,a)||(n[a]=[]),n[a].push(r)}return n},hmacSha256=(e,t,n=`hex`)=>{if(e==null||typeof e!=`string`||t==null||typeof t!=`string`)return``;let r=n===`base64`?`base64`:`hex`;try{return l(`sha256`,t).update(e).digest(r)}catch{return``}},join=(e,t=`,`)=>{if(!o(e)||!Array.isArray(e)||e.length===0)return``;let n=typeof t==`string`?t:`,`;return e.filter(e=>o(e)).map(e=>String(e)).join(n)},md5=(e,t=`hex`)=>{if(e==null||typeof e!=`string`)return``;let n=t===`base64`?`base64`:`hex`;try{return c(`md5`).update(e).digest(n)}catch{return``}},min=(...e)=>{let t=e.length===1&&Array.isArray(e[0])?e[0]:e,n=[];for(let e of t)if(!i(e)){if(typeof e==`number`&&!Number.isNaN(e))n.push(e);else if(typeof e==`string`){let t=Number(e);Number.isNaN(t)||n.push(t)}}return n.length===0?null:Math.min(...n)},padStart=(e,t,n=` `)=>{if(e==null)return``;let r=String(e);if(i(t)||typeof t!=`number`||t<0)return r;let a=typeof n==`string`?n:` `;return r.padStart(t,a)},d=[`sum`,`avg`,`count`,`min`,`max`,`concat`,`flatten`],reduce=(e,t,n)=>{if(i(e)||!Array.isArray(e)||i(t)||typeof t!=`string`)return null;let r=t;if(!d.includes(r))return null;if(r===`count`)return e.length;let a=extractValues(e,n);switch(r){case`sum`:return numericReduce(a,e=>e.reduce((e,t)=>e+t,0));case`avg`:return numericReduce(a,e=>e.length>0?e.reduce((e,t)=>e+t,0)/e.length:null);case`min`:return numericReduce(a,e=>e.length>0?Math.min(...e):null);case`max`:return numericReduce(a,e=>e.length>0?Math.max(...e):null);case`concat`:case`flatten`:return a.reduce((e,t)=>Array.isArray(t)?e.concat(t):(e.push(t),e),[]);default:return null}},extractValues=(e,t)=>i(t)||typeof t!=`string`?e:e.filter(e=>!i(e)&&typeof e==`object`&&!Array.isArray(e)).map(e=>e[t]),numericReduce=(e,t)=>t(e.filter(e=>typeof e==`number`&&!Number.isNaN(e))),regexMatch=(e,t,n=1)=>{if(i(e)||typeof e!=`string`||i(t)||typeof t!=`string`||t.length===0)return null;let r=typeof n==`number`?n:1;if(r<0)return null;try{let n=new RegExp(t),i=e.match(n);if(!i)return null;let a=i[r];return a===void 0?null:a}catch{return null}},replace=(e,t,n,r=!1)=>{if(i(e)||typeof e!=`string`)return``;if(typeof t!=`string`)return e;let a=typeof n==`string`?n:``;return r===!0?e.replaceAll(t,a):e.replace(t,a)},sha256=(e,t=`hex`)=>{if(e==null||typeof e!=`string`)return``;let n=t===`base64`?`base64`:`hex`;try{return c(`sha256`).update(e).digest(n)}catch{return``}},truncate=(e,t,n=`...`)=>{if(i(e)||typeof e!=`string`)return``;if(i(t)||typeof t!=`number`||t<0)return e;let r=typeof n==`string`?n:`...`;if(e.length<=t)return e;let a=Math.max(0,t-r.length);return a<=0?e.slice(0,t):e.slice(0,a)+r},urlParam=(e,t)=>{if(i(e)||typeof e!=`string`||i(t)||typeof t!=`string`)return null;try{return new URL(e).searchParams.get(t)}catch{return null}},zipObject=(e,t)=>{if(i(e)||!Array.isArray(e)||i(t)||!Array.isArray(t))return{};let n=Math.min(e.length,t.length),r=[];for(let i=0;i<n;i++){let n=e[i];typeof n==`string`&&r.push([n,t[i]])}return Object.fromEntries(r)},createExpressionHandler=(e=()=>new s.Jexl)=>{let a=e();return a.addFunction(`nextAnniversary`,(e,n)=>t({initialDate:e,format:n})),a.addFunction(`yearsElapsed`,(e,t,r)=>n({startDate:e,endDate:r,format:t})),a.addFunction(`hasPassed`,(e,t,n)=>r({date:e,yearsToAdd:n,format:t})),a.addFunction(`now`,()=>new Date().toISOString()),a.addFunction(`includes`,(e,t)=>i(e)||!Array.isArray(e)||e.length===0||i(t)?!1:Array.isArray(t)?t.every(t=>e.includes(t)):e.includes(t)),a.addFunction(`includesSome`,(e,t)=>i(e)||!Array.isArray(e)||e.length===0||i(t)?!1:Array.isArray(t)?t.some(t=>e.includes(t)):e.includes(t)),a.addFunction(`present`,e=>o(e)),a.addFunction(`missing`,e=>i(e)),a.addFunction(`keys`,e=>i(e)?[]:typeof e==`object`&&!Array.isArray(e)?Object.keys(e):[]),a.addFunction(`values`,e=>i(e)?[]:typeof e==`object`&&!Array.isArray(e)?Object.values(e):[]),a.addFunction(`deltaFromNowMs`,(e,t)=>{let n=Date.now(),r;if(typeof e==`number`)r=t===`seconds`?e*1e3:e;else if(typeof e==`string`)r=t===`timestamp`?parseInt(e,10):t===`seconds`?parseFloat(e)*1e3:new Date(e).getTime();else throw Error(`Unsupported date input type`);return r-n}),a.addBinaryOp(`??`,0,(e,t)=>i(e)?t:i(t)?e:e??t),a.addFunction(`capitalize`,capitalize),a.addFunction(`decodeBase64`,decodeBase64),a.addFunction(`encodeBase64`,encodeBase64),a.addFunction(`hmacSha256`,hmacSha256),a.addFunction(`md5`,md5),a.addFunction(`sha256`,sha256),a.addFunction(`decodeUri`,decodeUri),a.addFunction(`dedupe`,dedupe),a.addFunction(`groupBy`,groupBy),a.addFunction(`join`,join),a.addFunction(`min`,min),a.addFunction(`padStart`,padStart),a.addFunction(`zipObject`,zipObject),a.addFunction(`reduce`,reduce),a.addFunction(`regexMatch`,regexMatch),a.addFunction(`replace`,replace),a.addFunction(`truncate`,truncate),a.addFunction(`urlParam`,urlParam),a},f=/\${([^}]+)}/g,cleanExpression=e=>e.replace(/\$\./g,``).trim(),extractLeadingFunctionCall=e=>{let t=e.match(/^\w+\(/);if(!t)return null;let n=0;for(let r=t[0].length-1;r<e.length;r++)if(e[r]===`(`?n++:e[r]===`)`&&n--,n===0)return e.slice(r+1).trimStart().startsWith(`?`)?e.slice(0,r+1):null;return null},tryCompile=(e,t)=>{try{return e.compile(t)}catch{return null}},compileExpression=(e,t)=>{let n=tryCompile(e,t);if(n)return n;let r=extractLeadingFunctionCall(t);return r?tryCompile(e,`(${r})${t.slice(r.length)}`):null},extractExpressionBetweenDoubleCurlyBraces=e=>{if(e.startsWith(`{{`)&&e.endsWith(`}}`))return e.slice(2,-2)},evaluateJsonPath=(e,t)=>{try{if(!e.startsWith(`$`))throw Error(`JSONPath expression must start with '$': ${e}`);if(e.includes(`$_`)||e.match(/\$[^.[]/g)||e.includes(`[`)&&!e.includes(`]`)||e.includes(` `)&&!e.includes(`[`))throw Error(`Invalid JSONPath expression: ${e}`);let n=u({path:e,json:t});return n.length===0?void 0:n.length===1?n[0]:n}catch{throw Error(`Invalid JSONPath expression: ${e}`)}},replaceInterpolation=(e,t,n)=>e.replace(t,String(n)),handleSingleInterpolation=(e,t,n,r)=>{let i=e.path.trim();if(!i)return r;try{let a=compileExpression(t,i);if(a){let t=a.evalSync(n);if(t!==void 0)return replaceInterpolation(r,e.toReplace,t)}let s=evaluateJsonPathIncremental(`$.${i}`,n).value;return o(s)?replaceInterpolation(r,e.toReplace,s):r}catch{return r}},evaluateStringInterpolations=(e,t,n)=>{let r=e.match(f);if(!r)return;let i=r.length,a=Array(i);for(let e=0;e<i;e++)a[e]={toReplace:r[e],path:r[e].slice(2,-1)};return a.reduce((e,r)=>handleSingleInterpolation(r,n,t,e),String(e))},handleSegmentPathError=(e,t,n,r)=>{if(Array.isArray(t)){let e=parseInt(n,10);if(!isNaN(e)&&(e<0||e>=t.length))return{value:void 0,error:`Invalid array index '${n}' at '${r}'`,availableKeys:t.map((e,t)=>t.toString())}}return a(t)?{value:void 0,error:`Key '${n}' not found at '${r}'`,availableKeys:Object.keys(t)}:{value:void 0,error:`${e} at '${r}'`,availableKeys:[]}},handleJsonPathSegments=(e,t)=>{if(e[0]!==`$`)return{value:void 0,error:`JSON path must start with $`};let n=t,r=`$`;for(let t=1;t<e.length;t++){let i=e[t],o=i.startsWith(`[`)?`${r}${i}`:`${r}.${i}`;if(Array.isArray(n)){let e=parseInt(i,10);if(isNaN(e)||e<0||e>=n.length)return handleSegmentPathError(`Invalid array index`,n,i,r);n=n[e],r=o}else if(a(n)){if(!Object.prototype.hasOwnProperty.call(n,i))return handleSegmentPathError(`Key not found`,n,i,r);n=n[i],r=o}else return{value:void 0,error:`Cannot access '${i}' at '${r}' - parent is not an object`,availableKeys:[]}}return{value:n}},evaluateJsonPathIncremental=(e,t)=>{let n=/(\.\.)|(\[\*\])|(\[\?\()|(\[\d+:\d+\])/;try{if(n.test(e)){let n=evaluateJsonPath(e,t);return n===void 0?{value:void 0,error:`Invalid or empty JSONPath: '${e}'`}:{value:n}}return handleJsonPathSegments((e.match(/\$|(?:\['([^']+)'\])|(?:\["([^"]+)"\])|\[\d+\]|[^[\].]+/g)||[]).map(e=>e.replace(/^\['([^']+)'\]$/,`$1`).replace(/^\["([^"]+)"\]$/,`$1`).replace(/^\[(\d+)\]$/,`$1`)),t)}catch(e){return{value:void 0,error:`Something went wrong with evaluation of JSON path: ${String(e)}`}}},handleIncrementalJsonPath=(e,t)=>{let n=evaluateJsonPathIncremental(e,t);if(n.error)throw Error(`${n.error}${n.availableKeys?.length?`. Available keys: ${n.availableKeys.join(`, `)}`:``}`);return n.value},handleNormalJsonPath=(e,t)=>{try{return evaluateJsonPath(e,t)}catch{throw Error(`Invalid JSON path: "${e}"`)}},evaluateExpression=(e,t,n)=>{let r=e?.trim();if(r==null||r===``)throw Error(`Empty expression`);let i=a(t)?t:{},o=createExpressionHandler();o.addTransform(`key`,e=>typeof e!=`string`||!Object.prototype.hasOwnProperty.call(i,e)?null:i[e]);let s=extractExpressionBetweenDoubleCurlyBraces(r),c=cleanExpression(s??r),l=evaluateStringInterpolations(c,i,o);if(l)return l;if(!s&&r.startsWith(`$`))return n?.incrementalJsonPath?handleIncrementalJsonPath(r,i):handleNormalJsonPath(r,i);if(!l&&!s)return e;let u=compileExpression(o,c);if(!u||c===`.`)throw Error(`Invalid expression: "${r}"`);try{return u.evalSync(i)}catch{return}},safeEvaluateExpression=(e,t)=>{try{return evaluateExpression(e,t)}catch{return null}},safeEvaluateRecord=(e,t)=>{let evaluateValue=e=>Array.isArray(e)?e.map(evaluateValue):typeof e==`object`&&e?safeEvaluateRecord(e,t):typeof e==`string`?safeEvaluateExpression(e,t):e;return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,evaluateValue(t)]))},isValidExpression=e=>{try{return evaluateExpression(e),!0}catch{return!1}};export{evaluateExpression as evaluate,isValidExpression,safeEvaluateExpression as safeEvaluate,safeEvaluateRecord};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackone/expressions",
3
- "version": "0.28.0",
3
+ "version": "0.29.0",
4
4
  "description": "",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",