Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is There A Way To Merge Joi Schemas?

Is there any way to merge two joi schemas into a single schema?

Schema 1

{
  alpha: Joi.number().required(),
  beta: Joi.string().required(),
  chalie: Joi.object({
    xray: Joi.number().required(),
  }).required()
}

Schema 1

{
  delta: Joi.string().required(),
  echo: Joi.number().required(),
  charlie: Joi.object({
    zulu: Joi.string().required(),
  }).required()
}

Merged Schema:

{
  alpha: Joi.number().required(),
  beta: Joi.string().required(),
  chalie: Joi.object({
    xray: Joi.number().required(),
    zulu: Joi.string().required(),
  }).required()
  delta: Joi.string().required(),
  echo: Joi.number().required(),
}

Without nested objects it's easily done with Object.assign, but even a deep object merge won't work with the nested objects because the nested object is a function call.

like image 646
Undistraction Avatar asked Mar 20 '17 22:03

Undistraction


People also ask

What is Joi schema?

Hapi Joi is an object schema description language and validator for JavaScript objects. With Hapi Joi, we create blueprints or schemas for JavaScript objects (an object that stores information) to ensure validation of key information.

What is the use of joi in Nodejs?

Joi module is a popular module for data validation. This module validates the data based on schemas. There are various functions like optional(), required(), min(), max(), etc which make it easy to use and a user-friendly module for validating the data.


3 Answers

I was wondering the same thing, as I wanted to merge two different schemas, and found this: https://github.com/hapijs/joi/blob/v9.0.4/API.md#anyconcatschema

const a = Joi.string().valid('a');
const b = Joi.string().valid('b');
const ab = a.concat(b);

Hope that helps you

like image 156
szanata Avatar answered Oct 16 '22 07:10

szanata


Did you try Joi.append?

https://github.com/hapijs/joi/blob/v13.5.2/API.md#objectkeysschema

// Validate key a
const base = Joi.object().keys({
    a: Joi.number()
});

// Validate keys a, b.
const extended = base.append({
    b: Joi.string()
});

UPDATED (2020-05-03):

An easy way to accomplish that would be like this:

var base = Joi.object({ firstname: Joi.string() });
var fullName = base.keys({ lastName: Joi.number() });
like image 34
orlaqp Avatar answered Oct 16 '22 09:10

orlaqp


Using plain javascript objects was not an option for me. I tried using the .keys method to extend but it overwrites existing keys (for charlie in this case).

The solution I settled on was using .reach: Example:

const Joi = require('joi');
const originalSchema = Joi.object({
  a: { 
    deep: {
      b: Joi.string()
    }    
  },
  c: Joi.string()
});
const extendedSchema = Joi.object({
  a: { 
    deep: Joi
      .reach(originalSchema, 'a.deep')
      .keys({ anotherB: Joi.string() })
  },
  c: Joi.reach(originalSchema, 'c')
});

// No errors
extendedSchema.validate({ a: { deep: { b: 'hi', anotherB: 'hi' } }, c: 'wow' })
like image 6
mrBorna Avatar answered Oct 16 '22 07:10

mrBorna