@ai-matrx/records 0.72.12 → 0.72.23
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 +66 -0
- package/dist/app-table/index.d.cts +3 -3
- package/dist/app-table/index.d.ts +3 -3
- package/dist/core/index.d.cts +5 -5
- package/dist/core/index.d.ts +5 -5
- package/dist/{declareTable-Br8pE4fr.d.cts → declareTable-CLvpMdgJ.d.cts} +2 -2
- package/dist/{declareTable-DM6z1tc-.d.ts → declareTable-DY3oN4rq.d.ts} +2 -2
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/memory/index.cjs +2681 -0
- package/dist/memory/index.cjs.map +1 -0
- package/dist/memory/index.d.cts +126 -0
- package/dist/memory/index.d.ts +126 -0
- package/dist/memory/index.js +2658 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/{ports-DKBvsoya.d.cts → ports-DKOk7AT2.d.cts} +1 -1
- package/dist/{ports-Bhu2Q3V0.d.ts → ports-Df3VghxK.d.ts} +1 -1
- package/dist/{table-kind-D6Lz7ebE.d.ts → table-kind-CD9B1vtx.d.ts} +1 -1
- package/dist/{table-kind-D6VOew74.d.cts → table-kind-e-g5kGXV.d.cts} +1 -1
- package/dist/templates/index.cjs +59 -24
- package/dist/templates/index.cjs.map +1 -1
- package/dist/templates/index.d.cts +18 -1176
- package/dist/templates/index.d.ts +18 -1176
- package/dist/templates/index.js +59 -24
- package/dist/templates/index.js.map +1 -1
- package/dist/{validate-QtFxMmJc.d.ts → types-Ba11aOEO.d.ts} +1 -42
- package/dist/{validate-DUSrx-9E.d.cts → types-BtEKp3ot.d.cts} +1 -42
- package/dist/types-DxVoKKpL.d.ts +1186 -0
- package/dist/types-dlj1-2t2.d.cts +1186 -0
- package/dist/use-cases/index.d.cts +3 -2
- package/dist/use-cases/index.d.ts +3 -2
- package/dist/validate-CMb7R_ke.d.cts +44 -0
- package/dist/validate-E-g4LAZ6.d.ts +44 -0
- package/package.json +13 -1
package/dist/templates/index.js
CHANGED
|
@@ -3463,6 +3463,12 @@ function validateTemplate(raw, options = {}) {
|
|
|
3463
3463
|
seedLooks.add(p);
|
|
3464
3464
|
problems.push(p);
|
|
3465
3465
|
};
|
|
3466
|
+
const galleryBar = /* @__PURE__ */ new WeakSet();
|
|
3467
|
+
const sayGallery = (at, says) => {
|
|
3468
|
+
const p = { at, says };
|
|
3469
|
+
galleryBar.add(p);
|
|
3470
|
+
problems.push(p);
|
|
3471
|
+
};
|
|
3466
3472
|
const tz = raw.business?.timezone || "UTC";
|
|
3467
3473
|
const tablesRaw = allTables(raw);
|
|
3468
3474
|
const ISO_DAY = /\b\d{4}-\d{2}-\d{2}\b/;
|
|
@@ -3785,7 +3791,7 @@ function validateTemplate(raw, options = {}) {
|
|
|
3785
3791
|
say(`${tat}.rows`, `Only ${titles.size} of ${table.rows.length} rows have a title of their own; a list of look-alike names reads as generated.`);
|
|
3786
3792
|
}
|
|
3787
3793
|
});
|
|
3788
|
-
if (!hasLookupOrRollup)
|
|
3794
|
+
if (!hasLookupOrRollup) sayGallery("tables", "At least one relationship has to be read across: add a lookup or a rollup through a relation field.");
|
|
3789
3795
|
if (main) {
|
|
3790
3796
|
const normTitle = (v) => (storeText(v) ?? "").toLowerCase().replace(/\s+/g, " ").trim();
|
|
3791
3797
|
const rows = main.rows;
|
|
@@ -3853,8 +3859,8 @@ function validateTemplate(raw, options = {}) {
|
|
|
3853
3859
|
else surfaces.set(token, { at, ...table ? { table } : {} });
|
|
3854
3860
|
};
|
|
3855
3861
|
const views = spec.views ?? [];
|
|
3856
|
-
if (views.length < 3)
|
|
3857
|
-
if (!views.some((v) => v.kind === "grid"))
|
|
3862
|
+
if (views.length < 3) sayGallery("views", `A template shows at least three views; this one has ${views.length}.`);
|
|
3863
|
+
if (!views.some((v) => v.kind === "grid")) sayGallery("views", "One of the views is a grid \u2014 the table everyone recognises.");
|
|
3858
3864
|
views.forEach((view, i) => {
|
|
3859
3865
|
const at = `views[${i}] (${view.token})`;
|
|
3860
3866
|
claim(view.token, at, view.table);
|
|
@@ -3980,7 +3986,7 @@ function validateTemplate(raw, options = {}) {
|
|
|
3980
3986
|
}
|
|
3981
3987
|
};
|
|
3982
3988
|
const extras = spec.extras ?? [];
|
|
3983
|
-
if (extras.length < 2)
|
|
3989
|
+
if (extras.length < 2) sayGallery("extras", `A template carries at least two extras; this one has ${extras.length}.`);
|
|
3984
3990
|
const formTokens = new Set(forms.map((f) => f.token));
|
|
3985
3991
|
const viewTokens = new Set(views.map((v) => v.token));
|
|
3986
3992
|
const docTokens = new Set(extras.filter((e) => e.kind === "document").map((e) => e.token));
|
|
@@ -4329,7 +4335,8 @@ function validateTemplate(raw, options = {}) {
|
|
|
4329
4335
|
if (here >= 0 && Number.isFinite(firstWhen) && here < firstWhen && !TERMINAL_STAGE.test(st)) {
|
|
4330
4336
|
for (const k of rule.filled ?? []) {
|
|
4331
4337
|
if (!/^(?:datetime|date|checkbox|signature|attachment)$/.test(fieldOf(table, k)?.parityType ?? "")) continue;
|
|
4332
|
-
|
|
4338
|
+
const v = row.values?.[k];
|
|
4339
|
+
if (fieldOf(table, k)?.parityType === "checkbox" ? v === true || v === "true" : filled(v)) say(at, `"${row.key}" is ${st}, but already has "${fieldOf(table, k)?.label ?? k}", which only a ${rule.when.join("/")} record carries. Leave it empty until the record gets there.`);
|
|
4333
4340
|
}
|
|
4334
4341
|
}
|
|
4335
4342
|
if (!rule.when.includes(st)) continue;
|
|
@@ -4667,6 +4674,7 @@ function validateTemplate(raw, options = {}) {
|
|
|
4667
4674
|
}
|
|
4668
4675
|
}
|
|
4669
4676
|
adds += 1;
|
|
4677
|
+
for (const f of table.fields) if (f.default !== void 0 && !isComputed(f) && values[f.key] === void 0) values[f.key] = f.default;
|
|
4670
4678
|
const added = { key: `walk-${i}-${ri}`, values };
|
|
4671
4679
|
const landed = rules ? storeText(values[rules.stageField]) : null;
|
|
4672
4680
|
for (const k of landed ? rules?.requires?.[landed] ?? [] : []) if (!filled(values[k])) say(`${at}.action.rows[${ri}]`, `The new row "${keyValue}" lands in "${landed}", which needs "${k}" filled; the store would refuse it.`);
|
|
@@ -4990,7 +4998,8 @@ function validateTemplate(raw, options = {}) {
|
|
|
4990
4998
|
const at = `tables (${t.token}).fields (${f.key})`;
|
|
4991
4999
|
const text2 = `${f.key} ${norm(f.label)}`;
|
|
4992
5000
|
const e = effective(t.token, f);
|
|
4993
|
-
const
|
|
5001
|
+
const billingTable = /(invoice|bill|statement|receipt|payment|charge|fee|order|account)/i.test(`${t.token} ${t.labelSingular}`);
|
|
5002
|
+
const criminalCharges = /(^|_)charges?($|_)/.test(f.key) && behaviorOf(f) === "text" && !billingTable;
|
|
4994
5003
|
const phoneLike = behaviorOf(f) === "text" && /\b(cell|mobile|phone)\b/.test(norm(f.label));
|
|
4995
5004
|
const personal = PERSONAL_ONLY.test(f.key) || /\b(medical conditions?|medications?|diagnos[ie]s)\b/.test(norm(f.label));
|
|
4996
5005
|
const floored = (RESTRICTED_KEY.test(f.key) || RESTRICTED_LABEL.test(norm(f.label)) || criminalCharges) && (!personal || holdsPeople(t));
|
|
@@ -5294,7 +5303,8 @@ ${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));
|
|
|
5294
5303
|
const qq = agent.question;
|
|
5295
5304
|
const ask = norm(qq.ask);
|
|
5296
5305
|
const words = (t) => norm(t).split(" ").filter((w) => w.length >= 4);
|
|
5297
|
-
const
|
|
5306
|
+
const askWords = new Set(ask.split(" "));
|
|
5307
|
+
const mentions = (t) => !!norm(t) && ask.includes(norm(t)) || words(t).some((w) => ask.includes(w.replace(/s$/, ""))) || words(t).length === 0 && norm(t).split(" ").filter(Boolean).some((w) => w.length >= 3 && (askWords.has(w) || askWords.has(`${w}s`)));
|
|
5298
5308
|
for (const [k, v] of Object.entries(qq.expect.filter ?? {})) {
|
|
5299
5309
|
if (typeof v === "string" && !mentions(v) && !ask.includes(norm(v))) say("agent.question.ask", `It filters on ${k} = "${v}", and the question never says so.`);
|
|
5300
5310
|
}
|
|
@@ -5375,7 +5385,8 @@ ${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));
|
|
|
5375
5385
|
const named = (t) => {
|
|
5376
5386
|
if (!t) return false;
|
|
5377
5387
|
if (says.includes(norm(t))) return true;
|
|
5378
|
-
const
|
|
5388
|
+
const long = [...new Set(norm(t).split(" ").filter((w) => w.length >= 4))];
|
|
5389
|
+
const words = long.length ? long : [...new Set(norm(t).split(" ").filter((w) => w.length >= 2))];
|
|
5379
5390
|
const said = new Set(says.split(" "));
|
|
5380
5391
|
return words.length > 0 && words.filter((w) => said.has(w) || said.has(`${w}s`)).length >= Math.min(2, words.length);
|
|
5381
5392
|
};
|
|
@@ -5791,7 +5802,7 @@ ${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));
|
|
|
5791
5802
|
if (bothDates && !datesStated) say(`${at}.childDates`, `"${t.token}" and its ${rel.label.toLowerCase()} ("${parent.token}") both carry dates; say how they agree, e.g. {"relation": "${rel.key}", "field": "<this table's date>", "parentField": "<${parent.token}'s date>"} or say why they are independent in independentOf {"${rel.key}": "<reason>"}.`);
|
|
5792
5803
|
if (bothStatus && !statusStated) say(`${at}.statusAgrees`, `"${t.token}" and its ${rel.label.toLowerCase()} ("${parent.token}") both carry a status; say which child statuses need which parent status (statusAgrees), e.g. a Closed deal means a Sold listing.`);
|
|
5793
5804
|
}
|
|
5794
|
-
for (const f of t.fields.filter((x) => isNumber(x) && !isComputed(x) && /(^|_)(count|roster_size|
|
|
5805
|
+
for (const f of t.fields.filter((x) => isNumber(x) && !isComputed(x) && /(^|_)(count|roster_size|team_size|class_size|number_of|enrolled|headcount|players|members)($|_)/.test(x.key))) {
|
|
5795
5806
|
const linked = own.find((c) => c.fields.some((cf) => isRelation(cf) && cf.relationTarget === t.token));
|
|
5796
5807
|
const declared = (t.countMatches ?? []).find((c) => c.field === f.key);
|
|
5797
5808
|
const linkers = own.filter((c) => c.fields.some((cf) => isRelation(cf) && cf.relationTarget === t.token)).map((c) => c.labelPlural.toLowerCase());
|
|
@@ -5826,7 +5837,7 @@ ${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));
|
|
|
5826
5837
|
const describeOwes = (p) => {
|
|
5827
5838
|
const root = p.at.split(/[.\s[(]/)[0];
|
|
5828
5839
|
if (GALLERY_ONLY_ROOTS.includes(root)) return false;
|
|
5829
|
-
if (seedLooks.has(p)) return false;
|
|
5840
|
+
if (seedLooks.has(p) || galleryBar.has(p)) return false;
|
|
5830
5841
|
if (/^tables\[\d+\] \([^)]*\)\.rows$/.test(p.at)) return false;
|
|
5831
5842
|
return true;
|
|
5832
5843
|
};
|
|
@@ -5925,7 +5936,14 @@ function compileInstallPlan(written) {
|
|
|
5925
5936
|
const attachments = written.attachments ?? [];
|
|
5926
5937
|
const attachmentKeys = new Set(attachments.map((a) => a.key));
|
|
5927
5938
|
const spec = tokenizeValues({ ...written, attachments: void 0 }, attachmentKeys);
|
|
5928
|
-
const
|
|
5939
|
+
const bound = new Map(allTables(spec).filter((t) => t.bindsTo?.tableId).map((t) => [t.token, t.bindsTo]));
|
|
5940
|
+
const has = (token, key) => bound.get(token)?.fields.includes(key) ?? false;
|
|
5941
|
+
const tables = allTables(spec).map((t) => {
|
|
5942
|
+
if (bound.has(t.token)) return { ...t, rows: [] };
|
|
5943
|
+
const toBound = t.fields.filter((f) => f.parityType === "relation" && f.relationTarget && bound.has(f.relationTarget)).map((f) => f.key);
|
|
5944
|
+
if (!toBound.length) return t;
|
|
5945
|
+
return { ...t, rows: t.rows.map((r) => ({ ...r, values: Object.fromEntries(Object.entries(r.values ?? {}).filter(([k]) => !toBound.includes(k))) })) };
|
|
5946
|
+
});
|
|
5929
5947
|
const steps = [];
|
|
5930
5948
|
const tableRef = (token) => {
|
|
5931
5949
|
if (!tables.some((t) => t.token === token)) throw new Error(`The template names a table "${token}" it does not have.`);
|
|
@@ -5955,6 +5973,18 @@ function compileInstallPlan(written) {
|
|
|
5955
5973
|
}
|
|
5956
5974
|
}
|
|
5957
5975
|
for (const t of tables) {
|
|
5976
|
+
if (bound.has(t.token)) {
|
|
5977
|
+
for (const f of t.fields.filter((x) => !DERIVED.has(x.parityType) && x.parityType !== "formula" && x.parityType !== "relation" && !isSelfDeclaredField(x) && !has(t.token, x.key))) {
|
|
5978
|
+
steps.push({
|
|
5979
|
+
label: `bound.${t.token}.${f.key}`,
|
|
5980
|
+
door: "field_declare",
|
|
5981
|
+
args: { p_organization_id: "${org}", p_table_id: tableRef(t.token), p_spec: selfDeclaredFieldSpec(f) },
|
|
5982
|
+
save: { [`fields.${t.token}.${f.key}`]: [] },
|
|
5983
|
+
made: [{ kind: "field", ref: `fields.${t.token}.${f.key}`, table: `tables.${t.token}` }]
|
|
5984
|
+
});
|
|
5985
|
+
}
|
|
5986
|
+
continue;
|
|
5987
|
+
}
|
|
5958
5988
|
steps.push({
|
|
5959
5989
|
label: `tables.${t.token}`,
|
|
5960
5990
|
door: "table_from_example",
|
|
@@ -5965,7 +5995,7 @@ function compileInstallPlan(written) {
|
|
|
5965
5995
|
}
|
|
5966
5996
|
steps.push(...membersAddRowsSteps(spec, tableRef));
|
|
5967
5997
|
for (const t of tables) {
|
|
5968
|
-
for (const f of t.fields.filter((x) => x.parityType === "relation" && x.relationTarget)) {
|
|
5998
|
+
for (const f of t.fields.filter((x) => x.parityType === "relation" && x.relationTarget && !has(t.token, x.key))) {
|
|
5969
5999
|
steps.push({
|
|
5970
6000
|
label: `relations.${t.token}.${f.key}`,
|
|
5971
6001
|
door: "field_declare",
|
|
@@ -5976,7 +6006,7 @@ function compileInstallPlan(written) {
|
|
|
5976
6006
|
}
|
|
5977
6007
|
}
|
|
5978
6008
|
for (const t of tables) {
|
|
5979
|
-
for (const f of t.fields.filter(isSelfDeclaredField)) {
|
|
6009
|
+
for (const f of t.fields.filter((x) => isSelfDeclaredField(x) && !has(t.token, x.key))) {
|
|
5980
6010
|
steps.push({
|
|
5981
6011
|
label: `self_declared.${t.token}.${f.key}`,
|
|
5982
6012
|
door: "field_declare",
|
|
@@ -6012,7 +6042,7 @@ function compileInstallPlan(written) {
|
|
|
6012
6042
|
}
|
|
6013
6043
|
}
|
|
6014
6044
|
for (const t of tables) {
|
|
6015
|
-
for (const f of t.fields.filter((x) => DERIVED.has(x.parityType))) {
|
|
6045
|
+
for (const f of t.fields.filter((x) => DERIVED.has(x.parityType) && !has(t.token, x.key))) {
|
|
6016
6046
|
steps.push({
|
|
6017
6047
|
label: `derived.${t.token}.${f.key}`,
|
|
6018
6048
|
door: "field_declare",
|
|
@@ -6023,7 +6053,7 @@ function compileInstallPlan(written) {
|
|
|
6023
6053
|
}
|
|
6024
6054
|
}
|
|
6025
6055
|
for (const t of tables) {
|
|
6026
|
-
for (const f of formulaOrder(t)) {
|
|
6056
|
+
for (const f of formulaOrder(t).filter((x) => !has(t.token, x.key))) {
|
|
6027
6057
|
steps.push({
|
|
6028
6058
|
label: `formula.${t.token}.${f.key}`,
|
|
6029
6059
|
door: "field_declare",
|
|
@@ -6049,7 +6079,7 @@ function compileInstallPlan(written) {
|
|
|
6049
6079
|
saveEach: { array: [], key: ["data", "key"], value: ["id"], prefix: `fields.${token}.` }
|
|
6050
6080
|
});
|
|
6051
6081
|
}
|
|
6052
|
-
for (const d of spec.dimensions) {
|
|
6082
|
+
for (const d of spec.dimensions.filter((x) => !bound.has(x.table))) {
|
|
6053
6083
|
const overrides = {};
|
|
6054
6084
|
if (d.dimensions) overrides["dimensions"] = d.dimensions;
|
|
6055
6085
|
if (d.measures) overrides["measures"] = d.measures;
|
|
@@ -6206,18 +6236,22 @@ function compileInstallPlan(written) {
|
|
|
6206
6236
|
});
|
|
6207
6237
|
}
|
|
6208
6238
|
const host = compileHostExtras(spec);
|
|
6239
|
+
const agent = spec.agent;
|
|
6209
6240
|
return {
|
|
6210
6241
|
planVersion: INSTALL_PLAN_VERSION,
|
|
6211
6242
|
timezone: spec.business.timezone || "UTC",
|
|
6212
6243
|
steps,
|
|
6213
|
-
agent
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6244
|
+
...agent?.platformAgent ? {
|
|
6245
|
+
agent: {
|
|
6246
|
+
platformAgent: agent.platformAgent,
|
|
6247
|
+
name: agent.name,
|
|
6248
|
+
bindings: (agent.variables ?? []).map((v) => {
|
|
6249
|
+
const binding = host.agentBindings.get(v.name);
|
|
6250
|
+
return { variable: v.name, tableToken: v.table, describes: v.describes, ...binding ? { binding } : {} };
|
|
6251
|
+
})
|
|
6252
|
+
}
|
|
6253
|
+
} : {},
|
|
6254
|
+
...bound.size ? { ids: Object.fromEntries([...bound].map(([token, b]) => [`ref:tables.${token}`, b.tableId])) } : {},
|
|
6221
6255
|
...host.extras
|
|
6222
6256
|
};
|
|
6223
6257
|
}
|
|
@@ -6277,6 +6311,7 @@ export {
|
|
|
6277
6311
|
RECORDS_UI_FIELD_SURFACES,
|
|
6278
6312
|
RECORDS_UI_VIEW_LAYOUTS,
|
|
6279
6313
|
RELATIVE_DATE,
|
|
6314
|
+
RESOLVABLE_FIELD_TYPE_WORDS,
|
|
6280
6315
|
SERVER_DATE_GRAMMAR,
|
|
6281
6316
|
SHARED_BLOCKS,
|
|
6282
6317
|
SHARED_BLOCK_IDS,
|