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 64 lines 1.7 kB view raw
1import type { WithOptionalProperties } from "../core/types.ts"; 2import { lazyProperty } from "../util/lazy-property.ts"; 3import { isPlainObject } from "../data/object.ts"; 4import { 5 type Infer, 6 Schema, 7 type ValidationResult, 8 type Validator, 9 type ValidatorContext, 10} from "../validation.ts"; 11 12export type ObjectSchemaShape = Record<string, Validator>; 13 14export type ObjectSchemaOutput<Shape extends ObjectSchemaShape> = 15 WithOptionalProperties< 16 { 17 [K in keyof Shape]: Infer<Shape[K]>; 18 } 19 >; 20 21export class ObjectSchema< 22 const Shape extends ObjectSchemaShape = any, 23> extends Schema<ObjectSchemaOutput<Shape>> { 24 constructor(readonly shape: Shape) { 25 super(); 26 } 27 28 get validatorsMap(): Map<string, Validator> { 29 const map = new Map(Object.entries(this.shape)); 30 return lazyProperty(this, "validatorsMap", map); 31 } 32 33 validateInContext( 34 input: unknown, 35 ctx: ValidatorContext, 36 ): ValidationResult<ObjectSchemaOutput<Shape>> { 37 if (!isPlainObject(input)) { 38 return ctx.issueInvalidType(input, "object"); 39 } 40 41 let copy: Record<string, unknown> | undefined; 42 43 for (const [key, propDef] of this.validatorsMap) { 44 const result = ctx.validateChild(input, key, propDef); 45 if (!result.success) { 46 if (!(key in input)) { 47 return ctx.issueRequiredKey(input, key); 48 } 49 return result; 50 } 51 52 if (result.value === undefined && !(key in input)) { 53 continue; 54 } 55 56 if (result.value !== input[key]) { 57 copy ??= { ...input }; 58 copy[key] = result.value; 59 } 60 } 61 62 return ctx.success((copy ?? input) as ObjectSchemaOutput<Shape>); 63 } 64}