@qlover/fe-corekit 1.2.1

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.
@@ -0,0 +1,2574 @@
1
+ import { AxiosRequestConfig, AxiosStatic } from 'axios';
2
+
3
+ /**
4
+ * Generic interface for encryption/decryption operations
5
+ * Provides a standard contract for implementing encryption strategies
6
+ *
7
+ * @template ValueType - Type of value to encrypt/decrypt
8
+ * @template EncryptResult - Type of encrypted result
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // String encryption implementation
13
+ * class StringEncryptor implements Encryptor<string, string> {
14
+ * encrypt(value: string): string {
15
+ * // Encryption logic
16
+ * }
17
+ *
18
+ * decrypt(encryptedData: string): string {
19
+ * // Decryption logic
20
+ * }
21
+ * }
22
+ * ```
23
+ */
24
+ interface Encryptor<ValueType, EncryptResult> {
25
+ /**
26
+ * Encrypts the provided value
27
+ * @param value - Value to encrypt
28
+ * @returns Encrypted result
29
+ */
30
+ encrypt(value: ValueType): EncryptResult;
31
+ /**
32
+ * Decrypts the encrypted data
33
+ * @param encryptedData - Data to decrypt
34
+ * @returns Original value
35
+ */
36
+ decrypt(encryptedData: EncryptResult): ValueType;
37
+ }
38
+
39
+ /**
40
+ * Custom error class for executor operations.
41
+ *
42
+ * This class provides a structured way to handle errors that occur during executor operations.
43
+ * It extends the standard Error class to include an error identification string, which can be used
44
+ * to categorize and manage errors more effectively.
45
+ *
46
+ * @category Executor
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * try {
51
+ * // some executor operation
52
+ * } catch (error) {
53
+ * throw new ExecutorError('EXECUTOR_ERROR', error);
54
+ * }
55
+ * ```
56
+ *
57
+ * @example
58
+ *
59
+ * create an error with a message from a string
60
+ *
61
+ * ```typescript
62
+ * const error = new ExecutorError('ERROR_ID', 'This is an error message');
63
+ *
64
+ * // => error.message is 'This is an error message'
65
+ * // => error.id is 'ERROR_ID'
66
+ * ```
67
+ */
68
+ declare class ExecutorError extends Error {
69
+ id: string;
70
+ /**
71
+ * Constructs a new ExecutorError.
72
+ *
73
+ * if originalError is a string, it will be used as the error message.
74
+ * if originalError is an Error object, its message will be used as the error message.
75
+ * if originalError is not provided, the error message will be the id.
76
+ *
77
+ * @param id - A unique identifier for the error, used for categorization and tracking.
78
+ * @param originalError - The original error message or Error object that triggered this error.
79
+ * This parameter is optional.
80
+ */
81
+ constructor(id: string, originalError?: string | Error);
82
+ }
83
+
84
+ /**
85
+ * Represents the context in which a task is executed.
86
+ *
87
+ * This interface is designed to encapsulate the necessary information
88
+ * for executing a task, including parameters, potential errors, and
89
+ * the return value. It allows for additional properties to be added
90
+ * dynamically, making it flexible for various use cases.
91
+ *
92
+ * @template Params - The type of parameters that the task accepts.
93
+ *
94
+ * @since 1.0.14
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * const context: ExecutorContextInterface<MyParams> = {
99
+ * parameters: { id: 1 },
100
+ * error: null,
101
+ * returnValue: 'Success'
102
+ * };
103
+ * ```
104
+ */
105
+ interface ExecutorContext<Params = unknown> {
106
+ /**
107
+ * The error that occurred during the execution of the task.
108
+ *
109
+ * This property is optional and will be populated if an error
110
+ * occurs during task execution.
111
+ *
112
+ * @type {Error | undefined}
113
+ */
114
+ error?: Error;
115
+ /**
116
+ * The parameters passed to the task.
117
+ *
118
+ * These parameters are used to execute the task and are of a generic
119
+ * type, allowing for flexibility in the types of parameters that can
120
+ * be passed.
121
+ *
122
+ * @type {Params}
123
+ */
124
+ parameters: Params;
125
+ /**
126
+ * The return value of the task.
127
+ *
128
+ * This property is optional and will contain the result of the task
129
+ * execution if it completes successfully.
130
+ *
131
+ * @type {unknown | undefined}
132
+ */
133
+ returnValue?: unknown;
134
+ /**
135
+ * The runtime information of the task.
136
+ *
137
+ * The current runtime of each hook.
138
+ *
139
+ * This property is optional and will contain the runtime information
140
+ * of the task if it is executed.
141
+ *
142
+ * property is read-only
143
+ *
144
+ * will return a frozen object that will be cleared after the chain execution is complete.
145
+ *
146
+ */
147
+ hooksRuntimes: HookRuntimes;
148
+ }
149
+ interface HookRuntimes {
150
+ hookName?: string;
151
+ /**
152
+ * The return value of the task.
153
+ *
154
+ * Readonly
155
+ */
156
+ returnValue?: unknown;
157
+ /**
158
+ * 执行次数
159
+ */
160
+ times?: number;
161
+ /**
162
+ * 是否中断链
163
+ */
164
+ breakChain?: boolean;
165
+ /**
166
+ * 如果有返回值,是否中断链
167
+ *
168
+ * 一般常用于需要返回一个值时中断链,比如 onError 声明周期
169
+ */
170
+ returnBreakChain?: boolean;
171
+ [key: string]: unknown;
172
+ }
173
+
174
+ /**
175
+ * Type definition for promise-based task
176
+ * @template T - Return type of the task
177
+ * @template D - Input data type for the task
178
+ * @example
179
+ * ```typescript
180
+ * const promiseTask: PromiseTask<string, number> = async (data: number) => {
181
+ * return `Result: ${data}`;
182
+ * };
183
+ * ```
184
+ * @category ExecutorPlugin
185
+ */
186
+ type PromiseTask<Result, Params> = (context: ExecutorContext<Params>) => Promise<Result>;
187
+ /**
188
+ * Type definition for synchronous task
189
+ * @template Result - Return type of the task
190
+ * @template D - Input data type for the task
191
+ * @example
192
+ * ```typescript
193
+ * const syncTask: SyncTask<string, number> = (data: number) => {
194
+ * return `Result: ${data}`;
195
+ * };
196
+ * ```
197
+ * @category ExecutorPlugin
198
+ */
199
+ type SyncTask<Result, Params> = (context: ExecutorContext<Params>) => Result;
200
+ /**
201
+ * Union type for both promise and sync tasks
202
+ * @template T - Return type of the task
203
+ * @template D - Input data type for the task
204
+ * @category ExecutorPlugin
205
+ */
206
+ type Task<Result, Params> = PromiseTask<Result, Params> | SyncTask<Result, Params>;
207
+ /**
208
+ * Base plugin class for extending executor functionality.
209
+ *
210
+ * Plugins provide a way to intercept and modify the execution flow at different stages:
211
+ * - Before execution (onBefore)
212
+ * - After successful execution (onSuccess)
213
+ * - On error (onError)
214
+ * - Custom execution logic (onExec)
215
+ *
216
+ * LifeCycle:
217
+ *
218
+ * **onBefore**
219
+ * - onBefore can modify the input data before it reaches the task, before exec is called.
220
+ * - The parameter of the first plugin's onBefore is the input data of exec.
221
+ * - The parameter of other plugins' onBefore is the return value of previous plugin's onBefore.
222
+ * - Also, not return value, will use first plugin's onBefore return value or exec's input data.
223
+ * - The parameter of the first plugin's onBefore is the input data of exec.
224
+ * - If any plugin's onBefore throws an error, it immediately stops the onBefore chain and enters the onError chain.
225
+ *
226
+ * **onExec**
227
+ * - onExec can modify the task before it is executed.
228
+ * - Use first plugin's onExec return value or exec's task.
229
+ * - The exec execution is only allowed to be modified once, so only the first onExec lifecycle method registered in the plugins list will be used.
230
+ *
231
+ * **onSuccess**
232
+ * - When call exec, onSuccess will be executed after onExec.
233
+ * - onSuccess accept the result of previous plugin's onSuccess, and can return a new result to the next plugin's onSuccess.
234
+ * - That means, if any plugin's onSuccess returns a new value, the next plugin's onSuccess will accept the value of previous plugin's onSuccess as parameter,
235
+ * - and can continue to return a new value, until the last plugin's onSuccess. The entire chain will not stop.
236
+ * - The parameter of the first plugin's onSuccess is the result of exec.
237
+ * - If any plugin's onSuccess throws an error, it immediately stops the onSuccess chain and enters the onError chain.
238
+ *
239
+ * **onError**
240
+ * - When an error occurs during call exec, all plugins' onError will be ordered executed.
241
+ * - After exec, all errors will be wrapped with ExecutorError.
242
+ * - If onError of any of the plugins returns an error, the error is thrown and the entire chain is stopped, but execNoError only return the error.
243
+ * - If any plugin's onError throws an error, it immediately stops the entire chain and throws the error, since errors in the error chain cannot be caught. Whether exec or execNoError.
244
+ * - If all plugins' onError neither return nor throw an error, wrapping raw Errors with ExecutorError and throw.
245
+ * - If execNoError is called, the first error encountered is returned, and the entire lifecycle is terminated.
246
+ *
247
+ *
248
+ * **execNoError returns all errors as they are.**
249
+ *
250
+ * @template T - Type of data being processed
251
+ * @template R - Type of result after processing
252
+ *
253
+ * @example
254
+ * ```typescript
255
+ * class LoggerPlugin extends ExecutorPlugin {
256
+ * onBefore(data: unknown) {
257
+ * console.log('Before execution:', data);
258
+ * return data;
259
+ * }
260
+ *
261
+ * onSuccess(result: unknown) {
262
+ * console.log('Execution succeeded:', result);
263
+ * return result;
264
+ * }
265
+ *
266
+ * onError(error: Error) {
267
+ * console.error('Execution failed:', error);
268
+ * throw error;
269
+ * }
270
+ * }
271
+ * ```
272
+ * @category ExecutorPlugin
273
+ */
274
+ interface ExecutorPlugin<T = unknown> {
275
+ /**
276
+ * The pluginName of the plugin.
277
+ *
278
+ * Plugins with the same pluginName will be merged.
279
+ */
280
+ readonly pluginName: string;
281
+ /**
282
+ * Indicates if only one instance of this plugin should exist in the executor
283
+ * When true, attempting to add duplicate plugins will result in a warning
284
+ */
285
+ readonly onlyOne?: boolean;
286
+ /**
287
+ * Controls whether the plugin is active for specific hook executions
288
+ * @param name - Name of the hook being executed
289
+ * @param args - Arguments passed to the hook
290
+ * @returns Boolean indicating if the plugin should be executed
291
+ *
292
+ * @example
293
+ * ```typescript
294
+ * enabled(name: keyof ExecutorPlugin, context: ExecutorContextInterface<T>) {
295
+ * // Only enable for error handling
296
+ * return name === 'onError';
297
+ * }
298
+ * ```
299
+ */
300
+ enabled?(name: keyof ExecutorPlugin, context?: ExecutorContext<T>): boolean;
301
+ /**
302
+ * Hook executed before the main task
303
+ * Can modify the input data before it reaches the task
304
+ * @param data - Input data
305
+ * @returns Modified data or Promise of modified data
306
+ */
307
+ onBefore?(context: ExecutorContext<T>): void | Promise<void>;
308
+ /**
309
+ * Error handling hook
310
+ * - For `exec`: returning a value or throwing will break the chain
311
+ * - For `execNoError`: returning a value or throwing will return the error
312
+ *
313
+ * Because `onError` can break the chain, best practice is each plugin only handle plugin related error
314
+ *
315
+ * @param error - Error that occurred
316
+ * @param data - Original input data
317
+ * @returns ExecutorError, void, or Promise of either
318
+ */
319
+ onError?(context: ExecutorContext<T>): Promise<ExecutorError | Error | void> | ExecutorError | Error | void;
320
+ /**
321
+ * Hook executed after successful task completion
322
+ * Can transform the task result
323
+ * @param result - Task execution result
324
+ * @returns Modified result or Promise of modified result
325
+ */
326
+ onSuccess?(context: ExecutorContext<T>): void | Promise<void>;
327
+ /**
328
+ * Custom execution logic hook
329
+ * Only the first plugin with onExec will be used
330
+ * @param task - Task to be executed
331
+ * @returns Task result or Promise of result
332
+ */
333
+ onExec?(context: ExecutorContext<unknown>, task: Task<unknown, unknown>): Promise<unknown> | unknown;
334
+ }
335
+
336
+ /**
337
+ * Base executor class providing plugin management and execution pipeline
338
+ *
339
+ * The Executor pattern implements a pluggable execution pipeline that allows:
340
+ * 1. Pre-processing of input data
341
+ * 2. Post-processing of results
342
+ * 3. Error handling
343
+ * 4. Custom execution logic
344
+ *
345
+ * execNoError returns all errors as they are., and if there is a plugin onerror handler chain in which an error occurs, it will also return the error instead of throwing it.
346
+ *
347
+ * @abstract
348
+ * @class Executor
349
+ * @category Executor
350
+ * @example
351
+ * ```typescript
352
+ * // Create an executor instance
353
+ * const executor = new AsyncExecutor();
354
+ *
355
+ * // Add plugins
356
+ * executor.use(new LoggerPlugin());
357
+ * executor.use(new RetryPlugin({ maxAttempts: 3 }));
358
+ *
359
+ * // Execute a task
360
+ * const result = await executor.exec(async (data) => {
361
+ * return await someAsyncOperation(data);
362
+ * });
363
+ * ```
364
+ */
365
+ declare abstract class Executor<ExecutorConfig = unknown> {
366
+ protected config?: ExecutorConfig | undefined;
367
+ /**
368
+ * Array of active plugins
369
+ *
370
+ * - Purpose: Stores and manages executor plugins
371
+ * - Core Concept: Ordered plugin pipeline
372
+ * - Main Features:
373
+ * - Maintains plugin execution order
374
+ * - Supports plugin lifecycle management
375
+ * - Primary Use: Plugin orchestration and execution
376
+ *
377
+ * @example
378
+ * ```typescript
379
+ * protected plugins = [
380
+ * new LoggerPlugin(),
381
+ * new RetryPlugin()
382
+ * ];
383
+ * ```
384
+ */
385
+ protected plugins: ExecutorPlugin[];
386
+ /**
387
+ * Creates a new Executor instance
388
+ *
389
+ * - Purpose: Initialize executor with optional configuration
390
+ * - Core Concept: Configurable executor setup
391
+ * - Main Features: Configuration injection
392
+ * - Primary Use: Executor instantiation
393
+ *
394
+ * @param {ExecutorConfig} config - Optional configuration object
395
+ *
396
+ * @example
397
+ * ```typescript
398
+ * const executor = new Executor({
399
+ * // config options
400
+ * });
401
+ * ```
402
+ */
403
+ constructor(config?: ExecutorConfig | undefined);
404
+ /**
405
+ * Add a plugin to the executor
406
+ *
407
+ * - Purpose: Extends executor functionality through plugins
408
+ * - Core Concept: Plugin registration and deduplication
409
+ * - Main Features:
410
+ * - Prevents duplicate plugins if onlyOne is true
411
+ * - Maintains plugin execution order
412
+ * - Primary Use: Adding new capabilities to executor
413
+ *
414
+ * @param plugin - Plugin instance to add
415
+ *
416
+ * @example
417
+ * ```typescript
418
+ * executor.use(new LoggerPlugin());
419
+ * executor.use(new RetryPlugin({ maxAttempts: 3 }));
420
+ * ```
421
+ *
422
+ * @example
423
+ *
424
+ * Use a plain object as a plugin
425
+ * ```typescript
426
+ * executor.use({
427
+ * onBefore: (data) => ({ ...data, modified: true })
428
+ * });
429
+ * ```
430
+ */
431
+ use(plugin: ExecutorPlugin): void;
432
+ /**
433
+ * Execute a plugin hook
434
+ *
435
+ * - Purpose: Provides plugin hook execution mechanism
436
+ * - Core Concept: Plugin lifecycle management
437
+ * - Main Features:
438
+ * - Dynamic hook execution
439
+ * - Support for async and sync hooks
440
+ * - Primary Use: Running plugin lifecycle methods
441
+ *
442
+ * @param plugins - Plugins to execute
443
+ * @param name - Hook name to execute
444
+ * @param args - Arguments for the hook
445
+ *
446
+ * @example
447
+ * ```typescript
448
+ * await executor.runHook(plugins, 'beforeExec', data);
449
+ * ```
450
+ */
451
+ abstract runHooks(plugins: ExecutorPlugin[], name: keyof ExecutorPlugin, ...args: unknown[]): void | unknown | Promise<void | unknown>;
452
+ /**
453
+ * Execute a task with plugin pipeline
454
+ *
455
+ * - Purpose: Core task execution with plugin support
456
+ * - Core Concept: Task execution pipeline
457
+ * - Main Features:
458
+ * - Plugin hook integration
459
+ * - Error handling
460
+ * - Primary Use: Running tasks through the executor pipeline
461
+ *
462
+ * @param task - Task to execute
463
+ * @param data - Optional input data for task
464
+ * @throws {ExecutorError} If task execution fails
465
+ *
466
+ * @example
467
+ * ```typescript
468
+ * const result = await executor.exec(async (data) => {
469
+ * return await processData(data);
470
+ * });
471
+ * ```
472
+ */
473
+ abstract exec<Result, Params = unknown>(task: Task<Result, Params>): Promise<Result> | Result;
474
+ /**
475
+ * Execute a task with plugin pipeline and input data
476
+ *
477
+ * - Purpose: Core task execution with plugin support and input data
478
+ * - Core Concept: Task execution pipeline with data
479
+ * - Main Features:
480
+ * - Plugin hook integration
481
+ * - Error handling
482
+ * - Primary Use: Running tasks with input data through the executor pipeline
483
+ *
484
+ * @param data - Input data for task
485
+ * @param task - Task to execute
486
+ * @throws {ExecutorError} If task execution fails
487
+ *
488
+ * @example
489
+ * ```typescript
490
+ * const result = await executor.exec(data, async (data) => {
491
+ * return await processData(data);
492
+ * });
493
+ * ```
494
+ */
495
+ abstract exec<Result, Params = unknown>(data: unknown, task: Task<Result, Params>): Promise<Result> | Result;
496
+ /**
497
+ * Execute a task without throwing errors
498
+ *
499
+ * - Purpose: Safe task execution with error wrapping
500
+ * - Core Concept: Error-safe execution pipeline
501
+ * - Main Features:
502
+ * - Error wrapping in ExecutorError
503
+ * - Non-throwing execution
504
+ * - Primary Use: When error handling is preferred over exceptions
505
+ *
506
+ * @param task - Task to execute
507
+ *
508
+ * @example
509
+ * ```typescript
510
+ * const result = await executor.execNoError(async (data) => {
511
+ * return await riskyOperation(data);
512
+ * });
513
+ * if (result instanceof ExecutorError) {
514
+ * console.error('Task failed:', result);
515
+ * }
516
+ * ```
517
+ */
518
+ abstract execNoError<Result, Params = unknown>(task: Task<Result, Params>): Promise<Result | ExecutorError> | Result | ExecutorError;
519
+ /**
520
+ * Execute a task with input data without throwing errors
521
+ *
522
+ * - Purpose: Safe task execution with error wrapping and input data
523
+ * - Core Concept: Error-safe execution pipeline with data
524
+ * - Main Features:
525
+ * - Error wrapping in ExecutorError
526
+ * - Non-throwing execution
527
+ * - Primary Use: When error handling is preferred over exceptions with input data
528
+ *
529
+ * @param data - Input data for task
530
+ * @param task - Task to execute
531
+ *
532
+ * @example
533
+ * ```typescript
534
+ * const result = await executor.execNoError(data, async (data) => {
535
+ * return await riskyOperation(data);
536
+ * });
537
+ * if (result instanceof ExecutorError) {
538
+ * console.error('Task failed:', result);
539
+ * }
540
+ * ```
541
+ */
542
+ abstract execNoError<Result, Params = unknown>(data: unknown, task: Task<Result, Params>): Promise<Result | ExecutorError> | Result | ExecutorError;
543
+ }
544
+
545
+ /**
546
+ * Request adapter configuration
547
+ *
548
+ * This type defines the configuration options for a request adapter.
549
+ * It includes properties for URL, method, headers, and other request details.
550
+ * The main purpose is to provide a flexible structure for configuring HTTP requests.
551
+ *
552
+ * @since 1.0.14
553
+ */
554
+ type RequestAdapterConfig<RequestData = unknown> = {
555
+ /**
556
+ * Request URL path
557
+ * Will be combined with baseURL if provided
558
+ *
559
+ * Processed by FetchURLPlugin during request
560
+ *
561
+ * @todo Change to URL | Request, add attribute `input`
562
+ * @example
563
+ * ```typescript
564
+ * url: '/users/1'
565
+ * ```
566
+ */
567
+ url?: string;
568
+ /**
569
+ * HTTP request methods supported by the executor
570
+ * Follows standard HTTP method definitions
571
+ *
572
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
573
+ * @example
574
+ * ```typescript
575
+ * method: 'GET'
576
+ * ```
577
+ */
578
+ method?: string;
579
+ /**
580
+ * Base URL for all requests
581
+ * Will be prepended to the request URL
582
+ *
583
+ * @example
584
+ * ```typescript
585
+ * baseURL: 'https://api.example.com'
586
+ * // url = /users/1 => https://api.example.com/users/1
587
+ * // url = users/1 => https://api.example.com/users/1
588
+ * ```
589
+ */
590
+ baseURL?: string;
591
+ /**
592
+ * Request body data
593
+ *
594
+ * Mapping fetch `body`
595
+ *
596
+ * @typeParam RequestData - The type of the request body data.
597
+ * @example
598
+ * ```typescript
599
+ * data: { name: 'John Doe' }
600
+ * ```
601
+ */
602
+ data?: RequestData;
603
+ /**
604
+ * URL query parameters
605
+ * Will be serialized and appended to the URL
606
+ *
607
+ * @example
608
+ * ```typescript
609
+ * params: { search: 'query' }
610
+ * ```
611
+ */
612
+ params?: Record<string, unknown>;
613
+ /**
614
+ * Request headers
615
+ *
616
+ * @example
617
+ * ```typescript
618
+ * headers: { 'Content-Type': 'application/json' }
619
+ * ```
620
+ */
621
+ headers?: {
622
+ [key: string]: unknown;
623
+ };
624
+ /**
625
+ * Response type
626
+ *
627
+ * Specifies the type of data that the server will respond with.
628
+ *
629
+ * @example
630
+ * ```typescript
631
+ * responseType: 'json'
632
+ * ```
633
+ */
634
+ responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream' | 'formdata';
635
+ /**
636
+ * Request ID, used to identify the request in the abort plugin.
637
+ */
638
+ requestId?: string;
639
+ [key: string]: any;
640
+ };
641
+ /**
642
+ * Request adapter response
643
+ *
644
+ * This type defines the structure of a response from a request adapter.
645
+ * It includes the response data, status, headers, and the original request configuration.
646
+ *
647
+ * @typeParam Req - The type of the request data.
648
+ * @typeParam Res - The type of the response data.
649
+ */
650
+ type RequestAdapterResponse<Req = unknown, Res = unknown> = {
651
+ data: Res;
652
+ status: number;
653
+ statusText: string;
654
+ headers: {
655
+ [key: string]: unknown;
656
+ };
657
+ config: RequestAdapterConfig<Req>;
658
+ response: Response;
659
+ [key: string]: unknown;
660
+ };
661
+ /**
662
+ * Request adapter interface
663
+ *
664
+ * This interface defines the contract for request adapters.
665
+ * Adapters are responsible for handling the specific details of a request,
666
+ * such as URL construction, headers, and response handling.
667
+ *
668
+ */
669
+ interface RequestAdapterInterface<Config extends RequestAdapterConfig> {
670
+ /**
671
+ * The configuration for the request adapter.
672
+ *
673
+ * @type {Config}
674
+ */
675
+ readonly config: Config;
676
+ /**
677
+ * Sends a request using the specified options and returns a promise with the response.
678
+ *
679
+ * @typeParam Request - The type of the request data.
680
+ * @typeParam Response - The type of the response data.
681
+ * @param options - The configuration options for the request.
682
+ * @returns A promise that resolves to the response of the request.
683
+ * @example
684
+ * ```typescript
685
+ * adapter.request({ url: '/users', method: 'GET' }).then(response => console.log(response));
686
+ * ```
687
+ */
688
+ request<Request, Response>(options: RequestAdapterConfig<Request>): Promise<RequestAdapterResponse<Request, Response>>;
689
+ /**
690
+ * Retrieves the current configuration of the request adapter.
691
+ *
692
+ * @returns The current configuration.
693
+ * @example
694
+ * ```typescript
695
+ * const config = adapter.getConfig();
696
+ * ```
697
+ */
698
+ getConfig: () => Config;
699
+ }
700
+
701
+ /**
702
+ * Represents a custom error class for handling request-related errors in the application
703
+ *
704
+ * RequestError extends the base ExecutorError class to provide specific error handling
705
+ * for HTTP requests and fetch operations. It works in conjunction with RequestErrorID
706
+ * to categorize different types of request failures.
707
+ *
708
+ * @since 1.0.14
709
+ *
710
+ * @example
711
+ * ```typescript
712
+ * try {
713
+ * await fetchData(url);
714
+ * } catch (error) {
715
+ * if (error instanceof RequestError) {
716
+ * // Handle request specific error
717
+ * console.error('Request failed:', error.message);
718
+ * }
719
+ * }
720
+ * ```
721
+ */
722
+ declare class RequestError extends ExecutorError {
723
+ }
724
+ /**
725
+ * Error IDs for different fetch request failure scenarios
726
+ * Used to identify specific error types in error handling
727
+ *
728
+ * @description
729
+ * This enum provides a standardized set of error identifiers that can be used
730
+ * to categorize and handle different types of request failures in a consistent manner.
731
+ * Each error ID represents a specific failure scenario that might occur during HTTP requests.
732
+ *
733
+ * @example
734
+ * ```typescript
735
+ * if (error.id === RequestErrorID.RESPONSE_NOT_OK) {
736
+ * // Handle non-200 response
737
+ * } else if (error.id === RequestErrorID.ABORT_ERROR) {
738
+ * // Handle aborted request
739
+ * }
740
+ * ```
741
+ */
742
+ declare enum RequestErrorID {
743
+ /** Generic fetch request error */
744
+ REQUEST_ERROR = "REQUEST_ERROR",
745
+ /** Environment doesn't support fetch API */
746
+ ENV_FETCH_NOT_SUPPORT = "ENV_FETCH_NOT_SUPPORT",
747
+ /** No fetcher function provided */
748
+ FETCHER_NONE = "FETCHER_NONE",
749
+ /** Response status is not OK (not in 200-299 range) */
750
+ RESPONSE_NOT_OK = "RESPONSE_NOT_OK",
751
+ /** Request was aborted */
752
+ ABORT_ERROR = "ABORT_ERROR",
753
+ /** URL is not provided */
754
+ URL_NONE = "URL_NONE"
755
+ }
756
+
757
+ /**
758
+ * Generic interface for data serialization/deserialization operations
759
+ * Provides a standard contract for implementing serialization strategies
760
+ *
761
+ * This is a generic interface, you can implement it with different serialization strategies
762
+ *
763
+ * @template T - Type of data to serialize/deserialize, defaults to any
764
+ * @template R - Type of serialized result, defaults to string
765
+ *
766
+ * @since 1.0.10
767
+ *
768
+ * @example
769
+ * ```typescript
770
+ * // JSON serialization implementation
771
+ * class JSONSerializer implements Serializer {
772
+ * serialize(data: any): string {
773
+ * return JSON.stringify(data);
774
+ * }
775
+ *
776
+ * deserialize(data: string): any {
777
+ * return JSON.parse(data);
778
+ * }
779
+ * }
780
+ * ```
781
+ */
782
+ interface Serializer<T = unknown, R = string> {
783
+ /**
784
+ * Serializes data into a target format
785
+ * @since 1.0.10
786
+ * @param data - Data to serialize
787
+ * @returns Serialized representation
788
+ */
789
+ serialize(data: T): R;
790
+ /**
791
+ * Deserializes data from target format back to original form
792
+ * @since 1.0.10
793
+ * @param data - Data to deserialize
794
+ * @param defaultValue - Optional default value to return if deserialization fails
795
+ * @returns Original data structure
796
+ */
797
+ deserialize(data: R, defaultValue?: T): T;
798
+ }
799
+
800
+ /**
801
+ * Interface representing a synchronous storage mechanism.
802
+ *
803
+ * @template Key - The type of keys used to identify stored values.
804
+ * @template ValueType - The type of values stored, defaults to unknown.
805
+ *
806
+ * @example
807
+ * ```typescript
808
+ * const storage: SyncStorage<string, number> = ...;
809
+ * storage.setItem('key', 123);
810
+ * const value = storage.getItem('key', 0);
811
+ * ```
812
+ */
813
+ interface SyncStorage<Key, ValueType = unknown> {
814
+ /**
815
+ * The number of items stored.
816
+ */
817
+ readonly length: number;
818
+ /**
819
+ * Stores a value with the specified key.
820
+ *
821
+ * @param key - The key to identify the stored value.
822
+ * @param value - The value to store.
823
+ * @param options - Optional parameters for storage.
824
+ */
825
+ setItem<T>(key: Key, value: T, options?: unknown): void;
826
+ /**
827
+ * Retrieves a value by key.
828
+ *
829
+ * @param key - The key of the value to retrieve.
830
+ * @param defaultValue - The default value to return if the key is not found.
831
+ * @param options - Optional parameters for retrieval.
832
+ * @returns The value associated with the key, or the default value if not found.
833
+ */
834
+ getItem<T extends ValueType>(key: Key, defaultValue?: T, options?: unknown): T | null;
835
+ /**
836
+ * Removes a value by key.
837
+ *
838
+ * @param key - The key of the value to remove.
839
+ * @param options - Optional parameters for removal.
840
+ */
841
+ removeItem(key: Key, options?: unknown): void;
842
+ /**
843
+ * Clears all stored values.
844
+ */
845
+ clear(): void;
846
+ }
847
+ /**
848
+ * Interface representing an asynchronous storage mechanism.
849
+ *
850
+ * @template Key - The type of keys used to identify stored values.
851
+ * @template ValueType - The type of values stored, defaults to unknown.
852
+ *
853
+ * @example
854
+ *
855
+ * ```typescript
856
+ * const storage: AsyncStorage<string, number> = ...;
857
+ * await storage.setItem('key', 123);
858
+ * const value = await storage.getItem('key', 0);
859
+ * ```
860
+ *
861
+ */
862
+ interface AsyncStorage<Key, ValueType = unknown> {
863
+ /**
864
+ * The number of items stored.
865
+ */
866
+ readonly length: number;
867
+ /**
868
+ * Asynchronously stores a value with the specified key.
869
+ *
870
+ * @param key - The key to identify the stored value.
871
+ * @param value - The value to store.
872
+ * @param options - Optional parameters for storage.
873
+ * @returns A promise that resolves when the value is stored.
874
+ */
875
+ setItem<T>(key: Key, value: T, options?: unknown): Promise<void>;
876
+ /**
877
+ * Asynchronously retrieves a value by key.
878
+ *
879
+ * @param key - The key of the value to retrieve.
880
+ * @param defaultValue - The default value to return if the key is not found.
881
+ * @param options - Optional parameters for retrieval.
882
+ * @returns A promise that resolves to the value associated with the key, or the default value if not found.
883
+ */
884
+ getItem<T extends ValueType>(key: Key, defaultValue?: T, options?: unknown): Promise<T | null>;
885
+ /**
886
+ * Asynchronously removes a value by key.
887
+ *
888
+ * @param key - The key of the value to remove.
889
+ * @param options - Optional parameters for removal.
890
+ * @returns A promise that resolves when the value is removed.
891
+ */
892
+ removeItem(key: Key, options?: unknown): Promise<void>;
893
+ /**
894
+ * Asynchronously clears all stored values.
895
+ *
896
+ * @returns A promise that resolves when all values are cleared.
897
+ */
898
+ clear(): Promise<void>;
899
+ }
900
+
901
+ /**
902
+ * Get the value type of an object
903
+ *
904
+ * @since 1.0.14
905
+ *
906
+ * @example
907
+ * ```ts
908
+ * type T = { a: number; b: string };
909
+ * type V = ValueOf<T>; // V is number | string
910
+ * ```
911
+ */
912
+ type ValueOf<T> = T[keyof T];
913
+ /**
914
+ * Get the intersection type of two types
915
+ *
916
+ * @since 1.0.14
917
+ *
918
+ * @example
919
+ * ```ts
920
+ * type T1 = { a: number; b: string };
921
+ * type T2 = { a: number; c: boolean };
922
+ * type I = Intersection<T1, T2>; // I is { a: number }
923
+ * ```
924
+ */
925
+ type Intersection<T1, T2> = {
926
+ [P in keyof T1 & keyof T2]: T1[P] | T2[P];
927
+ };
928
+
929
+ /**
930
+ * Asynchronous implementation of the Executor pattern
931
+ *
932
+ * - Purpose: Provides asynchronous task execution with plugin support
933
+ * - Core Concept: Async execution pipeline with plugin hooks
934
+ * - Main Features:
935
+ * - Asynchronous plugin hook execution
936
+ * - Promise-based task handling
937
+ * - Error handling with plugin support
938
+ * - Primary Use: Handling async operations with extensible middleware
939
+ *
940
+ * @example
941
+ * ```typescript
942
+ * const executor = new AsyncExecutor();
943
+ * executor.use(new LogPlugin());
944
+ *
945
+ * const result = await executor.exec(async (data) => {
946
+ * const response = await fetch('https://api.example.com/data');
947
+ * return response.json();
948
+ * });
949
+ * ```
950
+ *
951
+ * @category AsyncExecutor
952
+ */
953
+ declare class AsyncExecutor<ExecutorConfig = unknown> extends Executor<ExecutorConfig> {
954
+ /**
955
+ * Execute plugin hook functions asynchronously
956
+ *
957
+ * - Purpose: Orchestrates asynchronous plugin hook execution
958
+ * - Core Concept: Sequential async plugin pipeline
959
+ * - Main Features:
960
+ * - Plugin enablement checking
961
+ * - Result chaining
962
+ * - Error hook special handling
963
+ * - Primary Use: Internal plugin lifecycle management
964
+ *
965
+ * Plugin execution flow:
966
+ * 1. Check if plugin is enabled for the hook
967
+ * 2. Execute plugin hook if available
968
+ * 3. Handle plugin results and chain breaking conditions
969
+ *
970
+ * @param plugins - Array of plugins to execute
971
+ * @param hookName - Name of the hook function to execute
972
+ * @param args - Arguments to pass to the hook function
973
+ * @returns Promise resolving to the hook execution result
974
+ *
975
+ * @example
976
+ * ```typescript
977
+ * const result = await this.runHook(
978
+ * this.plugins,
979
+ * 'beforeExec',
980
+ * { userId: 123 }
981
+ * );
982
+ * ```
983
+ */
984
+ runHooks<Params>(plugins: ExecutorPlugin[],
985
+ /**
986
+ * allow any string as hook name.
987
+ * if the hook name is not a function, it will be skipped
988
+ *
989
+ * @since 1.1.3
990
+ */
991
+ hookName: string, context?: ExecutorContext<Params>, ...args: unknown[]): Promise<unknown>;
992
+ /**
993
+ * Execute task without throwing errors
994
+ *
995
+ * - Purpose: Safe execution of async tasks
996
+ * - Core Concept: Error wrapping and handling
997
+ * - Main Features:
998
+ * - Catches all execution errors
999
+ * - Wraps errors in ExecutorError
1000
+ * - Returns either result or error object
1001
+ * - Primary Use: When you want to handle errors without try-catch
1002
+ *
1003
+ * @template T - Type of task return value
1004
+ * @param dataOrTask - Task data or task function
1005
+ * @param task - Task function (optional)
1006
+ * @returns Promise resolving to either result or ExecutorError
1007
+ *
1008
+ * @example
1009
+ * ```typescript
1010
+ * const result = await executor.execNoError(async () => {
1011
+ * const response = await riskyOperation();
1012
+ * return response.data;
1013
+ * });
1014
+ *
1015
+ * if (result instanceof ExecutorError) {
1016
+ * console.error('Operation failed:', result);
1017
+ * }
1018
+ * ```
1019
+ */
1020
+ execNoError<Result, Params = unknown>(dataOrTask: unknown | PromiseTask<Result, Params>, task?: PromiseTask<Result, Params>): Promise<Result | ExecutorError>;
1021
+ /**
1022
+ * Execute asynchronous task with full plugin pipeline
1023
+ *
1024
+ * - Purpose: Primary method for executing async tasks
1025
+ * - Core Concept: Full plugin pipeline execution
1026
+ * - Main Features:
1027
+ * - Plugin hook integration
1028
+ * - Task validation
1029
+ * - Custom execution support
1030
+ * - Primary Use: Running async tasks with plugin support
1031
+ *
1032
+ * Execution flow:
1033
+ * 1. Validate and prepare task
1034
+ * 2. Check for custom execution plugins
1035
+ * 3. Execute task with plugin pipeline
1036
+ *
1037
+ * @template T - Type of task return value
1038
+ * @template D - Type of task data
1039
+ * @param dataOrTask - Task data or task function
1040
+ * @param task - Task function (optional)
1041
+ * @throws {Error} When task is not an async function
1042
+ * @returns Promise resolving to task result
1043
+ *
1044
+ * @example
1045
+ * ```typescript
1046
+ * // With separate data and task
1047
+ * const data = { userId: 123 };
1048
+ * const result = await executor.exec(data, async (input) => {
1049
+ * return await fetchUserData(input.userId);
1050
+ * });
1051
+ *
1052
+ * // With combined task
1053
+ * const result = await executor.exec(async () => {
1054
+ * return await fetchData();
1055
+ * });
1056
+ * ```
1057
+ */
1058
+ exec<Result, Params = unknown>(dataOrTask: Params | PromiseTask<Result, Params>, task?: PromiseTask<Result, Params>): Promise<Result>;
1059
+ /**
1060
+ * Core task execution method with plugin hooks
1061
+ *
1062
+ * - Purpose: Implements the complete execution pipeline
1063
+ * - Core Concept: Sequential hook execution with error handling
1064
+ * - Main Features:
1065
+ * - Before/After hooks
1066
+ * - Error handling hooks
1067
+ * - Result transformation
1068
+ * - Primary Use: Internal pipeline orchestration
1069
+ *
1070
+ * Pipeline stages:
1071
+ * 1. onBefore hooks - Pre-process input data
1072
+ * 2. Task execution - Run the actual task
1073
+ * 3. onSuccess hooks - Post-process results
1074
+ * 4. onError hooks - Handle any errors
1075
+ *
1076
+ * @template T - Type of task return value
1077
+ * @template D - Type of task data
1078
+ * @param data - Input data for the task
1079
+ * @param actualTask - Task function to execute
1080
+ * @throws {ExecutorError} When task execution fails
1081
+ * @returns Promise resolving to task result(context.returnValue)
1082
+ *
1083
+ * @example
1084
+ * ```typescript
1085
+ * private async run(data, task) {
1086
+ * try {
1087
+ * const preparedData = await this.runHook(this.plugins, 'onBefore', data);
1088
+ * const result = await task(preparedData);
1089
+ * return await this.runHook(this.plugins, 'onSuccess', result);
1090
+ * } catch (error) {
1091
+ * const handledError = await this.runHook(
1092
+ * this.plugins,
1093
+ * 'onError',
1094
+ * error,
1095
+ * data
1096
+ * );
1097
+ * throw new ExecutorError('EXECUTION_FAILED', handledError);
1098
+ * }
1099
+ * }
1100
+ * ```
1101
+ */
1102
+ run<Result, Params = unknown>(data: Params, actualTask: PromiseTask<Result, Params>): Promise<Result>;
1103
+ }
1104
+
1105
+ /**
1106
+ * Synchronous executor class that extends the base Executor
1107
+ * Provides synchronous task execution with plugin support
1108
+ *
1109
+ * Key features:
1110
+ * 1. Synchronous plugin hook execution
1111
+ * 2. No Promise-based operations
1112
+ * 3. Immediate error handling
1113
+ * 4. Direct execution flow
1114
+ *
1115
+ * Use this executor when:
1116
+ * 1. All operations are synchronous
1117
+ * 2. You need immediate results
1118
+ * 3. Performance is critical
1119
+ * 4. No async operations are involved
1120
+ *
1121
+ * @extends Executor
1122
+ *
1123
+ * @example
1124
+ * ```typescript
1125
+ * // Create a sync executor
1126
+ * const executor = new SyncExecutor();
1127
+ *
1128
+ * // Add plugins for different purposes
1129
+ * executor.use(new ValidationPlugin());
1130
+ * executor.use(new LoggerPlugin());
1131
+ *
1132
+ * // Example 1: Basic sync task execution
1133
+ * const result = executor.exec((data) => {
1134
+ * return data.toUpperCase();
1135
+ * });
1136
+ *
1137
+ * // Example 2: Execution with input data
1138
+ * const data = { value: 'hello' };
1139
+ * const result = executor.exec(data, (input) => {
1140
+ * return input.value.toUpperCase();
1141
+ * });
1142
+ *
1143
+ * // Example 3: Error handling with execNoError
1144
+ * const result = executor.execNoError(() => {
1145
+ * throw new Error('Validation Error');
1146
+ * }); // Returns ExecutorError instead of throwing
1147
+ * ```
1148
+ * @category SyncExecutor
1149
+ */
1150
+ declare class SyncExecutor<ExecutorConfig = unknown> extends Executor<ExecutorConfig> {
1151
+ /**
1152
+ * Execute plugin hook functions synchronously
1153
+ * Manages the plugin execution chain and handles results
1154
+ *
1155
+ * Plugin execution flow:
1156
+ * 1. Check if plugin is enabled for the hook
1157
+ * 2. Execute plugin hook if available
1158
+ * 3. Handle plugin results and chain breaking conditions
1159
+ *
1160
+ * Key differences from AsyncExecutor:
1161
+ * - All operations are synchronous
1162
+ * - Results are immediately available
1163
+ * - No await statements needed
1164
+ *
1165
+ * @param plugins - Array of plugins to execute
1166
+ * @param hookName - Name of the hook function to execute
1167
+ * @param args - Arguments to pass to the hook function
1168
+ * @returns Result of the hook function execution
1169
+ *
1170
+ * @example
1171
+ * ```typescript
1172
+ * // Internal usage example
1173
+ * const result = this.runHook(
1174
+ * this.plugins,
1175
+ * 'onBefore',
1176
+ * { value: 'test' }
1177
+ * );
1178
+ * ```
1179
+ */
1180
+ runHooks<Params>(plugins: ExecutorPlugin[],
1181
+ /**
1182
+ * allow any string as hook name.
1183
+ * if the hook name is not a function, it will be skipped
1184
+ *
1185
+ * @since 1.1.3
1186
+ */
1187
+ hookName: string, context?: ExecutorContext<Params>, ...args: unknown[]): Params;
1188
+ /**
1189
+ * Execute task without throwing errors
1190
+ * Wraps all errors in ExecutorError for safe error handling
1191
+ *
1192
+ * Advantages over try-catch:
1193
+ * 1. Standardized error handling
1194
+ * 2. No exception propagation
1195
+ * 3. Consistent error types
1196
+ *
1197
+ * @template T - Type of task return value
1198
+ * @param dataOrTask - Task data or task function
1199
+ * @param task - Task function (optional)
1200
+ * @returns Task result or ExecutorError
1201
+ *
1202
+ * @example
1203
+ * ```typescript
1204
+ * const result = executor.execNoError((data) => {
1205
+ * if (!data.isValid) {
1206
+ * throw new Error('Invalid data');
1207
+ * }
1208
+ * return data.value;
1209
+ * });
1210
+ *
1211
+ * if (result instanceof ExecutorError) {
1212
+ * console.log('Task failed:', result.message);
1213
+ * } else {
1214
+ * console.log('Task succeeded:', result);
1215
+ * }
1216
+ * ```
1217
+ */
1218
+ execNoError<Result, Params = unknown>(dataOrTask: Params | SyncTask<Result, Params>, task?: SyncTask<Result, Params>): Result | ExecutorError;
1219
+ /**
1220
+ * Execute synchronous task with full plugin pipeline
1221
+ * Core method for task execution with plugin support
1222
+ *
1223
+ * Execution flow:
1224
+ * 1. Validate and prepare task
1225
+ * 2. Check for custom execution plugins
1226
+ * 3. Execute task with plugin pipeline
1227
+ *
1228
+ * Performance considerations:
1229
+ * - No async overhead
1230
+ * - Direct execution path
1231
+ * - Immediate results
1232
+ *
1233
+ * @template T - Type of task return value
1234
+ * @template D - Type of task data
1235
+ * @param dataOrTask - Task data or task function
1236
+ * @param task - Task function (optional)
1237
+ * @throws {Error} When task is not a function
1238
+ * @returns Task execution result
1239
+ *
1240
+ * @example
1241
+ * ```typescript
1242
+ * // Example with data transformation
1243
+ * const data = { numbers: [1, 2, 3] };
1244
+ * const task = (input) => {
1245
+ * return input.numbers.map(n => n * 2);
1246
+ * };
1247
+ *
1248
+ * const result = executor.exec(data, task);
1249
+ *
1250
+ * // Example with validation
1251
+ * const result = executor.exec((data) => {
1252
+ * if (typeof data !== 'string') {
1253
+ * throw new Error('Data must be string');
1254
+ * }
1255
+ * return data.trim();
1256
+ * });
1257
+ * ```
1258
+ */
1259
+ exec<Result, Params = unknown>(dataOrTask: Params | SyncTask<Result, Params>, task?: SyncTask<Result, Params>): Result;
1260
+ /**
1261
+ * Core method to run synchronous task with plugin hooks
1262
+ * Implements the complete execution pipeline with all plugin hooks
1263
+ *
1264
+ * Pipeline stages:
1265
+ * 1. onBefore hooks - Pre-process input data
1266
+ * 2. Task execution - Run the actual task
1267
+ * 3. onSuccess hooks - Post-process results
1268
+ * 4. onError hooks - Handle any errors
1269
+ *
1270
+ * Error handling strategy:
1271
+ * - Catches all errors
1272
+ * - Passes errors through plugin chain
1273
+ * - Wraps unhandled errors in ExecutorError
1274
+ *
1275
+ * @template T - Type of task return value
1276
+ * @template D - Type of task data
1277
+ * @param data - Data to pass to the task
1278
+ * @param actualTask - Actual task function to execute
1279
+ * @throws {ExecutorError} When task execution fails
1280
+ * @returns Task execution result
1281
+ *
1282
+ * @example
1283
+ * ```typescript
1284
+ * // Internal implementation example
1285
+ * private run(data, task) {
1286
+ * try {
1287
+ * const preparedData = this.runHook(this.plugins, 'onBefore', data);
1288
+ * const result = task(preparedData);
1289
+ * return this.runHook(this.plugins, 'onSuccess', result);
1290
+ * } catch (error) {
1291
+ * const handledError = this.runHook(
1292
+ * this.plugins,
1293
+ * 'onError',
1294
+ * error,
1295
+ * data
1296
+ * );
1297
+ * // Error handling logic
1298
+ * }
1299
+ * }
1300
+ * ```
1301
+ */
1302
+ run<Result, Params = unknown>(data: Params, actualTask: SyncTask<Result, Params>): Result;
1303
+ }
1304
+
1305
+ /**
1306
+ * Configuration options for the RetryPlugin
1307
+ *
1308
+ * This interface defines the configuration options for the RetryPlugin,
1309
+ * which is used to control the retry behavior of task executions.
1310
+ *
1311
+ * - Core Idea: Provide a flexible configuration for retry logic.
1312
+ * - Main Function: Define retry parameters such as max retries, delay, and conditions.
1313
+ * - Main Purpose: Allow customization of retry behavior to suit different use cases.
1314
+ *
1315
+ * @category RetryPlugin
1316
+ *
1317
+ * @example
1318
+ * ```typescript
1319
+ * const options: RetryOptions = {
1320
+ * maxRetries: 5,
1321
+ * retryDelay: 2000,
1322
+ * useExponentialBackoff: true,
1323
+ * shouldRetry: (error) => error.message !== 'Invalid credentials'
1324
+ * };
1325
+ * ```
1326
+ */
1327
+ interface RetryOptions {
1328
+ /**
1329
+ * Maximum number of retry attempts (starting from 0)
1330
+ * Will be clamped between 1 and SAFE_MAX_RETRIES (16)
1331
+ * @default 3
1332
+ */
1333
+ maxRetries: number;
1334
+ /**
1335
+ * Base delay between retry attempts in milliseconds
1336
+ * Used directly for fixed delay, or as base for exponential backoff
1337
+ * @default 1000
1338
+ */
1339
+ retryDelay: number;
1340
+ /**
1341
+ * When true, implements exponential backoff delay strategy
1342
+ * Delay formula: retryDelay * (2 ^ attemptNumber)
1343
+ * @default false
1344
+ */
1345
+ useExponentialBackoff: boolean;
1346
+ /**
1347
+ * Custom function to determine if a retry should be attempted
1348
+ * @param error - The error that caused the failure
1349
+ * @returns boolean indicating if retry should be attempted
1350
+ * @default () => true (always retry)
1351
+ */
1352
+ shouldRetry: (error: Error) => boolean;
1353
+ }
1354
+ /**
1355
+ * Plugin that implements retry logic for failed task executions
1356
+ *
1357
+ * This class provides a mechanism to retry failed tasks with configurable
1358
+ * options such as maximum retries, delay strategies, and custom retry conditions.
1359
+ *
1360
+ * - Core Idea: Enhance task execution reliability through retries.
1361
+ * - Main Function: Retry failed tasks based on specified conditions and strategies.
1362
+ * - Main Purpose: Improve success rates of task executions by handling transient errors.
1363
+ *
1364
+ * @implements {ExecutorPlugin}
1365
+ *
1366
+ * @example
1367
+ * ```typescript
1368
+ * const retryPlugin = new RetryPlugin({
1369
+ * maxRetries: 5,
1370
+ * retryDelay: 2000,
1371
+ * useExponentialBackoff: true,
1372
+ * shouldRetry: (error) => error.message !== 'Invalid credentials'
1373
+ * });
1374
+ * ```
1375
+ *
1376
+ * @category RetryPlugin
1377
+ */
1378
+ declare class RetryPlugin implements ExecutorPlugin {
1379
+ /**
1380
+ * The pluginName of the plugin
1381
+ */
1382
+ readonly pluginName = "RetryPlugin";
1383
+ /**
1384
+ * Ensures only one instance of RetryPlugin is used per executor
1385
+ */
1386
+ readonly onlyOne = true;
1387
+ /**
1388
+ * Normalized options with defaults applied
1389
+ */
1390
+ private readonly options;
1391
+ /**
1392
+ * Constructs a new instance of RetryPlugin with specified options.
1393
+ *
1394
+ * This constructor initializes the RetryPlugin with user-defined options,
1395
+ * applying default values where necessary and clamping the maxRetries value.
1396
+ *
1397
+ * @param options - Partial configuration options for retry behavior
1398
+ *
1399
+ * @example
1400
+ * ```typescript
1401
+ * const retryPlugin = new RetryPlugin({
1402
+ * maxRetries: 5,
1403
+ * retryDelay: 2000,
1404
+ * useExponentialBackoff: true
1405
+ * });
1406
+ * ```
1407
+ */
1408
+ constructor(options?: Partial<RetryOptions>);
1409
+ /**
1410
+ * Implements delay between retry attempts
1411
+ *
1412
+ * This method calculates and applies a delay between retry attempts,
1413
+ * using either a fixed delay or an exponential backoff strategy.
1414
+ *
1415
+ * @param attempt - Current attempt number
1416
+ * @returns Promise that resolves after the delay
1417
+ *
1418
+ * @example
1419
+ * ```typescript
1420
+ * await this.delay(2); // Applies delay for the third attempt
1421
+ * ```
1422
+ */
1423
+ private delay;
1424
+ /**
1425
+ * Custom execution hook that implements retry logic
1426
+ *
1427
+ * This method intercepts task execution to add retry capability,
1428
+ * executing the task with the configured retry logic.
1429
+ *
1430
+ * @template T - Type of task return value
1431
+ * @param task - Task to be executed with retry support
1432
+ * @returns Promise resolving to task result
1433
+ *
1434
+ * @example
1435
+ * ```typescript
1436
+ * const result = await retryPlugin.onExec(() => fetchData());
1437
+ * ```
1438
+ */
1439
+ onExec(context: ExecutorContext<unknown>, task: PromiseTask<unknown, unknown>): Promise<unknown>;
1440
+ /**
1441
+ * Determines if another retry attempt should be made
1442
+ *
1443
+ * This method checks if a retry should be attempted based on the
1444
+ * remaining retry count and a custom retry condition function.
1445
+ *
1446
+ * @param error - Error from failed attempt
1447
+ * @param retryCount - Number of retries remaining
1448
+ * @returns boolean indicating if retry should be attempted
1449
+ *
1450
+ * @example
1451
+ * ```typescript
1452
+ * if (this.shouldRetry({ error, retryCount })) {
1453
+ * // Proceed with retry
1454
+ * }
1455
+ * ```
1456
+ */
1457
+ private shouldRetry;
1458
+ /**
1459
+ * Core retry implementation
1460
+ *
1461
+ * This method recursively attempts to execute the task until it succeeds
1462
+ * or the maximum number of retries is reached, applying the configured delay strategy.
1463
+ *
1464
+ * @template T - Type of task return value
1465
+ * @param fn - Function to retry
1466
+ * @param options - Retry configuration options
1467
+ * @param retryCount - Number of retries remaining
1468
+ * @throws {ExecutorError} When all retry attempts fail
1469
+ * @returns Promise resolving to task result
1470
+ *
1471
+ * @example
1472
+ * ```typescript
1473
+ * const result = await this.retry(fetchData, options, 3);
1474
+ * ```
1475
+ */
1476
+ retry<Result, Params = unknown>(fn: PromiseTask<Result, Params>, context: ExecutorContext<Params>, options: RetryOptions, retryCount: number): Promise<Result | undefined>;
1477
+ }
1478
+
1479
+ /**
1480
+ * Available log levels
1481
+ * Used to categorize and control log output
1482
+ */
1483
+ declare const LEVELS: {
1484
+ readonly LOG: "LOG";
1485
+ readonly INFO: "INFO";
1486
+ readonly ERROR: "ERROR";
1487
+ readonly WARN: "WARN";
1488
+ readonly DEBUG: "DEBUG";
1489
+ };
1490
+ type LogLevel = (typeof LEVELS)[keyof typeof LEVELS];
1491
+ type LogArgument = unknown;
1492
+ /**
1493
+ * Options for execution logging
1494
+ * @interface ExecOptions
1495
+ */
1496
+ type ExecOptions = {
1497
+ /** When true, commands are only logged but not executed */
1498
+ isDryRun?: boolean;
1499
+ /** When true, indicates the command is from an external source */
1500
+ isExternal?: boolean;
1501
+ };
1502
+ /**
1503
+ * Logger class providing various logging methods
1504
+ *
1505
+ * The Logger class supports multiple log levels and can be configured
1506
+ * to operate in different environments such as CI, dry run, debug, and silent modes.
1507
+ *
1508
+ * - Core Idea: Provide a flexible and configurable logging utility.
1509
+ * - Main Function: Log messages at different levels with optional environment-specific behavior.
1510
+ * - Main Purpose: Facilitate debugging and monitoring by providing structured log output.
1511
+ *
1512
+ * @class Logger
1513
+ * @example
1514
+ * ```typescript
1515
+ * // Create a logger instance
1516
+ * const logger = new Logger({ debug: true });
1517
+ *
1518
+ * // Log messages at different levels
1519
+ * logger.info('This is an info message');
1520
+ * logger.error('This is an error message');
1521
+ * logger.debug('This is a debug message');
1522
+ * ```
1523
+ */
1524
+ declare class Logger {
1525
+ protected isCI: boolean;
1526
+ protected isDryRun: boolean;
1527
+ protected isDebug: boolean;
1528
+ protected isSilent: boolean;
1529
+ /**
1530
+ * Creates a new Logger instance
1531
+ *
1532
+ * This constructor initializes the Logger with configuration options
1533
+ * that determine its behavior in different environments.
1534
+ *
1535
+ * @param options - Logger configuration options
1536
+ * @param {boolean} options.isCI - Whether running in CI environment
1537
+ * @param {boolean} options.dryRun - Whether to perform dry run only
1538
+ * @param {boolean} options.debug - Whether to enable debug output
1539
+ * @param {boolean} options.silent - Whether to suppress all output
1540
+ *
1541
+ * @example
1542
+ * ```typescript
1543
+ * const logger = new Logger({ isCI: true, debug: true });
1544
+ * ```
1545
+ */
1546
+ constructor({ isCI, dryRun, debug, silent }?: {
1547
+ isCI?: boolean | undefined;
1548
+ dryRun?: boolean | undefined;
1549
+ debug?: boolean | undefined;
1550
+ silent?: boolean | undefined;
1551
+ });
1552
+ /**
1553
+ * Core logging method
1554
+ * Handles actual console output based on configuration
1555
+ *
1556
+ * @param level - Log level for the message
1557
+ * @param args - Arguments to log
1558
+ *
1559
+ * @example
1560
+ * ```typescript
1561
+ * this.print(LEVELS.INFO, 'Information message');
1562
+ * ```
1563
+ */
1564
+ protected print(_level: LogLevel, ...args: LogArgument[]): void;
1565
+ /**
1566
+ * Adds prefix to log messages
1567
+ * Can be overridden to customize log format
1568
+ *
1569
+ * @param value - The prefix value
1570
+ * @param _level - Log level (optional)
1571
+ * @returns Formatted prefix string or array
1572
+ *
1573
+ * @example
1574
+ * ```typescript
1575
+ * const prefix = this.prefix('INFO');
1576
+ * ```
1577
+ */
1578
+ prefix(value: string, _level?: LogLevel): string | string[];
1579
+ /**
1580
+ * Basic log output
1581
+ *
1582
+ * @param args - Values to log
1583
+ *
1584
+ * @example
1585
+ * ```typescript
1586
+ * logger.log('This is a log message');
1587
+ * ```
1588
+ */
1589
+ log(...args: LogArgument[]): void;
1590
+ /**
1591
+ * Informational log output
1592
+ *
1593
+ * @param args - Values to log
1594
+ *
1595
+ * @example
1596
+ * ```typescript
1597
+ * logger.info('This is an info message');
1598
+ * ```
1599
+ */
1600
+ info(...args: LogArgument[]): void;
1601
+ /**
1602
+ * Warning log output
1603
+ *
1604
+ * @param args - Values to log
1605
+ *
1606
+ * @example
1607
+ * ```typescript
1608
+ * logger.warn('This is a warning message');
1609
+ * ```
1610
+ */
1611
+ warn(...args: LogArgument[]): void;
1612
+ /**
1613
+ * Error log output
1614
+ *
1615
+ * @param args - Values to log
1616
+ *
1617
+ * @example
1618
+ * ```typescript
1619
+ * logger.error('This is an error message');
1620
+ * ```
1621
+ */
1622
+ error(...args: LogArgument[]): void;
1623
+ /**
1624
+ * Debug log output
1625
+ *
1626
+ * - Only active when debug mode is enabled
1627
+ * - Formats objects as JSON strings
1628
+ *
1629
+ * @param args - Values to log
1630
+ *
1631
+ * @example
1632
+ * ```typescript
1633
+ * logger.debug('This is a debug message');
1634
+ * ```
1635
+ */
1636
+ debug(...args: LogArgument[]): void;
1637
+ /**
1638
+ * Verbose log output
1639
+ *
1640
+ * - Only active when debug mode is enabled
1641
+ * - Uses purple color for output
1642
+ *
1643
+ * @param args - Values to log
1644
+ *
1645
+ * @example
1646
+ * ```typescript
1647
+ * logger.verbose('This is a verbose message');
1648
+ * ```
1649
+ */
1650
+ verbose(...args: LogArgument[]): void;
1651
+ /**
1652
+ * Command execution logging
1653
+ * Supports dry run mode and external command indication
1654
+ *
1655
+ * @param args - Command arguments and options
1656
+ *
1657
+ * @example
1658
+ * ```typescript
1659
+ * logger.exec('npm', 'install', { isDryRun: true });
1660
+ * logger.exec(['git', 'commit', '-m', 'feat: update'], { isExternal: true });
1661
+ * ```
1662
+ */
1663
+ exec(...args: (LogArgument | ExecOptions)[]): void;
1664
+ /**
1665
+ * Obtrusive log output
1666
+ * Adds extra line breaks in non-CI environments
1667
+ *
1668
+ * @param args - Values to log
1669
+ *
1670
+ * @example
1671
+ * ```typescript
1672
+ * logger.obtrusive('This is an important message');
1673
+ * ```
1674
+ */
1675
+ obtrusive(...args: LogArgument[]): void;
1676
+ }
1677
+
1678
+ /**
1679
+ * Request adapter fetch configuration
1680
+ *
1681
+ * This type defines the configuration options for a request adapter.
1682
+ * It includes properties for URL, method, headers, and other request details.
1683
+ * The main purpose is to provide a flexible structure for configuring HTTP requests.
1684
+ *
1685
+ * @since 1.0.14
1686
+ */
1687
+ type RequestAdapterFetchConfig<Request = unknown> = Omit<globalThis.RequestInit, 'headers'> & RequestAdapterConfig<Request> & {
1688
+ fetcher?: typeof fetch;
1689
+ onStreamProgress?: (progress: number) => void;
1690
+ signal?: AbortSignal;
1691
+ onAbort?(config: RequestAdapterFetchConfig): void;
1692
+ };
1693
+ declare class RequestAdapterFetch implements RequestAdapterInterface<RequestAdapterFetchConfig> {
1694
+ readonly config: RequestAdapterFetchConfig;
1695
+ private executor;
1696
+ /**
1697
+ * Creates a new FetchRequest instance
1698
+ * Automatically detects and configures fetch implementation
1699
+ *
1700
+ * - Core Idea: Simplify HTTP requests with built-in fetch support.
1701
+ * - Main Function: Initialize fetch requests with optional configuration.
1702
+ * - Main Purpose: Provide a flexible and extensible HTTP request utility.
1703
+ *
1704
+ * @param config - Request configuration options
1705
+ * @throws {FetchRequestError} When fetch is not available
1706
+ *
1707
+ * @example
1708
+ * ```typescript
1709
+ * const fetchRequest = new FetchRequest({ baseURL: 'https://api.example.com' });
1710
+ * ```
1711
+ */
1712
+ constructor(config?: Partial<RequestAdapterFetchConfig>);
1713
+ getConfig(): RequestAdapterFetchConfig;
1714
+ usePlugin(plugin: ExecutorPlugin): void;
1715
+ /**
1716
+ * Core request implementation
1717
+ * Merges configurations and executes fetch request
1718
+ *
1719
+ * - Core Idea: Execute HTTP requests with merged configurations.
1720
+ * - Main Function: Perform fetch requests using provided configurations.
1721
+ * - Main Purpose: Facilitate HTTP communication with error handling.
1722
+ *
1723
+ * @override
1724
+ * @param config - Request configuration
1725
+ * @returns Promise resolving to Response object
1726
+ * @throws {FetchRequestError} When fetcher is not available
1727
+ *
1728
+ * @example
1729
+ * ```typescript
1730
+ * const response = await fetchRequest.request({ url: '/data' });
1731
+ * ```
1732
+ */
1733
+ request<Request, Response>(config: RequestAdapterFetchConfig<Request>): Promise<RequestAdapterResponse<Request, Response>>;
1734
+ parametersToRequest(parameters: RequestAdapterFetchConfig): Request;
1735
+ /**
1736
+ * Converts the raw fetch response into a standardized adapter response.
1737
+ *
1738
+ * @param data The data extracted from the response based on the response type.
1739
+ * @param response The original fetch Response object.
1740
+ * @param config The configuration used for the fetch request.
1741
+ * @returns A RequestAdapterResponse containing the processed response data.
1742
+ */
1743
+ toAdapterResponse<Request>(data: unknown, response: Response, config: RequestAdapterFetchConfig<Request>): RequestAdapterResponse<Request>;
1744
+ /**
1745
+ * Extracts headers from the fetch Response object and returns them as a record.
1746
+ *
1747
+ * @param response The fetch Response object from which headers are extracted.
1748
+ * @returns A record of headers with header names as keys and header values as values.
1749
+ */
1750
+ getResponseHeaders(response: Response): Record<string, string>;
1751
+ }
1752
+
1753
+ /**
1754
+ * Axios request adapter
1755
+ *
1756
+ * Only base config is supported
1757
+ *
1758
+ * @since 1.0.14
1759
+ */
1760
+ declare class RequestAdapterAxios implements RequestAdapterInterface<AxiosRequestConfig> {
1761
+ readonly config: AxiosRequestConfig;
1762
+ private axiosInstance;
1763
+ constructor(axios: AxiosStatic, config?: AxiosRequestConfig);
1764
+ getConfig(): AxiosRequestConfig;
1765
+ request<Request, Response>(config: AxiosRequestConfig<Request>): Promise<RequestAdapterResponse<Request, Response>>;
1766
+ }
1767
+
1768
+ /**
1769
+ * Plugin for handling request cancellation
1770
+ * Provides abort functionality for fetch requests
1771
+ *
1772
+ * - Core Idea: Enhance request management with cancellation capabilities.
1773
+ * - Main Function: Allow requests to be aborted programmatically.
1774
+ * - Main Purpose: Improve control over network requests and resource management.
1775
+ *
1776
+ * Features:
1777
+ * - Request cancellation support
1778
+ * - Automatic cleanup of aborted requests
1779
+ * - Multiple concurrent request handling
1780
+ * - Custom abort callbacks
1781
+ *
1782
+ * **Not Support**
1783
+ * - Abort signal from outside
1784
+ *
1785
+ * Request parameters serialized to be used as unique identifiers.
1786
+ * Or you can pass in a specific requestid.
1787
+ *
1788
+ * You can also manually specify an onAbort callback that will be executed after termination.
1789
+ *
1790
+ * @implements {ExecutorPlugin}
1791
+ *
1792
+ * @example
1793
+ * ```typescript
1794
+ * // Basic usage
1795
+ * const abortPlugin = new AbortPlugin();
1796
+ * const client = new FetchRequest();
1797
+ * client.executor.use(abortPlugin);
1798
+ *
1799
+ * // Abort specific request
1800
+ * const config = { url: '/api/data' };
1801
+ * abortPlugin.abort(config);
1802
+ *
1803
+ * // Abort all pending requests
1804
+ * abortPlugin.abortAll();
1805
+ * ```
1806
+ *
1807
+ * @example
1808
+ *
1809
+ * Use RequestId to identify the request
1810
+ *
1811
+ * ```typescript
1812
+ * const abortPlugin = new AbortPlugin();
1813
+ * const client = new FetchRequest();
1814
+ * client.executor.use(abortPlugin);
1815
+ *
1816
+ * // Abort specific request
1817
+ * const config = { url: '/api/data', requestId: '123' };
1818
+ * abortPlugin.abort(config);
1819
+ * // or
1820
+ * abortPlugin.abort('123');
1821
+ * ```
1822
+ */
1823
+ declare class FetchAbortPlugin implements ExecutorPlugin {
1824
+ readonly pluginName = "FetchAbortPlugin";
1825
+ readonly onlyOne = true;
1826
+ /**
1827
+ * Map to store active AbortControllers
1828
+ * Keys are generated from request config
1829
+ */
1830
+ private controllers;
1831
+ /**
1832
+ * Generates unique key for request identification
1833
+ * Combines method, URL, params, and body to create unique identifier
1834
+ *
1835
+ * @param config - Request configuration
1836
+ * @returns Unique request identifier
1837
+ *
1838
+ * @example
1839
+ * ```typescript
1840
+ * const key = abortPlugin.generateRequestKey(config);
1841
+ * ```
1842
+ */
1843
+ private generateRequestKey;
1844
+ /**
1845
+ * Pre-request hook that sets up abort handling
1846
+ * Creates new AbortController and cancels any existing request with same key
1847
+ *
1848
+ * @param config - Request configuration
1849
+ * @returns Modified configuration with abort control
1850
+ *
1851
+ * @example
1852
+ * ```typescript
1853
+ * const modifiedConfig = abortPlugin.onBefore(config);
1854
+ * ```
1855
+ */
1856
+ onBefore(context: ExecutorContext<RequestAdapterConfig>): void;
1857
+ onSuccess({ parameters }: ExecutorContext<RequestAdapterConfig>): void;
1858
+ /**
1859
+ * Error handling hook for abort scenarios
1860
+ * Processes different types of abort errors and cleans up resources
1861
+ *
1862
+ * @param error - Original error
1863
+ * @param config - Request configuration
1864
+ * @returns RequestError or void
1865
+ *
1866
+ * @example
1867
+ * ```typescript
1868
+ * const error = abortPlugin.onError(new Error('AbortError'), config);
1869
+ * ```
1870
+ */
1871
+ onError({ error, parameters }: ExecutorContext<RequestAdapterConfig>): RequestError | void;
1872
+ /**
1873
+ * Determines if the given error is an abort error.
1874
+ *
1875
+ * - Identify errors that are related to request abortion.
1876
+ * - Check error properties to determine if it's an abort error.
1877
+ * - Provide a unified method to recognize abort errors.
1878
+ *
1879
+ * @param error - The error to check
1880
+ * @returns True if the error is an abort error, false otherwise
1881
+ *
1882
+ */
1883
+ isSameAbortError(error?: Error): boolean;
1884
+ /**
1885
+ * Aborts a specific request
1886
+ * Triggers abort callback if provided
1887
+ *
1888
+ * @param config - Configuration of request to abort
1889
+ *
1890
+ * @example
1891
+ * ```typescript
1892
+ * abortPlugin.abort({
1893
+ * url: '/api/data',
1894
+ * onAbort: (config) => {
1895
+ * console.log('Request aborted:', config.url);
1896
+ * }
1897
+ * });
1898
+ * ```
1899
+ */
1900
+ abort(config: RequestAdapterConfig | string): void;
1901
+ /**
1902
+ * Aborts all pending requests
1903
+ * Clears all stored controllers
1904
+ *
1905
+ * @example
1906
+ * ```typescript
1907
+ * // Cancel all requests when component unmounts
1908
+ * useEffect(() => {
1909
+ * return () => abortPlugin.abortAll();
1910
+ * }, []);
1911
+ * ```
1912
+ */
1913
+ abortAll(): void;
1914
+ }
1915
+
1916
+ /**
1917
+ * Plugin for URL manipulation and response handling
1918
+ * Provides URL composition and response status checking
1919
+ *
1920
+ * - Core Idea: Simplify URL handling and response validation.
1921
+ * - Main Function: Manage URL construction and check response status.
1922
+ * - Main Purpose: Ensure correct URL formation and response handling.
1923
+ *
1924
+ * Features:
1925
+ * - URL normalization
1926
+ * - Base URL handling
1927
+ * - Query parameter management
1928
+ * - Response status validation
1929
+ *
1930
+ * @implements {ExecutorPlugin}
1931
+ *
1932
+ * @example
1933
+ * ```typescript
1934
+ * // Basic usage
1935
+ * const urlPlugin = new FetchURLPlugin();
1936
+ * const client = new FetchRequest();
1937
+ * client.executor.use(urlPlugin);
1938
+ *
1939
+ * // Request with base URL and params
1940
+ * await client.get({
1941
+ * baseURL: 'https://api.example.com',
1942
+ * url: '/users',
1943
+ * params: { role: 'admin' }
1944
+ * });
1945
+ * ```
1946
+ */
1947
+ declare class FetchURLPlugin implements ExecutorPlugin {
1948
+ readonly pluginName = "FetchURLPlugin";
1949
+ /**
1950
+ * Checks if URL is absolute (starts with http:// or https://)
1951
+ *
1952
+ * @param url - URL to check
1953
+ * @returns Boolean indicating if URL is absolute
1954
+ *
1955
+ * @example
1956
+ * ```typescript
1957
+ * const isAbsolute = urlPlugin.isFullURL('https://example.com');
1958
+ * ```
1959
+ */
1960
+ isFullURL(url: string): boolean;
1961
+ /**
1962
+ * Appends query parameters to URL
1963
+ * Handles existing query parameters in URL
1964
+ *
1965
+ * @param url - Base URL
1966
+ * @param params - Parameters to append
1967
+ * @returns URL with query parameters
1968
+ *
1969
+ * @example
1970
+ * ```typescript
1971
+ * const url = urlPlugin.appendQueryParams(
1972
+ * 'https://api.example.com/users',
1973
+ * { role: 'admin', status: 'active' }
1974
+ * );
1975
+ * ```
1976
+ */
1977
+ appendQueryParams(url: string, params?: Record<string, unknown>): string;
1978
+ /**
1979
+ * Combines base URL with path.
1980
+ *
1981
+ * Ensures proper slash handling
1982
+ *
1983
+ * @param url - URL path
1984
+ * @param baseURL - Base URL
1985
+ * @returns Combined URL
1986
+ *
1987
+ * @example
1988
+ * ```typescript
1989
+ * const fullUrl = urlPlugin.connectBaseURL('/users', 'https://api.example.com');
1990
+ * ```
1991
+ */
1992
+ connectBaseURL(url: string, baseURL: string): string;
1993
+ /**
1994
+ * Builds complete URL from configuration.
1995
+ *
1996
+ * Handles base URL, path normalization, and query parameters.
1997
+ *
1998
+ * @param config - Request configuration
1999
+ * @returns Complete URL
2000
+ *
2001
+ * @example
2002
+ * ```typescript
2003
+ * const completeUrl = urlPlugin.buildUrl(config);
2004
+ * ```
2005
+ */
2006
+ buildUrl(config: RequestAdapterConfig): string;
2007
+ /**
2008
+ * Pre-request hook that builds complete URL
2009
+ *
2010
+ * @param config - Request configuration
2011
+ *
2012
+ * @example
2013
+ * ```typescript
2014
+ * urlPlugin.onBefore(config);
2015
+ * ```
2016
+ */
2017
+ onBefore({ parameters }: ExecutorContext<RequestAdapterConfig>): void;
2018
+ /**
2019
+ * Success hook that validates response status
2020
+ * Throws error for non-OK responses
2021
+ *
2022
+ * @param result - Fetch response
2023
+ * @returns Response if OK
2024
+ * @throws {RequestError} If response is not OK
2025
+ *
2026
+ * @example
2027
+ * ```typescript
2028
+ * const response = urlPlugin.onSuccess(fetchResponse);
2029
+ * ```
2030
+ */
2031
+ onSuccess({ returnValue }: ExecutorContext): void;
2032
+ /**
2033
+ * Error handling hook
2034
+ * Wraps non-RequestError errors
2035
+ *
2036
+ * @param error - Original error
2037
+ * @returns RequestError
2038
+ *
2039
+ * @example
2040
+ * ```typescript
2041
+ * const error = urlPlugin.onError(new Error('Network Error'));
2042
+ * ```
2043
+ */
2044
+ onError({ error }: ExecutorContext): RequestError;
2045
+ }
2046
+
2047
+ /**
2048
+ * Represents a scheduler for managing HTTP requests.
2049
+ *
2050
+ * This class provides a unified API for making HTTP requests with support for plugins,
2051
+ * streaming responses, and request cancellation. Future enhancements may include caching,
2052
+ * upload/download progress, retries, timeouts, and mock data.
2053
+ *
2054
+ * @since 1.0.14
2055
+ * @example
2056
+ *
2057
+ * Create a Adapter
2058
+ *
2059
+ * ```typescript
2060
+ * class MockRequestAdapter implements RequestAdapterInterface<any> {
2061
+ * config: any;
2062
+ *
2063
+ * constructor(config: any = {}) {
2064
+ * this.config = config;
2065
+ * }
2066
+ *
2067
+ * getConfig(): any {
2068
+ * return this.config;
2069
+ * }
2070
+ * async request<Request, Response>(
2071
+ * config: any
2072
+ * ): Promise<RequestAdapterResponse<Response, Request>> {
2073
+ * const sendConfig = { ...this.config, ...config };
2074
+ * await new Promise((resolve) => setTimeout(resolve, 1000));
2075
+ *
2076
+ * return {
2077
+ * status: 200,
2078
+ * statusText: 'ok',
2079
+ * headers: {},
2080
+ * data: sendConfig.data,
2081
+ * config: sendConfig
2082
+ * };
2083
+ * }
2084
+ *
2085
+ * ```
2086
+ *
2087
+ * @example
2088
+ *
2089
+ * Execute a request using the adapter
2090
+ *
2091
+ * ```typescript
2092
+ * const adapter = new MockRequestAdapter();
2093
+ * const scheduler = new RequestScheduler();
2094
+ * const reqData = 'mock response';
2095
+ * const response = await scheduler.request({ url: '/test', data: reqData });
2096
+ * // => response.data is 'mock response'
2097
+ * ```
2098
+ *
2099
+ * @template Config - The configuration type extending RequestAdapterConfig.
2100
+ */
2101
+ declare class RequestScheduler<Config extends RequestAdapterConfig> {
2102
+ readonly adapter: RequestAdapterInterface<Config>;
2103
+ readonly executor: AsyncExecutor;
2104
+ /**
2105
+ * Initializes a new instance of the RequestScheduler class.
2106
+ *
2107
+ * @since 1.0.14
2108
+ *
2109
+ * @param adapter - The request adapter interface to be used for making requests.
2110
+ */
2111
+ constructor(adapter: RequestAdapterInterface<Config>);
2112
+ /**
2113
+ * Adds a plugin to the request execution process.
2114
+ *
2115
+ * @since 1.0.14
2116
+ *
2117
+ * @param plugin - The plugin to be used by the executor.
2118
+ * @returns The current instance of RequestScheduler for chaining.
2119
+ */
2120
+ usePlugin(plugin: ExecutorPlugin): this;
2121
+ /**
2122
+ * Executes a request with the given configuration.
2123
+ *
2124
+ * @since 1.0.14
2125
+ *
2126
+ * @param config - The configuration for the request.
2127
+ * @returns A promise that resolves to the response of the request.
2128
+ */
2129
+ request<Request, Response>(config: RequestAdapterConfig<Request>): Promise<RequestAdapterResponse<Response, Request>>;
2130
+ /**
2131
+ * Executes a GET request.
2132
+ *
2133
+ * @param config - The configuration for the GET request.
2134
+ * @returns A promise that resolves to the response of the GET request.
2135
+ */
2136
+ get<Request, Response>(url: string, config?: RequestAdapterConfig<Request>): Promise<RequestAdapterResponse<Response, Request>>;
2137
+ /**
2138
+ * Executes a POST request.
2139
+ *
2140
+ * @param config - The configuration for the POST request.
2141
+ * @returns A promise that resolves to the response of the POST request.
2142
+ */
2143
+ post<Request, Response>(url: string, config?: RequestAdapterConfig<Request>): Promise<RequestAdapterResponse<Response, Request>>;
2144
+ /**
2145
+ * Executes a PUT request.
2146
+ *
2147
+ * @param config - The configuration for the PUT request.
2148
+ * @returns A promise that resolves to the response of the PUT request.
2149
+ */
2150
+ put<Request, Response>(url: string, config?: RequestAdapterConfig<Request>): Promise<RequestAdapterResponse<Response, Request>>;
2151
+ /**
2152
+ * Executes a DELETE request.
2153
+ *
2154
+ * @param config - The configuration for the DELETE request.
2155
+ * @returns A promise that resolves to the response of the DELETE request.
2156
+ */
2157
+ delete<Request, Response>(url: string, config?: RequestAdapterConfig<Request>): Promise<RequestAdapterResponse<Response, Request>>;
2158
+ /**
2159
+ * Executes a PATCH request.
2160
+ *
2161
+ * @param config - The configuration for the PATCH request.
2162
+ * @returns A promise that resolves to the response of the PATCH request.
2163
+ */
2164
+ patch<Request, Response>(url: string, config?: RequestAdapterConfig<Request>): Promise<RequestAdapterResponse<Response, Request>>;
2165
+ /**
2166
+ * Executes a HEAD request.
2167
+ *
2168
+ * @param config - The configuration for the HEAD request.
2169
+ * @returns A promise that resolves to the response of the HEAD request.
2170
+ */
2171
+ head<Request, Response>(url: string, config?: RequestAdapterConfig<Request>): Promise<RequestAdapterResponse<Response, Request>>;
2172
+ /**
2173
+ * Executes an OPTIONS request.
2174
+ *
2175
+ * @param config - The configuration for the OPTIONS request.
2176
+ * @returns A promise that resolves to the response of the OPTIONS request.
2177
+ */
2178
+ options<Request, Response>(url: string, config?: RequestAdapterConfig<Request>): Promise<RequestAdapterResponse<Response, Request>>;
2179
+ /**
2180
+ * Executes a TRACE request.
2181
+ *
2182
+ * @param config - The configuration for the TRACE request.
2183
+ * @returns A promise that resolves to the response of the TRACE request.
2184
+ */
2185
+ trace<Request, Response>(url: string, config?: RequestAdapterConfig<Request>): Promise<RequestAdapterResponse<Response, Request>>;
2186
+ /**
2187
+ * Executes a CONNECT request.
2188
+ *
2189
+ * @param config - The configuration for the CONNECT request.
2190
+ * @returns A promise that resolves to the response of the CONNECT request.
2191
+ */
2192
+ connect<Request, Response>(url: string, config?: RequestAdapterConfig<Request>): Promise<RequestAdapterResponse<Response, Request>>;
2193
+ }
2194
+
2195
+ /**
2196
+ * Enhanced JSON serialization implementation that combines standard JSON API with additional features
2197
+ *
2198
+ * Why implement both Serializer and JSON interfaces:
2199
+ * 1. Serializer interface provides a consistent API across different serialization formats
2200
+ * 2. JSON interface maintains compatibility with native JSON methods
2201
+ * 3. Allows seamless integration with both existing JSON code and new serialization patterns
2202
+ *
2203
+ * Enhanced capabilities beyond standard JSON:
2204
+ * 1. Cross-platform line ending normalization (\r\n -> \n)
2205
+ * 2. Built-in pretty printing configuration
2206
+ * 3. Default value support for failed deserialization
2207
+ * 4. Circular reference detection with clear error messages
2208
+ * 5. Type-safe interface with better TypeScript support
2209
+ *
2210
+ * Usage scenarios:
2211
+ * 1. Direct replacement for JSON global object
2212
+ * 2. Part of a pluggable serialization system
2213
+ * 3. Configuration file parsing with error handling
2214
+ * 4. Cross-platform data exchange
2215
+ *
2216
+ * @implements {Serializer<unknown, string>} - Generic serialization interface
2217
+ * @implements {JSON} - Standard JSON interface compatibility
2218
+ * @todo - If circular reference is detected, the error message is not very friendly, can use [flatted](https://www.npmjs.com/package/flatted) to improve it
2219
+ * @since 1.0.10
2220
+ *
2221
+ * @example
2222
+ * ```typescript
2223
+ * const serializer = new JSONSerializer({ pretty: true });
2224
+ *
2225
+ * // Using Serializer interface (with enhanced features)
2226
+ * const serialized = serializer.serialize({ name: "test" });
2227
+ * const deserialized = serializer.deserialize('invalid json', { fallback: true });
2228
+ *
2229
+ * // Using standard JSON API (maintains compatibility)
2230
+ * const json = serializer.stringify({ name: "test" });
2231
+ * const obj = serializer.parse(json);
2232
+ * ```
2233
+ *
2234
+ * @example
2235
+ *
2236
+ * `JSON.parse` may encounter errors, so we use `deserialize` method to handle them, set default value if needed
2237
+ *
2238
+ * ```typescript
2239
+ * const serializer = new JSONSerializer();
2240
+ * serializer.deserialize('invalid json', { fallback: true }); // returns { fallback: true }
2241
+ * ```
2242
+ *
2243
+ * @example
2244
+ * Or, use `JSONSerializer` replace native `JSON` methods
2245
+ *
2246
+ * ```typescript
2247
+ * const JSON = new JSONSerializer();
2248
+ *
2249
+ * JSON.stringify({ name: 'test' }); // same as JSON.stringify({ name: 'test' })
2250
+ * JSON.parse('{ "name": "test" }'); // same as JSON.parse('{ "name": "test" }')
2251
+ * ```
2252
+ */
2253
+ declare class JSONSerializer implements Serializer<unknown, string>, JSON {
2254
+ private options;
2255
+ /**
2256
+ * Implements Symbol.toStringTag to properly identify this class
2257
+ * Required by JSON interface
2258
+ */
2259
+ readonly [Symbol.toStringTag] = "JSONSerializer";
2260
+ constructor(options?: {
2261
+ /**
2262
+ * Enable pretty printing of JSON output
2263
+ * Adds automatic indentation and line breaks for better readability
2264
+ *
2265
+ * @since 1.0.10
2266
+ * @default false
2267
+ */
2268
+ pretty?: boolean;
2269
+ /**
2270
+ * Number of spaces to use for indentation when pretty printing
2271
+ * Only used when pretty is true
2272
+ *
2273
+ * @since 1.0.10
2274
+ * @default 2
2275
+ */
2276
+ indent?: number;
2277
+ /**
2278
+ * Custom replacer function for JSON.stringify
2279
+ * Allows custom transformation during serialization
2280
+ * Note: Will be wrapped to handle line endings
2281
+ *
2282
+ * @since 1.0.10
2283
+ */
2284
+ replacer?: (this: unknown, key: string, value: unknown) => unknown;
2285
+ });
2286
+ /**
2287
+ * Creates a replacer function that handles line endings normalization
2288
+ *
2289
+ * Why normalize line endings:
2290
+ * 1. Ensures consistent output across different platforms (Windows, Unix)
2291
+ * 2. Prevents issues with source control systems
2292
+ * 3. Makes string comparisons reliable
2293
+ *
2294
+ * Handles three cases:
2295
+ * 1. Array replacer - Used for property filtering
2296
+ * 2. Function replacer - Wrapped to handle line endings
2297
+ * 3. Null/undefined - Creates default line ending handler
2298
+ *
2299
+ * @private
2300
+ * @param replacer - Custom replacer function or array of properties to include
2301
+ * @returns Replacer function or array of properties to include
2302
+ * @since 1.0.10
2303
+ */
2304
+ private createReplacer;
2305
+ /**
2306
+ * Enhanced JSON.stringify with additional features
2307
+ *
2308
+ * Enhancements:
2309
+ * 1. Line ending normalization
2310
+ * 2. Configurable pretty printing
2311
+ * 3. Better error messages for circular references
2312
+ * 4. Type-safe replacer handling
2313
+ *
2314
+ * **If circular reference is detected, the error message is not very friendly, can use [flatted](https://www.npmjs.com/package/flatted) to improve it**
2315
+ *
2316
+ * @since 1.0.10
2317
+ * @override
2318
+ * @returns Serialized string
2319
+ */
2320
+ stringify(value: unknown, replacer?: ((this: unknown, key: string, value: unknown) => unknown) | (number | string)[] | null, space?: string | number): string;
2321
+ /**
2322
+ * Standard JSON.parse implementation
2323
+ * Note: Error handling is done in deserialize method
2324
+ *
2325
+ * @since 1.0.10
2326
+ * @override
2327
+ * @returns Parsed value
2328
+ */
2329
+ parse(text: string, reviver?: (this: unknown, key: string, value: unknown) => unknown): unknown;
2330
+ /**
2331
+ * Implements Serializer.serialize
2332
+ * Provides a simplified interface with configured options
2333
+ *
2334
+ * Benefits:
2335
+ * 1. Uses configured pretty printing
2336
+ * 2. Applies custom replacer if specified
2337
+ * 3. Maintains consistent line endings
2338
+ *
2339
+ * @override
2340
+ * @since 1.0.10
2341
+ * @returns Serialized string
2342
+ */
2343
+ serialize(data: unknown): string;
2344
+ /**
2345
+ * Implements Serializer.deserialize with enhanced error handling
2346
+ *
2347
+ * Benefits:
2348
+ * 1. Safe parsing with default value fallback
2349
+ * 2. No try-catch needed in calling code
2350
+ * 3. Predictable error handling
2351
+ *
2352
+ * @override
2353
+ * @since 1.0.10
2354
+ * @returns Parsed value
2355
+ */
2356
+ deserialize(data: string, defaultValue?: unknown): unknown;
2357
+ /**
2358
+ * Optimized serialization for arrays of primitive values
2359
+ * Avoids object property enumeration
2360
+ *
2361
+ * @param arr - Array of primitive values to serialize
2362
+ * @returns JSON array string
2363
+ * @since 1.0.10
2364
+ */
2365
+ serializeArray(arr: (string | number | boolean)[]): string;
2366
+ }
2367
+
2368
+ /**
2369
+ * Base64 serialization implementation
2370
+ * Provides string-to-base64 encoding/decoding with optional compression
2371
+ *
2372
+ * Features:
2373
+ * - Base64 encoding/decoding
2374
+ * - UTF-8 support
2375
+ * - URL-safe encoding option
2376
+ *
2377
+ * @implements {Serializer<string, string>}
2378
+ *
2379
+ * @since 1.0.10
2380
+ *
2381
+ * @example
2382
+ * ```typescript
2383
+ * const serializer = new Base64Serializer({ urlSafe: true });
2384
+ *
2385
+ * // Encode string to base64
2386
+ * const encoded = serializer.stringify("Hello World!");
2387
+ *
2388
+ * // Decode base64 back to string
2389
+ * const decoded = serializer.parse(encoded);
2390
+ * ```
2391
+ */
2392
+ declare class Base64Serializer implements Serializer<string, string> {
2393
+ private options;
2394
+ constructor(options?: {
2395
+ /**
2396
+ * Use URL-safe base64 encoding
2397
+ * @default false
2398
+ *
2399
+ * @since 1.0.10
2400
+ */
2401
+ urlSafe?: boolean;
2402
+ });
2403
+ /**
2404
+ * Serializes string to base64
2405
+ * @override
2406
+ * @since 1.0.10
2407
+ * @param data - String to encode
2408
+ * @returns Base64 encoded string
2409
+ */
2410
+ serialize(data: string): string;
2411
+ /**
2412
+ * Deserializes base64 string back to original
2413
+ * @override
2414
+ * @since 1.0.10
2415
+ * @param data - Base64 string to decode
2416
+ * @param defaultValue - Optional default value if decoding fails
2417
+ * @returns Decoded string
2418
+ */
2419
+ deserialize(data: string, defaultValue?: string): string;
2420
+ /**
2421
+ * Converts standard base64 to URL-safe base64
2422
+ * @since 1.0.10
2423
+ * @param base64 - Standard base64 string
2424
+ * @returns URL-safe base64 string
2425
+ */
2426
+ private makeUrlSafe;
2427
+ /**
2428
+ * Converts URL-safe base64 back to standard base64
2429
+ * @private
2430
+ * @since 1.0.10
2431
+ * @param safe - URL-safe base64 string
2432
+ * @returns Standard base64 string
2433
+ */
2434
+ private makeUrlUnsafe;
2435
+ }
2436
+
2437
+ /**
2438
+ * Represents a storage mechanism for JSON-serializable data.
2439
+ *
2440
+ * This class provides a way to store, retrieve, and manage JSON data
2441
+ * with optional expiration times. It can operate with a provided
2442
+ * synchronous storage backend or use an internal store.
2443
+ *
2444
+ * The main purpose of this class is to facilitate the storage of
2445
+ * complex data structures in a serialized JSON format, allowing
2446
+ * for easy retrieval and management.
2447
+ *
2448
+ * inner serializer is used by default, which is `JSONSerializer`.
2449
+ *
2450
+ * @since 1.0.17
2451
+ *
2452
+ * @example
2453
+ *
2454
+ * A simple example of how to use the JSONStorage class
2455
+ *
2456
+ * ```typescript
2457
+ * const storage = new JSONStorage();
2458
+ * storage.setItem('key', { data: 'value' }, 3600);
2459
+ * const value = storage.getItem('key');
2460
+ * // => { data: 'value' }
2461
+ * ```
2462
+ * @example
2463
+ *
2464
+ * If need persistent storage, you can use `localStorage` or `sessionStorage`
2465
+ *
2466
+ * ```typescript
2467
+ * const storage = new JSONStorage(localStorage);
2468
+ * storage.setItem('key', { data: 'value' }, 3600);
2469
+ * const value = storage.getItem('key');
2470
+ * // => { data: 'value' }
2471
+ * ```
2472
+ *
2473
+ * @example
2474
+ *
2475
+ * Or use custom serializer and storage
2476
+ *
2477
+ * ```typescript
2478
+ * // use native JSON
2479
+ * const customSerializer = {
2480
+ * serialize: JSON.stringify,
2481
+ * deserialize: JSON.parse,
2482
+ * };
2483
+ *
2484
+ * // can use localStorage or sessionStorage
2485
+ * const customStorage = {
2486
+ * setItem: (key: string, value: string) => {
2487
+ * localStorage.setItem(key, value);
2488
+ * },
2489
+ * getItem: (key: string) => {
2490
+ * return localStorage.getItem(key);
2491
+ * },
2492
+ * removeItem: (key: string) => {
2493
+ * localStorage.removeItem(key);
2494
+ * },
2495
+ * clear: () => {
2496
+ * localStorage.clear();
2497
+ * },
2498
+ * };
2499
+ *
2500
+ * const storage = new JSONStorage(customStorage, customSerializer);
2501
+ * storage.setItem('key', { data: 'value' }, 3600);
2502
+ * const value = storage.getItem('key');
2503
+ * ```
2504
+ *
2505
+ */
2506
+ declare class JSONStorage implements SyncStorage<string> {
2507
+ /**
2508
+ * The storage backend to use.
2509
+ */
2510
+ private readonly storage?;
2511
+ /**
2512
+ * The serializer used to serialize and deserialize the data.
2513
+ *
2514
+ * **serializer and deserialize is only support sync operation**
2515
+ */
2516
+ private readonly serializer;
2517
+ /**
2518
+ * The internal store for the JSONStorage class.
2519
+ *
2520
+ * If `storage` is not provided, it is stored in memory by default.
2521
+ */
2522
+ private store;
2523
+ /**
2524
+ * Initializes a new instance of the JSONStorage class.
2525
+ *
2526
+ * @param storage - An optional synchronous storage backend to use.
2527
+ */
2528
+ constructor(
2529
+ /**
2530
+ * The storage backend to use.
2531
+ */
2532
+ storage?: SyncStorage<string, string> | undefined,
2533
+ /**
2534
+ * The serializer used to serialize and deserialize the data.
2535
+ *
2536
+ * **serializer and deserialize is only support sync operation**
2537
+ */
2538
+ serializer?: Serializer<unknown, string>);
2539
+ /**
2540
+ * Gets the number of items stored in the local storage.
2541
+ *
2542
+ * @returns The number of stored items.
2543
+ */
2544
+ get length(): number;
2545
+ /**
2546
+ * Stores a value with an optional expiration time.
2547
+ *
2548
+ * @param key - The key under which the value is stored.
2549
+ * @param value - The value to store, which must be JSON-serializable.
2550
+ * @param expire - Optional expiration time in milliseconds.
2551
+ */
2552
+ setItem<T>(key: string, value: T, expire?: number): void;
2553
+ /**
2554
+ * Retrieves a stored value by its key.
2555
+ *
2556
+ * @param key - The key of the value to retrieve.
2557
+ * @param defaultValue - An optional default value to return if the key is not found.
2558
+ * @returns The stored value or the default value if the key is not found or expired.
2559
+ */
2560
+ getItem<T>(key: string, defaultValue?: T): T | null;
2561
+ /**
2562
+ * Removes a stored item by its key.
2563
+ *
2564
+ * @param key - The key of the item to remove.
2565
+ */
2566
+ removeItem(key: string): void;
2567
+ /**
2568
+ * Clears all stored items.
2569
+ */
2570
+ clear(): void;
2571
+ }
2572
+
2573
+ export { AsyncExecutor, Base64Serializer, Executor, ExecutorError, FetchAbortPlugin, FetchURLPlugin, JSONSerializer, JSONStorage, LEVELS, Logger, RequestAdapterAxios, RequestAdapterFetch, RequestError, RequestErrorID, RequestScheduler, RetryPlugin, SyncExecutor };
2574
+ export type { AsyncStorage, Encryptor, ExecOptions, ExecutorContext, ExecutorPlugin, HookRuntimes, Intersection, LogArgument, LogLevel, PromiseTask, RequestAdapterConfig, RequestAdapterFetchConfig, RequestAdapterInterface, RequestAdapterResponse, RetryOptions, Serializer, SyncStorage, SyncTask, Task, ValueOf };