Skip to content

Commit

Permalink
feat: optimize enum keyword, option loopEnum, to typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
epoberezkin committed Aug 11, 2020
1 parent 08d1224 commit 0c179f3
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/ajv.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ function Ajv(opts) {
throw new Error("option schemaId is not supported from v7")

opts.loopRequired = opts.loopRequired || Infinity
opts.loopEnum = opts.loopEnum || Infinity
if (opts.errorDataPath == "property") opts._errorDataPathProperty = true
if (opts.serialize === undefined) opts.serialize = stableStringify
this._metaOpts = getMetaSchemaOptions(this)
Expand Down
2 changes: 1 addition & 1 deletion lib/compile/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module.exports = function rules() {
{properties: ["additionalProperties", "patternProperties"]},
],
},
{rules: ["$ref", "enum", "not", "anyOf", "oneOf", "allOf", "if"]},
{rules: ["$ref", "not", "anyOf", "oneOf", "allOf", "if"]},
]

var ALL = ["type", "$comment"]
Expand Down
1 change: 0 additions & 1 deletion lib/dotjs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ module.exports = {
$comment: require("./comment"),
contains: require("./contains"),
dependencies: require("./dependencies"),
enum: require("./enum"),
format: require("./format"),
if: require("./if"),
items: require("./items"),
Expand Down
7 changes: 6 additions & 1 deletion lib/keyword.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,12 @@ function ruleCode(
it.dataPathArr
)};`
} else {
if (schemaType && typeof schema !== schemaType)
if (
schemaType &&
!(schemaType === "array"
? Array.isArray(schema)
: typeof schema === schemaType)
)
throw new Error(`${keyword} must be ${schemaType}`)
schemaCode = schemaRefOrVal()
}
Expand Down
1 change: 1 addition & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface Options {
inlineRefs?: boolean | number
passContext?: boolean
loopRequired?: number
loopEnum?: number
ownProperties?: boolean
multipleOfPrecision?: boolean | number
errorDataPath?: string
Expand Down
66 changes: 66 additions & 0 deletions lib/vocabularies/validation/enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {KeywordDefinition} from "../../types"
import {quotedString} from "../util"

const def: KeywordDefinition = {
keyword: "enum",
schemaType: "array",
$data: true,
code({write, fail, scope, data, $data, schema, schemaCode, opts}) {
const valid = scope.getName("valid")
if ($data) {
write(`let ${valid};`)
// TODO trim whitespace
write(
`if (${schemaCode} === undefined) ${valid} = true;
else {
${valid} = false;
if (Array.isArray(${schemaCode})) {`
)
loopEnum(<string>schemaCode)
write("}}")
fail(`!${valid}`)
} else {
if (schema.length === 0) throw new Error("enum must have non-empty array")
const vSchema = scope.getName("schema")
write(`const ${vSchema} = ${schemaCode};`)
if (schema.length > (opts.loopEnum as number)) {
write(`let ${valid} = false;`)
loopEnum(vSchema)
fail(`!${valid}`)
} else {
let cond: string = schema.reduce(
(c, _, i) => (c += (c && "||") + equalCode(vSchema, i)),
""
)
fail(`!(${cond})`)
}
}

function loopEnum(sch: string): void {
// TODO trim whitespace
write(
`for (const v of ${sch}) {
if (equal(${data}, v)) {
${valid} = true;
break;
}
}`
)
}

function equalCode(vSchema: string, i: number): string {
let sch = schema[i]
if (sch && typeof sch === "object") {
return `equal(${data}, ${vSchema}[${i}])`
}
if (typeof sch === "string") sch = quotedString(sch)
return `${data} === ${sch}`
}
},
error: {
message: () => '"should be equal to one of the allowed values"',
params: ({schemaCode}) => `{allowedValues: ${schemaCode}}`,
},
}

module.exports = def
1 change: 1 addition & 0 deletions lib/vocabularies/validation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const validation: Vocabulary = [
require("./limitItems"),
// any
require("./const"),
require("./enum"),
]

module.exports = validation

0 comments on commit 0c179f3

Please sign in to comment.