Code Monkey home page Code Monkey logo

nestjs-typegoose's Introduction

nestjs-typegoose

NPM

npm version Build Status Coverage Status npm npm bundle size David

Description

Injects typegoose models for nest components and controllers. Typegoose equivalant for @nestjs/mongoose.

Using Typegoose removes the need for having a Model interface.

Installation

npm install --save nestjs-typegoose

or

yarn add nestjs-typegoose

Documentation

Here is the full documentation describing all basic and advanced features.

Basic usage

You can checkout the example project for more details.

app.module.ts

import { Module } from "@nestjs/common";
import { TypegooseModule } from "nestjs-typegoose";
import { CatsModule } from "./cat.module.ts";

@Module({
  imports: [
    TypegooseModule.forRoot("mongodb://localhost:27017/nest", {
      useNewUrlParser: true,
    }),
    CatsModule,
  ],
})
export class ApplicationModule {}

Create class that describes your schema

cat.model.ts

import { prop } from "@typegoose/typegoose";
import { IsString } from "class-validator";

export class Cat {
  @IsString()
  @prop({ required: true })
  name: string;
}

Inject Cat for CatsModule

cat.module.ts

import { Module } from "@nestjs/common";
import { TypegooseModule } from "nestjs-typegoose";
import { Cat } from "./cat.model";
import { CatsController } from "./cats.controller";
import { CatsService } from "./cats.service";

@Module({
  imports: [TypegooseModule.forFeature([Cat])],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}

Get the cat model in a service

cats.service.ts

import { Injectable } from "@nestjs/common";
import { InjectModel } from "nestjs-typegoose";
import { Cat } from "./cat.model";
import { ReturnModelType } from "@typegoose/typegoose";

@Injectable()
export class CatsService {
  constructor(
    @InjectModel(Cat) private readonly catModel: ReturnModelType<typeof Cat>
  ) {}

  async create(createCatDto: { name: string }): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll(): Promise<Cat[] | null> {
    return await this.catModel.find().exec();
  }
}

Finally, use the service in a controller!

cats.controller.ts

import { Controller, Get, Post, Body } from "@nestjs/common";
import { CatsService } from "./cats.service";
import { Cat } from "./cats.model.ts";

@Controller("cats")
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Get()
  async getCats(): Promise<Cat[] | null> {
    return await this.catsService.findAll();
  }

  @Post()
  async create(@Body() cat: Cat): Promise<Cat> {
    return await this.catsService.create(cat);
  }
}

Requirements

  1. @typegoose/typegoose +6.1.5
  2. @nestjs/common +6.10.1
  3. @nestjs/core +6.10.1
  4. mongoose (with typings @types/mongoose) +5.7.12

License

nestjs-typegoose is MIT licensed.

nestjs-typegoose's People

Contributors

beaulac avatar bebjakub avatar cheerlesscloud avatar colinc-zylotech avatar decrn avatar dependabot[bot] avatar dirkbolte avatar duro avatar goodluckhf avatar hasezoey avatar kpfromer avatar lafeuil avatar luisvt avatar mmv08 avatar renovate-bot avatar semantic-release-bot 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

nestjs-typegoose's Issues

The package occupies updating the dependencies

When I install the package I get the following warnings saying that the package requires outdated @nestsJs and typegoose packages. Please update the dependencies in the package.

yarn add v1.22.4
[1/4] Resolving packages...
[2/4] Fetching packages...
info [email protected]: The platform "win32" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
info [email protected]: The platform "win32" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning " > [email protected]" has incorrect peer dependency "@nestjs/common@^6.10.1".
warning " > [email protected]" has incorrect peer dependency "@nestjs/core@^6.10.1".
warning " > [email protected]" has incorrect peer dependency "@typegoose/typegoose@^6.2.1".
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 2 new dependencies.
info Direct dependencies
└─ [email protected]
info All dependencies
├─ [email protected]
└─ [email protected]
Done in 84.02s.

The versions of packages I use are updated to their latest stable version:

"@nestjs/common": "^7.0.0",
"@nestjs/config": "^0.4.0",
"@typegoose/typegoose": "^7.0.0",

about InjectModel

My controller has a argument is a InjectModel, code:

      constructor(
          @InjectModel(Poll) private readonly model: ReturnModelType<typeof Poll>,
      ){
     }

and the Poll code is:

import { prop, modelOptions, getModelForClass } from '@typegoose/typegoose';
import { ApiProperty, ApiPropertyOptions } from '@nestjs/swagger';


@modelOptions({
  schemaOptions: {
    timestamps: true
  }
})
export class Poll {
  @ApiProperty({
      
  })
  @prop({required: true})
  title: string

  @prop({required: true})
  description: string

  @prop()
  poll: number

  @prop({select: false})
  userId: string

  @prop()
  userName: string

}

