import type {Id} from "./id.js" import type {TransactionOptions} from "mongodb" //////// //////// //////// export type Value = | null | undefined | boolean | number | string | bigint | Id export interface Row { [column: string]: Value } export interface Schema { [key: string]: Row | Schema } export interface Shape { [key: string]: boolean | Shape } export type AsRow = xRow export type AsSchema = xSchema export type AsShape = xShape export type SchemaToShape = { [P in keyof xSchema]: xSchema[P] extends Row ? boolean : xSchema[P] extends Schema ? SchemaToShape : never } export interface Table { create(...rows: xRow[]): Promise read(o: PaginatedConditional): Promise update(o: Update): Promise delete(o: Conditional): Promise readOne(o: Conditional): Promise count(o: Conditional): Promise average]: true}>( o: Conditional & {fields: xAveraged} ): Promise<{[P in keyof xAveraged]: number}> } export type RowFromTable> = xTable extends Table ? xRow : never export interface Tables { [key: string]: Tables | Table } export type SchemaToTables = Tables & { [P in keyof xSchema]: xSchema[P] extends Row ? Table : xSchema[P] extends Schema ? SchemaToTables : never } export interface Rows { [key: string]: Rows | Row[] } export type SchemaToRows = Rows & { [P in keyof xSchema]: xSchema[P] extends Row ? xSchema[P][] : xSchema[P] extends Schema ? SchemaToRows : never } export type Action = ({}: { tables: xTables abort(): Promise }) => Promise export type Transaction = (action: Action) => Promise export interface DatabaseFromTables { tables: xTables transaction(action: Action): Promise } export interface Database extends DatabaseFromTables> {} export interface DatabaseLike { tables: xTables transaction(action: ({}: { tables: xTables abort(): Promise }) => Promise): Promise } export interface MongoDatabase extends Database { transaction(action: Action, xResult>, options?: TransactionOptions): Promise } //////// //////// //////// export interface Condition { set?: Partial<{[P in keyof xRow]: true}> equal?: Partial less?: Partial lessy?: Partial greater?: Partial greatery?: Partial listed?: Partial search?: Partial<{[P in keyof xRow]: string | RegExp}> notSet?: Partial<{[P in keyof xRow]: true}> notEqual?: Partial notLess?: Partial notLessy?: Partial notGreater?: Partial notGreatery?: Partial notListed?: Partial notSearch?: Partial<{[P in keyof xRow]: string | RegExp}> } export type Conditions = false | ConditionTree export type ConditionOperation = "and" | "or" export type ConditionLeaf = Condition | Conditions export type ConditionBranch = [Op, ...ConditionLeaf[]] export type ConditionTree = | ConditionBranch<"and", xRow> | ConditionBranch<"or", xRow> export interface Conditional { conditions: Conditions } //////// //////// //////// export type Order = Partial<{ [P in keyof xRow]: "ascend" | "descend" | undefined }> export type Pagination = { limit?: number offset?: number order?: Order } export type PaginatedConditional = Conditional & Pagination export type Upsert = Conditional & {upsert: xRow} export type Write = Conditional & {write: Partial} export type Whole = Conditional & {whole: xRow} export type Update = Write | Whole | Upsert export type AmbiguousUpdate = Write & Whole & Upsert export type Assertion = Conditional & { make: () => Promise } //////// //////// //////// export namespace Operation { export enum Type { Create, Update, Delete, } export interface OpBase { type: Type path: string[] } export interface OpCreate extends OpBase { type: Type.Create rows: Row[] } export interface OpUpdate extends OpBase { type: Type.Update update: Update } export interface OpDelete extends OpBase { type: Type.Delete conditional: Conditional } export type Any = | OpCreate | OpUpdate | OpDelete } //////// //////// //////// export const serializationKey = "__serialized_type__" export interface SerializedValue { [serializationKey]: string value: any } export interface SerializedRow { [key: string]: any | SerializedValue } //////// //////// //////// // constraints for row export type UnconstrainRow = xConstraint & xRow export type ConstrainRow = Omit // constraints for table export type UnconstrainTable> = xTable extends Table ? Table> : never export type ConstrainTable> = xTable extends Table ? Table> : never // constraints for tables export type UnconstrainTables = { [P in keyof xTables]: xTables[P] extends Table ? UnconstrainTable : xTables[P] extends Tables ? UnconstrainTables : never } export type ConstrainTables = { [P in keyof xTables]: xTables[P] extends Table ? ConstrainTable : xTables[P] extends Tables ? ConstrainTables : never } // constraints for schema export type UnconstrainSchema = { [P in keyof xSchema]: xSchema[P] extends Row ? UnconstrainRow : xSchema[P] extends Schema ? UnconstrainSchema : never } export type ConstrainSchema = { [P in keyof xSchema]: xSchema[P] extends Row ? ConstrainRow : xSchema[P] extends Schema ? ConstrainSchema : never } //////// //////// //////// export interface FlexStorage { read(key: string): Promise write(key: string, data: T): Promise delete(key: string): Promise } export interface JsonStorage { read(key: string): T write(key: string, data: T): void delete(key: string): void } export interface SimpleStorage { getItem(key: string): string | undefined setItem(key: string, data: string): void removeItem(key: string): void } export interface Cache { time: number data: xData } //////// //////// //////// export type Await = T extends Promise ? U : T export type RemoveIndex = { [ K in keyof T as string extends K ? never : number extends K ? never : K ] : T[K] }