@stackone/expressions 0.29.0 → 0.30.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/README.md CHANGED
@@ -537,6 +537,36 @@ Returns the smallest value from the provided numbers.
537
537
 
538
538
  ##### String Functions
539
539
 
540
+ ###### asString(value)
541
+
542
+ Converts a value to its string representation.
543
+
544
+ - `value` (any): The value to convert
545
+ - Returns: string representation of the value, or empty string for null/undefined
546
+
547
+ ```js
548
+ // Convert numbers
549
+ "{{asString(42)}}" // Returns "42"
550
+ "{{asString(3.14)}}" // Returns "3.14"
551
+
552
+ // Convert booleans
553
+ "{{asString(true)}}" // Returns "true"
554
+ "{{asString(false)}}" // Returns "false"
555
+
556
+ // Strings pass through unchanged
557
+ "{{asString('hello')}}" // Returns "hello"
558
+
559
+ // Arrays and objects are JSON-stringified
560
+ "{{asString([1, 2, 3])}}" // Returns "[1,2,3]"
561
+ "{{asString({a: 1})}}" // Returns '{"a":1}'
562
+
563
+ // Null/undefined returns empty string
564
+ "{{asString(null)}}" // Returns ""
565
+
566
+ // From context variable
567
+ "{{asString($.userId)}}"
568
+ ```
569
+
540
570
  ###### capitalize(value, mode?)
541
571
 
542
572
  Capitalizes characters in a string.
@@ -710,6 +740,34 @@ Replaces occurrences of a search string with a replacement string.
710
740
  "{{replace($.text, ' ', '-', true)}}";
711
741
  ```
712
742
 
743
+ ###### split(value, separator?)
744
+
745
+ Splits a string into an array of substrings using a specified separator.
746
+
747
+ - `value` (string): The string to split
748
+ - `separator` (string, optional): The string used to separate the value (default: ',')
749
+ - Returns: array of substrings, or empty array for non-string input
750
+
751
+ ```js
752
+ // Split with default comma separator
753
+ "{{split('a,b,c')}}"; // Returns ["a", "b", "c"]
754
+
755
+ // Split with custom separator
756
+ "{{split('a-b-c', '-')}}"; // Returns ["a", "b", "c"]
757
+ "{{split('hello world', ' ')}}"; // Returns ["hello", "world"]
758
+ "{{split('a|b|c', '|')}}"; // Returns ["a", "b", "c"]
759
+
760
+ // Split with multi-character separator
761
+ "{{split('a AND b AND c', ' AND ')}}"; // Returns ["a", "b", "c"]
762
+
763
+ // Split into characters with empty separator
764
+ "{{split('hello', '')}}"; // Returns ["h", "e", "l", "l", "o"]
765
+
766
+ // Split from context variable
767
+ "{{split($.tags, ',')}}";
768
+ "{{split(data.csv, ',')}}";
769
+ ```
770
+
713
771
  ###### regexMatch(value, pattern, groupIndex?)
714
772
 
715
773
  Extracts a value from a string using a regular expression pattern. Returns the specified capture group, or null if no match is found.
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=`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;
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=`asString`,asString=e=>(0,o.isMissing)(e)?``:typeof e==`object`?JSON.stringify(e):String(e),d=`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),f=`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``}},p=`decodeUri`,decodeUri=e=>{if((0,o.isMissing)(e)||typeof e!=`string`)return``;try{return decodeURIComponent(e)}catch{return e}},m=`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},h=`encodeBase64`,encodeBase64=(e,t=`base64url`)=>{if((0,o.isMissing)(e)||typeof e!=`string`)return``;try{return Buffer.from(e).toString(t)}catch{return``}},g=`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},_=`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``}},v=`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)},y=`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``}},b=`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)},x=`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)},S=`reduce`,C=[`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(!C.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))),w=`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}},T=`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)},E=`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``}},D=`split`,split=(e,t=`,`)=>{if(typeof e!=`string`)return[];let n=typeof t==`string`?t:`,`;return e.split(n)},O=`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},k=`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}},A=`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(`asString`,asString),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(`split`,split),t.addFunction(`truncate`,truncate),t.addFunction(`urlParam`,urlParam),t},j=/\${([^}]+)}/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(j);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,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};
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 asString=e=>i(e)?``:typeof e==`object`?JSON.stringify(e):String(e),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``}},split=(e,t=`,`)=>{if(typeof e!=`string`)return[];let n=typeof t==`string`?t:`,`;return e.split(n)},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(`asString`,asString),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(`split`,split),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.29.0",
3
+ "version": "0.30.0",
4
4
  "description": "",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",