Giter Site home page Giter Site logo

overnight's People

Contributors

afusensi avatar alexy4744 avatar anandchowdhary avatar dependabot[bot] avatar polly3223 avatar seanpmaxwell avatar sweko avatar ydhn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

overnight's Issues

typescript not processing the start.ts file

I am working my through the "Setup Express with TypeScript in 3 Easy Steps" from April 15.
When I do
npm run start:express
the app crashes because the build/start.js is not there.
I suppose the ts processing has not occurred. I have followed from instructions precisely.
I am running on Mac OS with node 10.5.0.
See the console output below.

Bob

console output:

[email protected] start:express /Users/robertabarbanel/Documents/tsproject
nodemon --config "./util/nodemon.json"/

[nodemon] 1.19.0
[nodemon] to restart at any time, enter rs
[nodemon] watching: .
[nodemon] starting node build/start.js
internal/modules/cjs/loader.js:596
throw err;
^

Error: Cannot find module '/Users/robertabarbanel/Documents/tsproject/build/start.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:594:15)
at Function.Module._load (internal/modules/cjs/loader.js:520:25)
at Function.Module.runMain (internal/modules/cjs/loader.js:744:10)
at startup (internal/bootstrap/node.js:240:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:564:3)

Global response function

I'm trying to implement something where I can just return the object instead of using res.json, and would love to hear your thoughts on how it might be done.

For example, instead of this:

@Controller('api/users')
export class UserController {
    @Get(':id')
    private get(req: Request, res: Response) {
        return res.status(OK).json({
            message: 'get_called',
        });
    }
}

I can write this:

@Controller('api/users')
export class UserController {
    @Get(':id')
    private get(req: Request, res: Response) {
        return {
            message: 'get_called',
        };
    }
}

And perhaps have a global response function somewhere:

this.app.onResponse = (returned: any, req: Request, res: Response) => {
  res.json(returned);
};

Firebase functions implementation

Hi Sean,

I want to start off by saying again how much I love this project and the simplicity of it, it just makes working on API's so much easier, structured, predictable and consistent.

Now, for multiple reasons, I decided to stop building these live server apps and switched completely to the functions-based approach, more specifically firebase. Now coding these functions, even though it supports typescript out of the box, is a complete pain. There's no decent support for middleware, wrapping functions, it is indeed possible to manually add middleware and use some express features but that isn't a thing for callable functions.

Now I'd like to start working on something similar to overnightjs but for functions, at first, for firebase functions specifically.

The baseline concept is you'd have your controllers + child controllers and your basic decorators are @OnRequest and @OnCall in every class. The basic features to support would be middleware + wrappers for @OnRequest(<NAME>) and just wrappers for @OnCall(<NAME>).

Now because these would be functions operating independently from each other, we'd also want to have some decorator for things to be initialized only for the function, for example, a mongoose db connection, which you wouldn't necessarily want to configure globally for all your stuff, maybe this could be solved with the standard @wrapper?

In index.ts you'd configure your global middleware + global async wrappers for '@oncall and '@OnRequest;

Now for the end result, let's assume we have a controller called 'Reports' which has a child controller called 'Jobs' which has a function called 'daily'; Your end function name would be a camelCase of that tree, such as: reportsJobsDaily;

I was thinking instead of just making my own thing, I'd suggest we build it together as part of the @overnight project?

Let me know what you think, thanks.

Add controller prefix option

Would be cool if we could have a global prefix added to all controllers, like this:

