UNPKG

@cheetah.js/orm

Version:
318 lines (317 loc) 12.3 kB
import { PropertyOptions } from '../decorators/property.decorator'; import { Collection } from '../domain/collection'; import { Reference } from '../domain/reference'; import { ValueObject } from '../common/value-object'; export interface DriverInterface { connectionString: string; executeStatement(statement: Statement<any>): Promise<{ query: any; startTime: number; sql: string; }>; connect(): Promise<void>; disconnect(): Promise<void>; executeSql(s: string): Promise<any>; snapshot(tableName: string, options: any): Promise<SnapshotTable | undefined>; getCreateTableInstruction(schema: string | undefined, tableName: string, creates: ColDiff[]): string; getAlterTableFkInstruction(schema: string | undefined, tableName: string, colDiff: ColDiff, fk: ForeignKeyInfo): string; getCreateIndex(index: { name: string; properties?: string[]; }, schema: string | undefined, tableName: string): string; getAddColumn(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff, colDiffInstructions: string[]): void; getDropColumn(colDiffInstructions: string[], schema: string | undefined, tableName: string, colName: string): void; getDropIndex(index: { name: string; properties?: string[]; }, schema: string | undefined, tableName: string): string; getAlterTableType(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string; getAlterTableDefaultInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string; getAlterTablePrimaryKeyInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string; getDropConstraint(param: { name: string; }, schema: string | undefined, tableName: string): string; getAddUniqueConstraint(schema: string | undefined, tableName: string, colName: string): string; getAlterTableDropNullInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string; getAlterTableDropNotNullInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string; getAlterTableEnumInstruction(schema: string, tableName: string, colName: string, colDiff: ColDiff): string; getDropTypeEnumInstruction(param: { name: string; }, schema: string | undefined, tableName: string): string; startTransaction(): Promise<void>; commitTransaction(): Promise<void>; rollbackTransaction(): Promise<void>; } export type ValueOrInstance<T> = T extends ValueObject<any, any> ? T | T['value'] : NonNullable<T>; export type SnapshotConstraintInfo = { indexName: string; consDef: string; type: string; }; export interface ConnectionSettings<T extends DriverInterface = DriverInterface> { host?: string; port?: number; username?: string; password?: string; database?: string; connectionString?: string; ssl?: boolean; driver: T; entities?: Function[] | string; migrationPath?: string; } export type ConditionOperators<T, C> = { $ne?: T; $in?: T[]; $nin?: T[]; $like?: string; $gt?: T; $gte?: T; $lt?: T; $lte?: T; $and?: Condition<C>[]; $or?: Condition<C>[]; }; export type Condition<T> = { [P in keyof T]?: T[P] | ConditionOperators<T[P], T>; }; export type InstanceOf<T> = { [key in keyof T]: T[key]; }; export type ClassType<T = any> = { [k: string]: T; }; export interface EnumOptions<T> extends PropertyOptions { items?: (number | string)[] | (() => ClassType); array?: boolean; } export type JoinStatement<T> = { type: 'INNER' | 'LEFT' | 'RIGHT'; originalEntity?: Function; originTable: string; originSchema: string; originAlias: string; joinTable: string; joinSchema: string; joinAlias: string; joinEntity?: Function; joinWhere?: string; joinProperty: string; on: string; propertyKey: string | symbol; hooks?: { type: string; propertyName: string; }[]; }; export type Statement<T> = { statement?: 'select' | 'insert' | 'update' | 'delete'; table?: string; alias?: string; customSchema?: string; columns?: Array<keyof T>; join?: JoinStatement<T>[]; selectJoin?: Statement<T>[]; strategy?: 'select' | 'joined'; where?: string; values?: any; groupBy?: string[]; orderBy?: string[]; limit?: number; offset?: number; hooks?: { type: string; propertyName: string; }[]; instance?: InstanceOf<T>; joinProperty?: string; fkKey?: string; primaryKey?: string; originAlias?: string; originProperty?: string; joinEntity?: Function; originEntity?: Function; }; export type SnapshotTable = { tableName: string; schema?: string; columns: ColumnsInfo[]; indexes: SnapshotIndexInfo[]; foreignKeys?: ForeignKeyInfo[]; }; export type SnapshotIndexInfo = { table: string; indexName: string; columnName: string; }; export type ForeignKeyInfo = { referencedTableName: string; referencedColumnName: string; }; export type ColumnsInfo = { name: string; type: string; nullable?: boolean; default?: string | null; primary?: boolean; unique?: boolean; autoIncrement?: boolean; length?: number; isEnum?: boolean; precision?: number; scale?: number; isDecimal?: boolean; enumItems?: string[] | number[]; foreignKeys?: ForeignKeyInfo[]; }; export type SqlActionType = 'CREATE' | 'DELETE' | 'ALTER' | 'INDEX'; export type ColDiff = { actionType: SqlActionType; colName: string; colType?: string; colLength?: number; indexTables?: { name: string; properties?: string[]; }[]; colChanges?: { default?: string | null; primary?: boolean; unique?: boolean; nullable?: boolean; autoIncrement?: boolean; enumItems?: string[] | number[]; enumModified?: boolean; precision?: number; scale?: number; foreignKeys?: ForeignKeyInfo[]; }; }; export type TableDiff = { tableName: string; schema?: string; newTable?: boolean; colDiffs: ColDiff[]; }; export declare const PrimaryKeyType: unique symbol; export declare const PrimaryKeyProp: unique symbol; type ReadonlyPrimary<T> = T extends any[] ? Readonly<T> : T; export type Primary<T> = T extends { [PrimaryKeyType]?: infer PK; } ? ReadonlyPrimary<PK> : T extends { _id?: infer PK; } ? ReadonlyPrimary<PK> | string : T extends { uuid?: infer PK; } ? ReadonlyPrimary<PK> : T extends { id?: infer PK; } ? ReadonlyPrimary<PK> : never; export type PrimaryProperty<T> = T extends { [PrimaryKeyProp]?: infer PK; } ? PK : T extends { _id?: any; } ? '_id' | string : T extends { uuid?: any; } ? 'uuid' : T extends { id?: any; } ? 'id' : never; export type IPrimaryKeyValue = number | string | bigint | Date | { toHexString(): string; }; export type IPrimaryKey<T extends IPrimaryKeyValue = IPrimaryKeyValue> = T; export type OperatorMap<T> = { $and?: Query<T>[]; $or?: Query<T>[]; $eq?: ExpandScalar<T> | ExpandScalar<T>[]; $ne?: ExpandScalar<T>; $in?: ExpandScalar<T>[]; $nin?: ExpandScalar<T>[]; $not?: Query<T>; $gt?: ExpandScalar<T>; $gte?: ExpandScalar<T>; $lt?: ExpandScalar<T>; $lte?: ExpandScalar<T>; $like?: string; }; export type ExcludeFunctions<T, K extends keyof T> = T[K] extends Function ? never : (K extends symbol ? never : K); export type Scalar = boolean | number | string | bigint | symbol | Date | RegExp | Uint8Array | { toHexString(): string; }; export type ExpandProperty<T> = T extends Reference<infer U> ? NonNullable<U> : T extends Collection<infer U, any> ? NonNullable<U> : T extends (infer U)[] ? NonNullable<U> : NonNullable<T>; export type ExpandScalar<T> = null | (T extends string ? T | RegExp : T extends Date ? Date | string : T); type ExpandObject<T> = T extends object ? T extends Scalar ? never : { -readonly [K in keyof T as ExcludeFunctions<T, K>]?: Query<ExpandProperty<T[K]>> | FilterValue<ExpandProperty<T[K]>> | null; } : never; export type EntityProps<T> = { -readonly [K in keyof T as ExcludeFunctions<T, K>]?: T[K]; }; export type Query<T> = T extends object ? T extends Scalar ? never : FilterQuery<T> : FilterValue<T>; export type FilterValue2<T> = T | ExpandScalar<T> | Primary<T>; export type FilterValue<T> = OperatorMap<FilterValue2<T>> | FilterValue2<T> | FilterValue2<T>[] | null; export type EntityClass<T> = Function & { prototype: T; }; export type EntityName<T> = string | EntityClass<T> | { name: string; }; export type ObjectQuery<T> = ExpandObject<T> & OperatorMap<T>; export type FilterQuery<T> = ObjectQuery<T> | NonNullable<ExpandScalar<Primary<T>>> | NonNullable<EntityProps<T> & OperatorMap<T>> | FilterQuery<T>[]; export type Relationship<T> = { isRelation?: boolean; relation: 'one-to-many' | 'many-to-one'; type: Function; fkKey?: (string & keyof T) | ((e: T) => any); entity: () => EntityName<T>; originalEntity?: EntityName<T>; propertyKey: string | symbol; columnName: string; } & Partial<PropertyOptions>; export type Cast<T, R> = T extends R ? T : R; export type IsUnknown<T> = T extends unknown ? unknown extends T ? true : never : never; export type IdentifiedReference<T, PK extends keyof T | unknown = PrimaryProperty<T>> = true extends IsUnknown<PK> ? Reference<T> : ({ [K in Cast<PK, keyof T>]: T[K]; } & Reference<T>); export type Ref<T, PK extends keyof T | unknown = PrimaryProperty<T>> = IdentifiedReference<T, PK>; type Loadable<T extends object> = Collection<T, any> | Reference<T> | readonly T[]; type ExtractType<T> = T extends Loadable<infer U> ? U : T; type StringKeys<T, E extends string = never> = T extends Collection<any, any> ? `${Exclude<keyof ExtractType<T> | E, symbol>}` : T extends Ref<any> ? `${Exclude<keyof ExtractType<T> | E, symbol>}` : T extends object ? `${Exclude<keyof ExtractType<T> | E, symbol>}` : never; type Defined<T> = Exclude<T, null | undefined>; type GetStringKey<T, K extends StringKeys<T, string>, E extends string> = K extends keyof T ? ExtractType<T[K]> : (K extends E ? keyof T : never); type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; export type AutoPath<O, P extends string, E extends string = never, D extends Prev[number] = 5> = [D] extends [never] ? string : P extends any ? (P & `${string}.` extends never ? P : P & `${string}.`) extends infer Q ? Q extends `${infer A}.${infer B}` ? A extends StringKeys<O, E> ? `${A}.${AutoPath<Defined<GetStringKey<O, A, E>>, B, E, Prev[D]>}` : never : Q extends StringKeys<O, E> ? (Defined<GetStringKey<O, Q, E>> extends unknown ? Exclude<P, `${string}.`> : never) | (StringKeys<Defined<GetStringKey<O, Q, E>>, E> extends never ? never : `${Q}.`) : keyof ExtractType<O> : never : never; export declare enum QueryOrder { ASC = "ASC", ASC_NULLS_LAST = "ASC NULLS LAST", ASC_NULLS_FIRST = "ASC NULLS FIRST", DESC = "DESC", DESC_NULLS_LAST = "DESC NULLS LAST", DESC_NULLS_FIRST = "DESC NULLS FIRST", asc = "asc", asc_nulls_last = "asc nulls last", asc_nulls_first = "asc nulls first", desc = "desc", desc_nulls_last = "desc nulls last", desc_nulls_first = "desc nulls first" } export declare enum QueryOrderNumeric { ASC = 1, DESC = -1 } export type QueryOrderKeysFlat = QueryOrder | QueryOrderNumeric | keyof typeof QueryOrder; export type QueryOrderKeys<T> = QueryOrderKeysFlat | QueryOrderMap<T>; export type QueryOrderMap<T> = { [K in keyof T as ExcludeFunctions<T, K>]?: QueryOrderKeys<ExpandProperty<T[K]>>; }; export type EntityField<T, P extends string = never> = AutoPath<T, P, '*'>; export interface FindOptions<T, P extends string = never> { load?: readonly AutoPath<T, P>[]; orderBy?: (QueryOrderMap<T> & { 0?: never; }) | QueryOrderMap<T>[]; limit?: number; offset?: number; fields?: readonly EntityField<T, P>[]; schema?: string; loadStrategy?: 'select' | 'joined'; } export type FindOneOption<T, P extends string = never> = Omit<FindOptions<T, P>, 'limit' | 'offset'>; export {};