carvalhoviniciusluiz / cpf-cnpj-validator

Valida e formata strings de CPF ou CNPJ.
MIT License
206 stars 27 forks source link

Erro ao extender #11

Closed thiagoanselmo closed 4 years ago

thiagoanselmo commented 4 years ago

Boa noite, primeiramente muito show a lib!

Estou usando o @hapi/joi v17.1.0 e está dando erro ao extender como schema, veja que mudou a estrutura na v17

https://github.com/hapijs/joi/blob/master/API.md#extensions

Abaixo o erro que está dando devido a nova estrutura joi.


Error [ValidationError]: {
  "base": {
    "type": "string",
    "$_root": {
      "_types": [
        "alternatives",
        "any",
        "array",
        "boolean",
        "date",
        "function",
        "link",
        "number",
        "object",
        "string",
        "symbol",
        "binary"
      ],
      "alternatives": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "any": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "array": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "boolean": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "date": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "function": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "link": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "number": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "object": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "string": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "symbol": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "binary": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "allow": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "custom": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "disallow": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "equal": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "exist": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "forbidden": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "invalid": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "not": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "only": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "optional": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "options": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "prefs": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "preferences": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "required": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "strip": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "valid": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "when": function (...args) {\n\n            return this.any()[method](...args);\n        },
      "ValidationError": "[class extends Error {\n\n    constructor(message, details, original) {\n\n        super(message);\n        this._original = original;\n        this.details = details;\n    }\n\n    static isError(err) {\n\n        return err instanceof exports.ValidationError;\n    }\n}]",
      "version": "17.1.0",
      "cache": {
        "provision": "[provision(options) {\n\n        return new internals.Cache(options);\n    }]"
      },
      "assert": "[assert(value, schema, ...args /* [message], [options] */) {\n\n        internals.assert(value, schema, true, args);\n    }]",
      "attempt": "[attempt(value, schema, ...args /* [message], [options] */) {\n\n        return internals.assert(value, schema, false, args);\n    }]",
      "build": "[build(desc) {\n\n        Assert(typeof Manifest.build === 'function', 'Manifest functionality disabled');\n        return Manifest.build(this, desc);\n    }]",
      "checkPreferences": "[checkPreferences(prefs) {\n\n        Common.checkPreferences(prefs);\n    }]",
      "compile": "[compile(schema, options) {\n\n        return Compile.compile(this, schema, options);\n    }]",
      "defaults": "[defaults(modifier) {\n\n        Assert(typeof modifier === 'function', 'modifier must be a function');\n\n        const joi = Object.assign({}, this);\n        for (const type of joi._types) {\n            const schema = modifier(joi[type]());\n            Assert(Common.isSchema(schema), 'modifier must return a valid schema object');\n\n            joi[type] = function (...args) {\n\n                return internals.generate(this, schema, args);\n            };\n        }\n\n        return joi;\n    }]",
      "expression": "[expression(...args) {\n\n        return new Template(...args);\n    }]",
      "extend": "[extend(...extensions) {\n\n        Common.verifyFlat(extensions, 'extend');\n\n        Schemas = Schemas || require('./schemas');\n\n        Assert(extensions.length, 'You need to provide at least one extension');\n        this.assert(extensions, Schemas.extensions);\n\n        const joi = Object.assign({}, this);\n        joi._types = new Set(joi._types);\n\n        for (let extension of extensions) {\n            if (typeof extension === 'function') {\n                extension = extension(joi);\n            }\n\n            this.assert(extension, Schemas.extension);\n\n            const expanded = internals.expandExtension(extension, joi);\n            for (const item of expanded) {\n                Assert(joi[item.type] === undefined || joi._types.has(item.type), 'Cannot override name', item.type);\n\n                const base = item.base || this.any();\n                const schema = Extend.type(base, item);\n\n                joi._types.add(item.type);\n                joi[item.type] = function (...args) {\n\n                    return internals.generate(this, schema, args);\n                };\n            }\n        }\n\n        return joi;\n    }]",
      "isError": "[isError(err) {\n\n        return err instanceof exports.ValidationError;\n    }]",
      "isExpression": "[isTemplate(template) {\n\n        return template ? !!template[Common.symbols.template] : false;\n    }]",
      "isRef": function (ref) {\n\n    return ref ? !!ref[Common.symbols.ref] : false;\n},
      "isSchema": function (schema, options = {}) {\n\n    const any = schema && schema[exports.symbols.any];\n    if (!any) {\n        return false;\n    }\n\n    Assert(options.legacy || any.version === exports.version, 'Cannot mix different versions of joi schemas');\n    return true;\n},
      "in": "[in(...args) {\n\n        return Ref.in(...args);\n    }]",
      "override": Symbol(override),
      "ref": "[ref(...args) {\n\n        return Ref.create(...args);\n    }]",
      "types": "[types() {\n\n        const types = {};\n        for (const type of this._types) {\n            types[type] = this[type]();\n        }\n\n        for (const target in internals.aliases) {\n            types[target] = this[target]();\n        }\n\n        return types;\n    }]",
      "alt": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "bool": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "func": function (...args) {\n\n            Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');\n            return internals.generate(this, internals.types[type], args);\n        },
      "x": "[expression(...args) {\n\n        return new Template(...args);\n    }]",
      "trace": function () {\n\n        root._tracer = root._tracer || new internals.Tracer();\n        return root._tracer;\n    },
      "untrace": () => {\n\n        root._tracer = null;\n    }
    },
    "$_temp": {
      "ruleset": null,
      "whens": {}
    },
    "_ids": {
      "_byId": [],
      "_byKey": [],
      "_schemaChain": false
    },
    "_preferences": null,
    "_valids": null,
    "_invalids": null,
    "_rules": [],
    "_singleRules": [],
    "_refs": {
      "refs": []
    },
    "_flags": {},
    "_cache": null,
    "$_terms": {
      "alterations": null,
      "examples": null,
      "externals": null,
      "metas": [],
      "notes": [],
      "shared": null,
      "tags": [],
      "whens": null,
      "replacements": null
    },
    "$_super": {}
  },
  "name": "document",
  "language": {
    "cnpj": "informado é inválido",
    "cpf": "informado é inválido"
  },
  "rules": [
    {
      "name": "cnpj",
      "validate": "[validate(_, value, state, options) {\r\n                if (!cnpj.isValid(value)) {\r\n                    return this.createError('document.cnpj', { v: value }, state, options);\r\n                }\r\n                return value;\r\n            }]"
    },
    {
      "name": "cpf",
      "validate": "[validate(_, value, state, options) {\r\n                if (!cpf.isValid(value)) {\r\n                    return this.createError('document.cpf', { v: value }, state, options);\r\n                }\r\n                return value;\r\n            }]"
    }
  ],
  "type" [1]: -- missing --
}

[1] "type" is required
    at Object.exports.process (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/node_modules/@hapi/joi/lib/errors.js:184:16)
    at Object.internals.entry (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/node_modules/@hapi/joi/lib/validator.js:140:26)
    at Object.exports.entry (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/node_modules/@hapi/joi/lib/validator.js:26:30)
    at internals.Base.validate (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/node_modules/@hapi/joi/lib/base.js:534:26)
    at Object.internals.assert (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/node_modules/@hapi/joi/lib/index.js:225:27)
    at Object.assert (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/node_modules/@hapi/joi/lib/index.js:102:19)
    at Object.extend (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/node_modules/@hapi/joi/lib/index.js:166:18)
    at Object.<anonymous> (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/src/httpServer/schemas/v1/user/_id.js:4:21)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at loader (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.<computed> [as .js] (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Module.require (internal/modules/cjs/loader.js:848:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/src/httpServer/schemas/v1/user/index.js:16:11)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at loader (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.<computed> [as .js] (/home/thiago/Projetos/ENSA_Tecnologia/ensa-caldas/backend/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Module.require (internal/modules/cjs/loader.js:848:19) {
  _original: {
    base: {
      type: 'string',
      '$_root': [Object],
      '$_temp': [Object],
      _ids: [Object],
      _preferences: null,
      _valids: null,
      _invalids: null,
      _rules: [],
      _singleRules: Map {},
      _refs: [Object],
      _flags: {},
      _cache: null,
      '$_terms': [Object],
      '$_super': {}
    },
    name: 'document',
    language: { cnpj: 'informado é inválido', cpf: 'informado é inválido' },
    rules: [ [Object], [Object] ]
  },
  details: [
    {
      message: '"type" is required',
      path: [Array],
      type: 'any.required',
      context: [Object]
    }
  ]
}

Seria muito bem vindo fazer o update! ; )

carvalhoviniciusluiz commented 4 years ago

Adicionei o suporte hapi__joi v17.1.0, verifica se está tudo ok!

thiagoanselmo commented 4 years ago

Vou verificar, obrigado!!!

W1ll14nC4rl0s commented 3 years ago

Bom dia, muito legal esse recurso facilita muito nossa vida! estou com problema ao extender esse recurso ao joi é me apresentado o sequinte erro no console

/home/williancarlos/Documents/Estudos/grupoA/backend/node_modules/@hapi/joi/lib/index.js:243
    throw error;
    ^

Error [ValidationError]: {
  "cpf": {
    "verifierDigit": (digits) => {\r\n    const numbers = digits\r\n        .split('')\r\n        .map(number => {\r\n        return parseInt(number, 10);\r\n    });\r\n    const modulus = numbers.length + 1;\r\n    const multiplied = numbers.map((number, index) => number * (modulus - index));\r\n    const mod = multiplied.reduce((buffer, number) => buffer + number) % 11;\r\n    return (mod < 2 ? 0 : 11 - mod);\r\n},
    "strip": (number, strict) => {\r\n    const regex = strict ? STRICT_STRIP_REGEX : LOOSE_STRIP_REGEX;\r\n    return (number || '').replace(regex, '');\r\n},
    "format": (number) => {\r\n    return strip(number).replace(/^(\\d{3})(\\d{3})(\\d{3})(\\d{2})$/, '$1.$2.$3-$4');\r\n},
    "isValid": (number, strict) => {\r\n    const stripped = strip(number, strict);\r\n    if (!stripped) {\r\n        return false;\r\n    }\r\n    if (stripped.length !== 11) {\r\n        return false;\r\n    }\r\n    if (BLACKLIST.includes(stripped)) {\r\n        return false;\r\n    }\r\n    let numbers = stripped.substr(0, 9);\r\n    numbers += verifierDigit(numbers);\r\n    numbers += verifierDigit(numbers);\r\n    return numbers.substr(-2) === stripped.substr(-2);\r\n},
    "generate": (formatted) => {\r\n    let numbers = '';\r\n    for (let i = 0; i < 9; i += 1) {\r\n        numbers += Math.floor(Math.random() * 9);\r\n    }\r\n    numbers += verifierDigit(numbers);\r\n    numbers += verifierDigit(numbers);\r\n    return (formatted ? format(numbers) : numbers);\r\n}
  },
  "cnpj": {
    "verifierDigit": (digits) => {\r\n    let index = 2;\r\n    const reverse = digits.split('').reduce((buffer, number) => {\r\n        return [parseInt(number, 10)].concat(buffer);\r\n    }, []);\r\n    const sum = reverse.reduce((buffer, number) => {\r\n        buffer += number * index;\r\n        index = (index === 9 ? 2 : index + 1);\r\n        return buffer;\r\n    }, 0);\r\n    const mod = sum % 11;\r\n    return (mod < 2 ? 0 : 11 - mod);\r\n},
    "strip": (number, strict) => {\r\n    const regex = strict ? STRICT_STRIP_REGEX$1 : LOOSE_STRIP_REGEX$1;\r\n    return (number || '').replace(regex, '');\r\n},
    "format": (number) => {\r\n    return strip$1(number).replace(/^(\\d{2})(\\d{3})(\\d{3})(\\d{4})(\\d{2})$/, '$1.$2.$3/$4-$5');\r\n},
    "isValid": (number, strict) => {\r\n    const stripped = strip$1(number, strict);\r\n    if (!stripped) {\r\n        return false;\r\n    }\r\n    if (stripped.length !== 14) {\r\n        return false;\r\n    }\r\n    if (BLACKLIST$1.includes(stripped)) {\r\n        return false;\r\n    }\r\n    let numbers = stripped.substr(0, 12);\r\n    numbers += verifierDigit$1(numbers);\r\n    numbers += verifierDigit$1(numbers);\r\n    return numbers.substr(-2) === stripped.substr(-2);\r\n},
    "generate": (formatted) => {\r\n    let numbers = '';\r\n    for (let i = 0; i < 12; i += 1) {\r\n        numbers += Math.floor(Math.random() * 9);\r\n    }\r\n    numbers += verifierDigit$1(numbers);\r\n    numbers += verifierDigit$1(numbers);\r\n    return (formatted ? format$1(numbers) : numbers);\r\n}
  },
  "validator": "[joi => ({\r\n    type: 'document',\r\n    base: joi.string(),\r\n    messages: {\r\n        'document.cpf': 'CPF inválido',\r\n        'document.cnpj': 'CNPJ inválido'\r\n    },\r\n    rules: {\r\n        cpf: {\r\n            validate(value, helpers, args, options) {\r\n                if (!cpf.isValid(value)) {\r\n                    return helpers.error('document.cpf');\r\n                }\r\n                return value;\r\n            }\r\n        },\r\n        cnpj: {\r\n            validate(value, helpers, args, options) {\r\n                if (!cnpj.isValid(value)) {\r\n                    return helpers.error('document.cnpj');\r\n                }\r\n                return value;\r\n            }\r\n        }\r\n    }\r\n})]",
  "default": "[joi => ({\r\n    type: 'document',\r\n    base: joi.string(),\r\n    messages: {\r\n        'document.cpf': 'CPF inválido',\r\n        'document.cnpj': 'CNPJ inválido'\r\n    },\r\n    rules: {\r\n        cpf: {\r\n            validate(value, helpers, args, options) {\r\n                if (!cpf.isValid(value)) {\r\n                    return helpers.error('document.cpf');\r\n                }\r\n                return value;\r\n            }\r\n        },\r\n        cnpj: {\r\n            validate(value, helpers, args, options) {\r\n                if (!cnpj.isValid(value)) {\r\n                    return helpers.error('document.cnpj');\r\n                }\r\n                return value;\r\n            }\r\n        }\r\n    }\r\n})]",
  "type" [1]: -- missing --
}

[1] "type" is required
    at Object.exports.process (/home/williancarlos/Documents/Estudos/grupoA/backend/node_modules/@hapi/joi/lib/errors.js:184:16)
    at Object.internals.entry (/home/williancarlos/Documents/Estudos/grupoA/backend/node_modules/@hapi/joi/lib/validator.js:140:26)
    at Object.exports.entry (/home/williancarlos/Documents/Estudos/grupoA/backend/node_modules/@hapi/joi/lib/validator.js:26:30)
    at internals.Base.validate (/home/williancarlos/Documents/Estudos/grupoA/backend/node_modules/@hapi/joi/lib/base.js:534:26)
    at Object.internals.assert (/home/williancarlos/Documents/Estudos/grupoA/backend/node_modules/@hapi/joi/lib/index.js:225:27)
    at Object.assert (/home/williancarlos/Documents/Estudos/grupoA/backend/node_modules/@hapi/joi/lib/index.js:102:19)
    at Object.extend (/home/williancarlos/Documents/Estudos/grupoA/backend/node_modules/@hapi/joi/lib/index.js:166:18)
    at Object.<anonymous> (/home/williancarlos/Documents/Estudos/grupoA/backend/src/Routes/PrivateRoutes.js:2:34)
    at Module._compile (internal/modules/cjs/loader.js:1137:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10) {
  _original: {
    cpf: {
      verifierDigit: [Function: verifierDigit],
      strip: [Function: strip],
      format: [Function: format],
      isValid: [Function: isValid],
      generate: [Function: generate]
    },
    cnpj: {
      verifierDigit: [Function: verifierDigit$1],
      strip: [Function: strip$1],
      format: [Function: format$1],
      isValid: [Function: isValid$1],
      generate: [Function: generate$1]
    },
    validator: [Function: validator],
    default: [Function: validator]
  },
  details: [
    {
      message: '"type" is required',
      path: [ 'type' ],
      type: 'any.required',
      context: { label: 'type', key: 'type' }
    }
  ]
}

estou usando o node na versão 12.18.4, joi é @hapi/joi: 17.1.1 e @hapi/hapi: 19.2.0