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. --- .../node_modules/ajv/lib/compile/codegen/code.ts | 168 ----- .../node_modules/ajv/lib/compile/codegen/index.ts | 832 --------------------- .../node_modules/ajv/lib/compile/codegen/scope.ts | 215 ------ .../Front/node_modules/ajv/lib/compile/errors.ts | 184 ----- .../Front/node_modules/ajv/lib/compile/index.ts | 324 -------- .../node_modules/ajv/lib/compile/jtd/parse.ts | 411 ---------- .../node_modules/ajv/lib/compile/jtd/serialize.ts | 260 ------- .../node_modules/ajv/lib/compile/jtd/types.ts | 16 - .../Front/node_modules/ajv/lib/compile/names.ts | 27 - .../node_modules/ajv/lib/compile/ref_error.ts | 12 - .../Front/node_modules/ajv/lib/compile/resolve.ts | 146 ---- .../Front/node_modules/ajv/lib/compile/rules.ts | 50 -- .../Front/node_modules/ajv/lib/compile/util.ts | 213 ------ .../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 ---- 20 files changed, 4067 deletions(-) delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/codegen/code.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/codegen/index.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/codegen/scope.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/errors.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/index.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/jtd/parse.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/jtd/serialize.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/jtd/types.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/names.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/ref_error.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/resolve.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/rules.ts delete mode 100644 sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/util.ts 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') diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/codegen/code.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/codegen/code.ts deleted file mode 100644 index b1770197..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/codegen/code.ts +++ /dev/null @@ -1,168 +0,0 @@ -export abstract class _CodeOrName { - abstract readonly str: string - abstract readonly names: UsedNames - abstract toString(): string - abstract emptyStr(): boolean -} - -export const IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i - -export class Name extends _CodeOrName { - readonly str: string - constructor(s: string) { - super() - if (!IDENTIFIER.test(s)) throw new Error("CodeGen: name must be a valid identifier") - this.str = s - } - - toString(): string { - return this.str - } - - emptyStr(): boolean { - return false - } - - get names(): UsedNames { - return {[this.str]: 1} - } -} - -export class _Code extends _CodeOrName { - readonly _items: readonly CodeItem[] - private _str?: string - private _names?: UsedNames - - constructor(code: string | readonly CodeItem[]) { - super() - this._items = typeof code === "string" ? [code] : code - } - - toString(): string { - return this.str - } - - emptyStr(): boolean { - if (this._items.length > 1) return false - const item = this._items[0] - return item === "" || item === '""' - } - - get str(): string { - return (this._str ??= this._items.reduce((s: string, c: CodeItem) => `${s}${c}`, "")) - } - - get names(): UsedNames { - return (this._names ??= this._items.reduce((names: UsedNames, c) => { - if (c instanceof Name) names[c.str] = (names[c.str] || 0) + 1 - return names - }, {})) - } -} - -export type CodeItem = Name | string | number | boolean | null - -export type UsedNames = Record - -export type Code = _Code | Name - -export type SafeExpr = Code | number | boolean | null - -export const nil = new _Code("") - -type CodeArg = SafeExpr | string | undefined - -export function _(strs: TemplateStringsArray, ...args: CodeArg[]): _Code { - const code: CodeItem[] = [strs[0]] - let i = 0 - while (i < args.length) { - addCodeArg(code, args[i]) - code.push(strs[++i]) - } - return new _Code(code) -} - -const plus = new _Code("+") - -export function str(strs: TemplateStringsArray, ...args: (CodeArg | string[])[]): _Code { - const expr: CodeItem[] = [safeStringify(strs[0])] - let i = 0 - while (i < args.length) { - expr.push(plus) - addCodeArg(expr, args[i]) - expr.push(plus, safeStringify(strs[++i])) - } - optimize(expr) - return new _Code(expr) -} - -export function addCodeArg(code: CodeItem[], arg: CodeArg | string[]): void { - if (arg instanceof _Code) code.push(...arg._items) - else if (arg instanceof Name) code.push(arg) - else code.push(interpolate(arg)) -} - -function optimize(expr: CodeItem[]): void { - let i = 1 - while (i < expr.length - 1) { - if (expr[i] === plus) { - const res = mergeExprItems(expr[i - 1], expr[i + 1]) - if (res !== undefined) { - expr.splice(i - 1, 3, res) - continue - } - expr[i++] = "+" - } - i++ - } -} - -function mergeExprItems(a: CodeItem, b: CodeItem): CodeItem | undefined { - if (b === '""') return a - if (a === '""') return b - if (typeof a == "string") { - if (b instanceof Name || a[a.length - 1] !== '"') return - if (typeof b != "string") return `${a.slice(0, -1)}${b}"` - if (b[0] === '"') return a.slice(0, -1) + b.slice(1) - return - } - if (typeof b == "string" && b[0] === '"' && !(a instanceof Name)) return `"${a}${b.slice(1)}` - return -} - -export function strConcat(c1: Code, c2: Code): Code { - return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 : str`${c1}${c2}` -} - -// TODO do not allow arrays here -function interpolate(x?: string | string[] | number | boolean | null): SafeExpr | string { - return typeof x == "number" || typeof x == "boolean" || x === null - ? x - : safeStringify(Array.isArray(x) ? x.join(",") : x) -} - -export function stringify(x: unknown): Code { - return new _Code(safeStringify(x)) -} - -export function safeStringify(x: unknown): string { - return JSON.stringify(x) - .replace(/\u2028/g, "\\u2028") - .replace(/\u2029/g, "\\u2029") -} - -export function getProperty(key: Code | string | number): Code { - return typeof key == "string" && IDENTIFIER.test(key) ? new _Code(`.${key}`) : _`[${key}]` -} - -//Does best effort to format the name properly -export function getEsmExportName(key: Code | string | number): Code { - if (typeof key == "string" && IDENTIFIER.test(key)) { - return new _Code(`${key}`) - } - throw new Error(`CodeGen: invalid export name: ${key}, use explicit $id name mapping`) -} - -export function regexpCode(rx: RegExp): Code { - return new _Code(rx.toString()) -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/codegen/index.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/codegen/index.ts deleted file mode 100644 index 9d29055d..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/codegen/index.ts +++ /dev/null @@ -1,832 +0,0 @@ -import type {ScopeValueSets, NameValue, ValueScope, ValueScopeName} from "./scope" -import {_, nil, _Code, Code, Name, UsedNames, CodeItem, addCodeArg, _CodeOrName} from "./code" -import {Scope, varKinds} from "./scope" - -export {_, str, strConcat, nil, getProperty, stringify, regexpCode, Name, Code} from "./code" -export {Scope, ScopeStore, ValueScope, ValueScopeName, ScopeValueSets, varKinds} from "./scope" - -// type for expressions that can be safely inserted in code without quotes -export type SafeExpr = Code | number | boolean | null - -// type that is either Code of function that adds code to CodeGen instance using its methods -export type Block = Code | (() => void) - -export const operators = { - GT: new _Code(">"), - GTE: new _Code(">="), - LT: new _Code("<"), - LTE: new _Code("<="), - EQ: new _Code("==="), - NEQ: new _Code("!=="), - NOT: new _Code("!"), - OR: new _Code("||"), - AND: new _Code("&&"), - ADD: new _Code("+"), -} - -abstract class Node { - abstract readonly names: UsedNames - - optimizeNodes(): this | ChildNode | ChildNode[] | undefined { - return this - } - - optimizeNames(_names: UsedNames, _constants: Constants): this | undefined { - return this - } - - // get count(): number { - // return 1 - // } -} - -class Def extends Node { - constructor(private readonly varKind: Name, private readonly name: Name, private rhs?: SafeExpr) { - super() - } - - render({es5, _n}: CGOptions): string { - const varKind = es5 ? varKinds.var : this.varKind - const rhs = this.rhs === undefined ? "" : ` = ${this.rhs}` - return `${varKind} ${this.name}${rhs};` + _n - } - - optimizeNames(names: UsedNames, constants: Constants): this | undefined { - if (!names[this.name.str]) return - if (this.rhs) this.rhs = optimizeExpr(this.rhs, names, constants) - return this - } - - get names(): UsedNames { - return this.rhs instanceof _CodeOrName ? this.rhs.names : {} - } -} - -class Assign extends Node { - constructor(readonly lhs: Code, public rhs: SafeExpr, private readonly sideEffects?: boolean) { - super() - } - - render({_n}: CGOptions): string { - return `${this.lhs} = ${this.rhs};` + _n - } - - optimizeNames(names: UsedNames, constants: Constants): this | undefined { - if (this.lhs instanceof Name && !names[this.lhs.str] && !this.sideEffects) return - this.rhs = optimizeExpr(this.rhs, names, constants) - return this - } - - get names(): UsedNames { - const names = this.lhs instanceof Name ? {} : {...this.lhs.names} - return addExprNames(names, this.rhs) - } -} - -class AssignOp extends Assign { - constructor(lhs: Code, private readonly op: Code, rhs: SafeExpr, sideEffects?: boolean) { - super(lhs, rhs, sideEffects) - } - - render({_n}: CGOptions): string { - return `${this.lhs} ${this.op}= ${this.rhs};` + _n - } -} - -class Label extends Node { - readonly names: UsedNames = {} - constructor(readonly label: Name) { - super() - } - - render({_n}: CGOptions): string { - return `${this.label}:` + _n - } -} - -class Break extends Node { - readonly names: UsedNames = {} - constructor(readonly label?: Code) { - super() - } - - render({_n}: CGOptions): string { - const label = this.label ? ` ${this.label}` : "" - return `break${label};` + _n - } -} - -class Throw extends Node { - constructor(readonly error: Code) { - super() - } - - render({_n}: CGOptions): string { - return `throw ${this.error};` + _n - } - - get names(): UsedNames { - return this.error.names - } -} - -class AnyCode extends Node { - constructor(private code: SafeExpr) { - super() - } - - render({_n}: CGOptions): string { - return `${this.code};` + _n - } - - optimizeNodes(): this | undefined { - return `${this.code}` ? this : undefined - } - - optimizeNames(names: UsedNames, constants: Constants): this { - this.code = optimizeExpr(this.code, names, constants) - return this - } - - get names(): UsedNames { - return this.code instanceof _CodeOrName ? this.code.names : {} - } -} - -abstract class ParentNode extends Node { - constructor(readonly nodes: ChildNode[] = []) { - super() - } - - render(opts: CGOptions): string { - return this.nodes.reduce((code, n) => code + n.render(opts), "") - } - - optimizeNodes(): this | ChildNode | ChildNode[] | undefined { - const {nodes} = this - let i = nodes.length - while (i--) { - const n = nodes[i].optimizeNodes() - if (Array.isArray(n)) nodes.splice(i, 1, ...n) - else if (n) nodes[i] = n - else nodes.splice(i, 1) - } - return nodes.length > 0 ? this : undefined - } - - optimizeNames(names: UsedNames, constants: Constants): this | undefined { - const {nodes} = this - let i = nodes.length - while (i--) { - // iterating backwards improves 1-pass optimization - const n = nodes[i] - if (n.optimizeNames(names, constants)) continue - subtractNames(names, n.names) - nodes.splice(i, 1) - } - return nodes.length > 0 ? this : undefined - } - - get names(): UsedNames { - return this.nodes.reduce((names: UsedNames, n) => addNames(names, n.names), {}) - } - - // get count(): number { - // return this.nodes.reduce((c, n) => c + n.count, 1) - // } -} - -abstract class BlockNode extends ParentNode { - render(opts: CGOptions): string { - return "{" + opts._n + super.render(opts) + "}" + opts._n - } -} - -class Root extends ParentNode {} - -class Else extends BlockNode { - static readonly kind = "else" -} - -class If extends BlockNode { - static readonly kind = "if" - else?: If | Else - constructor(private condition: Code | boolean, nodes?: ChildNode[]) { - super(nodes) - } - - render(opts: CGOptions): string { - let code = `if(${this.condition})` + super.render(opts) - if (this.else) code += "else " + this.else.render(opts) - return code - } - - optimizeNodes(): If | ChildNode[] | undefined { - super.optimizeNodes() - const cond = this.condition - if (cond === true) return this.nodes // else is ignored here - let e = this.else - if (e) { - const ns = e.optimizeNodes() - e = this.else = Array.isArray(ns) ? new Else(ns) : (ns as Else | undefined) - } - if (e) { - if (cond === false) return e instanceof If ? e : e.nodes - if (this.nodes.length) return this - return new If(not(cond), e instanceof If ? [e] : e.nodes) - } - if (cond === false || !this.nodes.length) return undefined - return this - } - - optimizeNames(names: UsedNames, constants: Constants): this | undefined { - this.else = this.else?.optimizeNames(names, constants) - if (!(super.optimizeNames(names, constants) || this.else)) return - this.condition = optimizeExpr(this.condition, names, constants) - return this - } - - get names(): UsedNames { - const names = super.names - addExprNames(names, this.condition) - if (this.else) addNames(names, this.else.names) - return names - } - - // get count(): number { - // return super.count + (this.else?.count || 0) - // } -} - -abstract class For extends BlockNode { - static readonly kind = "for" -} - -class ForLoop extends For { - constructor(private iteration: Code) { - super() - } - - render(opts: CGOptions): string { - return `for(${this.iteration})` + super.render(opts) - } - - optimizeNames(names: UsedNames, constants: Constants): this | undefined { - if (!super.optimizeNames(names, constants)) return - this.iteration = optimizeExpr(this.iteration, names, constants) - return this - } - - get names(): UsedNames { - return addNames(super.names, this.iteration.names) - } -} - -class ForRange extends For { - constructor( - private readonly varKind: Name, - private readonly name: Name, - private readonly from: SafeExpr, - private readonly to: SafeExpr - ) { - super() - } - - render(opts: CGOptions): string { - const varKind = opts.es5 ? varKinds.var : this.varKind - const {name, from, to} = this - return `for(${varKind} ${name}=${from}; ${name}<${to}; ${name}++)` + super.render(opts) - } - - get names(): UsedNames { - const names = addExprNames(super.names, this.from) - return addExprNames(names, this.to) - } -} - -class ForIter extends For { - constructor( - private readonly loop: "of" | "in", - private readonly varKind: Name, - private readonly name: Name, - private iterable: Code - ) { - super() - } - - render(opts: CGOptions): string { - return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts) - } - - optimizeNames(names: UsedNames, constants: Constants): this | undefined { - if (!super.optimizeNames(names, constants)) return - this.iterable = optimizeExpr(this.iterable, names, constants) - return this - } - - get names(): UsedNames { - return addNames(super.names, this.iterable.names) - } -} - -class Func extends BlockNode { - static readonly kind = "func" - constructor(public name: Name, public args: Code, public async?: boolean) { - super() - } - - render(opts: CGOptions): string { - const _async = this.async ? "async " : "" - return `${_async}function ${this.name}(${this.args})` + super.render(opts) - } -} - -class Return extends ParentNode { - static readonly kind = "return" - - render(opts: CGOptions): string { - return "return " + super.render(opts) - } -} - -class Try extends BlockNode { - catch?: Catch - finally?: Finally - - render(opts: CGOptions): string { - let code = "try" + super.render(opts) - if (this.catch) code += this.catch.render(opts) - if (this.finally) code += this.finally.render(opts) - return code - } - - optimizeNodes(): this { - super.optimizeNodes() - this.catch?.optimizeNodes() as Catch | undefined - this.finally?.optimizeNodes() as Finally | undefined - return this - } - - optimizeNames(names: UsedNames, constants: Constants): this { - super.optimizeNames(names, constants) - this.catch?.optimizeNames(names, constants) - this.finally?.optimizeNames(names, constants) - return this - } - - get names(): UsedNames { - const names = super.names - if (this.catch) addNames(names, this.catch.names) - if (this.finally) addNames(names, this.finally.names) - return names - } - - // get count(): number { - // return super.count + (this.catch?.count || 0) + (this.finally?.count || 0) - // } -} - -class Catch extends BlockNode { - static readonly kind = "catch" - constructor(readonly error: Name) { - super() - } - - render(opts: CGOptions): string { - return `catch(${this.error})` + super.render(opts) - } -} - -class Finally extends BlockNode { - static readonly kind = "finally" - render(opts: CGOptions): string { - return "finally" + super.render(opts) - } -} - -type StartBlockNode = If | For | Func | Return | Try - -type LeafNode = Def | Assign | Label | Break | Throw | AnyCode - -type ChildNode = StartBlockNode | LeafNode - -type EndBlockNodeType = - | typeof If - | typeof Else - | typeof For - | typeof Func - | typeof Return - | typeof Catch - | typeof Finally - -type Constants = Record - -export interface CodeGenOptions { - es5?: boolean - lines?: boolean - ownProperties?: boolean -} - -interface CGOptions extends CodeGenOptions { - _n: "\n" | "" -} - -export class CodeGen { - readonly _scope: Scope - readonly _extScope: ValueScope - readonly _values: ScopeValueSets = {} - private readonly _nodes: ParentNode[] - private readonly _blockStarts: number[] = [] - private readonly _constants: Constants = {} - private readonly opts: CGOptions - - constructor(extScope: ValueScope, opts: CodeGenOptions = {}) { - this.opts = {...opts, _n: opts.lines ? "\n" : ""} - this._extScope = extScope - this._scope = new Scope({parent: extScope}) - this._nodes = [new Root()] - } - - toString(): string { - return this._root.render(this.opts) - } - - // returns unique name in the internal scope - name(prefix: string): Name { - return this._scope.name(prefix) - } - - // reserves unique name in the external scope - scopeName(prefix: string): ValueScopeName { - return this._extScope.name(prefix) - } - - // reserves unique name in the external scope and assigns value to it - scopeValue(prefixOrName: ValueScopeName | string, value: NameValue): Name { - const name = this._extScope.value(prefixOrName, value) - const vs = this._values[name.prefix] || (this._values[name.prefix] = new Set()) - vs.add(name) - return name - } - - getScopeValue(prefix: string, keyOrRef: unknown): ValueScopeName | undefined { - return this._extScope.getValue(prefix, keyOrRef) - } - - // return code that assigns values in the external scope to the names that are used internally - // (same names that were returned by gen.scopeName or gen.scopeValue) - scopeRefs(scopeName: Name): Code { - return this._extScope.scopeRefs(scopeName, this._values) - } - - scopeCode(): Code { - return this._extScope.scopeCode(this._values) - } - - private _def( - varKind: Name, - nameOrPrefix: Name | string, - rhs?: SafeExpr, - constant?: boolean - ): Name { - const name = this._scope.toName(nameOrPrefix) - if (rhs !== undefined && constant) this._constants[name.str] = rhs - this._leafNode(new Def(varKind, name, rhs)) - return name - } - - // `const` declaration (`var` in es5 mode) - const(nameOrPrefix: Name | string, rhs: SafeExpr, _constant?: boolean): Name { - return this._def(varKinds.const, nameOrPrefix, rhs, _constant) - } - - // `let` declaration with optional assignment (`var` in es5 mode) - let(nameOrPrefix: Name | string, rhs?: SafeExpr, _constant?: boolean): Name { - return this._def(varKinds.let, nameOrPrefix, rhs, _constant) - } - - // `var` declaration with optional assignment - var(nameOrPrefix: Name | string, rhs?: SafeExpr, _constant?: boolean): Name { - return this._def(varKinds.var, nameOrPrefix, rhs, _constant) - } - - // assignment code - assign(lhs: Code, rhs: SafeExpr, sideEffects?: boolean): CodeGen { - return this._leafNode(new Assign(lhs, rhs, sideEffects)) - } - - // `+=` code - add(lhs: Code, rhs: SafeExpr): CodeGen { - return this._leafNode(new AssignOp(lhs, operators.ADD, rhs)) - } - - // appends passed SafeExpr to code or executes Block - code(c: Block | SafeExpr): CodeGen { - if (typeof c == "function") c() - else if (c !== nil) this._leafNode(new AnyCode(c)) - return this - } - - // returns code for object literal for the passed argument list of key-value pairs - object(...keyValues: [Name | string, SafeExpr | string][]): _Code { - const code: CodeItem[] = ["{"] - for (const [key, value] of keyValues) { - if (code.length > 1) code.push(",") - code.push(key) - if (key !== value || this.opts.es5) { - code.push(":") - addCodeArg(code, value) - } - } - code.push("}") - return new _Code(code) - } - - // `if` clause (or statement if `thenBody` and, optionally, `elseBody` are passed) - if(condition: Code | boolean, thenBody?: Block, elseBody?: Block): CodeGen { - this._blockNode(new If(condition)) - - if (thenBody && elseBody) { - this.code(thenBody).else().code(elseBody).endIf() - } else if (thenBody) { - this.code(thenBody).endIf() - } else if (elseBody) { - throw new Error('CodeGen: "else" body without "then" body') - } - return this - } - - // `else if` clause - invalid without `if` or after `else` clauses - elseIf(condition: Code | boolean): CodeGen { - return this._elseNode(new If(condition)) - } - - // `else` clause - only valid after `if` or `else if` clauses - else(): CodeGen { - return this._elseNode(new Else()) - } - - // end `if` statement (needed if gen.if was used only with condition) - endIf(): CodeGen { - return this._endBlockNode(If, Else) - } - - private _for(node: For, forBody?: Block): CodeGen { - this._blockNode(node) - if (forBody) this.code(forBody).endFor() - return this - } - - // a generic `for` clause (or statement if `forBody` is passed) - for(iteration: Code, forBody?: Block): CodeGen { - return this._for(new ForLoop(iteration), forBody) - } - - // `for` statement for a range of values - forRange( - nameOrPrefix: Name | string, - from: SafeExpr, - to: SafeExpr, - forBody: (index: Name) => void, - varKind: Code = this.opts.es5 ? varKinds.var : varKinds.let - ): CodeGen { - const name = this._scope.toName(nameOrPrefix) - return this._for(new ForRange(varKind, name, from, to), () => forBody(name)) - } - - // `for-of` statement (in es5 mode replace with a normal for loop) - forOf( - nameOrPrefix: Name | string, - iterable: Code, - forBody: (item: Name) => void, - varKind: Code = varKinds.const - ): CodeGen { - const name = this._scope.toName(nameOrPrefix) - if (this.opts.es5) { - const arr = iterable instanceof Name ? iterable : this.var("_arr", iterable) - return this.forRange("_i", 0, _`${arr}.length`, (i) => { - this.var(name, _`${arr}[${i}]`) - forBody(name) - }) - } - return this._for(new ForIter("of", varKind, name, iterable), () => forBody(name)) - } - - // `for-in` statement. - // With option `ownProperties` replaced with a `for-of` loop for object keys - forIn( - nameOrPrefix: Name | string, - obj: Code, - forBody: (item: Name) => void, - varKind: Code = this.opts.es5 ? varKinds.var : varKinds.const - ): CodeGen { - if (this.opts.ownProperties) { - return this.forOf(nameOrPrefix, _`Object.keys(${obj})`, forBody) - } - const name = this._scope.toName(nameOrPrefix) - return this._for(new ForIter("in", varKind, name, obj), () => forBody(name)) - } - - // end `for` loop - endFor(): CodeGen { - return this._endBlockNode(For) - } - - // `label` statement - label(label: Name): CodeGen { - return this._leafNode(new Label(label)) - } - - // `break` statement - break(label?: Code): CodeGen { - return this._leafNode(new Break(label)) - } - - // `return` statement - return(value: Block | SafeExpr): CodeGen { - const node = new Return() - this._blockNode(node) - this.code(value) - if (node.nodes.length !== 1) throw new Error('CodeGen: "return" should have one node') - return this._endBlockNode(Return) - } - - // `try` statement - try(tryBody: Block, catchCode?: (e: Name) => void, finallyCode?: Block): CodeGen { - if (!catchCode && !finallyCode) throw new Error('CodeGen: "try" without "catch" and "finally"') - const node = new Try() - this._blockNode(node) - this.code(tryBody) - if (catchCode) { - const error = this.name("e") - this._currNode = node.catch = new Catch(error) - catchCode(error) - } - if (finallyCode) { - this._currNode = node.finally = new Finally() - this.code(finallyCode) - } - return this._endBlockNode(Catch, Finally) - } - - // `throw` statement - throw(error: Code): CodeGen { - return this._leafNode(new Throw(error)) - } - - // start self-balancing block - block(body?: Block, nodeCount?: number): CodeGen { - this._blockStarts.push(this._nodes.length) - if (body) this.code(body).endBlock(nodeCount) - return this - } - - // end the current self-balancing block - endBlock(nodeCount?: number): CodeGen { - const len = this._blockStarts.pop() - if (len === undefined) throw new Error("CodeGen: not in self-balancing block") - const toClose = this._nodes.length - len - if (toClose < 0 || (nodeCount !== undefined && toClose !== nodeCount)) { - throw new Error(`CodeGen: wrong number of nodes: ${toClose} vs ${nodeCount} expected`) - } - this._nodes.length = len - return this - } - - // `function` heading (or definition if funcBody is passed) - func(name: Name, args: Code = nil, async?: boolean, funcBody?: Block): CodeGen { - this._blockNode(new Func(name, args, async)) - if (funcBody) this.code(funcBody).endFunc() - return this - } - - // end function definition - endFunc(): CodeGen { - return this._endBlockNode(Func) - } - - optimize(n = 1): void { - while (n-- > 0) { - this._root.optimizeNodes() - this._root.optimizeNames(this._root.names, this._constants) - } - } - - private _leafNode(node: LeafNode): CodeGen { - this._currNode.nodes.push(node) - return this - } - - private _blockNode(node: StartBlockNode): void { - this._currNode.nodes.push(node) - this._nodes.push(node) - } - - private _endBlockNode(N1: EndBlockNodeType, N2?: EndBlockNodeType): CodeGen { - const n = this._currNode - if (n instanceof N1 || (N2 && n instanceof N2)) { - this._nodes.pop() - return this - } - throw new Error(`CodeGen: not in block "${N2 ? `${N1.kind}/${N2.kind}` : N1.kind}"`) - } - - private _elseNode(node: If | Else): CodeGen { - const n = this._currNode - if (!(n instanceof If)) { - throw new Error('CodeGen: "else" without "if"') - } - this._currNode = n.else = node - return this - } - - private get _root(): Root { - return this._nodes[0] as Root - } - - private get _currNode(): ParentNode { - const ns = this._nodes - return ns[ns.length - 1] - } - - private set _currNode(node: ParentNode) { - const ns = this._nodes - ns[ns.length - 1] = node - } - - // get nodeCount(): number { - // return this._root.count - // } -} - -function addNames(names: UsedNames, from: UsedNames): UsedNames { - for (const n in from) names[n] = (names[n] || 0) + (from[n] || 0) - return names -} - -function addExprNames(names: UsedNames, from: SafeExpr): UsedNames { - return from instanceof _CodeOrName ? addNames(names, from.names) : names -} - -function optimizeExpr(expr: T, names: UsedNames, constants: Constants): T -function optimizeExpr(expr: SafeExpr, names: UsedNames, constants: Constants): SafeExpr { - if (expr instanceof Name) return replaceName(expr) - if (!canOptimize(expr)) return expr - return new _Code( - expr._items.reduce((items: CodeItem[], c: SafeExpr | string) => { - if (c instanceof Name) c = replaceName(c) - if (c instanceof _Code) items.push(...c._items) - else items.push(c) - return items - }, []) - ) - - function replaceName(n: Name): SafeExpr { - const c = constants[n.str] - if (c === undefined || names[n.str] !== 1) return n - delete names[n.str] - return c - } - - function canOptimize(e: SafeExpr): e is _Code { - return ( - e instanceof _Code && - e._items.some( - (c) => c instanceof Name && names[c.str] === 1 && constants[c.str] !== undefined - ) - ) - } -} - -function subtractNames(names: UsedNames, from: UsedNames): void { - for (const n in from) names[n] = (names[n] || 0) - (from[n] || 0) -} - -export function not(x: T): T -export function not(x: Code | SafeExpr): Code | SafeExpr { - return typeof x == "boolean" || typeof x == "number" || x === null ? !x : _`!${par(x)}` -} - -const andCode = mappend(operators.AND) - -// boolean AND (&&) expression with the passed arguments -export function and(...args: Code[]): Code { - return args.reduce(andCode) -} - -const orCode = mappend(operators.OR) - -// boolean OR (||) expression with the passed arguments -export function or(...args: Code[]): Code { - return args.reduce(orCode) -} - -type MAppend = (x: Code, y: Code) => Code - -function mappend(op: Code): MAppend { - return (x, y) => (x === nil ? y : y === nil ? x : _`${par(x)} ${op} ${par(y)}`) -} - -function par(x: Code): Code { - return x instanceof Name ? x : _`(${x})` -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/codegen/scope.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/codegen/scope.ts deleted file mode 100644 index 51199229..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/codegen/scope.ts +++ /dev/null @@ -1,215 +0,0 @@ -import {_, nil, Code, Name} from "./code" - -interface NameGroup { - prefix: string - index: number -} - -export interface NameValue { - ref: ValueReference // this is the reference to any value that can be referred to from generated code via `globals` var in the closure - key?: unknown // any key to identify a global to avoid duplicates, if not passed ref is used - code?: Code // this is the code creating the value needed for standalone code wit_out closure - can be a primitive value, function or import (`require`) -} - -export type ValueReference = unknown // possibly make CodeGen parameterized type on this type - -class ValueError extends Error { - readonly value?: NameValue - constructor(name: ValueScopeName) { - super(`CodeGen: "code" for ${name} not defined`) - this.value = name.value - } -} - -interface ScopeOptions { - prefixes?: Set - parent?: Scope -} - -interface ValueScopeOptions extends ScopeOptions { - scope: ScopeStore - es5?: boolean - lines?: boolean -} - -export type ScopeStore = Record - -type ScopeValues = { - [Prefix in string]?: Map -} - -export type ScopeValueSets = { - [Prefix in string]?: Set -} - -export enum UsedValueState { - Started, - Completed, -} - -export type UsedScopeValues = { - [Prefix in string]?: Map -} - -export const varKinds = { - const: new Name("const"), - let: new Name("let"), - var: new Name("var"), -} - -export class Scope { - protected readonly _names: {[Prefix in string]?: NameGroup} = {} - protected readonly _prefixes?: Set - protected readonly _parent?: Scope - - constructor({prefixes, parent}: ScopeOptions = {}) { - this._prefixes = prefixes - this._parent = parent - } - - toName(nameOrPrefix: Name | string): Name { - return nameOrPrefix instanceof Name ? nameOrPrefix : this.name(nameOrPrefix) - } - - name(prefix: string): Name { - return new Name(this._newName(prefix)) - } - - protected _newName(prefix: string): string { - const ng = this._names[prefix] || this._nameGroup(prefix) - return `${prefix}${ng.index++}` - } - - private _nameGroup(prefix: string): NameGroup { - if (this._parent?._prefixes?.has(prefix) || (this._prefixes && !this._prefixes.has(prefix))) { - throw new Error(`CodeGen: prefix "${prefix}" is not allowed in this scope`) - } - return (this._names[prefix] = {prefix, index: 0}) - } -} - -interface ScopePath { - property: string - itemIndex: number -} - -export class ValueScopeName extends Name { - readonly prefix: string - value?: NameValue - scopePath?: Code - - constructor(prefix: string, nameStr: string) { - super(nameStr) - this.prefix = prefix - } - - setValue(value: NameValue, {property, itemIndex}: ScopePath): void { - this.value = value - this.scopePath = _`.${new Name(property)}[${itemIndex}]` - } -} - -interface VSOptions extends ValueScopeOptions { - _n: Code -} - -const line = _`\n` - -export class ValueScope extends Scope { - protected readonly _values: ScopeValues = {} - protected readonly _scope: ScopeStore - readonly opts: VSOptions - - constructor(opts: ValueScopeOptions) { - super(opts) - this._scope = opts.scope - this.opts = {...opts, _n: opts.lines ? line : nil} - } - - get(): ScopeStore { - return this._scope - } - - name(prefix: string): ValueScopeName { - return new ValueScopeName(prefix, this._newName(prefix)) - } - - value(nameOrPrefix: ValueScopeName | string, value: NameValue): ValueScopeName { - if (value.ref === undefined) throw new Error("CodeGen: ref must be passed in value") - const name = this.toName(nameOrPrefix) as ValueScopeName - const {prefix} = name - const valueKey = value.key ?? value.ref - let vs = this._values[prefix] - if (vs) { - const _name = vs.get(valueKey) - if (_name) return _name - } else { - vs = this._values[prefix] = new Map() - } - vs.set(valueKey, name) - - const s = this._scope[prefix] || (this._scope[prefix] = []) - const itemIndex = s.length - s[itemIndex] = value.ref - name.setValue(value, {property: prefix, itemIndex}) - return name - } - - getValue(prefix: string, keyOrRef: unknown): ValueScopeName | undefined { - const vs = this._values[prefix] - if (!vs) return - return vs.get(keyOrRef) - } - - scopeRefs(scopeName: Name, values: ScopeValues | ScopeValueSets = this._values): Code { - return this._reduceValues(values, (name: ValueScopeName) => { - if (name.scopePath === undefined) throw new Error(`CodeGen: name "${name}" has no value`) - return _`${scopeName}${name.scopePath}` - }) - } - - scopeCode( - values: ScopeValues | ScopeValueSets = this._values, - usedValues?: UsedScopeValues, - getCode?: (n: ValueScopeName) => Code | undefined - ): Code { - return this._reduceValues( - values, - (name: ValueScopeName) => { - if (name.value === undefined) throw new Error(`CodeGen: name "${name}" has no value`) - return name.value.code - }, - usedValues, - getCode - ) - } - - private _reduceValues( - values: ScopeValues | ScopeValueSets, - valueCode: (n: ValueScopeName) => Code | undefined, - usedValues: UsedScopeValues = {}, - getCode?: (n: ValueScopeName) => Code | undefined - ): Code { - let code: Code = nil - for (const prefix in values) { - const vs = values[prefix] - if (!vs) continue - const nameSet = (usedValues[prefix] = usedValues[prefix] || new Map()) - vs.forEach((name: ValueScopeName) => { - if (nameSet.has(name)) return - nameSet.set(name, UsedValueState.Started) - let c = valueCode(name) - if (c) { - const def = this.opts.es5 ? varKinds.var : varKinds.const - code = _`${code}${def} ${name} = ${c};${this.opts._n}` - } else if ((c = getCode?.(name))) { - code = _`${code}${c}${this.opts._n}` - } else { - throw new ValueError(name) - } - nameSet.set(name, UsedValueState.Completed) - }) - } - return code - } -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/errors.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/errors.ts deleted file mode 100644 index 18424a0f..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/errors.ts +++ /dev/null @@ -1,184 +0,0 @@ -import type {KeywordErrorCxt, KeywordErrorDefinition} from "../types" -import type {SchemaCxt} from "./index" -import {CodeGen, _, str, strConcat, Code, Name} from "./codegen" -import {SafeExpr} from "./codegen/code" -import {getErrorPath, Type} from "./util" -import N from "./names" - -export const keywordError: KeywordErrorDefinition = { - message: ({keyword}) => str`must pass "${keyword}" keyword validation`, -} - -export const keyword$DataError: KeywordErrorDefinition = { - message: ({keyword, schemaType}) => - schemaType - ? str`"${keyword}" keyword must be ${schemaType} ($data)` - : str`"${keyword}" keyword is invalid ($data)`, -} - -export interface ErrorPaths { - instancePath?: Code - schemaPath?: string - parentSchema?: boolean -} - -export function reportError( - cxt: KeywordErrorCxt, - error: KeywordErrorDefinition = keywordError, - errorPaths?: ErrorPaths, - overrideAllErrors?: boolean -): void { - const {it} = cxt - const {gen, compositeRule, allErrors} = it - const errObj = errorObjectCode(cxt, error, errorPaths) - if (overrideAllErrors ?? (compositeRule || allErrors)) { - addError(gen, errObj) - } else { - returnErrors(it, _`[${errObj}]`) - } -} - -export function reportExtraError( - cxt: KeywordErrorCxt, - error: KeywordErrorDefinition = keywordError, - errorPaths?: ErrorPaths -): void { - const {it} = cxt - const {gen, compositeRule, allErrors} = it - const errObj = errorObjectCode(cxt, error, errorPaths) - addError(gen, errObj) - if (!(compositeRule || allErrors)) { - returnErrors(it, N.vErrors) - } -} - -export function resetErrorsCount(gen: CodeGen, errsCount: Name): void { - gen.assign(N.errors, errsCount) - gen.if(_`${N.vErrors} !== null`, () => - gen.if( - errsCount, - () => gen.assign(_`${N.vErrors}.length`, errsCount), - () => gen.assign(N.vErrors, null) - ) - ) -} - -export function extendErrors({ - gen, - keyword, - schemaValue, - data, - errsCount, - it, -}: KeywordErrorCxt): void { - /* istanbul ignore if */ - if (errsCount === undefined) throw new Error("ajv implementation error") - const err = gen.name("err") - gen.forRange("i", errsCount, N.errors, (i) => { - gen.const(err, _`${N.vErrors}[${i}]`) - gen.if(_`${err}.instancePath === undefined`, () => - gen.assign(_`${err}.instancePath`, strConcat(N.instancePath, it.errorPath)) - ) - gen.assign(_`${err}.schemaPath`, str`${it.errSchemaPath}/${keyword}`) - if (it.opts.verbose) { - gen.assign(_`${err}.schema`, schemaValue) - gen.assign(_`${err}.data`, data) - } - }) -} - -function addError(gen: CodeGen, errObj: Code): void { - const err = gen.const("err", errObj) - gen.if( - _`${N.vErrors} === null`, - () => gen.assign(N.vErrors, _`[${err}]`), - _`${N.vErrors}.push(${err})` - ) - gen.code(_`${N.errors}++`) -} - -function returnErrors(it: SchemaCxt, errs: Code): void { - const {gen, validateName, schemaEnv} = it - if (schemaEnv.$async) { - gen.throw(_`new ${it.ValidationError as Name}(${errs})`) - } else { - gen.assign(_`${validateName}.errors`, errs) - gen.return(false) - } -} - -const E = { - keyword: new Name("keyword"), - schemaPath: new Name("schemaPath"), // also used in JTD errors - params: new Name("params"), - propertyName: new Name("propertyName"), - message: new Name("message"), - schema: new Name("schema"), - parentSchema: new Name("parentSchema"), -} - -function errorObjectCode( - cxt: KeywordErrorCxt, - error: KeywordErrorDefinition, - errorPaths?: ErrorPaths -): Code { - const {createErrors} = cxt.it - if (createErrors === false) return _`{}` - return errorObject(cxt, error, errorPaths) -} - -function errorObject( - cxt: KeywordErrorCxt, - error: KeywordErrorDefinition, - errorPaths: ErrorPaths = {} -): Code { - const {gen, it} = cxt - const keyValues: [Name, SafeExpr | string][] = [ - errorInstancePath(it, errorPaths), - errorSchemaPath(cxt, errorPaths), - ] - extraErrorProps(cxt, error, keyValues) - return gen.object(...keyValues) -} - -function errorInstancePath({errorPath}: SchemaCxt, {instancePath}: ErrorPaths): [Name, Code] { - const instPath = instancePath - ? str`${errorPath}${getErrorPath(instancePath, Type.Str)}` - : errorPath - return [N.instancePath, strConcat(N.instancePath, instPath)] -} - -function errorSchemaPath( - {keyword, it: {errSchemaPath}}: KeywordErrorCxt, - {schemaPath, parentSchema}: ErrorPaths -): [Name, string | Code] { - let schPath = parentSchema ? errSchemaPath : str`${errSchemaPath}/${keyword}` - if (schemaPath) { - schPath = str`${schPath}${getErrorPath(schemaPath, Type.Str)}` - } - return [E.schemaPath, schPath] -} - -function extraErrorProps( - cxt: KeywordErrorCxt, - {params, message}: KeywordErrorDefinition, - keyValues: [Name, SafeExpr | string][] -): void { - const {keyword, data, schemaValue, it} = cxt - const {opts, propertyName, topSchemaRef, schemaPath} = it - keyValues.push( - [E.keyword, keyword], - [E.params, typeof params == "function" ? params(cxt) : params || _`{}`] - ) - if (opts.messages) { - keyValues.push([E.message, typeof message == "function" ? message(cxt) : message]) - } - if (opts.verbose) { - keyValues.push( - [E.schema, schemaValue], - [E.parentSchema, _`${topSchemaRef}${schemaPath}`], - [N.data, data] - ) - } - if (propertyName) keyValues.push([E.propertyName, propertyName]) -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/index.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/index.ts deleted file mode 100644 index ebdbe3c7..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/index.ts +++ /dev/null @@ -1,324 +0,0 @@ -import type { - AnySchema, - AnySchemaObject, - AnyValidateFunction, - AsyncValidateFunction, - EvaluatedProperties, - EvaluatedItems, -} from "../types" -import type Ajv from "../core" -import type {InstanceOptions} from "../core" -import {CodeGen, _, nil, stringify, Name, Code, ValueScopeName} from "./codegen" -import ValidationError from "../runtime/validation_error" -import N from "./names" -import {LocalRefs, getFullPath, _getFullPath, inlineRef, normalizeId, resolveUrl} from "./resolve" -import {schemaHasRulesButRef, unescapeFragment} from "./util" -import {validateFunctionCode} from "./validate" -import * as URI from "uri-js" -import {JSONType} from "./rules" - -export type SchemaRefs = { - [Ref in string]?: SchemaEnv | AnySchema -} - -export interface SchemaCxt { - readonly gen: CodeGen - readonly allErrors?: boolean // validation mode - whether to collect all errors or break on error - readonly data: Name // Name with reference to the current part of data instance - readonly parentData: Name // should be used in keywords modifying data - readonly parentDataProperty: Code | number // should be used in keywords modifying data - readonly dataNames: Name[] - readonly dataPathArr: (Code | number)[] - readonly dataLevel: number // the level of the currently validated data, - // it can be used to access both the property names and the data on all levels from the top. - dataTypes: JSONType[] // data types applied to the current part of data instance - definedProperties: Set // set of properties to keep track of for required checks - readonly topSchemaRef: Code - readonly validateName: Name - evaluated?: Name - readonly ValidationError?: Name - readonly schema: AnySchema // current schema object - equal to parentSchema passed via KeywordCxt - readonly schemaEnv: SchemaEnv - readonly rootId: string - baseId: string // the current schema base URI that should be used as the base for resolving URIs in references (\$ref) - readonly schemaPath: Code // the run-time expression that evaluates to the property name of the current schema - readonly errSchemaPath: string // this is actual string, should not be changed to Code - readonly errorPath: Code - readonly propertyName?: Name - readonly compositeRule?: boolean // true indicates that the current schema is inside the compound keyword, - // where failing some rule doesn't mean validation failure (`anyOf`, `oneOf`, `not`, `if`). - // This flag is used to determine whether you can return validation result immediately after any error in case the option `allErrors` is not `true. - // You only need to use it if you have many steps in your keywords and potentially can define multiple errors. - props?: EvaluatedProperties | Name // properties evaluated by this schema - used by parent schema or assigned to validation function - items?: EvaluatedItems | Name // last item evaluated by this schema - used by parent schema or assigned to validation function - jtdDiscriminator?: string - jtdMetadata?: boolean - readonly createErrors?: boolean - readonly opts: InstanceOptions // Ajv instance option. - readonly self: Ajv // current Ajv instance -} - -export interface SchemaObjCxt extends SchemaCxt { - readonly schema: AnySchemaObject -} -interface SchemaEnvArgs { - readonly schema: AnySchema - readonly schemaId?: "$id" | "id" - readonly root?: SchemaEnv - readonly baseId?: string - readonly schemaPath?: string - readonly localRefs?: LocalRefs - readonly meta?: boolean -} - -export class SchemaEnv implements SchemaEnvArgs { - readonly schema: AnySchema - readonly schemaId?: "$id" | "id" - readonly root: SchemaEnv - baseId: string // TODO possibly, it should be readonly - schemaPath?: string - localRefs?: LocalRefs - readonly meta?: boolean - readonly $async?: boolean // true if the current schema is asynchronous. - readonly refs: SchemaRefs = {} - readonly dynamicAnchors: {[Ref in string]?: true} = {} - validate?: AnyValidateFunction - validateName?: ValueScopeName - serialize?: (data: unknown) => string - serializeName?: ValueScopeName - parse?: (data: string) => unknown - parseName?: ValueScopeName - - constructor(env: SchemaEnvArgs) { - let schema: AnySchemaObject | undefined - if (typeof env.schema == "object") schema = env.schema - this.schema = env.schema - this.schemaId = env.schemaId - this.root = env.root || this - this.baseId = env.baseId ?? normalizeId(schema?.[env.schemaId || "$id"]) - this.schemaPath = env.schemaPath - this.localRefs = env.localRefs - this.meta = env.meta - this.$async = schema?.$async - this.refs = {} - } -} - -// let codeSize = 0 -// let nodeCount = 0 - -// Compiles schema in SchemaEnv -export function compileSchema(this: Ajv, sch: SchemaEnv): SchemaEnv { - // TODO refactor - remove compilations - const _sch = getCompilingSchema.call(this, sch) - if (_sch) return _sch - const rootId = getFullPath(sch.root.baseId) // TODO if getFullPath removed 1 tests fails - const {es5, lines} = this.opts.code - const {ownProperties} = this.opts - const gen = new CodeGen(this.scope, {es5, lines, ownProperties}) - let _ValidationError - if (sch.$async) { - _ValidationError = gen.scopeValue("Error", { - ref: ValidationError, - code: _`require("ajv/dist/runtime/validation_error").default`, - }) - } - - const validateName = gen.scopeName("validate") - sch.validateName = validateName - - const schemaCxt: SchemaCxt = { - gen, - allErrors: this.opts.allErrors, - data: N.data, - parentData: N.parentData, - parentDataProperty: N.parentDataProperty, - dataNames: [N.data], - dataPathArr: [nil], // TODO can its length be used as dataLevel if nil is removed? - dataLevel: 0, - dataTypes: [], - definedProperties: new Set(), - topSchemaRef: gen.scopeValue( - "schema", - this.opts.code.source === true - ? {ref: sch.schema, code: stringify(sch.schema)} - : {ref: sch.schema} - ), - validateName, - ValidationError: _ValidationError, - schema: sch.schema, - schemaEnv: sch, - rootId, - baseId: sch.baseId || rootId, - schemaPath: nil, - errSchemaPath: sch.schemaPath || (this.opts.jtd ? "" : "#"), - errorPath: _`""`, - opts: this.opts, - self: this, - } - - let sourceCode: string | undefined - try { - this._compilations.add(sch) - validateFunctionCode(schemaCxt) - gen.optimize(this.opts.code.optimize) - // gen.optimize(1) - const validateCode = gen.toString() - sourceCode = `${gen.scopeRefs(N.scope)}return ${validateCode}` - // console.log((codeSize += sourceCode.length), (nodeCount += gen.nodeCount)) - if (this.opts.code.process) sourceCode = this.opts.code.process(sourceCode, sch) - // console.log("\n\n\n *** \n", sourceCode) - const makeValidate = new Function(`${N.self}`, `${N.scope}`, sourceCode) - const validate: AnyValidateFunction = makeValidate(this, this.scope.get()) - this.scope.value(validateName, {ref: validate}) - - validate.errors = null - validate.schema = sch.schema - validate.schemaEnv = sch - if (sch.$async) (validate as AsyncValidateFunction).$async = true - if (this.opts.code.source === true) { - validate.source = {validateName, validateCode, scopeValues: gen._values} - } - if (this.opts.unevaluated) { - const {props, items} = schemaCxt - validate.evaluated = { - props: props instanceof Name ? undefined : props, - items: items instanceof Name ? undefined : items, - dynamicProps: props instanceof Name, - dynamicItems: items instanceof Name, - } - if (validate.source) validate.source.evaluated = stringify(validate.evaluated) - } - sch.validate = validate - return sch - } catch (e) { - delete sch.validate - delete sch.validateName - if (sourceCode) this.logger.error("Error compiling schema, function code:", sourceCode) - // console.log("\n\n\n *** \n", sourceCode, this.opts) - throw e - } finally { - this._compilations.delete(sch) - } -} - -export function resolveRef( - this: Ajv, - root: SchemaEnv, - baseId: string, - ref: string -): AnySchema | SchemaEnv | undefined { - ref = resolveUrl(baseId, ref) - const schOrFunc = root.refs[ref] - if (schOrFunc) return schOrFunc - - let _sch = resolve.call(this, root, ref) - if (_sch === undefined) { - const schema = root.localRefs?.[ref] // TODO maybe localRefs should hold SchemaEnv - const {schemaId} = this.opts - if (schema) _sch = new SchemaEnv({schema, schemaId, root, baseId}) - } - - if (_sch === undefined) return - return (root.refs[ref] = inlineOrCompile.call(this, _sch)) -} - -function inlineOrCompile(this: Ajv, sch: SchemaEnv): AnySchema | SchemaEnv { - if (inlineRef(sch.schema, this.opts.inlineRefs)) return sch.schema - return sch.validate ? sch : compileSchema.call(this, sch) -} - -// Index of schema compilation in the currently compiled list -export function getCompilingSchema(this: Ajv, schEnv: SchemaEnv): SchemaEnv | void { - for (const sch of this._compilations) { - if (sameSchemaEnv(sch, schEnv)) return sch - } -} - -function sameSchemaEnv(s1: SchemaEnv, s2: SchemaEnv): boolean { - return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId -} - -// resolve and compile the references ($ref) -// TODO returns AnySchemaObject (if the schema can be inlined) or validation function -function resolve( - this: Ajv, - root: SchemaEnv, // information about the root schema for the current schema - ref: string // reference to resolve -): SchemaEnv | undefined { - let sch - while (typeof (sch = this.refs[ref]) == "string") ref = sch - return sch || this.schemas[ref] || resolveSchema.call(this, root, ref) -} - -// Resolve schema, its root and baseId -export function resolveSchema( - this: Ajv, - root: SchemaEnv, // root object with properties schema, refs TODO below SchemaEnv is assigned to it - ref: string // reference to resolve -): SchemaEnv | undefined { - const p = URI.parse(ref) - const refPath = _getFullPath(p) - let baseId = getFullPath(root.baseId) - // TODO `Object.keys(root.schema).length > 0` should not be needed - but removing breaks 2 tests - if (Object.keys(root.schema).length > 0 && refPath === baseId) { - return getJsonPointer.call(this, p, root) - } - - const id = normalizeId(refPath) - const schOrRef = this.refs[id] || this.schemas[id] - if (typeof schOrRef == "string") { - const sch = resolveSchema.call(this, root, schOrRef) - if (typeof sch?.schema !== "object") return - return getJsonPointer.call(this, p, sch) - } - - if (typeof schOrRef?.schema !== "object") return - if (!schOrRef.validate) compileSchema.call(this, schOrRef) - if (id === normalizeId(ref)) { - const {schema} = schOrRef - const {schemaId} = this.opts - const schId = schema[schemaId] - if (schId) baseId = resolveUrl(baseId, schId) - return new SchemaEnv({schema, schemaId, root, baseId}) - } - return getJsonPointer.call(this, p, schOrRef) -} - -const PREVENT_SCOPE_CHANGE = new Set([ - "properties", - "patternProperties", - "enum", - "dependencies", - "definitions", -]) - -function getJsonPointer( - this: Ajv, - parsedRef: URI.URIComponents, - {baseId, schema, root}: SchemaEnv -): SchemaEnv | undefined { - if (parsedRef.fragment?.[0] !== "/") return - for (const part of parsedRef.fragment.slice(1).split("/")) { - if (typeof schema === "boolean") return - const partSchema = schema[unescapeFragment(part)] - if (partSchema === undefined) return - schema = partSchema - // TODO PREVENT_SCOPE_CHANGE could be defined in keyword def? - const schId = typeof schema === "object" && schema[this.opts.schemaId] - if (!PREVENT_SCOPE_CHANGE.has(part) && schId) { - baseId = resolveUrl(baseId, schId) - } - } - let env: SchemaEnv | undefined - if (typeof schema != "boolean" && schema.$ref && !schemaHasRulesButRef(schema, this.RULES)) { - const $ref = resolveUrl(baseId, schema.$ref) - env = resolveSchema.call(this, root, $ref) - } - // even though resolution failed we need to return SchemaEnv to throw exception - // so that compileAsync loads missing schema. - const {schemaId} = this.opts - env = env || new SchemaEnv({schema, schemaId, root, baseId}) - if (env.schema !== env.root.schema) return env - return undefined -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/jtd/parse.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/jtd/parse.ts deleted file mode 100644 index cd2611e7..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/jtd/parse.ts +++ /dev/null @@ -1,411 +0,0 @@ -import type Ajv from "../../core" -import type {SchemaObject} from "../../types" -import {jtdForms, JTDForm, SchemaObjectMap} from "./types" -import {SchemaEnv, getCompilingSchema} from ".." -import {_, str, and, or, nil, not, CodeGen, Code, Name, SafeExpr} from "../codegen" -import MissingRefError from "../ref_error" -import N from "../names" -import {hasPropFunc} from "../../vocabularies/code" -import {hasRef} from "../../vocabularies/jtd/ref" -import {intRange, IntType} from "../../vocabularies/jtd/type" -import {parseJson, parseJsonNumber, parseJsonString} from "../../runtime/parseJson" -import {useFunc} from "../util" -import validTimestamp from "../../runtime/timestamp" - -type GenParse = (cxt: ParseCxt) => void - -const genParse: {[F in JTDForm]: GenParse} = { - elements: parseElements, - values: parseValues, - discriminator: parseDiscriminator, - properties: parseProperties, - optionalProperties: parseProperties, - enum: parseEnum, - type: parseType, - ref: parseRef, -} - -interface ParseCxt { - readonly gen: CodeGen - readonly self: Ajv // current Ajv instance - readonly schemaEnv: SchemaEnv - readonly definitions: SchemaObjectMap - schema: SchemaObject - data: Code - parseName: Name - char: Name -} - -export default function compileParser( - this: Ajv, - sch: SchemaEnv, - definitions: SchemaObjectMap -): SchemaEnv { - const _sch = getCompilingSchema.call(this, sch) - if (_sch) return _sch - const {es5, lines} = this.opts.code - const {ownProperties} = this.opts - const gen = new CodeGen(this.scope, {es5, lines, ownProperties}) - const parseName = gen.scopeName("parse") - const cxt: ParseCxt = { - self: this, - gen, - schema: sch.schema as SchemaObject, - schemaEnv: sch, - definitions, - data: N.data, - parseName, - char: gen.name("c"), - } - - let sourceCode: string | undefined - try { - this._compilations.add(sch) - sch.parseName = parseName - parserFunction(cxt) - gen.optimize(this.opts.code.optimize) - const parseFuncCode = gen.toString() - sourceCode = `${gen.scopeRefs(N.scope)}return ${parseFuncCode}` - const makeParse = new Function(`${N.scope}`, sourceCode) - const parse: (json: string) => unknown = makeParse(this.scope.get()) - this.scope.value(parseName, {ref: parse}) - sch.parse = parse - } catch (e) { - if (sourceCode) this.logger.error("Error compiling parser, function code:", sourceCode) - delete sch.parse - delete sch.parseName - throw e - } finally { - this._compilations.delete(sch) - } - return sch -} - -const undef = _`undefined` - -function parserFunction(cxt: ParseCxt): void { - const {gen, parseName, char} = cxt - gen.func(parseName, _`${N.json}, ${N.jsonPos}, ${N.jsonPart}`, false, () => { - gen.let(N.data) - gen.let(char) - gen.assign(_`${parseName}.message`, undef) - gen.assign(_`${parseName}.position`, undef) - gen.assign(N.jsonPos, _`${N.jsonPos} || 0`) - gen.const(N.jsonLen, _`${N.json}.length`) - parseCode(cxt) - skipWhitespace(cxt) - gen.if(N.jsonPart, () => { - gen.assign(_`${parseName}.position`, N.jsonPos) - gen.return(N.data) - }) - gen.if(_`${N.jsonPos} === ${N.jsonLen}`, () => gen.return(N.data)) - jsonSyntaxError(cxt) - }) -} - -function parseCode(cxt: ParseCxt): void { - let form: JTDForm | undefined - for (const key of jtdForms) { - if (key in cxt.schema) { - form = key - break - } - } - if (form) parseNullable(cxt, genParse[form]) - else parseEmpty(cxt) -} - -const parseBoolean = parseBooleanToken(true, parseBooleanToken(false, jsonSyntaxError)) - -function parseNullable(cxt: ParseCxt, parseForm: GenParse): void { - const {gen, schema, data} = cxt - if (!schema.nullable) return parseForm(cxt) - tryParseToken(cxt, "null", parseForm, () => gen.assign(data, null)) -} - -function parseElements(cxt: ParseCxt): void { - const {gen, schema, data} = cxt - parseToken(cxt, "[") - const ix = gen.let("i", 0) - gen.assign(data, _`[]`) - parseItems(cxt, "]", () => { - const el = gen.let("el") - parseCode({...cxt, schema: schema.elements, data: el}) - gen.assign(_`${data}[${ix}++]`, el) - }) -} - -function parseValues(cxt: ParseCxt): void { - const {gen, schema, data} = cxt - parseToken(cxt, "{") - gen.assign(data, _`{}`) - parseItems(cxt, "}", () => parseKeyValue(cxt, schema.values)) -} - -function parseItems(cxt: ParseCxt, endToken: string, block: () => void): void { - tryParseItems(cxt, endToken, block) - parseToken(cxt, endToken) -} - -function tryParseItems(cxt: ParseCxt, endToken: string, block: () => void): void { - const {gen} = cxt - gen.for(_`;${N.jsonPos}<${N.jsonLen} && ${jsonSlice(1)}!==${endToken};`, () => { - block() - tryParseToken(cxt, ",", () => gen.break(), hasItem) - }) - - function hasItem(): void { - tryParseToken(cxt, endToken, () => {}, jsonSyntaxError) - } -} - -function parseKeyValue(cxt: ParseCxt, schema: SchemaObject): void { - const {gen} = cxt - const key = gen.let("key") - parseString({...cxt, data: key}) - parseToken(cxt, ":") - parsePropertyValue(cxt, key, schema) -} - -function parseDiscriminator(cxt: ParseCxt): void { - const {gen, data, schema} = cxt - const {discriminator, mapping} = schema - parseToken(cxt, "{") - gen.assign(data, _`{}`) - const startPos = gen.const("pos", N.jsonPos) - const value = gen.let("value") - const tag = gen.let("tag") - tryParseItems(cxt, "}", () => { - const key = gen.let("key") - parseString({...cxt, data: key}) - parseToken(cxt, ":") - gen.if( - _`${key} === ${discriminator}`, - () => { - parseString({...cxt, data: tag}) - gen.assign(_`${data}[${key}]`, tag) - gen.break() - }, - () => parseEmpty({...cxt, data: value}) // can be discarded/skipped - ) - }) - gen.assign(N.jsonPos, startPos) - gen.if(_`${tag} === undefined`) - parsingError(cxt, str`discriminator tag not found`) - for (const tagValue in mapping) { - gen.elseIf(_`${tag} === ${tagValue}`) - parseSchemaProperties({...cxt, schema: mapping[tagValue]}, discriminator) - } - gen.else() - parsingError(cxt, str`discriminator value not in schema`) - gen.endIf() -} - -function parseProperties(cxt: ParseCxt): void { - const {gen, data} = cxt - parseToken(cxt, "{") - gen.assign(data, _`{}`) - parseSchemaProperties(cxt) -} - -function parseSchemaProperties(cxt: ParseCxt, discriminator?: string): void { - const {gen, schema, data} = cxt - const {properties, optionalProperties, additionalProperties} = schema - parseItems(cxt, "}", () => { - const key = gen.let("key") - parseString({...cxt, data: key}) - parseToken(cxt, ":") - gen.if(false) - parseDefinedProperty(cxt, key, properties) - parseDefinedProperty(cxt, key, optionalProperties) - if (discriminator) { - gen.elseIf(_`${key} === ${discriminator}`) - const tag = gen.let("tag") - parseString({...cxt, data: tag}) // can be discarded, it is already assigned - } - gen.else() - if (additionalProperties) { - parseEmpty({...cxt, data: _`${data}[${key}]`}) - } else { - parsingError(cxt, str`property ${key} not allowed`) - } - gen.endIf() - }) - if (properties) { - const hasProp = hasPropFunc(gen) - const allProps: Code = and( - ...Object.keys(properties).map((p): Code => _`${hasProp}.call(${data}, ${p})`) - ) - gen.if(not(allProps), () => parsingError(cxt, str`missing required properties`)) - } -} - -function parseDefinedProperty(cxt: ParseCxt, key: Name, schemas: SchemaObjectMap = {}): void { - const {gen} = cxt - for (const prop in schemas) { - gen.elseIf(_`${key} === ${prop}`) - parsePropertyValue(cxt, key, schemas[prop] as SchemaObject) - } -} - -function parsePropertyValue(cxt: ParseCxt, key: Name, schema: SchemaObject): void { - parseCode({...cxt, schema, data: _`${cxt.data}[${key}]`}) -} - -function parseType(cxt: ParseCxt): void { - const {gen, schema, data, self} = cxt - switch (schema.type) { - case "boolean": - parseBoolean(cxt) - break - case "string": - parseString(cxt) - break - case "timestamp": { - parseString(cxt) - const vts = useFunc(gen, validTimestamp) - const {allowDate, parseDate} = self.opts - const notValid = allowDate ? _`!${vts}(${data}, true)` : _`!${vts}(${data})` - const fail: Code = parseDate - ? or(notValid, _`(${data} = new Date(${data}), false)`, _`isNaN(${data}.valueOf())`) - : notValid - gen.if(fail, () => parsingError(cxt, str`invalid timestamp`)) - break - } - case "float32": - case "float64": - parseNumber(cxt) - break - default: { - const t = schema.type as IntType - if (!self.opts.int32range && (t === "int32" || t === "uint32")) { - parseNumber(cxt, 16) // 2 ** 53 - max safe integer - if (t === "uint32") { - gen.if(_`${data} < 0`, () => parsingError(cxt, str`integer out of range`)) - } - } else { - const [min, max, maxDigits] = intRange[t] - parseNumber(cxt, maxDigits) - gen.if(_`${data} < ${min} || ${data} > ${max}`, () => - parsingError(cxt, str`integer out of range`) - ) - } - } - } -} - -function parseString(cxt: ParseCxt): void { - parseToken(cxt, '"') - parseWith(cxt, parseJsonString) -} - -function parseEnum(cxt: ParseCxt): void { - const {gen, data, schema} = cxt - const enumSch = schema.enum - parseToken(cxt, '"') - // TODO loopEnum - gen.if(false) - for (const value of enumSch) { - const valueStr = JSON.stringify(value).slice(1) // remove starting quote - gen.elseIf(_`${jsonSlice(valueStr.length)} === ${valueStr}`) - gen.assign(data, str`${value}`) - gen.add(N.jsonPos, valueStr.length) - } - gen.else() - jsonSyntaxError(cxt) - gen.endIf() -} - -function parseNumber(cxt: ParseCxt, maxDigits?: number): void { - const {gen} = cxt - skipWhitespace(cxt) - gen.if( - _`"-0123456789".indexOf(${jsonSlice(1)}) < 0`, - () => jsonSyntaxError(cxt), - () => parseWith(cxt, parseJsonNumber, maxDigits) - ) -} - -function parseBooleanToken(bool: boolean, fail: GenParse): GenParse { - return (cxt) => { - const {gen, data} = cxt - tryParseToken( - cxt, - `${bool}`, - () => fail(cxt), - () => gen.assign(data, bool) - ) - } -} - -function parseRef(cxt: ParseCxt): void { - const {gen, self, definitions, schema, schemaEnv} = cxt - const {ref} = schema - const refSchema = definitions[ref] - if (!refSchema) throw new MissingRefError("", ref, `No definition ${ref}`) - if (!hasRef(refSchema)) return parseCode({...cxt, schema: refSchema}) - const {root} = schemaEnv - const sch = compileParser.call(self, new SchemaEnv({schema: refSchema, root}), definitions) - partialParse(cxt, getParser(gen, sch), true) -} - -function getParser(gen: CodeGen, sch: SchemaEnv): Code { - return sch.parse - ? gen.scopeValue("parse", {ref: sch.parse}) - : _`${gen.scopeValue("wrapper", {ref: sch})}.parse` -} - -function parseEmpty(cxt: ParseCxt): void { - parseWith(cxt, parseJson) -} - -function parseWith(cxt: ParseCxt, parseFunc: {code: string}, args?: SafeExpr): void { - partialParse(cxt, useFunc(cxt.gen, parseFunc), args) -} - -function partialParse(cxt: ParseCxt, parseFunc: Name, args?: SafeExpr): void { - const {gen, data} = cxt - gen.assign(data, _`${parseFunc}(${N.json}, ${N.jsonPos}${args ? _`, ${args}` : nil})`) - gen.assign(N.jsonPos, _`${parseFunc}.position`) - gen.if(_`${data} === undefined`, () => parsingError(cxt, _`${parseFunc}.message`)) -} - -function parseToken(cxt: ParseCxt, tok: string): void { - tryParseToken(cxt, tok, jsonSyntaxError) -} - -function tryParseToken(cxt: ParseCxt, tok: string, fail: GenParse, success?: GenParse): void { - const {gen} = cxt - const n = tok.length - skipWhitespace(cxt) - gen.if( - _`${jsonSlice(n)} === ${tok}`, - () => { - gen.add(N.jsonPos, n) - success?.(cxt) - }, - () => fail(cxt) - ) -} - -function skipWhitespace({gen, char: c}: ParseCxt): void { - gen.code( - _`while((${c}=${N.json}[${N.jsonPos}],${c}===" "||${c}==="\\n"||${c}==="\\r"||${c}==="\\t"))${N.jsonPos}++;` - ) -} - -function jsonSlice(len: number | Name): Code { - return len === 1 - ? _`${N.json}[${N.jsonPos}]` - : _`${N.json}.slice(${N.jsonPos}, ${N.jsonPos}+${len})` -} - -function jsonSyntaxError(cxt: ParseCxt): void { - parsingError(cxt, _`"unexpected token " + ${N.json}[${N.jsonPos}]`) -} - -function parsingError({gen, parseName}: ParseCxt, msg: Code): void { - gen.assign(_`${parseName}.message`, msg) - gen.assign(_`${parseName}.position`, N.jsonPos) - gen.return(undef) -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/jtd/serialize.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/jtd/serialize.ts deleted file mode 100644 index a8b36bd8..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/jtd/serialize.ts +++ /dev/null @@ -1,260 +0,0 @@ -import type Ajv from "../../core" -import type {SchemaObject} from "../../types" -import {jtdForms, JTDForm, SchemaObjectMap} from "./types" -import {SchemaEnv, getCompilingSchema} from ".." -import {_, str, and, getProperty, CodeGen, Code, Name} from "../codegen" -import MissingRefError from "../ref_error" -import N from "../names" -import {isOwnProperty} from "../../vocabularies/code" -import {hasRef} from "../../vocabularies/jtd/ref" -import {useFunc} from "../util" -import quote from "../../runtime/quote" - -const genSerialize: {[F in JTDForm]: (cxt: SerializeCxt) => void} = { - elements: serializeElements, - values: serializeValues, - discriminator: serializeDiscriminator, - properties: serializeProperties, - optionalProperties: serializeProperties, - enum: serializeString, - type: serializeType, - ref: serializeRef, -} - -interface SerializeCxt { - readonly gen: CodeGen - readonly self: Ajv // current Ajv instance - readonly schemaEnv: SchemaEnv - readonly definitions: SchemaObjectMap - schema: SchemaObject - data: Code -} - -export default function compileSerializer( - this: Ajv, - sch: SchemaEnv, - definitions: SchemaObjectMap -): SchemaEnv { - const _sch = getCompilingSchema.call(this, sch) - if (_sch) return _sch - const {es5, lines} = this.opts.code - const {ownProperties} = this.opts - const gen = new CodeGen(this.scope, {es5, lines, ownProperties}) - const serializeName = gen.scopeName("serialize") - const cxt: SerializeCxt = { - self: this, - gen, - schema: sch.schema as SchemaObject, - schemaEnv: sch, - definitions, - data: N.data, - } - - let sourceCode: string | undefined - try { - this._compilations.add(sch) - sch.serializeName = serializeName - gen.func(serializeName, N.data, false, () => { - gen.let(N.json, str``) - serializeCode(cxt) - gen.return(N.json) - }) - gen.optimize(this.opts.code.optimize) - const serializeFuncCode = gen.toString() - sourceCode = `${gen.scopeRefs(N.scope)}return ${serializeFuncCode}` - const makeSerialize = new Function(`${N.scope}`, sourceCode) - const serialize: (data: unknown) => string = makeSerialize(this.scope.get()) - this.scope.value(serializeName, {ref: serialize}) - sch.serialize = serialize - } catch (e) { - if (sourceCode) this.logger.error("Error compiling serializer, function code:", sourceCode) - delete sch.serialize - delete sch.serializeName - throw e - } finally { - this._compilations.delete(sch) - } - return sch -} - -function serializeCode(cxt: SerializeCxt): void { - let form: JTDForm | undefined - for (const key of jtdForms) { - if (key in cxt.schema) { - form = key - break - } - } - serializeNullable(cxt, form ? genSerialize[form] : serializeEmpty) -} - -function serializeNullable(cxt: SerializeCxt, serializeForm: (_cxt: SerializeCxt) => void): void { - const {gen, schema, data} = cxt - if (!schema.nullable) return serializeForm(cxt) - gen.if( - _`${data} === undefined || ${data} === null`, - () => gen.add(N.json, _`"null"`), - () => serializeForm(cxt) - ) -} - -function serializeElements(cxt: SerializeCxt): void { - const {gen, schema, data} = cxt - gen.add(N.json, str`[`) - const first = gen.let("first", true) - gen.forOf("el", data, (el) => { - addComma(cxt, first) - serializeCode({...cxt, schema: schema.elements, data: el}) - }) - gen.add(N.json, str`]`) -} - -function serializeValues(cxt: SerializeCxt): void { - const {gen, schema, data} = cxt - gen.add(N.json, str`{`) - const first = gen.let("first", true) - gen.forIn("key", data, (key) => serializeKeyValue(cxt, key, schema.values, first)) - gen.add(N.json, str`}`) -} - -function serializeKeyValue(cxt: SerializeCxt, key: Name, schema: SchemaObject, first: Name): void { - const {gen, data} = cxt - addComma(cxt, first) - serializeString({...cxt, data: key}) - gen.add(N.json, str`:`) - const value = gen.const("value", _`${data}${getProperty(key)}`) - serializeCode({...cxt, schema, data: value}) -} - -function serializeDiscriminator(cxt: SerializeCxt): void { - const {gen, schema, data} = cxt - const {discriminator} = schema - gen.add(N.json, str`{${JSON.stringify(discriminator)}:`) - const tag = gen.const("tag", _`${data}${getProperty(discriminator)}`) - serializeString({...cxt, data: tag}) - gen.if(false) - for (const tagValue in schema.mapping) { - gen.elseIf(_`${tag} === ${tagValue}`) - const sch = schema.mapping[tagValue] - serializeSchemaProperties({...cxt, schema: sch}, discriminator) - } - gen.endIf() - gen.add(N.json, str`}`) -} - -function serializeProperties(cxt: SerializeCxt): void { - const {gen} = cxt - gen.add(N.json, str`{`) - serializeSchemaProperties(cxt) - gen.add(N.json, str`}`) -} - -function serializeSchemaProperties(cxt: SerializeCxt, discriminator?: string): void { - const {gen, schema, data} = cxt - const {properties, optionalProperties} = schema - const props = keys(properties) - const optProps = keys(optionalProperties) - const allProps = allProperties(props.concat(optProps)) - let first = !discriminator - for (const key of props) { - serializeProperty(key, properties[key], keyValue(key)) - } - for (const key of optProps) { - const value = keyValue(key) - gen.if(and(_`${value} !== undefined`, isOwnProperty(gen, data, key)), () => - serializeProperty(key, optionalProperties[key], value) - ) - } - if (schema.additionalProperties) { - gen.forIn("key", data, (key) => - gen.if(isAdditional(key, allProps), () => - serializeKeyValue(cxt, key, {}, gen.let("first", first)) - ) - ) - } - - function keys(ps?: SchemaObjectMap): string[] { - return ps ? Object.keys(ps) : [] - } - - function allProperties(ps: string[]): string[] { - if (discriminator) ps.push(discriminator) - if (new Set(ps).size !== ps.length) { - throw new Error("JTD: properties/optionalProperties/disciminator overlap") - } - return ps - } - - function keyValue(key: string): Name { - return gen.const("value", _`${data}${getProperty(key)}`) - } - - function serializeProperty(key: string, propSchema: SchemaObject, value: Name): void { - if (first) first = false - else gen.add(N.json, str`,`) - gen.add(N.json, str`${JSON.stringify(key)}:`) - serializeCode({...cxt, schema: propSchema, data: value}) - } - - function isAdditional(key: Name, ps: string[]): Code | true { - return ps.length ? and(...ps.map((p) => _`${key} !== ${p}`)) : true - } -} - -function serializeType(cxt: SerializeCxt): void { - const {gen, schema, data} = cxt - switch (schema.type) { - case "boolean": - gen.add(N.json, _`${data} ? "true" : "false"`) - break - case "string": - serializeString(cxt) - break - case "timestamp": - gen.if( - _`${data} instanceof Date`, - () => gen.add(N.json, _`'"' + ${data}.toISOString() + '"'`), - () => serializeString(cxt) - ) - break - default: - serializeNumber(cxt) - } -} - -function serializeString({gen, data}: SerializeCxt): void { - gen.add(N.json, _`${useFunc(gen, quote)}(${data})`) -} - -function serializeNumber({gen, data}: SerializeCxt): void { - gen.add(N.json, _`"" + ${data}`) -} - -function serializeRef(cxt: SerializeCxt): void { - const {gen, self, data, definitions, schema, schemaEnv} = cxt - const {ref} = schema - const refSchema = definitions[ref] - if (!refSchema) throw new MissingRefError("", ref, `No definition ${ref}`) - if (!hasRef(refSchema)) return serializeCode({...cxt, schema: refSchema}) - const {root} = schemaEnv - const sch = compileSerializer.call(self, new SchemaEnv({schema: refSchema, root}), definitions) - gen.add(N.json, _`${getSerialize(gen, sch)}(${data})`) -} - -function getSerialize(gen: CodeGen, sch: SchemaEnv): Code { - return sch.serialize - ? gen.scopeValue("serialize", {ref: sch.serialize}) - : _`${gen.scopeValue("wrapper", {ref: sch})}.serialize` -} - -function serializeEmpty({gen, data}: SerializeCxt): void { - gen.add(N.json, _`JSON.stringify(${data})`) -} - -function addComma({gen}: SerializeCxt, first: Name): void { - gen.if( - first, - () => gen.assign(first, false), - () => gen.add(N.json, str`,`) - ) -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/jtd/types.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/jtd/types.ts deleted file mode 100644 index 7f361957..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/jtd/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type {SchemaObject} from "../../types" - -export type SchemaObjectMap = {[Ref in string]?: SchemaObject} - -export const jtdForms = [ - "elements", - "values", - "discriminator", - "properties", - "optionalProperties", - "enum", - "type", - "ref", -] as const - -export type JTDForm = typeof jtdForms[number] diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/names.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/names.ts deleted file mode 100644 index b4b242e1..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/names.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {Name} from "./codegen" - -const names = { - // validation function arguments - data: new Name("data"), // data passed to validation function - // args passed from referencing schema - valCxt: new Name("valCxt"), // validation/data context - should not be used directly, it is destructured to the names below - instancePath: new Name("instancePath"), - parentData: new Name("parentData"), - parentDataProperty: new Name("parentDataProperty"), - rootData: new Name("rootData"), // root data - same as the data passed to the first/top validation function - dynamicAnchors: new Name("dynamicAnchors"), // used to support recursiveRef and dynamicRef - // function scoped variables - vErrors: new Name("vErrors"), // null or array of validation errors - errors: new Name("errors"), // counter of validation errors - this: new Name("this"), - // "globals" - self: new Name("self"), - scope: new Name("scope"), - // JTD serialize/parse name for JSON string and position - json: new Name("json"), - jsonPos: new Name("jsonPos"), - jsonLen: new Name("jsonLen"), - jsonPart: new Name("jsonPart"), -} - -export default names diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/ref_error.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/ref_error.ts deleted file mode 100644 index 22b70b99..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/ref_error.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {resolveUrl, normalizeId, getFullPath} from "./resolve" - -export default class MissingRefError extends Error { - readonly missingRef: string - readonly missingSchema: string - - constructor(baseId: string, ref: string, msg?: string) { - super(msg || `can't resolve reference ${ref} from id ${baseId}`) - this.missingRef = resolveUrl(baseId, ref) - this.missingSchema = normalizeId(getFullPath(this.missingRef)) - } -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/resolve.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/resolve.ts deleted file mode 100644 index 9031e039..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/resolve.ts +++ /dev/null @@ -1,146 +0,0 @@ -import type {AnySchema, AnySchemaObject} from "../types" -import type Ajv from "../ajv" -import {eachItem} from "./util" -import * as equal from "fast-deep-equal" -import * as traverse from "json-schema-traverse" -import * as URI from "uri-js" - -// the hash of local references inside the schema (created by getSchemaRefs), used for inline resolution -export type LocalRefs = {[Ref in string]?: AnySchemaObject} - -// TODO refactor to use keyword definitions -const SIMPLE_INLINED = new Set([ - "type", - "format", - "pattern", - "maxLength", - "minLength", - "maxProperties", - "minProperties", - "maxItems", - "minItems", - "maximum", - "minimum", - "uniqueItems", - "multipleOf", - "required", - "enum", - "const", -]) - -export function inlineRef(schema: AnySchema, limit: boolean | number = true): boolean { - if (typeof schema == "boolean") return true - if (limit === true) return !hasRef(schema) - if (!limit) return false - return countKeys(schema) <= limit -} - -const REF_KEYWORDS = new Set([ - "$ref", - "$recursiveRef", - "$recursiveAnchor", - "$dynamicRef", - "$dynamicAnchor", -]) - -function hasRef(schema: AnySchemaObject): boolean { - for (const key in schema) { - if (REF_KEYWORDS.has(key)) return true - const sch = schema[key] - if (Array.isArray(sch) && sch.some(hasRef)) return true - if (typeof sch == "object" && hasRef(sch)) return true - } - return false -} - -function countKeys(schema: AnySchemaObject): number { - let count = 0 - for (const key in schema) { - if (key === "$ref") return Infinity - count++ - if (SIMPLE_INLINED.has(key)) continue - if (typeof schema[key] == "object") { - eachItem(schema[key], (sch) => (count += countKeys(sch))) - } - if (count === Infinity) return Infinity - } - return count -} - -export function getFullPath(id = "", normalize?: boolean): string { - if (normalize !== false) id = normalizeId(id) - const p = URI.parse(id) - return _getFullPath(p) -} - -export function _getFullPath(p: URI.URIComponents): string { - return URI.serialize(p).split("#")[0] + "#" -} - -const TRAILING_SLASH_HASH = /#\/?$/ -export function normalizeId(id: string | undefined): string { - return id ? id.replace(TRAILING_SLASH_HASH, "") : "" -} - -export function resolveUrl(baseId: string, id: string): string { - id = normalizeId(id) - return URI.resolve(baseId, id) -} - -const ANCHOR = /^[a-z_][-a-z0-9._]*$/i - -export function getSchemaRefs(this: Ajv, schema: AnySchema, baseId: string): LocalRefs { - if (typeof schema == "boolean") return {} - const {schemaId} = this.opts - const schId = normalizeId(schema[schemaId] || baseId) - const baseIds: {[JsonPtr in string]?: string} = {"": schId} - const pathPrefix = getFullPath(schId, false) - const localRefs: LocalRefs = {} - const schemaRefs: Set = new Set() - - traverse(schema, {allKeys: true}, (sch, jsonPtr, _, parentJsonPtr) => { - if (parentJsonPtr === undefined) return - const fullPath = pathPrefix + jsonPtr - let baseId = baseIds[parentJsonPtr] - if (typeof sch[schemaId] == "string") baseId = addRef.call(this, sch[schemaId]) - addAnchor.call(this, sch.$anchor) - addAnchor.call(this, sch.$dynamicAnchor) - baseIds[jsonPtr] = baseId - - function addRef(this: Ajv, ref: string): string { - ref = normalizeId(baseId ? URI.resolve(baseId, ref) : ref) - if (schemaRefs.has(ref)) throw ambiguos(ref) - schemaRefs.add(ref) - let schOrRef = this.refs[ref] - if (typeof schOrRef == "string") schOrRef = this.refs[schOrRef] - if (typeof schOrRef == "object") { - checkAmbiguosRef(sch, schOrRef.schema, ref) - } else if (ref !== normalizeId(fullPath)) { - if (ref[0] === "#") { - checkAmbiguosRef(sch, localRefs[ref], ref) - localRefs[ref] = sch - } else { - this.refs[ref] = fullPath - } - } - return ref - } - - function addAnchor(this: Ajv, anchor: unknown): void { - if (typeof anchor == "string") { - if (!ANCHOR.test(anchor)) throw new Error(`invalid anchor "${anchor}"`) - addRef.call(this, `#${anchor}`) - } - } - }) - - return localRefs - - function checkAmbiguosRef(sch1: AnySchema, sch2: AnySchema | undefined, ref: string): void { - if (sch2 !== undefined && !equal(sch1, sch2)) throw ambiguos(ref) - } - - function ambiguos(ref: string): Error { - return new Error(`reference "${ref}" resolves to more than one schema`) - } -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/rules.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/rules.ts deleted file mode 100644 index ea65074f..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/rules.ts +++ /dev/null @@ -1,50 +0,0 @@ -import type {AddedKeywordDefinition} from "../types" - -const _jsonTypes = ["string", "number", "integer", "boolean", "null", "object", "array"] as const - -export type JSONType = typeof _jsonTypes[number] - -const jsonTypes: Set = new Set(_jsonTypes) - -export function isJSONType(x: unknown): x is JSONType { - return typeof x == "string" && jsonTypes.has(x) -} - -type ValidationTypes = { - [K in JSONType]: boolean | RuleGroup | undefined -} - -export interface ValidationRules { - rules: RuleGroup[] - post: RuleGroup - all: {[Key in string]?: boolean | Rule} // rules that have to be validated - keywords: {[Key in string]?: boolean} // all known keywords (superset of "all") - types: ValidationTypes -} - -export interface RuleGroup { - type?: JSONType - rules: Rule[] -} - -// This interface wraps KeywordDefinition because definition can have multiple keywords -export interface Rule { - keyword: string - definition: AddedKeywordDefinition -} - -export function getRules(): ValidationRules { - const groups: Record<"number" | "string" | "array" | "object", RuleGroup> = { - number: {type: "number", rules: []}, - string: {type: "string", rules: []}, - array: {type: "array", rules: []}, - object: {type: "object", rules: []}, - } - return { - types: {...groups, integer: true, boolean: true, null: true}, - rules: [{rules: []}, groups.number, groups.string, groups.array, groups.object], - post: {rules: []}, - all: {}, - keywords: {}, - } -} diff --git a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/util.ts b/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/util.ts deleted file mode 100644 index cefae51c..00000000 --- a/sandbox/testAppNevena/Front/node_modules/ajv/lib/compile/util.ts +++ /dev/null @@ -1,213 +0,0 @@ -import type {AnySchema, EvaluatedProperties, EvaluatedItems} from "../types" -import type {SchemaCxt, SchemaObjCxt} from "." -import {_, getProperty, Code, Name, CodeGen} from "./codegen" -import {_Code} from "./codegen/code" -import type {Rule, ValidationRules} from "./rules" - -// TODO refactor to use Set -export function toHash(arr: T[]): {[K in T]?: true} { - const hash: {[K in T]?: true} = {} - for (const item of arr) hash[item] = true - return hash -} - -export function alwaysValidSchema(it: SchemaCxt, schema: AnySchema): boolean | void { - if (typeof schema == "boolean") return schema - if (Object.keys(schema).length === 0) return true - checkUnknownRules(it, schema) - return !schemaHasRules(schema, it.self.RULES.all) -} - -export function checkUnknownRules(it: SchemaCxt, schema: AnySchema = it.schema): void { - const {opts, self} = it - if (!opts.strictSchema) return - if (typeof schema === "boolean") return - const rules = self.RULES.keywords - for (const key in schema) { - if (!rules[key]) checkStrictMode(it, `unknown keyword: "${key}"`) - } -} - -export function schemaHasRules( - schema: AnySchema, - rules: {[Key in string]?: boolean | Rule} -): boolean { - if (typeof schema == "boolean") return !schema - for (const key in schema) if (rules[key]) return true - return false -} - -export function schemaHasRulesButRef(schema: AnySchema, RULES: ValidationRules): boolean { - if (typeof schema == "boolean") return !schema - for (const key in schema) if (key !== "$ref" && RULES.all[key]) return true - return false -} - -export function schemaRefOrVal( - {topSchemaRef, schemaPath}: SchemaObjCxt, - schema: unknown, - keyword: string, - $data?: string | false -): Code | number | boolean { - if (!$data) { - if (typeof schema == "number" || typeof schema == "boolean") return schema - if (typeof schema == "string") return _`${schema}` - } - return _`${topSchemaRef}${schemaPath}${getProperty(keyword)}` -} - -export function unescapeFragment(str: string): string { - return unescapeJsonPointer(decodeURIComponent(str)) -} - -export function escapeFragment(str: string | number): string { - return encodeURIComponent(escapeJsonPointer(str)) -} - -export function escapeJsonPointer(str: string | number): string { - if (typeof str == "number") return `${str}` - return str.replace(/~/g, "~0").replace(/\//g, "~1") -} - -export function unescapeJsonPointer(str: string): string { - return str.replace(/~1/g, "/").replace(/~0/g, "~") -} - -export function eachItem(xs: T | T[], f: (x: T) => void): void { - if (Array.isArray(xs)) { - for (const x of xs) f(x) - } else { - f(xs) - } -} - -type SomeEvaluated = EvaluatedProperties | EvaluatedItems - -type MergeEvaluatedFunc = ( - gen: CodeGen, - from: Name | T, - to: Name | Exclude | undefined, - toName?: typeof Name -) => Name | T - -interface MakeMergeFuncArgs { - mergeNames: (gen: CodeGen, from: Name, to: Name) => void - mergeToName: (gen: CodeGen, from: T, to: Name) => void - mergeValues: (from: T, to: Exclude) => T - resultToName: (gen: CodeGen, res?: T) => Name -} - -function makeMergeEvaluated({ - mergeNames, - mergeToName, - mergeValues, - resultToName, -}: MakeMergeFuncArgs): MergeEvaluatedFunc { - return (gen, from, to, toName) => { - const res = - to === undefined - ? from - : to instanceof Name - ? (from instanceof Name ? mergeNames(gen, from, to) : mergeToName(gen, from, to), to) - : from instanceof Name - ? (mergeToName(gen, to, from), from) - : mergeValues(from, to) - return toName === Name && !(res instanceof Name) ? resultToName(gen, res) : res - } -} - -interface MergeEvaluated { - props: MergeEvaluatedFunc - items: MergeEvaluatedFunc -} - -export const mergeEvaluated: MergeEvaluated = { - props: makeMergeEvaluated({ - mergeNames: (gen, from, to) => - gen.if(_`${to} !== true && ${from} !== undefined`, () => { - gen.if( - _`${from} === true`, - () => gen.assign(to, true), - () => gen.assign(to, _`${to} || {}`).code(_`Object.assign(${to}, ${from})`) - ) - }), - mergeToName: (gen, from, to) => - gen.if(_`${to} !== true`, () => { - if (from === true) { - gen.assign(to, true) - } else { - gen.assign(to, _`${to} || {}`) - setEvaluated(gen, to, from) - } - }), - mergeValues: (from, to) => (from === true ? true : {...from, ...to}), - resultToName: evaluatedPropsToName, - }), - items: makeMergeEvaluated({ - mergeNames: (gen, from, to) => - gen.if(_`${to} !== true && ${from} !== undefined`, () => - gen.assign(to, _`${from} === true ? true : ${to} > ${from} ? ${to} : ${from}`) - ), - mergeToName: (gen, from, to) => - gen.if(_`${to} !== true`, () => - gen.assign(to, from === true ? true : _`${to} > ${from} ? ${to} : ${from}`) - ), - mergeValues: (from, to) => (from === true ? true : Math.max(from, to)), - resultToName: (gen, items) => gen.var("items", items), - }), -} - -export function evaluatedPropsToName(gen: CodeGen, ps?: EvaluatedProperties): Name { - if (ps === true) return gen.var("props", true) - const props = gen.var("props", _`{}`) - if (ps !== undefined) setEvaluated(gen, props, ps) - return props -} - -export function setEvaluated(gen: CodeGen, props: Name, ps: {[K in string]?: true}): void { - Object.keys(ps).forEach((p) => gen.assign(_`${props}${getProperty(p)}`, true)) -} - -const snippets: {[S in string]?: _Code} = {} - -export function useFunc(gen: CodeGen, f: {code: string}): Name { - return gen.scopeValue("func", { - ref: f, - code: snippets[f.code] || (snippets[f.code] = new _Code(f.code)), - }) -} - -export enum Type { - Num, - Str, -} - -export function getErrorPath( - dataProp: Name | string | number, - dataPropType?: Type, - jsPropertySyntax?: boolean -): Code | string { - // let path - if (dataProp instanceof Name) { - const isNumber = dataPropType === Type.Num - return jsPropertySyntax - ? isNumber - ? _`"[" + ${dataProp} + "]"` - : _`"['" + ${dataProp} + "']"` - : isNumber - ? _`"/" + ${dataProp}` - : _`"/" + ${dataProp}.replace(/~/g, "~0").replace(/\\//g, "~1")` // TODO maybe use global escapePointer - } - return jsPropertySyntax ? getProperty(dataProp).toString() : "/" + escapeJsonPointer(dataProp) -} - -export function checkStrictMode( - it: SchemaCxt, - msg: string, - mode: boolean | "log" = it.opts.strictSchema -): void { - if (!mode) return - msg = `strict mode: ${msg}` - if (mode === true) throw new Error(msg) - it.self.logger.warn(msg) -} 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