Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jeremyben/reflet
Well-defined ๐ decorators for Node.
https://github.com/jeremyben/reflet
cron decorator-framework decorators express kiss mongoose node nodejs typescript
Last synced: about 1 month ago
JSON representation
Well-defined ๐ decorators for Node.
- Host: GitHub
- URL: https://github.com/jeremyben/reflet
- Owner: jeremyben
- License: mit
- Created: 2019-06-27T22:08:06.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2024-03-19T21:24:14.000Z (8 months ago)
- Last Synced: 2024-09-28T23:52:48.082Z (about 2 months ago)
- Topics: cron, decorator-framework, decorators, express, kiss, mongoose, node, nodejs, typescript
- Language: TypeScript
- Homepage:
- Size: 2.72 MB
- Stars: 19
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.MD
- License: LICENSE
Awesome Lists containing this project
README
Reflet ๐ซ
Reflet is a suite of modules made of well-typed [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html).
Reflet is simple and flexible. It will help you organize your app, without the pitfall of verbosity.
But most importantly, Reflet is french for reflection (pronounce _ruh flay_ ๐).## [Reflet/express](./express)
Organize your [Express](https://expressjs.com/) application.
**[Documentation](./express/README.MD)**.```ts
@Use(isAuthenticated)
@Router('/things')
class ThingRouter {@Get('/:id')
async get(@Params('id') id: string, @Res res: Response) {
const thing = await db.collection('things').find({ id })
res.status(200).send(thing)
}@Send({ status: 201 })
@UseGuards((req) => canCreateThing(req.user))
@Post()
async create(@Body('item') item: string) {
const newThing = await db.collection('things').insertOne({ item })
return newThing
```_Add-on: [Reflet/express-middlewares](./express-middlewares)_
## [Reflet/mongoose](./mongoose)
Declare your [Mongoose](https://mongoosejs.com/) models in a more concise way.
**[Documentation](./mongoose/README.MD)**.```ts
@Model()
@SchemaOptions({ autoIndex: false })
class User extends Model.I {
static findByEmail(email) {
return this.findOne({ email });
}@Field({ type: String, required: true })
email: string@Field(String)
name: string
}const user = new User({ email: '[email protected]', name: 'Jeremy' })
await user.save()
```## [Reflet/http](./http)
Typed HTTP primitives to use within any framework.
**[Documentation](./http/README.md)**.```ts
@Router('/things')
class ThingRouter {
@UseStatus(Status.Created)
@Post()
async create(@Headers(RequestHeader.Authorization) auth: string) {
if (!auth) {
throw HttpError.Unauthorized('Stop right there')
}
}
}
```## Philosophy ๐ฃ
Why another decorator framework ? Simply (and biasedly) put, a better developer experience.
### Simple and intuitive
Reflet modules aim to stay close to the technology's underlying abstractions they decorate,
so you **don't have to learn** a whole new terminology to be productive. ๐๏ธโ_e.g. [Reflet/express](./express) has decorators like `Use` for `app.use` method, `Router` for `express.Router`, `Send` for `res.send`.
If you're familiar with Express, you're gonna love its Reflet decorators._As such, Reflet modules don't try to be agnostic or compatible with multiple technologies at once (_e.g. decorators for both Express, Koa, Fastify_), because that would mean :
* more detached, less familiar abstractions. ๐ค
* less accurate static typing (conditional types to aknowledge differences). ๐คฅ
* hence, more error prone code (from my part and yours). ๐Instead, Reflet hopes to provide a well-defined and well-typed module for each libraries.
#### With accurate types
Reflet takes full advantage of TypeScript by **narrowing** its type signatures, to prevent as much mistakes as possible. ๐ฏ
_e.g. [`Headers` decorator](./express/README.MD#request-headers) narrows its input to a union of request headers instead of just `string`,
[`UseStatus` decorator](./express-middlewares/README.MD#response-status) narrows its input to a union of status codes instead of just `number`._#### With documentation at hand
Every exposed API is fully documented, with examples and even links to the original library documentation, so you're never alone in the dark of your editor theme. โ๏ธ
### Built-in flexibility
Most decorator frameworks are great for the simple stuff, but inevitably get in your way later down the road. ๐
Reflet does its best to avoid this by staying simple and to the point, **composable**, and by eating its own dog food: common decorators are built with lower-level tools, that are also provided to you. ๐
_e.g. exposed Express [parameter decorators](./express/README.MD#request-properties-injection) are created by the same `createParamDecorator` method that is provided to you._
#### With progressive features
This design allows for easy extension and plugins. ๐งฉ
In this regard, Reflet generally provides a core module with all the basic decorators to do everything, and **add-ons** for extra convenient features._e.g. [Reflet/express-middlewares](./express-middlewares) provides middleware decorators to handle authorization (`UseGuards`), response mapping (`UseInterceptor`), to complete the features of [Reflet/express](./express)._
### Self-control
NPM ecosystem got a bad rep by encouraging intricate third-party dependencies for the sake of DRY principle.
Time has come for a smarter dependency diet. ๐ณ![no dependencies](https://img.shields.io/badge/dependencies-none-brightgreen)
Reflet modules fully **own** their codebase. No direct third-party dependencies, only peer ones.
_e.g. [Reflet/express](./express) only asks for the necessary **peer** dependencies: `express`, `@types/express`, `@reflet/http`._
### Integration-tested
Reflet uses extensive integration testing, to make sure its decorators work with the underlying library.
_e.g. [Reflet/express](./express) is tested with HTTP requests, [Reflet/mongoose](./mongoose) is tested with mongoose queries and an in-memory mongo._
### Readable `source code`
Careful abstractions `&&` clear-cut modules `&&` commented/documented code `&&` small number of files/folders `===` reduced indirection and complexity. ๐งต
[Have a look](./express/src) and compare with similar frameworks. ๐งถ