Added new models and schemas for gender, address type, and shipping type.

-  **Feature**: Introduced Gender, AddressType, and ShippingType enums
- 🗑️ **Chore**: Removed obsolete schemas and service files from return feature
- 🛠️ **Refactor**: Updated index files to export new models
This commit is contained in:
Lorenz Hilpert
2025-04-03 11:53:27 +02:00
parent 0dee30062f
commit 81a7154470
68 changed files with 797 additions and 1195 deletions

View File

@@ -55,7 +55,7 @@ High-priority issues that must be addressed immediately due to their potential t
### 1. High Priority: [Issue Title] ### 1. High Priority: [Issue Title]
#### 🎯 Issue #### 🚨 Issue
Describe the issue clearly, including links to specific files and lines (e.g., file.js#L10). Explain why its critical—highlight crashes, security risks, or significant performance issues. Describe the issue clearly, including links to specific files and lines (e.g., file.js#L10). Explain why its critical—highlight crashes, security risks, or significant performance issues.
@@ -65,9 +65,16 @@ Provide specific steps or alternative approaches to resolve the issue.
#### ✨ Code Example #### ✨ Code Example
**Current**: [file](file.js#L10) Problematic code with path to the file and line of the code
```typescript ```typescript
// Before: Problematic code // Code...
// After: Improved version ```
**Improvement**: Improved version
```typescript
// Code...
``` ```
#### 📚 Relevant Documentation #### 📚 Relevant Documentation
@@ -92,9 +99,16 @@ Offer concrete steps or alternative approaches to mitigate the issue.
#### ✨ Code Example #### ✨ Code Example
**Current**: [file](file.js#L10) Problematic code with path to the file and line of the code
```typescript ```typescript
// Before: Problematic code // Code...
// After: Improved version ```
**Improvement**: Improved version
```typescript
// Code...
``` ```
#### 📚 Relevant Documentation #### 📚 Relevant Documentation
@@ -119,9 +133,16 @@ Provide suggestions or alternative implementations to mitigate the issue.
#### ✨ Code Example #### ✨ Code Example
**Current**: [file](file.js#L10) Problematic code with path to the file and line of the code
```typescript ```typescript
// Before: Problematic code // Code...
// After: Improved version ```
**Improvement**: Improved version
```typescript
// Code...
``` ```
#### 📚 Relevant Documentation #### 📚 Relevant Documentation
@@ -130,9 +151,20 @@ Include relevant resources for more information.
--- ---
## 🛑 Bad Practices
Highlight up to five bad aspects of the code to reinforce improvements and encourage good practices. Use different funny emoji at the beginning of each bad practice.
- Emoji **Bad Practice 1**:
Describe a specific weakness (e.g., clear code structure) with an example reference (e.g., file.js#L20). Explain why its bad.
- Emoji **Bad Practice 2**:
Outline another negative feature (e.g., effective error handling) with a snippet reference.
---
## ✅ Good Practices ## ✅ Good Practices
Highlight one up to five positive aspects of the code to reinforce well-implemented patterns and encourage good practices. Use different funny emoji at the beginning of each good practice. Highlight up to five positive aspects of the code to reinforce well-implemented patterns and encourage good practices. Use different funny emoji at the beginning of each good practice.
- Emoji **Good Practice 1**: - Emoji **Good Practice 1**:
Describe a specific strength (e.g., clear code structure) with an example reference (e.g., file.js#L20). Explain why its commendable. Describe a specific strength (e.g., clear code structure) with an example reference (e.g., file.js#L20). Explain why its commendable.

View File

@@ -1,4 +1,5 @@
export * from './lib/response-args.schema'; export * from './lib/response-args.schema';
export * from './lib/response-args';
export * from './lib/entity-cotnainer'; export * from './lib/entity-cotnainer';
export * from './lib/entity-container.schema'; export * from './lib/entity-container.schema';
export * from './lib/result'; export * from './lib/result';

View File

@@ -1,24 +1,28 @@
import { z } from 'zod'; import { z } from 'zod';
// @deprecated
export const ResponseArgsSchema = z.object({ export const ResponseArgsSchema = z.object({
error: z.boolean(), error: z.boolean(),
invalidProperties: z.record(z.string()), invalidProperties: z.record(z.string()),
message: z.string().optional(), message: z.string().optional(),
}); });
export function ResponseArgs<T>(resultSchema: z.ZodType<T>) { // @deprecated
export function CreateResponseArgs<T>(resultSchema: z.ZodType<T>) {
return ResponseArgsSchema.extend({ return ResponseArgsSchema.extend({
result: resultSchema, result: resultSchema,
}); });
} }
// @deprecated
const ListResponseArgsSchema = ResponseArgsSchema.extend({ const ListResponseArgsSchema = ResponseArgsSchema.extend({
skip: z.number(), skip: z.number(),
take: z.number(), take: z.number(),
hits: z.number(), hits: z.number(),
}); });
export function ListResponseArgs<T>(resultSchema: z.ZodType<T>) { // @deprecated
export function CreateListResponseArgs<T>(resultSchema: z.ZodType<T>) {
return ListResponseArgsSchema.extend({ return ListResponseArgsSchema.extend({
result: resultSchema.array(), result: resultSchema.array(),
}); });

View File

@@ -0,0 +1,12 @@
export interface ResponseArgs<T> {
error: boolean;
invalidProperties: Record<string, string>;
message?: string;
result: T;
}
export interface ListResponseArgs<T> extends ResponseArgs<T[]> {
skip: number;
take: number;
hits: number;
}

View File

@@ -1,8 +1,8 @@
import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core'; import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
import { isaActionChevronDown, isaNavigationKunden } from '@isa/icons'; import { isaActionChevronDown, isaNavigationKunden } from '@isa/icons';
import { Buyer } from '@isa/oms/data-access';
import { InfoButtonComponent } from '@isa/ui/buttons'; import { InfoButtonComponent } from '@isa/ui/buttons';
import { NgIconComponent, provideIcons } from '@ng-icons/core'; import { NgIconComponent, provideIcons } from '@ng-icons/core';
import { Buyer } from '@feature/return/services';
@Component({ @Component({
selector: 'lib-return-details-header', selector: 'lib-return-details-header',

View File

@@ -1,17 +1,12 @@
import { DatePipe } from "@angular/common"; import { DatePipe } from '@angular/common';
import { import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
ChangeDetectionStrategy, import { ReceiptListItem } from '@isa/oms/data-access';
Component, import { ClientRowImports, ItemRowDataImports } from '@isa/ui/item-rows';
computed,
input,
} from "@angular/core";
import { ReceiptListItem } from "@feature/return/services";
import { ClientRowImports, ItemRowDataImports } from "@isa/ui/item-rows";
@Component({ @Component({
selector: "lib-return-results-item-list", selector: 'lib-return-results-item-list',
templateUrl: "./return-results-item-list.component.html", templateUrl: './return-results-item-list.component.html',
styleUrls: ["./return-results-item-list.component.css"], styleUrls: ['./return-results-item-list.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true, standalone: true,
imports: [ClientRowImports, ItemRowDataImports, DatePipe], imports: [ClientRowImports, ItemRowDataImports, DatePipe],
@@ -23,13 +18,9 @@ export class ReturnResultsItemListComponent {
const firstName = this.item()?.billing?.person?.firstName; const firstName = this.item()?.billing?.person?.firstName;
const lastName = this.item()?.billing?.person?.lastName; const lastName = this.item()?.billing?.person?.lastName;
const buyerName = [lastName, firstName].filter((f) => !!f); const buyerName = [lastName, firstName].filter((f) => !!f);
const organisation = [this.item()?.billing?.organisation?.name].filter( const organisation = [this.item()?.billing?.organisation?.name].filter((f) => !!f);
(f) => !!f,
);
return [organisation.join(), buyerName.join(" ")] return [organisation.join(), buyerName.join(' ')].filter((f) => !!f).join(' - ');
.filter((f) => !!f)
.join(" - ");
}); });
receiptDate = computed(() => { receiptDate = computed(() => {
@@ -50,6 +41,6 @@ export class ReturnResultsItemListComponent {
address = computed(() => { address = computed(() => {
const address = this.item()?.billing?.address; const address = this.item()?.billing?.address;
return address ? [address.zipCode, address.city].join(" ") : ""; return address ? [address.zipCode, address.city].join(' ') : '';
}); });
} }

View File

@@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core'; import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { ReturnSearchStatus, ReturnSearchStore } from '@feature/return/services';
import { injectActivatedProcessId } from '@isa/core/process'; import { injectActivatedProcessId } from '@isa/core/process';
import { ReturnSearchStatus, ReturnSearchStore } from '@isa/oms/data-access';
import { import {
FilterService, FilterService,
SearchBarInputComponent, SearchBarInputComponent,

View File

@@ -1,7 +1,7 @@
import { inject } from '@angular/core'; import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router'; import { ResolveFn } from '@angular/router';
import { ReturnSearchService } from '@feature/return/services';
import { QuerySettingsDTO } from '@generated/swagger/oms-api'; import { QuerySettingsDTO } from '@generated/swagger/oms-api';
import { ReturnSearchService } from '@isa/oms/data-access';
export const querySettingsResolverFn: ResolveFn<QuerySettingsDTO> = () => export const querySettingsResolverFn: ResolveFn<QuerySettingsDTO> = () =>
inject(ReturnSearchService).querySettings(); inject(ReturnSearchService).querySettings();

View File

@@ -14,11 +14,7 @@ import {
ReturnOrderByListComponent, ReturnOrderByListComponent,
} from '@feature/return/containers'; } from '@feature/return/containers';
import { injectActivatedProcessId } from '@isa/core/process'; import { injectActivatedProcessId } from '@isa/core/process';
import {
ReturnSearchEntity,
ReturnSearchStatus,
ReturnSearchStore,
} from '@feature/return/services';
import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { import {
FilterMenuButtonComponent, FilterMenuButtonComponent,
@@ -31,6 +27,7 @@ import { restoreScrollPosition } from '@isa/core/scroll-position';
import { Platform } from '@angular/cdk/platform'; import { Platform } from '@angular/cdk/platform';
import { NgIconComponent, provideIcons } from '@ng-icons/core'; import { NgIconComponent, provideIcons } from '@ng-icons/core';
import { isaActionSort } from '@isa/icons'; import { isaActionSort } from '@isa/icons';
import { ReturnSearchEntity, ReturnSearchStatus, ReturnSearchStore } from '@isa/oms/data-access';
type EmptyState = { type EmptyState = {
title: string; title: string;

View File

@@ -1,8 +1,8 @@
import { Component, effect, inject, untracked } from '@angular/core'; import { Component, effect, inject, untracked } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop'; import { toSignal } from '@angular/core/rxjs-interop';
import { ActivatedRoute, Router, RouterOutlet } from '@angular/router'; import { ActivatedRoute, Router, RouterOutlet } from '@angular/router';
import { ReturnSearchStore } from '@feature/return/services';
import { injectActivatedProcessId } from '@isa/core/process'; import { injectActivatedProcessId } from '@isa/core/process';
import { ReturnSearchStore } from '@isa/oms/data-access';
import { FilterService, provideQuerySettings } from '@isa/shared/filter'; import { FilterService, provideQuerySettings } from '@isa/shared/filter';
@Component({ @Component({
@@ -10,11 +10,7 @@ import { FilterService, provideQuerySettings } from '@isa/shared/filter';
imports: [RouterOutlet], imports: [RouterOutlet],
templateUrl: './return-pages.component.html', templateUrl: './return-pages.component.html',
styleUrl: './return-pages.component.css', styleUrl: './return-pages.component.css',
providers: [ providers: [provideQuerySettings(() => inject(ActivatedRoute).snapshot.data['querySettings'])],
provideQuerySettings(
() => inject(ActivatedRoute).snapshot.data['querySettings'],
),
],
}) })
export class ReturnPagesComponent { export class ReturnPagesComponent {
#route = inject(ActivatedRoute); #route = inject(ActivatedRoute);
@@ -56,10 +52,7 @@ export class ReturnPagesComponent {
if (items) { if (items) {
if (items?.length === 1) { if (items?.length === 1) {
return await this._navigateTo([ return await this._navigateTo(['receipt', items[0].id.toString()]);
'receipt',
items[0].id.toString(),
]);
} }
if (items?.length >= 0) { if (items?.length >= 0) {

View File

@@ -1,7 +0,0 @@
# feature-return-services
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test feature-return-services` to execute the unit tests.

View File

@@ -1,34 +0,0 @@
import nx from '@nx/eslint-plugin';
import baseConfig from '../../../../eslint.config.mjs';
export default [
...baseConfig,
...nx.configs['flat/angular'],
...nx.configs['flat/angular-template'],
{
files: ['**/*.ts'],
rules: {
'@angular-eslint/directive-selector': [
'error',
{
type: 'attribute',
prefix: 'lib',
style: 'camelCase',
},
],
'@angular-eslint/component-selector': [
'error',
{
type: 'element',
prefix: 'lib',
style: 'kebab-case',
},
],
},
},
{
files: ['**/*.html'],
// Override or add rules here
rules: {},
},
];

View File

@@ -1,21 +0,0 @@
export default {
displayName: 'feature-return-services',
preset: '../../../../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
coverageDirectory: '../../../../coverage/libs/feature/return/services',
transform: {
'^.+\\.(ts|mjs|js|html)$': [
'jest-preset-angular',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
},
],
},
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
snapshotSerializers: [
'jest-preset-angular/build/serializers/no-ng-attributes',
'jest-preset-angular/build/serializers/ng-snapshot',
'jest-preset-angular/build/serializers/html-comment',
],
};

View File

@@ -1,20 +0,0 @@
{
"name": "feature-return-services",
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/feature/return/services/src",
"prefix": "lib",
"projectType": "library",
"tags": [],
"targets": {
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/feature/return/services/jest.config.ts"
}
},
"lint": {
"executor": "@nx/eslint:lint"
}
}
}