this.app.setPrefix("v1/");
super.addControllers([new UsersController()];

Then, the routes can be generated as /v1/users instead of /users, which can be used for versioning, or having a global /api prefix, etc.

Add possibility to wrap routes in try catch

OvernightJS can currently not handle errors happening in asynchronous function calls and will throw UnhandledPromiseRejectionWarning if the execution of this function is not wrapped in a try/catch block.

Having to wrap every controller method in a try catch is repetition and clutter for the code though, it could be a good idea to implement, or atleast find a way to support a typical 'handle async' wrapper function for controller methods.

Wrapping controller methods (or providing an option to wrap them) into something like this at router creation time would fix this issue.

Support for path aliases

Can we have support for multiple paths (aliased) which, perhaps something like this:

@Controller("user")
export class UserController {
  @Get("info", "example")
  get userInfo(req: Request, res: Response) {
    res.json({ user: "hello" });
  }
}

Using multiple attributes in the @Get() decorator, we can have aliased routes:

  • GET /user/info
  • GET /user/example

Both result in the userInfo() function being called.

[Question] Is there a way to use with express-validator?

Hi.

First of all, I must thank your work. To someone familiarized with Spring and Annotations, your express based lib looks awesome.

I have been trying to work with express-validator inside controllers but I'm not able. As middlewares, I use checks inside @Middleware annotation but, when I send an url request with empty body, any check is done and everytime OK response is sent. My piece of code looks like:

@Controller('vehicle/:vehicle_id/engine')
@ClassOptions({mergeParams: true})
export class VehicleEngineController {

    @Post()
    @Middleware([body('time').exists({checkNull: true}).withMessage('Time is required'), 
                body('registration').exists({checkNull: true}).withMessage('Registraton is required')])
    private async insertData(req: Request, res: Response) {
        return res.status(200).send(`Receive Data from Vehicle ${req.params.vehicle_id}`);
    }
}

Maybe, I'm missing or doing something wrong but I can't find a way. Is possible to work express-validator?? Could you guide me why?

Thanks.
Bye.

Environment:
Windows 10
NodeJS 10.16.0
OvernigthJS 1.6.9

cant handle single word route.

hello again sir. I really love your work. been using this on my side project. I just want to say thank you for everything.

Anyway I think I found a bug. so on this simple controller the Get() and Get(':id') is working as normal, but when I tried creating the Get('test') and Get('bar') I wont hit or get any response from that route. I have to this make an extension on the route name like bar/foo and test/tst something like that. You cant have a single word on a route? just wanted to let you know. thanks again and I support this. ❤️

im using the version: "@overnightjs/core": "1.6.11",

@Controller('users')
export class UsersController extends BaseController {

  @Get()
  private async getAllUsers(req: Request, res: Response) {
    try {
      res.json({
        users: await User.find()
      });
    } catch (error) {
      res.status(200).json({
        error
      });
    }
  }

  @Get(':id')
  private async getSingleUser(req: Request, res: Response) {
    const { id } = req.params;
    try {
      res.json({
        user: await User.findOneOrFail(id)
      });
    } catch (error) {
      res.json({
        errorMsg: error
      });
    }
  }

  @Get('test')
  @Middleware(JwtManager.middleware)
  private async test(req: ISecureRequest, res: Response) {
    console.log(req.payload)
    res.json({
      samp: 'asdf'
    })
  }

  @Get('bar')
  @Middleware(JwtManager.middleware)
  private async bar(req: ISecureRequest, res: Response) {
    console.log(req.payload)
    res.json({
      samp: 'asdf'
    })
  }

}

Class Middleware apply to all routes in all controllers with the same route prefix rather than all routes in that particular class

First of all, awesome works! Great module. Thank you.

I found this little issue in relating to middleware. Not sure wether it is by design or not. Could you help check.


Versions: ^1.6.9

Code Example:

1.Controller A - with route prefix /api/v1 attach to middlewareA



@Controller('api/v1/')
@ClassMiddleware([middleWareA])
export class ClassA {
    @Post('routeA1')
    private async a1(request: Request, response: Response) {
        return response.status(OK).json({})
    }

    @Post('routeA2')
    private async a2(request: Request, response: Response) {
        return response.status(OK).json({})
    }
}
  1. Controller B using the same prefix /api/v1 but has not assigned any middleware.
@Controller('api/v1/')
export class ClassB {
    @Post('routeB1')
    private async b1(request: Request, response: Response) {
        return response.status(OK).json({})
    }
}

Expected result:

middlewareA get invoke only in route in controller A

  • /api/v1/routeA1
  • /api/v1/routeA2

controller B /api/v1/routeB1 should get invoke directly without middlewareA

Actual result:

All route with prefix /api/v1/ got invoke with middlewareA

Class constructor X cannot be invoked without 'new'

Hey! I'm interested in trying out Overnight in a project, but I'm having trouble using it in a project that targets ES6/2015. When I create a controller class and use the @Controller("x/y/z") decorator, ts-node throws an error saying that Class constructor ClassName cannot be invoked without 'new'. If I remove the @Controller decorator the app will start up fine (but then, obviously, I lose the controller route).

After some digging around, I think this is happening because my project is targeting ES6, but Overnight is targeting ES5, and TypeScript can't extend an ES5 class. Once I switch my target to ES5 with the full es2015 lib everything starts to work again. I just wanted to check and confirm if this is intended, or if I'm goofing up somewhere.

Params not available when in controller

In this case:

@Controller(":id/about")
export class UserController {
  @Get()
  about(req: Request, res: Response) {
    console.log(req.params.id); // undefined
    res.json({ hello: "world" });
  }
}

req.params.id doesn't exist, because it's not defined in @Get() but in @Controller.

Is this intentional, or a bug with Express.js or with Overnight?

'Server' no longer exported

After upgrading from v1.7.3 of @overnightjs/core.

My TypeScript import statement:

import { Server } from '@overnightjs/core';

gives the error:

Module '"../node_modules/@overnightjs/core/lib"' has no exported member 'Server'.ts(2305)

Tracing this back to @overnightjs/core/lib/index.d.ts the error is:

Could not find a declaration file for module './Server'. '../node_modules/@overnightjs/core/lib/Server.js' implicitly has an 'any' type.ts(7016)

Downgrading to v1.7.2 fixes the issue.

@overnightjs/core: 1.7.3
typescript: ~3.8.3

Make decorators work with arrow functions as well as methods

Hey! I'm having trouble getting the Overnight path decorators to work with arrow functions (class properties) on a controller class. It works just fine with regular functions, but if we turn them into arrow functions it stops working, even though they still have the exact same signature. There are a couple reasons I want to do this, chiefly so I can easily use my own types for the request and response objects (mostly to get intellisense on req.app.locals); but also it helps with this binding in some corner cases.

Here's an example of what I'm trying to do:

type CustomRequestHandler = (req: CustomRequest, res: CustomResponse) => Promise<void>;

@Overnight.Controller("/something")
export class SomethingController {
    @Overnight.Get("example/1")
    async exampleOne(req: Express.Request, res: Express.Response) {
        // This works
    }

    @Overnight.Get("example/2")
    async exampleTwo(req: CustomRequest, res: CustomResponse) {
        // Also works
    }

    @Overnight.Get("example/3")
    exampleThree: CustomRequestHandler = async (req, res) => {
        // This is what I'm trying to do, but it does not work.
        // Unable to resolve signature of property decorator when called as an expression.
    }

    @Overnight.Get("example/4")
    exampleFour: (req: CustomRequest, res: CustomResponse) => Promise<void> = async (req, res) => {
    // Also does not work
    }
}

If I try to use arrow functions, TypeScript gives an error saying Unable to resolve signature of property decorator when called as an expression. I'm not super familiar with decorators yet, but I assume this error happens because @Overnight.Get is a method decorator, but arrow functions are considered properties. Would it be difficult to get the decorators work with both class methods and class properties?

Support for HTTP PATCH

Currently, only the following HTTP verbs are available to import from @overnightjs/core:

  • GET
  • POST
  • DELETE
  • PUT

PATCH should be added as well.

AddControllers not working

I use "overnightjs" on my app structure, but controllers that create the routes not work, only on a specific computer, all routes give me 'Error Cannot GET /MyRoute', I have another computer where works fine literarly run the same code, is some a incompatibility?

Computer with Error:
node: 12.16.3
typescript: 3.8.3
express: 4.17.1

base url pathname

Hello. I really like what you did here. so simple, easy to understand. Question though. I have controllers that has a basepath of api/v1 is there a way to add this into the setup of controllers on the server class rather than each controller? thank you.

Question: Do you plan supporting Swagger/OpenAPI?

Hello,

Firstly, I'd like to 👏 at you for building this library. I've been looking for a nice library to allow me to decorate express middleware without putting much effort into it. This library is just that.

Secondly, I'd like to ask, is there any plans on supporting OpenAPI/Swagger generation? As a backend developer, I'm asked to provide this documentation frequently and sometimes keeping it up to date with the ever-changing requirements can be daunting. I'd love to be able to use this tool to help me out with that.

What are your thoughts?

Feature Request: Middleware decorator on Server

Is it possible to declare once that you want the middleware to apply to every route you make on a server, not just a controller?

If it is possible, could you let me know what I missed, and if not, consider this a feature request that I may very well be able to make a PR for, just wanted to check in first.

Custom Middleware Implementation

Hey Sean, first of all thanks for this framework. I use it in a few of my API projects so far and it awesome! It's not really an issue, but more of a question.

I'm still struggling to get my head around how to implement custom Middleware using the decorator. For example, i can write this simple express app level middleware;

auth.middleware.js

import { Request , Response, NextFunction } from 'express'

export class AuthMiddleware {

  constructor() {
    console.log('AuthMiddleware')
  }

  public verifyAuth(req:Request, res:Response, next:NextFunction) {
    console.log('verifyAuth')
    // do stuff to verify the user should be able to access this route
    // could be JWT token auth, could be ACL database lookups, could be IP validation etc..
    next()
  }
}

And call it in the server constructor at an app level;

...

class ExampleServer extends Server {

  private authMiddleware = new AuthMiddleware()

  constructor() {
      super(true);
      this.app.use(bodyParser.json({limit: '50mb'}));
      this.app.use(bodyParser.urlencoded({extended: true}));
      this.app.use(this.authMiddleware.verifyAuth) // Here is the middleware
      this.setupControllers();
  }
}
...

Which works fine, but ideally i would be able to do something similar using the @Middleware decorator from within my API Controller file so i can decide which routes are effected;

...
@Controller('api/v1/generate')
export class MyController {

  private authMiddleware = new AuthMiddleware()

  constructor() { }

  @Get('middleware-test')
  @Middleware(authMiddleware.verifyAuth)
  protected test(req: Request, res: Response, next:NextFunction) {
    return res.status(200).json({
      message: 'OK'
    })
  }
}
...

Of course this doesn't work because the Middleware decorator is expecting the type RequestHandler to be returned. I'm not exactly sure whether what I'm trying to do is possible or practical or if there's a better way to do it. I've tried looking at how you implemented the JwtHandler to see if i can replicate that with my own middleware but to no success.

Any thoughts appreciated.

Examples with passport

Cool work on this, looking forward to messing about with it, I see there is support built in for using JWT is it almost the same approach when using passport for authentication. Would it just be passed into the method via the @Middleware decorator.

Would be nice to see some more examples with middleware for auth, maybe some mongodb integrations?

Feature request: Middleware decorator on class

I would like to be able to apply the same middleware to all routes on a router instance, rather than have to specify the same middleware annotation on each route. In traditional Express applications this would be a router.use(middleware); statement.

Unless I've missed a way to do this, could this be achieved by allowing the Middleware annotation on the controller class?

Overnight is an excellent library and truly a pleasure to use, thank you!

Erro build tsc

{
"extends": "../tsconfig",
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"removeComments": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"baseUrl": "./",
},
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2015",
"dom"
],
"include": ["./"],
"exclude": ["./node_modules", "**/*.test.ts"]
}

