{"version":3,"file":"crud.service.cjs","sources":["../../nestjs/crud.service.ts"],"sourcesContent":["import { Op, Model, ModelStatic } from 'sequelize';\nimport { FilterType } from '../common/enums/filter-type.enum';\nimport { OrderDirection } from '../common/enums/order-direction.enum';\nimport { Order } from '../common/interfaces/order.interface';\nimport { Filter } from '../common/interfaces/filter.interface';\nimport { merge } from '../common/helpers/merge.helper';\nimport { FindParams } from './interfaces/find-params.interface';\nimport { PK } from '../common/constatns/constatns';\n\nexport abstract class CrudService<T extends Model> {\n  constructor(params?) {\n    if (params) {\n      Object.assign(this, { ...params });\n    }\n  }\n\n  protected pk: string = 'id';\n  protected repository: ModelStatic<T>;\n  protected limit: number;\n  protected allowFilters: Filter[] = [{ key: PK }];\n  protected allowGroups: string[] = [];\n  protected allowOrders: string[] = [PK];\n  protected defaultGroups: string[] = [PK];\n  protected defaultOrders: Order[] = [[PK, OrderDirection.desc]];\n  protected fields;\n  protected fieldsExclude: string[];\n\n  getPK(): string {\n    return this.pk;\n  }\n\n  getRepository(): ModelStatic<T> {\n    return this.repository;\n  }\n\n  getFields(groups: string[] = []): { include: any; exclude: any } {\n    const fields = this.fields || [];\n    const fieldsExclude = this.fieldsExclude || [];\n    const fieldsInclude: any = [];\n\n    for (const [fieldQuery, fieldName] of fields) {\n      if (this.allowGroups.includes(fieldName)) {\n        if (groups.length && groups.includes(fieldName)) {\n          fieldsInclude.push([fieldQuery, fieldName]);\n        } else {\n          fieldsExclude.push(fieldName);\n        }\n      } else {\n        fieldsInclude.push([fieldQuery, fieldName]);\n      }\n    }\n\n    return {\n      include: fieldsInclude,\n      exclude: fieldsExclude,\n    };\n  }\n\n  getQueryFilters(queryFilters: object) {\n    const filters = structuredClone(queryFilters);\n\n    if (filters?.[PK]) {\n      filters[this.pk] = filters[PK];\n      delete filters[PK];\n    }\n\n    return filters;\n  }\n\n  getAllowFilters(): Filter[] {\n    const allowFilters = structuredClone(this.allowFilters);\n\n    return allowFilters.map((filter) => {\n      return {\n        ...filter,\n        key: filter.key === PK ? this.pk : filter.key,\n      };\n    });\n  }\n\n  getAllowOrders(): string[] {\n    const allowOrders = this.allowOrders;\n\n    return allowOrders.map((key) => {\n      return key === PK ? this.pk : key;\n    });\n  }\n\n  getFilters(query) {\n    const filters = [];\n    const queryFilters = this.getQueryFilters(query.filters);\n    const allowFilters = this.getAllowFilters();\n\n    if (queryFilters) {\n      for (const { key, field, type } of allowFilters) {\n        const filterKey = key;\n        const filterFiled = field || filterKey;\n        const filterValue = queryFilters?.[filterKey];\n        const filterValueFrom = queryFilters?.[`${filterFiled}_from`];\n        const filterValueTo = queryFilters?.[`${filterFiled}_to`];\n        const filterField = (this.fields || []).find(([select, fieldKey]) => fieldKey === filterFiled); // Custom field\n        let whereField = filterField\n          ? filterField[0]\n          : this.repository.sequelize.col(`${this.repository.name}.${filterFiled}`);\n        const whereValue: any = {};\n\n        switch (type) {\n          case FilterType.text:\n            if (filterValue) {\n              whereValue[Op.like] = `%${filterValue}%`;\n            }\n            break;\n\n          case FilterType.period:\n          case FilterType.range:\n            if (filterValueFrom) {\n              whereValue[Op.gte] = filterValueFrom;\n            }\n\n            if (filterValueTo) {\n              whereValue[Op.lte] = filterValueTo;\n            }\n            break;\n\n          case FilterType.number:\n          default:\n            if (filterValue) {\n              whereValue[Op.eq] = filterValue;\n            }\n            break;\n        }\n\n        if (whereField && Reflect.ownKeys(whereValue).length) {\n          filters.push(this.repository.sequelize.where(whereField, whereValue));\n        }\n      }\n    }\n\n    return filters;\n  }\n\n  getGroups(query) {\n    const groups: any = [];\n    const queryGroups = (query.groups || this.defaultGroups).map((key) => (key === PK ? this.pk : key));\n\n    if (queryGroups) {\n      for (let key of this.allowGroups) {\n        const fieldKey = key === PK ? this.pk : key;\n\n        if (queryGroups.includes(fieldKey)) {\n          groups.push(fieldKey);\n        }\n      }\n    }\n\n    return groups;\n  }\n\n  getOrders(query) {\n    const orders = [];\n    const allowOrders = this.getAllowOrders();\n    const queryOrders = query.orders\n      ? Object.entries(query.orders).map(([key, direction]) => [key, direction])\n      : this.defaultOrders;\n    const groups = this.getGroups(query);\n    const fields = this.getFields(groups);\n    const fieldNames = fields.include.map((field) => field[1]);\n\n    if (queryOrders) {\n      for (const key of allowOrders) {\n        const fieldKey = key;\n        const fieldInSelect = !fieldNames.length || fieldNames.includes(fieldKey);\n\n        const order = queryOrders\n          .map(([field, direction]) => {\n            if (field === PK) {\n              field = this.pk;\n            }\n\n            return [field, direction];\n          })\n          .find(([field, direction]) => {\n            return field === fieldKey;\n          });\n\n        if (order && fieldInSelect) {\n          orders.push(order);\n        }\n      }\n    }\n\n    return orders;\n  }\n\n  getLimit(query): number {\n    if (query?.limit) {\n      return +query.limit;\n    }\n\n    return this.limit;\n  }\n\n  getOffset(query): number {\n    return +query?.offset || 0;\n  }\n\n  getIncludes(query) {\n    const includes = query.includes || [];\n\n    return includes;\n  }\n\n  findAll({ scope, ...params }: FindParams) {\n    return this.repository.scope(scope).findAll(params as object);\n  }\n\n  findOne({ scope, ...params }: FindParams) {\n    return this.repository.scope(scope).findOne(params as object);\n  }\n\n  getFindParams({ params, query }): FindParams {\n    const filters = this.getFilters(query);\n    const includes = this.getIncludes(query);\n    const orders = this.getOrders(query);\n    const groups = this.getGroups(query);\n    const fields = this.getFields(groups);\n    const limit = this.getLimit(query);\n    const offset = this.getOffset(query);\n    const findParams = params || {};\n    const findParamsBase = {\n      attributes: {\n        include: fields?.include?.length ? fields?.include : [],\n        exclude: fields?.exclude?.length ? fields?.exclude : [],\n      },\n      include: includes,\n      scope: ['defaultScope'],\n      limit: limit,\n      offset: offset,\n      where: filters.length ? filters : undefined,\n      order: orders,\n      group: groups,\n    };\n\n    return merge(findParamsBase, findParams);\n  }\n\n  getItems({ params, query }: { params?; query? }) {\n    const findParams = this.getFindParams({ params, query });\n\n    return this.findAll({\n      ...findParams,\n    });\n  }\n\n  getItem({ params, query }: { params?; query? }) {\n    const findParams = this.getFindParams({ params, query });\n\n    return this.findOne({\n      ...findParams,\n    });\n  }\n\n  create(data: object) {\n    return this.repository.create(data as any);\n  }\n\n  update(pk: number, data: object, returning: boolean = true) {\n    return this.repository\n      .update(data, {\n        where: {\n          [this.pk]: pk,\n        } as any,\n      })\n      .then((result: any) => {\n        if (returning) {\n          return this.findOne({\n            where: {\n              [this.pk]: pk,\n            },\n          });\n        }\n\n        return result;\n      });\n  }\n\n  delete(where?) {\n    return this.repository.destroy({\n      where,\n    });\n  }\n}\n"],"names":["CrudService","params","PK","OrderDirection","groups","fields","fieldsExclude","fieldsInclude","fieldQuery","fieldName","queryFilters","filters","filter","key","query","allowFilters","field","type","filterKey","filterFiled","filterValue","filterValueFrom","filterValueTo","filterField","select","fieldKey","whereField","whereValue","FilterType","Op","queryGroups","orders","allowOrders","queryOrders","direction","fieldNames","fieldInSelect","order","scope","includes","limit","offset","findParams","findParamsBase","_a","_b","merge","data","pk","returning","result","where"],"mappings":"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"}