and jest code :

    import { Poll } from '@libs/db/models/poll.model';
    const module: TestingModule = await Test.createTestingModule({
      imports: [PollsModule],
      controllers: [PollsController],
      providers: [
        {
          provide: getModelForClass(Poll),
          useValue: getModelForClass(Poll)
        },
      ]
    }).compile();

and I get this error:
Nest can't resolve dependencies of the PollsController (?). Please make sure that the argument PollModel at index [0] is available in the PollsModule context.

Potential solutions:
- If PollModel is a provider, is it part of the current PollsModule?
- If PollModel is exported from a separate @Module, is that module imported within PollsModule?
  @Module({
    imports: [ /* the Module containing PollModel */ ]
  })

please help me to fix it

Basic NestJS typegoose/typegraphql example not working

I put up a basic project using NestJS, Typegoose and TypeGraphQL but the mongo query never returns:
https://github.com/elie222/nestjs-typegraphql-typegoose-example

Specifically in this file:

https://github.com/elie222/nestjs-typegraphql-typegoose-example/blob/master/src/cats/cats.resolver.ts

  @Query(() => [Cat])
  async cats(): Promise<Cat[]> {
    console.log("gets here");

    const cats = await this.catsService.listCats();
    
    console.log("never gets here", cats);

    return cats;
  }

Not sure if this is an issue with this package or Typegoose, or likely I'm just not setting things up as expected. Would be nice to get some sort of feedback but the promise just never returns.

TSDoc?

with this issue i request:
TSDoc all the functions

as someone that is new to Nest, it is kinda hard to understand what each function does (and without having used nest/mongoose)

Better setup for development

I think adding a code formatter would reduce style differences better developers. I also think adding a library to lint and format before git adds would be beneficial.
I think that the following libraries would be the best fit to achieve this:

  • prettier (and libraries to connect it with eslint)
  • husky
  • lint-staged

ModelType

  1. I noticed that i can't get "intellisense" with the injected ModelType (i.e save() etc.)
    When i use typegoose classes directly it works, like u can see on this capture (create method):
    image
  2. I also added @types/mongoose -dev and after that, i got many errors (cf. same capture).
    The error is : The value of type 'ModelType <Item>' can't be called. Would you like to include "New" ?
    Before that, the code is working without @type but maybe there is a problem that explains both anomaly ?

Documentation for Async Configuration Connection Options

I hope this is a good issue, I'm sorry if it is not. I'm struggling to configure the connection options while using the useFactory async configuration option. I have tried adding a connection object after returning the uri as shown below

TypegooseModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    uri: configService.MONGO_DB_URI,
    connectionOptions
  }),
  inject: [ConfigService]
})

The connectionOptions looks like this:

const connectionOptions: ConnectionOpenOptions = {
  useCreateIndex: true,
  useNewUrlParser: true,
};

However even after all this I get the ensureIndex and URL string parser deprecation warnings. Any assistance would be greatly appreciated

EDIT: After poking around, I've figured it out. The TypegooseModuleOptions expects a uri key and pairs of key -> value pairs. In essence you're supposed to spread the connection options ...connectionOptions. The reason I didn't do this initially was because of this code in the static forRootAsync method:

