diff --git a/package.json b/package.json index 90f6acf..80a18be 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "class-validator": "^0.14.0", "mysql2": "^3.2.1", "nest-winston": "^1.9.1", + "nestjs-paginate": "^8.1.3", "reflect-metadata": "^0.1.13", "rxjs": "^7.2.0", "typeorm": "^0.3.15", diff --git a/src/app.module.ts b/src/app.module.ts index cfe15b3..a4c18a7 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -14,7 +14,7 @@ import { AllExceptionsFilter } from './logger/any-exception.filter'; import loggerMiddleware from './logger/logger.middleware'; import { TypeOrmModule } from '@nestjs/typeorm'; import { MySqlCompanyModule } from './mysqlcompany/mysqlcompany.module'; -import { OrmMongoCompanyModule } from './ormmongocompany/ormmongocompany.module'; +// import { OrmMongoCompanyModule } from './ormmongocompany/ormmongocompany.module'; @Module({ imports: [ @@ -27,12 +27,12 @@ import { OrmMongoCompanyModule } from './ormmongocompany/ormmongocompany.module' port: 23306, username: 'root', password: 'example', - database: 'example_nodejs_nest_crud_company', + database: 'boilerplate_nestjs_api_crud_company', // entities: ['dist/modules/**/*.mysql.entity{.ts,.js}'], autoLoadEntities: true, // IMPORTANT: disable sync - synchronize: false, - // synchronize: true, + // synchronize: false, + synchronize: true, logging: true, }), // Router resigration for module (2nd level) will be declared inside the module @@ -40,7 +40,7 @@ import { OrmMongoCompanyModule } from './ormmongocompany/ormmongocompany.module' // ]), UsersModule, MySqlCompanyModule, - OrmMongoCompanyModule, + // OrmMongoCompanyModule, ], controllers: [AppController], providers: [ diff --git a/src/logger/any-exception.filter.ts b/src/logger/any-exception.filter.ts index 66e42fe..7a1383b 100644 --- a/src/logger/any-exception.filter.ts +++ b/src/logger/any-exception.filter.ts @@ -30,7 +30,8 @@ export class AllExceptionsFilter implements ExceptionFilter { message = exception.message; // trim the stack lines if (exception.stack) { - stack = exception.stack.split('\n').slice(1, 3).join('\n'); + // stack = exception.stack.split('\n').slice(1, 3).join('\n'); + stack = exception.stack; } } @@ -55,15 +56,19 @@ export class AllExceptionsFilter implements ExceptionFilter { this.logger.error(logMsg, stack, AllExceptionsFilter.name); } else { const requstBody = - Object.keys(body).length > 0 ? ` Body=${JSON.stringify(body)}` : ''; + Object.keys(body).length > 0 ? `Body=${JSON.stringify(body)}` : ''; const rawHeadersStr = Object.keys(rawHeaders).length > 0 - ? ` RawHeaders=${JSON.stringify(rawHeaders)}` + ? `RawHeaders=${JSON.stringify(rawHeaders)}` : ''; logMsg = `${message}\n${method.toLocaleUpperCase()} ${url}${requstBody}${rawHeadersStr}`; - this.logger.error(logMsg, stack, AllExceptionsFilter.name); + // this.logger.error(logMsg, stack, AllExceptionsFilter.name); + this.logger.error(message); + this.logger.debug( + `Request: ${method.toLocaleUpperCase()} ${url}\n${requstBody}\n${rawHeadersStr}\n${stack}`, + ); } response.header('Content-Type', 'application/json; charset=utf-8'); diff --git a/src/mysqlcompany/contract/README.md b/src/mysqlcompany/contract/README.md new file mode 100644 index 0000000..8271c37 --- /dev/null +++ b/src/mysqlcompany/contract/README.md @@ -0,0 +1,10 @@ +# Contract Module + +- This module demonstrates using: + - CRUD + - TypeORM: MySQL + - TypeORM Repository + - No QueryBuilder + - TypeOrmModule.forFeature & TypeOrmModule.forRoot{ autoLoadEntities: true } +- The Entities + - DB and Web-API entities are shared \ No newline at end of file diff --git a/src/mysqlcompany/contract/contracts.controller.ts b/src/mysqlcompany/contract/contracts.controller.ts new file mode 100644 index 0000000..4c38f55 --- /dev/null +++ b/src/mysqlcompany/contract/contracts.controller.ts @@ -0,0 +1,77 @@ +import { + Controller, + Get, + Post, + Body, + Patch, + Param, + Delete, + NotFoundException, + HttpCode, + BadRequestException, +} from '@nestjs/common'; +import { ApiResponse } from '@nestjs/swagger'; +import { ContractsService } from './contracts.service'; +import { Contract } from './entities/contract.entity'; +import { ContractCreateDto } from './dto/contract-create.dto'; +import { ContractUpdateDto } from './dto/contract-update.dto'; +import { EntityNotFoundError } from 'typeorm'; +import { Paginate, PaginateQuery, Paginated } from 'nestjs-paginate'; + +@Controller() +export class ContractsController { + constructor(private readonly contractsService: ContractsService) {} + + private handleEntityNotFoundError(id: number, e: Error) { + if (e instanceof EntityNotFoundError) { + throw new NotFoundException(`Not found: id=${id}`); + } else { + throw e; + } + } + + @Get() + @ApiResponse({ type: [Contract] }) + findAll(@Paginate() query: PaginateQuery): Promise> { + return this.contractsService.findAll(query); + } + + @Get(':id') + @ApiResponse({ type: Contract }) + async findOne(@Param('id') id: number): Promise { + // NOTE: the + operator returns the numeric representation of the object. + return this.contractsService.findOne(+id).catch((err) => { + this.handleEntityNotFoundError(id, err); + return null; + }); + } + + @Post() + @ApiResponse({ type: [Contract] }) + create(@Body() contractCreateDto: ContractCreateDto) { + return this.contractsService.create(contractCreateDto); + } + + @Patch(':id') + // Status 204 because no content will be returned + @HttpCode(204) + async update( + @Param('id') id: number, + @Body() contractUpdateDto: ContractUpdateDto, + ): Promise { + if (Object.keys(contractUpdateDto).length === 0) { + throw new BadRequestException('Request body is empty'); + } + await this.contractsService.update(+id, contractUpdateDto).catch((err) => { + this.handleEntityNotFoundError(id, err); + }); + } + + @Delete(':id') + @HttpCode(204) + async remove(@Param('id') id: number): Promise { + await this.contractsService.remove(+id).catch((err) => { + this.handleEntityNotFoundError(id, err); + }); + } +} diff --git a/src/mysqlcompany/contract/contracts.module.ts b/src/mysqlcompany/contract/contracts.module.ts new file mode 100644 index 0000000..618d99e --- /dev/null +++ b/src/mysqlcompany/contract/contracts.module.ts @@ -0,0 +1,15 @@ +import { Logger, Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { ContractsService } from './contracts.service'; +import { ContractsController } from './contracts.controller'; +import { Contract } from './entities/contract.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([Contract])], + controllers: [ContractsController], + providers: [Logger, ContractsService], + // If you want to use the repository outside of the module + // which imports TypeOrmModule.forFeature, you'll need to re-export the providers generated by it. + // exports: [TypeOrmModule], +}) +export class ContractsModule {} diff --git a/src/mysqlcompany/contract/contracts.service.ts b/src/mysqlcompany/contract/contracts.service.ts new file mode 100644 index 0000000..d17a07f --- /dev/null +++ b/src/mysqlcompany/contract/contracts.service.ts @@ -0,0 +1,70 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { EntityNotFoundError, Repository } from 'typeorm'; +import { Contract } from './entities/contract.entity'; +import { ContractCreateDto } from './dto/contract-create.dto'; +import { ContractUpdateDto } from './dto/contract-update.dto'; +import { + FilterOperator, + FilterSuffix, + PaginateQuery, + Paginated, + paginate, +} from 'nestjs-paginate'; + +@Injectable() +export class ContractsService { + constructor( + private readonly logger: Logger, + @InjectRepository(Contract) + private contractsRepository: Repository, + ) {} + + create(contractCreateDto: ContractCreateDto): Promise { + // Use Repository.create() will copy the values to destination object. + const contract = this.contractsRepository.create(contractCreateDto); + return this.contractsRepository.save(contract); + } + + findAll(query: PaginateQuery): Promise> { + return paginate(query, this.contractsRepository, { + relations: { staff: true }, + sortableColumns: ['id', 'title', 'details', 'staff.name'], + select: ['id', 'title', 'details', 'staff.name'], + filterableColumns: { + title: [FilterOperator.EQ, FilterOperator.ILIKE, FilterSuffix.NOT], + // staff.name: [FilterOperator.EQ, FilterOperator.ILIKE, FilterSuffix.NOT], + }, + }); + } + + findOne(id: number): Promise { + return this.contractsRepository.findOneOrFail({ where: { id } }); + } + + async update( + id: number, + contractUpdateDto: ContractUpdateDto, + ): Promise { + await this.isExist(id); + await this.contractsRepository.update({ id }, contractUpdateDto); + } + + async remove(id: number): Promise { + await this.isExist(id); + await this.contractsRepository.delete(id); + } + + // Helper function: Check if the entity exist. + // If entity does not exsit, return the Promise.reject() + private async isExist(id: number): Promise { + const cnt = await this.contractsRepository.countBy({ id }); + if (cnt > 0) { + return; + } else { + return Promise.reject( + new EntityNotFoundError(Contract, { where: { id } }), + ); + } + } +} diff --git a/src/mysqlcompany/contract/dto/contract-create.dto.ts b/src/mysqlcompany/contract/dto/contract-create.dto.ts new file mode 100644 index 0000000..dfb46d5 --- /dev/null +++ b/src/mysqlcompany/contract/dto/contract-create.dto.ts @@ -0,0 +1,30 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsNotEmpty, IsString, IsNumber, IsOptional } from 'class-validator'; +import { Staff } from 'src/mysqlcompany/staffs/entities/staff.entity'; +export class ContractCreateDto { + // NOTE: Since the id is auto-inc, so no id for the creation + // id: number; + + @ApiProperty({ + description: 'Contract name', + }) + @IsString() + @IsNotEmpty() + title: string; + + @ApiProperty({ + description: 'Contract details', + }) + @IsString() + @IsOptional() + details: string; + + @ApiProperty({ + type: Staff, + name: 'departmentId', + description: 'Department ID', + required: false, + }) + @IsOptional() + staff: Staff; +} diff --git a/src/mysqlcompany/contract/dto/contract-update.dto.ts b/src/mysqlcompany/contract/dto/contract-update.dto.ts new file mode 100644 index 0000000..4a57263 --- /dev/null +++ b/src/mysqlcompany/contract/dto/contract-update.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/swagger'; +import { ContractCreateDto } from './contract-create.dto'; + +export class ContractUpdateDto extends PartialType(ContractCreateDto) {} diff --git a/src/mysqlcompany/contract/entities/contract.entity.ts b/src/mysqlcompany/contract/entities/contract.entity.ts new file mode 100644 index 0000000..de5e365 --- /dev/null +++ b/src/mysqlcompany/contract/entities/contract.entity.ts @@ -0,0 +1,52 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Staff } from 'src/mysqlcompany/staffs/entities/staff.entity'; +import { + Column, + Entity, + JoinColumn, + OneToOne, + PrimaryGeneratedColumn, +} from 'typeorm'; + +@Entity('contracts') +export class Contract { + @ApiProperty({ + type: Number, + name: '_id', + description: 'id of contract, auto-incremented', + }) + // https://github.com/ppetzold/nestjs-paginate/issues/518 + // when use 'id', will cause duplicated column issue + @PrimaryGeneratedColumn('increment', { name: '_id' }) + id: number; + + @ApiProperty({ + type: String, + description: 'Contract title', + }) + @Column({ + type: 'varchar', + length: 255, + }) + title: string; + + @ApiProperty({ + type: String, + name: 'details', + description: 'Contract details', + required: false, + }) + @Column({ + type: 'text', + nullable: true, + }) + details: string; + + @ApiProperty({ + name: 'staff', + description: 'The staff of this contract', + type: () => Staff, + }) + @OneToOne(() => Staff) + staff: Staff; +} diff --git a/src/mysqlcompany/department/department.controller.ts b/src/mysqlcompany/department/department.controller.ts index 7ca3074..405043d 100644 --- a/src/mysqlcompany/department/department.controller.ts +++ b/src/mysqlcompany/department/department.controller.ts @@ -16,6 +16,7 @@ import { Department } from './entities/department.entity'; import { DepartmentCreateDto } from './dto/department-create.dto'; import { DepartmentUpdateDto } from './dto/department-update.dto'; import { EntityNotFoundError } from 'typeorm'; +import { Paginate, PaginateQuery, Paginated } from 'nestjs-paginate'; @Controller() export class DepartmentController { @@ -31,8 +32,8 @@ export class DepartmentController { @Get() @ApiResponse({ type: [Department] }) - findAll(): Promise { - return this.departmentService.findAll(); + findAll(@Paginate() query: PaginateQuery): Promise> { + return this.departmentService.findAll(query); } @Get(':id') diff --git a/src/mysqlcompany/department/department.service.ts b/src/mysqlcompany/department/department.service.ts index 24b77e4..d596a8a 100644 --- a/src/mysqlcompany/department/department.service.ts +++ b/src/mysqlcompany/department/department.service.ts @@ -4,27 +4,38 @@ import { EntityNotFoundError, Repository } from 'typeorm'; import { Department } from './entities/department.entity'; import { DepartmentCreateDto } from './dto/department-create.dto'; import { DepartmentUpdateDto } from './dto/department-update.dto'; +import { PaginateQuery, Paginated, paginate } from 'nestjs-paginate'; @Injectable() export class DepartmentService { constructor( private readonly logger: Logger, @InjectRepository(Department) - private departmentRepository: Repository, + private departmentsRepository: Repository, ) {} create(departmentCreateDto: DepartmentCreateDto): Promise { // Use Repository.create() will copy the values to destination object. - const department = this.departmentRepository.create(departmentCreateDto); - return this.departmentRepository.save(department); + const department = this.departmentsRepository.create(departmentCreateDto); + return this.departmentsRepository.save(department); } - findAll(): Promise { - return this.departmentRepository.find(); + findAll(query: PaginateQuery): Promise> { + return paginate(query, this.departmentsRepository, { + relations: { staffs: true }, + sortableColumns: ['id', 'name'], + // select: ['id', 'name', 'staffs.name'], + // searchableColumns: ['name', 'department.name'], + // filterableColumns: { + // 'home.pillows.color': [FilterOperator.EQ], + // }, + }); + + // return this.departmentsRepository.find(); } findOne(id: number): Promise { - return this.departmentRepository.findOneOrFail({ where: { id } }); + return this.departmentsRepository.findOneOrFail({ where: { id } }); } async update( @@ -32,18 +43,18 @@ export class DepartmentService { departmentUpdateDto: DepartmentUpdateDto, ): Promise { await this.isExist(id); - await this.departmentRepository.update({ id }, departmentUpdateDto); + await this.departmentsRepository.update({ id }, departmentUpdateDto); } async remove(id: number): Promise { await this.isExist(id); - await this.departmentRepository.delete(id); + await this.departmentsRepository.delete(id); } // Helper function: Check if the entity exist. // If entity does not exsit, return the Promise.reject() private async isExist(id: number): Promise { - const cnt = await this.departmentRepository.countBy({ id }); + const cnt = await this.departmentsRepository.countBy({ id }); if (cnt > 0) { return; } else { diff --git a/src/mysqlcompany/department/entities/department.entity.ts b/src/mysqlcompany/department/entities/department.entity.ts index f21ab53..9ed1acf 100644 --- a/src/mysqlcompany/department/entities/department.entity.ts +++ b/src/mysqlcompany/department/entities/department.entity.ts @@ -1,17 +1,23 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Staff } from 'src/mysqlcompany/staffs/entities/staff.entity'; -import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; +import { + Column, + Entity, + JoinColumn, + OneToMany, + PrimaryGeneratedColumn, +} from 'typeorm'; // @Entity('departments') @Entity('departments') export class Department { @ApiProperty({ type: Number, - name: 'id', + name: '_id', description: 'id of department, auto-incremented', required: true, }) - @PrimaryGeneratedColumn('increment') + @PrimaryGeneratedColumn('increment', { name: '_id' }) id: number; @ApiProperty({ @@ -25,6 +31,13 @@ export class Department { }) name: string; - // @OneToMany((type) => Staff, (staff) => staff.departmentId) - // staffs: Staff[]; + @OneToMany(() => Staff, (staff) => staff.department) + @ApiProperty({ + name: 'staffs', + description: 'The staffs under this department', + type: [Staff], + }) + @ApiPropertyOptional() + // @JoinColumn({ name: 'id', referencedColumnName: 'department_id' }) + staffs: Staff[]; } diff --git a/src/mysqlcompany/mysqlcompany.module.ts b/src/mysqlcompany/mysqlcompany.module.ts index d8234d8..1f0d542 100644 --- a/src/mysqlcompany/mysqlcompany.module.ts +++ b/src/mysqlcompany/mysqlcompany.module.ts @@ -4,6 +4,7 @@ import { MySqlCompanyController } from './mysqlcompany.controller'; import { DepartmentModule } from './department/department.module'; import { StaffsModule } from './staffs/staffs.module'; import { RouterModule } from '@nestjs/core'; +import { ContractsModule } from './contract/contracts.module'; @Module({ imports: [ @@ -23,11 +24,16 @@ import { RouterModule } from '@nestjs/core'; path: 'staffs', module: StaffsModule, }, + { + path: 'contracts', + module: ContractsModule, + }, ], }, ]), DepartmentModule, StaffsModule, + ContractsModule, ], controllers: [MySqlCompanyController], providers: [Logger, MySqlCompanyService], diff --git a/src/mysqlcompany/staffs/entities/staff.entity.ts b/src/mysqlcompany/staffs/entities/staff.entity.ts index e235615..4a1e5cc 100644 --- a/src/mysqlcompany/staffs/entities/staff.entity.ts +++ b/src/mysqlcompany/staffs/entities/staff.entity.ts @@ -1,4 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; +import { Contract } from 'src/mysqlcompany/contract/entities/contract.entity'; import { Department } from 'src/mysqlcompany/department/entities/department.entity'; import { Column, @@ -6,11 +7,11 @@ import { JoinColumn, JoinTable, ManyToOne, + OneToOne, PrimaryGeneratedColumn, } from 'typeorm'; @Entity('staffs') -@Entity() export class Staff { @ApiProperty({ type: Number, @@ -41,27 +42,35 @@ export class Staff { @Column({ name: 'staff_code', type: 'varchar', - length: 10, + length: 4, nullable: true, }) staffCode: number; @ApiProperty({ - type: Number, - name: 'departmentId', - description: 'Department ID', + name: 'department', + description: 'The Department that the staff is undered', + type: () => Department, required: false, }) - @Column({ - // Match existing column naming convention - name: 'department_id', - type: 'tinyint', - unsigned: true, - nullable: true, + @ManyToOne(() => Department, (department) => department.staffs, { + nullable: false, + eager: true, }) - departmentId: number; - - @ManyToOne(() => Department) + // @JoinColumn({ name: 'department_id', referencedColumnName: 'id' }) @JoinColumn({ name: 'department_id' }) department: Department; + + @ApiProperty({ + name: 'contract', + description: 'The staff contract', + type: () => Contract, + }) + @OneToOne(() => Contract, (contract) => contract.staff, { + nullable: false, + eager: true, + cascade: true, + }) + @JoinColumn({ name: 'contract_id' }) + contract: Contract; } diff --git a/src/mysqlcompany/staffs/staffs.controller.ts b/src/mysqlcompany/staffs/staffs.controller.ts index 63038dc..2204d92 100644 --- a/src/mysqlcompany/staffs/staffs.controller.ts +++ b/src/mysqlcompany/staffs/staffs.controller.ts @@ -16,6 +16,7 @@ import { Staff } from './entities/staff.entity'; import { StaffCreateDto } from './dto/staff-create.dto'; import { StaffUpdateDto } from './dto/staff-update.dto'; import { EntityNotFoundError } from 'typeorm'; +import { Paginate, PaginateQuery, Paginated } from 'nestjs-paginate'; @Controller() export class StaffsController { @@ -31,8 +32,8 @@ export class StaffsController { @Get() @ApiResponse({ type: [Staff] }) - findAll(): Promise { - return this.staffsService.findAll(); + findAll(@Paginate() query: PaginateQuery): Promise> { + return this.staffsService.findAll(query); } @Get(':id') diff --git a/src/mysqlcompany/staffs/staffs.service.ts b/src/mysqlcompany/staffs/staffs.service.ts index f1ace5e..9aa9aa2 100644 --- a/src/mysqlcompany/staffs/staffs.service.ts +++ b/src/mysqlcompany/staffs/staffs.service.ts @@ -1,9 +1,16 @@ -import { Injectable, Logger, NotFoundException } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { EntityNotFoundError, Repository } from 'typeorm'; import { Staff } from './entities/staff.entity'; import { StaffCreateDto } from './dto/staff-create.dto'; import { StaffUpdateDto } from './dto/staff-update.dto'; +import { + FilterOperator, + FilterSuffix, + PaginateQuery, + Paginated, + paginate, +} from 'nestjs-paginate'; @Injectable() export class StaffsService { @@ -19,22 +26,47 @@ export class StaffsService { return this.staffsRepository.save(staff); } - findAll(): Promise { - return this.staffsRepository.find({ - relations: { - department: true, - }, - select: { - id: true, - name: true, - - departmentId: false, - department: { - id: false, - name: true, - }, - }, + findAll(query: PaginateQuery): Promise> { + return paginate(query, this.staffsRepository, { + // loadEagerRelations: true, + // relations: { department: true, contract: true }, + relations: ['contract', 'department'], + // sortableColumns: ['id', 'name', 'staffCode', 'department.name'], + sortableColumns: ['id', 'name', 'department.name'], + select: [ + 'id', + 'name', + 'staffCode', + 'department.id', + 'department.name', + 'contract.id', + 'contract.title', + 'contract.details', + ], + // searchableColumns: ['name', 'department.name'], + // filterableColumns: { + // 'department.name': [ + // FilterOperator.EQ, + // FilterOperator.ILIKE, + // FilterSuffix.NOT, + // ], + // }, }); + // return this.staffsRepository.find({ + // relations: { + // department: true, + // }, + // select: { + // id: true, + // name: true, + + // departmentId: false, + // department: { + // id: false, + // name: true, + // }, + // }, + // }); } findOne(id: number): Promise { diff --git a/thunder-tests/thunderclient.json b/thunder-tests/thunderclient.json index 9932580..bd6c2c5 100644 --- a/thunder-tests/thunderclient.json +++ b/thunder-tests/thunderclient.json @@ -37,13 +37,42 @@ "colId": "8a14d631-7522-4fcd-a3b8-9a68166e5496", "containerId": "", "name": "Get MySQL Comany Staffs", - "url": "http://localhost:3000/mysql-company/staffs/", + "url": "http://localhost:3000/mysql-company/staffs/?limit=1&select=id,name,staffCode,department.name,contract.title", "method": "GET", "sortNum": 15000, "created": "2023-04-20T13:01:50.431Z", - "modified": "2023-04-20T13:17:36.471Z", + "modified": "2023-04-22T14:09:13.798Z", "headers": [], - "params": [], + "params": [ + { + "name": "limit", + "value": "1", + "isPath": false + }, + { + "name": "select", + "value": "id,name,staffCode,department.name,contract.title", + "isPath": false + }, + { + "name": "sortBy", + "value": "department.name:DESC", + "isDisabled": true, + "isPath": false + }, + { + "name": "sortBy", + "value": "name:ASC", + "isDisabled": true, + "isPath": false + }, + { + "name": "filter.department.name", + "value": "$ilike:Brown", + "isDisabled": true, + "isPath": false + } + ], "tests": [] }, { @@ -51,13 +80,61 @@ "colId": "8a14d631-7522-4fcd-a3b8-9a68166e5496", "containerId": "", "name": "Get MySQL Comany Departments", - "url": "http://localhost:3000/ormmongo-company/staffs", + "url": "http://localhost:3000/mysql-company/departments/", "method": "GET", "sortNum": 17500, "created": "2023-04-20T13:17:46.507Z", - "modified": "2023-04-20T15:00:49.647Z", + "modified": "2023-04-22T08:37:35.984Z", "headers": [], "params": [], "tests": [] + }, + { + "_id": "e4920ab9-8552-46d1-9431-a3aaaa187cce", + "colId": "8a14d631-7522-4fcd-a3b8-9a68166e5496", + "containerId": "", + "name": "Create MySQL Comany Staff", + "url": "http://localhost:3000/mysql-company/staffs/", + "method": "POST", + "sortNum": 16250, + "created": "2023-04-22T04:22:32.924Z", + "modified": "2023-04-22T13:45:24.200Z", + "headers": [ + { + "name": "Content-Type", + "value": "application/json" + } + ], + "params": [], + "body": { + "type": "json", + "raw": "{\n \"name\":\"{{#name}}\",\n \"department\":{ \"id\":2 },\n \"contract\": { \"title\":\"ZYX\" }\n}", + "form": [] + }, + "tests": [] + }, + { + "_id": "97997fc9-e49a-4a96-871b-6292c92c7567", + "colId": "8a14d631-7522-4fcd-a3b8-9a68166e5496", + "containerId": "", + "name": "Create MySQL Comany Department", + "url": "http://localhost:3000/mysql-company/departments/", + "method": "POST", + "sortNum": 16875, + "created": "2023-04-22T07:37:29.132Z", + "modified": "2023-04-22T07:38:11.328Z", + "headers": [ + { + "name": "Content-Type", + "value": "application/json" + } + ], + "params": [], + "body": { + "type": "json", + "raw": "{\n \"name\": \"Dept: {{#name}}\"\n}", + "form": [] + }, + "tests": [] } ] \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index f114c22..d2c5bf9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3863,6 +3863,13 @@ nest-winston@^1.9.1: dependencies: fast-safe-stringify "^2.1.1" +nestjs-paginate@^8.1.3: + version "8.1.3" + resolved "https://registry.yarnpkg.com/nestjs-paginate/-/nestjs-paginate-8.1.3.tgz#89c6a4fe88e3b2c885c0ca1daa115e889981d4d0" + integrity sha512-dQ7VKfssee/FkIf4aI409x1LBkFV2KdKoVDVv6HIwQmVmSeF4n8mkOVLWNh2QSFjqe9IN15ezrrFGzuWvVooTQ== + dependencies: + lodash "^4.17.21" + node-abort-controller@^3.0.1: version "3.1.1" resolved "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz"