Malik Bagwala
Malik Bagwala

Reputation: 3019

How to extend a Joi schema?

I have a joi schema called user

const user = {
  firstName: Joi.string()
    .min(2)
    .max(50)
    .required()
    .label('First Name'),
  lastName: Joi.string()
    .min(3)
    .max(50)
    .required()
    .label('Last Name'),
  email: Joi.string()
    .allow('')
    .email({ minDomainAtoms: 2 })
    .max(100)
    .label('Email Address'),
}

I had another one called owner

const ownerSchema = {
  firstName: Joi.string()
    .min(2)
    .max(50)
    .required()
    .label('First Name'),
  lastName: Joi.string()
    .min(3)
    .max(50)
    .required()
    .label('Last Name'),
  email: Joi.string()
    .allow('')
    .email({ minDomainAtoms: 2 })
    .max(100)
    .label('Email Address'),
  number: Joi.string()
    .regex(/[0-9]/)
    .length(10)
    .required()
    .label('Phone Number'),
  dateOfBirth: Joi.date(),

  kycDetails: Joi.array()
    .items(schemaKyc)
    .required(),
  bankDetails: Joi.array()
    .items(schemaBank)
    .required(),
  licenceDetails: Joi.array()
    .items(schemaLicence)
    .required(),
  insuranceDetails: Joi.array()
    .items(schemaInsurance)
    .required()
};

As you can see the both have three fields in common I want to be able to use the user schema in owner and whenever I make changes to the user I want it to reflect in the owner as well.

Upvotes: 25

Views: 21119

Answers (4)

Chihab JRAOUI
Chihab JRAOUI

Reputation: 216

I believe you can use Joi.concat() method:

const userSchema = Joi.object({ ... });
const ownerSchema = Joi.object({ ... });

userSchema.concat(ownerSchema);

And what will happen is if you have duplicate keys in both object, ownerSchema key will override userSchema keys.

Upvotes: 0

gidgud
gidgud

Reputation: 301

I use append as written in the docs

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

Upvotes: 12

lealceldeiro
lealceldeiro

Reputation: 14968

You can use object.keys([schema]), which

Sets or extends the allowed object keys where:

  • schema - optional object where each key is assigned a joi type object. If schema is {} no keys allowed. If schema is null or undefined, any key allowed. If schema is an object with keys, the keys are added to any previously defined keys (but narrows the selection if all keys previously allowed). Defaults to 'undefined' which allows any child key.

Example:

const base = Joi.object().keys({
    a: Joi.number(),
    b: Joi.string()
});
// Validate keys a, b and c.
const extended = base.keys({
    c: Joi.boolean()
});

Upvotes: 49

frogatto
frogatto

Reputation: 29285

Simply you can spread the user inside ownerSchema:

const ownerSchema = {
    ...user,
    /* owner specific fields goes here */
};

Upvotes: 8

Related Questions