@codex-ts/core-lib 1.1.5 → 2.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.
- package/README.md +362 -33
- package/fesm2022/codex-ts-core-lib.mjs +4357 -2708
- package/fesm2022/codex-ts-core-lib.mjs.map +1 -1
- package/lib/components/base-form.component.d.ts +3 -4
- package/lib/components/base-page.component.d.ts +2 -1
- package/lib/components/base-tabbed-form.component.d.ts +3 -4
- package/lib/components/base-table.component.d.ts +1 -0
- package/lib/components/base-task-dashboard.component.d.ts +21 -15
- package/lib/components/base-task-details.component.d.ts +4 -5
- package/lib/components/formly/field.interface.d.ts +34 -0
- package/lib/components/formly/form-field.wrapper.d.ts +6 -6
- package/lib/components/formly/formly.constants.d.ts +1 -0
- package/lib/components/formly/primeng-formly.module.d.ts +19 -0
- package/lib/components/formly/types/file-upload.type.d.ts +58 -0
- package/lib/components/formly/types/radio.type.d.ts +5 -0
- package/lib/components/formly/types/text-input.type.d.ts +10 -1
- package/lib/components/keycloak-error-banner/keycloak-error-page.component.d.ts +6 -0
- package/lib/components/not-found/not-found.component.d.ts +11 -0
- package/lib/components/unauthorized/unauthorized.component.d.ts +12 -0
- package/lib/keycloak/keycloak-service.token.d.ts +3 -0
- package/lib/keycloak/keycloak.guard.d.ts +1 -1
- package/lib/keycloak/keycloak.interface.d.ts +21 -0
- package/lib/keycloak/keycloak.service.d.ts +24 -3
- package/lib/models/base-task.model.d.ts +6 -4
- package/lib/models/base.comment.model.d.ts +5 -0
- package/lib/models/base.entity.model.d.ts +39 -0
- package/lib/models/base.model.d.ts +0 -44
- package/lib/models/department.interface.d.ts +4 -0
- package/lib/models/pagination/filter-criteria.interface.d.ts +3 -0
- package/lib/models/pagination/table-column-datatype.enum.d.ts +6 -0
- package/lib/models/reference-dto.interface.d.ts +5 -0
- package/lib/models/workflow.model.d.ts +27 -0
- package/lib/services/base-entity.service.d.ts +80 -0
- package/lib/services/base-error.service.d.ts +24 -0
- package/lib/services/base-task.service.d.ts +21 -19
- package/lib/services/entity-registry.service.d.ts +21 -0
- package/lib/services/entity-service.interface.d.ts +22 -0
- package/lib/services/form.service.d.ts +7 -8
- package/lib/services/http-utility.service.d.ts +18 -0
- package/lib/services/master-data-service.interface.d.ts +5 -0
- package/lib/services/task-entity-service.interface.d.ts +24 -0
- package/lib/validators/common-validators.d.ts +61 -0
- package/lib/workflow-engine/workflow-engine-api.service.d.ts +104 -0
- package/lib/workflow-engine/workflow-engine.models.d.ts +236 -0
- package/package.json +2 -2
- package/public-api.d.ts +53 -33
- package/lib/services/base-crud.service.d.ts +0 -36
- package/lib/services/entity.service.d.ts +0 -9
package/README.md
CHANGED
|
@@ -1,63 +1,392 @@
|
|
|
1
1
|
# CoreLib
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Reusable Angular library for enterprise applications, providing dynamic forms, CRUD services, and Keycloak-based authentication.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
CoreLib offers:
|
|
10
|
+
- Abstract components for forms, lists, and dashboards
|
|
11
|
+
- Generic CRUD services
|
|
12
|
+
- Strongly-typed models and enums
|
|
13
|
+
- Keycloak authentication and route protection
|
|
14
|
+
- Signal-based error handling and state management
|
|
15
|
+
- Built-in error pages and components
|
|
16
|
+
- Utilities for state management and notifications
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
8
21
|
|
|
9
22
|
```bash
|
|
10
|
-
|
|
23
|
+
npm install @codex-ts/core-lib
|
|
11
24
|
```
|
|
12
25
|
|
|
13
|
-
|
|
26
|
+
**Peer dependencies** (install in your app if not present):
|
|
27
|
+
- `@angular/core`, `@angular/common`, `@ngx-formly/core`, `primeng`, `rxjs`, `keycloak-js`
|
|
14
28
|
|
|
15
|
-
|
|
16
|
-
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Setup
|
|
32
|
+
|
|
33
|
+
### Configuring Keycloak with Environment Properties
|
|
34
|
+
|
|
35
|
+
You can configure Keycloak using environment-specific properties to avoid hardcoding sensitive values.
|
|
36
|
+
|
|
37
|
+
**Option 1: Using Angular's environment.ts**
|
|
38
|
+
|
|
39
|
+
Set your Keycloak config in `src/environments/environment.ts`:
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// environment.ts
|
|
43
|
+
export const environment = {
|
|
44
|
+
production: false,
|
|
45
|
+
keycloak: {
|
|
46
|
+
authServerUrl: 'https://<keycloak-server>/auth',
|
|
47
|
+
realm: '<realm>',
|
|
48
|
+
clientId: '<client-id>',
|
|
49
|
+
options: {
|
|
50
|
+
loginRedirect: '/dashboard',
|
|
51
|
+
bearerToken: true,
|
|
52
|
+
excludedUrls: ['/assets', '/public'],
|
|
53
|
+
roles: ['user', 'admin'],
|
|
54
|
+
tokenValidityThreshold: 60
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
17
58
|
```
|
|
18
59
|
|
|
19
|
-
|
|
60
|
+
Then provide it in your app module:
|
|
20
61
|
|
|
21
|
-
|
|
62
|
+
```typescript
|
|
63
|
+
import { environment } from '../environments/environment';
|
|
64
|
+
import { KEYCLOAK_CONFIG } from '@codex-ts/core-lib';
|
|
22
65
|
|
|
23
|
-
|
|
24
|
-
|
|
66
|
+
providers: [
|
|
67
|
+
{
|
|
68
|
+
provide: KEYCLOAK_CONFIG,
|
|
69
|
+
useValue: environment.keycloak
|
|
70
|
+
}
|
|
71
|
+
]
|
|
25
72
|
```
|
|
26
73
|
|
|
27
|
-
|
|
74
|
+
**Option 2: Using Runtime Environment (e.g., assets/config.json)**
|
|
28
75
|
|
|
29
|
-
|
|
76
|
+
1. Create a `config.json` file in your `assets` folder with Keycloak settings.
|
|
77
|
+
2. Load it at app startup and provide it to `KEYCLOAK_CONFIG` using an `APP_INITIALIZER`.
|
|
30
78
|
|
|
31
|
-
|
|
79
|
+
Example:
|
|
32
80
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
81
|
+
```typescript
|
|
82
|
+
// assets/config.json
|
|
83
|
+
{
|
|
84
|
+
"authServerUrl": "https://<keycloak-server>/auth",
|
|
85
|
+
"realm": "<realm>",
|
|
86
|
+
"clientId": "<client-id>",
|
|
87
|
+
"options": {
|
|
88
|
+
"loginRedirect": "/dashboard",
|
|
89
|
+
"bearerToken": true
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
37
93
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
94
|
+
```typescript
|
|
95
|
+
// app.module.ts
|
|
96
|
+
import { HttpClient } from '@angular/common/http';
|
|
97
|
+
import { APP_INITIALIZER } from '@angular/core';
|
|
98
|
+
import { KEYCLOAK_CONFIG } from '@codex-ts/core-lib';
|
|
42
99
|
|
|
43
|
-
|
|
100
|
+
export function loadConfig(http: HttpClient) {
|
|
101
|
+
return () => http.get('/assets/config.json')
|
|
102
|
+
.toPromise()
|
|
103
|
+
.then(config => {
|
|
104
|
+
(window as any).keycloakConfig = config;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
44
107
|
|
|
45
|
-
|
|
108
|
+
providers: [
|
|
109
|
+
{
|
|
110
|
+
provide: APP_INITIALIZER,
|
|
111
|
+
useFactory: loadConfig,
|
|
112
|
+
deps: [HttpClient],
|
|
113
|
+
multi: true
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
provide: KEYCLOAK_CONFIG,
|
|
117
|
+
useFactory: () => (window as any).keycloakConfig
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
```
|
|
46
121
|
|
|
47
|
-
|
|
48
|
-
|
|
122
|
+
This allows you to change Keycloak settings without rebuilding the app.
|
|
123
|
+
|
|
124
|
+
### 1. Import the Library Module
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import { CoreLibModule } from '@codex-ts/core-lib';
|
|
128
|
+
|
|
129
|
+
@NgModule({
|
|
130
|
+
imports: [CoreLibModule, ...]
|
|
131
|
+
})
|
|
132
|
+
export class AppModule {}
|
|
49
133
|
```
|
|
50
134
|
|
|
51
|
-
|
|
135
|
+
### 2. Configure Keycloak
|
|
52
136
|
|
|
53
|
-
|
|
137
|
+
Provide Keycloak configuration in your app module:
|
|
54
138
|
|
|
55
|
-
```
|
|
56
|
-
|
|
139
|
+
```typescript
|
|
140
|
+
import { KEYCLOAK_CONFIG } from '@codex-ts/core-lib';
|
|
141
|
+
|
|
142
|
+
providers: [
|
|
143
|
+
{
|
|
144
|
+
provide: KEYCLOAK_CONFIG,
|
|
145
|
+
useValue: {
|
|
146
|
+
authServerUrl: 'https://<keycloak-server>/auth',
|
|
147
|
+
realm: '<realm>',
|
|
148
|
+
clientId: '<client-id>',
|
|
149
|
+
options: {
|
|
150
|
+
loginRedirect: '/dashboard',
|
|
151
|
+
bearerToken: true,
|
|
152
|
+
excludedUrls: ['/assets', '/public'],
|
|
153
|
+
roles: ['user', 'admin'],
|
|
154
|
+
tokenValidityThreshold: 60
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
]
|
|
57
159
|
```
|
|
58
160
|
|
|
59
|
-
|
|
161
|
+
### 3. Register Interceptor and Guard
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
165
|
+
import { KeycloakAuthInterceptor, KeycloakAuthGuard } from '@codex-ts/core-lib';
|
|
166
|
+
|
|
167
|
+
providers: [
|
|
168
|
+
{ provide: HTTP_INTERCEPTORS, useClass: KeycloakAuthInterceptor, multi: true },
|
|
169
|
+
KeycloakAuthGuard
|
|
170
|
+
]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 4. Protect Routes
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
{
|
|
177
|
+
path: 'secure',
|
|
178
|
+
component: SecureComponent,
|
|
179
|
+
canActivate: [KeycloakAuthGuard],
|
|
180
|
+
data: { roles: ['admin'] }
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Usage
|
|
187
|
+
|
|
188
|
+
- Use provided base components and services for forms, lists, and CRUD operations.
|
|
189
|
+
- Inject `KeycloakService` to access authentication state, user info, and roles.
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
constructor(private keycloak: KeycloakService) {}
|
|
193
|
+
|
|
194
|
+
ngOnInit() {
|
|
195
|
+
if (this.keycloak.isAuthenticated$()) {
|
|
196
|
+
// User is authenticated
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## KeycloakService API
|
|
204
|
+
|
|
205
|
+
- `initialize()`: Initializes Keycloak.
|
|
206
|
+
- `login()`, `logout()`: Triggers login/logout.
|
|
207
|
+
- `getToken()`: Gets current access token.
|
|
208
|
+
- `getRoles()`, `hasRole(role)`: Role management.
|
|
209
|
+
- `userProfile$`: Observable for user profile.
|
|
210
|
+
|
|
211
|
+
**Example:**
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
if (this.keycloak.hasRole('admin')) {
|
|
215
|
+
// Show admin features
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Troubleshooting
|
|
222
|
+
|
|
223
|
+
- Ensure Keycloak server is reachable.
|
|
224
|
+
- Check DI configuration for KEYCLOAK_CONFIG.
|
|
225
|
+
- Use browser console for error logs from KeycloakService.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Contributing
|
|
230
|
+
|
|
231
|
+
- Fork, branch, and submit PRs.
|
|
232
|
+
- Write unit tests for new features.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## License
|
|
237
|
+
|
|
238
|
+
MIT
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Error Handling
|
|
243
|
+
|
|
244
|
+
CoreLib provides a comprehensive, signal-based error handling system:
|
|
245
|
+
|
|
246
|
+
### Features
|
|
247
|
+
- Centralized error state management using Angular signals
|
|
248
|
+
- Built-in error pages for common scenarios (404, 401, etc.)
|
|
249
|
+
- Dynamic error messages and status codes
|
|
250
|
+
- Automatic cleanup on navigation
|
|
251
|
+
- Toast notifications for non-critical errors
|
|
252
|
+
|
|
253
|
+
### Usage Example
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
// 1. Error Service in your components/services
|
|
257
|
+
constructor(private readonly errorService: BaseErrorService) {}
|
|
258
|
+
|
|
259
|
+
try {
|
|
260
|
+
// Your code
|
|
261
|
+
} catch (error) {
|
|
262
|
+
this.errorService.handleError(error);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// 2. React to errors in components
|
|
266
|
+
export class YourComponent {
|
|
267
|
+
private readonly errorService = inject(ERROR_SERVICE);
|
|
268
|
+
readonly error = this.errorService.error;
|
|
269
|
+
|
|
270
|
+
get errorMessage(): string {
|
|
271
|
+
return this.error()?.message ?? "Default message";
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Error Types
|
|
277
|
+
- HTTP errors (401, 403, 404, 500, etc.)
|
|
278
|
+
- Connection errors
|
|
279
|
+
- Client-side errors
|
|
280
|
+
- Application-specific errors
|
|
281
|
+
|
|
282
|
+
### Built-in Error Pages
|
|
283
|
+
- NotFoundComponent (404)
|
|
284
|
+
- UnauthorizedComponent (401/403)
|
|
285
|
+
- All error pages use signals for dynamic content
|
|
286
|
+
|
|
287
|
+
### Benefits
|
|
288
|
+
- Single source of truth for error handling
|
|
289
|
+
- Reactive updates with signals
|
|
290
|
+
- Consistent error handling across the application
|
|
291
|
+
- Improved debugging with error context
|
|
292
|
+
- Clean separation of error handling logic
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Task Management Implementation Example
|
|
297
|
+
|
|
298
|
+
This section demonstrates how to use `core-lib` to implement a typical task management module in your Angular application.
|
|
299
|
+
|
|
300
|
+
### Structure
|
|
301
|
+
|
|
302
|
+
- **Dashboard Component**: Extends `BaseTaskDashboardComponent` from core-lib for listing and managing tasks.
|
|
303
|
+
- **Details Component**: Extends `BaseFormComponent` or `BaseTaskDetailsComponent` for task details and editing.
|
|
304
|
+
- **Models**: Define task models extending `BaseTaskModel` and related interfaces.
|
|
305
|
+
- **Service**: Implements CRUD operations by extending `BaseCrudService`.
|
|
306
|
+
|
|
307
|
+
### Example
|
|
308
|
+
|
|
309
|
+
#### 1. Task Model
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { BaseTaskModel } from '@codex-ts/core-lib';
|
|
313
|
+
|
|
314
|
+
export interface CustomerServiceTask extends BaseTaskModel {
|
|
315
|
+
// Add custom fields here
|
|
316
|
+
status: string;
|
|
317
|
+
assignedTo: string;
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
#### 2. Task Service
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
import { Injectable } from '@angular/core';
|
|
325
|
+
import { BaseCrudService } from '@codex-ts/core-lib';
|
|
326
|
+
import { CustomerServiceTask } from './models/customer-service-task.model';
|
|
327
|
+
|
|
328
|
+
@Injectable({ providedIn: 'root' })
|
|
329
|
+
export class CustomerServiceTaskService extends BaseCrudService<CustomerServiceTask> {
|
|
330
|
+
constructor(/* inject dependencies */) {
|
|
331
|
+
super(/* pass dependencies and resource path */);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
#### 3. Dashboard Component
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
import { Component } from '@angular/core';
|
|
340
|
+
import { BaseTaskDashboardComponent } from '@codex-ts/core-lib';
|
|
341
|
+
import { CustomerServiceTaskService } from './customer-service-task.service';
|
|
342
|
+
import { CustomerServiceTask } from './models/customer-service-task.model';
|
|
343
|
+
|
|
344
|
+
@Component({
|
|
345
|
+
selector: 'app-customer-service-task-dashboard',
|
|
346
|
+
templateUrl: './customer-service-task-dashboard.component.html'
|
|
347
|
+
})
|
|
348
|
+
export class CustomerServiceTaskDashboardComponent
|
|
349
|
+
extends BaseTaskDashboardComponent<CustomerServiceTask> {
|
|
350
|
+
constructor(protected customerServiceTaskService: CustomerServiceTaskService) {
|
|
351
|
+
super(customerServiceTaskService);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
#### 4. Details Component
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
import { Component } from '@angular/core';
|
|
360
|
+
import { BaseFormComponent } from '@codex-ts/core-lib';
|
|
361
|
+
import { CustomerServiceTaskService } from './customer-service-task.service';
|
|
362
|
+
import { CustomerServiceTask } from './models/customer-service-task.model';
|
|
363
|
+
|
|
364
|
+
@Component({
|
|
365
|
+
selector: 'app-customer-task-details',
|
|
366
|
+
templateUrl: './customer-task-details.component.html'
|
|
367
|
+
})
|
|
368
|
+
export class CustomerTaskDetailsComponent
|
|
369
|
+
extends BaseFormComponent<CustomerServiceTask> {
|
|
370
|
+
constructor(protected customerServiceTaskService: CustomerServiceTaskService) {
|
|
371
|
+
super(customerServiceTaskService);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
#### 5. Routing and Guards
|
|
377
|
+
|
|
378
|
+
Protect routes using `KeycloakAuthGuard` and specify roles as needed:
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
{
|
|
382
|
+
path: 'tasks',
|
|
383
|
+
component: CustomerServiceTaskDashboardComponent,
|
|
384
|
+
canActivate: [KeycloakAuthGuard],
|
|
385
|
+
data: { roles: ['admin', 'user'] }
|
|
386
|
+
}
|
|
387
|
+
```
|
|
60
388
|
|
|
61
|
-
|
|
389
|
+
### Notes
|
|
62
390
|
|
|
63
|
-
|
|
391
|
+
- Use the provided base components and services for rapid development and consistency.
|
|
392
|
+
- Extend models and services as needed for your domain.
|