server/node_modules/@overnightjs/core/lib/Server.d.ts:9:19 - error TS1086: An accessor cannot be declared in an ambient context.

9 protected get app(): Application;
~~~

server/node_modules/@overnightjs/core/lib/Server.d.ts:10:19 - error TS1086: An accessor cannot be declared in an ambient context.

10 protected get showLogs(): boolean;
~~~~~~~~

server/node_modules/@overnightjs/core/lib/Server.d.ts:11:19 - error TS1086: An accessor cannot be declared in an ambient context.

11 protected set showLogs(showLogs: boolean);
~~~~~~~~

Found 3 errors.

Regex Support in Method Annotations

The following works in Express:

// Matches /snake
// Matches /ssnake
// Matches /sssnake
app.use(/\/s+nake/, (req, res) => {
    res.send('A slithery snake.')
});

It would be great if this worked with Overnight:

@Get(/s+nake/)
public getSnake(req: Request, res: Response): any {
    return res.status(OK).json({
        message: 'A slithery snake.',
    });
}

req.payload not defined

When I use req.payload.user = ... in a Middleware, error displays "Cannot set property 'user' of undefined".


I found I not add expressjs jwt middleware to my route.

Can't Import ErrorMiddleware

I'm trying to import ErrorMiddleware but getting the following error -

