@opensourcekd/ng-common-libs 1.2.4 → 1.2.5

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.
@@ -1,858 +1,41 @@
1
1
  'use strict';
2
2
 
3
3
  var core = require('@angular/core');
4
- var rxjs = require('rxjs');
5
- var operators = require('rxjs/operators');
6
- var http = require('@angular/common/http');
7
- var router = require('@angular/router');
8
-
9
- /******************************************************************************
10
- Copyright (c) Microsoft Corporation.
11
-
12
- Permission to use, copy, modify, and/or distribute this software for any
13
- purpose with or without fee is hereby granted.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
16
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
17
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
18
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
19
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
20
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21
- PERFORMANCE OF THIS SOFTWARE.
22
- ***************************************************************************** */
23
- /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
24
-
25
-
26
- function __decorate(decorators, target, key, desc) {
27
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
28
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
29
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
30
- return c > 3 && r && Object.defineProperty(target, key, r), r;
31
- }
32
-
33
- function __metadata(metadataKey, metadataValue) {
34
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
35
- }
36
-
37
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
38
- var e = new Error(message);
39
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
40
- };
41
-
42
- /**
43
- * EventBus - A centralized event bus for application-wide communication
44
- * Framework-agnostic implementation using only RxJS
45
- *
46
- * @example
47
- * ```typescript
48
- * // Create an instance
49
- * const eventBus = new EventBus();
50
- *
51
- * // Emit an event
52
- * eventBus.emit('user:login', { userId: '123', username: 'john' });
53
- *
54
- * // Subscribe to an event
55
- * eventBus.on('user:login').subscribe(data => {
56
- * console.log('User logged in:', data);
57
- * });
58
- * ```
59
- */
60
- class EventBus {
61
- eventSubject = new rxjs.Subject();
62
- /**
63
- * Emit an event with optional data
64
- * @param eventType - The type/name of the event
65
- * @param data - Optional data to send with the event
66
- */
67
- emit(eventType, data) {
68
- this.eventSubject.next({
69
- type: eventType,
70
- data,
71
- timestamp: Date.now()
72
- });
73
- }
74
- /**
75
- * Subscribe to a specific event type
76
- * @param eventType - The type/name of the event to listen for
77
- * @returns Observable that emits the event data
78
- */
79
- on(eventType) {
80
- return this.eventSubject.asObservable().pipe(operators.filter(event => event.type === eventType), operators.map(event => event.data));
81
- }
82
- /**
83
- * Subscribe to multiple event types
84
- * @param eventTypes - Array of event types to listen for
85
- * @returns Observable that emits the full event payload
86
- */
87
- onMultiple(eventTypes) {
88
- return this.eventSubject.asObservable().pipe(operators.filter(event => eventTypes.includes(event.type)));
89
- }
90
- /**
91
- * Subscribe to all events
92
- * @returns Observable that emits all event payloads
93
- */
94
- onAll() {
95
- return this.eventSubject.asObservable();
96
- }
97
- }
98
-
99
- /**
100
- * NgEventEmitter - Angular service wrapper for EventBus
101
- * Provides Angular dependency injection support for the framework-agnostic EventBus
102
- *
103
- * @example
104
- * ```typescript
105
- * import { Component, inject } from '@angular/core';
106
- * import { NgEventEmitter } from 'common-libs';
107
- *
108
- * @Component({
109
- * selector: 'app-example',
110
- * template: '...'
111
- * })
112
- * export class ExampleComponent {
113
- * private eventEmitter = inject(NgEventEmitter);
114
- *
115
- * ngOnInit() {
116
- * this.eventEmitter.on('user:login').subscribe(data => {
117
- * console.log('User logged in:', data);
118
- * });
119
- * }
120
- *
121
- * login() {
122
- * this.eventEmitter.emit('user:login', { userId: '123' });
123
- * }
124
- * }
125
- * ```
126
- */
127
- exports.NgEventEmitter = class NgEventEmitter extends EventBus {
128
- constructor() {
129
- super();
130
- }
131
- };
132
- exports.NgEventEmitter = __decorate([
133
- core.Injectable({
134
- providedIn: 'root'
135
- }),
136
- __metadata("design:paramtypes", [])
137
- ], exports.NgEventEmitter);
138
-
139
- /**
140
- * TokenManager - Manages authentication tokens
141
- * Framework-agnostic implementation using browser storage APIs
142
- * Handles storage, retrieval, and validation of JWT tokens
143
- *
144
- * @example
145
- * ```typescript
146
- * const tokenManager = new TokenManager();
147
- *
148
- * // Store a token
149
- * tokenManager.setToken('your-jwt-token');
150
- *
151
- * // Check if authenticated
152
- * if (tokenManager.isAuthenticated()) {
153
- * const userData = tokenManager.getUserFromToken();
154
- * }
155
- * ```
156
- */
157
- class TokenManager {
158
- TOKEN_KEY = 'auth_token';
159
- REFRESH_TOKEN_KEY = 'refresh_token';
160
- useSessionStorage = false;
161
- /**
162
- * Configure token manager
163
- */
164
- configure(config) {
165
- if (config.tokenKey) {
166
- this.TOKEN_KEY = config.tokenKey;
167
- }
168
- if (config.refreshTokenKey) {
169
- this.REFRESH_TOKEN_KEY = config.refreshTokenKey;
170
- }
171
- if (config.useSessionStorage !== undefined) {
172
- this.useSessionStorage = config.useSessionStorage;
173
- }
174
- }
175
- /**
176
- * Get the storage mechanism based on configuration
177
- */
178
- getStorage() {
179
- return this.useSessionStorage ? sessionStorage : localStorage;
180
- }
181
- /**
182
- * Set authentication token
183
- */
184
- setToken(token) {
185
- this.getStorage().setItem(this.TOKEN_KEY, token);
186
- }
187
- /**
188
- * Get authentication token
189
- */
190
- getToken() {
191
- return this.getStorage().getItem(this.TOKEN_KEY);
192
- }
193
- /**
194
- * Remove authentication token
195
- */
196
- removeToken() {
197
- this.getStorage().removeItem(this.TOKEN_KEY);
198
- }
199
- /**
200
- * Set refresh token
201
- */
202
- setRefreshToken(token) {
203
- this.getStorage().setItem(this.REFRESH_TOKEN_KEY, token);
204
- }
205
- /**
206
- * Get refresh token
207
- */
208
- getRefreshToken() {
209
- return this.getStorage().getItem(this.REFRESH_TOKEN_KEY);
210
- }
211
- /**
212
- * Remove refresh token
213
- */
214
- removeRefreshToken() {
215
- this.getStorage().removeItem(this.REFRESH_TOKEN_KEY);
216
- }
217
- /**
218
- * Clear all tokens
219
- */
220
- clearTokens() {
221
- this.removeToken();
222
- this.removeRefreshToken();
223
- }
224
- /**
225
- * Check if token exists
226
- */
227
- hasToken() {
228
- return !!this.getToken();
229
- }
230
- /**
231
- * Decode JWT token (without verification)
232
- * @param token - JWT token to decode
233
- * @returns Decoded token payload or null if invalid
234
- */
235
- decodeToken(token) {
236
- const tokenToDecode = token || this.getToken();
237
- if (!tokenToDecode)
238
- return null;
239
- try {
240
- const parts = tokenToDecode.split('.');
241
- if (parts.length !== 3)
242
- return null;
243
- const payload = parts[1];
244
- const decoded = JSON.parse(atob(payload.replace(/-/g, '+').replace(/_/g, '/')));
245
- return decoded;
246
- }
247
- catch (error) {
248
- console.error('Error decoding token:', error);
249
- return null;
250
- }
251
- }
252
- /**
253
- * Check if token is expired
254
- * @param token - Optional token to check (defaults to stored token)
255
- * @returns true if token is expired or invalid
256
- */
257
- isTokenExpired(token) {
258
- const decoded = this.decodeToken(token);
259
- if (!decoded || !decoded.exp)
260
- return true;
261
- const expirationDate = new Date(decoded.exp * 1000);
262
- return expirationDate <= new Date();
263
- }
264
- /**
265
- * Check if user is authenticated (has valid, non-expired token)
266
- */
267
- isAuthenticated() {
268
- return this.hasToken() && !this.isTokenExpired();
269
- }
270
- /**
271
- * Get token expiration date
272
- */
273
- getTokenExpirationDate(token) {
274
- const decoded = this.decodeToken(token);
275
- if (!decoded || !decoded.exp)
276
- return null;
277
- return new Date(decoded.exp * 1000);
278
- }
279
- /**
280
- * Get user data from token
281
- */
282
- getUserFromToken(token) {
283
- return this.decodeToken(token);
284
- }
285
- }
286
-
287
- /**
288
- * TokenService - Angular service wrapper for TokenManager
289
- * Provides Angular dependency injection support for the framework-agnostic TokenManager
290
- *
291
- * @example
292
- * ```typescript
293
- * import { Component, inject } from '@angular/core';
294
- * import { TokenService } from 'common-libs';
295
- *
296
- * export class AuthService {
297
- * private tokenService = inject(TokenService);
298
- *
299
- * login(token: string) {
300
- * this.tokenService.setToken(token);
301
- * }
302
- *
303
- * isAuthenticated(): boolean {
304
- * return this.tokenService.isAuthenticated();
305
- * }
306
- * }
307
- * ```
308
- */
309
- exports.TokenService = class TokenService extends TokenManager {
310
- constructor() {
311
- console.log("In TokenService of opensourcekd 2");
312
- super();
313
- }
314
- };
315
- exports.TokenService = __decorate([
316
- core.Injectable({
317
- providedIn: 'root'
318
- }),
319
- __metadata("design:paramtypes", [])
320
- ], exports.TokenService);
321
-
322
- /**
323
- * StorageManager - Type-safe wrapper for browser storage
324
- * Framework-agnostic implementation using browser storage APIs
325
- * Provides JSON serialization/deserialization and error handling
326
- *
327
- * @example
328
- * ```typescript
329
- * const storage = new StorageManager();
330
- *
331
- * // Store data
332
- * storage.setLocal('user-prefs', { theme: 'dark', lang: 'en' });
333
- *
334
- * // Retrieve data
335
- * const prefs = storage.getLocal('user-prefs');
336
- *
337
- * // With expiration
338
- * storage.setWithExpiration('temp-data', someData, 3600000); // 1 hour
339
- * ```
340
- */
341
- class StorageManager {
342
- /**
343
- * Set item in localStorage with JSON serialization
344
- */
345
- setLocal(key, value) {
346
- try {
347
- const serialized = JSON.stringify(value);
348
- localStorage.setItem(key, serialized);
349
- return true;
350
- }
351
- catch (error) {
352
- console.error('Error setting localStorage item:', error);
353
- return false;
354
- }
355
- }
356
- /**
357
- * Get item from localStorage with JSON deserialization
358
- */
359
- getLocal(key, defaultValue) {
360
- try {
361
- const item = localStorage.getItem(key);
362
- if (item === null) {
363
- return defaultValue !== undefined ? defaultValue : null;
364
- }
365
- return JSON.parse(item);
366
- }
367
- catch (error) {
368
- console.error('Error getting localStorage item:', error);
369
- return defaultValue !== undefined ? defaultValue : null;
370
- }
371
- }
372
- /**
373
- * Remove item from localStorage
374
- */
375
- removeLocal(key) {
376
- try {
377
- localStorage.removeItem(key);
378
- }
379
- catch (error) {
380
- console.error('Error removing localStorage item:', error);
381
- }
382
- }
383
- /**
384
- * Clear all localStorage items
385
- */
386
- clearLocal() {
387
- try {
388
- localStorage.clear();
389
- }
390
- catch (error) {
391
- console.error('Error clearing localStorage:', error);
392
- }
393
- }
394
- /**
395
- * Check if key exists in localStorage
396
- */
397
- hasLocal(key) {
398
- try {
399
- return localStorage.getItem(key) !== null;
400
- }
401
- catch (error) {
402
- console.error('Error checking localStorage key:', error);
403
- return false;
404
- }
405
- }
406
- /**
407
- * Get all localStorage keys
408
- */
409
- getLocalKeys() {
410
- try {
411
- return Object.keys(localStorage);
412
- }
413
- catch (error) {
414
- console.error('Error getting localStorage keys:', error);
415
- return [];
416
- }
417
- }
418
- /**
419
- * Set item in sessionStorage with JSON serialization
420
- */
421
- setSession(key, value) {
422
- try {
423
- const serialized = JSON.stringify(value);
424
- sessionStorage.setItem(key, serialized);
425
- return true;
426
- }
427
- catch (error) {
428
- console.error('Error setting sessionStorage item:', error);
429
- return false;
430
- }
431
- }
432
- /**
433
- * Get item from sessionStorage with JSON deserialization
434
- */
435
- getSession(key, defaultValue) {
436
- try {
437
- const item = sessionStorage.getItem(key);
438
- if (item === null) {
439
- return defaultValue !== undefined ? defaultValue : null;
440
- }
441
- return JSON.parse(item);
442
- }
443
- catch (error) {
444
- console.error('Error getting sessionStorage item:', error);
445
- return defaultValue !== undefined ? defaultValue : null;
446
- }
447
- }
448
- /**
449
- * Remove item from sessionStorage
450
- */
451
- removeSession(key) {
452
- try {
453
- sessionStorage.removeItem(key);
454
- }
455
- catch (error) {
456
- console.error('Error removing sessionStorage item:', error);
457
- }
458
- }
459
- /**
460
- * Clear all sessionStorage items
461
- */
462
- clearSession() {
463
- try {
464
- sessionStorage.clear();
465
- }
466
- catch (error) {
467
- console.error('Error clearing sessionStorage:', error);
468
- }
469
- }
470
- /**
471
- * Check if key exists in sessionStorage
472
- */
473
- hasSession(key) {
474
- try {
475
- return sessionStorage.getItem(key) !== null;
476
- }
477
- catch (error) {
478
- console.error('Error checking sessionStorage key:', error);
479
- return false;
480
- }
481
- }
482
- /**
483
- * Get all sessionStorage keys
484
- */
485
- getSessionKeys() {
486
- try {
487
- return Object.keys(sessionStorage);
488
- }
489
- catch (error) {
490
- console.error('Error getting sessionStorage keys:', error);
491
- return [];
492
- }
493
- }
494
- /**
495
- * Set item with expiration time
496
- * @param key - Storage key
497
- * @param value - Value to store
498
- * @param expirationMs - Expiration time in milliseconds
499
- * @param useSession - Use sessionStorage instead of localStorage
500
- */
501
- setWithExpiration(key, value, expirationMs, useSession = false) {
502
- const item = {
503
- value,
504
- expiration: Date.now() + expirationMs
505
- };
506
- return useSession
507
- ? this.setSession(key, item)
508
- : this.setLocal(key, item);
509
- }
510
- /**
511
- * Get item with expiration check
512
- * Returns null if item is expired
513
- */
514
- getWithExpiration(key, useSession = false) {
515
- const item = useSession
516
- ? this.getSession(key)
517
- : this.getLocal(key);
518
- if (!item)
519
- return null;
520
- if (Date.now() > item.expiration) {
521
- // Item expired, remove it
522
- if (useSession) {
523
- this.removeSession(key);
524
- }
525
- else {
526
- this.removeLocal(key);
527
- }
528
- return null;
529
- }
530
- return item.value;
531
- }
532
- }
533
-
534
- /**
535
- * StorageService - Angular service wrapper for StorageManager
536
- * Provides Angular dependency injection support for the framework-agnostic StorageManager
537
- *
538
- * @example
539
- * ```typescript
540
- * import { Component, inject } from '@angular/core';
541
- * import { StorageService } from 'common-libs';
542
- *
543
- * export class UserPreferencesService {
544
- * private storage = inject(StorageService);
545
- *
546
- * savePreferences(prefs: any) {
547
- * this.storage.setLocal('user-prefs', prefs);
548
- * }
549
- *
550
- * getPreferences() {
551
- * return this.storage.getLocal('user-prefs');
552
- * }
553
- * }
554
- * ```
555
- */
556
- exports.StorageService = class StorageService extends StorageManager {
557
- constructor() {
558
- super();
559
- }
560
- };
561
- exports.StorageService = __decorate([
562
- core.Injectable({
563
- providedIn: 'root'
564
- }),
565
- __metadata("design:paramtypes", [])
566
- ], exports.StorageService);
567
-
568
- /**
569
- * Log level enum
570
- */
571
- exports.LogLevel = void 0;
572
- (function (LogLevel) {
573
- LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
574
- LogLevel[LogLevel["INFO"] = 1] = "INFO";
575
- LogLevel[LogLevel["WARN"] = 2] = "WARN";
576
- LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
577
- LogLevel[LogLevel["NONE"] = 4] = "NONE";
578
- })(exports.LogLevel || (exports.LogLevel = {}));
579
- /**
580
- * Logger - Centralized logging utility
581
- * Framework-agnostic implementation using browser console APIs
582
- * Supports different log levels and can be configured globally
583
- *
584
- * @example
585
- * ```typescript
586
- * const logger = new Logger();
587
- *
588
- * // Configure
589
- * logger.configure({
590
- * level: LogLevel.DEBUG,
591
- * enableTimestamp: true,
592
- * prefix: 'MyApp'
593
- * });
594
- *
595
- * // Use
596
- * logger.info('User logged in', { userId: '123' });
597
- * logger.error('Failed to load data', error);
598
- * ```
599
- */
600
- class Logger {
601
- config = {
602
- level: exports.LogLevel.INFO,
603
- enableTimestamp: true,
604
- enableStackTrace: false,
605
- prefix: ''
606
- };
607
- /**
608
- * Configure the logger
609
- */
610
- configure(config) {
611
- this.config = { ...this.config, ...config };
612
- }
613
- /**
614
- * Set log level
615
- */
616
- setLevel(level) {
617
- this.config.level = level;
618
- }
619
- /**
620
- * Get current log level
621
- */
622
- getLevel() {
623
- return this.config.level;
624
- }
625
- /**
626
- * Format log message with timestamp and prefix
627
- */
628
- formatMessage(message, level) {
629
- const parts = [];
630
- if (this.config.enableTimestamp) {
631
- parts.push(`[${new Date().toISOString()}]`);
632
- }
633
- if (this.config.prefix) {
634
- parts.push(`[${this.config.prefix}]`);
635
- }
636
- parts.push(`[${level}]`);
637
- parts.push(message);
638
- return parts.join(' ');
639
- }
640
- /**
641
- * Check if log level should be logged
642
- */
643
- shouldLog(level) {
644
- return level >= this.config.level;
645
- }
646
- /**
647
- * Log debug message
648
- */
649
- debug(message, ...args) {
650
- if (this.shouldLog(exports.LogLevel.DEBUG)) {
651
- console.debug(this.formatMessage(message, 'DEBUG'), ...args);
652
- }
653
- }
654
- /**
655
- * Log info message
656
- */
657
- info(message, ...args) {
658
- if (this.shouldLog(exports.LogLevel.INFO)) {
659
- console.info(this.formatMessage(message, 'INFO'), ...args);
660
- }
661
- }
662
- /**
663
- * Log warning message
664
- */
665
- warn(message, ...args) {
666
- if (this.shouldLog(exports.LogLevel.WARN)) {
667
- console.warn(this.formatMessage(message, 'WARN'), ...args);
668
- }
669
- }
670
- /**
671
- * Log error message
672
- */
673
- error(message, error, ...args) {
674
- if (this.shouldLog(exports.LogLevel.ERROR)) {
675
- console.error(this.formatMessage(message, 'ERROR'), ...args);
676
- if (error) {
677
- console.error(error);
678
- if (this.config.enableStackTrace && error?.stack) {
679
- console.error('Stack trace:', error.stack);
680
- }
681
- }
682
- }
683
- }
684
- /**
685
- * Log a group of messages
686
- */
687
- group(label, callback) {
688
- if (this.shouldLog(exports.LogLevel.INFO)) {
689
- console.group(this.formatMessage(label, 'GROUP'));
690
- callback();
691
- console.groupEnd();
692
- }
693
- }
694
- /**
695
- * Log a collapsed group of messages
696
- */
697
- groupCollapsed(label, callback) {
698
- if (this.shouldLog(exports.LogLevel.INFO)) {
699
- console.groupCollapsed(this.formatMessage(label, 'GROUP'));
700
- callback();
701
- console.groupEnd();
702
- }
703
- }
704
- /**
705
- * Log a table (useful for arrays of objects)
706
- */
707
- table(data, columns) {
708
- if (this.shouldLog(exports.LogLevel.INFO)) {
709
- console.table(data, columns);
710
- }
711
- }
712
- /**
713
- * Log execution time of a function
714
- */
715
- async time(label, fn) {
716
- const start = performance.now();
717
- try {
718
- const result = await fn();
719
- const end = performance.now();
720
- const duration = (end - start).toFixed(2);
721
- this.info(`${label} completed in ${duration}ms`);
722
- return result;
723
- }
724
- catch (error) {
725
- const end = performance.now();
726
- const duration = (end - start).toFixed(2);
727
- this.error(`${label} failed after ${duration}ms`, error);
728
- throw error;
729
- }
730
- }
731
- }
732
-
733
- /**
734
- * LoggerService - Angular service wrapper for Logger
735
- * Provides Angular dependency injection support for the framework-agnostic Logger
736
- *
737
- * @example
738
- * ```typescript
739
- * import { Component, inject } from '@angular/core';
740
- * import { LoggerService, LogLevel } from 'common-libs';
741
- *
742
- * export class MyService {
743
- * private logger = inject(LoggerService);
744
- *
745
- * constructor() {
746
- * this.logger.configure({
747
- * level: LogLevel.DEBUG,
748
- * prefix: 'MyApp'
749
- * });
750
- * }
751
- *
752
- * doSomething() {
753
- * this.logger.info('Doing something');
754
- * }
755
- * }
756
- * ```
757
- */
758
- exports.LoggerService = class LoggerService extends Logger {
759
- constructor() {
760
- super();
761
- }
762
- };
763
- exports.LoggerService = __decorate([
764
- core.Injectable({
765
- providedIn: 'root'
766
- }),
767
- __metadata("design:paramtypes", [])
768
- ], exports.LoggerService);
4
+ var http = require('@angular/common/http');
5
+ var rxjs = require('rxjs');
769
6
 
