Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions packages/toolkits/pro/template/server/nestJs/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
],
root: true,
env: {
node: true,
jest: true,
},
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};
21 changes: 21 additions & 0 deletions packages/toolkits/pro/template/server/nestJs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# dependencies
/node_modules

# IDE
/.idea
/.awcache
/.vscode

# misc
npm-debug.log

# example
/quick-start

# tests
/test
/coverage
/.nyc_output

# dist
/dist
26 changes: 26 additions & 0 deletions packages/toolkits/pro/template/server/nestJs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
### Sequelize sample

### Installation

`npm install`

### Running

This example requires docker or a local MySQL installation. If using a local MySQL database, see `app.module.ts` for credentials, and make sure there are matching credentials in the database and the source code.

#### Docker

There is a `docker-compose.yml` file for starting Docker.

`docker-compose up`

After running the sample, you can stop the Docker container with

`docker-compose down`

### Run the sample

Then, run Nest as usual:

`npm run start`

11 changes: 11 additions & 0 deletions packages/toolkits/pro/template/server/nestJs/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: "3"

services:
mysql:
image: mysql:8
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test
ports:
- "3306:3306"
Empty file.
73 changes: 73 additions & 0 deletions packages/toolkits/pro/template/server/nestJs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"name": "nest-typescript-starter",
"version": "1.0.0",
"description": "Nest TypeScript starter repository",
"license": "MIT",
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint '{src,apps,libs,test}/**/*.ts' --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "echo 'No e2e tests implemented yet.'"
},
"dependencies": {
"@nestjs/common": "10.0.3",
"@nestjs/core": "10.0.3",
"@nestjs/platform-express": "10.0.3",
"@nestjs/sequelize": "10.0.0",
"mysql2": "3.4.3",
"reflect-metadata": "0.1.13",
"rimraf": "5.0.1",
"rxjs": "7.8.1",
"sequelize": "6.32.1",
"sequelize-typescript": "2.1.5",
"typescript": "5.1.6"
},
"devDependencies": {
"@nestjs/cli": "10.0.5",
"@nestjs/schematics": "10.0.1",
"@nestjs/testing": "10.0.3",
"@types/express": "4.17.17",
"@types/jest": "29.5.3",
"@types/node": "20.3.3",
"@types/supertest": "2.0.12",
"@typescript-eslint/eslint-plugin": "5.60.1",
"@typescript-eslint/parser": "5.60.1",
"eslint": "8.42.0",
"eslint-config-prettier": "8.8.0",
"eslint-plugin-import": "2.27.5",
"jest": "29.6.1",
"prettier": "2.8.8",
"supertest": "6.3.3",
"ts-jest": "29.1.1",
"ts-loader": "9.4.4",
"ts-node": "10.9.1",
"tsconfig-paths": "4.2.0",
"typescript": "5.1.6"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
20 changes: 20 additions & 0 deletions packages/toolkits/pro/template/server/nestJs/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { EmployeesModule } from './employees/employees.module';

@Module({
imports: [
SequelizeModule.forRoot({
dialect: '',
host: '',
port: '',
username: '',
password: '',
database: '',
autoLoadModels: true,
synchronize: true,
}),
EmployeesModule,
],
})
export class AppModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export class CreateEmployeeDto {
id: string;
name: string;
employeeNo: string;
department: string;
departmentLevel: string;
status: string;
workbenchName: string;
project: string;
type: string;
address: string;
roles: string;
lastUpdateUser: string;
createTime: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CreateEmployeeDto } from './dto/create-employee.dto';
import { EmployeesController } from './employees.controller';
import { EmployeesService } from './employees.service';

describe('EmployeesController', () => {
let employeesController: EmployeesController;
let employeesService: EmployeesService;

beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [EmployeesController],
providers: [
{
provide: EmployeesService,
useValue: {
create: jest
.fn()
.mockImplementation((employee: CreateEmployeeDto) =>
Promise.resolve({ id: '1', ...employee })
),
findAll: jest.fn().mockResolvedValue([
{
firstName: 'firstName #1',
lastName: 'lastName #1',
},
{
firstName: 'firstName #2',
lastName: 'lastName #2',
},
]),
findOne: jest.fn().mockImplementation((id: string) =>
Promise.resolve({
firstName: 'firstName #1',
lastName: 'lastName #1',
id,
})
),
remove: jest.fn(),
},
},
],
}).compile();

employeesController = app.get<EmployeesController>(EmployeesController);
employeesService = app.get<EmployeesService>(EmployeesService);
});