Module '"../../node_modules/@overnightjs/core/lib"' has no exported member 'ErrorMiddleware'.ts(2305)

Middleware on Server without root controller

Is it possible to declare once that you want the middleware to apply to every route you make on a server, not just a controller? I don't have a root controller so the answer in #43 does not help in this case.

I'd be happy to contribute a PR for this if it doesn't exist yet.

Enable Merge Params on the Router

Description

Currently it's impossible to specify parameters at the controller-level.

Which would be useful for routes nested under other controllers.

ProviderController = /providers
ProviderController.get = /:provider_name

InstallationController = /providers/:provider_name/installation
InstallationController.post = /:id

Example

import { Request, Response } from 'express';
import { Controller, Get } from '@overnightjs/core';

@Controller('health/:test')
export class HealthRoute {

  @Get(':id')
  public async get(req: Request, res: Response): Promise<any> {
    // Actual
    // {
    //   "id": "some-other-value"
    // }

    // Expected
    // {
    //   "test": "some-value",
    //   "id": "some-other-value"
    // }
    return res.status(200).json(req.params);
  }
}

Workaround

import PromiseRouter from 'express-promise-router';
import { Server as OvernightServer } from '@overnightjs/core';
import { HealthRoute } from './routes/routes';

export class ExpressServer extends OvernightServer {
  private server: Server;

