Giter Site home page Giter Site logo

nestjs / nest Goto Github PK

View Code? Open in Web Editor NEW
63.7K 742.0 7.3K 299.29 MB

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript ๐Ÿš€

Home Page: https://nestjs.com

License: MIT License

TypeScript 99.88% JavaScript 0.09% Shell 0.04%
nest javascript typescript nodejs framework nodejs-framework typescript-framework javascript-framework microservices websockets

nest's People

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  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

nest's Issues

Move rxjs to peerDependencies to allow custom versions usage

Error for client example from https://kamilmysliwiec.gitbooks.io/nest/content/real-time/microservices/basics.html

        this.client.send(pattern, data)
            .catch((err) => Observable.empty())
[ts] Property 'catch' does not exist on type 'Observable<{}>'.

this does not help

import { Observable } from 'rxjs';
import 'rxjs/add/operator/catch';

skipping via

(<any> this.client).send(pattern, data)

provides error at runtime

[Nest] 9905   - 5/10/2017, 3:44:13 AM   [ExceptionsHandler] this.client.send(...).catch is not a function
TypeError: this.client.send(...).catch is not a function

Multer and Nest

const upload = multer ({ dest: path})

I have: router.post('/uploadUserImage', upload.any(), api.uploadUserImage);

How i convert this in Nest ??

[Documentation] Incorrect method name in the middlewares example

In this page You're referencing a method name getUsers, unfortunately this method does not exist in the users service. Instead You should have used getAllUsers.

Again, I know it's just an example for demonstration purposes, but nevertheless it should work.

Another question: is there a way to contribute to the documentation? It can be a tedious task for you to do alone, I'll be happy to help in anyway!

Suggestion: CLI Tools

As per subject, a CLI tool can:

  • Make it easier for developers to start their new projects, with minimal entry barrier.
  • Help scaffolding new projects.
  • Help with building the project.
  • Setup a development server.
  • Might even help in deployment.

I can imagine that users of this project would have a background in angular (similar architecture, concepts, tooling) and those (me included!) use the angular CLI tool regularly.

So, in my humble opinion, a CLI tool should be the next logical step.

Testing component with Jest

Hello everyone ๐Ÿ˜ƒ

I was tried to testing my simple component with using Jest, but something was go wrong.

Configured Jest to working with TypeScript according to official example and tsconfig copied from Nest repo.

The simplest tested component:

import { Component } from 'nest.js';

@Component()
export class TestService {}

Test for the one:

import { TestService } from '../test.service';

it('should create instance', () => {
  const instance = new TestService();
})

Unfortunately result of run test is:

  โ— Test suite failed to run

    Cannot find module 'socket.io-client/package' from 'index.js'

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:169:17)
      at Object.<anonymous> (node_modules/socket.io/lib/index.js:10:21)

What am I doing wrong? Maybe someone has already tested Nest with Jest?

Cheers! ๐Ÿฅ‚

Hierarchical injector

Hi,
in order to make more reusable code, I would like to create a module which use a component which is not a part of this module, nor include in an imported module. The component will be inject by the ApplicationModule (main module). It seems that this is not supported?

Example:
AuthenticationModule has different controllers which use a UserService dependency.
UserModule also has different controllers which use a UserService dependency.

Depending on application, the UserService may be implemented in different way. What I want is defining this in the ApplicationModule for all modules, once for all.

@Module({
    modules: [ AuthenticationModule, UserModule ]
    components: [
        { provide: UserService, useClass: MyCustomUserService }
    ]
})
class ApplicationModule {}

@Module({
    controllers: [],
    components: [ AuthenticationService ],
    exports: [ 
        AuthenticationService
    ]
})
class AuthenticationModule {}

export class AuthenticationService {
    constructor(private userService: UserService) {}
}

I was expecting below code to work (similar to angular), but the userService dependency is not found.

How pass params to the Middleware?

Congratulations, it's a cool framework.

I'm need restrict access to route on role-based.
This works for me on express:

app.get('/dashboard', middleware.hasRole(['admin', 'creator', 'editor']), function(req,res){});

I have tried to implement a NestMiddleware, but I can not pass the parameters to it:

builder.use({
    middlewares: [ HasRole ],
    forRoutes: [{
    	path: 'dashboard', 
    	method: RequestMethod.ALL, 
    	data: { 'roles': ['admin', 'creator', 'editor'] } 
    }]
})

