How to use joi

Comprehensive joi code examples:

How to use joi.types:

61
62
63
64
65
66
67
68
69
70
71
72
73
}


const NODE_ENV   = (process.env.NODE_ENV) ? process.env.NODE_ENV : 'production'
const apiPattern = /^[^\/].*[^\/]$/;


const { string, number, array, boolean } = Joi.types();


const conectionSchema = Joi.object({
    name: string.required(),
    uri: string.uri().required()

How to use joi.x:

197
198
199
200
201
202
203
204
205
206
// const { error, value } = schema.validate(data);
// !error ? console.log("success!", Joi.isError(error)): console.log(Joi.isError(error))

//check giving argument is expression or not
//Joi.x is genrate a dynamic expression 
const expression = Joi.x('{a}');
// console.log('expression or not', Joi.isExpression(expression));


//isref

How to use joi.isExpression:

198
199
200
201
202
203
204
205
206
207
// !error ? console.log("success!", Joi.isError(error)): console.log(Joi.isError(error))

//check giving argument is expression or not
//Joi.x is genrate a dynamic expression 
const expression = Joi.x('{a}');
// console.log('expression or not', Joi.isExpression(expression));


//isref
const ref = Joi.ref('a');

How to use joi.valid:

15
16
17
18
19
20
21
22
23
24
    }));

const APPLICATION_NAME_OR_ALL =
    Joi.alternatives().try(
        applicationSchema.extract('name'),
        Joi.valid('all')
    ).required();

