@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
|
@@ -1020,4 +1020,4 @@ interface RecordsConfig {
|
|
|
1020
1020
|
knownDoors?: readonly string[];
|
|
1021
1021
|
}
|
|
1022
1022
|
|
|
1023
|
-
export { type SubscriptionBlock as $, type
|
|
1023
|
+
export { type SubscriptionBlock as $, type AggregateOperation as A, type BookingSummary as B, type DashboardTarget as C, type DashboardBlockKind as D, type DashboardTargetBase as E, type FormSummary as F, type DashboardTargetOp as G, type DashboardTargetResult as H, type DashboardTotals as I, type RecordsActor as J, type RecordsChangeSink as K, type RecordsErrorSink as L, type MySubscription as M, type RecordsFilter as N, type RecordsRealtimePort as O, type RecordsResolverPort as P, type QuietHours as Q, type RecordsConfig as R, type SubscriptionCadence as S, type RecordsResponse as T, type RecordsTableQuery as U, type Rule as V, type RuleAnswer as W, type RuleExpression as X, type SavedViewColorBy as Y, type SavedViewDefinition as Z, type SavedViewLayout as _, type AggregateFilter as a, bookingPath as a0, callersTimeZone as a1, hasQuietHours as a2, isRuleFilter as a3, liftWithheld as a4, measureKey as a5, publicFormPath as a6, stableFilterKey as a7, withCallersClock as a8, type AggregateMeasure as b, type AggregateBucket as c, type StoreFilter as d, type BookingAvailability as e, type BookingDeclared as f, type DashboardSummary as g, type DashboardBlock as h, type RecordFilter as i, type AggregateCompare as j, type DashboardRunResult as k, type StuckRow as l, type AggregateRow as m, type Subscription as n, type SubscriptionSpec as o, type DigestPreview as p, type SavedViewRow as q, type SavedViewSpecIn as r, type RowTemplateRow as s, type RecordsDataSource as t, type AggregateCompareKind as u, type AggregateCompareWindows as v, type AggregateDelta as w, type AggregateWindow as x, type BookingWindow as y, type DashboardBlockResult as z };
|
|
@@ -1020,4 +1020,4 @@ interface RecordsConfig {
|
|
|
1020
1020
|
knownDoors?: readonly string[];
|
|
1021
1021
|
}
|
|
1022
1022
|
|
|
1023
|
-
export { type SubscriptionBlock as $, type
|
|
1023
|
+
export { type SubscriptionBlock as $, type AggregateOperation as A, type BookingSummary as B, type DashboardTarget as C, type DashboardBlockKind as D, type DashboardTargetBase as E, type FormSummary as F, type DashboardTargetOp as G, type DashboardTargetResult as H, type DashboardTotals as I, type RecordsActor as J, type RecordsChangeSink as K, type RecordsErrorSink as L, type MySubscription as M, type RecordsFilter as N, type RecordsRealtimePort as O, type RecordsResolverPort as P, type QuietHours as Q, type RecordsConfig as R, type SubscriptionCadence as S, type RecordsResponse as T, type RecordsTableQuery as U, type Rule as V, type RuleAnswer as W, type RuleExpression as X, type SavedViewColorBy as Y, type SavedViewDefinition as Z, type SavedViewLayout as _, type AggregateFilter as a, bookingPath as a0, callersTimeZone as a1, hasQuietHours as a2, isRuleFilter as a3, liftWithheld as a4, measureKey as a5, publicFormPath as a6, stableFilterKey as a7, withCallersClock as a8, type AggregateMeasure as b, type AggregateBucket as c, type StoreFilter as d, type BookingAvailability as e, type BookingDeclared as f, type DashboardSummary as g, type DashboardBlock as h, type RecordFilter as i, type AggregateCompare as j, type DashboardRunResult as k, type StuckRow as l, type AggregateRow as m, type Subscription as n, type SubscriptionSpec as o, type DigestPreview as p, type SavedViewRow as q, type SavedViewSpecIn as r, type RowTemplateRow as s, type RecordsDataSource as t, type AggregateCompareKind as u, type AggregateCompareWindows as v, type AggregateDelta as w, type AggregateWindow as x, type BookingWindow as y, type DashboardBlockResult as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as ReadRow, g as Timestamp, U as Uuid, h as RecordDocument, R as RelationFlavor, O as OnDelete, aK as RelationBinding, f as RelationCardinality, i as RecordsResult, r as StoredRecord, q as Field, az as ParityFieldType, T as TableType, a as TableDisplay, S as StorageMode, b0 as TableOrigin, z as RecordsError } from './field-CekLWOPw.js';
|
|
2
|
-
import { t as RecordsDataSource } from './ports-
|
|
2
|
+
import { t as RecordsDataSource } from './ports-Df3VghxK.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* THE TWO LANES THE ARCHIVED-ITEMS LAW NAMES (Arman, 2026-09-09) — the same
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as ReadRow, g as Timestamp, U as Uuid, h as RecordDocument, R as RelationFlavor, O as OnDelete, aK as RelationBinding, f as RelationCardinality, i as RecordsResult, r as StoredRecord, q as Field, az as ParityFieldType, T as TableType, a as TableDisplay, S as StorageMode, b0 as TableOrigin, z as RecordsError } from './field-CekLWOPw.cjs';
|
|
2
|
-
import { t as RecordsDataSource } from './ports-
|
|
2
|
+
import { t as RecordsDataSource } from './ports-DKOk7AT2.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* THE TWO LANES THE ARCHIVED-ITEMS LAW NAMES (Arman, 2026-09-09) — the same
|
package/dist/templates/index.cjs
CHANGED
|
@@ -37,6 +37,7 @@ __export(templates_exports, {
|
|
|
37
37
|
RECORDS_UI_FIELD_SURFACES: () => RECORDS_UI_FIELD_SURFACES,
|
|
38
38
|
RECORDS_UI_VIEW_LAYOUTS: () => RECORDS_UI_VIEW_LAYOUTS,
|
|
39
39
|
RELATIVE_DATE: () => RELATIVE_DATE,
|
|
40
|
+
RESOLVABLE_FIELD_TYPE_WORDS: () => RESOLVABLE_FIELD_TYPE_WORDS,
|
|
40
41
|
SERVER_DATE_GRAMMAR: () => SERVER_DATE_GRAMMAR,
|
|
41
42
|
SHARED_BLOCKS: () => SHARED_BLOCKS,
|
|
42
43
|
SHARED_BLOCK_IDS: () => SHARED_BLOCK_IDS,
|
|
@@ -3601,6 +3602,12 @@ function validateTemplate(raw, options = {}) {
|
|
|
3601
3602
|
seedLooks.add(p);
|
|
3602
3603
|
problems.push(p);
|
|
3603
3604
|
};
|
|
3605
|
+
const galleryBar = /* @__PURE__ */ new WeakSet();
|
|
3606
|
+
const sayGallery = (at, says) => {
|
|
3607
|
+
const p = { at, says };
|
|
3608
|
+
galleryBar.add(p);
|
|
3609
|
+
problems.push(p);
|
|
3610
|
+
};
|
|
3604
3611
|
const tz = raw.business?.timezone || "UTC";
|
|
3605
3612
|
const tablesRaw = allTables(raw);
|
|
3606
3613
|
const ISO_DAY = /\b\d{4}-\d{2}-\d{2}\b/;
|
|
@@ -3923,7 +3930,7 @@ function validateTemplate(raw, options = {}) {
|
|
|
3923
3930
|
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.`);
|
|
3924
3931
|
}
|
|
3925
3932
|
});
|
|
3926
|
-
if (!hasLookupOrRollup)
|
|
3933
|
+
if (!hasLookupOrRollup) sayGallery("tables", "At least one relationship has to be read across: add a lookup or a rollup through a relation field.");
|
|
3927
3934
|
if (main) {
|
|
3928
3935
|
const normTitle = (v) => (storeText(v) ?? "").toLowerCase().replace(/\s+/g, " ").trim();
|
|
3929
3936
|
const rows = main.rows;
|
|
@@ -3991,8 +3998,8 @@ function validateTemplate(raw, options = {}) {
|
|
|
3991
3998
|
else surfaces.set(token, { at, ...table ? { table } : {} });
|
|
3992
3999
|
};
|
|
3993
4000
|
const views = spec.views ?? [];
|
|
3994
|
-
if (views.length < 3)
|
|
3995
|
-
if (!views.some((v) => v.kind === "grid"))
|
|
4001
|
+
if (views.length < 3) sayGallery("views", `A template shows at least three views; this one has ${views.length}.`);
|
|
4002
|
+
if (!views.some((v) => v.kind === "grid")) sayGallery("views", "One of the views is a grid \u2014 the table everyone recognises.");
|
|
3996
4003
|
views.forEach((view, i) => {
|
|
3997
4004
|
const at = `views[${i}] (${view.token})`;
|
|
3998
4005
|
claim(view.token, at, view.table);
|
|
@@ -4118,7 +4125,7 @@ function validateTemplate(raw, options = {}) {
|
|
|
4118
4125
|
}
|
|
4119
4126
|
};
|
|
4120
4127
|
const extras = spec.extras ?? [];
|
|
4121
|
-
if (extras.length < 2)
|
|
4128
|
+
if (extras.length < 2) sayGallery("extras", `A template carries at least two extras; this one has ${extras.length}.`);
|
|
4122
4129
|
const formTokens = new Set(forms.map((f) => f.token));
|
|
4123
4130
|
const viewTokens = new Set(views.map((v) => v.token));
|
|
4124
4131
|
const docTokens = new Set(extras.filter((e) => e.kind === "document").map((e) => e.token));
|
|
@@ -4467,7 +4474,8 @@ function validateTemplate(raw, options = {}) {
|
|
|
4467
4474
|
if (here >= 0 && Number.isFinite(firstWhen) && here < firstWhen && !TERMINAL_STAGE.test(st)) {
|
|
4468
4475
|
for (const k of rule.filled ?? []) {
|
|
4469
4476
|
if (!/^(?:datetime|date|checkbox|signature|attachment)$/.test(fieldOf(table, k)?.parityType ?? "")) continue;
|
|
4470
|
-
|
|
4477
|
+
const v = row.values?.[k];
|
|
4478
|
+
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.`);
|
|
4471
4479
|
}
|
|
4472
4480
|
}
|
|
4473
4481
|
if (!rule.when.includes(st)) continue;
|
|
@@ -4805,6 +4813,7 @@ function validateTemplate(raw, options = {}) {
|
|
|
4805
4813
|
}
|
|
4806
4814
|
}
|
|
4807
4815
|
adds += 1;
|
|
4816
|
+
for (const f of table.fields) if (f.default !== void 0 && !isComputed(f) && values[f.key] === void 0) values[f.key] = f.default;
|
|
4808
4817
|
const added = { key: `walk-${i}-${ri}`, values };
|
|
4809
4818
|
const landed = rules ? storeText(values[rules.stageField]) : null;
|
|
4810
4819
|
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.`);
|
|
@@ -5128,7 +5137,8 @@ function validateTemplate(raw, options = {}) {
|
|
|
5128
5137
|
const at = `tables (${t.token}).fields (${f.key})`;
|
|
5129
5138
|
const text2 = `${f.key} ${norm(f.label)}`;
|
|
5130
5139
|
const e = effective(t.token, f);
|
|
5131
|
-
const
|
|
5140
|
+
const billingTable = /(invoice|bill|statement|receipt|payment|charge|fee|order|account)/i.test(`${t.token} ${t.labelSingular}`);
|
|
5141
|
+
const criminalCharges = /(^|_)charges?($|_)/.test(f.key) && behaviorOf(f) === "text" && !billingTable;
|
|
5132
5142
|
const phoneLike = behaviorOf(f) === "text" && /\b(cell|mobile|phone)\b/.test(norm(f.label));
|
|
5133
5143
|
const personal = PERSONAL_ONLY.test(f.key) || /\b(medical conditions?|medications?|diagnos[ie]s)\b/.test(norm(f.label));
|
|
5134
5144
|
const floored = (RESTRICTED_KEY.test(f.key) || RESTRICTED_LABEL.test(norm(f.label)) || criminalCharges) && (!personal || holdsPeople(t));
|
|
@@ -5432,7 +5442,8 @@ ${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));
|
|
|
5432
5442
|
const qq = agent.question;
|
|
5433
5443
|
const ask = norm(qq.ask);
|
|
5434
5444
|
const words = (t) => norm(t).split(" ").filter((w) => w.length >= 4);
|
|
5435
|
-
const
|
|
5445
|
+
const askWords = new Set(ask.split(" "));
|
|
5446
|
+
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`)));
|
|
5436
5447
|
for (const [k, v] of Object.entries(qq.expect.filter ?? {})) {
|
|
5437
5448
|
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.`);
|
|
5438
5449
|
}
|
|
@@ -5513,7 +5524,8 @@ ${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));
|
|
|
5513
5524
|
const named = (t) => {
|
|
5514
5525
|
if (!t) return false;
|
|
5515
5526
|
if (says.includes(norm(t))) return true;
|
|
5516
|
-
const
|
|
5527
|
+
const long = [...new Set(norm(t).split(" ").filter((w) => w.length >= 4))];
|
|
5528
|
+
const words = long.length ? long : [...new Set(norm(t).split(" ").filter((w) => w.length >= 2))];
|
|
5517
5529
|
const said = new Set(says.split(" "));
|
|
5518
5530
|
return words.length > 0 && words.filter((w) => said.has(w) || said.has(`${w}s`)).length >= Math.min(2, words.length);
|
|
5519
5531
|
};
|
|
@@ -5929,7 +5941,7 @@ ${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));
|
|
|
5929
5941
|
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>"}.`);
|
|
5930
5942
|
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.`);
|
|
5931
5943
|
}
|
|
5932
|
-
for (const f of t.fields.filter((x) => isNumber(x) && !isComputed(x) && /(^|_)(count|roster_size|
|
|
5944
|
+
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))) {
|
|
5933
5945
|
const linked = own.find((c) => c.fields.some((cf) => isRelation(cf) && cf.relationTarget === t.token));
|
|
5934
5946
|
const declared = (t.countMatches ?? []).find((c) => c.field === f.key);
|
|
5935
5947
|
const linkers = own.filter((c) => c.fields.some((cf) => isRelation(cf) && cf.relationTarget === t.token)).map((c) => c.labelPlural.toLowerCase());
|
|
@@ -5964,7 +5976,7 @@ ${e.body}`.matchAll(MERGE_TOKEN)].map((m) => m[1]));
|
|
|
5964
5976
|
const describeOwes = (p) => {
|
|
5965
5977
|
const root = p.at.split(/[.\s[(]/)[0];
|
|
5966
5978
|
if (GALLERY_ONLY_ROOTS.includes(root)) return false;
|
|
5967
|
-
if (seedLooks.has(p)) return false;
|
|
5979
|
+
if (seedLooks.has(p) || galleryBar.has(p)) return false;
|
|
5968
5980
|
if (/^tables\[\d+\] \([^)]*\)\.rows$/.test(p.at)) return false;
|
|
5969
5981
|
return true;
|
|
5970
5982
|
};
|
|
@@ -6063,7 +6075,14 @@ function compileInstallPlan(written) {
|
|
|
6063
6075
|
const attachments = written.attachments ?? [];
|
|
6064
6076
|
const attachmentKeys = new Set(attachments.map((a) => a.key));
|
|
6065
6077
|
const spec = tokenizeValues({ ...written, attachments: void 0 }, attachmentKeys);
|
|
6066
|
-
const
|
|
6078
|
+
const bound = new Map(allTables(spec).filter((t) => t.bindsTo?.tableId).map((t) => [t.token, t.bindsTo]));
|
|
6079
|
+
const has = (token, key) => bound.get(token)?.fields.includes(key) ?? false;
|
|
6080
|
+
const tables = allTables(spec).map((t) => {
|
|
6081
|
+
if (bound.has(t.token)) return { ...t, rows: [] };
|
|
6082
|
+
const toBound = t.fields.filter((f) => f.parityType === "relation" && f.relationTarget && bound.has(f.relationTarget)).map((f) => f.key);
|
|
6083
|
+
if (!toBound.length) return t;
|
|
6084
|
+
return { ...t, rows: t.rows.map((r) => ({ ...r, values: Object.fromEntries(Object.entries(r.values ?? {}).filter(([k]) => !toBound.includes(k))) })) };
|
|
6085
|
+
});
|
|
6067
6086
|
const steps = [];
|
|
6068
6087
|
const tableRef = (token) => {
|
|
6069
6088
|
if (!tables.some((t) => t.token === token)) throw new Error(`The template names a table "${token}" it does not have.`);
|
|
@@ -6093,6 +6112,18 @@ function compileInstallPlan(written) {
|
|
|
6093
6112
|
}
|
|
6094
6113
|
}
|
|
6095
6114
|
for (const t of tables) {
|
|
6115
|
+
if (bound.has(t.token)) {
|
|
6116
|
+
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))) {
|
|
6117
|
+
steps.push({
|
|
6118
|
+
label: `bound.${t.token}.${f.key}`,
|
|
6119
|
+
door: "field_declare",
|
|
6120
|
+
args: { p_organization_id: "${org}", p_table_id: tableRef(t.token), p_spec: selfDeclaredFieldSpec(f) },
|
|
6121
|
+
save: { [`fields.${t.token}.${f.key}`]: [] },
|
|
6122
|
+
made: [{ kind: "field", ref: `fields.${t.token}.${f.key}`, table: `tables.${t.token}` }]
|
|
6123
|
+
});
|
|
6124
|
+
}
|
|
6125
|
+
continue;
|
|
6126
|
+
}
|
|
6096
6127
|
steps.push({
|
|
6097
6128
|
label: `tables.${t.token}`,
|
|
6098
6129
|
door: "table_from_example",
|
|
@@ -6103,7 +6134,7 @@ function compileInstallPlan(written) {
|
|
|
6103
6134
|
}
|
|
6104
6135
|
steps.push(...membersAddRowsSteps(spec, tableRef));
|
|
6105
6136
|
for (const t of tables) {
|
|
6106
|
-
for (const f of t.fields.filter((x) => x.parityType === "relation" && x.relationTarget)) {
|
|
6137
|
+
for (const f of t.fields.filter((x) => x.parityType === "relation" && x.relationTarget && !has(t.token, x.key))) {
|
|
6107
6138
|
steps.push({
|
|
6108
6139
|
label: `relations.${t.token}.${f.key}`,
|
|
6109
6140
|
door: "field_declare",
|
|
@@ -6114,7 +6145,7 @@ function compileInstallPlan(written) {
|
|
|
6114
6145
|
}
|
|
6115
6146
|
}
|
|
6116
6147
|
for (const t of tables) {
|
|
6117
|
-
for (const f of t.fields.filter(isSelfDeclaredField)) {
|
|
6148
|
+
for (const f of t.fields.filter((x) => isSelfDeclaredField(x) && !has(t.token, x.key))) {
|
|
6118
6149
|
steps.push({
|
|
6119
6150
|
label: `self_declared.${t.token}.${f.key}`,
|
|
6120
6151
|
door: "field_declare",
|
|
@@ -6150,7 +6181,7 @@ function compileInstallPlan(written) {
|
|
|
6150
6181
|
}
|
|
6151
6182
|
}
|
|
6152
6183
|
for (const t of tables) {
|
|
6153
|
-
for (const f of t.fields.filter((x) => DERIVED.has(x.parityType))) {
|
|
6184
|
+
for (const f of t.fields.filter((x) => DERIVED.has(x.parityType) && !has(t.token, x.key))) {
|
|
6154
6185
|
steps.push({
|
|
6155
6186
|
label: `derived.${t.token}.${f.key}`,
|
|
6156
6187
|
door: "field_declare",
|
|
@@ -6161,7 +6192,7 @@ function compileInstallPlan(written) {
|
|
|
6161
6192
|
}
|
|
6162
6193
|
}
|
|
6163
6194
|
for (const t of tables) {
|
|
6164
|
-
for (const f of formulaOrder(t)) {
|
|
6195
|
+
for (const f of formulaOrder(t).filter((x) => !has(t.token, x.key))) {
|
|
6165
6196
|
steps.push({
|
|
6166
6197
|
label: `formula.${t.token}.${f.key}`,
|
|
6167
6198
|
door: "field_declare",
|
|
@@ -6187,7 +6218,7 @@ function compileInstallPlan(written) {
|
|
|
6187
6218
|
saveEach: { array: [], key: ["data", "key"], value: ["id"], prefix: `fields.${token}.` }
|
|
6188
6219
|
});
|
|
6189
6220
|
}
|
|
6190
|
-
for (const d of spec.dimensions) {
|
|
6221
|
+
for (const d of spec.dimensions.filter((x) => !bound.has(x.table))) {
|
|
6191
6222
|
const overrides = {};
|
|
6192
6223
|
if (d.dimensions) overrides["dimensions"] = d.dimensions;
|
|
6193
6224
|
if (d.measures) overrides["measures"] = d.measures;
|
|
@@ -6344,18 +6375,22 @@ function compileInstallPlan(written) {
|
|
|
6344
6375
|
});
|
|
6345
6376
|
}
|
|
6346
6377
|
const host = compileHostExtras(spec);
|
|
6378
|
+
const agent = spec.agent;
|
|
6347
6379
|
return {
|
|
6348
6380
|
planVersion: INSTALL_PLAN_VERSION,
|
|
6349
6381
|
timezone: spec.business.timezone || "UTC",
|
|
6350
6382
|
steps,
|
|
6351
|
-
agent
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
|
|
6383
|
+
...agent?.platformAgent ? {
|
|
6384
|
+
agent: {
|
|
6385
|
+
platformAgent: agent.platformAgent,
|
|
6386
|
+
name: agent.name,
|
|
6387
|
+
bindings: (agent.variables ?? []).map((v) => {
|
|
6388
|
+
const binding = host.agentBindings.get(v.name);
|
|
6389
|
+
return { variable: v.name, tableToken: v.table, describes: v.describes, ...binding ? { binding } : {} };
|
|
6390
|
+
})
|
|
6391
|
+
}
|
|
6392
|
+
} : {},
|
|
6393
|
+
...bound.size ? { ids: Object.fromEntries([...bound].map(([token, b]) => [`ref:tables.${token}`, b.tableId])) } : {},
|
|
6359
6394
|
...host.extras
|
|
6360
6395
|
};
|
|
6361
6396
|
}
|