770
- /**
771
- * PermissionService - Manages user permissions and roles
772
- */
773
- exports.PermissionService = class PermissionService {
774
- tokenService = core.inject(exports.TokenService);
775
- /**
776
- * Check if user has a specific permission
777
- */
778
- hasPermission(permission) {
779
- const user = this.tokenService.getUserFromToken();
780
- const permissions = user?.permissions || [];
781
- return permissions.includes(permission);
782
- }
783
- /**
784
- * Check if user has any of the specified permissions
785
- */
786
- hasAnyPermission(permissions) {
787
- return permissions.some(permission => this.hasPermission(permission));
788
- }
789
- /**
790
- * Check if user has all of the specified permissions
791
- */
792
- hasAllPermissions(permissions) {
793
- return permissions.every(permission => this.hasPermission(permission));
794
- }
795
- /**
796
- * Check if user has a specific role
797
- */
798
- hasRole(role) {
799
- const user = this.tokenService.getUserFromToken();
800
- const roles = user?.roles || [];
801
- return roles.includes(role);
802
- }
803
- /**
804
- * Check if user has any of the specified roles
805
- */
806
- hasAnyRole(roles) {
807
- return roles.some(role => this.hasRole(role));
808
- }
809
- /**
810
- * Check if user has all of the specified roles
811
- */
812
- hasAllRoles(roles) {
813
- return roles.every(role => this.hasRole(role));
814
- }
815
- /**
816
- * Get all user permissions
817
- */
818
- getPermissions() {
819
- const user = this.tokenService.getUserFromToken();
820
- return user?.permissions || [];
821
- }
822
- /**
823
- * Get all user roles
824
- */
825
- getRoles() {
826
- const user = this.tokenService.getUserFromToken();
827
- return user?.roles || [];
828
- }
829
- /**
830
- * Get user ID from token
831
- */
832
- getUserId() {
833
- const user = this.tokenService.getUserFromToken();
834
- return user?.sub || user?.id || user?.userId || null;
835
- }
836
- /**
837
- * Get username from token
838
- */
839
- getUsername() {
840
- const user = this.tokenService.getUserFromToken();
841
- return user?.username || user?.name || user?.email || null;
842
- }
843
- /**
844
- * Get user email from token
845
- */
846
- getUserEmail() {
847
- const user = this.tokenService.getUserFromToken();
848
- return user?.email || null;
849
- }
7
+ /******************************************************************************
8
+ Copyright (c) Microsoft Corporation.
9
+
10
+ Permission to use, copy, modify, and/or distribute this software for any
11
+ purpose with or without fee is hereby granted.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19
+ PERFORMANCE OF THIS SOFTWARE.
20
+ ***************************************************************************** */
21
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
22
+
23
+
24
+ function __decorate(decorators, target, key, desc) {
25
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
26
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
27
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
28
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
29
+ }
30
+
31
+ function __metadata(metadataKey, metadataValue) {
32
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
33
+ }
34
+
35
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
36
+ var e = new Error(message);
37
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
850
38
  };
