update
This commit is contained in:
parent
d4dfdfc5dd
commit
ca73c44dfa
@ -2,6 +2,7 @@ CREATE TABLE "users" (
|
||||
"id" VARCHAR PRIMARY KEY,
|
||||
"phone_number" TEXT NOT NULL UNIQUE,
|
||||
"email" TEXT NOT NULL UNIQUE,
|
||||
"password" TEXT NOT NULL,
|
||||
"fullname" TEXT,
|
||||
"avatar" TEXT,
|
||||
"latitude" TEXT,
|
||||
@ -11,6 +12,7 @@ CREATE TABLE "users" (
|
||||
"fcm_token" TEXT,
|
||||
"is_verified" TEXT,
|
||||
"is_merchant" BOOLEAN,
|
||||
"role_id" INT,
|
||||
|
||||
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
||||
"updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now()
|
||||
|
@ -32,7 +32,9 @@
|
||||
"dependencies": {
|
||||
"@nestjs/common": "^9.0.0",
|
||||
"@nestjs/core": "^9.0.0",
|
||||
"@nestjs/cqrs": "^9.0.3",
|
||||
"@nestjs/event-emitter": "^1.4.1",
|
||||
"@nestjs/microservices": "^9.3.9",
|
||||
"@nestjs/platform-express": "^9.0.0",
|
||||
"@slonik/migrator": "^0.11.3",
|
||||
"cache-manager": "^5.1.6",
|
||||
@ -66,13 +68,16 @@
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"jest": "29.3.1",
|
||||
"prettier": "^2.3.2",
|
||||
"run-script-webpack-plugin": "^0.1.1",
|
||||
"source-map-support": "^0.5.20",
|
||||
"supertest": "^6.1.3",
|
||||
"ts-jest": "29.0.3",
|
||||
"ts-loader": "^9.2.3",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsconfig-paths": "4.1.1",
|
||||
"typescript": "^4.7.4"
|
||||
"typescript": "^4.7.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-node-externals": "^3.0.0"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
|
@ -3,18 +3,37 @@ import { SlonikModule } from 'nestjs-slonik';
|
||||
import { RedisClientOptions } from 'redis';
|
||||
import { postgresConnectionUrl } from './config/database.config';
|
||||
import { redisConfig } from './config/redis.config';
|
||||
import { UserModule } from './user/user.module';
|
||||
import { UserModule } from './modules/user/user.module';
|
||||
import { APP_INTERCEPTOR } from '@nestjs/core';
|
||||
import { ContextInterceptor } from './libs/application/context/ContextInterceptor';
|
||||
import { ExceptionInterceptor } from './libs/application/interceptors/exception.interceptors';
|
||||
import { RequestContextModule } from 'nestjs-request-context';
|
||||
import { CqrsModule } from '@nestjs/cqrs';
|
||||
import { EventEmitterModule } from '@nestjs/event-emitter';
|
||||
|
||||
const interceptors = [
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
useClass: ContextInterceptor
|
||||
},
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
useClass: ExceptionInterceptor
|
||||
}
|
||||
];
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
EventEmitterModule.forRoot(),
|
||||
RequestContextModule,
|
||||
SlonikModule.forRoot({
|
||||
connectionUri: postgresConnectionUrl,
|
||||
}),
|
||||
CqrsModule,
|
||||
CacheModule.register<RedisClientOptions>(redisConfig),
|
||||
UserModule
|
||||
],
|
||||
controllers: [],
|
||||
providers: [],
|
||||
providers: [...interceptors],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
@ -22,7 +22,7 @@ export class ExceptionInterceptor implements NestInterceptor {
|
||||
Array.isArray(err?.response?.message) &&
|
||||
typeof err?.response?.error === 'string' &&
|
||||
err.status === 400;
|
||||
|
||||
|
||||
if(isClassValidatorError) {
|
||||
err = new BadRequestException(
|
||||
new ApiErrorResponse({
|
||||
|
@ -170,7 +170,7 @@ export abstract class SqlRepositoryBase<
|
||||
*/
|
||||
protected generateInsertQuery(
|
||||
models: DbModel[],
|
||||
): SqlSqlToken<QueryResultRow> {
|
||||
): SqlSqlToken<QueryResultRow > {
|
||||
// TODO: generate query from an entire array to insert multiple records at once
|
||||
const entries = Object.entries(models[0]);
|
||||
const values: any = [];
|
||||
@ -186,7 +186,7 @@ export abstract class SqlRepositoryBase<
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const query = sql`INSERT INTO ${sql.identifier([
|
||||
this.tableName,
|
||||
])} (${sql.join(propertyNames, sql`, `)}) VALUES (${sql.join(
|
||||
@ -194,6 +194,7 @@ export abstract class SqlRepositoryBase<
|
||||
sql`, `,
|
||||
)})`;
|
||||
|
||||
|
||||
const parsedQuery = query;
|
||||
return parsedQuery;
|
||||
}
|
||||
|
13
src/main.ts
13
src/main.ts
@ -1,8 +1,21 @@
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
declare const module: any;
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
app.enableShutdownHooks();
|
||||
|
||||
app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true }));
|
||||
|
||||
await app.listen(3000);
|
||||
|
||||
if (module.hot) {
|
||||
module.hot.accept();
|
||||
module.hot.dispose(() => app.close());
|
||||
}
|
||||
}
|
||||
bootstrap();
|
||||
|
18
src/modules/user/commands/create-user.command.ts
Normal file
18
src/modules/user/commands/create-user.command.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { Command, CommandProps } from "@src/libs/ddd/base/command.base";
|
||||
|
||||
export class CreateUserCommand extends Command {
|
||||
readonly email: string;
|
||||
readonly password: string;
|
||||
readonly fullname: string;
|
||||
readonly phone_number: string;
|
||||
readonly role_id: number;
|
||||
|
||||
constructor(props: CommandProps<CreateUserCommand>) {
|
||||
super(props);
|
||||
this.email = props.email;
|
||||
this.password = props.password;
|
||||
this.phone_number = props.phone_number;
|
||||
this.fullname = props.fullname;
|
||||
this.role_id = props.role_id;
|
||||
}
|
||||
}
|
32
src/modules/user/commands/create-user.http.controller.ts
Normal file
32
src/modules/user/commands/create-user.http.controller.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { Post, ConflictException as ConflictHttpException, Body, Controller, InternalServerErrorException } from "@nestjs/common";
|
||||
import { match, Result} from 'oxide.ts';
|
||||
import { routesV1 } from "@src/config/app.routes";
|
||||
import { UserAlreadyExistsError } from "../domain/user.error";
|
||||
import { UserResponseDto } from "../dtos/user.response.dto";
|
||||
import { CreateUserCommand } from "./create-user.command";
|
||||
import { CommandBus } from "@nestjs/cqrs";
|
||||
import { CreateUserRequestDto } from "./create-user.request.dto";
|
||||
|
||||
@Controller(routesV1.version)
|
||||
export class CreateUserHttpController {
|
||||
constructor(private readonly commandBus: CommandBus) {}
|
||||
|
||||
@Post(routesV1.user.root)
|
||||
async create(@Body() body: CreateUserRequestDto): Promise<UserResponseDto> {
|
||||
const command = new CreateUserCommand(body);
|
||||
|
||||
const result: Result<UserResponseDto, UserAlreadyExistsError> =
|
||||
await this.commandBus.execute(command);
|
||||
|
||||
console.log(result);
|
||||
|
||||
return match(result, {
|
||||
Ok: (res: any) => res,
|
||||
Err: (error: Error) => {
|
||||
if(error instanceof UserAlreadyExistsError)
|
||||
throw new ConflictHttpException(error.message);
|
||||
throw error;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
20
src/modules/user/commands/create-user.message.controller.ts
Normal file
20
src/modules/user/commands/create-user.message.controller.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { Controller } from "@nestjs/common";
|
||||
import { CommandBus } from "@nestjs/cqrs";
|
||||
import { MessagePattern } from "@nestjs/microservices";
|
||||
import { UserResponseDto } from "../dtos/user.response.dto";
|
||||
import { CreateUserCommand } from "./create-user.command";
|
||||
import { CreateUserRequestDto } from "./create-user.request.dto";
|
||||
|
||||
@Controller()
|
||||
export class CreateUserMessageController {
|
||||
constructor(private readonly commandBus: CommandBus) {}
|
||||
|
||||
@MessagePattern('user.create')
|
||||
async create(message: CreateUserRequestDto): Promise<string> {
|
||||
const command = new CreateUserCommand(message);
|
||||
|
||||
const id: string = await this.commandBus.execute(command);
|
||||
|
||||
return id;
|
||||
}
|
||||
}
|
21
src/modules/user/commands/create-user.request.dto.ts
Normal file
21
src/modules/user/commands/create-user.request.dto.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { IsEmail, IsNotEmpty, IsNumber, IsString, MaxLength, MinLength, } from "class-validator";
|
||||
|
||||
export class CreateUserRequestDto {
|
||||
@IsEmail()
|
||||
readonly email: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@MaxLength(14)
|
||||
@MinLength(10)
|
||||
readonly phone_number: string
|
||||
|
||||
@IsNotEmpty()
|
||||
readonly fullname: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
readonly password: string;
|
||||
|
||||
@IsNumber()
|
||||
@IsNotEmpty()
|
||||
readonly role_id: number;
|
||||
}
|
46
src/modules/user/commands/create-user.service.ts
Normal file
46
src/modules/user/commands/create-user.service.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { ConflictException, Inject } from "@nestjs/common";
|
||||
import { CommandHandler, ICommandHandler } from "@nestjs/cqrs";
|
||||
import { AggregateID } from "@src/libs/ddd";
|
||||
import { Err, Ok, Result } from "oxide.ts";
|
||||
import { UserRepositoryPort } from "../database/user.repository.port";
|
||||
import { UserEntity } from "../domain/user.entity";
|
||||
import { UserAlreadyExistsError } from "../domain/user.error";
|
||||
import { UserResponseDto } from "../dtos/user.response.dto";
|
||||
import { USER_REPOSITORY } from "../user.di-tokens";
|
||||
import { CreateUserCommand } from "./create-user.command";
|
||||
|
||||
@CommandHandler(CreateUserCommand)
|
||||
export class CreateUserService implements ICommandHandler {
|
||||
constructor(
|
||||
@Inject(USER_REPOSITORY)
|
||||
protected readonly userRepo: UserRepositoryPort
|
||||
) {}
|
||||
|
||||
async execute(
|
||||
command: CreateUserCommand
|
||||
): Promise<Result<UserResponseDto, UserAlreadyExistsError>> {
|
||||
const user = UserEntity.create({
|
||||
email: command.email,
|
||||
password: command.password,
|
||||
fullname: command.fullname,
|
||||
phone_number: command.phone_number,
|
||||
role_id: command.role_id
|
||||
});
|
||||
|
||||
try {
|
||||
await this.userRepo.transaction(async () => this.userRepo.insert(user));
|
||||
|
||||
const userResponse = new UserResponseDto(user);
|
||||
userResponse.email = command.email;
|
||||
userResponse.fullname = command.fullname;
|
||||
userResponse.phone_number = command.phone_number;
|
||||
|
||||
return Ok(userResponse)
|
||||
} catch (error: any) {
|
||||
if(error instanceof ConflictException) {
|
||||
return Err(new UserAlreadyExistsError(error));
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { SqlRepositoryBase } from '@src/libs/db/sql-repository.base';
|
||||
import { InjectPool } from 'nestjs-slonik';
|
||||
import { DatabasePool } from 'slonik';
|
||||
import { DatabasePool, sql } from 'slonik';
|
||||
import { z } from 'zod';
|
||||
import { UserEntity } from '../domain/user.entity';
|
||||
import { UserMapper } from '../user.mapper';
|
||||
@ -12,15 +12,17 @@ export const userSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
email: z.string().email(),
|
||||
phone_number: z.string().min(10).max(15),
|
||||
password: z.string(),
|
||||
fullname: z.string(),
|
||||
avatar: z.string(),
|
||||
latitude: z.string(),
|
||||
longitude: z.string(),
|
||||
auth_token: z.string(),
|
||||
verify_token: z.string(),
|
||||
fcm_token: z.string(),
|
||||
is_verified: z.string(),
|
||||
is_merchant: z.string(),
|
||||
avatar: z.string().optional(),
|
||||
latitude: z.string().optional(),
|
||||
longitude: z.string().optional(),
|
||||
auth_token: z.string().optional(),
|
||||
verify_token: z.string().optional(),
|
||||
fcm_token: z.string().optional(),
|
||||
is_verified: z.string().optional(),
|
||||
is_merchant: z.string().optional(),
|
||||
role_id: z.number(),
|
||||
created_at: z.preprocess((val: any) => new Date(val), z.date()),
|
||||
updated_at: z.preprocess((val: any) => new Date(val), z.date()),
|
||||
});
|
||||
@ -36,10 +38,8 @@ export class UserRepository
|
||||
extends SqlRepositoryBase<UserEntity, UserModel>
|
||||
implements UserRepositoryPort
|
||||
{
|
||||
findOneByEmail(email: string): Promise<UserEntity> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
protected tableName: 'users';
|
||||
protected tableName = 'users';
|
||||
|
||||
protected schema = userSchema;
|
||||
|
||||
constructor(
|
||||
@ -49,10 +49,14 @@ export class UserRepository
|
||||
eventEmitter: EventEmitter2
|
||||
) {
|
||||
super(pool, mapper, eventEmitter, new Logger(UserRepository.name));
|
||||
}
|
||||
}
|
||||
|
||||
async updateAddress(user: UserEntity): Promise<void> {
|
||||
const address = user.getPropsCopy().address;
|
||||
async findOneByEmail(email: string): Promise<UserEntity> {
|
||||
const user = await this.pool.one(
|
||||
sql.type(userSchema)`SELECT * FROM "users" WHERE email = ${email}`
|
||||
)
|
||||
|
||||
return this.mapper.toDomain(user);
|
||||
}
|
||||
|
||||
}
|
@ -5,6 +5,7 @@ export class UserCreatedDomainEvent extends DomainEvent {
|
||||
readonly phone_number: string;
|
||||
readonly password: string;
|
||||
readonly fullname: string;
|
||||
readonly role_id: number;
|
||||
|
||||
constructor(props: DomainEventProps<UserCreatedDomainEvent>) {
|
||||
super(props);
|
||||
@ -12,5 +13,6 @@ export class UserCreatedDomainEvent extends DomainEvent {
|
||||
this.phone_number = props.phone_number;
|
||||
this.password = props.password;
|
||||
this.fullname = props.fullname;
|
||||
this.role_id = props.role_id;
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ export class UserEntity extends AggregateRoot<UserProps> {
|
||||
|
||||
static create(create: CreateUserProps): UserEntity {
|
||||
const id = v4();
|
||||
const props: UserProps = { ...create, role: UserRoles.user };
|
||||
const props: UserProps = { ...create };
|
||||
const user = new UserEntity({ id, props });
|
||||
user.addEvent(
|
||||
new UserCreatedDomainEvent({
|
||||
@ -17,14 +17,15 @@ export class UserEntity extends AggregateRoot<UserProps> {
|
||||
email: props.email,
|
||||
password: props.password,
|
||||
phone_number: props.password,
|
||||
fullname: props.fullname
|
||||
fullname: props.fullname,
|
||||
role_id: props.role_id
|
||||
})
|
||||
);
|
||||
return user;
|
||||
}
|
||||
|
||||
get role(): UserRoles {
|
||||
return this.props.role;
|
||||
return this.props.role_id;
|
||||
}
|
||||
|
||||
delete(): void {
|
||||
@ -36,6 +37,6 @@ export class UserEntity extends AggregateRoot<UserProps> {
|
||||
}
|
||||
|
||||
public validate(): void {
|
||||
throw new Error("Method not implemented.");
|
||||
// throw new Error("Method not implemented.");
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
import { ExceptionBase } from "@src/libs/exceptions";
|
||||
|
||||
export class UserAlreadyExistsError extends ExceptionBase {
|
||||
static readonly message = 'User already exists';
|
||||
|
||||
public readonly code = 'USER.ALREADY_EXISTS';
|
||||
|
||||
constructor(cause?: Error, metadata?: unknown) {
|
||||
super(UserAlreadyExistsError.message, cause, metadata);
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
export interface UserProps {
|
||||
password: string;
|
||||
phone_number: string;
|
||||
role: UserRoles;
|
||||
role_id: UserRoles;
|
||||
email: string;
|
||||
fullname: string;
|
||||
}
|
||||
@ -11,6 +11,7 @@ export interface CreateUserProps {
|
||||
phone_number: string;
|
||||
password: string;
|
||||
fullname: string;
|
||||
role_id: number;
|
||||
}
|
||||
|
||||
export interface UpdateUserProps {
|
||||
@ -20,6 +21,6 @@ export interface UpdateUserProps {
|
||||
}
|
||||
|
||||
export enum UserRoles {
|
||||
admin = 'admin',
|
||||
user = 'user'
|
||||
admin = 1,
|
||||
user = 2
|
||||
}
|
6
src/modules/user/dtos/user.paginated.response.dto.ts
Normal file
6
src/modules/user/dtos/user.paginated.response.dto.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { PaginatedResponseDto } from "@src/libs/api/paginated.response.base";
|
||||
import { UserResponseDto } from "./user.response.dto";
|
||||
|
||||
export class UserPaginatedResponseDto extends PaginatedResponseDto<UserResponseDto> {
|
||||
readonly data: readonly UserResponseDto[];
|
||||
}
|
7
src/modules/user/dtos/user.response.dto.ts
Normal file
7
src/modules/user/dtos/user.response.dto.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { ResponseBase } from "@src/libs/api/response.base";
|
||||
|
||||
export class UserResponseDto extends ResponseBase {
|
||||
email: string;
|
||||
phone_number: string;
|
||||
fullname: string;
|
||||
}
|
@ -0,0 +1 @@
|
||||
export const USER_REPOSITORY = Symbol('USER_REPOSITORY');
|
@ -1,5 +1,50 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { Mapper } from "@src/libs/ddd";
|
||||
import { UserModel, userSchema } from "./database/user.repository";
|
||||
import { UserEntity } from "./domain/user.entity";
|
||||
import { UserResponseDto } from "./dtos/user.response.dto";
|
||||
|
||||
@Injectable()
|
||||
export class UserMapper implements Mapper<
|
||||
export class UserMapper implements Mapper<UserEntity, UserModel, UserResponseDto> {
|
||||
toPersistence(entity: UserEntity): UserModel {
|
||||
const copy = entity.getPropsCopy();
|
||||
|
||||
const record: UserModel = {
|
||||
id: copy.id,
|
||||
email: copy.email,
|
||||
phone_number: copy.phone_number,
|
||||
password: copy.password,
|
||||
role_id: copy.role_id,
|
||||
fullname: copy.fullname,
|
||||
created_at: copy.createdAt,
|
||||
updated_at: copy.updatedAt,
|
||||
}
|
||||
|
||||
return userSchema.parse(record)
|
||||
}
|
||||
|
||||
toDomain(record: UserModel): UserEntity {
|
||||
const entity = new UserEntity({
|
||||
id: record.id,
|
||||
props: {
|
||||
email: record.email,
|
||||
fullname: record.fullname,
|
||||
password: record.password,
|
||||
phone_number: record.phone_number,
|
||||
role_id: record.role_id
|
||||
}
|
||||
});
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
toResponse(entity: UserEntity): UserResponseDto {
|
||||
const props = entity.getPropsCopy();
|
||||
const response = new UserResponseDto(entity);
|
||||
response.email = props.email;
|
||||
response.fullname = props.fullname;
|
||||
response.phone_number = props.phone_number;
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,32 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { Logger, Module, Provider } from '@nestjs/common';
|
||||
import { CqrsModule } from '@nestjs/cqrs';
|
||||
import { CreateUserHttpController } from './commands/create-user.http.controller';
|
||||
import { CreateUserMessageController } from './commands/create-user.message.controller';
|
||||
import { CreateUserService } from './commands/create-user.service';
|
||||
import { UserRepository } from './database/user.repository';
|
||||
import { USER_REPOSITORY } from './user.di-tokens';
|
||||
import { UserMapper } from './user.mapper';
|
||||
|
||||
@Module({})
|
||||
|
||||
const httpControllers = [
|
||||
CreateUserHttpController
|
||||
];
|
||||
|
||||
const messageControllers = [CreateUserMessageController];
|
||||
const commandHandlers: Provider[] = [CreateUserService];
|
||||
const mappers: Provider[] = [UserMapper];
|
||||
const repositories: Provider[] = [
|
||||
{ provide: USER_REPOSITORY, useClass: UserRepository}
|
||||
];
|
||||
|
||||
@Module({
|
||||
imports: [CqrsModule],
|
||||
controllers: [...httpControllers, ...messageControllers],
|
||||
providers: [
|
||||
Logger,
|
||||
...repositories,
|
||||
...mappers,
|
||||
...commandHandlers
|
||||
],
|
||||
})
|
||||
export class UserModule {}
|
||||
|
29
yarn.lock
29
yarn.lock
@ -724,6 +724,13 @@
|
||||
path-to-regexp "3.2.0"
|
||||
tslib "2.5.0"
|
||||
|
||||
"@nestjs/cqrs@^9.0.3":
|
||||
version "9.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@nestjs/cqrs/-/cqrs-9.0.3.tgz#1ccd87feffebf33b2f3b0170f98eda8c6c74796f"
|
||||
integrity sha512-hmbrqf51BVdgmnnxErnLVXfPNTEqr4Hz8DyLa9dKLIW3BuOyI5RDwJ/9sKbJ47UDBhumC5nQlNK9qk27mhqHfw==
|
||||
dependencies:
|
||||
uuid "9.0.0"
|
||||
|
||||
"@nestjs/event-emitter@^1.4.1":
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@nestjs/event-emitter/-/event-emitter-1.4.1.tgz#a96fae678b0257b9cd8f6c82c9f3f82a0690e221"
|
||||
@ -731,6 +738,14 @@
|
||||
dependencies:
|
||||
eventemitter2 "6.4.9"
|
||||
|
||||
"@nestjs/microservices@^9.3.9":
|
||||
version "9.3.9"
|
||||
resolved "https://registry.yarnpkg.com/@nestjs/microservices/-/microservices-9.3.9.tgz#dbcecd5c3903ee6433be303eec0415ff9e60fb81"
|
||||
integrity sha512-G4EsQpOS3l2dWjJID+z/YyDPTx+SEq/5YQ/cC8XV9Hap1S0rEmo+Z1R2OdlUt+ZnkcJp7H0GIHiB0EjaYanmjA==
|
||||
dependencies:
|
||||
iterare "1.2.1"
|
||||
tslib "2.5.0"
|
||||
|
||||
"@nestjs/platform-express@^9.0.0":
|
||||
version "9.3.9"
|
||||
resolved "https://registry.yarnpkg.com/@nestjs/platform-express/-/platform-express-9.3.9.tgz#557ace8589b54d4ee7bad87a1247a521058395d7"
|
||||
@ -4571,6 +4586,11 @@ run-parallel@^1.1.9:
|
||||
dependencies:
|
||||
queue-microtask "^1.2.2"
|
||||
|
||||
run-script-webpack-plugin@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/run-script-webpack-plugin/-/run-script-webpack-plugin-0.1.1.tgz#dad3114be32eb864d2160306e4d9c52a2c1cfd59"
|
||||
integrity sha512-PrxBRLv1K9itDKMlootSCyGhdTU+KbKGJ2wF6/k0eyo6M0YGPC58HYbS/J/QsDiwM0t7G99WcuCqto0J7omOXA==
|
||||
|
||||
rxjs@6.6.7, rxjs@^6.6.0:
|
||||
version "6.6.7"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
|
||||
@ -5245,6 +5265,11 @@ uuid@8.3.2, uuid@^8.3.2:
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||
|
||||
uuid@9.0.0:
|
||||
version "9.0.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
|
||||
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
|
||||
|
||||
v8-compile-cache-lib@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
|
||||
@ -5301,7 +5326,7 @@ webidl-conversions@^4.0.2:
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
|
||||
integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
|
||||
|
||||
webpack-node-externals@3.0.0:
|
||||
webpack-node-externals@3.0.0, webpack-node-externals@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz#1a3407c158d547a9feb4229a9e3385b7b60c9917"
|
||||
integrity sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==
|
||||
@ -5311,7 +5336,7 @@ webpack-sources@^3.2.3:
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
|
||||
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
|
||||
|
||||
webpack@5.75.0:
|
||||
webpack@5.75.0, webpack@^5.75.0:
|
||||
version "5.75.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152"
|
||||
integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==
|
||||
|
Loading…
Reference in New Issue
Block a user