首页 > 解决方案 > 扩展的 Joi 没有实现自定义操作符

问题描述

我在使用自定义运算符扩展 joi 类时遇到问题。我想验证 mongodb Id,但扩展对象抛出以下错误:

error: uncaughtException: JoiObj.string(...).objectId is not a function
TypeError: JoiObj.string(...).objectId is not a function

代码如下:

import Joi from 'joi';
import * as mongodb from 'mongodb';

interface ExtendedStringSchema extends Joi.StringSchema {
    objectId(): this;
}

interface ExtendedJoi extends Joi.Root {
    string(): ExtendedStringSchema;
}

const JoiObj: ExtendedJoi = Joi.extend({
    base: Joi.string(),
    type: 'objectId',
    messages: {
        'objectId.invalid': '"{{#label}}" must be a valid mongo id'
    },
    validate(value, helpers) {
        if (!mongodb.ObjectId.isValid(value)) {
            return helpers.error('objectId.invalid');
        }

        return value;
    }
});

const objIdSchema = JoiObj.object({
    id: JoiObj.string().objectId()
});

我找到了2个例子:

https://github.com/sideway/joi/issues/2357

如何使用 TypeScript 从 npm 扩展模块?

但是,它们使用的属性与 TS 定义文件中描述的属性不同,因此不起作用。

标签: javascriptnode.jstypescriptjoi

解决方案


你想扩展Joi.string()基地。请记住,您无法验证new mongodb.ObjectID(),因为它是 type object。您进行了扩展Joi.string(),这首先检查您的值是否为 type string。如果不是,它将停止验证。您只能验证new mongodb.ObjectID().toHexString()如下所示:"5f91a1449b13e3010c5548a2"

这个答案是使用joi17.2.1 和mongodb3.6.2

import Joi from 'joi';
import * as mongodb from 'mongodb';

interface ExtendedStringSchema extends Joi.StringSchema {
    objectId(): this;
}

interface ExtendedJoi extends Joi.Root {
    string(): ExtendedStringSchema;
}

const stringObjectExtension: Joi.Extension = {
    type: 'string',
    base: Joi.string(),
    messages: {
        'string.objectId': '{{#label}} must be a valid mongo id'
    },
    rules: {
      objectId: {
        validate: (value: any, helpers) => {
          if (!mongodb.ObjectId.isValid(value)) {
              return helpers.error('string.objectId')
          }

          return value;
        }
      }
    }
};

// create extended Joi
const JoiObj: ExtendedJoi = Joi.extend(stringObjectExtension);

// create new mongodb id
const id = new mongodb.ObjectID();

const objIdSchema = JoiObj.object({
    id: JoiObj.string().objectId()
});

// will fail because it won't pass the Joi.string() validation
const data1 = {
  id: id
};
console.log(objIdSchema.validate(data1).error);

// will succeed
const data2 = {
  id: id.toHexString()
};
console.log(objIdSchema.validate(data2).error);


推荐阅读