我可以使用ajv json模式验证日期,而无需将日期转换为字符串吗?

时间:2019-04-04 16:42:24

标签: node.js ajv

我有一个对象,其中包含日期类型的一个或多个属性。我想使用ajv json模式验证程序包来验证对象。 我可以使用toISOString()将date类型的属性转换为字符串。但是对象可以很安静,因此我不想转换整个对象的所有日期属性。 除了将日期转换为字符串,还有其他解决方案吗? 我能以某种方式创建自定义的ajv模式验证器吗?

 // My example schema
const schema = {
  "properties": {
    "createdAt": { 
       "type": "string",
       "format": "date-time"
    },
       "lastName": { "type": "string" },
       "firstName": { "type": "string" }
  }
};

// My example testobject
const testObj = {
   createdAt: new Date(),
   lastName: "Doe",
   firstName: "John"
}

// The validation
const validate = ajv.compile(schema);
const valid = validate(testObj);
if(!valid) console.log('Invalid: ' + ajv.errorsText(validate.errors));

这将执行控制台日志,因为testObj.createdAt是日期而不是字符串。

2 个答案:

答案 0 :(得分:0)

只需将您的ajv模式从"type": "string"更改为"type": "object",内置的ajv 日期时间格式就可以使用。这是working fiddle

您还可以定义自定义ajv格式来验证Date对象(或字符串),如下所示:

ajv = new Ajv();

ajv.addFormat('custom-date-time', function(dateTimeString) {
  if (typeof dateTimeString === 'object') {
    dateTimeString = dateTimeString.toISOString();
  }

  return !isNaN(Date.parse(dateTimeString));  // any test that returns true/false 
});

...,然后像这样在ajv模式中调用您的自定义格式:

const schema = {
  "properties": {
    "createdAt": {
      "type": "object",
      "format": "custom-date-time"

将所有内容放在一起,这里是代码和working fiddle for creating a custom date format

// My example schema

const schema = {
  "properties": {
    "createdAt": {
      "type": "object",
      "format": "custom-date-time"
    },
    "lastName": {
      "type": "string"
    },
    "firstName": {
      "type": "string"
    }
  }
};

// My example testobject
const testObj = {
  createdAt: new Date(),
  lastName: "Doe",
  firstName: "John"
}


// The validation
ajv = new Ajv();

ajv.addFormat('custom-date-time', function(dateTimeString) {
  if (typeof dateTimeString === 'object') {
    dateTimeString = dateTimeString.toISOString();
  }

  return !isNaN(Date.parse(dateTimeString));  // return true/false 
});

const validate = ajv.compile(schema);
const valid = validate(testObj);

if (valid)
  alert('valid');
else
  alert('Invalid: ' + ajv.errorsText(validate.errors));

答案 1 :(得分:0)

一种有效的方法是先转换为JSON Schema兼容对象(即JSON.parse(JSON.stringify(obj))正在克隆)。

function makeJsonSchemaCompatible (obj) {
  if (Array.isArray(obj)) {
    return obj.map((subObj) => makeJsonSchemaCompatible(subObj))
  } else if (obj && typeof obj === 'object') {
    const replacement = {}
    const className = obj.constructor.name
    if (className !== 'Object') {
      replacement.__className = className
    }
    Object.entries(obj).map(([k, v]) => { replacement[k] = makeJsonSchemaCompatible(v) })
    return replacement
  }

  return obj
}