xiongzhu пре 2 година
родитељ
комит
cb232f362a

+ 6 - 1
.env

@@ -59,4 +59,9 @@ MONGO_DB_HOST=120.78.133.82
 MONGO_DB_PORT=27017
 MONGO_DB_USERNAME=admin
 MONGO_DB_PASSWORD=s!wWj4*AvXqyBv
-MONGO_DB_DATABASE=chillgpt
+MONGO_DB_DATABASE=chillgpt
+
+WX_APP_ID=wx55dfde4d982b43fb
+WX_APP_SECRET=33097584ed2af75d5fd04ce15ad1eda8
+WX_MCH_ID=1642294106
+WX_MCH_KEY=SRhVwVEHxx7oR87S8Ce2kQeBtnftjCte

+ 6 - 1
.env.production

@@ -59,4 +59,9 @@ MONGO_DB_HOST=127.0.0.1
 MONGO_DB_PORT=27017
 MONGO_DB_USERNAME=admin
 MONGO_DB_PASSWORD=s!wWj4*AvXqyBv
-MONGO_DB_DATABASE=chillgpt
+MONGO_DB_DATABASE=chillgpt
+
+WX_APP_ID=wx55dfde4d982b43fb
+WX_APP_SECRET=33097584ed2af75d5fd04ce15ad1eda8
+WX_MCH_ID=1642294106
+WX_MCH_KEY=SRhVwVEHxx7oR87S8Ce2kQeBtnftjCte

Разлика између датотеке није приказан због своје велике величине
+ 406 - 84
graph.json


+ 4 - 0
package.json

@@ -30,6 +30,7 @@
     "@nestjs/devtools-integration": "^0.1.4",
     "@nestjs/jwt": "^10.0.1",
     "@nestjs/mapped-types": "1.2.2",
+    "@nestjs/mongoose": "^9.2.2",
     "@nestjs/passport": "^9.0.3",
     "@nestjs/platform-express": "^9.3.3",
     "@nestjs/swagger": "^6.2.1",
@@ -48,6 +49,8 @@
     "handlebars": "^4.7.7",
     "isomorphic-fetch": "^3.0.0",
     "keyv": "^4.5.2",
+    "mongodb": "^5.2.0",
+    "mongoose": "^7.0.4",
     "mysql2": "^3.1.2",
     "nodemailer": "^6.9.1",
     "p-timeout": "^6.1.1",
@@ -59,6 +62,7 @@
     "reflect-metadata": "^0.1.13",
     "rimraf": "^4.1.2",
     "rxjs": "^7.8.0",
+    "tnwx": "^2.5.6",
     "typeorm": "^0.3.12",
     "yup": "^1.0.0"
   },

+ 5 - 1
src/app.module.ts

@@ -12,6 +12,8 @@ import { DevtoolsModule } from '@nestjs/devtools-integration'
 import { AuthModule } from './auth/auth.module'
 import { FileModule } from './file/file.module'
 import { ChatModule } from './chat/chat.module'
