web3-validator
Advanced tools
Comparing version 1.0.3-dev.ad377d1.0 to 1.0.3-dev.b93934a.0
@@ -21,14 +21,3 @@ "use strict"; | ||
const web3_errors_1 = require("web3-errors"); | ||
const object_js_1 = require("./validation/object.js"); | ||
const errorFormatter = (error) => { | ||
if (error.message && error.instancePath && error.params && !(0, object_js_1.isNullish)(error.params.value)) { | ||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions | ||
return `value "${error.params.value}" at "${error.instancePath}" ${error.message}`; | ||
} | ||
if (error.message && error.instancePath) { | ||
return `value at "${error.instancePath}" ${error.message}`; | ||
} | ||
if (error.instancePath) { | ||
return `value at "${error.instancePath}" caused unspecified error`; | ||
} | ||
if (error.message) { | ||
@@ -47,4 +36,3 @@ return error.message; | ||
_compileErrors() { | ||
const errorMsgs = this.errors.map(errorFormatter); | ||
return errorMsgs; | ||
return this.errors.map(errorFormatter); | ||
} | ||
@@ -51,0 +39,0 @@ } |
@@ -36,3 +36,4 @@ "use strict"; | ||
} | ||
formats.bytes256 = formats.bytes; | ||
exports.default = formats; | ||
//# sourceMappingURL=formats.js.map |
import { AbiParameter } from 'web3-types'; | ||
import { ValidationError } from 'is-my-json-valid'; | ||
import { ZodIssueBase } from 'zod'; | ||
export declare type ValidInputTypes = Uint8Array | bigint | string | number | boolean; | ||
@@ -8,3 +8,3 @@ export declare type EthBaseTypes = 'bool' | 'bytes' | 'string' | 'uint' | 'int' | 'address' | 'tuple'; | ||
export declare type FullValidationSchema = ReadonlyArray<AbiParameter>; | ||
export declare type ShortValidationSchema = ReadonlyArray<string | EthBaseTypes | EthExtendedTypes | EthBaseTypesWithMeta | EthBaseTypesWithMeta | ShortValidationSchema>; | ||
export declare type ShortValidationSchema = ReadonlyArray<string | EthBaseTypes | EthExtendedTypes | EthBaseTypesWithMeta | ShortValidationSchema>; | ||
export declare type ValidationSchemaInput = FullValidationSchema | ShortValidationSchema; | ||
@@ -17,2 +17,7 @@ export declare type Web3ValidationOptions = { | ||
}; | ||
export declare type ValidationError = ZodIssueBase; | ||
export interface Validate { | ||
(value: Json): boolean; | ||
errors?: ValidationError[]; | ||
} | ||
export declare type Schema = { | ||
@@ -102,9 +107,2 @@ $schema?: string; | ||
}; | ||
export interface Validate { | ||
(value: Json): boolean; | ||
errors?: ValidationError[]; | ||
} | ||
export declare type RawValidationError = ValidationError & { | ||
schemaPath: string[]; | ||
}; | ||
export declare type JsonSchema = Schema; |
@@ -1,2 +0,2 @@ | ||
import { FullValidationSchema, Schema, ShortValidationSchema, ValidationSchemaInput, ValidInputTypes } from './types.js'; | ||
import { FullValidationSchema, ShortValidationSchema, ValidationSchemaInput, ValidInputTypes } from './types.js'; | ||
export declare const parseBaseType: <T = string>(type: string) => { | ||
@@ -8,4 +8,4 @@ baseType?: T | undefined; | ||
}; | ||
export declare const abiSchemaToJsonSchema: (abis: ShortValidationSchema | FullValidationSchema, level?: string) => Schema; | ||
export declare const ethAbiToJsonSchema: (abis: ValidationSchemaInput) => Schema; | ||
export declare const abiSchemaToJsonSchema: (abis: ShortValidationSchema | FullValidationSchema, level?: string) => import("./types.js").Schema; | ||
export declare const ethAbiToJsonSchema: (abis: ValidationSchemaInput) => import("./types.js").Schema; | ||
export declare const fetchArrayElement: (data: Array<unknown>, level: number) => unknown; | ||
@@ -12,0 +12,0 @@ export declare const transformJsonDataToAbiFormat: (abis: FullValidationSchema, data: ReadonlyArray<unknown> | Record<string, unknown>, transformedData?: Array<unknown>) => Array<unknown>; |
@@ -34,8 +34,6 @@ "use strict"; | ||
} | ||
if (typeof value === 'number') { | ||
return value === 1 || value === 0; | ||
} | ||
return false; | ||
// type === number | ||
return value === 1 || value === 0; | ||
}; | ||
exports.isBoolean = isBoolean; | ||
//# sourceMappingURL=boolean.js.map |
import { Web3ValidationErrorObject } from 'web3-types'; | ||
import { Validate, Json, Schema } from './types.js'; | ||
import { Json, JsonSchema } from './types.js'; | ||
export declare class Validator { | ||
private static validatorInstance?; | ||
private constructor(); | ||
static factory(): Validator; | ||
private readonly _schemas; | ||
getSchema(key: string): Validate | undefined; | ||
addSchema(key: string, schema: Schema): void; | ||
private createValidator; | ||
validate(schema: Schema, data: Json, options?: { | ||
validate(schema: JsonSchema, data: Json, options?: { | ||
silent?: boolean; | ||
}): Web3ValidationErrorObject<string, Record<string, any>, unknown>[] | undefined; | ||
private convertErrors; | ||
getOrCreateValidator(schema: Schema): Validate; | ||
static getKey(schema: Schema): string; | ||
private getObjectValueByPath; | ||
private untilde; | ||
} |
@@ -7,12 +7,52 @@ "use strict"; | ||
exports.Validator = void 0; | ||
const utils_js_1 = require("ethereum-cryptography/utils.js"); | ||
const blake2b_js_1 = require("ethereum-cryptography/blake2b.js"); | ||
const is_my_json_valid_1 = __importDefault(require("is-my-json-valid")); | ||
const formats_js_1 = __importDefault(require("./formats.js")); | ||
const zod_1 = require("zod"); | ||
const errors_js_1 = require("./errors.js"); | ||
const formats_1 = __importDefault(require("./formats")); | ||
const convertToZod = (schema) => { | ||
if ((!(schema === null || schema === void 0 ? void 0 : schema.type) || (schema === null || schema === void 0 ? void 0 : schema.type) === 'object') && (schema === null || schema === void 0 ? void 0 : schema.properties)) { | ||
const obj = {}; | ||
for (const name of Object.keys(schema.properties)) { | ||
const zItem = convertToZod(schema.properties[name]); | ||
if (zItem) { | ||
obj[name] = zItem; | ||
} | ||
} | ||
if (Array.isArray(schema.required)) { | ||
return zod_1.z | ||
.object(obj) | ||
.partial() | ||
.required(schema.required.reduce((acc, v) => (Object.assign(Object.assign({}, acc), { [v]: true })), {})); | ||
} | ||
return zod_1.z.object(obj).partial(); | ||
} | ||
if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'array' && (schema === null || schema === void 0 ? void 0 : schema.items)) { | ||
if (Array.isArray(schema.items) && schema.items.length > 0) { | ||
const arr = []; | ||
for (const item of schema.items) { | ||
const zItem = convertToZod(item); | ||
if (zItem) { | ||
arr.push(zItem); | ||
} | ||
} | ||
return zod_1.z.tuple(arr); | ||
} | ||
return zod_1.z.array(convertToZod(schema.items)); | ||
} | ||
if (schema.oneOf && Array.isArray(schema.oneOf)) { | ||
return zod_1.z.union(schema.oneOf.map(oneOfSchema => convertToZod(oneOfSchema))); | ||
} | ||
if (schema === null || schema === void 0 ? void 0 : schema.format) { | ||
return zod_1.z.any().refine(formats_1.default[schema.format], (value) => ({ | ||
params: { value, format: schema.format }, | ||
})); | ||
} | ||
if ((schema === null || schema === void 0 ? void 0 : schema.type) && | ||
(schema === null || schema === void 0 ? void 0 : schema.type) !== 'object' && | ||
typeof zod_1.z[String(schema.type)] === 'function') { | ||
return zod_1.z[String(schema.type)](); | ||
} | ||
return zod_1.z.object({ data: zod_1.z.any() }).partial(); | ||
}; | ||
class Validator { | ||
// eslint-disable-next-line no-useless-constructor, @typescript-eslint/no-empty-function | ||
constructor() { | ||
this._schemas = new Map(); | ||
} | ||
static factory() { | ||
@@ -24,23 +64,8 @@ if (!Validator.validatorInstance) { | ||
} | ||
getSchema(key) { | ||
return this._schemas.get(key); | ||
} | ||
addSchema(key, schema) { | ||
this._schemas.set(key, this.createValidator(schema)); | ||
} | ||
// eslint-disable-next-line class-methods-use-this | ||
createValidator(schema) { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call | ||
// @ts-expect-error validator params correction | ||
return (0, is_my_json_valid_1.default)(schema, { | ||
formats: formats_js_1.default, | ||
greedy: true, | ||
verbose: true, | ||
additionalProperties: false, | ||
}); | ||
} | ||
validate(schema, data, options) { | ||
const localValidate = this.getOrCreateValidator(schema); | ||
if (!localValidate(data)) { | ||
const errors = this.convertErrors(localValidate.errors, schema, data); | ||
var _a, _b; | ||
const zod = convertToZod(schema); | ||
const result = zod.safeParse(data); | ||
if (!result.success) { | ||
const errors = this.convertErrors((_b = (_a = result.error) === null || _a === void 0 ? void 0 : _a.issues) !== null && _b !== void 0 ? _b : []); | ||
if (errors) { | ||
@@ -55,5 +80,7 @@ if (options === null || options === void 0 ? void 0 : options.silent) { | ||
} | ||
convertErrors(errors, schema, data) { | ||
// eslint-disable-next-line class-methods-use-this | ||
convertErrors(errors) { | ||
if (errors && Array.isArray(errors) && errors.length > 0) { | ||
return errors.map((error) => { | ||
var _a; | ||
let message; | ||
@@ -63,51 +90,35 @@ let keyword; | ||
let schemaPath; | ||
schemaPath = Array.isArray(error.schemaPath) | ||
? error.schemaPath.slice(1).join('/') | ||
: ''; | ||
const { field } = error; | ||
const _instancePath = schemaPath || | ||
// eslint-disable-next-line no-useless-escape | ||
((field === null || field === void 0 ? void 0 : field.length) >= 4 ? `${field.slice(4).replace(/\"|\[|\]/g, '')}` : '/'); | ||
const instancePath = _instancePath ? `/${_instancePath}` : ''; | ||
if ((error === null || error === void 0 ? void 0 : error.message) === 'has less items than allowed') { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const schemaData = this.getObjectValueByPath(schema, schemaPath); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
if (schemaData.minItems) { | ||
keyword = 'minItems'; | ||
schemaPath = `${schemaPath}/minItems`; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access | ||
params = { limit: schemaData.minItems }; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions | ||
message = `must NOT have fewer than ${schemaData.minItems} items`; | ||
} | ||
schemaPath = error.path.join('/'); | ||
const field = String(error.path[error.path.length - 1]); | ||
const instancePath = error.path.join('/'); | ||
if (error.code === zod_1.ZodIssueCode.too_big) { | ||
keyword = 'maxItems'; | ||
schemaPath = `${instancePath}/maxItems`; | ||
params = { limit: error.maximum }; | ||
message = `must NOT have more than ${error.maximum} items`; | ||
} | ||
else if ((error === null || error === void 0 ? void 0 : error.message) === 'has more items than allowed') { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const schemaData = this.getObjectValueByPath(schema, schemaPath); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
if (schemaData.maxItems) { | ||
keyword = 'maxItems'; | ||
schemaPath = `${schemaPath}/maxItems`; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access | ||
params = { limit: schemaData.maxItems }; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions | ||
message = `must NOT have more than ${schemaData.maxItems} items`; | ||
} | ||
else if (error.code === zod_1.ZodIssueCode.too_small) { | ||
keyword = 'minItems'; | ||
schemaPath = `${instancePath}/minItems`; | ||
params = { limit: error.minimum }; | ||
message = `must NOT have fewer than ${error.minimum} items`; | ||
} | ||
else if ((error === null || error === void 0 ? void 0 : error.message.startsWith('must be')) && | ||
(error === null || error === void 0 ? void 0 : error.message.endsWith('format'))) { | ||
const formatName = error === null || error === void 0 ? void 0 : error.message.split(' ')[2]; | ||
if (formatName) { | ||
message = `must pass "${formatName}" validation`; | ||
else if (error.code === zod_1.ZodIssueCode.custom) { | ||
const { value, format } = ((_a = error.params) !== null && _a !== void 0 ? _a : {}); | ||
if (typeof value === 'undefined') { | ||
message = `value at "/${schemaPath}" is required`; | ||
} | ||
else { | ||
message = `value "${ | ||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions | ||
typeof value === 'object' ? JSON.stringify(value) : value}" at "/${schemaPath}" must pass "${format}" validation`; | ||
} | ||
params = { value }; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const dataValue = this.getObjectValueByPath(data, instancePath); | ||
return { | ||
keyword: keyword !== null && keyword !== void 0 ? keyword : error.field, | ||
instancePath, | ||
schemaPath: `#${schemaPath}`, | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
params: params !== null && params !== void 0 ? params : { value: dataValue }, | ||
keyword: keyword !== null && keyword !== void 0 ? keyword : field, | ||
instancePath: instancePath ? `/${instancePath}` : '', | ||
schemaPath: schemaPath ? `#${schemaPath}` : '#', | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
params: params !== null && params !== void 0 ? params : { value: error.message }, | ||
message: message !== null && message !== void 0 ? message : error.message, | ||
@@ -119,65 +130,4 @@ }; | ||
} | ||
getOrCreateValidator(schema) { | ||
const key = Validator.getKey(schema); | ||
let _validator = this.getSchema(key); | ||
if (!_validator) { | ||
this.addSchema(key, schema); | ||
_validator = this.getSchema(key); | ||
} | ||
return _validator; | ||
} | ||
static getKey(schema) { | ||
return (0, utils_js_1.toHex)((0, blake2b_js_1.blake2b)((0, utils_js_1.utf8ToBytes)(JSON.stringify(schema)))); | ||
} | ||
getObjectValueByPath(obj, pointer, objpath) { | ||
try { | ||
if (typeof obj !== 'object') | ||
throw new Error('Invalid input object'); | ||
if (typeof pointer !== 'string') | ||
throw new Error('Invalid JSON pointer'); | ||
const parts = pointer.split('/'); | ||
if (!['', '#'].includes(parts.shift())) { | ||
throw new Error('Invalid JSON pointer'); | ||
} | ||
if (parts.length === 0) | ||
return obj; | ||
let curr = obj; | ||
for (const part of parts) { | ||
if (typeof part !== 'string') | ||
throw new Error('Invalid JSON pointer'); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument | ||
if (objpath) | ||
objpath.push(curr); // does not include target itself, but includes head | ||
const prop = this.untilde(part); | ||
if (typeof curr !== 'object') | ||
return undefined; | ||
if (!Object.prototype.hasOwnProperty.call(curr, prop)) | ||
return undefined; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access | ||
curr = curr[prop]; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return | ||
return curr; | ||
} | ||
catch (e) { | ||
return ''; | ||
} | ||
} | ||
// eslint-disable-next-line class-methods-use-this | ||
untilde(string) { | ||
if (!string.includes('~')) | ||
return string; | ||
return string.replace(/~[01]/g, match => { | ||
switch (match) { | ||
case '~1': | ||
return '/'; | ||
case '~0': | ||
return '~'; | ||
default: | ||
throw new Error('Unreachable'); | ||
} | ||
}); | ||
} | ||
} | ||
exports.Validator = Validator; | ||
//# sourceMappingURL=validator.js.map |
@@ -18,14 +18,3 @@ /* | ||
import { BaseWeb3Error, ERR_VALIDATION } from 'web3-errors'; | ||
import { isNullish } from './validation/object.js'; | ||
const errorFormatter = (error) => { | ||
if (error.message && error.instancePath && error.params && !isNullish(error.params.value)) { | ||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions | ||
return `value "${error.params.value}" at "${error.instancePath}" ${error.message}`; | ||
} | ||
if (error.message && error.instancePath) { | ||
return `value at "${error.instancePath}" ${error.message}`; | ||
} | ||
if (error.instancePath) { | ||
return `value at "${error.instancePath}" caused unspecified error`; | ||
} | ||
if (error.message) { | ||
@@ -44,6 +33,5 @@ return error.message; | ||
_compileErrors() { | ||
const errorMsgs = this.errors.map(errorFormatter); | ||
return errorMsgs; | ||
return this.errors.map(errorFormatter); | ||
} | ||
} | ||
//# sourceMappingURL=errors.js.map |
import { isAddress } from './validation/address.js'; | ||
import { isBlockNumber, isBlockNumberOrTag, isBlockTag, } from './validation/block.js'; | ||
import { isBlockNumber, isBlockNumberOrTag, isBlockTag } from './validation/block.js'; | ||
import { isBloom } from './validation/bloom.js'; | ||
@@ -34,3 +34,4 @@ import { isBoolean } from './validation/boolean.js'; | ||
} | ||
formats.bytes256 = formats.bytes; | ||
export default formats; | ||
//# sourceMappingURL=formats.js.map |
@@ -31,7 +31,5 @@ /* | ||
} | ||
if (typeof value === 'number') { | ||
return value === 1 || value === 0; | ||
} | ||
return false; | ||
// type === number | ||
return value === 1 || value === 0; | ||
}; | ||
//# sourceMappingURL=boolean.js.map |
@@ -1,11 +0,51 @@ | ||
import { toHex, utf8ToBytes } from 'ethereum-cryptography/utils.js'; | ||
import { blake2b } from 'ethereum-cryptography/blake2b.js'; | ||
import validator from 'is-my-json-valid'; | ||
import formats from './formats.js'; | ||
import { z, ZodIssueCode } from 'zod'; | ||
import { Web3ValidatorError } from './errors.js'; | ||
import formats from './formats'; | ||
const convertToZod = (schema) => { | ||
if ((!(schema === null || schema === void 0 ? void 0 : schema.type) || (schema === null || schema === void 0 ? void 0 : schema.type) === 'object') && (schema === null || schema === void 0 ? void 0 : schema.properties)) { | ||
const obj = {}; | ||
for (const name of Object.keys(schema.properties)) { | ||
const zItem = convertToZod(schema.properties[name]); | ||
if (zItem) { | ||
obj[name] = zItem; | ||
} | ||
} | ||
if (Array.isArray(schema.required)) { | ||
return z | ||
.object(obj) | ||
.partial() | ||
.required(schema.required.reduce((acc, v) => (Object.assign(Object.assign({}, acc), { [v]: true })), {})); | ||
} | ||
return z.object(obj).partial(); | ||
} | ||
if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'array' && (schema === null || schema === void 0 ? void 0 : schema.items)) { | ||
if (Array.isArray(schema.items) && schema.items.length > 0) { | ||
const arr = []; | ||
for (const item of schema.items) { | ||
const zItem = convertToZod(item); | ||
if (zItem) { | ||
arr.push(zItem); | ||
} | ||
} | ||
return z.tuple(arr); | ||
} | ||
return z.array(convertToZod(schema.items)); | ||
} | ||
if (schema.oneOf && Array.isArray(schema.oneOf)) { | ||
return z.union(schema.oneOf.map(oneOfSchema => convertToZod(oneOfSchema))); | ||
} | ||
if (schema === null || schema === void 0 ? void 0 : schema.format) { | ||
return z.any().refine(formats[schema.format], (value) => ({ | ||
params: { value, format: schema.format }, | ||
})); | ||
} | ||
if ((schema === null || schema === void 0 ? void 0 : schema.type) && | ||
(schema === null || schema === void 0 ? void 0 : schema.type) !== 'object' && | ||
typeof z[String(schema.type)] === 'function') { | ||
return z[String(schema.type)](); | ||
} | ||
return z.object({ data: z.any() }).partial(); | ||
}; | ||
export class Validator { | ||
// eslint-disable-next-line no-useless-constructor, @typescript-eslint/no-empty-function | ||
constructor() { | ||
this._schemas = new Map(); | ||
} | ||
static factory() { | ||
@@ -17,23 +57,8 @@ if (!Validator.validatorInstance) { | ||
} | ||
getSchema(key) { | ||
return this._schemas.get(key); | ||
} | ||
addSchema(key, schema) { | ||
this._schemas.set(key, this.createValidator(schema)); | ||
} | ||
// eslint-disable-next-line class-methods-use-this | ||
createValidator(schema) { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call | ||
// @ts-expect-error validator params correction | ||
return validator(schema, { | ||
formats, | ||
greedy: true, | ||
verbose: true, | ||
additionalProperties: false, | ||
}); | ||
} | ||
validate(schema, data, options) { | ||
const localValidate = this.getOrCreateValidator(schema); | ||
if (!localValidate(data)) { | ||
const errors = this.convertErrors(localValidate.errors, schema, data); | ||
var _a, _b; | ||
const zod = convertToZod(schema); | ||
const result = zod.safeParse(data); | ||
if (!result.success) { | ||
const errors = this.convertErrors((_b = (_a = result.error) === null || _a === void 0 ? void 0 : _a.issues) !== null && _b !== void 0 ? _b : []); | ||
if (errors) { | ||
@@ -48,5 +73,7 @@ if (options === null || options === void 0 ? void 0 : options.silent) { | ||
} | ||
convertErrors(errors, schema, data) { | ||
// eslint-disable-next-line class-methods-use-this | ||
convertErrors(errors) { | ||
if (errors && Array.isArray(errors) && errors.length > 0) { | ||
return errors.map((error) => { | ||
var _a; | ||
let message; | ||
@@ -56,51 +83,35 @@ let keyword; | ||
let schemaPath; | ||
schemaPath = Array.isArray(error.schemaPath) | ||
? error.schemaPath.slice(1).join('/') | ||
: ''; | ||
const { field } = error; | ||
const _instancePath = schemaPath || | ||
// eslint-disable-next-line no-useless-escape | ||
((field === null || field === void 0 ? void 0 : field.length) >= 4 ? `${field.slice(4).replace(/\"|\[|\]/g, '')}` : '/'); | ||
const instancePath = _instancePath ? `/${_instancePath}` : ''; | ||
if ((error === null || error === void 0 ? void 0 : error.message) === 'has less items than allowed') { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const schemaData = this.getObjectValueByPath(schema, schemaPath); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
if (schemaData.minItems) { | ||
keyword = 'minItems'; | ||
schemaPath = `${schemaPath}/minItems`; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access | ||
params = { limit: schemaData.minItems }; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions | ||
message = `must NOT have fewer than ${schemaData.minItems} items`; | ||
} | ||
schemaPath = error.path.join('/'); | ||
const field = String(error.path[error.path.length - 1]); | ||
const instancePath = error.path.join('/'); | ||
if (error.code === ZodIssueCode.too_big) { | ||
keyword = 'maxItems'; | ||
schemaPath = `${instancePath}/maxItems`; | ||
params = { limit: error.maximum }; | ||
message = `must NOT have more than ${error.maximum} items`; | ||
} | ||
else if ((error === null || error === void 0 ? void 0 : error.message) === 'has more items than allowed') { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const schemaData = this.getObjectValueByPath(schema, schemaPath); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
if (schemaData.maxItems) { | ||
keyword = 'maxItems'; | ||
schemaPath = `${schemaPath}/maxItems`; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access | ||
params = { limit: schemaData.maxItems }; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions | ||
message = `must NOT have more than ${schemaData.maxItems} items`; | ||
} | ||
else if (error.code === ZodIssueCode.too_small) { | ||
keyword = 'minItems'; | ||
schemaPath = `${instancePath}/minItems`; | ||
params = { limit: error.minimum }; | ||
message = `must NOT have fewer than ${error.minimum} items`; | ||
} | ||
else if ((error === null || error === void 0 ? void 0 : error.message.startsWith('must be')) && | ||
(error === null || error === void 0 ? void 0 : error.message.endsWith('format'))) { | ||
const formatName = error === null || error === void 0 ? void 0 : error.message.split(' ')[2]; | ||
if (formatName) { | ||
message = `must pass "${formatName}" validation`; | ||
else if (error.code === ZodIssueCode.custom) { | ||
const { value, format } = ((_a = error.params) !== null && _a !== void 0 ? _a : {}); | ||
if (typeof value === 'undefined') { | ||
message = `value at "/${schemaPath}" is required`; | ||
} | ||
else { | ||
message = `value "${ | ||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions | ||
typeof value === 'object' ? JSON.stringify(value) : value}" at "/${schemaPath}" must pass "${format}" validation`; | ||
} | ||
params = { value }; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const dataValue = this.getObjectValueByPath(data, instancePath); | ||
return { | ||
keyword: keyword !== null && keyword !== void 0 ? keyword : error.field, | ||
instancePath, | ||
schemaPath: `#${schemaPath}`, | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
params: params !== null && params !== void 0 ? params : { value: dataValue }, | ||
keyword: keyword !== null && keyword !== void 0 ? keyword : field, | ||
instancePath: instancePath ? `/${instancePath}` : '', | ||
schemaPath: schemaPath ? `#${schemaPath}` : '#', | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
params: params !== null && params !== void 0 ? params : { value: error.message }, | ||
message: message !== null && message !== void 0 ? message : error.message, | ||
@@ -112,64 +123,3 @@ }; | ||
} | ||
getOrCreateValidator(schema) { | ||
const key = Validator.getKey(schema); | ||
let _validator = this.getSchema(key); | ||
if (!_validator) { | ||
this.addSchema(key, schema); | ||
_validator = this.getSchema(key); | ||
} | ||
return _validator; | ||
} | ||
static getKey(schema) { | ||
return toHex(blake2b(utf8ToBytes(JSON.stringify(schema)))); | ||
} | ||
getObjectValueByPath(obj, pointer, objpath) { | ||
try { | ||
if (typeof obj !== 'object') | ||
throw new Error('Invalid input object'); | ||
if (typeof pointer !== 'string') | ||
throw new Error('Invalid JSON pointer'); | ||
const parts = pointer.split('/'); | ||
if (!['', '#'].includes(parts.shift())) { | ||
throw new Error('Invalid JSON pointer'); | ||
} | ||
if (parts.length === 0) | ||
return obj; | ||
let curr = obj; | ||
for (const part of parts) { | ||
if (typeof part !== 'string') | ||
throw new Error('Invalid JSON pointer'); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument | ||
if (objpath) | ||
objpath.push(curr); // does not include target itself, but includes head | ||
const prop = this.untilde(part); | ||
if (typeof curr !== 'object') | ||
return undefined; | ||
if (!Object.prototype.hasOwnProperty.call(curr, prop)) | ||
return undefined; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access | ||
curr = curr[prop]; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return | ||
return curr; | ||
} | ||
catch (e) { | ||
return ''; | ||
} | ||
} | ||
// eslint-disable-next-line class-methods-use-this | ||
untilde(string) { | ||
if (!string.includes('~')) | ||
return string; | ||
return string.replace(/~[01]/g, match => { | ||
switch (match) { | ||
case '~1': | ||
return '/'; | ||
case '~0': | ||
return '~'; | ||
default: | ||
throw new Error('Unreachable'); | ||
} | ||
}); | ||
} | ||
} | ||
//# sourceMappingURL=validator.js.map |
import { AbiParameter } from 'web3-types'; | ||
import { ValidationError } from 'is-my-json-valid'; | ||
import { ZodIssueBase } from 'zod'; | ||
export declare type ValidInputTypes = Uint8Array | bigint | string | number | boolean; | ||
@@ -8,3 +8,3 @@ export declare type EthBaseTypes = 'bool' | 'bytes' | 'string' | 'uint' | 'int' | 'address' | 'tuple'; | ||
export declare type FullValidationSchema = ReadonlyArray<AbiParameter>; | ||
export declare type ShortValidationSchema = ReadonlyArray<string | EthBaseTypes | EthExtendedTypes | EthBaseTypesWithMeta | EthBaseTypesWithMeta | ShortValidationSchema>; | ||
export declare type ShortValidationSchema = ReadonlyArray<string | EthBaseTypes | EthExtendedTypes | EthBaseTypesWithMeta | ShortValidationSchema>; | ||
export declare type ValidationSchemaInput = FullValidationSchema | ShortValidationSchema; | ||
@@ -17,2 +17,7 @@ export declare type Web3ValidationOptions = { | ||
}; | ||
export declare type ValidationError = ZodIssueBase; | ||
export interface Validate { | ||
(value: Json): boolean; | ||
errors?: ValidationError[]; | ||
} | ||
export declare type Schema = { | ||
@@ -102,10 +107,3 @@ $schema?: string; | ||
}; | ||
export interface Validate { | ||
(value: Json): boolean; | ||
errors?: ValidationError[]; | ||
} | ||
export declare type RawValidationError = ValidationError & { | ||
schemaPath: string[]; | ||
}; | ||
export declare type JsonSchema = Schema; | ||
//# sourceMappingURL=types.d.ts.map |
@@ -1,2 +0,2 @@ | ||
import { FullValidationSchema, Schema, ShortValidationSchema, ValidationSchemaInput, ValidInputTypes } from './types.js'; | ||
import { FullValidationSchema, ShortValidationSchema, ValidationSchemaInput, ValidInputTypes } from './types.js'; | ||
export declare const parseBaseType: <T = string>(type: string) => { | ||
@@ -8,4 +8,4 @@ baseType?: T | undefined; | ||
}; | ||
export declare const abiSchemaToJsonSchema: (abis: ShortValidationSchema | FullValidationSchema, level?: string) => Schema; | ||
export declare const ethAbiToJsonSchema: (abis: ValidationSchemaInput) => Schema; | ||
export declare const abiSchemaToJsonSchema: (abis: ShortValidationSchema | FullValidationSchema, level?: string) => import("./types.js").Schema; | ||
export declare const ethAbiToJsonSchema: (abis: ValidationSchemaInput) => import("./types.js").Schema; | ||
export declare const fetchArrayElement: (data: Array<unknown>, level: number) => unknown; | ||
@@ -12,0 +12,0 @@ export declare const transformJsonDataToAbiFormat: (abis: FullValidationSchema, data: ReadonlyArray<unknown> | Record<string, unknown>, transformedData?: Array<unknown>) => Array<unknown>; |
import { Web3ValidationErrorObject } from 'web3-types'; | ||
import { Validate, Json, Schema } from './types.js'; | ||
import { Json, JsonSchema } from './types.js'; | ||
export declare class Validator { | ||
private static validatorInstance?; | ||
private constructor(); | ||
static factory(): Validator; | ||
private readonly _schemas; | ||
getSchema(key: string): Validate | undefined; | ||
addSchema(key: string, schema: Schema): void; | ||
private createValidator; | ||
validate(schema: Schema, data: Json, options?: { | ||
validate(schema: JsonSchema, data: Json, options?: { | ||
silent?: boolean; | ||
}): Web3ValidationErrorObject<string, Record<string, any>, unknown>[] | undefined; | ||
private convertErrors; | ||
getOrCreateValidator(schema: Schema): Validate; | ||
static getKey(schema: Schema): string; | ||
private getObjectValueByPath; | ||
private untilde; | ||
} | ||
//# sourceMappingURL=validator.d.ts.map |
{ | ||
"name": "web3-validator", | ||
"version": "1.0.3-dev.ad377d1.0+ad377d1", | ||
"version": "1.0.3-dev.b93934a.0+b93934a", | ||
"description": "JSON-Schema compatible validator for web3", | ||
@@ -49,6 +49,6 @@ "main": "./lib/commonjs/index.js", | ||
"ethereum-cryptography": "^2.0.0", | ||
"is-my-json-valid": "^2.20.6", | ||
"util": "^0.12.5", | ||
"web3-errors": "1.0.3-dev.ad377d1.0+ad377d1", | ||
"web3-types": "1.0.3-dev.ad377d1.0+ad377d1" | ||
"web3-errors": "1.0.3-dev.b93934a.0+b93934a", | ||
"web3-types": "1.0.3-dev.b93934a.0+b93934a", | ||
"zod": "^3.21.4" | ||
}, | ||
@@ -69,3 +69,3 @@ "devDependencies": { | ||
}, | ||
"gitHead": "ad377d16a7e9a8e82857d6102bb4efd95c543e4f" | ||
"gitHead": "b93934a62277a85a616b55d45356ec5f0c5f71ea" | ||
} |
@@ -21,20 +21,3 @@ /* | ||
import { isNullish } from './validation/object.js'; | ||
const errorFormatter = (error: Web3ValidationErrorObject): string => { | ||
if (error.message && error.instancePath && error.params && !isNullish(error.params.value)) { | ||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions | ||
return `value "${(error.params as { value: unknown }).value}" at "${error.instancePath}" ${ | ||
error.message | ||
}`; | ||
} | ||
if (error.message && error.instancePath) { | ||
return `value at "${error.instancePath}" ${error.message}`; | ||
} | ||
if (error.instancePath) { | ||
return `value at "${error.instancePath}" caused unspecified error`; | ||
} | ||
if (error.message) { | ||
@@ -62,5 +45,4 @@ return error.message; | ||
private _compileErrors(): string[] { | ||
const errorMsgs = this.errors.map(errorFormatter); | ||
return errorMsgs; | ||
return this.errors.map(errorFormatter); | ||
} | ||
} |
@@ -20,4 +20,3 @@ /* | ||
import { isAddress } from './validation/address.js'; | ||
import { isBlockNumber,isBlockNumberOrTag, | ||
isBlockTag, } from './validation/block.js'; | ||
import { isBlockNumber, isBlockNumberOrTag, isBlockTag } from './validation/block.js'; | ||
import { isBloom } from './validation/bloom.js'; | ||
@@ -56,3 +55,4 @@ import { isBoolean } from './validation/boolean.js'; | ||
} | ||
formats.bytes256 = formats.bytes; | ||
export default formats; |
@@ -19,3 +19,3 @@ /* | ||
import { AbiParameter } from 'web3-types'; | ||
import { ValidationError } from 'is-my-json-valid'; | ||
import { ZodIssueBase } from 'zod'; | ||
@@ -48,8 +48,3 @@ export type ValidInputTypes = Uint8Array | bigint | string | number | boolean; | ||
export type ShortValidationSchema = ReadonlyArray< | ||
| string | ||
| EthBaseTypes | ||
| EthExtendedTypes | ||
| EthBaseTypesWithMeta | ||
| EthBaseTypesWithMeta | ||
| ShortValidationSchema | ||
string | EthBaseTypes | EthExtendedTypes | EthBaseTypesWithMeta | ShortValidationSchema | ||
>; | ||
@@ -62,5 +57,11 @@ export type ValidationSchemaInput = FullValidationSchema | ShortValidationSchema; | ||
// is-my-json-valid types | ||
export type Json = string | number | boolean | Array<Json> | { [id: string]: Json }; | ||
export type ValidationError = ZodIssueBase; | ||
export interface Validate { | ||
(value: Json): boolean; | ||
errors?: ValidationError[]; | ||
} | ||
export type Schema = { | ||
@@ -147,10 +148,3 @@ // version | ||
}; | ||
export interface Validate { | ||
(value: Json): boolean; | ||
errors?: ValidationError[]; | ||
} | ||
export type RawValidationError = ValidationError & { | ||
schemaPath: string[]; | ||
}; | ||
export type JsonSchema = Schema; |
@@ -23,3 +23,2 @@ /* | ||
JsonSchema, | ||
Schema, | ||
ShortValidationSchema, | ||
@@ -82,3 +81,3 @@ ValidationSchemaInput, | ||
type: string, | ||
parentSchema: Schema = {}, | ||
parentSchema: JsonSchema = {}, | ||
): { format?: string; required?: boolean } => { | ||
@@ -85,0 +84,0 @@ const typePropertyPresent = Object.keys(parentSchema).includes('type'); |
@@ -38,7 +38,4 @@ /* | ||
if (typeof value === 'number') { | ||
return value === 1 || value === 0; | ||
} | ||
return false; | ||
// type === number | ||
return value === 1 || value === 0; | ||
}; |
@@ -19,14 +19,77 @@ /* | ||
import { toHex, utf8ToBytes } from 'ethereum-cryptography/utils.js'; | ||
import { blake2b } from 'ethereum-cryptography/blake2b.js'; | ||
import validator from 'is-my-json-valid'; | ||
import formats from './formats.js'; | ||
import { z, ZodType, ZodIssue, ZodIssueCode, ZodTypeAny } from 'zod'; | ||
import { RawCreateParams } from 'zod/lib/types'; | ||
import { Web3ValidatorError } from './errors.js'; | ||
import { Validate, Json, Schema, RawValidationError } from './types.js'; | ||
import { Json, JsonSchema } from './types.js'; | ||
import formats from './formats'; | ||
const convertToZod = (schema: JsonSchema): ZodType => { | ||
if ((!schema?.type || schema?.type === 'object') && schema?.properties) { | ||
const obj: { [key: string]: ZodType } = {}; | ||
for (const name of Object.keys(schema.properties)) { | ||
const zItem = convertToZod(schema.properties[name]); | ||
if (zItem) { | ||
obj[name] = zItem; | ||
} | ||
} | ||
if (Array.isArray(schema.required)) { | ||
return z | ||
.object(obj) | ||
.partial() | ||
.required(schema.required.reduce((acc, v: string) => ({ ...acc, [v]: true }), {})); | ||
} | ||
return z.object(obj).partial(); | ||
} | ||
if (schema?.type === 'array' && schema?.items) { | ||
if (Array.isArray(schema.items) && schema.items.length > 0) { | ||
const arr: Partial<[ZodTypeAny, ...ZodTypeAny[]]> = []; | ||
for (const item of schema.items) { | ||
const zItem = convertToZod(item); | ||
if (zItem) { | ||
arr.push(zItem); | ||
} | ||
} | ||
return z.tuple(arr as [ZodTypeAny, ...ZodTypeAny[]]); | ||
} | ||
return z.array(convertToZod(schema.items as JsonSchema)); | ||
} | ||
if (schema.oneOf && Array.isArray(schema.oneOf)) { | ||
return z.union( | ||
schema.oneOf.map(oneOfSchema => convertToZod(oneOfSchema)) as [ | ||
ZodTypeAny, | ||
ZodTypeAny, | ||
...ZodTypeAny[], | ||
], | ||
); | ||
} | ||
if (schema?.format) { | ||
return z.any().refine(formats[schema.format], (value: unknown) => ({ | ||
params: { value, format: schema.format }, | ||
})); | ||
} | ||
if ( | ||
schema?.type && | ||
schema?.type !== 'object' && | ||
typeof (z as unknown as { [key: string]: (params?: RawCreateParams) => ZodType })[ | ||
String(schema.type) | ||
] === 'function' | ||
) { | ||
return (z as unknown as { [key: string]: (params?: RawCreateParams) => ZodType })[ | ||
String(schema.type) | ||
](); | ||
} | ||
return z.object({ data: z.any() }).partial(); | ||
}; | ||
export class Validator { | ||
// eslint-disable-next-line no-use-before-define | ||
private static validatorInstance?: Validator; | ||
// eslint-disable-next-line no-useless-constructor, @typescript-eslint/no-empty-function | ||
private constructor() {} | ||
public static factory(): Validator { | ||
@@ -38,31 +101,8 @@ if (!Validator.validatorInstance) { | ||
} | ||
private readonly _schemas: Map<string, Validate> = new Map(); | ||
public getSchema(key: string) { | ||
return this._schemas.get(key); | ||
} | ||
public addSchema(key: string, schema: Schema) { | ||
this._schemas.set(key, this.createValidator(schema)); | ||
} | ||
// eslint-disable-next-line class-methods-use-this | ||
private createValidator(schema: Schema): Validate { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call | ||
// @ts-expect-error validator params correction | ||
return validator(schema, { | ||
formats, | ||
greedy: true, | ||
verbose: true, | ||
additionalProperties: false, | ||
}) as Validate; | ||
} | ||
public validate(schema: Schema, data: Json, options?: { silent?: boolean }) { | ||
const localValidate = this.getOrCreateValidator(schema); | ||
if (!localValidate(data)) { | ||
const errors = this.convertErrors( | ||
localValidate.errors as RawValidationError[], | ||
schema, | ||
data, | ||
); | ||
public validate(schema: JsonSchema, data: Json, options?: { silent?: boolean }) { | ||
const zod = convertToZod(schema); | ||
const result = zod.safeParse(data); | ||
if (!result.success) { | ||
const errors = this.convertErrors(result.error?.issues ?? []); | ||
if (errors) { | ||
@@ -77,9 +117,6 @@ if (options?.silent) { | ||
} | ||
private convertErrors( | ||
errors: RawValidationError[] | undefined, | ||
schema: Schema, | ||
data: Json, | ||
): Web3ValidationErrorObject[] | undefined { | ||
// eslint-disable-next-line class-methods-use-this | ||
private convertErrors(errors: ZodIssue[] | undefined): Web3ValidationErrorObject[] | undefined { | ||
if (errors && Array.isArray(errors) && errors.length > 0) { | ||
return errors.map((error: RawValidationError) => { | ||
return errors.map((error: ZodIssue) => { | ||
let message; | ||
@@ -90,54 +127,40 @@ let keyword; | ||
schemaPath = Array.isArray(error.schemaPath) | ||
? error.schemaPath.slice(1).join('/') | ||
: ''; | ||
schemaPath = error.path.join('/'); | ||
const { field } = error; | ||
const _instancePath = | ||
schemaPath || | ||
// eslint-disable-next-line no-useless-escape | ||
(field?.length >= 4 ? `${field.slice(4).replace(/\"|\[|\]/g, '')}` : '/'); | ||
const field = String(error.path[error.path.length - 1]); | ||
const instancePath = error.path.join('/'); | ||
if (error.code === ZodIssueCode.too_big) { | ||
keyword = 'maxItems'; | ||
schemaPath = `${instancePath}/maxItems`; | ||
params = { limit: error.maximum }; | ||
message = `must NOT have more than ${error.maximum} items`; | ||
} else if (error.code === ZodIssueCode.too_small) { | ||
keyword = 'minItems'; | ||
schemaPath = `${instancePath}/minItems`; | ||
params = { limit: error.minimum }; | ||
message = `must NOT have fewer than ${error.minimum} items`; | ||
} else if (error.code === ZodIssueCode.custom) { | ||
const { value, format } = (error.params ?? {}) as { | ||
value: unknown; | ||
format: string; | ||
}; | ||
const instancePath = _instancePath ? `/${_instancePath}` : ''; | ||
if (error?.message === 'has less items than allowed') { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const schemaData = this.getObjectValueByPath(schema, schemaPath); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
if (schemaData.minItems) { | ||
keyword = 'minItems'; | ||
schemaPath = `${schemaPath}/minItems`; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access | ||
params = { limit: schemaData.minItems }; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions | ||
message = `must NOT have fewer than ${schemaData.minItems} items`; | ||
if (typeof value === 'undefined') { | ||
message = `value at "/${schemaPath}" is required`; | ||
} else { | ||
message = `value "${ | ||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions | ||
typeof value === 'object' ? JSON.stringify(value) : value | ||
}" at "/${schemaPath}" must pass "${format}" validation`; | ||
} | ||
} else if (error?.message === 'has more items than allowed') { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const schemaData = this.getObjectValueByPath(schema, schemaPath); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
if (schemaData.maxItems) { | ||
keyword = 'maxItems'; | ||
schemaPath = `${schemaPath}/maxItems`; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access | ||
params = { limit: schemaData.maxItems }; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions | ||
message = `must NOT have more than ${schemaData.maxItems} items`; | ||
} | ||
} else if ( | ||
error?.message.startsWith('must be') && | ||
error?.message.endsWith('format') | ||
) { | ||
const formatName = error?.message.split(' ')[2]; | ||
if (formatName) { | ||
message = `must pass "${formatName}" validation`; | ||
} | ||
params = { value }; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const dataValue = this.getObjectValueByPath(data as object, instancePath); | ||
return { | ||
keyword: keyword ?? error.field, | ||
instancePath, | ||
schemaPath: `#${schemaPath}`, | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
params: params ?? { value: dataValue }, | ||
keyword: keyword ?? field, | ||
instancePath: instancePath ? `/${instancePath}` : '', | ||
schemaPath: schemaPath ? `#${schemaPath}` : '#', | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
params: params ?? { value: error.message }, | ||
message: message ?? error.message, | ||
@@ -149,57 +172,2 @@ } as Web3ValidationErrorObject; | ||
} | ||
public getOrCreateValidator(schema: Schema): Validate { | ||
const key = Validator.getKey(schema); | ||
let _validator = this.getSchema(key); | ||
if (!_validator) { | ||
this.addSchema(key, schema); | ||
_validator = this.getSchema(key); | ||
} | ||
return _validator!; | ||
} | ||
public static getKey(schema: Schema) { | ||
return toHex(blake2b(utf8ToBytes(JSON.stringify(schema)))); | ||
} | ||
private getObjectValueByPath(obj: object, pointer: string, objpath?: object[]) { | ||
try { | ||
if (typeof obj !== 'object') throw new Error('Invalid input object'); | ||
if (typeof pointer !== 'string') throw new Error('Invalid JSON pointer'); | ||
const parts = pointer.split('/'); | ||
if (!['', '#'].includes(parts.shift() as string)) { | ||
throw new Error('Invalid JSON pointer'); | ||
} | ||
if (parts.length === 0) return obj; | ||
let curr: any = obj; | ||
for (const part of parts) { | ||
if (typeof part !== 'string') throw new Error('Invalid JSON pointer'); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument | ||
if (objpath) objpath.push(curr); // does not include target itself, but includes head | ||
const prop = this.untilde(part); | ||
if (typeof curr !== 'object') return undefined; | ||
if (!Object.prototype.hasOwnProperty.call(curr, prop)) return undefined; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access | ||
curr = curr[prop]; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return | ||
return curr; | ||
} catch (e) { | ||
return ''; | ||
} | ||
} | ||
// eslint-disable-next-line class-methods-use-this | ||
private untilde(string: string) { | ||
if (!string.includes('~')) return string; | ||
return string.replace(/~[01]/g, match => { | ||
switch (match) { | ||
case '~1': | ||
return '/'; | ||
case '~0': | ||
return '~'; | ||
default: | ||
throw new Error('Unreachable'); | ||
} | ||
}); | ||
} | ||
} |
@@ -26,7 +26,5 @@ /* | ||
private readonly _validator: Validator; | ||
public constructor() { | ||
this._validator = Validator.factory(); | ||
} | ||
public validateJSONSchema( | ||
@@ -39,3 +37,2 @@ schema: object, | ||
} | ||
public validate( | ||
@@ -42,0 +39,0 @@ schema: ValidationSchemaInput, |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
922621
5431
+ Addedzod@^3.21.4
+ Addedzod@3.23.8(transitive)
- Removedis-my-json-valid@^2.20.6
- Removedgenerate-function@2.3.1(transitive)
- Removedgenerate-object-property@1.2.0(transitive)
- Removedis-my-ip-valid@1.0.1(transitive)
- Removedis-my-json-valid@2.20.6(transitive)
- Removedis-property@1.0.2(transitive)
- Removedjsonpointer@5.0.1(transitive)
- Removedxtend@4.0.2(transitive)