Here we can think of implementing guardians directly in the controller, inspired by the canActivate concept of Angular2:

{
  path: 'dashboard', 
  component: dashboardComponent, 
  canActivate: [ RoleGuard ], 
  data: { roles: [ 'admin', 'creator', 'editor' ] } 
}

Something like so:

@RequestMapping({ 
	path: '/dashboard', 
	method: RequestMethod.GET, 
	canActivate: [ HasRole ],
	data: { roles: [ 'admin', 'creator', 'editor' ] } 
})

@kamilmysliwiec What do you think is better, do you plan to implement something like this for the future?

Support for multiple simultaneous servers (e.g. HTTP and HTTPS)

The current implementation of NestApplication.listen() does not support easily adding multiple Server backends, since it directly calls .listen() on the Express Application (which only creates an HTTP server).

At the very least, it would be helpful to add a public method on NestApplication that calls the setup functions (setupMiddleswares, setupRoutes, etc.) without calling express.listen().

For anyone else having this issue, a workaround is below:

const expressInstance = express();

const app = NestFactory.create(ApplicationModule, expressInstance);

app.listen(80, () => {
    console.log("HTTP server listening on port 80");
});

let httpsOptions = {
    key: fs.readFileSync("./secrets/private-key.pem"),
    cert: fs.readFileSync("./secrets/public-certificate.pem")
};

const httpsServer = https.createServer(httpsOptions);
httpsServer.addListener("request", expressInstance);
httpsServer.listen(443, () => {
    console.log("HTTPS server listening on port 443");
});

Mixed web and microservice app

Can we have application type that is web app (handle http/websocket requests) and microservice (has tcp server that used by other microservices) at the same time? It's common;y used microservice type.

How to run the project

I've completed the tutorial. But I don't know how the hell run it. And I've been looking in the docs and I found nothing.

Problem with express typing

Following along with the Setup Application instructions, when I add express I get the error upon typescript compilation:
node_modules/nest.js/core/middlewares/interfaces/nest-middleware.interface.d.ts(1,1): error TS2688: Cannot find type definition file for 'express'.

I used npm install --save-dev @types/express to add the typing and now I get the error:
index.ts(1,8): error TS1192: Module '"C:/Users/Matt/dev/tests/nest-test/node_modules/@types/express/index"' has no default export.

tsc error

Hi @kamilmysliwiec ! Thanks for your framework, it looks very promising!

I just wanted to report this error with typescript typings. When I run tsc from the command line with the following tsconfig.json configuration I get the error below:

node_modules/nest.js/nest-factory.d.ts(10,63): error TS2304: Cannot find name 'NestApplication'.

{
    "compilerOptions": {
        "module": "commonjs",
        "declaration": false,
        "noImplicitAny": false,
        "removeComments": true,
        "noLib": false,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "target": "es6",
        "sourceMap": true,
        "allowJs": true,
        "outDir": "./dist"
    },
    "include": [
        "app/**/*"
    ],
    "exclude": [
        "node_modules",
        "**/*.spec.ts"
    ]
}

Roadmap

I would like to participate in collaborating on the project, I suggest that it is important to create a roadmap and an organization for them.

Built-in authentication

Hi, I'm loving nest framework! Great work!

I'd like to suggest this feature request. Not sure if it is in the plan but I think is something it provides extreme value for a higher level framework, since it is something basically all apps need. This would probably mean to adopt an ORM or make adapters for them.

A personal preference of a good framework that has this is FeathersJS, remaining very unopinionated and lean. Although it doesn't have the great TS support that nest has :)

Community question: Development environment

What is everyone using for their development environment? Has anyone successfully gotten interactive server-side debugging working with Nest or TypeScript-compiled tools?

WebSocket adapters

It would be great to extract the websocket functionality to use a proper adapter pattern.

Right now there's a stub of an adapter which just returns a socket.io instance.

Ideally:

  • Wrap any websocket functionality in an adapter
  • Call that in nest side code

This lets socket.io be potentially swapped out for alternatives, without breaking changes.

Suggestion: ORM integration

Many frameworks have a preferred ORM integrated out of the box (ASP.NET with Entity Framework, Laravel with Eloquent, Sails with Waterline). Perhaps Nest should consider doing this as well? TypeORM seems to be picking up steam and perhaps could be a candidate https://github.com/typeorm/typeorm.