provide: 'DbConnectionToken',
useFactory: (typegooseModuleOptions: TypegooseModuleOptions) => {
  const {
    uri,
    ...typegooseOptions
  } = typegooseModuleOptions;

I thought the options would be automatically be assigned to the ...typegooseOptions before instantiating the connection.
Sorry for the inconvenience, you can close this issue.

Typescript Error at `pre` hook?

I have i am trying to implement pre hook. The following code works fine, but it is giving me TS lint error potantially invalid reference access to a class field via this. of a nested function.

@pre<Cat>('save', function (next) {
  this.updatedAt = new Date();
  next();
})

But the above code working though. It updates my updatedaAt field.

I am not sure this is related to this library or typegoose itself. But any help would be appriciated!

Thanks.

Support multiple db connections

Because of the hardcoded value

DbConnectionToken

in:

export function createTypegooseProviders(models: TypegooseClassWithOptions[] = []) {
  return models.map(({ typegooseClass, schemaOptions = {} }) => ({
    provide: getModelToken(typegooseClass.name),
    useFactory: (connection: Connection) => new typegooseClass().setModelForClass(typegooseClass, {
      existingConnection: connection,
      schemaOptions
    }),
    inject: ['DbConnectionToken']
  }));
}

We cannot have a few database connections. In the project I'm working on the architecture is that we have a db per nest module, so we have a few modules with different DBs.

As a quick fix I created my own methods forRoot and forFeature that use the passed connectionName.

Take a look at this:

import { TypegooseModule, getModelToken } from 'nestjs-typegoose';
import { Connection } from 'mongoose';
import { TypegooseClass } from 'nestjs-typegoose/dist/typegoose-class.interface';
import {
	TypegooseClassWithOptions,
	convertToTypegooseClassWithOptions,
} from 'nestjs-typegoose/dist/typegoose.providers';
import { TypegooseCoreModule } from 'nestjs-typegoose/dist/typegoose-core.module';
import { DynamicModule } from '@nestjs/common';
import { ConnectionOptions } from 'mongoose';

import * as mongoose from 'mongoose';

declare module 'nestjs-typegoose' {
	export class TypegooseModule {
		static forRoot(uri: string, options?: ConnectionOptions): DynamicModule;
		static forFeature(
			models: (TypegooseClass<any> | TypegooseClassWithOptions)[],
			connectionName: string,
		): DynamicModule;
	}
}

const createTypegooseProviders = (
	models: TypegooseClassWithOptions[] = [],
	connectionName: string = 'DbConnectionToken',
) => {
	return models.map(({ typegooseClass, schemaOptions = {} }) => ({
		provide: getModelToken(typegooseClass.name),
		useFactory: (connection: Connection) =>
			new typegooseClass().setModelForClass(typegooseClass, {
				existingConnection: connection,
				schemaOptions,
			}),
		inject: [connectionName],
	}));
};

TypegooseCoreModule.forRoot = (
	uri: string,
	options: ConnectionOptions = {},
): DynamicModule => {
	const connectionProvider = {
		// @ts-ignore
		provide: options.connectionName || 'DbConnectionToken',
		useFactory: () => mongoose.createConnection(uri, options),
	};
	return {
		module: TypegooseCoreModule,
		providers: [connectionProvider],
		exports: [connectionProvider],
	};
};

TypegooseModule.forFeature = (
	models: (TypegooseClass<any> | TypegooseClassWithOptions)[],
	connectionName?: string,
): DynamicModule => {
	const convertedModels = models.map(model =>
		convertToTypegooseClassWithOptions(model),
	);

	const providers = createTypegooseProviders(convertedModels, connectionName);

	return {
		module: TypegooseModule,
		providers,
		exports: providers,
	};
};

And now we can declare a new nest module and pass the db connection name (in this case usersDb) like this:

@Module({
	imports: [
		TypegooseModule.forRoot(ConfigService.envs.MONGO_USERS_URI, {
			// @ts-ignore
			connectionName: 'usersDb',
		}),
		TypegooseModule.forFeature([User], 'usersDb'),
	],
	exports: [UsersService],
	providers: [UsersService],
})
export class UsersModule { }

Not sure if this can be used exactly like this, but so far its been working with no issues.

Error when using newUrlParser

I am getting this error when trying to use the newUrlParser.

CODE:

@Module({ imports: [ GraphQLModule.forRoot({ autoSchemaFile: 'schema.gql', }), TypegooseModule.forRoot('mongodb://localhost:27017/nest', { useNewUrlParser:true}) ], controllers: [AppController], providers: [AppService], }) export class AppModule { }

ERROR:
TS2345: Argument of type '{ useNewUrlParser: boolean; }' is not assignable to parameter of type 'TypegooseConnectionOptions'.
  Object literal may only specify known properties, and 'useNewUrlParser' does not exist in type 'TypegooseConnectionOptions'.

Dependencies:
"nestjs-typegoose": "^7.0.0",
"@typegoose/typegoose": "^6.1.2",

Jest tests start breaking after upgrading to @typegoose/typegoose v6

I just spent the last day and a half tearing my hair out trying to figure out why my tests were breaking after upgrading to @typegoose/typegoose v6.

Turns out that the typegoose library stores an internal map of all the models that it has bootstrapped, and when you run getModelForClass if the model already exists in that map, it just returns the first created model.

The problem arises when you use something like MongoMemoryServer to spin up and teardown an in memory Mongo server, as well as a new instance of your nest app for each test block.

The connections to each server are created and dropped just fine, however, that model map is still stuck in a singleton living in the typegoose package. So when it comes around to try and bootstrap models for the second test block, the models from the old server are still in that map, and silently get returned back when getModelForClass is called.

So my services were getting old models, still pinned to the old connection.

I managed to fix this by adding the following to nestjs-typegoose in the onModuleDestroy function

  async onModuleDestroy() {
    const connection = this.moduleRef.get<any>(this.connectionName);

    if (connection) {
      await connection.close();
      // ==========
      for (const modelName of connection.modelNames()) {
        connection.deleteModel(modelName);
        typegooseData.models.clear();
        typegooseData.constructors.clear();
      }
      // ==========
    }
  }

I have this living in a temporary fork I created here:

https://github.com/duro/nestjs-typegoose/tree/dist

However, this is likely not the final solution. It appears that typegoose is releasing new functions in v6.1 for deleteModel. So once that drops, the above code you likely change to this:

import { deleteModel } from '@typegoose/typegoose'

  async onModuleDestroy() {
    const connection = this.moduleRef.get<any>(this.connectionName);

    if (connection) {
      await connection.close();
      // ==========
      for (const modelName of connection.modelNames()) {
        deleteModel(modelName);
      }
      // ==========
    }
  }

This new function handles removing the model from mongoose, and the Typegoose model data store.

See here:

https://github.com/typegoose/typegoose/blob/master/src/typegoose.ts#L206

Just leaving this here for anyone else who runs across this and hopefully the don't loose a day and a half to this.

Once v6.1 of @typegoose/typegoose releases, I'm happy to come back around with a real PR to try and integrate this.

v5.2.0 Cannot find module 'nestjs-typegoose'

My CI build is erroring with Cannot find module 'nestjs-typegoose'.

I SSH'd into the container doing the build, and when I run ls -lah inside the node_modules/nestjs-typegoose folder I get this:

bash-4.2# ls -lah
total 536K
drwxr-xr-x    3 root root 4.0K Jun  7 00:55 .
drwxr-xr-x 1096 root root  36K Jun  7 00:55 ..
-rw-r--r--    1 root root 3.9K Jun  7 00:55 .npmignore
-rw-r--r--    1 root root  886 Jun  7 00:55 CHANGELOG.md
-rw-r--r--    1 root root 4.2K Jun  7 00:55 CONTRIBUTING.md
-rw-r--r--    1 root root 1.1K Jun  7 00:55 LICENSE
-rw-r--r--    1 root root 6.3K Jun  7 00:55 README.md
-rw-r--r--    1 root root 453K Jun  7 00:55 package-lock.json
-rw-r--r--    1 root root 1.7K Jun  7 00:55 package.json
drwxr-xr-x    2 root root 4.0K Jun  7 00:55 testing-project
-rw-r--r--    1 root root  925 Jun  7 00:55 tslint.json

It would appear there is no dist/index.js. Did something go wrong in the package and push to NPM?

No way to save using mongoose-auto-increment

import * as mongooseAutoIncrement from 'mongoose-auto-increment'
import { prop, arrayProp, plugin, pre, Typegoose, index } from 'typegoose'

@plugin(mongooseAutoIncrement.plugin, {
model: Test.name,
field: 'id',
startAt: 1,
incrementBy: 1,
})
export class Test extends Typegoose {
@IsString()
@prop({ required: true })
name: string
}

When saving, this plugin causes the request to continue, neither error nor output

v5.2 Not Working with Nest TestModule

Hi!
When updating to the new version I tried to run my tests and I realized that the library lost its compatibility with Nest TestModule.
I have created a repository where it is possible to recreate the error, when I launch the app with start: dev there are no problems, but when I run the tests, the models are not injected correctly in the service and it displays the following error:

Link of repository to recreate this issue

https://github.com/krouw/nestjs-typegoose-test

Regards!!!

About the document

Is there any more complete documentation, because I would like to know the parameter description of the options object of prop.

'useNewUrlParser' does not exist in type 'TypegooseConnectionOptions'

As the title suggest I am getting the following error when trying to register the module:

'useNewUrlParser' does not exist in type 'TypegooseConnectionOptions'

in app.module.ts:

import { Module, Logger } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { TypegooseModule } from 'nestjs-typegoose';
import { AppController } from './app.controller';
import { UsersModule } from './accounts/account.module';
import * as dotenv from 'dotenv';

// loading .env file
dotenv.config();

@Module({
  imports: [
    UsersModule,
    GraphQLModule.forRoot({
      cors: false,
      playground: true,
      autoSchemaFile: true,
      // return the req in the graphql context
      context: ({ req, res, connection }) =>
        connection ? { req: connection.context } : { req, res },
      installSubscriptionHandlers: true,
      subscriptions: {
        onConnect: (connectionParams, webSocket, context) => {
          Logger.log('Connected!');
          // TODO: auth for subscription
        },
      },
    }),
    TypegooseModule.forRoot(process.env.DB_URL, {
      useNewUrlParser: true,
      useFindAndModify: false,
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}

using version: [email protected]

An example of a graphql server and typegoose

It would be amazing to have an example to create a graphql server with the code-first way and typegoose.

Indeed, I tried for a long time to merge the typegoose model with the @ObjectType which are really very similar, but I still didn't succeed.

It would be impressive if it was possible to do both with 1 class.

Global schema options

It would be nice to be able to return schema options that will be applied to all models from the .forRoot call.

For example, If I want timestamps on all of my models I have to pass {timestamps: true} to all of my models. It would be nice If i could just return something like this from .forRoot Options and spread it into each model when calling .forFeature

{
  uri: "myUri",
  schemaOptions: {
    timestamps: true
  }
}

use of micro-package is-class?

Considering all that's going on with npm and these micro-packages, wouldn't it be a better idea to just move the existing code from is-class as a util part of the source-code, rather than having it on npmjs where there's no guarantees that it will be the same code as in the linked github?

class-validator?

The example in the readme has class-validator included in it.

import { prop } from "@typegoose/typegoose";
import { IsString } from "class-validator";

export class Cat {
  @IsString()
  @prop({ required: true })
  name: string;
}

Does nestjs-typegoose have integration with class-validator? from my searching it appears that the answer is no. If there isn't integration, it probably shouldnt be in the initial readme, cuz it confused me for a bit. An example with class-validator would be cool though, and might be something that could be integrated into typegoose core.

Pre save hook called twice during jest testing

I have been trying to track down this issue all day and cannot figure out what is going on. I have a simple service with a register function. My automated login after registration test keeps failing. I found it's because the pre-save hook gets called twice and re-hashes the hashed password. This behavior does not happen during normal operation... only under jest testing.

This code produces the console log at the bottom.

@pre<User>('save', function(next) {
	try {
		console.trace();
		if (this.isModified('password')) {
			const salt = genSaltSync(10);
			this.password = hashSync(this.password, salt);
			console.log(this.password, this.isModified('password'));
		}
		next();
	} catch (error) {
		next();
	}
})
		console.log('before new');
		const newUser = new this.userModel(data);
		console.log(newUser);
		console.log('new');
		newUser.claims.concat(claims || []);
		newUser.agreements.concat(agreements || []);
		console.log('before validate');
		await newUser.validate();
		console.log('validate');
		console.log('before save');
		await newUser.save();
		console.log('save');
  console.log src/app/modules/sso.module/sso.service.ts:66
    new

  console.log src/app/modules/sso.module/sso.service.ts:69
    before validate

  console.log src/app/modules/sso.module/sso.service.ts:71
    validate

  console.log src/app/modules/sso.module/sso.service.ts:72
    before save

  console.error internal/console/constructor.js:334
    Trace: 
        at model.<anonymous> (E:\Development\Node\mm-mono\libs\api\models\user.model.ts:9:11)
        at callMiddlewareFunction (E:\Development\Node\mm-mono\node_modules\kareem\index.js:482:23)
        at model.next (E:\Development\Node\mm-mono\node_modules\kareem\index.js:58:7)
        at _next (E:\Development\Node\mm-mono\node_modules\kareem\index.js:106:10)
        at E:\Development\Node\mm-mono\node_modules\kareem\index.js:507:38
        at processTicksAndRejections (internal/process/task_queues.js:75:11)

  console.log ../../libs/api/models/user.model.ts:13
    $2a$10$l.vp7u7hBdA1JtHr8h2P5OcA9t/Oq1mnVBB7OKDWMJ786tdUAhsxG true

  console.error internal/console/constructor.js:334
    Trace: 
        at model.<anonymous> (E:\Development\Node\mm-mono\libs\api\models\user.model.ts:9:11)
        at callMiddlewareFunction (E:\Development\Node\mm-mono\node_modules\kareem\index.js:482:23)
        at model.next (E:\Development\Node\mm-mono\node_modules\kareem\index.js:58:7)
        at _next (E:\Development\Node\mm-mono\node_modules\kareem\index.js:106:10)
        at E:\Development\Node\mm-mono\node_modules\kareem\index.js:507:38
        at processTicksAndRejections (internal/process/task_queues.js:75:11)

  console.log ../../libs/api/models/user.model.ts:13
    $2a$10$fbPEr0dK3AEk74YT5nQZK.7WWOWB1.4zogJrlY2tRKl1VwNHNzQ/K true

  console.log src/app/modules/sso.module/sso.service.ts:74
    save


Error: Invalid model object

For the life of me, I can't make this work.

I'm getting an error:

Z:\digimet\node_modules\nestjs-typegoose\dist\typegoose.providers.js:15
    throw new Error('Invalid model object');
    ^

Error: Invalid model object
    at Object.exports.convertToTypegooseClassWithOptions (Z:\digimet\node_modules\nestjs-typegoose\dist\typegoose.providers.js:15:11)
    at models.map.model (Z:\digimet\node_modules\nestjs-typegoose\dist\typegoose.module.js:26:75)
    at Array.map (<anonymous>)
    at Function.forFeature (Z:\digimet\node_modules\nestjs-typegoose\dist\typegoose.module.js:26:40)
    at Z:\digimet\dist\apps\api\main.js:1024:82
    at Module../apps/api/src/app/user/user.module.ts (Z:\digimet\dist\apps\api\main.js:1033:2)
    at __webpack_require__ (Z:\digimet\dist\apps\api\main.js:20:30)
    at Module../apps/api/src/app/app.module.ts (Z:\digimet\dist\apps\api\main.js:105:75)
    at __webpack_require__ (Z:\digimet\dist\apps\api\main.js:20:30)
    at Module../apps/api/src/main.ts (Z:\digimet\dist\apps\api\main.js:1150:73)
    at __webpack_require__ (Z:\digimet\dist\apps\api\main.js:20:30)
    at Object.0 (Z:\digimet\dist\apps\api\main.js:1368:18)
    at __webpack_require__ (Z:\digimet\dist\apps\api\main.js:20:30)
    at Z:\digimet\dist\apps\api\main.js:84:18
    at Object.<anonymous> (Z:\digimet\dist\apps\api\main.js:87:10)
    at Module._compile (internal/modules/cjs/loader.js:688:30)

My model is :


export class User extends Typegoose {
  @prop()
  id: string;

  @prop()
  firstName: string;

  @prop()
  lastName: string;

  @prop({
    unique: true
  })
  email: string;

  @prop()
  password: string;

  @prop()
  avatar: string;

  @prop()
  description: string;

}

The error occurs in my feature module user.module at typegoose.providers.js where my model fails the check of IsClass.
As you see the class is elementary and properly extends Typegoose class.

I even tried modifying the typegoose.providers.js to console.log the class that is analyzed, and the output is: [Function: User]

What am I doing wrong?

DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.

Hi All!
With current version of this module I cannot specify in the property useUnifiedTopology: true it shows me this argument is not assignable to parameter of type TypegooseConnectionOptions.
It would be really helpful if someone could help me to resolve this.

Alternate name for the collection

Is there a way to pass it an alternate name for the collection. Mongoose provides the schemaOptions, where you can define an object for an alternate name, which looks like: { collection: 'category'}. See below. How would you give the collection a different name in your implementation?

export const CategorySchema = new Schema({
name: { type: String, required: true, unique: true },
}, { collection: 'category' });

When I used the `extends` base model, something strange happened.

Base Model

 @modelOptions({
  schemaOptions: {
    timestamps: true
  }
})
export abstract class BasicModel {
  _id?: string;

  @prop({
    enum: FIELD_STATUS_ENUM,
    default: FIELD_STATUS_ENUM.USABLE
  })
  public status: FIELD_STATUS_ENUM;

  static get schema(): Schema {
    return buildSchema(this as any, {
      timestamps: true,
      toJSON: {
        getters: true,
        virtuals: true
      }
    });
  }

  static get modelName(): string {
    return this.name;
  }

  get id(): string {
    return this._id;
  }
}

The Feature Model

// RoleModel
 @index(
  {
    role_name: 1
  },
  {
    unique: true
  }
)
export class Role extends BasicModel {
  @prop()
  public role_name: string;

  @prop()
  public role_description: string;
}

And Other Feature Model

// basicUnitModel
@modelOptions({
  schemaOptions: {
    collection: 'basic_unit',
  },
})
export class BasicUnit extends BasicModel {

  @prop({
    unique: true,
  })
  public unit_name: string;
}

Problems

When I create a new role using the service

// role.service.ts
public async createRole(role: Role): Promise<Role> {
    return await this.create(role);
  }

Sometimes, After I restart the app serve, I call the this.roleService.create (role) to created the role in roles collection, But it save to the basic_uint collection by mistake.

This only happens when I use extends BasicModel for RoleModel

🤔 I think it might be a bug.

Can you tell me what is causing this? I don't want to give up extends and bypass this problem.

Why this package?

Hi... I want to add mongo support for my NestJS app and I found this package? But I would like to ask, what advantages have this over the official @nestjs/mongoose...

I manage to use Typegoose with @nestjs/mongoose without problems or any extra complication:

My model:

import { prop, buildSchema, getModelForClass } from '@typegoose/typegoose';

export class User {
  @prop({ required: true })
  email: string;

  @prop({ required: true })
  password: string;
}

export const UserModel = getModelForClass(User);
export const UserSchema = buildSchema(User)

Controller:

import { Controller, Get, Post, Body } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './models/user.model';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  async getUsers(): Promise<User[] | null> {
    return await this.usersService.findAll();
  }

  @Post()
  async create(@Body() userDto: Partial<User>): Promise<User> {
    return await this.usersService.create(userDto);
  }
}

The service:

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { ReturnModelType } from '@typegoose/typegoose';

import { User } from './models/user.model';

@Injectable()
export class UsersService {
  constructor(
    @InjectModel(User.name) // This take the name of the class or you can use `UserModel.modelName`
    private readonly userModel: ReturnModelType<typeof User>
  ) {}

  async create(createUserDto: Partial<User>): Promise<User> {
    const createdCat = new this.userModel(createUserDto);
    return await createdCat.save();
  }

  async findAll(): Promise<User[]> {
    return await this.userModel.find().exec();
  }
}

and finally the Users module

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

import { User, UserSchema } from './models/user.model';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [
    // MongooseModule.forFeature([{ name: UserModel.modelName, schema: UserModel.schema }])
    // or this
    MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])
  ],
  controllers: [UsersController],
  providers: [UsersService]
})
export class UsersModule {}

