├── LICENSE ├── README.md ├── employee-gql-service-nest8 ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── README.md ├── nest-cli.json ├── package-lock.json ├── package.json ├── src │ ├── app.module.ts │ ├── employee │ │ ├── dto │ │ │ └── create-employee.input.ts │ │ ├── employee.module.ts │ │ ├── employee.resolver.ts │ │ ├── employee.service.ts │ │ └── entity │ │ │ └── employee.entity.ts │ ├── graphql-schema.gql │ ├── main.ts │ └── project │ │ ├── dto │ │ ├── create-project.input.ts │ │ └── update-project.input.ts │ │ ├── entity │ │ └── project.entity.ts │ │ ├── project.module.ts │ │ ├── project.resolver.ts │ │ └── project.service.ts ├── test │ ├── app.e2e-spec.ts │ └── jest-e2e.json ├── tsconfig.build.json └── tsconfig.json └── employee-gql-service ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── README.md ├── nest-cli.json ├── package-lock.json ├── package.json ├── src ├── app.controller.spec.ts ├── app.module.ts ├── employee │ ├── dto │ │ └── create-employee.input.ts │ ├── employee.module.ts │ ├── employee.resolver.ts │ ├── employee.service.ts │ └── entities │ │ └── employee.entity.ts ├── graphql-schema.gql ├── main.ts └── project │ ├── dto │ ├── create-project.input.ts │ └── update-project.input.ts │ ├── entities │ └── project.entity.ts │ ├── project.module.ts │ ├── project.resolver.ts │ └── project.service.ts ├── test ├── app.e2e-spec.ts └── jest-e2e.json ├── tsconfig.build.json └── tsconfig.json /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nestjs-graphql-course-youtube 2 | This is source project of this tutorial. https://youtu.be/_PVA98-ooWA 3 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | sourceType: 'module', 6 | }, 7 | plugins: ['@typescript-eslint/eslint-plugin'], 8 | extends: [ 9 | 'plugin:@typescript-eslint/recommended', 10 | 'plugin:prettier/recommended', 11 | ], 12 | root: true, 13 | env: { 14 | node: true, 15 | jest: true, 16 | }, 17 | ignorePatterns: ['.eslintrc.js'], 18 | rules: { 19 | '@typescript-eslint/interface-name-prefix': 'off', 20 | '@typescript-eslint/explicit-function-return-type': 'off', 21 | '@typescript-eslint/explicit-module-boundary-types': 'off', 22 | '@typescript-eslint/no-explicit-any': 'off', 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | 13 | # OS 14 | .DS_Store 15 | 16 | # Tests 17 | /coverage 18 | /.nyc_output 19 | 20 | # IDEs and editors 21 | /.idea 22 | .project 23 | .classpath 24 | .c9/ 25 | *.launch 26 | .settings/ 27 | *.sublime-workspace 28 | 29 | # IDE - VSCode 30 | .vscode/* 31 | !.vscode/settings.json 32 | !.vscode/tasks.json 33 | !.vscode/launch.json 34 | !.vscode/extensions.json -------------------------------------------------------------------------------- /employee-gql-service-nest8/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /employee-gql-service-nest8/README.md: -------------------------------------------------------------------------------- 1 |

2 | Nest Logo 3 |

