/** * API Client Singleton Service (@plyaz/core) * Manages the API client with environment-specific configurations and intelligent defaults * * The app reads process.env and constructs ApiClientOptions, then passes to this service. * Service never touches process.env directly - all env reading happens in the app layer. * * @module services/ApiClientService */ import type { ApiClientWithEvents, ApiClientOptions } from '@plyaz/types/api'; import { type ClientEventManager, type EndpointsList } from '@plyaz/api/frontend'; import type { CoreApiEnvironmentConfig } from '@plyaz/types/core'; import type { ResponseError } from 'fetchff'; export declare class ApiClientService { private static get instance(); private static set instance(value); private static get isInitializing(); private static set isInitializing(value); private static get initPromise(); private static set initPromise(value); /** * Build the core error handler for API clients. * This handler emits errors to CoreEventManager for global error handling. * * Handles: * - Single errors (network, timeout) * - Array of errors from API responses (validation, business logic) * - Serialization to unified SerializedError format * - Event emission to CORE_EVENTS.SYSTEM.ERROR and CORE_EVENTS.API.REQUEST_ERROR * * @returns Error handler function compatible with ApiClientOptions.onError */ static buildCoreErrorHandler(): (error: ResponseError) => Promise; /** * Initialize the API client with environment config and API options * * @param envConfig - Environment metadata (env, apiKey) * @param apiConfig - API configuration (baseURL, encryption, timeout, event handlers, etc.) * @returns Promise that resolves to the initialized client */ static init(envConfig: CoreApiEnvironmentConfig, apiConfig?: Partial): Promise>; /** * Internal initialization logic * Merges environment-specific defaults with API configuration * * Merge Priority (lowest to highest): * 1. Environment defaults (PRODUCTION_CONFIG / STAGING_CONFIG / DEVELOPMENT_CONFIG) * 2. Environment metadata (envConfig - apiKey) * 3. API configuration (apiConfig - baseURL, encryption, timeout, etc.) */ private static createClient; /** * Get the initialized client instance * * @throws {ApiPackageError} If client not initialized */ static getClient(): ApiClientWithEvents; /** * Check if client is initialized */ static isInitialized(): boolean; /** * Reinitialize with new config and options */ static reinitialize(envConfig: CoreApiEnvironmentConfig, apiConfig?: Partial): Promise>; /** * Dispose of the client instance */ static dispose(): void; /** * Emits an API error event via CoreEventManager. * Called when API operations fail to integrate with global error handling. * * **CRITICAL**: This event emission triggers automatic error state updates. * The global error store MUST subscribe to CORE_EVENTS.API.REQUEST_ERROR to: * 1. Capture all API errors automatically * 2. Update global error state for UI display * 3. Ensure individual domain stores remain error-free (only domain data) * * This is the unified error hook that: * - On frontend: Emits event that global error store subscribes to * - On backend: Emits event for logging/monitoring (can be configured to rethrow) * * @param error - The error that occurred * @param options - Additional context for the error * @param options.method - HTTP method (GET, POST, etc.) * @param options.url - Request URL * @param options.requestId - Unique request identifier * @param options.status - HTTP status code (if available) * @param options.duration - Request duration in ms * @param options.rethrow - Whether to rethrow the error after emitting (default: false) * * @example * ```typescript * // Global error store setup (in @plyaz/store) * CoreEventManager.on(CORE_EVENTS.API.REQUEST_ERROR, (payload) => { * errorStore.setError({ * message: payload.error.message, * status: payload.status, * url: payload.url, * requestId: payload.requestId, * }); * }); * * // Frontend usage - emit to store * ApiClientService.emitApiError(error, { * method: 'GET', * url: '/api/users', * requestId: '123', * duration: 500, * }); * * // Backend usage - emit and rethrow * ApiClientService.emitApiError(error, { * method: 'POST', * url: '/api/orders', * requestId: '456', * duration: 1200, * rethrow: true, * }); * ``` */ static emitApiError(error: unknown, options: { method: string; url: string; requestId: string; status?: number; duration: number; rethrow?: boolean; }): void; /** * Create a dedicated API client instance (NOT the singleton) * * Use this when you need an isolated client with its own configuration * that doesn't affect or get affected by the shared singleton instance. * * @param envConfig - Environment metadata (env, apiKey) * @param apiConfig - API configuration (baseURL, encryption, timeout, etc.) * @returns Promise that resolves to a new dedicated client instance * * @example * ```typescript * // Create a dedicated client for feature flags service * const flagsClient = await ApiClientService.createInstance( * { env: 'production' }, * { * baseURL: 'https://flags.example.com', * timeout: 5000, * } * ); * * // This client is independent from ApiClientService.getClient() * flagsClient.updateConfig({ timeout: 3000 }); // Only affects this instance * ``` */ static createInstance(envConfig: CoreApiEnvironmentConfig, apiConfig?: Partial): Promise>; /** * Create a standalone API client with Core error handling. * * This is a simpler alternative to `createInstance()` that doesn't require * environment config. Use this when you just need the error handling without * environment-specific defaults (production validation, etc.). * * **Use cases:** * - Domain services that need their own API client * - Testing with isolated API clients * - Simple client creation without environment setup * * @param apiConfig - API configuration (baseURL, timeout, etc.) * @returns Promise that resolves to a client with Core error handling * * @example * ```typescript * // In BaseDomainService or any service * const client = await ApiClientService.createStandaloneClient({ * baseURL: '/api/examples', * timeout: 10000, * }); * * // Errors are automatically emitted to CoreEventManager * const response = await client.get('/items'); * ``` */ static createStandaloneClient(apiConfig: ApiClientOptions): Promise>; } export declare const getApiClient: () => ApiClientWithEvents; export declare const initApiClient: (envConfig: CoreApiEnvironmentConfig, apiConfig?: Partial) => Promise>; export declare const createApiClientInstance: (envConfig: CoreApiEnvironmentConfig, apiConfig?: Partial) => Promise>; export declare const createStandaloneApiClient: (apiConfig: ApiClientOptions) => Promise>; //# sourceMappingURL=ApiClientService.d.ts.map