851
- exports.PermissionService = __decorate([
852
- core.Injectable({
853
- providedIn: 'root'
854
- })
855
- ], exports.PermissionService);
856
39
 
857
40
  function mitt(n){return {all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e]);},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]));},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e);}),(i=n.get("*"))&&i.slice().map(function(n){n(t,e);});}}}
858
41
 
@@ -1492,427 +675,11 @@ exports.AuthService = __decorate([
1492
675
  exports.EventBusService])
1493
676
  ], exports.AuthService);
1494
677
 
1495
- /**
1496
- * Factory function to create an auth guard with configuration
1497
- *
1498
- * @example
1499
- * ```typescript
1500
- * // In routes
1501
- * {
1502
- * path: 'dashboard',
1503
- * component: DashboardComponent,
1504
- * canActivate: [createAuthGuard({ redirectUrl: '/login' })]
1505
- * }
1506
- * ```
1507
- */
1508
- function createAuthGuard(config = {}) {
1509
- return (route, state) => {
1510
- const tokenService = core.inject(exports.TokenService);
1511
- const router$1 = core.inject(router.Router);
1512
- const redirectUrl = config.redirectUrl || '/login';
1513
- const checkExpiration = config.checkExpiration !== false;
1514
- const hasToken = tokenService.hasToken();
1515
- const isExpired = checkExpiration ? tokenService.isTokenExpired() : false;
1516
- if (hasToken && !isExpired) {
1517
- return true;
1518
- }
1519
- // Store the attempted URL for redirecting after login
1520
- const returnUrl = state.url;
1521
- router$1.navigate([redirectUrl], {
1522
- queryParams: { returnUrl },
1523
- queryParamsHandling: 'merge'
1524
- });
1525
- return false;
1526
- };
1527
- }
1528
- /**
1529
- * Default auth guard - redirects to '/login' if not authenticated
1530
- */
1531
- const authGuard = createAuthGuard();
1532
- /**
1533
- * Permission-based guard factory
1534
- * Checks if user has required permissions from token
1535
- *
1536
- * @example
1537
- * ```typescript
1538
- * {
1539
- * path: 'admin',
1540
- * component: AdminComponent,
1541
- * canActivate: [createPermissionGuard(['admin', 'editor'])]
1542
- * }
1543
- * ```
1544
- */
1545
- function createPermissionGuard(requiredPermissions, config = {}) {
1546
- return (route, state) => {
1547
- const tokenService = core.inject(exports.TokenService);
1548
- const router$1 = core.inject(router.Router);
1549
- const redirectUrl = config.redirectUrl || '/unauthorized';
1550
- // First check authentication
1551
- if (!tokenService.isAuthenticated()) {
1552
- router$1.navigate(['/login'], {
1553
- queryParams: { returnUrl: state.url }
1554
- });
1555
- return false;
1556
- }
1557
- // Check permissions
1558
- const user = tokenService.getUserFromToken();
1559
- const userPermissions = user?.permissions || user?.roles || [];
1560
- const hasPermission = requiredPermissions.some(permission => userPermissions.includes(permission));
1561
- if (!hasPermission) {
1562
- router$1.navigate([redirectUrl]);
1563
- return false;
1564
- }
1565
- return true;
1566
- };
1567
- }
1568
- /**
1569
- * Role-based guard factory
1570
- * Checks if user has required role from token
1571
- *
1572
- * @example
1573
- * ```typescript
1574
- * {
1575
- * path: 'admin',
1576
- * component: AdminComponent,
1577
- * canActivate: [createRoleGuard(['admin'])]
1578
- * }
1579
- * ```
1580
- */
1581
- function createRoleGuard(requiredRoles, config = {}) {
1582
- return createPermissionGuard(requiredRoles, config);
1583
- }
1584
-
1585
- const defaultConfig$1 = {
1586
- headerName: 'Authorization',
1587
- tokenPrefix: 'Bearer',
1588
- excludedUrls: []
1589
- };
1590
- let interceptorConfig = { ...defaultConfig$1 };
1591
- /**
1592
- * Configure the auth interceptor
1593
- */
1594
- function configureAuthInterceptor(config) {
1595
- interceptorConfig = { ...defaultConfig$1, ...config };
1596
- }
1597
- /**
1598
- * Auth Interceptor - Automatically adds authentication token to HTTP requests
1599
- *
1600
- * @example
1601
- * ```typescript
1602
- * // In app.config.ts
1603
- * export const appConfig: ApplicationConfig = {
1604
- * providers: [
1605
- * provideHttpClient(
1606
- * withInterceptors([authInterceptor])
1607
- * )
1608
- * ]
1609
- * };
1610
- * ```
1611
- */
1612
- const authInterceptor = (req, next) => {
1613
- const tokenService = core.inject(exports.TokenService);
1614
- const config = interceptorConfig;
1615
- // Check if URL should be excluded
1616
- const isExcluded = config.excludedUrls?.some(url => req.url.includes(url));
1617
- if (isExcluded) {
1618
- return next(req);
1619
- }
1620
- // Get token and add to request if available
1621
- const token = tokenService.getToken();
1622
- if (token) {
1623
- const authReq = req.clone({
1624
- setHeaders: {
1625
- [config.headerName]: `${config.tokenPrefix} ${token}`
1626
- }
1627
- });
1628
- return next(authReq);
1629
- }
1630
- return next(req);
1631
- };
1632
-
1633
- const defaultConfig = {
1634
- enableLogging: true,
1635
- retryAttempts: 0,
1636
- retryDelay: 1000,
1637
- retryStatusCodes: [408, 429, 500, 502, 503, 504],
1638
- excludedUrls: []
1639
- };
1640
- let errorConfig = { ...defaultConfig };
1641
- /**
1642
- * Configure the error handling interceptor
1643
- */
1644
- function configureErrorHandling(config) {
1645
- errorConfig = { ...defaultConfig, ...config };
1646
- }
1647
- /**
1648
- * Error handling interceptor - Handles HTTP errors and retries
1649
- *
1650
- * @example
1651
- * ```typescript
1652
- * // In app.config.ts
1653
- * export const appConfig: ApplicationConfig = {
1654
- * providers: [
1655
- * provideHttpClient(
1656
- * withInterceptors([errorHandlingInterceptor])
1657
- * )
1658
- * ]
1659
- * };
1660
- *
1661
- * // Configure retry behavior
1662
- * configureErrorHandling({
1663
- * retryAttempts: 3,
1664
- * retryDelay: 2000,
1665
- * retryStatusCodes: [500, 502, 503]
1666
- * });
1667
- * ```
1668
- */
1669
- const errorHandlingInterceptor = (req, next) => {
1670
- const logger = core.inject(exports.LoggerService);
1671
- const config = errorConfig;
1672
- // Check if URL should be excluded
1673
- const isExcluded = config.excludedUrls?.some(url => req.url.includes(url));
1674
- if (isExcluded) {
1675
- return next(req);
1676
- }
1677
- return next(req).pipe(
1678
- // Retry logic with exponential backoff
1679
- operators.retry({
1680
- count: config.retryAttempts,
1681
- delay: (error, retryCount) => {
1682
- // Only retry for specific status codes
1683
- if (!config.retryStatusCodes?.includes(error.status)) {
1684
- return rxjs.throwError(() => error);
1685
- }
1686
- const delay = config.retryDelay * Math.pow(2, retryCount - 1);
1687
- if (config.enableLogging) {
1688
- logger.warn(`Retrying request (attempt ${retryCount}) after ${delay}ms`, { url: req.url, status: error.status });
1689
- }
1690
- return rxjs.timer(delay);
1691
- }
1692
- }),
1693
- // Error handling
1694
- operators.catchError((error) => {
1695
- if (config.enableLogging) {
1696
- logger.error('HTTP request failed', error, {
1697
- url: req.url,
1698
- status: error.status,
1699
- message: error.message
1700
- });
1701
- }
1702
- return rxjs.throwError(() => error);
1703
- }));
1704
- };
1705
- /**
1706
- * HTTP Error class with additional context
1707
- */
1708
- class HttpError extends Error {
1709
- status;
1710
- statusText;
1711
- url;
1712
- originalError;
1713
- constructor(status, statusText, url, originalError) {
1714
- super(`HTTP ${status} ${statusText}: ${url}`);
1715
- this.status = status;
1716
- this.statusText = statusText;
1717
- this.url = url;
1718
- this.originalError = originalError;
1719
- this.name = 'HttpError';
1720
- }
1721
- }
1722
- /**
1723
- * Parse HTTP error and return user-friendly message
1724
- */
1725
- function parseHttpError(error) {
1726
- if (error.error instanceof ErrorEvent) {
1727
- // Client-side error
1728
- return `Network error: ${error.error.message}`;
1729
- }
1730
- else {
1731
- // Server-side error
1732
- const errorMessage = error.error?.message || error.message || 'Unknown error';
1733
- return `Server error (${error.status}): ${errorMessage}`;
1734
- }
1735
- }
1736
- /**
1737
- * Check if error is a network error
1738
- */
1739
- function isNetworkError(error) {
1740
- return error.error instanceof ErrorEvent || error.status === 0;
1741
- }
1742
- /**
1743
- * Check if error is a server error (5xx)
1744
- */
1745
- function isServerError(error) {
1746
- return error.status >= 500 && error.status < 600;
1747
- }
1748
- /**
1749
- * Check if error is a client error (4xx)
1750
- */
1751
- function isClientError(error) {
1752
- return error.status >= 400 && error.status < 500;
1753
- }
1754
-
1755
- const defaultCacheConfig = {
1756
- enabled: true,
1757
- maxAge: 60000, // 1 minute
1758
- excludedUrls: [],
1759
- cacheableUrls: [],
1760
- cacheMethods: ['GET']
1761
- };
1762
- let cacheConfig = { ...defaultCacheConfig };
1763
- const cache = new Map();
1764
- const MAX_CACHE_SIZE = 100; // Maximum number of cached entries
1765
- /**
1766
- * Configure the caching interceptor
1767
- */
1768
- function configureCaching(config) {
1769
- cacheConfig = { ...defaultCacheConfig, ...config };
1770
- }
1771
- /**
1772
- * Clean up expired cache entries
1773
- */
1774
- function cleanupCache() {
1775
- const now = Date.now();
1776
- const keysToDelete = [];
1777
- cache.forEach((entry, key) => {
1778
- const age = now - entry.timestamp;
1779
- if (age >= cacheConfig.maxAge) {
1780
- keysToDelete.push(key);
1781
- }
1782
- });
1783
- keysToDelete.forEach(key => cache.delete(key));
1784
- }
1785
- /**
1786
- * Evict oldest cache entry if cache is full
1787
- */
1788
- function evictOldestIfFull() {
1789
- if (cache.size >= MAX_CACHE_SIZE) {
1790
- let oldestKey = null;
1791
- let oldestTimestamp = Infinity;
1792
- cache.forEach((entry, key) => {
1793
- if (entry.timestamp < oldestTimestamp) {
1794
- oldestTimestamp = entry.timestamp;
1795
- oldestKey = key;
1796
- }
1797
- });
1798
- if (oldestKey) {
1799
- cache.delete(oldestKey);
1800
- }
1801
- }
1802
- }
1803
- /**
1804
- * Clear all cached entries
1805
- */
1806
- function clearCache() {
1807
- cache.clear();
1808
- }
1809
- /**
1810
- * Clear cache entry for specific URL
1811
- */
1812
- function clearCacheEntry(url) {
1813
- cache.delete(url);
1814
- }
1815
- /**
1816
- * Caching interceptor - Caches HTTP GET requests
1817
- *
1818
- * @example
1819
- * ```typescript
1820
- * // In app.config.ts
1821
- * export const appConfig: ApplicationConfig = {
1822
- * providers: [
1823
- * provideHttpClient(
1824
- * withInterceptors([cachingInterceptor])
1825
- * )
1826
- * ]
1827
- * };
1828
- *
1829
- * // Configure caching
1830
- * configureCaching({
1831
- * enabled: true,
1832
- * maxAge: 300000, // 5 minutes
1833
- * cacheableUrls: ['/api/users', '/api/products']
1834
- * });
1835
- * ```
1836
- */
1837
- const cachingInterceptor = (req, next) => {
1838
- const logger = core.inject(exports.LoggerService);
1839
- const config = cacheConfig;
1840
- // Only cache if enabled
1841
- if (!config.enabled) {
1842
- return next(req);
1843
- }
1844
- // Only cache specific methods (default: GET)
1845
- if (!config.cacheMethods?.includes(req.method)) {
1846
- return next(req);
1847
- }
1848
- // Check if URL should be excluded
1849
- const isExcluded = config.excludedUrls?.some(url => req.url.includes(url));
1850
- if (isExcluded) {
1851
- return next(req);
1852
- }
1853
- // Check if URL is explicitly cacheable (if list is provided)
1854
- if (config.cacheableUrls && config.cacheableUrls.length > 0) {
1855
- const isCacheable = config.cacheableUrls.some(url => req.url.includes(url));
1856
- if (!isCacheable) {
1857
- return next(req);
1858
- }
1859
- }
1860
- const cacheKey = req.urlWithParams;
1861
- // Check cache
1862
- const cached = cache.get(cacheKey);
1863
- if (cached) {
1864
- const age = Date.now() - cached.timestamp;
1865
- if (age < config.maxAge) {
1866
- logger.debug(`Cache hit for ${cacheKey}`, { age });
1867
- return new rxjs.Observable(observer => {
1868
- observer.next(cached.response.clone());
1869
- observer.complete();
1870
- });
1871
- }
1872
- else {
1873
- // Cache expired
1874
- cache.delete(cacheKey);
1875
- }
1876
- }
1877
- // Clean up expired entries periodically
1878
- if (Math.random() < 0.1) { // 10% chance on each request
1879
- cleanupCache();
1880
- }
1881
- // Make request and cache response
1882
- return next(req).pipe(operators.tap(event => {
1883
- if (event instanceof http.HttpResponse) {
1884
- evictOldestIfFull();
1885
- cache.set(cacheKey, {
1886
- response: event.clone(),
1887
- timestamp: Date.now()
1888
- });
1889
- logger.debug(`Cached response for ${cacheKey}`);
1890
- }
1891
- }));
1892
- };
1893
-
1894
678
  exports.AUTH0_CONFIG = AUTH0_CONFIG;
