├── .gitignore ├── .prettierrc ├── README.md ├── dist ├── app.module.d.ts ├── app.module.js ├── app.module.js.map ├── config │ ├── keys.d.ts │ ├── keys.js │ └── keys.js.map ├── main.d.ts ├── main.js ├── main.js.map ├── products │ ├── dto │ │ ├── create-product.dto.d.ts │ │ ├── create-product.dto.js │ │ └── create-product.dto.js.map │ ├── interfaces │ │ ├── product.interface.d.ts │ │ ├── product.interface.js │ │ └── product.interface.js.map │ ├── products.controller.d.ts │ ├── products.controller.js │ ├── products.controller.js.map │ ├── products.module.d.ts │ ├── products.module.js │ ├── products.module.js.map │ ├── products.service.d.ts │ ├── products.service.js │ ├── products.service.js.map │ └── schemas │ │ ├── product.schema.d.ts │ │ ├── product.schema.js │ │ └── product.schema.js.map └── tsconfig.build.tsbuildinfo ├── nest-cli.json ├── package-lock.json ├── package.json ├── src ├── app.module.ts ├── config │ └── keys.ts ├── main.ts └── products │ ├── dto │ └── create-product.dto.ts │ ├── interfaces │ └── product.interface.ts │ ├── products.controller.ts │ ├── products.module.ts │ ├── products.service.spec.ts │ ├── products.service.ts │ └── schemas │ └── product.schema.ts ├── test ├── app.e2e-spec.ts ├── jest-e2e.json └── utils │ └── db-test-module.ts ├── tsconfig.build.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NestJS REST API 2 | 3 | A CRUD REST API using the NestJS framework and MongoDB/Mongoose. 4 | 5 | ## Setup 6 | 7 | Create a `.env` file in the root of the project with your mongodb uri 8 | 9 | e.g. 10 | 11 | ``` 12 | DB_CONNECTION_STRING=mongodb+srv://:@/?retryWrites=true&w=majority 13 | ``` 14 | 15 | ## Installation 16 | 17 | ```bash 18 | $ npm install 19 | ``` 20 | 21 | ## Running the app 22 | 23 | ```bash 24 | # development 25 | $ npm run start 26 | 27 | # watch mode 28 | $ npm run start:dev 29 | 30 | # production mode 31 | $ npm run start:prod 32 | ``` 33 | -------------------------------------------------------------------------------- /dist/app.module.d.ts: -------------------------------------------------------------------------------- 1 | export declare class AppModule { 2 | } 3 | -------------------------------------------------------------------------------- /dist/app.module.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | Object.defineProperty(exports, "__esModule", { value: true }); 9 | exports.AppModule = void 0; 10 | const common_1 = require("@nestjs/common"); 11 | const mongoose_1 = require("@nestjs/mongoose"); 12 | const products_module_1 = require("./products/products.module"); 13 | const keys_1 = require("./config/keys"); 14 | let AppModule = class AppModule { 15 | }; 16 | AppModule = __decorate([ 17 | common_1.Module({ 18 | imports: [mongoose_1.MongooseModule.forRoot(keys_1.default.mongoURI), products_module_1.ProductsModule], 19 | }) 20 | ], AppModule); 21 | exports.AppModule = AppModule; 22 | //# sourceMappingURL=app.module.js.map -------------------------------------------------------------------------------- /dist/app.module.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,+CAAkD;AAClD,gEAA4D;AAC5D,wCAAmC;AAKnC,IAAa,SAAS,GAAtB,MAAa,SAAS;CAAG,CAAA;AAAZ,SAAS;IAHrB,eAAM,CAAC;QACN,OAAO,EAAE,CAAC,yBAAc,CAAC,OAAO,CAAC,cAAM,CAAC,QAAQ,CAAC,EAAE,gCAAc,CAAC;KACnE,CAAC;GACW,SAAS,CAAG;AAAZ,8BAAS"} -------------------------------------------------------------------------------- /dist/config/keys.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: { 2 | mongoURI: string; 3 | }; 4 | export default _default; 5 | -------------------------------------------------------------------------------- /dist/config/keys.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | require('dotenv').config(); 4 | exports.default = { 5 | mongoURI: process.env.DB_CONNECTION_STRING, 6 | }; 7 | //# sourceMappingURL=keys.js.map -------------------------------------------------------------------------------- /dist/config/keys.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/config/keys.ts"],"names":[],"mappings":";;AAAA,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;AAE3B,kBAAe;IACb,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;CAC3C,CAAC"} -------------------------------------------------------------------------------- /dist/main.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /dist/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const core_1 = require("@nestjs/core"); 4 | const app_module_1 = require("./app.module"); 5 | async function bootstrap() { 6 | const app = await core_1.NestFactory.create(app_module_1.AppModule); 7 | await app.listen(3000); 8 | console.log(`Application is running on: ${app.getUrl()}`); 9 | } 10 | bootstrap(); 11 | //# sourceMappingURL=main.js.map -------------------------------------------------------------------------------- /dist/main.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;AAAA,uCAA2C;AAC3C,6CAAyC;AAEzC,KAAK,UAAU,SAAS;IACtB,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,CAAC,CAAC;IAChD,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,8BAA8B,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC5D,CAAC;AACD,SAAS,EAAE,CAAC"} -------------------------------------------------------------------------------- /dist/products/dto/create-product.dto.d.ts: -------------------------------------------------------------------------------- 1 | export declare class CreateProductDto { 2 | readonly name: string; 3 | readonly description: string; 4 | readonly qty: number; 5 | } 6 | -------------------------------------------------------------------------------- /dist/products/dto/create-product.dto.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.CreateProductDto = void 0; 4 | class CreateProductDto { 5 | } 6 | exports.CreateProductDto = CreateProductDto; 7 | //# sourceMappingURL=create-product.dto.js.map -------------------------------------------------------------------------------- /dist/products/dto/create-product.dto.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"create-product.dto.js","sourceRoot":"","sources":["../../../src/products/dto/create-product.dto.ts"],"names":[],"mappings":";;;AAAA,MAAa,gBAAgB;CAI5B;AAJD,4CAIC"} -------------------------------------------------------------------------------- /dist/products/interfaces/product.interface.d.ts: -------------------------------------------------------------------------------- 1 | export interface Product { 2 | id?: string; 3 | name: string; 4 | description: string; 5 | qty: number; 6 | } 7 | -------------------------------------------------------------------------------- /dist/products/interfaces/product.interface.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | //# sourceMappingURL=product.interface.js.map -------------------------------------------------------------------------------- /dist/products/interfaces/product.interface.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"product.interface.js","sourceRoot":"","sources":["../../../src/products/interfaces/product.interface.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /dist/products/products.controller.d.ts: -------------------------------------------------------------------------------- 1 | import { CreateProductDto } from './dto/create-product.dto'; 2 | import { Product } from './interfaces/product.interface'; 3 | import { ProductsService } from './products.service'; 4 | export declare class ProductsController { 5 | private readonly productsService; 6 | constructor(productsService: ProductsService); 7 | findAll(): Promise; 8 | findOne(id: string): Promise; 9 | create(createProductDto: CreateProductDto): Promise; 10 | delete(id: string): Promise; 11 | update(id: string, updateProductDto: CreateProductDto): Promise; 12 | } 13 | -------------------------------------------------------------------------------- /dist/products/products.controller.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | var __metadata = (this && this.__metadata) || function (k, v) { 9 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 10 | }; 11 | var __param = (this && this.__param) || function (paramIndex, decorator) { 12 | return function (target, key) { decorator(target, key, paramIndex); } 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | exports.ProductsController = void 0; 16 | const common_1 = require("@nestjs/common"); 17 | const create_product_dto_1 = require("./dto/create-product.dto"); 18 | const products_service_1 = require("./products.service"); 19 | let ProductsController = class ProductsController { 20 | constructor(productsService) { 21 | this.productsService = productsService; 22 | } 23 | findAll() { 24 | return this.productsService.findAll(); 25 | } 26 | findOne(id) { 27 | return this.productsService.findOne(id); 28 | } 29 | create(createProductDto) { 30 | return this.productsService.create(createProductDto); 31 | } 32 | delete(id) { 33 | return this.productsService.delete(id); 34 | } 35 | update(id, updateProductDto) { 36 | return this.productsService.update(id, updateProductDto); 37 | } 38 | }; 39 | __decorate([ 40 | common_1.Get(), 41 | __metadata("design:type", Function), 42 | __metadata("design:paramtypes", []), 43 | __metadata("design:returntype", Promise) 44 | ], ProductsController.prototype, "findAll", null); 45 | __decorate([ 46 | common_1.Get(':id'), 47 | __param(0, common_1.Param('id')), 48 | __metadata("design:type", Function), 49 | __metadata("design:paramtypes", [String]), 50 | __metadata("design:returntype", Promise) 51 | ], ProductsController.prototype, "findOne", null); 52 | __decorate([ 53 | common_1.Post(), 54 | __param(0, common_1.Body()), 55 | __metadata("design:type", Function), 56 | __metadata("design:paramtypes", [create_product_dto_1.CreateProductDto]), 57 | __metadata("design:returntype", Promise) 58 | ], ProductsController.prototype, "create", null); 59 | __decorate([ 60 | common_1.Delete(':id'), 61 | __param(0, common_1.Param('id')), 62 | __metadata("design:type", Function), 63 | __metadata("design:paramtypes", [String]), 64 | __metadata("design:returntype", Promise) 65 | ], ProductsController.prototype, "delete", null); 66 | __decorate([ 67 | common_1.Put(':id'), 68 | __param(0, common_1.Param('id')), 69 | __param(1, common_1.Body()), 70 | __metadata("design:type", Function), 71 | __metadata("design:paramtypes", [String, create_product_dto_1.CreateProductDto]), 72 | __metadata("design:returntype", Promise) 73 | ], ProductsController.prototype, "update", null); 74 | ProductsController = __decorate([ 75 | common_1.Controller('products'), 76 | __metadata("design:paramtypes", [products_service_1.ProductsService]) 77 | ], ProductsController); 78 | exports.ProductsController = ProductsController; 79 | //# sourceMappingURL=products.controller.js.map -------------------------------------------------------------------------------- /dist/products/products.controller.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"products.controller.js","sourceRoot":"","sources":["../../src/products/products.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAQwB;AACxB,iEAA4D;AAE5D,yDAAqD;AAGrD,IAAa,kBAAkB,GAA/B,MAAa,kBAAkB;IAC7B,YAA6B,eAAgC;QAAhC,oBAAe,GAAf,eAAe,CAAiB;IAAG,CAAC;IAGjE,OAAO;QACL,OAAO,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;IACxC,CAAC;IAGD,OAAO,CAAc,EAAU;QAC7B,OAAO,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC;IAGD,MAAM,CAAS,gBAAkC;QAC/C,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACvD,CAAC;IAGD,MAAM,CAAc,EAAU;QAC5B,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC;IAGD,MAAM,CACS,EAAU,EACf,gBAAkC;QAE1C,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAC3D,CAAC;CACF,CAAA;AA1BC;IADC,YAAG,EAAE;;;;iDAGL;AAGD;IADC,YAAG,CAAC,KAAK,CAAC;IACF,WAAA,cAAK,CAAC,IAAI,CAAC,CAAA;;;;iDAEnB;AAGD;IADC,aAAI,EAAE;IACC,WAAA,aAAI,EAAE,CAAA;;qCAAmB,qCAAgB;;gDAEhD;AAGD;IADC,eAAM,CAAC,KAAK,CAAC;IACN,WAAA,cAAK,CAAC,IAAI,CAAC,CAAA;;;;gDAElB;AAGD;IADC,YAAG,CAAC,KAAK,CAAC;IAER,WAAA,cAAK,CAAC,IAAI,CAAC,CAAA;IACX,WAAA,aAAI,EAAE,CAAA;;6CAAmB,qCAAgB;;gDAG3C;AA7BU,kBAAkB;IAD9B,mBAAU,CAAC,UAAU,CAAC;qCAEyB,kCAAe;GADlD,kBAAkB,CA8B9B;AA9BY,gDAAkB"} -------------------------------------------------------------------------------- /dist/products/products.module.d.ts: -------------------------------------------------------------------------------- 1 | export declare class ProductsModule { 2 | } 3 | -------------------------------------------------------------------------------- /dist/products/products.module.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | Object.defineProperty(exports, "__esModule", { value: true }); 9 | exports.ProductsModule = void 0; 10 | const common_1 = require("@nestjs/common"); 11 | const mongoose_1 = require("@nestjs/mongoose"); 12 | const products_controller_1 = require("./products.controller"); 13 | const products_service_1 = require("./products.service"); 14 | const product_schema_1 = require("./schemas/product.schema"); 15 | let ProductsModule = class ProductsModule { 16 | }; 17 | ProductsModule = __decorate([ 18 | common_1.Module({ 19 | imports: [ 20 | mongoose_1.MongooseModule.forFeature([ 21 | { name: product_schema_1.ProductClass.name, schema: product_schema_1.ProductSchema }, 22 | ]), 23 | ], 24 | controllers: [products_controller_1.ProductsController], 25 | providers: [products_service_1.ProductsService], 26 | }) 27 | ], ProductsModule); 28 | exports.ProductsModule = ProductsModule; 29 | //# sourceMappingURL=products.module.js.map -------------------------------------------------------------------------------- /dist/products/products.module.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"products.module.js","sourceRoot":"","sources":["../../src/products/products.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,+CAAkD;AAClD,+DAA2D;AAC3D,yDAAqD;AACrD,6DAAuE;AAWvE,IAAa,cAAc,GAA3B,MAAa,cAAc;CAAG,CAAA;AAAjB,cAAc;IAT1B,eAAM,CAAC;QACN,OAAO,EAAE;YACP,yBAAc,CAAC,UAAU,CAAC;gBACxB,EAAE,IAAI,EAAE,6BAAY,CAAC,IAAI,EAAE,MAAM,EAAE,8BAAa,EAAE;aACnD,CAAC;SACH;QACD,WAAW,EAAE,CAAC,wCAAkB,CAAC;QACjC,SAAS,EAAE,CAAC,kCAAe,CAAC;KAC7B,CAAC;GACW,cAAc,CAAG;AAAjB,wCAAc"} -------------------------------------------------------------------------------- /dist/products/products.service.d.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'mongoose'; 2 | import { Product } from './interfaces/product.interface'; 3 | import { ProductClass } from './schemas/product.schema'; 4 | export declare class ProductsService { 5 | private productModel; 6 | constructor(productModel: Model); 7 | findAll(): Promise; 8 | findOne(id: string): Promise; 9 | create(product: Product): Promise; 10 | delete(id: string): Promise; 11 | update(id: string, product: Product): Promise; 12 | } 13 | -------------------------------------------------------------------------------- /dist/products/products.service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | var __metadata = (this && this.__metadata) || function (k, v) { 9 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 10 | }; 11 | var __param = (this && this.__param) || function (paramIndex, decorator) { 12 | return function (target, key) { decorator(target, key, paramIndex); } 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | exports.ProductsService = void 0; 16 | const mongoose_1 = require("mongoose"); 17 | const common_1 = require("@nestjs/common"); 18 | const mongoose_2 = require("@nestjs/mongoose"); 19 | let ProductsService = class ProductsService { 20 | constructor(productModel) { 21 | this.productModel = productModel; 22 | } 23 | async findAll() { 24 | return await this.productModel.find().exec(); 25 | } 26 | async findOne(id) { 27 | return await this.productModel.findOne({ _id: id }); 28 | } 29 | async create(product) { 30 | const newProduct = new this.productModel(product); 31 | return await newProduct.save(); 32 | } 33 | async delete(id) { 34 | return await this.productModel.findByIdAndRemove(id); 35 | } 36 | async update(id, product) { 37 | return await this.productModel.findByIdAndUpdate(id, product, { 38 | new: true, 39 | }); 40 | } 41 | }; 42 | ProductsService = __decorate([ 43 | common_1.Injectable(), 44 | __param(0, mongoose_2.InjectModel('Product')), 45 | __metadata("design:paramtypes", [mongoose_1.Model]) 46 | ], ProductsService); 47 | exports.ProductsService = ProductsService; 48 | //# sourceMappingURL=products.service.js.map -------------------------------------------------------------------------------- /dist/products/products.service.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"products.service.js","sourceRoot":"","sources":["../../src/products/products.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uCAAiC;AACjC,2CAA4C;AAC5C,+CAA+C;AAK/C,IAAa,eAAe,GAA5B,MAAa,eAAe;IAC1B,YAEU,YAAiC;QAAjC,iBAAY,GAAZ,YAAY,CAAqB;IACxC,CAAC;IAEJ,KAAK,CAAC,OAAO;QACX,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,EAAU;QACtB,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAgB;QAC3B,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,OAAgB;QACvC,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,EAAE,EAAE,OAAO,EAAE;YAC5D,GAAG,EAAE,IAAI;SACV,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AA5BY,eAAe;IAD3B,mBAAU,EAAE;IAGR,WAAA,sBAAW,CAAC,SAAS,CAAC,CAAA;qCACD,gBAAK;GAHlB,eAAe,CA4B3B;AA5BY,0CAAe"} -------------------------------------------------------------------------------- /dist/products/schemas/product.schema.d.ts: -------------------------------------------------------------------------------- 1 | import { Document } from 'mongoose'; 2 | export declare class ProductClass extends Document { 3 | name: string; 4 | qty: number; 5 | description: string; 6 | } 7 | export declare const ProductSchema: import("mongoose").Schema; 8 | -------------------------------------------------------------------------------- /dist/products/schemas/product.schema.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | var __metadata = (this && this.__metadata) || function (k, v) { 9 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 10 | }; 11 | Object.defineProperty(exports, "__esModule", { value: true }); 12 | exports.ProductSchema = exports.ProductClass = void 0; 13 | const mongoose_1 = require("@nestjs/mongoose"); 14 | const mongoose_2 = require("mongoose"); 15 | let ProductClass = class ProductClass extends mongoose_2.Document { 16 | }; 17 | __decorate([ 18 | mongoose_1.Prop(), 19 | __metadata("design:type", String) 20 | ], ProductClass.prototype, "name", void 0); 21 | __decorate([ 22 | mongoose_1.Prop(), 23 | __metadata("design:type", Number) 24 | ], ProductClass.prototype, "qty", void 0); 25 | __decorate([ 26 | mongoose_1.Prop(), 27 | __metadata("design:type", String) 28 | ], ProductClass.prototype, "description", void 0); 29 | ProductClass = __decorate([ 30 | mongoose_1.Schema() 31 | ], ProductClass); 32 | exports.ProductClass = ProductClass; 33 | exports.ProductSchema = mongoose_1.SchemaFactory.createForClass(ProductClass); 34 | //# sourceMappingURL=product.schema.js.map -------------------------------------------------------------------------------- /dist/products/schemas/product.schema.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"product.schema.js","sourceRoot":"","sources":["../../../src/products/schemas/product.schema.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+CAA+D;AAC/D,uCAAoC;AAGpC,IAAa,YAAY,GAAzB,MAAa,YAAa,SAAQ,mBAAQ;CASzC,CAAA;AAPC;IADC,eAAI,EAAE;;0CACM;AAGb;IADC,eAAI,EAAE;;yCACK;AAGZ;IADC,eAAI,EAAE;;iDACa;AART,YAAY;IADxB,iBAAM,EAAE;GACI,YAAY,CASxB;AATY,oCAAY;AAWZ,QAAA,aAAa,GAAG,wBAAa,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC"} -------------------------------------------------------------------------------- /nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "collection": "@nestjs/schematics", 3 | "sourceRoot": "src" 4 | } 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "project-name", 3 | "version": "0.0.1", 4 | "description": "", 5 | "author": "", 6 | "private": true, 7 | "license": "UNLICENSED", 8 | "scripts": { 9 | "prebuild": "rimraf dist", 10 | "build": "nest build", 11 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 12 | "start": "nest start", 13 | "start:dev": "nest start --watch", 14 | "start:debug": "nest start --debug --watch", 15 | "start:prod": "node dist/main", 16 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", 17 | "test": "jest", 18 | "test:watch": "jest --watch", 19 | "test:cov": "jest --coverage", 20 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 21 | "test:e2e": "jest --config ./test/jest-e2e.json" 22 | }, 23 | "dependencies": { 24 | "@nestjs/common": "^7.0.0", 25 | "@nestjs/core": "^7.0.0", 26 | "@nestjs/mongoose": "^7.0.2", 27 | "@nestjs/platform-express": "^7.0.0", 28 | "dotenv": "^8.2.0", 29 | "mongoose": "^5.9.26", 30 | "reflect-metadata": "^0.1.13", 31 | "rimraf": "^3.0.2", 32 | "rxjs": "^6.5.4" 33 | }, 34 | "devDependencies": { 35 | "@nestjs/cli": "^7.0.0", 36 | "@nestjs/schematics": "^7.0.0", 37 | "@nestjs/testing": "^7.0.0", 38 | "@types/express": "^4.17.3", 39 | "@types/jest": "25.2.3", 40 | "@types/mongoose": "^5.7.34", 41 | "@types/node": "^13.9.1", 42 | "@types/supertest": "^2.0.8", 43 | "@typescript-eslint/eslint-plugin": "3.0.2", 44 | "@typescript-eslint/parser": "3.0.2", 45 | "eslint": "7.1.0", 46 | "eslint-config-prettier": "^6.10.0", 47 | "eslint-plugin-import": "^2.20.1", 48 | "jest": "26.0.1", 49 | "mongodb-memory-server": "^6.6.3", 50 | "prettier": "^1.19.1", 51 | "supertest": "^4.0.2", 52 | "ts-jest": "26.1.0", 53 | "ts-loader": "^6.2.1", 54 | "ts-node": "^8.6.2", 55 | "tsconfig-paths": "^3.9.0", 56 | "typescript": "^3.7.4" 57 | }, 58 | "jest": { 59 | "moduleFileExtensions": [ 60 | "js", 61 | "json", 62 | "ts" 63 | ], 64 | "rootDir": "src", 65 | "testRegex": ".spec.ts$", 66 | "transform": { 67 | "^.+\\.(t|j)s$": "ts-jest" 68 | }, 69 | "coverageDirectory": "../coverage", 70 | "testEnvironment": "node" 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { MongooseModule } from '@nestjs/mongoose'; 3 | import { ProductsModule } from './products/products.module'; 4 | import config from './config/keys'; 5 | 6 | @Module({ 7 | imports: [MongooseModule.forRoot(config.mongoURI), ProductsModule], 8 | }) 9 | export class AppModule {} 10 | -------------------------------------------------------------------------------- /src/config/keys.ts: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | 3 | export default { 4 | mongoURI: process.env.DB_CONNECTION_STRING, 5 | }; 6 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core'; 2 | import { AppModule } from './app.module'; 3 | 4 | async function bootstrap() { 5 | const app = await NestFactory.create(AppModule); 6 | await app.listen(3000); 7 | console.log(`Application is running on: ${await app.getUrl()}`); 8 | } 9 | bootstrap(); 10 | -------------------------------------------------------------------------------- /src/products/dto/create-product.dto.ts: -------------------------------------------------------------------------------- 1 | export class CreateProductDto { 2 | readonly name: string; 3 | readonly description: string; 4 | readonly qty: number; 5 | } 6 | -------------------------------------------------------------------------------- /src/products/interfaces/product.interface.ts: -------------------------------------------------------------------------------- 1 | export interface Product { 2 | id?: string; 3 | name: string; 4 | description: string; 5 | qty: number; 6 | } 7 | -------------------------------------------------------------------------------- /src/products/products.controller.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Controller, 3 | Get, 4 | Post, 5 | Put, 6 | Delete, 7 | Body, 8 | Param, 9 | } from '@nestjs/common'; 10 | import { CreateProductDto } from './dto/create-product.dto'; 11 | import { Product } from './interfaces/product.interface'; 12 | import { ProductsService } from './products.service'; 13 | 14 | @Controller('products') 15 | export class ProductsController { 16 | constructor(private readonly productsService: ProductsService) {} 17 | 18 | @Get() 19 | findAll(): Promise { 20 | return this.productsService.findAll(); 21 | } 22 | 23 | @Get(':id') 24 | findOne(@Param('id') id: string): Promise { 25 | return this.productsService.findOne(id); 26 | } 27 | 28 | @Post() 29 | create(@Body() createProductDto: CreateProductDto): Promise { 30 | return this.productsService.create(createProductDto); 31 | } 32 | 33 | @Delete(':id') 34 | delete(@Param('id') id: string): Promise { 35 | return this.productsService.delete(id); 36 | } 37 | 38 | @Put(':id') 39 | update( 40 | @Param('id') id: string, 41 | @Body() updateProductDto: CreateProductDto, 42 | ): Promise { 43 | return this.productsService.update(id, updateProductDto); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/products/products.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { MongooseModule } from '@nestjs/mongoose'; 3 | import { ProductsController } from './products.controller'; 4 | import { ProductsService } from './products.service'; 5 | import { ProductClass, ProductSchema } from './schemas/product.schema'; 6 | 7 | @Module({ 8 | imports: [ 9 | MongooseModule.forFeature([ 10 | { name: ProductClass.name, schema: ProductSchema }, 11 | ]), 12 | ], 13 | controllers: [ProductsController], 14 | providers: [ProductsService], 15 | }) 16 | export class ProductsModule {} 17 | -------------------------------------------------------------------------------- /src/products/products.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { ProductsService } from './products.service'; 3 | import { MongooseModule, getConnectionToken } from '@nestjs/mongoose'; 4 | import { Connection } from 'mongoose'; 5 | import { ProductClass, ProductSchema } from './schemas/product.schema'; 6 | import DbModule, { 7 | closeMongoConnection, 8 | } from '../../test/utils/db-test-module'; 9 | 10 | describe('ProductService', () => { 11 | let service: ProductsService; 12 | let connection: Connection; 13 | 14 | beforeEach(async () => { 15 | const module: TestingModule = await Test.createTestingModule({ 16 | imports: [ 17 | DbModule({ 18 | connectionName: (new Date().getTime() * Math.random()).toString(16), 19 | }), 20 | MongooseModule.forFeature([ 21 | { name: ProductClass.name, schema: ProductSchema }, 22 | ]), 23 | ], 24 | providers: [ProductsService], 25 | }).compile(); 26 | 27 | service = module.get(ProductsService); 28 | connection = await module.get(getConnectionToken()); 29 | }); 30 | 31 | afterEach(async () => { 32 | await connection.close(); 33 | await closeMongoConnection(); 34 | }); 35 | 36 | it('should be defined', async () => { 37 | expect(service).toBeDefined(); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /src/products/products.service.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'mongoose'; 2 | import { Injectable } from '@nestjs/common'; 3 | import { InjectModel } from '@nestjs/mongoose'; 4 | import { Product } from './interfaces/product.interface'; 5 | import { ProductClass } from './schemas/product.schema'; 6 | 7 | @Injectable() 8 | export class ProductsService { 9 | constructor( 10 | @InjectModel(ProductClass.name) 11 | private productModel: Model, 12 | ) {} 13 | 14 | async findAll(): Promise { 15 | return await this.productModel.find().exec(); 16 | } 17 | 18 | async findOne(id: string): Promise { 19 | return await this.productModel.findOne({ _id: id }); 20 | } 21 | 22 | async create(product: Product): Promise { 23 | const newProduct = new this.productModel(product); 24 | return await newProduct.save(); 25 | } 26 | 27 | async delete(id: string): Promise { 28 | return await this.productModel.findByIdAndRemove(id); 29 | } 30 | 31 | async update(id: string, product: Product): Promise { 32 | return await this.productModel.findByIdAndUpdate(id, product, { 33 | new: true, 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/products/schemas/product.schema.ts: -------------------------------------------------------------------------------- 1 | import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; 2 | import { Document } from 'mongoose'; 3 | 4 | @Schema() 5 | export class ProductClass extends Document { 6 | @Prop() 7 | name: string; 8 | 9 | @Prop() 10 | qty: number; 11 | 12 | @Prop() 13 | description: string; 14 | } 15 | 16 | export const ProductSchema = SchemaFactory.createForClass(ProductClass); 17 | -------------------------------------------------------------------------------- /test/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { INestApplication } from '@nestjs/common'; 3 | import * as request from 'supertest'; 4 | import { AppModule } from './../src/app.module'; 5 | 6 | describe('AppController (e2e)', () => { 7 | let app: INestApplication; 8 | 9 | beforeEach(async () => { 10 | const moduleFixture: TestingModule = await Test.createTestingModule({ 11 | imports: [AppModule], 12 | }).compile(); 13 | 14 | app = moduleFixture.createNestApplication(); 15 | await app.init(); 16 | }); 17 | 18 | it('/ (GET)', () => { 19 | return request(app.getHttpServer()) 20 | .get('/products') 21 | .expect(200) 22 | .expect('[]'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /test/jest-e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "moduleFileExtensions": ["js", "json", "ts"], 3 | "rootDir": ".", 4 | "testEnvironment": "node", 5 | "testRegex": ".e2e-spec.ts$", 6 | "transform": { 7 | "^.+\\.(t|j)s$": "ts-jest" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/utils/db-test-module.ts: -------------------------------------------------------------------------------- 1 | import { MongooseModule, MongooseModuleOptions } from '@nestjs/mongoose'; 2 | import { MongoMemoryServer } from 'mongodb-memory-server'; 3 | 4 | let mongod: MongoMemoryServer; 5 | 6 | export default (customOpts: MongooseModuleOptions = {}) => 7 | MongooseModule.forRootAsync({ 8 | useFactory: async () => { 9 | mongod = new MongoMemoryServer(); 10 | const uri = await mongod.getUri(); 11 | return { 12 | uri, 13 | ...customOpts, 14 | }; 15 | }, 16 | }); 17 | 18 | export const closeMongoConnection = async () => { 19 | if (mongod) await mongod.stop(); 20 | }; 21 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "es2017", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true 14 | } 15 | } 16 | --------------------------------------------------------------------------------