@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.
- package/CHANGELOG.md +36 -0
- package/dist/core/index.cjs +244 -2
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +27 -3
- package/dist/core/index.d.ts +27 -3
- package/dist/core/index.js +244 -2
- package/dist/core/index.js.map +1 -1
- package/dist/{field-CdHqvIIy.d.cts → field-D0Rr4Cqb.d.cts} +52 -3
- package/dist/{field-CdHqvIIy.d.ts → field-D0Rr4Cqb.d.ts} +52 -3
- package/dist/index.cjs +212 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +126 -3
- package/dist/index.d.ts +126 -3
- package/dist/index.js +212 -2
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +244 -2
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +197 -3
- package/dist/react/index.d.ts +197 -3
- package/dist/react/index.js +244 -2
- package/dist/react/index.js.map +1 -1
- package/dist/use-cases/index.cjs.map +1 -1
- package/dist/use-cases/index.d.cts +1 -1
- package/dist/use-cases/index.d.ts +1 -1
- package/dist/use-cases/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -562,6 +562,8 @@ var STORE_DOORS = [
|
|
|
562
562
|
{ name: "relation_target_ours", args: "p_entity_token text, p_row_id uuid", returns: "jsonb", security: "definer" },
|
|
563
563
|
{ name: "relation_targets", args: "p_organization_id uuid, p_record_id uuid, p_via_key text", returns: "SETOF uuid", security: "definer" },
|
|
564
564
|
{ name: "relation_uncarry", args: "p_organization_id uuid, p_container_id uuid, p_item_id uuid", returns: "integer", security: "definer" },
|
|
565
|
+
{ name: "relation_words", args: "p_organization_id uuid, p_field_id uuid, p_value text", returns: "text", security: "definer" },
|
|
566
|
+
{ 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" },
|
|
565
567
|
{ name: "reopen_declared_doors", args: "", returns: "TABLE(reopened text)", security: "definer" },
|
|
566
568
|
{ name: "required_epoch", args: "p_container_type text, p_container_id uuid, p_item_type text, p_item_id uuid", returns: "bigint", security: "definer" },
|
|
567
569
|
{ name: "resolve_first_match", args: "p_organization_id uuid, p_record_id uuid", returns: "jsonb", security: "invoker" },
|
|
@@ -758,9 +760,9 @@ var STORE_REFUSAL_CODES = [
|
|
|
758
760
|
{ code: "22007", raised_by: "dashboard_window_sql" },
|
|
759
761
|
{ code: "22012", raised_by: "rule_eval" },
|
|
760
762
|
{ 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" },
|
|
761
|
-
{ 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" },
|
|
763
|
+
{ 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" },
|
|
762
764
|
{ 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" },
|
|
763
|
-
{ 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" },
|
|
765
|
+
{ 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" },
|
|
764
766
|
{ code: "40001", raised_by: "has_visibility_at" },
|
|
765
767
|
{ 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" },
|
|
766
768
|
{ code: "42703", raised_by: "entity_table,portal_declare" },
|
|
@@ -1911,6 +1913,18 @@ var DOORS = {
|
|
|
1911
1913
|
promotedRead: "promoted_read",
|
|
1912
1914
|
relationTargets: "relation_targets",
|
|
1913
1915
|
relationOwn: "relation_own",
|
|
1916
|
+
// REL-DISP, 2026-09-21. WHAT A RELATION CELL READS, through that column's own
|
|
1917
|
+
// display spec. `custom.record_words` is declared server_only — it takes a bare
|
|
1918
|
+
// record id with no field to scope it — so these are how a screen gets the
|
|
1919
|
+
// words, and they are the ONE way in: three separate copies of "read tableList,
|
|
1920
|
+
// find title_field, call rowName" lived in labels.tsx, RelationPicker.tsx and
|
|
1921
|
+
// PortalsPanel.tsx, and none of them could ever have shown two columns joined.
|
|
1922
|
+
// The `_many` door is the batch TAILS-2 recorded as missing ("there is still no
|
|
1923
|
+
// batch door on the store"), which is why the browser resolved labels one id at
|
|
1924
|
+
// a time. The ladder is NOT batched: the store asks it per record inside
|
|
1925
|
+
// `custom._words_for`, so batching buys a round trip and never a disclosure.
|
|
1926
|
+
relationWords: "relation_words",
|
|
1927
|
+
relationWordsMany: "relation_words_many",
|
|
1914
1928
|
homeAdd: "home_add",
|
|
1915
1929
|
recordReparent: "record_reparent",
|
|
1916
1930
|
containmentChain: "containment_chain",
|
|
@@ -2782,6 +2796,26 @@ function createRecordsClient(config) {
|
|
|
2782
2796
|
"fieldRetire"
|
|
2783
2797
|
);
|
|
2784
2798
|
},
|
|
2799
|
+
async relationWords({ field_id, value }) {
|
|
2800
|
+
return callDoor(
|
|
2801
|
+
DOORS.relationWords,
|
|
2802
|
+
{ p_organization_id: org, p_field_id: field_id, p_value: value },
|
|
2803
|
+
"relationWords"
|
|
2804
|
+
);
|
|
2805
|
+
},
|
|
2806
|
+
async relationWordsMany({ field_id, record_ids }) {
|
|
2807
|
+
const result = await callDoor(
|
|
2808
|
+
DOORS.relationWordsMany,
|
|
2809
|
+
{ p_organization_id: org, p_field_id: field_id, p_record_ids: record_ids },
|
|
2810
|
+
"relationWordsMany"
|
|
2811
|
+
);
|
|
2812
|
+
if (!result.ok) return result;
|
|
2813
|
+
const map = {};
|
|
2814
|
+
for (const row of result.data ?? []) {
|
|
2815
|
+
if (row?.record_id && typeof row.words === "string") map[row.record_id] = row.words;
|
|
2816
|
+
}
|
|
2817
|
+
return { ok: true, data: map };
|
|
2818
|
+
},
|
|
2785
2819
|
async tableDeclare({ spec, homeId }) {
|
|
2786
2820
|
return callDoor(
|
|
2787
2821
|
DOORS.tableDeclare,
|
|
@@ -4682,6 +4716,209 @@ function looksLikeAnId(value) {
|
|
|
4682
4716
|
return typeof value === "string" && UUID.test(value);
|
|
4683
4717
|
}
|
|
4684
4718
|
|
|
4719
|
+
// src/coerce.ts
|
|
4720
|
+
var FIELD_KINDS = [
|
|
4721
|
+
"attachment",
|
|
4722
|
+
"checkbox",
|
|
4723
|
+
"currency",
|
|
4724
|
+
"datetime",
|
|
4725
|
+
"email",
|
|
4726
|
+
"formula",
|
|
4727
|
+
"json",
|
|
4728
|
+
"long_text",
|
|
4729
|
+
"lookup",
|
|
4730
|
+
"member",
|
|
4731
|
+
"multi_select",
|
|
4732
|
+
"number",
|
|
4733
|
+
"percent",
|
|
4734
|
+
"phone",
|
|
4735
|
+
"relation",
|
|
4736
|
+
"rollup",
|
|
4737
|
+
"select",
|
|
4738
|
+
"text",
|
|
4739
|
+
"url"
|
|
4740
|
+
];
|
|
4741
|
+
function fieldKindFor(field, kernel) {
|
|
4742
|
+
const format = (field.format ?? "").toLowerCase();
|
|
4743
|
+
const config = field.config ?? {};
|
|
4744
|
+
switch (field.type) {
|
|
4745
|
+
case "boolean":
|
|
4746
|
+
return "checkbox";
|
|
4747
|
+
case "text":
|
|
4748
|
+
if (format === "email") return "email";
|
|
4749
|
+
if (format === "phone") return "phone";
|
|
4750
|
+
if (format === "url") return "url";
|
|
4751
|
+
if (format === "json" || config["json"] === true) return "json";
|
|
4752
|
+
if (format === "long" || config["multiline"] === true) return "long_text";
|
|
4753
|
+
return "text";
|
|
4754
|
+
case "range": {
|
|
4755
|
+
const kind = String(config["kind"] ?? "number");
|
|
4756
|
+
if (kind === "date" || kind === "datetime") return "datetime";
|
|
4757
|
+
if (format === "currency") return "currency";
|
|
4758
|
+
if (format === "percent" || field.unit === "%") return "percent";
|
|
4759
|
+
return "number";
|
|
4760
|
+
}
|
|
4761
|
+
case "list":
|
|
4762
|
+
return field.multi ? "multi_select" : "select";
|
|
4763
|
+
case "relation": {
|
|
4764
|
+
const parity = String(config["parity"] ?? "");
|
|
4765
|
+
if (parity === "attachment" || parity === "member") return parity;
|
|
4766
|
+
if (kernel?.file && field.relation_target === kernel.file) return "attachment";
|
|
4767
|
+
if (kernel?.person && field.relation_target === kernel.person) return "member";
|
|
4768
|
+
return "relation";
|
|
4769
|
+
}
|
|
4770
|
+
case "formula": {
|
|
4771
|
+
const via = config["via"];
|
|
4772
|
+
if (via && config["agg"]) return "rollup";
|
|
4773
|
+
if (via) return "lookup";
|
|
4774
|
+
return "formula";
|
|
4775
|
+
}
|
|
4776
|
+
default:
|
|
4777
|
+
return "text";
|
|
4778
|
+
}
|
|
4779
|
+
}
|
|
4780
|
+
var TRUE_WORDS = /* @__PURE__ */ new Set(["true", "yes", "y", "1", "\u2713", "x", "checked", "on"]);
|
|
4781
|
+
var FALSE_WORDS = /* @__PURE__ */ new Set(["false", "no", "n", "0", "", "unchecked", "off"]);
|
|
4782
|
+
function coercionLabel(field) {
|
|
4783
|
+
const label = (field.label ?? "").trim();
|
|
4784
|
+
if (label !== "") return label;
|
|
4785
|
+
const name = (field.name ?? "").trim();
|
|
4786
|
+
if (name !== "") return name;
|
|
4787
|
+
return field.key.replace(/[_-]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim();
|
|
4788
|
+
}
|
|
4789
|
+
function coerceTypedAnswer(field, raw, opts = {}) {
|
|
4790
|
+
const label = opts.label ?? coercionLabel(field);
|
|
4791
|
+
const text = raw.trim();
|
|
4792
|
+
const kind = fieldKindFor(field, opts.kernel);
|
|
4793
|
+
if (text === "" && kind !== "checkbox") return { value: null };
|
|
4794
|
+
switch (kind) {
|
|
4795
|
+
case "checkbox": {
|
|
4796
|
+
const word = text.toLowerCase();
|
|
4797
|
+
if (TRUE_WORDS.has(word)) return { value: true };
|
|
4798
|
+
if (FALSE_WORDS.has(word)) return { value: word === "" ? null : false };
|
|
4799
|
+
return {
|
|
4800
|
+
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.`
|
|
4801
|
+
};
|
|
4802
|
+
}
|
|
4803
|
+
case "number":
|
|
4804
|
+
case "currency":
|
|
4805
|
+
case "percent": {
|
|
4806
|
+
const negative = /^\(.*\)$/.test(text);
|
|
4807
|
+
const bare = text.replace(/^\(|\)$/g, "").replace(/[\s,]/g, "").replace(/^[^\d.\-+]+/, "").replace(/[^\d.\-+eE]+$/, "");
|
|
4808
|
+
const n = Number(bare);
|
|
4809
|
+
if (bare === "" || Number.isNaN(n)) {
|
|
4810
|
+
return {
|
|
4811
|
+
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.`
|
|
4812
|
+
};
|
|
4813
|
+
}
|
|
4814
|
+
return { value: negative ? -n : n };
|
|
4815
|
+
}
|
|
4816
|
+
case "datetime": {
|
|
4817
|
+
const wantsTime = String(field.config?.["kind"] ?? "date") === "datetime";
|
|
4818
|
+
const plainDay = /^\s*(\d{4})-(\d{2})-(\d{2})\s*$/.exec(raw);
|
|
4819
|
+
if (!wantsTime && plainDay) return { value: `${plainDay[1]}-${plainDay[2]}-${plainDay[3]}` };
|
|
4820
|
+
const at = Date.parse(text);
|
|
4821
|
+
if (Number.isNaN(at)) {
|
|
4822
|
+
return {
|
|
4823
|
+
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.`
|
|
4824
|
+
};
|
|
4825
|
+
}
|
|
4826
|
+
const parsed = new Date(at);
|
|
4827
|
+
if (wantsTime) return { value: parsed.toISOString() };
|
|
4828
|
+
const y = parsed.getFullYear();
|
|
4829
|
+
const m = String(parsed.getMonth() + 1).padStart(2, "0");
|
|
4830
|
+
const d = String(parsed.getDate()).padStart(2, "0");
|
|
4831
|
+
return { value: `${y}-${m}-${d}` };
|
|
4832
|
+
}
|
|
4833
|
+
case "json": {
|
|
4834
|
+
try {
|
|
4835
|
+
return { value: JSON.parse(text) };
|
|
4836
|
+
} catch {
|
|
4837
|
+
return {
|
|
4838
|
+
refusal: `${label} holds a document, and \u201C${raw}\u201D is not valid JSON. Write the whole object, braces and all.`
|
|
4839
|
+
};
|
|
4840
|
+
}
|
|
4841
|
+
}
|
|
4842
|
+
case "select":
|
|
4843
|
+
case "multi_select": {
|
|
4844
|
+
if (!opts.options) {
|
|
4845
|
+
return {
|
|
4846
|
+
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.`
|
|
4847
|
+
};
|
|
4848
|
+
}
|
|
4849
|
+
const wanted = kind === "multi_select" ? text.split(/[,;]/).map((w) => w.trim()).filter((w) => w.length > 0) : [text];
|
|
4850
|
+
if (wanted.length === 0) return { value: kind === "multi_select" ? [] : null };
|
|
4851
|
+
const matched = [];
|
|
4852
|
+
const unmatched = [];
|
|
4853
|
+
for (const word of wanted) {
|
|
4854
|
+
const hit = opts.options.byWord.get(word.toLowerCase());
|
|
4855
|
+
if (hit === void 0) unmatched.push(word);
|
|
4856
|
+
else matched.push(hit);
|
|
4857
|
+
}
|
|
4858
|
+
if (unmatched.length > 0) {
|
|
4859
|
+
const offered = opts.options.labels.length > 0 ? opts.options.labels.join(", ") : "it has none yet";
|
|
4860
|
+
return {
|
|
4861
|
+
refusal: `${label} does not have ${unmatched.map((w) => `\u201C${w}\u201D`).join(" or ")} among its options. It offers: ${offered}.`,
|
|
4862
|
+
unmatched
|
|
4863
|
+
};
|
|
4864
|
+
}
|
|
4865
|
+
return { value: kind === "multi_select" ? matched : matched[0] };
|
|
4866
|
+
}
|
|
4867
|
+
// AN IDENTITY IS NOT A WORD. Writing the word would put a string where an
|
|
4868
|
+
// id belongs, and every filter, colour and rollup built on that column
|
|
4869
|
+
// would stop agreeing with it. So it is refused and the person is told
|
|
4870
|
+
// which control does hold it.
|
|
4871
|
+
case "member":
|
|
4872
|
+
return {
|
|
4873
|
+
refusal: `${label} names a person in this organization, so it is chosen rather than typed. Open it and pick them.`
|
|
4874
|
+
};
|
|
4875
|
+
case "attachment":
|
|
4876
|
+
return {
|
|
4877
|
+
refusal: `${label} holds a file, which cannot arrive as typed-in text. Open it and attach the file.`
|
|
4878
|
+
};
|
|
4879
|
+
case "relation":
|
|
4880
|
+
return {
|
|
4881
|
+
refusal: `${label} points at another record, so it is chosen rather than typed. Open it and pick the record.`
|
|
4882
|
+
};
|
|
4883
|
+
case "formula":
|
|
4884
|
+
case "lookup":
|
|
4885
|
+
case "rollup":
|
|
4886
|
+
return {
|
|
4887
|
+
refusal: `${label} is worked out by the system, so nothing can be written into it.`
|
|
4888
|
+
};
|
|
4889
|
+
default:
|
|
4890
|
+
return { value: raw };
|
|
4891
|
+
}
|
|
4892
|
+
}
|
|
4893
|
+
function coerceTypedAnswers(fields, answers, opts = {}) {
|
|
4894
|
+
const byKey = new Map(fields.map((f) => [f.key, f]));
|
|
4895
|
+
const values = {};
|
|
4896
|
+
const refusals = {};
|
|
4897
|
+
const unknownKeys = [];
|
|
4898
|
+
for (const [key, given] of Object.entries(answers)) {
|
|
4899
|
+
const field = byKey.get(key);
|
|
4900
|
+
if (!field) {
|
|
4901
|
+
unknownKeys.push(key);
|
|
4902
|
+
values[key] = given;
|
|
4903
|
+
continue;
|
|
4904
|
+
}
|
|
4905
|
+
if (typeof given !== "string") {
|
|
4906
|
+
values[key] = given;
|
|
4907
|
+
continue;
|
|
4908
|
+
}
|
|
4909
|
+
const opt = {};
|
|
4910
|
+
const choices = opts.options?.get(key);
|
|
4911
|
+
if (choices) opt.options = choices;
|
|
4912
|
+
if (opts.kernel) opt.kernel = opts.kernel;
|
|
4913
|
+
const label = opts.labels?.[key];
|
|
4914
|
+
if (label) opt.label = label;
|
|
4915
|
+
const answered = coerceTypedAnswer(field, given, opt);
|
|
4916
|
+
if ("refusal" in answered) refusals[key] = answered.refusal;
|
|
4917
|
+
else values[key] = answered.value;
|
|
4918
|
+
}
|
|
4919
|
+
return { values, refusals, unknownKeys };
|
|
4920
|
+
}
|
|
4921
|
+
|
|
4685
4922
|
// src/pipeline.ts
|
|
4686
4923
|
var PIPELINE_RULE_KINDS = ["moves", "requires", "who", "limit", "entry"];
|
|
4687
4924
|
var STAGE_RULE_ON_FAIL = ["refuse", "require_approval"];
|
|
@@ -4998,6 +5235,7 @@ export {
|
|
|
4998
5235
|
CONTEXT_POLICIES,
|
|
4999
5236
|
DELIVERIES,
|
|
5000
5237
|
ENTITY_TOKENS,
|
|
5238
|
+
FIELD_KINDS,
|
|
5001
5239
|
FIELD_SENSITIVITIES,
|
|
5002
5240
|
FIELD_SOURCES,
|
|
5003
5241
|
FRESHNESS,
|
|
@@ -5036,7 +5274,11 @@ export {
|
|
|
5036
5274
|
choiceSlug,
|
|
5037
5275
|
choiceValuesOf,
|
|
5038
5276
|
choicesOf,
|
|
5277
|
+
coerceTypedAnswer,
|
|
5278
|
+
coerceTypedAnswers,
|
|
5279
|
+
coercionLabel,
|
|
5039
5280
|
err,
|
|
5281
|
+
fieldKindFor,
|
|
5040
5282
|
forgetAllOps,
|
|
5041
5283
|
highestLevel,
|
|
5042
5284
|
holdsARetiredChoice,
|