@statedelta-libs/expressions 1.1.0 → 1.2.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 +132 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +29 -3
- package/dist/index.d.ts +29 -3
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
- **Path syntax** - Suporte a wildcards (`items[*].price`)
|
|
16
16
|
- **Dependency extraction** - Para dirty tracking/reatividade
|
|
17
17
|
- **Conditions nativo** - Condicionais integradas com expressions nos lados
|
|
18
|
+
- **Custom Transforms** - Extensão do walker via transforms registrados (`$query`, `$mapper`, etc.)
|
|
18
19
|
- **Type-safe** - TypeScript nativo com inferência
|
|
19
20
|
|
|
20
21
|
## Instalação
|
|
@@ -455,6 +456,115 @@ Ambas as abordagens são **seguras contra injeção de código**:
|
|
|
455
456
|
|
|
456
457
|
Funções só são acessíveis se existirem no `scope` fornecido pelo desenvolvedor.
|
|
457
458
|
|
|
459
|
+
## Custom Transforms
|
|
460
|
+
|
|
461
|
+
Mecanismo de extensão do walker para tipos de expressão customizados. Permite registrar transforms que interceptam objetos com chaves específicas e os convertem em expressões padrão antes da compilação.
|
|
462
|
+
|
|
463
|
+
### API
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
const transforms = {
|
|
467
|
+
$query: (node) => ({
|
|
468
|
+
$fn: "__query",
|
|
469
|
+
args: [node.$query, node.params ?? {}]
|
|
470
|
+
}),
|
|
471
|
+
$mapper: (node) => ({
|
|
472
|
+
$fn: "__mapper",
|
|
473
|
+
args: [node.$mapper, node.params ?? {}]
|
|
474
|
+
}),
|
|
475
|
+
};
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### Uso com compile() e compileAST()
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
import { compile, compileAST } from '@statedelta-libs/expressions';
|
|
482
|
+
|
|
483
|
+
const scope = {
|
|
484
|
+
__query: (name, params) => queryEngine.run(name, params),
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
// Closures
|
|
488
|
+
const { fn } = compile(
|
|
489
|
+
{ $query: "isKingAttacked", params: { row: 0, col: 4 } },
|
|
490
|
+
{ scope, transforms }
|
|
491
|
+
);
|
|
492
|
+
|
|
493
|
+
// AST (mesmo contrato)
|
|
494
|
+
const { fn } = compileAST(
|
|
495
|
+
{ $query: "isKingAttacked", params: { row: 0, col: 4 } },
|
|
496
|
+
{ scope, transforms }
|
|
497
|
+
);
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Expressions dentro de params
|
|
501
|
+
|
|
502
|
+
Os params do transform são compilados recursivamente — referências e expressões dentro deles são resolvidas normalmente:
|
|
503
|
+
|
|
504
|
+
```typescript
|
|
505
|
+
const { fn } = compile(
|
|
506
|
+
{ $query: "check", params: { row: { $: "myRow" }, col: { $: "myCol" } } },
|
|
507
|
+
{ scope, transforms }
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
fn({ myRow: 5, myCol: 3 });
|
|
511
|
+
// → __query("check", { row: 5, col: 3 })
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Aninhamento
|
|
515
|
+
|
|
516
|
+
Transforms funcionam em qualquer posição — dentro de `$if`, `$pipe`, `$fn`, conditions, plain objects:
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
// Dentro de condition
|
|
520
|
+
{
|
|
521
|
+
$if: {
|
|
522
|
+
left: { $query: "isAttacked", params: { row: 0 } },
|
|
523
|
+
op: "eq",
|
|
524
|
+
right: true
|
|
525
|
+
},
|
|
526
|
+
then: "check",
|
|
527
|
+
else: "safe"
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Dentro de plain object (walk automático)
|
|
531
|
+
{
|
|
532
|
+
damage: { $query: "getDamage", params: { base: 10 } },
|
|
533
|
+
name: "attack"
|
|
534
|
+
}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### Extração de deps
|
|
538
|
+
|
|
539
|
+
`extractDeps` também resolve transforms para capturar dependências internas:
|
|
540
|
+
|
|
541
|
+
```typescript
|
|
542
|
+
import { extractDeps } from '@statedelta-libs/expressions';
|
|
543
|
+
|
|
544
|
+
const deps = extractDeps(
|
|
545
|
+
{ $query: "check", params: { row: { $: "myRow" } } },
|
|
546
|
+
transforms
|
|
547
|
+
);
|
|
548
|
+
// ["myRow"]
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### Proteção contra loops infinitos
|
|
552
|
+
|
|
553
|
+
Se um transform retornar um objeto com a mesma chave de entrada, um erro é lançado:
|
|
554
|
+
|
|
555
|
+
```typescript
|
|
556
|
+
const badTransforms = {
|
|
557
|
+
$loop: (node) => ({ $loop: node.$loop }), // mesma chave!
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
compile({ $loop: "test" }, { transforms: badTransforms });
|
|
561
|
+
// Error: Transform "$loop" returned object with same key — infinite loop
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### Performance
|
|
565
|
+
|
|
566
|
+
Transforms são resolvidos **em tempo de compilação**. Zero overhead em runtime — a função compilada resultante é idêntica a uma expressão `$fn` normal.
|
|
567
|
+
|
|
458
568
|
## Type Detection
|
|
459
569
|
|
|
460
570
|
O compilador detecta automaticamente o tipo de expressão baseado na estrutura do objeto:
|
|
@@ -466,6 +576,7 @@ O compilador detecta automaticamente o tipo de expressão baseado na estrutura d
|
|
|
466
576
|
| Function | `{ $fn }` presente | `{ $fn: "add", args: [...] }` |
|
|
467
577
|
| Pipe | `{ $pipe }` presente | `{ $pipe: [...] }` |
|
|
468
578
|
| Condition | `{ left, op }` com operador válido | `{ left: { $: "age" }, op: "gte", right: 18 }` |
|
|
579
|
+
| Custom Transform | Chave registrada em `transforms` | `{ $query: "check", params: {...} }` |
|
|
469
580
|
| Literal | Nenhum dos acima | `{ foo: "bar" }`, `42`, `"hello"` |
|
|
470
581
|
|
|
471
582
|
### Distinção entre Conditions e Effect Objects
|
|
@@ -616,6 +727,7 @@ import type {
|
|
|
616
727
|
Scope,
|
|
617
728
|
CompileOptions,
|
|
618
729
|
AccessorFn,
|
|
730
|
+
TransformFn,
|
|
619
731
|
} from '@statedelta-libs/expressions';
|
|
620
732
|
|
|
621
733
|
// Type guards
|
|
@@ -668,6 +780,26 @@ import {
|
|
|
668
780
|
|
|
669
781
|
4. **Novos tipos**: `ConditionOp`, `Condition`, `ConditionGroup`, `ConditionExpr` exportados diretamente do expressions.
|
|
670
782
|
|
|
783
|
+
### v1.1 → v1.2
|
|
784
|
+
|
|
785
|
+
1. **Custom Transforms**: Nova option `transforms` em `CompileOptions` e `CompileASTOptions`. Permite estender o walker com tipos de expressão customizados (`$query`, `$mapper`, etc.):
|
|
786
|
+
```typescript
|
|
787
|
+
const transforms = {
|
|
788
|
+
$query: (node) => ({ $fn: "__query", args: [node.$query, node.params ?? {}] }),
|
|
789
|
+
};
|
|
790
|
+
compile(expr, { scope, transforms });
|
|
791
|
+
compileAST(expr, { scope, transforms });
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
2. **extractDeps com transforms**: `extractDeps` agora aceita `transforms` como segundo argumento para capturar deps dentro de expressões customizadas:
|
|
795
|
+
```typescript
|
|
796
|
+
extractDeps(expr, transforms);
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
3. **Novo tipo**: `TransformFn` exportado diretamente do expressions.
|
|
800
|
+
|
|
801
|
+
4. **Zero breaking change**: O campo `transforms` é opcional. Sem ele, o comportamento é idêntico ao anterior.
|
|
802
|
+
|
|
671
803
|
## Licença
|
|
672
804
|
|
|
673
805
|
MIT © Anderson D. Rosa
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var omniAst=require('omni-ast');var on=Object.defineProperty;var rn=(n,t)=>{for(var s in t)on(n,s,{get:t[s],enumerable:true});};var y=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,T=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,b=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),x=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),h=n=>n!==null&&typeof n=="object"&&"left"in n&&"op"in n&&x.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),E=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,sn=n=>h(n)||E(n),I=n=>{if(n===null)return true;let t=typeof n;if(t==="string"||t==="number"||t==="boolean"||Array.isArray(n))return true;if(t==="object"&&n!==null){let s=n,e="left"in s&&"op"in s&&x.has(s.op);return !("$"in s)&&!("$if"in s)&&!("$fn"in s)&&!("$pipe"in s)&&!e&&!("logic"in s)}return false};var R=new Map;function q(n){let t=[],s=n.length,e=0,r="";for(;e<s;){let o=n[e];if(o===".")r&&(t.push({type:"key",value:r}),r=""),e++;else if(o==="["){r&&(t.push({type:"key",value:r}),r=""),e++;let i=e;for(;e<s&&n[e]!=="]";)e++;let f=n.slice(i,e);if(e++,f==="*")t.push({type:"wildcard",value:"*"});else {let l=parseInt(f,10);t.push({type:"index",value:isNaN(l)?f:l});}}else r+=o,e++;}return r&&t.push({type:"key",value:r}),t}function J(n){return n.includes("[*]")}function O(n){let t=R.get(n);return t||(t=J(n)?un(n):fn(n),R.set(n,t),t)}function fn(n){if(!n.includes(".")&&!n.includes("["))return r=>r?.[n];let t=q(n),s=t.length;if(s===2){let[r,o]=t,i=r.value,f=o.value;return l=>l?.[i]?.[f]}if(s===3){let[r,o,i]=t,f=r.value,l=o.value,c=i.value;return a=>a?.[f]?.[l]?.[c]}let e=t.map(r=>r.value);return r=>{let o=r;for(let i=0;i<s&&o!=null;i++)o=o[e[i]];return o}}function un(n){let t=q(n),s=[];for(let e=0;e<t.length;e++)t[e].type==="wildcard"&&s.push(e);return s.length===1?ln(t,s[0]):cn(t,s)}function ln(n,t){let s=n.slice(0,t).map(i=>i.value),e=n.slice(t+1).map(i=>i.value),r=s.length,o=e.length;if(o===0){if(r===1){let i=s[0];return f=>f?.[i]}return i=>{let f=i;for(let l=0;l<r&&f!=null;l++)f=f[s[l]];return f}}if(o===1){let i=e[0];if(r===1){let f=s[0];return l=>{let c=l?.[f];if(Array.isArray(c))return c.map(a=>a?.[i])}}return f=>{let l=f;for(let c=0;c<r&&l!=null;c++)l=l[s[c]];if(Array.isArray(l))return l.map(c=>c?.[i])}}return i=>{let f=i;for(let l=0;l<r&&f!=null;l++)f=f[s[l]];if(Array.isArray(f))return f.map(l=>{let c=l;for(let a=0;a<o&&c!=null;a++)c=c[e[a]];return c})}}function cn(n,t){let s=[],e=0;for(let o=0;o<t.length;o++){let i=t[o],f=o===t.length-1,l=n.slice(e,i).map(c=>c.value);l.length>0&&s.push({type:"access",keys:l}),s.push({type:f?"map":"flatMap",keys:[]}),e=i+1;}let r=n.slice(e).map(o=>o.value);return o=>{let i=o;for(let f of s){if(i==null)return;if(f.type==="access")for(let l of f.keys){if(i==null)return;i=i[l];}else if(f.type==="flatMap"){if(!Array.isArray(i))return;i=i.flatMap(l=>{let c=l;return Array.isArray(c)?c:[c]});}else if(f.type==="map"){if(!Array.isArray(i))return;r.length>0&&(i=i.map(l=>{let c=l;for(let a of r){if(c==null)return;c=c[a];}return c}));}}return i}}function an(n,t){return O(t)(n)}function F(n){let t=n.indexOf("[*]");return t===-1?n:n.slice(0,t)}function pn(){R.clear();}function dn(){return R.size}function k(n){let t=new Set;return A(n,t),Array.from(t)}function A(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r=0;r<n.length;r++)A(n[r],t);return}if(y(n)){t.add(F(n.$));return}if(T(n)){if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if;t.add(F(r));}else A(n.$if,t);A(n.then,t),n.else!==void 0&&A(n.else,t);return}if(C(n)){for(let r=0;r<n.$pipe.length;r++)A(n.$pipe[r],t);return}if(b(n)){if(n.args)for(let r=0;r<n.args.length;r++){let o=n.args[r];typeof o!="function"&&A(o,t);}return}if(h(n)){A(n.left,t),n.right!==void 0&&A(n.right,t);return}if(E(n)){for(let r=0;r<n.conditions.length;r++)A(n.conditions[r],t);return}let s=n,e=Object.keys(s);for(let r=0;r<e.length;r++)A(s[e[r]],t);}function gn(n){return k(n).length>0}function mn(n){return k(n).length===0}function yn(n){return JSON.stringify(n)}function N(n,t={}){let s=t.scope??{},e=t.accessor,r=m(n,s,e),o=k(n),i=yn(n);return {fn:r,deps:o,hash:i}}function m(n,t,s){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let e=n.map(r=>m(r,t,s));return r=>e.map(o=>o(r))}if(y(n))return hn(n,s);if(T(n))return En(n,t,s);if(C(n))return Tn(n,t,s);if(b(n))return bn(n,t,s);if(h(n))return Cn(n,t,s);if(E(n))return An(n,t,s);if(I(n)){let e=n,r=Object.keys(e),o=r.map(i=>m(e[i],t,s));return i=>{let f={};for(let l=0;l<r.length;l++)f[r[l]]=o[l](i);return f}}return ()=>n}function B(n,t){return t?s=>t(n,s):O(n)}function hn(n,t){return B(n.$,t)}function En(n,t,s){let e;if(typeof n.$if=="string"){let i=n.$if.startsWith("!")?n.$if.slice(1):n.$if,f=B(i,s);e=n.$if.startsWith("!")?c=>!f(c):c=>!!f(c);}else {let i=m(n.$if,t,s);e=f=>!!i(f);}let r=m(n.then,t,s),o=n.else!==void 0?m(n.else,t,s):()=>{};return i=>e(i)?r(i):o(i)}function Tn(n,t,s){let e=n.$pipe;if(e.length===0)return ()=>{};if(e.length===1)return m(e[0],t,s);let r=m(e[0],t,s),o=e.slice(1).map(f=>m(f,t,s)),i=o.length;if(i===1){let[f]=o;return l=>{let c=r(l),a=f(l);return typeof a=="function"?a(c):a}}if(i===2){let[f,l]=o;return c=>{let a=r(c),p=f(c);return a=typeof p=="function"?p(a):p,p=l(c),typeof p=="function"?p(a):p}}if(i===3){let[f,l,c]=o;return a=>{let p=r(a),d=f(a);return p=typeof d=="function"?d(p):d,d=l(a),p=typeof d=="function"?d(p):d,d=c(a),typeof d=="function"?d(p):d}}return f=>{let l=r(f);for(let c=0;c<i;c++){let a=o[c](f);l=typeof a=="function"?a(l):a;}return l}}function bn(n,t,s){let e=n.$fn,r=n.args;if(r===void 0)return ()=>{let f=t[e];if(!f)throw new Error(`Function not found in scope: ${e}`);return f};let o=r.map(f=>typeof f=="function"?()=>f:m(f,t,s)),i=o.length;if(i===0)return f=>{let l=t[e];if(!l)throw new Error(`Function not found in scope: ${e}`);return l()};if(i===1){let[f]=o;return l=>{let c=t[e];if(!c)throw new Error(`Function not found in scope: ${e}`);return c(f(l))}}if(i===2){let[f,l]=o;return c=>{let a=t[e];if(!a)throw new Error(`Function not found in scope: ${e}`);return a(f(c),l(c))}}if(i===3){let[f,l,c]=o;return a=>{let p=t[e];if(!p)throw new Error(`Function not found in scope: ${e}`);return p(f(a),l(a),c(a))}}return f=>{let l=t[e];if(!l)throw new Error(`Function not found in scope: ${e}`);return l(...o.map(c=>c(f)))}}function Cn(n,t,s){let e=m(n.left,t,s),r=n.right!==void 0?m(n.right,t,s):()=>{};switch(n.op){case "eq":return o=>e(o)===r(o);case "neq":return o=>e(o)!==r(o);case "gt":return o=>e(o)>r(o);case "gte":return o=>e(o)>=r(o);case "lt":return o=>e(o)<r(o);case "lte":return o=>e(o)<=r(o);case "in":return o=>{let i=r(o);return Array.isArray(i)&&i.includes(e(o))};case "notIn":return o=>{let i=r(o);return !Array.isArray(i)||!i.includes(e(o))};case "contains":return o=>{let i=e(o);return Array.isArray(i)&&i.includes(r(o))};case "notContains":return o=>{let i=e(o);return !Array.isArray(i)||!i.includes(r(o))};case "exists":return o=>e(o)!==void 0;case "notExists":return o=>e(o)===void 0;case "matches":return o=>{let i=e(o),f=r(o);return typeof i!="string"||typeof f!="string"?false:new RegExp(f).test(i)};case "notMatches":return o=>{let i=e(o),f=r(o);return typeof i!="string"||typeof f!="string"?true:!new RegExp(f).test(i)};case "startsWith":return o=>{let i=e(o),f=r(o);return typeof i=="string"&&typeof f=="string"&&i.startsWith(f)};case "endsWith":return o=>{let i=e(o),f=r(o);return typeof i=="string"&&typeof f=="string"&&i.endsWith(f)}}}function An(n,t,s){let e=n.conditions.map(o=>m(o,t,s)),r=e.length;if(r===1)return o=>!!e[0](o);if(r===2){let[o,i]=e;return n.logic==="AND"?f=>!!o(f)&&!!i(f):f=>!!o(f)||!!i(f)}if(r===3){let[o,i,f]=e;return n.logic==="AND"?l=>!!o(l)&&!!i(l)&&!!f(l):l=>!!o(l)||!!i(l)||!!f(l)}return n.logic==="AND"?o=>{for(let i=0;i<r;i++)if(!e[i](o))return false;return true}:o=>{for(let i=0;i<r;i++)if(e[i](o))return true;return false}}function $n(n,t,s={}){return N(n,s).fn(t)}var v=class{constructor(t=1e3){this.cache=new Map,this._maxSize=t;}get(t,s={}){let e=JSON.stringify(t),r=this.cache.get(e);if(r)return this.cache.delete(e),this.cache.set(e,r),r;let o=N(t,s);if(this.cache.size>=this._maxSize){let i=this.cache.keys().next().value;i&&this.cache.delete(i);}return this.cache.set(e,o),o}has(t){return this.cache.has(JSON.stringify(t))}delete(t){return this.cache.delete(JSON.stringify(t))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(t){for(this._maxSize=t;this.cache.size>this._maxSize;){let s=this.cache.keys().next().value;s&&this.cache.delete(s);}}},K=new v;function Sn(n,t={}){return K.get(n,t)}function M(n,t="root",s={}){let e=[];return $(n,t,e,s),{valid:e.length===0,errors:e}}function $(n,t,s,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let i=0;i<n.length;i++)$(n[i],`${t}[${i}]`,s,e);return}if(y(n)){(!n.$||typeof n.$!="string")&&s.push(`${t}: invalid reference, $ must be non-empty string`);return}if(T(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||s.push(`${t}.$if: empty path in string shorthand`):$(n.$if,`${t}.$if`,s,e),$(n.then,`${t}.then`,s,e),n.else!==void 0&&$(n.else,`${t}.else`,s,e);return}if(C(n)){if(!Array.isArray(n.$pipe)){s.push(`${t}.$pipe: must be an array`);return}if(n.$pipe.length===0){s.push(`${t}.$pipe: must have at least one element`);return}for(let i=0;i<n.$pipe.length;i++)$(n.$pipe[i],`${t}.$pipe[${i}]`,s,e);return}if(b(n)){if(!n.$fn||typeof n.$fn!="string"){s.push(`${t}: invalid function, $fn must be non-empty string`);return}if(e.scope&&!(n.$fn in e.scope)&&s.push(`${t}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))s.push(`${t}.args: must be an array`);else for(let i=0;i<n.args.length;i++){let f=n.args[i];typeof f!="function"&&$(f,`${t}.args[${i}]`,s,e);}return}if(h(n)){x.has(n.op)||s.push(`${t}: invalid operator "${n.op}"`),$(n.left,`${t}.left`,s,e),n.right!==void 0&&$(n.right,`${t}.right`,s,e);return}if(E(n)){if(n.logic!=="AND"&&n.logic!=="OR"&&s.push(`${t}: invalid logic "${n.logic}", must be "AND" or "OR"`),!Array.isArray(n.conditions)){s.push(`${t}.conditions: must be an array`);return}for(let i=0;i<n.conditions.length;i++)$(n.conditions[i],`${t}.conditions[${i}]`,s,e);return}let r=n,o=Object.keys(r);for(let i=0;i<o.length;i++){let f=o[i];$(r[f],`${t}.${f}`,s,e);}}function kn(n,t={}){let s=M(n,"root",t);if(!s.valid)throw new Error(`Invalid expression: ${s.errors.join("; ")}`)}function wn(n,t={}){return M(n,"root",t).valid}var U={};rn(U,{$:()=>P,$cond:()=>Q,$fn:()=>Y,$if:()=>On,$pipe:()=>H,cond:()=>Nn,fn:()=>Rn,pipe:()=>Fn,ref:()=>xn});function P(n){return {$:n}}var xn=P;function Y(n,t){return t===void 0||t.length===0?{$fn:n}:{$fn:n,args:t}}var Rn=Y;function On(n,t,s){return s===void 0?{$if:n,then:t}:{$if:n,then:t,else:s}}function H(...n){return {$pipe:n}}var Fn=H;function Q(n,t,s){return s===void 0?{left:n,op:t}:{left:n,op:t,right:s}}var Nn=Q;var z="data",Z="scope",vn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function G(n,t={}){let{dataParam:s=z,scopeParam:e=Z,noPrefixes:r=false,useAccessor:o=false,lexicalPrefix:i}=t;return g(n,s,e,r,o,i)}function g(n,t,s,e,r,o){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=>g(i,t,s,e,r,o)));if(y(n))return jn(n.$,t,e,r,o);if(T(n))return Wn(n,t,s,e,r,o);if(C(n))return In(n.$pipe,t,s,e,r,o);if(b(n))return Dn(n,t,s,e,r,o);if(h(n))return Mn(n,t,s,e,r,o);if(E(n))return zn(n,t,s,e,r,o);if(typeof n=="object"){let f=Object.entries(n).map(([l,c])=>omniAst.builders.property(omniAst.builders.identifier(l),g(c,t,s,e,r,o)));return omniAst.builders.objectExpression(f)}return omniAst.builders.literal(null)}var L="accessor";function V(n,t){return t?n===t||n.startsWith(t+"."):false}function jn(n,t,s,e,r){return e?V(n,r)?w(n,t,true):omniAst.builders.callExpression(omniAst.builders.identifier(L),[omniAst.builders.literal(n),omniAst.builders.identifier(t)]):n.includes("[*]")?Gn(n,t,s):w(n,t,s)}function w(n,t,s){let e=j(n);if(e.length===0)return s?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(t);let r;if(s){let o=e[0];r=omniAst.builders.identifier(o.value);for(let i=1;i<e.length;i++){let f=e[i];f.type==="key"?r=omniAst.builders.memberExpression(r,omniAst.builders.identifier(f.value),false,true):r=omniAst.builders.memberExpression(r,omniAst.builders.literal(f.value),true,true);}}else {r=omniAst.builders.identifier(t);for(let o of e)o.type==="key"?r=omniAst.builders.memberExpression(r,omniAst.builders.identifier(o.value),false,true):r=omniAst.builders.memberExpression(r,omniAst.builders.literal(o.value),true,true);}return r}function Gn(n,t,s){let e=n.indexOf("[*]"),r=n.slice(0,e),o=n.slice(e+3),i;if(r?i=w(r,t,s):i=s?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(t),!o||o==="")return i;if(o.includes("[*]"))return nn(i,o);let f="_i",l=o.startsWith(".")?o.slice(1):o,c=omniAst.builders.identifier(f);if(l){let a=j(l);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(i,omniAst.builders.identifier("map"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(f)],c)])}function nn(n,t){let s=t.indexOf("[*]"),e=t.slice(0,s),r=t.slice(s+3),o="_i",i=e.startsWith(".")?e.slice(1):e,f=omniAst.builders.identifier(o);if(i){let c=j(i);for(let a of c)a.type==="key"&&(f=omniAst.builders.memberExpression(f,omniAst.builders.identifier(a.value),false,true));}if(r.includes("[*]")){let c=nn(f,r);return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(o)],c)])}let l=r.startsWith(".")?r.slice(1):r;if(l){let c=j(l);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(o)],f)])}function Wn(n,t,s,e,r,o){let i;if(typeof n.$if=="string"){let c=n.$if.startsWith("!"),a=c?n.$if.slice(1):n.$if,p;r?V(a,o)?p=w(a,t,true):p=omniAst.builders.callExpression(omniAst.builders.identifier(L),[omniAst.builders.literal(a),omniAst.builders.identifier(t)]):p=w(a,t,e),i=c?omniAst.builders.unaryExpression("!",p):p;}else i=g(n.$if,t,s,e,r,o);let f=g(n.then,t,s,e,r,o),l=n.else!==void 0?g(n.else,t,s,e,r,o):omniAst.builders.identifier("undefined");return omniAst.builders.conditionalExpression(i,f,l)}function Dn(n,t,s,e,r,o){let i=e?omniAst.builders.identifier(n.$fn):omniAst.builders.memberExpression(omniAst.builders.identifier(s),omniAst.builders.identifier(n.$fn),false,false);if(n.args===void 0)return i;let f=n.args.map(l=>typeof l=="function"?omniAst.builders.literal(null):g(l,t,s,e,r,o));return omniAst.builders.callExpression(i,f)}function In(n,t,s,e,r,o){if(n.length===0)return omniAst.builders.identifier("undefined");if(n.length===1)return g(n[0],t,s,e,r,o);let i=g(n[0],t,s,e,r,o);for(let f=1;f<n.length;f++){let l=g(n[f],t,s,e,r,o);i=omniAst.builders.callExpression(l,[i]);}return i}function X(n,t,s,e,r,o){if(y(n)){let i=n.$;return r?V(i,o)?w(i,t,true):omniAst.builders.callExpression(omniAst.builders.identifier(L),[omniAst.builders.literal(i),omniAst.builders.identifier(t)]):w(i,t,e)}return g(n,t,s,e,r,o)}function Mn(n,t,s,e,r,o){let i=X(n.left,t,s,e,r,o),f=n.right!==void 0?X(n.right,t,s,e,r,o):omniAst.builders.literal(null),l=vn[n.op];if(l)return omniAst.builders.binaryExpression(l,i,f);switch(n.op){case "in":return omniAst.builders.callExpression(omniAst.builders.memberExpression(f,omniAst.builders.identifier("includes")),[i]);case "notIn":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(f,omniAst.builders.identifier("includes")),[i]));case "contains":return omniAst.builders.callExpression(omniAst.builders.memberExpression(i,omniAst.builders.identifier("includes"),false,true),[f]);case "notContains":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(i,omniAst.builders.identifier("includes"),false,true),[f]));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"),[f]),omniAst.builders.identifier("test")),[i]);case "notMatches":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[f]),omniAst.builders.identifier("test")),[i]));case "startsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(i,omniAst.builders.identifier("startsWith"),false,true),[f]);case "endsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(i,omniAst.builders.identifier("endsWith"),false,true),[f]);default:return omniAst.builders.binaryExpression("===",i,f)}}function zn(n,t,s,e,r,o){let{logic:i,conditions:f}=n,l=i==="AND"?"&&":"||";if(f.length===0)return omniAst.builders.literal(i==="AND");if(f.length===1)return g(f[0],t,s,e,r,o);let c=g(f[0],t,s,e,r,o);for(let a=1;a<f.length;a++){let p=g(f[a],t,s,e,r,o);c=omniAst.builders.logicalExpression(l,c,p);}return c}function j(n){let t=[],s=n.length,e=0,r="";for(;e<s;){let o=n[e];if(o===".")r&&(t.push({type:"key",value:r}),r=""),e++;else if(o==="["){r&&(t.push({type:"key",value:r}),r=""),e++;let i=e;for(;e<s&&n[e]!=="]";)e++;let f=n.slice(i,e);if(e++,f!=="*"){let l=parseInt(f,10);t.push({type:"index",value:isNaN(l)?f:l});}}else r+=o,e++;}return r&&t.push({type:"key",value:r}),t}function tn(n,t=[z]){return omniAst.builders.arrowFunctionExpression(t.map(s=>omniAst.builders.identifier(s)),n)}function W(n){let t=new Set;return S(n,t),t}function S(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let e of n)S(e,t);return}if(y(n))return;if(T(n)){S(n.$if,t),S(n.then,t),n.else!==void 0&&S(n.else,t);return}if(C(n)){for(let e of n.$pipe)S(e,t);return}if(b(n)){if(t.add(n.$fn),n.args)for(let e of n.args)typeof e!="function"&&S(e,t);return}if(h(n)){n.left!==void 0&&typeof n.left=="object"&&S(n.left,t),n.right!==void 0&&typeof n.right=="object"&&S(n.right,t);return}if(E(n)){for(let e of n.conditions)S(e,t);return}let s=n;for(let e of Object.keys(s))S(s[e],t);}function D(n){let t=new Set;for(let s of n){let e=s.indexOf("."),r=s.indexOf("["),o=s.length;e!==-1&&(o=Math.min(o,e)),r!==-1&&(o=Math.min(o,r));let i=s.slice(0,o);i&&t.add(i);}return t}function Vn(n){return JSON.stringify(n)}function _n(n,t,s,e,r){let o=G(n,{noPrefixes:true,useAccessor:e,lexicalPrefix:r}),i=omniAst.generate(o),f="";e?r&&(f=`const{${r}}=data??{};`):t.size>0&&(f=`const{${[...t].join(",")}}=data??{};`);let l=e?new Set([...s,"accessor"]):s,c=l.size>0?`const{${[...l].join(",")}}=scope;`:"";return c?`(function(scope){${c}return function(data){${f}return ${i}}})`:`(function(){return function(data){${f}return ${i}}})`}function _(n,t={}){let{scope:s={},returnCode:e=false,useAccessor:r=false,lexicalPrefix:o}=t,i=k(n),f=D(i),l=W(n),c=Vn(n),a=_n(n,f,l,r,o);if(e)return {code:a,deps:i,hash:c,dataRoots:[...f],scopeFns:[...l]};let p;try{p=new Function(`return ${a}`)()(s);}catch(d){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${d instanceof Error?d.message:String(d)}`)}return {fn:p,deps:i,hash:c}}function en(n,t,s={}){let{fn:e}=_(n,s);return e(t)}var ht="0.1.1";exports.ExpressionCache=v;exports.VERSION=ht;exports.assertValid=kn;exports.builders=U;exports.cache=K;exports.cached=Sn;exports.clearPathCache=pn;exports.compile=N;exports.compileAST=_;exports.compilePath=O;exports.dslToAST=G;exports.evaluate=$n;exports.evaluateAST=en;exports.extractDataRoots=D;exports.extractDeps=k;exports.extractScopeFns=W;exports.get=an;exports.getPathCacheSize=dn;exports.hasDeps=gn;exports.hasWildcard=J;exports.isCondition=h;exports.isConditionExpr=sn;exports.isConditionGroup=E;exports.isConditional=T;exports.isFn=b;exports.isLiteral=I;exports.isPipe=C;exports.isPure=mn;exports.isRef=y;exports.isValid=wn;exports.normalizePath=F;exports.validate=M;exports.wrapInFunction=tn;
|
|
1
|
+
'use strict';var omniAst=require('omni-ast');var rn=Object.defineProperty;var sn=(n,e)=>{for(var i in e)rn(n,i,{get:e[i],enumerable:true});};var h=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,A=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,$=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",k=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),F=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),E=n=>n!==null&&typeof n=="object"&&"left"in n&&"op"in n&&F.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),T=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,fn=n=>E(n)||T(n),M=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,f="left"in i&&"op"in i&&F.has(i.op);return !("$"in i)&&!("$if"in i)&&!("$fn"in i)&&!("$pipe"in i)&&!f&&!("logic"in i)}return false};var x=new Map;function J(n){let e=[],i=n.length,f=0,o="";for(;f<i;){let s=n[f];if(s===".")o&&(e.push({type:"key",value:o}),o=""),f++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),f++;let t=f;for(;f<i&&n[f]!=="]";)f++;let r=n.slice(t,f);if(f++,r==="*")e.push({type:"wildcard",value:"*"});else {let c=parseInt(r,10);e.push({type:"index",value:isNaN(c)?r:c});}}else o+=s,f++;}return o&&e.push({type:"key",value:o}),e}function B(n){return n.includes("[*]")}function O(n){let e=x.get(n);return e||(e=B(n)?un(n):cn(n),x.set(n,e),e)}function cn(n){if(!n.includes(".")&&!n.includes("["))return o=>o?.[n];let e=J(n),i=e.length;if(i===2){let[o,s]=e,t=o.value,r=s.value;return c=>c?.[t]?.[r]}if(i===3){let[o,s,t]=e,r=o.value,c=s.value,l=t.value;return a=>a?.[r]?.[c]?.[l]}let f=e.map(o=>o.value);return o=>{let s=o;for(let t=0;t<i&&s!=null;t++)s=s[f[t]];return s}}function un(n){let e=J(n),i=[];for(let f=0;f<e.length;f++)e[f].type==="wildcard"&&i.push(f);return i.length===1?ln(e,i[0]):an(e,i)}function ln(n,e){let i=n.slice(0,e).map(t=>t.value),f=n.slice(e+1).map(t=>t.value),o=i.length,s=f.length;if(s===0){if(o===1){let t=i[0];return r=>r?.[t]}return t=>{let r=t;for(let c=0;c<o&&r!=null;c++)r=r[i[c]];return r}}if(s===1){let t=f[0];if(o===1){let r=i[0];return c=>{let l=c?.[r];if(Array.isArray(l))return l.map(a=>a?.[t])}}return r=>{let c=r;for(let l=0;l<o&&c!=null;l++)c=c[i[l]];if(Array.isArray(c))return c.map(l=>l?.[t])}}return t=>{let r=t;for(let c=0;c<o&&r!=null;c++)r=r[i[c]];if(Array.isArray(r))return r.map(c=>{let l=c;for(let a=0;a<s&&l!=null;a++)l=l[f[a]];return l})}}function an(n,e){let i=[],f=0;for(let s=0;s<e.length;s++){let t=e[s],r=s===e.length-1,c=n.slice(f,t).map(l=>l.value);c.length>0&&i.push({type:"access",keys:c}),i.push({type:r?"map":"flatMap",keys:[]}),f=t+1;}let o=n.slice(f).map(s=>s.value);return s=>{let t=s;for(let r of i){if(t==null)return;if(r.type==="access")for(let c of r.keys){if(t==null)return;t=t[c];}else if(r.type==="flatMap"){if(!Array.isArray(t))return;t=t.flatMap(c=>{let l=c;return Array.isArray(l)?l:[l]});}else if(r.type==="map"){if(!Array.isArray(t))return;o.length>0&&(t=t.map(c=>{let l=c;for(let a of o){if(l==null)return;l=l[a];}return l}));}}return t}}function pn(n,e){return O(e)(n)}function j(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function dn(){x.clear();}function gn(){return x.size}function w(n,e){let i=new Set;return b(n,i,e),Array.from(i)}function b(n,e,i){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let s=0;s<n.length;s++)b(n[s],e,i);return}if(h(n)){e.add(j(n.$));return}if(A(n)){if(typeof n.$if=="string"){let s=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(j(s));}else b(n.$if,e,i);b(n.then,e,i),n.else!==void 0&&b(n.else,e,i);return}if(k(n)){for(let s=0;s<n.$pipe.length;s++)b(n.$pipe[s],e,i);return}if($(n)){if(n.args)for(let s=0;s<n.args.length;s++){let t=n.args[s];typeof t!="function"&&b(t,e,i);}return}if(E(n)){b(n.left,e,i),n.right!==void 0&&b(n.right,e,i);return}if(T(n)){for(let s=0;s<n.conditions.length;s++)b(n.conditions[s],e,i);return}if(i){let s=n,t=Object.keys(s);for(let r=0;r<t.length;r++){let c=t[r];if(c in i){let l=i[c](s);if(typeof l=="object"&&l!==null&&c in l)throw new Error(`Transform "${c}" returned object with same key \u2014 infinite loop`);b(l,e,i);return}}}let f=n,o=Object.keys(f);for(let s=0;s<o.length;s++)b(f[o[s]],e,i);}function yn(n){return w(n).length>0}function mn(n){return w(n).length===0}function hn(n){return JSON.stringify(n)}function N(n,e={}){let i=e.scope??{},f=e.accessor,o=e.transforms,s=m(n,i,f,o),t=w(n,o),r=hn(n);return {fn:s,deps:t,hash:r}}function m(n,e,i,f){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let o=n.map(s=>m(s,e,i,f));return s=>o.map(t=>t(s))}if(h(n))return En(n,i);if(A(n))return Tn(n,e,i,f);if(k(n))return bn(n,e,i,f);if($(n))return Cn(n,e,i,f);if(E(n))return An(n,e,i,f);if(T(n))return $n(n,e,i,f);if(f){let o=n,s=Object.keys(o);for(let t=0;t<s.length;t++){let r=s[t];if(r in f){let c=f[r](o);if(typeof c=="object"&&c!==null&&r in c)throw new Error(`Transform "${r}" returned object with same key \u2014 infinite loop`);return m(c,e,i,f)}}}if(M(n)){let o=n,s=Object.keys(o),t=s.map(r=>m(o[r],e,i,f));return r=>{let c={};for(let l=0;l<s.length;l++)c[s[l]]=t[l](r);return c}}return ()=>n}function K(n,e){return e?i=>e(n,i):O(n)}function En(n,e){return K(n.$,e)}function Tn(n,e,i,f){let o;if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if,c=K(r,i);o=n.$if.startsWith("!")?a=>!c(a):a=>!!c(a);}else {let r=m(n.$if,e,i,f);o=c=>!!r(c);}let s=m(n.then,e,i,f),t=n.else!==void 0?m(n.else,e,i,f):()=>{};return r=>o(r)?s(r):t(r)}function bn(n,e,i,f){let o=n.$pipe;if(o.length===0)return ()=>{};if(o.length===1)return m(o[0],e,i,f);let s=m(o[0],e,i,f),t=o.slice(1).map(c=>m(c,e,i,f)),r=t.length;if(r===1){let[c]=t;return l=>{let a=s(l),p=c(l);return typeof p=="function"?p(a):p}}if(r===2){let[c,l]=t;return a=>{let p=s(a),d=c(a);return p=typeof d=="function"?d(p):d,d=l(a),typeof d=="function"?d(p):d}}if(r===3){let[c,l,a]=t;return p=>{let d=s(p),g=c(p);return d=typeof g=="function"?g(d):g,g=l(p),d=typeof g=="function"?g(d):g,g=a(p),typeof g=="function"?g(d):g}}return c=>{let l=s(c);for(let a=0;a<r;a++){let p=t[a](c);l=typeof p=="function"?p(l):p;}return l}}function Cn(n,e,i,f){let o=n.$fn,s=n.args;if(s===void 0)return ()=>{let c=e[o];if(!c)throw new Error(`Function not found in scope: ${o}`);return c};let t=s.map(c=>typeof c=="function"?()=>c:m(c,e,i,f)),r=t.length;if(r===0)return c=>{let l=e[o];if(!l)throw new Error(`Function not found in scope: ${o}`);return l()};if(r===1){let[c]=t;return l=>{let a=e[o];if(!a)throw new Error(`Function not found in scope: ${o}`);return a(c(l))}}if(r===2){let[c,l]=t;return a=>{let p=e[o];if(!p)throw new Error(`Function not found in scope: ${o}`);return p(c(a),l(a))}}if(r===3){let[c,l,a]=t;return p=>{let d=e[o];if(!d)throw new Error(`Function not found in scope: ${o}`);return d(c(p),l(p),a(p))}}return c=>{let l=e[o];if(!l)throw new Error(`Function not found in scope: ${o}`);return l(...t.map(a=>a(c)))}}function An(n,e,i,f){let o=m(n.left,e,i,f),s=n.right!==void 0?m(n.right,e,i,f):()=>{};switch(n.op){case "eq":return t=>o(t)===s(t);case "neq":return t=>o(t)!==s(t);case "gt":return t=>o(t)>s(t);case "gte":return t=>o(t)>=s(t);case "lt":return t=>o(t)<s(t);case "lte":return t=>o(t)<=s(t);case "in":return t=>{let r=s(t);return Array.isArray(r)&&r.includes(o(t))};case "notIn":return t=>{let r=s(t);return !Array.isArray(r)||!r.includes(o(t))};case "contains":return t=>{let r=o(t);return Array.isArray(r)&&r.includes(s(t))};case "notContains":return t=>{let r=o(t);return !Array.isArray(r)||!r.includes(s(t))};case "exists":return t=>o(t)!==void 0;case "notExists":return t=>o(t)===void 0;case "matches":return t=>{let r=o(t),c=s(t);return typeof r!="string"||typeof c!="string"?false:new RegExp(c).test(r)};case "notMatches":return t=>{let r=o(t),c=s(t);return typeof r!="string"||typeof c!="string"?true:!new RegExp(c).test(r)};case "startsWith":return t=>{let r=o(t),c=s(t);return typeof r=="string"&&typeof c=="string"&&r.startsWith(c)};case "endsWith":return t=>{let r=o(t),c=s(t);return typeof r=="string"&&typeof c=="string"&&r.endsWith(c)}}}function $n(n,e,i,f){let o=n.conditions.map(t=>m(t,e,i,f)),s=o.length;if(s===1)return t=>!!o[0](t);if(s===2){let[t,r]=o;return n.logic==="AND"?c=>!!t(c)&&!!r(c):c=>!!t(c)||!!r(c)}if(s===3){let[t,r,c]=o;return n.logic==="AND"?l=>!!t(l)&&!!r(l)&&!!c(l):l=>!!t(l)||!!r(l)||!!c(l)}return n.logic==="AND"?t=>{for(let r=0;r<s;r++)if(!o[r](t))return false;return true}:t=>{for(let r=0;r<s;r++)if(o[r](t))return true;return false}}function kn(n,e,i={}){return N(n,i).fn(e)}var v=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,i={}){let f=JSON.stringify(e),o=this.cache.get(f);if(o)return this.cache.delete(f),this.cache.set(f,o),o;let s=N(e,i);if(this.cache.size>=this._maxSize){let t=this.cache.keys().next().value;t&&this.cache.delete(t);}return this.cache.set(f,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);}}},Y=new v;function Sn(n,e={}){return Y.get(n,e)}function z(n,e="root",i={}){let f=[];return S(n,e,f,i),{valid:f.length===0,errors:f}}function S(n,e,i,f){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let t=0;t<n.length;t++)S(n[t],`${e}[${t}]`,i,f);return}if(h(n)){(!n.$||typeof n.$!="string")&&i.push(`${e}: invalid reference, $ must be non-empty string`);return}if(A(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||i.push(`${e}.$if: empty path in string shorthand`):S(n.$if,`${e}.$if`,i,f),S(n.then,`${e}.then`,i,f),n.else!==void 0&&S(n.else,`${e}.else`,i,f);return}if(k(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 t=0;t<n.$pipe.length;t++)S(n.$pipe[t],`${e}.$pipe[${t}]`,i,f);return}if($(n)){if(!n.$fn||typeof n.$fn!="string"){i.push(`${e}: invalid function, $fn must be non-empty string`);return}if(f.scope&&!(n.$fn in f.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 t=0;t<n.args.length;t++){let r=n.args[t];typeof r!="function"&&S(r,`${e}.args[${t}]`,i,f);}return}if(E(n)){F.has(n.op)||i.push(`${e}: invalid operator "${n.op}"`),S(n.left,`${e}.left`,i,f),n.right!==void 0&&S(n.right,`${e}.right`,i,f);return}if(T(n)){if(n.logic!=="AND"&&n.logic!=="OR"&&i.push(`${e}: invalid logic "${n.logic}", must be "AND" or "OR"`),!Array.isArray(n.conditions)){i.push(`${e}.conditions: must be an array`);return}for(let t=0;t<n.conditions.length;t++)S(n.conditions[t],`${e}.conditions[${t}]`,i,f);return}let o=n,s=Object.keys(o);for(let t=0;t<s.length;t++){let r=s[t];S(o[r],`${e}.${r}`,i,f);}}function wn(n,e={}){let i=z(n,"root",e);if(!i.valid)throw new Error(`Invalid expression: ${i.errors.join("; ")}`)}function Rn(n,e={}){return z(n,"root",e).valid}var Z={};sn(Z,{$:()=>H,$cond:()=>X,$fn:()=>Q,$if:()=>On,$pipe:()=>U,cond:()=>Nn,fn:()=>xn,pipe:()=>jn,ref:()=>Fn});function H(n){return {$:n}}var Fn=H;function Q(n,e){return e===void 0||e.length===0?{$fn:n}:{$fn:n,args:e}}var xn=Q;function On(n,e,i){return i===void 0?{$if:n,then:e}:{$if:n,then:e,else:i}}function U(...n){return {$pipe:n}}var jn=U;function X(n,e,i){return i===void 0?{left:n,op:e}:{left:n,op:e,right:i}}var Nn=X;var L="data",nn="scope",vn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function W(n,e={}){let{dataParam:i=L,scopeParam:f=nn,noPrefixes:o=false,useAccessor:s=false,lexicalPrefix:t,transforms:r}=e;return y(n,i,f,o,s,t,r)}function y(n,e,i,f,o,s,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(r=>y(r,e,i,f,o,s,t)));if(h(n))return Gn(n.$,e,f,o,s);if(A(n))return Dn(n,e,i,f,o,s,t);if(k(n))return Mn(n.$pipe,e,i,f,o,s,t);if($(n))return In(n,e,i,f,o,s,t);if(E(n))return zn(n,e,i,f,o,s,t);if(T(n))return Ln(n,e,i,f,o,s,t);if(t&&typeof n=="object"){let r=n,c=Object.keys(r);for(let l=0;l<c.length;l++){let a=c[l];if(a in t){let p=t[a](r);if(typeof p=="object"&&p!==null&&a in p)throw new Error(`Transform "${a}" returned object with same key \u2014 infinite loop`);return y(p,e,i,f,o,s,t)}}}if(typeof n=="object"){let c=Object.entries(n).map(([l,a])=>omniAst.builders.property(omniAst.builders.identifier(l),y(a,e,i,f,o,s,t)));return omniAst.builders.objectExpression(c)}return omniAst.builders.literal(null)}var V="accessor";function _(n,e){return e?n===e||n.startsWith(e+"."):false}function Gn(n,e,i,f,o){return f?_(n,o)?R(n,e,true):omniAst.builders.callExpression(omniAst.builders.identifier(V),[omniAst.builders.literal(n),omniAst.builders.identifier(e)]):n.includes("[*]")?Wn(n,e,i):R(n,e,i)}function R(n,e,i){let f=G(n);if(f.length===0)return i?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e);let o;if(i){let s=f[0];o=omniAst.builders.identifier(s.value);for(let t=1;t<f.length;t++){let r=f[t];r.type==="key"?o=omniAst.builders.memberExpression(o,omniAst.builders.identifier(r.value),false,true):o=omniAst.builders.memberExpression(o,omniAst.builders.literal(r.value),true,true);}}else {o=omniAst.builders.identifier(e);for(let s of f)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 Wn(n,e,i){let f=n.indexOf("[*]"),o=n.slice(0,f),s=n.slice(f+3),t;if(o?t=R(o,e,i):t=i?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e),!s||s==="")return t;if(s.includes("[*]"))return en(t,s);let r="_i",c=s.startsWith(".")?s.slice(1):s,l=omniAst.builders.identifier(r);if(c){let a=G(c);for(let p of a)p.type==="key"?l=omniAst.builders.memberExpression(l,omniAst.builders.identifier(p.value),false,true):l=omniAst.builders.memberExpression(l,omniAst.builders.literal(p.value),true,true);}return omniAst.builders.callExpression(omniAst.builders.memberExpression(t,omniAst.builders.identifier("map"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(r)],l)])}function en(n,e){let i=e.indexOf("[*]"),f=e.slice(0,i),o=e.slice(i+3),s="_i",t=f.startsWith(".")?f.slice(1):f,r=omniAst.builders.identifier(s);if(t){let l=G(t);for(let a of l)a.type==="key"&&(r=omniAst.builders.memberExpression(r,omniAst.builders.identifier(a.value),false,true));}if(o.includes("[*]")){let l=en(r,o);return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],l)])}let c=o.startsWith(".")?o.slice(1):o;if(c){let l=G(c);for(let a of l)a.type==="key"&&(r=omniAst.builders.memberExpression(r,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)],r)])}function Dn(n,e,i,f,o,s,t){let r;if(typeof n.$if=="string"){let a=n.$if.startsWith("!"),p=a?n.$if.slice(1):n.$if,d;o?_(p,s)?d=R(p,e,true):d=omniAst.builders.callExpression(omniAst.builders.identifier(V),[omniAst.builders.literal(p),omniAst.builders.identifier(e)]):d=R(p,e,f),r=a?omniAst.builders.unaryExpression("!",d):d;}else r=y(n.$if,e,i,f,o,s,t);let c=y(n.then,e,i,f,o,s,t),l=n.else!==void 0?y(n.else,e,i,f,o,s,t):omniAst.builders.identifier("undefined");return omniAst.builders.conditionalExpression(r,c,l)}function In(n,e,i,f,o,s,t){let r=f?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 r;let c=n.args.map(l=>typeof l=="function"?omniAst.builders.literal(null):y(l,e,i,f,o,s,t));return omniAst.builders.callExpression(r,c)}function Mn(n,e,i,f,o,s,t){if(n.length===0)return omniAst.builders.identifier("undefined");if(n.length===1)return y(n[0],e,i,f,o,s,t);let r=y(n[0],e,i,f,o,s,t);for(let c=1;c<n.length;c++){let l=y(n[c],e,i,f,o,s,t);r=omniAst.builders.callExpression(l,[r]);}return r}function P(n,e,i,f,o,s,t){if(h(n)){let r=n.$;return o?_(r,s)?R(r,e,true):omniAst.builders.callExpression(omniAst.builders.identifier(V),[omniAst.builders.literal(r),omniAst.builders.identifier(e)]):R(r,e,f)}return y(n,e,i,f,o,s,t)}function zn(n,e,i,f,o,s,t){let r=P(n.left,e,i,f,o,s,t),c=n.right!==void 0?P(n.right,e,i,f,o,s,t):omniAst.builders.literal(null),l=vn[n.op];if(l)return omniAst.builders.binaryExpression(l,r,c);switch(n.op){case "in":return omniAst.builders.callExpression(omniAst.builders.memberExpression(c,omniAst.builders.identifier("includes")),[r]);case "notIn":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(c,omniAst.builders.identifier("includes")),[r]));case "contains":return omniAst.builders.callExpression(omniAst.builders.memberExpression(r,omniAst.builders.identifier("includes"),false,true),[c]);case "notContains":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(r,omniAst.builders.identifier("includes"),false,true),[c]));case "exists":return omniAst.builders.binaryExpression("!=",r,omniAst.builders.literal(null));case "notExists":return omniAst.builders.binaryExpression("==",r,omniAst.builders.literal(null));case "matches":return omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[c]),omniAst.builders.identifier("test")),[r]);case "notMatches":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[c]),omniAst.builders.identifier("test")),[r]));case "startsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(r,omniAst.builders.identifier("startsWith"),false,true),[c]);case "endsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(r,omniAst.builders.identifier("endsWith"),false,true),[c]);default:return omniAst.builders.binaryExpression("===",r,c)}}function Ln(n,e,i,f,o,s,t){let{logic:r,conditions:c}=n,l=r==="AND"?"&&":"||";if(c.length===0)return omniAst.builders.literal(r==="AND");if(c.length===1)return y(c[0],e,i,f,o,s,t);let a=y(c[0],e,i,f,o,s,t);for(let p=1;p<c.length;p++){let d=y(c[p],e,i,f,o,s,t);a=omniAst.builders.logicalExpression(l,a,d);}return a}function G(n){let e=[],i=n.length,f=0,o="";for(;f<i;){let s=n[f];if(s===".")o&&(e.push({type:"key",value:o}),o=""),f++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),f++;let t=f;for(;f<i&&n[f]!=="]";)f++;let r=n.slice(t,f);if(f++,r!=="*"){let c=parseInt(r,10);e.push({type:"index",value:isNaN(c)?r:c});}}else o+=s,f++;}return o&&e.push({type:"key",value:o}),e}function tn(n,e=[L]){return omniAst.builders.arrowFunctionExpression(e.map(i=>omniAst.builders.identifier(i)),n)}function D(n,e){let i=new Set;return C(n,i,e),i}function C(n,e,i){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let o of n)C(o,e,i);return}if(h(n))return;if(A(n)){C(n.$if,e,i),C(n.then,e,i),n.else!==void 0&&C(n.else,e,i);return}if(k(n)){for(let o of n.$pipe)C(o,e,i);return}if($(n)){if(e.add(n.$fn),n.args)for(let o of n.args)typeof o!="function"&&C(o,e,i);return}if(E(n)){n.left!==void 0&&typeof n.left=="object"&&C(n.left,e,i),n.right!==void 0&&typeof n.right=="object"&&C(n.right,e,i);return}if(T(n)){for(let o of n.conditions)C(o,e,i);return}if(i){let o=n,s=Object.keys(o);for(let t=0;t<s.length;t++){let r=s[t];if(r in i){let c=i[r](o);if(typeof c=="object"&&c!==null&&r in c)throw new Error(`Transform "${r}" returned object with same key \u2014 infinite loop`);C(c,e,i);return}}}let f=n;for(let o of Object.keys(f))C(f[o],e,i);}function I(n){let e=new Set;for(let i of n){let f=i.indexOf("."),o=i.indexOf("["),s=i.length;f!==-1&&(s=Math.min(s,f)),o!==-1&&(s=Math.min(s,o));let t=i.slice(0,s);t&&e.add(t);}return e}function _n(n){return JSON.stringify(n)}function qn(n,e,i,f,o,s){let t=W(n,{noPrefixes:true,useAccessor:f,lexicalPrefix:o,transforms:s}),r=omniAst.generate(t),c="";f?o&&(c=`const{${o}}=data??{};`):e.size>0&&(c=`const{${[...e].join(",")}}=data??{};`);let l=f?new Set([...i,"accessor"]):i,a=l.size>0?`const{${[...l].join(",")}}=scope;`:"";return a?`(function(scope){${a}return function(data){${c}return ${r}}})`:`(function(){return function(data){${c}return ${r}}})`}function q(n,e={}){let{scope:i={},returnCode:f=false,useAccessor:o=false,lexicalPrefix:s,transforms:t}=e,r=w(n,t),c=I(r),l=D(n,t),a=_n(n),p=qn(n,c,l,o,s,t);if(f)return {code:p,deps:r,hash:a,dataRoots:[...c],scopeFns:[...l]};let d;try{d=new Function(`return ${p}`)()(i);}catch(g){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${g instanceof Error?g.message:String(g)}`)}return {fn:d,deps:r,hash:a}}function on(n,e,i={}){let{fn:f}=q(n,i);return f(e)}var Ee="0.1.1";exports.ExpressionCache=v;exports.VERSION=Ee;exports.assertValid=wn;exports.builders=Z;exports.cache=Y;exports.cached=Sn;exports.clearPathCache=dn;exports.compile=N;exports.compileAST=q;exports.compilePath=O;exports.dslToAST=W;exports.evaluate=kn;exports.evaluateAST=on;exports.extractDataRoots=I;exports.extractDeps=w;exports.extractScopeFns=D;exports.get=pn;exports.getPathCacheSize=gn;exports.hasDeps=yn;exports.hasWildcard=B;exports.isCondition=E;exports.isConditionExpr=fn;exports.isConditionGroup=T;exports.isConditional=A;exports.isFn=$;exports.isLiteral=M;exports.isPipe=k;exports.isPure=mn;exports.isRef=h;exports.isValid=Rn;exports.normalizePath=j;exports.validate=z;exports.wrapInFunction=tn;
|
package/dist/index.d.cts
CHANGED
|
@@ -133,6 +133,14 @@ interface ValidationResult {
|
|
|
133
133
|
* @example { add, subtract, multiply, filter, map, sum }
|
|
134
134
|
*/
|
|
135
135
|
type Scope = Record<string, (...args: any[]) => any>;
|
|
136
|
+
/**
|
|
137
|
+
* Options for compilation
|
|
138
|
+
*/
|
|
139
|
+
/**
|
|
140
|
+
* Transform function for custom expression types.
|
|
141
|
+
* Receives the raw node and must return a valid Expression.
|
|
142
|
+
*/
|
|
143
|
+
type TransformFn = (node: Record<string, unknown>) => Expression;
|
|
136
144
|
/**
|
|
137
145
|
* Options for compilation
|
|
138
146
|
*/
|
|
@@ -148,6 +156,13 @@ interface CompileOptions<T = unknown> {
|
|
|
148
156
|
* compile(expr, { accessor: (path, ctx) => ctx.get(path) })
|
|
149
157
|
*/
|
|
150
158
|
accessor?: AccessorFn<T>;
|
|
159
|
+
/**
|
|
160
|
+
* Custom expression transforms.
|
|
161
|
+
* Key = marker (e.g. "$query"), value = transform function.
|
|
162
|
+
* The walker calls the transform before treating as literal.
|
|
163
|
+
* The returned Expression is compiled recursively.
|
|
164
|
+
*/
|
|
165
|
+
transforms?: Record<string, TransformFn>;
|
|
151
166
|
}
|
|
152
167
|
/**
|
|
153
168
|
* Check if value is a reference expression
|
|
@@ -292,7 +307,7 @@ declare function getPathCacheSize(): number;
|
|
|
292
307
|
* @example { "$": "user.age" } → ["user.age"]
|
|
293
308
|
* @example { "$if": "$isVip", "then": { "$": "price.vip" } } → ["$isVip", "price.vip"]
|
|
294
309
|
*/
|
|
295
|
-
declare function extractDeps(expr: Expression): string[];
|
|
310
|
+
declare function extractDeps(expr: Expression, transforms?: Record<string, TransformFn>): string[];
|
|
296
311
|
/**
|
|
297
312
|
* Check if expression has dependencies
|
|
298
313
|
*/
|
|
@@ -547,6 +562,11 @@ interface TransformOptions {
|
|
|
547
562
|
* - `lexicalPrefix: "params"` → `params?.foo` instead of `accessor("params.foo", data)`
|
|
548
563
|
*/
|
|
549
564
|
lexicalPrefix?: string;
|
|
565
|
+
/**
|
|
566
|
+
* Custom expression transforms.
|
|
567
|
+
* Key = marker (e.g. "$query"), value = transform function.
|
|
568
|
+
*/
|
|
569
|
+
transforms?: Record<string, TransformFn>;
|
|
550
570
|
}
|
|
551
571
|
/**
|
|
552
572
|
* Transform DSL expression to AST node
|
|
@@ -583,6 +603,7 @@ declare function wrapInFunction(bodyAst: ASTNode, params?: string[]): ASTNode;
|
|
|
583
603
|
* Extract all function names used from scope in an expression
|
|
584
604
|
*
|
|
585
605
|
* @param expr - DSL expression to analyze
|
|
606
|
+
* @param transforms - Optional custom transforms (to resolve custom nodes before collecting)
|
|
586
607
|
* @returns Set of function names used
|
|
587
608
|
*
|
|
588
609
|
* @example
|
|
@@ -600,7 +621,7 @@ declare function wrapInFunction(bodyAst: ASTNode, params?: string[]): ASTNode;
|
|
|
600
621
|
* // Set { "filter", "sum" }
|
|
601
622
|
* ```
|
|
602
623
|
*/
|
|
603
|
-
declare function extractScopeFns(expr: Expression): Set<string>;
|
|
624
|
+
declare function extractScopeFns(expr: Expression, transforms?: Record<string, TransformFn>): Set<string>;
|
|
604
625
|
/**
|
|
605
626
|
* Extract root-level data dependencies from paths
|
|
606
627
|
*
|
|
@@ -642,6 +663,11 @@ interface CompileASTOptions {
|
|
|
642
663
|
* - `lexicalPrefix: "params"` → `params?.foo` instead of `accessor("params.foo", data)`
|
|
643
664
|
*/
|
|
644
665
|
lexicalPrefix?: string;
|
|
666
|
+
/**
|
|
667
|
+
* Custom expression transforms.
|
|
668
|
+
* Key = marker (e.g. "$query"), value = transform function.
|
|
669
|
+
*/
|
|
670
|
+
transforms?: Record<string, TransformFn>;
|
|
645
671
|
}
|
|
646
672
|
/** Result when returnCode is true */
|
|
647
673
|
interface CompileASTCodeResult {
|
|
@@ -726,4 +752,4 @@ declare function evaluateAST<T = unknown, R = unknown>(expr: Expression, data: T
|
|
|
726
752
|
*/
|
|
727
753
|
declare const VERSION = "0.1.1";
|
|
728
754
|
|
|
729
|
-
export { type AccessorFn, type CallbackFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type Condition, type ConditionExpr, type ConditionGroup, type ConditionOp, type ConditionalExpr, type Expression, ExpressionCache, type FnArg, 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 };
|
|
755
|
+
export { type AccessorFn, type CallbackFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type Condition, type ConditionExpr, type ConditionGroup, type ConditionOp, type ConditionalExpr, type Expression, ExpressionCache, type FnArg, type FnExpr, type Literal, type PathGetter, type PipeExpr, type RefExpr, type Scope, type TransformFn, 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
|
@@ -133,6 +133,14 @@ interface ValidationResult {
|
|
|
133
133
|
* @example { add, subtract, multiply, filter, map, sum }
|
|
134
134
|
*/
|
|
135
135
|
type Scope = Record<string, (...args: any[]) => any>;
|
|
136
|
+
/**
|
|
137
|
+
* Options for compilation
|
|
138
|
+
*/
|
|
139
|
+
/**
|
|
140
|
+
* Transform function for custom expression types.
|
|
141
|
+
* Receives the raw node and must return a valid Expression.
|
|
142
|
+
*/
|
|
143
|
+
type TransformFn = (node: Record<string, unknown>) => Expression;
|
|
136
144
|
/**
|
|
137
145
|
* Options for compilation
|
|
138
146
|
*/
|
|
@@ -148,6 +156,13 @@ interface CompileOptions<T = unknown> {
|
|
|
148
156
|
* compile(expr, { accessor: (path, ctx) => ctx.get(path) })
|
|
149
157
|
*/
|
|
150
158
|
accessor?: AccessorFn<T>;
|
|
159
|
+
/**
|
|
160
|
+
* Custom expression transforms.
|
|
161
|
+
* Key = marker (e.g. "$query"), value = transform function.
|
|
162
|
+
* The walker calls the transform before treating as literal.
|
|
163
|
+
* The returned Expression is compiled recursively.
|
|
164
|
+
*/
|
|
165
|
+
transforms?: Record<string, TransformFn>;
|
|
151
166
|
}
|
|
152
167
|
/**
|
|
153
168
|
* Check if value is a reference expression
|
|
@@ -292,7 +307,7 @@ declare function getPathCacheSize(): number;
|
|
|
292
307
|
* @example { "$": "user.age" } → ["user.age"]
|
|
293
308
|
* @example { "$if": "$isVip", "then": { "$": "price.vip" } } → ["$isVip", "price.vip"]
|
|
294
309
|
*/
|
|
295
|
-
declare function extractDeps(expr: Expression): string[];
|
|
310
|
+
declare function extractDeps(expr: Expression, transforms?: Record<string, TransformFn>): string[];
|
|
296
311
|
/**
|
|
297
312
|
* Check if expression has dependencies
|
|
298
313
|
*/
|
|
@@ -547,6 +562,11 @@ interface TransformOptions {
|
|
|
547
562
|
* - `lexicalPrefix: "params"` → `params?.foo` instead of `accessor("params.foo", data)`
|
|
548
563
|
*/
|
|
549
564
|
lexicalPrefix?: string;
|
|
565
|
+
/**
|
|
566
|
+
* Custom expression transforms.
|
|
567
|
+
* Key = marker (e.g. "$query"), value = transform function.
|
|
568
|
+
*/
|
|
569
|
+
transforms?: Record<string, TransformFn>;
|
|
550
570
|
}
|
|
551
571
|
/**
|
|
552
572
|
* Transform DSL expression to AST node
|
|
@@ -583,6 +603,7 @@ declare function wrapInFunction(bodyAst: ASTNode, params?: string[]): ASTNode;
|
|
|
583
603
|
* Extract all function names used from scope in an expression
|
|
584
604
|
*
|
|
585
605
|
* @param expr - DSL expression to analyze
|
|
606
|
+
* @param transforms - Optional custom transforms (to resolve custom nodes before collecting)
|
|
586
607
|
* @returns Set of function names used
|
|
587
608
|
*
|
|
588
609
|
* @example
|
|
@@ -600,7 +621,7 @@ declare function wrapInFunction(bodyAst: ASTNode, params?: string[]): ASTNode;
|
|
|
600
621
|
* // Set { "filter", "sum" }
|
|
601
622
|
* ```
|
|
602
623
|
*/
|
|
603
|
-
declare function extractScopeFns(expr: Expression): Set<string>;
|
|
624
|
+
declare function extractScopeFns(expr: Expression, transforms?: Record<string, TransformFn>): Set<string>;
|
|
604
625
|
/**
|
|
605
626
|
* Extract root-level data dependencies from paths
|
|
606
627
|
*
|
|
@@ -642,6 +663,11 @@ interface CompileASTOptions {
|
|
|
642
663
|
* - `lexicalPrefix: "params"` → `params?.foo` instead of `accessor("params.foo", data)`
|
|
643
664
|
*/
|
|
644
665
|
lexicalPrefix?: string;
|
|
666
|
+
/**
|
|
667
|
+
* Custom expression transforms.
|
|
668
|
+
* Key = marker (e.g. "$query"), value = transform function.
|
|
669
|
+
*/
|
|
670
|
+
transforms?: Record<string, TransformFn>;
|
|
645
671
|
}
|
|
646
672
|
/** Result when returnCode is true */
|
|
647
673
|
interface CompileASTCodeResult {
|
|
@@ -726,4 +752,4 @@ declare function evaluateAST<T = unknown, R = unknown>(expr: Expression, data: T
|
|
|
726
752
|
*/
|
|
727
753
|
declare const VERSION = "0.1.1";
|
|
728
754
|
|
|
729
|
-
export { type AccessorFn, type CallbackFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type Condition, type ConditionExpr, type ConditionGroup, type ConditionOp, type ConditionalExpr, type Expression, ExpressionCache, type FnArg, 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 };
|
|
755
|
+
export { type AccessorFn, type CallbackFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type Condition, type ConditionExpr, type ConditionGroup, type ConditionOp, type ConditionalExpr, type Expression, ExpressionCache, type FnArg, type FnExpr, type Literal, type PathGetter, type PipeExpr, type RefExpr, type Scope, type TransformFn, 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 {builders,generate}from'omni-ast';var on=Object.defineProperty;var rn=(n,t)=>{for(var s in t)on(n,s,{get:t[s],enumerable:true});};var y=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,T=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,b=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),x=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),h=n=>n!==null&&typeof n=="object"&&"left"in n&&"op"in n&&x.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),E=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,sn=n=>h(n)||E(n),I=n=>{if(n===null)return true;let t=typeof n;if(t==="string"||t==="number"||t==="boolean"||Array.isArray(n))return true;if(t==="object"&&n!==null){let s=n,e="left"in s&&"op"in s&&x.has(s.op);return !("$"in s)&&!("$if"in s)&&!("$fn"in s)&&!("$pipe"in s)&&!e&&!("logic"in s)}return false};var R=new Map;function q(n){let t=[],s=n.length,e=0,r="";for(;e<s;){let o=n[e];if(o===".")r&&(t.push({type:"key",value:r}),r=""),e++;else if(o==="["){r&&(t.push({type:"key",value:r}),r=""),e++;let i=e;for(;e<s&&n[e]!=="]";)e++;let f=n.slice(i,e);if(e++,f==="*")t.push({type:"wildcard",value:"*"});else {let l=parseInt(f,10);t.push({type:"index",value:isNaN(l)?f:l});}}else r+=o,e++;}return r&&t.push({type:"key",value:r}),t}function J(n){return n.includes("[*]")}function O(n){let t=R.get(n);return t||(t=J(n)?un(n):fn(n),R.set(n,t),t)}function fn(n){if(!n.includes(".")&&!n.includes("["))return r=>r?.[n];let t=q(n),s=t.length;if(s===2){let[r,o]=t,i=r.value,f=o.value;return l=>l?.[i]?.[f]}if(s===3){let[r,o,i]=t,f=r.value,l=o.value,c=i.value;return a=>a?.[f]?.[l]?.[c]}let e=t.map(r=>r.value);return r=>{let o=r;for(let i=0;i<s&&o!=null;i++)o=o[e[i]];return o}}function un(n){let t=q(n),s=[];for(let e=0;e<t.length;e++)t[e].type==="wildcard"&&s.push(e);return s.length===1?ln(t,s[0]):cn(t,s)}function ln(n,t){let s=n.slice(0,t).map(i=>i.value),e=n.slice(t+1).map(i=>i.value),r=s.length,o=e.length;if(o===0){if(r===1){let i=s[0];return f=>f?.[i]}return i=>{let f=i;for(let l=0;l<r&&f!=null;l++)f=f[s[l]];return f}}if(o===1){let i=e[0];if(r===1){let f=s[0];return l=>{let c=l?.[f];if(Array.isArray(c))return c.map(a=>a?.[i])}}return f=>{let l=f;for(let c=0;c<r&&l!=null;c++)l=l[s[c]];if(Array.isArray(l))return l.map(c=>c?.[i])}}return i=>{let f=i;for(let l=0;l<r&&f!=null;l++)f=f[s[l]];if(Array.isArray(f))return f.map(l=>{let c=l;for(let a=0;a<o&&c!=null;a++)c=c[e[a]];return c})}}function cn(n,t){let s=[],e=0;for(let o=0;o<t.length;o++){let i=t[o],f=o===t.length-1,l=n.slice(e,i).map(c=>c.value);l.length>0&&s.push({type:"access",keys:l}),s.push({type:f?"map":"flatMap",keys:[]}),e=i+1;}let r=n.slice(e).map(o=>o.value);return o=>{let i=o;for(let f of s){if(i==null)return;if(f.type==="access")for(let l of f.keys){if(i==null)return;i=i[l];}else if(f.type==="flatMap"){if(!Array.isArray(i))return;i=i.flatMap(l=>{let c=l;return Array.isArray(c)?c:[c]});}else if(f.type==="map"){if(!Array.isArray(i))return;r.length>0&&(i=i.map(l=>{let c=l;for(let a of r){if(c==null)return;c=c[a];}return c}));}}return i}}function an(n,t){return O(t)(n)}function F(n){let t=n.indexOf("[*]");return t===-1?n:n.slice(0,t)}function pn(){R.clear();}function dn(){return R.size}function k(n){let t=new Set;return A(n,t),Array.from(t)}function A(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r=0;r<n.length;r++)A(n[r],t);return}if(y(n)){t.add(F(n.$));return}if(T(n)){if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if;t.add(F(r));}else A(n.$if,t);A(n.then,t),n.else!==void 0&&A(n.else,t);return}if(C(n)){for(let r=0;r<n.$pipe.length;r++)A(n.$pipe[r],t);return}if(b(n)){if(n.args)for(let r=0;r<n.args.length;r++){let o=n.args[r];typeof o!="function"&&A(o,t);}return}if(h(n)){A(n.left,t),n.right!==void 0&&A(n.right,t);return}if(E(n)){for(let r=0;r<n.conditions.length;r++)A(n.conditions[r],t);return}let s=n,e=Object.keys(s);for(let r=0;r<e.length;r++)A(s[e[r]],t);}function gn(n){return k(n).length>0}function mn(n){return k(n).length===0}function yn(n){return JSON.stringify(n)}function N(n,t={}){let s=t.scope??{},e=t.accessor,r=m(n,s,e),o=k(n),i=yn(n);return {fn:r,deps:o,hash:i}}function m(n,t,s){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let e=n.map(r=>m(r,t,s));return r=>e.map(o=>o(r))}if(y(n))return hn(n,s);if(T(n))return En(n,t,s);if(C(n))return Tn(n,t,s);if(b(n))return bn(n,t,s);if(h(n))return Cn(n,t,s);if(E(n))return An(n,t,s);if(I(n)){let e=n,r=Object.keys(e),o=r.map(i=>m(e[i],t,s));return i=>{let f={};for(let l=0;l<r.length;l++)f[r[l]]=o[l](i);return f}}return ()=>n}function B(n,t){return t?s=>t(n,s):O(n)}function hn(n,t){return B(n.$,t)}function En(n,t,s){let e;if(typeof n.$if=="string"){let i=n.$if.startsWith("!")?n.$if.slice(1):n.$if,f=B(i,s);e=n.$if.startsWith("!")?c=>!f(c):c=>!!f(c);}else {let i=m(n.$if,t,s);e=f=>!!i(f);}let r=m(n.then,t,s),o=n.else!==void 0?m(n.else,t,s):()=>{};return i=>e(i)?r(i):o(i)}function Tn(n,t,s){let e=n.$pipe;if(e.length===0)return ()=>{};if(e.length===1)return m(e[0],t,s);let r=m(e[0],t,s),o=e.slice(1).map(f=>m(f,t,s)),i=o.length;if(i===1){let[f]=o;return l=>{let c=r(l),a=f(l);return typeof a=="function"?a(c):a}}if(i===2){let[f,l]=o;return c=>{let a=r(c),p=f(c);return a=typeof p=="function"?p(a):p,p=l(c),typeof p=="function"?p(a):p}}if(i===3){let[f,l,c]=o;return a=>{let p=r(a),d=f(a);return p=typeof d=="function"?d(p):d,d=l(a),p=typeof d=="function"?d(p):d,d=c(a),typeof d=="function"?d(p):d}}return f=>{let l=r(f);for(let c=0;c<i;c++){let a=o[c](f);l=typeof a=="function"?a(l):a;}return l}}function bn(n,t,s){let e=n.$fn,r=n.args;if(r===void 0)return ()=>{let f=t[e];if(!f)throw new Error(`Function not found in scope: ${e}`);return f};let o=r.map(f=>typeof f=="function"?()=>f:m(f,t,s)),i=o.length;if(i===0)return f=>{let l=t[e];if(!l)throw new Error(`Function not found in scope: ${e}`);return l()};if(i===1){let[f]=o;return l=>{let c=t[e];if(!c)throw new Error(`Function not found in scope: ${e}`);return c(f(l))}}if(i===2){let[f,l]=o;return c=>{let a=t[e];if(!a)throw new Error(`Function not found in scope: ${e}`);return a(f(c),l(c))}}if(i===3){let[f,l,c]=o;return a=>{let p=t[e];if(!p)throw new Error(`Function not found in scope: ${e}`);return p(f(a),l(a),c(a))}}return f=>{let l=t[e];if(!l)throw new Error(`Function not found in scope: ${e}`);return l(...o.map(c=>c(f)))}}function Cn(n,t,s){let e=m(n.left,t,s),r=n.right!==void 0?m(n.right,t,s):()=>{};switch(n.op){case "eq":return o=>e(o)===r(o);case "neq":return o=>e(o)!==r(o);case "gt":return o=>e(o)>r(o);case "gte":return o=>e(o)>=r(o);case "lt":return o=>e(o)<r(o);case "lte":return o=>e(o)<=r(o);case "in":return o=>{let i=r(o);return Array.isArray(i)&&i.includes(e(o))};case "notIn":return o=>{let i=r(o);return !Array.isArray(i)||!i.includes(e(o))};case "contains":return o=>{let i=e(o);return Array.isArray(i)&&i.includes(r(o))};case "notContains":return o=>{let i=e(o);return !Array.isArray(i)||!i.includes(r(o))};case "exists":return o=>e(o)!==void 0;case "notExists":return o=>e(o)===void 0;case "matches":return o=>{let i=e(o),f=r(o);return typeof i!="string"||typeof f!="string"?false:new RegExp(f).test(i)};case "notMatches":return o=>{let i=e(o),f=r(o);return typeof i!="string"||typeof f!="string"?true:!new RegExp(f).test(i)};case "startsWith":return o=>{let i=e(o),f=r(o);return typeof i=="string"&&typeof f=="string"&&i.startsWith(f)};case "endsWith":return o=>{let i=e(o),f=r(o);return typeof i=="string"&&typeof f=="string"&&i.endsWith(f)}}}function An(n,t,s){let e=n.conditions.map(o=>m(o,t,s)),r=e.length;if(r===1)return o=>!!e[0](o);if(r===2){let[o,i]=e;return n.logic==="AND"?f=>!!o(f)&&!!i(f):f=>!!o(f)||!!i(f)}if(r===3){let[o,i,f]=e;return n.logic==="AND"?l=>!!o(l)&&!!i(l)&&!!f(l):l=>!!o(l)||!!i(l)||!!f(l)}return n.logic==="AND"?o=>{for(let i=0;i<r;i++)if(!e[i](o))return false;return true}:o=>{for(let i=0;i<r;i++)if(e[i](o))return true;return false}}function $n(n,t,s={}){return N(n,s).fn(t)}var v=class{constructor(t=1e3){this.cache=new Map,this._maxSize=t;}get(t,s={}){let e=JSON.stringify(t),r=this.cache.get(e);if(r)return this.cache.delete(e),this.cache.set(e,r),r;let o=N(t,s);if(this.cache.size>=this._maxSize){let i=this.cache.keys().next().value;i&&this.cache.delete(i);}return this.cache.set(e,o),o}has(t){return this.cache.has(JSON.stringify(t))}delete(t){return this.cache.delete(JSON.stringify(t))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(t){for(this._maxSize=t;this.cache.size>this._maxSize;){let s=this.cache.keys().next().value;s&&this.cache.delete(s);}}},K=new v;function Sn(n,t={}){return K.get(n,t)}function M(n,t="root",s={}){let e=[];return $(n,t,e,s),{valid:e.length===0,errors:e}}function $(n,t,s,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let i=0;i<n.length;i++)$(n[i],`${t}[${i}]`,s,e);return}if(y(n)){(!n.$||typeof n.$!="string")&&s.push(`${t}: invalid reference, $ must be non-empty string`);return}if(T(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||s.push(`${t}.$if: empty path in string shorthand`):$(n.$if,`${t}.$if`,s,e),$(n.then,`${t}.then`,s,e),n.else!==void 0&&$(n.else,`${t}.else`,s,e);return}if(C(n)){if(!Array.isArray(n.$pipe)){s.push(`${t}.$pipe: must be an array`);return}if(n.$pipe.length===0){s.push(`${t}.$pipe: must have at least one element`);return}for(let i=0;i<n.$pipe.length;i++)$(n.$pipe[i],`${t}.$pipe[${i}]`,s,e);return}if(b(n)){if(!n.$fn||typeof n.$fn!="string"){s.push(`${t}: invalid function, $fn must be non-empty string`);return}if(e.scope&&!(n.$fn in e.scope)&&s.push(`${t}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))s.push(`${t}.args: must be an array`);else for(let i=0;i<n.args.length;i++){let f=n.args[i];typeof f!="function"&&$(f,`${t}.args[${i}]`,s,e);}return}if(h(n)){x.has(n.op)||s.push(`${t}: invalid operator "${n.op}"`),$(n.left,`${t}.left`,s,e),n.right!==void 0&&$(n.right,`${t}.right`,s,e);return}if(E(n)){if(n.logic!=="AND"&&n.logic!=="OR"&&s.push(`${t}: invalid logic "${n.logic}", must be "AND" or "OR"`),!Array.isArray(n.conditions)){s.push(`${t}.conditions: must be an array`);return}for(let i=0;i<n.conditions.length;i++)$(n.conditions[i],`${t}.conditions[${i}]`,s,e);return}let r=n,o=Object.keys(r);for(let i=0;i<o.length;i++){let f=o[i];$(r[f],`${t}.${f}`,s,e);}}function kn(n,t={}){let s=M(n,"root",t);if(!s.valid)throw new Error(`Invalid expression: ${s.errors.join("; ")}`)}function wn(n,t={}){return M(n,"root",t).valid}var U={};rn(U,{$:()=>P,$cond:()=>Q,$fn:()=>Y,$if:()=>On,$pipe:()=>H,cond:()=>Nn,fn:()=>Rn,pipe:()=>Fn,ref:()=>xn});function P(n){return {$:n}}var xn=P;function Y(n,t){return t===void 0||t.length===0?{$fn:n}:{$fn:n,args:t}}var Rn=Y;function On(n,t,s){return s===void 0?{$if:n,then:t}:{$if:n,then:t,else:s}}function H(...n){return {$pipe:n}}var Fn=H;function Q(n,t,s){return s===void 0?{left:n,op:t}:{left:n,op:t,right:s}}var Nn=Q;var z="data",Z="scope",vn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function G(n,t={}){let{dataParam:s=z,scopeParam:e=Z,noPrefixes:r=false,useAccessor:o=false,lexicalPrefix:i}=t;return g(n,s,e,r,o,i)}function g(n,t,s,e,r,o){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=>g(i,t,s,e,r,o)));if(y(n))return jn(n.$,t,e,r,o);if(T(n))return Wn(n,t,s,e,r,o);if(C(n))return In(n.$pipe,t,s,e,r,o);if(b(n))return Dn(n,t,s,e,r,o);if(h(n))return Mn(n,t,s,e,r,o);if(E(n))return zn(n,t,s,e,r,o);if(typeof n=="object"){let f=Object.entries(n).map(([l,c])=>builders.property(builders.identifier(l),g(c,t,s,e,r,o)));return builders.objectExpression(f)}return builders.literal(null)}var L="accessor";function V(n,t){return t?n===t||n.startsWith(t+"."):false}function jn(n,t,s,e,r){return e?V(n,r)?w(n,t,true):builders.callExpression(builders.identifier(L),[builders.literal(n),builders.identifier(t)]):n.includes("[*]")?Gn(n,t,s):w(n,t,s)}function w(n,t,s){let e=j(n);if(e.length===0)return s?builders.identifier("undefined"):builders.identifier(t);let r;if(s){let o=e[0];r=builders.identifier(o.value);for(let i=1;i<e.length;i++){let f=e[i];f.type==="key"?r=builders.memberExpression(r,builders.identifier(f.value),false,true):r=builders.memberExpression(r,builders.literal(f.value),true,true);}}else {r=builders.identifier(t);for(let o of e)o.type==="key"?r=builders.memberExpression(r,builders.identifier(o.value),false,true):r=builders.memberExpression(r,builders.literal(o.value),true,true);}return r}function Gn(n,t,s){let e=n.indexOf("[*]"),r=n.slice(0,e),o=n.slice(e+3),i;if(r?i=w(r,t,s):i=s?builders.identifier("undefined"):builders.identifier(t),!o||o==="")return i;if(o.includes("[*]"))return nn(i,o);let f="_i",l=o.startsWith(".")?o.slice(1):o,c=builders.identifier(f);if(l){let a=j(l);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(i,builders.identifier("map"),false,true),[builders.arrowFunctionExpression([builders.identifier(f)],c)])}function nn(n,t){let s=t.indexOf("[*]"),e=t.slice(0,s),r=t.slice(s+3),o="_i",i=e.startsWith(".")?e.slice(1):e,f=builders.identifier(o);if(i){let c=j(i);for(let a of c)a.type==="key"&&(f=builders.memberExpression(f,builders.identifier(a.value),false,true));}if(r.includes("[*]")){let c=nn(f,r);return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(o)],c)])}let l=r.startsWith(".")?r.slice(1):r;if(l){let c=j(l);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(o)],f)])}function Wn(n,t,s,e,r,o){let i;if(typeof n.$if=="string"){let c=n.$if.startsWith("!"),a=c?n.$if.slice(1):n.$if,p;r?V(a,o)?p=w(a,t,true):p=builders.callExpression(builders.identifier(L),[builders.literal(a),builders.identifier(t)]):p=w(a,t,e),i=c?builders.unaryExpression("!",p):p;}else i=g(n.$if,t,s,e,r,o);let f=g(n.then,t,s,e,r,o),l=n.else!==void 0?g(n.else,t,s,e,r,o):builders.identifier("undefined");return builders.conditionalExpression(i,f,l)}function Dn(n,t,s,e,r,o){let i=e?builders.identifier(n.$fn):builders.memberExpression(builders.identifier(s),builders.identifier(n.$fn),false,false);if(n.args===void 0)return i;let f=n.args.map(l=>typeof l=="function"?builders.literal(null):g(l,t,s,e,r,o));return builders.callExpression(i,f)}function In(n,t,s,e,r,o){if(n.length===0)return builders.identifier("undefined");if(n.length===1)return g(n[0],t,s,e,r,o);let i=g(n[0],t,s,e,r,o);for(let f=1;f<n.length;f++){let l=g(n[f],t,s,e,r,o);i=builders.callExpression(l,[i]);}return i}function X(n,t,s,e,r,o){if(y(n)){let i=n.$;return r?V(i,o)?w(i,t,true):builders.callExpression(builders.identifier(L),[builders.literal(i),builders.identifier(t)]):w(i,t,e)}return g(n,t,s,e,r,o)}function Mn(n,t,s,e,r,o){let i=X(n.left,t,s,e,r,o),f=n.right!==void 0?X(n.right,t,s,e,r,o):builders.literal(null),l=vn[n.op];if(l)return builders.binaryExpression(l,i,f);switch(n.op){case "in":return builders.callExpression(builders.memberExpression(f,builders.identifier("includes")),[i]);case "notIn":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(f,builders.identifier("includes")),[i]));case "contains":return builders.callExpression(builders.memberExpression(i,builders.identifier("includes"),false,true),[f]);case "notContains":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(i,builders.identifier("includes"),false,true),[f]));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"),[f]),builders.identifier("test")),[i]);case "notMatches":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[f]),builders.identifier("test")),[i]));case "startsWith":return builders.callExpression(builders.memberExpression(i,builders.identifier("startsWith"),false,true),[f]);case "endsWith":return builders.callExpression(builders.memberExpression(i,builders.identifier("endsWith"),false,true),[f]);default:return builders.binaryExpression("===",i,f)}}function zn(n,t,s,e,r,o){let{logic:i,conditions:f}=n,l=i==="AND"?"&&":"||";if(f.length===0)return builders.literal(i==="AND");if(f.length===1)return g(f[0],t,s,e,r,o);let c=g(f[0],t,s,e,r,o);for(let a=1;a<f.length;a++){let p=g(f[a],t,s,e,r,o);c=builders.logicalExpression(l,c,p);}return c}function j(n){let t=[],s=n.length,e=0,r="";for(;e<s;){let o=n[e];if(o===".")r&&(t.push({type:"key",value:r}),r=""),e++;else if(o==="["){r&&(t.push({type:"key",value:r}),r=""),e++;let i=e;for(;e<s&&n[e]!=="]";)e++;let f=n.slice(i,e);if(e++,f!=="*"){let l=parseInt(f,10);t.push({type:"index",value:isNaN(l)?f:l});}}else r+=o,e++;}return r&&t.push({type:"key",value:r}),t}function tn(n,t=[z]){return builders.arrowFunctionExpression(t.map(s=>builders.identifier(s)),n)}function W(n){let t=new Set;return S(n,t),t}function S(n,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let e of n)S(e,t);return}if(y(n))return;if(T(n)){S(n.$if,t),S(n.then,t),n.else!==void 0&&S(n.else,t);return}if(C(n)){for(let e of n.$pipe)S(e,t);return}if(b(n)){if(t.add(n.$fn),n.args)for(let e of n.args)typeof e!="function"&&S(e,t);return}if(h(n)){n.left!==void 0&&typeof n.left=="object"&&S(n.left,t),n.right!==void 0&&typeof n.right=="object"&&S(n.right,t);return}if(E(n)){for(let e of n.conditions)S(e,t);return}let s=n;for(let e of Object.keys(s))S(s[e],t);}function D(n){let t=new Set;for(let s of n){let e=s.indexOf("."),r=s.indexOf("["),o=s.length;e!==-1&&(o=Math.min(o,e)),r!==-1&&(o=Math.min(o,r));let i=s.slice(0,o);i&&t.add(i);}return t}function Vn(n){return JSON.stringify(n)}function _n(n,t,s,e,r){let o=G(n,{noPrefixes:true,useAccessor:e,lexicalPrefix:r}),i=generate(o),f="";e?r&&(f=`const{${r}}=data??{};`):t.size>0&&(f=`const{${[...t].join(",")}}=data??{};`);let l=e?new Set([...s,"accessor"]):s,c=l.size>0?`const{${[...l].join(",")}}=scope;`:"";return c?`(function(scope){${c}return function(data){${f}return ${i}}})`:`(function(){return function(data){${f}return ${i}}})`}function _(n,t={}){let{scope:s={},returnCode:e=false,useAccessor:r=false,lexicalPrefix:o}=t,i=k(n),f=D(i),l=W(n),c=Vn(n),a=_n(n,f,l,r,o);if(e)return {code:a,deps:i,hash:c,dataRoots:[...f],scopeFns:[...l]};let p;try{p=new Function(`return ${a}`)()(s);}catch(d){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${d instanceof Error?d.message:String(d)}`)}return {fn:p,deps:i,hash:c}}function en(n,t,s={}){let{fn:e}=_(n,s);return e(t)}var ht="0.1.1";export{v as ExpressionCache,ht as VERSION,kn as assertValid,U as builders,K as cache,Sn as cached,pn as clearPathCache,N as compile,_ as compileAST,O as compilePath,G as dslToAST,$n as evaluate,en as evaluateAST,D as extractDataRoots,k as extractDeps,W as extractScopeFns,an as get,dn as getPathCacheSize,gn as hasDeps,J as hasWildcard,h as isCondition,sn as isConditionExpr,E as isConditionGroup,T as isConditional,b as isFn,I as isLiteral,C as isPipe,mn as isPure,y as isRef,wn as isValid,F as normalizePath,M as validate,tn as wrapInFunction};
|
|
1
|
+
import {builders,generate}from'omni-ast';var rn=Object.defineProperty;var sn=(n,e)=>{for(var i in e)rn(n,i,{get:e[i],enumerable:true});};var h=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,A=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,$=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",k=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),F=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),E=n=>n!==null&&typeof n=="object"&&"left"in n&&"op"in n&&F.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),T=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,fn=n=>E(n)||T(n),M=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,f="left"in i&&"op"in i&&F.has(i.op);return !("$"in i)&&!("$if"in i)&&!("$fn"in i)&&!("$pipe"in i)&&!f&&!("logic"in i)}return false};var x=new Map;function J(n){let e=[],i=n.length,f=0,o="";for(;f<i;){let s=n[f];if(s===".")o&&(e.push({type:"key",value:o}),o=""),f++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),f++;let t=f;for(;f<i&&n[f]!=="]";)f++;let r=n.slice(t,f);if(f++,r==="*")e.push({type:"wildcard",value:"*"});else {let c=parseInt(r,10);e.push({type:"index",value:isNaN(c)?r:c});}}else o+=s,f++;}return o&&e.push({type:"key",value:o}),e}function B(n){return n.includes("[*]")}function O(n){let e=x.get(n);return e||(e=B(n)?un(n):cn(n),x.set(n,e),e)}function cn(n){if(!n.includes(".")&&!n.includes("["))return o=>o?.[n];let e=J(n),i=e.length;if(i===2){let[o,s]=e,t=o.value,r=s.value;return c=>c?.[t]?.[r]}if(i===3){let[o,s,t]=e,r=o.value,c=s.value,l=t.value;return a=>a?.[r]?.[c]?.[l]}let f=e.map(o=>o.value);return o=>{let s=o;for(let t=0;t<i&&s!=null;t++)s=s[f[t]];return s}}function un(n){let e=J(n),i=[];for(let f=0;f<e.length;f++)e[f].type==="wildcard"&&i.push(f);return i.length===1?ln(e,i[0]):an(e,i)}function ln(n,e){let i=n.slice(0,e).map(t=>t.value),f=n.slice(e+1).map(t=>t.value),o=i.length,s=f.length;if(s===0){if(o===1){let t=i[0];return r=>r?.[t]}return t=>{let r=t;for(let c=0;c<o&&r!=null;c++)r=r[i[c]];return r}}if(s===1){let t=f[0];if(o===1){let r=i[0];return c=>{let l=c?.[r];if(Array.isArray(l))return l.map(a=>a?.[t])}}return r=>{let c=r;for(let l=0;l<o&&c!=null;l++)c=c[i[l]];if(Array.isArray(c))return c.map(l=>l?.[t])}}return t=>{let r=t;for(let c=0;c<o&&r!=null;c++)r=r[i[c]];if(Array.isArray(r))return r.map(c=>{let l=c;for(let a=0;a<s&&l!=null;a++)l=l[f[a]];return l})}}function an(n,e){let i=[],f=0;for(let s=0;s<e.length;s++){let t=e[s],r=s===e.length-1,c=n.slice(f,t).map(l=>l.value);c.length>0&&i.push({type:"access",keys:c}),i.push({type:r?"map":"flatMap",keys:[]}),f=t+1;}let o=n.slice(f).map(s=>s.value);return s=>{let t=s;for(let r of i){if(t==null)return;if(r.type==="access")for(let c of r.keys){if(t==null)return;t=t[c];}else if(r.type==="flatMap"){if(!Array.isArray(t))return;t=t.flatMap(c=>{let l=c;return Array.isArray(l)?l:[l]});}else if(r.type==="map"){if(!Array.isArray(t))return;o.length>0&&(t=t.map(c=>{let l=c;for(let a of o){if(l==null)return;l=l[a];}return l}));}}return t}}function pn(n,e){return O(e)(n)}function j(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function dn(){x.clear();}function gn(){return x.size}function w(n,e){let i=new Set;return b(n,i,e),Array.from(i)}function b(n,e,i){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let s=0;s<n.length;s++)b(n[s],e,i);return}if(h(n)){e.add(j(n.$));return}if(A(n)){if(typeof n.$if=="string"){let s=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(j(s));}else b(n.$if,e,i);b(n.then,e,i),n.else!==void 0&&b(n.else,e,i);return}if(k(n)){for(let s=0;s<n.$pipe.length;s++)b(n.$pipe[s],e,i);return}if($(n)){if(n.args)for(let s=0;s<n.args.length;s++){let t=n.args[s];typeof t!="function"&&b(t,e,i);}return}if(E(n)){b(n.left,e,i),n.right!==void 0&&b(n.right,e,i);return}if(T(n)){for(let s=0;s<n.conditions.length;s++)b(n.conditions[s],e,i);return}if(i){let s=n,t=Object.keys(s);for(let r=0;r<t.length;r++){let c=t[r];if(c in i){let l=i[c](s);if(typeof l=="object"&&l!==null&&c in l)throw new Error(`Transform "${c}" returned object with same key \u2014 infinite loop`);b(l,e,i);return}}}let f=n,o=Object.keys(f);for(let s=0;s<o.length;s++)b(f[o[s]],e,i);}function yn(n){return w(n).length>0}function mn(n){return w(n).length===0}function hn(n){return JSON.stringify(n)}function N(n,e={}){let i=e.scope??{},f=e.accessor,o=e.transforms,s=m(n,i,f,o),t=w(n,o),r=hn(n);return {fn:s,deps:t,hash:r}}function m(n,e,i,f){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let o=n.map(s=>m(s,e,i,f));return s=>o.map(t=>t(s))}if(h(n))return En(n,i);if(A(n))return Tn(n,e,i,f);if(k(n))return bn(n,e,i,f);if($(n))return Cn(n,e,i,f);if(E(n))return An(n,e,i,f);if(T(n))return $n(n,e,i,f);if(f){let o=n,s=Object.keys(o);for(let t=0;t<s.length;t++){let r=s[t];if(r in f){let c=f[r](o);if(typeof c=="object"&&c!==null&&r in c)throw new Error(`Transform "${r}" returned object with same key \u2014 infinite loop`);return m(c,e,i,f)}}}if(M(n)){let o=n,s=Object.keys(o),t=s.map(r=>m(o[r],e,i,f));return r=>{let c={};for(let l=0;l<s.length;l++)c[s[l]]=t[l](r);return c}}return ()=>n}function K(n,e){return e?i=>e(n,i):O(n)}function En(n,e){return K(n.$,e)}function Tn(n,e,i,f){let o;if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if,c=K(r,i);o=n.$if.startsWith("!")?a=>!c(a):a=>!!c(a);}else {let r=m(n.$if,e,i,f);o=c=>!!r(c);}let s=m(n.then,e,i,f),t=n.else!==void 0?m(n.else,e,i,f):()=>{};return r=>o(r)?s(r):t(r)}function bn(n,e,i,f){let o=n.$pipe;if(o.length===0)return ()=>{};if(o.length===1)return m(o[0],e,i,f);let s=m(o[0],e,i,f),t=o.slice(1).map(c=>m(c,e,i,f)),r=t.length;if(r===1){let[c]=t;return l=>{let a=s(l),p=c(l);return typeof p=="function"?p(a):p}}if(r===2){let[c,l]=t;return a=>{let p=s(a),d=c(a);return p=typeof d=="function"?d(p):d,d=l(a),typeof d=="function"?d(p):d}}if(r===3){let[c,l,a]=t;return p=>{let d=s(p),g=c(p);return d=typeof g=="function"?g(d):g,g=l(p),d=typeof g=="function"?g(d):g,g=a(p),typeof g=="function"?g(d):g}}return c=>{let l=s(c);for(let a=0;a<r;a++){let p=t[a](c);l=typeof p=="function"?p(l):p;}return l}}function Cn(n,e,i,f){let o=n.$fn,s=n.args;if(s===void 0)return ()=>{let c=e[o];if(!c)throw new Error(`Function not found in scope: ${o}`);return c};let t=s.map(c=>typeof c=="function"?()=>c:m(c,e,i,f)),r=t.length;if(r===0)return c=>{let l=e[o];if(!l)throw new Error(`Function not found in scope: ${o}`);return l()};if(r===1){let[c]=t;return l=>{let a=e[o];if(!a)throw new Error(`Function not found in scope: ${o}`);return a(c(l))}}if(r===2){let[c,l]=t;return a=>{let p=e[o];if(!p)throw new Error(`Function not found in scope: ${o}`);return p(c(a),l(a))}}if(r===3){let[c,l,a]=t;return p=>{let d=e[o];if(!d)throw new Error(`Function not found in scope: ${o}`);return d(c(p),l(p),a(p))}}return c=>{let l=e[o];if(!l)throw new Error(`Function not found in scope: ${o}`);return l(...t.map(a=>a(c)))}}function An(n,e,i,f){let o=m(n.left,e,i,f),s=n.right!==void 0?m(n.right,e,i,f):()=>{};switch(n.op){case "eq":return t=>o(t)===s(t);case "neq":return t=>o(t)!==s(t);case "gt":return t=>o(t)>s(t);case "gte":return t=>o(t)>=s(t);case "lt":return t=>o(t)<s(t);case "lte":return t=>o(t)<=s(t);case "in":return t=>{let r=s(t);return Array.isArray(r)&&r.includes(o(t))};case "notIn":return t=>{let r=s(t);return !Array.isArray(r)||!r.includes(o(t))};case "contains":return t=>{let r=o(t);return Array.isArray(r)&&r.includes(s(t))};case "notContains":return t=>{let r=o(t);return !Array.isArray(r)||!r.includes(s(t))};case "exists":return t=>o(t)!==void 0;case "notExists":return t=>o(t)===void 0;case "matches":return t=>{let r=o(t),c=s(t);return typeof r!="string"||typeof c!="string"?false:new RegExp(c).test(r)};case "notMatches":return t=>{let r=o(t),c=s(t);return typeof r!="string"||typeof c!="string"?true:!new RegExp(c).test(r)};case "startsWith":return t=>{let r=o(t),c=s(t);return typeof r=="string"&&typeof c=="string"&&r.startsWith(c)};case "endsWith":return t=>{let r=o(t),c=s(t);return typeof r=="string"&&typeof c=="string"&&r.endsWith(c)}}}function $n(n,e,i,f){let o=n.conditions.map(t=>m(t,e,i,f)),s=o.length;if(s===1)return t=>!!o[0](t);if(s===2){let[t,r]=o;return n.logic==="AND"?c=>!!t(c)&&!!r(c):c=>!!t(c)||!!r(c)}if(s===3){let[t,r,c]=o;return n.logic==="AND"?l=>!!t(l)&&!!r(l)&&!!c(l):l=>!!t(l)||!!r(l)||!!c(l)}return n.logic==="AND"?t=>{for(let r=0;r<s;r++)if(!o[r](t))return false;return true}:t=>{for(let r=0;r<s;r++)if(o[r](t))return true;return false}}function kn(n,e,i={}){return N(n,i).fn(e)}var v=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,i={}){let f=JSON.stringify(e),o=this.cache.get(f);if(o)return this.cache.delete(f),this.cache.set(f,o),o;let s=N(e,i);if(this.cache.size>=this._maxSize){let t=this.cache.keys().next().value;t&&this.cache.delete(t);}return this.cache.set(f,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);}}},Y=new v;function Sn(n,e={}){return Y.get(n,e)}function z(n,e="root",i={}){let f=[];return S(n,e,f,i),{valid:f.length===0,errors:f}}function S(n,e,i,f){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let t=0;t<n.length;t++)S(n[t],`${e}[${t}]`,i,f);return}if(h(n)){(!n.$||typeof n.$!="string")&&i.push(`${e}: invalid reference, $ must be non-empty string`);return}if(A(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||i.push(`${e}.$if: empty path in string shorthand`):S(n.$if,`${e}.$if`,i,f),S(n.then,`${e}.then`,i,f),n.else!==void 0&&S(n.else,`${e}.else`,i,f);return}if(k(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 t=0;t<n.$pipe.length;t++)S(n.$pipe[t],`${e}.$pipe[${t}]`,i,f);return}if($(n)){if(!n.$fn||typeof n.$fn!="string"){i.push(`${e}: invalid function, $fn must be non-empty string`);return}if(f.scope&&!(n.$fn in f.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 t=0;t<n.args.length;t++){let r=n.args[t];typeof r!="function"&&S(r,`${e}.args[${t}]`,i,f);}return}if(E(n)){F.has(n.op)||i.push(`${e}: invalid operator "${n.op}"`),S(n.left,`${e}.left`,i,f),n.right!==void 0&&S(n.right,`${e}.right`,i,f);return}if(T(n)){if(n.logic!=="AND"&&n.logic!=="OR"&&i.push(`${e}: invalid logic "${n.logic}", must be "AND" or "OR"`),!Array.isArray(n.conditions)){i.push(`${e}.conditions: must be an array`);return}for(let t=0;t<n.conditions.length;t++)S(n.conditions[t],`${e}.conditions[${t}]`,i,f);return}let o=n,s=Object.keys(o);for(let t=0;t<s.length;t++){let r=s[t];S(o[r],`${e}.${r}`,i,f);}}function wn(n,e={}){let i=z(n,"root",e);if(!i.valid)throw new Error(`Invalid expression: ${i.errors.join("; ")}`)}function Rn(n,e={}){return z(n,"root",e).valid}var Z={};sn(Z,{$:()=>H,$cond:()=>X,$fn:()=>Q,$if:()=>On,$pipe:()=>U,cond:()=>Nn,fn:()=>xn,pipe:()=>jn,ref:()=>Fn});function H(n){return {$:n}}var Fn=H;function Q(n,e){return e===void 0||e.length===0?{$fn:n}:{$fn:n,args:e}}var xn=Q;function On(n,e,i){return i===void 0?{$if:n,then:e}:{$if:n,then:e,else:i}}function U(...n){return {$pipe:n}}var jn=U;function X(n,e,i){return i===void 0?{left:n,op:e}:{left:n,op:e,right:i}}var Nn=X;var L="data",nn="scope",vn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function W(n,e={}){let{dataParam:i=L,scopeParam:f=nn,noPrefixes:o=false,useAccessor:s=false,lexicalPrefix:t,transforms:r}=e;return y(n,i,f,o,s,t,r)}function y(n,e,i,f,o,s,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(r=>y(r,e,i,f,o,s,t)));if(h(n))return Gn(n.$,e,f,o,s);if(A(n))return Dn(n,e,i,f,o,s,t);if(k(n))return Mn(n.$pipe,e,i,f,o,s,t);if($(n))return In(n,e,i,f,o,s,t);if(E(n))return zn(n,e,i,f,o,s,t);if(T(n))return Ln(n,e,i,f,o,s,t);if(t&&typeof n=="object"){let r=n,c=Object.keys(r);for(let l=0;l<c.length;l++){let a=c[l];if(a in t){let p=t[a](r);if(typeof p=="object"&&p!==null&&a in p)throw new Error(`Transform "${a}" returned object with same key \u2014 infinite loop`);return y(p,e,i,f,o,s,t)}}}if(typeof n=="object"){let c=Object.entries(n).map(([l,a])=>builders.property(builders.identifier(l),y(a,e,i,f,o,s,t)));return builders.objectExpression(c)}return builders.literal(null)}var V="accessor";function _(n,e){return e?n===e||n.startsWith(e+"."):false}function Gn(n,e,i,f,o){return f?_(n,o)?R(n,e,true):builders.callExpression(builders.identifier(V),[builders.literal(n),builders.identifier(e)]):n.includes("[*]")?Wn(n,e,i):R(n,e,i)}function R(n,e,i){let f=G(n);if(f.length===0)return i?builders.identifier("undefined"):builders.identifier(e);let o;if(i){let s=f[0];o=builders.identifier(s.value);for(let t=1;t<f.length;t++){let r=f[t];r.type==="key"?o=builders.memberExpression(o,builders.identifier(r.value),false,true):o=builders.memberExpression(o,builders.literal(r.value),true,true);}}else {o=builders.identifier(e);for(let s of f)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 Wn(n,e,i){let f=n.indexOf("[*]"),o=n.slice(0,f),s=n.slice(f+3),t;if(o?t=R(o,e,i):t=i?builders.identifier("undefined"):builders.identifier(e),!s||s==="")return t;if(s.includes("[*]"))return en(t,s);let r="_i",c=s.startsWith(".")?s.slice(1):s,l=builders.identifier(r);if(c){let a=G(c);for(let p of a)p.type==="key"?l=builders.memberExpression(l,builders.identifier(p.value),false,true):l=builders.memberExpression(l,builders.literal(p.value),true,true);}return builders.callExpression(builders.memberExpression(t,builders.identifier("map"),false,true),[builders.arrowFunctionExpression([builders.identifier(r)],l)])}function en(n,e){let i=e.indexOf("[*]"),f=e.slice(0,i),o=e.slice(i+3),s="_i",t=f.startsWith(".")?f.slice(1):f,r=builders.identifier(s);if(t){let l=G(t);for(let a of l)a.type==="key"&&(r=builders.memberExpression(r,builders.identifier(a.value),false,true));}if(o.includes("[*]")){let l=en(r,o);return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],l)])}let c=o.startsWith(".")?o.slice(1):o;if(c){let l=G(c);for(let a of l)a.type==="key"&&(r=builders.memberExpression(r,builders.identifier(a.value),false,true));}return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],r)])}function Dn(n,e,i,f,o,s,t){let r;if(typeof n.$if=="string"){let a=n.$if.startsWith("!"),p=a?n.$if.slice(1):n.$if,d;o?_(p,s)?d=R(p,e,true):d=builders.callExpression(builders.identifier(V),[builders.literal(p),builders.identifier(e)]):d=R(p,e,f),r=a?builders.unaryExpression("!",d):d;}else r=y(n.$if,e,i,f,o,s,t);let c=y(n.then,e,i,f,o,s,t),l=n.else!==void 0?y(n.else,e,i,f,o,s,t):builders.identifier("undefined");return builders.conditionalExpression(r,c,l)}function In(n,e,i,f,o,s,t){let r=f?builders.identifier(n.$fn):builders.memberExpression(builders.identifier(i),builders.identifier(n.$fn),false,false);if(n.args===void 0)return r;let c=n.args.map(l=>typeof l=="function"?builders.literal(null):y(l,e,i,f,o,s,t));return builders.callExpression(r,c)}function Mn(n,e,i,f,o,s,t){if(n.length===0)return builders.identifier("undefined");if(n.length===1)return y(n[0],e,i,f,o,s,t);let r=y(n[0],e,i,f,o,s,t);for(let c=1;c<n.length;c++){let l=y(n[c],e,i,f,o,s,t);r=builders.callExpression(l,[r]);}return r}function P(n,e,i,f,o,s,t){if(h(n)){let r=n.$;return o?_(r,s)?R(r,e,true):builders.callExpression(builders.identifier(V),[builders.literal(r),builders.identifier(e)]):R(r,e,f)}return y(n,e,i,f,o,s,t)}function zn(n,e,i,f,o,s,t){let r=P(n.left,e,i,f,o,s,t),c=n.right!==void 0?P(n.right,e,i,f,o,s,t):builders.literal(null),l=vn[n.op];if(l)return builders.binaryExpression(l,r,c);switch(n.op){case "in":return builders.callExpression(builders.memberExpression(c,builders.identifier("includes")),[r]);case "notIn":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(c,builders.identifier("includes")),[r]));case "contains":return builders.callExpression(builders.memberExpression(r,builders.identifier("includes"),false,true),[c]);case "notContains":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(r,builders.identifier("includes"),false,true),[c]));case "exists":return builders.binaryExpression("!=",r,builders.literal(null));case "notExists":return builders.binaryExpression("==",r,builders.literal(null));case "matches":return builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[c]),builders.identifier("test")),[r]);case "notMatches":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[c]),builders.identifier("test")),[r]));case "startsWith":return builders.callExpression(builders.memberExpression(r,builders.identifier("startsWith"),false,true),[c]);case "endsWith":return builders.callExpression(builders.memberExpression(r,builders.identifier("endsWith"),false,true),[c]);default:return builders.binaryExpression("===",r,c)}}function Ln(n,e,i,f,o,s,t){let{logic:r,conditions:c}=n,l=r==="AND"?"&&":"||";if(c.length===0)return builders.literal(r==="AND");if(c.length===1)return y(c[0],e,i,f,o,s,t);let a=y(c[0],e,i,f,o,s,t);for(let p=1;p<c.length;p++){let d=y(c[p],e,i,f,o,s,t);a=builders.logicalExpression(l,a,d);}return a}function G(n){let e=[],i=n.length,f=0,o="";for(;f<i;){let s=n[f];if(s===".")o&&(e.push({type:"key",value:o}),o=""),f++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),f++;let t=f;for(;f<i&&n[f]!=="]";)f++;let r=n.slice(t,f);if(f++,r!=="*"){let c=parseInt(r,10);e.push({type:"index",value:isNaN(c)?r:c});}}else o+=s,f++;}return o&&e.push({type:"key",value:o}),e}function tn(n,e=[L]){return builders.arrowFunctionExpression(e.map(i=>builders.identifier(i)),n)}function D(n,e){let i=new Set;return C(n,i,e),i}function C(n,e,i){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let o of n)C(o,e,i);return}if(h(n))return;if(A(n)){C(n.$if,e,i),C(n.then,e,i),n.else!==void 0&&C(n.else,e,i);return}if(k(n)){for(let o of n.$pipe)C(o,e,i);return}if($(n)){if(e.add(n.$fn),n.args)for(let o of n.args)typeof o!="function"&&C(o,e,i);return}if(E(n)){n.left!==void 0&&typeof n.left=="object"&&C(n.left,e,i),n.right!==void 0&&typeof n.right=="object"&&C(n.right,e,i);return}if(T(n)){for(let o of n.conditions)C(o,e,i);return}if(i){let o=n,s=Object.keys(o);for(let t=0;t<s.length;t++){let r=s[t];if(r in i){let c=i[r](o);if(typeof c=="object"&&c!==null&&r in c)throw new Error(`Transform "${r}" returned object with same key \u2014 infinite loop`);C(c,e,i);return}}}let f=n;for(let o of Object.keys(f))C(f[o],e,i);}function I(n){let e=new Set;for(let i of n){let f=i.indexOf("."),o=i.indexOf("["),s=i.length;f!==-1&&(s=Math.min(s,f)),o!==-1&&(s=Math.min(s,o));let t=i.slice(0,s);t&&e.add(t);}return e}function _n(n){return JSON.stringify(n)}function qn(n,e,i,f,o,s){let t=W(n,{noPrefixes:true,useAccessor:f,lexicalPrefix:o,transforms:s}),r=generate(t),c="";f?o&&(c=`const{${o}}=data??{};`):e.size>0&&(c=`const{${[...e].join(",")}}=data??{};`);let l=f?new Set([...i,"accessor"]):i,a=l.size>0?`const{${[...l].join(",")}}=scope;`:"";return a?`(function(scope){${a}return function(data){${c}return ${r}}})`:`(function(){return function(data){${c}return ${r}}})`}function q(n,e={}){let{scope:i={},returnCode:f=false,useAccessor:o=false,lexicalPrefix:s,transforms:t}=e,r=w(n,t),c=I(r),l=D(n,t),a=_n(n),p=qn(n,c,l,o,s,t);if(f)return {code:p,deps:r,hash:a,dataRoots:[...c],scopeFns:[...l]};let d;try{d=new Function(`return ${p}`)()(i);}catch(g){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${g instanceof Error?g.message:String(g)}`)}return {fn:d,deps:r,hash:a}}function on(n,e,i={}){let{fn:f}=q(n,i);return f(e)}var Ee="0.1.1";export{v as ExpressionCache,Ee as VERSION,wn as assertValid,Z as builders,Y as cache,Sn as cached,dn as clearPathCache,N as compile,q as compileAST,O as compilePath,W as dslToAST,kn as evaluate,on as evaluateAST,I as extractDataRoots,w as extractDeps,D as extractScopeFns,pn as get,gn as getPathCacheSize,yn as hasDeps,B as hasWildcard,E as isCondition,fn as isConditionExpr,T as isConditionGroup,A as isConditional,$ as isFn,M as isLiteral,k as isPipe,mn as isPure,h as isRef,Rn as isValid,j as normalizePath,z as validate,tn as wrapInFunction};
|