/** * A plain object representing a single JSON Schema node. * * **When to use** * * Use to represent an arbitrary JSON Schema object regardless of dialect. * * **Details** * * This is an open record type (`[x: string]: unknown`) so it can hold any JSON * Schema keyword. Most functions in this module accept or return this type. * * @stability stable * @category models * @since 4.0.0 */ export interface JsonSchema { [x: string]: unknown; } /** * The set of JSON Schema dialects supported by this module. * * **When to use** * * Use as the dialect marker for `JsonSchema` documents when parsing, * converting, or emitting schemas across the supported formats. * * **Details** * * Supported values are `"draft-04"` for JSON Schema Draft-04, `"draft-07"` * for JSON Schema Draft-07, `"draft-2020-12"` for JSON Schema Draft 2020-12 * and the canonical internal form, `"openapi-3.1"` for OpenAPI 3.1, and * `"openapi-3.0"` for OpenAPI 3.0. * * @see {@link Document} for a single root schema tagged with a dialect * @see {@link MultiDocument} for multiple root schemas tagged with a dialect * * @stability stable * @category models * @since 4.0.0 */ export type Dialect = "draft-04" | "draft-07" | "draft-2020-12" | "openapi-3.1" | "openapi-3.0"; /** * The JSON Schema primitive type names. * * **When to use** * * Use to restrict a JSON Schema `type` keyword to the supported primitive names. * * @stability stable * @category models * @since 4.0.0 */ export type Type = "string" | "number" | "boolean" | "array" | "object" | "null" | "integer"; /** * A record of named JSON Schema definitions, keyed by definition name. * * **When to use** * * Use as the shared lookup table for named JSON Schema nodes that are * referenced from JSON Schema documents. * * **Details** * * The map is dialect-neutral. Conversion APIs emit it as `$defs`, * `definitions`, or `components.schemas` depending on the target format. * * @see {@link Document} for a single root schema with definitions * @see {@link MultiDocument} for multiple root schemas sharing definitions * @stability stable * @category models * @since 4.0.0 */ export interface Definitions extends Record { } /** * A structured container for a single JSON Schema and its associated * definitions. * * **When to use** * * Use when you need to carry a root schema together with its shared * definitions, or when converting between dialects with the `from*` and `to*` * functions. * * **Details** * * The `schema` field holds the root schema *without* the definitions * collection. Root definitions are stored separately in `definitions` and * referenced via `#/$defs/` for Draft-2020-12, `#/definitions/` * for Draft-04 and Draft-07, and `#/components/schemas/` for OpenAPI 3.1 * and OpenAPI 3.0. * * **Example** (Inspecting a parsed document) * * ```ts import.meta.vitest * import { JsonSchema } from "effect" * * const raw: JsonSchema.JsonSchema = { * type: "string", * $defs: { Trimmed: { type: "string", minLength: 1 } } * } * * const doc = JsonSchema.fromSchemaDraft2020_12(raw) * * doc.dialect // => "draft-2020-12" * doc.schema // => { type: "string" } * doc.definitions // => { Trimmed: { type: "string", minLength: 1 } } * ``` * * @see {@link MultiDocument} * @see {@link fromSchemaDraft2020_12} * @stability stable * @category models * @since 4.0.0 */ export interface Document { readonly dialect: D; readonly schema: JsonSchema; readonly definitions: Definitions; } /** * Like {@link Document}, but carries multiple root schemas that share a * single definitions pool. * * **When to use** * * Use when generating several schemas, such as a request body * and a response body, that reference the same set of definitions. * * **Details** * * The `schemas` tuple is non-empty and contains at least one element. * * @see {@link Document} * @see {@link toMultiDocumentOpenApi3_1} * @stability stable * @category models * @since 4.0.0 */ export interface MultiDocument { readonly dialect: D; readonly schemas: readonly [JsonSchema, ...Array]; readonly definitions: Definitions; } /** * Represents the `$schema` meta-schema URI for JSON Schema Draft-04. * * **When to use** * * Use when constructing a Draft-04 JSON Schema document and you need a stable * value for the root `$schema` field. * * @see {@link META_SCHEMA_URI_DRAFT_07} for the Draft-07 `$schema` URI * @stability stable * @category constants * @since 4.0.0 */ export declare const META_SCHEMA_URI_DRAFT_04 = "http://json-schema.org/draft-04/schema#"; /** * Represents the `$schema` meta-schema URI for JSON Schema Draft-07. * * **When to use** * * Use when constructing a Draft-07 JSON Schema document and you need a stable * value for the root `$schema` field. * * **Details** * * The exported value is the literal string * `http://json-schema.org/draft-07/schema#`. * * @see {@link META_SCHEMA_URI_DRAFT_04} for the Draft-04 `$schema` URI * @see {@link META_SCHEMA_URI_DRAFT_2020_12} for the Draft 2020-12 `$schema` URI * * @stability stable * @category constants * @since 4.0.0 */ export declare const META_SCHEMA_URI_DRAFT_07 = "http://json-schema.org/draft-07/schema#"; /** * Represents the `$schema` meta-schema URI for JSON Schema Draft 2020-12. * * **When to use** * * Use when you need to populate the `$schema` field while emitting a JSON * Schema document that should declare JSON Schema Draft 2020-12. * * **Details** * * The exported value is the literal string * `https://json-schema.org/draft/2020-12/schema`. * * @see {@link META_SCHEMA_URI_DRAFT_07} for the Draft-07 `$schema` URI * * @stability stable * @category constants * @since 4.0.0 */ export declare const META_SCHEMA_URI_DRAFT_2020_12 = "https://json-schema.org/draft/2020-12/schema"; /** * Parses a raw Draft-07 JSON Schema into a `Document<"draft-2020-12">`. * * **When to use** * * Use when you have a raw JSON Schema object that follows Draft-07 conventions * and need the canonical Draft-2020-12 document representation. * * **Details** * * This converts Draft-07 tuple syntax (`items` as array plus * `additionalItems`) to Draft-2020-12 form (`prefixItems` plus `items`), splits * `dependencies` into `dependentRequired` and `dependentSchemas`, converts * plain-name `$id` fragments to `$anchor`, and extracts root-level * `definitions` into the `definitions` field. Local JSON Pointer refs are * relocated when one of these structural conversions moves its target. * * **Gotchas** * * Unknown and custom keywords are copied as opaque values. Their contents are * not treated as nested schemas. Draft-07 keywords such as `if` / `then` / * `else` and `contains` are preserved and their subschemas are converted. * Siblings of a valid Draft-07 `$ref` are ignored according to Draft-07 * semantics. The conversion throws when a Draft-07 `$id` fragment cannot be * represented as a Draft-2020-12 `$anchor`, or when an unknown Draft-07 * keyword would become an active Draft-2020-12 keyword after copying. * * **Example** (Parsing a Draft-07 schema) * * ```ts import.meta.vitest * import { JsonSchema } from "effect" * * const raw: JsonSchema.JsonSchema = { * type: "object", * properties: { * tags: { * type: "array", * items: { type: "string" } * } * } * } * * const doc = JsonSchema.fromSchemaDraft07(raw) * doc.dialect // => "draft-2020-12" * doc.schema.properties // => { tags: { type: "array", items: { type: "string" } } } * ``` * * @see {@link fromSchemaDraft2020_12} * @see {@link fromSchemaOpenApi3_0} * @see {@link toDocumentDraft07} * @stability stable * @category decoding * @since 4.0.0 */ export declare function fromSchemaDraft07(js: JsonSchema): Document<"draft-2020-12">; /** * Parses a raw Draft-2020-12 JSON Schema into a `Document<"draft-2020-12">`. * * **When to use** * * Use when you already have a raw JSON Schema object in Draft-2020-12 format. * * **Details** * * This separates `$defs` from the root schema into the `definitions` field. * Unlike {@link fromSchemaDraft07}, this performs no keyword rewriting. * * **Example** (Parsing a Draft-2020-12 schema) * * ```ts import.meta.vitest * import { JsonSchema } from "effect" * * const raw: JsonSchema.JsonSchema = { * type: "number", * minimum: 0, * $defs: { PositiveInt: { type: "integer", minimum: 1 } } * } * * const doc = JsonSchema.fromSchemaDraft2020_12(raw) * doc.schema // => { type: "number", minimum: 0 } * doc.definitions // => { PositiveInt: { type: "integer", minimum: 1 } } * ``` * * @see {@link fromSchemaDraft07} * @see {@link fromSchemaOpenApi3_1} * @stability stable * @category decoding * @since 4.0.0 */ export declare function fromSchemaDraft2020_12(js: JsonSchema): Document<"draft-2020-12">; /** * Parses a raw OpenAPI 3.1 JSON Schema into a `Document<"draft-2020-12">`. * * **When to use** * * Use when you need to consume raw JSON Schema objects from an OpenAPI 3.1 * specification. * * **Details** * * This rewrites `#/components/schemas/...` refs to `#/$defs/...`, normalizes the * OpenAPI base dialect URI to Draft 2020-12, converts the deprecated singular * `example` field to `examples`, then delegates to * {@link fromSchemaDraft2020_12}. * * **Gotchas** * * When both `example` and `examples` are present, the singular example is * prepended to the array. Custom `$schema` dialect URIs and unknown keywords * are copied opaquely. Component references inside a schema resource identified * by `$id` are left unchanged because they are relative to that resource. * * **Example** (Parsing an OpenAPI 3.1 schema) * * ```ts import.meta.vitest * import { JsonSchema } from "effect" * * const raw: JsonSchema.JsonSchema = { * type: "object", * properties: { * user: { $ref: "#/components/schemas/User" } * } * } * * const doc = JsonSchema.fromSchemaOpenApi3_1(raw) * doc.schema.properties // => { user: { $ref: "#/$defs/User" } } * ``` * * @see {@link fromSchemaOpenApi3_0} * @see {@link toMultiDocumentOpenApi3_1} * @stability stable * @category decoding * @since 4.0.0 */ export declare function fromSchemaOpenApi3_1(js: JsonSchema): Document<"draft-2020-12">; /** * Parses a raw OpenAPI 3.0 JSON Schema into a `Document<"draft-2020-12">`. * * **When to use** * * Use when you need to consume raw JSON Schema objects from an OpenAPI 3.0 * specification. * * **Details** * * This directly converts OpenAPI 3.0 schema objects to Draft-2020-12. It * handles `nullable`, singular `example`, boolean `exclusiveMinimum` and * `exclusiveMaximum`, and OpenAPI component refs. Only values in OpenAPI * schema positions are traversed as schemas. * * **Gotchas** * * OpenAPI 3.0 specifies that `nullable` applies only when the same Schema * Object has an explicit string `type`. For compatibility with tooling that * uses a single-member `allOf` for nullable references, this converter also * rewrites `{ nullable: true, allOf: [schema] }` to * `{ anyOf: [schema, { type: "null" }] }` when there is no string `type` or * existing `anyOf`. Sibling constraints such as `enum` remain unchanged and * may still reject null. * * Unknown keywords, vendor extensions, and annotation values are * copied opaquely unless their name would become active in Draft 2020-12 and * change meaning, in which case conversion throws. Siblings of a valid * OpenAPI 3.0 `$ref` are ignored. * * **Example** (Parsing an OpenAPI 3.0 nullable schema) * * ```ts import.meta.vitest * import { JsonSchema } from "effect" * * const raw: JsonSchema.JsonSchema = { * type: "string", * nullable: true * } * * const doc = JsonSchema.fromSchemaOpenApi3_0(raw) * doc.schema.type // => ["string", "null"] * ``` * * @see {@link fromSchemaOpenApi3_1} * @see {@link fromSchemaDraft07} * @stability stable * @category decoding * @since 4.0.0 */ export declare function fromSchemaOpenApi3_0(schema: JsonSchema): Document<"draft-2020-12">; /** * Converts a `Document<"draft-2020-12">` to a `Document<"draft-07">`. * * **When to use** * * Use when you need to output a canonical JSON Schema document in Draft-07 * format. * * **Details** * * This rewrites `#/$defs/...` refs to `#/definitions/...`, converts * Draft-2020-12 tuple syntax (`prefixItems` plus `items`) to Draft-07 form * (`items` as array plus `additionalItems`), merges `dependentRequired` and * `dependentSchemas` into `dependencies`, and converts both the root schema * and all definitions. Local JSON Pointer refs are relocated when structural * keywords move. * * **Gotchas** * * Unknown and custom keywords are copied as opaque values. Known keywords * that Draft-07 cannot represent cause the conversion to throw * instead of being dropped. These include dynamic references, * `unevaluatedProperties`, `unevaluatedItems`, and non-default `minContains` * or `maxContains` constraints. Conversion also throws when an opaque * Draft-2020-12 keyword would collide with an active Draft-07 keyword, or when * `$id` and `$anchor` occur together because Draft-07 cannot preserve both identifiers. * * **Example** (Converting to Draft-07) * * ```ts import.meta.vitest * import { JsonSchema } from "effect" * * const doc = JsonSchema.fromSchemaDraft2020_12({ * type: "array", * prefixItems: [{ type: "string" }, { type: "number" }], * items: { type: "boolean" } * }) * * const draft07 = JsonSchema.toDocumentDraft07(doc) * draft07.dialect // => "draft-07" * draft07.schema.items // => [{ type: "string" }, { type: "number" }] * draft07.schema.additionalItems // => { type: "boolean" } * ``` * * @see {@link fromSchemaDraft07} * @see {@link toDocumentDraft04} for converting to Draft-04 * @see {@link toMultiDocumentOpenApi3_1} * @stability stable * @category encoding * @since 4.0.0 */ export declare function toDocumentDraft07(document: Document<"draft-2020-12">): Document<"draft-07">; /** * Converts a `Document<"draft-2020-12">` to a `Document<"draft-04">`. * * **When to use** * * Use when you need to output a canonical JSON Schema document in Draft-04 * format. * * **Details** * * This directly rewrites `#/$defs/...` refs to `#/definitions/...`, converts * tuple syntax, merges canonical dependencies, lowers `const` to `enum`, * converts numeric exclusive bounds to the Draft-04 boolean form, lowers * conditionals and basic `contains` through boolean applicators, and converts * both the root schema and all definitions. * * **Gotchas** * * Unknown and custom keywords are copied as opaque values. Newer annotation * keywords are preserved as Draft-04 extensions. Known keywords * without a Draft-04 equivalent, including `propertyNames`, non-default * `contains` cardinality, dynamic references, and unevaluated constraints, * cause the conversion to throw instead of being dropped. A conditional with * both branches also throws when lowering it would duplicate a nested schema * identifier. Conversion also throws when an opaque Draft-2020-12 keyword * would collide with an active Draft-04 keyword, or when `$id` and `$anchor` * occur together because Draft-04 cannot preserve both identifiers. * * **Example** (Converting exclusive bounds) * * ```ts import.meta.vitest * import { JsonSchema } from "effect" * * const doc = JsonSchema.fromSchemaDraft2020_12({ * type: "number", * exclusiveMinimum: 0 * }) * * JsonSchema.toDocumentDraft04(doc).schema // => { type: "number", minimum: 0, exclusiveMinimum: true } * ``` * * @see {@link toDocumentDraft07} for converting to Draft-07 * @stability stable * @category encoding * @since 4.0.0 */ export declare function toDocumentDraft04(document: Document<"draft-2020-12">): Document<"draft-04">; /** * Converts a `MultiDocument<"draft-2020-12">` to a * `MultiDocument<"openapi-3.1">`. * * **When to use** * * Use when you need to emit an OpenAPI 3.1 multi-document from canonical JSON * Schema documents. * * **Details** * * This rewrites local `#/$defs/...` refs to `#/components/schemas/...` and * sanitizes definition keys to match the OpenAPI component key pattern * (`^[a-zA-Z0-9.\-_]+$`) by replacing invalid characters with `_`. Valid keys * are preserved. When sanitized keys collide, the converter appends the first * available `_1`, `_2`, and subsequent suffix, with allocation independent of * definition insertion order. All local refs are updated to use the allocated * keys, including refs to paths within a definition. * * **Gotchas** * * External refs and local refs outside `#/$defs` are left unchanged. Conversion * throws when a custom keyword would become an active OpenAPI keyword and * therefore change meaning. References inside schema resources identified by * `$id` are left unchanged. Conversion throws when an identified root schema * references the detached shared definitions pool because OpenAPI cannot * preserve that fragment reference. * * **Example** (Converting to OpenAPI 3.1) * * ```ts import.meta.vitest * import { JsonSchema } from "effect" * * const multi: JsonSchema.MultiDocument<"draft-2020-12"> = { * dialect: "draft-2020-12", * schemas: [{ $ref: "#/$defs/User" }], * definitions: { * User: { type: "object", properties: { name: { type: "string" } } } * } * } * * const openapi = JsonSchema.toMultiDocumentOpenApi3_1(multi) * openapi.dialect // => "openapi-3.1" * openapi.schemas[0] // => { $ref: "#/components/schemas/User" } * ``` * * @see {@link toDocumentDraft07} * @see {@link MultiDocument} * @stability stable * @category encoding * @since 4.0.0 */ export declare function toMultiDocumentOpenApi3_1(multiDocument: MultiDocument<"draft-2020-12">): MultiDocument<"openapi-3.1">; //# sourceMappingURL=JsonSchema.d.ts.map