Skip to content

Commit

Permalink
refactor: allOf to typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
epoberezkin committed Aug 17, 2020
1 parent 43df463 commit db7574d
Show file tree
Hide file tree
Showing 19 changed files with 240 additions and 75 deletions.
10 changes: 7 additions & 3 deletions lib/ajv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import Cache from "./cache"
import {ValidationError, MissingRefError} from "./compile/error_classes"
import rules from "./compile/rules"
import $dataMetaSchema from "./data"
import {Vocabulary, Options} from "./types"

var compileSchema = require("./compile"),
resolve = require("./compile/resolve"),
stableStringify = require("fast-json-stable-stringify"),
validationVocabulary = require("./vocabularies/validation")
stableStringify = require("fast-json-stable-stringify")

const validationVocabulary: Vocabulary = require("./vocabularies/validation")
const applicatorVocabulary: Vocabulary = require("./vocabularies/applicator")

module.exports = Ajv

Expand Down Expand Up @@ -47,7 +50,7 @@ const META_SUPPORT_DATA = ["/properties"]
* @param {Object} opts optional options
* @return {Object} ajv instance
*/
function Ajv(opts): void {
export default function Ajv(opts: Options): void {
if (!(this instanceof Ajv)) return new Ajv(opts)
opts = this._opts = {...(opts || {})}
setLogger(this)
Expand All @@ -74,6 +77,7 @@ function Ajv(opts): void {

if (opts.formats) addInitialFormats(this)
this.addVocabulary(validationVocabulary, true)
this.addVocabulary(applicatorVocabulary, true)
if (opts.keywords) addInitialKeywords(this, opts.keywords)
addDefaultMetaSchema(this)
if (typeof opts.meta == "object") this.addMetaSchema(opts.meta)
Expand Down
79 changes: 79 additions & 0 deletions lib/compile/context._ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
interface ContextConstructorArgument {
ajv: any
schema: any
isRoot: boolean
baseId: string
}

export default class SchemaCompilationContext {
isTop?: boolean = true
async: boolean
schema: any
isRoot: boolean
baseId: string

// TODO ajv type
constructor({ajv, schema, isRoot, baseId}: ContextConstructorArgument) {
this.async = schema.$async === true
this.schema = schema
this.isRoot = isRoot
this.baseId = baseId
}
}


// root: _root,
// schemaPath: "",
// errSchemaPath: "#",
// errorPath: '""',
// dataPathArr: [""],
// level: 0,
// dataLevel: 0,
// data: "data", // TODO get unique name when passed from applicator keywords
// gen: new CodeGen(),
// MissingRefError,
// RULES: RULES,
// validate: validateCode,
// util: util,
// resolve: resolve,
// resolveRef: resolveRef,
// usePattern: usePattern,
// useDefault: useDefault,
// useCustomRule: useCustomRule,
// opts: opts,
// formats: formats,
// logger: self.logger,
// self: self,


// level: number
// dataLevel: number
// data: string
// dataPathArr: string[]
// schemaPath: string
// errorPath: string
// errSchemaPath: string
// gen: CodeGen
// createErrors?: boolean // TODO maybe remove later
// opts: Options
// formats: {
// [index: string]: Format | undefined
// }
// // keywords: {
// // [index: string]: KeywordDefinition | undefined
// // }
// compositeRule?: boolean
// validate: (it: CompilationContext) => string
// usePattern: (str: string) => string
// useDefault: (value: any) => string
// useCustomRule: (rule: Rule, schema: any, parentSchema: object, it: CompilationContext) => any
// util: object // TODO
// self: object // TODO
// RULES: ValidationRules
// logger: Logger // TODO ?
// isTop: boolean // TODO ?
// root: SchemaRoot // TODO ?
// rootId?: string // TODO ?
// MissingRefError: typeof MissingRefError
// resolve: any
// resolveRef: (...args: any[]) => any
31 changes: 17 additions & 14 deletions lib/compile/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import CodeGen from "./codegen"
import {toQuotedString} from "./util"
import {MissingRefError} from "./error_classes"
import validateCode from "./validate"
import {applySchema} from "./subschema"
import {Rule} from "./rules"
import {CompilationContext, KeywordDefinition, ErrorObject} from "../types"

Expand Down Expand Up @@ -93,12 +94,13 @@ function compile(schema, root, localRefs, baseId) {

var $async = _schema.$async === true

var sourceCode = validateCode({
// TODO refactor to extract code from gen
let sourceCode = <string>validateCode({
isTop: true,
async: _schema.$async === true,
schema: _schema,
isRoot: isRoot,
baseId: baseId,
isRoot,
baseId,
root: _root,
schemaPath: "",
errSchemaPath: "#",
Expand All @@ -109,18 +111,19 @@ function compile(schema, root, localRefs, baseId) {
data: "data", // TODO get unique name when passed from applicator keywords
gen: new CodeGen(),
MissingRefError,
RULES: RULES,
validate: validateCode,
util: util,
resolve: resolve,
resolveRef: resolveRef,
usePattern: usePattern,
useDefault: useDefault,
useCustomRule: useCustomRule,
opts: opts,
formats: formats,
RULES,
validateCode,
applySchema, // TODO remove to imports
util, // TODO remove to imports
resolve, // TODO remove to imports
resolveRef, // TODO remove to imports
usePattern, // TODO remove to imports
useDefault, // TODO remove to imports
useCustomRule, // TODO remove to imports
opts,
formats,
logger: self.logger,
self: self,
self,
})

sourceCode =
Expand Down
2 changes: 1 addition & 1 deletion lib/compile/rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default function rules(): ValidationRules {
{properties: ["additionalProperties", "patternProperties"]},
],
},
{rules: ["$ref", "not", "anyOf", "oneOf", "allOf", "if"]},
{rules: ["$ref", "not", "anyOf", "oneOf", "if"]},
],
all: toHash(ALL),
keywords: {},
Expand Down
30 changes: 30 additions & 0 deletions lib/compile/subschema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {CompilationContext} from "../types"
import validateCode from "./validate"
import {getProperty, escapeFragment} from "./util"

export interface Subschema {
schema: any
schemaPath: string
errSchemaPath: string
}

export function applySchema(it: CompilationContext, subschema: Subschema): string {
const {gen, level} = it
const nextIt = {...it, ...subschema, level: level + 1}
const nextValid = gen.name("valid")
// TODO remove true once appendGen is removed
validateCode(nextIt, nextValid, true)
return nextValid
}

export function applyKeywordSubschema(
it: CompilationContext,
keyword: string,
prop: string | number
): string {
return applySchema(it, {
schema: it.schema[keyword][prop],
schemaPath: it.schemaPath + getProperty(keyword) + getProperty(prop),
errSchemaPath: `${it.errSchemaPath}/${keyword}/${escapeFragment("" + prop)}`,
})
}
8 changes: 4 additions & 4 deletions lib/compile/validate/boolSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ const boolError: KeywordErrorDefinition = {
params: () => "{}",
}

export function booleanOrEmptySchema(it: CompilationContext): void {
const {gen, isTop, schema, level} = it
export function booleanOrEmptySchema(it: CompilationContext, valid: string): void {
const {gen, isTop, schema} = it
if (isTop) {
if (schema === false) {
falseSchemaError(it, false)
Expand All @@ -22,10 +22,10 @@ export function booleanOrEmptySchema(it: CompilationContext): void {
)
} else {
if (schema === false) {
gen.code(`var valid${level} = false;`) // TODO level, var
gen.code(`var ${valid} = false;`) // TODO var
falseSchemaError(it)
} else {
gen.code(`var valid${level} = true;`) // TODO level, var
gen.code(`var ${valid} = true;`) // TODO var
}
}
}
Expand Down
41 changes: 30 additions & 11 deletions lib/compile/validate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ const resolve = require("../resolve")
* "validate" is a variable name to which this function will be assigned
* validateRef etc. are defined in the parent scope in index.js
*/
export default function validateCode(it: CompilationContext): string {
export default function validateCode(
it: CompilationContext,
valid?: string,
appendGen?: true // TODO remove once all callers pass true
): string | void {
const {
isTop,
schema,
Expand All @@ -26,9 +30,17 @@ export default function validateCode(it: CompilationContext): string {
gen,
opts: {$comment},
} = it
// TODO _out
let _out = gen._out
gen._out = ""

let _out
if (!appendGen) {
// TODO _out
_out = gen._out
gen._out = ""
}

// TODO valid must be non-optional or maybe it must be returned
if (!valid) valid = `valid${level}`

checkUnknownKeywords(it)
checkRefsAndKeywords(it)

Expand All @@ -47,18 +59,25 @@ export default function validateCode(it: CompilationContext): string {
checkAsync(it)
gen.code(`var errs_${level} = errors;`)
typeAndKeywords()
gen.code(`var valid${level} = errors === errs_${level};`)
// TODO level, var
gen.code(`var ${valid} = errors === errs_${level};`)
}

// TODO _out
;[_out, gen._out] = [gen._out, _out]
return _out
if (!appendGen) {
// TODO _out
;[_out, gen._out] = [gen._out, _out]
return _out
}

function booleanOrEmpty(): true | void {
if (typeof schema == "boolean" || !schemaHasRules(schema, RULES.all)) {
booleanOrEmptySchema(it)
// TODO _out
;[_out, gen._out] = [gen._out, _out]
// TODO remove type cast once valid is non optional
booleanOrEmptySchema(it, <string>valid)

if (!appendGen) {
// TODO _out
;[_out, gen._out] = [gen._out, _out]
}
return true
}
}
Expand Down
34 changes: 0 additions & 34 deletions lib/dot/allOf.jst

This file was deleted.

2 changes: 1 addition & 1 deletion lib/dot/custom.jst
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ var {{=$valid}};
$it.schemaPath = '';
}}
{{# def.setCompositeRule }}
{{ var $code = it.validate($it).replace(/validate\.schema/g, $validateCode); }}
{{ var $code = it.validateCode($it).replace(/validate\.schema/g, $validateCode); }}
{{# def.resetCompositeRule }}
{{= $code }}
{{??}}
Expand Down
4 changes: 2 additions & 2 deletions lib/dot/definitions.def
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@

{{## def.generateSubschemaCode:
{{
var $code = it.validate($it);
var $code = it.validateCode($it);
$it.baseId = $currentBaseId;
}}
#}}


{{## def.insertSubschemaCode:
{{= it.validate($it) }}
{{= it.validateCode($it) }}
{{ $it.baseId = $currentBaseId; }}
#}}

Expand Down
2 changes: 1 addition & 1 deletion lib/dot/not.jst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
$it.opts.allErrors = false;
}
}}
{{= it.validate($it) }}
{{= it.validateCode($it) }}
{{
$it.createErrors = true;
if ($allErrorsOption) $it.opts.allErrors = $allErrorsOption;
Expand Down
2 changes: 1 addition & 1 deletion lib/dot/ref.jst
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
$it.schemaPath = '';
$it.errSchemaPath = $schema;
}}
{{ var $code = it.validate($it).replace(/validate\.schema/g, $refVal.code); }}
{{ var $code = it.validateCode($it).replace(/validate\.schema/g, $refVal.code); }}
{{= $code }}
{{? $breakOnError}}
if ({{=$nextValid}}) {
Expand Down
1 change: 0 additions & 1 deletion lib/dotjs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
//all requires must be explicit because browserify won't work with dynamic requires
module.exports = {
$ref: require("./ref"),
allOf: require("./allOf"),
anyOf: require("./anyOf"),
contains: require("./contains"),
dependencies: require("./dependencies"),
Expand Down
Loading

0 comments on commit db7574d

Please sign in to comment.