src/lib/shared/field-type-catalog.ts

Total Symbols
5
Lines of Code
112
Avg Complexity
1.2
Avg Coverage
100.0%

File Relationships

graph LR getFieldTypeOptions["getFieldTypeOptions"] getFieldTypeLabel["getFieldTypeLabel"] getFieldTypeGroupedOptions["getFieldTypeGroupedOptions"] getFieldTypeOptions -->|calls| getFieldTypeLabel getFieldTypeGroupedOptions -->|calls| getFieldTypeLabel click getFieldTypeOptions "../symbols/d108aaeac92c9305.html" click getFieldTypeLabel "../symbols/554362aa9aa64584.html" click getFieldTypeGroupedOptions "../symbols/bc5b8e85f8463f4e.html"

Symbols by Kind

function 3
interface 2

All Symbols

Name Kind Visibility Status Lines Signature
FieldTypeOption interface exported- 38-41 interface FieldTypeOption
FieldTypeGroup interface exported- 44-48 interface FieldTypeGroup
getFieldTypeLabel function exported- 66-74 getFieldTypeLabel(type: FieldType): : string
getFieldTypeOptions function exported- 80-86 getFieldTypeOptions( types: readonly FieldType[] = FIELD_TYPES, ): : FieldTypeOption[]
getFieldTypeGroupedOptions function exported- 93-111 getFieldTypeGroupedOptions( types: readonly FieldType[] = FIELD_TYPES, ): : FieldTypeGroup[]

Full Source

import {
  FIELD_TYPES,
  FIELD_TYPES_BY_CATEGORY,
  type FieldCategory,
  type FieldType,
} from "@/types";

/**
 * Human-readable label overrides for field types.
 * Falls back to title-cased hyphen-split names when not listed here.
 */
const FIELD_TYPE_LABEL_OVERRIDES: Partial<Record<FieldType, string>> = {
  cpf: "CPF",
  cnpj: "CNPJ",
  "cpf-cnpj": "CPF/CNPJ",
  rg: "RG",
  cep: "CEP",
  "zip-code": "ZIP Code",
  "full-name": "Nome Completo",
  "first-name": "Primeiro Nome",
  "last-name": "Sobrenome",
  "birth-date": "Data de Nascimento",
  "start-date": "Data de Início",
  "end-date": "Data de Fim",
  "due-date": "Vencimento",
  "employee-count": "Nº Funcionários",
  "job-title": "Cargo",
  username: "Usuário",
  website: "Website",
  url: "URL",
  text: "Texto",
  number: "Número",
  money: "Valor Monetário",
  unknown: "Desconhecido",
};

/** A field type with its display label. */
export interface FieldTypeOption {
  value: FieldType;
  label: string;
}

/** A named group of field type options, used to render `<optgroup>` elements. */
export interface FieldTypeGroup {
  category: FieldCategory;
  label: string;
  options: FieldTypeOption[];
}

/** Portuguese labels for each field category. */
const FIELD_CATEGORY_LABELS: Record<FieldCategory, string> = {
  personal: "Pessoal",
  contact: "Contato",
  address: "Endereço",
  document: "Documentos",
  financial: "Financeiro",
  authentication: "Autenticação",
  professional: "Profissional",
  ecommerce: "E-commerce",
  system: "Sistema",
  generic: "Genérico",
  unknown: "Desconhecido",
};

/** Returns a human-readable label for the given field type. */
export function getFieldTypeLabel(type: FieldType): string {
  const override = FIELD_TYPE_LABEL_OVERRIDES[type];
  if (override) return override;

  return type
    .split("-")
    .map((chunk) => chunk.charAt(0).toUpperCase() + chunk.slice(1))
    .join(" ");
}

/**
 * Builds a sorted list of `{ value, label }` options from the given field types.
 * Defaults to all known `FIELD_TYPES` when none are provided.
 */
export function getFieldTypeOptions(
  types: readonly FieldType[] = FIELD_TYPES,
): FieldTypeOption[] {
  return [...types]
    .map((type) => ({ value: type, label: getFieldTypeLabel(type) }))
    .sort((a, b) => a.label.localeCompare(b.label, "pt-BR"));
}

/**
 * Returns field type options grouped by category, sorted alphabetically within
 * each group and with groups themselves sorted alphabetically by their label.
 * Groups with no matching types are omitted.
 */
export function getFieldTypeGroupedOptions(
  types: readonly FieldType[] = FIELD_TYPES,
): FieldTypeGroup[] {
  const typeSet = new Set(types);

  return (
    Object.entries(FIELD_TYPES_BY_CATEGORY) as [FieldCategory, FieldType[]][]
  )
    .map(([category, categoryTypes]) => ({
      category,
      label: FIELD_CATEGORY_LABELS[category],
      options: categoryTypes
        .filter((t) => typeSet.has(t))
        .map((type) => ({ value: type, label: getFieldTypeLabel(type) }))
        .sort((a, b) => a.label.localeCompare(b.label, "pt-BR")),
    }))
    .filter((group) => group.options.length > 0)
    .sort((a, b) => a.label.localeCompare(b.label, "pt-BR"));
}