Skip to content

Extensions remove language of previous extension with the same base #1658

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

Closed
tomyam1 opened this issue Nov 20, 2018 · 3 comments
Closed

Extensions remove language of previous extension with the same base #1658

tomyam1 opened this issue Nov 20, 2018 · 3 comments
Assignees
Labels
bug Bug or defect
Milestone

Comments

@tomyam1
Copy link

tomyam1 commented Nov 20, 2018

Context

  • node version: v8.10.0
  • joi version: 14.1.0
  • environment (node, browser): node
  • used with (hapi, standalone, ...): standalone
  • any other relevant information:

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

Here is an example of two extensions for the number base type. The first extension loses its language definition.

After tracing the code, this seems to happen because language definitions are merged using Object.assign. Maybe something like lodash.merge would be more appropriate?

const BaseJoi = require('joi');
const Assert = require('assert');

const ExtendedJoi = BaseJoi.extend(
    function (joi) {
        return {
            base: joi.number(),
            name: 'number',
            language: {
                greaterThan10: `Must be > 10`
            },
            rules: [
                {
                    name: `greaterThan10`,
                    validate(params, value, state, options) {
                        return value > 10
                            ? value
                            : this.createError(`number.greaterThan10`, {v: value}, state, options)
                    }
                }
            ]
        }
    },
    function (joi) {
        return {
            base: joi.number(),
            name: 'number',
            language: {
                greaterThan20: `Must be > 20`
            },
            rules: [
                {
                    name: `greaterThan20`,
                    validate(params, value, state, options) {
                        return value > 20
                            ? value
                            : this.createError(`number.greaterThan20`, {v: value}, state, options)
                    }
                }
            ]
        }
    }
);

const schema = ExtendedJoi.number()
    .greaterThan10()
    .greaterThan20();

// Passes both rules
Assert.equal(schema.validate(30).value, 30);

// Failed second rule - message is OK
Assert.equal(schema.validate(15).error.message, '"value" Must be > 20');

// Failed first rule - can't use it's language
Assert.equal(schema.validate(5).error.message, 'Error code "number.greaterThan10" is not defined, your custom type is missing the correct language definition');

Which result you had ?

The first extension lost its language definition.

What did you expect ?

Both extension would work as expected

@Marsup Marsup added the bug Bug or defect label Nov 23, 2018
@Marsup Marsup self-assigned this Nov 24, 2018
@Marsup Marsup closed this as completed in e63e3fb Nov 24, 2018
@Marsup Marsup added this to the 14.1.1 milestone Nov 24, 2018
@Marsup
Copy link
Collaborator

Marsup commented Nov 24, 2018

Thanks for the report! The fix is published.

@tomyam1
Copy link
Author

tomyam1 commented Nov 24, 2018

Thanks a lot for the super quick fix!

@lock
Copy link

lock bot commented Jan 9, 2020

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Bug or defect
Projects
None yet
Development

No branches or pull requests

2 participants