@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.
Files changed (60) hide show
  1. package/.eslintrc.json +31 -0
  2. package/README.md +24 -0
  3. package/ng-package.json +10 -0
  4. package/package.json +12 -0
  5. package/src/assets/i18n/mosa-de-DE.json +60 -0
  6. package/src/assets/i18n/mosa-en-US.json +60 -0
  7. package/src/lib/constants/local-storage.constant.ts +4 -0
  8. package/src/lib/enums/browser.enum.ts +9 -0
  9. package/src/lib/enums/content-position.enum.ts +11 -0
  10. package/src/lib/enums/i18n-supported.enum.ts +10 -0
  11. package/src/lib/enums/theme.enum.ts +4 -0
  12. package/src/lib/models/api-options.model.ts +21 -0
  13. package/src/lib/models/dictionary-item.model.ts +8 -0
  14. package/src/lib/models/key-map.model.ts +3 -0
  15. package/src/lib/models/logger/log-event.model.ts +8 -0
  16. package/src/lib/models/logger/log-message-data.model.ts +5 -0
  17. package/src/lib/models/logger/log-type.model.ts +1 -0
  18. package/src/lib/models/logger/log.model.ts +10 -0
  19. package/src/lib/models/logger/logger-base-config.model.ts +8 -0
  20. package/src/lib/models/logger/logger-config.model.ts +9 -0
  21. package/src/lib/models/logger/logger-default-config.model.ts +5 -0
  22. package/src/lib/models/mosa-duration.model.ts +1 -0
  23. package/src/lib/models/sieve/sieve-filter.model.ts +10 -0
  24. package/src/lib/models/sieve/sieve-operator.model.ts +69 -0
  25. package/src/lib/models/sieve/sieve-options.model.ts +13 -0
  26. package/src/lib/models/sieve/sieve-response.model.ts +4 -0
  27. package/src/lib/models/sieve/sieve-sort.model.ts +7 -0
  28. package/src/lib/models/token-settings.model.ts +5 -0
  29. package/src/lib/models/transform-matrix.model.ts +5 -0
  30. package/src/lib/mosa-core.module.ts +117 -0
  31. package/src/lib/pipes/dictionary-item-pipe/dictionary-item-pipe.module.ts +15 -0
  32. package/src/lib/pipes/dictionary-item-pipe/dictionary-item.pipe.ts +14 -0
  33. package/src/lib/pipes/find-in-array/find-in-array-pipe.module.ts +17 -0
  34. package/src/lib/pipes/find-in-array/find-in-array.pipe.spec.ts +8 -0
  35. package/src/lib/pipes/find-in-array/find-in-array.pipe.ts +34 -0
  36. package/src/lib/pipes/join/join-pipe.module.ts +17 -0
  37. package/src/lib/pipes/join/join.pipe.spec.ts +8 -0
  38. package/src/lib/pipes/join/join.pipe.ts +20 -0
  39. package/src/lib/pipes/mosa-date-pipe/mosa-date-pipe.module.ts +14 -0
  40. package/src/lib/pipes/mosa-date-pipe/mosa-date.pipe.ts +102 -0
  41. package/src/lib/pipes/mosa-duration-pipe/mosa-duration-pipe.module.ts +13 -0
  42. package/src/lib/pipes/mosa-duration-pipe/mosa-duration.pipe.ts +106 -0
  43. package/src/lib/services/api.service.ts +270 -0
  44. package/src/lib/services/core-logger.service.ts +219 -0
  45. package/src/lib/services/guards/can-deactivate.guard.ts +18 -0
  46. package/src/lib/services/mosa-socket.service.ts +46 -0
  47. package/src/lib/services/translation/assets-i18n-loader.service.ts +67 -0
  48. package/src/lib/services/translation/custom-translate-loader.service.ts +27 -0
  49. package/src/lib/services/translation/translate-collector.service.ts +60 -0
  50. package/src/lib/utils/commons.util.ts +100 -0
  51. package/src/lib/utils/dictionary.util.ts +140 -0
  52. package/src/lib/utils/item.util.ts +4 -0
  53. package/src/lib/utils/promise.util.ts +3 -0
  54. package/src/lib/utils/prototypes.util.ts +167 -0
  55. package/src/lib/utils/sieve.util.ts +169 -0
  56. package/src/lib/utils/size.util.ts +4 -0
  57. package/src/public-api.ts +1 -0
  58. package/tsconfig.lib.json +16 -0
  59. package/tsconfig.lib.prod.json +10 -0
  60. 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,8 @@
1
+ import { JoinPipe } from './join.pipe';
2
+
3
+ describe('JoinPipe', (): void => {
4
+ it('create an instance', (): void => {
5
+ const pipe: JoinPipe = new JoinPipe();
6
+ void expect(pipe).toBeTruthy();
7
+ });
8
+ });
@@ -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
+ }