View File

@@ -1,3 +0,0 @@
export * from './lib/return-search.service';
export * from './lib/return-search.store';
export * from './lib/schemas';

View File

@@ -1,58 +0,0 @@
import { inject, Injectable } from '@angular/core';
import { QuerySettingsDTO, ReceiptService } from '@generated/swagger/oms-api';
import { map, Observable, throwError } from 'rxjs';
import {
QueryTokenSchema,
QueryTokenInput,
} from './schemas/query-token.schema';
import {
ListResponseArgs,
ListResponseArgsSchema,
ReceiptListItemSchema,
} from './schemas/receipt-list-item.schema';
import { safeParse } from '@isa/utils/z-safe-parse';
@Injectable({ providedIn: 'root' })
export class ReturnSearchService {
#receiptService = inject(ReceiptService);
querySettings(): Observable<QuerySettingsDTO> {
return this.#receiptService.ReceiptQueryReceiptSettings().pipe(
map((res) => {
if (res.error || !res.result) {
throw new Error('Failed to fetch query settings');
}
return res.result;
}),
);
}
search(queryToken: QueryTokenInput): Observable<ListResponseArgs> {
try {
queryToken = QueryTokenSchema.parse(queryToken);
} catch (error) {
return throwError(() => error);
}
return this.#receiptService
.ReceiptQueryReceipt({
queryToken,
})
.pipe(
map((res) => {
if (res.error || !res.result) {
throw new Error('Failed to fetch receipt list items');
}
return safeParse(ListResponseArgsSchema, {
hits: res.hits,
skip: res.skip,
take: res.take,
error: res.error,
invalidProperties: res.invalidProperties,
result: safeParse(ReceiptListItemSchema.array(), res.result),
});
}),
);
}
}

View File