Global route for all controllers

Hi,

is there any suggested way how to set a "global" route for all controllers?

For example, I want to define this route:
/api/

for my controllers:

@Controller('user')
export class UserController

@Controller('customer')
export class CustomerController

with the following result:

/api/user
/api/customer

Thank you

build error

Compiling the project results in
screen shot 2017-05-04 at 20 31 17
this error.

This seems to stem from the express_1.default(); line. Removing .default seems to resolve this issue.

Here's my tsconfig for reference
tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "",
    "module": "commonjs",
    "mapRoot": "./",
    "outDir": "../server-dist",
    "declaration": false,
    "noImplicitAny": false,
    "noLib": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": ["es2016"],
    "target": "es6",
    "sourceMap": true,
    "allowJs": true
  },
  "exclude": [
    "node_modules"
  ]
}

Question: Inject class by identifier for interfaces

Hi,

is it possible to configure the dependency injector that I can map a typescript interface to a specific class?

Example:

@Controller('registration')
export class RegistrationController {

  private readonly registrationService: RegistrationService;

  constructor(registrationService: IRegistrationService) {
    this.registrationService = registrationService;
  }
export interface IRegistrationService {
  register(): void;
}
export class RegistrationService implements IRegistrationService {
  public register(): void {
    // ...
 }
}

How can I tell my module that for the IRegistrationService I'd like to inject the RegistrationService class?

In AngularJS I could use a string as identifier and use an @Inject decorator on the constructor parameter of the controller class

Example:

@ngModule({
  providers: [
    {provide: 'RegistrationService', useClass: RegistrationService},
  ],
})
export class RegistrationModule {
}
@Controller('registration')
export class RegistrationController {

  private readonly registrationService: RegistrationService;

  constructor(@Inject('RegistrationService') registrationService: IRegistrationService) {
    this.registrationService = registrationService;
  }

Is this possible?

Contributing guidelines

Repo should have some contributing guidelines for new people who would like to contribute , I would like to add initial CONTRIBUTING.md which can be modified later.

@Body argument decorator fails with multiple named arguments

Only the first @Body argument decorator returns the expected result.
Repeated uses return undefined results.

Example:

@Controller("auth")
export class AuthorizationController {

    @Post()
    authenticate(@Request() req: Req,
                 @Response() res: Res,
                 @Body("user") user: string,
                 @Body("password") password: string)
    {
        console.log(user);     // returns 'example_user'
        console.log(password); // returns 'undefined'
        console.dir(req.body); // returns { user: 'example_user', password: 'password' }
        res.sendStatus(HttpStatus.OK);
    }

}

[Documentation] ID issue

On this page You're looking for users using the find method, but the IDs are stored in the service as numbers and the received param will be a string. So here's a quick fix:

This:

    @RequestMapping({ path: '/:id' })
    getUser(req, res) {
        this.usersService.getUser(req.params.id)
            .then((user) => res.status(200).json(user));
    }

Needs to change to this:

    @RequestMapping({ path: '/:id' })
    getUser(req, res) {
        this.usersService.getUser(Number(req.params.id)) // simply casted to number
            .then((user) => res.status(200).json(user));
    }

I know it's just an example for demonstration purposes, but it should work nonetheless.

Programatic Configuration: @Configuration class decorator

Like Spring does it could be great to allow programatic configuration classes.

These classes are responsible to load configuration properties and can be injected.
For example theses classes could have access to file system property files (json, properties or what else) or remote ones like S3 bucket.

It could help to defined default server properties like default api path, listened ports or for remote access providers token.
We also can imagine context property classes by module. A module that is not a sub module where define configuration class is can't be injected in modules classes.

It also could be awesome to have something like Spring Load Config with to hot server reload with external configuration change hooks.

Multiple Params not found?

I can't seem to get a second parameter to be picked up by the decorators, I've got the following code:

@Controller('player-activity')
export class PlayerActivityController {
    constructor(private playerActivityService: PlayerActivityService) {}

