import { codigosResposta } from "./respostas"; // ─── Tipagem ELicencie ────────────────────────────────────────────── /** * Mapa de códigos HTTP de erro usados pelo sistema ELicencie. * * Single source of truth para derivar `codigoErroELicencie`. */ export const codigosErros = { 400: "Erro de requisição", 403: "Não autenticado", 500: "Erro interno", 504: "Tempo de resposta excedido", }; // ─── Mapeamento bidirecional de códigos ───────────────────────────── /** ELicencie → P-Resposta (403 → 401) */ const mapaCodigoELicencieParaPResposta = { 400: codigosResposta.erroConhecido, 403: codigosResposta.erroPermissao, 500: codigosResposta.erroDesconhecido, 504: codigosResposta.tempoEsgotado, }; /** P-Resposta → ELicencie (401 → 403, 404 → 400) */ const mapaCodigoPRespostaParaELicencie = { [codigosResposta.erroConhecido]: 400, [codigosResposta.erroPermissao]: 403, [codigosResposta.erroDesconhecido]: 500, [codigosResposta.erroNaoEncontrado]: 400, [codigosResposta.tempoEsgotado]: 504, }; // ─── Type guard ───────────────────────────────────────────────────── /** Detecta se a entrada já está no formato P-Resposta (possui campo `cod`). */ function eRespostaPadrao(entrada) { return "cod" in entrada; } // ─── Conversores de detalhes ──────────────────────────────────────── /** `Record` → `string[]` (passthrough se já for array). */ function detalhesParaArray(detalhes) { if (!detalhes) return undefined; if (Array.isArray(detalhes)) return detalhes; const entries = Object.entries(detalhes); if (entries.length === 0) return undefined; return entries.map(([chave, valor]) => { const valorStr = typeof valor === "string" ? valor : JSON.stringify(valor); return `${chave}: ${valorStr}`; }); } // ─── Builder de resposta dual ─────────────────────────────────────── /** * Monta um objeto compatível com **ambos** os formatos em runtime. * * Tipado como `tipoResposta`, mas em runtime também contém * `codigo`, `erro` e `detalhes` (Record) do formato ELicencie. */ function montarRespostaDual(op) { const detalhesArray = detalhesParaArray(op.detalhesOriginal); const detalhesRecord = op.detalhesOriginal && !Array.isArray(op.detalhesOriginal) ? op.detalhesOriginal : undefined; return { // P-Resposta cod: op.cod, valor: op.valor, mensagem: op.mensagem, eErro: op.eErro, eCerto: !op.eErro, detalhes: detalhesArray, // ELicencie (runtime) codigo: op.codigoELicencie, erro: op.erroELicencie, ...(detalhesRecord ? { detalhes: detalhesRecord } : {}), }; } // ─── Conversor principal ──────────────────────────────────────────── /** * Converte uma resposta para o formato **P-Resposta** (padrão do pacote), * mantendo em runtime os campos de **ambos** os formatos para * compatibilidade durante a transição de sistema. * * **Tipo de retorno:** `tipoResposta` * * **Conteúdo em runtime:** campos P-Resposta + campos ELicencie * * | P-Resposta | ELicencie | Relação | * |-------------|-------------|----------------------| * | `cod` | `codigo` | mapeamento de código | * | `mensagem` | `erro` | mesmo conteúdo | * | `valor` | `valor` | direto | * | `eErro` | `eErro` | direto | * | `eCerto` | — | derivado | * | `detalhes` | `detalhes` | string[] / Record | * * @example * ```ts * const res = converterRespostaELicencieParaPResposta(respostaQualquer) * * // Consumidor P-Resposta * if (res.eCerto) console.log(res.valor) * * // Consumidor ELicencie (lê campo extra em runtime) * const resAny = res as any * if (!resAny.eErro) console.log(resAny.valor) * ``` */ export const converterRespostaELicencieParaPResposta = (entrada) => { // ── Entrada já é P-Resposta: enriquecer com campos ELicencie ── if (eRespostaPadrao(entrada)) { if (!entrada.eErro) { return montarRespostaDual({ cod: codigosResposta.sucesso, valor: entrada.valor, mensagem: undefined, eErro: false, codigoELicencie: 200, erroELicencie: undefined, detalhesOriginal: entrada.detalhes, }); } return montarRespostaDual({ cod: entrada.cod, valor: undefined, mensagem: entrada.mensagem, eErro: true, codigoELicencie: mapaCodigoPRespostaParaELicencie[entrada.cod], erroELicencie: entrada.mensagem, detalhesOriginal: entrada.detalhes, }); } // ── Entrada é ELicencie: construir P-Resposta + preservar campos ── if (!entrada.eErro) { return montarRespostaDual({ cod: codigosResposta.sucesso, valor: entrada.valor, mensagem: undefined, eErro: false, codigoELicencie: entrada.codigo, erroELicencie: undefined, detalhesOriginal: entrada.detalhes, }); } return montarRespostaDual({ cod: mapaCodigoELicencieParaPResposta[entrada.codigo], valor: undefined, mensagem: entrada.erro, eErro: true, codigoELicencie: entrada.codigo, erroELicencie: entrada.erro, detalhesOriginal: entrada.detalhes, }); };