@@ -1,243 +0,0 @@
import { patchState, signalStore, type, withMethods } from '@ngrx/signals';
import { rxMethod } from '@ngrx/signals/rxjs-interop';
import {
addEntity,
entityConfig,
updateEntity,
withEntities,
} from '@ngrx/signals/entities';
import { debounceTime, distinctUntilChanged, pipe, switchMap, tap } from 'rxjs';
import { ReturnSearchService } from './return-search.service';
import { tapResponse } from '@ngrx/operators';
import { inject } from '@angular/core';
import { ReceiptListItem, QueryTokenSchema, ListResponseArgs } from './schemas';
export enum ReturnSearchStatus {
Idle = 'idle',
Pending = 'pending',
Success = 'success',
Error = 'error',
}
export type ReturnSearchEntity = {
processId: number;
status: ReturnSearchStatus;
params?: Record<string, string>;
items?: ReceiptListItem[];
hits?: number;
error?: string | unknown;
};
const config = entityConfig({
entity: type<ReturnSearchEntity>(),
selectId: (entity) => entity.processId,
});
export const ReturnSearchStore = signalStore(
{ providedIn: 'root' },
withEntities<ReturnSearchEntity>(config),
withMethods((store) => ({
getEntity(processId: number): ReturnSearchEntity | undefined {
return store.entities().find((e) => e.processId === processId);
},
})),
withMethods((store) => ({
_getQueryToken({
params,
skip = 0,
}: {
params: Record<string, string>;
skip: number;
}) {
const { qs, orderBy = [], ...filter } = params;
return {
filter,
input: {
qs,
},
orderBy,
skip,
take: 25,
};
},
_beforeSearch(processId: number) {
const entity = store.getEntity(processId);
if (entity) {
patchState(
store,
updateEntity(
{
id: processId,
changes: {
status: ReturnSearchStatus.Pending,
items: [],
hits: 0,
},
},
config,
),
);
} else {
const entity: ReturnSearchEntity = {
processId,
status: ReturnSearchStatus.Pending,
};
patchState(store, addEntity(entity, config));
}
},
_beforeReload(processId: number) {
patchState(
store,
updateEntity(
{
id: processId,
changes: {
status: ReturnSearchStatus.Pending,
},
},
config,
),
);
},
_handleSearchSuccess({
processId,
response,
}: {
processId: number;
response: ListResponseArgs;
}) {
patchState(
store,
updateEntity(
{
id: processId,
changes: {
status: ReturnSearchStatus.Success,
hits: response.hits,
items: response.result,
},
},
config,
),
);
},
_handleReloadSuccess({
processId,
response,
}: {
processId: number;
response: ListResponseArgs;
}) {
const entityItems = store.getEntity(processId)?.items;
patchState(
store,
updateEntity(
{
id: processId,
changes: {
status: ReturnSearchStatus.Success,
hits: response.hits,
items: entityItems
? [...entityItems, ...response.result]
: response.result,
},
},
config,
),
);
},
_handleSearchError({
processId,
error,
}: {
processId: number;
error: unknown;
}) {
console.error(error);
patchState(
store,
updateEntity(
{
id: processId,
changes: {
items: [],
hits: 0,
status: ReturnSearchStatus.Error,
error,
},
},
config,
),
);
},
_handleReloadError({
processId,
error,
}: {
processId: number;
error: unknown;
}) {
console.error(error);
patchState(
store,
updateEntity(
{
id: processId,
changes: {
status: ReturnSearchStatus.Error,
error,
},
},
config,
),
);
},
})),
withMethods((store, returnSearchService = inject(ReturnSearchService)) => ({
search: rxMethod<{ processId: number; params: Record<string, string> }>(
pipe(
debounceTime(100),
distinctUntilChanged(),
tap(({ processId }) => store._beforeSearch(processId)),
switchMap(({ processId, params }) =>
returnSearchService
.search(
QueryTokenSchema.parse(store._getQueryToken({ params, skip: 0 })),
)
.pipe(
tapResponse(
(response) =>
store._handleSearchSuccess({ processId, response }),
(error) => store._handleSearchError({ processId, error }),
),
),
),
),
),
reload: rxMethod<{ processId: number; params: Record<string, string> }>(
pipe(
debounceTime(100),
distinctUntilChanged(),
tap(({ processId }) => store._beforeReload(processId)),
switchMap(({ processId, params }) =>
returnSearchService
.search(
QueryTokenSchema.parse(
store._getQueryToken({
params,
skip: store.getEntity(processId)?.items?.length ?? 0,
}),
),
)
.pipe(
tapResponse(
(response) =>
store._handleReloadSuccess({ processId, response }),
(error) => store._handleReloadError({ processId, error }),
),
),
),
),
),
})),
);

View File

@@ -1,26 +0,0 @@
import { z } from 'zod';
import { GeoLocationSchema } from './geo-location.schema';
export const AddressSchema = z
.object({
apartment: z.string().optional().describe('Apartment'),
careOf: z.string().optional().describe('c/o, zu Händen von'),
city: z.string().optional().describe('Ort'),
country: z
.string()
.regex(/^[A-Z]{3}$/)
.optional()
.describe('Land (ISO3166 A 3)'),
district: z.string().optional().describe('Stadtteil, District'),
geoLocation: GeoLocationSchema.optional().describe('Orts-Koordinaten'),
info: z.string().optional().describe('Adresszusatz'),
po: z.string().optional().describe('Postfach'),
region: z.string().optional().describe('Region'),
state: z.string().optional().describe('Bundesland, Bundesstaat, Kanton, ...'),
street: z.string().optional().describe('Straße'),
streetNumber: z.string().optional().describe('Hausnummer'),
zipCode: z.string().optional().describe('Postleitzahl'),
})
.describe('AddressDTO');
export type Address = z.infer<typeof AddressSchema>;

View File

@@ -1,16 +0,0 @@
import { z } from 'zod';
import { AddressSchema } from './address.schema';
import { CommunicationDetailsSchema } from './communication-details.schemas';
import { OrganisationSchema } from './receipt-list-item.schema';
import { GenderSchema } from './gender.schema';
export const AddresseeSchema = z.object({
address: AddressSchema.optional(),
communicationDetails: CommunicationDetailsSchema.optional(),
firstName: z.string().optional(),
lastName: z.string().optional(),
locale: z.string().optional(),
organisation: OrganisationSchema.optional(),
title: z.string().optional(),
gender: GenderSchema.optional(),
});

View File

@@ -1,3 +0,0 @@
import { z } from 'zod';
export const BranchSchema = z.object({});

View File

@@ -1,6 +0,0 @@
import { z } from 'zod';
import { AddresseeSchema } from './addressee.schema';
export const BuyerSchema = AddresseeSchema.extend({});
export type Buyer = z.infer<typeof BuyerSchema>;

View File

@@ -1,9 +0,0 @@
import { z } from 'zod';
export const CommunicationDetailsSchema = z.object({
email: z.string().email(),
mobile: z.string().optional(),
phone: z.string().optional(),
});
export type CommunicationDetails = z.infer<typeof CommunicationDetailsSchema>;

View File

@@ -1,7 +0,0 @@
import { z } from 'zod';
export const FetchReturnDetailsSchema = z.object({
receiptId: z.number(),
});
export type FetchReturnDetails = z.infer<typeof FetchReturnDetailsSchema>;

View File

@@ -1,3 +0,0 @@
import { z } from 'zod';
export const GeoLocationSchema = z.object({});

View File

@@ -1,21 +0,0 @@
export * from './address.schema';
export * from './address.type.schema';
export * from './buyer.schema';
export * from './communication-details.schemas';
export * from './fetch-return-details.schema';
export * from './geo-location.schema';
export * from './label.schema';
export * from './order.schema';
export * from './payer-2.schema';
export * from './payment-info.schema';
export * from './payment.schema';
export * from './query-token.schema';
export * from './receipt-delivery-type.schema';
export * from './receipt-item.schema';
export * from './receipt-list-item.schema';
export * from './receipt-type.schema';
export * from './receipt.schema';
export * from './response-args-of-receipt.schema';
export * from './response-args.schema';
export * from './shipping-address-2.schema';
export * from './shipping-type.schema';

View File

@@ -1,3 +0,0 @@
import { z } from 'zod';
export const LabelSchema = z.object({});

View File

@@ -1,17 +0,0 @@
import { z } from 'zod';
export enum OrderItemType {
NotSet = 0,
SignleItem = 1,
VATBundle = 2,
ItemPrice = 4,
ComponentPrice = 8,
SubItem = 16,
Accessory = 32,
Set = 64,
Postage = 128,
HandlingFee = 256,
Voucher = 512,
}
export const OrderItemTypeSchema = z.nativeEnum(OrderItemType);

View File

@@ -1,7 +0,0 @@
import { z } from 'zod';
export const OrderSchema = z.object({
id: z.number(),
orderNumber: z.string(),
orderDate: z.coerce.date(),
});

View File

@@ -1,3 +0,0 @@
import { AddresseeSchema } from './addressee.schema';
export const Payer2Schema = AddresseeSchema.extend({});

View File

@@ -1,3 +0,0 @@
import { z } from 'zod';
export const PaymentInfoSchema = z.object({});

View File

@@ -1,18 +0,0 @@
import { z } from 'zod';
export enum PaymentStatus {
NotSet = 0,
ProformaInvoicePrinted = 1,
InvoicePrinted = 2,
Paid = 4,
OnApproval = 8,
Free = 16,
Dunning1 = 32,
ProformaInvoicePaid = 64,
Canceled = 128,
Dunning2 = 256,
PartiallyPaid = 512,
Outstanding = 1024,
}
export const PaymentStatusSchema = z.nativeEnum(PaymentStatus);

View File

@@ -1,3 +0,0 @@
import { z } from 'zod';
export const Payment = z.object({});

View File

@@ -1,7 +0,0 @@
import { z } from 'zod';
export const PriceValueSchema = z.object({
value: z.number(),
currency: z.string(),
currencySymbol: z.string().optional(),
});

View File

@@ -1,8 +0,0 @@
import { z } from 'zod';
import { PriceValueSchema } from './price-value.schema';
import { VATValueSchema } from './vat-value.schema';
export const PriceSchema = z.object({
value: PriceValueSchema,
vat: VATValueSchema,
});

View File

@@ -1,13 +0,0 @@
import { z } from 'zod';
export const ProductSchema = z.object({
name: z.string(),
contributors: z.string(),
ean: z.string(),
manufacturer: z.string(),
publicationDate: z.coerce.date(),
format: z.string(),
formatDetail: z.string(),
});
export type Product = z.infer<typeof ProductSchema>;

View File

@@ -1,7 +0,0 @@
import { z } from 'zod';
export enum ReceiptDeliveryType {
NotSet = 0,
}
export const ReceiptDeliveryTypeSchema = z.nativeEnum(ReceiptDeliveryType);

View File

