@tekki-forge/expression 0.0.0-stage → 0.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 +4 -2
- package/dist/ast.d.ts +56 -0
- package/dist/ast.js +12 -0
- package/dist/ast.js.map +1 -0
- package/dist/evaluate.d.ts +15 -0
- package/dist/evaluate.js +443 -0
- package/dist/evaluate.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.d.ts +3 -0
- package/dist/parser.js +323 -0
- package/dist/parser.js.map +1 -0
- package/dist/references.d.ts +11 -0
- package/dist/references.js +42 -0
- package/dist/references.js.map +1 -0
- package/dist/typecheck.d.ts +22 -0
- package/dist/typecheck.js +362 -0
- package/dist/typecheck.js.map +1 -0
- package/dist/values.d.ts +18 -0
- package/dist/values.js +84 -0
- package/dist/values.js.map +1 -0
- package/package.json +35 -3
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { ExpressionError } from "./ast.js";
|
|
2
|
+
const MAX_AST_DEPTH = 5000;
|
|
3
|
+
const isNumeric = (t) => t === "number" || t === "decimal" || t === "any";
|
|
4
|
+
const isDateLike = (t) => t === "date" || t === "datetime" || t === "any";
|
|
5
|
+
/** Common type of two types, or null when incompatible. */
|
|
6
|
+
export function unify(a, b) {
|
|
7
|
+
if (a === "any")
|
|
8
|
+
return b;
|
|
9
|
+
if (b === "any")
|
|
10
|
+
return a;
|
|
11
|
+
if (a === b)
|
|
12
|
+
return a;
|
|
13
|
+
if ((a === "number" || a === "decimal") && (b === "number" || b === "decimal"))
|
|
14
|
+
return "decimal";
|
|
15
|
+
if ((a === "date" || a === "datetime") && (b === "date" || b === "datetime"))
|
|
16
|
+
return "datetime";
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
function comparable(a, b, ordering) {
|
|
20
|
+
const u = unify(a, b);
|
|
21
|
+
if (u === null)
|
|
22
|
+
return false;
|
|
23
|
+
if (ordering && u === "boolean")
|
|
24
|
+
return false;
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
function knownList(rec) {
|
|
28
|
+
const keys = Object.keys(rec);
|
|
29
|
+
return keys.length ? keys.join(", ") : "(none)";
|
|
30
|
+
}
|
|
31
|
+
function arityText(min, max) {
|
|
32
|
+
if (min === max)
|
|
33
|
+
return `${min} argument${min === 1 ? "" : "s"}`;
|
|
34
|
+
if (max === Infinity)
|
|
35
|
+
return `at least ${min} argument${min === 1 ? "" : "s"}`;
|
|
36
|
+
return `${min}–${max} arguments`;
|
|
37
|
+
}
|
|
38
|
+
function argError(node, index, expected, got) {
|
|
39
|
+
const pos = node.args[index]?.pos ?? node.pos;
|
|
40
|
+
throw new ExpressionError(`Function ${node.name} expects ${expected} as argument ${index + 1}, got ${got} at ${pos}`, pos);
|
|
41
|
+
}
|
|
42
|
+
function requireNumeric(node, args, i) {
|
|
43
|
+
if (!isNumeric(args[i]))
|
|
44
|
+
argError(node, i, "a number", args[i]);
|
|
45
|
+
}
|
|
46
|
+
function requireString(node, args, i) {
|
|
47
|
+
if (args[i] !== "string" && args[i] !== "any")
|
|
48
|
+
argError(node, i, "a string", args[i]);
|
|
49
|
+
}
|
|
50
|
+
function requireDate(node, args, i) {
|
|
51
|
+
if (!isDateLike(args[i]))
|
|
52
|
+
argError(node, i, "a date", args[i]);
|
|
53
|
+
}
|
|
54
|
+
function unifyAll(node, args) {
|
|
55
|
+
let t = "any";
|
|
56
|
+
for (let i = 0; i < args.length; i++) {
|
|
57
|
+
const u = unify(t, args[i]);
|
|
58
|
+
if (u === null) {
|
|
59
|
+
const pos = node.args[i].pos;
|
|
60
|
+
throw new ExpressionError(`Function ${node.name} arguments have incompatible types: ${t} and ${args[i]} at ${pos}`, pos);
|
|
61
|
+
}
|
|
62
|
+
t = u;
|
|
63
|
+
}
|
|
64
|
+
return t;
|
|
65
|
+
}
|
|
66
|
+
const numericUnary = {
|
|
67
|
+
min: 1,
|
|
68
|
+
max: 1,
|
|
69
|
+
check(args, node) {
|
|
70
|
+
requireNumeric(node, args, 0);
|
|
71
|
+
return args[0];
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
const stringUnary = {
|
|
75
|
+
min: 1,
|
|
76
|
+
max: 1,
|
|
77
|
+
check(args, node) {
|
|
78
|
+
requireString(node, args, 0);
|
|
79
|
+
return "string";
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
const datePart = {
|
|
83
|
+
min: 1,
|
|
84
|
+
max: 1,
|
|
85
|
+
check(args, node) {
|
|
86
|
+
requireDate(node, args, 0);
|
|
87
|
+
return "number";
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
const scalarMinMax = {
|
|
91
|
+
min: 2,
|
|
92
|
+
max: Infinity,
|
|
93
|
+
check(args, node) {
|
|
94
|
+
const t = unifyAll(node, args);
|
|
95
|
+
if (t === "boolean") {
|
|
96
|
+
throw new ExpressionError(`Function ${node.name} cannot compare boolean values at ${node.pos}`, node.pos);
|
|
97
|
+
}
|
|
98
|
+
return t;
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
export const FUNCTIONS = new Map([
|
|
102
|
+
[
|
|
103
|
+
"round",
|
|
104
|
+
{
|
|
105
|
+
min: 1,
|
|
106
|
+
max: 2,
|
|
107
|
+
check(args, node) {
|
|
108
|
+
requireNumeric(node, args, 0);
|
|
109
|
+
if (args.length > 1 && args[1] !== "number" && args[1] !== "any")
|
|
110
|
+
argError(node, 1, "a number", args[1]);
|
|
111
|
+
return args[0];
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
["floor", numericUnary],
|
|
116
|
+
["ceil", numericUnary],
|
|
117
|
+
["abs", numericUnary],
|
|
118
|
+
["min", scalarMinMax],
|
|
119
|
+
["max", scalarMinMax],
|
|
120
|
+
[
|
|
121
|
+
"coalesce",
|
|
122
|
+
{
|
|
123
|
+
min: 1,
|
|
124
|
+
max: Infinity,
|
|
125
|
+
check: (args, node) => unifyAll(node, args),
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
["concat", { min: 1, max: Infinity, check: () => "string" }],
|
|
129
|
+
["upper", stringUnary],
|
|
130
|
+
["lower", stringUnary],
|
|
131
|
+
["trim", stringUnary],
|
|
132
|
+
[
|
|
133
|
+
"length",
|
|
134
|
+
{
|
|
135
|
+
min: 1,
|
|
136
|
+
max: 1,
|
|
137
|
+
check(args, node) {
|
|
138
|
+
requireString(node, args, 0);
|
|
139
|
+
return "number";
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
[
|
|
144
|
+
"if",
|
|
145
|
+
{
|
|
146
|
+
min: 3,
|
|
147
|
+
max: 3,
|
|
148
|
+
check(args, node) {
|
|
149
|
+
if (args[0] !== "boolean" && args[0] !== "any")
|
|
150
|
+
argError(node, 0, "a boolean condition", args[0]);
|
|
151
|
+
const u = unify(args[1], args[2]);
|
|
152
|
+
if (u === null) {
|
|
153
|
+
throw new ExpressionError(`Function if branches have incompatible types: ${args[1]} and ${args[2]} at ${node.pos}`, node.pos);
|
|
154
|
+
}
|
|
155
|
+
return u;
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
["now", { min: 0, max: 0, check: () => "datetime" }],
|
|
160
|
+
["today", { min: 0, max: 0, check: () => "date" }],
|
|
161
|
+
[
|
|
162
|
+
"days_between",
|
|
163
|
+
{
|
|
164
|
+
min: 2,
|
|
165
|
+
max: 2,
|
|
166
|
+
check(args, node) {
|
|
167
|
+
requireDate(node, args, 0);
|
|
168
|
+
requireDate(node, args, 1);
|
|
169
|
+
return "number";
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
[
|
|
174
|
+
"add_days",
|
|
175
|
+
{
|
|
176
|
+
min: 2,
|
|
177
|
+
max: 2,
|
|
178
|
+
check(args, node) {
|
|
179
|
+
requireDate(node, args, 0);
|
|
180
|
+
requireNumeric(node, args, 1);
|
|
181
|
+
return args[0];
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
["year", datePart],
|
|
186
|
+
["month", datePart],
|
|
187
|
+
["day", datePart],
|
|
188
|
+
]);
|
|
189
|
+
const AGGREGATE_NAMES = ["sum", "avg", "count"];
|
|
190
|
+
const OP_VERB = {
|
|
191
|
+
"+": ["add", "and"],
|
|
192
|
+
"-": ["subtract", "and"],
|
|
193
|
+
"*": ["multiply", "and"],
|
|
194
|
+
"/": ["divide", "by"],
|
|
195
|
+
"%": ["compute modulo of", "and"],
|
|
196
|
+
};
|
|
197
|
+
function checkBinary(e, l, r) {
|
|
198
|
+
switch (e.op) {
|
|
199
|
+
case "+":
|
|
200
|
+
case "-":
|
|
201
|
+
case "*":
|
|
202
|
+
case "/":
|
|
203
|
+
case "%": {
|
|
204
|
+
if (!isNumeric(l) || !isNumeric(r)) {
|
|
205
|
+
const [verb, joiner] = OP_VERB[e.op];
|
|
206
|
+
const hint = e.op === "+" && (l === "string" || r === "string") ? ' (use concat() to join strings)' : "";
|
|
207
|
+
throw new ExpressionError(`Cannot ${verb} ${l} ${joiner} ${r}${hint} at ${e.pos}`, e.pos);
|
|
208
|
+
}
|
|
209
|
+
if (l === "decimal" || r === "decimal")
|
|
210
|
+
return "decimal";
|
|
211
|
+
if (l === "number" && r === "number")
|
|
212
|
+
return "number";
|
|
213
|
+
return "any";
|
|
214
|
+
}
|
|
215
|
+
case "==":
|
|
216
|
+
case "!=":
|
|
217
|
+
case "<":
|
|
218
|
+
case "<=":
|
|
219
|
+
case ">":
|
|
220
|
+
case ">=": {
|
|
221
|
+
const ordering = e.op !== "==" && e.op !== "!=";
|
|
222
|
+
if (!comparable(l, r, ordering)) {
|
|
223
|
+
throw new ExpressionError(`Cannot compare ${l} and ${r} with "${e.op}" at ${e.pos}`, e.pos);
|
|
224
|
+
}
|
|
225
|
+
return "boolean";
|
|
226
|
+
}
|
|
227
|
+
case "and":
|
|
228
|
+
case "or": {
|
|
229
|
+
if ((l !== "boolean" && l !== "any") || (r !== "boolean" && r !== "any")) {
|
|
230
|
+
throw new ExpressionError(`Operator ${e.op} expects boolean operands, got ${l} and ${r} at ${e.pos}`, e.pos);
|
|
231
|
+
}
|
|
232
|
+
return "boolean";
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function infer(e, env, depth) {
|
|
237
|
+
if (depth > MAX_AST_DEPTH)
|
|
238
|
+
throw new ExpressionError("Expression is nested too deeply");
|
|
239
|
+
if (typeof e !== "object" || e === null)
|
|
240
|
+
throw new ExpressionError("Malformed expression node");
|
|
241
|
+
let t;
|
|
242
|
+
switch (e.kind) {
|
|
243
|
+
case "literal": {
|
|
244
|
+
const v = e.value;
|
|
245
|
+
t =
|
|
246
|
+
v === null
|
|
247
|
+
? "any"
|
|
248
|
+
: typeof v === "number"
|
|
249
|
+
? "number"
|
|
250
|
+
: typeof v === "string"
|
|
251
|
+
? "string"
|
|
252
|
+
: typeof v === "boolean"
|
|
253
|
+
? "boolean"
|
|
254
|
+
: bad();
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
case "field": {
|
|
258
|
+
if (!Object.hasOwn(env.fields, e.name)) {
|
|
259
|
+
throw new ExpressionError(`Unknown field "${e.name}" at ${e.pos} — known fields: ${knownList(env.fields)}`, e.pos);
|
|
260
|
+
}
|
|
261
|
+
t = env.fields[e.name];
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
case "unary": {
|
|
265
|
+
const o = infer(e.operand, env, depth + 1);
|
|
266
|
+
if (e.op === "-") {
|
|
267
|
+
if (!isNumeric(o))
|
|
268
|
+
throw new ExpressionError(`Cannot negate ${o} at ${e.pos}`, e.pos);
|
|
269
|
+
t = o;
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
if (o !== "boolean" && o !== "any") {
|
|
273
|
+
throw new ExpressionError(`Operator not expects a boolean, got ${o} at ${e.pos}`, e.pos);
|
|
274
|
+
}
|
|
275
|
+
t = "boolean";
|
|
276
|
+
}
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
case "binary": {
|
|
280
|
+
const l = infer(e.left, env, depth + 1);
|
|
281
|
+
const r = infer(e.right, env, depth + 1);
|
|
282
|
+
t = checkBinary(e, l, r);
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
case "call": {
|
|
286
|
+
const spec = FUNCTIONS.get(e.name);
|
|
287
|
+
if (!spec) {
|
|
288
|
+
if (AGGREGATE_NAMES.includes(e.name)) {
|
|
289
|
+
throw new ExpressionError(`Aggregate ${e.name} expects a relation field argument, e.g. ${e.name}(lines.amount), at ${e.pos}`, e.pos);
|
|
290
|
+
}
|
|
291
|
+
throw new ExpressionError(`Unknown function "${e.name}" at ${e.pos} — known functions: ${[...FUNCTIONS.keys(), ...AGGREGATE_NAMES].join(", ")}`, e.pos);
|
|
292
|
+
}
|
|
293
|
+
if (!Array.isArray(e.args))
|
|
294
|
+
bad();
|
|
295
|
+
if (e.args.length < spec.min || e.args.length > spec.max) {
|
|
296
|
+
const extra = (e.name === "min" || e.name === "max") && e.args.length < 2
|
|
297
|
+
? ` (or a single relation field for the aggregate form, e.g. ${e.name}(lines.amount))`
|
|
298
|
+
: "";
|
|
299
|
+
throw new ExpressionError(`Function ${e.name} expects ${arityText(spec.min, spec.max)}${extra}, got ${e.args.length} at ${e.pos}`, e.pos);
|
|
300
|
+
}
|
|
301
|
+
const argTypes = e.args.map((a) => infer(a, env, depth + 1));
|
|
302
|
+
t = spec.check(argTypes, e);
|
|
303
|
+
break;
|
|
304
|
+
}
|
|
305
|
+
case "aggregate": {
|
|
306
|
+
const rels = env.relations ?? {};
|
|
307
|
+
if (!Object.hasOwn(rels, e.relation)) {
|
|
308
|
+
throw new ExpressionError(`Unknown relation "${e.relation}" at ${e.pos} — known relations: ${knownList(rels)}`, e.pos);
|
|
309
|
+
}
|
|
310
|
+
const relFields = rels[e.relation];
|
|
311
|
+
if (e.field === null) {
|
|
312
|
+
if (e.fn !== "count") {
|
|
313
|
+
throw new ExpressionError(`Aggregate ${e.fn} requires a field, e.g. ${e.fn}(${e.relation}.amount), at ${e.pos}`, e.pos);
|
|
314
|
+
}
|
|
315
|
+
t = "number";
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
if (!Object.hasOwn(relFields, e.field)) {
|
|
319
|
+
throw new ExpressionError(`Unknown field "${e.field}" on relation "${e.relation}" at ${e.pos} — known fields: ${knownList(relFields)}`, e.pos);
|
|
320
|
+
}
|
|
321
|
+
const ft = relFields[e.field];
|
|
322
|
+
switch (e.fn) {
|
|
323
|
+
case "count":
|
|
324
|
+
t = "number";
|
|
325
|
+
break;
|
|
326
|
+
case "sum":
|
|
327
|
+
case "avg":
|
|
328
|
+
if (!isNumeric(ft)) {
|
|
329
|
+
throw new ExpressionError(`Aggregate ${e.fn} requires a numeric field, but ${e.relation}.${e.field} is ${ft} at ${e.pos}`, e.pos);
|
|
330
|
+
}
|
|
331
|
+
t = ft;
|
|
332
|
+
break;
|
|
333
|
+
case "min":
|
|
334
|
+
case "max":
|
|
335
|
+
if (ft === "boolean") {
|
|
336
|
+
throw new ExpressionError(`Aggregate ${e.fn} cannot be applied to boolean field ${e.relation}.${e.field} at ${e.pos}`, e.pos);
|
|
337
|
+
}
|
|
338
|
+
t = ft;
|
|
339
|
+
break;
|
|
340
|
+
default:
|
|
341
|
+
bad();
|
|
342
|
+
}
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
default:
|
|
346
|
+
bad();
|
|
347
|
+
}
|
|
348
|
+
e.type = t;
|
|
349
|
+
return t;
|
|
350
|
+
}
|
|
351
|
+
function bad() {
|
|
352
|
+
throw new ExpressionError("Malformed expression node");
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Infer (and validate) the static type of an expression.
|
|
356
|
+
* Side effect: annotates every node with its `type`, which `evaluate()` then uses to pick
|
|
357
|
+
* decimal vs. number arithmetic and date handling.
|
|
358
|
+
*/
|
|
359
|
+
export function inferType(expr, env) {
|
|
360
|
+
return infer(expr, env, 0);
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=typecheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typecheck.js","sourceRoot":"","sources":["../src/typecheck.ts"],"names":[],"mappings":"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"}
|
package/dist/values.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import DecimalDefault from "decimal.js";
|
|
2
|
+
import type { Decimal } from "decimal.js";
|
|
3
|
+
/** Private Decimal constructor: 40 significant digits, half-away-from-zero, truncated modulo (like JS %). */
|
|
4
|
+
export declare const D: typeof DecimalDefault.Decimal;
|
|
5
|
+
export type Dec = Decimal;
|
|
6
|
+
/** Objects such as decimal.js / Prisma Decimal instances that carry their value in toString(). */
|
|
7
|
+
export declare function isDecimalLike(v: unknown): v is {
|
|
8
|
+
toString(): string;
|
|
9
|
+
};
|
|
10
|
+
export declare function toDec(v: unknown): Dec | null;
|
|
11
|
+
export declare function decToString(d: Dec): string;
|
|
12
|
+
export declare function toNum(v: unknown): number | null;
|
|
13
|
+
export declare function toDate(v: unknown): Date | null;
|
|
14
|
+
/**
|
|
15
|
+
* Normalize a decimal-ish value (number, numeric string, bigint, Decimal-like object) into a plain
|
|
16
|
+
* decimal string without exponent notation, e.g. "12.5", "0.0001", "-3". Returns null if not numeric.
|
|
17
|
+
*/
|
|
18
|
+
export declare function toDecimalString(v: unknown): string | null;
|
package/dist/values.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import DecimalDefault from "decimal.js";
|
|
2
|
+
// decimal.js ships ESM-style typings in a CommonJS-typed package; under NodeNext the default import is
|
|
3
|
+
// typed as the module namespace. At runtime (ESM) the default export is the constructor itself.
|
|
4
|
+
const DecimalCtor = (DecimalDefault.default ??
|
|
5
|
+
DecimalDefault);
|
|
6
|
+
/** Private Decimal constructor: 40 significant digits, half-away-from-zero, truncated modulo (like JS %). */
|
|
7
|
+
export const D = DecimalCtor.clone({
|
|
8
|
+
precision: 40,
|
|
9
|
+
rounding: DecimalCtor.ROUND_HALF_UP,
|
|
10
|
+
modulo: DecimalCtor.ROUND_DOWN,
|
|
11
|
+
toExpNeg: -9e15,
|
|
12
|
+
toExpPos: 9e15,
|
|
13
|
+
});
|
|
14
|
+
const NUMERIC_RE = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/;
|
|
15
|
+
/** Objects such as decimal.js / Prisma Decimal instances that carry their value in toString(). */
|
|
16
|
+
export function isDecimalLike(v) {
|
|
17
|
+
return (typeof v === "object" &&
|
|
18
|
+
v !== null &&
|
|
19
|
+
!(v instanceof Date) &&
|
|
20
|
+
!Array.isArray(v) &&
|
|
21
|
+
typeof v.toString === "function" &&
|
|
22
|
+
v.toString !== Object.prototype.toString);
|
|
23
|
+
}
|
|
24
|
+
export function toDec(v) {
|
|
25
|
+
let s;
|
|
26
|
+
if (typeof v === "number") {
|
|
27
|
+
if (!Number.isFinite(v))
|
|
28
|
+
return null;
|
|
29
|
+
return new D(v);
|
|
30
|
+
}
|
|
31
|
+
else if (typeof v === "bigint") {
|
|
32
|
+
s = v.toString();
|
|
33
|
+
}
|
|
34
|
+
else if (typeof v === "string") {
|
|
35
|
+
s = v.trim();
|
|
36
|
+
}
|
|
37
|
+
else if (isDecimalLike(v)) {
|
|
38
|
+
s = String(v.toString()).trim();
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
if (!NUMERIC_RE.test(s))
|
|
44
|
+
return null;
|
|
45
|
+
const d = new D(s);
|
|
46
|
+
return d.isFinite() ? d : null;
|
|
47
|
+
}
|
|
48
|
+
export function decToString(d) {
|
|
49
|
+
return d.isZero() ? "0" : d.toFixed();
|
|
50
|
+
}
|
|
51
|
+
export function toNum(v) {
|
|
52
|
+
if (typeof v === "number")
|
|
53
|
+
return Number.isFinite(v) ? v : null;
|
|
54
|
+
if (typeof v === "bigint")
|
|
55
|
+
return Number(v);
|
|
56
|
+
if (typeof v === "string" || isDecimalLike(v)) {
|
|
57
|
+
const s = String(v.toString()).trim();
|
|
58
|
+
if (!NUMERIC_RE.test(s))
|
|
59
|
+
return null;
|
|
60
|
+
const n = Number(s);
|
|
61
|
+
return Number.isFinite(n) ? n : null;
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
export function toDate(v) {
|
|
66
|
+
if (v instanceof Date)
|
|
67
|
+
return Number.isNaN(v.getTime()) ? null : v;
|
|
68
|
+
if (typeof v === "string") {
|
|
69
|
+
const t = Date.parse(v.trim());
|
|
70
|
+
return Number.isNaN(t) ? null : new Date(t);
|
|
71
|
+
}
|
|
72
|
+
if (typeof v === "number" && Number.isFinite(v))
|
|
73
|
+
return new Date(v);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Normalize a decimal-ish value (number, numeric string, bigint, Decimal-like object) into a plain
|
|
78
|
+
* decimal string without exponent notation, e.g. "12.5", "0.0001", "-3". Returns null if not numeric.
|
|
79
|
+
*/
|
|
80
|
+
export function toDecimalString(v) {
|
|
81
|
+
const d = toDec(v);
|
|
82
|
+
return d ? decToString(d) : null;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"values.js","sourceRoot":"","sources":["../src/values.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,YAAY,CAAC;AAGxC,uGAAuG;AACvG,gGAAgG;AAChG,MAAM,WAAW,GAAG,CAAE,cAA0D,CAAC,OAAO;IACtF,cAAc,CAA8B,CAAC;AAE/C,6GAA6G;AAC7G,MAAM,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC;IACjC,SAAS,EAAE,EAAE;IACb,QAAQ,EAAE,WAAW,CAAC,aAAa;IACnC,MAAM,EAAE,WAAW,CAAC,UAAU;IAC9B,QAAQ,EAAE,CAAC,IAAI;IACf,QAAQ,EAAE,IAAI;CACf,CAAC,CAAC;AAGH,MAAM,UAAU,GAAG,iDAAiD,CAAC;AAErE,kGAAkG;AAClG,MAAM,UAAU,aAAa,CAAC,CAAU;IACtC,OAAO,CACL,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,KAAK,IAAI;QACV,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC;QACpB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACjB,OAAQ,CAA4B,CAAC,QAAQ,KAAK,UAAU;QAC3D,CAA2B,CAAC,QAAQ,KAAK,MAAM,CAAC,SAAS,CAAC,QAAQ,CACpE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,CAAU;IAC9B,IAAI,CAAS,CAAC;IACd,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACrC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;SAAM,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QACjC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;IACnB,CAAC;SAAM,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QACjC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACf,CAAC;SAAM,IAAI,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5B,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACnB,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAAM;IAChC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,CAAU;IAC9B,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACrC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,CAAU;IAC/B,IAAI,CAAC,YAAY,IAAI;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,CAAU;IACxC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACnB,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACnC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekki-forge/expression",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Safe expression language for Forge computed fields (parser, type checker, evaluator)",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"code-generator",
|
|
7
|
+
"forge",
|
|
8
|
+
"full-stack",
|
|
9
|
+
"tekki-forge"
|
|
10
|
+
],
|
|
11
|
+
"author": "Mahy KANE",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=22"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"decimal.js": "^10.6.0"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc -p tsconfig.json",
|
|
36
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
37
|
+
}
|
|
6
38
|
}
|