@manifesto-ai/core 2.5.0 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -7
- package/dist/index.d.ts +1749 -19
- package/dist/index.js +18456 -36
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/__tests__/apply.test.d.ts +0 -2
- package/dist/__tests__/apply.test.d.ts.map +0 -1
- package/dist/__tests__/apply.test.js +0 -279
- package/dist/__tests__/apply.test.js.map +0 -1
- package/dist/__tests__/defaults.test.d.ts +0 -2
- package/dist/__tests__/defaults.test.d.ts.map +0 -1
- package/dist/__tests__/defaults.test.js +0 -74
- package/dist/__tests__/defaults.test.js.map +0 -1
- package/dist/__tests__/jcs.test.d.ts +0 -2
- package/dist/__tests__/jcs.test.d.ts.map +0 -1
- package/dist/__tests__/jcs.test.js +0 -45
- package/dist/__tests__/jcs.test.js.map +0 -1
- package/dist/core/apply.d.ts +0 -17
- package/dist/core/apply.d.ts.map +0 -1
- package/dist/core/apply.js +0 -198
- package/dist/core/apply.js.map +0 -1
- package/dist/core/compute.d.ts +0 -17
- package/dist/core/compute.d.ts.map +0 -1
- package/dist/core/compute.js +0 -305
- package/dist/core/compute.js.map +0 -1
- package/dist/core/compute.test.d.ts +0 -2
- package/dist/core/compute.test.d.ts.map +0 -1
- package/dist/core/compute.test.js +0 -950
- package/dist/core/compute.test.js.map +0 -1
- package/dist/core/explain.d.ts +0 -14
- package/dist/core/explain.d.ts.map +0 -1
- package/dist/core/explain.js +0 -78
- package/dist/core/explain.js.map +0 -1
- package/dist/core/index.d.ts +0 -5
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -5
- package/dist/core/index.js.map +0 -1
- package/dist/core/validate.d.ts +0 -16
- package/dist/core/validate.d.ts.map +0 -1
- package/dist/core/validate.js +0 -361
- package/dist/core/validate.js.map +0 -1
- package/dist/core/validate.test.d.ts +0 -2
- package/dist/core/validate.test.d.ts.map +0 -1
- package/dist/core/validate.test.js +0 -638
- package/dist/core/validate.test.js.map +0 -1
- package/dist/core/validation-utils.d.ts +0 -20
- package/dist/core/validation-utils.d.ts.map +0 -1
- package/dist/core/validation-utils.js +0 -292
- package/dist/core/validation-utils.js.map +0 -1
- package/dist/errors.d.ts +0 -30
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -51
- package/dist/errors.js.map +0 -1
- package/dist/evaluator/computed.d.ts +0 -14
- package/dist/evaluator/computed.d.ts.map +0 -1
- package/dist/evaluator/computed.js +0 -60
- package/dist/evaluator/computed.js.map +0 -1
- package/dist/evaluator/context.d.ts +0 -62
- package/dist/evaluator/context.d.ts.map +0 -1
- package/dist/evaluator/context.js +0 -44
- package/dist/evaluator/context.js.map +0 -1
- package/dist/evaluator/dag.d.ts +0 -30
- package/dist/evaluator/dag.d.ts.map +0 -1
- package/dist/evaluator/dag.js +0 -121
- package/dist/evaluator/dag.js.map +0 -1
- package/dist/evaluator/expr.d.ts +0 -11
- package/dist/evaluator/expr.d.ts.map +0 -1
- package/dist/evaluator/expr.js +0 -667
- package/dist/evaluator/expr.js.map +0 -1
- package/dist/evaluator/expr.test.d.ts +0 -2
- package/dist/evaluator/expr.test.d.ts.map +0 -1
- package/dist/evaluator/expr.test.js +0 -508
- package/dist/evaluator/expr.test.js.map +0 -1
- package/dist/evaluator/flow.d.ts +0 -36
- package/dist/evaluator/flow.d.ts.map +0 -1
- package/dist/evaluator/flow.js +0 -390
- package/dist/evaluator/flow.js.map +0 -1
- package/dist/evaluator/flow.test.d.ts +0 -2
- package/dist/evaluator/flow.test.d.ts.map +0 -1
- package/dist/evaluator/flow.test.js +0 -499
- package/dist/evaluator/flow.test.js.map +0 -1
- package/dist/evaluator/index.d.ts +0 -6
- package/dist/evaluator/index.d.ts.map +0 -1
- package/dist/evaluator/index.js +0 -6
- package/dist/evaluator/index.js.map +0 -1
- package/dist/factories.d.ts +0 -22
- package/dist/factories.d.ts.map +0 -1
- package/dist/factories.js +0 -44
- package/dist/factories.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/dist/index.test.js +0 -14
- package/dist/index.test.js.map +0 -1
- package/dist/schema/action.d.ts +0 -14
- package/dist/schema/action.d.ts.map +0 -1
- package/dist/schema/action.js +0 -30
- package/dist/schema/action.js.map +0 -1
- package/dist/schema/common.d.ts +0 -37
- package/dist/schema/common.d.ts.map +0 -1
- package/dist/schema/common.js +0 -20
- package/dist/schema/common.js.map +0 -1
- package/dist/schema/computed.d.ts +0 -23
- package/dist/schema/computed.d.ts.map +0 -1
- package/dist/schema/computed.js +0 -34
- package/dist/schema/computed.js.map +0 -1
- package/dist/schema/defaults.d.ts +0 -12
- package/dist/schema/defaults.d.ts.map +0 -1
- package/dist/schema/defaults.js +0 -19
- package/dist/schema/defaults.js.map +0 -1
- package/dist/schema/domain.d.ts +0 -50
- package/dist/schema/domain.d.ts.map +0 -1
- package/dist/schema/domain.js +0 -60
- package/dist/schema/domain.js.map +0 -1
- package/dist/schema/expr.d.ts +0 -310
- package/dist/schema/expr.d.ts.map +0 -1
- package/dist/schema/expr.js +0 -289
- package/dist/schema/expr.js.map +0 -1
- package/dist/schema/field.d.ts +0 -48
- package/dist/schema/field.d.ts.map +0 -1
- package/dist/schema/field.js +0 -31
- package/dist/schema/field.js.map +0 -1
- package/dist/schema/flow.d.ts +0 -103
- package/dist/schema/flow.d.ts.map +0 -1
- package/dist/schema/flow.js +0 -82
- package/dist/schema/flow.js.map +0 -1
- package/dist/schema/host-context.d.ts +0 -12
- package/dist/schema/host-context.d.ts.map +0 -1
- package/dist/schema/host-context.js +0 -23
- package/dist/schema/host-context.js.map +0 -1
- package/dist/schema/index.d.ts +0 -15
- package/dist/schema/index.d.ts.map +0 -1
- package/dist/schema/index.js +0 -28
- package/dist/schema/index.js.map +0 -1
- package/dist/schema/patch.d.ts +0 -59
- package/dist/schema/patch.d.ts.map +0 -1
- package/dist/schema/patch.js +0 -60
- package/dist/schema/patch.js.map +0 -1
- package/dist/schema/result.d.ts +0 -142
- package/dist/schema/result.d.ts.map +0 -1
- package/dist/schema/result.js +0 -94
- package/dist/schema/result.js.map +0 -1
- package/dist/schema/snapshot.d.ts +0 -153
- package/dist/schema/snapshot.d.ts.map +0 -1
- package/dist/schema/snapshot.js +0 -160
- package/dist/schema/snapshot.js.map +0 -1
- package/dist/schema/trace.d.ts +0 -98
- package/dist/schema/trace.d.ts.map +0 -1
- package/dist/schema/trace.js +0 -90
- package/dist/schema/trace.js.map +0 -1
- package/dist/schema/type-spec.d.ts +0 -34
- package/dist/schema/type-spec.d.ts.map +0 -1
- package/dist/schema/type-spec.js +0 -40
- package/dist/schema/type-spec.js.map +0 -1
- package/dist/utils/canonical.d.ts +0 -37
- package/dist/utils/canonical.d.ts.map +0 -1
- package/dist/utils/canonical.js +0 -122
- package/dist/utils/canonical.js.map +0 -1
- package/dist/utils/canonical.test.d.ts +0 -2
- package/dist/utils/canonical.test.d.ts.map +0 -1
- package/dist/utils/canonical.test.js +0 -183
- package/dist/utils/canonical.test.js.map +0 -1
- package/dist/utils/hash.d.ts +0 -55
- package/dist/utils/hash.d.ts.map +0 -1
- package/dist/utils/hash.js +0 -183
- package/dist/utils/hash.js.map +0 -1
- package/dist/utils/hash.test.d.ts +0 -2
- package/dist/utils/hash.test.d.ts.map +0 -1
- package/dist/utils/hash.test.js +0 -253
- package/dist/utils/hash.test.js.map +0 -1
- package/dist/utils/index.d.ts +0 -4
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -4
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/path.d.ts +0 -40
- package/dist/utils/path.d.ts.map +0 -1
- package/dist/utils/path.js +0 -132
- package/dist/utils/path.js.map +0 -1
- package/dist/utils/path.test.d.ts +0 -2
- package/dist/utils/path.test.d.ts.map +0 -1
- package/dist/utils/path.test.js +0 -191
- package/dist/utils/path.test.js.map +0 -1
package/dist/evaluator/expr.js
DELETED
|
@@ -1,667 +0,0 @@
|
|
|
1
|
-
import { ok, err } from "../schema/common.js";
|
|
2
|
-
import { createError } from "../errors.js";
|
|
3
|
-
import { getByPath } from "../utils/path.js";
|
|
4
|
-
import { withCollectionContext } from "./context.js";
|
|
5
|
-
/**
|
|
6
|
-
* Evaluate an expression node
|
|
7
|
-
* All expressions are pure and total (always return a value or error)
|
|
8
|
-
*/
|
|
9
|
-
export function evaluateExpr(expr, ctx) {
|
|
10
|
-
switch (expr.kind) {
|
|
11
|
-
// Literals
|
|
12
|
-
case "lit":
|
|
13
|
-
return ok(expr.value);
|
|
14
|
-
case "get":
|
|
15
|
-
return evaluateGet(expr.path, ctx);
|
|
16
|
-
// Comparison
|
|
17
|
-
case "eq":
|
|
18
|
-
return evaluateBinary(expr.left, expr.right, ctx, (a, b) => a === b);
|
|
19
|
-
case "neq":
|
|
20
|
-
return evaluateBinary(expr.left, expr.right, ctx, (a, b) => a !== b);
|
|
21
|
-
case "gt":
|
|
22
|
-
return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) > toNumber(b));
|
|
23
|
-
case "gte":
|
|
24
|
-
return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) >= toNumber(b));
|
|
25
|
-
case "lt":
|
|
26
|
-
return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) < toNumber(b));
|
|
27
|
-
case "lte":
|
|
28
|
-
return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) <= toNumber(b));
|
|
29
|
-
// Logical
|
|
30
|
-
case "and":
|
|
31
|
-
return evaluateAnd(expr.args, ctx);
|
|
32
|
-
case "or":
|
|
33
|
-
return evaluateOr(expr.args, ctx);
|
|
34
|
-
case "not":
|
|
35
|
-
return evaluateNot(expr.arg, ctx);
|
|
36
|
-
// Conditional
|
|
37
|
-
case "if":
|
|
38
|
-
return evaluateIf(expr, ctx);
|
|
39
|
-
// Arithmetic
|
|
40
|
-
case "add":
|
|
41
|
-
return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) + toNumber(b));
|
|
42
|
-
case "sub":
|
|
43
|
-
return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) - toNumber(b));
|
|
44
|
-
case "mul":
|
|
45
|
-
return evaluateBinary(expr.left, expr.right, ctx, (a, b) => toNumber(a) * toNumber(b));
|
|
46
|
-
case "div":
|
|
47
|
-
return evaluateDiv(expr.left, expr.right, ctx);
|
|
48
|
-
case "mod":
|
|
49
|
-
return evaluateMod(expr.left, expr.right, ctx);
|
|
50
|
-
case "min":
|
|
51
|
-
return evaluateMin(expr.args, ctx);
|
|
52
|
-
case "max":
|
|
53
|
-
return evaluateMax(expr.args, ctx);
|
|
54
|
-
case "abs":
|
|
55
|
-
return evaluateAbs(expr.arg, ctx);
|
|
56
|
-
case "neg":
|
|
57
|
-
return evaluateNeg(expr.arg, ctx);
|
|
58
|
-
// String
|
|
59
|
-
case "concat":
|
|
60
|
-
return evaluateConcat(expr.args, ctx);
|
|
61
|
-
case "substring":
|
|
62
|
-
return evaluateSubstring(expr, ctx);
|
|
63
|
-
case "trim":
|
|
64
|
-
return evaluateTrim(expr.str, ctx);
|
|
65
|
-
// Collection
|
|
66
|
-
case "len":
|
|
67
|
-
return evaluateLen(expr.arg, ctx);
|
|
68
|
-
case "at":
|
|
69
|
-
return evaluateAt(expr.array, expr.index, ctx);
|
|
70
|
-
case "first":
|
|
71
|
-
return evaluateFirst(expr.array, ctx);
|
|
72
|
-
case "last":
|
|
73
|
-
return evaluateLast(expr.array, ctx);
|
|
74
|
-
case "slice":
|
|
75
|
-
return evaluateSlice(expr, ctx);
|
|
76
|
-
case "includes":
|
|
77
|
-
return evaluateIncludes(expr.array, expr.item, ctx);
|
|
78
|
-
case "filter":
|
|
79
|
-
return evaluateFilter(expr.array, expr.predicate, ctx);
|
|
80
|
-
case "map":
|
|
81
|
-
return evaluateMap(expr.array, expr.mapper, ctx);
|
|
82
|
-
case "find":
|
|
83
|
-
return evaluateFind(expr.array, expr.predicate, ctx);
|
|
84
|
-
case "every":
|
|
85
|
-
return evaluateEvery(expr.array, expr.predicate, ctx);
|
|
86
|
-
case "some":
|
|
87
|
-
return evaluateSome(expr.array, expr.predicate, ctx);
|
|
88
|
-
case "append":
|
|
89
|
-
return evaluateAppend(expr.array, expr.items, ctx);
|
|
90
|
-
// Object
|
|
91
|
-
case "object":
|
|
92
|
-
return evaluateObject(expr.fields, ctx);
|
|
93
|
-
case "field":
|
|
94
|
-
return evaluateField(expr.object, expr.property, ctx);
|
|
95
|
-
case "keys":
|
|
96
|
-
return evaluateKeys(expr.obj, ctx);
|
|
97
|
-
case "values":
|
|
98
|
-
return evaluateValues(expr.obj, ctx);
|
|
99
|
-
case "entries":
|
|
100
|
-
return evaluateEntries(expr.obj, ctx);
|
|
101
|
-
case "merge":
|
|
102
|
-
return evaluateMerge(expr.objects, ctx);
|
|
103
|
-
// Type
|
|
104
|
-
case "typeof":
|
|
105
|
-
return evaluateTypeof(expr.arg, ctx);
|
|
106
|
-
case "isNull":
|
|
107
|
-
return evaluateIsNull(expr.arg, ctx);
|
|
108
|
-
case "coalesce":
|
|
109
|
-
return evaluateCoalesce(expr.args, ctx);
|
|
110
|
-
default:
|
|
111
|
-
return err(createError("INTERNAL_ERROR", `Unknown expression kind: ${expr.kind}`, ctx.currentAction ?? "", ctx.nodePath, ctx.trace.timestamp));
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
// ============ Helper Functions ============
|
|
115
|
-
function toNumber(value) {
|
|
116
|
-
if (typeof value === "number")
|
|
117
|
-
return value;
|
|
118
|
-
if (typeof value === "string")
|
|
119
|
-
return parseFloat(value) || 0;
|
|
120
|
-
if (typeof value === "boolean")
|
|
121
|
-
return value ? 1 : 0;
|
|
122
|
-
return 0;
|
|
123
|
-
}
|
|
124
|
-
function toBoolean(value) {
|
|
125
|
-
if (value === null || value === undefined)
|
|
126
|
-
return false;
|
|
127
|
-
if (typeof value === "boolean")
|
|
128
|
-
return value;
|
|
129
|
-
if (typeof value === "number")
|
|
130
|
-
return value !== 0;
|
|
131
|
-
if (typeof value === "string")
|
|
132
|
-
return value.length > 0;
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
function toString(value) {
|
|
136
|
-
if (value === null || value === undefined)
|
|
137
|
-
return "";
|
|
138
|
-
if (typeof value === "string")
|
|
139
|
-
return value;
|
|
140
|
-
return String(value);
|
|
141
|
-
}
|
|
142
|
-
// ============ Get ============
|
|
143
|
-
/**
|
|
144
|
-
* Generate a deterministic UUID from intentId and counter
|
|
145
|
-
* Uses a simple hash to create reproducible UUIDs
|
|
146
|
-
*/
|
|
147
|
-
function generateDeterministicUuid(intentId, counter) {
|
|
148
|
-
// Create a simple hash-based UUID from intentId and counter
|
|
149
|
-
// This ensures the same intentId + counter always produces the same UUID
|
|
150
|
-
const seed = `${intentId}-${counter}`;
|
|
151
|
-
let hash = 0;
|
|
152
|
-
for (let i = 0; i < seed.length; i++) {
|
|
153
|
-
const char = seed.charCodeAt(i);
|
|
154
|
-
hash = ((hash << 5) - hash) + char;
|
|
155
|
-
hash = hash & hash; // Convert to 32-bit integer
|
|
156
|
-
}
|
|
157
|
-
// Convert hash to hex string and format as UUID
|
|
158
|
-
const hex = Math.abs(hash).toString(16).padStart(8, '0');
|
|
159
|
-
const hex2 = Math.abs(hash * 31).toString(16).padStart(4, '0');
|
|
160
|
-
const hex3 = Math.abs(hash * 37).toString(16).padStart(4, '0');
|
|
161
|
-
const hex4 = Math.abs(hash * 41).toString(16).padStart(4, '0');
|
|
162
|
-
const hex5 = Math.abs(hash * 43).toString(16).padStart(12, '0');
|
|
163
|
-
return `${hex.slice(0, 8)}-${hex2.slice(0, 4)}-4${hex3.slice(1, 4)}-${hex4.slice(0, 4)}-${hex5.slice(0, 12)}`;
|
|
164
|
-
}
|
|
165
|
-
function evaluateGet(path, ctx) {
|
|
166
|
-
// Handle collection context variables
|
|
167
|
-
if (path.startsWith("$item")) {
|
|
168
|
-
if (ctx.$item === undefined) {
|
|
169
|
-
return ok(undefined);
|
|
170
|
-
}
|
|
171
|
-
if (path === "$item") {
|
|
172
|
-
return ok(ctx.$item);
|
|
173
|
-
}
|
|
174
|
-
// e.g., $item.completed
|
|
175
|
-
const subPath = path.slice(6); // Remove "$item."
|
|
176
|
-
return ok(getByPath(ctx.$item, subPath));
|
|
177
|
-
}
|
|
178
|
-
if (path === "$index") {
|
|
179
|
-
return ok(ctx.$index);
|
|
180
|
-
}
|
|
181
|
-
if (path === "$array") {
|
|
182
|
-
return ok(ctx.$array);
|
|
183
|
-
}
|
|
184
|
-
// Handle $system paths (special runtime values)
|
|
185
|
-
if (path.startsWith("$system.")) {
|
|
186
|
-
const systemPath = path.slice(8); // Remove "$system."
|
|
187
|
-
if (systemPath === "uuid") {
|
|
188
|
-
// Generate deterministic UUID from intentId + counter
|
|
189
|
-
const intentId = ctx.intentId ?? "no-intent";
|
|
190
|
-
const counter = ctx.uuidCounter ?? 0;
|
|
191
|
-
// Increment counter for next uuid call (mutable on purpose for determinism across calls)
|
|
192
|
-
if (ctx.uuidCounter !== undefined) {
|
|
193
|
-
ctx.uuidCounter = counter + 1;
|
|
194
|
-
}
|
|
195
|
-
return ok(generateDeterministicUuid(intentId, counter));
|
|
196
|
-
}
|
|
197
|
-
if (systemPath === "timestamp") {
|
|
198
|
-
// Return the snapshot's timestamp (set by Host)
|
|
199
|
-
return ok(new Date(ctx.snapshot.meta.timestamp).toISOString());
|
|
200
|
-
}
|
|
201
|
-
// Unknown $system path
|
|
202
|
-
return ok(undefined);
|
|
203
|
-
}
|
|
204
|
-
// Handle meta path (snapshot metadata)
|
|
205
|
-
if (path.startsWith("meta.")) {
|
|
206
|
-
const metaPath = path.slice(5); // Remove "meta."
|
|
207
|
-
if (metaPath === "intentId") {
|
|
208
|
-
return ok(ctx.intentId);
|
|
209
|
-
}
|
|
210
|
-
if (metaPath === "actionName") {
|
|
211
|
-
return ok(ctx.currentAction);
|
|
212
|
-
}
|
|
213
|
-
return ok(getByPath(ctx.snapshot.meta, metaPath));
|
|
214
|
-
}
|
|
215
|
-
// Handle input path
|
|
216
|
-
if (path.startsWith("input.") || path === "input") {
|
|
217
|
-
const subPath = path === "input" ? "" : path.slice(6);
|
|
218
|
-
return ok(subPath ? getByPath(ctx.snapshot.input, subPath) : ctx.snapshot.input);
|
|
219
|
-
}
|
|
220
|
-
// Handle computed path
|
|
221
|
-
if (path.startsWith("computed.")) {
|
|
222
|
-
return ok(ctx.snapshot.computed[path]);
|
|
223
|
-
}
|
|
224
|
-
// Handle system path (snapshot.system, not $system)
|
|
225
|
-
if (path.startsWith("system.")) {
|
|
226
|
-
const subPath = path.slice(7);
|
|
227
|
-
return ok(getByPath(ctx.snapshot.system, subPath));
|
|
228
|
-
}
|
|
229
|
-
// Default: get from data
|
|
230
|
-
return ok(getByPath(ctx.snapshot.data, path));
|
|
231
|
-
}
|
|
232
|
-
// ============ Binary Operations ============
|
|
233
|
-
function evaluateBinary(left, right, ctx, op) {
|
|
234
|
-
const leftResult = evaluateExpr(left, ctx);
|
|
235
|
-
if (!leftResult.ok)
|
|
236
|
-
return leftResult;
|
|
237
|
-
const rightResult = evaluateExpr(right, ctx);
|
|
238
|
-
if (!rightResult.ok)
|
|
239
|
-
return rightResult;
|
|
240
|
-
return ok(op(leftResult.value, rightResult.value));
|
|
241
|
-
}
|
|
242
|
-
// ============ Logical ============
|
|
243
|
-
function evaluateAnd(args, ctx) {
|
|
244
|
-
for (const arg of args) {
|
|
245
|
-
const result = evaluateExpr(arg, ctx);
|
|
246
|
-
if (!result.ok)
|
|
247
|
-
return result;
|
|
248
|
-
if (!toBoolean(result.value))
|
|
249
|
-
return ok(false);
|
|
250
|
-
}
|
|
251
|
-
return ok(true);
|
|
252
|
-
}
|
|
253
|
-
function evaluateOr(args, ctx) {
|
|
254
|
-
for (const arg of args) {
|
|
255
|
-
const result = evaluateExpr(arg, ctx);
|
|
256
|
-
if (!result.ok)
|
|
257
|
-
return result;
|
|
258
|
-
if (toBoolean(result.value))
|
|
259
|
-
return ok(true);
|
|
260
|
-
}
|
|
261
|
-
return ok(false);
|
|
262
|
-
}
|
|
263
|
-
function evaluateNot(arg, ctx) {
|
|
264
|
-
const result = evaluateExpr(arg, ctx);
|
|
265
|
-
if (!result.ok)
|
|
266
|
-
return result;
|
|
267
|
-
return ok(!toBoolean(result.value));
|
|
268
|
-
}
|
|
269
|
-
// ============ Conditional ============
|
|
270
|
-
function evaluateIf(expr, ctx) {
|
|
271
|
-
const condResult = evaluateExpr(expr.cond, ctx);
|
|
272
|
-
if (!condResult.ok)
|
|
273
|
-
return condResult;
|
|
274
|
-
return evaluateExpr(toBoolean(condResult.value) ? expr.then : expr.else, ctx);
|
|
275
|
-
}
|
|
276
|
-
// ============ Arithmetic ============
|
|
277
|
-
function evaluateDiv(left, right, ctx) {
|
|
278
|
-
const leftResult = evaluateExpr(left, ctx);
|
|
279
|
-
if (!leftResult.ok)
|
|
280
|
-
return leftResult;
|
|
281
|
-
const rightResult = evaluateExpr(right, ctx);
|
|
282
|
-
if (!rightResult.ok)
|
|
283
|
-
return rightResult;
|
|
284
|
-
const divisor = toNumber(rightResult.value);
|
|
285
|
-
if (divisor === 0)
|
|
286
|
-
return ok(null); // Division by zero returns null, not error
|
|
287
|
-
return ok(toNumber(leftResult.value) / divisor);
|
|
288
|
-
}
|
|
289
|
-
function evaluateMod(left, right, ctx) {
|
|
290
|
-
const leftResult = evaluateExpr(left, ctx);
|
|
291
|
-
if (!leftResult.ok)
|
|
292
|
-
return leftResult;
|
|
293
|
-
const rightResult = evaluateExpr(right, ctx);
|
|
294
|
-
if (!rightResult.ok)
|
|
295
|
-
return rightResult;
|
|
296
|
-
const divisor = toNumber(rightResult.value);
|
|
297
|
-
if (divisor === 0)
|
|
298
|
-
return ok(null);
|
|
299
|
-
return ok(toNumber(leftResult.value) % divisor);
|
|
300
|
-
}
|
|
301
|
-
function evaluateMin(args, ctx) {
|
|
302
|
-
if (args.length === 0)
|
|
303
|
-
return ok(null);
|
|
304
|
-
const values = [];
|
|
305
|
-
for (const arg of args) {
|
|
306
|
-
const result = evaluateExpr(arg, ctx);
|
|
307
|
-
if (!result.ok)
|
|
308
|
-
return result;
|
|
309
|
-
values.push(toNumber(result.value));
|
|
310
|
-
}
|
|
311
|
-
return ok(Math.min(...values));
|
|
312
|
-
}
|
|
313
|
-
function evaluateMax(args, ctx) {
|
|
314
|
-
if (args.length === 0)
|
|
315
|
-
return ok(null);
|
|
316
|
-
const values = [];
|
|
317
|
-
for (const arg of args) {
|
|
318
|
-
const result = evaluateExpr(arg, ctx);
|
|
319
|
-
if (!result.ok)
|
|
320
|
-
return result;
|
|
321
|
-
values.push(toNumber(result.value));
|
|
322
|
-
}
|
|
323
|
-
return ok(Math.max(...values));
|
|
324
|
-
}
|
|
325
|
-
function evaluateAbs(arg, ctx) {
|
|
326
|
-
const result = evaluateExpr(arg, ctx);
|
|
327
|
-
if (!result.ok)
|
|
328
|
-
return result;
|
|
329
|
-
return ok(Math.abs(toNumber(result.value)));
|
|
330
|
-
}
|
|
331
|
-
function evaluateNeg(arg, ctx) {
|
|
332
|
-
const result = evaluateExpr(arg, ctx);
|
|
333
|
-
if (!result.ok)
|
|
334
|
-
return result;
|
|
335
|
-
return ok(-toNumber(result.value));
|
|
336
|
-
}
|
|
337
|
-
// ============ String ============
|
|
338
|
-
function evaluateConcat(args, ctx) {
|
|
339
|
-
// First, evaluate all arguments to determine if this is array or string concat
|
|
340
|
-
const values = [];
|
|
341
|
-
for (const arg of args) {
|
|
342
|
-
const result = evaluateExpr(arg, ctx);
|
|
343
|
-
if (!result.ok)
|
|
344
|
-
return result;
|
|
345
|
-
values.push(result.value);
|
|
346
|
-
}
|
|
347
|
-
// If any argument is an array, treat as array concatenation
|
|
348
|
-
const hasArray = values.some(v => Array.isArray(v));
|
|
349
|
-
if (hasArray) {
|
|
350
|
-
const result = [];
|
|
351
|
-
for (const value of values) {
|
|
352
|
-
if (Array.isArray(value)) {
|
|
353
|
-
result.push(...value);
|
|
354
|
-
}
|
|
355
|
-
else if (value !== null && value !== undefined) {
|
|
356
|
-
// Single value gets added as element
|
|
357
|
-
result.push(value);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
return ok(result);
|
|
361
|
-
}
|
|
362
|
-
// Otherwise, string concatenation
|
|
363
|
-
const parts = values.map(v => toString(v));
|
|
364
|
-
return ok(parts.join(""));
|
|
365
|
-
}
|
|
366
|
-
function evaluateSubstring(expr, ctx) {
|
|
367
|
-
const strResult = evaluateExpr(expr.str, ctx);
|
|
368
|
-
if (!strResult.ok)
|
|
369
|
-
return strResult;
|
|
370
|
-
const startResult = evaluateExpr(expr.start, ctx);
|
|
371
|
-
if (!startResult.ok)
|
|
372
|
-
return startResult;
|
|
373
|
-
const str = toString(strResult.value);
|
|
374
|
-
const start = toNumber(startResult.value);
|
|
375
|
-
if (expr.end) {
|
|
376
|
-
const endResult = evaluateExpr(expr.end, ctx);
|
|
377
|
-
if (!endResult.ok)
|
|
378
|
-
return endResult;
|
|
379
|
-
return ok(str.substring(start, toNumber(endResult.value)));
|
|
380
|
-
}
|
|
381
|
-
return ok(str.substring(start));
|
|
382
|
-
}
|
|
383
|
-
function evaluateTrim(str, ctx) {
|
|
384
|
-
const result = evaluateExpr(str, ctx);
|
|
385
|
-
if (!result.ok)
|
|
386
|
-
return result;
|
|
387
|
-
return ok(toString(result.value).trim());
|
|
388
|
-
}
|
|
389
|
-
// ============ Collection ============
|
|
390
|
-
function evaluateLen(arg, ctx) {
|
|
391
|
-
const result = evaluateExpr(arg, ctx);
|
|
392
|
-
if (!result.ok)
|
|
393
|
-
return result;
|
|
394
|
-
const value = result.value;
|
|
395
|
-
if (Array.isArray(value))
|
|
396
|
-
return ok(value.length);
|
|
397
|
-
if (typeof value === "string")
|
|
398
|
-
return ok(value.length);
|
|
399
|
-
if (typeof value === "object" && value !== null)
|
|
400
|
-
return ok(Object.keys(value).length);
|
|
401
|
-
return ok(0);
|
|
402
|
-
}
|
|
403
|
-
function evaluateAt(array, index, ctx) {
|
|
404
|
-
const arrayResult = evaluateExpr(array, ctx);
|
|
405
|
-
if (!arrayResult.ok)
|
|
406
|
-
return arrayResult;
|
|
407
|
-
const indexResult = evaluateExpr(index, ctx);
|
|
408
|
-
if (!indexResult.ok)
|
|
409
|
-
return indexResult;
|
|
410
|
-
const base = arrayResult.value;
|
|
411
|
-
const key = indexResult.value;
|
|
412
|
-
// Array indexing: at(array, numericIndex)
|
|
413
|
-
if (Array.isArray(base)) {
|
|
414
|
-
const idx = toNumber(key);
|
|
415
|
-
if (idx < 0 || idx >= base.length)
|
|
416
|
-
return ok(null);
|
|
417
|
-
return ok(base[idx]);
|
|
418
|
-
}
|
|
419
|
-
// Record lookup: at(record, stringKey)
|
|
420
|
-
if (typeof base === "object" && base !== null && typeof key === "string") {
|
|
421
|
-
return ok(base[key] ?? null);
|
|
422
|
-
}
|
|
423
|
-
return ok(null);
|
|
424
|
-
}
|
|
425
|
-
function evaluateFirst(array, ctx) {
|
|
426
|
-
const result = evaluateExpr(array, ctx);
|
|
427
|
-
if (!result.ok)
|
|
428
|
-
return result;
|
|
429
|
-
const arr = result.value;
|
|
430
|
-
if (!Array.isArray(arr) || arr.length === 0)
|
|
431
|
-
return ok(null);
|
|
432
|
-
return ok(arr[0]);
|
|
433
|
-
}
|
|
434
|
-
function evaluateLast(array, ctx) {
|
|
435
|
-
const result = evaluateExpr(array, ctx);
|
|
436
|
-
if (!result.ok)
|
|
437
|
-
return result;
|
|
438
|
-
const arr = result.value;
|
|
439
|
-
if (!Array.isArray(arr) || arr.length === 0)
|
|
440
|
-
return ok(null);
|
|
441
|
-
return ok(arr[arr.length - 1]);
|
|
442
|
-
}
|
|
443
|
-
function evaluateSlice(expr, ctx) {
|
|
444
|
-
const arrayResult = evaluateExpr(expr.array, ctx);
|
|
445
|
-
if (!arrayResult.ok)
|
|
446
|
-
return arrayResult;
|
|
447
|
-
const startResult = evaluateExpr(expr.start, ctx);
|
|
448
|
-
if (!startResult.ok)
|
|
449
|
-
return startResult;
|
|
450
|
-
const arr = arrayResult.value;
|
|
451
|
-
if (!Array.isArray(arr))
|
|
452
|
-
return ok([]);
|
|
453
|
-
const start = toNumber(startResult.value);
|
|
454
|
-
if (expr.end) {
|
|
455
|
-
const endResult = evaluateExpr(expr.end, ctx);
|
|
456
|
-
if (!endResult.ok)
|
|
457
|
-
return endResult;
|
|
458
|
-
return ok(arr.slice(start, toNumber(endResult.value)));
|
|
459
|
-
}
|
|
460
|
-
return ok(arr.slice(start));
|
|
461
|
-
}
|
|
462
|
-
function evaluateIncludes(array, item, ctx) {
|
|
463
|
-
const arrayResult = evaluateExpr(array, ctx);
|
|
464
|
-
if (!arrayResult.ok)
|
|
465
|
-
return arrayResult;
|
|
466
|
-
const itemResult = evaluateExpr(item, ctx);
|
|
467
|
-
if (!itemResult.ok)
|
|
468
|
-
return itemResult;
|
|
469
|
-
const arr = arrayResult.value;
|
|
470
|
-
if (!Array.isArray(arr))
|
|
471
|
-
return ok(false);
|
|
472
|
-
return ok(arr.includes(itemResult.value));
|
|
473
|
-
}
|
|
474
|
-
function evaluateFilter(array, predicate, ctx) {
|
|
475
|
-
const arrayResult = evaluateExpr(array, ctx);
|
|
476
|
-
if (!arrayResult.ok)
|
|
477
|
-
return arrayResult;
|
|
478
|
-
const arr = arrayResult.value;
|
|
479
|
-
if (!Array.isArray(arr))
|
|
480
|
-
return ok([]);
|
|
481
|
-
const filtered = [];
|
|
482
|
-
for (let i = 0; i < arr.length; i++) {
|
|
483
|
-
const itemCtx = withCollectionContext(ctx, arr[i], i, arr);
|
|
484
|
-
const predicateResult = evaluateExpr(predicate, itemCtx);
|
|
485
|
-
if (!predicateResult.ok)
|
|
486
|
-
return predicateResult;
|
|
487
|
-
if (toBoolean(predicateResult.value)) {
|
|
488
|
-
filtered.push(arr[i]);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
return ok(filtered);
|
|
492
|
-
}
|
|
493
|
-
function evaluateMap(array, mapper, ctx) {
|
|
494
|
-
const arrayResult = evaluateExpr(array, ctx);
|
|
495
|
-
if (!arrayResult.ok)
|
|
496
|
-
return arrayResult;
|
|
497
|
-
const arr = arrayResult.value;
|
|
498
|
-
if (!Array.isArray(arr))
|
|
499
|
-
return ok([]);
|
|
500
|
-
const mapped = [];
|
|
501
|
-
for (let i = 0; i < arr.length; i++) {
|
|
502
|
-
const itemCtx = withCollectionContext(ctx, arr[i], i, arr);
|
|
503
|
-
const mapResult = evaluateExpr(mapper, itemCtx);
|
|
504
|
-
if (!mapResult.ok)
|
|
505
|
-
return mapResult;
|
|
506
|
-
mapped.push(mapResult.value);
|
|
507
|
-
}
|
|
508
|
-
return ok(mapped);
|
|
509
|
-
}
|
|
510
|
-
function evaluateFind(array, predicate, ctx) {
|
|
511
|
-
const arrayResult = evaluateExpr(array, ctx);
|
|
512
|
-
if (!arrayResult.ok)
|
|
513
|
-
return arrayResult;
|
|
514
|
-
const arr = arrayResult.value;
|
|
515
|
-
if (!Array.isArray(arr))
|
|
516
|
-
return ok(null);
|
|
517
|
-
for (let i = 0; i < arr.length; i++) {
|
|
518
|
-
const itemCtx = withCollectionContext(ctx, arr[i], i, arr);
|
|
519
|
-
const predicateResult = evaluateExpr(predicate, itemCtx);
|
|
520
|
-
if (!predicateResult.ok)
|
|
521
|
-
return predicateResult;
|
|
522
|
-
if (toBoolean(predicateResult.value)) {
|
|
523
|
-
return ok(arr[i]);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
return ok(null);
|
|
527
|
-
}
|
|
528
|
-
function evaluateEvery(array, predicate, ctx) {
|
|
529
|
-
const arrayResult = evaluateExpr(array, ctx);
|
|
530
|
-
if (!arrayResult.ok)
|
|
531
|
-
return arrayResult;
|
|
532
|
-
const arr = arrayResult.value;
|
|
533
|
-
if (!Array.isArray(arr))
|
|
534
|
-
return ok(true);
|
|
535
|
-
for (let i = 0; i < arr.length; i++) {
|
|
536
|
-
const itemCtx = withCollectionContext(ctx, arr[i], i, arr);
|
|
537
|
-
const predicateResult = evaluateExpr(predicate, itemCtx);
|
|
538
|
-
if (!predicateResult.ok)
|
|
539
|
-
return predicateResult;
|
|
540
|
-
if (!toBoolean(predicateResult.value)) {
|
|
541
|
-
return ok(false);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
return ok(true);
|
|
545
|
-
}
|
|
546
|
-
function evaluateSome(array, predicate, ctx) {
|
|
547
|
-
const arrayResult = evaluateExpr(array, ctx);
|
|
548
|
-
if (!arrayResult.ok)
|
|
549
|
-
return arrayResult;
|
|
550
|
-
const arr = arrayResult.value;
|
|
551
|
-
if (!Array.isArray(arr))
|
|
552
|
-
return ok(false);
|
|
553
|
-
for (let i = 0; i < arr.length; i++) {
|
|
554
|
-
const itemCtx = withCollectionContext(ctx, arr[i], i, arr);
|
|
555
|
-
const predicateResult = evaluateExpr(predicate, itemCtx);
|
|
556
|
-
if (!predicateResult.ok)
|
|
557
|
-
return predicateResult;
|
|
558
|
-
if (toBoolean(predicateResult.value)) {
|
|
559
|
-
return ok(true);
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
return ok(false);
|
|
563
|
-
}
|
|
564
|
-
function evaluateAppend(array, items, ctx) {
|
|
565
|
-
const arrayResult = evaluateExpr(array, ctx);
|
|
566
|
-
if (!arrayResult.ok)
|
|
567
|
-
return arrayResult;
|
|
568
|
-
const arr = arrayResult.value;
|
|
569
|
-
const baseArray = Array.isArray(arr) ? [...arr] : [];
|
|
570
|
-
for (const itemExpr of items) {
|
|
571
|
-
const itemResult = evaluateExpr(itemExpr, ctx);
|
|
572
|
-
if (!itemResult.ok)
|
|
573
|
-
return itemResult;
|
|
574
|
-
baseArray.push(itemResult.value);
|
|
575
|
-
}
|
|
576
|
-
return ok(baseArray);
|
|
577
|
-
}
|
|
578
|
-
// ============ Object ============
|
|
579
|
-
function evaluateObject(fields, ctx) {
|
|
580
|
-
const result = {};
|
|
581
|
-
for (const [key, valueExpr] of Object.entries(fields)) {
|
|
582
|
-
const valueResult = evaluateExpr(valueExpr, ctx);
|
|
583
|
-
if (!valueResult.ok)
|
|
584
|
-
return valueResult;
|
|
585
|
-
result[key] = valueResult.value;
|
|
586
|
-
}
|
|
587
|
-
return ok(result);
|
|
588
|
-
}
|
|
589
|
-
function evaluateField(objectExpr, property, ctx) {
|
|
590
|
-
const result = evaluateExpr(objectExpr, ctx);
|
|
591
|
-
if (!result.ok)
|
|
592
|
-
return result;
|
|
593
|
-
const obj = result.value;
|
|
594
|
-
if (typeof obj !== "object" || obj === null || Array.isArray(obj))
|
|
595
|
-
return ok(null);
|
|
596
|
-
return ok(obj[property] ?? null);
|
|
597
|
-
}
|
|
598
|
-
function evaluateKeys(obj, ctx) {
|
|
599
|
-
const result = evaluateExpr(obj, ctx);
|
|
600
|
-
if (!result.ok)
|
|
601
|
-
return result;
|
|
602
|
-
const value = result.value;
|
|
603
|
-
if (typeof value !== "object" || value === null)
|
|
604
|
-
return ok([]);
|
|
605
|
-
return ok(Object.keys(value));
|
|
606
|
-
}
|
|
607
|
-
function evaluateValues(obj, ctx) {
|
|
608
|
-
const result = evaluateExpr(obj, ctx);
|
|
609
|
-
if (!result.ok)
|
|
610
|
-
return result;
|
|
611
|
-
const value = result.value;
|
|
612
|
-
if (typeof value !== "object" || value === null)
|
|
613
|
-
return ok([]);
|
|
614
|
-
return ok(Object.values(value));
|
|
615
|
-
}
|
|
616
|
-
function evaluateEntries(obj, ctx) {
|
|
617
|
-
const result = evaluateExpr(obj, ctx);
|
|
618
|
-
if (!result.ok)
|
|
619
|
-
return result;
|
|
620
|
-
const value = result.value;
|
|
621
|
-
if (typeof value !== "object" || value === null)
|
|
622
|
-
return ok([]);
|
|
623
|
-
return ok(Object.entries(value));
|
|
624
|
-
}
|
|
625
|
-
function evaluateMerge(objects, ctx) {
|
|
626
|
-
const merged = {};
|
|
627
|
-
for (const objExpr of objects) {
|
|
628
|
-
const result = evaluateExpr(objExpr, ctx);
|
|
629
|
-
if (!result.ok)
|
|
630
|
-
return result;
|
|
631
|
-
const value = result.value;
|
|
632
|
-
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
633
|
-
Object.assign(merged, value);
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
return ok(merged);
|
|
637
|
-
}
|
|
638
|
-
// ============ Type ============
|
|
639
|
-
function evaluateTypeof(arg, ctx) {
|
|
640
|
-
const result = evaluateExpr(arg, ctx);
|
|
641
|
-
if (!result.ok)
|
|
642
|
-
return result;
|
|
643
|
-
const value = result.value;
|
|
644
|
-
if (value === null)
|
|
645
|
-
return ok("null");
|
|
646
|
-
if (Array.isArray(value))
|
|
647
|
-
return ok("array");
|
|
648
|
-
return ok(typeof value);
|
|
649
|
-
}
|
|
650
|
-
function evaluateIsNull(arg, ctx) {
|
|
651
|
-
const result = evaluateExpr(arg, ctx);
|
|
652
|
-
if (!result.ok)
|
|
653
|
-
return result;
|
|
654
|
-
return ok(result.value === null || result.value === undefined);
|
|
655
|
-
}
|
|
656
|
-
function evaluateCoalesce(args, ctx) {
|
|
657
|
-
for (const arg of args) {
|
|
658
|
-
const result = evaluateExpr(arg, ctx);
|
|
659
|
-
if (!result.ok)
|
|
660
|
-
return result;
|
|
661
|
-
if (result.value !== null && result.value !== undefined) {
|
|
662
|
-
return result;
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
return ok(null);
|
|
666
|
-
}
|
|
667
|
-
//# sourceMappingURL=expr.js.map
|