@codex-ts/core-lib 1.0.16 → 1.0.18
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/fesm2022/codex-ts-core-lib.mjs +182 -35
- package/fesm2022/codex-ts-core-lib.mjs.map +1 -1
- package/lib/keycloak/keycloak-config.interface.d.ts +56 -7
- package/lib/keycloak/keycloak.interceptor.d.ts +11 -0
- package/lib/keycloak/keycloak.providers.d.ts +25 -0
- package/lib/keycloak/keycloak.service.d.ts +52 -0
- package/package.json +1 -1
- package/src/lib/assets/keycloak/silent-check-sso.html +0 -11
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, PLATFORM_ID, signal, computed, Injectable, importProvidersFrom, Component, NgModule, Directive, Input, ViewChild, Pipe } from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, PLATFORM_ID, signal, computed, Injectable, importProvidersFrom, APP_INITIALIZER, Component, NgModule, Directive, Input, ViewChild, Pipe } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common/http';
|
|
4
|
-
import { HttpClient, HttpClientModule, HttpParams } from '@angular/common/http';
|
|
4
|
+
import { HttpClient, HTTP_INTERCEPTORS, HttpClientModule, HttpParams } from '@angular/common/http';
|
|
5
5
|
import * as i1$2 from '@angular/common';
|
|
6
6
|
import { isPlatformBrowser, CommonModule, formatDate } from '@angular/common';
|
|
7
|
+
import { from, mergeMap, catchError, throwError, map, BehaviorSubject, finalize, Observable, forkJoin, of, isObservable, Subject, take as take$1, tap as tap$1, takeUntil as takeUntil$1, ReplaySubject, distinctUntilChanged as distinctUntilChanged$1 } from 'rxjs';
|
|
7
8
|
import * as i1$3 from '@angular/router';
|
|
8
9
|
import { Router } from '@angular/router';
|
|
9
10
|
import { toObservable } from '@angular/core/rxjs-interop';
|
|
10
|
-
import {
|
|
11
|
-
import { retry, timeout, catchError, take, map as map$1, finalize as finalize$1, switchMap, takeUntil, mergeMap, tap, debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
11
|
+
import { retry, timeout, catchError as catchError$1, take, map as map$1, finalize as finalize$1, switchMap, takeUntil, mergeMap as mergeMap$1, tap, debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
12
12
|
import * as i4 from 'primeng/api';
|
|
13
13
|
import * as i1$1 from '@angular/forms';
|
|
14
14
|
import { FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
@@ -138,6 +138,28 @@ var TaskRole;
|
|
|
138
138
|
|
|
139
139
|
const KEYCLOAK_CONFIG = new InjectionToken('KEYCLOAK_CONFIG');
|
|
140
140
|
|
|
141
|
+
/** Keycloak error types */
|
|
142
|
+
var KeycloakErrorType;
|
|
143
|
+
(function (KeycloakErrorType) {
|
|
144
|
+
KeycloakErrorType["SCRIPT_LOAD"] = "SCRIPT_LOAD_ERROR";
|
|
145
|
+
KeycloakErrorType["INIT"] = "INIT_ERROR";
|
|
146
|
+
KeycloakErrorType["TOKEN_REFRESH"] = "TOKEN_REFRESH_ERROR";
|
|
147
|
+
KeycloakErrorType["PROFILE_LOAD"] = "PROFILE_LOAD_ERROR";
|
|
148
|
+
})(KeycloakErrorType || (KeycloakErrorType = {}));
|
|
149
|
+
/** Keycloak error with type and details */
|
|
150
|
+
class KeycloakError extends Error {
|
|
151
|
+
type;
|
|
152
|
+
originalError;
|
|
153
|
+
constructor(type, message, originalError) {
|
|
154
|
+
super(message);
|
|
155
|
+
this.type = type;
|
|
156
|
+
this.originalError = originalError;
|
|
157
|
+
this.name = 'KeycloakError';
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Service for handling Keycloak authentication and authorization
|
|
162
|
+
*/
|
|
141
163
|
class KeycloakService {
|
|
142
164
|
http = inject(HttpClient);
|
|
143
165
|
platformId = inject(PLATFORM_ID);
|
|
@@ -148,6 +170,22 @@ class KeycloakService {
|
|
|
148
170
|
#userProfile = signal(null);
|
|
149
171
|
isAuthenticated$ = computed(() => this.#isAuthenticated());
|
|
150
172
|
userProfile$ = computed(() => this.#userProfile());
|
|
173
|
+
/** Check if URL should be excluded from bearer token */
|
|
174
|
+
isUrlExcluded(url) {
|
|
175
|
+
return this.config.bearerExcludedUrls?.some(excluded => url.startsWith(excluded) || new RegExp(excluded).test(url)) ?? false;
|
|
176
|
+
}
|
|
177
|
+
/** Validate Keycloak configuration */
|
|
178
|
+
validateConfig() {
|
|
179
|
+
if (!this.config.authServerUrl) {
|
|
180
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Auth server URL is required');
|
|
181
|
+
}
|
|
182
|
+
if (!this.config.realm) {
|
|
183
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Realm is required');
|
|
184
|
+
}
|
|
185
|
+
if (!this.config.clientId) {
|
|
186
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Client ID is required');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
151
189
|
loadKeycloakScript() {
|
|
152
190
|
if (!this.isBrowser)
|
|
153
191
|
return Promise.resolve();
|
|
@@ -165,19 +203,30 @@ class KeycloakService {
|
|
|
165
203
|
getSilentCheckUrl() {
|
|
166
204
|
if (!this.isBrowser)
|
|
167
205
|
return '';
|
|
168
|
-
|
|
206
|
+
// Use the configured URL or fallback to a default location
|
|
207
|
+
return this.config.silentCheckSsoRedirectUri ??
|
|
208
|
+
`${window.location.origin}/assets/silent-check-sso.html`;
|
|
169
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Initialize Keycloak authentication
|
|
212
|
+
* @returns Promise resolving to true if initialization is successful
|
|
213
|
+
* @throws KeycloakError if initialization fails
|
|
214
|
+
*/
|
|
170
215
|
async initialize() {
|
|
171
216
|
if (!this.isBrowser)
|
|
172
217
|
return false;
|
|
173
218
|
try {
|
|
219
|
+
this.validateConfig();
|
|
174
220
|
await this.loadKeycloakScript();
|
|
175
221
|
const keycloak = new Keycloak(this.config);
|
|
176
222
|
this.#keycloakInstance.set(keycloak);
|
|
177
|
-
const
|
|
178
|
-
onLoad: '
|
|
179
|
-
silentCheckSsoRedirectUri: this.getSilentCheckUrl()
|
|
180
|
-
|
|
223
|
+
const initOptions = {
|
|
224
|
+
onLoad: 'login-required',
|
|
225
|
+
silentCheckSsoRedirectUri: this.getSilentCheckUrl(),
|
|
226
|
+
checkLoginIframe: false,
|
|
227
|
+
...this.config.initOptions
|
|
228
|
+
};
|
|
229
|
+
const authenticated = await keycloak.init(initOptions);
|
|
181
230
|
this.#isAuthenticated.set(authenticated);
|
|
182
231
|
if (authenticated) {
|
|
183
232
|
await this.loadUserProfile();
|
|
@@ -185,45 +234,78 @@ class KeycloakService {
|
|
|
185
234
|
return authenticated;
|
|
186
235
|
}
|
|
187
236
|
catch (error) {
|
|
188
|
-
|
|
189
|
-
return false;
|
|
237
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Failed to initialize Keycloak', error);
|
|
190
238
|
}
|
|
191
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* Redirect to Keycloak login page
|
|
242
|
+
* @param options Additional login options
|
|
243
|
+
* @returns Promise resolving when login is complete
|
|
244
|
+
*/
|
|
192
245
|
login(options = {}) {
|
|
246
|
+
const instance = this.#keycloakInstance();
|
|
247
|
+
if (!instance) {
|
|
248
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Keycloak not initialized');
|
|
249
|
+
}
|
|
193
250
|
const loginOptions = {
|
|
194
251
|
...this.config.loginOptions,
|
|
195
252
|
...options
|
|
196
253
|
};
|
|
197
|
-
return
|
|
254
|
+
return instance.login(loginOptions);
|
|
198
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* Logout the current user
|
|
258
|
+
* @returns Promise resolving when logout is complete
|
|
259
|
+
*/
|
|
199
260
|
logout() {
|
|
200
|
-
|
|
261
|
+
const instance = this.#keycloakInstance();
|
|
262
|
+
if (!instance) {
|
|
263
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Keycloak not initialized');
|
|
264
|
+
}
|
|
265
|
+
return instance.logout();
|
|
201
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Get the current access token
|
|
269
|
+
* @returns Promise resolving to the access token or null
|
|
270
|
+
*/
|
|
202
271
|
async getToken() {
|
|
203
272
|
try {
|
|
204
273
|
await this.updateToken(this.config.tokenValidityInSeconds || 60);
|
|
205
|
-
return this.#keycloakInstance()?.token;
|
|
274
|
+
return this.#keycloakInstance()?.token ?? null;
|
|
206
275
|
}
|
|
207
276
|
catch (error) {
|
|
208
|
-
|
|
209
|
-
return null;
|
|
277
|
+
throw new KeycloakError(KeycloakErrorType.TOKEN_REFRESH, 'Failed to get token', error);
|
|
210
278
|
}
|
|
211
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* Get the current user's roles
|
|
282
|
+
* @returns Array of role names
|
|
283
|
+
*/
|
|
212
284
|
getRoles() {
|
|
213
285
|
const keycloak = this.#keycloakInstance();
|
|
214
|
-
if (!keycloak
|
|
215
|
-
|
|
286
|
+
if (!keycloak) {
|
|
287
|
+
throw new KeycloakError(KeycloakErrorType.INIT, 'Keycloak not initialized');
|
|
216
288
|
}
|
|
217
|
-
return keycloak.realmAccess
|
|
289
|
+
return keycloak.realmAccess?.roles ?? [];
|
|
218
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Check if the current user has a specific role
|
|
293
|
+
* @param role Role name to check
|
|
294
|
+
* @returns true if user has the role
|
|
295
|
+
*/
|
|
219
296
|
hasRole(role) {
|
|
220
297
|
return this.getRoles().includes(role);
|
|
221
298
|
}
|
|
299
|
+
/**
|
|
300
|
+
* Update the access token if it's close to expiring
|
|
301
|
+
* @param minValidity Minimum validity time in seconds
|
|
302
|
+
* @returns Promise resolving to true if token was refreshed
|
|
303
|
+
*/
|
|
222
304
|
updateToken(minValidity = 60) {
|
|
223
305
|
return new Promise((resolve, reject) => {
|
|
224
306
|
const keycloak = this.#keycloakInstance();
|
|
225
307
|
if (!keycloak?.token) {
|
|
226
|
-
|
|
308
|
+
reject(new KeycloakError(KeycloakErrorType.TOKEN_REFRESH, 'No token available'));
|
|
227
309
|
return;
|
|
228
310
|
}
|
|
229
311
|
keycloak.updateToken(minValidity)
|
|
@@ -231,8 +313,7 @@ class KeycloakService {
|
|
|
231
313
|
resolve(refreshed);
|
|
232
314
|
})
|
|
233
315
|
.catch((error) => {
|
|
234
|
-
|
|
235
|
-
reject(error);
|
|
316
|
+
reject(new KeycloakError(KeycloakErrorType.TOKEN_REFRESH, 'Failed to refresh token', error));
|
|
236
317
|
});
|
|
237
318
|
});
|
|
238
319
|
}
|
|
@@ -256,6 +337,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImpor
|
|
|
256
337
|
args: [{ providedIn: 'root' }]
|
|
257
338
|
}] });
|
|
258
339
|
|
|
340
|
+
class KeycloakAuthInterceptor {
|
|
341
|
+
keycloakService;
|
|
342
|
+
constructor(keycloakService) {
|
|
343
|
+
this.keycloakService = keycloakService;
|
|
344
|
+
}
|
|
345
|
+
intercept(req, next) {
|
|
346
|
+
// Skip bearer token for excluded URLs
|
|
347
|
+
if (this.keycloakService.isUrlExcluded(req.url)) {
|
|
348
|
+
return next.handle(req);
|
|
349
|
+
}
|
|
350
|
+
return from(this.keycloakService.getToken()).pipe(mergeMap(token => {
|
|
351
|
+
if (token) {
|
|
352
|
+
const authReq = req.clone({
|
|
353
|
+
headers: req.headers.set('Authorization', `Bearer ${token}`)
|
|
354
|
+
});
|
|
355
|
+
return next.handle(authReq);
|
|
356
|
+
}
|
|
357
|
+
return next.handle(req);
|
|
358
|
+
}), catchError((error) => {
|
|
359
|
+
// Handle 401/403 errors by refreshing token or redirecting to login
|
|
360
|
+
if (error.status === 401 || error.status === 403) {
|
|
361
|
+
return from(this.keycloakService.updateToken()).pipe(mergeMap(refreshed => {
|
|
362
|
+
if (refreshed) {
|
|
363
|
+
return from(this.keycloakService.getToken()).pipe(mergeMap(newToken => {
|
|
364
|
+
const authReq = req.clone({
|
|
365
|
+
headers: req.headers.set('Authorization', `Bearer ${newToken}`)
|
|
366
|
+
});
|
|
367
|
+
return next.handle(authReq);
|
|
368
|
+
}));
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
// Token refresh failed, redirect to login
|
|
372
|
+
this.keycloakService.login();
|
|
373
|
+
return throwError(() => error);
|
|
374
|
+
}
|
|
375
|
+
}));
|
|
376
|
+
}
|
|
377
|
+
return throwError(() => error);
|
|
378
|
+
}));
|
|
379
|
+
}
|
|
380
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: KeycloakAuthInterceptor, deps: [{ token: KeycloakService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
381
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: KeycloakAuthInterceptor });
|
|
382
|
+
}
|
|
383
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: KeycloakAuthInterceptor, decorators: [{
|
|
384
|
+
type: Injectable
|
|
385
|
+
}], ctorParameters: () => [{ type: KeycloakService }] });
|
|
386
|
+
|
|
387
|
+
function initializeKeycloak(keycloak) {
|
|
388
|
+
return () => keycloak.initialize();
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Provides Keycloak authentication and authorization services
|
|
392
|
+
* @param config Keycloak configuration
|
|
393
|
+
* @returns Array of providers for Keycloak integration
|
|
394
|
+
*/
|
|
259
395
|
function provideKeycloak(config) {
|
|
260
396
|
return [
|
|
261
397
|
importProvidersFrom(HttpClientModule),
|
|
@@ -263,7 +399,18 @@ function provideKeycloak(config) {
|
|
|
263
399
|
provide: KEYCLOAK_CONFIG,
|
|
264
400
|
useValue: config
|
|
265
401
|
},
|
|
266
|
-
KeycloakService
|
|
402
|
+
KeycloakService,
|
|
403
|
+
{
|
|
404
|
+
provide: APP_INITIALIZER,
|
|
405
|
+
useFactory: initializeKeycloak,
|
|
406
|
+
multi: true,
|
|
407
|
+
deps: [KeycloakService]
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
provide: HTTP_INTERCEPTORS,
|
|
411
|
+
useClass: KeycloakAuthInterceptor,
|
|
412
|
+
multi: true
|
|
413
|
+
}
|
|
267
414
|
];
|
|
268
415
|
}
|
|
269
416
|
|
|
@@ -334,7 +481,7 @@ class HttpUtilityService {
|
|
|
334
481
|
if (options?.timeoutMs) {
|
|
335
482
|
request$ = request$.pipe(timeout(options.timeoutMs));
|
|
336
483
|
}
|
|
337
|
-
return request$.pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
484
|
+
return request$.pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
338
485
|
}
|
|
339
486
|
/**
|
|
340
487
|
* Perform a POST request with enhanced options
|
|
@@ -357,7 +504,7 @@ class HttpUtilityService {
|
|
|
357
504
|
if (options?.timeoutMs) {
|
|
358
505
|
request$ = request$.pipe(timeout(options.timeoutMs));
|
|
359
506
|
}
|
|
360
|
-
return request$.pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
507
|
+
return request$.pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
361
508
|
}
|
|
362
509
|
/**
|
|
363
510
|
* Perform a PUT request with enhanced options
|
|
@@ -380,7 +527,7 @@ class HttpUtilityService {
|
|
|
380
527
|
if (options?.timeoutMs) {
|
|
381
528
|
request$ = request$.pipe(timeout(options.timeoutMs));
|
|
382
529
|
}
|
|
383
|
-
return request$.pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
530
|
+
return request$.pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
384
531
|
}
|
|
385
532
|
/**
|
|
386
533
|
* Perform a DELETE request with enhanced options
|
|
@@ -402,7 +549,7 @@ class HttpUtilityService {
|
|
|
402
549
|
if (options?.timeoutMs) {
|
|
403
550
|
request$ = request$.pipe(timeout(options.timeoutMs));
|
|
404
551
|
}
|
|
405
|
-
return request$.pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
552
|
+
return request$.pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
406
553
|
}
|
|
407
554
|
/**
|
|
408
555
|
* Upload a file with optional additional data
|
|
@@ -465,7 +612,7 @@ class HttpUtilityService {
|
|
|
465
612
|
});
|
|
466
613
|
}
|
|
467
614
|
// Standard request without progress tracking
|
|
468
|
-
return request$.pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
615
|
+
return request$.pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
469
616
|
}
|
|
470
617
|
/**
|
|
471
618
|
* Execute multiple HTTP requests in parallel
|
|
@@ -474,7 +621,7 @@ class HttpUtilityService {
|
|
|
474
621
|
*/
|
|
475
622
|
batchRequests(requests) {
|
|
476
623
|
this.loading.next(true);
|
|
477
|
-
return forkJoin(requests).pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
624
|
+
return forkJoin(requests).pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
478
625
|
}
|
|
479
626
|
/**
|
|
480
627
|
* Download a file from the server
|
|
@@ -493,7 +640,7 @@ class HttpUtilityService {
|
|
|
493
640
|
if (options?.timeoutMs) {
|
|
494
641
|
request$ = request$.pipe(timeout(options.timeoutMs));
|
|
495
642
|
}
|
|
496
|
-
return request$.pipe(catchError(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
643
|
+
return request$.pipe(catchError$1(this.handleError.bind(this)), finalize(() => this.loading.next(false)));
|
|
497
644
|
}
|
|
498
645
|
/**
|
|
499
646
|
* Create parameter string from an object
|
|
@@ -1814,7 +1961,7 @@ class BaseFormComponent extends BasePageComponent {
|
|
|
1814
1961
|
}));
|
|
1815
1962
|
}
|
|
1816
1963
|
loadFormData() {
|
|
1817
|
-
return this.route.queryParams.pipe(take(1), mergeMap(params => {
|
|
1964
|
+
return this.route.queryParams.pipe(take(1), mergeMap$1(params => {
|
|
1818
1965
|
const state = this.getRouterState();
|
|
1819
1966
|
if (this.state.mode === AppConstants.PAGE_MODE.CREATE) {
|
|
1820
1967
|
return of(void 0);
|
|
@@ -2407,7 +2554,7 @@ class BaseTabbedFormComponent extends BasePageComponent {
|
|
|
2407
2554
|
activeTab: tabs[0]?.value || ''
|
|
2408
2555
|
};
|
|
2409
2556
|
// Then initialize form
|
|
2410
|
-
this.route.queryParams.pipe(take$1(1), tap$1(() => this.state = { ...this.state, loading: true }), tap$1(params => this.initializeForm(params)), map(() => void 0), catchError
|
|
2557
|
+
this.route.queryParams.pipe(take$1(1), tap$1(() => this.state = { ...this.state, loading: true }), tap$1(params => this.initializeForm(params)), map(() => void 0), catchError(error => {
|
|
2411
2558
|
console.error('Error initializing form:', error);
|
|
2412
2559
|
this.showError(AppMessages.FORM.ERROR.INIT);
|
|
2413
2560
|
return of(void 0);
|
|
@@ -2469,7 +2616,7 @@ class BaseTabbedFormComponent extends BasePageComponent {
|
|
|
2469
2616
|
throw new Error(`UUID is required for ${this.state.mode} mode when no formData is provided`);
|
|
2470
2617
|
}
|
|
2471
2618
|
return uuid;
|
|
2472
|
-
}), tap$1(() => this.state = { ...this.state, loading: true }), tap$1(uuid => this.loadEntity(uuid)), catchError
|
|
2619
|
+
}), tap$1(() => this.state = { ...this.state, loading: true }), tap$1(uuid => this.loadEntity(uuid)), catchError(error => {
|
|
2473
2620
|
console.error('Error loading UUID:', error);
|
|
2474
2621
|
this.showError(`${AppMessages.FORM.ERROR.LOAD} UUID`);
|
|
2475
2622
|
return of(void 0);
|
|
@@ -2670,7 +2817,7 @@ class BaseListTabbedFormComponent extends BasePageComponent {
|
|
|
2670
2817
|
this.setupRouteParamsSubscription();
|
|
2671
2818
|
}
|
|
2672
2819
|
initializeFormFromQueryParams() {
|
|
2673
|
-
this.route.queryParams.pipe(take$1(1), catchError
|
|
2820
|
+
this.route.queryParams.pipe(take$1(1), catchError(error => {
|
|
2674
2821
|
console.error('Error initializing form:', error);
|
|
2675
2822
|
this.showError(AppMessages.FORM.ERROR.INIT);
|
|
2676
2823
|
throw error;
|
|
@@ -3120,5 +3267,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImpor
|
|
|
3120
3267
|
* Generated bundle index. Do not edit.
|
|
3121
3268
|
*/
|
|
3122
3269
|
|
|
3123
|
-
export { AppConstants, AppMessages, BaseCrudService, BaseFormComponent, BaseListPageComponent, BaseListTabbedFormComponent, BasePageComponent, BaseTabbedFormComponent, BaseTaskDashboardComponent, BaseTaskDetailsComponent, BaseTaskService, ComponentContext, CoreFormlyModule, FormService, FormlyConfigService, HttpUtilityService, IndianDatePipe, KEYCLOAK_CONFIG, KeycloakAuthGuard, KeycloakService, NotificationService, TabbedFormType, TaskRole, UtilsService, provideKeycloak };
|
|
3270
|
+
export { AppConstants, AppMessages, BaseCrudService, BaseFormComponent, BaseListPageComponent, BaseListTabbedFormComponent, BasePageComponent, BaseTabbedFormComponent, BaseTaskDashboardComponent, BaseTaskDetailsComponent, BaseTaskService, ComponentContext, CoreFormlyModule, FormService, FormlyConfigService, HttpUtilityService, IndianDatePipe, KEYCLOAK_CONFIG, KeycloakAuthGuard, KeycloakError, KeycloakErrorType, KeycloakService, NotificationService, TabbedFormType, TaskRole, UtilsService, provideKeycloak };
|
|
3124
3271
|
//# sourceMappingURL=codex-ts-core-lib.mjs.map
|