Files
update_field_api/src/parse/prompt-picklist.ts
T

135 lines
3.8 KiB
TypeScript
Raw Normal View History

2026-06-17 11:41:12 -03:00
import type { Clarizen, JsonValue } from "@arco/clarizen-lib";
import { isCancel, select, spinner, text } from "@clack/prompts";
import { formatFieldHint } from "../metadata/field-hints.js";
import {
fetchPickListOptions,
formatPickListOptionLabel,
getPickListEntityType,
type FieldWithRefs,
} from "../metadata/picklist.js";
import { pickFromFiltered } from "../metadata/picker.js";
import { parseFieldValue, ValueParseError } from "./value.js";
export interface FieldValueSelection {
value: JsonValue;
displayLabel?: string;
}
async function pickPickListOption(
field: FieldWithRefs,
options: Array<{ value: string; label: string }>,
): Promise<string | symbol> {
const fieldLabel = field.label ?? field.name ?? "valor";
return pickFromFiltered(
`Escolha o valor para ${fieldLabel}`,
options,
"Como deseja buscar na lista?",
);
}
async function promptPickListSelection(
clarizen: Clarizen,
field: FieldWithRefs,
pickListTypeName: string,
): Promise<FieldValueSelection | symbol> {
const loadSpinner = spinner();
loadSpinner.start(`Carregando opções de ${pickListTypeName}...`);
const pickListOptions = await fetchPickListOptions(
clarizen,
pickListTypeName,
(count) => {
loadSpinner.message(
`Carregando opções de ${pickListTypeName}... (${count})`,
);
},
);
loadSpinner.stop(`${pickListOptions.length} opção(ões) carregada(s).`);
if (pickListOptions.length === 0) {
console.log(
`\nNenhuma opção encontrada para ${pickListTypeName}. Informe o ID manualmente.\n`,
);
return promptManualEntityValue(field);
}
const selectOptions = pickListOptions.map((o) => ({
value: o.id,
label: formatPickListOptionLabel(o),
}));
const selectedId = await pickPickListOption(field, selectOptions);
if (isCancel(selectedId)) return selectedId;
const match = pickListOptions.find((o) => o.id === selectedId);
return {
value: { id: selectedId },
displayLabel: match
? `${match.label} (${match.id})`
: String(selectedId),
};
}
async function promptManualEntityValue(
field: FieldWithRefs,
): Promise<FieldValueSelection | symbol> {
while (true) {
const raw = await text({
message: "Informe o ID da entidade (ex: /Tipo/guid)",
validate: (value) => (!value?.trim() ? "Valor obrigatório." : undefined),
});
if (isCancel(raw)) return raw;
try {
const value = parseFieldValue(raw, field);
return { value, displayLabel: formatEntityDisplayLabel(value) };
} catch (err) {
if (err instanceof ValueParseError) {
console.error(`\n Erro: ${err.message}\n`);
continue;
}
throw err;
}
}
}
function formatEntityDisplayLabel(value: JsonValue): string | undefined {
if (value && typeof value === "object" && "id" in value) {
const id = (value as { id?: unknown }).id;
if (typeof id === "string") return id;
}
return undefined;
}
export async function promptPickListValue(
clarizen: Clarizen,
field: FieldWithRefs,
): Promise<FieldValueSelection | symbol> {
console.log("\n" + formatFieldHint(field) + "\n");
if (field.nullable) {
const action = await select({
message: "O que deseja fazer com este campo?",
options: [
{ value: "set", label: "Definir um valor" },
{ value: "clear", label: "Limpar campo (null)" },
],
});
if (isCancel(action)) return action;
if (action === "clear") {
return { value: null, displayLabel: "(vazio / null)" };
}
}
const pickListTypeName = getPickListEntityType(field);
if (!pickListTypeName) {
console.log(
"\nPicklist sem tipo de referência na metadata. Informe o ID manualmente.\n",
);
return promptManualEntityValue(field);
}
return promptPickListSelection(clarizen, field, pickListTypeName);
}