import type { Annotation } from "../_schema.js" import * as MO from "../_schema.js" import { named } from "../_schema.js" import * as Arbitrary from "../Arbitrary.js" import * as Constructor from "../Constructor.js" import * as Encoder from "../Encoder.js" import * as Guard from "../Guard.js" import * as Parser from "../Parser.js" import * as S from "./schemed.js" export type SchemaForModel = MO.Schema< MO.ParserInputOf, M, MO.ConstructorInputOf, MO.EncodedOf, MO.ApiOf & MO.ApiSelfType > export type ParserFor = Parser.Parser< MO.ParserInputOf, MO.ParserErrorOf, MO.ParsedShapeOf > export type ConstructorFor = Constructor.Constructor< MO.ConstructorInputOf, MO.ParsedShapeOf, MO.ConstructorErrorOf > export type EncoderFor = Encoder.Encoder< MO.ParsedShapeOf, MO.EncodedOf > export type GuardFor = Guard.Guard> export type ArbitraryFor = Arbitrary.Gen< MO.ParsedShapeOf > export type ModelFor = M extends MO.ParsedShapeOf ? SchemaForModel : SchemaForModel, Self> export interface Model extends S.Schemed, MO.Schema< MO.ParserInputOf, M, MO.ConstructorInputOf, MO.EncodedOf, MO.ApiOf > { [S.schemaField]: Self readonly Parser: ParserFor> readonly Constructor: ConstructorFor> readonly Encoder: EncoderFor> readonly Guard: GuardFor> readonly Arbitrary: ArbitraryFor> } /** * @inject genericName */ export function Model(__name?: string) { return (self: Self): Model => { const schemed = S.Schemed(named(__name ?? "Model(Anonymous)")(self)) const schema = S.schema(schemed) Object.defineProperty(schemed, MO.SchemaContinuationSymbol, { value: schema }) Object.defineProperty(schemed, "Api", { get() { return self.Api } }) Object.defineProperty(schemed, ">>>", { value: self[">>>"] }) Object.defineProperty(schemed, "Parser", { value: Parser.for(schema) }) Object.defineProperty(schemed, "Constructor", { value: Constructor.for(schema) }) Object.defineProperty(schemed, "Encoder", { value: Encoder.for(schema) }) Object.defineProperty(schemed, "Guard", { value: Guard.for(schema) }) Object.defineProperty(schemed, "Arbitrary", { value: Arbitrary.for(schema) }) Object.defineProperty(schemed, "annotate", { value: (identifier: Annotation, meta: Meta) => new MO.SchemaAnnotated(schema, identifier, meta) }) // @ts-expect-error the following is correct return schemed } }