@@ -1,19 +0,0 @@
import { EntityContainerSchema } from '@isa/common/result';
import { z } from 'zod';
import { BranchSchema } from './branch.schema';
import { OrderItemTypeSchema } from './order-item-type.schema';
import { PaymentStatusSchema } from './payment-status.schema';
import { ProductSchema } from './product.schema';
import { PriceSchema } from './price.schema';
export const ReceiptItemSchema = z.object({
id: z.number(),
lineNumber: z.number(),
orderBranch: EntityContainerSchema(BranchSchema),
orderItemType: OrderItemTypeSchema,
paymentStatus: PaymentStatusSchema,
product: ProductSchema,
price: PriceSchema,
});
export type ReceiptItem = z.infer<typeof ReceiptItemSchema>;

View File

@@ -1,53 +0,0 @@
import { z } from 'zod';
import { ResponseArgsSchema } from './response-args.schema';
import { CommunicationDetailsSchema } from './communication-details.schemas';
import { AddressSchema } from './address.schema';
// PersonNamesDTO
export const PersonSchema = z.object({
firstName: z.string().optional(),
gender: z.number().optional(),
lastName: z.string().optional(),
title: z.string().optional(),
});
// OrganisationDTO
export const OrganisationSchema = z.object({
name: z.string(),
});
// AddresseeDTO
export const AddresseeSchema = z.object({
person: PersonSchema,
address: AddressSchema.optional(),
organisation: OrganisationSchema.optional(),
communicationDetails: CommunicationDetailsSchema.optional(),
});
// ReceiptListItemDTO
export const ReceiptListItemSchema = z.object({
id: z.number(),
label: z.string(),
orderNumber: z.string(),
receiptNumber: z.string(),
printedDate: z.string(),
billing: AddresseeSchema,
});
// ListResponseArgsOfReceiptListItemDTO
export const ListResponseArgsSchema = ResponseArgsSchema.extend({
hits: z.number(),
skip: z.number(),
take: z.number(),
result: ReceiptListItemSchema.array(),
});
// TODO: Auslagern um ein generisches ListResponseArgs Schema zu haben
export function createListResponseArgsSchema(schema: z.ZodSchema<unknown>) {
return ListResponseArgsSchema.extend({
result: schema.array(),
});
}
export type ListResponseArgs = z.infer<typeof ListResponseArgsSchema>;
export type ReceiptListItem = z.infer<typeof ReceiptListItemSchema>;

View File

@@ -1,22 +0,0 @@
import { z } from 'zod';
import { BuyerSchema } from './buyer.schema';
import { EntityContainerSchema } from '@isa/common/result';
import { ReceiptItemSchema } from './receipt-item.schema';
import { ReceiptTypeSchema } from './receipt-type.schema';
import { OrderSchema } from './order.schema';
import { Payer2Schema } from './payer-2.schema';
import { ShippingAddress2Schema } from './shipping-address-2.schema';
export const ReceiptSchema = z.object({
id: z.number(),
receiptType: ReceiptTypeSchema,
buyer: BuyerSchema,
items: EntityContainerSchema(ReceiptItemSchema).array(),
printedDate: z.coerce.date(),
receiptNumber: z.string(),
order: EntityContainerSchema(OrderSchema),
billing: Payer2Schema,
shipping: ShippingAddress2Schema,
});
export type Receipt = z.infer<typeof ReceiptSchema>;

View File

@@ -1,7 +0,0 @@
import { ResponseArgs } from '@isa/common/result';
import { ReceiptSchema } from './receipt.schema';
import { z } from 'zod';
export const ResponseArgsOfReceiptSchema = ResponseArgs(ReceiptSchema);
export type ResponseArgsOfReceipt = z.infer<typeof ResponseArgsOfReceiptSchema>;

View File

@@ -1,9 +0,0 @@
import { z } from "zod";
export const ResponseArgsSchema = z.object({
error: z.boolean(),
invalidProperties: z.record(z.string()).optional(),
message: z.string().optional(),
});
export type ResponseArgs = z.infer<typeof ResponseArgsSchema>;

View File

@@ -1,3 +0,0 @@
import { AddresseeSchema } from './receipt-list-item.schema';
export const ShippingAddress2Schema = AddresseeSchema.extend({});

View File

@@ -1,14 +0,0 @@
import { z } from 'zod';
export enum TypeOfDelivery {
NotSet = 0,
Standard = 1,
Express = 2,
AirMail = 4,
SeeOrOverland = 8,
Courier = 16,
CashOnDelivery = 32,
DeliveryVehicle = 64,
}
export const TypeOfDeliverySchema = z.nativeEnum(TypeOfDelivery);

View File

@@ -1,10 +0,0 @@
import { z } from 'zod';
export enum ValidationStatus {
NotSet = 0,
Validate = 1,
ValidateManually = 2,
ValidateAutomatically = 4,
}
export const ValidationStatusSchema = z.nativeEnum(ValidationStatus);

View File

@@ -1,15 +0,0 @@
import { z } from 'zod';
export enum VATType {
NotSet = 0,
ZeroRate = 1,
StandardRate = 2,
MediumRate = 4,
ReducedRate = 8,
VeryReducedRate = 16,
RateForServices = 32,
TaxPaidAtSource = 64,
MixedVAT = 128,
}
export const VATTypeSchema = z.nativeEnum(VATType);

View File

@@ -1,8 +0,0 @@
import { z } from 'zod';
import { VATTypeSchema } from './vat-type.schema';
export const VATValueSchema = z.object({
inPercent: z.number(),
value: z.number(),
vatType: VATTypeSchema,
});

View File

@@ -1,6 +0,0 @@
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone';
setupZoneTestEnv({
errorOnUnknownElements: true,
errorOnUnknownProperties: true,
});

View File

@@ -1,28 +0,0 @@
{
"compilerOptions": {
"target": "es2022",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
],
"extends": "../../../../tsconfig.base.json",
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}

View File

@@ -1,12 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../../dist/out-tsc",
"declaration": true,
"declarationMap": true,
"inlineSources": true,
"types": []
},
"exclude": ["src/**/*.spec.ts", "src/test-setup.ts", "jest.config.ts", "src/**/*.test.ts"],
"include": ["src/**/*.ts"]
}

View File

@@ -1,11 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../../dist/out-tsc",
"module": "commonjs",
"target": "es2016",
"types": ["jest", "node"]
},
"files": ["src/test-setup.ts"],
"include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"]
}

View File

@@ -1,6 +1,9 @@
export * from './lib/errors';
export * from './lib/models'; export * from './lib/models';
export * from './lib/schemas'; export * from './lib/schemas';
export * from './lib/return-details.service'; export * from './lib/return-details.service';
export * from './lib/return-details.store'; export * from './lib/return-details.store';
export * from './lib/return-process.service'; export * from './lib/return-process.service';
export * from './lib/return-process.store'; export * from './lib/return-process.store';
export * from './lib/return-search.service';
export * from './lib/return-search.store';

View File

@@ -0,0 +1,38 @@
import { ListResponseArgs } from '@isa/common/result';
import { QueryTokenInput } from '../schemas';
import { ReceiptListItem } from '../models';
export const ReturnSearchErrorCode = {
PARSE_QUERY_TOKEN: 'PARSE_QUERY_TOKEN',
} as const;
export type ReturnSearchErrorCode =
(typeof ReturnSearchErrorCode)[keyof typeof ReturnSearchErrorCode];
export class ReturnSearchError extends Error {
constructor(
public readonly code: ReturnSearchErrorCode,
message?: string,
) {
super(message || code);
}
}
export class ReturnSearchParseQueryTokenError extends ReturnSearchError {
constructor(
public queryToken: QueryTokenInput,
messsage: string,
) {
super(ReturnSearchErrorCode.PARSE_QUERY_TOKEN, messsage);
}
}
export class ReturnSearchSearchError extends ReturnSearchError {
constructor(
messsage: string,
public queryToken: QueryTokenInput,
public response?: ListResponseArgs<ReceiptListItem>,
) {
super(ReturnSearchErrorCode.PARSE_QUERY_TOKEN, messsage);
}
}

View File

