hapijs / joi

The most powerful data validation library for JS
Other
20.89k stars 1.51k forks source link

Joi does not work with application with Custom Prototypes #3031

Open niightly opened 6 months ago

niightly commented 6 months ago

Runtime

node

Runtime version

v20.12.1

Module version

17.12.3

Last module version without issue

14.3.1

Used with

standalone

Any other relevant information

No response

What are you trying to achieve or the steps to reproduce?

I took the liberty to create a proof of concept => https://stackblitz.com/edit/nodejs-server-1krq6c?file=server.js. I was upgrading an application (too old) and because of this that are several prototypes implemented that are affecting the new versions of joi.

What was the result you got?

The error below:

<ROOT_FOLDER>/joi-test/node_modules/joi/lib/base.js:800
            target.$_terms[key] = this.$_terms[key] ? this.$_terms[key].slice() : null;
                                                                        ^

TypeError: this.$_terms[key].slice is not a function
    at internals.Base._assign (<ROOT_FOLDER>/joi-test/node_modules/joi/lib/base.js:800:73)
    at exports.type (<ROOT_FOLDER>/joi-test/node_modules/joi/lib/extend.js:17:25)
    at internals.Base.extend (<ROOT_FOLDER>/joi-test/node_modules/joi/lib/base.js:451:23)
    at Object.<anonymous> (<ROOT_FOLDER>/joi-test/node_modules/joi/lib/types/any.js:13:23)
    at Module._compile (node:internal/modules/cjs/loader:1369:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
    at Module.load (node:internal/modules/cjs/loader:1206:32)
    at Module._load (node:internal/modules/cjs/loader:1022:12)
    at Module.require (node:internal/modules/cjs/loader:1231:19)
    at require (node:internal/modules/helpers:179:18)

What result did you expect?

the same behavior as the older versions, I was able to use joi normally without error

Marsup commented 6 months ago

Hi, I'm not seeing joi being used in your repro, did you forget to push something?

Marsup commented 6 months ago

I tried on my side with your prototype, I think you're running into risks with many libraries with this. If you have control over this, you should define your extensions this way:

Object.defineProperty(Object.prototype, "key_from", {
  enumerable: false,
  value: function (value) {
    const keys = Object.keys(this);

    if (keys.length === 0) {
      return null;
    }
    return keys.find((key) => this[key] == value);
  },
})

I'm honestly not sure it's worth fixing in joi.