@ai-matrx/records 0.43.0 → 0.45.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.
@@ -1,7 +1,7 @@
1
- import { g as Timestamp, U as Uuid, h as RecordDocument, i as RecordsResult, j as RecordRead, k as ReadRow, l as Field, m as StoredRecord, N as NewFieldDeclaration, n as FieldPatch, o as RecordRevision, p as ReadValue, q as FieldProposal, r as TableProposal, s as RecordsError, W as WriteConflict, P as PgError, t as StaleWriteDetail, u as PredictedRefusal } from '../field-CdHqvIIy.cjs';
2
- export { A as ABSENCE_REASONS, v as ACTOR_VOCABULARY, w as AbsenceReason, x as Actor, y as COMPUTE_ON, z as CONTEXT_POLICIES, C as ComputeOn, e as ContextPolicy, D as DELIVERIES, B as Delivery, E as ENTITY_TOKENS, G as EntityToken, H as FIELD_SENSITIVITIES, I as FIELD_SOURCES, J as FRESHNESS, K as FieldBehavior, c as FieldRule, d as FieldSensitivity, b as FieldSource, F as FieldTypeWord, L as ForbiddenEnvelopeWord, M as Freshness, Q as HiddenFieldNotice, V as KERNEL_TABLES, X as KernelTableName, Y as MERGE_FIELD_MODIFIERS, Z as MERGE_FIELD_SEMANTIC_TYPES, _ as MERGE_FIELD_SOURCES, $ as MergeFieldModifier, a0 as MergeFieldSemanticType, a1 as MergeFieldSource, a2 as ON_DELETE, a3 as OVERRIDE_POLICIES, O as OnDelete, a4 as OverridePolicy, a5 as PARITY_FIELD_TYPES, a6 as PER_VALUE_ACCESS_WORDS, a7 as ParityFieldType, a8 as ParityFieldTypeDescriptor, a9 as PerValueAccessWord, aa as ProvenancePointer, ab as RELATION_BINDINGS, ac as RELATION_CARDINALITIES, ad as RELATION_FLAVORS, ae as RETIRED_ACTOR_WORDS, af as RULE_NODE_KINDS, ag as RULE_USES, ah as RecordsErrorCode, ai as RelationBinding, f as RelationCardinality, R as RelationFlavor, aj as RetiredActorWord, ak as RuleNodeKind, al as RuleUse, am as STORAGE_MODES, an as STORE_DOORS, ao as STORE_KNOBS, ap as STORE_REFUSAL_CODES, S as StorageMode, aq as StoreDoorName, ar as StoreRefusalCode, as as TABLE_DISPLAYS, at as TABLE_ORIGINS, au as TABLE_TYPES, a as TableDisplay, av as TableOrigin, T as TableType, aw as VALUE_ALTERNATE_KEYS, ax as VALUE_ENVELOPE_KEYS, ay as ValueAlternate, az as ValueAlternateKey, aA as ValueEnvelope, aB as ValueEnvelopeKey, aC as ValueSource, aD as err, aE as isRecordsErr, aF as ok } from '../field-CdHqvIIy.cjs';
1
+ import { g as Timestamp, U as Uuid, h as RecordDocument, i as RecordsResult, j as RecordRead, k as ReadRow, l as Field, m as StoredRecord, N as NewFieldDeclaration, n as FieldPatch, o as RecordRevision, p as ReadValue, q as FieldProposal, r as TableProposal, s as RecordsError, W as WriteConflict, P as PgError, t as StaleWriteDetail, u as PredictedRefusal } from '../field-D0Rr4Cqb.cjs';
2
+ export { A as ABSENCE_REASONS, v as ACTOR_VOCABULARY, w as AbsenceReason, x as Actor, y as COMPUTE_ON, z as CONTEXT_POLICIES, C as ComputeOn, e as ContextPolicy, D as DELIVERIES, B as Delivery, E as ENTITY_TOKENS, G as EntityToken, H as FIELD_SENSITIVITIES, I as FIELD_SOURCES, J as FRESHNESS, K as FieldBehavior, c as FieldRule, d as FieldSensitivity, b as FieldSource, F as FieldTypeWord, L as ForbiddenEnvelopeWord, M as Freshness, Q as HiddenFieldNotice, V as KERNEL_TABLES, X as KernelTableName, Y as MERGE_FIELD_MODIFIERS, Z as MERGE_FIELD_SEMANTIC_TYPES, _ as MERGE_FIELD_SOURCES, $ as MergeFieldModifier, a0 as MergeFieldSemanticType, a1 as MergeFieldSource, a2 as ON_DELETE, a3 as OVERRIDE_POLICIES, O as OnDelete, a4 as OverridePolicy, a5 as PARITY_FIELD_TYPES, a6 as PER_VALUE_ACCESS_WORDS, a7 as ParityFieldType, a8 as ParityFieldTypeDescriptor, a9 as PerValueAccessWord, aa as ProvenancePointer, ab as RELATION_BINDINGS, ac as RELATION_CARDINALITIES, ad as RELATION_FLAVORS, ae as RETIRED_ACTOR_WORDS, af as RULE_NODE_KINDS, ag as RULE_USES, ah as RecordsErrorCode, ai as RelationBinding, f as RelationCardinality, aj as RelationDisplay, R as RelationFlavor, ak as RetiredActorWord, al as RuleNodeKind, am as RuleUse, an as STORAGE_MODES, ao as STORE_DOORS, ap as STORE_KNOBS, aq as STORE_REFUSAL_CODES, S as StorageMode, ar as StoreDoorName, as as StoreRefusalCode, at as TABLE_DISPLAYS, au as TABLE_ORIGINS, av as TABLE_TYPES, a as TableDisplay, aw as TableOrigin, T as TableType, ax as VALUE_ALTERNATE_KEYS, ay as VALUE_ENVELOPE_KEYS, az as ValueAlternate, aA as ValueAlternateKey, aB as ValueEnvelope, aC as ValueEnvelopeKey, aD as ValueSource, aE as err, aF as isRecordsErr, aG as ok } from '../field-D0Rr4Cqb.cjs';
3
3
  import { RelationCoordinate, RecordsConfig, Table, TableCapacity, EntityTableFacts, NewEntityFieldDeclaration, EntityFieldRights, EntityRecordRead, EntityRecordsFound, Pipeline, PipelineColumn, PipelineVerdict, PipelineMoveResult, PipelineSpec, PipelineDeclared, StageRuleOnFail, StageRuleEnforcement, StagePending, StagePendingOnBoard, PipelineGate, PipelineGatePreview, FormSummary, BookingSummary, BookingAvailability, BookingDeclared, ImportPlan, ImportPolicy, ImportOpened, ImportBatchResult, ImportFinished, ImportReport, ImportRun, InboundDeclared, InboundAddress, PortalSummary, PortalCard, PortalInvitation, PortalRevocation, PortalPreviewRow, DashboardSummary, DashboardBlock, AggregateFilter, DashboardRunResult, StuckRow, CaptureSheetSummary, CaptureSheetFace, CaptureFileRef, CaptureOutcome, EnrichmentSummary, EnrichDeclared, EnrichDueRow, EnrichCell, EnrichRun, AggregateMeasure, AggregateBucket, AggregateRow, Subscription, MySubscription, SubscriptionSpec, DigestPreview, SavedViewRow, SavedViewSpecIn, DocToken, DocUnresolvedToken, DocTemplateRow, DocRenderRow, DocSignatureRow, RecordHistoryEntry, RecordScopeContext, ConversationScope, ConversationScopeContext, FieldHistoryEntry, RestorePreview, RestoreResult, CommentThreadRead, CommentWritten, AnonTokenBinding, ChecklistSpec, ChecklistDeclared, ChecklistTemplateSummary, ChecklistTemplateShape, ChecklistRunStarted, ChecklistRunStep, ChecklistRunSummary, ChecklistStepCompleted, WorkState, WorkGraph, WorkInstantiation, WorkTurn, WorkAssignmentField, WorkSlotHold, WorkInboxItem, WorkListFlavour, WorkListItem, WorkAssignment, WorkRecordState, WorkApprover, WorkChange, WorkApprovalFiled, WorkApprovalDecision, ExternalPrincipalCard, PublishBinding, ResolvedPublishBinding, MyLevel, RecordsDataSource } from '../index.cjs';
