Created
January 2, 2025 02:48
-
-
Save DIEGOHORVATTI/ff23811cc4d47e34911f69217f1c4a99 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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