Расширить Joi с пользовательским типом для заполненных строк - PullRequest
0 голосов
/ 04 февраля 2019

Я хочу создать пользовательский тип Joi для populatedString s, используя .extend(..) для создания типа на основе joi.string(), который:

  • Обрезает строку
  • Изменяет значение на undefined, если trimmed string === '', чтобы проверенный вывод вообще не содержал ключ
  • Переопределяет .required(), поэтому он действует на обрезанную строку и создает ошибки, используя мой собственный язык.Когда .required () установлен для моего типа, это означает, что для него требуется строка, которая не только содержит пробелы или является пустой

Моя попытка на данный момент близка:

    const StandardJoi = require("joi");

    const Joi = StandardJoi.extend(joi => ({
      base: joi.string(),
      name: "populatedString",
      language: {
        required: "needs to be a a string containing non whitespace characters"
      },
      pre(value, state, options) {
        value = value.trim();
        return value === "" ? undefined : value;
      },
      rules: [
        {
          name: "required",
          validate(params, value, state, options) {
            if (value === undefined) {
              return this.createError(
                "populatedString.required",
                { v: value },
                state,
                options
              );
            }

            return value;
          }
        }
      ]
    }));

Примеры того, как он работает

    Joi.populatedString().validate(" x "); // $.value === 'x'
    Joi.populatedString().validate("  "); // $.value === undefined

    // $.error.details
    //
    // [ { message: '"value" needs to be a a string containing non whitespace characters',​​​​​
    // ​​​​​    path: [],​​​​​
    // ​​​​​    type: 'populatedString.required',​​​​​
    // ​​​​​    context: { v: undefined, key: undefined, label: 'value' } } ]​​​​​
    Joi.populatedString()
      .required()
      .validate("  ");

    // $.value
    //
    // { inObj1: 'o' }
    Joi.object()
      .keys({
        inObj1: Joi.populatedString()
      })
      .validate({ inObj1: " o " });

Но он не выходит из строя (как и должно быть) для

    // ​​​​​{ error: null, value: {}, then: [λ: then], catch: [λ: catch] }​​​​​
    Joi.object()
      .keys({
        inObj2: Joi.populatedString(),
        inObj3: Joi.populatedString().required()
      })
      .validate({ inObj2: "  " });

Даже если inObj3 равен .required() и не поставляется, он нене подведет.

1 Ответ

0 голосов
/ 05 февраля 2019

Мне удалось решить:

    const BaseJoi = require("joi");

    const Joi = BaseJoi.extend(joi => ({
      base: joi.string(),
      name: "populatedString",
      language: {
        required: "needs to be a a string containing non whitespace characters"
      },
      pre(value, state, options) {
        value = value.trim();
        return value === "" ? undefined : value;
      },
      rules: [
        {
          name: "required",
          setup(params) {
            return this.options({ presence: "required" });
          },
          validate(params, value, state, options) {
            if (value === undefined) {
              return this.createError(
                "populatedString.required",
                { v: value },
                state,
                options
              );
            }

            return value;
          }
        }
      ]
    }));

Исправлено было добавить setup и позволить ему установить опцию presence = required, если был вызван required().

...