loom-schema
Version:
Class-based JSON Schema library with full TypeScript support
149 lines • 6.83 kB
TypeScript
import { type ErrorObject, type Options as AjvOptions, type KeywordDefinition, type Vocabulary } from "ajv";
export interface BaseSchemaOptions {
$schema?: string;
$id?: string;
$vocabulary?: Record<string, boolean>;
$comment?: string;
$anchor?: string;
$recursiveAnchor?: boolean;
$recursiveRef?: string;
title?: string;
description?: string;
examples?: any[];
deprecated?: boolean;
readOnly?: boolean;
writeOnly?: boolean;
default?: any;
allOf?: JsonSchemaInput[];
anyOf?: JsonSchemaInput[];
oneOf?: JsonSchemaInput[];
not?: JsonSchema | boolean;
if?: JsonSchema | boolean;
then?: JsonSchema | boolean;
else?: JsonSchema | boolean;
$ref?: string;
$defs?: Record<string, JsonSchema | boolean>;
enum?: any[];
const?: any;
[key: string]: any;
}
export type JsonSchemaType = "string" | "number" | "integer" | "boolean" | "object" | "array" | "null";
export type KnownFormat = "date-time" | "date" | "time" | "duration" | "email" | "idn-email" | "hostname" | "idn-hostname" | "ipv4" | "ipv6" | "uri" | "uri-reference" | "iri" | "iri-reference" | "uuid" | "json-pointer" | "relative-json-pointer" | "regex" | string;
export interface StringSchemaOptions extends BaseSchemaOptions {
type?: "string";
format?: KnownFormat;
pattern?: string;
minLength?: number;
maxLength?: number;
contentEncoding?: string;
contentMediaType?: string;
contentSchema?: JsonSchemaInput | boolean;
}
export interface NumberSchemaOptions extends BaseSchemaOptions {
type?: "number";
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
multipleOf?: number;
}
export interface IntegerSchemaOptions extends BaseSchemaOptions {
type?: "integer";
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
multipleOf?: number;
}
export interface BooleanSchemaOptions extends BaseSchemaOptions {
type?: "boolean";
}
export interface ArraySchemaOptions extends BaseSchemaOptions {
type?: "array";
items?: JsonSchemaInput;
prefixItems?: JsonSchemaInput[];
additionalItems?: JsonSchemaInput;
contains?: JsonSchemaInput;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
minContains?: number;
maxContains?: number;
unevaluatedItems?: JsonSchemaInput | boolean;
}
export interface ObjectSchemaOptions extends BaseSchemaOptions {
type?: "object";
properties?: Record<string, JsonSchemaInput>;
patternProperties?: Record<string, JsonSchemaInput>;
additionalProperties?: JsonSchemaInput | boolean;
propertyNames?: JsonSchemaInput;
minProperties?: number;
maxProperties?: number;
required?: string[];
dependentSchemas?: Record<string, JsonSchemaInput>;
dependentRequired?: Record<string, string[]>;
unevaluatedProperties?: JsonSchemaInput | boolean;
}
export interface NullSchemaOptions extends BaseSchemaOptions {
type?: "null";
}
export type JsonSchema = JsonSchemaBase;
export type JsonSchemaBase = BaseSchemaOptions;
export type SchemaFragment<T = any> = {
toSchema(name?: string, visited?: Map<SchemaFragment<any>, string>, usageMap?: Map<SchemaFragment<any>, number>): JsonSchema;
validate(data: any, ajvOptions?: AjvOptions & {
customKeywords?: (KeywordDefinition | string)[];
customVocabularies?: Vocabulary[];
}): Promise<{
valid: boolean;
errors: ErrorObject[] | null | undefined;
}>;
toSchemaWithUsage?: (name?: string) => JsonSchema;
};
export type JsonSchemaInput = JsonSchema | SchemaFragment<any>;
export declare const schema: (options?: Partial<ObjectSchemaOptions>) => SchemaFragment<any>;
export declare const string: (options?: Partial<StringSchemaOptions>) => SchemaFragment<string>;
export declare const number: (options?: Partial<NumberSchemaOptions>) => SchemaFragment<number>;
export declare const integer: (options?: Partial<IntegerSchemaOptions>) => SchemaFragment<number>;
export declare const boolean: (options?: Partial<BooleanSchemaOptions>) => SchemaFragment<boolean>;
export declare const nil: (options?: Partial<NullSchemaOptions>) => SchemaFragment<null>;
export declare const array: <T extends JsonSchemaInput | undefined = undefined>(options: Partial<ArraySchemaOptions> & {
items?: T;
}) => SchemaFragment<T extends SchemaFragment<infer U> ? U[] : any[]>;
type InferExplicit<T extends {
properties: Record<string, JsonSchemaInput>;
required?: readonly (keyof T["properties"])[];
}> = {
[K in T["required"] extends readonly (keyof T["properties"])[] ? T["required"][number] : never]: T["properties"][K] extends SchemaFragment<infer U> ? U : any;
} & {
[K in Exclude<keyof T["properties"], T["required"] extends readonly (keyof T["properties"])[] ? T["required"][number] : never>]?: T["properties"][K] extends SchemaFragment<infer U> ? U : any;
};
type AllowAny<T extends object> = [keyof T] extends [never] ? T : T & {
[K in Exclude<string, keyof T>]?: any;
};
export declare function object<const T extends Partial<ObjectSchemaOptions>>(options: AllowAny<T>): SchemaFragment<"properties" extends keyof T ? T extends {
properties: Record<string, JsonSchemaInput>;
required?: readonly (keyof T["properties"])[];
} ? InferExplicit<T> : {
[K in keyof T]: T[K] extends SchemaFragment<infer U> ? U : any;
} : {
[K in keyof T]: T[K] extends SchemaFragment<infer U> ? U : any;
}>;
export type Infer<T> = T extends SchemaFragment<infer U> ? U : never;
type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
type AllOfOut<T extends readonly JsonSchemaInput[]> = UnionToIntersection<{
[K in keyof T]: T[K] extends SchemaFragment<infer A> ? A : unknown;
}[number]>;
type AnyOfOut<T extends readonly JsonSchemaInput[]> = {
[K in keyof T]: T[K] extends SchemaFragment<infer A> ? A : unknown;
}[number];
export declare const allOf: <T extends readonly [JsonSchemaInput, ...JsonSchemaInput[]]>(fragments: T, options?: Partial<BaseSchemaOptions>) => SchemaFragment<AllOfOut<T>>;
export declare const anyOf: <T extends readonly [JsonSchemaInput, ...JsonSchemaInput[]]>(fragments: T, options?: Partial<BaseSchemaOptions>) => SchemaFragment<AnyOfOut<T>>;
export declare const oneOf: <T extends readonly SchemaFragment<any>[]>(fragments: T, options?: Partial<BaseSchemaOptions>) => SchemaFragment<T[number] extends SchemaFragment<infer U> ? U : never>;
export declare const conditional: ({ if: ifFragment, then: thenFragment, else: elseFragment, }: {
if: JsonSchemaInput;
then: JsonSchemaInput;
else: JsonSchemaInput;
}, options?: Partial<BaseSchemaOptions>) => SchemaFragment<any>;
export {};
//# sourceMappingURL=schema.d.ts.map