npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@tsh96/nest-mongoose-crud

v1.1.2

Published

<div align="center"> <h1>Nest Mongoose Crud</h1> </div>

Downloads

3

Readme

Description

This package provides several decorators and classes for endpoints generation, model validation, and access control

Features

  • Super easy to install and start using the full-featured controllers and services.
  • DB and service agnostic extendable CRUD controllers.
  • Reach query parsing with filtering, pagination, and sorting.
  • Query, path params and DTOs validation included.
  • Overriding or inherit controller methods with ease
  • Tiny config
  • Swagger documentation
  • Code Generator

Install

Create a new nestjs project and install following dependencies.

Yarn (Recommended)

yarn add @tsh96/nest-mongoose-crud class-transformer class-validator @nestjs/swagger @nestjs/mongoose mongoose
yarn add -D @types/mongoose

Npm

npm install @tsh96/nest-mongoose-crud class-transformer class-validator @nestjs/swagger @nestjs/mongoose mongoose
npm install @types/mongoose

Getting started

Codegen

Codegen is a handy tool to generate code for controller, dto, module, schema and service.

yarn codegen [resource] [path?]

For example yarn codegen cat will create a files under src/cat folder and yarn codegen puppy d1/d2 will create a files under src/d1/d2

Manually

Create a mongoose schema

// dog.schema.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { ApiProperty } from '@nestjs/swagger';
import { IsNumber, IsString } from 'class-validator';
import { Document } from 'mongoose';

export type DogDocument = Dog & Document;

@Schema()
export class Dog {
  @Prop() // For mongoose
  @ApiProperty() // For swagger
  @IsString() // For class validator
  name: string;

  @Prop() // For mongoose
  @ApiProperty() // For swagger
  @IsNumber() // For class validator
  age: number;

  @Prop() // For mongoose
  @ApiProperty() // For swagger
  @IsString() // For class validator
  breed: string;
}

export const DogSchema = SchemaFactory.createForClass(Dog);

Create Dto(s) for services:

//dog.dto.ts
import { ApiProperty } from '@nestjs/swagger';
import { IsNumber, IsString, IsOptional } from 'class-validator';
import { Dog } from './dog.schema';

export class CreateDogDto extends Dog {
  @ApiProperty() // For swagger
  @IsString() // For class validator
  name: string;

  @ApiProperty() // For swagger
  @IsNumber() // For class validator
  age: number;

  @ApiProperty() // For swagger
  @IsString() // For class validator
  breed: string;
}

export class UpdateDogDto {
  @ApiProperty({ required: false }) // For swagger
  @IsString() // For class validator
  @IsOptional() // For class validator
  name?: string;

  @ApiProperty({ required: false }) // For swagger
  @IsNumber() // For class validator
  @IsOptional() // For class validator
  age?: number;

  @ApiProperty({ required: false }) // For swagger
  @IsString() // For class validator
  @IsOptional() // For class validator
  breed?: string;
}

Then create a crud service. Must have CrudInjectable decorator and extends CrudService:

//dog.service.ts
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { Dog, DogDocument } from './dog.schema';
import { CreateDogDto, UpdateDogDto } from './dog.dto';
import { CrudInjectable, CrudService } from 'nest-mongoose-crud';

@CrudInjectable({
  createDto: CreateDogDto,
  updateDto: UpdateDogDto,
  mongooseModel: Dog,
  filterQuery: UpdateDogDto,
}) // For Crud Service
export class DogsService extends CrudService {
  constructor(@InjectModel(Dog.name) dogModel: Model<DogDocument>) {
    super(dogModel);
  }
}

Create a controller. Must have Crud decorator and extends CrudController::

//dogs.controller.ts
import { ParseArrayPipe } from '@nestjs/common';
import { ApiBearerAuth } from '@nestjs/swagger';
import { AuthResource, Crud, CrudController } from 'nest-mongoose-crud';
import { DogsService } from './dog.service';

