import type { Keyof } from "@fabric/core"; import type { FieldToType } from "./fields/field-to-type.ts"; import { Field, type FieldDefinition } from "./fields/index.ts"; export type CustomModelFields = Record; export interface Collection< TName extends string = string, TFields extends CustomModelFields = CustomModelFields, > { name: TName; fields: TFields; } export const DefaultModelFields = { id: Field.uuid({ isPrimaryKey: true }), streamId: Field.uuid({ isIndexed: true }), streamVersion: Field.integer({ isUnsigned: true, hasArbitraryPrecision: true, }), deletedAt: Field.timestamp({ isOptional: true }), }; export interface Model< TName extends string = string, TFields extends CustomModelFields = CustomModelFields, > extends Collection { fields: typeof DefaultModelFields & TFields; } export function defineModel< TName extends string, TFields extends CustomModelFields, >(name: TName, fields: TFields): Model { return { name, fields: { ...DefaultModelFields, ...fields }, } as const; } export function defineCollection< TName extends string, TFields extends CustomModelFields, >(name: TName, fields: TFields): Collection { return { name, fields, } as const; } export type ModelToType = { [K in Keyof]: FieldToType; }; export type ModelFieldNames = Keyof< TModel["fields"] >; export type ModelAddressableFields = { [K in Keyof]: TModel["fields"][K] extends { isUnique: true } ? K : never; }[Keyof];