I am not saying that this project does not contribute anything to the community, I am sure there is some reason why it exists, I do not want to be misunderstood, but why maintain another package instead of contribute to the official one and make it better

How to call static methods?

Hallo,

I defined a static method on my Typegoose model and then tried to use the model within a service.
The TypeScript compiler issues an error, though:

error TS2339: Property 'findAll' does not exist on type 'ModelType'.

How can I solve this?
Here's my code:

export class DBShipping extends Typegoose {
	@staticMethod
	static findAll(this: ModelType<DBShipping> & typeof DBShipping, userId: UserId) {
		....
	}
        ....
}


constructor(@InjectModel(DBShipping) private shippingModel: ModelType<DBShipping>) {
	}

....
const shippings = await this.shippingModel.findAll(context.user.id);

Thanks!

Documentation / Dependencies

Thx for this module, it's realy nice.

Just some questions about the documentation in the section "Cats Service" :

It seems like you use Cat Interface and not Cat Model, is it normal ?
Also we can see a reference to Cats Schema.

In the requierement, you dont list @nestjs/mongoose that you use for the @InjectModel. We dont need to install it ? [EDIT] => looks like you added "InjectModel" directly inside your module nestjs-typegoose

Regards

Update to typegoose/typegoose v6 - TypeError: (intermediate value).setModelForClass is not a function

