@ai-matrx/records 0.57.2 → 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 +126 -0
- package/dist/core/index.cjs +643 -168
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +305 -7
- package/dist/core/index.d.ts +305 -7
- package/dist/core/index.js +643 -168
- 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 +432 -47
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +1054 -205
- package/dist/react/index.d.ts +1054 -205
- package/dist/react/index.js +432 -47
- 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",
|
|
@@ -5284,6 +5413,10 @@ function createRecordsClient(config) {
|
|
|
5284
5413
|
})
|
|
5285
5414
|
);
|
|
5286
5415
|
},
|
|
5416
|
+
async tableFacts() {
|
|
5417
|
+
if (!doorExists(DOORS.tableFacts)) return ok(null);
|
|
5418
|
+
return callDoor(DOORS.tableFacts, { p_organization_id: org }, "tableFacts");
|
|
5419
|
+
},
|
|
5287
5420
|
async tableArchived({ table_id }) {
|
|
5288
5421
|
const kernel = await callDoor(DOORS.tableKernelId, {}, "tableArchived.kernel");
|
|
5289
5422
|
if (!kernel.ok) return err(kernel.error);
|
|
@@ -5467,23 +5600,6 @@ function createRecordsClient(config) {
|
|
|
5467
5600
|
const { document } = unfold(row.document);
|
|
5468
5601
|
return { ...document, id: row.id, organization_id: org };
|
|
5469
5602
|
});
|
|
5470
|
-
if (doorExists(DOORS.tableFacts)) {
|
|
5471
|
-
const facts = await callDoor(
|
|
5472
|
-
DOORS.tableFacts,
|
|
5473
|
-
{ p_organization_id: org },
|
|
5474
|
-
"tableList.facts"
|
|
5475
|
-
);
|
|
5476
|
-
if (facts.ok) {
|
|
5477
|
-
const byId = new Map((facts.data ?? []).map((f) => [f.table_id, f]));
|
|
5478
|
-
const me = config.actor.user_id ?? null;
|
|
5479
|
-
for (const table of tables) {
|
|
5480
|
-
const fact = byId.get(table.id);
|
|
5481
|
-
if (!fact) continue;
|
|
5482
|
-
table.visibility = fact.visibility;
|
|
5483
|
-
if (fact.mine && me) table.created_by = me;
|
|
5484
|
-
}
|
|
5485
|
-
}
|
|
5486
|
-
}
|
|
5487
5603
|
tables.sort((a, b) => (a.name ?? "").localeCompare(b.name ?? ""));
|
|
5488
5604
|
return ok(tables);
|
|
5489
5605
|
},
|
|
@@ -5677,10 +5793,11 @@ function createRecordsClient(config) {
|
|
|
5677
5793
|
"pipelineRead"
|
|
5678
5794
|
);
|
|
5679
5795
|
},
|
|
5680
|
-
async pipelineBoard({ table_id, measure }) {
|
|
5796
|
+
async pipelineBoard({ table_id, measure, filter }) {
|
|
5797
|
+
const asked = filter && stableFilterKey(filter) !== "{}";
|
|
5681
5798
|
return callDoor(
|
|
5682
5799
|
DOORS.pipelineBoard,
|
|
5683
|
-
{ 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 },
|
|
5684
5801
|
"pipelineBoard"
|
|
5685
5802
|
);
|
|
5686
5803
|
},
|
|
@@ -5704,6 +5821,13 @@ function createRecordsClient(config) {
|
|
|
5704
5821
|
"pipelineMove"
|
|
5705
5822
|
);
|
|
5706
5823
|
},
|
|
5824
|
+
async pipelineMoveMany({ moves }) {
|
|
5825
|
+
return callDoor(
|
|
5826
|
+
DOORS.pipelineMoveMany,
|
|
5827
|
+
{ p_organization_id: org, p_moves: moves },
|
|
5828
|
+
"pipelineMoveMany"
|
|
5829
|
+
);
|
|
5830
|
+
},
|
|
5707
5831
|
async pipelineDeclare({ table_id, spec }) {
|
|
5708
5832
|
return callDoor(
|
|
5709
5833
|
DOORS.pipelineDeclare,
|
|
@@ -5753,6 +5877,18 @@ function createRecordsClient(config) {
|
|
|
5753
5877
|
"pipelineGatePreview"
|
|
5754
5878
|
);
|
|
5755
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
|
+
},
|
|
5756
5892
|
async ruleMembers({ rule_id }) {
|
|
5757
5893
|
return callDoor(
|
|
5758
5894
|
DOORS.ruleMembers,
|
|
@@ -5805,6 +5941,13 @@ function createRecordsClient(config) {
|
|
|
5805
5941
|
"bookingDeclare"
|
|
5806
5942
|
);
|
|
5807
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
|
+
},
|
|
5808
5951
|
async formDeclare(args) {
|
|
5809
5952
|
return callDoor(
|
|
5810
5953
|
DOORS.formDeclare,
|
|
@@ -5980,11 +6123,33 @@ function createRecordsClient(config) {
|
|
|
5980
6123
|
p_tables: args.tables,
|
|
5981
6124
|
p_portal_id: args.portal_id ?? null,
|
|
5982
6125
|
p_slug: args.slug ?? null,
|
|
5983
|
-
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 } : {}
|
|
5984
6129
|
},
|
|
5985
6130
|
"portalDeclare"
|
|
5986
6131
|
);
|
|
5987
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
|
+
},
|
|
5988
6153
|
async portalInvite(args) {
|
|
5989
6154
|
return callDoor(
|
|
5990
6155
|
DOORS.portalInvite,
|
|
@@ -6183,10 +6348,17 @@ function createRecordsClient(config) {
|
|
|
6183
6348
|
"dashboardDeclare"
|
|
6184
6349
|
);
|
|
6185
6350
|
},
|
|
6186
|
-
async dashboardRun({ dashboard_id, filter }) {
|
|
6351
|
+
async dashboardRun({ dashboard_id, filter, compare, grain }) {
|
|
6187
6352
|
return callDoor(
|
|
6188
6353
|
DOORS.dashboardRun,
|
|
6189
|
-
{
|
|
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
|
+
},
|
|
6190
6362
|
"dashboardRun"
|
|
6191
6363
|
);
|
|
6192
6364
|
},
|
|
@@ -6211,7 +6383,7 @@ function createRecordsClient(config) {
|
|
|
6211
6383
|
"dashboardDelete"
|
|
6212
6384
|
);
|
|
6213
6385
|
},
|
|
6214
|
-
async recordAggregate({ table_id, groupBy, measures, bucket, filter, limit }) {
|
|
6386
|
+
async recordAggregate({ table_id, groupBy, measures, bucket, filter, limit, compare }) {
|
|
6215
6387
|
return callDoor(
|
|
6216
6388
|
DOORS.recordAggregate,
|
|
6217
6389
|
{
|
|
@@ -6221,7 +6393,8 @@ function createRecordsClient(config) {
|
|
|
6221
6393
|
p_measures: measures ?? [],
|
|
6222
6394
|
p_bucket: bucket ?? null,
|
|
6223
6395
|
p_filter: filter ?? {},
|
|
6224
|
-
p_limit: limit ?? 200
|
|
6396
|
+
p_limit: limit ?? 200,
|
|
6397
|
+
...compare ? { p_compare: compare } : {}
|
|
6225
6398
|
},
|
|
6226
6399
|
"recordAggregate"
|
|
6227
6400
|
);
|
|
@@ -6949,6 +7122,13 @@ function createRecordsClient(config) {
|
|
|
6949
7122
|
"workApprovalDecide"
|
|
6950
7123
|
);
|
|
6951
7124
|
},
|
|
7125
|
+
async workDecideMany({ decisions }) {
|
|
7126
|
+
return callDoor(
|
|
7127
|
+
DOORS.workDecideMany,
|
|
7128
|
+
{ p_organization_id: org, p_decisions: decisions },
|
|
7129
|
+
"workDecideMany"
|
|
7130
|
+
);
|
|
7131
|
+
},
|
|
6952
7132
|
async workApprovalRead({ approval_id }) {
|
|
6953
7133
|
return callDoor(
|
|
6954
7134
|
DOORS.workApprovalRead,
|
|
@@ -7152,6 +7332,69 @@ function createRecordsClient(config) {
|
|
|
7152
7332
|
"tableFromExample"
|
|
7153
7333
|
);
|
|
7154
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
|
+
},
|
|
7155
7398
|
async autonumberBackfill({ field_id }) {
|
|
7156
7399
|
return callDoor(
|
|
7157
7400
|
DOORS.autonumberBackfill,
|
|
@@ -7246,27 +7489,6 @@ function useRecordsActor() {
|
|
|
7246
7489
|
|
|
7247
7490
|
// src/react/hooks.ts
|
|
7248
7491
|
var import_react2 = require("react");
|
|
7249
|
-
|
|
7250
|
-
// src/aggregate.ts
|
|
7251
|
-
function measureKey(measure) {
|
|
7252
|
-
return measure.op === "count" ? "count" : `${measure.op}_${measure.key ?? ""}`;
|
|
7253
|
-
}
|
|
7254
|
-
function stableFilterKey(filter) {
|
|
7255
|
-
if (!filter) return "{}";
|
|
7256
|
-
const keys = Object.keys(filter).sort();
|
|
7257
|
-
if (keys.length === 0) return "{}";
|
|
7258
|
-
const parts = keys.map((key) => {
|
|
7259
|
-
const value = filter[key];
|
|
7260
|
-
if (value !== null && typeof value === "object") {
|
|
7261
|
-
const window2 = value;
|
|
7262
|
-
return `${JSON.stringify(key)}:{"from":${JSON.stringify(window2.from ?? null)},"to":${JSON.stringify(window2.to ?? null)}}`;
|
|
7263
|
-
}
|
|
7264
|
-
return `${JSON.stringify(key)}:${JSON.stringify(value ?? null)}`;
|
|
7265
|
-
});
|
|
7266
|
-
return `{${parts.join(",")}}`;
|
|
7267
|
-
}
|
|
7268
|
-
|
|
7269
|
-
// src/react/hooks.ts
|
|
7270
7492
|
function useAsync(run, deps) {
|
|
7271
7493
|
const client = useRecordsClient();
|
|
7272
7494
|
const [state, setState] = (0, import_react2.useState)(
|
|
@@ -7746,6 +7968,88 @@ function useMergeField(key, state) {
|
|
|
7746
7968
|
return resolution;
|
|
7747
7969
|
}
|
|
7748
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
|
+
|
|
7749
8053
|
// src/vocabulary.ts
|
|
7750
8054
|
var TABLE_TYPES = [
|
|
7751
8055
|
"entity",
|
|
@@ -7857,6 +8161,7 @@ var FIELD_KINDS = [
|
|
|
7857
8161
|
"currency",
|
|
7858
8162
|
"datetime",
|
|
7859
8163
|
"email",
|
|
8164
|
+
"entity_reference",
|
|
7860
8165
|
"formula",
|
|
7861
8166
|
"json",
|
|
7862
8167
|
"long_text",
|
|
@@ -7895,6 +8200,7 @@ function fieldKindFor(field, kernel) {
|
|
|
7895
8200
|
case "list":
|
|
7896
8201
|
return field.multi ? "multi_select" : "select";
|
|
7897
8202
|
case "relation": {
|
|
8203
|
+
if (isEntityReferenceConfig(config)) return "entity_reference";
|
|
7898
8204
|
const parity = String(config["parity"] ?? "");
|
|
7899
8205
|
if (parity === "attachment" || parity === "member") return parity;
|
|
7900
8206
|
if (kernel?.file && field.relation_target === kernel.file) return "attachment";
|
|
@@ -7912,6 +8218,14 @@ function fieldKindFor(field, kernel) {
|
|
|
7912
8218
|
}
|
|
7913
8219
|
}
|
|
7914
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
|
+
}
|
|
7915
8229
|
var TRUE_WORDS = /* @__PURE__ */ new Set(["true", "yes", "y", "1", "\u2713", "x", "checked", "on"]);
|
|
7916
8230
|
var FALSE_WORDS = /* @__PURE__ */ new Set(["false", "no", "n", "0", "", "unchecked", "off"]);
|
|
7917
8231
|
function coercionLabel(field) {
|
|
@@ -8027,6 +8341,23 @@ function coerceTypedAnswer(field, raw, opts = {}) {
|
|
|
8027
8341
|
return {
|
|
8028
8342
|
refusal: `${label} points at another record, so it is chosen rather than typed. Open it and pick the record.`
|
|
8029
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
|
+
}
|
|
8030
8361
|
case "formula":
|
|
8031
8362
|
case "lookup":
|
|
8032
8363
|
case "rollup":
|
|
@@ -8083,6 +8414,10 @@ function publicFormPath(formId) {
|
|
|
8083
8414
|
}
|
|
8084
8415
|
|
|
8085
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
|
+
}
|
|
8086
8421
|
function portalPath(slug) {
|
|
8087
8422
|
return `/portal/c/${slug}`;
|
|
8088
8423
|
}
|
|
@@ -8105,6 +8440,56 @@ function emptyPortalArchiveLine() {
|
|
|
8105
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.";
|
|
8106
8441
|
}
|
|
8107
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
|
+
|
|
8108
8493
|
// src/capture-queue.ts
|
|
8109
8494
|
var DB_NAME = "matrx-capture";
|
|
8110
8495
|
var DB_VERSION = 1;
|