diff --git a/AI.md b/AI.md index c001c62..0758f03 100644 --- a/AI.md +++ b/AI.md @@ -79,8 +79,46 @@ const respostas = gerarRespostas((op) => { const r = respostas.erroInterno({ erro: new Error("boom"), local: "user.service" }) ``` +## Validação com Zod (`zRespostas`) + +Para validar payloads de resposta recebidos de APIs ou serviços com [Zod](https://zod.dev): + +```ts +import z from "zod" +import { zRespostas, type tipoZResposta } from "p-respostas" + +// 1. Validando payload com tipo específico de sucesso +const schemaUsuario = zRespostas( + z.object({ + id: z.string(), + nome: z.string(), + }) +) + +const resposta = schemaUsuario.parse(jsonRecebidoDaApi) + +if (resposta.eCerto) { + // TypeScript sabe que resposta.valor tem { id: string; nome: string } + console.log("Dados do usuário:", resposta.valor.nome) +} else { + // TypeScript sabe que resposta.mensagem é string e cod é um dos códigos de erro + console.error("Falha:", resposta.mensagem, "Código:", resposta.cod) +} + +// 2. Aceitando qualquer valor no sucesso (default z.any()) +const schemaGenerico = zRespostas() + +// 3. Schemas e tipos auxiliares exportados: +// - zResposta (alias idêntico a zRespostas) +// - zRespostaSucesso(zValor?) +// - zRespostaErro +// - zCodigosRespostaErro +// - tipoZResposta +``` + ## Garantias / restrições - Este pacote é amplamente importado por outros projetos. - Os arquivos em `dist-*` são gerados automaticamente. - Mudanças aqui devem focar em **melhorar o consumo (exports/tipos/docs)** sem alterar comportamento. + diff --git a/README.md b/README.md index 2120d75..b6f79c2 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ Contrato simples e tipado de respostas para APIs e serviços (sucesso/erro), com ## Instalação ```bash +bun add p-respostas +# ou pnpm add p-respostas # ou npm i p-respostas @@ -68,6 +70,26 @@ Cria um conjunto de funções padronizadas para gerar respostas. Instância default de `gerarRespostas(() => ({}))`. +### Validação Zod (`zRespostas`) + +Permite validar e inferir tipos de payloads recebidos via HTTP/APIs: + +```ts +import z from "zod" +import { zRespostas } from "p-respostas" + +const schema = zRespostas(z.string()) +const resultado = schema.parse(payload) + +if (resultado.eCerto) { + console.log("Sucesso:", resultado.valor) +} else { + console.log("Erro:", resultado.mensagem, resultado.cod) +} +``` + +Também exporta `zResposta`, `zRespostaSucesso`, `zRespostaErro`, `zCodigosRespostaErro` e `type tipoZResposta`. + ## Compatibilidade - Node: `>=20` diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..f760565 --- /dev/null +++ b/bun.lock @@ -0,0 +1,98 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "p-respostas", + "devDependencies": { + "@biomejs/biome": "^2", + "@types/bun": "^1.4.2", + "@types/node": "^22.19.15", + "p-comuns": "git+https://git2.idz.one/publico/_comuns.git#bun", + "typescript": "^7", + "zod": "4.4.3", + }, + "peerDependencies": { + "p-comuns": "git+https://git2.idz.one/publico/_comuns.git#bun", + "zod": "4.4.3", + }, + }, + }, + "packages": { + "@biomejs/biome": ["@biomejs/biome@2.4.12", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.12", "@biomejs/cli-darwin-x64": "2.4.12", "@biomejs/cli-linux-arm64": "2.4.12", "@biomejs/cli-linux-arm64-musl": "2.4.12", "@biomejs/cli-linux-x64": "2.4.12", "@biomejs/cli-linux-x64-musl": "2.4.12", "@biomejs/cli-win32-arm64": "2.4.12", "@biomejs/cli-win32-x64": "2.4.12" }, "bin": { "biome": "bin/biome" } }, "sha512-Rro7adQl3NLq/zJCIL98eElXKI8eEiBtoeu5TbXF/U3qbjuSc7Jb5rjUbeHHcquDWeSf3HnGP7XI5qGrlRk/pA=="], + + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BnMU4Pc3ciEVteVpZ0BK33MLr7X57F5w1dwDLDn+/iy/yTrA4Q/N2yftidFtsA4vrDh0FMXDpacNV/Tl3fbmng=="], + + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-x9uJ0bI1rJsWICp3VH8w/5PnAVD3A7SqzDpbrfoUQX1QyWrK5jSU4fRLo/wSgGeplCivbxBRKmt5Xq4/nWvq8A=="], + + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-tOwuCuZZtKi1jVzbk/5nXmIsziOB6yqN8c9r9QM0EJYPU6DpQWf11uBOSCfFKKM4H3d9ZoarvlgMfbcuD051Pw=="], + + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-FhfpkAAlKL6kwvcVap0Hgp4AhZmtd3YImg0kK1jd7C/aSoh4SfsB2f++yG1rU0lr8Y5MCFJrcSkmssiL9Xnnig=="], + + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.12", "", { "os": "linux", "cpu": "x64" }, "sha512-8pFeAnLU9QdW9jCIslB/v82bI0lhBmz2ZAKc8pVMFPO0t0wAHsoEkrUQUbMkIorTRIjbqyNZHA3lEXavsPWYSw=="], + + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.12", "", { "os": "linux", "cpu": "x64" }, "sha512-dwTIgZrGutzhkQCuvHynCkyW6hJxUuyZqKKO0YNfaS2GUoRO+tOvxXZqZB6SkWAOdfZTzwaw8IEdUnIkHKHoew=="], + + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-B0DLnx0vA9ya/3v7XyCaP+/lCpnbWbMOfUFFve+xb5OxyYvdHaS55YsSddr228Y+JAFk58agCuZTsqNiw2a6ig=="], + + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.12", "", { "os": "win32", "cpu": "x64" }, "sha512-yMckRzTyZ83hkk8iDFWswqSdU8tvZxspJKnYNh7JZr/zhZNOlzH13k4ecboU6MurKExCe2HUkH75pGI/O2JwGA=="], + + "@types/bun": ["@types/bun@1.4.2", "", { "dependencies": { "bun-types": "1.4.2" } }, "sha512-GimotNn7+ZV0uVArItBbriZsR1oNf0+WTzPkdcFrzShI7k2norL0uzEaJT8T33dWr7O/c9ZDuAFQrctKCi72oQ=="], + + "@types/node": ["@types/node@22.20.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q=="], + + "@typescript/typescript-aix-ppc64": ["@typescript/typescript-aix-ppc64@7.0.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ=="], + + "@typescript/typescript-darwin-arm64": ["@typescript/typescript-darwin-arm64@7.0.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA=="], + + "@typescript/typescript-darwin-x64": ["@typescript/typescript-darwin-x64@7.0.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA=="], + + "@typescript/typescript-freebsd-arm64": ["@typescript/typescript-freebsd-arm64@7.0.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ=="], + + "@typescript/typescript-freebsd-x64": ["@typescript/typescript-freebsd-x64@7.0.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw=="], + + "@typescript/typescript-linux-arm": ["@typescript/typescript-linux-arm@7.0.2", "", { "os": "linux", "cpu": "arm" }, "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ=="], + + "@typescript/typescript-linux-arm64": ["@typescript/typescript-linux-arm64@7.0.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ=="], + + "@typescript/typescript-linux-loong64": ["@typescript/typescript-linux-loong64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ=="], + + "@typescript/typescript-linux-mips64el": ["@typescript/typescript-linux-mips64el@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA=="], + + "@typescript/typescript-linux-ppc64": ["@typescript/typescript-linux-ppc64@7.0.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA=="], + + "@typescript/typescript-linux-riscv64": ["@typescript/typescript-linux-riscv64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ=="], + + "@typescript/typescript-linux-s390x": ["@typescript/typescript-linux-s390x@7.0.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw=="], + + "@typescript/typescript-linux-x64": ["@typescript/typescript-linux-x64@7.0.2", "", { "os": "linux", "cpu": "x64" }, "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A=="], + + "@typescript/typescript-netbsd-arm64": ["@typescript/typescript-netbsd-arm64@7.0.2", "", { "os": "none", "cpu": "arm64" }, "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA=="], + + "@typescript/typescript-netbsd-x64": ["@typescript/typescript-netbsd-x64@7.0.2", "", { "os": "none", "cpu": "x64" }, "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA=="], + + "@typescript/typescript-openbsd-arm64": ["@typescript/typescript-openbsd-arm64@7.0.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ=="], + + "@typescript/typescript-openbsd-x64": ["@typescript/typescript-openbsd-x64@7.0.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg=="], + + "@typescript/typescript-sunos-x64": ["@typescript/typescript-sunos-x64@7.0.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g=="], + + "@typescript/typescript-win32-arm64": ["@typescript/typescript-win32-arm64@7.0.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ=="], + + "@typescript/typescript-win32-x64": ["@typescript/typescript-win32-x64@7.0.2", "", { "os": "win32", "cpu": "x64" }, "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g=="], + + "bun-types": ["bun-types@1.4.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-bxV1FgK7yBIzjRe5zBozIM4Bem11ZJcCXSrjWRG3YWLt8yFDePu4cLjpebO8OvPeIE9trbyPF4fuj3Cia4Fj3w=="], + + "dayjs": ["dayjs@1.11.21", "", {}, "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA=="], + + "p-comuns": ["p-comuns@git+https://git2.idz.one/publico/_comuns.git#cd4ea4d36b1ca745076865cb16d785d2e5f14446", { "peerDependencies": { "dayjs": "^1.11.18", "uuid": "^11.1.0", "zod": "4.4.3" } }, "cd4ea4d36b1ca745076865cb16d785d2e5f14446"], + + "typescript": ["typescript@7.0.2", "", { "optionalDependencies": { "@typescript/typescript-aix-ppc64": "7.0.2", "@typescript/typescript-darwin-arm64": "7.0.2", "@typescript/typescript-darwin-x64": "7.0.2", "@typescript/typescript-freebsd-arm64": "7.0.2", "@typescript/typescript-freebsd-x64": "7.0.2", "@typescript/typescript-linux-arm": "7.0.2", "@typescript/typescript-linux-arm64": "7.0.2", "@typescript/typescript-linux-loong64": "7.0.2", "@typescript/typescript-linux-mips64el": "7.0.2", "@typescript/typescript-linux-ppc64": "7.0.2", "@typescript/typescript-linux-riscv64": "7.0.2", "@typescript/typescript-linux-s390x": "7.0.2", "@typescript/typescript-linux-x64": "7.0.2", "@typescript/typescript-netbsd-arm64": "7.0.2", "@typescript/typescript-netbsd-x64": "7.0.2", "@typescript/typescript-openbsd-arm64": "7.0.2", "@typescript/typescript-openbsd-x64": "7.0.2", "@typescript/typescript-sunos-x64": "7.0.2", "@typescript/typescript-win32-arm64": "7.0.2", "@typescript/typescript-win32-x64": "7.0.2" }, "bin": { "tsc": "bin/tsc" } }, "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA=="], + + "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "uuid": ["uuid@11.1.1", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ=="], + + "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + } +} diff --git a/dist-back/converter-resposta-e-licencie-para-p-resposta.js b/dist-back/converter-resposta-e-licencie-para-p-resposta.js index f6f462d..1362e22 100644 --- a/dist-back/converter-resposta-e-licencie-para-p-resposta.js +++ b/dist-back/converter-resposta-e-licencie-para-p-resposta.js @@ -1,123 +1,154 @@ "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" +Object.defineProperty(exports, "__esModule", { value: true }); +exports.converterRespostaELicencieParaPResposta = exports.codigosErros = void 0; +const respostas_1 = require("./respostas"); +// ─── Tipagem ELicencie ────────────────────────────────────────────── +/** + * Mapa de códigos HTTP de erro usados pelo sistema ELicencie. + * + * Single source of truth para derivar `codigoErroELicencie`. + */ +exports.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: import_respostas.codigosResposta.erroConhecido, - 403: import_respostas.codigosResposta.erroPermissao, - 500: import_respostas.codigosResposta.erroDesconhecido, - 504: import_respostas.codigosResposta.tempoEsgotado + 400: respostas_1.codigosResposta.erroConhecido, + 403: respostas_1.codigosResposta.erroPermissao, + 500: respostas_1.codigosResposta.erroDesconhecido, + 504: respostas_1.codigosResposta.tempoEsgotado, }; +/** P-Resposta → ELicencie (401 → 403, 404 → 400) */ 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 + [respostas_1.codigosResposta.erroConhecido]: 400, + [respostas_1.codigosResposta.erroPermissao]: 403, + [respostas_1.codigosResposta.erroDesconhecido]: 500, + [respostas_1.codigosResposta.erroNaoEncontrado]: 400, + [respostas_1.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; + return "cod" in entrada; } +// ─── Conversores de detalhes ──────────────────────────────────────── +/** `Record` → `string[]` (passthrough se já for array). */ 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}`; - }); + 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 : 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 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) + * ``` + */ const converterRespostaELicencieParaPResposta = (entrada) => { - if (eRespostaPadrao(entrada)) { + // ── Entrada já é P-Resposta: enriquecer com campos ELicencie ── + if (eRespostaPadrao(entrada)) { + if (!entrada.eErro) { + return montarRespostaDual({ + cod: respostas_1.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: import_respostas.codigosResposta.sucesso, - valor: entrada.valor, - mensagem: void 0, - eErro: false, - codigoELicencie: 200, - erroELicencie: void 0, - detalhesOriginal: entrada.detalhes - }); + return montarRespostaDual({ + cod: respostas_1.codigosResposta.sucesso, + valor: entrada.valor, + mensagem: undefined, + eErro: false, + codigoELicencie: entrada.codigo, + erroELicencie: undefined, + 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 + cod: mapaCodigoELicencieParaPResposta[entrada.codigo], + valor: undefined, + mensagem: entrada.erro, + eErro: true, + codigoELicencie: entrada.codigo, + erroELicencie: entrada.erro, + 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 -}); +exports.converterRespostaELicencieParaPResposta = converterRespostaELicencieParaPResposta; diff --git a/dist-back/index.js b/dist-back/index.js index 5042b75..fa9c4c8 100644 --- a/dist-back/index.js +++ b/dist-back/index.js @@ -1,24 +1,19 @@ "use strict"; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __hasOwnProp = Object.prototype.hasOwnProperty; -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; +// Re-export da API pública do pacote. +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; -var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); -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") -}); +Object.defineProperty(exports, "__esModule", { value: true }); +__exportStar(require("./converter-resposta-e-licencie-para-p-resposta"), exports); +__exportStar(require("./respostas"), exports); diff --git a/dist-back/respostas.js b/dist-back/respostas.js index 69e4cd8..8220c97 100644 --- a/dist-back/respostas.js +++ b/dist-back/respostas.js @@ -1,162 +1,156 @@ "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 respostas_exports = {}; -__export(respostas_exports, { - IniciarRespostas: () => IniciarRespostas, - codigosResposta: () => codigosResposta, - gerarRespostas: () => gerarRespostas, - respostaComuns: () => respostaComuns -}); -module.exports = __toCommonJS(respostas_exports); -var codigosResposta = /* @__PURE__ */ ((codigosResposta2) => { - codigosResposta2[codigosResposta2["sucesso"] = 200] = "sucesso"; - codigosResposta2[codigosResposta2["erroConhecido"] = 400] = "erroConhecido"; - codigosResposta2[codigosResposta2["erroPermissao"] = 401] = "erroPermissao"; - codigosResposta2[codigosResposta2["erroNaoEncontrado"] = 404] = "erroNaoEncontrado"; - codigosResposta2[codigosResposta2["erroDesconhecido"] = 500] = "erroDesconhecido"; - codigosResposta2[codigosResposta2["tempoEsgotado"] = 504] = "tempoEsgotado"; - return codigosResposta2; -})(codigosResposta || {}); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.respostaComuns = exports.gerarRespostas = exports.IniciarRespostas = exports.codigosResposta = void 0; +/** + * Códigos padrão usados pelo contrato de respostas. + * + * Observação: este enum é parte da API pública do pacote. + */ +var codigosResposta; +(function (codigosResposta) { + codigosResposta[codigosResposta["sucesso"] = 200] = "sucesso"; + codigosResposta[codigosResposta["erroConhecido"] = 400] = "erroConhecido"; + codigosResposta[codigosResposta["erroPermissao"] = 401] = "erroPermissao"; + codigosResposta[codigosResposta["erroNaoEncontrado"] = 404] = "erroNaoEncontrado"; + codigosResposta[codigosResposta["erroDesconhecido"] = 500] = "erroDesconhecido"; + codigosResposta[codigosResposta["tempoEsgotado"] = 504] = "tempoEsgotado"; +})(codigosResposta || (exports.codigosResposta = codigosResposta = {})); +// ─── 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, callback) { - if (!callback) return resposta; - return callback(resposta); + if (!callback) + return resposta; + return callback(resposta); } -const IniciarRespostas = (callback) => { - const valor = (valor2, detalhes) => { - const resposta = { - cod: 200 /* sucesso */, - valor: valor2, - mensagem: void 0, - eErro: false, - eCerto: true, - detalhes +const IniciarRespostas = ( +/** Callback opcional de interceptação — invocado após a construção de cada resposta */ +callback) => { + const valor = (valor, detalhes) => { + const resposta = { + cod: codigosResposta.sucesso, + valor, + mensagem: undefined, + eErro: false, + eCerto: true, + detalhes, + }; + return aplicarCallback(resposta, callback); }; - return aplicarCallback(resposta, callback); - }; - const valorTrue = (detalhes) => { - const resposta = { - cod: 200 /* sucesso */, - valor: true, - mensagem: void 0, - eErro: false, - eCerto: true, - detalhes + const valorTrue = (detalhes) => { + const resposta = { + cod: codigosResposta.sucesso, + valor: true, + mensagem: undefined, + eErro: false, + eCerto: true, + detalhes, + }; + return aplicarCallback(resposta, callback); }; - return aplicarCallback(resposta, callback); - }; - const erro = (mensagem, detalhes) => { - const resposta = { - cod: 400 /* erroConhecido */, - valor: void 0, - mensagem, - eErro: true, - eCerto: false, - detalhes + const erro = (mensagem, detalhes) => { + const resposta = { + cod: codigosResposta.erroConhecido, + valor: undefined, + mensagem, + eErro: true, + eCerto: false, + detalhes, + }; + return aplicarCallback(resposta, callback); }; - return aplicarCallback(resposta, callback); - }; - const erroPermissao = (mensagem, detalhes) => { - const resposta = { - cod: 401 /* erroPermissao */, - valor: void 0, - mensagem: mensagem || "Sem permiss\xE3o para esse recurso.", - eErro: true, - eCerto: false, - detalhes + const erroPermissao = (mensagem, detalhes) => { + const resposta = { + cod: codigosResposta.erroPermissao, + valor: undefined, + mensagem: mensagem || "Sem permissão para esse recurso.", + eErro: true, + eCerto: false, + detalhes, + }; + return aplicarCallback(resposta, callback); }; - return aplicarCallback(resposta, callback); - }; - const naoEncontrado = (mensagem, detalhes) => { - const resposta = { - 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.", - eErro: true, - eCerto: false, - detalhes + const naoEncontrado = (mensagem, detalhes) => { + const resposta = { + cod: codigosResposta.erroNaoEncontrado, + valor: undefined, + mensagem: mensagem || + "Registro não encontrado ou a execução dessa ação depende de um registro existente.", + eErro: true, + eCerto: false, + detalhes, + }; + return aplicarCallback(resposta, callback); }; - return aplicarCallback(resposta, callback); - }; - const erroInterno = (op) => { - const mensagemFim = `${op.mensagem || "Erro interno"}`; - const resposta = { - cod: 500 /* erroDesconhecido */, - valor: void 0, - mensagem: mensagemFim, - eErro: true, - eCerto: false + const erroInterno = (op) => { + const mensagemFim = `${op.mensagem || "Erro interno"}`; + const resposta = { + cod: codigosResposta.erroDesconhecido, + valor: undefined, + mensagem: mensagemFim, + eErro: true, + eCerto: false, + }; + return aplicarCallback(resposta, callback); }; - return aplicarCallback(resposta, callback); - }; - const tempoEsgotado = (mensagem, detalhes) => { - const resposta = { - cod: 504 /* tempoEsgotado */, - valor: void 0, - mensagem: mensagem || "Tempo de resposta esgotado ao tentar acessar o recurso.", - eErro: true, - eCerto: false, - detalhes + const tempoEsgotado = (mensagem, detalhes) => { + const resposta = { + cod: codigosResposta.tempoEsgotado, + valor: undefined, + mensagem: mensagem || "Tempo de resposta esgotado ao tentar acessar o recurso.", + eErro: true, + eCerto: false, + detalhes, + }; + return aplicarCallback(resposta, callback); + }; + const erroEspera = tempoEsgotado; + return { + /** + * Gera uma resposta de sucesso + */ + valor, + /** + * Gera uma resposta de sucesso com valor true + */ + valorTrue, + /** + * Gera uma resposta de erro conhecido + */ + erro, + /** + * Gera uma resposta de erro de permissão,será necessário fazer o login novamente + */ + erroPermissao, + /** + * Gera uma resposta de erro desconhecido, geralmente tem origem de um exception + */ + erroInterno, + /** + * Gera uma resposta de erro quando um registro não é encontrado ou sua execução depende de um registro existente + */ + naoEncontrado, + /** + * Gera uma resposta de erro quando o tempo de resposta é esgotado + */ + tempoEsgotado, + /** + * Gera uma resposta de erro quando o tempo de resposta é esgotado + */ + erroEspera, }; - return aplicarCallback(resposta, callback); - }; - const erroEspera = tempoEsgotado; - return { - /** - * Gera uma resposta de sucesso - */ - valor, - /** - * Gera uma resposta de sucesso com valor true - */ - valorTrue, - /** - * Gera uma resposta de erro conhecido - */ - erro, - /** - * Gera uma resposta de erro de permissão,será necessário fazer o login novamente - */ - erroPermissao, - /** - * Gera uma resposta de erro desconhecido, geralmente tem origem de um exception - */ - erroInterno, - /** - * Gera uma resposta de erro quando um registro não é encontrado ou sua execução depende de um registro existente - */ - naoEncontrado, - /** - * Gera uma resposta de erro quando o tempo de resposta é esgotado - */ - tempoEsgotado, - /** - * Gera uma resposta de erro quando o tempo de resposta é esgotado - */ - erroEspera - }; }; -const gerarRespostas = IniciarRespostas; -const respostaComuns = IniciarRespostas(); -// Annotate the CommonJS export names for ESM import in node: -0 && (module.exports = { - IniciarRespostas, - codigosResposta, - gerarRespostas, - respostaComuns -}); +exports.IniciarRespostas = IniciarRespostas; +/** + * @deprecated Use IniciarRespostas em seu lugar + */ +exports.gerarRespostas = exports.IniciarRespostas; +/** + * Instância default (sem handler de interceptação). + */ +exports.respostaComuns = (0, exports.IniciarRespostas)(); diff --git a/dist-front/converter-resposta-e-licencie-para-p-resposta.js b/dist-front/converter-resposta-e-licencie-para-p-resposta.js new file mode 100644 index 0000000..81a0620 --- /dev/null +++ b/dist-front/converter-resposta-e-licencie-para-p-resposta.js @@ -0,0 +1,150 @@ +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, + }); +}; diff --git a/dist-front/index.d.mts b/dist-front/index.d.mts deleted file mode 100644 index b21d47f..0000000 --- a/dist-front/index.d.mts +++ /dev/null @@ -1,136 +0,0 @@ -/** - * Códigos padrão usados pelo contrato de respostas. - * - * Observação: este enum é parte da API pública do pacote. - */ -declare enum codigosResposta { - sucesso = 200, - erroConhecido = 400, - erroPermissao = 401, - erroNaoEncontrado = 404, - erroDesconhecido = 500, - tempoEsgotado = 504 -} -type tipoRespostaSucesso = { - cod: codigosResposta.sucesso; - valor: T; - mensagem: undefined; - eErro: false; - eCerto: true; - detalhes?: string[]; -}; -type tipoRespostaErro = { - cod: codigosResposta.erroConhecido | codigosResposta.erroDesconhecido | codigosResposta.erroPermissao | codigosResposta.erroNaoEncontrado | codigosResposta.tempoEsgotado; - valor: undefined; - mensagem: string; - eErro: true; - eCerto: false; - detalhes?: string[]; -}; -type tipoResposta = tipoRespostaSucesso | tipoRespostaErro; -type tipoPrErroInterno = { - erro: any; - mensagem?: string; - 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. - * - * @param registrarErroInterno callback para registrar/normalizar erros internos. - */ -interface InterfaceRespostas { - valor: (valor: T, detalhes?: string[]) => tipoRespostaSucesso; - valorTrue: (detalhes?: string[]) => tipoRespostaSucesso; - erro: (mensagem: string, detalhes?: string[]) => tipoRespostaErro; - erroPermissao: (mensagem?: string | undefined | null, detalhes?: string[]) => tipoRespostaErro; - erroInterno: (op: tipoPrErroInterno) => tipoRespostaErro; - naoEncontrado: (mensagem?: string | undefined | null, detalhes?: string[]) => tipoRespostaErro; - 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: (callback?: tipoCallbackResposta) => InterfaceRespostas; -/** - * Instância default (sem handler de interceptação). - */ -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 }; diff --git a/dist-front/index.js b/dist-front/index.js new file mode 100644 index 0000000..1192c29 --- /dev/null +++ b/dist-front/index.js @@ -0,0 +1,3 @@ +// Re-export da API pública do pacote. +export * from "./converter-resposta-e-licencie-para-p-resposta"; +export * from "./respostas"; diff --git a/dist-front/index.mjs b/dist-front/index.mjs deleted file mode 100644 index 985850d..0000000 --- a/dist-front/index.mjs +++ /dev/null @@ -1 +0,0 @@ -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}; diff --git a/dist-front/respostas.js b/dist-front/respostas.js new file mode 100644 index 0000000..0ddcf95 --- /dev/null +++ b/dist-front/respostas.js @@ -0,0 +1,152 @@ +/** + * Códigos padrão usados pelo contrato de respostas. + * + * Observação: este enum é parte da API pública do pacote. + */ +export var codigosResposta; +(function (codigosResposta) { + codigosResposta[codigosResposta["sucesso"] = 200] = "sucesso"; + codigosResposta[codigosResposta["erroConhecido"] = 400] = "erroConhecido"; + codigosResposta[codigosResposta["erroPermissao"] = 401] = "erroPermissao"; + codigosResposta[codigosResposta["erroNaoEncontrado"] = 404] = "erroNaoEncontrado"; + codigosResposta[codigosResposta["erroDesconhecido"] = 500] = "erroDesconhecido"; + codigosResposta[codigosResposta["tempoEsgotado"] = 504] = "tempoEsgotado"; +})(codigosResposta || (codigosResposta = {})); +// ─── 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, callback) { + if (!callback) + return resposta; + return callback(resposta); +} +export const IniciarRespostas = ( +/** Callback opcional de interceptação — invocado após a construção de cada resposta */ +callback) => { + const valor = (valor, detalhes) => { + const resposta = { + cod: codigosResposta.sucesso, + valor, + mensagem: undefined, + eErro: false, + eCerto: true, + detalhes, + }; + return aplicarCallback(resposta, callback); + }; + const valorTrue = (detalhes) => { + const resposta = { + cod: codigosResposta.sucesso, + valor: true, + mensagem: undefined, + eErro: false, + eCerto: true, + detalhes, + }; + return aplicarCallback(resposta, callback); + }; + const erro = (mensagem, detalhes) => { + const resposta = { + cod: codigosResposta.erroConhecido, + valor: undefined, + mensagem, + eErro: true, + eCerto: false, + detalhes, + }; + return aplicarCallback(resposta, callback); + }; + const erroPermissao = (mensagem, detalhes) => { + const resposta = { + cod: codigosResposta.erroPermissao, + valor: undefined, + mensagem: mensagem || "Sem permissão para esse recurso.", + eErro: true, + eCerto: false, + detalhes, + }; + return aplicarCallback(resposta, callback); + }; + const naoEncontrado = (mensagem, detalhes) => { + const resposta = { + cod: codigosResposta.erroNaoEncontrado, + valor: undefined, + mensagem: mensagem || + "Registro não encontrado ou a execução dessa ação depende de um registro existente.", + eErro: true, + eCerto: false, + detalhes, + }; + return aplicarCallback(resposta, callback); + }; + const erroInterno = (op) => { + const mensagemFim = `${op.mensagem || "Erro interno"}`; + const resposta = { + cod: codigosResposta.erroDesconhecido, + valor: undefined, + mensagem: mensagemFim, + eErro: true, + eCerto: false, + }; + return aplicarCallback(resposta, callback); + }; + const tempoEsgotado = (mensagem, detalhes) => { + const resposta = { + cod: codigosResposta.tempoEsgotado, + valor: undefined, + mensagem: mensagem || "Tempo de resposta esgotado ao tentar acessar o recurso.", + eErro: true, + eCerto: false, + detalhes, + }; + return aplicarCallback(resposta, callback); + }; + const erroEspera = tempoEsgotado; + return { + /** + * Gera uma resposta de sucesso + */ + valor, + /** + * Gera uma resposta de sucesso com valor true + */ + valorTrue, + /** + * Gera uma resposta de erro conhecido + */ + erro, + /** + * Gera uma resposta de erro de permissão,será necessário fazer o login novamente + */ + erroPermissao, + /** + * Gera uma resposta de erro desconhecido, geralmente tem origem de um exception + */ + erroInterno, + /** + * Gera uma resposta de erro quando um registro não é encontrado ou sua execução depende de um registro existente + */ + naoEncontrado, + /** + * Gera uma resposta de erro quando o tempo de resposta é esgotado + */ + tempoEsgotado, + /** + * Gera uma resposta de erro quando o tempo de resposta é esgotado + */ + erroEspera, + }; +}; +/** + * @deprecated Use IniciarRespostas em seu lugar + */ +export const gerarRespostas = IniciarRespostas; +/** + * Instância default (sem handler de interceptação). + */ +export const respostaComuns = IniciarRespostas(); diff --git a/package.json b/package.json index 335f634..7798345 100644 --- a/package.json +++ b/package.json @@ -1,38 +1,38 @@ { "name": "p-respostas", - "version": "0.69.0", + "version": "0.70.0", "description": "Contrato simples de respostas (sucesso/erro) para APIs e serviços.", "main": "./dist-back/index.js", - "module": "./dist-front/index.mjs", + "module": "./dist-front/index.js", "exports": { ".": { - "types": "./dist-front/index.d.mts", - "import": "./dist-front/index.mjs", + "types": "./src/index.ts", + "import": "./dist-front/index.js", "require": "./dist-back/index.js" } }, - "types": "./dist-front/index.d.mts", + "types": "./src/index.ts", "engines": { "node": ">=20" }, "sideEffects": false, "scripts": { - "biome": "npx @biomejs/biome check --write ./src", - "build": "npm --no-git-tag-version version minor && pnpm run biome && tsup --config ./node_modules/p-comuns/tsup/tsup.config.ts && pnpm run pacote", - "nodev": "check-node-version --node '= 22'", - "pacote": "npm pack && npm pack && mv $(npm pack --silent) pacote.tgz" + "biome": "biome check --write ./src", + "build": "npm --no-git-tag-version version minor && bun run biome && bun x tsc -p tsconfig-back.json && bun x tsc -p tsconfig-front.json", + "check": "bun run biome && bun x tsc --noEmit", + "test": "bun test tests/", + "teste": "bun test tests/" }, "peerDependencies": { - "p-comuns": "git+https://git2.idz.one/publico/_comuns.git", + "p-comuns": "git+https://git2.idz.one/publico/_comuns.git#bun", "zod": "4.4.3" }, "devDependencies": { - "@biomejs/biome": "2.4.12", + "@biomejs/biome": "^2", + "@types/bun": "^1.4.2", "@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", + "p-comuns": "git+https://git2.idz.one/publico/_comuns.git#bun", + "typescript": "^7", "zod": "4.4.3" }, "keywords": [], diff --git a/pacote.tgz b/pacote.tgz deleted file mode 100644 index 0ca8ea1..0000000 Binary files a/pacote.tgz and /dev/null differ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 8875ff0..0000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,1175 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - devDependencies: - '@biomejs/biome': - specifier: 2.4.0 - version: 2.4.0 - '@types/node': - specifier: ^22.19.15 - version: 22.19.15 - check-node-version: - specifier: ^4.2.1 - version: 4.2.1 - p-comuns: - specifier: git+https://git2.idz.one/publico/_comuns.git - version: git+https://git2.idz.one/publico/_comuns.git#0a6ce2e323918c3bc855cdba154ed90f576092b2(cross-fetch@4.1.0)(dayjs@1.11.20)(uuid@11.1.0)(zod@4.3.6) - tsup: - specifier: ^8.5.1 - version: 8.5.1(typescript@6.0.2) - typescript: - specifier: ^6 - version: 6.0.2 - zod: - specifier: 4.3.6 - version: 4.3.6 - -packages: - - '@biomejs/biome@2.4.0': - resolution: {integrity: sha512-iluT61cORUDIC5i/y42ljyQraCemmmcgbMLLCnYO+yh+2hjTmcMFcwY8G0zTzWCsPb3t3AyKc+0t/VuhPZULUg==} - engines: {node: '>=14.21.3'} - hasBin: true - - '@biomejs/cli-darwin-arm64@2.4.0': - resolution: {integrity: sha512-L+YpOtPSuU0etomfvFTPWRsa7+8ejaJL3yaROEoT/96HDJbR6OsvZQk0C8JUYou+XFdP+JcGxqZknkp4n934RA==} - engines: {node: '>=14.21.3'} - cpu: [arm64] - os: [darwin] - - '@biomejs/cli-darwin-x64@2.4.0': - resolution: {integrity: sha512-Aq+S7ffpb5ynTyLgtnEjG+W6xuTd2F7FdC7J6ShpvRhZwJhjzwITGF9vrqoOnw0sv1XWkt2Q1Rpg+hleg/Xg7Q==} - engines: {node: '>=14.21.3'} - cpu: [x64] - os: [darwin] - - '@biomejs/cli-linux-arm64-musl@2.4.0': - resolution: {integrity: sha512-1rhDUq8sf7xX3tg7vbnU3WVfanKCKi40OXc4VleBMzRStmQHdeBY46aFP6VdwEomcVjyNiu+Zcr3LZtAdrZrjQ==} - engines: {node: '>=14.21.3'} - cpu: [arm64] - os: [linux] - - '@biomejs/cli-linux-arm64@2.4.0': - resolution: {integrity: sha512-u2p54IhvNAWB+h7+rxCZe3reNfQYFK+ppDw+q0yegrGclFYnDPZAntv/PqgUacpC3uxTeuWFgWW7RFe3lHuxOA==} - engines: {node: '>=14.21.3'} - cpu: [arm64] - os: [linux] - - '@biomejs/cli-linux-x64-musl@2.4.0': - resolution: {integrity: sha512-Omo0xhl63z47X+CrE5viEWKJhejJyndl577VoXg763U/aoATrK3r5+8DPh02GokWPeODX1Hek00OtjjooGan9w==} - engines: {node: '>=14.21.3'} - cpu: [x64] - os: [linux] - - '@biomejs/cli-linux-x64@2.4.0': - resolution: {integrity: sha512-WVFOhsnzhrbMGOSIcB9yFdRV2oG2KkRRhIZiunI9gJqSU3ax9ErdnTxRfJUxZUI9NbzVxC60OCXNcu+mXfF/Tw==} - engines: {node: '>=14.21.3'} - cpu: [x64] - os: [linux] - - '@biomejs/cli-win32-arm64@2.4.0': - resolution: {integrity: sha512-aqRwW0LJLV1v1NzyLvLWQhdLmDSAV1vUh+OBdYJaa8f28XBn5BZavo+WTfqgEzALZxlNfBmu6NGO6Al3MbCULw==} - engines: {node: '>=14.21.3'} - cpu: [arm64] - os: [win32] - - '@biomejs/cli-win32-x64@2.4.0': - resolution: {integrity: sha512-g47s+V+OqsGxbSZN3lpav6WYOk0PIc3aCBAq+p6dwSynL3K5MA6Cg6nkzDOlu28GEHwbakW+BllzHCJCxnfK5Q==} - engines: {node: '>=14.21.3'} - cpu: [x64] - os: [win32] - - '@esbuild/aix-ppc64@0.27.5': - resolution: {integrity: sha512-nGsF/4C7uzUj+Nj/4J+Zt0bYQ6bz33Phz8Lb2N80Mti1HjGclTJdXZ+9APC4kLvONbjxN1zfvYNd8FEcbBK/MQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.27.5': - resolution: {integrity: sha512-Oeghq+XFgh1pUGd1YKs4DDoxzxkoUkvko+T/IVKwlghKLvvjbGFB3ek8VEDBmNvqhwuL0CQS3cExdzpmUyIrgA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.27.5': - resolution: {integrity: sha512-Cv781jd0Rfj/paoNrul1/r4G0HLvuFKYh7C9uHZ2Pl8YXstzvCyyeWENTFR9qFnRzNMCjXmsulZuvosDg10Mog==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.27.5': - resolution: {integrity: sha512-nQD7lspbzerlmtNOxYMFAGmhxgzn8Z7m9jgFkh6kpkjsAhZee1w8tJW3ZlW+N9iRePz0oPUDrYrXidCPSImD0Q==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.27.5': - resolution: {integrity: sha512-I+Ya/MgC6rr8oRWGRDF3BXDfP8K1BVUggHqN6VI2lUZLdDi1IM1v2cy0e3lCPbP+pVcK3Tv8cgUhHse1kaNZZw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.27.5': - resolution: {integrity: sha512-MCjQUtC8wWJn/pIPM7vQaO69BFgwPD1jriEdqwTCKzWjGgkMbcg+M5HzrOhPhuYe1AJjXlHmD142KQf+jnYj8A==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.27.5': - resolution: {integrity: sha512-X6xVS+goSH0UelYXnuf4GHLwpOdc8rgK/zai+dKzBMnncw7BTQIwquOodE7EKvY2UVUetSqyAfyZC1D+oqLQtg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.27.5': - resolution: {integrity: sha512-233X1FGo3a8x1ekLB6XT69LfZ83vqz+9z3TSEQCTYfMNY880A97nr81KbPcAMl9rmOFp11wO0dP+eB18KU/Ucg==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.27.5': - resolution: {integrity: sha512-euKkilsNOv7x/M1NKsx5znyprbpsRFIzTV6lWziqJch7yWYayfLtZzDxDTl+LSQDJYAjd9TVb/Kt5UKIrj2e4A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.27.5': - resolution: {integrity: sha512-0wkVrYHG4sdCCN/bcwQ7yYMXACkaHc3UFeaEOwSVW6e5RycMageYAFv+JS2bKLwHyeKVUvtoVH+5/RHq0fgeFw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.27.5': - resolution: {integrity: sha512-hVRQX4+P3MS36NxOy24v/Cdsimy/5HYePw+tmPqnNN1fxV0bPrFWR6TMqwXPwoTM2VzbkA+4lbHWUKDd5ZDA/w==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.27.5': - resolution: {integrity: sha512-mKqqRuOPALI8nDzhOBmIS0INvZOOFGGg5n1osGIXAx8oersceEbKd4t1ACNTHM3sJBXGFAlEgqM+svzjPot+ZQ==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.27.5': - resolution: {integrity: sha512-EE/QXH9IyaAj1qeuIV5+/GZkBTipgGO782Ff7Um3vPS9cvLhJJeATy4Ggxikz2inZ46KByamMn6GqtqyVjhenA==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.27.5': - resolution: {integrity: sha512-0V2iF1RGxBf1b7/BjurA5jfkl7PtySjom1r6xOK2q9KWw/XCpAdtB6KNMO+9xx69yYfSCRR9FE0TyKfHA2eQMw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.27.5': - resolution: {integrity: sha512-rYxThBx6G9HN6tFNuvB/vykeLi4VDsm5hE5pVwzqbAjZEARQrWu3noZSfbEnPZ/CRXP3271GyFk/49up2W190g==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.27.5': - resolution: {integrity: sha512-uEP2q/4qgd8goEUc4QIdU/1P2NmEtZ/zX5u3OpLlCGhJIuBIv0s0wr7TB2nBrd3/A5XIdEkkS5ZLF0ULuvaaYQ==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.27.5': - resolution: {integrity: sha512-+Gq47Wqq6PLOOZuBzVSII2//9yyHNKZLuwfzCemqexqOQCSz0zy0O26kIzyp9EMNMK+nZ0tFHBZrCeVUuMs/ew==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.27.5': - resolution: {integrity: sha512-3F/5EG8VHfN/I+W5cO1/SV2H9Q/5r7vcHabMnBqhHK2lTWOh3F8vixNzo8lqxrlmBtZVFpW8pmITHnq54+Tq4g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.27.5': - resolution: {integrity: sha512-28t+Sj3CPN8vkMOlZotOmDgilQwVvxWZl7b8rxpn73Tt/gCnvrHxQUMng4uu3itdFvrtba/1nHejvxqz8xgEMA==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.27.5': - resolution: {integrity: sha512-Doz/hKtiuVAi9hMsBMpwBANhIZc8l238U2Onko3t2xUp8xtM0ZKdDYHMnm/qPFVthY8KtxkXaocwmMh6VolzMA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.27.5': - resolution: {integrity: sha512-WfGVaa1oz5A7+ZFPkERIbIhKT4olvGl1tyzTRaB5yoZRLqC0KwaO95FeZtOdQj/oKkjW57KcVF944m62/0GYtA==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.27.5': - resolution: {integrity: sha512-Xh+VRuh6OMh3uJ0JkCjI57l+DVe7VRGBYymen8rFPnTVgATBwA6nmToxM2OwTlSvrnWpPKkrQUj93+K9huYC6A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.27.5': - resolution: {integrity: sha512-aC1gpJkkaUADHuAdQfuVTnqVUTLqqUNhAvEwHwVWcnVVZvNlDPGA0UveZsfXJJ9T6k9Po4eHi3c02gbdwO3g6w==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.27.5': - resolution: {integrity: sha512-0UNx2aavV0fk6UpZcwXFLztA2r/k9jTUa7OW7SAea1VYUhkug99MW1uZeXEnPn5+cHOd0n8myQay6TlFnBR07w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.27.5': - resolution: {integrity: sha512-5nlJ3AeJWCTSzR7AEqVjT/faWyqKU86kCi1lLmxVqmNR+j4HrYdns+eTGjS/vmrzCIe8inGQckUadvS0+JkKdQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.27.5': - resolution: {integrity: sha512-PWypQR+d4FLfkhBIV+/kHsUELAnMpx1bRvvsn3p+/sAERbnCzFrtDRG2Xw5n+2zPxBK2+iaP+vetsRl4Ti7WgA==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@rollup/rollup-android-arm-eabi@4.60.1': - resolution: {integrity: sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.60.1': - resolution: {integrity: sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.60.1': - resolution: {integrity: sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.60.1': - resolution: {integrity: sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.60.1': - resolution: {integrity: sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.60.1': - resolution: {integrity: sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.60.1': - resolution: {integrity: sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.60.1': - resolution: {integrity: sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.60.1': - resolution: {integrity: sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.60.1': - resolution: {integrity: sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loong64-gnu@4.60.1': - resolution: {integrity: sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-loong64-musl@4.60.1': - resolution: {integrity: sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-ppc64-gnu@4.60.1': - resolution: {integrity: sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-ppc64-musl@4.60.1': - resolution: {integrity: sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.60.1': - resolution: {integrity: sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-musl@4.60.1': - resolution: {integrity: sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.60.1': - resolution: {integrity: sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.60.1': - resolution: {integrity: sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.60.1': - resolution: {integrity: sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-openbsd-x64@4.60.1': - resolution: {integrity: sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.60.1': - resolution: {integrity: sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.60.1': - resolution: {integrity: sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.60.1': - resolution: {integrity: sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.60.1': - resolution: {integrity: sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.60.1': - resolution: {integrity: sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==} - cpu: [x64] - os: [win32] - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/node@22.19.15': - resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} - - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} - engines: {node: '>=0.4.0'} - hasBin: true - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - bundle-require@5.1.0: - resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - peerDependencies: - esbuild: '>=0.18' - - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - chalk@3.0.0: - resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} - engines: {node: '>=8'} - - check-node-version@4.2.1: - resolution: {integrity: sha512-YYmFYHV/X7kSJhuN/QYHUu998n/TRuDe8UenM3+m5NrkiH670lb9ILqHIvBencvJc4SDh+XcbXMR4b+TtubJiw==} - engines: {node: '>=8.3.0'} - hasBin: true - - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} - - cross-fetch@4.1.0: - resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} - - dayjs@1.11.20: - resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - esbuild@0.27.5: - resolution: {integrity: sha512-zdQoHBjuDqKsvV5OPaWansOwfSQ0Js+Uj9J85TBvj3bFW1JjWTSULMRwdQAc8qMeIScbClxeMK0jlrtB9linhA==} - engines: {node: '>=18'} - hasBin: true - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - fix-dts-default-cjs-exports@1.0.1: - resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} - engines: {node: '>=10'} - - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - load-tsconfig@0.2.5: - resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - map-values@1.0.1: - resolution: {integrity: sha512-BbShUnr5OartXJe1GeccAWtfro11hhgNJg6G9/UtWKjVGvV5U4C09cg5nk8JUevhXODaXY+hQ3xxMUKSs62ONQ==} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - mlly@1.8.2: - resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-filter@1.0.2: - resolution: {integrity: sha512-NahvP2vZcy1ZiiYah30CEPw0FpDcSkSePJBMpzl5EQgCmISijiGuJm3SPYp7U+Lf2TljyaIw3E5EgkEx/TNEVA==} - - p-comuns@git+https://git2.idz.one/publico/_comuns.git#0a6ce2e323918c3bc855cdba154ed90f576092b2: - resolution: {commit: 0a6ce2e323918c3bc855cdba154ed90f576092b2, repo: https://git2.idz.one/publico/_comuns.git, type: git} - version: 0.317.0 - peerDependencies: - cross-fetch: 4.1.0 - dayjs: ^1.11.18 - uuid: ^11.1.0 - zod: 4.1.4 - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} - engines: {node: '>=12'} - - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} - - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - - postcss-load-config@6.0.1: - resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} - engines: {node: '>= 18'} - peerDependencies: - jiti: '>=1.21.0' - postcss: '>=8.0.9' - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - jiti: - optional: true - postcss: - optional: true - tsx: - optional: true - yaml: - optional: true - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - rollup@4.60.1: - resolution: {integrity: sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} - - sucrase@3.35.1: - resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} - - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - - tsup@8.5.1: - resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - '@microsoft/api-extractor': ^7.36.0 - '@swc/core': ^1 - postcss: ^8.4.12 - typescript: '>=4.5.0' - peerDependenciesMeta: - '@microsoft/api-extractor': - optional: true - '@swc/core': - optional: true - postcss: - optional: true - typescript: - optional: true - - typescript@6.0.2: - resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==} - engines: {node: '>=14.17'} - hasBin: true - - ufo@1.6.3: - resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - uuid@11.1.0: - resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} - hasBin: true - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - - zod@4.3.6: - resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} - -snapshots: - - '@biomejs/biome@2.4.0': - optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.4.0 - '@biomejs/cli-darwin-x64': 2.4.0 - '@biomejs/cli-linux-arm64': 2.4.0 - '@biomejs/cli-linux-arm64-musl': 2.4.0 - '@biomejs/cli-linux-x64': 2.4.0 - '@biomejs/cli-linux-x64-musl': 2.4.0 - '@biomejs/cli-win32-arm64': 2.4.0 - '@biomejs/cli-win32-x64': 2.4.0 - - '@biomejs/cli-darwin-arm64@2.4.0': - optional: true - - '@biomejs/cli-darwin-x64@2.4.0': - optional: true - - '@biomejs/cli-linux-arm64-musl@2.4.0': - optional: true - - '@biomejs/cli-linux-arm64@2.4.0': - optional: true - - '@biomejs/cli-linux-x64-musl@2.4.0': - optional: true - - '@biomejs/cli-linux-x64@2.4.0': - optional: true - - '@biomejs/cli-win32-arm64@2.4.0': - optional: true - - '@biomejs/cli-win32-x64@2.4.0': - optional: true - - '@esbuild/aix-ppc64@0.27.5': - optional: true - - '@esbuild/android-arm64@0.27.5': - optional: true - - '@esbuild/android-arm@0.27.5': - optional: true - - '@esbuild/android-x64@0.27.5': - optional: true - - '@esbuild/darwin-arm64@0.27.5': - optional: true - - '@esbuild/darwin-x64@0.27.5': - optional: true - - '@esbuild/freebsd-arm64@0.27.5': - optional: true - - '@esbuild/freebsd-x64@0.27.5': - optional: true - - '@esbuild/linux-arm64@0.27.5': - optional: true - - '@esbuild/linux-arm@0.27.5': - optional: true - - '@esbuild/linux-ia32@0.27.5': - optional: true - - '@esbuild/linux-loong64@0.27.5': - optional: true - - '@esbuild/linux-mips64el@0.27.5': - optional: true - - '@esbuild/linux-ppc64@0.27.5': - optional: true - - '@esbuild/linux-riscv64@0.27.5': - optional: true - - '@esbuild/linux-s390x@0.27.5': - optional: true - - '@esbuild/linux-x64@0.27.5': - optional: true - - '@esbuild/netbsd-arm64@0.27.5': - optional: true - - '@esbuild/netbsd-x64@0.27.5': - optional: true - - '@esbuild/openbsd-arm64@0.27.5': - optional: true - - '@esbuild/openbsd-x64@0.27.5': - optional: true - - '@esbuild/openharmony-arm64@0.27.5': - optional: true - - '@esbuild/sunos-x64@0.27.5': - optional: true - - '@esbuild/win32-arm64@0.27.5': - optional: true - - '@esbuild/win32-ia32@0.27.5': - optional: true - - '@esbuild/win32-x64@0.27.5': - optional: true - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@rollup/rollup-android-arm-eabi@4.60.1': - optional: true - - '@rollup/rollup-android-arm64@4.60.1': - optional: true - - '@rollup/rollup-darwin-arm64@4.60.1': - optional: true - - '@rollup/rollup-darwin-x64@4.60.1': - optional: true - - '@rollup/rollup-freebsd-arm64@4.60.1': - optional: true - - '@rollup/rollup-freebsd-x64@4.60.1': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.60.1': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.60.1': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.60.1': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.60.1': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.60.1': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.60.1': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.60.1': - optional: true - - '@rollup/rollup-linux-ppc64-musl@4.60.1': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.60.1': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.60.1': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.60.1': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.60.1': - optional: true - - '@rollup/rollup-linux-x64-musl@4.60.1': - optional: true - - '@rollup/rollup-openbsd-x64@4.60.1': - optional: true - - '@rollup/rollup-openharmony-arm64@4.60.1': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.60.1': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.60.1': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.60.1': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.60.1': - optional: true - - '@types/estree@1.0.8': {} - - '@types/node@22.19.15': - dependencies: - undici-types: 6.21.0 - - acorn@8.16.0: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - any-promise@1.3.0: {} - - bundle-require@5.1.0(esbuild@0.27.5): - dependencies: - esbuild: 0.27.5 - load-tsconfig: 0.2.5 - - cac@6.7.14: {} - - chalk@3.0.0: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - check-node-version@4.2.1: - dependencies: - chalk: 3.0.0 - map-values: 1.0.1 - minimist: 1.2.8 - object-filter: 1.0.2 - run-parallel: 1.2.0 - semver: 6.3.1 - - chokidar@4.0.3: - dependencies: - readdirp: 4.1.2 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - commander@4.1.1: {} - - confbox@0.1.8: {} - - consola@3.4.2: {} - - cross-fetch@4.1.0: - dependencies: - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding - - dayjs@1.11.20: {} - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - esbuild@0.27.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.27.5 - '@esbuild/android-arm': 0.27.5 - '@esbuild/android-arm64': 0.27.5 - '@esbuild/android-x64': 0.27.5 - '@esbuild/darwin-arm64': 0.27.5 - '@esbuild/darwin-x64': 0.27.5 - '@esbuild/freebsd-arm64': 0.27.5 - '@esbuild/freebsd-x64': 0.27.5 - '@esbuild/linux-arm': 0.27.5 - '@esbuild/linux-arm64': 0.27.5 - '@esbuild/linux-ia32': 0.27.5 - '@esbuild/linux-loong64': 0.27.5 - '@esbuild/linux-mips64el': 0.27.5 - '@esbuild/linux-ppc64': 0.27.5 - '@esbuild/linux-riscv64': 0.27.5 - '@esbuild/linux-s390x': 0.27.5 - '@esbuild/linux-x64': 0.27.5 - '@esbuild/netbsd-arm64': 0.27.5 - '@esbuild/netbsd-x64': 0.27.5 - '@esbuild/openbsd-arm64': 0.27.5 - '@esbuild/openbsd-x64': 0.27.5 - '@esbuild/openharmony-arm64': 0.27.5 - '@esbuild/sunos-x64': 0.27.5 - '@esbuild/win32-arm64': 0.27.5 - '@esbuild/win32-ia32': 0.27.5 - '@esbuild/win32-x64': 0.27.5 - - fdir@6.5.0(picomatch@4.0.4): - optionalDependencies: - picomatch: 4.0.4 - - fix-dts-default-cjs-exports@1.0.1: - dependencies: - magic-string: 0.30.21 - mlly: 1.8.2 - rollup: 4.60.1 - - fsevents@2.3.3: - optional: true - - has-flag@4.0.0: {} - - joycon@3.1.1: {} - - lilconfig@3.1.3: {} - - lines-and-columns@1.2.4: {} - - load-tsconfig@0.2.5: {} - - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - map-values@1.0.1: {} - - minimist@1.2.8: {} - - mlly@1.8.2: - dependencies: - acorn: 8.16.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.3 - - ms@2.1.3: {} - - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - - node-fetch@2.7.0: - dependencies: - whatwg-url: 5.0.0 - - object-assign@4.1.1: {} - - object-filter@1.0.2: {} - - p-comuns@git+https://git2.idz.one/publico/_comuns.git#0a6ce2e323918c3bc855cdba154ed90f576092b2(cross-fetch@4.1.0)(dayjs@1.11.20)(uuid@11.1.0)(zod@4.3.6): - dependencies: - cross-fetch: 4.1.0 - dayjs: 1.11.20 - uuid: 11.1.0 - zod: 4.3.6 - - pathe@2.0.3: {} - - picocolors@1.1.1: {} - - picomatch@4.0.4: {} - - pirates@4.0.7: {} - - pkg-types@1.3.1: - dependencies: - confbox: 0.1.8 - mlly: 1.8.2 - pathe: 2.0.3 - - postcss-load-config@6.0.1: - dependencies: - lilconfig: 3.1.3 - - queue-microtask@1.2.3: {} - - readdirp@4.1.2: {} - - resolve-from@5.0.0: {} - - rollup@4.60.1: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.1 - '@rollup/rollup-android-arm64': 4.60.1 - '@rollup/rollup-darwin-arm64': 4.60.1 - '@rollup/rollup-darwin-x64': 4.60.1 - '@rollup/rollup-freebsd-arm64': 4.60.1 - '@rollup/rollup-freebsd-x64': 4.60.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.1 - '@rollup/rollup-linux-arm-musleabihf': 4.60.1 - '@rollup/rollup-linux-arm64-gnu': 4.60.1 - '@rollup/rollup-linux-arm64-musl': 4.60.1 - '@rollup/rollup-linux-loong64-gnu': 4.60.1 - '@rollup/rollup-linux-loong64-musl': 4.60.1 - '@rollup/rollup-linux-ppc64-gnu': 4.60.1 - '@rollup/rollup-linux-ppc64-musl': 4.60.1 - '@rollup/rollup-linux-riscv64-gnu': 4.60.1 - '@rollup/rollup-linux-riscv64-musl': 4.60.1 - '@rollup/rollup-linux-s390x-gnu': 4.60.1 - '@rollup/rollup-linux-x64-gnu': 4.60.1 - '@rollup/rollup-linux-x64-musl': 4.60.1 - '@rollup/rollup-openbsd-x64': 4.60.1 - '@rollup/rollup-openharmony-arm64': 4.60.1 - '@rollup/rollup-win32-arm64-msvc': 4.60.1 - '@rollup/rollup-win32-ia32-msvc': 4.60.1 - '@rollup/rollup-win32-x64-gnu': 4.60.1 - '@rollup/rollup-win32-x64-msvc': 4.60.1 - fsevents: 2.3.3 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - semver@6.3.1: {} - - source-map@0.7.6: {} - - sucrase@3.35.1: - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - commander: 4.1.1 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.7 - tinyglobby: 0.2.15 - ts-interface-checker: 0.1.13 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - - tinyexec@0.3.2: {} - - tinyglobby@0.2.15: - dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - - tr46@0.0.3: {} - - tree-kill@1.2.2: {} - - ts-interface-checker@0.1.13: {} - - tsup@8.5.1(typescript@6.0.2): - dependencies: - bundle-require: 5.1.0(esbuild@0.27.5) - cac: 6.7.14 - chokidar: 4.0.3 - consola: 3.4.2 - debug: 4.4.3 - esbuild: 0.27.5 - fix-dts-default-cjs-exports: 1.0.1 - joycon: 3.1.1 - picocolors: 1.1.1 - postcss-load-config: 6.0.1 - resolve-from: 5.0.0 - rollup: 4.60.1 - source-map: 0.7.6 - sucrase: 3.35.1 - tinyexec: 0.3.2 - tinyglobby: 0.2.15 - tree-kill: 1.2.2 - optionalDependencies: - typescript: 6.0.2 - transitivePeerDependencies: - - jiti - - supports-color - - tsx - - yaml - - typescript@6.0.2: {} - - ufo@1.6.3: {} - - undici-types@6.21.0: {} - - uuid@11.1.0: {} - - webidl-conversions@3.0.1: {} - - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - zod@4.3.6: {} diff --git a/src/converter-resposta-e-licencie-para-p-resposta.ts b/src/converter-resposta-e-licencie-para-p-resposta.ts index 7fffd02..58bfb9d 100644 --- a/src/converter-resposta-e-licencie-para-p-resposta.ts +++ b/src/converter-resposta-e-licencie-para-p-resposta.ts @@ -1,8 +1,4 @@ -import { - codigosResposta, - type tipoResposta, - type tipoRespostaErro, -} from "./respostas" +import { codigosResposta, type tipoResposta, type tipoRespostaErro } from "./respostas" // ─── Tipagem ELicencie ────────────────────────────────────────────── @@ -37,9 +33,7 @@ export interface tipoRespostaErroELicencie { detalhes?: Record } -export type tipoRespostaELicencie = - | tipoRespostaSucessoELicencie - | tipoRespostaErroELicencie +export type tipoRespostaELicencie = tipoRespostaSucessoELicencie | tipoRespostaErroELicencie // ─── Tipo de entrada (transição) ──────────────────────────────────── @@ -52,10 +46,7 @@ export type tipoEntradaTransicao = tipoRespostaELicencie | tipoResposta // ─── Mapeamento bidirecional de códigos ───────────────────────────── /** ELicencie → P-Resposta (403 → 401) */ -const mapaCodigoELicencieParaPResposta: Record< - codigoErroELicencie, - tipoRespostaErro["cod"] -> = { +const mapaCodigoELicencieParaPResposta: Record = { 400: codigosResposta.erroConhecido, 403: codigosResposta.erroPermissao, 500: codigosResposta.erroDesconhecido, @@ -63,10 +54,7 @@ const mapaCodigoELicencieParaPResposta: Record< } /** P-Resposta → ELicencie (401 → 403, 404 → 400) */ -const mapaCodigoPRespostaParaELicencie: Record< - tipoRespostaErro["cod"], - codigoErroELicencie -> = { +const mapaCodigoPRespostaParaELicencie: Record = { [codigosResposta.erroConhecido]: 400, [codigosResposta.erroPermissao]: 403, [codigosResposta.erroDesconhecido]: 500, @@ -77,18 +65,14 @@ const mapaCodigoPRespostaParaELicencie: Record< // ─── Type guard ───────────────────────────────────────────────────── /** Detecta se a entrada já está no formato P-Resposta (possui campo `cod`). */ -function eRespostaPadrao( - entrada: tipoEntradaTransicao, -): entrada is tipoResposta { +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 { +function detalhesParaArray(detalhes?: Record | string[]): string[] | undefined { if (!detalhes) return undefined if (Array.isArray(detalhes)) return detalhes @@ -120,9 +104,7 @@ function montarRespostaDual(op: { }): tipoResposta { const detalhesArray = detalhesParaArray(op.detalhesOriginal) const detalhesRecord = - op.detalhesOriginal && !Array.isArray(op.detalhesOriginal) - ? op.detalhesOriginal - : undefined + op.detalhesOriginal && !Array.isArray(op.detalhesOriginal) ? op.detalhesOriginal : undefined return { // P-Resposta diff --git a/src/respostas.ts b/src/respostas.ts index 8d2104b..e389b95 100644 --- a/src/respostas.ts +++ b/src/respostas.ts @@ -1,3 +1,5 @@ +import z from "zod" + /** * Códigos padrão usados pelo contrato de respostas. * @@ -50,9 +52,7 @@ export type tipoPrErroInterno = { * 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 +export type tipoCallbackResposta = (resposta: tipoResposta) => tipoResposta /** * Cria um conjunto de geradores de respostas. @@ -63,23 +63,11 @@ export interface InterfaceRespostas { valor: (valor: T, detalhes?: string[]) => tipoRespostaSucesso valorTrue: (detalhes?: string[]) => tipoRespostaSucesso erro: (mensagem: string, detalhes?: string[]) => tipoRespostaErro - erroPermissao: ( - mensagem?: string | undefined | null, - detalhes?: string[], - ) => tipoRespostaErro + erroPermissao: (mensagem?: string | undefined | null, detalhes?: string[]) => tipoRespostaErro erroInterno: (op: tipoPrErroInterno) => tipoRespostaErro - naoEncontrado: ( - mensagem?: string | undefined | null, - detalhes?: string[], - ) => tipoRespostaErro - tempoEsgotado: ( - mensagem?: string | undefined | null, - detalhes?: string[], - ) => tipoRespostaErro - erroEspera: ( - mensagem?: string | undefined | null, - detalhes?: string[], - ) => tipoRespostaErro + naoEncontrado: (mensagem?: string | undefined | null, detalhes?: string[]) => tipoRespostaErro + tempoEsgotado: (mensagem?: string | undefined | null, detalhes?: string[]) => tipoRespostaErro + erroEspera: (mensagem?: string | undefined | null, detalhes?: string[]) => tipoRespostaErro } // ─── Helper interno ───────────────────────────────────────────────── @@ -190,8 +178,7 @@ export const IniciarRespostas = ( const resposta: tipoRespostaErro = { cod: codigosResposta.tempoEsgotado, valor: undefined, - mensagem: - mensagem || "Tempo de resposta esgotado ao tentar acessar o recurso.", + mensagem: mensagem || "Tempo de resposta esgotado ao tentar acessar o recurso.", eErro: true, eCerto: false, detalhes, @@ -247,3 +234,76 @@ export const gerarRespostas = IniciarRespostas * Instância default (sem handler de interceptação). */ export const respostaComuns = IniciarRespostas() + +// ─── Schemas Zod ─────────────────────────────────────────────────── + +/** + * Validador para os códigos HTTP de erro aceitos pelo contrato p-respostas. + */ +export const zCodigosRespostaErro = z.union([ + z.literal(codigosResposta.erroConhecido), + z.literal(codigosResposta.erroPermissao), + z.literal(codigosResposta.erroNaoEncontrado), + z.literal(codigosResposta.erroDesconhecido), + z.literal(codigosResposta.tempoEsgotado), +]) + +/** + * Schema Zod para respostas de sucesso do contrato p-respostas. + */ +export const zRespostaSucesso = (zValor?: T) => + z.object({ + cod: z.literal(codigosResposta.sucesso), + eCerto: z.literal(true), + eErro: z.literal(false), + valor: zValor ?? (z.any() as unknown as T), + detalhes: z.array(z.string()).nullish(), + }) + +/** + * Schema Zod para respostas de erro do contrato p-respostas. + */ +export const zRespostaErro = z.object({ + cod: zCodigosRespostaErro, + eCerto: z.literal(false), + eErro: z.literal(true), + mensagem: z.string(), + detalhes: z.array(z.string()).nullish(), +}) + +/** + * Schema Zod completo para o contrato p-respostas (sucesso ou erro). + * + * @param zValor Schema Zod para validar o campo `valor` em caso de sucesso. + * Se omitido, aceita qualquer valor (`z.any()`). + */ +export const zRespostas = (zValor?: T) => + z + .object({ + cod: z.literal(codigosResposta.sucesso), + eCerto: z.literal(true), + eErro: z.literal(false), + valor: zValor ?? (z.any() as unknown as T), + detalhes: z.array(z.string()).nullish(), + }) + .or( + z.object({ + cod: zCodigosRespostaErro, + eCerto: z.literal(false), + eErro: z.literal(true), + mensagem: z.string(), + detalhes: z.array(z.string()).nullish(), + }), + ) + +/** + * Alias singular para `zRespostas`. + */ +export const zResposta = zRespostas + +/** + * Tipo inferido a partir de `zRespostas`. + */ +export type tipoZResposta = z.infer< + ReturnType> +> diff --git a/tests/respostas.test.ts b/tests/respostas.test.ts new file mode 100644 index 0000000..b82ef01 --- /dev/null +++ b/tests/respostas.test.ts @@ -0,0 +1,236 @@ +import { describe, expect, it } from "bun:test" +import z from "zod" +import { + codigosResposta, + respostaComuns, + zCodigosRespostaErro, + zResposta, + zRespostaErro, + zRespostaSucesso, + zRespostas, + type tipoZResposta, +} from "../src/respostas" + +describe("zRespostas - Sucesso", () => { + it("deve validar resposta de sucesso com schema específico (string)", () => { + const schema = zRespostas(z.string()) + const res = respostaComuns.valor("Operação realizada com sucesso") + + const parsed = schema.parse(res) + expect(parsed.cod).toBe(codigosResposta.sucesso) + expect(parsed.eCerto).toBe(true) + expect(parsed.eErro).toBe(false) + if (parsed.eCerto) { + expect(parsed.valor).toBe("Operação realizada com sucesso") + } + }) + + it("deve validar resposta de sucesso com schema de objeto complexo", () => { + const zUsuario = z.object({ + id: z.number(), + nome: z.string(), + ativo: z.boolean(), + }) + const schema = zRespostas(zUsuario) + const res = respostaComuns.valor({ id: 10, nome: "Maria", ativo: true }, [ + "detalhe 1", + ]) + + const parsed = schema.parse(res) + expect(parsed.eCerto).toBe(true) + if (parsed.eCerto) { + expect(parsed.valor.id).toBe(10) + expect(parsed.valor.nome).toBe("Maria") + expect(parsed.valor.ativo).toBe(true) + expect(parsed.detalhes).toEqual(["detalhe 1"]) + } + }) + + it("deve aceitar qualquer valor quando invocado sem parâmetros (default z.any())", () => { + const schema = zRespostas() + const resString = respostaComuns.valor("qualquer texto") + const resNumero = respostaComuns.valor(12345) + const resBool = respostaComuns.valorTrue() + + expect(schema.parse(resString).eCerto).toBe(true) + expect(schema.parse(resNumero).eCerto).toBe(true) + expect(schema.parse(resBool).eCerto).toBe(true) + }) + + it("deve funcionar com zRespostaSucesso isoladamente", () => { + const schema = zRespostaSucesso(z.number()) + const res = respostaComuns.valor(99) + + const parsed = schema.parse(res) + expect(parsed.cod).toBe(200) + expect(parsed.valor).toBe(99) + }) + + it("deve rejeitar sucesso quando o tipo de valor for incompatível", () => { + const schema = zRespostas(z.string()) + const resInvalido = { + cod: codigosResposta.sucesso, + eCerto: true, + eErro: false, + valor: 12345, // número em vez de string + } + + expect(() => schema.parse(resInvalido)).toThrow() + }) + + it("deve aceitar detalhes nullish (null, undefined ou ausente)", () => { + const schema = zRespostas(z.string()) + + const resComNull = { + cod: codigosResposta.sucesso, + eCerto: true, + eErro: false, + valor: "ok", + detalhes: null, + } + const resSemDetalhes = { + cod: codigosResposta.sucesso, + eCerto: true, + eErro: false, + valor: "ok", + } + + expect(schema.parse(resComNull).detalhes).toBeNull() + expect(schema.parse(resSemDetalhes).detalhes).toBeUndefined() + }) +}) + +describe("zRespostas - Erro", () => { + const schema = zRespostas(z.string()) + + it("deve validar erroConhecido (400)", () => { + const res = respostaComuns.erro("Dados inválidos", ["campo X obrigatório"]) + const parsed = schema.parse(res) + + expect(parsed.cod).toBe(codigosResposta.erroConhecido) + expect(parsed.eCerto).toBe(false) + expect(parsed.eErro).toBe(true) + if (parsed.eErro) { + expect(parsed.mensagem).toBe("Dados inválidos") + expect(parsed.detalhes).toEqual(["campo X obrigatório"]) + } + }) + + it("deve validar erroPermissao (401)", () => { + const res = respostaComuns.erroPermissao("Acesso negado") + const parsed = schema.parse(res) + + expect(parsed.cod).toBe(codigosResposta.erroPermissao) + expect(parsed.eErro).toBe(true) + if (parsed.eErro) { + expect(parsed.mensagem).toBe("Acesso negado") + } + }) + + it("deve validar erroNaoEncontrado (404)", () => { + const res = respostaComuns.naoEncontrado("Usuário não encontrado") + const parsed = schema.parse(res) + + expect(parsed.cod).toBe(codigosResposta.erroNaoEncontrado) + expect(parsed.eErro).toBe(true) + if (parsed.eErro) { + expect(parsed.mensagem).toBe("Usuário não encontrado") + } + }) + + it("deve validar erroDesconhecido (500)", () => { + const res = respostaComuns.erroInterno({ + erro: new Error("Falha no banco"), + local: "usuario.service", + mensagem: "Erro inesperado", + }) + const parsed = schema.parse(res) + + expect(parsed.cod).toBe(codigosResposta.erroDesconhecido) + expect(parsed.eErro).toBe(true) + if (parsed.eErro) { + expect(parsed.mensagem).toBe("Erro inesperado") + } + }) + + it("deve validar tempoEsgotado (504)", () => { + const res = respostaComuns.tempoEsgotado("Gateway Timeout") + const parsed = schema.parse(res) + + expect(parsed.cod).toBe(codigosResposta.tempoEsgotado) + expect(parsed.eErro).toBe(true) + if (parsed.eErro) { + expect(parsed.mensagem).toBe("Gateway Timeout") + } + }) + + it("deve funcionar com zRespostaErro isoladamente", () => { + const res = respostaComuns.erro("Falha simples") + const parsed = zRespostaErro.parse(res) + + expect(parsed.cod).toBe(400) + expect(parsed.mensagem).toBe("Falha simples") + }) + + it("deve rejeitar códigos de erro não pertencentes a codigosResposta", () => { + const resInvalido = { + cod: 403, // 403 não é código do enum codigosResposta (p-respostas usa 401) + eCerto: false, + eErro: true, + mensagem: "Proibido", + } + + expect(() => schema.parse(resInvalido)).toThrow() + }) + + it("deve rejeitar erro sem mensagem", () => { + const resSemMsg = { + cod: codigosResposta.erroConhecido, + eCerto: false, + eErro: true, + } + + expect(() => schema.parse(resSemMsg)).toThrow() + }) +}) + +describe("zRespostas - Consistência e Aliases", () => { + it("zResposta deve ser idêntico a zRespostas", () => { + expect(zResposta).toBe(zRespostas) + }) + + it("zCodigosRespostaErro deve aceitar apenas os 5 códigos de erro", () => { + expect(zCodigosRespostaErro.parse(400)).toBe(400) + expect(zCodigosRespostaErro.parse(401)).toBe(401) + expect(zCodigosRespostaErro.parse(404)).toBe(404) + expect(zCodigosRespostaErro.parse(500)).toBe(500) + expect(zCodigosRespostaErro.parse(504)).toBe(504) + + expect(() => zCodigosRespostaErro.parse(200)).toThrow() + expect(() => zCodigosRespostaErro.parse(403)).toThrow() + expect(() => zCodigosRespostaErro.parse(502)).toThrow() + }) + + it("deve permitir narrowing estático em TypeScript", () => { + const schema = zRespostas(z.string()) + const res: tipoZResposta = schema.parse( + respostaComuns.valor("dados"), + ) + + if (res.eCerto) { + const v: string = res.valor + expect(v).toBe("dados") + } else { + const m: string = res.mensagem + expect(m).toBeDefined() + } + + if (res.cod === codigosResposta.sucesso) { + const v: string = res.valor + expect(v).toBe("dados") + } else { + const m: string = res.mensagem + expect(m).toBeDefined() + } + }) +}) diff --git a/tsconfig-back.json b/tsconfig-back.json index c9cde5d..ccf6329 100644 --- a/tsconfig-back.json +++ b/tsconfig-back.json @@ -1,7 +1,8 @@ { "extends": "./tsconfig", "compilerOptions": { - "outDir": "./dist-require", + "outDir": "./dist-back", "module": "commonjs" } } + diff --git a/tsconfig-front.json b/tsconfig-front.json index ae18c06..d12f7d1 100644 --- a/tsconfig-front.json +++ b/tsconfig-front.json @@ -1,7 +1,9 @@ { "extends": "./tsconfig", "compilerOptions": { - "outDir": "./dist-import", - "module": "ES6" + "outDir": "./dist-front", + "module": "ESNext", + "moduleResolution": "bundler" } } + diff --git a/tsconfig.json b/tsconfig.json index b83149f..d86acff 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,7 @@ "rootDir": "./src", /* Define a pasta raiz para os arquivos de origem. */ /* Emissão */ - "declaration": true, /* Gera arquivos .d.ts para os arquivos TypeScript. */ + "declaration": false, /* Não gera arquivos .d.ts. */ /* Interoperabilidade de Módulos */ "esModuleInterop": true, /* Habilita a compatibilidade com módulos CommonJS ao importar. */ @@ -21,7 +21,8 @@ /* Verificação de Tipos */ "strict": true, /* Habilita todas as opções de verificação estrita de tipos. */ - "skipLibCheck": true /* Ignora a verificação de tipos em arquivos de declaração de bibliotecas. */ + "skipLibCheck": true, /* Ignora a verificação de tipos em arquivos de declaração de bibliotecas. */ + "types": ["node", "bun"] }, "include": ["src/**/*"] /* Inclui todos os arquivos TypeScript dentro da pasta src. */ }