Compare commits
No commits in common. "4216498dfc55683129e1906f37b66cb4acfa67ab" and "bbbfb889ff73c8d136a5458387c44d303709de14" have entirely different histories.
4216498dfc
...
bbbfb889ff
@ -32,10 +32,7 @@
|
|||||||
"@nestjs/platform-express": "^11.0.1",
|
"@nestjs/platform-express": "^11.0.1",
|
||||||
"@prisma/adapter-pg": "^7.3.0",
|
"@prisma/adapter-pg": "^7.3.0",
|
||||||
"@prisma/client": "^7.3.0",
|
"@prisma/client": "^7.3.0",
|
||||||
"@teacinema/common": "^1.0.0",
|
|
||||||
"@teacinema/contracts": "^1.0.0",
|
"@teacinema/contracts": "^1.0.0",
|
||||||
"class-transformer": "^0.5.1",
|
|
||||||
"class-validator": "^0.14.3",
|
|
||||||
"dotenv-expand": "^12.0.3",
|
"dotenv-expand": "^12.0.3",
|
||||||
"ioredis": "^5.9.2",
|
"ioredis": "^5.9.2",
|
||||||
"prisma": "^7.3.0",
|
"prisma": "^7.3.0",
|
||||||
|
|||||||
@ -7,6 +7,6 @@ export default defineConfig({
|
|||||||
path: 'prisma/migrations'
|
path: 'prisma/migrations'
|
||||||
},
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
url: process.env['DATABASE_URI']
|
url: process.env['POSTGRES_URI']
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,18 +1,14 @@
|
|||||||
import { Module } from '@nestjs/common'
|
import { Module } from '@nestjs/common'
|
||||||
import { ConfigModule } from '@nestjs/config'
|
import { ConfigModule } from '@nestjs/config'
|
||||||
|
|
||||||
import { dabataseEnv, grpcEnv, redisEnv } from './config'
|
|
||||||
import { PrismaModule } from './infra/prisma/prisma.module'
|
import { PrismaModule } from './infra/prisma/prisma.module'
|
||||||
import { RedisModule } from './infra/redis/redis.module'
|
import { RedisModule } from './infra/redis/redis.module'
|
||||||
import { AuthModule } from './modules/auth/auth.module'
|
import { AuthModule } from './modules/auth/auth.module'
|
||||||
import { OtpModule } from './modules/otp/otp.module'
|
import { OtpModule } from './modules/otp/otp.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot({
|
ConfigModule.forRoot({ isGlobal: true }),
|
||||||
isGlobal: true,
|
|
||||||
load: [dabataseEnv, grpcEnv, redisEnv]
|
|
||||||
}),
|
|
||||||
PrismaModule,
|
PrismaModule,
|
||||||
RedisModule,
|
RedisModule,
|
||||||
AuthModule,
|
AuthModule,
|
||||||
|
|||||||
19
src/config/env/database.env.ts
vendored
19
src/config/env/database.env.ts
vendored
@ -1,19 +0,0 @@
|
|||||||
import { registerAs } from '@nestjs/config'
|
|
||||||
|
|
||||||
import { validateEnv } from '@/shared/utils'
|
|
||||||
|
|
||||||
import { DatabaseConfig } from '../interfaces/database.interface'
|
|
||||||
import { DatabaseValidator } from '../validators'
|
|
||||||
|
|
||||||
export const dabataseEnv = registerAs<DatabaseConfig>('database', () => {
|
|
||||||
validateEnv(process.env, DatabaseValidator)
|
|
||||||
|
|
||||||
return {
|
|
||||||
username: process.env.DATABASE_USERNAME,
|
|
||||||
password: process.env.DATABASE_PASSWORD,
|
|
||||||
host: process.env.DATABASE_HOST,
|
|
||||||
port: parseInt(process.env.DATABASE_PORT),
|
|
||||||
name: process.env.DATABASE_NAME,
|
|
||||||
uri: process.env.DATABASE_URI
|
|
||||||
}
|
|
||||||
})
|
|
||||||
15
src/config/env/grpc.env.ts
vendored
15
src/config/env/grpc.env.ts
vendored
@ -1,15 +0,0 @@
|
|||||||
import { registerAs } from '@nestjs/config'
|
|
||||||
|
|
||||||
import { validateEnv } from '@/shared/utils'
|
|
||||||
|
|
||||||
import type { GrpcConfig } from '../interfaces/grpc.interface'
|
|
||||||
import { GrpcValidator } from '../validators'
|
|
||||||
|
|
||||||
export const grpcEnv = registerAs<GrpcConfig>('grpc', () => {
|
|
||||||
validateEnv(process.env, GrpcValidator)
|
|
||||||
|
|
||||||
return {
|
|
||||||
host: process.env.GRPC_HOST,
|
|
||||||
port: parseInt(process.env.GRPC_PORT)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
3
src/config/env/index.ts
vendored
3
src/config/env/index.ts
vendored
@ -1,3 +0,0 @@
|
|||||||
export * from './grpc.env'
|
|
||||||
export * from './database.env'
|
|
||||||
export * from './redis.env'
|
|
||||||
16
src/config/env/redis.env.ts
vendored
16
src/config/env/redis.env.ts
vendored
@ -1,16 +0,0 @@
|
|||||||
import { registerAs } from '@nestjs/config'
|
|
||||||
|
|
||||||
import { RedisConfig } from '@/config/interfaces/redis.interface'
|
|
||||||
import { RedisValidator } from '@/config/validators'
|
|
||||||
import { validateEnv } from '@/shared/utils'
|
|
||||||
|
|
||||||
export const redisEnv = registerAs<RedisConfig>('redis', () => {
|
|
||||||
validateEnv(process.env, RedisValidator)
|
|
||||||
|
|
||||||
return {
|
|
||||||
username: process.env.REDIS_USERNAME,
|
|
||||||
password: process.env.REDIS_PASSWORD,
|
|
||||||
host: process.env.REDIS_HOST,
|
|
||||||
port: parseInt(process.env.REDIS_PORT)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
export * from './env'
|
|
||||||
export * from './interfaces'
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { DatabaseConfig } from './database.interface'
|
|
||||||
import { GrpcConfig } from './grpc.interface'
|
|
||||||
import { RedisConfig } from './redis.interface'
|
|
||||||
|
|
||||||
export interface AllConfigs {
|
|
||||||
database: DatabaseConfig
|
|
||||||
grpc: GrpcConfig
|
|
||||||
redis: RedisConfig
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
export interface DatabaseConfig {
|
|
||||||
username: string
|
|
||||||
password: string
|
|
||||||
host: string
|
|
||||||
port: number
|
|
||||||
name: string
|
|
||||||
uri: string
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
export interface GrpcConfig {
|
|
||||||
host: string
|
|
||||||
port: number
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
export * from './all-configs.interface'
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
export interface RedisConfig {
|
|
||||||
username: string
|
|
||||||
password: string
|
|
||||||
host: string
|
|
||||||
port: number
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
import { IsInt, IsString, Max, Min } from 'class-validator'
|
|
||||||
|
|
||||||
export class DatabaseValidator {
|
|
||||||
@IsString()
|
|
||||||
public DATABASE_USERNAME: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
public DATABASE_PASSWORD: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
public DATABASE_HOST: string
|
|
||||||
|
|
||||||
@Min(1)
|
|
||||||
@Max(65535)
|
|
||||||
@IsInt()
|
|
||||||
public DATABASE_PORT: number
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
public DATABASE_NAME: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
public DATABASE_URI: string
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { IsInt, IsString } from 'class-validator'
|
|
||||||
|
|
||||||
export class GrpcValidator {
|
|
||||||
@IsString()
|
|
||||||
public GRPC_HOST: string
|
|
||||||
|
|
||||||
@IsInt()
|
|
||||||
public GRPC_PORT: number
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
export * from './grpc.validator'
|
|
||||||
export * from './database.validator'
|
|
||||||
export * from './redis.validator'
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
import { IsInt, IsString, Max, Min } from 'class-validator'
|
|
||||||
|
|
||||||
export class RedisValidator {
|
|
||||||
@IsString()
|
|
||||||
public REDIS_USERNAME: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
public REDIS_PASSWORD: string
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
public REDIS_HOST: string
|
|
||||||
|
|
||||||
@Min(1)
|
|
||||||
@Max(65535)
|
|
||||||
@IsInt()
|
|
||||||
public REDIS_PORT: number
|
|
||||||
}
|
|
||||||
@ -8,8 +8,6 @@ import { ConfigService } from '@nestjs/config'
|
|||||||
import { PrismaPg } from '@prisma/adapter-pg'
|
import { PrismaPg } from '@prisma/adapter-pg'
|
||||||
import { PrismaClient } from '@prisma/generated/client'
|
import { PrismaClient } from '@prisma/generated/client'
|
||||||
|
|
||||||
import { AllConfigs } from '@/config'
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PrismaService
|
export class PrismaService
|
||||||
extends PrismaClient
|
extends PrismaClient
|
||||||
@ -17,16 +15,14 @@ export class PrismaService
|
|||||||
{
|
{
|
||||||
private readonly logger = new Logger(PrismaService.name)
|
private readonly logger = new Logger(PrismaService.name)
|
||||||
|
|
||||||
public constructor(
|
public constructor(private readonly configService: ConfigService) {
|
||||||
private readonly configService: ConfigService<AllConfigs>
|
|
||||||
) {
|
|
||||||
super({
|
super({
|
||||||
adapter: new PrismaPg({
|
adapter: new PrismaPg({
|
||||||
user: configService.get('database.username', { infer: true }),
|
user: configService.getOrThrow<string>('POSTGRES_USERNAME'),
|
||||||
password: configService.get('database.password', { infer: true }),
|
password: configService.getOrThrow<string>('POSTGRES_PASSWORD'),
|
||||||
host: configService.get('database.host', { infer: true }),
|
host: configService.getOrThrow<string>('POSTGRES_HOST'),
|
||||||
port: configService.get('database.port', { infer: true }),
|
port: configService.getOrThrow<number>('POSTGRES_PORT'),
|
||||||
database: configService.get('database.name', { infer: true })
|
database: configService.getOrThrow<string>('POSTGRES_DATABASE_NAME')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,8 +7,6 @@ import {
|
|||||||
import { ConfigService } from '@nestjs/config'
|
import { ConfigService } from '@nestjs/config'
|
||||||
import Redis from 'ioredis'
|
import Redis from 'ioredis'
|
||||||
|
|
||||||
import { AllConfigs } from '@/config'
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RedisService
|
export class RedisService
|
||||||
extends Redis
|
extends Redis
|
||||||
@ -16,14 +14,12 @@ export class RedisService
|
|||||||
{
|
{
|
||||||
private readonly logger = new Logger(RedisService.name)
|
private readonly logger = new Logger(RedisService.name)
|
||||||
|
|
||||||
public constructor(
|
public constructor(private readonly configService: ConfigService) {
|
||||||
private readonly configService: ConfigService<AllConfigs>
|
|
||||||
) {
|
|
||||||
super({
|
super({
|
||||||
username: configService.get('redis.username', { infer: true }),
|
username: configService.getOrThrow<string>('REDIS_USERNAME'),
|
||||||
host: configService.get('redis.host', { infer: true }),
|
host: configService.getOrThrow<string>('REDIS_HOST'),
|
||||||
port: configService.get('redis.port', { infer: true }),
|
port: configService.getOrThrow<number>('REDIS_PORT'),
|
||||||
password: configService.get('redis.password', { infer: true }),
|
password: configService.getOrThrow<string>('REDIS_PASSWORD'),
|
||||||
maxRetriesPerRequest: 5,
|
maxRetriesPerRequest: 5,
|
||||||
enableOfflineQueue: true
|
enableOfflineQueue: true
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,22 +1,15 @@
|
|||||||
import { ConfigService } from '@nestjs/config'
|
|
||||||
import { NestFactory } from '@nestjs/core'
|
import { NestFactory } from '@nestjs/core'
|
||||||
import { MicroserviceOptions, Transport } from '@nestjs/microservices'
|
import { MicroserviceOptions, Transport } from '@nestjs/microservices'
|
||||||
|
|
||||||
import { AppModule } from './app.module'
|
import { AppModule } from './app.module'
|
||||||
import { AllConfigs } from './config'
|
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule)
|
const app = await NestFactory.create(AppModule)
|
||||||
|
|
||||||
const config = app.get(ConfigService<AllConfigs>)
|
|
||||||
const host = config.get('grpc.host', { infer: true })
|
|
||||||
const port = config.get('grpc.port', { infer: true })
|
|
||||||
const url = `${host}:${port}`
|
|
||||||
|
|
||||||
app.connectMicroservice<MicroserviceOptions>({
|
app.connectMicroservice<MicroserviceOptions>({
|
||||||
transport: Transport.GRPC,
|
transport: Transport.GRPC,
|
||||||
options: {
|
options: {
|
||||||
url,
|
url: 'localhost:50051',
|
||||||
package: 'auth.v1',
|
package: 'auth.v1',
|
||||||
protoPath: 'node_modules/@teacinema/contracts/proto/auth.proto',
|
protoPath: 'node_modules/@teacinema/contracts/proto/auth.proto',
|
||||||
loader: {
|
loader: {
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { Injectable } from '@nestjs/common'
|
import { Injectable } from '@nestjs/common'
|
||||||
import { RpcException } from '@nestjs/microservices'
|
import { RpcException } from '@nestjs/microservices'
|
||||||
import { Account } from '@prisma/generated/client'
|
import { Account } from '@prisma/generated/client'
|
||||||
import { RpcStatus } from '@teacinema/common'
|
|
||||||
import {
|
import {
|
||||||
SendOtpRequest,
|
SendOtpRequest,
|
||||||
SendOtpResponse,
|
SendOtpResponse,
|
||||||
@ -62,10 +61,7 @@ export class AuthService {
|
|||||||
: await this.authRepository.findByEmail(identifier)
|
: await this.authRepository.findByEmail(identifier)
|
||||||
|
|
||||||
if (!account) {
|
if (!account) {
|
||||||
throw new RpcException({
|
throw new RpcException('Account not found')
|
||||||
code: RpcStatus.NOT_FOUND,
|
|
||||||
details: 'Account not found'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPhoneType && !account.isPhoneVerified) {
|
if (isPhoneType && !account.isPhoneVerified) {
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { Injectable } from '@nestjs/common'
|
import { Injectable } from '@nestjs/common'
|
||||||
import { RpcException } from '@nestjs/microservices'
|
import { RpcException } from '@nestjs/microservices'
|
||||||
import { RpcStatus } from '@teacinema/common'
|
|
||||||
import { createHash } from 'node:crypto'
|
import { createHash } from 'node:crypto'
|
||||||
|
|
||||||
import { RedisService } from '@/infra/redis/redis.service'
|
import { RedisService } from '@/infra/redis/redis.service'
|
||||||
@ -32,18 +31,12 @@ export class OtpService {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (!stroredHash) {
|
if (!stroredHash) {
|
||||||
throw new RpcException({
|
throw new RpcException('Invalid or expired code')
|
||||||
code: RpcStatus.NOT_FOUND,
|
|
||||||
details: 'Invalid or expired code'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const hash = createHash('sha256').update(code).digest('hex')
|
const hash = createHash('sha256').update(code).digest('hex')
|
||||||
if (stroredHash !== hash) {
|
if (stroredHash !== hash) {
|
||||||
throw new RpcException({
|
throw new RpcException('Invalid or expired code')
|
||||||
code: RpcStatus.NOT_FOUND,
|
|
||||||
details: 'Invalid or expired code'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.redisService.del(`otp:${type}:${indentifier}`)
|
await this.redisService.del(`otp:${type}:${indentifier}`)
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
import { ClassConstructor, plainToClass } from 'class-transformer'
|
|
||||||
import { validateSync } from 'class-validator'
|
|
||||||
|
|
||||||
export function validateEnv<T extends object>(
|
|
||||||
config: Record<string, unknown>,
|
|
||||||
envVariableClass: ClassConstructor<T>
|
|
||||||
) {
|
|
||||||
const validatedConfig = plainToClass(envVariableClass, config, {
|
|
||||||
enableImplicitConversion: true
|
|
||||||
})
|
|
||||||
|
|
||||||
const errors = validateSync(validatedConfig, {
|
|
||||||
skipMissingProperties: false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (errors.length > 0) {
|
|
||||||
const errorMessages = errors
|
|
||||||
.map(
|
|
||||||
error =>
|
|
||||||
`\nError in ${error.property}\n:
|
|
||||||
+ ${Object.entries(error.constraints)
|
|
||||||
.map(([key, value]) => `${key}: ${value}`)
|
|
||||||
.join('\n')}`
|
|
||||||
)
|
|
||||||
.join('\n')
|
|
||||||
|
|
||||||
console.error(`\n${errors.toString()}`)
|
|
||||||
throw new Error(errorMessages)
|
|
||||||
}
|
|
||||||
|
|
||||||
return validatedConfig
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
export * from './env'
|
|
||||||
@ -16,7 +16,7 @@
|
|||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strictNullChecks": false,
|
"strictNullChecks": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"strictBindCallApply": false,
|
"strictBindCallApply": false,
|
||||||
|
|||||||
34
yarn.lock
34
yarn.lock
@ -1354,11 +1354,6 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.1.0.tgz#a79b55dbaf8604812f52d140b2c9ab41bc150bb8"
|
resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.1.0.tgz#a79b55dbaf8604812f52d140b2c9ab41bc150bb8"
|
||||||
integrity sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==
|
integrity sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==
|
||||||
|
|
||||||
"@teacinema/common@^1.0.0":
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcommon/-/1.0.0/common-1.0.0.tgz#3b79ae6eb46352ed1544535be094fe0ead244c36"
|
|
||||||
integrity sha512-L006mySvhRpUlRHf3ONbXA0RG42gbQ9QAnmQuZx4zejHEsWB9702xe18MSYcBilv+lmYkQpiX/g3p8P7suLfqQ==
|
|
||||||
|
|
||||||
"@teacinema/contracts@^1.0.0":
|
"@teacinema/contracts@^1.0.0":
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcontracts/-/1.0.1/contracts-1.0.1.tgz#25021fecb1d33d0505fd11ca3d8201660cb1bcbe"
|
resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcontracts/-/1.0.1/contracts-1.0.1.tgz#25021fecb1d33d0505fd11ca3d8201660cb1bcbe"
|
||||||
@ -1632,11 +1627,6 @@
|
|||||||
"@types/methods" "^1.1.4"
|
"@types/methods" "^1.1.4"
|
||||||
"@types/superagent" "^8.1.0"
|
"@types/superagent" "^8.1.0"
|
||||||
|
|
||||||
"@types/validator@^13.15.3":
|
|
||||||
version "13.15.10"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.15.10.tgz#742b77ec34d58554b94a76a14cef30d59e3c16b9"
|
|
||||||
integrity sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==
|
|
||||||
|
|
||||||
"@types/yargs-parser@*":
|
"@types/yargs-parser@*":
|
||||||
version "21.0.3"
|
version "21.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15"
|
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15"
|
||||||
@ -2442,20 +2432,6 @@ cjs-module-lexer@^2.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz#b3ca5101843389259ade7d88c77bd06ce55849ca"
|
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz#b3ca5101843389259ade7d88c77bd06ce55849ca"
|
||||||
integrity sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==
|
integrity sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==
|
||||||
|
|
||||||
class-transformer@^0.5.1:
|
|
||||||
version "0.5.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336"
|
|
||||||
integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==
|
|
||||||
|
|
||||||
class-validator@^0.14.3:
|
|
||||||
version "0.14.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.14.3.tgz#834a4caafa8359aed73d7708badb4cf271be50fe"
|
|
||||||
integrity sha512-rXXekcjofVN1LTOSw+u4u9WXVEUvNBVjORW154q/IdmYWy1nMbOU9aNtZB0t8m+FJQ9q91jlr2f9CwwUFdFMRA==
|
|
||||||
dependencies:
|
|
||||||
"@types/validator" "^13.15.3"
|
|
||||||
libphonenumber-js "^1.11.1"
|
|
||||||
validator "^13.15.20"
|
|
||||||
|
|
||||||
cli-cursor@^3.1.0:
|
cli-cursor@^3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
|
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
|
||||||
@ -4153,11 +4129,6 @@ levn@^0.4.1:
|
|||||||
prelude-ls "^1.2.1"
|
prelude-ls "^1.2.1"
|
||||||
type-check "~0.4.0"
|
type-check "~0.4.0"
|
||||||
|
|
||||||
libphonenumber-js@^1.11.1:
|
|
||||||
version "1.12.35"
|
|
||||||
resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.12.35.tgz#149d4a66b2a7a518998c430c6d33465abaed23c4"
|
|
||||||
integrity sha512-T/Cz6iLcsZdb5jDncDcUNhSAJ0VlSC9TnsqtBNdpkaAmy24/R1RhErtNWVWBrcUZKs9hSgaVsBkc7HxYnazIfw==
|
|
||||||
|
|
||||||
lilconfig@^2.1.0:
|
lilconfig@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52"
|
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52"
|
||||||
@ -5764,11 +5735,6 @@ valibot@1.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/valibot/-/valibot-1.2.0.tgz#8fc720d9e4082ba16e30a914064a39619b2f1d6f"
|
resolved "https://registry.yarnpkg.com/valibot/-/valibot-1.2.0.tgz#8fc720d9e4082ba16e30a914064a39619b2f1d6f"
|
||||||
integrity sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==
|
integrity sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==
|
||||||
|
|
||||||
validator@^13.15.20:
|
|
||||||
version "13.15.26"
|
|
||||||
resolved "https://registry.yarnpkg.com/validator/-/validator-13.15.26.tgz#36c3deeab30e97806a658728a155c66fcaa5b944"
|
|
||||||
integrity sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==
|
|
||||||
|
|
||||||
vary@^1, vary@^1.1.2:
|
vary@^1, vary@^1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user