0.0.3Updated 3 hours ago
type Prettify<T> = {
  [K in keyof T]: T[K]
}

type SchemaTypes = 'serial' | 'number' | 'integer' | 'text' | 'boolean' | 'timestamp'
type SchemaDataType<T extends SchemaTypes> =
  T extends 'serial' ? number :
  T extends 'number' ? number :
  T extends 'integer' ? number :
  T extends 'text' ? string :
  T extends 'boolean' ? boolean :
  T extends 'timestamp' ? Date :
  never;

export type Infer<T extends Schema> = Prettify<
  {
    [K in keyof T as T[K]['nullable'] extends true ? K : never]?: SchemaDataType<T[K]['type']> | null
  } 
  &
  {
    [K in keyof T as T[K]['nullable'] extends true ? never : K]: SchemaDataType<T[K]['type']>
  }
>;

export interface SchemaValue<T extends SchemaTypes> {
  type: T
  nullable?: boolean
  default?: SchemaDataType<T>
  unique?: boolean
}

export const field = <T extends SchemaTypes, C extends Omit<SchemaValue<T>, 'type'>>(type: T, config: C = {} as C) => {
  return {
    type,
    ...config
  }
}

export type Schema = Record<string, SchemaValue<SchemaTypes>>