    @Get('/:localeID/:memberID')
    async activity (@Response() res, @Param('localeID') localeID, @Param('memberID') memberID) {
        console.log(`player-activity.controller: localeID: ${localeID}, memberID: ${memberID}`);
        const playerActivity: any[] = await this.playerActivityService.getActivity(+localeID, +memberID);
        res.status(HttpStatus.OK).json(playerActivity);
    }
}

and the first param item is fine, but the second is coming through as undefined.

screen shot 2017-05-04 at 23 24 27

(ignore first log line )

Is this an issue or something I have done wrong?

Parametrizable middleware

In my express applications, I often define a role check middleware factory.
It takes a role array as a parameter, so I can reuse it for different roles checking (admin, moderator, etc) without rewrite a specific middleware for each case.

Is it possible to do something similar with Nest middlewares?

Singletons

What's the preferred method for defining a singleton?

An @Singleton decorator might be nice.

[Documentation] TypeScript dependency management

In the documentation you mentioned:

It is incredibly easy to manage dependencies with TypeScript. If you are not TypeScript enthusiast and you work with plain JavaScript, you have to do it in this way:

This is slightly confusing since there's not mention of how to "manage dependencies with TypeScript" and the examples in the documentation will not run unless I add the @Dependencies([UsersService]) decorator. Without this decorator I'd get this exception:

[Nest] 2031   - 4/11/2017, 1:08:53 PM   [ExceptionsHandler] Cannot read property 'getUser' of undefined
TypeError: Cannot read property 'getUser' of undefined

No way to use RPC client from service

  1. RPC client cant be defined in service
  2. Controller (with defined RPC client) cannot be injected in service to call RCP actions via controller methods
  3. Controller cant be RPC client without defining @RequestMapping() on some method (try to remove method with @RequestMapping from controller and in controller constructor call this.client.send() after some timeout, this.client will be null)

Just got example from documentation (Client section) and tried all above.
IMHO the most important is 2 issue cause it's useful to have controllers that works with all transport (http/ws/rpc) things and services for all other work. So service should be able to inject appropriate controller to call RPC client action or send smth away via websocket.

Update. Or maybe we can move RPC client/server to Gateway? They can be injected into anything and rpc has same interaction logic as websocket (ability to receive and send messages).

Hapi and Koa integration

Express is a very great Node server library, but some project also use Hapi or Koa.
Does it a good idea to integrate them into Nest as adapters and let people choose the one they want / need ?

Can't inject services into module with @Inject

Hi,

it looks like I'm not able to inject a service into my module when I'm using the @Inject decorator.

Following code is throwing an resolve error:

@Module({
  controllers: [
    AuthenticationController,
  ],
  components: [
    {provide: 'AuthenticationService', useClass: HttpBasicAuthenticationService},
  ],
})
export class AuthenticationModule implements NestModule {

  private readonly authenticationService: IAuthenticationService;

  constructor(
    @Inject('AuthenticationService') authenticationService: IAuthenticationService,
  ) {
    this.authenticationService = authenticationService;
  }
}

Error:

[Nest] 10638   - 2017-5-5 15:17:32   [ExceptionHandler] Nest could not resolves dependencies of AuthenticationModule.
Error: Nest could not resolves dependencies of AuthenticationModule.

The service class is decorated with the @component decorator.

Can I help you by contributing ?

Hello,

First of all congrats for the initiative !
I'm very enthusiastic about the project and I'd like to help you by contributing.
I cloned the repository and I started to fix sinon warnings in the unit tests.

Tell me if you need ! ;-)

Future of the framework, contributions, evangelism

@kamilmysliwiec

First of all I'd like to say I really like the idea and your work so far, secondly: what are you plans for the future of the project? Here are some questions I'd love to hear your answers to.

  1. Do you plan to move it to it's own GitHub organization (eg. nest/nest)?
  2. Do you intend to create a website (GitHub Pages?)?
  3. How do you want to approach contributions?
  4. Is there any roadmap?
  5. Are you going to make some future milestones that community could help you achieve?
  6. What are your plans for making the framework more popular (and thus attract more contributors)?

Thanks for the answers.

websocket cluster

hi,

i see that you have included by default socket.io.. i'm thinking about a cluster scenario where i have a load balancer that is splitting load between nodes in a round-robin fashion. in that case the HTTP fallback of socket.io it will fail because requests will hit everytime different nodes, that will require to restablish the connection + re-auth. (basically they will become useless).
in the past i resolved this issue keeping different servers for APIs calls and WS interactions in order to put a round robin LB on the APIs and a IP hash LB for WS.

do you have thinked about this issue? if the connection is a real WS one (and not the HTTP fallback) it will persist also through a round robin LB?

thanks.

Question: Views folder

With the given structure of Nest projects, where is the preferred place to put views?

Auth0 Example

Looking for an auth0 example since it's defacto authentication platform nowadays

[Question] Strange behavior with DI and factory

Hello again,

I came across a problem where I am not sure if this is a wanted behavior regarding the injection via a factory.

I have the following module configuration:

Problem Case

@Module({
  components: [
    UserModelFactory,
    {
      provide: 'UserModel',
      useFactory: (userModelFactory: UserModelFactory) => {
        return userModelFactory.getSingletonInstance();
      },
      inject: [UserModelFactory],
    },
  ],
})
export class MongooseModelsModule {
}

In my repository layer I want to inject the mongoose model created by the factory class:

export class UserRepository implements IUserRepository {
  private readonly user: mongoose.Model<UserDocument>;

