@statedelta-libs/expressions 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +295 -7
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +80 -12
- package/dist/index.d.ts +80 -12
- package/dist/index.js +1 -1
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
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
|
+
- **Custom Transforms** - Extensão do walker via transforms registrados (`$query`, `$mapper`, etc.)
|
|
18
19
|
- **Type-safe** - TypeScript nativo com inferência
|
|
19
20
|
|
|
20
21
|
## Instalação
|
|
@@ -93,6 +94,75 @@ fn(data); // Executa (mais rápido que compile())
|
|
|
93
94
|
| Hot path crítico | `compileAST()` | V8 JIT otimiza melhor |
|
|
94
95
|
| Expressões complexas | `compileAST()` | Ganho maior em nested calls |
|
|
95
96
|
|
|
97
|
+
#### useAccessor (compileAST)
|
|
98
|
+
|
|
99
|
+
Para contextos inteligentes (ex: `TickContext`), use `useAccessor: true` para gerar `accessor(path, data)` ao invés de acesso direto:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
const ctx = new TickContext();
|
|
103
|
+
|
|
104
|
+
const { fn } = compileAST(
|
|
105
|
+
{ $fn: "add", args: [{ $: "hp" }, { $: "mp" }] },
|
|
106
|
+
{
|
|
107
|
+
scope: {
|
|
108
|
+
add,
|
|
109
|
+
accessor: (path) => ctx.get(path) // closure que captura ctx
|
|
110
|
+
},
|
|
111
|
+
useAccessor: true
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
fn(); // usa ctx.get("hp") + ctx.get("mp")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Código gerado:
|
|
119
|
+
```js
|
|
120
|
+
(function(scope){
|
|
121
|
+
const{add,accessor}=scope;
|
|
122
|
+
return function(data){
|
|
123
|
+
return add(accessor("hp",data),accessor("mp",data))
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### lexicalPrefix (compileAST)
|
|
129
|
+
|
|
130
|
+
Para máxima performance em paths específicos, use `lexicalPrefix` para acesso direto via destructuring:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
const ctx = new TickContext();
|
|
134
|
+
|
|
135
|
+
const { fn } = compileAST(
|
|
136
|
+
{ $fn: "add", args: [{ $: "hp" }, { $: "params.damage" }] },
|
|
137
|
+
{
|
|
138
|
+
scope: {
|
|
139
|
+
add,
|
|
140
|
+
accessor: (path) => ctx.get(path)
|
|
141
|
+
},
|
|
142
|
+
useAccessor: true,
|
|
143
|
+
lexicalPrefix: "params" // params.* vai direto, resto via accessor
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
fn({ params: { damage: 25 } }); // ctx.get("hp") + params.damage
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Código gerado:
|
|
151
|
+
```js
|
|
152
|
+
(function(scope){
|
|
153
|
+
const{add,accessor}=scope;
|
|
154
|
+
return function(data){
|
|
155
|
+
const{params}=data??{}; // destructuring direto (rápido!)
|
|
156
|
+
return add(accessor("hp",data),params?.damage)
|
|
157
|
+
}
|
|
158
|
+
})
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
| Path | Com lexicalPrefix | Sem lexicalPrefix |
|
|
162
|
+
|------|-------------------|-------------------|
|
|
163
|
+
| `params.damage` | `params?.damage` (direto) | `accessor("params.damage", data)` |
|
|
164
|
+
| `hp` | `accessor("hp", data)` | `accessor("hp", data)` |
|
|
165
|
+
|
|
96
166
|
### evaluate() / evaluateAST()
|
|
97
167
|
|
|
98
168
|
Compila e executa em um passo.
|
|
@@ -122,6 +192,33 @@ const deps = extractDeps({
|
|
|
122
192
|
// ["$isVip", "price.vip", "price.regular"]
|
|
123
193
|
```
|
|
124
194
|
|
|
195
|
+
## JSON Aninhado (Walk Automático)
|
|
196
|
+
|
|
197
|
+
O compilador **percorre automaticamente** todo o JSON e resolve expressões onde quer que estejam:
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
const { fn } = compile({
|
|
201
|
+
name: "John",
|
|
202
|
+
damage: { $: "params.damage" },
|
|
203
|
+
active: { $if: "hp.current", then: true, else: false },
|
|
204
|
+
nested: {
|
|
205
|
+
deep: {
|
|
206
|
+
value: { $fn: "add", args: [{ $: "a" }, { $: "b" }] }
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}, { scope });
|
|
210
|
+
|
|
211
|
+
fn({ params: { damage: 25 }, hp: { current: 100 }, a: 1, b: 2 });
|
|
212
|
+
// {
|
|
213
|
+
// name: "John",
|
|
214
|
+
// damage: 25,
|
|
215
|
+
// active: true,
|
|
216
|
+
// nested: { deep: { value: 3 } }
|
|
217
|
+
// }
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Não precisa de walker manual - o `compile()` e `compileAST()` já fazem isso internamente.
|
|
221
|
+
|
|
125
222
|
## Tipos de Expressão
|
|
126
223
|
|
|
127
224
|
### Literal
|
|
@@ -189,14 +286,36 @@ Chama função do scope com argumentos compilados.
|
|
|
189
286
|
// → scope.getTimestamp()
|
|
190
287
|
```
|
|
191
288
|
|
|
192
|
-
### Condition
|
|
289
|
+
### Condition
|
|
290
|
+
|
|
291
|
+
Condicionais compiladas internamente. Ambos os lados aceitam qualquer expressão:
|
|
193
292
|
|
|
194
293
|
```typescript
|
|
195
|
-
//
|
|
294
|
+
// Ref vs literal (básico)
|
|
196
295
|
{ left: { $: "user.age" }, op: "gte", right: 18 }
|
|
296
|
+
|
|
297
|
+
// Ref vs Ref
|
|
298
|
+
{ left: { $: "price" }, op: "lte", right: { $: "budget" } }
|
|
299
|
+
|
|
300
|
+
// $fn nos lados
|
|
301
|
+
{ left: { $fn: "add", args: [{ $: "a" }, { $: "b" }] }, op: "gt", right: 100 }
|
|
302
|
+
|
|
303
|
+
// $pipe no lado
|
|
304
|
+
{ left: { $pipe: [{ $: "name" }, { $fn: "upper" }] }, op: "eq", right: "ADMIN" }
|
|
305
|
+
|
|
306
|
+
// Condition group
|
|
307
|
+
{
|
|
308
|
+
logic: "AND",
|
|
309
|
+
conditions: [
|
|
310
|
+
{ left: { $: "active" }, op: "eq", right: true },
|
|
311
|
+
{ left: { $fn: "len", args: [{ $: "items" }] }, op: "gte", right: 3 }
|
|
312
|
+
]
|
|
313
|
+
}
|
|
197
314
|
```
|
|
198
315
|
|
|
199
|
-
|
|
316
|
+
**Operadores:** `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `notIn`, `contains`, `notContains`, `exists`, `notExists`, `matches`, `notMatches`, `startsWith`, `endsWith`
|
|
317
|
+
|
|
318
|
+
> **Nota:** Objetos com `op: "set"` ou outros operadores não-condition são tratados como literals.
|
|
200
319
|
|
|
201
320
|
## Scope
|
|
202
321
|
|
|
@@ -254,7 +373,7 @@ O accessor é propagado para:
|
|
|
254
373
|
- Shorthand de `$if` (`{ $if: "path", ... }`)
|
|
255
374
|
- Argumentos de `$fn`
|
|
256
375
|
- Steps de `$pipe`
|
|
257
|
-
- Conditions (
|
|
376
|
+
- Conditions (compiladas internamente)
|
|
258
377
|
|
|
259
378
|
**Performance:** Igual ao acesso direto (~25-30M ops/s).
|
|
260
379
|
|
|
@@ -337,6 +456,115 @@ Ambas as abordagens são **seguras contra injeção de código**:
|
|
|
337
456
|
|
|
338
457
|
Funções só são acessíveis se existirem no `scope` fornecido pelo desenvolvedor.
|
|
339
458
|
|
|
459
|
+
## Custom Transforms
|
|
460
|
+
|
|
461
|
+
Mecanismo de extensão do walker para tipos de expressão customizados. Permite registrar transforms que interceptam objetos com chaves específicas e os convertem em expressões padrão antes da compilação.
|
|
462
|
+
|
|
463
|
+
### API
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
const transforms = {
|
|
467
|
+
$query: (node) => ({
|
|
468
|
+
$fn: "__query",
|
|
469
|
+
args: [node.$query, node.params ?? {}]
|
|
470
|
+
}),
|
|
471
|
+
$mapper: (node) => ({
|
|
472
|
+
$fn: "__mapper",
|
|
473
|
+
args: [node.$mapper, node.params ?? {}]
|
|
474
|
+
}),
|
|
475
|
+
};
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### Uso com compile() e compileAST()
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
import { compile, compileAST } from '@statedelta-libs/expressions';
|
|
482
|
+
|
|
483
|
+
const scope = {
|
|
484
|
+
__query: (name, params) => queryEngine.run(name, params),
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
// Closures
|
|
488
|
+
const { fn } = compile(
|
|
489
|
+
{ $query: "isKingAttacked", params: { row: 0, col: 4 } },
|
|
490
|
+
{ scope, transforms }
|
|
491
|
+
);
|
|
492
|
+
|
|
493
|
+
// AST (mesmo contrato)
|
|
494
|
+
const { fn } = compileAST(
|
|
495
|
+
{ $query: "isKingAttacked", params: { row: 0, col: 4 } },
|
|
496
|
+
{ scope, transforms }
|
|
497
|
+
);
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Expressions dentro de params
|
|
501
|
+
|
|
502
|
+
Os params do transform são compilados recursivamente — referências e expressões dentro deles são resolvidas normalmente:
|
|
503
|
+
|
|
504
|
+
```typescript
|
|
505
|
+
const { fn } = compile(
|
|
506
|
+
{ $query: "check", params: { row: { $: "myRow" }, col: { $: "myCol" } } },
|
|
507
|
+
{ scope, transforms }
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
fn({ myRow: 5, myCol: 3 });
|
|
511
|
+
// → __query("check", { row: 5, col: 3 })
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Aninhamento
|
|
515
|
+
|
|
516
|
+
Transforms funcionam em qualquer posição — dentro de `$if`, `$pipe`, `$fn`, conditions, plain objects:
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
// Dentro de condition
|
|
520
|
+
{
|
|
521
|
+
$if: {
|
|
522
|
+
left: { $query: "isAttacked", params: { row: 0 } },
|
|
523
|
+
op: "eq",
|
|
524
|
+
right: true
|
|
525
|
+
},
|
|
526
|
+
then: "check",
|
|
527
|
+
else: "safe"
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Dentro de plain object (walk automático)
|
|
531
|
+
{
|
|
532
|
+
damage: { $query: "getDamage", params: { base: 10 } },
|
|
533
|
+
name: "attack"
|
|
534
|
+
}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### Extração de deps
|
|
538
|
+
|
|
539
|
+
`extractDeps` também resolve transforms para capturar dependências internas:
|
|
540
|
+
|
|
541
|
+
```typescript
|
|
542
|
+
import { extractDeps } from '@statedelta-libs/expressions';
|
|
543
|
+
|
|
544
|
+
const deps = extractDeps(
|
|
545
|
+
{ $query: "check", params: { row: { $: "myRow" } } },
|
|
546
|
+
transforms
|
|
547
|
+
);
|
|
548
|
+
// ["myRow"]
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### Proteção contra loops infinitos
|
|
552
|
+
|
|
553
|
+
Se um transform retornar um objeto com a mesma chave de entrada, um erro é lançado:
|
|
554
|
+
|
|
555
|
+
```typescript
|
|
556
|
+
const badTransforms = {
|
|
557
|
+
$loop: (node) => ({ $loop: node.$loop }), // mesma chave!
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
compile({ $loop: "test" }, { transforms: badTransforms });
|
|
561
|
+
// Error: Transform "$loop" returned object with same key — infinite loop
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### Performance
|
|
565
|
+
|
|
566
|
+
Transforms são resolvidos **em tempo de compilação**. Zero overhead em runtime — a função compilada resultante é idêntica a uma expressão `$fn` normal.
|
|
567
|
+
|
|
340
568
|
## Type Detection
|
|
341
569
|
|
|
342
570
|
O compilador detecta automaticamente o tipo de expressão baseado na estrutura do objeto:
|
|
@@ -348,6 +576,7 @@ O compilador detecta automaticamente o tipo de expressão baseado na estrutura d
|
|
|
348
576
|
| Function | `{ $fn }` presente | `{ $fn: "add", args: [...] }` |
|
|
349
577
|
| Pipe | `{ $pipe }` presente | `{ $pipe: [...] }` |
|
|
350
578
|
| Condition | `{ left, op }` com operador válido | `{ left: { $: "age" }, op: "gte", right: 18 }` |
|
|
579
|
+
| Custom Transform | Chave registrada em `transforms` | `{ $query: "check", params: {...} }` |
|
|
351
580
|
| Literal | Nenhum dos acima | `{ foo: "bar" }`, `42`, `"hello"` |
|
|
352
581
|
|
|
353
582
|
### Distinção entre Conditions e Effect Objects
|
|
@@ -371,7 +600,7 @@ Funções declarativas para construir expressões. Disponíveis via namespace `b
|
|
|
371
600
|
```typescript
|
|
372
601
|
import { builders, compile } from '@statedelta-libs/expressions';
|
|
373
602
|
|
|
374
|
-
const { $, $fn, $if, $pipe } = builders;
|
|
603
|
+
const { $, $fn, $if, $pipe, $cond } = builders;
|
|
375
604
|
```
|
|
376
605
|
|
|
377
606
|
### `$` / `ref` - Path Reference
|
|
@@ -423,13 +652,33 @@ $pipe(
|
|
|
423
652
|
)
|
|
424
653
|
```
|
|
425
654
|
|
|
655
|
+
### `$cond` / `cond` - Condition
|
|
656
|
+
|
|
657
|
+
```typescript
|
|
658
|
+
// Básico
|
|
659
|
+
$cond($("age"), "gte", 18)
|
|
660
|
+
// { left: { $: "age" }, op: "gte", right: 18 }
|
|
661
|
+
|
|
662
|
+
// Exists (sem right)
|
|
663
|
+
$cond($("email"), "exists")
|
|
664
|
+
|
|
665
|
+
// Ref vs Ref
|
|
666
|
+
$cond($("price"), "lte", $("budget"))
|
|
667
|
+
|
|
668
|
+
// Com $fn nos lados
|
|
669
|
+
$cond($fn("add", [$("a"), $("b")]), "gt", 100)
|
|
670
|
+
|
|
671
|
+
// Com $pipe
|
|
672
|
+
$cond($pipe($("name"), $fn("upper")), "eq", "ADMIN")
|
|
673
|
+
```
|
|
674
|
+
|
|
426
675
|
### Exemplo Completo
|
|
427
676
|
|
|
428
677
|
```typescript
|
|
429
678
|
import { builders, compile } from '@statedelta-libs/expressions';
|
|
430
679
|
import { filter, map, sum } from '@statedelta-libs/operators';
|
|
431
680
|
|
|
432
|
-
const { $, $fn, $if, $pipe } = builders;
|
|
681
|
+
const { $, $fn, $if, $pipe, $cond } = builders;
|
|
433
682
|
|
|
434
683
|
const scope = { filter, map, sum };
|
|
435
684
|
|
|
@@ -459,6 +708,7 @@ fn({
|
|
|
459
708
|
| `$` | `ref` |
|
|
460
709
|
| `$fn` | `fn` |
|
|
461
710
|
| `$pipe` | `pipe` |
|
|
711
|
+
| `$cond` | `cond` |
|
|
462
712
|
|
|
463
713
|
## TypeScript
|
|
464
714
|
|
|
@@ -470,9 +720,14 @@ import type {
|
|
|
470
720
|
ConditionalExpr,
|
|
471
721
|
FnExpr,
|
|
472
722
|
PipeExpr,
|
|
723
|
+
Condition,
|
|
724
|
+
ConditionGroup,
|
|
725
|
+
ConditionExpr,
|
|
726
|
+
ConditionOp,
|
|
473
727
|
Scope,
|
|
474
728
|
CompileOptions,
|
|
475
729
|
AccessorFn,
|
|
730
|
+
TransformFn,
|
|
476
731
|
} from '@statedelta-libs/expressions';
|
|
477
732
|
|
|
478
733
|
// Type guards
|
|
@@ -512,6 +767,39 @@ import {
|
|
|
512
767
|
|
|
513
768
|
4. **Novo**: `$pipe` como sintaxe DSL para composição
|
|
514
769
|
|
|
770
|
+
### v1.0 → v1.1
|
|
771
|
+
|
|
772
|
+
1. **Conditions internas**: `@statedelta-libs/conditions` não é mais dependência. Conditions são compiladas internamente.
|
|
773
|
+
|
|
774
|
+
2. **Expressions nos lados**: `left`/`right` de conditions agora aceitam qualquer `Expression` (`$fn`, `$pipe`, `$if`, etc), não apenas `Ref | literal`.
|
|
775
|
+
|
|
776
|
+
3. **Novo builder**: `$cond(left, op, right?)` para construir conditions com expressions:
|
|
777
|
+
```typescript
|
|
778
|
+
$cond($fn("add", [$("a"), $("b")]), "gt", 100)
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
4. **Novos tipos**: `ConditionOp`, `Condition`, `ConditionGroup`, `ConditionExpr` exportados diretamente do expressions.
|
|
782
|
+
|
|
783
|
+
### v1.1 → v1.2
|
|
784
|
+
|
|
785
|
+
1. **Custom Transforms**: Nova option `transforms` em `CompileOptions` e `CompileASTOptions`. Permite estender o walker com tipos de expressão customizados (`$query`, `$mapper`, etc.):
|
|
786
|
+
```typescript
|
|
787
|
+
const transforms = {
|
|
788
|
+
$query: (node) => ({ $fn: "__query", args: [node.$query, node.params ?? {}] }),
|
|
789
|
+
};
|
|
790
|
+
compile(expr, { scope, transforms });
|
|
791
|
+
compileAST(expr, { scope, transforms });
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
2. **extractDeps com transforms**: `extractDeps` agora aceita `transforms` como segundo argumento para capturar deps dentro de expressões customizadas:
|
|
795
|
+
```typescript
|
|
796
|
+
extractDeps(expr, transforms);
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
3. **Novo tipo**: `TransformFn` exportado diretamente do expressions.
|
|
800
|
+
|
|
801
|
+
4. **Zero breaking change**: O campo `transforms` é opcional. Sem ele, o comportamento é idêntico ao anterior.
|
|
802
|
+
|
|
515
803
|
## Licença
|
|
516
804
|
|
|
517
805
|
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 rn=Object.defineProperty;var sn=(n,e)=>{for(var i in e)rn(n,i,{get:e[i],enumerable:true});};var h=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,A=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,$=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",k=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),F=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),E=n=>n!==null&&typeof n=="object"&&"left"in n&&"op"in n&&F.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),T=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,fn=n=>E(n)||T(n),M=n=>{if(n===null)return true;let e=typeof n;if(e==="string"||e==="number"||e==="boolean"||Array.isArray(n))return true;if(e==="object"&&n!==null){let i=n,f="left"in i&&"op"in i&&F.has(i.op);return !("$"in i)&&!("$if"in i)&&!("$fn"in i)&&!("$pipe"in i)&&!f&&!("logic"in i)}return false};var x=new Map;function J(n){let e=[],i=n.length,f=0,o="";for(;f<i;){let s=n[f];if(s===".")o&&(e.push({type:"key",value:o}),o=""),f++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),f++;let t=f;for(;f<i&&n[f]!=="]";)f++;let r=n.slice(t,f);if(f++,r==="*")e.push({type:"wildcard",value:"*"});else {let c=parseInt(r,10);e.push({type:"index",value:isNaN(c)?r:c});}}else o+=s,f++;}return o&&e.push({type:"key",value:o}),e}function B(n){return n.includes("[*]")}function O(n){let e=x.get(n);return e||(e=B(n)?un(n):cn(n),x.set(n,e),e)}function cn(n){if(!n.includes(".")&&!n.includes("["))return o=>o?.[n];let e=J(n),i=e.length;if(i===2){let[o,s]=e,t=o.value,r=s.value;return c=>c?.[t]?.[r]}if(i===3){let[o,s,t]=e,r=o.value,c=s.value,l=t.value;return a=>a?.[r]?.[c]?.[l]}let f=e.map(o=>o.value);return o=>{let s=o;for(let t=0;t<i&&s!=null;t++)s=s[f[t]];return s}}function un(n){let e=J(n),i=[];for(let f=0;f<e.length;f++)e[f].type==="wildcard"&&i.push(f);return i.length===1?ln(e,i[0]):an(e,i)}function ln(n,e){let i=n.slice(0,e).map(t=>t.value),f=n.slice(e+1).map(t=>t.value),o=i.length,s=f.length;if(s===0){if(o===1){let t=i[0];return r=>r?.[t]}return t=>{let r=t;for(let c=0;c<o&&r!=null;c++)r=r[i[c]];return r}}if(s===1){let t=f[0];if(o===1){let r=i[0];return c=>{let l=c?.[r];if(Array.isArray(l))return l.map(a=>a?.[t])}}return r=>{let c=r;for(let l=0;l<o&&c!=null;l++)c=c[i[l]];if(Array.isArray(c))return c.map(l=>l?.[t])}}return t=>{let r=t;for(let c=0;c<o&&r!=null;c++)r=r[i[c]];if(Array.isArray(r))return r.map(c=>{let l=c;for(let a=0;a<s&&l!=null;a++)l=l[f[a]];return l})}}function an(n,e){let i=[],f=0;for(let s=0;s<e.length;s++){let t=e[s],r=s===e.length-1,c=n.slice(f,t).map(l=>l.value);c.length>0&&i.push({type:"access",keys:c}),i.push({type:r?"map":"flatMap",keys:[]}),f=t+1;}let o=n.slice(f).map(s=>s.value);return s=>{let t=s;for(let r of i){if(t==null)return;if(r.type==="access")for(let c of r.keys){if(t==null)return;t=t[c];}else if(r.type==="flatMap"){if(!Array.isArray(t))return;t=t.flatMap(c=>{let l=c;return Array.isArray(l)?l:[l]});}else if(r.type==="map"){if(!Array.isArray(t))return;o.length>0&&(t=t.map(c=>{let l=c;for(let a of o){if(l==null)return;l=l[a];}return l}));}}return t}}function pn(n,e){return O(e)(n)}function j(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function dn(){x.clear();}function gn(){return x.size}function w(n,e){let i=new Set;return b(n,i,e),Array.from(i)}function b(n,e,i){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let s=0;s<n.length;s++)b(n[s],e,i);return}if(h(n)){e.add(j(n.$));return}if(A(n)){if(typeof n.$if=="string"){let s=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(j(s));}else b(n.$if,e,i);b(n.then,e,i),n.else!==void 0&&b(n.else,e,i);return}if(k(n)){for(let s=0;s<n.$pipe.length;s++)b(n.$pipe[s],e,i);return}if($(n)){if(n.args)for(let s=0;s<n.args.length;s++){let t=n.args[s];typeof t!="function"&&b(t,e,i);}return}if(E(n)){b(n.left,e,i),n.right!==void 0&&b(n.right,e,i);return}if(T(n)){for(let s=0;s<n.conditions.length;s++)b(n.conditions[s],e,i);return}if(i){let s=n,t=Object.keys(s);for(let r=0;r<t.length;r++){let c=t[r];if(c in i){let l=i[c](s);if(typeof l=="object"&&l!==null&&c in l)throw new Error(`Transform "${c}" returned object with same key \u2014 infinite loop`);b(l,e,i);return}}}let f=n,o=Object.keys(f);for(let s=0;s<o.length;s++)b(f[o[s]],e,i);}function yn(n){return w(n).length>0}function mn(n){return w(n).length===0}function hn(n){return JSON.stringify(n)}function N(n,e={}){let i=e.scope??{},f=e.accessor,o=e.transforms,s=m(n,i,f,o),t=w(n,o),r=hn(n);return {fn:s,deps:t,hash:r}}function m(n,e,i,f){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let o=n.map(s=>m(s,e,i,f));return s=>o.map(t=>t(s))}if(h(n))return En(n,i);if(A(n))return Tn(n,e,i,f);if(k(n))return bn(n,e,i,f);if($(n))return Cn(n,e,i,f);if(E(n))return An(n,e,i,f);if(T(n))return $n(n,e,i,f);if(f){let o=n,s=Object.keys(o);for(let t=0;t<s.length;t++){let r=s[t];if(r in f){let c=f[r](o);if(typeof c=="object"&&c!==null&&r in c)throw new Error(`Transform "${r}" returned object with same key \u2014 infinite loop`);return m(c,e,i,f)}}}if(M(n)){let o=n,s=Object.keys(o),t=s.map(r=>m(o[r],e,i,f));return r=>{let c={};for(let l=0;l<s.length;l++)c[s[l]]=t[l](r);return c}}return ()=>n}function K(n,e){return e?i=>e(n,i):O(n)}function En(n,e){return K(n.$,e)}function Tn(n,e,i,f){let o;if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if,c=K(r,i);o=n.$if.startsWith("!")?a=>!c(a):a=>!!c(a);}else {let r=m(n.$if,e,i,f);o=c=>!!r(c);}let s=m(n.then,e,i,f),t=n.else!==void 0?m(n.else,e,i,f):()=>{};return r=>o(r)?s(r):t(r)}function bn(n,e,i,f){let o=n.$pipe;if(o.length===0)return ()=>{};if(o.length===1)return m(o[0],e,i,f);let s=m(o[0],e,i,f),t=o.slice(1).map(c=>m(c,e,i,f)),r=t.length;if(r===1){let[c]=t;return l=>{let a=s(l),p=c(l);return typeof p=="function"?p(a):p}}if(r===2){let[c,l]=t;return a=>{let p=s(a),d=c(a);return p=typeof d=="function"?d(p):d,d=l(a),typeof d=="function"?d(p):d}}if(r===3){let[c,l,a]=t;return p=>{let d=s(p),g=c(p);return d=typeof g=="function"?g(d):g,g=l(p),d=typeof g=="function"?g(d):g,g=a(p),typeof g=="function"?g(d):g}}return c=>{let l=s(c);for(let a=0;a<r;a++){let p=t[a](c);l=typeof p=="function"?p(l):p;}return l}}function Cn(n,e,i,f){let o=n.$fn,s=n.args;if(s===void 0)return ()=>{let c=e[o];if(!c)throw new Error(`Function not found in scope: ${o}`);return c};let t=s.map(c=>typeof c=="function"?()=>c:m(c,e,i,f)),r=t.length;if(r===0)return c=>{let l=e[o];if(!l)throw new Error(`Function not found in scope: ${o}`);return l()};if(r===1){let[c]=t;return l=>{let a=e[o];if(!a)throw new Error(`Function not found in scope: ${o}`);return a(c(l))}}if(r===2){let[c,l]=t;return a=>{let p=e[o];if(!p)throw new Error(`Function not found in scope: ${o}`);return p(c(a),l(a))}}if(r===3){let[c,l,a]=t;return p=>{let d=e[o];if(!d)throw new Error(`Function not found in scope: ${o}`);return d(c(p),l(p),a(p))}}return c=>{let l=e[o];if(!l)throw new Error(`Function not found in scope: ${o}`);return l(...t.map(a=>a(c)))}}function An(n,e,i,f){let o=m(n.left,e,i,f),s=n.right!==void 0?m(n.right,e,i,f):()=>{};switch(n.op){case "eq":return t=>o(t)===s(t);case "neq":return t=>o(t)!==s(t);case "gt":return t=>o(t)>s(t);case "gte":return t=>o(t)>=s(t);case "lt":return t=>o(t)<s(t);case "lte":return t=>o(t)<=s(t);case "in":return t=>{let r=s(t);return Array.isArray(r)&&r.includes(o(t))};case "notIn":return t=>{let r=s(t);return !Array.isArray(r)||!r.includes(o(t))};case "contains":return t=>{let r=o(t);return Array.isArray(r)&&r.includes(s(t))};case "notContains":return t=>{let r=o(t);return !Array.isArray(r)||!r.includes(s(t))};case "exists":return t=>o(t)!==void 0;case "notExists":return t=>o(t)===void 0;case "matches":return t=>{let r=o(t),c=s(t);return typeof r!="string"||typeof c!="string"?false:new RegExp(c).test(r)};case "notMatches":return t=>{let r=o(t),c=s(t);return typeof r!="string"||typeof c!="string"?true:!new RegExp(c).test(r)};case "startsWith":return t=>{let r=o(t),c=s(t);return typeof r=="string"&&typeof c=="string"&&r.startsWith(c)};case "endsWith":return t=>{let r=o(t),c=s(t);return typeof r=="string"&&typeof c=="string"&&r.endsWith(c)}}}function $n(n,e,i,f){let o=n.conditions.map(t=>m(t,e,i,f)),s=o.length;if(s===1)return t=>!!o[0](t);if(s===2){let[t,r]=o;return n.logic==="AND"?c=>!!t(c)&&!!r(c):c=>!!t(c)||!!r(c)}if(s===3){let[t,r,c]=o;return n.logic==="AND"?l=>!!t(l)&&!!r(l)&&!!c(l):l=>!!t(l)||!!r(l)||!!c(l)}return n.logic==="AND"?t=>{for(let r=0;r<s;r++)if(!o[r](t))return false;return true}:t=>{for(let r=0;r<s;r++)if(o[r](t))return true;return false}}function kn(n,e,i={}){return N(n,i).fn(e)}var v=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,i={}){let f=JSON.stringify(e),o=this.cache.get(f);if(o)return this.cache.delete(f),this.cache.set(f,o),o;let s=N(e,i);if(this.cache.size>=this._maxSize){let t=this.cache.keys().next().value;t&&this.cache.delete(t);}return this.cache.set(f,s),s}has(e){return this.cache.has(JSON.stringify(e))}delete(e){return this.cache.delete(JSON.stringify(e))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(e){for(this._maxSize=e;this.cache.size>this._maxSize;){let i=this.cache.keys().next().value;i&&this.cache.delete(i);}}},Y=new v;function Sn(n,e={}){return Y.get(n,e)}function z(n,e="root",i={}){let f=[];return S(n,e,f,i),{valid:f.length===0,errors:f}}function S(n,e,i,f){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let t=0;t<n.length;t++)S(n[t],`${e}[${t}]`,i,f);return}if(h(n)){(!n.$||typeof n.$!="string")&&i.push(`${e}: invalid reference, $ must be non-empty string`);return}if(A(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||i.push(`${e}.$if: empty path in string shorthand`):S(n.$if,`${e}.$if`,i,f),S(n.then,`${e}.then`,i,f),n.else!==void 0&&S(n.else,`${e}.else`,i,f);return}if(k(n)){if(!Array.isArray(n.$pipe)){i.push(`${e}.$pipe: must be an array`);return}if(n.$pipe.length===0){i.push(`${e}.$pipe: must have at least one element`);return}for(let t=0;t<n.$pipe.length;t++)S(n.$pipe[t],`${e}.$pipe[${t}]`,i,f);return}if($(n)){if(!n.$fn||typeof n.$fn!="string"){i.push(`${e}: invalid function, $fn must be non-empty string`);return}if(f.scope&&!(n.$fn in f.scope)&&i.push(`${e}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))i.push(`${e}.args: must be an array`);else for(let t=0;t<n.args.length;t++){let r=n.args[t];typeof r!="function"&&S(r,`${e}.args[${t}]`,i,f);}return}if(E(n)){F.has(n.op)||i.push(`${e}: invalid operator "${n.op}"`),S(n.left,`${e}.left`,i,f),n.right!==void 0&&S(n.right,`${e}.right`,i,f);return}if(T(n)){if(n.logic!=="AND"&&n.logic!=="OR"&&i.push(`${e}: invalid logic "${n.logic}", must be "AND" or "OR"`),!Array.isArray(n.conditions)){i.push(`${e}.conditions: must be an array`);return}for(let t=0;t<n.conditions.length;t++)S(n.conditions[t],`${e}.conditions[${t}]`,i,f);return}let o=n,s=Object.keys(o);for(let t=0;t<s.length;t++){let r=s[t];S(o[r],`${e}.${r}`,i,f);}}function wn(n,e={}){let i=z(n,"root",e);if(!i.valid)throw new Error(`Invalid expression: ${i.errors.join("; ")}`)}function Rn(n,e={}){return z(n,"root",e).valid}var Z={};sn(Z,{$:()=>H,$cond:()=>X,$fn:()=>Q,$if:()=>On,$pipe:()=>U,cond:()=>Nn,fn:()=>xn,pipe:()=>jn,ref:()=>Fn});function H(n){return {$:n}}var Fn=H;function Q(n,e){return e===void 0||e.length===0?{$fn:n}:{$fn:n,args:e}}var xn=Q;function On(n,e,i){return i===void 0?{$if:n,then:e}:{$if:n,then:e,else:i}}function U(...n){return {$pipe:n}}var jn=U;function X(n,e,i){return i===void 0?{left:n,op:e}:{left:n,op:e,right:i}}var Nn=X;var L="data",nn="scope",vn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function W(n,e={}){let{dataParam:i=L,scopeParam:f=nn,noPrefixes:o=false,useAccessor:s=false,lexicalPrefix:t,transforms:r}=e;return y(n,i,f,o,s,t,r)}function y(n,e,i,f,o,s,t){if(n===null)return omniAst.builders.literal(null);if(typeof n=="string")return omniAst.builders.literal(n);if(typeof n=="number")return omniAst.builders.literal(n);if(typeof n=="boolean")return omniAst.builders.literal(n);if(Array.isArray(n))return omniAst.builders.arrayExpression(n.map(r=>y(r,e,i,f,o,s,t)));if(h(n))return Gn(n.$,e,f,o,s);if(A(n))return Dn(n,e,i,f,o,s,t);if(k(n))return Mn(n.$pipe,e,i,f,o,s,t);if($(n))return In(n,e,i,f,o,s,t);if(E(n))return zn(n,e,i,f,o,s,t);if(T(n))return Ln(n,e,i,f,o,s,t);if(t&&typeof n=="object"){let r=n,c=Object.keys(r);for(let l=0;l<c.length;l++){let a=c[l];if(a in t){let p=t[a](r);if(typeof p=="object"&&p!==null&&a in p)throw new Error(`Transform "${a}" returned object with same key \u2014 infinite loop`);return y(p,e,i,f,o,s,t)}}}if(typeof n=="object"){let c=Object.entries(n).map(([l,a])=>omniAst.builders.property(omniAst.builders.identifier(l),y(a,e,i,f,o,s,t)));return omniAst.builders.objectExpression(c)}return omniAst.builders.literal(null)}var V="accessor";function _(n,e){return e?n===e||n.startsWith(e+"."):false}function Gn(n,e,i,f,o){return f?_(n,o)?R(n,e,true):omniAst.builders.callExpression(omniAst.builders.identifier(V),[omniAst.builders.literal(n),omniAst.builders.identifier(e)]):n.includes("[*]")?Wn(n,e,i):R(n,e,i)}function R(n,e,i){let f=G(n);if(f.length===0)return i?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e);let o;if(i){let s=f[0];o=omniAst.builders.identifier(s.value);for(let t=1;t<f.length;t++){let r=f[t];r.type==="key"?o=omniAst.builders.memberExpression(o,omniAst.builders.identifier(r.value),false,true):o=omniAst.builders.memberExpression(o,omniAst.builders.literal(r.value),true,true);}}else {o=omniAst.builders.identifier(e);for(let s of f)s.type==="key"?o=omniAst.builders.memberExpression(o,omniAst.builders.identifier(s.value),false,true):o=omniAst.builders.memberExpression(o,omniAst.builders.literal(s.value),true,true);}return o}function Wn(n,e,i){let f=n.indexOf("[*]"),o=n.slice(0,f),s=n.slice(f+3),t;if(o?t=R(o,e,i):t=i?omniAst.builders.identifier("undefined"):omniAst.builders.identifier(e),!s||s==="")return t;if(s.includes("[*]"))return en(t,s);let r="_i",c=s.startsWith(".")?s.slice(1):s,l=omniAst.builders.identifier(r);if(c){let a=G(c);for(let p of a)p.type==="key"?l=omniAst.builders.memberExpression(l,omniAst.builders.identifier(p.value),false,true):l=omniAst.builders.memberExpression(l,omniAst.builders.literal(p.value),true,true);}return omniAst.builders.callExpression(omniAst.builders.memberExpression(t,omniAst.builders.identifier("map"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(r)],l)])}function en(n,e){let i=e.indexOf("[*]"),f=e.slice(0,i),o=e.slice(i+3),s="_i",t=f.startsWith(".")?f.slice(1):f,r=omniAst.builders.identifier(s);if(t){let l=G(t);for(let a of l)a.type==="key"&&(r=omniAst.builders.memberExpression(r,omniAst.builders.identifier(a.value),false,true));}if(o.includes("[*]")){let l=en(r,o);return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],l)])}let c=o.startsWith(".")?o.slice(1):o;if(c){let l=G(c);for(let a of l)a.type==="key"&&(r=omniAst.builders.memberExpression(r,omniAst.builders.identifier(a.value),false,true));}return omniAst.builders.callExpression(omniAst.builders.memberExpression(n,omniAst.builders.identifier("flatMap"),false,true),[omniAst.builders.arrowFunctionExpression([omniAst.builders.identifier(s)],r)])}function Dn(n,e,i,f,o,s,t){let r;if(typeof n.$if=="string"){let a=n.$if.startsWith("!"),p=a?n.$if.slice(1):n.$if,d;o?_(p,s)?d=R(p,e,true):d=omniAst.builders.callExpression(omniAst.builders.identifier(V),[omniAst.builders.literal(p),omniAst.builders.identifier(e)]):d=R(p,e,f),r=a?omniAst.builders.unaryExpression("!",d):d;}else r=y(n.$if,e,i,f,o,s,t);let c=y(n.then,e,i,f,o,s,t),l=n.else!==void 0?y(n.else,e,i,f,o,s,t):omniAst.builders.identifier("undefined");return omniAst.builders.conditionalExpression(r,c,l)}function In(n,e,i,f,o,s,t){let r=f?omniAst.builders.identifier(n.$fn):omniAst.builders.memberExpression(omniAst.builders.identifier(i),omniAst.builders.identifier(n.$fn),false,false);if(n.args===void 0)return r;let c=n.args.map(l=>typeof l=="function"?omniAst.builders.literal(null):y(l,e,i,f,o,s,t));return omniAst.builders.callExpression(r,c)}function Mn(n,e,i,f,o,s,t){if(n.length===0)return omniAst.builders.identifier("undefined");if(n.length===1)return y(n[0],e,i,f,o,s,t);let r=y(n[0],e,i,f,o,s,t);for(let c=1;c<n.length;c++){let l=y(n[c],e,i,f,o,s,t);r=omniAst.builders.callExpression(l,[r]);}return r}function P(n,e,i,f,o,s,t){if(h(n)){let r=n.$;return o?_(r,s)?R(r,e,true):omniAst.builders.callExpression(omniAst.builders.identifier(V),[omniAst.builders.literal(r),omniAst.builders.identifier(e)]):R(r,e,f)}return y(n,e,i,f,o,s,t)}function zn(n,e,i,f,o,s,t){let r=P(n.left,e,i,f,o,s,t),c=n.right!==void 0?P(n.right,e,i,f,o,s,t):omniAst.builders.literal(null),l=vn[n.op];if(l)return omniAst.builders.binaryExpression(l,r,c);switch(n.op){case "in":return omniAst.builders.callExpression(omniAst.builders.memberExpression(c,omniAst.builders.identifier("includes")),[r]);case "notIn":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(c,omniAst.builders.identifier("includes")),[r]));case "contains":return omniAst.builders.callExpression(omniAst.builders.memberExpression(r,omniAst.builders.identifier("includes"),false,true),[c]);case "notContains":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(r,omniAst.builders.identifier("includes"),false,true),[c]));case "exists":return omniAst.builders.binaryExpression("!=",r,omniAst.builders.literal(null));case "notExists":return omniAst.builders.binaryExpression("==",r,omniAst.builders.literal(null));case "matches":return omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[c]),omniAst.builders.identifier("test")),[r]);case "notMatches":return omniAst.builders.unaryExpression("!",omniAst.builders.callExpression(omniAst.builders.memberExpression(omniAst.builders.newExpression(omniAst.builders.identifier("RegExp"),[c]),omniAst.builders.identifier("test")),[r]));case "startsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(r,omniAst.builders.identifier("startsWith"),false,true),[c]);case "endsWith":return omniAst.builders.callExpression(omniAst.builders.memberExpression(r,omniAst.builders.identifier("endsWith"),false,true),[c]);default:return omniAst.builders.binaryExpression("===",r,c)}}function Ln(n,e,i,f,o,s,t){let{logic:r,conditions:c}=n,l=r==="AND"?"&&":"||";if(c.length===0)return omniAst.builders.literal(r==="AND");if(c.length===1)return y(c[0],e,i,f,o,s,t);let a=y(c[0],e,i,f,o,s,t);for(let p=1;p<c.length;p++){let d=y(c[p],e,i,f,o,s,t);a=omniAst.builders.logicalExpression(l,a,d);}return a}function G(n){let e=[],i=n.length,f=0,o="";for(;f<i;){let s=n[f];if(s===".")o&&(e.push({type:"key",value:o}),o=""),f++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),f++;let t=f;for(;f<i&&n[f]!=="]";)f++;let r=n.slice(t,f);if(f++,r!=="*"){let c=parseInt(r,10);e.push({type:"index",value:isNaN(c)?r:c});}}else o+=s,f++;}return o&&e.push({type:"key",value:o}),e}function tn(n,e=[L]){return omniAst.builders.arrowFunctionExpression(e.map(i=>omniAst.builders.identifier(i)),n)}function D(n,e){let i=new Set;return C(n,i,e),i}function C(n,e,i){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let o of n)C(o,e,i);return}if(h(n))return;if(A(n)){C(n.$if,e,i),C(n.then,e,i),n.else!==void 0&&C(n.else,e,i);return}if(k(n)){for(let o of n.$pipe)C(o,e,i);return}if($(n)){if(e.add(n.$fn),n.args)for(let o of n.args)typeof o!="function"&&C(o,e,i);return}if(E(n)){n.left!==void 0&&typeof n.left=="object"&&C(n.left,e,i),n.right!==void 0&&typeof n.right=="object"&&C(n.right,e,i);return}if(T(n)){for(let o of n.conditions)C(o,e,i);return}if(i){let o=n,s=Object.keys(o);for(let t=0;t<s.length;t++){let r=s[t];if(r in i){let c=i[r](o);if(typeof c=="object"&&c!==null&&r in c)throw new Error(`Transform "${r}" returned object with same key \u2014 infinite loop`);C(c,e,i);return}}}let f=n;for(let o of Object.keys(f))C(f[o],e,i);}function I(n){let e=new Set;for(let i of n){let f=i.indexOf("."),o=i.indexOf("["),s=i.length;f!==-1&&(s=Math.min(s,f)),o!==-1&&(s=Math.min(s,o));let t=i.slice(0,s);t&&e.add(t);}return e}function _n(n){return JSON.stringify(n)}function qn(n,e,i,f,o,s){let t=W(n,{noPrefixes:true,useAccessor:f,lexicalPrefix:o,transforms:s}),r=omniAst.generate(t),c="";f?o&&(c=`const{${o}}=data??{};`):e.size>0&&(c=`const{${[...e].join(",")}}=data??{};`);let l=f?new Set([...i,"accessor"]):i,a=l.size>0?`const{${[...l].join(",")}}=scope;`:"";return a?`(function(scope){${a}return function(data){${c}return ${r}}})`:`(function(){return function(data){${c}return ${r}}})`}function q(n,e={}){let{scope:i={},returnCode:f=false,useAccessor:o=false,lexicalPrefix:s,transforms:t}=e,r=w(n,t),c=I(r),l=D(n,t),a=_n(n),p=qn(n,c,l,o,s,t);if(f)return {code:p,deps:r,hash:a,dataRoots:[...c],scopeFns:[...l]};let d;try{d=new Function(`return ${p}`)()(i);}catch(g){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${g instanceof Error?g.message:String(g)}`)}return {fn:d,deps:r,hash:a}}function on(n,e,i={}){let{fn:f}=q(n,i);return f(e)}var Ee="0.1.1";exports.ExpressionCache=v;exports.VERSION=Ee;exports.assertValid=wn;exports.builders=Z;exports.cache=Y;exports.cached=Sn;exports.clearPathCache=dn;exports.compile=N;exports.compileAST=q;exports.compilePath=O;exports.dslToAST=W;exports.evaluate=kn;exports.evaluateAST=on;exports.extractDataRoots=I;exports.extractDeps=w;exports.extractScopeFns=D;exports.get=pn;exports.getPathCacheSize=gn;exports.hasDeps=yn;exports.hasWildcard=B;exports.isCondition=E;exports.isConditionExpr=fn;exports.isConditionGroup=T;exports.isConditional=A;exports.isFn=$;exports.isLiteral=M;exports.isPipe=k;exports.isPure=mn;exports.isRef=h;exports.isValid=Rn;exports.normalizePath=j;exports.validate=z;exports.wrapInFunction=tn;
|
package/dist/index.d.cts
CHANGED
|
@@ -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
|
*/
|
|
@@ -110,6 +133,14 @@ interface ValidationResult {
|
|
|
110
133
|
* @example { add, subtract, multiply, filter, map, sum }
|
|
111
134
|
*/
|
|
112
135
|
type Scope = Record<string, (...args: any[]) => any>;
|
|
136
|
+
/**
|
|
137
|
+
* Options for compilation
|
|
138
|
+
*/
|
|
139
|
+
/**
|
|
140
|
+
* Transform function for custom expression types.
|
|
141
|
+
* Receives the raw node and must return a valid Expression.
|
|
142
|
+
*/
|
|
143
|
+
type TransformFn = (node: Record<string, unknown>) => Expression;
|
|
113
144
|
/**
|
|
114
145
|
* Options for compilation
|
|
115
146
|
*/
|
|
@@ -125,6 +156,13 @@ interface CompileOptions<T = unknown> {
|
|
|
125
156
|
* compile(expr, { accessor: (path, ctx) => ctx.get(path) })
|
|
126
157
|
*/
|
|
127
158
|
accessor?: AccessorFn<T>;
|
|
159
|
+
/**
|
|
160
|
+
* Custom expression transforms.
|
|
161
|
+
* Key = marker (e.g. "$query"), value = transform function.
|
|
162
|
+
* The walker calls the transform before treating as literal.
|
|
163
|
+
* The returned Expression is compiled recursively.
|
|
164
|
+
*/
|
|
165
|
+
transforms?: Record<string, TransformFn>;
|
|
128
166
|
}
|
|
129
167
|
/**
|
|
130
168
|
* Check if value is a reference expression
|
|
@@ -143,15 +181,14 @@ declare const isFn: (v: unknown) => v is FnExpr;
|
|
|
143
181
|
*/
|
|
144
182
|
declare const isPipe: (v: unknown) => v is PipeExpr;
|
|
145
183
|
/**
|
|
146
|
-
* Check if value is a condition
|
|
184
|
+
* Check if value is a condition expression
|
|
147
185
|
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
* properties but with non-condition operators like "set".
|
|
186
|
+
* Verifies `op` is a valid condition operator to distinguish from
|
|
187
|
+
* effect objects that also have `left` and `op` (e.g. op: "set").
|
|
151
188
|
*/
|
|
152
189
|
declare const isCondition: (v: unknown) => v is Condition;
|
|
153
190
|
/**
|
|
154
|
-
* Check if value is a condition group
|
|
191
|
+
* Check if value is a condition group
|
|
155
192
|
*/
|
|
156
193
|
declare const isConditionGroup: (v: unknown) => v is ConditionGroup;
|
|
157
194
|
/**
|
|
@@ -270,7 +307,7 @@ declare function getPathCacheSize(): number;
|
|
|
270
307
|
* @example { "$": "user.age" } → ["user.age"]
|
|
271
308
|
* @example { "$if": "$isVip", "then": { "$": "price.vip" } } → ["$isVip", "price.vip"]
|
|
272
309
|
*/
|
|
273
|
-
declare function extractDeps(expr: Expression): string[];
|
|
310
|
+
declare function extractDeps(expr: Expression, transforms?: Record<string, TransformFn>): string[];
|
|
274
311
|
/**
|
|
275
312
|
* Check if expression has dependencies
|
|
276
313
|
*/
|
|
@@ -452,16 +489,36 @@ declare function $pipe(...steps: Expression[]): PipeExpr;
|
|
|
452
489
|
* Alias for $pipe (pipe builder)
|
|
453
490
|
*/
|
|
454
491
|
declare const pipe: typeof $pipe;
|
|
492
|
+
/**
|
|
493
|
+
* Create a condition expression.
|
|
494
|
+
*
|
|
495
|
+
* @param left - Left side (any expression)
|
|
496
|
+
* @param op - Condition operator
|
|
497
|
+
* @param right - Right side (any expression, optional for exists/notExists)
|
|
498
|
+
* @returns Condition
|
|
499
|
+
*
|
|
500
|
+
* @example
|
|
501
|
+
* $cond($("age"), "gte", 18)
|
|
502
|
+
* $cond($fn("getScore", [$("user")]), "gt", 100)
|
|
503
|
+
* $cond($("email"), "exists")
|
|
504
|
+
*/
|
|
505
|
+
declare function $cond(left: Expression, op: ConditionOp, right?: Expression): Condition;
|
|
506
|
+
/**
|
|
507
|
+
* Alias for $cond (condition builder)
|
|
508
|
+
*/
|
|
509
|
+
declare const cond: typeof $cond;
|
|
455
510
|
|
|
456
511
|
declare const builders_$: typeof $;
|
|
512
|
+
declare const builders_$cond: typeof $cond;
|
|
457
513
|
declare const builders_$fn: typeof $fn;
|
|
458
514
|
declare const builders_$if: typeof $if;
|
|
459
515
|
declare const builders_$pipe: typeof $pipe;
|
|
516
|
+
declare const builders_cond: typeof cond;
|
|
460
517
|
declare const builders_fn: typeof fn;
|
|
461
518
|
declare const builders_pipe: typeof pipe;
|
|
462
519
|
declare const builders_ref: typeof ref;
|
|
463
520
|
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 };
|
|
521
|
+
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
522
|
}
|
|
466
523
|
|
|
467
524
|
/**
|
|
@@ -505,6 +562,11 @@ interface TransformOptions {
|
|
|
505
562
|
* - `lexicalPrefix: "params"` → `params?.foo` instead of `accessor("params.foo", data)`
|
|
506
563
|
*/
|
|
507
564
|
lexicalPrefix?: string;
|
|
565
|
+
/**
|
|
566
|
+
* Custom expression transforms.
|
|
567
|
+
* Key = marker (e.g. "$query"), value = transform function.
|
|
568
|
+
*/
|
|
569
|
+
transforms?: Record<string, TransformFn>;
|
|
508
570
|
}
|
|
509
571
|
/**
|
|
510
572
|
* Transform DSL expression to AST node
|
|
@@ -541,6 +603,7 @@ declare function wrapInFunction(bodyAst: ASTNode, params?: string[]): ASTNode;
|
|
|
541
603
|
* Extract all function names used from scope in an expression
|
|
542
604
|
*
|
|
543
605
|
* @param expr - DSL expression to analyze
|
|
606
|
+
* @param transforms - Optional custom transforms (to resolve custom nodes before collecting)
|
|
544
607
|
* @returns Set of function names used
|
|
545
608
|
*
|
|
546
609
|
* @example
|
|
@@ -558,7 +621,7 @@ declare function wrapInFunction(bodyAst: ASTNode, params?: string[]): ASTNode;
|
|
|
558
621
|
* // Set { "filter", "sum" }
|
|
559
622
|
* ```
|
|
560
623
|
*/
|
|
561
|
-
declare function extractScopeFns(expr: Expression): Set<string>;
|
|
624
|
+
declare function extractScopeFns(expr: Expression, transforms?: Record<string, TransformFn>): Set<string>;
|
|
562
625
|
/**
|
|
563
626
|
* Extract root-level data dependencies from paths
|
|
564
627
|
*
|
|
@@ -600,6 +663,11 @@ interface CompileASTOptions {
|
|
|
600
663
|
* - `lexicalPrefix: "params"` → `params?.foo` instead of `accessor("params.foo", data)`
|
|
601
664
|
*/
|
|
602
665
|
lexicalPrefix?: string;
|
|
666
|
+
/**
|
|
667
|
+
* Custom expression transforms.
|
|
668
|
+
* Key = marker (e.g. "$query"), value = transform function.
|
|
669
|
+
*/
|
|
670
|
+
transforms?: Record<string, TransformFn>;
|
|
603
671
|
}
|
|
604
672
|
/** Result when returnCode is true */
|
|
605
673
|
interface CompileASTCodeResult {
|
|
@@ -684,4 +752,4 @@ declare function evaluateAST<T = unknown, R = unknown>(expr: Expression, data: T
|
|
|
684
752
|
*/
|
|
685
753
|
declare const VERSION = "0.1.1";
|
|
686
754
|
|
|
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 };
|
|
755
|
+
export { type AccessorFn, type CallbackFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type Condition, type ConditionExpr, type ConditionGroup, type ConditionOp, type ConditionalExpr, type Expression, ExpressionCache, type FnArg, type FnExpr, type Literal, type PathGetter, type PipeExpr, type RefExpr, type Scope, type TransformFn, type TransformOptions, VERSION, type ValidateOptions, type ValidationResult, assertValid, builders, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalizePath, validate, wrapInFunction };
|
package/dist/index.d.ts
CHANGED
|
@@ -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
|
*/
|
|
@@ -110,6 +133,14 @@ interface ValidationResult {
|
|
|
110
133
|
* @example { add, subtract, multiply, filter, map, sum }
|
|
111
134
|
*/
|
|
112
135
|
type Scope = Record<string, (...args: any[]) => any>;
|
|
136
|
+
/**
|
|
137
|
+
* Options for compilation
|
|
138
|
+
*/
|
|
139
|
+
/**
|
|
140
|
+
* Transform function for custom expression types.
|
|
141
|
+
* Receives the raw node and must return a valid Expression.
|
|
142
|
+
*/
|
|
143
|
+
type TransformFn = (node: Record<string, unknown>) => Expression;
|
|
113
144
|
/**
|
|
114
145
|
* Options for compilation
|
|
115
146
|
*/
|
|
@@ -125,6 +156,13 @@ interface CompileOptions<T = unknown> {
|
|
|
125
156
|
* compile(expr, { accessor: (path, ctx) => ctx.get(path) })
|
|
126
157
|
*/
|
|
127
158
|
accessor?: AccessorFn<T>;
|
|
159
|
+
/**
|
|
160
|
+
* Custom expression transforms.
|
|
161
|
+
* Key = marker (e.g. "$query"), value = transform function.
|
|
162
|
+
* The walker calls the transform before treating as literal.
|
|
163
|
+
* The returned Expression is compiled recursively.
|
|
164
|
+
*/
|
|
165
|
+
transforms?: Record<string, TransformFn>;
|
|
128
166
|
}
|
|
129
167
|
/**
|
|
130
168
|
* Check if value is a reference expression
|
|
@@ -143,15 +181,14 @@ declare const isFn: (v: unknown) => v is FnExpr;
|
|
|
143
181
|
*/
|
|
144
182
|
declare const isPipe: (v: unknown) => v is PipeExpr;
|
|
145
183
|
/**
|
|
146
|
-
* Check if value is a condition
|
|
184
|
+
* Check if value is a condition expression
|
|
147
185
|
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
* properties but with non-condition operators like "set".
|
|
186
|
+
* Verifies `op` is a valid condition operator to distinguish from
|
|
187
|
+
* effect objects that also have `left` and `op` (e.g. op: "set").
|
|
151
188
|
*/
|
|
152
189
|
declare const isCondition: (v: unknown) => v is Condition;
|
|
153
190
|
/**
|
|
154
|
-
* Check if value is a condition group
|
|
191
|
+
* Check if value is a condition group
|
|
155
192
|
*/
|
|
156
193
|
declare const isConditionGroup: (v: unknown) => v is ConditionGroup;
|
|
157
194
|
/**
|
|
@@ -270,7 +307,7 @@ declare function getPathCacheSize(): number;
|
|
|
270
307
|
* @example { "$": "user.age" } → ["user.age"]
|
|
271
308
|
* @example { "$if": "$isVip", "then": { "$": "price.vip" } } → ["$isVip", "price.vip"]
|
|
272
309
|
*/
|
|
273
|
-
declare function extractDeps(expr: Expression): string[];
|
|
310
|
+
declare function extractDeps(expr: Expression, transforms?: Record<string, TransformFn>): string[];
|
|
274
311
|
/**
|
|
275
312
|
* Check if expression has dependencies
|
|
276
313
|
*/
|
|
@@ -452,16 +489,36 @@ declare function $pipe(...steps: Expression[]): PipeExpr;
|
|
|
452
489
|
* Alias for $pipe (pipe builder)
|
|
453
490
|
*/
|
|
454
491
|
declare const pipe: typeof $pipe;
|
|
492
|
+
/**
|
|
493
|
+
* Create a condition expression.
|
|
494
|
+
*
|
|
495
|
+
* @param left - Left side (any expression)
|
|
496
|
+
* @param op - Condition operator
|
|
497
|
+
* @param right - Right side (any expression, optional for exists/notExists)
|
|
498
|
+
* @returns Condition
|
|
499
|
+
*
|
|
500
|
+
* @example
|
|
501
|
+
* $cond($("age"), "gte", 18)
|
|
502
|
+
* $cond($fn("getScore", [$("user")]), "gt", 100)
|
|
503
|
+
* $cond($("email"), "exists")
|
|
504
|
+
*/
|
|
505
|
+
declare function $cond(left: Expression, op: ConditionOp, right?: Expression): Condition;
|
|
506
|
+
/**
|
|
507
|
+
* Alias for $cond (condition builder)
|
|
508
|
+
*/
|
|
509
|
+
declare const cond: typeof $cond;
|
|
455
510
|
|
|
456
511
|
declare const builders_$: typeof $;
|
|
512
|
+
declare const builders_$cond: typeof $cond;
|
|
457
513
|
declare const builders_$fn: typeof $fn;
|
|
458
514
|
declare const builders_$if: typeof $if;
|
|
459
515
|
declare const builders_$pipe: typeof $pipe;
|
|
516
|
+
declare const builders_cond: typeof cond;
|
|
460
517
|
declare const builders_fn: typeof fn;
|
|
461
518
|
declare const builders_pipe: typeof pipe;
|
|
462
519
|
declare const builders_ref: typeof ref;
|
|
463
520
|
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 };
|
|
521
|
+
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
522
|
}
|
|
466
523
|
|
|
467
524
|
/**
|
|
@@ -505,6 +562,11 @@ interface TransformOptions {
|
|
|
505
562
|
* - `lexicalPrefix: "params"` → `params?.foo` instead of `accessor("params.foo", data)`
|
|
506
563
|
*/
|
|
507
564
|
lexicalPrefix?: string;
|
|
565
|
+
/**
|
|
566
|
+
* Custom expression transforms.
|
|
567
|
+
* Key = marker (e.g. "$query"), value = transform function.
|
|
568
|
+
*/
|
|
569
|
+
transforms?: Record<string, TransformFn>;
|
|
508
570
|
}
|
|
509
571
|
/**
|
|
510
572
|
* Transform DSL expression to AST node
|
|
@@ -541,6 +603,7 @@ declare function wrapInFunction(bodyAst: ASTNode, params?: string[]): ASTNode;
|
|
|
541
603
|
* Extract all function names used from scope in an expression
|
|
542
604
|
*
|
|
543
605
|
* @param expr - DSL expression to analyze
|
|
606
|
+
* @param transforms - Optional custom transforms (to resolve custom nodes before collecting)
|
|
544
607
|
* @returns Set of function names used
|
|
545
608
|
*
|
|
546
609
|
* @example
|
|
@@ -558,7 +621,7 @@ declare function wrapInFunction(bodyAst: ASTNode, params?: string[]): ASTNode;
|
|
|
558
621
|
* // Set { "filter", "sum" }
|
|
559
622
|
* ```
|
|
560
623
|
*/
|
|
561
|
-
declare function extractScopeFns(expr: Expression): Set<string>;
|
|
624
|
+
declare function extractScopeFns(expr: Expression, transforms?: Record<string, TransformFn>): Set<string>;
|
|
562
625
|
/**
|
|
563
626
|
* Extract root-level data dependencies from paths
|
|
564
627
|
*
|
|
@@ -600,6 +663,11 @@ interface CompileASTOptions {
|
|
|
600
663
|
* - `lexicalPrefix: "params"` → `params?.foo` instead of `accessor("params.foo", data)`
|
|
601
664
|
*/
|
|
602
665
|
lexicalPrefix?: string;
|
|
666
|
+
/**
|
|
667
|
+
* Custom expression transforms.
|
|
668
|
+
* Key = marker (e.g. "$query"), value = transform function.
|
|
669
|
+
*/
|
|
670
|
+
transforms?: Record<string, TransformFn>;
|
|
603
671
|
}
|
|
604
672
|
/** Result when returnCode is true */
|
|
605
673
|
interface CompileASTCodeResult {
|
|
@@ -684,4 +752,4 @@ declare function evaluateAST<T = unknown, R = unknown>(expr: Expression, data: T
|
|
|
684
752
|
*/
|
|
685
753
|
declare const VERSION = "0.1.1";
|
|
686
754
|
|
|
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 };
|
|
755
|
+
export { type AccessorFn, type CallbackFn, type CompileASTCodeResult, type CompileASTOptions, type CompileOptions, type CompiledExpression, type CompiledFn, type Condition, type ConditionExpr, type ConditionGroup, type ConditionOp, type ConditionalExpr, type Expression, ExpressionCache, type FnArg, type FnExpr, type Literal, type PathGetter, type PipeExpr, type RefExpr, type Scope, type TransformFn, type TransformOptions, VERSION, type ValidateOptions, type ValidationResult, assertValid, builders, cache, cached, clearPathCache, compile, compileAST, compilePath, dslToAST, evaluate, evaluateAST, extractDataRoots, extractDeps, extractScopeFns, get, getPathCacheSize, hasDeps, hasWildcard, isCondition, isConditionExpr, isConditionGroup, isConditional, isFn, isLiteral, isPipe, isPure, isRef, isValid, normalizePath, validate, wrapInFunction };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {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 rn=Object.defineProperty;var sn=(n,e)=>{for(var i in e)rn(n,i,{get:e[i],enumerable:true});};var h=n=>n!==null&&typeof n=="object"&&"$"in n&&typeof n.$=="string"&&Object.keys(n).length===1,A=n=>n!==null&&typeof n=="object"&&"$if"in n&&"then"in n,$=n=>n!==null&&typeof n=="object"&&"$fn"in n&&typeof n.$fn=="string",k=n=>n!==null&&typeof n=="object"&&"$pipe"in n&&Array.isArray(n.$pipe),F=new Set(["eq","neq","gt","gte","lt","lte","in","notIn","contains","notContains","exists","notExists","matches","notMatches","startsWith","endsWith"]),E=n=>n!==null&&typeof n=="object"&&"left"in n&&"op"in n&&F.has(n.op)&&!("$"in n)&&!("$if"in n)&&!("$fn"in n),T=n=>n!==null&&typeof n=="object"&&"logic"in n&&"conditions"in n,fn=n=>E(n)||T(n),M=n=>{if(n===null)return true;let e=typeof n;if(e==="string"||e==="number"||e==="boolean"||Array.isArray(n))return true;if(e==="object"&&n!==null){let i=n,f="left"in i&&"op"in i&&F.has(i.op);return !("$"in i)&&!("$if"in i)&&!("$fn"in i)&&!("$pipe"in i)&&!f&&!("logic"in i)}return false};var x=new Map;function J(n){let e=[],i=n.length,f=0,o="";for(;f<i;){let s=n[f];if(s===".")o&&(e.push({type:"key",value:o}),o=""),f++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),f++;let t=f;for(;f<i&&n[f]!=="]";)f++;let r=n.slice(t,f);if(f++,r==="*")e.push({type:"wildcard",value:"*"});else {let c=parseInt(r,10);e.push({type:"index",value:isNaN(c)?r:c});}}else o+=s,f++;}return o&&e.push({type:"key",value:o}),e}function B(n){return n.includes("[*]")}function O(n){let e=x.get(n);return e||(e=B(n)?un(n):cn(n),x.set(n,e),e)}function cn(n){if(!n.includes(".")&&!n.includes("["))return o=>o?.[n];let e=J(n),i=e.length;if(i===2){let[o,s]=e,t=o.value,r=s.value;return c=>c?.[t]?.[r]}if(i===3){let[o,s,t]=e,r=o.value,c=s.value,l=t.value;return a=>a?.[r]?.[c]?.[l]}let f=e.map(o=>o.value);return o=>{let s=o;for(let t=0;t<i&&s!=null;t++)s=s[f[t]];return s}}function un(n){let e=J(n),i=[];for(let f=0;f<e.length;f++)e[f].type==="wildcard"&&i.push(f);return i.length===1?ln(e,i[0]):an(e,i)}function ln(n,e){let i=n.slice(0,e).map(t=>t.value),f=n.slice(e+1).map(t=>t.value),o=i.length,s=f.length;if(s===0){if(o===1){let t=i[0];return r=>r?.[t]}return t=>{let r=t;for(let c=0;c<o&&r!=null;c++)r=r[i[c]];return r}}if(s===1){let t=f[0];if(o===1){let r=i[0];return c=>{let l=c?.[r];if(Array.isArray(l))return l.map(a=>a?.[t])}}return r=>{let c=r;for(let l=0;l<o&&c!=null;l++)c=c[i[l]];if(Array.isArray(c))return c.map(l=>l?.[t])}}return t=>{let r=t;for(let c=0;c<o&&r!=null;c++)r=r[i[c]];if(Array.isArray(r))return r.map(c=>{let l=c;for(let a=0;a<s&&l!=null;a++)l=l[f[a]];return l})}}function an(n,e){let i=[],f=0;for(let s=0;s<e.length;s++){let t=e[s],r=s===e.length-1,c=n.slice(f,t).map(l=>l.value);c.length>0&&i.push({type:"access",keys:c}),i.push({type:r?"map":"flatMap",keys:[]}),f=t+1;}let o=n.slice(f).map(s=>s.value);return s=>{let t=s;for(let r of i){if(t==null)return;if(r.type==="access")for(let c of r.keys){if(t==null)return;t=t[c];}else if(r.type==="flatMap"){if(!Array.isArray(t))return;t=t.flatMap(c=>{let l=c;return Array.isArray(l)?l:[l]});}else if(r.type==="map"){if(!Array.isArray(t))return;o.length>0&&(t=t.map(c=>{let l=c;for(let a of o){if(l==null)return;l=l[a];}return l}));}}return t}}function pn(n,e){return O(e)(n)}function j(n){let e=n.indexOf("[*]");return e===-1?n:n.slice(0,e)}function dn(){x.clear();}function gn(){return x.size}function w(n,e){let i=new Set;return b(n,i,e),Array.from(i)}function b(n,e,i){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let s=0;s<n.length;s++)b(n[s],e,i);return}if(h(n)){e.add(j(n.$));return}if(A(n)){if(typeof n.$if=="string"){let s=n.$if.startsWith("!")?n.$if.slice(1):n.$if;e.add(j(s));}else b(n.$if,e,i);b(n.then,e,i),n.else!==void 0&&b(n.else,e,i);return}if(k(n)){for(let s=0;s<n.$pipe.length;s++)b(n.$pipe[s],e,i);return}if($(n)){if(n.args)for(let s=0;s<n.args.length;s++){let t=n.args[s];typeof t!="function"&&b(t,e,i);}return}if(E(n)){b(n.left,e,i),n.right!==void 0&&b(n.right,e,i);return}if(T(n)){for(let s=0;s<n.conditions.length;s++)b(n.conditions[s],e,i);return}if(i){let s=n,t=Object.keys(s);for(let r=0;r<t.length;r++){let c=t[r];if(c in i){let l=i[c](s);if(typeof l=="object"&&l!==null&&c in l)throw new Error(`Transform "${c}" returned object with same key \u2014 infinite loop`);b(l,e,i);return}}}let f=n,o=Object.keys(f);for(let s=0;s<o.length;s++)b(f[o[s]],e,i);}function yn(n){return w(n).length>0}function mn(n){return w(n).length===0}function hn(n){return JSON.stringify(n)}function N(n,e={}){let i=e.scope??{},f=e.accessor,o=e.transforms,s=m(n,i,f,o),t=w(n,o),r=hn(n);return {fn:s,deps:t,hash:r}}function m(n,e,i,f){if(n===null)return ()=>null;if(typeof n!="object")return ()=>n;if(Array.isArray(n)){let o=n.map(s=>m(s,e,i,f));return s=>o.map(t=>t(s))}if(h(n))return En(n,i);if(A(n))return Tn(n,e,i,f);if(k(n))return bn(n,e,i,f);if($(n))return Cn(n,e,i,f);if(E(n))return An(n,e,i,f);if(T(n))return $n(n,e,i,f);if(f){let o=n,s=Object.keys(o);for(let t=0;t<s.length;t++){let r=s[t];if(r in f){let c=f[r](o);if(typeof c=="object"&&c!==null&&r in c)throw new Error(`Transform "${r}" returned object with same key \u2014 infinite loop`);return m(c,e,i,f)}}}if(M(n)){let o=n,s=Object.keys(o),t=s.map(r=>m(o[r],e,i,f));return r=>{let c={};for(let l=0;l<s.length;l++)c[s[l]]=t[l](r);return c}}return ()=>n}function K(n,e){return e?i=>e(n,i):O(n)}function En(n,e){return K(n.$,e)}function Tn(n,e,i,f){let o;if(typeof n.$if=="string"){let r=n.$if.startsWith("!")?n.$if.slice(1):n.$if,c=K(r,i);o=n.$if.startsWith("!")?a=>!c(a):a=>!!c(a);}else {let r=m(n.$if,e,i,f);o=c=>!!r(c);}let s=m(n.then,e,i,f),t=n.else!==void 0?m(n.else,e,i,f):()=>{};return r=>o(r)?s(r):t(r)}function bn(n,e,i,f){let o=n.$pipe;if(o.length===0)return ()=>{};if(o.length===1)return m(o[0],e,i,f);let s=m(o[0],e,i,f),t=o.slice(1).map(c=>m(c,e,i,f)),r=t.length;if(r===1){let[c]=t;return l=>{let a=s(l),p=c(l);return typeof p=="function"?p(a):p}}if(r===2){let[c,l]=t;return a=>{let p=s(a),d=c(a);return p=typeof d=="function"?d(p):d,d=l(a),typeof d=="function"?d(p):d}}if(r===3){let[c,l,a]=t;return p=>{let d=s(p),g=c(p);return d=typeof g=="function"?g(d):g,g=l(p),d=typeof g=="function"?g(d):g,g=a(p),typeof g=="function"?g(d):g}}return c=>{let l=s(c);for(let a=0;a<r;a++){let p=t[a](c);l=typeof p=="function"?p(l):p;}return l}}function Cn(n,e,i,f){let o=n.$fn,s=n.args;if(s===void 0)return ()=>{let c=e[o];if(!c)throw new Error(`Function not found in scope: ${o}`);return c};let t=s.map(c=>typeof c=="function"?()=>c:m(c,e,i,f)),r=t.length;if(r===0)return c=>{let l=e[o];if(!l)throw new Error(`Function not found in scope: ${o}`);return l()};if(r===1){let[c]=t;return l=>{let a=e[o];if(!a)throw new Error(`Function not found in scope: ${o}`);return a(c(l))}}if(r===2){let[c,l]=t;return a=>{let p=e[o];if(!p)throw new Error(`Function not found in scope: ${o}`);return p(c(a),l(a))}}if(r===3){let[c,l,a]=t;return p=>{let d=e[o];if(!d)throw new Error(`Function not found in scope: ${o}`);return d(c(p),l(p),a(p))}}return c=>{let l=e[o];if(!l)throw new Error(`Function not found in scope: ${o}`);return l(...t.map(a=>a(c)))}}function An(n,e,i,f){let o=m(n.left,e,i,f),s=n.right!==void 0?m(n.right,e,i,f):()=>{};switch(n.op){case "eq":return t=>o(t)===s(t);case "neq":return t=>o(t)!==s(t);case "gt":return t=>o(t)>s(t);case "gte":return t=>o(t)>=s(t);case "lt":return t=>o(t)<s(t);case "lte":return t=>o(t)<=s(t);case "in":return t=>{let r=s(t);return Array.isArray(r)&&r.includes(o(t))};case "notIn":return t=>{let r=s(t);return !Array.isArray(r)||!r.includes(o(t))};case "contains":return t=>{let r=o(t);return Array.isArray(r)&&r.includes(s(t))};case "notContains":return t=>{let r=o(t);return !Array.isArray(r)||!r.includes(s(t))};case "exists":return t=>o(t)!==void 0;case "notExists":return t=>o(t)===void 0;case "matches":return t=>{let r=o(t),c=s(t);return typeof r!="string"||typeof c!="string"?false:new RegExp(c).test(r)};case "notMatches":return t=>{let r=o(t),c=s(t);return typeof r!="string"||typeof c!="string"?true:!new RegExp(c).test(r)};case "startsWith":return t=>{let r=o(t),c=s(t);return typeof r=="string"&&typeof c=="string"&&r.startsWith(c)};case "endsWith":return t=>{let r=o(t),c=s(t);return typeof r=="string"&&typeof c=="string"&&r.endsWith(c)}}}function $n(n,e,i,f){let o=n.conditions.map(t=>m(t,e,i,f)),s=o.length;if(s===1)return t=>!!o[0](t);if(s===2){let[t,r]=o;return n.logic==="AND"?c=>!!t(c)&&!!r(c):c=>!!t(c)||!!r(c)}if(s===3){let[t,r,c]=o;return n.logic==="AND"?l=>!!t(l)&&!!r(l)&&!!c(l):l=>!!t(l)||!!r(l)||!!c(l)}return n.logic==="AND"?t=>{for(let r=0;r<s;r++)if(!o[r](t))return false;return true}:t=>{for(let r=0;r<s;r++)if(o[r](t))return true;return false}}function kn(n,e,i={}){return N(n,i).fn(e)}var v=class{constructor(e=1e3){this.cache=new Map,this._maxSize=e;}get(e,i={}){let f=JSON.stringify(e),o=this.cache.get(f);if(o)return this.cache.delete(f),this.cache.set(f,o),o;let s=N(e,i);if(this.cache.size>=this._maxSize){let t=this.cache.keys().next().value;t&&this.cache.delete(t);}return this.cache.set(f,s),s}has(e){return this.cache.has(JSON.stringify(e))}delete(e){return this.cache.delete(JSON.stringify(e))}clear(){this.cache.clear();}get size(){return this.cache.size}get maxSize(){return this._maxSize}set maxSize(e){for(this._maxSize=e;this.cache.size>this._maxSize;){let i=this.cache.keys().next().value;i&&this.cache.delete(i);}}},Y=new v;function Sn(n,e={}){return Y.get(n,e)}function z(n,e="root",i={}){let f=[];return S(n,e,f,i),{valid:f.length===0,errors:f}}function S(n,e,i,f){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let t=0;t<n.length;t++)S(n[t],`${e}[${t}]`,i,f);return}if(h(n)){(!n.$||typeof n.$!="string")&&i.push(`${e}: invalid reference, $ must be non-empty string`);return}if(A(n)){typeof n.$if=="string"?(n.$if.startsWith("!")?n.$if.slice(1):n.$if)||i.push(`${e}.$if: empty path in string shorthand`):S(n.$if,`${e}.$if`,i,f),S(n.then,`${e}.then`,i,f),n.else!==void 0&&S(n.else,`${e}.else`,i,f);return}if(k(n)){if(!Array.isArray(n.$pipe)){i.push(`${e}.$pipe: must be an array`);return}if(n.$pipe.length===0){i.push(`${e}.$pipe: must have at least one element`);return}for(let t=0;t<n.$pipe.length;t++)S(n.$pipe[t],`${e}.$pipe[${t}]`,i,f);return}if($(n)){if(!n.$fn||typeof n.$fn!="string"){i.push(`${e}: invalid function, $fn must be non-empty string`);return}if(f.scope&&!(n.$fn in f.scope)&&i.push(`${e}: function "${n.$fn}" not found in scope`),n.args!==void 0)if(!Array.isArray(n.args))i.push(`${e}.args: must be an array`);else for(let t=0;t<n.args.length;t++){let r=n.args[t];typeof r!="function"&&S(r,`${e}.args[${t}]`,i,f);}return}if(E(n)){F.has(n.op)||i.push(`${e}: invalid operator "${n.op}"`),S(n.left,`${e}.left`,i,f),n.right!==void 0&&S(n.right,`${e}.right`,i,f);return}if(T(n)){if(n.logic!=="AND"&&n.logic!=="OR"&&i.push(`${e}: invalid logic "${n.logic}", must be "AND" or "OR"`),!Array.isArray(n.conditions)){i.push(`${e}.conditions: must be an array`);return}for(let t=0;t<n.conditions.length;t++)S(n.conditions[t],`${e}.conditions[${t}]`,i,f);return}let o=n,s=Object.keys(o);for(let t=0;t<s.length;t++){let r=s[t];S(o[r],`${e}.${r}`,i,f);}}function wn(n,e={}){let i=z(n,"root",e);if(!i.valid)throw new Error(`Invalid expression: ${i.errors.join("; ")}`)}function Rn(n,e={}){return z(n,"root",e).valid}var Z={};sn(Z,{$:()=>H,$cond:()=>X,$fn:()=>Q,$if:()=>On,$pipe:()=>U,cond:()=>Nn,fn:()=>xn,pipe:()=>jn,ref:()=>Fn});function H(n){return {$:n}}var Fn=H;function Q(n,e){return e===void 0||e.length===0?{$fn:n}:{$fn:n,args:e}}var xn=Q;function On(n,e,i){return i===void 0?{$if:n,then:e}:{$if:n,then:e,else:i}}function U(...n){return {$pipe:n}}var jn=U;function X(n,e,i){return i===void 0?{left:n,op:e}:{left:n,op:e,right:i}}var Nn=X;var L="data",nn="scope",vn={eq:"===",neq:"!==",gt:">",gte:">=",lt:"<",lte:"<="};function W(n,e={}){let{dataParam:i=L,scopeParam:f=nn,noPrefixes:o=false,useAccessor:s=false,lexicalPrefix:t,transforms:r}=e;return y(n,i,f,o,s,t,r)}function y(n,e,i,f,o,s,t){if(n===null)return builders.literal(null);if(typeof n=="string")return builders.literal(n);if(typeof n=="number")return builders.literal(n);if(typeof n=="boolean")return builders.literal(n);if(Array.isArray(n))return builders.arrayExpression(n.map(r=>y(r,e,i,f,o,s,t)));if(h(n))return Gn(n.$,e,f,o,s);if(A(n))return Dn(n,e,i,f,o,s,t);if(k(n))return Mn(n.$pipe,e,i,f,o,s,t);if($(n))return In(n,e,i,f,o,s,t);if(E(n))return zn(n,e,i,f,o,s,t);if(T(n))return Ln(n,e,i,f,o,s,t);if(t&&typeof n=="object"){let r=n,c=Object.keys(r);for(let l=0;l<c.length;l++){let a=c[l];if(a in t){let p=t[a](r);if(typeof p=="object"&&p!==null&&a in p)throw new Error(`Transform "${a}" returned object with same key \u2014 infinite loop`);return y(p,e,i,f,o,s,t)}}}if(typeof n=="object"){let c=Object.entries(n).map(([l,a])=>builders.property(builders.identifier(l),y(a,e,i,f,o,s,t)));return builders.objectExpression(c)}return builders.literal(null)}var V="accessor";function _(n,e){return e?n===e||n.startsWith(e+"."):false}function Gn(n,e,i,f,o){return f?_(n,o)?R(n,e,true):builders.callExpression(builders.identifier(V),[builders.literal(n),builders.identifier(e)]):n.includes("[*]")?Wn(n,e,i):R(n,e,i)}function R(n,e,i){let f=G(n);if(f.length===0)return i?builders.identifier("undefined"):builders.identifier(e);let o;if(i){let s=f[0];o=builders.identifier(s.value);for(let t=1;t<f.length;t++){let r=f[t];r.type==="key"?o=builders.memberExpression(o,builders.identifier(r.value),false,true):o=builders.memberExpression(o,builders.literal(r.value),true,true);}}else {o=builders.identifier(e);for(let s of f)s.type==="key"?o=builders.memberExpression(o,builders.identifier(s.value),false,true):o=builders.memberExpression(o,builders.literal(s.value),true,true);}return o}function Wn(n,e,i){let f=n.indexOf("[*]"),o=n.slice(0,f),s=n.slice(f+3),t;if(o?t=R(o,e,i):t=i?builders.identifier("undefined"):builders.identifier(e),!s||s==="")return t;if(s.includes("[*]"))return en(t,s);let r="_i",c=s.startsWith(".")?s.slice(1):s,l=builders.identifier(r);if(c){let a=G(c);for(let p of a)p.type==="key"?l=builders.memberExpression(l,builders.identifier(p.value),false,true):l=builders.memberExpression(l,builders.literal(p.value),true,true);}return builders.callExpression(builders.memberExpression(t,builders.identifier("map"),false,true),[builders.arrowFunctionExpression([builders.identifier(r)],l)])}function en(n,e){let i=e.indexOf("[*]"),f=e.slice(0,i),o=e.slice(i+3),s="_i",t=f.startsWith(".")?f.slice(1):f,r=builders.identifier(s);if(t){let l=G(t);for(let a of l)a.type==="key"&&(r=builders.memberExpression(r,builders.identifier(a.value),false,true));}if(o.includes("[*]")){let l=en(r,o);return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],l)])}let c=o.startsWith(".")?o.slice(1):o;if(c){let l=G(c);for(let a of l)a.type==="key"&&(r=builders.memberExpression(r,builders.identifier(a.value),false,true));}return builders.callExpression(builders.memberExpression(n,builders.identifier("flatMap"),false,true),[builders.arrowFunctionExpression([builders.identifier(s)],r)])}function Dn(n,e,i,f,o,s,t){let r;if(typeof n.$if=="string"){let a=n.$if.startsWith("!"),p=a?n.$if.slice(1):n.$if,d;o?_(p,s)?d=R(p,e,true):d=builders.callExpression(builders.identifier(V),[builders.literal(p),builders.identifier(e)]):d=R(p,e,f),r=a?builders.unaryExpression("!",d):d;}else r=y(n.$if,e,i,f,o,s,t);let c=y(n.then,e,i,f,o,s,t),l=n.else!==void 0?y(n.else,e,i,f,o,s,t):builders.identifier("undefined");return builders.conditionalExpression(r,c,l)}function In(n,e,i,f,o,s,t){let r=f?builders.identifier(n.$fn):builders.memberExpression(builders.identifier(i),builders.identifier(n.$fn),false,false);if(n.args===void 0)return r;let c=n.args.map(l=>typeof l=="function"?builders.literal(null):y(l,e,i,f,o,s,t));return builders.callExpression(r,c)}function Mn(n,e,i,f,o,s,t){if(n.length===0)return builders.identifier("undefined");if(n.length===1)return y(n[0],e,i,f,o,s,t);let r=y(n[0],e,i,f,o,s,t);for(let c=1;c<n.length;c++){let l=y(n[c],e,i,f,o,s,t);r=builders.callExpression(l,[r]);}return r}function P(n,e,i,f,o,s,t){if(h(n)){let r=n.$;return o?_(r,s)?R(r,e,true):builders.callExpression(builders.identifier(V),[builders.literal(r),builders.identifier(e)]):R(r,e,f)}return y(n,e,i,f,o,s,t)}function zn(n,e,i,f,o,s,t){let r=P(n.left,e,i,f,o,s,t),c=n.right!==void 0?P(n.right,e,i,f,o,s,t):builders.literal(null),l=vn[n.op];if(l)return builders.binaryExpression(l,r,c);switch(n.op){case "in":return builders.callExpression(builders.memberExpression(c,builders.identifier("includes")),[r]);case "notIn":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(c,builders.identifier("includes")),[r]));case "contains":return builders.callExpression(builders.memberExpression(r,builders.identifier("includes"),false,true),[c]);case "notContains":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(r,builders.identifier("includes"),false,true),[c]));case "exists":return builders.binaryExpression("!=",r,builders.literal(null));case "notExists":return builders.binaryExpression("==",r,builders.literal(null));case "matches":return builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[c]),builders.identifier("test")),[r]);case "notMatches":return builders.unaryExpression("!",builders.callExpression(builders.memberExpression(builders.newExpression(builders.identifier("RegExp"),[c]),builders.identifier("test")),[r]));case "startsWith":return builders.callExpression(builders.memberExpression(r,builders.identifier("startsWith"),false,true),[c]);case "endsWith":return builders.callExpression(builders.memberExpression(r,builders.identifier("endsWith"),false,true),[c]);default:return builders.binaryExpression("===",r,c)}}function Ln(n,e,i,f,o,s,t){let{logic:r,conditions:c}=n,l=r==="AND"?"&&":"||";if(c.length===0)return builders.literal(r==="AND");if(c.length===1)return y(c[0],e,i,f,o,s,t);let a=y(c[0],e,i,f,o,s,t);for(let p=1;p<c.length;p++){let d=y(c[p],e,i,f,o,s,t);a=builders.logicalExpression(l,a,d);}return a}function G(n){let e=[],i=n.length,f=0,o="";for(;f<i;){let s=n[f];if(s===".")o&&(e.push({type:"key",value:o}),o=""),f++;else if(s==="["){o&&(e.push({type:"key",value:o}),o=""),f++;let t=f;for(;f<i&&n[f]!=="]";)f++;let r=n.slice(t,f);if(f++,r!=="*"){let c=parseInt(r,10);e.push({type:"index",value:isNaN(c)?r:c});}}else o+=s,f++;}return o&&e.push({type:"key",value:o}),e}function tn(n,e=[L]){return builders.arrowFunctionExpression(e.map(i=>builders.identifier(i)),n)}function D(n,e){let i=new Set;return C(n,i,e),i}function C(n,e,i){if(n===null||typeof n!="object")return;if(Array.isArray(n)){for(let o of n)C(o,e,i);return}if(h(n))return;if(A(n)){C(n.$if,e,i),C(n.then,e,i),n.else!==void 0&&C(n.else,e,i);return}if(k(n)){for(let o of n.$pipe)C(o,e,i);return}if($(n)){if(e.add(n.$fn),n.args)for(let o of n.args)typeof o!="function"&&C(o,e,i);return}if(E(n)){n.left!==void 0&&typeof n.left=="object"&&C(n.left,e,i),n.right!==void 0&&typeof n.right=="object"&&C(n.right,e,i);return}if(T(n)){for(let o of n.conditions)C(o,e,i);return}if(i){let o=n,s=Object.keys(o);for(let t=0;t<s.length;t++){let r=s[t];if(r in i){let c=i[r](o);if(typeof c=="object"&&c!==null&&r in c)throw new Error(`Transform "${r}" returned object with same key \u2014 infinite loop`);C(c,e,i);return}}}let f=n;for(let o of Object.keys(f))C(f[o],e,i);}function I(n){let e=new Set;for(let i of n){let f=i.indexOf("."),o=i.indexOf("["),s=i.length;f!==-1&&(s=Math.min(s,f)),o!==-1&&(s=Math.min(s,o));let t=i.slice(0,s);t&&e.add(t);}return e}function _n(n){return JSON.stringify(n)}function qn(n,e,i,f,o,s){let t=W(n,{noPrefixes:true,useAccessor:f,lexicalPrefix:o,transforms:s}),r=generate(t),c="";f?o&&(c=`const{${o}}=data??{};`):e.size>0&&(c=`const{${[...e].join(",")}}=data??{};`);let l=f?new Set([...i,"accessor"]):i,a=l.size>0?`const{${[...l].join(",")}}=scope;`:"";return a?`(function(scope){${a}return function(data){${c}return ${r}}})`:`(function(){return function(data){${c}return ${r}}})`}function q(n,e={}){let{scope:i={},returnCode:f=false,useAccessor:o=false,lexicalPrefix:s,transforms:t}=e,r=w(n,t),c=I(r),l=D(n,t),a=_n(n),p=qn(n,c,l,o,s,t);if(f)return {code:p,deps:r,hash:a,dataRoots:[...c],scopeFns:[...l]};let d;try{d=new Function(`return ${p}`)()(i);}catch(g){throw new Error(`AST compilation failed. If this is due to CSP, use the standard compile() function instead. Error: ${g instanceof Error?g.message:String(g)}`)}return {fn:d,deps:r,hash:a}}function on(n,e,i={}){let{fn:f}=q(n,i);return f(e)}var Ee="0.1.1";export{v as ExpressionCache,Ee as VERSION,wn as assertValid,Z as builders,Y as cache,Sn as cached,dn as clearPathCache,N as compile,q as compileAST,O as compilePath,W as dslToAST,kn as evaluate,on as evaluateAST,I as extractDataRoots,w as extractDeps,D as extractScopeFns,pn as get,gn as getPathCacheSize,yn as hasDeps,B as hasWildcard,E as isCondition,fn as isConditionExpr,T as isConditionGroup,A as isConditional,$ as isFn,M as isLiteral,k as isPipe,mn as isPure,h as isRef,Rn as isValid,j as normalizePath,z as validate,tn as wrapInFunction};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statedelta-libs/expressions",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.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",
|