@hyperjump/json-schema
Advanced tools
Comparing version 1.5.1 to 1.5.2
@@ -93,5 +93,11 @@ import curry from "just-curry-it"; | ||
// itemPattern is experimental, but is necessary for meta-validation | ||
const itemPatternKeywordId = "https://json-schema.org/keyword/itemPattern"; | ||
const isItemPatternEnabled = isExperimentalKeywordEnabled(itemPatternKeywordId); | ||
setExperimentalKeywordEnabled(itemPatternKeywordId, true); | ||
const compiledSchema = await compile(schema.dialectId); | ||
metaValidators[schema.dialectId] = interpret(compiledSchema); | ||
setExperimentalKeywordEnabled(itemPatternKeywordId, isItemPatternEnabled); | ||
setExperimentalKeywordEnabled(dyanmicRefKeywordId, isDynamicRefEnabled); | ||
@@ -98,0 +104,0 @@ } |
@@ -8,2 +8,3 @@ import { addKeyword } from "./keywords.js"; | ||
import anyOf from "./keywords/anyOf.js"; | ||
import conditional from "./keywords/conditional.js"; | ||
import const_ from "./keywords/const.js"; | ||
@@ -31,2 +32,3 @@ import contains from "./keywords/contains.js"; | ||
import if_ from "./keywords/if.js"; | ||
import itemPattern from "./keywords/itemPattern.js"; | ||
import items from "./keywords/items.js"; | ||
@@ -79,2 +81,3 @@ import maxContains from "./keywords/maxContains.js"; | ||
addKeyword(anyOf); | ||
addKeyword(conditional); | ||
addKeyword(const_); | ||
@@ -126,2 +129,3 @@ addKeyword(contains); | ||
addKeyword(required); | ||
addKeyword(itemPattern); | ||
addKeyword(title); | ||
@@ -128,0 +132,0 @@ addKeyword(then); |
@@ -1,2 +0,2 @@ | ||
import { filter, every, pipe } from "@hyperjump/pact"; | ||
import { concat, join, empty, map, filter, every, pipe, tap } from "@hyperjump/pact"; | ||
import * as Schema from "../schema.js"; | ||
@@ -11,22 +11,20 @@ import * as Instance from "../instance.js"; | ||
const compile = async (schema, ast, parentSchema) => { | ||
const patterns = []; | ||
const propertiesKeyword = getKeywordName(schema.dialectId, "https://json-schema.org/keyword/properties"); | ||
const propertiesSchema = await Schema.step(propertiesKeyword, parentSchema); | ||
if (Schema.typeOf(propertiesSchema, "object")) { | ||
for (const name of Schema.keys(propertiesSchema)) { | ||
patterns.push(regexEscape(name)); | ||
} | ||
} | ||
const propertyPatterns = Schema.typeOf(propertiesSchema, "object") | ||
? map((propertyName) => "^" + regexEscape(propertyName) + "$", Schema.keys(propertiesSchema)) | ||
: empty(); | ||
const patternPropertiesKeyword = getKeywordName(schema.dialectId, "https://json-schema.org/keyword/patternProperties"); | ||
const patternProperties = await Schema.step(patternPropertiesKeyword, parentSchema); | ||
if (Schema.typeOf(patternProperties, "object")) { | ||
patterns.push(...Schema.keys(patternProperties)); | ||
} | ||
const patternPropertyPatterns = Schema.typeOf(patternProperties, "object") | ||
? Schema.keys(patternProperties) | ||
: empty(); | ||
return [ | ||
new RegExp(patterns.length > 0 ? patterns.join("|") : "(?!)", "u"), | ||
await Validation.compile(schema, ast) | ||
]; | ||
const pattern = pipe( | ||
concat(propertyPatterns, patternPropertyPatterns), | ||
join("|") | ||
) || "(?!)"; | ||
return [new RegExp(pattern, "u"), await Validation.compile(schema, ast)]; | ||
}; | ||
@@ -33,0 +31,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { pipe, map, filter, reduce, collectSet, zip, range } from "@hyperjump/pact"; | ||
import { pipe, map, filter, count, collectSet, zip, range } from "@hyperjump/pact"; | ||
import * as Schema from "../schema.js"; | ||
@@ -37,3 +37,3 @@ import * as Instance from "../instance.js"; | ||
filter((item) => Validation.interpret(contains, item, ast, dynamicAnchors, quiet)), | ||
reduce((matches) => matches + 1, 0) | ||
count | ||
); | ||
@@ -40,0 +40,0 @@ return matches >= minContains && matches <= maxContains; |
@@ -15,6 +15,4 @@ import { pipe, asyncMap, asyncCollectArray } from "@hyperjump/pact"; | ||
const interpret = (dependentRequired, instance) => { | ||
const value = Instance.value(instance); | ||
return !Instance.typeOf(instance, "object") || dependentRequired.every(([propertyName, required]) => { | ||
return !(propertyName in value) || required.every((key) => key in value); | ||
return !Instance.has(propertyName, instance) || required.every((key) => Instance.has(key, instance)); | ||
}); | ||
@@ -21,0 +19,0 @@ }; |
@@ -16,6 +16,4 @@ import { pipe, asyncMap, asyncCollectArray } from "@hyperjump/pact"; | ||
const interpret = (dependentSchemas, instance, ast, dynamicAnchors, quiet) => { | ||
const value = Instance.value(instance); | ||
return !Instance.typeOf(instance, "object") || dependentSchemas.every(([propertyName, dependentSchema]) => { | ||
return !(propertyName in value) || Validation.interpret(dependentSchema, instance, ast, dynamicAnchors, quiet); | ||
return !Instance.has(propertyName, instance) || Validation.interpret(dependentSchema, instance, ast, dynamicAnchors, quiet); | ||
}); | ||
@@ -25,3 +23,2 @@ }; | ||
const collectEvaluatedProperties = (dependentSchemas, instance, ast, dynamicAnchors) => { | ||
const value = Instance.value(instance); | ||
if (!Instance.typeOf(instance, "object")) { | ||
@@ -33,3 +30,3 @@ return false; | ||
for (const [propertyName, dependentSchema] of dependentSchemas) { | ||
if (propertyName in value) { | ||
if (Instance.has(propertyName, instance)) { | ||
const propertyNames = Validation.collectEvaluatedProperties(dependentSchema, instance, ast, dynamicAnchors); | ||
@@ -36,0 +33,0 @@ if (propertyNames === false) { |
@@ -16,7 +16,3 @@ import { pipe, asyncMap, asyncCollectArray, every, zip, take } from "@hyperjump/pact"; | ||
const interpret = (prefixItems, instance, ast, dynamicAnchors, quiet) => { | ||
if (!Instance.typeOf(instance, "array")) { | ||
return true; | ||
} | ||
return pipe( | ||
return !Instance.typeOf(instance, "array") || pipe( | ||
zip(prefixItems, Instance.iter(instance)), | ||
@@ -23,0 +19,0 @@ take(Instance.length(instance)), |
@@ -207,3 +207,3 @@ import { nil as nilPointer, append as pointerAppend, get as pointerGet } from "@hyperjump/json-pointer"; | ||
export const uri = (doc) => doc.id ? `${doc.id}#${encodeURI(doc.pointer)}` : undefined; | ||
export const value = (doc) => Reference.isReference(doc.value) ? Reference.value(doc.value) : doc.value; | ||
export const value = (doc) => doc.value; | ||
export const has = (key, doc) => key in value(doc); | ||
@@ -210,0 +210,0 @@ export const typeOf = (doc, type) => jsonTypeOf(value(doc), type); |
{ | ||
"name": "@hyperjump/json-schema", | ||
"version": "1.5.1", | ||
"version": "1.5.2", | ||
"description": "A JSON Schema validator with support for custom keywords, vocabularies, and dialects", | ||
@@ -67,3 +67,3 @@ "type": "module", | ||
"@hyperjump/json-pointer": "^1.0.0", | ||
"@hyperjump/pact": "^1.0.0", | ||
"@hyperjump/pact": "^1.2.0", | ||
"@hyperjump/uri": "^1.2.0", | ||
@@ -70,0 +70,0 @@ "content-type": "^1.0.4", |
@@ -21,3 +21,5 @@ # Hyperjump - JSON Schema | ||
## Install | ||
Includes support for node.js (ES Modules, TypeScript) and browsers. | ||
Includes support for node.js (ES Modules, TypeScript) and browsers (works with | ||
CSP | ||
[`unsafe-eval`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#unsafe_eval_expressions)). | ||
@@ -24,0 +26,0 @@ ### Node.js |
@@ -37,3 +37,5 @@ import { defineVocabulary, loadDialect } from "../lib/keywords.js"; | ||
"else": "https://json-schema.org/keyword/else", | ||
"conditional": "https://json-schema.org/keyword/conditional", | ||
"items": "https://json-schema.org/keyword/items", | ||
"itemPattern": "https://json-schema.org/keyword/itemPattern", | ||
"not": "https://json-schema.org/keyword/not", | ||
@@ -40,0 +42,0 @@ "oneOf": "https://json-schema.org/keyword/oneOf", |
@@ -11,2 +11,3 @@ export default { | ||
"contains": { "$dynamicRef": "meta" }, | ||
"itemPattern": { "$ref": "#/$defs/itemPattern" }, | ||
"additionalProperties": { "$dynamicRef": "meta" }, | ||
@@ -37,2 +38,12 @@ "properties": { | ||
"else": { "$dynamicRef": "meta" }, | ||
"conditional": { | ||
"type": "array", | ||
"items": { | ||
"if": { "type": "array" }, | ||
"then": { | ||
"items": { "$dynamicRef": "meta" } | ||
}, | ||
"else": { "$dynamicRef": "meta" } | ||
} | ||
}, | ||
"allOf": { "$ref": "#/$defs/schemaArray" }, | ||
@@ -49,4 +60,19 @@ "anyOf": { "$ref": "#/$defs/schemaArray" }, | ||
"items": { "$dynamicRef": "meta" } | ||
}, | ||
"itemPattern": { | ||
"type": "array", | ||
"itemPattern": [ | ||
[ | ||
{ | ||
"if": { "type": "array" }, | ||
"then": { "$ref": "#/$defs/itemPattern" }, | ||
"else": { "$dynamicRef": "meta" } | ||
}, | ||
{ "enum": ["?", "*", "+"] }, "?", | ||
"|", | ||
{ "const": "|" } | ||
], "*" | ||
] | ||
} | ||
} | ||
}; |
355103
180
10406
784
Updated@hyperjump/pact@^1.2.0