Skip to content

Commit

Permalink
chore: cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
sagold committed Jun 5, 2024
1 parent 2986ac8 commit 07ad747
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 45 deletions.
3 changes: 1 addition & 2 deletions lib/draft2019/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { resolveAllOf } from "../features/allOf";
import { resolveAnyOf } from "../features/anyOf";
import { resolveOneOf } from "../features/oneOf";


const draft2019Config: DraftConfig = {
typeKeywords: {
array: [
Expand All @@ -45,7 +44,7 @@ const draft2019Config: DraftConfig = {
"additionalProperties",
"allOf",
"anyOf",
"dependencies",
// "dependencies",
"dependentSchemas",
"dependentRequired",
"enum",
Expand Down
91 changes: 57 additions & 34 deletions lib/draft2019/validation/keyword.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import { reduceSchema } from "../../reduceSchema";
import { validateDependentSchemas, validateDependentRequired } from "../../features/dependencies";
import { JsonValidator } from "../../validation/type";
import { SchemaNode } from "../../schemaNode";
import { omit } from "../../utils/omit";

/**
* Get a list of tests to search for a matching pattern to a property
*/
const getPatternTests = (patternProperties: unknown) => isObject(patternProperties) ?
Object.keys(patternProperties).map((pattern) => new RegExp(pattern))
: []
const getPatternTests = (patternProperties: unknown) =>
isObject(patternProperties)
? Object.keys(patternProperties).map((pattern) => new RegExp(pattern))
: [];

/** tests if a property is evaluated by the given schema */
function isPropertyEvaluated(schemaNode: SchemaNode, propertyName: string, value: unknown) {
Expand All @@ -29,7 +31,7 @@ function isPropertyEvaluated(schemaNode: SchemaNode, propertyName: string, value
}
// PATTERN-PROPERTIES
const patterns = getPatternTests(schema.patternProperties);
if (patterns.find(pattern => pattern.test(propertyName))) {
if (patterns.find((pattern) => pattern.test(propertyName))) {
return true;
}
// ADDITIONAL-PROPERTIES
Expand All @@ -41,6 +43,7 @@ function isPropertyEvaluated(schemaNode: SchemaNode, propertyName: string, value
}

const KeywordValidation: Record<string, JsonValidator> = {
// ...omit(Keywords, "dependencies"),
...Keywords,
dependencies: undefined,
dependentSchemas: validateDependentSchemas,
Expand Down Expand Up @@ -74,16 +77,19 @@ const KeywordValidation: Record<string, JsonValidator> = {

const testPatterns = getPatternTests(resolvedSchema.patternProperties);

unevaluated = unevaluated.filter(key => {
unevaluated = unevaluated.filter((key) => {
if (resolvedSchema.properties?.[key]) {
return false;
}
// special case: an evaluation in if statement counts too
// we have an unevaluated prop only if the if-schema does not match
if (isObject(schema.if) && isPropertyEvaluated(node.next({ type: "object", ...schema.if }), key, value[key])) {
if (
isObject(schema.if) &&
isPropertyEvaluated(node.next({ type: "object", ...schema.if }), key, value[key])
) {
return false;
}
if (testPatterns.find(pattern => pattern.test(key))) {
if (testPatterns.find((pattern) => pattern.test(key))) {
return false;
}
// @todo is this evaluated by additionaProperties per property
Expand All @@ -99,20 +105,25 @@ const KeywordValidation: Record<string, JsonValidator> = {

const errors: JsonError[] = [];
if (resolvedSchema.unevaluatedProperties === false) {
unevaluated.forEach(key => {
errors.push(draft.errors.unevaluatedPropertyError({
pointer: `${pointer}/${key}`,
value: JSON.stringify(value[key]),
schema
}))
unevaluated.forEach((key) => {
errors.push(
draft.errors.unevaluatedPropertyError({
pointer: `${pointer}/${key}`,
value: JSON.stringify(value[key]),
schema
})
);
});
return errors;
}

unevaluated.forEach(key => {
unevaluated.forEach((key) => {
if (isObject(resolvedSchema.unevaluatedProperties)) {
// note: only key changes
const keyErrors = draft.validate(node.next(resolvedSchema.unevaluatedProperties, key), value[key]);
const keyErrors = draft.validate(
node.next(resolvedSchema.unevaluatedProperties, key),
value[key]
);
errors.push(...keyErrors);
}
});
Expand All @@ -127,7 +138,12 @@ const KeywordValidation: Record<string, JsonValidator> = {
unevaluatedItems: (node, value: unknown[]) => {
const { draft, schema, pointer } = node;
// if not in items, and not matches additionalItems
if (!Array.isArray(value) || value.length === 0 || schema.unevaluatedItems == null || schema.unevaluatedItems === true) {
if (
!Array.isArray(value) ||
value.length === 0 ||
schema.unevaluatedItems == null ||
schema.unevaluatedItems === true
) {
return undefined;
}

Expand All @@ -143,9 +159,11 @@ const KeywordValidation: Record<string, JsonValidator> = {
if (isObject(schema.if)) {
const nextSchemaNode: JsonSchema = { type: "array", ...schema.if };
if (draft.isValid(value, nextSchemaNode)) {

if (Array.isArray(nextSchemaNode.items) && nextSchemaNode.items.length === value.length) {
return undefined
if (
Array.isArray(nextSchemaNode.items) &&
nextSchemaNode.items.length === value.length
) {
return undefined;
}
}
// need to test remaining items?
Expand All @@ -154,30 +172,33 @@ const KeywordValidation: Record<string, JsonValidator> = {
if (isObject(resolvedSchema.items)) {
const nextSchemaNode = { ...resolvedSchema, unevaluatedItems: undefined } as JsonSchema;
const errors = draft.validate(node.next(nextSchemaNode), value);
return errors.map(e => draft.errors.unevaluatedItemsError({ ...e.data }));
return errors.map((e) => draft.errors.unevaluatedItemsError({ ...e.data }));
}

if (Array.isArray(resolvedSchema.items)) {
const items: { index: number, value: unknown }[] = [];
const items: { index: number; value: unknown }[] = [];
for (let i = resolvedSchema.items.length; i < value.length; i += 1) {
if (i < resolvedSchema.items.length) {
if (draft.validate(node.next(resolvedSchema.items[i], i), value[i]).length > 0) {
if (
draft.validate(node.next(resolvedSchema.items[i], i), value[i]).length > 0
) {
items.push({ index: i, value: value[i] });
}
} else {
items.push({ index: i, value: value[i] });
}
}
return items.map(item => draft.errors.unevaluatedItemsError({
pointer: `${pointer}/${item.index}`,
value: JSON.stringify(item.value),
schema: resolvedSchema.unevaluatedItems
}))
return items.map((item) =>
draft.errors.unevaluatedItemsError({
pointer: `${pointer}/${item.index}`,
value: JSON.stringify(item.value),
schema: resolvedSchema.unevaluatedItems
})
);
}

if (isObject(resolvedSchema.unevaluatedItems)) {
return value.map((item, index) => {

if (!draft.isValid(item, resolvedSchema.unevaluatedItems)) {
return draft.errors.unevaluatedItemsError({
pointer: `${pointer}/${index}`,
Expand All @@ -190,12 +211,14 @@ const KeywordValidation: Record<string, JsonValidator> = {

const errors: JsonError[] = [];
value.forEach((item, index) => {
errors.push(draft.errors.unevaluatedItemsError({
pointer: `${pointer}/${index}`,
value: JSON.stringify(item),
schema
}))
})
errors.push(
draft.errors.unevaluatedItemsError({
pointer: `${pointer}/${index}`,
value: JSON.stringify(item),
schema
})
);
});

return errors;
}
Expand Down
14 changes: 5 additions & 9 deletions lib/validation/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@ import { SchemaNode } from "../schemaNode";
import { JsonError } from "../types";

export interface JsonTypeValidator {
(node: SchemaNode, value: unknown): Array<
void | undefined | JsonError | JsonError[] | JsonError[][]
>;
(
node: SchemaNode,
value: unknown
): Array<void | undefined | JsonError | JsonError[] | JsonError[][]>;
}

export interface JsonValidator {
(node: SchemaNode, value: unknown):
| void
| undefined
| JsonError
| JsonError[]
| JsonError[][];
(node: SchemaNode, value: unknown): void | undefined | JsonError | JsonError[] | JsonError[][];
}

/**
Expand Down

0 comments on commit 07ad747

Please sign in to comment.