const APIDefinition = {
    add: [

How to use joi.filter:

12
13
14
15
16
17
18
19
20
21
* The value of this property is an instance of Filters.
*
* All options can be overwritten by each route.
* Options:
*  enabled - enable the queryFilter
*  ignoreKeys - ignore the key. Note that only keys of type Joi.filter() in the validate.query object are used.
*  rename - A Joi-schema with .rename() functions that are used to get renames of the keys.
*           Can also be a plain Object with keys being the query-name, and the value being the database-name.
*      This is used to rename API-facing filter-names to database-column names.
*/

How to use joi.invalid:

461
462
463
464
465
466
467
468
469
470
  .optional()
  .meta({ tags: ['Restricted'] })
  .when('status', {
    is: CASE_STATUS_TYPES.calendared,
    otherwise: joi.optional(),
    then: joi.invalid(true),
  })
  .description('Temporarily blocked from trial.'),
blockedDate: JoiValidationConstants.ISO_DATE.when('blocked', {
  is: true,

How to use joi.objectId:

175
176
177
178
179
180
181
182
183
184
auth: null,
description: 'Update a user\'s password.',
tags: ['api', 'User', 'Password'],
validate: {
  params: {
    _id: Joi.objectId().required()
  },
  payload: {
    password: Joi.string().required()
      .description('The user\'s new password')

How to use joi.function:

21
22
23
24
25
26
27
28
29
30
dialect: Joi.string().default('postgres'),
dialectOptions: Joi.object({
  ssl: Joi.boolean().default(false)
}),
hooks: Joi.object({
  beforeConnect: Joi.function()
}),
host: Joi.string(),
password: Joi.string(),
port: Joi.number().default(5432),

How to use joi.custom:

121
122
123
124
125
126
127
128
129
130
131
};


function condition(fun, then, otherwise) {
  return Joi.alternatives().conditional(
    Joi.ref('.'), {
      is: Joi.custom((value, helper) => (fun(value) ? value : helper.message({}))),
      then,
      otherwise
    }
  );

How to use joi.reach:

69
70
71
72
73
74
75
76
77
78
  })
} else {
  type = new GraphQLObjectType({
    name: typeName,
    description: desc.description,
    fields: () => descsToFields(mapValues(desc.children, (child, k) => Joi.reach(schema, k)))
  })
}
cachedTypes[typeName] = type
return type

How to use joi.isSchema:

236
237
238
239
240
241
242
243
244
245
246
 *
 * @param  {Object} joiObj
 * @return {Boolean}
 */
utilities.isJoi = function(joiObj) {
  return joiObj && Joi.isSchema(joiObj)
};


/**
 * does JOI object have children

How to use joi._flags:

545
546
547
548
549
550
551
552
553
554
  }
  if (joi._valids._set && joi._valids._set.length) {
    item.enum = joi._valids._set;
  }
  if (joi._flags.hasOwnProperty('default')) {
    item.default = joi._flags.default;
  }
  return param;
}

How to use joi.only:

43
44
45
46
47
48
49
50
51
52
configTypes.password = configTypes.string;
configTypes.int = configTypes.integer;
configTypes.bool = configTypes.boolean;

const manifestSchema = {
  $schema: joi.only(CANONICAL_SCHEMA).default(CANONICAL_SCHEMA),
  // FoxxStore metadata
  name: joi.string().regex(/^[-_a-z][-_a-z0-9]*$/i).optional(),
  version: joi.string().optional(),
  keywords: joi.array().optional(),

How to use joi.isRef:

134
135
136
137
138
139
140
141
142
143
	}
}

const min = find(schema._rules, { name: 'min' });
if (min) {
	swagger.minimum = joi.isRef(min.args.limit) ? getRefValue(min.args.limit, schema, 0) : min.args.limit;
}

const max = find(schema._rules, { name: 'max' });
if (max) {

How to use joi.when:

158
159
160
161
162
163
164
165
166
167
    PARTY_TYPES.partnershipAsTaxMattersPartner,
    PARTY_TYPES.partnershipBBA,
    PARTY_TYPES.partnershipOtherThanTaxMatters,
  ),
otherwise: joi.optional().allow(null),
then: joi.when('orderForCds', {
  is: joi.not(true),
  otherwise: joi.optional().allow(null),
  then: joi.required(),
}),

How to use joi.defaults:

How to use joi.allow:

583
584
585
586
587
588
589
590
591
592
  .allow(null)
  .description('Litigation costs for the case.'),
mailingDate: JoiValidationConstants.STRING.max(25)
  .when('isPaper', {
    is: true,
    otherwise: joi.allow(null).optional(),
    then: joi.required(),
  })
  .description('Date that petition was mailed to the court.'),
noticeOfAttachments: joi

How to use joi._valids:

542
543
544
545
546
547
548
549
550
551
item.type = type[0];
if (type.length > 1) {
  item.format = type[1];
}
if (joi._valids._set && joi._valids._set.length) {
  item.enum = joi._valids._set;
}
if (joi._flags.hasOwnProperty('default')) {
  item.default = joi._flags.default;
}

How to use joi.extend:

How to use joi.compile:

74
75
76
77
78
79
80
81
82
83
  // use casted values
  ctx.set(result.value);
}

if (this.spec.body) {
  result = Joi.compile(this.spec.body).validate(ctx.body);
  if (result.error) return result.error;
  // use casted values
  ctx.body = result.value;
}

How to use joi.ValidationError:

How to use joi.fileSize:

80
81
82
83
84
85
86
87
88
89
  currentUser: Joi.any(),
  challengeId: Joi.id(),
  attachments: Joi.array().items(Joi.object().keys({
    name: Joi.string().required(),
    url: Joi.string().uri().required(),
    fileSize: Joi.fileSize(),
    description: Joi.string()
  })).required().min(1)
}

How to use joi.assert:

1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
      name: 'test',
      type: 'test',
      pushEndpointExpired: false,
    },
  ];
  Joi.assert(res, route.options.response.schema);
});

it('should allow returning approximateLastAccessTime', () => {
  const route = getRoute(makeRoutes({}), '/account/devices');

How to use joi.attempt:

6
7
8
9
10
11
12
13
14
15
const ClientCredentialsGrantType = require('./lib/client-credentials-grant-type');
const { AuthorizationCodeSchema, ClientCredentialsSchema, ResourceOwnerPasswordSchema } = require('./lib/config');

class AuthorizationCode extends AuthorizationCodeGrantType {
  constructor(options) {
    const config = Joi.attempt(options, AuthorizationCodeSchema, 'Invalid options provided to simple-oauth2');
    const client = new Client(config);

    super(config, client);
  }

How to use joi.perPage:

25
26
27
28
29
30
31
32
33
34
35
}


searchPhases.schema = {
  criteria: Joi.object().keys({
    page: Joi.page(),
    perPage: Joi.perPage().default(100),
    name: Joi.string()
  })
}

How to use joi.page:

24
25
26
27
28
29
30
31
32
33
34
  return { total, page, perPage, result }
}


searchPhases.schema = {
  criteria: Joi.object().keys({
    page: Joi.page(),
    perPage: Joi.perPage().default(100),
    name: Joi.string()
  })
}

How to use joi.binary:

7
8
9
10
11
12
13
14
15
16
{ type: 'byte', base: Joi.string().base64() },
{ type: 'date-time', base: Joi.date().iso() },
{
    type: 'file',
    base: Joi.object({
        value: Joi.binary().required(true),
        consumes: Joi.array().items(
            Joi.string().regex(/multipart\/form-data|application\/x-www-form-urlencoded/)
        ).required(true),
        in: Joi.string().regex(/formData/).required(true)

How to use joi.ref:

63
64
65
66
67
68
69
70
71
72
user_id,
// 使用 password 这个规则,验证 req.body.oldPwd 的值
old_password: password,
// 使用 joi.not(joi.ref('oldPwd')).concat(password) 规则,验证 req.body.newPwd 的值
// 解读:
// 1. joi.ref('oldPwd') 表示 newPwd 的值必须和 oldPwd 的值保持一致
// 2. joi.not(joi.ref('oldPwd')) 表示 newPwd 的值不能等于 oldPwd 的值
// 3. .concat() 用于合并 joi.not(joi.ref('oldPwd')) 和 password 这两条验证规则
password: joi.not(joi.ref('old_password')).concat(password),
repassword: joi.ref('password')

How to use joi.isError:

1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
    .valid(FILE_STATUS_PHASE1.TO_UPLOAD, FILE_STATUS_PHASE1.WAITING_VERIFICATION, FILE_STATUS_PHASE1.WAITING_CORRECTION, FILE_STATUS_PHASE1.VALIDATED)
    .required(),
  [`${document}FilesComment`]: Joi.alternatives().conditional(`${document}FilesStatus`, {
    is: FILE_STATUS_PHASE1.WAITING_CORRECTION,
    then: Joi.string().trim().required(),
    otherwise: Joi.isError(new Error()),
  }),
}).validate(req.body);
if (bodyError) return res.status(400).send({ ok: false, code: bodyError });
if (!tempValue[`${document}FilesComment`]) tempValue[`${document}FilesComment`] = undefined;