/* eslint-disable @typescript-eslint/ban-ts-comment */ // Keep in mind that this file is automatically generated. // You can change the content of this file, but it will be overwritten. import { Prisma } from '@prisma/client'; import _ from 'lodash'; import { Aggregate, AnyRecord, BaseOption, CountArgs, Find, ModelName, models, ModelScalarFields, ModelStructure, ModelTypes, } from './prisma-repo'; export const extractCondition = (conditions: Cursor | Where | number | string) => { const dbCond = _.isObject(conditions) ? conditions : { id: _.toNumber(conditions) }; return dbCond; }; /** * @param modelName - The model name */ const BaseRepository = < T extends ModelName, Where extends ModelTypes[T]['Where'], Select extends ModelTypes[T]['Select'], Include extends ModelTypes[T]['Include'], Create extends ModelTypes[T]['Create'], Update extends ModelTypes[T]['Update'], Cursor extends ModelTypes[T]['Cursor'], Order extends ModelTypes[T]['Order'], Delegate extends ModelTypes[T]['Delegate'], Scalar extends ModelScalarFields, Model extends ModelStructure[T] >( modelName: T ) => { abstract class AbstractBaseRepository { protected static modelName: T = modelName; /** * Find zero or more `model` that matches the filter.\ * Note, that providing `undefined` is treated as the value not being there. */ public static async findAll( conditions: Where | number | string, filterQueryParams: AnyRecord = {}, query: AnyRecord = {}, option: Find = {} ) { const limit = +(query.limit === 'all' ? 0 : _.get(query, 'limit', 10)); const offset = query.page && query.page > 0 ? limit * (query.page - 1) : 0; const otherOptions = _.omit(query, ['limit', 'offset', 'page']); const where = { ...extractCondition(conditions), ...filterQueryParams, ...otherOptions, }; return { // @ts-ignore rows: (await AbstractBaseRepository.model.findMany({ // @ts-ignore where, ...option, skip: offset, ...(limit > 0 && { take: limit }), })) as Model[], /* @ts-ignore */ count: await this.count(where), }; } /** * Alternative of `findAll`.\ * It works same as `findOne` but only have different names.\ * It exists for anyone who prefer to use prisma `functions` original name. */ public static async findMany(...params: Parameters) { return AbstractBaseRepository.findAll(...params); } /** * Find the first `model` that matches the filter.\ * Note, that providing `undefined` is treated as the value not being there. */ public static async findOne( conditions: Where | number | string, option: Find = {} ) { const where = extractCondition(conditions); // @ts-ignore return AbstractBaseRepository.model.findFirst({ // @ts-ignore where, ...option, }) as Promise; } /** * Alternative of `findOne`.\ * It works same as `findOne` but only have different names.\ * It exists for anyone who prefer to use prisma `functions` original name. */ public static async findFirst(...params: Parameters) { return AbstractBaseRepository.findOne(...params); } /** * Find zero or one `model` that matches the filter.\ * Note, that providing `undefined` is treated as the value not being there.\ * It works same as `findOne` or `findFirst` but only accept a unique column. */ public static async findUnique( conditions: Cursor | number | string, option: BaseOption = {} ) { const where = extractCondition(conditions); // @ts-ignore return AbstractBaseRepository.model.findUnique({ // @ts-ignore where, ...option, }) as Promise; } /** * Create a `model`. */ public static async create(data: Create, option: BaseOption = {}) { // @ts-ignore return AbstractBaseRepository.model.create({ data, ...option }) as Promise; } /** * Update a `model`. */ public static async update( conditions: Where | number | string, data: Update | Create, option: BaseOption = {} ) { const where = extractCondition(conditions); // @ts-ignore return AbstractBaseRepository.model.update({ data, // @ts-ignore where, ...option, }) as Promise; } /** * Delete any `model` that match with the conditions. */ public static async delete(conditions: Where | number | string) { const where = extractCondition(conditions); // @ts-ignore return AbstractBaseRepository.model.deleteMany({ // @ts-ignore where, }) as Promise; } /** * Delete a `model`. */ public static async deleteOne(conditions: Where | number | string) { const where = extractCondition(conditions); // @ts-ignore return AbstractBaseRepository.model.delete({ // @ts-ignore where, }) as Promise; } /** * Create or update one `model`. */ public static async updateOrCreate( conditions: Where | number | string, data: Create, option: Find = {} ) { const obj = await AbstractBaseRepository.findOne(conditions, option); if (obj) return AbstractBaseRepository.update(conditions, data, option); return AbstractBaseRepository.create(data); } /** * Alternative of `updateOrCreate`.\ * It works same as `updateOrCreate` but only have different names.\ * It exists for anyone who prefer to use prisma `functions` original name. */ public static async upsert(...params: Parameters) { return AbstractBaseRepository.updateOrCreate(...params); } /** * Create many `model`. */ public static async bulkCreate(data: Prisma.Enumerable, skipDuplicates = true) { // @ts-ignore return AbstractBaseRepository.model.createMany({ data, // @ts-ignore skipDuplicates, }) as Promise; } /** * Alternative of `bulkCreate`.\ * It works same as `bulkCreate` but only have different names.\ * It exists for anyone who prefer to use prisma `functions` original name. */ public static async createMany(...params: Parameters) { return AbstractBaseRepository.bulkCreate(...params); } /** * Update zero or more `model`. * Note, that providing `undefined` is treated as the value not being there. */ public static async bulkUpdate(where: Where, data: Prisma.Enumerable) { // @ts-ignore return AbstractBaseRepository.model.updateMany({ data, where, }) as Promise; } /** * Alternative of `bulkUpdate`.\ * It works same as `bulkUpdate` but only have different names.\ * It exists for anyone who prefer to use prisma `functions` original name. */ public static async updateMany(...params: Parameters) { return AbstractBaseRepository.bulkUpdate(...params); } /** * Count the number of `model`.\ * Note, that providing `undefined` is treated as the value not being there. */ public static async count( conditions: Where | number | string, option: CountArgs = {} ) { const where = extractCondition(conditions); // @ts-ignore return AbstractBaseRepository.model.count({ // @ts-ignore where, ...option, }) as Promise; } public static async groupBy( conditions: Where | number | string, aggregator: Omit< // @ts-ignore Parameters[0], 'where' | 'cursor' > & { groupBy: Scalar[]; } ) { const where = extractCondition(conditions); // @ts-ignore return AbstractBaseRepository.model.groupBy({ // @ts-ignore where, ...aggregator, }); } /** * Allows you to perform aggregations operations on a `model`.\ * Note, that providing `undefined` is treated as the value not being there.\ * If no any kind of aggregator provided, will use `count` by default. */ public static aggregate( conditions: Where | number | string, aggregator: Omit< // @ts-ignore Parameters[0], 'cursor' | 'take' | 'skip' | 'orderBy' | 'where' >, option: Aggregate = {} ) { // @ts-ignore const aggregate = AbstractBaseRepository.model.aggregate as Delegate['aggregate']; const where = extractCondition(conditions); if (_.isEmpty(aggregator)) { // @ts-ignore // eslint-disable-next-line no-param-reassign, no-underscore-dangle aggregator._count = true; } // @ts-ignore return aggregate({ // @ts-ignore where, ...aggregator, ...option, }) as ReturnType; } public static get model(): Delegate { // @ts-ignore return models[AbstractBaseRepository.modelName]; } } return AbstractBaseRepository; }; export default BaseRepository;