+import { MembershipModule } from './membership/membership.module';
+import { WeixinModule } from './weixin/weixin.module';
 
 @Module({
     imports: [
@@ -62,7 +64,9 @@ import { ChatModule } from './chat/chat.module'
         UsersModule,
         AuthModule,
         FileModule,
-        ChatModule
+        ChatModule,
+        MembershipModule,
+        WeixinModule
     ],
     controllers: [AppController],
     providers: [AppService]

+ 5 - 0
src/auth/auth.module.ts

@@ -8,6 +8,7 @@ import { UsersModule } from 'src/users/users.module'
 import { AuthController } from './auth.controller'
 import { APP_GUARD } from '@nestjs/core'
 import { JwtAuthGuard } from './jwt-auth.guard'
+import { RolesGuard } from './roles.guard'
 
 @Module({
     imports: [ConfigModule.forFeature(jwtConfig), JwtModule.registerAsync(jwtConfig.asProvider()), UsersModule],
@@ -17,6 +18,10 @@ import { JwtAuthGuard } from './jwt-auth.guard'
         {
             provide: APP_GUARD,
             useClass: JwtAuthGuard
+        },
+        {
+            provide: APP_GUARD,
+            useClass: RolesGuard
         }
     ],
     controllers: [AuthController],

+ 6 - 0
src/auth/roles.decorator.ts

@@ -0,0 +1,6 @@
+import { SetMetadata } from '@nestjs/common';
+
+export const HAS_ROLES_KEY = 'hasRoles';
+export const HAS_ANY_ROLES_KEY = 'hasAnyRoles';
+export const HasRoles = (...roles: string[]) => SetMetadata(HAS_ROLES_KEY, roles);
+export const HasAnyRoles = (...roles: string[]) => SetMetadata(HAS_ANY_ROLES_KEY, roles);

+ 49 - 0
src/auth/roles.guard.ts

@@ -0,0 +1,49 @@
+import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'
+import { Reflector } from '@nestjs/core'
+import { HAS_ANY_ROLES_KEY, HAS_ROLES_KEY } from './roles.decorator'
+import { Role } from 'src/model/role.enum'
+
+@Injectable()
+export class RolesGuard implements CanActivate {
+    constructor(private reflector: Reflector) {}
+
+    canActivate(context: ExecutionContext): boolean {
+        const classRoles = this.reflector.get<Role[]>(HAS_ROLES_KEY, context.getClass())
+        const classAnyRoles = this.reflector.get<Role[]>(HAS_ANY_ROLES_KEY, context.getClass())
+
+        const roles = this.reflector.get<Role[]>(HAS_ROLES_KEY, context.getHandler())
+        const anyRoles = this.reflector.get<Role[]>(HAS_ANY_ROLES_KEY, context.getHandler())
+        if (!classRoles && !classAnyRoles && !roles && !anyRoles) {
+            return true
+        }
+
+        let result = true
+        const request = context.switchToHttp().getRequest()
+        const userRoles = request.user?.roles || []
+
+        if (classRoles) {
+            result = result && matchAll(classRoles, userRoles)
+        }
+
+        if (classAnyRoles) {
+            result = result && matchAny(classAnyRoles, userRoles)
+        }
+
+        if (roles) {
+            result = result && matchAll(roles, userRoles)
+        }
+
+        if (anyRoles) {
+            result = result && matchAny(anyRoles, userRoles)
+        }
+        return result
+    }
+}
+
+function matchAny(roles: Role[], userRoles: Role[]) {
+    return roles.some((role) => userRoles.includes(role))
+}
+
+function matchAll(roles: Role[], userRoles: Role[]) {
+    return roles.every((role) => userRoles.includes(role))
+}

BIN
src/cert/apiclient_cert.p12


+ 25 - 0
src/cert/apiclient_cert.pem

@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEMTCCAxmgAwIBAgIUeW8mXMOVl6wUlIzqYMzeYD8xyyAwDQYJKoZIhvcNAQEL
+BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
+FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
+Q0EwHhcNMjMwNDE4MDcwMDQwWhcNMjgwNDE2MDcwMDQwWjCBijETMBEGA1UEAwwK
+MTY0MjI5NDEwNjEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTYwNAYDVQQL
+DC3ljY7lgqjoibrmnK/lk4HkuK3lv4PvvIjmt7HlnLPvvInmnInpmZDlhazlj7gx
+CzAJBgNVBAYMAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBANDIBJ5vzhjJOwzfHWPiqKzvWGqRF3zjQr6kJ/e+2c5l
+xBB6gtC6FoiwuuYPZBrwggtEkIzjGbNn0mESWbcr8msX60zi5cANV8fInbXsz78/
+x7kPv0eWeARMy7tO9umR1VuxfQYkoRdQb5JeBu5y8CWqLY/p2y80soh/ygxpx6wM
+UfBP6p9zY8bSJlCyH6GOkcZVvGsmhbYkY8HYObH72AM8aX0gzTuYaWarT+J9h5jo
+dNzXTkh5ubTsbS9Nce76GggjS4irAtXMQGURdAG63OiAGPpbk95WhTy+rZvA/BiV
+1o1sMAcFi+oaF3aYqYH16Gcs8+K/mlTKqxnZSz7vkjkCAwEAAaOBuTCBtjAJBgNV
+HRMEAjAAMAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0
+cDovL2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIw
+RTUwREJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0
+MjJFMTJCMjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUA
+A4IBAQCSFb0sRjwaqeaSGhVb3VMLiLh5ck0gy8+8N6LQHoesh8Oi3HkfDQEEG0O+
+aouDISMhyg1eMi21X1xNG4gy/EXtwZlzNRjWqfYfTlvC6Fil2fDv9BC+gEFdz77U
+1wOu2EI0RQ6lrawjqZTtKntLN6XO63WrlMftrEKmBXkgIUakQvtbJbuz4rEdseOB
+34z1dqwyFgu+KriUQcD1QVlGBMTNMVovU3G5Ri5xxV2+gPloAzuhBUZ1H3GNqP/x
+hG3RS+E/10B0Hp8HUOkyoK0kdqCTj67RSB1Ad6vr6Ls/HeE5gERI2T1HEeycCzdt
+aiy1vOfgqjpeqRBzolwuVVBg26l0
+-----END CERTIFICATE-----

+ 28 - 0
src/cert/apiclient_key.pem

@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDQyASeb84YyTsM
+3x1j4qis71hqkRd840K+pCf3vtnOZcQQeoLQuhaIsLrmD2Qa8IILRJCM4xmzZ9Jh
+Elm3K/JrF+tM4uXADVfHyJ217M+/P8e5D79HlngETMu7TvbpkdVbsX0GJKEXUG+S
+XgbucvAlqi2P6dsvNLKIf8oMacesDFHwT+qfc2PG0iZQsh+hjpHGVbxrJoW2JGPB
+2Dmx+9gDPGl9IM07mGlmq0/ifYeY6HTc105Iebm07G0vTXHu+hoII0uIqwLVzEBl
+EXQButzogBj6W5PeVoU8vq2bwPwYldaNbDAHBYvqGhd2mKmB9ehnLPPiv5pUyqsZ
+2Us+75I5AgMBAAECggEAC9Gm4Uk3A5QwsZPX2BW2ssOB39aC2+EJoD0uvgmhzttX
+9A7bZPGD4Q0QJ4HritLeqcCh5jfc9pkEAdbGGWZ1fLaH7XxSwUKAG6ExvGDBifQU
+XFeV3nmYJbYrOllIBQTqbRxpFXXxYJ5/EmwcPFdpXNh7Z9A3Rj7XdH63c2hxkz2t
+Hf8xK9SCFjH67gfmC8w9jHZqjXnveMY8/CAH6O+P4+eGWNMT97nLla2/5jKmkJ0Y
+0w4/ixjT5wboXnOktMq9jNIMqayv6NcShQSK+LrSfjz8UE1zwG2JXlJyElDc5Y9f
+yvD4EdX9Ce1jelf0elY1srNJLIcAt1kT/CfZIWRuGQKBgQDuJss5pSap85PGNAV0
+6A8Tv8ilH8K4VTiUrmOsbYf5le1/RZxOjcGyGERAbf8Aq4GwhnMkpFFjx9+zEEt/
+p/e3tDPybekr9aDM1lg+e9TzV61uqCfGXg24lYO1/EXKAGx+GgMnXHBjvSEBlU+l
+w5O1nik1cBczVBiwMR+1ptOtVwKBgQDgbbkw1pQUlYz1/C+g8nl3E6oAh/DHQePS
+OZzY0+BsDq1LEpJg89LmQ68g2OyaTIKuzE/VpCHHylq95Ddpnzuh+oj71Pin/If1
+jWh6Bh6MVsI0YCg04Bv2M97j+UIdo/E402jTeo2Bm+Zbl1p8EHMIWtGExkbifktZ
+ojc38OBy7wKBgQDJTPlTDIoV9dHfI3HJU64K331WNfZ9oWtmIdIWma7qBRTvE4P/
+0kr7ow9t9owpoM7Ky5rgShSR5wzrasambPAy05tlPApwIft9qWCF0F48IsxyUKju
+P+oRMDBYz5ieGqWaIZqw1q4ZYHBZyj+8ughM6BelF85EkL0dkShgf1dFmQKBgQDb
+6kjM1YdXQFBXfl3Bjbh+eZNdX9gNuMAgcPoD8mJ4IE2pQbKUNHhV0L8cJdR7QjvQ
+Qz57r5C2cNBIQQgXhMPvbkuq0b8zBR7I/F8DK1nl1OIKZqsfXPepYpynsckauFoY
+f/i5Od7NwVGSMJam+YtvBWdHfu9Y4768P1tygqO9mwKBgDteDZYqE/XHaPIKS7rv
+uwXOOJvMnQxbuC9ftxUW+iRAud51GiYhIizYSgxiVG4ZteSZRWSANu0un1WnDFW5
+AC+bUhP+7BMawy3cz/b6HOgl4gjcCsMT3CSuXngxjzWSFmv0rb41Z18yoN2KTqVs
+rPMkpjXa7NQLx/8mneBhnGpu
+-----END PRIVATE KEY-----

+ 12 - 0
src/membership/dto/memberPlan.dto.ts

@@ -0,0 +1,12 @@
+import { IsNumber, IsString } from 'class-validator'
+
+export class MemberPlanDto {
+    @IsString()
+    name: string
+
+    @IsNumber()
+    price: number
+
+    @IsNumber()
+    duration: number
+}

+ 4 - 0
src/membership/dto/membership.dto.ts

@@ -0,0 +1,4 @@
+import { IsNumber } from 'class-validator'
+
+export class MembershipDto {
+}

+ 20 - 0
src/membership/entities/memberPlan.entity.ts

@@ -0,0 +1,20 @@
+import { ApiTags } from '@nestjs/swagger'
+import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn } from 'typeorm'
+
+@Entity()
+export class MemberPlan {
+    @PrimaryGeneratedColumn()
+    id: number
+
+    @Column()
+    name: string
+
+    @Column()
+    price: number
+    
+    @Column()
+    duration: number
+
+    @CreateDateColumn()
+    createdAt: Date
+}

+ 17 - 0
src/membership/entities/membership.entity.ts

@@ -0,0 +1,17 @@
+import { ApiProperty } from '@nestjs/swagger'
+import { Column, CreateDateColumn, Entity, PrimaryColumn, PrimaryGeneratedColumn } from 'typeorm'
+
+@Entity()
+export class Membership {
+    @PrimaryColumn()
+    userId: number
+
+    @Column()
+    expireAt: Date
+
+    @Column()
+    planId: number
+
+    @CreateDateColumn()
+    createdAt: Date
+}

+ 17 - 0
src/membership/membership.admin.controller.ts

@@ -0,0 +1,17 @@
+import { Public } from 'src/auth/public.decorator'
+import { MembershipService } from './membership.service'
+import { Body, Controller, Get, Post, Req } from '@nestjs/common'
+import { MemberPlanDto } from './dto/memberPlan.dto'
+import { HasRoles } from 'src/auth/roles.decorator'
+import { Role } from 'src/model/role.enum'
+
+@Controller('/admin/membership')
+@HasRoles(Role.Admin)
+export class MembershipAdminController {
+    constructor(private readonly membershipService: MembershipService) {}
+
+    @Post('/save')
+    async save(@Body() memberPlanDto: MemberPlanDto) {
+        return await this.membershipService.save(memberPlanDto)
+    }
+}

+ 24 - 0
src/membership/membership.controller.ts

@@ -0,0 +1,24 @@
+import { Public } from 'src/auth/public.decorator'
+import { MembershipService } from './membership.service'
+import { Body, Controller, Get, Post, Req } from '@nestjs/common'
+
+@Controller('/membership')
+export class MembershipController {
+    constructor(private readonly membershipService: MembershipService) {}
+
+    @Get('/get')
+    async getMembership(@Req() req) {
+        return this.membershipService.getMembership(req.user.id)
+    }
+
+    @Post('/renew')
+    async renewMembership(@Req() req, @Body() body: { planId: number }) {
+        return this.membershipService.renewMembership(req.user.id, body.planId)
+    }
+
+    @Public()
+    @Get('/plans')
+    async getPlans() {
+        return await this.membershipService.getPlans()
+    }
+}

+ 14 - 0
src/membership/membership.module.ts

@@ -0,0 +1,14 @@
+import { Module } from '@nestjs/common'
+import { MembershipService } from './membership.service'
+import { MembershipController } from './membership.controller'
+import { TypeOrmModule } from '@nestjs/typeorm'
+import { Membership } from './entities/membership.entity'
+import { MemberPlan } from './entities/memberPlan.entity'
+import { MembershipAdminController } from './membership.admin.controller'
+
+@Module({
+    imports: [TypeOrmModule.forFeature([Membership, MemberPlan]), TypeOrmModule.forFeature([MemberPlan])],
+    providers: [MembershipService],
+    controllers: [MembershipController, MembershipAdminController]
+})
+export class MembershipModule {}

+ 58 - 0
src/membership/membership.service.ts

@@ -0,0 +1,58 @@
+import { Injectable, NotFoundException } from '@nestjs/common'
+import { InjectRepository } from '@nestjs/typeorm'
+import { Membership } from './entities/membership.entity'
+import { Repository } from 'typeorm'
+import { MemberPlan } from './entities/memberPlan.entity'
+import { addDays } from 'date-fns'
+import { MemberPlanDto } from './dto/memberPlan.dto'
+@Injectable()
+export class MembershipService {
+    constructor(
+        @InjectRepository(Membership) private readonly memberShipRepository: Repository<Membership>,
+        @InjectRepository(MemberPlan) private readonly memberPlanRepository: Repository<MemberPlan>
+    ) {}
+
+    async renewMembership(userId: number, planId: number) {
+        const plan = await this.memberPlanRepository.findOneBy({
+            id: planId
+        })
+        if (!plan) {
+            throw new NotFoundException(`Plan #${planId} not found`)
+        }
+        let membership = await this.memberShipRepository.findOneBy({
+            userId: userId
+        })
+        if (!membership) {
+            membership = new Membership()
+            membership.userId = userId
+            membership.planId = planId
+            membership.expireAt = addDays(new Date(), plan.duration)
+        } else {
+            if (membership.expireAt < new Date()) {
+                membership.expireAt = addDays(new Date(), plan.duration)
+            } else {
+                membership.expireAt = addDays(membership.expireAt, plan.duration)
+            }
+        }
+        await this.memberShipRepository.save(membership)
+        return 'renewed'
+    }
+
+    async getMembership(userId: number) {
+        const membership = await this.memberShipRepository.findOneBy({
+            userId: userId
+        })
+        if (!membership) {
+            throw new NotFoundException(`Membership #${userId} not found`)
+        }
+        return membership
+    }
+
+    async getPlans() {
+        return await this.memberPlanRepository.find()
+    }
+
+    async save(memberPlanDto: MemberPlanDto) {
+        return await this.memberPlanRepository.save(memberPlanDto)
+    }
+}

+ 0 - 16
src/migrations/1589834500772-Api.ts

@@ -1,16 +0,0 @@
-import { MigrationInterface, QueryRunner } from 'typeorm'
-
-export class Api1589834500772 implements MigrationInterface {
-    name = 'Api1589834500772'
-
-    public async up(queryRunner: QueryRunner): Promise<void> {
-        await queryRunner.query(
-            'CREATE TABLE `user` (`id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `username` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(60) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB',
-            undefined
-        )
-    }
-
-    public async down(queryRunner: QueryRunner): Promise<void> {
-        await queryRunner.query('DROP TABLE `user`', undefined)
-    }
-}

+ 10 - 7
src/users/entities/users.entity.ts

@@ -1,4 +1,4 @@
-import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
+import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn } from 'typeorm'
 import { Role } from '../../model/role.enum'
 
 @Entity()
@@ -13,20 +13,23 @@ export class Users {
     username: string
 
     @Column({ nullable: true })
-    avatar: string
+    avatar?: string
 
     @Column({ unique: true, nullable: true })
-    email: string
+    email?: string
 
-    @Column({ length: 60, nullable: true })
-    password: string
+    @Column({ nullable: true })
+    password?: string
 
-    @Column({ length: 20, unique: true, nullable: true })
-    phone: string
+    @Column({ nullable: true, unique: true })
+    phone?: string
 
     @Column({ type: 'set', enum: Role, default: Role.User })
     roles: Role[]
 
     @Column({ nullable: true })
     invitor?: number
+
+    @CreateDateColumn()
+    createdAt: Date
 }

+ 2 - 2
src/users/interfaces/users.interface.ts

@@ -2,6 +2,6 @@ export interface IUsers {
     readonly id: number
     readonly name: string
     readonly username: string
-    readonly email: string
-    readonly password: string
+    readonly email?: string
+    readonly password?: string
 }

+ 0 - 140
src/users/users.controller.spec.ts

@@ -1,140 +0,0 @@
-import { BadRequestException, NotFoundException } from '@nestjs/common'
-import { Test, TestingModule } from '@nestjs/testing'
-import { UserProfileDto } from './dto/user-profile.dto'
-import { UserDto } from './dto/user.dto'
-import { UsersController } from './users.controller'
-import { UsersService } from './users.service'
-
-const userDto: UserDto = {
-    name: 'name #1',
-    username: 'username #1',
-    email: 'test@example.com',
-    password: 'password123'
-}
-
-const userUpdateDto: UserDto = {
-    name: 'name #1 update',
-    username: 'username #1 update',
-    email: 'test@example.com',
-    password: 'password123'
-}
-
-const userProfileDto: UserProfileDto = {
-    name: 'name #1',
-    username: 'username #1',
-    email: 'test@example.com'
-}
-
-describe('Users Controller', () => {
-    let usersController: UsersController
-    let usersService: UsersService
-
-    beforeEach(async () => {
-        const module: TestingModule = await Test.createTestingModule({
-            controllers: [UsersController],
-            providers: [
-                {
-                    provide: UsersService,
-                    useValue: {
-                        findAll: jest.fn(() => {}),
-                        findById: jest.fn(() => userDto),
-                        updateProfileUser: jest.fn(() => {}),
-                        updateUser: jest.fn(() => {}),
-                        deleteUser: jest.fn(() => userDto)
-                    }
-                }
-            ]
-        }).compile()
-
-        usersController = module.get<UsersController>(UsersController)
-        usersService = module.get<UsersService>(UsersService)
-    })
-
-    describe('Users Controller', () => {
-        it('should be defined', () => {
-            expect(usersController).toBeDefined()
-        })
-
-        describe('findAllUser() method', () => {
-            it('should call method findAllUser in userService', async () => {
-                const createSpy = jest.spyOn(usersService, 'findAll')
-
-                await usersController.findAllUser()
-                expect(createSpy).toHaveBeenCalled()
-            })
-        })
-
-        describe('findOneUser() method', () => {
-            it('should call method findOneUser in userService', async () => {
-                const createSpy = jest.spyOn(usersService, 'findById')
-
-                await usersController.findOneUser('anyid')
-                expect(createSpy).toHaveBeenCalledWith('anyid')
-            })
-        })
-
-        describe('findById() method', () => {
-            it('should call method getUser in userService', async () => {
-                const createSpy = jest.spyOn(usersService, 'findById')
-
-                await usersController.getUser('1')
-                expect(createSpy).toHaveBeenCalledWith('1')
-            })
-
-            it('should return an exception if update user fails', async () => {
-                usersService.findById = jest.fn().mockResolvedValueOnce(null)
-                await expect(usersController.getUser('not correct id')).rejects.toThrow(NotFoundException)
-            })
-        })
-
-        describe('updateProfileUser() method', () => {
-            it('should call method updateProfileUser in userService', async () => {
-                const createSpy = jest.spyOn(usersService, 'updateProfileUser')
-
-                await usersController.updateProfileUser('1', userProfileDto)
-                expect(createSpy).toHaveBeenCalledWith('1', userProfileDto)
-            })
-
-            it('should return an exception if update profile user fails', async () => {
-                usersService.updateProfileUser = jest.fn().mockRejectedValueOnce(null)
-                await expect(
-                    usersController.updateProfileUser('not a correct id', {
-                        name: 'not a correct name',
-                        username: 'not a correct username',
-                        email: 'not a correct email'
-                    })
-                ).rejects.toThrow(BadRequestException)
-            })
-        })
-
-        describe('updateUser() method', () => {
-            it('should call method updateUser in userService', async () => {
-                const createSpy = jest.spyOn(usersService, 'updateUser')
-
-                await usersController.updateUser('1', userUpdateDto)
-                expect(createSpy).toHaveBeenCalledWith('1', userUpdateDto)
-            })
-
-            it('should return an exception if update user fails', async () => {
-                usersService.updateUser = jest.fn().mockRejectedValueOnce(null)
-                await expect(
-                    usersController.updateUser('not a correct id', {
-                        name: 'not a correct name',
-                        username: 'not a correct username',
-                        email: 'not a correct email',
-                        password: 'not a correct password'
-                    })
-                ).rejects.toThrow(BadRequestException)
-            })
-        })
-
-        describe('deleteUser() method', () => {
-            it('should call method deleteUser in userService', async () => {
-                const createSpy = jest.spyOn(usersService, 'deleteUser')
-
-                await usersController.deleteUser('anyid')
-                expect(createSpy).toHaveBeenCalledWith('anyid')
-            })
-        })
-    })
-})

+ 3 - 0
src/users/users.controller.ts

@@ -16,6 +16,8 @@ import { UserProfileDto } from './dto/user-profile.dto'
 import { UserUpdateDto } from './dto/user-update.dto'
 import { IUsers } from './interfaces/users.interface'
 import { ApiTags } from '@nestjs/swagger'
+import { HasRoles } from 'src/auth/roles.decorator'
+import { Role } from 'src/model/role.enum'
 
 @ApiTags('users')
 @Controller('users')
@@ -27,6 +29,7 @@ export class UsersController {
         return this.usersService.findById(req.user.userId)
     }
 
+ 
     @Post('/update')
     public async update(@Body() userProfileDto: UserProfileDto, @Req() req): Promise<any> {
         try {

+ 0 - 235
src/users/users.service.spec.ts

@@ -1,235 +0,0 @@
-import { HttpException, HttpStatus, NotFoundException } from '@nestjs/common'
-import { Test, TestingModule } from '@nestjs/testing'
-import { getRepositoryToken } from '@nestjs/typeorm'
-import { Repository } from 'typeorm'
-import { BcryptService } from '../shared/hashing/bcrypt.service'
-import { HashingService } from '../shared/hashing/hashing.service'
-import { UserDto } from './dto/user.dto'
-import { Users } from './entities/users.entity'
-import { UsersService } from './users.service'
-
-const userArray = [
-    {
-        id: 1,
-        name: 'name #1',
-        username: 'username #1',
-        email: 'test1@example.com',
-        password: 'pass123'
-    },
-    {
-        id: 2,
-        name: 'name #2',
-        username: 'username #2',
-        email: 'test2@example.com',
-        password: 'pass123'
-    }
-]
-
-const oneUser = {
-    id: 1,
-    name: 'name #1',
-    username: 'username #1',
-    email: 'test@example.com',
-    password: 'pass123'
-}
-
-const createUser: UserDto = {
-    name: 'name #1',
-    username: 'username #1',
-    email: 'test@example.com',
-    password: 'pass123'
-}
-
-const updateUserByEmail = {
-    name: 'name #1',
-    username: 'username #1',
-    email: 'test@example.com',
-    password: 'pass123'
-}
-
-const updateUserByPassword = {
-    name: 'name #1',
-    username: 'username #1',
-    email: 'test@example.com',
-    password: 'pass123'
-}
-
-const updateProfileUser = {
-    name: 'name #1',
-    username: 'username #1',
-    email: 'test@example.com',
-    password: 'pass123'
-}
-
-const updateUser = {
-    id: 1,
-    name: 'name #1 update',
-    username: 'username #1 update',
-    email: 'test@example.com',
-    password: 'pass123'
-}
-
-describe('UsersService', () => {
-    let service: UsersService
-    let repository: Repository<Users>
-
-    beforeEach(async () => {
-        const module: TestingModule = await Test.createTestingModule({
-            providers: [
-                UsersService,
-                {
-                    provide: HashingService,
-                    useClass: BcryptService
-                },
-                {
-                    provide: getRepositoryToken(Users),
-                    useValue: {
-                        find: jest.fn().mockResolvedValue(userArray),
-                        findOne: jest.fn().mockResolvedValue(oneUser),
-                        findOneBy: jest.fn().mockResolvedValueOnce(oneUser),
-                        save: jest.fn().mockReturnValue(createUser),
-                        updateByEmail: jest.fn().mockResolvedValue(updateUserByEmail),
-                        updateByPassword: jest.fn().mockResolvedValue(updateUserByPassword),
-                        updateProfileUser: jest.fn().mockResolvedValue(updateProfileUser),
-                        update: jest.fn().mockReturnValue(updateUser),
-                        remove: jest.fn()
-                    }
-                }
-            ]
-        }).compile()
-
-        service = module.get<UsersService>(UsersService)
-        repository = module.get<Repository<Users>>(getRepositoryToken(Users))
-    })
-
-    it('should be defined', () => {
-        expect(service).toBeDefined()
-    })
-
-    describe('findAll() method', () => {
-        it('should return an array of all users', async () => {
-            const users = await service.findAll()
-            expect(users).toEqual(userArray)
-        })
-    })
-
-    describe('findByEmail() method', () => {
-        it('should find a user by email', async () => {
-            expect(await service.findByEmail('test@example.com')).toEqual(oneUser)
-        })
-
-        it('should throw an exception if it not found a user by email', async () => {
-            repository.findOneBy = jest.fn().mockResolvedValueOnce(null)
-            await expect(service.findByEmail('not a correct email')).rejects.toThrow(NotFoundException)
-        })
-    })
-    describe('findById() method', () => {
-        it('should find a user by id', async () => {
-            expect(await service.findById('anyid')).toEqual(oneUser)
-        })
-
-        it('should throw an exception if it not found a user by id', async () => {
-            repository.findOneBy = jest.fn().mockResolvedValueOnce(null)
-            await expect(service.findById('not a correct id')).rejects.toThrow(NotFoundException)
-        })
-    })
-
-    describe('create() method', () => {
-        it('should create a new user', async () => {
-            expect(
-                await service.create({
-                    name: 'name #1',
-                    username: 'username #1',
-                    email: 'test@example.com',
-                    password: 'pass123'
-                })
-            ).toEqual(createUser)
-        })
-
-        it('should return an exception if login fails', async () => {
-            repository.save = jest.fn().mockRejectedValueOnce(null)
-            await expect(
-                service.create({
-                    name: 'not a correct name',
-                    username: 'not a correct username',
-                    email: 'not a correct email',
-                    password: 'not a correct password'
-                })
-            ).rejects.toThrow(HttpException)
-        })
-    })
-
-    describe('updateByEmail() method', () => {
-        it('should update a user by email', async () => {
-            expect(await service.updateByEmail('test@example.com')).toEqual(updateUserByEmail)
-        })
-
-        it('should return an exception if update by email fails', async () => {
-            repository.save = jest.fn().mockRejectedValueOnce(null)
-            await expect(service.updateByEmail('not a correct email')).rejects.toThrow(HttpException)
-        })
-    })
-
-    describe('updateByPassword() method', () => {
-        it('should update a user by password', async () => {
-            expect(await service.updateByPassword('test@example.com', 'pass123')).toEqual(updateUserByPassword)
-        })
-
-        it('should return an exception if update by password fails', async () => {
-            repository.save = jest.fn().mockRejectedValueOnce(null)
-            await expect(service.updateByPassword('not a correct email', 'not correct password')).rejects.toThrow(
-                HttpException
-            )
-        })
-    })
-
-    describe('updateProfileUser() method', () => {
-        it('should update profile of a user by id', async () => {
-            expect(await service.updateProfileUser('anyid', updateProfileUser)).toEqual(updateProfileUser)
-        })
-
-        it('should return an exception if update profile user fails', async () => {
-            repository.save = jest.fn().mockRejectedValueOnce(null)
-            await expect(
-                service.updateProfileUser('not a correct id', {
-                    name: 'not a correct name',
-                    username: 'not a correct username',
-                    email: 'not a correct email'
-                })
-            ).rejects.toThrow(HttpException)
-        })
-    })
-
-    describe('updateUser() method', () => {
-        it('should update a user by id', async () => {
-            expect(await service.updateUser('anyid', updateUser)).toEqual(updateUser)
-        })
-
-        it('should return an exception if update profile user fails', async () => {
-            repository.update = jest.fn().mockRejectedValueOnce(null)
-            await expect(
-                service.updateUser('not a correct id', {
-                    name: 'not a correct name',
-                    username: 'not a correct username',
-                    email: 'not a correct email',
-                    password: 'not a correct password'
-                })
-            ).rejects.toThrow(HttpException)
-        })
-    })
-
-    describe('deleteUser() method', () => {
-        it('should remove a user by id', async () => {
-            const removeSpy = jest.spyOn(repository, 'remove')
-            const user = await service.deleteUser('any id')
-            expect(removeSpy).toBeCalledWith(oneUser)
-            expect(user).toBeUndefined()
-        })
-
-        it('should throw an error if no user is found with an id', async () => {
-            repository.findOneBy = jest.fn().mockResolvedValueOnce(undefined)
-            await expect(service.deleteUser('bad id')).rejects.toThrow(NotFoundException)
-            expect(repository.findOneBy).toBeCalledTimes(1)
-        })
-    })
-})

+ 15 - 0
src/weixin/weixin.config.ts

@@ -0,0 +1,15 @@
+import { ConfigService, registerAs } from '@nestjs/config'
+import { config } from 'dotenv'
+
+config()
+
+const configService = new ConfigService()
+
+export default registerAs('weixin', () => {
+    return {
+        appId: configService.get<string>('WX_APP_ID'),
+        appSecret: configService.get<string>('WX_APP_SECRET'),
+        mchId: configService.get<string>('WX_MCH_ID'),
+        mchKey: configService.get<string>('WX_MCH_KEY')
+    }
+})

+ 4 - 0
src/weixin/weixin.controller.ts

@@ -0,0 +1,4 @@
+import { Controller } from '@nestjs/common';
+
+@Controller('weixin')
+export class WeixinController {}

+ 9 - 0
src/weixin/weixin.module.ts

@@ -0,0 +1,9 @@
+import { Module } from '@nestjs/common';
+import { WeixinController } from './weixin.controller';
+import { WeixinService } from './weixin.service';
+
+@Module({
+  controllers: [WeixinController],
+  providers: [WeixinService]
+})
+export class WeixinModule {}

+ 4 - 0
src/weixin/weixin.service.ts

@@ -0,0 +1,4 @@
+import { Injectable } from '@nestjs/common';
+
+@Injectable()
+export class WeixinService {}

+ 505 - 10
yarn.lock

@@ -856,6 +856,11 @@
   resolved "https://registry.npmmirror.com/@nestjs/mapped-types/-/mapped-types-1.2.2.tgz#d9ddb143776e309dbc1a518ac1607fddac1e140e"
   integrity sha512-3dHxLXs3M0GPiriAcCFFJQHoDFUuzTD5w6JDhE7TyfT89YKpe6tcCCIqOZWdXmt9AZjjK30RkHRSFF+QEnWFQg==
 
+"@nestjs/mongoose@^9.2.2":
+  version "9.2.2"
+  resolved "https://registry.npmmirror.com/@nestjs/mongoose/-/mongoose-9.2.2.tgz#104f9eb57f5f5841a96f6e4ae08a6e1904ef0b93"
+  integrity sha512-szNuSUCwwbQSSeiTh8+tZ9fHV4nuzHwBDROb0hX0s7crwY15TunCfwyKbB2XjqkEQWUAasDeCBuKOJSL9N6tTg==
+
 "@nestjs/passport@^9.0.3":
   version "9.0.3"
   resolved "https://registry.npmmirror.com/@nestjs/passport/-/passport-9.0.3.tgz#4df0e6de3176e04a5770cb432e58f129c8e49f9e"
@@ -968,6 +973,83 @@
   resolved "https://registry.npmmirror.com/@sqltools/formatter/-/formatter-1.2.5.tgz#3abc203c79b8c3e90fd6c156a0c62d5403520e12"
   integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==
 
+"@tnwx/accesstoken@^2.5.6":
+  version "2.5.6"
+  resolved "https://registry.npmmirror.com/@tnwx/accesstoken/-/accesstoken-2.5.6.tgz#f77ff9faac7ea85e5a8e90f26cf1a64f076a33a9"
+  integrity sha512-Mr+LmNwLWXjeLH9chKMa3FFQRQ9B8cgVA4Vk5fgrORl5a9vcfi6ym+EU1VPXI9/VXnPogbb5eat7aN9Zbye78A==
+  dependencies:
+    "@tnwx/cache" "^2.5.6"
+    "@tnwx/kits" "^2.5.6"
+
+"@tnwx/cache@^2.5.6":
+  version "2.5.6"
+  resolved "https://registry.npmmirror.com/@tnwx/cache/-/cache-2.5.6.tgz#855cc1bf9c6f33de2e61533f6cbbc4059541f6df"
+  integrity sha512-9sWzfhLt/XfgS0Av7iStp8/nu5ck9j9TuOD51H0Tw1rk/pXpJs4HKVw54wyBILG8BagNYrGydwyJYu3ia5t53Q==
+
+"@tnwx/commons@^2.5.6":
+  version "2.5.6"
+  resolved "https://registry.npmmirror.com/@tnwx/commons/-/commons-2.5.6.tgz#b0c79d70cc19bada99d8dcaf68fe378e271de414"
+  integrity sha512-4KNjSxHfzsLkzBgawxnXrdNXiOC2hWDst81eyJQAfGqCmXJpWsELTdFq7H7nHR1tpbb9Nj2XYh+k0IuteS/WGA==
+  dependencies:
+    "@tnwx/accesstoken" "^2.5.6"
+    "@tnwx/cache" "^2.5.6"
+    "@tnwx/kits" "^2.5.6"
+
+"@tnwx/kits@^2.5.6":
+  version "2.5.6"
+  resolved "https://registry.npmmirror.com/@tnwx/kits/-/kits-2.5.6.tgz#44e816d3688b7e1902ecaee41fa830850c367a01"
+  integrity sha512-l/xBjZ8FSy51gOvh+rfUUPSB1MLBg9JYsN2N4rwnOwcb2WtkkdK279K0Uiw4/ND3L4vIpwGMR0L3DKHJVOwXXQ==
+  dependencies:
+    axios "^0.19.0"
+    concat-stream "^2.0.0"
+    request "^2.88.0"
+    urlencode "^1.1.0"
+    uuid "^3.3.3"
+    xml2js "^0.4.22"
+
+"@tnwx/miniprogram@^2.5.6":
+  version "2.5.6"
+  resolved "https://registry.npmmirror.com/@tnwx/miniprogram/-/miniprogram-2.5.6.tgz#d8c9ccf191d861661523fd06536c9b5cc2e14840"
+  integrity sha512-IeNVaQWfgomcioJipcEgmNp6r3VBWJS67DyW++UwUyZa+PtmK6Nr3168lXuwTA2M8OOQOenQ8UC04urm1FPumw==
+  dependencies:
+    "@tnwx/commons" "^2.5.6"
+
+"@tnwx/opencp@^2.5.6":
+  version "2.5.6"
+  resolved "https://registry.npmmirror.com/@tnwx/opencp/-/opencp-2.5.6.tgz#20472d4cbb22d37d61e5e26f05321c63c449e9fb"
+  integrity sha512-TxsQ9WOp9GOhFWaH0i8c66OcmgvqA6J2x7FSLuGC3QE2+LbCi4eey5O8ViRTwZ3JL0v4vcEic1zqnRQPOrF6UQ==
+  dependencies:
+    "@tnwx/commons" "^2.5.6"
+
+"@tnwx/openmp@^2.5.6":
+  version "2.5.6"
+  resolved "https://registry.npmmirror.com/@tnwx/openmp/-/openmp-2.5.6.tgz#3aa3c8c050dd57e5e5f288b13d0f7d4ba79b8464"
+  integrity sha512-YhCI34VaA2zajnM4Rs/Xd5VscTENYspaU4e0CpRIw1ZflwVdWjSBW1lwG/5DxgOT/b1f/u1n7Uh51sdjr1QRWQ==
+  dependencies:
+    "@tnwx/commons" "^2.5.6"
+
+"@tnwx/wxcp@^2.5.6":
+  version "2.5.6"
+  resolved "https://registry.npmmirror.com/@tnwx/wxcp/-/wxcp-2.5.6.tgz#1a65b0b4927abd33d9c2a791fc78d52718079b65"
+  integrity sha512-CBqag7OaV2A42/xg6M96sM7vL2zYjDhTXwsPVbwRodvSP/v+5QT2iPJh72EGsdWEjJ+0EFuPRb/aRi/e5oVYhQ==
+  dependencies:
+    "@tnwx/commons" "^2.5.6"
+
+"@tnwx/wxmp@^2.5.6":
+  version "2.5.6"
+  resolved "https://registry.npmmirror.com/@tnwx/wxmp/-/wxmp-2.5.6.tgz#fe6113f23182f81a032bbbe252289f2a57efabea"
+  integrity sha512-9k64beuCiZ+bgj2MAsjtq4cohF9OMZ+VBex2U4TmPn3zhzjK0MlNIa24UoyxPDx+eykpkBHgruNo4gLjH8quSw==
+  dependencies:
+    "@tnwx/commons" "^2.5.6"
+
+"@tnwx/wxpay@^2.5.6":
+  version "2.5.6"
+  resolved "https://registry.npmmirror.com/@tnwx/wxpay/-/wxpay-2.5.6.tgz#9acd9977abb7ce3ce18319604dad659f227d8a62"
+  integrity sha512-ujJ0nrAZvCwNId5LWZKFfTz1vDTO2rHcA5Pu+91Nf4aZ27Y+bNdoAtKuTgMUB3PlxNsNVBJzQ+xJtR9Byp4rvA==
+  dependencies:
+    "@tnwx/cache" "^2.5.6"
+    "@tnwx/kits" "^2.5.6"
+
 "@tootallnate/once@1":
   version "1.1.2"
   resolved "https://registry.npmmirror.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
@@ -1237,6 +1319,19 @@
   dependencies:
     "@types/superagent" "*"
 
+"@types/webidl-conversions@*":
+  version "7.0.0"
+  resolved "https://registry.npmmirror.com/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz#2b8e60e33906459219aa587e9d1a612ae994cfe7"
+  integrity sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==
+
+"@types/whatwg-url@^8.2.1":
+  version "8.2.2"
+  resolved "https://registry.npmmirror.com/@types/whatwg-url/-/whatwg-url-8.2.2.tgz#749d5b3873e845897ada99be4448041d4cc39e63"
+  integrity sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==
+  dependencies:
+    "@types/node" "*"
+    "@types/webidl-conversions" "*"
+
 "@types/xml2js@^0.4.5":
   version "0.4.11"
   resolved "https://registry.npmmirror.com/@types/xml2js/-/xml2js-0.4.11.tgz#bf46a84ecc12c41159a7bd9cf51ae84129af0e79"
@@ -1545,7 +1640,7 @@ ajv@8.12.0, ajv@^8.0.0:
     require-from-string "^2.0.2"
     uri-js "^4.2.2"
 
-ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5:
+ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
   version "6.12.6"
   resolved "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
   integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
@@ -1694,6 +1789,18 @@ asap@^2.0.0:
   resolved "https://registry.npmmirror.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
   integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
 
+asn1@~0.2.3:
+  version "0.2.6"
+  resolved "https://registry.npmmirror.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
+  integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==
+  dependencies:
+    safer-buffer "~2.1.0"
+
+assert-plus@1.0.0, assert-plus@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.npmmirror.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+  integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==
+
 ast-types@^0.13.2:
   version "0.13.4"
   resolved "https://registry.npmmirror.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782"
@@ -1706,6 +1813,23 @@ asynckit@^0.4.0:
   resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
   integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
 
+aws-sign2@~0.7.0:
+  version "0.7.0"
+  resolved "https://registry.npmmirror.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
+  integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==
+
+aws4@^1.8.0:
+  version "1.12.0"
+  resolved "https://registry.npmmirror.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3"
+  integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==
+
+axios@^0.19.0:
+  version "0.19.2"
+  resolved "https://registry.npmmirror.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
+  integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
+  dependencies:
+    follow-redirects "1.5.10"
+
 axios@^1.3.5:
   version "1.3.5"
   resolved "https://registry.npmmirror.com/axios/-/axios-1.3.5.tgz#e07209b39a0d11848e3e341fa087acd71dadc542"
@@ -1792,6 +1916,13 @@ basic-auth@^2.0.1:
   dependencies:
     safe-buffer "5.1.2"
 
+bcrypt-pbkdf@^1.0.0:
+  version "1.0.2"
+  resolved "https://registry.npmmirror.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
+  integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==
+  dependencies:
+    tweetnacl "^0.14.3"
+
 bcrypt@^5.1.0:
   version "5.1.0"
   resolved "https://registry.npmmirror.com/bcrypt/-/bcrypt-5.1.0.tgz#bbb27665dbc400480a524d8991ac7434e8529e17"
@@ -1901,6 +2032,11 @@ bser@2.1.1:
   dependencies:
     node-int64 "^0.4.0"
 
+bson@^5.0.1, bson@^5.2.0:
+  version "5.2.0"
+  resolved "https://registry.npmmirror.com/bson/-/bson-5.2.0.tgz#c81d35dd30e2798203e5422a639780ea98dd25ba"
+  integrity sha512-HevkSpDbpUfsrHWmWiAsNavANKYIErV2ePXllp1bwq5CDreAaFVj6RVlZpJnxK4WWDCJ/5jMUpaY6G526q3Hjg==
+
 buffer-equal-constant-time@1.0.1:
   version "1.0.1"
   resolved "https://registry.npmmirror.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
@@ -1972,6 +2108,11 @@ caniuse-lite@^1.0.30001449:
   resolved "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz#0ef8a1cf8b16be47a0f9fc4ecfc952232724b32a"
   integrity sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw==
 
+caseless@~0.12.0:
+  version "0.12.0"
+  resolved "https://registry.npmmirror.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+  integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==
+
 chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2:
   version "4.1.2"
   resolved "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
@@ -2152,7 +2293,7 @@ color-support@^1.1.2:
   resolved "https://registry.npmmirror.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
   integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
 
-combined-stream@^1.0.8:
+combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
   version "1.0.8"
   resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
   integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
@@ -2189,6 +2330,16 @@ concat-stream@^1.5.2:
     readable-stream "^2.2.2"
     typedarray "^0.0.6"
 
+concat-stream@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmmirror.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1"
+  integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==
+  dependencies:
+    buffer-from "^1.0.0"
+    inherits "^2.0.3"
+    readable-stream "^3.0.2"
+    typedarray "^0.0.6"
+
 consola@^2.15.0:
   version "2.15.3"
   resolved "https://registry.npmmirror.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550"
@@ -2241,6 +2392,11 @@ copy-to@^2.0.1:
   resolved "https://registry.npmmirror.com/copy-to/-/copy-to-2.0.1.tgz#2680fbb8068a48d08656b6098092bdafc906f4a5"
   integrity sha512-3DdaFaU/Zf1AnpLiFDeNCD4TOWe3Zl2RZaTzUvWiIk5ERzcCodOE20Vqq4fzCbNoHURFHT4/us/Lfq+S2zyY4w==
 
+core-util-is@1.0.2:
+  version "1.0.2"
+  resolved "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+  integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==
+
 core-util-is@^1.0.2, core-util-is@~1.0.0:
   version "1.0.3"
   resolved "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
@@ -2284,6 +2440,13 @@ crypt@0.0.2:
   resolved "https://registry.npmmirror.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
   integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==
 
+dashdash@^1.12.0:
+  version "1.14.1"
+  resolved "https://registry.npmmirror.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+  integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==
+  dependencies:
+    assert-plus "^1.0.0"
+
 data-uri-to-buffer@3:
   version "3.0.1"
   resolved "https://registry.npmmirror.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636"
@@ -2306,13 +2469,20 @@ debug@2.6.9, debug@^2.2.0, 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.4:
+debug@4, debug@4.x, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, 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.1.0:
+  version "3.1.0"
+  resolved "https://registry.npmmirror.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
+  integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
+  dependencies:
+    ms "2.0.0"
+
 dedent@^0.7.0:
   version "0.7.0"
   resolved "https://registry.npmmirror.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
@@ -2436,6 +2606,14 @@ dotenv@16.0.3, dotenv@^16.0.3:
   resolved "https://registry.npmmirror.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07"
   integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==
 
+ecc-jsbn@~0.1.1:
+  version "0.1.2"
+  resolved "https://registry.npmmirror.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
+  integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==
+  dependencies:
+    jsbn "~0.1.0"
+    safer-buffer "^2.1.0"
+
 ecdsa-sig-formatter@1.0.11:
   version "1.0.11"
   resolved "https://registry.npmmirror.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
@@ -2780,6 +2958,11 @@ extend-shallow@^2.0.1:
   dependencies:
     is-extendable "^0.1.0"
 
+extend@~3.0.2:
+  version "3.0.2"
+  resolved "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
+  integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
+
 external-editor@^3.0.3:
   version "3.1.0"
   resolved "https://registry.npmmirror.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495"
@@ -2789,6 +2972,16 @@ external-editor@^3.0.3:
     iconv-lite "^0.4.24"
     tmp "^0.0.33"
 
+extsprintf@1.3.0:
+  version "1.3.0"
+  resolved "https://registry.npmmirror.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
+  integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==
+
+extsprintf@^1.2.0:
+  version "1.4.1"
+  resolved "https://registry.npmmirror.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07"
+  integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==
+
 fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
   version "3.1.3"
   resolved "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@@ -2907,11 +3100,23 @@ flatted@^3.1.0:
   resolved "https://registry.npmmirror.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
   integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
 
+follow-redirects@1.5.10:
+  version "1.5.10"
+  resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
+  integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
+  dependencies:
+    debug "=3.1.0"
+
 follow-redirects@^1.15.0:
   version "1.15.2"
   resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
   integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
 
+forever-agent@~0.6.1:
+  version "0.6.1"
+  resolved "https://registry.npmmirror.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+  integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==
+
 fork-ts-checker-webpack-plugin@8.0.0:
   version "8.0.0"
   resolved "https://registry.npmmirror.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz#dae45dfe7298aa5d553e2580096ced79b6179504"
@@ -2939,6 +3144,15 @@ form-data@^4.0.0:
     combined-stream "^1.0.8"
     mime-types "^2.1.12"
 
+form-data@~2.3.2:
+  version "2.3.3"
+  resolved "https://registry.npmmirror.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
+  integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
+  dependencies:
+    asynckit "^0.4.0"
+    combined-stream "^1.0.6"
+    mime-types "^2.1.12"
+
 formidable@^2.1.2:
   version "2.1.2"
   resolved "https://registry.npmmirror.com/formidable/-/formidable-2.1.2.tgz#fa973a2bec150e4ce7cac15589d7a25fc30ebd89"
@@ -3096,6 +3310,13 @@ get-uri@3:
     fs-extra "^8.1.0"
     ftp "^0.3.10"
 
+getpass@^0.1.1:
+  version "0.1.7"
+  resolved "https://registry.npmmirror.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
+  integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==
+  dependencies:
+    assert-plus "^1.0.0"
+
 glob-parent@^5.1.2, glob-parent@~5.1.2:
   version "5.1.2"
   resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@@ -3204,6 +3425,19 @@ handlebars@^4.7.7:
   optionalDependencies:
     uglify-js "^3.1.4"
 
+har-schema@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmmirror.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
+  integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==
+
+har-validator@~5.1.3:
+  version "5.1.5"
+  resolved "https://registry.npmmirror.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
+  integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
+  dependencies:
+    ajv "^6.12.3"
+    har-schema "^2.0.0"
+
 has-flag@^3.0.0:
   version "3.0.0"
   resolved "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@@ -3266,6 +3500,15 @@ http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1:
     agent-base "6"
     debug "4"
 
+http-signature@~1.2.0:
+  version "1.2.0"
+  resolved "https://registry.npmmirror.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
+  integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==
+  dependencies:
+    assert-plus "^1.0.0"
+    jsprim "^1.2.2"
+    sshpk "^1.7.0"
+
 https-proxy-agent@5, 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"
@@ -3299,7 +3542,7 @@ humanize-ms@^1.2.0, humanize-ms@^1.2.1:
   dependencies:
     ms "^2.0.0"
 
-iconv-lite@0.4.24, iconv-lite@^0.4.15, iconv-lite@^0.4.24:
+iconv-lite@0.4.24, iconv-lite@^0.4.15, iconv-lite@^0.4.24, iconv-lite@~0.4.11:
   version "0.4.24"
   resolved "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
   integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@@ -3514,6 +3757,11 @@ is-type-of@^1.0.0:
     is-class-hotfix "~0.0.6"
     isstream "~0.1.2"
 
+is-typedarray@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
+  integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==
+
 is-unicode-supported@^0.1.0:
   version "0.1.0"
   resolved "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
@@ -3994,6 +4242,11 @@ js-yaml@^3.13.1:
     argparse "^1.0.7"
     esprima "^4.0.0"
 
+jsbn@~0.1.0:
+  version "0.1.1"
+  resolved "https://registry.npmmirror.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+  integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==
+
 jsesc@^2.5.1:
   version "2.5.2"
   resolved "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
@@ -4019,11 +4272,21 @@ json-schema-traverse@^1.0.0:
   resolved "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
   integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
 
+json-schema@0.4.0:
+  version "0.4.0"
+  resolved "https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
+  integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
+
 json-stable-stringify-without-jsonify@^1.0.1:
   version "1.0.1"
   resolved "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
   integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
 
+json-stringify-safe@~5.0.1:
+  version "5.0.1"
+  resolved "https://registry.npmmirror.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+  integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
+
 json5@^2.2.2, json5@^2.2.3:
   version "2.2.3"
   resolved "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
@@ -4060,6 +4323,16 @@ jsonwebtoken@9.0.0, jsonwebtoken@^9.0.0:
     ms "^2.1.1"
     semver "^7.3.8"
 
+jsprim@^1.2.2:
+  version "1.4.2"
+  resolved "https://registry.npmmirror.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb"
+  integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==
+  dependencies:
+    assert-plus "1.0.0"
+    extsprintf "1.3.0"
+    json-schema "0.4.0"
+    verror "1.10.0"
+
 jstoxml@^2.0.0:
   version "2.2.9"
   resolved "https://registry.npmmirror.com/jstoxml/-/jstoxml-2.2.9.tgz#2eebd5e55383fe66a375022ca0aa88f77bc4fb84"
@@ -4082,6 +4355,11 @@ jws@^3.2.2:
     jwa "^1.4.1"
     safe-buffer "^5.0.1"
 
+kareem@2.5.1:
+  version "2.5.1"
+  resolved "https://registry.npmmirror.com/kareem/-/kareem-2.5.1.tgz#7b8203e11819a8e77a34b3517d3ead206764d15d"
+  integrity sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==
+
 keyv@^4.5.2:
   version "4.5.2"
   resolved "https://registry.npmmirror.com/keyv/-/keyv-4.5.2.tgz#0e310ce73bf7851ec702f2eaf46ec4e3805cce56"
@@ -4262,6 +4540,11 @@ memfs@^3.4.1:
   dependencies:
     fs-monkey "^1.0.3"
 
+memory-pager@^1.0.2:
+  version "1.5.0"
+  resolved "https://registry.npmmirror.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5"
+  integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==
+
 merge-descriptors@1.0.1, merge-descriptors@^1.0.1:
   version "1.0.1"
   resolved "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
@@ -4295,7 +4578,7 @@ mime-db@1.52.0:
   resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
   integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
 
-mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34:
+mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34:
   version "2.1.35"
   resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
   integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
@@ -4392,6 +4675,61 @@ mkdirp@^2.1.3:
   resolved "https://registry.npmmirror.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19"
   integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==
 
+mongodb-connection-string-url@^2.6.0:
+  version "2.6.0"
+  resolved "https://registry.npmmirror.com/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz#57901bf352372abdde812c81be47b75c6b2ec5cf"
+  integrity sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==
+  dependencies:
+    "@types/whatwg-url" "^8.2.1"
+    whatwg-url "^11.0.0"
+
+mongodb@5.1.0:
+  version "5.1.0"
+  resolved "https://registry.npmmirror.com/mongodb/-/mongodb-5.1.0.tgz#e551f9e496777bde9173e51d16c163ab2c805b9d"
+  integrity sha512-qgKb7y+EI90y4weY3z5+lIgm8wmexbonz0GalHkSElQXVKtRuwqXuhXKccyvIjXCJVy9qPV82zsinY0W1FBnJw==
+  dependencies:
+    bson "^5.0.1"
+    mongodb-connection-string-url "^2.6.0"
+    socks "^2.7.1"
+  optionalDependencies:
+    saslprep "^1.0.3"
+
+mongodb@^5.2.0:
+  version "5.2.0"
+  resolved "https://registry.npmmirror.com/mongodb/-/mongodb-5.2.0.tgz#58c3688614e793a8e970d797255130db9fd6ddea"
+  integrity sha512-nLgo95eP1acvjBcOdrUV3aqpWwHZCZwhYA2opB8StybbtQL/WoE5pk92qUUfjbKOWcGLYJczTqQbfOQhYtrkKg==
+  dependencies:
+    bson "^5.2.0"
+    mongodb-connection-string-url "^2.6.0"
+    socks "^2.7.1"
+  optionalDependencies:
+    saslprep "^1.0.3"
+
+mongoose@^7.0.4:
+  version "7.0.4"
+  resolved "https://registry.npmmirror.com/mongoose/-/mongoose-7.0.4.tgz#7f6c31e12d86eed516ab5d1f5e6f8196d3682ed2"
+  integrity sha512-MEmQOOqQUvW1PJcji64NtA2EFGHrEvk9o4g//isVYSJW2+8Y8u49C2qFBKzn1t6/l9onQn012o/PcFqR6ixQpQ==
+  dependencies:
+    bson "^5.0.1"
+    kareem "2.5.1"
+    mongodb "5.1.0"
+    mpath "0.9.0"
+    mquery "5.0.0"
+    ms "2.1.3"
+    sift "16.0.1"
+
+mpath@0.9.0:
+  version "0.9.0"
+  resolved "https://registry.npmmirror.com/mpath/-/mpath-0.9.0.tgz#0c122fe107846e31fc58c75b09c35514b3871904"
+  integrity sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==
+
+mquery@5.0.0:
+  version "5.0.0"
+  resolved "https://registry.npmmirror.com/mquery/-/mquery-5.0.0.tgz#a95be5dfc610b23862df34a47d3e5d60e110695d"
+  integrity sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==
+  dependencies:
+    debug "4.x"
+
 ms@*, ms@2.1.3, ms@^2.0.0, ms@^2.1.1:
   version "2.1.3"
   resolved "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
@@ -4564,6 +4902,11 @@ npmlog@^5.0.1:
     gauge "^3.0.0"
     set-blocking "^2.0.0"
 
+oauth-sign@~0.9.0:
+  version "0.9.0"
+  resolved "https://registry.npmmirror.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
+  integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
+
 object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1:
   version "4.1.1"
   resolved "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@@ -4847,6 +5190,11 @@ pause@0.0.1:
   resolved "https://registry.npmmirror.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d"
   integrity sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==
 
+performance-now@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.npmmirror.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
+  integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==
+
 picocolors@^1.0.0:
   version "1.0.0"
   resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
@@ -4955,6 +5303,11 @@ proxy-from-env@^1.0.0, proxy-from-env@^1.1.0:
   resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
   integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
 
+psl@^1.1.28:
+  version "1.9.0"
+  resolved "https://registry.npmmirror.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
+  integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
+
 pump@^3.0.0:
   version "3.0.0"
   resolved "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
@@ -4963,7 +5316,7 @@ pump@^3.0.0:
     end-of-stream "^1.1.0"
     once "^1.3.1"
 
-punycode@^2.1.0:
+punycode@^2.1.0, punycode@^2.1.1:
   version "2.3.0"
   resolved "https://registry.npmmirror.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
   integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
@@ -4987,6 +5340,11 @@ qs@^6.11.0, qs@^6.4.0:
   dependencies:
     side-channel "^1.0.4"
 
+qs@~6.5.2:
+  version "6.5.3"
+  resolved "https://registry.npmmirror.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
+  integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
+
 queue-microtask@^1.2.2:
   version "1.2.3"
   resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@@ -5070,7 +5428,7 @@ readable-stream@^2.2.2, readable-stream@^2.3.6:
     string_decoder "~1.1.1"
     util-deprecate "~1.0.1"
 
-readable-stream@^3.4.0, readable-stream@^3.6.0:
+readable-stream@^3.0.2, readable-stream@^3.4.0, 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==
@@ -5098,6 +5456,32 @@ reflect-metadata@^0.1.13:
   resolved "https://registry.npmmirror.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
   integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
 
+request@^2.88.0:
+  version "2.88.2"
+  resolved "https://registry.npmmirror.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
+  integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
+  dependencies:
+    aws-sign2 "~0.7.0"
+    aws4 "^1.8.0"
+    caseless "~0.12.0"
+    combined-stream "~1.0.6"
+    extend "~3.0.2"
+    forever-agent "~0.6.1"
+    form-data "~2.3.2"
+    har-validator "~5.1.3"
+    http-signature "~1.2.0"
+    is-typedarray "~1.0.0"
+    isstream "~0.1.2"
+    json-stringify-safe "~5.0.1"
+    mime-types "~2.1.19"
+    oauth-sign "~0.9.0"
+    performance-now "^2.1.0"
+    qs "~6.5.2"
+    safe-buffer "^5.1.2"
+    tough-cookie "~2.5.0"
+    tunnel-agent "^0.6.0"
+    uuid "^3.3.2"
+
 require-directory@^2.1.1:
   version "2.1.1"
   resolved "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
@@ -5211,16 +5595,23 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
   resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
   integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
 
-safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0:
+safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
   version "5.2.1"
   resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
   integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
 
-"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0":
+"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
   version "2.1.2"
   resolved "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
   integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
 
+saslprep@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.npmmirror.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226"
+  integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==
+  dependencies:
+    sparse-bitfield "^3.0.3"
+
 sax@>=0.6.0:
   version "1.2.4"
   resolved "https://registry.npmmirror.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
@@ -5348,6 +5739,11 @@ side-channel@^1.0.4:
     get-intrinsic "^1.0.2"
     object-inspect "^1.9.0"
 
+sift@16.0.1:
+  version "16.0.1"
+  resolved "https://registry.npmmirror.com/sift/-/sift-16.0.1.tgz#e9c2ccc72191585008cf3e36fc447b2d2633a053"
+  integrity sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==
+
 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.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
@@ -5382,7 +5778,7 @@ socks-proxy-agent@5, socks-proxy-agent@^5.0.0:
     debug "4"
     socks "^2.3.3"
 
-socks@^2.3.3:
+socks@^2.3.3, socks@^2.7.1:
   version "2.7.1"
   resolved "https://registry.npmmirror.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55"
   integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==
@@ -5416,6 +5812,13 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
   resolved "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
   integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
 
+sparse-bitfield@^3.0.3:
+  version "3.0.3"
+  resolved "https://registry.npmmirror.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11"
+  integrity sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==
+  dependencies:
+    memory-pager "^1.0.2"
+
 sprintf-js@~1.0.2:
   version "1.0.3"
   resolved "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
@@ -5426,6 +5829,21 @@ sqlstring@^2.3.2:
   resolved "https://registry.npmmirror.com/sqlstring/-/sqlstring-2.3.3.tgz#2ddc21f03bce2c387ed60680e739922c65751d0c"
   integrity sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==
 
+sshpk@^1.7.0:
+  version "1.17.0"
+  resolved "https://registry.npmmirror.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5"
+  integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==
+  dependencies:
+    asn1 "~0.2.3"
+    assert-plus "^1.0.0"
+    bcrypt-pbkdf "^1.0.0"
+    dashdash "^1.12.0"
+    ecc-jsbn "~0.1.1"
+    getpass "^0.1.1"
+    jsbn "~0.1.0"
+    safer-buffer "^2.0.2"
+    tweetnacl "~0.14.0"
+
 stack-utils@^2.0.3:
   version "2.0.6"
   resolved "https://registry.npmmirror.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f"
@@ -5675,6 +6093,22 @@ tmpl@1.0.5:
   resolved "https://registry.npmmirror.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
   integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==
 
+tnwx@^2.5.6:
+  version "2.5.6"
+  resolved "https://registry.npmmirror.com/tnwx/-/tnwx-2.5.6.tgz#c9cd53f312ccc95ce52ca5a435a07de4988558dc"
+  integrity sha512-IlDjnYhNkjZGuCmDkDN+QYIzwq8AL33POUQ0LOozZVHJUThuADuSCQcjWLssMTeBEvFMly0UONAYYhDtwJUMvw==
+  dependencies:
+    "@tnwx/accesstoken" "^2.5.6"
+    "@tnwx/cache" "^2.5.6"
+    "@tnwx/commons" "^2.5.6"
+    "@tnwx/kits" "^2.5.6"
+    "@tnwx/miniprogram" "^2.5.6"
+    "@tnwx/opencp" "^2.5.6"
+    "@tnwx/openmp" "^2.5.6"
+    "@tnwx/wxcp" "^2.5.6"
+    "@tnwx/wxmp" "^2.5.6"
+    "@tnwx/wxpay" "^2.5.6"
+
 to-arraybuffer@^1.0.0:
   version "1.0.1"
   resolved "https://registry.npmmirror.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
@@ -5702,6 +6136,21 @@ toposort@^2.0.2:
   resolved "https://registry.npmmirror.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330"
   integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==
 
+tough-cookie@~2.5.0:
+  version "2.5.0"
+  resolved "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
+  integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
+  dependencies:
+    psl "^1.1.28"
+    punycode "^2.1.1"
+
+tr46@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9"
+  integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==
+  dependencies:
+    punycode "^2.1.1"
+
 tr46@~0.0.3:
   version "0.0.3"
   resolved "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
@@ -5799,6 +6248,18 @@ tsutils@^3.21.0:
   dependencies:
     tslib "^1.8.1"
 
+tunnel-agent@^0.6.0:
+  version "0.6.0"
+  resolved "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
+  integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==
+  dependencies:
+    safe-buffer "^5.0.1"
+
+tweetnacl@^0.14.3, tweetnacl@~0.14.0:
+  version "0.14.5"
+  resolved "https://registry.npmmirror.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+  integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==
+
 type-check@^0.4.0, type-check@~0.4.0:
   version "0.4.0"
   resolved "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
@@ -5920,6 +6381,13 @@ uri-js@^4.2.2:
   dependencies:
     punycode "^2.1.0"
 
+urlencode@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.npmmirror.com/urlencode/-/urlencode-1.1.0.tgz#1f2ba26f013c85f0133f7a3ad6ff2730adf7cbb7"
+  integrity sha512-OOAOh9owHXr/rCN1tteSnYwIvsrGHamSz0hafMhmQa7RcS4+Ets6/2iVClVGjt9jkDW84UqoMw/Gmpc7QolX6A==
+  dependencies:
+    iconv-lite "~0.4.11"
+
 urllib@^2.33.1:
   version "2.40.0"
   resolved "https://registry.npmmirror.com/urllib/-/urllib-2.40.0.tgz#c63d4425081908560d7e1c4dc651f7d723a3cf76"
@@ -5972,6 +6440,11 @@ uuid@9.0.0, uuid@^9.0.0:
   resolved "https://registry.npmmirror.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
   integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
 
+uuid@^3.3.2, uuid@^3.3.3:
+  version "3.4.0"
+  resolved "https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
+  integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
+
 v8-compile-cache-lib@^3.0.1:
   version "3.0.1"
   resolved "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
@@ -5996,6 +6469,15 @@ vary@^1, vary@~1.1.2:
   resolved "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
   integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
 
+verror@1.10.0:
+  version "1.10.0"
+  resolved "https://registry.npmmirror.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
+  integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==
+  dependencies:
+    assert-plus "^1.0.0"
+    core-util-is "1.0.2"
+    extsprintf "^1.2.0"
+
 vm2@^3.9.11:
   version "3.9.16"
   resolved "https://registry.npmmirror.com/vm2/-/vm2-3.9.16.tgz#0fbc2a265f7bf8b837cea6f4a908f88a3f93b8e6"
@@ -6031,6 +6513,11 @@ webidl-conversions@^3.0.0:
   resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
   integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
 
+webidl-conversions@^7.0.0:
+  version "7.0.0"
+  resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
+  integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==
+
 webpack-node-externals@3.0.0:
   version "3.0.0"
   resolved "https://registry.npmmirror.com/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz#1a3407c158d547a9feb4229a9e3385b7b60c9917"
@@ -6076,6 +6563,14 @@ whatwg-fetch@^3.4.1:
   resolved "https://registry.npmmirror.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c"
   integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==
 
+whatwg-url@^11.0.0:
+  version "11.0.0"
+  resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018"
+  integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==
+  dependencies:
+    tr46 "^3.0.0"
+    webidl-conversions "^7.0.0"
+
 whatwg-url@^5.0.0:
   version "5.0.0"
   resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"

Неке датотеке нису приказане због велике количине промена