4
- export { AggregateOperation, AggregateWindow, BookingWindow, CaptureField, CaptureQuestion, CaptureQueue, CaptureQueueCounts, CaptureQueueOptions, CaptureQueuePorts, CaptureQueueStore, CaptureSyncReport, ChecklistRequirement, ChecklistRequirementKind, ChecklistRoleSpec, ChecklistStepSpec, ChecklistTrigger, ChecklistTriggerKind, ChoiceOption, CustomFieldTableType, DashboardBlockKind, DashboardBlockResult, DocSignatureCheck, EnrichAlternate, EnrichSource, Enrichment, EntityFieldValue, EntityRecordMatch, HistoryActor, HistoryActorKind, HistoryChange, Home, ImportColumnPlan, ImportOutcome, ImportProposal, MergeField, MergeFieldProvenance, MergeFieldResolution, MergeFieldTransform, MissingBehavior, PERMISSION_LEVELS, PIPELINE_RULE_KINDS, PermissionLevel, PipelineMissingField, PipelineRule, PipelineRuleKind, PipelineStage, PortalPrincipal, PortalTableExposure, QueuedCapture, QueuedCaptureFile, QueuedCaptureState, QuietHours, REFUSALS_WORTH_REPEATING, RecordComment, RecordScopeComment, RecordScopeField, RecordScopeHistoryEntry, RecordScopeRelation, RecordScopeWithheld, RecordsActor, RecordsChangeSink, RecordsErrorSink, RecordsFilter, RecordsRealtimePort, RecordsResolverPort, RecordsResponse, RecordsTableQuery, RegisteredTable, Relation, RelationCarries, RelationProperties, RelationTarget, ResolutionTriple, Rule, RuleAnswer, RuleExpression, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, StageRuleWarning, SubscriptionBlock, SubscriptionCadence, WorkDueState, WorkInboxKind, WorkOrigin, WorkTemplateNode, WorkTemplateRelation, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isDecided, isOwnOp, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, openCaptureQueue, optionKey, optionLabel, portalPath, publicFormPath, rememberedOpCount, scopeChip } from '../index.cjs';
4
+ export { AggregateOperation, AggregateWindow, BookingWindow, CaptureField, CaptureQuestion, CaptureQueue, CaptureQueueCounts, CaptureQueueOptions, CaptureQueuePorts, CaptureQueueStore, CaptureSyncReport, ChecklistRequirement, ChecklistRequirementKind, ChecklistRoleSpec, ChecklistStepSpec, ChecklistTrigger, ChecklistTriggerKind, ChoiceOption, ChoiceOptions, CoerceOptions, Coerced, CoercedAnswers, CoercibleField, CustomFieldTableType, DashboardBlockKind, DashboardBlockResult, DocSignatureCheck, EnrichAlternate, EnrichSource, Enrichment, EntityFieldValue, EntityRecordMatch, FIELD_KINDS, FieldKind, HistoryActor, HistoryActorKind, HistoryChange, Home, ImportColumnPlan, ImportOutcome, ImportProposal, KernelTargets, MergeField, MergeFieldProvenance, MergeFieldResolution, MergeFieldTransform, MissingBehavior, PERMISSION_LEVELS, PIPELINE_RULE_KINDS, PermissionLevel, PipelineMissingField, PipelineRule, PipelineRuleKind, PipelineStage, PortalPrincipal, PortalTableExposure, QueuedCapture, QueuedCaptureFile, QueuedCaptureState, QuietHours, REFUSALS_WORTH_REPEATING, RecordComment, RecordScopeComment, RecordScopeField, RecordScopeHistoryEntry, RecordScopeRelation, RecordScopeWithheld, RecordsActor, RecordsChangeSink, RecordsErrorSink, RecordsFilter, RecordsRealtimePort, RecordsResolverPort, RecordsResponse, RecordsTableQuery, RegisteredTable, Relation, RelationCarries, RelationProperties, RelationTarget, ResolutionTriple, Rule, RuleAnswer, RuleExpression, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, StageRuleWarning, SubscriptionBlock, SubscriptionCadence, WorkDueState, WorkInboxKind, WorkOrigin, WorkTemplateNode, WorkTemplateRelation, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isDecided, isOwnOp, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, openCaptureQueue, optionKey, optionLabel, portalPath, publicFormPath, rememberedOpCount, scopeChip } from '../index.cjs';
5
5
 
6
6
  /**
7
7
  * DOOR-8. As-of on EITHER clock, and they are different questions:
@@ -211,6 +211,28 @@ interface RecordsClient {
211
211
  field_id: Uuid;
212
212
  patch: FieldPatch;
213
213
  }): Promise<RecordsResult<Uuid>>;
214
+ /**
215
+ * REL-DISP. THE WORDS ONE RELATION CELL SHOWS, resolved by the store through
216
+ * that column's own display spec — one column or several, joined by its
217
+ * separator. Never resolve a relation label any other way: the store's
218
+ * `custom._words_for` is the one body that decides what a record is called, it
219
+ * asks the visibility ladder BEFORE it reads the name, and a record this reader
220
+ * may not open comes back as the withheld sentence rather than its name or id.
221
+ * A value that is not an id is handed straight back — it is already words.
222
+ */
223
+ relationWords(args: {
224
+ field_id: Uuid;
225
+ value: string;
226
+ }): Promise<RecordsResult<string | null>>;
227
+ /**
228
+ * The same answer for a WHOLE PAGE of cells in one round trip. Prefer this
229
+ * wherever a grid, board, list or picker resolves more than one chip: the
230
+ * per-id lane is what made a page of relation cells a page of requests.
231
+ */
232
+ relationWordsMany(args: {
233
+ field_id: Uuid;
234
+ record_ids: Uuid[];
235
+ }): Promise<RecordsResult<Record<string, string>>>;
214
236
  /** Take a field off a table. Refuses the title field, the last field, and one another field reads through. */
