@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/react/index.d.cts
CHANGED
|
@@ -3147,6 +3147,11 @@ declare const STORE_DOORS: readonly [{
|
|
|
3147
3147
|
readonly args: "";
|
|
3148
3148
|
readonly returns: "TABLE(function_name text, identity_args text, why text)";
|
|
3149
3149
|
readonly security: "invoker";
|
|
3150
|
+
}, {
|
|
3151
|
+
readonly name: "tables_i_can_open";
|
|
3152
|
+
readonly args: "";
|
|
3153
|
+
readonly returns: "TABLE(table_id uuid, table_name text, organization_id uuid, organization_name text, member boolean, visibility text, updated_at timestamp with time zone)";
|
|
3154
|
+
readonly security: "definer";
|
|
3150
3155
|
}, {
|
|
3151
3156
|
readonly name: "tables_shared_with_me";
|
|
3152
3157
|
readonly args: "";
|
|
@@ -3267,6 +3272,11 @@ declare const STORE_DOORS: readonly [{
|
|
|
3267
3272
|
readonly args: "p_user uuid, p_organization_id uuid, p_table_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level, OUT o_all_visible boolean, OUT o_true_visibility platform.visibility[], OUT o_granted_all uuid[], OUT o_granted_visible uuid[], OUT o_carried_visible uuid[], OUT o_ladder_calls integer, OUT o_fallback boolean, OUT o_note text";
|
|
3268
3273
|
readonly returns: "record";
|
|
3269
3274
|
readonly security: "definer";
|
|
3275
|
+
}, {
|
|
3276
|
+
readonly name: "where_id_opens";
|
|
3277
|
+
readonly args: "p_id uuid";
|
|
3278
|
+
readonly returns: "jsonb";
|
|
3279
|
+
readonly security: "definer";
|
|
3270
3280
|
}, {
|
|
3271
3281
|
readonly name: "widget_kernel_id";
|
|
3272
3282
|
readonly args: "";
|
|
@@ -3710,7 +3720,7 @@ declare const STORE_REFUSAL_CODES: readonly [{
|
|
|
3710
3720
|
readonly raised_by: "has_visibility_at";
|
|
3711
3721
|
}, {
|
|
3712
3722
|
readonly code: "42501";
|
|
3713
|
-
readonly raised_by: "_doc_render_immutable,_doc_signature_immutable,_field_definition_write,_field_write_door,_rule_definition_write,_store_door,agent_table_claim,anon_capture,anon_inbound_land,anon_publish,anon_token_issue,anon_token_verify,anon_write,assert_client_may_change,assert_client_may_open,assert_client_may_reach,assert_may_know_table,assert_organization_admin,assert_store_door,booking_confirm,booking_declare,booking_hold,capture_submit,checklist_run,comment_write,conversation_scope_bind,conversation_scope_unbind,doc_sign,enrich_declare,enrich_due,enrich_land,enrich_normalize,entity_field_declare,entity_field_retire,entity_field_update,entity_value_write,external_write_through,form_declare,form_submit,inbound_mail_land,io_comment_resolve,io_comment_write,io_import_begin,io_import_finish,io_restore,migrate_purge,migrate_purge_hard,migrate_purge_hard_request,migrate_reclass,my_levels,organization_clear,portal_declare,portal_invitation,portal_invite,portal_invite_accept,portal_principal_bind,promote_table,query_visibility_parity,read_record,read_records,read_records_archived,read_records_by_ids,read_records_matching,record_table,record_write_graph,relation_halves_disagreements,relation_halves_repair,share_grant,subscription_mute,subscription_preview,table_share_outside_accept,table_share_outside_invite,table_share_outside_resend,table_webhook_declare,visibility_as_of,work_approval_decide,work_approval_read,work_approval_request,work_person";
|
|
3723
|
+
readonly raised_by: "_doc_render_immutable,_doc_signature_immutable,_field_definition_write,_field_write_door,_rule_definition_write,_store_door,agent_table_claim,anon_capture,anon_inbound_land,anon_publish,anon_token_issue,anon_token_verify,anon_write,assert_client_may_change,assert_client_may_open,assert_client_may_reach,assert_may_know_table,assert_organization_admin,assert_store_door,booking_confirm,booking_declare,booking_hold,capture_submit,checklist_run,comment_write,conversation_scope_bind,conversation_scope_unbind,doc_sign,enrich_declare,enrich_due,enrich_land,enrich_normalize,entity_field_declare,entity_field_retire,entity_field_update,entity_value_write,external_write_through,form_declare,form_submit,inbound_mail_land,io_comment_resolve,io_comment_write,io_import_begin,io_import_finish,io_restore,migrate_purge,migrate_purge_hard,migrate_purge_hard_request,migrate_reclass,my_levels,organization_clear,organization_contents,portal_declare,portal_invitation,portal_invite,portal_invite_accept,portal_principal_bind,promote_table,query_visibility_parity,read_record,read_records,read_records_archived,read_records_by_ids,read_records_matching,record_table,record_write_graph,relation_halves_disagreements,relation_halves_repair,share_grant,subscription_mute,subscription_preview,table_share_outside_accept,table_share_outside_invite,table_share_outside_resend,table_webhook_declare,visibility_as_of,work_approval_decide,work_approval_read,work_approval_request,work_person";
|
|
3714
3724
|
}, {
|
|
3715
3725
|
readonly code: "42703";
|
|
3716
3726
|
readonly raised_by: "entity_table,portal_declare";
|
|
@@ -4666,6 +4676,17 @@ interface NewFieldDeclaration {
|
|
|
4666
4676
|
of?: string;
|
|
4667
4677
|
/** A formula: the expression, in the same shape a Rule uses (REC-15). */
|
|
4668
4678
|
expr?: Record<string, unknown>;
|
|
4679
|
+
/**
|
|
4680
|
+
* A formula IN THE LANGUAGE A PERSON TYPES — `{Visit fee} - {Deposit taken}` (GRID-PRIMITIVES
|
|
4681
|
+
* G3). The store parses it (`custom.formula_parse`), keeps the text in `config.formula_text`
|
|
4682
|
+
* and the expression it parses to in `config.expr`; send this OR `expr`, never both.
|
|
4683
|
+
*/
|
|
4684
|
+
formula_text?: string;
|
|
4685
|
+
/**
|
|
4686
|
+
* LANE SC-R — an `entity_reference` column's kinds: the platform entity tokens it may point at
|
|
4687
|
+
* (`note`, `site`, `agent` …), kept by the store in `config.allowed_types`.
|
|
4688
|
+
*/
|
|
4689
|
+
allowed_types?: string[];
|
|
4669
4690
|
compute_on?: ComputeOn;
|
|
4670
4691
|
relation_max?: number;
|
|
4671
4692
|
/**
|
|
@@ -4708,7 +4729,7 @@ interface NewFieldDeclaration {
|
|
|
4708
4729
|
* `checkbox` landed, which is how the store's own refusals came to name a list
|
|
4709
4730
|
* that no longer matched it.
|
|
4710
4731
|
*/
|
|
4711
|
-
type FieldTypeWord = DeclarableFieldKind | FieldBehavior | "number" | "integer" | "decimal" | "float" | "long_text" | "string";
|
|
4732
|
+
type FieldTypeWord = DeclarableFieldKind | FieldBehavior | "number" | "integer" | "decimal" | "float" | "long_text" | "string" | "autonumber" | "created_time" | "modified_time" | "entity_reference";
|
|
4712
4733
|
/**
|
|
4713
4734
|
* What `custom.field_update` accepts.
|
|
4714
4735
|
*
|
|
@@ -4810,6 +4831,13 @@ interface FieldPatch {
|
|
|
4810
4831
|
* Field document under the guards rather than through them.
|
|
4811
4832
|
*/
|
|
4812
4833
|
expr?: Record<string, unknown>;
|
|
4834
|
+
/**
|
|
4835
|
+
* RE-AIMING A FORMULA IN THE LANGUAGE A PERSON TYPES (GRID-PRIMITIVES G3). Same arm as
|
|
4836
|
+
* `expr` — send it with `type: "formula"`; the store parses it and keeps both the text and
|
|
4837
|
+
* the expression. Measured on the dev clone 2026-09-23: `{"type":"formula","formula_text":
|
|
4838
|
+
* "{Visit fee} * 2"}` re-aims the column and keeps its other settings.
|
|
4839
|
+
*/
|
|
4840
|
+
formula_text?: string;
|
|
4813
4841
|
}
|
|
4814
4842
|
/**
|
|
4815
4843
|
* Whether a choice column takes values that are not one of its choices
|
|
@@ -4900,7 +4928,7 @@ interface CoercibleField {
|
|
|
4900
4928
|
* `plain_text`, `long_text`, `number` and `boolean` are behaviours that carry
|
|
4901
4929
|
* no parity type of their own; every other word here is a parity type.
|
|
4902
4930
|
*/
|
|
4903
|
-
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"];
|
|
4931
|
+
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"];
|
|
4904
4932
|
/**
|
|
4905
4933
|
* 🚨 THE UNION IS DERIVED FROM THE LIST ABOVE, and the list is what the
|
|
4906
4934
|
* coverage test walks. Add a kind here and the test drives it; give it no arm
|
|
@@ -4954,6 +4982,13 @@ interface CoerceOptions {
|
|
|
4954
4982
|
*/
|
|
4955
4983
|
label?: string | undefined;
|
|
4956
4984
|
}
|
|
4985
|
+
/**
|
|
4986
|
+
* SC-R / P12. Whether a relation's config makes it an ENTITY REFERENCE: target
|
|
4987
|
+
* mode `any` (REL-8) restricted by a non-empty `allowed_types`.
|
|
4988
|
+
*/
|
|
4989
|
+
declare function isEntityReferenceConfig(config: Record<string, unknown> | null | undefined): boolean;
|
|
4990
|
+
/** The platform kinds an entity-reference Field may name, lower-cased, in its own order. */
|
|
4991
|
+
declare function entityReferenceKindsOf(field: Pick<CoercibleField, "config">): string[];
|
|
4957
4992
|
/** The Field's name in plain words — never its key on a screen. */
|
|
4958
4993
|
declare function coercionLabel(field: CoercibleField): string;
|
|
4959
4994
|
/**
|
|
@@ -5367,6 +5402,48 @@ interface PipelineMoveResult {
|
|
|
5367
5402
|
}[];
|
|
5368
5403
|
what_happens?: string;
|
|
5369
5404
|
}
|
|
5405
|
+
/** One card of a batch move (`custom.pipeline_move_many`). The version is REQUIRED: it is the
|
|
5406
|
+
* version the board loaded, and a card that changed since answers `changed_since_loaded`. */
|
|
5407
|
+
interface PipelineMoveManyItem {
|
|
5408
|
+
record_id: Uuid;
|
|
5409
|
+
stage: string;
|
|
5410
|
+
expected_version: number;
|
|
5411
|
+
/** Columns the stage asks for, filled in on the way in. */
|
|
5412
|
+
also?: Record<string, unknown>;
|
|
5413
|
+
}
|
|
5414
|
+
/** What one card of a batch move came to. The sentence is always the store's own. */
|
|
5415
|
+
type PipelineMoveVerdict = "moved" | "needs_approval" | "needs_fields" | "changed_since_loaded" | "no_right" | "refused";
|
|
5416
|
+
interface PipelineMoveManyResult {
|
|
5417
|
+
index: number;
|
|
5418
|
+
record_id: Uuid;
|
|
5419
|
+
stage: string;
|
|
5420
|
+
verdict: PipelineMoveVerdict;
|
|
5421
|
+
sentence: string;
|
|
5422
|
+
/** Set on `needs_fields`: the empty columns the stage asks for. */
|
|
5423
|
+
needs?: PipelineMissingField[];
|
|
5424
|
+
/** Set on `moved` / `needs_approval`: the card's version now. */
|
|
5425
|
+
version?: number;
|
|
5426
|
+
/** Set on `changed_since_loaded`: the version that won. */
|
|
5427
|
+
current_version?: number;
|
|
5428
|
+
expected_version?: number;
|
|
5429
|
+
approval_id?: Uuid;
|
|
5430
|
+
approvers?: {
|
|
5431
|
+
user_id: Uuid;
|
|
5432
|
+
name: string | null;
|
|
5433
|
+
why: string;
|
|
5434
|
+
}[];
|
|
5435
|
+
warnings?: StageRuleWarning[];
|
|
5436
|
+
rule?: string;
|
|
5437
|
+
code?: string;
|
|
5438
|
+
}
|
|
5439
|
+
/** What `custom.pipeline_move_many` answers: the counts, then one verdict per card in order. */
|
|
5440
|
+
interface PipelineMoveMany {
|
|
5441
|
+
asked: number;
|
|
5442
|
+
moved: number;
|
|
5443
|
+
needs_approval: number;
|
|
5444
|
+
not_moved: number;
|
|
5445
|
+
results: PipelineMoveManyResult[];
|
|
5446
|
+
}
|
|
5370
5447
|
/**
|
|
5371
5448
|
* ONE GATE ON A STAGE, as the condition builder on the stage settings screen writes it.
|
|
5372
5449
|
* `requires`, `who` and `limits` are sugar over this shape; this is the general form, and
|
|
@@ -5914,6 +5991,124 @@ interface PortalCard {
|
|
|
5914
5991
|
* decides whether they can sign in at all.
|
|
5915
5992
|
*/
|
|
5916
5993
|
external_lane_open: boolean;
|
|
5994
|
+
/** S6 — the look and forms exactly as the owner stored them (`{}` when none). */
|
|
5995
|
+
config: PortalConfig;
|
|
5996
|
+
/** S6 — the look as a client sees it: the portal's own values over the organization's brand. */
|
|
5997
|
+
style: PortalStyle;
|
|
5998
|
+
/** S6 — every form on the portal, in its order, with its title, Table and state. */
|
|
5999
|
+
forms: PortalFormRef[];
|
|
6000
|
+
/** S6 — the accent names a portal may carry (the design system's `STYLE_COLORS`). */
|
|
6001
|
+
accents: PortalAccent[];
|
|
6002
|
+
/**
|
|
6003
|
+
* S6 — the pictures that could be this portal's logo: the organization's own PUBLIC pictures in
|
|
6004
|
+
* Files, newest first. A private file is never offered, because the store would refuse it.
|
|
6005
|
+
*/
|
|
6006
|
+
logo_candidates: Array<{
|
|
6007
|
+
file_id: Uuid;
|
|
6008
|
+
name: string;
|
|
6009
|
+
url: string | null;
|
|
6010
|
+
}>;
|
|
6011
|
+
}
|
|
6012
|
+
/** The design system's colour names (`STYLE_COLORS`), which is all an accent may be. */
|
|
6013
|
+
declare const PORTAL_ACCENTS: readonly ["slate", "green", "amber", "red", "blue", "violet", "teal"];
|
|
6014
|
+
type PortalAccent = (typeof PORTAL_ACCENTS)[number];
|
|
6015
|
+
declare function isPortalAccent(word: unknown): word is PortalAccent;
|
|
6016
|
+
/** One link in a portal's footer. The store takes only `https://`, `mailto:` and `tel:`. */
|
|
6017
|
+
interface PortalFooterLink {
|
|
6018
|
+
label: string;
|
|
6019
|
+
url: string;
|
|
6020
|
+
}
|
|
6021
|
+
/** A portal's look as the owner sets it. Every key is optional; absent means "the organization's". */
|
|
6022
|
+
interface PortalStyleInput {
|
|
6023
|
+
display_name?: string | null;
|
|
6024
|
+
welcome?: string | null;
|
|
6025
|
+
logo_file_id?: Uuid | null;
|
|
6026
|
+
accent?: PortalAccent | null;
|
|
6027
|
+
footer_links?: PortalFooterLink[] | null;
|
|
6028
|
+
}
|
|
6029
|
+
/** One form on a portal, as the owner sets it. `order` is the position; `label` overrides the title. */
|
|
6030
|
+
interface PortalFormInput {
|
|
6031
|
+
form_id: Uuid;
|
|
6032
|
+
label?: string | null;
|
|
6033
|
+
order?: number | null;
|
|
6034
|
+
}
|
|
6035
|
+
/**
|
|
6036
|
+
* What `portalDeclare({ config })` sends. A key given REPLACES that key; a key not given is KEPT;
|
|
6037
|
+
* `style: null` puts the organization's brand back and `forms: []` takes every form off.
|
|
6038
|
+
*/
|
|
6039
|
+
interface PortalConfigInput {
|
|
6040
|
+
style?: PortalStyleInput | null;
|
|
6041
|
+
forms?: PortalFormInput[] | null;
|
|
6042
|
+
}
|
|
6043
|
+
/** The look and forms as the store holds them (normalized by the store). */
|
|
6044
|
+
interface PortalConfig {
|
|
6045
|
+
style?: PortalStyleInput;
|
|
6046
|
+
forms?: Array<{
|
|
6047
|
+
form_id: Uuid;
|
|
6048
|
+
label?: string;
|
|
6049
|
+
order: number;
|
|
6050
|
+
}>;
|
|
6051
|
+
}
|
|
6052
|
+
/** The look a client is shown — resolved by the store, never computed by a screen. */
|
|
6053
|
+
interface PortalStyle {
|
|
6054
|
+
display_name: string;
|
|
6055
|
+
welcome: string | null;
|
|
6056
|
+
logo_file_id: Uuid | null;
|
|
6057
|
+
/** The logo's PUBLIC address, or null. Readable by anybody the portal is shown to. */
|
|
6058
|
+
logo_url: string | null;
|
|
6059
|
+
/** Null means the app's own colour. */
|
|
6060
|
+
accent: PortalAccent | null;
|
|
6061
|
+
footer_links: PortalFooterLink[];
|
|
6062
|
+
/** Which of the values above came from the organization rather than the portal. */
|
|
6063
|
+
from_organization: Array<"display_name" | "logo">;
|
|
6064
|
+
}
|
|
6065
|
+
/** One form on a portal, with what the owner needs to see about it. */
|
|
6066
|
+
interface PortalFormRef {
|
|
6067
|
+
form_id: Uuid;
|
|
6068
|
+
/** What the portal calls it (the owner's label, else the form's title). */
|
|
6069
|
+
label: string;
|
|
6070
|
+
order: number;
|
|
6071
|
+
title: string;
|
|
6072
|
+
table_id: Uuid | null;
|
|
6073
|
+
table: string;
|
|
6074
|
+
/** `gone` is a form that was removed; the outsider's list only ever carries `open`. */
|
|
6075
|
+
state: "open" | "closed" | "full" | "gone";
|
|
6076
|
+
}
|
|
6077
|
+
/** A Table's stages as a portal client may be told them (`custom.portal_me` → tables[].stage). */
|
|
6078
|
+
interface PortalStage {
|
|
6079
|
+
/** The stage Field's key on the record. */
|
|
6080
|
+
field: string;
|
|
6081
|
+
label: string;
|
|
6082
|
+
/** In the order they were declared. A record stores the stage's `key`. */
|
|
6083
|
+
stages: Array<{
|
|
6084
|
+
key: string;
|
|
6085
|
+
label: string;
|
|
6086
|
+
retired: boolean;
|
|
6087
|
+
}>;
|
|
6088
|
+
}
|
|
6089
|
+
/** What `custom.portal_form` answers: one form on the caller's own portal. */
|
|
6090
|
+
interface PortalFormSpec {
|
|
6091
|
+
form_id: Uuid;
|
|
6092
|
+
portal_id: Uuid;
|
|
6093
|
+
table_id: Uuid;
|
|
6094
|
+
title: string;
|
|
6095
|
+
label: string;
|
|
6096
|
+
presentation: Record<string, unknown>;
|
|
6097
|
+
/** The form's exposed Fields as the store holds them — never the one naming the client. */
|
|
6098
|
+
fields: Array<Record<string, unknown> & {
|
|
6099
|
+
id: Uuid;
|
|
6100
|
+
key: string;
|
|
6101
|
+
}>;
|
|
6102
|
+
required: string[];
|
|
6103
|
+
state: "open" | "closed" | "full";
|
|
6104
|
+
message: string | null;
|
|
6105
|
+
}
|
|
6106
|
+
/** What `custom.portal_form_submit` answers. `held` waits for the office; `message` says so. */
|
|
6107
|
+
interface PortalFormAnswer {
|
|
6108
|
+
submission_id: Uuid | null;
|
|
6109
|
+
record_id: Uuid | null;
|
|
6110
|
+
state: "accepted" | "held" | "rejected" | "closed" | "full" | "too_many";
|
|
6111
|
+
message: string | null;
|
|
5917
6112
|
}
|
|
5918
6113
|
/** What `custom.portal_invite` answers. `say` is the door's own sentence. */
|
|
5919
6114
|
interface PortalInvitation {
|
|
@@ -6040,6 +6235,22 @@ type AggregateFilter = string | number | boolean | null | AggregateWindow;
|
|
|
6040
6235
|
* lands somewhere else, which is the only way a drill-through can lie.
|
|
6041
6236
|
*/
|
|
6042
6237
|
type RecordFilter = Record<string, AggregateFilter>;
|
|
6238
|
+
/**
|
|
6239
|
+
* S2-PRIME FILTER-GROUPS — A READ DOOR'S QUESTION, IN EITHER OF ITS TWO SHAPES.
|
|
6240
|
+
*
|
|
6241
|
+
* The flat `RecordFilter` above (field key → scalar / `null` / window, AND only) is what
|
|
6242
|
+
* dashboards, drill-throughs and the notifier carry. A `RuleExpression` — `{op, args}`, ALL / ANY /
|
|
6243
|
+
* NOT groups nested to any depth, fields by id — is what the condition builder, a view's own
|
|
6244
|
+
* filter and every membership Rule speak. `custom.record_filter_sql(org, table, filter)` turns
|
|
6245
|
+
* EITHER into the one WHERE clause the grid (`list`), the aggregate and the board all use, so the
|
|
6246
|
+
* three can never disagree about which records a view holds.
|
|
6247
|
+
*/
|
|
6248
|
+
type StoreFilter = RecordFilter | RuleExpression;
|
|
6249
|
+
/**
|
|
6250
|
+
* Is this filter a Rule expression? The store's own test (`custom.filter_is_rule`): an object
|
|
6251
|
+
* whose `op` is a word and which carries `args`.
|
|
6252
|
+
*/
|
|
6253
|
+
declare function isRuleFilter(filter: unknown): filter is RuleExpression;
|
|
6043
6254
|
/** One measure. `count` counts rows and needs no Field; the rest read one. */
|
|
6044
6255
|
interface AggregateMeasure {
|
|
6045
6256
|
op: AggregateOperation;
|
|
@@ -6055,6 +6266,90 @@ interface AggregateRow {
|
|
|
6055
6266
|
groups: Record<string, string | null>;
|
|
6056
6267
|
measures: Record<string, number | null>;
|
|
6057
6268
|
row_count: number;
|
|
6269
|
+
/**
|
|
6270
|
+
* S3 — present only when the question carried a comparison. The same group
|
|
6271
|
+
* in the PRIOR window: a bucket is matched by its position in its own window
|
|
6272
|
+
* (week 1 of September beside week 1 of August), so `prior_groups` names the
|
|
6273
|
+
* prior bucket's own date. `null` when the prior window had no such group.
|
|
6274
|
+
*/
|
|
6275
|
+
prior_groups?: Record<string, string | null> | null;
|
|
6276
|
+
/** The prior window's measures, keyed exactly like `measures`. */
|
|
6277
|
+
prior_measures?: Record<string, number | null> | null;
|
|
6278
|
+
prior_row_count?: number | null;
|
|
6279
|
+
/** Every measure now and before, the change, and the change as a percent of before. */
|
|
6280
|
+
delta?: Record<string, AggregateDelta> | null;
|
|
6281
|
+
/** The two windows this row was worked out over, and the calendar that cut them. */
|
|
6282
|
+
compare?: AggregateCompareWindows | null;
|
|
6283
|
+
/**
|
|
6284
|
+
* S3 — a compared, bucketed row's POSITION in its window (0 = the first
|
|
6285
|
+
* bucket). A row the current window has not reached yet has a position and
|
|
6286
|
+
* no current bucket, so a chart names it "Week 6" rather than inventing a date.
|
|
6287
|
+
*/
|
|
6288
|
+
position?: number | null;
|
|
6289
|
+
}
|
|
6290
|
+
/**
|
|
6291
|
+
* S3 — WHAT A PERIOD IS COMPARED AGAINST (`custom.agg_compare_kinds()`).
|
|
6292
|
+
* `previous_period` is the period before, of the same length (August before
|
|
6293
|
+
* September; an explicit window shifted back by its own length);
|
|
6294
|
+
* `same_period_last_year`; `range` is a fixed `baseline`.
|
|
6295
|
+
*/
|
|
6296
|
+
type AggregateCompareKind = "previous_period" | "same_period_last_year" | "range";
|
|
6297
|
+
/**
|
|
6298
|
+
* S3 — ONE COMPARISON, as `custom.record_aggregate(p_compare)` and a
|
|
6299
|
+
* dashboard block's `compare` both take it. The current window is either the
|
|
6300
|
+
* calendar `period` holding `at` (default: now, in the organization's time
|
|
6301
|
+
* zone) or an explicit `from`/`to`. A date alone ("2026-09-01") is that local
|
|
6302
|
+
* day in the organization's time zone.
|
|
6303
|
+
*/
|
|
6304
|
+
interface AggregateCompare {
|
|
6305
|
+
against?: AggregateCompareKind;
|
|
6306
|
+
/** The date Field the period runs along. Defaults to the bucket's key. */
|
|
6307
|
+
key?: string;
|
|
6308
|
+
period?: AggregateBucket;
|
|
6309
|
+
at?: string;
|
|
6310
|
+
from?: string;
|
|
6311
|
+
to?: string;
|
|
6312
|
+
/** Compare the part of the period that has happened ("month to date"). */
|
|
6313
|
+
to_date?: boolean;
|
|
6314
|
+
/** The fixed period `range` compares against. Half-open: `to` is excluded. */
|
|
6315
|
+
baseline?: {
|
|
6316
|
+
from: string;
|
|
6317
|
+
to: string;
|
|
6318
|
+
};
|
|
6319
|
+
}
|
|
6320
|
+
/** One measure now and before. `change_pct` is null when before was nothing or zero. */
|
|
6321
|
+
interface AggregateDelta {
|
|
6322
|
+
current: number | null;
|
|
6323
|
+
prior: number | null;
|
|
6324
|
+
change: number | null;
|
|
6325
|
+
change_pct: number | null;
|
|
6326
|
+
}
|
|
6327
|
+
/**
|
|
6328
|
+
* S3 — THE TWO WINDOWS the store actually ran, as local ISO moments with the
|
|
6329
|
+
* organization's offset ("2026-09-01T00:00:00-07:00"), and the calendar that
|
|
6330
|
+
* cut them. A screen labels the comparison from THIS, never from its own clock.
|
|
6331
|
+
*/
|
|
6332
|
+
interface AggregateCompareWindows {
|
|
6333
|
+
key: string;
|
|
6334
|
+
against: AggregateCompareKind;
|
|
6335
|
+
period: AggregateBucket | null;
|
|
6336
|
+
to_date: boolean;
|
|
6337
|
+
time_zone: string;
|
|
6338
|
+
week_start: string;
|
|
6339
|
+
/** The bucket grain the windows were counted in, when the question had a bucket. */
|
|
6340
|
+
grain: AggregateBucket | null;
|
|
6341
|
+
/** How many buckets the current window holds — what a target's pace is shared over. */
|
|
6342
|
+
bucket_count: number | null;
|
|
6343
|
+
window: {
|
|
6344
|
+
from: string;
|
|
6345
|
+
to: string;
|
|
6346
|
+
};
|
|
6347
|
+
prior_window: {
|
|
6348
|
+
from: string;
|
|
6349
|
+
to: string;
|
|
6350
|
+
};
|
|
6351
|
+
/** On a row from `recordAggregate`: that row's bucket position (see `AggregateRow.position`). */
|
|
6352
|
+
position?: number | null;
|
|
6058
6353
|
}
|
|
6059
6354
|
/** The measure key the store answers with, so a chart can find its own series. */
|
|
6060
6355
|
declare function measureKey(measure: AggregateMeasure): string;
|
|
@@ -6070,7 +6365,7 @@ declare function measureKey(measure: AggregateMeasure): string;
|
|
|
6070
6365
|
* one question. `undefined` and an empty filter are both `"{}"` — the caller
|
|
6071
6366
|
* asked nothing, and there is only one way to ask nothing.
|
|
6072
6367
|
*/
|
|
6073
|
-
declare function stableFilterKey(filter:
|
|
6368
|
+
declare function stableFilterKey(filter: StoreFilter | null | undefined): string;
|
|
6074
6369
|
|
|
6075
6370
|
/**
|
|
6076
6371
|
* Who the data belongs to. A test organization is created under this name — the
|
|
@@ -6628,6 +6923,187 @@ declare function recordChangeTrigger(tableId: Uuid, options?: {
|
|
|
6628
6923
|
actions?: RecordChangeAction[];
|
|
6629
6924
|
changed_fields?: string[];
|
|
6630
6925
|
};
|
|
6926
|
+
/**
|
|
6927
|
+
* One entry of `custom.table_list_everywhere` — `public.get_user_tables`' own shape plus
|
|
6928
|
+
* `store`, so a picker swaps one call and keeps its code. `store` says which home opens it.
|
|
6929
|
+
*/
|
|
6930
|
+
interface TableListEntry {
|
|
6931
|
+
id: Uuid;
|
|
6932
|
+
table_name: string;
|
|
6933
|
+
description: string | null;
|
|
6934
|
+
version: number | null;
|
|
6935
|
+
user_id: Uuid | null;
|
|
6936
|
+
is_public: boolean | null;
|
|
6937
|
+
visibility: string | null;
|
|
6938
|
+
organization_id: Uuid;
|
|
6939
|
+
created_at: string;
|
|
6940
|
+
updated_at: string | null;
|
|
6941
|
+
last_activity_at: string | null;
|
|
6942
|
+
row_count: number;
|
|
6943
|
+
field_count: number;
|
|
6944
|
+
store: "older" | "records";
|
|
6945
|
+
}
|
|
6946
|
+
/** Where a synced table comes from. `external_id` is the source's own id (a spreadsheet id). */
|
|
6947
|
+
interface TableSyncSource {
|
|
6948
|
+
provider: string;
|
|
6949
|
+
external_id: string;
|
|
6950
|
+
tab_id?: string | null;
|
|
6951
|
+
synced_at?: string | null;
|
|
6952
|
+
}
|
|
6953
|
+
/** What `custom.table_sync` takes: the source, its columns, and every row it has NOW. */
|
|
6954
|
+
interface TableSyncSpec {
|
|
6955
|
+
source: TableSyncSource;
|
|
6956
|
+
table_name: string;
|
|
6957
|
+
columns: string[];
|
|
6958
|
+
rows: {
|
|
6959
|
+
ref: string;
|
|
6960
|
+
values: Record<string, string | number | boolean | null>;
|
|
6961
|
+
}[];
|
|
6962
|
+
}
|
|
6963
|
+
interface TableSyncResult {
|
|
6964
|
+
table_id: Uuid;
|
|
6965
|
+
created: boolean;
|
|
6966
|
+
fields_added: number;
|
|
6967
|
+
rows_inserted: number;
|
|
6968
|
+
rows_updated: number;
|
|
6969
|
+
rows_archived: number;
|
|
6970
|
+
source_system: string;
|
|
6971
|
+
}
|
|
6972
|
+
/**
|
|
6973
|
+
* A sheet tab's cells (header row first) → the spec `custom.table_sync` takes. Every row is
|
|
6974
|
+
* named by its sheet row number (`row-2` is the first row under the header) unless
|
|
6975
|
+
* `refColumn` names a column holding a stable id; a blank or repeated ref is refused here, so
|
|
6976
|
+
* the store never sees two rows claiming to be the same source row. Wholly blank rows are
|
|
6977
|
+
* skipped. Pure.
|
|
6978
|
+
*/
|
|
6979
|
+
declare function sheetSyncSpec(args: {
|
|
6980
|
+
source: TableSyncSource;
|
|
6981
|
+
tableName: string;
|
|
6982
|
+
cells: readonly (readonly (string | number | boolean | null | undefined)[])[];
|
|
6983
|
+
refColumn?: string;
|
|
6984
|
+
}): TableSyncSpec;
|
|
6985
|
+
/** One row of `custom.table_row_counts`: the rows of that Table this reader may see. */
|
|
6986
|
+
interface TableRowCount {
|
|
6987
|
+
table_id: Uuid;
|
|
6988
|
+
visible_rows: number;
|
|
6989
|
+
}
|
|
6990
|
+
/**
|
|
6991
|
+
* One row of `custom.record_headers`: the row's own columns the document door does not answer.
|
|
6992
|
+
* `created_by` is the caller's own id on rows the caller made and null on every other; `mine`
|
|
6993
|
+
* says which.
|
|
6994
|
+
*/
|
|
6995
|
+
interface RecordHeader {
|
|
6996
|
+
id: Uuid;
|
|
6997
|
+
table_id: Uuid;
|
|
6998
|
+
created_at: string;
|
|
6999
|
+
updated_at: string;
|
|
7000
|
+
version: number;
|
|
7001
|
+
deleted_at: string | null;
|
|
7002
|
+
mine: boolean;
|
|
7003
|
+
created_by: Uuid | null;
|
|
7004
|
+
}
|
|
7005
|
+
/**
|
|
7006
|
+
* Fold `table_row_counts` onto a table list: `row_count` set on every Table the counts name.
|
|
7007
|
+
* A Table the counts do not name keeps what it had — the store answers no row for a Table this
|
|
7008
|
+
* reader may not know, and that is never turned into a zero. Pure.
|
|
7009
|
+
*/
|
|
7010
|
+
declare function withRowCounts<T extends {
|
|
7011
|
+
id: Uuid;
|
|
7012
|
+
row_count?: number | null;
|
|
7013
|
+
}>(tables: readonly T[], counts: readonly TableRowCount[] | null | undefined): T[];
|
|
7014
|
+
/** What `custom.view_record_order_set` answers. */
|
|
7015
|
+
interface ViewOrderSet {
|
|
7016
|
+
view_id: Uuid;
|
|
7017
|
+
table_id: Uuid;
|
|
7018
|
+
order: "manual";
|
|
7019
|
+
named: number;
|
|
7020
|
+
positioned: number;
|
|
7021
|
+
}
|
|
7022
|
+
/**
|
|
7023
|
+
* The order to send after a drag: `order` with `moved` taken out and put at `toIndex` (clamped).
|
|
7024
|
+
* The store keeps every row the call does not name in its old place after the named ones, so a
|
|
7025
|
+
* screen may send only the rows it shows. Pure.
|
|
7026
|
+
*/
|
|
7027
|
+
declare function moveInOrder(order: readonly Uuid[], moved: Uuid, toIndex: number): Uuid[];
|
|
7028
|
+
/**
|
|
7029
|
+
* What `custom.table_share_outside_grant` answers. `person` says which path ran:
|
|
7030
|
+
* `outside_account` (granted at once and notified — never made a member), `member` (a plain
|
|
7031
|
+
* share), `no_account` (the invitation door's own answer, with its link and delivery).
|
|
7032
|
+
*/
|
|
7033
|
+
interface OutsideShareAnswer {
|
|
7034
|
+
granted: boolean;
|
|
7035
|
+
invited: boolean;
|
|
7036
|
+
joined: boolean;
|
|
7037
|
+
person: "outside_account" | "member" | "no_account";
|
|
7038
|
+
email: string;
|
|
7039
|
+
table: string;
|
|
7040
|
+
level: string;
|
|
7041
|
+
level_label: string;
|
|
7042
|
+
say: string;
|
|
7043
|
+
user_id?: Uuid;
|
|
7044
|
+
permission_id?: Uuid;
|
|
7045
|
+
invitation_id?: Uuid | null;
|
|
7046
|
+
accept_path?: string | null;
|
|
7047
|
+
delivery_say?: string | null;
|
|
7048
|
+
}
|
|
7049
|
+
|
|
7050
|
+
/** The three placement facts, as the Table document or `custom.table` carries them. */
|
|
7051
|
+
interface TablePlacement {
|
|
7052
|
+
kept_by_the_app?: boolean | null;
|
|
7053
|
+
kept_for?: string | null;
|
|
7054
|
+
offered_as_context?: boolean | null;
|
|
7055
|
+
}
|
|
7056
|
+
/**
|
|
7057
|
+
* One row of `custom.table_facts` since SC-1 — the two lane facts it always answered
|
|
7058
|
+
* (`visibility`, `mine`) and the placement, with the sentence a person reads and where the
|
|
7059
|
+
* table is used. A store without the SC-1 door answers the first three columns only; every
|
|
7060
|
+
* placement column is then `undefined`, and the readers below treat the table as the
|
|
7061
|
+
* organization's own — exactly what that store's older screens did.
|
|
7062
|
+
*/
|
|
7063
|
+
interface TablePlacementFact extends TablePlacement {
|
|
7064
|
+
table_id: Uuid;
|
|
7065
|
+
visibility: string;
|
|
7066
|
+
mine: boolean;
|
|
7067
|
+
/** The heading a kept table is listed under: "The context system", "The choices behind your columns", … */
|
|
7068
|
+
keeper_group?: string | null;
|
|
7069
|
+
/** One plain sentence: who keeps it and where it opens from. Null for the organization's own. */
|
|
7070
|
+
keeper_says?: string | null;
|
|
7071
|
+
/** Where the table is used: `table` (another Table, or itself) or `scope` (a context scope). */
|
|
7072
|
+
used_in_kind?: "table" | "scope" | null;
|
|
7073
|
+
used_in_id?: Uuid | null;
|
|
7074
|
+
/** The Table that page belongs to, when `used_in_kind` is `table`. */
|
|
7075
|
+
used_in_table_id?: Uuid | null;
|
|
7076
|
+
}
|
|
7077
|
+
/** Whether a person's list of tables keeps this one out of sight until "Show everything". */
|
|
7078
|
+
declare function keptOutOfSight(placement: TablePlacement | null | undefined): boolean;
|
|
7079
|
+
/** Whether the context picker may offer this Table. Absent is no. */
|
|
7080
|
+
declare function offeredAsContext(placement: TablePlacement | null | undefined): boolean;
|
|
7081
|
+
/**
|
|
7082
|
+
* The placement facts folded onto a table list, by id. Pure — returns new objects and leaves
|
|
7083
|
+
* the list it was given alone. A table the facts do not name is returned unchanged.
|
|
7084
|
+
*/
|
|
7085
|
+
declare function withTablePlacement<T extends {
|
|
7086
|
+
id: Uuid;
|
|
7087
|
+
}>(tables: readonly T[], facts: readonly TablePlacementFact[] | null | undefined): Array<T & Partial<TablePlacementFact>>;
|
|
7088
|
+
/**
|
|
7089
|
+
* THE KEPT TABLES, GROUPED UNDER THEIR KEEPER, in the order each group first appears. A kept
|
|
7090
|
+
* table the store gave no heading goes under "Kept by the app" — never dropped.
|
|
7091
|
+
*/
|
|
7092
|
+
declare function keptGroups<T extends TablePlacement & Partial<TablePlacementFact>>(tables: readonly T[]): Array<{
|
|
7093
|
+
group: string;
|
|
7094
|
+
tables: T[];
|
|
7095
|
+
}>;
|
|
7096
|
+
/**
|
|
7097
|
+
* WHERE A KEPT TABLE OPENS FROM (THE DOOR LAW): the host's own addresses for a table and for a
|
|
7098
|
+
* context scope, chosen by what the store said the table is used in. With nothing said, the
|
|
7099
|
+
* table's own page — a kept table is never a row with nowhere to go.
|
|
7100
|
+
*/
|
|
7101
|
+
declare function keptTableHref(fact: {
|
|
7102
|
+
table_id: Uuid;
|
|
7103
|
+
} & Partial<TablePlacementFact>, hrefs: {
|
|
7104
|
+
table: (tableId: Uuid) => string;
|
|
7105
|
+
scope: (scopeId: Uuid) => string;
|
|
7106
|
+
}): string;
|
|
6631
7107
|
|
|
6632
7108
|
/** The seven shapes a block can take, exactly as `custom.dashboard_kinds()` answers. */
|
|
6633
7109
|
type DashboardBlockKind = "number" | "bar" | "column" | "line" | "donut" | "table" | "stuck";
|
|
@@ -6660,6 +7136,43 @@ interface DashboardBlock {
|
|
|
6660
7136
|
state_key?: string;
|
|
6661
7137
|
/** `stuck` only: how long a record may sit on the same value. Defaults to 14. */
|
|
6662
7138
|
days?: number;
|
|
7139
|
+
/**
|
|
7140
|
+
* S3 — the comparison this block makes (this month against last month).
|
|
7141
|
+
* The door fills `key` from the bucket when it is left out, and refuses a
|
|
7142
|
+
* comparison along a Field the Table does not have, by name.
|
|
7143
|
+
*/
|
|
7144
|
+
compare?: AggregateCompare | null;
|
|
7145
|
+
/** S3 — the number this block is aiming for. */
|
|
7146
|
+
target?: DashboardTarget | null;
|
|
7147
|
+
}
|
|
7148
|
+
/**
|
|
7149
|
+
* S3 — A BLOCK'S TARGET. `measure` is one of the block's own measure keys
|
|
7150
|
+
* (default: the first). `per: "period"` is a target for the whole window (a
|
|
7151
|
+
* monthly target — a bucketed chart draws its even share per bucket as the
|
|
7152
|
+
* pace); `per: "bucket"` is a target for every bar or point.
|
|
7153
|
+
*
|
|
7154
|
+
* A target is a FIXED NUMBER (`value`) or A GOAL COLUMN (`field`, a Field key of
|
|
7155
|
+
* the block's Table): the store adds that column up (`op`, default `sum`) over
|
|
7156
|
+
* exactly the records the block's own number read — same filter, same window,
|
|
7157
|
+
* same reader — so "invoiced against quoted" is about the same jobs. Exactly
|
|
7158
|
+
* one of the two; a goal column is always `per: "period"`.
|
|
7159
|
+
*/
|
|
7160
|
+
type DashboardTarget = DashboardTargetBase & ({
|
|
7161
|
+
value: number;
|
|
7162
|
+
field?: never;
|
|
7163
|
+
op?: never;
|
|
7164
|
+
} | {
|
|
7165
|
+
field: string;
|
|
7166
|
+
op?: DashboardTargetOp;
|
|
7167
|
+
value?: never;
|
|
7168
|
+
});
|
|
7169
|
+
/** How a goal column is added up across the block's records. */
|
|
7170
|
+
type DashboardTargetOp = "sum" | "avg" | "min" | "max";
|
|
7171
|
+
/** What every target carries, whichever kind it is. */
|
|
7172
|
+
interface DashboardTargetBase {
|
|
7173
|
+
label?: string;
|
|
7174
|
+
measure?: string;
|
|
7175
|
+
per?: "period" | "bucket";
|
|
6663
7176
|
}
|
|
6664
7177
|
/** One dashboard as `custom.dashboards` reports it to its organization. */
|
|
6665
7178
|
interface DashboardSummary {
|
|
@@ -6718,6 +7231,56 @@ interface DashboardBlockResult {
|
|
|
6718
7231
|
refused?: string;
|
|
6719
7232
|
/** The SQLSTATE that refusal carried. */
|
|
6720
7233
|
sqlstate?: string;
|
|
7234
|
+
/**
|
|
7235
|
+
* S3 — the windows this block was actually compared over; `null` when it was
|
|
7236
|
+
* not compared. (The comparison it was ASKED to make is the saved block's.)
|
|
7237
|
+
*/
|
|
7238
|
+
compare?: AggregateCompareWindows | null;
|
|
7239
|
+
/** S3 — why a canvas comparison was not applied to this block (it has no date). */
|
|
7240
|
+
compare_refused?: string;
|
|
7241
|
+
/**
|
|
7242
|
+
* S3 — the block's first (or target) measure added up across its rows, now
|
|
7243
|
+
* and before, when the measure adds up (count, sum, filled, empty) or the
|
|
7244
|
+
* block has one row. Worked out by the store from the rows it answered, so
|
|
7245
|
+
* a tile, a chart and a ring cannot disagree.
|
|
7246
|
+
*/
|
|
7247
|
+
totals?: DashboardTotals;
|
|
7248
|
+
/** S3 — the target, with how far the current total has come and its pace per bucket. */
|
|
7249
|
+
target?: DashboardTargetResult;
|
|
7250
|
+
}
|
|
7251
|
+
/** S3 — one block's total, now and before. */
|
|
7252
|
+
interface DashboardTotals {
|
|
7253
|
+
measure: string;
|
|
7254
|
+
current: number | null;
|
|
7255
|
+
prior: number | null;
|
|
7256
|
+
change: number | null;
|
|
7257
|
+
change_pct: number | null;
|
|
7258
|
+
}
|
|
7259
|
+
/** S3 — a target as the run answers it. */
|
|
7260
|
+
interface DashboardTargetResult {
|
|
7261
|
+
/**
|
|
7262
|
+
* The number aimed at: the fixed value, or the goal column added up over this
|
|
7263
|
+
* block's records. `null` when a goal column had nothing to add up, or was refused.
|
|
7264
|
+
*/
|
|
7265
|
+
value: number | null;
|
|
7266
|
+
/** A goal column's key, when the target is read from one. */
|
|
7267
|
+
field?: string;
|
|
7268
|
+
/** How that column was added up. */
|
|
7269
|
+
op?: DashboardTargetOp;
|
|
7270
|
+
/**
|
|
7271
|
+
* The store's own sentence when THIS reader may not read the goal column — the
|
|
7272
|
+
* block still answers its number; only the target is withheld.
|
|
7273
|
+
*/
|
|
7274
|
+
refused?: string;
|
|
7275
|
+
label: string;
|
|
7276
|
+
measure: string;
|
|
7277
|
+
per: "period" | "bucket";
|
|
7278
|
+
/** The current total the target is measured against. */
|
|
7279
|
+
current: number | null;
|
|
7280
|
+
/** current ÷ value, 4 decimals. */
|
|
7281
|
+
progress: number | null;
|
|
7282
|
+
/** The line a bucketed chart draws: the target's even share of one bucket, or the target itself per bucket. */
|
|
7283
|
+
pace: number | null;
|
|
6721
7284
|
}
|
|
6722
7285
|
/** What `custom.dashboard_run` answers: the canvas, and every block's own result. */
|
|
6723
7286
|
interface DashboardRunResult {
|
|
@@ -6727,6 +7290,15 @@ interface DashboardRunResult {
|
|
|
6727
7290
|
presentation: Record<string, unknown>;
|
|
6728
7291
|
/** The one filter bar this run was asked with. */
|
|
6729
7292
|
filter: Record<string, AggregateFilter>;
|
|
7293
|
+
/** S3 — the date grain the canvas re-cut every bucketed block to, or null. */
|
|
7294
|
+
grain?: AggregateBucket | null;
|
|
7295
|
+
/** S3 — the canvas comparison this run was asked with, or null. */
|
|
7296
|
+
compare?: AggregateCompare | null;
|
|
7297
|
+
/** S3 — the organization's calendar every date on this canvas was cut with. */
|
|
7298
|
+
calendar?: {
|
|
7299
|
+
time_zone: string;
|
|
7300
|
+
week_start: string;
|
|
7301
|
+
};
|
|
6730
7302
|
blocks: DashboardBlockResult[];
|
|
6731
7303
|
}
|
|
6732
7304
|
|
|
@@ -7458,11 +8030,22 @@ interface SavedViewRow {
|
|
|
7458
8030
|
name: string;
|
|
7459
8031
|
table_id: Uuid | null;
|
|
7460
8032
|
filters: RecordFilter;
|
|
8033
|
+
/**
|
|
8034
|
+
* THE WHOLE VIEW (S0 ONE-SAVED-VIEW, 2026-09-23): `platform.saved_view` is the ONE saved-view
|
|
8035
|
+
* store, so this is what the view bar, the board, the calendar and the gallery draw from —
|
|
8036
|
+
* `layout` (the kind), `group_field`, `measure`, `date_field`, `image_field`, `sorts`, `rule_id`,
|
|
8037
|
+
* `is_default`, `presentation`, G7's `grid`, G13's `order`, the mover's `moved_from`.
|
|
8038
|
+
*/
|
|
8039
|
+
definition: Record<string, unknown>;
|
|
7461
8040
|
created_at: string;
|
|
7462
8041
|
}
|
|
7463
|
-
/**
|
|
8042
|
+
/**
|
|
8043
|
+
* What `custom.view_declare` is asked for. With `view_id` the door MERGES: `name` changes only
|
|
8044
|
+
* when sent, `filters` only when the key is sent, each `definition` key replaces that one key and
|
|
8045
|
+
* a key sent as `null` is removed — so a screen sends only what it changed.
|
|
8046
|
+
*/
|
|
7464
8047
|
interface SavedViewSpecIn {
|
|
7465
|
-
name
|
|
8048
|
+
name?: string;
|
|
7466
8049
|
filters?: RecordFilter | null;
|
|
7467
8050
|
definition?: Record<string, unknown> | null;
|
|
7468
8051
|
view_id?: Uuid | null;
|
|
@@ -7493,43 +8076,204 @@ interface SubscriptionBlock {
|
|
|
7493
8076
|
}
|
|
7494
8077
|
|
|
7495
8078
|
/**
|
|
7496
|
-
*
|
|
7497
|
-
*
|
|
8079
|
+
* The data seam: a structural subset of `SupabaseClient`. The package never
|
|
8080
|
+
* opens a database connection of its own and never holds a key — the HOST
|
|
8081
|
+
* supplies a client that already carries the operating person's session, which
|
|
8082
|
+
* is what makes DOOR-5 and AGT-N-4 true (the store sees the person, not us).
|
|
7498
8083
|
*/
|
|
7499
|
-
interface
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
|
|
8084
|
+
interface RecordsDataSource {
|
|
8085
|
+
/**
|
|
8086
|
+
* Call a door. The name is always a door the live catalogue has; `/core`
|
|
8087
|
+
* refuses `door_absent` before it ever reaches here for one that does not.
|
|
8088
|
+
*/
|
|
8089
|
+
rpc(fn: string, args: Record<string, unknown>,
|
|
8090
|
+
/**
|
|
8091
|
+
* THE SCHEMA THE DOOR LIVES IN, always supplied: `custom` for the store's
|
|
8092
|
+
* own doors, `iam` for the trust doors (the external principal and the
|
|
8093
|
+
* publish binding, which are the PLATFORM's). A host binding supabase-js
|
|
8094
|
+
* routes this to `client.schema(options.schema).rpc(fn, args)`; a host that
|
|
8095
|
+
* ignores it calls its own default PostgREST profile — `public` — and is
|
|
8096
|
+
* refused by name, which is the failure we want rather than a silent answer
|
|
8097
|
+
* from the wrong system. (Before 2026-09-18 this was described as "only ever
|
|
8098
|
+
* `iam`" and the store's doors went unqualified; the extension's first real
|
|
8099
|
+
* turn proved that asks `public.store_is_open` and finds nothing.)
|
|
8100
|
+
*/
|
|
8101
|
+
options?: {
|
|
8102
|
+
schema?: string;
|
|
8103
|
+
}): PromiseLike<{
|
|
8104
|
+
data: unknown;
|
|
8105
|
+
error: PgError | null;
|
|
8106
|
+
}>;
|
|
8107
|
+
/** Reads of `custom.*` go through the schema-qualified builder, never a bare `from`. */
|
|
8108
|
+
schema(name: string): {
|
|
8109
|
+
from(table: string): RecordsTableQuery;
|
|
8110
|
+
};
|
|
7503
8111
|
}
|
|
7504
|
-
/** The
|
|
7505
|
-
interface
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
/** REL-3. A snapshot is a frozen copy in the relation's payload — never a pointer into History. */
|
|
7511
|
-
binding: RelationBinding;
|
|
7512
|
-
/** REL-4. */
|
|
7513
|
-
ordered: boolean;
|
|
7514
|
-
/** REL-5. */
|
|
7515
|
-
loops: "allowed" | "refused";
|
|
7516
|
-
/** REL-6. */
|
|
7517
|
-
carries: RelationCarries;
|
|
7518
|
-
/** REL-7. */
|
|
7519
|
-
cardinality: RelationCardinality;
|
|
8112
|
+
/** The read surface the list and query paths use. A real supabase-js client satisfies it. */
|
|
8113
|
+
interface RecordsTableQuery {
|
|
8114
|
+
select(columns: string, options?: {
|
|
8115
|
+
count?: "exact" | "planned" | "estimated";
|
|
8116
|
+
head?: boolean;
|
|
8117
|
+
}): RecordsFilter;
|
|
7520
8118
|
}
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
8119
|
+
interface RecordsFilter extends PromiseLike<RecordsResponse> {
|
|
8120
|
+
eq(column: string, value: unknown): RecordsFilter;
|
|
8121
|
+
neq(column: string, value: unknown): RecordsFilter;
|
|
8122
|
+
in(column: string, values: readonly unknown[]): RecordsFilter;
|
|
8123
|
+
is(column: string, value: null | boolean): RecordsFilter;
|
|
8124
|
+
gte(column: string, value: unknown): RecordsFilter;
|
|
8125
|
+
lte(column: string, value: unknown): RecordsFilter;
|
|
8126
|
+
order(column: string, options?: {
|
|
8127
|
+
ascending?: boolean;
|
|
8128
|
+
}): RecordsFilter;
|
|
8129
|
+
range(from: number, to: number): RecordsFilter;
|
|
8130
|
+
limit(count: number): RecordsFilter;
|
|
8131
|
+
}
|
|
8132
|
+
interface RecordsResponse {
|
|
8133
|
+
data: unknown;
|
|
8134
|
+
error: PgError | null;
|
|
8135
|
+
count?: number | null;
|
|
8136
|
+
}
|
|
8137
|
+
/**
|
|
8138
|
+
* WHO IS ACTING. AGT-N-4: an agent carries the exact authority of the person
|
|
8139
|
+
* operating it — there is no agent identity and there are no service roles. So
|
|
8140
|
+
* the actor word and the person are two separate facts, and `on_behalf_of` is
|
|
8141
|
+
* meaningful only when the actor is `agent`.
|
|
8142
|
+
*/
|
|
8143
|
+
interface RecordsActor {
|
|
8144
|
+
actor: Actor;
|
|
8145
|
+
/** The signed-in person. The store reads this from the session, not from us; this is for the client's own mirror. */
|
|
8146
|
+
user_id?: Uuid;
|
|
8147
|
+
/** Only an agent acts on behalf of a person (the store refuses it otherwise). */
|
|
8148
|
+
on_behalf_of?: Uuid;
|
|
8149
|
+
}
|
|
8150
|
+
/**
|
|
8151
|
+
* OPTIONAL. A live-updates seam. The default degradation is stated rather than
|
|
8152
|
+
* silent: with no port bound, `useRecords` reports `live: false` and the screen
|
|
8153
|
+
* can say "not live" instead of quietly going stale.
|
|
8154
|
+
*
|
|
8155
|
+
* A host binds this with `@ai-matrx/data/react`'s channel hygiene — the package
|
|
8156
|
+
* deliberately does NOT depend on it, so the headless core stays free of a
|
|
8157
|
+
* realtime client and a host that has one keeps using the one it already has.
|
|
8158
|
+
*/
|
|
8159
|
+
interface RecordsRealtimePort {
|
|
8160
|
+
/**
|
|
8161
|
+
* Watch one organization's records of one table. Returns an unsubscribe.
|
|
8162
|
+
*
|
|
8163
|
+
* THE HOST NUDGES THROUGH THIS SINK AND REACHES AROUND NOTHING. Until 0.43.0 the callback
|
|
8164
|
+
* was `(recordId: Uuid) => void` and a host that also wanted to say "the SHAPE moved"
|
|
8165
|
+
* imported `tableShapeChanged` from `@ai-matrx/records/react` and called it directly —
|
|
8166
|
+
* which worked, and which meant the port contract did not describe half of what a port
|
|
8167
|
+
* actually does. A column appearing is not a row changing, and the package owns the
|
|
8168
|
+
* difference.
|
|
8169
|
+
*
|
|
8170
|
+
* NOTHING THAT ARRIVES HERE IS DATA. A nudge has not passed the read door, so the hook
|
|
8171
|
+
* re-reads — by id set when the nudge names ids, whole-page when it cannot.
|
|
8172
|
+
*/
|
|
8173
|
+
subscribeRecords(args: {
|
|
8174
|
+
organization_id: Uuid;
|
|
8175
|
+
table_id: Uuid;
|
|
8176
|
+
}, sink: RecordsChangeSink): () => void;
|
|
8177
|
+
}
|
|
8178
|
+
/** What a realtime port may tell the package. Two calls, because a column is not a row. */
|
|
8179
|
+
interface RecordsChangeSink {
|
|
8180
|
+
/**
|
|
8181
|
+
* THESE RECORDS MOVED. `null` means "I cannot tell you which" — a reconnect, a tab wake, or
|
|
8182
|
+
* a change above the store's own id cap — and is the one case that costs a whole-page read.
|
|
8183
|
+
* An EMPTY array is not the same thing and is not a nudge at all.
|
|
8184
|
+
*/
|
|
8185
|
+
records(ids: readonly Uuid[] | null): void;
|
|
8186
|
+
/**
|
|
8187
|
+
* THIS TABLE'S SHAPE MOVED — a column added, retired or changed. Re-reading the rows would
|
|
8188
|
+
* redraw the same table without the new column in it, which is a screen that is out of date
|
|
8189
|
+
* while looking healthy.
|
|
8190
|
+
*/
|
|
8191
|
+
shape(): void;
|
|
8192
|
+
}
|
|
8193
|
+
/**
|
|
8194
|
+
* OPTIONAL. Where a refusal that nobody asked about goes — the loud funnel.
|
|
8195
|
+
* Default degradation: `console.error` with the store's own words, never
|
|
8196
|
+
* silence.
|
|
8197
|
+
*/
|
|
8198
|
+
type RecordsErrorSink = (error: {
|
|
8199
|
+
code: string;
|
|
8200
|
+
message: string;
|
|
8201
|
+
hint?: string;
|
|
8202
|
+
where: string;
|
|
8203
|
+
}) => void;
|
|
8204
|
+
/**
|
|
8205
|
+
* OPTIONAL. The merge-field resolver's server half (`W5-MERGE-B`). While it is
|
|
8206
|
+
* not bound, `useMergeField` answers `pending` WITH THE REASON — never a blank,
|
|
8207
|
+
* never a literal placeholder left in the text (DYN-14).
|
|
8208
|
+
*/
|
|
8209
|
+
interface RecordsResolverPort {
|
|
8210
|
+
resolve(args: {
|
|
8211
|
+
organization_id: Uuid;
|
|
8212
|
+
merge_field_keys: string[];
|
|
8213
|
+
/** The live selection the `state` source reads (DYNAMIC-VALUES §C). */
|
|
8214
|
+
state?: Record<string, unknown>;
|
|
8215
|
+
}): Promise<unknown>;
|
|
8216
|
+
}
|
|
8217
|
+
/** The one config a host binds. */
|
|
8218
|
+
interface RecordsConfig {
|
|
8219
|
+
/** REQUIRED. */
|
|
8220
|
+
dataSource: RecordsDataSource;
|
|
8221
|
+
/** REQUIRED. */
|
|
8222
|
+
actor: RecordsActor;
|
|
8223
|
+
/**
|
|
8224
|
+
* REQUIRED. REC-29: organizations are hard walls, and the store is keyed
|
|
8225
|
+
* `(organization_id, id)`. There is no "current organization" this package
|
|
8226
|
+
* discovers for itself — the host says which one, every time.
|
|
8227
|
+
*/
|
|
8228
|
+
organizationId: Uuid;
|
|
8229
|
+
realtime?: RecordsRealtimePort;
|
|
8230
|
+
onError?: RecordsErrorSink;
|
|
8231
|
+
resolver?: RecordsResolverPort;
|
|
8232
|
+
/**
|
|
8233
|
+
* The schema the record store lives in. Exists so a rehearsal branch and
|
|
8234
|
+
* production can differ without a fork; it is `custom` everywhere today.
|
|
8235
|
+
*/
|
|
8236
|
+
schema?: string;
|
|
8237
|
+
}
|
|
8238
|
+
|
|
8239
|
+
/**
|
|
8240
|
+
* REL-6. Whether Visibility flows along this relation and the MAXIMUM access
|
|
8241
|
+
* level it carries. Default off on `referenced`, on for `owned`.
|
|
8242
|
+
*/
|
|
8243
|
+
interface RelationCarries {
|
|
8244
|
+
carries: boolean;
|
|
8245
|
+
/** The ceiling — a relation never carries more access than this. */
|
|
8246
|
+
max_access: string | null;
|
|
8247
|
+
}
|
|
8248
|
+
/** The seven properties, each its own question. */
|
|
8249
|
+
interface RelationProperties {
|
|
8250
|
+
/** REL-1. Stored once on the contained table, read from the field's side. */
|
|
8251
|
+
flavor: RelationFlavor;
|
|
8252
|
+
/** REL-2. Separate from flavour. */
|
|
8253
|
+
on_delete: OnDelete;
|
|
8254
|
+
/** REL-3. A snapshot is a frozen copy in the relation's payload — never a pointer into History. */
|
|
8255
|
+
binding: RelationBinding;
|
|
8256
|
+
/** REL-4. */
|
|
8257
|
+
ordered: boolean;
|
|
8258
|
+
/** REL-5. */
|
|
8259
|
+
loops: "allowed" | "refused";
|
|
8260
|
+
/** REL-6. */
|
|
8261
|
+
carries: RelationCarries;
|
|
8262
|
+
/** REL-7. */
|
|
8263
|
+
cardinality: RelationCardinality;
|
|
8264
|
+
}
|
|
8265
|
+
/**
|
|
8266
|
+
* REL-8 / REL-N-1. A target is a REFERENCE, written that way from the first
|
|
8267
|
+
* line of code, because it may name a row outside our database. One Table,
|
|
8268
|
+
* several, or any — polymorphic without restriction. External targets are
|
|
8269
|
+
* read-only in v1.
|
|
8270
|
+
*/
|
|
8271
|
+
type RelationTarget = {
|
|
8272
|
+
kind: "ours";
|
|
8273
|
+
entity_token: string;
|
|
8274
|
+
row_id: Uuid;
|
|
8275
|
+
} | {
|
|
8276
|
+
kind: "external";
|
|
7533
8277
|
connection_token: string;
|
|
7534
8278
|
external_table: string;
|
|
7535
8279
|
external_key: string;
|
|
@@ -7599,6 +8343,53 @@ type RelationWordsManyArgs = {
|
|
|
7599
8343
|
display?: RelationDisplaySpec | null;
|
|
7600
8344
|
record_ids: Uuid[];
|
|
7601
8345
|
};
|
|
8346
|
+
/** One reference as the store keeps it. */
|
|
8347
|
+
interface EntityRef {
|
|
8348
|
+
/** The `platform.entity_types` token: `note`, `web_site`, `agent` … */
|
|
8349
|
+
token: string;
|
|
8350
|
+
id: Uuid;
|
|
8351
|
+
}
|
|
8352
|
+
/** One reference as a read door answers it. */
|
|
8353
|
+
interface EntityRefWithWords extends EntityRef {
|
|
8354
|
+
/**
|
|
8355
|
+
* The thing's own title — or the store's withheld sentence when the reader
|
|
8356
|
+
* may not open it; `null` when the kind names no title.
|
|
8357
|
+
*/
|
|
8358
|
+
label: string | null;
|
|
8359
|
+
}
|
|
8360
|
+
/** One kind of platform thing a record may point at (`custom.entity_reference_kinds`). */
|
|
8361
|
+
interface EntityReferenceKind {
|
|
8362
|
+
token: string;
|
|
8363
|
+
/** What a person reads: "Note", "Site", "Agent". */
|
|
8364
|
+
label: string;
|
|
8365
|
+
/** The picker's grouping: the admin-assigned reference category, else the schema. */
|
|
8366
|
+
category: string;
|
|
8367
|
+
}
|
|
8368
|
+
/**
|
|
8369
|
+
* The references a cell holds, whichever shape it arrived in — one object, a
|
|
8370
|
+
* list, or what a read door rendered (with labels). Anything that is not a
|
|
8371
|
+
* reference is left out, never guessed at.
|
|
8372
|
+
*/
|
|
8373
|
+
declare function entityRefsOf(value: unknown): EntityRefWithWords[];
|
|
8374
|
+
/**
|
|
8375
|
+
* What to WRITE for an entity-reference cell: `{token, id}` only, each thing
|
|
8376
|
+
* once, first mention first — the label a read door added is dropped, because
|
|
8377
|
+
* the store reads it and never keeps it (REL-14). A single-valued column gets
|
|
8378
|
+
* the one object (or `null`), a multi-valued one the list.
|
|
8379
|
+
*/
|
|
8380
|
+
declare function entityRefsToWrite(value: unknown, multi: boolean): EntityRef | EntityRef[] | null;
|
|
8381
|
+
/**
|
|
8382
|
+
* The kinds of platform thing a record may point at — what the field editor's
|
|
8383
|
+
* kind picker lists. `custom.entity_reference_kinds()`.
|
|
8384
|
+
*/
|
|
8385
|
+
declare function entityReferenceKinds(source: RecordsDataSource): Promise<RecordsResult<EntityReferenceKind[]>>;
|
|
8386
|
+
/**
|
|
8387
|
+
* THE WORDS HELPER. The words of each `{token, id}` for a picker or a chip
|
|
8388
|
+
* before anything is saved — each label read by the store for THIS person and
|
|
8389
|
+
* withheld when they may not open the thing. `custom.entity_reference_words`.
|
|
8390
|
+
* A saved cell needs no call: every read door already answers its labels.
|
|
8391
|
+
*/
|
|
8392
|
+
declare function entityReferenceWords(source: RecordsDataSource, organizationId: Uuid, refs: readonly EntityRef[]): Promise<RecordsResult<EntityRefWithWords[]>>;
|
|
7602
8393
|
|
|
7603
8394
|
/**
|
|
7604
8395
|
* DYN-14 / DYN-15. An ordered list of merge fields ENDING IN A LITERAL, or the
|
|
@@ -7906,6 +8697,34 @@ interface WorkApprovalDecision {
|
|
|
7906
8697
|
version: number | null;
|
|
7907
8698
|
message: string;
|
|
7908
8699
|
}
|
|
8700
|
+
/** One inbox decision of a batch (`custom.work_decide_many`). */
|
|
8701
|
+
interface WorkDecideManyItem {
|
|
8702
|
+
/** The inbox item — a `work_approval` record's id (`WorkInboxItem.item_id`). */
|
|
8703
|
+
item: Uuid;
|
|
8704
|
+
decision: "approve" | "decline";
|
|
8705
|
+
note?: string | null;
|
|
8706
|
+
}
|
|
8707
|
+
type WorkDecideVerdict = "approved" | "declined" | "already_decided" | "no_right" | "refused";
|
|
8708
|
+
interface WorkDecideManyResult {
|
|
8709
|
+
index: number;
|
|
8710
|
+
item: Uuid;
|
|
8711
|
+
decision: "approve" | "decline";
|
|
8712
|
+
verdict: WorkDecideVerdict;
|
|
8713
|
+
/** The store's own sentence: what was applied, or why it was not. */
|
|
8714
|
+
sentence: string;
|
|
8715
|
+
subject_id?: Uuid;
|
|
8716
|
+
version?: number | null;
|
|
8717
|
+
record_ids?: Uuid[];
|
|
8718
|
+
code?: string;
|
|
8719
|
+
}
|
|
8720
|
+
/** What `custom.work_decide_many` answers: the counts, then one verdict per item in order. */
|
|
8721
|
+
interface WorkDecideMany {
|
|
8722
|
+
asked: number;
|
|
8723
|
+
approved: number;
|
|
8724
|
+
declined: number;
|
|
8725
|
+
not_decided: number;
|
|
8726
|
+
results: WorkDecideManyResult[];
|
|
8727
|
+
}
|
|
7909
8728
|
/** What `custom.work_assign` answers: the value, the access, and who holds it now. */
|
|
7910
8729
|
interface WorkAssignment {
|
|
7911
8730
|
record_id: Uuid;
|
|
@@ -8154,167 +8973,6 @@ interface ResolvedPublishBinding {
|
|
|
8154
8973
|
notice: string;
|
|
8155
8974
|
}
|
|
8156
8975
|
|
|
8157
|
-
/**
|
|
8158
|
-
* The data seam: a structural subset of `SupabaseClient`. The package never
|
|
8159
|
-
* opens a database connection of its own and never holds a key — the HOST
|
|
8160
|
-
* supplies a client that already carries the operating person's session, which
|
|
8161
|
-
* is what makes DOOR-5 and AGT-N-4 true (the store sees the person, not us).
|
|
8162
|
-
*/
|
|
8163
|
-
interface RecordsDataSource {
|
|
8164
|
-
/**
|
|
8165
|
-
* Call a door. The name is always a door the live catalogue has; `/core`
|
|
8166
|
-
* refuses `door_absent` before it ever reaches here for one that does not.
|
|
8167
|
-
*/
|
|
8168
|
-
rpc(fn: string, args: Record<string, unknown>,
|
|
8169
|
-
/**
|
|
8170
|
-
* THE SCHEMA THE DOOR LIVES IN, always supplied: `custom` for the store's
|
|
8171
|
-
* own doors, `iam` for the trust doors (the external principal and the
|
|
8172
|
-
* publish binding, which are the PLATFORM's). A host binding supabase-js
|
|
8173
|
-
* routes this to `client.schema(options.schema).rpc(fn, args)`; a host that
|
|
8174
|
-
* ignores it calls its own default PostgREST profile — `public` — and is
|
|
8175
|
-
* refused by name, which is the failure we want rather than a silent answer
|
|
8176
|
-
* from the wrong system. (Before 2026-09-18 this was described as "only ever
|
|
8177
|
-
* `iam`" and the store's doors went unqualified; the extension's first real
|
|
8178
|
-
* turn proved that asks `public.store_is_open` and finds nothing.)
|
|
8179
|
-
*/
|
|
8180
|
-
options?: {
|
|
8181
|
-
schema?: string;
|
|
8182
|
-
}): PromiseLike<{
|
|
8183
|
-
data: unknown;
|
|
8184
|
-
error: PgError | null;
|
|
8185
|
-
}>;
|
|
8186
|
-
/** Reads of `custom.*` go through the schema-qualified builder, never a bare `from`. */
|
|
8187
|
-
schema(name: string): {
|
|
8188
|
-
from(table: string): RecordsTableQuery;
|
|
8189
|
-
};
|
|
8190
|
-
}
|
|
8191
|
-
/** The read surface the list and query paths use. A real supabase-js client satisfies it. */
|
|
8192
|
-
interface RecordsTableQuery {
|
|
8193
|
-
select(columns: string, options?: {
|
|
8194
|
-
count?: "exact" | "planned" | "estimated";
|
|
8195
|
-
head?: boolean;
|
|
8196
|
-
}): RecordsFilter;
|
|
8197
|
-
}
|
|
8198
|
-
interface RecordsFilter extends PromiseLike<RecordsResponse> {
|
|
8199
|
-
eq(column: string, value: unknown): RecordsFilter;
|
|
8200
|
-
neq(column: string, value: unknown): RecordsFilter;
|
|
8201
|
-
in(column: string, values: readonly unknown[]): RecordsFilter;
|
|
8202
|
-
is(column: string, value: null | boolean): RecordsFilter;
|
|
8203
|
-
gte(column: string, value: unknown): RecordsFilter;
|
|
8204
|
-
lte(column: string, value: unknown): RecordsFilter;
|
|
8205
|
-
order(column: string, options?: {
|
|
8206
|
-
ascending?: boolean;
|
|
8207
|
-
}): RecordsFilter;
|
|
8208
|
-
range(from: number, to: number): RecordsFilter;
|
|
8209
|
-
limit(count: number): RecordsFilter;
|
|
8210
|
-
}
|
|
8211
|
-
interface RecordsResponse {
|
|
8212
|
-
data: unknown;
|
|
8213
|
-
error: PgError | null;
|
|
8214
|
-
count?: number | null;
|
|
8215
|
-
}
|
|
8216
|
-
/**
|
|
8217
|
-
* WHO IS ACTING. AGT-N-4: an agent carries the exact authority of the person
|
|
8218
|
-
* operating it — there is no agent identity and there are no service roles. So
|
|
8219
|
-
* the actor word and the person are two separate facts, and `on_behalf_of` is
|
|
8220
|
-
* meaningful only when the actor is `agent`.
|
|
8221
|
-
*/
|
|
8222
|
-
interface RecordsActor {
|
|
8223
|
-
actor: Actor;
|
|
8224
|
-
/** The signed-in person. The store reads this from the session, not from us; this is for the client's own mirror. */
|
|
8225
|
-
user_id?: Uuid;
|
|
8226
|
-
/** Only an agent acts on behalf of a person (the store refuses it otherwise). */
|
|
8227
|
-
on_behalf_of?: Uuid;
|
|
8228
|
-
}
|
|
8229
|
-
/**
|
|
8230
|
-
* OPTIONAL. A live-updates seam. The default degradation is stated rather than
|
|
8231
|
-
* silent: with no port bound, `useRecords` reports `live: false` and the screen
|
|
8232
|
-
* can say "not live" instead of quietly going stale.
|
|
8233
|
-
*
|
|
8234
|
-
* A host binds this with `@ai-matrx/data/react`'s channel hygiene — the package
|
|
8235
|
-
* deliberately does NOT depend on it, so the headless core stays free of a
|
|
8236
|
-
* realtime client and a host that has one keeps using the one it already has.
|
|
8237
|
-
*/
|
|
8238
|
-
interface RecordsRealtimePort {
|
|
8239
|
-
/**
|
|
8240
|
-
* Watch one organization's records of one table. Returns an unsubscribe.
|
|
8241
|
-
*
|
|
8242
|
-
* THE HOST NUDGES THROUGH THIS SINK AND REACHES AROUND NOTHING. Until 0.43.0 the callback
|
|
8243
|
-
* was `(recordId: Uuid) => void` and a host that also wanted to say "the SHAPE moved"
|
|
8244
|
-
* imported `tableShapeChanged` from `@ai-matrx/records/react` and called it directly —
|
|
8245
|
-
* which worked, and which meant the port contract did not describe half of what a port
|
|
8246
|
-
* actually does. A column appearing is not a row changing, and the package owns the
|
|
8247
|
-
* difference.
|
|
8248
|
-
*
|
|
8249
|
-
* NOTHING THAT ARRIVES HERE IS DATA. A nudge has not passed the read door, so the hook
|
|
8250
|
-
* re-reads — by id set when the nudge names ids, whole-page when it cannot.
|
|
8251
|
-
*/
|
|
8252
|
-
subscribeRecords(args: {
|
|
8253
|
-
organization_id: Uuid;
|
|
8254
|
-
table_id: Uuid;
|
|
8255
|
-
}, sink: RecordsChangeSink): () => void;
|
|
8256
|
-
}
|
|
8257
|
-
/** What a realtime port may tell the package. Two calls, because a column is not a row. */
|
|
8258
|
-
interface RecordsChangeSink {
|
|
8259
|
-
/**
|
|
8260
|
-
* THESE RECORDS MOVED. `null` means "I cannot tell you which" — a reconnect, a tab wake, or
|
|
8261
|
-
* a change above the store's own id cap — and is the one case that costs a whole-page read.
|
|
8262
|
-
* An EMPTY array is not the same thing and is not a nudge at all.
|
|
8263
|
-
*/
|
|
8264
|
-
records(ids: readonly Uuid[] | null): void;
|
|
8265
|
-
/**
|
|
8266
|
-
* THIS TABLE'S SHAPE MOVED — a column added, retired or changed. Re-reading the rows would
|
|
8267
|
-
* redraw the same table without the new column in it, which is a screen that is out of date
|
|
8268
|
-
* while looking healthy.
|
|
8269
|
-
*/
|
|
8270
|
-
shape(): void;
|
|
8271
|
-
}
|
|
8272
|
-
/**
|
|
8273
|
-
* OPTIONAL. Where a refusal that nobody asked about goes — the loud funnel.
|
|
8274
|
-
* Default degradation: `console.error` with the store's own words, never
|
|
8275
|
-
* silence.
|
|
8276
|
-
*/
|
|
8277
|
-
type RecordsErrorSink = (error: {
|
|
8278
|
-
code: string;
|
|
8279
|
-
message: string;
|
|
8280
|
-
hint?: string;
|
|
8281
|
-
where: string;
|
|
8282
|
-
}) => void;
|
|
8283
|
-
/**
|
|
8284
|
-
* OPTIONAL. The merge-field resolver's server half (`W5-MERGE-B`). While it is
|
|
8285
|
-
* not bound, `useMergeField` answers `pending` WITH THE REASON — never a blank,
|
|
8286
|
-
* never a literal placeholder left in the text (DYN-14).
|
|
8287
|
-
*/
|
|
8288
|
-
interface RecordsResolverPort {
|
|
8289
|
-
resolve(args: {
|
|
8290
|
-
organization_id: Uuid;
|
|
8291
|
-
merge_field_keys: string[];
|
|
8292
|
-
/** The live selection the `state` source reads (DYNAMIC-VALUES §C). */
|
|
8293
|
-
state?: Record<string, unknown>;
|
|
8294
|
-
}): Promise<unknown>;
|
|
8295
|
-
}
|
|
8296
|
-
/** The one config a host binds. */
|
|
8297
|
-
interface RecordsConfig {
|
|
8298
|
-
/** REQUIRED. */
|
|
8299
|
-
dataSource: RecordsDataSource;
|
|
8300
|
-
/** REQUIRED. */
|
|
8301
|
-
actor: RecordsActor;
|
|
8302
|
-
/**
|
|
8303
|
-
* REQUIRED. REC-29: organizations are hard walls, and the store is keyed
|
|
8304
|
-
* `(organization_id, id)`. There is no "current organization" this package
|
|
8305
|
-
* discovers for itself — the host says which one, every time.
|
|
8306
|
-
*/
|
|
8307
|
-
organizationId: Uuid;
|
|
8308
|
-
realtime?: RecordsRealtimePort;
|
|
8309
|
-
onError?: RecordsErrorSink;
|
|
8310
|
-
resolver?: RecordsResolverPort;
|
|
8311
|
-
/**
|
|
8312
|
-
* The schema the record store lives in. Exists so a rehearsal branch and
|
|
8313
|
-
* production can differ without a fork; it is `custom` everywhere today.
|
|
8314
|
-
*/
|
|
8315
|
-
schema?: string;
|
|
8316
|
-
}
|
|
8317
|
-
|
|
8318
8976
|
/** One value the agent was given, with the triple that makes it citable. */
|
|
8319
8977
|
interface RecordScopeField {
|
|
8320
8978
|
key: string;
|
|
@@ -8601,7 +9259,7 @@ interface RecordsClient {
|
|
|
8601
9259
|
* `recordAggregate` counts with, so the rows a drill-through opens are the
|
|
8602
9260
|
* rows the number on the dashboard counted.
|
|
8603
9261
|
*/
|
|
8604
|
-
filter?:
|
|
9262
|
+
filter?: StoreFilter;
|
|
8605
9263
|
limit?: number;
|
|
8606
9264
|
offset?: number;
|
|
8607
9265
|
}): Promise<RecordsResult<{
|
|
@@ -8809,6 +9467,12 @@ interface RecordsClient {
|
|
|
8809
9467
|
pipelineBoard(args: {
|
|
8810
9468
|
table_id: Uuid;
|
|
8811
9469
|
measure?: string | null;
|
|
9470
|
+
/**
|
|
9471
|
+
* S2-PRIME — the view's question, either shape (`StoreFilter`). Given, the headings count and
|
|
9472
|
+
* total exactly the cards the same filter puts on the board (`custom.pipeline_board`'s
|
|
9473
|
+
* four-argument door); left out, the whole table this person may see, as before.
|
|
9474
|
+
*/
|
|
9475
|
+
filter?: StoreFilter | null;
|
|
8812
9476
|
}): Promise<RecordsResult<PipelineColumn[]>>;
|
|
8813
9477
|
/** Whether this card may go to that column — asked BEFORE the finger lets go. */
|
|
8814
9478
|
pipelineTransitionRefusal(args: {
|
|
@@ -8829,6 +9493,16 @@ interface RecordsClient {
|
|
|
8829
9493
|
also?: Record<string, unknown>;
|
|
8830
9494
|
expected_version?: number | null;
|
|
8831
9495
|
}): Promise<RecordsResult<PipelineMoveResult>>;
|
|
9496
|
+
/**
|
|
9497
|
+
* MOVE MANY CARDS IN ONE CALL (lane S4, `custom.pipeline_move_many`). Each card is judged by
|
|
9498
|
+
* `pipeline_move` exactly as one is, in its own savepoint: a refused card writes nothing and the
|
|
9499
|
+
* others still land. `expected_version` is required per card — a card that changed since the
|
|
9500
|
+
* board loaded answers `changed_since_loaded` and is never overwritten. A refusal of the WHOLE
|
|
9501
|
+
* call (a stranger, an empty batch, more than the `custom/batch_items_max` knob) is the error.
|
|
9502
|
+
*/
|
|
9503
|
+
pipelineMoveMany(args: {
|
|
9504
|
+
moves: PipelineMoveManyItem[];
|
|
9505
|
+
}): Promise<RecordsResult<PipelineMoveMany>>;
|
|
8832
9506
|
/** Declare (or re-state) a pipeline: the stage column and its transition Rules. */
|
|
8833
9507
|
pipelineDeclare(args: {
|
|
8834
9508
|
table_id: Uuid;
|
|
@@ -8871,9 +9545,25 @@ interface RecordsClient {
|
|
|
8871
9545
|
stage: string;
|
|
8872
9546
|
gate: PipelineGate | Record<string, unknown>;
|
|
8873
9547
|
}): Promise<RecordsResult<PipelineGatePreview>>;
|
|
9548
|
+
/**
|
|
9549
|
+
* SERVER LANE ONLY. `custom.rule_members` walks the whole scope table through the evaluator and
|
|
9550
|
+
* returns STORED rows — no visibility ladder, no masking — so no browser role holds EXECUTE on it
|
|
9551
|
+
* and it answers 42501 from a signed-in seat. A screen reads a Rule's members through
|
|
9552
|
+
* `ruleMembersVisible`.
|
|
9553
|
+
*/
|
|
8874
9554
|
ruleMembers(args: {
|
|
8875
9555
|
rule_id: Uuid;
|
|
8876
9556
|
}): Promise<RecordsResult<StoredRecord[]>>;
|
|
9557
|
+
/**
|
|
9558
|
+
* S2-PRIME — THE MEMBERS OF A MEMBERSHIP RULE THIS PERSON MAY SEE, a page at a time
|
|
9559
|
+
* (`custom.rule_members_visible`): the list door asked the Rule's own test, so the rows are the
|
|
9560
|
+
* read door's — the same ladder, masked documents, the same page ceiling.
|
|
9561
|
+
*/
|
|
9562
|
+
ruleMembersVisible(args: {
|
|
9563
|
+
rule_id: Uuid;
|
|
9564
|
+
limit?: number;
|
|
9565
|
+
offset?: number;
|
|
9566
|
+
}): Promise<RecordsResult<ReadRow[]>>;
|
|
8877
9567
|
/** Is this one record a member, and WHY — the store's own answer. */
|
|
8878
9568
|
ruleMembership(args: {
|
|
8879
9569
|
rule_id: Uuid;
|
|
@@ -8951,6 +9641,22 @@ interface RecordsClient {
|
|
|
8951
9641
|
form_id?: Uuid | null;
|
|
8952
9642
|
slug?: string | null;
|
|
8953
9643
|
}): Promise<RecordsResult<Uuid>>;
|
|
9644
|
+
/**
|
|
9645
|
+
* WHICH OF A FORM'S QUESTIONS ARE ASKED, given the answers so far — for the OWNER's preview of
|
|
9646
|
+
* a draft (`custom.form_preview_asks`). One row per question in order; `asked` is false only
|
|
9647
|
+
* when the store's own Rule said so. Undecided and unworkable conditions are asked, the second
|
|
9648
|
+
* with the store's sentence in `said`.
|
|
9649
|
+
*/
|
|
9650
|
+
formPreviewAsks(args: {
|
|
9651
|
+
table_id: Uuid;
|
|
9652
|
+
questions: unknown[];
|
|
9653
|
+
values: Record<string, unknown>;
|
|
9654
|
+
}): Promise<RecordsResult<Array<{
|
|
9655
|
+
field_key: string;
|
|
9656
|
+
asked: boolean;
|
|
9657
|
+
decided: boolean;
|
|
9658
|
+
said: string | null;
|
|
9659
|
+
}>>>;
|
|
8954
9660
|
/**
|
|
8955
9661
|
* What the store makes of a file's columns, before anything is written.
|
|
8956
9662
|
* `columns` is `[{header, samples}]` — the first page of the file is plenty.
|
|
@@ -9114,7 +9820,35 @@ interface RecordsClient {
|
|
|
9114
9820
|
portal_id?: Uuid | null;
|
|
9115
9821
|
slug?: string | null;
|
|
9116
9822
|
sign_in_method?: string | null;
|
|
9823
|
+
/**
|
|
9824
|
+
* S6 — the portal's own look and its forms. A key given REPLACES that key; a key not given
|
|
9825
|
+
* is KEPT (leave `config` out and both stay exactly as they are). The store judges it and
|
|
9826
|
+
* refuses by name: a logo that is not a public picture of this organization's Files, an
|
|
9827
|
+
* accent that is not a design-system colour name, a form whose Table the portal does not show.
|
|
9828
|
+
*/
|
|
9829
|
+
config?: PortalConfigInput | null;
|
|
9117
9830
|
}): Promise<RecordsResult<Uuid>>;
|
|
9831
|
+
/**
|
|
9832
|
+
* S6 — THE CLIENT'S SIDE: one form of HER portal (`custom.portal_form`). Refused unless the
|
|
9833
|
+
* caller is a live principal of that live portal and the form is on its list; the Field that
|
|
9834
|
+
* names the client is never one of the questions — the portal fills it.
|
|
9835
|
+
*/
|
|
9836
|
+
portalForm(args: {
|
|
9837
|
+
portal_id: Uuid;
|
|
9838
|
+
form_id: Uuid;
|
|
9839
|
+
}): Promise<RecordsResult<PortalFormSpec>>;
|
|
9840
|
+
/**
|
|
9841
|
+
* S6 — send one form of her portal (`custom.portal_form_submit`). The store fills the Field
|
|
9842
|
+
* that names the client with her own record, and the answer reaches her own list at once
|
|
9843
|
+
* (`accepted`) or waits for the office (`held`, with the store's sentence). `client_key`
|
|
9844
|
+
* makes a retry the same submission.
|
|
9845
|
+
*/
|
|
9846
|
+
portalFormSubmit(args: {
|
|
9847
|
+
portal_id: Uuid;
|
|
9848
|
+
form_id: Uuid;
|
|
9849
|
+
answers: Record<string, unknown>;
|
|
9850
|
+
client_key?: string | null;
|
|
9851
|
+
}): Promise<RecordsResult<PortalFormAnswer>>;
|
|
9118
9852
|
/**
|
|
9119
9853
|
* Invite one person, as one record of the portal's client Table.
|
|
9120
9854
|
*
|
|
@@ -9170,6 +9904,14 @@ interface RecordsClient {
|
|
|
9170
9904
|
dashboardRun(args: {
|
|
9171
9905
|
dashboard_id: Uuid;
|
|
9172
9906
|
filter?: RecordFilter;
|
|
9907
|
+
/**
|
|
9908
|
+
* S3 — compare every block that does not carry its own comparison (the
|
|
9909
|
+
* block's own wins, as its own filter does). A block with no date to
|
|
9910
|
+
* compare along answers alone and says so in `compare_refused`.
|
|
9911
|
+
*/
|
|
9912
|
+
compare?: AggregateCompare | null;
|
|
9913
|
+
/** S3 — re-cut every bucketed block to one date grain (the canvas's picker). */
|
|
9914
|
+
grain?: AggregateBucket | null;
|
|
9173
9915
|
}): Promise<RecordsResult<DashboardRunResult>>;
|
|
9174
9916
|
/** The seventh block kind on its own: records that have sat on the same value too long. */
|
|
9175
9917
|
dashboardStuck(args: {
|
|
@@ -9295,8 +10037,15 @@ interface RecordsClient {
|
|
|
9295
10037
|
* A scalar is an equality and an object is a half-open moment window, and
|
|
9296
10038
|
* either way it lands in the SAME WHERE as visibility.
|
|
9297
10039
|
*/
|
|
9298
|
-
filter?:
|
|
10040
|
+
filter?: StoreFilter;
|
|
9299
10041
|
limit?: number;
|
|
10042
|
+
/**
|
|
10043
|
+
* S3 — answer the same question over a prior window too (previous period,
|
|
10044
|
+
* same period last year, or a fixed baseline). Each row then carries
|
|
10045
|
+
* `prior_measures`, `delta` and the two `compare` windows. Buckets are cut
|
|
10046
|
+
* in the organization's calendar (knobs `custom/time_zone`, `custom/week_start`).
|
|
10047
|
+
*/
|
|
10048
|
+
compare?: AggregateCompare | null;
|
|
9300
10049
|
}): Promise<RecordsResult<AggregateRow[]>>;
|
|
9301
10050
|
/** The measures the store itself offers. Asked, never hardcoded in a picker. */
|
|
9302
10051
|
aggOperations(): Promise<RecordsResult<string[]>>;
|
|
@@ -9832,6 +10581,15 @@ interface RecordsClient {
|
|
|
9832
10581
|
approve: boolean;
|
|
9833
10582
|
note?: string | null;
|
|
9834
10583
|
}): Promise<RecordsResult<WorkApprovalDecision>>;
|
|
10584
|
+
/**
|
|
10585
|
+
* DECIDE MANY INBOX ITEMS IN ONE CALL (lane S4, `custom.work_decide_many`). Each is judged by
|
|
10586
|
+
* `work_approval_decide` exactly as one is, in its own savepoint: a refused decision leaves that
|
|
10587
|
+
* item waiting and the others still stand. Verdicts: approved, declined, already_decided,
|
|
10588
|
+
* no_right, refused — each with the store's own sentence.
|
|
10589
|
+
*/
|
|
10590
|
+
workDecideMany(args: {
|
|
10591
|
+
decisions: WorkDecideManyItem[];
|
|
10592
|
+
}): Promise<RecordsResult<WorkDecideMany>>;
|
|
9835
10593
|
/** One waiting change in full, for the person deciding it or the one who asked. */
|
|
9836
10594
|
workApprovalRead(args: {
|
|
9837
10595
|
approval_id: Uuid;
|
|
@@ -9987,6 +10745,61 @@ interface RecordsClient {
|
|
|
9987
10745
|
limit?: number;
|
|
9988
10746
|
}): Promise<RecordsResult<IoExportPage>>;
|
|
9989
10747
|
/** G5. That page as an .xlsx; a withheld column is named on its own sheet. */
|
|
10748
|
+
/** G9. Every table a picker may offer here, from BOTH stores, each saying which store opens it. */
|
|
10749
|
+
tableListEverywhere(): Promise<RecordsResult<{
|
|
10750
|
+
success: boolean;
|
|
10751
|
+
tables: TableListEntry[];
|
|
10752
|
+
}>>;
|
|
10753
|
+
/**
|
|
10754
|
+
* G10. Refresh a synced source (a sheet tab) into ONE Table under `home_id`: new rows added,
|
|
10755
|
+
* changed rows updated, rows the source dropped archived — never destroyed; columns the
|
|
10756
|
+
* person added in Matrx survive. Build the spec with `sheetSyncSpec`.
|
|
10757
|
+
*/
|
|
10758
|
+
tableSync(args: {
|
|
10759
|
+
home_id: Uuid;
|
|
10760
|
+
spec: TableSyncSpec;
|
|
10761
|
+
}): Promise<RecordsResult<TableSyncResult>>;
|
|
10762
|
+
/**
|
|
10763
|
+
* G11. The record-store Table a context scope's template-bound item provisions — one per item
|
|
10764
|
+
* and scope. A scope provisioned before the move answers with its moved Table (same id); the
|
|
10765
|
+
* Home defaults to the organization's own.
|
|
10766
|
+
*/
|
|
10767
|
+
scopeTableProvision(args: {
|
|
10768
|
+
item_id: Uuid;
|
|
10769
|
+
scope_id: Uuid;
|
|
10770
|
+
home_id?: Uuid | null;
|
|
10771
|
+
}): Promise<RecordsResult<Uuid>>;
|
|
10772
|
+
/** G12. The rows of each Table this reader may see, in one call (fold with `withRowCounts`). A Table she may not know gets no row. */
|
|
10773
|
+
tableRowCounts(args: {
|
|
10774
|
+
table_ids: Uuid[];
|
|
10775
|
+
}): Promise<RecordsResult<TableRowCount[]>>;
|
|
10776
|
+
/** G12. Each live record's own header (created, updated, version) that the read door does not answer. */
|
|
10777
|
+
recordHeaders(args: {
|
|
10778
|
+
ids: Uuid[];
|
|
10779
|
+
}): Promise<RecordsResult<RecordHeader[]>>;
|
|
10780
|
+
/**
|
|
10781
|
+
* G14. Share a Table with a person by email or account id: an existing account outside the
|
|
10782
|
+
* organization is granted at once and notified (never made a member); an address with no
|
|
10783
|
+
* account is invited. The organization's outside-sharing setting decides first.
|
|
10784
|
+
*/
|
|
10785
|
+
tableShareOutsideGrant(args: {
|
|
10786
|
+
table_id: Uuid;
|
|
10787
|
+
person: string;
|
|
10788
|
+
level?: "viewer" | "commenter" | "editor" | "admin";
|
|
10789
|
+
}): Promise<RecordsResult<OutsideShareAnswer>>;
|
|
10790
|
+
/** G13. Keep a hand-set order on a saved view: the named rows first, in this order (build it with `moveInOrder`). */
|
|
10791
|
+
viewRecordOrderSet(args: {
|
|
10792
|
+
view_id: Uuid;
|
|
10793
|
+
record_ids: Uuid[];
|
|
10794
|
+
}): Promise<RecordsResult<ViewOrderSet>>;
|
|
10795
|
+
/** G13. A page of a hand-ordered view: placed rows by position, then the rest by created time. */
|
|
10796
|
+
readInViewOrder(args: {
|
|
10797
|
+
view_id: Uuid;
|
|
10798
|
+
limit?: number;
|
|
10799
|
+
offset?: number;
|
|
10800
|
+
}): Promise<RecordsResult<Array<ReadRow & {
|
|
10801
|
+
position: number | null;
|
|
10802
|
+
}>>>;
|
|
9990
10803
|
exportXlsx(args: {
|
|
9991
10804
|
table_id: Uuid;
|
|
9992
10805
|
columns?: string[] | null;
|
|
@@ -10142,7 +10955,7 @@ interface UseRecordsOptions {
|
|
|
10142
10955
|
* This is what makes a dashboard number walkable: the same object that
|
|
10143
10956
|
* counted it opens it.
|
|
10144
10957
|
*/
|
|
10145
|
-
filter?:
|
|
10958
|
+
filter?: StoreFilter;
|
|
10146
10959
|
}
|
|
10147
10960
|
interface UseRecordsState extends Async<{
|
|
10148
10961
|
rows: ReadRow[];
|
|
@@ -10346,4 +11159,15 @@ declare function useFieldMutation(): UseFieldMutation;
|
|
|
10346
11159
|
*/
|
|
10347
11160
|
declare function useMergeField(key: string | null, state?: Record<string, unknown>): MergeFieldResolution | null;
|
|
10348
11161
|
|
|
10349
|
-
|
|
11162
|
+
interface EntityReferenceRead<T> {
|
|
11163
|
+
data: T | null;
|
|
11164
|
+
loading: boolean;
|
|
11165
|
+
/** The store's own refusal, verbatim. */
|
|
11166
|
+
error: RecordsError | null;
|
|
11167
|
+
}
|
|
11168
|
+
/** The kinds of platform thing a record may point at, for the kind picker. */
|
|
11169
|
+
declare function useEntityReferenceKinds(): EntityReferenceRead<EntityReferenceKind[]>;
|
|
11170
|
+
/** The words of each reference, read for THIS person (withheld where they may not open it). */
|
|
11171
|
+
declare function useEntityReferenceWords(refs: readonly EntityRef[]): EntityReferenceRead<EntityRefWithWords[]>;
|
|
11172
|
+
|
|
11173
|
+
export { ABSENCE_REASONS, ACTOR_VOCABULARY, ARCHIVE_LANES, ARCHIVE_LANE_LABEL, ARCHIVE_LANE_MEANS, type AbsenceReason, type ActionRefusal, type ActionRunResult, type 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, COMPUTE_ON, CONTEXT_POLICIES, 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 ComputeOn, type ContextPolicy, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DECLARABLE_FIELD_KINDS, DEFAULT_ARCHIVE_LANE, DEFAULT_PORTAL_ARCHIVE_FILTER, DELIVERIES, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type DashboardTarget, type DashboardTargetBase, type DashboardTargetOp, type DashboardTargetResult, type DashboardTotals, type DeclarableFieldKind, type DecorationColor, type DecorationPath, type DecorationRule, type DecorationRuleOp, type DecorationTarget, type Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, 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 EntityReferenceRead, type EntityTableFacts, type EntityToken, type ExampleBuilt, type ExampleSpec, type ExternalPrincipalCard, FIELD_KINDS, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldHistoryEntry, type FieldKind, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type FieldTypeWord, type ForbiddenEnvelopeWord, type FormSummary, type FormulaParse, type Freshness, type GridLayout, type GridLayoutMode, type GridRowHeight, type HiddenFieldNotice, 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, KERNEL_TABLES, type KernelTableName, type KernelTargets, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OutsideShareAnswer, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, PIPELINE_RULE_KINDS, PORTAL_ACCENTS, PORTAL_ARCHIVE_FILTERS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type 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 PredictedRefusal, type ProvenancePointer, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordChangeAction, type RecordComment, type RecordDocument, type RecordEvent, type RecordFilter, type RecordGraphWritten, type RecordHeader, type RecordHistoryEntry, type RecordRead, type RecordRevision, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, RecordsProvider, type RecordsProviderProps, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplay, type RelationDisplaySpec, type RelationFlavor, type RelationProperties, type RelationStore, type RelationTarget, type RelationWordsManyArgs, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RetiredActorWord, type RowAction, type RowActionStep, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreFilter, type StoreRefusalCode, type StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableArchiveProgress, type TableCapacity, type TableDecorations, type TableDisplay, type TableListEntry, type TableOrigin, type TablePlacement, type TablePlacementFact, type TableProposal, type TableRowCount, type TableSyncResult, type TableSyncSource, type TableSyncSpec, type TableType, type TableWebhook, type TableWebhookDeclared, type Timestamp, type UseEntityFieldMutation, type UseFieldMutation, type UseRecordMutation, type UseRecordsOptions, type UseRecordsState, type UseTableArchive, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, 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, type WriteConflict, actionRefusals, allowsOtherValues, archivedByLine, archivedWhen, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, emptyArchiveLine, emptyPortalArchiveLine, entityReferenceKinds, entityReferenceKindsOf, entityReferenceWords, entityRefsOf, entityRefsToWrite, err, exampleSpec, exportPageXlsx, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isArchiveLane, isDecided, isEntityReferenceConfig, isOwnOp, isPortalAccent, isPortalArchiveFilter, isRecordsErr, isRuleFilter, isTheChosen, keptGroups, keptOutOfSight, keptTableHref, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, moveInOrder, offeredAsContext, ok, openCaptureQueue, optionKey, optionLabel, portalArchiveConsequence, portalConfirmLine, portalPath, portalTitleTypedBack, publicFormPath, recordChangeTrigger, rememberedOpCount, sameDocument, scopeChip, sheetSyncSpec, stableFilterKey, tableShapeChanged, useEntityFieldMutation, useEntityFieldRights, useEntityFields, useEntityRecord, useEntityReferenceKinds, useEntityReferenceWords, useEntityTable, useFieldMutation, useFields, useMergeField, useMyLevel, useMyLevels, useOptionalRecordsClient, useRecord, useRecordChangeRevision, useRecordMutation, useRecords, useRecordsActor, useRecordsClient, useTable, useTableArchive, useTables, withRowCounts, withTablePlacement };
|