From 8bcb3dadb4477fe47910f99bd8c296146894b8dc Mon Sep 17 00:00:00 2001 From: zhumeisongsong Date: Tue, 17 Dec 2024 12:15:04 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refactor:=20=E2=99=BB=EF=B8=8F=20rename=20d?= =?UTF-8?q?omain=20repository=20interface=20definition=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/users/domain/src/index.ts | 2 +- .../lib/users-repository.interface.spec.ts | 60 +++++++++++++++++++ .../src/lib/users-repository.interface.ts | 8 +++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 libs/users/domain/src/lib/users-repository.interface.spec.ts create mode 100644 libs/users/domain/src/lib/users-repository.interface.ts diff --git a/libs/users/domain/src/index.ts b/libs/users/domain/src/index.ts index 7e85695..f727c23 100644 --- a/libs/users/domain/src/index.ts +++ b/libs/users/domain/src/index.ts @@ -1,2 +1,2 @@ export * from './lib/user.entity'; -export * from './lib/users.repository'; +export * from './lib/users-repository.interface'; diff --git a/libs/users/domain/src/lib/users-repository.interface.spec.ts b/libs/users/domain/src/lib/users-repository.interface.spec.ts new file mode 100644 index 0000000..89a6fa4 --- /dev/null +++ b/libs/users/domain/src/lib/users-repository.interface.spec.ts @@ -0,0 +1,60 @@ +import { UsersRepository } from './users-repository.interface'; +import { User } from './user.entity'; + +class MockUsersRepository implements UsersRepository { + private users: User[] = [ + { id: '1', email: 'john@example.com', firstName: 'John', lastName: 'Doe' }, + { + id: '2', + email: 'jane@example.com', + firstName: 'Jane', + lastName: 'Smith', + }, + ]; + + async findOneById(id: string): Promise { + return this.users.find((user) => user.id === id) || null; + } + + async findOneByEmail(email: string): Promise { + return this.users.find((user) => user.email === email) || null; + } +} + +describe('UsersRepository', () => { + let usersRepository: UsersRepository; + + beforeEach(() => { + usersRepository = new MockUsersRepository(); + }); + + test('findOneById should return a user by id', async () => { + const user = await usersRepository.findOneById('1'); + expect(user).toEqual({ + id: '1', + email: 'john@example.com', + firstName: 'John', + lastName: 'Doe', + }); + }); + + test('findOneById should return null if user not found', async () => { + const user = await usersRepository.findOneById('3'); + expect(user).toBeNull(); + }); + + test('findOneByEmail should return a user by email', async () => { + const user = await usersRepository.findOneByEmail('jane@example.com'); + expect(user).toEqual({ + id: '2', + email: 'jane@example.com', + firstName: 'Jane', + lastName: 'Smith', + }); + }); + + test('findOneByEmail should return null if user not found', async () => { + const user = await usersRepository.findOneByEmail('nonexistent@example.com'); + expect(user).toBeNull(); + }); +}); diff --git a/libs/users/domain/src/lib/users-repository.interface.ts b/libs/users/domain/src/lib/users-repository.interface.ts new file mode 100644 index 0000000..90f45a8 --- /dev/null +++ b/libs/users/domain/src/lib/users-repository.interface.ts @@ -0,0 +1,8 @@ +import { User } from './user.entity'; + +export interface UsersRepository { + findOneById(id: string): Promise; + findOneByEmail(email: string): Promise; +} + +export const USERS_REPOSITORY = Symbol('USERS_REPOSITORY'); \ No newline at end of file From 9504bdb3dc56c584c1c26e9386be6fd1f86acb28 Mon Sep 17 00:00:00 2001 From: zhumeisongsong Date: Tue, 17 Dec 2024 12:41:02 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20=E2=99=BB=EF=B8=8F=20use=20case?= =?UTF-8?q?=20uses=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../get-user-by-email.use-case.spec.ts | 70 ++++---- .../use-cases/get-user-by-email.use-case.ts | 12 +- .../use-cases/get-user-by-id.use-case.spec.ts | 66 ++++---- .../lib/use-cases/get-user-by-id.use-case.ts | 15 +- .../application/src/lib/users.service.spec.ts | 92 +++++------ .../application/src/lib/users.service.ts | 30 ++-- .../domain/src/lib/users.repository.spec.ts | 60 ------- libs/users/domain/src/lib/users.repository.ts | 8 - package.json | 1 + pnpm-lock.yaml | 151 +++++++++++++++++- 10 files changed, 293 insertions(+), 212 deletions(-) delete mode 100644 libs/users/domain/src/lib/users.repository.spec.ts delete mode 100644 libs/users/domain/src/lib/users.repository.ts diff --git a/libs/users/application/src/lib/use-cases/get-user-by-email.use-case.spec.ts b/libs/users/application/src/lib/use-cases/get-user-by-email.use-case.spec.ts index d575708..3c693f9 100644 --- a/libs/users/application/src/lib/use-cases/get-user-by-email.use-case.spec.ts +++ b/libs/users/application/src/lib/use-cases/get-user-by-email.use-case.spec.ts @@ -1,45 +1,49 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { NotFoundException } from '@nestjs/common'; import { GetUserByEmailUseCase } from './get-user-by-email.use-case'; -import { UsersRepository } from '@users/domain'; +import { UsersService } from '../users.service'; describe('GetUserByEmailUseCase', () => { - let getUserByEmailUseCase: GetUserByEmailUseCase; - let usersRepository: UsersRepository; - - beforeEach(() => { - usersRepository = { - findOneById: jest.fn(), - findOneByEmail: jest.fn(), - }; - getUserByEmailUseCase = new GetUserByEmailUseCase(usersRepository); + let useCase: GetUserByEmailUseCase; + let usersService: UsersService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + GetUserByEmailUseCase, + { + provide: UsersService, + useValue: { + findOneByEmail: jest.fn(), + }, + }, + ], + }).compile(); + + useCase = module.get(GetUserByEmailUseCase); + usersService = module.get(UsersService); + }); + + it('should be defined', () => { + expect(useCase).toBeDefined(); }); describe('execute', () => { - it('should return user when found', async () => { - const mockUser = { - id: '1', - email: 'test@example.com', - firstName: 'John', - lastName: 'Doe', - }; - (usersRepository.findOneByEmail as jest.Mock).mockResolvedValue(mockUser); - - const result = await getUserByEmailUseCase.execute('test@example.com'); - - expect(result).toEqual(mockUser); - expect(usersRepository.findOneByEmail).toHaveBeenCalledWith( - 'test@example.com', - ); - }); + it('should return a user when found', async () => { + const mockUser = { id: '1', email: 'test@test.com', firstName: 'John', lastName: 'Doe' }; + jest.spyOn(usersService, 'findOneByEmail').mockResolvedValue(mockUser); - it('should return null when user not found', async () => { - (usersRepository.findOneByEmail as jest.Mock).mockResolvedValue(null); + const result = await useCase.execute('test@test.com'); + + expect(result).toBe(mockUser); + expect(usersService.findOneByEmail).toHaveBeenCalledWith('test@test.com'); + }); - const result = await getUserByEmailUseCase.execute('test@example.com'); + it('should throw NotFoundException when user is not found', async () => { + jest.spyOn(usersService, 'findOneByEmail').mockRejectedValue(new NotFoundException()); - expect(result).toBeNull(); - expect(usersRepository.findOneByEmail).toHaveBeenCalledWith( - 'test@example.com', - ); + await expect(useCase.execute('test@test.com')).rejects.toThrow(NotFoundException); + expect(usersService.findOneByEmail).toHaveBeenCalledWith('test@test.com'); }); }); }); diff --git a/libs/users/application/src/lib/use-cases/get-user-by-email.use-case.ts b/libs/users/application/src/lib/use-cases/get-user-by-email.use-case.ts index d98366a..d1129f8 100644 --- a/libs/users/application/src/lib/use-cases/get-user-by-email.use-case.ts +++ b/libs/users/application/src/lib/use-cases/get-user-by-email.use-case.ts @@ -1,14 +1,14 @@ -import { Inject, Injectable } from "@nestjs/common"; -import { User, USERS_REPOSITORY, UsersRepository } from "@users/domain"; +import { Injectable } from "@nestjs/common"; +import { User } from "@users/domain"; +import { UsersService } from "../users.service"; @Injectable() export class GetUserByEmailUseCase { constructor( - @Inject(USERS_REPOSITORY) - private readonly usersRepository: UsersRepository, + private readonly usersService: UsersService, ) {} - async execute(email: string): Promise { - return this.usersRepository.findOneByEmail(email); + async execute(email: string): Promise { + return this.usersService.findOneByEmail(email); } } diff --git a/libs/users/application/src/lib/use-cases/get-user-by-id.use-case.spec.ts b/libs/users/application/src/lib/use-cases/get-user-by-id.use-case.spec.ts index a167ff8..ddc1cdd 100644 --- a/libs/users/application/src/lib/use-cases/get-user-by-id.use-case.spec.ts +++ b/libs/users/application/src/lib/use-cases/get-user-by-id.use-case.spec.ts @@ -1,41 +1,49 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { NotFoundException } from '@nestjs/common'; import { GetUserByIdUseCase } from './get-user-by-id.use-case'; -import { UsersRepository } from '@users/domain'; +import { UsersService } from '../users.service'; describe('GetUserByIdUseCase', () => { - let getUserByIdUseCase: GetUserByIdUseCase; - let usersRepository: UsersRepository; - - beforeEach(() => { - usersRepository = { - findOneById: jest.fn(), - findOneByEmail: jest.fn(), - }; - getUserByIdUseCase = new GetUserByIdUseCase(usersRepository); + let useCase: GetUserByIdUseCase; + let usersService: UsersService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + GetUserByIdUseCase, + { + provide: UsersService, + useValue: { + findOneById: jest.fn(), + }, + }, + ], + }).compile(); + + useCase = module.get(GetUserByIdUseCase); + usersService = module.get(UsersService); + }); + + it('should be defined', () => { + expect(useCase).toBeDefined(); }); describe('execute', () => { - it('should return user when found', async () => { - const mockUser = { - id: '1', - email: 'test@example.com', - firstName: 'John', - lastName: 'Doe', - }; - (usersRepository.findOneById as jest.Mock).mockResolvedValue(mockUser); - - const result = await getUserByIdUseCase.execute('1'); - - expect(result).toEqual(mockUser); - expect(usersRepository.findOneById).toHaveBeenCalledWith('1'); - }); + it('should return a user when found', async () => { + const mockUser = { id: '1', email: 'test@test.com', firstName: 'John', lastName: 'Doe' }; + jest.spyOn(usersService, 'findOneById').mockResolvedValue(mockUser); - it('should return null when user not found', async () => { - (usersRepository.findOneById as jest.Mock).mockResolvedValue(null); + const result = await useCase.execute('1'); + + expect(result).toBe(mockUser); + expect(usersService.findOneById).toHaveBeenCalledWith('1'); + }); - const result = await getUserByIdUseCase.execute('1'); + it('should throw NotFoundException when user is not found', async () => { + jest.spyOn(usersService, 'findOneById').mockRejectedValue(new NotFoundException()); - expect(result).toBeNull(); - expect(usersRepository.findOneById).toHaveBeenCalledWith('1'); + await expect(useCase.execute('1')).rejects.toThrow(NotFoundException); + expect(usersService.findOneById).toHaveBeenCalledWith('1'); }); }); }); diff --git a/libs/users/application/src/lib/use-cases/get-user-by-id.use-case.ts b/libs/users/application/src/lib/use-cases/get-user-by-id.use-case.ts index ec72ca8..13a8c54 100644 --- a/libs/users/application/src/lib/use-cases/get-user-by-id.use-case.ts +++ b/libs/users/application/src/lib/use-cases/get-user-by-id.use-case.ts @@ -1,14 +1,13 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { User, USERS_REPOSITORY, UsersRepository } from '@users/domain'; +import { Injectable } from '@nestjs/common'; +import { User } from '@users/domain'; + +import { UsersService } from '../users.service'; @Injectable() export class GetUserByIdUseCase { - constructor( - @Inject(USERS_REPOSITORY) - private readonly usersRepository: UsersRepository, - ) {} + constructor(private readonly usersService: UsersService) {} - async execute(id: string): Promise { - return await this.usersRepository.findOneById(id); + async execute(id: string): Promise { + return await this.usersService.findOneById(id); } } diff --git a/libs/users/application/src/lib/users.service.spec.ts b/libs/users/application/src/lib/users.service.spec.ts index 7ac903a..fd1c85c 100644 --- a/libs/users/application/src/lib/users.service.spec.ts +++ b/libs/users/application/src/lib/users.service.spec.ts @@ -1,87 +1,75 @@ import { Test, TestingModule } from '@nestjs/testing'; - +import { NotFoundException } from '@nestjs/common'; import { UsersService } from './users.service'; -import { GetUserByIdUseCase } from './use-cases/get-user-by-id.use-case'; -import { GetUserByEmailUseCase } from './use-cases/get-user-by-email.use-case'; +import { USERS_REPOSITORY } from '@users/domain'; +import { userError } from '@zhumeisong/common-error-exception'; describe('UsersService', () => { let service: UsersService; - let getUserByIdUseCase: GetUserByIdUseCase; - let getUserByEmailUseCase: GetUserByEmailUseCase; + let usersRepository: any; beforeEach(async () => { + usersRepository = { + findOneById: jest.fn(), + findOneByEmail: jest.fn(), + }; + const module: TestingModule = await Test.createTestingModule({ providers: [ UsersService, { - provide: GetUserByIdUseCase, - useValue: { - execute: jest.fn(), - }, - }, - { - provide: GetUserByEmailUseCase, - useValue: { - execute: jest.fn(), - }, + provide: USERS_REPOSITORY, + useValue: usersRepository, }, ], }).compile(); service = module.get(UsersService); - getUserByIdUseCase = module.get(GetUserByIdUseCase); - getUserByEmailUseCase = module.get(GetUserByEmailUseCase); }); - describe('getUserById', () => { - it('should return user when found', async () => { - const mockUser = { - id: '1', - email: 'test@example.com', - firstName: 'John', - lastName: 'Doe', - }; - (getUserByIdUseCase.execute as jest.Mock).mockResolvedValue(mockUser); + it('should be defined', () => { + expect(service).toBeDefined(); + }); + + describe('findOneById', () => { + it('should return a user when found', async () => { + const mockUser = { id: '1', email: 'test@test.com', firstName: 'John', lastName: 'Doe' }; + usersRepository.findOneById.mockResolvedValue(mockUser); const result = await service.findOneById('1'); - expect(result).toEqual(mockUser); - expect(getUserByIdUseCase.execute).toHaveBeenCalledWith('1'); + expect(result).toBe(mockUser); + expect(usersRepository.findOneById).toHaveBeenCalledWith('1'); }); - it('should return null when user not found', async () => { - (getUserByIdUseCase.execute as jest.Mock).mockResolvedValue(null); - - const result = await service.findOneById('1'); + it('should throw NotFoundException when user is not found', async () => { + usersRepository.findOneById.mockResolvedValue(null); - expect(result).toBeNull(); - expect(getUserByIdUseCase.execute).toHaveBeenCalledWith('1'); + await expect(service.findOneById('1')).rejects.toThrow( + new NotFoundException(userError.NOT_FOUND) + ); + expect(usersRepository.findOneById).toHaveBeenCalledWith('1'); }); }); - describe('getUserByEmail', () => { - it('should return user when found', async () => { - const mockUser = { - id: '1', - email: 'test@example.com', - firstName: 'John', - lastName: 'Doe', - }; - (getUserByEmailUseCase.execute as jest.Mock).mockResolvedValue(mockUser); + describe('findOneByEmail', () => { + it('should return a user when found', async () => { + const mockUser = { id: '1', email: 'test@test.com', firstName: 'John', lastName: 'Doe' }; + usersRepository.findOneByEmail.mockResolvedValue(mockUser); - const result = await service.findOneByEmail('test@example.com'); + const result = await service.findOneByEmail('test@test.com'); - expect(result).toEqual(mockUser); - expect(getUserByEmailUseCase.execute).toHaveBeenCalledWith('test@example.com'); + expect(result).toBe(mockUser); + expect(usersRepository.findOneByEmail).toHaveBeenCalledWith('test@test.com'); }); - it('should return null when user not found', async () => { - (getUserByEmailUseCase.execute as jest.Mock).mockResolvedValue(null); - - const result = await service.findOneByEmail('test@example.com'); + it('should throw NotFoundException when user is not found', async () => { + usersRepository.findOneByEmail.mockResolvedValue(null); - expect(result).toBeNull(); - expect(getUserByEmailUseCase.execute).toHaveBeenCalledWith('test@example.com'); + await expect(service.findOneByEmail('test@test.com')).rejects.toThrow( + new NotFoundException(userError.NOT_FOUND) + ); + expect(usersRepository.findOneByEmail).toHaveBeenCalledWith('test@test.com'); }); }); }); diff --git a/libs/users/application/src/lib/users.service.ts b/libs/users/application/src/lib/users.service.ts index c8a0897..35c3b24 100644 --- a/libs/users/application/src/lib/users.service.ts +++ b/libs/users/application/src/lib/users.service.ts @@ -1,21 +1,29 @@ -import { Injectable } from '@nestjs/common'; -import { User } from '@users/domain'; - -import { GetUserByIdUseCase } from './use-cases/get-user-by-id.use-case'; -import { GetUserByEmailUseCase } from './use-cases/get-user-by-email.use-case'; +import { Inject, Injectable, NotFoundException } from '@nestjs/common'; +import { User, USERS_REPOSITORY, UsersRepository } from '@users/domain'; +import { userError } from '@zhumeisong/common-error-exception'; @Injectable() export class UsersService { constructor( - private readonly getUserByIdUseCase: GetUserByIdUseCase, - private readonly getUserByEmailUseCase: GetUserByEmailUseCase, + @Inject(USERS_REPOSITORY) + private readonly usersRepository: UsersRepository, ) {} - async findOneById(id: string): Promise { - return this.getUserByIdUseCase.execute(id); + async findOneById(id: string): Promise { + const user = await this.usersRepository.findOneById(id); + if (!user) { + throw new NotFoundException(userError.NOT_FOUND); + } + + return user; } - async findOneByEmail(email: string): Promise { - return this.getUserByEmailUseCase.execute(email); + async findOneByEmail(email: string): Promise { + const user = await this.usersRepository.findOneByEmail(email); + if (!user) { + throw new NotFoundException(userError.NOT_FOUND); + } + + return user; } } diff --git a/libs/users/domain/src/lib/users.repository.spec.ts b/libs/users/domain/src/lib/users.repository.spec.ts deleted file mode 100644 index 242ab4e..0000000 --- a/libs/users/domain/src/lib/users.repository.spec.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { UsersRepository } from './users.repository'; -import { User } from './user.entity'; - -class MockUsersRepository implements UsersRepository { - private users: User[] = [ - { id: '1', email: 'john@example.com', firstName: 'John', lastName: 'Doe' }, - { - id: '2', - email: 'jane@example.com', - firstName: 'Jane', - lastName: 'Smith', - }, - ]; - - async findOneById(id: string): Promise { - return this.users.find((user) => user.id === id) || null; - } - - async findOneByEmail(email: string): Promise { - return this.users.find((user) => user.email === email) || null; - } -} - -describe('UsersRepository', () => { - let usersRepository: UsersRepository; - - beforeEach(() => { - usersRepository = new MockUsersRepository(); - }); - - test('findOneById should return a user by id', async () => { - const user = await usersRepository.findOneById('1'); - expect(user).toEqual({ - id: '1', - email: 'john@example.com', - firstName: 'John', - lastName: 'Doe', - }); - }); - - test('findOneById should return null if user not found', async () => { - const user = await usersRepository.findOneById('3'); - expect(user).toBeNull(); - }); - - test('findOneByEmail should return a user by email', async () => { - const user = await usersRepository.findOneByEmail('jane@example.com'); - expect(user).toEqual({ - id: '2', - email: 'jane@example.com', - firstName: 'Jane', - lastName: 'Smith', - }); - }); - - test('findOneByEmail should return null if user not found', async () => { - const user = await usersRepository.findOneByEmail('nonexistent@example.com'); - expect(user).toBeNull(); - }); -}); diff --git a/libs/users/domain/src/lib/users.repository.ts b/libs/users/domain/src/lib/users.repository.ts deleted file mode 100644 index 90f45a8..0000000 --- a/libs/users/domain/src/lib/users.repository.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { User } from './user.entity'; - -export interface UsersRepository { - findOneById(id: string): Promise; - findOneByEmail(email: string): Promise; -} - -export const USERS_REPOSITORY = Symbol('USERS_REPOSITORY'); \ No newline at end of file diff --git a/package.json b/package.json index 5fae898..602624e 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@nestjs/mongoose": "^10.1.0", "@nestjs/platform-express": "^10.4.7", "@nestjs/throttler": "^6.2.1", + "@zhumeisong/common-error-exception": "^1.0.2", "aws-sdk": "^2.1692.0", "axios": "^1.7.7", "class-validator": "^0.14.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5385c81..b3fc651 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,6 +44,9 @@ importers: '@nestjs/throttler': specifier: ^6.2.1 version: 6.3.0(@nestjs/common@10.4.15(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(reflect-metadata@0.2.2) + '@zhumeisong/common-error-exception': + specifier: ^1.0.2 + version: 1.0.2 aws-sdk: specifier: ^2.1692.0 version: 2.1692.0 @@ -167,7 +170,7 @@ importers: version: 24.2.0(typescript@5.7.2) ts-jest: specifier: ^29.2.5 - version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@22.10.2)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.7.2)))(typescript@5.7.2) + version: 29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@22.10.2)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.7.2)))(typescript@5.7.2) ts-node: specifier: 10.9.2 version: 10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.7.2) @@ -2314,6 +2317,9 @@ packages: resolution: {integrity: sha512-/HcYgtUSiJiot/XWGLOlGxPYUG65+/31V8oqk17vZLW1xlCoR4PampyePljOxY2n8/3jz9+tIFzICsyGujJZoA==} engines: {node: '>=18.12.0'} + '@zhumeisong/common-error-exception@1.0.2': + resolution: {integrity: sha512-pXO93m1nYsxUeul/TeplnKomznUOVO/skWAG9YUvaytXzUzIDYXYvVPbYa9l2kfAGlwy3/kvAjb8MJqyqLssEg==} + '@zhumeisong/git-cz-config@1.4.2': resolution: {integrity: sha512-99r+1tfvgAHWAFYvlFSAw7rzUB/S8HXdf/aot+/mwBdgF09jwWWbvS62l+MM8SYrHDCc4F4n69A8W9ASqEKk0g==} @@ -4017,6 +4023,9 @@ packages: engines: {node: '>=12'} hasBin: true + http-status-codes@2.3.0: + resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} + https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -7712,21 +7721,45 @@ snapshots: dependencies: '@babel/core': 7.26.0 + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -7757,11 +7790,23 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -7772,41 +7817,89 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.9 + optional: true + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -10531,6 +10624,11 @@ snapshots: js-yaml: 3.14.1 tslib: 2.8.1 + '@zhumeisong/common-error-exception@1.0.2': + dependencies: + '@zhumeisong/semantic-release-config': 1.3.3 + http-status-codes: 2.3.0 + '@zhumeisong/git-cz-config@1.4.2': dependencies: '@zhumeisong/semantic-release-config': 1.3.3 @@ -10566,7 +10664,7 @@ snapshots: agent-base@7.1.1: dependencies: - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -10739,6 +10837,20 @@ snapshots: transitivePeerDependencies: - debug + babel-jest@29.7.0(@babel/core@7.25.8): + dependencies: + '@babel/core': 7.25.8 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.25.8) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + optional: true + babel-jest@29.7.0(@babel/core@7.26.0): dependencies: '@babel/core': 7.26.0 @@ -10846,6 +10958,26 @@ snapshots: optionalDependencies: '@babel/traverse': 7.25.9 + babel-preset-current-node-syntax@1.1.0(@babel/core@7.25.8): + dependencies: + '@babel/core': 7.25.8 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.8) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.8) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.8) + '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.25.8) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.8) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.8) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.8) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.8) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.8) + optional: true + babel-preset-current-node-syntax@1.1.0(@babel/core@7.26.0): dependencies: '@babel/core': 7.26.0 @@ -10865,6 +10997,13 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.26.0) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.26.0) + babel-preset-jest@29.6.3(@babel/core@7.25.8): + dependencies: + '@babel/core': 7.25.8 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.8) + optional: true + babel-preset-jest@29.6.3(@babel/core@7.26.0): dependencies: '@babel/core': 7.26.0 @@ -12502,6 +12641,8 @@ snapshots: - debug - supports-color + http-status-codes@2.3.0: {} + https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 @@ -15147,7 +15288,7 @@ snapshots: tslib: 2.8.1 optional: true - ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@22.10.2)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.7.2)))(typescript@5.7.2): + ts-jest@29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@22.10.2)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.7.2)))(typescript@5.7.2): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -15161,10 +15302,10 @@ snapshots: typescript: 5.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@babel/core': 7.26.0 + '@babel/core': 7.25.8 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.26.0) + babel-jest: 29.7.0(@babel/core@7.25.8) ts-loader@9.5.1(typescript@5.7.2)(webpack@5.96.1): dependencies: