/* eslint-disable @typescript-eslint/no-dynamic-delete */ import db from '@database/models/_instance' import { Request } from 'express' import _ from 'lodash' import { Transaction } from 'sequelize' import getterObject from './getterObject' import Multers from './Multer' class withState { private req: Request constructor(req: Request) { this.req = req this.req.setState = this.setState.bind(this) this.req.setBody = this.setBody.bind(this) this.req.setFieldState = this.setFieldState.bind(this) this.req.getState = this.getState.bind(this) this.req.getCookies = this.getCookies.bind(this) this.req.getHeaders = this.getHeaders.bind(this) this.req.getQuery = this.getQuery.bind(this) this.req.getQueryPolluted = this.getQueryPolluted.bind(this) this.req.getParams = this.getParams.bind(this) this.req.getBody = this.getBody.bind(this) this.req.getSingleArrayFile = this.getSingleArrayFile.bind(this) this.req.pickSingleFieldMulter = this.pickSingleFieldMulter.bind(this) this.req.getMultiArrayFile = this.getMultiArrayFile.bind(this) this.req.pickMultiFieldMulter = this.pickMultiFieldMulter.bind(this) this.req.getTransaction = this.getTransaction.bind(this) this.req.rollbackTransactions = this.rollbackTransactions.bind(this) this.req._transaction = {} } setState(value: object): void { this.req.state = { ...(this.req.state || {}), ...value, } } setBody(value: object): void { this.req.body = { ...this.req.body, ...value, } } setFieldState(key: any, value: any): void { _.set(this.req.state, key, value) } getState(path: any, defaultValue?: any): any { return _.get(this.req.state, path, defaultValue) } getCookies(path?: any, defaultValue?: any): any { return getterObject(this.req.cookies, path, defaultValue) } getHeaders(path?: any, defaultValue?: any): any { return getterObject(this.req.headers, path, defaultValue) } getQuery(path?: any, defaultValue?: any): any { return getterObject(this.req.query, path, defaultValue) } getQueryPolluted(path?: any, defaultValue?: any): any { // @ts-expect-error return getterObject(this.req.queryPolluted, path, defaultValue) } getParams(path?: any, defaultValue?: any): any { return getterObject(this.req.params, path, defaultValue) } getBody(path?: any, defaultValue?: any): any { return getterObject(this.req.body, path, defaultValue) } async getTransaction(id?: any): Promise<Transaction> { id = id === undefined ? 1 : id const txn = this.req._transaction[id] if (txn) { return txn } const newTxn = await db.sequelize.transaction() this.req._transaction[id] = newTxn return newTxn } async rollbackTransactions(): Promise<void> { const { _transaction } = this.req const entryTransactions = Object.entries(_transaction) for (let i = 0; i < entryTransactions.length; i += 1) { const [id, value] = entryTransactions[i] as [any, Transaction] await value.rollback() delete _transaction[id] } } getSingleArrayFile(name: string): any { const data = getterObject( this.req, ['files', name, '0'].join('.') ) as unknown as Express.Multer.File if (data) { return data } } pickSingleFieldMulter(fields: string[]): Partial<any> { return Multers.pickSingleFieldMulter(this.req, fields) } getMultiArrayFile(name: string): any { const data = _.get(this.req.files, name, []) as Express.Multer.File if (data) { return data } } pickMultiFieldMulter(fields: string[]): Partial<any> { return Multers.pickMultiFieldMulter(this.req, fields) } } export default withState