specified
Version:
Type-safe typescript data specification verification
113 lines (112 loc) • 4.41 kB
TypeScript
import { ValidationFailure } from "./validation_error";
export { ValidationFailure } from "./validation_error";
export interface GlobalOptions {
readonly failEarly?: boolean;
}
export interface SpecOptions<LocalOptions extends {} = {}> {
readonly local?: LocalOptions;
readonly global: GlobalOptions;
}
export interface ConstraintDefinition {
readonly name: string;
readonly settings?: object;
}
export interface SpecConstraint<T> {
readonly version: 1;
readonly eval: (value: T) => {
err?: ValidationFailure | null;
};
readonly definition: ConstraintDefinition;
}
export interface SpecDefinition {
readonly type: string;
readonly nested?: {
[key: string]: SpecDefinition;
};
readonly alias?: string;
readonly constraints?: ConstraintDefinition[];
readonly adjustments?: object;
readonly flags?: string[];
readonly defaultValue?: unknown;
readonly descriptions?: {
[attr: string]: string;
};
}
export declare type EvalResult<T> = {
err: ValidationFailure;
} | {
err: null;
value: T;
};
export interface Spec<R extends EvalResult<any>, LocalOpts extends {} = {}> {
readonly version: 1;
readonly eval: (value: unknown, options: SpecOptions<LocalOpts>) => R;
readonly definition: SpecDefinition;
}
export declare type VerifiedType<S extends Spec<any, any>> = Extract<ReturnType<S["eval"]>, {
err: null;
}>["value"];
export declare type EvalResultOf<S extends Spec<any, any>> = {
err: ValidationFailure;
} | {
err: null;
value: VerifiedType<S>;
};
export declare type LocalOptionsOf<S extends Spec<any, any>> = Required<Parameters<S["eval"]>[1]>["local"];
interface VerifyResult<T> {
readonly err: ValidationFailure | null;
readonly value: () => T;
}
interface VerifyOptions {
errorClass: new (msg: string, err: ValidationFailure) => ValidationFailure;
}
export declare const verify: <S extends Spec<EvalResult<any>, {}>>(spec: S, value: unknown, globalOptions?: GlobalOptions, verifyOptions?: VerifyOptions) => VerifyResult<Extract<ReturnType<S["eval"]>, {
err: null;
}>["value"]>;
export declare const alias: <S extends Spec<EvalResult<any>, any>>(aliasName: string, spec: S) => Spec<EvalResultOf<S>, Required<Parameters<S["eval"]>[1]>["local"]>;
export declare const constrain: <S extends Spec<EvalResult<any>, any>>(spec: S, constraints: SpecConstraint<Extract<ReturnType<S["eval"]>, {
err: null;
}>["value"]>[]) => Spec<EvalResultOf<S>, Required<Parameters<S["eval"]>[1]>["local"]>;
export declare function optional<S extends Spec<EvalResult<any>, any>>(spec: S): Spec<EvalResultOf<S>, LocalOptionsOf<S>> & {
optional: true;
};
export declare function optional<S extends Spec<EvalResult<any>, any>>(spec: S, options: {}): Spec<EvalResultOf<S>, LocalOptionsOf<S>> & {
optional: true;
};
export declare function optional<S extends Spec<EvalResult<any>, any>>(spec: S, options: {
defaultValue: VerifiedType<S>;
}): Spec<EvalResultOf<S>, LocalOptionsOf<S>> & {
optional: false;
};
export declare const adjust: <S extends Spec<EvalResult<any>, any>>(spec: S, adjustedOptions: Required<Parameters<S["eval"]>[1]>["local"]) => Spec<EvalResultOf<S>, Required<Parameters<S["eval"]>[1]>["local"]>;
export declare const definitionOf: <S extends Spec<EvalResult<any>, any>>(spec: S) => SpecDefinition;
export interface AliasedNestedSpecDefinition extends Pick<SpecDefinition, Exclude<keyof SpecDefinition, "nested">> {
nested?: {
[key: string]: SpecDefinition | {
alias: string;
};
};
}
export declare const extractAliases: (def: SpecDefinition) => {
definition: AliasedNestedSpecDefinition | {
alias: string;
};
aliases: {
[name: string]: AliasedNestedSpecDefinition;
};
};
declare type SpecEvalResultType<S> = S extends Spec<EvalResult<any>, any> ? EvalResultOf<S> : never;
declare type TupleSpecEvalResultTypes<T> = {
[P in keyof T]: SpecEvalResultType<T[P]>;
};
declare type TupleTypeUnion<TT> = TT extends Array<infer U> ? U : never;
export declare const either: <SpecsTuple extends Spec<any, any>[]>(...specs: SpecsTuple) => {
version: 1;
definition: {
type: string;
nested: {};
};
eval: (value: unknown, options: SpecOptions<{}>) => TupleTypeUnion<TupleSpecEvalResultTypes<SpecsTuple>> | {
err: ValidationFailure;
};
};