@ai-matrx/records 0.82.1 → 0.83.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/CHANGELOG.md +12 -0
- package/dist/memory/index.cjs +2 -0
- package/dist/memory/index.cjs.map +1 -1
- package/dist/memory/index.js +2 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/templates/index.cjs +29 -134
- package/dist/templates/index.cjs.map +1 -1
- package/dist/templates/index.d.cts +9 -5
- package/dist/templates/index.d.ts +9 -5
- package/dist/templates/index.js +29 -134
- package/dist/templates/index.js.map +1 -1
- package/package.json +3 -3
package/dist/templates/index.cjs
CHANGED
|
@@ -30,7 +30,7 @@ __export(templates_exports, {
|
|
|
30
30
|
DEFAULT_TEMPLATE_AGENT: () => DEFAULT_TEMPLATE_AGENT,
|
|
31
31
|
DESIGNATED_REAL_NUMBERS: () => DESIGNATED_REAL_NUMBERS,
|
|
32
32
|
ENTITY_REFERENCE_KINDS: () => ENTITY_REFERENCE_KINDS,
|
|
33
|
-
|
|
33
|
+
FORMULA_FUNCTION_NAMES: () => FORMULA_FUNCTION_NAMES,
|
|
34
34
|
GALLERY_ONLY: () => GALLERY_ONLY,
|
|
35
35
|
GOOD_OUTCOME: () => GOOD_OUTCOME,
|
|
36
36
|
INDUSTRY_GROUPS: () => INDUSTRY_GROUPS,
|
|
@@ -113,7 +113,7 @@ __export(templates_exports, {
|
|
|
113
113
|
numberedStreet: () => numberedStreet,
|
|
114
114
|
packageDescribeResult: () => packageDescribeResult,
|
|
115
115
|
parseAt: () => parseAt,
|
|
116
|
-
|
|
116
|
+
parseGateFormula: () => parseGateFormula,
|
|
117
117
|
parseNumeric: () => parseNumeric,
|
|
118
118
|
pathOfAt: () => pathOfAt,
|
|
119
119
|
peopleOf: () => peopleOf,
|
|
@@ -492,6 +492,7 @@ var CATALOGUE_STATUSES = ["planned", "authoring", "checking", "waiting_on_lane_1
|
|
|
492
492
|
|
|
493
493
|
// src/templates/validate.ts
|
|
494
494
|
var import_uuid = require("@ai-matrx/kit/uuid");
|
|
495
|
+
var import_formula = require("@ai-matrx/kit/formula");
|
|
495
496
|
|
|
496
497
|
// src/templates/confidential.ts
|
|
497
498
|
var TABLE_KERNEL_ID = "11111111-0000-4000-8000-000000000001";
|
|
@@ -2903,134 +2904,28 @@ function storeFilterMatches(row, filter, _timeZone) {
|
|
|
2903
2904
|
return have === String(want);
|
|
2904
2905
|
});
|
|
2905
2906
|
}
|
|
2906
|
-
var
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
"NOT",
|
|
2929
|
-
"OR",
|
|
2930
|
-
"REGEX_MATCH",
|
|
2931
|
-
"RIGHT",
|
|
2932
|
-
"ROUND",
|
|
2933
|
-
"SUBSTITUTE",
|
|
2934
|
-
"SUM",
|
|
2935
|
-
"SWITCH",
|
|
2936
|
-
"TODAY",
|
|
2937
|
-
"NOW",
|
|
2938
|
-
"TRIM",
|
|
2939
|
-
"UPPER",
|
|
2940
|
-
"WORKDAY",
|
|
2941
|
-
"YEAR"
|
|
2942
|
-
]);
|
|
2943
|
-
function fxTokens(text) {
|
|
2944
|
-
const out = [];
|
|
2945
|
-
let i = 0;
|
|
2946
|
-
while (i < text.length) {
|
|
2947
|
-
const c = text[i];
|
|
2948
|
-
if (/\s/.test(c)) i += 1;
|
|
2949
|
-
else if (c === "{") {
|
|
2950
|
-
const j = text.indexOf("}", i);
|
|
2951
|
-
if (j < 0) return "a { has no closing }";
|
|
2952
|
-
out.push({ t: "ref", v: text.slice(i + 1, j).trim() });
|
|
2953
|
-
i = j + 1;
|
|
2954
|
-
} else if (c === "'" || c === '"') {
|
|
2955
|
-
const j = text.indexOf(c, i + 1);
|
|
2956
|
-
if (j < 0) return "a quoted word has no closing quote";
|
|
2957
|
-
out.push({ t: "str", v: text.slice(i + 1, j) });
|
|
2958
|
-
i = j + 1;
|
|
2959
|
-
} else if (/[0-9.]/.test(c)) {
|
|
2960
|
-
const m = /^[0-9]*\.?[0-9]+/.exec(text.slice(i));
|
|
2961
|
-
out.push({ t: "num", v: m[0] });
|
|
2962
|
-
i += m[0].length;
|
|
2963
|
-
} else if (/[A-Za-z_]/.test(c)) {
|
|
2964
|
-
const m = /^[A-Za-z_][A-Za-z_0-9]*/.exec(text.slice(i));
|
|
2965
|
-
out.push({ t: "name", v: m[0] });
|
|
2966
|
-
i += m[0].length;
|
|
2967
|
-
} else if ("+-*/(),%".includes(c)) {
|
|
2968
|
-
out.push({ t: "op", v: c });
|
|
2969
|
-
i += 1;
|
|
2970
|
-
} else return `"${c}" is not part of a formula`;
|
|
2971
|
-
}
|
|
2972
|
-
return out;
|
|
2973
|
-
}
|
|
2974
|
-
function parseFormula(text) {
|
|
2975
|
-
const toks = fxTokens(text);
|
|
2976
|
-
if (typeof toks === "string") return toks;
|
|
2977
|
-
let p = 0;
|
|
2978
|
-
const peek = () => toks[p];
|
|
2979
|
-
const fail = (why) => {
|
|
2980
|
-
throw new Error(why);
|
|
2981
|
-
};
|
|
2982
|
-
const expr = () => {
|
|
2983
|
-
let a = term();
|
|
2984
|
-
while (peek()?.t === "op" && (peek().v === "+" || peek().v === "-")) {
|
|
2985
|
-
const op = toks[p++].v;
|
|
2986
|
-
a = { k: "bin", op, a, b: term() };
|
|
2987
|
-
}
|
|
2988
|
-
return a;
|
|
2989
|
-
};
|
|
2990
|
-
const term = () => {
|
|
2991
|
-
let a = factor();
|
|
2992
|
-
while (peek()?.t === "op" && (peek().v === "*" || peek().v === "/" || peek().v === "%")) {
|
|
2993
|
-
const op = toks[p++].v;
|
|
2994
|
-
a = { k: "bin", op, a, b: factor() };
|
|
2995
|
-
}
|
|
2996
|
-
return a;
|
|
2997
|
-
};
|
|
2998
|
-
const factor = () => {
|
|
2999
|
-
const tk = toks[p++];
|
|
3000
|
-
if (!tk) return fail("the formula ends too early");
|
|
3001
|
-
if (tk.t === "num") return { k: "num", v: parseNumeric(tk.v) };
|
|
3002
|
-
if (tk.t === "str") return { k: "str", v: tk.v };
|
|
3003
|
-
if (tk.t === "ref") return { k: "ref", v: tk.v };
|
|
3004
|
-
if (tk.t === "op" && tk.v === "-") return { k: "neg", a: factor() };
|
|
3005
|
-
if (tk.t === "op" && tk.v === "(") {
|
|
3006
|
-
const e = expr();
|
|
3007
|
-
if (toks[p++]?.v !== ")") fail("a ( has no closing )");
|
|
3008
|
-
return e;
|
|
3009
|
-
}
|
|
3010
|
-
if (tk.t === "name") {
|
|
3011
|
-
const f = tk.v.toUpperCase();
|
|
3012
|
-
if (!FORMULA_FUNCTIONS.has(f)) fail(`${tk.v} is not a formula function the store knows`);
|
|
3013
|
-
if (toks[p++]?.v !== "(") fail(`${f} is followed by its arguments in ( )`);
|
|
3014
|
-
const args = [];
|
|
3015
|
-
if (peek()?.v !== ")") {
|
|
3016
|
-
args.push(expr());
|
|
3017
|
-
while (peek()?.v === ",") {
|
|
3018
|
-
p += 1;
|
|
3019
|
-
args.push(expr());
|
|
3020
|
-
}
|
|
3021
|
-
}
|
|
3022
|
-
if (toks[p++]?.v !== ")") fail(`${f}( has no closing )`);
|
|
3023
|
-
return { k: "call", f, args };
|
|
3024
|
-
}
|
|
3025
|
-
return fail(`"${tk.v}" is out of place`);
|
|
3026
|
-
};
|
|
3027
|
-
try {
|
|
3028
|
-
const e = expr();
|
|
3029
|
-
if (p !== toks.length) return `"${toks[p].v}" is out of place`;
|
|
3030
|
-
return e;
|
|
3031
|
-
} catch (err) {
|
|
3032
|
-
return err.message;
|
|
3033
|
-
}
|
|
2907
|
+
var FORMULA_FUNCTION_NAMES = new Set(import_formula.FORMULA_FUNCTIONS.map((f) => f.name));
|
|
2908
|
+
function toFx(n) {
|
|
2909
|
+
switch (n.kind) {
|
|
2910
|
+
case "number":
|
|
2911
|
+
return { k: "num", v: parseNumeric(n.raw) };
|
|
2912
|
+
case "string":
|
|
2913
|
+
return { k: "str", v: n.value };
|
|
2914
|
+
case "boolean":
|
|
2915
|
+
return { k: "call", f: n.value ? "TRUE" : "FALSE", args: [] };
|
|
2916
|
+
case "reference":
|
|
2917
|
+
return { k: "ref", v: n.name };
|
|
2918
|
+
case "unary":
|
|
2919
|
+
return { k: "neg", a: toFx(n.operand) };
|
|
2920
|
+
case "binary":
|
|
2921
|
+
return { k: "bin", op: n.operator, a: toFx(n.left), b: toFx(n.right) };
|
|
2922
|
+
case "call":
|
|
2923
|
+
return { k: "call", f: n.name, args: n.args.map(toFx) };
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
function parseGateFormula(text) {
|
|
2927
|
+
const parsed = (0, import_formula.parseFormula)(text);
|
|
2928
|
+
return parsed.ok ? toFx(parsed.ast) : parsed.error;
|
|
3034
2929
|
}
|
|
3035
2930
|
function formulaRefs(n) {
|
|
3036
2931
|
if (n.k === "ref") return [n.v];
|
|
@@ -3070,7 +2965,7 @@ function evalFormula(n, valueOf) {
|
|
|
3070
2965
|
if (n.op === "*") return { ok: true, v: q(a.n * b.n, a.d * b.d) };
|
|
3071
2966
|
if (b.n === 0n) return { ok: false, why: "it divides by zero on a row" };
|
|
3072
2967
|
if (n.op === "/") return { ok: true, v: q(a.n * b.d, a.d * b.n) };
|
|
3073
|
-
return { ok: false, why:
|
|
2968
|
+
return { ok: false, why: `${n.op} is not mirrored` };
|
|
3074
2969
|
}
|
|
3075
2970
|
case "call": {
|
|
3076
2971
|
if (n.f === "ABS" && n.args.length === 1) {
|
|
@@ -3813,7 +3708,7 @@ function validateTemplate(raw, options = {}) {
|
|
|
3813
3708
|
return isComputed(pf) ? computedOf(target, pf, { key: far.key, values: far.values }, depth + 1) : { ok: true, v: far.values?.[f.pick] ?? null };
|
|
3814
3709
|
}
|
|
3815
3710
|
if (f.parityType === "formula" && f.formula) {
|
|
3816
|
-
const ast =
|
|
3711
|
+
const ast = parseGateFormula(f.formula);
|
|
3817
3712
|
if (typeof ast === "string") return { ok: false, why: ast };
|
|
3818
3713
|
let why = null;
|
|
3819
3714
|
const r2 = evalFormula(ast, (label2) => {
|
|
@@ -3843,7 +3738,7 @@ function validateTemplate(raw, options = {}) {
|
|
|
3843
3738
|
if (!f) return false;
|
|
3844
3739
|
if (isNumber(f)) return true;
|
|
3845
3740
|
if (f.parityType !== "formula" || !f.formula) return false;
|
|
3846
|
-
const ast =
|
|
3741
|
+
const ast = parseGateFormula(f.formula);
|
|
3847
3742
|
if (typeof ast === "string") return false;
|
|
3848
3743
|
const refsStored = formulaRefs(ast).every((l) => {
|
|
3849
3744
|
const rf = byToken.get(table)?.fields.find((x) => x.label === l);
|
|
@@ -5150,7 +5045,7 @@ function validateTemplate(raw, options = {}) {
|
|
|
5150
5045
|
say(fat, `"${f.label}" is a formula; write it in formula, naming fields in braces: {Total} - {Paid}.`);
|
|
5151
5046
|
continue;
|
|
5152
5047
|
}
|
|
5153
|
-
const ast =
|
|
5048
|
+
const ast = parseGateFormula(f.formula);
|
|
5154
5049
|
if (typeof ast === "string") {
|
|
5155
5050
|
say(fat, `The formula "${f.formula}" cannot be read: ${ast}.`);
|
|
5156
5051
|
continue;
|