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 68 lines 1.7 kB view raw
1import type { $Typed } from "../core.ts"; 2import { 3 Schema, 4 type ValidationResult, 5 type Validator, 6 type ValidatorContext, 7} from "../validation.ts"; 8 9export type TypedRefSchemaValidator<V extends { $type?: string } = any> = 10 V extends { $type?: infer T extends string } 11 ? { $type: T } & Validator<V & { $type?: T }> 12 : never; 13 14export type TypedRefGetter<V extends { $type?: string } = any> = () => 15 TypedRefSchemaValidator<V>; 16 17export type TypedRefSchemaOutput<V extends { $type?: string } = any> = V extends 18 { $type?: infer T extends string } ? $Typed<V, T> : never; 19 20export class TypedRefSchema<V extends { $type?: string } = any> extends Schema< 21 TypedRefSchemaOutput<V> 22> { 23 #getter: TypedRefGetter<V>; 24 25 constructor(getter: TypedRefGetter<V>) { 26 super(); 27 this.#getter = getter; 28 } 29 30 get schema(): TypedRefSchemaValidator<V> { 31 const value = this.#getter.call(null); 32 33 this.#getter = throwAlreadyCalled; 34 35 Object.defineProperty(this, "schema", { 36 value, 37 writable: false, 38 enumerable: false, 39 configurable: true, 40 }); 41 42 return value; 43 } 44 45 get $type(): TypedRefSchemaOutput<V>["$type"] { 46 return this.schema.$type; 47 } 48 49 validateInContext( 50 input: unknown, 51 ctx: ValidatorContext, 52 ): ValidationResult<TypedRefSchemaOutput<V>> { 53 const result = ctx.validate(input, this.schema); 54 if (!result.success) return result; 55 56 if (result.value.$type !== this.$type) { 57 return ctx.issueInvalidPropertyValue(result.value, "$type", [ 58 this.$type, 59 ]); 60 } 61 62 return result as ValidationResult<TypedRefSchemaOutput<V>>; 63 } 64} 65 66function throwAlreadyCalled(): never { 67 throw new Error("TypedRefSchema getter called multiple times"); 68}