  constructor(
    @Inject('UserModel') user: mongoose.Model<UserDocument>,
  ) {
    this.user = user;
  }
}

Still I get an error message that the dependency of my repository class could not be resolved. My factory class itself is called and the model is created right.

I debugged the code and came to the following line where the problem is coming up:

    scanForComponentInRelatedModules(module, name) {
        const relatedModules = module.relatedModules || [];
        let component = null;
        relatedModules.forEach((relatedModule) => {
            const { components, exports } = relatedModule;
            // Coponents contains 'UserModel' but exports doesn't resulting in returning null
            if (!exports.has(name) || !components.has(name))
                return;
            component = components.get(name);
            if (!component.isResolved) {
                this.loadInstanceOfComponent(component, relatedModule);
            }
        });
        return component;
    }

Is it really necessary that the 'UserModel' must be within the exports metadata as I only define the component for the injection (see module above). This behavior seems strange to me.

Solution / Workaround

Doing the following Module configuration I get a working result:

@Module({
  exports: {
    UserModelFactory,
  },
  components: [
    UserModelFactory,
    {
      provide: 'UserModelFactory',
      useFactory: (userModelFactory: UserModelFactory) => {
        return userModelFactory.getSingletonInstance();
      },
      inject: [UserModelFactory],
    },
  ],
})
export class MongooseModelsModule {
}
export class UserRepository implements IUserRepository {
  private readonly user: mongoose.Model<UserDocument>;

  constructor(
    @Inject('UserModelFactory') user: mongoose.Model<UserDocument>,
  ) {
    this.user = user;
  }
}

This seems a bit awkward to me as I have to name my key the same as the class constructor AND I have to put the constructor into components and exports. Is this behavior intended?

Typescript - Interface injecting

Hi,

is it possible to inject a component based on its interface?

Let's assume the following component:

class UserRepository implements IUserRepository

This component is injected into the controller by interface from which is implemented:

export class UserController {
    constructor(private userService: IUserRepository) {}

It would be great to be able to set dependencies as follows:

@Module({
    controllers: [ UsersController ],
    components: [
        { provide: IUserRepository, useClass: UserRepository }
    ],
})

Thanks

Make Logger service public available

To prevent additional loggers usages make existing Logger service public available.
Also extend declaration for INestMicroservice with logger field to allow app.logger.log(...) usage on startup instead of console.log('Microservice is listening on port 3000')) from examples.
Also made logMessage method public to print messages with custom colors.

[Documentation] Express Typing

It's really good to see a web framework that deals with TypeScript as a first class citizen! I'm really excited about this project because of this.

However, when turning the option: noImplicitAny in the tsconfig.json the compiler will produce warnings about a lot of the examples in the documentation.

I highly recommend adding Express TypeScript declarations to the examples like so:

import {Request,Response,NextFunction} from "@types/express";


@Controller({})
export class UsersController {
	getAllUsers(req:Request, res:Response, next:NextFunction) {
		// will have auto completion, type safety ...etc
	}
}

Direct injection between components

How can inject a B component directly into A component to use its methods without going through the shared module?

Eg:

import { Component } from 'nest.js';

@Component()
export class BComponent {
    public bMethod() {
      return "foo";
  	}
}

import { Component } from 'nest.js';
import { BComponent } from '../helper/b.component';

@Component()
export class AComponent {

  	private aMethod() {
  		console.log(Bcomponent.bMethod());
    }           

}

The output: Property 'bMethod' does not exist on type 'typeof Bcomponent'.

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.