Suite of AT Protocol TypeScript libraries built on web standards
20
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 72 lines 2.1 kB view raw
1import { 2 type Infer, 3 IssueCustom, 4 type PropertyKey, 5 type ValidationResult, 6 type Validator, 7 type ValidatorContext, 8} from "../validation.ts"; 9import type { CustomAssertionContext } from "./custom.ts"; 10 11export type RefinementCheck<T> = { 12 check: (value: T, ctx: CustomAssertionContext) => boolean; 13 message: string; 14 path?: PropertyKey | readonly PropertyKey[]; 15}; 16 17export type RefinementAssertion<T, Out extends T> = { 18 check: (this: null, value: T, ctx: CustomAssertionContext) => value is Out; 19 message: string; 20 path?: PropertyKey | readonly PropertyKey[]; 21}; 22 23export type InferRefinement<R> = R extends RefinementCheck<infer T> ? T 24 : R extends RefinementAssertion<infer T, any> ? T 25 : never; 26 27export type Refinement<T = any, Out extends T = T> = 28 | RefinementCheck<T> 29 | RefinementAssertion<T, Out>; 30 31export function refine<S extends Validator, Out extends Infer<S>>( 32 schema: S, 33 refinement: RefinementAssertion<Infer<S>, Out>, 34): S & Validator<Out>; 35export function refine<S extends Validator>( 36 schema: S, 37 refinement: RefinementCheck<Infer<S>>, 38): S; 39export function refine< 40 R extends Refinement, 41 S extends Validator<InferRefinement<R>>, 42>(schema: S, refinement: R): S; 43export function refine<S extends Validator>( 44 schema: S, 45 refinement: Refinement<Infer<S>>, 46): S { 47 return Object.create(schema, { 48 validateInContext: { 49 value: validateInContextUnbound.bind({ schema, refinement }), 50 enumerable: false, 51 writable: false, 52 configurable: true, 53 }, 54 }); 55} 56 57function validateInContextUnbound<S extends Validator>( 58 this: { schema: S; refinement: Refinement<Infer<S>> }, 59 input: unknown, 60 ctx: ValidatorContext, 61): ValidationResult<Infer<S>> { 62 const result = ctx.validate(input, this.schema); 63 if (!result.success) return result; 64 65 const checkResult = this.refinement.check.call(null, result.value, ctx); 66 if (!checkResult) { 67 const path = ctx.concatPath(this.refinement.path); 68 return ctx.failure(new IssueCustom(path, input, this.refinement.message)); 69 } 70 71 return result; 72}