@statedelta-libs/expressions 1.0.0 → 1.1.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 +163 -7
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +52 -10
- package/dist/index.d.ts +52 -10
- package/dist/index.js +1 -1
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
- **$pipe** - Composição com valor inicial (sintaxe DSL)
|
|
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
18
|
- **Type-safe** - TypeScript nativo com inferência
|
|
19
19
|
|
|
20
20
|
## Instalação
|
|
@@ -93,6 +93,75 @@ fn(data); // Executa (mais rápido que compile())
|
|
|
93
93
|
| Hot path crítico | `compileAST()` | V8 JIT otimiza melhor |
|
|
94
94
|
| Expressões complexas | `compileAST()` | Ganho maior em nested calls |
|
|
95
95
|
|
|
96
|
+
#### useAccessor (compileAST)
|
|
97
|
+
|
|
98
|
+
Para contextos inteligentes (ex: `TickContext`), use `useAccessor: true` para gerar `accessor(path, data)` ao invés de acesso direto:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const ctx = new TickContext();
|
|
102
|
+
|
|
103
|
+
const { fn } = compileAST(
|
|
104
|
+
{ $fn: "add", args: [{ $: "hp" }, { $: "mp" }] },
|
|
105
|
+
{
|
|
106
|
+
scope: {
|
|
107
|
+
add,
|
|
108
|
+
accessor: (path) => ctx.get(path) // closure que captura ctx
|
|
109
|
+
},
|
|
110
|
+
useAccessor: true
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
fn(); // usa ctx.get("hp") + ctx.get("mp")
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Código gerado:
|
|
118
|
+
```js
|
|
119
|
+
(function(scope){
|
|
120
|
+
const{add,accessor}=scope;
|
|
121
|
+
return function(data){
|
|
122
|
+
return add(accessor("hp",data),accessor("mp",data))
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### lexicalPrefix (compileAST)
|
|
128
|
+
|
|
129
|
+
Para máxima performance em paths específicos, use `lexicalPrefix` para acesso direto via destructuring:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
const ctx = new TickContext();
|
|
133
|
+
|
|
134
|
+
const { fn } = compileAST(
|
|
135
|
+
{ $fn: "add", args: [{ $: "hp" }, { $: "params.damage" }] },
|
|
136
|
+
{
|
|
137
|
+
scope: {
|
|
138
|
+
add,
|
|
139
|
+
accessor: (path) => ctx.get(path)
|
|
140
|
+
},
|
|
141
|
+
useAccessor: true,
|
|
142
|
+
lexicalPrefix: "params" // params.* vai direto, resto via accessor
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
fn({ params: { damage: 25 } }); // ctx.get("hp") + params.damage
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Código gerado:
|
|
150
|
+
```js
|
|
151
|
+
(function(scope){
|
|
152
|
+
const{add,accessor}=scope;
|
|
153
|
+
return function(data){
|
|
154
|
+
const{params}=data??{}; // destructuring direto (rápido!)
|
|
155
|
+
return add(accessor("hp",data),params?.damage)
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
| Path | Com lexicalPrefix | Sem lexicalPrefix |
|
|
161
|
+
|------|-------------------|-------------------|
|
|
162
|
+
| `params.damage` | `params?.damage` (direto) | `accessor("params.damage", data)` |
|
|
163
|
+
| `hp` | `accessor("hp", data)` | `accessor("hp", data)` |
|
|
164
|
+
|
|
96
165
|
### evaluate() / evaluateAST()
|
|
97
166
|
|
|
98
167
|
Compila e executa em um passo.
|
|
@@ -122,6 +191,33 @@ const deps = extractDeps({
|
|
|
122
191
|
// ["$isVip", "price.vip", "price.regular"]
|
|
123
192
|
```
|
|
124
193
|
|
|
194
|
+
## JSON Aninhado (Walk Automático)
|
|
195
|
+
|
|
196
|
+
O compilador **percorre automaticamente** todo o JSON e resolve expressões onde quer que estejam:
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
const { fn } = compile({
|
|
200
|
+
name: "John",
|
|
201
|
+
damage: { $: "params.damage" },
|
|
202
|
+
active: { $if: "hp.current", then: true, else: false },
|
|
203
|
+
nested: {
|
|
204
|
+
deep: {
|
|
205
|
+
value: { $fn: "add", args: [{ $: "a" }, { $: "b" }] }
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}, { scope });
|
|
209
|
+
|
|
210
|
+
fn({ params: { damage: 25 }, hp: { current: 100 }, a: 1, b: 2 });
|
|
211
|
+
// {
|
|
212
|
+
// name: "John",
|
|
213
|
+
// damage: 25,
|
|
214
|
+
// active: true,
|
|
215
|
+
// nested: { deep: { value: 3 } }
|
|
216
|
+
// }
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Não precisa de walker manual - o `compile()` e `compileAST()` já fazem isso internamente.
|
|
220
|
+
|
|
125
221
|
## Tipos de Expressão
|
|
126
222
|
|
|
127
223
|
### Literal
|
|
@@ -189,14 +285,36 @@ Chama função do scope com argumentos compilados.
|
|
|
189
285
|
// → scope.getTimestamp()
|
|
190
286
|
```
|
|
191
287
|
|
|
192
|
-
### Condition
|
|
288
|
+
### Condition
|
|
289
|
+
|
|
290
|
+
Condicionais compiladas internamente. Ambos os lados aceitam qualquer expressão:
|
|
193
291
|
|
|
194
292
|
```typescript
|
|
195
|
-
//
|
|
293
|
+
// Ref vs literal (básico)
|
|
196
294
|
{ left: { $: "user.age" }, op: "gte", right: 18 }
|
|
295
|
+
|
|
296
|
+
// Ref vs Ref
|
|
297
|
+
{ left: { $: "price" }, op: "lte", right: { $: "budget" } }
|
|
298
|
+
|
|
299
|
+
// $fn nos lados
|
|
300
|
+
{ left: { $fn: "add", args: [{ $: "a" }, { $: "b" }] }, op: "gt", right: 100 }
|
|
301
|
+
|
|
302
|
+
// $pipe no lado
|
|
303
|
+
{ left: { $pipe: [{ $: "name" }, { $fn: "upper" }] }, op: "eq", right: "ADMIN" }
|
|
304
|
+
|
|
305
|
+
// Condition group
|
|
306
|
+
{
|
|
307
|
+
logic: "AND",
|
|
308
|
+
conditions: [
|
|
309
|
+
{ left: { $: "active" }, op: "eq", right: true },
|
|
310
|
+
{ left: { $fn: "len", args: [{ $: "items" }] }, op: "gte", right: 3 }
|
|
311
|
+
]
|
|
312
|
+
}
|
|
197
313
|
```
|
|
198
314
|
|
|
199
|
-
|
|
315
|
+
**Operadores:** `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `notIn`, `contains`, `notContains`, `exists`, `notExists`, `matches`, `notMatches`, `startsWith`, `endsWith`
|
|
316
|
+
|
|
317
|
+
> **Nota:** Objetos com `op: "set"` ou outros operadores não-condition são tratados como literals.
|
|
200
318
|
|
|
201
319
|
## Scope
|
|
202
320
|
|
|
@@ -254,7 +372,7 @@ O accessor é propagado para:
|
|
|
254
372
|
- Shorthand de `$if` (`{ $if: "path", ... }`)
|
|
255
373
|
- Argumentos de `$fn`
|
|
256
374
|
- Steps de `$pipe`
|
|
257
|
-
- Conditions (
|
|
375
|
+
- Conditions (compiladas internamente)
|
|
258
376
|
|
|
259
377
|
**Performance:** Igual ao acesso direto (~25-30M ops/s).
|
|
260
378
|
|
|
@@ -371,7 +489,7 @@ Funções declarativas para construir expressões. Disponíveis via namespace `b
|
|
|
371
489
|
```typescript
|
|
372
490
|
import { builders, compile } from '@statedelta-libs/expressions';
|
|
373
491
|
|
|
374
|
-
const { $, $fn, $if, $pipe } = builders;
|
|
492
|
+
const { $, $fn, $if, $pipe, $cond } = builders;
|
|
375
493
|
```
|
|
376
494
|
|
|
377
495
|
### `$` / `ref` - Path Reference
|
|
@@ -423,13 +541,33 @@ $pipe(
|
|
|
423
541
|
)
|
|
424
542
|
```
|
|
425
543
|
|
|
544
|
+
### `$cond` / `cond` - Condition
|
|
545
|
+
|
|
546
|
+
```typescript
|
|
547
|
+
// Básico
|
|
548
|
+
$cond($("age"), "gte", 18)
|
|
549
|
+
// { left: { $: "age" }, op: "gte", right: 18 }
|
|
550
|
+
|
|
551
|
+
// Exists (sem right)
|
|
552
|
+
$cond($("email"), "exists")
|
|
553
|
+
|
|
554
|
+
// Ref vs Ref
|
|
555
|
+
$cond($("price"), "lte", $("budget"))
|
|
556
|
+
|
|
557
|
+
// Com $fn nos lados
|
|
558
|
+
$cond($fn("add", [$("a"), $("b")]), "gt", 100)
|
|
559
|
+
|
|
560
|
+
// Com $pipe
|
|
561
|
+
$cond($pipe($("name"), $fn("upper")), "eq", "ADMIN")
|
|
562
|
+
```
|
|
563
|
+
|
|
426
564
|
### Exemplo Completo
|
|
427
565
|
|
|
428
566
|
```typescript
|
|
429
567
|
import { builders, compile } from '@statedelta-libs/expressions';
|
|
430
568
|
import { filter, map, sum } from '@statedelta-libs/operators';
|
|
431
569
|
|
|
432
|
-
const { $, $fn, $if, $pipe } = builders;
|
|
570
|
+
const { $, $fn, $if, $pipe, $cond } = builders;
|
|
433
571
|
|
|
434
572
|
const scope = { filter, map, sum };
|
|
435
573
|
|
|
@@ -459,6 +597,7 @@ fn({
|
|
|
459
597
|
| `$` | `ref` |
|
|
460
598
|
| `$fn` | `fn` |
|
|
461
599
|
| `$pipe` | `pipe` |
|
|
600
|
+
| `$cond` | `cond` |
|
|
462
601
|
|
|
463
602
|
## TypeScript
|
|
464
603
|
|
|
@@ -470,6 +609,10 @@ import type {
|
|
|
470
609
|
ConditionalExpr,
|
|
471
610
|
FnExpr,
|
|
472
611
|
PipeExpr,
|
|
612
|
+
Condition,
|
|
613
|
+
ConditionGroup,
|
|
614
|
+
ConditionExpr,
|
|
615
|
+
ConditionOp,
|
|
473
616
|
Scope,
|
|
474
617
|
CompileOptions,
|
|
475
618
|
AccessorFn,
|
|
@@ -512,6 +655,19 @@ import {
|
|
|
512
655
|
|
|
513
656
|
4. **Novo**: `$pipe` como sintaxe DSL para composição
|
|
514
657
|
|
|
658
|
+
### v1.0 → v1.1
|
|
659
|
+
|
|
660
|
+
1. **Conditions internas**: `@statedelta-libs/conditions` não é mais dependência. Conditions são compiladas internamente.
|
|
661
|
+
|
|
662
|
+
2. **Expressions nos lados**: `left`/`right` de conditions agora aceitam qualquer `Expression` (`$fn`, `$pipe`, `$if`, etc), não apenas `Ref | literal`.
|
|
663
|
+
|
|
664
|
+
3. **Novo builder**: `$cond(left, op, right?)` para construir conditions com expressions:
|
|
665
|
+
```typescript
|
|
666
|
+
$cond($fn("add", [$("a"), $("b")]), "gt", 100)
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
4. **Novos tipos**: `ConditionOp`, `Condition`, `ConditionGroup`, `ConditionExpr` exportados diretamente do expressions.
|
|
670
|
+
|
|
515
671
|
## Licença
|
|
516
672
|
|
|
517
673
|
MIT © Anderson D. Rosa
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var conditions=require('@statedelta-libs/conditions'),omniAst=require('omni-ast');var sn=Object.defineProperty;var fn=(n,e)=>{for(var i in e)sn(n,i,{get:e[i],enumerable:true});};var m=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,E=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,T=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",b=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),_=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),y=n=>n!==null&&typeof n=="object"&&"left"in n&&"op"in n&&_.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),h=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,ln=n=>y(n)||h(n),z=n=>{if(n===null)return true;let e=typeof n;if(e==="string"||e==="number"||e==="boolean"||Array.isArray(n))return true;if(e==="object"&&n!==null){let i=n,t="left"in i&&"op"in i&&_.has(i.op);return !("$"in i)&&!("$if"in i)&&!("$fn"in i)&&!("$pipe"in i)&&!t&&!("logic"in i)}return false};var R=new Map;function q(n){let e=[],i=n.length,t=0,r="";for(;t<i;){let f=n[t];if(f===".")r&&(e.push({type:"key",value:r}),r=""),t++;else if(f==="["){r&&(e.push({type:"key",value:r}),r=""),t++;let o=t;for(;t<i&&n[t]!=="]";)t++;let s=n.slice(o,t);if(t++,s==="*")e.push({type:"wildcard",value:"*"});else {let u=parseInt(s,10);e.push({type:"index",value:isNaN(u)?s:u});}}else r+=f,t++;}return r&&e.push({type:"key",value:r}),e}function J(n){return n.includes("[*]")}function F(n){let e=R.get(n);return e||(e=J(n)?cn(n):un(n),R.set(n,e),e)}function un(n){if(!n.includes(".")&&!n.includes("["))return r=>r?.[n];let e=q(n),i=e.length;if(i===2){let[r,f]=e,o=r.value,s=f.value;return u=>u?.[o]?.[s]}if(i===3){let[r,f,o]=e,s=r.value,u=f.value,c=o.value;return a=>a?.[s]?.[u]?.[c]}let t=e.map(r=>r.value);return r=>{let f=r;for(let o=0;o<i&&f!=null;o++)f=f[t[o]];return f}}function cn(n){let e=q(n),i=[];for(let t=0;t<e.length;t++)e[t].type==="wildcard"&&i.push(t);return i.length===1?an(e,i[0]):pn(e,i)}function an(n,e){let i=n.slice(0,e).map(o=>o.value),t=n.slice(e+1).map(o=>o.value),r=i.length,f=t.length;if(f===0){if(r===1){let o=i[0];return s=>s?.[o]}return o=>{let s=o;for(let u=0;u<r&&s!=null;u++)s=s[i[u]];return s}}if(f===1){let o=t[0];if(r===1){let s=i[0];return u=>{let c=u?.[s];if(Array.isArray(c))return c.map(a=>a?.[o])}}return s=>{let u=s;for(let c=0;c<r&&u!=null;c++)u=u[i[c]];if(Array.isArray(u))return u.map(c=>c?.[o])}}return o=>{let s=o;for(let u=0;u<r&&s!=null;u++)s=s[i[u]];if(Array.isArray(s))return s.map(u=>{let c=u;for(let a=0;a<f&&c!=null;a++)c=c[t[a]];return c})}}function pn(n,e){let i=[],t=0;for(let f=0;f<e.length;f++){let o=e[f],s=f===e.length-1,u=n.slice(t,o).map(c=>c.value);u.length>0&&i.push({type:"access",keys:u}),i.push({type:s?"map":"flatMap",keys:[]}),t=o+1;}let r=n.slice(t).map(f=>f.value);return f=>{let o=f;for(let s of i){if(o==null)return;if(s.type==="access")for(let u of s.keys){if(o==null)return;o=o[u];}else if(s.type==="flatMap"){if(!Array.isArray(o))return;o=o.flatMap(u=>{let c=u;return Array.isArray(c)?c:[c]});}else if(s.type==="map"){if(!Array.isArray(o))return;r.length>0&&(o=o.map(u=>{let c=u;for(let a of r){if(c==null)return;c=c[a];}return c}));}}return o}}function dn(n,e){return F(e)(n)}function x(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function gn(){R.clear();}function mn(){return R.size}function k(n){let e=new Set;return $(n,e),Array.from(e)}function $(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r=0;r<n.length;r++)$(n[r],e);return}if(m(n)){e.add(x(n.$));return}if(E(n)){if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(x(r));}else $(n.$if,e);$(n.then,e),n.else!==void 0&&$(n.else,e);return}if(b(n)){for(let r=0;r<n.$pipe.length;r++)$(n.$pipe[r],e);return}if(T(n)){if(n.args)for(let r=0;r<n.args.length;r++){let f=n.args[r];typeof f!="function"&&$(f,e);}return}if(y(n)){conditions.isRef(n.left)&&e.add(x(n.left.$)),n.right!==void 0&&conditions.isRef(n.right)&&e.add(x(n.right.$));return}if(h(n)){for(let r=0;r<n.conditions.length;r++)$(n.conditions[r],e);return}let i=n,t=Object.keys(i);for(let r=0;r<t.length;r++)$(i[t[r]],e);}function yn(n){return k(n).length>0}function hn(n){return k(n).length===0}function En(n){return JSON.stringify(n)}function O(n,e={}){let i=e.scope??{},t=e.accessor,r=S(n,i,t),f=k(n),o=En(n);return {fn:r,deps:f,hash:o}}function S(n,e,i){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let t=n.map(r=>S(r,e,i));return r=>t.map(f=>f(r))}if(m(n))return Tn(n,i);if(E(n))return bn(n,e,i);if(b(n))return Cn(n,e,i);if(T(n))return Sn(n,e,i);if(y(n))return conditions.compile(n,i?{accessor:i}:void 0);if(h(n))return conditions.compile(n,i?{accessor:i}:void 0);if(z(n)){let t=n,r=Object.keys(t),f=r.map(o=>S(t[o],e,i));return o=>{let s={};for(let u=0;u<r.length;u++)s[r[u]]=f[u](o);return s}}return ()=>n}function Y(n,e){return e?i=>e(n,i):F(n)}function Tn(n,e){return Y(n.$,e)}function bn(n,e,i){let t;if(typeof n.$if=="string"){let o=n.$if.startsWith("!")?n.$if.slice(1):n.$if,s=Y(o,i);t=n.$if.startsWith("!")?c=>!s(c):c=>!!s(c);}else {let o=S(n.$if,e,i);t=s=>!!o(s);}let r=S(n.then,e,i),f=n.else!==void 0?S(n.else,e,i):()=>{};return o=>t(o)?r(o):f(o)}function Cn(n,e,i){let t=n.$pipe;if(t.length===0)return ()=>{};if(t.length===1)return S(t[0],e,i);let r=S(t[0],e,i),f=t.slice(1).map(s=>S(s,e,i)),o=f.length;if(o===1){let[s]=f;return u=>{let c=r(u),a=s(u);return typeof a=="function"?a(c):a}}if(o===2){let[s,u]=f;return c=>{let a=r(c),p=s(c);return a=typeof p=="function"?p(a):p,p=u(c),typeof p=="function"?p(a):p}}if(o===3){let[s,u,c]=f;return a=>{let p=r(a),d=s(a);return p=typeof d=="function"?d(p):d,d=u(a),p=typeof d=="function"?d(p):d,d=c(a),typeof d=="function"?d(p):d}}return s=>{let u=r(s);for(let c=0;c<o;c++){let a=f[c](s);u=typeof a=="function"?a(u):a;}return u}}function Sn(n,e,i){let t=n.$fn,r=n.args;if(r===void 0)return ()=>{let s=e[t];if(!s)throw new Error(`Function not found in scope: ${t}`);return s};let f=r.map(s=>typeof s=="function"?()=>s:S(s,e,i)),o=f.length;if(o===0)return s=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u()};if(o===1){let[s]=f;return u=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c(s(u))}}if(o===2){let[s,u]=f;return c=>{let a=e[t];if(!a)throw new Error(`Function not found in scope: ${t}`);return a(s(c),u(c))}}if(o===3){let[s,u,c]=f;return a=>{let p=e[t];if(!p)throw new Error(`Function not found in scope: ${t}`);return p(s(a),u(a),c(a))}}return s=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u(...f.map(c=>c(s)))}}function $n(n,e,i={}){return O(n,i).fn(e)}var N=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,i={}){let t=JSON.stringify(e),r=this.cache.get(t);if(r)return this.cache.delete(t),this.cache.set(t,r),r;let f=O(e,i);if(this.cache.size>=this._maxSize){let o=this.cache.keys().next().value;o&&this.cache.delete(o);}return this.cache.set(t,f),f}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);}}},H=new N;function An(n,e={}){return H.get(n,e)}function M(n,e="root",i={}){let t=[];return A(n,e,t,i),{valid:t.length===0,errors:t}}function A(n,e,i,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let o=0;o<n.length;o++)A(n[o],`${e}[${o}]`,i,t);return}if(m(n)){(!n.$||typeof n.$!="string")&&i.push(`${e}: invalid reference, $ must be non-empty string`);return}if(E(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||i.push(`${e}.$if: empty path in string shorthand`):A(n.$if,`${e}.$if`,i,t),A(n.then,`${e}.then`,i,t),n.else!==void 0&&A(n.else,`${e}.else`,i,t);return}if(b(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 o=0;o<n.$pipe.length;o++)A(n.$pipe[o],`${e}.$pipe[${o}]`,i,t);return}if(T(n)){if(!n.$fn||typeof n.$fn!="string"){i.push(`${e}: invalid function, $fn must be non-empty string`);return}if(t.scope&&!(n.$fn in t.scope)&&i.push(`${e}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))i.push(`${e}.args: must be an array`);else for(let o=0;o<n.args.length;o++){let s=n.args[o];typeof s!="function"&&A(s,`${e}.args[${o}]`,i,t);}return}if(y(n)){let o=conditions.validate(n,e);o.valid||i.push(...o.errors);return}if(h(n)){let o=conditions.validate(n,e);o.valid||i.push(...o.errors);return}let r=n,f=Object.keys(r);for(let o=0;o<f.length;o++){let s=f[o];A(r[s],`${e}.${s}`,i,t);}}function kn(n,e={}){let i=M(n,"root",e);if(!i.valid)throw new Error(`Invalid expression: ${i.errors.join("; ")}`)}function wn(n,e={}){return M(n,"root",e).valid}var Z={};fn(Z,{$:()=>Q,$fn:()=>U,$if:()=>Fn,$pipe:()=>X,fn:()=>Rn,pipe:()=>On,ref:()=>xn});function Q(n){return {$:n}}var xn=Q;function U(n,e){return e===void 0||e.length===0?{$fn:n}:{$fn:n,args:e}}var Rn=U;function Fn(n,e,i){return i===void 0?{$if:n,then:e}:{$if:n,then:e,else:i}}function X(...n){return {$pipe:n}}var On=X;var D="data",en="scope",Nn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function v(n,e={}){let{dataParam:i=D,scopeParam:t=en,noPrefixes:r=false,useAccessor:f=false,lexicalPrefix:o}=e;return g(n,i,t,r,f,o)}function g(n,e,i,t,r,f){if(n===null)return omniAst.builders.literal(null);if(typeof n=="string")return omniAst.builders.literal(n);if(typeof n=="number")return omniAst.builders.literal(n);if(typeof n=="boolean")return omniAst.builders.literal(n);if(Array.isArray(n))return omniAst.builders.arrayExpression(n.map(o=>g(o,e,i,t,r,f)));if(m(n))return jn(n.$,e,t,r,f);if(E(n))return Gn(n,e,i,t,r,f);if(b(n))return zn(n.$pipe,e,i,t,r,f);if(T(n))return Wn(n,e,i,t,r,f);if(y(n))return Mn(n,e,i,t,r,f);if(h(n))return Dn(n,e,i,t,r,f);if(typeof n=="object"){let s=Object.entries(n).map(([u,c])=>omniAst.builders.property(omniAst.builders.identifier(u),g(c,e,i,t,r,f)));return omniAst.builders.objectExpression(s)}return omniAst.builders.literal(null)}var I="accessor";function L(n,e){return e?n===e||n.startsWith(e+"."):false}function jn(n,e,i,t,r){return t?L(n,r)?w(n,e,true):omniAst.builders.callExpression(omniAst.builders.identifier(I),[omniAst.builders.literal(n),omniAst.builders.identifier(e)]):n.includes("[*]")?vn(n,e,i):w(n,e,i)}function w(n,e,i){let t=j(n);if(t.length===0)return i?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e);let r;if(i){let f=t[0];r=omniAst.builders.identifier(f.value);for(let o=1;o<t.length;o++){let s=t[o];s.type==="key"?r=omniAst.builders.memberExpression(r,omniAst.builders.identifier(s.value),false,true):r=omniAst.builders.memberExpression(r,omniAst.builders.literal(s.value),true,true);}}else {r=omniAst.builders.identifier(e);for(let f of t)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);}return r}function vn(n,e,i){let t=n.indexOf("[*]"),r=n.slice(0,t),f=n.slice(t+3),o;if(r?o=w(r,e,i):o=i?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e),!f||f==="")return o;if(f.includes("[*]"))return tn(o,f);let s="_i",u=f.startsWith(".")?f.slice(1):f,c=omniAst.builders.identifier(s);if(u){let a=j(u);for(let p of a)p.type==="key"?c=omniAst.builders.memberExpression(c,omniAst.builders.identifier(p.value),false,true):c=omniAst.builders.memberExpression(c,omniAst.builders.literal(p.value),true,true);}return omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("map"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],c)])}function tn(n,e){let i=e.indexOf("[*]"),t=e.slice(0,i),r=e.slice(i+3),f="_i",o=t.startsWith(".")?t.slice(1):t,s=omniAst.builders.identifier(f);if(o){let c=j(o);for(let a of c)a.type==="key"&&(s=omniAst.builders.memberExpression(s,omniAst.builders.identifier(a.value),false,true));}if(r.includes("[*]")){let c=tn(s,r);return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(f)],c)])}let u=r.startsWith(".")?r.slice(1):r;if(u){let c=j(u);for(let a of c)a.type==="key"&&(s=omniAst.builders.memberExpression(s,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(f)],s)])}function Gn(n,e,i,t,r,f){let o;if(typeof n.$if=="string"){let c=n.$if.startsWith("!"),a=c?n.$if.slice(1):n.$if,p;r?L(a,f)?p=w(a,e,true):p=omniAst.builders.callExpression(omniAst.builders.identifier(I),[omniAst.builders.literal(a),omniAst.builders.identifier(e)]):p=w(a,e,t),o=c?omniAst.builders.unaryExpression("!",p):p;}else o=g(n.$if,e,i,t,r,f);let s=g(n.then,e,i,t,r,f),u=n.else!==void 0?g(n.else,e,i,t,r,f):omniAst.builders.identifier("undefined");return omniAst.builders.conditionalExpression(o,s,u)}function Wn(n,e,i,t,r,f){let o=t?omniAst.builders.identifier(n.$fn):omniAst.builders.memberExpression(omniAst.builders.identifier(i),omniAst.builders.identifier(n.$fn),false,false);if(n.args===void 0)return o;let s=n.args.map(u=>typeof u=="function"?omniAst.builders.literal(null):g(u,e,i,t,r,f));return omniAst.builders.callExpression(o,s)}function zn(n,e,i,t,r,f){if(n.length===0)return omniAst.builders.identifier("undefined");if(n.length===1)return g(n[0],e,i,t,r,f);let o=g(n[0],e,i,t,r,f);for(let s=1;s<n.length;s++){let u=g(n[s],e,i,t,r,f);o=omniAst.builders.callExpression(u,[o]);}return o}function nn(n,e,i,t,r,f){if(m(n)){let o=n.$;return r?L(o,f)?w(o,e,true):omniAst.builders.callExpression(omniAst.builders.identifier(I),[omniAst.builders.literal(o),omniAst.builders.identifier(e)]):w(o,e,t)}return g(n,e,i,t,r,f)}function Mn(n,e,i,t,r,f){let o=nn(n.left,e,i,t,r,f),s=n.right!==void 0?nn(n.right,e,i,t,r,f):omniAst.builders.literal(null),u=Nn[n.op];if(u)return omniAst.builders.binaryExpression(u,o,s);switch(n.op){case "in":return omniAst.builders.callExpression(omniAst.builders.memberExpression(s,omniAst.builders.identifier("includes")),[o]);case "notIn":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(s,omniAst.builders.identifier("includes")),[o]));case "contains":return omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("includes"),false,true),[s]);case "notContains":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("includes"),false,true),[s]));case "exists":return omniAst.builders.binaryExpression("!=",o,omniAst.builders.literal(null));case "notExists":return omniAst.builders.binaryExpression("==",o,omniAst.builders.literal(null));case "matches":return omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[s]),omniAst.builders.identifier("test")),[o]);case "notMatches":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[s]),omniAst.builders.identifier("test")),[o]));case "startsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("startsWith"),false,true),[s]);case "endsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(o,omniAst.builders.identifier("endsWith"),false,true),[s]);default:return omniAst.builders.binaryExpression("===",o,s)}}function Dn(n,e,i,t,r,f){let{logic:o,conditions:s}=n,u=o==="AND"?"&&":"||";if(s.length===0)return omniAst.builders.literal(o==="AND");if(s.length===1)return g(s[0],e,i,t,r,f);let c=g(s[0],e,i,t,r,f);for(let a=1;a<s.length;a++){let p=g(s[a],e,i,t,r,f);c=omniAst.builders.logicalExpression(u,c,p);}return c}function j(n){let e=[],i=n.length,t=0,r="";for(;t<i;){let f=n[t];if(f===".")r&&(e.push({type:"key",value:r}),r=""),t++;else if(f==="["){r&&(e.push({type:"key",value:r}),r=""),t++;let o=t;for(;t<i&&n[t]!=="]";)t++;let s=n.slice(o,t);if(t++,s!=="*"){let u=parseInt(s,10);e.push({type:"index",value:isNaN(u)?s:u});}}else r+=f,t++;}return r&&e.push({type:"key",value:r}),e}function on(n,e=[D]){return omniAst.builders.arrowFunctionExpression(e.map(i=>omniAst.builders.identifier(i)),n)}function G(n){let e=new Set;return C(n,e),e}function C(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let t of n)C(t,e);return}if(m(n))return;if(E(n)){C(n.$if,e),C(n.then,e),n.else!==void 0&&C(n.else,e);return}if(b(n)){for(let t of n.$pipe)C(t,e);return}if(T(n)){if(e.add(n.$fn),n.args)for(let t of n.args)typeof t!="function"&&C(t,e);return}if(y(n)){n.left!==void 0&&typeof n.left=="object"&&C(n.left,e),n.right!==void 0&&typeof n.right=="object"&&C(n.right,e);return}if(h(n)){for(let t of n.conditions)C(t,e);return}let i=n;for(let t of Object.keys(i))C(i[t],e);}function W(n){let e=new Set;for(let i of n){let t=i.indexOf("."),r=i.indexOf("["),f=i.length;t!==-1&&(f=Math.min(f,t)),r!==-1&&(f=Math.min(f,r));let o=i.slice(0,f);o&&e.add(o);}return e}function Ln(n){return JSON.stringify(n)}function Vn(n,e,i,t,r){let f=v(n,{noPrefixes:true,useAccessor:t,lexicalPrefix:r}),o=omniAst.generate(f),s="";t?r&&(s=`const{${r}}=data??{};`):e.size>0&&(s=`const{${[...e].join(",")}}=data??{};`);let u=t?new Set([...i,"accessor"]):i,c=u.size>0?`const{${[...u].join(",")}}=scope;`:"";return c?`(function(scope){${c}return function(data){${s}return ${o}}})`:`(function(){return function(data){${s}return ${o}}})`}function V(n,e={}){let{scope:i={},returnCode:t=false,useAccessor:r=false,lexicalPrefix:f}=e,o=k(n),s=W(o),u=G(n),c=Ln(n),a=Vn(n,s,u,r,f);if(t)return {code:a,deps:o,hash:c,dataRoots:[...s],scopeFns:[...u]};let p;try{p=new Function(`return ${a}`)()(i);}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:o,hash:c}}function rn(n,e,i={}){let{fn:t}=V(n,i);return t(e)}var Te="0.1.1";exports.ExpressionCache=N;exports.VERSION=Te;exports.assertValid=kn;exports.builders=Z;exports.cache=H;exports.cached=An;exports.clearPathCache=gn;exports.compile=O;exports.compileAST=V;exports.compilePath=F;exports.dslToAST=v;exports.evaluate=$n;exports.evaluateAST=rn;exports.extractDataRoots=W;exports.extractDeps=k;exports.extractScopeFns=G;exports.get=dn;exports.getPathCacheSize=mn;exports.hasDeps=yn;exports.hasWildcard=J;exports.isCondition=y;exports.isConditionExpr=ln;exports.isConditionGroup=h;exports.isConditional=E;exports.isFn=T;exports.isLiteral=z;exports.isPipe=b;exports.isPure=hn;exports.isRef=m;exports.isValid=wn;exports.normalizePath=x;exports.validate=M;exports.wrapInFunction=on;
|
|
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;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { ConditionExpr, Condition, ConditionGroup } from '@statedelta-libs/conditions';
|
|
2
|
-
export { Condition, ConditionExpr, ConditionGroup, Ref } from '@statedelta-libs/conditions';
|
|
3
1
|
import { types } from 'omni-ast';
|
|
4
2
|
|
|
5
3
|
/**
|
|
@@ -7,7 +5,10 @@ import { types } from 'omni-ast';
|
|
|
7
5
|
*
|
|
8
6
|
* Core types for expression compilation.
|
|
9
7
|
*/
|
|
10
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Condition operators
|
|
10
|
+
*/
|
|
11
|
+
type ConditionOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "contains" | "notContains" | "exists" | "notExists" | "matches" | "notMatches" | "startsWith" | "endsWith";
|
|
11
12
|
/**
|
|
12
13
|
* Reference to a path in data object
|
|
13
14
|
* @example { "$": "user.name" }
|
|
@@ -60,6 +61,28 @@ interface PipeExpr {
|
|
|
60
61
|
type Literal = string | number | boolean | null | Literal[] | {
|
|
61
62
|
[key: string]: Literal;
|
|
62
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* Condition expression - both sides accept any Expression
|
|
66
|
+
* @example { left: { $: "age" }, op: "gte", right: 18 }
|
|
67
|
+
* @example { left: { $fn: "getAge", args: [{ $: "user" }] }, op: "gte", right: 18 }
|
|
68
|
+
*/
|
|
69
|
+
interface Condition {
|
|
70
|
+
left: Expression;
|
|
71
|
+
op: ConditionOp;
|
|
72
|
+
right?: Expression;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Condition group with AND/OR logic
|
|
76
|
+
* @example { logic: "AND", conditions: [...] }
|
|
77
|
+
*/
|
|
78
|
+
interface ConditionGroup {
|
|
79
|
+
logic: "AND" | "OR";
|
|
80
|
+
conditions: Expression[];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Union of condition types
|
|
84
|
+
*/
|
|
85
|
+
type ConditionExpr = Condition | ConditionGroup;
|
|
63
86
|
/**
|
|
64
87
|
* Union of all expression types
|
|
65
88
|
*/
|
|
@@ -143,15 +166,14 @@ declare const isFn: (v: unknown) => v is FnExpr;
|
|
|
143
166
|
*/
|
|
144
167
|
declare const isPipe: (v: unknown) => v is PipeExpr;
|
|
145
168
|
/**
|
|
146
|
-
* Check if value is a condition
|
|
169
|
+
* Check if value is a condition expression
|
|
147
170
|
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
* properties but with non-condition operators like "set".
|
|
171
|
+
* Verifies `op` is a valid condition operator to distinguish from
|
|
172
|
+
* effect objects that also have `left` and `op` (e.g. op: "set").
|
|
151
173
|
*/
|
|
152
174
|
declare const isCondition: (v: unknown) => v is Condition;
|
|
153
175
|
/**
|
|
154
|
-
* Check if value is a condition group
|
|
176
|
+
* Check if value is a condition group
|
|
155
177
|
*/
|
|
156
178
|
declare const isConditionGroup: (v: unknown) => v is ConditionGroup;
|
|
157
179
|
/**
|
|
@@ -452,16 +474,36 @@ declare function $pipe(...steps: Expression[]): PipeExpr;
|
|
|
452
474
|
* Alias for $pipe (pipe builder)
|
|
453
475
|
*/
|
|
454
476
|
declare const pipe: typeof $pipe;
|
|
477
|
+
/**
|
|
478
|
+
* Create a condition expression.
|
|
479
|
+
*
|
|
480
|
+
* @param left - Left side (any expression)
|
|
481
|
+
* @param op - Condition operator
|
|
482
|
+
* @param right - Right side (any expression, optional for exists/notExists)
|
|
483
|
+
* @returns Condition
|
|
484
|
+
*
|
|
485
|
+
* @example
|
|
486
|
+
* $cond($("age"), "gte", 18)
|
|
487
|
+
* $cond($fn("getScore", [$("user")]), "gt", 100)
|
|
488
|
+
* $cond($("email"), "exists")
|
|
489
|
+
*/
|
|
490
|
+
declare function $cond(left: Expression, op: ConditionOp, right?: Expression): Condition;
|
|
491
|
+
/**
|
|
492
|
+
* Alias for $cond (condition builder)
|
|
493
|
+
*/
|
|
494
|
+
declare const cond: typeof $cond;
|
|
455
495
|
|
|
456
496
|
declare const builders_$: typeof $;
|
|
497
|
+
declare const builders_$cond: typeof $cond;
|
|
457
498
|
declare const builders_$fn: typeof $fn;
|
|
458
499
|
declare const builders_$if: typeof $if;
|
|
459
500
|
declare const builders_$pipe: typeof $pipe;
|
|
501
|
+
declare const builders_cond: typeof cond;
|
|
460
502
|
declare const builders_fn: typeof fn;
|
|
461
503
|
declare const builders_pipe: typeof pipe;
|
|
462
504
|
declare const builders_ref: typeof ref;
|
|
463
505
|
declare namespace builders {
|
|
464
|
-
export { builders_$ as $, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
506
|
+
export { builders_$ as $, builders_$cond as $cond, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_cond as cond, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
465
507
|
}
|
|
466
508
|
|
|
467
509
|
/**
|
|
@@ -684,4 +726,4 @@ declare function evaluateAST<T = unknown, R = unknown>(expr: Expression, data: T
|
|
|
684
726
|
*/
|
|
685
727
|
declare const VERSION = "0.1.1";
|
|
686
728
|
|
|
687
|
-
export { type AccessorFn, type CallbackFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, 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 };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { ConditionExpr, Condition, ConditionGroup } from '@statedelta-libs/conditions';
|
|
2
|
-
export { Condition, ConditionExpr, ConditionGroup, Ref } from '@statedelta-libs/conditions';
|
|
3
1
|
import { types } from 'omni-ast';
|
|
4
2
|
|
|
5
3
|
/**
|
|
@@ -7,7 +5,10 @@ import { types } from 'omni-ast';
|
|
|
7
5
|
*
|
|
8
6
|
* Core types for expression compilation.
|
|
9
7
|
*/
|
|
10
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Condition operators
|
|
10
|
+
*/
|
|
11
|
+
type ConditionOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "contains" | "notContains" | "exists" | "notExists" | "matches" | "notMatches" | "startsWith" | "endsWith";
|
|
11
12
|
/**
|
|
12
13
|
* Reference to a path in data object
|
|
13
14
|
* @example { "$": "user.name" }
|
|
@@ -60,6 +61,28 @@ interface PipeExpr {
|
|
|
60
61
|
type Literal = string | number | boolean | null | Literal[] | {
|
|
61
62
|
[key: string]: Literal;
|
|
62
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* Condition expression - both sides accept any Expression
|
|
66
|
+
* @example { left: { $: "age" }, op: "gte", right: 18 }
|
|
67
|
+
* @example { left: { $fn: "getAge", args: [{ $: "user" }] }, op: "gte", right: 18 }
|
|
68
|
+
*/
|
|
69
|
+
interface Condition {
|
|
70
|
+
left: Expression;
|
|
71
|
+
op: ConditionOp;
|
|
72
|
+
right?: Expression;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Condition group with AND/OR logic
|
|
76
|
+
* @example { logic: "AND", conditions: [...] }
|
|
77
|
+
*/
|
|
78
|
+
interface ConditionGroup {
|
|
79
|
+
logic: "AND" | "OR";
|
|
80
|
+
conditions: Expression[];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Union of condition types
|
|
84
|
+
*/
|
|
85
|
+
type ConditionExpr = Condition | ConditionGroup;
|
|
63
86
|
/**
|
|
64
87
|
* Union of all expression types
|
|
65
88
|
*/
|
|
@@ -143,15 +166,14 @@ declare const isFn: (v: unknown) => v is FnExpr;
|
|
|
143
166
|
*/
|
|
144
167
|
declare const isPipe: (v: unknown) => v is PipeExpr;
|
|
145
168
|
/**
|
|
146
|
-
* Check if value is a condition
|
|
169
|
+
* Check if value is a condition expression
|
|
147
170
|
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
* properties but with non-condition operators like "set".
|
|
171
|
+
* Verifies `op` is a valid condition operator to distinguish from
|
|
172
|
+
* effect objects that also have `left` and `op` (e.g. op: "set").
|
|
151
173
|
*/
|
|
152
174
|
declare const isCondition: (v: unknown) => v is Condition;
|
|
153
175
|
/**
|
|
154
|
-
* Check if value is a condition group
|
|
176
|
+
* Check if value is a condition group
|
|
155
177
|
*/
|
|
156
178
|
declare const isConditionGroup: (v: unknown) => v is ConditionGroup;
|
|
157
179
|
/**
|
|
@@ -452,16 +474,36 @@ declare function $pipe(...steps: Expression[]): PipeExpr;
|
|
|
452
474
|
* Alias for $pipe (pipe builder)
|
|
453
475
|
*/
|
|
454
476
|
declare const pipe: typeof $pipe;
|
|
477
|
+
/**
|
|
478
|
+
* Create a condition expression.
|
|
479
|
+
*
|
|
480
|
+
* @param left - Left side (any expression)
|
|
481
|
+
* @param op - Condition operator
|
|
482
|
+
* @param right - Right side (any expression, optional for exists/notExists)
|
|
483
|
+
* @returns Condition
|
|
484
|
+
*
|
|
485
|
+
* @example
|
|
486
|
+
* $cond($("age"), "gte", 18)
|
|
487
|
+
* $cond($fn("getScore", [$("user")]), "gt", 100)
|
|
488
|
+
* $cond($("email"), "exists")
|
|
489
|
+
*/
|
|
490
|
+
declare function $cond(left: Expression, op: ConditionOp, right?: Expression): Condition;
|
|
491
|
+
/**
|
|
492
|
+
* Alias for $cond (condition builder)
|
|
493
|
+
*/
|
|
494
|
+
declare const cond: typeof $cond;
|
|
455
495
|
|
|
456
496
|
declare const builders_$: typeof $;
|
|
497
|
+
declare const builders_$cond: typeof $cond;
|
|
457
498
|
declare const builders_$fn: typeof $fn;
|
|
458
499
|
declare const builders_$if: typeof $if;
|
|
459
500
|
declare const builders_$pipe: typeof $pipe;
|
|
501
|
+
declare const builders_cond: typeof cond;
|
|
460
502
|
declare const builders_fn: typeof fn;
|
|
461
503
|
declare const builders_pipe: typeof pipe;
|
|
462
504
|
declare const builders_ref: typeof ref;
|
|
463
505
|
declare namespace builders {
|
|
464
|
-
export { builders_$ as $, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
506
|
+
export { builders_$ as $, builders_$cond as $cond, builders_$fn as $fn, builders_$if as $if, builders_$pipe as $pipe, builders_cond as cond, builders_fn as fn, builders_pipe as pipe, builders_ref as ref };
|
|
465
507
|
}
|
|
466
508
|
|
|
467
509
|
/**
|
|
@@ -684,4 +726,4 @@ declare function evaluateAST<T = unknown, R = unknown>(expr: Expression, data: T
|
|
|
684
726
|
*/
|
|
685
727
|
declare const VERSION = "0.1.1";
|
|
686
728
|
|
|
687
|
-
export { type AccessorFn, type CallbackFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, 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 };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {isRef,compile,validate}from'@statedelta-libs/conditions';import {builders,generate}from'omni-ast';var sn=Object.defineProperty;var fn=(n,e)=>{for(var i in e)sn(n,i,{get:e[i],enumerable:true});};var m=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,E=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,T=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",b=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),_=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),y=n=>n!==null&&typeof n=="object"&&"left"in n&&"op"in n&&_.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),h=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,ln=n=>y(n)||h(n),z=n=>{if(n===null)return true;let e=typeof n;if(e==="string"||e==="number"||e==="boolean"||Array.isArray(n))return true;if(e==="object"&&n!==null){let i=n,t="left"in i&&"op"in i&&_.has(i.op);return !("$"in i)&&!("$if"in i)&&!("$fn"in i)&&!("$pipe"in i)&&!t&&!("logic"in i)}return false};var R=new Map;function q(n){let e=[],i=n.length,t=0,r="";for(;t<i;){let f=n[t];if(f===".")r&&(e.push({type:"key",value:r}),r=""),t++;else if(f==="["){r&&(e.push({type:"key",value:r}),r=""),t++;let o=t;for(;t<i&&n[t]!=="]";)t++;let s=n.slice(o,t);if(t++,s==="*")e.push({type:"wildcard",value:"*"});else {let u=parseInt(s,10);e.push({type:"index",value:isNaN(u)?s:u});}}else r+=f,t++;}return r&&e.push({type:"key",value:r}),e}function J(n){return n.includes("[*]")}function F(n){let e=R.get(n);return e||(e=J(n)?cn(n):un(n),R.set(n,e),e)}function un(n){if(!n.includes(".")&&!n.includes("["))return r=>r?.[n];let e=q(n),i=e.length;if(i===2){let[r,f]=e,o=r.value,s=f.value;return u=>u?.[o]?.[s]}if(i===3){let[r,f,o]=e,s=r.value,u=f.value,c=o.value;return a=>a?.[s]?.[u]?.[c]}let t=e.map(r=>r.value);return r=>{let f=r;for(let o=0;o<i&&f!=null;o++)f=f[t[o]];return f}}function cn(n){let e=q(n),i=[];for(let t=0;t<e.length;t++)e[t].type==="wildcard"&&i.push(t);return i.length===1?an(e,i[0]):pn(e,i)}function an(n,e){let i=n.slice(0,e).map(o=>o.value),t=n.slice(e+1).map(o=>o.value),r=i.length,f=t.length;if(f===0){if(r===1){let o=i[0];return s=>s?.[o]}return o=>{let s=o;for(let u=0;u<r&&s!=null;u++)s=s[i[u]];return s}}if(f===1){let o=t[0];if(r===1){let s=i[0];return u=>{let c=u?.[s];if(Array.isArray(c))return c.map(a=>a?.[o])}}return s=>{let u=s;for(let c=0;c<r&&u!=null;c++)u=u[i[c]];if(Array.isArray(u))return u.map(c=>c?.[o])}}return o=>{let s=o;for(let u=0;u<r&&s!=null;u++)s=s[i[u]];if(Array.isArray(s))return s.map(u=>{let c=u;for(let a=0;a<f&&c!=null;a++)c=c[t[a]];return c})}}function pn(n,e){let i=[],t=0;for(let f=0;f<e.length;f++){let o=e[f],s=f===e.length-1,u=n.slice(t,o).map(c=>c.value);u.length>0&&i.push({type:"access",keys:u}),i.push({type:s?"map":"flatMap",keys:[]}),t=o+1;}let r=n.slice(t).map(f=>f.value);return f=>{let o=f;for(let s of i){if(o==null)return;if(s.type==="access")for(let u of s.keys){if(o==null)return;o=o[u];}else if(s.type==="flatMap"){if(!Array.isArray(o))return;o=o.flatMap(u=>{let c=u;return Array.isArray(c)?c:[c]});}else if(s.type==="map"){if(!Array.isArray(o))return;r.length>0&&(o=o.map(u=>{let c=u;for(let a of r){if(c==null)return;c=c[a];}return c}));}}return o}}function dn(n,e){return F(e)(n)}function x(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function gn(){R.clear();}function mn(){return R.size}function k(n){let e=new Set;return $(n,e),Array.from(e)}function $(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let r=0;r<n.length;r++)$(n[r],e);return}if(m(n)){e.add(x(n.$));return}if(E(n)){if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(x(r));}else $(n.$if,e);$(n.then,e),n.else!==void 0&&$(n.else,e);return}if(b(n)){for(let r=0;r<n.$pipe.length;r++)$(n.$pipe[r],e);return}if(T(n)){if(n.args)for(let r=0;r<n.args.length;r++){let f=n.args[r];typeof f!="function"&&$(f,e);}return}if(y(n)){isRef(n.left)&&e.add(x(n.left.$)),n.right!==void 0&&isRef(n.right)&&e.add(x(n.right.$));return}if(h(n)){for(let r=0;r<n.conditions.length;r++)$(n.conditions[r],e);return}let i=n,t=Object.keys(i);for(let r=0;r<t.length;r++)$(i[t[r]],e);}function yn(n){return k(n).length>0}function hn(n){return k(n).length===0}function En(n){return JSON.stringify(n)}function O(n,e={}){let i=e.scope??{},t=e.accessor,r=S(n,i,t),f=k(n),o=En(n);return {fn:r,deps:f,hash:o}}function S(n,e,i){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let t=n.map(r=>S(r,e,i));return r=>t.map(f=>f(r))}if(m(n))return Tn(n,i);if(E(n))return bn(n,e,i);if(b(n))return Cn(n,e,i);if(T(n))return Sn(n,e,i);if(y(n))return compile(n,i?{accessor:i}:void 0);if(h(n))return compile(n,i?{accessor:i}:void 0);if(z(n)){let t=n,r=Object.keys(t),f=r.map(o=>S(t[o],e,i));return o=>{let s={};for(let u=0;u<r.length;u++)s[r[u]]=f[u](o);return s}}return ()=>n}function Y(n,e){return e?i=>e(n,i):F(n)}function Tn(n,e){return Y(n.$,e)}function bn(n,e,i){let t;if(typeof n.$if=="string"){let o=n.$if.startsWith("!")?n.$if.slice(1):n.$if,s=Y(o,i);t=n.$if.startsWith("!")?c=>!s(c):c=>!!s(c);}else {let o=S(n.$if,e,i);t=s=>!!o(s);}let r=S(n.then,e,i),f=n.else!==void 0?S(n.else,e,i):()=>{};return o=>t(o)?r(o):f(o)}function Cn(n,e,i){let t=n.$pipe;if(t.length===0)return ()=>{};if(t.length===1)return S(t[0],e,i);let r=S(t[0],e,i),f=t.slice(1).map(s=>S(s,e,i)),o=f.length;if(o===1){let[s]=f;return u=>{let c=r(u),a=s(u);return typeof a=="function"?a(c):a}}if(o===2){let[s,u]=f;return c=>{let a=r(c),p=s(c);return a=typeof p=="function"?p(a):p,p=u(c),typeof p=="function"?p(a):p}}if(o===3){let[s,u,c]=f;return a=>{let p=r(a),d=s(a);return p=typeof d=="function"?d(p):d,d=u(a),p=typeof d=="function"?d(p):d,d=c(a),typeof d=="function"?d(p):d}}return s=>{let u=r(s);for(let c=0;c<o;c++){let a=f[c](s);u=typeof a=="function"?a(u):a;}return u}}function Sn(n,e,i){let t=n.$fn,r=n.args;if(r===void 0)return ()=>{let s=e[t];if(!s)throw new Error(`Function not found in scope: ${t}`);return s};let f=r.map(s=>typeof s=="function"?()=>s:S(s,e,i)),o=f.length;if(o===0)return s=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u()};if(o===1){let[s]=f;return u=>{let c=e[t];if(!c)throw new Error(`Function not found in scope: ${t}`);return c(s(u))}}if(o===2){let[s,u]=f;return c=>{let a=e[t];if(!a)throw new Error(`Function not found in scope: ${t}`);return a(s(c),u(c))}}if(o===3){let[s,u,c]=f;return a=>{let p=e[t];if(!p)throw new Error(`Function not found in scope: ${t}`);return p(s(a),u(a),c(a))}}return s=>{let u=e[t];if(!u)throw new Error(`Function not found in scope: ${t}`);return u(...f.map(c=>c(s)))}}function $n(n,e,i={}){return O(n,i).fn(e)}var N=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,i={}){let t=JSON.stringify(e),r=this.cache.get(t);if(r)return this.cache.delete(t),this.cache.set(t,r),r;let f=O(e,i);if(this.cache.size>=this._maxSize){let o=this.cache.keys().next().value;o&&this.cache.delete(o);}return this.cache.set(t,f),f}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);}}},H=new N;function An(n,e={}){return H.get(n,e)}function M(n,e="root",i={}){let t=[];return A(n,e,t,i),{valid:t.length===0,errors:t}}function A(n,e,i,t){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let o=0;o<n.length;o++)A(n[o],`${e}[${o}]`,i,t);return}if(m(n)){(!n.$||typeof n.$!="string")&&i.push(`${e}: invalid reference, $ must be non-empty string`);return}if(E(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||i.push(`${e}.$if: empty path in string shorthand`):A(n.$if,`${e}.$if`,i,t),A(n.then,`${e}.then`,i,t),n.else!==void 0&&A(n.else,`${e}.else`,i,t);return}if(b(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 o=0;o<n.$pipe.length;o++)A(n.$pipe[o],`${e}.$pipe[${o}]`,i,t);return}if(T(n)){if(!n.$fn||typeof n.$fn!="string"){i.push(`${e}: invalid function, $fn must be non-empty string`);return}if(t.scope&&!(n.$fn in t.scope)&&i.push(`${e}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))i.push(`${e}.args: must be an array`);else for(let o=0;o<n.args.length;o++){let s=n.args[o];typeof s!="function"&&A(s,`${e}.args[${o}]`,i,t);}return}if(y(n)){let o=validate(n,e);o.valid||i.push(...o.errors);return}if(h(n)){let o=validate(n,e);o.valid||i.push(...o.errors);return}let r=n,f=Object.keys(r);for(let o=0;o<f.length;o++){let s=f[o];A(r[s],`${e}.${s}`,i,t);}}function kn(n,e={}){let i=M(n,"root",e);if(!i.valid)throw new Error(`Invalid expression: ${i.errors.join("; ")}`)}function wn(n,e={}){return M(n,"root",e).valid}var Z={};fn(Z,{$:()=>Q,$fn:()=>U,$if:()=>Fn,$pipe:()=>X,fn:()=>Rn,pipe:()=>On,ref:()=>xn});function Q(n){return {$:n}}var xn=Q;function U(n,e){return e===void 0||e.length===0?{$fn:n}:{$fn:n,args:e}}var Rn=U;function Fn(n,e,i){return i===void 0?{$if:n,then:e}:{$if:n,then:e,else:i}}function X(...n){return {$pipe:n}}var On=X;var D="data",en="scope",Nn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function v(n,e={}){let{dataParam:i=D,scopeParam:t=en,noPrefixes:r=false,useAccessor:f=false,lexicalPrefix:o}=e;return g(n,i,t,r,f,o)}function g(n,e,i,t,r,f){if(n===null)return builders.literal(null);if(typeof n=="string")return builders.literal(n);if(typeof n=="number")return builders.literal(n);if(typeof n=="boolean")return builders.literal(n);if(Array.isArray(n))return builders.arrayExpression(n.map(o=>g(o,e,i,t,r,f)));if(m(n))return jn(n.$,e,t,r,f);if(E(n))return Gn(n,e,i,t,r,f);if(b(n))return zn(n.$pipe,e,i,t,r,f);if(T(n))return Wn(n,e,i,t,r,f);if(y(n))return Mn(n,e,i,t,r,f);if(h(n))return Dn(n,e,i,t,r,f);if(typeof n=="object"){let s=Object.entries(n).map(([u,c])=>builders.property(builders.identifier(u),g(c,e,i,t,r,f)));return builders.objectExpression(s)}return builders.literal(null)}var I="accessor";function L(n,e){return e?n===e||n.startsWith(e+"."):false}function jn(n,e,i,t,r){return t?L(n,r)?w(n,e,true):builders.callExpression(builders.identifier(I),[builders.literal(n),builders.identifier(e)]):n.includes("[*]")?vn(n,e,i):w(n,e,i)}function w(n,e,i){let t=j(n);if(t.length===0)return i?builders.identifier("undefined"):builders.identifier(e);let r;if(i){let f=t[0];r=builders.identifier(f.value);for(let o=1;o<t.length;o++){let s=t[o];s.type==="key"?r=builders.memberExpression(r,builders.identifier(s.value),false,true):r=builders.memberExpression(r,builders.literal(s.value),true,true);}}else {r=builders.identifier(e);for(let f of t)f.type==="key"?r=builders.memberExpression(r,builders.identifier(f.value),false,true):r=builders.memberExpression(r,builders.literal(f.value),true,true);}return r}function vn(n,e,i){let t=n.indexOf("[*]"),r=n.slice(0,t),f=n.slice(t+3),o;if(r?o=w(r,e,i):o=i?builders.identifier("undefined"):builders.identifier(e),!f||f==="")return o;if(f.includes("[*]"))return tn(o,f);let s="_i",u=f.startsWith(".")?f.slice(1):f,c=builders.identifier(s);if(u){let a=j(u);for(let p of a)p.type==="key"?c=builders.memberExpression(c,builders.identifier(p.value),false,true):c=builders.memberExpression(c,builders.literal(p.value),true,true);}return builders.callExpression(builders.memberExpression(o,builders.identifier("map"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],c)])}function tn(n,e){let i=e.indexOf("[*]"),t=e.slice(0,i),r=e.slice(i+3),f="_i",o=t.startsWith(".")?t.slice(1):t,s=builders.identifier(f);if(o){let c=j(o);for(let a of c)a.type==="key"&&(s=builders.memberExpression(s,builders.identifier(a.value),false,true));}if(r.includes("[*]")){let c=tn(s,r);return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(f)],c)])}let u=r.startsWith(".")?r.slice(1):r;if(u){let c=j(u);for(let a of c)a.type==="key"&&(s=builders.memberExpression(s,builders.identifier(a.value),false,true));}return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(f)],s)])}function Gn(n,e,i,t,r,f){let o;if(typeof n.$if=="string"){let c=n.$if.startsWith("!"),a=c?n.$if.slice(1):n.$if,p;r?L(a,f)?p=w(a,e,true):p=builders.callExpression(builders.identifier(I),[builders.literal(a),builders.identifier(e)]):p=w(a,e,t),o=c?builders.unaryExpression("!",p):p;}else o=g(n.$if,e,i,t,r,f);let s=g(n.then,e,i,t,r,f),u=n.else!==void 0?g(n.else,e,i,t,r,f):builders.identifier("undefined");return builders.conditionalExpression(o,s,u)}function Wn(n,e,i,t,r,f){let o=t?builders.identifier(n.$fn):builders.memberExpression(builders.identifier(i),builders.identifier(n.$fn),false,false);if(n.args===void 0)return o;let s=n.args.map(u=>typeof u=="function"?builders.literal(null):g(u,e,i,t,r,f));return builders.callExpression(o,s)}function zn(n,e,i,t,r,f){if(n.length===0)return builders.identifier("undefined");if(n.length===1)return g(n[0],e,i,t,r,f);let o=g(n[0],e,i,t,r,f);for(let s=1;s<n.length;s++){let u=g(n[s],e,i,t,r,f);o=builders.callExpression(u,[o]);}return o}function nn(n,e,i,t,r,f){if(m(n)){let o=n.$;return r?L(o,f)?w(o,e,true):builders.callExpression(builders.identifier(I),[builders.literal(o),builders.identifier(e)]):w(o,e,t)}return g(n,e,i,t,r,f)}function Mn(n,e,i,t,r,f){let o=nn(n.left,e,i,t,r,f),s=n.right!==void 0?nn(n.right,e,i,t,r,f):builders.literal(null),u=Nn[n.op];if(u)return builders.binaryExpression(u,o,s);switch(n.op){case "in":return builders.callExpression(builders.memberExpression(s,builders.identifier("includes")),[o]);case "notIn":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(s,builders.identifier("includes")),[o]));case "contains":return builders.callExpression(builders.memberExpression(o,builders.identifier("includes"),false,true),[s]);case "notContains":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(o,builders.identifier("includes"),false,true),[s]));case "exists":return builders.binaryExpression("!=",o,builders.literal(null));case "notExists":return builders.binaryExpression("==",o,builders.literal(null));case "matches":return builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[s]),builders.identifier("test")),[o]);case "notMatches":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[s]),builders.identifier("test")),[o]));case "startsWith":return builders.callExpression(builders.memberExpression(o,builders.identifier("startsWith"),false,true),[s]);case "endsWith":return builders.callExpression(builders.memberExpression(o,builders.identifier("endsWith"),false,true),[s]);default:return builders.binaryExpression("===",o,s)}}function Dn(n,e,i,t,r,f){let{logic:o,conditions:s}=n,u=o==="AND"?"&&":"||";if(s.length===0)return builders.literal(o==="AND");if(s.length===1)return g(s[0],e,i,t,r,f);let c=g(s[0],e,i,t,r,f);for(let a=1;a<s.length;a++){let p=g(s[a],e,i,t,r,f);c=builders.logicalExpression(u,c,p);}return c}function j(n){let e=[],i=n.length,t=0,r="";for(;t<i;){let f=n[t];if(f===".")r&&(e.push({type:"key",value:r}),r=""),t++;else if(f==="["){r&&(e.push({type:"key",value:r}),r=""),t++;let o=t;for(;t<i&&n[t]!=="]";)t++;let s=n.slice(o,t);if(t++,s!=="*"){let u=parseInt(s,10);e.push({type:"index",value:isNaN(u)?s:u});}}else r+=f,t++;}return r&&e.push({type:"key",value:r}),e}function on(n,e=[D]){return builders.arrowFunctionExpression(e.map(i=>builders.identifier(i)),n)}function G(n){let e=new Set;return C(n,e),e}function C(n,e){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let t of n)C(t,e);return}if(m(n))return;if(E(n)){C(n.$if,e),C(n.then,e),n.else!==void 0&&C(n.else,e);return}if(b(n)){for(let t of n.$pipe)C(t,e);return}if(T(n)){if(e.add(n.$fn),n.args)for(let t of n.args)typeof t!="function"&&C(t,e);return}if(y(n)){n.left!==void 0&&typeof n.left=="object"&&C(n.left,e),n.right!==void 0&&typeof n.right=="object"&&C(n.right,e);return}if(h(n)){for(let t of n.conditions)C(t,e);return}let i=n;for(let t of Object.keys(i))C(i[t],e);}function W(n){let e=new Set;for(let i of n){let t=i.indexOf("."),r=i.indexOf("["),f=i.length;t!==-1&&(f=Math.min(f,t)),r!==-1&&(f=Math.min(f,r));let o=i.slice(0,f);o&&e.add(o);}return e}function Ln(n){return JSON.stringify(n)}function Vn(n,e,i,t,r){let f=v(n,{noPrefixes:true,useAccessor:t,lexicalPrefix:r}),o=generate(f),s="";t?r&&(s=`const{${r}}=data??{};`):e.size>0&&(s=`const{${[...e].join(",")}}=data??{};`);let u=t?new Set([...i,"accessor"]):i,c=u.size>0?`const{${[...u].join(",")}}=scope;`:"";return c?`(function(scope){${c}return function(data){${s}return ${o}}})`:`(function(){return function(data){${s}return ${o}}})`}function V(n,e={}){let{scope:i={},returnCode:t=false,useAccessor:r=false,lexicalPrefix:f}=e,o=k(n),s=W(o),u=G(n),c=Ln(n),a=Vn(n,s,u,r,f);if(t)return {code:a,deps:o,hash:c,dataRoots:[...s],scopeFns:[...u]};let p;try{p=new Function(`return ${a}`)()(i);}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:o,hash:c}}function rn(n,e,i={}){let{fn:t}=V(n,i);return t(e)}var Te="0.1.1";export{N as ExpressionCache,Te as VERSION,kn as assertValid,Z as builders,H as cache,An as cached,gn as clearPathCache,O as compile,V as compileAST,F as compilePath,v as dslToAST,$n as evaluate,rn as evaluateAST,W as extractDataRoots,k as extractDeps,G as extractScopeFns,dn as get,mn as getPathCacheSize,yn as hasDeps,J as hasWildcard,y as isCondition,ln as isConditionExpr,h as isConditionGroup,E as isConditional,T as isFn,z as isLiteral,b as isPipe,hn as isPure,m as isRef,wn as isValid,x as normalizePath,M as validate,on as wrapInFunction};
|
|
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};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statedelta-libs/expressions",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "JSON DSL compiler for optimized functions - StateDelta expression engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"
|
|
18
|
-
"omni-ast": "^2.0.0"
|
|
17
|
+
"omni-ast": "^2.0.2"
|
|
19
18
|
},
|
|
20
19
|
"files": [
|
|
21
20
|
"dist",
|