I have a function that returns other functions like so:
export const makeAudienceDb = () => {
async function insert({ ...params }: AudienceAttributes) {
const audience = await AudienceModel.create({ ...params })
const audienceToJson = audience.toJSON()
return audienceToJson
}
async function findById({ id }: { id: number }) {
const user = await AudienceModel.findByPk(id)
return user?.toJSON()
}
async function remove({ id }: { id: number }) {
return AudienceModel.destroy({ where: { id } })
}
async function update({
id,
...changes
}: { id: number } & AudienceAttributes) {
const updated = await AudienceModel.update(
{ ...changes },
{ where: { id } }
)
return updated
}
return Object.freeze({
insert,
findById,
remove,
update,
})
}
I have other models, e.g UserModel, PostModel which have the same database operations as makeAudienceDb. e.g
export const makeUsersDb = ({ hashPassword, createToken }: DBDeps) => {
async function insert({ ...params }: User) {
if (params.password) {
params.password = await hashPassword(params.password)
}
const newUser = await UserModel.create({ ...params })
const returnedUser = newUser.toJSON()
const { id } = newUser
const { name, username, email, password } = returnedUser as User
const payload = {
id,
email,
}
const token = createToken(payload)
const user = { id, name, username, password, email }
return { user, token }
}
async function findById({ id }: { id: number }) {
const user = await UserModel.findByPk(id)
return user?.toJSON()
}
async function findByEmail({ email }: { email: string }) {
const user = await UserModel.findOne({ where: { email } })
return user?.toJSON()
}
async function remove({ id }: { id: number }) {
return UserModel.destroy({ where: { id } })
}
async function update({ id, ...changes }: { id: number } & User) {
const updated = await UserModel.update({ ...changes }, { where: { id } })
return updated
}
return Object.freeze({
insert,
findByEmail,
findById,
remove,
update,
})
}
This leads to code duplication across various levels. I want to know how to create one major function that I can reuse for other database operations. So instead of me having makeAudienceDb, makeUsersDb, I could just have one major function e.g majorDatabaseOps where makeAudienceDb and makeUsersDb could just inherit from. I know this is possible with ES6 Classes and Interfaces but I was just wondering how I could implement the same in a functional way. Any contribution is welcome. Thank you very much!