import {
BulkCrudOperationKeys,
LoggerOfFlags,
OperationKeys,
RepositoryFlags,
} from "@decaf-ts/db-decorators";
import { Adapter } from "./Adapter";
import { Observable, type Observer } from "../interfaces/index";
import { Logger } from "@decaf-ts/logging";
import { Constructor } from "@decaf-ts/decoration";
import { Model } from "@decaf-ts/decorator-validation";
import { ContextualArgs } from "../utils";
import { Context } from "./Context";
import { Repository } from "../repository/Repository";
export type FlagsOfContext<C extends Context<any>> =
C extends Context<infer F> ? F : never;
export type LoggerOfContext<C extends Context<any>> = LoggerOfFlags<
FlagsOfContext<C>
>;
export type ContextOfRepository<R extends Repository<any, any>> =
R extends Repository<any, infer A> ? ContextOf<A> : never;
export type FlagsOfRepository<R extends Repository<any, any>> = FlagsOfContext<
ContextOfRepository<R>
>;
export type LoggerOfRepository<R extends Repository<any, any>> =
LoggerOfContext<ContextOfRepository<R>>;
export type ContextOf<
OBJ extends Repository<any, any> | Adapter<any, any, any, any>,
> =
OBJ extends Adapter<any, any, any, infer C>
? C
: OBJ extends Repository<any, any>
? ContextOfRepository<OBJ>
: never;
export type LoggerOfAdapter<A extends Adapter<any, any, any, any>> =
A extends Adapter<any, any, any, infer C> ? LoggerOfContext<C> : never;
export type FlagsOfAdapter<A extends Adapter<any, any, any, any>> =
A extends Adapter<any, any, any, infer C> ? FlagsOfContext<C> : never;
export type LoggerOf<
OBJ extends
| AdapterFlags<any>
| Context<any>
| Adapter<any, any, any>
| Repository<any, any>,
> =
OBJ extends AdapterFlags<any>
? LoggerOfFlags<OBJ>
: OBJ extends Context<any>
? LoggerOfContext<OBJ>
: OBJ extends Repository<any, any>
? LoggerOfRepository<OBJ>
: OBJ extends Adapter<any, any, any>
? // @ts-expect-error stoopid eslint
LoggerOfAdapter<OBJ>
: Logger;
export type FlagsOf<
OBJ extends Repository<any, any> | Adapter<any, any, any, any> | Context<any>,
> =
OBJ extends Context<any>
? FlagsOfContext<OBJ>
: OBJ extends Repository<any, any>
? FlagsOfRepository<OBJ>
: OBJ extends Adapter<any, any, any, any>
? FlagsOfAdapter<OBJ>
: never;
export type PersistenceObservable<CONTEXT extends Context<any>> = Observable<
[Observer, ObserverFilter?],
[
Constructor | string,
OperationKeys | BulkCrudOperationKeys | string,
EventIds,
...ContextualArgs<CONTEXT>,
]
>;
export type PersistenceObserver<CONTEXT extends Context<any>> = Observer<
[
Constructor | string,
OperationKeys | BulkCrudOperationKeys | string,
EventIds,
...ContextualArgs<CONTEXT>,
]
>;
/**
* @description Type representing possible ID formats for database events
* @summary A union type that defines the possible formats for event identifiers in the persistence layer.
* These can be single values (string, number, bigint) or arrays of these types.
* @typedef {(string|number|bigint|string[]|number[]|bigint[])} EventIds
* @memberOf module:core
*/
export type EventIds =
| string
| number
| bigint
| string[]
| number[]
| bigint[];
export type ObserverFilter = (
table: string | Constructor,
event: OperationKeys | BulkCrudOperationKeys | string,
id: EventIds,
...args: [...any[], Context<any>]
) => boolean;
export type InferredAdapterConfig<A> =
A extends Adapter<infer CONF, any, any> ? CONF : never;
export interface AdapterDispatch<A extends Adapter<any, any, any, any>>
extends PersistenceObservable<ContextOf<A>> {
close(): Promise<void>;
updateObservers<M extends Model>(
table: Constructor<M> | string,
event: OperationKeys | BulkCrudOperationKeys | string,
id: EventIds,
...args: ContextualArgs<ContextOf<A>>
): Promise<void>;
}
export interface Migration<QUERYRUNNER, A extends Adapter<any, any, any, any>> {
transaction: boolean;
up(qr: QUERYRUNNER, adapter?: A, ctx?: ContextOf<A>): Promise<void>;
down(qr: QUERYRUNNER, adapter?: A, ctx?: ContextOf<A>): Promise<void>;
}
export type RepositoryFor<A extends Adapter<any, any, any, any>> =
A extends Adapter<any, any, any, any> ? ReturnType<A["repository"]> : never;
export type PreparedModel = {
record: Record<string, any>;
id: string;
transient?: Record<string, any>;
};
export type AdapterFlags<LOG extends Logger = Logger> = RepositoryFlags<LOG> & {
allowRawStatements: boolean;
allowGenerationOverride: boolean;
squashSimpleQueries: boolean;
allowComplexStatements: boolean;
};
Source