@stackone/expressions 0.22.0 → 0.24.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 +116 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -330,6 +330,69 @@ Checks if an array includes at least one value from another array or a single va
|
|
|
330
330
|
"{{includesSome($.allowedRoles, $.currentUser.roles)}}";
|
|
331
331
|
```
|
|
332
332
|
|
|
333
|
+
###### groupBy(array, key)
|
|
334
|
+
|
|
335
|
+
Groups an array of objects by the value of a specified key. Items with missing or null values for the key are collected under `"__missing__"`.
|
|
336
|
+
|
|
337
|
+
- `array` (array): Array of objects to group
|
|
338
|
+
- `key` (string): The object key to group by
|
|
339
|
+
- Returns: object mapping each unique key value to an array of matching items
|
|
340
|
+
|
|
341
|
+
```js
|
|
342
|
+
// Group employees by department
|
|
343
|
+
"{{groupBy($.employees, 'dept')}}";
|
|
344
|
+
// { eng: [{dept: "eng", ...}, ...], hr: [{dept: "hr", ...}] }
|
|
345
|
+
|
|
346
|
+
// Group tickets by status
|
|
347
|
+
"{{groupBy($.tickets, 'status')}}";
|
|
348
|
+
// { open: [...], closed: [...] }
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
###### reduce(array, operation, field?)
|
|
352
|
+
|
|
353
|
+
Applies an aggregate operation to an array. When `field` is specified, that field is extracted from each object before applying the operation.
|
|
354
|
+
|
|
355
|
+
- `array` (array): The array to reduce
|
|
356
|
+
- `operation` (string): One of `"sum"`, `"avg"`, `"count"`, `"min"`, `"max"`, `"concat"`, `"flatten"`
|
|
357
|
+
- `field` (string, optional): Object key to extract values from before reducing
|
|
358
|
+
- Returns: the aggregated result, or null if invalid
|
|
359
|
+
|
|
360
|
+
```js
|
|
361
|
+
// Sum numbers
|
|
362
|
+
"{{reduce([1, 2, 3], 'sum')}}"; // Returns 6
|
|
363
|
+
|
|
364
|
+
// Sum a field from objects
|
|
365
|
+
"{{reduce($.orders, 'sum', 'total')}}"; // Returns sum of all order totals
|
|
366
|
+
|
|
367
|
+
// Average scores
|
|
368
|
+
"{{reduce($.reviews, 'avg', 'rating')}}"; // Returns average rating
|
|
369
|
+
|
|
370
|
+
// Count items
|
|
371
|
+
"{{reduce($.users, 'count')}}"; // Returns number of users
|
|
372
|
+
|
|
373
|
+
// Concatenate arrays from a field
|
|
374
|
+
"{{reduce($.users, 'concat', 'permissions')}}"; // Returns all permissions merged
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
###### zipObject(keys, values)
|
|
378
|
+
|
|
379
|
+
Combines two parallel arrays into an object by pairing `keys[i]` with `values[i]`. If the arrays differ in length, the shorter length is used. Non-string keys are skipped.
|
|
380
|
+
|
|
381
|
+
- `keys` (array): Array of string keys
|
|
382
|
+
- `values` (array): Array of values to pair with each key
|
|
383
|
+
- Returns: object mapping each key to its corresponding value
|
|
384
|
+
|
|
385
|
+
```js
|
|
386
|
+
// Combine field names and values into an object
|
|
387
|
+
"{{zipObject(['name', 'email'], ['John', 'john@example.com'])}}"; // Returns { name: "John", email: "john@example.com" }
|
|
388
|
+
|
|
389
|
+
// Numeric values
|
|
390
|
+
"{{zipObject(['count', 'total'], [5, 100])}}"; // Returns { count: 5, total: 100 }
|
|
391
|
+
|
|
392
|
+
// From context variables
|
|
393
|
+
"{{zipObject($.fieldNames, $.fieldValues)}}";
|
|
394
|
+
```
|
|
395
|
+
|
|
333
396
|
###### dedupe(array)
|
|
334
397
|
|
|
335
398
|
Removes duplicate entries from an array, returning a new array with unique values. Primitives are compared by type and value (so `1` and `"1"` are distinct). Objects are compared by their contents with keys sorted, so `{a:1,b:2}` and `{b:2,a:1}` are treated as duplicates.
|
|
@@ -445,6 +508,33 @@ Returns the values of an object as an array. If the input is not an object, null
|
|
|
445
508
|
"{{values($.user)}}";
|
|
446
509
|
```
|
|
447
510
|
|
|
511
|
+
##### Math Functions
|
|
512
|
+
|
|
513
|
+
###### min(...values)
|
|
514
|
+
|
|
515
|
+
Returns the smallest value from the provided numbers.
|
|
516
|
+
|
|
517
|
+
- `values` (number | number[]): Numbers to compare (individual values or an array)
|
|
518
|
+
- Returns: smallest number, or null if no valid numbers provided
|
|
519
|
+
|
|
520
|
+
```js
|
|
521
|
+
// Multiple arguments
|
|
522
|
+
"{{min(3, 1, 2)}}"; // Returns 1
|
|
523
|
+
|
|
524
|
+
// Array of numbers
|
|
525
|
+
"{{min([5, 2, 8])}}"; // Returns 2
|
|
526
|
+
|
|
527
|
+
// Mixed positive and negative
|
|
528
|
+
"{{min(-10, 0, 10)}}"; // Returns -10
|
|
529
|
+
|
|
530
|
+
// From context variables
|
|
531
|
+
"{{min(a, b, c)}}";
|
|
532
|
+
"{{min($.values)}}";
|
|
533
|
+
|
|
534
|
+
// Invalid input returns null
|
|
535
|
+
"{{min([])}}"; // Returns null
|
|
536
|
+
```
|
|
537
|
+
|
|
448
538
|
##### String Functions
|
|
449
539
|
|
|
450
540
|
###### capitalize(value, mode?)
|
|
@@ -562,6 +652,32 @@ Pads the start of a string with another string until it reaches the target lengt
|
|
|
562
652
|
"{{padStart($.id, 8, '0')}}";
|
|
563
653
|
```
|
|
564
654
|
|
|
655
|
+
###### replace(value, search, replacement, replaceAll?)
|
|
656
|
+
|
|
657
|
+
Replaces occurrences of a search string with a replacement string.
|
|
658
|
+
|
|
659
|
+
- `value` (string): The string to perform replacement on
|
|
660
|
+
- `search` (string): The substring to search for
|
|
661
|
+
- `replacement` (string): The string to replace matches with
|
|
662
|
+
- `replaceAll` (boolean, optional): If true, replaces all occurrences; otherwise replaces only the first (default: false)
|
|
663
|
+
- Returns: string with replacements made, or original string if search not found
|
|
664
|
+
|
|
665
|
+
```js
|
|
666
|
+
// Replace first occurrence (default)
|
|
667
|
+
"{{replace('hello world', 'world', 'there')}}"; // Returns "hello there"
|
|
668
|
+
"{{replace('hello hello', 'hello', 'hi')}}"; // Returns "hi hello"
|
|
669
|
+
|
|
670
|
+
// Replace all occurrences
|
|
671
|
+
"{{replace('hello hello', 'hello', 'hi', true)}}"; // Returns "hi hi"
|
|
672
|
+
"{{replace('foo-bar-baz', '-', '_', true)}}"; // Returns "foo_bar_baz"
|
|
673
|
+
|
|
674
|
+
// Remove characters by replacing with empty string
|
|
675
|
+
"{{replace('a-b-c', '-', '', true)}}"; // Returns "abc"
|
|
676
|
+
|
|
677
|
+
// Replace from context variable
|
|
678
|
+
"{{replace($.text, ' ', '-', true)}}";
|
|
679
|
+
```
|
|
680
|
+
|
|
565
681
|
###### regexMatch(value, pattern, groupIndex?)
|
|
566
682
|
|
|
567
683
|
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(`jsonpath-plus`);const l=`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),u=`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},d=`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)},f=`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)},p=`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}},m=`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},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(`dedupe`,dedupe),t.addFunction(`join`,join),t.addFunction(p,regexMatch),t.addFunction(`padStart`,padStart),t.addFunction(p,regexMatch),t.addFunction(`truncate`,truncate),t},h=/\${([^}]+)}/g,cleanExpression=e=>e.replace(/\$\./g,``).trim(),compileExpression=(e,t)=>{try{return e.compile(t)}catch{return 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,c.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(h);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(),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(`jsonpath-plus`);const l=`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),u=`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},d=`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},f=`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)},p=`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)},m=`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)},h=`reduce`,g=[`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(!g.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))),_=`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}},v=`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)},y=`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},b=`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(`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},x=/\${([^}]+)}/g,cleanExpression=e=>e.replace(/\$\./g,``).trim(),compileExpression=(e,t)=>{try{return e.compile(t)}catch{return 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,c.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(x);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(),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{JSONPath as u}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),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},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)},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)},d
|
|
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{JSONPath as u}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),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},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)},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)},d=[`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(!d.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)},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},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(`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},f=/\${([^}]+)}/g,cleanExpression=e=>e.replace(/\$\./g,``).trim(),compileExpression=(e,t)=>{try{return e.compile(t)}catch{return 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 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(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 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(),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};
|