Итак, это будет суперкраткий учебник для людей, которые пытаются писать расширения JOI. Недавно я написал расширение для проверки идентификаторов объектов mongodb, и здесь я опишу шаги для этого; Давайте начнем

Джой использует то, что называется extension объектами, для «расширения» своей функциональности.
Эти объекты обычно выглядят примерно так:

{
   base: any_joi_base_function_you_want_to_use,
   name: 'the_name_of_your_validation',
   language: { // This is where you'd store error messages
      'key_name': 'Error messages',
   },
   pre(value, state, options) {
      you can parse the object value here or 
      even add a base check and throw error
   },
   rules: [{
      name: 'name_of_sub_validation',
      validate(params, value, state, options) {
         if (some_condition_doesn't_match) {
            return this.createError(
              'path_to_err_in_language',
              { v: value }, 
              state, 
              options
            );
         }
         return value;
      },
   }, ...more_rules],
}

теперь мы можем либо передать этот объект в качестве аргумента методу Joi.extend, либо создать функцию, которая возвращает такой объект 👆
Джой говорит, что вы также можете передать массив, состоящий из комбинации двух; Я не пробовал.

Переходя к расширению идентификаторов объектов, мы знаем, что идентификаторы объектов по сути являются строками. Таким образом, мы можем использовать Joi.string методы в качестве основы. Назовем его dbId. Почему? Мы могли бы забить несколько rules здесь. Скажем, у вас также есть таблица postgres, которая использует UUID в качестве идентификаторов. 🤷‍♂
А пока давайте остановимся на создании только одного правила; для mongoDb mongoid.

Как мы проверяем, является ли строка действительным идентификатором mongo?

Простой; Если вы используете mongoose в качестве ODM, он предоставляет функцию, с помощью которой вы можете проверить, является ли значение допустимым Mongo Type. Об этом подробнее здесь".

Здесь мы можем использовать функцию mongoose.Types.ObjectId.isValid. Очевидно, что он возвращает истину / ложь в зависимости от переданного значения.

Соединяя все части вместе

Теперь у нас есть все необходимое для создания нашего первого метода фабрики объектов расширения. Это должно выглядеть примерно так:

const extention = joi => ({
   base: joi.string(),
   name: 'dbId',
   language: {
      mongoid: 'needs to be a valid object id',
   },
   rules: [{
      name: 'mongoid',
      validate(params, value, state, options) {
         if (!Mongoose.Types.ObjectId.isValid(value)) {
            return this.createError(
              'dbId.mongoid',
              { v: value },
              state,
              options
            );
         }
         return value;
      },
   }],
});

Теперь все, что вам нужно сделать, это расширить исходный объект Joi с помощью фабричного метода, и все готово 👍

const Joi = require('@hapi/joi');
const CustomJoi = Joi.extend(extention);
// You can now use CustomJoi.dbId().mongoid() as a validation in your schemas!

Ага; вот и все;
Вы можете найти код и ссылку npm для этого пакета здесь:





Ваше здоровье! ☕️