Skip to content

Commit

Permalink
refactor: $dataMetaSchema now uses $data in keyword definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
epoberezkin committed Aug 29, 2020
1 parent 9f6a541 commit 057cdfc
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 44 deletions.
4 changes: 2 additions & 2 deletions lib/ajv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ Ajv.prototype.addKeyword = customKeyword.addKeyword
Ajv.prototype.getKeyword = customKeyword.getKeyword
Ajv.prototype.removeKeyword = customKeyword.removeKeyword
Ajv.prototype.validateKeyword = customKeyword.validateKeyword
Ajv.prototype.$dataMetaSchema = $dataMetaSchema

Ajv.ValidationError = ValidationError
Ajv.MissingRefError = MissingRefError
Ajv.$dataMetaSchema = $dataMetaSchema

var META_SCHEMA_ID = "http://json-schema.org/draft-07/schema"

Expand Down Expand Up @@ -428,7 +428,7 @@ function addDefaultMetaSchema(self) {
if (self._opts.meta === false) return
var metaSchema = require("./refs/json-schema-draft-07.json")
if (self._opts.$data) {
metaSchema = $dataMetaSchema(metaSchema, META_SUPPORT_DATA)
metaSchema = self.$dataMetaSchema(metaSchema, META_SUPPORT_DATA)
}
self.addMetaSchema(metaSchema, META_SCHEMA_ID, true)
self._refs["http://json-schema.org/schema"] = META_SCHEMA_ID
Expand Down
45 changes: 10 additions & 35 deletions lib/data.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,29 @@
// TODO use $data in keyword definitions
const KEYWORDS = [
"multipleOf",
"maximum",
"exclusiveMaximum",
"minimum",
"exclusiveMinimum",
"maxLength",
"minLength",
"pattern",
"additionalItems",
"maxItems",
"minItems",
"uniqueItems",
"maxProperties",
"minProperties",
"required",
"additionalProperties",
"enum",
"format",
"const",
]

export default function $dataMetaSchema(
this,
metaSchema: object,
keywordsJsonPointers: string[]
): object {
const rules = this.RULES.all
for (const jsonPointer of keywordsJsonPointers) {
metaSchema = JSON.parse(JSON.stringify(metaSchema))
const segments = jsonPointer.split("/").slice(1) // first segment is an empty string
let keywords = metaSchema
for (const seg of segments) keywords = keywords[seg]

for (const key of KEYWORDS) {
for (const key in rules) {
const $data = rules[key]?.definition?.$data
const schema = keywords[key]
if (schema) keywords[key] = schemaOrData(schema)
if ($data && schema) keywords[key] = schemaOrData(schema)
}
}

return metaSchema
}

function schemaOrData(schema: object): object {
return {
anyOf: [
schema,
{
$ref: "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#",
},
],
}
const $dataRef = {
$ref: "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#",
}

module.exports = $dataMetaSchema
export function schemaOrData(schema: object | boolean): object {
return {anyOf: [schema, $dataRef]}
}
9 changes: 2 additions & 7 deletions lib/keyword.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {KeywordDefinition, Vocabulary, ErrorObject, ValidateFunction} from "./types"
import {ValidationRules, Rule} from "./compile/rules"
import {definitionSchema} from "./definition_schema"
import {schemaOrData} from "./data"

const IDENTIFIER = /^[a-z_$][a-z0-9_$-]*$/i

Expand Down Expand Up @@ -99,17 +100,11 @@ function eachItem<T>(xs: T | T[], f: (x: T) => void): void {
}
}

const $dataRef = {
$ref: "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#",
}

function keywordMetaschema(this: any, def: KeywordDefinition): void {
// TODO this Ajv
let metaSchema = def.metaSchema
if (metaSchema === undefined) return
if (def.$data && this._opts.$data) {
metaSchema = {anyOf: [metaSchema, $dataRef]}
}
if (def.$data && this._opts.$data) metaSchema = schemaOrData(metaSchema)
def.validateSchema = this.compile(metaSchema, true)
}

Expand Down

0 comments on commit 057cdfc

Please sign in to comment.