Hi there, firstly i'd like to say thank you for the package it's great! but I updated my package today and am currently getting stuck with errors. I am getting a

TypeError: (intermediate value).setModelForClass is not a function

Error. The full error is:

[Nest] 23619 - 08/10/2019, 15:17:02 [ExceptionHandler] (intermediate value).setModelForClass is not a function +1ms TypeError: (intermediate value).setModelForClass is not a function at InstanceWrapper.useFactory [as metatype] (/Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/nestjs-typegoose/dist/typegoose.providers.js:20:58) at Injector.instantiateClass (/Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/@nestjs/core/injector/injector.js:279:55) at callback (/Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/@nestjs/core/injector/injector.js:74:41) at processTicksAndRejections (internal/process/task_queues.js:85:5) at Injector.resolveConstructorParams (/Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/@nestjs/core/injector/injector.js:113:24) at Injector.loadInstance (/Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/@nestjs/core/injector/injector.js:78:9) at Injector.loadProvider (/Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/@nestjs/core/injector/injector.js:35:9) at async Promise.all (index 3) at InstanceLoader.createInstancesOfProviders (/Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/@nestjs/core/injector/instance-loader.js:41:9) at /Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/@nestjs/core/injector/instance-loader.js:27:13 at async Promise.all (index 7) at InstanceLoader.createInstances (/Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/@nestjs/core/injector/instance-loader.js:26:9) at InstanceLoader.createInstancesOfDependencies (/Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/@nestjs/core/injector/instance-loader.js:16:9) at /Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/@nestjs/core/nest-factory.js:82:17 at Function.asyncRun (/Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/@nestjs/core/errors/exceptions-zone.js:17:13) at NestFactoryStatic.initialize (/Users/aidanmcdonagh/Documents/KHIPU Documents/KHIPU Kloud/KHIPU Kloud Backend V2/khipu-kloud-server/node_modules/@nestjs/core/nest-factory.js:80:13) error Command failed with exit code 1.