  public constructor() {
    super();

    // We're basically wrapping out Router and passing in the params we want ourselves.
    this.addControllers([new HealthRoute()], () => PromiseRouter({
      mergeParams: true
    }));
  }

  public listen(port: number): void {
    this.app.listen(port, () => {
      console.log(`Started server on port: ${port}`);
    });
  }
}

Testing

Hey @seanpmaxwell,

Awesome piece of code ya have here. We're using it in Production and it's all great. We're trying to figure out how to test the controllers/middlewares with Jest. Any good advice? So far the only way I can do it is make the method public and mock a request/response but that doesn't do any good for the Middleware decorator.

Let me know if I can help with a PR if you have any ideas.

Thanks,
Brandon.

Unable to access "this" inside controllers

I have a simple controller with the following code

import expressAsyncHandler from 'express-async-handler'
import { Controller, ClassErrorMiddleware, Post, Wrapper } from '@overnightjs/core'
import { Logger } from '@overnightjs/logger'
import { OK } from 'http-status-codes'
import { myAsyncAction } from './actions'
import { LogErrorAndStop } from '../middleware/error-handlers'

@Controller("api/auth")
@ClassErrorMiddleware(LogErrorAndStop)
export class AuthController {
    private thingINeedFromClass: string

   constructor() {
       this.thingINeedFromClass = "TEST"
   }

    @Post("sign-up")
    @Wrapper(expressAsyncHandler)
    private async signUp(req: Request, res: Response): Promise<void> {
        Logger.Info("Sign up called")
        Logger.Info(req.body, true)

        console.log(this) // <----

        await myAsyncAction(this.thingINeedFromClass)

       res.status(OK)
    }
}

When I log this it's undefined. If I try and call the same function in this class without the Class decorator, this is accessible as expected.

overnight version 1.7.2

Thanks !

Import class with path alias failed

Hi, first of all thanks for creating such awesome library. I'm in the middle of trying OvernightJS and having problem trying to import a class into my controller, got an error saying :
image

UserController :
image

CompanyModelClass :
image

tsconfig :
image

package.json :
image

Somehow when I changed the import to '../models/company' and it works. Also importing '@Models/firebase' works fine too.

I'm quite new to typescript, sry if this question isn't related to OvernightJS itself.

Thanks and appreciate a lot!

heres the public repo for the error

hello @seanpmaxwell heres the repo for my project that has a weird error if you want to check it out. I haven't done a guide on how to run this but you can just npm install and run npm run dev let know me what you think. thank you sir. you're a hero.

ES6+ targeting with overnight decorators

while node advances in versions - more of the language does not require transformation. i can't seem to get classes to work with es6 target and i don't want to change to es5 to fix it.
any suggestions ?

dev mode: ts-node with debugger

Loading the dotenv variables doesn't seem to work (probably doing it wrong?)

I'm trying to load my env variables with dotenv, -- just converting a working api project to Overnightjs;

However I keep getting a bunch of errors with clientID's missing and whatnot due to the dotenv file not being processed.

So far I've tried it:

  • At the start of the start.ts file
  • At the start of the public start() function inside the server class
  • after the super inside the server constructor

None of them have worked so far so I'm a bit confused where its supposed to go.

Thanks & great package, I think once I finish the transfer I'll never be able to go back to writing typescript+express without overnight. I've tried nest 2-3 times but gave up due to how many things needed to be changed/how complex it was. The cons have outweighed the pros but with overnight most things are quite straightforward and the benefits are plenty, especially at scale!

Parameter path isn't recognized when there is another path

Here is my controller

@Controller('api/authors/')
export class AuthorController {

    @Get(':id')
    async private get(req: Request, res: Response) {
       //Logic
    }

    @Get('random')
    async private get(req: Request, res: Response) {
       //Logic
    }

    @Get('')
    async private getAll(req: Request, res: Response) {
       //Logic
    }

}

The controller should work as follows:

  1. /api/authors/authorId, e.g. /api/authors/3 should return author with the specified id
  2. /api/authors should return all authors
  3. /api/authors/random should return a random author

When, in Postman, I make a request to either /api/authors or /api/authors/random it works fine. But when I try to make a request to /api/authors/3 it says:

Cannot GET /api/authors/3

However If I remove the code associated with @Get(random) it is back to normal, /api/authors/3 works fine again.

Global middleware for async handler

I'm trying to add the async handler (express-async-handler as a global middleware, but I'm unable to get it to work and would love some help.

Doing this works:

import asyncHandler from "express-async-handler";

@Controller("users")
@ClassMiddleware(asyncHandler)
export class UserController {}

But doing this doesn't work (because the types of the handler and required ParamsDictionary don't match (Argument of type '(handler: RequestHandler) => RequestHandler' is not assignable to parameter of type 'RequestHandler'):

super.addControllers([new UsersController()], undefined, asyncHandler);

But doing any of the following don't work either, but don't have the TS error:

super.addControllers([new UsersController()], undefined, () => asyncHandler());
super.addControllers([new UsersController()], undefined, (req, res, next) => asyncHandler(next));

When doing this, the error is "Argument of type 'Request<ParamsDictionary, any, any>' is not assignable to parameter of type 'RequestHandler'.":

super.addControllers([new UsersController()], undefined, req => asyncHandler(req));

I'm sure I'm just doing something silly...

Wrapper does not work when method has more than 3 parameters

I'm not sure if this is a bug or an unimplemented feature.

Version: 1.6.14

Clearly if @Wrapper(...) is not used on a method, then the method must be of type (req: Request, res: Response) => any to work. However, if @Wrapper(func) is defined, then the method method(...) really could be of any type, as long as func(method) is of type (req: Request, res: Response) => any.

Currently, if method(...) has up to three parameters, this works. However, if method(...) has more than three parameters, then the method returns null.

Consider the following:

@Controller('path')
export class BigWrapperController {