@@ -1,5 +1,3 @@
import { z } from 'zod';
export enum AddressType { export enum AddressType {
NotSet = 0, NotSet = 0,
Billing = 1, Billing = 1,
@@ -7,5 +5,3 @@ export enum AddressType {
Buyer = 4, Buyer = 4,
PackageStation = 8, PackageStation = 8,
} }
export const AddressTypeSchema = z.nativeEnum(AddressType);

View File

@@ -1,10 +1,6 @@
import { z } from 'zod';
export enum Gender { export enum Gender {
NotSet = 0, NotSet = 0,
Neutrum = 1, Neutrum = 1,
Male = 2, Male = 2,
Female = 4, Female = 4,
} }
export const GenderSchema = z.nativeEnum(Gender);

View File

@@ -1,8 +1,12 @@
export * from './address-type';
export * from './buyer'; export * from './buyer';
export * from './eligible-for-return'; export * from './eligible-for-return';
export * from './gender';
export * from './product'; export * from './product';
export * from './quantity'; export * from './quantity';
export * from './receipt-item'; export * from './receipt-item';
export * from './receipt-list-item';
export * from './receipt-type';
export * from './receipt'; export * from './receipt';
export * from './return-process-answer'; export * from './return-process-answer';
export * from './return-process-question-key'; export * from './return-process-question-key';
@@ -10,3 +14,4 @@ export * from './return-process-question-type';
export * from './return-process-question'; export * from './return-process-question';
export * from './return-process-status'; export * from './return-process-status';
export * from './return-process'; export * from './return-process';
export * from './shipping-type';

View File

@@ -0,0 +1,5 @@
import { ReceiptListItemDTO } from '@generated/swagger/oms-api';
export interface ReceiptListItem extends ReceiptListItemDTO {
id: number;
}

View File

@@ -1,5 +1,3 @@
import { z } from 'zod';
export enum ReceiptType { export enum ReceiptType {
NotSet = 0, NotSet = 0,
ShippingNote = 1, ShippingNote = 1,
@@ -15,5 +13,3 @@ export enum ReceiptType {
CashReceipt = 1024, CashReceipt = 1024,
ReturnReceipt = 2048, ReturnReceipt = 2048,
} }
export const ReceiptTypeSchema = z.nativeEnum(ReceiptType);

View File

@@ -1,5 +1,3 @@
import { z } from 'zod';
export enum ShippingType { export enum ShippingType {
NotSet = 0, NotSet = 0,
PostCard = 1, PostCard = 1,
@@ -11,5 +9,3 @@ export enum ShippingType {
Palette = 64, Palette = 64,
MerchandiseShipmentSmall = 128, MerchandiseShipmentSmall = 128,
} }
export const ShippingTypeSchema = z.nativeEnum(ShippingType);

View File

@@ -0,0 +1,73 @@
import { inject, Injectable } from '@angular/core';
import { QuerySettingsDTO, ReceiptService } from '@generated/swagger/oms-api';
import { map, Observable, throwError } from 'rxjs';
import { QueryTokenInput, QueryTokenSchema } from './schemas';
import { ReceiptListItem } from './models';
import { ListResponseArgs } from '@isa/common/result';
import {
ReturnSearchParseQueryTokenError,
ReturnSearchSearchError,
} from './errors/return-search.error';
import { ZodError } from 'zod';
@Injectable({ providedIn: 'root' })
export class ReturnSearchService {
#receiptService = inject(ReceiptService);
/**
* Fetches query settings for receipt search.
*
* @returns {Observable<QuerySettingsDTO>} An observable containing the query settings.
* @throws {Error} If the query settings cannot be fetched.
*/
querySettings(): Observable<QuerySettingsDTO> {
return this.#receiptService.ReceiptQueryReceiptSettings().pipe(
map((res) => {
if (res.error || !res.result) {
throw new Error('Failed to fetch query settings');
}
return res.result;
}),
);
}
/**
* Executes a search for receipts based on the provided query token.
*
* @param {QueryTokenInput} queryToken - The query token containing search parameters.
* @returns {Observable<ListResponseArgs<ReceiptListItem>>} An observable containing the search results.
* @throws {ReturnSearchParseQueryTokenError} If the query token is invalid.
* @throws {ReturnSearchSearchError} If the search fails due to an API error.
*/
search(queryToken: QueryTokenInput): Observable<ListResponseArgs<ReceiptListItem>> {
try {
queryToken = QueryTokenSchema.parse(queryToken);
} catch (error) {
if (error instanceof ZodError) {
return throwError(() => new ReturnSearchParseQueryTokenError(queryToken, error.message));
}
if (error instanceof Error) {
return throwError(() => new ReturnSearchParseQueryTokenError(queryToken, error.message));
}
return throwError(() => new ReturnSearchParseQueryTokenError(queryToken, 'Unknown error'));
}
return this.#receiptService
.ReceiptQueryReceipt({
queryToken,
})
.pipe(
map((res) => {
if (res.error) {
throw new ReturnSearchSearchError(
res.message || 'Unknown Error',
queryToken,
res as ListResponseArgs<ReceiptListItem>,
);
}
return res as ListResponseArgs<ReceiptListItem>;
}),
);
}
}

View File

@@ -0,0 +1,168 @@
import { createServiceFactory } from '@ngneat/spectator/jest';
import { ReturnSearchStore, ReturnSearchStatus } from './return-search.store';
import { ReturnSearchService } from './return-search.service';
import { of, throwError } from 'rxjs';
import { ListResponseArgs } from '@isa/common/result';
import { ReceiptListItem } from './models';
describe('ReturnSearchStore', () => {
const createService = createServiceFactory({
service: ReturnSearchStore,
mocks: [ReturnSearchService],
});
it('should create the store', () => {
const spectator = createService();
expect(spectator.service).toBeTruthy();
});
describe('getEntity', () => {
it('should return undefined if the entity does not exist', () => {
const spectator = createService();
const entity = spectator.service.getEntity(1);
expect(entity).toBeUndefined();
});
it('should return the entity if it exists', () => {
const spectator = createService();
spectator.service.beforeSearch(1);
const entity = spectator.service.getEntity(1);
expect(entity).toBeDefined();
expect(entity?.processId).toBe(1);
});
});
describe('beforeSearch', () => {
it('should initialize a new entity if it does not exist', () => {
const spectator = createService();
spectator.service.beforeSearch(1);
const entity = spectator.service.getEntity(1);
expect(entity).toEqual({
processId: 1,
status: ReturnSearchStatus.Pending,
});
});
it('should reset an existing entity', () => {
const spectator = createService();
spectator.service.beforeSearch(1);
spectator.service.handleSearchSuccess({
processId: 1,
response: { hits: 10, result: [], error: false, skip: 0, take: 10, invalidProperties: {} },
});
spectator.service.beforeSearch(1);
const entity = spectator.service.getEntity(1);
expect(entity?.status).toBe(ReturnSearchStatus.Pending);
expect(entity?.items).toEqual([]);
expect(entity?.hits).toBe(0);
});
});
describe('handleSearchSuccess', () => {
it('should update the entity with search results', () => {
const spectator = createService();
const response: ListResponseArgs<ReceiptListItem> = {
hits: 5,
skip: 0,
error: false,
take: 10,
invalidProperties: {},
result: [{ id: 1 }],
};
spectator.service.beforeSearch(1);
spectator.service.handleSearchSuccess({ processId: 1, response });
const entity = spectator.service.getEntity(1);
expect(entity?.status).toBe(ReturnSearchStatus.Success);
expect(entity?.hits).toBe(5);
expect(entity?.items).toEqual(response.result);
});
});
describe('handleSearchError', () => {
it('should update the entity with an error status', () => {
const spectator = createService();
const error = new Error('Search failed');
spectator.service.beforeSearch(1);
spectator.service.handleSearchError({ processId: 1, error });
const entity = spectator.service.getEntity(1);
expect(entity?.status).toBe(ReturnSearchStatus.Error);
expect(entity?.error).toBe(error);
});
});
describe('search', () => {
it('should call the search service and handle success', () => {
const spectator = createService();
const mockResponse: ListResponseArgs<ReceiptListItem> = {
hits: 3,
skip: 0,
error: false,
take: 10,
invalidProperties: {},
result: [{ id: 1 }],
};
const returnSearchService = spectator.inject(ReturnSearchService);
returnSearchService.search.mockReturnValue(of(mockResponse));
spectator.service.search({ processId: 1, params: {} });
const entity = spectator.service.getEntity(1);
expect(entity?.status).toBe(ReturnSearchStatus.Success);
expect(entity?.hits).toBe(3);
expect(entity?.items).toEqual(mockResponse.result);
});
it('should call the search service and handle error', () => {
const spectator = createService();
const error = new Error('Search failed');
const returnSearchService = spectator.inject(ReturnSearchService);
returnSearchService.search.mockReturnValue(throwError(() => error));
spectator.service.search({ processId: 1, params: {} });
const entity = spectator.service.getEntity(1);
expect(entity?.status).toBe(ReturnSearchStatus.Error);
expect(entity?.error).toBe(error);
});
});
describe('reload', () => {
it('should append new results to the existing items', () => {
const spectator = createService();
const initialResponse: ListResponseArgs<ReceiptListItem> = {
hits: 2,
skip: 0,
error: false,
take: 10,
invalidProperties: {},
result: [{ id: 1 }],
};
const reloadResponse: ListResponseArgs<ReceiptListItem> = {
hits: 3,
skip: 0,
error: false,
take: 10,
invalidProperties: {},
result: [{ id: 2 }],
};
const returnSearchService = spectator.inject(ReturnSearchService);
returnSearchService.search
.mockReturnValueOnce(of(initialResponse))
.mockReturnValueOnce(of(reloadResponse));
spectator.service.search({ processId: 1, params: {} });
spectator.service.reload({ processId: 1, params: {} });
const entity = spectator.service.getEntity(1);
expect(entity?.items).toEqual([
{ id: '1', name: 'Item 1' },
{ id: '2', name: 'Item 2' },
]);
});
});
});

View File

@@ -0,0 +1,299 @@
import { patchState, signalStore, type, withMethods } from '@ngrx/signals';
import { rxMethod } from '@ngrx/signals/rxjs-interop';
import { addEntity, entityConfig, updateEntity, withEntities } from '@ngrx/signals/entities';
import { debounceTime, distinctUntilChanged, pipe, switchMap, tap } from 'rxjs';
import { ReturnSearchService } from './return-search.service';
import { tapResponse } from '@ngrx/operators';
import { inject } from '@angular/core';
import { QueryTokenSchema } from './schemas';
import { ListResponseArgs } from '@isa/common/result';
import { ReceiptListItem } from './models';
import { isEqual } from 'lodash-es';
/**
* Enum representing the status of a return search process.
*/
export enum ReturnSearchStatus {
Idle = 'idle',
Pending = 'pending',
Success = 'success',
Error = 'error',
}
/**
* Type definition for a return search entity.
*/
export type ReturnSearchEntity = {
processId: number; // Unique identifier for the search process
status: ReturnSearchStatus; // Current status of the search process
params?: Record<string, string>; // Search parameters
items?: ReceiptListItem[]; // List of receipt items returned by the search
hits?: number; // Total number of results
error?: string | unknown; // Error details, if any
};
const config = entityConfig({
entity: type<ReturnSearchEntity>(),
selectId: (entity) => entity.processId,
});
/**
* Signal store for managing return search state and operations.
*/
export const ReturnSearchStore = signalStore(
{ providedIn: 'root' },
withEntities<ReturnSearchEntity>(config),
withMethods((store) => ({
/**
* Retrieves a return search entity by its process ID.
*
* @param {number} processId - The unique identifier of the search process.
* @returns {ReturnSearchEntity | undefined} The corresponding entity or undefined if not found.
*/
getEntity(processId: number): ReturnSearchEntity | undefined {
return store.entities().find((e) => e.processId === processId);
},
})),
withMethods((store) => ({
/**
* Constructs a query token for the search operation.
*
* @param {Object} options - Options for constructing the query token.
* @param {Record<string, string>} options.params - Search parameters.
* @param {number} [options.skip=0] - Number of items to skip for pagination.
* @returns {Object} The constructed query token.
*/
getQueryToken({ params, skip = 0 }: { params: Record<string, string>; skip: number }) {
const { qs, orderBy = [], ...filter } = params;
return {
filter,
input: {
qs,
},
orderBy,
skip,
take: 25,
};
},
/**
* Prepares the store state before initiating a search operation.
*
* @param {number} processId - The unique identifier of the search process.
*/
beforeSearch(processId: number) {
const entity = store.getEntity(processId);
if (entity) {
patchState(
store,
updateEntity(
{
id: processId,
changes: {
status: ReturnSearchStatus.Pending,
items: [],
hits: 0,
},
},
config,
),
);
} else {
const entity: ReturnSearchEntity = {
processId,
status: ReturnSearchStatus.Pending,
};
patchState(store, addEntity(entity, config));
}
},
/**
* Prepares the store state before reloading search results.
*
* @param {number} processId - The unique identifier of the search process.
*/
beforeReload(processId: number) {
patchState(
store,
updateEntity(
{
id: processId,
changes: {
status: ReturnSearchStatus.Pending,
},
},
config,
),
);
},
/**
* Handles the success response of a search operation.
*
* @param {Object} options - Options for handling the success response.
* @param {number} options.processId - The unique identifier of the search process.
* @param {ListResponseArgs<ReceiptListItem>} options.response - The search response.
*/
handleSearchSuccess({
processId,
response,
}: {
processId: number;
response: ListResponseArgs<ReceiptListItem>;
}) {
patchState(
store,
updateEntity(
{
id: processId,
changes: {
status: ReturnSearchStatus.Success,
hits: response.hits,
items: response.result,
},
},
config,
),
);
},
/**
* Handles the success response of a reload operation.
*
* @param {Object} options - Options for handling the success response.
* @param {number} options.processId - The unique identifier of the search process.
* @param {ListResponseArgs<ReceiptListItem>} options.response - The reload response.
*/
handleReloadSuccess({
processId,
response,
}: {
processId: number;
response: ListResponseArgs<ReceiptListItem>;
}) {
const entityItems = store.getEntity(processId)?.items;
patchState(
store,
updateEntity(
{
id: processId,
changes: {
status: ReturnSearchStatus.Success,
hits: response.hits,
items: entityItems ? [...entityItems, ...response.result] : response.result,
},
},
config,
),
);
},
/**
* Handles errors encountered during a search operation.
*
* @param {Object} options - Options for handling the error.
* @param {number} options.processId - The unique identifier of the search process.
* @param {unknown} options.error - The error encountered.
*/
handleSearchError({ processId, error }: { processId: number; error: unknown }) {
console.error(error);
patchState(
store,
updateEntity(
{
id: processId,
changes: {
items: [],
hits: 0,
status: ReturnSearchStatus.Error,
error,
},
},
config,
),
);
},
/**
* Handles errors encountered during a reload operation.
*
* @param {Object} options - Options for handling the error.
* @param {number} options.processId - The unique identifier of the search process.
* @param {unknown} options.error - The error encountered.
*/
handleReloadError({ processId, error }: { processId: number; error: unknown }) {
console.error(error);
patchState(
store,
updateEntity(
{
id: processId,
changes: {
status: ReturnSearchStatus.Error,
error,
},
},
config,
),
);
},
})),
withMethods((store, returnSearchService = inject(ReturnSearchService)) => ({
/**
* Initiates a search operation.
*
* @param {Object} options - Options for the search operation.
* @param {number} options.processId - The unique identifier of the search process.
* @param {Record<string, string>} options.params - Search parameters.
*/
search: rxMethod<{ processId: number; params: Record<string, string> }>(
pipe(
debounceTime(100),
distinctUntilChanged(),
tap(({ processId }) => store.beforeSearch(processId)),
switchMap(({ processId, params }) =>
returnSearchService
.search(QueryTokenSchema.parse(store.getQueryToken({ params, skip: 0 })))
.pipe(
tapResponse(
(response) => store.handleSearchSuccess({ processId, response }),
(error) => store.handleSearchError({ processId, error }),
),
),
),
),
),
/**
* Initiates a reload operation to fetch additional search results.
*
* @param {Object} options - Options for the reload operation.
* @param {number} options.processId - The unique identifier of the search process.
* @param {Record<string, string>} options.params - Search parameters.
*/
reload: rxMethod<{ processId: number; params: Record<string, string> }>(
pipe(
debounceTime(100),
distinctUntilChanged(isEqual),
tap(({ processId }) => store.beforeReload(processId)),
switchMap(({ processId, params }) =>
returnSearchService
.search(
QueryTokenSchema.parse(
store.getQueryToken({
params,
skip: store.getEntity(processId)?.items?.length ?? 0,
}),
),
)
.pipe(
tapResponse(
(response) => store.handleReloadSuccess({ processId, response }),
(error) => store.handleReloadError({ processId, error }),
),
),
),
),
),
})),
);

View File

@@ -1 +1,2 @@
export * from './fetch-return-details'; export * from './fetch-return-details';
export * from './query-token.schema';

View File

@@ -15,4 +15,4 @@ export const QueryTokenSchema = z.object({
take: z.number().default(25), take: z.number().default(25),
}); });
export type QueryTokenInput = z.input<typeof QueryTokenSchema>; export type QueryTokenInput = z.infer<typeof QueryTokenSchema>;

