Skip to content

Commit f1784a5

Browse files
authored
Update to ajv version 7.2.3 (#307)
* Migrate to ajv 7 * Add `$validateWithAjv` function to leverage ajv caching * Write a description for $validateWithAjv function * Improve $validateWithAjv description comment
1 parent 7f7b954 commit f1784a5

File tree

8 files changed

+58
-1776
lines changed

8 files changed

+58
-1776
lines changed

build-schema-validator.js

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
'use strict'
22

3-
const Ajv = require('ajv')
4-
const fs = require('fs')
5-
const path = require('path')
6-
const pack = require('ajv-pack')
3+
const Ajv = require('ajv').default
4+
const schema = require('ajv/dist/refs/json-schema-draft-07.json')
5+
const standalone = require('ajv/dist/standalone').default
76

8-
const ajv = new Ajv({
9-
sourceCode: true // this option is required by ajv-pack
10-
})
7+
const { basename, join } = require('path')
8+
const { writeFileSync } = require('fs')
119

12-
const validate = ajv.compile(require('ajv/lib/refs/json-schema-draft-07.json'))
10+
// *************************
1311

14-
const moduleCode = `// This file is autogenerated by ${path.basename(__filename)}, do not edit
12+
const ajv = new Ajv({ code: { source: true } })
13+
const validator = ajv.compile(schema)
14+
const moduleCode = `/* CODE GENERATED BY '${basename(__filename)}' DO NOT EDIT! */\n${standalone(ajv, validator)}`
1515

16-
function nop () { return true }
17-
18-
${pack(ajv, validate).replace(/root\.refVal\[0\]/gm, 'nop')}
19-
`
20-
21-
fs.writeFileSync(path.join(__dirname, 'schema-validator.js'), moduleCode)
16+
writeFileSync(join(__dirname, 'schema-validator.js'), moduleCode)

index.js

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
/* eslint no-prototype-builtins: 0 */
44

5-
const Ajv = require('ajv')
5+
const Ajv = require('ajv').default
66
const merge = require('deepmerge')
77
const clone = require('rfdc')({ proto: true })
88
const fjsCloned = Symbol('fast-json-stringify.cloned')
@@ -87,6 +87,40 @@ function build (schema, options) {
8787
${$asBoolean.toString()}
8888
${$asBooleanNullable.toString()}
8989
90+
91+
/**
92+
* Used by schemas that are dependant on calling 'ajv.validate' during runtime,
93+
* it stores the value of the '$id' property of the schema (if it has it) inside
94+
* a cache which is used to figure out if the schema was compiled into a validator
95+
* by ajv on a previous call, if it was then the '$id' string will be used to
96+
* invoke 'ajv.validate', this allows:
97+
*
98+
* 1. Schemas that depend on ajv.validate calls to leverage ajv caching system.
99+
* 2. To avoid errors, since directly invoking 'ajv.validate' with the same
100+
* schema (that contains an '$id' property) twice will throw an error.
101+
*/
102+
const $validateWithAjv = (function() {
103+
const cache = new Set()
104+
105+
return function (schema, target) {
106+
const id = schema.$id
107+
108+
if (!id) {
109+
return ajv.validate(schema, target)
110+
}
111+
112+
const cached = cache.has(id)
113+
114+
if (cached) {
115+
return ajv.validate(id, target)
116+
} else {
117+
cache.add(id)
118+
return ajv.validate(schema, target)
119+
}
120+
}
121+
})()
122+
123+
90124
var isLong = ${isLong ? isLong.toString() : false}
91125
92126
function parseInteger(int) { return Math.${intParseFunctionName}(int) }
@@ -870,7 +904,7 @@ function addIfThenElse (location, name) {
870904
let mergedLocation = mergeLocation(location, { schema: merged })
871905

872906
code += `
873-
valid = ajv.validate(${JSON.stringify(i)}, obj)
907+
valid = $validateWithAjv(${JSON.stringify(i)}, obj)
874908
if (valid) {
875909
`
876910
if (merged.if && merged.then) {
@@ -1189,7 +1223,7 @@ function nested (laterCode, name, key, location, subKey, isArray) {
11891223
// 2. `nested`, through `buildCode`, replaces any reference in object properties with the actual schema
11901224
// (see https://github.com/fastify/fast-json-stringify/blob/6da3b3e8ac24b1ca5578223adedb4083b7adf8db/index.js#L631)
11911225
code += `
1192-
${index === 0 ? 'if' : 'else if'}(ajv.validate(${JSON.stringify(location.schema)}, obj${accessor}))
1226+
${index === 0 ? 'if' : 'else if'}($validateWithAjv(${JSON.stringify(location.schema)}, obj${accessor}))
11931227
${nestedResult.code}
11941228
`
11951229
laterCode = nestedResult.laterCode
@@ -1205,7 +1239,7 @@ function nested (laterCode, name, key, location, subKey, isArray) {
12051239

12061240
// see comment on anyOf about derefencing the schema before calling ajv.validate
12071241
code += `
1208-
${index === 0 ? 'if' : 'else if'}(ajv.validate(${JSON.stringify(location.schema)}, obj${accessor}))
1242+
${index === 0 ? 'if' : 'else if'}($validateWithAjv(${JSON.stringify(location.schema)}, obj${accessor}))
12091243
${nestedResult.code}
12101244
`
12111245
laterCode = nestedResult.laterCode

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
},
3131
"homepage": "https://github.com/fastify/fast-json-stringify#readme",
3232
"devDependencies": {
33-
"ajv-pack": "^0.3.1",
3433
"benchmark": "^2.1.4",
3534
"compile-json-stringify": "^0.1.2",
3635
"is-my-json-valid": "^2.20.0",
@@ -44,7 +43,7 @@
4443
"typescript": "^4.0.2"
4544
},
4645
"dependencies": {
47-
"ajv": "^6.11.0",
46+
"ajv": "^7.2.3",
4847
"deepmerge": "^4.2.2",
4948
"rfdc": "^1.2.0",
5049
"string-similarity": "^4.0.1"

0 commit comments

Comments
 (0)