From 93020b3153b63d5f65bb0bee19d7b21c729fd35e Mon Sep 17 00:00:00 2001 From: Tria Date: Thu, 4 Jun 2026 16:18:14 +0300 Subject: [PATCH 1/4] working on payment --- apps/edr-freight-api/src/app.module.ts | 2 + .../payment/entities/payment.entity.ts | 59 ++++ .../src/modules/payment/payment.controller.ts | 27 ++ .../src/modules/payment/payment.module.ts | 12 + .../src/modules/payment/payment.service.ts | 42 +++ .../payment/strategies/payment.strategy.ts | 9 + .../strategies/payment.telebirr.strategy.ts | 307 ++++++++++++++++++ .../payment/strategies/payments.types.ts | 39 +++ .../strategies/telebirr/telebirr.crypto.ts | 98 ++++++ .../strategies/telebirr/telebirr.types.ts | 69 ++++ 10 files changed, 664 insertions(+) create mode 100644 apps/edr-freight-api/src/modules/payment/entities/payment.entity.ts create mode 100644 apps/edr-freight-api/src/modules/payment/payment.controller.ts create mode 100644 apps/edr-freight-api/src/modules/payment/payment.module.ts create mode 100644 apps/edr-freight-api/src/modules/payment/payment.service.ts create mode 100644 apps/edr-freight-api/src/modules/payment/strategies/payment.strategy.ts create mode 100644 apps/edr-freight-api/src/modules/payment/strategies/payment.telebirr.strategy.ts create mode 100644 apps/edr-freight-api/src/modules/payment/strategies/payments.types.ts create mode 100644 apps/edr-freight-api/src/modules/payment/strategies/telebirr/telebirr.crypto.ts create mode 100644 apps/edr-freight-api/src/modules/payment/strategies/telebirr/telebirr.types.ts diff --git a/apps/edr-freight-api/src/app.module.ts b/apps/edr-freight-api/src/app.module.ts index a4ecf321e..1f9e7a5ce 100644 --- a/apps/edr-freight-api/src/app.module.ts +++ b/apps/edr-freight-api/src/app.module.ts @@ -30,6 +30,7 @@ import { } from "./seed/edr-freight.seed"; import { EdrOrgSeeder } from "./seed/edr-org.seeder"; import { DemoUsersSeeder } from "./seed/demo-users.seeder"; +import { PaymentModule } from "./modules/payment/payment.module"; @Module({ imports: [ @@ -70,6 +71,7 @@ import { DemoUsersSeeder } from "./seed/demo-users.seeder"; RuleEngineModule, BackofficeModule, DemoPermissionsModule, + PaymentModule ], providers: [EdrOrgSeeder, DemoUsersSeeder], }) diff --git a/apps/edr-freight-api/src/modules/payment/entities/payment.entity.ts b/apps/edr-freight-api/src/modules/payment/entities/payment.entity.ts new file mode 100644 index 000000000..4858aa979 --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/entities/payment.entity.ts @@ -0,0 +1,59 @@ +import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn } from "typeorm"; + + +type PaymentType = "booking" +type PaymentMethod = "telebirr" | "cbe-birr" | "ebirr" +type Currency = "etb" | "usd" +type PaymentStatus = "action-required" | "processing" | "success" | "failed" | "canceled" | "refunded" + +@Entity({ schema: 'freight', name: 'payments' }) +export class PaymentEntity extends BaseEntity { + @PrimaryGeneratedColumn("uuid") + id!: string + + @Column({ type: 'varchar', length: 255, name: "ref_id" }) + refId!: string + + @Column({ type: 'varchar', length: 255, name: "table_id" }) + tableId!: string + + @Column({ type: "enum", enum: ["booking"] }) + type!: PaymentType; + + @Column({ type: "enum", enum: ["telebirr", "cbe-birr", "ebirr"] }) + method!: PaymentMethod + + @Column({ type: "enum", enum: ["etb", "usd"] }) + currency!: Currency + + @Column({ type: "numeric" }) + amount!: number + + @Column({ type: "json", name: "client_action" }) + clientAction?: string; + + @Column({ type: "varchar", length: 255, unique: true, name: "merchant_order_id", }) + merchantOrderId?: string + + @Column({ type: "varchar", length: 255, unique: true, name: "transaction_id", }) + transactionId?: string + + @Column({ type: "enum", enum: ["action-required", "processing", "success", "failed", "canceled", "refunded"], default: "action-required" }) + status!: PaymentStatus + + @Column({ type: "date", nullable: true, name: "paid_at" }) + paidAt?: Date + + @Column({ type: "date", nullable: true, name: "refunded_at" }) + refundedAt?: Date + + @Column({ type: "varchar", length: 30, nullable: true, name: "failer_code" }) + failerCode?: string + + @Column({ type: "varchar", length: 255, nullable: true, name: "failer_message" }) + failureMessage?: string + + @CreateDateColumn({ name: "created_at" }) + createdAt!: Date + +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/payment.controller.ts b/apps/edr-freight-api/src/modules/payment/payment.controller.ts new file mode 100644 index 000000000..7cd453f4c --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/payment.controller.ts @@ -0,0 +1,27 @@ +import { Controller, Post } from "@nestjs/common"; +import { PaymentService } from "./payment.service"; +import { randomUUID } from "crypto"; + +@Controller("payments") +export class PaymentController { + constructor(private readonly paymentService: PaymentService) { } + + @Post("/initiate") + async initiatePayment() { + const tableId = randomUUID() + const resp = await this.paymentService.create({ + amount: 20, + currency: "etb", + method: "telebirr", + type: "booking", + tableId: tableId + }) + return resp + } + + @Post("web-hooks/telebirr") + paymentWebhook() { + + } + +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/payment.module.ts b/apps/edr-freight-api/src/modules/payment/payment.module.ts new file mode 100644 index 000000000..120effaf7 --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/payment.module.ts @@ -0,0 +1,12 @@ +import { Module } from "@nestjs/common"; +import { PaymentTelebirrStrategy } from "./strategies/payment.telebirr.strategy"; +import { PaymentService } from "./payment.service"; +import { HttpModule } from "@nestjs/axios"; +import { PaymentController } from "./payment.controller"; + +@Module({ + imports: [HttpModule,], + providers: [PaymentTelebirrStrategy, PaymentService], + controllers: [PaymentController] +}) +export class PaymentModule { } \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/payment.service.ts b/apps/edr-freight-api/src/modules/payment/payment.service.ts new file mode 100644 index 000000000..1dab7ffd7 --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/payment.service.ts @@ -0,0 +1,42 @@ +import { Injectable, NotFoundException } from "@nestjs/common"; +import { DataSource, Repository } from "typeorm"; +import { PaymentEntity } from "./entities/payment.entity"; +import { PaymentStrategy } from "./strategies/payment.strategy"; +import { PaymentTelebirrStrategy } from "./strategies/payment.telebirr.strategy"; + +type PaymentMethod = PaymentEntity["method"] +@Injectable() +export class PaymentService { + private strategies: Map; + private readonly paymentRepo: Repository; + + constructor( + private readonly dataSource: DataSource, + private readonly telebirrPaymentStategy: PaymentTelebirrStrategy) { + this.strategies = new Map([ + ["telebirr", this.telebirrPaymentStategy as PaymentStrategy] + ]) + this.paymentRepo = this.dataSource.getRepository(PaymentEntity) + } + + async create(data: Pick): Promise { + const strategy = this.strategies.get(data.method) + if (!strategy) throw new NotFoundException("strategy not found") + return strategy.pay(data.amount, data.currency, "") + // const payment = this.paymentRepo.create({ + // amount: data.amount, + // method: data.method, + // type: data.type, + // currency: data.currency, + // tableId: data.tableId, + // }) + // await this.paymentRepo.save(payment) + // return link; + } + + getPaymentByReferenceIdAndMethod(data: Pick): Promise { + return this.paymentRepo.findOneBy(data) + } + + +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/strategies/payment.strategy.ts b/apps/edr-freight-api/src/modules/payment/strategies/payment.strategy.ts new file mode 100644 index 000000000..a74fe9782 --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/strategies/payment.strategy.ts @@ -0,0 +1,9 @@ +import { Injectable } from "@nestjs/common"; +import { PaymentEntity } from "../entities/payment.entity"; + +type PaymentCurrency = PaymentEntity["currency"] + +@Injectable() +export abstract class PaymentStrategy { + abstract pay(amount: number, currency: PaymentCurrency, refId: string): Promise +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/strategies/payment.telebirr.strategy.ts b/apps/edr-freight-api/src/modules/payment/strategies/payment.telebirr.strategy.ts new file mode 100644 index 000000000..521b6ee9b --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/strategies/payment.telebirr.strategy.ts @@ -0,0 +1,307 @@ +import { Injectable, Logger } from "@nestjs/common"; +import { PaymentStrategy } from "./payment.strategy"; +import { ConfigService } from '@nestjs/config'; +import { HttpService } from '@nestjs/axios'; +import { AxiosError, AxiosRequestConfig } from 'axios'; +import { firstValueFrom } from 'rxjs'; +import * as https from 'node:https'; +import { PaymentEntity } from "../entities/payment.entity"; +import { ProviderInitiationInput, ProviderInitiationResult, ProviderStatus } from "./payments.types"; +import { CreateOrderRequest, CreateOrderResponse, FabricTokenResponse, QueryOrderResponse } from "./telebirr/telebirr.types"; +import { createNonceStr, createTimestamp, signRequestObject, verifyRequestObject } from "./telebirr/telebirr.crypto"; +import { randomUUID } from "node:crypto"; + + + +// type PaymentCurrency = PaymentEntity["currency"] +type PaymentIntentStatus = PaymentEntity["status"] +const TELEBIRR_HTTP_TIMEOUT_MS = 10_000; + +@Injectable() +export class PaymentTelebirrStrategy implements PaymentStrategy { + async pay(amount: number): Promise { + const refId = randomUUID() + const resp = await this.initiate({ + amountMinor: amount, + bookingRef: refId, + currency: "etb", + merchantOrderId: "", + platform: "web" + }) + return resp; + } + + // readonly method = PaymentMethodType.TELEBIRR; + private readonly logger = new Logger(PaymentTelebirrStrategy.name); + private readonly httpsAgent: https.Agent; + + constructor( + private readonly config: ConfigService, + private readonly http: HttpService, + ) { + const insecure = this.config.get('telebirr.insecureTls'); + if (insecure) { + this.logger.warn('TELEBIRR_INSECURE_TLS=true — TLS verification disabled for Telebirr calls. DEV ONLY.'); + } + this.httpsAgent = new https.Agent({ + rejectUnauthorized: !insecure, + secureProtocol: 'TLSv1_2_method', + }); + } + + async initiate(input: ProviderInitiationInput): Promise { + const fabricToken = await this.applyFabricToken(); + const requestBody = this.buildCreateOrderRequest(input); + const response = await this.requestCreateOrder(fabricToken, requestBody); + + const prepayId = response.biz_content?.prepay_id; + if (!prepayId) { + throw new Error( + `Telebirr createOrder returned no prepay_id: ${JSON.stringify(response)}`, + ); + } + + const expiresAt = this.computeExpiresAt(requestBody.biz_content.timeout_express); + const platform = input.platform ?? 'web'; + const clientAction = + platform === 'mobile' + ? { + type: 'LAUNCH_APP' as const, + prepayId, + receiveCode: response.biz_content?.receiveCode, + shortCode: this.merchantCode, + } + : { type: 'REDIRECT' as const, url: this.buildCheckoutUrl(prepayId) }; + + return { + providerOrderId: prepayId, + clientAction, + expiresAt, + rawInitiation: { + request: this.sanitize(requestBody), + response, + }, + }; + } + + async queryStatus(merchantOrderId: string): Promise { + const fabricToken = await this.applyFabricToken(); + const requestBody = this.buildQueryOrderRequest(merchantOrderId); + const response = await this.postJson( + `${this.baseUrl}/payment/v1/merchant/queryOrder`, + requestBody, + { + 'Content-Type': 'application/json', + 'X-APP-Key': this.fabricAppId, + Authorization: fabricToken, + }, + ); + + const tradeStatus = response.biz_content?.trade_status; + const providerTxnId = + response.biz_content?.trans_id ?? response.biz_content?.payment_order_id; + const mapped = this.mapTradeStatus(tradeStatus); + + return { + status: mapped, + providerTxnId, + failureCode: + mapped === "failed" && tradeStatus ? tradeStatus : undefined, + rawResponse: response as Record, + }; + } + + mapTradeStatus(tradeStatus: string | undefined): PaymentIntentStatus { + switch (tradeStatus) { + case 'PAY_SUCCESS': + return "success"; + case 'PAY_FAILED': + case 'ORDER_CLOSED': + return "failed"; + case 'WAIT_PAY': + return "action-required"; + case 'PAYING': + return "processing"; + default: + return "processing"; + } + } + + mapWebhookTradeStatus(tradeStatus: string | undefined): PaymentIntentStatus { + switch (tradeStatus) { + case 'Completed': + return "success"; + case 'Failure': + case 'Expired': + return "failed"; + case 'Paying': + case 'Pending': + return "processing"; + default: + return "processing"; + } + } + + verifyWebhookSignature(payload: Record): boolean { + if (!this.publicKey) { + this.logger.error('TELEBIRR_PUBLIC_KEY not configured; rejecting all webhooks'); + return false; + } + return verifyRequestObject(payload, this.publicKey); + } + + private async applyFabricToken(): Promise { + const response = await this.postJson( + `${this.baseUrl}/payment/v1/token`, + { appSecret: this.appSecret }, + { + 'Content-Type': 'application/json', + 'X-APP-Key': this.fabricAppId, + }, + ); + if (!response?.token) { + throw new Error(`Telebirr token request failed: ${JSON.stringify(response)}`); + } + return response.token; + } + + private async requestCreateOrder( + fabricToken: string, + body: CreateOrderRequest, + ): Promise { + return this.postJson( + `${this.baseUrl}/payment/v1/inapp/createOrder`, + body, + { + 'Content-Type': 'application/json', + 'X-APP-Key': this.fabricAppId, + Authorization: fabricToken, + }, + ); + } + + private buildCreateOrderRequest(input: ProviderInitiationInput): CreateOrderRequest { + const totalAmount = String(input.amountMinor / 100); + const req = { + timestamp: createTimestamp(), + nonce_str: createNonceStr(), + method: 'payment.preorder' as const, + version: '1.0' as const, + biz_content: { + notify_url: this.notifyUrl, + appid: this.merchantAppId, + merch_code: this.merchantCode, + merch_order_id: input.merchantOrderId, + trade_type: 'Checkout' as const, + title: `EDR Booking`, + total_amount: totalAmount, + trans_currency: input.currency, + timeout_express: this.timeoutExpress, + }, + }; + const sign = signRequestObject(req as unknown as Record, this.privateKey); + return { ...req, sign, sign_type: 'SHA256WithRSA' }; + } + + private buildQueryOrderRequest(merchantOrderId: string): Record { + const req = { + timestamp: createTimestamp(), + nonce_str: createNonceStr(), + method: 'payment.queryorder', + version: '1.0', + biz_content: { + appid: this.merchantAppId, + merch_code: this.merchantCode, + merch_order_id: merchantOrderId, + }, + }; + const sign = signRequestObject(req as Record, this.privateKey); + return { ...req, sign, sign_type: 'SHA256WithRSA' }; + } + + private buildCheckoutUrl(prepayId: string): string { + const map: Record = { + appid: this.merchantAppId, + merch_code: this.merchantCode, + nonce_str: createNonceStr(), + prepay_id: prepayId, + timestamp: createTimestamp(), + }; + const sign = signRequestObject(map, this.privateKey); + const rawRequest = [ + `appid=${map.appid}`, + `merch_code=${map.merch_code}`, + `nonce_str=${map.nonce_str}`, + `prepay_id=${map.prepay_id}`, + `timestamp=${map.timestamp}`, + 'sign_type=SHA256WithRSA', + `sign=${sign}`, + 'version=1.0', + 'trade_type=Checkout', + ].join('&'); + return `${this.webBaseUrl}${rawRequest}`; + } + + private computeExpiresAt(timeoutExpress: string): Date { + const match = /^(\d+)([smhd])$/.exec(timeoutExpress); + const minutes = match ? this.toMinutes(parseInt(match[1], 10), match[2]) : 15; + return new Date(Date.now() + minutes * 60_000); + } + + private toMinutes(n: number, unit: string): number { + switch (unit) { + case 's': return Math.max(1, Math.round(n / 60)); + case 'm': return n; + case 'h': return n * 60; + case 'd': return n * 60 * 24; + default: return 15; + } + } + + private async postJson( + url: string, + body: unknown, + headers: Record, + ): Promise { + const config: AxiosRequestConfig = { + headers, + timeout: TELEBIRR_HTTP_TIMEOUT_MS, + httpsAgent: this.httpsAgent, + }; + const started = Date.now(); + try { + const res = await firstValueFrom(this.http.post(url, body, config)); + this.logger.debug(`Telebirr POST ${url} status=${res.status} latency=${Date.now() - started}ms`); + return res.data; + } catch (err) { + if (err instanceof AxiosError) { + this.logger.error( + `Telebirr POST ${url} failed: status=${err.response?.status} body=${JSON.stringify(err.response?.data)} code=${err.code} message=${err.message}`, + ); + } else { + this.logger.error(`Telebirr POST ${url} threw: ${err instanceof Error ? err.message : err}`); + } + throw err; + } + } + + private sanitize(body: CreateOrderRequest): Record { + const { sign: _sign, ...rest } = body; + return rest; + } + + private get baseUrl(): string { return this.config.get('telebirr.baseUrl') ?? ''; } + private get webBaseUrl(): string { return this.config.get('telebirr.webBaseUrl') ?? ''; } + private get fabricAppId(): string { return this.config.get('telebirr.fabricAppId') ?? ''; } + private get appSecret(): string { return this.config.get('telebirr.appSecret') ?? ''; } + private get merchantAppId(): string { return this.config.get('telebirr.merchantAppId') ?? ''; } + private get merchantCode(): string { return this.config.get('telebirr.merchantCode') ?? ''; } + private get notifyUrl(): string { return this.config.get('telebirr.notifyUrl') ?? ''; } + private get timeoutExpress(): string { return this.config.get('telebirr.timeoutExpress') ?? '15m'; } + private get privateKey(): string { return this.config.get('telebirr.privateKey') ?? ''; } + private get publicKey(): string { + return this.config.get('telebirr.publicKey') ?? ''; + } + + +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/strategies/payments.types.ts b/apps/edr-freight-api/src/modules/payment/strategies/payments.types.ts new file mode 100644 index 000000000..bf803c3e2 --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/strategies/payments.types.ts @@ -0,0 +1,39 @@ +import { PaymentEntity } from "../entities/payment.entity"; + +type PaymentIntentStatus = PaymentEntity["status"] +type PaymentMethodType = PaymentEntity["method"] + +export type PaymentPlatform = 'web' | 'mobile'; + +export type ClientAction = + | { type: 'REDIRECT'; url: string } + | { type: 'LAUNCH_APP'; prepayId: string; receiveCode?: string; shortCode: string }; + +export interface ProviderInitiationInput { + merchantOrderId: string; + bookingRef: string; + amountMinor: number; + currency: string; + platform?: PaymentPlatform; +} + +export interface ProviderInitiationResult { + providerOrderId: string; + clientAction: ClientAction; + expiresAt: Date; + rawInitiation: Record; +} + +export interface ProviderStatus { + status: PaymentIntentStatus; + providerTxnId?: string; + failureCode?: string; + failureMessage?: string; + rawResponse: Record; +} + +export interface PaymentProvider { + readonly method: PaymentMethodType; + initiate(input: ProviderInitiationInput): Promise; + queryStatus(merchantOrderId: string): Promise; +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/strategies/telebirr/telebirr.crypto.ts b/apps/edr-freight-api/src/modules/payment/strategies/telebirr/telebirr.crypto.ts new file mode 100644 index 000000000..20319818d --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/strategies/telebirr/telebirr.crypto.ts @@ -0,0 +1,98 @@ +import * as crypto from 'crypto'; + +const EXCLUDE_FIELDS = new Set([ + 'sign', + 'sign_type', + 'header', + 'refund_info', + 'openType', + 'raw_request', + 'biz_content', +]); + +const NONCE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + +export function buildCanonicalString(requestObject: Record): string { + const fieldMap: Record = {}; + + for (const key of Object.keys(requestObject)) { + if (EXCLUDE_FIELDS.has(key)) continue; + fieldMap[key] = requestObject[key]; + } + + const biz = requestObject['biz_content']; + if (biz && typeof biz === 'object') { + for (const key of Object.keys(biz as Record)) { + if (EXCLUDE_FIELDS.has(key)) continue; + fieldMap[key] = (biz as Record)[key]; + } + } + + return Object.keys(fieldMap) + .sort() + .map((k) => `${k}=${fieldMap[k]}`) + .join('&'); +} + +export function signRequestObject( + requestObject: Record, + privateKey: string, +): string { + return signString(buildCanonicalString(requestObject), privateKey); +} + +export function verifyRequestObject( + requestObject: Record, + publicKey: string, +): boolean { + const signature = requestObject['sign']; + if (typeof signature !== 'string' || signature.length === 0) return false; + return verifySignature(buildCanonicalString(requestObject), signature, publicKey); +} + +export function signString(text: string, privateKey: string): string { + const signature = crypto.sign('sha256', Buffer.from(text), { + key: privateKey, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST, + }); + return signature.toString('base64'); +} + +export function verifySignature( + text: string, + signatureBase64: string, + publicKey: string, +): boolean { + try { + return crypto.verify( + 'sha256', + Buffer.from(text), + { + key: publicKey, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST, + }, + Buffer.from(signatureBase64, 'base64'), + ); + } catch { + return false; + } +} + +export function createTimestamp(): string { + return Math.round(Date.now() / 1000).toString(); +} + +export function createNonceStr(length = 32): string { + const bytes = crypto.randomBytes(length); + let out = ''; + for (let i = 0; i < length; i++) { + out += NONCE_CHARS[bytes[i] % NONCE_CHARS.length]; + } + return out; +} + +export function createMerchantOrderId(): string { + return `${Date.now()}${crypto.randomBytes(4).toString('hex')}`; +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/strategies/telebirr/telebirr.types.ts b/apps/edr-freight-api/src/modules/payment/strategies/telebirr/telebirr.types.ts new file mode 100644 index 000000000..6cc29e9f4 --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/strategies/telebirr/telebirr.types.ts @@ -0,0 +1,69 @@ +export interface FabricTokenResponse { + token: string; + expires_in?: number | string; +} + +export interface CreateOrderBizContent { + notify_url: string; + appid: string; + merch_code: string; + merch_order_id: string; + trade_type: 'Checkout' | 'InApp' | 'MiniApp'; + title: string; + total_amount: string; + trans_currency: string; + timeout_express: string; +} + +export interface CreateOrderRequest { + timestamp: string; + nonce_str: string; + method: 'payment.preorder'; + version: '1.0'; + biz_content: CreateOrderBizContent; + sign: string; + sign_type: 'SHA256WithRSA'; +} + +export interface CreateOrderResponse { + code?: string; + msg?: string; + biz_content?: { + prepay_id?: string; + receiveCode?: string; + [key: string]: unknown; + }; + [key: string]: unknown; +} + +export type TelebirrTradeStatus = + | 'PAY_SUCCESS' + | 'PAY_FAILED' + | 'WAIT_PAY' + | 'ORDER_CLOSED' + | 'PAYING' + | 'ACCEPTED' + | 'REFUNDING' + | 'REFUND_SUCCESS' + | 'REFUND_FAILED'; + +export interface QueryOrderResponse { + result?: 'SUCCESS' | 'FAIL'; + code?: string; + msg?: string; + nonce_str?: string; + sign?: string; + sign_type?: string; + biz_content?: { + merch_order_id?: string; + order_status?: string; + trade_status?: TelebirrTradeStatus | string; + payment_order_id?: string; + trans_id?: string; + trans_time?: string; + trans_currency?: string; + total_amount?: string; + [key: string]: unknown; + }; + [key: string]: unknown; +} \ No newline at end of file From 7c124d9845aff37236566aa846e3a92fa396fa26 Mon Sep 17 00:00:00 2001 From: Tria Date: Fri, 5 Jun 2026 11:01:01 +0300 Subject: [PATCH 2/4] telebirr configured --- .../1780639311366-CreatePaymentTable.ts | 96 +++++++++++++++++++ .../1780639978834-AlterClientActionToJsonb.ts | 28 ++++++ .../1780644945086-UpdatePaymentTimestamp.ts | 33 +++++++ .../payment/entities/payment.entity.ts | 21 ++-- .../src/modules/payment/payment.controller.ts | 50 ++++++++-- .../src/modules/payment/payment.module.ts | 6 +- .../src/modules/payment/payment.repository.ts | 38 ++++++++ .../src/modules/payment/payment.service.ts | 87 +++++++++++++---- .../payment/strategies/payment.strategy.ts | 5 +- .../strategies/payment.telebirr.strategy.ts | 16 ++-- .../payment/strategies/payments.types.ts | 2 +- 11 files changed, 328 insertions(+), 54 deletions(-) create mode 100644 apps/edr-freight-api/src/migrations/1780639311366-CreatePaymentTable.ts create mode 100644 apps/edr-freight-api/src/migrations/1780639978834-AlterClientActionToJsonb.ts create mode 100644 apps/edr-freight-api/src/migrations/1780644945086-UpdatePaymentTimestamp.ts create mode 100644 apps/edr-freight-api/src/modules/payment/payment.repository.ts diff --git a/apps/edr-freight-api/src/migrations/1780639311366-CreatePaymentTable.ts b/apps/edr-freight-api/src/migrations/1780639311366-CreatePaymentTable.ts new file mode 100644 index 000000000..cbb60d5d4 --- /dev/null +++ b/apps/edr-freight-api/src/migrations/1780639311366-CreatePaymentTable.ts @@ -0,0 +1,96 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CreatePaymentTable1780639311366 implements MigrationInterface { + name = "CreatePaymentTable1780639311366"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE TYPE freight.payments_type_enum AS ENUM ('booking'); + `); + + await queryRunner.query(` + CREATE TYPE freight.payments_method_enum AS ENUM ('telebirr', 'cbe-birr', 'ebirr'); + `); + + await queryRunner.query(` + CREATE TYPE freight.payments_currency_enum AS ENUM ('ETB', 'USD'); + `); + + await queryRunner.query(` + CREATE TYPE freight.payments_status_enum AS ENUM ( + 'action-required', + 'processing', + 'success', + 'failed', + 'canceled', + 'refunded' + ); + `); + + await queryRunner.query(` + CREATE TABLE freight.payments ( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + + ref_id varchar(255) NOT NULL, + + type freight.payments_type_enum NOT NULL, + + method freight.payments_method_enum NOT NULL, + + currency freight.payments_currency_enum NOT NULL, + + amount numeric NOT NULL, + + raw_initiation jsonb NOT NULL DEFAULT '{}'::jsonb, + + client_action json, + + merchant_order_id varchar(255) NOT NULL, + + transaction_id varchar(255), + + status freight.payments_status_enum NOT NULL DEFAULT 'action-required', + + paid_at date, + + refunded_at date, + + expires_at date, + + failer_code varchar(30), + + failer_message varchar(255), + + created_at TIMESTAMP NOT NULL DEFAULT now(), + + CONSTRAINT PK_payments PRIMARY KEY (id), + + CONSTRAINT UQ_payments_merchant_order_id UNIQUE (merchant_order_id), + + CONSTRAINT UQ_payments_transaction_id UNIQUE (transaction_id) + ); + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DROP TABLE IF EXISTS freight.payments; + `); + + await queryRunner.query(` + DROP TYPE IF EXISTS freight.payments_status_enum; + `); + + await queryRunner.query(` + DROP TYPE IF EXISTS freight.payments_currency_enum; + `); + + await queryRunner.query(` + DROP TYPE IF EXISTS freight.payments_method_enum; + `); + + await queryRunner.query(` + DROP TYPE IF EXISTS freight.payments_type_enum; + `); + } +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/migrations/1780639978834-AlterClientActionToJsonb.ts b/apps/edr-freight-api/src/migrations/1780639978834-AlterClientActionToJsonb.ts new file mode 100644 index 000000000..723331ab3 --- /dev/null +++ b/apps/edr-freight-api/src/migrations/1780639978834-AlterClientActionToJsonb.ts @@ -0,0 +1,28 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AlterClientActionToJsonb1780639978834 implements MigrationInterface { + name = "AlterClientActionToJsonb1780639978834"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE freight.payments + ALTER COLUMN client_action TYPE jsonb + USING client_action::jsonb; + `); + + await queryRunner.query(` + ALTER TABLE freight.payments + ALTER COLUMN client_action DROP DEFAULT; + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE freight.payments + ALTER COLUMN client_action TYPE json + USING client_action::json; + `); + } + + +} diff --git a/apps/edr-freight-api/src/migrations/1780644945086-UpdatePaymentTimestamp.ts b/apps/edr-freight-api/src/migrations/1780644945086-UpdatePaymentTimestamp.ts new file mode 100644 index 000000000..6cfc7fc8f --- /dev/null +++ b/apps/edr-freight-api/src/migrations/1780644945086-UpdatePaymentTimestamp.ts @@ -0,0 +1,33 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdatePaymentTimestamp1780644945086 implements MigrationInterface { + name = "UpdatePaymentTimestamp1780644945086"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE freight.payments + ALTER COLUMN refunded_at TYPE timestamp + USING refunded_at::timestamp; + `); + + await queryRunner.query(` + ALTER TABLE freight.payments + ALTER COLUMN expires_at TYPE timestamp + USING expires_at::timestamp; + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE freight.payments + ALTER COLUMN refunded_at TYPE timestamptz + USING refunded_at::timestamptz; + `); + + await queryRunner.query(` + ALTER TABLE freight.payments + ALTER COLUMN expires_at TYPE timestamptz + USING expires_at::timestamptz; + `); + } +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/entities/payment.entity.ts b/apps/edr-freight-api/src/modules/payment/entities/payment.entity.ts index 4858aa979..f4b784a62 100644 --- a/apps/edr-freight-api/src/modules/payment/entities/payment.entity.ts +++ b/apps/edr-freight-api/src/modules/payment/entities/payment.entity.ts @@ -3,7 +3,7 @@ import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn } type PaymentType = "booking" type PaymentMethod = "telebirr" | "cbe-birr" | "ebirr" -type Currency = "etb" | "usd" +type Currency = "ETB" | "USD" type PaymentStatus = "action-required" | "processing" | "success" | "failed" | "canceled" | "refunded" @Entity({ schema: 'freight', name: 'payments' }) @@ -14,26 +14,26 @@ export class PaymentEntity extends BaseEntity { @Column({ type: 'varchar', length: 255, name: "ref_id" }) refId!: string - @Column({ type: 'varchar', length: 255, name: "table_id" }) - tableId!: string - @Column({ type: "enum", enum: ["booking"] }) type!: PaymentType; @Column({ type: "enum", enum: ["telebirr", "cbe-birr", "ebirr"] }) method!: PaymentMethod - @Column({ type: "enum", enum: ["etb", "usd"] }) + @Column({ type: "enum", enum: ["ETB", "USD"] }) currency!: Currency @Column({ type: "numeric" }) amount!: number - @Column({ type: "json", name: "client_action" }) - clientAction?: string; + @Column({ type: "jsonb", default: {}, name: "raw_initiation" }) + rawInitiation?: Record + + @Column({ type: "jsonb", name: "client_action" }) + clientAction?: Record; @Column({ type: "varchar", length: 255, unique: true, name: "merchant_order_id", }) - merchantOrderId?: string + merchantOrderId!: string @Column({ type: "varchar", length: 255, unique: true, name: "transaction_id", }) transactionId?: string @@ -44,9 +44,12 @@ export class PaymentEntity extends BaseEntity { @Column({ type: "date", nullable: true, name: "paid_at" }) paidAt?: Date - @Column({ type: "date", nullable: true, name: "refunded_at" }) + @Column({ type: "timestamp", nullable: true, name: "refunded_at" }) refundedAt?: Date + @Column({ type: "timestamp", nullable: true, name: "expires_at" }) + expiresAt?: Date + @Column({ type: "varchar", length: 30, nullable: true, name: "failer_code" }) failerCode?: string diff --git a/apps/edr-freight-api/src/modules/payment/payment.controller.ts b/apps/edr-freight-api/src/modules/payment/payment.controller.ts index 7cd453f4c..dda0e4af8 100644 --- a/apps/edr-freight-api/src/modules/payment/payment.controller.ts +++ b/apps/edr-freight-api/src/modules/payment/payment.controller.ts @@ -1,24 +1,54 @@ -import { Controller, Post } from "@nestjs/common"; +import { Controller, Get, NotFoundException, Param, ParseUUIDPipe, Post, Res } from "@nestjs/common"; import { PaymentService } from "./payment.service"; +import { Public } from "@edr/api-common"; import { randomUUID } from "crypto"; - +import { Response } from "express" +@Public() @Controller("payments") export class PaymentController { constructor(private readonly paymentService: PaymentService) { } @Post("/initiate") async initiatePayment() { - const tableId = randomUUID() - const resp = await this.paymentService.create({ - amount: 20, - currency: "etb", - method: "telebirr", - type: "booking", - tableId: tableId + + //Only for testing.. + const data = await this.paymentService.pay(20, "ETB", "telebirr", (_) => { + return new Promise((resp, _) => { + resp({ + id: randomUUID(), + type: "booking" + }) + }); }) - return resp + + return data } + + @Get("/telebirr/:refId") + async pay(@Param("refId", ParseUUIDPipe) refId: string, @Res() res: Response) { + const payment = await this.paymentService.getActivePaymentByRefIdAndMethod(refId, "telebirr") + if (!payment) { + throw new NotFoundException('payment not found') + } + return res.send(` + + + + Redirecting... + + +

Redirecting...

+ + + + + `); + } + + @Post("web-hooks/telebirr") paymentWebhook() { diff --git a/apps/edr-freight-api/src/modules/payment/payment.module.ts b/apps/edr-freight-api/src/modules/payment/payment.module.ts index 120effaf7..b20c331b3 100644 --- a/apps/edr-freight-api/src/modules/payment/payment.module.ts +++ b/apps/edr-freight-api/src/modules/payment/payment.module.ts @@ -3,10 +3,12 @@ import { PaymentTelebirrStrategy } from "./strategies/payment.telebirr.strategy" import { PaymentService } from "./payment.service"; import { HttpModule } from "@nestjs/axios"; import { PaymentController } from "./payment.controller"; +import { ConfigModule } from "@nestjs/config"; +import { PaymentRepository } from "./payment.repository"; @Module({ - imports: [HttpModule,], - providers: [PaymentTelebirrStrategy, PaymentService], + imports: [HttpModule, ConfigModule], + providers: [PaymentRepository, PaymentTelebirrStrategy, PaymentService], controllers: [PaymentController] }) export class PaymentModule { } \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/payment.repository.ts b/apps/edr-freight-api/src/modules/payment/payment.repository.ts new file mode 100644 index 000000000..229ea7b58 --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/payment.repository.ts @@ -0,0 +1,38 @@ +import { Injectable } from "@nestjs/common"; +import { DataSource, FindOptionsWhere, QueryDeepPartialEntity, QueryRunner, Repository } from "typeorm"; +import { PaymentEntity } from "./entities/payment.entity"; + +@Injectable() +export class PaymentRepository { + private readonly paymentRepo: Repository; + constructor(private readonly dataSource: DataSource) { + this.paymentRepo = this.dataSource.getRepository(PaymentEntity) + } + + async createTr(qr: QueryRunner, data: Pick): Promise { + const payment = qr.manager.create(PaymentEntity, data) + return qr.manager.save(payment) + } + + findOneBy(options: FindOptionsWhere | FindOptionsWhere[]): Promise { + return this.paymentRepo.findOneBy(options); + } + + update(where: FindOptionsWhere, data: QueryDeepPartialEntity) { + return this.paymentRepo.update(where, data) + } + + getActivePaymentByRefIdAndMethod(refId: string, method: PaymentEntity["method"]) { + return this.paymentRepo + .createQueryBuilder('payment') + .where('payment.method = :method', { method }) + .andWhere('payment.refId = :refId', { refId }) + .andWhere('payment.status IN (:...statuses)', { + statuses: ['action-required'], + }) + .andWhere('payment.expiresAt > :now', { now: new Date() }) + .getOne(); + } + + +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/payment.service.ts b/apps/edr-freight-api/src/modules/payment/payment.service.ts index 1dab7ffd7..f02d2502c 100644 --- a/apps/edr-freight-api/src/modules/payment/payment.service.ts +++ b/apps/edr-freight-api/src/modules/payment/payment.service.ts @@ -1,41 +1,90 @@ import { Injectable, NotFoundException } from "@nestjs/common"; -import { DataSource, Repository } from "typeorm"; +import { DataSource, QueryRunner } from "typeorm"; import { PaymentEntity } from "./entities/payment.entity"; import { PaymentStrategy } from "./strategies/payment.strategy"; import { PaymentTelebirrStrategy } from "./strategies/payment.telebirr.strategy"; +import { PaymentRepository } from "./payment.repository"; +import { ClientAction, PaymentPlatform } from "./strategies/payments.types"; +import * as crypto from 'crypto'; type PaymentMethod = PaymentEntity["method"] +type CurrencyType = PaymentEntity["currency"] + @Injectable() export class PaymentService { private strategies: Map; - private readonly paymentRepo: Repository; constructor( - private readonly dataSource: DataSource, + private readonly datasource: DataSource, + private readonly paymentRepo: PaymentRepository, private readonly telebirrPaymentStategy: PaymentTelebirrStrategy) { this.strategies = new Map([ ["telebirr", this.telebirrPaymentStategy as PaymentStrategy] ]) - this.paymentRepo = this.dataSource.getRepository(PaymentEntity) } - async create(data: Pick): Promise { - const strategy = this.strategies.get(data.method) - if (!strategy) throw new NotFoundException("strategy not found") - return strategy.pay(data.amount, data.currency, "") - // const payment = this.paymentRepo.create({ - // amount: data.amount, - // method: data.method, - // type: data.type, - // currency: data.currency, - // tableId: data.tableId, - // }) - // await this.paymentRepo.save(payment) - // return link; + async pay(amount: number, currency: CurrencyType, method: PaymentMethod, cb: (qr: QueryRunner) => Promise<{ id: string, type: PaymentEntity["type"] }>, payform: PaymentPlatform = "web"): Promise<{ + refId: string, + clientAction: ClientAction, + status: PaymentEntity["status"], + paidAt?: string, + failureCode?: string, + failureMessage?: string, + }> { + + const strategy = this.strategies.get(method) + if (!strategy) { + throw new NotFoundException("strategy not found") + } + + const orderId = `freigh${Date.now()}${crypto.randomBytes(4).toString('hex')}` //todo: make it dynamic + const paymentResp = await strategy.pay({ + amountMinor: amount, + currency: currency, + merchantOrderId: orderId, + platform: payform, + }); + + const queryRunner = this.datasource.createQueryRunner() + await queryRunner.connect() + await queryRunner.startTransaction() + + console.log(paymentResp.expiresAt) + try { + const resp = await cb(queryRunner) + const payment = await this.paymentRepo.createTr(queryRunner, { + amount, + currency, + method, + refId: resp.id, + type: resp.type, + merchantOrderId: orderId, + rawInitiation: paymentResp.rawInitiation, + clientAction: paymentResp.clientAction, + expiresAt: paymentResp.expiresAt + + }) + await queryRunner.commitTransaction() + return { + refId: payment.refId, + clientAction: paymentResp.clientAction, + status: payment.status, + paidAt: payment.paidAt?.toISOString(), + failureCode: payment.failerCode ?? undefined, + failureMessage: payment.failureMessage ?? undefined, + } + } catch (err) { + await queryRunner.rollbackTransaction() + throw new Error("payment failed") + } finally { + await queryRunner.release() + } + } - getPaymentByReferenceIdAndMethod(data: Pick): Promise { - return this.paymentRepo.findOneBy(data) + + async getActivePaymentByRefIdAndMethod(refId: string, method: PaymentEntity["method"]): Promise { + return this.paymentRepo.getActivePaymentByRefIdAndMethod(refId, method) } diff --git a/apps/edr-freight-api/src/modules/payment/strategies/payment.strategy.ts b/apps/edr-freight-api/src/modules/payment/strategies/payment.strategy.ts index a74fe9782..b1daa2770 100644 --- a/apps/edr-freight-api/src/modules/payment/strategies/payment.strategy.ts +++ b/apps/edr-freight-api/src/modules/payment/strategies/payment.strategy.ts @@ -1,9 +1,8 @@ import { Injectable } from "@nestjs/common"; -import { PaymentEntity } from "../entities/payment.entity"; +import { ProviderInitiationInput, ProviderInitiationResult } from "./payments.types"; -type PaymentCurrency = PaymentEntity["currency"] @Injectable() export abstract class PaymentStrategy { - abstract pay(amount: number, currency: PaymentCurrency, refId: string): Promise + abstract pay(data: ProviderInitiationInput): Promise } \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/strategies/payment.telebirr.strategy.ts b/apps/edr-freight-api/src/modules/payment/strategies/payment.telebirr.strategy.ts index 521b6ee9b..3fa5fdc75 100644 --- a/apps/edr-freight-api/src/modules/payment/strategies/payment.telebirr.strategy.ts +++ b/apps/edr-freight-api/src/modules/payment/strategies/payment.telebirr.strategy.ts @@ -9,25 +9,20 @@ import { PaymentEntity } from "../entities/payment.entity"; import { ProviderInitiationInput, ProviderInitiationResult, ProviderStatus } from "./payments.types"; import { CreateOrderRequest, CreateOrderResponse, FabricTokenResponse, QueryOrderResponse } from "./telebirr/telebirr.types"; import { createNonceStr, createTimestamp, signRequestObject, verifyRequestObject } from "./telebirr/telebirr.crypto"; -import { randomUUID } from "node:crypto"; // type PaymentCurrency = PaymentEntity["currency"] type PaymentIntentStatus = PaymentEntity["status"] + const TELEBIRR_HTTP_TIMEOUT_MS = 10_000; @Injectable() export class PaymentTelebirrStrategy implements PaymentStrategy { - async pay(amount: number): Promise { - const refId = randomUUID() - const resp = await this.initiate({ - amountMinor: amount, - bookingRef: refId, - currency: "etb", - merchantOrderId: "", - platform: "web" - }) + async pay(data: ProviderInitiationInput): Promise { + // const refId = randomUUID() + // const orderId = createMerchantOrderId() + const resp = await this.initiate(data) return resp; } @@ -151,6 +146,7 @@ export class PaymentTelebirrStrategy implements PaymentStrategy { } private async applyFabricToken(): Promise { + console.log(this.baseUrl, "base url") const response = await this.postJson( `${this.baseUrl}/payment/v1/token`, { appSecret: this.appSecret }, diff --git a/apps/edr-freight-api/src/modules/payment/strategies/payments.types.ts b/apps/edr-freight-api/src/modules/payment/strategies/payments.types.ts index bf803c3e2..dae192db9 100644 --- a/apps/edr-freight-api/src/modules/payment/strategies/payments.types.ts +++ b/apps/edr-freight-api/src/modules/payment/strategies/payments.types.ts @@ -11,7 +11,7 @@ export type ClientAction = export interface ProviderInitiationInput { merchantOrderId: string; - bookingRef: string; + // bookingRef: string; amountMinor: number; currency: string; platform?: PaymentPlatform; From c0dc9f5fc55211bbf6be1a0a38a5222e55635ff7 Mon Sep 17 00:00:00 2001 From: Tria Date: Fri, 5 Jun 2026 12:54:35 +0300 Subject: [PATCH 3/4] payment --- .../payment/dto/update-payment-status.dto.ts | 23 + .../src/modules/payment/payment.controller.ts | 7 +- .../src/modules/payment/payment.module.ts | 6 +- .../src/modules/payment/payment.repository.ts | 1 + .../src/modules/payment/payment.service.ts | 24 +- .../payment/webhooks/dto/telebirr.dto.ts | 13 + .../webhooks/providers/telebirr.service.ts | 49 + .../payment/webhooks/webhook.controller.ts | 41 + pnpm-lock.yaml | 2092 ++++++++++++++++- 9 files changed, 2163 insertions(+), 93 deletions(-) create mode 100644 apps/edr-freight-api/src/modules/payment/dto/update-payment-status.dto.ts create mode 100644 apps/edr-freight-api/src/modules/payment/webhooks/dto/telebirr.dto.ts create mode 100644 apps/edr-freight-api/src/modules/payment/webhooks/providers/telebirr.service.ts create mode 100644 apps/edr-freight-api/src/modules/payment/webhooks/webhook.controller.ts diff --git a/apps/edr-freight-api/src/modules/payment/dto/update-payment-status.dto.ts b/apps/edr-freight-api/src/modules/payment/dto/update-payment-status.dto.ts new file mode 100644 index 000000000..de72c8ba7 --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/dto/update-payment-status.dto.ts @@ -0,0 +1,23 @@ +import { IsEnum, IsOptional, IsString } from "class-validator"; + +export enum PaymentStatus { + REQUIRES_ACTION, + PROCESSING, + SUCCEEDED, + FAILED, + CANCELLED, + REFUNDED, + +} +export class UpdatePaymentStatusDto { + @IsString() + orderId!: string; + + + @IsEnum(PaymentStatus) + status!: PaymentStatus + + @IsOptional() + @IsString() + failureMessage?: string +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/payment.controller.ts b/apps/edr-freight-api/src/modules/payment/payment.controller.ts index dda0e4af8..9614d9517 100644 --- a/apps/edr-freight-api/src/modules/payment/payment.controller.ts +++ b/apps/edr-freight-api/src/modules/payment/payment.controller.ts @@ -1,8 +1,9 @@ -import { Controller, Get, NotFoundException, Param, ParseUUIDPipe, Post, Res } from "@nestjs/common"; +import { Body, Controller, Get, NotFoundException, Param, ParseUUIDPipe, Post, Res } from "@nestjs/common"; import { PaymentService } from "./payment.service"; import { Public } from "@edr/api-common"; import { randomUUID } from "crypto"; import { Response } from "express" +import { UpdatePaymentStatusDto } from "./dto/update-payment-status.dto"; @Public() @Controller("payments") export class PaymentController { @@ -49,9 +50,5 @@ export class PaymentController { } - @Post("web-hooks/telebirr") - paymentWebhook() { - - } } \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/payment.module.ts b/apps/edr-freight-api/src/modules/payment/payment.module.ts index b20c331b3..e9f99bd06 100644 --- a/apps/edr-freight-api/src/modules/payment/payment.module.ts +++ b/apps/edr-freight-api/src/modules/payment/payment.module.ts @@ -5,10 +5,12 @@ import { HttpModule } from "@nestjs/axios"; import { PaymentController } from "./payment.controller"; import { ConfigModule } from "@nestjs/config"; import { PaymentRepository } from "./payment.repository"; +import { WebhookController } from "./webhooks/webhook.controller"; +import { TelebirrWebhookService } from "./webhooks/providers/telebirr.service"; @Module({ imports: [HttpModule, ConfigModule], - providers: [PaymentRepository, PaymentTelebirrStrategy, PaymentService], - controllers: [PaymentController] + providers: [PaymentRepository, PaymentTelebirrStrategy, PaymentService, TelebirrWebhookService], + controllers: [PaymentController, WebhookController] }) export class PaymentModule { } \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/payment.repository.ts b/apps/edr-freight-api/src/modules/payment/payment.repository.ts index 229ea7b58..3f93fd77d 100644 --- a/apps/edr-freight-api/src/modules/payment/payment.repository.ts +++ b/apps/edr-freight-api/src/modules/payment/payment.repository.ts @@ -35,4 +35,5 @@ export class PaymentRepository { } + } \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/payment.service.ts b/apps/edr-freight-api/src/modules/payment/payment.service.ts index f02d2502c..cee35bf79 100644 --- a/apps/edr-freight-api/src/modules/payment/payment.service.ts +++ b/apps/edr-freight-api/src/modules/payment/payment.service.ts @@ -1,11 +1,12 @@ import { Injectable, NotFoundException } from "@nestjs/common"; -import { DataSource, QueryRunner } from "typeorm"; +import { DataSource, QueryRunner } from "typeorm"; import { PaymentEntity } from "./entities/payment.entity"; import { PaymentStrategy } from "./strategies/payment.strategy"; import { PaymentTelebirrStrategy } from "./strategies/payment.telebirr.strategy"; import { PaymentRepository } from "./payment.repository"; import { ClientAction, PaymentPlatform } from "./strategies/payments.types"; import * as crypto from 'crypto'; +import { PaymentStatus, UpdatePaymentStatusDto } from "./dto/update-payment-status.dto"; type PaymentMethod = PaymentEntity["method"] type CurrencyType = PaymentEntity["currency"] @@ -88,4 +89,25 @@ export class PaymentService { } + async handleTelebirrPaymentCb(dto: UpdatePaymentStatusDto): Promise { + switch (dto.status) { + case PaymentStatus.SUCCEEDED: + await this.paymentRepo.update({ merchantOrderId: dto.orderId }, { status: "success" }) + break; + case PaymentStatus.FAILED: + await this.paymentRepo.update({ merchantOrderId: dto.orderId }, { status: "failed", failureMessage: dto.failureMessage }) + break; + case PaymentStatus.CANCELLED: + await this.paymentRepo.update({ merchantOrderId: dto.orderId }, { status: "canceled" }) + break; + case PaymentStatus.PROCESSING: + await this.paymentRepo.update({ merchantOrderId: dto.orderId }, { status: "canceled" }) + break; + case PaymentStatus.REFUNDED: + await this.paymentRepo.update({ merchantOrderId: dto.orderId }, { status: "canceled" }) + break; + + } + } + } \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/webhooks/dto/telebirr.dto.ts b/apps/edr-freight-api/src/modules/payment/webhooks/dto/telebirr.dto.ts new file mode 100644 index 000000000..ef6bf4b3a --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/webhooks/dto/telebirr.dto.ts @@ -0,0 +1,13 @@ +export class TelebirrDto { + merch_order_id!: string; + payment_order_id!: string; + trade_status!: string; + trans_id?: string; + total_amount?: string; + trans_currency?: string; + notify_time?: string; + trans_end_time?: string; + sign!: string; + sign_type?: string; + [key: string]: unknown; +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/webhooks/providers/telebirr.service.ts b/apps/edr-freight-api/src/modules/payment/webhooks/providers/telebirr.service.ts new file mode 100644 index 000000000..cd734f81a --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/webhooks/providers/telebirr.service.ts @@ -0,0 +1,49 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import * as crypto from "crypto" +import { TelebirrDto } from '../dto/telebirr.dto'; +@Injectable() +export class TelebirrWebhookService { + // private readonly logger = new Logger(TelebirrWebhookService.name); + + constructor( + private readonly config: ConfigService + ) { } + + verifyTelebirrNotification(payload: TelebirrDto) { + // 1. Extract the signature provided by Telebirr + const { sign, ...bizContent } = payload; + + if (!sign) { + throw new Error("Missing 'sign' field from Telebirr payload"); + } + + // 2. Sort the remaining keys alphabetically to rebuild the raw string + const sortedKeys = Object.keys(bizContent).sort(); + const signString = sortedKeys + .map(key => `${key}=${typeof bizContent[key] === 'object' ? JSON.stringify(bizContent[key]) : bizContent[key]}`) + .join('&'); + + // 3. Convert Telebirr's public key into an object specifying RSA-PSS padding + const publicKey = { + key: this.config.get("telebirr.publicKey") ?? "", + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength: 32 // Telebirr standard salt length + }; + + // 4. Verify the signature against the sorted string + const isVerified = crypto.verify( + "sha256", + Buffer.from(signString), + publicKey, + Buffer.from(sign, 'base64') + ); + + return isVerified; + } + + async handle(payload: TelebirrDto): Promise { + + } + +} \ No newline at end of file diff --git a/apps/edr-freight-api/src/modules/payment/webhooks/webhook.controller.ts b/apps/edr-freight-api/src/modules/payment/webhooks/webhook.controller.ts new file mode 100644 index 000000000..378853728 --- /dev/null +++ b/apps/edr-freight-api/src/modules/payment/webhooks/webhook.controller.ts @@ -0,0 +1,41 @@ +import { All, Body, Controller, HttpCode, HttpStatus, Logger, } from '@nestjs/common'; +import { TelebirrWebhookService } from './providers/telebirr.service'; +import { ApiOperation } from '@nestjs/swagger'; +import { TelebirrDto } from './dto/telebirr.dto'; + +@Controller("payments/webhooks") +export class WebhookController { + constructor(private readonly telebirr: TelebirrWebhookService) { } + private readonly logger = new Logger(WebhookController.name); + + @All('telebirr') + @HttpCode(HttpStatus.OK) + @ApiOperation({ + summary: 'Telebirr payment notification callback (Ethiopia)', + description: 'Webhook endpoint for Telebirr payment status updates. Used by Ethiopian passengers.' + }) + async receiveTelebirr(@Body() payload: TelebirrDto) { + this.logger.log( + `Telebirr webhook Called`, + ); + + try { + const verified = this.telebirr.verifyTelebirrNotification(payload) + if (!verified) { + throw new Error("not valid") + } + const merchantOrderId = payload.merch_order_id; + if (merchantOrderId.startsWith("freight")) { + await this.telebirr.handle(payload); + } else if (merchantOrderId.startsWith("passagner")) { + //todo: handle else where + } + + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + this.logger.error(`Telebirr webhook handler threw: ${message}`); + } + return { code: '0', message: 'OK' }; + } + +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8c735c36c..df069b83d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,7 +16,7 @@ importers: devDependencies: '@commitlint/cli': specifier: ^19.5.0 - version: 19.8.1(@types/node@20.19.41)(typescript@5.9.3) + version: 19.8.1(@types/node@24.13.0)(typescript@5.9.3) '@commitlint/config-conventional': specifier: ^19.5.0 version: 19.8.1 @@ -152,7 +152,7 @@ importers: version: 7.2.2 ts-jest: specifier: ^29.2.5 - version: 29.4.11(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.41)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)))(typescript@5.9.3) + version: 29.4.11(@babel/core@7.29.0)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.0))(jest-util@30.4.1)(jest@29.7.0(@types/node@20.19.41)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)))(typescript@5.9.3) ts-loader: specifier: ^9.5.1 version: 9.5.7(typescript@5.9.3)(webpack@5.106.0) @@ -228,7 +228,7 @@ importers: version: link:../../../packages/config/tsconfig '@tailwindcss/vite': specifier: ^4.3.0 - version: 4.3.0(vite@5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0)) + version: 4.3.0(vite@5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0)) '@types/react': specifier: ^18.3.11 version: 18.3.29 @@ -237,7 +237,7 @@ importers: version: 18.3.7(@types/react@18.3.29) '@vitejs/plugin-react': specifier: ^4.3.2 - version: 4.7.0(vite@5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0)) + version: 4.7.0(vite@5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0)) autoprefixer: specifier: ^10.4.20 version: 10.5.0(postcss@8.5.15) @@ -255,10 +255,10 @@ importers: version: 5.9.3 vite: specifier: ^5.4.8 - version: 5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0) + version: 5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0) vitest: specifier: ^2.1.2 - version: 2.1.9(@types/node@20.19.41)(jsdom@25.0.1(canvas@2.11.2))(lightningcss@1.32.0)(msw@2.14.6(@types/node@20.19.41)(typescript@5.9.3))(terser@5.48.0) + version: 2.1.9(@types/node@24.13.0)(jsdom@25.0.1(canvas@2.11.2))(lightningcss@1.32.0)(msw@2.14.6(@types/node@24.13.0)(typescript@5.9.3))(terser@5.48.0) apps/edr-freight-web/portal: dependencies: @@ -325,7 +325,7 @@ importers: version: link:../../../packages/config/tsconfig '@tailwindcss/vite': specifier: ^4.3.0 - version: 4.3.0(vite@5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0)) + version: 4.3.0(vite@5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0)) '@types/react': specifier: ^18.3.11 version: 18.3.29 @@ -334,7 +334,7 @@ importers: version: 18.3.7(@types/react@18.3.29) '@vitejs/plugin-react': specifier: ^4.3.2 - version: 4.7.0(vite@5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0)) + version: 4.7.0(vite@5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0)) autoprefixer: specifier: ^10.4.20 version: 10.5.0(postcss@8.5.15) @@ -352,10 +352,10 @@ importers: version: 5.9.3 vite: specifier: ^5.4.8 - version: 5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0) + version: 5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0) vitest: specifier: ^2.1.2 - version: 2.1.9(@types/node@20.19.41)(jsdom@25.0.1(canvas@2.11.2))(lightningcss@1.32.0)(msw@2.14.6(@types/node@20.19.41)(typescript@5.9.3))(terser@5.48.0) + version: 2.1.9(@types/node@24.13.0)(jsdom@25.0.1(canvas@2.11.2))(lightningcss@1.32.0)(msw@2.14.6(@types/node@24.13.0)(typescript@5.9.3))(terser@5.48.0) apps/edr-passenger-api: dependencies: @@ -440,7 +440,7 @@ importers: version: 7.2.2 ts-jest: specifier: ^29.2.5 - version: 29.4.11(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.41)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)))(typescript@5.9.3) + version: 29.4.11(@babel/core@7.29.0)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.0))(jest-util@30.4.1)(jest@29.7.0(@types/node@20.19.41)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)))(typescript@5.9.3) ts-loader: specifier: ^9.5.1 version: 9.5.7(typescript@5.9.3)(webpack@5.106.0) @@ -498,7 +498,7 @@ importers: version: 18.3.7(@types/react@18.3.29) '@vitejs/plugin-react': specifier: ^4.3.2 - version: 4.7.0(vite@5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0)) + version: 4.7.0(vite@5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0)) autoprefixer: specifier: ^10.4.20 version: 10.5.0(postcss@8.5.15) @@ -516,10 +516,10 @@ importers: version: 5.9.3 vite: specifier: ^5.4.8 - version: 5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0) + version: 5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0) vitest: specifier: ^2.1.2 - version: 2.1.9(@types/node@20.19.41)(jsdom@25.0.1(canvas@2.11.2))(lightningcss@1.32.0)(msw@2.14.6(@types/node@20.19.41)(typescript@5.9.3))(terser@5.48.0) + version: 2.1.9(@types/node@24.13.0)(jsdom@25.0.1(canvas@2.11.2))(lightningcss@1.32.0)(msw@2.14.6(@types/node@24.13.0)(typescript@5.9.3))(terser@5.48.0) apps/edr-passenger-web/portal: dependencies: @@ -565,7 +565,7 @@ importers: version: 18.3.7(@types/react@18.3.29) '@vitejs/plugin-react': specifier: ^4.3.2 - version: 4.7.0(vite@5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0)) + version: 4.7.0(vite@5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0)) autoprefixer: specifier: ^10.4.20 version: 10.5.0(postcss@8.5.15) @@ -583,10 +583,110 @@ importers: version: 5.9.3 vite: specifier: ^5.4.8 - version: 5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0) + version: 5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0) vitest: specifier: ^2.1.2 - version: 2.1.9(@types/node@20.19.41)(jsdom@25.0.1(canvas@2.11.2))(lightningcss@1.32.0)(msw@2.14.6(@types/node@20.19.41)(typescript@5.9.3))(terser@5.48.0) + version: 2.1.9(@types/node@24.13.0)(jsdom@25.0.1(canvas@2.11.2))(lightningcss@1.32.0)(msw@2.14.6(@types/node@24.13.0)(typescript@5.9.3))(terser@5.48.0) + + apps/edr-payment-webhook: + dependencies: + '@nestjs/axios': + specifier: ^4.0.1 + version: 4.0.1(@nestjs/common@11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.17.0)(rxjs@7.8.2) + '@nestjs/common': + specifier: ^11.0.1 + version: 11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/config': + specifier: ^4.0.0 + version: 4.0.4(@nestjs/common@11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) + '@nestjs/core': + specifier: ^11.0.1 + version: 11.1.23(@nestjs/common@11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/microservices@11.1.23)(@nestjs/platform-express@11.1.23)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/platform-express': + specifier: ^11.0.1 + version: 11.1.23(@nestjs/common@11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.23) + '@nestjs/swagger': + specifier: ^11.4.2 + version: 11.4.4(@nestjs/common@11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.23)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) + axios: + specifier: ^1.17.0 + version: 1.17.0 + reflect-metadata: + specifier: ^0.2.2 + version: 0.2.2 + rxjs: + specifier: ^7.8.1 + version: 7.8.2 + devDependencies: + '@eslint/eslintrc': + specifier: ^3.2.0 + version: 3.3.5 + '@eslint/js': + specifier: ^9.18.0 + version: 9.39.4 + '@nestjs/cli': + specifier: ^11.0.0 + version: 11.0.21(@types/node@24.13.0)(prettier@3.8.3) + '@nestjs/schematics': + specifier: ^11.0.0 + version: 11.1.0(chokidar@4.0.3)(prettier@3.8.3)(typescript@5.9.3) + '@nestjs/testing': + specifier: ^11.0.1 + version: 11.1.23(@nestjs/common@11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.23)(@nestjs/microservices@11.1.23)(@nestjs/platform-express@11.1.23) + '@types/express': + specifier: ^5.0.0 + version: 5.0.6 + '@types/jest': + specifier: ^30.0.0 + version: 30.0.0 + '@types/node': + specifier: ^24.0.0 + version: 24.13.0 + '@types/supertest': + specifier: ^7.0.0 + version: 7.2.0 + eslint: + specifier: ^9.18.0 + version: 9.39.4(jiti@2.7.0) + eslint-config-prettier: + specifier: ^10.0.1 + version: 10.1.8(eslint@9.39.4(jiti@2.7.0)) + eslint-plugin-prettier: + specifier: ^5.2.2 + version: 5.5.6(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.4(jiti@2.7.0)))(eslint@9.39.4(jiti@2.7.0))(prettier@3.8.3) + globals: + specifier: ^17.0.0 + version: 17.6.0 + jest: + specifier: ^30.0.0 + version: 30.4.2(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3)) + prettier: + specifier: ^3.4.2 + version: 3.8.3 + source-map-support: + specifier: ^0.5.21 + version: 0.5.21 + supertest: + specifier: ^7.0.0 + version: 7.2.2 + ts-jest: + specifier: ^29.2.5 + version: 29.4.11(@babel/core@7.29.0)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.0))(jest-util@30.4.1)(jest@30.4.2(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3)))(typescript@5.9.3) + ts-loader: + specifier: ^9.5.2 + version: 9.5.7(typescript@5.9.3)(webpack@5.106.0) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@24.13.0)(typescript@5.9.3) + tsconfig-paths: + specifier: ^4.2.0 + version: 4.2.0 + typescript: + specifier: ^5.7.3 + version: 5.9.3 + typescript-eslint: + specifier: ^8.20.0 + version: 8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) packages/api-common: dependencies: @@ -687,7 +787,7 @@ importers: version: 1.4.3(@types/react-dom@18.3.7(@types/react@18.3.29))(@types/react@18.3.29)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) shadcn: specifier: ^4.7.0 - version: 4.8.0(@types/node@20.19.41)(babel-plugin-macros@3.1.0)(typescript@5.9.3) + version: 4.8.0(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(typescript@5.9.3) tailwind-merge: specifier: ^3.6.0 version: 3.6.0 @@ -1114,6 +1214,15 @@ packages: peerDependencies: '@noble/ciphers': ^1.0.0 + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@emotion/babel-plugin@11.13.5': resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} @@ -1316,14 +1425,42 @@ packages: resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@2.1.4': resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@8.57.1': resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@faker-js/faker@10.4.0': resolution: {integrity: sha512-sDBWI3yLy8EcDzgobvJTWq1MJYzAkQdpjXuPukga9wXonhpMRvd1Izuo2Qgwey2OiEoRIBr35RMU9HJRoOHzpw==} engines: {node: ^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0, npm: '>=10'} @@ -1372,6 +1509,18 @@ packages: peerDependencies: react-hook-form: ^7.55.0 + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + '@humanwhocodes/config-array@0.13.0': resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} @@ -1385,6 +1534,10 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + '@inquirer/ansi@1.0.2': resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} engines: {node: '>=18'} @@ -1585,6 +1738,10 @@ packages: resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/console@30.4.1': + resolution: {integrity: sha512-v3bhyxUh9Hgmo5p6hAOXe14/R3ZxZDOsvHleh4B07z3m/x4/ngPUXEm9XwK4sF4u+f+P2ORb0Ge+MgpaqRMVDA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/core@29.7.0': resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1594,26 +1751,67 @@ packages: node-notifier: optional: true + '@jest/core@30.4.2': + resolution: {integrity: sha512-TZJA6cPJUFxoWhxaLo8t0VX/MZX2wPWr0uIDvLSHIvN4gu9h02vSzqI2kBADG1ExqQlC+cY09xKMSreivvrChQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/diff-sequences@30.4.0': + resolution: {integrity: sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/environment@29.7.0': resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/environment@30.4.1': + resolution: {integrity: sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/expect-utils@29.7.0': resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/expect-utils@30.4.1': + resolution: {integrity: sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/expect@29.7.0': resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/expect@30.4.1': + resolution: {integrity: sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/fake-timers@29.7.0': resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/fake-timers@30.4.1': + resolution: {integrity: sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/get-type@30.1.0': + resolution: {integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/globals@29.7.0': resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/globals@30.4.1': + resolution: {integrity: sha512-ZbuY4cmXC8DkxYjfvT2DbcHWL2T6vmsMhXCDcmTB2T0y0gaezBI77ufq5ZAIdcRkYZ7NEQEDg1xFeKbxUJ5v5Q==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/pattern@30.4.0': + resolution: {integrity: sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/reporters@29.7.0': resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1623,30 +1821,67 @@ packages: node-notifier: optional: true + '@jest/reporters@30.4.1': + resolution: {integrity: sha512-/SnkPCzEQpUaBH81kjdEdDdo2WZl5hxw+BmLDGWjRkm8o7XlhjwsU36cqwe5PGBE5WYpBvDzRSdXx9rbGuJtNA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + '@jest/schemas@29.6.3': resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/schemas@30.4.1': + resolution: {integrity: sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/snapshot-utils@30.4.1': + resolution: {integrity: sha512-ObY4ljvQ95mt6iwKtVLetR/4yXiAgl3H4nJxhztr0MTjrN97TwDYrnCp/kF60Ec9HdhkWTHSu+Hg05aXfngpOA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/source-map@29.6.3': resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/source-map@30.0.1': + resolution: {integrity: sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/test-result@29.7.0': resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-result@30.4.1': + resolution: {integrity: sha512-/ZG7pgEiOmmWkN9TplKbOu4id2N5lh7FHwRwlkgBVAzGdRH+OkkQ8wX/kIxg4zmd3ZQvAL1RwL2yWsvNYYECTw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/test-sequencer@29.7.0': resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-sequencer@30.4.1': + resolution: {integrity: sha512-PeYE+4td5rKjoRPxztObrXU+H8hsjZfxKMXOcmrr34JerSyB/ROOxbbicz8B7A5j9R9VayDnVPvBmedqCsFCdw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/transform@29.7.0': resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/transform@30.4.1': + resolution: {integrity: sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/types@29.6.3': resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/types@30.4.1': + resolution: {integrity: sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -1867,6 +2102,12 @@ packages: moment-jalaali: optional: true + '@napi-rs/wasm-runtime@1.1.4': + resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + '@nestjs/axios@4.0.1': resolution: {integrity: sha512-68pFJgu+/AZbWkGu65Z3r55bTsCPlgyKaV4BSG8yUAD72q1PPuyVRgUwFv6BxdnibTUHlyxm06FmYWNC+bjN7A==} peerDependencies: @@ -2192,6 +2433,10 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@pkgr/core@0.3.6': + resolution: {integrity: sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==} + engines: {node: ^14.18.0 || >=16.0.0} + '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -3275,6 +3520,9 @@ packages: '@sinclair/typebox@0.27.10': resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} + '@sinclair/typebox@0.34.49': + resolution: {integrity: sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==} + '@sindresorhus/merge-streams@4.0.0': resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} @@ -3285,6 +3533,9 @@ packages: '@sinonjs/fake-timers@10.3.0': resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@sinonjs/fake-timers@15.4.0': + resolution: {integrity: sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==} + '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} @@ -3714,6 +3965,9 @@ packages: cpu: [arm64] os: [win32] + '@tybys/wasm-util@0.10.2': + resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + '@types/amqplib@0.10.8': resolution: {integrity: sha512-vtDp8Pk1wsE/AuQ8/Rgtm6KUZYqcnTgNvEHwzCkX8rL7AGsC6zqAfKAAJhUZXFhM/Pp++tbnUHiam/8vVpPztA==} @@ -3809,6 +4063,9 @@ packages: '@types/jest@29.5.14': resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + '@types/jest@30.0.0': + resolution: {integrity: sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -3833,6 +4090,9 @@ packages: '@types/node@20.19.41': resolution: {integrity: sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==} + '@types/node@24.13.0': + resolution: {integrity: sha512-5vtOqGQr4NJKeEzV441FcOi2MeG9UTWq9LqVLGneDdu4vlX17H8kQ2PA2UmNwCUGPVDj4oBjNhS7ReVEIWJJrg==} + '@types/pako@2.0.4': resolution: {integrity: sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw==} @@ -3888,6 +4148,9 @@ packages: '@types/supertest@6.0.3': resolution: {integrity: sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==} + '@types/supertest@7.2.0': + resolution: {integrity: sha512-uh2Lv57xvggst6lCqNdFAmDSvoMG7M/HDtX4iUCquxQ5EGPtaPM5PL5Hmi7LCvOG8db7YaCPNJEeoI8s/WzIQw==} + '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -3914,6 +4177,14 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/eslint-plugin@8.60.1': + resolution: {integrity: sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.60.1 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/parser@8.59.4': resolution: {integrity: sha512-zORHqO/tuhxY1zWuTvMUqddRxpiFJ72xVfcNoWpqdLjs6lfPbuQBJuW4pk+49/uBMy7Ssr4bzgjiKmmDB1UbZQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3921,22 +4192,45 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/parser@8.60.1': + resolution: {integrity: sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/project-service@8.59.4': resolution: {integrity: sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/project-service@8.60.1': + resolution: {integrity: sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/scope-manager@8.59.4': resolution: {integrity: sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.60.1': + resolution: {integrity: sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/tsconfig-utils@8.59.4': resolution: {integrity: sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/tsconfig-utils@8.60.1': + resolution: {integrity: sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/type-utils@8.59.4': resolution: {integrity: sha512-uonTuPAAKr9XaBGqJ3LjYTh72zy5DyGesljO9gtmk/eFW0W1fRHjnwVYKB35Lm8d5Q5CluEW3gPHjTvZTmgrfA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3944,16 +4238,33 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/type-utils@8.60.1': + resolution: {integrity: sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/types@8.59.4': resolution: {integrity: sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.60.1': + resolution: {integrity: sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.59.4': resolution: {integrity: sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/typescript-estree@8.60.1': + resolution: {integrity: sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/utils@8.59.4': resolution: {integrity: sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3961,13 +4272,134 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/utils@8.60.1': + resolution: {integrity: sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/visitor-keys@8.59.4': resolution: {integrity: sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.60.1': + resolution: {integrity: sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.1': resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==} + '@unrs/resolver-binding-android-arm-eabi@1.12.2': + resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.12.2': + resolution: {integrity: sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.12.2': + resolution: {integrity: sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.12.2': + resolution: {integrity: sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.12.2': + resolution: {integrity: sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': + resolution: {integrity: sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': + resolution: {integrity: sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': + resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.12.2': + resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': + resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==} + cpu: [loong64] + os: [linux] + + '@unrs/resolver-binding-linux-loong64-musl@1.12.2': + resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==} + cpu: [loong64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': + resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': + resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': + resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': + resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.12.2': + resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.12.2': + resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-openharmony-arm64@1.12.2': + resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==} + cpu: [arm64] + os: [openharmony] + + '@unrs/resolver-binding-wasm32-wasi@1.12.2': + resolution: {integrity: sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': + resolution: {integrity: sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': + resolution: {integrity: sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.12.2': + resolution: {integrity: sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==} + cpu: [x64] + os: [win32] + '@vitejs/plugin-react@4.7.0': resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} engines: {node: ^14.18.0 || >=16.0.0} @@ -4701,20 +5133,37 @@ packages: axios@1.16.1: resolution: {integrity: sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==} + axios@1.17.0: + resolution: {integrity: sha512-J8SwNxprqqpbfenehxWYXE7CW+wM1BB4w3+N+g+/Wx40xM4rsLrfPmHHxSWIxJLYDgSY/HqlFPIYb2/S3rxafw==} + babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.8.0 + babel-jest@30.4.1: + resolution: {integrity: sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + '@babel/core': ^7.11.0 || ^8.0.0-0 + babel-plugin-istanbul@6.1.1: resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} engines: {node: '>=8'} + babel-plugin-istanbul@7.0.1: + resolution: {integrity: sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==} + engines: {node: '>=12'} + babel-plugin-jest-hoist@29.6.3: resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + babel-plugin-jest-hoist@30.4.0: + resolution: {integrity: sha512-9EdtWM/sSfXLOGLwSn+GS6pIXyBnL07/8gyJlwFXjWy4DxMOyItqyUT29d4lQiS380EZwYlX7/At4PgBS+m2aA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + babel-plugin-macros@3.1.0: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} @@ -4730,6 +5179,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + babel-preset-jest@30.4.0: + resolution: {integrity: sha512-lBY4jxsNmCnSiu7kquw8ZC9F4+XLMOKypT3RnNHPvU2Kpd4W0xaPuLr5ZkRyOsvLYAY4yaW1ZwTW4xB7NIiZzg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + '@babel/core': ^7.11.0 || ^8.0.0-beta.1 + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -4964,9 +5419,16 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + cjs-module-lexer@1.4.3: resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + cjs-module-lexer@2.2.0: + resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} + class-transformer@0.5.1: resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} @@ -5723,6 +6185,12 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + eslint-config-prettier@9.1.2: resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} hasBin: true @@ -5763,6 +6231,20 @@ packages: '@typescript-eslint/parser': optional: true + eslint-plugin-prettier@5.5.6: + resolution: {integrity: sha512-ifetmTcxWfz+4qRW3pH/ujdTq2jQIj59AxJMIN26K5avYgU8dxycUETQonWiW+wPrYXA0j3Try0l1CnwVQtDqQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + eslint-plugin-react-hooks@4.6.2: resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} engines: {node: '>=10'} @@ -5788,10 +6270,18 @@ packages: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@5.0.1: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} @@ -5802,6 +6292,20 @@ packages: deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5883,6 +6387,10 @@ packages: resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} engines: {node: ^18.19.0 || >=20.5.0} + exit-x@0.2.2: + resolution: {integrity: sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==} + engines: {node: '>= 0.8.0'} + exit@0.1.2: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} @@ -5899,6 +6407,10 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + expect@30.4.1: + resolution: {integrity: sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + express-rate-limit@8.5.2: resolution: {integrity: sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==} engines: {node: '>= 16'} @@ -5932,6 +6444,9 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + fast-equals@5.4.0: resolution: {integrity: sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==} engines: {node: '>=6.0.0'} @@ -5998,6 +6513,10 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + file-selector@2.1.2: resolution: {integrity: sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==} engines: {node: '>= 12'} @@ -6045,6 +6564,10 @@ packages: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true @@ -6283,6 +6806,14 @@ packages: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@17.6.0: + resolution: {integrity: sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==} + engines: {node: '>=18'} + globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -6882,6 +7413,10 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + istanbul-reports@3.2.0: resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} engines: {node: '>=8'} @@ -6904,10 +7439,18 @@ packages: resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-changed-files@30.4.1: + resolution: {integrity: sha512-IuctmYrxi21iOSOaIXpJWalHyPAsVv0GeBHKDn8C1CA4W5htHn7INL+wdnL4Bo0+olEndvAFkmb++tIQJG+vvg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-circus@29.7.0: resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-circus@30.4.2: + resolution: {integrity: sha512-rvHH7VlY6LgbJXJTQ87GW62g1FntOtbhh0zT+v04kC+pgL6aBKyYINXxWukCpj3dcIBMw5/XUbtDS9dU9JTXeQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-cli@29.7.0: resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6918,6 +7461,16 @@ packages: node-notifier: optional: true + jest-cli@30.4.2: + resolution: {integrity: sha512-jfA2ocvVHMXS2QijrJ0d31ektP+d/W0T5RpcTX2Pq+3sVqHlsXVCM2+FmwpL+bdY8OfHpIg9xMxLF17Zg0U49Q==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + jest-config@29.7.0: resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6930,22 +7483,53 @@ packages: ts-node: optional: true + jest-config@30.4.2: + resolution: {integrity: sha512-rNHAShJQqQwFNoL0hbf3BphSBOWnpOUAKvidLS/AjNVLPfoj5mSf4jQMfW3cYOs6hXeZC7nF7mDHaBnbxELOzg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + '@types/node': '*' + esbuild-register: '>=3.4.0' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + esbuild-register: + optional: true + ts-node: + optional: true + jest-diff@29.7.0: resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-diff@30.4.1: + resolution: {integrity: sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-docblock@29.7.0: resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-docblock@30.4.0: + resolution: {integrity: sha512-ZPMabUZCx5MpbZ2eBYSvZ0J8fvo3dR9oM+eeUpb3aKNQFuS2tu3Duw1TNlMoP8k3WQgKGJuhcMFvwcVuq6T7oA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-each@29.7.0: resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-each@30.4.1: + resolution: {integrity: sha512-/8MJbH6fuj48TstjrMf+u/pd06Qezz5xOXvZA6442heNOWr8bdeoGZX2d9fCn028CoMgYmroH9//zky5GfyYmA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-environment-node@29.7.0: resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-environment-node@30.4.1: + resolution: {integrity: sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-get-type@29.6.3: resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6954,22 +7538,42 @@ packages: resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-haste-map@30.4.1: + resolution: {integrity: sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-leak-detector@29.7.0: resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-leak-detector@30.4.1: + resolution: {integrity: sha512-IpmyiioeHxiWDhesHnUFmOxcTzwCwKpgACgWajtAP+nYQXiY7DakTxB6Bx9JFiRMljr0AX1PvnQdaU1KFoz6NQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-matcher-utils@29.7.0: resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-matcher-utils@30.4.1: + resolution: {integrity: sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-message-util@29.7.0: resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-message-util@30.4.1: + resolution: {integrity: sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-mock@29.7.0: resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-mock@30.4.1: + resolution: {integrity: sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-pnp-resolver@1.2.3: resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} engines: {node: '>=6'} @@ -6983,38 +7587,74 @@ packages: resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-regex-util@30.4.0: + resolution: {integrity: sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-resolve-dependencies@29.7.0: resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve-dependencies@30.4.2: + resolution: {integrity: sha512-gDiVh1I+GxYzz9oXlyw+1wv6VOYX1WYxMOfjsA3iGKePV2oxmbHhwxfkALxNxYy1ciw6APWwkW2zZONwP97aEQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-resolve@29.7.0: resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve@30.4.1: + resolution: {integrity: sha512-Zry8Yq/yJcNAZ7dJ5F2heic8AheXvbFZ7XI5V+h28nrYZ7Qoyy4dItq8OodjnYD270mvX+ZudmrNV9cysqhW5Q==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-runner@29.7.0: resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runner@30.4.2: + resolution: {integrity: sha512-2dw0PslVYXxffXGpLo+Ejad+KcI1Qkjn7f4X4619gf21oCUmL+SPfjqIa/losUem3yEOvfNZe/F1HWUcNpODcg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-runtime@29.7.0: resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runtime@30.4.2: + resolution: {integrity: sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-snapshot@29.7.0: resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-snapshot@30.4.1: + resolution: {integrity: sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-util@29.7.0: resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-util@30.4.1: + resolution: {integrity: sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-validate@29.7.0: resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-validate@30.4.1: + resolution: {integrity: sha512-PDWi4SOwLnwqNDfHZjOcsEFyZ4fc/2W2gVL3DEoyqnB6jCQMLRtfBong8s6omIw3lI0HWOus12xfnFmQtjW3fw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-watcher@29.7.0: resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-watcher@30.4.1: + resolution: {integrity: sha512-/l9UonmvCwjHH7d2h3iAwIloLc1H0S8mJZ/LNK3i86hqwPAz8otUJjP9MfYtz9Tt77Su5FD2xGjZn8d31IZHlw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} @@ -7023,6 +7663,10 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-worker@30.4.1: + resolution: {integrity: sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest@29.7.0: resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7033,6 +7677,16 @@ packages: node-notifier: optional: true + jest@30.4.2: + resolution: {integrity: sha512-Yi1jqNC/Oq0N4hBgNH/YvBpP1P57QqundgytzYqy3yqAa7NZPNjSoi4SGbRAXDMdBzNE6xBCi5U7RgfrvMEUVQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + jiti@1.21.7: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true @@ -7718,6 +8372,11 @@ packages: resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} engines: {node: '>=0.10.0'} + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -8243,6 +8902,10 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + prettier-linter-helpers@1.0.1: + resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==} + engines: {node: '>=6.0.0'} + prettier@3.8.3: resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==} engines: {node: '>=14'} @@ -8252,6 +8915,10 @@ packages: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-format@30.4.1: + resolution: {integrity: sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + pretty-ms@9.3.0: resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} engines: {node: '>=18'} @@ -8333,6 +9000,9 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + pure-rand@7.0.1: + resolution: {integrity: sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==} + qrcode@1.5.4: resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} engines: {node: '>=10.13.0'} @@ -9255,6 +9925,10 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + synckit@0.11.13: + resolution: {integrity: sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==} + engines: {node: ^14.18.0 || >=16.0.0} + tabbable@6.4.0: resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} @@ -9702,6 +10376,13 @@ packages: typeorm-aurora-data-api-driver: optional: true + typescript-eslint@8.60.1: + resolution: {integrity: sha512-6m5hkkRAp8lKvhVpcprAIn5KkehQEh+47oHH2VGnExEh7dhNxXlg6GPAOIu6TxbVQxhebrJDvjl3020ooiWCMA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -9727,6 +10408,9 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + unicode-properties@1.4.1: resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} @@ -9756,6 +10440,9 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unrs-resolver@1.12.2: + resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==} + unset-value@1.0.0: resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} engines: {node: '>=0.10.0'} @@ -10107,6 +10794,10 @@ packages: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ws@8.20.1: resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==} engines: {node: '>=10.0.0'} @@ -10294,6 +10985,18 @@ snapshots: - '@types/node' - chokidar + '@angular-devkit/schematics-cli@19.2.24(@types/node@24.13.0)(chokidar@4.0.3)': + dependencies: + '@angular-devkit/core': 19.2.24(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.24(chokidar@4.0.3) + '@inquirer/prompts': 7.3.2(@types/node@24.13.0) + ansi-colors: 4.1.3 + symbol-observable: 4.0.0 + yargs-parser: 21.1.1 + transitivePeerDependencies: + - '@types/node' + - chokidar + '@angular-devkit/schematics@19.2.24(chokidar@4.0.3)': dependencies: '@angular-devkit/core': 19.2.24(chokidar@4.0.3) @@ -10677,11 +11380,11 @@ snapshots: '@colors/colors@1.5.0': optional: true - '@commitlint/cli@19.8.1(@types/node@20.19.41)(typescript@5.9.3)': + '@commitlint/cli@19.8.1(@types/node@24.13.0)(typescript@5.9.3)': dependencies: '@commitlint/format': 19.8.1 '@commitlint/lint': 19.8.1 - '@commitlint/load': 19.8.1(@types/node@20.19.41)(typescript@5.9.3) + '@commitlint/load': 19.8.1(@types/node@24.13.0)(typescript@5.9.3) '@commitlint/read': 19.8.1 '@commitlint/types': 19.8.1 tinyexec: 1.1.2 @@ -10728,7 +11431,7 @@ snapshots: '@commitlint/rules': 19.8.1 '@commitlint/types': 19.8.1 - '@commitlint/load@19.8.1(@types/node@20.19.41)(typescript@5.9.3)': + '@commitlint/load@19.8.1(@types/node@24.13.0)(typescript@5.9.3)': dependencies: '@commitlint/config-validator': 19.8.1 '@commitlint/execute-rule': 19.8.1 @@ -10736,7 +11439,7 @@ snapshots: '@commitlint/types': 19.8.1 chalk: 5.6.2 cosmiconfig: 9.0.1(typescript@5.9.3) - cosmiconfig-typescript-loader: 6.3.0(@types/node@20.19.41)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3) + cosmiconfig-typescript-loader: 6.3.0(@types/node@24.13.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -10831,6 +11534,22 @@ snapshots: dependencies: '@noble/ciphers': 1.3.0 + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + '@emotion/babel-plugin@11.13.5': dependencies: '@babel/helper-module-imports': 7.28.6 @@ -10988,8 +11707,29 @@ snapshots: eslint: 8.57.1 eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.7.0))': + dependencies: + eslint: 9.39.4(jiti@2.7.0) + eslint-visitor-keys: 3.4.3 + '@eslint-community/regexpp@4.12.2': {} + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.15.0 @@ -11004,8 +11744,31 @@ snapshots: transitivePeerDependencies: - supports-color + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.15.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + '@eslint/js@8.57.1': {} + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + '@faker-js/faker@10.4.0': {} '@fast-csv/format@4.3.5': @@ -11065,6 +11828,18 @@ snapshots: '@standard-schema/utils': 0.3.0 react-hook-form: 7.76.0(react@19.2.6) + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 @@ -11077,6 +11852,8 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} + '@humanwhocodes/retry@0.4.3': {} + '@inquirer/ansi@1.0.2': {} '@inquirer/ansi@2.0.5': {} @@ -11091,6 +11868,16 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 + '@inquirer/checkbox@4.3.2(@types/node@24.13.0)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@24.13.0) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.13.0) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.13.0 + '@inquirer/confirm@5.1.21(@types/node@20.19.41)': dependencies: '@inquirer/core': 10.3.2(@types/node@20.19.41) @@ -11098,12 +11885,19 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 - '@inquirer/confirm@6.0.13(@types/node@20.19.41)': + '@inquirer/confirm@5.1.21(@types/node@24.13.0)': dependencies: - '@inquirer/core': 11.1.10(@types/node@20.19.41) - '@inquirer/type': 4.0.5(@types/node@20.19.41) + '@inquirer/core': 10.3.2(@types/node@24.13.0) + '@inquirer/type': 3.0.10(@types/node@24.13.0) optionalDependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 + + '@inquirer/confirm@6.0.13(@types/node@24.13.0)': + dependencies: + '@inquirer/core': 11.1.10(@types/node@24.13.0) + '@inquirer/type': 4.0.5(@types/node@24.13.0) + optionalDependencies: + '@types/node': 24.13.0 '@inquirer/core@10.3.2(@types/node@20.19.41)': dependencies: @@ -11118,17 +11912,30 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 - '@inquirer/core@11.1.10(@types/node@20.19.41)': + '@inquirer/core@10.3.2(@types/node@24.13.0)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.13.0) + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.13.0 + + '@inquirer/core@11.1.10(@types/node@24.13.0)': dependencies: '@inquirer/ansi': 2.0.5 '@inquirer/figures': 2.0.5 - '@inquirer/type': 4.0.5(@types/node@20.19.41) + '@inquirer/type': 4.0.5(@types/node@24.13.0) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 '@inquirer/editor@4.2.23(@types/node@20.19.41)': dependencies: @@ -11138,6 +11945,14 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 + '@inquirer/editor@4.2.23(@types/node@24.13.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@24.13.0) + '@inquirer/external-editor': 1.0.3(@types/node@24.13.0) + '@inquirer/type': 3.0.10(@types/node@24.13.0) + optionalDependencies: + '@types/node': 24.13.0 + '@inquirer/expand@4.0.23(@types/node@20.19.41)': dependencies: '@inquirer/core': 10.3.2(@types/node@20.19.41) @@ -11146,6 +11961,14 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 + '@inquirer/expand@4.0.23(@types/node@24.13.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@24.13.0) + '@inquirer/type': 3.0.10(@types/node@24.13.0) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.13.0 + '@inquirer/external-editor@1.0.3(@types/node@20.19.41)': dependencies: chardet: 2.1.1 @@ -11153,6 +11976,13 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 + '@inquirer/external-editor@1.0.3(@types/node@24.13.0)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 24.13.0 + '@inquirer/figures@1.0.15': {} '@inquirer/figures@2.0.5': {} @@ -11164,6 +11994,13 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 + '@inquirer/input@4.3.1(@types/node@24.13.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@24.13.0) + '@inquirer/type': 3.0.10(@types/node@24.13.0) + optionalDependencies: + '@types/node': 24.13.0 + '@inquirer/number@3.0.23(@types/node@20.19.41)': dependencies: '@inquirer/core': 10.3.2(@types/node@20.19.41) @@ -11171,6 +12008,13 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 + '@inquirer/number@3.0.23(@types/node@24.13.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@24.13.0) + '@inquirer/type': 3.0.10(@types/node@24.13.0) + optionalDependencies: + '@types/node': 24.13.0 + '@inquirer/password@4.0.23(@types/node@20.19.41)': dependencies: '@inquirer/ansi': 1.0.2 @@ -11179,6 +12023,14 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 + '@inquirer/password@4.0.23(@types/node@24.13.0)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@24.13.0) + '@inquirer/type': 3.0.10(@types/node@24.13.0) + optionalDependencies: + '@types/node': 24.13.0 + '@inquirer/prompts@7.10.1(@types/node@20.19.41)': dependencies: '@inquirer/checkbox': 4.3.2(@types/node@20.19.41) @@ -11194,6 +12046,21 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 + '@inquirer/prompts@7.10.1(@types/node@24.13.0)': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@24.13.0) + '@inquirer/confirm': 5.1.21(@types/node@24.13.0) + '@inquirer/editor': 4.2.23(@types/node@24.13.0) + '@inquirer/expand': 4.0.23(@types/node@24.13.0) + '@inquirer/input': 4.3.1(@types/node@24.13.0) + '@inquirer/number': 3.0.23(@types/node@24.13.0) + '@inquirer/password': 4.0.23(@types/node@24.13.0) + '@inquirer/rawlist': 4.1.11(@types/node@24.13.0) + '@inquirer/search': 3.2.2(@types/node@24.13.0) + '@inquirer/select': 4.4.2(@types/node@24.13.0) + optionalDependencies: + '@types/node': 24.13.0 + '@inquirer/prompts@7.3.2(@types/node@20.19.41)': dependencies: '@inquirer/checkbox': 4.3.2(@types/node@20.19.41) @@ -11209,6 +12076,21 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 + '@inquirer/prompts@7.3.2(@types/node@24.13.0)': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@24.13.0) + '@inquirer/confirm': 5.1.21(@types/node@24.13.0) + '@inquirer/editor': 4.2.23(@types/node@24.13.0) + '@inquirer/expand': 4.0.23(@types/node@24.13.0) + '@inquirer/input': 4.3.1(@types/node@24.13.0) + '@inquirer/number': 3.0.23(@types/node@24.13.0) + '@inquirer/password': 4.0.23(@types/node@24.13.0) + '@inquirer/rawlist': 4.1.11(@types/node@24.13.0) + '@inquirer/search': 3.2.2(@types/node@24.13.0) + '@inquirer/select': 4.4.2(@types/node@24.13.0) + optionalDependencies: + '@types/node': 24.13.0 + '@inquirer/rawlist@4.1.11(@types/node@20.19.41)': dependencies: '@inquirer/core': 10.3.2(@types/node@20.19.41) @@ -11217,6 +12099,14 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 + '@inquirer/rawlist@4.1.11(@types/node@24.13.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@24.13.0) + '@inquirer/type': 3.0.10(@types/node@24.13.0) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.13.0 + '@inquirer/search@3.2.2(@types/node@20.19.41)': dependencies: '@inquirer/core': 10.3.2(@types/node@20.19.41) @@ -11226,6 +12116,15 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 + '@inquirer/search@3.2.2(@types/node@24.13.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@24.13.0) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.13.0) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.13.0 + '@inquirer/select@4.4.2(@types/node@20.19.41)': dependencies: '@inquirer/ansi': 1.0.2 @@ -11236,13 +12135,27 @@ snapshots: optionalDependencies: '@types/node': 20.19.41 + '@inquirer/select@4.4.2(@types/node@24.13.0)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@24.13.0) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.13.0) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.13.0 + '@inquirer/type@3.0.10(@types/node@20.19.41)': optionalDependencies: '@types/node': 20.19.41 - '@inquirer/type@4.0.5(@types/node@20.19.41)': + '@inquirer/type@3.0.10(@types/node@24.13.0)': optionalDependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 + + '@inquirer/type@4.0.5(@types/node@24.13.0)': + optionalDependencies: + '@types/node': 24.13.0 '@internationalized/date@3.12.0': dependencies: @@ -11274,12 +12187,21 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 20.19.41 + '@types/node': 24.13.0 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 + '@jest/console@30.4.1': + dependencies: + '@jest/types': 30.4.1 + '@types/node': 24.13.0 + chalk: 4.1.2 + jest-message-util: 30.4.1 + jest-util: 30.4.1 + slash: 3.0.0 + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3))': dependencies: '@jest/console': 29.7.0 @@ -11287,14 +12209,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.41 + '@types/node': 24.13.0 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.41)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)) + jest-config: 29.7.0(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -11315,17 +12237,66 @@ snapshots: - supports-color - ts-node + '@jest/core@30.4.2(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3))': + dependencies: + '@jest/console': 30.4.1 + '@jest/pattern': 30.4.0 + '@jest/reporters': 30.4.1 + '@jest/test-result': 30.4.1 + '@jest/transform': 30.4.1 + '@jest/types': 30.4.1 + '@types/node': 24.13.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 4.4.0 + exit-x: 0.2.2 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-changed-files: 30.4.1 + jest-config: 30.4.2(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3)) + jest-haste-map: 30.4.1 + jest-message-util: 30.4.1 + jest-regex-util: 30.4.0 + jest-resolve: 30.4.1 + jest-resolve-dependencies: 30.4.2 + jest-runner: 30.4.2 + jest-runtime: 30.4.2 + jest-snapshot: 30.4.1 + jest-util: 30.4.1 + jest-validate: 30.4.1 + jest-watcher: 30.4.1 + pretty-format: 30.4.1 + slash: 3.0.0 + transitivePeerDependencies: + - babel-plugin-macros + - esbuild-register + - supports-color + - ts-node + + '@jest/diff-sequences@30.4.0': {} + '@jest/environment@29.7.0': dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.41 + '@types/node': 24.13.0 jest-mock: 29.7.0 + '@jest/environment@30.4.1': + dependencies: + '@jest/fake-timers': 30.4.1 + '@jest/types': 30.4.1 + '@types/node': 24.13.0 + jest-mock: 30.4.1 + '@jest/expect-utils@29.7.0': dependencies: jest-get-type: 29.6.3 + '@jest/expect-utils@30.4.1': + dependencies: + '@jest/get-type': 30.1.0 + '@jest/expect@29.7.0': dependencies: expect: 29.7.0 @@ -11333,15 +12304,33 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/expect@30.4.1': + dependencies: + expect: 30.4.1 + jest-snapshot: 30.4.1 + transitivePeerDependencies: + - supports-color + '@jest/fake-timers@29.7.0': dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.19.41 + '@types/node': 24.13.0 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 + '@jest/fake-timers@30.4.1': + dependencies: + '@jest/types': 30.4.1 + '@sinonjs/fake-timers': 15.4.0 + '@types/node': 24.13.0 + jest-message-util: 30.4.1 + jest-mock: 30.4.1 + jest-util: 30.4.1 + + '@jest/get-type@30.1.0': {} + '@jest/globals@29.7.0': dependencies: '@jest/environment': 29.7.0 @@ -11351,6 +12340,20 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/globals@30.4.1': + dependencies: + '@jest/environment': 30.4.1 + '@jest/expect': 30.4.1 + '@jest/types': 30.4.1 + jest-mock: 30.4.1 + transitivePeerDependencies: + - supports-color + + '@jest/pattern@30.4.0': + dependencies: + '@types/node': 24.13.0 + jest-regex-util: 30.4.0 + '@jest/reporters@29.7.0': dependencies: '@bcoe/v8-coverage': 0.2.3 @@ -11359,7 +12362,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.31 - '@types/node': 20.19.41 + '@types/node': 24.13.0 chalk: 4.1.2 collect-v8-coverage: 1.0.3 exit: 0.1.2 @@ -11380,16 +12383,61 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/reporters@30.4.1': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 30.4.1 + '@jest/test-result': 30.4.1 + '@jest/transform': 30.4.1 + '@jest/types': 30.4.1 + '@jridgewell/trace-mapping': 0.3.31 + '@types/node': 24.13.0 + chalk: 4.1.2 + collect-v8-coverage: 1.0.3 + exit-x: 0.2.2 + glob: 10.5.0 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.2.0 + jest-message-util: 30.4.1 + jest-util: 30.4.1 + jest-worker: 30.4.1 + slash: 3.0.0 + string-length: 4.0.2 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + '@jest/schemas@29.6.3': dependencies: '@sinclair/typebox': 0.27.10 + '@jest/schemas@30.4.1': + dependencies: + '@sinclair/typebox': 0.34.49 + + '@jest/snapshot-utils@30.4.1': + dependencies: + '@jest/types': 30.4.1 + chalk: 4.1.2 + graceful-fs: 4.2.11 + natural-compare: 1.4.0 + '@jest/source-map@29.6.3': dependencies: '@jridgewell/trace-mapping': 0.3.31 callsites: 3.1.0 graceful-fs: 4.2.11 + '@jest/source-map@30.0.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + callsites: 3.1.0 + graceful-fs: 4.2.11 + '@jest/test-result@29.7.0': dependencies: '@jest/console': 29.7.0 @@ -11397,6 +12445,13 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 collect-v8-coverage: 1.0.3 + '@jest/test-result@30.4.1': + dependencies: + '@jest/console': 30.4.1 + '@jest/types': 30.4.1 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.3 + '@jest/test-sequencer@29.7.0': dependencies: '@jest/test-result': 29.7.0 @@ -11404,6 +12459,13 @@ snapshots: jest-haste-map: 29.7.0 slash: 3.0.0 + '@jest/test-sequencer@30.4.1': + dependencies: + '@jest/test-result': 30.4.1 + graceful-fs: 4.2.11 + jest-haste-map: 30.4.1 + slash: 3.0.0 + '@jest/transform@29.7.0': dependencies: '@babel/core': 7.29.0 @@ -11424,12 +12486,41 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/transform@30.4.1': + dependencies: + '@babel/core': 7.29.0 + '@jest/types': 30.4.1 + '@jridgewell/trace-mapping': 0.3.31 + babel-plugin-istanbul: 7.0.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 30.4.1 + jest-regex-util: 30.4.0 + jest-util: 30.4.1 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 5.0.1 + transitivePeerDependencies: + - supports-color + '@jest/types@29.6.3': dependencies: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.19.41 + '@types/node': 24.13.0 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + + '@jest/types@30.4.1': + dependencies: + '@jest/pattern': 30.4.0 + '@jest/schemas': 30.4.1 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 24.13.0 '@types/yargs': 17.0.35 chalk: 4.1.2 @@ -11677,12 +12768,25 @@ snapshots: transitivePeerDependencies: - '@types/react' + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.2 + optional: true + '@nestjs/axios@4.0.1(@nestjs/common@11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.16.1)(rxjs@7.8.2)': dependencies: '@nestjs/common': 11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) axios: 1.16.1 rxjs: 7.8.2 + '@nestjs/axios@4.0.1(@nestjs/common@11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.17.0)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + axios: 1.17.0 + rxjs: 7.8.2 + '@nestjs/cli@11.0.21(@types/node@20.19.41)(prettier@3.8.3)': dependencies: '@angular-devkit/core': 19.2.24(chokidar@4.0.3) @@ -11719,6 +12823,42 @@ snapshots: - uglify-js - webpack-cli + '@nestjs/cli@11.0.21(@types/node@24.13.0)(prettier@3.8.3)': + dependencies: + '@angular-devkit/core': 19.2.24(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.24(chokidar@4.0.3) + '@angular-devkit/schematics-cli': 19.2.24(@types/node@24.13.0)(chokidar@4.0.3) + '@inquirer/prompts': 7.10.1(@types/node@24.13.0) + '@nestjs/schematics': 11.1.0(chokidar@4.0.3)(prettier@3.8.3)(typescript@5.9.3) + ansis: 4.2.0 + chokidar: 4.0.3 + cli-table3: 0.6.5 + commander: 4.1.1 + fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.106.0) + glob: 13.0.6 + node-emoji: 1.11.0 + ora: 5.4.1 + tsconfig-paths: 4.2.0 + tsconfig-paths-webpack-plugin: 4.2.0 + typescript: 5.9.3 + webpack: 5.106.0 + webpack-node-externals: 3.0.0 + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/css' + - '@swc/html' + - '@types/node' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - prettier + - uglify-js + - webpack-cli + '@nestjs/common@11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: file-type: 21.3.4 @@ -11966,6 +13106,8 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@pkgr/core@0.3.6': {} + '@popperjs/core@2.11.8': {} '@radix-ui/number@1.1.1': {} @@ -13139,6 +14281,8 @@ snapshots: '@sinclair/typebox@0.27.10': {} + '@sinclair/typebox@0.34.49': {} + '@sindresorhus/merge-streams@4.0.0': {} '@sinonjs/commons@3.0.1': @@ -13149,6 +14293,10 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 + '@sinonjs/fake-timers@15.4.0': + dependencies: + '@sinonjs/commons': 3.0.1 + '@socket.io/component-emitter@3.1.2': {} '@sqltools/formatter@1.2.5': {} @@ -13241,12 +14389,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.3.0 '@tailwindcss/oxide-win32-x64-msvc': 4.3.0 - '@tailwindcss/vite@4.3.0(vite@5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0))': + '@tailwindcss/vite@4.3.0(vite@5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0))': dependencies: '@tailwindcss/node': 4.3.0 '@tailwindcss/oxide': 4.3.0 tailwindcss: 4.3.0 - vite: 5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0) + vite: 5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0) '@tanstack/query-core@5.100.11': {} @@ -13716,6 +14864,11 @@ snapshots: '@turbo/windows-arm64@2.9.14': optional: true + '@tybys/wasm-util@0.10.2': + dependencies: + tslib: 2.8.1 + optional: true + '@types/amqplib@0.10.8': dependencies: '@types/node': 20.19.41 @@ -13744,15 +14897,15 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 20.19.41 + '@types/node': 24.13.0 '@types/connect@3.4.38': dependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 '@types/conventional-commits-parser@5.0.2': dependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 '@types/cookiejar@2.1.5': {} @@ -13796,7 +14949,7 @@ snapshots: '@types/express-serve-static-core@5.1.1': dependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 '@types/qs': 6.15.1 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -13809,7 +14962,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 '@types/hoist-non-react-statics@3.3.7(@types/react@18.3.29)': dependencies: @@ -13833,6 +14986,11 @@ snapshots: expect: 29.7.0 pretty-format: 29.7.0 + '@types/jest@30.0.0': + dependencies: + expect: 30.4.1 + pretty-format: 30.4.1 + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} @@ -13840,7 +14998,7 @@ snapshots: '@types/jsonwebtoken@9.0.10': dependencies: '@types/ms': 2.1.0 - '@types/node': 20.19.41 + '@types/node': 24.13.0 '@types/methods@1.1.4': {} @@ -13856,6 +15014,10 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/node@24.13.0': + dependencies: + undici-types: 7.18.2 + '@types/pako@2.0.4': {} '@types/parse-json@4.0.2': {} @@ -13884,16 +15046,16 @@ snapshots: '@types/send@1.2.1': dependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 20.19.41 + '@types/node': 24.13.0 '@types/set-cookie-parser@2.4.10': dependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 '@types/signature_pad@2.3.6': {} @@ -13905,7 +15067,7 @@ snapshots: dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 - '@types/node': 20.19.41 + '@types/node': 24.13.0 form-data: 4.0.5 '@types/supertest@6.0.3': @@ -13913,6 +15075,11 @@ snapshots: '@types/methods': 1.1.4 '@types/superagent': 8.1.10 + '@types/supertest@7.2.0': + dependencies: + '@types/methods': 1.1.4 + '@types/superagent': 8.1.10 + '@types/trusted-types@2.0.7': optional: true @@ -13944,6 +15111,22 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/eslint-plugin@8.60.1(@typescript-eslint/parser@8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.60.1 + '@typescript-eslint/type-utils': 8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/utils': 8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.60.1 + eslint: 9.39.4(jiti@2.7.0) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.59.4 @@ -13956,6 +15139,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.60.1 + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/typescript-estree': 8.60.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.60.1 + debug: 4.4.3 + eslint: 9.39.4(jiti@2.7.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/project-service@8.59.4(typescript@5.9.3)': dependencies: '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@5.9.3) @@ -13965,15 +15160,33 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/project-service@8.60.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.60.1(typescript@5.9.3) + '@typescript-eslint/types': 8.60.1 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/scope-manager@8.59.4': dependencies: '@typescript-eslint/types': 8.59.4 '@typescript-eslint/visitor-keys': 8.59.4 + '@typescript-eslint/scope-manager@8.60.1': + dependencies: + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/visitor-keys': 8.60.1 + '@typescript-eslint/tsconfig-utils@8.59.4(typescript@5.9.3)': dependencies: typescript: 5.9.3 + '@typescript-eslint/tsconfig-utils@8.60.1(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + '@typescript-eslint/type-utils@8.59.4(eslint@8.57.1)(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.59.4 @@ -13986,8 +15199,22 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/type-utils@8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/typescript-estree': 8.60.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.4(jiti@2.7.0) + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/types@8.59.4': {} + '@typescript-eslint/types@8.60.1': {} + '@typescript-eslint/typescript-estree@8.59.4(typescript@5.9.3)': dependencies: '@typescript-eslint/project-service': 8.59.4(typescript@5.9.3) @@ -14003,6 +15230,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@8.60.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.60.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.60.1(typescript@5.9.3) + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/visitor-keys': 8.60.1 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.8.1 + tinyglobby: 0.2.16 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@8.59.4(eslint@8.57.1)(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) @@ -14014,14 +15256,100 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) + '@typescript-eslint/scope-manager': 8.60.1 + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/typescript-estree': 8.60.1(typescript@5.9.3) + eslint: 9.39.4(jiti@2.7.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/visitor-keys@8.59.4': dependencies: '@typescript-eslint/types': 8.59.4 eslint-visitor-keys: 5.0.1 + '@typescript-eslint/visitor-keys@8.60.1': + dependencies: + '@typescript-eslint/types': 8.60.1 + eslint-visitor-keys: 5.0.1 + '@ungap/structured-clone@1.3.1': {} - '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0))': + '@unrs/resolver-binding-android-arm-eabi@1.12.2': + optional: true + + '@unrs/resolver-binding-android-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.12.2': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-loong64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-openharmony-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.12.2': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.12.2': + optional: true + + '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) @@ -14029,7 +15357,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0) + vite: 5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0) transitivePeerDependencies: - supports-color @@ -14040,14 +15368,14 @@ snapshots: chai: 5.3.3 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.9(msw@2.14.6(@types/node@20.19.41)(typescript@5.9.3))(vite@5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0))': + '@vitest/mocker@2.1.9(msw@2.14.6(@types/node@24.13.0)(typescript@5.9.3))(vite@5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0))': dependencies: '@vitest/spy': 2.1.9 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - msw: 2.14.6(@types/node@20.19.41)(typescript@5.9.3) - vite: 5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0) + msw: 2.14.6(@types/node@24.13.0)(typescript@5.9.3) + vite: 5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0) '@vitest/pretty-format@2.1.9': dependencies: @@ -15186,6 +16514,16 @@ snapshots: - debug - supports-color + axios@1.17.0: + dependencies: + follow-redirects: 1.16.0 + form-data: 4.0.5 + https-proxy-agent: 5.0.1 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + - supports-color + babel-jest@29.7.0(@babel/core@7.29.0): dependencies: '@babel/core': 7.29.0 @@ -15199,6 +16537,19 @@ snapshots: transitivePeerDependencies: - supports-color + babel-jest@30.4.1(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@jest/transform': 30.4.1 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 7.0.1 + babel-preset-jest: 30.4.0(@babel/core@7.29.0) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + babel-plugin-istanbul@6.1.1: dependencies: '@babel/helper-plugin-utils': 7.28.6 @@ -15209,6 +16560,16 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-istanbul@7.0.1: + dependencies: + '@babel/helper-plugin-utils': 7.28.6 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.6 + istanbul-lib-instrument: 6.0.3 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + babel-plugin-jest-hoist@29.6.3: dependencies: '@babel/template': 7.28.6 @@ -15216,6 +16577,10 @@ snapshots: '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.28.0 + babel-plugin-jest-hoist@30.4.0: + dependencies: + '@types/babel__core': 7.20.5 + babel-plugin-macros@3.1.0: dependencies: '@babel/runtime': 7.29.2 @@ -15247,6 +16612,12 @@ snapshots: babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + babel-preset-jest@30.4.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + babel-plugin-jest-hoist: 30.4.0 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + balanced-match@1.0.2: {} balanced-match@4.0.4: {} @@ -15518,8 +16889,12 @@ snapshots: ci-info@3.9.0: {} + ci-info@4.4.0: {} + cjs-module-lexer@1.4.3: {} + cjs-module-lexer@2.2.0: {} + class-transformer@0.5.1: {} class-utils@0.3.6: @@ -15724,9 +17099,9 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig-typescript-loader@6.3.0(@types/node@20.19.41)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3): + cosmiconfig-typescript-loader@6.3.0(@types/node@24.13.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3): dependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 cosmiconfig: 9.0.1(typescript@5.9.3) jiti: 2.6.1 typescript: 5.9.3 @@ -16307,6 +17682,10 @@ snapshots: escape-string-regexp@4.0.0: {} + eslint-config-prettier@10.1.8(eslint@9.39.4(jiti@2.7.0)): + dependencies: + eslint: 9.39.4(jiti@2.7.0) + eslint-config-prettier@9.1.2(eslint@8.57.1): dependencies: eslint: 8.57.1 @@ -16358,6 +17737,16 @@ snapshots: - eslint-import-resolver-webpack - supports-color + eslint-plugin-prettier@5.5.6(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.4(jiti@2.7.0)))(eslint@9.39.4(jiti@2.7.0))(prettier@3.8.3): + dependencies: + eslint: 9.39.4(jiti@2.7.0) + prettier: 3.8.3 + prettier-linter-helpers: 1.0.1 + synckit: 0.11.13 + optionalDependencies: + '@types/eslint': 9.6.1 + eslint-config-prettier: 10.1.8(eslint@9.39.4(jiti@2.7.0)) + eslint-plugin-react-hooks@4.6.2(eslint@8.57.1): dependencies: eslint: 8.57.1 @@ -16398,8 +17787,15 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-visitor-keys@3.4.3: {} + eslint-visitor-keys@4.2.1: {} + eslint-visitor-keys@5.0.1: {} eslint@8.57.1: @@ -16445,6 +17841,53 @@ snapshots: transitivePeerDependencies: - supports-color + eslint@9.39.4(jiti@2.7.0): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.7.0 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + espree@9.6.1: dependencies: acorn: 8.16.0 @@ -16542,6 +17985,8 @@ snapshots: strip-final-newline: 4.0.0 yoctocolors: 2.1.2 + exit-x@0.2.2: {} + exit@0.1.2: {} expand-brackets@2.1.4: @@ -16566,6 +18011,15 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 + expect@30.4.1: + dependencies: + '@jest/expect-utils': 30.4.1 + '@jest/get-type': 30.1.0 + jest-matcher-utils: 30.4.1 + jest-message-util: 30.4.1 + jest-mock: 30.4.1 + jest-util: 30.4.1 + express-rate-limit@8.5.2(express@5.2.1): dependencies: express: 5.2.1 @@ -16637,6 +18091,8 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-diff@1.3.0: {} + fast-equals@5.4.0: {} fast-glob@3.3.3: @@ -16702,6 +18158,10 @@ snapshots: dependencies: flat-cache: 3.2.0 + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + file-selector@2.1.2: dependencies: tslib: 2.8.1 @@ -16769,6 +18229,11 @@ snapshots: keyv: 4.5.4 rimraf: 3.0.2 + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + flat@5.0.2: {} flatted@3.4.2: {} @@ -17024,6 +18489,10 @@ snapshots: dependencies: type-fest: 0.20.2 + globals@14.0.0: {} + + globals@17.6.0: {} + globalthis@1.0.4: dependencies: define-properties: 1.2.1 @@ -17606,6 +19075,14 @@ snapshots: transitivePeerDependencies: - supports-color + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + debug: 4.4.3 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + istanbul-reports@3.2.0: dependencies: html-escaper: 2.0.2 @@ -17638,13 +19115,19 @@ snapshots: jest-util: 29.7.0 p-limit: 3.1.0 + jest-changed-files@30.4.1: + dependencies: + execa: 5.1.1 + jest-util: 30.4.1 + p-limit: 3.1.0 + jest-circus@29.7.0(babel-plugin-macros@3.1.0): dependencies: '@jest/environment': 29.7.0 '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.41 + '@types/node': 24.13.0 chalk: 4.1.2 co: 4.6.0 dedent: 1.7.2(babel-plugin-macros@3.1.0) @@ -17664,6 +19147,32 @@ snapshots: - babel-plugin-macros - supports-color + jest-circus@30.4.2(babel-plugin-macros@3.1.0): + dependencies: + '@jest/environment': 30.4.1 + '@jest/expect': 30.4.1 + '@jest/test-result': 30.4.1 + '@jest/types': 30.4.1 + '@types/node': 24.13.0 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.7.2(babel-plugin-macros@3.1.0) + is-generator-fn: 2.1.0 + jest-each: 30.4.1 + jest-matcher-utils: 30.4.1 + jest-message-util: 30.4.1 + jest-runtime: 30.4.2 + jest-snapshot: 30.4.1 + jest-util: 30.4.1 + p-limit: 3.1.0 + pretty-format: 30.4.1 + pure-rand: 7.0.1 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-cli@29.7.0(@types/node@20.19.41)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)): dependencies: '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)) @@ -17683,6 +19192,25 @@ snapshots: - supports-color - ts-node + jest-cli@30.4.2(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3)): + dependencies: + '@jest/core': 30.4.2(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3)) + '@jest/test-result': 30.4.1 + '@jest/types': 30.4.1 + chalk: 4.1.2 + exit-x: 0.2.2 + import-local: 3.2.0 + jest-config: 30.4.2(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3)) + jest-util: 30.4.1 + jest-validate: 30.4.1 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - esbuild-register + - supports-color + - ts-node + jest-config@29.7.0(@types/node@20.19.41)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)): dependencies: '@babel/core': 7.29.0 @@ -17714,6 +19242,69 @@ snapshots: - babel-plugin-macros - supports-color + jest-config@29.7.0(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)): + dependencies: + '@babel/core': 7.29.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.29.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0(babel-plugin-macros@3.1.0) + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 24.13.0 + ts-node: 10.9.2(@types/node@20.19.41)(typescript@5.9.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-config@30.4.2(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3)): + dependencies: + '@babel/core': 7.29.0 + '@jest/get-type': 30.1.0 + '@jest/pattern': 30.4.0 + '@jest/test-sequencer': 30.4.1 + '@jest/types': 30.4.1 + babel-jest: 30.4.1(@babel/core@7.29.0) + chalk: 4.1.2 + ci-info: 4.4.0 + deepmerge: 4.3.1 + glob: 10.5.0 + graceful-fs: 4.2.11 + jest-circus: 30.4.2(babel-plugin-macros@3.1.0) + jest-docblock: 30.4.0 + jest-environment-node: 30.4.1 + jest-regex-util: 30.4.0 + jest-resolve: 30.4.1 + jest-runner: 30.4.2 + jest-util: 30.4.1 + jest-validate: 30.4.1 + parse-json: 5.2.0 + pretty-format: 30.4.1 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 24.13.0 + ts-node: 10.9.2(@types/node@24.13.0)(typescript@5.9.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-diff@29.7.0: dependencies: chalk: 4.1.2 @@ -17721,10 +19312,21 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 + jest-diff@30.4.1: + dependencies: + '@jest/diff-sequences': 30.4.0 + '@jest/get-type': 30.1.0 + chalk: 4.1.2 + pretty-format: 30.4.1 + jest-docblock@29.7.0: dependencies: detect-newline: 3.1.0 + jest-docblock@30.4.0: + dependencies: + detect-newline: 3.1.0 + jest-each@29.7.0: dependencies: '@jest/types': 29.6.3 @@ -17733,22 +19335,40 @@ snapshots: jest-util: 29.7.0 pretty-format: 29.7.0 + jest-each@30.4.1: + dependencies: + '@jest/get-type': 30.1.0 + '@jest/types': 30.4.1 + chalk: 4.1.2 + jest-util: 30.4.1 + pretty-format: 30.4.1 + jest-environment-node@29.7.0: dependencies: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.41 + '@types/node': 24.13.0 jest-mock: 29.7.0 jest-util: 29.7.0 + jest-environment-node@30.4.1: + dependencies: + '@jest/environment': 30.4.1 + '@jest/fake-timers': 30.4.1 + '@jest/types': 30.4.1 + '@types/node': 24.13.0 + jest-mock: 30.4.1 + jest-util: 30.4.1 + jest-validate: 30.4.1 + jest-get-type@29.6.3: {} jest-haste-map@29.7.0: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 20.19.41 + '@types/node': 24.13.0 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -17760,11 +19380,31 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + jest-haste-map@30.4.1: + dependencies: + '@jest/types': 30.4.1 + '@types/node': 24.13.0 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 30.4.0 + jest-util: 30.4.1 + jest-worker: 30.4.1 + picomatch: 4.0.4 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + jest-leak-detector@29.7.0: dependencies: jest-get-type: 29.6.3 pretty-format: 29.7.0 + jest-leak-detector@30.4.1: + dependencies: + '@jest/get-type': 30.1.0 + pretty-format: 30.4.1 + jest-matcher-utils@29.7.0: dependencies: chalk: 4.1.2 @@ -17772,6 +19412,13 @@ snapshots: jest-get-type: 29.6.3 pretty-format: 29.7.0 + jest-matcher-utils@30.4.1: + dependencies: + '@jest/get-type': 30.1.0 + chalk: 4.1.2 + jest-diff: 30.4.1 + pretty-format: 30.4.1 + jest-message-util@29.7.0: dependencies: '@babel/code-frame': 7.29.0 @@ -17784,18 +19431,43 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 + jest-message-util@30.4.1: + dependencies: + '@babel/code-frame': 7.29.0 + '@jest/types': 30.4.1 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-util: 30.4.1 + picomatch: 4.0.4 + pretty-format: 30.4.1 + slash: 3.0.0 + stack-utils: 2.0.6 + jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.19.41 + '@types/node': 24.13.0 jest-util: 29.7.0 + jest-mock@30.4.1: + dependencies: + '@jest/types': 30.4.1 + '@types/node': 24.13.0 + jest-util: 30.4.1 + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): optionalDependencies: jest-resolve: 29.7.0 + jest-pnp-resolver@1.2.3(jest-resolve@30.4.1): + optionalDependencies: + jest-resolve: 30.4.1 + jest-regex-util@29.6.3: {} + jest-regex-util@30.4.0: {} + jest-resolve-dependencies@29.7.0: dependencies: jest-regex-util: 29.6.3 @@ -17803,6 +19475,13 @@ snapshots: transitivePeerDependencies: - supports-color + jest-resolve-dependencies@30.4.2: + dependencies: + jest-regex-util: 30.4.0 + jest-snapshot: 30.4.1 + transitivePeerDependencies: + - supports-color + jest-resolve@29.7.0: dependencies: chalk: 4.1.2 @@ -17815,6 +19494,17 @@ snapshots: resolve.exports: 2.0.3 slash: 3.0.0 + jest-resolve@30.4.1: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 30.4.1 + jest-pnp-resolver: 1.2.3(jest-resolve@30.4.1) + jest-util: 30.4.1 + jest-validate: 30.4.1 + slash: 3.0.0 + unrs-resolver: 1.12.2 + jest-runner@29.7.0: dependencies: '@jest/console': 29.7.0 @@ -17822,7 +19512,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.41 + '@types/node': 24.13.0 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -17841,6 +19531,33 @@ snapshots: transitivePeerDependencies: - supports-color + jest-runner@30.4.2: + dependencies: + '@jest/console': 30.4.1 + '@jest/environment': 30.4.1 + '@jest/test-result': 30.4.1 + '@jest/transform': 30.4.1 + '@jest/types': 30.4.1 + '@types/node': 24.13.0 + chalk: 4.1.2 + emittery: 0.13.1 + exit-x: 0.2.2 + graceful-fs: 4.2.11 + jest-docblock: 30.4.0 + jest-environment-node: 30.4.1 + jest-haste-map: 30.4.1 + jest-leak-detector: 30.4.1 + jest-message-util: 30.4.1 + jest-resolve: 30.4.1 + jest-runtime: 30.4.2 + jest-util: 30.4.1 + jest-watcher: 30.4.1 + jest-worker: 30.4.1 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + jest-runtime@29.7.0: dependencies: '@jest/environment': 29.7.0 @@ -17850,7 +19567,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.41 + '@types/node': 24.13.0 chalk: 4.1.2 cjs-module-lexer: 1.4.3 collect-v8-coverage: 1.0.3 @@ -17868,6 +19585,33 @@ snapshots: transitivePeerDependencies: - supports-color + jest-runtime@30.4.2: + dependencies: + '@jest/environment': 30.4.1 + '@jest/fake-timers': 30.4.1 + '@jest/globals': 30.4.1 + '@jest/source-map': 30.0.1 + '@jest/test-result': 30.4.1 + '@jest/transform': 30.4.1 + '@jest/types': 30.4.1 + '@types/node': 24.13.0 + chalk: 4.1.2 + cjs-module-lexer: 2.2.0 + collect-v8-coverage: 1.0.3 + glob: 10.5.0 + graceful-fs: 4.2.11 + jest-haste-map: 30.4.1 + jest-message-util: 30.4.1 + jest-mock: 30.4.1 + jest-regex-util: 30.4.0 + jest-resolve: 30.4.1 + jest-snapshot: 30.4.1 + jest-util: 30.4.1 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + jest-snapshot@29.7.0: dependencies: '@babel/core': 7.29.0 @@ -17893,15 +19637,50 @@ snapshots: transitivePeerDependencies: - supports-color + jest-snapshot@30.4.1: + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 + '@jest/expect-utils': 30.4.1 + '@jest/get-type': 30.1.0 + '@jest/snapshot-utils': 30.4.1 + '@jest/transform': 30.4.1 + '@jest/types': 30.4.1 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + chalk: 4.1.2 + expect: 30.4.1 + graceful-fs: 4.2.11 + jest-diff: 30.4.1 + jest-matcher-utils: 30.4.1 + jest-message-util: 30.4.1 + jest-util: 30.4.1 + pretty-format: 30.4.1 + semver: 7.8.1 + synckit: 0.11.13 + transitivePeerDependencies: + - supports-color + jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.19.41 + '@types/node': 24.13.0 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 picomatch: 2.3.2 + jest-util@30.4.1: + dependencies: + '@jest/types': 30.4.1 + '@types/node': 24.13.0 + chalk: 4.1.2 + ci-info: 4.4.0 + graceful-fs: 4.2.11 + picomatch: 4.0.4 + jest-validate@29.7.0: dependencies: '@jest/types': 29.6.3 @@ -17911,30 +19690,58 @@ snapshots: leven: 3.1.0 pretty-format: 29.7.0 + jest-validate@30.4.1: + dependencies: + '@jest/get-type': 30.1.0 + '@jest/types': 30.4.1 + camelcase: 6.3.0 + chalk: 4.1.2 + leven: 3.1.0 + pretty-format: 30.4.1 + jest-watcher@29.7.0: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.41 + '@types/node': 24.13.0 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 jest-util: 29.7.0 string-length: 4.0.2 + jest-watcher@30.4.1: + dependencies: + '@jest/test-result': 30.4.1 + '@jest/types': 30.4.1 + '@types/node': 24.13.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 30.4.1 + string-length: 4.0.2 + jest-worker@27.5.1: dependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@29.7.0: dependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 + jest-worker@30.4.1: + dependencies: + '@types/node': 24.13.0 + '@ungap/structured-clone': 1.3.1 + jest-util: 30.4.1 + merge-stream: 2.0.0 + supports-color: 8.1.1 + jest@29.7.0(@types/node@20.19.41)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)): dependencies: '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)) @@ -17947,6 +19754,19 @@ snapshots: - supports-color - ts-node + jest@30.4.2(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3)): + dependencies: + '@jest/core': 30.4.2(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3)) + '@jest/types': 30.4.1 + import-local: 3.2.0 + jest-cli: 30.4.2(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - esbuild-register + - supports-color + - ts-node + jiti@1.21.7: {} jiti@2.6.1: {} @@ -18559,9 +20379,9 @@ snapshots: ms@2.1.3: {} - msw@2.14.6(@types/node@20.19.41)(typescript@5.9.3): + msw@2.14.6(@types/node@24.13.0)(typescript@5.9.3): dependencies: - '@inquirer/confirm': 6.0.13(@types/node@20.19.41) + '@inquirer/confirm': 6.0.13(@types/node@24.13.0) '@mswjs/interceptors': 0.41.9 '@open-draft/deferred-promise': 3.0.0 '@types/statuses': 2.0.6 @@ -18633,6 +20453,8 @@ snapshots: transitivePeerDependencies: - supports-color + napi-postinstall@0.3.4: {} + natural-compare@1.4.0: {} negotiator@1.0.0: {} @@ -19122,6 +20944,10 @@ snapshots: prelude-ls@1.2.1: {} + prettier-linter-helpers@1.0.1: + dependencies: + fast-diff: 1.3.0 + prettier@3.8.3: {} pretty-format@29.7.0: @@ -19130,6 +20956,13 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 + pretty-format@30.4.1: + dependencies: + '@jest/schemas': 30.4.1 + ansi-styles: 5.2.0 + react-is-18: react-is@18.3.1 + react-is-19: react-is@19.2.6 + pretty-ms@9.3.0: dependencies: parse-ms: 4.0.0 @@ -19239,6 +21072,8 @@ snapshots: pure-rand@6.1.0: {} + pure-rand@7.0.1: {} + qrcode@1.5.4: dependencies: dijkstrajs: 1.0.3 @@ -19961,7 +21796,7 @@ snapshots: safe-buffer: 5.2.1 to-buffer: 1.2.2 - shadcn@4.8.0(@types/node@20.19.41)(babel-plugin-macros@3.1.0)(typescript@5.9.3): + shadcn@4.8.0(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(typescript@5.9.3): dependencies: '@babel/core': 7.29.0 '@babel/parser': 7.29.3 @@ -19982,7 +21817,7 @@ snapshots: fuzzysort: 3.1.0 https-proxy-agent: 7.0.6 kleur: 4.1.5 - msw: 2.14.6(@types/node@20.19.41)(typescript@5.9.3) + msw: 2.14.6(@types/node@24.13.0)(typescript@5.9.3) node-fetch: 3.3.2 open: 11.0.0 ora: 8.2.0 @@ -20372,6 +22207,10 @@ snapshots: symbol-tree@3.2.4: {} + synckit@0.11.13: + dependencies: + '@pkgr/core': 0.3.6 + tabbable@6.4.0: {} tagged-tag@1.0.0: {} @@ -20616,7 +22455,7 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.4.11(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.41)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)))(typescript@5.9.3): + ts-jest@29.4.11(@babel/core@7.29.0)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.0))(jest-util@30.4.1)(jest@29.7.0(@types/node@20.19.41)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.41)(typescript@5.9.3)))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 @@ -20631,10 +22470,30 @@ snapshots: yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.29.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.29.0) - jest-util: 29.7.0 + '@jest/transform': 30.4.1 + '@jest/types': 30.4.1 + babel-jest: 30.4.1(@babel/core@7.29.0) + jest-util: 30.4.1 + + ts-jest@29.4.11(@babel/core@7.29.0)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.0))(jest-util@30.4.1)(jest@30.4.2(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3)))(typescript@5.9.3): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.9 + jest: 30.4.2(@types/node@24.13.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3)) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.8.1 + type-fest: 4.41.0 + typescript: 5.9.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.29.0 + '@jest/transform': 30.4.1 + '@jest/types': 30.4.1 + babel-jest: 30.4.1(@babel/core@7.29.0) + jest-util: 30.4.1 ts-loader@9.5.7(typescript@5.9.3)(webpack@5.106.0): dependencies: @@ -20669,6 +22528,24 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + ts-node@10.9.2(@types/node@24.13.0)(typescript@5.9.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.12 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 24.13.0 + acorn: 8.16.0 + acorn-walk: 8.3.5 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.4 + make-error: 1.3.6 + typescript: 5.9.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + tsconfig-paths-webpack-plugin@4.2.0: dependencies: chalk: 4.1.2 @@ -20805,6 +22682,17 @@ snapshots: - babel-plugin-macros - supports-color + typescript-eslint@8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.60.1(@typescript-eslint/parser@8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/parser': 8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.60.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.60.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.7.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + typescript@5.9.3: {} uglify-js@3.19.3: @@ -20825,6 +22713,8 @@ snapshots: undici-types@6.21.0: {} + undici-types@7.18.2: {} + unicode-properties@1.4.1: dependencies: base64-js: 1.5.1 @@ -20854,6 +22744,33 @@ snapshots: unpipe@1.0.0: {} + unrs-resolver@1.12.2: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.12.2 + '@unrs/resolver-binding-android-arm64': 1.12.2 + '@unrs/resolver-binding-darwin-arm64': 1.12.2 + '@unrs/resolver-binding-darwin-x64': 1.12.2 + '@unrs/resolver-binding-freebsd-x64': 1.12.2 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.12.2 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.12.2 + '@unrs/resolver-binding-linux-arm64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-arm64-musl': 1.12.2 + '@unrs/resolver-binding-linux-loong64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-loong64-musl': 1.12.2 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-riscv64-musl': 1.12.2 + '@unrs/resolver-binding-linux-s390x-gnu': 1.12.2 + '@unrs/resolver-binding-linux-x64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-x64-musl': 1.12.2 + '@unrs/resolver-binding-openharmony-arm64': 1.12.2 + '@unrs/resolver-binding-wasm32-wasi': 1.12.2 + '@unrs/resolver-binding-win32-arm64-msvc': 1.12.2 + '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2 + '@unrs/resolver-binding-win32-x64-msvc': 1.12.2 + unset-value@1.0.0: dependencies: has-value: 0.3.1 @@ -20994,13 +22911,13 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 - vite-node@2.1.9(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0): + vite-node@2.1.9(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 1.1.2 - vite: 5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0) + vite: 5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0) transitivePeerDependencies: - '@types/node' - less @@ -21012,21 +22929,21 @@ snapshots: - supports-color - terser - vite@5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0): + vite@5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0): dependencies: esbuild: 0.21.5 postcss: 8.5.15 rollup: 4.60.4 optionalDependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 fsevents: 2.3.3 lightningcss: 1.32.0 terser: 5.48.0 - vitest@2.1.9(@types/node@20.19.41)(jsdom@25.0.1(canvas@2.11.2))(lightningcss@1.32.0)(msw@2.14.6(@types/node@20.19.41)(typescript@5.9.3))(terser@5.48.0): + vitest@2.1.9(@types/node@24.13.0)(jsdom@25.0.1(canvas@2.11.2))(lightningcss@1.32.0)(msw@2.14.6(@types/node@24.13.0)(typescript@5.9.3))(terser@5.48.0): dependencies: '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(msw@2.14.6(@types/node@20.19.41)(typescript@5.9.3))(vite@5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0)) + '@vitest/mocker': 2.1.9(msw@2.14.6(@types/node@24.13.0)(typescript@5.9.3))(vite@5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0)) '@vitest/pretty-format': 2.1.9 '@vitest/runner': 2.1.9 '@vitest/snapshot': 2.1.9 @@ -21042,11 +22959,11 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.1.1 tinyrainbow: 1.2.0 - vite: 5.4.21(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0) - vite-node: 2.1.9(@types/node@20.19.41)(lightningcss@1.32.0)(terser@5.48.0) + vite: 5.4.21(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0) + vite-node: 2.1.9(@types/node@24.13.0)(lightningcss@1.32.0)(terser@5.48.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 20.19.41 + '@types/node': 24.13.0 jsdom: 25.0.1(canvas@2.11.2) transitivePeerDependencies: - less @@ -21261,6 +23178,11 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 + write-file-atomic@5.0.1: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + ws@8.20.1: {} wsl-utils@0.3.1: From 02018c339d049711c4c5ea30fcfef1eb00e7b16e Mon Sep 17 00:00:00 2001 From: Tria Date: Fri, 5 Jun 2026 12:57:44 +0300 Subject: [PATCH 4/4] payment --- .../edr-freight-api/src/modules/payment/payment.controller.ts | 3 +-- .../modules/payment/webhooks/providers/telebirr.service.ts | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/edr-freight-api/src/modules/payment/payment.controller.ts b/apps/edr-freight-api/src/modules/payment/payment.controller.ts index 9614d9517..8e9944c28 100644 --- a/apps/edr-freight-api/src/modules/payment/payment.controller.ts +++ b/apps/edr-freight-api/src/modules/payment/payment.controller.ts @@ -1,9 +1,8 @@ -import { Body, Controller, Get, NotFoundException, Param, ParseUUIDPipe, Post, Res } from "@nestjs/common"; +import { Controller, Get, NotFoundException, Param, ParseUUIDPipe, Post, Res } from "@nestjs/common"; import { PaymentService } from "./payment.service"; import { Public } from "@edr/api-common"; import { randomUUID } from "crypto"; import { Response } from "express" -import { UpdatePaymentStatusDto } from "./dto/update-payment-status.dto"; @Public() @Controller("payments") export class PaymentController { diff --git a/apps/edr-freight-api/src/modules/payment/webhooks/providers/telebirr.service.ts b/apps/edr-freight-api/src/modules/payment/webhooks/providers/telebirr.service.ts index cd734f81a..96b4c1f0d 100644 --- a/apps/edr-freight-api/src/modules/payment/webhooks/providers/telebirr.service.ts +++ b/apps/edr-freight-api/src/modules/payment/webhooks/providers/telebirr.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Logger } from '@nestjs/common'; +import { Injectable, } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import * as crypto from "crypto" import { TelebirrDto } from '../dto/telebirr.dto'; @@ -43,7 +43,7 @@ export class TelebirrWebhookService { } async handle(payload: TelebirrDto): Promise { - + console.log(payload) } } \ No newline at end of file