I have about 9 classes which I am loading into my .forFeature() function and prior to that am importing my Typegoose forRootAsync Module. If you would like some more information please ask, thank you.

Can't resolve dependencies error

Hi, I am using this module for the first time. It looks great, but my reference documentation didn't work properly after it was written.

app.module.ts

import { Module } from '@nestjs/common';
import { AppService } from './app.service';
import { AppController } from './app.controller';
import { TypegooseModule } from 'nestjs-typegoose';
import { ProfileModule } from './profile/profile.module';

@Module({
    imports: [
        TypegooseModule.forRoot('mongodb://localhost/user', {
            useNewUrlParser: true,
        }),
        ProfileModule,
    ],
    controllers: [AppController],
    providers: [AppService],
})
export class AppModule {}

profile.model.ts

import { prop, Typegoose } from 'typegoose';

export class Profile extends Typegoose {
    @prop({ required: true, unique: true })
    nickname: string;
}

profile.module.ts

import { Module } from '@nestjs/common';
import { ProfileService } from './profile.service';
import { TypegooseModule } from 'nestjs-typegoose';
import { ProfileController } from './profile.controller';

import { Profile } from './profile.model';

@Module({
    imports: [TypegooseModule.forFeature(Profile)],
    controllers: [ProfileController],
    providers: [ProfileService],
})
export class ProfileModule {}

