@asor-studio/asor-core 1.0.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/LICENSE +18 -0
- package/README.md +43 -0
- package/fesm2022/asor-studio-asor-core.mjs +1 -0
- package/index.d.ts +2428 -0
- package/package.json +35 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,2428 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { OnInit, OnDestroy, QueryList, Type, PipeTransform } from '@angular/core';
|
|
3
|
+
import { ActivatedRoute, CanActivate, Data, Router, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, RedirectCommand } from '@angular/router';
|
|
4
|
+
import { Location } from '@angular/common';
|
|
5
|
+
import { Observable, BehaviorSubject, ReplaySubject } from 'rxjs';
|
|
6
|
+
import { HttpParams, HttpHeaders, HttpResponse, HttpRequest, HttpErrorResponse, HttpStatusCode, HttpInterceptor, HttpHandler, HttpEvent } from '@angular/common/http';
|
|
7
|
+
import * as _asor_studio_asor_core from '@asor-studio/asor-core';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Base configuration class for the asor-core library.
|
|
11
|
+
* This class can be extended in consuming applications to add custom routes, URLs, and configurations
|
|
12
|
+
* while preserving all base properties from the library.
|
|
13
|
+
*
|
|
14
|
+
* The class uses a pattern where base properties are protected and merged with extended properties
|
|
15
|
+
* through public getters, ensuring that child class extensions don't overwrite base configurations.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // In your application, extend ConfigConst
|
|
19
|
+
* export class AppConfig extends ConfigConst {
|
|
20
|
+
* // Override base values
|
|
21
|
+
* static override BaseApi = '/api/v2';
|
|
22
|
+
* static override SiteBaseUrl = 'https://myapp.com';
|
|
23
|
+
*
|
|
24
|
+
* // Extend Route with new routes (base routes are preserved)
|
|
25
|
+
* protected static override _routeExtensions = {
|
|
26
|
+
* HOME: 'home',
|
|
27
|
+
* DASHBOARD: 'dashboard',
|
|
28
|
+
* PROFILE: 'profile'
|
|
29
|
+
* };
|
|
30
|
+
*
|
|
31
|
+
* // Extend Url with new URLs (base URLs are preserved)
|
|
32
|
+
* protected static override _urlExtensions = {
|
|
33
|
+
* HOME: AppConfig.SiteBaseUrl.concat('/home'),
|
|
34
|
+
* DASHBOARD: AppConfig.SiteBaseUrl.concat('/dashboard')
|
|
35
|
+
* };
|
|
36
|
+
*
|
|
37
|
+
* // Extend AuthCheck with new checks (base checks are preserved)
|
|
38
|
+
* protected static override _authCheckExtensions = {
|
|
39
|
+
* ADMIN_ACCESS: 'admin-access',
|
|
40
|
+
* VIEW_REPORTS: 'view-reports'
|
|
41
|
+
* };
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* // Usage anywhere in your app - use AppConfig instead of ConfigConst
|
|
45
|
+
* import { AppConfig } from './config/app.config';
|
|
46
|
+
*/
|
|
47
|
+
declare abstract class ConfigConst {
|
|
48
|
+
/** Base API URL for all HTTP requests */
|
|
49
|
+
static BaseApi: string;
|
|
50
|
+
/** Base URL for the site/application */
|
|
51
|
+
static SiteBaseUrl: string;
|
|
52
|
+
/** Base URL for static assets */
|
|
53
|
+
static SiteAssetsUrl: string;
|
|
54
|
+
/**
|
|
55
|
+
* Base route identifiers.
|
|
56
|
+
* In child classes, add custom routes via _routeExtensions.
|
|
57
|
+
* @protected
|
|
58
|
+
*/
|
|
59
|
+
protected static _routeBase: {
|
|
60
|
+
NONE: string;
|
|
61
|
+
PAGE_UNAUTHORIZED: string;
|
|
62
|
+
LOGIN: string;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Extension point for custom routes in child classes.
|
|
66
|
+
* Override this in your extended class to add new routes.
|
|
67
|
+
* @protected
|
|
68
|
+
*/
|
|
69
|
+
protected static _routeExtensions: Record<string, string>;
|
|
70
|
+
/**
|
|
71
|
+
* Merged Route object containing both base and extended routes.
|
|
72
|
+
* Accessing this getter returns all routes from the base class and any extensions.
|
|
73
|
+
*/
|
|
74
|
+
static get Route(): {
|
|
75
|
+
NONE: string;
|
|
76
|
+
PAGE_UNAUTHORIZED: string;
|
|
77
|
+
LOGIN: string;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Base URL paths.
|
|
81
|
+
* In child classes, add custom URLs via _urlExtensions.
|
|
82
|
+
* @protected
|
|
83
|
+
*/
|
|
84
|
+
protected static _urlBase: {
|
|
85
|
+
readonly UNAUTHORIZED: string;
|
|
86
|
+
readonly LOGIN: string;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Extension point for custom URLs in child classes.
|
|
90
|
+
* Override this in your extended class to add new URLs.
|
|
91
|
+
* @protected
|
|
92
|
+
*/
|
|
93
|
+
protected static _urlExtensions: Record<string, string>;
|
|
94
|
+
/**
|
|
95
|
+
* Merged Url object containing both base and extended URLs.
|
|
96
|
+
* Accessing this getter returns all URLs from the base class and any extensions.
|
|
97
|
+
*/
|
|
98
|
+
static get Url(): {
|
|
99
|
+
UNAUTHORIZED: string;
|
|
100
|
+
LOGIN: string;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Base translation URL configuration.
|
|
104
|
+
* In child classes, add custom translation configs via _translationUrlExtensions.
|
|
105
|
+
* @protected
|
|
106
|
+
*/
|
|
107
|
+
protected static _translationUrlBase: {
|
|
108
|
+
DefaultLanguage: string;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Extension point for custom translation URL configs in child classes.
|
|
112
|
+
* Override this in your extended class to add new translation configurations.
|
|
113
|
+
* @protected
|
|
114
|
+
*/
|
|
115
|
+
protected static _translationUrlExtensions: Record<string, any>;
|
|
116
|
+
/**
|
|
117
|
+
* Merged TranslationUrl object containing both base and extended translation configs.
|
|
118
|
+
* Accessing this getter returns all configs from the base class and any extensions.
|
|
119
|
+
*/
|
|
120
|
+
static get TranslationUrl(): {
|
|
121
|
+
DefaultLanguage: string;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Base authorization check identifiers.
|
|
125
|
+
* In child classes, add custom auth checks via _authCheckExtensions.
|
|
126
|
+
* @protected
|
|
127
|
+
*/
|
|
128
|
+
protected static _authCheckBase: {
|
|
129
|
+
PAGE_UNAUTHORIZED: string;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Extension point for custom authorization checks in child classes.
|
|
133
|
+
* Override this in your extended class to add new authorization checks.
|
|
134
|
+
* @protected
|
|
135
|
+
*/
|
|
136
|
+
protected static _authCheckExtensions: Record<string, string>;
|
|
137
|
+
/**
|
|
138
|
+
* Merged AuthCheck object containing both base and extended authorization checks.
|
|
139
|
+
* Accessing this getter returns all checks from the base class and any extensions.
|
|
140
|
+
*/
|
|
141
|
+
static get AuthCheck(): {
|
|
142
|
+
PAGE_UNAUTHORIZED: string;
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Base cache identifiers.
|
|
146
|
+
* In child classes, add custom cache keys via _cacheExtensions.
|
|
147
|
+
* @protected
|
|
148
|
+
*/
|
|
149
|
+
protected static _cacheBase: {
|
|
150
|
+
NONE: string;
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Extension point for custom cache identifiers in child classes.
|
|
154
|
+
* Override this in your extended class to add new cache keys.
|
|
155
|
+
* @protected
|
|
156
|
+
*/
|
|
157
|
+
protected static _cacheExtensions: Record<string, string>;
|
|
158
|
+
/**
|
|
159
|
+
* Merged Cache object containing both base and extended cache identifiers.
|
|
160
|
+
* Accessing this getter returns all cache keys from the base class and any extensions.
|
|
161
|
+
*/
|
|
162
|
+
static get Cache(): {
|
|
163
|
+
NONE: string;
|
|
164
|
+
};
|
|
165
|
+
static SetConfiguration(config: any): void;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Base abstract class for Molecule components following the Atomic Design pattern.
|
|
170
|
+
* Molecules are composite components made up of smaller atomic elements.
|
|
171
|
+
* Automatically extracts molecule configuration from route data and sets up i18n paths.
|
|
172
|
+
*
|
|
173
|
+
* This class provides foundational functionality for all molecule-level components,
|
|
174
|
+
* including access to route data, current molecule configuration, and translation paths.
|
|
175
|
+
*
|
|
176
|
+
* @Directive - Can be extended by Angular components
|
|
177
|
+
* @abstract - Must be extended, cannot be instantiated directly
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* // Create a molecule component
|
|
181
|
+
* @Component({
|
|
182
|
+
* selector: 'app-user-card',
|
|
183
|
+
* templateUrl: './user-card.component.html'
|
|
184
|
+
* })
|
|
185
|
+
* export class UserCardComponent extends BaseMolecule implements OnInit {
|
|
186
|
+
* ngOnInit() {
|
|
187
|
+
* // Access molecule configuration
|
|
188
|
+
* console.log(this.currentMolecule.I18nPath);
|
|
189
|
+
* // Use inherited i18n paths
|
|
190
|
+
* console.log(this.I18nPath);
|
|
191
|
+
* }
|
|
192
|
+
* }
|
|
193
|
+
*/
|
|
194
|
+
declare abstract class BaseMolecule implements IComp {
|
|
195
|
+
static readonly className: string;
|
|
196
|
+
/**
|
|
197
|
+
* Injected ActivatedRoute for accessing route data and parameters.
|
|
198
|
+
*/
|
|
199
|
+
protected route: ActivatedRoute;
|
|
200
|
+
/**
|
|
201
|
+
* Configuration object for the current molecule component.
|
|
202
|
+
* Contains metadata like component name, i18n paths, and other molecule-specific settings.
|
|
203
|
+
*/
|
|
204
|
+
protected currentMolecule: IMolecule;
|
|
205
|
+
/**
|
|
206
|
+
* Array of i18n translation paths for this molecule.
|
|
207
|
+
* Inherited from the molecule configuration in route data.
|
|
208
|
+
* Used by translation utilities to load appropriate language files.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* // I18nPath might contain: ['/common', '/user-module']
|
|
212
|
+
* this.translateUtility.getTranslation$('SAVE_BUTTON', this.I18nPath, 'en');
|
|
213
|
+
*/
|
|
214
|
+
I18nPath: string[];
|
|
215
|
+
/**
|
|
216
|
+
* Initializes the base molecule by extracting configuration from route data.
|
|
217
|
+
* Automatically finds the matching molecule configuration based on component class name
|
|
218
|
+
* and sets up i18n translation paths.
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* // Route configuration with molecule data:
|
|
222
|
+
* {
|
|
223
|
+
* path: 'users',
|
|
224
|
+
* component: UserListComponent,
|
|
225
|
+
* data: {
|
|
226
|
+
* Molecules: [
|
|
227
|
+
* {
|
|
228
|
+
* Component: UserListComponent,
|
|
229
|
+
* I18nPath: ['/common', '/users']
|
|
230
|
+
* }
|
|
231
|
+
* ]
|
|
232
|
+
* } as IAsorRoute
|
|
233
|
+
* }
|
|
234
|
+
*/
|
|
235
|
+
constructor();
|
|
236
|
+
/**
|
|
237
|
+
* Lifecycle hook called when the component view is about to enter.
|
|
238
|
+
* Must be implemented by derived classes to define component-specific initialization logic.
|
|
239
|
+
*
|
|
240
|
+
* @throws Error if not implemented by the extending class
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* export class MyMolecule extends BaseMolecule {
|
|
244
|
+
* baseCompViewWillEnter(): void {
|
|
245
|
+
* console.log('Component is entering view');
|
|
246
|
+
* this.loadData();
|
|
247
|
+
* }
|
|
248
|
+
* }
|
|
249
|
+
*/
|
|
250
|
+
baseCompViewEnter(): void;
|
|
251
|
+
/**
|
|
252
|
+
* Lifecycle hook called when the component view is about to leave.
|
|
253
|
+
* Must be implemented by derived classes to define component-specific cleanup logic.
|
|
254
|
+
*
|
|
255
|
+
* @throws Error if not implemented by the extending class
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* export class MyMolecule extends BaseMolecule {
|
|
259
|
+
* baseCompViewWillLeave(): void {
|
|
260
|
+
* console.log('Component is leaving view');
|
|
261
|
+
* this.cleanup();
|
|
262
|
+
* }
|
|
263
|
+
* }
|
|
264
|
+
*/
|
|
265
|
+
baseCompViewLeave(): void;
|
|
266
|
+
/**
|
|
267
|
+
* Returns the name of the current component class.
|
|
268
|
+
* Used internally to match the component with its configuration in route data.
|
|
269
|
+
*
|
|
270
|
+
* @returns The class name of the component as a string
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* // For class UserCardComponent extends BaseMolecule
|
|
274
|
+
* console.log(this.getClassName()); // Outputs: "UserCardComponent"
|
|
275
|
+
*/
|
|
276
|
+
getClassName(): string;
|
|
277
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BaseMolecule, never>;
|
|
278
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<BaseMolecule, never, never, {}, {}, never, never, true, never>;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Enum representing all standard HTTP request methods.
|
|
283
|
+
* Used for configuring HTTP requests in the application.
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* // Use in HTTP request configuration
|
|
287
|
+
* const request = {
|
|
288
|
+
* method: IHttpMethod.POST,
|
|
289
|
+
* url: '/api/users',
|
|
290
|
+
* body: userData
|
|
291
|
+
* };
|
|
292
|
+
*/
|
|
293
|
+
declare enum IHttpMethod {
|
|
294
|
+
/** Retrieve data from the server without modifying it */
|
|
295
|
+
GET = "GET",
|
|
296
|
+
/** Submit data to create a new resource on the server */
|
|
297
|
+
POST = "POST",
|
|
298
|
+
/** Update or replace an existing resource completely */
|
|
299
|
+
PUT = "PUT",
|
|
300
|
+
/** Remove a resource from the server */
|
|
301
|
+
DELETE = "DELETE",
|
|
302
|
+
/** Partially update an existing resource */
|
|
303
|
+
PATCH = "PATCH",
|
|
304
|
+
/** Retrieve headers only, without the response body */
|
|
305
|
+
HEAD = "HEAD",
|
|
306
|
+
/** Describe the communication options for the target resource */
|
|
307
|
+
OPTIONS = "OPTIONS",
|
|
308
|
+
/** Establish a tunnel to the server (typically for SSL/TLS) */
|
|
309
|
+
CONNECT = "CONNECT",
|
|
310
|
+
/** Perform a message loop-back test along the path to the target resource */
|
|
311
|
+
TRACE = "TRACE"
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Enum representing standard HTTP status codes.
|
|
315
|
+
* Organized by category: 1xx (Informational), 2xx (Success), 3xx (Redirection), 4xx (Client Error), 5xx (Server Error).
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* // Check status code in error handler
|
|
319
|
+
* if (error.status === IHttpStatusCode.Unauthorized) {
|
|
320
|
+
* this.router.navigate(['/login']);
|
|
321
|
+
* } else if (error.status === IHttpStatusCode.NotFound) {
|
|
322
|
+
* this.showMessage('Resource not found');
|
|
323
|
+
* }
|
|
324
|
+
*/
|
|
325
|
+
declare enum IHttpStatusCode {
|
|
326
|
+
/** The server has received the request headers and the client should proceed to send the request body */
|
|
327
|
+
Continue = 100,
|
|
328
|
+
/** The server is switching protocols as requested by the client */
|
|
329
|
+
SwitchingProtocols = 101,
|
|
330
|
+
/** The server has received and is processing the request, but no response is available yet */
|
|
331
|
+
Processing = 102,
|
|
332
|
+
/** The request has succeeded */
|
|
333
|
+
OK = 200,
|
|
334
|
+
/** The request has been fulfilled and resulted in a new resource being created */
|
|
335
|
+
Created = 201,
|
|
336
|
+
/** The request has been accepted for processing, but processing has not been completed */
|
|
337
|
+
Accepted = 202,
|
|
338
|
+
/** The server successfully processed the request but is returning information from another source */
|
|
339
|
+
NonAuthoritativeInformation = 203,
|
|
340
|
+
/** The server successfully processed the request but is not returning any content */
|
|
341
|
+
NoContent = 204,
|
|
342
|
+
/** The server successfully processed the request and is instructing the client to reset the document view */
|
|
343
|
+
ResetContent = 205,
|
|
344
|
+
/** The server is delivering only part of the resource due to a range header sent by the client */
|
|
345
|
+
PartialContent = 206,
|
|
346
|
+
/** The requested resource has multiple choices, each with different locations */
|
|
347
|
+
MultipleChoices = 300,
|
|
348
|
+
/** The resource has been moved permanently to a new URI */
|
|
349
|
+
MovedPermanently = 301,
|
|
350
|
+
/** The resource resides temporarily under a different URI */
|
|
351
|
+
Found = 302,
|
|
352
|
+
/** The response to the request can be found under a different URI using GET */
|
|
353
|
+
SeeOther = 303,
|
|
354
|
+
/** The resource has not been modified since the last request */
|
|
355
|
+
NotModified = 304,
|
|
356
|
+
/** The requested resource must be accessed through the proxy given by the Location field */
|
|
357
|
+
UseProxy = 305,
|
|
358
|
+
/** The resource resides temporarily under a different URI (same as 302) */
|
|
359
|
+
TemporaryRedirect = 307,
|
|
360
|
+
/** The resource has been permanently moved to another URI */
|
|
361
|
+
PermanentRedirect = 308,
|
|
362
|
+
/** The server cannot process the request due to client error (malformed syntax, invalid parameters, etc.) */
|
|
363
|
+
BadRequest = 400,
|
|
364
|
+
/** Authentication is required and has failed or has not been provided */
|
|
365
|
+
Unauthorized = 401,
|
|
366
|
+
/** Reserved for future use (payment required) */
|
|
367
|
+
PaymentRequired = 402,
|
|
368
|
+
/** The client does not have access rights to the content */
|
|
369
|
+
Forbidden = 403,
|
|
370
|
+
/** The server cannot find the requested resource */
|
|
371
|
+
NotFound = 404,
|
|
372
|
+
/** The request method is not supported for the requested resource */
|
|
373
|
+
MethodNotAllowed = 405,
|
|
374
|
+
/** The requested resource is not available in a format acceptable to the client */
|
|
375
|
+
NotAcceptable = 406,
|
|
376
|
+
/** The client must first authenticate itself with the proxy */
|
|
377
|
+
ProxyAuthenticationRequired = 407,
|
|
378
|
+
/** The server timed out waiting for the request */
|
|
379
|
+
RequestTimeout = 408,
|
|
380
|
+
/** The request could not be completed due to a conflict with the current state of the resource */
|
|
381
|
+
Conflict = 409,
|
|
382
|
+
/** The requested resource is no longer available and will not be available again */
|
|
383
|
+
Gone = 410,
|
|
384
|
+
/** The request did not specify the length of its content (Content-Length header) */
|
|
385
|
+
LengthRequired = 411,
|
|
386
|
+
/** One or more conditions in the request header fields evaluated to false */
|
|
387
|
+
PreconditionFailed = 412,
|
|
388
|
+
/** The request entity is larger than limits defined by server */
|
|
389
|
+
PayloadTooLarge = 413,
|
|
390
|
+
/** The URI provided was too long for the server to process */
|
|
391
|
+
URITooLong = 414,
|
|
392
|
+
/** The request entity has a media type which the server does not support */
|
|
393
|
+
UnsupportedMediaType = 415,
|
|
394
|
+
/** The client has asked for a portion of the file, but the server cannot supply that portion */
|
|
395
|
+
RangeNotSatisfiable = 416,
|
|
396
|
+
/** The expectation given in the Expect request header could not be met */
|
|
397
|
+
ExpectationFailed = 417,
|
|
398
|
+
/** The request was well-formed but was unable to be followed due to semantic errors */
|
|
399
|
+
UnprocessableEntity = 422,
|
|
400
|
+
/** The resource that is being accessed is locked */
|
|
401
|
+
Locked = 423,
|
|
402
|
+
/** The request failed due to failure of a previous request */
|
|
403
|
+
FailedDependency = 424,
|
|
404
|
+
/** The client should switch to a different protocol */
|
|
405
|
+
UpgradeRequired = 426,
|
|
406
|
+
/** The origin server requires the request to be conditional */
|
|
407
|
+
PreconditionRequired = 428,
|
|
408
|
+
/** The user has sent too many requests in a given amount of time */
|
|
409
|
+
TooManyRequests = 429,
|
|
410
|
+
/** The server is unwilling to process the request because header fields are too large */
|
|
411
|
+
RequestHeaderFieldsTooLarge = 431,
|
|
412
|
+
/** The server cannot legally provide the requested resource */
|
|
413
|
+
UnavailableForLegalReasons = 451,
|
|
414
|
+
/** A generic error message when the server encounters an unexpected condition */
|
|
415
|
+
InternalServerError = 500,
|
|
416
|
+
/** The server does not support the functionality required to fulfill the request */
|
|
417
|
+
NotImplemented = 501,
|
|
418
|
+
/** The server received an invalid response from an upstream server */
|
|
419
|
+
BadGateway = 502,
|
|
420
|
+
/** The server is currently unavailable (overloaded or down for maintenance) */
|
|
421
|
+
ServiceUnavailable = 503,
|
|
422
|
+
/** The server did not receive a timely response from an upstream server */
|
|
423
|
+
GatewayTimeout = 504,
|
|
424
|
+
/** The server does not support the HTTP protocol version used in the request */
|
|
425
|
+
HTTPVersionNotSupported = 505,
|
|
426
|
+
/** The server has an internal configuration error */
|
|
427
|
+
VariantAlsoNegotiates = 506,
|
|
428
|
+
/** The server is unable to store the representation needed to complete the request */
|
|
429
|
+
InsufficientStorage = 507,
|
|
430
|
+
/** The server detected an infinite loop while processing the request */
|
|
431
|
+
LoopDetected = 508,
|
|
432
|
+
/** Further extensions to the request are required for the server to fulfill it */
|
|
433
|
+
NotExtended = 510,
|
|
434
|
+
/** The client needs to authenticate to gain network access */
|
|
435
|
+
NetworkAuthenticationRequired = 511
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Enum representing the possible authorization statuses returned by the authentication API.
|
|
439
|
+
* Used to determine if a user is authorized to perform specific actions.
|
|
440
|
+
*
|
|
441
|
+
* @example
|
|
442
|
+
* // Check authorization status
|
|
443
|
+
* if (authResponse.authorized === AuthStatus.Ok) {
|
|
444
|
+
* // User is authorized
|
|
445
|
+
* this.performAction();
|
|
446
|
+
* } else if (authResponse.authorized === AuthStatus.NotAllow) {
|
|
447
|
+
* // User is not allowed
|
|
448
|
+
* this.showErrorMessage('Access denied');
|
|
449
|
+
* }
|
|
450
|
+
*/
|
|
451
|
+
declare enum AuthStatus {
|
|
452
|
+
/** Authorization successful - user is allowed to proceed */
|
|
453
|
+
Ok = "ok",
|
|
454
|
+
/** Authorization requires retry - temporary issue */
|
|
455
|
+
Retray = "re",
|
|
456
|
+
/** Authorization denied - user does not have permission */
|
|
457
|
+
NotAllow = "na",
|
|
458
|
+
/** Authorization expired - user session has expired */
|
|
459
|
+
Expired = "ex"
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
type GlobalEnum_d_AuthStatus = AuthStatus;
|
|
463
|
+
declare const GlobalEnum_d_AuthStatus: typeof AuthStatus;
|
|
464
|
+
type GlobalEnum_d_IHttpMethod = IHttpMethod;
|
|
465
|
+
declare const GlobalEnum_d_IHttpMethod: typeof IHttpMethod;
|
|
466
|
+
type GlobalEnum_d_IHttpStatusCode = IHttpStatusCode;
|
|
467
|
+
declare const GlobalEnum_d_IHttpStatusCode: typeof IHttpStatusCode;
|
|
468
|
+
declare namespace GlobalEnum_d {
|
|
469
|
+
export {
|
|
470
|
+
GlobalEnum_d_AuthStatus as AuthStatus,
|
|
471
|
+
GlobalEnum_d_IHttpMethod as IHttpMethod,
|
|
472
|
+
GlobalEnum_d_IHttpStatusCode as IHttpStatusCode,
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Constants for State Handler configuration
|
|
478
|
+
*/
|
|
479
|
+
declare class StateConst {
|
|
480
|
+
static readonly EncryptType: {
|
|
481
|
+
readonly AES: "AES";
|
|
482
|
+
};
|
|
483
|
+
static readonly Generate: {
|
|
484
|
+
readonly AUTO: "AUTO";
|
|
485
|
+
readonly CUSTOM: "CUSTOM";
|
|
486
|
+
};
|
|
487
|
+
static readonly StoreType: {
|
|
488
|
+
readonly VOLATILE: "VOLATILE";
|
|
489
|
+
readonly SESSION: "SESSION";
|
|
490
|
+
readonly LOCAL: "LOCAL";
|
|
491
|
+
};
|
|
492
|
+
static readonly Data: {
|
|
493
|
+
readonly REPLACE: "REPLACE";
|
|
494
|
+
readonly MERGE: "MERGE";
|
|
495
|
+
};
|
|
496
|
+
static readonly Cookie: {
|
|
497
|
+
readonly STATE: "STATE";
|
|
498
|
+
readonly KEY: "KEY";
|
|
499
|
+
readonly KEY_EXPIRE: 365;
|
|
500
|
+
};
|
|
501
|
+
static readonly CMPLX12 = 12;
|
|
502
|
+
static readonly CMPLX6 = 6;
|
|
503
|
+
}
|
|
504
|
+
type EncryptType = typeof StateConst.EncryptType[keyof typeof StateConst.EncryptType];
|
|
505
|
+
type GenerateType = typeof StateConst.Generate[keyof typeof StateConst.Generate];
|
|
506
|
+
type StoreType = typeof StateConst.StoreType[keyof typeof StateConst.StoreType];
|
|
507
|
+
type DataMethod = typeof StateConst.Data[keyof typeof StateConst.Data];
|
|
508
|
+
|
|
509
|
+
type StateConstants_d_DataMethod = DataMethod;
|
|
510
|
+
type StateConstants_d_EncryptType = EncryptType;
|
|
511
|
+
type StateConstants_d_GenerateType = GenerateType;
|
|
512
|
+
type StateConstants_d_StateConst = StateConst;
|
|
513
|
+
declare const StateConstants_d_StateConst: typeof StateConst;
|
|
514
|
+
type StateConstants_d_StoreType = StoreType;
|
|
515
|
+
declare namespace StateConstants_d {
|
|
516
|
+
export { StateConstants_d_StateConst as StateConst };
|
|
517
|
+
export type { StateConstants_d_DataMethod as DataMethod, StateConstants_d_EncryptType as EncryptType, StateConstants_d_GenerateType as GenerateType, StateConstants_d_StoreType as StoreType };
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Configuration for StateHandler initialization
|
|
522
|
+
*/
|
|
523
|
+
interface StateHandlerConfig {
|
|
524
|
+
encryptionType?: EncryptType;
|
|
525
|
+
nameType?: GenerateType;
|
|
526
|
+
keyType?: GenerateType;
|
|
527
|
+
callBackStateName?: () => string;
|
|
528
|
+
callBackStateKey?: () => string;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Options for creating a dataset
|
|
532
|
+
*/
|
|
533
|
+
interface CreateDataSetOption {
|
|
534
|
+
encrypt?: boolean;
|
|
535
|
+
storeType?: StoreType;
|
|
536
|
+
freeze?: boolean;
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Options for updating a dataset
|
|
540
|
+
*/
|
|
541
|
+
interface UpdateDataSetOption {
|
|
542
|
+
method?: DataMethod;
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Internal data element structure
|
|
546
|
+
*/
|
|
547
|
+
interface DataElement {
|
|
548
|
+
name: string;
|
|
549
|
+
encrypt: boolean;
|
|
550
|
+
storeType: StoreType;
|
|
551
|
+
freeze: boolean;
|
|
552
|
+
data: any;
|
|
553
|
+
lastUpdate: number;
|
|
554
|
+
readCount: number;
|
|
555
|
+
writeCount: number;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Registry entry structure for component registrations
|
|
559
|
+
*/
|
|
560
|
+
interface RegistryEntry<T = any> {
|
|
561
|
+
propsIsUpdated: (props: T) => void;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Base abstract class for Page/Component-level components following the Atomic Design pattern.
|
|
566
|
+
* Components (Pages) are the highest level in the hierarchy, composed of molecules and atoms.
|
|
567
|
+
* Provides automatic lifecycle management, route data extraction, and i18n path configuration.
|
|
568
|
+
* Compatible with both standard Angular and Ionic frameworks.
|
|
569
|
+
*
|
|
570
|
+
* This class handles:
|
|
571
|
+
* - Automatic extraction of configuration from route data
|
|
572
|
+
* - Lifecycle hooks for both Angular (ngOnInit/ngOnDestroy) and Ionic (ionViewWillEnter/ionViewWillLeave)
|
|
573
|
+
* - MenuBar molecule integration and lifecycle propagation
|
|
574
|
+
* - Translation path management
|
|
575
|
+
*
|
|
576
|
+
* @Directive - Can be extended by Angular components
|
|
577
|
+
* @abstract - Must be extended, cannot be instantiated directly
|
|
578
|
+
*
|
|
579
|
+
* @example
|
|
580
|
+
* // Create a page component
|
|
581
|
+
* @Component({
|
|
582
|
+
* selector: 'app-user-list-page',
|
|
583
|
+
* templateUrl: './user-list-page.component.html'
|
|
584
|
+
* })
|
|
585
|
+
* export class UserListPageComponent extends BaseComponent {
|
|
586
|
+
* // Component automatically inherits i18n paths and lifecycle management
|
|
587
|
+
* // Custom logic can be added by overriding baseCompViewWillEnter/Leave
|
|
588
|
+
* }
|
|
589
|
+
*/
|
|
590
|
+
declare abstract class BaseComponent implements IComp, OnInit, OnDestroy {
|
|
591
|
+
static readonly className: string;
|
|
592
|
+
/**
|
|
593
|
+
* Optional reference to a menuBar molecule component.
|
|
594
|
+
* When present, the menuBar's lifecycle hooks are automatically called
|
|
595
|
+
* during this component's lifecycle events.
|
|
596
|
+
*
|
|
597
|
+
* @example
|
|
598
|
+
* // In template:
|
|
599
|
+
* // <app-menu-bar #ChildRef></app-menu-bar>
|
|
600
|
+
*/
|
|
601
|
+
ChildrenRef: QueryList<BaseMolecule> | undefined;
|
|
602
|
+
/**
|
|
603
|
+
* Injected ActivatedRoute for accessing route data and parameters.
|
|
604
|
+
*/
|
|
605
|
+
private route;
|
|
606
|
+
/**
|
|
607
|
+
* Array of i18n translation paths for this component.
|
|
608
|
+
* Inherited from route configuration data.
|
|
609
|
+
* Used by translation utilities to load appropriate language files.
|
|
610
|
+
*
|
|
611
|
+
* @example
|
|
612
|
+
* // Access in component:
|
|
613
|
+
* this.translateUtility.getTranslation$('TITLE', this.I18nPath, 'en');
|
|
614
|
+
*/
|
|
615
|
+
I18nPath: string[];
|
|
616
|
+
/**
|
|
617
|
+
* Initializes the base component by extracting configuration from route data.
|
|
618
|
+
* Automatically sets up i18n translation paths and previous component URL.
|
|
619
|
+
*
|
|
620
|
+
* @example
|
|
621
|
+
* // Route configuration:
|
|
622
|
+
* {
|
|
623
|
+
* path: 'users',
|
|
624
|
+
* component: UserListComponent,
|
|
625
|
+
* data: {
|
|
626
|
+
* I18nPath: ['/common', '/users'],
|
|
627
|
+
* FromComponentURL: '/dashboard'
|
|
628
|
+
* } as IAsorRoute
|
|
629
|
+
* }
|
|
630
|
+
*/
|
|
631
|
+
constructor();
|
|
632
|
+
/**
|
|
633
|
+
* Angular lifecycle hook called when the component is initialized.
|
|
634
|
+
* Automatically calls baseCompViewWillEnter() to trigger component-specific initialization.
|
|
635
|
+
*/
|
|
636
|
+
ngOnInit(): void;
|
|
637
|
+
/**
|
|
638
|
+
* Angular lifecycle hook called when the component is about to be destroyed.
|
|
639
|
+
* Automatically calls baseCompViewWillLeave() to trigger component-specific cleanup.
|
|
640
|
+
*/
|
|
641
|
+
ngOnDestroy(): void;
|
|
642
|
+
/**
|
|
643
|
+
* Ionic lifecycle hook called when the view is about to enter and become the active view.
|
|
644
|
+
* This is called regardless of whether it is the first load or cached view.
|
|
645
|
+
* Delegates to baseCompViewWillEnter() for consistency across Angular and Ionic.
|
|
646
|
+
*/
|
|
647
|
+
ionViewWillEnter(): void;
|
|
648
|
+
/**
|
|
649
|
+
* Ionic lifecycle hook called when the view is about to leave and no longer be the active view.
|
|
650
|
+
* This is called when navigating away from the current view.
|
|
651
|
+
* Delegates to baseCompViewWillLeave() for consistency across Angular and Ionic.
|
|
652
|
+
*/
|
|
653
|
+
ionViewWillLeave(): void;
|
|
654
|
+
/**
|
|
655
|
+
* Called when the component view is about to enter/initialize.
|
|
656
|
+
* Automatically propagates the lifecycle event to the menuBar molecule if present.
|
|
657
|
+
* Can be overridden by derived classes to add custom initialization logic.
|
|
658
|
+
*
|
|
659
|
+
* @example
|
|
660
|
+
* export class MyComponent extends BaseComponent {
|
|
661
|
+
* override baseCompViewWillEnter(): void {
|
|
662
|
+
* super.baseCompViewWillEnter(); // Call parent to handle menuBar
|
|
663
|
+
* console.log('Component entering view');
|
|
664
|
+
* this.loadData();
|
|
665
|
+
* }
|
|
666
|
+
* }
|
|
667
|
+
*/
|
|
668
|
+
baseCompViewEnter(): void;
|
|
669
|
+
/**
|
|
670
|
+
* Called when the component view is about to leave/destroy.
|
|
671
|
+
* Automatically propagates the lifecycle event to the menuBar molecule if present.
|
|
672
|
+
* Can be overridden by derived classes to add custom cleanup logic.
|
|
673
|
+
*
|
|
674
|
+
* @example
|
|
675
|
+
* export class MyComponent extends BaseComponent {
|
|
676
|
+
* override baseCompViewWillLeave(): void {
|
|
677
|
+
* super.baseCompViewWillLeave(); // Call parent to handle menuBar
|
|
678
|
+
* console.log('Component leaving view');
|
|
679
|
+
* this.cleanup();
|
|
680
|
+
* }
|
|
681
|
+
* }
|
|
682
|
+
*/
|
|
683
|
+
baseCompViewLeave(): void;
|
|
684
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BaseComponent, never>;
|
|
685
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<BaseComponent, never, never, {}, {}, never, never, true, never>;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Interface for route guard configuration with authentication and molecule support.
|
|
690
|
+
* Used in route data configuration to define page-level authentication, child guards, and molecule components.
|
|
691
|
+
*
|
|
692
|
+
* @example
|
|
693
|
+
* // Route configuration
|
|
694
|
+
* {
|
|
695
|
+
* path: 'users',
|
|
696
|
+
* component: UserListComponent,
|
|
697
|
+
* canActivate: [AuthGuard],
|
|
698
|
+
* data: {
|
|
699
|
+
* AuthCheck: 'view-users',
|
|
700
|
+
* I18nPath: ['/common', '/users'],
|
|
701
|
+
* FromComponentURL: '/dashboard',
|
|
702
|
+
* Molecules: [
|
|
703
|
+
* {
|
|
704
|
+
* Component: UserMenuBarComponent,
|
|
705
|
+
* I18nPath: ['/common', '/users']
|
|
706
|
+
* }
|
|
707
|
+
* ]
|
|
708
|
+
* } as IAsorRoute
|
|
709
|
+
* }
|
|
710
|
+
*/
|
|
711
|
+
interface IAsorRoute {
|
|
712
|
+
/** Optional child guard for nested route protection */
|
|
713
|
+
ChildGuard?: Type<CanActivate>;
|
|
714
|
+
/** Authorization key to check against the backend (e.g., 'view-users', 'admin-access') */
|
|
715
|
+
AuthCheck?: string;
|
|
716
|
+
/** Array of i18n translation paths for this route */
|
|
717
|
+
I18nPath: string[];
|
|
718
|
+
/** Array of molecule components to be used in this route */
|
|
719
|
+
Molecules?: IMolecule[];
|
|
720
|
+
/** Array of component to be used in this route */
|
|
721
|
+
Components?: IComponent[];
|
|
722
|
+
/** Optional dataset creation configuration */
|
|
723
|
+
CreateDataSet?: ICreateDataSet;
|
|
724
|
+
/** Optional state handler configuration */
|
|
725
|
+
ConnectDataSet?: IConnectDataSet;
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Interface for state handler configuration.
|
|
729
|
+
* Used in route data to automatically connect datasets when the route is loaded.
|
|
730
|
+
*
|
|
731
|
+
* @example
|
|
732
|
+
* ConnectDataSet: {
|
|
733
|
+
* selectors: {
|
|
734
|
+
* title: 'title',
|
|
735
|
+
* complex: 'complex'
|
|
736
|
+
* }
|
|
737
|
+
* }
|
|
738
|
+
*/
|
|
739
|
+
interface IConnectDataSet {
|
|
740
|
+
/** Name of the dataset to connect */
|
|
741
|
+
name: string;
|
|
742
|
+
/** Selector for the dataset to connect */
|
|
743
|
+
selectors: {
|
|
744
|
+
[key: string]: string;
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Interface for dataset creation configuration.
|
|
749
|
+
* Used in route data to automatically create datasets when the route is loaded.
|
|
750
|
+
*
|
|
751
|
+
* @example
|
|
752
|
+
* CreateDataSet: {
|
|
753
|
+
* name: 'userProfile',
|
|
754
|
+
* data: { name: '', email: '' },
|
|
755
|
+
* option: { storeType: StateConst.StoreType.SESSION }
|
|
756
|
+
* }
|
|
757
|
+
*/
|
|
758
|
+
interface ICreateDataSet {
|
|
759
|
+
/** Name of the dataset to create */
|
|
760
|
+
name: string;
|
|
761
|
+
/** Initial data for the dataset */
|
|
762
|
+
data: any;
|
|
763
|
+
/** Optional creation options (encryption, storage type, etc.) */
|
|
764
|
+
option?: CreateDataSetOption;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Interface representing a Molecule component in the Atomic Design pattern.
|
|
768
|
+
* Molecules are composite UI components made up of smaller atoms.
|
|
769
|
+
*
|
|
770
|
+
* @example
|
|
771
|
+
* const userMenuMolecule: IMolecule = {
|
|
772
|
+
* Molecule: UserMenuBarComponent,
|
|
773
|
+
* I18nPath: ['/common', '/user-menu'],
|
|
774
|
+
* ExtraData: { showProfile: true }
|
|
775
|
+
* };
|
|
776
|
+
*/
|
|
777
|
+
interface IMolecule {
|
|
778
|
+
/** Array of i18n translation paths for this molecule */
|
|
779
|
+
I18nPath: string[];
|
|
780
|
+
/** Optional state handler configuration */
|
|
781
|
+
ConnectDataSet?: IConnectDataSet;
|
|
782
|
+
/** The Angular component class extending BaseMolecule */
|
|
783
|
+
Molecule: Type<BaseMolecule> & ICompStatic;
|
|
784
|
+
/** Optional extra data to pass to the molecule component */
|
|
785
|
+
ExtraData?: Data;
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Interface representing a Component in the Atomic Design pattern.
|
|
789
|
+
* Components are the smallest UI components.
|
|
790
|
+
*
|
|
791
|
+
* @example
|
|
792
|
+
* const userMenuComponent: IComponent = {
|
|
793
|
+
* Component: UserMenuBarComponent,
|
|
794
|
+
* I18nPath: ['/common', '/user-menu'],
|
|
795
|
+
* ExtraData: { showProfile: true }
|
|
796
|
+
* };
|
|
797
|
+
*/
|
|
798
|
+
interface IComponent {
|
|
799
|
+
/** Array of i18n translation paths for this component */
|
|
800
|
+
I18nPath: string[];
|
|
801
|
+
/** Optional state handler configuration */
|
|
802
|
+
ConnectDataSet?: IConnectDataSet;
|
|
803
|
+
/** The Angular component class extending BaseComponent */
|
|
804
|
+
Component: Type<BaseComponent> & ICompStatic;
|
|
805
|
+
/** Optional extra data to pass to the component */
|
|
806
|
+
ExtraData?: Data;
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* Interface defining the contract for components with lifecycle hooks and i18n support.
|
|
810
|
+
* Implemented by BaseComponent and BaseMolecule classes.
|
|
811
|
+
*
|
|
812
|
+
* @example
|
|
813
|
+
* export class MyComponent implements IComp {
|
|
814
|
+
* I18nPath: string[] = ['/common', '/my-module'];
|
|
815
|
+
*
|
|
816
|
+
* baseCompViewWillEnter(): void {
|
|
817
|
+
* console.log('Component entering view');
|
|
818
|
+
* this.loadData();
|
|
819
|
+
* }
|
|
820
|
+
*
|
|
821
|
+
* baseCompViewWillLeave(): void {
|
|
822
|
+
* console.log('Component leaving view');
|
|
823
|
+
* this.cleanup();
|
|
824
|
+
* }
|
|
825
|
+
* }
|
|
826
|
+
*/
|
|
827
|
+
/**
|
|
828
|
+
* Static interface to enforce `className` on the class constructor (static side).
|
|
829
|
+
* Used in `IComponent` and `IMolecule` to ensure all classes declare a static `className`.
|
|
830
|
+
*/
|
|
831
|
+
interface ICompStatic {
|
|
832
|
+
readonly className: string;
|
|
833
|
+
}
|
|
834
|
+
interface IComp {
|
|
835
|
+
/** Array of i18n translation paths for this component */
|
|
836
|
+
I18nPath: string[];
|
|
837
|
+
/** Called when the component view is about to enter/initialize */
|
|
838
|
+
baseCompViewEnter(): void;
|
|
839
|
+
/** Called when the component view is about to leave/destroy */
|
|
840
|
+
baseCompViewLeave(): void;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Interface for authorization response from the backend API.
|
|
844
|
+
* Contains the authorization status indicating if the user is allowed to perform an action.
|
|
845
|
+
*
|
|
846
|
+
* @example
|
|
847
|
+
* const authResponse: IAuth = {
|
|
848
|
+
* authorized: AuthStatus.Ok
|
|
849
|
+
* };
|
|
850
|
+
*
|
|
851
|
+
* if (authResponse.authorized === AuthStatus.Ok) {
|
|
852
|
+
* // User is authorized
|
|
853
|
+
* } else if (authResponse.authorized === AuthStatus.NotAllow) {
|
|
854
|
+
* // Access denied
|
|
855
|
+
* }
|
|
856
|
+
*/
|
|
857
|
+
interface IAuth {
|
|
858
|
+
/** Authorization status (Ok, Retray, or NotAllow) */
|
|
859
|
+
authorized: AuthStatus;
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Interface for cache path configuration.
|
|
863
|
+
* Defines how HTTP requests to specific URL paths should be cached.
|
|
864
|
+
*
|
|
865
|
+
* @example
|
|
866
|
+
* const userCachePath: IPath = {
|
|
867
|
+
* pathValue: '/api/users',
|
|
868
|
+
* isPersistent: true, // Cache survives page refresh
|
|
869
|
+
* reqPayloadCache: false, // Don't include request body in cache key
|
|
870
|
+
* resctrictRoute: '/dashboard', // Only cache when on dashboard route
|
|
871
|
+
* clearOn: ['/api/users/create', '/api/users/update'] // Clear cache on these paths
|
|
872
|
+
* };
|
|
873
|
+
*/
|
|
874
|
+
interface IPath {
|
|
875
|
+
/** If true, cache persists in sessionStorage across page refreshes */
|
|
876
|
+
isPersistent: boolean;
|
|
877
|
+
/** If true, includes request payload in cache key (useful for POST/PUT requests) */
|
|
878
|
+
reqPayloadCache: boolean;
|
|
879
|
+
/** Route restriction - cache only applies when user is on this route (ConfigConst.Route.NONE for no restriction) */
|
|
880
|
+
resctrictRoute: string;
|
|
881
|
+
/** The URL path pattern to match (e.g., '/api/users', '/api/products') */
|
|
882
|
+
pathValue: string;
|
|
883
|
+
/** Array of URL paths that should clear this cache when accessed */
|
|
884
|
+
clearOn: string[];
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Interface for configuring the HTTP request handler.
|
|
888
|
+
* Used to initialize HttpRequestHandler with the base API URL.
|
|
889
|
+
*
|
|
890
|
+
* @example
|
|
891
|
+
* const config: IHttpRequestHandlerConfig = {
|
|
892
|
+
* baseApiUrl: 'https://api.example.com'
|
|
893
|
+
* };
|
|
894
|
+
*
|
|
895
|
+
* const handler = new HttpRequestHandler(config);
|
|
896
|
+
*/
|
|
897
|
+
interface IHttpRequestHandlerConfig {
|
|
898
|
+
/** Base URL for all API requests (e.g., 'https://api.example.com', '/api') */
|
|
899
|
+
baseApiUrl: string;
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* Interface for form validation errors returned by the backend.
|
|
903
|
+
* Maps form field names to their error messages.
|
|
904
|
+
*
|
|
905
|
+
* @example
|
|
906
|
+
* const formErrors: IHttpFormError = {
|
|
907
|
+
* email: 'Email is required',
|
|
908
|
+
* password: 'Password must be at least 8 characters',
|
|
909
|
+
* username: 'Username already taken'
|
|
910
|
+
* };
|
|
911
|
+
*
|
|
912
|
+
* // Access errors
|
|
913
|
+
* console.log(formErrors['email']); // 'Email is required'
|
|
914
|
+
*/
|
|
915
|
+
interface IHttpFormError {
|
|
916
|
+
/** Form field name mapped to error message */
|
|
917
|
+
[key: string | symbol]: string;
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* Interface for HTTP error responses from the backend.
|
|
921
|
+
* Contains error key and optional form validation errors.
|
|
922
|
+
*
|
|
923
|
+
* @example
|
|
924
|
+
* const errorResponse: IHttpResponseError = {
|
|
925
|
+
* key: 'VALIDATION_ERROR',
|
|
926
|
+
* form: {
|
|
927
|
+
* email: 'Invalid email format',
|
|
928
|
+
* password: 'Password is required'
|
|
929
|
+
* }
|
|
930
|
+
* };
|
|
931
|
+
*
|
|
932
|
+
* @example
|
|
933
|
+
* // Generic error without form details
|
|
934
|
+
* const genericError: IHttpResponseError = {
|
|
935
|
+
* key: 'SERVER_ERROR'
|
|
936
|
+
* };
|
|
937
|
+
*/
|
|
938
|
+
interface IHttpResponseError {
|
|
939
|
+
/** Error key/code identifying the type of error */
|
|
940
|
+
key: string;
|
|
941
|
+
/** Optional form validation errors mapping field names to error messages */
|
|
942
|
+
form?: IHttpFormError;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
/**
|
|
946
|
+
* Base cache path configuration class for the asor-core library.
|
|
947
|
+
* This class can be extended in consuming applications to add custom cache path configurations
|
|
948
|
+
* while preserving all base cache paths from the library.
|
|
949
|
+
*
|
|
950
|
+
* The class uses a pattern where base paths are protected and merged with extended paths
|
|
951
|
+
* through a public getter, ensuring that child class extensions don't overwrite base cache configurations.
|
|
952
|
+
*
|
|
953
|
+
* @example
|
|
954
|
+
* // In your application, extend ConfigCache
|
|
955
|
+
* export class AppCacheConfig extends ConfigCache {
|
|
956
|
+
* // Add custom cache paths (base paths are preserved)
|
|
957
|
+
* protected static override _pathsExtensions: IPath[] = [
|
|
958
|
+
* {
|
|
959
|
+
* isPersistent: true,
|
|
960
|
+
* reqPayloadCache: false,
|
|
961
|
+
* resctrictRoute: AppConfig.Route.NONE,
|
|
962
|
+
* pathValue: '/api/users',
|
|
963
|
+
* clearOn: ['/api/users/create', '/api/users/update']
|
|
964
|
+
* },
|
|
965
|
+
* {
|
|
966
|
+
* isPersistent: false,
|
|
967
|
+
* reqPayloadCache: true,
|
|
968
|
+
* resctrictRoute: AppConfig.Route.DASHBOARD,
|
|
969
|
+
* pathValue: '/api/dashboard/stats',
|
|
970
|
+
* clearOn: []
|
|
971
|
+
* },
|
|
972
|
+
* {
|
|
973
|
+
* isPersistent: true,
|
|
974
|
+
* reqPayloadCache: false,
|
|
975
|
+
* resctrictRoute: AppConfig.Route.NONE,
|
|
976
|
+
* pathValue: AppConfig.Cache.USER_PROFILE,
|
|
977
|
+
* clearOn: ['/api/users/logout']
|
|
978
|
+
* }
|
|
979
|
+
* ];
|
|
980
|
+
* }
|
|
981
|
+
*
|
|
982
|
+
* // Usage in CachePathUtility
|
|
983
|
+
* import { AppCacheConfig } from './config/app-cache.config';
|
|
984
|
+
*
|
|
985
|
+
* const cachePathUtility = new CachePathUtility();
|
|
986
|
+
* cachePathUtility.config(AppCacheConfig.Paths);
|
|
987
|
+
*
|
|
988
|
+
* // Now you have both base cache paths (I18N_COMPONENT, I18N_MOLECULE)
|
|
989
|
+
* // AND your custom cache paths (/api/users, /api/dashboard/stats, etc.)
|
|
990
|
+
*/
|
|
991
|
+
declare abstract class ConfigCache {
|
|
992
|
+
/**
|
|
993
|
+
* Base cache path configurations from the library.
|
|
994
|
+
* These define caching behavior for i18n components and molecules.
|
|
995
|
+
* In child classes, add custom cache paths via _pathsExtensions.
|
|
996
|
+
* @protected
|
|
997
|
+
*/
|
|
998
|
+
protected static _pathsBase: IPath[];
|
|
999
|
+
/**
|
|
1000
|
+
* Extension point for custom cache paths in child classes.
|
|
1001
|
+
* Override this in your extended class to add new cache path configurations.
|
|
1002
|
+
* @protected
|
|
1003
|
+
*
|
|
1004
|
+
* @example
|
|
1005
|
+
* protected static override _pathsExtensions: IPath[] = [
|
|
1006
|
+
* {
|
|
1007
|
+
* isPersistent: true,
|
|
1008
|
+
* reqPayloadCache: false,
|
|
1009
|
+
* resctrictRoute: ConfigConst.Route.NONE,
|
|
1010
|
+
* pathValue: '/api/custom-endpoint',
|
|
1011
|
+
* clearOn: []
|
|
1012
|
+
* }
|
|
1013
|
+
* ];
|
|
1014
|
+
*/
|
|
1015
|
+
protected static _pathsExtensions: IPath[];
|
|
1016
|
+
/**
|
|
1017
|
+
* Merged Paths array containing both base and extended cache path configurations.
|
|
1018
|
+
* Accessing this getter returns all cache paths from the base class and any extensions.
|
|
1019
|
+
*
|
|
1020
|
+
* @example
|
|
1021
|
+
* // Get all cache paths
|
|
1022
|
+
* const allPaths = ConfigCache.Paths;
|
|
1023
|
+
*
|
|
1024
|
+
* // Use with CachePathUtility
|
|
1025
|
+
* cachePathUtility.config(ConfigCache.Paths);
|
|
1026
|
+
*/
|
|
1027
|
+
static get Paths(): IPath[];
|
|
1028
|
+
static SetConfiguration(config: any): void;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* Livelli di log disponibili.
|
|
1033
|
+
* - ALL: tutti i livelli attivi
|
|
1034
|
+
* - INFO, DEBUG, WARNING, ERROR: singoli livelli
|
|
1035
|
+
*/
|
|
1036
|
+
type LogLevel = 'ALL' | 'INFO' | 'DEBUG' | 'WARNING' | 'ERROR';
|
|
1037
|
+
interface LogClassConfig {
|
|
1038
|
+
/** Nome della classe (deve corrispondere a constructor.name) */
|
|
1039
|
+
className: string;
|
|
1040
|
+
/** Livelli di log attivi per questa classe */
|
|
1041
|
+
levels: LogLevel[];
|
|
1042
|
+
}
|
|
1043
|
+
/**
|
|
1044
|
+
* Configurazione globale dei log.
|
|
1045
|
+
*
|
|
1046
|
+
* - `defaultLevels`: livelli attivi di default per tutte le classi non configurate esplicitamente.
|
|
1047
|
+
* - `classConfigs`: configurazione specifica per classe.
|
|
1048
|
+
*
|
|
1049
|
+
* @example
|
|
1050
|
+
* ```ts
|
|
1051
|
+
* ConsoleLogsConfig.classConfigs = [
|
|
1052
|
+
* { className: 'StateService', levels: ['ERROR', 'WARNING'] },
|
|
1053
|
+
* { className: 'AuthService', levels: ['ALL'] },
|
|
1054
|
+
* { className: 'CacheService', levels: ['INFO', 'ERROR'] },
|
|
1055
|
+
* ];
|
|
1056
|
+
* ```
|
|
1057
|
+
*/
|
|
1058
|
+
declare class ConsoleLogsConfig {
|
|
1059
|
+
/** Livelli attivi di default (se la classe non è configurata) */
|
|
1060
|
+
static defaultLevels: LogLevel[];
|
|
1061
|
+
/** Se true, i log non vengono stampati nella console del browser */
|
|
1062
|
+
static silent: boolean;
|
|
1063
|
+
/** Configurazione per singola classe */
|
|
1064
|
+
static classConfigs: LogClassConfig[];
|
|
1065
|
+
/**
|
|
1066
|
+
* Verifica se un livello di log è attivo per una determinata classe.
|
|
1067
|
+
*/
|
|
1068
|
+
static isLevelEnabled(className: string, level: LogLevel): boolean;
|
|
1069
|
+
/**
|
|
1070
|
+
* Imposta la configurazione per una classe specifica.
|
|
1071
|
+
*/
|
|
1072
|
+
static setClassLevels(className: string, levels: LogLevel[]): void;
|
|
1073
|
+
/**
|
|
1074
|
+
* Rimuove la configurazione specifica di una classe (tornerà ai default).
|
|
1075
|
+
*/
|
|
1076
|
+
static removeClassConfig(className: string): void;
|
|
1077
|
+
/**
|
|
1078
|
+
* Resetta tutta la configurazione ai valori di default.
|
|
1079
|
+
*/
|
|
1080
|
+
static reset(): void;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
/**
|
|
1084
|
+
* Utility class for managing routing and navigation in Angular applications.
|
|
1085
|
+
* Provides methods for navigation, parameter retrieval, and route checking.
|
|
1086
|
+
*
|
|
1087
|
+
* @Injectable - Provided in root, available application-wide
|
|
1088
|
+
*/
|
|
1089
|
+
declare class RoutingUtility {
|
|
1090
|
+
static readonly _name: string;
|
|
1091
|
+
protected route: ActivatedRoute;
|
|
1092
|
+
protected router: Router;
|
|
1093
|
+
protected location: Location;
|
|
1094
|
+
constructor();
|
|
1095
|
+
/**
|
|
1096
|
+
* Retrieves a query parameter value from the current route snapshot.
|
|
1097
|
+
*
|
|
1098
|
+
* @param key - The name of the query parameter to retrieve
|
|
1099
|
+
* @returns The value of the query parameter, or an empty string if not found
|
|
1100
|
+
*
|
|
1101
|
+
* @example
|
|
1102
|
+
* // URL: /page?userId=123
|
|
1103
|
+
* const userId = routingUtility.getNavParams('userId'); // Returns '123'
|
|
1104
|
+
*/
|
|
1105
|
+
getNavParams(key: string): string;
|
|
1106
|
+
/**
|
|
1107
|
+
* Retrieves a path parameter value from the current route snapshot.
|
|
1108
|
+
* Path parameters are defined in the route configuration (e.g., '/users/:id').
|
|
1109
|
+
*
|
|
1110
|
+
* @param key - The name of the path parameter to retrieve
|
|
1111
|
+
* @returns The value of the path parameter, or an empty string if not found
|
|
1112
|
+
*
|
|
1113
|
+
* @example
|
|
1114
|
+
* // Route config: { path: 'users/:userId', component: UserComponent }
|
|
1115
|
+
* // URL: /users/123
|
|
1116
|
+
* const userId = routingUtility.getPathParams('userId'); // Returns '123'
|
|
1117
|
+
*/
|
|
1118
|
+
getPathParams(key: string): string;
|
|
1119
|
+
/**
|
|
1120
|
+
* Checks if the current URL contains the specified route string.
|
|
1121
|
+
*
|
|
1122
|
+
* @param route - The route string to search for in the current URL
|
|
1123
|
+
* @returns True if the current URL contains the route string, false otherwise
|
|
1124
|
+
*
|
|
1125
|
+
* @example
|
|
1126
|
+
* // Current URL: /dashboard/settings
|
|
1127
|
+
* const isInDashboard = routingUtility.currentNavPass('dashboard'); // Returns true
|
|
1128
|
+
*/
|
|
1129
|
+
currentNavPass(route: string): boolean;
|
|
1130
|
+
/**
|
|
1131
|
+
* Navigates to the specified route with optional query parameters.
|
|
1132
|
+
* Constructs a full URL and removes the site base URL before navigation.
|
|
1133
|
+
*
|
|
1134
|
+
* @param route - The target route path
|
|
1135
|
+
* @param params - Optional object containing query parameters to append to the URL
|
|
1136
|
+
*
|
|
1137
|
+
* @example
|
|
1138
|
+
* routingUtility.navigate('/users', { page: 1, sort: 'name' });
|
|
1139
|
+
* // Navigates to: /users?page=1&sort=name
|
|
1140
|
+
*/
|
|
1141
|
+
navigate(route: string, params?: any): void;
|
|
1142
|
+
/**
|
|
1143
|
+
* Navigates to the specified route with both state object and query parameters.
|
|
1144
|
+
* The state object is accessible via router's navigation extras and doesn't appear in the URL.
|
|
1145
|
+
*
|
|
1146
|
+
* @param route - The target route path
|
|
1147
|
+
* @param obj - Optional state object to pass with the navigation (accessible via getStateParams)
|
|
1148
|
+
* @param params - Optional object containing query parameters to append to the URL
|
|
1149
|
+
*
|
|
1150
|
+
* @example
|
|
1151
|
+
* routingUtility.navigateWithStateObj('/details', { user: userData }, { id: 123 });
|
|
1152
|
+
* // Navigates to: /details?id=123 (with user data in state)
|
|
1153
|
+
*/
|
|
1154
|
+
navigateWithStateObj(route: string, obj?: any, params?: any): void;
|
|
1155
|
+
/**
|
|
1156
|
+
* Retrieves the state object from the current navigation.
|
|
1157
|
+
* This returns the state object passed during navigation via navigateWithStateObj.
|
|
1158
|
+
*
|
|
1159
|
+
* @returns The state object from the current location, or undefined if no state was passed
|
|
1160
|
+
*
|
|
1161
|
+
* @example
|
|
1162
|
+
* const stateData = routingUtility.getStateParams();
|
|
1163
|
+
* // Returns the state object passed during navigation
|
|
1164
|
+
*/
|
|
1165
|
+
getStateParams(): any;
|
|
1166
|
+
/**
|
|
1167
|
+
* Retrieves the base router instance.
|
|
1168
|
+
*
|
|
1169
|
+
* @returns The base router instance
|
|
1170
|
+
*/
|
|
1171
|
+
getBaseRouter(): Router;
|
|
1172
|
+
/**
|
|
1173
|
+
* Retrieves the base activated route instance.
|
|
1174
|
+
*
|
|
1175
|
+
* @returns The base activated route instance
|
|
1176
|
+
*/
|
|
1177
|
+
getBaseActivatedRoute(): ActivatedRoute;
|
|
1178
|
+
/**
|
|
1179
|
+
* Retrieves the base location instance.
|
|
1180
|
+
*
|
|
1181
|
+
* @returns The base location instance
|
|
1182
|
+
*/
|
|
1183
|
+
getBaseLocation(): Location;
|
|
1184
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RoutingUtility, never>;
|
|
1185
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<RoutingUtility>;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
/**
|
|
1189
|
+
* Handler class for making HTTP requests with a simplified callback-based API.
|
|
1190
|
+
* Provides a wrapper around Angular's HttpClient with automatic subscription management.
|
|
1191
|
+
* Supports GET, POST, PUT, and DELETE operations with both callback and Observable patterns.
|
|
1192
|
+
*
|
|
1193
|
+
* @example
|
|
1194
|
+
* // Initialize with base URL
|
|
1195
|
+
* const handler = new HttpRequestHandler({
|
|
1196
|
+
* baseApiUrl: 'https://api.example.com'
|
|
1197
|
+
* });
|
|
1198
|
+
*/
|
|
1199
|
+
declare class HttpRequestHandler {
|
|
1200
|
+
static readonly className = "HttpRequestHandler";
|
|
1201
|
+
/**
|
|
1202
|
+
* Base URL for all HTTP requests.
|
|
1203
|
+
* Set during construction from the configuration.
|
|
1204
|
+
*/
|
|
1205
|
+
private baseUrl;
|
|
1206
|
+
/**
|
|
1207
|
+
* Injected HttpClient instance for making HTTP requests.
|
|
1208
|
+
*/
|
|
1209
|
+
private http;
|
|
1210
|
+
/**
|
|
1211
|
+
* Creates a new HttpRequestHandler instance.
|
|
1212
|
+
* Validates configuration and sets up the base URL for all requests.
|
|
1213
|
+
*
|
|
1214
|
+
* @param config - Configuration object containing base API URL
|
|
1215
|
+
* @throws Error if configuration is missing
|
|
1216
|
+
*
|
|
1217
|
+
* @example
|
|
1218
|
+
* const handler = new HttpRequestHandler({
|
|
1219
|
+
* baseApiUrl: 'https://api.example.com/v1'
|
|
1220
|
+
* });
|
|
1221
|
+
*/
|
|
1222
|
+
constructor(config: IHttpRequestHandlerConfig);
|
|
1223
|
+
/**
|
|
1224
|
+
* Performs an HTTP GET request to retrieve data.
|
|
1225
|
+
*
|
|
1226
|
+
* @template T - Type of the expected response data
|
|
1227
|
+
* @param endpoint - API endpoint path (will be appended to baseUrl)
|
|
1228
|
+
* @param params - Optional HTTP query parameters
|
|
1229
|
+
* @returns IHttpRequest object with send() and obs() methods
|
|
1230
|
+
*
|
|
1231
|
+
* @example
|
|
1232
|
+
* // Simple GET request
|
|
1233
|
+
* handler.get<User[]>('users').send({
|
|
1234
|
+
* next: (users) => {
|
|
1235
|
+
* this.userList = users;
|
|
1236
|
+
* },
|
|
1237
|
+
* error: (err) => console.error('Failed to load users', err),
|
|
1238
|
+
* complete: () => console.log('User load complete')
|
|
1239
|
+
* });
|
|
1240
|
+
*
|
|
1241
|
+
* @example
|
|
1242
|
+
* // GET with query parameters
|
|
1243
|
+
* const params = new HttpParams()
|
|
1244
|
+
* .set('page', '1')
|
|
1245
|
+
* .set('limit', '10');
|
|
1246
|
+
*
|
|
1247
|
+
* handler.get<User[]>('users', params).send({
|
|
1248
|
+
* next: (users) => this.displayUsers(users)
|
|
1249
|
+
* });
|
|
1250
|
+
*/
|
|
1251
|
+
get<T>(endpoint: string, params?: HttpParams): IHttpRequest;
|
|
1252
|
+
/**
|
|
1253
|
+
* Performs an HTTP POST request to create new data.
|
|
1254
|
+
*
|
|
1255
|
+
* @template T - Type of the expected response data
|
|
1256
|
+
* @param endpoint - API endpoint path (will be appended to baseUrl)
|
|
1257
|
+
* @param body - Request body data to send
|
|
1258
|
+
* @param headers - Optional HTTP headers
|
|
1259
|
+
* @returns IHttpRequest object with send() and obs() methods
|
|
1260
|
+
*
|
|
1261
|
+
* @example
|
|
1262
|
+
* // Create a new user
|
|
1263
|
+
* const newUser = { name: 'John Doe', email: 'john@example.com' };
|
|
1264
|
+
*
|
|
1265
|
+
* handler.post<User>('users', newUser).send({
|
|
1266
|
+
* next: (createdUser) => {
|
|
1267
|
+
* console.log('User created:', createdUser);
|
|
1268
|
+
* this.router.navigate(['/users', createdUser.id]);
|
|
1269
|
+
* },
|
|
1270
|
+
* error: (err) => this.showError('Failed to create user'),
|
|
1271
|
+
* complete: () => this.hideLoader()
|
|
1272
|
+
* });
|
|
1273
|
+
*
|
|
1274
|
+
* @example
|
|
1275
|
+
* // POST with custom headers
|
|
1276
|
+
* const headers = new HttpHeaders().set('Content-Type', 'application/json');
|
|
1277
|
+
* handler.post<Response>('login', credentials, headers).send({
|
|
1278
|
+
* next: (response) => this.handleLogin(response)
|
|
1279
|
+
* });
|
|
1280
|
+
*/
|
|
1281
|
+
post<T>(endpoint: string, body: any, headers?: HttpHeaders): IHttpRequest;
|
|
1282
|
+
/**
|
|
1283
|
+
* Performs an HTTP PUT request to update existing data.
|
|
1284
|
+
*
|
|
1285
|
+
* @template T - Type of the expected response data
|
|
1286
|
+
* @param endpoint - API endpoint path (will be appended to baseUrl)
|
|
1287
|
+
* @param body - Request body data to send
|
|
1288
|
+
* @param headers - Optional HTTP headers
|
|
1289
|
+
* @returns IHttpRequest object with send() and obs() methods
|
|
1290
|
+
*
|
|
1291
|
+
* @example
|
|
1292
|
+
* // Update a user
|
|
1293
|
+
* const updatedUser = { id: 1, name: 'Jane Doe', email: 'jane@example.com' };
|
|
1294
|
+
*
|
|
1295
|
+
* handler.put<User>('users/1', updatedUser).send({
|
|
1296
|
+
* next: (user) => {
|
|
1297
|
+
* console.log('User updated:', user);
|
|
1298
|
+
* this.refreshUserList();
|
|
1299
|
+
* },
|
|
1300
|
+
* error: (err) => this.showError('Update failed'),
|
|
1301
|
+
* complete: () => console.log('Update complete')
|
|
1302
|
+
* });
|
|
1303
|
+
*/
|
|
1304
|
+
put<T>(endpoint: string, body: any, headers?: HttpHeaders): IHttpRequest;
|
|
1305
|
+
/**
|
|
1306
|
+
* Performs an HTTP DELETE request to remove data.
|
|
1307
|
+
*
|
|
1308
|
+
* @template T - Type of the expected response data
|
|
1309
|
+
* @param endpoint - API endpoint path (will be appended to baseUrl)
|
|
1310
|
+
* @returns IHttpRequest object with send() and obs() methods
|
|
1311
|
+
*
|
|
1312
|
+
* @example
|
|
1313
|
+
* // Delete a user
|
|
1314
|
+
* handler.delete<void>('users/1').send({
|
|
1315
|
+
* next: () => {
|
|
1316
|
+
* console.log('User deleted');
|
|
1317
|
+
* this.removeFromList(1);
|
|
1318
|
+
* },
|
|
1319
|
+
* error: (err) => this.showError('Delete failed'),
|
|
1320
|
+
* complete: () => this.hideLoader()
|
|
1321
|
+
* });
|
|
1322
|
+
*
|
|
1323
|
+
* @example
|
|
1324
|
+
* // Delete with confirmation
|
|
1325
|
+
* if (confirm('Are you sure?')) {
|
|
1326
|
+
* handler.delete('users/1').send({
|
|
1327
|
+
* next: () => this.refreshUserList()
|
|
1328
|
+
* });
|
|
1329
|
+
* }
|
|
1330
|
+
*/
|
|
1331
|
+
delete<T>(endpoint: string): IHttpRequest;
|
|
1332
|
+
/**
|
|
1333
|
+
* Internal wrapper that converts an Observable into an IHttpRequest object.
|
|
1334
|
+
* Provides automatic subscription cleanup and error handling.
|
|
1335
|
+
* Returns an object with send() for callback-based usage and obs() for Observable access.
|
|
1336
|
+
*
|
|
1337
|
+
* @param callback - Function that returns an Observable
|
|
1338
|
+
* @returns IHttpRequest object with send and obs methods
|
|
1339
|
+
* @private
|
|
1340
|
+
*/
|
|
1341
|
+
private wrapper;
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Interface for authorization-specific callback handlers.
|
|
1345
|
+
* Used with AuthUtility to handle authorization success and failure cases.
|
|
1346
|
+
*
|
|
1347
|
+
* @example
|
|
1348
|
+
* const authCallbacks: IHttpAuthSubscribe = {
|
|
1349
|
+
* authorize: (response: IAuth) => {
|
|
1350
|
+
* console.log('Authorized:', response);
|
|
1351
|
+
* this.proceedWithAction();
|
|
1352
|
+
* },
|
|
1353
|
+
* unAuthorize: (error: IAuth) => {
|
|
1354
|
+
* console.log('Unauthorized:', error);
|
|
1355
|
+
* this.showAccessDenied();
|
|
1356
|
+
* }
|
|
1357
|
+
* };
|
|
1358
|
+
*
|
|
1359
|
+
* authUtility.checkAuthAction('delete-user', authCallbacks);
|
|
1360
|
+
*/
|
|
1361
|
+
interface IHttpAuthSubscribe {
|
|
1362
|
+
/** Called when authorization is successful */
|
|
1363
|
+
authorize: (res: IAuth) => void;
|
|
1364
|
+
/** Called when authorization fails or is denied */
|
|
1365
|
+
unAuthorize: (err: IAuth) => void;
|
|
1366
|
+
}
|
|
1367
|
+
/**
|
|
1368
|
+
* Interface for HTTP request subscription callbacks.
|
|
1369
|
+
* Similar to RxJS Observer but with automatic subscription cleanup.
|
|
1370
|
+
*
|
|
1371
|
+
* @example
|
|
1372
|
+
* const callbacks: IHttpSubscribe = {
|
|
1373
|
+
* next: (data) => {
|
|
1374
|
+
* console.log('Received:', data);
|
|
1375
|
+
* this.processData(data);
|
|
1376
|
+
* },
|
|
1377
|
+
* error: (err) => {
|
|
1378
|
+
* console.error('Error:', err);
|
|
1379
|
+
* this.handleError(err);
|
|
1380
|
+
* },
|
|
1381
|
+
* complete: () => {
|
|
1382
|
+
* console.log('Request completed');
|
|
1383
|
+
* this.hideLoader();
|
|
1384
|
+
* }
|
|
1385
|
+
* };
|
|
1386
|
+
*
|
|
1387
|
+
* handler.get('users').send(callbacks);
|
|
1388
|
+
*/
|
|
1389
|
+
interface IHttpSubscribe {
|
|
1390
|
+
/** Called when data is received from the server */
|
|
1391
|
+
next: (res: any) => void;
|
|
1392
|
+
/** Called when an error occurs during the request */
|
|
1393
|
+
error: (err: any) => void;
|
|
1394
|
+
/** Called when the request completes (success or error) */
|
|
1395
|
+
complete: () => void;
|
|
1396
|
+
}
|
|
1397
|
+
/**
|
|
1398
|
+
* Interface representing an HTTP request that can be sent with callbacks or converted to an Observable.
|
|
1399
|
+
* Provides two ways to handle the request: callback-based (send) or reactive (obs).
|
|
1400
|
+
*
|
|
1401
|
+
* @example
|
|
1402
|
+
* // Callback-based approach
|
|
1403
|
+
* const request: IHttpRequest = handler.get('users');
|
|
1404
|
+
* request.send({
|
|
1405
|
+
* next: (users) => console.log(users),
|
|
1406
|
+
* error: (err) => console.error(err),
|
|
1407
|
+
* complete: () => console.log('Done')
|
|
1408
|
+
* });
|
|
1409
|
+
*
|
|
1410
|
+
* @example
|
|
1411
|
+
* // Observable approach (for RxJS operators)
|
|
1412
|
+
* const request: IHttpRequest = handler.get('users');
|
|
1413
|
+
* request.obs().pipe(
|
|
1414
|
+
* map(users => users.filter(u => u.active)),
|
|
1415
|
+
* catchError(err => of([]))
|
|
1416
|
+
* ).subscribe(filteredUsers => console.log(filteredUsers));
|
|
1417
|
+
*/
|
|
1418
|
+
interface IHttpRequest {
|
|
1419
|
+
/** Send the request with callback handlers */
|
|
1420
|
+
send: (sub: IHttpSubscribe) => void;
|
|
1421
|
+
/** Get the underlying Observable for RxJS operations */
|
|
1422
|
+
obs: () => Observable<any>;
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
/**
|
|
1426
|
+
* Utility class for managing internationalization (i18n) and translation services.
|
|
1427
|
+
* Handles loading translation files from multiple modules and provides reactive translation lookups.
|
|
1428
|
+
* Supports lazy-loading of translation files and caching to optimize performance.
|
|
1429
|
+
*
|
|
1430
|
+
* @Injectable - Provided in root, available application-wide
|
|
1431
|
+
*/
|
|
1432
|
+
declare class TranslateUtility {
|
|
1433
|
+
/**
|
|
1434
|
+
* Cache storage for loaded translations.
|
|
1435
|
+
* Structure: { [modulePath]: { [language]: { [key]: translatedValue } } }
|
|
1436
|
+
*/
|
|
1437
|
+
protected translations: {
|
|
1438
|
+
[modulePath: string]: {
|
|
1439
|
+
[lang: string]: any;
|
|
1440
|
+
};
|
|
1441
|
+
};
|
|
1442
|
+
/**
|
|
1443
|
+
* BehaviorSubjects for reactive translation updates.
|
|
1444
|
+
* Key format: "modulePath|language|translationKey"
|
|
1445
|
+
*/
|
|
1446
|
+
protected translationSubjects: {
|
|
1447
|
+
[key: string]: BehaviorSubject<string>;
|
|
1448
|
+
};
|
|
1449
|
+
/**
|
|
1450
|
+
* Loading state trackers to prevent duplicate HTTP requests.
|
|
1451
|
+
* Structure: { [modulePath]: { [language]: BehaviorSubject<boolean> } }
|
|
1452
|
+
*/
|
|
1453
|
+
protected loading: {
|
|
1454
|
+
[modulePath: string]: {
|
|
1455
|
+
[lang: string]: BehaviorSubject<boolean>;
|
|
1456
|
+
};
|
|
1457
|
+
};
|
|
1458
|
+
/**
|
|
1459
|
+
* HTTP request handler configured to fetch translation files from assets.
|
|
1460
|
+
*/
|
|
1461
|
+
protected requestHandler: HttpRequestHandler;
|
|
1462
|
+
constructor();
|
|
1463
|
+
/**
|
|
1464
|
+
* Retrieves a translated value for the specified key from one or more module paths.
|
|
1465
|
+
* Searches through multiple modules in order and returns the first found translation.
|
|
1466
|
+
* Automatically loads translation files if not already cached.
|
|
1467
|
+
*
|
|
1468
|
+
* @param key - The translation key to look up (e.g., 'COMMON.SAVE', 'ERROR.NOT_FOUND')
|
|
1469
|
+
* @param modulePaths - Array of module paths to search for the translation (e.g., ['/common', '/auth'])
|
|
1470
|
+
* @param lang - Language code (defaults to ConfigConst.TranslationUrl.DefaultLanguage)
|
|
1471
|
+
* @returns Observable that emits the translated string, or the original key if not found
|
|
1472
|
+
*
|
|
1473
|
+
* @example
|
|
1474
|
+
* // Load translation from multiple modules
|
|
1475
|
+
* translateUtility.getTranslation$('COMMON.SAVE', ['/common', '/shared'], 'en')
|
|
1476
|
+
* .subscribe(translation => {
|
|
1477
|
+
* console.log(translation); // Outputs: "Save" (if found in en.json)
|
|
1478
|
+
* });
|
|
1479
|
+
*
|
|
1480
|
+
* @example
|
|
1481
|
+
* // Using default language
|
|
1482
|
+
* translateUtility.getTranslation$('ERROR.NOT_FOUND', ['/errors'])
|
|
1483
|
+
* .subscribe(translation => {
|
|
1484
|
+
* console.log(translation); // Uses default language from ConfigConst
|
|
1485
|
+
* });
|
|
1486
|
+
*/
|
|
1487
|
+
getTranslation$(key: string, modulePaths: string[], lang?: string): Observable<string>;
|
|
1488
|
+
/**
|
|
1489
|
+
* Loads translation files from the server for a specific module and language.
|
|
1490
|
+
* Implements caching and prevents duplicate requests for the same module/language combination.
|
|
1491
|
+
* Translation files are expected to be located at: `i18n{modulePath}/{lang}.json`
|
|
1492
|
+
*
|
|
1493
|
+
* @param modulePath - The module path (e.g., '/common', '/auth', '/dashboard')
|
|
1494
|
+
* @param lang - Language code (e.g., 'en', 'it', 'es', 'fr')
|
|
1495
|
+
* @returns Observable that completes when translations are loaded and cached
|
|
1496
|
+
*
|
|
1497
|
+
* @example
|
|
1498
|
+
* // Load English translations for the common module
|
|
1499
|
+
* translateUtility.loadTranslations('/common', 'en')
|
|
1500
|
+
* .subscribe(() => {
|
|
1501
|
+
* console.log('Common translations loaded');
|
|
1502
|
+
* });
|
|
1503
|
+
*
|
|
1504
|
+
* @example
|
|
1505
|
+
* // Translation file structure example (i18n/common/en.json):
|
|
1506
|
+
* // {
|
|
1507
|
+
* // "COMMON.SAVE": "Save",
|
|
1508
|
+
* // "COMMON.CANCEL": "Cancel",
|
|
1509
|
+
* // "COMMON.DELETE": "Delete"
|
|
1510
|
+
* // }
|
|
1511
|
+
* translateUtility.loadTranslations('/common', 'en')
|
|
1512
|
+
* .subscribe(() => {
|
|
1513
|
+
* // Translations are now available in cache
|
|
1514
|
+
* });
|
|
1515
|
+
*/
|
|
1516
|
+
loadTranslations(modulePath: string, lang: string): Observable<any>;
|
|
1517
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TranslateUtility, never>;
|
|
1518
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<TranslateUtility>;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
/**
|
|
1522
|
+
* Utility class for managing cache path configurations and validation.
|
|
1523
|
+
* Handles URL pattern matching, route restrictions, and cache invalidation relationships.
|
|
1524
|
+
* Works in conjunction with CacheUtility to determine which requests should be cached.
|
|
1525
|
+
*
|
|
1526
|
+
* @example
|
|
1527
|
+
* const paths: IPath[] = [
|
|
1528
|
+
* {
|
|
1529
|
+
* pathValue: '/api/users',
|
|
1530
|
+
* resctrictRoute: '/dashboard',
|
|
1531
|
+
* clearOn: ['/api/users/create', '/api/users/update'],
|
|
1532
|
+
* isPersistent: true
|
|
1533
|
+
* }
|
|
1534
|
+
* ];
|
|
1535
|
+
* const cachePathUtility = new CachePathUtility(paths);
|
|
1536
|
+
*/
|
|
1537
|
+
declare class CachePathUtility {
|
|
1538
|
+
/**
|
|
1539
|
+
* Array of cache path configurations defining caching behavior for different URLs.
|
|
1540
|
+
*/
|
|
1541
|
+
protected paths: IPath[];
|
|
1542
|
+
/**
|
|
1543
|
+
* Routing utility instance for checking current navigation state.
|
|
1544
|
+
*/
|
|
1545
|
+
protected RoutingUtility: RoutingUtility;
|
|
1546
|
+
/**
|
|
1547
|
+
* Initializes the cache path utility with an array of path configurations.
|
|
1548
|
+
*
|
|
1549
|
+
* @param paths - Array of IPath configurations defining cache behavior for different URL patterns
|
|
1550
|
+
*
|
|
1551
|
+
* @example
|
|
1552
|
+
* const config: IPath[] = [
|
|
1553
|
+
* { pathValue: '/api/products', isPersistent: true, clearOn: [] },
|
|
1554
|
+
* { pathValue: '/api/cart', isPersistent: false, clearOn: ['/api/checkout'] }
|
|
1555
|
+
* ];
|
|
1556
|
+
* const utility = new CachePathUtility(config);
|
|
1557
|
+
*/
|
|
1558
|
+
constructor(paths: IPath[]);
|
|
1559
|
+
/**
|
|
1560
|
+
* Retrieves the cache configuration for a given URL path.
|
|
1561
|
+
* Uses partial matching to find the first configuration where the path contains the pathValue.
|
|
1562
|
+
*
|
|
1563
|
+
* @param path - The URL path to look up configuration for
|
|
1564
|
+
* @returns The IPath configuration if found, undefined otherwise
|
|
1565
|
+
*
|
|
1566
|
+
* @example
|
|
1567
|
+
* // Configuration: { pathValue: '/api/users', isPersistent: true }
|
|
1568
|
+
* const config = cachePathUtility.config('/api/users/123');
|
|
1569
|
+
* console.log(config?.isPersistent); // true
|
|
1570
|
+
*
|
|
1571
|
+
* @example
|
|
1572
|
+
* const config = cachePathUtility.config('/api/products/search?q=test');
|
|
1573
|
+
* if (config) {
|
|
1574
|
+
* // Use configuration settings for caching logic
|
|
1575
|
+
* }
|
|
1576
|
+
*/
|
|
1577
|
+
config(path: string): IPath | undefined;
|
|
1578
|
+
/**
|
|
1579
|
+
* Checks if a given path should be cached based on configuration and current route restrictions.
|
|
1580
|
+
* Validates both URL pattern matching and optional route restrictions.
|
|
1581
|
+
*
|
|
1582
|
+
* @param path - The URL path to check
|
|
1583
|
+
* @returns True if the path matches a cache configuration and meets route restrictions, false otherwise
|
|
1584
|
+
*
|
|
1585
|
+
* @example
|
|
1586
|
+
* // Configuration: { pathValue: '/api/users', resctrictRoute: '/dashboard' }
|
|
1587
|
+
* // Current route: /dashboard
|
|
1588
|
+
* const shouldCache = cachePathUtility.exist('/api/users');
|
|
1589
|
+
* // Returns true only if user is on /dashboard route
|
|
1590
|
+
*
|
|
1591
|
+
* @example
|
|
1592
|
+
* // Configuration: { pathValue: '/api/global', resctrictRoute: ConfigConst.Route.NONE }
|
|
1593
|
+
* const shouldCache = cachePathUtility.exist('/api/global/settings');
|
|
1594
|
+
* // Returns true regardless of current route
|
|
1595
|
+
*/
|
|
1596
|
+
exist(path: string): boolean;
|
|
1597
|
+
/**
|
|
1598
|
+
* Finds a cache configuration that should be cleared when the given path is accessed.
|
|
1599
|
+
* Used for cache invalidation when related endpoints are called (e.g., clearing user list cache when creating a new user).
|
|
1600
|
+
*
|
|
1601
|
+
* @param path - The URL path that triggers cache invalidation
|
|
1602
|
+
* @returns The IPath configuration that should be cleared, or undefined if none found
|
|
1603
|
+
*
|
|
1604
|
+
* @example
|
|
1605
|
+
* // Configuration: { pathValue: '/api/users', clearOn: ['/api/users/create'] }
|
|
1606
|
+
* const configToClear = cachePathUtility.relationCleanOnConfig('/api/users/create');
|
|
1607
|
+
* // Returns the '/api/users' configuration, indicating its cache should be cleared
|
|
1608
|
+
*
|
|
1609
|
+
* @example
|
|
1610
|
+
* // Use case: Invalidate product list cache when adding new product
|
|
1611
|
+
* // Config: { pathValue: '/api/products', clearOn: ['/api/products/add'] }
|
|
1612
|
+
* const config = cachePathUtility.relationCleanOnConfig('/api/products/add');
|
|
1613
|
+
* if (config) {
|
|
1614
|
+
* // Clear all cache entries matching config.pathValue
|
|
1615
|
+
* }
|
|
1616
|
+
*/
|
|
1617
|
+
relationCleanOnConfig(path: string): IPath | undefined;
|
|
1618
|
+
/**
|
|
1619
|
+
* Checks if accessing the given path should trigger cache invalidation for any configured paths.
|
|
1620
|
+
* Returns true if any cache configuration has this path in its clearOn array.
|
|
1621
|
+
*
|
|
1622
|
+
* @param path - The URL path to check for cache invalidation triggers
|
|
1623
|
+
* @returns True if the path should trigger cache clearing, false otherwise
|
|
1624
|
+
*
|
|
1625
|
+
* @example
|
|
1626
|
+
* // Configuration: { pathValue: '/api/cart', clearOn: ['/api/checkout'] }
|
|
1627
|
+
* const shouldClear = cachePathUtility.existRelationCleanOn('/api/checkout');
|
|
1628
|
+
* // Returns true, indicating cart cache should be cleared
|
|
1629
|
+
*
|
|
1630
|
+
* @example
|
|
1631
|
+
* // Typical usage in cache interceptor
|
|
1632
|
+
* if (cachePathUtility.existRelationCleanOn(request.url)) {
|
|
1633
|
+
* const configToClear = cachePathUtility.relationCleanOnConfig(request.url);
|
|
1634
|
+
* // Clear cache for configToClear.pathValue
|
|
1635
|
+
* }
|
|
1636
|
+
*/
|
|
1637
|
+
existRelationCleanOn(path: string): boolean;
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
/**
|
|
1641
|
+
* Utility class for managing HTTP response caching with both memory and persistent storage.
|
|
1642
|
+
* Provides intelligent caching mechanisms based on URL patterns and request payloads.
|
|
1643
|
+
* Supports automatic cache invalidation and cleanup through relationship configurations.
|
|
1644
|
+
*
|
|
1645
|
+
* @example
|
|
1646
|
+
* // Initialize cache with path configuration
|
|
1647
|
+
* const cachePaths: IPath[] = [
|
|
1648
|
+
* { pathValue: '/api/users', isPersistent: true, reqPayloadCache: false },
|
|
1649
|
+
* { pathValue: '/api/products', isPersistent: false, reqPayloadCache: true }
|
|
1650
|
+
* ];
|
|
1651
|
+
* const cacheUtility = new CacheUtility(cachePaths);
|
|
1652
|
+
*/
|
|
1653
|
+
declare class CacheUtility {
|
|
1654
|
+
/**
|
|
1655
|
+
* Name of the sessionStorage key used for persistent cache storage.
|
|
1656
|
+
*/
|
|
1657
|
+
protected cache_name: string;
|
|
1658
|
+
/**
|
|
1659
|
+
* In-memory cache storage using a Map for fast lookups.
|
|
1660
|
+
* Key: request URL (optionally with payload hash), Value: cached HTTP response
|
|
1661
|
+
*/
|
|
1662
|
+
protected cacheApp: Map<string, HttpResponse<any>>;
|
|
1663
|
+
/**
|
|
1664
|
+
* Utility instance for managing cache path configurations and relationships.
|
|
1665
|
+
*/
|
|
1666
|
+
protected cachePathUtility: CachePathUtility;
|
|
1667
|
+
/**
|
|
1668
|
+
* Initializes the cache utility with path configurations and loads existing cache from sessionStorage.
|
|
1669
|
+
* Restores persistent cache data from previous sessions automatically.
|
|
1670
|
+
*
|
|
1671
|
+
* @param path - Array of path configurations defining which URLs should be cached and how
|
|
1672
|
+
*
|
|
1673
|
+
* @example
|
|
1674
|
+
* const cachePaths: IPath[] = [
|
|
1675
|
+
* {
|
|
1676
|
+
* pathValue: '/api/users',
|
|
1677
|
+
* isPersistent: true, // Survives page refresh
|
|
1678
|
+
* reqPayloadCache: false // Cache by URL only
|
|
1679
|
+
* },
|
|
1680
|
+
* {
|
|
1681
|
+
* pathValue: '/api/search',
|
|
1682
|
+
* isPersistent: false, // Memory-only cache
|
|
1683
|
+
* reqPayloadCache: true // Include request body in cache key
|
|
1684
|
+
* }
|
|
1685
|
+
* ];
|
|
1686
|
+
* const cache = new CacheUtility(cachePaths);
|
|
1687
|
+
*/
|
|
1688
|
+
constructor(path: IPath[]);
|
|
1689
|
+
/**
|
|
1690
|
+
* Validates if a cached response is still valid and usable.
|
|
1691
|
+
* Removes invalid entries (empty arrays or null responses) from the cache automatically.
|
|
1692
|
+
*
|
|
1693
|
+
* @param key - The cache key to validate
|
|
1694
|
+
* @param res - The cached HTTP response to validate
|
|
1695
|
+
* @returns True if the response is valid, false otherwise
|
|
1696
|
+
*
|
|
1697
|
+
* @example
|
|
1698
|
+
* const isValid = cacheUtility.isValidResponse('/api/users', cachedResponse);
|
|
1699
|
+
* // Returns false for empty arrays or null responses
|
|
1700
|
+
*/
|
|
1701
|
+
protected isValidResponse(key: string, res: HttpResponse<any>): boolean;
|
|
1702
|
+
/**
|
|
1703
|
+
* Determines if a request/response pair should be processed by the cache system.
|
|
1704
|
+
* Checks both response validity and if the request URL matches any configured cache paths.
|
|
1705
|
+
*
|
|
1706
|
+
* @param req - The HTTP request to evaluate
|
|
1707
|
+
* @param res - The HTTP response to evaluate
|
|
1708
|
+
* @returns True if the request should be cached, false otherwise
|
|
1709
|
+
*
|
|
1710
|
+
* @example
|
|
1711
|
+
* const shouldCache = cacheUtility.pass(httpRequest, httpResponse);
|
|
1712
|
+
* if (shouldCache) {
|
|
1713
|
+
* cacheUtility.set(httpRequest, httpResponse);
|
|
1714
|
+
* }
|
|
1715
|
+
*/
|
|
1716
|
+
pass(req: HttpRequest<any>, res: HttpResponse<any>): boolean;
|
|
1717
|
+
/**
|
|
1718
|
+
* Retrieves a cached HTTP response for the given request.
|
|
1719
|
+
* Handles cache key generation based on URL and optionally request payload.
|
|
1720
|
+
* Automatically handles cache invalidation based on relationship configurations.
|
|
1721
|
+
* Returns a cloned response to prevent mutations of cached data.
|
|
1722
|
+
*
|
|
1723
|
+
* @param req - The HTTP request to look up in cache
|
|
1724
|
+
* @returns The cached HTTP response if found, undefined otherwise
|
|
1725
|
+
*
|
|
1726
|
+
* @example
|
|
1727
|
+
* // Simple GET request cache lookup
|
|
1728
|
+
* const cachedResponse = cacheUtility.get(httpRequest);
|
|
1729
|
+
* if (cachedResponse) {
|
|
1730
|
+
* return of(cachedResponse); // Use cached data
|
|
1731
|
+
* } else {
|
|
1732
|
+
* return this.http.get(...); // Fetch from server
|
|
1733
|
+
* }
|
|
1734
|
+
*
|
|
1735
|
+
* @example
|
|
1736
|
+
* // POST request with payload-based caching
|
|
1737
|
+
* const searchRequest = new HttpRequest('POST', '/api/search', { query: 'angular' });
|
|
1738
|
+
* const cached = cacheUtility.get(searchRequest);
|
|
1739
|
+
* // Cache key includes hashed request body: '/api/search#[base64-encoded-body]'
|
|
1740
|
+
*/
|
|
1741
|
+
get(req: HttpRequest<any>): HttpResponse<any> | undefined;
|
|
1742
|
+
/**
|
|
1743
|
+
* Stores an HTTP response in the cache for the given request.
|
|
1744
|
+
* Handles both memory-based and persistent (sessionStorage) caching.
|
|
1745
|
+
* Cache key is generated from URL and optionally includes request payload hash.
|
|
1746
|
+
*
|
|
1747
|
+
* @param req - The HTTP request to use as cache key
|
|
1748
|
+
* @param res - The HTTP response to cache
|
|
1749
|
+
*
|
|
1750
|
+
* @example
|
|
1751
|
+
* // Cache a simple GET request response
|
|
1752
|
+
* this.http.get('/api/users').subscribe(response => {
|
|
1753
|
+
* cacheUtility.set(httpRequest, new HttpResponse({ body: response }));
|
|
1754
|
+
* });
|
|
1755
|
+
*
|
|
1756
|
+
* @example
|
|
1757
|
+
* // Cache POST request with payload-specific caching
|
|
1758
|
+
* const request = new HttpRequest('POST', '/api/search', { query: 'test' });
|
|
1759
|
+
* this.http.request(request).subscribe(response => {
|
|
1760
|
+
* cacheUtility.set(request, response);
|
|
1761
|
+
* // Different payloads create different cache entries
|
|
1762
|
+
* });
|
|
1763
|
+
*
|
|
1764
|
+
* @example
|
|
1765
|
+
* // Persistent cache survives page refresh
|
|
1766
|
+
* // Configuration: { pathValue: '/api/users', isPersistent: true }
|
|
1767
|
+
* cacheUtility.set(request, response);
|
|
1768
|
+
* // After page reload, cache is still available via sessionStorage
|
|
1769
|
+
*/
|
|
1770
|
+
set(req: HttpRequest<any>, res: HttpResponse<any>): void;
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
/**
|
|
1774
|
+
* Utility class for managing authentication and authorization flows.
|
|
1775
|
+
* Handles authorization checks against the backend API and provides callback-based authorization status.
|
|
1776
|
+
*
|
|
1777
|
+
* @Injectable - Provided in root, available application-wide
|
|
1778
|
+
*
|
|
1779
|
+
* @example
|
|
1780
|
+
* // Inject in a component or service
|
|
1781
|
+
* constructor(private authUtility: AuthUtility) {}
|
|
1782
|
+
*/
|
|
1783
|
+
declare class AuthUtility {
|
|
1784
|
+
/**
|
|
1785
|
+
* HTTP request handler configured to communicate with the authentication API.
|
|
1786
|
+
*/
|
|
1787
|
+
protected requestHandler: HttpRequestHandler;
|
|
1788
|
+
constructor();
|
|
1789
|
+
/**
|
|
1790
|
+
* Retrieves authorization information from the backend for a specific authorization code.
|
|
1791
|
+
* Returns an IHttpRequest that can be subscribed to or sent with custom callbacks.
|
|
1792
|
+
*
|
|
1793
|
+
* @param code - The authorization code to validate (e.g., user action code, permission code)
|
|
1794
|
+
* @returns IHttpRequest object that can be used to send the request and handle the response
|
|
1795
|
+
*
|
|
1796
|
+
* @example
|
|
1797
|
+
* // Simple authorization check
|
|
1798
|
+
* const request = authUtility.getAuthorization('delete-user-permission');
|
|
1799
|
+
* request.send({
|
|
1800
|
+
* next: (authData) => console.log('Authorization response:', authData),
|
|
1801
|
+
* error: (err) => console.error('Auth error:', err)
|
|
1802
|
+
* });
|
|
1803
|
+
*
|
|
1804
|
+
* @example
|
|
1805
|
+
* // Check if user can access admin panel
|
|
1806
|
+
* authUtility.getAuthorization('admin-access').send({
|
|
1807
|
+
* next: (auth: IAuth) => {
|
|
1808
|
+
* if (auth.authorized === AuthStatus.Ok) {
|
|
1809
|
+
* this.router.navigate(['/admin']);
|
|
1810
|
+
* }
|
|
1811
|
+
* }
|
|
1812
|
+
* });
|
|
1813
|
+
*/
|
|
1814
|
+
getAuthorization(code: string): IHttpRequest;
|
|
1815
|
+
/**
|
|
1816
|
+
* Checks authorization for a specific action and executes appropriate callbacks based on the result.
|
|
1817
|
+
* Automatically handles the authorization flow by calling authorize() on success or unAuthorize() on failure.
|
|
1818
|
+
*
|
|
1819
|
+
* @param key - The authorization key/code to validate
|
|
1820
|
+
* @param auth - Callback object with authorize and optional unAuthorize methods
|
|
1821
|
+
*
|
|
1822
|
+
* @example
|
|
1823
|
+
* // Check if user can delete a resource
|
|
1824
|
+
* authUtility.checkAuthAction('delete-resource', {
|
|
1825
|
+
* authorize: (authData: IAuth) => {
|
|
1826
|
+
* console.log('User is authorized to delete');
|
|
1827
|
+
* this.deleteResource();
|
|
1828
|
+
* },
|
|
1829
|
+
* unAuthorize: (error) => {
|
|
1830
|
+
* console.log('User is NOT authorized');
|
|
1831
|
+
* this.showErrorMessage('You do not have permission to delete this resource');
|
|
1832
|
+
* }
|
|
1833
|
+
* });
|
|
1834
|
+
*
|
|
1835
|
+
* @example
|
|
1836
|
+
* // Protect a sensitive action with authorization check
|
|
1837
|
+
* authUtility.checkAuthAction('export-data', {
|
|
1838
|
+
* authorize: (auth: IAuth) => {
|
|
1839
|
+
* // User has permission
|
|
1840
|
+
* this.exportUserData();
|
|
1841
|
+
* },
|
|
1842
|
+
* unAuthorize: (error) => {
|
|
1843
|
+
* // User lacks permission or error occurred
|
|
1844
|
+
* this.notifyService.error('Access denied');
|
|
1845
|
+
* }
|
|
1846
|
+
* });
|
|
1847
|
+
*/
|
|
1848
|
+
checkAuthAction(key: string, auth: IHttpAuthSubscribe): void;
|
|
1849
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AuthUtility, never>;
|
|
1850
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AuthUtility>;
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
interface LogEntry {
|
|
1854
|
+
timestamp: string;
|
|
1855
|
+
level: LogLevel;
|
|
1856
|
+
className: string;
|
|
1857
|
+
message: string;
|
|
1858
|
+
params: any[];
|
|
1859
|
+
source?: any;
|
|
1860
|
+
}
|
|
1861
|
+
declare class ConsoleLogsUtility {
|
|
1862
|
+
static logStream$: ReplaySubject<LogEntry>;
|
|
1863
|
+
private static readonly COLORS;
|
|
1864
|
+
private static formatTimestamp;
|
|
1865
|
+
private static buildLog;
|
|
1866
|
+
static info<T>(_class: T, ..._args: any[]): void;
|
|
1867
|
+
static debug<T>(_class: T, ..._args: any[]): void;
|
|
1868
|
+
static warning<T>(_class: T, ..._args: any[]): void;
|
|
1869
|
+
static error<T>(_class: T, ..._args: any[]): void;
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
/**
|
|
1873
|
+
* Type definition for a constructor that can be mixed in.
|
|
1874
|
+
* Represents any class constructor (including abstract classes) that can be extended.
|
|
1875
|
+
*/
|
|
1876
|
+
type Constructor<T = {}> = abstract new (...args: any[]) => T;
|
|
1877
|
+
/**
|
|
1878
|
+
* Interface defining the storage handler functionality that will be added by the mixin.
|
|
1879
|
+
* This includes reactive props management and data change handling.
|
|
1880
|
+
*/
|
|
1881
|
+
interface IStorageHandler<T = any> {
|
|
1882
|
+
propsStore: T;
|
|
1883
|
+
storageHandlerDataChanges(prev: any, curr: any): void;
|
|
1884
|
+
}
|
|
1885
|
+
/**
|
|
1886
|
+
* Mixin function that adds storage handler functionality to any base class.
|
|
1887
|
+
* This enables state management, reactive props, and automatic store synchronization.
|
|
1888
|
+
*
|
|
1889
|
+
* The mixin extracts storage configuration from route data and sets up:
|
|
1890
|
+
* - Dataset creation in the state store
|
|
1891
|
+
* - Reactive connection to store state
|
|
1892
|
+
* - Automatic prop-to-store synchronization via Proxy
|
|
1893
|
+
*
|
|
1894
|
+
* @param Base - The base class to extend with storage handler functionality
|
|
1895
|
+
* @returns A function that accepts a type parameter and returns a class with typed props
|
|
1896
|
+
*
|
|
1897
|
+
* @example
|
|
1898
|
+
* // Use with BaseComponent with typed props
|
|
1899
|
+
* interface MyProps { name: string; email: string; }
|
|
1900
|
+
* export class MyStorageComp extends StorageHandlerMixin<MyProps>(BaseComponent) {
|
|
1901
|
+
* storageHandlerDataChanges(prev: any, curr: any): void {
|
|
1902
|
+
* console.log('Data updated:', data);
|
|
1903
|
+
* // this.props is typed as MyProps
|
|
1904
|
+
* }
|
|
1905
|
+
* }
|
|
1906
|
+
*
|
|
1907
|
+
* @example
|
|
1908
|
+
* // Use with BaseMolecule without typed props (defaults to any)
|
|
1909
|
+
* export class MyStorageMolecule extends StorageHandlerMixin(BaseMolecule) {
|
|
1910
|
+
* storageHandlerDataChanges(data: any): void {
|
|
1911
|
+
* console.log('Data updated:', data);
|
|
1912
|
+
* }
|
|
1913
|
+
* }
|
|
1914
|
+
*/
|
|
1915
|
+
declare function BaseHandlerMixin<T extends object = any, TBase extends Constructor = Constructor>(Base: TBase): Constructor<IStorageHandler<T> & {
|
|
1916
|
+
propsStore: T;
|
|
1917
|
+
storageHandlerDataChanges(prev: T, curr: T): void;
|
|
1918
|
+
}> & TBase;
|
|
1919
|
+
|
|
1920
|
+
declare const BaseStorageComponent_base: _asor_studio_asor_core.Constructor<IStorageHandler<any> & {
|
|
1921
|
+
propsStore: any;
|
|
1922
|
+
storageHandlerDataChanges(prev: any, curr: any): void;
|
|
1923
|
+
}> & typeof BaseComponent;
|
|
1924
|
+
/**
|
|
1925
|
+
* Base abstract class for Page/Component-level components with integrated storage handler functionality.
|
|
1926
|
+
* Extends BaseComponent with automatic state management, reactive props, and store synchronization.
|
|
1927
|
+
*
|
|
1928
|
+
* This class combines the lifecycle management and i18n capabilities of BaseComponent
|
|
1929
|
+
* with the storage handling features from BaseHandlerMixin.
|
|
1930
|
+
*
|
|
1931
|
+
* Storage features:
|
|
1932
|
+
* - Automatic dataset creation from route configuration
|
|
1933
|
+
* - Reactive connection to state store
|
|
1934
|
+
* - Proxy-based prop-to-store synchronization
|
|
1935
|
+
* - Support for nested object updates
|
|
1936
|
+
*
|
|
1937
|
+
* @Directive - Can be extended by Angular components
|
|
1938
|
+
* @abstract - Must be extended, cannot be instantiated directly
|
|
1939
|
+
*
|
|
1940
|
+
* @example
|
|
1941
|
+
* // Route configuration with storage:
|
|
1942
|
+
* {
|
|
1943
|
+
* path: 'user-profile',
|
|
1944
|
+
* component: UserProfileComponent,
|
|
1945
|
+
* data: {
|
|
1946
|
+
* I18nPath: ['/common', '/user'],
|
|
1947
|
+
* CreateDataSet: {
|
|
1948
|
+
* name: 'userProfile',
|
|
1949
|
+
* data: { name: '', email: '' },
|
|
1950
|
+
* option: CreateDataSetOption.CREATE_IF_NOT_EXISTS
|
|
1951
|
+
* },
|
|
1952
|
+
* ConnectDataSet: {
|
|
1953
|
+
* propStructure: {
|
|
1954
|
+
* name: ['userProfile', 'name'],
|
|
1955
|
+
* email: ['userProfile', 'email']
|
|
1956
|
+
* }
|
|
1957
|
+
* }
|
|
1958
|
+
* } as IAsorRoute
|
|
1959
|
+
* }
|
|
1960
|
+
*
|
|
1961
|
+
* @example
|
|
1962
|
+
* // Component implementation:
|
|
1963
|
+
* @Component({
|
|
1964
|
+
* selector: 'app-user-profile',
|
|
1965
|
+
* templateUrl: './user-profile.component.html'
|
|
1966
|
+
* })
|
|
1967
|
+
* export class UserProfileComponent extends BaseStorageHandlerComp {
|
|
1968
|
+
*
|
|
1969
|
+
* storageHandlerDataChanges(data: any): void {
|
|
1970
|
+
* console.log('Store data updated:', data);
|
|
1971
|
+
* // React to store changes
|
|
1972
|
+
* }
|
|
1973
|
+
*
|
|
1974
|
+
* updateUserName(newName: string): void {
|
|
1975
|
+
* // This automatically updates the store
|
|
1976
|
+
* this.props.name = newName;
|
|
1977
|
+
* }
|
|
1978
|
+
* }
|
|
1979
|
+
*/
|
|
1980
|
+
declare abstract class BaseStorageComponent<T extends object = Record<string, any>> extends BaseStorageComponent_base implements IStorageHandler<T> {
|
|
1981
|
+
/**
|
|
1982
|
+
* Typed props object for type-safe state management.
|
|
1983
|
+
* This provides strongly-typed access to the propsStore from the mixin.
|
|
1984
|
+
* The propsStore is flattened from a nested structure grouped by dataset root
|
|
1985
|
+
* to a flat structure with direct property access while maintaining proxy reactivity.
|
|
1986
|
+
*/
|
|
1987
|
+
get props(): T;
|
|
1988
|
+
constructor();
|
|
1989
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BaseStorageComponent<any>, never>;
|
|
1990
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<BaseStorageComponent<any>, never, never, {}, {}, never, never, true, never>;
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1993
|
+
declare const BaseStorageMolecule_base: _asor_studio_asor_core.Constructor<IStorageHandler<any> & {
|
|
1994
|
+
propsStore: any;
|
|
1995
|
+
storageHandlerDataChanges(prev: any, curr: any): void;
|
|
1996
|
+
}> & typeof BaseMolecule;
|
|
1997
|
+
/**
|
|
1998
|
+
* Base abstract class for Molecule-level components with integrated storage handler functionality.
|
|
1999
|
+
* Extends BaseMolecule with automatic state management, reactive props, and store synchronization.
|
|
2000
|
+
*
|
|
2001
|
+
* This class combines the Atomic Design molecule structure and i18n capabilities of BaseMolecule
|
|
2002
|
+
* with the storage handling features from BaseHandlerMixin.
|
|
2003
|
+
*
|
|
2004
|
+
* Storage features:
|
|
2005
|
+
* - Automatic dataset creation from route configuration
|
|
2006
|
+
* - Reactive connection to state store
|
|
2007
|
+
* - Proxy-based prop-to-store synchronization
|
|
2008
|
+
* - Support for nested object updates
|
|
2009
|
+
*
|
|
2010
|
+
* @Directive - Can be extended by Angular components
|
|
2011
|
+
* @abstract - Must be extended, cannot be instantiated directly
|
|
2012
|
+
*
|
|
2013
|
+
* @example
|
|
2014
|
+
* // Route configuration with molecule storage:
|
|
2015
|
+
* {
|
|
2016
|
+
* path: 'dashboard',
|
|
2017
|
+
* component: DashboardComponent,
|
|
2018
|
+
* data: {
|
|
2019
|
+
* Molecules: [{
|
|
2020
|
+
* Component: UserCardMolecule,
|
|
2021
|
+
* I18nPath: ['/common', '/user-card']
|
|
2022
|
+
* }],
|
|
2023
|
+
* CreateDataSet: {
|
|
2024
|
+
* name: 'userData',
|
|
2025
|
+
* data: { name: '', avatar: '' },
|
|
2026
|
+
* option: CreateDataSetOption.CREATE_IF_NOT_EXISTS
|
|
2027
|
+
* },
|
|
2028
|
+
* ConnectDataSet: {
|
|
2029
|
+
* propStructure: {
|
|
2030
|
+
* name: ['userData', 'name'],
|
|
2031
|
+
* avatar: ['userData', 'avatar']
|
|
2032
|
+
* }
|
|
2033
|
+
* }
|
|
2034
|
+
* } as IAsorRoute
|
|
2035
|
+
* }
|
|
2036
|
+
*
|
|
2037
|
+
* @example
|
|
2038
|
+
* // Molecule implementation:
|
|
2039
|
+
* @Component({
|
|
2040
|
+
* selector: 'app-user-card',
|
|
2041
|
+
* templateUrl: './user-card.component.html'
|
|
2042
|
+
* })
|
|
2043
|
+
* export class UserCardMolecule extends BaseStorageHandlerMolecule implements OnInit {
|
|
2044
|
+
*
|
|
2045
|
+
* ngOnInit(): void {
|
|
2046
|
+
* // Molecule initialization
|
|
2047
|
+
* }
|
|
2048
|
+
*
|
|
2049
|
+
* storageHandlerDataChanges(data: any): void {
|
|
2050
|
+
* console.log('Store data updated:', data);
|
|
2051
|
+
* }
|
|
2052
|
+
*
|
|
2053
|
+
* baseCompViewWillEnter(): void {
|
|
2054
|
+
* console.log('Molecule entering view');
|
|
2055
|
+
* }
|
|
2056
|
+
*
|
|
2057
|
+
* baseCompViewWillLeave(): void {
|
|
2058
|
+
* console.log('Molecule leaving view');
|
|
2059
|
+
* }
|
|
2060
|
+
*
|
|
2061
|
+
* updateUserAvatar(newAvatar: string): void {
|
|
2062
|
+
* // This automatically updates the store
|
|
2063
|
+
* this.props.avatar = newAvatar;
|
|
2064
|
+
* }
|
|
2065
|
+
* }
|
|
2066
|
+
*/
|
|
2067
|
+
declare abstract class BaseStorageMolecule<T extends object = Record<string, any>> extends BaseStorageMolecule_base implements IStorageHandler<T> {
|
|
2068
|
+
/**
|
|
2069
|
+
* Typed props object for type-safe state management.
|
|
2070
|
+
* This provides strongly-typed access to the propsStore from the mixin.
|
|
2071
|
+
* The propsStore is flattened from a nested structure grouped by dataset root
|
|
2072
|
+
* to a flat structure with direct property access while maintaining proxy reactivity.
|
|
2073
|
+
*/
|
|
2074
|
+
get props(): T;
|
|
2075
|
+
constructor();
|
|
2076
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BaseStorageMolecule<any>, never>;
|
|
2077
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<BaseStorageMolecule<any>, never, never, {}, {}, never, never, true, never>;
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
/**
|
|
2081
|
+
* Service for managing and distributing HTTP error notifications across the application.
|
|
2082
|
+
* Implements a centralized error notification system using RxJS observables.
|
|
2083
|
+
* Allows components to register callbacks that will be invoked when HTTP errors occur.
|
|
2084
|
+
* Automatically manages subscriptions to prevent memory leaks.
|
|
2085
|
+
*
|
|
2086
|
+
* @Injectable - Provided in root, available application-wide
|
|
2087
|
+
*
|
|
2088
|
+
* @example
|
|
2089
|
+
* // In an HTTP interceptor
|
|
2090
|
+
* constructor(private notifyErrorService: NotifyErrorService) {}
|
|
2091
|
+
*
|
|
2092
|
+
* intercept(req, next) {
|
|
2093
|
+
* return next.handle(req).pipe(
|
|
2094
|
+
* catchError((error: HttpErrorResponse) => {
|
|
2095
|
+
* this.notifyErrorService.send(error);
|
|
2096
|
+
* return throwError(error);
|
|
2097
|
+
* })
|
|
2098
|
+
* );
|
|
2099
|
+
* }
|
|
2100
|
+
*/
|
|
2101
|
+
declare class NotifyErrorService {
|
|
2102
|
+
static readonly className = "NotifyErrorService";
|
|
2103
|
+
/**
|
|
2104
|
+
* BehaviorSubject that holds the latest HTTP error response.
|
|
2105
|
+
* Null when no error has occurred yet.
|
|
2106
|
+
*/
|
|
2107
|
+
private dataSubject;
|
|
2108
|
+
/**
|
|
2109
|
+
* Observable stream of HTTP error responses that subscribers can listen to.
|
|
2110
|
+
*/
|
|
2111
|
+
private dataSub;
|
|
2112
|
+
/**
|
|
2113
|
+
* Map storing active subscriptions by component class name.
|
|
2114
|
+
* Used to automatically unsubscribe previous subscriptions before creating new ones.
|
|
2115
|
+
*/
|
|
2116
|
+
private sub;
|
|
2117
|
+
/**
|
|
2118
|
+
* Broadcasts an HTTP error to all registered subscribers.
|
|
2119
|
+
* This method is typically called by HTTP interceptors when an error occurs.
|
|
2120
|
+
*
|
|
2121
|
+
* @param error - The HTTP error response to broadcast
|
|
2122
|
+
*
|
|
2123
|
+
* @example
|
|
2124
|
+
* // In an HTTP interceptor
|
|
2125
|
+
* catchError((error: HttpErrorResponse) => {
|
|
2126
|
+
* this.notifyErrorService.send(error);
|
|
2127
|
+
* return throwError(error);
|
|
2128
|
+
* });
|
|
2129
|
+
*
|
|
2130
|
+
* @example
|
|
2131
|
+
* // Manually send an error
|
|
2132
|
+
* const customError = new HttpErrorResponse({
|
|
2133
|
+
* status: IHttpStatusCode.NotFound,
|
|
2134
|
+
* statusText: 'Not Found',
|
|
2135
|
+
* error: { message: 'Resource not found' }
|
|
2136
|
+
* });
|
|
2137
|
+
* this.notifyErrorService.send(customError);
|
|
2138
|
+
*/
|
|
2139
|
+
send(error: HttpErrorResponse): void;
|
|
2140
|
+
/**
|
|
2141
|
+
* Registers a callback function to be invoked when HTTP errors occur.
|
|
2142
|
+
* Automatically unsubscribes any previous subscription for the same class name.
|
|
2143
|
+
* This prevents memory leaks and ensures only one active subscription per component.
|
|
2144
|
+
*
|
|
2145
|
+
* @param className - Unique identifier for this subscriber (typically the component class name)
|
|
2146
|
+
* @param callBack - Function to execute when an error occurs, receives status code and error details
|
|
2147
|
+
*
|
|
2148
|
+
* @example
|
|
2149
|
+
* // In a component's ngOnInit
|
|
2150
|
+
* ngOnInit() {
|
|
2151
|
+
* this.notifyErrorService.registry(
|
|
2152
|
+
* 'UserListComponent',
|
|
2153
|
+
* (status: HttpStatusCode, error: IHttpResponseError) => {
|
|
2154
|
+
* if (status === IHttpStatusCode.Unauthorized) {
|
|
2155
|
+
* this.router.navigate(['/login']);
|
|
2156
|
+
* } else if (status === IHttpStatusCode.NotFound) {
|
|
2157
|
+
* this.showMessage('Resource not found');
|
|
2158
|
+
* } else {
|
|
2159
|
+
* this.showMessage(error.message || 'An error occurred');
|
|
2160
|
+
* }
|
|
2161
|
+
* }
|
|
2162
|
+
* );
|
|
2163
|
+
* }
|
|
2164
|
+
*
|
|
2165
|
+
* @example
|
|
2166
|
+
* // Handle specific error types
|
|
2167
|
+
* this.notifyErrorService.registry(
|
|
2168
|
+
* 'ProductListComponent',
|
|
2169
|
+
* (status, error) => {
|
|
2170
|
+
* switch (status) {
|
|
2171
|
+
* case IHttpStatusCode.BadRequest:
|
|
2172
|
+
* this.toast.error('Invalid request');
|
|
2173
|
+
* break;
|
|
2174
|
+
* case IHttpStatusCode.Unauthorized:
|
|
2175
|
+
* this.authService.logout();
|
|
2176
|
+
* break;
|
|
2177
|
+
* case IHttpStatusCode.Forbidden:
|
|
2178
|
+
* this.toast.error('Access forbidden');
|
|
2179
|
+
* break;
|
|
2180
|
+
* case IHttpStatusCode.NotFound:
|
|
2181
|
+
* this.toast.error('Resource not found');
|
|
2182
|
+
* break;
|
|
2183
|
+
* case IHttpStatusCode.TooManyRequests:
|
|
2184
|
+
* this.toast.error('Too many requests. Please try again later.');
|
|
2185
|
+
* break;
|
|
2186
|
+
* case IHttpStatusCode.InternalServerError:
|
|
2187
|
+
* this.toast.error('Server error. Please try again later.');
|
|
2188
|
+
* break;
|
|
2189
|
+
* }
|
|
2190
|
+
* }
|
|
2191
|
+
* );
|
|
2192
|
+
*/
|
|
2193
|
+
registry(className: string, callBack: (status: HttpStatusCode, error: IHttpResponseError) => void): void;
|
|
2194
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NotifyErrorService, never>;
|
|
2195
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<NotifyErrorService>;
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
declare class AuthGuard implements CanActivate {
|
|
2199
|
+
static readonly className = "AuthGuard";
|
|
2200
|
+
private routingUtility;
|
|
2201
|
+
private authUtility;
|
|
2202
|
+
private injector;
|
|
2203
|
+
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree | RedirectCommand>;
|
|
2204
|
+
private executeAuthCheck;
|
|
2205
|
+
private normalizeGuardResult;
|
|
2206
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AuthGuard, never>;
|
|
2207
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AuthGuard>;
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
declare class ErrorInterceptor implements HttpInterceptor {
|
|
2211
|
+
static readonly className = "ErrorInterceptor";
|
|
2212
|
+
private notifyErrorService;
|
|
2213
|
+
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
|
|
2214
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ErrorInterceptor, never>;
|
|
2215
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ErrorInterceptor>;
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
declare class CacheInterceptor implements HttpInterceptor {
|
|
2219
|
+
static readonly className = "CacheInterceptor";
|
|
2220
|
+
private cacheUtility;
|
|
2221
|
+
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
|
|
2222
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<CacheInterceptor, never>;
|
|
2223
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<CacheInterceptor>;
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
declare class TranslatePipe implements PipeTransform, OnDestroy {
|
|
2227
|
+
private translateUtility;
|
|
2228
|
+
private changeDetectorRef;
|
|
2229
|
+
private lastKey;
|
|
2230
|
+
private translatedValue;
|
|
2231
|
+
private subscription;
|
|
2232
|
+
private context;
|
|
2233
|
+
constructor();
|
|
2234
|
+
transform(key: string, lang?: string): string;
|
|
2235
|
+
private decodeHtmlEntities;
|
|
2236
|
+
ngOnDestroy(): void;
|
|
2237
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TranslatePipe, never>;
|
|
2238
|
+
static ɵpipe: i0.ɵɵPipeDeclaration<TranslatePipe, "translate", true>;
|
|
2239
|
+
}
|
|
2240
|
+
|
|
2241
|
+
/**
|
|
2242
|
+
* StateHandler Service
|
|
2243
|
+
* Manages application state with optional encryption and persistence
|
|
2244
|
+
*/
|
|
2245
|
+
declare class StateService {
|
|
2246
|
+
static readonly className = "StateService";
|
|
2247
|
+
protected initialized: boolean;
|
|
2248
|
+
protected containerRoot: DataElement[];
|
|
2249
|
+
protected conf: StateHandlerConfig;
|
|
2250
|
+
protected intervalId: any;
|
|
2251
|
+
protected registryMap: Map<string, RegistryEntry<any>>;
|
|
2252
|
+
/**
|
|
2253
|
+
* Initialize the logical storage data
|
|
2254
|
+
*
|
|
2255
|
+
* @param conf Configuration object
|
|
2256
|
+
*
|
|
2257
|
+
* Note: Call this before using any other methods to initialize the component
|
|
2258
|
+
*/
|
|
2259
|
+
initialize(conf?: StateHandlerConfig): void;
|
|
2260
|
+
/**
|
|
2261
|
+
* Create a new dataset in state storage
|
|
2262
|
+
*
|
|
2263
|
+
* @param name Name of field root
|
|
2264
|
+
* @param data All type of data
|
|
2265
|
+
* @param option Configuration options
|
|
2266
|
+
* @returns Success status
|
|
2267
|
+
*/
|
|
2268
|
+
createDataSet(name: string, data: any, option: CreateDataSetOption): boolean;
|
|
2269
|
+
/**
|
|
2270
|
+
* Read object data from state
|
|
2271
|
+
*
|
|
2272
|
+
* @param name Name of field root (string) or path (array of strings)
|
|
2273
|
+
* @returns Dataset or null if not found
|
|
2274
|
+
*/
|
|
2275
|
+
readDataSet(path: string): any;
|
|
2276
|
+
/**
|
|
2277
|
+
* Update data into state
|
|
2278
|
+
*
|
|
2279
|
+
* @param name Name of field root (string) or path (array of strings)
|
|
2280
|
+
* @param data All type of data
|
|
2281
|
+
* @param option Update options
|
|
2282
|
+
* @returns Success status
|
|
2283
|
+
*/
|
|
2284
|
+
updateDataSet(path: string, data: any, option?: UpdateDataSetOption): boolean;
|
|
2285
|
+
/**
|
|
2286
|
+
* Trigger change notification for registered components
|
|
2287
|
+
* Finds all registry entries matching the changed path and invokes their callbacks
|
|
2288
|
+
* @param changedPath Path that was modified (string or array of strings)
|
|
2289
|
+
*/
|
|
2290
|
+
triggerChange(changedPath?: string): void;
|
|
2291
|
+
/**
|
|
2292
|
+
* Remove object from list
|
|
2293
|
+
* @param name Name of the root dataset
|
|
2294
|
+
*/
|
|
2295
|
+
deleteRootDataSet(name: string): void;
|
|
2296
|
+
/**
|
|
2297
|
+
* Create name of state
|
|
2298
|
+
*/
|
|
2299
|
+
private getStateName;
|
|
2300
|
+
/**
|
|
2301
|
+
* Create key encryption of state
|
|
2302
|
+
*/
|
|
2303
|
+
protected getStateKey(): string;
|
|
2304
|
+
/**
|
|
2305
|
+
* Encrypt data
|
|
2306
|
+
*/
|
|
2307
|
+
private encrypt;
|
|
2308
|
+
/**
|
|
2309
|
+
* Decrypt data
|
|
2310
|
+
*/
|
|
2311
|
+
private decrypt;
|
|
2312
|
+
/**
|
|
2313
|
+
* Connect to state changes and return an observable of mapped properties
|
|
2314
|
+
* Similar to React's connect HOC pattern
|
|
2315
|
+
*
|
|
2316
|
+
* @param propStructure Object mapping property names to state paths
|
|
2317
|
+
* @returns Observable that emits mapped data whenever state changes
|
|
2318
|
+
*
|
|
2319
|
+
* @example
|
|
2320
|
+
* const user$ = stateHandler.connect({
|
|
2321
|
+
* name: "account.user.name",
|
|
2322
|
+
* surname: "account.user.surname"
|
|
2323
|
+
* });
|
|
2324
|
+
*
|
|
2325
|
+
* user$.subscribe(data => {
|
|
2326
|
+
* console.log(data.name, data.surname);
|
|
2327
|
+
* });
|
|
2328
|
+
*/
|
|
2329
|
+
registry<T = any>(componentName: string, propStructure: {
|
|
2330
|
+
[key: string]: string;
|
|
2331
|
+
}, callback: (props: T) => void): void;
|
|
2332
|
+
/**
|
|
2333
|
+
* Resolve properties from state based on mapping structure
|
|
2334
|
+
* @param propStructure Object mapping property names to state paths
|
|
2335
|
+
* @returns Object with resolved values
|
|
2336
|
+
*/
|
|
2337
|
+
resolveProps(propStructure: {
|
|
2338
|
+
[key: string]: string;
|
|
2339
|
+
}): any;
|
|
2340
|
+
/**
|
|
2341
|
+
* Clean up on service destruction
|
|
2342
|
+
*/
|
|
2343
|
+
ngOnDestroy(): void;
|
|
2344
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StateService, never>;
|
|
2345
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<StateService>;
|
|
2346
|
+
}
|
|
2347
|
+
|
|
2348
|
+
/**
|
|
2349
|
+
* Utility class for string operations
|
|
2350
|
+
*/
|
|
2351
|
+
declare class StringUtils {
|
|
2352
|
+
static isEmpty(value: any): boolean;
|
|
2353
|
+
static isNotEmpty(value: any): boolean;
|
|
2354
|
+
static isString(value: any): boolean;
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
/**
|
|
2358
|
+
* Utility class for collection operations
|
|
2359
|
+
*/
|
|
2360
|
+
declare class CollectionUtils {
|
|
2361
|
+
static isEmpty(value: any): boolean;
|
|
2362
|
+
static isNotEmpty(value: any): boolean;
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
/**
|
|
2366
|
+
* Utility class for object operations
|
|
2367
|
+
*/
|
|
2368
|
+
declare class ObjectUtils {
|
|
2369
|
+
static isEmpty(value: any): boolean;
|
|
2370
|
+
static isNotEmpty(value: any): boolean;
|
|
2371
|
+
static isObject(value: any): boolean;
|
|
2372
|
+
static cloneDeep(value: any): any;
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2375
|
+
/**
|
|
2376
|
+
* Utility class for random string generation
|
|
2377
|
+
*/
|
|
2378
|
+
declare class RandomUtils {
|
|
2379
|
+
/**
|
|
2380
|
+
* Generate a random string of specified length
|
|
2381
|
+
* @param length Length of the random string
|
|
2382
|
+
* @returns Random string
|
|
2383
|
+
*/
|
|
2384
|
+
static makeid(length: number): string;
|
|
2385
|
+
}
|
|
2386
|
+
|
|
2387
|
+
/**
|
|
2388
|
+
* Utility class for cookie operations
|
|
2389
|
+
*/
|
|
2390
|
+
declare class CookieUtils {
|
|
2391
|
+
/**
|
|
2392
|
+
* Add a cookie
|
|
2393
|
+
* @param name Cookie name
|
|
2394
|
+
* @param value Cookie value
|
|
2395
|
+
* @param days Days until expiration
|
|
2396
|
+
*/
|
|
2397
|
+
static add(name: string, value: string, days: number): void;
|
|
2398
|
+
/**
|
|
2399
|
+
* Read a cookie
|
|
2400
|
+
* @param name Cookie name
|
|
2401
|
+
* @returns Cookie value or empty string if not found
|
|
2402
|
+
*/
|
|
2403
|
+
static read(name: string): string;
|
|
2404
|
+
/**
|
|
2405
|
+
* Delete a cookie
|
|
2406
|
+
* @param name Cookie name
|
|
2407
|
+
*/
|
|
2408
|
+
static delete(name: string): void;
|
|
2409
|
+
}
|
|
2410
|
+
|
|
2411
|
+
type AsorWidgetMode = 'off' | 'on' | 'spy';
|
|
2412
|
+
declare class AsorWidgetComponent {
|
|
2413
|
+
mode: AsorWidgetMode;
|
|
2414
|
+
readonly logoSrc = "data:image/png;base64,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";
|
|
2415
|
+
isOpen: boolean;
|
|
2416
|
+
activeTab: 'console' | 'storage' | 'other';
|
|
2417
|
+
/** In spy mode, tracks whether the widget has been revealed via CTRL+I */
|
|
2418
|
+
private spyActivated;
|
|
2419
|
+
get isVisible(): boolean;
|
|
2420
|
+
onKeyDown(event: KeyboardEvent): void;
|
|
2421
|
+
toggleSlider(): void;
|
|
2422
|
+
selectTab(tab: 'console' | 'storage' | 'other'): void;
|
|
2423
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AsorWidgetComponent, never>;
|
|
2424
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AsorWidgetComponent, "asor-core-widget", never, { "mode": { "alias": "mode"; "required": false; }; }, {}, never, never, true, never>;
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
export { GlobalEnum_d as AsorGlobalEnum, StateConstants_d as AsorStorage, AsorWidgetComponent, AuthGuard, AuthUtility, BaseComponent, BaseHandlerMixin, BaseMolecule, BaseStorageComponent, BaseStorageMolecule, CacheInterceptor, CachePathUtility, CacheUtility, CollectionUtils, ConfigCache, ConfigConst, ConsoleLogsConfig, ConsoleLogsUtility, CookieUtils, ErrorInterceptor, HttpRequestHandler, NotifyErrorService, ObjectUtils, RandomUtils, RoutingUtility, StateConst, StateService, StringUtils, TranslatePipe, TranslateUtility };
|
|
2428
|
+
export type { AsorWidgetMode, Constructor, CreateDataSetOption, DataElement, DataMethod, EncryptType, GenerateType, IAsorRoute, IAuth, IComp, ICompStatic, IComponent, IConnectDataSet, ICreateDataSet, IHttpAuthSubscribe, IHttpFormError, IHttpRequest, IHttpRequestHandlerConfig, IHttpResponseError, IHttpSubscribe, IMolecule, IPath, IStorageHandler, LogClassConfig, LogEntry, LogLevel, RegistryEntry, StateHandlerConfig, StoreType, UpdateDataSetOption };
|