@opensourcekd/ng-common-libs 2.0.6 → 2.0.7
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/README.md +6 -0
- package/dist/index.cjs +235 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +206 -2
- package/dist/index.mjs +235 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
|
|
24
24
|
- **AuthService**: Complete Auth0 authentication with token management (Pure TypeScript - no Angular dependency)
|
|
25
25
|
- **EventBus**: Framework-agnostic event bus using RxJS
|
|
26
|
+
- **Logger**: OpenTelemetry-compliant structured logging with observable log streams
|
|
26
27
|
- **Works with any framework**: Angular, React, Vue, Svelte, vanilla JS
|
|
27
28
|
- **Module Federation Support**: Singleton pattern works across shell + MFEs
|
|
28
29
|
- **Zero Framework Lock-in**: Core services are pure TypeScript classes
|
|
@@ -94,6 +95,7 @@ import {
|
|
|
94
95
|
// Services
|
|
95
96
|
AuthService,
|
|
96
97
|
EventBus,
|
|
98
|
+
Logger,
|
|
97
99
|
|
|
98
100
|
// Helper Functions
|
|
99
101
|
configureAuth0,
|
|
@@ -121,6 +123,10 @@ import {
|
|
|
121
123
|
AppState,
|
|
122
124
|
AuthorizationParams,
|
|
123
125
|
CallbackResult,
|
|
126
|
+
LogRecord,
|
|
127
|
+
LogAttributes,
|
|
128
|
+
LogSeverity,
|
|
129
|
+
LoggerOptions,
|
|
124
130
|
} from '@opensourcekd/ng-common-libs';
|
|
125
131
|
```
|
|
126
132
|
|
package/dist/index.cjs
CHANGED
|
@@ -443,6 +443,8 @@ class AuthService {
|
|
|
443
443
|
}
|
|
444
444
|
const token = await this.auth0Client.getTokenSilently();
|
|
445
445
|
this.setToken(token);
|
|
446
|
+
// Clean up OAuth callback parameters from URL
|
|
447
|
+
this.cleanupCallbackUrl();
|
|
446
448
|
console.log("[AuthService] Authentication successful");
|
|
447
449
|
this.emitAuthEvent('login_success', { user, appState: result.appState });
|
|
448
450
|
return { success: true, appState: result.appState };
|
|
@@ -665,6 +667,34 @@ class AuthService {
|
|
|
665
667
|
this.eventBus.emit(event.type, event);
|
|
666
668
|
console.log('[AuthService] Auth event emitted:', event.type);
|
|
667
669
|
}
|
|
670
|
+
/**
|
|
671
|
+
* Clean up OAuth callback parameters from URL after successful authentication
|
|
672
|
+
* Removes 'code' and 'state' parameters while preserving other query parameters
|
|
673
|
+
*/
|
|
674
|
+
cleanupCallbackUrl() {
|
|
675
|
+
try {
|
|
676
|
+
const url = new URL(window.location.href);
|
|
677
|
+
const params = new URLSearchParams(url.search);
|
|
678
|
+
// Check if OAuth params exist
|
|
679
|
+
const hasCode = params.has('code');
|
|
680
|
+
const hasState = params.has('state');
|
|
681
|
+
if (hasCode || hasState) {
|
|
682
|
+
// Remove OAuth callback parameters
|
|
683
|
+
params.delete('code');
|
|
684
|
+
params.delete('state');
|
|
685
|
+
// Construct new URL without OAuth params
|
|
686
|
+
const newSearch = params.toString();
|
|
687
|
+
const newUrl = `${url.pathname}${newSearch ? '?' + newSearch : ''}${url.hash}`;
|
|
688
|
+
// Replace URL without adding to browser history
|
|
689
|
+
window.history.replaceState({}, '', newUrl);
|
|
690
|
+
console.log('[AuthService] OAuth callback parameters cleaned from URL');
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
catch (error) {
|
|
694
|
+
console.warn('[AuthService] Failed to clean up callback URL:', error);
|
|
695
|
+
// Don't throw - URL cleanup is not critical for auth functionality
|
|
696
|
+
}
|
|
697
|
+
}
|
|
668
698
|
}
|
|
669
699
|
/**
|
|
670
700
|
* Create AuthService instance using AUTH0_CONFIG
|
|
@@ -704,10 +734,215 @@ function createAuthService(eventBus) {
|
|
|
704
734
|
return new AuthService(auth0Config, eventBus, STORAGE_CONFIG, STORAGE_KEYS);
|
|
705
735
|
}
|
|
706
736
|
|
|
737
|
+
/**
|
|
738
|
+
* OpenTelemetry severity levels
|
|
739
|
+
* Based on OpenTelemetry log data model
|
|
740
|
+
* @see https://opentelemetry.io/docs/specs/otel/logs/data-model/
|
|
741
|
+
*/
|
|
742
|
+
exports.LogSeverity = void 0;
|
|
743
|
+
(function (LogSeverity) {
|
|
744
|
+
LogSeverity[LogSeverity["TRACE"] = 1] = "TRACE";
|
|
745
|
+
LogSeverity[LogSeverity["DEBUG"] = 5] = "DEBUG";
|
|
746
|
+
LogSeverity[LogSeverity["INFO"] = 9] = "INFO";
|
|
747
|
+
LogSeverity[LogSeverity["WARN"] = 13] = "WARN";
|
|
748
|
+
LogSeverity[LogSeverity["ERROR"] = 17] = "ERROR";
|
|
749
|
+
LogSeverity[LogSeverity["FATAL"] = 21] = "FATAL";
|
|
750
|
+
})(exports.LogSeverity || (exports.LogSeverity = {}));
|
|
751
|
+
/**
|
|
752
|
+
* Logger - OpenTelemetry-compliant structured logging
|
|
753
|
+
* Framework-agnostic implementation using RxJS for observability
|
|
754
|
+
*
|
|
755
|
+
* Conforms to OpenTelemetry log data model:
|
|
756
|
+
* - Structured logging with severity levels
|
|
757
|
+
* - Timestamp in milliseconds
|
|
758
|
+
* - Support for attributes and resource context
|
|
759
|
+
* - Observable log stream for integration with OTel exporters
|
|
760
|
+
*
|
|
761
|
+
* @example
|
|
762
|
+
* ```typescript
|
|
763
|
+
* // Create a logger instance
|
|
764
|
+
* const logger = new Logger({
|
|
765
|
+
* name: 'MyService',
|
|
766
|
+
* minSeverity: LogSeverity.INFO,
|
|
767
|
+
* resource: {
|
|
768
|
+
* 'service.name': 'my-app',
|
|
769
|
+
* 'deployment.environment': 'production'
|
|
770
|
+
* }
|
|
771
|
+
* });
|
|
772
|
+
*
|
|
773
|
+
* // Simple logging
|
|
774
|
+
* logger.info('User logged in');
|
|
775
|
+
* logger.error('Failed to fetch data');
|
|
776
|
+
*
|
|
777
|
+
* // Structured logging with attributes
|
|
778
|
+
* logger.info('User action', {
|
|
779
|
+
* userId: '123',
|
|
780
|
+
* action: 'purchase',
|
|
781
|
+
* amount: 99.99
|
|
782
|
+
* });
|
|
783
|
+
*
|
|
784
|
+
* // Subscribe to log stream (e.g., for sending to OTel collector)
|
|
785
|
+
* logger.getLogStream().subscribe(logRecord => {
|
|
786
|
+
* // Send to OTel exporter, custom backend, etc.
|
|
787
|
+
* console.log(JSON.stringify(logRecord));
|
|
788
|
+
* });
|
|
789
|
+
*
|
|
790
|
+
* // Log with trace correlation
|
|
791
|
+
* logger.info('Processing request',
|
|
792
|
+
* { requestId: 'abc-123' },
|
|
793
|
+
* { traceId: '1234...', spanId: '5678...' }
|
|
794
|
+
* );
|
|
795
|
+
* ```
|
|
796
|
+
*/
|
|
797
|
+
class Logger {
|
|
798
|
+
logSubject = new rxjs.Subject();
|
|
799
|
+
name;
|
|
800
|
+
minSeverity;
|
|
801
|
+
resource;
|
|
802
|
+
consoleOutput;
|
|
803
|
+
/**
|
|
804
|
+
* Create a new Logger instance
|
|
805
|
+
* @param options - Optional configuration for the logger
|
|
806
|
+
*/
|
|
807
|
+
constructor(options) {
|
|
808
|
+
this.name = options?.name;
|
|
809
|
+
this.minSeverity = options?.minSeverity ?? exports.LogSeverity.TRACE;
|
|
810
|
+
this.resource = options?.resource;
|
|
811
|
+
this.consoleOutput = options?.consoleOutput ?? true;
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Get the logger name
|
|
815
|
+
* @returns The logger name if provided during initialization
|
|
816
|
+
*/
|
|
817
|
+
getName() {
|
|
818
|
+
return this.name;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Get the observable log stream
|
|
822
|
+
* Subscribe to this to receive all log records emitted by this logger
|
|
823
|
+
* @returns Observable that emits LogRecord objects
|
|
824
|
+
*/
|
|
825
|
+
getLogStream() {
|
|
826
|
+
return this.logSubject.asObservable();
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Emit a log record
|
|
830
|
+
* @param severity - Severity level
|
|
831
|
+
* @param severityText - Severity level text
|
|
832
|
+
* @param body - Log message
|
|
833
|
+
* @param attributes - Optional structured attributes
|
|
834
|
+
* @param context - Optional trace context (traceId, spanId)
|
|
835
|
+
*/
|
|
836
|
+
log(severity, severityText, body, attributes, context) {
|
|
837
|
+
// Check if we should log based on minimum severity
|
|
838
|
+
if (severity < this.minSeverity) {
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
const logRecord = {
|
|
842
|
+
timestamp: Date.now(),
|
|
843
|
+
severityNumber: severity,
|
|
844
|
+
severityText,
|
|
845
|
+
body,
|
|
846
|
+
attributes,
|
|
847
|
+
traceId: context?.traceId,
|
|
848
|
+
spanId: context?.spanId,
|
|
849
|
+
resource: this.resource
|
|
850
|
+
};
|
|
851
|
+
// Emit to observable stream
|
|
852
|
+
this.logSubject.next(logRecord);
|
|
853
|
+
// Console output if enabled
|
|
854
|
+
if (this.consoleOutput) {
|
|
855
|
+
this.outputToConsole(logRecord);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Output log to console
|
|
860
|
+
* @param logRecord - The log record to output
|
|
861
|
+
*/
|
|
862
|
+
outputToConsole(logRecord) {
|
|
863
|
+
const prefix = this.name ? `[${this.name}]` : '';
|
|
864
|
+
const message = `${prefix} ${logRecord.body}`;
|
|
865
|
+
const meta = logRecord.attributes;
|
|
866
|
+
switch (logRecord.severityNumber) {
|
|
867
|
+
case exports.LogSeverity.TRACE:
|
|
868
|
+
case exports.LogSeverity.DEBUG:
|
|
869
|
+
console.debug(message, meta);
|
|
870
|
+
break;
|
|
871
|
+
case exports.LogSeverity.INFO:
|
|
872
|
+
console.info(message, meta);
|
|
873
|
+
break;
|
|
874
|
+
case exports.LogSeverity.WARN:
|
|
875
|
+
console.warn(message, meta);
|
|
876
|
+
break;
|
|
877
|
+
case exports.LogSeverity.ERROR:
|
|
878
|
+
case exports.LogSeverity.FATAL:
|
|
879
|
+
console.error(message, meta);
|
|
880
|
+
break;
|
|
881
|
+
default:
|
|
882
|
+
console.log(message, meta);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Log a TRACE level message
|
|
887
|
+
* @param body - Log message
|
|
888
|
+
* @param attributes - Optional structured attributes
|
|
889
|
+
* @param context - Optional trace context
|
|
890
|
+
*/
|
|
891
|
+
trace(body, attributes, context) {
|
|
892
|
+
this.log(exports.LogSeverity.TRACE, 'TRACE', body, attributes, context);
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* Log a DEBUG level message
|
|
896
|
+
* @param body - Log message
|
|
897
|
+
* @param attributes - Optional structured attributes
|
|
898
|
+
* @param context - Optional trace context
|
|
899
|
+
*/
|
|
900
|
+
debug(body, attributes, context) {
|
|
901
|
+
this.log(exports.LogSeverity.DEBUG, 'DEBUG', body, attributes, context);
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Log an INFO level message
|
|
905
|
+
* @param body - Log message
|
|
906
|
+
* @param attributes - Optional structured attributes
|
|
907
|
+
* @param context - Optional trace context
|
|
908
|
+
*/
|
|
909
|
+
info(body, attributes, context) {
|
|
910
|
+
this.log(exports.LogSeverity.INFO, 'INFO', body, attributes, context);
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Log a WARN level message
|
|
914
|
+
* @param body - Log message
|
|
915
|
+
* @param attributes - Optional structured attributes
|
|
916
|
+
* @param context - Optional trace context
|
|
917
|
+
*/
|
|
918
|
+
warn(body, attributes, context) {
|
|
919
|
+
this.log(exports.LogSeverity.WARN, 'WARN', body, attributes, context);
|
|
920
|
+
}
|
|
921
|
+
/**
|
|
922
|
+
* Log an ERROR level message
|
|
923
|
+
* @param body - Log message
|
|
924
|
+
* @param attributes - Optional structured attributes
|
|
925
|
+
* @param context - Optional trace context
|
|
926
|
+
*/
|
|
927
|
+
error(body, attributes, context) {
|
|
928
|
+
this.log(exports.LogSeverity.ERROR, 'ERROR', body, attributes, context);
|
|
929
|
+
}
|
|
930
|
+
/**
|
|
931
|
+
* Log a FATAL level message
|
|
932
|
+
* @param body - Log message
|
|
933
|
+
* @param attributes - Optional structured attributes
|
|
934
|
+
* @param context - Optional trace context
|
|
935
|
+
*/
|
|
936
|
+
fatal(body, attributes, context) {
|
|
937
|
+
this.log(exports.LogSeverity.FATAL, 'FATAL', body, attributes, context);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
|
|
707
941
|
exports.APP_CONFIG = APP_CONFIG;
|
|
708
942
|
exports.AUTH0_CONFIG = AUTH0_CONFIG;
|
|
709
943
|
exports.AuthService = AuthService;
|
|
710
944
|
exports.EventBus = EventBus;
|
|
945
|
+
exports.Logger = Logger;
|
|
711
946
|
exports.STORAGE_CONFIG = STORAGE_CONFIG;
|
|
712
947
|
exports.STORAGE_KEYS = STORAGE_KEYS;
|
|
713
948
|
exports.configureAuth0 = configureAuth0;
|