@ApiBearerAuth() // For Swagger Api
@AuthResource('dog') // For Access Control (Roles Guard)
@Crud('dogs', { crudService: DogsService, ParseArrayPipe }) // For Crud Controller
export class DogsController extends CrudController<DogsService, any> {
  constructor(readonly service: DogsService) {
    super(service);
  }
}

Connect controller and service with a module

//dogs.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { Dog, DogSchema } from './dog.schema';
import { DogsController } from './dogs.controller';
import { DogsService } from './dog.service';
import { JwtAuthModule } from 'src/jwt-auth/jwt-auth.module';

@Module({
  imports: [
    MongooseModule.forFeature([{ name: Dog.name, schema: DogSchema }]),
    JwtAuthModule,
  ],
  controllers: [DogsController],
  providers: [DogsService],
})
export class DogsModule {}

BINGO!

API endpoints

| Action | One | Bulk | | ------ | --------------------- | --------------------------------------- | | Create | POST /dogs | POST /dogs/bulk | | Read | GET /dogs/:dogId | GET /dogs | | Update | PUT /dogs/:dogId | PUT /dogs requiredParam(filter) | | Delete | DELETE /dogs/:dogId | DELETE /dogs requiredBody([...ids]) |

Access Control

@AuthResource and @AuthActions decorators are worked together to define permissions for each endpoint. @AuthResource is used on controllers and @AuthActions is used on actions (methods). For example

//dogs.controller.ts
import { ParseArrayPipe } from '@nestjs/common';
import { ApiBearerAuth } from '@nestjs/swagger';
import {
  AuthResource,
  AuthActions,
  Crud,
  CrudController,
} from 'nest-mongoose-crud';
import { DogsService } from './dog.service';

@ApiBearerAuth() // For Swagger Api
@AuthResource('dog') // For Access Control (Roles Guard)
@Crud('dogs', { crudService: DogsService, ParseArrayPipe }) // For Crud Controller
export class DogsController extends CrudController<DogsService, any> {
  constructor(readonly service: DogsService) {
    super(service);
  }

  @Patch('feed')
  @AuthActions('Feed')
  // @AuthActions('FeedOne', 'FeedMany')  it also can be multiple
  feed() {
    // code here
  }
}

Some basic actions are included in the crud actions:

| Action | One | Bulk | | ------ | ------------------------- | ------------ | | Create | CreateOne, CreateMany | CreateMany | | Read | ReadOne, ReadMany | ReadMany | | Update | UpdateOne, UpdateMany | UpdateMany | | Delete | DeleteOne, DeleteMany | DeleteMany |

Override/Inheritance

You can override or inherit controllers as below:

//imports ...
@ApiBearerAuth() // For Swagger Api
@AuthResource('dog') // For Access Control (Roles Guard)
@Crud('dogs', { crudService: DogsService, ParseArrayPipe }) // For Crud Controller
export class DogsController extends CrudController<DogsService, any> {
  constructor(readonly service: DogsService) {
    super(service);
  }

  @Post()
  @AuthActions('CreateOne')
  ApiOkResponse({ type: CreateOneResponse });
  createOne(@Body() body: CreateDogDto) {
    // code here...
    return super(body); //inherit (optional)
  }
}

Here are the method names for respective action.

| Action | One | Bulk | | ------ | ------------ | ------------ | | Create | createOne | createMany | | Read | findById | findMany | | Update | updateById | updateMany | | Delete | deleteById | deleteMany |

Services also:

//imports ...

@CrudInjectable({
  createDto: CreateDogDto,
  updateDto: UpdateDogDto,
  mongooseModel: Dog,
  filterQuery: UpdateDogDto,
}) // For Crud Service
export class DogsService extends CrudService {
  constructor(@InjectModel(Dog.name) dogModel: Model<DogDocument>) {
    super(dogModel);
  }

  feed() {
    //code here...
  }
}