This commit is contained in:
Luiz Silva 2026-06-19 17:11:15 -03:00
parent 9f8aa2299a
commit 91952a6fa5
8 changed files with 420 additions and 3 deletions

View file

@ -0,0 +1,123 @@
"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
});

View file

@ -15,8 +15,10 @@ 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")
});

View file

@ -68,4 +68,69 @@ declare const gerarRespostas: (callback?: tipoCallbackResposta) => InterfaceResp
*/
declare const respostaComuns: InterfaceRespostas;
export { IniciarRespostas, type InterfaceRespostas, codigosResposta, gerarRespostas, respostaComuns, type tipoCallbackResposta, type tipoPrErroInterno, type tipoResposta, type tipoRespostaErro, type tipoRespostaSucesso };
/**
* 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<T> {
codigo: 200;
eErro: false;
valor: T;
erro: undefined;
detalhes?: Record<string, any>;
}
interface tipoRespostaErroELicencie {
codigo: codigoErroELicencie;
eErro: true;
erro: string;
valor: undefined;
detalhes?: Record<string, any>;
}
type tipoRespostaELicencie<T> = tipoRespostaSucessoELicencie<T> | 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<T> = tipoRespostaELicencie<T> | tipoResposta<T>;
/**
* 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<T>`
*
* **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: <T>(entrada: tipoEntradaTransicao<T>) => tipoResposta<T>;
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 };

View file

@ -1 +1 @@
var m=(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))(m||{});function t(s,a){return a?a(s):s}var i=s=>{let a=(o,r)=>t({cod:200,valor:o,mensagem:void 0,eErro:!1,eCerto:!0,detalhes:r},s),d=o=>t({cod:200,valor:!0,mensagem:void 0,eErro:!1,eCerto:!0,detalhes:o},s),u=(o,r)=>t({cod:400,valor:void 0,mensagem:o,eErro:!0,eCerto:!1,detalhes:r},s),c=(o,r)=>t({cod:401,valor:void 0,mensagem:o||"Sem permiss\xE3o para esse recurso.",eErro:!0,eCerto:!1,detalhes:r},s),g=(o,r)=>t({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},s),e=o=>{let n={cod:500,valor:void 0,mensagem:`${o.mensagem||"Erro interno"}`,eErro:!0,eCerto:!1};return t(n,s)},p=(o,r)=>t({cod:504,valor:void 0,mensagem:o||"Tempo de resposta esgotado ao tentar acessar o recurso.",eErro:!0,eCerto:!1,detalhes:r},s);return{valor:a,valorTrue:d,erro:u,erroPermissao:c,erroInterno:e,naoEncontrado:g,tempoEsgotado:p,erroEspera:p}},l=i,R=i();export{i as IniciarRespostas,m as codigosResposta,l as gerarRespostas,R as respostaComuns};
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};

View file

@ -1,6 +1,6 @@
{
"name": "p-respostas",
"version": "0.67.0",
"version": "0.68.0",
"description": "Contrato simples de respostas (sucesso/erro) para APIs e serviços.",
"main": "./dist-back/index.js",
"module": "./dist-front/index.mjs",

Binary file not shown.

View file

@ -0,0 +1,225 @@
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<T> {
codigo: 200
eErro: false
valor: T
erro: undefined
detalhes?: Record<string, any>
}
export interface tipoRespostaErroELicencie {
codigo: codigoErroELicencie
eErro: true
erro: string
valor: undefined
detalhes?: Record<string, any>
}
export type tipoRespostaELicencie<T> =
| tipoRespostaSucessoELicencie<T>
| 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<T> = tipoRespostaELicencie<T> | tipoResposta<T>
// ─── 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<T>(
entrada: tipoEntradaTransicao<T>,
): entrada is tipoResposta<T> {
return "cod" in entrada
}
// ─── Conversores de detalhes ────────────────────────────────────────
/** `Record<string, any>` → `string[]` (passthrough se já for array). */
function detalhesParaArray(
detalhes?: Record<string, any> | 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<T>`, mas em runtime também contém
* `codigo`, `erro` e `detalhes` (Record) do formato ELicencie.
*/
function montarRespostaDual<T>(op: {
cod: tipoResposta<T>["cod"]
valor: T | undefined
mensagem: string | undefined
eErro: boolean
codigoELicencie: 200 | codigoErroELicencie
erroELicencie: string | undefined
detalhesOriginal?: Record<string, any> | string[]
}): tipoResposta<T> {
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<T>
}
// ─── 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<T>`
*
* **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 = <T>(
entrada: tipoEntradaTransicao<T>,
): tipoResposta<T> => {
// ── Entrada já é P-Resposta: enriquecer com campos ELicencie ──
if (eRespostaPadrao(entrada)) {
if (!entrada.eErro) {
return montarRespostaDual<T>({
cod: codigosResposta.sucesso,
valor: entrada.valor,
mensagem: undefined,
eErro: false,
codigoELicencie: 200,
erroELicencie: undefined,
detalhesOriginal: entrada.detalhes,
})
}
return montarRespostaDual<T>({
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<T>({
cod: codigosResposta.sucesso,
valor: entrada.valor,
mensagem: undefined,
eErro: false,
codigoELicencie: entrada.codigo,
erroELicencie: undefined,
detalhesOriginal: entrada.detalhes,
})
}
return montarRespostaDual<T>({
cod: mapaCodigoELicencieParaPResposta[entrada.codigo],
valor: undefined,
mensagem: entrada.erro,
eErro: true,
codigoELicencie: entrada.codigo,
erroELicencie: entrada.erro,
detalhesOriginal: entrada.detalhes,
})
}

View file

@ -1,2 +1,4 @@
// Re-export da API pública do pacote.
export * from "./converter-resposta-e-licencie-para-p-resposta"
export * from "./respostas"