/* eslint-disable @typescript-eslint/ban-types,@typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types */ import at from "lodash/at"; import pick from "lodash/pick"; export interface EntityType< TUnsaved = any, TSaved = any, TIds extends object = any > { _saved: TSaved; _unsaved: TUnsaved; _idKeys: TIds; idOf: (rec: TSaved) => TIds; } export type UnsavedR = T["_unsaved"]; export type SavedR = T["_saved"]; export type KeyType = R["_idKeys"]; export interface PgRecordInfo< Unsaved = any, Saved extends Unsaved & IdType = any, IdType extends object = any > extends EntityType { tableName: string; schemaName: string; idKeys: (keyof Saved)[]; } /** * Extract the runtime key name from a recordInfo */ export function idKeysOf( recordInfoWithIdKey: RI ): string[] { return recordInfoWithIdKey.idKeys as any; } /** * Turns a record type with possibly more fields than "id" into an array */ export function collectIdValues( idObj: KeyType, knexRecordType: RecordT ): string[] { return at(idObj, idKeysOf(knexRecordType)); } function castToRecordInfo( runtimeData: Omit ): PgRecordInfo { return runtimeData as PgRecordInfo; } /** * * Creates a record descriptor that captures the table name, primary key name, * unsaved type, and saved type of a database record type. Assumes "id" as the * primary key name * */ export function recordInfo( schemaName: string, tableName: string ): PgRecordInfo>; export function recordInfo( schemaName: string, tableName: string ): PgRecordInfo>; /** * * Creates a record descriptor that captures the table name, primary key name, * unsaved type, and saved type of a database record type. * */ export function recordInfo< Unsaved, Saved extends Unsaved, Id extends keyof Saved >( schemaName: string, tableName: string, idKey: Id[] ): PgRecordInfo>; /** * * Don't use this signature be sure to provide unsaved and saved types. * */ export function recordInfo( schemaName: string, tableName: string, idKeys?: string[] ) { idKeys = idKeys || ["id"]; return castToRecordInfo({ schemaName, tableName, idKeys, idOf: (rec) => pick(rec, idKeys as any), }); } /** * * Creates a record descriptor for records with composite primary keys * */ export function compositeRecordType< TUnsaved, TSaved extends TUnsaved = TUnsaved >( schemaName: string, tableName: string ): { withCompositeKeys( keys: TKeys[] ): PgRecordInfo>; } { return { withCompositeKeys(keys) { return castToRecordInfo({ schemaName, tableName, idKeys: keys, idOf: (rec) => pick(rec, keys), }); }, }; }