1895
- exports.HttpError = HttpError;
1896
679
  exports.STORAGE_CONFIG = STORAGE_CONFIG;
1897
680
  exports.STORAGE_KEYS = STORAGE_KEYS;
1898
- exports.authGuard = authGuard;
1899
- exports.authInterceptor = authInterceptor;
1900
- exports.cachingInterceptor = cachingInterceptor;
1901
- exports.clearCache = clearCache;
1902
- exports.clearCacheEntry = clearCacheEntry;
1903
681
  exports.configureAuth0 = configureAuth0;
1904
- exports.configureAuthInterceptor = configureAuthInterceptor;
1905
- exports.configureCaching = configureCaching;
1906
- exports.configureErrorHandling = configureErrorHandling;
1907
- exports.createAuthGuard = createAuthGuard;
1908
- exports.createPermissionGuard = createPermissionGuard;
1909
- exports.createRoleGuard = createRoleGuard;
1910
- exports.errorHandlingInterceptor = errorHandlingInterceptor;
1911
682
  exports.getStorageItem = getStorageItem;
1912
- exports.isClientError = isClientError;
1913
- exports.isNetworkError = isNetworkError;
1914
- exports.isServerError = isServerError;
1915
- exports.parseHttpError = parseHttpError;
1916
683
  exports.removeStorageItem = removeStorageItem;
1917
684
  exports.setStorageItem = setStorageItem;
1918
685
  //# sourceMappingURL=index.cjs.map