215
237
  fieldRetire(args: {
216
238
  field_id: Uuid;
@@ -1374,6 +1396,8 @@ declare const DOORS: {
1374
1396
  readonly promotedRead: "promoted_read";
1375
1397
  readonly relationTargets: "relation_targets";
1376
1398
  readonly relationOwn: "relation_own";
1399
+ readonly relationWords: "relation_words";
1400
+ readonly relationWordsMany: "relation_words_many";
1377
1401
  readonly homeAdd: "home_add";
1378
1402
  readonly recordReparent: "record_reparent";
1379
1403
  readonly containmentChain: "containment_chain";
@@ -1,7 +1,7 @@
1
- import { g as Timestamp, U as Uuid, h as RecordDocument, i as RecordsResult, j as RecordRead, k as ReadRow, l as Field, m as StoredRecord, N as NewFieldDeclaration, n as FieldPatch, o as RecordRevision, p as ReadValue, q as FieldProposal, r as TableProposal, s as RecordsError, W as WriteConflict, P as PgError, t as StaleWriteDetail, u as PredictedRefusal } from '../field-CdHqvIIy.js';
2
- export { A as ABSENCE_REASONS, v as ACTOR_VOCABULARY, w as AbsenceReason, x as Actor, y as COMPUTE_ON, z as CONTEXT_POLICIES, C as ComputeOn, e as ContextPolicy, D as DELIVERIES, B as Delivery, E as ENTITY_TOKENS, G as EntityToken, H as FIELD_SENSITIVITIES, I as FIELD_SOURCES, J as FRESHNESS, K as FieldBehavior, c as FieldRule, d as FieldSensitivity, b as FieldSource, F as FieldTypeWord, L as ForbiddenEnvelopeWord, M as Freshness, Q as HiddenFieldNotice, V as KERNEL_TABLES, X as KernelTableName, Y as MERGE_FIELD_MODIFIERS, Z as MERGE_FIELD_SEMANTIC_TYPES, _ as MERGE_FIELD_SOURCES, $ as MergeFieldModifier, a0 as MergeFieldSemanticType, a1 as MergeFieldSource, a2 as ON_DELETE, a3 as OVERRIDE_POLICIES, O as OnDelete, a4 as OverridePolicy, a5 as PARITY_FIELD_TYPES, a6 as PER_VALUE_ACCESS_WORDS, a7 as ParityFieldType, a8 as ParityFieldTypeDescriptor, a9 as PerValueAccessWord, aa as ProvenancePointer, ab as RELATION_BINDINGS, ac as RELATION_CARDINALITIES, ad as RELATION_FLAVORS, ae as RETIRED_ACTOR_WORDS, af as RULE_NODE_KINDS, ag as RULE_USES, ah as RecordsErrorCode, ai as RelationBinding, f as RelationCardinality, R as RelationFlavor, aj as RetiredActorWord, ak as RuleNodeKind, al as RuleUse, am as STORAGE_MODES, an as STORE_DOORS, ao as STORE_KNOBS, ap as STORE_REFUSAL_CODES, S as StorageMode, aq as StoreDoorName, ar as StoreRefusalCode, as as TABLE_DISPLAYS, at as TABLE_ORIGINS, au as TABLE_TYPES, a as TableDisplay, av as TableOrigin, T as TableType, aw as VALUE_ALTERNATE_KEYS, ax as VALUE_ENVELOPE_KEYS, ay as ValueAlternate, az as ValueAlternateKey, aA as ValueEnvelope, aB as ValueEnvelopeKey, aC as ValueSource, aD as err, aE as isRecordsErr, aF as ok } from '../field-CdHqvIIy.js';
1
+ import { g as Timestamp, U as Uuid, h as RecordDocument, i as RecordsResult, j as RecordRead, k as ReadRow, l as Field, m as StoredRecord, N as NewFieldDeclaration, n as FieldPatch, o as RecordRevision, p as ReadValue, q as FieldProposal, r as TableProposal, s as RecordsError, W as WriteConflict, P as PgError, t as StaleWriteDetail, u as PredictedRefusal } from '../field-D0Rr4Cqb.js';
2
+ export { A as ABSENCE_REASONS, v as ACTOR_VOCABULARY, w as AbsenceReason, x as Actor, y as COMPUTE_ON, z as CONTEXT_POLICIES, C as ComputeOn, e as ContextPolicy, D as DELIVERIES, B as Delivery, E as ENTITY_TOKENS, G as EntityToken, H as FIELD_SENSITIVITIES, I as FIELD_SOURCES, J as FRESHNESS, K as FieldBehavior, c as FieldRule, d as FieldSensitivity, b as FieldSource, F as FieldTypeWord, L as ForbiddenEnvelopeWord, M as Freshness, Q as HiddenFieldNotice, V as KERNEL_TABLES, X as KernelTableName, Y as MERGE_FIELD_MODIFIERS, Z as MERGE_FIELD_SEMANTIC_TYPES, _ as MERGE_FIELD_SOURCES, $ as MergeFieldModifier, a0 as MergeFieldSemanticType, a1 as MergeFieldSource, a2 as ON_DELETE, a3 as OVERRIDE_POLICIES, O as OnDelete, a4 as OverridePolicy, a5 as PARITY_FIELD_TYPES, a6 as PER_VALUE_ACCESS_WORDS, a7 as ParityFieldType, a8 as ParityFieldTypeDescriptor, a9 as PerValueAccessWord, aa as ProvenancePointer, ab as RELATION_BINDINGS, ac as RELATION_CARDINALITIES, ad as RELATION_FLAVORS, ae as RETIRED_ACTOR_WORDS, af as RULE_NODE_KINDS, ag as RULE_USES, ah as RecordsErrorCode, ai as RelationBinding, f as RelationCardinality, aj as RelationDisplay, R as RelationFlavor, ak as RetiredActorWord, al as RuleNodeKind, am as RuleUse, an as STORAGE_MODES, ao as STORE_DOORS, ap as STORE_KNOBS, aq as STORE_REFUSAL_CODES, S as StorageMode, ar as StoreDoorName, as as StoreRefusalCode, at as TABLE_DISPLAYS, au as TABLE_ORIGINS, av as TABLE_TYPES, a as TableDisplay, aw as TableOrigin, T as TableType, ax as VALUE_ALTERNATE_KEYS, ay as VALUE_ENVELOPE_KEYS, az as ValueAlternate, aA as ValueAlternateKey, aB as ValueEnvelope, aC as ValueEnvelopeKey, aD as ValueSource, aE as err, aF as isRecordsErr, aG as ok } from '../field-D0Rr4Cqb.js';
3
3
  import { RelationCoordinate, RecordsConfig, Table, TableCapacity, EntityTableFacts, NewEntityFieldDeclaration, EntityFieldRights, EntityRecordRead, EntityRecordsFound, Pipeline, PipelineColumn, PipelineVerdict, PipelineMoveResult, PipelineSpec, PipelineDeclared, StageRuleOnFail, StageRuleEnforcement, StagePending, StagePendingOnBoard, PipelineGate, PipelineGatePreview, FormSummary, BookingSummary, BookingAvailability, BookingDeclared, ImportPlan, ImportPolicy, ImportOpened, ImportBatchResult, ImportFinished, ImportReport, ImportRun, InboundDeclared, InboundAddress, PortalSummary, PortalCard, PortalInvitation, PortalRevocation, PortalPreviewRow, DashboardSummary, DashboardBlock, AggregateFilter, DashboardRunResult, StuckRow, CaptureSheetSummary, CaptureSheetFace, CaptureFileRef, CaptureOutcome, EnrichmentSummary, EnrichDeclared, EnrichDueRow, EnrichCell, EnrichRun, AggregateMeasure, AggregateBucket, AggregateRow, Subscription, MySubscription, SubscriptionSpec, DigestPreview, SavedViewRow, SavedViewSpecIn, DocToken, DocUnresolvedToken, DocTemplateRow, DocRenderRow, DocSignatureRow, RecordHistoryEntry, RecordScopeContext, ConversationScope, ConversationScopeContext, FieldHistoryEntry, RestorePreview, RestoreResult, CommentThreadRead, CommentWritten, AnonTokenBinding, ChecklistSpec, ChecklistDeclared, ChecklistTemplateSummary, ChecklistTemplateShape, ChecklistRunStarted, ChecklistRunStep, ChecklistRunSummary, ChecklistStepCompleted, WorkState, WorkGraph, WorkInstantiation, WorkTurn, WorkAssignmentField, WorkSlotHold, WorkInboxItem, WorkListFlavour, WorkListItem, WorkAssignment, WorkRecordState, WorkApprover, WorkChange, WorkApprovalFiled, WorkApprovalDecision, ExternalPrincipalCard, PublishBinding, ResolvedPublishBinding, MyLevel, RecordsDataSource } from '../index.js';
4
- export { AggregateOperation, AggregateWindow, BookingWindow, CaptureField, CaptureQuestion, CaptureQueue, CaptureQueueCounts, CaptureQueueOptions, CaptureQueuePorts, CaptureQueueStore, CaptureSyncReport, ChecklistRequirement, ChecklistRequirementKind, ChecklistRoleSpec, ChecklistStepSpec, ChecklistTrigger, ChecklistTriggerKind, ChoiceOption, CustomFieldTableType, DashboardBlockKind, DashboardBlockResult, DocSignatureCheck, EnrichAlternate, EnrichSource, Enrichment, EntityFieldValue, EntityRecordMatch, HistoryActor, HistoryActorKind, HistoryChange, Home, ImportColumnPlan, ImportOutcome, ImportProposal, MergeField, MergeFieldProvenance, MergeFieldResolution, MergeFieldTransform, MissingBehavior, PERMISSION_LEVELS, PIPELINE_RULE_KINDS, PermissionLevel, PipelineMissingField, PipelineRule, PipelineRuleKind, PipelineStage, PortalPrincipal, PortalTableExposure, QueuedCapture, QueuedCaptureFile, QueuedCaptureState, QuietHours, REFUSALS_WORTH_REPEATING, RecordComment, RecordScopeComment, RecordScopeField, RecordScopeHistoryEntry, RecordScopeRelation, RecordScopeWithheld, RecordsActor, RecordsChangeSink, RecordsErrorSink, RecordsFilter, RecordsRealtimePort, RecordsResolverPort, RecordsResponse, RecordsTableQuery, RegisteredTable, Relation, RelationCarries, RelationProperties, RelationTarget, ResolutionTriple, Rule, RuleAnswer, RuleExpression, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, StageRuleWarning, SubscriptionBlock, SubscriptionCadence, WorkDueState, WorkInboxKind, WorkOrigin, WorkTemplateNode, WorkTemplateRelation, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isDecided, isOwnOp, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, openCaptureQueue, optionKey, optionLabel, portalPath, publicFormPath, rememberedOpCount, scopeChip } from '../index.js';
4
+ export { AggregateOperation, AggregateWindow, BookingWindow, CaptureField, CaptureQuestion, CaptureQueue, CaptureQueueCounts, CaptureQueueOptions, CaptureQueuePorts, CaptureQueueStore, CaptureSyncReport, ChecklistRequirement, ChecklistRequirementKind, ChecklistRoleSpec, ChecklistStepSpec, ChecklistTrigger, ChecklistTriggerKind, ChoiceOption, ChoiceOptions, CoerceOptions, Coerced, CoercedAnswers, CoercibleField, CustomFieldTableType, DashboardBlockKind, DashboardBlockResult, DocSignatureCheck, EnrichAlternate, EnrichSource, Enrichment, EntityFieldValue, EntityRecordMatch, FIELD_KINDS, FieldKind, HistoryActor, HistoryActorKind, HistoryChange, Home, ImportColumnPlan, ImportOutcome, ImportProposal, KernelTargets, MergeField, MergeFieldProvenance, MergeFieldResolution, MergeFieldTransform, MissingBehavior, PERMISSION_LEVELS, PIPELINE_RULE_KINDS, PermissionLevel, PipelineMissingField, PipelineRule, PipelineRuleKind, PipelineStage, PortalPrincipal, PortalTableExposure, QueuedCapture, QueuedCaptureFile, QueuedCaptureState, QuietHours, REFUSALS_WORTH_REPEATING, RecordComment, RecordScopeComment, RecordScopeField, RecordScopeHistoryEntry, RecordScopeRelation, RecordScopeWithheld, RecordsActor, RecordsChangeSink, RecordsErrorSink, RecordsFilter, RecordsRealtimePort, RecordsResolverPort, RecordsResponse, RecordsTableQuery, RegisteredTable, Relation, RelationCarries, RelationProperties, RelationTarget, ResolutionTriple, Rule, RuleAnswer, RuleExpression, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, StageRuleWarning, SubscriptionBlock, SubscriptionCadence, WorkDueState, WorkInboxKind, WorkOrigin, WorkTemplateNode, WorkTemplateRelation, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isDecided, isOwnOp, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, openCaptureQueue, optionKey, optionLabel, portalPath, publicFormPath, rememberedOpCount, scopeChip } from '../index.js';
5
5
 
6
6
  /**
7
7
  * DOOR-8. As-of on EITHER clock, and they are different questions:
@@ -211,6 +211,28 @@ interface RecordsClient {
211
211
  field_id: Uuid;
212
212
  patch: FieldPatch;
213
213
  }): Promise<RecordsResult<Uuid>>;
214
+ /**
215
+ * REL-DISP. THE WORDS ONE RELATION CELL SHOWS, resolved by the store through
216
+ * that column's own display spec — one column or several, joined by its
217
+ * separator. Never resolve a relation label any other way: the store's
218
+ * `custom._words_for` is the one body that decides what a record is called, it
219
+ * asks the visibility ladder BEFORE it reads the name, and a record this reader
220
+ * may not open comes back as the withheld sentence rather than its name or id.
221
+ * A value that is not an id is handed straight back — it is already words.
222
+ */
223
+ relationWords(args: {
224
+ field_id: Uuid;
225
+ value: string;
226
+ }): Promise<RecordsResult<string | null>>;
227
+ /**
228
+ * The same answer for a WHOLE PAGE of cells in one round trip. Prefer this
229
+ * wherever a grid, board, list or picker resolves more than one chip: the
230
+ * per-id lane is what made a page of relation cells a page of requests.
231
+ */
232
+ relationWordsMany(args: {
233
+ field_id: Uuid;
234
+ record_ids: Uuid[];
235
+ }): Promise<RecordsResult<Record<string, string>>>;
214
236
  /** Take a field off a table. Refuses the title field, the last field, and one another field reads through. */
215
237
  fieldRetire(args: {
216
238
  field_id: Uuid;
@@ -1374,6 +1396,8 @@ declare const DOORS: {
1374
1396
  readonly promotedRead: "promoted_read";
1375
1397
  readonly relationTargets: "relation_targets";
1376
1398
  readonly relationOwn: "relation_own";
1399
+ readonly relationWords: "relation_words";
1400
+ readonly relationWordsMany: "relation_words_many";
1377
1401
  readonly homeAdd: "home_add";
1378
1402
  readonly recordReparent: "record_reparent";
1379
1403
  readonly containmentChain: "containment_chain";
@@ -124,6 +124,209 @@ function looksLikeAnId(value) {
124
124
  return typeof value === "string" && UUID.test(value);
125
125
  }
126
126
 
127
+ // src/coerce.ts
128
+ var FIELD_KINDS = [
129
+ "attachment",
130
+ "checkbox",
131
+ "currency",
132
+ "datetime",
133
+ "email",
134
+ "formula",
135
+ "json",
136
+ "long_text",
137
+ "lookup",
138
+ "member",
139
+ "multi_select",
140
+ "number",
141
+ "percent",
142
+ "phone",
143
+ "relation",
144
+ "rollup",
145
+ "select",
146
+ "text",
147
+ "url"
148
+ ];
149
+ function fieldKindFor(field, kernel) {
150
+ const format = (field.format ?? "").toLowerCase();
151
+ const config = field.config ?? {};
152
+ switch (field.type) {
153
+ case "boolean":
154
+ return "checkbox";
155
+ case "text":
156
+ if (format === "email") return "email";
157
+ if (format === "phone") return "phone";
158
+ if (format === "url") return "url";
159
+ if (format === "json" || config["json"] === true) return "json";
160
+ if (format === "long" || config["multiline"] === true) return "long_text";
161
+ return "text";
162
+ case "range": {
163
+ const kind = String(config["kind"] ?? "number");
164
+ if (kind === "date" || kind === "datetime") return "datetime";
165
+ if (format === "currency") return "currency";
166
+ if (format === "percent" || field.unit === "%") return "percent";
167
+ return "number";
168
+ }
169
+ case "list":
170
+ return field.multi ? "multi_select" : "select";
171
+ case "relation": {
172
+ const parity = String(config["parity"] ?? "");
173
+ if (parity === "attachment" || parity === "member") return parity;
174
+ if (kernel?.file && field.relation_target === kernel.file) return "attachment";
175
+ if (kernel?.person && field.relation_target === kernel.person) return "member";
176
+ return "relation";
177
+ }
178
+ case "formula": {
179
+ const via = config["via"];
180
+ if (via && config["agg"]) return "rollup";
181
+ if (via) return "lookup";
182
+ return "formula";
183
+ }
184
+ default:
185
+ return "text";
186
+ }
187
+ }
188
+ var TRUE_WORDS = /* @__PURE__ */ new Set(["true", "yes", "y", "1", "\u2713", "x", "checked", "on"]);
189
+ var FALSE_WORDS = /* @__PURE__ */ new Set(["false", "no", "n", "0", "", "unchecked", "off"]);
190
+ function coercionLabel(field) {
191
+ const label = (field.label ?? "").trim();
192
+ if (label !== "") return label;
193
+ const name = (field.name ?? "").trim();
194
+ if (name !== "") return name;
195
+ return field.key.replace(/[_-]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim();
196
+ }
197
+ function coerceTypedAnswer(field, raw, opts = {}) {
198
+ const label = opts.label ?? coercionLabel(field);
199
+ const text = raw.trim();
200
+ const kind = fieldKindFor(field, opts.kernel);
201
+ if (text === "" && kind !== "checkbox") return { value: null };
202
+ switch (kind) {
203
+ case "checkbox": {
204
+ const word = text.toLowerCase();
205
+ if (TRUE_WORDS.has(word)) return { value: true };
206
+ if (FALSE_WORDS.has(word)) return { value: word === "" ? null : false };
207
+ return {
208
+ refusal: `${label} is a tick box, so it takes yes or no \u2014 \u201C${raw}\u201D is neither. Write TRUE/FALSE, yes/no or 1/0.`
209
+ };
210
+ }
211
+ case "number":
212
+ case "currency":
213
+ case "percent": {
214
+ const negative = /^\(.*\)$/.test(text);
215
+ const bare = text.replace(/^\(|\)$/g, "").replace(/[\s,]/g, "").replace(/^[^\d.\-+]+/, "").replace(/[^\d.\-+eE]+$/, "");
216
+ const n = Number(bare);
217
+ if (bare === "" || Number.isNaN(n)) {
218
+ return {
219
+ refusal: `${label} holds a number, and \u201C${raw}\u201D is not one. Write digits \u2014 a currency symbol, a percent sign, commas and brackets for a negative are all fine.`
220
+ };
221
+ }
222
+ return { value: negative ? -n : n };
223
+ }
224
+ case "datetime": {
225
+ const wantsTime = String(field.config?.["kind"] ?? "date") === "datetime";
226
+ const plainDay = /^\s*(\d{4})-(\d{2})-(\d{2})\s*$/.exec(raw);
227
+ if (!wantsTime && plainDay) return { value: `${plainDay[1]}-${plainDay[2]}-${plainDay[3]}` };
228
+ const at = Date.parse(text);
229
+ if (Number.isNaN(at)) {
230
+ return {
231
+ refusal: `${label} holds a date, and \u201C${raw}\u201D is not one this can read. Write it as 2026-09-21, or the way your spreadsheet writes dates.`
232
+ };
233
+ }
234
+ const parsed = new Date(at);
235
+ if (wantsTime) return { value: parsed.toISOString() };
236
+ const y = parsed.getFullYear();
237
+ const m = String(parsed.getMonth() + 1).padStart(2, "0");
238
+ const d = String(parsed.getDate()).padStart(2, "0");
239
+ return { value: `${y}-${m}-${d}` };
240
+ }
241
+ case "json": {
242
+ try {
243
+ return { value: JSON.parse(text) };
244
+ } catch {
245
+ return {
246
+ refusal: `${label} holds a document, and \u201C${raw}\u201D is not valid JSON. Write the whole object, braces and all.`
247
+ };
248
+ }
249
+ }
250
+ case "select":
251
+ case "multi_select": {
252
+ if (!opts.options) {
253
+ return {
254
+ refusal: `${label} is a list and its options have not been read yet, so nothing can be matched to \u201C${raw}\u201D. Try again once the column's choices have loaded.`
255
+ };
256
+ }
257
+ const wanted = kind === "multi_select" ? text.split(/[,;]/).map((w) => w.trim()).filter((w) => w.length > 0) : [text];
258
+ if (wanted.length === 0) return { value: kind === "multi_select" ? [] : null };
259
+ const matched = [];
260
+ const unmatched = [];
261
+ for (const word of wanted) {
262
+ const hit = opts.options.byWord.get(word.toLowerCase());
263
+ if (hit === void 0) unmatched.push(word);
264
+ else matched.push(hit);
265
+ }
266
+ if (unmatched.length > 0) {
267
+ const offered = opts.options.labels.length > 0 ? opts.options.labels.join(", ") : "it has none yet";
268
+ return {
269
+ refusal: `${label} does not have ${unmatched.map((w) => `\u201C${w}\u201D`).join(" or ")} among its options. It offers: ${offered}.`,
270
+ unmatched
271
+ };
272
+ }
273
+ return { value: kind === "multi_select" ? matched : matched[0] };
274
+ }
275
+ // AN IDENTITY IS NOT A WORD. Writing the word would put a string where an
276
+ // id belongs, and every filter, colour and rollup built on that column
277
+ // would stop agreeing with it. So it is refused and the person is told
278
+ // which control does hold it.
279
+ case "member":
280
+ return {
281
+ refusal: `${label} names a person in this organization, so it is chosen rather than typed. Open it and pick them.`
282
+ };
283
+ case "attachment":
284
+ return {
285
+ refusal: `${label} holds a file, which cannot arrive as typed-in text. Open it and attach the file.`
286
+ };
287
+ case "relation":
288
+ return {
289
+ refusal: `${label} points at another record, so it is chosen rather than typed. Open it and pick the record.`
290
+ };
291
+ case "formula":
292
+ case "lookup":
293
+ case "rollup":
294
+ return {
295
+ refusal: `${label} is worked out by the system, so nothing can be written into it.`
296
+ };
297
+ default:
298
+ return { value: raw };
299
+ }
300
+ }
301
+ function coerceTypedAnswers(fields, answers, opts = {}) {
302
+ const byKey = new Map(fields.map((f) => [f.key, f]));
303
+ const values = {};
304
+ const refusals = {};
305
+ const unknownKeys = [];
306
+ for (const [key, given] of Object.entries(answers)) {
307
+ const field = byKey.get(key);
308
+ if (!field) {
309
+ unknownKeys.push(key);
310
+ values[key] = given;
311
+ continue;
312
+ }
313
+ if (typeof given !== "string") {
314
+ values[key] = given;
315
+ continue;
316
+ }
317
+ const opt = {};
318
+ const choices = opts.options?.get(key);
319
+ if (choices) opt.options = choices;
320
+ if (opts.kernel) opt.kernel = opts.kernel;
321
+ const label = opts.labels?.[key];
322
+ if (label) opt.label = label;
323
+ const answered = coerceTypedAnswer(field, given, opt);
324
+ if ("refusal" in answered) refusals[key] = answered.refusal;
325
+ else values[key] = answered.value;
326
+ }
327
+ return { values, refusals, unknownKeys };
328
+ }
329
+
127
330
  // src/pipeline.ts
128
331
  var PIPELINE_RULE_KINDS = ["moves", "requires", "who", "limit", "entry"];
129
332
  var STAGE_RULE_ON_FAIL = ["refuse", "require_approval"];
@@ -955,6 +1158,8 @@ var STORE_DOORS = [
955
1158
  { name: "relation_target_ours", args: "p_entity_token text, p_row_id uuid", returns: "jsonb", security: "definer" },
956
1159
  { name: "relation_targets", args: "p_organization_id uuid, p_record_id uuid, p_via_key text", returns: "SETOF uuid", security: "definer" },
957
1160
  { name: "relation_uncarry", args: "p_organization_id uuid, p_container_id uuid, p_item_id uuid", returns: "integer", security: "definer" },
1161
+ { name: "relation_words", args: "p_organization_id uuid, p_field_id uuid, p_value text", returns: "text", security: "definer" },
1162
+ { name: "relation_words_many", args: "p_organization_id uuid, p_field_id uuid, p_record_ids uuid[]", returns: "TABLE(record_id uuid, words text)", security: "definer" },
958
1163
  { name: "reopen_declared_doors", args: "", returns: "TABLE(reopened text)", security: "definer" },
959
1164
  { name: "required_epoch", args: "p_container_type text, p_container_id uuid, p_item_type text, p_item_id uuid", returns: "bigint", security: "definer" },
960
1165
  { name: "resolve_first_match", args: "p_organization_id uuid, p_record_id uuid", returns: "jsonb", security: "invoker" },
@@ -1151,9 +1356,9 @@ var STORE_REFUSAL_CODES = [
1151
1356
  { code: "22007", raised_by: "dashboard_window_sql" },
1152
1357
  { code: "22012", raised_by: "rule_eval" },
1153
1358
  { code: "22023", raised_by: "_booking_availability,_entity_custom_fields_guard,_take_op_id,_value_envelope,_work_shape_guard,actor_word,agg_assert_key,agg_sql,anon_token_issue,booking_declare,containment_parent,dashboard_block_normalize,dashboard_window_sql,doc_render_body,doc_render_write,doc_signature_write,enrich_declare,enrich_land,enrich_normalize,enrich_pin,entity_value_write,external_history_event,external_source_declare,external_stub_upsert,external_write_through,field_history,io_export,io_import_begin,io_import_finish,io_import_plan,io_import_report,io_proposal_accept,migrate_merge,migrate_reclass,my_levels,organization_clear,page_size,pin_agent_cells,pipeline_move,portal_declare,provenance_write,query_by_coordinates,query_rollup,record_update,record_write_many,relation_carry,rule_eval,rule_members,share_grant,share_lane_set,sign_request_create,sign_request_sign,subscription_declare,table_rules,visibility_as_of,work_approval_request,work_list,work_slot_hold" },
1154
- { code: "23503", raised_by: "_booking_availability,_checklist_instantiate,_containment_guard,_field_document_for,_pipeline_stage_key,_record_rule_uses,agg_digest_assemble,anon_publish,anon_rate_take,anon_token_issue,anon_write,assert_organization_wall,booking_cancel,booking_confirm,booking_declare,booking_hold,booking_reschedule,capture_publish,checklist_declare,checklist_steps_table,comment_write,dashboard_declare,delete_rule,doc_sign,doc_template_save,enrich_declare,enrich_due,enrich_land,form_declare,form_submit,home_add,inbound_declare,inbound_mail_land,inbound_set,io_comment_write,io_import_begin,io_import_finish,io_import_report,io_import_rows,io_proposal_accept,migrate_demote,migrate_promote,pipeline_board,pipeline_declare,pipeline_move,pipeline_read,pipeline_transition_refusal,promote_field,promote_table,record_applicability,record_reparent,relation_carry,relation_own,resolve_first_match,rule_applies,rule_declare,rule_eval,rule_members,rule_run,sign_request_create,subscription_mute,subscription_preview,view_declare,work_set_state,work_take_assignment,work_template_instantiate" },
1359
+ { code: "23503", raised_by: "_booking_availability,_checklist_instantiate,_containment_guard,_display_spec_for,_field_document_for,_pipeline_stage_key,_record_rule_uses,agg_digest_assemble,anon_publish,anon_rate_take,anon_token_issue,anon_write,assert_organization_wall,booking_cancel,booking_confirm,booking_declare,booking_hold,booking_reschedule,capture_publish,checklist_declare,checklist_steps_table,comment_write,dashboard_declare,delete_rule,doc_sign,doc_template_save,enrich_declare,enrich_due,enrich_land,form_declare,form_submit,home_add,inbound_declare,inbound_mail_land,inbound_set,io_comment_write,io_import_begin,io_import_finish,io_import_report,io_import_rows,io_proposal_accept,migrate_demote,migrate_promote,pipeline_board,pipeline_declare,pipeline_move,pipeline_read,pipeline_transition_refusal,promote_field,promote_table,record_applicability,record_reparent,relation_carry,relation_own,resolve_first_match,rule_applies,rule_declare,rule_eval,rule_members,rule_run,sign_request_create,subscription_mute,subscription_preview,view_declare,work_set_state,work_take_assignment,work_template_instantiate" },
1155
1360
  { code: "23505", raised_by: "_unique_rule_holds,doc_sign,doc_signature_write,entity_field_declare,field_declare,home_add,inbound_declare,io_proposal_accept,relation_carry,relation_own,share_grant,sign_request_cancel,sign_request_create,table_share_outside_invite,table_share_outside_resend,work_approval_decide,work_slot_hold" },
1156
- { code: "23514", raised_by: "_checklist_instantiate,_checklist_step_guard,_containment_guard,_dated_values_guard,_derived_fields,_entity_custom_fields_guard,_field_class_guard,_field_document_for,_field_shape_guard,_field_type_parity_guard,_merge_field_shape_guard,_merge_field_temporal_guard,_promoted_field_cap_guard,_record_rule_uses,_resolve_choice_words,_rule_shape_guard,_rule_topology_guard,_store_relation_edge_names_its_field,_table_columns_word_guard,_table_shape_guard,_undeclared_key_guard,_value_envelope,_work_shape_guard,_workdoors_approval_guard,assert_columns_are_defined,assert_entity_is_organization_scoped,booking_declare,capture_publish,capture_sheet_declare,checklist_declare,checklist_step_complete,doc_sign,doc_signature_write,doc_template_save,entity_field_declare,entity_field_retire,entity_field_update,entity_records_find,entity_table,field_declare,field_retire,field_update,home_add,io_import_rows,migrate_merge,relation_carry,relation_own,sign_request_create,sign_request_sign,table_declare,validate_value_envelope,validate_values,work_set_state,work_slots_declare,work_take_assignment,work_template_instantiate" },
1361
+ { code: "23514", raised_by: "_checklist_instantiate,_checklist_step_guard,_containment_guard,_dated_values_guard,_derived_fields,_display_spec_for,_entity_custom_fields_guard,_field_class_guard,_field_document_for,_field_shape_guard,_field_type_parity_guard,_merge_field_shape_guard,_merge_field_temporal_guard,_promoted_field_cap_guard,_record_rule_uses,_resolve_choice_words,_rule_shape_guard,_rule_topology_guard,_store_relation_edge_names_its_field,_table_columns_word_guard,_table_shape_guard,_undeclared_key_guard,_value_envelope,_with_display,_work_shape_guard,_workdoors_approval_guard,assert_columns_are_defined,assert_entity_is_organization_scoped,booking_declare,capture_publish,capture_sheet_declare,checklist_declare,checklist_step_complete,doc_sign,doc_signature_write,doc_template_save,entity_field_declare,entity_field_retire,entity_field_update,entity_records_find,entity_table,field_declare,field_retire,field_update,home_add,io_import_rows,migrate_merge,relation_carry,relation_own,sign_request_create,sign_request_sign,table_declare,validate_value_envelope,validate_values,work_set_state,work_slots_declare,work_take_assignment,work_template_instantiate" },
1157
1362
  { code: "40001", raised_by: "has_visibility_at" },
1158
1363
  { code: "42501", raised_by: "_doc_render_immutable,_doc_signature_immutable,_field_definition_write,_field_write_door,_rule_definition_write,_store_door,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,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_reclass,my_levels,organization_clear,portal_declare,portal_invitation,portal_invite,portal_principal_bind,promote_table,query_visibility_parity,read_record,read_records,read_records_by_ids,record_table,share_grant,subscription_mute,subscription_preview,table_share_outside_accept,table_share_outside_invite,table_share_outside_resend,visibility_as_of,work_approval_decide,work_approval_read,work_approval_request,work_person" },
1159
1364
  { code: "42703", raised_by: "entity_table,portal_declare" },
@@ -2309,6 +2514,18 @@ var DOORS = {
2309
2514
  promotedRead: "promoted_read",
2310
2515
  relationTargets: "relation_targets",
2311
2516
  relationOwn: "relation_own",
2517
+ // REL-DISP, 2026-09-21. WHAT A RELATION CELL READS, through that column's own
2518
+ // display spec. `custom.record_words` is declared server_only — it takes a bare
2519
+ // record id with no field to scope it — so these are how a screen gets the
2520
+ // words, and they are the ONE way in: three separate copies of "read tableList,
2521
+ // find title_field, call rowName" lived in labels.tsx, RelationPicker.tsx and
2522
+ // PortalsPanel.tsx, and none of them could ever have shown two columns joined.
2523
+ // The `_many` door is the batch TAILS-2 recorded as missing ("there is still no
2524
+ // batch door on the store"), which is why the browser resolved labels one id at
2525
+ // a time. The ladder is NOT batched: the store asks it per record inside
2526
+ // `custom._words_for`, so batching buys a round trip and never a disclosure.
2527
+ relationWords: "relation_words",
2528
+ relationWordsMany: "relation_words_many",
2312
2529
  homeAdd: "home_add",
2313
2530
  recordReparent: "record_reparent",
2314
2531
  containmentChain: "containment_chain",
@@ -3188,6 +3405,26 @@ function createRecordsClient(config) {
3188
3405
  "fieldRetire"
3189
3406
  );
3190
3407
  },
3408
+ async relationWords({ field_id, value }) {
3409
+ return callDoor(
3410
+ DOORS.relationWords,
3411
+ { p_organization_id: org, p_field_id: field_id, p_value: value },
3412
+ "relationWords"
3413
+ );
3414
+ },
3415
+ async relationWordsMany({ field_id, record_ids }) {
3416
+ const result = await callDoor(
3417
+ DOORS.relationWordsMany,
3418
+ { p_organization_id: org, p_field_id: field_id, p_record_ids: record_ids },
3419
+ "relationWordsMany"
3420
+ );
3421
+ if (!result.ok) return result;
3422
+ const map = {};
3423
+ for (const row of result.data ?? []) {
3424
+ if (row?.record_id && typeof row.words === "string") map[row.record_id] = row.words;
3425
+ }
3426
+ return { ok: true, data: map };
3427
+ },
3191
3428
  async tableDeclare({ spec, homeId }) {
3192
3429
  return callDoor(
3193
3430
  DOORS.tableDeclare,
@@ -5048,6 +5285,7 @@ export {
5048
5285
  DELIVERIES,
5049
5286
  DOORS,
5050
5287
  ENTITY_TOKENS,
5288
+ FIELD_KINDS,
5051
5289
  FIELD_SENSITIVITIES,
5052
5290
  FIELD_SOURCES,
5053
5291
  FRESHNESS,
@@ -5088,6 +5326,9 @@ export {
5088
5326
  choiceSlug,
5089
5327
  choiceValuesOf,
5090
5328
  choicesOf,
5329
+ coerceTypedAnswer,
5330
+ coerceTypedAnswers,
5331
+ coercionLabel,
5091
5332
  createRecordsClient,
5092
5333
  doorAbsent,
5093
5334
  doorCensus,
@@ -5095,6 +5336,7 @@ export {
5095
5336
  err,
5096
5337
  exportCsv,
5097
5338
  exportXlsx,
5339
+ fieldKindFor,
5098
5340
  forgetAllOps,
5099
5341
  highestLevel,
5100
5342
  holdsARetiredChoice,