import * as Avro from "./avro.domain"; import { Union } from "./union"; import { Null } from "./primitives"; type RequiredField = { type: T; doc?: string; }; type DefaultedField = { type: T; doc?: string; default: T["_ts"]; }; type NullableField = { type: T; doc?: string; default: null; }; type UnbrandedField = | RequiredField | NullableField | DefaultedField; function Field( props: RequiredField | T ): Avro.RequiredField; function Field( props: DefaultedField ): Avro.DefaultedField; function Field( props: NullableField ): Avro.NullableField; function Field(props: UnbrandedField | T) { if (typeof props === "string" || !("doc" in props || "default" in props)) return { type: props }; else if ("default" in props && props.default === null) { return { ...props, type: Union([Null(), props.type]), }; } else return props; } type Record< O extends { [key: string]: Avro.Field }, _ts extends { [key in keyof O]: O[key]["_ts"] } > = Avro.RecordType & { _ts: _ts; }; const Record = < O extends { [key: string]: Avro.Field }, _ts extends { [key in keyof O]: O[key]["_ts"] } >( name: string, fields: O ): Record => (({ type: "record", name, fields: Object.keys(fields).map((name) => ({ name, ...fields[name] })), } as unknown) as Record); export { Record, Field };