@mosa-ng/core 17.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +31 -0
- package/README.md +24 -0
- package/ng-package.json +10 -0
- package/package.json +12 -0
- package/src/assets/i18n/mosa-de-DE.json +60 -0
- package/src/assets/i18n/mosa-en-US.json +60 -0
- package/src/lib/constants/local-storage.constant.ts +4 -0
- package/src/lib/enums/browser.enum.ts +9 -0
- package/src/lib/enums/content-position.enum.ts +11 -0
- package/src/lib/enums/i18n-supported.enum.ts +10 -0
- package/src/lib/enums/theme.enum.ts +4 -0
- package/src/lib/models/api-options.model.ts +21 -0
- package/src/lib/models/dictionary-item.model.ts +8 -0
- package/src/lib/models/key-map.model.ts +3 -0
- package/src/lib/models/logger/log-event.model.ts +8 -0
- package/src/lib/models/logger/log-message-data.model.ts +5 -0
- package/src/lib/models/logger/log-type.model.ts +1 -0
- package/src/lib/models/logger/log.model.ts +10 -0
- package/src/lib/models/logger/logger-base-config.model.ts +8 -0
- package/src/lib/models/logger/logger-config.model.ts +9 -0
- package/src/lib/models/logger/logger-default-config.model.ts +5 -0
- package/src/lib/models/mosa-duration.model.ts +1 -0
- package/src/lib/models/sieve/sieve-filter.model.ts +10 -0
- package/src/lib/models/sieve/sieve-operator.model.ts +69 -0
- package/src/lib/models/sieve/sieve-options.model.ts +13 -0
- package/src/lib/models/sieve/sieve-response.model.ts +4 -0
- package/src/lib/models/sieve/sieve-sort.model.ts +7 -0
- package/src/lib/models/token-settings.model.ts +5 -0
- package/src/lib/models/transform-matrix.model.ts +5 -0
- package/src/lib/mosa-core.module.ts +117 -0
- package/src/lib/pipes/dictionary-item-pipe/dictionary-item-pipe.module.ts +15 -0
- package/src/lib/pipes/dictionary-item-pipe/dictionary-item.pipe.ts +14 -0
- package/src/lib/pipes/find-in-array/find-in-array-pipe.module.ts +17 -0
- package/src/lib/pipes/find-in-array/find-in-array.pipe.spec.ts +8 -0
- package/src/lib/pipes/find-in-array/find-in-array.pipe.ts +34 -0
- package/src/lib/pipes/join/join-pipe.module.ts +17 -0
- package/src/lib/pipes/join/join.pipe.spec.ts +8 -0
- package/src/lib/pipes/join/join.pipe.ts +20 -0
- package/src/lib/pipes/mosa-date-pipe/mosa-date-pipe.module.ts +14 -0
- package/src/lib/pipes/mosa-date-pipe/mosa-date.pipe.ts +102 -0
- package/src/lib/pipes/mosa-duration-pipe/mosa-duration-pipe.module.ts +13 -0
- package/src/lib/pipes/mosa-duration-pipe/mosa-duration.pipe.ts +106 -0
- package/src/lib/services/api.service.ts +270 -0
- package/src/lib/services/core-logger.service.ts +219 -0
- package/src/lib/services/guards/can-deactivate.guard.ts +18 -0
- package/src/lib/services/mosa-socket.service.ts +46 -0
- package/src/lib/services/translation/assets-i18n-loader.service.ts +67 -0
- package/src/lib/services/translation/custom-translate-loader.service.ts +27 -0
- package/src/lib/services/translation/translate-collector.service.ts +60 -0
- package/src/lib/utils/commons.util.ts +100 -0
- package/src/lib/utils/dictionary.util.ts +140 -0
- package/src/lib/utils/item.util.ts +4 -0
- package/src/lib/utils/promise.util.ts +3 -0
- package/src/lib/utils/prototypes.util.ts +167 -0
- package/src/lib/utils/sieve.util.ts +169 -0
- package/src/lib/utils/size.util.ts +4 -0
- package/src/public-api.ts +1 -0
- package/tsconfig.lib.json +16 -0
- package/tsconfig.lib.prod.json +10 -0
- package/tsconfig.spec.json +14 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Pipe, PipeTransform } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Pipe({
|
|
4
|
+
name: 'findInArray',
|
|
5
|
+
})
|
|
6
|
+
export class FindInArrayPipe implements PipeTransform {
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
public transform<T>(searchValue: any, array: T[], searchKey: keyof T, returnElements?: (keyof T)[]): any {
|
|
10
|
+
// Return if array is empty or null
|
|
11
|
+
if (!array || !array.length) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
const foundItem: T = array.find((val: T): boolean => (searchKey ? val[ searchKey as keyof T ] : val) === searchValue);
|
|
17
|
+
if (!foundItem) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Return whole item
|
|
22
|
+
if (!returnElements) {
|
|
23
|
+
return foundItem;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (returnElements.length === 1) {
|
|
27
|
+
return foundItem[ returnElements[ 0 ] ];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Return given values to the keys
|
|
31
|
+
return returnElements.map((val: keyof T) => foundItem[ val as keyof T ]);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { NgModule } from '@angular/core';
|
|
3
|
+
import { JoinPipe } from './join.pipe';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@NgModule({
|
|
7
|
+
declarations: [
|
|
8
|
+
JoinPipe,
|
|
9
|
+
],
|
|
10
|
+
exports: [
|
|
11
|
+
JoinPipe,
|
|
12
|
+
],
|
|
13
|
+
imports: [
|
|
14
|
+
CommonModule,
|
|
15
|
+
],
|
|
16
|
+
})
|
|
17
|
+
export class JoinPipeModule { }
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Pipe, PipeTransform } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Pipe({
|
|
4
|
+
name: 'join',
|
|
5
|
+
})
|
|
6
|
+
export class JoinPipe implements PipeTransform {
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Join array by separator
|
|
10
|
+
* @param array
|
|
11
|
+
* @param returnField
|
|
12
|
+
* @param separator
|
|
13
|
+
*/
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
|
+
public transform(array: any[], returnField: any, separator: string = ', '): string {
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
+
return array.map((val: any): string => returnField ? val[ returnField ] : val).join(separator);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CommonModule, DatePipe } from '@angular/common';
|
|
2
|
+
import { NgModule } from '@angular/core';
|
|
3
|
+
import { MosaDatePipe } from './mosa-date.pipe';
|
|
4
|
+
|
|
5
|
+
@NgModule({
|
|
6
|
+
declarations: [ MosaDatePipe ],
|
|
7
|
+
imports: [
|
|
8
|
+
CommonModule,
|
|
9
|
+
],
|
|
10
|
+
exports: [ MosaDatePipe ],
|
|
11
|
+
providers: [ DatePipe ],
|
|
12
|
+
})
|
|
13
|
+
export class MosaDatePipeModule {
|
|
14
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { DatePipe } from '@angular/common';
|
|
2
|
+
import { Pipe, PipeTransform } from '@angular/core';
|
|
3
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
4
|
+
import { BehaviorSubject, Observable } from 'rxjs';
|
|
5
|
+
import { map } from 'rxjs/operators';
|
|
6
|
+
|
|
7
|
+
@Pipe({
|
|
8
|
+
name: 'mosaDate',
|
|
9
|
+
})
|
|
10
|
+
export class MosaDatePipe implements PipeTransform {
|
|
11
|
+
|
|
12
|
+
private readonly store$: BehaviorSubject<number>;
|
|
13
|
+
private templates: Record<string, string>;
|
|
14
|
+
|
|
15
|
+
constructor(
|
|
16
|
+
private readonly myTranslateService: TranslateService,
|
|
17
|
+
private readonly myDatePipe: DatePipe,
|
|
18
|
+
) {
|
|
19
|
+
this.store$ = new BehaviorSubject<number>(null);
|
|
20
|
+
this.updateTemplates();
|
|
21
|
+
setInterval((): void => {
|
|
22
|
+
this.store$.next(new Date().getTime());
|
|
23
|
+
}, 10);
|
|
24
|
+
this.myTranslateService.onLangChange.subscribe((): void => {
|
|
25
|
+
this.updateTemplates();
|
|
26
|
+
this.store$.next(new Date().getTime());
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public transform(date: string | Date, mode: 'full' | 'timeSince' | 'date' = 'timeSince'): Observable<string> {
|
|
31
|
+
return this.store$.pipe(map((currentDate: number): string => this.calcDate(currentDate, date, mode)));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private calcDate(currentDate: number, date: string | Date, mode: 'full' | 'timeSince' | 'date'): string {
|
|
35
|
+
let parsed: number;
|
|
36
|
+
if (date instanceof Date) {
|
|
37
|
+
parsed = new Date(date.toString()).getTime();
|
|
38
|
+
} else {
|
|
39
|
+
parsed = new Date(date).getTime();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!currentDate) {
|
|
43
|
+
currentDate = new Date().getTime();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const convertedDate = this.myDatePipe.transform(parsed, 'dd. MMM. yyyy hh:mm aaa');
|
|
47
|
+
if (mode === 'full' || mode === 'timeSince') {
|
|
48
|
+
const seconds = ((currentDate - parsed) * .001) >> 0;
|
|
49
|
+
const minutes = seconds / 60;
|
|
50
|
+
const hours = minutes / 60;
|
|
51
|
+
const days = hours / 24;
|
|
52
|
+
const years = days / 365;
|
|
53
|
+
|
|
54
|
+
const timeSince: string = this.templates[ 'prefix' ] + (
|
|
55
|
+
seconds < 60 && this.template('seconds', seconds) ||
|
|
56
|
+
seconds < 120 && this.template('minute', 1) ||
|
|
57
|
+
minutes < 60 && this.template('minutes', minutes) ||
|
|
58
|
+
minutes < 120 && this.template('hour', 1) ||
|
|
59
|
+
hours < 24 && this.template('hours', hours) ||
|
|
60
|
+
hours < 42 && this.template('day', 1) ||
|
|
61
|
+
days < 30 && this.template('days', days) ||
|
|
62
|
+
days < 45 && this.template('month', 1) ||
|
|
63
|
+
days < 365 && this.template('months', days / 30) ||
|
|
64
|
+
years < 1.5 && this.template('year', 1) ||
|
|
65
|
+
this.template('years', years)
|
|
66
|
+
) + this.templates[ 'prefix' ];
|
|
67
|
+
|
|
68
|
+
if (mode === 'timeSince') {
|
|
69
|
+
return timeSince;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (mode === 'full') {
|
|
73
|
+
return `${convertedDate} (${timeSince})`;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return convertedDate;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private template(key: string, val: number): string {
|
|
81
|
+
return this.templates[ key ] && this.templates[ key ].replace(/%d/i, String(Math.abs(Math.round(val))));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private updateTemplates(): void {
|
|
85
|
+
this.templates = {
|
|
86
|
+
prefix: this.myTranslateService.instant('mosa.pipes.timeSince.prefix'),
|
|
87
|
+
suffix: this.myTranslateService.instant('mosa.pipes.timeSince.suffix'),
|
|
88
|
+
seconds: this.myTranslateService.instant('mosa.pipes.timeSince.seconds'),
|
|
89
|
+
minute: this.myTranslateService.instant('mosa.pipes.timeSince.minute'),
|
|
90
|
+
minutes: this.myTranslateService.instant('mosa.pipes.timeSince.minutes'),
|
|
91
|
+
hour: this.myTranslateService.instant('mosa.pipes.timeSince.hour'),
|
|
92
|
+
hours: this.myTranslateService.instant('mosa.pipes.timeSince.hours'),
|
|
93
|
+
day: this.myTranslateService.instant('mosa.pipes.timeSince.day'),
|
|
94
|
+
days: this.myTranslateService.instant('mosa.pipes.timeSince.days'),
|
|
95
|
+
month: this.myTranslateService.instant('mosa.pipes.timeSince.month'),
|
|
96
|
+
months: this.myTranslateService.instant('mosa.pipes.timeSince.months'),
|
|
97
|
+
year: this.myTranslateService.instant('mosa.pipes.timeSince.year'),
|
|
98
|
+
years: this.myTranslateService.instant('mosa.pipes.timeSince.years'),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { NgModule } from '@angular/core';
|
|
3
|
+
import { MosaDurationPipe } from './mosa-duration.pipe';
|
|
4
|
+
|
|
5
|
+
@NgModule({
|
|
6
|
+
declarations: [ MosaDurationPipe ],
|
|
7
|
+
imports: [
|
|
8
|
+
CommonModule,
|
|
9
|
+
],
|
|
10
|
+
exports: [ MosaDurationPipe ],
|
|
11
|
+
})
|
|
12
|
+
export class MosaDurationPipeModule {
|
|
13
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Pipe, PipeTransform } from '@angular/core';
|
|
2
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
3
|
+
import { BehaviorSubject, Observable } from 'rxjs';
|
|
4
|
+
import { map } from 'rxjs/operators';
|
|
5
|
+
import { MosaDurationFormat } from '../../models/mosa-duration.model';
|
|
6
|
+
|
|
7
|
+
@Pipe({
|
|
8
|
+
name: 'mosaDuration',
|
|
9
|
+
})
|
|
10
|
+
export class MosaDurationPipe implements PipeTransform {
|
|
11
|
+
|
|
12
|
+
private readonly store$: BehaviorSubject<number>;
|
|
13
|
+
private readonly interval: NodeJS.Timeout;
|
|
14
|
+
|
|
15
|
+
constructor(
|
|
16
|
+
private readonly myTranslateService: TranslateService,
|
|
17
|
+
) {
|
|
18
|
+
this.store$ = new BehaviorSubject<number>(new Date().getTime());
|
|
19
|
+
this.interval = setInterval(() => {
|
|
20
|
+
this.store$.next(new Date().getTime());
|
|
21
|
+
}, 1000);
|
|
22
|
+
this.myTranslateService.onLangChange.subscribe((): void => {
|
|
23
|
+
this.store$.next(new Date().getTime());
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Converts a timestamp to a duration in the given format
|
|
29
|
+
* @param millis
|
|
30
|
+
* @param format
|
|
31
|
+
* @returns
|
|
32
|
+
* auto: 15000 -> 15 seconds
|
|
33
|
+
* seconds: 15000 -> 15 seconds
|
|
34
|
+
* minutes: 60000 -> 1 minute
|
|
35
|
+
* hours: 7200000 -> 2 hours
|
|
36
|
+
* days: 172800000 -> 2 days
|
|
37
|
+
*/
|
|
38
|
+
public transform(millis: number, format: MosaDurationFormat = 'auto'): Observable<string> {
|
|
39
|
+
return this.store$.pipe(
|
|
40
|
+
map((currentDate: number): string => {
|
|
41
|
+
if (!millis) {
|
|
42
|
+
clearInterval(this.interval);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (millis - currentDate < 0) {
|
|
47
|
+
clearInterval(this.interval);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return this.calcDuration(currentDate, millis, format);
|
|
52
|
+
}),
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
private getTranslation(num: number, format: MosaDurationFormat): string {
|
|
58
|
+
if (num === 1) {
|
|
59
|
+
return `${ num.toFixed(0) } ${ this.myTranslateService.instant(`mosa.commons.dateTime[${ format }].label`) }`;
|
|
60
|
+
}
|
|
61
|
+
return `${ num.toFixed(0) } ${ this.myTranslateService.instant(`mosa.commons.dateTime[${ format }].plural.label`) }`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
private calcDuration(currentDate: number, millis: number, format: MosaDurationFormat): string {
|
|
66
|
+
millis = millis - currentDate;
|
|
67
|
+
|
|
68
|
+
const seconds: number = millis / 1000;
|
|
69
|
+
if (format === 'seconds') {
|
|
70
|
+
return this.getTranslation(seconds, 'seconds');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const minutes: number = seconds / 60;
|
|
74
|
+
if (format === 'minutes') {
|
|
75
|
+
return this.getTranslation(minutes, 'minutes');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const hours: number = minutes / 60;
|
|
79
|
+
if (format === 'hours') {
|
|
80
|
+
return this.getTranslation(hours, 'hours');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const days: number = hours / 24;
|
|
84
|
+
if (format === 'days') {
|
|
85
|
+
return this.getTranslation(days, 'days');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (format === 'auto') {
|
|
89
|
+
if (seconds < 60) {
|
|
90
|
+
return this.getTranslation(seconds, 'seconds');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (minutes < 60) {
|
|
94
|
+
return this.getTranslation(minutes, 'minutes');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (hours < 24) {
|
|
98
|
+
return this.getTranslation(hours, 'hours');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return this.getTranslation(days, 'days');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { HttpClient, HttpErrorResponse, HttpEvent, HttpHeaders, HttpResponse } from '@angular/common/http';
|
|
2
|
+
import { Injectable } from '@angular/core';
|
|
3
|
+
import { Observable, throwError } from 'rxjs';
|
|
4
|
+
import { catchError, map } from 'rxjs/operators';
|
|
5
|
+
import { IApiOptions } from '../models/api-options.model';
|
|
6
|
+
import { ITokenSettings } from '../models/token-settings.model';
|
|
7
|
+
import { CoreLoggerService } from './core-logger.service';
|
|
8
|
+
import { isNullOrEmpty } from '../utils/commons.util';
|
|
9
|
+
|
|
10
|
+
export const LOCAL_STORAGE_TOKEN_KEY = 'tokenSettings';
|
|
11
|
+
|
|
12
|
+
@Injectable({
|
|
13
|
+
providedIn: 'root',
|
|
14
|
+
})
|
|
15
|
+
export class ApiService {
|
|
16
|
+
|
|
17
|
+
constructor(
|
|
18
|
+
private readonly myCoreLoggerService: CoreLoggerService,
|
|
19
|
+
private readonly myHttpClient: HttpClient,
|
|
20
|
+
) {
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Gets an access token
|
|
25
|
+
* @deprecated use getToken()
|
|
26
|
+
*/
|
|
27
|
+
public getAccessToken(): string {
|
|
28
|
+
return window.localStorage.getItem('jwtAccessToken');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Sets an access token
|
|
33
|
+
* @param token
|
|
34
|
+
* @deprecated use setToken()
|
|
35
|
+
*/
|
|
36
|
+
public setAccessToken(token: string): void {
|
|
37
|
+
window.localStorage.setItem('jwtAccessToken', token);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Removes an access token from local storage
|
|
42
|
+
* @deprecated use deleteAccessToken()
|
|
43
|
+
*/
|
|
44
|
+
public removeAccessToken(): void {
|
|
45
|
+
window.localStorage.removeItem('jwtAccessToken');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Sets the token
|
|
50
|
+
* @param tokenSettings
|
|
51
|
+
*/
|
|
52
|
+
public setToken(tokenSettings: ITokenSettings): void {
|
|
53
|
+
window.localStorage.setItem(LOCAL_STORAGE_TOKEN_KEY, JSON.stringify(tokenSettings));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Gets token
|
|
58
|
+
*/
|
|
59
|
+
public getToken(): ITokenSettings {
|
|
60
|
+
const tokenSettings: string = window.localStorage.getItem(LOCAL_STORAGE_TOKEN_KEY);
|
|
61
|
+
if (isNullOrEmpty(tokenSettings)) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return JSON.parse(tokenSettings);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Deletes token
|
|
70
|
+
*/
|
|
71
|
+
public deleteToken(): void {
|
|
72
|
+
window.localStorage.removeItem(LOCAL_STORAGE_TOKEN_KEY);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Makes an http get call
|
|
77
|
+
* @param url
|
|
78
|
+
* @param headers
|
|
79
|
+
* @param options
|
|
80
|
+
*/
|
|
81
|
+
public get<T>(url: string, headers?: HttpHeaders, options?: IApiOptions): Observable<T> {
|
|
82
|
+
options = ApiService.serializeOptions(options);
|
|
83
|
+
headers = this.getHeaders(headers, options);
|
|
84
|
+
|
|
85
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
86
|
+
return this.myHttpClient.get<T>(url, { ...options.httpOptions as any, headers })
|
|
87
|
+
.pipe(
|
|
88
|
+
map((response: HttpEvent<T>) => this.handleResponse(response)),
|
|
89
|
+
catchError((err: HttpErrorResponse): Observable<never> => this.handleError(err, options)),
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Makes an async http get call, which also includes the response headers
|
|
95
|
+
* @param url
|
|
96
|
+
* @param headers
|
|
97
|
+
* @param options
|
|
98
|
+
*/
|
|
99
|
+
public async getWithHeadersAsync<T>(url: string, headers?: HttpHeaders, options?: IApiOptions): Promise<HttpEvent<T>> {
|
|
100
|
+
return this.getWithHeaders<T>(url, headers, options).toPromise();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Makes an http get call, which also includes the response headers
|
|
105
|
+
* @param url
|
|
106
|
+
* @param headers
|
|
107
|
+
* @param options
|
|
108
|
+
*/
|
|
109
|
+
public getWithHeaders<T>(url: string, headers?: HttpHeaders, options?: IApiOptions): Observable<HttpEvent<T>> {
|
|
110
|
+
options = ApiService.serializeOptions(options);
|
|
111
|
+
headers = this.getHeaders(headers, options);
|
|
112
|
+
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114
|
+
return this.myHttpClient.get<T>(url, { ...options.httpOptions as any, headers, observe: 'response' })
|
|
115
|
+
.pipe(
|
|
116
|
+
catchError((err: HttpErrorResponse): Observable<never> => this.handleError(err, options)),
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Makes an http patch call (For partial updates)
|
|
122
|
+
* @param url
|
|
123
|
+
* @param data
|
|
124
|
+
* @param headers
|
|
125
|
+
* @param options
|
|
126
|
+
*/
|
|
127
|
+
public patch<T, T1>(url: string, data?: T, headers?: HttpHeaders, options?: IApiOptions): Observable<T1> {
|
|
128
|
+
options = ApiService.serializeOptions(options);
|
|
129
|
+
headers = this.getHeaders(headers, options);
|
|
130
|
+
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
132
|
+
return this.myHttpClient.patch<T1>(url, data, { ...options.httpOptions as any, headers })
|
|
133
|
+
.pipe(
|
|
134
|
+
map((response: HttpEvent<T1>) => this.handleResponse(response)),
|
|
135
|
+
catchError((err: HttpErrorResponse): Observable<never> => this.handleError(err, options)),
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Makes an http put call
|
|
141
|
+
* @param url
|
|
142
|
+
* @param data
|
|
143
|
+
* @param headers
|
|
144
|
+
* @param options
|
|
145
|
+
*/
|
|
146
|
+
public put<T, T1>(url: string, data?: T, headers?: HttpHeaders, options?: IApiOptions): Observable<T1> {
|
|
147
|
+
options = ApiService.serializeOptions(options);
|
|
148
|
+
headers = this.getHeaders(headers, options);
|
|
149
|
+
|
|
150
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
151
|
+
return this.myHttpClient.put<T1>(url, data, { ...options.httpOptions as any, headers })
|
|
152
|
+
.pipe(
|
|
153
|
+
map((response: HttpEvent<T1>) => this.handleResponse(response)),
|
|
154
|
+
catchError((err: HttpErrorResponse): Observable<never> => this.handleError(err, options)),
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Makes an http post call
|
|
160
|
+
* @param url
|
|
161
|
+
* @param data
|
|
162
|
+
* @param headers
|
|
163
|
+
* @param options
|
|
164
|
+
*/
|
|
165
|
+
public post<T, T1>(url: string, data?: T, headers?: HttpHeaders, options?: IApiOptions): Observable<T1> {
|
|
166
|
+
options = ApiService.serializeOptions(options);
|
|
167
|
+
headers = this.getHeaders(headers, options);
|
|
168
|
+
|
|
169
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
170
|
+
return this.myHttpClient.post<T1>(url, data, { ...options.httpOptions as any, headers })
|
|
171
|
+
.pipe(
|
|
172
|
+
map((response: HttpEvent<T1>) => this.handleResponse(response)),
|
|
173
|
+
catchError((err: HttpErrorResponse): Observable<never> => this.handleError(err, options)),
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* makes an http delete call
|
|
179
|
+
* @param url
|
|
180
|
+
* @param headers
|
|
181
|
+
* @param options
|
|
182
|
+
* @returns Observable
|
|
183
|
+
*/
|
|
184
|
+
public delete<T>(url: string, headers?: HttpHeaders, options?: IApiOptions): Observable<T> {
|
|
185
|
+
options = ApiService.serializeOptions(options);
|
|
186
|
+
headers = this.getHeaders(headers, options);
|
|
187
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
188
|
+
return this.myHttpClient.delete<T>(url, { ...options.httpOptions as {}, headers })
|
|
189
|
+
.pipe(
|
|
190
|
+
catchError((err: HttpErrorResponse): Observable<never> => this.handleError(err, options)),
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Appends a script to the html body
|
|
196
|
+
* @param path
|
|
197
|
+
* @param attributes
|
|
198
|
+
* @param onLoad
|
|
199
|
+
*/
|
|
200
|
+
public loadExternalScript(path: string, attributes?: { key: string, value: string }[],
|
|
201
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
202
|
+
onLoad?: ((this: GlobalEventHandlers, ev: Event) => any)): void {
|
|
203
|
+
const script = document.createElement('script');
|
|
204
|
+
script.type = 'text/javascript';
|
|
205
|
+
script.src = path;
|
|
206
|
+
script.async = true;
|
|
207
|
+
|
|
208
|
+
if (onLoad) {
|
|
209
|
+
script.onload = onLoad;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (attributes) {
|
|
213
|
+
for (const attribute of attributes) {
|
|
214
|
+
script.setAttribute(attribute.key, attribute.value);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
document.body.append(script);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
private handleError(err: HttpErrorResponse, options: IApiOptions): Observable<never> {
|
|
222
|
+
if (!options?.skipErrorHandling) {
|
|
223
|
+
this.myCoreLoggerService.logError({ msg: err });
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return throwError(err);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private handleResponse<T>(response: HttpEvent<T>): T {
|
|
230
|
+
if (response instanceof HttpResponse) {
|
|
231
|
+
return response.body;
|
|
232
|
+
}
|
|
233
|
+
return response as T;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private getHeaders(headers: HttpHeaders, options: IApiOptions): HttpHeaders {
|
|
237
|
+
if (!headers) {
|
|
238
|
+
headers = new HttpHeaders();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (!options.skipContentType) {
|
|
242
|
+
if (!headers.get('Content-Type')) {
|
|
243
|
+
headers = headers.set('Content-Type', 'application/json');
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (!options?.skipAuth) {
|
|
248
|
+
if (this.getToken()) {
|
|
249
|
+
const tokenSettings: ITokenSettings = this.getToken();
|
|
250
|
+
headers = headers.set('Authorization', `${ tokenSettings.tokenType } ${ tokenSettings.token }`);
|
|
251
|
+
} else {
|
|
252
|
+
// Deprecated. Use ITokenSettings
|
|
253
|
+
headers = headers.set('Authorization', `Bearer ${ this.getAccessToken() }`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return headers;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
private static serializeOptions(options: IApiOptions): IApiOptions {
|
|
260
|
+
if (!options) {
|
|
261
|
+
options = {};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (!options.httpOptions) {
|
|
265
|
+
options.httpOptions = {};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return options;
|
|
269
|
+
}
|
|
270
|
+
}
|