profile.service.ts

import { ModelType } from 'typegoose';
import { Profile } from './profile.model';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';

@Injectable()
export class ProfileService {
    constructor(@InjectModel('profile') private readonly model: ModelType<Profile>) {}

    async findAll() {
        return await this.model.find();
    }
}

After executing the npm start command, an error was thrown:

⇢ npm start

> [email protected] start /Users/abel/Desktop/develop/modules/user
> ts-node -r tsconfig-paths/register src/main.ts

[Nest] 10377   - 2018-9-17 13:23:12   [NestFactory] Starting Nest application...
[Nest] 10377   - 2018-9-17 13:23:12   [InstanceLoader] TypegooseModule dependencies initialized +22ms
[Nest] 10377   - 2018-9-17 13:23:12   [InstanceLoader] AppModule dependencies initialized +0ms
[Nest] 10377   - 2018-9-17 13:23:12   [ExceptionHandler] Nest can't resolve dependencies of the ProfileService (?). Please make sure that the argument at index [0] is available in the current context. +12ms
Error: Nest can't resolve dependencies of the ProfileService (?). Please make sure that the argument at index [0] is available in the current context.
    at Injector.lookupComponentInExports (/Users/abel/Desktop/develop/modules/user/node_modules/@nestjs/core/injector/injector.js:146:19)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:228:7)
    at Function.Module.runMain (module.js:695:11)
    at Object.<anonymous> (/Users/abel/Desktop/develop/modules/user/node_modules/ts-node/src/bin.ts:157:12)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:191:16)
    at bootstrap_node.js:612:3

