@opensourcekd/ng-common-libs 1.2.3 → 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.
- package/README.md +77 -282
- package/dist/angular/index.cjs +512 -1100
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.d.ts +240 -582
- package/dist/angular/index.mjs +508 -1086
- package/dist/angular/index.mjs.map +1 -1
- package/dist/core/index.cjs +0 -528
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +2 -277
- package/dist/core/index.mjs +1 -526
- package/dist/core/index.mjs.map +1 -1
- package/dist/index.cjs +554 -1087
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +250 -539
- package/dist/index.mjs +552 -1072
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -8
package/README.md
CHANGED
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
# ng-common-libs
|
|
2
2
|
|
|
3
|
-
Angular 18
|
|
3
|
+
Angular 18 library with Auth0 authentication service and MicroFrontend event bus.
|
|
4
4
|
|
|
5
5
|
## 🎯 Dual-Layer Architecture
|
|
6
6
|
|
|
7
7
|
This library features a **dual-layer architecture**:
|
|
8
8
|
|
|
9
|
-
- **Core Layer** (`@opensourcekd/ng-common-libs/core`): Framework-agnostic
|
|
10
|
-
- **Angular Layer** (`@opensourcekd/ng-common-libs` or `/angular`): Angular-specific
|
|
9
|
+
- **Core Layer** (`@opensourcekd/ng-common-libs/core`): Framework-agnostic event bus using only RxJS. Use in React, Vue, Svelte, or vanilla JavaScript projects.
|
|
10
|
+
- **Angular Layer** (`@opensourcekd/ng-common-libs` or `/angular`): Angular-specific services with dependency injection.
|
|
11
11
|
|
|
12
12
|
## 🚀 Features
|
|
13
13
|
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **Storage Manager**: Type-safe localStorage/sessionStorage wrapper (framework-agnostic)
|
|
17
|
-
- **Logger**: Configurable logging with multiple levels (framework-agnostic)
|
|
18
|
-
- **Authorization**: Angular guards, interceptors, and permission handling
|
|
19
|
-
- **HTTP Utilities**: Error handling, caching, and retry logic for Angular HTTP requests
|
|
14
|
+
- **EventBusService**: MicroFrontend-ready event bus with replay buffer for cross-app communication
|
|
15
|
+
- **Auth0 Integration**: Complete Auth0 authentication service with token management
|
|
20
16
|
|
|
21
17
|
## 📦 Installation
|
|
22
18
|
|
|
@@ -24,263 +20,93 @@ This library features a **dual-layer architecture**:
|
|
|
24
20
|
npm install @opensourcekd/ng-common-libs
|
|
25
21
|
```
|
|
26
22
|
|
|
23
|
+
> **Note:** `mitt` and `@auth0/auth0-spa-js` are bundled with the library. You don't need to install them separately.
|
|
24
|
+
>
|
|
25
|
+
> **Module Federation**: Just configure `@opensourcekd/ng-common-libs` as shared in your webpack config. The bundled dependencies (`mitt`, `@auth0/auth0-spa-js`) will be included automatically, ensuring they're loaded only once across all micro-frontends.
|
|
26
|
+
|
|
27
27
|
## 🔧 Usage
|
|
28
28
|
|
|
29
|
-
###
|
|
29
|
+
### Auth0 Authentication
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
Complete Auth0 integration with automatic token management and event emission:
|
|
32
32
|
|
|
33
33
|
```typescript
|
|
34
|
-
import { Component,
|
|
35
|
-
import {
|
|
34
|
+
import { Component, inject } from '@angular/core';
|
|
35
|
+
import { AuthService, configureAuth0 } from '@opensourcekd/ng-common-libs';
|
|
36
|
+
|
|
37
|
+
// Configure Auth0 in your app.config.ts
|
|
38
|
+
configureAuth0({
|
|
39
|
+
domain: 'your-domain.auth0.com',
|
|
40
|
+
clientId: 'your-client-id',
|
|
41
|
+
audience: 'https://your-api.com',
|
|
42
|
+
});
|
|
36
43
|
|
|
37
44
|
@Component({
|
|
38
|
-
selector: 'app-
|
|
39
|
-
template:
|
|
45
|
+
selector: 'app-login',
|
|
46
|
+
template: `
|
|
47
|
+
<button (click)="login()">Login with Auth0</button>
|
|
48
|
+
<button (click)="logout()" *ngIf="user">Logout</button>
|
|
49
|
+
<div *ngIf="user">Welcome, {{ user.name }}!</div>
|
|
50
|
+
`
|
|
40
51
|
})
|
|
41
|
-
export class
|
|
42
|
-
private
|
|
52
|
+
export class LoginComponent {
|
|
53
|
+
private authService = inject(AuthService);
|
|
54
|
+
user = this.authService.getUser();
|
|
43
55
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this.eventEmitter.on('user:login').subscribe(data => {
|
|
47
|
-
console.log('User logged in:', data);
|
|
48
|
-
});
|
|
56
|
+
async login() {
|
|
57
|
+
await this.authService.login();
|
|
49
58
|
}
|
|
50
59
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
this.eventEmitter.emit('user:login', {
|
|
54
|
-
userId: '123',
|
|
55
|
-
username: 'john'
|
|
56
|
-
});
|
|
60
|
+
async logout() {
|
|
61
|
+
await this.authService.logout();
|
|
57
62
|
}
|
|
58
63
|
}
|
|
59
64
|
```
|
|
60
65
|
|
|
61
|
-
|
|
66
|
+
See the [Auth0 Service Usage Guide](./docs/AUTH_SERVICE_USAGE.md) for complete integration instructions.
|
|
62
67
|
|
|
63
|
-
|
|
68
|
+
### EventBusService
|
|
64
69
|
|
|
65
|
-
|
|
70
|
+
Cross-application event communication for MicroFrontend architectures:
|
|
66
71
|
|
|
67
72
|
```typescript
|
|
68
|
-
import { inject } from '@angular/core';
|
|
69
|
-
import {
|
|
70
|
-
|
|
71
|
-
export class AuthService {
|
|
72
|
-
private tokenService = inject(TokenService);
|
|
73
|
-
|
|
74
|
-
login(token: string) {
|
|
75
|
-
this.tokenService.setToken(token);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
logout() {
|
|
79
|
-
this.tokenService.clearTokens();
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
isAuthenticated(): boolean {
|
|
83
|
-
return this.tokenService.isAuthenticated();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
getUserData() {
|
|
87
|
-
return this.tokenService.getUserFromToken();
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
#### Auth Guard
|
|
93
|
-
|
|
94
|
-
Protect routes with authentication guards:
|
|
95
|
-
|
|
96
|
-
```typescript
|
|
97
|
-
import { Routes } from '@angular/router';
|
|
98
|
-
import { authGuard, createRoleGuard } from '@opensourcekd/ng-common-libs';
|
|
99
|
-
|
|
100
|
-
export const routes: Routes = [
|
|
101
|
-
{
|
|
102
|
-
path: 'dashboard',
|
|
103
|
-
component: DashboardComponent,
|
|
104
|
-
canActivate: [authGuard]
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
path: 'admin',
|
|
108
|
-
component: AdminComponent,
|
|
109
|
-
canActivate: [createRoleGuard(['admin'], { redirectUrl: '/unauthorized' })]
|
|
110
|
-
}
|
|
111
|
-
];
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
#### Auth Interceptor
|
|
115
|
-
|
|
116
|
-
Automatically add authentication tokens to HTTP requests:
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
import { ApplicationConfig } from '@angular/core';
|
|
120
|
-
import { provideHttpClient, withInterceptors } from '@angular/common/http';
|
|
121
|
-
import { authInterceptor, configureAuthInterceptor } from '@opensourcekd/ng-common-libs';
|
|
122
|
-
|
|
123
|
-
// Configure the interceptor (optional)
|
|
124
|
-
configureAuthInterceptor({
|
|
125
|
-
headerName: 'Authorization',
|
|
126
|
-
tokenPrefix: 'Bearer',
|
|
127
|
-
excludedUrls: ['/auth/login', '/auth/register']
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
export const appConfig: ApplicationConfig = {
|
|
131
|
-
providers: [
|
|
132
|
-
provideHttpClient(
|
|
133
|
-
withInterceptors([authInterceptor])
|
|
134
|
-
)
|
|
135
|
-
]
|
|
136
|
-
};
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
#### Permission Service
|
|
140
|
-
|
|
141
|
-
Check user permissions and roles:
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
import { inject } from '@angular/core';
|
|
145
|
-
import { PermissionService } from '@opensourcekd/ng-common-libs';
|
|
146
|
-
|
|
147
|
-
export class MyComponent {
|
|
148
|
-
private permissionService = inject(PermissionService);
|
|
149
|
-
|
|
150
|
-
canEditPost(): boolean {
|
|
151
|
-
return this.permissionService.hasPermission('posts:edit');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
isAdmin(): boolean {
|
|
155
|
-
return this.permissionService.hasRole('admin');
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Storage Service
|
|
161
|
-
|
|
162
|
-
Type-safe storage operations with JSON serialization:
|
|
163
|
-
|
|
164
|
-
```typescript
|
|
165
|
-
import { inject } from '@angular/core';
|
|
166
|
-
import { StorageService } from '@opensourcekd/ng-common-libs';
|
|
167
|
-
|
|
168
|
-
export class UserPreferencesService {
|
|
169
|
-
private storage = inject(StorageService);
|
|
170
|
-
|
|
171
|
-
savePreferences(prefs: UserPreferences) {
|
|
172
|
-
this.storage.setLocal('user-prefs', prefs);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
getPreferences(): UserPreferences | null {
|
|
176
|
-
return this.storage.getLocal<UserPreferences>('user-prefs');
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// With expiration (1 hour)
|
|
180
|
-
saveTempData(data: any) {
|
|
181
|
-
this.storage.setWithExpiration('temp-data', data, 3600000);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
getTempData() {
|
|
185
|
-
return this.storage.getWithExpiration('temp-data');
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Logger Service
|
|
73
|
+
import { Component, OnInit, inject } from '@angular/core';
|
|
74
|
+
import { EventBusService } from '@opensourcekd/ng-common-libs';
|
|
191
75
|
|
|
192
|
-
|
|
76
|
+
@Component({
|
|
77
|
+
selector: 'app-event-example',
|
|
78
|
+
template: `<button (click)="sendEvent()">Send Event</button>`
|
|
79
|
+
})
|
|
80
|
+
export class EventExampleComponent implements OnInit {
|
|
81
|
+
private eventBus = inject(EventBusService);
|
|
193
82
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
export class MyService {
|
|
199
|
-
private logger = inject(LoggerService);
|
|
200
|
-
|
|
201
|
-
constructor() {
|
|
202
|
-
// Configure logger
|
|
203
|
-
this.logger.configure({
|
|
204
|
-
level: LogLevel.DEBUG,
|
|
205
|
-
enableTimestamp: true,
|
|
206
|
-
prefix: 'MyApp'
|
|
83
|
+
ngOnInit() {
|
|
84
|
+
// Subscribe to all events
|
|
85
|
+
this.eventBus.onePlusNEvents.subscribe(event => {
|
|
86
|
+
console.log('Event received:', event);
|
|
207
87
|
});
|
|
208
88
|
}
|
|
209
89
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
this.
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
this.logger.time('fetchData', async () => {
|
|
218
|
-
return await this.fetchData();
|
|
219
|
-
});
|
|
90
|
+
sendEvent() {
|
|
91
|
+
// Send structured event
|
|
92
|
+
this.eventBus.sendEvent(JSON.stringify({
|
|
93
|
+
type: 'user:action',
|
|
94
|
+
payload: { userId: '123' },
|
|
95
|
+
timestamp: new Date().toISOString()
|
|
96
|
+
}));
|
|
220
97
|
}
|
|
221
98
|
}
|
|
222
99
|
```
|
|
223
100
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
#### Error Handling Interceptor
|
|
227
|
-
|
|
228
|
-
Handle HTTP errors with automatic retry:
|
|
229
|
-
|
|
230
|
-
```typescript
|
|
231
|
-
import { ApplicationConfig } from '@angular/core';
|
|
232
|
-
import { provideHttpClient, withInterceptors } from '@angular/common/http';
|
|
233
|
-
import { errorHandlingInterceptor, configureErrorHandling } from '@opensourcekd/ng-common-libs';
|
|
234
|
-
|
|
235
|
-
// Configure error handling
|
|
236
|
-
configureErrorHandling({
|
|
237
|
-
enableLogging: true,
|
|
238
|
-
retryAttempts: 3,
|
|
239
|
-
retryDelay: 1000,
|
|
240
|
-
retryStatusCodes: [500, 502, 503, 504]
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
export const appConfig: ApplicationConfig = {
|
|
244
|
-
providers: [
|
|
245
|
-
provideHttpClient(
|
|
246
|
-
withInterceptors([errorHandlingInterceptor])
|
|
247
|
-
)
|
|
248
|
-
]
|
|
249
|
-
};
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
#### Caching Interceptor
|
|
253
|
-
|
|
254
|
-
Cache HTTP responses:
|
|
255
|
-
|
|
256
|
-
```typescript
|
|
257
|
-
import { ApplicationConfig } from '@angular/core';
|
|
258
|
-
import { provideHttpClient, withInterceptors } from '@angular/common/http';
|
|
259
|
-
import { cachingInterceptor, configureCaching } from '@opensourcekd/ng-common-libs';
|
|
260
|
-
|
|
261
|
-
// Configure caching
|
|
262
|
-
configureCaching({
|
|
263
|
-
enabled: true,
|
|
264
|
-
maxAge: 300000, // 5 minutes
|
|
265
|
-
cacheableUrls: ['/api/users', '/api/products']
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
export const appConfig: ApplicationConfig = {
|
|
269
|
-
providers: [
|
|
270
|
-
provideHttpClient(
|
|
271
|
-
withInterceptors([cachingInterceptor])
|
|
272
|
-
)
|
|
273
|
-
]
|
|
274
|
-
};
|
|
275
|
-
```
|
|
101
|
+
See the [EventBus Service Usage Guide](./docs/EVENT_BUS_USAGE.md) for advanced patterns and MicroFrontend examples.
|
|
276
102
|
|
|
277
103
|
### For Non-Angular Projects (React, Vue, Svelte, Vanilla JS)
|
|
278
104
|
|
|
279
|
-
Use the framework-agnostic core
|
|
105
|
+
Use the framework-agnostic core event bus:
|
|
280
106
|
|
|
281
107
|
```typescript
|
|
282
108
|
// Import from /core
|
|
283
|
-
import { EventBus
|
|
109
|
+
import { EventBus } from '@opensourcekd/ng-common-libs/core';
|
|
284
110
|
|
|
285
111
|
// Event Bus
|
|
286
112
|
const eventBus = new EventBus();
|
|
@@ -288,23 +114,6 @@ eventBus.emit('user:login', { userId: '123' });
|
|
|
288
114
|
eventBus.on('user:login').subscribe(data => {
|
|
289
115
|
console.log('User logged in:', data);
|
|
290
116
|
});
|
|
291
|
-
|
|
292
|
-
// Token Manager
|
|
293
|
-
const tokenManager = new TokenManager();
|
|
294
|
-
tokenManager.setToken('your-jwt-token');
|
|
295
|
-
if (tokenManager.isAuthenticated()) {
|
|
296
|
-
const user = tokenManager.getUserFromToken();
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Storage Manager
|
|
300
|
-
const storage = new StorageManager();
|
|
301
|
-
storage.setLocal('preferences', { theme: 'dark' });
|
|
302
|
-
const prefs = storage.getLocal('preferences');
|
|
303
|
-
|
|
304
|
-
// Logger
|
|
305
|
-
const logger = new Logger();
|
|
306
|
-
logger.configure({ level: LogLevel.DEBUG, prefix: 'MyApp' });
|
|
307
|
-
logger.info('Application started');
|
|
308
117
|
```
|
|
309
118
|
|
|
310
119
|
#### React Example
|
|
@@ -364,49 +173,36 @@ export default {
|
|
|
364
173
|
|
|
365
174
|
## 📚 Documentation
|
|
366
175
|
|
|
367
|
-
- **[Usage
|
|
368
|
-
- **[
|
|
176
|
+
- **[Auth0 Service Usage](./docs/AUTH_SERVICE_USAGE.md)** - Complete Auth0 authentication integration guide
|
|
177
|
+
- **[EventBus Service Usage](./docs/EVENT_BUS_USAGE.md)** - Cross-application event communication guide
|
|
369
178
|
- **[Deployment Guide](./docs/DEPLOYMENT.md)** - Publishing, versioning, and consumption
|
|
370
179
|
- **[Microapp Triggering Guide](./docs/MICROAPP_TRIGGERING.md)** - Automatic build triggering for consuming microapps
|
|
371
180
|
- **[Module Federation Guide](./docs/MODULE_FEDERATION.md)** - Runtime sharing with Module Federation
|
|
372
|
-
- **[Architecture Decisions](./ARCHITECTURE_DECISIONS.md)** - Detailed architecture and design decisions
|
|
373
181
|
|
|
374
182
|
## 📝 API Documentation
|
|
375
183
|
|
|
376
|
-
###
|
|
377
|
-
|
|
378
|
-
- `emit<T>(eventType: string, data?: T): void` - Emit an event
|
|
379
|
-
- `on<T>(eventType: string): Observable<T>` - Subscribe to an event
|
|
380
|
-
- `onMultiple(eventTypes: string[]): Observable<EventPayload>` - Subscribe to multiple events
|
|
381
|
-
- `onAll(): Observable<EventPayload>` - Subscribe to all events
|
|
382
|
-
|
|
383
|
-
### TokenService
|
|
184
|
+
### AuthService
|
|
384
185
|
|
|
385
|
-
- `
|
|
386
|
-
- `
|
|
387
|
-
- `
|
|
388
|
-
- `
|
|
389
|
-
- `
|
|
390
|
-
- `
|
|
391
|
-
- `
|
|
186
|
+
- `login(options?: RedirectLoginOptions): Promise<void>` - Initiate Auth0 login
|
|
187
|
+
- `logout(options?: LogoutOptions): Promise<void>` - Logout and clear session
|
|
188
|
+
- `handleCallback(): Promise<{ success: boolean, appState?: any }>` - Handle Auth0 callback
|
|
189
|
+
- `getToken(): Promise<string | null>` - Get access token asynchronously
|
|
190
|
+
- `getTokenSync(): string | null` - Get cached access token synchronously
|
|
191
|
+
- `getUser(): Signal<UserInfo | null>` - Get user information as signal
|
|
192
|
+
- `isAuthenticated(): Signal<boolean>` - Check authentication status
|
|
193
|
+
- `isLoading(): Signal<boolean>` - Check if authentication is loading
|
|
392
194
|
|
|
393
|
-
###
|
|
195
|
+
### EventBusService
|
|
394
196
|
|
|
395
|
-
- `
|
|
396
|
-
- `
|
|
397
|
-
- `removeLocal(key: string): void` - Remove item from localStorage
|
|
398
|
-
- `setSession<T>(key: string, value: T): boolean` - Set item in sessionStorage
|
|
399
|
-
- `getSession<T>(key: string, defaultValue?: T): T | null` - Get item from sessionStorage
|
|
400
|
-
- `setWithExpiration<T>(key, value, expirationMs, useSession?): boolean` - Set item with expiration
|
|
401
|
-
- `getWithExpiration<T>(key, useSession?): T | null` - Get item with expiration check
|
|
197
|
+
- `sendEvent(event: string): void` - Send event to all subscribers
|
|
198
|
+
- `onePlusNEvents: Observable<string>` - Subscribe to all events with replay buffer
|
|
402
199
|
|
|
403
|
-
###
|
|
200
|
+
### EventBus (Core)
|
|
404
201
|
|
|
405
|
-
- `
|
|
406
|
-
- `
|
|
407
|
-
- `
|
|
408
|
-
- `
|
|
409
|
-
- `time<T>(label: string, fn: () => Promise<T> | T): Promise<T>` - Measure execution time
|
|
202
|
+
- `emit<T>(eventType: string, data?: T): void` - Emit an event
|
|
203
|
+
- `on<T>(eventType: string): Observable<T>` - Subscribe to an event
|
|
204
|
+
- `onMultiple(eventTypes: string[]): Observable<EventPayload>` - Subscribe to multiple events
|
|
205
|
+
- `onAll(): Observable<EventPayload>` - Subscribe to all events
|
|
410
206
|
|
|
411
207
|
## 🛠️ Development
|
|
412
208
|
|
|
@@ -436,4 +232,3 @@ Contributions, issues, and feature requests are welcome!
|
|
|
436
232
|
## ⭐ Show your support
|
|
437
233
|
|
|
438
234
|
Give a ⭐️ if this project helped you!
|
|
439
|
-
|