4 | 5 | [circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456 6 | [circleci-url]: https://circleci.com/gh/nestjs/nest 7 | 8 |

A progressive Node.js framework for building efficient and scalable server-side applications.

9 |

10 | NPM Version 11 | Package License 12 | NPM Downloads 13 | CircleCI 14 | Coverage 15 | Discord 16 | Backers on Open Collective 17 | Sponsors on Open Collective 18 | 19 | Support us 20 | 21 |

22 | 24 | 25 | ## Description 26 | 27 | [Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. 28 | 29 | ## Installation 30 | 31 | ```bash 32 | $ npm install 33 | ``` 34 | 35 | ## Running the app 36 | 37 | ```bash 38 | # development 39 | $ npm run start 40 | 41 | # watch mode 42 | $ npm run start:dev 43 | 44 | # production mode 45 | $ npm run start:prod 46 | ``` 47 | 48 | ## Test 49 | 50 | ```bash 51 | # unit tests 52 | $ npm run test 53 | 54 | # e2e tests 55 | $ npm run test:e2e 56 | 57 | # test coverage 58 | $ npm run test:cov 59 | ``` 60 | 61 | ## Support 62 | 63 | Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). 64 | 65 | ## Stay in touch 66 | 67 | - Author - [Kamil Myśliwiec](https://kamilmysliwiec.com) 68 | - Website - [https://nestjs.com](https://nestjs.com/) 69 | - Twitter - [@nestframework](https://twitter.com/nestframework) 70 | 71 | ## License 72 | 73 | Nest is [MIT licensed](LICENSE). 74 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "collection": "@nestjs/schematics", 3 | "sourceRoot": "src" 4 | } 5 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "employee-gql-service-nest8", 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": "^8.0.0", 25 | "@nestjs/core": "^8.0.0", 26 | "@nestjs/graphql": "^8.0.2", 27 | "@nestjs/platform-express": "^8.0.0", 28 | "@nestjs/typeorm": "^8.0.1", 29 | "apollo-server-express": "^2.25.2", 30 | "graphql": "^15.5.1", 31 | "graphql-tools": "^7.0.5", 32 | "pg": "^8.6.0", 33 | "reflect-metadata": "^0.1.13", 34 | "rimraf": "^3.0.2", 35 | "rxjs": "^7.2.0", 36 | "typeorm": "^0.2.34" 37 | }, 38 | "devDependencies": { 39 | "@nestjs/cli": "^8.0.0", 40 | "@nestjs/schematics": "^8.0.0", 41 | "@nestjs/testing": "^8.0.0", 42 | "@types/express": "^4.17.13", 43 | "@types/jest": "^26.0.24", 44 | "@types/node": "^16.0.0", 45 | "@types/supertest": "^2.0.11", 46 | "@typescript-eslint/eslint-plugin": "^4.28.2", 47 | "@typescript-eslint/parser": "^4.28.2", 48 | "eslint": "^7.30.0", 49 | "eslint-config-prettier": "^8.3.0", 50 | "eslint-plugin-prettier": "^3.4.0", 51 | "jest": "27.0.6", 52 | "prettier": "^2.3.2", 53 | "supertest": "^6.1.3", 54 | "ts-jest": "^27.0.3", 55 | "ts-loader": "^9.2.3", 56 | "ts-node": "^10.0.0", 57 | "tsconfig-paths": "^3.10.1", 58 | "typescript": "^4.3.5" 59 | }, 60 | "jest": { 61 | "moduleFileExtensions": [ 62 | "js", 63 | "json", 64 | "ts" 65 | ], 66 | "rootDir": "src", 67 | "testRegex": ".*\\.spec\\.ts$", 68 | "transform": { 69 | "^.+\\.(t|j)s$": "ts-jest" 70 | }, 71 | "collectCoverageFrom": [ 72 | "**/*.(t|j)s" 73 | ], 74 | "coverageDirectory": "../coverage", 75 | "testEnvironment": "node" 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { EmployeeModule } from './employee/employee.module'; 3 | import { ProjectModule } from './project/project.module'; 4 | import { GraphQLModule } from '@nestjs/graphql'; 5 | import { TypeOrmModule } from '@nestjs/typeorm'; 6 | import { join } from 'path'; 7 | 8 | @Module({ 9 | imports: [EmployeeModule, ProjectModule,GraphQLModule.forRoot( 10 | { 11 | autoSchemaFile: join(process.cwd(), 'src/graphql-schema.gql') 12 | } 13 | ), 14 | TypeOrmModule.forRoot({ 15 | type: 'postgres', 16 | host: '192.168.1.6', 17 | port: 5432, 18 | username: 'nairobi', 19 | password: '1qazxsw2#', 20 | database: 'employee', 21 | entities: ["dist/**/*.entity{.ts,.js}"], 22 | synchronize: true, 23 | }),], 24 | controllers: [], 25 | providers: [], 26 | }) 27 | export class AppModule {} 28 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/employee/dto/create-employee.input.ts: -------------------------------------------------------------------------------- 1 | import { Field, InputType } from "@nestjs/graphql" 2 | 3 | @InputType() 4 | export class EmployeeCreateDTO { 5 | @Field() 6 | firstName: string 7 | @Field() 8 | lastName: string 9 | @Field() 10 | designation: string 11 | @Field({ nullable: true }) 12 | city: string 13 | 14 | @Field() 15 | projectId: string 16 | } -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/employee/employee.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { EmployeeService } from './employee.service'; 3 | import { EmployeeResolver } from './employee.resolver'; 4 | import { TypeOrmModule } from '@nestjs/typeorm'; 5 | import { Employee } from './entity/employee.entity'; 6 | import { ProjectModule } from 'src/project/project.module'; 7 | 8 | @Module({ 9 | imports: [TypeOrmModule.forFeature([Employee]), ProjectModule], 10 | providers: [EmployeeService, EmployeeResolver] 11 | }) 12 | export class EmployeeModule {} 13 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/employee/employee.resolver.ts: -------------------------------------------------------------------------------- 1 | import { } from '@nestjs/graphql'; 2 | import { Resolver, Query, Mutation, Args, ResolveField, Parent } from '@nestjs/graphql'; 3 | import { Project } from 'src/project/entity/project.entity'; 4 | import { EmployeeCreateDTO } from './dto/create-employee.input'; 5 | import { EmployeeService } from './employee.service'; 6 | import { Employee } from './entity/employee.entity' 7 | @Resolver(() => Employee) 8 | export class EmployeeResolver { 9 | constructor(private employeeService: EmployeeService) { } 10 | 11 | @Query(() => [Employee], { name: "getAllEmployees" }) 12 | findAll() { 13 | return this.employeeService.findAll(); 14 | } 15 | 16 | @Mutation(() => Employee, { name: "createEmployee" }) 17 | create(@Args('employeeInput') employee: EmployeeCreateDTO) { 18 | return this.employeeService.create(employee) 19 | } 20 | @Query(() => Employee) 21 | findOne(@Args("id") id: string) { 22 | return this.employeeService.findOne(id) 23 | } 24 | 25 | 26 | 27 | @ResolveField(() => Project) 28 | project(@Parent() employee: Employee) { 29 | return this.employeeService.getProject(employee.projectId) 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/employee/employee.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { InjectRepository } from '@nestjs/typeorm'; 3 | import { Project } from 'src/project/entity/project.entity'; 4 | import { ProjectModule } from 'src/project/project.module'; 5 | import { ProjectService } from 'src/project/project.service'; 6 | import { Repository } from 'typeorm'; 7 | import { EmployeeCreateDTO } from './dto/create-employee.input'; 8 | import { Employee } from './entity/employee.entity'; 9 | 10 | @Injectable() 11 | export class EmployeeService { 12 | 13 | constructor(@InjectRepository(Employee) private employeeRepository: Repository, 14 | private projectService: ProjectService) { 15 | 16 | } 17 | 18 | async findAll(): Promise { 19 | return this.employeeRepository.find(); 20 | } 21 | async findOne(id: string) { 22 | return this.employeeRepository.findOne(id) 23 | } 24 | 25 | async create(employee: EmployeeCreateDTO): Promise { 26 | 27 | let emp = this.employeeRepository.create(employee); 28 | return this.employeeRepository.save(emp) 29 | 30 | } 31 | 32 | async getProject(id: string): Promise { 33 | return this.projectService.findOne(id) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/employee/entity/employee.entity.ts: -------------------------------------------------------------------------------- 1 | import { Field, ObjectType } from "@nestjs/graphql" 2 | import { Project } from "src/project/entity/project.entity" 3 | import { Column, Entity, ManyToOne, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm" 4 | 5 | @ObjectType() 6 | @Entity() 7 | export class Employee { 8 | @Field() 9 | @PrimaryGeneratedColumn('uuid') 10 | id: string 11 | @Field() 12 | @Column() 13 | firstName: string 14 | @Field() 15 | @Column() 16 | lastName: string 17 | @Field() 18 | @Column() 19 | designation: string 20 | @Field({ nullable: true }) 21 | @Column({ nullable: true }) 22 | city: string 23 | 24 | @ManyToOne(() => Project, project => project.employees) 25 | @Field(() => Project) 26 | project: Project 27 | 28 | @Column() 29 | @Field() 30 | projectId: string 31 | 32 | } -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/graphql-schema.gql: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------ 2 | # THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY) 3 | # ------------------------------------------------------ 4 | 5 | type Employee { 6 | id: String! 7 | firstName: String! 8 | lastName: String! 9 | designation: String! 10 | city: String 11 | project: Project! 12 | projectId: String! 13 | } 14 | 15 | type Project { 16 | id: String! 17 | name: String! 18 | code: Int! 19 | employees: [Employee!] 20 | } 21 | 22 | type Query { 23 | getAllEmployees: [Employee!]! 24 | findOne(id: String!): Employee! 25 | getAllProjects: [Project!]! 26 | project(id: String!): Project! 27 | } 28 | 29 | type Mutation { 30 | createEmployee(employeeInput: EmployeeCreateDTO!): Employee! 31 | createProject(project: CreateProjectInput!): Project! 32 | updateProject(project: UpdateProjectInput!): Project! 33 | removeProject(id: String!): Project! 34 | } 35 | 36 | input EmployeeCreateDTO { 37 | firstName: String! 38 | lastName: String! 39 | designation: String! 40 | city: String 41 | projectId: String! 42 | } 43 | 44 | input CreateProjectInput { 45 | name: String! 46 | code: Int! 47 | } 48 | 49 | input UpdateProjectInput { 50 | id: String! 51 | name: String! 52 | code: Int! 53 | } 54 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/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 | } 8 | bootstrap(); 9 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/project/dto/create-project.input.ts: -------------------------------------------------------------------------------- 1 | import { InputType, Int, Field } from '@nestjs/graphql'; 2 | 3 | @InputType() 4 | export class CreateProjectInput { 5 | 6 | 7 | @Field() 8 | name: string 9 | @Field(() => Int) 10 | code: number 11 | } -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/project/dto/update-project.input.ts: -------------------------------------------------------------------------------- 1 | import { CreateProjectInput } from './create-project.input'; 2 | import { InputType, Field, Int, PartialType } from '@nestjs/graphql'; 3 | 4 | @InputType() 5 | export class UpdateProjectInput { 6 | 7 | @Field() 8 | id: string 9 | @Field() 10 | name: string 11 | @Field(() => Int) 12 | code: number 13 | 14 | 15 | } -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/project/entity/project.entity.ts: -------------------------------------------------------------------------------- 1 | import { ObjectType, Field, Int } from '@nestjs/graphql'; 2 | import { Employee } from 'src/employee/entity/employee.entity'; 3 | import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; 4 | 5 | @ObjectType() 6 | @Entity() 7 | export class Project { 8 | 9 | @Field() 10 | @PrimaryGeneratedColumn('uuid') 11 | id: string 12 | @Field() 13 | @Column() 14 | name: string 15 | @Field(() => Int) 16 | @Column() 17 | code: number 18 | 19 | @OneToMany(() => Employee, employee => employee.project) 20 | @Field(() => [Employee], { nullable: true }) 21 | employees: Employee[] 22 | 23 | } -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/project/project.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { ProjectService } from './project.service'; 3 | import { ProjectResolver } from './project.resolver'; 4 | import { TypeOrmModule } from '@nestjs/typeorm'; 5 | import { Project } from './entity/project.entity'; 6 | 7 | @Module({ 8 | imports: [TypeOrmModule.forFeature([Project])], 9 | providers: [ProjectResolver, ProjectService], 10 | exports: [ProjectService] 11 | }) 12 | export class ProjectModule { } -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/project/project.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql'; 2 | import { ProjectService } from './project.service'; 3 | import { Project } from './entity/project.entity'; 4 | import { CreateProjectInput } from './dto/create-project.input'; 5 | import { UpdateProjectInput } from './dto/update-project.input'; 6 | 7 | @Resolver(() => Project) 8 | export class ProjectResolver { 9 | constructor(private readonly projectService: ProjectService) { } 10 | 11 | @Mutation(() => Project) 12 | createProject(@Args('project') project: CreateProjectInput) { 13 | return this.projectService.create(project); 14 | } 15 | 16 | @Query(() => [Project], { name: 'getAllProjects' }) 17 | findAll() { 18 | return this.projectService.findAll(); 19 | } 20 | 21 | @Query(() => Project, { name: 'project' }) 22 | findOne(@Args('id') id: string) { 23 | return this.projectService.findOne(id); 24 | } 25 | 26 | @Mutation(() => Project) 27 | updateProject(@Args('project') project: UpdateProjectInput) { 28 | return this.projectService.update(project.id, project); 29 | } 30 | 31 | @Mutation(() => Project) 32 | removeProject(@Args('id') id: string) { 33 | return this.projectService.remove(id); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/src/project/project.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, NotFoundException } from '@nestjs/common'; 2 | import { InjectRepository } from '@nestjs/typeorm'; 3 | import { Repository } from 'typeorm'; 4 | import { CreateProjectInput } from './dto/create-project.input'; 5 | import { UpdateProjectInput } from './dto/update-project.input'; 6 | import { Project } from './entity/project.entity'; 7 | 8 | @Injectable() 9 | export class ProjectService { 10 | 11 | constructor(@InjectRepository(Project) private projectRepository: Repository) { } 12 | 13 | create(project: CreateProjectInput): Promise { 14 | let proj = this.projectRepository.create(project); 15 | return this.projectRepository.save(proj) //you can directly use this without create. depends on DTO. this explained in video 16 | 17 | } 18 | 19 | async findAll(): Promise { 20 | return this.projectRepository.find({ 21 | relations: ["employees"] 22 | }); 23 | } 24 | 25 | async findOne(id: string): Promise { 26 | return this.projectRepository.findOne(id, { relations: ["employees"] }); 27 | } 28 | 29 | update(id: string, updateProjectInput: UpdateProjectInput) { 30 | let project: Project = this.projectRepository.create(updateProjectInput) 31 | project.id = id; 32 | return this.projectRepository.save(project) 33 | } 34 | 35 | async remove(id: string) { 36 | let proj = this.findOne(id) 37 | if (proj) { 38 | let ret = await this.projectRepository.delete(id) 39 | if (ret.affected === 1) { 40 | return proj; 41 | } 42 | } 43 | throw new NotFoundException(`Record cannot find by id ${id}`) 44 | } 45 | } -------------------------------------------------------------------------------- /employee-gql-service-nest8/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('/') 21 | .expect(200) 22 | .expect('Hello World!'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/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 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /employee-gql-service-nest8/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 | "skipLibCheck": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /employee-gql-service/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | sourceType: 'module', 6 | }, 7 | plugins: ['@typescript-eslint/eslint-plugin'], 8 | extends: [ 9 | 'plugin:@typescript-eslint/recommended', 10 | 'plugin:prettier/recommended', 11 | ], 12 | root: true, 13 | env: { 14 | node: true, 15 | jest: true, 16 | }, 17 | ignorePatterns: ['.eslintrc.js'], 18 | rules: { 19 | '@typescript-eslint/interface-name-prefix': 'off', 20 | '@typescript-eslint/explicit-function-return-type': 'off', 21 | '@typescript-eslint/explicit-module-boundary-types': 'off', 22 | '@typescript-eslint/no-explicit-any': 'off', 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /employee-gql-service/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | 13 | # OS 14 | .DS_Store 15 | 16 | # Tests 17 | /coverage 18 | /.nyc_output 19 | 20 | # IDEs and editors 21 | /.idea 22 | .project 23 | .classpath 24 | .c9/ 25 | *.launch 26 | .settings/ 27 | *.sublime-workspace 28 | 29 | # IDE - VSCode 30 | .vscode/* 31 | !.vscode/settings.json 32 | !.vscode/tasks.json 33 | !.vscode/launch.json 34 | !.vscode/extensions.json -------------------------------------------------------------------------------- /employee-gql-service/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /employee-gql-service/README.md: -------------------------------------------------------------------------------- 1 |

2 | Nest Logo 3 |

4 | 5 | [circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456 6 | [circleci-url]: https://circleci.com/gh/nestjs/nest 7 | 8 |

A progressive Node.js framework for building efficient and scalable server-side applications.

9 |

10 | NPM Version 11 | Package License 12 | NPM Downloads 13 | CircleCI 14 | Coverage 15 | Discord 16 | Backers on Open Collective 17 | Sponsors on Open Collective 18 | 19 | Support us 20 | 21 |

22 | 24 | 25 | ## Description 26 | 27 | [Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. 28 | 29 | ## Installation 30 | 31 | ```bash 32 | $ npm install 33 | ``` 34 | 35 | ## Running the app 36 | 37 | ```bash 38 | # development 39 | $ npm run start 40 | 41 | # watch mode 42 | $ npm run start:dev 43 | 44 | # production mode 45 | $ npm run start:prod 46 | ``` 47 | 48 | ## Test 49 | 50 | ```bash 51 | # unit tests 52 | $ npm run test 53 | 54 | # e2e tests 55 | $ npm run test:e2e 56 | 57 | # test coverage 58 | $ npm run test:cov 59 | ``` 60 | 61 | ## Support 62 | 63 | Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). 64 | 65 | ## Stay in touch 66 | 67 | - Author - [Kamil Myśliwiec](https://kamilmysliwiec.com) 68 | - Website - [https://nestjs.com](https://nestjs.com/) 69 | - Twitter - [@nestframework](https://twitter.com/nestframework) 70 | 71 | ## License 72 | 73 | Nest is [MIT licensed](LICENSE). 74 | -------------------------------------------------------------------------------- /employee-gql-service/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "collection": "@nestjs/schematics", 3 | "sourceRoot": "src" 4 | } 5 | -------------------------------------------------------------------------------- /employee-gql-service/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "employee-gql-service", 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.6.15", 25 | "@nestjs/core": "^7.6.15", 26 | "@nestjs/graphql": "^7.10.6", 27 | "@nestjs/platform-express": "^7.6.15", 28 | "@nestjs/typeorm": "^7.1.5", 29 | "apollo-server-express": "^2.24.1", 30 | "graphql": "^15.5.0", 31 | "graphql-tools": "^7.0.5", 32 | "pg": "^8.6.0", 33 | "reflect-metadata": "^0.1.13", 34 | "rimraf": "^3.0.2", 35 | "rxjs": "^6.6.6", 36 | "typeorm": "^0.2.32" 37 | }, 38 | "devDependencies": { 39 | "@nestjs/cli": "^7.6.0", 40 | "@nestjs/schematics": "^7.3.0", 41 | "@nestjs/testing": "^7.6.15", 42 | "@types/express": "^4.17.11", 43 | "@types/jest": "^26.0.22", 44 | "@types/node": "^14.14.36", 45 | "@types/supertest": "^2.0.10", 46 | "@typescript-eslint/eslint-plugin": "^4.19.0", 47 | "@typescript-eslint/parser": "^4.19.0", 48 | "eslint": "^7.22.0", 49 | "eslint-config-prettier": "^8.1.0", 50 | "eslint-plugin-prettier": "^3.3.1", 51 | "jest": "^26.6.3", 52 | "prettier": "^2.2.1", 53 | "supertest": "^6.1.3", 54 | "ts-jest": "^26.5.4", 55 | "ts-loader": "^8.0.18", 56 | "ts-node": "^9.1.1", 57 | "tsconfig-paths": "^3.9.0", 58 | "typescript": "^4.2.3" 59 | }, 60 | "jest": { 61 | "moduleFileExtensions": [ 62 | "js", 63 | "json", 64 | "ts" 65 | ], 66 | "rootDir": "src", 67 | "testRegex": ".*\\.spec\\.ts$", 68 | "transform": { 69 | "^.+\\.(t|j)s$": "ts-jest" 70 | }, 71 | "collectCoverageFrom": [ 72 | "**/*.(t|j)s" 73 | ], 74 | "coverageDirectory": "../coverage", 75 | "testEnvironment": "node" 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /employee-gql-service/src/app.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | 5 | describe('AppController', () => { 6 | let appController: AppController; 7 | 8 | beforeEach(async () => { 9 | const app: TestingModule = await Test.createTestingModule({ 10 | controllers: [AppController], 11 | providers: [AppService], 12 | }).compile(); 13 | 14 | appController = app.get(AppController); 15 | }); 16 | 17 | describe('root', () => { 18 | it('should return "Hello World!"', () => { 19 | expect(appController.getHello()).toBe('Hello World!'); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /employee-gql-service/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { GraphQLModule } from '@nestjs/graphql'; 3 | import { TypeOrmModule } from '@nestjs/typeorm'; 4 | import { join } from 'path'; 5 | import { EmployeeModule } from './employee/employee.module'; 6 | import { ProjectModule } from './project/project.module'; 7 | 8 | 9 | 10 | @Module({ 11 | imports: [EmployeeModule, GraphQLModule.forRoot( 12 | { 13 | autoSchemaFile: join(process.cwd(), 'src/graphql-schema.gql') 14 | } 15 | ), 16 | TypeOrmModule.forRoot({ 17 | type: 'postgres', 18 | host: 'localhost', 19 | port: 5432, 20 | username: 'nairobi', 21 | password: '1qazxsw2#', 22 | database: 'employee', 23 | entities: ["dist/**/*.entity{.ts,.js}"], 24 | synchronize: true, 25 | }), 26 | ProjectModule], 27 | controllers: [], 28 | providers: [], 29 | }) 30 | export class AppModule { } 31 | -------------------------------------------------------------------------------- /employee-gql-service/src/employee/dto/create-employee.input.ts: -------------------------------------------------------------------------------- 1 | import { Field, InputType } from "@nestjs/graphql" 2 | 3 | @InputType() 4 | export class EmployeeCreateDTO { 5 | @Field() 6 | firstName: string 7 | @Field() 8 | lastName: string 9 | @Field() 10 | designation: string 11 | @Field({ nullable: true }) 12 | city: string 13 | 14 | @Field() 15 | projectId: string 16 | } -------------------------------------------------------------------------------- /employee-gql-service/src/employee/employee.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { EmployeeService } from './employee.service'; 3 | import { EmployeeResolver } from './employee.resolver'; 4 | import { TypeOrmModule } from '@nestjs/typeorm'; 5 | import { Employee } from './entities/employee.entity'; 6 | import { ProjectModule } from 'src/project/project.module'; 7 | 8 | @Module({ 9 | imports: [TypeOrmModule.forFeature([Employee]), ProjectModule], 10 | providers: [EmployeeService, EmployeeResolver] 11 | }) 12 | export class EmployeeModule { } 13 | -------------------------------------------------------------------------------- /employee-gql-service/src/employee/employee.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Resolver, Query, Mutation, Args, ResolveField, Parent } from '@nestjs/graphql'; 2 | import { identity } from 'rxjs'; 3 | import { Project } from 'src/project/entities/project.entity'; 4 | import { EmployeeCreateDTO } from './dto/create-employee.input'; 5 | import { EmployeeService } from './employee.service'; 6 | import { Employee } from './entities/employee.entity'; 7 | 8 | @Resolver(() => Employee) 9 | export class EmployeeResolver { 10 | 11 | constructor(private employeeService: EmployeeService) { } 12 | 13 | @Query(() => [Employee], { name: "getAllEmployees" }) 14 | findAll() { 15 | return this.employeeService.findAll(); 16 | } 17 | 18 | @Mutation(() => Employee, { name: "createEmployee" }) 19 | create(@Args('employeeInput') employee: EmployeeCreateDTO) { 20 | return this.employeeService.create(employee) 21 | } 22 | @Query(() => Employee) 23 | findOne(@Args("id") id: string) { 24 | return this.employeeService.findOne(id) 25 | } 26 | 27 | 28 | 29 | @ResolveField(() => Project) 30 | project(@Parent() employee: Employee) { 31 | return this.employeeService.getProject(employee.projectId) 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /employee-gql-service/src/employee/employee.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { InjectRepository } from '@nestjs/typeorm'; 3 | import { Project } from 'src/project/entities/project.entity'; 4 | import { ProjectModule } from 'src/project/project.module'; 5 | import { ProjectService } from 'src/project/project.service'; 6 | import { Repository } from 'typeorm'; 7 | import { EmployeeCreateDTO } from './dto/create-employee.input'; 8 | import { Employee } from './entities/employee.entity'; 9 | 10 | @Injectable() 11 | export class EmployeeService { 12 | 13 | 14 | constructor(@InjectRepository(Employee) private employeeRepository: Repository, 15 | private projectService: ProjectService) { 16 | 17 | } 18 | 19 | async findAll(): Promise { 20 | return this.employeeRepository.find(); 21 | } 22 | async findOne(id: string) { 23 | return this.employeeRepository.findOne(id) 24 | } 25 | 26 | async create(employee: EmployeeCreateDTO): Promise { 27 | 28 | let emp = this.employeeRepository.create(employee); 29 | return this.employeeRepository.save(emp) 30 | 31 | } 32 | 33 | async getProject(id: string): Promise { 34 | return this.projectService.findOne(id) 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /employee-gql-service/src/employee/entities/employee.entity.ts: -------------------------------------------------------------------------------- 1 | import { Field, ObjectType } from "@nestjs/graphql" 2 | import { Project } from "src/project/entities/project.entity" 3 | import { Column, Entity, ManyToOne, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm" 4 | 5 | @ObjectType() 6 | @Entity() 7 | export class Employee { 8 | @Field() 9 | @PrimaryGeneratedColumn('uuid') 10 | id: string 11 | @Field() 12 | @Column() 13 | firstName: string 14 | @Field() 15 | @Column() 16 | lastName: string 17 | @Field() 18 | @Column() 19 | designation: string 20 | @Field({ nullable: true }) 21 | @Column({ nullable: true }) 22 | city: string 23 | 24 | @ManyToOne(() => Project, project => project.employees) 25 | @Field(() => Project) 26 | project: Project 27 | 28 | @Column() 29 | @Field() 30 | projectId: string 31 | 32 | } -------------------------------------------------------------------------------- /employee-gql-service/src/graphql-schema.gql: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------ 2 | # THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY) 3 | # ------------------------------------------------------ 4 | 5 | type Employee { 6 | id: String! 7 | firstName: String! 8 | lastName: String! 9 | designation: String! 10 | city: String 11 | project: Project! 12 | projectId: String! 13 | } 14 | 15 | type Project { 16 | id: String! 17 | name: String! 18 | code: Int! 19 | employees: [Employee!] 20 | } 21 | 22 | type Query { 23 | getAllEmployees: [Employee!]! 24 | findOne(id: String!): Employee! 25 | getAllProjects: [Project!]! 26 | project(id: String!): Project! 27 | } 28 | 29 | type Mutation { 30 | createEmployee(employeeInput: EmployeeCreateDTO!): Employee! 31 | createProject(project: CreateProjectInput!): Project! 32 | updateProject(project: UpdateProjectInput!): Project! 33 | removeProject(id: String!): Project! 34 | } 35 | 36 | input EmployeeCreateDTO { 37 | firstName: String! 38 | lastName: String! 39 | designation: String! 40 | city: String 41 | projectId: String! 42 | } 43 | 44 | input CreateProjectInput { 45 | name: String! 46 | code: Int! 47 | } 48 | 49 | input UpdateProjectInput { 50 | id: String! 51 | name: String! 52 | code: Int! 53 | } 54 | -------------------------------------------------------------------------------- /employee-gql-service/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 | } 8 | bootstrap(); 9 | -------------------------------------------------------------------------------- /employee-gql-service/src/project/dto/create-project.input.ts: -------------------------------------------------------------------------------- 1 | import { InputType, Int, Field } from '@nestjs/graphql'; 2 | 3 | @InputType() 4 | export class CreateProjectInput { 5 | 6 | 7 | @Field() 8 | name: string 9 | @Field(() => Int) 10 | code: number 11 | } 12 | -------------------------------------------------------------------------------- /employee-gql-service/src/project/dto/update-project.input.ts: -------------------------------------------------------------------------------- 1 | import { CreateProjectInput } from './create-project.input'; 2 | import { InputType, Field, Int, PartialType } from '@nestjs/graphql'; 3 | 4 | @InputType() 5 | export class UpdateProjectInput { 6 | 7 | @Field() 8 | id: string 9 | @Field() 10 | name: string 11 | @Field(() => Int) 12 | code: number 13 | 14 | 15 | } 16 | -------------------------------------------------------------------------------- /employee-gql-service/src/project/entities/project.entity.ts: -------------------------------------------------------------------------------- 1 | import { ObjectType, Field, Int } from '@nestjs/graphql'; 2 | import { Employee } from 'src/employee/entities/employee.entity'; 3 | import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; 4 | 5 | @ObjectType() 6 | @Entity() 7 | export class Project { 8 | 9 | @Field() 10 | @PrimaryGeneratedColumn('uuid') 11 | id: string 12 | @Field() 13 | @Column() 14 | name: string 15 | @Field(() => Int) 16 | @Column() 17 | code: number 18 | 19 | @OneToMany(() => Employee, employee => employee.project) 20 | @Field(() => [Employee], { nullable: true }) 21 | employees: Employee[] 22 | 23 | } 24 | -------------------------------------------------------------------------------- /employee-gql-service/src/project/project.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { ProjectService } from './project.service'; 3 | import { ProjectResolver } from './project.resolver'; 4 | import { TypeOrmModule } from '@nestjs/typeorm'; 5 | import { Project } from './entities/project.entity'; 6 | 7 | @Module({ 8 | imports: [TypeOrmModule.forFeature([Project])], 9 | providers: [ProjectResolver, ProjectService], 10 | exports: [ProjectService] 11 | }) 12 | export class ProjectModule { } 13 | -------------------------------------------------------------------------------- /employee-gql-service/src/project/project.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql'; 2 | import { ProjectService } from './project.service'; 3 | import { Project } from './entities/project.entity'; 4 | import { CreateProjectInput } from './dto/create-project.input'; 5 | import { UpdateProjectInput } from './dto/update-project.input'; 6 | 7 | @Resolver(() => Project) 8 | export class ProjectResolver { 9 | constructor(private readonly projectService: ProjectService) { } 10 | 11 | @Mutation(() => Project) 12 | createProject(@Args('project') project: CreateProjectInput) { 13 | return this.projectService.create(project); 14 | } 15 | 16 | @Query(() => [Project], { name: 'getAllProjects' }) 17 | findAll() { 18 | return this.projectService.findAll(); 19 | } 20 | 21 | @Query(() => Project, { name: 'project' }) 22 | findOne(@Args('id') id: string) { 23 | return this.projectService.findOne(id); 24 | } 25 | 26 | @Mutation(() => Project) 27 | updateProject(@Args('project') project: UpdateProjectInput) { 28 | return this.projectService.update(project.id, project); 29 | } 30 | 31 | @Mutation(() => Project) 32 | removeProject(@Args('id') id: string) { 33 | return this.projectService.remove(id); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /employee-gql-service/src/project/project.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, NotFoundException } from '@nestjs/common'; 2 | import { InjectRepository } from '@nestjs/typeorm'; 3 | import { Repository } from 'typeorm'; 4 | import { CreateProjectInput } from './dto/create-project.input'; 5 | import { UpdateProjectInput } from './dto/update-project.input'; 6 | import { Project } from './entities/project.entity'; 7 | 8 | @Injectable() 9 | export class ProjectService { 10 | 11 | constructor(@InjectRepository(Project) private projectRepository: Repository) { } 12 | 13 | create(project: CreateProjectInput): Promise { 14 | let proj = this.projectRepository.create(project); 15 | return this.projectRepository.save(proj) //you can directly use this without create. depends on DTO. this explained in video 16 | 17 | } 18 | 19 | async findAll(): Promise { 20 | return this.projectRepository.find({ 21 | relations: ["employees"] 22 | }); 23 | } 24 | 25 | async findOne(id: string): Promise { 26 | return this.projectRepository.findOne(id, { relations: ["employees"] }); 27 | } 28 | 29 | update(id: string, updateProjectInput: UpdateProjectInput) { 30 | let project: Project = this.projectRepository.create(updateProjectInput) 31 | project.id = id; 32 | return this.projectRepository.save(project) 33 | } 34 | 35 | async remove(id: string) { 36 | let proj = this.findOne(id) 37 | if (proj) { 38 | let ret = await this.projectRepository.delete(id) 39 | if (ret.affected === 1) { 40 | return proj; 41 | } 42 | } 43 | throw new NotFoundException(`Record cannot find by id ${id}`) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /employee-gql-service/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('/') 21 | .expect(200) 22 | .expect('Hello World!'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /employee-gql-service/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 | -------------------------------------------------------------------------------- /employee-gql-service/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /employee-gql-service/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 | --------------------------------------------------------------------------------