@mysteryinfosolutions/api-core 1.8.0 → 1.9.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 +930 -33
- package/fesm2022/mysteryinfosolutions-api-core.mjs +795 -46
- package/fesm2022/mysteryinfosolutions-api-core.mjs.map +1 -1
- package/index.d.ts +837 -24
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken } from '@angular/core';
|
|
2
3
|
import { Observable } from 'rxjs';
|
|
3
|
-
import { HttpClient } from '@angular/common/http';
|
|
4
|
+
import { HttpClient, HttpErrorResponse, HttpInterceptorFn } from '@angular/common/http';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Configuration for a table column.
|
|
8
|
+
*
|
|
9
|
+
* @template T The type of data row this column applies to
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const columns: TableColumn<User>[] = [
|
|
13
|
+
* {
|
|
14
|
+
* key: 'name',
|
|
15
|
+
* label: 'Full Name',
|
|
16
|
+
* isSortable: true,
|
|
17
|
+
* width: '200px'
|
|
18
|
+
* },
|
|
19
|
+
* {
|
|
20
|
+
* key: 'email',
|
|
21
|
+
* label: 'Email Address',
|
|
22
|
+
* type: 'text',
|
|
23
|
+
* hideOnMobile: true
|
|
24
|
+
* },
|
|
25
|
+
* {
|
|
26
|
+
* key: 'createdAt',
|
|
27
|
+
* label: 'Created',
|
|
28
|
+
* pipe: 'date',
|
|
29
|
+
* valueGetter: (row) => row.createdAt
|
|
30
|
+
* }
|
|
31
|
+
* ];
|
|
32
|
+
*/
|
|
33
|
+
interface TableColumn<T = Record<string, unknown>> {
|
|
6
34
|
/** Unique key used to identify the column */
|
|
7
35
|
key: keyof T | string;
|
|
8
36
|
/** Display label for the column header */
|
|
@@ -13,74 +41,252 @@ interface TableColumn<T = any> {
|
|
|
13
41
|
width?: string;
|
|
14
42
|
/** Type of cell rendering */
|
|
15
43
|
type?: 'text' | 'checkbox' | 'action' | 'custom';
|
|
16
|
-
/** Function to extract value from row */
|
|
17
|
-
valueGetter?: (row: T) =>
|
|
44
|
+
/** Function to extract value from row - return type can be any displayable value */
|
|
45
|
+
valueGetter?: (row: T) => string | number | boolean | Date | null | undefined;
|
|
18
46
|
/** Whether to hide the column on mobile screen sizes */
|
|
19
47
|
hideOnMobile?: boolean;
|
|
20
48
|
/** Optional Angular pipe to apply to the value */
|
|
21
|
-
pipe?: 'date' | 'currency' | 'uppercase' | 'lowercase' | string;
|
|
49
|
+
pipe?: 'date' | 'currency' | 'uppercase' | 'lowercase' | 'number' | 'percent' | string;
|
|
22
50
|
/** CSS class to apply to cell */
|
|
23
51
|
cellClass?: string;
|
|
24
52
|
/** CSS class to apply to header */
|
|
25
53
|
headerClass?: string;
|
|
26
54
|
/** Whether the column should be visible at all (default: true) */
|
|
27
55
|
visible?: boolean;
|
|
56
|
+
/** Alignment for cell content */
|
|
57
|
+
align?: 'left' | 'center' | 'right';
|
|
58
|
+
/** Whether the column is sticky (remains visible when scrolling) */
|
|
59
|
+
sticky?: boolean;
|
|
28
60
|
}
|
|
29
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Enum defining column selection modes for API queries.
|
|
64
|
+
*
|
|
65
|
+
* @remarks
|
|
66
|
+
* Used to control which columns are returned in API responses,
|
|
67
|
+
* useful for optimizing payload size and performance.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* const filter = {
|
|
71
|
+
* selectMode: SELECT_MODE.ONLYCOLUMNS,
|
|
72
|
+
* selectColumns: 'id,name,email'
|
|
73
|
+
* };
|
|
74
|
+
*/
|
|
30
75
|
declare enum SELECT_MODE {
|
|
76
|
+
/** Return all columns (default behavior) */
|
|
31
77
|
ALL = 1,
|
|
78
|
+
/** Return only specified columns via selectColumns parameter */
|
|
32
79
|
ONLYCOLUMNS = 2
|
|
33
80
|
}
|
|
34
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Base filter class providing common filtering, pagination, and sorting capabilities.
|
|
84
|
+
*
|
|
85
|
+
* @remarks
|
|
86
|
+
* Extend this class in your custom filter types to add domain-specific filter properties.
|
|
87
|
+
* The base filter handles pagination, sorting, searching, and date range filtering.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* interface UserFilter extends Filter {
|
|
91
|
+
* role?: string;
|
|
92
|
+
* isActive?: boolean;
|
|
93
|
+
* departmentId?: number;
|
|
94
|
+
* }
|
|
95
|
+
*
|
|
96
|
+
* const filter: UserFilter = {
|
|
97
|
+
* page: 1,
|
|
98
|
+
* pageLength: 25,
|
|
99
|
+
* search: 'john',
|
|
100
|
+
* role: 'admin',
|
|
101
|
+
* sort: [new SortItem('name', 'ASC')]
|
|
102
|
+
* };
|
|
103
|
+
*/
|
|
35
104
|
declare abstract class Filter {
|
|
105
|
+
/** Array of specific IDs to filter by */
|
|
36
106
|
ids?: number[];
|
|
107
|
+
/** Column name to use for date range filtering */
|
|
37
108
|
dateRangeColumn?: string;
|
|
109
|
+
/** Start date for date range filter (ISO format) */
|
|
38
110
|
dateRangeFrom?: string;
|
|
111
|
+
/** End date for date range filter (ISO format) */
|
|
39
112
|
dateRangeTo?: string;
|
|
113
|
+
/** Current page number (1-based) */
|
|
40
114
|
page?: number;
|
|
115
|
+
/** Number of records per page */
|
|
41
116
|
pageLength?: number;
|
|
117
|
+
/** Array of sort configurations */
|
|
42
118
|
sort?: SortItem[];
|
|
119
|
+
/** Search query string */
|
|
43
120
|
search?: string;
|
|
121
|
+
/** Comma-separated list of columns to search in */
|
|
44
122
|
searchColumns?: string;
|
|
123
|
+
/** Comma-separated list of columns to select/return */
|
|
45
124
|
selectColumns?: string;
|
|
125
|
+
/** Mode for column selection */
|
|
46
126
|
selectMode?: SELECT_MODE;
|
|
47
|
-
[key: string]: string | number | number[] | SortItem[] | SELECT_MODE | boolean | undefined;
|
|
48
127
|
}
|
|
49
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Standard error object returned by the API.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* {
|
|
134
|
+
* code: 'VALIDATION_ERROR',
|
|
135
|
+
* message: 'Invalid email address',
|
|
136
|
+
* details: 'Email must be in valid format',
|
|
137
|
+
* showMessageToUser: true
|
|
138
|
+
* }
|
|
139
|
+
*/
|
|
50
140
|
interface IMisError {
|
|
141
|
+
/** Short error identifier */
|
|
51
142
|
error?: string;
|
|
143
|
+
/** Error code for programmatic handling */
|
|
52
144
|
code?: string;
|
|
145
|
+
/** Human-readable error message */
|
|
53
146
|
message?: string;
|
|
147
|
+
/** Detailed error information */
|
|
54
148
|
details?: string;
|
|
55
|
-
|
|
149
|
+
/** Stack trace (only in development) */
|
|
150
|
+
stack?: string | Record<string, unknown>;
|
|
151
|
+
/** Default fallback message */
|
|
56
152
|
defaultMessage?: string;
|
|
153
|
+
/** Whether this error should be displayed to the user */
|
|
57
154
|
showMessageToUser?: boolean;
|
|
58
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Pagination metadata returned with multi-result responses.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* {
|
|
161
|
+
* totalRecords: 150,
|
|
162
|
+
* currentPage: 2,
|
|
163
|
+
* lastPage: 15,
|
|
164
|
+
* perPage: 10,
|
|
165
|
+
* next: 3,
|
|
166
|
+
* previous: 1
|
|
167
|
+
* }
|
|
168
|
+
*/
|
|
59
169
|
interface IMultiresultMetaData {
|
|
170
|
+
/** Total number of records across all pages */
|
|
60
171
|
totalRecords: number;
|
|
172
|
+
/** Previous page number (if exists) */
|
|
61
173
|
previous?: number;
|
|
174
|
+
/** Current page number */
|
|
62
175
|
currentPage?: number;
|
|
176
|
+
/** Next page number (if exists) */
|
|
63
177
|
next?: number;
|
|
178
|
+
/** Number of records per page */
|
|
64
179
|
perPage?: number;
|
|
180
|
+
/** Current segment/batch number */
|
|
65
181
|
segment?: number;
|
|
182
|
+
/** Last page number */
|
|
66
183
|
lastPage?: number;
|
|
67
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Container for paginated list responses.
|
|
187
|
+
*
|
|
188
|
+
* @template T The type of records in the list
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* const response: IMultiresult<User> = {
|
|
192
|
+
* records: [
|
|
193
|
+
* { id: 1, name: 'John' },
|
|
194
|
+
* { id: 2, name: 'Jane' }
|
|
195
|
+
* ],
|
|
196
|
+
* pager: {
|
|
197
|
+
* totalRecords: 100,
|
|
198
|
+
* currentPage: 1,
|
|
199
|
+
* lastPage: 10,
|
|
200
|
+
* perPage: 10
|
|
201
|
+
* }
|
|
202
|
+
* };
|
|
203
|
+
*/
|
|
68
204
|
interface IMultiresult<T> {
|
|
205
|
+
/** Array of records for the current page */
|
|
69
206
|
records: T[];
|
|
207
|
+
/** Pagination metadata */
|
|
70
208
|
pager: IMultiresultMetaData;
|
|
71
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Standard API response wrapper.
|
|
212
|
+
*
|
|
213
|
+
* @template T The type of data contained in the response
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* // Success response
|
|
217
|
+
* const response: IResponse<User> = {
|
|
218
|
+
* status: 200,
|
|
219
|
+
* data: { id: 1, name: 'John' },
|
|
220
|
+
* infoDtls: null
|
|
221
|
+
* };
|
|
222
|
+
*
|
|
223
|
+
* // Error response
|
|
224
|
+
* const errorResponse: IResponse<User> = {
|
|
225
|
+
* status: 400,
|
|
226
|
+
* data: null,
|
|
227
|
+
* error: {
|
|
228
|
+
* code: 'VALIDATION_ERROR',
|
|
229
|
+
* message: 'Invalid input'
|
|
230
|
+
* }
|
|
231
|
+
* };
|
|
232
|
+
*/
|
|
72
233
|
interface IResponse<T> {
|
|
234
|
+
/** HTTP status code */
|
|
73
235
|
status?: number;
|
|
236
|
+
/** Response data (null if error occurred) */
|
|
74
237
|
data?: T | null;
|
|
238
|
+
/** Error information (present if request failed) */
|
|
75
239
|
error?: IMisError;
|
|
76
|
-
|
|
240
|
+
/** Additional information or metadata */
|
|
241
|
+
infoDtls?: Record<string, unknown> | null;
|
|
77
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Type alias for paginated list responses.
|
|
245
|
+
*
|
|
246
|
+
* @template T The type of records in the list
|
|
247
|
+
*/
|
|
78
248
|
type PagedResponse<T> = IResponse<IMultiresult<T>>;
|
|
249
|
+
/**
|
|
250
|
+
* Type alias for single record responses.
|
|
251
|
+
*
|
|
252
|
+
* @template T The type of the record
|
|
253
|
+
*/
|
|
79
254
|
type SingleResponse<T> = IResponse<T>;
|
|
80
255
|
|
|
256
|
+
/**
|
|
257
|
+
* Represents a single sort configuration for a field.
|
|
258
|
+
*
|
|
259
|
+
* @remarks
|
|
260
|
+
* Used in filter objects to specify sorting criteria.
|
|
261
|
+
* Multiple SortItem instances can be combined for multi-column sorting.
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* // Single sort
|
|
265
|
+
* const sort = new SortItem('name', 'ASC');
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* // Multi-column sort
|
|
269
|
+
* const sorts = [
|
|
270
|
+
* new SortItem('priority', 'DESC'),
|
|
271
|
+
* new SortItem('createdAt', 'DESC'),
|
|
272
|
+
* new SortItem('name', 'ASC')
|
|
273
|
+
* ];
|
|
274
|
+
*
|
|
275
|
+
* const filter = {
|
|
276
|
+
* page: 1,
|
|
277
|
+
* pageLength: 25,
|
|
278
|
+
* sort: sorts
|
|
279
|
+
* };
|
|
280
|
+
*/
|
|
81
281
|
declare class SortItem {
|
|
82
282
|
field: string;
|
|
83
283
|
order: 'ASC' | 'DESC';
|
|
284
|
+
/**
|
|
285
|
+
* Creates a sort configuration.
|
|
286
|
+
*
|
|
287
|
+
* @param field The field/column name to sort by
|
|
288
|
+
* @param order Sort direction: 'ASC' (ascending) or 'DESC' (descending)
|
|
289
|
+
*/
|
|
84
290
|
constructor(field: string, order: 'ASC' | 'DESC');
|
|
85
291
|
}
|
|
86
292
|
|
|
@@ -150,6 +356,143 @@ declare abstract class BaseResourceConfig<T> {
|
|
|
150
356
|
permissions: Record<StandardPermission | string, string>;
|
|
151
357
|
}
|
|
152
358
|
|
|
359
|
+
/**
|
|
360
|
+
* Configuration options for the api-core library.
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* // In your app.config.ts or module providers
|
|
364
|
+
* import { API_CORE_CONFIG, ApiCoreConfig } from '@mysteryinfosolutions/api-core';
|
|
365
|
+
*
|
|
366
|
+
* export const appConfig: ApplicationConfig = {
|
|
367
|
+
* providers: [
|
|
368
|
+
* {
|
|
369
|
+
* provide: API_CORE_CONFIG,
|
|
370
|
+
* useValue: {
|
|
371
|
+
* pagination: {
|
|
372
|
+
* defaultPage: 1,
|
|
373
|
+
* defaultPageLength: 25,
|
|
374
|
+
* pageLengthOptions: [25, 50, 100]
|
|
375
|
+
* },
|
|
376
|
+
* api: {
|
|
377
|
+
* dateFormat: 'iso',
|
|
378
|
+
* includeCredentials: true
|
|
379
|
+
* }
|
|
380
|
+
* } as ApiCoreConfig
|
|
381
|
+
* }
|
|
382
|
+
* ]
|
|
383
|
+
* };
|
|
384
|
+
*/
|
|
385
|
+
interface ApiCoreConfig {
|
|
386
|
+
/**
|
|
387
|
+
* Pagination configuration defaults
|
|
388
|
+
*/
|
|
389
|
+
pagination?: {
|
|
390
|
+
/** Default page number (1-based) */
|
|
391
|
+
defaultPage?: number;
|
|
392
|
+
/** Default number of items per page */
|
|
393
|
+
defaultPageLength?: number;
|
|
394
|
+
/** Available page length options for user selection */
|
|
395
|
+
pageLengthOptions?: number[];
|
|
396
|
+
/** Maximum allowed page length (to prevent large requests) */
|
|
397
|
+
maxPageLength?: number;
|
|
398
|
+
};
|
|
399
|
+
/**
|
|
400
|
+
* API request/response configuration
|
|
401
|
+
*/
|
|
402
|
+
api?: {
|
|
403
|
+
/** Date format for API requests ('iso' | 'timestamp' | 'custom') */
|
|
404
|
+
dateFormat?: 'iso' | 'timestamp' | 'custom';
|
|
405
|
+
/** Custom date formatter function (if dateFormat is 'custom') */
|
|
406
|
+
dateFormatter?: (date: Date) => string;
|
|
407
|
+
/** Whether to include credentials in requests */
|
|
408
|
+
includeCredentials?: boolean;
|
|
409
|
+
/** Default headers to include in all requests */
|
|
410
|
+
defaultHeaders?: Record<string, string>;
|
|
411
|
+
/** Request timeout in milliseconds */
|
|
412
|
+
timeout?: number;
|
|
413
|
+
};
|
|
414
|
+
/**
|
|
415
|
+
* Query string formatting options
|
|
416
|
+
*/
|
|
417
|
+
queryString?: {
|
|
418
|
+
/** Format for array parameters ('brackets' | 'comma' | 'repeat') */
|
|
419
|
+
arrayFormat?: 'brackets' | 'comma' | 'repeat';
|
|
420
|
+
/** Custom array formatter function */
|
|
421
|
+
arrayFormatter?: (key: string, values: unknown[]) => string;
|
|
422
|
+
/** Whether to encode query parameters */
|
|
423
|
+
encode?: boolean;
|
|
424
|
+
/** Custom encoder function */
|
|
425
|
+
encoder?: (value: string) => string;
|
|
426
|
+
};
|
|
427
|
+
/**
|
|
428
|
+
* Sort configuration
|
|
429
|
+
*/
|
|
430
|
+
sort?: {
|
|
431
|
+
/** Default sort order */
|
|
432
|
+
defaultOrder?: 'ASC' | 'DESC';
|
|
433
|
+
/** Separator between field and order in query string */
|
|
434
|
+
separator?: string;
|
|
435
|
+
/** Whether to allow multi-column sorting */
|
|
436
|
+
allowMultiSort?: boolean;
|
|
437
|
+
};
|
|
438
|
+
/**
|
|
439
|
+
* Error handling configuration
|
|
440
|
+
*/
|
|
441
|
+
errorHandling?: {
|
|
442
|
+
/** Whether to log errors to console */
|
|
443
|
+
logErrors?: boolean;
|
|
444
|
+
/** Whether to show user-friendly error messages */
|
|
445
|
+
showUserMessages?: boolean;
|
|
446
|
+
/** Global error handler function */
|
|
447
|
+
onError?: (error: unknown) => void;
|
|
448
|
+
};
|
|
449
|
+
/**
|
|
450
|
+
* Loading state configuration
|
|
451
|
+
*/
|
|
452
|
+
loading?: {
|
|
453
|
+
/** Minimum loading time in ms (prevents flash of loading state) */
|
|
454
|
+
minLoadingTime?: number;
|
|
455
|
+
/** Whether to show loading indicators by default */
|
|
456
|
+
showLoadingByDefault?: boolean;
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Default configuration values for the api-core library.
|
|
461
|
+
*/
|
|
462
|
+
declare const DEFAULT_API_CORE_CONFIG: Required<ApiCoreConfig>;
|
|
463
|
+
/**
|
|
464
|
+
* Injection token for api-core configuration.
|
|
465
|
+
*
|
|
466
|
+
* @example
|
|
467
|
+
* // Provide custom configuration
|
|
468
|
+
* providers: [
|
|
469
|
+
* {
|
|
470
|
+
* provide: API_CORE_CONFIG,
|
|
471
|
+
* useValue: {
|
|
472
|
+
* pagination: { defaultPageLength: 25 }
|
|
473
|
+
* } as ApiCoreConfig
|
|
474
|
+
* }
|
|
475
|
+
* ]
|
|
476
|
+
*
|
|
477
|
+
* @example
|
|
478
|
+
* // Inject in service
|
|
479
|
+
* constructor(@Inject(API_CORE_CONFIG) private config: ApiCoreConfig) {}
|
|
480
|
+
*/
|
|
481
|
+
declare const API_CORE_CONFIG: InjectionToken<ApiCoreConfig>;
|
|
482
|
+
/**
|
|
483
|
+
* Merges user-provided configuration with default values.
|
|
484
|
+
*
|
|
485
|
+
* @param userConfig User-provided configuration
|
|
486
|
+
* @returns Merged configuration with defaults
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* const config = mergeConfig({
|
|
490
|
+
* pagination: { defaultPageLength: 25 }
|
|
491
|
+
* });
|
|
492
|
+
* // Returns full config with defaultPageLength: 25 and all other defaults
|
|
493
|
+
*/
|
|
494
|
+
declare function mergeConfig(userConfig?: ApiCoreConfig): Required<ApiCoreConfig>;
|
|
495
|
+
|
|
153
496
|
declare class ApiCore {
|
|
154
497
|
static ɵfac: i0.ɵɵFactoryDeclaration<ApiCore, never>;
|
|
155
498
|
static ɵcmp: i0.ɵɵComponentDeclaration<ApiCore, "lib-api-core", never, {}, {}, never, never, true, never>;
|
|
@@ -174,12 +517,133 @@ declare class ApiCore {
|
|
|
174
517
|
*/
|
|
175
518
|
declare function generatePermissions<T extends string = StandardPermission>(resource: string, extra?: T[]): Record<T | StandardPermission, string>;
|
|
176
519
|
|
|
520
|
+
/**
|
|
521
|
+
* Converts an array of SortItem objects into a comma-separated sort string.
|
|
522
|
+
*
|
|
523
|
+
* @param sortItems Array of sort configurations
|
|
524
|
+
* @returns Formatted sort string (e.g., "name:ASC,createdAt:DESC") or empty string
|
|
525
|
+
*
|
|
526
|
+
* @example
|
|
527
|
+
* const sorts = [
|
|
528
|
+
* new SortItem('name', 'ASC'),
|
|
529
|
+
* new SortItem('createdAt', 'DESC')
|
|
530
|
+
* ];
|
|
531
|
+
* const sortString = sortObjectToString(sorts);
|
|
532
|
+
* // Returns: "name:ASC,createdAt:DESC"
|
|
533
|
+
*/
|
|
177
534
|
declare const sortObjectToString: (sortItems: SortItem[]) => string;
|
|
178
|
-
|
|
179
|
-
|
|
535
|
+
/**
|
|
536
|
+
* Converts a filter object into a URL query string.
|
|
537
|
+
*
|
|
538
|
+
* @param filter Filter object with query parameters
|
|
539
|
+
* @returns URL query string with '?' prefix, or empty string if no parameters
|
|
540
|
+
*
|
|
541
|
+
* @remarks
|
|
542
|
+
* - Automatically converts SortItem arrays to sort strings
|
|
543
|
+
* - Encodes all values for URL safety
|
|
544
|
+
* - Filters out undefined and null values
|
|
545
|
+
* - Arrays are encoded as comma-separated values in brackets
|
|
546
|
+
*
|
|
547
|
+
* @example
|
|
548
|
+
* const filter = {
|
|
549
|
+
* page: 1,
|
|
550
|
+
* pageLength: 25,
|
|
551
|
+
* search: 'John Doe',
|
|
552
|
+
* roles: ['admin', 'user'],
|
|
553
|
+
* sort: [new SortItem('name', 'ASC')]
|
|
554
|
+
* };
|
|
555
|
+
* const queryString = jsonToQueryString(filter);
|
|
556
|
+
* // Returns: "?page=1&pageLength=25&search=John%20Doe&roles=[admin,user]&sort=name:ASC"
|
|
557
|
+
*/
|
|
558
|
+
declare const jsonToQueryString: (filter: Record<string, unknown>) => string;
|
|
559
|
+
/**
|
|
560
|
+
* Checks if an object is empty (has no own properties).
|
|
561
|
+
*
|
|
562
|
+
* @param obj Object to check
|
|
563
|
+
* @returns True if object is null, undefined, or has no properties
|
|
564
|
+
*
|
|
565
|
+
* @example
|
|
566
|
+
* isEmpty({}); // true
|
|
567
|
+
* isEmpty(null); // true
|
|
568
|
+
* isEmpty(undefined); // true
|
|
569
|
+
* isEmpty({ page: 1 }); // false
|
|
570
|
+
* isEmpty([]); // true (arrays with no length)
|
|
571
|
+
*/
|
|
572
|
+
declare const isEmpty: (obj: Record<string, unknown> | null | undefined) => boolean;
|
|
180
573
|
|
|
181
574
|
/**
|
|
182
|
-
*
|
|
575
|
+
* Generic reactive state management service for data-driven features.
|
|
576
|
+
*
|
|
577
|
+
* @template TRecord The type of record/entity being managed
|
|
578
|
+
* @template TFilter Filter type extending Partial<TRecord> & Filter
|
|
579
|
+
*
|
|
580
|
+
* @remarks
|
|
581
|
+
* BaseStateService provides comprehensive state management for list-based views including:
|
|
582
|
+
* - Filter state with pagination and sorting
|
|
583
|
+
* - Records collection with CRUD helpers
|
|
584
|
+
* - Loading states (with context keys)
|
|
585
|
+
* - Error handling
|
|
586
|
+
* - Record selection
|
|
587
|
+
* - Pagination metadata
|
|
588
|
+
*
|
|
589
|
+
* All state is reactive using RxJS BehaviorSubjects, making it easy to integrate
|
|
590
|
+
* with Angular templates using the async pipe.
|
|
591
|
+
*
|
|
592
|
+
* @example
|
|
593
|
+
* // Basic setup in component
|
|
594
|
+
* @Component({
|
|
595
|
+
* selector: 'app-users',
|
|
596
|
+
* providers: [BaseStateService] // Component-level instance
|
|
597
|
+
* })
|
|
598
|
+
* export class UsersComponent implements OnInit, OnDestroy {
|
|
599
|
+
* state = new BaseStateService<User, UserFilter>();
|
|
600
|
+
*
|
|
601
|
+
* constructor(private userService: UserService) {}
|
|
602
|
+
*
|
|
603
|
+
* ngOnInit() {
|
|
604
|
+
* // Subscribe to filter changes
|
|
605
|
+
* this.state.filter$.subscribe(filter => {
|
|
606
|
+
* this.loadUsers(filter);
|
|
607
|
+
* });
|
|
608
|
+
*
|
|
609
|
+
* // Set initial filter
|
|
610
|
+
* this.state.setFilter({ page: 1, pageLength: 25 });
|
|
611
|
+
* }
|
|
612
|
+
*
|
|
613
|
+
* loadUsers(filter: UserFilter) {
|
|
614
|
+
* this.state.setLoading('list', true);
|
|
615
|
+
*
|
|
616
|
+
* this.userService.getAll(filter).subscribe({
|
|
617
|
+
* next: (response) => {
|
|
618
|
+
* if (response.data) {
|
|
619
|
+
* this.state.setApiResponse(response.data);
|
|
620
|
+
* }
|
|
621
|
+
* this.state.setLoading('list', false);
|
|
622
|
+
* },
|
|
623
|
+
* error: (err) => {
|
|
624
|
+
* this.state.setError('Failed to load users');
|
|
625
|
+
* this.state.setLoading('list', false);
|
|
626
|
+
* }
|
|
627
|
+
* });
|
|
628
|
+
* }
|
|
629
|
+
*
|
|
630
|
+
* ngOnDestroy() {
|
|
631
|
+
* this.state.destroy();
|
|
632
|
+
* }
|
|
633
|
+
* }
|
|
634
|
+
*
|
|
635
|
+
* @example
|
|
636
|
+
* // Using in template
|
|
637
|
+
* <div *ngIf="state.isLoading$('list') | async">Loading...</div>
|
|
638
|
+
* <div *ngIf="state.error$ | async as error">{{ error }}</div>
|
|
639
|
+
*
|
|
640
|
+
* <div *ngFor="let user of state.records$ | async">
|
|
641
|
+
* {{ user.name }}
|
|
642
|
+
* </div>
|
|
643
|
+
*
|
|
644
|
+
* <div *ngIf="state.pager$ | async as pager">
|
|
645
|
+
* Page {{ pager.currentPage }} of {{ pager.lastPage }}
|
|
646
|
+
* </div>
|
|
183
647
|
*/
|
|
184
648
|
declare class BaseStateService<TRecord, TFilter extends Partial<TRecord> & Filter = Partial<TRecord> & Filter> {
|
|
185
649
|
private readonly filterSubject;
|
|
@@ -188,17 +652,35 @@ declare class BaseStateService<TRecord, TFilter extends Partial<TRecord> & Filte
|
|
|
188
652
|
private readonly selectedSubject;
|
|
189
653
|
private readonly loadingMapSubject;
|
|
190
654
|
private readonly errorSubject;
|
|
191
|
-
/**
|
|
655
|
+
/**
|
|
656
|
+
* Observable stream of current filter.
|
|
657
|
+
* Optimized with distinctUntilChanged to prevent duplicate emissions.
|
|
658
|
+
*/
|
|
192
659
|
filter$: Observable<TFilter>;
|
|
193
|
-
/**
|
|
660
|
+
/**
|
|
661
|
+
* Observable stream of current records.
|
|
662
|
+
* Optimized with distinctUntilChanged for reference equality.
|
|
663
|
+
*/
|
|
194
664
|
records$: Observable<TRecord[]>;
|
|
195
|
-
/**
|
|
665
|
+
/**
|
|
666
|
+
* Observable stream of current pager metadata.
|
|
667
|
+
* Optimized with distinctUntilChanged for deep equality.
|
|
668
|
+
*/
|
|
196
669
|
pager$: Observable<IMultiresultMetaData | null>;
|
|
197
|
-
/**
|
|
670
|
+
/**
|
|
671
|
+
* Observable stream of the currently selected record.
|
|
672
|
+
* Optimized with distinctUntilChanged for reference equality.
|
|
673
|
+
*/
|
|
198
674
|
selected$: Observable<TRecord | null>;
|
|
199
|
-
/**
|
|
675
|
+
/**
|
|
676
|
+
* Observable stream of loading state.
|
|
677
|
+
* Optimized with distinctUntilChanged for deep equality.
|
|
678
|
+
*/
|
|
200
679
|
loading$: Observable<Record<string, boolean>>;
|
|
201
|
-
/**
|
|
680
|
+
/**
|
|
681
|
+
* Observable stream of current error message.
|
|
682
|
+
* Optimized with distinctUntilChanged for value equality.
|
|
683
|
+
*/
|
|
202
684
|
error$: Observable<string | null>;
|
|
203
685
|
/** Returns the current filter. */
|
|
204
686
|
get currentFilter(): TFilter;
|
|
@@ -232,10 +714,25 @@ declare class BaseStateService<TRecord, TFilter extends Partial<TRecord> & Filte
|
|
|
232
714
|
*/
|
|
233
715
|
setApiResponse(response: IMultiresult<TRecord>): void;
|
|
234
716
|
/**
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
717
|
+
* Updates the sort order in the current filter.
|
|
718
|
+
* Toggles order if column already exists and no explicit sort is provided, or adds it otherwise.
|
|
719
|
+
*
|
|
720
|
+
* @param column Column name to sort by
|
|
721
|
+
* @param sort Optional sort order. If not provided and column exists, toggles between ASC/DESC.
|
|
722
|
+
* If not provided and column doesn't exist, defaults to ASC.
|
|
723
|
+
*
|
|
724
|
+
* @example
|
|
725
|
+
* // Add new sort (defaults to ASC)
|
|
726
|
+
* state.setSort('name');
|
|
727
|
+
*
|
|
728
|
+
* @example
|
|
729
|
+
* // Toggle existing sort
|
|
730
|
+
* state.setSort('name'); // If already ASC, becomes DESC; if DESC, becomes ASC
|
|
731
|
+
*
|
|
732
|
+
* @example
|
|
733
|
+
* // Explicitly set sort order
|
|
734
|
+
* state.setSort('name', 'DESC'); // Always sets to DESC
|
|
735
|
+
*/
|
|
239
736
|
setSort(column: string, sort?: "ASC" | "DESC"): void;
|
|
240
737
|
/**
|
|
241
738
|
* Removes a specific column from the current sort.
|
|
@@ -252,6 +749,10 @@ declare class BaseStateService<TRecord, TFilter extends Partial<TRecord> & Filte
|
|
|
252
749
|
*
|
|
253
750
|
* @param key A unique key representing the loading context (e.g., "list", "detail")
|
|
254
751
|
* @returns Observable emitting `true` if the given context is loading, `false` otherwise.
|
|
752
|
+
*
|
|
753
|
+
* @remarks
|
|
754
|
+
* Optimized with distinctUntilChanged to prevent duplicate emissions
|
|
755
|
+
* and shareReplay to share subscriptions.
|
|
255
756
|
*/
|
|
256
757
|
isLoading$(key: string): Observable<boolean>;
|
|
257
758
|
/**
|
|
@@ -329,19 +830,331 @@ declare class BaseStateService<TRecord, TFilter extends Partial<TRecord> & Filte
|
|
|
329
830
|
destroySubscriptions(subjects?: Array<'filterSubject' | 'recordsSubject' | 'pagerSubject' | 'selectedSubject' | 'loadingMapSubject' | 'errorSubject'>): void;
|
|
330
831
|
}
|
|
331
832
|
|
|
833
|
+
/**
|
|
834
|
+
* Abstract base service providing standard CRUD operations for REST APIs.
|
|
835
|
+
*
|
|
836
|
+
* @template T The full model type representing your entity
|
|
837
|
+
* @template TFilter Filter type extending Partial<T> & Filter for query parameters
|
|
838
|
+
* @template TCreate DTO type for creating new records (defaults to Partial<T>)
|
|
839
|
+
* @template TUpdate DTO type for updating records (defaults to Partial<T>)
|
|
840
|
+
*
|
|
841
|
+
* @remarks
|
|
842
|
+
* Extend this class in your feature services to get type-safe CRUD operations
|
|
843
|
+
* with minimal boilerplate. The service automatically handles:
|
|
844
|
+
* - Query string generation from filters
|
|
845
|
+
* - Pagination and sorting
|
|
846
|
+
* - Standardized response/error handling
|
|
847
|
+
* - Type safety throughout the request/response cycle
|
|
848
|
+
*
|
|
849
|
+
* @example
|
|
850
|
+
* // Define your model
|
|
851
|
+
* interface User {
|
|
852
|
+
* id: number;
|
|
853
|
+
* name: string;
|
|
854
|
+
* email: string;
|
|
855
|
+
* role: string;
|
|
856
|
+
* }
|
|
857
|
+
*
|
|
858
|
+
* // Define custom filter
|
|
859
|
+
* interface UserFilter extends Filter {
|
|
860
|
+
* role?: string;
|
|
861
|
+
* isActive?: boolean;
|
|
862
|
+
* }
|
|
863
|
+
*
|
|
864
|
+
* // Create service
|
|
865
|
+
* @Injectable({ providedIn: 'root' })
|
|
866
|
+
* export class UserService extends BaseService<User, UserFilter> {
|
|
867
|
+
* constructor(http: HttpClient) {
|
|
868
|
+
* super(http, '/api/users');
|
|
869
|
+
* }
|
|
870
|
+
*
|
|
871
|
+
* // Add custom methods
|
|
872
|
+
* activateUser(id: number): Observable<IResponse<User>> {
|
|
873
|
+
* return this.http.post<IResponse<User>>(`${this.baseUrl}/${id}/activate`, {});
|
|
874
|
+
* }
|
|
875
|
+
* }
|
|
876
|
+
*
|
|
877
|
+
* @example
|
|
878
|
+
* // With separate DTOs for create/update
|
|
879
|
+
* interface CreateUserDto {
|
|
880
|
+
* name: string;
|
|
881
|
+
* email: string;
|
|
882
|
+
* password: string;
|
|
883
|
+
* }
|
|
884
|
+
*
|
|
885
|
+
* interface UpdateUserDto {
|
|
886
|
+
* name?: string;
|
|
887
|
+
* email?: string;
|
|
888
|
+
* // Note: password excluded
|
|
889
|
+
* }
|
|
890
|
+
*
|
|
891
|
+
* @Injectable({ providedIn: 'root' })
|
|
892
|
+
* export class UserService extends BaseService<
|
|
893
|
+
* User,
|
|
894
|
+
* UserFilter,
|
|
895
|
+
* CreateUserDto,
|
|
896
|
+
* UpdateUserDto
|
|
897
|
+
* > {
|
|
898
|
+
* constructor(http: HttpClient) {
|
|
899
|
+
* super(http, '/api/users');
|
|
900
|
+
* }
|
|
901
|
+
* }
|
|
902
|
+
*/
|
|
332
903
|
declare abstract class BaseService<T, // Full model type
|
|
333
904
|
TFilter extends Partial<T> & Filter = Partial<T> & Filter, // Filter: model fields + pagination/sorting
|
|
334
905
|
TCreate = Partial<T>, // DTO for create
|
|
335
906
|
TUpdate = Partial<T>> {
|
|
336
907
|
protected http: HttpClient;
|
|
337
908
|
protected baseUrl: string;
|
|
909
|
+
/**
|
|
910
|
+
* Creates an instance of BaseService.
|
|
911
|
+
*
|
|
912
|
+
* @param http Angular HttpClient for making HTTP requests
|
|
913
|
+
* @param baseUrl Base URL for the resource API endpoint (e.g., '/api/users')
|
|
914
|
+
*/
|
|
338
915
|
constructor(http: HttpClient, baseUrl: string);
|
|
916
|
+
/**
|
|
917
|
+
* Fetches a paginated list of records with optional filtering and sorting.
|
|
918
|
+
*
|
|
919
|
+
* @param filter Optional filter object containing pagination, sorting, and search criteria
|
|
920
|
+
* @returns Observable of response containing records array and pagination metadata
|
|
921
|
+
*
|
|
922
|
+
* @example
|
|
923
|
+
* // Basic usage
|
|
924
|
+
* userService.getAll().subscribe(response => {
|
|
925
|
+
* console.log(response.data?.records);
|
|
926
|
+
* console.log(response.data?.pager.totalRecords);
|
|
927
|
+
* });
|
|
928
|
+
*
|
|
929
|
+
* @example
|
|
930
|
+
* // With filters
|
|
931
|
+
* userService.getAll({
|
|
932
|
+
* page: 2,
|
|
933
|
+
* pageLength: 25,
|
|
934
|
+
* search: 'john',
|
|
935
|
+
* role: 'admin',
|
|
936
|
+
* sort: [new SortItem('name', 'ASC')]
|
|
937
|
+
* }).subscribe(response => {
|
|
938
|
+
* // Handle response
|
|
939
|
+
* });
|
|
940
|
+
*/
|
|
339
941
|
getAll(filter?: TFilter): Observable<IResponse<IMultiresult<T>>>;
|
|
942
|
+
/**
|
|
943
|
+
* Fetches a single record by its ID.
|
|
944
|
+
*
|
|
945
|
+
* @param id The unique identifier of the record
|
|
946
|
+
* @returns Observable of response containing the single record
|
|
947
|
+
*
|
|
948
|
+
* @example
|
|
949
|
+
* userService.getDetails(123).subscribe(response => {
|
|
950
|
+
* if (response.data) {
|
|
951
|
+
* console.log('User:', response.data);
|
|
952
|
+
* }
|
|
953
|
+
* });
|
|
954
|
+
*/
|
|
340
955
|
getDetails(id: number): Observable<IResponse<T>>;
|
|
956
|
+
/**
|
|
957
|
+
* Creates a new record.
|
|
958
|
+
*
|
|
959
|
+
* @param data Data transfer object containing fields for the new record
|
|
960
|
+
* @returns Observable of response containing the created record (usually with generated ID)
|
|
961
|
+
*
|
|
962
|
+
* @example
|
|
963
|
+
* userService.create({
|
|
964
|
+
* name: 'John Doe',
|
|
965
|
+
* email: 'john@example.com',
|
|
966
|
+
* password: 'secure123'
|
|
967
|
+
* }).subscribe(response => {
|
|
968
|
+
* if (response.data) {
|
|
969
|
+
* console.log('Created user:', response.data);
|
|
970
|
+
* }
|
|
971
|
+
* });
|
|
972
|
+
*/
|
|
341
973
|
create(data: TCreate): Observable<IResponse<T>>;
|
|
974
|
+
/**
|
|
975
|
+
* Updates an existing record.
|
|
976
|
+
*
|
|
977
|
+
* @param id The unique identifier of the record to update
|
|
978
|
+
* @param data Data transfer object containing fields to update (partial update supported)
|
|
979
|
+
* @returns Observable of response containing the updated record
|
|
980
|
+
*
|
|
981
|
+
* @example
|
|
982
|
+
* userService.update(123, {
|
|
983
|
+
* name: 'Jane Doe',
|
|
984
|
+
* email: 'jane@example.com'
|
|
985
|
+
* }).subscribe(response => {
|
|
986
|
+
* if (response.data) {
|
|
987
|
+
* console.log('Updated user:', response.data);
|
|
988
|
+
* }
|
|
989
|
+
* });
|
|
990
|
+
*/
|
|
342
991
|
update(id: number, data: TUpdate): Observable<IResponse<T>>;
|
|
343
|
-
|
|
992
|
+
/**
|
|
993
|
+
* Deletes a record (soft or hard delete).
|
|
994
|
+
*
|
|
995
|
+
* @param id The unique identifier of the record to delete
|
|
996
|
+
* @param method Deletion method: 'soft' (mark as deleted, reversible) or 'hard' (permanent removal)
|
|
997
|
+
* @returns Observable of response confirming deletion
|
|
998
|
+
*
|
|
999
|
+
* @remarks
|
|
1000
|
+
* - Soft delete: Record is marked as deleted but can be restored later
|
|
1001
|
+
* - Hard delete: Record is permanently removed from the database
|
|
1002
|
+
* - Default is 'soft' for safety
|
|
1003
|
+
*
|
|
1004
|
+
* @example
|
|
1005
|
+
* // Soft delete (default)
|
|
1006
|
+
* userService.delete(123).subscribe(() => {
|
|
1007
|
+
* console.log('User soft deleted');
|
|
1008
|
+
* });
|
|
1009
|
+
*
|
|
1010
|
+
* @example
|
|
1011
|
+
* // Hard delete (permanent)
|
|
1012
|
+
* userService.delete(123, 'hard').subscribe(() => {
|
|
1013
|
+
* console.log('User permanently deleted');
|
|
1014
|
+
* });
|
|
1015
|
+
*/
|
|
1016
|
+
delete(id: number, method?: 'soft' | 'hard'): Observable<IResponse<unknown>>;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
/**
|
|
1020
|
+
* Configuration options for the ApiErrorHandler.
|
|
1021
|
+
*/
|
|
1022
|
+
interface ApiErrorHandlerConfig {
|
|
1023
|
+
/** Whether to log errors to console (default: true in dev, false in prod) */
|
|
1024
|
+
logErrors?: boolean;
|
|
1025
|
+
/** Custom error message transformer */
|
|
1026
|
+
errorMessageTransformer?: (error: HttpErrorResponse) => string;
|
|
1027
|
+
/** Callback to be called when an error occurs */
|
|
1028
|
+
onError?: (error: ProcessedError) => void;
|
|
1029
|
+
}
|
|
1030
|
+
/**
|
|
1031
|
+
* Processed error information with additional context.
|
|
1032
|
+
*/
|
|
1033
|
+
interface ProcessedError {
|
|
1034
|
+
/** HTTP status code */
|
|
1035
|
+
status: number;
|
|
1036
|
+
/** User-friendly error message */
|
|
1037
|
+
message: string;
|
|
1038
|
+
/** Technical error details */
|
|
1039
|
+
details?: string;
|
|
1040
|
+
/** Error code from API */
|
|
1041
|
+
code?: string;
|
|
1042
|
+
/** Original HTTP error response */
|
|
1043
|
+
originalError: HttpErrorResponse;
|
|
1044
|
+
/** Whether this error should be shown to user */
|
|
1045
|
+
showToUser: boolean;
|
|
1046
|
+
/** Error type classification */
|
|
1047
|
+
type: 'network' | 'client' | 'server' | 'unknown';
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Service for handling and processing API errors consistently.
|
|
1051
|
+
*
|
|
1052
|
+
* @example
|
|
1053
|
+
* // Basic usage in a service
|
|
1054
|
+
* constructor(private errorHandler: ApiErrorHandler) {}
|
|
1055
|
+
*
|
|
1056
|
+
* loadData() {
|
|
1057
|
+
* this.http.get('/api/data').subscribe({
|
|
1058
|
+
* error: (err: HttpErrorResponse) => {
|
|
1059
|
+
* const processed = this.errorHandler.handleError(err);
|
|
1060
|
+
* this.showErrorToUser(processed.message);
|
|
1061
|
+
* }
|
|
1062
|
+
* });
|
|
1063
|
+
* }
|
|
1064
|
+
*
|
|
1065
|
+
* @example
|
|
1066
|
+
* // Configure globally
|
|
1067
|
+
* providers: [
|
|
1068
|
+
* {
|
|
1069
|
+
* provide: ApiErrorHandler,
|
|
1070
|
+
* useFactory: () => {
|
|
1071
|
+
* const handler = new ApiErrorHandler();
|
|
1072
|
+
* handler.configure({
|
|
1073
|
+
* logErrors: true,
|
|
1074
|
+
* onError: (error) => {
|
|
1075
|
+
* // Send to logging service
|
|
1076
|
+
* loggingService.logError(error);
|
|
1077
|
+
* }
|
|
1078
|
+
* });
|
|
1079
|
+
* return handler;
|
|
1080
|
+
* }
|
|
1081
|
+
* }
|
|
1082
|
+
* ]
|
|
1083
|
+
*/
|
|
1084
|
+
declare class ApiErrorHandler {
|
|
1085
|
+
private config;
|
|
1086
|
+
/**
|
|
1087
|
+
* Configure the error handler.
|
|
1088
|
+
*
|
|
1089
|
+
* @param config Configuration options
|
|
1090
|
+
*/
|
|
1091
|
+
configure(config: ApiErrorHandlerConfig): void;
|
|
1092
|
+
/**
|
|
1093
|
+
* Process an HTTP error and return structured error information.
|
|
1094
|
+
*
|
|
1095
|
+
* @param error The HTTP error response
|
|
1096
|
+
* @returns Processed error with user-friendly message and metadata
|
|
1097
|
+
*/
|
|
1098
|
+
handleError(error: HttpErrorResponse): ProcessedError;
|
|
1099
|
+
/**
|
|
1100
|
+
* Extract error message from various error formats.
|
|
1101
|
+
*
|
|
1102
|
+
* @param error The HTTP error response
|
|
1103
|
+
* @returns User-friendly error message
|
|
1104
|
+
*/
|
|
1105
|
+
extractErrorMessage(error: HttpErrorResponse): string;
|
|
1106
|
+
/**
|
|
1107
|
+
* Get default error message based on HTTP status code.
|
|
1108
|
+
*
|
|
1109
|
+
* @param status HTTP status code
|
|
1110
|
+
* @returns Default error message
|
|
1111
|
+
*/
|
|
1112
|
+
private getDefaultMessageForStatus;
|
|
1113
|
+
/**
|
|
1114
|
+
* Classify error type based on status code.
|
|
1115
|
+
*
|
|
1116
|
+
* @param status HTTP status code
|
|
1117
|
+
* @returns Error type classification
|
|
1118
|
+
*/
|
|
1119
|
+
private getErrorType;
|
|
1120
|
+
/**
|
|
1121
|
+
* Determine if error should be shown to user.
|
|
1122
|
+
*
|
|
1123
|
+
* @param error HTTP error response
|
|
1124
|
+
* @returns Whether to show error to user
|
|
1125
|
+
*/
|
|
1126
|
+
private shouldShowToUser;
|
|
1127
|
+
/**
|
|
1128
|
+
* Process the error into a structured format.
|
|
1129
|
+
*
|
|
1130
|
+
* @param error HTTP error response
|
|
1131
|
+
* @returns Processed error object
|
|
1132
|
+
*/
|
|
1133
|
+
private processError;
|
|
1134
|
+
/**
|
|
1135
|
+
* Log error to console (in dev mode).
|
|
1136
|
+
*
|
|
1137
|
+
* @param error Processed error
|
|
1138
|
+
*/
|
|
1139
|
+
private logError;
|
|
1140
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ApiErrorHandler, never>;
|
|
1141
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ApiErrorHandler>;
|
|
344
1142
|
}
|
|
345
1143
|
|
|
346
|
-
|
|
347
|
-
|
|
1144
|
+
/**
|
|
1145
|
+
* HTTP Interceptor that catches errors and processes them through the ApiErrorHandler.
|
|
1146
|
+
*
|
|
1147
|
+
* @example
|
|
1148
|
+
* // In your app.config.ts or main provider:
|
|
1149
|
+
* export const appConfig: ApplicationConfig = {
|
|
1150
|
+
* providers: [
|
|
1151
|
+
* provideHttpClient(
|
|
1152
|
+
* withInterceptors([apiErrorInterceptor])
|
|
1153
|
+
* )
|
|
1154
|
+
* ]
|
|
1155
|
+
* };
|
|
1156
|
+
*/
|
|
1157
|
+
declare const apiErrorInterceptor: HttpInterceptorFn;
|
|
1158
|
+
|
|
1159
|
+
export { API_CORE_CONFIG, ApiCore, ApiErrorHandler, BaseResourceConfig, BaseService, BaseStateService, DEFAULT_API_CORE_CONFIG, Filter, SELECT_MODE, SortItem, apiErrorInterceptor, generatePermissions, isEmpty, jsonToQueryString, mergeConfig, sortObjectToString };
|
|
1160
|
+
export type { ApiCoreConfig, ApiErrorHandlerConfig, IMisError, IMultiresult, IMultiresultMetaData, IResponse, PagedResponse, ProcessedError, SingleResponse, StandardPermission, TableColumn };
|