Repository navigation
Feat/joi integration #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| # Joi | ||
|
|
||
| ## Integração com br-docs | ||
|
|
||
| A extensão de Joi do **br-docs** adiciona um novo tipo chamado `document` com regras específicas para documentos brasileiros. | ||
|
|
||
| ### Instalação | ||
|
|
||
| ```bash | ||
| npm i br-docs joi | ||
| ``` | ||
|
|
||
| ### Uso básico | ||
|
|
||
| ```typescript | ||
| import Joi from "joi"; | ||
| import documentExtension from "br-docs/joi"; | ||
|
|
||
| const JoiExtended = Joi.extend(documentExtension); | ||
|
|
||
| const schema = JoiExtended.object({ | ||
| cpf: JoiExtended.document().cpf().required(), | ||
| cnpj: JoiExtended.document().cnpj().required(), | ||
| nis: JoiExtended.document().nis().required(), | ||
| cnh: JoiExtended.document().cnh().required(), | ||
| cep: JoiExtended.document().cep().required(), | ||
| telefone: JoiExtended.document().phone().required(), | ||
| pix: JoiExtended.document().pix().required(), | ||
| boleto: JoiExtended.document().boleto().required(), | ||
| celular: JoiExtended.document().celular().required(), | ||
| }); | ||
|
|
||
| const result = schema.validate({ | ||
| cpf: "123.456.789-09", | ||
| cnpj: "11.222.333/0001-81", | ||
| nis: "123.45678.90-1", | ||
| cnh: "02650306461", | ||
| cep: "01001-000", | ||
| telefone: "(11) 3456-7890", | ||
| pix: "email@dominio.com", | ||
| boleto: "34191.79001 01043.510047 91020.150008 6 84570000002000", | ||
| celular: "(11) 98765-4321", | ||
| }); | ||
|
|
||
| if (result.error) { | ||
| console.error(result.error.details); | ||
| } | ||
| ``` | ||
|
|
||
| ## Regras disponíveis | ||
|
|
||
| As regras abaixo validam o valor e retornam erro com mensagens específicas: | ||
|
|
||
| - `document().cpf()` — CPF inválido | ||
| - `document().cnpj()` — CNPJ inválido | ||
| - `document().nis()` — NIS inválido | ||
| - `document().cnh()` — CNH inválida | ||
| - `document().cep()` — CEP inválido | ||
| - `document().phone()` — Telefone inválido | ||
| - `document().pix()` — Chave PIX inválida | ||
| - `document().boleto()` — Boleto inválido | ||
| - `document().celular()` — Celular inválido | ||
|
|
||
| ## Mensagens de erro personalizadas | ||
|
|
||
| Você pode customizar mensagens normalmente pelo Joi: | ||
|
|
||
| ```typescript | ||
| const schema = JoiExtended.object({ | ||
| cpf: JoiExtended.document().cpf().messages({ | ||
| "document.cpf": "CPF informado não é válido", | ||
| }), | ||
| }); | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # Extensões | ||
|
|
||
| Nesta seção você encontra integrações do **br-docs** com bibliotecas de validação e outros ecossistemas. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| import BaseJoi, { Schema } from "joi"; | ||
| import validator from "../joi"; | ||
| import { describe, expect, it } from "vitest"; | ||
|
|
||
| const Joi = BaseJoi.extend(validator); | ||
|
|
||
| function expectOk(schema: Schema, value: string) { | ||
| const { error } = schema.validate(value); | ||
| expect(error).toBeUndefined(); | ||
| } | ||
|
|
||
| function expectErr(schema: Schema, value: string, code: string) { | ||
| const { error } = schema.validate(value); | ||
| expect(error).toBeTruthy(); | ||
| expect(error!.details[0].type).toBe(code); | ||
| } | ||
|
|
||
| describe("br-docs Joi extension", () => { | ||
| it("cpf", () => { | ||
| expectOk(Joi.document().cpf(), "529.982.247-25"); | ||
| expectErr(Joi.document().cpf(), "123", "document.cpf"); | ||
| }); | ||
|
|
||
| it("cnpj", () => { | ||
| expectOk(Joi.document().cnpj(), "04.252.011/0001-10"); | ||
| expectErr(Joi.document().cnpj(), "123", "document.cnpj"); | ||
| }); | ||
|
|
||
| it("nis", () => { | ||
| expectOk(Joi.document().nis(), "16029214650"); | ||
| expectErr(Joi.document().nis(), "16029214651", "document.nis"); | ||
| }); | ||
|
|
||
| it("cnh", () => { | ||
| expectOk(Joi.document().cnh(), "60930978987"); | ||
| expectErr(Joi.document().cnh(), "11111111111", "document.cnh"); | ||
| }); | ||
|
|
||
| it("cep / phone / celular / uuid / pix", () => { | ||
| expectOk(Joi.document().cep(), "01001-000"); | ||
| expectOk(Joi.document().phone(), "1133334444"); | ||
| expectOk(Joi.document().celular(), "11999998888"); | ||
| expectOk(Joi.document().uuid(), "550e8400-e29b-41d4-a716-446655440000"); | ||
| expectOk(Joi.document().pix(), "a@b.com"); | ||
| }); | ||
|
Comment on lines
+39
to
+45
|
||
|
|
||
| it("boleto", () => { | ||
| expectOk( | ||
| Joi.document().boleto(), | ||
| "00190.00009 02372.190005 00017.356171 9 63690000007179", | ||
| ); | ||
| expectErr(Joi.document().boleto(), "123", "document.boleto"); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,3 +1,6 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Cnpj } from "./cnpj"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Cpf } from "./cpf"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Interface que define o método de validação de um documento. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Implementa o método de validação que verifica se o documento é válido. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -45,3 +48,35 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export { Telefone } from "./telefone"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export { Cnh } from "./cnh"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export { Boleto } from "./boleto"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export { Nis } from "./nis"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const validator = (joi: any) => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: "document", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| base: joi.string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| messages: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "document.cpf": "CPF inválido", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "document.cnpj": "CNPJ inválido", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rules: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cpf: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validate(value: any, helpers: any, args: any, options: any) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 62 in src/index.ts
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!Cpf.isValid(value)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return helpers.error("document.cpf"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return value; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cnpj: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validate(value: any, helpers: any, args: any, options: any) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 71 in src/index.ts
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!Cnpj.isValid(value)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return helpers.error("document.cnpj"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return value; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export default validator; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+52
to
+82
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const validator = (joi: any) => ({ | |
| type: "document", | |
| base: joi.string(), | |
| messages: { | |
| "document.cpf": "CPF inválido", | |
| "document.cnpj": "CNPJ inválido", | |
| }, | |
| rules: { | |
| cpf: { | |
| validate(value: any, helpers: any, args: any, options: any) { | |
| if (!Cpf.isValid(value)) { | |
| return helpers.error("document.cpf"); | |
| } | |
| return value; | |
| }, | |
| }, | |
| cnpj: { | |
| validate(value: any, helpers: any, args: any, options: any) { | |
| if (!Cnpj.isValid(value)) { | |
| return helpers.error("document.cnpj"); | |
| } | |
| return value; | |
| }, | |
| }, | |
| }, | |
| }); | |
| export default validator; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test expects Joi.document().uuid() to work, but the uuid validation rule is not implemented in the validator extension (src/joi.ts). This test will fail at runtime. The uuid rule needs to be added to src/joi.ts before this test can pass.