【问题标题】:Extended Joi not implementing custom operators扩展的 Joi 没有实现自定义操作符
【发布时间】:2021-02-05 03:51:02
【问题描述】:

我在使用自定义运算符扩展 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

How to extend a module from npm using TypeScript?

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

【问题讨论】:

  • 您使用的是哪个joimongodb 版本?

标签: javascript node.js typescript joi


【解决方案1】:

我也有这个问题。我用这个包解决了。

https://www.npmjs.com/package/joi-oid

const Joi = require('joi-oid')

const schema = Joi.object({
  id: Joi.objectId(),
  name: Joi.string(),
  age: Joi.number().min(18),
})

祝你好运:)

【讨论】:

    【解决方案2】:

    您想扩展 Joi.string() 基础。请记住,您无法验证new mongodb.ObjectID(),因为它的类型为object。您扩展了Joi.string(),如果您的值是string 类型,这将检查首先。如果不是,它将停止验证。您只能验证 new mongodb.ObjectID().toHexString(),它看起来像:"5f91a1449b13e3010c5548a2"

    此答案使用joi 17.2.1 和mongodb 3.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);
    
    

    【讨论】:

    • 非常感谢a1300,我也错过了规则部分,即使我有点搞砸了,结构也不正确。这完美无瑕。谢谢!
    • 扩展你的解决方案,你可以在stringObjectExtension对象中传递prepare: (val) => ({ value: val.toHexString ? val.toHexString() : val })。它将在验证之前处理转换,而不是在数据中手动转换。
    猜你喜欢
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-04
    • 2017-04-22
    • 1970-01-01
    相关资源
    最近更新 更多