diff --git a/.agent b/.agent deleted file mode 160000 index 5503367..0000000 --- a/.agent +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5503367656ec04508537df58064fdc1293fce956 diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index c57d840..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule ".agent"] - path = .agent - url = https://git2.idz.one/publico/.agent.git diff --git a/dist-back/converter-resposta-e-licencie-para-p-resposta.js b/dist-back/converter-resposta-e-licencie-para-p-resposta.js deleted file mode 100644 index f6f462d..0000000 --- a/dist-back/converter-resposta-e-licencie-para-p-resposta.js +++ /dev/null @@ -1,123 +0,0 @@ -"use strict"; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; -var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; -}; -var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); -var converter_resposta_e_licencie_para_p_resposta_exports = {}; -__export(converter_resposta_e_licencie_para_p_resposta_exports, { - codigosErros: () => codigosErros, - converterRespostaELicencieParaPResposta: () => converterRespostaELicencieParaPResposta -}); -module.exports = __toCommonJS(converter_resposta_e_licencie_para_p_resposta_exports); -var import_respostas = require("./respostas"); -const codigosErros = { - 400: "Erro de requisi\xE7\xE3o", - 403: "N\xE3o autenticado", - 500: "Erro interno", - 504: "Tempo de resposta excedido" -}; -const mapaCodigoELicencieParaPResposta = { - 400: import_respostas.codigosResposta.erroConhecido, - 403: import_respostas.codigosResposta.erroPermissao, - 500: import_respostas.codigosResposta.erroDesconhecido, - 504: import_respostas.codigosResposta.tempoEsgotado -}; -const mapaCodigoPRespostaParaELicencie = { - [import_respostas.codigosResposta.erroConhecido]: 400, - [import_respostas.codigosResposta.erroPermissao]: 403, - [import_respostas.codigosResposta.erroDesconhecido]: 500, - [import_respostas.codigosResposta.erroNaoEncontrado]: 400, - [import_respostas.codigosResposta.tempoEsgotado]: 504 -}; -function eRespostaPadrao(entrada) { - return "cod" in entrada; -} -function detalhesParaArray(detalhes) { - if (!detalhes) return void 0; - if (Array.isArray(detalhes)) return detalhes; - const entries = Object.entries(detalhes); - if (entries.length === 0) return void 0; - return entries.map(([chave, valor]) => { - const valorStr = typeof valor === "string" ? valor : JSON.stringify(valor); - return `${chave}: ${valorStr}`; - }); -} -function montarRespostaDual(op) { - const detalhesArray = detalhesParaArray(op.detalhesOriginal); - const detalhesRecord = op.detalhesOriginal && !Array.isArray(op.detalhesOriginal) ? op.detalhesOriginal : void 0; - 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 } : {} - }; -} -const converterRespostaELicencieParaPResposta = (entrada) => { - if (eRespostaPadrao(entrada)) { - if (!entrada.eErro) { - return montarRespostaDual({ - cod: import_respostas.codigosResposta.sucesso, - valor: entrada.valor, - mensagem: void 0, - eErro: false, - codigoELicencie: 200, - erroELicencie: void 0, - detalhesOriginal: entrada.detalhes - }); - } - return montarRespostaDual({ - cod: entrada.cod, - valor: void 0, - mensagem: entrada.mensagem, - eErro: true, - codigoELicencie: mapaCodigoPRespostaParaELicencie[entrada.cod], - erroELicencie: entrada.mensagem, - detalhesOriginal: entrada.detalhes - }); - } - if (!entrada.eErro) { - return montarRespostaDual({ - cod: import_respostas.codigosResposta.sucesso, - valor: entrada.valor, - mensagem: void 0, - eErro: false, - codigoELicencie: entrada.codigo, - erroELicencie: void 0, - detalhesOriginal: entrada.detalhes - }); - } - return montarRespostaDual({ - cod: mapaCodigoELicencieParaPResposta[entrada.codigo], - valor: void 0, - mensagem: entrada.erro, - eErro: true, - codigoELicencie: entrada.codigo, - erroELicencie: entrada.erro, - detalhesOriginal: entrada.detalhes - }); -}; -// Annotate the CommonJS export names for ESM import in node: -0 && (module.exports = { - codigosErros, - converterRespostaELicencieParaPResposta -}); diff --git a/dist-back/index.js b/dist-back/index.js index 5042b75..9a3bc08 100644 --- a/dist-back/index.js +++ b/dist-back/index.js @@ -15,10 +15,8 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var index_exports = {}; module.exports = __toCommonJS(index_exports); -__reExport(index_exports, require("./converter-resposta-e-licencie-para-p-resposta"), module.exports); __reExport(index_exports, require("./respostas"), module.exports); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { - ...require("./converter-resposta-e-licencie-para-p-resposta"), ...require("./respostas") }); diff --git a/dist-back/respostas.js b/dist-back/respostas.js index 69e4cd8..12e1e05 100644 --- a/dist-back/respostas.js +++ b/dist-back/respostas.js @@ -18,7 +18,6 @@ var __copyProps = (to, from, except, desc) => { var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var respostas_exports = {}; __export(respostas_exports, { - IniciarRespostas: () => IniciarRespostas, codigosResposta: () => codigosResposta, gerarRespostas: () => gerarRespostas, respostaComuns: () => respostaComuns @@ -33,13 +32,9 @@ var codigosResposta = /* @__PURE__ */ ((codigosResposta2) => { codigosResposta2[codigosResposta2["tempoEsgotado"] = 504] = "tempoEsgotado"; return codigosResposta2; })(codigosResposta || {}); -function aplicarCallback(resposta, callback) { - if (!callback) return resposta; - return callback(resposta); -} -const IniciarRespostas = (callback) => { +const gerarRespostas = (registrarErroInterno) => { const valor = (valor2, detalhes) => { - const resposta = { + return { cod: 200 /* sucesso */, valor: valor2, mensagem: void 0, @@ -47,10 +42,9 @@ const IniciarRespostas = (callback) => { eCerto: true, detalhes }; - return aplicarCallback(resposta, callback); }; const valorTrue = (detalhes) => { - const resposta = { + return { cod: 200 /* sucesso */, valor: true, mensagem: void 0, @@ -58,10 +52,9 @@ const IniciarRespostas = (callback) => { eCerto: true, detalhes }; - return aplicarCallback(resposta, callback); }; const erro = (mensagem, detalhes) => { - const resposta = { + return { cod: 400 /* erroConhecido */, valor: void 0, mensagem, @@ -69,10 +62,9 @@ const IniciarRespostas = (callback) => { eCerto: false, detalhes }; - return aplicarCallback(resposta, callback); }; const erroPermissao = (mensagem, detalhes) => { - const resposta = { + return { cod: 401 /* erroPermissao */, valor: void 0, mensagem: mensagem || "Sem permiss\xE3o para esse recurso.", @@ -80,10 +72,9 @@ const IniciarRespostas = (callback) => { eCerto: false, detalhes }; - return aplicarCallback(resposta, callback); }; const naoEncontrado = (mensagem, detalhes) => { - const resposta = { + return { cod: 404 /* erroNaoEncontrado */, valor: void 0, mensagem: mensagem || "Registro n\xE3o encontrado ou a execu\xE7\xE3o dessa a\xE7\xE3o depende de um registro existente.", @@ -91,21 +82,21 @@ const IniciarRespostas = (callback) => { eCerto: false, detalhes }; - return aplicarCallback(resposta, callback); }; const erroInterno = (op) => { + const resRegistro = registrarErroInterno(op); const mensagemFim = `${op.mensagem || "Erro interno"}`; - const resposta = { + return { cod: 500 /* erroDesconhecido */, valor: void 0, mensagem: mensagemFim, eErro: true, - eCerto: false + eCerto: false, + ...resRegistro }; - return aplicarCallback(resposta, callback); }; const tempoEsgotado = (mensagem, detalhes) => { - const resposta = { + return { cod: 504 /* tempoEsgotado */, valor: void 0, mensagem: mensagem || "Tempo de resposta esgotado ao tentar acessar o recurso.", @@ -113,7 +104,6 @@ const IniciarRespostas = (callback) => { eCerto: false, detalhes }; - return aplicarCallback(resposta, callback); }; const erroEspera = tempoEsgotado; return { @@ -151,11 +141,9 @@ const IniciarRespostas = (callback) => { erroEspera }; }; -const gerarRespostas = IniciarRespostas; -const respostaComuns = IniciarRespostas(); +const respostaComuns = gerarRespostas(() => ({})); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { - IniciarRespostas, codigosResposta, gerarRespostas, respostaComuns diff --git a/dist-front/index.d.mts b/dist-front/index.d.mts index b21d47f..97c6e86 100644 --- a/dist-front/index.d.mts +++ b/dist-front/index.d.mts @@ -34,13 +34,6 @@ type tipoPrErroInterno = { local: string; __filename?: string; }; -/** - * Tipo do callback opcional de interceptação de respostas. - * - * Quando fornecido, é invocado após a construção de toda resposta, - * permitindo side-effects (ex.: logging, telemetria) sem alterar o tipo. - */ -type tipoCallbackResposta = (resposta: tipoResposta) => tipoResposta; /** * Cria um conjunto de geradores de respostas. * @@ -56,81 +49,14 @@ interface InterfaceRespostas { tempoEsgotado: (mensagem?: string | undefined | null, detalhes?: string[]) => tipoRespostaErro; erroEspera: (mensagem?: string | undefined | null, detalhes?: string[]) => tipoRespostaErro; } -declare const IniciarRespostas: ( -/** Callback opcional de interceptação — invocado após a construção de cada resposta */ -callback?: tipoCallbackResposta) => InterfaceRespostas; -/** - * @deprecated Use IniciarRespostas em seu lugar +declare const gerarRespostas: ( +/** Faz um processamento quando erro interno + * Recebe o erro gerado, mensagem personalizada e detalhes */ -declare const gerarRespostas: (callback?: tipoCallbackResposta) => InterfaceRespostas; +registrarErroInterno: (op: tipoPrErroInterno) => Partial) => InterfaceRespostas; /** - * Instância default (sem handler de interceptação). + * Instância default (sem handler de erro interno). */ declare const respostaComuns: InterfaceRespostas; -/** - * Mapa de códigos HTTP de erro usados pelo sistema ELicencie. - * - * Single source of truth para derivar `codigoErroELicencie`. - */ -declare const codigosErros: { - readonly 400: "Erro de requisição"; - readonly 403: "Não autenticado"; - readonly 500: "Erro interno"; - readonly 504: "Tempo de resposta excedido"; -}; -/** Códigos HTTP de erro reconhecidos pelo ELicencie. */ -type codigoErroELicencie = keyof typeof codigosErros; -interface tipoRespostaSucessoELicencie { - codigo: 200; - eErro: false; - valor: T; - erro: undefined; - detalhes?: Record; -} -interface tipoRespostaErroELicencie { - codigo: codigoErroELicencie; - eErro: true; - erro: string; - valor: undefined; - detalhes?: Record; -} -type tipoRespostaELicencie = tipoRespostaSucessoELicencie | tipoRespostaErroELicencie; -/** - * Durante a transição de sistema, a entrada pode chegar em qualquer um - * dos dois formatos. O conversor detecta e normaliza para P-Resposta. - */ -type tipoEntradaTransicao = tipoRespostaELicencie | tipoResposta; -/** - * 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) - * ``` - */ -declare const converterRespostaELicencieParaPResposta: (entrada: tipoEntradaTransicao) => tipoResposta; - -export { IniciarRespostas, type InterfaceRespostas, type codigoErroELicencie, codigosErros, codigosResposta, converterRespostaELicencieParaPResposta, gerarRespostas, respostaComuns, type tipoCallbackResposta, type tipoEntradaTransicao, type tipoPrErroInterno, type tipoResposta, type tipoRespostaELicencie, type tipoRespostaErro, type tipoRespostaErroELicencie, type tipoRespostaSucesso, type tipoRespostaSucessoELicencie }; +export { type InterfaceRespostas, codigosResposta, gerarRespostas, respostaComuns, type tipoPrErroInterno, type tipoResposta, type tipoRespostaErro, type tipoRespostaSucesso }; diff --git a/dist-front/index.mjs b/dist-front/index.mjs index 985850d..4f11a71 100644 --- a/dist-front/index.mjs +++ b/dist-front/index.mjs @@ -1 +1 @@ -var l=(o=>(o[o.sucesso=200]="sucesso",o[o.erroConhecido=400]="erroConhecido",o[o.erroPermissao=401]="erroPermissao",o[o.erroNaoEncontrado=404]="erroNaoEncontrado",o[o.erroDesconhecido=500]="erroDesconhecido",o[o.tempoEsgotado=504]="tempoEsgotado",o))(l||{});function n(e,t){return t?t(e):e}var u=e=>{let t=(r,s)=>n({cod:200,valor:r,mensagem:void 0,eErro:!1,eCerto:!0,detalhes:s},e),i=r=>n({cod:200,valor:!0,mensagem:void 0,eErro:!1,eCerto:!0,detalhes:r},e),c=(r,s)=>n({cod:400,valor:void 0,mensagem:r,eErro:!0,eCerto:!1,detalhes:s},e),d=(r,s)=>n({cod:401,valor:void 0,mensagem:r||"Sem permiss\xE3o para esse recurso.",eErro:!0,eCerto:!1,detalhes:s},e),E=(r,s)=>n({cod:404,valor:void 0,mensagem:r||"Registro n\xE3o encontrado ou a execu\xE7\xE3o dessa a\xE7\xE3o depende de um registro existente.",eErro:!0,eCerto:!1,detalhes:s},e),o=r=>{let a={cod:500,valor:void 0,mensagem:`${r.mensagem||"Erro interno"}`,eErro:!0,eCerto:!1};return n(a,e)},g=(r,s)=>n({cod:504,valor:void 0,mensagem:r||"Tempo de resposta esgotado ao tentar acessar o recurso.",eErro:!0,eCerto:!1,detalhes:s},e);return{valor:t,valorTrue:i,erro:c,erroPermissao:d,erroInterno:o,naoEncontrado:E,tempoEsgotado:g,erroEspera:g}},L=u,y=u();var x={400:"Erro de requisi\xE7\xE3o",403:"N\xE3o autenticado",500:"Erro interno",504:"Tempo de resposta excedido"},m={400:400,403:401,500:500,504:504},R={400:400,401:403,500:500,404:400,504:504};function f(e){return"cod"in e}function T(e){if(!e)return;if(Array.isArray(e))return e;let t=Object.entries(e);if(t.length!==0)return t.map(([i,c])=>{let d=typeof c=="string"?c:JSON.stringify(c);return`${i}: ${d}`})}function p(e){let t=T(e.detalhesOriginal),i=e.detalhesOriginal&&!Array.isArray(e.detalhesOriginal)?e.detalhesOriginal:void 0;return{cod:e.cod,valor:e.valor,mensagem:e.mensagem,eErro:e.eErro,eCerto:!e.eErro,detalhes:t,codigo:e.codigoELicencie,erro:e.erroELicencie,...i?{detalhes:i}:{}}}var C=e=>f(e)?e.eErro?p({cod:e.cod,valor:void 0,mensagem:e.mensagem,eErro:!0,codigoELicencie:R[e.cod],erroELicencie:e.mensagem,detalhesOriginal:e.detalhes}):p({cod:200,valor:e.valor,mensagem:void 0,eErro:!1,codigoELicencie:200,erroELicencie:void 0,detalhesOriginal:e.detalhes}):e.eErro?p({cod:m[e.codigo],valor:void 0,mensagem:e.erro,eErro:!0,codigoELicencie:e.codigo,erroELicencie:e.erro,detalhesOriginal:e.detalhes}):p({cod:200,valor:e.valor,mensagem:void 0,eErro:!1,codigoELicencie:e.codigo,erroELicencie:void 0,detalhesOriginal:e.detalhes});export{u as IniciarRespostas,x as codigosErros,l as codigosResposta,C as converterRespostaELicencieParaPResposta,L as gerarRespostas,y as respostaComuns}; +var u=(e=>(e[e.sucesso=200]="sucesso",e[e.erroConhecido=400]="erroConhecido",e[e.erroPermissao=401]="erroPermissao",e[e.erroNaoEncontrado=404]="erroNaoEncontrado",e[e.erroDesconhecido=500]="erroDesconhecido",e[e.tempoEsgotado=504]="tempoEsgotado",e))(u||{}),g=t=>{let n=(o,r)=>({cod:200,valor:o,mensagem:void 0,eErro:!1,eCerto:!0,detalhes:r}),a=o=>({cod:200,valor:!0,mensagem:void 0,eErro:!1,eCerto:!0,detalhes:o}),i=(o,r)=>({cod:400,valor:void 0,mensagem:o,eErro:!0,eCerto:!1,detalhes:r}),p=(o,r)=>({cod:401,valor:void 0,mensagem:o||"Sem permiss\xE3o para esse recurso.",eErro:!0,eCerto:!1,detalhes:r}),d=(o,r)=>({cod:404,valor:void 0,mensagem:o||"Registro n\xE3o encontrado ou a execu\xE7\xE3o dessa a\xE7\xE3o depende de um registro existente.",eErro:!0,eCerto:!1,detalhes:r}),e=o=>{let r=t(o);return{cod:500,valor:void 0,mensagem:`${o.mensagem||"Erro interno"}`,eErro:!0,eCerto:!1,...r}},s=(o,r)=>({cod:504,valor:void 0,mensagem:o||"Tempo de resposta esgotado ao tentar acessar o recurso.",eErro:!0,eCerto:!1,detalhes:r});return{valor:n,valorTrue:a,erro:i,erroPermissao:p,erroInterno:e,naoEncontrado:d,tempoEsgotado:s,erroEspera:s}},l=g(()=>({}));export{u as codigosResposta,g as gerarRespostas,l as respostaComuns}; diff --git a/package.json b/package.json index 335f634..1334871 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "p-respostas", - "version": "0.69.0", + "version": "0.66.0", "description": "Contrato simples de respostas (sucesso/erro) para APIs e serviços.", "main": "./dist-back/index.js", "module": "./dist-front/index.mjs", @@ -24,16 +24,16 @@ }, "peerDependencies": { "p-comuns": "git+https://git2.idz.one/publico/_comuns.git", - "zod": "4.4.3" + "zod": "4.3.6" }, "devDependencies": { - "@biomejs/biome": "2.4.12", + "@biomejs/biome": "2.4.0", "@types/node": "^22.19.15", "check-node-version": "^4.2.1", "p-comuns": "git+https://git2.idz.one/publico/_comuns.git", "tsup": "^8.5.1", "typescript": "^6", - "zod": "4.4.3" + "zod": "4.3.6" }, "keywords": [], "author": { diff --git a/pacote.tgz b/pacote.tgz index 0ca8ea1..0c1023a 100644 Binary files a/pacote.tgz and b/pacote.tgz differ diff --git a/src/converter-resposta-e-licencie-para-p-resposta.ts b/src/converter-resposta-e-licencie-para-p-resposta.ts deleted file mode 100644 index 7fffd02..0000000 --- a/src/converter-resposta-e-licencie-para-p-resposta.ts +++ /dev/null @@ -1,225 +0,0 @@ -import { - codigosResposta, - type tipoResposta, - type tipoRespostaErro, -} 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", -} as const - -/** Códigos HTTP de erro reconhecidos pelo ELicencie. */ -export type codigoErroELicencie = keyof typeof codigosErros - -export interface tipoRespostaSucessoELicencie { - codigo: 200 - eErro: false - valor: T - erro: undefined - detalhes?: Record -} - -export interface tipoRespostaErroELicencie { - codigo: codigoErroELicencie - eErro: true - erro: string - valor: undefined - detalhes?: Record -} - -export type tipoRespostaELicencie = - | tipoRespostaSucessoELicencie - | tipoRespostaErroELicencie - -// ─── Tipo de entrada (transição) ──────────────────────────────────── - -/** - * Durante a transição de sistema, a entrada pode chegar em qualquer um - * dos dois formatos. O conversor detecta e normaliza para P-Resposta. - */ -export type tipoEntradaTransicao = tipoRespostaELicencie | tipoResposta - -// ─── Mapeamento bidirecional de códigos ───────────────────────────── - -/** ELicencie → P-Resposta (403 → 401) */ -const mapaCodigoELicencieParaPResposta: Record< - codigoErroELicencie, - tipoRespostaErro["cod"] -> = { - 400: codigosResposta.erroConhecido, - 403: codigosResposta.erroPermissao, - 500: codigosResposta.erroDesconhecido, - 504: codigosResposta.tempoEsgotado, -} - -/** P-Resposta → ELicencie (401 → 403, 404 → 400) */ -const mapaCodigoPRespostaParaELicencie: Record< - tipoRespostaErro["cod"], - codigoErroELicencie -> = { - [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: tipoEntradaTransicao, -): entrada is tipoResposta { - return "cod" in entrada -} - -// ─── Conversores de detalhes ──────────────────────────────────────── - -/** `Record` → `string[]` (passthrough se já for array). */ -function detalhesParaArray( - detalhes?: Record | string[], -): string[] | undefined { - 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: { - cod: tipoResposta["cod"] - valor: T | undefined - mensagem: string | undefined - eErro: boolean - codigoELicencie: 200 | codigoErroELicencie - erroELicencie: string | undefined - detalhesOriginal?: Record | string[] -}): tipoResposta { - 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 } : {}), - } as tipoResposta -} - -// ─── 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: tipoEntradaTransicao, -): tipoResposta => { - // ── 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, - }) -} diff --git a/src/index.ts b/src/index.ts index 06a9396..9f14c03 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,2 @@ // Re-export da API pública do pacote. - -export * from "./converter-resposta-e-licencie-para-p-resposta" export * from "./respostas" diff --git a/src/respostas.ts b/src/respostas.ts index 8d2104b..407582f 100644 --- a/src/respostas.ts +++ b/src/respostas.ts @@ -44,16 +44,6 @@ export type tipoPrErroInterno = { __filename?: string } -/** - * Tipo do callback opcional de interceptação de respostas. - * - * Quando fornecido, é invocado após a construção de toda resposta, - * permitindo side-effects (ex.: logging, telemetria) sem alterar o tipo. - */ -export type tipoCallbackResposta = ( - resposta: tipoResposta, -) => tipoResposta - /** * Cria um conjunto de geradores de respostas. * @@ -82,28 +72,14 @@ export interface InterfaceRespostas { ) => tipoRespostaErro } -// ─── Helper interno ───────────────────────────────────────────────── -/** - * Aplica o callback de interceptação quando fornecido. - * Retorno com cast seguro: o callback preserva a forma da resposta, - * mas o TypeScript não consegue estreitar o genérico ao subtipo - * concreto (ex.: tipoRespostaSucesso), então o cast é inevitável - * e está isolado neste único ponto. - */ -function aplicarCallback>( - resposta: R, - callback?: tipoCallbackResposta, -): R { - if (!callback) return resposta - return callback(resposta) as R -} - -export const IniciarRespostas = ( - /** Callback opcional de interceptação — invocado após a construção de cada resposta */ - callback?: tipoCallbackResposta, +export const gerarRespostas = ( + /** Faz um processamento quando erro interno + * Recebe o erro gerado, mensagem personalizada e detalhes + */ + registrarErroInterno: (op: tipoPrErroInterno) => Partial, ): InterfaceRespostas => { const valor = (valor: T, detalhes?: string[]): tipoRespostaSucesso => { - const resposta: tipoRespostaSucesso = { + return { cod: codigosResposta.sucesso, valor, mensagem: undefined, @@ -111,11 +87,10 @@ export const IniciarRespostas = ( eCerto: true, detalhes, } - return aplicarCallback(resposta, callback) } const valorTrue = (detalhes?: string[]): tipoRespostaSucesso => { - const resposta: tipoRespostaSucesso = { + return { cod: codigosResposta.sucesso, valor: true, mensagem: undefined, @@ -123,11 +98,10 @@ export const IniciarRespostas = ( eCerto: true, detalhes, } - return aplicarCallback(resposta, callback) } const erro = (mensagem: string, detalhes?: string[]): tipoRespostaErro => { - const resposta: tipoRespostaErro = { + return { cod: codigosResposta.erroConhecido, valor: undefined, mensagem, @@ -135,14 +109,13 @@ export const IniciarRespostas = ( eCerto: false, detalhes, } - return aplicarCallback(resposta, callback) } const erroPermissao = ( mensagem?: string | undefined | null, detalhes?: string[], ): tipoRespostaErro => { - const resposta: tipoRespostaErro = { + return { cod: codigosResposta.erroPermissao, valor: undefined, mensagem: mensagem || "Sem permissão para esse recurso.", @@ -150,14 +123,13 @@ export const IniciarRespostas = ( eCerto: false, detalhes, } - return aplicarCallback(resposta, callback) } const naoEncontrado = ( mensagem?: string | undefined | null, detalhes?: string[], ): tipoRespostaErro => { - const resposta: tipoRespostaErro = { + return { cod: codigosResposta.erroNaoEncontrado, valor: undefined, mensagem: @@ -167,27 +139,28 @@ export const IniciarRespostas = ( eCerto: false, detalhes, } - return aplicarCallback(resposta, callback) } const erroInterno = (op: tipoPrErroInterno): tipoRespostaErro => { + const resRegistro = registrarErroInterno(op) + const mensagemFim = `${op.mensagem || "Erro interno"}` - const resposta: tipoRespostaErro = { + return { cod: codigosResposta.erroDesconhecido, valor: undefined, mensagem: mensagemFim, eErro: true, eCerto: false, + ...resRegistro, } - return aplicarCallback(resposta, callback) } const tempoEsgotado = ( mensagem?: string | undefined | null, detalhes?: string[], ): tipoRespostaErro => { - const resposta: tipoRespostaErro = { + return { cod: codigosResposta.tempoEsgotado, valor: undefined, mensagem: @@ -196,7 +169,6 @@ export const IniciarRespostas = ( eCerto: false, detalhes, } - return aplicarCallback(resposta, callback) } const erroEspera = tempoEsgotado @@ -239,11 +211,6 @@ export const IniciarRespostas = ( } /** - * @deprecated Use IniciarRespostas em seu lugar + * Instância default (sem handler de erro interno). */ -export const gerarRespostas = IniciarRespostas - -/** - * Instância default (sem handler de interceptação). - */ -export const respostaComuns = IniciarRespostas() +export const respostaComuns = gerarRespostas(() => ({})) diff --git a/tsconfig.json b/tsconfig.json index b83149f..a03482a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,8 +3,7 @@ /* Linguagem e Ambiente */ "target": "ES2020", /* Define a versão do JavaScript para o código emitido. */ "lib": ["ES2022", "DOM", "DOM.Iterable"],/* Especifica as bibliotecas padrão a serem incluídas, como DOM para iteradores. */ - // IA manter "ignoreDeprecations": "6.0", -"ignoreDeprecations": "6.0", /* Ignora erros de compatibilidade com depreciações TS 6.x */ + "ignoreDeprecations": "6.0", /* Ignora erros de compatibilidade com depreciações TS 6.x */ "experimentalDecorators": true, /* Habilita o suporte experimental a decoradores. */ "emitDecoratorMetadata": true, /* Emite metadados de tipos de design para declarações decoradas. */