@ai-matrx/records 0.57.3 → 0.58.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 +116 -0
- package/dist/core/index.cjs +625 -151
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +272 -7
- package/dist/core/index.d.ts +272 -7
- package/dist/core/index.js +625 -151
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +329 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +825 -195
- package/dist/index.d.ts +825 -195
- package/dist/index.js +329 -2
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +428 -30
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +1029 -205
- package/dist/react/index.d.ts +1029 -205
- package/dist/react/index.js +428 -30
- package/dist/react/index.js.map +1 -1
- package/dist/{types-BpBSMhYq.d.cts → types-NKSc_jZq.d.cts} +31 -3
- package/dist/{types-BpBSMhYq.d.ts → types-NKSc_jZq.d.ts} +31 -3
- package/dist/use-cases/index.cjs.map +1 -1
- package/dist/use-cases/index.d.cts +2 -2
- package/dist/use-cases/index.d.ts +2 -2
- package/dist/use-cases/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { p as Uuid, T as Timestamp, u as ReadRow, q as RecordDocument, aT as TableType, aR as TableDisplay, aL as StorageMode, aS as TableOrigin, S as StoredRecord, v as Field, aq as ParityFieldType,
|
|
2
|
-
export {
|
|
1
|
+
import { p as Uuid, T as Timestamp, u as ReadRow, q as RecordDocument, aT as TableType, aR as TableDisplay, aL as StorageMode, aS as TableOrigin, S as StoredRecord, v as Field, aq as ParityFieldType, aF as RuleNodeKind, aG as RuleUse, D as RecordsError, U as UseCase, M as Actor, G as PgError, aD as RelationFlavor, am as OnDelete, aA as RelationBinding, aB as RelationCardinality, r as RecordsResult, aj as MergeFieldSource, ai as MergeFieldSemanticType, ah as MergeFieldModifier, an as OverridePolicy, $ as Delivery, aa as Freshness } from './types-NKSc_jZq.js';
|
|
2
|
+
export { J as ABSENCE_REASONS, K as ACTOR_VOCABULARY, L as AbsenceReason, O as COMPUTE_ON, Q as CONTEXT_POLICIES, V as ComputeOn, X as ContextPolicy, Y as DECLARABLE_FIELD_KINDS, Z as DELIVERIES, _ as DeclarableFieldKind, a0 as ENTITY_TOKENS, a1 as EntityToken, a2 as FIELD_SENSITIVITIES, a3 as FIELD_SOURCES, a4 as FRESHNESS, a5 as FieldBehavior, x as FieldPatch, A as FieldProposal, a6 as FieldRule, a7 as FieldSensitivity, a8 as FieldSource, E as FieldTypeWord, a9 as ForbiddenEnvelopeWord, ab as HiddenFieldNotice, ac as KERNEL_TABLES, ad as KernelTableName, ae as MERGE_FIELD_MODIFIERS, af as MERGE_FIELD_SEMANTIC_TYPES, ag as MERGE_FIELD_SOURCES, w as NewFieldDeclaration, ak as ON_DELETE, al as OVERRIDE_POLICIES, ao as PARITY_FIELD_TYPES, ap as PER_VALUE_ACCESS_WORDS, ar as ParityFieldTypeDescriptor, as as PerValueAccessWord, I as PredictedRefusal, at as ProvenancePointer, au as RELATION_BINDINGS, av as RELATION_CARDINALITIES, aw as RELATION_FLAVORS, ax as RETIRED_ACTOR_WORDS, ay as RULE_NODE_KINDS, az as RULE_USES, z as ReadValue, s as RecordGraphWritten, t as RecordRead, y as RecordRevision, R as RecordsErrorCode, aC as RelationDisplay, aE as RetiredActorWord, aH as STORAGE_MODES, aI as STORE_DOORS, aJ as STORE_KNOBS, aK as STORE_REFUSAL_CODES, H as StaleWriteDetail, aM as StoreDoorName, aN as StoreRefusalCode, aO as TABLE_DISPLAYS, aP as TABLE_ORIGINS, aQ as TABLE_TYPES, C as TableProposal, aU as VALUE_ALTERNATE_KEYS, aV as VALUE_ENVELOPE_KEYS, aW as ValueAlternate, aX as ValueAlternateKey, aY as ValueEnvelope, aZ as ValueEnvelopeKey, a_ as ValueSource, W as WriteConflict, a$ as allowsOtherValues, b0 as err, b1 as isRecordsErr, b2 as ok } from './types-NKSc_jZq.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* THE TWO LANES THE ARCHIVED-ITEMS LAW NAMES (Arman, 2026-09-09) — the same
|
|
@@ -298,7 +298,7 @@ interface CoercibleField {
|
|
|
298
298
|
* `plain_text`, `long_text`, `number` and `boolean` are behaviours that carry
|
|
299
299
|
* no parity type of their own; every other word here is a parity type.
|
|
300
300
|
*/
|
|
301
|
-
declare const FIELD_KINDS: readonly ["attachment", "checkbox", "currency", "datetime", "email", "formula", "json", "long_text", "lookup", "member", "multi_select", "number", "percent", "phone", "relation", "rollup", "select", "text", "url"];
|
|
301
|
+
declare const FIELD_KINDS: readonly ["attachment", "checkbox", "currency", "datetime", "email", "entity_reference", "formula", "json", "long_text", "lookup", "member", "multi_select", "number", "percent", "phone", "relation", "rollup", "select", "text", "url"];
|
|
302
302
|
/**
|
|
303
303
|
* 🚨 THE UNION IS DERIVED FROM THE LIST ABOVE, and the list is what the
|
|
304
304
|
* coverage test walks. Add a kind here and the test drives it; give it no arm
|
|
@@ -352,6 +352,13 @@ interface CoerceOptions {
|
|
|
352
352
|
*/
|
|
353
353
|
label?: string | undefined;
|
|
354
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* SC-R / P12. Whether a relation's config makes it an ENTITY REFERENCE: target
|
|
357
|
+
* mode `any` (REL-8) restricted by a non-empty `allowed_types`.
|
|
358
|
+
*/
|
|
359
|
+
declare function isEntityReferenceConfig(config: Record<string, unknown> | null | undefined): boolean;
|
|
360
|
+
/** The platform kinds an entity-reference Field may name, lower-cased, in its own order. */
|
|
361
|
+
declare function entityReferenceKindsOf(field: Pick<CoercibleField, "config">): string[];
|
|
355
362
|
/** The Field's name in plain words — never its key on a screen. */
|
|
356
363
|
declare function coercionLabel(field: CoercibleField): string;
|
|
357
364
|
/**
|
|
@@ -765,6 +772,48 @@ interface PipelineMoveResult {
|
|
|
765
772
|
}[];
|
|
766
773
|
what_happens?: string;
|
|
767
774
|
}
|
|
775
|
+
/** One card of a batch move (`custom.pipeline_move_many`). The version is REQUIRED: it is the
|
|
776
|
+
* version the board loaded, and a card that changed since answers `changed_since_loaded`. */
|
|
777
|
+
interface PipelineMoveManyItem {
|
|
778
|
+
record_id: Uuid;
|
|
779
|
+
stage: string;
|
|
780
|
+
expected_version: number;
|
|
781
|
+
/** Columns the stage asks for, filled in on the way in. */
|
|
782
|
+
also?: Record<string, unknown>;
|
|
783
|
+
}
|
|
784
|
+
/** What one card of a batch move came to. The sentence is always the store's own. */
|
|
785
|
+
type PipelineMoveVerdict = "moved" | "needs_approval" | "needs_fields" | "changed_since_loaded" | "no_right" | "refused";
|
|
786
|
+
interface PipelineMoveManyResult {
|
|
787
|
+
index: number;
|
|
788
|
+
record_id: Uuid;
|
|
789
|
+
stage: string;
|
|
790
|
+
verdict: PipelineMoveVerdict;
|
|
791
|
+
sentence: string;
|
|
792
|
+
/** Set on `needs_fields`: the empty columns the stage asks for. */
|
|
793
|
+
needs?: PipelineMissingField[];
|
|
794
|
+
/** Set on `moved` / `needs_approval`: the card's version now. */
|
|
795
|
+
version?: number;
|
|
796
|
+
/** Set on `changed_since_loaded`: the version that won. */
|
|
797
|
+
current_version?: number;
|
|
798
|
+
expected_version?: number;
|
|
799
|
+
approval_id?: Uuid;
|
|
800
|
+
approvers?: {
|
|
801
|
+
user_id: Uuid;
|
|
802
|
+
name: string | null;
|
|
803
|
+
why: string;
|
|
804
|
+
}[];
|
|
805
|
+
warnings?: StageRuleWarning[];
|
|
806
|
+
rule?: string;
|
|
807
|
+
code?: string;
|
|
808
|
+
}
|
|
809
|
+
/** What `custom.pipeline_move_many` answers: the counts, then one verdict per card in order. */
|
|
810
|
+
interface PipelineMoveMany {
|
|
811
|
+
asked: number;
|
|
812
|
+
moved: number;
|
|
813
|
+
needs_approval: number;
|
|
814
|
+
not_moved: number;
|
|
815
|
+
results: PipelineMoveManyResult[];
|
|
816
|
+
}
|
|
768
817
|
/**
|
|
769
818
|
* ONE GATE ON A STAGE, as the condition builder on the stage settings screen writes it.
|
|
770
819
|
* `requires`, `who` and `limits` are sugar over this shape; this is the general form, and
|
|
@@ -1312,6 +1361,124 @@ interface PortalCard {
|
|
|
1312
1361
|
* decides whether they can sign in at all.
|
|
1313
1362
|
*/
|
|
1314
1363
|
external_lane_open: boolean;
|
|
1364
|
+
/** S6 — the look and forms exactly as the owner stored them (`{}` when none). */
|
|
1365
|
+
config: PortalConfig;
|
|
1366
|
+
/** S6 — the look as a client sees it: the portal's own values over the organization's brand. */
|
|
1367
|
+
style: PortalStyle;
|
|
1368
|
+
/** S6 — every form on the portal, in its order, with its title, Table and state. */
|
|
1369
|
+
forms: PortalFormRef[];
|
|
1370
|
+
/** S6 — the accent names a portal may carry (the design system's `STYLE_COLORS`). */
|
|
1371
|
+
accents: PortalAccent[];
|
|
1372
|
+
/**
|
|
1373
|
+
* S6 — the pictures that could be this portal's logo: the organization's own PUBLIC pictures in
|
|
1374
|
+
* Files, newest first. A private file is never offered, because the store would refuse it.
|
|
1375
|
+
*/
|
|
1376
|
+
logo_candidates: Array<{
|
|
1377
|
+
file_id: Uuid;
|
|
1378
|
+
name: string;
|
|
1379
|
+
url: string | null;
|
|
1380
|
+
}>;
|
|
1381
|
+
}
|
|
1382
|
+
/** The design system's colour names (`STYLE_COLORS`), which is all an accent may be. */
|
|
1383
|
+
declare const PORTAL_ACCENTS: readonly ["slate", "green", "amber", "red", "blue", "violet", "teal"];
|
|
1384
|
+
type PortalAccent = (typeof PORTAL_ACCENTS)[number];
|
|
1385
|
+
declare function isPortalAccent(word: unknown): word is PortalAccent;
|
|
1386
|
+
/** One link in a portal's footer. The store takes only `https://`, `mailto:` and `tel:`. */
|
|
1387
|
+
interface PortalFooterLink {
|
|
1388
|
+
label: string;
|
|
1389
|
+
url: string;
|
|
1390
|
+
}
|
|
1391
|
+
/** A portal's look as the owner sets it. Every key is optional; absent means "the organization's". */
|
|
1392
|
+
interface PortalStyleInput {
|
|
1393
|
+
display_name?: string | null;
|
|
1394
|
+
welcome?: string | null;
|
|
1395
|
+
logo_file_id?: Uuid | null;
|
|
1396
|
+
accent?: PortalAccent | null;
|
|
1397
|
+
footer_links?: PortalFooterLink[] | null;
|
|
1398
|
+
}
|
|
1399
|
+
/** One form on a portal, as the owner sets it. `order` is the position; `label` overrides the title. */
|
|
1400
|
+
interface PortalFormInput {
|
|
1401
|
+
form_id: Uuid;
|
|
1402
|
+
label?: string | null;
|
|
1403
|
+
order?: number | null;
|
|
1404
|
+
}
|
|
1405
|
+
/**
|
|
1406
|
+
* What `portalDeclare({ config })` sends. A key given REPLACES that key; a key not given is KEPT;
|
|
1407
|
+
* `style: null` puts the organization's brand back and `forms: []` takes every form off.
|
|
1408
|
+
*/
|
|
1409
|
+
interface PortalConfigInput {
|
|
1410
|
+
style?: PortalStyleInput | null;
|
|
1411
|
+
forms?: PortalFormInput[] | null;
|
|
1412
|
+
}
|
|
1413
|
+
/** The look and forms as the store holds them (normalized by the store). */
|
|
1414
|
+
interface PortalConfig {
|
|
1415
|
+
style?: PortalStyleInput;
|
|
1416
|
+
forms?: Array<{
|
|
1417
|
+
form_id: Uuid;
|
|
1418
|
+
label?: string;
|
|
1419
|
+
order: number;
|
|
1420
|
+
}>;
|
|
1421
|
+
}
|
|
1422
|
+
/** The look a client is shown — resolved by the store, never computed by a screen. */
|
|
1423
|
+
interface PortalStyle {
|
|
1424
|
+
display_name: string;
|
|
1425
|
+
welcome: string | null;
|
|
1426
|
+
logo_file_id: Uuid | null;
|
|
1427
|
+
/** The logo's PUBLIC address, or null. Readable by anybody the portal is shown to. */
|
|
1428
|
+
logo_url: string | null;
|
|
1429
|
+
/** Null means the app's own colour. */
|
|
1430
|
+
accent: PortalAccent | null;
|
|
1431
|
+
footer_links: PortalFooterLink[];
|
|
1432
|
+
/** Which of the values above came from the organization rather than the portal. */
|
|
1433
|
+
from_organization: Array<"display_name" | "logo">;
|
|
1434
|
+
}
|
|
1435
|
+
/** One form on a portal, with what the owner needs to see about it. */
|
|
1436
|
+
interface PortalFormRef {
|
|
1437
|
+
form_id: Uuid;
|
|
1438
|
+
/** What the portal calls it (the owner's label, else the form's title). */
|
|
1439
|
+
label: string;
|
|
1440
|
+
order: number;
|
|
1441
|
+
title: string;
|
|
1442
|
+
table_id: Uuid | null;
|
|
1443
|
+
table: string;
|
|
1444
|
+
/** `gone` is a form that was removed; the outsider's list only ever carries `open`. */
|
|
1445
|
+
state: "open" | "closed" | "full" | "gone";
|
|
1446
|
+
}
|
|
1447
|
+
/** A Table's stages as a portal client may be told them (`custom.portal_me` → tables[].stage). */
|
|
1448
|
+
interface PortalStage {
|
|
1449
|
+
/** The stage Field's key on the record. */
|
|
1450
|
+
field: string;
|
|
1451
|
+
label: string;
|
|
1452
|
+
/** In the order they were declared. A record stores the stage's `key`. */
|
|
1453
|
+
stages: Array<{
|
|
1454
|
+
key: string;
|
|
1455
|
+
label: string;
|
|
1456
|
+
retired: boolean;
|
|
1457
|
+
}>;
|
|
1458
|
+
}
|
|
1459
|
+
/** What `custom.portal_form` answers: one form on the caller's own portal. */
|
|
1460
|
+
interface PortalFormSpec {
|
|
1461
|
+
form_id: Uuid;
|
|
1462
|
+
portal_id: Uuid;
|
|
1463
|
+
table_id: Uuid;
|
|
1464
|
+
title: string;
|
|
1465
|
+
label: string;
|
|
1466
|
+
presentation: Record<string, unknown>;
|
|
1467
|
+
/** The form's exposed Fields as the store holds them — never the one naming the client. */
|
|
1468
|
+
fields: Array<Record<string, unknown> & {
|
|
1469
|
+
id: Uuid;
|
|
1470
|
+
key: string;
|
|
1471
|
+
}>;
|
|
1472
|
+
required: string[];
|
|
1473
|
+
state: "open" | "closed" | "full";
|
|
1474
|
+
message: string | null;
|
|
1475
|
+
}
|
|
1476
|
+
/** What `custom.portal_form_submit` answers. `held` waits for the office; `message` says so. */
|
|
1477
|
+
interface PortalFormAnswer {
|
|
1478
|
+
submission_id: Uuid | null;
|
|
1479
|
+
record_id: Uuid | null;
|
|
1480
|
+
state: "accepted" | "held" | "rejected" | "closed" | "full" | "too_many";
|
|
1481
|
+
message: string | null;
|
|
1315
1482
|
}
|
|
1316
1483
|
/** What `custom.portal_invite` answers. `say` is the door's own sentence. */
|
|
1317
1484
|
interface PortalInvitation {
|
|
@@ -1438,6 +1605,22 @@ type AggregateFilter = string | number | boolean | null | AggregateWindow;
|
|
|
1438
1605
|
* lands somewhere else, which is the only way a drill-through can lie.
|
|
1439
1606
|
*/
|
|
1440
1607
|
type RecordFilter = Record<string, AggregateFilter>;
|
|
1608
|
+
/**
|
|
1609
|
+
* S2-PRIME FILTER-GROUPS — A READ DOOR'S QUESTION, IN EITHER OF ITS TWO SHAPES.
|
|
1610
|
+
*
|
|
1611
|
+
* The flat `RecordFilter` above (field key → scalar / `null` / window, AND only) is what
|
|
1612
|
+
* dashboards, drill-throughs and the notifier carry. A `RuleExpression` — `{op, args}`, ALL / ANY /
|
|
1613
|
+
* NOT groups nested to any depth, fields by id — is what the condition builder, a view's own
|
|
1614
|
+
* filter and every membership Rule speak. `custom.record_filter_sql(org, table, filter)` turns
|
|
1615
|
+
* EITHER into the one WHERE clause the grid (`list`), the aggregate and the board all use, so the
|
|
1616
|
+
* three can never disagree about which records a view holds.
|
|
1617
|
+
*/
|
|
1618
|
+
type StoreFilter = RecordFilter | RuleExpression;
|
|
1619
|
+
/**
|
|
1620
|
+
* Is this filter a Rule expression? The store's own test (`custom.filter_is_rule`): an object
|
|
1621
|
+
* whose `op` is a word and which carries `args`.
|
|
1622
|
+
*/
|
|
1623
|
+
declare function isRuleFilter(filter: unknown): filter is RuleExpression;
|
|
1441
1624
|
/** One measure. `count` counts rows and needs no Field; the rest read one. */
|
|
1442
1625
|
interface AggregateMeasure {
|
|
1443
1626
|
op: AggregateOperation;
|
|
@@ -1453,6 +1636,90 @@ interface AggregateRow {
|
|
|
1453
1636
|
groups: Record<string, string | null>;
|
|
1454
1637
|
measures: Record<string, number | null>;
|
|
1455
1638
|
row_count: number;
|
|
1639
|
+
/**
|
|
1640
|
+
* S3 — present only when the question carried a comparison. The same group
|
|
1641
|
+
* in the PRIOR window: a bucket is matched by its position in its own window
|
|
1642
|
+
* (week 1 of September beside week 1 of August), so `prior_groups` names the
|
|
1643
|
+
* prior bucket's own date. `null` when the prior window had no such group.
|
|
1644
|
+
*/
|
|
1645
|
+
prior_groups?: Record<string, string | null> | null;
|
|
1646
|
+
/** The prior window's measures, keyed exactly like `measures`. */
|
|
1647
|
+
prior_measures?: Record<string, number | null> | null;
|
|
1648
|
+
prior_row_count?: number | null;
|
|
1649
|
+
/** Every measure now and before, the change, and the change as a percent of before. */
|
|
1650
|
+
delta?: Record<string, AggregateDelta> | null;
|
|
1651
|
+
/** The two windows this row was worked out over, and the calendar that cut them. */
|
|
1652
|
+
compare?: AggregateCompareWindows | null;
|
|
1653
|
+
/**
|
|
1654
|
+
* S3 — a compared, bucketed row's POSITION in its window (0 = the first
|
|
1655
|
+
* bucket). A row the current window has not reached yet has a position and
|
|
1656
|
+
* no current bucket, so a chart names it "Week 6" rather than inventing a date.
|
|
1657
|
+
*/
|
|
1658
|
+
position?: number | null;
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* S3 — WHAT A PERIOD IS COMPARED AGAINST (`custom.agg_compare_kinds()`).
|
|
1662
|
+
* `previous_period` is the period before, of the same length (August before
|
|
1663
|
+
* September; an explicit window shifted back by its own length);
|
|
1664
|
+
* `same_period_last_year`; `range` is a fixed `baseline`.
|
|
1665
|
+
*/
|
|
1666
|
+
type AggregateCompareKind = "previous_period" | "same_period_last_year" | "range";
|
|
1667
|
+
/**
|
|
1668
|
+
* S3 — ONE COMPARISON, as `custom.record_aggregate(p_compare)` and a
|
|
1669
|
+
* dashboard block's `compare` both take it. The current window is either the
|
|
1670
|
+
* calendar `period` holding `at` (default: now, in the organization's time
|
|
1671
|
+
* zone) or an explicit `from`/`to`. A date alone ("2026-09-01") is that local
|
|
1672
|
+
* day in the organization's time zone.
|
|
1673
|
+
*/
|
|
1674
|
+
interface AggregateCompare {
|
|
1675
|
+
against?: AggregateCompareKind;
|
|
1676
|
+
/** The date Field the period runs along. Defaults to the bucket's key. */
|
|
1677
|
+
key?: string;
|
|
1678
|
+
period?: AggregateBucket;
|
|
1679
|
+
at?: string;
|
|
1680
|
+
from?: string;
|
|
1681
|
+
to?: string;
|
|
1682
|
+
/** Compare the part of the period that has happened ("month to date"). */
|
|
1683
|
+
to_date?: boolean;
|
|
1684
|
+
/** The fixed period `range` compares against. Half-open: `to` is excluded. */
|
|
1685
|
+
baseline?: {
|
|
1686
|
+
from: string;
|
|
1687
|
+
to: string;
|
|
1688
|
+
};
|
|
1689
|
+
}
|
|
1690
|
+
/** One measure now and before. `change_pct` is null when before was nothing or zero. */
|
|
1691
|
+
interface AggregateDelta {
|
|
1692
|
+
current: number | null;
|
|
1693
|
+
prior: number | null;
|
|
1694
|
+
change: number | null;
|
|
1695
|
+
change_pct: number | null;
|
|
1696
|
+
}
|
|
1697
|
+
/**
|
|
1698
|
+
* S3 — THE TWO WINDOWS the store actually ran, as local ISO moments with the
|
|
1699
|
+
* organization's offset ("2026-09-01T00:00:00-07:00"), and the calendar that
|
|
1700
|
+
* cut them. A screen labels the comparison from THIS, never from its own clock.
|
|
1701
|
+
*/
|
|
1702
|
+
interface AggregateCompareWindows {
|
|
1703
|
+
key: string;
|
|
1704
|
+
against: AggregateCompareKind;
|
|
1705
|
+
period: AggregateBucket | null;
|
|
1706
|
+
to_date: boolean;
|
|
1707
|
+
time_zone: string;
|
|
1708
|
+
week_start: string;
|
|
1709
|
+
/** The bucket grain the windows were counted in, when the question had a bucket. */
|
|
1710
|
+
grain: AggregateBucket | null;
|
|
1711
|
+
/** How many buckets the current window holds — what a target's pace is shared over. */
|
|
1712
|
+
bucket_count: number | null;
|
|
1713
|
+
window: {
|
|
1714
|
+
from: string;
|
|
1715
|
+
to: string;
|
|
1716
|
+
};
|
|
1717
|
+
prior_window: {
|
|
1718
|
+
from: string;
|
|
1719
|
+
to: string;
|
|
1720
|
+
};
|
|
1721
|
+
/** On a row from `recordAggregate`: that row's bucket position (see `AggregateRow.position`). */
|
|
1722
|
+
position?: number | null;
|
|
1456
1723
|
}
|
|
1457
1724
|
/** The measure key the store answers with, so a chart can find its own series. */
|
|
1458
1725
|
declare function measureKey(measure: AggregateMeasure): string;
|
|
@@ -1468,7 +1735,7 @@ declare function measureKey(measure: AggregateMeasure): string;
|
|
|
1468
1735
|
* one question. `undefined` and an empty filter are both `"{}"` — the caller
|
|
1469
1736
|
* asked nothing, and there is only one way to ask nothing.
|
|
1470
1737
|
*/
|
|
1471
|
-
declare function stableFilterKey(filter:
|
|
1738
|
+
declare function stableFilterKey(filter: StoreFilter | null | undefined): string;
|
|
1472
1739
|
|
|
1473
1740
|
/** `custom.decoration_colors()` — the palette, in the order an uncolored choice takes. */
|
|
1474
1741
|
type DecorationColor = "slate" | "green" | "amber" | "red" | "blue" | "violet" | "teal";
|
|
@@ -1702,6 +1969,187 @@ declare function recordChangeTrigger(tableId: Uuid, options?: {
|
|
|
1702
1969
|
actions?: RecordChangeAction[];
|
|
1703
1970
|
changed_fields?: string[];
|
|
1704
1971
|
};
|
|
1972
|
+
/**
|
|
1973
|
+
* One entry of `custom.table_list_everywhere` — `public.get_user_tables`' own shape plus
|
|
1974
|
+
* `store`, so a picker swaps one call and keeps its code. `store` says which home opens it.
|
|
1975
|
+
*/
|
|
1976
|
+
interface TableListEntry {
|
|
1977
|
+
id: Uuid;
|
|
1978
|
+
table_name: string;
|
|
1979
|
+
description: string | null;
|
|
1980
|
+
version: number | null;
|
|
1981
|
+
user_id: Uuid | null;
|
|
1982
|
+
is_public: boolean | null;
|
|
1983
|
+
visibility: string | null;
|
|
1984
|
+
organization_id: Uuid;
|
|
1985
|
+
created_at: string;
|
|
1986
|
+
updated_at: string | null;
|
|
1987
|
+
last_activity_at: string | null;
|
|
1988
|
+
row_count: number;
|
|
1989
|
+
field_count: number;
|
|
1990
|
+
store: "older" | "records";
|
|
1991
|
+
}
|
|
1992
|
+
/** Where a synced table comes from. `external_id` is the source's own id (a spreadsheet id). */
|
|
1993
|
+
interface TableSyncSource {
|
|
1994
|
+
provider: string;
|
|
1995
|
+
external_id: string;
|
|
1996
|
+
tab_id?: string | null;
|
|
1997
|
+
synced_at?: string | null;
|
|
1998
|
+
}
|
|
1999
|
+
/** What `custom.table_sync` takes: the source, its columns, and every row it has NOW. */
|
|
2000
|
+
interface TableSyncSpec {
|
|
2001
|
+
source: TableSyncSource;
|
|
2002
|
+
table_name: string;
|
|
2003
|
+
columns: string[];
|
|
2004
|
+
rows: {
|
|
2005
|
+
ref: string;
|
|
2006
|
+
values: Record<string, string | number | boolean | null>;
|
|
2007
|
+
}[];
|
|
2008
|
+
}
|
|
2009
|
+
interface TableSyncResult {
|
|
2010
|
+
table_id: Uuid;
|
|
2011
|
+
created: boolean;
|
|
2012
|
+
fields_added: number;
|
|
2013
|
+
rows_inserted: number;
|
|
2014
|
+
rows_updated: number;
|
|
2015
|
+
rows_archived: number;
|
|
2016
|
+
source_system: string;
|
|
2017
|
+
}
|
|
2018
|
+
/**
|
|
2019
|
+
* A sheet tab's cells (header row first) → the spec `custom.table_sync` takes. Every row is
|
|
2020
|
+
* named by its sheet row number (`row-2` is the first row under the header) unless
|
|
2021
|
+
* `refColumn` names a column holding a stable id; a blank or repeated ref is refused here, so
|
|
2022
|
+
* the store never sees two rows claiming to be the same source row. Wholly blank rows are
|
|
2023
|
+
* skipped. Pure.
|
|
2024
|
+
*/
|
|
2025
|
+
declare function sheetSyncSpec(args: {
|
|
2026
|
+
source: TableSyncSource;
|
|
2027
|
+
tableName: string;
|
|
2028
|
+
cells: readonly (readonly (string | number | boolean | null | undefined)[])[];
|
|
2029
|
+
refColumn?: string;
|
|
2030
|
+
}): TableSyncSpec;
|
|
2031
|
+
/** One row of `custom.table_row_counts`: the rows of that Table this reader may see. */
|
|
2032
|
+
interface TableRowCount {
|
|
2033
|
+
table_id: Uuid;
|
|
2034
|
+
visible_rows: number;
|
|
2035
|
+
}
|
|
2036
|
+
/**
|
|
2037
|
+
* One row of `custom.record_headers`: the row's own columns the document door does not answer.
|
|
2038
|
+
* `created_by` is the caller's own id on rows the caller made and null on every other; `mine`
|
|
2039
|
+
* says which.
|
|
2040
|
+
*/
|
|
2041
|
+
interface RecordHeader {
|
|
2042
|
+
id: Uuid;
|
|
2043
|
+
table_id: Uuid;
|
|
2044
|
+
created_at: string;
|
|
2045
|
+
updated_at: string;
|
|
2046
|
+
version: number;
|
|
2047
|
+
deleted_at: string | null;
|
|
2048
|
+
mine: boolean;
|
|
2049
|
+
created_by: Uuid | null;
|
|
2050
|
+
}
|
|
2051
|
+
/**
|
|
2052
|
+
* Fold `table_row_counts` onto a table list: `row_count` set on every Table the counts name.
|
|
2053
|
+
* A Table the counts do not name keeps what it had — the store answers no row for a Table this
|
|
2054
|
+
* reader may not know, and that is never turned into a zero. Pure.
|
|
2055
|
+
*/
|
|
2056
|
+
declare function withRowCounts<T extends {
|
|
2057
|
+
id: Uuid;
|
|
2058
|
+
row_count?: number | null;
|
|
2059
|
+
}>(tables: readonly T[], counts: readonly TableRowCount[] | null | undefined): T[];
|
|
2060
|
+
/** What `custom.view_record_order_set` answers. */
|
|
2061
|
+
interface ViewOrderSet {
|
|
2062
|
+
view_id: Uuid;
|
|
2063
|
+
table_id: Uuid;
|
|
2064
|
+
order: "manual";
|
|
2065
|
+
named: number;
|
|
2066
|
+
positioned: number;
|
|
2067
|
+
}
|
|
2068
|
+
/**
|
|
2069
|
+
* The order to send after a drag: `order` with `moved` taken out and put at `toIndex` (clamped).
|
|
2070
|
+
* The store keeps every row the call does not name in its old place after the named ones, so a
|
|
2071
|
+
* screen may send only the rows it shows. Pure.
|
|
2072
|
+
*/
|
|
2073
|
+
declare function moveInOrder(order: readonly Uuid[], moved: Uuid, toIndex: number): Uuid[];
|
|
2074
|
+
/**
|
|
2075
|
+
* What `custom.table_share_outside_grant` answers. `person` says which path ran:
|
|
2076
|
+
* `outside_account` (granted at once and notified — never made a member), `member` (a plain
|
|
2077
|
+
* share), `no_account` (the invitation door's own answer, with its link and delivery).
|
|
2078
|
+
*/
|
|
2079
|
+
interface OutsideShareAnswer {
|
|
2080
|
+
granted: boolean;
|
|
2081
|
+
invited: boolean;
|
|
2082
|
+
joined: boolean;
|
|
2083
|
+
person: "outside_account" | "member" | "no_account";
|
|
2084
|
+
email: string;
|
|
2085
|
+
table: string;
|
|
2086
|
+
level: string;
|
|
2087
|
+
level_label: string;
|
|
2088
|
+
say: string;
|
|
2089
|
+
user_id?: Uuid;
|
|
2090
|
+
permission_id?: Uuid;
|
|
2091
|
+
invitation_id?: Uuid | null;
|
|
2092
|
+
accept_path?: string | null;
|
|
2093
|
+
delivery_say?: string | null;
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
/** The three placement facts, as the Table document or `custom.table` carries them. */
|
|
2097
|
+
interface TablePlacement {
|
|
2098
|
+
kept_by_the_app?: boolean | null;
|
|
2099
|
+
kept_for?: string | null;
|
|
2100
|
+
offered_as_context?: boolean | null;
|
|
2101
|
+
}
|
|
2102
|
+
/**
|
|
2103
|
+
* One row of `custom.table_facts` since SC-1 — the two lane facts it always answered
|
|
2104
|
+
* (`visibility`, `mine`) and the placement, with the sentence a person reads and where the
|
|
2105
|
+
* table is used. A store without the SC-1 door answers the first three columns only; every
|
|
2106
|
+
* placement column is then `undefined`, and the readers below treat the table as the
|
|
2107
|
+
* organization's own — exactly what that store's older screens did.
|
|
2108
|
+
*/
|
|
2109
|
+
interface TablePlacementFact extends TablePlacement {
|
|
2110
|
+
table_id: Uuid;
|
|
2111
|
+
visibility: string;
|
|
2112
|
+
mine: boolean;
|
|
2113
|
+
/** The heading a kept table is listed under: "The context system", "The choices behind your columns", … */
|
|
2114
|
+
keeper_group?: string | null;
|
|
2115
|
+
/** One plain sentence: who keeps it and where it opens from. Null for the organization's own. */
|
|
2116
|
+
keeper_says?: string | null;
|
|
2117
|
+
/** Where the table is used: `table` (another Table, or itself) or `scope` (a context scope). */
|
|
2118
|
+
used_in_kind?: "table" | "scope" | null;
|
|
2119
|
+
used_in_id?: Uuid | null;
|
|
2120
|
+
/** The Table that page belongs to, when `used_in_kind` is `table`. */
|
|
2121
|
+
used_in_table_id?: Uuid | null;
|
|
2122
|
+
}
|
|
2123
|
+
/** Whether a person's list of tables keeps this one out of sight until "Show everything". */
|
|
2124
|
+
declare function keptOutOfSight(placement: TablePlacement | null | undefined): boolean;
|
|
2125
|
+
/** Whether the context picker may offer this Table. Absent is no. */
|
|
2126
|
+
declare function offeredAsContext(placement: TablePlacement | null | undefined): boolean;
|
|
2127
|
+
/**
|
|
2128
|
+
* The placement facts folded onto a table list, by id. Pure — returns new objects and leaves
|
|
2129
|
+
* the list it was given alone. A table the facts do not name is returned unchanged.
|
|
2130
|
+
*/
|
|
2131
|
+
declare function withTablePlacement<T extends {
|
|
2132
|
+
id: Uuid;
|
|
2133
|
+
}>(tables: readonly T[], facts: readonly TablePlacementFact[] | null | undefined): Array<T & Partial<TablePlacementFact>>;
|
|
2134
|
+
/**
|
|
2135
|
+
* THE KEPT TABLES, GROUPED UNDER THEIR KEEPER, in the order each group first appears. A kept
|
|
2136
|
+
* table the store gave no heading goes under "Kept by the app" — never dropped.
|
|
2137
|
+
*/
|
|
2138
|
+
declare function keptGroups<T extends TablePlacement & Partial<TablePlacementFact>>(tables: readonly T[]): Array<{
|
|
2139
|
+
group: string;
|
|
2140
|
+
tables: T[];
|
|
2141
|
+
}>;
|
|
2142
|
+
/**
|
|
2143
|
+
* WHERE A KEPT TABLE OPENS FROM (THE DOOR LAW): the host's own addresses for a table and for a
|
|
2144
|
+
* context scope, chosen by what the store said the table is used in. With nothing said, the
|
|
2145
|
+
* table's own page — a kept table is never a row with nowhere to go.
|
|
2146
|
+
*/
|
|
2147
|
+
declare function keptTableHref(fact: {
|
|
2148
|
+
table_id: Uuid;
|
|
2149
|
+
} & Partial<TablePlacementFact>, hrefs: {
|
|
2150
|
+
table: (tableId: Uuid) => string;
|
|
2151
|
+
scope: (scopeId: Uuid) => string;
|
|
2152
|
+
}): string;
|
|
1705
2153
|
|
|
1706
2154
|
/** The seven shapes a block can take, exactly as `custom.dashboard_kinds()` answers. */
|
|
1707
2155
|
type DashboardBlockKind = "number" | "bar" | "column" | "line" | "donut" | "table" | "stuck";
|
|
@@ -1734,6 +2182,43 @@ interface DashboardBlock {
|
|
|
1734
2182
|
state_key?: string;
|
|
1735
2183
|
/** `stuck` only: how long a record may sit on the same value. Defaults to 14. */
|
|
1736
2184
|
days?: number;
|
|
2185
|
+
/**
|
|
2186
|
+
* S3 — the comparison this block makes (this month against last month).
|
|
2187
|
+
* The door fills `key` from the bucket when it is left out, and refuses a
|
|
2188
|
+
* comparison along a Field the Table does not have, by name.
|
|
2189
|
+
*/
|
|
2190
|
+
compare?: AggregateCompare | null;
|
|
2191
|
+
/** S3 — the number this block is aiming for. */
|
|
2192
|
+
target?: DashboardTarget | null;
|
|
2193
|
+
}
|
|
2194
|
+
/**
|
|
2195
|
+
* S3 — A BLOCK'S TARGET. `measure` is one of the block's own measure keys
|
|
2196
|
+
* (default: the first). `per: "period"` is a target for the whole window (a
|
|
2197
|
+
* monthly target — a bucketed chart draws its even share per bucket as the
|
|
2198
|
+
* pace); `per: "bucket"` is a target for every bar or point.
|
|
2199
|
+
*
|
|
2200
|
+
* A target is a FIXED NUMBER (`value`) or A GOAL COLUMN (`field`, a Field key of
|
|
2201
|
+
* the block's Table): the store adds that column up (`op`, default `sum`) over
|
|
2202
|
+
* exactly the records the block's own number read — same filter, same window,
|
|
2203
|
+
* same reader — so "invoiced against quoted" is about the same jobs. Exactly
|
|
2204
|
+
* one of the two; a goal column is always `per: "period"`.
|
|
2205
|
+
*/
|
|
2206
|
+
type DashboardTarget = DashboardTargetBase & ({
|
|
2207
|
+
value: number;
|
|
2208
|
+
field?: never;
|
|
2209
|
+
op?: never;
|
|
2210
|
+
} | {
|
|
2211
|
+
field: string;
|
|
2212
|
+
op?: DashboardTargetOp;
|
|
2213
|
+
value?: never;
|
|
2214
|
+
});
|
|
2215
|
+
/** How a goal column is added up across the block's records. */
|
|
2216
|
+
type DashboardTargetOp = "sum" | "avg" | "min" | "max";
|
|
2217
|
+
/** What every target carries, whichever kind it is. */
|
|
2218
|
+
interface DashboardTargetBase {
|
|
2219
|
+
label?: string;
|
|
2220
|
+
measure?: string;
|
|
2221
|
+
per?: "period" | "bucket";
|
|
1737
2222
|
}
|
|
1738
2223
|
/** One dashboard as `custom.dashboards` reports it to its organization. */
|
|
1739
2224
|
interface DashboardSummary {
|
|
@@ -1792,6 +2277,56 @@ interface DashboardBlockResult {
|
|
|
1792
2277
|
refused?: string;
|
|
1793
2278
|
/** The SQLSTATE that refusal carried. */
|
|
1794
2279
|
sqlstate?: string;
|
|
2280
|
+
/**
|
|
2281
|
+
* S3 — the windows this block was actually compared over; `null` when it was
|
|
2282
|
+
* not compared. (The comparison it was ASKED to make is the saved block's.)
|
|
2283
|
+
*/
|
|
2284
|
+
compare?: AggregateCompareWindows | null;
|
|
2285
|
+
/** S3 — why a canvas comparison was not applied to this block (it has no date). */
|
|
2286
|
+
compare_refused?: string;
|
|
2287
|
+
/**
|
|
2288
|
+
* S3 — the block's first (or target) measure added up across its rows, now
|
|
2289
|
+
* and before, when the measure adds up (count, sum, filled, empty) or the
|
|
2290
|
+
* block has one row. Worked out by the store from the rows it answered, so
|
|
2291
|
+
* a tile, a chart and a ring cannot disagree.
|
|
2292
|
+
*/
|
|
2293
|
+
totals?: DashboardTotals;
|
|
2294
|
+
/** S3 — the target, with how far the current total has come and its pace per bucket. */
|
|
2295
|
+
target?: DashboardTargetResult;
|
|
2296
|
+
}
|
|
2297
|
+
/** S3 — one block's total, now and before. */
|
|
2298
|
+
interface DashboardTotals {
|
|
2299
|
+
measure: string;
|
|
2300
|
+
current: number | null;
|
|
2301
|
+
prior: number | null;
|
|
2302
|
+
change: number | null;
|
|
2303
|
+
change_pct: number | null;
|
|
2304
|
+
}
|
|
2305
|
+
/** S3 — a target as the run answers it. */
|
|
2306
|
+
interface DashboardTargetResult {
|
|
2307
|
+
/**
|
|
2308
|
+
* The number aimed at: the fixed value, or the goal column added up over this
|
|
2309
|
+
* block's records. `null` when a goal column had nothing to add up, or was refused.
|
|
2310
|
+
*/
|
|
2311
|
+
value: number | null;
|
|
2312
|
+
/** A goal column's key, when the target is read from one. */
|
|
2313
|
+
field?: string;
|
|
2314
|
+
/** How that column was added up. */
|
|
2315
|
+
op?: DashboardTargetOp;
|
|
2316
|
+
/**
|
|
2317
|
+
* The store's own sentence when THIS reader may not read the goal column — the
|
|
2318
|
+
* block still answers its number; only the target is withheld.
|
|
2319
|
+
*/
|
|
2320
|
+
refused?: string;
|
|
2321
|
+
label: string;
|
|
2322
|
+
measure: string;
|
|
2323
|
+
per: "period" | "bucket";
|
|
2324
|
+
/** The current total the target is measured against. */
|
|
2325
|
+
current: number | null;
|
|
2326
|
+
/** current ÷ value, 4 decimals. */
|
|
2327
|
+
progress: number | null;
|
|
2328
|
+
/** The line a bucketed chart draws: the target's even share of one bucket, or the target itself per bucket. */
|
|
2329
|
+
pace: number | null;
|
|
1795
2330
|
}
|
|
1796
2331
|
/** What `custom.dashboard_run` answers: the canvas, and every block's own result. */
|
|
1797
2332
|
interface DashboardRunResult {
|
|
@@ -1801,6 +2336,15 @@ interface DashboardRunResult {
|
|
|
1801
2336
|
presentation: Record<string, unknown>;
|
|
1802
2337
|
/** The one filter bar this run was asked with. */
|
|
1803
2338
|
filter: Record<string, AggregateFilter>;
|
|
2339
|
+
/** S3 — the date grain the canvas re-cut every bucketed block to, or null. */
|
|
2340
|
+
grain?: AggregateBucket | null;
|
|
2341
|
+
/** S3 — the canvas comparison this run was asked with, or null. */
|
|
2342
|
+
compare?: AggregateCompare | null;
|
|
2343
|
+
/** S3 — the organization's calendar every date on this canvas was cut with. */
|
|
2344
|
+
calendar?: {
|
|
2345
|
+
time_zone: string;
|
|
2346
|
+
week_start: string;
|
|
2347
|
+
};
|
|
1804
2348
|
blocks: DashboardBlockResult[];
|
|
1805
2349
|
}
|
|
1806
2350
|
|
|
@@ -2532,11 +3076,22 @@ interface SavedViewRow {
|
|
|
2532
3076
|
name: string;
|
|
2533
3077
|
table_id: Uuid | null;
|
|
2534
3078
|
filters: RecordFilter;
|
|
3079
|
+
/**
|
|
3080
|
+
* THE WHOLE VIEW (S0 ONE-SAVED-VIEW, 2026-09-23): `platform.saved_view` is the ONE saved-view
|
|
3081
|
+
* store, so this is what the view bar, the board, the calendar and the gallery draw from —
|
|
3082
|
+
* `layout` (the kind), `group_field`, `measure`, `date_field`, `image_field`, `sorts`, `rule_id`,
|
|
3083
|
+
* `is_default`, `presentation`, G7's `grid`, G13's `order`, the mover's `moved_from`.
|
|
3084
|
+
*/
|
|
3085
|
+
definition: Record<string, unknown>;
|
|
2535
3086
|
created_at: string;
|
|
2536
3087
|
}
|
|
2537
|
-
/**
|
|
3088
|
+
/**
|
|
3089
|
+
* What `custom.view_declare` is asked for. With `view_id` the door MERGES: `name` changes only
|
|
3090
|
+
* when sent, `filters` only when the key is sent, each `definition` key replaces that one key and
|
|
3091
|
+
* a key sent as `null` is removed — so a screen sends only what it changed.
|
|
3092
|
+
*/
|
|
2538
3093
|
interface SavedViewSpecIn {
|
|
2539
|
-
name
|
|
3094
|
+
name?: string;
|
|
2540
3095
|
filters?: RecordFilter | null;
|
|
2541
3096
|
definition?: Record<string, unknown> | null;
|
|
2542
3097
|
view_id?: Uuid | null;
|
|
@@ -2567,38 +3122,199 @@ interface SubscriptionBlock {
|
|
|
2567
3122
|
}
|
|
2568
3123
|
|
|
2569
3124
|
/**
|
|
2570
|
-
*
|
|
2571
|
-
*
|
|
3125
|
+
* The data seam: a structural subset of `SupabaseClient`. The package never
|
|
3126
|
+
* opens a database connection of its own and never holds a key — the HOST
|
|
3127
|
+
* supplies a client that already carries the operating person's session, which
|
|
3128
|
+
* is what makes DOOR-5 and AGT-N-4 true (the store sees the person, not us).
|
|
2572
3129
|
*/
|
|
2573
|
-
interface
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
3130
|
+
interface RecordsDataSource {
|
|
3131
|
+
/**
|
|
3132
|
+
* Call a door. The name is always a door the live catalogue has; `/core`
|
|
3133
|
+
* refuses `door_absent` before it ever reaches here for one that does not.
|
|
3134
|
+
*/
|
|
3135
|
+
rpc(fn: string, args: Record<string, unknown>,
|
|
3136
|
+
/**
|
|
3137
|
+
* THE SCHEMA THE DOOR LIVES IN, always supplied: `custom` for the store's
|
|
3138
|
+
* own doors, `iam` for the trust doors (the external principal and the
|
|
3139
|
+
* publish binding, which are the PLATFORM's). A host binding supabase-js
|
|
3140
|
+
* routes this to `client.schema(options.schema).rpc(fn, args)`; a host that
|
|
3141
|
+
* ignores it calls its own default PostgREST profile — `public` — and is
|
|
3142
|
+
* refused by name, which is the failure we want rather than a silent answer
|
|
3143
|
+
* from the wrong system. (Before 2026-09-18 this was described as "only ever
|
|
3144
|
+
* `iam`" and the store's doors went unqualified; the extension's first real
|
|
3145
|
+
* turn proved that asks `public.store_is_open` and finds nothing.)
|
|
3146
|
+
*/
|
|
3147
|
+
options?: {
|
|
3148
|
+
schema?: string;
|
|
3149
|
+
}): PromiseLike<{
|
|
3150
|
+
data: unknown;
|
|
3151
|
+
error: PgError | null;
|
|
3152
|
+
}>;
|
|
3153
|
+
/** Reads of `custom.*` go through the schema-qualified builder, never a bare `from`. */
|
|
3154
|
+
schema(name: string): {
|
|
3155
|
+
from(table: string): RecordsTableQuery;
|
|
3156
|
+
};
|
|
2577
3157
|
}
|
|
2578
|
-
/** The
|
|
2579
|
-
interface
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
3158
|
+
/** The read surface the list and query paths use. A real supabase-js client satisfies it. */
|
|
3159
|
+
interface RecordsTableQuery {
|
|
3160
|
+
select(columns: string, options?: {
|
|
3161
|
+
count?: "exact" | "planned" | "estimated";
|
|
3162
|
+
head?: boolean;
|
|
3163
|
+
}): RecordsFilter;
|
|
3164
|
+
}
|
|
3165
|
+
interface RecordsFilter extends PromiseLike<RecordsResponse> {
|
|
3166
|
+
eq(column: string, value: unknown): RecordsFilter;
|
|
3167
|
+
neq(column: string, value: unknown): RecordsFilter;
|
|
3168
|
+
in(column: string, values: readonly unknown[]): RecordsFilter;
|
|
3169
|
+
is(column: string, value: null | boolean): RecordsFilter;
|
|
3170
|
+
gte(column: string, value: unknown): RecordsFilter;
|
|
3171
|
+
lte(column: string, value: unknown): RecordsFilter;
|
|
3172
|
+
order(column: string, options?: {
|
|
3173
|
+
ascending?: boolean;
|
|
3174
|
+
}): RecordsFilter;
|
|
3175
|
+
range(from: number, to: number): RecordsFilter;
|
|
3176
|
+
limit(count: number): RecordsFilter;
|
|
3177
|
+
}
|
|
3178
|
+
interface RecordsResponse {
|
|
3179
|
+
data: unknown;
|
|
3180
|
+
error: PgError | null;
|
|
3181
|
+
count?: number | null;
|
|
2594
3182
|
}
|
|
2595
3183
|
/**
|
|
2596
|
-
*
|
|
2597
|
-
*
|
|
2598
|
-
*
|
|
2599
|
-
*
|
|
3184
|
+
* WHO IS ACTING. AGT-N-4: an agent carries the exact authority of the person
|
|
3185
|
+
* operating it — there is no agent identity and there are no service roles. So
|
|
3186
|
+
* the actor word and the person are two separate facts, and `on_behalf_of` is
|
|
3187
|
+
* meaningful only when the actor is `agent`.
|
|
2600
3188
|
*/
|
|
2601
|
-
|
|
3189
|
+
interface RecordsActor {
|
|
3190
|
+
actor: Actor;
|
|
3191
|
+
/** The signed-in person. The store reads this from the session, not from us; this is for the client's own mirror. */
|
|
3192
|
+
user_id?: Uuid;
|
|
3193
|
+
/** Only an agent acts on behalf of a person (the store refuses it otherwise). */
|
|
3194
|
+
on_behalf_of?: Uuid;
|
|
3195
|
+
}
|
|
3196
|
+
/**
|
|
3197
|
+
* OPTIONAL. A live-updates seam. The default degradation is stated rather than
|
|
3198
|
+
* silent: with no port bound, `useRecords` reports `live: false` and the screen
|
|
3199
|
+
* can say "not live" instead of quietly going stale.
|
|
3200
|
+
*
|
|
3201
|
+
* A host binds this with `@ai-matrx/data/react`'s channel hygiene — the package
|
|
3202
|
+
* deliberately does NOT depend on it, so the headless core stays free of a
|
|
3203
|
+
* realtime client and a host that has one keeps using the one it already has.
|
|
3204
|
+
*/
|
|
3205
|
+
interface RecordsRealtimePort {
|
|
3206
|
+
/**
|
|
3207
|
+
* Watch one organization's records of one table. Returns an unsubscribe.
|
|
3208
|
+
*
|
|
3209
|
+
* THE HOST NUDGES THROUGH THIS SINK AND REACHES AROUND NOTHING. Until 0.43.0 the callback
|
|
3210
|
+
* was `(recordId: Uuid) => void` and a host that also wanted to say "the SHAPE moved"
|
|
3211
|
+
* imported `tableShapeChanged` from `@ai-matrx/records/react` and called it directly —
|
|
3212
|
+
* which worked, and which meant the port contract did not describe half of what a port
|
|
3213
|
+
* actually does. A column appearing is not a row changing, and the package owns the
|
|
3214
|
+
* difference.
|
|
3215
|
+
*
|
|
3216
|
+
* NOTHING THAT ARRIVES HERE IS DATA. A nudge has not passed the read door, so the hook
|
|
3217
|
+
* re-reads — by id set when the nudge names ids, whole-page when it cannot.
|
|
3218
|
+
*/
|
|
3219
|
+
subscribeRecords(args: {
|
|
3220
|
+
organization_id: Uuid;
|
|
3221
|
+
table_id: Uuid;
|
|
3222
|
+
}, sink: RecordsChangeSink): () => void;
|
|
3223
|
+
}
|
|
3224
|
+
/** What a realtime port may tell the package. Two calls, because a column is not a row. */
|
|
3225
|
+
interface RecordsChangeSink {
|
|
3226
|
+
/**
|
|
3227
|
+
* THESE RECORDS MOVED. `null` means "I cannot tell you which" — a reconnect, a tab wake, or
|
|
3228
|
+
* a change above the store's own id cap — and is the one case that costs a whole-page read.
|
|
3229
|
+
* An EMPTY array is not the same thing and is not a nudge at all.
|
|
3230
|
+
*/
|
|
3231
|
+
records(ids: readonly Uuid[] | null): void;
|
|
3232
|
+
/**
|
|
3233
|
+
* THIS TABLE'S SHAPE MOVED — a column added, retired or changed. Re-reading the rows would
|
|
3234
|
+
* redraw the same table without the new column in it, which is a screen that is out of date
|
|
3235
|
+
* while looking healthy.
|
|
3236
|
+
*/
|
|
3237
|
+
shape(): void;
|
|
3238
|
+
}
|
|
3239
|
+
/**
|
|
3240
|
+
* OPTIONAL. Where a refusal that nobody asked about goes — the loud funnel.
|
|
3241
|
+
* Default degradation: `console.error` with the store's own words, never
|
|
3242
|
+
* silence.
|
|
3243
|
+
*/
|
|
3244
|
+
type RecordsErrorSink = (error: {
|
|
3245
|
+
code: string;
|
|
3246
|
+
message: string;
|
|
3247
|
+
hint?: string;
|
|
3248
|
+
where: string;
|
|
3249
|
+
}) => void;
|
|
3250
|
+
/**
|
|
3251
|
+
* OPTIONAL. The merge-field resolver's server half (`W5-MERGE-B`). While it is
|
|
3252
|
+
* not bound, `useMergeField` answers `pending` WITH THE REASON — never a blank,
|
|
3253
|
+
* never a literal placeholder left in the text (DYN-14).
|
|
3254
|
+
*/
|
|
3255
|
+
interface RecordsResolverPort {
|
|
3256
|
+
resolve(args: {
|
|
3257
|
+
organization_id: Uuid;
|
|
3258
|
+
merge_field_keys: string[];
|
|
3259
|
+
/** The live selection the `state` source reads (DYNAMIC-VALUES §C). */
|
|
3260
|
+
state?: Record<string, unknown>;
|
|
3261
|
+
}): Promise<unknown>;
|
|
3262
|
+
}
|
|
3263
|
+
/** The one config a host binds. */
|
|
3264
|
+
interface RecordsConfig {
|
|
3265
|
+
/** REQUIRED. */
|
|
3266
|
+
dataSource: RecordsDataSource;
|
|
3267
|
+
/** REQUIRED. */
|
|
3268
|
+
actor: RecordsActor;
|
|
3269
|
+
/**
|
|
3270
|
+
* REQUIRED. REC-29: organizations are hard walls, and the store is keyed
|
|
3271
|
+
* `(organization_id, id)`. There is no "current organization" this package
|
|
3272
|
+
* discovers for itself — the host says which one, every time.
|
|
3273
|
+
*/
|
|
3274
|
+
organizationId: Uuid;
|
|
3275
|
+
realtime?: RecordsRealtimePort;
|
|
3276
|
+
onError?: RecordsErrorSink;
|
|
3277
|
+
resolver?: RecordsResolverPort;
|
|
3278
|
+
/**
|
|
3279
|
+
* The schema the record store lives in. Exists so a rehearsal branch and
|
|
3280
|
+
* production can differ without a fork; it is `custom` everywhere today.
|
|
3281
|
+
*/
|
|
3282
|
+
schema?: string;
|
|
3283
|
+
}
|
|
3284
|
+
|
|
3285
|
+
/**
|
|
3286
|
+
* REL-6. Whether Visibility flows along this relation and the MAXIMUM access
|
|
3287
|
+
* level it carries. Default off on `referenced`, on for `owned`.
|
|
3288
|
+
*/
|
|
3289
|
+
interface RelationCarries {
|
|
3290
|
+
carries: boolean;
|
|
3291
|
+
/** The ceiling — a relation never carries more access than this. */
|
|
3292
|
+
max_access: string | null;
|
|
3293
|
+
}
|
|
3294
|
+
/** The seven properties, each its own question. */
|
|
3295
|
+
interface RelationProperties {
|
|
3296
|
+
/** REL-1. Stored once on the contained table, read from the field's side. */
|
|
3297
|
+
flavor: RelationFlavor;
|
|
3298
|
+
/** REL-2. Separate from flavour. */
|
|
3299
|
+
on_delete: OnDelete;
|
|
3300
|
+
/** REL-3. A snapshot is a frozen copy in the relation's payload — never a pointer into History. */
|
|
3301
|
+
binding: RelationBinding;
|
|
3302
|
+
/** REL-4. */
|
|
3303
|
+
ordered: boolean;
|
|
3304
|
+
/** REL-5. */
|
|
3305
|
+
loops: "allowed" | "refused";
|
|
3306
|
+
/** REL-6. */
|
|
3307
|
+
carries: RelationCarries;
|
|
3308
|
+
/** REL-7. */
|
|
3309
|
+
cardinality: RelationCardinality;
|
|
3310
|
+
}
|
|
3311
|
+
/**
|
|
3312
|
+
* REL-8 / REL-N-1. A target is a REFERENCE, written that way from the first
|
|
3313
|
+
* line of code, because it may name a row outside our database. One Table,
|
|
3314
|
+
* several, or any — polymorphic without restriction. External targets are
|
|
3315
|
+
* read-only in v1.
|
|
3316
|
+
*/
|
|
3317
|
+
type RelationTarget = {
|
|
2602
3318
|
kind: "ours";
|
|
2603
3319
|
entity_token: string;
|
|
2604
3320
|
row_id: Uuid;
|
|
@@ -2673,6 +3389,53 @@ type RelationWordsManyArgs = {
|
|
|
2673
3389
|
display?: RelationDisplaySpec | null;
|
|
2674
3390
|
record_ids: Uuid[];
|
|
2675
3391
|
};
|
|
3392
|
+
/** One reference as the store keeps it. */
|
|
3393
|
+
interface EntityRef {
|
|
3394
|
+
/** The `platform.entity_types` token: `note`, `web_site`, `agent` … */
|
|
3395
|
+
token: string;
|
|
3396
|
+
id: Uuid;
|
|
3397
|
+
}
|
|
3398
|
+
/** One reference as a read door answers it. */
|
|
3399
|
+
interface EntityRefWithWords extends EntityRef {
|
|
3400
|
+
/**
|
|
3401
|
+
* The thing's own title — or the store's withheld sentence when the reader
|
|
3402
|
+
* may not open it; `null` when the kind names no title.
|
|
3403
|
+
*/
|
|
3404
|
+
label: string | null;
|
|
3405
|
+
}
|
|
3406
|
+
/** One kind of platform thing a record may point at (`custom.entity_reference_kinds`). */
|
|
3407
|
+
interface EntityReferenceKind {
|
|
3408
|
+
token: string;
|
|
3409
|
+
/** What a person reads: "Note", "Site", "Agent". */
|
|
3410
|
+
label: string;
|
|
3411
|
+
/** The picker's grouping: the admin-assigned reference category, else the schema. */
|
|
3412
|
+
category: string;
|
|
3413
|
+
}
|
|
3414
|
+
/**
|
|
3415
|
+
* The references a cell holds, whichever shape it arrived in — one object, a
|
|
3416
|
+
* list, or what a read door rendered (with labels). Anything that is not a
|
|
3417
|
+
* reference is left out, never guessed at.
|
|
3418
|
+
*/
|
|
3419
|
+
declare function entityRefsOf(value: unknown): EntityRefWithWords[];
|
|
3420
|
+
/**
|
|
3421
|
+
* What to WRITE for an entity-reference cell: `{token, id}` only, each thing
|
|
3422
|
+
* once, first mention first — the label a read door added is dropped, because
|
|
3423
|
+
* the store reads it and never keeps it (REL-14). A single-valued column gets
|
|
3424
|
+
* the one object (or `null`), a multi-valued one the list.
|
|
3425
|
+
*/
|
|
3426
|
+
declare function entityRefsToWrite(value: unknown, multi: boolean): EntityRef | EntityRef[] | null;
|
|
3427
|
+
/**
|
|
3428
|
+
* The kinds of platform thing a record may point at — what the field editor's
|
|
3429
|
+
* kind picker lists. `custom.entity_reference_kinds()`.
|
|
3430
|
+
*/
|
|
3431
|
+
declare function entityReferenceKinds(source: RecordsDataSource): Promise<RecordsResult<EntityReferenceKind[]>>;
|
|
3432
|
+
/**
|
|
3433
|
+
* THE WORDS HELPER. The words of each `{token, id}` for a picker or a chip
|
|
3434
|
+
* before anything is saved — each label read by the store for THIS person and
|
|
3435
|
+
* withheld when they may not open the thing. `custom.entity_reference_words`.
|
|
3436
|
+
* A saved cell needs no call: every read door already answers its labels.
|
|
3437
|
+
*/
|
|
3438
|
+
declare function entityReferenceWords(source: RecordsDataSource, organizationId: Uuid, refs: readonly EntityRef[]): Promise<RecordsResult<EntityRefWithWords[]>>;
|
|
2676
3439
|
|
|
2677
3440
|
/**
|
|
2678
3441
|
* DYN-14 / DYN-15. An ordered list of merge fields ENDING IN A LITERAL, or the
|
|
@@ -2980,6 +3743,34 @@ interface WorkApprovalDecision {
|
|
|
2980
3743
|
version: number | null;
|
|
2981
3744
|
message: string;
|
|
2982
3745
|
}
|
|
3746
|
+
/** One inbox decision of a batch (`custom.work_decide_many`). */
|
|
3747
|
+
interface WorkDecideManyItem {
|
|
3748
|
+
/** The inbox item — a `work_approval` record's id (`WorkInboxItem.item_id`). */
|
|
3749
|
+
item: Uuid;
|
|
3750
|
+
decision: "approve" | "decline";
|
|
3751
|
+
note?: string | null;
|
|
3752
|
+
}
|
|
3753
|
+
type WorkDecideVerdict = "approved" | "declined" | "already_decided" | "no_right" | "refused";
|
|
3754
|
+
interface WorkDecideManyResult {
|
|
3755
|
+
index: number;
|
|
3756
|
+
item: Uuid;
|
|
3757
|
+
decision: "approve" | "decline";
|
|
3758
|
+
verdict: WorkDecideVerdict;
|
|
3759
|
+
/** The store's own sentence: what was applied, or why it was not. */
|
|
3760
|
+
sentence: string;
|
|
3761
|
+
subject_id?: Uuid;
|
|
3762
|
+
version?: number | null;
|
|
3763
|
+
record_ids?: Uuid[];
|
|
3764
|
+
code?: string;
|
|
3765
|
+
}
|
|
3766
|
+
/** What `custom.work_decide_many` answers: the counts, then one verdict per item in order. */
|
|
3767
|
+
interface WorkDecideMany {
|
|
3768
|
+
asked: number;
|
|
3769
|
+
approved: number;
|
|
3770
|
+
declined: number;
|
|
3771
|
+
not_decided: number;
|
|
3772
|
+
results: WorkDecideManyResult[];
|
|
3773
|
+
}
|
|
2983
3774
|
/** What `custom.work_assign` answers: the value, the access, and who holds it now. */
|
|
2984
3775
|
interface WorkAssignment {
|
|
2985
3776
|
record_id: Uuid;
|
|
@@ -3228,167 +4019,6 @@ interface ResolvedPublishBinding {
|
|
|
3228
4019
|
notice: string;
|
|
3229
4020
|
}
|
|
3230
4021
|
|
|
3231
|
-
/**
|
|
3232
|
-
* The data seam: a structural subset of `SupabaseClient`. The package never
|
|
3233
|
-
* opens a database connection of its own and never holds a key — the HOST
|
|
3234
|
-
* supplies a client that already carries the operating person's session, which
|
|
3235
|
-
* is what makes DOOR-5 and AGT-N-4 true (the store sees the person, not us).
|
|
3236
|
-
*/
|
|
3237
|
-
interface RecordsDataSource {
|
|
3238
|
-
/**
|
|
3239
|
-
* Call a door. The name is always a door the live catalogue has; `/core`
|
|
3240
|
-
* refuses `door_absent` before it ever reaches here for one that does not.
|
|
3241
|
-
*/
|
|
3242
|
-
rpc(fn: string, args: Record<string, unknown>,
|
|
3243
|
-
/**
|
|
3244
|
-
* THE SCHEMA THE DOOR LIVES IN, always supplied: `custom` for the store's
|
|
3245
|
-
* own doors, `iam` for the trust doors (the external principal and the
|
|
3246
|
-
* publish binding, which are the PLATFORM's). A host binding supabase-js
|
|
3247
|
-
* routes this to `client.schema(options.schema).rpc(fn, args)`; a host that
|
|
3248
|
-
* ignores it calls its own default PostgREST profile — `public` — and is
|
|
3249
|
-
* refused by name, which is the failure we want rather than a silent answer
|
|
3250
|
-
* from the wrong system. (Before 2026-09-18 this was described as "only ever
|
|
3251
|
-
* `iam`" and the store's doors went unqualified; the extension's first real
|
|
3252
|
-
* turn proved that asks `public.store_is_open` and finds nothing.)
|
|
3253
|
-
*/
|
|
3254
|
-
options?: {
|
|
3255
|
-
schema?: string;
|
|
3256
|
-
}): PromiseLike<{
|
|
3257
|
-
data: unknown;
|
|
3258
|
-
error: PgError | null;
|
|
3259
|
-
}>;
|
|
3260
|
-
/** Reads of `custom.*` go through the schema-qualified builder, never a bare `from`. */
|
|
3261
|
-
schema(name: string): {
|
|
3262
|
-
from(table: string): RecordsTableQuery;
|
|
3263
|
-
};
|
|
3264
|
-
}
|
|
3265
|
-
/** The read surface the list and query paths use. A real supabase-js client satisfies it. */
|
|
3266
|
-
interface RecordsTableQuery {
|
|
3267
|
-
select(columns: string, options?: {
|
|
3268
|
-
count?: "exact" | "planned" | "estimated";
|
|
3269
|
-
head?: boolean;
|
|
3270
|
-
}): RecordsFilter;
|
|
3271
|
-
}
|
|
3272
|
-
interface RecordsFilter extends PromiseLike<RecordsResponse> {
|
|
3273
|
-
eq(column: string, value: unknown): RecordsFilter;
|
|
3274
|
-
neq(column: string, value: unknown): RecordsFilter;
|
|
3275
|
-
in(column: string, values: readonly unknown[]): RecordsFilter;
|
|
3276
|
-
is(column: string, value: null | boolean): RecordsFilter;
|
|
3277
|
-
gte(column: string, value: unknown): RecordsFilter;
|
|
3278
|
-
lte(column: string, value: unknown): RecordsFilter;
|
|
3279
|
-
order(column: string, options?: {
|
|
3280
|
-
ascending?: boolean;
|
|
3281
|
-
}): RecordsFilter;
|
|
3282
|
-
range(from: number, to: number): RecordsFilter;
|
|
3283
|
-
limit(count: number): RecordsFilter;
|
|
3284
|
-
}
|
|
3285
|
-
interface RecordsResponse {
|
|
3286
|
-
data: unknown;
|
|
3287
|
-
error: PgError | null;
|
|
3288
|
-
count?: number | null;
|
|
3289
|
-
}
|
|
3290
|
-
/**
|
|
3291
|
-
* WHO IS ACTING. AGT-N-4: an agent carries the exact authority of the person
|
|
3292
|
-
* operating it — there is no agent identity and there are no service roles. So
|
|
3293
|
-
* the actor word and the person are two separate facts, and `on_behalf_of` is
|
|
3294
|
-
* meaningful only when the actor is `agent`.
|
|
3295
|
-
*/
|
|
3296
|
-
interface RecordsActor {
|
|
3297
|
-
actor: Actor;
|
|
3298
|
-
/** The signed-in person. The store reads this from the session, not from us; this is for the client's own mirror. */
|
|
3299
|
-
user_id?: Uuid;
|
|
3300
|
-
/** Only an agent acts on behalf of a person (the store refuses it otherwise). */
|
|
3301
|
-
on_behalf_of?: Uuid;
|
|
3302
|
-
}
|
|
3303
|
-
/**
|
|
3304
|
-
* OPTIONAL. A live-updates seam. The default degradation is stated rather than
|
|
3305
|
-
* silent: with no port bound, `useRecords` reports `live: false` and the screen
|
|
3306
|
-
* can say "not live" instead of quietly going stale.
|
|
3307
|
-
*
|
|
3308
|
-
* A host binds this with `@ai-matrx/data/react`'s channel hygiene — the package
|
|
3309
|
-
* deliberately does NOT depend on it, so the headless core stays free of a
|
|
3310
|
-
* realtime client and a host that has one keeps using the one it already has.
|
|
3311
|
-
*/
|
|
3312
|
-
interface RecordsRealtimePort {
|
|
3313
|
-
/**
|
|
3314
|
-
* Watch one organization's records of one table. Returns an unsubscribe.
|
|
3315
|
-
*
|
|
3316
|
-
* THE HOST NUDGES THROUGH THIS SINK AND REACHES AROUND NOTHING. Until 0.43.0 the callback
|
|
3317
|
-
* was `(recordId: Uuid) => void` and a host that also wanted to say "the SHAPE moved"
|
|
3318
|
-
* imported `tableShapeChanged` from `@ai-matrx/records/react` and called it directly —
|
|
3319
|
-
* which worked, and which meant the port contract did not describe half of what a port
|
|
3320
|
-
* actually does. A column appearing is not a row changing, and the package owns the
|
|
3321
|
-
* difference.
|
|
3322
|
-
*
|
|
3323
|
-
* NOTHING THAT ARRIVES HERE IS DATA. A nudge has not passed the read door, so the hook
|
|
3324
|
-
* re-reads — by id set when the nudge names ids, whole-page when it cannot.
|
|
3325
|
-
*/
|
|
3326
|
-
subscribeRecords(args: {
|
|
3327
|
-
organization_id: Uuid;
|
|
3328
|
-
table_id: Uuid;
|
|
3329
|
-
}, sink: RecordsChangeSink): () => void;
|
|
3330
|
-
}
|
|
3331
|
-
/** What a realtime port may tell the package. Two calls, because a column is not a row. */
|
|
3332
|
-
interface RecordsChangeSink {
|
|
3333
|
-
/**
|
|
3334
|
-
* THESE RECORDS MOVED. `null` means "I cannot tell you which" — a reconnect, a tab wake, or
|
|
3335
|
-
* a change above the store's own id cap — and is the one case that costs a whole-page read.
|
|
3336
|
-
* An EMPTY array is not the same thing and is not a nudge at all.
|
|
3337
|
-
*/
|
|
3338
|
-
records(ids: readonly Uuid[] | null): void;
|
|
3339
|
-
/**
|
|
3340
|
-
* THIS TABLE'S SHAPE MOVED — a column added, retired or changed. Re-reading the rows would
|
|
3341
|
-
* redraw the same table without the new column in it, which is a screen that is out of date
|
|
3342
|
-
* while looking healthy.
|
|
3343
|
-
*/
|
|
3344
|
-
shape(): void;
|
|
3345
|
-
}
|
|
3346
|
-
/**
|
|
3347
|
-
* OPTIONAL. Where a refusal that nobody asked about goes — the loud funnel.
|
|
3348
|
-
* Default degradation: `console.error` with the store's own words, never
|
|
3349
|
-
* silence.
|
|
3350
|
-
*/
|
|
3351
|
-
type RecordsErrorSink = (error: {
|
|
3352
|
-
code: string;
|
|
3353
|
-
message: string;
|
|
3354
|
-
hint?: string;
|
|
3355
|
-
where: string;
|
|
3356
|
-
}) => void;
|
|
3357
|
-
/**
|
|
3358
|
-
* OPTIONAL. The merge-field resolver's server half (`W5-MERGE-B`). While it is
|
|
3359
|
-
* not bound, `useMergeField` answers `pending` WITH THE REASON — never a blank,
|
|
3360
|
-
* never a literal placeholder left in the text (DYN-14).
|
|
3361
|
-
*/
|
|
3362
|
-
interface RecordsResolverPort {
|
|
3363
|
-
resolve(args: {
|
|
3364
|
-
organization_id: Uuid;
|
|
3365
|
-
merge_field_keys: string[];
|
|
3366
|
-
/** The live selection the `state` source reads (DYNAMIC-VALUES §C). */
|
|
3367
|
-
state?: Record<string, unknown>;
|
|
3368
|
-
}): Promise<unknown>;
|
|
3369
|
-
}
|
|
3370
|
-
/** The one config a host binds. */
|
|
3371
|
-
interface RecordsConfig {
|
|
3372
|
-
/** REQUIRED. */
|
|
3373
|
-
dataSource: RecordsDataSource;
|
|
3374
|
-
/** REQUIRED. */
|
|
3375
|
-
actor: RecordsActor;
|
|
3376
|
-
/**
|
|
3377
|
-
* REQUIRED. REC-29: organizations are hard walls, and the store is keyed
|
|
3378
|
-
* `(organization_id, id)`. There is no "current organization" this package
|
|
3379
|
-
* discovers for itself — the host says which one, every time.
|
|
3380
|
-
*/
|
|
3381
|
-
organizationId: Uuid;
|
|
3382
|
-
realtime?: RecordsRealtimePort;
|
|
3383
|
-
onError?: RecordsErrorSink;
|
|
3384
|
-
resolver?: RecordsResolverPort;
|
|
3385
|
-
/**
|
|
3386
|
-
* The schema the record store lives in. Exists so a rehearsal branch and
|
|
3387
|
-
* production can differ without a fork; it is `custom` everywhere today.
|
|
3388
|
-
*/
|
|
3389
|
-
schema?: string;
|
|
3390
|
-
}
|
|
3391
|
-
|
|
3392
4022
|
/**
|
|
3393
4023
|
* THE CLIENT OPERATION LEDGER — how a browser recognises the echo of its own write.
|
|
3394
4024
|
*
|
|
@@ -3542,4 +4172,4 @@ interface ConversationScopeContext {
|
|
|
3542
4172
|
/** `About: Acme Industrial` — the chip a bound chat wears. */
|
|
3543
4173
|
declare function scopeChip(scope: ConversationScope): string;
|
|
3544
4174
|
|
|
3545
|
-
export { ARCHIVE_LANES, ARCHIVE_LANE_LABEL, ARCHIVE_LANE_MEANS, type ActionRefusal, type ActionRunResult, Actor, type AggregateBucket, type AggregateFilter, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AggregateWindow, type AnonTokenBinding, type ArchiveLane, type ArchivedDoorRow, type ArchivedRow, type BookingAvailability, type BookingDeclared, type BookingSummary, type BookingWindow, type CaptureField, type CaptureFileRef, type CaptureOutcome, type CaptureQuestion, type CaptureQueue, type CaptureQueueCounts, type CaptureQueueOptions, type CaptureQueuePorts, type CaptureQueueStore, type CaptureSheetFace, type CaptureSheetSummary, type CaptureSyncReport, type ChecklistDeclared, type ChecklistRequirement, type ChecklistRequirementKind, type ChecklistRoleSpec, type ChecklistRunStarted, type ChecklistRunStep, type ChecklistRunSummary, type ChecklistSpec, type ChecklistStepCompleted, type ChecklistStepSpec, type ChecklistTemplateShape, type ChecklistTemplateSummary, type ChecklistTrigger, type ChecklistTriggerKind, type ChoiceOption, type ChoiceOptions, type CoerceOptions, type Coerced, type CoercedAnswers, type CoercibleField, type CommentThreadRead, type CommentWritten, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DEFAULT_ARCHIVE_LANE, DEFAULT_PORTAL_ARCHIVE_FILTER, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type DecorationColor, type DecorationPath, type DecorationRule, type DecorationRuleOp, type DecorationTarget, Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, type EnrichAlternate, type EnrichCell, type EnrichDeclared, type EnrichDueRow, type EnrichRun, type EnrichSource, type Enrichment, type EnrichmentSummary, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityTableFacts, type ExampleBuilt, type ExampleSpec, type ExternalPrincipalCard, FIELD_KINDS, Field, type FieldHistoryEntry, type FieldKind, type FormSummary, type FormulaParse, Freshness, type GridLayout, type GridLayoutMode, type GridRowHeight, type HistoryActor, type HistoryActorKind, type HistoryChange, type Home, type ImportBatchResult, type ImportColumnPlan, type ImportColumnsDeclared, type ImportFinished, type ImportOpened, type ImportOutcome, type ImportPlan, type ImportPolicy, type ImportProposal, type ImportReport, type ImportRun, type InboundAddress, type InboundDeclared, type IoExportPage, type KernelTargets, type MergeField, MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, MergeFieldSemanticType, MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, OnDelete, OverridePolicy, PERMISSION_LEVELS, PIPELINE_RULE_KINDS, PORTAL_ARCHIVE_FILTERS, ParityFieldType, type PermissionLevel, PgError, type Pipeline, type PipelineColumn, type PipelineDeclared, type PipelineGate, type PipelineGatePreview, type PipelineMissingField, type PipelineMoveResult, type PipelineRule, type PipelineRuleKind, type PipelineSpec, type PipelineStage, type PipelineVerdict, type PortalArchiveAnswer, type PortalArchiveFilter, type PortalCard, type PortalInvitation, type PortalPreviewRow, type PortalPrincipal, type PortalRevocation, type PortalSummary, type PortalTableExposure, type PortalTableRef, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, ReadRow, type RecordChangeAction, type RecordComment, RecordDocument, type RecordEvent, type RecordFilter, type RecordHistoryEntry, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, RecordsError, type RecordsErrorSink, type RecordsFilter, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsTableQuery, type RegisteredTable, type Relation, RelationBinding, RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplaySpec, RelationFlavor, type RelationProperties, type RelationStore, type RelationTarget, type RelationWordsManyArgs, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RowAction, type RowActionStep, type Rule, type RuleAnswer, type RuleExpression, RuleNodeKind, RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, StorageMode, StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, type Table, type TableArchiveProgress, type TableCapacity, type TableDecorations, TableDisplay, TableOrigin, TableType, type TableWebhook, type TableWebhookDeclared, Timestamp, Uuid, type ViewLayout, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, actionRefusals, archivedByLine, archivedWhen, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, emptyArchiveLine, emptyPortalArchiveLine, exampleSpec, exportPageXlsx, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isArchiveLane, isDecided, isOwnOp, isPortalArchiveFilter, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, openCaptureQueue, optionKey, optionLabel, portalArchiveConsequence, portalConfirmLine, portalPath, portalTitleTypedBack, publicFormPath, recordChangeTrigger, rememberedOpCount, sameDocument, scopeChip, stableFilterKey };
|
|
4175
|
+
export { ARCHIVE_LANES, ARCHIVE_LANE_LABEL, ARCHIVE_LANE_MEANS, type ActionRefusal, type ActionRunResult, Actor, type AggregateBucket, type AggregateCompare, type AggregateCompareKind, type AggregateCompareWindows, type AggregateDelta, type AggregateFilter, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AggregateWindow, type AnonTokenBinding, type ArchiveLane, type ArchivedDoorRow, type ArchivedRow, type BookingAvailability, type BookingDeclared, type BookingSummary, type BookingWindow, type CaptureField, type CaptureFileRef, type CaptureOutcome, type CaptureQuestion, type CaptureQueue, type CaptureQueueCounts, type CaptureQueueOptions, type CaptureQueuePorts, type CaptureQueueStore, type CaptureSheetFace, type CaptureSheetSummary, type CaptureSyncReport, type ChecklistDeclared, type ChecklistRequirement, type ChecklistRequirementKind, type ChecklistRoleSpec, type ChecklistRunStarted, type ChecklistRunStep, type ChecklistRunSummary, type ChecklistSpec, type ChecklistStepCompleted, type ChecklistStepSpec, type ChecklistTemplateShape, type ChecklistTemplateSummary, type ChecklistTrigger, type ChecklistTriggerKind, type ChoiceOption, type ChoiceOptions, type CoerceOptions, type Coerced, type CoercedAnswers, type CoercibleField, type CommentThreadRead, type CommentWritten, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DEFAULT_ARCHIVE_LANE, DEFAULT_PORTAL_ARCHIVE_FILTER, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type DashboardTarget, type DashboardTargetBase, type DashboardTargetOp, type DashboardTargetResult, type DashboardTotals, type DecorationColor, type DecorationPath, type DecorationRule, type DecorationRuleOp, type DecorationTarget, Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, type EnrichAlternate, type EnrichCell, type EnrichDeclared, type EnrichDueRow, type EnrichRun, type EnrichSource, type Enrichment, type EnrichmentSummary, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityRef, type EntityRefWithWords, type EntityReferenceKind, type EntityTableFacts, type ExampleBuilt, type ExampleSpec, type ExternalPrincipalCard, FIELD_KINDS, Field, type FieldHistoryEntry, type FieldKind, type FormSummary, type FormulaParse, Freshness, type GridLayout, type GridLayoutMode, type GridRowHeight, type HistoryActor, type HistoryActorKind, type HistoryChange, type Home, type ImportBatchResult, type ImportColumnPlan, type ImportColumnsDeclared, type ImportFinished, type ImportOpened, type ImportOutcome, type ImportPlan, type ImportPolicy, type ImportProposal, type ImportReport, type ImportRun, type InboundAddress, type InboundDeclared, type IoExportPage, type KernelTargets, type MergeField, MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, MergeFieldSemanticType, MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, OnDelete, type OutsideShareAnswer, OverridePolicy, PERMISSION_LEVELS, PIPELINE_RULE_KINDS, PORTAL_ACCENTS, PORTAL_ARCHIVE_FILTERS, ParityFieldType, type PermissionLevel, PgError, type Pipeline, type PipelineColumn, type PipelineDeclared, type PipelineGate, type PipelineGatePreview, type PipelineMissingField, type PipelineMoveMany, type PipelineMoveManyItem, type PipelineMoveManyResult, type PipelineMoveResult, type PipelineMoveVerdict, type PipelineRule, type PipelineRuleKind, type PipelineSpec, type PipelineStage, type PipelineVerdict, type PortalAccent, type PortalArchiveAnswer, type PortalArchiveFilter, type PortalCard, type PortalConfig, type PortalConfigInput, type PortalFooterLink, type PortalFormAnswer, type PortalFormInput, type PortalFormRef, type PortalFormSpec, type PortalInvitation, type PortalPreviewRow, type PortalPrincipal, type PortalRevocation, type PortalStage, type PortalStyle, type PortalStyleInput, type PortalSummary, type PortalTableExposure, type PortalTableRef, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, ReadRow, type RecordChangeAction, type RecordComment, RecordDocument, type RecordEvent, type RecordFilter, type RecordHeader, type RecordHistoryEntry, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, RecordsError, type RecordsErrorSink, type RecordsFilter, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, RelationBinding, RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplaySpec, RelationFlavor, type RelationProperties, type RelationStore, type RelationTarget, type RelationWordsManyArgs, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RowAction, type RowActionStep, type Rule, type RuleAnswer, type RuleExpression, RuleNodeKind, RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, StorageMode, type StoreFilter, StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, type Table, type TableArchiveProgress, type TableCapacity, type TableDecorations, TableDisplay, type TableListEntry, TableOrigin, type TablePlacement, type TablePlacementFact, type TableRowCount, type TableSyncResult, type TableSyncSource, type TableSyncSpec, TableType, type TableWebhook, type TableWebhookDeclared, Timestamp, Uuid, type ViewLayout, type ViewOrderSet, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDecideMany, type WorkDecideManyItem, type WorkDecideManyResult, type WorkDecideVerdict, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, actionRefusals, archivedByLine, archivedWhen, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, emptyArchiveLine, emptyPortalArchiveLine, entityReferenceKinds, entityReferenceKindsOf, entityReferenceWords, entityRefsOf, entityRefsToWrite, exampleSpec, exportPageXlsx, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isArchiveLane, isDecided, isEntityReferenceConfig, isOwnOp, isPortalAccent, isPortalArchiveFilter, isRuleFilter, isTheChosen, keptGroups, keptOutOfSight, keptTableHref, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, moveInOrder, offeredAsContext, openCaptureQueue, optionKey, optionLabel, portalArchiveConsequence, portalConfirmLine, portalPath, portalTitleTypedBack, publicFormPath, recordChangeTrigger, rememberedOpCount, sameDocument, scopeChip, sheetSyncSpec, stableFilterKey, withRowCounts, withTablePlacement };
|