error TS2307: Cannot find module 'typegoose-options.interface'.

$ rm -rf dist && tsc
node_modules/nestjs-typegoose/dist/typegoose.module.d.ts:6:45 - error TS2307: Cannot find module 'typegoose-options.interface'.

6 import { TypegooseModuleAsyncOptions } from 'typegoose-options.interface';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Found 1 error.

v5.2.1 issues with forFeature

Was this an expected breaking change? With v5.2.1 I am now getting the following build error:

services/nest-example/src/app.module.ts:25:32 - error TS2345: Argument of type 'typeof User' is not assignable to parameter of type '(TypegooseClass<any> | TypegooseClassWithOptions)[]'.
  Type 'typeof User' is missing the following properties from type '(TypegooseClass<any> | TypegooseClassWithOptions)[]': pop, push, concat, join, and 25 more.

25     TypegooseModule.forFeature(User),

Nothing in the code on my end has changed.

User extends from Typegoose. I am running version 5.7.1 of Typegoose.

How to set timestamp in this library

export const UserModel = new User().getModelForClass(User, { schemaOptions: { timestamps: true } }); this is how to add timestamps in typegoose, but I cannot find the solution in terms of how to add timestamps in this library. so can you guys give me some advice?

Visual Studio Code - Debug Mode Crash

Strange issue : the visual studio code debugger code crash when i import TypegooseModule.forRoot

Same issue with a fresh project from "git clone https://github.com/nestjs/typescript-starter.git project" and different node 10 / 11 & 12 and a VSC updated

└─ $ ▶  cd /sandbox/project ; env 'DEBUG=app:*' /usr/local/bin/node --nolazy -r ts-node/register --inspect-brk=10800 /sandbox/project/src/main.ts 
Debugger listening on ws://127.0.0.1:10800/0947c54f-0d61-4142-b819-6daf9b54339c
For help see https://nodejs.org/en/docs/inspector
Debugger attached.
FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal.
 1: node::Abort() [/usr/local/bin/node]
 2: 0x1363f0c [/usr/local/bin/node]
 3: v8::Utils::ReportApiFailure(char const*, char const*) [/usr/local/bin/node]
 4: 0x13e2801 [/usr/local/bin/node]
 5: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [/usr/local/bin/node]
 6: 0xb43758 [/usr/local/bin/node]
 7: v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node]
 8: 0x33eb1510437d
Abandon
import * as config from 'config';

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

import { TypegooseModule } from 'nestjs-typegoose';

const aggregationsWarpUri: string = config.get('mongo.aggregationsWarpUri');


@Module({
  imports: [
    TypegooseModule.forRoot(aggregationsWarpUri, { useNewUrlParser: true, useUnifiedTopology: true, connectionName: 'aggregationsWarpConnection' }),    
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

If i comment TypegooseModule.forRoot, i have no issues to start the debugger

A classic start work well too : npm start

My lunch script for the debugger :

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
      {
      "type": "node",
      "request": "launch",
      "name": "Debug Nest Framework",
      "args": ["${workspaceFolder}/src/main.ts"],
      "runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
      "sourceMaps": true,
      "cwd": "${workspaceRoot}",
      "protocol": "inspector",
      "console": "integratedTerminal",
      "env": {
        "DEBUG": "app:*"
      },
    }]
  }

the options [connectionName] is not supported

I'm trying to use multiple dbs in my app, however I get this error:

the options [connectionName] is not supported

Here is my usage of the typegoose module

@Module({
  imports: [
    TypegooseModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (config: ConfigService) => ({
        uri: config.get('MONGODB_URI_TODOS'),
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useCreateIndex: true,
        connectionName: 'todos-db',
      })
    }),
    TypegooseModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (config: ConfigService) => ({
        uri: config.get('MONGODB_URI_USERS'),
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useCreateIndex: true,
        connectionName: 'users-db',
      })
    }),
    ConfigModule,
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

Versions:

"nestjs-typegoose": "^7.0.0",
"@nestjs/mongoose": "6.3.1",
"@typegoose/typegoose": "6.2.2",

A lot of warning

hello, I'm getting a lot of theses on start… Am I doing something wrong ?

Screenshot 2020-05-15 at 15 00 48

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.