View File

@@ -1,6 +1,6 @@
import { inject, Pipe, PipeTransform } from '@angular/core'; import { inject, Pipe, PipeTransform } from '@angular/core';
import { ReceiptType } from '@feature/return/services';
import { ReceiptTypeTranslationService } from './receipt-type-translation.service'; import { ReceiptTypeTranslationService } from './receipt-type-translation.service';
import { ReceiptType } from '@isa/oms/data-access';
@Pipe({ @Pipe({
name: 'omsReceiptTypeTranslation', name: 'omsReceiptTypeTranslation',

View File

@@ -1,5 +1,5 @@
import { inject, Injectable, InjectionToken, Provider } from '@angular/core'; import { inject, Injectable, InjectionToken, Provider } from '@angular/core';
import { ReceiptType } from '@feature/return/services'; import { ReceiptType } from '@isa/oms/data-access';
const receiptTypeTranslations = { const receiptTypeTranslations = {
[ReceiptType.NotSet]: 'Nicht gesetzt', [ReceiptType.NotSet]: 'Nicht gesetzt',

468
package-lock.json generated
View File

@@ -29,9 +29,11 @@
"@ngrx/signals": "19.1.0", "@ngrx/signals": "19.1.0",
"@ngrx/store": "19.1.0", "@ngrx/store": "19.1.0",
"@ngrx/store-devtools": "19.1.0", "@ngrx/store-devtools": "19.1.0",
"@types/lodash-es": "^4.17.12",
"angular-oauth2-oidc": "^17.0.2", "angular-oauth2-oidc": "^17.0.2",
"angular-oauth2-oidc-jwks": "^17.0.2", "angular-oauth2-oidc-jwks": "^17.0.2",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"moment": "^2.30.1", "moment": "^2.30.1",
"ng2-pdf-viewer": "^10.4.0", "ng2-pdf-viewer": "^10.4.0",
"ngx-matomo-client": "^7.0.1", "ngx-matomo-client": "^7.0.1",
@@ -75,7 +77,6 @@
"@swc-node/register": "~1.9.1", "@swc-node/register": "~1.9.1",
"@swc/core": "~1.5.7", "@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11", "@swc/helpers": "~0.5.11",
"@types/jasmine": "~5.1.4",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/lodash": "^4.17.16", "@types/lodash": "^4.17.16",
"@types/node": "18.16.9", "@types/node": "18.16.9",
@@ -87,20 +88,10 @@
"eslint-config-prettier": "^9.0.0", "eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.2.3", "eslint-plugin-prettier": "^5.2.3",
"husky": "^9.1.7", "husky": "^9.1.7",
"jasmine-core": "~5.4.0",
"jasmine-marbles": "^0.9.2",
"jasmine-spec-reporter": "~7.0.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0", "jest-environment-jsdom": "^29.7.0",
"jest-environment-node": "^29.7.0", "jest-environment-node": "^29.7.0",
"jest-preset-angular": "~14.4.0", "jest-preset-angular": "~14.4.0",
"karma": "~6.4.4",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "^2.2.1",
"karma-coverage-istanbul-reporter": "~3.0.3",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"karma-junit-reporter": "~2.0.1",
"ng-mocks": "^14.13.4", "ng-mocks": "^14.13.4",
"ng-swagger-gen": "^2.3.1", "ng-swagger-gen": "^2.3.1",
"nx": "20.4.6", "nx": "20.4.6",
@@ -3810,6 +3801,8 @@
"integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">=0.1.90" "node": ">=0.1.90"
} }
@@ -9559,7 +9552,9 @@
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT",
"optional": true,
"peer": true
}, },
"node_modules/@softarc/eslint-plugin-sheriff": { "node_modules/@softarc/eslint-plugin-sheriff": {
"version": "0.18.0", "version": "0.18.0",
@@ -11478,6 +11473,8 @@
"integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"@types/node": "*" "@types/node": "*"
} }
@@ -11623,13 +11620,6 @@
"@types/istanbul-lib-report": "*" "@types/istanbul-lib-report": "*"
} }
}, },
"node_modules/@types/jasmine": {
"version": "5.1.7",
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.7.tgz",
"integrity": "sha512-DVOfk9FaClQfNFpSfaML15jjB5cjffDMvjtph525sroR5BEAW2uKnTOYUTqTFuZFjNvH0T5XMIydvIctnUKufw==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/jest": { "node_modules/@types/jest": {
"version": "29.5.14", "version": "29.5.14",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz",
@@ -11705,9 +11695,17 @@
"version": "4.17.16", "version": "4.17.16",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz",
"integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==", "integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/lodash-es": {
"version": "4.17.12",
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"license": "MIT",
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/mdx": { "node_modules/@types/mdx": {
"version": "2.0.13", "version": "2.0.13",
"resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz",
@@ -13311,6 +13309,8 @@
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": "^4.5.0 || >= 5.9" "node": "^4.5.0 || >= 5.9"
} }
@@ -14566,16 +14566,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/colors": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.1.90"
}
},
"node_modules/columnify": { "node_modules/columnify": {
"version": "1.6.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz",
@@ -14724,6 +14714,8 @@
"integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"debug": "2.6.9", "debug": "2.6.9",
"finalhandler": "1.1.2", "finalhandler": "1.1.2",
@@ -14750,6 +14742,8 @@
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"ms": "2.0.0" "ms": "2.0.0"
} }
@@ -14760,6 +14754,8 @@
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">= 0.8" "node": ">= 0.8"
} }
@@ -14770,6 +14766,8 @@
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"debug": "2.6.9", "debug": "2.6.9",
"encodeurl": "~1.0.2", "encodeurl": "~1.0.2",
@@ -14788,7 +14786,9 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT",
"optional": true,
"peer": true
}, },
"node_modules/connect/node_modules/on-finished": { "node_modules/connect/node_modules/on-finished": {
"version": "2.3.0", "version": "2.3.0",
@@ -14796,6 +14796,8 @@
"integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"ee-first": "1.1.1" "ee-first": "1.1.1"
}, },
@@ -14809,6 +14811,8 @@
"integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
} }
@@ -14966,6 +14970,8 @@
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"object-assign": "^4", "object-assign": "^4",
"vary": "^1" "vary": "^1"
@@ -15448,7 +15454,9 @@
"resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
"integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT",
"optional": true,
"peer": true
}, },
"node_modules/cwd": { "node_modules/cwd": {
"version": "0.10.0", "version": "0.10.0",
@@ -15943,7 +15951,9 @@
"resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
"integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT",
"optional": true,
"peer": true
}, },
"node_modules/didyoumean": { "node_modules/didyoumean": {
"version": "1.2.2", "version": "1.2.2",
@@ -16038,6 +16048,8 @@
"integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"custom-event": "~1.0.0", "custom-event": "~1.0.0",
"ent": "~2.2.0", "ent": "~2.2.0",
@@ -16278,6 +16290,8 @@
"integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"@types/cors": "^2.8.12", "@types/cors": "^2.8.12",
"@types/node": ">=10.0.0", "@types/node": ">=10.0.0",
@@ -16299,6 +16313,8 @@
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
} }
@@ -16309,6 +16325,8 @@
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
} }
@@ -16319,6 +16337,8 @@
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"ms": "^2.1.3" "ms": "^2.1.3"
}, },
@@ -16337,6 +16357,8 @@
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
}, },
@@ -16386,6 +16408,8 @@
"integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==", "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"call-bound": "^1.0.3", "call-bound": "^1.0.3",
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
@@ -17174,7 +17198,9 @@
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT",
"optional": true,
"peer": true
}, },
"node_modules/external-editor": { "node_modules/external-editor": {
"version": "3.1.0", "version": "3.1.0",
@@ -19858,6 +19884,8 @@
"integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">= 8.0.0" "node": ">= 8.0.0"
}, },
@@ -20073,36 +20101,6 @@
"node": "*" "node": "*"
} }
}, },
"node_modules/jasmine-core": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.4.0.tgz",
"integrity": "sha512-T4fio3W++llLd7LGSGsioriDHgWyhoL6YTu4k37uwJLF7DzOzspz7mNxRoM3cQdLWtL/ebazQpIf/yZGJx/gzg==",
"dev": true,
"license": "MIT"
},
"node_modules/jasmine-marbles": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/jasmine-marbles/-/jasmine-marbles-0.9.2.tgz",
"integrity": "sha512-T7RjG4fRsdiGGzbQZ6Kj39qYt6O1/KIcR4FkUNsD3DUGkd/AzpwzN+xtk0DXlLWEz5BaVdK1SzMgQDVw879c4Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"lodash": "^4.17.20"
},
"peerDependencies": {
"rxjs": "^7.0.0"
}
},
"node_modules/jasmine-spec-reporter": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-7.0.0.tgz",
"integrity": "sha512-OtC7JRasiTcjsaCBPtMO0Tl8glCejM4J4/dNuOJdA8lBjz4PmWjYQ6pzb0uzpBNAWJMDudYuj9OdXJWqM2QTJg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"colors": "1.4.0"
}
},
"node_modules/jest": { "node_modules/jest": {
"version": "29.7.0", "version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
@@ -21714,6 +21712,8 @@
"integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"@colors/colors": "1.5.0", "@colors/colors": "1.5.0",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
@@ -21747,276 +21747,6 @@
"node": ">= 10" "node": ">= 10"
} }
}, },
"node_modules/karma-chrome-launcher": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz",
"integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"which": "^1.2.1"
}
},
"node_modules/karma-chrome-launcher/node_modules/which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"which": "bin/which"
}
},
"node_modules/karma-coverage": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz",
"integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==",
"dev": true,
"license": "MIT",
"dependencies": {
"istanbul-lib-coverage": "^3.2.0",
"istanbul-lib-instrument": "^5.1.0",
"istanbul-lib-report": "^3.0.0",
"istanbul-lib-source-maps": "^4.0.1",
"istanbul-reports": "^3.0.5",
"minimatch": "^3.0.4"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/karma-coverage-istanbul-reporter": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-3.0.3.tgz",
"integrity": "sha512-wE4VFhG/QZv2Y4CdAYWDbMmcAHeS926ZIji4z+FkB2aF/EposRb6DP6G5ncT/wXhqUfAb/d7kZrNKPonbvsATw==",
"dev": true,
"license": "MIT",
"dependencies": {
"istanbul-lib-coverage": "^3.0.0",
"istanbul-lib-report": "^3.0.0",
"istanbul-lib-source-maps": "^3.0.6",
"istanbul-reports": "^3.0.2",
"minimatch": "^3.0.4"
},
"funding": {
"url": "https://github.com/sponsors/mattlewis92"
}
},
"node_modules/karma-coverage-istanbul-reporter/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/karma-coverage-istanbul-reporter/node_modules/istanbul-lib-source-maps": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz",
"integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"debug": "^4.1.1",
"istanbul-lib-coverage": "^2.0.5",
"make-dir": "^2.1.0",
"rimraf": "^2.6.3",
"source-map": "^0.6.1"
},
"engines": {
"node": ">=6"
}
},
"node_modules/karma-coverage-istanbul-reporter/node_modules/istanbul-lib-source-maps/node_modules/istanbul-lib-coverage": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
"integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=6"
}
},
"node_modules/karma-coverage-istanbul-reporter/node_modules/make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
"dev": true,
"license": "MIT",
"dependencies": {
"pify": "^4.0.1",
"semver": "^5.6.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/karma-coverage-istanbul-reporter/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",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/karma-coverage-istanbul-reporter/node_modules/pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/karma-coverage-istanbul-reporter/node_modules/rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"deprecated": "Rimraf versions prior to v4 are no longer supported",
"dev": true,
"license": "ISC",
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
}
},
"node_modules/karma-coverage-istanbul-reporter/node_modules/semver": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver"
}
},
"node_modules/karma-coverage-istanbul-reporter/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/karma-coverage/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/karma-coverage/node_modules/istanbul-lib-instrument": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
"integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@babel/core": "^7.12.3",
"@babel/parser": "^7.14.7",
"@istanbuljs/schema": "^0.1.2",
"istanbul-lib-coverage": "^3.2.0",
"semver": "^6.3.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/karma-coverage/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",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/karma-coverage/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",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/karma-jasmine": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz",
"integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"jasmine-core": "^4.1.0"
},
"engines": {
"node": ">=12"
},
"peerDependencies": {
"karma": "^6.0.0"
}
},
"node_modules/karma-jasmine-html-reporter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz",
"integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"jasmine-core": "^4.0.0 || ^5.0.0",
"karma": "^6.0.0",
"karma-jasmine": "^5.0.0"
}
},
"node_modules/karma-jasmine/node_modules/jasmine-core": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.1.tgz",
"integrity": "sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==",
"dev": true,
"license": "MIT"
},
"node_modules/karma-junit-reporter": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/karma-junit-reporter/-/karma-junit-reporter-2.0.1.tgz",
"integrity": "sha512-VtcGfE0JE4OE1wn0LK8xxDKaTP7slN8DO3I+4xg6gAi1IoAHAXOJ1V9G/y45Xg6sxdxPOR3THCFtDlAfBo9Afw==",
"dev": true,
"license": "MIT",
"dependencies": {
"path-is-absolute": "^1.0.0",
"xmlbuilder": "12.0.0"
},
"engines": {
"node": ">= 8"
},
"peerDependencies": {
"karma": ">=0.9"
}
},
"node_modules/karma-source-map-support": { "node_modules/karma-source-map-support": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz",
@@ -22033,6 +21763,8 @@
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@@ -22044,6 +21776,8 @@
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"anymatch": "~3.1.2", "anymatch": "~3.1.2",
"braces": "~3.0.2", "braces": "~3.0.2",
@@ -22069,6 +21803,8 @@
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"string-width": "^4.2.0", "string-width": "^4.2.0",
"strip-ansi": "^6.0.0", "strip-ansi": "^6.0.0",
@@ -22080,7 +21816,9 @@
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT",
"optional": true,
"peer": true
}, },
"node_modules/karma/node_modules/glob-parent": { "node_modules/karma/node_modules/glob-parent": {
"version": "5.1.2", "version": "5.1.2",
@@ -22088,6 +21826,8 @@
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"is-glob": "^4.0.1" "is-glob": "^4.0.1"
}, },
@@ -22101,6 +21841,8 @@
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
@@ -22111,6 +21853,8 @@
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"bin": { "bin": {
"mime": "cli.js" "mime": "cli.js"
}, },
@@ -22124,6 +21868,8 @@
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
}, },
@@ -22137,6 +21883,8 @@
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"minimist": "^1.2.6" "minimist": "^1.2.6"
}, },
@@ -22150,6 +21898,8 @@
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">=8.6" "node": ">=8.6"
}, },
@@ -22163,6 +21913,8 @@
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"picomatch": "^2.2.1" "picomatch": "^2.2.1"
}, },
@@ -22176,6 +21928,8 @@
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true, "dev": true,
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@@ -22186,6 +21940,8 @@
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"emoji-regex": "^8.0.0", "emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0", "is-fullwidth-code-point": "^3.0.0",
@@ -22201,6 +21957,8 @@
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"ansi-styles": "^4.0.0", "ansi-styles": "^4.0.0",
"string-width": "^4.1.0", "string-width": "^4.1.0",
@@ -22219,6 +21977,8 @@
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"cliui": "^7.0.2", "cliui": "^7.0.2",
"escalade": "^3.1.1", "escalade": "^3.1.1",
@@ -22238,6 +21998,8 @@
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">=10" "node": ">=10"
} }
@@ -22738,6 +22500,12 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"license": "MIT"
},
"node_modules/lodash.clonedeepwith": { "node_modules/lodash.clonedeepwith": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz", "resolved": "https://registry.npmjs.org/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz",
@@ -27006,6 +26774,8 @@
"integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">=0.9" "node": ">=0.9"
} }
@@ -28741,6 +28511,8 @@
"integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"accepts": "~1.3.4", "accepts": "~1.3.4",
"base64id": "~2.0.0", "base64id": "~2.0.0",
@@ -28760,6 +28532,8 @@
"integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"debug": "~4.3.4", "debug": "~4.3.4",
"ws": "~8.17.1" "ws": "~8.17.1"
@@ -28771,6 +28545,8 @@
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"ms": "^2.1.3" "ms": "^2.1.3"
}, },
@@ -28789,6 +28565,8 @@
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
}, },
@@ -28811,6 +28589,8 @@
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"@socket.io/component-emitter": "~3.1.0", "@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1" "debug": "~4.3.1"
@@ -28825,6 +28605,8 @@
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"ms": "^2.1.3" "ms": "^2.1.3"
}, },
@@ -28843,6 +28625,8 @@
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"ms": "^2.1.3" "ms": "^2.1.3"
}, },
@@ -30827,6 +30611,8 @@
} }
], ],
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"bin": { "bin": {
"ua-parser-js": "script/cli.js" "ua-parser-js": "script/cli.js"
}, },
@@ -31241,6 +31027,8 @@
"integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@@ -32214,16 +32002,6 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/xmlbuilder": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-12.0.0.tgz",
"integrity": "sha512-lMo8DJ8u6JRWp0/Y4XLa/atVDr75H9litKlb2E5j3V3MesoL50EBgZDWoLT3F/LztVnG67GjPXLZpqcky/UMnQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0"
}
},
"node_modules/xmlchars": { "node_modules/xmlchars": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",

View File

@@ -43,6 +43,7 @@
"angular-oauth2-oidc": "^17.0.2", "angular-oauth2-oidc": "^17.0.2",
"angular-oauth2-oidc-jwks": "^17.0.2", "angular-oauth2-oidc-jwks": "^17.0.2",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"moment": "^2.30.1", "moment": "^2.30.1",
"ng2-pdf-viewer": "^10.4.0", "ng2-pdf-viewer": "^10.4.0",
"ngx-matomo-client": "^7.0.1", "ngx-matomo-client": "^7.0.1",
@@ -88,6 +89,7 @@
"@swc/helpers": "~0.5.11", "@swc/helpers": "~0.5.11",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/lodash": "^4.17.16", "@types/lodash": "^4.17.16",
"@types/lodash-es": "^4.17.12",
"@types/node": "18.16.9", "@types/node": "18.16.9",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"@typescript-eslint/utils": "^8.19.0", "@typescript-eslint/utils": "^8.19.0",

View File

@@ -22,7 +22,6 @@
"libs/feature/return/containers/src/index.ts" "libs/feature/return/containers/src/index.ts"
], ],
"@feature/return/pages": ["libs/feature/return/pages/src/index.ts"], "@feature/return/pages": ["libs/feature/return/pages/src/index.ts"],
"@feature/return/services": ["libs/feature/return/services/src/index.ts"],
"@generated/swagger/availability-api": [ "@generated/swagger/availability-api": [
"generated/swagger/availability-api/src/index.ts" "generated/swagger/availability-api/src/index.ts"
], ],