diff --git a/biome.json b/biome.json index 2c39dc01..109f2e3d 100644 --- a/biome.json +++ b/biome.json @@ -32,7 +32,8 @@ "noExplicitAny": "info" }, "style": { - "useImportType": "off" + "useImportType": "off", + "noNonNullAssertion": "info" } } }, diff --git a/modules/core/src/api/errors/error-mapper.ts b/modules/core/src/api/errors/error-mapper.ts index e585c8ac..9b7d8bfd 100644 --- a/modules/core/src/api/errors/error-mapper.ts +++ b/modules/core/src/api/errors/error-mapper.ts @@ -1,4 +1,10 @@ -import { ConnectionError, UniqueConstraintError } from "sequelize"; +import { + ConnectionError, + DatabaseError, + ForeignKeyConstraintError, + UniqueConstraintError, + ValidationError, +} from "sequelize"; import { ApiError } from "./api-error"; import { ConflictApiError } from "./conflict-api-error"; @@ -11,26 +17,50 @@ import { UnavailableApiError } from "./unavailable-api-error"; import { ValidationApiError } from "./validation-api-error"; import { ValidationErrorCollection } from "./validation-error-collection"; -/** - * Mapea errores de la aplicación a errores de la API. - * - * Esta función toma un error de la aplicación y lo convierte en un objeto ApiError - * adecuado para enviar como respuesta HTTP. Maneja errores comunes como validación, - * conflictos, no encontrados, autenticación y errores de infraestructura. - * - * @param error - El error de la aplicación a mapear. - * @returns Un objeto ApiError que representa el error mapeado. - * @example - * const error = new Error("Invalid input"); - * const apiError = errorMapper.toApiError(error); - * console.log(apiError); - * // Output: ValidationApiError { status: 422, title: 'Validation Failed', detail: 'Invalid input', type: 'https://httpstatuses.com/422' } - * @throws {ApiError} Si el error no puede ser mapeado a un tipo conocido. - * @see ApiError - * @see ValidationApiError - */ - export const errorMapper = { + toDomainError(error: unknown): Error { + if (error instanceof UniqueConstraintError) { + const field = error.errors[0]?.path || "unknown_field"; + return new Error(`A record with this ${field} already exists.`); + } + + if (error instanceof ForeignKeyConstraintError) { + return new Error("A referenced entity was not found or is invalid."); + } + + if (error instanceof ValidationError) { + return new Error(`Invalid data provided: ${error.message}`); + } + + if (error instanceof DatabaseError) { + return new Error("Database error occurred."); + } + + if (error instanceof Error) { + return error; // Fallback a error estándar + } + + return new Error("Unknown persistence error."); + }, + + /** + * Mapea errores de la aplicación a errores de la API. + * + * Esta función toma un error de la aplicación y lo convierte en un objeto ApiError + * adecuado para enviar como respuesta HTTP. Maneja errores comunes como validación, + * conflictos, no encontrados, autenticación y errores de infraestructura. + * + * @param error - El error de la aplicación a mapear. + * @returns Un objeto ApiError que representa el error mapeado. + * @example + * const error = new Error("Invalid input"); + * const apiError = errorMapper.toApiError(error); + * console.log(apiError); + * // Output: ValidationApiError { status: 422, title: 'Validation Failed', detail: 'Invalid input', type: 'https://httpstatuses.com/422' } + * @throws {ApiError} Si el error no puede ser mapeado a un tipo conocido. + * @see ApiError + * @see ValidationApiError + */ toApiError: (error: Error): ApiError => { const message = error.message || "An unexpected error occurred"; diff --git a/modules/customer-invoices/src/api/application/create-customer-invoice/create-customer-invoice.use-case.ts b/modules/customer-invoices/src/api/application/create-customer-invoice/create-customer-invoice.use-case.ts index cdf07a76..ecc125e9 100644 --- a/modules/customer-invoices/src/api/application/create-customer-invoice/create-customer-invoice.use-case.ts +++ b/modules/customer-invoices/src/api/application/create-customer-invoice/create-customer-invoice.use-case.ts @@ -1,149 +1,41 @@ import { ITransactionManager } from "@erp/core/api"; -import { UniqueID } from "@repo/rdx-ddd"; +import { CreateCustomerInvoiceCommandDTO } from "@erp/customer-invoices/common/dto"; +import { Result } from "@repo/rdx-utils"; import { Transaction } from "sequelize"; -import { ICreateCustomerInvoiceRequestDTO } from "../../common/dto"; -import { ICustomerInvoiceProps, ICustomerInvoiceService } from "../domain"; +import { ICustomerInvoiceService } from "../../domain"; +import { mapDTOToCustomerInvoiceProps } from "../helpers"; +import { CreateCustomerInvoicesPresenter } from "./presenter"; export class CreateCustomerInvoiceUseCase { constructor( private readonly customerInvoiceService: ICustomerInvoiceService, - private readonly transactionManager: ITransactionManager + private readonly transactionManager: ITransactionManager, + private readonly presenter: CreateCustomerInvoicesPresenter ) {} - public execute(customerInvoiceID: UniqueID, data: ICreateCustomerInvoiceRequestDTO) { + public execute(dto: CreateCustomerInvoiceCommandDTO) { + const invoicePropOrError = mapDTOToCustomerInvoiceProps(dto); + + if (invoicePropOrError.isFailure) { + return Result.fail(invoicePropOrError.error); + } + + const invoiceOrError = this.customerInvoiceService.build(invoicePropOrError.data); + + if (invoiceOrError.isFailure) { + return Result.fail(invoiceOrError.error); + } + + const newInvoice = invoiceOrError.data; + return this.transactionManager.complete(async (transaction: Transaction) => { - try { - /*const validOrErrors = this.validateCustomerInvoiceData(dto); - if (validOrErrors.isFailure) { - return Result.fail(validOrErrors.error); - } - - const data = validOrErrors.data;*/ - - const invoiceProps: ICustomerInvoiceProps = { - customerInvoiceNumber: data.customerInvoice_number, - customerInvoiceSeries: data.customerInvoice_series, - issueDate: data.issue_date, - operationDate: data.operation_date, - customerInvoiceCurrency: data.currency, - }; - - // Update customerInvoice with dto - return await this.customerInvoiceService.createCustomerInvoice( - customerInvoiceID, - invoiceProps, - transaction - ); - } catch (error: unknown) { - logger.error(error as Error); - return Result.fail(error as Error); + const result = await this.customerInvoiceService.save(newInvoice, transaction); + if (result.isFailure) { + return Result.fail(result.error); } + + const viewDTO = this.presenter.toDTO(newInvoice); + return Result.ok(viewDTO); }); } - - private validateCustomerInvoiceData( - dto: ICreateCustomerInvoiceRequestDTO - ): Result { - const errors: Error[] = []; - - const customerInvoiceNumerOrError = CustomerInvoiceNumber.create(dto.customerInvoice_number); - const customerInvoiceSeriesOrError = CustomerInvoiceSerie.create(dto.customerInvoice_series); - const issueDateOrError = UtcDate.create(dto.issue_date); - const operationDateOrError = UtcDate.create(dto.operation_date); - - const result = Result.combine([ - customerInvoiceNumerOrError, - customerInvoiceSeriesOrError, - issueDateOrError, - operationDateOrError, - ]); - - if (result.isFailure) { - return Result.fail(result.error); - } - - const validatedData: ICustomerInvoiceProps = { - status: CustomerInvoiceStatus.createDraft(), - customerInvoiceNumber: customerInvoiceNumerOrError.data, - customerInvoiceSeries: customerInvoiceSeriesOrError.data, - issueDate: issueDateOrError.data, - operationDate: operationDateOrError.data, - customerInvoiceCurrency: dto.currency, - }; - - /*if (errors.length > 0) { - const message = errors.map((err) => err.message).toString(); - return Result.fail(new Error(message)); - }*/ - return Result.ok(validatedData); - - /*let customerInvoice_status = CustomerInvoiceStatus.create(dto.status).object; - if (customerInvoice_status.isEmpty()) { - customerInvoice_status = CustomerInvoiceStatus.createDraft(); - } - - let customerInvoice_series = CustomerInvoiceSeries.create(dto.customerInvoice_series).object; - if (customerInvoice_series.isEmpty()) { - customerInvoice_series = CustomerInvoiceSeries.create(dto.customerInvoice_series).object; - } - - let issue_date = CustomerInvoiceDate.create(dto.issue_date).object; - if (issue_date.isEmpty()) { - issue_date = CustomerInvoiceDate.createCurrentDate().object; - } - - let operation_date = CustomerInvoiceDate.create(dto.operation_date).object; - if (operation_date.isEmpty()) { - operation_date = CustomerInvoiceDate.createCurrentDate().object; - } - - let customerInvoiceCurrency = Currency.createFromCode(dto.currency).object; - - if (customerInvoiceCurrency.isEmpty()) { - customerInvoiceCurrency = Currency.createDefaultCode().object; - } - - let customerInvoiceLanguage = Language.createFromCode(dto.language_code).object; - - if (customerInvoiceLanguage.isEmpty()) { - customerInvoiceLanguage = Language.createDefaultCode().object; - } - - const items = new Collection( - dto.items?.map( - (item) => - CustomerInvoiceSimpleItem.create({ - description: Description.create(item.description).object, - quantity: Quantity.create(item.quantity).object, - unitPrice: UnitPrice.create({ - amount: item.unit_price.amount, - currencyCode: item.unit_price.currency, - precision: item.unit_price.precision, - }).object, - }).object - ) - ); - - if (!customerInvoice_status.isDraft()) { - throw Error("Error al crear una factura que no es borrador"); - } - - return DraftCustomerInvoice.create( - { - customerInvoiceSeries: customerInvoice_series, - issueDate: issue_date, - operationDate: operation_date, - customerInvoiceCurrency, - language: customerInvoiceLanguage, - customerInvoiceNumber: CustomerInvoiceNumber.create(undefined).object, - //notes: Note.create(customerInvoiceDTO.notes).object, - - //senderId: UniqueID.create(null).object, - recipient, - - items, - }, - customerInvoiceId - );*/ - } } diff --git a/modules/customer-invoices/src/api/application/create-customer-invoice/index.ts b/modules/customer-invoices/src/api/application/create-customer-invoice/index.ts index e92f8281..5420fda5 100644 --- a/modules/customer-invoices/src/api/application/create-customer-invoice/index.ts +++ b/modules/customer-invoices/src/api/application/create-customer-invoice/index.ts @@ -1 +1,2 @@ export * from "./create-customer-invoice.use-case"; +export * from "./presenter"; diff --git a/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/create-customer-invoices.presenter.ts b/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/create-customer-invoices.presenter.ts new file mode 100644 index 00000000..8e1f881b --- /dev/null +++ b/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/create-customer-invoices.presenter.ts @@ -0,0 +1,27 @@ +import { CustomerInvoice } from "@erp/customer-invoices/api/domain"; +import { CustomerInvoicesCreationResultDTO } from "@erp/customer-invoices/common/dto"; + +export class CreateCustomerInvoicesPresenter { + public toDTO(invoice: CustomerInvoice): CustomerInvoicesCreationResultDTO { + return { + id: invoice.id.toPrimitive(), + + invoice_status: invoice.status.toString(), + invoice_number: invoice.invoiceNumber.toString(), + invoice_series: invoice.invoiceSeries.toString(), + issue_date: invoice.issueDate.toISOString(), + operation_date: invoice.operationDate.toISOString(), + language_code: "ES", + currency: "EUR", + + //subtotal_price: invoice.calculateSubtotal().toPrimitive(), + //total_price: invoice.calculateTotal().toPrimitive(), + + //recipient: CustomerInvoiceParticipantPresenter(customerInvoice.recipient), + + metadata: { + entity: "customer-invoice", + }, + }; + } +} diff --git a/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/index.ts b/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/index.ts new file mode 100644 index 00000000..2ff37706 --- /dev/null +++ b/modules/customer-invoices/src/api/application/create-customer-invoice/presenter/index.ts @@ -0,0 +1 @@ +export * from "./create-customer-invoices.presenter"; diff --git a/modules/customer-invoices/src/api/application/helpers/build-customer-invoice-from-dto.ts b/modules/customer-invoices/src/api/application/helpers/build-customer-invoice-from-dto.ts deleted file mode 100644 index ab73e6c5..00000000 --- a/modules/customer-invoices/src/api/application/helpers/build-customer-invoice-from-dto.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { ValidationErrorCollection, ValidationErrorDetail } from "@erp/core/api"; -import { UniqueID, UtcDate } from "@repo/rdx-ddd"; -import { Result } from "@repo/rdx-utils"; -import { CreateCustomerInvoiceCommandDTO } from "../../../common/dto"; -import { CustomerInvoiceNumber, CustomerInvoiceProps, CustomerInvoiceSerie } from "../../domain"; -import { buildInvoiceItemsFromDTO } from "./build-customer-invoice-items-from-dto"; -import { extractOrPushError } from "./extract-or-push-error"; - -export async function buildInvoiceFromDTO( - dto: CreateCustomerInvoiceCommandDTO -): Promise> { - const errors: ValidationErrorDetail[] = []; - - const invoiceNumber = extractOrPushError( - CustomerInvoiceNumber.create(dto.invoice_number), - "invoice_number", - errors - ); - const invoiceSeries = extractOrPushError( - CustomerInvoiceSerie.create(dto.invoice_series), - "invoice_series", - errors - ); - const issueDate = extractOrPushError(UtcDate.createFromISO(dto.issue_date), "issue_date", errors); - const operationDate = extractOrPushError( - UtcDate.createFromISO(dto.operation_date), - "operation_date", - errors - ); - - // 🔄 Validar y construir los items de factura con helper especializado - const itemsResult = await buildInvoiceItemsFromDTO(dto.items); - if (itemsResult.isFailure) { - return Result.fail(itemsResult.error); - } - - if (errors.length > 0) { - return Result.fail(new ValidationErrorCollection(errors)); - } - - return Result.ok({ - id: UniqueID.create(), - customerId: customerId.data, - invoiceNumber: invoiceNumber.data, - invoiceSeries: invoiceSeries.data, - issueDate: issueDate.data, - operationDate: operationDate.data, - subtotalPrice: subtotalPrice.data, - discount: discount.data, - tax: tax.data, - totalAmount: totalAmount.data, - lines: itemsResult.data, - }); -} diff --git a/modules/customer-invoices/src/api/application/helpers/has-no-undefined-fields.ts b/modules/customer-invoices/src/api/application/helpers/has-no-undefined-fields.ts index d6a2ff3f..beabd781 100644 --- a/modules/customer-invoices/src/api/application/helpers/has-no-undefined-fields.ts +++ b/modules/customer-invoices/src/api/application/helpers/has-no-undefined-fields.ts @@ -24,3 +24,27 @@ export function hasNoUndefinedFields>( ): obj is { [K in keyof T]-?: Exclude } { return Object.values(obj).every((value) => value !== undefined); } + +/** + * + * @description Verifica si un objeto tiene campos con valor undefined. + * Esta función es el complemento de `hasNoUndefinedFields`. + * + * @example + * const obj = { a: 1, b: 'test', c: null }; + * console.log(hasUndefinedFields(obj)); // false + * + * const objWithUndefined = { a: 1, b: undefined, c: null }; + * console.log(hasUndefinedFields(objWithUndefined)); // true + * + * @template T - El tipo del objeto. + * @param obj - El objeto a evaluar. + * @returns true si el objeto tiene al menos un campo undefined, false en caso contrario. + * + */ + +export function hasUndefinedFields>( + obj: T +): obj is { [K in keyof T]-?: Exclude } { + return !hasNoUndefinedFields(obj); +} diff --git a/modules/customer-invoices/src/api/application/helpers/index.ts b/modules/customer-invoices/src/api/application/helpers/index.ts index 711ba4b1..02b751c0 100644 --- a/modules/customer-invoices/src/api/application/helpers/index.ts +++ b/modules/customer-invoices/src/api/application/helpers/index.ts @@ -1 +1 @@ -export * from "./build-customer-invoice-from-dto"; +export * from "./map-dto-to-customer-invoice-props"; diff --git a/modules/customer-invoices/src/api/application/helpers/build-customer-invoice-items-from-dto.ts b/modules/customer-invoices/src/api/application/helpers/map-dto-to-customer-invoice-items-props.ts similarity index 97% rename from modules/customer-invoices/src/api/application/helpers/build-customer-invoice-items-from-dto.ts rename to modules/customer-invoices/src/api/application/helpers/map-dto-to-customer-invoice-items-props.ts index 8e087c4b..cee02cec 100644 --- a/modules/customer-invoices/src/api/application/helpers/build-customer-invoice-items-from-dto.ts +++ b/modules/customer-invoices/src/api/application/helpers/map-dto-to-customer-invoice-items-props.ts @@ -11,7 +11,7 @@ import { import { extractOrPushError } from "./extract-or-push-error"; import { hasNoUndefinedFields } from "./has-no-undefined-fields"; -export function buildInvoiceItemsFromDTO( +export function mapDTOToCustomerInvoiceItemsProps( dtoItems: Pick["items"] ): Result { const errors: ValidationErrorDetail[] = []; diff --git a/modules/customer-invoices/src/api/application/helpers/map-dto-to-customer-invoice-props.ts b/modules/customer-invoices/src/api/application/helpers/map-dto-to-customer-invoice-props.ts new file mode 100644 index 00000000..4625e5d0 --- /dev/null +++ b/modules/customer-invoices/src/api/application/helpers/map-dto-to-customer-invoice-props.ts @@ -0,0 +1,84 @@ +import { ValidationErrorCollection, ValidationErrorDetail } from "@erp/core/api"; +import { UtcDate } from "@repo/rdx-ddd"; +import { Result } from "@repo/rdx-utils"; +import { CreateCustomerInvoiceCommandDTO } from "../../../common/dto"; +import { + CustomerInvoiceNumber, + CustomerInvoiceProps, + CustomerInvoiceSerie, + CustomerInvoiceStatus, +} from "../../domain"; +import { extractOrPushError } from "./extract-or-push-error"; +import { mapDTOToCustomerInvoiceItemsProps } from "./map-dto-to-customer-invoice-items-props"; + +/** + * Convierte el DTO a las props validadas (CustomerInvoiceProps). + * No construye directamente el agregado. + * + * @param dto - DTO con los datos de la factura de cliente + * @returns CustomerInvoiceProps - Las propiedades para crear una factura de cliente o error + * + */ + +export function mapDTOToCustomerInvoiceProps( + dto: CreateCustomerInvoiceCommandDTO +): Result { + const errors: ValidationErrorDetail[] = []; + + //const invoiceId = extractOrPushError(UniqueID.create(dto.id), "invoice_id", errors); + + const invoiceNumber = extractOrPushError( + CustomerInvoiceNumber.create(dto.invoice_number), + "invoice_number", + errors + ); + const invoiceSeries = extractOrPushError( + CustomerInvoiceSerie.create(dto.invoice_series), + "invoice_series", + errors + ); + const issueDate = extractOrPushError(UtcDate.createFromISO(dto.issue_date), "issue_date", errors); + const operationDate = extractOrPushError( + UtcDate.createFromISO(dto.operation_date), + "operation_date", + errors + ); + + //const currency = extractOrPushError(Currency.(dto.currency), "currency", errors); + const currency = dto.currency; + + // 🔄 Validar y construir los items de factura con helper especializado + const itemsResult = mapDTOToCustomerInvoiceItemsProps(dto.items); + if (itemsResult.isFailure) { + return Result.fail(itemsResult.error); + } + + if (errors.length > 0) { + return Result.fail(new ValidationErrorCollection(errors)); + } + + const invoiceProps: CustomerInvoiceProps = { + invoiceNumber: invoiceNumber!, + invoiceSeries: invoiceSeries!, + issueDate: issueDate!, + operationDate: operationDate!, + status: CustomerInvoiceStatus.createDraft(), + currency, + }; + + return Result.ok(invoiceProps); + + /*if (hasNoUndefinedFields(invoiceProps)) { + const invoiceOrError = CustomerInvoice.create(invoiceProps, invoiceId); + if (invoiceOrError.isFailure) { + return Result.fail(invoiceOrError.error); + } + return Result.ok(invoiceOrError.data); + } + + return Result.fail( + new ValidationErrorCollection([ + { path: "", message: "Error building from DTO: Some fields are undefined" }, + ]) + );*/ +} diff --git a/modules/customer-invoices/src/api/application/index.ts b/modules/customer-invoices/src/api/application/index.ts index 7401f0ba..cbb37010 100644 --- a/modules/customer-invoices/src/api/application/index.ts +++ b/modules/customer-invoices/src/api/application/index.ts @@ -1,4 +1,4 @@ -//export * from "./create-customer-invoice"; +export * from "./create-customer-invoice"; //export * from "./delete-customer-invoice"; //export * from "./get-customer-invoice"; export * from "./list-customer-invoices"; diff --git a/modules/customer-invoices/src/api/application/list-customer-invoices/presenter/list-invoices.presenter.ts b/modules/customer-invoices/src/api/application/list-customer-invoices/presenter/list-invoices.presenter.ts index b28048f1..82f1660b 100644 --- a/modules/customer-invoices/src/api/application/list-customer-invoices/presenter/list-invoices.presenter.ts +++ b/modules/customer-invoices/src/api/application/list-customer-invoices/presenter/list-invoices.presenter.ts @@ -20,8 +20,8 @@ export const listCustomerInvoicesPresenter: ListCustomerInvoicesPresenter = { id: invoice.id.toPrimitive(), invoice_status: invoice.status.toString(), - invoice_number: invoice.customerInvoiceNumber.toString(), - invoice_series: invoice.customerInvoiceSeries.toString(), + invoice_number: invoice.invoiceNumber.toString(), + invoice_series: invoice.invoiceSeries.toString(), issue_date: invoice.issueDate.toISOString(), operation_date: invoice.operationDate.toISOString(), language_code: "ES", diff --git a/modules/customer-invoices/src/api/controllers/create-customer-invoice/create-customer-invoice.ts b/modules/customer-invoices/src/api/controllers/create-customer-invoice/create-customer-invoice.ts index 242fd04c..a233afc9 100644 --- a/modules/customer-invoices/src/api/controllers/create-customer-invoice/create-customer-invoice.ts +++ b/modules/customer-invoices/src/api/controllers/create-customer-invoice/create-customer-invoice.ts @@ -3,8 +3,7 @@ import { CreateCustomerInvoiceCommandDTO } from "../../../common/dto"; export class CreateCustomerInvoiceController extends ExpressController { public constructor( - private readonly createCustomerInvoice: any, // Replace with actual type - private readonly presenter: any // Replace with actual type + private readonly createCustomerInvoice: any // Replace with actual type ) { super(); } @@ -26,14 +25,10 @@ export class CreateCustomerInvoiceController extends ExpressController { const result = await this.createCustomerInvoice.execute(dto); if (result.isFailure) { - /*if (error instanceof AggregatedValidationError) { - return this.invalidInputError(error.message, error.details); - }*/ - const apiError = errorMapper.toApiError(result.error); return this.handleApiError(apiError); } - return this.created(this.presenter.toDTO(result.data)); + return this.created(result.data); } } diff --git a/modules/customer-invoices/src/api/controllers/create-customer-invoice/index.ts b/modules/customer-invoices/src/api/controllers/create-customer-invoice/index.ts index aba6da9a..413e267c 100644 --- a/modules/customer-invoices/src/api/controllers/create-customer-invoice/index.ts +++ b/modules/customer-invoices/src/api/controllers/create-customer-invoice/index.ts @@ -1 +1,21 @@ -export * from "./create-customer-invoice"; +import { SequelizeTransactionManager } from "@erp/core/api"; +import { Sequelize } from "sequelize"; +import { CreateCustomerInvoiceUseCase, CreateCustomerInvoicesPresenter } from "../../application/"; +import { CustomerInvoiceService } from "../../domain"; +import { CustomerInvoiceRepository, customerInvoiceMapper } from "../../infrastructure"; +import { CreateCustomerInvoiceController } from "./create-customer-invoice"; + +export const buildCreateCustomerInvoicesController = (database: Sequelize) => { + const transactionManager = new SequelizeTransactionManager(database); + const customerInvoiceRepository = new CustomerInvoiceRepository(database, customerInvoiceMapper); + const customerInvoiceService = new CustomerInvoiceService(customerInvoiceRepository); + const presenter = new CreateCustomerInvoicesPresenter(); + + const useCase = new CreateCustomerInvoiceUseCase( + customerInvoiceService, + transactionManager, + presenter + ); + + return new CreateCustomerInvoiceController(useCase); +}; diff --git a/modules/customer-invoices/src/api/controllers/get-customer-invoice/presenter/get-invoice.presenter.ts b/modules/customer-invoices/src/api/controllers/get-customer-invoice/presenter/get-invoice.presenter.ts index 579ea79a..de9b53eb 100644 --- a/modules/customer-invoices/src/api/controllers/get-customer-invoice/presenter/get-invoice.presenter.ts +++ b/modules/customer-invoices/src/api/controllers/get-customer-invoice/presenter/get-invoice.presenter.ts @@ -10,8 +10,8 @@ export const getCustomerInvoicePresenter: IGetCustomerInvoicePresenter = { id: customerInvoice.id.toPrimitive(), customerInvoice_status: customerInvoice.status.toString(), - customerInvoice_number: customerInvoice.customerInvoiceNumber.toString(), - customerInvoice_series: customerInvoice.customerInvoiceSeries.toString(), + customerInvoice_number: customerInvoice.invoiceNumber.toString(), + customerInvoice_series: customerInvoice.invoiceSeries.toString(), issue_date: customerInvoice.issueDate.toDateString(), operation_date: customerInvoice.operationDate.toDateString(), language_code: "ES", diff --git a/modules/customer-invoices/src/api/controllers/list-customer-invoices/list-customer-invoices.controller.ts b/modules/customer-invoices/src/api/controllers/list-customer-invoices/list-customer-invoices.controller.ts index 6c2f8715..daf9b7c0 100644 --- a/modules/customer-invoices/src/api/controllers/list-customer-invoices/list-customer-invoices.controller.ts +++ b/modules/customer-invoices/src/api/controllers/list-customer-invoices/list-customer-invoices.controller.ts @@ -24,10 +24,6 @@ export class ListCustomerInvoicesController extends ExpressController { const result = await this.listCustomerInvoices.execute(criteria); if (result.isFailure) { - /*if (error instanceof AggregatedValidationError) { - return this.invalidInputError(error.message, error.details); - }*/ - const apiError = errorMapper.toApiError(result.error); return this.handleApiError(apiError); } diff --git a/modules/customer-invoices/src/api/domain/aggregates/customer-invoice.ts b/modules/customer-invoices/src/api/domain/aggregates/customer-invoice.ts index 4b02e64e..c16164a0 100644 --- a/modules/customer-invoices/src/api/domain/aggregates/customer-invoice.ts +++ b/modules/customer-invoices/src/api/domain/aggregates/customer-invoice.ts @@ -8,8 +8,8 @@ import { } from "../value-objects"; export interface CustomerInvoiceProps { - customerInvoiceNumber: CustomerInvoiceNumber; - customerInvoiceSeries: CustomerInvoiceSerie; + invoiceNumber: CustomerInvoiceNumber; + invoiceSeries: CustomerInvoiceSerie; status: CustomerInvoiceStatus; @@ -19,7 +19,7 @@ export interface CustomerInvoiceProps { //dueDate: UtcDate; // ? --> depende de la forma de pago //tax: Tax; // ? --> detalles? - customerInvoiceCurrency: string; + currency: string; //language: Language; @@ -37,8 +37,8 @@ export interface CustomerInvoiceProps { export interface ICustomerInvoice { id: UniqueID; - customerInvoiceNumber: CustomerInvoiceNumber; - customerInvoiceSeries: CustomerInvoiceSerie; + invoiceNumber: CustomerInvoiceNumber; + invoiceSeries: CustomerInvoiceSerie; status: CustomerInvoiceStatus; @@ -53,7 +53,7 @@ export interface ICustomerInvoice { //tax: Tax; //language: Language; - customerInvoiceCurrency: string; + currency: string; //purchareOrderNumber: string; //notes: Note; @@ -77,7 +77,6 @@ export class CustomerInvoice protected constructor(props: CustomerInvoiceProps, id?: UniqueID) { super(props, id); - this._items = props.items || CustomerInvoiceItems.create(); } @@ -95,12 +94,12 @@ export class CustomerInvoice return Result.ok(customerInvoice); } - get customerInvoiceNumber() { - return this.props.customerInvoiceNumber; + get invoiceNumber() { + return this.props.invoiceNumber; } - get customerInvoiceSeries() { - return this.props.customerInvoiceSeries; + get invoiceSeries() { + return this.props.invoiceSeries; } get issueDate() { @@ -159,8 +158,8 @@ export class CustomerInvoice return this.props.shipTo; }*/ - get customerInvoiceCurrency() { - return this.props.customerInvoiceCurrency; + get currency() { + return this.props.currency; } /*get notes() { @@ -183,7 +182,7 @@ export class CustomerInvoice calculateSubtotal(): MoneyValue { const customerInvoiceSubtotal = MoneyValue.create({ amount: 0, - currency_code: this.props.customerInvoiceCurrency, + currency_code: this.props.currency, scale: 2, }).data; @@ -196,7 +195,7 @@ export class CustomerInvoice calculateTaxTotal(): MoneyValue { const taxTotal = MoneyValue.create({ amount: 0, - currency_code: this.props.customerInvoiceCurrency, + currency_code: this.props.currency, scale: 2, }).data; diff --git a/modules/customer-invoices/src/api/domain/repositories/customer-invoice-repository.interface.ts b/modules/customer-invoices/src/api/domain/repositories/customer-invoice-repository.interface.ts index 0f37d9cb..8b9e05af 100644 --- a/modules/customer-invoices/src/api/domain/repositories/customer-invoice-repository.interface.ts +++ b/modules/customer-invoices/src/api/domain/repositories/customer-invoice-repository.interface.ts @@ -4,13 +4,46 @@ import { Collection, Result } from "@repo/rdx-utils"; import { CustomerInvoice } from "../aggregates"; export interface ICustomerInvoiceRepository { - findAll( - criteria: Criteria, - transaction?: any - ): Promise, Error>>; - getById(id: UniqueID, transaction?: any): Promise>; - deleteById(id: UniqueID, transaction?: any): Promise>; + /** + * + * Persiste una nueva factura o actualiza una existente. + * + * @param invoice - El agregado a guardar. + * @param transaction - Transacción activa para la operación. + * @returns Result + */ + save(invoice: CustomerInvoice, transaction: any): Promise>; - create(customerInvoice: CustomerInvoice, transaction?: any): Promise; - update(customerInvoice: CustomerInvoice, transaction?: any): Promise; -} + /** + * + * Busca una factura por su identificador único. + * @param id - UUID de la factura. + * @param transaction - Transacción activa para la operación. + * @returns Result + */ + findById(id: UniqueID, transaction: any): Promise>; + + /** + * + * Consulta facturas usando un objeto Criteria (filtros, orden, paginación). + * @param criteria - Criterios de búsqueda. + * @param transaction - Transacción activa para la operación. + * @returns Result + * + * @see Criteria + */ + findByCriteria( + criteria: Criteria, + transaction: any + ): Promise, Error>>; + + /** + * + * Elimina o marca como eliminada una factura. + * @param id - UUID de la factura a eliminar. + * @param transaction - Transacción activa para la operación. + * @returns Result + */ + deleteById(id: UniqueID, transaction: any): Promise>; + + \ No newline at end of file diff --git a/modules/customer-invoices/src/api/domain/services/customer-invoice-service.interface.ts b/modules/customer-invoices/src/api/domain/services/customer-invoice-service.interface.ts index 50f66775..e5c2639d 100644 --- a/modules/customer-invoices/src/api/domain/services/customer-invoice-service.interface.ts +++ b/modules/customer-invoices/src/api/domain/services/customer-invoice-service.interface.ts @@ -4,29 +4,28 @@ import { Collection, Result } from "@repo/rdx-utils"; import { CustomerInvoice, CustomerInvoiceProps } from "../aggregates"; export interface ICustomerInvoiceService { - findCustomerInvoices( + build(props: CustomerInvoiceProps): Result; + + save(invoice: CustomerInvoice, transaction: any): Promise>; + + findByCriteria( criteria: Criteria, transaction?: any ): Promise, Error>>; - findCustomerInvoiceById( - customerInvoiceId: UniqueID, - transaction?: any - ): Promise>; - updateCustomerInvoiceById( - customerInvoiceId: UniqueID, + getById(id: UniqueID, transaction?: any): Promise>; + + updateById( + id: UniqueID, data: Partial, transaction?: any ): Promise>; createCustomerInvoice( - customerInvoiceId: UniqueID, + id: UniqueID, data: CustomerInvoiceProps, transaction?: any ): Promise>; - deleteCustomerInvoiceById( - customerInvoiceId: UniqueID, - transaction?: any - ): Promise>; + deleteById(id: UniqueID, transaction?: any): Promise>; } diff --git a/modules/customer-invoices/src/api/domain/services/customer-invoice.service.ts b/modules/customer-invoices/src/api/domain/services/customer-invoice.service.ts index f9b1a42b..6f9a99cb 100644 --- a/modules/customer-invoices/src/api/domain/services/customer-invoice.service.ts +++ b/modules/customer-invoices/src/api/domain/services/customer-invoice.service.ts @@ -7,13 +7,42 @@ import { ICustomerInvoiceRepository } from "../repositories"; import { ICustomerInvoiceService } from "./customer-invoice-service.interface"; export class CustomerInvoiceService implements ICustomerInvoiceService { - constructor(private readonly repo: ICustomerInvoiceRepository) {} + constructor(private readonly repository: ICustomerInvoiceRepository) {} - async findCustomerInvoices( + /** + * Construye un nuevo agregado CustomerInvoice a partir de props validadas. + * + * @param props - Las propiedades ya validadas para crear la factura. + * @returns Result - El agregado construido o un error si falla la creación. + */ + build(props: CustomerInvoiceProps): Result { + return CustomerInvoice.create(props); + } + + /** + * Guarda una instancia de CustomerInvoice en persistencia. + * + * @param invoice - El agregado a guardar. + * @param transaction - Transacción activa para la operación. + * @returns Result - El agregado guardado o un error si falla la operación. + */ + async save(invoice: CustomerInvoice, transaction: any): Promise> { + const saved = await this.repository.save(invoice, transaction); + return saved.isSuccess ? Result.ok(invoice) : Result.fail(saved.error); + } + + /** + * Obtiene una colección de facturas que cumplen con los filtros definidos en un objeto Criteria. + * + * @param criteria - Objeto con condiciones de filtro, paginación y orden. + * @param transaction - Transacción activa para la operación. + * @returns Result, Error> - Colección de facturas o error. + */ + async findByCriteria( criteria: Criteria, transaction?: Transaction ): Promise, Error>> { - const customerInvoicesOrError = await this.repo.findAll(criteria, transaction); + const customerInvoicesOrError = await this.repository.findAll(criteria, transaction); if (customerInvoicesOrError.isFailure) { return Result.fail(customerInvoicesOrError.error); } @@ -25,20 +54,32 @@ export class CustomerInvoiceService implements ICustomerInvoiceService { return customerInvoicesOrError; } - async findCustomerInvoiceById( - customerInvoiceId: UniqueID, - transaction?: Transaction - ): Promise> { - return await this.repo.getById(customerInvoiceId, transaction); + /** + * Recupera una factura por su identificador único. + * + * @param id - Identificador UUID de la factura. + * @param transaction - Transacción activa para la operación. + * @returns Result - Factura encontrada o error. + */ + async getById(id: UniqueID, transaction?: Transaction): Promise> { + return await this.repository.getById(id, transaction); } - async updateCustomerInvoiceById( + /** + * Actualiza parcialmente una factura existente con nuevos datos. + * + * @param id - Identificador de la factura a actualizar. + * @param changes - Subconjunto de props válidas para aplicar. + * @param transaction - Transacción activa para la operación. + * @returns Result - Factura actualizada o error. + */ + async updateById( customerInvoiceId: UniqueID, - data: Partial, + changes: Partial, transaction?: Transaction ): Promise> { // Verificar si la factura existe - const customerInvoiceOrError = await this.repo.getById(customerInvoiceId, transaction); + const customerInvoiceOrError = await this.repository.getById(customerInvoiceId, transaction); if (customerInvoiceOrError.isFailure) { return Result.fail(new Error("CustomerInvoice not found")); } @@ -64,7 +105,7 @@ export class CustomerInvoiceService implements ICustomerInvoiceService { transaction?: Transaction ): Promise> { // Verificar si la factura existe - const customerInvoiceOrError = await this.repo.getById(customerInvoiceId, transaction); + const customerInvoiceOrError = await this.repository.getById(customerInvoiceId, transaction); if (customerInvoiceOrError.isSuccess) { return Result.fail(new Error("CustomerInvoice exists")); } @@ -78,14 +119,18 @@ export class CustomerInvoiceService implements ICustomerInvoiceService { const newCustomerInvoice = newCustomerInvoiceOrError.data; - await this.repo.create(newCustomerInvoice, transaction); + await this.repository.create(newCustomerInvoice, transaction); return Result.ok(newCustomerInvoice); } - async deleteCustomerInvoiceById( - customerInvoiceId: UniqueID, - transaction?: Transaction - ): Promise> { - return this.repo.deleteById(customerInvoiceId, transaction); + /** + * Elimina (o marca como eliminada) una factura según su ID. + * + * @param id - Identificador UUID de la factura. + * @param transaction - Transacción activa para la operación. + * @returns Result - Resultado de la operación. + */ + async deleteById(id: UniqueID, transaction?: Transaction): Promise> { + return this.repository.deleteById(id, transaction); } } diff --git a/modules/customer-invoices/src/api/infrastructure/mappers/customer-invoice.mapper.ts b/modules/customer-invoices/src/api/infrastructure/mappers/customer-invoice.mapper.ts index fa1039f3..d0f3c132 100644 --- a/modules/customer-invoices/src/api/infrastructure/mappers/customer-invoice.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/mappers/customer-invoice.mapper.ts @@ -90,8 +90,8 @@ export class CustomerInvoiceMapper return { id: source.id.toString(), invoice_status: source.status.toPrimitive(), - invoice_series: source.customerInvoiceSeries.toPrimitive(), - invoice_number: source.customerInvoiceNumber.toPrimitive(), + invoice_series: source.invoiceSeries.toPrimitive(), + invoice_number: source.invoiceNumber.toPrimitive(), issue_date: source.issueDate.toPrimitive(), operation_date: source.operationDate.toPrimitive(), invoice_language: "es", diff --git a/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice.repository.ts b/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice.repository.ts index 1d65b403..f05360c8 100644 --- a/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice.repository.ts +++ b/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice.repository.ts @@ -1,123 +1,109 @@ -import { SequelizeRepository } from "@erp/core/api"; -import { Criteria } from "@repo/rdx-criteria/server"; +import { SequelizeRepository, errorMapper } from "@erp/core/api"; +import { Criteria, CriteriaToSequelizeConverter } from "@repo/rdx-criteria/server"; import { UniqueID } from "@repo/rdx-ddd"; import { Collection, Result } from "@repo/rdx-utils"; import { Sequelize, Transaction } from "sequelize"; import { CustomerInvoice, ICustomerInvoiceRepository } from "../../domain"; import { ICustomerInvoiceMapper } from "../mappers/customer-invoice.mapper"; -import { CustomerInvoiceItemModel } from "./customer-invoice-item.model"; import { CustomerInvoiceModel } from "./customer-invoice.model"; export class CustomerInvoiceRepository extends SequelizeRepository implements ICustomerInvoiceRepository { - private readonly _mapper!: ICustomerInvoiceMapper; - - /** - * 🔹 Función personalizada para mapear errores de unicidad en autenticación - */ - private _customErrorMapper(error: Error): string | null { - if (error.name === "SequelizeUniqueConstraintError") { - return "CustomerInvoice with this email already exists"; - } - - return null; - } + private readonly model: typeof CustomerInvoiceModel; + private readonly mapper!: ICustomerInvoiceMapper; constructor(database: Sequelize, mapper: ICustomerInvoiceMapper) { super(database); - this._mapper = mapper; + + this.model = database.model("CustomerInvoice") as typeof CustomerInvoiceModel; + this.mapper = mapper; } - async customerInvoiceExists( - id: UniqueID, - transaction?: Transaction - ): Promise> { + /** + * + * Persiste una nueva factura o actualiza una existente. + * + * @param invoice - El agregado a guardar. + * @param transaction - Transacción activa para la operación. + * @returns Result + */ + async save( + invoice: CustomerInvoice, + transaction: Transaction + ): Promise> { try { - const _customerInvoice = await this._getById(CustomerInvoiceModel, id, {}, transaction); - - return Result.ok(Boolean(id.equals(_customerInvoice.id))); - } catch (error: any) { - return this._handleDatabaseError(error, this._customErrorMapper); + const data = this.mapper.mapToPersistence(invoice); + await this.model.upsert(data, { transaction }); + return Result.ok(invoice); + } catch (err: unknown) { + return Result.fail(errorMapper.toDomainError(err)); } } - async findAll( + /** + * + * Busca una factura por su identificador único. + * @param id - UUID de la factura. + * @param transaction - Transacción activa para la operación. + * @returns Result + */ + async findById(id: UniqueID, transaction: Transaction): Promise> { + try { + const rawData = await this._findById(this.model, id.toString(), { transaction }); + + if (!rawData) { + return Result.fail(new Error(`Invoice with id ${id} not found.`)); + } + + return this.mapper.mapToDomain(rawData); + } catch (err: unknown) { + return Result.fail(errorMapper.toDomainError(err)); + } + } + + /** + * + * Consulta facturas usando un objeto Criteria (filtros, orden, paginación). + * @param criteria - Criterios de búsqueda. + * @param transaction - Transacción activa para la operación. + * @returns Result + * + * @see Criteria + */ + public async findByCriteria( criteria: Criteria, - transaction?: Transaction + transaction: Transaction ): Promise, Error>> { try { - const rawCustomerInvoices = await CustomerInvoiceModel.findAll({ - include: [ - { - model: CustomerInvoiceItemModel, - as: "items", - }, - ], + const converter = new CriteriaToSequelizeConverter(); + const query = converter.convert(criteria); + + const instances = await this.model.findAll({ + ...query, transaction, - ...this.convertCriteria(criteria), }); - return this._mapper.mapArrayToDomain(rawCustomerInvoices); - } catch (error: unknown) { - console.error("Error in findAll", error); - return this._handleDatabaseError(error, this._customErrorMapper); + return this.mapper.mapArrayToDomain(instances); + } catch (err: unknown) { + return Result.fail(errorMapper.toDomainError(err)); } } - async getById(id: UniqueID, transaction?: Transaction): Promise> { + /** + * + * Elimina o marca como eliminada una factura. + * @param id - UUID de la factura a eliminar. + * @param transaction - Transacción activa para la operación. + * @returns Result + */ + async deleteById(id: UniqueID, transaction: any): Promise> { try { - const rawCustomerInvoice: any = await this._getById( - CustomerInvoiceModel, - id, - { - include: [ - { - model: CustomerInvoiceItemModel, - as: "items", - }, - ], - }, - transaction - ); - - if (!rawCustomerInvoice === true) { - return Result.fail(new Error(`CustomerInvoice with id ${id.toString()} not exists`)); - } - } catch (error: any) { - return this._handleDatabaseError(error, this._customErrorMapper); + await this._deleteById(this.model, id, false, transaction); + return Result.ok(); + } catch (err: unknown) { + return Result.fail(errorMapper.toDomainError(err)); } } - - async deleteById(id: UniqueID, transaction?: Transaction): Promise> { - try { - this._deleteById(CustomerInvoiceModel, id, false, transaction); - return Result.ok(true); - } catch (error: any) { - return this._handleDatabaseError(error, this._customErrorMapper); - } - } - - async create(customerInvoice: CustomerInvoice, transaction?: Transaction): Promise { - const customerInvoiceData = this._mapper.mapToPersistence(customerInvoice); - await this._save( - CustomerInvoiceModel, - customerInvoice.id, - customerInvoiceData, - {}, - transaction - ); - } - - async update(customerInvoice: CustomerInvoice, transaction?: Transaction): Promise { - const customerInvoiceData = this._mapper.mapToPersistence(customerInvoice); - await this._save( - CustomerInvoiceModel, - customerInvoice.id, - customerInvoiceData, - {}, - transaction - ); - } } diff --git a/modules/customer-invoices/src/common/dto/request/create-customer-invoice.command.dto.ts b/modules/customer-invoices/src/common/dto/request/create-customer-invoice.command.dto.ts index 98e75053..45f80005 100644 --- a/modules/customer-invoices/src/common/dto/request/create-customer-invoice.command.dto.ts +++ b/modules/customer-invoices/src/common/dto/request/create-customer-invoice.command.dto.ts @@ -2,6 +2,7 @@ import * as z from "zod/v4"; export const CreateCustomerInvoiceCommandSchema = z.object({ id: z.string().uuid(), + status: z.string(), invoice_number: z.string().min(1, "Customer invoice number is required"), invoice_series: z.string().min(1, "Customer invoice series is required"), issue_date: z.string().datetime({ offset: true, message: "Invalid issue date format" }), diff --git a/modules/customer-invoices/src/common/dto/response/customer-invoice-creation.result.dto.ts b/modules/customer-invoices/src/common/dto/response/customer-invoice-creation.result.dto.ts index e69de29b..3d2b5ead 100644 --- a/modules/customer-invoices/src/common/dto/response/customer-invoice-creation.result.dto.ts +++ b/modules/customer-invoices/src/common/dto/response/customer-invoice-creation.result.dto.ts @@ -0,0 +1,19 @@ +import { MetadataSchema } from "@erp/core"; +import * as z from "zod/v4"; + +export const CustomerInvoicesCreationResultSchema = z.object({ + id: z.uuid(), + invoice_status: z.string(), + invoice_number: z.string(), + invoice_series: z.string(), + issue_date: z.iso.datetime({ offset: true }), + operation_date: z.iso.datetime({ offset: true }), + language_code: z.string(), + currency: z.string(), + + metadata: MetadataSchema.optional(), +}); + +export type CustomerInvoicesCreationResultDTO = z.infer< + typeof CustomerInvoicesCreationResultSchema +>; diff --git a/modules/customer-invoices/src/common/dto/response/index.ts b/modules/customer-invoices/src/common/dto/response/index.ts index fed6daf7..6b34fd8e 100644 --- a/modules/customer-invoices/src/common/dto/response/index.ts +++ b/modules/customer-invoices/src/common/dto/response/index.ts @@ -1 +1,2 @@ +export * from "./customer-invoice-creation.result.dto"; export * from "./list-customer-invoices.result.dto"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3e2801d2..18c0a752 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -639,7 +639,7 @@ importers: version: 4.1.10 tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@2.4.2)(postcss@8.5.6)(tsx@4.19.4)(typescript@5.8.3) + version: 8.4.0(jiti@2.4.2)(postcss@8.5.6)(tsx@4.19.4)(typescript@5.8.3) tw-animate-css: specifier: ^1.2.9 version: 1.3.4 @@ -2855,11 +2855,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - add@2.0.6: resolution: {integrity: sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q==} @@ -3269,9 +3264,6 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - connect-history-api-fallback@1.6.0: resolution: {integrity: sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==} engines: {node: '>=0.8'} @@ -3765,9 +3757,6 @@ packages: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} - fix-dts-default-cjs-exports@1.0.1: - resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} - fn.name@1.1.0: resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} @@ -4721,9 +4710,6 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.7.4: - resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} - module-alias@2.2.3: resolution: {integrity: sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==} @@ -5012,9 +4998,6 @@ packages: pathe@0.2.0: resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==} - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - pause@0.0.1: resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==} @@ -5047,9 +5030,6 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - pnpm@10.12.2: resolution: {integrity: sha512-oyVAGFuWTuMLtOl55AWtxq9ZImtDjuTMGfnodzZnpm0wL1v+5go508rGnjXkuW5winHdACt+k1nEESoXIqwyPw==} engines: {node: '>=18.12'} @@ -5899,25 +5879,6 @@ packages: typescript: optional: true - tsup@8.5.0: - resolution: {integrity: sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - '@microsoft/api-extractor': ^7.36.0 - '@swc/core': ^1 - postcss: ^8.4.12 - typescript: '>=4.5.0' - peerDependenciesMeta: - '@microsoft/api-extractor': - optional: true - '@swc/core': - optional: true - postcss: - optional: true - typescript: - optional: true - tsutils@3.21.0: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -5992,9 +5953,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - ufo@1.6.1: - resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - uglify-js@3.19.3: resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} @@ -8412,8 +8370,6 @@ snapshots: acorn@8.14.1: {} - acorn@8.15.0: {} - add@2.0.6: {} ag-charts-types@11.3.2: {} @@ -8864,8 +8820,6 @@ snapshots: concat-map@0.0.1: {} - confbox@0.1.8: {} - connect-history-api-fallback@1.6.0: {} consola@2.15.3: {} @@ -9376,12 +9330,6 @@ snapshots: locate-path: 5.0.0 path-exists: 4.0.0 - fix-dts-default-cjs-exports@1.0.1: - dependencies: - magic-string: 0.30.17 - mlly: 1.7.4 - rollup: 4.41.1 - fn.name@1.1.0: {} follow-redirects@1.15.9: {} @@ -10485,13 +10433,6 @@ snapshots: mkdirp@3.0.1: {} - mlly@1.7.4: - dependencies: - acorn: 8.15.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.1 - module-alias@2.2.3: {} moment-timezone@0.5.48: @@ -10792,8 +10733,6 @@ snapshots: pathe@0.2.0: {} - pathe@2.0.3: {} - pause@0.0.1: {} pg-connection-string@2.9.0: {} @@ -10815,12 +10754,6 @@ snapshots: dependencies: find-up: 4.1.0 - pkg-types@1.3.1: - dependencies: - confbox: 0.1.8 - mlly: 1.7.4 - pathe: 2.0.3 - pnpm@10.12.2: {} postcss-load-config@3.1.4(postcss@8.5.6)(ts-node@10.9.2(@types/node@22.15.32)(typescript@5.8.3)): @@ -11707,34 +11640,6 @@ snapshots: - tsx - yaml - tsup@8.5.0(jiti@2.4.2)(postcss@8.5.6)(tsx@4.19.4)(typescript@5.8.3): - dependencies: - bundle-require: 5.1.0(esbuild@0.25.5) - cac: 6.7.14 - chokidar: 4.0.3 - consola: 3.4.2 - debug: 4.4.1(supports-color@8.1.1) - esbuild: 0.25.5 - fix-dts-default-cjs-exports: 1.0.1 - joycon: 3.1.1 - picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.4.2)(postcss@8.5.6)(tsx@4.19.4) - resolve-from: 5.0.0 - rollup: 4.41.1 - source-map: 0.8.0-beta.0 - sucrase: 3.35.0 - tinyexec: 0.3.2 - tinyglobby: 0.2.14 - tree-kill: 1.2.2 - optionalDependencies: - postcss: 8.5.6 - typescript: 5.8.3 - transitivePeerDependencies: - - jiti - - supports-color - - tsx - - yaml - tsutils@3.21.0(typescript@5.8.3): dependencies: tslib: 1.14.1 @@ -11812,8 +11717,6 @@ snapshots: typescript@5.8.3: {} - ufo@1.6.1: {} - uglify-js@3.19.3: optional: true