@statedelta-libs/expressions 0.0.3 → 0.1.1
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 +96 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +109 -4
- package/dist/index.d.ts +109 -4
- package/dist/index.js +1 -1
- package/package.json +15 -15
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -364,6 +364,102 @@ Objetos com `path` e `op` só são tratados como conditions se `op` for um opera
|
|
|
364
364
|
|
|
365
365
|
Isso permite que effect objects de handlers (que usam `{ resource, op: "set", path, value }`) sejam processados corretamente sem serem confundidos com conditions.
|
|
366
366
|
|
|
367
|
+
## Builders
|
|
368
|
+
|
|
369
|
+
Funções declarativas para construir expressões. Disponíveis via namespace `builders`:
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
import { builders, compile } from '@statedelta-libs/expressions';
|
|
373
|
+
|
|
374
|
+
const { $, $fn, $if, $pipe } = builders;
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### `$` / `ref` - Path Reference
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
$("player.hp") // { $: "player.hp" }
|
|
381
|
+
$("items[0].price") // { $: "items[0].price" }
|
|
382
|
+
$("items[*].price") // { $: "items[*].price" } (wildcard)
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### `$fn` / `fn` - Function Call
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
// Com argumentos - chama a função
|
|
389
|
+
$fn("add", [$("a"), $("b")]) // { $fn: "add", args: [...] }
|
|
390
|
+
$fn("multiply", [10, $("x")]) // literal + expression
|
|
391
|
+
|
|
392
|
+
// Sem argumentos - retorna referência à função (útil em $pipe)
|
|
393
|
+
$fn("sum") // { $fn: "sum" }
|
|
394
|
+
|
|
395
|
+
// Com callbacks (predicados, mappers)
|
|
396
|
+
$fn("filter", [(item) => item.active])
|
|
397
|
+
$fn("map", [(item) => item.price])
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### `$if` - Conditional
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
// Com else
|
|
404
|
+
$if($("isVip"), 0.2, 0)
|
|
405
|
+
// { $if: { $: "isVip" }, then: 0.2, else: 0 }
|
|
406
|
+
|
|
407
|
+
// Sem else
|
|
408
|
+
$if($("active"), "yes")
|
|
409
|
+
// { $if: { $: "active" }, then: "yes" }
|
|
410
|
+
|
|
411
|
+
// Nested
|
|
412
|
+
$if($("level1"), $if($("level2"), "deep", "shallow"), "none")
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### `$pipe` / `pipe` - Composition
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
$pipe(
|
|
419
|
+
$("items"), // valor inicial
|
|
420
|
+
$fn("filter", [(x) => x.active]), // transforma
|
|
421
|
+
$fn("map", [(x) => x.price]), // transforma
|
|
422
|
+
$fn("sum") // resultado
|
|
423
|
+
)
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Exemplo Completo
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
import { builders, compile } from '@statedelta-libs/expressions';
|
|
430
|
+
import { filter, map, sum } from '@statedelta-libs/operators';
|
|
431
|
+
|
|
432
|
+
const { $, $fn, $if, $pipe } = builders;
|
|
433
|
+
|
|
434
|
+
const scope = { filter, map, sum };
|
|
435
|
+
|
|
436
|
+
// Soma preços de itens ativos com desconto VIP
|
|
437
|
+
const expr = $pipe(
|
|
438
|
+
$("items"),
|
|
439
|
+
$fn("filter", [(item) => item.active]),
|
|
440
|
+
$fn("map", [(item) => item.price]),
|
|
441
|
+
$fn("sum")
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
const { fn } = compile(expr, { scope });
|
|
445
|
+
|
|
446
|
+
fn({
|
|
447
|
+
items: [
|
|
448
|
+
{ price: 10, active: true },
|
|
449
|
+
{ price: 20, active: false },
|
|
450
|
+
{ price: 30, active: true }
|
|
451
|
+
]
|
|
452
|
+
}); // 40
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Aliases
|
|
456
|
+
|
|
457
|
+
| Builder | Alias |
|
|
458
|
+
|---------|-------|
|
|
459
|
+
| `$` | `ref` |
|
|
460
|
+
| `$fn` | `fn` |
|
|
461
|
+
| `$pipe` | `pipe` |
|
|
462
|
+
|
|
367
463
|
## TypeScript
|
|
368
464
|
|
|
369
465
|
```typescript
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var conditions=require('@statedelta-libs/conditions'),omniAst=require('omni-ast');var m=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,E=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,T=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",A=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),I=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),g=n=>n!==null&&typeof n=="object"&&"path"in n&&"op"in n&&I.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),y=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,U=n=>g(n)||y(n),z=n=>{if(n===null)return true;let e=typeof n;if(e==="string"||e==="number"||e==="boolean"||Array.isArray(n))return true;if(e==="object"&&n!==null){let o=n,t="path"in o&&"op"in o&&I.has(o.op);return !("$"in o)&&!("$if"in o)&&!("$fn"in o)&&!("$pipe"in o)&&!t&&!("logic"in o)}return false};var R=new Map;function V(n){let e=[],o=n.length,t=0,i="";for(;t<o;){let s=n[t];if(s===".")i&&(e.push({type:"key",value:i}),i=""),t++;else if(s==="["){i&&(e.push({type:"key",value:i}),i=""),t++;let r=t;for(;t<o&&n[t]!=="]";)t++;let f=n.slice(r,t);if(t++,f==="*")e.push({type:"wildcard",value:"*"});else {let c=parseInt(f,10);e.push({type:"index",value:isNaN(c)?f:c});}}else i+=s,t++;}return i&&e.push({type:"key",value:i}),e}function L(n){return n.includes("[*]")}function O(n){let e=R.get(n);return e||(e=L(n)?Z(n):X(n),R.set(n,e),e)}function X(n){if(!n.includes(".")&&!n.includes("["))return i=>i?.[n];let e=V(n),o=e.length;if(o===2){let[i,s]=e,r=i.value,f=s.value;return c=>c?.[r]?.[f]}if(o===3){let[i,s,r]=e,f=i.value,c=s.value,u=r.value;return a=>a?.[f]?.[c]?.[u]}let t=e.map(i=>i.value);return i=>{let s=i;for(let r=0;r<o&&s!=null;r++)s=s[t[r]];return s}}function Z(n){let e=V(n),o=[];for(let t=0;t<e.length;t++)e[t].type==="wildcard"&&o.push(t);return o.length===1?nn(e,o[0]):en(e,o)}function nn(n,e){let o=n.slice(0,e).map(r=>r.value),t=n.slice(e+1).map(r=>r.value),i=o.length,s=t.length;if(s===0){if(i===1){let r=o[0];return f=>f?.[r]}return r=>{let f=r;for(let c=0;c<i&&f!=null;c++)f=f[o[c]];return f}}if(s===1){let r=t[0];if(i===1){let f=o[0];return c=>{let u=c?.[f];if(Array.isArray(u))return u.map(a=>a?.[r])}}return f=>{let c=f;for(let u=0;u<i&&c!=null;u++)c=c[o[u]];if(Array.isArray(c))return c.map(u=>u?.[r])}}return r=>{let f=r;for(let c=0;c<i&&f!=null;c++)f=f[o[c]];if(Array.isArray(f))return f.map(c=>{let u=c;for(let a=0;a<s&&u!=null;a++)u=u[t[a]];return u})}}function en(n,e){let o=[],t=0;for(let s=0;s<e.length;s++){let r=e[s],f=s===e.length-1,c=n.slice(t,r).map(u=>u.value);c.length>0&&o.push({type:"access",keys:c}),o.push({type:f?"map":"flatMap",keys:[]}),t=r+1;}let i=n.slice(t).map(s=>s.value);return s=>{let r=s;for(let f of o){if(r==null)return;if(f.type==="access")for(let c of f.keys){if(r==null)return;r=r[c];}else if(f.type==="flatMap"){if(!Array.isArray(r))return;r=r.flatMap(c=>{let u=c;return Array.isArray(u)?u:[u]});}else if(f.type==="map"){if(!Array.isArray(r))return;i.length>0&&(r=r.map(c=>{let u=c;for(let a of i){if(u==null)return;u=u[a];}return u}));}}return r}}function tn(n,e){return O(e)(n)}function w(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function on(){R.clear();}function rn(){return R.size}function k(n){let e=new Set;return S(n,e),Array.from(e)}function S(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let i=0;i<n.length;i++)S(n[i],e);return}if(m(n)){e.add(w(n.$));return}if(E(n)){if(typeof n.$if=="string"){let i=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(w(i));}else S(n.$if,e);S(n.then,e),n.else!==void 0&&S(n.else,e);return}if(A(n)){for(let i=0;i<n.$pipe.length;i++)S(n.$pipe[i],e);return}if(T(n)){if(n.args)for(let i=0;i<n.args.length;i++)S(n.args[i],e);return}if(g(n)){e.add(w(n.path)),n.value!==void 0&&conditions.isRef(n.value)&&e.add(w(n.value.$));return}if(y(n)){for(let i=0;i<n.conditions.length;i++)S(n.conditions[i],e);return}let o=n,t=Object.keys(o);for(let i=0;i<t.length;i++)S(o[t[i]],e);}function ln(n){return k(n).length>0}function fn(n){return k(n).length===0}function cn(n){return JSON.stringify(n)}function F(n,e={}){let o=e.scope??{},t=e.accessor,i=C(n,o,t),s=k(n),r=cn(n);return {fn:i,deps:s,hash:r}}function C(n,e,o){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let t=n.map(i=>C(i,e,o));return i=>t.map(s=>s(i))}if(m(n))return un(n,o);if(E(n))return an(n,e,o);if(A(n))return pn(n,e,o);if(T(n))return dn(n,e,o);if(g(n))return conditions.compile(n,o?{accessor:o}:void 0);if(y(n))return conditions.compile(n,o?{accessor:o}:void 0);if(z(n)){let t=n,i=Object.keys(t),s=i.map(r=>C(t[r],e,o));return r=>{let f={};for(let c=0;c<i.length;c++)f[i[c]]=s[c](r);return f}}return ()=>n}function q(n,e){return e?o=>e(n,o):O(n)}function un(n,e){return q(n.$,e)}function an(n,e,o){let t;if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if,f=q(r,o);t=n.$if.startsWith("!")?u=>!f(u):u=>!!f(u);}else {let r=C(n.$if,e,o);t=f=>!!r(f);}let i=C(n.then,e,o),s=n.else!==void 0?C(n.else,e,o):()=>{};return r=>t(r)?i(r):s(r)}function pn(n,e,o){let t=n.$pipe;if(t.length===0)return ()=>{};if(t.length===1)return C(t[0],e,o);let i=C(t[0],e,o),s=t.slice(1).map(f=>C(f,e,o)),r=s.length;if(r===1){let[f]=s;return c=>{let u=i(c),a=f(c);return typeof a=="function"?a(u):a}}if(r===2){let[f,c]=s;return u=>{let a=i(u),p=f(u);return a=typeof p=="function"?p(a):p,p=c(u),typeof p=="function"?p(a):p}}if(r===3){let[f,c,u]=s;return a=>{let p=i(a),h=f(a);return p=typeof h=="function"?h(p):h,h=c(a),p=typeof h=="function"?h(p):h,h=u(a),typeof h=="function"?h(p):h}}return f=>{let c=i(f);for(let u=0;u<r;u++){let a=s[u](f);c=typeof a=="function"?a(c):a;}return c}}function dn(n,e,o){let t=n.$fn,i=n.args;if(i===void 0)return ()=>{let f=e[t];if(!f)throw new Error(`Function not found in scope: ${t}`);return f};let s=i.map(f=>C(f,e,o)),r=s.length;if(r===0)return f=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c()};if(r===1){let[f]=s;return c=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u(f(c))}}if(r===2){let[f,c]=s;return u=>{let a=e[t];if(!a)throw new Error(`Function not found in scope: ${t}`);return a(f(u),c(u))}}if(r===3){let[f,c,u]=s;return a=>{let p=e[t];if(!p)throw new Error(`Function not found in scope: ${t}`);return p(f(a),c(a),u(a))}}return f=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c(...s.map(u=>u(f)))}}function mn(n,e,o={}){return F(n,o).fn(e)}var v=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,o={}){let t=JSON.stringify(e),i=this.cache.get(t);if(i)return this.cache.delete(t),this.cache.set(t,i),i;let s=F(e,o);if(this.cache.size>=this._maxSize){let r=this.cache.keys().next().value;r&&this.cache.delete(r);}return this.cache.set(t,s),s}has(e){return this.cache.has(JSON.stringify(e))}delete(e){return this.cache.delete(JSON.stringify(e))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(e){for(this._maxSize=e;this.cache.size>this._maxSize;){let o=this.cache.keys().next().value;o&&this.cache.delete(o);}}},J=new v;function gn(n,e={}){return J.get(n,e)}function P(n,e="root",o={}){let t=[];return $(n,e,t,o),{valid:t.length===0,errors:t}}function $(n,e,o,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r=0;r<n.length;r++)$(n[r],`${e}[${r}]`,o,t);return}if(m(n)){(!n.$||typeof n.$!="string")&&o.push(`${e}: invalid reference, $ must be non-empty string`);return}if(E(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||o.push(`${e}.$if: empty path in string shorthand`):$(n.$if,`${e}.$if`,o,t),$(n.then,`${e}.then`,o,t),n.else!==void 0&&$(n.else,`${e}.else`,o,t);return}if(A(n)){if(!Array.isArray(n.$pipe)){o.push(`${e}.$pipe: must be an array`);return}if(n.$pipe.length===0){o.push(`${e}.$pipe: must have at least one element`);return}for(let r=0;r<n.$pipe.length;r++)$(n.$pipe[r],`${e}.$pipe[${r}]`,o,t);return}if(T(n)){if(!n.$fn||typeof n.$fn!="string"){o.push(`${e}: invalid function, $fn must be non-empty string`);return}if(t.scope&&!(n.$fn in t.scope)&&o.push(`${e}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))o.push(`${e}.args: must be an array`);else for(let r=0;r<n.args.length;r++)$(n.args[r],`${e}.args[${r}]`,o,t);return}if(g(n)){let r=conditions.validate(n,e);r.valid||o.push(...r.errors);return}if(y(n)){let r=conditions.validate(n,e);r.valid||o.push(...r.errors);return}let i=n,s=Object.keys(i);for(let r=0;r<s.length;r++){let f=s[r];$(i[f],`${e}.${f}`,o,t);}}function yn(n,e={}){let o=P(n,"root",e);if(!o.valid)throw new Error(`Invalid expression: ${o.errors.join("; ")}`)}function hn(n,e={}){return P(n,"root",e).valid}var D="data",K="scope",En={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function j(n,e={}){let{dataParam:o=D,scopeParam:t=K,noPrefixes:i=false}=e;return d(n,o,t,i)}function d(n,e,o,t){if(n===null)return omniAst.builders.literal(null);if(typeof n=="string")return omniAst.builders.literal(n);if(typeof n=="number")return omniAst.builders.literal(n);if(typeof n=="boolean")return omniAst.builders.literal(n);if(Array.isArray(n))return omniAst.builders.arrayExpression(n.map(i=>d(i,e,o,t)));if(m(n))return Tn(n.$,e,t);if(E(n))return Cn(n,e,o,t);if(A(n))return Sn(n.$pipe,e,o,t);if(T(n))return bn(n,e,o,t);if(g(n))return $n(n,e,o,t);if(y(n))return kn(n,e,o,t);if(typeof n=="object"){let s=Object.entries(n).map(([r,f])=>omniAst.builders.property(omniAst.builders.identifier(r),d(f,e,o,t)));return omniAst.builders.objectExpression(s)}return omniAst.builders.literal(null)}function Tn(n,e,o){return n.includes("[*]")?An(n,e,o):x(n,e,o)}function x(n,e,o){let t=N(n);if(t.length===0)return o?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e);let i;if(o){let s=t[0];i=omniAst.builders.identifier(s.value);for(let r=1;r<t.length;r++){let f=t[r];f.type==="key"?i=omniAst.builders.memberExpression(i,omniAst.builders.identifier(f.value),false,true):i=omniAst.builders.memberExpression(i,omniAst.builders.literal(f.value),true,true);}}else {i=omniAst.builders.identifier(e);for(let s of t)s.type==="key"?i=omniAst.builders.memberExpression(i,omniAst.builders.identifier(s.value),false,true):i=omniAst.builders.memberExpression(i,omniAst.builders.literal(s.value),true,true);}return i}function An(n,e,o){let t=n.indexOf("[*]"),i=n.slice(0,t),s=n.slice(t+3),r;if(i?r=x(i,e,o):r=o?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e),!s||s==="")return r;if(s.includes("[*]"))return Y(r,s);let f="_i",c=s.startsWith(".")?s.slice(1):s,u=omniAst.builders.identifier(f);if(c){let a=N(c);for(let p of a)p.type==="key"?u=omniAst.builders.memberExpression(u,omniAst.builders.identifier(p.value),false,true):u=omniAst.builders.memberExpression(u,omniAst.builders.literal(p.value),true,true);}return omniAst.builders.callExpression(omniAst.builders.memberExpression(r,omniAst.builders.identifier("map"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(f)],u)])}function Y(n,e){let o=e.indexOf("[*]"),t=e.slice(0,o),i=e.slice(o+3),s="_i",r=t.startsWith(".")?t.slice(1):t,f=omniAst.builders.identifier(s);if(r){let u=N(r);for(let a of u)a.type==="key"&&(f=omniAst.builders.memberExpression(f,omniAst.builders.identifier(a.value),false,true));}if(i.includes("[*]")){let u=Y(f,i);return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],u)])}let c=i.startsWith(".")?i.slice(1):i;if(c){let u=N(c);for(let a of u)a.type==="key"&&(f=omniAst.builders.memberExpression(f,omniAst.builders.identifier(a.value),false,true));}return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],f)])}function Cn(n,e,o,t){let i;if(typeof n.$if=="string"){let f=n.$if.startsWith("!"),c=f?n.$if.slice(1):n.$if,u=x(c,e,t);i=f?omniAst.builders.unaryExpression("!",u):u;}else i=d(n.$if,e,o,t);let s=d(n.then,e,o,t),r=n.else!==void 0?d(n.else,e,o,t):omniAst.builders.identifier("undefined");return omniAst.builders.conditionalExpression(i,s,r)}function bn(n,e,o,t){let i=t?omniAst.builders.identifier(n.$fn):omniAst.builders.memberExpression(omniAst.builders.identifier(o),omniAst.builders.identifier(n.$fn),false,false);if(n.args===void 0)return i;let s=n.args.map(r=>d(r,e,o,t));return omniAst.builders.callExpression(i,s)}function Sn(n,e,o,t){if(n.length===0)return omniAst.builders.identifier("undefined");if(n.length===1)return d(n[0],e,o,t);let i=d(n[0],e,o,t);for(let s=1;s<n.length;s++){let r=d(n[s],e,o,t);i=omniAst.builders.callExpression(r,[i]);}return i}function $n(n,e,o,t){let i=x(n.path,e,t),s=n.value!==void 0?m(n.value)?x(n.value.$,e,t):d(n.value,e,o,t):omniAst.builders.literal(null),r=En[n.op];if(r)return omniAst.builders.binaryExpression(r,i,s);switch(n.op){case "in":return omniAst.builders.callExpression(omniAst.builders.memberExpression(s,omniAst.builders.identifier("includes")),[i]);case "notIn":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(s,omniAst.builders.identifier("includes")),[i]));case "contains":return omniAst.builders.callExpression(omniAst.builders.memberExpression(i,omniAst.builders.identifier("includes"),false,true),[s]);case "notContains":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(i,omniAst.builders.identifier("includes"),false,true),[s]));case "exists":return omniAst.builders.binaryExpression("!=",i,omniAst.builders.literal(null));case "notExists":return omniAst.builders.binaryExpression("==",i,omniAst.builders.literal(null));case "matches":return omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[s]),omniAst.builders.identifier("test")),[i]);case "notMatches":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[s]),omniAst.builders.identifier("test")),[i]));case "startsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(i,omniAst.builders.identifier("startsWith"),false,true),[s]);case "endsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(i,omniAst.builders.identifier("endsWith"),false,true),[s]);default:return omniAst.builders.binaryExpression("===",i,s)}}function kn(n,e,o,t){let{logic:i,conditions:s}=n,r=i==="AND"?"&&":"||";if(s.length===0)return omniAst.builders.literal(i==="AND");if(s.length===1)return d(s[0],e,o,t);let f=d(s[0],e,o,t);for(let c=1;c<s.length;c++){let u=d(s[c],e,o,t);f=omniAst.builders.logicalExpression(r,f,u);}return f}function N(n){let e=[],o=n.length,t=0,i="";for(;t<o;){let s=n[t];if(s===".")i&&(e.push({type:"key",value:i}),i=""),t++;else if(s==="["){i&&(e.push({type:"key",value:i}),i=""),t++;let r=t;for(;t<o&&n[t]!=="]";)t++;let f=n.slice(r,t);if(t++,f!=="*"){let c=parseInt(f,10);e.push({type:"index",value:isNaN(c)?f:c});}}else i+=s,t++;}return i&&e.push({type:"key",value:i}),e}function H(n,e=[D]){return omniAst.builders.arrowFunctionExpression(e.map(o=>omniAst.builders.identifier(o)),n)}function G(n){let e=new Set;return b(n,e),e}function b(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let t of n)b(t,e);return}if(m(n))return;if(E(n)){b(n.$if,e),b(n.then,e),n.else!==void 0&&b(n.else,e);return}if(A(n)){for(let t of n.$pipe)b(t,e);return}if(T(n)){if(e.add(n.$fn),n.args)for(let t of n.args)b(t,e);return}if(g(n)){n.value!==void 0&&typeof n.value=="object"&&b(n.value,e);return}if(y(n)){for(let t of n.conditions)b(t,e);return}let o=n;for(let t of Object.keys(o))b(o[t],e);}function W(n){let e=new Set;for(let o of n){let t=o.indexOf("."),i=o.indexOf("["),s=o.length;t!==-1&&(s=Math.min(s,t)),i!==-1&&(s=Math.min(s,i));let r=o.slice(0,s);r&&e.add(r);}return e}function xn(n){return JSON.stringify(n)}function Rn(n,e,o){let t=j(n,{noPrefixes:true}),i=omniAst.generate(t),s=e.size>0?`const{${[...e].join(",")}}=data??{};`:"",r=o.size>0?`const{${[...o].join(",")}}=scope;`:"";return r?`(function(scope){${r}return function(data){${s}return ${i}}})`:`(function(){return function(data){${s}return ${i}}})`}function M(n,e={}){let{scope:o={},returnCode:t=false}=e,i=k(n),s=W(i),r=G(n),f=xn(n),c=Rn(n,s,r);if(t)return {code:c,deps:i,hash:f,dataRoots:[...s],scopeFns:[...r]};let u;try{u=new Function(`return ${c}`)()(o);}catch(a){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${a instanceof Error?a.message:String(a)}`)}return {fn:u,deps:i,hash:f}}function Q(n,e,o={}){let{fn:t}=M(n,o);return t(e)}var re="0.0.3";exports.ExpressionCache=v;exports.VERSION=re;exports.assertValid=yn;exports.cache=J;exports.cached=gn;exports.clearPathCache=on;exports.compile=F;exports.compileAST=M;exports.compilePath=O;exports.dslToAST=j;exports.evaluate=mn;exports.evaluateAST=Q;exports.extractDataRoots=W;exports.extractDeps=k;exports.extractScopeFns=G;exports.get=tn;exports.getPathCacheSize=rn;exports.hasDeps=ln;exports.hasWildcard=L;exports.isCondition=g;exports.isConditionExpr=U;exports.isConditionGroup=y;exports.isConditional=E;exports.isFn=T;exports.isLiteral=z;exports.isPipe=A;exports.isPure=fn;exports.isRef=m;exports.isValid=hn;exports.normalizePath=w;exports.validate=P;exports.wrapInFunction=H;
|
|
1
|
+
'use strict';var conditions=require('@statedelta-libs/conditions'),omniAst=require('omni-ast');var en=Object.defineProperty;var tn=(n,e)=>{for(var i in e)en(n,i,{get:e[i],enumerable:true});};var m=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,E=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,T=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",C=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),I=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),g=n=>n!==null&&typeof n=="object"&&"path"in n&&"op"in n&&I.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),y=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,on=n=>g(n)||y(n),P=n=>{if(n===null)return true;let e=typeof n;if(e==="string"||e==="number"||e==="boolean"||Array.isArray(n))return true;if(e==="object"&&n!==null){let i=n,t="path"in i&&"op"in i&&I.has(i.op);return !("$"in i)&&!("$if"in i)&&!("$fn"in i)&&!("$pipe"in i)&&!t&&!("logic"in i)}return false};var R=new Map;function V(n){let e=[],i=n.length,t=0,o="";for(;t<i;){let s=n[t];if(s===".")o&&(e.push({type:"key",value:o}),o=""),t++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),t++;let r=t;for(;t<i&&n[t]!=="]";)t++;let f=n.slice(r,t);if(t++,f==="*")e.push({type:"wildcard",value:"*"});else {let u=parseInt(f,10);e.push({type:"index",value:isNaN(u)?f:u});}}else o+=s,t++;}return o&&e.push({type:"key",value:o}),e}function L(n){return n.includes("[*]")}function O(n){let e=R.get(n);return e||(e=L(n)?sn(n):rn(n),R.set(n,e),e)}function rn(n){if(!n.includes(".")&&!n.includes("["))return o=>o?.[n];let e=V(n),i=e.length;if(i===2){let[o,s]=e,r=o.value,f=s.value;return u=>u?.[r]?.[f]}if(i===3){let[o,s,r]=e,f=o.value,u=s.value,c=r.value;return a=>a?.[f]?.[u]?.[c]}let t=e.map(o=>o.value);return o=>{let s=o;for(let r=0;r<i&&s!=null;r++)s=s[t[r]];return s}}function sn(n){let e=V(n),i=[];for(let t=0;t<e.length;t++)e[t].type==="wildcard"&&i.push(t);return i.length===1?ln(e,i[0]):fn(e,i)}function ln(n,e){let i=n.slice(0,e).map(r=>r.value),t=n.slice(e+1).map(r=>r.value),o=i.length,s=t.length;if(s===0){if(o===1){let r=i[0];return f=>f?.[r]}return r=>{let f=r;for(let u=0;u<o&&f!=null;u++)f=f[i[u]];return f}}if(s===1){let r=t[0];if(o===1){let f=i[0];return u=>{let c=u?.[f];if(Array.isArray(c))return c.map(a=>a?.[r])}}return f=>{let u=f;for(let c=0;c<o&&u!=null;c++)u=u[i[c]];if(Array.isArray(u))return u.map(c=>c?.[r])}}return r=>{let f=r;for(let u=0;u<o&&f!=null;u++)f=f[i[u]];if(Array.isArray(f))return f.map(u=>{let c=u;for(let a=0;a<s&&c!=null;a++)c=c[t[a]];return c})}}function fn(n,e){let i=[],t=0;for(let s=0;s<e.length;s++){let r=e[s],f=s===e.length-1,u=n.slice(t,r).map(c=>c.value);u.length>0&&i.push({type:"access",keys:u}),i.push({type:f?"map":"flatMap",keys:[]}),t=r+1;}let o=n.slice(t).map(s=>s.value);return s=>{let r=s;for(let f of i){if(r==null)return;if(f.type==="access")for(let u of f.keys){if(r==null)return;r=r[u];}else if(f.type==="flatMap"){if(!Array.isArray(r))return;r=r.flatMap(u=>{let c=u;return Array.isArray(c)?c:[c]});}else if(f.type==="map"){if(!Array.isArray(r))return;o.length>0&&(r=r.map(u=>{let c=u;for(let a of o){if(c==null)return;c=c[a];}return c}));}}return r}}function un(n,e){return O(e)(n)}function k(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function cn(){R.clear();}function an(){return R.size}function S(n){let e=new Set;return $(n,e),Array.from(e)}function $(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let o=0;o<n.length;o++)$(n[o],e);return}if(m(n)){e.add(k(n.$));return}if(E(n)){if(typeof n.$if=="string"){let o=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(k(o));}else $(n.$if,e);$(n.then,e),n.else!==void 0&&$(n.else,e);return}if(C(n)){for(let o=0;o<n.$pipe.length;o++)$(n.$pipe[o],e);return}if(T(n)){if(n.args)for(let o=0;o<n.args.length;o++)$(n.args[o],e);return}if(g(n)){e.add(k(n.path)),n.value!==void 0&&conditions.isRef(n.value)&&e.add(k(n.value.$));return}if(y(n)){for(let o=0;o<n.conditions.length;o++)$(n.conditions[o],e);return}let i=n,t=Object.keys(i);for(let o=0;o<t.length;o++)$(i[t[o]],e);}function dn(n){return S(n).length>0}function mn(n){return S(n).length===0}function gn(n){return JSON.stringify(n)}function F(n,e={}){let i=e.scope??{},t=e.accessor,o=A(n,i,t),s=S(n),r=gn(n);return {fn:o,deps:s,hash:r}}function A(n,e,i){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let t=n.map(o=>A(o,e,i));return o=>t.map(s=>s(o))}if(m(n))return yn(n,i);if(E(n))return hn(n,e,i);if(C(n))return En(n,e,i);if(T(n))return Tn(n,e,i);if(g(n))return conditions.compile(n,i?{accessor:i}:void 0);if(y(n))return conditions.compile(n,i?{accessor:i}:void 0);if(P(n)){let t=n,o=Object.keys(t),s=o.map(r=>A(t[r],e,i));return r=>{let f={};for(let u=0;u<o.length;u++)f[o[u]]=s[u](r);return f}}return ()=>n}function q(n,e){return e?i=>e(n,i):O(n)}function yn(n,e){return q(n.$,e)}function hn(n,e,i){let t;if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if,f=q(r,i);t=n.$if.startsWith("!")?c=>!f(c):c=>!!f(c);}else {let r=A(n.$if,e,i);t=f=>!!r(f);}let o=A(n.then,e,i),s=n.else!==void 0?A(n.else,e,i):()=>{};return r=>t(r)?o(r):s(r)}function En(n,e,i){let t=n.$pipe;if(t.length===0)return ()=>{};if(t.length===1)return A(t[0],e,i);let o=A(t[0],e,i),s=t.slice(1).map(f=>A(f,e,i)),r=s.length;if(r===1){let[f]=s;return u=>{let c=o(u),a=f(u);return typeof a=="function"?a(c):a}}if(r===2){let[f,u]=s;return c=>{let a=o(c),p=f(c);return a=typeof p=="function"?p(a):p,p=u(c),typeof p=="function"?p(a):p}}if(r===3){let[f,u,c]=s;return a=>{let p=o(a),h=f(a);return p=typeof h=="function"?h(p):h,h=u(a),p=typeof h=="function"?h(p):h,h=c(a),typeof h=="function"?h(p):h}}return f=>{let u=o(f);for(let c=0;c<r;c++){let a=s[c](f);u=typeof a=="function"?a(u):a;}return u}}function Tn(n,e,i){let t=n.$fn,o=n.args;if(o===void 0)return ()=>{let f=e[t];if(!f)throw new Error(`Function not found in scope: ${t}`);return f};let s=o.map(f=>A(f,e,i)),r=s.length;if(r===0)return f=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u()};if(r===1){let[f]=s;return u=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c(f(u))}}if(r===2){let[f,u]=s;return c=>{let a=e[t];if(!a)throw new Error(`Function not found in scope: ${t}`);return a(f(c),u(c))}}if(r===3){let[f,u,c]=s;return a=>{let p=e[t];if(!p)throw new Error(`Function not found in scope: ${t}`);return p(f(a),u(a),c(a))}}return f=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u(...s.map(c=>c(f)))}}function Cn(n,e,i={}){return F(n,i).fn(e)}var v=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,i={}){let t=JSON.stringify(e),o=this.cache.get(t);if(o)return this.cache.delete(t),this.cache.set(t,o),o;let s=F(e,i);if(this.cache.size>=this._maxSize){let r=this.cache.keys().next().value;r&&this.cache.delete(r);}return this.cache.set(t,s),s}has(e){return this.cache.has(JSON.stringify(e))}delete(e){return this.cache.delete(JSON.stringify(e))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(e){for(this._maxSize=e;this.cache.size>this._maxSize;){let i=this.cache.keys().next().value;i&&this.cache.delete(i);}}},J=new v;function An(n,e={}){return J.get(n,e)}function z(n,e="root",i={}){let t=[];return x(n,e,t,i),{valid:t.length===0,errors:t}}function x(n,e,i,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r=0;r<n.length;r++)x(n[r],`${e}[${r}]`,i,t);return}if(m(n)){(!n.$||typeof n.$!="string")&&i.push(`${e}: invalid reference, $ must be non-empty string`);return}if(E(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||i.push(`${e}.$if: empty path in string shorthand`):x(n.$if,`${e}.$if`,i,t),x(n.then,`${e}.then`,i,t),n.else!==void 0&&x(n.else,`${e}.else`,i,t);return}if(C(n)){if(!Array.isArray(n.$pipe)){i.push(`${e}.$pipe: must be an array`);return}if(n.$pipe.length===0){i.push(`${e}.$pipe: must have at least one element`);return}for(let r=0;r<n.$pipe.length;r++)x(n.$pipe[r],`${e}.$pipe[${r}]`,i,t);return}if(T(n)){if(!n.$fn||typeof n.$fn!="string"){i.push(`${e}: invalid function, $fn must be non-empty string`);return}if(t.scope&&!(n.$fn in t.scope)&&i.push(`${e}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))i.push(`${e}.args: must be an array`);else for(let r=0;r<n.args.length;r++)x(n.args[r],`${e}.args[${r}]`,i,t);return}if(g(n)){let r=conditions.validate(n,e);r.valid||i.push(...r.errors);return}if(y(n)){let r=conditions.validate(n,e);r.valid||i.push(...r.errors);return}let o=n,s=Object.keys(o);for(let r=0;r<s.length;r++){let f=s[r];x(o[f],`${e}.${f}`,i,t);}}function bn(n,e={}){let i=z(n,"root",e);if(!i.valid)throw new Error(`Invalid expression: ${i.errors.join("; ")}`)}function $n(n,e={}){return z(n,"root",e).valid}var Q={};tn(Q,{$:()=>K,$fn:()=>Y,$if:()=>kn,$pipe:()=>H,fn:()=>Sn,pipe:()=>wn,ref:()=>xn});function K(n){return {$:n}}var xn=K;function Y(n,e){return e===void 0||e.length===0?{$fn:n}:{$fn:n,args:e}}var Sn=Y;function kn(n,e,i){return i===void 0?{$if:n,then:e}:{$if:n,then:e,else:i}}function H(...n){return {$pipe:n}}var wn=H;var D="data",U="scope",Rn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function j(n,e={}){let{dataParam:i=D,scopeParam:t=U,noPrefixes:o=false}=e;return d(n,i,t,o)}function d(n,e,i,t){if(n===null)return omniAst.builders.literal(null);if(typeof n=="string")return omniAst.builders.literal(n);if(typeof n=="number")return omniAst.builders.literal(n);if(typeof n=="boolean")return omniAst.builders.literal(n);if(Array.isArray(n))return omniAst.builders.arrayExpression(n.map(o=>d(o,e,i,t)));if(m(n))return On(n.$,e,t);if(E(n))return vn(n,e,i,t);if(C(n))return jn(n.$pipe,e,i,t);if(T(n))return Nn(n,e,i,t);if(g(n))return Gn(n,e,i,t);if(y(n))return Wn(n,e,i,t);if(typeof n=="object"){let s=Object.entries(n).map(([r,f])=>omniAst.builders.property(omniAst.builders.identifier(r),d(f,e,i,t)));return omniAst.builders.objectExpression(s)}return omniAst.builders.literal(null)}function On(n,e,i){return n.includes("[*]")?Fn(n,e,i):w(n,e,i)}function w(n,e,i){let t=N(n);if(t.length===0)return i?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e);let o;if(i){let s=t[0];o=omniAst.builders.identifier(s.value);for(let r=1;r<t.length;r++){let f=t[r];f.type==="key"?o=omniAst.builders.memberExpression(o,omniAst.builders.identifier(f.value),false,true):o=omniAst.builders.memberExpression(o,omniAst.builders.literal(f.value),true,true);}}else {o=omniAst.builders.identifier(e);for(let s of t)s.type==="key"?o=omniAst.builders.memberExpression(o,omniAst.builders.identifier(s.value),false,true):o=omniAst.builders.memberExpression(o,omniAst.builders.literal(s.value),true,true);}return o}function Fn(n,e,i){let t=n.indexOf("[*]"),o=n.slice(0,t),s=n.slice(t+3),r;if(o?r=w(o,e,i):r=i?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e),!s||s==="")return r;if(s.includes("[*]"))return X(r,s);let f="_i",u=s.startsWith(".")?s.slice(1):s,c=omniAst.builders.identifier(f);if(u){let a=N(u);for(let p of a)p.type==="key"?c=omniAst.builders.memberExpression(c,omniAst.builders.identifier(p.value),false,true):c=omniAst.builders.memberExpression(c,omniAst.builders.literal(p.value),true,true);}return omniAst.builders.callExpression(omniAst.builders.memberExpression(r,omniAst.builders.identifier("map"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(f)],c)])}function X(n,e){let i=e.indexOf("[*]"),t=e.slice(0,i),o=e.slice(i+3),s="_i",r=t.startsWith(".")?t.slice(1):t,f=omniAst.builders.identifier(s);if(r){let c=N(r);for(let a of c)a.type==="key"&&(f=omniAst.builders.memberExpression(f,omniAst.builders.identifier(a.value),false,true));}if(o.includes("[*]")){let c=X(f,o);return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],c)])}let u=o.startsWith(".")?o.slice(1):o;if(u){let c=N(u);for(let a of c)a.type==="key"&&(f=omniAst.builders.memberExpression(f,omniAst.builders.identifier(a.value),false,true));}return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],f)])}function vn(n,e,i,t){let o;if(typeof n.$if=="string"){let f=n.$if.startsWith("!"),u=f?n.$if.slice(1):n.$if,c=w(u,e,t);o=f?omniAst.builders.unaryExpression("!",c):c;}else o=d(n.$if,e,i,t);let s=d(n.then,e,i,t),r=n.else!==void 0?d(n.else,e,i,t):omniAst.builders.identifier("undefined");return omniAst.builders.conditionalExpression(o,s,r)}function Nn(n,e,i,t){let o=t?omniAst.builders.identifier(n.$fn):omniAst.builders.memberExpression(omniAst.builders.identifier(i),omniAst.builders.identifier(n.$fn),false,false);if(n.args===void 0)return o;let s=n.args.map(r=>d(r,e,i,t));return omniAst.builders.callExpression(o,s)}function jn(n,e,i,t){if(n.length===0)return omniAst.builders.identifier("undefined");if(n.length===1)return d(n[0],e,i,t);let o=d(n[0],e,i,t);for(let s=1;s<n.length;s++){let r=d(n[s],e,i,t);o=omniAst.builders.callExpression(r,[o]);}return o}function Gn(n,e,i,t){let o=w(n.path,e,t),s=n.value!==void 0?m(n.value)?w(n.value.$,e,t):d(n.value,e,i,t):omniAst.builders.literal(null),r=Rn[n.op];if(r)return omniAst.builders.binaryExpression(r,o,s);switch(n.op){case "in":return omniAst.builders.callExpression(omniAst.builders.memberExpression(s,omniAst.builders.identifier("includes")),[o]);case "notIn":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(s,omniAst.builders.identifier("includes")),[o]));case "contains":return omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("includes"),false,true),[s]);case "notContains":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("includes"),false,true),[s]));case "exists":return omniAst.builders.binaryExpression("!=",o,omniAst.builders.literal(null));case "notExists":return omniAst.builders.binaryExpression("==",o,omniAst.builders.literal(null));case "matches":return omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[s]),omniAst.builders.identifier("test")),[o]);case "notMatches":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[s]),omniAst.builders.identifier("test")),[o]));case "startsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("startsWith"),false,true),[s]);case "endsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("endsWith"),false,true),[s]);default:return omniAst.builders.binaryExpression("===",o,s)}}function Wn(n,e,i,t){let{logic:o,conditions:s}=n,r=o==="AND"?"&&":"||";if(s.length===0)return omniAst.builders.literal(o==="AND");if(s.length===1)return d(s[0],e,i,t);let f=d(s[0],e,i,t);for(let u=1;u<s.length;u++){let c=d(s[u],e,i,t);f=omniAst.builders.logicalExpression(r,f,c);}return f}function N(n){let e=[],i=n.length,t=0,o="";for(;t<i;){let s=n[t];if(s===".")o&&(e.push({type:"key",value:o}),o=""),t++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),t++;let r=t;for(;t<i&&n[t]!=="]";)t++;let f=n.slice(r,t);if(t++,f!=="*"){let u=parseInt(f,10);e.push({type:"index",value:isNaN(u)?f:u});}}else o+=s,t++;}return o&&e.push({type:"key",value:o}),e}function Z(n,e=[D]){return omniAst.builders.arrowFunctionExpression(e.map(i=>omniAst.builders.identifier(i)),n)}function G(n){let e=new Set;return b(n,e),e}function b(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let t of n)b(t,e);return}if(m(n))return;if(E(n)){b(n.$if,e),b(n.then,e),n.else!==void 0&&b(n.else,e);return}if(C(n)){for(let t of n.$pipe)b(t,e);return}if(T(n)){if(e.add(n.$fn),n.args)for(let t of n.args)b(t,e);return}if(g(n)){n.value!==void 0&&typeof n.value=="object"&&b(n.value,e);return}if(y(n)){for(let t of n.conditions)b(t,e);return}let i=n;for(let t of Object.keys(i))b(i[t],e);}function W(n){let e=new Set;for(let i of n){let t=i.indexOf("."),o=i.indexOf("["),s=i.length;t!==-1&&(s=Math.min(s,t)),o!==-1&&(s=Math.min(s,o));let r=i.slice(0,s);r&&e.add(r);}return e}function zn(n){return JSON.stringify(n)}function Dn(n,e,i){let t=j(n,{noPrefixes:true}),o=omniAst.generate(t),s=e.size>0?`const{${[...e].join(",")}}=data??{};`:"",r=i.size>0?`const{${[...i].join(",")}}=scope;`:"";return r?`(function(scope){${r}return function(data){${s}return ${o}}})`:`(function(){return function(data){${s}return ${o}}})`}function M(n,e={}){let{scope:i={},returnCode:t=false}=e,o=S(n),s=W(o),r=G(n),f=zn(n),u=Dn(n,s,r);if(t)return {code:u,deps:o,hash:f,dataRoots:[...s],scopeFns:[...r]};let c;try{c=new Function(`return ${u}`)()(i);}catch(a){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${a instanceof Error?a.message:String(a)}`)}return {fn:c,deps:o,hash:f}}function nn(n,e,i={}){let{fn:t}=M(n,i);return t(e)}var ye="0.1.1";exports.ExpressionCache=v;exports.VERSION=ye;exports.assertValid=bn;exports.builders=Q;exports.cache=J;exports.cached=An;exports.clearPathCache=cn;exports.compile=F;exports.compileAST=M;exports.compilePath=O;exports.dslToAST=j;exports.evaluate=Cn;exports.evaluateAST=nn;exports.extractDataRoots=W;exports.extractDeps=S;exports.extractScopeFns=G;exports.get=un;exports.getPathCacheSize=an;exports.hasDeps=dn;exports.hasWildcard=L;exports.isCondition=g;exports.isConditionExpr=on;exports.isConditionGroup=y;exports.isConditional=E;exports.isFn=T;exports.isLiteral=P;exports.isPipe=C;exports.isPure=mn;exports.isRef=m;exports.isValid=$n;exports.normalizePath=k;exports.validate=z;exports.wrapInFunction=Z;
|
package/dist/index.d.cts
CHANGED
|
@@ -48,10 +48,17 @@ interface PipeExpr {
|
|
|
48
48
|
type Literal = string | number | boolean | null | Literal[] | {
|
|
49
49
|
[key: string]: Literal;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Callback function - used as argument in $fn (e.g., predicates, mappers)
|
|
53
|
+
* Not serializable to JSON, but valid in code.
|
|
54
|
+
* @example (item) => item.active
|
|
55
|
+
* @example (a, b) => a + b
|
|
56
|
+
*/
|
|
57
|
+
type CallbackFn = (...args: any[]) => unknown;
|
|
51
58
|
/**
|
|
52
59
|
* Union of all expression types
|
|
53
60
|
*/
|
|
54
|
-
type Expression = Literal | RefExpr | ConditionalExpr | FnExpr | PipeExpr | ConditionExpr;
|
|
61
|
+
type Expression = Literal | RefExpr | ConditionalExpr | FnExpr | PipeExpr | ConditionExpr | CallbackFn;
|
|
55
62
|
/**
|
|
56
63
|
* Compiled expression function
|
|
57
64
|
*/
|
|
@@ -91,7 +98,7 @@ interface ValidationResult {
|
|
|
91
98
|
* Function scope - functions available to $fn expressions
|
|
92
99
|
* @example { add, subtract, multiply, filter, map, sum }
|
|
93
100
|
*/
|
|
94
|
-
type Scope = Record<string, (...args:
|
|
101
|
+
type Scope = Record<string, (...args: any[]) => any>;
|
|
95
102
|
/**
|
|
96
103
|
* Options for compilation
|
|
97
104
|
*/
|
|
@@ -349,6 +356,104 @@ declare function assertValid(expr: Expression, options?: ValidateOptions): void;
|
|
|
349
356
|
*/
|
|
350
357
|
declare function isValid(expr: Expression, options?: ValidateOptions): boolean;
|
|
351
358
|
|
|
359
|
+
/**
|
|
360
|
+
* @statedelta-libs/expressions - Builders
|
|
361
|
+
*
|
|
362
|
+
* Funções declarativas para construir expressões.
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* ```typescript
|
|
366
|
+
* import { $, $fn, $if, $pipe } from "@statedelta-libs/expressions";
|
|
367
|
+
*
|
|
368
|
+
* // Path reference
|
|
369
|
+
* $("player.hp") // { $: "player.hp" }
|
|
370
|
+
*
|
|
371
|
+
* // Function call
|
|
372
|
+
* $fn("add", [$("a"), $("b")]) // { $fn: "add", args: [{ $: "a" }, { $: "b" }] }
|
|
373
|
+
*
|
|
374
|
+
* // Conditional
|
|
375
|
+
* $if(condition, "then", "else")
|
|
376
|
+
*
|
|
377
|
+
* // Pipe
|
|
378
|
+
* $pipe($("items"), $fn("filter", [pred]), $fn("sum"))
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Create a path reference expression.
|
|
384
|
+
*
|
|
385
|
+
* @param path - Dot-notation path to value
|
|
386
|
+
* @returns RefExpr
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* $("player.hp") // { $: "player.hp" }
|
|
390
|
+
* $("items[0].price") // { $: "items[0].price" }
|
|
391
|
+
* $("items[*].price") // { $: "items[*].price" } (wildcard)
|
|
392
|
+
*/
|
|
393
|
+
declare function $(path: string): RefExpr;
|
|
394
|
+
/**
|
|
395
|
+
* Alias for $ (ref builder)
|
|
396
|
+
*/
|
|
397
|
+
declare const ref: typeof $;
|
|
398
|
+
/**
|
|
399
|
+
* Create a function call expression.
|
|
400
|
+
*
|
|
401
|
+
* @param name - Function name (from scope)
|
|
402
|
+
* @param args - Arguments (can be expressions)
|
|
403
|
+
* @returns FnExpr
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* $fn("add", [$("a"), $("b")]) // { $fn: "add", args: [...] }
|
|
407
|
+
* $fn("multiply", [10, $("x")]) // literal + expression
|
|
408
|
+
* $fn("sum") // no args - returns function reference
|
|
409
|
+
* $fn("now", []) // empty args - calls function
|
|
410
|
+
*/
|
|
411
|
+
declare function $fn(name: string, args?: Expression[]): FnExpr;
|
|
412
|
+
/**
|
|
413
|
+
* Alias for $fn (function builder)
|
|
414
|
+
*/
|
|
415
|
+
declare const fn: typeof $fn;
|
|
416
|
+
/**
|
|
417
|
+
* Create a conditional expression.
|
|
418
|
+
*
|
|
419
|
+
* @param condition - Condition to evaluate
|
|
420
|
+
* @param thenExpr - Value if true
|
|
421
|
+
* @param elseExpr - Value if false (optional)
|
|
422
|
+
* @returns ConditionalExpr
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* $if(condition, "alive", "dead")
|
|
426
|
+
* $if($("isVip"), 0.2, 0)
|
|
427
|
+
* $if(gte("hp", 0), $("hp"), 0)
|
|
428
|
+
*/
|
|
429
|
+
declare function $if(condition: Expression, thenExpr: Expression, elseExpr?: Expression): ConditionalExpr;
|
|
430
|
+
/**
|
|
431
|
+
* Create a pipe expression (composition with initial value).
|
|
432
|
+
*
|
|
433
|
+
* @param steps - Pipeline steps (first is input, rest are transformers)
|
|
434
|
+
* @returns PipeExpr
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
* $pipe($("items"), $fn("filter", [pred]), $fn("sum"))
|
|
438
|
+
* $pipe($("name"), $fn("uppercase"), $fn("trim"))
|
|
439
|
+
*/
|
|
440
|
+
declare function $pipe(...steps: Expression[]): PipeExpr;
|
|
441
|
+
/**
|
|
442
|
+
* Alias for $pipe (pipe builder)
|
|
443
|
+
*/
|
|
444
|
+
declare const pipe: typeof $pipe;
|
|
445
|
+
|
|
446
|
+
declare const builders_$: typeof $;
|
|
447
|
+
declare const builders_$fn: typeof $fn;
|
|
448
|
+
declare const builders_$if: typeof $if;
|
|
449
|
+
declare const builders_$pipe: typeof $pipe;
|
|
450
|
+
declare const builders_fn: typeof fn;
|
|
451
|
+
declare const builders_pipe: typeof pipe;
|
|
452
|
+
declare const builders_ref: typeof ref;
|
|
453
|
+
declare namespace builders {
|
|
454
|
+
export { builders_$ as $, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
455
|
+
}
|
|
456
|
+
|
|
352
457
|
/**
|
|
353
458
|
* @statedelta-libs/expressions - DSL to AST Transformer
|
|
354
459
|
*
|
|
@@ -544,6 +649,6 @@ declare function evaluateAST<T = unknown, R = unknown>(expr: Expression, data: T
|
|
|
544
649
|
* ); // 3
|
|
545
650
|
* ```
|
|
546
651
|
*/
|
|
547
|
-
declare const VERSION = "0.
|
|
652
|
+
declare const VERSION = "0.1.1";
|
|
548
653
|
|
|
549
|
-
export { type AccessorFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type ConditionalExpr, type Expression, ExpressionCache, type FnExpr, type Literal, type PathGetter, type PipeExpr, type RefExpr, type Scope, type TransformOptions, VERSION, type ValidateOptions, type ValidationResult, assertValid, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalizePath, validate, wrapInFunction };
|
|
654
|
+
export { type AccessorFn, type CallbackFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type ConditionalExpr, type Expression, ExpressionCache, type FnExpr, type Literal, type PathGetter, type PipeExpr, type RefExpr, type Scope, type TransformOptions, VERSION, type ValidateOptions, type ValidationResult, assertValid, builders, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalizePath, validate, wrapInFunction };
|
package/dist/index.d.ts
CHANGED
|
@@ -48,10 +48,17 @@ interface PipeExpr {
|
|
|
48
48
|
type Literal = string | number | boolean | null | Literal[] | {
|
|
49
49
|
[key: string]: Literal;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Callback function - used as argument in $fn (e.g., predicates, mappers)
|
|
53
|
+
* Not serializable to JSON, but valid in code.
|
|
54
|
+
* @example (item) => item.active
|
|
55
|
+
* @example (a, b) => a + b
|
|
56
|
+
*/
|
|
57
|
+
type CallbackFn = (...args: any[]) => unknown;
|
|
51
58
|
/**
|
|
52
59
|
* Union of all expression types
|
|
53
60
|
*/
|
|
54
|
-
type Expression = Literal | RefExpr | ConditionalExpr | FnExpr | PipeExpr | ConditionExpr;
|
|
61
|
+
type Expression = Literal | RefExpr | ConditionalExpr | FnExpr | PipeExpr | ConditionExpr | CallbackFn;
|
|
55
62
|
/**
|
|
56
63
|
* Compiled expression function
|
|
57
64
|
*/
|
|
@@ -91,7 +98,7 @@ interface ValidationResult {
|
|
|
91
98
|
* Function scope - functions available to $fn expressions
|
|
92
99
|
* @example { add, subtract, multiply, filter, map, sum }
|
|
93
100
|
*/
|
|
94
|
-
type Scope = Record<string, (...args:
|
|
101
|
+
type Scope = Record<string, (...args: any[]) => any>;
|
|
95
102
|
/**
|
|
96
103
|
* Options for compilation
|
|
97
104
|
*/
|
|
@@ -349,6 +356,104 @@ declare function assertValid(expr: Expression, options?: ValidateOptions): void;
|
|
|
349
356
|
*/
|
|
350
357
|
declare function isValid(expr: Expression, options?: ValidateOptions): boolean;
|
|
351
358
|
|
|
359
|
+
/**
|
|
360
|
+
* @statedelta-libs/expressions - Builders
|
|
361
|
+
*
|
|
362
|
+
* Funções declarativas para construir expressões.
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* ```typescript
|
|
366
|
+
* import { $, $fn, $if, $pipe } from "@statedelta-libs/expressions";
|
|
367
|
+
*
|
|
368
|
+
* // Path reference
|
|
369
|
+
* $("player.hp") // { $: "player.hp" }
|
|
370
|
+
*
|
|
371
|
+
* // Function call
|
|
372
|
+
* $fn("add", [$("a"), $("b")]) // { $fn: "add", args: [{ $: "a" }, { $: "b" }] }
|
|
373
|
+
*
|
|
374
|
+
* // Conditional
|
|
375
|
+
* $if(condition, "then", "else")
|
|
376
|
+
*
|
|
377
|
+
* // Pipe
|
|
378
|
+
* $pipe($("items"), $fn("filter", [pred]), $fn("sum"))
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Create a path reference expression.
|
|
384
|
+
*
|
|
385
|
+
* @param path - Dot-notation path to value
|
|
386
|
+
* @returns RefExpr
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* $("player.hp") // { $: "player.hp" }
|
|
390
|
+
* $("items[0].price") // { $: "items[0].price" }
|
|
391
|
+
* $("items[*].price") // { $: "items[*].price" } (wildcard)
|
|
392
|
+
*/
|
|
393
|
+
declare function $(path: string): RefExpr;
|
|
394
|
+
/**
|
|
395
|
+
* Alias for $ (ref builder)
|
|
396
|
+
*/
|
|
397
|
+
declare const ref: typeof $;
|
|
398
|
+
/**
|
|
399
|
+
* Create a function call expression.
|
|
400
|
+
*
|
|
401
|
+
* @param name - Function name (from scope)
|
|
402
|
+
* @param args - Arguments (can be expressions)
|
|
403
|
+
* @returns FnExpr
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* $fn("add", [$("a"), $("b")]) // { $fn: "add", args: [...] }
|
|
407
|
+
* $fn("multiply", [10, $("x")]) // literal + expression
|
|
408
|
+
* $fn("sum") // no args - returns function reference
|
|
409
|
+
* $fn("now", []) // empty args - calls function
|
|
410
|
+
*/
|
|
411
|
+
declare function $fn(name: string, args?: Expression[]): FnExpr;
|
|
412
|
+
/**
|
|
413
|
+
* Alias for $fn (function builder)
|
|
414
|
+
*/
|
|
415
|
+
declare const fn: typeof $fn;
|
|
416
|
+
/**
|
|
417
|
+
* Create a conditional expression.
|
|
418
|
+
*
|
|
419
|
+
* @param condition - Condition to evaluate
|
|
420
|
+
* @param thenExpr - Value if true
|
|
421
|
+
* @param elseExpr - Value if false (optional)
|
|
422
|
+
* @returns ConditionalExpr
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* $if(condition, "alive", "dead")
|
|
426
|
+
* $if($("isVip"), 0.2, 0)
|
|
427
|
+
* $if(gte("hp", 0), $("hp"), 0)
|
|
428
|
+
*/
|
|
429
|
+
declare function $if(condition: Expression, thenExpr: Expression, elseExpr?: Expression): ConditionalExpr;
|
|
430
|
+
/**
|
|
431
|
+
* Create a pipe expression (composition with initial value).
|
|
432
|
+
*
|
|
433
|
+
* @param steps - Pipeline steps (first is input, rest are transformers)
|
|
434
|
+
* @returns PipeExpr
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
* $pipe($("items"), $fn("filter", [pred]), $fn("sum"))
|
|
438
|
+
* $pipe($("name"), $fn("uppercase"), $fn("trim"))
|
|
439
|
+
*/
|
|
440
|
+
declare function $pipe(...steps: Expression[]): PipeExpr;
|
|
441
|
+
/**
|
|
442
|
+
* Alias for $pipe (pipe builder)
|
|
443
|
+
*/
|
|
444
|
+
declare const pipe: typeof $pipe;
|
|
445
|
+
|
|
446
|
+
declare const builders_$: typeof $;
|
|
447
|
+
declare const builders_$fn: typeof $fn;
|
|
448
|
+
declare const builders_$if: typeof $if;
|
|
449
|
+
declare const builders_$pipe: typeof $pipe;
|
|
450
|
+
declare const builders_fn: typeof fn;
|
|
451
|
+
declare const builders_pipe: typeof pipe;
|
|
452
|
+
declare const builders_ref: typeof ref;
|
|
453
|
+
declare namespace builders {
|
|
454
|
+
export { builders_$ as $, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
455
|
+
}
|
|
456
|
+
|
|
352
457
|
/**
|
|
353
458
|
* @statedelta-libs/expressions - DSL to AST Transformer
|
|
354
459
|
*
|
|
@@ -544,6 +649,6 @@ declare function evaluateAST<T = unknown, R = unknown>(expr: Expression, data: T
|
|
|
544
649
|
* ); // 3
|
|
545
650
|
* ```
|
|
546
651
|
*/
|
|
547
|
-
declare const VERSION = "0.
|
|
652
|
+
declare const VERSION = "0.1.1";
|
|
548
653
|
|
|
549
|
-
export { type AccessorFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type ConditionalExpr, type Expression, ExpressionCache, type FnExpr, type Literal, type PathGetter, type PipeExpr, type RefExpr, type Scope, type TransformOptions, VERSION, type ValidateOptions, type ValidationResult, assertValid, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalizePath, validate, wrapInFunction };
|
|
654
|
+
export { type AccessorFn, type CallbackFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type ConditionalExpr, type Expression, ExpressionCache, type FnExpr, type Literal, type PathGetter, type PipeExpr, type RefExpr, type Scope, type TransformOptions, VERSION, type ValidateOptions, type ValidationResult, assertValid, builders, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalizePath, validate, wrapInFunction };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {isRef,compile,validate}from'@statedelta-libs/conditions';import {builders,generate}from'omni-ast';var m=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,E=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,T=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",A=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),I=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),g=n=>n!==null&&typeof n=="object"&&"path"in n&&"op"in n&&I.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),y=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,U=n=>g(n)||y(n),z=n=>{if(n===null)return true;let e=typeof n;if(e==="string"||e==="number"||e==="boolean"||Array.isArray(n))return true;if(e==="object"&&n!==null){let o=n,t="path"in o&&"op"in o&&I.has(o.op);return !("$"in o)&&!("$if"in o)&&!("$fn"in o)&&!("$pipe"in o)&&!t&&!("logic"in o)}return false};var R=new Map;function V(n){let e=[],o=n.length,t=0,i="";for(;t<o;){let s=n[t];if(s===".")i&&(e.push({type:"key",value:i}),i=""),t++;else if(s==="["){i&&(e.push({type:"key",value:i}),i=""),t++;let r=t;for(;t<o&&n[t]!=="]";)t++;let f=n.slice(r,t);if(t++,f==="*")e.push({type:"wildcard",value:"*"});else {let c=parseInt(f,10);e.push({type:"index",value:isNaN(c)?f:c});}}else i+=s,t++;}return i&&e.push({type:"key",value:i}),e}function L(n){return n.includes("[*]")}function O(n){let e=R.get(n);return e||(e=L(n)?Z(n):X(n),R.set(n,e),e)}function X(n){if(!n.includes(".")&&!n.includes("["))return i=>i?.[n];let e=V(n),o=e.length;if(o===2){let[i,s]=e,r=i.value,f=s.value;return c=>c?.[r]?.[f]}if(o===3){let[i,s,r]=e,f=i.value,c=s.value,u=r.value;return a=>a?.[f]?.[c]?.[u]}let t=e.map(i=>i.value);return i=>{let s=i;for(let r=0;r<o&&s!=null;r++)s=s[t[r]];return s}}function Z(n){let e=V(n),o=[];for(let t=0;t<e.length;t++)e[t].type==="wildcard"&&o.push(t);return o.length===1?nn(e,o[0]):en(e,o)}function nn(n,e){let o=n.slice(0,e).map(r=>r.value),t=n.slice(e+1).map(r=>r.value),i=o.length,s=t.length;if(s===0){if(i===1){let r=o[0];return f=>f?.[r]}return r=>{let f=r;for(let c=0;c<i&&f!=null;c++)f=f[o[c]];return f}}if(s===1){let r=t[0];if(i===1){let f=o[0];return c=>{let u=c?.[f];if(Array.isArray(u))return u.map(a=>a?.[r])}}return f=>{let c=f;for(let u=0;u<i&&c!=null;u++)c=c[o[u]];if(Array.isArray(c))return c.map(u=>u?.[r])}}return r=>{let f=r;for(let c=0;c<i&&f!=null;c++)f=f[o[c]];if(Array.isArray(f))return f.map(c=>{let u=c;for(let a=0;a<s&&u!=null;a++)u=u[t[a]];return u})}}function en(n,e){let o=[],t=0;for(let s=0;s<e.length;s++){let r=e[s],f=s===e.length-1,c=n.slice(t,r).map(u=>u.value);c.length>0&&o.push({type:"access",keys:c}),o.push({type:f?"map":"flatMap",keys:[]}),t=r+1;}let i=n.slice(t).map(s=>s.value);return s=>{let r=s;for(let f of o){if(r==null)return;if(f.type==="access")for(let c of f.keys){if(r==null)return;r=r[c];}else if(f.type==="flatMap"){if(!Array.isArray(r))return;r=r.flatMap(c=>{let u=c;return Array.isArray(u)?u:[u]});}else if(f.type==="map"){if(!Array.isArray(r))return;i.length>0&&(r=r.map(c=>{let u=c;for(let a of i){if(u==null)return;u=u[a];}return u}));}}return r}}function tn(n,e){return O(e)(n)}function w(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function on(){R.clear();}function rn(){return R.size}function k(n){let e=new Set;return S(n,e),Array.from(e)}function S(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let i=0;i<n.length;i++)S(n[i],e);return}if(m(n)){e.add(w(n.$));return}if(E(n)){if(typeof n.$if=="string"){let i=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(w(i));}else S(n.$if,e);S(n.then,e),n.else!==void 0&&S(n.else,e);return}if(A(n)){for(let i=0;i<n.$pipe.length;i++)S(n.$pipe[i],e);return}if(T(n)){if(n.args)for(let i=0;i<n.args.length;i++)S(n.args[i],e);return}if(g(n)){e.add(w(n.path)),n.value!==void 0&&isRef(n.value)&&e.add(w(n.value.$));return}if(y(n)){for(let i=0;i<n.conditions.length;i++)S(n.conditions[i],e);return}let o=n,t=Object.keys(o);for(let i=0;i<t.length;i++)S(o[t[i]],e);}function ln(n){return k(n).length>0}function fn(n){return k(n).length===0}function cn(n){return JSON.stringify(n)}function F(n,e={}){let o=e.scope??{},t=e.accessor,i=C(n,o,t),s=k(n),r=cn(n);return {fn:i,deps:s,hash:r}}function C(n,e,o){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let t=n.map(i=>C(i,e,o));return i=>t.map(s=>s(i))}if(m(n))return un(n,o);if(E(n))return an(n,e,o);if(A(n))return pn(n,e,o);if(T(n))return dn(n,e,o);if(g(n))return compile(n,o?{accessor:o}:void 0);if(y(n))return compile(n,o?{accessor:o}:void 0);if(z(n)){let t=n,i=Object.keys(t),s=i.map(r=>C(t[r],e,o));return r=>{let f={};for(let c=0;c<i.length;c++)f[i[c]]=s[c](r);return f}}return ()=>n}function q(n,e){return e?o=>e(n,o):O(n)}function un(n,e){return q(n.$,e)}function an(n,e,o){let t;if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if,f=q(r,o);t=n.$if.startsWith("!")?u=>!f(u):u=>!!f(u);}else {let r=C(n.$if,e,o);t=f=>!!r(f);}let i=C(n.then,e,o),s=n.else!==void 0?C(n.else,e,o):()=>{};return r=>t(r)?i(r):s(r)}function pn(n,e,o){let t=n.$pipe;if(t.length===0)return ()=>{};if(t.length===1)return C(t[0],e,o);let i=C(t[0],e,o),s=t.slice(1).map(f=>C(f,e,o)),r=s.length;if(r===1){let[f]=s;return c=>{let u=i(c),a=f(c);return typeof a=="function"?a(u):a}}if(r===2){let[f,c]=s;return u=>{let a=i(u),p=f(u);return a=typeof p=="function"?p(a):p,p=c(u),typeof p=="function"?p(a):p}}if(r===3){let[f,c,u]=s;return a=>{let p=i(a),h=f(a);return p=typeof h=="function"?h(p):h,h=c(a),p=typeof h=="function"?h(p):h,h=u(a),typeof h=="function"?h(p):h}}return f=>{let c=i(f);for(let u=0;u<r;u++){let a=s[u](f);c=typeof a=="function"?a(c):a;}return c}}function dn(n,e,o){let t=n.$fn,i=n.args;if(i===void 0)return ()=>{let f=e[t];if(!f)throw new Error(`Function not found in scope: ${t}`);return f};let s=i.map(f=>C(f,e,o)),r=s.length;if(r===0)return f=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c()};if(r===1){let[f]=s;return c=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u(f(c))}}if(r===2){let[f,c]=s;return u=>{let a=e[t];if(!a)throw new Error(`Function not found in scope: ${t}`);return a(f(u),c(u))}}if(r===3){let[f,c,u]=s;return a=>{let p=e[t];if(!p)throw new Error(`Function not found in scope: ${t}`);return p(f(a),c(a),u(a))}}return f=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c(...s.map(u=>u(f)))}}function mn(n,e,o={}){return F(n,o).fn(e)}var v=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,o={}){let t=JSON.stringify(e),i=this.cache.get(t);if(i)return this.cache.delete(t),this.cache.set(t,i),i;let s=F(e,o);if(this.cache.size>=this._maxSize){let r=this.cache.keys().next().value;r&&this.cache.delete(r);}return this.cache.set(t,s),s}has(e){return this.cache.has(JSON.stringify(e))}delete(e){return this.cache.delete(JSON.stringify(e))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(e){for(this._maxSize=e;this.cache.size>this._maxSize;){let o=this.cache.keys().next().value;o&&this.cache.delete(o);}}},J=new v;function gn(n,e={}){return J.get(n,e)}function P(n,e="root",o={}){let t=[];return $(n,e,t,o),{valid:t.length===0,errors:t}}function $(n,e,o,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r=0;r<n.length;r++)$(n[r],`${e}[${r}]`,o,t);return}if(m(n)){(!n.$||typeof n.$!="string")&&o.push(`${e}: invalid reference, $ must be non-empty string`);return}if(E(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||o.push(`${e}.$if: empty path in string shorthand`):$(n.$if,`${e}.$if`,o,t),$(n.then,`${e}.then`,o,t),n.else!==void 0&&$(n.else,`${e}.else`,o,t);return}if(A(n)){if(!Array.isArray(n.$pipe)){o.push(`${e}.$pipe: must be an array`);return}if(n.$pipe.length===0){o.push(`${e}.$pipe: must have at least one element`);return}for(let r=0;r<n.$pipe.length;r++)$(n.$pipe[r],`${e}.$pipe[${r}]`,o,t);return}if(T(n)){if(!n.$fn||typeof n.$fn!="string"){o.push(`${e}: invalid function, $fn must be non-empty string`);return}if(t.scope&&!(n.$fn in t.scope)&&o.push(`${e}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))o.push(`${e}.args: must be an array`);else for(let r=0;r<n.args.length;r++)$(n.args[r],`${e}.args[${r}]`,o,t);return}if(g(n)){let r=validate(n,e);r.valid||o.push(...r.errors);return}if(y(n)){let r=validate(n,e);r.valid||o.push(...r.errors);return}let i=n,s=Object.keys(i);for(let r=0;r<s.length;r++){let f=s[r];$(i[f],`${e}.${f}`,o,t);}}function yn(n,e={}){let o=P(n,"root",e);if(!o.valid)throw new Error(`Invalid expression: ${o.errors.join("; ")}`)}function hn(n,e={}){return P(n,"root",e).valid}var D="data",K="scope",En={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function j(n,e={}){let{dataParam:o=D,scopeParam:t=K,noPrefixes:i=false}=e;return d(n,o,t,i)}function d(n,e,o,t){if(n===null)return builders.literal(null);if(typeof n=="string")return builders.literal(n);if(typeof n=="number")return builders.literal(n);if(typeof n=="boolean")return builders.literal(n);if(Array.isArray(n))return builders.arrayExpression(n.map(i=>d(i,e,o,t)));if(m(n))return Tn(n.$,e,t);if(E(n))return Cn(n,e,o,t);if(A(n))return Sn(n.$pipe,e,o,t);if(T(n))return bn(n,e,o,t);if(g(n))return $n(n,e,o,t);if(y(n))return kn(n,e,o,t);if(typeof n=="object"){let s=Object.entries(n).map(([r,f])=>builders.property(builders.identifier(r),d(f,e,o,t)));return builders.objectExpression(s)}return builders.literal(null)}function Tn(n,e,o){return n.includes("[*]")?An(n,e,o):x(n,e,o)}function x(n,e,o){let t=N(n);if(t.length===0)return o?builders.identifier("undefined"):builders.identifier(e);let i;if(o){let s=t[0];i=builders.identifier(s.value);for(let r=1;r<t.length;r++){let f=t[r];f.type==="key"?i=builders.memberExpression(i,builders.identifier(f.value),false,true):i=builders.memberExpression(i,builders.literal(f.value),true,true);}}else {i=builders.identifier(e);for(let s of t)s.type==="key"?i=builders.memberExpression(i,builders.identifier(s.value),false,true):i=builders.memberExpression(i,builders.literal(s.value),true,true);}return i}function An(n,e,o){let t=n.indexOf("[*]"),i=n.slice(0,t),s=n.slice(t+3),r;if(i?r=x(i,e,o):r=o?builders.identifier("undefined"):builders.identifier(e),!s||s==="")return r;if(s.includes("[*]"))return Y(r,s);let f="_i",c=s.startsWith(".")?s.slice(1):s,u=builders.identifier(f);if(c){let a=N(c);for(let p of a)p.type==="key"?u=builders.memberExpression(u,builders.identifier(p.value),false,true):u=builders.memberExpression(u,builders.literal(p.value),true,true);}return builders.callExpression(builders.memberExpression(r,builders.identifier("map"),false,true),[builders.arrowFunctionExpression([builders.identifier(f)],u)])}function Y(n,e){let o=e.indexOf("[*]"),t=e.slice(0,o),i=e.slice(o+3),s="_i",r=t.startsWith(".")?t.slice(1):t,f=builders.identifier(s);if(r){let u=N(r);for(let a of u)a.type==="key"&&(f=builders.memberExpression(f,builders.identifier(a.value),false,true));}if(i.includes("[*]")){let u=Y(f,i);return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],u)])}let c=i.startsWith(".")?i.slice(1):i;if(c){let u=N(c);for(let a of u)a.type==="key"&&(f=builders.memberExpression(f,builders.identifier(a.value),false,true));}return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],f)])}function Cn(n,e,o,t){let i;if(typeof n.$if=="string"){let f=n.$if.startsWith("!"),c=f?n.$if.slice(1):n.$if,u=x(c,e,t);i=f?builders.unaryExpression("!",u):u;}else i=d(n.$if,e,o,t);let s=d(n.then,e,o,t),r=n.else!==void 0?d(n.else,e,o,t):builders.identifier("undefined");return builders.conditionalExpression(i,s,r)}function bn(n,e,o,t){let i=t?builders.identifier(n.$fn):builders.memberExpression(builders.identifier(o),builders.identifier(n.$fn),false,false);if(n.args===void 0)return i;let s=n.args.map(r=>d(r,e,o,t));return builders.callExpression(i,s)}function Sn(n,e,o,t){if(n.length===0)return builders.identifier("undefined");if(n.length===1)return d(n[0],e,o,t);let i=d(n[0],e,o,t);for(let s=1;s<n.length;s++){let r=d(n[s],e,o,t);i=builders.callExpression(r,[i]);}return i}function $n(n,e,o,t){let i=x(n.path,e,t),s=n.value!==void 0?m(n.value)?x(n.value.$,e,t):d(n.value,e,o,t):builders.literal(null),r=En[n.op];if(r)return builders.binaryExpression(r,i,s);switch(n.op){case "in":return builders.callExpression(builders.memberExpression(s,builders.identifier("includes")),[i]);case "notIn":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(s,builders.identifier("includes")),[i]));case "contains":return builders.callExpression(builders.memberExpression(i,builders.identifier("includes"),false,true),[s]);case "notContains":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(i,builders.identifier("includes"),false,true),[s]));case "exists":return builders.binaryExpression("!=",i,builders.literal(null));case "notExists":return builders.binaryExpression("==",i,builders.literal(null));case "matches":return builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[s]),builders.identifier("test")),[i]);case "notMatches":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[s]),builders.identifier("test")),[i]));case "startsWith":return builders.callExpression(builders.memberExpression(i,builders.identifier("startsWith"),false,true),[s]);case "endsWith":return builders.callExpression(builders.memberExpression(i,builders.identifier("endsWith"),false,true),[s]);default:return builders.binaryExpression("===",i,s)}}function kn(n,e,o,t){let{logic:i,conditions:s}=n,r=i==="AND"?"&&":"||";if(s.length===0)return builders.literal(i==="AND");if(s.length===1)return d(s[0],e,o,t);let f=d(s[0],e,o,t);for(let c=1;c<s.length;c++){let u=d(s[c],e,o,t);f=builders.logicalExpression(r,f,u);}return f}function N(n){let e=[],o=n.length,t=0,i="";for(;t<o;){let s=n[t];if(s===".")i&&(e.push({type:"key",value:i}),i=""),t++;else if(s==="["){i&&(e.push({type:"key",value:i}),i=""),t++;let r=t;for(;t<o&&n[t]!=="]";)t++;let f=n.slice(r,t);if(t++,f!=="*"){let c=parseInt(f,10);e.push({type:"index",value:isNaN(c)?f:c});}}else i+=s,t++;}return i&&e.push({type:"key",value:i}),e}function H(n,e=[D]){return builders.arrowFunctionExpression(e.map(o=>builders.identifier(o)),n)}function G(n){let e=new Set;return b(n,e),e}function b(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let t of n)b(t,e);return}if(m(n))return;if(E(n)){b(n.$if,e),b(n.then,e),n.else!==void 0&&b(n.else,e);return}if(A(n)){for(let t of n.$pipe)b(t,e);return}if(T(n)){if(e.add(n.$fn),n.args)for(let t of n.args)b(t,e);return}if(g(n)){n.value!==void 0&&typeof n.value=="object"&&b(n.value,e);return}if(y(n)){for(let t of n.conditions)b(t,e);return}let o=n;for(let t of Object.keys(o))b(o[t],e);}function W(n){let e=new Set;for(let o of n){let t=o.indexOf("."),i=o.indexOf("["),s=o.length;t!==-1&&(s=Math.min(s,t)),i!==-1&&(s=Math.min(s,i));let r=o.slice(0,s);r&&e.add(r);}return e}function xn(n){return JSON.stringify(n)}function Rn(n,e,o){let t=j(n,{noPrefixes:true}),i=generate(t),s=e.size>0?`const{${[...e].join(",")}}=data??{};`:"",r=o.size>0?`const{${[...o].join(",")}}=scope;`:"";return r?`(function(scope){${r}return function(data){${s}return ${i}}})`:`(function(){return function(data){${s}return ${i}}})`}function M(n,e={}){let{scope:o={},returnCode:t=false}=e,i=k(n),s=W(i),r=G(n),f=xn(n),c=Rn(n,s,r);if(t)return {code:c,deps:i,hash:f,dataRoots:[...s],scopeFns:[...r]};let u;try{u=new Function(`return ${c}`)()(o);}catch(a){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${a instanceof Error?a.message:String(a)}`)}return {fn:u,deps:i,hash:f}}function Q(n,e,o={}){let{fn:t}=M(n,o);return t(e)}var re="0.0.3";export{v as ExpressionCache,re as VERSION,yn as assertValid,J as cache,gn as cached,on as clearPathCache,F as compile,M as compileAST,O as compilePath,j as dslToAST,mn as evaluate,Q as evaluateAST,W as extractDataRoots,k as extractDeps,G as extractScopeFns,tn as get,rn as getPathCacheSize,ln as hasDeps,L as hasWildcard,g as isCondition,U as isConditionExpr,y as isConditionGroup,E as isConditional,T as isFn,z as isLiteral,A as isPipe,fn as isPure,m as isRef,hn as isValid,w as normalizePath,P as validate,H as wrapInFunction};
|
|
1
|
+
import {isRef,compile,validate}from'@statedelta-libs/conditions';import {builders,generate}from'omni-ast';var en=Object.defineProperty;var tn=(n,e)=>{for(var i in e)en(n,i,{get:e[i],enumerable:true});};var m=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,E=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,T=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",C=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),I=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),g=n=>n!==null&&typeof n=="object"&&"path"in n&&"op"in n&&I.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),y=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,on=n=>g(n)||y(n),P=n=>{if(n===null)return true;let e=typeof n;if(e==="string"||e==="number"||e==="boolean"||Array.isArray(n))return true;if(e==="object"&&n!==null){let i=n,t="path"in i&&"op"in i&&I.has(i.op);return !("$"in i)&&!("$if"in i)&&!("$fn"in i)&&!("$pipe"in i)&&!t&&!("logic"in i)}return false};var R=new Map;function V(n){let e=[],i=n.length,t=0,o="";for(;t<i;){let s=n[t];if(s===".")o&&(e.push({type:"key",value:o}),o=""),t++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),t++;let r=t;for(;t<i&&n[t]!=="]";)t++;let f=n.slice(r,t);if(t++,f==="*")e.push({type:"wildcard",value:"*"});else {let u=parseInt(f,10);e.push({type:"index",value:isNaN(u)?f:u});}}else o+=s,t++;}return o&&e.push({type:"key",value:o}),e}function L(n){return n.includes("[*]")}function O(n){let e=R.get(n);return e||(e=L(n)?sn(n):rn(n),R.set(n,e),e)}function rn(n){if(!n.includes(".")&&!n.includes("["))return o=>o?.[n];let e=V(n),i=e.length;if(i===2){let[o,s]=e,r=o.value,f=s.value;return u=>u?.[r]?.[f]}if(i===3){let[o,s,r]=e,f=o.value,u=s.value,c=r.value;return a=>a?.[f]?.[u]?.[c]}let t=e.map(o=>o.value);return o=>{let s=o;for(let r=0;r<i&&s!=null;r++)s=s[t[r]];return s}}function sn(n){let e=V(n),i=[];for(let t=0;t<e.length;t++)e[t].type==="wildcard"&&i.push(t);return i.length===1?ln(e,i[0]):fn(e,i)}function ln(n,e){let i=n.slice(0,e).map(r=>r.value),t=n.slice(e+1).map(r=>r.value),o=i.length,s=t.length;if(s===0){if(o===1){let r=i[0];return f=>f?.[r]}return r=>{let f=r;for(let u=0;u<o&&f!=null;u++)f=f[i[u]];return f}}if(s===1){let r=t[0];if(o===1){let f=i[0];return u=>{let c=u?.[f];if(Array.isArray(c))return c.map(a=>a?.[r])}}return f=>{let u=f;for(let c=0;c<o&&u!=null;c++)u=u[i[c]];if(Array.isArray(u))return u.map(c=>c?.[r])}}return r=>{let f=r;for(let u=0;u<o&&f!=null;u++)f=f[i[u]];if(Array.isArray(f))return f.map(u=>{let c=u;for(let a=0;a<s&&c!=null;a++)c=c[t[a]];return c})}}function fn(n,e){let i=[],t=0;for(let s=0;s<e.length;s++){let r=e[s],f=s===e.length-1,u=n.slice(t,r).map(c=>c.value);u.length>0&&i.push({type:"access",keys:u}),i.push({type:f?"map":"flatMap",keys:[]}),t=r+1;}let o=n.slice(t).map(s=>s.value);return s=>{let r=s;for(let f of i){if(r==null)return;if(f.type==="access")for(let u of f.keys){if(r==null)return;r=r[u];}else if(f.type==="flatMap"){if(!Array.isArray(r))return;r=r.flatMap(u=>{let c=u;return Array.isArray(c)?c:[c]});}else if(f.type==="map"){if(!Array.isArray(r))return;o.length>0&&(r=r.map(u=>{let c=u;for(let a of o){if(c==null)return;c=c[a];}return c}));}}return r}}function un(n,e){return O(e)(n)}function k(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function cn(){R.clear();}function an(){return R.size}function S(n){let e=new Set;return $(n,e),Array.from(e)}function $(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let o=0;o<n.length;o++)$(n[o],e);return}if(m(n)){e.add(k(n.$));return}if(E(n)){if(typeof n.$if=="string"){let o=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(k(o));}else $(n.$if,e);$(n.then,e),n.else!==void 0&&$(n.else,e);return}if(C(n)){for(let o=0;o<n.$pipe.length;o++)$(n.$pipe[o],e);return}if(T(n)){if(n.args)for(let o=0;o<n.args.length;o++)$(n.args[o],e);return}if(g(n)){e.add(k(n.path)),n.value!==void 0&&isRef(n.value)&&e.add(k(n.value.$));return}if(y(n)){for(let o=0;o<n.conditions.length;o++)$(n.conditions[o],e);return}let i=n,t=Object.keys(i);for(let o=0;o<t.length;o++)$(i[t[o]],e);}function dn(n){return S(n).length>0}function mn(n){return S(n).length===0}function gn(n){return JSON.stringify(n)}function F(n,e={}){let i=e.scope??{},t=e.accessor,o=A(n,i,t),s=S(n),r=gn(n);return {fn:o,deps:s,hash:r}}function A(n,e,i){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let t=n.map(o=>A(o,e,i));return o=>t.map(s=>s(o))}if(m(n))return yn(n,i);if(E(n))return hn(n,e,i);if(C(n))return En(n,e,i);if(T(n))return Tn(n,e,i);if(g(n))return compile(n,i?{accessor:i}:void 0);if(y(n))return compile(n,i?{accessor:i}:void 0);if(P(n)){let t=n,o=Object.keys(t),s=o.map(r=>A(t[r],e,i));return r=>{let f={};for(let u=0;u<o.length;u++)f[o[u]]=s[u](r);return f}}return ()=>n}function q(n,e){return e?i=>e(n,i):O(n)}function yn(n,e){return q(n.$,e)}function hn(n,e,i){let t;if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if,f=q(r,i);t=n.$if.startsWith("!")?c=>!f(c):c=>!!f(c);}else {let r=A(n.$if,e,i);t=f=>!!r(f);}let o=A(n.then,e,i),s=n.else!==void 0?A(n.else,e,i):()=>{};return r=>t(r)?o(r):s(r)}function En(n,e,i){let t=n.$pipe;if(t.length===0)return ()=>{};if(t.length===1)return A(t[0],e,i);let o=A(t[0],e,i),s=t.slice(1).map(f=>A(f,e,i)),r=s.length;if(r===1){let[f]=s;return u=>{let c=o(u),a=f(u);return typeof a=="function"?a(c):a}}if(r===2){let[f,u]=s;return c=>{let a=o(c),p=f(c);return a=typeof p=="function"?p(a):p,p=u(c),typeof p=="function"?p(a):p}}if(r===3){let[f,u,c]=s;return a=>{let p=o(a),h=f(a);return p=typeof h=="function"?h(p):h,h=u(a),p=typeof h=="function"?h(p):h,h=c(a),typeof h=="function"?h(p):h}}return f=>{let u=o(f);for(let c=0;c<r;c++){let a=s[c](f);u=typeof a=="function"?a(u):a;}return u}}function Tn(n,e,i){let t=n.$fn,o=n.args;if(o===void 0)return ()=>{let f=e[t];if(!f)throw new Error(`Function not found in scope: ${t}`);return f};let s=o.map(f=>A(f,e,i)),r=s.length;if(r===0)return f=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u()};if(r===1){let[f]=s;return u=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c(f(u))}}if(r===2){let[f,u]=s;return c=>{let a=e[t];if(!a)throw new Error(`Function not found in scope: ${t}`);return a(f(c),u(c))}}if(r===3){let[f,u,c]=s;return a=>{let p=e[t];if(!p)throw new Error(`Function not found in scope: ${t}`);return p(f(a),u(a),c(a))}}return f=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u(...s.map(c=>c(f)))}}function Cn(n,e,i={}){return F(n,i).fn(e)}var v=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,i={}){let t=JSON.stringify(e),o=this.cache.get(t);if(o)return this.cache.delete(t),this.cache.set(t,o),o;let s=F(e,i);if(this.cache.size>=this._maxSize){let r=this.cache.keys().next().value;r&&this.cache.delete(r);}return this.cache.set(t,s),s}has(e){return this.cache.has(JSON.stringify(e))}delete(e){return this.cache.delete(JSON.stringify(e))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(e){for(this._maxSize=e;this.cache.size>this._maxSize;){let i=this.cache.keys().next().value;i&&this.cache.delete(i);}}},J=new v;function An(n,e={}){return J.get(n,e)}function z(n,e="root",i={}){let t=[];return x(n,e,t,i),{valid:t.length===0,errors:t}}function x(n,e,i,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r=0;r<n.length;r++)x(n[r],`${e}[${r}]`,i,t);return}if(m(n)){(!n.$||typeof n.$!="string")&&i.push(`${e}: invalid reference, $ must be non-empty string`);return}if(E(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||i.push(`${e}.$if: empty path in string shorthand`):x(n.$if,`${e}.$if`,i,t),x(n.then,`${e}.then`,i,t),n.else!==void 0&&x(n.else,`${e}.else`,i,t);return}if(C(n)){if(!Array.isArray(n.$pipe)){i.push(`${e}.$pipe: must be an array`);return}if(n.$pipe.length===0){i.push(`${e}.$pipe: must have at least one element`);return}for(let r=0;r<n.$pipe.length;r++)x(n.$pipe[r],`${e}.$pipe[${r}]`,i,t);return}if(T(n)){if(!n.$fn||typeof n.$fn!="string"){i.push(`${e}: invalid function, $fn must be non-empty string`);return}if(t.scope&&!(n.$fn in t.scope)&&i.push(`${e}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))i.push(`${e}.args: must be an array`);else for(let r=0;r<n.args.length;r++)x(n.args[r],`${e}.args[${r}]`,i,t);return}if(g(n)){let r=validate(n,e);r.valid||i.push(...r.errors);return}if(y(n)){let r=validate(n,e);r.valid||i.push(...r.errors);return}let o=n,s=Object.keys(o);for(let r=0;r<s.length;r++){let f=s[r];x(o[f],`${e}.${f}`,i,t);}}function bn(n,e={}){let i=z(n,"root",e);if(!i.valid)throw new Error(`Invalid expression: ${i.errors.join("; ")}`)}function $n(n,e={}){return z(n,"root",e).valid}var Q={};tn(Q,{$:()=>K,$fn:()=>Y,$if:()=>kn,$pipe:()=>H,fn:()=>Sn,pipe:()=>wn,ref:()=>xn});function K(n){return {$:n}}var xn=K;function Y(n,e){return e===void 0||e.length===0?{$fn:n}:{$fn:n,args:e}}var Sn=Y;function kn(n,e,i){return i===void 0?{$if:n,then:e}:{$if:n,then:e,else:i}}function H(...n){return {$pipe:n}}var wn=H;var D="data",U="scope",Rn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function j(n,e={}){let{dataParam:i=D,scopeParam:t=U,noPrefixes:o=false}=e;return d(n,i,t,o)}function d(n,e,i,t){if(n===null)return builders.literal(null);if(typeof n=="string")return builders.literal(n);if(typeof n=="number")return builders.literal(n);if(typeof n=="boolean")return builders.literal(n);if(Array.isArray(n))return builders.arrayExpression(n.map(o=>d(o,e,i,t)));if(m(n))return On(n.$,e,t);if(E(n))return vn(n,e,i,t);if(C(n))return jn(n.$pipe,e,i,t);if(T(n))return Nn(n,e,i,t);if(g(n))return Gn(n,e,i,t);if(y(n))return Wn(n,e,i,t);if(typeof n=="object"){let s=Object.entries(n).map(([r,f])=>builders.property(builders.identifier(r),d(f,e,i,t)));return builders.objectExpression(s)}return builders.literal(null)}function On(n,e,i){return n.includes("[*]")?Fn(n,e,i):w(n,e,i)}function w(n,e,i){let t=N(n);if(t.length===0)return i?builders.identifier("undefined"):builders.identifier(e);let o;if(i){let s=t[0];o=builders.identifier(s.value);for(let r=1;r<t.length;r++){let f=t[r];f.type==="key"?o=builders.memberExpression(o,builders.identifier(f.value),false,true):o=builders.memberExpression(o,builders.literal(f.value),true,true);}}else {o=builders.identifier(e);for(let s of t)s.type==="key"?o=builders.memberExpression(o,builders.identifier(s.value),false,true):o=builders.memberExpression(o,builders.literal(s.value),true,true);}return o}function Fn(n,e,i){let t=n.indexOf("[*]"),o=n.slice(0,t),s=n.slice(t+3),r;if(o?r=w(o,e,i):r=i?builders.identifier("undefined"):builders.identifier(e),!s||s==="")return r;if(s.includes("[*]"))return X(r,s);let f="_i",u=s.startsWith(".")?s.slice(1):s,c=builders.identifier(f);if(u){let a=N(u);for(let p of a)p.type==="key"?c=builders.memberExpression(c,builders.identifier(p.value),false,true):c=builders.memberExpression(c,builders.literal(p.value),true,true);}return builders.callExpression(builders.memberExpression(r,builders.identifier("map"),false,true),[builders.arrowFunctionExpression([builders.identifier(f)],c)])}function X(n,e){let i=e.indexOf("[*]"),t=e.slice(0,i),o=e.slice(i+3),s="_i",r=t.startsWith(".")?t.slice(1):t,f=builders.identifier(s);if(r){let c=N(r);for(let a of c)a.type==="key"&&(f=builders.memberExpression(f,builders.identifier(a.value),false,true));}if(o.includes("[*]")){let c=X(f,o);return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],c)])}let u=o.startsWith(".")?o.slice(1):o;if(u){let c=N(u);for(let a of c)a.type==="key"&&(f=builders.memberExpression(f,builders.identifier(a.value),false,true));}return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],f)])}function vn(n,e,i,t){let o;if(typeof n.$if=="string"){let f=n.$if.startsWith("!"),u=f?n.$if.slice(1):n.$if,c=w(u,e,t);o=f?builders.unaryExpression("!",c):c;}else o=d(n.$if,e,i,t);let s=d(n.then,e,i,t),r=n.else!==void 0?d(n.else,e,i,t):builders.identifier("undefined");return builders.conditionalExpression(o,s,r)}function Nn(n,e,i,t){let o=t?builders.identifier(n.$fn):builders.memberExpression(builders.identifier(i),builders.identifier(n.$fn),false,false);if(n.args===void 0)return o;let s=n.args.map(r=>d(r,e,i,t));return builders.callExpression(o,s)}function jn(n,e,i,t){if(n.length===0)return builders.identifier("undefined");if(n.length===1)return d(n[0],e,i,t);let o=d(n[0],e,i,t);for(let s=1;s<n.length;s++){let r=d(n[s],e,i,t);o=builders.callExpression(r,[o]);}return o}function Gn(n,e,i,t){let o=w(n.path,e,t),s=n.value!==void 0?m(n.value)?w(n.value.$,e,t):d(n.value,e,i,t):builders.literal(null),r=Rn[n.op];if(r)return builders.binaryExpression(r,o,s);switch(n.op){case "in":return builders.callExpression(builders.memberExpression(s,builders.identifier("includes")),[o]);case "notIn":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(s,builders.identifier("includes")),[o]));case "contains":return builders.callExpression(builders.memberExpression(o,builders.identifier("includes"),false,true),[s]);case "notContains":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(o,builders.identifier("includes"),false,true),[s]));case "exists":return builders.binaryExpression("!=",o,builders.literal(null));case "notExists":return builders.binaryExpression("==",o,builders.literal(null));case "matches":return builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[s]),builders.identifier("test")),[o]);case "notMatches":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[s]),builders.identifier("test")),[o]));case "startsWith":return builders.callExpression(builders.memberExpression(o,builders.identifier("startsWith"),false,true),[s]);case "endsWith":return builders.callExpression(builders.memberExpression(o,builders.identifier("endsWith"),false,true),[s]);default:return builders.binaryExpression("===",o,s)}}function Wn(n,e,i,t){let{logic:o,conditions:s}=n,r=o==="AND"?"&&":"||";if(s.length===0)return builders.literal(o==="AND");if(s.length===1)return d(s[0],e,i,t);let f=d(s[0],e,i,t);for(let u=1;u<s.length;u++){let c=d(s[u],e,i,t);f=builders.logicalExpression(r,f,c);}return f}function N(n){let e=[],i=n.length,t=0,o="";for(;t<i;){let s=n[t];if(s===".")o&&(e.push({type:"key",value:o}),o=""),t++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),t++;let r=t;for(;t<i&&n[t]!=="]";)t++;let f=n.slice(r,t);if(t++,f!=="*"){let u=parseInt(f,10);e.push({type:"index",value:isNaN(u)?f:u});}}else o+=s,t++;}return o&&e.push({type:"key",value:o}),e}function Z(n,e=[D]){return builders.arrowFunctionExpression(e.map(i=>builders.identifier(i)),n)}function G(n){let e=new Set;return b(n,e),e}function b(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let t of n)b(t,e);return}if(m(n))return;if(E(n)){b(n.$if,e),b(n.then,e),n.else!==void 0&&b(n.else,e);return}if(C(n)){for(let t of n.$pipe)b(t,e);return}if(T(n)){if(e.add(n.$fn),n.args)for(let t of n.args)b(t,e);return}if(g(n)){n.value!==void 0&&typeof n.value=="object"&&b(n.value,e);return}if(y(n)){for(let t of n.conditions)b(t,e);return}let i=n;for(let t of Object.keys(i))b(i[t],e);}function W(n){let e=new Set;for(let i of n){let t=i.indexOf("."),o=i.indexOf("["),s=i.length;t!==-1&&(s=Math.min(s,t)),o!==-1&&(s=Math.min(s,o));let r=i.slice(0,s);r&&e.add(r);}return e}function zn(n){return JSON.stringify(n)}function Dn(n,e,i){let t=j(n,{noPrefixes:true}),o=generate(t),s=e.size>0?`const{${[...e].join(",")}}=data??{};`:"",r=i.size>0?`const{${[...i].join(",")}}=scope;`:"";return r?`(function(scope){${r}return function(data){${s}return ${o}}})`:`(function(){return function(data){${s}return ${o}}})`}function M(n,e={}){let{scope:i={},returnCode:t=false}=e,o=S(n),s=W(o),r=G(n),f=zn(n),u=Dn(n,s,r);if(t)return {code:u,deps:o,hash:f,dataRoots:[...s],scopeFns:[...r]};let c;try{c=new Function(`return ${u}`)()(i);}catch(a){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${a instanceof Error?a.message:String(a)}`)}return {fn:c,deps:o,hash:f}}function nn(n,e,i={}){let{fn:t}=M(n,i);return t(e)}var ye="0.1.1";export{v as ExpressionCache,ye as VERSION,bn as assertValid,Q as builders,J as cache,An as cached,cn as clearPathCache,F as compile,M as compileAST,O as compilePath,j as dslToAST,Cn as evaluate,nn as evaluateAST,W as extractDataRoots,S as extractDeps,G as extractScopeFns,un as get,an as getPathCacheSize,dn as hasDeps,L as hasWildcard,g as isCondition,on as isConditionExpr,y as isConditionGroup,E as isConditional,T as isFn,P as isLiteral,C as isPipe,mn as isPure,m as isRef,$n as isValid,k as normalizePath,z as validate,Z as wrapInFunction};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statedelta-libs/expressions",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "JSON DSL compiler for optimized functions - StateDelta expression engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -13,9 +13,20 @@
|
|
|
13
13
|
"require": "./dist/index.cjs"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsup",
|
|
18
|
+
"dev": "tsup --watch",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"test:coverage": "vitest run --coverage",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"clean": "rm -rf dist",
|
|
24
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
25
|
+
"format:check": "prettier --check \"src/**/*.ts\""
|
|
26
|
+
},
|
|
16
27
|
"dependencies": {
|
|
17
|
-
"
|
|
18
|
-
"
|
|
28
|
+
"@statedelta-libs/conditions": "^0.1.1",
|
|
29
|
+
"omni-ast": "^2.0.0"
|
|
19
30
|
},
|
|
20
31
|
"files": [
|
|
21
32
|
"dist",
|
|
@@ -46,16 +57,5 @@
|
|
|
46
57
|
},
|
|
47
58
|
"devDependencies": {
|
|
48
59
|
"@vitest/coverage-v8": "^4.0.16"
|
|
49
|
-
},
|
|
50
|
-
"scripts": {
|
|
51
|
-
"build": "tsup",
|
|
52
|
-
"dev": "tsup --watch",
|
|
53
|
-
"test": "vitest run",
|
|
54
|
-
"test:watch": "vitest",
|
|
55
|
-
"test:coverage": "vitest run --coverage",
|
|
56
|
-
"typecheck": "tsc --noEmit",
|
|
57
|
-
"clean": "rm -rf dist",
|
|
58
|
-
"format": "prettier --write \"src/**/*.ts\"",
|
|
59
|
-
"format:check": "prettier --check \"src/**/*.ts\""
|
|
60
60
|
}
|
|
61
|
-
}
|
|
61
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Anderson D. Rosa
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|