diff --git a/src/index.ts b/src/index.ts index 52765c4..1cdbf71 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,6 +35,10 @@ export { type ExternalRefResolver, fetchExternalRef, } from "./lib/refUtils.ts"; +export { + createSchemaFromJson, + inferSchema, +} from "./lib/schema-inference.ts"; export type { SchemaBuilderComponents, SchemaBuilderRegistry, @@ -49,6 +53,11 @@ export { useSlotProps, } from "./registry/index.ts"; export type { JsonSchema } from "./types/jsonSchema.ts"; +export { + type ValidationError, + type ValidationResult, + validateJson, +} from "./utils/jsonValidator.ts"; export { InferSchemaDialog, type InferSchemaDialogProps, diff --git a/src/lib/schema-inference.ts b/src/lib/schema-inference.ts index da7e408..0fcd04c 100644 --- a/src/lib/schema-inference.ts +++ b/src/lib/schema-inference.ts @@ -320,8 +320,16 @@ function inferNumberSchema(num: number): JsonSchema { // --- Main Inference Function --- /** - * Infers a JSON Schema from a JSON object - * Based on json-schema-generator approach + * Infers a JSON Schema fragment describing a single parsed JSON value. + * + * Recurses through objects and arrays, detecting primitive types, string + * formats (date, date-time, email, uuid, uri), enums and a few semantic + * formats across array items. The result is a bare schema fragment, not a + * full document — use {@link createSchemaFromJson} for a self-contained schema. + * + * @param obj - An already-parsed JSON value (object, array, or primitive). + * @returns The inferred JSON Schema fragment for that value. + * @public */ export function inferSchema(obj: unknown): JsonSchema { if (obj === null) return { type: "null" }; @@ -346,7 +354,16 @@ export function inferSchema(obj: unknown): JsonSchema { } /** - * Creates a full JSON Schema document from a JSON object + * Builds a complete, self-contained JSON Schema document from an example value. + * + * Wraps {@link inferSchema} and adds document-level fields (`$schema`, `title`, + * `description`). The root is always normalized to an `object` schema: object + * and array inputs are described directly, while a primitive root is wrapped + * under a `value` property. + * + * @param jsonObject - An already-parsed JSON value to derive the schema from. + * @returns A draft-07 JSON Schema document describing the input. + * @public */ export function createSchemaFromJson(jsonObject: unknown): JsonSchema { const inferredSchema = inferSchema(jsonObject); diff --git a/src/utils/jsonValidator.ts b/src/utils/jsonValidator.ts index 2bbbddb..278a9c5 100644 --- a/src/utils/jsonValidator.ts +++ b/src/utils/jsonValidator.ts @@ -16,15 +16,35 @@ const ajv = new Ajv({ }); addFormats(ajv); +/** + * A single validation problem found in the input. + * @public + */ export interface ValidationError { + /** + * JSON Pointer (RFC 6901) to the offending value, e.g. `/user/age`. + * `"/"` denotes the document root (used for syntax errors and empty input). + */ path: string; + /** Human-readable description of the problem (from ajv, or a parse error). */ message: string; + /** 1-based line number of the error in the source text, when locatable. */ line?: number; + /** 1-based column number of the error in the source text, when locatable. */ column?: number; } +/** + * Outcome of validating a JSON document against a schema. + * @public + */ export interface ValidationResult { + /** `true` when the input parses and satisfies the schema. */ valid: boolean; + /** + * The problems found. Empty (or omitted) when {@link ValidationResult.valid} + * is `true`; otherwise contains one entry per violation. + */ errors?: ValidationError[]; } @@ -226,7 +246,18 @@ function caughtErrorResult( } /** - * Validates a JSON string against a schema and returns validation results + * Validates a JSON document against a JSON Schema. + * + * Never throws: malformed JSON, empty input, and schema violations are all + * reported through the returned {@link ValidationResult}. Schema-level errors + * carry a JSON Pointer `path`; syntax/parse errors are reported at the root + * (`"/"`) with `line`/`column` pointing at the offending position when known. + * + * @param jsonInput - The JSON document to validate, as a raw string. + * @param schema - The JSON Schema to validate against. + * @returns A {@link ValidationResult}; `valid` is `true` only when the input + * parses and satisfies the schema, otherwise `errors` lists each problem. + * @public */ export function validateJson( jsonInput: string,