|
1 | | -import { compile, getKeyword, getSchema } from "@hyperjump/json-schema/experimental"; |
| 1 | +import { compile, getKeyword, getSchema, Validation } from "@hyperjump/json-schema/experimental"; |
2 | 2 | import * as Instance from "@hyperjump/json-schema/instance/experimental"; |
3 | 3 | import * as Schema from "@hyperjump/browser"; |
4 | 4 | import { pointerSegments } from "@hyperjump/json-pointer"; |
5 | 5 | import { toAbsoluteIri } from "@hyperjump/uri"; |
6 | 6 | import { Localization } from "./localization.js"; |
| 7 | +import { JsonSchemaErrorsOutputPlugin } from "./output-plugin.js"; |
7 | 8 |
|
8 | 9 | /** |
9 | 10 | * @import * as API from "./index.d.ts" |
10 | 11 | * @import { Browser } from "@hyperjump/browser"; |
11 | | - * @import { SchemaDocument } from "@hyperjump/json-schema/experimental"; |
| 12 | + * @import { SchemaDocument, CompiledSchema } from "@hyperjump/json-schema/experimental"; |
12 | 13 | * @import { JsonNode } from "@hyperjump/json-schema/instance/experimental" |
13 | 14 | */ |
14 | 15 |
|
@@ -194,3 +195,53 @@ export const getErrors = async (normalizedErrors, rootInstance, localization) => |
194 | 195 |
|
195 | 196 | return errors; |
196 | 197 | }; |
| 198 | + |
| 199 | +/** |
| 200 | + * @overload |
| 201 | + * @param {string} schemaUri |
| 202 | + * @returns {Promise<API.EvaluateInstance>} |
| 203 | + * |
| 204 | + * @overload |
| 205 | + * @param {string} schemaUri |
| 206 | + * @param {API.Json} instance |
| 207 | + * @param {API.JsonSchemaErrorsOptions} [options] |
| 208 | + * @returns {Promise<API.ValidationResult>} |
| 209 | + * |
| 210 | + * @param {string} schemaUri |
| 211 | + * @param {API.Json} instance |
| 212 | + * @param {API.JsonSchemaErrorsOptions} [options] |
| 213 | + */ |
| 214 | +export const validate = async (schemaUri, instance, options) => { |
| 215 | + const schema = await getSchema(schemaUri); |
| 216 | + const compiledSchema = await compile(schema); |
| 217 | + |
| 218 | + if (instance === undefined) { |
| 219 | + /** @type API.EvaluateInstance */ |
| 220 | + return (instance, options) => { |
| 221 | + return evaluateCompiledSchema(compiledSchema, instance, options); |
| 222 | + }; |
| 223 | + } else { |
| 224 | + return evaluateCompiledSchema(compiledSchema, instance, options); |
| 225 | + } |
| 226 | +}; |
| 227 | + |
| 228 | +/** @type (compiledSchema: CompiledSchema, instance: API.Json, options?: API.ValidationOptions) => Promise<API.ValidationResult> */ |
| 229 | +const evaluateCompiledSchema = async (compiledSchema, instance, options = {}) => { |
| 230 | + const localization = await Localization.forLocale(options.locale ?? "en-US"); |
| 231 | + const jsonNode = Instance.fromJs(instance); |
| 232 | + const outputPlugin = new JsonSchemaErrorsOutputPlugin(); |
| 233 | + const context = { |
| 234 | + ast: compiledSchema.ast, |
| 235 | + plugins: [...compiledSchema.ast.plugins, outputPlugin, ...options.plugins ?? []] |
| 236 | + }; |
| 237 | + const valid = Validation.interpret(compiledSchema.schemaUri, jsonNode, context); |
| 238 | + |
| 239 | + if (valid) { |
| 240 | + return { valid }; |
| 241 | + } else { |
| 242 | + return { |
| 243 | + valid, |
| 244 | + errors: await getErrors(outputPlugin.output, jsonNode, localization) |
| 245 | + }; |
| 246 | + } |
| 247 | +}; |
0 commit comments