{"id":15019932,"url":"https://github.com/jeremyben/reflet","last_synced_at":"2025-10-24T20:30:52.216Z","repository":{"id":46001117,"uuid":"194169202","full_name":"jeremyben/reflet","owner":"jeremyben","description":"Well-defined 💍 decorators for Node.","archived":false,"fork":false,"pushed_at":"2024-03-19T21:24:14.000Z","size":2847,"stargazers_count":20,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-31T03:55:14.820Z","etag":null,"topics":["cron","decorator-framework","decorators","express","kiss","mongoose","node","nodejs","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jeremyben.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-27T22:08:06.000Z","updated_at":"2024-10-02T19:18:10.000Z","dependencies_parsed_at":"2024-10-10T10:40:59.394Z","dependency_job_id":"51e5cfd6-4f2c-4dde-a590-30da5ab419c7","html_url":"https://github.com/jeremyben/reflet","commit_stats":{"total_commits":450,"total_committers":2,"mean_commits":225.0,"dds":"0.028888888888888853","last_synced_commit":"3d927dbe9d74ddf55998c7c5acf37039b1c512ed"},"previous_names":[],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeremyben%2Freflet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeremyben%2Freflet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeremyben%2Freflet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeremyben%2Freflet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeremyben","download_url":"https://codeload.github.com/jeremyben/reflet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238030288,"owners_count":19404859,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cron","decorator-framework","decorators","express","kiss","mongoose","node","nodejs","typescript"],"created_at":"2024-09-24T19:54:20.154Z","updated_at":"2025-10-24T20:30:46.775Z","avatar_url":"https://github.com/jeremyben.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eReflet 💫\u003c/h1\u003e\n\nReflet is a suite of modules made of well-typed [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html).\u003cbr\u003e\nReflet is simple and flexible. It will help you organize your app, without the pitfall of verbosity.\u003cbr\u003e\n\u003csub\u003eBut most importantly, Reflet is french for reflection (pronounce _ruh flay_ 🐔).\u003c/sub\u003e\n\n## [Reflet/express](./express)\n\nOrganize your [Express](https://expressjs.com/) application.\u003cbr\u003e**[Documentation](./express/README.MD)**.\n\n```ts\n@Use(isAuthenticated)\n@Router('/things')\nclass ThingRouter {\n\n  @Get('/:id')\n  async get(@Params('id') id: string, @Res res: Response) {\n    const thing = await db.collection('things').find({ id })\n    res.status(200).send(thing)\n  }\n\n  @Send({ status: 201 })\n  @UseGuards((req) =\u003e canCreateThing(req.user))\n  @Post()\n  async create(@Body('item') item: string) {\n    const newThing = await db.collection('things').insertOne({ item })\n    return newThing\n```\n\n_Add-on: [Reflet/express-middlewares](./express-middlewares)_\n\n## [Reflet/mongoose](./mongoose)\n\nDeclare your [Mongoose](https://mongoosejs.com/) models in a more concise way.\u003cbr\u003e**[Documentation](./mongoose/README.MD)**.\n\n```ts\n@Model()\n@SchemaOptions({ autoIndex: false })\nclass User extends Model.I {\n  static findByEmail(email) {\n    return this.findOne({ email });\n  }\n\n  @Field({ type: String, required: true })\n  email: string\n\n  @Field(String)\n  name: string\n}\n\nconst user = new User({ email: 'jeremy@example.com', name: 'Jeremy' })\nawait user.save()\n```\n\n## [Reflet/http](./http)\n\nTyped HTTP primitives to use within any framework.\u003cbr\u003e**[Documentation](./http/README.md)**.\n\n```ts\n@Router('/things')\nclass ThingRouter {\n  @UseStatus(Status.Created)\n  @Post()\n  async create(@Headers(RequestHeader.Authorization) auth: string) {\n    if (!auth) {\n      throw HttpError.Unauthorized('Stop right there')\n    }\n  }\n}\n```\n\n## Philosophy 📣\n\nWhy another decorator framework ? Simply \u003csub\u003e(and biasedly)\u003c/sub\u003e put, a better developer experience.\n\n### Simple and intuitive\n\nReflet modules aim to stay close to the technology's underlying abstractions they decorate, \u003cbr\u003eso you **don't have to learn** a whole new terminology to be productive. 🏌️‍\n\n_e.g. [Reflet/express](./express) has decorators like `Use` for `app.use` method, `Router` for `express.Router`, `Send` for `res.send`.\u003cbr\u003eIf you're familiar with Express, you're gonna love its Reflet decorators._\n\nAs 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 :\n\n* more detached, less familiar abstractions. 🤔\n* less accurate static typing (conditional types to aknowledge differences). 🤥\n* hence, more error prone code (from my part and yours). 😠\n\nInstead, Reflet hopes to provide a well-defined and well-typed module for each libraries.\n\n#### With accurate types\n\nReflet takes full advantage of TypeScript by **narrowing** its type signatures, to prevent as much mistakes as possible. 🎯\n\n_e.g. [`Headers` decorator](./express/README.MD#request-headers) narrows its input to a union of request headers instead of just `string`, \u003cbr\u003e[`UseStatus` decorator](./express-middlewares/README.MD#response-status) narrows its input to a union of status codes instead of just `number`._\n\n#### With documentation at hand\n\nEvery 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. ☀️\n\n### Built-in flexibility\n\nMost decorator frameworks are great for the simple stuff, but inevitably get in your way later down the road. 🎠\n\nReflet 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. 🐎\n\n_e.g. exposed Express [parameter decorators](./express/README.MD#request-properties-injection) are created by the same `createParamDecorator` method that is provided to you._\n\n#### With progressive features\n\nThis design allows for easy extension and plugins. 🧩\u003cbr\u003eIn this regard, Reflet generally provides a core module with all the basic decorators to do everything, and **add-ons** for extra convenient features.\n\n_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)._\n\n### Self-control\n\nNPM ecosystem got a bad rep by encouraging intricate third-party dependencies for the sake of DRY principle. \u003cbr\u003eTime has come for a smarter dependency diet. 🍳\n\n![no dependencies](https://img.shields.io/badge/dependencies-none-brightgreen)\n\nReflet modules fully **own** their codebase. No direct third-party dependencies, only peer ones.\n\n_e.g. [Reflet/express](./express) only asks for the necessary **peer** dependencies: `express`, `@types/express`, `@reflet/http`._\n\n### Integration-tested\n\nReflet uses extensive integration testing, to make sure its decorators work with the underlying library.\n\n_e.g. [Reflet/express](./express) is tested with HTTP requests, [Reflet/mongoose](./mongoose) is tested with mongoose queries and an in-memory mongo._\n\n### Readable `source code`\n\nCareful abstractions `\u0026\u0026` clear-cut modules `\u0026\u0026` commented/documented code `\u0026\u0026` small number of files/folders `===` reduced indirection and complexity. 🧵\n\n[Have a look](./express/src) and compare with similar frameworks. 🧶\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeremyben%2Freflet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeremyben%2Freflet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeremyben%2Freflet/lists"}