Skip to content

Instantly share code, notes, and snippets.

@DIEGOHORVATTI
Created January 2, 2025 02:48
Show Gist options
  • Save DIEGOHORVATTI/ff23811cc4d47e34911f69217f1c4a99 to your computer and use it in GitHub Desktop.
Save DIEGOHORVATTI/ff23811cc4d47e34911f69217f1c4a99 to your computer and use it in GitHub Desktop.
import { Elysia, t as Type } from 'elysia'
import cors from '@elysiajs/cors'
import { openApi } from '@/middlewares/open-api'
import { rateLimit } from '@/middlewares/rate-limit'
import { MongoClient, Db, Collection, Document, Filter, ObjectId } from 'mongodb'
import { NODE_ENV, version } from '@/constants/config'
import { generateFilterSchema } from '@/shared'
let db: Db
const createModel = <T extends Document>(name: string, schema: Record<string, any>) => {
const mappedSchema = schema as T
const composition = Type.Object(mappedSchema)
const filters = Type.Object(generateFilterSchema<typeof mappedSchema>(mappedSchema))
return {
composition,
schema: mappedSchema,
filters,
getCollection: (name: string): Collection<T> => db.collection<T>(name),
insert: async (data: typeof schema) => {
return await db.collection(name).insertOne(data)
},
save: async (data: typeof schema) => {
const result = await db.collection(name).insertOne(data)
const document = await db.collection<typeof schema>(name).findOne({ _id: new ObjectId(result.insertedId) })
if (!document) {
throw new Error('Failed to retrieve the inserted document.')
}
return document
},
find: async ({
page = 0,
limit = 10,
startDate,
endDate,
...fiters
}: Filter<typeof filters.static & { startDate: string; endDate: string }>) => {
const regexFilters = Object.fromEntries(
Object.entries(fiters).map(([key, value]) => [key, new RegExp(value, 'i')])
)
const options = { skip: (Math.max(page, 1) - 1) * limit, limit }
const query = {
...regexFilters,
...(startDate && { createdAt: { $gte: new Date(startDate as string) } }),
...(endDate && { createdAt: { $lte: new Date(endDate as string) } })
}
console.log(query)
return await db.collection(name).find(query, options).toArray()
}
}
}
// Definindo o schema do modelo Partner
const schema = {
address: Type.String({ default: 'Rua dos Bobos, nº 0' }),
role: Type.Enum(
{
medico: 'Médico',
enfermeiro: 'Enfermeiro',
tecnico: 'Técnico'
},
{ default: 'Médico' }
),
name: Type.String({ default: 'Fulano' }),
document: Type.String({ default: '000.000.000-00' }),
specialties: Type.Array(Type.String({ default: 'Clínico Geral' })),
phone: Type.String({ default: '0000-0000' }),
email: Type.String({ default: '[email protected]' }),
crm: Type.Optional(Type.String({ default: '0000000' }))
}
export const PartnerModel = createModel<typeof schema>('partners', schema)
const run = async () => {
const client = new MongoClient('mongodb://root:password@localhost:27017')
await client.connect()
db = client.db('elysia')
console.info('🐋 Database connected')
if (NODE_ENV) console.info(`🌟 ${NODE_ENV}`)
if (version) console.info(`🔖 v${version}`)
new Elysia()
.use(
cors({
preflight: true,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
})
)
.use(rateLimit)
.onError(({ code, error }) => {
if (code === 'NOT_FOUND') return 'Route not found 😭'
if (code === 'VALIDATION') {
const { summary, ...primaryError } = error.all[0]
if ('path' in primaryError) return { error: `${primaryError.path.slice('/'.length)}: ${summary}` }
return { error: summary }
}
return error
})
.use(openApi)
.use(
new Elysia({ tags: ['Parceiros'], prefix: '/partners' })
.post(
'/filters',
async ({ body }) => {
const partners = await PartnerModel.find(body)
return { message: 'Parceiros encontrados com sucesso', partners }
},
{
body: PartnerModel.filters,
detail: { description: 'Lista todos os parceiros com filtros e paginação' }
}
)
.post(
'/partners',
async ({ body }) => {
const partner = await PartnerModel.save(body)
return { message: 'Parceiro inserido com sucesso', partner }
},
{
body: PartnerModel.composition,
detail: { description: 'Insere um novo parceiro na base de dados' }
}
)
)
.listen(3000, ({ url }) => console.info(`🦊 Elysia is running at ${url}`))
}
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment