diff --git a/package.json b/package.json index 877ae95..7e741fb 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", - "test": "jest", + "test": "jest --verbose", "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", @@ -39,6 +39,7 @@ "@nestjs/platform-express": "^9.0.0", "@nestjs/swagger": "^6.1.4", "@nestjs/typeorm": "^9.0.1", + "bcrypt": "^5.1.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", "dotenv": "^16.0.3", @@ -71,6 +72,7 @@ "lint-staged": "^13.1.0", "prettier": "^2.3.2", "source-map-support": "^0.5.20", + "sqlite3": "^5.1.6", "supertest": "^6.1.3", "ts-jest": "28.0.8", "ts-loader": "^9.2.3", @@ -93,6 +95,9 @@ "**/*.(t|j)s" ], "coverageDirectory": "../coverage", - "testEnvironment": "node" + "testEnvironment": "node", + "moduleNameMapper": { + "src/(.*)$": "/$1" + } } } diff --git a/src/app.module.ts b/src/app.module.ts index 51696d8..d11a850 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -4,8 +4,10 @@ import { TypeOrmModule } from "@nestjs/typeorm"; import { AppController } from "./app.controller"; import { AppService } from "./app.service"; +import { AuthModule } from "./auth/auth.module"; import { dataSourceOptions } from "./config/data-source"; import { validate } from "./config/env.validation"; +import { UserModule } from "./user/user.module"; @Module({ imports: [ @@ -13,6 +15,8 @@ import { validate } from "./config/env.validation"; validate, }), TypeOrmModule.forRoot(dataSourceOptions), + UserModule, + AuthModule, ], controllers: [AppController], providers: [AppService], diff --git a/src/auth/auth.controller.spec.ts b/src/auth/auth.controller.spec.ts new file mode 100644 index 0000000..ae5d8ce --- /dev/null +++ b/src/auth/auth.controller.spec.ts @@ -0,0 +1,79 @@ +import { ConflictException } from "@nestjs/common"; +import { Test, TestingModule } from "@nestjs/testing"; +import { getRepositoryToken, TypeOrmModule } from "@nestjs/typeorm"; +import { dataSourceJest } from "src/config/data-source"; +import { UserEntity } from "src/user/entities/user.entity"; +import { CreateUserRespose } from "src/user/resposes/create-user-respose"; +import { UserService } from "src/user/user.service"; +import { Repository } from "typeorm"; + +import { CreateUserDto } from "../user/dto/create-user.dto"; +import { AuthController } from "./auth.controller"; +import { AuthService } from "./auth.service"; + +describe("AuthController", () => { + let authController: AuthController; + let authService: AuthService; + let userRepository: Repository; + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [TypeOrmModule.forRoot(dataSourceJest)], + controllers: [AuthController], + providers: [ + AuthService, + UserService, + { + provide: getRepositoryToken(UserEntity), + useValue: UserEntity, // 使用測試資料庫的 Repository + }, + ], + }).compile(); + + authController = module.get(AuthController); + authService = module.get(AuthService); + userRepository = module.get>( + getRepositoryToken(UserEntity), + ); + }); + describe("create", () => { + it("應該會創建一個使用者,並返回 201 狀態碼", async () => { + const createUserDto: CreateUserDto = { + email: "jhon@gmail.com", + name: "displayname", + account: "account", + password: "Password@123", + }; + const expectedResponse: CreateUserRespose = { + statusCode: 201, + message: "創建成功", + }; + jest.spyOn(authService, "register").mockResolvedValue(expectedResponse); + const result = await authController.register(createUserDto); + expect(result).toEqual(expectedResponse); + }); + it("應該會發生資料使用者重覆,並返回 409 狀態碼", async () => { + const createUserDto1: CreateUserDto = { + email: "jhon1@gmail.com", + name: "displayname", + account: "account1", + password: "Password@123", + }; + try { + await authService.register(createUserDto1); + await authService.register(createUserDto1); + } catch (error) { + expect(error).toBeInstanceOf(ConflictException); + expect(error.response).toEqual({ + statusCode: 409, + message: ["email 已被註冊。", "account 已被註冊。"], + error: "Conflict", + }); + } + }); + }); + afterEach(async () => { + if (userRepository && userRepository.clear) { + await userRepository.clear(); + } + }); +}); diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts new file mode 100644 index 0000000..0f4c827 --- /dev/null +++ b/src/auth/auth.controller.ts @@ -0,0 +1,40 @@ +import { Body, Controller, Post } from "@nestjs/common"; +import { + ApiBadRequestResponse, + ApiConflictResponse, + ApiCreatedResponse, + ApiOperation, + ApiTags, +} from "@nestjs/swagger"; +import { CreateUserDto } from "src/user/dto/create-user.dto"; +import { CreateUserBadrequestError } from "src/user/exceptions/create-user-badrequest-error.exception"; +import { CreateUserConflictError } from "src/user/exceptions/create-user-conflict-error.exception"; +import { CreateUserRespose } from "src/user/resposes/create-user-respose"; + +import { AuthService } from "./auth.service"; + +@ApiTags("Auth") +@Controller("auth") +export class AuthController { + constructor(private readonly authService: AuthService) {} + @Post("register") + @ApiOperation({ + summary: "使用者註冊", + description: "會檢查是否重複過的資料", + }) + @ApiCreatedResponse({ + description: "使用者創建成功", + type: CreateUserRespose, + }) + @ApiConflictResponse({ + description: "使用者資料重覆", + type: CreateUserConflictError, + }) + @ApiBadRequestResponse({ + description: "使用者格式不符", + type: CreateUserBadrequestError, + }) + register(@Body() userDto: CreateUserDto) { + return this.authService.register(userDto); + } +} diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts new file mode 100644 index 0000000..72bc4bd --- /dev/null +++ b/src/auth/auth.module.ts @@ -0,0 +1,14 @@ +import { Module } from "@nestjs/common"; +import { TypeOrmModule } from "@nestjs/typeorm"; +import { UserEntity } from "src/user/entities/user.entity"; +import { UserModule } from "src/user/user.module"; + +import { AuthController } from "./auth.controller"; +import { AuthService } from "./auth.service"; + +@Module({ + imports: [UserModule, TypeOrmModule.forFeature([UserEntity])], + controllers: [AuthController], + providers: [AuthService], +}) +export class AuthModule {} diff --git a/src/auth/auth.service.spec.ts b/src/auth/auth.service.spec.ts new file mode 100644 index 0000000..771b808 --- /dev/null +++ b/src/auth/auth.service.spec.ts @@ -0,0 +1,129 @@ +import { ConflictException, HttpStatus } from "@nestjs/common"; +import { Test, TestingModule } from "@nestjs/testing"; +import { getRepositoryToken, TypeOrmModule } from "@nestjs/typeorm"; +import { validate } from "class-validator"; +import { dataSourceJest } from "src/config/data-source"; +import { CreateUserDto } from "src/user/dto/create-user.dto"; +import { UserEntity } from "src/user/entities/user.entity"; +import { UserService } from "src/user/user.service"; +import { Repository } from "typeorm"; + +import { AuthService } from "./auth.service"; + +describe("AuthService", () => { + let authService: AuthService; + let userRepository: Repository; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [TypeOrmModule.forRoot(dataSourceJest)], + providers: [ + AuthService, + UserService, + { + provide: getRepositoryToken(UserEntity), + useValue: UserEntity, // 使用測試資料庫的 Repository + }, + ], + }).compile(); + + authService = module.get(AuthService); + userRepository = module.get>( + getRepositoryToken(UserEntity), + ); + }); + + describe("createUser - Data", () => { + it("應該會創建 一個使用者", async () => { + const test_data: CreateUserDto = { + email: "jhon@gmail.com", + name: "displayname", + account: "account1", + password: "Password@123", + }; + const user = await authService.register(test_data); + + expect(user).toBeDefined(); + expect(user.statusCode).toEqual(HttpStatus.CREATED); + expect(user.message).toEqual("創建成功"); + }); + it("應該會發生 email、account 已被註冊衝突", async () => { + const createUserDto1: CreateUserDto = { + email: "jhon@gmail.com", + name: "displayname", + account: "account", + password: "Password@123", + }; + try { + await authService.register(createUserDto1); + await authService.register(createUserDto1); + } catch (error) { + expect(error).toBeInstanceOf(ConflictException); + expect(error.response).toEqual({ + statusCode: 409, + message: ["email 已被註冊。", "account 已被註冊。"], + error: "Conflict", + }); + } + }); + it("應該會發生 email 已被註冊衝突", async () => { + const test_data1: CreateUserDto = { + email: "jhon@gmail.com", + name: "displayname", + account: "account1", + password: "Password@123", + }; + const test_data2: CreateUserDto = { + email: "jhon@gmail.com", + name: "displayname", + account: "account2", + password: "Password@123", + }; + const errors = await validate(test_data1); + expect(errors.length).toBe(0); + try { + await authService.register(test_data1); + await authService.register(test_data2); + } catch (error) { + expect(error).toBeInstanceOf(ConflictException); + expect(error.response).toEqual({ + statusCode: 409, + message: ["email 已被註冊。"], + error: "Conflict", + }); + } + }); + it("應該會發生 account 已被註冊衝突", async () => { + const test_data1: CreateUserDto = { + email: "jhon@gmail.com", + name: "displayname", + account: "account", + password: "Password@123", + }; + const test_data2: CreateUserDto = { + email: "jhon2@gmail.com", + name: "displayname", + account: "account", + password: "Password@123", + }; + const errors = await validate(test_data1); + expect(errors.length).toBe(0); + try { + await authService.register(test_data1); + await authService.register(test_data2); + } catch (error) { + expect(error).toBeInstanceOf(ConflictException); + expect(error.response).toEqual({ + statusCode: 409, + message: ["account 已被註冊。"], + error: "Conflict", + }); + } + }); + }); + afterEach(async () => { + if (userRepository && userRepository.clear) { + await userRepository.clear(); + } + }); +}); diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts new file mode 100644 index 0000000..7afab79 --- /dev/null +++ b/src/auth/auth.service.ts @@ -0,0 +1,32 @@ +import { ConflictException, Injectable } from "@nestjs/common"; +import { InjectRepository } from "@nestjs/typeorm"; +import { CreateUserDto } from "src/user/dto/create-user.dto"; +import { UserEntity } from "src/user/entities/user.entity"; +import { UserService } from "src/user/user.service"; +import { Repository } from "typeorm"; + +@Injectable() +export class AuthService { + constructor( + private userService: UserService, + @InjectRepository(UserEntity) + private userRepository: Repository, + ) {} + async register(userDto: CreateUserDto) { + const existingUser = await this.userRepository.findOne({ + where: [{ email: userDto.email }, { account: userDto.account }], + }); + + if (existingUser) { + const keys = ["email", "account"]; + const conflictedAttributes = []; + keys.forEach(key => { + if (existingUser[key] === userDto[key]) { + conflictedAttributes.push(key + " 已被註冊。"); + } + }); + throw new ConflictException(conflictedAttributes); + } + return this.userService.create(userDto); + } +} diff --git a/src/config/data-source.ts b/src/config/data-source.ts index c76b8a2..ac0fd77 100644 --- a/src/config/data-source.ts +++ b/src/config/data-source.ts @@ -1,4 +1,5 @@ import * as dotenv from "dotenv"; +import { UserEntity } from "src/user/entities/user.entity"; import { DataSource, DataSourceOptions } from "typeorm"; dotenv.config(); @@ -19,5 +20,12 @@ export const dataSourceOptions: DataSourceOptions = { logging: false, }; +export const dataSourceJest: DataSourceOptions = { + type: "sqlite", + database: ":memory:", + entities: [UserEntity], + synchronize: true, +}; + const dataSource = new DataSource(dataSourceOptions); export default dataSource; diff --git a/src/database/migrations/1685726623031-UserInitMigration.ts b/src/database/migrations/1685726623031-UserInitMigration.ts new file mode 100644 index 0000000..4f8798a --- /dev/null +++ b/src/database/migrations/1685726623031-UserInitMigration.ts @@ -0,0 +1,31 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UserInitMigration1685726623031 implements MigrationInterface { + name = "UserInitMigration1685726623031"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE \`users\` ( + \`id\` int NOT NULL AUTO_INCREMENT, + \`email\` varchar(255) NOT NULL, + \`name\` varchar(255) NOT NULL, + \`account\` varchar(255) NOT NULL, + \`password\` varchar(60) NULL, + \`createdAt\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + UNIQUE INDEX \`IDX_97672ac88f789774dd47f7c8be\` (\`email\`), + UNIQUE INDEX \`IDX_dd44b05034165835d6dcc18d68\` (\`account\`), + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `DROP INDEX \`IDX_dd44b05034165835d6dcc18d68\` ON \`users\``, + ); + await queryRunner.query( + `DROP INDEX \`IDX_97672ac88f789774dd47f7c8be\` ON \`users\``, + ); + await queryRunner.query(`DROP TABLE \`users\``); + } +} diff --git a/src/main.ts b/src/main.ts index caba4c9..542e632 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,9 +3,11 @@ import { NestFactory } from "@nestjs/core"; import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger"; import { AppModule } from "./app.module"; +import { validationPipe } from "./pipes/validation-pipe"; async function bootstrap() { const app = await NestFactory.create(AppModule); + app.useGlobalPipes(validationPipe); setupSwagger(app); await app.listen(3000); } diff --git a/src/pipes/validation-pipe.ts b/src/pipes/validation-pipe.ts new file mode 100644 index 0000000..26991c6 --- /dev/null +++ b/src/pipes/validation-pipe.ts @@ -0,0 +1,9 @@ +import { HttpStatus, ValidationPipe } from "@nestjs/common"; + +export const validationPipe = new ValidationPipe({ + errorHttpStatusCode: HttpStatus.BAD_REQUEST, + stopAtFirstError: false, + disableErrorMessages: false, + transform: true, + whitelist: true, +}); diff --git a/src/user/dto/create-user.dto.spec.ts b/src/user/dto/create-user.dto.spec.ts new file mode 100644 index 0000000..339a671 --- /dev/null +++ b/src/user/dto/create-user.dto.spec.ts @@ -0,0 +1,133 @@ +import { ArgumentMetadata, BadRequestException } from "@nestjs/common"; +import { validationPipe } from "src/pipes/validation-pipe"; + +import { CreateUserDto } from "./create-user.dto"; + +describe("createUser-DTO", () => { + it("應該會發生 email 欄位未填驗證失敗", async () => { + const createUserDto: CreateUserDto = { + email: "", + name: "displayname", + account: "account", + password: "Password@123", + }; + const metadata: ArgumentMetadata = { + type: "body", + metatype: CreateUserDto, + data: "@Body()", + }; + await validationPipe.transform(createUserDto, metadata).catch(error => { + expect(error).toBeInstanceOf(BadRequestException); + expect(error.response).toEqual({ + statusCode: 400, + message: ["email 為必填欄位。", "email 必須是信箱格式。"], + error: "Bad Request", + }); + }); + }); + it("應該會發生 email 欄位格式驗證失敗", async () => { + const createUserDto: CreateUserDto = { + email: "jhon", + name: "displayname", + account: "account", + password: "Password@123", + }; + const metadata: ArgumentMetadata = { + type: "body", + metatype: CreateUserDto, + data: "@Body()", + }; + await validationPipe.transform(createUserDto, metadata).catch(error => { + expect(error).toBeInstanceOf(BadRequestException); + expect(error.response).toEqual({ + statusCode: 400, + message: ["email 必須是信箱格式。"], + error: "Bad Request", + }); + }); + }); + it("應該會發生 name 欄位未填驗證失敗", async () => { + const createUserDto: CreateUserDto = { + email: "jhon@gmail.com", + name: "", + account: "account", + password: "Password@123", + }; + const metadata: ArgumentMetadata = { + type: "body", + metatype: CreateUserDto, + data: "@Body()", + }; + await validationPipe.transform(createUserDto, metadata).catch(error => { + expect(error).toBeInstanceOf(BadRequestException); + expect(error.response).toEqual({ + statusCode: 400, + message: ["name 為必填欄位。"], + error: "Bad Request", + }); + }); + }); + it("應該會發生 account 欄位未填驗證失敗", async () => { + const createUserDto: CreateUserDto = { + email: "jhon@gmail.com", + name: "displayname", + account: "", + password: "Password@123", + }; + const metadata: ArgumentMetadata = { + type: "body", + metatype: CreateUserDto, + data: "@Body()", + }; + await validationPipe.transform(createUserDto, metadata).catch(error => { + expect(error).toBeInstanceOf(BadRequestException); + expect(error.response).toEqual({ + statusCode: 400, + message: ["account 為必填欄位。"], + error: "Bad Request", + }); + }); + }); + it("應該會發生 password 欄位未填驗證失敗", async () => { + const createUserDto: CreateUserDto = { + email: "jhon@gmail.com", + name: "displayname", + account: "account", + password: "", + }; + const metadata: ArgumentMetadata = { + type: "body", + metatype: CreateUserDto, + data: "@Body()", + }; + await validationPipe.transform(createUserDto, metadata).catch(error => { + expect(error).toBeInstanceOf(BadRequestException); + expect(error.response).toEqual({ + statusCode: 400, + message: ["password 必須長度大於等於8個字。", "password 為必填欄位。"], + error: "Bad Request", + }); + }); + }); + it("應該會發生 password 欄位長度驗證失敗", async () => { + const createUserDto: CreateUserDto = { + email: "jhon@gmail.com", + name: "displayname", + account: "account", + password: "123", + }; + const metadata: ArgumentMetadata = { + type: "body", + metatype: CreateUserDto, + data: "@Body()", + }; + await validationPipe.transform(createUserDto, metadata).catch(error => { + expect(error).toBeInstanceOf(BadRequestException); + expect(error.response).toEqual({ + statusCode: 400, + message: ["password 必須長度大於等於8個字。"], + error: "Bad Request", + }); + }); + }); +}); diff --git a/src/user/dto/create-user.dto.ts b/src/user/dto/create-user.dto.ts new file mode 100644 index 0000000..51cbc7e --- /dev/null +++ b/src/user/dto/create-user.dto.ts @@ -0,0 +1,42 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { IsEmail, IsNotEmpty, MinLength } from "class-validator"; + +export class CreateUserDto { + @ApiProperty({ + description: "使用者信箱", + example: "jhon@gmail.com", + }) + @IsEmail({}, { message: "email 必須是信箱格式。" }) + @IsNotEmpty({ + message: "email 為必填欄位。", + }) + public readonly email: string; + + @ApiProperty({ + description: "顯示名", + example: "displayname", + }) + @IsNotEmpty({ + message: "name 為必填欄位。", + }) + public readonly name: string; + + @ApiProperty({ + description: "登入用帳號名", + example: "account", + }) + @IsNotEmpty({ + message: "account 為必填欄位。", + }) + public readonly account: string; + + @ApiProperty({ + description: "使用者密碼", + example: "Password@123", + }) + @IsNotEmpty({ + message: "password 為必填欄位。", + }) + @MinLength(8, { message: "password 必須長度大於等於8個字。" }) + public readonly password: string; +} diff --git a/src/user/entities/user.entity.ts b/src/user/entities/user.entity.ts new file mode 100644 index 0000000..56025a1 --- /dev/null +++ b/src/user/entities/user.entity.ts @@ -0,0 +1,28 @@ +import { + BaseEntity, + Column, + CreateDateColumn, + Entity, + PrimaryGeneratedColumn, +} from "typeorm"; + +@Entity({ name: "users" }) +export class UserEntity extends BaseEntity { + @PrimaryGeneratedColumn() + id: number; + + @Column({ unique: true }) + email: string; + + @Column() + name: string; + + @Column({ unique: true }) + account: string; + + @Column("varchar", { length: 60, nullable: true }) + password: string; + + @CreateDateColumn() + createdAt: Date; +} diff --git a/src/user/exceptions/create-user-badrequest-error.exception.ts b/src/user/exceptions/create-user-badrequest-error.exception.ts new file mode 100644 index 0000000..ef2c7f3 --- /dev/null +++ b/src/user/exceptions/create-user-badrequest-error.exception.ts @@ -0,0 +1,53 @@ +import { ApiProperty } from "@nestjs/swagger"; + +export class CreateUserBadrequestError { + @ApiProperty({ + type: "number", + description: "HTTP 回應代碼", + example: "400", + }) + public readonly statusCode: number; + + @ApiProperty({ + type: "array", + description: "錯誤訊息", + items: { + properties: { + email: { + description: "email 為必填欄位。 \n" + "email 必須是信箱格式。 \n", + type: "string", + }, + name: { + description: "name 為必填欄位。 \n", + type: "string", + }, + account: { + description: "account 為必填欄位。 \n", + type: "string", + }, + password: { + description: + "password 為必填欄位。 \n" + + "password 必須長度大於等於8個字。 \n", + type: "string", + }, + }, + }, + example: [ + "email 為必填欄位。", + "email 必須是信箱格式。", + "name 為必填欄位。", + "account 為必填欄位。", + "password 為必填欄位。", + "password 必須長度大於等於8個字。", + ], + }) + public readonly message: string[]; + + @ApiProperty({ + type: "string", + description: "錯誤狀態碼敘述", + example: "Bad Request", + }) + public readonly error: string; +} diff --git a/src/user/exceptions/create-user-conflict-error.exception.ts b/src/user/exceptions/create-user-conflict-error.exception.ts new file mode 100644 index 0000000..3908f68 --- /dev/null +++ b/src/user/exceptions/create-user-conflict-error.exception.ts @@ -0,0 +1,36 @@ +import { ApiProperty } from "@nestjs/swagger"; + +export class CreateUserConflictError { + @ApiProperty({ + type: "number", + description: "HTTP 回應代碼", + example: "409", + }) + public readonly statusCode: number; + + @ApiProperty({ + type: "array", + description: "錯誤訊息", + items: { + properties: { + email: { + description: "email 已被註冊。 \n", + type: "string", + }, + account: { + description: "account 已被註冊。 \n", + type: "string", + }, + }, + }, + example: ["email 已被註冊。", "account 已被註冊。"], + }) + public readonly message: string[]; + + @ApiProperty({ + type: "string", + description: "錯誤狀態碼敘述", + example: "Conflict", + }) + public readonly error: string; +} diff --git a/src/user/resposes/create-user-respose.ts b/src/user/resposes/create-user-respose.ts new file mode 100644 index 0000000..851cbb0 --- /dev/null +++ b/src/user/resposes/create-user-respose.ts @@ -0,0 +1,17 @@ +import { ApiProperty } from "@nestjs/swagger"; + +export class CreateUserRespose { + @ApiProperty({ + type: "number", + description: "HTTP 回應代碼", + example: "201", + }) + public readonly statusCode: number; + + @ApiProperty({ + type: "number", + description: "創建成功回應", + example: "創建成功", + }) + public readonly message: string; +} diff --git a/src/user/user.module.ts b/src/user/user.module.ts new file mode 100644 index 0000000..01f5337 --- /dev/null +++ b/src/user/user.module.ts @@ -0,0 +1,9 @@ +import { Module } from "@nestjs/common"; + +import { UserService } from "./user.service"; + +@Module({ + providers: [UserService], + exports: [UserService], +}) +export class UserModule {} diff --git a/src/user/user.service.spec.ts b/src/user/user.service.spec.ts new file mode 100644 index 0000000..1b412d0 --- /dev/null +++ b/src/user/user.service.spec.ts @@ -0,0 +1,41 @@ +import { HttpStatus } from "@nestjs/common"; +import { Test, TestingModule } from "@nestjs/testing"; +import { getRepositoryToken, TypeOrmModule } from "@nestjs/typeorm"; +import { dataSourceJest } from "src/config/data-source"; + +import { CreateUserDto } from "./dto/create-user.dto"; +import { UserEntity } from "./entities/user.entity"; +import { UserService } from "./user.service"; + +describe("UserService", () => { + let userService: UserService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [TypeOrmModule.forRoot(dataSourceJest)], + providers: [ + UserService, + { + provide: getRepositoryToken(UserEntity), + useValue: UserEntity, // 使用測試資料庫的 Repository + }, + ], + }).compile(); + + userService = module.get(UserService); + }); + + it("應該會創建 一個使用者", async () => { + const test_data: CreateUserDto = { + email: "jhon@gmail.com", + name: "displayname", + account: "account1", + password: "Password@123", + }; + const user = await userService.create(test_data); + + expect(user).toBeDefined(); + expect(user.statusCode).toEqual(HttpStatus.CREATED); + expect(user.message).toEqual("創建成功"); + }); +}); diff --git a/src/user/user.service.ts b/src/user/user.service.ts new file mode 100644 index 0000000..c9539a4 --- /dev/null +++ b/src/user/user.service.ts @@ -0,0 +1,22 @@ +import { HttpStatus, Injectable } from "@nestjs/common"; +import * as bcrypt from "bcrypt"; + +import { CreateUserDto } from "./dto/create-user.dto"; +import { UserEntity } from "./entities/user.entity"; + +@Injectable() +export class UserService { + async create(userDto: CreateUserDto) { + const hash = await bcrypt.hashSync(userDto.password, 5); + const user = new UserEntity(); + user.name = userDto.name; + user.account = userDto.account; + user.email = userDto.email; + user.password = hash; + await user.save(); + return { + statusCode: HttpStatus.CREATED, + message: "創建成功", + }; + } +} diff --git a/yarn.lock b/yarn.lock index 877caae..0a92e1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -535,6 +535,11 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@gar/promisify@^1.0.1": + version "1.1.3" + resolved "https://registry.npmmirror.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + "@humanwhocodes/config-array@^0.11.8": version "0.11.8" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" @@ -819,6 +824,21 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@mapbox/node-pre-gyp@^1.0.0", "@mapbox/node-pre-gyp@^1.0.10": + version "1.0.10" + resolved "https://registry.npmmirror.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c" + integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA== + dependencies: + detect-libc "^2.0.0" + https-proxy-agent "^5.0.0" + make-dir "^3.1.0" + node-fetch "^2.6.7" + nopt "^5.0.0" + npmlog "^5.0.1" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.11" + "@nestjs/cli@^9.0.0": version "9.1.5" resolved "https://registry.yarnpkg.com/@nestjs/cli/-/cli-9.1.5.tgz#aa150991b209dc2b459c974cc1c43ea10a276ff8" @@ -952,6 +972,22 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@npmcli/fs@^1.0.0": + version "1.1.1" + resolved "https://registry.npmmirror.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" + integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== + dependencies: + "@gar/promisify" "^1.0.1" + semver "^7.3.5" + +"@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.npmmirror.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + "@nuxtjs/opencollective@0.3.2": version "0.3.2" resolved "https://registry.yarnpkg.com/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz#620ce1044f7ac77185e825e1936115bb38e2681c" @@ -985,6 +1021,11 @@ resolved "https://registry.npmmirror.com/@sqltools/formatter/-/formatter-1.2.5.tgz#3abc203c79b8c3e90fd6c156a0c62d5403520e12" integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw== +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.npmmirror.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -1469,6 +1510,11 @@ JSONStream@^1.0.4: jsonparse "^1.2.0" through ">=2.2.7 <3" +abbrev@1: + version "1.1.1" + resolved "https://registry.npmmirror.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" @@ -1497,6 +1543,22 @@ acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== +agent-base@6, agent-base@^6.0.2: + version "6.0.2" + resolved "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agentkeepalive@^4.1.3: + version "4.3.0" + resolved "https://registry.npmmirror.com/agentkeepalive/-/agentkeepalive-4.3.0.tgz#bb999ff07412653c1803b3ced35e50729830a255" + integrity sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg== + dependencies: + debug "^4.1.0" + depd "^2.0.0" + humanize-ms "^1.2.1" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -1616,6 +1678,27 @@ append-field@^1.0.0: resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" integrity sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw== +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.npmmirror.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +are-we-there-yet@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" + integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + +are-we-there-yet@^3.0.0: + version "3.0.1" + resolved "https://registry.npmmirror.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" + integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" @@ -1759,6 +1842,14 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +bcrypt@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/bcrypt/-/bcrypt-5.1.0.tgz#bbb27665dbc400480a524d8991ac7434e8529e17" + integrity sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q== + dependencies: + "@mapbox/node-pre-gyp" "^1.0.10" + node-addon-api "^5.0.0" + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -1863,6 +1954,30 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +cacache@^15.2.0: + version "15.3.0" + resolved "https://registry.npmmirror.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" + integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== + dependencies: + "@npmcli/fs" "^1.0.0" + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -1950,6 +2065,11 @@ chokidar@3.5.3, chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + chrome-trace-event@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" @@ -2095,6 +2215,11 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-support@^1.1.2, color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.npmmirror.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + colorette@^2.0.19: version "2.0.19" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" @@ -2155,6 +2280,11 @@ consola@^2.15.0: resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== +console-control-strings@^1.0.0, console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + content-disposition@0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" @@ -2276,6 +2406,13 @@ debug@2.6.9, debug@^2.6.9: dependencies: ms "2.0.0" +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -2283,13 +2420,6 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - decamelize-keys@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" @@ -2338,12 +2468,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + denque@^2.0.1: version "2.1.0" resolved "https://registry.npmmirror.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== -depd@2.0.0: +depd@2.0.0, depd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -2353,6 +2488,11 @@ destroy@1.2.0: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== +detect-libc@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" + integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== + detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -2454,6 +2594,13 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +encoding@^0.1.12: + version "0.1.13" + resolved "https://registry.npmmirror.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -2469,6 +2616,16 @@ enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0, enhanced-resolve@^5.7.0: graceful-fs "^4.2.4" tapable "^2.2.0" +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.npmmirror.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.npmmirror.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -3011,6 +3168,13 @@ fs-extra@10.1.0, fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + fs-monkey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" @@ -3046,6 +3210,35 @@ functions-have-names@^1.2.2: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +gauge@^3.0.0: + version "3.0.2" + resolved "https://registry.npmmirror.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" + integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.2" + console-control-strings "^1.0.0" + has-unicode "^2.0.1" + object-assign "^4.1.1" + signal-exit "^3.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.2" + +gauge@^4.0.3: + version "4.0.4" + resolved "https://registry.npmmirror.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" + integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + generate-function@^2.3.1: version "2.3.1" resolved "https://registry.npmmirror.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" @@ -3182,6 +3375,11 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +graceful-fs@^4.2.6: + version "4.2.11" + resolved "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + grapheme-splitter@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" @@ -3226,6 +3424,11 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -3260,6 +3463,11 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== +http-cache-semantics@^4.1.0: + version "4.1.1" + resolved "https://registry.npmmirror.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -3271,6 +3479,23 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -3286,6 +3511,13 @@ human-signals@^3.0.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-3.0.1.tgz#c740920859dafa50e5a3222da9d3bf4bb0e5eef5" integrity sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ== +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.npmmirror.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + husky@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.2.tgz#5816a60db02650f1f22c8b69b928fd6bcd77a236" @@ -3298,7 +3530,7 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.6.3: +iconv-lite@^0.6.2, iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -3341,6 +3573,11 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.npmmirror.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -3413,6 +3650,11 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -3496,6 +3738,11 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== + is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" @@ -4305,7 +4552,7 @@ magic-string@0.26.2: dependencies: sourcemap-codec "^1.4.8" -make-dir@^3.0.0: +make-dir@^3.0.0, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== @@ -4317,6 +4564,28 @@ make-error@1.x, make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +make-fetch-happen@^9.1.0: + version "9.1.0" + resolved "https://registry.npmmirror.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" + integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== + dependencies: + agentkeepalive "^4.1.3" + cacache "^15.2.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.2" + promise-retry "^2.0.1" + socks-proxy-agent "^6.0.0" + ssri "^8.0.0" + makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -4449,6 +4718,65 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^1.3.2: + version "1.4.1" + resolved "https://registry.npmmirror.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" + integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== + dependencies: + minipass "^3.1.0" + minipass-sized "^1.0.3" + minizlib "^2.0.0" + optionalDependencies: + encoding "^0.1.12" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.npmmirror.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.npmmirror.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: + version "3.3.6" + resolved "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + +minizlib@^2.0.0, minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.npmmirror.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + mkdirp@^0.5.4: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" @@ -4456,7 +4784,7 @@ mkdirp@^0.5.4: dependencies: minimist "^1.2.6" -mkdirp@^1.0.4: +mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.npmmirror.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -4471,7 +4799,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.1.1: +ms@2.1.3, ms@^2.0.0, ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -4534,7 +4862,7 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -negotiator@0.6.3: +negotiator@0.6.3, negotiator@^0.6.2: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== @@ -4549,6 +4877,16 @@ node-abort-controller@^3.0.1: resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.0.1.tgz#f91fa50b1dee3f909afabb7e261b1e1d6b0cb74e" integrity sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw== +node-addon-api@^4.2.0: + version "4.3.0" + resolved "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" + integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== + +node-addon-api@^5.0.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" + integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== + node-emoji@1.11.0: version "1.11.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" @@ -4563,6 +4901,29 @@ node-fetch@^2.6.1: dependencies: whatwg-url "^5.0.0" +node-fetch@^2.6.7: + version "2.6.11" + resolved "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25" + integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== + dependencies: + whatwg-url "^5.0.0" + +node-gyp@8.x: + version "8.4.1" + resolved "https://registry.npmmirror.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" + integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^9.1.0" + nopt "^5.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -4573,6 +4934,13 @@ node-releases@^2.0.6: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.8.tgz#0f349cdc8fcfa39a92ac0be9bc48b7706292b9ae" integrity sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A== +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -4612,6 +4980,26 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" +npmlog@^5.0.1: + version "5.0.1" + resolved "https://registry.npmmirror.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" + integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== + dependencies: + are-we-there-yet "^2.0.0" + console-control-strings "^1.1.0" + gauge "^3.0.0" + set-blocking "^2.0.0" + +npmlog@^6.0.0: + version "6.0.2" + resolved "https://registry.npmmirror.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" + integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.3" + set-blocking "^2.0.0" + object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -4902,6 +5290,19 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + prompts@^2.0.1: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -5021,6 +5422,15 @@ readable-stream@^2.2.2: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -5118,6 +5528,11 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.npmmirror.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -5264,6 +5679,11 @@ serve-static@1.15.0: parseurl "~1.3.3" send "0.18.0" +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -5307,7 +5727,7 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -5348,6 +5768,28 @@ slice-ansi@^5.0.0: ansi-styles "^6.0.0" is-fullwidth-code-point "^4.0.0" +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.npmmirror.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +socks-proxy-agent@^6.0.0: + version "6.2.1" + resolved "https://registry.npmmirror.com/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz#2687a31f9d7185e38d530bef1944fe1f1496d6ce" + integrity sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + +socks@^2.6.2: + version "2.7.1" + resolved "https://registry.npmmirror.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + source-map-support@0.5.13: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" @@ -5417,11 +5859,29 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +sqlite3@^5.1.6: + version "5.1.6" + resolved "https://registry.npmmirror.com/sqlite3/-/sqlite3-5.1.6.tgz#1d4fbc90fe4fbd51e952e0a90fd8f6c2b9098e97" + integrity sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw== + dependencies: + "@mapbox/node-pre-gyp" "^1.0.0" + node-addon-api "^4.2.0" + tar "^6.1.11" + optionalDependencies: + node-gyp "8.x" + sqlstring@^2.3.2: version "2.3.3" resolved "https://registry.npmmirror.com/sqlstring/-/sqlstring-2.3.3.tgz#2ddc21f03bce2c387ed60680e739922c65751d0c" integrity sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg== +ssri@^8.0.0, ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.npmmirror.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== + dependencies: + minipass "^3.1.1" + stack-utils@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" @@ -5452,7 +5912,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5628,6 +6088,18 @@ tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: + version "6.1.15" + resolved "https://registry.npmmirror.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69" + integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" @@ -5941,6 +6413,20 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.npmmirror.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" @@ -6104,13 +6590,20 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which@^2.0.1: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" +wide-align@^1.1.2, wide-align@^1.1.5: + version "1.1.5" + resolved "https://registry.npmmirror.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + windows-release@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-4.0.0.tgz#4725ec70217d1bf6e02c7772413b29cdde9ec377"