    @Get('3args')
    @Wrapper(returnAsMessage(1, 1, 1))
    sum3(num1: number, num2: number, num3: number): number {
        return num1 + num2 + num3;
    }

    @Get('4args')
    @Wrapper(returnAsMessage(1, 1, 1, 1))
    sum4(num1: number, num2: number, num3: number, num4: number): number {
        return num1 + num2 + num3 + num4;
    }

}

/**
 * Wrapper that passes its arguments to the method and then handles the
 * request with a 200 status code and the method's return value as a
 * message in the response body.
 * @param args Arguments to be passed to the method
 */
function returnAsMessage(...args: any) {
    return (method: Function): RequestHandler => {
        return (req: Request, res: Response): Response => {
            return res.status(200).json({
                message: method(...args)
            })
        }
    }
}

When calling the route /path/3args, the response is:

{
    message: 3
}

When calling the route /path/4args, the response is:

{
    message: null // Should be 4
}

Code to reproduce is linked here.

Working with passport js

Hi,

I'm looking to integrate passportjs with typescript and overnight js, but it don't work.
Please, do you have or can you do an example with typescript, overnight js and passport (google) integration ?

I'm lost.

Thanks

Would you want to implement dynamic routers via the Controllers?

Hey Sean, love the package so far. I found it from one of your blog posts, so keep writing!

I've been playing around with the package and one thing that caught my eye was the CustomRouter idea. I like the idea I just feel like since the Controller's implementation is based on which Router you end up using, adding the Router in the Server config blurs the single responsibility principle a bit.

I was thinking maybe you could add a second argument or even config object to the Controller decorator that accepts the Router and then either in the Server.addControllers method or the private Server._getRouter method you could just use the router attached to the Controller. This would allow more flexibility I think.

This is just a thought and I've only glanced over the src code, but if you think it's viable and useable I could submit a PR. Just let me know.

Thanks! And keep up the great work on this!

Question: TypeScript Configuration / getOwnMetadata() returns undefined

Hello,

I try to use this project for my next js-server application. I tried many things to got this to working but for whatever reason the metadata could not be readen.

As far as I understand the problem for me are the getRouter() implementation in the main Server.js file. Line 65 always returns undefined:

var classMetadata = Reflect.getOwnMetadata(types_1.classMetadataKey, prototype);

Maybe I messed up with the tsconfig. These are my current settings:

{
  "compilerOptions": {
    "target": "es6",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    "outDir": "./dist",                       /* Redirect output structure to the directory. */
    "baseUrl": "./",
    "importHelpers": true,                    /* Import emit helpers from 'tslib'. */
    "strict": true,                           /* Enable all strict type-checking options. */
    "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    "experimentalDecorators": true,           /* Enables experimental support for ES7 decorators. */
    "emitDecoratorMetadata": true,            /* Enables experimental support for emitting type metadata for decorators. */
    "skipLibCheck": true,                     /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true  /* Disallow inconsistently-cased references to the same file. */
  }
}

For the demo purpose I used the example UserController.ts provided by the example application.

TypeScript: 3.9.2
Node: v14.1.0
npm: 6.14.4
@overnightjs/core 1.7.0

The readme says something about the lib property but no more information are given there -_- Many thanks for your support in advance.

Dennis

Set prefix in all controllers

I have the same problem this issue #48.

Only I'm using inversify to inject the services into my controllers, so I can't use a parent controller.

ControllerExample.ts

import { Controller, Get, Middleware } from '@overnightjs/core'
import { injectable, inject } from 'inversify'

import TYPES from '@src/ioc/types'

import BannerService from './BannerService'

@injectable()
@Controller('banner')
class BannerController {
  private bannerService: BannerService

  constructor(@inject(TYPES.BannerService) bannerService: BannerService) {
    this.bannerService = bannerService
  }
}

export BannerController

Server.ts

import DIContainer from './ioc'
import TYPES from './ioc/types'
import BannerController from './modules/banner/BannerController'
...
const bannerController = DIContainer.get<BannerController>(TYPES.BannerController)
super.addControllers([bannerController])

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.