Installations
npm install @overnightjs/core
Developer Guide
Typescript
No
Module System
CommonJS
Node Version
14.15.1
NPM Version
7.12.1
Score
81.2
Supply Chain
96.1
Quality
73.6
Maintenance
100
Vulnerability
100
License
Releases
Unable to fetch releases
Contributors
Unable to fetch Contributors
Languages
TypeScript (100%)
Developer
seanpmaxwell
Download Statistics
Total Downloads
1,355,290
Last Day
650
Last Week
3,320
Last Month
17,220
Last Year
237,012
GitHub Statistics
876 Stars
359 Commits
40 Forks
16 Watching
26 Branches
9 Contributors
Bundle Size
609.81 kB
Minified
239.34 kB
Minified + Gzipped
Package Meta Information
Latest Version
1.7.6
Package Id
@overnightjs/core@1.7.6
Unpacked Size
94.95 kB
Size
15.27 kB
File Count
39
NPM Version
7.12.1
Node Version
14.15.1
Total Downloads
Cumulative downloads
Total Downloads
1,355,290
Last day
-26.1%
650
Compared to previous day
Last week
-30.5%
3,320
Compared to previous week
Last month
9.9%
17,220
Compared to previous month
Last year
-24.6%
237,012
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
OvernightJS
:warning: OvernightJS/logger and OvernightJS/jwt are deprecated. For logging please see jet-logger.
TypeScript decorators for the ExpressJS Web Server!
What is it
OvernightJS is a simple library to add TypeScript decorators for methods meant to call Express routes. It also includes a package for managing json-web-tokens and printing logs.
Features
- Define a base route using a @Controller decorator.
- Decorators to convert class methods to Express routes (@Get, @Put, @Post, @Delete etc).
- Method decorators also work with arrow functions set as class properties.
- @Middleware and @ClassMiddleware decorators.
- @ErrorMiddleware and @ErrorMiddleware decorators to handle request errors.
- Add options to controllers the same as you would Express routers with @ClassOptions.
- Support for child-controllers with @ChildControllers.
- @Wrapper and @ClassWrapper decorators to wrap functions.
- Server superclass to initialize ExpressJS server and setup controllers.
- Allows for adding your own custom Router classes if you don't want to use the standard express Router.
- Easy to configure logging tool.
- Json-Web-Token management.
- Master repo includes a sample application, if you want to practice with an API calling tool such as Postman.
- Compatible with both es5 and es6.
- Fully type safe :)
Why OvernightJS
OvernightJS isn't meant to be a replacement for Express. If you're already somewhat familiar with ExpressJS, you can learn Overnight in about 10 minutes. There are some other frameworks which do add decorators for Express such as NestJS and TsExpressDecorators, but these are massive frameworks with entire websites dedicated to their documentation. OvernightJS is clean, simple, and aside from the decorators, you can interact with ExpressJS in the same way you would any other Node application.
Installation
You can get the latest release using npm:
1$ npm install --save @overnightjs/core express 2$ npm install --save-dev @types/express
Important! OvernightJS requires Node >= 6, Express >= 4, TypeScript >= 2.0 and the
experimentalDecorators
,lib
compilation options in yourtsconfig.json
file.
Quick start
Create your controller
1import { OK, BAD_REQUEST } from 'http-status-codes'; 2import { Controller, Middleware, Get, Post, Put, Delete } from '@overnightjs/core'; 3import { Request, Response } from 'express'; 4import Logger from 'jet-logger'; 5 6@Controller('api/users') 7export class UserController { 8 9 @Get(':id') 10 private get(req: Request, res: Response) { 11 Logger.Info(req.params.id); 12 return res.status(OK).json({ 13 message: 'get_called', 14 }); 15 } 16 17 @Get('') 18 @Middleware([middleware1, middleware2]) 19 private getAll(req: ISecureRequest, res: Response) { 20 Logger.Info(req.payload, true); 21 return res.status(OK).json({ 22 message: 'get_all_called', 23 }); 24 } 25 26 @Post() 27 private add(req: Request, res: Response) { 28 Logger.Info(req.body, true); 29 return res.status(OK).json({ 30 message: 'add_called', 31 }); 32 } 33 34 @Put('update-user') 35 private update(req: Request, res: Response) { 36 Logger.Info(req.body); 37 return res.status(OK).json({ 38 message: 'update_called', 39 }); 40 } 41 42 @Delete('delete/:id') 43 private delete(req: Request, res: Response) { 44 Logger.Info(req.params, true); 45 return res.status(OK).json({ 46 message: 'delete_called', 47 }); 48 } 49 50 @Get(/ane/) // Rexes supported. Matches /lane, /cane, etc. 51 public getAne(req: Request, res: Response): any { 52 return res.status(OK).json({ 53 message: '/ane/', 54 }); 55 } 56 57 @Get('practice/async') 58 private async getWithAsync(req: Request, res: Response) { 59 try { 60 const asyncMsg = await this.asyncMethod(req); 61 return res.status(OK).json({ 62 message: asyncMsg, 63 }); 64 } catch (err) { 65 Logger.Err(err, true); 66 return res.status(BAD_REQUEST).json({ 67 error: err.message, 68 }); 69 } 70 } 71 72 private asyncMethod(req: Request): Promise<string> { 73 return new Promise((resolve) => { 74 resolve(req.originalUrl + ' called'); 75 }); 76 } 77}
- You don't have to use class methods, you can also use class properties whose value is an arrow function. You will have to cast Overnight to the 'any' type to avoid type errors though.
1import * as OvernightJS from '@overnightjs/core'; 2 3 ... 4 5 @(OvernightJS as any).Get('arrow/:id') 6 private get = (req: Request, res: Response) => { 7 this.logger.info(req.params.id); 8 return res.status(200).json({msg: 'get_arrow_called'}); 9 }
- If you want your middleware to apply to every route in a class use the
@ClassMiddleware
decorator.
1import { Controller, ClassMiddleware } from '@overnightjs/core'; 2 3@Controller('api/users') 4@ClassMiddleware([middleware1, middleware2]) 5export class UserController { 6 7 ... 8}
- You can set the
@ErrorMiddleware
/@ClassErrorMiddleware
decorators to use Express error handling.
1import { Controller, ErrorMiddleware, ClassErrorMiddleware } from '@overnightjs/core'; 2 3@Controller('api/users') 4@ClassErrorMiddleware(errorMiddleware1) 5export class UserController { 6 7 @Get(':id') 8 @ErrorMiddleware(errorMiddleware2) 9 private get(req: Request, res: Response) 10 ... 11}
- Child-controllers can be added with the
@ChildControllers
decorator. There's no limit to how many levels of nesting you can add. Make sure to instantiate them before adding them. Options at the class level can be added with@ClassOptions
decorator.
1import { Controller, ClassOptions, ChildControllers } from '@overnightjs/core'; 2import { ChildController1, ChildController2 } from '...' 3 4@Controller('api/users') 5@ClassOptions({mergeParams: true}) 6@ChildControllers([ 7 new ChildController1(), 8 new ChildController2(), 9]) 10export class ParentController { 11 12 ... 13}
- You can wrap each class method in a custom function with the
@Wrapper
decorator. If you use the@ClassWrapper
decorator then every method in that class will be wrapped with the provided method.
1import * as expressAsyncHandler from 'express-async-handler'; 2import { ClassWrapper, Controller, Get, Wrapper } from '@overnightjs/core'; 3import { Request, Response } from 'express'; 4 5@Controller('wrapper-practice') 6// Or instead of using @Wrapper below you could use @ClassWrapper here 7export class WrapperController { 8 9 @Get('async-third-party/:id') 10 @Wrapper(expressAsyncHandler) 11 private async asyncThirdParty(req: Request, res: Response) { 12 const asyncMsg = await someAsyncFunction(); 13 return res.status(200).json({ 14 message: asyncMsg, 15 }); 16 } 17}
Import your controllers into the server
OvernightJS provides a Server superclass which initializes a new ExpressJS application. The express
object is accessed using this.app
, which is a protected, readonly class variable. You can interact
with this variable like you would any normal express Application created with require('express')()
.
If you want to print to the console the name of each controller that has been successfully configured,
set showLogs
to true
via the this.showLogs
setter or the Server constructor()
.
super.addControllers()
must be called to enable all of the routes in your controller. Make sure to
call it after setting up your middleware. You can pass super.addControllers()
a single controller-instance
or an array of controller-instances, but they must be instantiated first.
1import * as bodyParser from 'body-parser'; 2import { Server } from '@overnightjs/core'; 3import Logger from 'jet-logger'; 4import { UserController } from './UserController'; 5import { SignupController } from './SignupController'; 6 7export class SampleServer extends Server { 8 9 constructor() { 10 super(process.env.NODE_ENV === 'development'); // setting showLogs to true 11 this.app.use(bodyParser.json()); 12 this.app.use(bodyParser.urlencoded({extended: true})); 13 this.setupControllers(); 14 } 15 16 private setupControllers(): void { 17 const userController = new UserController(); 18 const signupController = new SignupController(); 19 const dbConnObj = new SomeDbConnClass('credentials'); 20 signupController.setDbConn(dbConnObj); 21 userController.setDbConn(dbConnObj); 22 // super.addControllers() must be called, and can be passed a single controller or an array of 23 // controllers. Optional router object can also be passed as second argument. 24 super.addControllers( 25 [userController, signupController], 26 /*, optional router here*/, 27 /* middleware that will apply to all controllers here */, 28 ); 29 } 30 31 public start(port: number): void { 32 this.app.listen(port, () => { 33 Logger.Imp('Server listening on port: ' + port); 34 }) 35 } 36}
IMPORTANT NOTE: If you initialize environment variables from some script which imports the Server script, those environment variables must be configured before importing the Server script or else they could end up undefined for nested controllers.
See how awesome this is!
Without the above decorators we would have to wrap each controller method with something like:
1/* In the controller file*/ 2class UserController { 3 4 public getRoutes(): Router { 5 const router = Router(); 6 router.get('/', [your middleware], (req, res) => { 7 // Do some stuff in here 8 }); 9 router.get('/anotherRoute', [other middleware], (req, res) => { 10 // Do some stuff in here 11 }); 12 // Repeat for every single controller method 13 return router; 14 } 15} 16 17let userController = new UserController(); 18this.app.use('/api/users', userController.getRoutes()); 19// Repeat for every single controller class
This would get really tedious overtime and lead to a lot of boiler plate code.
Using a Custom Router
Suppose you don't want to use the built in "Router" object which is provided by Express. Maybe you
want use express-promise-router because you don't like using try/catch
blocks. OvernightJS allows
you to pass in a custom router object in the super.addControllers()
method. Simply pass in your
custom router as the second param after the controller-instance/s. When you don't specify a custom
router, the default express.Router() object is used.
- Controller using express-promise-router:
1import { Request, Response } from 'express'; 2import { Controller, Get } from '@overnightjs/core'; 3 4@Controller('api/posts') 5export class PostController { 6 7 @Get(':id') 8 private get(req: Request, res: Response) { 9 return this.someAsyncFunction(req.params.id) 10 .then(ret => res.status(200).json({msg: ret})); 11 } 12 13 private someAsyncFunction(id: number): Promise<string> { 14 return new Promise((res, rej) => { 15 isNaN(id) ? rej('Invalid id') : res('Valid id'); 16 }) 17 } 18}
- Add express-promise-router in the
super.addControllers()
method:
1import * as customRouter from 'express-promise-router'; 2import { Server } from '@overnightjs/core'; 3import { PostController } from './controllers/PostController'; 4 5export class CustomRouterServer extends Server { 6 7 constructor() { 8 super(); 9 super.addControllers(new PostController(), customRouter); // <-- custom router added here 10 } 11 12 ... 13}
That's All!!
Please star this repo if you found it useful. Happy web-deving :)
License
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
Found 3/13 approved changesets -- score normalized to 2
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 20 are checked with a SAST tool
Reason
38 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7
- Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x
- Warn: Project is vulnerable to: GHSA-phwq-j96m-2c2q
- Warn: Project is vulnerable to: GHSA-ghr5-ch3p-vcr6
- Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc
- Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx
- Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h
- Warn: Project is vulnerable to: GHSA-8cf7-32gw-wr33
- Warn: Project is vulnerable to: GHSA-hjrf-2m68-5959
- Warn: Project is vulnerable to: GHSA-qwph-4952-7xr6
- Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw
- Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3
- Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h
- Warn: Project is vulnerable to: GHSA-48ww-j4fc-435p
- Warn: Project is vulnerable to: GHSA-hwqf-gcqm-7353
- Warn: Project is vulnerable to: GHSA-9h6g-pr28-7cqp
- Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9
- Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j
- Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w
- Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg
- Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p
- Warn: Project is vulnerable to: GHSA-qgmg-gppg-76g5
- Warn: Project is vulnerable to: GHSA-xx4c-jj58-r7x6
- Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92
- Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw
- Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c
- Warn: Project is vulnerable to: GHSA-2j2x-2gpw-g8fm
- Warn: Project is vulnerable to: GHSA-4q6p-r6v2-jvc5
- Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6
- Warn: Project is vulnerable to: GHSA-896r-f27r-55mw
- Warn: Project is vulnerable to: GHSA-g6ww-v8xp-vmwg
- Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
Score
2
/10
Last Scanned on 2025-01-27
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More