@ai-matrx/records 0.58.117 → 0.58.118
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 +8 -0
- package/dist/core/index.cjs +98 -5
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +55 -1
- package/dist/core/index.d.ts +55 -1
- package/dist/core/index.js +98 -5
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +98 -5
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +55 -1
- package/dist/react/index.d.ts +55 -1
- package/dist/react/index.js +98 -5
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.cts
CHANGED
|
@@ -10865,6 +10865,25 @@ interface RecordQuery {
|
|
|
10865
10865
|
offset?: number;
|
|
10866
10866
|
}
|
|
10867
10867
|
|
|
10868
|
+
/** One organization the client could not use, with the sentence that says why. */
|
|
10869
|
+
interface OrganizationUnavailable {
|
|
10870
|
+
organization_id: Uuid;
|
|
10871
|
+
reason: string;
|
|
10872
|
+
}
|
|
10873
|
+
/** `organizationsOpen`: the organizations whose store answers, and those that do not (with why). */
|
|
10874
|
+
interface OrganizationsOpenAnswer {
|
|
10875
|
+
open: Uuid[];
|
|
10876
|
+
unavailable: OrganizationUnavailable[];
|
|
10877
|
+
}
|
|
10878
|
+
/** `metadataSearch`: every match, each carrying the organization it came from. */
|
|
10879
|
+
interface MetadataSearchAnswer {
|
|
10880
|
+
matches: Array<Record<string, unknown> & {
|
|
10881
|
+
organization_id: Uuid | null;
|
|
10882
|
+
}>;
|
|
10883
|
+
/** Organizations asked in order (the ones that answered). */
|
|
10884
|
+
organizations_covered: Uuid[];
|
|
10885
|
+
unavailable: OrganizationUnavailable[];
|
|
10886
|
+
}
|
|
10868
10887
|
interface RecordsClient {
|
|
10869
10888
|
/** The config this client was built with, so a screen can show who it is acting as. */
|
|
10870
10889
|
readonly config: RecordsConfig;
|
|
@@ -11930,6 +11949,13 @@ interface RecordsClient {
|
|
|
11930
11949
|
*/
|
|
11931
11950
|
recordAggregate(args: {
|
|
11932
11951
|
table_id: Uuid;
|
|
11952
|
+
/**
|
|
11953
|
+
* OPTIONAL FILTER (active-org law): with `config.organizationIds` set, the table is looked
|
|
11954
|
+
* up across all the person's organizations and the aggregate runs in the one that OWNS it
|
|
11955
|
+
* (each row then carries that `organization_id`); this narrows the lookup to one. Absent and
|
|
11956
|
+
* no `organizationIds` ⇒ this client's own organization, exactly as before.
|
|
11957
|
+
*/
|
|
11958
|
+
organization_id?: Uuid | null;
|
|
11933
11959
|
/** Field keys whose values become the groups. */
|
|
11934
11960
|
groupBy?: string[];
|
|
11935
11961
|
/** `count` needs no key; every other operation reads one Field. */
|
|
@@ -12279,9 +12305,37 @@ interface RecordsClient {
|
|
|
12279
12305
|
record_id: Uuid;
|
|
12280
12306
|
organization_id?: Uuid | null;
|
|
12281
12307
|
}): Promise<RecordsResult<ReadValue[]>>;
|
|
12308
|
+
/**
|
|
12309
|
+
* Metadata search across EVERY organization the person belongs to (`config.organizationIds`;
|
|
12310
|
+
* `organization_id` narrows to one). Each match carries its own `organization_id`; an
|
|
12311
|
+
* organization whose store is off or refuses is listed in `unavailable` WITH its reason and
|
|
12312
|
+
* never hides the rest. Only when NO organization answers is the whole search a failure (the
|
|
12313
|
+
* first refusal). The door itself is not in the store's catalogue yet, so today every
|
|
12314
|
+
* organization refuses in the door-absent sentence — named, never faked.
|
|
12315
|
+
*/
|
|
12282
12316
|
metadataSearch(args: {
|
|
12283
12317
|
text: string;
|
|
12284
|
-
|
|
12318
|
+
organization_id?: Uuid | null;
|
|
12319
|
+
}): Promise<RecordsResult<MetadataSearchAnswer>>;
|
|
12320
|
+
/**
|
|
12321
|
+
* WHICH of the person's organizations can this client use right now? Asks every organization
|
|
12322
|
+
* in scope (`organization_id` narrows to one) whether its record store is open, so a host can
|
|
12323
|
+
* say "organization X is unavailable: <reason>" instead of silently dropping it. Organization
|
|
12324
|
+
* order is the person's own, never completion order.
|
|
12325
|
+
*/
|
|
12326
|
+
organizationsOpen(args?: {
|
|
12327
|
+
organization_id?: Uuid | null;
|
|
12328
|
+
}): Promise<RecordsResult<OrganizationsOpenAnswer>>;
|
|
12329
|
+
/**
|
|
12330
|
+
* The organization that OWNS a table or record — the one a write to it must run in. A
|
|
12331
|
+
* `table_id` is looked up across all the person's organizations; a `record_id` is opened in its
|
|
12332
|
+
* own. `null` = found in none of them. Never a permission: the store's doors still decide.
|
|
12333
|
+
*/
|
|
12334
|
+
ownerOrganization(args: {
|
|
12335
|
+
table_id?: Uuid | null;
|
|
12336
|
+
record_id?: Uuid | null;
|
|
12337
|
+
organization_id?: Uuid | null;
|
|
12338
|
+
}): Promise<RecordsResult<Uuid | null>>;
|
|
12285
12339
|
/**
|
|
12286
12340
|
* Mint an embed token. `mode` is `read` OR `write` and never both — the store
|
|
12287
12341
|
* refuses a token carrying two decisions. The secret comes back ONCE, because
|
package/dist/react/index.d.ts
CHANGED
|
@@ -10865,6 +10865,25 @@ interface RecordQuery {
|
|
|
10865
10865
|
offset?: number;
|
|
10866
10866
|
}
|
|
10867
10867
|
|
|
10868
|
+
/** One organization the client could not use, with the sentence that says why. */
|
|
10869
|
+
interface OrganizationUnavailable {
|
|
10870
|
+
organization_id: Uuid;
|
|
10871
|
+
reason: string;
|
|
10872
|
+
}
|
|
10873
|
+
/** `organizationsOpen`: the organizations whose store answers, and those that do not (with why). */
|
|
10874
|
+
interface OrganizationsOpenAnswer {
|
|
10875
|
+
open: Uuid[];
|
|
10876
|
+
unavailable: OrganizationUnavailable[];
|
|
10877
|
+
}
|
|
10878
|
+
/** `metadataSearch`: every match, each carrying the organization it came from. */
|
|
10879
|
+
interface MetadataSearchAnswer {
|
|
10880
|
+
matches: Array<Record<string, unknown> & {
|
|
10881
|
+
organization_id: Uuid | null;
|
|
10882
|
+
}>;
|
|
10883
|
+
/** Organizations asked in order (the ones that answered). */
|
|
10884
|
+
organizations_covered: Uuid[];
|
|
10885
|
+
unavailable: OrganizationUnavailable[];
|
|
10886
|
+
}
|
|
10868
10887
|
interface RecordsClient {
|
|
10869
10888
|
/** The config this client was built with, so a screen can show who it is acting as. */
|
|
10870
10889
|
readonly config: RecordsConfig;
|
|
@@ -11930,6 +11949,13 @@ interface RecordsClient {
|
|
|
11930
11949
|
*/
|
|
11931
11950
|
recordAggregate(args: {
|
|
11932
11951
|
table_id: Uuid;
|
|
11952
|
+
/**
|
|
11953
|
+
* OPTIONAL FILTER (active-org law): with `config.organizationIds` set, the table is looked
|
|
11954
|
+
* up across all the person's organizations and the aggregate runs in the one that OWNS it
|
|
11955
|
+
* (each row then carries that `organization_id`); this narrows the lookup to one. Absent and
|
|
11956
|
+
* no `organizationIds` ⇒ this client's own organization, exactly as before.
|
|
11957
|
+
*/
|
|
11958
|
+
organization_id?: Uuid | null;
|
|
11933
11959
|
/** Field keys whose values become the groups. */
|
|
11934
11960
|
groupBy?: string[];
|
|
11935
11961
|
/** `count` needs no key; every other operation reads one Field. */
|
|
@@ -12279,9 +12305,37 @@ interface RecordsClient {
|
|
|
12279
12305
|
record_id: Uuid;
|
|
12280
12306
|
organization_id?: Uuid | null;
|
|
12281
12307
|
}): Promise<RecordsResult<ReadValue[]>>;
|
|
12308
|
+
/**
|
|
12309
|
+
* Metadata search across EVERY organization the person belongs to (`config.organizationIds`;
|
|
12310
|
+
* `organization_id` narrows to one). Each match carries its own `organization_id`; an
|
|
12311
|
+
* organization whose store is off or refuses is listed in `unavailable` WITH its reason and
|
|
12312
|
+
* never hides the rest. Only when NO organization answers is the whole search a failure (the
|
|
12313
|
+
* first refusal). The door itself is not in the store's catalogue yet, so today every
|
|
12314
|
+
* organization refuses in the door-absent sentence — named, never faked.
|
|
12315
|
+
*/
|
|
12282
12316
|
metadataSearch(args: {
|
|
12283
12317
|
text: string;
|
|
12284
|
-
|
|
12318
|
+
organization_id?: Uuid | null;
|
|
12319
|
+
}): Promise<RecordsResult<MetadataSearchAnswer>>;
|
|
12320
|
+
/**
|
|
12321
|
+
* WHICH of the person's organizations can this client use right now? Asks every organization
|
|
12322
|
+
* in scope (`organization_id` narrows to one) whether its record store is open, so a host can
|
|
12323
|
+
* say "organization X is unavailable: <reason>" instead of silently dropping it. Organization
|
|
12324
|
+
* order is the person's own, never completion order.
|
|
12325
|
+
*/
|
|
12326
|
+
organizationsOpen(args?: {
|
|
12327
|
+
organization_id?: Uuid | null;
|
|
12328
|
+
}): Promise<RecordsResult<OrganizationsOpenAnswer>>;
|
|
12329
|
+
/**
|
|
12330
|
+
* The organization that OWNS a table or record — the one a write to it must run in. A
|
|
12331
|
+
* `table_id` is looked up across all the person's organizations; a `record_id` is opened in its
|
|
12332
|
+
* own. `null` = found in none of them. Never a permission: the store's doors still decide.
|
|
12333
|
+
*/
|
|
12334
|
+
ownerOrganization(args: {
|
|
12335
|
+
table_id?: Uuid | null;
|
|
12336
|
+
record_id?: Uuid | null;
|
|
12337
|
+
organization_id?: Uuid | null;
|
|
12338
|
+
}): Promise<RecordsResult<Uuid | null>>;
|
|
12285
12339
|
/**
|
|
12286
12340
|
* Mint an embed token. `mode` is `read` OR `write` and never both — the store
|
|
12287
12341
|
* refuses a token carrying two decisions. The secret comes back ONCE, because
|
package/dist/react/index.js
CHANGED
|
@@ -39727,6 +39727,13 @@ function createRecordsClient(config) {
|
|
|
39727
39727
|
}
|
|
39728
39728
|
return last;
|
|
39729
39729
|
}
|
|
39730
|
+
const spans = (filter) => Boolean(filter) || (config.organizationIds?.length ?? 0) > 0;
|
|
39731
|
+
const metadataSearchDoor = () => {
|
|
39732
|
+
const refusal = doorAbsent(DOORS.metadataSearch);
|
|
39733
|
+
scream({ code: refusal.code, message: refusal.message, ...refusal.hint ? { hint: refusal.hint } : {}, where: "metadataSearch" });
|
|
39734
|
+
return err(refusal);
|
|
39735
|
+
};
|
|
39736
|
+
const unavailableReason = (error) => `${error.message}${error.hint ? ` ${error.hint}` : ""}`;
|
|
39730
39737
|
const client = {
|
|
39731
39738
|
config,
|
|
39732
39739
|
async recordWrite({ table_id, data }) {
|
|
@@ -41056,7 +41063,23 @@ function createRecordsClient(config) {
|
|
|
41056
41063
|
"dashboardDelete"
|
|
41057
41064
|
);
|
|
41058
41065
|
},
|
|
41059
|
-
async recordAggregate({ table_id, groupBy, measures, bucket, filter, limit, compare }) {
|
|
41066
|
+
async recordAggregate({ table_id, organization_id, groupBy, measures, bucket, filter, limit, compare }) {
|
|
41067
|
+
if (spans(organization_id)) {
|
|
41068
|
+
const owner = await client.ownerOrganization({ table_id, ...organization_id ? { organization_id } : {} });
|
|
41069
|
+
const target = owner.ok && owner.data ? owner.data : organization_id ?? org;
|
|
41070
|
+
if (target !== org) {
|
|
41071
|
+
const answered = await clientFor(target).recordAggregate({
|
|
41072
|
+
table_id,
|
|
41073
|
+
...groupBy ? { groupBy } : {},
|
|
41074
|
+
...measures ? { measures } : {},
|
|
41075
|
+
...bucket !== void 0 ? { bucket } : {},
|
|
41076
|
+
...filter ? { filter } : {},
|
|
41077
|
+
...limit !== void 0 ? { limit } : {},
|
|
41078
|
+
...compare !== void 0 ? { compare } : {}
|
|
41079
|
+
});
|
|
41080
|
+
return answered.ok ? ok(answered.data.map((row) => ({ ...row, organization_id: target }))) : answered;
|
|
41081
|
+
}
|
|
41082
|
+
}
|
|
41060
41083
|
return callDoor(
|
|
41061
41084
|
DOORS.recordAggregate,
|
|
41062
41085
|
{
|
|
@@ -41972,10 +41995,80 @@ function createRecordsClient(config) {
|
|
|
41972
41995
|
"ruleDeclare"
|
|
41973
41996
|
);
|
|
41974
41997
|
},
|
|
41975
|
-
async metadataSearch() {
|
|
41976
|
-
|
|
41977
|
-
|
|
41978
|
-
|
|
41998
|
+
async metadataSearch({ text, organization_id }) {
|
|
41999
|
+
if (spans(organization_id) && readOrgs(organization_id).length > 0) {
|
|
42000
|
+
const targets = readOrgs(organization_id).filter((t) => t !== null);
|
|
42001
|
+
const unavailable = [];
|
|
42002
|
+
const answers = await Promise.all(
|
|
42003
|
+
targets.map(async (t) => {
|
|
42004
|
+
const sub = clientFor(t);
|
|
42005
|
+
const open = await sub.storeIsOpen();
|
|
42006
|
+
if (!open.ok) {
|
|
42007
|
+
unavailable.push({ organization_id: t, reason: unavailableReason(open.error) });
|
|
42008
|
+
return null;
|
|
42009
|
+
}
|
|
42010
|
+
if (!open.data) {
|
|
42011
|
+
unavailable.push({ organization_id: t, reason: "The custom data store is switched off for this organization." });
|
|
42012
|
+
return null;
|
|
42013
|
+
}
|
|
42014
|
+
const found = metadataSearchDoor();
|
|
42015
|
+
if (!found.ok) {
|
|
42016
|
+
unavailable.push({ organization_id: t, reason: unavailableReason(found.error) });
|
|
42017
|
+
return { t, found };
|
|
42018
|
+
}
|
|
42019
|
+
return { t, found };
|
|
42020
|
+
})
|
|
42021
|
+
);
|
|
42022
|
+
const matches = [];
|
|
42023
|
+
const covered = [];
|
|
42024
|
+
let firstRefusal = null;
|
|
42025
|
+
for (const answer of answers) {
|
|
42026
|
+
if (!answer) continue;
|
|
42027
|
+
if (!answer.found.ok) {
|
|
42028
|
+
firstRefusal ??= answer.found.error;
|
|
42029
|
+
continue;
|
|
42030
|
+
}
|
|
42031
|
+
covered.push(answer.t);
|
|
42032
|
+
for (const m of answer.found.data.matches) matches.push({ ...m, organization_id: answer.t });
|
|
42033
|
+
}
|
|
42034
|
+
const inOrder = (a, b) => targets.indexOf(a.organization_id) - targets.indexOf(b.organization_id);
|
|
42035
|
+
unavailable.sort(inOrder);
|
|
42036
|
+
if (covered.length === 0 && firstRefusal) return err(firstRefusal);
|
|
42037
|
+
return ok({ matches, organizations_covered: covered, unavailable });
|
|
42038
|
+
}
|
|
42039
|
+
return metadataSearchDoor();
|
|
42040
|
+
},
|
|
42041
|
+
async organizationsOpen(args) {
|
|
42042
|
+
const targets = readOrgs(args?.organization_id).filter((t) => t !== null);
|
|
42043
|
+
const open = [];
|
|
42044
|
+
const unavailable = [];
|
|
42045
|
+
await Promise.all(
|
|
42046
|
+
targets.map(async (t) => {
|
|
42047
|
+
const result = await clientFor(t).storeIsOpen();
|
|
42048
|
+
if (!result.ok) unavailable.push({ organization_id: t, reason: unavailableReason(result.error) });
|
|
42049
|
+
else if (!result.data)
|
|
42050
|
+
unavailable.push({ organization_id: t, reason: "The custom data store is switched off for this organization." });
|
|
42051
|
+
else open.push(t);
|
|
42052
|
+
})
|
|
42053
|
+
);
|
|
42054
|
+
const position = (id) => targets.indexOf(id);
|
|
42055
|
+
open.sort((a, b) => position(a) - position(b));
|
|
42056
|
+
unavailable.sort((a, b) => position(a.organization_id) - position(b.organization_id));
|
|
42057
|
+
return ok({ open, unavailable });
|
|
42058
|
+
},
|
|
42059
|
+
async ownerOrganization({ table_id, record_id, organization_id }) {
|
|
42060
|
+
if (table_id) {
|
|
42061
|
+
const read = await client.tableRead({ table_id, ...organization_id ? { organization_id } : {} });
|
|
42062
|
+
if (!read.ok) return err(read.error);
|
|
42063
|
+
return ok(read.data ? read.data.organization_id ?? null : null);
|
|
42064
|
+
}
|
|
42065
|
+
if (record_id) {
|
|
42066
|
+
const read = await client.recordRead({ record_id, ...organization_id ? { organization_id } : {} });
|
|
42067
|
+
if (!read.ok) return ok(null);
|
|
42068
|
+
const targets = readOrgs(organization_id);
|
|
42069
|
+
return ok(recordOrgs.get(record_id) ?? organization_id ?? (targets.length === 1 ? targets[0] ?? null : null));
|
|
42070
|
+
}
|
|
42071
|
+
return ok(null);
|
|
41979
42072
|
},
|
|
41980
42073
|
async fieldPropose() {
|
|
41981
42074
|
const refusal = doorAbsent(DOORS.fieldPropose);
|