From 6555fb80fdd8f6a5d201efadec3189d1244830a0 Mon Sep 17 00:00:00 2001 From: Nevena Bojovic Date: Tue, 1 Mar 2022 22:05:25 +0100 Subject: Izbrisala bin, obj i node-modules. --- .../ajv/lib/compile/validate/applicability.ts | 22 - .../ajv/lib/compile/validate/boolSchema.ts | 47 -- .../ajv/lib/compile/validate/dataType.ts | 229 -------- .../ajv/lib/compile/validate/defaults.ts | 32 -- .../node_modules/ajv/lib/compile/validate/index.ts | 573 --------------------- .../ajv/lib/compile/validate/keyword.ts | 171 ------ .../ajv/lib/compile/validate/subschema.ts | 135 ----- 7 files changed, 1209 deletions(-) delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/applicability.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/boolSchema.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/dataType.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/defaults.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/index.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/keyword.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/subschema.ts (limited to 'sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate') diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/applicability.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/applicability.ts deleted file mode 100644 index 478b704a..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/applicability.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type {AnySchemaObject} from "../../types" -import type {SchemaObjCxt} from ".." -import type {JSONType, RuleGroup, Rule} from "../rules" - -export function schemaHasRulesForType( - {schema, self}: SchemaObjCxt, - type: JSONType -): boolean | undefined { - const group = self.RULES.types[type] - return group && group !== true && shouldUseGroup(schema, group) -} - -export function shouldUseGroup(schema: AnySchemaObject, group: RuleGroup): boolean { - return group.rules.some((rule) => shouldUseRule(schema, rule)) -} - -export function shouldUseRule(schema: AnySchemaObject, rule: Rule): boolean | undefined { - return ( - schema[rule.keyword] !== undefined || - rule.definition.implements?.some((kwd) => schema[kwd] !== undefined) - ) -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/boolSchema.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/boolSchema.ts deleted file mode 100644 index 15635501..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/boolSchema.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type {KeywordErrorDefinition, KeywordErrorCxt} from "../../types" -import type {SchemaCxt} from ".." -import {reportError} from "../errors" -import {_, Name} from "../codegen" -import N from "../names" - -const boolError: KeywordErrorDefinition = { - message: "boolean schema is false", -} - -export function topBoolOrEmptySchema(it: SchemaCxt): void { - const {gen, schema, validateName} = it - if (schema === false) { - falseSchemaError(it, false) - } else if (typeof schema == "object" && schema.$async === true) { - gen.return(N.data) - } else { - gen.assign(_`${validateName}.errors`, null) - gen.return(true) - } -} - -export function boolOrEmptySchema(it: SchemaCxt, valid: Name): void { - const {gen, schema} = it - if (schema === false) { - gen.var(valid, false) // TODO var - falseSchemaError(it) - } else { - gen.var(valid, true) // TODO var - } -} - -function falseSchemaError(it: SchemaCxt, overrideAllErrors?: boolean): void { - const {gen, data} = it - // TODO maybe some other interface should be used for non-keyword validation errors... - const cxt: KeywordErrorCxt = { - gen, - keyword: "false schema", - data, - schema: false, - schemaCode: false, - schemaValue: false, - params: {}, - it, - } - reportError(cxt, boolError, undefined, overrideAllErrors) -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/dataType.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/dataType.ts deleted file mode 100644 index b315c2ce..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/dataType.ts +++ /dev/null @@ -1,229 +0,0 @@ -import type { - KeywordErrorDefinition, - KeywordErrorCxt, - ErrorObject, - AnySchemaObject, -} from "../../types" -import type {SchemaObjCxt} from ".." -import {isJSONType, JSONType} from "../rules" -import {schemaHasRulesForType} from "./applicability" -import {reportError} from "../errors" -import {_, nil, and, not, operators, Code, Name} from "../codegen" -import {toHash, schemaRefOrVal} from "../util" - -export enum DataType { - Correct, - Wrong, -} - -export function getSchemaTypes(schema: AnySchemaObject): JSONType[] { - const types = getJSONTypes(schema.type) - const hasNull = types.includes("null") - if (hasNull) { - if (schema.nullable === false) throw new Error("type: null contradicts nullable: false") - } else { - if (!types.length && schema.nullable !== undefined) { - throw new Error('"nullable" cannot be used without "type"') - } - if (schema.nullable === true) types.push("null") - } - return types -} - -export function getJSONTypes(ts: unknown | unknown[]): JSONType[] { - const types: unknown[] = Array.isArray(ts) ? ts : ts ? [ts] : [] - if (types.every(isJSONType)) return types - throw new Error("type must be JSONType or JSONType[]: " + types.join(",")) -} - -export function coerceAndCheckDataType(it: SchemaObjCxt, types: JSONType[]): boolean { - const {gen, data, opts} = it - const coerceTo = coerceToTypes(types, opts.coerceTypes) - const checkTypes = - types.length > 0 && - !(coerceTo.length === 0 && types.length === 1 && schemaHasRulesForType(it, types[0])) - if (checkTypes) { - const wrongType = checkDataTypes(types, data, opts.strictNumbers, DataType.Wrong) - gen.if(wrongType, () => { - if (coerceTo.length) coerceData(it, types, coerceTo) - else reportTypeError(it) - }) - } - return checkTypes -} - -const COERCIBLE: Set = new Set(["string", "number", "integer", "boolean", "null"]) -function coerceToTypes(types: JSONType[], coerceTypes?: boolean | "array"): JSONType[] { - return coerceTypes - ? types.filter((t) => COERCIBLE.has(t) || (coerceTypes === "array" && t === "array")) - : [] -} - -function coerceData(it: SchemaObjCxt, types: JSONType[], coerceTo: JSONType[]): void { - const {gen, data, opts} = it - const dataType = gen.let("dataType", _`typeof ${data}`) - const coerced = gen.let("coerced", _`undefined`) - if (opts.coerceTypes === "array") { - gen.if(_`${dataType} == 'object' && Array.isArray(${data}) && ${data}.length == 1`, () => - gen - .assign(data, _`${data}[0]`) - .assign(dataType, _`typeof ${data}`) - .if(checkDataTypes(types, data, opts.strictNumbers), () => gen.assign(coerced, data)) - ) - } - gen.if(_`${coerced} !== undefined`) - for (const t of coerceTo) { - if (COERCIBLE.has(t) || (t === "array" && opts.coerceTypes === "array")) { - coerceSpecificType(t) - } - } - gen.else() - reportTypeError(it) - gen.endIf() - - gen.if(_`${coerced} !== undefined`, () => { - gen.assign(data, coerced) - assignParentData(it, coerced) - }) - - function coerceSpecificType(t: string): void { - switch (t) { - case "string": - gen - .elseIf(_`${dataType} == "number" || ${dataType} == "boolean"`) - .assign(coerced, _`"" + ${data}`) - .elseIf(_`${data} === null`) - .assign(coerced, _`""`) - return - case "number": - gen - .elseIf( - _`${dataType} == "boolean" || ${data} === null - || (${dataType} == "string" && ${data} && ${data} == +${data})` - ) - .assign(coerced, _`+${data}`) - return - case "integer": - gen - .elseIf( - _`${dataType} === "boolean" || ${data} === null - || (${dataType} === "string" && ${data} && ${data} == +${data} && !(${data} % 1))` - ) - .assign(coerced, _`+${data}`) - return - case "boolean": - gen - .elseIf(_`${data} === "false" || ${data} === 0 || ${data} === null`) - .assign(coerced, false) - .elseIf(_`${data} === "true" || ${data} === 1`) - .assign(coerced, true) - return - case "null": - gen.elseIf(_`${data} === "" || ${data} === 0 || ${data} === false`) - gen.assign(coerced, null) - return - - case "array": - gen - .elseIf( - _`${dataType} === "string" || ${dataType} === "number" - || ${dataType} === "boolean" || ${data} === null` - ) - .assign(coerced, _`[${data}]`) - } - } -} - -function assignParentData({gen, parentData, parentDataProperty}: SchemaObjCxt, expr: Name): void { - // TODO use gen.property - gen.if(_`${parentData} !== undefined`, () => - gen.assign(_`${parentData}[${parentDataProperty}]`, expr) - ) -} - -export function checkDataType( - dataType: JSONType, - data: Name, - strictNums?: boolean | "log", - correct = DataType.Correct -): Code { - const EQ = correct === DataType.Correct ? operators.EQ : operators.NEQ - let cond: Code - switch (dataType) { - case "null": - return _`${data} ${EQ} null` - case "array": - cond = _`Array.isArray(${data})` - break - case "object": - cond = _`${data} && typeof ${data} == "object" && !Array.isArray(${data})` - break - case "integer": - cond = numCond(_`!(${data} % 1) && !isNaN(${data})`) - break - case "number": - cond = numCond() - break - default: - return _`typeof ${data} ${EQ} ${dataType}` - } - return correct === DataType.Correct ? cond : not(cond) - - function numCond(_cond: Code = nil): Code { - return and(_`typeof ${data} == "number"`, _cond, strictNums ? _`isFinite(${data})` : nil) - } -} - -export function checkDataTypes( - dataTypes: JSONType[], - data: Name, - strictNums?: boolean | "log", - correct?: DataType -): Code { - if (dataTypes.length === 1) { - return checkDataType(dataTypes[0], data, strictNums, correct) - } - let cond: Code - const types = toHash(dataTypes) - if (types.array && types.object) { - const notObj = _`typeof ${data} != "object"` - cond = types.null ? notObj : _`!${data} || ${notObj}` - delete types.null - delete types.array - delete types.object - } else { - cond = nil - } - if (types.number) delete types.integer - for (const t in types) cond = and(cond, checkDataType(t as JSONType, data, strictNums, correct)) - return cond -} - -export type TypeError = ErrorObject<"type", {type: string}> - -const typeError: KeywordErrorDefinition = { - message: ({schema}) => `must be ${schema}`, - params: ({schema, schemaValue}) => - typeof schema == "string" ? _`{type: ${schema}}` : _`{type: ${schemaValue}}`, -} - -export function reportTypeError(it: SchemaObjCxt): void { - const cxt = getTypeErrorContext(it) - reportError(cxt, typeError) -} - -function getTypeErrorContext(it: SchemaObjCxt): KeywordErrorCxt { - const {gen, data, schema} = it - const schemaCode = schemaRefOrVal(it, schema, "type") - return { - gen, - keyword: "type", - data, - schema: schema.type, - schemaCode, - schemaValue: schemaCode, - parentSchema: schema, - params: {}, - it, - } -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/defaults.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/defaults.ts deleted file mode 100644 index 2ad3d4df..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/defaults.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type {SchemaObjCxt} from ".." -import {_, getProperty, stringify} from "../codegen" -import {checkStrictMode} from "../util" - -export function assignDefaults(it: SchemaObjCxt, ty?: string): void { - const {properties, items} = it.schema - if (ty === "object" && properties) { - for (const key in properties) { - assignDefault(it, key, properties[key].default) - } - } else if (ty === "array" && Array.isArray(items)) { - items.forEach((sch, i: number) => assignDefault(it, i, sch.default)) - } -} - -function assignDefault(it: SchemaObjCxt, prop: string | number, defaultValue: unknown): void { - const {gen, compositeRule, data, opts} = it - if (defaultValue === undefined) return - const childData = _`${data}${getProperty(prop)}` - if (compositeRule) { - checkStrictMode(it, `default is ignored for: ${childData}`) - return - } - - let condition = _`${childData} === undefined` - if (opts.useDefaults === "empty") { - condition = _`${condition} || ${childData} === null || ${childData} === ""` - } - // `${childData} === undefined` + - // (opts.useDefaults === "empty" ? ` || ${childData} === null || ${childData} === ""` : "") - gen.if(condition, _`${childData} = ${stringify(defaultValue)}`) -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/index.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/index.ts deleted file mode 100644 index 0f40584e..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/index.ts +++ /dev/null @@ -1,573 +0,0 @@ -import type { - AddedKeywordDefinition, - AnySchema, - AnySchemaObject, - KeywordErrorCxt, - KeywordCxtParams, -} from "../../types" -import type {SchemaCxt, SchemaObjCxt} from ".." -import type {InstanceOptions} from "../../core" -import {boolOrEmptySchema, topBoolOrEmptySchema} from "./boolSchema" -import {coerceAndCheckDataType, getSchemaTypes} from "./dataType" -import {shouldUseGroup, shouldUseRule} from "./applicability" -import {checkDataType, checkDataTypes, reportTypeError, DataType} from "./dataType" -import {assignDefaults} from "./defaults" -import {funcKeywordCode, macroKeywordCode, validateKeywordUsage, validSchemaType} from "./keyword" -import {getSubschema, extendSubschemaData, SubschemaArgs, extendSubschemaMode} from "./subschema" -import {_, nil, str, or, not, getProperty, Block, Code, Name, CodeGen} from "../codegen" -import N from "../names" -import {resolveUrl} from "../resolve" -import { - schemaRefOrVal, - schemaHasRulesButRef, - checkUnknownRules, - checkStrictMode, - unescapeJsonPointer, - mergeEvaluated, -} from "../util" -import type {JSONType, Rule, RuleGroup} from "../rules" -import { - ErrorPaths, - reportError, - reportExtraError, - resetErrorsCount, - keyword$DataError, -} from "../errors" - -// schema compilation - generates validation function, subschemaCode (below) is used for subschemas -export function validateFunctionCode(it: SchemaCxt): void { - if (isSchemaObj(it)) { - checkKeywords(it) - if (schemaCxtHasRules(it)) { - topSchemaObjCode(it) - return - } - } - validateFunction(it, () => topBoolOrEmptySchema(it)) -} - -function validateFunction( - {gen, validateName, schema, schemaEnv, opts}: SchemaCxt, - body: Block -): void { - if (opts.code.es5) { - gen.func(validateName, _`${N.data}, ${N.valCxt}`, schemaEnv.$async, () => { - gen.code(_`"use strict"; ${funcSourceUrl(schema, opts)}`) - destructureValCxtES5(gen, opts) - gen.code(body) - }) - } else { - gen.func(validateName, _`${N.data}, ${destructureValCxt(opts)}`, schemaEnv.$async, () => - gen.code(funcSourceUrl(schema, opts)).code(body) - ) - } -} - -function destructureValCxt(opts: InstanceOptions): Code { - return _`{${N.instancePath}="", ${N.parentData}, ${N.parentDataProperty}, ${N.rootData}=${ - N.data - }${opts.dynamicRef ? _`, ${N.dynamicAnchors}={}` : nil}}={}` -} - -function destructureValCxtES5(gen: CodeGen, opts: InstanceOptions): void { - gen.if( - N.valCxt, - () => { - gen.var(N.instancePath, _`${N.valCxt}.${N.instancePath}`) - gen.var(N.parentData, _`${N.valCxt}.${N.parentData}`) - gen.var(N.parentDataProperty, _`${N.valCxt}.${N.parentDataProperty}`) - gen.var(N.rootData, _`${N.valCxt}.${N.rootData}`) - if (opts.dynamicRef) gen.var(N.dynamicAnchors, _`${N.valCxt}.${N.dynamicAnchors}`) - }, - () => { - gen.var(N.instancePath, _`""`) - gen.var(N.parentData, _`undefined`) - gen.var(N.parentDataProperty, _`undefined`) - gen.var(N.rootData, N.data) - if (opts.dynamicRef) gen.var(N.dynamicAnchors, _`{}`) - } - ) -} - -function topSchemaObjCode(it: SchemaObjCxt): void { - const {schema, opts, gen} = it - validateFunction(it, () => { - if (opts.$comment && schema.$comment) commentKeyword(it) - checkNoDefault(it) - gen.let(N.vErrors, null) - gen.let(N.errors, 0) - if (opts.unevaluated) resetEvaluated(it) - typeAndKeywords(it) - returnResults(it) - }) - return -} - -function resetEvaluated(it: SchemaObjCxt): void { - // TODO maybe some hook to execute it in the end to check whether props/items are Name, as in assignEvaluated - const {gen, validateName} = it - it.evaluated = gen.const("evaluated", _`${validateName}.evaluated`) - gen.if(_`${it.evaluated}.dynamicProps`, () => gen.assign(_`${it.evaluated}.props`, _`undefined`)) - gen.if(_`${it.evaluated}.dynamicItems`, () => gen.assign(_`${it.evaluated}.items`, _`undefined`)) -} - -function funcSourceUrl(schema: AnySchema, opts: InstanceOptions): Code { - const schId = typeof schema == "object" && schema[opts.schemaId] - return schId && (opts.code.source || opts.code.process) ? _`/*# sourceURL=${schId} */` : nil -} - -// schema compilation - this function is used recursively to generate code for sub-schemas -function subschemaCode(it: SchemaCxt, valid: Name): void { - if (isSchemaObj(it)) { - checkKeywords(it) - if (schemaCxtHasRules(it)) { - subSchemaObjCode(it, valid) - return - } - } - boolOrEmptySchema(it, valid) -} - -function schemaCxtHasRules({schema, self}: SchemaCxt): boolean { - if (typeof schema == "boolean") return !schema - for (const key in schema) if (self.RULES.all[key]) return true - return false -} - -function isSchemaObj(it: SchemaCxt): it is SchemaObjCxt { - return typeof it.schema != "boolean" -} - -function subSchemaObjCode(it: SchemaObjCxt, valid: Name): void { - const {schema, gen, opts} = it - if (opts.$comment && schema.$comment) commentKeyword(it) - updateContext(it) - checkAsyncSchema(it) - const errsCount = gen.const("_errs", N.errors) - typeAndKeywords(it, errsCount) - // TODO var - gen.var(valid, _`${errsCount} === ${N.errors}`) -} - -function checkKeywords(it: SchemaObjCxt): void { - checkUnknownRules(it) - checkRefsAndKeywords(it) -} - -function typeAndKeywords(it: SchemaObjCxt, errsCount?: Name): void { - if (it.opts.jtd) return schemaKeywords(it, [], false, errsCount) - const types = getSchemaTypes(it.schema) - const checkedTypes = coerceAndCheckDataType(it, types) - schemaKeywords(it, types, !checkedTypes, errsCount) -} - -function checkRefsAndKeywords(it: SchemaObjCxt): void { - const {schema, errSchemaPath, opts, self} = it - if (schema.$ref && opts.ignoreKeywordsWithRef && schemaHasRulesButRef(schema, self.RULES)) { - self.logger.warn(`$ref: keywords ignored in schema at path "${errSchemaPath}"`) - } -} - -function checkNoDefault(it: SchemaObjCxt): void { - const {schema, opts} = it - if (schema.default !== undefined && opts.useDefaults && opts.strictSchema) { - checkStrictMode(it, "default is ignored in the schema root") - } -} - -function updateContext(it: SchemaObjCxt): void { - const schId = it.schema[it.opts.schemaId] - if (schId) it.baseId = resolveUrl(it.baseId, schId) -} - -function checkAsyncSchema(it: SchemaObjCxt): void { - if (it.schema.$async && !it.schemaEnv.$async) throw new Error("async schema in sync schema") -} - -function commentKeyword({gen, schemaEnv, schema, errSchemaPath, opts}: SchemaObjCxt): void { - const msg = schema.$comment - if (opts.$comment === true) { - gen.code(_`${N.self}.logger.log(${msg})`) - } else if (typeof opts.$comment == "function") { - const schemaPath = str`${errSchemaPath}/$comment` - const rootName = gen.scopeValue("root", {ref: schemaEnv.root}) - gen.code(_`${N.self}.opts.$comment(${msg}, ${schemaPath}, ${rootName}.schema)`) - } -} - -function returnResults(it: SchemaCxt): void { - const {gen, schemaEnv, validateName, ValidationError, opts} = it - if (schemaEnv.$async) { - // TODO assign unevaluated - gen.if( - _`${N.errors} === 0`, - () => gen.return(N.data), - () => gen.throw(_`new ${ValidationError as Name}(${N.vErrors})`) - ) - } else { - gen.assign(_`${validateName}.errors`, N.vErrors) - if (opts.unevaluated) assignEvaluated(it) - gen.return(_`${N.errors} === 0`) - } -} - -function assignEvaluated({gen, evaluated, props, items}: SchemaCxt): void { - if (props instanceof Name) gen.assign(_`${evaluated}.props`, props) - if (items instanceof Name) gen.assign(_`${evaluated}.items`, items) -} - -function schemaKeywords( - it: SchemaObjCxt, - types: JSONType[], - typeErrors: boolean, - errsCount?: Name -): void { - const {gen, schema, data, allErrors, opts, self} = it - const {RULES} = self - if (schema.$ref && (opts.ignoreKeywordsWithRef || !schemaHasRulesButRef(schema, RULES))) { - gen.block(() => keywordCode(it, "$ref", (RULES.all.$ref as Rule).definition)) // TODO typecast - return - } - if (!opts.jtd) checkStrictTypes(it, types) - gen.block(() => { - for (const group of RULES.rules) groupKeywords(group) - groupKeywords(RULES.post) - }) - - function groupKeywords(group: RuleGroup): void { - if (!shouldUseGroup(schema, group)) return - if (group.type) { - gen.if(checkDataType(group.type, data, opts.strictNumbers)) - iterateKeywords(it, group) - if (types.length === 1 && types[0] === group.type && typeErrors) { - gen.else() - reportTypeError(it) - } - gen.endIf() - } else { - iterateKeywords(it, group) - } - // TODO make it "ok" call? - if (!allErrors) gen.if(_`${N.errors} === ${errsCount || 0}`) - } -} - -function iterateKeywords(it: SchemaObjCxt, group: RuleGroup): void { - const { - gen, - schema, - opts: {useDefaults}, - } = it - if (useDefaults) assignDefaults(it, group.type) - gen.block(() => { - for (const rule of group.rules) { - if (shouldUseRule(schema, rule)) { - keywordCode(it, rule.keyword, rule.definition, group.type) - } - } - }) -} - -function checkStrictTypes(it: SchemaObjCxt, types: JSONType[]): void { - if (it.schemaEnv.meta || !it.opts.strictTypes) return - checkContextTypes(it, types) - if (!it.opts.allowUnionTypes) checkMultipleTypes(it, types) - checkKeywordTypes(it, it.dataTypes) -} - -function checkContextTypes(it: SchemaObjCxt, types: JSONType[]): void { - if (!types.length) return - if (!it.dataTypes.length) { - it.dataTypes = types - return - } - types.forEach((t) => { - if (!includesType(it.dataTypes, t)) { - strictTypesError(it, `type "${t}" not allowed by context "${it.dataTypes.join(",")}"`) - } - }) - it.dataTypes = it.dataTypes.filter((t) => includesType(types, t)) -} - -function checkMultipleTypes(it: SchemaObjCxt, ts: JSONType[]): void { - if (ts.length > 1 && !(ts.length === 2 && ts.includes("null"))) { - strictTypesError(it, "use allowUnionTypes to allow union type keyword") - } -} - -function checkKeywordTypes(it: SchemaObjCxt, ts: JSONType[]): void { - const rules = it.self.RULES.all - for (const keyword in rules) { - const rule = rules[keyword] - if (typeof rule == "object" && shouldUseRule(it.schema, rule)) { - const {type} = rule.definition - if (type.length && !type.some((t) => hasApplicableType(ts, t))) { - strictTypesError(it, `missing type "${type.join(",")}" for keyword "${keyword}"`) - } - } - } -} - -function hasApplicableType(schTs: JSONType[], kwdT: JSONType): boolean { - return schTs.includes(kwdT) || (kwdT === "number" && schTs.includes("integer")) -} - -function includesType(ts: JSONType[], t: JSONType): boolean { - return ts.includes(t) || (t === "integer" && ts.includes("number")) -} - -function strictTypesError(it: SchemaObjCxt, msg: string): void { - const schemaPath = it.schemaEnv.baseId + it.errSchemaPath - msg += ` at "${schemaPath}" (strictTypes)` - checkStrictMode(it, msg, it.opts.strictTypes) -} - -export class KeywordCxt implements KeywordErrorCxt { - readonly gen: CodeGen - readonly allErrors?: boolean - readonly keyword: string - readonly data: Name // Name referencing the current level of the data instance - readonly $data?: string | false - schema: any // keyword value in the schema - readonly schemaValue: Code | number | boolean // Code reference to keyword schema value or primitive value - readonly schemaCode: Code | number | boolean // Code reference to resolved schema value (different if schema is $data) - readonly schemaType: JSONType[] // allowed type(s) of keyword value in the schema - readonly parentSchema: AnySchemaObject - readonly errsCount?: Name // Name reference to the number of validation errors collected before this keyword, - // requires option trackErrors in keyword definition - params: KeywordCxtParams // object to pass parameters to error messages from keyword code - readonly it: SchemaObjCxt // schema compilation context (schema is guaranteed to be an object, not boolean) - readonly def: AddedKeywordDefinition - - constructor(it: SchemaObjCxt, def: AddedKeywordDefinition, keyword: string) { - validateKeywordUsage(it, def, keyword) - this.gen = it.gen - this.allErrors = it.allErrors - this.keyword = keyword - this.data = it.data - this.schema = it.schema[keyword] - this.$data = def.$data && it.opts.$data && this.schema && this.schema.$data - this.schemaValue = schemaRefOrVal(it, this.schema, keyword, this.$data) - this.schemaType = def.schemaType - this.parentSchema = it.schema - this.params = {} - this.it = it - this.def = def - - if (this.$data) { - this.schemaCode = it.gen.const("vSchema", getData(this.$data, it)) - } else { - this.schemaCode = this.schemaValue - if (!validSchemaType(this.schema, def.schemaType, def.allowUndefined)) { - throw new Error(`${keyword} value must be ${JSON.stringify(def.schemaType)}`) - } - } - - if ("code" in def ? def.trackErrors : def.errors !== false) { - this.errsCount = it.gen.const("_errs", N.errors) - } - } - - result(condition: Code, successAction?: () => void, failAction?: () => void): void { - this.failResult(not(condition), successAction, failAction) - } - - failResult(condition: Code, successAction?: () => void, failAction?: () => void): void { - this.gen.if(condition) - if (failAction) failAction() - else this.error() - if (successAction) { - this.gen.else() - successAction() - if (this.allErrors) this.gen.endIf() - } else { - if (this.allErrors) this.gen.endIf() - else this.gen.else() - } - } - - pass(condition: Code, failAction?: () => void): void { - this.failResult(not(condition), undefined, failAction) - } - - fail(condition?: Code): void { - if (condition === undefined) { - this.error() - if (!this.allErrors) this.gen.if(false) // this branch will be removed by gen.optimize - return - } - this.gen.if(condition) - this.error() - if (this.allErrors) this.gen.endIf() - else this.gen.else() - } - - fail$data(condition: Code): void { - if (!this.$data) return this.fail(condition) - const {schemaCode} = this - this.fail(_`${schemaCode} !== undefined && (${or(this.invalid$data(), condition)})`) - } - - error(append?: boolean, errorParams?: KeywordCxtParams, errorPaths?: ErrorPaths): void { - if (errorParams) { - this.setParams(errorParams) - this._error(append, errorPaths) - this.setParams({}) - return - } - this._error(append, errorPaths) - } - - private _error(append?: boolean, errorPaths?: ErrorPaths): void { - ;(append ? reportExtraError : reportError)(this, this.def.error, errorPaths) - } - - $dataError(): void { - reportError(this, this.def.$dataError || keyword$DataError) - } - - reset(): void { - if (this.errsCount === undefined) throw new Error('add "trackErrors" to keyword definition') - resetErrorsCount(this.gen, this.errsCount) - } - - ok(cond: Code | boolean): void { - if (!this.allErrors) this.gen.if(cond) - } - - setParams(obj: KeywordCxtParams, assign?: true): void { - if (assign) Object.assign(this.params, obj) - else this.params = obj - } - - block$data(valid: Name, codeBlock: () => void, $dataValid: Code = nil): void { - this.gen.block(() => { - this.check$data(valid, $dataValid) - codeBlock() - }) - } - - check$data(valid: Name = nil, $dataValid: Code = nil): void { - if (!this.$data) return - const {gen, schemaCode, schemaType, def} = this - gen.if(or(_`${schemaCode} === undefined`, $dataValid)) - if (valid !== nil) gen.assign(valid, true) - if (schemaType.length || def.validateSchema) { - gen.elseIf(this.invalid$data()) - this.$dataError() - if (valid !== nil) gen.assign(valid, false) - } - gen.else() - } - - invalid$data(): Code { - const {gen, schemaCode, schemaType, def, it} = this - return or(wrong$DataType(), invalid$DataSchema()) - - function wrong$DataType(): Code { - if (schemaType.length) { - /* istanbul ignore if */ - if (!(schemaCode instanceof Name)) throw new Error("ajv implementation error") - const st = Array.isArray(schemaType) ? schemaType : [schemaType] - return _`${checkDataTypes(st, schemaCode, it.opts.strictNumbers, DataType.Wrong)}` - } - return nil - } - - function invalid$DataSchema(): Code { - if (def.validateSchema) { - const validateSchemaRef = gen.scopeValue("validate$data", {ref: def.validateSchema}) // TODO value.code for standalone - return _`!${validateSchemaRef}(${schemaCode})` - } - return nil - } - } - - subschema(appl: SubschemaArgs, valid: Name): SchemaCxt { - const subschema = getSubschema(this.it, appl) - extendSubschemaData(subschema, this.it, appl) - extendSubschemaMode(subschema, appl) - const nextContext = {...this.it, ...subschema, items: undefined, props: undefined} - subschemaCode(nextContext, valid) - return nextContext - } - - mergeEvaluated(schemaCxt: SchemaCxt, toName?: typeof Name): void { - const {it, gen} = this - if (!it.opts.unevaluated) return - if (it.props !== true && schemaCxt.props !== undefined) { - it.props = mergeEvaluated.props(gen, schemaCxt.props, it.props, toName) - } - if (it.items !== true && schemaCxt.items !== undefined) { - it.items = mergeEvaluated.items(gen, schemaCxt.items, it.items, toName) - } - } - - mergeValidEvaluated(schemaCxt: SchemaCxt, valid: Name): boolean | void { - const {it, gen} = this - if (it.opts.unevaluated && (it.props !== true || it.items !== true)) { - gen.if(valid, () => this.mergeEvaluated(schemaCxt, Name)) - return true - } - } -} - -function keywordCode( - it: SchemaObjCxt, - keyword: string, - def: AddedKeywordDefinition, - ruleType?: JSONType -): void { - const cxt = new KeywordCxt(it, def, keyword) - if ("code" in def) { - def.code(cxt, ruleType) - } else if (cxt.$data && def.validate) { - funcKeywordCode(cxt, def) - } else if ("macro" in def) { - macroKeywordCode(cxt, def) - } else if (def.compile || def.validate) { - funcKeywordCode(cxt, def) - } -} - -const JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/ -const RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/ -export function getData( - $data: string, - {dataLevel, dataNames, dataPathArr}: SchemaCxt -): Code | number { - let jsonPointer - let data: Code - if ($data === "") return N.rootData - if ($data[0] === "/") { - if (!JSON_POINTER.test($data)) throw new Error(`Invalid JSON-pointer: ${$data}`) - jsonPointer = $data - data = N.rootData - } else { - const matches = RELATIVE_JSON_POINTER.exec($data) - if (!matches) throw new Error(`Invalid JSON-pointer: ${$data}`) - const up: number = +matches[1] - jsonPointer = matches[2] - if (jsonPointer === "#") { - if (up >= dataLevel) throw new Error(errorMsg("property/index", up)) - return dataPathArr[dataLevel - up] - } - if (up > dataLevel) throw new Error(errorMsg("data", up)) - data = dataNames[dataLevel - up] - if (!jsonPointer) return data - } - - let expr = data - const segments = jsonPointer.split("/") - for (const segment of segments) { - if (segment) { - data = _`${data}${getProperty(unescapeJsonPointer(segment))}` - expr = _`${expr} && ${data}` - } - } - return expr - - function errorMsg(pointerType: string, up: number): string { - return `Cannot access ${pointerType} ${up} levels up, current level is ${dataLevel}` - } -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/keyword.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/keyword.ts deleted file mode 100644 index f854aa71..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/keyword.ts +++ /dev/null @@ -1,171 +0,0 @@ -import type {KeywordCxt} from "." -import type { - AnySchema, - SchemaValidateFunction, - AnyValidateFunction, - AddedKeywordDefinition, - MacroKeywordDefinition, - FuncKeywordDefinition, -} from "../../types" -import type {SchemaObjCxt} from ".." -import {_, nil, not, stringify, Code, Name, CodeGen} from "../codegen" -import N from "../names" -import type {JSONType} from "../rules" -import {callValidateCode} from "../../vocabularies/code" -import {extendErrors} from "../errors" - -type KeywordCompilationResult = AnySchema | SchemaValidateFunction | AnyValidateFunction - -export function macroKeywordCode(cxt: KeywordCxt, def: MacroKeywordDefinition): void { - const {gen, keyword, schema, parentSchema, it} = cxt - const macroSchema = def.macro.call(it.self, schema, parentSchema, it) - const schemaRef = useKeyword(gen, keyword, macroSchema) - if (it.opts.validateSchema !== false) it.self.validateSchema(macroSchema, true) - - const valid = gen.name("valid") - cxt.subschema( - { - schema: macroSchema, - schemaPath: nil, - errSchemaPath: `${it.errSchemaPath}/${keyword}`, - topSchemaRef: schemaRef, - compositeRule: true, - }, - valid - ) - cxt.pass(valid, () => cxt.error(true)) -} - -export function funcKeywordCode(cxt: KeywordCxt, def: FuncKeywordDefinition): void { - const {gen, keyword, schema, parentSchema, $data, it} = cxt - checkAsyncKeyword(it, def) - const validate = - !$data && def.compile ? def.compile.call(it.self, schema, parentSchema, it) : def.validate - const validateRef = useKeyword(gen, keyword, validate) - const valid = gen.let("valid") - cxt.block$data(valid, validateKeyword) - cxt.ok(def.valid ?? valid) - - function validateKeyword(): void { - if (def.errors === false) { - assignValid() - if (def.modifying) modifyData(cxt) - reportErrs(() => cxt.error()) - } else { - const ruleErrs = def.async ? validateAsync() : validateSync() - if (def.modifying) modifyData(cxt) - reportErrs(() => addErrs(cxt, ruleErrs)) - } - } - - function validateAsync(): Name { - const ruleErrs = gen.let("ruleErrs", null) - gen.try( - () => assignValid(_`await `), - (e) => - gen.assign(valid, false).if( - _`${e} instanceof ${it.ValidationError as Name}`, - () => gen.assign(ruleErrs, _`${e}.errors`), - () => gen.throw(e) - ) - ) - return ruleErrs - } - - function validateSync(): Code { - const validateErrs = _`${validateRef}.errors` - gen.assign(validateErrs, null) - assignValid(nil) - return validateErrs - } - - function assignValid(_await: Code = def.async ? _`await ` : nil): void { - const passCxt = it.opts.passContext ? N.this : N.self - const passSchema = !(("compile" in def && !$data) || def.schema === false) - gen.assign( - valid, - _`${_await}${callValidateCode(cxt, validateRef, passCxt, passSchema)}`, - def.modifying - ) - } - - function reportErrs(errors: () => void): void { - gen.if(not(def.valid ?? valid), errors) - } -} - -function modifyData(cxt: KeywordCxt): void { - const {gen, data, it} = cxt - gen.if(it.parentData, () => gen.assign(data, _`${it.parentData}[${it.parentDataProperty}]`)) -} - -function addErrs(cxt: KeywordCxt, errs: Code): void { - const {gen} = cxt - gen.if( - _`Array.isArray(${errs})`, - () => { - gen - .assign(N.vErrors, _`${N.vErrors} === null ? ${errs} : ${N.vErrors}.concat(${errs})`) - .assign(N.errors, _`${N.vErrors}.length`) - extendErrors(cxt) - }, - () => cxt.error() - ) -} - -function checkAsyncKeyword({schemaEnv}: SchemaObjCxt, def: FuncKeywordDefinition): void { - if (def.async && !schemaEnv.$async) throw new Error("async keyword in sync schema") -} - -function useKeyword(gen: CodeGen, keyword: string, result?: KeywordCompilationResult): Name { - if (result === undefined) throw new Error(`keyword "${keyword}" failed to compile`) - return gen.scopeValue( - "keyword", - typeof result == "function" ? {ref: result} : {ref: result, code: stringify(result)} - ) -} - -export function validSchemaType( - schema: unknown, - schemaType: JSONType[], - allowUndefined = false -): boolean { - // TODO add tests - return ( - !schemaType.length || - schemaType.some((st) => - st === "array" - ? Array.isArray(schema) - : st === "object" - ? schema && typeof schema == "object" && !Array.isArray(schema) - : typeof schema == st || (allowUndefined && typeof schema == "undefined") - ) - ) -} - -export function validateKeywordUsage( - {schema, opts, self, errSchemaPath}: SchemaObjCxt, - def: AddedKeywordDefinition, - keyword: string -): void { - /* istanbul ignore if */ - if (Array.isArray(def.keyword) ? !def.keyword.includes(keyword) : def.keyword !== keyword) { - throw new Error("ajv implementation error") - } - - const deps = def.dependencies - if (deps?.some((kwd) => !Object.prototype.hasOwnProperty.call(schema, kwd))) { - throw new Error(`parent schema must have dependencies of ${keyword}: ${deps.join(",")}`) - } - - if (def.validateSchema) { - const valid = def.validateSchema(schema[keyword]) - if (!valid) { - const msg = - `keyword "${keyword}" value is invalid at path "${errSchemaPath}": ` + - self.errorsText(def.validateSchema.errors) - if (opts.validateSchema === "log") self.logger.error(msg) - else throw new Error(msg) - } - } -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/subschema.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/subschema.ts deleted file mode 100644 index 9072ed77..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/validate/subschema.ts +++ /dev/null @@ -1,135 +0,0 @@ -import type {AnySchema} from "../../types" -import type {SchemaObjCxt} from ".." -import {_, str, getProperty, Code, Name} from "../codegen" -import {escapeFragment, getErrorPath, Type} from "../util" -import type {JSONType} from "../rules" - -export interface SubschemaContext { - // TODO use Optional? align with SchemCxt property types - schema: AnySchema - schemaPath: Code - errSchemaPath: string - topSchemaRef?: Code - errorPath?: Code - dataLevel?: number - dataTypes?: JSONType[] - data?: Name - parentData?: Name - parentDataProperty?: Code | number - dataNames?: Name[] - dataPathArr?: (Code | number)[] - propertyName?: Name - jtdDiscriminator?: string - jtdMetadata?: boolean - compositeRule?: true - createErrors?: boolean - allErrors?: boolean -} - -export type SubschemaArgs = Partial<{ - keyword: string - schemaProp: string | number - schema: AnySchema - schemaPath: Code - errSchemaPath: string - topSchemaRef: Code - data: Name | Code - dataProp: Code | string | number - dataTypes: JSONType[] - definedProperties: Set - propertyName: Name - dataPropType: Type - jtdDiscriminator: string - jtdMetadata: boolean - compositeRule: true - createErrors: boolean - allErrors: boolean -}> - -export function getSubschema( - it: SchemaObjCxt, - {keyword, schemaProp, schema, schemaPath, errSchemaPath, topSchemaRef}: SubschemaArgs -): SubschemaContext { - if (keyword !== undefined && schema !== undefined) { - throw new Error('both "keyword" and "schema" passed, only one allowed') - } - - if (keyword !== undefined) { - const sch = it.schema[keyword] - return schemaProp === undefined - ? { - schema: sch, - schemaPath: _`${it.schemaPath}${getProperty(keyword)}`, - errSchemaPath: `${it.errSchemaPath}/${keyword}`, - } - : { - schema: sch[schemaProp], - schemaPath: _`${it.schemaPath}${getProperty(keyword)}${getProperty(schemaProp)}`, - errSchemaPath: `${it.errSchemaPath}/${keyword}/${escapeFragment(schemaProp)}`, - } - } - - if (schema !== undefined) { - if (schemaPath === undefined || errSchemaPath === undefined || topSchemaRef === undefined) { - throw new Error('"schemaPath", "errSchemaPath" and "topSchemaRef" are required with "schema"') - } - return { - schema, - schemaPath, - topSchemaRef, - errSchemaPath, - } - } - - throw new Error('either "keyword" or "schema" must be passed') -} - -export function extendSubschemaData( - subschema: SubschemaContext, - it: SchemaObjCxt, - {dataProp, dataPropType: dpType, data, dataTypes, propertyName}: SubschemaArgs -): void { - if (data !== undefined && dataProp !== undefined) { - throw new Error('both "data" and "dataProp" passed, only one allowed') - } - - const {gen} = it - - if (dataProp !== undefined) { - const {errorPath, dataPathArr, opts} = it - const nextData = gen.let("data", _`${it.data}${getProperty(dataProp)}`, true) - dataContextProps(nextData) - subschema.errorPath = str`${errorPath}${getErrorPath(dataProp, dpType, opts.jsPropertySyntax)}` - subschema.parentDataProperty = _`${dataProp}` - subschema.dataPathArr = [...dataPathArr, subschema.parentDataProperty] - } - - if (data !== undefined) { - const nextData = data instanceof Name ? data : gen.let("data", data, true) // replaceable if used once? - dataContextProps(nextData) - if (propertyName !== undefined) subschema.propertyName = propertyName - // TODO something is possibly wrong here with not changing parentDataProperty and not appending dataPathArr - } - - if (dataTypes) subschema.dataTypes = dataTypes - - function dataContextProps(_nextData: Name): void { - subschema.data = _nextData - subschema.dataLevel = it.dataLevel + 1 - subschema.dataTypes = [] - it.definedProperties = new Set() - subschema.parentData = it.data - subschema.dataNames = [...it.dataNames, _nextData] - } -} - -export function extendSubschemaMode( - subschema: SubschemaContext, - {jtdDiscriminator, jtdMetadata, compositeRule, createErrors, allErrors}: SubschemaArgs -): void { - if (compositeRule !== undefined) subschema.compositeRule = compositeRule - if (createErrors !== undefined) subschema.createErrors = createErrors - if (allErrors !== undefined) subschema.allErrors = allErrors - subschema.jtdDiscriminator = jtdDiscriminator // not inherited - subschema.jtdMetadata = jtdMetadata // not inherited -} -- cgit v1.2.3