validateSchema模塊 首先來看錯誤檢測: 可以註意到,這裡傳了兩個參數,其實第一個參數來源於一個JSON文件: 這個JSON文件非常大,可以觀察一下部分內容: 從描述可以猜測,這裡的key對應options中的key,value就是檢測方式。 比如說entry放到required代表是必 ...
validateSchema模塊
首先來看錯誤檢測:
const webpackOptionsValidationErrors = validateSchema(webpackOptionsSchema, options); if(webpackOptionsValidationErrors.length) { throw new WebpackOptionsValidationError(webpackOptionsValidationErrors); }
可以註意到,這裡傳了兩個參數,其實第一個參數來源於一個JSON文件:
const webpackOptionsSchema = require("../schemas/webpackOptionsSchema.json");
這個JSON文件非常大,可以觀察一下部分內容:
{
"plugins": {
"description": "Add additional plugins to the compiler.",
"type": "array"
},
"resolve": {
"description": "Options for the resolver",
"anyOf": [
{
"$ref": "#/definitions/resolve"
}
]
},
"required": [
"entry"
],
"type": "object"
}
從描述可以猜測,這裡的key對應options中的key,value就是檢測方式。
比如說entry放到required代表是必須的,plugins的type為array代表這個鍵必須是一個數組,而$ref代表一個路徑映射,即#/definnitions/resolve。
在JSON文件的開頭有一個definitions,其中resolve對應的內容如下:
{
"definitions": {
"resolve": {
"additionalProperties": false,
"properties": {
"alias": {
// ...
}
// ...
},
"type": "object"
}
}
}
簡單明瞭,就不多解釋了。
下麵進入validateSchema模塊,流程如圖:
內部代碼簡化如下:
const Ajv = require("ajv"); const ajv = new Ajv({ errorDataPath: "configuration", allErrors: true, verbose: true }); require("ajv-keywords")(ajv, ["instanceof"]); require("../schemas/ajv.absolutePath")(ajv); function validateSchema(schema, options) { // 仍然是多配置與單配置 if(Array.isArray(options)) { /*...*/ } else { return validateObject(schema, options); } } function validateObject(schema, options) { // 轉換JSON文件 const validate = ajv.compile(schema); // 檢測配置對象 const valid = validate(options); // 返回錯誤對象 return valid ? [] : filterErrors(validate.errors); } function filterErrors(errors) { /*...*/ } module.exports = validateSchema;
這裡引入的ajv模塊是一個工具,就像之前的JSON5一樣,作用是將一個JSON配置文件轉換成一個對象,用於檢測對象的合法性。
在github上,該工具的Getting started如圖所示:
簡直跟源碼中的使用過程一模一樣,所以有興趣的可以自己去看看教程學一下。
由於JSON十分巨大,所以編譯後的對象也十分巨大,這裡根據vue腳手架中的配置,只看常規的參數是如何進行檢測的,比如說devServer、devtool、entry、module、output、plugins、resolve,測試代碼如下:
var Ajv = require('ajv'); const ajv = new Ajv({ errorDataPath: "configuration", allErrors: true, verbose: true }); // 簡化後的JSON文件 const json = require('./tmp.json'); const validate = ajv.compile(json);
打包後嘗試獲取生成的validate函數,整理後源碼如下:
(function(self, RULES, formats, root, refVal, defaults, customRules, co, equal, ucs2length, ValidationError) { var refVal0 = refVal[0]; // ... var refVal13 = refVal[13]; var validate = (function(data, dataPath, parentData, parentDataProperty, rootData) { 'use strict'; // 負責收集錯誤信息 var vErrors = null; // 負責對錯誤進行計數 var errors = 0; if (rootData === undefined) rootData = data; // 這是根級對象 if ((data && typeof data === "object" && !Array.isArray(data))) { var errs__0 = errors; var valid1 = true; for (var key0 in data) { /*...*/ } // 在這裡進行檢測 // 每出現一個錯誤errors+1並記錄vErrors中 var data1 = data.devServer; if (data1 !== undefined) { /*...*/ } var data1 = data.devtool; if (data1 !== undefined) { /*...*/ } var data1 = data.entry; if (data1 === undefined) { /*...*/ } else { /*...*/ } var data1 = data.module; if (data1 !== undefined) { /*...*/ } var data1 = data.output; if (data1 !== undefined) { /*...*/ } var data1 = data.plugins; if (data1 !== undefined) { /*...*/ } var data1 = data.resolve; if (data1 !== undefined) { /*...*/ } } else { /*...*/ } validate.errors = vErrors; // 判斷是否產生錯誤 return errors === 0; }); return validate; })
調用validate(options),options在函數中就相當於那個data,validate會依次從data中取出需要校驗的key,按照JSON文件中的規則進行判斷。
這裡有一個比較麻煩的點,就是頂部的refVal,由於這是一個內部的IIFE,所以從這裡看不出refVal數組如何定義的。憑藉我的聰明才智,還是從源碼中獲取到了對應的定義:
打開後,其實是一堆validate函數,所以就不展開看了。
其實validate並不只有這麼多,其中還可以分為特殊校驗器和公共校驗器,其中公共校驗器不會針對特殊的鍵來進行校驗,在這裡可以先列出來。(友情警告:千萬不要點開!!!)
refVal1
if ((data && typeof data === "object" && !Array.isArray(data))) { if (Object.keys(data).length < 1) { var err = { keyword: 'minProperties', dataPath: (dataPath || '') + "", schemaPath: '#/oneOf/0/minProperties', params: { limit: 1 }, message: 'should NOT have less than 1 properties', schema: 1, parentSchema: validate.schema.oneOf[0], data: data }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var errs__1 = errors; var valid2 = true; for (var key1 in data) { var data1 = data[key1]; var errs_2 = errors; var errs__2 = errors; var prevValid2 = false; var valid2 = false; var errs_3 = errors; if (typeof data1 === "string") { if (ucs2length(data1) < 1) { var err = { keyword: 'minLength', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/oneOf/0/additionalProperties/oneOf/0/minLength', params: { limit: 1 }, message: 'should NOT be shorter than 1 characters', schema: 1, parentSchema: validate.schema.oneOf[0].additionalProperties.oneOf[0], data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } } else { var err = { keyword: 'type', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/oneOf/0/additionalProperties/oneOf/0/type', params: { type: 'string' }, message: 'should be string', schema: validate.schema.oneOf[0].additionalProperties.oneOf[0].type, parentSchema: validate.schema.oneOf[0].additionalProperties.oneOf[0], data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid3 = errors === errs_3; if (valid3) valid2 = prevValid2 = true; var errs_3 = errors; var errs__3 = errors; var valid3 = false; var errs_4 = errors; var errs_5 = errors; if (Array.isArray(data1)) { if (data1.length < 1) { var err = { keyword: 'minItems', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/minItems', params: { limit: 1 }, message: 'should NOT have less than 1 items', schema: 1, parentSchema: refVal2, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid5 = true; if (data1.length > 1) { var i = data1.length, j; outer: for (; i--;) { for (j = i; j--;) { if (equal(data1[i], data1[j])) { valid5 = false; break outer; } } } } if (!valid5) { var err = { keyword: 'uniqueItems', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/uniqueItems', params: { i: i, j: j }, message: 'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)', schema: true, parentSchema: refVal2, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var errs__5 = errors; var valid5; for (var i5 = 0; i5 < data1.length; i5++) { var data2 = data1[i5]; var errs_6 = errors; if (typeof data2 === "string") { if (ucs2length(data2) < 1) { var err = { keyword: 'minLength', dataPath: (dataPath || '') + '[\'' + key1 + '\'][' + i5 + ']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/items/minLength', params: { limit: 1 }, message: 'should NOT be shorter than 1 characters', schema: 1, parentSchema: refVal2.items, data: data2 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } } else { var err = { keyword: 'type', dataPath: (dataPath || '') + '[\'' + key1 + '\'][' + i5 + ']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/items/type', params: { type: 'string' }, message: 'should be string', schema: refVal2.items.type, parentSchema: refVal2.items, data: data2 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid6 = errors === errs_6; } } else { var err = { keyword: 'type', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/type', params: { type: 'array' }, message: 'should be array', schema: refVal2.type, parentSchema: refVal2, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid5 = errors === errs_5; var valid4 = errors === errs_4; valid3 = valid3 || valid4; if (!valid3) { var err = { keyword: 'anyOf', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/oneOf/0/additionalProperties/oneOf/1/anyOf', params: {}, message: 'should match some schema in anyOf', schema: validate.schema.oneOf[0].additionalProperties.oneOf[1].anyOf, parentSchema: validate.schema.oneOf[0].additionalProperties.oneOf[1], data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } else { errors = errs__3; if (vErrors !== null) { if (errs__3) vErrors.length = errs__3; else vErrors = null; } } var valid3 = errors === errs_3; if (valid3 && prevValid2) valid2 = false; else { if (valid3) valid2 = prevValid2 = true; } if (!valid2) { var err = { keyword: 'oneOf', dataPath: (dataPath || '') + '[\'' + key1 + '\']', schemaPath: '#/oneOf/0/additionalProperties/oneOf', params: {}, message: 'should match exactly one schema in oneOf', schema: validate.schema.oneOf[0].additionalProperties.oneOf, parentSchema: validate.schema.oneOf[0].additionalProperties, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } else { errors = errs__2; if (vErrors !== null) { if (errs__2) vErrors.length = errs__2; else vErrors = null; } } var valid2 = errors === errs_2; } } else { var err = { keyword: 'type', dataPath: (dataPath || '') + "", schemaPath: '#/oneOf/0/type', params: { type: 'object' }, message: 'should be object', schema: validate.schema.oneOf[0].type, parentSchema: validate.schema.oneOf[0], data: data }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid1 = errors === errs_1; if (valid1) valid0 = prevValid0 = true; var errs_1 = errors; if (typeof data === "string") { if (ucs2length(data) < 1) { var err = { keyword: 'minLength', dataPath: (dataPath || '') + "", schemaPath: '#/oneOf/1/minLength', params: { limit: 1 }, message: 'should NOT be shorter than 1 characters', schema: 1, parentSchema: validate.schema.oneOf[1], data: data }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } } else { var err = { keyword: 'type', dataPath: (dataPath || '') + "", schemaPath: '#/oneOf/1/type', params: { type: 'string' }, message: 'should be string', schema: validate.schema.oneOf[1].type, parentSchema: validate.schema.oneOf[1], data: data }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid1 = errors === errs_1; if (valid1 && prevValid0) valid0 = false; else { if (valid1) valid0 = prevValid0 = true; var errs_1 = errors; var errs__1 = errors; var valid1 = false; var errs_2 = errors; var errs_3 = errors; if (Array.isArray(data)) { if (data.length < 1) { var err = { keyword: 'minItems', dataPath: (dataPath || '') + "", schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/minItems', params: { limit: 1 }, message: 'should NOT have less than 1 items', schema: 1, parentSchema: refVal[2], data: data }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid3 = true; if (data.length > 1) { var i = data.length, j; outer: for (; i--;) { for (j = i; j--;) { if (equal(data[i], data[j])) { valid3 = false; break outer; } } } } if (!valid3) { var err = { keyword: 'uniqueItems', dataPath: (dataPath || '') + "", schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/uniqueItems', params: { i: i, j: j }, message: 'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)', schema: true, parentSchema: refVal[2], data: data }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var errs__3 = errors; var valid3; for (var i3 = 0; i3 < data.length; i3++) { var data1 = data[i3]; var errs_4 = errors; if (typeof data1 === "string") { if (ucs2length(data1) < 1) { var err = { keyword: 'minLength', dataPath: (dataPath || '') + '[' + i3 + ']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/items/minLength', params: { limit: 1 }, message: 'should NOT be shorter than 1 characters', schema: 1, parentSchema: refVal[2].items, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } } else { var err = { keyword: 'type', dataPath: (dataPath || '') + '[' + i3 + ']', schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/items/type', params: { type: 'string' }, message: 'should be string', schema: refVal[2].items.type, parentSchema: refVal[2].items, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid4 = errors === errs_4; } } else { var err = { keyword: 'type', dataPath: (dataPath || '') + "", schemaPath: '#/definitions/common.nonEmptyArrayOfUniqueStringValues/type', params: { type: 'array' }, message: 'should be array', schema: refVal[2].type, parentSchema: refVal[2], data: data }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid3 = errors === errs_3; var valid2 = errors === errs_2; valid1 = valid1 || valid2; if (!valid1) { var err = { keyword: 'anyOf', dataPath: (dataPath || '') + "", schemaPath: '#/oneOf/2/anyOf', params: {}, message: 'should match some schema in anyOf', schema: validate.schema.oneOf[2].anyOf, parentSchema: validate.schema.oneOf[2], data: data }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } else { errors = errs__1; if (vErrors !== null) { if (errs__1) vErrors.length = errs__1; else vErrors = null; } } var valid1 = errors === errs_1; if (valid1 && prevValid0) valid0 = false; else { if (valid1) valid0 = prevValid0 = true; var valid1 = true; if (valid1 && prevValid0) valid0 = false; else { if (valid1) valid0 = prevValid0 = true; } } } if (!valid0) { var err = { keyword: 'oneOf', dataPath: (dataPath || '') + "", schemaPath: '#/oneOf', params: {}, message: 'should match exactly one schema in oneOf', schema: validate.schema.oneOf, parentSchema: validate.schema, data: data }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } else { errors = errs__0; if (vErrors !== null) { if (errs__0) vErrors.length = errs__0; else vErrors = null; } }View Code
規則:
1.數據可以為字元串、對象、數組
2.字元串必須為非空字元串
3.數組必須是非空數組,元素必須是非空字元串且不能重覆
4.如果是對象則至少要有2個鍵,鍵的規則滿足2、3
refVal3
if ((data && typeof data === "object" && !Array.isArray(data))) { var errs__0 = errors; var valid1 = true; for (var key0 in data) { var isAdditional0 = !(false || validate.schema.properties[key0]); if (isAdditional0) { valid1 = false; var err = { keyword: 'additionalProperties', dataPath: (dataPath || '') + "", schemaPath: '#/additionalProperties', params: { additionalProperty: '' + key0 + '' }, message: 'should NOT have additional properties', schema: false, parentSchema: validate.schema, data: data }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } } var data1 = data.exprContextCritical; if (data1 !== undefined) { var errs_1 = errors; if (typeof data1 !== "boolean") { var err = { keyword: 'type', dataPath: (dataPath || '') + '.exprContextCritical', schemaPath: '#/properties/exprContextCritical/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.exprContextCritical.type, parentSchema: validate.schema.properties.exprContextCritical, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid1 = errors === errs_1; } var data1 = data.exprContextRecursive; if (data1 !== undefined) { var errs_1 = errors; if (typeof data1 !== "boolean") { var err = { keyword: 'type', dataPath: (dataPath || '') + '.exprContextRecursive', schemaPath: '#/properties/exprContextRecursive/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.exprContextRecursive.type, parentSchema: validate.schema.properties.exprContextRecursive, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid1 = errors === errs_1; } if (data.exprContextRegExp !== undefined) { var errs_1 = errors; var valid1 = errors === errs_1; } var data1 = data.exprContextRequest; if (data1 !== undefined) { var errs_1 = errors; if (typeof data1 !== "string") { var err = { keyword: 'type', dataPath: (dataPath || '') + '.exprContextRequest', schemaPath: '#/properties/exprContextRequest/type', params: { type: 'string' }, message: 'should be string', schema: validate.schema.properties.exprContextRequest.type, parentSchema: validate.schema.properties.exprContextRequest, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid1 = errors === errs_1; } var data1 = data.loaders; if (data1 !== undefined) { var errs_1 = errors; var errs__1 = errors; var valid1 = false; var errs_2 = errors; if (!refVal4(data1, (dataPath || '') + '.loaders', data, 'loaders', rootData)) { if (vErrors === null) vErrors = refVal4.errors; else vErrors = vErrors.concat(refVal4.errors); errors = vErrors.length; } var valid2 = errors === errs_2; valid1 = valid1 || valid2; if (!valid1) { var err = { keyword: 'anyOf', dataPath: (dataPath || '') + '.loaders', schemaPath: '#/properties/loaders/anyOf', params: {}, message: 'should match some schema in anyOf', schema: validate.schema.properties.loaders.anyOf, parentSchema: validate.schema.properties.loaders, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } else { errors = errs__1; if (vErrors !== null) { if (errs__1) vErrors.length = errs__1; else vErrors = null; } } var valid1 = errors === errs_1; } if (data.noParse !== undefined) { var errs_1 = errors; var valid1 = errors === errs_1; } if (data.rules !== undefined) { var errs_1 = errors; var errs_2 = errors; if (!refVal[4](data.rules, (dataPath || '') + '.rules', data, 'rules', rootData)) { if (vErrors === null) vErrors = refVal[4].errors; else vErrors = vErrors.concat(refVal[4].errors); errors = vErrors.length; } var valid2 = errors === errs_2; var valid1 = errors === errs_1; } var data1 = data.unknownContextCritical; if (data1 !== undefined) { var errs_1 = errors; if (typeof data1 !== "boolean") { var err = { keyword: 'type', dataPath: (dataPath || '') + '.unknownContextCritical', schemaPath: '#/properties/unknownContextCritical/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.unknownContextCritical.type, parentSchema: validate.schema.properties.unknownContextCritical, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid1 = errors === errs_1; } var data1 = data.unknownContextRecursive; if (data1 !== undefined) { var errs_1 = errors; if (typeof data1 !== "boolean") { var err = { keyword: 'type', dataPath: (dataPath || '') + '.unknownContextRecursive', schemaPath: '#/properties/unknownContextRecursive/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.unknownContextRecursive.type, parentSchema: validate.schema.properties.unknownContextRecursive, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid1 = errors === errs_1; } if (data.unknownContextRegExp !== undefined) { var errs_1 = errors; var valid1 = errors === errs_1; } var data1 = data.unknownContextRequest; if (data1 !== undefined) { var errs_1 = errors; if (typeof data1 !== "string") { var err = { keyword: 'type', dataPath: (dataPath || '') + '.unknownContextRequest', schemaPath: '#/properties/unknownContextRequest/type', params: { type: 'string' }, message: 'should be string', schema: validate.schema.properties.unknownContextRequest.type, parentSchema: validate.schema.properties.unknownContextRequest, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid1 = errors === errs_1; } if (data.unsafeCache !== undefined) { var errs_1 = errors; var valid1 = errors === errs_1; } var data1 = data.wrappedContextCritical; if (data1 !== undefined) { var errs_1 = errors; if (typeof data1 !== "boolean") { var err = { keyword: 'type', dataPath: (dataPath || '') + '.wrappedContextCritical', schemaPath: '#/properties/wrappedContextCritical/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.wrappedContextCritical.type, parentSchema: validate.schema.properties.wrappedContextCritical, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid1 = errors === errs_1; } var data1 = data.wrappedContextRecursive; if (data1 !== undefined) { var errs_1 = errors; if (typeof data1 !== "boolean") { var err = { keyword: 'type', dataPath: (dataPath || '') + '.wrappedContextRecursive', schemaPath: '#/properties/wrappedContextRecursive/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.wrappedContextRecursive.type, parentSchema: validate.schema.properties.wrappedContextRecursive, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid1 = errors === errs_1; } var data1 = data.strictExportPresence; if (data1 !== undefined) { var errs_1 = errors; if (typeof data1 !== "boolean") { var err = { keyword: 'type', dataPath: (dataPath || '') + '.strictExportPresence', schemaPath: '#/properties/strictExportPresence/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.strictExportPresence.type, parentSchema: validate.schema.properties.strictExportPresence, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid1 = errors === errs_1; } var data1 = data.strictThisContextOnImports; if (data1 !== undefined) { var errs_1 = errors; if (typeof data1 !== "boolean") { var err = { keyword: 'type', dataPath: (dataPath || '') + '.strictThisContextOnImports', schemaPath: '#/properties/strictThisContextOnImports/type', params: { type: 'boolean' }, message: 'should be boolean', schema: validate.schema.properties.strictThisContextOnImports.type, parentSchema: validate.schema.properties.strictThisContextOnImports, data: data1 }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } var valid1 = errors === errs_1; } } else { var err = { keyword: 'type', dataPath: (dataPath || '') + "", schemaPath: '#/type', params: { type: 'object' }, message: 'should be object', schema: validate.schema.type, parentSchema: validate.sche