@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.cjs
CHANGED
|
@@ -2222,6 +2222,7 @@ __export(react_exports, {
|
|
|
2222
2222
|
PERMISSION_LEVELS: () => PERMISSION_LEVELS,
|
|
2223
2223
|
PER_VALUE_ACCESS_WORDS: () => PER_VALUE_ACCESS_WORDS,
|
|
2224
2224
|
PIPELINE_RULE_KINDS: () => PIPELINE_RULE_KINDS,
|
|
2225
|
+
PORTAL_ACCENTS: () => PORTAL_ACCENTS,
|
|
2225
2226
|
PORTAL_ARCHIVE_FILTERS: () => PORTAL_ARCHIVE_FILTERS,
|
|
2226
2227
|
REFUSALS_WORTH_REPEATING: () => REFUSALS_WORTH_REPEATING,
|
|
2227
2228
|
RELATION_BINDINGS: () => RELATION_BINDINGS,
|
|
@@ -2257,6 +2258,11 @@ __export(react_exports, {
|
|
|
2257
2258
|
coercionLabel: () => coercionLabel,
|
|
2258
2259
|
emptyArchiveLine: () => emptyArchiveLine,
|
|
2259
2260
|
emptyPortalArchiveLine: () => emptyPortalArchiveLine,
|
|
2261
|
+
entityReferenceKinds: () => entityReferenceKinds,
|
|
2262
|
+
entityReferenceKindsOf: () => entityReferenceKindsOf,
|
|
2263
|
+
entityReferenceWords: () => entityReferenceWords,
|
|
2264
|
+
entityRefsOf: () => entityRefsOf,
|
|
2265
|
+
entityRefsToWrite: () => entityRefsToWrite,
|
|
2260
2266
|
err: () => err,
|
|
2261
2267
|
exampleSpec: () => exampleSpec,
|
|
2262
2268
|
exportPageXlsx: () => exportPageXlsx,
|
|
@@ -2267,16 +2273,24 @@ __export(react_exports, {
|
|
|
2267
2273
|
indexedDbStore: () => indexedDbStore,
|
|
2268
2274
|
isArchiveLane: () => isArchiveLane,
|
|
2269
2275
|
isDecided: () => isDecided,
|
|
2276
|
+
isEntityReferenceConfig: () => isEntityReferenceConfig,
|
|
2270
2277
|
isOwnOp: () => isOwnOp,
|
|
2278
|
+
isPortalAccent: () => isPortalAccent,
|
|
2271
2279
|
isPortalArchiveFilter: () => isPortalArchiveFilter,
|
|
2272
2280
|
isRecordsErr: () => isRecordsErr,
|
|
2281
|
+
isRuleFilter: () => isRuleFilter,
|
|
2273
2282
|
isTheChosen: () => isTheChosen,
|
|
2283
|
+
keptGroups: () => keptGroups,
|
|
2284
|
+
keptOutOfSight: () => keptOutOfSight,
|
|
2285
|
+
keptTableHref: () => keptTableHref,
|
|
2274
2286
|
looksLikeAnId: () => looksLikeAnId,
|
|
2275
2287
|
mayDrag: () => mayDrag,
|
|
2276
2288
|
measureKey: () => measureKey,
|
|
2277
2289
|
memoryStore: () => memoryStore,
|
|
2278
2290
|
mintClientKey: () => mintClientKey,
|
|
2279
2291
|
mintOpId: () => mintOpId,
|
|
2292
|
+
moveInOrder: () => moveInOrder,
|
|
2293
|
+
offeredAsContext: () => offeredAsContext,
|
|
2280
2294
|
ok: () => ok,
|
|
2281
2295
|
openCaptureQueue: () => openCaptureQueue,
|
|
2282
2296
|
optionKey: () => optionKey,
|
|
@@ -2290,12 +2304,15 @@ __export(react_exports, {
|
|
|
2290
2304
|
rememberedOpCount: () => rememberedOpCount,
|
|
2291
2305
|
sameDocument: () => sameDocument,
|
|
2292
2306
|
scopeChip: () => scopeChip,
|
|
2307
|
+
sheetSyncSpec: () => sheetSyncSpec,
|
|
2293
2308
|
stableFilterKey: () => stableFilterKey,
|
|
2294
2309
|
tableShapeChanged: () => tableShapeChanged,
|
|
2295
2310
|
useEntityFieldMutation: () => useEntityFieldMutation,
|
|
2296
2311
|
useEntityFieldRights: () => useEntityFieldRights,
|
|
2297
2312
|
useEntityFields: () => useEntityFields,
|
|
2298
2313
|
useEntityRecord: () => useEntityRecord,
|
|
2314
|
+
useEntityReferenceKinds: () => useEntityReferenceKinds,
|
|
2315
|
+
useEntityReferenceWords: () => useEntityReferenceWords,
|
|
2299
2316
|
useEntityTable: () => useEntityTable,
|
|
2300
2317
|
useFieldMutation: () => useFieldMutation,
|
|
2301
2318
|
useFields: () => useFields,
|
|
@@ -2311,7 +2328,9 @@ __export(react_exports, {
|
|
|
2311
2328
|
useRecordsClient: () => useRecordsClient,
|
|
2312
2329
|
useTable: () => useTable,
|
|
2313
2330
|
useTableArchive: () => useTableArchive,
|
|
2314
|
-
useTables: () => useTables
|
|
2331
|
+
useTables: () => useTables,
|
|
2332
|
+
withRowCounts: () => withRowCounts,
|
|
2333
|
+
withTablePlacement: () => withTablePlacement
|
|
2315
2334
|
});
|
|
2316
2335
|
module.exports = __toCommonJS(react_exports);
|
|
2317
2336
|
|
|
@@ -2358,6 +2377,31 @@ function sameDocument(a, b) {
|
|
|
2358
2377
|
return JSON.stringify(a) === JSON.stringify(b);
|
|
2359
2378
|
}
|
|
2360
2379
|
|
|
2380
|
+
// src/aggregate.ts
|
|
2381
|
+
function isRuleFilter(filter) {
|
|
2382
|
+
if (!filter || typeof filter !== "object" || Array.isArray(filter)) return false;
|
|
2383
|
+
const node = filter;
|
|
2384
|
+
return typeof node.op === "string" && Array.isArray(node.args);
|
|
2385
|
+
}
|
|
2386
|
+
function measureKey(measure) {
|
|
2387
|
+
return measure.op === "count" ? "count" : `${measure.op}_${measure.key ?? ""}`;
|
|
2388
|
+
}
|
|
2389
|
+
function stableFilterKey(filter) {
|
|
2390
|
+
if (!filter) return "{}";
|
|
2391
|
+
if (isRuleFilter(filter)) return JSON.stringify(filter);
|
|
2392
|
+
const keys = Object.keys(filter).sort();
|
|
2393
|
+
if (keys.length === 0) return "{}";
|
|
2394
|
+
const parts = keys.map((key) => {
|
|
2395
|
+
const value = filter[key];
|
|
2396
|
+
if (value !== null && typeof value === "object") {
|
|
2397
|
+
const window2 = value;
|
|
2398
|
+
return `${JSON.stringify(key)}:{"from":${JSON.stringify(window2.from ?? null)},"to":${JSON.stringify(window2.to ?? null)}}`;
|
|
2399
|
+
}
|
|
2400
|
+
return `${JSON.stringify(key)}:${JSON.stringify(value ?? null)}`;
|
|
2401
|
+
});
|
|
2402
|
+
return `{${parts.join(",")}}`;
|
|
2403
|
+
}
|
|
2404
|
+
|
|
2361
2405
|
// src/ops.ts
|
|
2362
2406
|
var REMEMBER_MS = 3e4;
|
|
2363
2407
|
var REMEMBER_MAX = 500;
|
|
@@ -2513,6 +2557,51 @@ function recordChangeTrigger(tableId, options = {}) {
|
|
|
2513
2557
|
...options.changedFields && options.changedFields.length > 0 ? { changed_fields: options.changedFields } : {}
|
|
2514
2558
|
};
|
|
2515
2559
|
}
|
|
2560
|
+
function sheetSyncSpec(args) {
|
|
2561
|
+
const [header = [], ...body] = args.cells;
|
|
2562
|
+
const columns = header.map((c, i) => {
|
|
2563
|
+
const name = c == null ? "" : String(c).trim();
|
|
2564
|
+
return name === "" ? `Column ${i + 1}` : name;
|
|
2565
|
+
});
|
|
2566
|
+
if (columns.length === 0) {
|
|
2567
|
+
throw new Error("The sheet has no header row, so there are no columns to sync. Nothing was sent.");
|
|
2568
|
+
}
|
|
2569
|
+
const seenCol = /* @__PURE__ */ new Set();
|
|
2570
|
+
for (const c of columns) {
|
|
2571
|
+
if (seenCol.has(c)) throw new Error(`The sheet has two columns named "${c}". Rename one and sync again.`);
|
|
2572
|
+
seenCol.add(c);
|
|
2573
|
+
}
|
|
2574
|
+
const refIdx = args.refColumn == null ? -1 : columns.indexOf(args.refColumn);
|
|
2575
|
+
if (args.refColumn != null && refIdx < 0) {
|
|
2576
|
+
throw new Error(`The id column "${args.refColumn}" is not in the sheet's header. Nothing was sent.`);
|
|
2577
|
+
}
|
|
2578
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2579
|
+
const rows = [];
|
|
2580
|
+
body.forEach((cells, i) => {
|
|
2581
|
+
if (cells.every((v) => v == null || String(v).trim() === "")) return;
|
|
2582
|
+
const ref = refIdx >= 0 ? String(cells[refIdx] ?? "").trim() : `row-${i + 2}`;
|
|
2583
|
+
if (ref === "") throw new Error(`Sheet row ${i + 2} has no value in the id column "${args.refColumn}".`);
|
|
2584
|
+
if (seen.has(ref)) throw new Error(`Two sheet rows share the id "${ref}"; each row needs its own.`);
|
|
2585
|
+
seen.add(ref);
|
|
2586
|
+
const values = {};
|
|
2587
|
+
columns.forEach((c, j) => {
|
|
2588
|
+
const v = cells[j];
|
|
2589
|
+
values[c] = v === void 0 || v === "" ? null : v;
|
|
2590
|
+
});
|
|
2591
|
+
rows.push({ ref, values });
|
|
2592
|
+
});
|
|
2593
|
+
return { source: args.source, table_name: args.tableName, columns, rows };
|
|
2594
|
+
}
|
|
2595
|
+
function withRowCounts(tables, counts) {
|
|
2596
|
+
if (!counts) return [...tables];
|
|
2597
|
+
const byId = new Map(counts.map((c) => [c.table_id, Number(c.visible_rows)]));
|
|
2598
|
+
return tables.map((t) => byId.has(t.id) ? { ...t, row_count: byId.get(t.id) } : t);
|
|
2599
|
+
}
|
|
2600
|
+
function moveInOrder(order, moved, toIndex) {
|
|
2601
|
+
const rest = order.filter((id) => id !== moved);
|
|
2602
|
+
const at = Math.max(0, Math.min(Math.trunc(toIndex), rest.length));
|
|
2603
|
+
return [...rest.slice(0, at), moved, ...rest.slice(at)];
|
|
2604
|
+
}
|
|
2516
2605
|
|
|
2517
2606
|
// src/store.generated.ts
|
|
2518
2607
|
var ACTOR_VOCABULARY = ["user", "agent", "system"];
|
|
@@ -3188,6 +3277,7 @@ var STORE_DOORS = [
|
|
|
3188
3277
|
{ name: "table_work_kind", args: "p_organization_id uuid, p_table_id uuid", returns: "text", security: "invoker" },
|
|
3189
3278
|
{ name: "tables_at_home", args: "p_organization_id uuid, p_home_ids uuid[]", returns: "TABLE(table_id uuid, home_record_id uuid, kind text)", security: "definer" },
|
|
3190
3279
|
{ name: "tables_described_without_asking", args: "", returns: "TABLE(function_name text, identity_args text, why text)", security: "invoker" },
|
|
3280
|
+
{ name: "tables_i_can_open", args: "", returns: "TABLE(table_id uuid, table_name text, organization_id uuid, organization_name text, member boolean, visibility text, updated_at timestamp with time zone)", security: "definer" },
|
|
3191
3281
|
{ name: "tables_shared_with_me", args: "", returns: "TABLE(table_id uuid, organization_id uuid, organization text, table_name text, level text, level_label text, shared_at timestamp with time zone, opens boolean, say text)", security: "definer" },
|
|
3192
3282
|
{ name: "trg_associations_bump_visibility", args: "", returns: "trigger", security: "definer" },
|
|
3193
3283
|
{ name: "undeclared_keys", args: "p_organization_id uuid, p_table_id uuid, p_data jsonb", returns: "text[]", security: "invoker" },
|
|
@@ -3212,6 +3302,7 @@ var STORE_DOORS = [
|
|
|
3212
3302
|
{ name: "visible_predicate_sql", args: "p_user uuid, p_organization_id uuid, p_table_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level, p_alias text DEFAULT 'r'::text", returns: "text", security: "definer" },
|
|
3213
3303
|
{ name: "visible_record_ids", args: "p_user_id uuid, p_required permission_level DEFAULT 'viewer'::permission_level", returns: "TABLE(id uuid)", security: "definer" },
|
|
3214
3304
|
{ name: "visible_set", 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", returns: "record", security: "definer" },
|
|
3305
|
+
{ name: "where_id_opens", args: "p_id uuid", returns: "jsonb", security: "definer" },
|
|
3215
3306
|
{ name: "widget_kernel_id", args: "", returns: "uuid", security: "invoker" },
|
|
3216
3307
|
{ name: "withheld_marker", args: "p_mask jsonb, p_key text", returns: "jsonb", security: "invoker" },
|
|
3217
3308
|
{ name: "withheld_sentence", args: "p_mask jsonb, p_key text", returns: "text", security: "invoker" },
|
|
@@ -3318,7 +3409,7 @@ var STORE_REFUSAL_CODES = [
|
|
|
3318
3409
|
{ code: "23505", raised_by: "_share_write_person,_unique_rule_holds,doc_sign,doc_signature_write,entity_field_declare,field_declare,home_add,inbound_declare,io_proposal_accept,relation_carry,relation_own,sign_request_cancel,sign_request_create,table_share_outside_resend,work_approval_decide,work_slot_hold" },
|
|
3319
3410
|
{ code: "23514", raised_by: "_checklist_instantiate,_checklist_step_guard,_containment_guard,_dated_values_guard,_derived_fields,_display_format_check,_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,_relation_halves_agree,_relation_kernel_targets,_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,action_run,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_comment_write,io_import_rows,migrate_merge,migrate_purge_hard,portal_archive,portal_restore,record_write_graph,relation_carry,relation_halves_repair,relation_own,sign_request_create,sign_request_sign,table_declare,table_from_example,validate_value_envelope,validate_values,work_set_state,work_slots_declare,work_take_assignment,work_template_instantiate" },
|
|
3320
3411
|
{ code: "40001", raised_by: "has_visibility_at" },
|
|
3321
|
-
{ code: "42501", 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" },
|
|
3412
|
+
{ code: "42501", 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" },
|
|
3322
3413
|
{ code: "42703", raised_by: "entity_table,portal_declare" },
|
|
3323
3414
|
{ code: "53400", raised_by: "anon_rate_take,delete_cascade_closure,enrich_due,enrich_land,promote_field" },
|
|
3324
3415
|
{ code: "54000", raised_by: "action_run,hub_changed_by,table_decorate,table_from_example,table_webhook_declare" },
|
|
@@ -4379,6 +4470,20 @@ var OWED_BY = {
|
|
|
4379
4470
|
table_webhook_archive: "GRID-PRIMITIVES G4 \u2014 gridprim_every_row_change_reaches_the_webhook.sql (chair's production apply)",
|
|
4380
4471
|
table_from_example: "GRID-PRIMITIVES G5 \u2014 gridprim_a_table_can_start_from_a_real_example.sql (chair's production apply)",
|
|
4381
4472
|
autonumber_backfill: "GRID-PRIMITIVES G5 \u2014 gridprim_a_table_can_start_from_a_real_example.sql (chair's production apply)",
|
|
4473
|
+
table_list_everywhere: "GRID-PRIMITIVES G9 \u2014 gridprim_every_picker_lists_both_stores.sql (chair's production apply)",
|
|
4474
|
+
table_sync: "GRID-PRIMITIVES G10 \u2014 gridprim_a_synced_sheet_is_one_table_that_refreshes.sql (chair's production apply)",
|
|
4475
|
+
scope_table_provision: "GRID-PRIMITIVES G11 \u2014 gridprim_a_scope_provisions_its_table_in_the_store.sql (chair's production apply)",
|
|
4476
|
+
table_row_counts: "GRID-PRIMITIVES G12 \u2014 gridprim_every_table_counts_its_rows_and_every_row_shows_its_header.sql + its grant file (chair's production apply)",
|
|
4477
|
+
view_record_order_set: "GRID-PRIMITIVES G13 \u2014 gridprim_a_view_keeps_the_order_a_person_dragged.sql + its grant file (chair's production apply)",
|
|
4478
|
+
table_share_outside_grant: "GRID-PRIMITIVES G14 \u2014 gridprim_a_known_outsider_is_granted_at_once.sql + gridprim_a_signed_in_person_may_share_with_a_known_outsider.sql (chair's production apply)",
|
|
4479
|
+
read_records_in_view_order: "GRID-PRIMITIVES G13 \u2014 gridprim_a_view_keeps_the_order_a_person_dragged.sql + its grant file (chair's production apply)",
|
|
4480
|
+
rule_members_visible: "S2-PRIME FILTER-GROUPS \u2014 filtergroups_a_views_nested_question_is_one_where_clause.sql + its grant file (chair's production apply)",
|
|
4481
|
+
record_headers: "GRID-PRIMITIVES G12 \u2014 gridprim_every_table_counts_its_rows_and_every_row_shows_its_header.sql + its grant file (chair's production apply)",
|
|
4482
|
+
pipeline_move_many: "UI-CHAMPIONS S4 \u2014 uichamp_s4_a_selection_moves_and_decides_in_one_call.sql + its grant file (chair's production apply)",
|
|
4483
|
+
work_decide_many: "UI-CHAMPIONS S4 \u2014 uichamp_s4_a_selection_moves_and_decides_in_one_call.sql + its grant file (chair's production apply)",
|
|
4484
|
+
portal_form: "UI-CHAMPIONS S6 \u2014 uichamp_s6_a_portal_carries_its_look_and_its_forms.sql + uichamp_s6_a_signed_in_person_may_open_a_portals_look_and_forms.sql (chair's production apply)",
|
|
4485
|
+
portal_form_submit: "UI-CHAMPIONS S6 \u2014 uichamp_s6_a_portal_carries_its_look_and_its_forms.sql + uichamp_s6_a_signed_in_person_may_open_a_portals_look_and_forms.sql (chair's production apply)",
|
|
4486
|
+
form_preview_asks: "FORMS-FIX-1 \u2014 formsfix1_the_owners_preview_asks_the_store_the_same_question.sql + its grant file (chair's production apply)",
|
|
4382
4487
|
rule_declare: "W1-RULE \u2014 `custom.record_write` writes `data_class = 'record'`, so the ONE write door cannot make a Rule record; declaring a Rule (and therefore a DOOR-18 subscription) needs a door of its own"
|
|
4383
4488
|
};
|
|
4384
4489
|
var TRUST_SCHEMA = "iam";
|
|
@@ -4582,6 +4687,8 @@ var DOORS = {
|
|
|
4582
4687
|
pipelineBoard: "pipeline_board",
|
|
4583
4688
|
pipelineTransitionRefusal: "pipeline_transition_refusal",
|
|
4584
4689
|
pipelineMove: "pipeline_move",
|
|
4690
|
+
/** Lane S4: many cards, one call, a verdict and a version per card. */
|
|
4691
|
+
pipelineMoveMany: "pipeline_move_many",
|
|
4585
4692
|
tableStageField: "table_stage_field",
|
|
4586
4693
|
// STAGE-RULES. A gate can refuse or it can hand the change to the approvals queue; the
|
|
4587
4694
|
// closed list is the store's, the knob is the organization's, and what is WAITING on a
|
|
@@ -4592,6 +4699,7 @@ var DOORS = {
|
|
|
4592
4699
|
pipelinePending: "pipeline_pending",
|
|
4593
4700
|
pipelineGatePreview: "pipeline_gate_preview",
|
|
4594
4701
|
ruleMembers: "rule_members",
|
|
4702
|
+
ruleMembersVisible: "rule_members_visible",
|
|
4595
4703
|
ruleMembership: "rule_membership",
|
|
4596
4704
|
ruleRun: "rule_run",
|
|
4597
4705
|
ruleEval: "rule_eval",
|
|
@@ -4606,6 +4714,12 @@ var DOORS = {
|
|
|
4606
4714
|
// are server-lane doors and a browser never calls them.
|
|
4607
4715
|
forms: "forms",
|
|
4608
4716
|
formDeclare: "form_declare",
|
|
4717
|
+
/**
|
|
4718
|
+
* WHICH QUESTIONS THE OWNER'S PREVIEW ASKS NEXT (lane FORMS-FIX-1). The same store answer a
|
|
4719
|
+
* stranger's form gets (`custom._form_questions_asked` → `custom.rule_eval`), behind the
|
|
4720
|
+
* organization wall and the caller's own rung on the Table — never `rule_eval` from a browser.
|
|
4721
|
+
*/
|
|
4722
|
+
formPreviewAsks: "form_preview_asks",
|
|
4609
4723
|
// PRODUCTS row 14 — "let clients book a 30-minute consult". A booking page IS an
|
|
4610
4724
|
// `anon_form`, so it is opened and closed by `anonPublish` like any other; this is
|
|
4611
4725
|
// the owner's list of them with the numbers that make it worth opening. The
|
|
@@ -4665,6 +4779,11 @@ var DOORS = {
|
|
|
4665
4779
|
portalInvite: "portal_invite",
|
|
4666
4780
|
portalRevoke: "portal_revoke",
|
|
4667
4781
|
portalPreview: "portal_preview",
|
|
4782
|
+
// S6 — the CLIENT's two form doors. They are store doors (schema `custom`), called by a
|
|
4783
|
+
// signed-in portal principal, and each refuses anybody who is not a live principal of that
|
|
4784
|
+
// live portal — so, unlike the sign-in pair above, they belong in this table.
|
|
4785
|
+
portalForm: "portal_form",
|
|
4786
|
+
portalFormSubmit: "portal_form_submit",
|
|
4668
4787
|
// ORG-CLEANUP, 2026-09-22 — A PORTAL IS ARCHIVED, NEVER DELETED.
|
|
4669
4788
|
// `portals` keeps its signature and HIDES archived portals (the law's default
|
|
4670
4789
|
// is to hide); `list_portals(org, 'active'|'archived'|'all')` is the
|
|
@@ -4860,6 +4979,8 @@ var DOORS = {
|
|
|
4860
4979
|
workApprovalRequest: "work_approval_request",
|
|
4861
4980
|
workApprovalMayDecide: "work_approval_may_decide",
|
|
4862
4981
|
workApprovalDecide: "work_approval_decide",
|
|
4982
|
+
/** Lane S4: many inbox decisions, one call, a verdict per item. */
|
|
4983
|
+
workDecideMany: "work_decide_many",
|
|
4863
4984
|
workApprovalRead: "work_approval_read",
|
|
4864
4985
|
// PRODUCTS row 13 — checklists and SOP runs.
|
|
4865
4986
|
checklistRefusal: "checklist_refusal",
|
|
@@ -4885,6 +5006,14 @@ var DOORS = {
|
|
|
4885
5006
|
tableFromExample: "table_from_example",
|
|
4886
5007
|
autonumberBackfill: "autonumber_backfill",
|
|
4887
5008
|
ioExport: "io_export",
|
|
5009
|
+
tableListEverywhere: "table_list_everywhere",
|
|
5010
|
+
tableSync: "table_sync",
|
|
5011
|
+
scopeTableProvision: "scope_table_provision",
|
|
5012
|
+
tableRowCounts: "table_row_counts",
|
|
5013
|
+
recordHeaders: "record_headers",
|
|
5014
|
+
viewRecordOrderSet: "view_record_order_set",
|
|
5015
|
+
readRecordsInViewOrder: "read_records_in_view_order",
|
|
5016
|
+
tableShareOutsideGrant: "table_share_outside_grant",
|
|
4888
5017
|
// Declared here BECAUSE they do not exist yet: naming them is what makes the
|
|
4889
5018
|
// absence visible to `pnpm check:store-registry` and to the suite.
|
|
4890
5019
|
metadataSearch: "metadata_search",
|
|
@@ -5664,10 +5793,11 @@ function createRecordsClient(config) {
|
|
|
5664
5793
|
"pipelineRead"
|
|
5665
5794
|
);
|
|
5666
5795
|
},
|
|
5667
|
-
async pipelineBoard({ table_id, measure }) {
|
|
5796
|
+
async pipelineBoard({ table_id, measure, filter }) {
|
|
5797
|
+
const asked = filter && stableFilterKey(filter) !== "{}";
|
|
5668
5798
|
return callDoor(
|
|
5669
5799
|
DOORS.pipelineBoard,
|
|
5670
|
-
{ p_organization_id: org, p_table_id: table_id, p_measure: measure ?? null },
|
|
5800
|
+
asked ? { p_organization_id: org, p_table_id: table_id, p_measure: measure ?? null, p_filter: filter } : { p_organization_id: org, p_table_id: table_id, p_measure: measure ?? null },
|
|
5671
5801
|
"pipelineBoard"
|
|
5672
5802
|
);
|
|
5673
5803
|
},
|
|
@@ -5691,6 +5821,13 @@ function createRecordsClient(config) {
|
|
|
5691
5821
|
"pipelineMove"
|
|
5692
5822
|
);
|
|
5693
5823
|
},
|
|
5824
|
+
async pipelineMoveMany({ moves }) {
|
|
5825
|
+
return callDoor(
|
|
5826
|
+
DOORS.pipelineMoveMany,
|
|
5827
|
+
{ p_organization_id: org, p_moves: moves },
|
|
5828
|
+
"pipelineMoveMany"
|
|
5829
|
+
);
|
|
5830
|
+
},
|
|
5694
5831
|
async pipelineDeclare({ table_id, spec }) {
|
|
5695
5832
|
return callDoor(
|
|
5696
5833
|
DOORS.pipelineDeclare,
|
|
@@ -5740,6 +5877,18 @@ function createRecordsClient(config) {
|
|
|
5740
5877
|
"pipelineGatePreview"
|
|
5741
5878
|
);
|
|
5742
5879
|
},
|
|
5880
|
+
async ruleMembersVisible({ rule_id, limit = 200, offset = 0 }) {
|
|
5881
|
+
const door = await callDoor(
|
|
5882
|
+
DOORS.ruleMembersVisible,
|
|
5883
|
+
{ p_organization_id: org, p_rule_id: rule_id, p_limit: limit, p_offset: offset },
|
|
5884
|
+
"ruleMembersVisible"
|
|
5885
|
+
);
|
|
5886
|
+
if (!door.ok) return err(door.error);
|
|
5887
|
+
return ok((door.data ?? []).map((row) => {
|
|
5888
|
+
const { document, hidden } = unfold(row.document);
|
|
5889
|
+
return { id: row.id, document, level: row.level, hidden };
|
|
5890
|
+
}));
|
|
5891
|
+
},
|
|
5743
5892
|
async ruleMembers({ rule_id }) {
|
|
5744
5893
|
return callDoor(
|
|
5745
5894
|
DOORS.ruleMembers,
|
|
@@ -5792,6 +5941,13 @@ function createRecordsClient(config) {
|
|
|
5792
5941
|
"bookingDeclare"
|
|
5793
5942
|
);
|
|
5794
5943
|
},
|
|
5944
|
+
async formPreviewAsks({ table_id, questions, values }) {
|
|
5945
|
+
return callDoor(
|
|
5946
|
+
DOORS.formPreviewAsks,
|
|
5947
|
+
{ p_organization_id: org, p_table_id: table_id, p_questions: questions, p_values: values },
|
|
5948
|
+
"formPreviewAsks"
|
|
5949
|
+
);
|
|
5950
|
+
},
|
|
5795
5951
|
async formDeclare(args) {
|
|
5796
5952
|
return callDoor(
|
|
5797
5953
|
DOORS.formDeclare,
|
|
@@ -5967,11 +6123,33 @@ function createRecordsClient(config) {
|
|
|
5967
6123
|
p_tables: args.tables,
|
|
5968
6124
|
p_portal_id: args.portal_id ?? null,
|
|
5969
6125
|
p_slug: args.slug ?? null,
|
|
5970
|
-
p_sign_in_method: args.sign_in_method ?? "magic_link"
|
|
6126
|
+
p_sign_in_method: args.sign_in_method ?? "magic_link",
|
|
6127
|
+
// S6: sent only when given, so a caller that says nothing about the look keeps it.
|
|
6128
|
+
...args.config !== void 0 ? { p_config: args.config } : {}
|
|
5971
6129
|
},
|
|
5972
6130
|
"portalDeclare"
|
|
5973
6131
|
);
|
|
5974
6132
|
},
|
|
6133
|
+
async portalForm({ portal_id, form_id }) {
|
|
6134
|
+
return callDoor(
|
|
6135
|
+
DOORS.portalForm,
|
|
6136
|
+
{ p_organization_id: org, p_portal_id: portal_id, p_form_id: form_id },
|
|
6137
|
+
"portalForm"
|
|
6138
|
+
);
|
|
6139
|
+
},
|
|
6140
|
+
async portalFormSubmit({ portal_id, form_id, answers, client_key }) {
|
|
6141
|
+
return callDoor(
|
|
6142
|
+
DOORS.portalFormSubmit,
|
|
6143
|
+
{
|
|
6144
|
+
p_organization_id: org,
|
|
6145
|
+
p_portal_id: portal_id,
|
|
6146
|
+
p_form_id: form_id,
|
|
6147
|
+
p_payload: answers,
|
|
6148
|
+
p_client_key: client_key ?? null
|
|
6149
|
+
},
|
|
6150
|
+
"portalFormSubmit"
|
|
6151
|
+
);
|
|
6152
|
+
},
|
|
5975
6153
|
async portalInvite(args) {
|
|
5976
6154
|
return callDoor(
|
|
5977
6155
|
DOORS.portalInvite,
|
|
@@ -6170,10 +6348,17 @@ function createRecordsClient(config) {
|
|
|
6170
6348
|
"dashboardDeclare"
|
|
6171
6349
|
);
|
|
6172
6350
|
},
|
|
6173
|
-
async dashboardRun({ dashboard_id, filter }) {
|
|
6351
|
+
async dashboardRun({ dashboard_id, filter, compare, grain }) {
|
|
6174
6352
|
return callDoor(
|
|
6175
6353
|
DOORS.dashboardRun,
|
|
6176
|
-
{
|
|
6354
|
+
{
|
|
6355
|
+
p_organization_id: org,
|
|
6356
|
+
p_dashboard_id: dashboard_id,
|
|
6357
|
+
p_filter: filter ?? {},
|
|
6358
|
+
// Sent only when asked, so a caller that never compares calls exactly what it did.
|
|
6359
|
+
...compare ? { p_compare: compare } : {},
|
|
6360
|
+
...grain ? { p_grain: grain } : {}
|
|
6361
|
+
},
|
|
6177
6362
|
"dashboardRun"
|
|
6178
6363
|
);
|
|
6179
6364
|
},
|
|
@@ -6198,7 +6383,7 @@ function createRecordsClient(config) {
|
|
|
6198
6383
|
"dashboardDelete"
|
|
6199
6384
|
);
|
|
6200
6385
|
},
|
|
6201
|
-
async recordAggregate({ table_id, groupBy, measures, bucket, filter, limit }) {
|
|
6386
|
+
async recordAggregate({ table_id, groupBy, measures, bucket, filter, limit, compare }) {
|
|
6202
6387
|
return callDoor(
|
|
6203
6388
|
DOORS.recordAggregate,
|
|
6204
6389
|
{
|
|
@@ -6208,7 +6393,8 @@ function createRecordsClient(config) {
|
|
|
6208
6393
|
p_measures: measures ?? [],
|
|
6209
6394
|
p_bucket: bucket ?? null,
|
|
6210
6395
|
p_filter: filter ?? {},
|
|
6211
|
-
p_limit: limit ?? 200
|
|
6396
|
+
p_limit: limit ?? 200,
|
|
6397
|
+
...compare ? { p_compare: compare } : {}
|
|
6212
6398
|
},
|
|
6213
6399
|
"recordAggregate"
|
|
6214
6400
|
);
|
|
@@ -6936,6 +7122,13 @@ function createRecordsClient(config) {
|
|
|
6936
7122
|
"workApprovalDecide"
|
|
6937
7123
|
);
|
|
6938
7124
|
},
|
|
7125
|
+
async workDecideMany({ decisions }) {
|
|
7126
|
+
return callDoor(
|
|
7127
|
+
DOORS.workDecideMany,
|
|
7128
|
+
{ p_organization_id: org, p_decisions: decisions },
|
|
7129
|
+
"workDecideMany"
|
|
7130
|
+
);
|
|
7131
|
+
},
|
|
6939
7132
|
async workApprovalRead({ approval_id }) {
|
|
6940
7133
|
return callDoor(
|
|
6941
7134
|
DOORS.workApprovalRead,
|
|
@@ -7139,6 +7332,69 @@ function createRecordsClient(config) {
|
|
|
7139
7332
|
"tableFromExample"
|
|
7140
7333
|
);
|
|
7141
7334
|
},
|
|
7335
|
+
async tableListEverywhere() {
|
|
7336
|
+
return callDoor(
|
|
7337
|
+
DOORS.tableListEverywhere,
|
|
7338
|
+
{ p_organization_id: org },
|
|
7339
|
+
"tableListEverywhere"
|
|
7340
|
+
);
|
|
7341
|
+
},
|
|
7342
|
+
async tableSync({ home_id, spec }) {
|
|
7343
|
+
return callDoor(
|
|
7344
|
+
DOORS.tableSync,
|
|
7345
|
+
{ p_organization_id: org, p_home_id: home_id, p_spec: spec },
|
|
7346
|
+
"tableSync"
|
|
7347
|
+
);
|
|
7348
|
+
},
|
|
7349
|
+
async scopeTableProvision({ home_id, item_id, scope_id }) {
|
|
7350
|
+
return callDoor(
|
|
7351
|
+
DOORS.scopeTableProvision,
|
|
7352
|
+
{ p_organization_id: org, p_item_id: item_id, p_scope_id: scope_id, p_home_id: home_id ?? null },
|
|
7353
|
+
"scopeTableProvision"
|
|
7354
|
+
);
|
|
7355
|
+
},
|
|
7356
|
+
async tableRowCounts({ table_ids }) {
|
|
7357
|
+
return callDoor(
|
|
7358
|
+
DOORS.tableRowCounts,
|
|
7359
|
+
{ p_organization_id: org, p_table_ids: table_ids },
|
|
7360
|
+
"tableRowCounts"
|
|
7361
|
+
);
|
|
7362
|
+
},
|
|
7363
|
+
async recordHeaders({ ids }) {
|
|
7364
|
+
return callDoor(
|
|
7365
|
+
DOORS.recordHeaders,
|
|
7366
|
+
{ p_organization_id: org, p_ids: ids },
|
|
7367
|
+
"recordHeaders"
|
|
7368
|
+
);
|
|
7369
|
+
},
|
|
7370
|
+
async tableShareOutsideGrant({ table_id, person, level }) {
|
|
7371
|
+
return callDoor(
|
|
7372
|
+
DOORS.tableShareOutsideGrant,
|
|
7373
|
+
{ p_organization_id: org, p_table_id: table_id, p_person: person, p_level: level ?? "viewer" },
|
|
7374
|
+
"tableShareOutsideGrant"
|
|
7375
|
+
);
|
|
7376
|
+
},
|
|
7377
|
+
async viewRecordOrderSet({ view_id, record_ids }) {
|
|
7378
|
+
return callDoor(
|
|
7379
|
+
DOORS.viewRecordOrderSet,
|
|
7380
|
+
{ p_organization_id: org, p_view_id: view_id, p_record_ids: record_ids },
|
|
7381
|
+
"viewRecordOrderSet"
|
|
7382
|
+
);
|
|
7383
|
+
},
|
|
7384
|
+
async readInViewOrder({ view_id, limit, offset }) {
|
|
7385
|
+
const door = await callDoor(
|
|
7386
|
+
DOORS.readRecordsInViewOrder,
|
|
7387
|
+
{ p_organization_id: org, p_view_id: view_id, p_by_id: false, p_limit: limit ?? 200, p_offset: offset ?? 0 },
|
|
7388
|
+
"readInViewOrder"
|
|
7389
|
+
);
|
|
7390
|
+
if (!door.ok) return err(door.error);
|
|
7391
|
+
return ok(
|
|
7392
|
+
(door.data ?? []).map((row) => {
|
|
7393
|
+
const { document, hidden } = unfold(row.document);
|
|
7394
|
+
return { id: row.id, document, level: row.level, hidden, position: row.position ?? null };
|
|
7395
|
+
})
|
|
7396
|
+
);
|
|
7397
|
+
},
|
|
7142
7398
|
async autonumberBackfill({ field_id }) {
|
|
7143
7399
|
return callDoor(
|
|
7144
7400
|
DOORS.autonumberBackfill,
|
|
@@ -7233,27 +7489,6 @@ function useRecordsActor() {
|
|
|
7233
7489
|
|
|
7234
7490
|
// src/react/hooks.ts
|
|
7235
7491
|
var import_react2 = require("react");
|
|
7236
|
-
|
|
7237
|
-
// src/aggregate.ts
|
|
7238
|
-
function measureKey(measure) {
|
|
7239
|
-
return measure.op === "count" ? "count" : `${measure.op}_${measure.key ?? ""}`;
|
|
7240
|
-
}
|
|
7241
|
-
function stableFilterKey(filter) {
|
|
7242
|
-
if (!filter) return "{}";
|
|
7243
|
-
const keys = Object.keys(filter).sort();
|
|
7244
|
-
if (keys.length === 0) return "{}";
|
|
7245
|
-
const parts = keys.map((key) => {
|
|
7246
|
-
const value = filter[key];
|
|
7247
|
-
if (value !== null && typeof value === "object") {
|
|
7248
|
-
const window2 = value;
|
|
7249
|
-
return `${JSON.stringify(key)}:{"from":${JSON.stringify(window2.from ?? null)},"to":${JSON.stringify(window2.to ?? null)}}`;
|
|
7250
|
-
}
|
|
7251
|
-
return `${JSON.stringify(key)}:${JSON.stringify(value ?? null)}`;
|
|
7252
|
-
});
|
|
7253
|
-
return `{${parts.join(",")}}`;
|
|
7254
|
-
}
|
|
7255
|
-
|
|
7256
|
-
// src/react/hooks.ts
|
|
7257
7492
|
function useAsync(run, deps) {
|
|
7258
7493
|
const client = useRecordsClient();
|
|
7259
7494
|
const [state, setState] = (0, import_react2.useState)(
|
|
@@ -7733,6 +7968,88 @@ function useMergeField(key, state) {
|
|
|
7733
7968
|
return resolution;
|
|
7734
7969
|
}
|
|
7735
7970
|
|
|
7971
|
+
// src/react/entity-reference.ts
|
|
7972
|
+
var import_react3 = require("react");
|
|
7973
|
+
|
|
7974
|
+
// src/relation.ts
|
|
7975
|
+
var ENTITY_REF_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
7976
|
+
function isRefLike(value) {
|
|
7977
|
+
return typeof value === "object" && value !== null && "token" in value && "id" in value;
|
|
7978
|
+
}
|
|
7979
|
+
function entityRefsOf(value) {
|
|
7980
|
+
const items = Array.isArray(value) ? value : value == null ? [] : [value];
|
|
7981
|
+
const out = [];
|
|
7982
|
+
for (const item of items) {
|
|
7983
|
+
if (!isRefLike(item)) continue;
|
|
7984
|
+
const token = String(item.token ?? "").trim().toLowerCase();
|
|
7985
|
+
const id = String(item.id ?? "").trim();
|
|
7986
|
+
if (!token || !ENTITY_REF_ID.test(id)) continue;
|
|
7987
|
+
const label = item.label;
|
|
7988
|
+
out.push({ token, id: id.toLowerCase(), label: typeof label === "string" ? label : null });
|
|
7989
|
+
}
|
|
7990
|
+
return out;
|
|
7991
|
+
}
|
|
7992
|
+
function entityRefsToWrite(value, multi) {
|
|
7993
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7994
|
+
const refs = [];
|
|
7995
|
+
for (const ref of entityRefsOf(value)) {
|
|
7996
|
+
const k = `${ref.token}:${ref.id}`;
|
|
7997
|
+
if (seen.has(k)) continue;
|
|
7998
|
+
seen.add(k);
|
|
7999
|
+
refs.push({ token: ref.token, id: ref.id });
|
|
8000
|
+
}
|
|
8001
|
+
if (multi) return refs;
|
|
8002
|
+
return refs[0] ?? null;
|
|
8003
|
+
}
|
|
8004
|
+
async function entityReferenceKinds(source) {
|
|
8005
|
+
const { data, error } = await source.rpc("entity_reference_kinds", {}, { schema: "custom" });
|
|
8006
|
+
if (error) return err(mapPgError(error, "entityReferenceKinds"));
|
|
8007
|
+
return ok(Array.isArray(data) ? data : []);
|
|
8008
|
+
}
|
|
8009
|
+
async function entityReferenceWords(source, organizationId, refs) {
|
|
8010
|
+
if (refs.length === 0) return ok([]);
|
|
8011
|
+
const { data, error } = await source.rpc(
|
|
8012
|
+
"entity_reference_words",
|
|
8013
|
+
{ p_organization_id: organizationId, p_refs: refs.map((r) => ({ token: r.token, id: r.id })) },
|
|
8014
|
+
{ schema: "custom" }
|
|
8015
|
+
);
|
|
8016
|
+
if (error) return err(mapPgError(error, "entityReferenceWords"));
|
|
8017
|
+
return ok(entityRefsOf(data));
|
|
8018
|
+
}
|
|
8019
|
+
|
|
8020
|
+
// src/react/entity-reference.ts
|
|
8021
|
+
function useEntityReferenceKinds() {
|
|
8022
|
+
const client = useRecordsClient();
|
|
8023
|
+
const [state, setState] = (0, import_react3.useState)({ data: null, loading: true, error: null });
|
|
8024
|
+
(0, import_react3.useEffect)(() => {
|
|
8025
|
+
let live = true;
|
|
8026
|
+
void entityReferenceKinds(client.config.dataSource).then((res) => {
|
|
8027
|
+
if (!live) return;
|
|
8028
|
+
setState(res.ok ? { data: res.data, loading: false, error: null } : { data: null, loading: false, error: res.error });
|
|
8029
|
+
});
|
|
8030
|
+
return () => {
|
|
8031
|
+
live = false;
|
|
8032
|
+
};
|
|
8033
|
+
}, [client]);
|
|
8034
|
+
return state;
|
|
8035
|
+
}
|
|
8036
|
+
function useEntityReferenceWords(refs) {
|
|
8037
|
+
const client = useRecordsClient();
|
|
8038
|
+
const key = refs.map((r) => `${r.token}:${r.id}`).join(",");
|
|
8039
|
+
const [state, setState] = (0, import_react3.useState)({ data: null, loading: refs.length > 0, error: null });
|
|
8040
|
+
(0, import_react3.useEffect)(() => {
|
|
8041
|
+
let live = true;
|
|
8042
|
+
void entityReferenceWords(client.config.dataSource, client.config.organizationId, refs).then((res) => {
|
|
8043
|
+
if (!live) return;
|
|
8044
|
+
setState(res.ok ? { data: res.data, loading: false, error: null } : { data: null, loading: false, error: res.error });
|
|
8045
|
+
});
|
|
8046
|
+
return () => {
|
|
8047
|
+
live = false;
|
|
8048
|
+
};
|
|
8049
|
+
}, [client, key]);
|
|
8050
|
+
return state;
|
|
8051
|
+
}
|
|
8052
|
+
|
|
7736
8053
|
// src/vocabulary.ts
|
|
7737
8054
|
var TABLE_TYPES = [
|
|
7738
8055
|
"entity",
|
|
@@ -7844,6 +8161,7 @@ var FIELD_KINDS = [
|
|
|
7844
8161
|
"currency",
|
|
7845
8162
|
"datetime",
|
|
7846
8163
|
"email",
|
|
8164
|
+
"entity_reference",
|
|
7847
8165
|
"formula",
|
|
7848
8166
|
"json",
|
|
7849
8167
|
"long_text",
|
|
@@ -7882,6 +8200,7 @@ function fieldKindFor(field, kernel) {
|
|
|
7882
8200
|
case "list":
|
|
7883
8201
|
return field.multi ? "multi_select" : "select";
|
|
7884
8202
|
case "relation": {
|
|
8203
|
+
if (isEntityReferenceConfig(config)) return "entity_reference";
|
|
7885
8204
|
const parity = String(config["parity"] ?? "");
|
|
7886
8205
|
if (parity === "attachment" || parity === "member") return parity;
|
|
7887
8206
|
if (kernel?.file && field.relation_target === kernel.file) return "attachment";
|
|
@@ -7899,6 +8218,14 @@ function fieldKindFor(field, kernel) {
|
|
|
7899
8218
|
}
|
|
7900
8219
|
}
|
|
7901
8220
|
var UUID_TEXT = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
8221
|
+
function isEntityReferenceConfig(config) {
|
|
8222
|
+
const allowed = config?.["allowed_types"];
|
|
8223
|
+
return Array.isArray(allowed) && allowed.length > 0;
|
|
8224
|
+
}
|
|
8225
|
+
function entityReferenceKindsOf(field) {
|
|
8226
|
+
const allowed = field.config?.["allowed_types"];
|
|
8227
|
+
return Array.isArray(allowed) ? allowed.map((k) => String(k).trim().toLowerCase()).filter(Boolean) : [];
|
|
8228
|
+
}
|
|
7902
8229
|
var TRUE_WORDS = /* @__PURE__ */ new Set(["true", "yes", "y", "1", "\u2713", "x", "checked", "on"]);
|
|
7903
8230
|
var FALSE_WORDS = /* @__PURE__ */ new Set(["false", "no", "n", "0", "", "unchecked", "off"]);
|
|
7904
8231
|
function coercionLabel(field) {
|
|
@@ -8014,6 +8341,23 @@ function coerceTypedAnswer(field, raw, opts = {}) {
|
|
|
8014
8341
|
return {
|
|
8015
8342
|
refusal: `${label} points at another record, so it is chosen rather than typed. Open it and pick the record.`
|
|
8016
8343
|
};
|
|
8344
|
+
// SC-R / P12. An entity reference names a platform thing by kind and id.
|
|
8345
|
+
// An import or an agent may hand over `note:<id>` — or a bare id when the
|
|
8346
|
+
// column allows exactly one kind; the store then decides whether the thing
|
|
8347
|
+
// is there and whether the writer may open it. Words are chosen, not typed.
|
|
8348
|
+
case "entity_reference": {
|
|
8349
|
+
const allowed = entityReferenceKindsOf(field);
|
|
8350
|
+
const [maybeToken, maybeId] = text.includes(":") ? text.split(/:(.*)/s, 2) : ["", text];
|
|
8351
|
+
const token = (maybeToken ?? "").trim().toLowerCase() || (allowed.length === 1 ? allowed[0] : "");
|
|
8352
|
+
const id = (maybeId ?? "").trim();
|
|
8353
|
+
if (token && UUID_TEXT.test(id)) {
|
|
8354
|
+
const ref = { token, id: id.toLowerCase() };
|
|
8355
|
+
return { value: field.multi ? [ref] : ref };
|
|
8356
|
+
}
|
|
8357
|
+
return {
|
|
8358
|
+
refusal: `${label} points at something on the platform, so it is chosen rather than typed. Open it and pick it.`
|
|
8359
|
+
};
|
|
8360
|
+
}
|
|
8017
8361
|
case "formula":
|
|
8018
8362
|
case "lookup":
|
|
8019
8363
|
case "rollup":
|
|
@@ -8070,6 +8414,10 @@ function publicFormPath(formId) {
|
|
|
8070
8414
|
}
|
|
8071
8415
|
|
|
8072
8416
|
// src/portal.ts
|
|
8417
|
+
var PORTAL_ACCENTS = ["slate", "green", "amber", "red", "blue", "violet", "teal"];
|
|
8418
|
+
function isPortalAccent(word) {
|
|
8419
|
+
return typeof word === "string" && PORTAL_ACCENTS.includes(word);
|
|
8420
|
+
}
|
|
8073
8421
|
function portalPath(slug) {
|
|
8074
8422
|
return `/portal/c/${slug}`;
|
|
8075
8423
|
}
|
|
@@ -8092,6 +8440,56 @@ function emptyPortalArchiveLine() {
|
|
|
8092
8440
|
return "No portal of this organization has been archived. A portal you put away waits here until somebody restores it, and nothing is ever destroyed.";
|
|
8093
8441
|
}
|
|
8094
8442
|
|
|
8443
|
+
// src/placement.ts
|
|
8444
|
+
function keptOutOfSight(placement) {
|
|
8445
|
+
return placement?.kept_by_the_app === true;
|
|
8446
|
+
}
|
|
8447
|
+
function offeredAsContext(placement) {
|
|
8448
|
+
return placement?.offered_as_context === true;
|
|
8449
|
+
}
|
|
8450
|
+
function withTablePlacement(tables, facts) {
|
|
8451
|
+
if (!facts) return [...tables];
|
|
8452
|
+
const byId = new Map(facts.map((f) => [f.table_id, f]));
|
|
8453
|
+
return tables.map((table) => {
|
|
8454
|
+
const fact = byId.get(table.id);
|
|
8455
|
+
if (!fact || fact.kept_by_the_app === void 0) return table;
|
|
8456
|
+
return {
|
|
8457
|
+
...table,
|
|
8458
|
+
kept_by_the_app: fact.kept_by_the_app,
|
|
8459
|
+
kept_for: fact.kept_for ?? null,
|
|
8460
|
+
offered_as_context: fact.offered_as_context ?? false,
|
|
8461
|
+
keeper_group: fact.keeper_group ?? null,
|
|
8462
|
+
keeper_says: fact.keeper_says ?? null,
|
|
8463
|
+
used_in_kind: fact.used_in_kind ?? null,
|
|
8464
|
+
used_in_id: fact.used_in_id ?? null,
|
|
8465
|
+
used_in_table_id: fact.used_in_table_id ?? null
|
|
8466
|
+
};
|
|
8467
|
+
});
|
|
8468
|
+
}
|
|
8469
|
+
function keptGroups(tables) {
|
|
8470
|
+
const out = [];
|
|
8471
|
+
const at = /* @__PURE__ */ new Map();
|
|
8472
|
+
for (const table of tables) {
|
|
8473
|
+
if (!keptOutOfSight(table)) continue;
|
|
8474
|
+
const group = table.keeper_group?.trim() || "Kept by the app";
|
|
8475
|
+
let i = at.get(group);
|
|
8476
|
+
if (i === void 0) {
|
|
8477
|
+
i = out.length;
|
|
8478
|
+
at.set(group, i);
|
|
8479
|
+
out.push({ group, tables: [] });
|
|
8480
|
+
}
|
|
8481
|
+
out[i].tables.push(table);
|
|
8482
|
+
}
|
|
8483
|
+
return out;
|
|
8484
|
+
}
|
|
8485
|
+
function keptTableHref(fact, hrefs) {
|
|
8486
|
+
if (fact.used_in_kind === "scope" && fact.used_in_id) return hrefs.scope(fact.used_in_id);
|
|
8487
|
+
if (fact.used_in_kind === "table" && (fact.used_in_table_id || fact.used_in_id)) {
|
|
8488
|
+
return hrefs.table(fact.used_in_table_id || fact.used_in_id);
|
|
8489
|
+
}
|
|
8490
|
+
return hrefs.table(fact.table_id);
|
|
8491
|
+
}
|
|
8492
|
+
|
|
8095
8493
|
// src/capture-queue.ts
|
|
8096
8494
|
var DB_NAME = "matrx-capture";
|
|
8097
8495
|
var DB_VERSION = 1;
|