Updated the files.
This commit is contained in:
parent
1553e6b971
commit
753967d4f5
23418 changed files with 3784666 additions and 0 deletions
56
my-app/node_modules/ajv/lib/vocabularies/applicator/additionalItems.ts
generated
vendored
Executable file
56
my-app/node_modules/ajv/lib/vocabularies/applicator/additionalItems.ts
generated
vendored
Executable file
|
@ -0,0 +1,56 @@
|
|||
import type {
|
||||
CodeKeywordDefinition,
|
||||
ErrorObject,
|
||||
KeywordErrorDefinition,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, not, Name} from "../../compile/codegen"
|
||||
import {alwaysValidSchema, checkStrictMode, Type} from "../../compile/util"
|
||||
|
||||
export type AdditionalItemsError = ErrorObject<"additionalItems", {limit: number}, AnySchema>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({params: {len}}) => str`must NOT have more than ${len} items`,
|
||||
params: ({params: {len}}) => _`{limit: ${len}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "additionalItems" as const,
|
||||
type: "array",
|
||||
schemaType: ["boolean", "object"],
|
||||
before: "uniqueItems",
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {parentSchema, it} = cxt
|
||||
const {items} = parentSchema
|
||||
if (!Array.isArray(items)) {
|
||||
checkStrictMode(it, '"additionalItems" is ignored when "items" is not an array of schemas')
|
||||
return
|
||||
}
|
||||
validateAdditionalItems(cxt, items)
|
||||
},
|
||||
}
|
||||
|
||||
export function validateAdditionalItems(cxt: KeywordCxt, items: AnySchema[]): void {
|
||||
const {gen, schema, data, keyword, it} = cxt
|
||||
it.items = true
|
||||
const len = gen.const("len", _`${data}.length`)
|
||||
if (schema === false) {
|
||||
cxt.setParams({len: items.length})
|
||||
cxt.pass(_`${len} <= ${items.length}`)
|
||||
} else if (typeof schema == "object" && !alwaysValidSchema(it, schema)) {
|
||||
const valid = gen.var("valid", _`${len} <= ${items.length}`) // TODO var
|
||||
gen.if(not(valid), () => validateItems(valid))
|
||||
cxt.ok(valid)
|
||||
}
|
||||
|
||||
function validateItems(valid: Name): void {
|
||||
gen.forRange("i", items.length, len, (i) => {
|
||||
cxt.subschema({keyword, dataProp: i, dataPropType: Type.Num}, valid)
|
||||
if (!it.allErrors) gen.if(not(valid), () => gen.break())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default def
|
118
my-app/node_modules/ajv/lib/vocabularies/applicator/additionalProperties.ts
generated
vendored
Executable file
118
my-app/node_modules/ajv/lib/vocabularies/applicator/additionalProperties.ts
generated
vendored
Executable file
|
@ -0,0 +1,118 @@
|
|||
import type {
|
||||
CodeKeywordDefinition,
|
||||
AddedKeywordDefinition,
|
||||
ErrorObject,
|
||||
KeywordErrorDefinition,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import {allSchemaProperties, usePattern, isOwnProperty} from "../code"
|
||||
import {_, nil, or, not, Code, Name} from "../../compile/codegen"
|
||||
import N from "../../compile/names"
|
||||
import type {SubschemaArgs} from "../../compile/validate/subschema"
|
||||
import {alwaysValidSchema, schemaRefOrVal, Type} from "../../compile/util"
|
||||
|
||||
export type AdditionalPropertiesError = ErrorObject<
|
||||
"additionalProperties",
|
||||
{additionalProperty: string},
|
||||
AnySchema
|
||||
>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: "must NOT have additional properties",
|
||||
params: ({params}) => _`{additionalProperty: ${params.additionalProperty}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition & AddedKeywordDefinition = {
|
||||
keyword: "additionalProperties",
|
||||
type: ["object"],
|
||||
schemaType: ["boolean", "object"],
|
||||
allowUndefined: true,
|
||||
trackErrors: true,
|
||||
error,
|
||||
code(cxt) {
|
||||
const {gen, schema, parentSchema, data, errsCount, it} = cxt
|
||||
/* istanbul ignore if */
|
||||
if (!errsCount) throw new Error("ajv implementation error")
|
||||
const {allErrors, opts} = it
|
||||
it.props = true
|
||||
if (opts.removeAdditional !== "all" && alwaysValidSchema(it, schema)) return
|
||||
const props = allSchemaProperties(parentSchema.properties)
|
||||
const patProps = allSchemaProperties(parentSchema.patternProperties)
|
||||
checkAdditionalProperties()
|
||||
cxt.ok(_`${errsCount} === ${N.errors}`)
|
||||
|
||||
function checkAdditionalProperties(): void {
|
||||
gen.forIn("key", data, (key: Name) => {
|
||||
if (!props.length && !patProps.length) additionalPropertyCode(key)
|
||||
else gen.if(isAdditional(key), () => additionalPropertyCode(key))
|
||||
})
|
||||
}
|
||||
|
||||
function isAdditional(key: Name): Code {
|
||||
let definedProp: Code
|
||||
if (props.length > 8) {
|
||||
// TODO maybe an option instead of hard-coded 8?
|
||||
const propsSchema = schemaRefOrVal(it, parentSchema.properties, "properties")
|
||||
definedProp = isOwnProperty(gen, propsSchema as Code, key)
|
||||
} else if (props.length) {
|
||||
definedProp = or(...props.map((p) => _`${key} === ${p}`))
|
||||
} else {
|
||||
definedProp = nil
|
||||
}
|
||||
if (patProps.length) {
|
||||
definedProp = or(definedProp, ...patProps.map((p) => _`${usePattern(cxt, p)}.test(${key})`))
|
||||
}
|
||||
return not(definedProp)
|
||||
}
|
||||
|
||||
function deleteAdditional(key: Name): void {
|
||||
gen.code(_`delete ${data}[${key}]`)
|
||||
}
|
||||
|
||||
function additionalPropertyCode(key: Name): void {
|
||||
if (opts.removeAdditional === "all" || (opts.removeAdditional && schema === false)) {
|
||||
deleteAdditional(key)
|
||||
return
|
||||
}
|
||||
|
||||
if (schema === false) {
|
||||
cxt.setParams({additionalProperty: key})
|
||||
cxt.error()
|
||||
if (!allErrors) gen.break()
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof schema == "object" && !alwaysValidSchema(it, schema)) {
|
||||
const valid = gen.name("valid")
|
||||
if (opts.removeAdditional === "failing") {
|
||||
applyAdditionalSchema(key, valid, false)
|
||||
gen.if(not(valid), () => {
|
||||
cxt.reset()
|
||||
deleteAdditional(key)
|
||||
})
|
||||
} else {
|
||||
applyAdditionalSchema(key, valid)
|
||||
if (!allErrors) gen.if(not(valid), () => gen.break())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function applyAdditionalSchema(key: Name, valid: Name, errors?: false): void {
|
||||
const subschema: SubschemaArgs = {
|
||||
keyword: "additionalProperties",
|
||||
dataProp: key,
|
||||
dataPropType: Type.Str,
|
||||
}
|
||||
if (errors === false) {
|
||||
Object.assign(subschema, {
|
||||
compositeRule: true,
|
||||
createErrors: false,
|
||||
allErrors: false,
|
||||
})
|
||||
}
|
||||
cxt.subschema(subschema, valid)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
22
my-app/node_modules/ajv/lib/vocabularies/applicator/allOf.ts
generated
vendored
Executable file
22
my-app/node_modules/ajv/lib/vocabularies/applicator/allOf.ts
generated
vendored
Executable file
|
@ -0,0 +1,22 @@
|
|||
import type {CodeKeywordDefinition, AnySchema} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {alwaysValidSchema} from "../../compile/util"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "allOf",
|
||||
schemaType: "array",
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, schema, it} = cxt
|
||||
/* istanbul ignore if */
|
||||
if (!Array.isArray(schema)) throw new Error("ajv implementation error")
|
||||
const valid = gen.name("valid")
|
||||
schema.forEach((sch: AnySchema, i: number) => {
|
||||
if (alwaysValidSchema(it, sch)) return
|
||||
const schCxt = cxt.subschema({keyword: "allOf", schemaProp: i}, valid)
|
||||
cxt.ok(valid)
|
||||
cxt.mergeEvaluated(schCxt)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
14
my-app/node_modules/ajv/lib/vocabularies/applicator/anyOf.ts
generated
vendored
Executable file
14
my-app/node_modules/ajv/lib/vocabularies/applicator/anyOf.ts
generated
vendored
Executable file
|
@ -0,0 +1,14 @@
|
|||
import type {CodeKeywordDefinition, ErrorNoParams, AnySchema} from "../../types"
|
||||
import {validateUnion} from "../code"
|
||||
|
||||
export type AnyOfError = ErrorNoParams<"anyOf", AnySchema[]>
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "anyOf",
|
||||
schemaType: "array",
|
||||
trackErrors: true,
|
||||
code: validateUnion,
|
||||
error: {message: "must match a schema in anyOf"},
|
||||
}
|
||||
|
||||
export default def
|
109
my-app/node_modules/ajv/lib/vocabularies/applicator/contains.ts
generated
vendored
Executable file
109
my-app/node_modules/ajv/lib/vocabularies/applicator/contains.ts
generated
vendored
Executable file
|
@ -0,0 +1,109 @@
|
|||
import type {
|
||||
CodeKeywordDefinition,
|
||||
KeywordErrorDefinition,
|
||||
ErrorObject,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, Name} from "../../compile/codegen"
|
||||
import {alwaysValidSchema, checkStrictMode, Type} from "../../compile/util"
|
||||
|
||||
export type ContainsError = ErrorObject<
|
||||
"contains",
|
||||
{minContains: number; maxContains?: number},
|
||||
AnySchema
|
||||
>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({params: {min, max}}) =>
|
||||
max === undefined
|
||||
? str`must contain at least ${min} valid item(s)`
|
||||
: str`must contain at least ${min} and no more than ${max} valid item(s)`,
|
||||
params: ({params: {min, max}}) =>
|
||||
max === undefined ? _`{minContains: ${min}}` : _`{minContains: ${min}, maxContains: ${max}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "contains",
|
||||
type: "array",
|
||||
schemaType: ["object", "boolean"],
|
||||
before: "uniqueItems",
|
||||
trackErrors: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, schema, parentSchema, data, it} = cxt
|
||||
let min: number
|
||||
let max: number | undefined
|
||||
const {minContains, maxContains} = parentSchema
|
||||
if (it.opts.next) {
|
||||
min = minContains === undefined ? 1 : minContains
|
||||
max = maxContains
|
||||
} else {
|
||||
min = 1
|
||||
}
|
||||
const len = gen.const("len", _`${data}.length`)
|
||||
cxt.setParams({min, max})
|
||||
if (max === undefined && min === 0) {
|
||||
checkStrictMode(it, `"minContains" == 0 without "maxContains": "contains" keyword ignored`)
|
||||
return
|
||||
}
|
||||
if (max !== undefined && min > max) {
|
||||
checkStrictMode(it, `"minContains" > "maxContains" is always invalid`)
|
||||
cxt.fail()
|
||||
return
|
||||
}
|
||||
if (alwaysValidSchema(it, schema)) {
|
||||
let cond = _`${len} >= ${min}`
|
||||
if (max !== undefined) cond = _`${cond} && ${len} <= ${max}`
|
||||
cxt.pass(cond)
|
||||
return
|
||||
}
|
||||
|
||||
it.items = true
|
||||
const valid = gen.name("valid")
|
||||
if (max === undefined && min === 1) {
|
||||
validateItems(valid, () => gen.if(valid, () => gen.break()))
|
||||
} else if (min === 0) {
|
||||
gen.let(valid, true)
|
||||
if (max !== undefined) gen.if(_`${data}.length > 0`, validateItemsWithCount)
|
||||
} else {
|
||||
gen.let(valid, false)
|
||||
validateItemsWithCount()
|
||||
}
|
||||
cxt.result(valid, () => cxt.reset())
|
||||
|
||||
function validateItemsWithCount(): void {
|
||||
const schValid = gen.name("_valid")
|
||||
const count = gen.let("count", 0)
|
||||
validateItems(schValid, () => gen.if(schValid, () => checkLimits(count)))
|
||||
}
|
||||
|
||||
function validateItems(_valid: Name, block: () => void): void {
|
||||
gen.forRange("i", 0, len, (i) => {
|
||||
cxt.subschema(
|
||||
{
|
||||
keyword: "contains",
|
||||
dataProp: i,
|
||||
dataPropType: Type.Num,
|
||||
compositeRule: true,
|
||||
},
|
||||
_valid
|
||||
)
|
||||
block()
|
||||
})
|
||||
}
|
||||
|
||||
function checkLimits(count: Name): void {
|
||||
gen.code(_`${count}++`)
|
||||
if (max === undefined) {
|
||||
gen.if(_`${count} >= ${min}`, () => gen.assign(valid, true).break())
|
||||
} else {
|
||||
gen.if(_`${count} > ${max}`, () => gen.assign(valid, false).break())
|
||||
if (min === 1) gen.assign(valid, true)
|
||||
else gen.if(_`${count} >= ${min}`, () => gen.assign(valid, true))
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
112
my-app/node_modules/ajv/lib/vocabularies/applicator/dependencies.ts
generated
vendored
Executable file
112
my-app/node_modules/ajv/lib/vocabularies/applicator/dependencies.ts
generated
vendored
Executable file
|
@ -0,0 +1,112 @@
|
|||
import type {
|
||||
CodeKeywordDefinition,
|
||||
ErrorObject,
|
||||
KeywordErrorDefinition,
|
||||
SchemaMap,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str} from "../../compile/codegen"
|
||||
import {alwaysValidSchema} from "../../compile/util"
|
||||
import {checkReportMissingProp, checkMissingProp, reportMissingProp, propertyInData} from "../code"
|
||||
|
||||
export type PropertyDependencies = {[K in string]?: string[]}
|
||||
|
||||
export interface DependenciesErrorParams {
|
||||
property: string
|
||||
missingProperty: string
|
||||
depsCount: number
|
||||
deps: string // TODO change to string[]
|
||||
}
|
||||
|
||||
type SchemaDependencies = SchemaMap
|
||||
|
||||
export type DependenciesError = ErrorObject<
|
||||
"dependencies",
|
||||
DependenciesErrorParams,
|
||||
{[K in string]?: string[] | AnySchema}
|
||||
>
|
||||
|
||||
export const error: KeywordErrorDefinition = {
|
||||
message: ({params: {property, depsCount, deps}}) => {
|
||||
const property_ies = depsCount === 1 ? "property" : "properties"
|
||||
return str`must have ${property_ies} ${deps} when property ${property} is present`
|
||||
},
|
||||
params: ({params: {property, depsCount, deps, missingProperty}}) =>
|
||||
_`{property: ${property},
|
||||
missingProperty: ${missingProperty},
|
||||
depsCount: ${depsCount},
|
||||
deps: ${deps}}`, // TODO change to reference
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "dependencies",
|
||||
type: "object",
|
||||
schemaType: "object",
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const [propDeps, schDeps] = splitDependencies(cxt)
|
||||
validatePropertyDeps(cxt, propDeps)
|
||||
validateSchemaDeps(cxt, schDeps)
|
||||
},
|
||||
}
|
||||
|
||||
function splitDependencies({schema}: KeywordCxt): [PropertyDependencies, SchemaDependencies] {
|
||||
const propertyDeps: PropertyDependencies = {}
|
||||
const schemaDeps: SchemaDependencies = {}
|
||||
for (const key in schema) {
|
||||
if (key === "__proto__") continue
|
||||
const deps = Array.isArray(schema[key]) ? propertyDeps : schemaDeps
|
||||
deps[key] = schema[key]
|
||||
}
|
||||
return [propertyDeps, schemaDeps]
|
||||
}
|
||||
|
||||
export function validatePropertyDeps(
|
||||
cxt: KeywordCxt,
|
||||
propertyDeps: {[K in string]?: string[]} = cxt.schema
|
||||
): void {
|
||||
const {gen, data, it} = cxt
|
||||
if (Object.keys(propertyDeps).length === 0) return
|
||||
const missing = gen.let("missing")
|
||||
for (const prop in propertyDeps) {
|
||||
const deps = propertyDeps[prop] as string[]
|
||||
if (deps.length === 0) continue
|
||||
const hasProperty = propertyInData(gen, data, prop, it.opts.ownProperties)
|
||||
cxt.setParams({
|
||||
property: prop,
|
||||
depsCount: deps.length,
|
||||
deps: deps.join(", "),
|
||||
})
|
||||
if (it.allErrors) {
|
||||
gen.if(hasProperty, () => {
|
||||
for (const depProp of deps) {
|
||||
checkReportMissingProp(cxt, depProp)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
gen.if(_`${hasProperty} && (${checkMissingProp(cxt, deps, missing)})`)
|
||||
reportMissingProp(cxt, missing)
|
||||
gen.else()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function validateSchemaDeps(cxt: KeywordCxt, schemaDeps: SchemaMap = cxt.schema): void {
|
||||
const {gen, data, keyword, it} = cxt
|
||||
const valid = gen.name("valid")
|
||||
for (const prop in schemaDeps) {
|
||||
if (alwaysValidSchema(it, schemaDeps[prop] as AnySchema)) continue
|
||||
gen.if(
|
||||
propertyInData(gen, data, prop, it.opts.ownProperties),
|
||||
() => {
|
||||
const schCxt = cxt.subschema({keyword, schemaProp: prop}, valid)
|
||||
cxt.mergeValidEvaluated(schCxt, valid)
|
||||
},
|
||||
() => gen.var(valid, true) // TODO var
|
||||
)
|
||||
cxt.ok(valid)
|
||||
}
|
||||
}
|
||||
|
||||
export default def
|
11
my-app/node_modules/ajv/lib/vocabularies/applicator/dependentSchemas.ts
generated
vendored
Executable file
11
my-app/node_modules/ajv/lib/vocabularies/applicator/dependentSchemas.ts
generated
vendored
Executable file
|
@ -0,0 +1,11 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import {validateSchemaDeps} from "./dependencies"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "dependentSchemas",
|
||||
type: "object",
|
||||
schemaType: "object",
|
||||
code: (cxt) => validateSchemaDeps(cxt),
|
||||
}
|
||||
|
||||
export default def
|
80
my-app/node_modules/ajv/lib/vocabularies/applicator/if.ts
generated
vendored
Executable file
80
my-app/node_modules/ajv/lib/vocabularies/applicator/if.ts
generated
vendored
Executable file
|
@ -0,0 +1,80 @@
|
|||
import type {
|
||||
CodeKeywordDefinition,
|
||||
ErrorObject,
|
||||
KeywordErrorDefinition,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import type {SchemaObjCxt} from "../../compile"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, not, Name} from "../../compile/codegen"
|
||||
import {alwaysValidSchema, checkStrictMode} from "../../compile/util"
|
||||
|
||||
export type IfKeywordError = ErrorObject<"if", {failingKeyword: string}, AnySchema>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({params}) => str`must match "${params.ifClause}" schema`,
|
||||
params: ({params}) => _`{failingKeyword: ${params.ifClause}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "if",
|
||||
schemaType: ["object", "boolean"],
|
||||
trackErrors: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, parentSchema, it} = cxt
|
||||
if (parentSchema.then === undefined && parentSchema.else === undefined) {
|
||||
checkStrictMode(it, '"if" without "then" and "else" is ignored')
|
||||
}
|
||||
const hasThen = hasSchema(it, "then")
|
||||
const hasElse = hasSchema(it, "else")
|
||||
if (!hasThen && !hasElse) return
|
||||
|
||||
const valid = gen.let("valid", true)
|
||||
const schValid = gen.name("_valid")
|
||||
validateIf()
|
||||
cxt.reset()
|
||||
|
||||
if (hasThen && hasElse) {
|
||||
const ifClause = gen.let("ifClause")
|
||||
cxt.setParams({ifClause})
|
||||
gen.if(schValid, validateClause("then", ifClause), validateClause("else", ifClause))
|
||||
} else if (hasThen) {
|
||||
gen.if(schValid, validateClause("then"))
|
||||
} else {
|
||||
gen.if(not(schValid), validateClause("else"))
|
||||
}
|
||||
|
||||
cxt.pass(valid, () => cxt.error(true))
|
||||
|
||||
function validateIf(): void {
|
||||
const schCxt = cxt.subschema(
|
||||
{
|
||||
keyword: "if",
|
||||
compositeRule: true,
|
||||
createErrors: false,
|
||||
allErrors: false,
|
||||
},
|
||||
schValid
|
||||
)
|
||||
cxt.mergeEvaluated(schCxt)
|
||||
}
|
||||
|
||||
function validateClause(keyword: string, ifClause?: Name): () => void {
|
||||
return () => {
|
||||
const schCxt = cxt.subschema({keyword}, schValid)
|
||||
gen.assign(valid, schValid)
|
||||
cxt.mergeValidEvaluated(schCxt, valid)
|
||||
if (ifClause) gen.assign(ifClause, _`${keyword}`)
|
||||
else cxt.setParams({ifClause: keyword})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
function hasSchema(it: SchemaObjCxt, keyword: string): boolean {
|
||||
const schema = it.schema[keyword]
|
||||
return schema !== undefined && !alwaysValidSchema(it, schema)
|
||||
}
|
||||
|
||||
export default def
|
53
my-app/node_modules/ajv/lib/vocabularies/applicator/index.ts
generated
vendored
Executable file
53
my-app/node_modules/ajv/lib/vocabularies/applicator/index.ts
generated
vendored
Executable file
|
@ -0,0 +1,53 @@
|
|||
import type {ErrorNoParams, Vocabulary} from "../../types"
|
||||
import additionalItems, {AdditionalItemsError} from "./additionalItems"
|
||||
import prefixItems from "./prefixItems"
|
||||
import items from "./items"
|
||||
import items2020, {ItemsError} from "./items2020"
|
||||
import contains, {ContainsError} from "./contains"
|
||||
import dependencies, {DependenciesError} from "./dependencies"
|
||||
import propertyNames, {PropertyNamesError} from "./propertyNames"
|
||||
import additionalProperties, {AdditionalPropertiesError} from "./additionalProperties"
|
||||
import properties from "./properties"
|
||||
import patternProperties from "./patternProperties"
|
||||
import notKeyword, {NotKeywordError} from "./not"
|
||||
import anyOf, {AnyOfError} from "./anyOf"
|
||||
import oneOf, {OneOfError} from "./oneOf"
|
||||
import allOf from "./allOf"
|
||||
import ifKeyword, {IfKeywordError} from "./if"
|
||||
import thenElse from "./thenElse"
|
||||
|
||||
export default function getApplicator(draft2020 = false): Vocabulary {
|
||||
const applicator = [
|
||||
// any
|
||||
notKeyword,
|
||||
anyOf,
|
||||
oneOf,
|
||||
allOf,
|
||||
ifKeyword,
|
||||
thenElse,
|
||||
// object
|
||||
propertyNames,
|
||||
additionalProperties,
|
||||
dependencies,
|
||||
properties,
|
||||
patternProperties,
|
||||
]
|
||||
// array
|
||||
if (draft2020) applicator.push(prefixItems, items2020)
|
||||
else applicator.push(additionalItems, items)
|
||||
applicator.push(contains)
|
||||
return applicator
|
||||
}
|
||||
|
||||
export type ApplicatorKeywordError =
|
||||
| ErrorNoParams<"false schema">
|
||||
| AdditionalItemsError
|
||||
| ItemsError
|
||||
| ContainsError
|
||||
| AdditionalPropertiesError
|
||||
| DependenciesError
|
||||
| IfKeywordError
|
||||
| AnyOfError
|
||||
| OneOfError
|
||||
| NotKeywordError
|
||||
| PropertyNamesError
|
59
my-app/node_modules/ajv/lib/vocabularies/applicator/items.ts
generated
vendored
Executable file
59
my-app/node_modules/ajv/lib/vocabularies/applicator/items.ts
generated
vendored
Executable file
|
@ -0,0 +1,59 @@
|
|||
import type {CodeKeywordDefinition, AnySchema, AnySchemaObject} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_} from "../../compile/codegen"
|
||||
import {alwaysValidSchema, mergeEvaluated, checkStrictMode} from "../../compile/util"
|
||||
import {validateArray} from "../code"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "items",
|
||||
type: "array",
|
||||
schemaType: ["object", "array", "boolean"],
|
||||
before: "uniqueItems",
|
||||
code(cxt: KeywordCxt) {
|
||||
const {schema, it} = cxt
|
||||
if (Array.isArray(schema)) return validateTuple(cxt, "additionalItems", schema)
|
||||
it.items = true
|
||||
if (alwaysValidSchema(it, schema)) return
|
||||
cxt.ok(validateArray(cxt))
|
||||
},
|
||||
}
|
||||
|
||||
export function validateTuple(
|
||||
cxt: KeywordCxt,
|
||||
extraItems: string,
|
||||
schArr: AnySchema[] = cxt.schema
|
||||
): void {
|
||||
const {gen, parentSchema, data, keyword, it} = cxt
|
||||
checkStrictTuple(parentSchema)
|
||||
if (it.opts.unevaluated && schArr.length && it.items !== true) {
|
||||
it.items = mergeEvaluated.items(gen, schArr.length, it.items)
|
||||
}
|
||||
const valid = gen.name("valid")
|
||||
const len = gen.const("len", _`${data}.length`)
|
||||
schArr.forEach((sch: AnySchema, i: number) => {
|
||||
if (alwaysValidSchema(it, sch)) return
|
||||
gen.if(_`${len} > ${i}`, () =>
|
||||
cxt.subschema(
|
||||
{
|
||||
keyword,
|
||||
schemaProp: i,
|
||||
dataProp: i,
|
||||
},
|
||||
valid
|
||||
)
|
||||
)
|
||||
cxt.ok(valid)
|
||||
})
|
||||
|
||||
function checkStrictTuple(sch: AnySchemaObject): void {
|
||||
const {opts, errSchemaPath} = it
|
||||
const l = schArr.length
|
||||
const fullTuple = l === sch.minItems && (l === sch.maxItems || sch[extraItems] === false)
|
||||
if (opts.strictTuples && !fullTuple) {
|
||||
const msg = `"${keyword}" is ${l}-tuple, but minItems or maxItems/${extraItems} are not specified or different at path "${errSchemaPath}"`
|
||||
checkStrictMode(it, msg, opts.strictTuples)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default def
|
36
my-app/node_modules/ajv/lib/vocabularies/applicator/items2020.ts
generated
vendored
Executable file
36
my-app/node_modules/ajv/lib/vocabularies/applicator/items2020.ts
generated
vendored
Executable file
|
@ -0,0 +1,36 @@
|
|||
import type {
|
||||
CodeKeywordDefinition,
|
||||
KeywordErrorDefinition,
|
||||
ErrorObject,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str} from "../../compile/codegen"
|
||||
import {alwaysValidSchema} from "../../compile/util"
|
||||
import {validateArray} from "../code"
|
||||
import {validateAdditionalItems} from "./additionalItems"
|
||||
|
||||
export type ItemsError = ErrorObject<"items", {limit: number}, AnySchema>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({params: {len}}) => str`must NOT have more than ${len} items`,
|
||||
params: ({params: {len}}) => _`{limit: ${len}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "items",
|
||||
type: "array",
|
||||
schemaType: ["object", "boolean"],
|
||||
before: "uniqueItems",
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {schema, parentSchema, it} = cxt
|
||||
const {prefixItems} = parentSchema
|
||||
it.items = true
|
||||
if (alwaysValidSchema(it, schema)) return
|
||||
if (prefixItems) validateAdditionalItems(cxt, prefixItems)
|
||||
else cxt.ok(validateArray(cxt))
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
38
my-app/node_modules/ajv/lib/vocabularies/applicator/not.ts
generated
vendored
Executable file
38
my-app/node_modules/ajv/lib/vocabularies/applicator/not.ts
generated
vendored
Executable file
|
@ -0,0 +1,38 @@
|
|||
import type {CodeKeywordDefinition, ErrorNoParams, AnySchema} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {alwaysValidSchema} from "../../compile/util"
|
||||
|
||||
export type NotKeywordError = ErrorNoParams<"not", AnySchema>
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "not",
|
||||
schemaType: ["object", "boolean"],
|
||||
trackErrors: true,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, schema, it} = cxt
|
||||
if (alwaysValidSchema(it, schema)) {
|
||||
cxt.fail()
|
||||
return
|
||||
}
|
||||
|
||||
const valid = gen.name("valid")
|
||||
cxt.subschema(
|
||||
{
|
||||
keyword: "not",
|
||||
compositeRule: true,
|
||||
createErrors: false,
|
||||
allErrors: false,
|
||||
},
|
||||
valid
|
||||
)
|
||||
|
||||
cxt.failResult(
|
||||
valid,
|
||||
() => cxt.reset(),
|
||||
() => cxt.error()
|
||||
)
|
||||
},
|
||||
error: {message: "must NOT be valid"},
|
||||
}
|
||||
|
||||
export default def
|
82
my-app/node_modules/ajv/lib/vocabularies/applicator/oneOf.ts
generated
vendored
Executable file
82
my-app/node_modules/ajv/lib/vocabularies/applicator/oneOf.ts
generated
vendored
Executable file
|
@ -0,0 +1,82 @@
|
|||
import type {
|
||||
CodeKeywordDefinition,
|
||||
ErrorObject,
|
||||
KeywordErrorDefinition,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, Name} from "../../compile/codegen"
|
||||
import {alwaysValidSchema} from "../../compile/util"
|
||||
import {SchemaCxt} from "../../compile"
|
||||
|
||||
export type OneOfError = ErrorObject<
|
||||
"oneOf",
|
||||
{passingSchemas: [number, number] | null},
|
||||
AnySchema[]
|
||||
>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: "must match exactly one schema in oneOf",
|
||||
params: ({params}) => _`{passingSchemas: ${params.passing}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "oneOf",
|
||||
schemaType: "array",
|
||||
trackErrors: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, schema, parentSchema, it} = cxt
|
||||
/* istanbul ignore if */
|
||||
if (!Array.isArray(schema)) throw new Error("ajv implementation error")
|
||||
if (it.opts.discriminator && parentSchema.discriminator) return
|
||||
const schArr: AnySchema[] = schema
|
||||
const valid = gen.let("valid", false)
|
||||
const passing = gen.let("passing", null)
|
||||
const schValid = gen.name("_valid")
|
||||
cxt.setParams({passing})
|
||||
// TODO possibly fail straight away (with warning or exception) if there are two empty always valid schemas
|
||||
|
||||
gen.block(validateOneOf)
|
||||
|
||||
cxt.result(
|
||||
valid,
|
||||
() => cxt.reset(),
|
||||
() => cxt.error(true)
|
||||
)
|
||||
|
||||
function validateOneOf(): void {
|
||||
schArr.forEach((sch: AnySchema, i: number) => {
|
||||
let schCxt: SchemaCxt | undefined
|
||||
if (alwaysValidSchema(it, sch)) {
|
||||
gen.var(schValid, true)
|
||||
} else {
|
||||
schCxt = cxt.subschema(
|
||||
{
|
||||
keyword: "oneOf",
|
||||
schemaProp: i,
|
||||
compositeRule: true,
|
||||
},
|
||||
schValid
|
||||
)
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
gen
|
||||
.if(_`${schValid} && ${valid}`)
|
||||
.assign(valid, false)
|
||||
.assign(passing, _`[${passing}, ${i}]`)
|
||||
.else()
|
||||
}
|
||||
|
||||
gen.if(schValid, () => {
|
||||
gen.assign(valid, true)
|
||||
gen.assign(passing, i)
|
||||
if (schCxt) cxt.mergeEvaluated(schCxt, Name)
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
91
my-app/node_modules/ajv/lib/vocabularies/applicator/patternProperties.ts
generated
vendored
Executable file
91
my-app/node_modules/ajv/lib/vocabularies/applicator/patternProperties.ts
generated
vendored
Executable file
|
@ -0,0 +1,91 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {allSchemaProperties, usePattern} from "../code"
|
||||
import {_, not, Name} from "../../compile/codegen"
|
||||
import {alwaysValidSchema, checkStrictMode} from "../../compile/util"
|
||||
import {evaluatedPropsToName, Type} from "../../compile/util"
|
||||
import {AnySchema} from "../../types"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "patternProperties",
|
||||
type: "object",
|
||||
schemaType: "object",
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, schema, data, parentSchema, it} = cxt
|
||||
const {opts} = it
|
||||
const patterns = allSchemaProperties(schema)
|
||||
const alwaysValidPatterns = patterns.filter((p) =>
|
||||
alwaysValidSchema(it, schema[p] as AnySchema)
|
||||
)
|
||||
|
||||
if (
|
||||
patterns.length === 0 ||
|
||||
(alwaysValidPatterns.length === patterns.length &&
|
||||
(!it.opts.unevaluated || it.props === true))
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const checkProperties =
|
||||
opts.strictSchema && !opts.allowMatchingProperties && parentSchema.properties
|
||||
const valid = gen.name("valid")
|
||||
if (it.props !== true && !(it.props instanceof Name)) {
|
||||
it.props = evaluatedPropsToName(gen, it.props)
|
||||
}
|
||||
const {props} = it
|
||||
validatePatternProperties()
|
||||
|
||||
function validatePatternProperties(): void {
|
||||
for (const pat of patterns) {
|
||||
if (checkProperties) checkMatchingProperties(pat)
|
||||
if (it.allErrors) {
|
||||
validateProperties(pat)
|
||||
} else {
|
||||
gen.var(valid, true) // TODO var
|
||||
validateProperties(pat)
|
||||
gen.if(valid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkMatchingProperties(pat: string): void {
|
||||
for (const prop in checkProperties) {
|
||||
if (new RegExp(pat).test(prop)) {
|
||||
checkStrictMode(
|
||||
it,
|
||||
`property ${prop} matches pattern ${pat} (use allowMatchingProperties)`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function validateProperties(pat: string): void {
|
||||
gen.forIn("key", data, (key) => {
|
||||
gen.if(_`${usePattern(cxt, pat)}.test(${key})`, () => {
|
||||
const alwaysValid = alwaysValidPatterns.includes(pat)
|
||||
if (!alwaysValid) {
|
||||
cxt.subschema(
|
||||
{
|
||||
keyword: "patternProperties",
|
||||
schemaProp: pat,
|
||||
dataProp: key,
|
||||
dataPropType: Type.Str,
|
||||
},
|
||||
valid
|
||||
)
|
||||
}
|
||||
|
||||
if (it.opts.unevaluated && props !== true) {
|
||||
gen.assign(_`${props}[${key}]`, true)
|
||||
} else if (!alwaysValid && !it.allErrors) {
|
||||
// can short-circuit if `unevaluatedProperties` is not supported (opts.next === false)
|
||||
// or if all properties were evaluated (props === true)
|
||||
gen.if(not(valid), () => gen.break())
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
12
my-app/node_modules/ajv/lib/vocabularies/applicator/prefixItems.ts
generated
vendored
Executable file
12
my-app/node_modules/ajv/lib/vocabularies/applicator/prefixItems.ts
generated
vendored
Executable file
|
@ -0,0 +1,12 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import {validateTuple} from "./items"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "prefixItems",
|
||||
type: "array",
|
||||
schemaType: ["array"],
|
||||
before: "uniqueItems",
|
||||
code: (cxt) => validateTuple(cxt, "items"),
|
||||
}
|
||||
|
||||
export default def
|
57
my-app/node_modules/ajv/lib/vocabularies/applicator/properties.ts
generated
vendored
Executable file
57
my-app/node_modules/ajv/lib/vocabularies/applicator/properties.ts
generated
vendored
Executable file
|
@ -0,0 +1,57 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import {KeywordCxt} from "../../compile/validate"
|
||||
import {propertyInData, allSchemaProperties} from "../code"
|
||||
import {alwaysValidSchema, toHash, mergeEvaluated} from "../../compile/util"
|
||||
import apDef from "./additionalProperties"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "properties",
|
||||
type: "object",
|
||||
schemaType: "object",
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, schema, parentSchema, data, it} = cxt
|
||||
if (it.opts.removeAdditional === "all" && parentSchema.additionalProperties === undefined) {
|
||||
apDef.code(new KeywordCxt(it, apDef, "additionalProperties"))
|
||||
}
|
||||
const allProps = allSchemaProperties(schema)
|
||||
for (const prop of allProps) {
|
||||
it.definedProperties.add(prop)
|
||||
}
|
||||
if (it.opts.unevaluated && allProps.length && it.props !== true) {
|
||||
it.props = mergeEvaluated.props(gen, toHash(allProps), it.props)
|
||||
}
|
||||
const properties = allProps.filter((p) => !alwaysValidSchema(it, schema[p]))
|
||||
if (properties.length === 0) return
|
||||
const valid = gen.name("valid")
|
||||
|
||||
for (const prop of properties) {
|
||||
if (hasDefault(prop)) {
|
||||
applyPropertySchema(prop)
|
||||
} else {
|
||||
gen.if(propertyInData(gen, data, prop, it.opts.ownProperties))
|
||||
applyPropertySchema(prop)
|
||||
if (!it.allErrors) gen.else().var(valid, true)
|
||||
gen.endIf()
|
||||
}
|
||||
cxt.it.definedProperties.add(prop)
|
||||
cxt.ok(valid)
|
||||
}
|
||||
|
||||
function hasDefault(prop: string): boolean | undefined {
|
||||
return it.opts.useDefaults && !it.compositeRule && schema[prop].default !== undefined
|
||||
}
|
||||
|
||||
function applyPropertySchema(prop: string): void {
|
||||
cxt.subschema(
|
||||
{
|
||||
keyword: "properties",
|
||||
schemaProp: prop,
|
||||
dataProp: prop,
|
||||
},
|
||||
valid
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
50
my-app/node_modules/ajv/lib/vocabularies/applicator/propertyNames.ts
generated
vendored
Executable file
50
my-app/node_modules/ajv/lib/vocabularies/applicator/propertyNames.ts
generated
vendored
Executable file
|
@ -0,0 +1,50 @@
|
|||
import type {
|
||||
CodeKeywordDefinition,
|
||||
ErrorObject,
|
||||
KeywordErrorDefinition,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, not} from "../../compile/codegen"
|
||||
import {alwaysValidSchema} from "../../compile/util"
|
||||
|
||||
export type PropertyNamesError = ErrorObject<"propertyNames", {propertyName: string}, AnySchema>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: "property name must be valid",
|
||||
params: ({params}) => _`{propertyName: ${params.propertyName}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "propertyNames",
|
||||
type: "object",
|
||||
schemaType: ["object", "boolean"],
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, schema, data, it} = cxt
|
||||
if (alwaysValidSchema(it, schema)) return
|
||||
const valid = gen.name("valid")
|
||||
|
||||
gen.forIn("key", data, (key) => {
|
||||
cxt.setParams({propertyName: key})
|
||||
cxt.subschema(
|
||||
{
|
||||
keyword: "propertyNames",
|
||||
data: key,
|
||||
dataTypes: ["string"],
|
||||
propertyName: key,
|
||||
compositeRule: true,
|
||||
},
|
||||
valid
|
||||
)
|
||||
gen.if(not(valid), () => {
|
||||
cxt.error(true)
|
||||
if (!it.allErrors) gen.break()
|
||||
})
|
||||
})
|
||||
|
||||
cxt.ok(valid)
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
13
my-app/node_modules/ajv/lib/vocabularies/applicator/thenElse.ts
generated
vendored
Executable file
13
my-app/node_modules/ajv/lib/vocabularies/applicator/thenElse.ts
generated
vendored
Executable file
|
@ -0,0 +1,13 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {checkStrictMode} from "../../compile/util"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: ["then", "else"],
|
||||
schemaType: ["object", "boolean"],
|
||||
code({keyword, parentSchema, it}: KeywordCxt) {
|
||||
if (parentSchema.if === undefined) checkStrictMode(it, `"${keyword}" without "if" is ignored`)
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
168
my-app/node_modules/ajv/lib/vocabularies/code.ts
generated
vendored
Executable file
168
my-app/node_modules/ajv/lib/vocabularies/code.ts
generated
vendored
Executable file
|
@ -0,0 +1,168 @@
|
|||
import type {AnySchema, SchemaMap} from "../types"
|
||||
import type {SchemaCxt} from "../compile"
|
||||
import type {KeywordCxt} from "../compile/validate"
|
||||
import {CodeGen, _, and, or, not, nil, strConcat, getProperty, Code, Name} from "../compile/codegen"
|
||||
import {alwaysValidSchema, Type} from "../compile/util"
|
||||
import N from "../compile/names"
|
||||
import {useFunc} from "../compile/util"
|
||||
export function checkReportMissingProp(cxt: KeywordCxt, prop: string): void {
|
||||
const {gen, data, it} = cxt
|
||||
gen.if(noPropertyInData(gen, data, prop, it.opts.ownProperties), () => {
|
||||
cxt.setParams({missingProperty: _`${prop}`}, true)
|
||||
cxt.error()
|
||||
})
|
||||
}
|
||||
|
||||
export function checkMissingProp(
|
||||
{gen, data, it: {opts}}: KeywordCxt,
|
||||
properties: string[],
|
||||
missing: Name
|
||||
): Code {
|
||||
return or(
|
||||
...properties.map((prop) =>
|
||||
and(noPropertyInData(gen, data, prop, opts.ownProperties), _`${missing} = ${prop}`)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export function reportMissingProp(cxt: KeywordCxt, missing: Name): void {
|
||||
cxt.setParams({missingProperty: missing}, true)
|
||||
cxt.error()
|
||||
}
|
||||
|
||||
export function hasPropFunc(gen: CodeGen): Name {
|
||||
return gen.scopeValue("func", {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
ref: Object.prototype.hasOwnProperty,
|
||||
code: _`Object.prototype.hasOwnProperty`,
|
||||
})
|
||||
}
|
||||
|
||||
export function isOwnProperty(gen: CodeGen, data: Name, property: Name | string): Code {
|
||||
return _`${hasPropFunc(gen)}.call(${data}, ${property})`
|
||||
}
|
||||
|
||||
export function propertyInData(
|
||||
gen: CodeGen,
|
||||
data: Name,
|
||||
property: Name | string,
|
||||
ownProperties?: boolean
|
||||
): Code {
|
||||
const cond = _`${data}${getProperty(property)} !== undefined`
|
||||
return ownProperties ? _`${cond} && ${isOwnProperty(gen, data, property)}` : cond
|
||||
}
|
||||
|
||||
export function noPropertyInData(
|
||||
gen: CodeGen,
|
||||
data: Name,
|
||||
property: Name | string,
|
||||
ownProperties?: boolean
|
||||
): Code {
|
||||
const cond = _`${data}${getProperty(property)} === undefined`
|
||||
return ownProperties ? or(cond, not(isOwnProperty(gen, data, property))) : cond
|
||||
}
|
||||
|
||||
export function allSchemaProperties(schemaMap?: SchemaMap): string[] {
|
||||
return schemaMap ? Object.keys(schemaMap).filter((p) => p !== "__proto__") : []
|
||||
}
|
||||
|
||||
export function schemaProperties(it: SchemaCxt, schemaMap: SchemaMap): string[] {
|
||||
return allSchemaProperties(schemaMap).filter(
|
||||
(p) => !alwaysValidSchema(it, schemaMap[p] as AnySchema)
|
||||
)
|
||||
}
|
||||
|
||||
export function callValidateCode(
|
||||
{schemaCode, data, it: {gen, topSchemaRef, schemaPath, errorPath}, it}: KeywordCxt,
|
||||
func: Code,
|
||||
context: Code,
|
||||
passSchema?: boolean
|
||||
): Code {
|
||||
const dataAndSchema = passSchema ? _`${schemaCode}, ${data}, ${topSchemaRef}${schemaPath}` : data
|
||||
const valCxt: [Name, Code | number][] = [
|
||||
[N.instancePath, strConcat(N.instancePath, errorPath)],
|
||||
[N.parentData, it.parentData],
|
||||
[N.parentDataProperty, it.parentDataProperty],
|
||||
[N.rootData, N.rootData],
|
||||
]
|
||||
if (it.opts.dynamicRef) valCxt.push([N.dynamicAnchors, N.dynamicAnchors])
|
||||
const args = _`${dataAndSchema}, ${gen.object(...valCxt)}`
|
||||
return context !== nil ? _`${func}.call(${context}, ${args})` : _`${func}(${args})`
|
||||
}
|
||||
|
||||
const newRegExp = _`new RegExp`
|
||||
|
||||
export function usePattern({gen, it: {opts}}: KeywordCxt, pattern: string): Name {
|
||||
const u = opts.unicodeRegExp ? "u" : ""
|
||||
const {regExp} = opts.code
|
||||
const rx = regExp(pattern, u)
|
||||
|
||||
return gen.scopeValue("pattern", {
|
||||
key: rx.toString(),
|
||||
ref: rx,
|
||||
code: _`${regExp.code === "new RegExp" ? newRegExp : useFunc(gen, regExp)}(${pattern}, ${u})`,
|
||||
})
|
||||
}
|
||||
|
||||
export function validateArray(cxt: KeywordCxt): Name {
|
||||
const {gen, data, keyword, it} = cxt
|
||||
const valid = gen.name("valid")
|
||||
if (it.allErrors) {
|
||||
const validArr = gen.let("valid", true)
|
||||
validateItems(() => gen.assign(validArr, false))
|
||||
return validArr
|
||||
}
|
||||
gen.var(valid, true)
|
||||
validateItems(() => gen.break())
|
||||
return valid
|
||||
|
||||
function validateItems(notValid: () => void): void {
|
||||
const len = gen.const("len", _`${data}.length`)
|
||||
gen.forRange("i", 0, len, (i) => {
|
||||
cxt.subschema(
|
||||
{
|
||||
keyword,
|
||||
dataProp: i,
|
||||
dataPropType: Type.Num,
|
||||
},
|
||||
valid
|
||||
)
|
||||
gen.if(not(valid), notValid)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function validateUnion(cxt: KeywordCxt): void {
|
||||
const {gen, schema, keyword, it} = cxt
|
||||
/* istanbul ignore if */
|
||||
if (!Array.isArray(schema)) throw new Error("ajv implementation error")
|
||||
const alwaysValid = schema.some((sch: AnySchema) => alwaysValidSchema(it, sch))
|
||||
if (alwaysValid && !it.opts.unevaluated) return
|
||||
|
||||
const valid = gen.let("valid", false)
|
||||
const schValid = gen.name("_valid")
|
||||
|
||||
gen.block(() =>
|
||||
schema.forEach((_sch: AnySchema, i: number) => {
|
||||
const schCxt = cxt.subschema(
|
||||
{
|
||||
keyword,
|
||||
schemaProp: i,
|
||||
compositeRule: true,
|
||||
},
|
||||
schValid
|
||||
)
|
||||
gen.assign(valid, _`${valid} || ${schValid}`)
|
||||
const merged = cxt.mergeValidEvaluated(schCxt, schValid)
|
||||
// can short-circuit if `unevaluatedProperties/Items` not supported (opts.unevaluated !== true)
|
||||
// or if all properties and items were evaluated (it.props === true && it.items === true)
|
||||
if (!merged) gen.if(not(valid))
|
||||
})
|
||||
)
|
||||
|
||||
cxt.result(
|
||||
valid,
|
||||
() => cxt.reset(),
|
||||
() => cxt.error(true)
|
||||
)
|
||||
}
|
10
my-app/node_modules/ajv/lib/vocabularies/core/id.ts
generated
vendored
Executable file
10
my-app/node_modules/ajv/lib/vocabularies/core/id.ts
generated
vendored
Executable file
|
@ -0,0 +1,10 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "id",
|
||||
code() {
|
||||
throw new Error('NOT SUPPORTED: keyword "id", use "$id" for schema ID')
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
16
my-app/node_modules/ajv/lib/vocabularies/core/index.ts
generated
vendored
Executable file
16
my-app/node_modules/ajv/lib/vocabularies/core/index.ts
generated
vendored
Executable file
|
@ -0,0 +1,16 @@
|
|||
import type {Vocabulary} from "../../types"
|
||||
import idKeyword from "./id"
|
||||
import refKeyword from "./ref"
|
||||
|
||||
const core: Vocabulary = [
|
||||
"$schema",
|
||||
"$id",
|
||||
"$defs",
|
||||
"$vocabulary",
|
||||
{keyword: "$comment"},
|
||||
"definitions",
|
||||
idKeyword,
|
||||
refKeyword,
|
||||
]
|
||||
|
||||
export default core
|
129
my-app/node_modules/ajv/lib/vocabularies/core/ref.ts
generated
vendored
Executable file
129
my-app/node_modules/ajv/lib/vocabularies/core/ref.ts
generated
vendored
Executable file
|
@ -0,0 +1,129 @@
|
|||
import type {CodeKeywordDefinition, AnySchema} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import MissingRefError from "../../compile/ref_error"
|
||||
import {callValidateCode} from "../code"
|
||||
import {_, nil, stringify, Code, Name} from "../../compile/codegen"
|
||||
import N from "../../compile/names"
|
||||
import {SchemaEnv, resolveRef} from "../../compile"
|
||||
import {mergeEvaluated} from "../../compile/util"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "$ref",
|
||||
schemaType: "string",
|
||||
code(cxt: KeywordCxt): void {
|
||||
const {gen, schema: $ref, it} = cxt
|
||||
const {baseId, schemaEnv: env, validateName, opts, self} = it
|
||||
const {root} = env
|
||||
if (($ref === "#" || $ref === "#/") && baseId === root.baseId) return callRootRef()
|
||||
const schOrEnv = resolveRef.call(self, root, baseId, $ref)
|
||||
if (schOrEnv === undefined) throw new MissingRefError(it.opts.uriResolver, baseId, $ref)
|
||||
if (schOrEnv instanceof SchemaEnv) return callValidate(schOrEnv)
|
||||
return inlineRefSchema(schOrEnv)
|
||||
|
||||
function callRootRef(): void {
|
||||
if (env === root) return callRef(cxt, validateName, env, env.$async)
|
||||
const rootName = gen.scopeValue("root", {ref: root})
|
||||
return callRef(cxt, _`${rootName}.validate`, root, root.$async)
|
||||
}
|
||||
|
||||
function callValidate(sch: SchemaEnv): void {
|
||||
const v = getValidate(cxt, sch)
|
||||
callRef(cxt, v, sch, sch.$async)
|
||||
}
|
||||
|
||||
function inlineRefSchema(sch: AnySchema): void {
|
||||
const schName = gen.scopeValue(
|
||||
"schema",
|
||||
opts.code.source === true ? {ref: sch, code: stringify(sch)} : {ref: sch}
|
||||
)
|
||||
const valid = gen.name("valid")
|
||||
const schCxt = cxt.subschema(
|
||||
{
|
||||
schema: sch,
|
||||
dataTypes: [],
|
||||
schemaPath: nil,
|
||||
topSchemaRef: schName,
|
||||
errSchemaPath: $ref,
|
||||
},
|
||||
valid
|
||||
)
|
||||
cxt.mergeEvaluated(schCxt)
|
||||
cxt.ok(valid)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export function getValidate(cxt: KeywordCxt, sch: SchemaEnv): Code {
|
||||
const {gen} = cxt
|
||||
return sch.validate
|
||||
? gen.scopeValue("validate", {ref: sch.validate})
|
||||
: _`${gen.scopeValue("wrapper", {ref: sch})}.validate`
|
||||
}
|
||||
|
||||
export function callRef(cxt: KeywordCxt, v: Code, sch?: SchemaEnv, $async?: boolean): void {
|
||||
const {gen, it} = cxt
|
||||
const {allErrors, schemaEnv: env, opts} = it
|
||||
const passCxt = opts.passContext ? N.this : nil
|
||||
if ($async) callAsyncRef()
|
||||
else callSyncRef()
|
||||
|
||||
function callAsyncRef(): void {
|
||||
if (!env.$async) throw new Error("async schema referenced by sync schema")
|
||||
const valid = gen.let("valid")
|
||||
gen.try(
|
||||
() => {
|
||||
gen.code(_`await ${callValidateCode(cxt, v, passCxt)}`)
|
||||
addEvaluatedFrom(v) // TODO will not work with async, it has to be returned with the result
|
||||
if (!allErrors) gen.assign(valid, true)
|
||||
},
|
||||
(e) => {
|
||||
gen.if(_`!(${e} instanceof ${it.ValidationError as Name})`, () => gen.throw(e))
|
||||
addErrorsFrom(e)
|
||||
if (!allErrors) gen.assign(valid, false)
|
||||
}
|
||||
)
|
||||
cxt.ok(valid)
|
||||
}
|
||||
|
||||
function callSyncRef(): void {
|
||||
cxt.result(
|
||||
callValidateCode(cxt, v, passCxt),
|
||||
() => addEvaluatedFrom(v),
|
||||
() => addErrorsFrom(v)
|
||||
)
|
||||
}
|
||||
|
||||
function addErrorsFrom(source: Code): void {
|
||||
const errs = _`${source}.errors`
|
||||
gen.assign(N.vErrors, _`${N.vErrors} === null ? ${errs} : ${N.vErrors}.concat(${errs})`) // TODO tagged
|
||||
gen.assign(N.errors, _`${N.vErrors}.length`)
|
||||
}
|
||||
|
||||
function addEvaluatedFrom(source: Code): void {
|
||||
if (!it.opts.unevaluated) return
|
||||
const schEvaluated = sch?.validate?.evaluated
|
||||
// TODO refactor
|
||||
if (it.props !== true) {
|
||||
if (schEvaluated && !schEvaluated.dynamicProps) {
|
||||
if (schEvaluated.props !== undefined) {
|
||||
it.props = mergeEvaluated.props(gen, schEvaluated.props, it.props)
|
||||
}
|
||||
} else {
|
||||
const props = gen.var("props", _`${source}.evaluated.props`)
|
||||
it.props = mergeEvaluated.props(gen, props, it.props, Name)
|
||||
}
|
||||
}
|
||||
if (it.items !== true) {
|
||||
if (schEvaluated && !schEvaluated.dynamicItems) {
|
||||
if (schEvaluated.items !== undefined) {
|
||||
it.items = mergeEvaluated.items(gen, schEvaluated.items, it.items)
|
||||
}
|
||||
} else {
|
||||
const items = gen.var("items", _`${source}.evaluated.items`)
|
||||
it.items = mergeEvaluated.items(gen, items, it.items, Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default def
|
110
my-app/node_modules/ajv/lib/vocabularies/discriminator/index.ts
generated
vendored
Executable file
110
my-app/node_modules/ajv/lib/vocabularies/discriminator/index.ts
generated
vendored
Executable file
|
@ -0,0 +1,110 @@
|
|||
import type {CodeKeywordDefinition, AnySchemaObject, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, getProperty, Name} from "../../compile/codegen"
|
||||
import {DiscrError, DiscrErrorObj} from "../discriminator/types"
|
||||
import {resolveRef, SchemaEnv} from "../../compile"
|
||||
import {schemaHasRulesButRef} from "../../compile/util"
|
||||
|
||||
export type DiscriminatorError = DiscrErrorObj<DiscrError.Tag> | DiscrErrorObj<DiscrError.Mapping>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({params: {discrError, tagName}}) =>
|
||||
discrError === DiscrError.Tag
|
||||
? `tag "${tagName}" must be string`
|
||||
: `value of tag "${tagName}" must be in oneOf`,
|
||||
params: ({params: {discrError, tag, tagName}}) =>
|
||||
_`{error: ${discrError}, tag: ${tagName}, tagValue: ${tag}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "discriminator",
|
||||
type: "object",
|
||||
schemaType: "object",
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, data, schema, parentSchema, it} = cxt
|
||||
const {oneOf} = parentSchema
|
||||
if (!it.opts.discriminator) {
|
||||
throw new Error("discriminator: requires discriminator option")
|
||||
}
|
||||
const tagName = schema.propertyName
|
||||
if (typeof tagName != "string") throw new Error("discriminator: requires propertyName")
|
||||
if (schema.mapping) throw new Error("discriminator: mapping is not supported")
|
||||
if (!oneOf) throw new Error("discriminator: requires oneOf keyword")
|
||||
const valid = gen.let("valid", false)
|
||||
const tag = gen.const("tag", _`${data}${getProperty(tagName)}`)
|
||||
gen.if(
|
||||
_`typeof ${tag} == "string"`,
|
||||
() => validateMapping(),
|
||||
() => cxt.error(false, {discrError: DiscrError.Tag, tag, tagName})
|
||||
)
|
||||
cxt.ok(valid)
|
||||
|
||||
function validateMapping(): void {
|
||||
const mapping = getMapping()
|
||||
gen.if(false)
|
||||
for (const tagValue in mapping) {
|
||||
gen.elseIf(_`${tag} === ${tagValue}`)
|
||||
gen.assign(valid, applyTagSchema(mapping[tagValue]))
|
||||
}
|
||||
gen.else()
|
||||
cxt.error(false, {discrError: DiscrError.Mapping, tag, tagName})
|
||||
gen.endIf()
|
||||
}
|
||||
|
||||
function applyTagSchema(schemaProp?: number): Name {
|
||||
const _valid = gen.name("valid")
|
||||
const schCxt = cxt.subschema({keyword: "oneOf", schemaProp}, _valid)
|
||||
cxt.mergeEvaluated(schCxt, Name)
|
||||
return _valid
|
||||
}
|
||||
|
||||
function getMapping(): {[T in string]?: number} {
|
||||
const oneOfMapping: {[T in string]?: number} = {}
|
||||
const topRequired = hasRequired(parentSchema)
|
||||
let tagRequired = true
|
||||
for (let i = 0; i < oneOf.length; i++) {
|
||||
let sch = oneOf[i]
|
||||
if (sch?.$ref && !schemaHasRulesButRef(sch, it.self.RULES)) {
|
||||
sch = resolveRef.call(it.self, it.schemaEnv.root, it.baseId, sch?.$ref)
|
||||
if (sch instanceof SchemaEnv) sch = sch.schema
|
||||
}
|
||||
const propSch = sch?.properties?.[tagName]
|
||||
if (typeof propSch != "object") {
|
||||
throw new Error(
|
||||
`discriminator: oneOf subschemas (or referenced schemas) must have "properties/${tagName}"`
|
||||
)
|
||||
}
|
||||
tagRequired = tagRequired && (topRequired || hasRequired(sch))
|
||||
addMappings(propSch, i)
|
||||
}
|
||||
if (!tagRequired) throw new Error(`discriminator: "${tagName}" must be required`)
|
||||
return oneOfMapping
|
||||
|
||||
function hasRequired({required}: AnySchemaObject): boolean {
|
||||
return Array.isArray(required) && required.includes(tagName)
|
||||
}
|
||||
|
||||
function addMappings(sch: AnySchemaObject, i: number): void {
|
||||
if (sch.const) {
|
||||
addMapping(sch.const, i)
|
||||
} else if (sch.enum) {
|
||||
for (const tagValue of sch.enum) {
|
||||
addMapping(tagValue, i)
|
||||
}
|
||||
} else {
|
||||
throw new Error(`discriminator: "properties/${tagName}" must have "const" or "enum"`)
|
||||
}
|
||||
}
|
||||
|
||||
function addMapping(tagValue: unknown, i: number): void {
|
||||
if (typeof tagValue != "string" || tagValue in oneOfMapping) {
|
||||
throw new Error(`discriminator: "${tagName}" values must be unique strings`)
|
||||
}
|
||||
oneOfMapping[tagValue] = i
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
12
my-app/node_modules/ajv/lib/vocabularies/discriminator/types.ts
generated
vendored
Executable file
12
my-app/node_modules/ajv/lib/vocabularies/discriminator/types.ts
generated
vendored
Executable file
|
@ -0,0 +1,12 @@
|
|||
import type {ErrorObject} from "../../types"
|
||||
|
||||
export enum DiscrError {
|
||||
Tag = "tag",
|
||||
Mapping = "mapping",
|
||||
}
|
||||
|
||||
export type DiscrErrorObj<E extends DiscrError> = ErrorObject<
|
||||
"discriminator",
|
||||
{error: E; tag: string; tagValue: unknown},
|
||||
string
|
||||
>
|
23
my-app/node_modules/ajv/lib/vocabularies/draft2020.ts
generated
vendored
Executable file
23
my-app/node_modules/ajv/lib/vocabularies/draft2020.ts
generated
vendored
Executable file
|
@ -0,0 +1,23 @@
|
|||
import type {Vocabulary} from "../types"
|
||||
import coreVocabulary from "./core"
|
||||
import validationVocabulary from "./validation"
|
||||
import getApplicatorVocabulary from "./applicator"
|
||||
import dynamicVocabulary from "./dynamic"
|
||||
import nextVocabulary from "./next"
|
||||
import unevaluatedVocabulary from "./unevaluated"
|
||||
import formatVocabulary from "./format"
|
||||
import {metadataVocabulary, contentVocabulary} from "./metadata"
|
||||
|
||||
const draft2020Vocabularies: Vocabulary[] = [
|
||||
dynamicVocabulary,
|
||||
coreVocabulary,
|
||||
validationVocabulary,
|
||||
getApplicatorVocabulary(true),
|
||||
formatVocabulary,
|
||||
metadataVocabulary,
|
||||
contentVocabulary,
|
||||
nextVocabulary,
|
||||
unevaluatedVocabulary,
|
||||
]
|
||||
|
||||
export default draft2020Vocabularies
|
17
my-app/node_modules/ajv/lib/vocabularies/draft7.ts
generated
vendored
Executable file
17
my-app/node_modules/ajv/lib/vocabularies/draft7.ts
generated
vendored
Executable file
|
@ -0,0 +1,17 @@
|
|||
import type {Vocabulary} from "../types"
|
||||
import coreVocabulary from "./core"
|
||||
import validationVocabulary from "./validation"
|
||||
import getApplicatorVocabulary from "./applicator"
|
||||
import formatVocabulary from "./format"
|
||||
import {metadataVocabulary, contentVocabulary} from "./metadata"
|
||||
|
||||
const draft7Vocabularies: Vocabulary[] = [
|
||||
coreVocabulary,
|
||||
validationVocabulary,
|
||||
getApplicatorVocabulary(),
|
||||
formatVocabulary,
|
||||
metadataVocabulary,
|
||||
contentVocabulary,
|
||||
]
|
||||
|
||||
export default draft7Vocabularies
|
31
my-app/node_modules/ajv/lib/vocabularies/dynamic/dynamicAnchor.ts
generated
vendored
Executable file
31
my-app/node_modules/ajv/lib/vocabularies/dynamic/dynamicAnchor.ts
generated
vendored
Executable file
|
@ -0,0 +1,31 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, getProperty, Code} from "../../compile/codegen"
|
||||
import N from "../../compile/names"
|
||||
import {SchemaEnv, compileSchema} from "../../compile"
|
||||
import {getValidate} from "../core/ref"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "$dynamicAnchor",
|
||||
schemaType: "string",
|
||||
code: (cxt) => dynamicAnchor(cxt, cxt.schema),
|
||||
}
|
||||
|
||||
export function dynamicAnchor(cxt: KeywordCxt, anchor: string): void {
|
||||
const {gen, it} = cxt
|
||||
it.schemaEnv.root.dynamicAnchors[anchor] = true
|
||||
const v = _`${N.dynamicAnchors}${getProperty(anchor)}`
|
||||
const validate = it.errSchemaPath === "#" ? it.validateName : _getValidate(cxt)
|
||||
gen.if(_`!${v}`, () => gen.assign(v, validate))
|
||||
}
|
||||
|
||||
function _getValidate(cxt: KeywordCxt): Code {
|
||||
const {schemaEnv, schema, self} = cxt.it
|
||||
const {root, baseId, localRefs, meta} = schemaEnv.root
|
||||
const {schemaId} = self.opts
|
||||
const sch = new SchemaEnv({schema, schemaId, root, baseId, localRefs, meta})
|
||||
compileSchema.call(self, sch)
|
||||
return getValidate(cxt, sch)
|
||||
}
|
||||
|
||||
export default def
|
51
my-app/node_modules/ajv/lib/vocabularies/dynamic/dynamicRef.ts
generated
vendored
Executable file
51
my-app/node_modules/ajv/lib/vocabularies/dynamic/dynamicRef.ts
generated
vendored
Executable file
|
@ -0,0 +1,51 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, getProperty, Code, Name} from "../../compile/codegen"
|
||||
import N from "../../compile/names"
|
||||
import {callRef} from "../core/ref"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "$dynamicRef",
|
||||
schemaType: "string",
|
||||
code: (cxt) => dynamicRef(cxt, cxt.schema),
|
||||
}
|
||||
|
||||
export function dynamicRef(cxt: KeywordCxt, ref: string): void {
|
||||
const {gen, keyword, it} = cxt
|
||||
if (ref[0] !== "#") throw new Error(`"${keyword}" only supports hash fragment reference`)
|
||||
const anchor = ref.slice(1)
|
||||
if (it.allErrors) {
|
||||
_dynamicRef()
|
||||
} else {
|
||||
const valid = gen.let("valid", false)
|
||||
_dynamicRef(valid)
|
||||
cxt.ok(valid)
|
||||
}
|
||||
|
||||
function _dynamicRef(valid?: Name): void {
|
||||
// TODO the assumption here is that `recursiveRef: #` always points to the root
|
||||
// of the schema object, which is not correct, because there may be $id that
|
||||
// makes # point to it, and the target schema may not contain dynamic/recursiveAnchor.
|
||||
// Because of that 2 tests in recursiveRef.json fail.
|
||||
// This is a similar problem to #815 (`$id` doesn't alter resolution scope for `{ "$ref": "#" }`).
|
||||
// (This problem is not tested in JSON-Schema-Test-Suite)
|
||||
if (it.schemaEnv.root.dynamicAnchors[anchor]) {
|
||||
const v = gen.let("_v", _`${N.dynamicAnchors}${getProperty(anchor)}`)
|
||||
gen.if(v, _callRef(v, valid), _callRef(it.validateName, valid))
|
||||
} else {
|
||||
_callRef(it.validateName, valid)()
|
||||
}
|
||||
}
|
||||
|
||||
function _callRef(validate: Code, valid?: Name): () => void {
|
||||
return valid
|
||||
? () =>
|
||||
gen.block(() => {
|
||||
callRef(cxt, validate)
|
||||
gen.let(valid, true)
|
||||
})
|
||||
: () => callRef(cxt, validate)
|
||||
}
|
||||
}
|
||||
|
||||
export default def
|
9
my-app/node_modules/ajv/lib/vocabularies/dynamic/index.ts
generated
vendored
Executable file
9
my-app/node_modules/ajv/lib/vocabularies/dynamic/index.ts
generated
vendored
Executable file
|
@ -0,0 +1,9 @@
|
|||
import type {Vocabulary} from "../../types"
|
||||
import dynamicAnchor from "./dynamicAnchor"
|
||||
import dynamicRef from "./dynamicRef"
|
||||
import recursiveAnchor from "./recursiveAnchor"
|
||||
import recursiveRef from "./recursiveRef"
|
||||
|
||||
const dynamic: Vocabulary = [dynamicAnchor, dynamicRef, recursiveAnchor, recursiveRef]
|
||||
|
||||
export default dynamic
|
14
my-app/node_modules/ajv/lib/vocabularies/dynamic/recursiveAnchor.ts
generated
vendored
Executable file
14
my-app/node_modules/ajv/lib/vocabularies/dynamic/recursiveAnchor.ts
generated
vendored
Executable file
|
@ -0,0 +1,14 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import {dynamicAnchor} from "./dynamicAnchor"
|
||||
import {checkStrictMode} from "../../compile/util"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "$recursiveAnchor",
|
||||
schemaType: "boolean",
|
||||
code(cxt) {
|
||||
if (cxt.schema) dynamicAnchor(cxt, "")
|
||||
else checkStrictMode(cxt.it, "$recursiveAnchor: false is ignored")
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
10
my-app/node_modules/ajv/lib/vocabularies/dynamic/recursiveRef.ts
generated
vendored
Executable file
10
my-app/node_modules/ajv/lib/vocabularies/dynamic/recursiveRef.ts
generated
vendored
Executable file
|
@ -0,0 +1,10 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import {dynamicRef} from "./dynamicRef"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "$recursiveRef",
|
||||
schemaType: "string",
|
||||
code: (cxt) => dynamicRef(cxt, cxt.schema),
|
||||
}
|
||||
|
||||
export default def
|
18
my-app/node_modules/ajv/lib/vocabularies/errors.ts
generated
vendored
Executable file
18
my-app/node_modules/ajv/lib/vocabularies/errors.ts
generated
vendored
Executable file
|
@ -0,0 +1,18 @@
|
|||
import type {TypeError} from "../compile/validate/dataType"
|
||||
import type {ApplicatorKeywordError} from "./applicator"
|
||||
import type {ValidationKeywordError} from "./validation"
|
||||
import type {FormatError} from "./format/format"
|
||||
import type {UnevaluatedPropertiesError} from "./unevaluated/unevaluatedProperties"
|
||||
import type {UnevaluatedItemsError} from "./unevaluated/unevaluatedItems"
|
||||
import type {DependentRequiredError} from "./validation/dependentRequired"
|
||||
import type {DiscriminatorError} from "./discriminator"
|
||||
|
||||
export type DefinedError =
|
||||
| TypeError
|
||||
| ApplicatorKeywordError
|
||||
| ValidationKeywordError
|
||||
| FormatError
|
||||
| UnevaluatedPropertiesError
|
||||
| UnevaluatedItemsError
|
||||
| DependentRequiredError
|
||||
| DiscriminatorError
|
120
my-app/node_modules/ajv/lib/vocabularies/format/format.ts
generated
vendored
Executable file
120
my-app/node_modules/ajv/lib/vocabularies/format/format.ts
generated
vendored
Executable file
|
@ -0,0 +1,120 @@
|
|||
import type {
|
||||
AddedFormat,
|
||||
FormatValidator,
|
||||
AsyncFormatValidator,
|
||||
CodeKeywordDefinition,
|
||||
KeywordErrorDefinition,
|
||||
ErrorObject,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, nil, or, Code, getProperty, regexpCode} from "../../compile/codegen"
|
||||
|
||||
type FormatValidate =
|
||||
| FormatValidator<string>
|
||||
| FormatValidator<number>
|
||||
| AsyncFormatValidator<string>
|
||||
| AsyncFormatValidator<number>
|
||||
| RegExp
|
||||
| string
|
||||
| true
|
||||
|
||||
export type FormatError = ErrorObject<"format", {format: string}, string | {$data: string}>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({schemaCode}) => str`must match format "${schemaCode}"`,
|
||||
params: ({schemaCode}) => _`{format: ${schemaCode}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "format",
|
||||
type: ["number", "string"],
|
||||
schemaType: "string",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt, ruleType?: string) {
|
||||
const {gen, data, $data, schema, schemaCode, it} = cxt
|
||||
const {opts, errSchemaPath, schemaEnv, self} = it
|
||||
if (!opts.validateFormats) return
|
||||
|
||||
if ($data) validate$DataFormat()
|
||||
else validateFormat()
|
||||
|
||||
function validate$DataFormat(): void {
|
||||
const fmts = gen.scopeValue("formats", {
|
||||
ref: self.formats,
|
||||
code: opts.code.formats,
|
||||
})
|
||||
const fDef = gen.const("fDef", _`${fmts}[${schemaCode}]`)
|
||||
const fType = gen.let("fType")
|
||||
const format = gen.let("format")
|
||||
// TODO simplify
|
||||
gen.if(
|
||||
_`typeof ${fDef} == "object" && !(${fDef} instanceof RegExp)`,
|
||||
() => gen.assign(fType, _`${fDef}.type || "string"`).assign(format, _`${fDef}.validate`),
|
||||
() => gen.assign(fType, _`"string"`).assign(format, fDef)
|
||||
)
|
||||
cxt.fail$data(or(unknownFmt(), invalidFmt()))
|
||||
|
||||
function unknownFmt(): Code {
|
||||
if (opts.strictSchema === false) return nil
|
||||
return _`${schemaCode} && !${format}`
|
||||
}
|
||||
|
||||
function invalidFmt(): Code {
|
||||
const callFormat = schemaEnv.$async
|
||||
? _`(${fDef}.async ? await ${format}(${data}) : ${format}(${data}))`
|
||||
: _`${format}(${data})`
|
||||
const validData = _`(typeof ${format} == "function" ? ${callFormat} : ${format}.test(${data}))`
|
||||
return _`${format} && ${format} !== true && ${fType} === ${ruleType} && !${validData}`
|
||||
}
|
||||
}
|
||||
|
||||
function validateFormat(): void {
|
||||
const formatDef: AddedFormat | undefined = self.formats[schema]
|
||||
if (!formatDef) {
|
||||
unknownFormat()
|
||||
return
|
||||
}
|
||||
if (formatDef === true) return
|
||||
const [fmtType, format, fmtRef] = getFormat(formatDef)
|
||||
if (fmtType === ruleType) cxt.pass(validCondition())
|
||||
|
||||
function unknownFormat(): void {
|
||||
if (opts.strictSchema === false) {
|
||||
self.logger.warn(unknownMsg())
|
||||
return
|
||||
}
|
||||
throw new Error(unknownMsg())
|
||||
|
||||
function unknownMsg(): string {
|
||||
return `unknown format "${schema as string}" ignored in schema at path "${errSchemaPath}"`
|
||||
}
|
||||
}
|
||||
|
||||
function getFormat(fmtDef: AddedFormat): [string, FormatValidate, Code] {
|
||||
const code =
|
||||
fmtDef instanceof RegExp
|
||||
? regexpCode(fmtDef)
|
||||
: opts.code.formats
|
||||
? _`${opts.code.formats}${getProperty(schema)}`
|
||||
: undefined
|
||||
const fmt = gen.scopeValue("formats", {key: schema, ref: fmtDef, code})
|
||||
if (typeof fmtDef == "object" && !(fmtDef instanceof RegExp)) {
|
||||
return [fmtDef.type || "string", fmtDef.validate, _`${fmt}.validate`]
|
||||
}
|
||||
|
||||
return ["string", fmtDef, fmt]
|
||||
}
|
||||
|
||||
function validCondition(): Code {
|
||||
if (typeof formatDef == "object" && !(formatDef instanceof RegExp) && formatDef.async) {
|
||||
if (!schemaEnv.$async) throw new Error("async format in sync schema")
|
||||
return _`await ${fmtRef}(${data})`
|
||||
}
|
||||
return typeof format == "function" ? _`${fmtRef}(${data})` : _`${fmtRef}.test(${data})`
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
6
my-app/node_modules/ajv/lib/vocabularies/format/index.ts
generated
vendored
Executable file
6
my-app/node_modules/ajv/lib/vocabularies/format/index.ts
generated
vendored
Executable file
|
@ -0,0 +1,6 @@
|
|||
import type {Vocabulary} from "../../types"
|
||||
import formatKeyword from "./format"
|
||||
|
||||
const format: Vocabulary = [formatKeyword]
|
||||
|
||||
export default format
|
89
my-app/node_modules/ajv/lib/vocabularies/jtd/discriminator.ts
generated
vendored
Executable file
89
my-app/node_modules/ajv/lib/vocabularies/jtd/discriminator.ts
generated
vendored
Executable file
|
@ -0,0 +1,89 @@
|
|||
import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, not, getProperty, Name} from "../../compile/codegen"
|
||||
import {checkMetadata} from "./metadata"
|
||||
import {checkNullableObject} from "./nullable"
|
||||
import {typeErrorMessage, typeErrorParams, _JTDTypeError} from "./error"
|
||||
import {DiscrError, DiscrErrorObj} from "../discriminator/types"
|
||||
|
||||
export type JTDDiscriminatorError =
|
||||
| _JTDTypeError<"discriminator", "object", string>
|
||||
| DiscrErrorObj<DiscrError.Tag>
|
||||
| DiscrErrorObj<DiscrError.Mapping>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: (cxt) => {
|
||||
const {schema, params} = cxt
|
||||
return params.discrError
|
||||
? params.discrError === DiscrError.Tag
|
||||
? `tag "${schema}" must be string`
|
||||
: `value of tag "${schema}" must be in mapping`
|
||||
: typeErrorMessage(cxt, "object")
|
||||
},
|
||||
params: (cxt) => {
|
||||
const {schema, params} = cxt
|
||||
return params.discrError
|
||||
? _`{error: ${params.discrError}, tag: ${schema}, tagValue: ${params.tag}}`
|
||||
: typeErrorParams(cxt, "object")
|
||||
},
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "discriminator",
|
||||
schemaType: "string",
|
||||
implements: ["mapping"],
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
checkMetadata(cxt)
|
||||
const {gen, data, schema, parentSchema} = cxt
|
||||
const [valid, cond] = checkNullableObject(cxt, data)
|
||||
|
||||
gen.if(cond)
|
||||
validateDiscriminator()
|
||||
gen.elseIf(not(valid))
|
||||
cxt.error()
|
||||
gen.endIf()
|
||||
cxt.ok(valid)
|
||||
|
||||
function validateDiscriminator(): void {
|
||||
const tag = gen.const("tag", _`${data}${getProperty(schema)}`)
|
||||
gen.if(_`${tag} === undefined`)
|
||||
cxt.error(false, {discrError: DiscrError.Tag, tag})
|
||||
gen.elseIf(_`typeof ${tag} == "string"`)
|
||||
validateMapping(tag)
|
||||
gen.else()
|
||||
cxt.error(false, {discrError: DiscrError.Tag, tag}, {instancePath: schema})
|
||||
gen.endIf()
|
||||
}
|
||||
|
||||
function validateMapping(tag: Name): void {
|
||||
gen.if(false)
|
||||
for (const tagValue in parentSchema.mapping) {
|
||||
gen.elseIf(_`${tag} === ${tagValue}`)
|
||||
gen.assign(valid, applyTagSchema(tagValue))
|
||||
}
|
||||
gen.else()
|
||||
cxt.error(
|
||||
false,
|
||||
{discrError: DiscrError.Mapping, tag},
|
||||
{instancePath: schema, schemaPath: "mapping", parentSchema: true}
|
||||
)
|
||||
gen.endIf()
|
||||
}
|
||||
|
||||
function applyTagSchema(schemaProp: string): Name {
|
||||
const _valid = gen.name("valid")
|
||||
cxt.subschema(
|
||||
{
|
||||
keyword: "mapping",
|
||||
schemaProp,
|
||||
jtdDiscriminator: schema,
|
||||
},
|
||||
_valid
|
||||
)
|
||||
return _valid
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
32
my-app/node_modules/ajv/lib/vocabularies/jtd/elements.ts
generated
vendored
Executable file
32
my-app/node_modules/ajv/lib/vocabularies/jtd/elements.ts
generated
vendored
Executable file
|
@ -0,0 +1,32 @@
|
|||
import type {CodeKeywordDefinition, SchemaObject} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {alwaysValidSchema} from "../../compile/util"
|
||||
import {validateArray} from "../code"
|
||||
import {_, not} from "../../compile/codegen"
|
||||
import {checkMetadata} from "./metadata"
|
||||
import {checkNullable} from "./nullable"
|
||||
import {typeError, _JTDTypeError} from "./error"
|
||||
|
||||
export type JTDElementsError = _JTDTypeError<"elements", "array", SchemaObject>
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "elements",
|
||||
schemaType: "object",
|
||||
error: typeError("array"),
|
||||
code(cxt: KeywordCxt) {
|
||||
checkMetadata(cxt)
|
||||
const {gen, data, schema, it} = cxt
|
||||
if (alwaysValidSchema(it, schema)) return
|
||||
const [valid] = checkNullable(cxt)
|
||||
gen.if(not(valid), () =>
|
||||
gen.if(
|
||||
_`Array.isArray(${data})`,
|
||||
() => gen.assign(valid, validateArray(cxt)),
|
||||
() => cxt.error()
|
||||
)
|
||||
)
|
||||
cxt.ok(valid)
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
45
my-app/node_modules/ajv/lib/vocabularies/jtd/enum.ts
generated
vendored
Executable file
45
my-app/node_modules/ajv/lib/vocabularies/jtd/enum.ts
generated
vendored
Executable file
|
@ -0,0 +1,45 @@
|
|||
import type {CodeKeywordDefinition, KeywordErrorDefinition, ErrorObject} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, or, and, Code} from "../../compile/codegen"
|
||||
import {checkMetadata} from "./metadata"
|
||||
import {checkNullable} from "./nullable"
|
||||
|
||||
export type JTDEnumError = ErrorObject<"enum", {allowedValues: string[]}, string[]>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: "must be equal to one of the allowed values",
|
||||
params: ({schemaCode}) => _`{allowedValues: ${schemaCode}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "enum",
|
||||
schemaType: "array",
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
checkMetadata(cxt)
|
||||
const {gen, data, schema, schemaValue, parentSchema, it} = cxt
|
||||
if (schema.length === 0) throw new Error("enum must have non-empty array")
|
||||
if (schema.length !== new Set(schema).size) throw new Error("enum items must be unique")
|
||||
let valid: Code
|
||||
const isString = _`typeof ${data} == "string"`
|
||||
if (schema.length >= it.opts.loopEnum) {
|
||||
let cond: Code
|
||||
;[valid, cond] = checkNullable(cxt, isString)
|
||||
gen.if(cond, loopEnum)
|
||||
} else {
|
||||
/* istanbul ignore if */
|
||||
if (!Array.isArray(schema)) throw new Error("ajv implementation error")
|
||||
valid = and(isString, or(...schema.map((value: string) => _`${data} === ${value}`)))
|
||||
if (parentSchema.nullable) valid = or(_`${data} === null`, valid)
|
||||
}
|
||||
cxt.pass(valid)
|
||||
|
||||
function loopEnum(): void {
|
||||
gen.forOf("v", schemaValue as Code, (v) =>
|
||||
gen.if(_`${valid} = ${data} === ${v}`, () => gen.break())
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
23
my-app/node_modules/ajv/lib/vocabularies/jtd/error.ts
generated
vendored
Executable file
23
my-app/node_modules/ajv/lib/vocabularies/jtd/error.ts
generated
vendored
Executable file
|
@ -0,0 +1,23 @@
|
|||
import type {KeywordErrorDefinition, KeywordErrorCxt, ErrorObject} from "../../types"
|
||||
import {_, Code} from "../../compile/codegen"
|
||||
|
||||
export type _JTDTypeError<K extends string, T extends string, S> = ErrorObject<
|
||||
K,
|
||||
{type: T; nullable: boolean},
|
||||
S
|
||||
>
|
||||
|
||||
export function typeError(t: string): KeywordErrorDefinition {
|
||||
return {
|
||||
message: (cxt) => typeErrorMessage(cxt, t),
|
||||
params: (cxt) => typeErrorParams(cxt, t),
|
||||
}
|
||||
}
|
||||
|
||||
export function typeErrorMessage({parentSchema}: KeywordErrorCxt, t: string): string {
|
||||
return parentSchema?.nullable ? `must be ${t} or null` : `must be ${t}`
|
||||
}
|
||||
|
||||
export function typeErrorParams({parentSchema}: KeywordErrorCxt, t: string): Code {
|
||||
return _`{type: ${t}, nullable: ${!!parentSchema?.nullable}}`
|
||||
}
|
37
my-app/node_modules/ajv/lib/vocabularies/jtd/index.ts
generated
vendored
Executable file
37
my-app/node_modules/ajv/lib/vocabularies/jtd/index.ts
generated
vendored
Executable file
|
@ -0,0 +1,37 @@
|
|||
import type {Vocabulary} from "../../types"
|
||||
import refKeyword from "./ref"
|
||||
import typeKeyword, {JTDTypeError} from "./type"
|
||||
import enumKeyword, {JTDEnumError} from "./enum"
|
||||
import elements, {JTDElementsError} from "./elements"
|
||||
import properties, {JTDPropertiesError} from "./properties"
|
||||
import optionalProperties from "./optionalProperties"
|
||||
import discriminator, {JTDDiscriminatorError} from "./discriminator"
|
||||
import values, {JTDValuesError} from "./values"
|
||||
import union from "./union"
|
||||
import metadata from "./metadata"
|
||||
|
||||
const jtdVocabulary: Vocabulary = [
|
||||
"definitions",
|
||||
refKeyword,
|
||||
typeKeyword,
|
||||
enumKeyword,
|
||||
elements,
|
||||
properties,
|
||||
optionalProperties,
|
||||
discriminator,
|
||||
values,
|
||||
union,
|
||||
metadata,
|
||||
{keyword: "additionalProperties", schemaType: "boolean"},
|
||||
{keyword: "nullable", schemaType: "boolean"},
|
||||
]
|
||||
|
||||
export default jtdVocabulary
|
||||
|
||||
export type JTDErrorObject =
|
||||
| JTDTypeError
|
||||
| JTDEnumError
|
||||
| JTDElementsError
|
||||
| JTDPropertiesError
|
||||
| JTDDiscriminatorError
|
||||
| JTDValuesError
|
24
my-app/node_modules/ajv/lib/vocabularies/jtd/metadata.ts
generated
vendored
Executable file
24
my-app/node_modules/ajv/lib/vocabularies/jtd/metadata.ts
generated
vendored
Executable file
|
@ -0,0 +1,24 @@
|
|||
import {KeywordCxt} from "../../ajv"
|
||||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import {alwaysValidSchema} from "../../compile/util"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "metadata",
|
||||
schemaType: "object",
|
||||
code(cxt: KeywordCxt) {
|
||||
checkMetadata(cxt)
|
||||
const {gen, schema, it} = cxt
|
||||
if (alwaysValidSchema(it, schema)) return
|
||||
const valid = gen.name("valid")
|
||||
cxt.subschema({keyword: "metadata", jtdMetadata: true}, valid)
|
||||
cxt.ok(valid)
|
||||
},
|
||||
}
|
||||
|
||||
export function checkMetadata({it, keyword}: KeywordCxt, metadata?: boolean): void {
|
||||
if (it.jtdMetadata !== metadata) {
|
||||
throw new Error(`JTD: "${keyword}" cannot be used in this schema location`)
|
||||
}
|
||||
}
|
||||
|
||||
export default def
|
21
my-app/node_modules/ajv/lib/vocabularies/jtd/nullable.ts
generated
vendored
Executable file
21
my-app/node_modules/ajv/lib/vocabularies/jtd/nullable.ts
generated
vendored
Executable file
|
@ -0,0 +1,21 @@
|
|||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, not, nil, Code, Name} from "../../compile/codegen"
|
||||
|
||||
export function checkNullable(
|
||||
{gen, data, parentSchema}: KeywordCxt,
|
||||
cond: Code = nil
|
||||
): [Name, Code] {
|
||||
const valid = gen.name("valid")
|
||||
if (parentSchema.nullable) {
|
||||
gen.let(valid, _`${data} === null`)
|
||||
cond = not(valid)
|
||||
} else {
|
||||
gen.let(valid, false)
|
||||
}
|
||||
return [valid, cond]
|
||||
}
|
||||
|
||||
export function checkNullableObject(cxt: KeywordCxt, cond: Code): [Name, Code] {
|
||||
const [valid, cond_] = checkNullable(cxt, cond)
|
||||
return [valid, _`${cond_} && typeof ${cxt.data} == "object" && !Array.isArray(${cxt.data})`]
|
||||
}
|
15
my-app/node_modules/ajv/lib/vocabularies/jtd/optionalProperties.ts
generated
vendored
Executable file
15
my-app/node_modules/ajv/lib/vocabularies/jtd/optionalProperties.ts
generated
vendored
Executable file
|
@ -0,0 +1,15 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {validateProperties, error} from "./properties"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "optionalProperties",
|
||||
schemaType: "object",
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
if (cxt.parentSchema.properties) return
|
||||
validateProperties(cxt)
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
184
my-app/node_modules/ajv/lib/vocabularies/jtd/properties.ts
generated
vendored
Executable file
184
my-app/node_modules/ajv/lib/vocabularies/jtd/properties.ts
generated
vendored
Executable file
|
@ -0,0 +1,184 @@
|
|||
import type {
|
||||
CodeKeywordDefinition,
|
||||
ErrorObject,
|
||||
KeywordErrorDefinition,
|
||||
SchemaObject,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {propertyInData, allSchemaProperties, isOwnProperty} from "../code"
|
||||
import {alwaysValidSchema, schemaRefOrVal} from "../../compile/util"
|
||||
import {_, and, not, Code, Name} from "../../compile/codegen"
|
||||
import {checkMetadata} from "./metadata"
|
||||
import {checkNullableObject} from "./nullable"
|
||||
import {typeErrorMessage, typeErrorParams, _JTDTypeError} from "./error"
|
||||
|
||||
enum PropError {
|
||||
Additional = "additional",
|
||||
Missing = "missing",
|
||||
}
|
||||
|
||||
type PropKeyword = "properties" | "optionalProperties"
|
||||
|
||||
type PropSchema = {[P in string]?: SchemaObject}
|
||||
|
||||
export type JTDPropertiesError =
|
||||
| _JTDTypeError<PropKeyword, "object", PropSchema>
|
||||
| ErrorObject<PropKeyword, {error: PropError.Additional; additionalProperty: string}, PropSchema>
|
||||
| ErrorObject<PropKeyword, {error: PropError.Missing; missingProperty: string}, PropSchema>
|
||||
|
||||
export const error: KeywordErrorDefinition = {
|
||||
message: (cxt) => {
|
||||
const {params} = cxt
|
||||
return params.propError
|
||||
? params.propError === PropError.Additional
|
||||
? "must NOT have additional properties"
|
||||
: `must have property '${params.missingProperty}'`
|
||||
: typeErrorMessage(cxt, "object")
|
||||
},
|
||||
params: (cxt) => {
|
||||
const {params} = cxt
|
||||
return params.propError
|
||||
? params.propError === PropError.Additional
|
||||
? _`{error: ${params.propError}, additionalProperty: ${params.additionalProperty}}`
|
||||
: _`{error: ${params.propError}, missingProperty: ${params.missingProperty}}`
|
||||
: typeErrorParams(cxt, "object")
|
||||
},
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "properties",
|
||||
schemaType: "object",
|
||||
error,
|
||||
code: validateProperties,
|
||||
}
|
||||
|
||||
// const error: KeywordErrorDefinition = {
|
||||
// message: "should NOT have additional properties",
|
||||
// params: ({params}) => _`{additionalProperty: ${params.additionalProperty}}`,
|
||||
// }
|
||||
|
||||
export function validateProperties(cxt: KeywordCxt): void {
|
||||
checkMetadata(cxt)
|
||||
const {gen, data, parentSchema, it} = cxt
|
||||
const {additionalProperties, nullable} = parentSchema
|
||||
if (it.jtdDiscriminator && nullable) throw new Error("JTD: nullable inside discriminator mapping")
|
||||
if (commonProperties()) {
|
||||
throw new Error("JTD: properties and optionalProperties have common members")
|
||||
}
|
||||
const [allProps, properties] = schemaProperties("properties")
|
||||
const [allOptProps, optProperties] = schemaProperties("optionalProperties")
|
||||
if (properties.length === 0 && optProperties.length === 0 && additionalProperties) {
|
||||
return
|
||||
}
|
||||
|
||||
const [valid, cond] =
|
||||
it.jtdDiscriminator === undefined
|
||||
? checkNullableObject(cxt, data)
|
||||
: [gen.let("valid", false), true]
|
||||
gen.if(cond, () =>
|
||||
gen.assign(valid, true).block(() => {
|
||||
validateProps(properties, "properties", true)
|
||||
validateProps(optProperties, "optionalProperties")
|
||||
if (!additionalProperties) validateAdditional()
|
||||
})
|
||||
)
|
||||
cxt.pass(valid)
|
||||
|
||||
function commonProperties(): boolean {
|
||||
const props = parentSchema.properties as Record<string, any> | undefined
|
||||
const optProps = parentSchema.optionalProperties as Record<string, any> | undefined
|
||||
if (!(props && optProps)) return false
|
||||
for (const p in props) {
|
||||
if (Object.prototype.hasOwnProperty.call(optProps, p)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function schemaProperties(keyword: string): [string[], string[]] {
|
||||
const schema = parentSchema[keyword]
|
||||
const allPs = schema ? allSchemaProperties(schema) : []
|
||||
if (it.jtdDiscriminator && allPs.some((p) => p === it.jtdDiscriminator)) {
|
||||
throw new Error(`JTD: discriminator tag used in ${keyword}`)
|
||||
}
|
||||
const ps = allPs.filter((p) => !alwaysValidSchema(it, schema[p]))
|
||||
return [allPs, ps]
|
||||
}
|
||||
|
||||
function validateProps(props: string[], keyword: string, required?: boolean): void {
|
||||
const _valid = gen.var("valid")
|
||||
for (const prop of props) {
|
||||
gen.if(
|
||||
propertyInData(gen, data, prop, it.opts.ownProperties),
|
||||
() => applyPropertySchema(prop, keyword, _valid),
|
||||
() => missingProperty(prop)
|
||||
)
|
||||
cxt.ok(_valid)
|
||||
}
|
||||
|
||||
function missingProperty(prop: string): void {
|
||||
if (required) {
|
||||
gen.assign(_valid, false)
|
||||
cxt.error(false, {propError: PropError.Missing, missingProperty: prop}, {schemaPath: prop})
|
||||
} else {
|
||||
gen.assign(_valid, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function applyPropertySchema(prop: string, keyword: string, _valid: Name): void {
|
||||
cxt.subschema(
|
||||
{
|
||||
keyword,
|
||||
schemaProp: prop,
|
||||
dataProp: prop,
|
||||
},
|
||||
_valid
|
||||
)
|
||||
}
|
||||
|
||||
function validateAdditional(): void {
|
||||
gen.forIn("key", data, (key: Name) => {
|
||||
const addProp = isAdditional(key, allProps, "properties", it.jtdDiscriminator)
|
||||
const addOptProp = isAdditional(key, allOptProps, "optionalProperties")
|
||||
const extra =
|
||||
addProp === true ? addOptProp : addOptProp === true ? addProp : and(addProp, addOptProp)
|
||||
gen.if(extra, () => {
|
||||
if (it.opts.removeAdditional) {
|
||||
gen.code(_`delete ${data}[${key}]`)
|
||||
} else {
|
||||
cxt.error(
|
||||
false,
|
||||
{propError: PropError.Additional, additionalProperty: key},
|
||||
{instancePath: key, parentSchema: true}
|
||||
)
|
||||
if (!it.opts.allErrors) gen.break()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function isAdditional(
|
||||
key: Name,
|
||||
props: string[],
|
||||
keyword: string,
|
||||
jtdDiscriminator?: string
|
||||
): Code | true {
|
||||
let additional: Code | boolean
|
||||
if (props.length > 8) {
|
||||
// TODO maybe an option instead of hard-coded 8?
|
||||
const propsSchema = schemaRefOrVal(it, parentSchema[keyword], keyword)
|
||||
additional = not(isOwnProperty(gen, propsSchema as Code, key))
|
||||
if (jtdDiscriminator !== undefined) {
|
||||
additional = and(additional, _`${key} !== ${jtdDiscriminator}`)
|
||||
}
|
||||
} else if (props.length || jtdDiscriminator !== undefined) {
|
||||
const ps = jtdDiscriminator === undefined ? props : [jtdDiscriminator].concat(props)
|
||||
additional = and(...ps.map((p) => _`${key} !== ${p}`))
|
||||
} else {
|
||||
additional = true
|
||||
}
|
||||
return additional
|
||||
}
|
||||
}
|
||||
|
||||
export default def
|
76
my-app/node_modules/ajv/lib/vocabularies/jtd/ref.ts
generated
vendored
Executable file
76
my-app/node_modules/ajv/lib/vocabularies/jtd/ref.ts
generated
vendored
Executable file
|
@ -0,0 +1,76 @@
|
|||
import type {CodeKeywordDefinition, AnySchemaObject} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {compileSchema, SchemaEnv} from "../../compile"
|
||||
import {_, not, nil, stringify} from "../../compile/codegen"
|
||||
import MissingRefError from "../../compile/ref_error"
|
||||
import N from "../../compile/names"
|
||||
import {getValidate, callRef} from "../core/ref"
|
||||
import {checkMetadata} from "./metadata"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "ref",
|
||||
schemaType: "string",
|
||||
code(cxt: KeywordCxt) {
|
||||
checkMetadata(cxt)
|
||||
const {gen, data, schema: ref, parentSchema, it} = cxt
|
||||
const {
|
||||
schemaEnv: {root},
|
||||
} = it
|
||||
const valid = gen.name("valid")
|
||||
if (parentSchema.nullable) {
|
||||
gen.var(valid, _`${data} === null`)
|
||||
gen.if(not(valid), validateJtdRef)
|
||||
} else {
|
||||
gen.var(valid, false)
|
||||
validateJtdRef()
|
||||
}
|
||||
cxt.ok(valid)
|
||||
|
||||
function validateJtdRef(): void {
|
||||
const refSchema = (root.schema as AnySchemaObject).definitions?.[ref]
|
||||
if (!refSchema) {
|
||||
throw new MissingRefError(it.opts.uriResolver, "", ref, `No definition ${ref}`)
|
||||
}
|
||||
if (hasRef(refSchema) || !it.opts.inlineRefs) callValidate(refSchema)
|
||||
else inlineRefSchema(refSchema)
|
||||
}
|
||||
|
||||
function callValidate(schema: AnySchemaObject): void {
|
||||
const sch = compileSchema.call(
|
||||
it.self,
|
||||
new SchemaEnv({schema, root, schemaPath: `/definitions/${ref}`})
|
||||
)
|
||||
const v = getValidate(cxt, sch)
|
||||
const errsCount = gen.const("_errs", N.errors)
|
||||
callRef(cxt, v, sch, sch.$async)
|
||||
gen.assign(valid, _`${errsCount} === ${N.errors}`)
|
||||
}
|
||||
|
||||
function inlineRefSchema(schema: AnySchemaObject): void {
|
||||
const schName = gen.scopeValue(
|
||||
"schema",
|
||||
it.opts.code.source === true ? {ref: schema, code: stringify(schema)} : {ref: schema}
|
||||
)
|
||||
cxt.subschema(
|
||||
{
|
||||
schema,
|
||||
dataTypes: [],
|
||||
schemaPath: nil,
|
||||
topSchemaRef: schName,
|
||||
errSchemaPath: `/definitions/${ref}`,
|
||||
},
|
||||
valid
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export function hasRef(schema: AnySchemaObject): boolean {
|
||||
for (const key in schema) {
|
||||
let sch: AnySchemaObject
|
||||
if (key === "ref" || (typeof (sch = schema[key]) == "object" && hasRef(sch))) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export default def
|
75
my-app/node_modules/ajv/lib/vocabularies/jtd/type.ts
generated
vendored
Executable file
75
my-app/node_modules/ajv/lib/vocabularies/jtd/type.ts
generated
vendored
Executable file
|
@ -0,0 +1,75 @@
|
|||
import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, nil, or, Code} from "../../compile/codegen"
|
||||
import validTimestamp from "../../runtime/timestamp"
|
||||
import {useFunc} from "../../compile/util"
|
||||
import {checkMetadata} from "./metadata"
|
||||
import {typeErrorMessage, typeErrorParams, _JTDTypeError} from "./error"
|
||||
|
||||
export type JTDTypeError = _JTDTypeError<"type", JTDType, JTDType>
|
||||
|
||||
export type IntType = "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32"
|
||||
|
||||
export const intRange: {[T in IntType]: [number, number, number]} = {
|
||||
int8: [-128, 127, 3],
|
||||
uint8: [0, 255, 3],
|
||||
int16: [-32768, 32767, 5],
|
||||
uint16: [0, 65535, 5],
|
||||
int32: [-2147483648, 2147483647, 10],
|
||||
uint32: [0, 4294967295, 10],
|
||||
}
|
||||
|
||||
export type JTDType = "boolean" | "string" | "timestamp" | "float32" | "float64" | IntType
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: (cxt) => typeErrorMessage(cxt, cxt.schema),
|
||||
params: (cxt) => typeErrorParams(cxt, cxt.schema),
|
||||
}
|
||||
|
||||
function timestampCode(cxt: KeywordCxt): Code {
|
||||
const {gen, data, it} = cxt
|
||||
const {timestamp, allowDate} = it.opts
|
||||
if (timestamp === "date") return _`${data} instanceof Date `
|
||||
const vts = useFunc(gen, validTimestamp)
|
||||
const allowDateArg = allowDate ? _`, true` : nil
|
||||
const validString = _`typeof ${data} == "string" && ${vts}(${data}${allowDateArg})`
|
||||
return timestamp === "string" ? validString : or(_`${data} instanceof Date`, validString)
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "type",
|
||||
schemaType: "string",
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
checkMetadata(cxt)
|
||||
const {data, schema, parentSchema, it} = cxt
|
||||
let cond: Code
|
||||
switch (schema) {
|
||||
case "boolean":
|
||||
case "string":
|
||||
cond = _`typeof ${data} == ${schema}`
|
||||
break
|
||||
case "timestamp": {
|
||||
cond = timestampCode(cxt)
|
||||
break
|
||||
}
|
||||
case "float32":
|
||||
case "float64":
|
||||
cond = _`typeof ${data} == "number"`
|
||||
break
|
||||
default: {
|
||||
const sch = schema as IntType
|
||||
cond = _`typeof ${data} == "number" && isFinite(${data}) && !(${data} % 1)`
|
||||
if (!it.opts.int32range && (sch === "int32" || sch === "uint32")) {
|
||||
if (sch === "uint32") cond = _`${cond} && ${data} >= 0`
|
||||
} else {
|
||||
const [min, max] = intRange[sch]
|
||||
cond = _`${cond} && ${data} >= ${min} && ${data} <= ${max}`
|
||||
}
|
||||
}
|
||||
}
|
||||
cxt.pass(parentSchema.nullable ? or(_`${data} === null`, cond) : cond)
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
12
my-app/node_modules/ajv/lib/vocabularies/jtd/union.ts
generated
vendored
Executable file
12
my-app/node_modules/ajv/lib/vocabularies/jtd/union.ts
generated
vendored
Executable file
|
@ -0,0 +1,12 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import {validateUnion} from "../code"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "union",
|
||||
schemaType: "array",
|
||||
trackErrors: true,
|
||||
code: validateUnion,
|
||||
error: {message: "must match a schema in union"},
|
||||
}
|
||||
|
||||
export default def
|
58
my-app/node_modules/ajv/lib/vocabularies/jtd/values.ts
generated
vendored
Executable file
58
my-app/node_modules/ajv/lib/vocabularies/jtd/values.ts
generated
vendored
Executable file
|
@ -0,0 +1,58 @@
|
|||
import type {CodeKeywordDefinition, SchemaObject} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {alwaysValidSchema, Type} from "../../compile/util"
|
||||
import {not, or, Name} from "../../compile/codegen"
|
||||
import {checkMetadata} from "./metadata"
|
||||
import {checkNullableObject} from "./nullable"
|
||||
import {typeError, _JTDTypeError} from "./error"
|
||||
|
||||
export type JTDValuesError = _JTDTypeError<"values", "object", SchemaObject>
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "values",
|
||||
schemaType: "object",
|
||||
error: typeError("object"),
|
||||
code(cxt: KeywordCxt) {
|
||||
checkMetadata(cxt)
|
||||
const {gen, data, schema, it} = cxt
|
||||
const [valid, cond] = checkNullableObject(cxt, data)
|
||||
if (alwaysValidSchema(it, schema)) {
|
||||
gen.if(not(or(cond, valid)), () => cxt.error())
|
||||
} else {
|
||||
gen.if(cond)
|
||||
gen.assign(valid, validateMap())
|
||||
gen.elseIf(not(valid))
|
||||
cxt.error()
|
||||
gen.endIf()
|
||||
}
|
||||
cxt.ok(valid)
|
||||
|
||||
function validateMap(): Name | boolean {
|
||||
const _valid = gen.name("valid")
|
||||
if (it.allErrors) {
|
||||
const validMap = gen.let("valid", true)
|
||||
validateValues(() => gen.assign(validMap, false))
|
||||
return validMap
|
||||
}
|
||||
gen.var(_valid, true)
|
||||
validateValues(() => gen.break())
|
||||
return _valid
|
||||
|
||||
function validateValues(notValid: () => void): void {
|
||||
gen.forIn("key", data, (key) => {
|
||||
cxt.subschema(
|
||||
{
|
||||
keyword: "values",
|
||||
dataProp: key,
|
||||
dataPropType: Type.Str,
|
||||
},
|
||||
_valid
|
||||
)
|
||||
gen.if(not(_valid), notValid)
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
17
my-app/node_modules/ajv/lib/vocabularies/metadata.ts
generated
vendored
Executable file
17
my-app/node_modules/ajv/lib/vocabularies/metadata.ts
generated
vendored
Executable file
|
@ -0,0 +1,17 @@
|
|||
import type {Vocabulary} from "../types"
|
||||
|
||||
export const metadataVocabulary: Vocabulary = [
|
||||
"title",
|
||||
"description",
|
||||
"default",
|
||||
"deprecated",
|
||||
"readOnly",
|
||||
"writeOnly",
|
||||
"examples",
|
||||
]
|
||||
|
||||
export const contentVocabulary: Vocabulary = [
|
||||
"contentMediaType",
|
||||
"contentEncoding",
|
||||
"contentSchema",
|
||||
]
|
8
my-app/node_modules/ajv/lib/vocabularies/next.ts
generated
vendored
Executable file
8
my-app/node_modules/ajv/lib/vocabularies/next.ts
generated
vendored
Executable file
|
@ -0,0 +1,8 @@
|
|||
import type {Vocabulary} from "../types"
|
||||
import dependentRequired from "./validation/dependentRequired"
|
||||
import dependentSchemas from "./applicator/dependentSchemas"
|
||||
import limitContains from "./validation/limitContains"
|
||||
|
||||
const next: Vocabulary = [dependentRequired, dependentSchemas, limitContains]
|
||||
|
||||
export default next
|
7
my-app/node_modules/ajv/lib/vocabularies/unevaluated/index.ts
generated
vendored
Executable file
7
my-app/node_modules/ajv/lib/vocabularies/unevaluated/index.ts
generated
vendored
Executable file
|
@ -0,0 +1,7 @@
|
|||
import type {Vocabulary} from "../../types"
|
||||
import unevaluatedProperties from "./unevaluatedProperties"
|
||||
import unevaluatedItems from "./unevaluatedItems"
|
||||
|
||||
const unevaluated: Vocabulary = [unevaluatedProperties, unevaluatedItems]
|
||||
|
||||
export default unevaluated
|
47
my-app/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedItems.ts
generated
vendored
Executable file
47
my-app/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedItems.ts
generated
vendored
Executable file
|
@ -0,0 +1,47 @@
|
|||
import type {
|
||||
CodeKeywordDefinition,
|
||||
ErrorObject,
|
||||
KeywordErrorDefinition,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, not, Name} from "../../compile/codegen"
|
||||
import {alwaysValidSchema, Type} from "../../compile/util"
|
||||
|
||||
export type UnevaluatedItemsError = ErrorObject<"unevaluatedItems", {limit: number}, AnySchema>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({params: {len}}) => str`must NOT have more than ${len} items`,
|
||||
params: ({params: {len}}) => _`{limit: ${len}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "unevaluatedItems",
|
||||
type: "array",
|
||||
schemaType: ["boolean", "object"],
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, schema, data, it} = cxt
|
||||
const items = it.items || 0
|
||||
if (items === true) return
|
||||
const len = gen.const("len", _`${data}.length`)
|
||||
if (schema === false) {
|
||||
cxt.setParams({len: items})
|
||||
cxt.fail(_`${len} > ${items}`)
|
||||
} else if (typeof schema == "object" && !alwaysValidSchema(it, schema)) {
|
||||
const valid = gen.var("valid", _`${len} <= ${items}`)
|
||||
gen.if(not(valid), () => validateItems(valid, items))
|
||||
cxt.ok(valid)
|
||||
}
|
||||
it.items = true
|
||||
|
||||
function validateItems(valid: Name, from: Name | number): void {
|
||||
gen.forRange("i", from, len, (i) => {
|
||||
cxt.subschema({keyword: "unevaluatedItems", dataProp: i, dataPropType: Type.Num}, valid)
|
||||
if (!it.allErrors) gen.if(not(valid), () => gen.break())
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
85
my-app/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedProperties.ts
generated
vendored
Executable file
85
my-app/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedProperties.ts
generated
vendored
Executable file
|
@ -0,0 +1,85 @@
|
|||
import type {
|
||||
CodeKeywordDefinition,
|
||||
KeywordErrorDefinition,
|
||||
ErrorObject,
|
||||
AnySchema,
|
||||
} from "../../types"
|
||||
import {_, not, and, Name, Code} from "../../compile/codegen"
|
||||
import {alwaysValidSchema, Type} from "../../compile/util"
|
||||
import N from "../../compile/names"
|
||||
|
||||
export type UnevaluatedPropertiesError = ErrorObject<
|
||||
"unevaluatedProperties",
|
||||
{unevaluatedProperty: string},
|
||||
AnySchema
|
||||
>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: "must NOT have unevaluated properties",
|
||||
params: ({params}) => _`{unevaluatedProperty: ${params.unevaluatedProperty}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "unevaluatedProperties",
|
||||
type: "object",
|
||||
schemaType: ["boolean", "object"],
|
||||
trackErrors: true,
|
||||
error,
|
||||
code(cxt) {
|
||||
const {gen, schema, data, errsCount, it} = cxt
|
||||
/* istanbul ignore if */
|
||||
if (!errsCount) throw new Error("ajv implementation error")
|
||||
const {allErrors, props} = it
|
||||
if (props instanceof Name) {
|
||||
gen.if(_`${props} !== true`, () =>
|
||||
gen.forIn("key", data, (key: Name) =>
|
||||
gen.if(unevaluatedDynamic(props, key), () => unevaluatedPropCode(key))
|
||||
)
|
||||
)
|
||||
} else if (props !== true) {
|
||||
gen.forIn("key", data, (key: Name) =>
|
||||
props === undefined
|
||||
? unevaluatedPropCode(key)
|
||||
: gen.if(unevaluatedStatic(props, key), () => unevaluatedPropCode(key))
|
||||
)
|
||||
}
|
||||
it.props = true
|
||||
cxt.ok(_`${errsCount} === ${N.errors}`)
|
||||
|
||||
function unevaluatedPropCode(key: Name): void {
|
||||
if (schema === false) {
|
||||
cxt.setParams({unevaluatedProperty: key})
|
||||
cxt.error()
|
||||
if (!allErrors) gen.break()
|
||||
return
|
||||
}
|
||||
|
||||
if (!alwaysValidSchema(it, schema)) {
|
||||
const valid = gen.name("valid")
|
||||
cxt.subschema(
|
||||
{
|
||||
keyword: "unevaluatedProperties",
|
||||
dataProp: key,
|
||||
dataPropType: Type.Str,
|
||||
},
|
||||
valid
|
||||
)
|
||||
if (!allErrors) gen.if(not(valid), () => gen.break())
|
||||
}
|
||||
}
|
||||
|
||||
function unevaluatedDynamic(evaluatedProps: Name, key: Name): Code {
|
||||
return _`!${evaluatedProps} || !${evaluatedProps}[${key}]`
|
||||
}
|
||||
|
||||
function unevaluatedStatic(evaluatedProps: {[K in string]?: true}, key: Name): Code {
|
||||
const ps: Code[] = []
|
||||
for (const p in evaluatedProps) {
|
||||
if (evaluatedProps[p] === true) ps.push(_`${key} !== ${p}`)
|
||||
}
|
||||
return and(...ps)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
28
my-app/node_modules/ajv/lib/vocabularies/validation/const.ts
generated
vendored
Executable file
28
my-app/node_modules/ajv/lib/vocabularies/validation/const.ts
generated
vendored
Executable file
|
@ -0,0 +1,28 @@
|
|||
import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_} from "../../compile/codegen"
|
||||
import {useFunc} from "../../compile/util"
|
||||
import equal from "../../runtime/equal"
|
||||
|
||||
export type ConstError = ErrorObject<"const", {allowedValue: any}>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: "must be equal to constant",
|
||||
params: ({schemaCode}) => _`{allowedValue: ${schemaCode}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "const",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, data, $data, schemaCode, schema} = cxt
|
||||
if ($data || (schema && typeof schema == "object")) {
|
||||
cxt.fail$data(_`!${useFunc(gen, equal)}(${data}, ${schemaCode})`)
|
||||
} else {
|
||||
cxt.fail(_`${schema} !== ${data}`)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
23
my-app/node_modules/ajv/lib/vocabularies/validation/dependentRequired.ts
generated
vendored
Executable file
23
my-app/node_modules/ajv/lib/vocabularies/validation/dependentRequired.ts
generated
vendored
Executable file
|
@ -0,0 +1,23 @@
|
|||
import type {CodeKeywordDefinition, ErrorObject} from "../../types"
|
||||
import {
|
||||
validatePropertyDeps,
|
||||
error,
|
||||
DependenciesErrorParams,
|
||||
PropertyDependencies,
|
||||
} from "../applicator/dependencies"
|
||||
|
||||
export type DependentRequiredError = ErrorObject<
|
||||
"dependentRequired",
|
||||
DependenciesErrorParams,
|
||||
PropertyDependencies
|
||||
>
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "dependentRequired",
|
||||
type: "object",
|
||||
schemaType: "object",
|
||||
error,
|
||||
code: (cxt) => validatePropertyDeps(cxt),
|
||||
}
|
||||
|
||||
export default def
|
54
my-app/node_modules/ajv/lib/vocabularies/validation/enum.ts
generated
vendored
Executable file
54
my-app/node_modules/ajv/lib/vocabularies/validation/enum.ts
generated
vendored
Executable file
|
@ -0,0 +1,54 @@
|
|||
import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, or, Name, Code} from "../../compile/codegen"
|
||||
import {useFunc} from "../../compile/util"
|
||||
import equal from "../../runtime/equal"
|
||||
|
||||
export type EnumError = ErrorObject<"enum", {allowedValues: any[]}, any[] | {$data: string}>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: "must be equal to one of the allowed values",
|
||||
params: ({schemaCode}) => _`{allowedValues: ${schemaCode}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "enum",
|
||||
schemaType: "array",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, data, $data, schema, schemaCode, it} = cxt
|
||||
if (!$data && schema.length === 0) throw new Error("enum must have non-empty array")
|
||||
const useLoop = schema.length >= it.opts.loopEnum
|
||||
let eql: Name | undefined
|
||||
const getEql = (): Name => (eql ??= useFunc(gen, equal))
|
||||
|
||||
let valid: Code
|
||||
if (useLoop || $data) {
|
||||
valid = gen.let("valid")
|
||||
cxt.block$data(valid, loopEnum)
|
||||
} else {
|
||||
/* istanbul ignore if */
|
||||
if (!Array.isArray(schema)) throw new Error("ajv implementation error")
|
||||
const vSchema = gen.const("vSchema", schemaCode)
|
||||
valid = or(...schema.map((_x: unknown, i: number) => equalCode(vSchema, i)))
|
||||
}
|
||||
cxt.pass(valid)
|
||||
|
||||
function loopEnum(): void {
|
||||
gen.assign(valid, false)
|
||||
gen.forOf("v", schemaCode as Code, (v) =>
|
||||
gen.if(_`${getEql()}(${data}, ${v})`, () => gen.assign(valid, true).break())
|
||||
)
|
||||
}
|
||||
|
||||
function equalCode(vSchema: Name, i: number): Code {
|
||||
const sch = schema[i]
|
||||
return typeof sch === "object" && sch !== null
|
||||
? _`${getEql()}(${data}, ${vSchema}[${i}])`
|
||||
: _`${data} === ${sch}`
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
49
my-app/node_modules/ajv/lib/vocabularies/validation/index.ts
generated
vendored
Executable file
49
my-app/node_modules/ajv/lib/vocabularies/validation/index.ts
generated
vendored
Executable file
|
@ -0,0 +1,49 @@
|
|||
import type {ErrorObject, Vocabulary} from "../../types"
|
||||
import limitNumber, {LimitNumberError} from "./limitNumber"
|
||||
import multipleOf, {MultipleOfError} from "./multipleOf"
|
||||
import limitLength from "./limitLength"
|
||||
import pattern, {PatternError} from "./pattern"
|
||||
import limitProperties from "./limitProperties"
|
||||
import required, {RequiredError} from "./required"
|
||||
import limitItems from "./limitItems"
|
||||
import uniqueItems, {UniqueItemsError} from "./uniqueItems"
|
||||
import constKeyword, {ConstError} from "./const"
|
||||
import enumKeyword, {EnumError} from "./enum"
|
||||
|
||||
const validation: Vocabulary = [
|
||||
// number
|
||||
limitNumber,
|
||||
multipleOf,
|
||||
// string
|
||||
limitLength,
|
||||
pattern,
|
||||
// object
|
||||
limitProperties,
|
||||
required,
|
||||
// array
|
||||
limitItems,
|
||||
uniqueItems,
|
||||
// any
|
||||
{keyword: "type", schemaType: ["string", "array"]},
|
||||
{keyword: "nullable", schemaType: "boolean"},
|
||||
constKeyword,
|
||||
enumKeyword,
|
||||
]
|
||||
|
||||
export default validation
|
||||
|
||||
type LimitError = ErrorObject<
|
||||
"maxItems" | "minItems" | "minProperties" | "maxProperties" | "minLength" | "maxLength",
|
||||
{limit: number},
|
||||
number | {$data: string}
|
||||
>
|
||||
|
||||
export type ValidationKeywordError =
|
||||
| LimitError
|
||||
| LimitNumberError
|
||||
| MultipleOfError
|
||||
| PatternError
|
||||
| RequiredError
|
||||
| UniqueItemsError
|
||||
| ConstError
|
||||
| EnumError
|
16
my-app/node_modules/ajv/lib/vocabularies/validation/limitContains.ts
generated
vendored
Executable file
16
my-app/node_modules/ajv/lib/vocabularies/validation/limitContains.ts
generated
vendored
Executable file
|
@ -0,0 +1,16 @@
|
|||
import type {CodeKeywordDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {checkStrictMode} from "../../compile/util"
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: ["maxContains", "minContains"],
|
||||
type: "array",
|
||||
schemaType: "number",
|
||||
code({keyword, parentSchema, it}: KeywordCxt) {
|
||||
if (parentSchema.contains === undefined) {
|
||||
checkStrictMode(it, `"${keyword}" without "contains" is ignored`)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
26
my-app/node_modules/ajv/lib/vocabularies/validation/limitItems.ts
generated
vendored
Executable file
26
my-app/node_modules/ajv/lib/vocabularies/validation/limitItems.ts
generated
vendored
Executable file
|
@ -0,0 +1,26 @@
|
|||
import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, operators} from "../../compile/codegen"
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message({keyword, schemaCode}) {
|
||||
const comp = keyword === "maxItems" ? "more" : "fewer"
|
||||
return str`must NOT have ${comp} than ${schemaCode} items`
|
||||
},
|
||||
params: ({schemaCode}) => _`{limit: ${schemaCode}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: ["maxItems", "minItems"],
|
||||
type: "array",
|
||||
schemaType: "number",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {keyword, data, schemaCode} = cxt
|
||||
const op = keyword === "maxItems" ? operators.GT : operators.LT
|
||||
cxt.fail$data(_`${data}.length ${op} ${schemaCode}`)
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
30
my-app/node_modules/ajv/lib/vocabularies/validation/limitLength.ts
generated
vendored
Executable file
30
my-app/node_modules/ajv/lib/vocabularies/validation/limitLength.ts
generated
vendored
Executable file
|
@ -0,0 +1,30 @@
|
|||
import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, operators} from "../../compile/codegen"
|
||||
import {useFunc} from "../../compile/util"
|
||||
import ucs2length from "../../runtime/ucs2length"
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message({keyword, schemaCode}) {
|
||||
const comp = keyword === "maxLength" ? "more" : "fewer"
|
||||
return str`must NOT have ${comp} than ${schemaCode} characters`
|
||||
},
|
||||
params: ({schemaCode}) => _`{limit: ${schemaCode}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: ["maxLength", "minLength"],
|
||||
type: "string",
|
||||
schemaType: "number",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {keyword, data, schemaCode, it} = cxt
|
||||
const op = keyword === "maxLength" ? operators.GT : operators.LT
|
||||
const len =
|
||||
it.opts.unicode === false ? _`${data}.length` : _`${useFunc(cxt.gen, ucs2length)}(${data})`
|
||||
cxt.fail$data(_`${len} ${op} ${schemaCode}`)
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
42
my-app/node_modules/ajv/lib/vocabularies/validation/limitNumber.ts
generated
vendored
Executable file
42
my-app/node_modules/ajv/lib/vocabularies/validation/limitNumber.ts
generated
vendored
Executable file
|
@ -0,0 +1,42 @@
|
|||
import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, operators, Code} from "../../compile/codegen"
|
||||
|
||||
const ops = operators
|
||||
|
||||
type Kwd = "maximum" | "minimum" | "exclusiveMaximum" | "exclusiveMinimum"
|
||||
|
||||
type Comparison = "<=" | ">=" | "<" | ">"
|
||||
|
||||
const KWDs: {[K in Kwd]: {okStr: Comparison; ok: Code; fail: Code}} = {
|
||||
maximum: {okStr: "<=", ok: ops.LTE, fail: ops.GT},
|
||||
minimum: {okStr: ">=", ok: ops.GTE, fail: ops.LT},
|
||||
exclusiveMaximum: {okStr: "<", ok: ops.LT, fail: ops.GTE},
|
||||
exclusiveMinimum: {okStr: ">", ok: ops.GT, fail: ops.LTE},
|
||||
}
|
||||
|
||||
export type LimitNumberError = ErrorObject<
|
||||
Kwd,
|
||||
{limit: number; comparison: Comparison},
|
||||
number | {$data: string}
|
||||
>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({keyword, schemaCode}) => str`must be ${KWDs[keyword as Kwd].okStr} ${schemaCode}`,
|
||||
params: ({keyword, schemaCode}) =>
|
||||
_`{comparison: ${KWDs[keyword as Kwd].okStr}, limit: ${schemaCode}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: Object.keys(KWDs),
|
||||
type: "number",
|
||||
schemaType: "number",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {keyword, data, schemaCode} = cxt
|
||||
cxt.fail$data(_`${data} ${KWDs[keyword as Kwd].fail} ${schemaCode} || isNaN(${data})`)
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
26
my-app/node_modules/ajv/lib/vocabularies/validation/limitProperties.ts
generated
vendored
Executable file
26
my-app/node_modules/ajv/lib/vocabularies/validation/limitProperties.ts
generated
vendored
Executable file
|
@ -0,0 +1,26 @@
|
|||
import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str, operators} from "../../compile/codegen"
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message({keyword, schemaCode}) {
|
||||
const comp = keyword === "maxProperties" ? "more" : "fewer"
|
||||
return str`must NOT have ${comp} than ${schemaCode} properties`
|
||||
},
|
||||
params: ({schemaCode}) => _`{limit: ${schemaCode}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: ["maxProperties", "minProperties"],
|
||||
type: "object",
|
||||
schemaType: "number",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {keyword, data, schemaCode} = cxt
|
||||
const op = keyword === "maxProperties" ? operators.GT : operators.LT
|
||||
cxt.fail$data(_`Object.keys(${data}).length ${op} ${schemaCode}`)
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
34
my-app/node_modules/ajv/lib/vocabularies/validation/multipleOf.ts
generated
vendored
Executable file
34
my-app/node_modules/ajv/lib/vocabularies/validation/multipleOf.ts
generated
vendored
Executable file
|
@ -0,0 +1,34 @@
|
|||
import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {_, str} from "../../compile/codegen"
|
||||
|
||||
export type MultipleOfError = ErrorObject<
|
||||
"multipleOf",
|
||||
{multipleOf: number},
|
||||
number | {$data: string}
|
||||
>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({schemaCode}) => str`must be multiple of ${schemaCode}`,
|
||||
params: ({schemaCode}) => _`{multipleOf: ${schemaCode}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "multipleOf",
|
||||
type: "number",
|
||||
schemaType: "number",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, data, schemaCode, it} = cxt
|
||||
// const bdt = bad$DataType(schemaCode, <string>def.schemaType, $data)
|
||||
const prec = it.opts.multipleOfPrecision
|
||||
const res = gen.let("res")
|
||||
const invalid = prec
|
||||
? _`Math.abs(Math.round(${res}) - ${res}) > 1e-${prec}`
|
||||
: _`${res} !== parseInt(${res})`
|
||||
cxt.fail$data(_`(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${invalid}))`)
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
28
my-app/node_modules/ajv/lib/vocabularies/validation/pattern.ts
generated
vendored
Executable file
28
my-app/node_modules/ajv/lib/vocabularies/validation/pattern.ts
generated
vendored
Executable file
|
@ -0,0 +1,28 @@
|
|||
import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {usePattern} from "../code"
|
||||
import {_, str} from "../../compile/codegen"
|
||||
|
||||
export type PatternError = ErrorObject<"pattern", {pattern: string}, string | {$data: string}>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({schemaCode}) => str`must match pattern "${schemaCode}"`,
|
||||
params: ({schemaCode}) => _`{pattern: ${schemaCode}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "pattern",
|
||||
type: "string",
|
||||
schemaType: "string",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {data, $data, schema, schemaCode, it} = cxt
|
||||
// TODO regexp should be wrapped in try/catchs
|
||||
const u = it.opts.unicodeRegExp ? "u" : ""
|
||||
const regExp = $data ? _`(new RegExp(${schemaCode}, ${u}))` : usePattern(cxt, schema)
|
||||
cxt.fail$data(_`!${regExp}.test(${data})`)
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
98
my-app/node_modules/ajv/lib/vocabularies/validation/required.ts
generated
vendored
Executable file
98
my-app/node_modules/ajv/lib/vocabularies/validation/required.ts
generated
vendored
Executable file
|
@ -0,0 +1,98 @@
|
|||
import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {
|
||||
checkReportMissingProp,
|
||||
checkMissingProp,
|
||||
reportMissingProp,
|
||||
propertyInData,
|
||||
noPropertyInData,
|
||||
} from "../code"
|
||||
import {_, str, nil, not, Name, Code} from "../../compile/codegen"
|
||||
import {checkStrictMode} from "../../compile/util"
|
||||
|
||||
export type RequiredError = ErrorObject<
|
||||
"required",
|
||||
{missingProperty: string},
|
||||
string[] | {$data: string}
|
||||
>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({params: {missingProperty}}) => str`must have required property '${missingProperty}'`,
|
||||
params: ({params: {missingProperty}}) => _`{missingProperty: ${missingProperty}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "required",
|
||||
type: "object",
|
||||
schemaType: "array",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, schema, schemaCode, data, $data, it} = cxt
|
||||
const {opts} = it
|
||||
if (!$data && schema.length === 0) return
|
||||
const useLoop = schema.length >= opts.loopRequired
|
||||
if (it.allErrors) allErrorsMode()
|
||||
else exitOnErrorMode()
|
||||
|
||||
if (opts.strictRequired) {
|
||||
const props = cxt.parentSchema.properties
|
||||
const {definedProperties} = cxt.it
|
||||
for (const requiredKey of schema) {
|
||||
if (props?.[requiredKey] === undefined && !definedProperties.has(requiredKey)) {
|
||||
const schemaPath = it.schemaEnv.baseId + it.errSchemaPath
|
||||
const msg = `required property "${requiredKey}" is not defined at "${schemaPath}" (strictRequired)`
|
||||
checkStrictMode(it, msg, it.opts.strictRequired)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function allErrorsMode(): void {
|
||||
if (useLoop || $data) {
|
||||
cxt.block$data(nil, loopAllRequired)
|
||||
} else {
|
||||
for (const prop of schema) {
|
||||
checkReportMissingProp(cxt, prop)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function exitOnErrorMode(): void {
|
||||
const missing = gen.let("missing")
|
||||
if (useLoop || $data) {
|
||||
const valid = gen.let("valid", true)
|
||||
cxt.block$data(valid, () => loopUntilMissing(missing, valid))
|
||||
cxt.ok(valid)
|
||||
} else {
|
||||
gen.if(checkMissingProp(cxt, schema, missing))
|
||||
reportMissingProp(cxt, missing)
|
||||
gen.else()
|
||||
}
|
||||
}
|
||||
|
||||
function loopAllRequired(): void {
|
||||
gen.forOf("prop", schemaCode as Code, (prop) => {
|
||||
cxt.setParams({missingProperty: prop})
|
||||
gen.if(noPropertyInData(gen, data, prop, opts.ownProperties), () => cxt.error())
|
||||
})
|
||||
}
|
||||
|
||||
function loopUntilMissing(missing: Name, valid: Name): void {
|
||||
cxt.setParams({missingProperty: missing})
|
||||
gen.forOf(
|
||||
missing,
|
||||
schemaCode as Code,
|
||||
() => {
|
||||
gen.assign(valid, propertyInData(gen, data, missing, opts.ownProperties))
|
||||
gen.if(not(valid), () => {
|
||||
cxt.error()
|
||||
gen.break()
|
||||
})
|
||||
},
|
||||
nil
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
79
my-app/node_modules/ajv/lib/vocabularies/validation/uniqueItems.ts
generated
vendored
Executable file
79
my-app/node_modules/ajv/lib/vocabularies/validation/uniqueItems.ts
generated
vendored
Executable file
|
@ -0,0 +1,79 @@
|
|||
import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
|
||||
import type {KeywordCxt} from "../../compile/validate"
|
||||
import {checkDataTypes, getSchemaTypes, DataType} from "../../compile/validate/dataType"
|
||||
import {_, str, Name} from "../../compile/codegen"
|
||||
import {useFunc} from "../../compile/util"
|
||||
import equal from "../../runtime/equal"
|
||||
|
||||
export type UniqueItemsError = ErrorObject<
|
||||
"uniqueItems",
|
||||
{i: number; j: number},
|
||||
boolean | {$data: string}
|
||||
>
|
||||
|
||||
const error: KeywordErrorDefinition = {
|
||||
message: ({params: {i, j}}) =>
|
||||
str`must NOT have duplicate items (items ## ${j} and ${i} are identical)`,
|
||||
params: ({params: {i, j}}) => _`{i: ${i}, j: ${j}}`,
|
||||
}
|
||||
|
||||
const def: CodeKeywordDefinition = {
|
||||
keyword: "uniqueItems",
|
||||
type: "array",
|
||||
schemaType: "boolean",
|
||||
$data: true,
|
||||
error,
|
||||
code(cxt: KeywordCxt) {
|
||||
const {gen, data, $data, schema, parentSchema, schemaCode, it} = cxt
|
||||
if (!$data && !schema) return
|
||||
const valid = gen.let("valid")
|
||||
const itemTypes = parentSchema.items ? getSchemaTypes(parentSchema.items) : []
|
||||
cxt.block$data(valid, validateUniqueItems, _`${schemaCode} === false`)
|
||||
cxt.ok(valid)
|
||||
|
||||
function validateUniqueItems(): void {
|
||||
const i = gen.let("i", _`${data}.length`)
|
||||
const j = gen.let("j")
|
||||
cxt.setParams({i, j})
|
||||
gen.assign(valid, true)
|
||||
gen.if(_`${i} > 1`, () => (canOptimize() ? loopN : loopN2)(i, j))
|
||||
}
|
||||
|
||||
function canOptimize(): boolean {
|
||||
return itemTypes.length > 0 && !itemTypes.some((t) => t === "object" || t === "array")
|
||||
}
|
||||
|
||||
function loopN(i: Name, j: Name): void {
|
||||
const item = gen.name("item")
|
||||
const wrongType = checkDataTypes(itemTypes, item, it.opts.strictNumbers, DataType.Wrong)
|
||||
const indices = gen.const("indices", _`{}`)
|
||||
gen.for(_`;${i}--;`, () => {
|
||||
gen.let(item, _`${data}[${i}]`)
|
||||
gen.if(wrongType, _`continue`)
|
||||
if (itemTypes.length > 1) gen.if(_`typeof ${item} == "string"`, _`${item} += "_"`)
|
||||
gen
|
||||
.if(_`typeof ${indices}[${item}] == "number"`, () => {
|
||||
gen.assign(j, _`${indices}[${item}]`)
|
||||
cxt.error()
|
||||
gen.assign(valid, false).break()
|
||||
})
|
||||
.code(_`${indices}[${item}] = ${i}`)
|
||||
})
|
||||
}
|
||||
|
||||
function loopN2(i: Name, j: Name): void {
|
||||
const eql = useFunc(gen, equal)
|
||||
const outer = gen.name("outer")
|
||||
gen.label(outer).for(_`;${i}--;`, () =>
|
||||
gen.for(_`${j} = ${i}; ${j}--;`, () =>
|
||||
gen.if(_`${eql}(${data}[${i}], ${data}[${j}])`, () => {
|
||||
cxt.error()
|
||||
gen.assign(valid, false).break(outer)
|
||||
})
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default def
|
Loading…
Add table
Add a link
Reference in a new issue