diff --git a/generated/swagger/oms-api/src/models.ts b/generated/swagger/oms-api/src/models.ts index 8dbb4cd6a..1314e3529 100644 --- a/generated/swagger/oms-api/src/models.ts +++ b/generated/swagger/oms-api/src/models.ts @@ -37,6 +37,7 @@ export { Gender } from './models/gender'; export { DateRangeDTO } from './models/date-range-dto'; export { PaymentType } from './models/payment-type'; export { PaymentStatus } from './models/payment-status'; +export { LoyaltyDTO } from './models/loyalty-dto'; export { QueryTokenDTO } from './models/query-token-dto'; export { ListResponseArgsOfOrderItemListItemDTO } from './models/list-response-args-of-order-item-list-item-dto'; export { ResponseArgsOfIEnumerableOfOrderItemListItemDTO } from './models/response-args-of-ienumerable-of-order-item-list-item-dto'; @@ -130,7 +131,6 @@ export { Price } from './models/price'; export { ShippingTarget } from './models/shipping-target'; export { EntityDTOBaseOfShopItemDTOAndIShopItem } from './models/entity-dtobase-of-shop-item-dtoand-ishop-item'; export { CampaignDTO } from './models/campaign-dto'; -export { LoyaltyDTO } from './models/loyalty-dto'; export { EntityDTOBaseOfOrderItemDTOAndIOrderItem } from './models/entity-dtobase-of-order-item-dtoand-iorder-item'; export { EntityDTOContainerOfSupplierDTO } from './models/entity-dtocontainer-of-supplier-dto'; export { SupplierDTO } from './models/supplier-dto'; @@ -207,6 +207,8 @@ export { EntityDTOContainerOfOrderItemSubsetTransitionDTO } from './models/entit export { OrderItemSubsetTransitionDTO } from './models/order-item-subset-transition-dto'; export { EntityDTOBaseOfOrderItemSubsetTransitionDTOAndIOrderItemStatusTransition } from './models/entity-dtobase-of-order-item-subset-transition-dtoand-iorder-item-status-transition'; export { EntityDTOBaseOfOrderItemSubsetTaskDTOAndIOrderItemStatusTask } from './models/entity-dtobase-of-order-item-subset-task-dtoand-iorder-item-status-task'; +export { LoyaltyCollectValues } from './models/loyalty-collect-values'; +export { LoyaltyCollectType } from './models/loyalty-collect-type'; export { ResponseArgsOfBoolean } from './models/response-args-of-boolean'; export { ResponseArgsOfOrderItemDTO } from './models/response-args-of-order-item-dto'; export { ResponseArgsOfIEnumerableOfOrderItemDTO } from './models/response-args-of-ienumerable-of-order-item-dto'; diff --git a/generated/swagger/oms-api/src/models/display-order-item-dto.ts b/generated/swagger/oms-api/src/models/display-order-item-dto.ts index f9f5d9e34..e020ac4d6 100644 --- a/generated/swagger/oms-api/src/models/display-order-item-dto.ts +++ b/generated/swagger/oms-api/src/models/display-order-item-dto.ts @@ -1,5 +1,6 @@ /* tslint:disable */ import { EntityDTOBaseOfDisplayOrderItemDTOAndIOrderItem } from './entity-dtobase-of-display-order-item-dtoand-iorder-item'; +import { LoyaltyDTO } from './loyalty-dto'; import { DisplayOrderDTO } from './display-order-dto'; import { PriceDTO } from './price-dto'; import { ProductDTO } from './product-dto'; @@ -23,6 +24,11 @@ export interface DisplayOrderItemDTO extends EntityDTOBaseOfDisplayOrderItemDTOA */ features?: {[key: string]: string}; + /** + * Loylty + */ + loyalty?: LoyaltyDTO; + /** * Bestellung */ diff --git a/generated/swagger/oms-api/src/models/loyalty-collect-type.ts b/generated/swagger/oms-api/src/models/loyalty-collect-type.ts new file mode 100644 index 000000000..942a67c04 --- /dev/null +++ b/generated/swagger/oms-api/src/models/loyalty-collect-type.ts @@ -0,0 +1,2 @@ +/* tslint:disable */ +export type LoyaltyCollectType = 0 | 1 | 2; \ No newline at end of file diff --git a/generated/swagger/oms-api/src/models/loyalty-collect-values.ts b/generated/swagger/oms-api/src/models/loyalty-collect-values.ts new file mode 100644 index 000000000..7663a8b0b --- /dev/null +++ b/generated/swagger/oms-api/src/models/loyalty-collect-values.ts @@ -0,0 +1,18 @@ +/* tslint:disable */ +import { LoyaltyCollectType } from './loyalty-collect-type'; + +/** + * Loyalty collect values + */ +export interface LoyaltyCollectValues { + + /** + * Collect Type + */ + collectType: LoyaltyCollectType; + + /** + * Quantity (optional, default null) + */ + quantity?: number; +} diff --git a/generated/swagger/oms-api/src/models/order-item-list-item-dto.ts b/generated/swagger/oms-api/src/models/order-item-list-item-dto.ts index c0d18a7f8..770679582 100644 --- a/generated/swagger/oms-api/src/models/order-item-list-item-dto.ts +++ b/generated/swagger/oms-api/src/models/order-item-list-item-dto.ts @@ -4,6 +4,7 @@ import { EnvironmentChannel } from './environment-channel'; import { CRUDA } from './cruda'; import { DateRangeDTO } from './date-range-dto'; import { Gender } from './gender'; +import { LoyaltyDTO } from './loyalty-dto'; import { OrderType } from './order-type'; import { PaymentStatus } from './payment-status'; import { PaymentType } from './payment-type'; @@ -102,6 +103,11 @@ export interface OrderItemListItemDTO { */ lastName?: string; + /** + * Loylty + */ + loyalty?: LoyaltyDTO; + /** * Bestellfiliale */ diff --git a/generated/swagger/oms-api/src/models/receipt-item-list-item-dto.ts b/generated/swagger/oms-api/src/models/receipt-item-list-item-dto.ts index b2d6b8b26..85b22677a 100644 --- a/generated/swagger/oms-api/src/models/receipt-item-list-item-dto.ts +++ b/generated/swagger/oms-api/src/models/receipt-item-list-item-dto.ts @@ -1,12 +1,19 @@ /* tslint:disable */ import { EntityReferenceDTO } from './entity-reference-dto'; +import { KeyValueDTOOfStringAndString } from './key-value-dtoof-string-and-string'; import { CRUDA } from './cruda'; import { PriceDTO } from './price-dto'; +import { LoyaltyDTO } from './loyalty-dto'; import { ProductDTO } from './product-dto'; import { PromotionDTO } from './promotion-dto'; import { QuantityDTO } from './quantity-dto'; import { ReceiptListItemDTO } from './receipt-list-item-dto'; export interface ReceiptItemListItemDTO extends EntityReferenceDTO{ + + /** + * Mögliche Aktionen + */ + actions?: Array; buyerComment?: string; /** @@ -19,6 +26,11 @@ export interface ReceiptItemListItemDTO extends EntityReferenceDTO{ */ discountedPrice?: PriceDTO; + /** + * Zusätzliche Markierungen + */ + features?: {[key: string]: string}; + /** * PK */ @@ -35,6 +47,11 @@ export interface ReceiptItemListItemDTO extends EntityReferenceDTO{ */ lineNumber?: number; + /** + * Loyalty + */ + loyalty?: LoyaltyDTO; + /** * Bestellnummer */ diff --git a/generated/swagger/oms-api/src/services/order.service.ts b/generated/swagger/oms-api/src/services/order.service.ts index d942d9f87..c5be95d57 100644 --- a/generated/swagger/oms-api/src/services/order.service.ts +++ b/generated/swagger/oms-api/src/services/order.service.ts @@ -21,6 +21,8 @@ import { ResponseArgsOfQuerySettingsDTO } from '../models/response-args-of-query import { ResponseArgsOfIEnumerableOfAutocompleteDTO } from '../models/response-args-of-ienumerable-of-autocomplete-dto'; import { AutocompleteTokenDTO } from '../models/autocomplete-token-dto'; import { ListResponseArgsOfDBHOrderItemListItemDTO } from '../models/list-response-args-of-dbhorder-item-list-item-dto'; +import { ResponseArgsOfIEnumerableOfDBHOrderItemListItemDTO } from '../models/response-args-of-ienumerable-of-dbhorder-item-list-item-dto'; +import { LoyaltyCollectValues } from '../models/loyalty-collect-values'; import { ListResponseArgsOfOrderItemListItemDTO } from '../models/list-response-args-of-order-item-list-item-dto'; import { ResponseArgsOfIEnumerableOfOrderItemDTO } from '../models/response-args-of-ienumerable-of-order-item-dto'; import { OrderItemDTO } from '../models/order-item-dto'; @@ -54,6 +56,7 @@ class OrderService extends __BaseService { static readonly OrderKundenbestellungenSettingsPath = '/kundenbestellungen/s/settings'; static readonly OrderKundenbestellungenAutocompletePath = '/kundenbestellungen/s/complete'; static readonly OrderKundenbestellungenPath = '/kundenbestellungen/s'; + static readonly OrderLoyaltyCollectPath = '/order/{orderId}/orderitem/{orderItemId}/orderitemsubset/{orderItemSubsetId}/loyaltycollect'; static readonly OrderQueryOrderItemPath = '/order/item/s'; static readonly OrderQueryOrderItemAutocompletePath = '/order/item/s/complete'; static readonly OrderGetOrderItemPath = '/order/orderitem/{orderItemId}'; @@ -636,6 +639,63 @@ class OrderService extends __BaseService { ); } + /** + * Ausgabe order Storno von Prämienbestellposten + * Falls die Menge/Stückzahl kleiner der ursprünglichen Menge/Stückzahl ist, wird eine neue Bestellpostenteilmenge erzeugt. + * @param params The `OrderService.OrderLoyaltyCollectParams` containing the following parameters: + * + * - `orderItemSubsetId`: PK Bestellpostenteilmenge + * + * - `orderItemId`: PK Bestellposten + * + * - `orderId`: PK Bestellung + * + * - `data`: Daten zur Änderung des Bearbeitungsstatus + */ + OrderLoyaltyCollectResponse(params: OrderService.OrderLoyaltyCollectParams): __Observable<__StrictHttpResponse> { + let __params = this.newParams(); + let __headers = new HttpHeaders(); + let __body: any = null; + + + + __body = params.data; + let req = new HttpRequest( + 'POST', + this.rootUrl + `/order/${encodeURIComponent(String(params.orderId))}/orderitem/${encodeURIComponent(String(params.orderItemId))}/orderitemsubset/${encodeURIComponent(String(params.orderItemSubsetId))}/loyaltycollect`, + __body, + { + headers: __headers, + params: __params, + responseType: 'json' + }); + + return this.http.request(req).pipe( + __filter(_r => _r instanceof HttpResponse), + __map((_r) => { + return _r as __StrictHttpResponse; + }) + ); + } + /** + * Ausgabe order Storno von Prämienbestellposten + * Falls die Menge/Stückzahl kleiner der ursprünglichen Menge/Stückzahl ist, wird eine neue Bestellpostenteilmenge erzeugt. + * @param params The `OrderService.OrderLoyaltyCollectParams` containing the following parameters: + * + * - `orderItemSubsetId`: PK Bestellpostenteilmenge + * + * - `orderItemId`: PK Bestellposten + * + * - `orderId`: PK Bestellung + * + * - `data`: Daten zur Änderung des Bearbeitungsstatus + */ + OrderLoyaltyCollect(params: OrderService.OrderLoyaltyCollectParams): __Observable { + return this.OrderLoyaltyCollectResponse(params).pipe( + __map(_r => _r.body as ResponseArgsOfIEnumerableOfDBHOrderItemListItemDTO) + ); + } + /** * Suche nach Bestellposten * @param queryToken Suchkriterien @@ -1671,6 +1731,32 @@ module OrderService { buyerNumber?: null | string; } + /** + * Parameters for OrderLoyaltyCollect + */ + export interface OrderLoyaltyCollectParams { + + /** + * PK Bestellpostenteilmenge + */ + orderItemSubsetId: number; + + /** + * PK Bestellposten + */ + orderItemId: number; + + /** + * PK Bestellung + */ + orderId: number; + + /** + * Daten zur Änderung des Bearbeitungsstatus + */ + data: LoyaltyCollectValues; + } + /** * Parameters for OrderUpdateOrderItem */ diff --git a/generated/swagger/oms-api/src/services/receipt.service.ts b/generated/swagger/oms-api/src/services/receipt.service.ts index ea036bf87..647078435 100644 --- a/generated/swagger/oms-api/src/services/receipt.service.ts +++ b/generated/swagger/oms-api/src/services/receipt.service.ts @@ -236,6 +236,7 @@ class ReceiptService extends __BaseService { } /** + * Aufgabe auf erledigt setzen * @param taskId undefined */ ReceiptReceiptItemTaskCompletedResponse(taskId: number): __Observable<__StrictHttpResponse> { @@ -261,6 +262,7 @@ class ReceiptService extends __BaseService { ); } /** + * Aufgabe auf erledigt setzen * @param taskId undefined */ ReceiptReceiptItemTaskCompleted(taskId: number): __Observable { diff --git a/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/confirmation-list-item-action-card/confirmation-list-item-action-card.component.css b/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/confirmation-list-item-action-card/confirmation-list-item-action-card.component.css index e69de29bb..c9a66a7ff 100644 --- a/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/confirmation-list-item-action-card/confirmation-list-item-action-card.component.css +++ b/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/confirmation-list-item-action-card/confirmation-list-item-action-card.component.css @@ -0,0 +1,3 @@ +.confirmation-list-item-done { + @apply bg-transparent p-0; +} diff --git a/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/confirmation-list-item-action-card/confirmation-list-item-action-card.component.html b/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/confirmation-list-item-action-card/confirmation-list-item-action-card.component.html index e69de29bb..f83052fc3 100644 --- a/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/confirmation-list-item-action-card/confirmation-list-item-action-card.component.html +++ b/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/confirmation-list-item-action-card/confirmation-list-item-action-card.component.html @@ -0,0 +1,62 @@ +
+ @if (!isComplete()) { +
+ Bitte buchen Sie die Prämie aus dem Abholfach aus oder wählen Sie eine + andere Aktion. +
+ +
+ + Prämie ausbuchen + Nicht gefunden + Stornieren + + + +
+ } @else { +
+ Artikel wurde Storniert und Lesepunkte gut geschrieben. +
+ + + + Abgeschlossen + + } +
diff --git a/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/confirmation-list-item-action-card/confirmation-list-item-action-card.component.ts b/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/confirmation-list-item-action-card/confirmation-list-item-action-card.component.ts index de364935b..9407795cd 100644 --- a/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/confirmation-list-item-action-card/confirmation-list-item-action-card.component.ts +++ b/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/confirmation-list-item-action-card/confirmation-list-item-action-card.component.ts @@ -1,13 +1,111 @@ -import { ChangeDetectionStrategy, Component, input } from '@angular/core'; -import { DisplayOrderItem } from '@isa/oms/data-access'; +import { + ChangeDetectionStrategy, + Component, + input, + inject, + computed, + signal, + effect, +} from '@angular/core'; +import { isaActionCheck } from '@isa/icons'; +import { + DisplayOrderItem, + OrderRewardCollectFacade, + LoyaltyCollectType, + OrderItemSubsetResource, + getProcessingStatusCompleted, +} from '@isa/oms/data-access'; +import { ButtonComponent } from '@isa/ui/buttons'; +import { NgIcon } from '@ng-icons/core'; +import { provideIcons } from '@ng-icons/core'; +import { OrderConfiramtionStore } from '../../../reward-order-confirmation.store'; +import { + DropdownButtonComponent, + DropdownOptionComponent, +} from '@isa/ui/input-controls'; @Component({ selector: 'checkout-confirmation-list-item-action-card', templateUrl: './confirmation-list-item-action-card.component.html', styleUrls: ['./confirmation-list-item-action-card.component.css'], changeDetection: ChangeDetectionStrategy.OnPush, - imports: [], + imports: [ + NgIcon, + ButtonComponent, + DropdownButtonComponent, + DropdownOptionComponent, + ], + providers: [provideIcons({ isaActionCheck }), OrderItemSubsetResource], }) export class ConfirmationListItemActionCardComponent { + LoyaltyCollectType = LoyaltyCollectType; + #orderRewardCollectFacade = inject(OrderRewardCollectFacade); + #store = inject(OrderConfiramtionStore); + #orderItemSubsetResource = inject(OrderItemSubsetResource); + item = input.required(); + + orders = this.#store.orders; + + getOrderIdBasedOnItem = computed(() => { + const item = this.item(); + const orders = this.orders(); + if (!orders) { + return undefined; + } + const order = orders.find((order) => + order.items?.some((orderItem) => orderItem.id === item.id), + ); + return order?.id; + }); + + orderItemSubsets = this.#orderItemSubsetResource.orderItemSubsets; + selectedAction = signal(LoyaltyCollectType.Collect); + isComplete = computed(() => { + const subsets = this.orderItemSubsets(); + const statuses = subsets?.map((subset) => subset.processingStatus); + return getProcessingStatusCompleted(statuses); + }); + + constructor() { + effect(() => { + const item = this.item(); + const orderItemSubsetIds = item.subsetItems + ?.map((subset) => subset.id) + ?.filter((id): id is number => id !== undefined); + + if (orderItemSubsetIds?.length) { + this.#orderItemSubsetResource.loadOrderItemSubsets(orderItemSubsetIds); + } + }); + } + + setDropdownAction(value: LoyaltyCollectType) { + this.selectedAction.set(value); + } + + async onCollect() { + const item = this.item(); + const orderId = this.getOrderIdBasedOnItem(); + const orderItemId = item.id; + const collectType = this.selectedAction(); + + if (orderId && orderItemId) { + for (const subsetItem of item.subsetItems ?? []) { + const orderItemSubsetId = subsetItem.id; + const quantity = subsetItem.quantity; + + if (orderItemSubsetId && !!quantity) { + await this.#orderRewardCollectFacade.collect({ + orderId, + orderItemId, + orderItemSubsetId, + collectType, + quantity, + }); + } + } + this.#orderItemSubsetResource.refresh(); + } + } } diff --git a/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/order-confirmation-item-list-item.component.css b/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/order-confirmation-item-list-item.component.css index 129106481..3d00373b9 100644 --- a/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/order-confirmation-item-list-item.component.css +++ b/libs/checkout/feature/reward-order-confirmation/src/lib/order-confirmation-item-list/order-confirmation-item-list-item/order-confirmation-item-list-item.component.css @@ -1,3 +1,3 @@ -:host { - @apply flex w-full items-start gap-6; -} +:host { + @apply flex w-full items-start gap-6; +} diff --git a/libs/common/data-access/src/lib/schemas/date-range.schema.ts b/libs/common/data-access/src/lib/schemas/date-range.schema.ts new file mode 100644 index 000000000..faa67816f --- /dev/null +++ b/libs/common/data-access/src/lib/schemas/date-range.schema.ts @@ -0,0 +1,8 @@ +import z from 'zod'; + +export const DateRangeSchema = z.object({ + start: z.string().optional(), + end: z.string().optional(), +}); + +export type DateRange = z.infer; diff --git a/libs/common/data-access/src/lib/schemas/index.ts b/libs/common/data-access/src/lib/schemas/index.ts index 9c8fed279..0cbb303b8 100644 --- a/libs/common/data-access/src/lib/schemas/index.ts +++ b/libs/common/data-access/src/lib/schemas/index.ts @@ -2,6 +2,7 @@ export * from './address.schema'; export * from './addressee-with-reference.schema'; export * from './buyer-type.schema'; export * from './communication-details.schema'; +export * from './date-range.schema'; export * from './entity-container.schema'; export * from './entity-reference-container.schema'; export * from './entity-reference.schema'; diff --git a/libs/oms/data-access/src/index.ts b/libs/oms/data-access/src/index.ts index b6f115547..c8d58e3cf 100644 --- a/libs/oms/data-access/src/index.ts +++ b/libs/oms/data-access/src/index.ts @@ -19,8 +19,9 @@ export * from './lib/errors'; export * from './lib/questions'; export * from './lib/models'; export * from './lib/facades'; -export * from './lib/helpers/return-process'; +export * from './lib/helpers'; export * from './lib/schemas'; export * from './lib/services'; export * from './lib/operators'; export * from './lib/stores'; +export * from './lib/resources'; diff --git a/libs/oms/data-access/src/lib/facades/index.ts b/libs/oms/data-access/src/lib/facades/index.ts index ae27d95e7..aaeec24a9 100644 --- a/libs/oms/data-access/src/lib/facades/index.ts +++ b/libs/oms/data-access/src/lib/facades/index.ts @@ -1 +1,2 @@ export { OrderCreationFacade } from './order-creation.facade'; +export { OrderRewardCollectFacade } from './order-reward-collect.facade'; diff --git a/libs/oms/data-access/src/lib/facades/order-reward-collect.facade.spec.ts b/libs/oms/data-access/src/lib/facades/order-reward-collect.facade.spec.ts new file mode 100644 index 000000000..28a27a87f --- /dev/null +++ b/libs/oms/data-access/src/lib/facades/order-reward-collect.facade.spec.ts @@ -0,0 +1,105 @@ +import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; +import { OrderRewardCollectFacade } from './order-reward-collect.facade'; +import { OrderRewardCollectService } from '../services'; +import { DBHOrderItemListItemDTO } from '@generated/swagger/oms-api'; + +describe('OrderRewardCollectFacade', () => { + let spectator: SpectatorService; + const createService = createServiceFactory({ + service: OrderRewardCollectFacade, + mocks: [OrderRewardCollectService], + }); + + beforeEach(() => { + spectator = createService(); + }); + + describe('collect', () => { + it('should delegate to OrderRewardCollectService.collect', async () => { + // Arrange + const mockParams = { + orderId: 123, + orderItemId: 456, + orderItemSubsetId: 789, + collectType: 1 as const, // Valid LoyaltyCollectType.Collect + quantity: 2, + }; + const mockResult: DBHOrderItemListItemDTO[] = [ + { orderItemType: 1 } as DBHOrderItemListItemDTO, + ]; + const rewardItemService = spectator.inject(OrderRewardCollectService); + (rewardItemService.collect as jest.Mock).mockResolvedValue(mockResult); + + // Act + const result = await spectator.service.collect(mockParams); + + // Assert + expect(result).toEqual(mockResult); + expect(rewardItemService.collect).toHaveBeenCalledWith({ + orderId: mockParams.orderId, + orderItemId: mockParams.orderItemId, + orderItemSubsetId: mockParams.orderItemSubsetId, + collectType: mockParams.collectType, + quantity: mockParams.quantity, + }); + expect(rewardItemService.collect).toHaveBeenCalledTimes(1); + }); + + it('should propagate errors from OrderRewardCollectService', async () => { + // Arrange + const mockParams = { + orderId: 123, + orderItemId: 456, + orderItemSubsetId: 789, + collectType: 1 as const, // Valid LoyaltyCollectType.Collect + quantity: 2, + }; + const errorMessage = 'Failed to collect reward item'; + const rewardItemService = spectator.inject(OrderRewardCollectService); + (rewardItemService.collect as jest.Mock).mockRejectedValue( + new Error(errorMessage), + ); + + // Act & Assert + await expect(spectator.service.collect(mockParams)).rejects.toThrow( + errorMessage, + ); + expect(rewardItemService.collect).toHaveBeenCalledWith({ + orderId: mockParams.orderId, + orderItemId: mockParams.orderItemId, + orderItemSubsetId: mockParams.orderItemSubsetId, + collectType: mockParams.collectType, + quantity: mockParams.quantity, + }); + }); + }); + + describe('getOrderItemSubset', () => { + it('should delegate to OrderRewardCollectService.fetchOrderItemSubset', async () => { + // Arrange + const mockParams = { + orderItemSubsetId: 789, + }; + const mockResult = { + id: 789, + quantity: 2, + name: 'Test Subset', + }; + const rewardItemService = spectator.inject(OrderRewardCollectService); + (rewardItemService.fetchOrderItemSubset as jest.Mock).mockResolvedValue( + mockResult, + ); + + // Act + const result = await spectator.service.getOrderItemSubset(mockParams); + + // Assert + expect(result).toEqual(mockResult); + expect(rewardItemService.fetchOrderItemSubset).toHaveBeenCalledWith( + mockParams, + undefined, + ); + expect(rewardItemService.fetchOrderItemSubset).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/libs/oms/data-access/src/lib/facades/order-reward-collect.facade.ts b/libs/oms/data-access/src/lib/facades/order-reward-collect.facade.ts new file mode 100644 index 000000000..4f1e098ae --- /dev/null +++ b/libs/oms/data-access/src/lib/facades/order-reward-collect.facade.ts @@ -0,0 +1,25 @@ +import { inject, Injectable } from '@angular/core'; +import { OrderRewardCollectService } from '../services'; +import { + FetchOrderItemSubsetSchemaInput, + OrderLoyaltyCollectInput, +} from '../schemas'; + +@Injectable({ providedIn: 'root' }) +export class OrderRewardCollectFacade { + #orderRewardCollectService = inject(OrderRewardCollectService); + + async collect(params: OrderLoyaltyCollectInput) { + return this.#orderRewardCollectService.collect(params); + } + + async getOrderItemSubset( + params: FetchOrderItemSubsetSchemaInput, + abortSignal?: AbortSignal, + ) { + return this.#orderRewardCollectService.fetchOrderItemSubset( + params, + abortSignal, + ); + } +} diff --git a/libs/oms/data-access/src/lib/helpers/index.ts b/libs/oms/data-access/src/lib/helpers/index.ts new file mode 100644 index 000000000..ce3ebfa31 --- /dev/null +++ b/libs/oms/data-access/src/lib/helpers/index.ts @@ -0,0 +1,2 @@ +export * from './return-process'; +export * from './reward'; diff --git a/libs/oms/data-access/src/lib/helpers/reward/get-processing-status-completed.helper.spec.ts b/libs/oms/data-access/src/lib/helpers/reward/get-processing-status-completed.helper.spec.ts new file mode 100644 index 000000000..9687ca0de --- /dev/null +++ b/libs/oms/data-access/src/lib/helpers/reward/get-processing-status-completed.helper.spec.ts @@ -0,0 +1,97 @@ +import { OrderItemProcessingStatusValue } from '../../schemas'; +import { getProcessingStatusCompleted } from './get-processing-status-completed.helper'; + +describe('getProcessingStatusCompleted', () => { + it('should return true when all statuses are different from Bestellt (16)', () => { + // Arrange + const statuses = [ + OrderItemProcessingStatusValue.Versendet, // 64 + OrderItemProcessingStatusValue.Eingetroffen, // 128 + OrderItemProcessingStatusValue.Abgeholt, // 256 + ]; + + // Act + const result = getProcessingStatusCompleted(statuses); + + // Assert + expect(result).toBe(true); + }); + + it('should return true when statuses include various completed states', () => { + // Arrange + const statuses = [ + OrderItemProcessingStatusValue.Zugestellt, // 4194304 + OrderItemProcessingStatusValue.Abgeholt, // 256 + OrderItemProcessingStatusValue.Versendet, // 64 + ]; + + // Act + const result = getProcessingStatusCompleted(statuses); + + // Assert + expect(result).toBe(true); + }); + + it('should return false when at least one status is Bestellt (16)', () => { + // Arrange + const statuses = [ + OrderItemProcessingStatusValue.Versendet, // 64 + OrderItemProcessingStatusValue.Bestellt, // 16 + OrderItemProcessingStatusValue.Abgeholt, // 256 + ]; + + // Act + const result = getProcessingStatusCompleted(statuses); + + // Assert + expect(result).toBe(false); + }); + + it('should return false when all statuses are Bestellt (16)', () => { + // Arrange + const statuses = [ + OrderItemProcessingStatusValue.Bestellt, // 16 + OrderItemProcessingStatusValue.Bestellt, // 16 + OrderItemProcessingStatusValue.Bestellt, // 16 + ]; + + // Act + const result = getProcessingStatusCompleted(statuses); + + // Assert + expect(result).toBe(false); + }); + + it('should return false when array is empty', () => { + // Arrange + const statuses: number[] = []; + + // Act + const result = getProcessingStatusCompleted(statuses); + + // Assert + expect(result).toBe(false); + }); + + it('should return false when statuses is undefined', () => { + // Arrange + const statuses = undefined; + + // Act + const result = getProcessingStatusCompleted(statuses); + + // Assert + expect(result).toBe(false); + }); + + it('should return true with single status different from Bestellt', () => { + // Arrange + const statuses = [OrderItemProcessingStatusValue.Abgeholt]; // 256 + + // Act + const result = getProcessingStatusCompleted(statuses); + + // Assert + expect(result).toBe(true); + }); +}); diff --git a/libs/oms/data-access/src/lib/helpers/reward/get-processing-status-completed.helper.ts b/libs/oms/data-access/src/lib/helpers/reward/get-processing-status-completed.helper.ts new file mode 100644 index 000000000..d6b2b17ba --- /dev/null +++ b/libs/oms/data-access/src/lib/helpers/reward/get-processing-status-completed.helper.ts @@ -0,0 +1,18 @@ +import { OrderItemProcessingStatusValue } from '../../schemas'; + +/** + * Checks if all processing statuses are completed (not in "Bestellt" state). + * Returns true if all statuses are different from "Bestellt" (16). + * Returns false if any status is still "Bestellt" (16) or if the array is empty/undefined. + */ +export const getProcessingStatusCompleted = ( + statuses: number[] | undefined, +): boolean => { + if (!statuses || statuses.length === 0) { + return false; + } + + return statuses.every( + (status) => status !== OrderItemProcessingStatusValue.Bestellt, + ); +}; diff --git a/libs/oms/data-access/src/lib/helpers/reward/index.ts b/libs/oms/data-access/src/lib/helpers/reward/index.ts new file mode 100644 index 000000000..5e7ab59e6 --- /dev/null +++ b/libs/oms/data-access/src/lib/helpers/reward/index.ts @@ -0,0 +1 @@ +export * from './get-processing-status-completed.helper'; diff --git a/libs/oms/data-access/src/lib/index.ts b/libs/oms/data-access/src/lib/index.ts index 022fa20ff..19770dd00 100644 --- a/libs/oms/data-access/src/lib/index.ts +++ b/libs/oms/data-access/src/lib/index.ts @@ -6,3 +6,4 @@ export * from './questions'; export * from './schemas'; export * from './services'; export * from './stores'; +export * from './resources'; diff --git a/libs/oms/data-access/src/lib/resources/index.ts b/libs/oms/data-access/src/lib/resources/index.ts new file mode 100644 index 000000000..25a9a5908 --- /dev/null +++ b/libs/oms/data-access/src/lib/resources/index.ts @@ -0,0 +1 @@ +export * from './order-item-subset.resource'; diff --git a/libs/oms/data-access/src/lib/resources/order-item-subset.resource.ts b/libs/oms/data-access/src/lib/resources/order-item-subset.resource.ts new file mode 100644 index 000000000..bf48ff362 --- /dev/null +++ b/libs/oms/data-access/src/lib/resources/order-item-subset.resource.ts @@ -0,0 +1,51 @@ +import { computed, inject, Injectable, resource, signal } from '@angular/core'; +import { DisplayOrderItemSubset } from '../schemas'; +import { OrderRewardCollectFacade } from '../facades'; + +@Injectable() +export class OrderItemSubsetResource { + #orderRewardCollectFacade = inject(OrderRewardCollectFacade); + + #orderItemSubsetIds = signal(undefined); + + #orderItemSubsetsResource = resource({ + params: computed(() => ({ + orderItemSubsetIds: this.#orderItemSubsetIds(), + })), + loader: async ({ + params, + abortSignal, + }): Promise => { + if (!params?.orderItemSubsetIds?.length) { + return []; + } + + const results: DisplayOrderItemSubset[] = []; + for (const id of params.orderItemSubsetIds) { + const result = await this.#orderRewardCollectFacade.getOrderItemSubset( + { orderItemSubsetId: id }, + abortSignal, + ); + if (result) { + results.push(result); + } + } + return results; + }, + defaultValue: [], + }); + + readonly orderItemSubsets = this.#orderItemSubsetsResource.value.asReadonly(); + readonly loading = this.#orderItemSubsetsResource.isLoading; + readonly error = computed( + () => this.#orderItemSubsetsResource.error()?.message ?? null, + ); + + loadOrderItemSubsets(orderItemSubsetIds: number[] | undefined) { + this.#orderItemSubsetIds.set(orderItemSubsetIds); + } + + refresh() { + this.#orderItemSubsetsResource.reload(); + } +} diff --git a/libs/oms/data-access/src/lib/schemas/display-order-item-subset.schema.ts b/libs/oms/data-access/src/lib/schemas/display-order-item-subset.schema.ts new file mode 100644 index 000000000..ca95ac225 --- /dev/null +++ b/libs/oms/data-access/src/lib/schemas/display-order-item-subset.schema.ts @@ -0,0 +1,51 @@ +import { EntitySchema, DateRangeSchema } from '@isa/common/data-access'; +import { z } from 'zod'; +import { OrderItemProcessingStatusValueSchema } from './order-item-processing-status-value.schema'; + +// Forward declaration for circular reference +export const DisplayOrderItemSubsetSchema = z + .object({ + compartmentCode: z.string().describe('Compartment code').optional(), + compartmentInfo: z.string().describe('Compartment information').optional(), + compartmentStart: z.string().describe('Compartment start').optional(), + compartmentStop: z.string().describe('Compartment stop').optional(), + description: z.string().describe('Description text').optional(), + estimatedDelivery: DateRangeSchema.describe( + 'Estimated delivery date range', + ).optional(), + estimatedShippingDate: z + .string() + .describe('Estimated shipping date') + .optional(), + orderItem: z + .lazy(() => z.any()) + .describe('Order item') + .optional(), // Circular reference to DisplayOrderItem + orderItemSubsetNumber: z + .string() + .describe('Order item subset number') + .optional(), + preferredPickUpDate: z + .string() + .describe('Preferred pick up date') + .optional(), + processingStatus: + OrderItemProcessingStatusValueSchema.describe('Processing status'), + processingStatusDate: z + .string() + .describe('Processing status date') + .optional(), + quantity: z.number().describe('Quantity').optional(), + specialComment: z.string().describe('Special comment').optional(), + ssc: z.string().describe('SSC code').optional(), + sscText: z.string().describe('SSC text').optional(), + supplierLabel: z.string().describe('Supplier label').optional(), + supplierName: z.string().describe('Supplier name').optional(), + supplyChannel: z.string().describe('Supply channel').optional(), + trackingNumber: z.string().describe('Tracking number').optional(), + }) + .extend(EntitySchema.shape); + +export type DisplayOrderItemSubset = z.infer< + typeof DisplayOrderItemSubsetSchema +>; diff --git a/libs/oms/data-access/src/lib/schemas/display-order-item.schema.ts b/libs/oms/data-access/src/lib/schemas/display-order-item.schema.ts index e269c7629..ca8d6540a 100644 --- a/libs/oms/data-access/src/lib/schemas/display-order-item.schema.ts +++ b/libs/oms/data-access/src/lib/schemas/display-order-item.schema.ts @@ -1,32 +1,33 @@ -import { EntitySchema, QuantityUnitTypeSchema } from '@isa/common/data-access'; -import { z } from 'zod'; -import { PriceSchema } from './price.schema'; -import { ProductSchema } from './product.schema'; -import { PromotionSchema } from './promotion.schema'; - -// Forward declaration for circular reference -export const DisplayOrderItemSchema = z - .object({ - buyerComment: z.string().describe('Buyer comment').optional(), - description: z.string().describe('Description text').optional(), - features: z.record(z.string().describe('Features'), z.string()).optional(), - order: z - .lazy(() => z.any()) - .describe('Order') - .optional(), // Circular reference to DisplayOrder - orderDate: z.string().describe('Order date').optional(), - orderItemNumber: z.string().describe('OrderItem number').optional(), - price: PriceSchema.describe('Price information').optional(), - product: ProductSchema.describe('Product').optional(), - promotion: PromotionSchema.describe('Promotion information').optional(), - quantity: z.number().describe('Quantity').optional(), - quantityUnit: z.string().describe('Quantity unit').optional(), - quantityUnitType: QuantityUnitTypeSchema.describe('QuantityUnit type'), - subsetItems: z - .array(z.lazy(() => z.any())) - .describe('Subset items') - .optional(), // Circular reference to DisplayOrderItemSubset - }) - .extend(EntitySchema.shape); - -export type DisplayOrderItem = z.infer; +import { EntitySchema, QuantityUnitTypeSchema } from '@isa/common/data-access'; +import { z } from 'zod'; +import { PriceSchema } from './price.schema'; +import { ProductSchema } from './product.schema'; +import { PromotionSchema } from './promotion.schema'; +import { DisplayOrderItemSubsetSchema } from './display-order-item-subset.schema'; + +// Forward declaration for circular reference +export const DisplayOrderItemSchema = z + .object({ + buyerComment: z.string().describe('Buyer comment').optional(), + description: z.string().describe('Description text').optional(), + features: z.record(z.string().describe('Features'), z.string()).optional(), + order: z + .lazy(() => z.any()) + .describe('Order') + .optional(), // Circular reference to DisplayOrder + orderDate: z.string().describe('Order date').optional(), + orderItemNumber: z.string().describe('OrderItem number').optional(), + price: PriceSchema.describe('Price information').optional(), + product: ProductSchema.describe('Product').optional(), + promotion: PromotionSchema.describe('Promotion information').optional(), + quantity: z.number().describe('Quantity').optional(), + quantityUnit: z.string().describe('Quantity unit').optional(), + quantityUnitType: QuantityUnitTypeSchema.describe('QuantityUnit type'), + subsetItems: z + .array(DisplayOrderItemSubsetSchema) + .describe('Subset items') + .optional(), + }) + .extend(EntitySchema.shape); + +export type DisplayOrderItem = z.infer; diff --git a/libs/oms/data-access/src/lib/schemas/fetch-order-item-subset.schema.ts b/libs/oms/data-access/src/lib/schemas/fetch-order-item-subset.schema.ts new file mode 100644 index 000000000..a591fd929 --- /dev/null +++ b/libs/oms/data-access/src/lib/schemas/fetch-order-item-subset.schema.ts @@ -0,0 +1,9 @@ +import z from 'zod'; + +export const FetchOrderItemSubsetSchema = z.object({ + orderItemSubsetId: z.number(), +}); + +export type FetchOrderItemSubsetSchemaInput = z.infer< + typeof FetchOrderItemSubsetSchema +>; diff --git a/libs/oms/data-access/src/lib/schemas/index.ts b/libs/oms/data-access/src/lib/schemas/index.ts index 597f27d66..20c8d1cc7 100644 --- a/libs/oms/data-access/src/lib/schemas/index.ts +++ b/libs/oms/data-access/src/lib/schemas/index.ts @@ -17,3 +17,8 @@ export * from './return-receipt-values.schema'; export * from './shipping-type.schema'; export * from './terms-of-delivery.schema'; export * from './type-of-delivery.schema'; +export * from './loyalty-collect-type.schema'; +export * from './order-loyalty-collect.schema'; +export * from './fetch-order-item-subset.schema'; +export * from './display-order-item-subset.schema'; +export * from './order-item-processing-status-value.schema'; diff --git a/libs/oms/data-access/src/lib/schemas/loyalty-collect-type.schema.ts b/libs/oms/data-access/src/lib/schemas/loyalty-collect-type.schema.ts new file mode 100644 index 000000000..5214d23af --- /dev/null +++ b/libs/oms/data-access/src/lib/schemas/loyalty-collect-type.schema.ts @@ -0,0 +1,21 @@ +import z from 'zod'; + +export const LoyaltyCollectType = { + Collect: 0, + OutOfStock: 1, + Cancel: 2, +} as const; + +const ALL_FLAGS = Object.values(LoyaltyCollectType).reduce( + (a, b) => a | b, + 0, +); + +export const LoyaltyCollectTypeSchema = z + .nativeEnum(LoyaltyCollectType) + .refine((val) => (val & ALL_FLAGS) === val, { + message: 'Invalid loyalty collect type', + }) + .describe('Loyalty collect type'); + +export type LoyaltyCollectType = z.infer; diff --git a/libs/oms/data-access/src/lib/schemas/order-item-processing-status-value.schema.ts b/libs/oms/data-access/src/lib/schemas/order-item-processing-status-value.schema.ts new file mode 100644 index 000000000..f068d5b23 --- /dev/null +++ b/libs/oms/data-access/src/lib/schemas/order-item-processing-status-value.schema.ts @@ -0,0 +1,51 @@ +import z from 'zod'; + +export const OrderItemProcessingStatusValue = { + NotSet: 0, + NeuAngelegt1: 1, + NeuAngelegt2: 2, + NeuÜbernommen: 4, + Geparkt: 8, + Bestellt: 16, + VorbereitungVersand: 32, + Versendet: 64, + Eingetroffen: 128, + Abgeholt: 256, + StorniertKunde: 512, + Storniert: 1024, + StorniertLieferant: 2048, + NichtLieferbar: 4096, + Nachbestellt: 8192, + Zurückgegeben: 16384, + ZumDownloadVerfügbar: 32768, + Downloaded: 65536, + NichtAbgeholt: 131072, + AnsLagerNichtAbgeholt: 262144, + Angefragt: 524288, + WeitergeleitetIntern: 1048576, + Überfällig: 2097152, + Zugestellt: 4194304, + LieferantErmittelt: 8388608, + DerzeitNichtLieferbar: 16777216, + Reserviert: 33554432, + Zusammengestellt: 67108864, + Verpackt: 134217728, + Lieferschein: 268435456, +} as const; + +export const OrderItemProcessingStatusValueSchema = z.number().refine( + (val) => { + // Validate that the value is a valid combination of flags + const allFlags = Object.values( + OrderItemProcessingStatusValue, + ).reduce((acc, flag) => acc | flag, 0); + return (val & allFlags) === val; + }, + { + message: 'Invalid order item processing status value', + }, +); + +export type OrderItemProcessingStatusValue = z.infer< + typeof OrderItemProcessingStatusValueSchema +>; diff --git a/libs/oms/data-access/src/lib/schemas/order-loyalty-collect.schema.ts b/libs/oms/data-access/src/lib/schemas/order-loyalty-collect.schema.ts new file mode 100644 index 000000000..4af718f4a --- /dev/null +++ b/libs/oms/data-access/src/lib/schemas/order-loyalty-collect.schema.ts @@ -0,0 +1,14 @@ +import z from 'zod'; +import { LoyaltyCollectTypeSchema } from './loyalty-collect-type.schema'; + +export const OrderLoyaltyCollectSchema = z.object({ + orderId: z.number(), + orderItemId: z.number(), + orderItemSubsetId: z.number(), + collectType: LoyaltyCollectTypeSchema, + quantity: z.number().int().nonnegative(), +}); + +export type OrderLoyaltyCollectInput = z.infer< + typeof OrderLoyaltyCollectSchema +>; diff --git a/libs/oms/data-access/src/lib/services/index.ts b/libs/oms/data-access/src/lib/services/index.ts index c5e93e301..38b663f69 100644 --- a/libs/oms/data-access/src/lib/services/index.ts +++ b/libs/oms/data-access/src/lib/services/index.ts @@ -8,3 +8,4 @@ export * from './return-details.service'; export * from './return-process.service'; export * from './return-search.service'; export * from './return-task-list.service'; +export * from './order-reward-collect.service'; diff --git a/libs/oms/data-access/src/lib/services/order-reward-collect.service.spec.ts b/libs/oms/data-access/src/lib/services/order-reward-collect.service.spec.ts new file mode 100644 index 000000000..5da808ca1 --- /dev/null +++ b/libs/oms/data-access/src/lib/services/order-reward-collect.service.spec.ts @@ -0,0 +1,111 @@ +import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; +import { OrderRewardCollectService } from './order-reward-collect.service'; +import { + OrderService, + DBHOrderItemListItemDTO, +} from '@generated/swagger/oms-api'; +import { of } from 'rxjs'; + +describe('OrderRewardCollectService', () => { + let spectator: SpectatorService; + const createService = createServiceFactory({ + service: OrderRewardCollectService, + mocks: [OrderService], + }); + + beforeEach(() => { + spectator = createService(); + }); + + it('should be created', () => { + expect(spectator.service).toBeTruthy(); + }); + + describe('collect', () => { + it('should collect reward item successfully', async () => { + // Arrange + const mockParams = { + orderId: 123, + orderItemId: 456, + orderItemSubsetId: 789, + collectType: 1 as const, // Valid LoyaltyCollectType.Collect + quantity: 2, + }; + const mockResult: DBHOrderItemListItemDTO[] = [ + { orderItemType: 1 } as DBHOrderItemListItemDTO, + ]; + const mockResponse = { result: mockResult, error: false }; + const orderService = spectator.inject(OrderService); + orderService.OrderLoyaltyCollect.mockReturnValue(of(mockResponse)); + + // Act + const result = await spectator.service.collect(mockParams); + + // Assert + expect(result).toEqual(mockResult); + expect(orderService.OrderLoyaltyCollect).toHaveBeenCalledWith({ + orderId: mockParams.orderId, + orderItemId: mockParams.orderItemId, + orderItemSubsetId: mockParams.orderItemSubsetId, + data: { + collectType: mockParams.collectType, + quantity: mockParams.quantity, + }, + }); + expect(orderService.OrderLoyaltyCollect).toHaveBeenCalledTimes(1); + }); + + it('should throw error if API response contains error', async () => { + // Arrange + const mockParams = { + orderId: 123, + orderItemId: 456, + orderItemSubsetId: 789, + collectType: 1 as const, // Valid LoyaltyCollectType.Collect + quantity: 2, + }; + const mockResponse = { error: true, result: undefined }; + const orderService = spectator.inject(OrderService); + orderService.OrderLoyaltyCollect.mockReturnValue(of(mockResponse)); + + // Act & Assert + await expect(spectator.service.collect(mockParams)).rejects.toThrow(); + expect(orderService.OrderLoyaltyCollect).toHaveBeenCalledWith({ + orderId: mockParams.orderId, + orderItemId: mockParams.orderItemId, + orderItemSubsetId: mockParams.orderItemSubsetId, + data: { + collectType: mockParams.collectType, + quantity: mockParams.quantity, + }, + }); + }); + }); + + describe('fetchOrderItemSubset', () => { + it('should fetch order item subset successfully', async () => { + // Arrange + const mockParams = { + orderItemSubsetId: 789, + }; + const mockResult = { + id: 789, + quantity: 2, + name: 'Test Subset', + }; + const mockResponse = { result: mockResult, error: false }; + const orderService = spectator.inject(OrderService); + orderService.OrderGetOrderItemSubset.mockReturnValue(of(mockResponse)); + + // Act + const result = await spectator.service.fetchOrderItemSubset(mockParams); + + // Assert + expect(result).toEqual(mockResult); + expect(orderService.OrderGetOrderItemSubset).toHaveBeenCalledWith( + mockParams.orderItemSubsetId, + ); + expect(orderService.OrderGetOrderItemSubset).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/libs/oms/data-access/src/lib/services/order-reward-collect.service.ts b/libs/oms/data-access/src/lib/services/order-reward-collect.service.ts new file mode 100644 index 000000000..9fabc74dc --- /dev/null +++ b/libs/oms/data-access/src/lib/services/order-reward-collect.service.ts @@ -0,0 +1,77 @@ +import { inject, Injectable } from '@angular/core'; +import { OrderService } from '@generated/swagger/oms-api'; +import { ResponseArgsError, takeUntilAborted } from '@isa/common/data-access'; +import { logger } from '@isa/core/logging'; +import { firstValueFrom } from 'rxjs'; +import { + DisplayOrderItemSubset, + FetchOrderItemSubsetSchema, + FetchOrderItemSubsetSchemaInput, + OrderLoyaltyCollectInput, + OrderLoyaltyCollectSchema, +} from '../schemas'; + +@Injectable({ providedIn: 'root' }) +export class OrderRewardCollectService { + #logger = logger(() => ({ service: 'OrderRewardCollectService' })); + #orderService = inject(OrderService); + + async collect(params: OrderLoyaltyCollectInput) { + try { + params = OrderLoyaltyCollectSchema.parse(params); + } catch (error) { + this.#logger.error('Failed to parse schema', error); + throw error; + } + + const req$ = this.#orderService.OrderLoyaltyCollect({ + orderId: params.orderId, + orderItemId: params.orderItemId, + orderItemSubsetId: params.orderItemSubsetId, + data: { + collectType: params.collectType, + quantity: params.quantity, + }, + }); + + const res = await firstValueFrom(req$); + + if (res.error) { + const error = new ResponseArgsError(res); + this.#logger.error('Failed to collect reward item', error); + throw error; + } + + return res.result; + } + + async fetchOrderItemSubset( + params: FetchOrderItemSubsetSchemaInput, + abortSignal?: AbortSignal, + ) { + try { + params = FetchOrderItemSubsetSchema.parse(params); + } catch (error) { + this.#logger.error('Failed to parse schema', error); + throw error; + } + + let req$ = this.#orderService.OrderGetOrderItemSubset( + params.orderItemSubsetId, + ); + + if (abortSignal) { + req$ = req$.pipe(takeUntilAborted(abortSignal)); + } + + const res = await firstValueFrom(req$); + + if (res.error) { + const error = new ResponseArgsError(res); + this.#logger.error('Failed to fetch order item subset', error); + throw error; + } + + return res.result as DisplayOrderItemSubset; + } +} diff --git a/package-lock.json b/package-lock.json index a3aa4427e..4933d8cd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -364,7 +364,6 @@ "integrity": "sha512-qEt+M6UAuBUD8lrhmHFFpaKYVeANfVrgZijkebfdDJtQybNL/2bVypJCX7D60XHC2weKHSrp8f18uhmNnvjeGg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ts-morph": "^21.0.0", "vfile": "^6.0.3" @@ -429,7 +428,6 @@ "integrity": "sha512-VtXxfJzrBZ8MQN83shXNaTUaLSOIwa+4/3LD5drxSnHuYJrz+d3FIApWAxcA9QzucsTDZwXyFxaWZN/e5XVm6g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@angular-devkit/core": "20.3.6", "rxjs": "7.8.2" @@ -446,7 +444,6 @@ "integrity": "sha512-yCybq8Lh6PnuN5oa81qFDmHjV/MMB1tOY99NU6N/DM4IcbGdyS8IFEeVvM3ohz6bTnqvkmi3rSxWs1jDWvm5/Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "2.3.0", "@angular-devkit/architect": "0.2003.6", @@ -600,7 +597,6 @@ "integrity": "sha512-uLRk3865Iz/EO9Zm/mrFfdyoZinJBihXE6HVDYRYjAqsgW14LsD8pkpWy9+LYlOwcH96Ndnev+msxaTJaNXtPg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ajv": "8.17.1", "ajv-formats": "3.0.1", @@ -629,7 +625,6 @@ "integrity": "sha512-QD7QS1oR0XcZ9ZI4D1c4JjKmSn2up/ocOU2FS1mMO7S5RtAZMsPv4J3r+6ywHA2ev2sRySOQ0D8OYBcEuYX9Jw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@angular-devkit/core": "20.3.6", "jsonc-parser": "3.3.1", @@ -744,7 +739,6 @@ "integrity": "sha512-5Vyo/VJ1DrIsAkudFpZj1f7CpCLYuiTzTQksHTiZE18iYsLKRkEC7y9S6+TiHrdD96rhNxL28Pz9FDU4lIBjkw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@angular-eslint/bundled-angular-compiler": "20.4.0", "eslint-scope": "^8.0.2" @@ -774,7 +768,6 @@ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.6.tgz", "integrity": "sha512-qNaVvEOKvigoCQMg0ABnq44HhiHqKD4WN3KoUcXneklcMYCzFE5nuQxKylfWzCRiI5XqiJ9pqiL1m2D7o+Vdiw==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -791,7 +784,6 @@ "integrity": "sha512-O5qyxCCe77tu1zy9XudKxqFqi5zih0ZI8J8Anra/ZZdtTKbLMprXMGFzMYzwCqvcIzzbmOumkSJKoXbFazHaaw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "2.3.0", "@angular-devkit/architect": "0.2003.6", @@ -885,6 +877,18 @@ } } }, + "node_modules/@angular/build/node_modules/@types/node": { + "version": "24.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz", + "integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "undici-types": "~7.16.0" + } + }, "node_modules/@angular/build/node_modules/vite": { "version": "7.1.5", "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.5.tgz", @@ -998,7 +1002,6 @@ "integrity": "sha512-1RozAub7Gcl5ES3vBYatIgoMDgujlvySwHARoYT+1VhbYvM0RTt4sn2aDhHxqG0GcyiXR5zISkzJvldaY2nQCQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@angular-devkit/architect": "0.2003.6", "@angular-devkit/core": "20.3.6", @@ -1033,7 +1036,6 @@ "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.6.tgz", "integrity": "sha512-+gHMuFe0wz4f+vfGZ2q+fSQSYaY7KlN7QdDrFqLnA7H2sythzhXvRbXEtp4DkPjihh9gupXg2MeLh1ROy5AfSw==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1050,7 +1052,6 @@ "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.6.tgz", "integrity": "sha512-OdjXBsAsnn7qiW6fSHClwn9XwjVxhtO9+RbDc6Mf+YPCnJq0s8T78H2fc8VdJFp/Rs+tMZcwwjd9VZPm8+2XWA==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1063,7 +1064,6 @@ "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.6.tgz", "integrity": "sha512-VOFRBx9fBt2jW9I8qD23fwGeKxBI8JssJBAMqnFPl3k59VJWHQi6LlXZCLCBNdfwflTJdKeRvdgT51Q0k6tnFQ==", "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "7.28.3", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -1096,7 +1096,6 @@ "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.6.tgz", "integrity": "sha512-sDURQWnjwE4Y750u/5qwkZEYMoI4CrKghnx4aKulxCnohR3//C78wvz6p8MtCuqYfzGkdQZDYFg8tgAz17qgPw==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1122,7 +1121,6 @@ "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.6.tgz", "integrity": "sha512-tBGo/LBtCtSrClMY4DTm/3UiSjqLLMEYXS/4E0nW1mFDv7ulKnaAQB+KbfBmmTHYxlKLs+SxjKv6GoydMPSurA==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1151,7 +1149,6 @@ "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-20.3.6.tgz", "integrity": "sha512-isOHiGYHSK+ySK8ry21PGO3jpJpF90E3J2BZ+LUhzpi1SzFBguEVg7j8fvbCLodiwweOnuAiKEHO0F3WpfCQ9Q==", "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "7.28.3", "@types/babel__core": "7.20.5", @@ -1176,7 +1173,6 @@ "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.6.tgz", "integrity": "sha512-gFp1yd+HtRN8XdpMatRLO5w6FLIzsnF31lD2Duo4BUTCoMAMdfaNT6FtcvNdKu7ANo27Ke26fxEEE2bh6FU98A==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1199,7 +1195,6 @@ "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.6.tgz", "integrity": "sha512-teO8tBygk6vD1waiLmHGXtXPF/9a9Bw2XI+s550KtJlQqRpr7IUWOFPPQik/uGkppv5Jrv6fP+8mh9QX9zoWnQ==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1243,7 +1238,6 @@ "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.6.tgz", "integrity": "sha512-fSAYOR9nKpH5PoBYFNdII3nAFl2maUrYiISU33CnGwb7J7Q0s09k231c/P5tVN4URi+jdADVwiBI8cIYk8SVrg==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1262,7 +1256,6 @@ "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-20.3.6.tgz", "integrity": "sha512-utHJCoEO4EKH372BSMnNbcR96yDVkUeV7xcJb+cw9ruTOxGvCG/DUWR1h64xk3Ns6nvFmggTnIVgnBDn+92VpQ==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1305,7 +1298,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz", "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -3722,9 +3714,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { @@ -4219,7 +4211,6 @@ "integrity": "sha512-nqhDw2ZcAUrKNPwhjinJny903bRhI0rQhiDz1LksjeRxqa36i3l75+4iXbOy0rlDpLJGxqtgoPavQjmmyS5UJw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@inquirer/checkbox": "^4.2.1", "@inquirer/confirm": "^5.1.14", @@ -6427,6 +6418,117 @@ "win32" ] }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@mdx-js/react": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", @@ -7133,7 +7235,6 @@ "integrity": "sha512-YEdHA/rXlydI+ecmsidM0imAhAgyN+fSCOWRJtm72Kx10J6kS2tN1/Zah/hf9C9Msj9OOl0w22aOo7/Sy0qRqg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@module-federation/bridge-react-webpack-plugin": "0.17.1", "@module-federation/cli": "0.17.1", @@ -7470,7 +7571,6 @@ "integrity": "sha512-uQmammw3Osg8370yiRqZwKo7eA5zkyml9pAX9x4oS9QAkEBvQpDogERlF9f7gAgcP2P3v+xLg3/bCdquD0gt8A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@module-federation/runtime": "0.21.1", "@module-federation/webpack-bundler-runtime": "0.21.1" @@ -7718,7 +7818,6 @@ "integrity": "sha512-4kr6zTFFwGywJx6whBtxsc84V+COAuuBpEdEbPZN//YLXhNB0iz2IGsy9r9wDl+06h84bD+3dQ05l9euRLgXzQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@module-federation/runtime": "0.17.1", "@module-federation/webpack-bundler-runtime": "0.17.1" @@ -8290,7 +8389,6 @@ "resolved": "https://registry.npmjs.org/@ngrx/signals/-/signals-20.0.1.tgz", "integrity": "sha512-7YYPH4nTkmLEgibJnwi527toEm3tsnlCzp5AzT9osS8JxN9cHxkG6iQ7fzhw9N4bTt+8wyUZb7PF0YLFYD2RHA==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -8309,7 +8407,6 @@ "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-20.0.1.tgz", "integrity": "sha512-SWIHKe9lBoNf4rOklaWbCRAz8ie1Duf1iL4SMe6BipqhdUfJ/pEbcz3xMQUIlv1CciHhRgMJFTzFrDxamYHknQ==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.0.0" }, @@ -10422,7 +10519,6 @@ "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", @@ -11630,7 +11726,6 @@ "integrity": "sha512-sUd2LfiDhqYVfvknuoz0+/c+wSpn693xotnG5g1CSWKZArbtwiYzBIVnNlcHGmuoBRsnj/TkSq8dTQ7gwfBroQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@module-federation/runtime-tools": "0.18.0", "@rspack/binding": "1.5.8", @@ -11874,7 +11969,6 @@ "integrity": "sha512-YPIEyKPBOyJYlda5fA49kMThzZ4WidomEMDghshux8xidbjDaPWBZdyVPQj3IXyW0teGlUM/TH0TH2weumMZrg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@angular-devkit/core": "20.3.6", "@angular-devkit/schematics": "20.3.6", @@ -12142,7 +12236,6 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -12558,7 +12651,6 @@ "dev": true, "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.23" @@ -12784,7 +12876,6 @@ "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@swc/counter": "^0.1.3" } @@ -12795,7 +12886,6 @@ "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -13128,7 +13218,6 @@ "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -13339,8 +13428,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.9.tgz", "integrity": "sha512-IeB32oIV4oGArLrd7znD2rkHQ6EDCM+2Sr76dJnrHwv9OHBTTM6nuDLK9bmikXzPa0ZlWMWtRGo/Uw4mrzQedA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/node-forge": { "version": "1.3.14", @@ -13564,7 +13652,6 @@ "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/types": "8.46.2", @@ -13672,7 +13759,6 @@ "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -13732,7 +13818,6 @@ "integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.2", @@ -14234,7 +14319,6 @@ "integrity": "sha512-hGISOaP18plkzbWEcP/QvtRW1xDXF2+96HbEX6byqQhAUbiS5oH6/9JwW+QsQCIYON2bI6QZBF+2PvOmrRZ9wA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/utils": "3.2.4", "fflate": "^0.8.2", @@ -14468,7 +14552,6 @@ "integrity": "sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -14526,7 +14609,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -14646,7 +14728,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -14860,6 +14941,32 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/aproba": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", + "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", @@ -15608,7 +15715,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.9", "caniuse-lite": "^1.0.30001746", @@ -15951,6 +16057,24 @@ ], "license": "CC-BY-4.0" }, + "node_modules/canvas": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz", + "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.17.0", + "simple-get": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/case-sensitive-paths-webpack-plugin": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", @@ -16024,7 +16148,6 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "license": "MIT", - "peer": true, "dependencies": { "readdirp": "^4.0.1" }, @@ -16359,6 +16482,18 @@ "dev": true, "license": "MIT" }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "color-support": "bin.js" + } + }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -16525,6 +16660,15 @@ "node": ">=0.8" } }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, "node_modules/content-disposition": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", @@ -18005,6 +18149,21 @@ "dev": true, "license": "MIT" }, + "node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/dedent": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", @@ -18546,7 +18705,6 @@ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "iconv-lite": "^0.6.2" } @@ -18748,7 +18906,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -18790,7 +18947,6 @@ "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -18879,7 +19035,6 @@ "integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -18940,7 +19095,6 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -19329,7 +19483,6 @@ "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", @@ -19931,7 +20084,6 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -20265,6 +20417,77 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, + "node_modules/gauge/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/generator-function": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", @@ -20734,6 +20957,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -20920,7 +21152,6 @@ "integrity": "sha512-V/PZeWsqhfpE27nKeX9EO2sbR+D17A+tLf6qU+ht66jdUsN0QLKJN27Z+1+gHrVMKgndBahes0PU6rRihDgHTw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", "html-minifier-terser": "^6.0.2", @@ -21919,7 +22150,6 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -23579,7 +23809,6 @@ "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -26786,7 +27015,6 @@ "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jiti": "lib/jiti-cli.mjs" } @@ -26847,7 +27075,6 @@ "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "abab": "^2.0.6", "cssstyle": "^3.0.0", @@ -27399,7 +27626,6 @@ "integrity": "sha512-kdTwsyRuncDfjEs0DlRILWNvxhDG/Zij4YLO4TMJgDLW+8OzpfkdPnRgrsRuY1o+oaxJGWsps5f/RVBgGmmN0w==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -27567,7 +27793,6 @@ "integrity": "sha512-SL0JY3DaxylDuo/MecFeiC+7pedM0zia33zl0vcjgwcq1q1FWWF1To9EIauPbl8GbMCU0R2e0uJ8bZunhYKD2g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", @@ -28305,6 +28530,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -28660,6 +28900,15 @@ "thenify-all": "^1.0.0" } }, + "node_modules/nan": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz", + "integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -28780,7 +29029,6 @@ "integrity": "sha512-hwPZNeV/6C3pWojK70AHxe6uk1rz2bzoe+WdH+GIWouUcyXrjYQjOFyLfOGD0ia9D+yWVzjsi4CKVK/dQFDQ6Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.3.0", "@rollup/plugin-json": "^6.1.0", @@ -29364,6 +29612,22 @@ "node": ">=8" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -29391,7 +29655,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "dependencies": { "@napi-rs/wasm-runtime": "0.2.4", "@yarnpkg/lockfile": "^1.1.0", @@ -30640,7 +30903,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -31535,7 +31797,6 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -31888,7 +32149,6 @@ "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -31899,7 +32159,6 @@ "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -32412,6 +32671,77 @@ "dev": true, "license": "MIT" }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/roarr": { "version": "2.15.4", "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", @@ -32436,7 +32766,6 @@ "integrity": "sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -32569,7 +32898,6 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "license": "Apache-2.0", - "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -33132,7 +33460,6 @@ "resolved": "https://registry.npmjs.org/scandit-web-datacapture-core/-/scandit-web-datacapture-core-6.28.6.tgz", "integrity": "sha512-D7rC+SWWG0XoZVo+LNlvpJi8+sxsylhn5zvzfDGhrDI6zTAT812HNgoGJDjNNZTZ8iaS5/dYg8LU5b+N4MLsZQ==", "license": "SEE LICENSE IN LICENSE", - "peer": true, "dependencies": { "@types/howler": "^2.2.11", "@types/js-cookie": "^2.2.6", @@ -33462,6 +33789,15 @@ "node": ">= 18" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, "node_modules/set-cookie-parser": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", @@ -33659,6 +33995,20 @@ "license": "MIT", "optional": true }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/sirv": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", @@ -34017,7 +34367,6 @@ "integrity": "sha512-G3KZ36EVzXyHds72B/qtWiJnhUpM0xOUeYlDcO9DSHL1bDTv15cW4+upBl+mcBZrDvU838cn7Bv4GpF+O5MCfw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@storybook/global": "^5.0.0", "@testing-library/jest-dom": "^6.6.3", @@ -34357,7 +34706,6 @@ "integrity": "sha512-ZIdT8eUv8tegmqy1tTIdJv9We2DumkNZFdCF5mz/Kpq3OcTaxSuCAYZge6HKK2CmNC02G1eJig2RV7XTw5hQrA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@adobe/css-tools": "~4.3.3", "debug": "^4.3.2", @@ -34588,7 +34936,6 @@ "integrity": "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -34665,7 +35012,6 @@ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -34909,7 +35255,6 @@ "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.14.0", @@ -35543,7 +35888,6 @@ "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -35650,8 +35994,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "peer": true + "license": "0BSD" }, "node_modules/tsscmp": { "version": "1.0.6", @@ -35765,7 +36108,6 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "devOptional": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -35780,7 +36122,6 @@ "integrity": "sha512-vbw8bOmiuYNdzzV3lsiWv6sRwjyuKJMQqWulBOU7M0RrxedXledX8G8kBbQeiOYDnTfiXz0Y4081E1QMNB6iQg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/eslint-plugin": "8.46.2", "@typescript-eslint/parser": "8.46.2", @@ -35845,7 +36186,8 @@ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "dev": true, "license": "MIT", - "optional": true + "optional": true, + "peer": true }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", @@ -36216,7 +36558,6 @@ "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -36315,7 +36656,6 @@ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", @@ -36562,7 +36902,6 @@ "integrity": "sha512-4JLXU0tD6OZNVqlwzm3HGEhAHufSiyv+skb7q0d2367VDMzrU1Q/ZeepvkcHH0rZie6uqEtTQQe0OEOOluH3Mg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -36684,7 +37023,6 @@ "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", @@ -37206,7 +37544,6 @@ "integrity": "sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-html-community": "0.0.8", "html-entities": "^2.1.0", @@ -37439,6 +37776,56 @@ "node": ">=8" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wide-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/wide-align/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wildcard": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", @@ -37587,7 +37974,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=8.3.0" }, @@ -37675,7 +38061,6 @@ "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", "dev": true, "license": "ISC", - "peer": true, "bin": { "yaml": "bin.mjs" }, @@ -37863,7 +38248,6 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -37882,8 +38266,7 @@ "version": "0.15.1", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==", - "license": "MIT", - "peer": true + "license": "MIT" } } }