import type { ForbidUndefinedValue, NextVersion, ValueEvolution, ValueSchema, ValueSchemaDecoded, } from '../domain/schema-model/index.js'; import type { ValueESchema } from './value-eschema.js'; import { DraftedValueESchemaBuilder } from './drafted-value-eschema-builder.js'; export class ValueESchemaBuilder< TVersion extends string, TLatest extends ValueSchema, > { constructor( private readonly name: string, private readonly evolutions: readonly ValueEvolution[], readonly version: TVersion, private readonly finish: ( version: V, evolutions: readonly ValueEvolution[], ) => ValueESchema, ) {} evolve, S extends ValueSchema>( version: V, schema: S & ForbidUndefinedValue, migration: (previous: ValueSchemaDecoded) => ValueSchemaDecoded, ) { return new ValueESchemaBuilder( this.name, [...this.evolutions, { version, schema, migration }], version, this.finish, ); } draft( schema: S & ForbidUndefinedValue, migrations: { readonly forward: ( previous: ValueSchemaDecoded, ) => ValueSchemaDecoded; readonly backward: ( draft: ValueSchemaDecoded, ) => ValueSchemaDecoded; }, ): DraftedValueESchemaBuilder { return new DraftedValueESchemaBuilder( this.name, this.evolutions, this.version, { schema, forward: migrations.forward, backward: migrations.backward, }, ); } build(): ValueESchema { return this.finish(this.version, this.evolutions); } }