it('should be defined', () => {
expect(employeesController).toBeDefined();
});

describe('findAll()', () => {
it('should find all employees ', () => {
employeesController.getEmployee();
expect(employeesService.getEmployee).toHaveBeenCalled();
});
});

describe('findOne()', () => {
it('should find a employee', () => {
employeesController.findOne('1');
expect(employeesService.findOne).toHaveBeenCalled();
expect(employeesController.findOne('1')).resolves.toEqual({
firstName: 'firstName #1',
lastName: 'lastName #1',
id: '1',
});
});
});

describe('remove()', () => {
it('should remove the employee', () => {
employeesController.remove('2');
expect(employeesService.remove).toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Query,
} from '@nestjs/common';
import { CreateEmployeeDto } from './dto/create-employee.dto';
import { Employee } from './models/employee.model';
import { EmployeesService } from './employees.service';

@Controller('employee')
export class EmployeesController {
constructor(private readonly employeesService: EmployeesService) {}

@Post('getEmployee')
getEmployee(@Query() searchInfo): Promise<Employee[]> {
return this.employeesService.getEmployee(searchInfo);
}

@Get('getEmployee/:id')
findOne(@Param('id') id: string): Promise<Employee> {
return this.employeesService.findOne(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { Employee } from './models/employee.model';
import { EmployeesController } from './employees.controller';
import { EmployeesService } from './employees.service';

@Module({
imports: [SequelizeModule.forFeature([Employee])],
providers: [EmployeesService],
controllers: [EmployeesController],
})
export class EmployeesModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Test, TestingModule } from '@nestjs/testing';
import { Employee } from './models/employee.model';
import { EmployeesService } from './employees.service';
import { getModelToken } from '@nestjs/sequelize';

const employeesArray = [
{
firstName: 'firstName #1',
lastName: 'lastName #1',
},
{
firstName: 'firstName #2',
lastName: 'lastName #2',
},
];

const oneEmployee = {
firstName: 'firstName #1',
lastName: 'lastName #1',
};

describe('EmployeeService', () => {
let service: EmployeesService;
let model: typeof Employee;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
EmployeesService,
{
provide: getModelToken(Employee),
useValue: {
findAll: jest.fn(() => employeesArray),
findOne: jest.fn(),
create: jest.fn(() => oneEmployee),
remove: jest.fn(),
destroy: jest.fn(() => oneEmployee),
},
},
],
}).compile();

service = module.get<EmployeesService>(EmployeesService);
model = module.get<typeof Employee>(getModelToken(Employee));
});

it('should be defined', () => {
expect(service).toBeDefined();
});

describe('findAll()', () => {
it('should return an array of employees', async () => {
const employees = await service.getEmployee();
expect(employees).toEqual(employeesArray);
});
});

describe('findOne()', () => {
it('should get a single employee', () => {
const findSpy = jest.spyOn(model, 'findOne');
expect(service.findOne('1'));
expect(findSpy).toBeCalledWith({ where: { id: '1' } });
});
});

describe('remove()', () => {
it('should remove a employee', async () => {
const findSpy = jest.spyOn(model, 'findOne').mockReturnValue({
destroy: jest.fn(),
} as any);
const retVal = await service.remove('2');
expect(findSpy).toBeCalledWith({ where: { id: '2' } });
expect(retVal).toBeUndefined();
});
});
});
Loading