@ipcom/asterisk-ari 0.0.164 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../node_modules/exponential-backoff/src/options.ts", "../../node_modules/exponential-backoff/src/jitter/full/full.jitter.ts", "../../node_modules/exponential-backoff/src/jitter/no/no.jitter.ts", "../../node_modules/exponential-backoff/src/jitter/jitter.factory.ts", "../../node_modules/exponential-backoff/src/delay/delay.base.ts", "../../node_modules/exponential-backoff/src/delay/skip-first/skip-first.delay.ts", "../../node_modules/exponential-backoff/src/delay/always/always.delay.ts", "../../node_modules/exponential-backoff/src/delay/delay.factory.ts", "../../node_modules/exponential-backoff/src/backoff.ts", "../../src/index.ts", "../../src/ari-client/baseClient.ts", "../../src/ari-client/resources/applications.ts", "../../src/ari-client/resources/asterisk.ts", "../../src/ari-client/resources/bridges.ts", "../../src/ari-client/utils.ts", "../../src/ari-client/resources/channels.ts", "../../node_modules/uuid/dist/esm/stringify.js", "../../node_modules/uuid/dist/esm/rng.js", "../../node_modules/uuid/dist/esm/native.js", "../../node_modules/uuid/dist/esm/v4.js", "../../src/ari-client/resources/endpoints.ts", "../../src/ari-client/resources/playbacks.ts", "../../src/ari-client/resources/sounds.ts", "../../src/ari-client/websocketClient.ts", "../../src/ari-client/resources/recordings.ts", "../../src/ari-client/ariClient.ts"],
4
- "sourcesContent": [null, null, null, null, null, null, null, null, null, "/**\n * @file Main entry point for the Asterisk REST Interface (ARI) client package\n * @description This file exports all the necessary classes, types and interfaces for interacting with the ARI\n */\n\n/**\n * Main client class for interacting with Asterisk REST Interface\n * @packageDocumentation\n */\nexport { AriClient } from './ari-client/ariClient.js';\n\n/**\n * Resource Classes\n * These classes provide direct access to ARI resources\n */\nexport { Channels, ChannelInstance } from './ari-client/resources/channels.js';\n\nexport { Endpoints } from './ari-client/resources/endpoints.js';\nexport { Applications } from './ari-client/resources/applications.js';\nexport { Sounds } from './ari-client/resources/sounds.js';\nexport {\n Playbacks,\n PlaybackInstance,\n} from './ari-client/resources/playbacks.js';\nexport { Asterisk } from './ari-client/resources/asterisk.js';\nexport { Bridges, BridgeInstance } from './ari-client/resources/bridges.js';\n\n/**\n * Type Definitions\n * These types and interfaces define the shape of data structures used throughout the API\n */\n\n// Configuration Types\nexport type {\n AriClientConfig,\n AriApplication,\n} from './ari-client/interfaces/index.js';\n\n// Channel Related Types\nexport type {\n Channel,\n ChannelEvent,\n ChannelPlayback,\n ChannelVar,\n ChannelDialplan,\n OriginateRequest,\n RecordingOptions,\n SnoopOptions,\n ExternalMediaOptions,\n RTPStats,\n} from './ari-client/interfaces/index.js';\n\n// Playback Related Types\nexport type {\n Playback,\n PlaybackEvent,\n PlaybackOptions,\n PlaybackControlRequest,\n PlayMediaRequest,\n} from './ari-client/interfaces/index.js';\n\n// Bridge Related Types\nexport type {\n Bridge,\n BridgePlayback,\n CreateBridgeRequest,\n RemoveChannelRequest,\n AddChannelRequest,\n} from './ari-client/interfaces/index.js';\n\n// Endpoint Related Types\nexport type {\n Endpoint,\n EndpointDetails,\n} from './ari-client/interfaces/index.js';\n\n// Application Related Types\nexport type {\n Application,\n ApplicationDetails,\n} from './ari-client/interfaces/index.js';\n\n// Sound Related Types\nexport type { Sound, SoundListRequest } from './ari-client/interfaces/index.js';\n\n// Asterisk Related Types\nexport type {\n AsteriskInfo,\n Module,\n Logging,\n Variable,\n AsteriskPing,\n} from './ari-client/interfaces/index.js';\n\n// WebSocket Related Types\nexport type {\n WebSocketEvent,\n WebSocketEventType,\n // Eventos individuais\n ChannelDtmfReceived,\n ChannelDialplanEvent,\n ChannelVarset,\n StasisStart,\n PlaybackStarted,\n PlaybackContinuing,\n PlaybackFinished,\n BridgeCreated,\n BridgeDestroyed,\n ChannelCreated,\n ChannelDestroyed,\n ApplicationMoveFailed,\n RecordingStarted,\n RecordingFinished,\n RecordingFailed,\n DeviceStateChanged,\n BridgeMerged,\n BridgeBlindTransfer,\n BridgeAttendedTransfer,\n BridgeVideoSourceChanged,\n ChannelEnteredBridge,\n ChannelLeftBridge,\n ChannelStateChange,\n ChannelTalkingStarted,\n ChannelTalkingFinished,\n ChannelUnhold,\n ChannelHold,\n ContactStatusChange,\n EndpointStateChange,\n Dial,\n StasisEnd,\n TextMessageReceived,\n ChannelConnectedLine,\n ChannelHangupRequest,\n PeerStatusChange,\n} from './ari-client/interfaces/index.js';\n", "import axios, {\n type AxiosInstance,\n type AxiosRequestConfig,\n isAxiosError,\n} from 'axios';\n\n/**\n * Custom error class for HTTP-related errors\n */\nclass HTTPError extends Error {\n constructor(\n message: string,\n public readonly status?: number,\n public readonly method?: string,\n public readonly url?: string\n ) {\n super(message);\n this.name = 'HTTPError';\n }\n}\n\n/**\n * BaseClient handles HTTP communications with the ARI server.\n * Provides methods for making HTTP requests and manages authentication and error handling.\n */\nexport class BaseClient {\n private readonly client: AxiosInstance;\n\n /**\n * Creates a new BaseClient instance.\n *\n * @param {string} baseUrl - The base URL for the API\n * @param {string} username - Username for authentication\n * @param {string} password - Password for authentication\n * @param {boolean} [secure=false] - Whether to use secure connections (HTTPS/WSS)\n * @param {number} [timeout=5000] - Request timeout in milliseconds\n * @throws {Error} If the base URL format is invalid\n */\n constructor(\n private readonly baseUrl: string,\n private readonly username: string,\n private readonly password: string,\n private readonly secure: boolean = false,\n timeout = 5000\n ) {\n if (!/^https?:\\/\\/.+/.test(baseUrl)) {\n throw new Error(\n 'Invalid base URL. It must start with http:// or https://'\n );\n }\n\n this.client = axios.create({\n baseURL: baseUrl,\n auth: { username, password },\n timeout,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n this.addInterceptors();\n }\n\n /**\n * Gets the base URL of the client.\n */\n public getBaseUrl(): string {\n return this.baseUrl;\n }\n\n /**\n * Gets the configured credentials including security settings.\n * Used by WebSocketClient to determine authentication method.\n */\n public getCredentials(): {\n baseUrl: string;\n username: string;\n password: string;\n secure: boolean;\n } {\n return {\n baseUrl: this.baseUrl,\n username: this.username,\n password: this.password,\n secure: this.secure,\n };\n }\n\n /**\n * Adds request and response interceptors to the Axios instance.\n */\n private addInterceptors(): void {\n this.client.interceptors.request.use(\n (config) => {\n return config;\n },\n (error: unknown) => {\n const message = this.getErrorMessage(error);\n console.error('[Request Error]', message);\n return Promise.reject(new HTTPError(message));\n }\n );\n\n this.client.interceptors.response.use(\n (response) => {\n return response;\n },\n (error: unknown) => {\n if (isAxiosError(error)) {\n const status = error.response?.status ?? 0;\n const method = error.config?.method?.toUpperCase() ?? 'UNKNOWN';\n const url = error.config?.url ?? 'unknown-url';\n const message =\n error.response?.data?.message || error.message || 'Unknown error';\n\n if (status === 404) {\n console.warn(`[404] Not Found: ${url}`);\n } else if (status >= 500) {\n console.error(`[${status}] Server Error: ${url}`);\n } else if (status > 0) {\n console.warn(`[${status}] ${method} ${url}: ${message}`);\n } else {\n console.error(`[Network] Request failed: ${message}`);\n }\n\n throw new HTTPError(message, status || undefined, method, url);\n }\n\n const message = this.getErrorMessage(error);\n console.error('[Unexpected Error]', message);\n throw new Error(message);\n }\n );\n }\n\n /**\n * Executes a GET request.\n *\n * @param path - API endpoint path\n * @param config - Optional Axios request configuration\n * @returns Promise with the response data\n */\n async get<T>(path: string, config?: AxiosRequestConfig): Promise<T> {\n try {\n const response = await this.client.get<T>(path, config);\n return response.data;\n } catch (error: unknown) {\n throw this.handleRequestError(error);\n }\n }\n\n /**\n * Executes a POST request.\n *\n * @param path - API endpoint path\n * @param data - Request payload\n * @param config - Optional Axios request configuration\n * @returns Promise with the response data\n */\n async post<T, D = unknown>(\n path: string,\n data?: D,\n config?: AxiosRequestConfig\n ): Promise<T> {\n try {\n const response = await this.client.post<T>(path, data, config);\n return response.data;\n } catch (error: unknown) {\n throw this.handleRequestError(error);\n }\n }\n\n /**\n * Executes a PUT request.\n *\n * @param path - API endpoint path\n * @param data - Request payload\n * @param config - Optional Axios request configuration\n * @returns Promise with the response data\n */\n async put<T, D = unknown>(\n path: string,\n data: D,\n config?: AxiosRequestConfig\n ): Promise<T> {\n try {\n const response = await this.client.put<T>(path, data, config);\n return response.data;\n } catch (error: unknown) {\n throw this.handleRequestError(error);\n }\n }\n\n /**\n * Executes a DELETE request.\n *\n * @param path - API endpoint path\n * @param config - Optional Axios request configuration\n * @returns Promise with the response data\n */\n async delete<T>(path: string, config?: AxiosRequestConfig): Promise<T> {\n try {\n const response = await this.client.delete<T>(path, config);\n return response.data;\n } catch (error: unknown) {\n throw this.handleRequestError(error);\n }\n }\n\n /**\n * Handles and formats error messages from various error types.\n */\n private getErrorMessage(error: unknown): string {\n if (isAxiosError(error)) {\n return error.response?.data?.message || error.message || 'HTTP Error';\n }\n if (error instanceof Error) {\n return error.message;\n }\n return 'An unknown error occurred';\n }\n\n /**\n * Handles errors from HTTP requests.\n */\n private handleRequestError(error: unknown): never {\n const message = this.getErrorMessage(error);\n if (isAxiosError(error)) {\n throw new HTTPError(\n message,\n error.response?.status,\n error.config?.method?.toUpperCase(),\n error.config?.url\n );\n }\n throw new Error(message);\n }\n\n /**\n * Sets custom headers for the client instance.\n */\n setHeaders(headers: Record<string, string>): void {\n this.client.defaults.headers.common = {\n ...this.client.defaults.headers.common,\n ...headers,\n };\n }\n\n /**\n * Gets the current request timeout setting.\n */\n getTimeout(): number {\n return this.client.defaults.timeout || 5000;\n }\n\n /**\n * Updates the request timeout setting.\n */\n setTimeout(timeout: number): void {\n this.client.defaults.timeout = timeout;\n }\n}\n", "import type { BaseClient } from '../baseClient.js';\nimport type {\n Application,\n ApplicationDetails,\n} from '../interfaces/applications.types.js';\n\nexport interface ApplicationMessage {\n event: string;\n data?: Record<string, any>;\n}\n\nexport class Applications {\n constructor(private client: BaseClient) {}\n\n /**\n * Lists all applications.\n *\n * @returns A promise that resolves to an array of Application objects.\n * @throws {Error} If the API response is not an array.\n */\n async list(): Promise<Application[]> {\n const applications = await this.client.get<unknown>('/applications');\n\n if (!Array.isArray(applications)) {\n throw new Error('Resposta da API /applications n\u00E3o \u00E9 um array.');\n }\n\n return applications as Application[];\n }\n\n /**\n * Retrieves details of a specific application.\n *\n * @param appName - The name of the application to retrieve details for.\n * @returns A promise that resolves to an ApplicationDetails object.\n * @throws {Error} If there's an error fetching the application details.\n */\n async getDetails(appName: string): Promise<ApplicationDetails> {\n try {\n return await this.client.get<ApplicationDetails>(\n `/applications/${appName}`\n );\n } catch (error) {\n console.error(`Erro ao obter detalhes do aplicativo ${appName}:`, error);\n throw error;\n }\n }\n\n /**\n * Sends a message to a specific application.\n *\n * @param appName - The name of the application to send the message to.\n * @param body - The message to be sent, containing an event and optional data.\n * @returns A promise that resolves when the message is successfully sent.\n */\n async sendMessage(appName: string, body: ApplicationMessage): Promise<void> {\n await this.client.post<void>(`/applications/${appName}/messages`, body);\n }\n}\n", "import type { BaseClient } from '../baseClient.js';\nimport type {\n AsteriskInfo,\n AsteriskPing,\n Logging,\n Module,\n Variable,\n} from '../interfaces';\n\nfunction toQueryParams<T>(options: T): string {\n return new URLSearchParams(\n Object.entries(options as Record<string, string>)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => [key, String(value)])\n ).toString();\n}\n\nexport class Asterisk {\n constructor(private client: BaseClient) {}\n\n async ping(): Promise<AsteriskPing> {\n return this.client.get<AsteriskPing>('/asterisk/ping');\n }\n\n /**\n * Retrieves information about the Asterisk server.\n */\n async get(): Promise<AsteriskInfo> {\n return this.client.get<AsteriskInfo>('/asterisk/info');\n }\n\n /**\n * Lists all loaded modules in the Asterisk server.\n */\n async list(): Promise<Module[]> {\n return this.client.get<Module[]>('/asterisk/modules');\n }\n\n /**\n * Manages a specific module in the Asterisk server.\n *\n * @param moduleName - The name of the module to manage.\n * @param action - The action to perform on the module: \"load\", \"unload\", or \"reload\".\n * @returns A promise that resolves when the action is completed successfully.\n * @throws {Error} Throws an error if the HTTP method or action is invalid.\n */\n async manage(\n moduleName: string,\n action: 'load' | 'unload' | 'reload'\n ): Promise<void> {\n const url = `/asterisk/modules/${moduleName}`;\n switch (action) {\n case 'load':\n await this.client.post<void>(`${url}?action=load`);\n break;\n case 'unload':\n await this.client.delete<void>(url);\n break;\n case 'reload':\n await this.client.put<void>(url, {});\n break;\n default:\n throw new Error(`A\u00E7\u00E3o inv\u00E1lida: ${action}`);\n }\n }\n\n /**\n * Retrieves all configured logging channels.\n */\n async listLoggingChannels(): Promise<Logging[]> {\n return this.client.get<Logging[]>('/asterisk/logging');\n }\n\n /**\n * Adds or removes a log channel in the Asterisk server.\n */\n async manageLogChannel(\n logChannelName: string,\n action: 'add' | 'remove',\n configuration?: { type?: string; configuration?: string }\n ): Promise<void> {\n const queryParams = toQueryParams(configuration || {});\n return this.client.post<void>(\n `/asterisk/logging/${logChannelName}?action=${encodeURIComponent(action)}&${queryParams}`\n );\n }\n\n /**\n * Retrieves the value of a global variable.\n */\n async getGlobalVariable(variableName: string): Promise<Variable> {\n return this.client.get<Variable>(\n `/asterisk/variables?variable=${encodeURIComponent(variableName)}`\n );\n }\n\n /**\n * Sets a global variable.\n */\n async setGlobalVariable(variableName: string, value: string): Promise<void> {\n return this.client.post<void>(\n `/asterisk/variables?variable=${encodeURIComponent(variableName)}&value=${encodeURIComponent(value)}`\n );\n }\n}\n", "import { EventEmitter } from 'events';\nimport { isAxiosError } from 'axios';\nimport type { AriClient } from '../ariClient';\nimport type { BaseClient } from '../baseClient.js';\nimport type {\n AddChannelRequest,\n Bridge,\n BridgePlayback,\n CreateBridgeRequest,\n PlayMediaRequest,\n RemoveChannelRequest,\n WebSocketEvent,\n} from '../interfaces';\nimport { bridgeEvents } from '../interfaces/events.types';\nimport { toQueryParams } from '../utils';\n\n/**\n * Extracts an error message from various error types.\n *\n * This utility function attempts to retrieve the most relevant error message\n * from different error objects, including Axios errors and standard Error instances.\n *\n * @param error - The error object to extract the message from.\n * Can be of type AxiosError, Error, or any unknown type.\n *\n * @returns A string containing the extracted error message.\n * For Axios errors, it prioritizes the response data message,\n * then falls back to the error message, and finally a default Axios error message.\n * For standard Error instances, it returns the error message.\n * For unknown error types, it returns a generic error message.\n */\nconst getErrorMessage = (error: unknown): string => {\n if (isAxiosError(error)) {\n return (\n error.response?.data?.message ||\n error.message ||\n 'Um erro do axios ocorreu'\n );\n }\n if (error instanceof Error) {\n return error.message;\n }\n return 'Um erro desconhecido ocorreu';\n};\n\n/**\n * Represents an instance of a Bridge that provides methods to control\n * bridges, manage event listeners, and manipulate its state.\n */\nexport class BridgeInstance {\n private readonly eventEmitter = new EventEmitter();\n private readonly listenersMap = new Map<\n string,\n ((...args: any[]) => void)[]\n >(); // \uD83D\uDD39 Guarda listeners para remo\u00E7\u00E3o posterior\n private bridgeData: Bridge | null = null;\n public readonly id: string;\n\n /**\n * Creates a new BridgeInstance.\n *\n * @param client - The AriClient instance for making API calls.\n * @param baseClient - The BaseClient instance for making HTTP requests.\n * @param bridgeId - Optional. The ID of the bridge. If not provided, a new ID will be generated.\n */\n constructor(\n private readonly client: AriClient,\n private readonly baseClient: BaseClient,\n bridgeId?: string\n ) {\n this.id = bridgeId || `bridge-${Date.now()}`;\n }\n\n /**\n * Registers a listener for specific bridge events.\n *\n * @param event - The type of event to listen for.\n * @param listener - The callback function to be called when the event occurs.\n */\n /**\n * Registers a listener for specific bridge events.\n *\n * This method allows you to attach an event listener to the bridge instance for a specific event type.\n * When the specified event occurs, the provided listener function will be called with the event data.\n *\n * @template T - The specific type of WebSocketEvent to listen for.\n * It receives the event data as its parameter.\n * @returns {void}\n *\n * @example\n * bridge.on('BridgeCreated', (event) => {\n *\n * });\n * @param event\n * @param listener\n */\n on<T extends WebSocketEvent['type']>(\n event: T,\n listener: (data: Extract<WebSocketEvent, { type: T }>) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n // \uD83D\uDD39 Verifica se o listener j\u00E1 est\u00E1 registrado\n const existingListeners = this.listenersMap.get(event) || [];\n if (existingListeners.includes(listener)) {\n console.warn(\n `Listener j\u00E1 registrado para evento ${event}, reutilizando.`\n );\n return;\n }\n\n const wrappedListener = (data: WebSocketEvent) => {\n if ('bridge' in data && data.bridge?.id === this.id) {\n listener(data as Extract<WebSocketEvent, { type: T }>);\n }\n };\n\n this.eventEmitter.on(event, wrappedListener);\n\n // \uD83D\uDD39 Armazena o listener para futura remo\u00E7\u00E3o\n if (!this.listenersMap.has(event)) {\n this.listenersMap.set(event, []);\n }\n this.listenersMap\n .get(event)!\n .push(wrappedListener as (...args: any[]) => void);\n }\n\n /**\n * Registers a one-time listener for specific bridge events.\n *\n * @param event - The type of event to listen for.\n * @param listener - The callback function to be called when the event occurs.\n */\n once<T extends WebSocketEvent['type']>(\n event: T,\n listener: (data: Extract<WebSocketEvent, { type: T }>) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n const eventKey = `${event}-${this.id}`;\n\n // \uD83D\uDD39 Verifica se j\u00E1 existe um listener igual para evitar duplica\u00E7\u00E3o\n const existingListeners = this.listenersMap.get(eventKey) || [];\n if (existingListeners.includes(listener)) {\n console.warn(\n `One-time listener j\u00E1 registrado para evento ${eventKey}, reutilizando.`\n );\n return;\n }\n\n const wrappedListener = (data: WebSocketEvent) => {\n if ('bridge' in data && data.bridge?.id === this.id) {\n listener(data as Extract<WebSocketEvent, { type: T }>);\n\n // \uD83D\uDD39 Remove automaticamente o listener ap\u00F3s a primeira execu\u00E7\u00E3o\n this.off(event, wrappedListener);\n }\n };\n\n this.eventEmitter.once(event, wrappedListener);\n\n // \uD83D\uDD39 Armazena o listener para futura remo\u00E7\u00E3o\n if (!this.listenersMap.has(eventKey)) {\n this.listenersMap.set(eventKey, []);\n }\n this.listenersMap\n .get(eventKey)!\n .push(wrappedListener as (...args: any[]) => void);\n }\n\n /**\n * Removes event listener(s) from the bridge.\n *\n * @param event - The type of event to remove listeners for.\n * @param listener - Optional. The specific listener to remove. If not provided, all listeners for the event will be removed.\n */\n off<T extends WebSocketEvent['type']>(\n event: T,\n listener?: (data: Extract<WebSocketEvent, { type: T }>) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n if (listener) {\n this.eventEmitter.off(event, listener);\n const storedListeners = this.listenersMap.get(event) || [];\n this.listenersMap.set(\n event,\n storedListeners.filter((l) => l !== listener)\n );\n } else {\n this.eventEmitter.removeAllListeners(event);\n this.listenersMap.delete(event);\n }\n }\n\n /**\n * Cleans up the BridgeInstance, resetting its state and clearing resources.\n */\n public cleanup(): void {\n // Limpar dados do bridge\n this.bridgeData = null;\n\n // Remover todos os listeners\n this.removeAllListeners();\n\n // Limpar o map de listeners\n this.listenersMap.clear();\n\n console.log(`Bridge instance ${this.id} cleaned up`);\n }\n\n /**\n * Emits an event if it corresponds to the current bridge.\n *\n * @param event - The WebSocketEvent to emit.\n */\n emitEvent(event: WebSocketEvent): void {\n if (!event) {\n console.warn('Invalid event received');\n return;\n }\n\n if ('bridge' in event && event.bridge?.id === this.id) {\n this.eventEmitter.emit(event.type, event);\n }\n }\n\n /**\n * Removes all event listeners from this bridge instance.\n */\n removeAllListeners(): void {\n console.log(`Removing all event listeners for bridge ${this.id}`);\n this.listenersMap.forEach((listeners, event) => {\n listeners.forEach((listener) => {\n this.eventEmitter.off(\n event as string,\n listener as (...args: any[]) => void\n );\n });\n });\n\n this.listenersMap.clear();\n this.eventEmitter.removeAllListeners();\n }\n\n /**\n * Retrieves the current details of the bridge.\n *\n * @returns A Promise that resolves to the Bridge object containing the current details.\n * @throws An error if the retrieval fails.\n */\n async get(): Promise<Bridge> {\n try {\n if (!this.id) {\n throw new Error('No bridge associated with this instance');\n }\n\n this.bridgeData = await this.baseClient.get<Bridge>(\n `/bridges/${this.id}`\n );\n return this.bridgeData;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error retrieving details for bridge ${this.id}:`, message);\n throw new Error(`Failed to get bridge details: ${message}`);\n }\n }\n\n /**\n * Adds channels to the bridge.\n *\n * @param request - The AddChannelRequest object containing the channels to add.\n * @throws An error if the operation fails.\n */\n async add(request: AddChannelRequest): Promise<void> {\n try {\n const queryParams = toQueryParams({\n channel: Array.isArray(request.channel)\n ? request.channel.join(',')\n : request.channel,\n ...(request.role && { role: request.role }),\n });\n\n await this.baseClient.post<void>(\n `/bridges/${this.id}/addChannel?${queryParams}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error adding channels to bridge ${this.id}:`, message);\n throw new Error(`Failed to add channels: ${message}`);\n }\n }\n\n /**\n * Removes channels from the bridge.\n *\n * @param request - The RemoveChannelRequest object containing the channels to remove.\n * @throws An error if the operation fails.\n */\n async remove(request: RemoveChannelRequest): Promise<void> {\n try {\n const queryParams = toQueryParams({\n channel: Array.isArray(request.channel)\n ? request.channel.join(',')\n : request.channel,\n });\n\n await this.baseClient.post<void>(\n `/bridges/${this.id}/removeChannel?${queryParams}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error removing channels from bridge ${this.id}:`, message);\n throw new Error(`Failed to remove channels: ${message}`);\n }\n }\n\n /**\n * Plays media on the bridge.\n *\n * @param request - The PlayMediaRequest object containing the media details to play.\n * @returns A Promise that resolves to a BridgePlayback object.\n * @throws An error if the operation fails.\n */\n async playMedia(request: PlayMediaRequest): Promise<BridgePlayback> {\n try {\n const queryParams = new URLSearchParams({\n ...(request.lang && { lang: request.lang }),\n ...(request.offsetms && { offsetms: request.offsetms.toString() }),\n ...(request.skipms && { skipms: request.skipms.toString() }),\n ...(request.playbackId && { playbackId: request.playbackId }),\n }).toString();\n\n const result = await this.baseClient.post<BridgePlayback>(\n `/bridges/${this.id}/play?${queryParams}`,\n { media: request.media }\n );\n\n return result;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error playing media on bridge ${this.id}:`, message);\n throw new Error(`Failed to play media: ${message}`);\n }\n }\n\n /**\n * Stops media playback on the bridge.\n *\n * @param playbackId - The ID of the playback to stop.\n * @throws An error if the operation fails.\n */\n async stopPlayback(playbackId: string): Promise<void> {\n try {\n await this.baseClient.delete<void>(\n `/bridges/${this.id}/play/${playbackId}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error stopping playback on bridge ${this.id}:`, message);\n throw new Error(`Failed to stop playback: ${message}`);\n }\n }\n\n /**\n * Sets the video source for the bridge.\n *\n * @param channelId - The ID of the channel to set as the video source.\n * @throws An error if the operation fails.\n */\n async setVideoSource(channelId: string): Promise<void> {\n try {\n await this.baseClient.post<void>(\n `/bridges/${this.id}/videoSource/${channelId}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(\n `Error setting video source for bridge ${this.id}:`,\n message\n );\n throw new Error(`Failed to set video source: ${message}`);\n }\n }\n\n /**\n * Removes the video source from the bridge.\n *\n * @throws An error if the operation fails.\n */\n async clearVideoSource(): Promise<void> {\n try {\n await this.baseClient.delete<void>(`/bridges/${this.id}/videoSource`);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(\n `Error removing video source from bridge ${this.id}:`,\n message\n );\n throw new Error(`Failed to remove video source: ${message}`);\n }\n }\n\n /**\n * Checks if the bridge has listeners for a specific event.\n *\n * @param event - The event type to check for listeners.\n * @returns A boolean indicating whether there are listeners for the event.\n */\n hasListeners(event: string): boolean {\n return this.eventEmitter.listenerCount(event) > 0;\n }\n\n /**\n * Retrieves the current bridge data without making an API call.\n *\n * @returns The current Bridge object or null if no data is available.\n */\n getCurrentData(): Bridge | null {\n return this.bridgeData;\n }\n}\nexport class Bridges {\n private readonly bridgeInstances = new Map<string, BridgeInstance>();\n private eventQueue = new Map<string, NodeJS.Timeout>();\n constructor(\n private readonly baseClient: BaseClient,\n private readonly client: AriClient\n ) {}\n /**\n * Creates or retrieves a Bridge instance.\n *\n * This method manages the creation and retrieval of BridgeInstance objects.\n * If an ID is provided and an instance with that ID already exists, it returns the existing instance.\n * If an ID is provided but no instance exists, it creates a new instance with that ID.\n * If no ID is provided, it creates a new instance with a generated ID.\n *\n * @param {Object} params - The parameters for creating or retrieving a Bridge instance.\n * @param {string} [params.id] - Optional. The ID of the Bridge instance to create or retrieve.\n *\n * @returns {BridgeInstance} A BridgeInstance object, either newly created or retrieved from existing instances.\n *\n * @throws {Error} If there's an error in creating or retrieving the Bridge instance.\n */\n Bridge({ id }: { id?: string }): BridgeInstance {\n try {\n if (!id) {\n const instance = new BridgeInstance(this.client, this.baseClient);\n this.bridgeInstances.set(instance.id, instance);\n return instance;\n }\n\n if (!this.bridgeInstances.has(id)) {\n const instance = new BridgeInstance(this.client, this.baseClient, id);\n this.bridgeInstances.set(id, instance);\n return instance;\n }\n\n return this.bridgeInstances.get(id)!;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error creating/retrieving bridge instance:`, message);\n throw new Error(`Failed to manage bridge instance: ${message}`);\n }\n }\n\n /**\n * Removes all bridge instances and cleans up their resources.\n * This method ensures proper cleanup of all bridges and their associated listeners.\n */\n public remove(): void {\n // Salvar os IDs antes de come\u00E7ar a limpeza\n const bridgeIds = Array.from(this.bridgeInstances.keys());\n\n for (const bridgeId of bridgeIds) {\n try {\n const instance = this.bridgeInstances.get(bridgeId);\n if (instance) {\n instance.cleanup(); // Usar o novo m\u00E9todo cleanup\n this.bridgeInstances.delete(bridgeId);\n console.log(`Bridge instance ${bridgeId} removed and cleaned up`);\n }\n } catch (error) {\n console.error(`Error cleaning up bridge ${bridgeId}:`, error);\n }\n }\n\n // Garantir que o map est\u00E1 vazio\n this.bridgeInstances.clear();\n console.log('All bridge instances have been removed and cleaned up');\n }\n\n /**\n * Removes a bridge instance from the collection of managed bridges.\n *\n * This function removes the specified bridge instance, cleans up its event listeners,\n * and logs the removal. If the bridge instance doesn't exist, it logs a warning.\n *\n * @param {string} bridgeId - The unique identifier of the bridge instance to be removed.\n * @throws {Error} Throws an error if the bridgeId is not provided.\n * @returns {void}\n */\n public removeBridgeInstance(bridgeId: string): void {\n if (!bridgeId) {\n throw new Error('Bridge ID is required');\n }\n\n const instance = this.bridgeInstances.get(bridgeId);\n if (instance) {\n try {\n instance.cleanup();\n this.bridgeInstances.delete(bridgeId);\n console.log(`Bridge instance ${bridgeId} removed from memory`);\n } catch (error) {\n console.error(`Error removing bridge instance ${bridgeId}:`, error);\n throw error;\n }\n } else {\n console.warn(`Attempt to remove non-existent instance: ${bridgeId}`);\n }\n }\n\n /**\n * Propagates a WebSocket event to a specific bridge instance.\n *\n * This function checks if the received event is valid and related to a bridge,\n * then emits the event to the corresponding bridge instance if it exists.\n *\n * @param {WebSocketEvent} event - The WebSocket event to be propagated.\n * This should be an object containing information about the event,\n * including the bridge ID and event type.\n *\n * @returns {void}\n *\n * @remarks\n * - If the event is invalid (null or undefined), a warning is logged and the function returns early.\n * - The function checks if the event is bridge-related and if the event contains a valid bridge ID.\n * - If a matching bridge instance is found, the event is emitted to that instance.\n * - If no matching bridge instance is found, a warning is logged.\n */\n public propagateEventToBridge(event: WebSocketEvent): void {\n if (!event || !('bridge' in event) || !event.bridge?.id) {\n console.warn('Invalid WebSocket event received');\n return;\n }\n\n const key = `${event.type}-${event.bridge.id}`;\n const existing = this.eventQueue.get(key);\n if (existing) {\n clearTimeout(existing);\n }\n\n this.eventQueue.set(\n key,\n setTimeout(() => {\n const instance = this.bridgeInstances.get(event.bridge!.id!);\n if (instance) {\n instance.emitEvent(event);\n } else {\n console.warn(\n `No instance found for bridge ${event.bridge!.id}. Event ignored.`\n );\n }\n this.eventQueue.delete(key);\n }, 100)\n );\n }\n /**\n * Performs a cleanup of the Bridges instance, clearing all event queues and removing all bridge instances.\n *\n * This method is responsible for:\n * 1. Clearing all pending timeouts in the event queue.\n * 2. Removing all bridge instances managed by this Bridges object.\n *\n * It should be called when the Bridges instance is no longer needed or before reinitializing\n * to ensure all resources are properly released.\n *\n * @returns {void}\n */\n public cleanup(): void {\n // Limpar event queue\n this.eventQueue.forEach((timeout) => clearTimeout(timeout));\n this.eventQueue.clear();\n\n // Limpar todas as inst\u00E2ncias\n this.remove();\n }\n\n /**\n * Lists all active bridges in the system.\n *\n * This asynchronous function retrieves a list of all currently active bridges\n * by making a GET request to the \"/bridges\" endpoint using the base client.\n *\n * @returns {Promise<Bridge[]>} A promise that resolves to an array of Bridge objects.\n * Each Bridge object represents an active bridge in the system.\n *\n * @throws {Error} If there's an error in fetching the bridges or if the request fails.\n *\n * @example\n * try {\n * const bridges = await bridgesInstance.list();\n *\n * } catch (error) {\n * console.error('Failed to fetch bridges:', error);\n * }\n */\n async list(): Promise<Bridge[]> {\n return this.baseClient.get<Bridge[]>('/bridges');\n }\n\n /**\n * Creates a new bridge in the system.\n *\n * This asynchronous function sends a POST request to create a new bridge\n * using the provided configuration details.\n *\n * @param request - The configuration details for creating the new bridge.\n * @param request.type - The type of bridge to create (e.g., 'mixing', 'holding').\n * @param request.name - Optional. A custom name for the bridge.\n * @param request.bridgeId - Optional. A specific ID for the bridge. If not provided, one will be generated.\n *\n * @returns A Promise that resolves to a Bridge object representing the newly created bridge.\n * The Bridge object contains details such as id, technology, bridge_type, bridge_class, channels, etc.\n *\n * @throws Will throw an error if the bridge creation fails or if there's a network issue.\n */\n async createBridge(request: CreateBridgeRequest): Promise<Bridge> {\n return this.baseClient.post<Bridge>('/bridges', request);\n }\n\n /**\n * Retrieves detailed information about a specific bridge.\n *\n * This asynchronous function fetches the complete details of a bridge\n * identified by its unique ID. It makes a GET request to the ARI endpoint\n * for the specified bridge.\n *\n * @param bridgeId - The unique identifier of the bridge to retrieve details for.\n * This should be a string that uniquely identifies the bridge in the system.\n *\n * @returns A Promise that resolves to a Bridge object containing all the details\n * of the specified bridge. This includes information such as the bridge's\n * ID, type, channels, and other relevant properties.\n *\n * @throws Will throw an error if the bridge cannot be found, if there's a network issue,\n * or if the server responds with an error.\n */\n async get(bridgeId: string): Promise<Bridge> {\n return this.baseClient.get<Bridge>(`/bridges/${bridgeId}`);\n }\n\n /**\n * Destroys (deletes) a specific bridge in the system.\n *\n * This asynchronous function sends a DELETE request to remove a bridge\n * identified by its unique ID. Once destroyed, the bridge and all its\n * associated resources are permanently removed from the system.\n *\n * @param bridgeId - The unique identifier of the bridge to be destroyed.\n * This should be a string that uniquely identifies the bridge in the system.\n *\n * @returns A Promise that resolves to void when the bridge is successfully destroyed.\n * If the operation is successful, the bridge no longer exists in the system.\n *\n * @throws Will throw an error if the bridge cannot be found, if there's a network issue,\n * or if the server responds with an error during the deletion process.\n */\n async destroy(bridgeId: string): Promise<void> {\n return this.baseClient.delete<void>(`/bridges/${bridgeId}`);\n }\n\n /**\n * Adds one or more channels to a specified bridge.\n *\n * This asynchronous function sends a POST request to add channels to an existing bridge.\n * It can handle adding a single channel or multiple channels in one operation.\n *\n * @param bridgeId - The unique identifier of the bridge to which channels will be added.\n * @param request - An object containing the details of the channel(s) to be added.\n * @param request.channel - A single channel ID or an array of channel IDs to add to the bridge.\n * @param request.role - Optional. Specifies the role of the channel(s) in the bridge.\n *\n * @returns A Promise that resolves to void when the operation is successful.\n *\n * @throws Will throw an error if the request fails, such as if the bridge doesn't exist\n * or if there's a network issue.\n */\n async addChannels(\n bridgeId: string,\n request: AddChannelRequest\n ): Promise<void> {\n const queryParams = toQueryParams({\n channel: Array.isArray(request.channel)\n ? request.channel.join(',')\n : request.channel,\n ...(request.role && { role: request.role }),\n });\n\n await this.baseClient.post<void>(\n `/bridges/${bridgeId}/addChannel?${queryParams}`\n );\n }\n\n /**\n * Removes one or more channels from a specified bridge.\n *\n * This asynchronous function sends a POST request to remove channels from an existing bridge.\n * It can handle removing a single channel or multiple channels in one operation.\n *\n * @param bridgeId - The unique identifier of the bridge from which channels will be removed.\n * @param request - An object containing the details of the channel(s) to be removed.\n * @param request.channel - A single channel ID or an array of channel IDs to remove from the bridge.\n *\n * @returns A Promise that resolves to void when the operation is successful.\n *\n * @throws Will throw an error if the request fails, such as if the bridge doesn't exist,\n * if the channels are not in the bridge, or if there's a network issue.\n */\n async removeChannels(\n bridgeId: string,\n request: RemoveChannelRequest\n ): Promise<void> {\n const queryParams = toQueryParams({\n channel: Array.isArray(request.channel)\n ? request.channel.join(',')\n : request.channel,\n });\n\n await this.baseClient.post<void>(\n `/bridges/${bridgeId}/removeChannel?${queryParams}`\n );\n }\n\n /**\n * Plays media on a specified bridge.\n *\n * This asynchronous function initiates media playback on a bridge identified by its ID.\n * It allows for customization of the playback through various options in the request.\n *\n * @param bridgeId - The unique identifier of the bridge on which to play the media.\n * @param request - An object containing the media playback request details.\n * @param request.media - The media to be played (e.g., sound file, URL).\n * @param request.lang - Optional. The language of the media content.\n * @param request.offsetms - Optional. The offset in milliseconds to start playing from.\n * @param request.skipms - Optional. The number of milliseconds to skip before playing.\n * @param request.playbackId - Optional. A custom ID for the playback session.\n *\n * @returns A Promise that resolves to a BridgePlayback object, containing details about the initiated playback.\n *\n * @throws Will throw an error if the playback request fails or if there's a network issue.\n */\n async playMedia(\n bridgeId: string,\n request: PlayMediaRequest\n ): Promise<BridgePlayback> {\n const queryParams = toQueryParams({\n ...(request.lang && { lang: request.lang }),\n ...(request.offsetms && { offsetms: request.offsetms.toString() }),\n ...(request.skipms && { skipms: request.skipms.toString() }),\n ...(request.playbackId && { playbackId: request.playbackId }),\n });\n\n return this.baseClient.post<BridgePlayback>(\n `/bridges/${bridgeId}/play?${queryParams}`,\n { media: request.media }\n );\n }\n\n /**\n * Stops media playback on a specified bridge.\n *\n * This asynchronous function sends a DELETE request to stop the playback of media\n * on a bridge identified by its ID and a specific playback session.\n *\n * @param bridgeId - The unique identifier of the bridge where the playback is to be stopped.\n * @param playbackId - The unique identifier of the playback session to be stopped.\n *\n * @returns A Promise that resolves to void when the playback is successfully stopped.\n *\n * @throws Will throw an error if the request fails, such as if the bridge or playback session\n * doesn't exist, or if there's a network issue.\n */\n async stopPlayback(bridgeId: string, playbackId: string): Promise<void> {\n await this.baseClient.delete<void>(\n `/bridges/${bridgeId}/play/${playbackId}`\n );\n }\n\n /**\n * Sets the video source for a specified bridge.\n *\n * This asynchronous function configures a channel as the video source for a given bridge.\n * It sends a POST request to the ARI endpoint to update the bridge's video source.\n *\n * @param bridgeId - The unique identifier of the bridge for which to set the video source.\n * @param channelId - The unique identifier of the channel to be set as the video source.\n *\n * @returns A Promise that resolves to void when the video source is successfully set.\n *\n * @throws Will throw an error if the request fails, such as if the bridge or channel\n * doesn't exist, or if there's a network issue.\n */\n async setVideoSource(bridgeId: string, channelId: string): Promise<void> {\n const queryParams = toQueryParams({ channelId });\n await this.baseClient.post<void>(\n `/bridges/${bridgeId}/videoSource?${queryParams}`\n );\n }\n\n /**\n * Clears the video source for a specified bridge.\n *\n * This asynchronous function removes the currently set video source from a bridge.\n * It sends a DELETE request to the ARI endpoint to clear the video source configuration.\n *\n * @param bridgeId - The unique identifier of the bridge from which to clear the video source.\n * This should be a string that uniquely identifies the bridge in the system.\n *\n * @returns A Promise that resolves to void when the video source is successfully cleared.\n * If the operation is successful, the bridge will no longer have a designated video source.\n *\n * @throws Will throw an error if the request fails, such as if the bridge doesn't exist,\n * if there's no video source set, or if there's a network issue.\n */\n async clearVideoSource(bridgeId: string): Promise<void> {\n await this.baseClient.delete<void>(`/bridges/${bridgeId}/videoSource`);\n }\n\n /**\n * Retrieves the count of active bridge instances.\n *\n * This function returns the total number of bridge instances currently\n * managed by the Bridges class. It provides a quick way to check how many\n * active bridges are present in the system.\n *\n * @returns {number} The count of active bridge instances.\n */\n getInstanceCount(): number {\n return this.bridgeInstances.size;\n }\n\n /**\n * Checks if a bridge instance exists in the collection of managed bridges.\n *\n * This function verifies whether a bridge instance with the specified ID\n * is currently being managed by the Bridges class.\n *\n * @param bridgeId - The unique identifier of the bridge instance to check.\n * This should be a string that uniquely identifies the bridge in the system.\n *\n * @returns A boolean value indicating whether the bridge instance exists.\n * Returns true if the bridge instance is found, false otherwise.\n */\n hasInstance(bridgeId: string): boolean {\n return this.bridgeInstances.has(bridgeId);\n }\n\n /**\n * Retrieves all active bridge instances currently managed by the Bridges class.\n *\n * This method provides a way to access all the BridgeInstance objects that are\n * currently active and being managed. It returns a new Map to prevent direct\n * modification of the internal bridgeInstances collection.\n *\n * @returns A new Map object containing all active bridge instances, where the keys\n * are the bridge IDs (strings) and the values are the corresponding\n * BridgeInstance objects. If no bridges are active, an empty Map is returned.\n */\n getAllInstances(): Map<string, BridgeInstance> {\n return new Map(this.bridgeInstances);\n }\n}\n", "import type { Channel, WebSocketEvent } from './interfaces';\n\nexport function toQueryParams<T>(options: T): string {\n return new URLSearchParams(\n Object.entries(options as Record<string, string>)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => [key, value as string])\n ).toString();\n}\n\nexport function isPlaybackEvent(\n event: WebSocketEvent,\n playbackId?: string\n): event is Extract<WebSocketEvent, { playbackId: string }> {\n const hasPlayback = 'playback' in event && event.playback?.id !== undefined;\n return hasPlayback && (!playbackId || event.playback?.id === playbackId);\n}\n\n/**\n * Verifica se um evento pertence a um canal e opcionalmente valida o ID do canal.\n * @param event O evento WebSocket a ser validado.\n * @param channelId Opcional. O ID do canal a ser validado.\n * @returns Verdadeiro se o evento \u00E9 relacionado a um canal (e ao ID, se fornecido).\n */\nexport function isChannelEvent(\n event: WebSocketEvent,\n channelId?: string\n): event is Extract<WebSocketEvent, { channel: Channel }> {\n // Verifica se o evento tem a propriedade `channel`\n const hasChannel = 'channel' in event && event.channel?.id !== undefined;\n\n return hasChannel && (!channelId || event.channel?.id === channelId);\n}\n\nexport const channelEvents = [\n 'ChannelCreated',\n 'ChannelDestroyed',\n 'ChannelEnteredBridge',\n 'ChannelLeftBridge',\n 'ChannelStateChange',\n 'ChannelDtmfReceived',\n 'ChannelDialplan',\n 'ChannelCallerId',\n 'ChannelUserevent',\n 'ChannelHangupRequest',\n 'ChannelVarset',\n 'ChannelTalkingStarted',\n 'ChannelTalkingFinished',\n 'ChannelHold',\n 'ChannelUnhold',\n];\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { EventEmitter } from 'events';\nimport { isAxiosError } from 'axios';\nimport { v4 as uuidv4 } from 'uuid';\nimport type { AriClient } from '../ariClient';\nimport type { BaseClient } from '../baseClient.js';\nimport type {\n Channel,\n ChannelPlayback,\n ChannelVar,\n ExternalMediaOptions,\n OriginateRequest,\n PlaybackOptions,\n RTPStats,\n RecordingOptions,\n SnoopOptions,\n WebSocketEvent,\n} from '../interfaces';\nimport { toQueryParams } from '../utils';\nimport type { PlaybackInstance } from './playbacks';\n\n/**\n * Utility function to extract error message\n */\nconst getErrorMessage = (error: unknown): string => {\n if (isAxiosError(error)) {\n return (\n error.response?.data?.message ||\n error.message ||\n 'An axios error occurred'\n );\n }\n if (error instanceof Error) {\n return error.message;\n }\n return 'An unknown error occurred';\n};\n\n/**\n * Represents an instance of a communication channel managed by the AriClient.\n */\nexport class ChannelInstance {\n private readonly eventEmitter = new EventEmitter();\n private channelData: Channel | null = null;\n private readonly listenersMap = new Map<\n string,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n ((...args: any[]) => void)[]\n >(); // \uD83D\uDD39 Guarda listeners para remo\u00E7\u00E3o posterior\n public readonly id: string;\n\n constructor(\n private readonly client: AriClient,\n private readonly baseClient: BaseClient,\n channelId?: string\n ) {\n this.id = channelId || `channel-${Date.now()}`;\n }\n\n /**\n * Registers an event listener for specific channel events\n */\n on<T extends WebSocketEvent['type']>(\n event: T,\n listener: (data: Extract<WebSocketEvent, { type: T }>) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n // \uD83D\uDD39 Verifica se o listener j\u00E1 est\u00E1 registrado para evitar duplica\u00E7\u00E3o\n const existingListeners = this.listenersMap.get(event) || [];\n if (existingListeners.includes(listener)) {\n console.warn(\n `Listener j\u00E1 registrado para evento ${event}, reutilizando.`\n );\n return;\n }\n\n const wrappedListener = (data: WebSocketEvent) => {\n if ('channel' in data && data.channel?.id === this.id) {\n listener(data as Extract<WebSocketEvent, { type: T }>);\n }\n };\n\n this.eventEmitter.on(event, wrappedListener);\n\n // \uD83D\uDD39 Armazena o listener para futura remo\u00E7\u00E3o\n if (!this.listenersMap.has(event)) {\n this.listenersMap.set(event, []);\n }\n this.listenersMap\n .get(event)!\n .push(wrappedListener as (...args: any[]) => void);\n }\n\n /**\n * Registers a one-time event listener\n */\n once<T extends WebSocketEvent['type']>(\n event: T,\n listener: (data: Extract<WebSocketEvent, { type: T }>) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n const eventKey = `${event}-${this.id}`;\n\n // \uD83D\uDD39 Verifica se j\u00E1 existe um listener igual para evitar duplica\u00E7\u00E3o\n const existingListeners = this.listenersMap.get(eventKey) || [];\n if (existingListeners.includes(listener)) {\n console.warn(\n `One-time listener j\u00E1 registrado para evento ${eventKey}, reutilizando.`\n );\n return;\n }\n\n const wrappedListener = (data: WebSocketEvent) => {\n if ('channel' in data && data.channel?.id === this.id) {\n listener(data as Extract<WebSocketEvent, { type: T }>);\n\n // \uD83D\uDD39 Remove automaticamente o listener ap\u00F3s a primeira execu\u00E7\u00E3o\n this.off(event, wrappedListener);\n }\n };\n\n this.eventEmitter.once(event, wrappedListener);\n\n // \uD83D\uDD39 Armazena o listener para futura remo\u00E7\u00E3o\n if (!this.listenersMap.has(eventKey)) {\n this.listenersMap.set(eventKey, []);\n }\n this.listenersMap\n .get(eventKey)!\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n .push(wrappedListener as (...args: any[]) => void);\n }\n\n /**\n * Removes event listener(s) for a specific WebSocket event type.\n * If a specific listener is provided, only that listener is removed.\n * Otherwise, all listeners for the given event type are removed.\n *\n * @param {T} event - The type of WebSocket event to remove listener(s) for\n * @param {(data: WebSocketEvent) => void} [listener] - Optional specific listener to remove\n * @throws {Error} If no event type is provided\n */\n off<T extends WebSocketEvent['type']>(\n event: T,\n listener?: (data: Extract<WebSocketEvent, { type: T }>) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n if (listener) {\n this.eventEmitter.off(event, listener);\n const storedListeners = this.listenersMap.get(event) || [];\n this.listenersMap.set(\n event,\n storedListeners.filter((l) => l !== listener)\n );\n } else {\n this.eventEmitter.removeAllListeners(event);\n this.listenersMap.delete(event);\n }\n }\n\n /**\n * Cleans up the ChannelInstance, resetting its state and clearing resources.\n */\n public cleanup(): void {\n // Limpar dados do canal\n this.channelData = null;\n\n // Remover todos os listeners\n this.removeAllListeners();\n\n // Limpar o map de listeners\n this.listenersMap.clear();\n\n console.log(`Channel instance ${this.id} cleaned up`);\n }\n\n /**\n * Emits an event if it matches the current channel\n */\n emitEvent(event: WebSocketEvent): void {\n if (!event) {\n console.warn('Received invalid event');\n return;\n }\n\n if ('channel' in event && event.channel?.id === this.id) {\n this.eventEmitter.emit(event.type, event);\n }\n }\n\n /**\n * Removes all event listeners associated with the current instance.\n * This ensures that there are no lingering event handlers for the channel.\n *\n * @return {void} This method does not return a value.\n */\n removeAllListeners(): void {\n console.log(`Removing all event listeners for channel ${this.id}`);\n\n this.listenersMap.forEach((listeners, event) => {\n listeners.forEach((listener) => {\n this.eventEmitter.off(\n event as string,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n listener as (...args: any[]) => void\n );\n });\n });\n\n this.listenersMap.clear();\n this.eventEmitter.removeAllListeners();\n }\n\n /**\n * Answers the channel\n */\n async answer(): Promise<void> {\n try {\n await this.baseClient.post<void>(`/channels/${this.id}/answer`);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error answering channel ${this.id}:`, message);\n throw new Error(`Failed to answer channel: ${message}`);\n }\n }\n\n /**\n * Originates a new channel\n *\n * @param data - Channel origination configuration\n * @returns Promise resolving to the created channel\n * @throws Error if channel already exists or origination fails\n */\n async originate(data: OriginateRequest): Promise<Channel> {\n if (this.channelData) {\n throw new Error('Channel has already been created');\n }\n\n try {\n this.channelData = await this.baseClient.post<Channel, OriginateRequest>(\n '/channels',\n data\n );\n return this.channelData;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error originating channel:`, message);\n throw new Error(`Failed to originate channel: ${message}`);\n }\n }\n\n /**\n * Continues the execution of a dialplan for the current channel.\n *\n * @param {string} [context] - The dialplan context to continue execution in, if specified.\n * @param {string} [extension] - The dialplan extension to proceed with, if provided.\n * @param {number} [priority] - The priority within the dialplan extension to resume at, if specified.\n * @param {string} [label] - The label to start from within the dialplan, if given.\n * @return {Promise<void>} Resolves when the dialplan is successfully continued.\n */\n async continueDialplan(\n context?: string,\n extension?: string,\n priority?: number,\n label?: string\n ): Promise<void> {\n try {\n if (!this.channelData) {\n this.channelData = await this.getDetails();\n }\n\n await this.baseClient.post<void>(`/channels/${this.id}/continue`, {\n context,\n extension,\n priority,\n label,\n });\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(\n `Error continuing dialplan for channel ${this.id}:`,\n message\n );\n throw new Error(`Failed to continue dialplan: ${message}`);\n }\n }\n\n /**\n * Initiates a snoop operation on this channel with the provided options.\n * Snooping allows you to listen in or interact with an existing call.\n *\n * @param {SnoopOptions} options - Configuration options for the snooping operation.\n * @return {Promise<Channel>} A promise that resolves to the snooped channel data.\n * @throws {Error} If the channel is not initialized or if snooping fails.\n */\n async snoop(options: SnoopOptions): Promise<Channel> {\n try {\n if (!this.channelData) {\n this.channelData = await this.getDetails();\n }\n\n const queryParams = toQueryParams(options);\n return await this.baseClient.post<Channel>(\n `/channels/${this.id}/snoop?${queryParams}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error snooping on channel ${this.id}:`, message);\n throw new Error(`Failed to snoop channel: ${message}`);\n }\n }\n\n /**\n * Initiates a snoop operation on this channel with a specific snoop ID.\n *\n * @param {string} snoopId - The unique identifier for the snoop operation.\n * @param {SnoopOptions} options - Configuration options for the snooping operation.\n * @return {Promise<Channel>} A promise that resolves to the snooped channel data.\n * @throws {Error} If the channel is not initialized or if snooping fails.\n */\n async snoopWithId(snoopId: string, options: SnoopOptions): Promise<Channel> {\n try {\n if (!this.channelData) {\n this.channelData = await this.getDetails();\n }\n\n const queryParams = toQueryParams(options);\n return await this.baseClient.post<Channel>(\n `/channels/${this.id}/snoop/${snoopId}?${queryParams}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error snooping with ID on channel ${this.id}:`, message);\n throw new Error(`Failed to snoop channel with ID: ${message}`);\n }\n }\n\n /**\n * Plays media on the channel\n */\n async play(\n options: { media: string; lang?: string },\n playbackId?: string\n ): Promise<PlaybackInstance> {\n if (!options.media) {\n throw new Error('Media URL is required');\n }\n\n try {\n if (!this.channelData) {\n this.channelData = await this.getDetails();\n }\n\n const playback = this.client.Playback(playbackId || uuidv4());\n await this.baseClient.post<void>(\n `/channels/${this.id}/play/${playback.id}`,\n options\n );\n\n return playback;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error playing media on channel ${this.id}:`, message);\n throw new Error(`Failed to play media: ${message}`);\n }\n }\n\n /**\n * Gets the current channel details\n */\n async getDetails(): Promise<Channel> {\n try {\n if (this.channelData) {\n return this.channelData;\n }\n\n if (!this.id) {\n throw new Error('No channel ID associated with this instance');\n }\n\n const details = await this.baseClient.get<Channel>(\n `/channels/${this.id}`\n );\n this.channelData = details;\n return details;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(\n `Error retrieving channel details for ${this.id}:`,\n message\n );\n throw new Error(`Failed to get channel details: ${message}`);\n }\n }\n\n /**\n * Checks if the channel has any listeners for a specific event\n */\n hasListeners(event: string): boolean {\n return this.eventEmitter.listenerCount(event) > 0;\n }\n\n /**\n * Gets the count of listeners for a specific event\n */\n getListenerCount(event: string): number {\n return this.eventEmitter.listenerCount(event);\n }\n\n /**\n * Fetches a specific channel variable.\n *\n * @param {string} variable - The name of the variable to retrieve. This parameter is required.\n * @return {Promise<ChannelVar>} A promise that resolves with the value of the requested channel variable.\n * @throws {Error} If the 'variable' parameter is not provided.\n */\n async getVariable(variable: string): Promise<ChannelVar> {\n if (!variable) {\n throw new Error(\"The 'variable' parameter is required.\");\n }\n return this.baseClient.get<ChannelVar>(\n `/channels/${this.id}/variable?variable=${encodeURIComponent(variable)}`\n );\n }\n\n /**\n * Terminates the active call associated with the current channel.\n * This method ensures that channel details are initialized before attempting to hang up.\n * If the channel ID is invalid or cannot be determined, an error is thrown.\n *\n * @return {Promise<void>} A promise that resolves when the call is successfully terminated.\n */\n async hangup(): Promise<void> {\n if (!this.channelData) {\n this.channelData = await this.getDetails();\n }\n\n if (!this.channelData?.id) {\n throw new Error('N\u00E3o foi poss\u00EDvel inicializar o canal. ID inv\u00E1lido.');\n }\n\n await this.baseClient.delete(`/channels/${this.channelData.id}`);\n }\n\n /**\n * Plays media on the specified channel using the provided media URL and optional playback options.\n *\n * @param {string} media - The URL or identifier of the media to be played.\n * @param {PlaybackOptions} [options] - Optional playback settings such as volume, playback speed, etc.\n * @return {Promise<ChannelPlayback>} A promise that resolves with the playback details for the channel.\n * @throws {Error} Throws an error if the channel has not been created.\n */\n async playMedia(\n media: string,\n options?: PlaybackOptions\n ): Promise<ChannelPlayback> {\n if (!this.channelData) {\n throw new Error('O canal ainda n\u00E3o foi criado.');\n }\n\n const queryParams = options\n ? `?${new URLSearchParams(options as Record<string, string>).toString()}`\n : '';\n\n return this.baseClient.post<ChannelPlayback>(\n `/channels/${this.channelData.id}/play${queryParams}`,\n { media }\n );\n }\n\n /**\n * Stops the playback for the given playback ID.\n *\n * @param {string} playbackId - The unique identifier for the playback to be stopped.\n * @return {Promise<void>} A promise that resolves when the playback is successfully stopped.\n * @throws {Error} Throws an error if the instance is not associated with a channel.\n */\n async stopPlayback(playbackId: string): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.delete<void>(\n `/channels/${this.channelData.id}/play/${playbackId}`\n );\n }\n\n /**\n * Pauses the playback of the specified media on a channel.\n *\n * @param {string} playbackId - The unique identifier of the playback to be paused.\n * @return {Promise<void>} A promise that resolves when the playback has been successfully paused.\n * @throws {Error} Throws an error if the channel is not associated with the current instance.\n */\n async pausePlayback(playbackId: string): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.post<void>(\n `/channels/${this.channelData.id}/play/${playbackId}/pause`\n );\n }\n\n /**\n * Resumes playback of the specified playback session on the associated channel.\n *\n * @param {string} playbackId - The unique identifier of the playback session to be resumed.\n * @return {Promise<void>} A promise that resolves when the playback has been successfully resumed.\n * @throws {Error} Throws an error if the channel is not associated with this instance.\n */\n async resumePlayback(playbackId: string): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.delete<void>(\n `/channels/${this.channelData.id}/play/${playbackId}/pause`\n );\n }\n\n /**\n * Rewinds the playback of a media by a specified amount of milliseconds.\n *\n * @param {string} playbackId - The unique identifier for the playback session to be rewound.\n * @param {number} skipMs - The number of milliseconds to rewind the playback.\n * @return {Promise<void>} A promise that resolves when the rewind operation is complete.\n */\n async rewindPlayback(playbackId: string, skipMs: number): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.post<void>(\n `/channels/${this.channelData.id}/play/${playbackId}/rewind`,\n { skipMs }\n );\n }\n\n /**\n * Fast forwards the playback by a specific duration in milliseconds.\n *\n * @param {string} playbackId - The unique identifier of the playback to be fast-forwarded.\n * @param {number} skipMs - The number of milliseconds to fast forward the playback.\n * @return {Promise<void>} A Promise that resolves when the fast-forward operation is complete.\n * @throws {Error} If no channel is associated with this instance.\n */\n async fastForwardPlayback(playbackId: string, skipMs: number): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.post<void>(\n `/channels/${this.channelData.id}/play/${playbackId}/forward`,\n { skipMs }\n );\n }\n\n /**\n * Mutes the specified channel for the given direction.\n *\n * @param {(\"both\" | \"in\" | \"out\")} [direction=\"both\"] - The direction to mute the channel. It can be \"both\" to mute incoming and outgoing, \"in\" to mute incoming, or \"out\" to mute outgoing.\n * @return {Promise<void>} A promise that resolves when the channel is successfully muted.\n * @throws {Error} If the channel is not associated with this instance.\n */\n async muteChannel(direction: 'both' | 'in' | 'out' = 'both'): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.post<void>(\n `/channels/${this.channelData.id}/mute?direction=${direction}`\n );\n }\n\n /**\n * Unmutes a previously muted channel in the specified direction.\n *\n * @param {\"both\" | \"in\" | \"out\"} direction - The direction in which to unmute the channel.\n * Defaults to \"both\", which unmutes both incoming and outgoing communication.\n * @return {Promise<void>} A promise that resolves once the channel has been successfully unmuted.\n * @throws {Error} If the channel is not associated with the current instance.\n */\n async unmuteChannel(\n direction: 'both' | 'in' | 'out' = 'both'\n ): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.delete<void>(\n `/channels/${this.channelData.id}/mute?direction=${direction}`\n );\n }\n\n /**\n * Places the associated channel on hold if the channel is valid and linked to this instance.\n *\n * @return {Promise<void>} A promise that resolves when the hold action is successfully executed.\n * @throws {Error} Throws an error if the channel is not associated with this instance.\n */\n async holdChannel(): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.post<void>(`/channels/${this.channelData.id}/hold`);\n }\n\n /**\n * Removes the hold status from a specific channel associated with this instance.\n * The method sends a delete request to the server to release the hold on the channel.\n * If no channel is associated with this instance, an error will be thrown.\n *\n * @return {Promise<void>} A promise that resolves when the channel hold has been successfully removed.\n * @throws {Error} If no channel is associated with this instance.\n */\n async unholdChannel(): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.delete<void>(`/channels/${this.channelData.id}/hold`);\n }\n}\n\n/**\n * The `Channels` class provides a comprehensive interface for managing\n * and interacting with communication channels.\n */\nexport class Channels {\n private readonly channelInstances = new Map<string, ChannelInstance>();\n private eventQueue = new Map<string, NodeJS.Timeout>();\n\n constructor(\n private readonly baseClient: BaseClient,\n private readonly client: AriClient\n ) {}\n\n /**\n * Creates or retrieves a ChannelInstance.\n *\n * @param {Object} [params] - Optional parameters for getting/creating a channel instance\n * @param {string} [params.id] - Optional ID of an existing channel\n * @returns {ChannelInstance} The requested or new channel instance\n * @throws {Error} If channel creation/retrieval fails\n *\n * @example\n * // Create new channel without ID\n * const channel1 = client.channels.Channel();\n *\n * // Create/retrieve channel with specific ID\n * const channel2 = client.channels.Channel({ id: 'some-id' });\n */\n Channel(params?: { id?: string }): ChannelInstance {\n try {\n const id = params?.id;\n\n if (!id) {\n const instance = new ChannelInstance(this.client, this.baseClient);\n this.channelInstances.set(instance.id, instance);\n return instance;\n }\n\n if (!this.channelInstances.has(id)) {\n const instance = new ChannelInstance(this.client, this.baseClient, id);\n this.channelInstances.set(id, instance);\n return instance;\n }\n\n return this.channelInstances.get(id)!;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error creating/retrieving channel instance:`, message);\n throw new Error(`Failed to manage channel instance: ${message}`);\n }\n }\n\n public cleanup(): void {\n // Limpar event queue\n this.eventQueue.forEach((timeout) => clearTimeout(timeout));\n this.eventQueue.clear();\n\n // Limpar todas as inst\u00E2ncias\n this.remove();\n }\n\n /**\n * Removes all channel instances and cleans up their resources.\n * This method ensures proper cleanup of all channels and their associated listeners.\n */\n public remove(): void {\n // Salvar os IDs antes de come\u00E7ar a limpeza\n const channelIds = Array.from(this.channelInstances.keys());\n\n for (const channelId of channelIds) {\n try {\n const instance = this.channelInstances.get(channelId);\n if (instance) {\n instance.cleanup(); // Usar o novo m\u00E9todo cleanup\n this.channelInstances.delete(channelId);\n console.log(`Channel instance ${channelId} removed and cleaned up`);\n }\n } catch (error) {\n console.error(`Error cleaning up channel ${channelId}:`, error);\n }\n }\n\n // Garantir que o map est\u00E1 vazio\n this.channelInstances.clear();\n console.log('All channel instances have been removed and cleaned up');\n }\n\n /**\n * Retrieves the details of a specific channel.\n *\n * @param {string} id - The unique identifier of the channel to retrieve.\n * @returns {Promise<Channel>} A promise that resolves to the Channel object containing the channel details.\n * @throws {Error} If no channel ID is associated with this instance or if there's an error retrieving the channel details.\n */\n async get(id: string): Promise<Channel> {\n try {\n if (!id) {\n throw new Error('No channel ID associated with this instance');\n }\n\n return await this.baseClient.get<Channel>(`/channels/${id}`);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error retrieving channel details for ${id}:`, message);\n throw new Error(`Failed to get channel details: ${message}`);\n }\n }\n\n /**\n * Removes a channel instance from the collection.\n */\n public removeChannelInstance(channelId: string): void {\n if (!channelId) {\n throw new Error('Channel ID is required');\n }\n\n const instance = this.channelInstances.get(channelId);\n if (instance) {\n try {\n instance.cleanup();\n this.channelInstances.delete(channelId);\n console.log(`Channel instance ${channelId} removed from memory`);\n } catch (error) {\n console.error(`Error removing channel instance ${channelId}:`, error);\n throw error;\n }\n } else {\n console.warn(`Attempt to remove non-existent instance: ${channelId}`);\n }\n }\n\n /**\n * Propagates a WebSocket event to a specific channel.\n */\n public propagateEventToChannel(event: WebSocketEvent): void {\n if (!event || !('channel' in event) || !event.channel?.id) {\n console.warn('Invalid WebSocket event received');\n return;\n }\n\n const key = `${event.type}-${event.channel.id}`;\n const existing = this.eventQueue.get(key);\n if (existing) {\n clearTimeout(existing);\n }\n\n this.eventQueue.set(\n key,\n setTimeout(() => {\n const instance = this.channelInstances.get(event.channel!.id!);\n if (instance) {\n instance.emitEvent(event);\n } else {\n console.warn(\n `No instance found for channel ${event.channel!.id}. Event ignored.`\n );\n }\n this.eventQueue.delete(key);\n }, 100)\n );\n }\n\n /**\n * Initiates a new channel.\n */\n async originate(data: OriginateRequest): Promise<Channel> {\n if (!data.endpoint) {\n throw new Error('Endpoint is required for channel origination');\n }\n\n try {\n return await this.baseClient.post<Channel>('/channels', data);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error originating channel:`, message);\n throw new Error(`Failed to originate channel: ${message}`);\n }\n }\n\n /**\n * Lists all active channels.\n */\n async list(): Promise<Channel[]> {\n try {\n const channels = await this.baseClient.get<unknown>('/channels');\n if (!Array.isArray(channels)) {\n throw new Error('API response for /channels is not an array');\n }\n return channels as Channel[];\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error listing channels:`, message);\n throw new Error(`Failed to list channels: ${message}`);\n }\n }\n\n /**\n * Gets the count of active channel instances.\n */\n getInstanceCount(): number {\n return this.channelInstances.size;\n }\n\n /**\n * Checks if a channel instance exists.\n */\n hasInstance(channelId: string): boolean {\n return this.channelInstances.has(channelId);\n }\n\n /**\n * Gets all active channel instances.\n */\n getAllInstances(): Map<string, ChannelInstance> {\n return new Map(this.channelInstances);\n }\n\n /**\n * Terminates an active call on the specified channel.\n *\n * @param {string} channelId - The unique identifier of the channel to hang up.\n * @param {Object} [options] - Optional parameters for the hangup request.\n * @param {string} [options.reason_code] - A code indicating the reason for the hangup.\n * @param {string} [options.reason] - A descriptive reason for the hangup.\n * @return {Promise<void>} A promise that resolves when the call has been successfully terminated.\n */\n async hangup(\n channelId: string,\n options?: { reason_code?: string; reason?: string }\n ): Promise<void> {\n const queryParams = new URLSearchParams({\n ...(options?.reason_code && { reason_code: options.reason_code }),\n ...(options?.reason && { reason: options.reason }),\n });\n\n return this.baseClient.delete<void>(\n `/channels/${channelId}?${queryParams.toString()}`\n );\n }\n\n /**\n * Initiates snooping on a specified channel with the provided options.\n *\n * @param {string} channelId - The unique identifier of the channel to snoop on.\n * @param {SnoopOptions} options - Configuration options for the snooping operation.\n * @return {Promise<Channel>} A promise that resolves to the snooped channel data.\n */\n async snoopChannel(\n channelId: string,\n options: SnoopOptions\n ): Promise<Channel> {\n const queryParams = toQueryParams(options);\n return this.baseClient.post<Channel>(\n `/channels/${channelId}/snoop?${queryParams}`\n );\n }\n\n /**\n * Starts a silence mode for the specified channel.\n *\n * @param {string} channelId - The unique identifier of the channel where silence mode should be started.\n * @return {Promise<void>} A promise that resolves when the silence mode is successfully started.\n */\n async startSilence(channelId: string): Promise<void> {\n return this.baseClient.post<void>(`/channels/${channelId}/silence`);\n }\n\n /**\n * Stops the silence mode for a specific channel.\n *\n * @param {string} channelId - The unique identifier of the channel for which silence mode should be stopped.\n * @return {Promise<void>} A promise that resolves when the operation is complete.\n */\n async stopSilence(channelId: string): Promise<void> {\n return this.baseClient.delete<void>(`/channels/${channelId}/silence`);\n }\n\n /**\n * Retrieves the Real-Time Protocol (RTP) statistics for a specific channel.\n *\n * @param {string} channelId - The unique identifier of the channel for which RTP statistics are fetched.\n * @return {Promise<RTPStats>} A promise that resolves to the RTP statistics for the specified channel.\n */\n async getRTPStatistics(channelId: string): Promise<RTPStats> {\n return this.baseClient.get<RTPStats>(\n `/channels/${channelId}/rtp_statistics`\n );\n }\n\n /**\n * Creates an external media channel with the given options.\n *\n * @param {ExternalMediaOptions} options - The configuration options for creating the external media channel.\n * @return {Promise<Channel>} A promise that resolves with the created external media channel.\n */\n async createExternalMedia(options: ExternalMediaOptions): Promise<Channel> {\n const queryParams = toQueryParams(options);\n return this.baseClient.post<Channel>(\n `/channels/externalMedia?${queryParams}`\n );\n }\n\n /**\n * Initiates playback of a specific media item on a channel using the provided playback ID.\n *\n * @param {string} channelId - The unique identifier of the channel where playback will occur.\n * @param {string} playbackId - The unique identifier for the specific playback session.\n * @param {string} media - The media content to be played.\n * @param {PlaybackOptions} [options] - Optional playback configuration parameters.\n * @return {Promise<ChannelPlayback>} A promise that resolves with the playback details for the channel.\n */\n async playWithId(\n channelId: string,\n playbackId: string,\n media: string,\n options?: PlaybackOptions\n ): Promise<ChannelPlayback> {\n const queryParams = options ? `?${toQueryParams(options)}` : '';\n return this.baseClient.post<ChannelPlayback>(\n `/channels/${channelId}/play/${playbackId}${queryParams}`,\n { media }\n );\n }\n\n /**\n * Initiates a snoop operation on a specific channel using the provided channel ID and snoop ID.\n *\n * @param {string} channelId - The unique identifier of the channel to snoop on.\n * @param {string} snoopId - The unique identifier for the snoop operation.\n * @param {SnoopOptions} options - Additional options and parameters for the snoop operation.\n * @return {Promise<Channel>} A promise that resolves to the channel details after the snoop operation is initiated.\n */\n async snoopChannelWithId(\n channelId: string,\n snoopId: string,\n options: SnoopOptions\n ): Promise<Channel> {\n const queryParams = toQueryParams(options);\n return this.baseClient.post<Channel>(\n `/channels/${channelId}/snoop/${snoopId}?${queryParams}`\n );\n }\n\n /**\n * Starts Music on Hold for the specified channel with the provided Music on Hold class.\n *\n * @param {string} channelId - The unique identifier of the channel.\n * @param {string} mohClass - The Music on Hold class to be applied.\n * @return {Promise<void>} A promise that resolves when the operation is complete.\n */\n async startMohWithClass(channelId: string, mohClass: string): Promise<void> {\n const queryParams = `mohClass=${encodeURIComponent(mohClass)}`;\n await this.baseClient.post<void>(\n `/channels/${channelId}/moh?${queryParams}`\n );\n }\n\n /**\n * Retrieves the value of a specified variable for a given channel.\n *\n * @param {string} channelId - The unique identifier of the channel.\n * @param {string} variable - The name of the variable to retrieve.\n * @return {Promise<ChannelVar>} A promise that resolves to the value of the channel variable.\n * @throws {Error} Throws an error if the 'variable' parameter is not provided.\n */\n async getChannelVariable(\n channelId: string,\n variable: string\n ): Promise<ChannelVar> {\n if (!variable) {\n throw new Error(\"The 'variable' parameter is required.\");\n }\n return this.baseClient.get<ChannelVar>(\n `/channels/${channelId}/variable?variable=${encodeURIComponent(variable)}`\n );\n }\n\n /**\n * Sets a variable for a specific channel.\n *\n * @param {string} channelId - The unique identifier of the channel.\n * @param {string} variable - The name of the variable to be set. This parameter is required.\n * @param {string} [value] - The value of the variable to be set. This parameter is optional.\n * @return {Promise<void>} A promise that resolves when the variable is successfully set.\n * @throws {Error} Throws an error if the `variable` parameter is not provided.\n */\n async setChannelVariable(\n channelId: string,\n variable: string,\n value?: string\n ): Promise<void> {\n if (!variable) {\n throw new Error(\"The 'variable' parameter is required.\");\n }\n const queryParams = new URLSearchParams({\n variable,\n ...(value && { value }),\n });\n await this.baseClient.post<void>(\n `/channels/${channelId}/variable?${queryParams}`\n );\n }\n\n /**\n * Moves a specified channel to the given application with optional arguments.\n *\n * @param {string} channelId - The unique identifier of the channel to be moved.\n * @param {string} app - The target application to which the channel will be moved.\n * @param {string} [appArgs] - Optional arguments to be passed to the target application.\n * @return {Promise<void>} A promise that resolves when the operation is completed.\n */\n async moveToApplication(\n channelId: string,\n app: string,\n appArgs?: string\n ): Promise<void> {\n await this.baseClient.post<void>(`/channels/${channelId}/move`, {\n app,\n appArgs,\n });\n }\n\n /**\n * Continues the execution of a dialplan for a specific channel.\n *\n * @param {string} channelId - The unique identifier of the channel.\n * @param {string} [context] - The dialplan context to continue execution in, if specified.\n * @param {string} [extension] - The dialplan extension to proceed with, if provided.\n * @param {number} [priority] - The priority within the dialplan extension to resume at, if specified.\n * @param {string} [label] - The label to start from within the dialplan, if given.\n * @return {Promise<void>} Resolves when the dialplan is successfully continued.\n */\n async continueDialplan(\n channelId: string,\n context?: string,\n extension?: string,\n priority?: number,\n label?: string\n ): Promise<void> {\n await this.baseClient.post<void>(`/channels/${channelId}/continue`, {\n context,\n extension,\n priority,\n label,\n });\n }\n\n /**\n * Stops the music on hold for the specified channel.\n *\n * @param {string} channelId - The unique identifier of the channel where music on hold should be stopped.\n * @return {Promise<void>} Resolves when the music on hold is successfully stopped.\n */\n async stopMusicOnHold(channelId: string): Promise<void> {\n await this.baseClient.delete<void>(`/channels/${channelId}/moh`);\n }\n\n /**\n * Initiates the music on hold for the specified channel.\n *\n * @param {string} channelId - The unique identifier of the channel where the music on hold will be started.\n * @return {Promise<void>} A promise that resolves when the operation has been successfully invoked.\n */\n async startMusicOnHold(channelId: string): Promise<void> {\n await this.baseClient.post<void>(`/channels/${channelId}/moh`);\n }\n\n /**\n * Starts recording for a specific channel based on the provided options.\n *\n * @param {string} channelId - The unique identifier of the channel to start recording.\n * @param {RecordingOptions} options - The recording options to configure the recording process.\n * @return {Promise<Channel>} A promise that resolves to the channel object with updated recording state.\n */\n async record(channelId: string, options: RecordingOptions): Promise<Channel> {\n const queryParams = toQueryParams(options);\n return this.baseClient.post<Channel>(\n `/channels/${channelId}/record?${queryParams}`\n );\n }\n\n /**\n * Initiates a call on the specified channel with optional parameters for caller identification and timeout duration.\n *\n * @param {string} channelId - The ID of the channel where the call will be initiated.\n * @param {string} [caller] - Optional parameter specifying the name or identifier of the caller.\n * @param {number} [timeout] - Optional parameter defining the timeout duration for the call in seconds.\n * @return {Promise<void>} A promise that resolves when the call has been successfully initiated.\n */\n async dial(\n channelId: string,\n caller?: string,\n timeout?: number\n ): Promise<void> {\n const queryParams = new URLSearchParams({\n ...(caller && { caller }),\n ...(timeout && { timeout: timeout.toString() }),\n });\n await this.baseClient.post<void>(\n `/channels/${channelId}/dial?${queryParams}`\n );\n }\n\n /**\n * Redirects a channel to the specified endpoint.\n *\n * This method sends a POST request to update the redirect endpoint for the given channel.\n *\n * @param {string} channelId - The unique identifier of the channel to be redirected.\n * @param {string} endpoint - The new endpoint to redirect the channel to.\n * @return {Promise<void>} A promise that resolves when the operation is complete.\n */\n async redirectChannel(channelId: string, endpoint: string): Promise<void> {\n await this.baseClient.post<void>(\n `/channels/${channelId}/redirect?endpoint=${encodeURIComponent(endpoint)}`\n );\n }\n\n /**\n * Answers a specified channel by sending a POST request to the corresponding endpoint.\n *\n * @param {string} channelId - The unique identifier of the channel to be answered.\n * @return {Promise<void>} A promise that resolves when the channel has been successfully answered.\n */\n async answerChannel(channelId: string): Promise<void> {\n await this.baseClient.post<void>(`/channels/${channelId}/answer`);\n }\n\n /**\n * Rings the specified channel by sending a POST request to the appropriate endpoint.\n *\n * @param {string} channelId - The unique identifier of the channel to be rung.\n * @return {Promise<void>} A promise that resolves when the operation completes successfully.\n */\n async ringChannel(channelId: string): Promise<void> {\n await this.baseClient.post<void>(`/channels/${channelId}/ring`);\n }\n\n /**\n * Stops the ring channel for the specified channel ID.\n *\n * This method sends a DELETE request to the server to stop the ring action\n * associated with the provided channel ID.\n *\n * @param {string} channelId - The unique identifier of the channel for which the ring action should be stopped.\n * @return {Promise<void>} A promise that resolves when the ring channel is successfully stopped.\n */\n async stopRingChannel(channelId: string): Promise<void> {\n await this.baseClient.delete<void>(`/channels/${channelId}/ring`);\n }\n\n /**\n * Sends DTMF (Dual-Tone Multi-Frequency) signals to a specified channel.\n *\n * @param {string} channelId - The ID of the channel to which the DTMF signals should be sent.\n * @param {string} dtmf - The DTMF tones to be sent, represented as a string. Each character corresponds to a specific tone.\n * @param {Object} [options] - Optional configuration for the DTMF signal timing.\n * @param {number} [options.before] - Time in milliseconds to wait before sending the first DTMF tone.\n * @param {number} [options.between] - Time in milliseconds to wait between sending successive DTMF tones.\n * @param {number} [options.duration] - Duration in milliseconds for each DTMF tone.\n * @param {number} [options.after] - Time in milliseconds to wait after sending the last DTMF tone.\n * @return {Promise<void>} A promise that resolves when the DTMF signals are successfully sent.\n */\n async sendDTMF(\n channelId: string,\n dtmf: string,\n options?: {\n before?: number;\n between?: number;\n duration?: number;\n after?: number;\n }\n ): Promise<void> {\n const queryParams = toQueryParams({ dtmf, ...options });\n await this.baseClient.post<void>(\n `/channels/${channelId}/dtmf?${queryParams}`\n );\n }\n\n /**\n * Mutes a specified channel in the given direction.\n *\n * @param {string} channelId - The unique identifier of the channel to be muted.\n * @param {\"both\" | \"in\" | \"out\"} [direction=\"both\"] - The direction for muting, can be \"both\", \"in\", or \"out\". Default is \"both\".\n * @return {Promise<void>} A promise that resolves when the channel is successfully muted.\n */\n async muteChannel(\n channelId: string,\n direction: 'both' | 'in' | 'out' = 'both'\n ): Promise<void> {\n await this.baseClient.post<void>(\n `/channels/${channelId}/mute?direction=${direction}`\n );\n }\n\n /**\n * Unmutes a previously muted channel, allowing communication in the specified direction(s).\n *\n * @param {string} channelId - The unique identifier of the channel to be unmuted.\n * @param {\"both\" | \"in\" | \"out\"} [direction=\"both\"] - The direction of communication to unmute. Valid options are \"both\", \"in\" (incoming messages), or \"out\" (outgoing messages). Defaults to \"both\".\n * @return {Promise<void>} A promise that resolves when the channel is successfully unmuted.\n */\n async unmuteChannel(\n channelId: string,\n direction: 'both' | 'in' | 'out' = 'both'\n ): Promise<void> {\n await this.baseClient.delete<void>(\n `/channels/${channelId}/mute?direction=${direction}`\n );\n }\n\n /**\n * Places a specific channel on hold by sending a POST request to the server.\n *\n * @param {string} channelId - The unique identifier of the channel to be placed on hold.\n * @return {Promise<void>} A promise that resolves when the channel hold operation is completed.\n */\n async holdChannel(channelId: string): Promise<void> {\n await this.baseClient.post<void>(`/channels/${channelId}/hold`);\n }\n\n /**\n * Removes the hold status from a specific channel by its ID.\n *\n * @param {string} channelId - The unique identifier of the channel to unhold.\n * @return {Promise<void>} A promise that resolves when the channel hold is successfully removed.\n */\n async unholdChannel(channelId: string): Promise<void> {\n await this.baseClient.delete<void>(`/channels/${channelId}/hold`);\n }\n\n /**\n * Creates a new communication channel with the specified configuration.\n *\n * @param {OriginateRequest} data - The configuration data required to create the channel, including relevant details such as endpoint and channel variables.\n * @return {Promise<Channel>} A promise that resolves with the details of the created channel.\n */\n async createChannel(data: OriginateRequest): Promise<Channel> {\n return this.baseClient.post<Channel>('/channels/create', data);\n }\n\n /**\n * Initiates a new channel with the specified channel ID and originates a call using the provided data.\n *\n * @param {string} channelId - The unique identifier of the channel to be created.\n * @param {OriginateRequest} data - The data required to originate the call, including details such as endpoint and caller information.\n * @return {Promise<Channel>} A promise that resolves to the created Channel object.\n */\n async originateWithId(\n channelId: string,\n data: OriginateRequest\n ): Promise<Channel> {\n return this.baseClient.post<Channel>(`/channels/${channelId}`, data);\n }\n}\n", "import validate from './validate.js';\nconst byteToHex = [];\nfor (let i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n return (byteToHex[arr[offset + 0]] +\n byteToHex[arr[offset + 1]] +\n byteToHex[arr[offset + 2]] +\n byteToHex[arr[offset + 3]] +\n '-' +\n byteToHex[arr[offset + 4]] +\n byteToHex[arr[offset + 5]] +\n '-' +\n byteToHex[arr[offset + 6]] +\n byteToHex[arr[offset + 7]] +\n '-' +\n byteToHex[arr[offset + 8]] +\n byteToHex[arr[offset + 9]] +\n '-' +\n byteToHex[arr[offset + 10]] +\n byteToHex[arr[offset + 11]] +\n byteToHex[arr[offset + 12]] +\n byteToHex[arr[offset + 13]] +\n byteToHex[arr[offset + 14]] +\n byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n const uuid = unsafeStringify(arr, offset);\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;\n", "import { randomFillSync } from 'crypto';\nconst rnds8Pool = new Uint8Array(256);\nlet poolPtr = rnds8Pool.length;\nexport default function rng() {\n if (poolPtr > rnds8Pool.length - 16) {\n randomFillSync(rnds8Pool);\n poolPtr = 0;\n }\n return rnds8Pool.slice(poolPtr, (poolPtr += 16));\n}\n", "import { randomUUID } from 'crypto';\nexport default { randomUUID };\n", "import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n options = options || {};\n const rnds = options.random || (options.rng || rng)();\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n if (buf) {\n offset = offset || 0;\n for (let i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nexport default v4;\n", "import type { BaseClient } from '../baseClient.js';\nimport type { Endpoint, EndpointDetails } from '../interfaces/endpoints.types';\n\nexport class Endpoints {\n constructor(private client: BaseClient) {}\n\n /**\n * Lists all available endpoints.\n *\n * @returns A promise that resolves to an array of Endpoint objects representing all available endpoints.\n * @throws {Error} If the API response is not an array.\n */\n async list(): Promise<Endpoint[]> {\n const endpoints = await this.client.get<unknown>('/endpoints');\n\n if (!Array.isArray(endpoints)) {\n throw new Error('Resposta da API /endpoints n\u00E3o \u00E9 um array.');\n }\n\n return endpoints as Endpoint[];\n }\n\n /**\n * Retrieves details of a specific endpoint.\n *\n * @param technology - The technology of the endpoint (e.g., \"PJSIP\").\n * @param resource - The specific resource name of the endpoint (e.g., \"9001\").\n * @returns A promise that resolves to an EndpointDetails object containing the details of the specified endpoint.\n */\n async getDetails(\n technology: string,\n resource: string\n ): Promise<EndpointDetails> {\n return this.client.get<EndpointDetails>(\n `/endpoints/${technology}/${resource}`\n );\n }\n\n /**\n * Sends a message to a specific endpoint.\n *\n * @param technology - The technology of the endpoint (e.g., \"PJSIP\").\n * @param resource - The specific resource name of the endpoint (e.g., \"9001\").\n * @param message - The message payload to send to the endpoint.\n * @returns A promise that resolves when the message has been successfully sent.\n */\n async sendMessage(\n technology: string,\n resource: string,\n message: Record<string, unknown>\n ): Promise<void> {\n await this.client.post<void>(\n `/endpoints/${technology}/${resource}/sendMessage`,\n message\n );\n }\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { EventEmitter } from 'events';\nimport { isAxiosError } from 'axios';\nimport type { AriClient } from '../ariClient';\nimport type { BaseClient } from '../baseClient.js';\nimport type { Playback, WebSocketEvent } from '../interfaces';\n\n/**\n * Utility function to extract error message\n * @param error - The error object to process\n * @returns A formatted error message\n */\nconst getErrorMessage = (error: unknown): string => {\n if (isAxiosError(error)) {\n return (\n error.response?.data?.message ||\n error.message ||\n 'An axios error occurred'\n );\n }\n if (error instanceof Error) {\n return error.message;\n }\n return 'An unknown error occurred';\n};\n\n/**\n * Represents a playback instance that provides methods for controlling media playback,\n * managing event listeners, and handling playback state.\n */\nexport class PlaybackInstance {\n private readonly eventEmitter = new EventEmitter();\n private readonly listenersMap = new Map<\n string,\n ((...args: any[]) => void)[]\n >(); // \uD83D\uDD39 Guarda listeners para remo\u00E7\u00E3o posterior\n private playbackData: Playback | null = null;\n public readonly id: string;\n\n /**\n * Creates a new PlaybackInstance.\n *\n * @param {AriClient} client - ARI client for communication\n * @param {BaseClient} baseClient - Base client for HTTP requests\n * @param {string} [playbackId] - Optional playback ID, generates timestamp-based ID if not provided\n */\n constructor(\n private readonly client: AriClient,\n private readonly baseClient: BaseClient,\n private readonly playbackId: string = `playback-${Date.now()}`\n ) {\n this.id = playbackId;\n }\n\n /**\n * Registers an event listener for a specific WebSocket event type.\n *\n * @param {T} event - Event type to listen for\n * @param {(data: WebSocketEvent) => void} listener - Callback function for the event\n */\n on<T extends WebSocketEvent['type']>(\n event: T,\n listener: (data: Extract<WebSocketEvent, { type: T }>) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n // \uD83D\uDD39 Verifica se o listener j\u00E1 est\u00E1 registrado para evitar duplica\u00E7\u00E3o\n const existingListeners = this.listenersMap.get(event) || [];\n if (existingListeners.includes(listener)) {\n console.warn(\n `Listener j\u00E1 registrado para evento ${event}, reutilizando.`\n );\n return;\n }\n\n const wrappedListener = (data: WebSocketEvent) => {\n if ('playback' in data && data.playback?.id === this.id) {\n listener(data as Extract<WebSocketEvent, { type: T }>);\n }\n };\n\n this.eventEmitter.on(event, wrappedListener);\n\n // \uD83D\uDD39 Armazena o listener para futura remo\u00E7\u00E3o\n if (!this.listenersMap.has(event)) {\n this.listenersMap.set(event, []);\n }\n this.listenersMap\n .get(event)!\n .push(wrappedListener as (...args: any[]) => void);\n }\n\n /**\n * Registers a one-time event listener for a specific WebSocket event type.\n *\n * @param {T} event - Event type to listen for\n * @param {(data: WebSocketEvent) => void} listener - Callback function for the event\n */\n once<T extends WebSocketEvent['type']>(\n event: T,\n listener: (data: Extract<WebSocketEvent, { type: T }>) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n const eventKey = `${event}-${this.id}`;\n\n // \uD83D\uDD39 Verifica se j\u00E1 existe um listener igual para evitar duplica\u00E7\u00E3o\n const existingListeners = this.listenersMap.get(eventKey) || [];\n if (existingListeners.includes(listener)) {\n console.warn(\n `One-time listener j\u00E1 registrado para evento ${eventKey}, reutilizando.`\n );\n return;\n }\n\n const wrappedListener = (data: WebSocketEvent) => {\n if ('playback' in data && data.playback?.id === this.id) {\n listener(data as Extract<WebSocketEvent, { type: T }>);\n\n // \uD83D\uDD39 Remove automaticamente o listener ap\u00F3s a primeira execu\u00E7\u00E3o\n this.off(event, wrappedListener);\n }\n };\n\n this.eventEmitter.once(event, wrappedListener);\n\n // \uD83D\uDD39 Armazena o listener para futura remo\u00E7\u00E3o\n if (!this.listenersMap.has(eventKey)) {\n this.listenersMap.set(eventKey, []);\n }\n this.listenersMap\n .get(eventKey)!\n .push(wrappedListener as (...args: any[]) => void);\n }\n\n /**\n * Removes event listener(s) for a specific WebSocket event type.\n *\n * @param {T} event - Event type to remove listener(s) for\n * @param {(data: WebSocketEvent) => void} [listener] - Optional specific listener to remove\n */\n off<T extends WebSocketEvent['type']>(\n event: T,\n listener?: (data: Extract<WebSocketEvent, { type: T }>) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n if (listener) {\n this.eventEmitter.off(event, listener);\n const storedListeners = this.listenersMap.get(event) || [];\n this.listenersMap.set(\n event,\n storedListeners.filter((l) => l !== listener)\n );\n } else {\n this.eventEmitter.removeAllListeners(event);\n this.listenersMap.delete(event);\n }\n }\n\n /**\n * Cleans up the PlaybackInstance, resetting its state and clearing resources.\n */\n public cleanup(): void {\n // Limpar dados do playback\n this.playbackData = null;\n\n // Remover todos os listeners\n this.removeAllListeners();\n\n // Limpar o map de listeners\n this.listenersMap.clear();\n\n console.log(`Playback instance ${this.id} cleaned up`);\n }\n\n /**\n * Emits a WebSocket event if it matches the current playback instance.\n *\n * @param {WebSocketEvent} event - Event to emit\n */\n emitEvent(event: WebSocketEvent): void {\n if (!event) {\n console.warn('Received invalid event');\n return;\n }\n\n if ('playback' in event && event.playback?.id === this.id) {\n this.eventEmitter.emit(event.type, event);\n }\n }\n\n /**\n * Retrieves current playback data.\n *\n * @returns {Promise<Playback>} Current playback data\n * @throws {Error} If playback is not properly initialized\n */\n async get(): Promise<Playback> {\n if (!this.id) {\n throw new Error('No playback associated with this instance');\n }\n\n try {\n this.playbackData = await this.baseClient.get<Playback>(\n `/playbacks/${this.id}`\n );\n return this.playbackData;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error retrieving playback data for ${this.id}:`, message);\n throw new Error(`Failed to get playback data: ${message}`);\n }\n }\n\n /**\n * Controls playback with specified operation.\n *\n * @param {\"pause\" | \"unpause\" | \"reverse\" | \"forward\"} operation - Control operation to perform\n * @throws {Error} If playback is not properly initialized or operation fails\n */\n async control(\n operation: 'pause' | 'unpause' | 'reverse' | 'forward'\n ): Promise<void> {\n if (!this.id) {\n throw new Error('No playback associated with this instance');\n }\n\n try {\n await this.baseClient.post<void>(\n `/playbacks/${this.id}/control?operation=${operation}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error controlling playback ${this.id}:`, message);\n throw new Error(`Failed to control playback: ${message}`);\n }\n }\n\n /**\n * Stops the current playback.\n *\n * @throws {Error} If playback is not properly initialized or stop operation fails\n */\n async stop(): Promise<void> {\n if (!this.id) {\n throw new Error('No playback associated with this instance');\n }\n\n try {\n await this.baseClient.delete<void>(`/playbacks/${this.id}`);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error stopping playback ${this.id}:`, message);\n throw new Error(`Failed to stop playback: ${message}`);\n }\n }\n\n /**\n * Removes all event listeners associated with this playback instance.\n * This method clears both the internal listener map and the event emitter.\n *\n * @remarks\n * This method performs the following actions:\n * 1. Logs a message indicating the removal of listeners.\n * 2. Iterates through all stored listeners and removes them from the event emitter.\n * 3. Clears the internal listener map.\n * 4. Removes all listeners from the event emitter.\n *\n * @returns {void} This method doesn't return a value.\n */\n removeAllListeners(): void {\n console.log(`Removing all event listeners for playback ${this.id}`);\n this.listenersMap.forEach((listeners, event) => {\n listeners.forEach((listener) => {\n this.eventEmitter.off(\n event as string,\n listener as (...args: any[]) => void\n );\n });\n });\n\n this.listenersMap.clear();\n this.eventEmitter.removeAllListeners();\n }\n\n /**\n * Checks if the playback instance has any listeners for a specific event.\n *\n * @param {string} event - Event type to check\n * @returns {boolean} True if there are listeners for the event\n */\n hasListeners(event: string): boolean {\n return this.eventEmitter.listenerCount(event) > 0;\n }\n\n /**\n * Gets the current playback data without making an API call.\n *\n * @returns {Playback | null} Current playback data or null if not available\n */\n getCurrentData(): Playback | null {\n return this.playbackData;\n }\n}\n\n/**\n * Manages playback instances and their related operations in the Asterisk REST Interface.\n * This class provides functionality to create, control, and manage playback instances,\n * as well as handle WebSocket events related to playbacks.\n */\nexport class Playbacks {\n private playbackInstances = new Map<string, PlaybackInstance>();\n private eventQueue = new Map<string, NodeJS.Timeout>();\n\n constructor(\n private baseClient: BaseClient,\n private client: AriClient\n ) {}\n\n /**\n * Gets or creates a playback instance\n * @param {Object} [params] - Optional parameters for getting/creating a playback instance\n * @param {string} [params.id] - Optional ID of an existing playback\n * @returns {PlaybackInstance} The requested or new playback instance\n */\n Playback(params?: { id?: string }): PlaybackInstance {\n try {\n const id = params?.id;\n\n if (!id) {\n const instance = new PlaybackInstance(this.client, this.baseClient);\n this.playbackInstances.set(instance.id, instance);\n return instance;\n }\n\n if (!this.playbackInstances.has(id)) {\n const instance = new PlaybackInstance(this.client, this.baseClient, id);\n this.playbackInstances.set(id, instance);\n return instance;\n }\n\n return this.playbackInstances.get(id)!;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error creating/retrieving playback instance:`, message);\n throw new Error(`Failed to manage playback instance: ${message}`);\n }\n }\n\n /**\n * Cleans up resources associated with the Playbacks instance.\n * This method performs the following cleanup operations:\n * 1. Clears all pending timeouts in the event queue.\n * 2. Removes all playback instances.\n *\n * @remarks\n * This method should be called when the Playbacks instance is no longer needed\n * to ensure proper resource management and prevent memory leaks.\n *\n * @returns {void} This method doesn't return a value.\n */\n public cleanup(): void {\n // Limpar event queue\n this.eventQueue.forEach((timeout) => clearTimeout(timeout));\n this.eventQueue.clear();\n\n // Limpar todas as inst\u00E2ncias\n this.remove();\n }\n\n /**\n * Removes all playback instances and cleans up their resources.\n */\n public remove(): void {\n // Salvar os IDs antes de come\u00E7ar a limpeza\n const playbackIds = Array.from(this.playbackInstances.keys());\n\n for (const playbackId of playbackIds) {\n try {\n const instance = this.playbackInstances.get(playbackId);\n if (instance) {\n instance.cleanup(); // Usar o novo m\u00E9todo cleanup\n this.playbackInstances.delete(playbackId);\n console.log(`Playback instance ${playbackId} removed and cleaned up`);\n }\n } catch (error) {\n console.error(`Error cleaning up playback ${playbackId}:`, error);\n }\n }\n\n // Garantir que o map est\u00E1 vazio\n this.playbackInstances.clear();\n console.log('All playback instances have been removed and cleaned up');\n }\n\n /**\n * Removes a playback instance and cleans up its resources\n * @param {string} playbackId - ID of the playback instance to remove\n * @throws {Error} If the playback instance doesn't exist\n */\n public removePlaybackInstance(playbackId: string): void {\n if (!playbackId) {\n throw new Error('Playback ID is required');\n }\n\n const instance = this.playbackInstances.get(playbackId);\n if (instance) {\n try {\n instance.cleanup();\n this.playbackInstances.delete(playbackId);\n console.log(`Playback instance ${playbackId} removed from memory`);\n } catch (error) {\n console.error(`Error removing playback instance ${playbackId}:`, error);\n throw error;\n }\n } else {\n console.warn(`Attempt to remove non-existent instance: ${playbackId}`);\n }\n }\n\n /**\n * Propagates WebSocket events to the corresponding playback instance\n * @param {WebSocketEvent} event - The WebSocket event to propagate\n */\n public propagateEventToPlayback(event: WebSocketEvent): void {\n if (!event || !('playback' in event) || !event.playback?.id) {\n console.warn('Invalid WebSocket event received');\n return;\n }\n\n const key = `${event.type}-${event.playback.id}`;\n const existing = this.eventQueue.get(key);\n if (existing) {\n clearTimeout(existing);\n }\n\n this.eventQueue.set(\n key,\n setTimeout(() => {\n const instance = this.playbackInstances.get(event.playback!.id!);\n if (instance) {\n instance.emitEvent(event);\n } else {\n console.warn(\n `No instance found for playback ${event.playback!.id}. Event ignored.`\n );\n }\n this.eventQueue.delete(key);\n }, 100)\n );\n }\n\n /**\n * Retrieves details of a specific playback\n * @param {string} playbackId - ID of the playback to get details for\n * @returns {Promise<Playback>} Promise resolving to playback details\n * @throws {Error} If the playback ID is invalid or the request fails\n */\n async get(playbackId: string): Promise<Playback> {\n if (!playbackId) {\n throw new Error('Playback ID is required');\n }\n\n try {\n return await this.baseClient.get<Playback>(`/playbacks/${playbackId}`);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error getting playback details ${playbackId}:`, message);\n throw new Error(`Failed to get playback details: ${message}`);\n }\n }\n\n /**\n * Controls a specific playback instance\n * @param {string} playbackId - ID of the playback to control\n * @param {\"pause\" | \"unpause\" | \"reverse\" | \"forward\"} operation - Operation to perform\n * @throws {Error} If the playback ID is invalid or the operation fails\n */\n async control(\n playbackId: string,\n operation: 'pause' | 'unpause' | 'reverse' | 'forward'\n ): Promise<void> {\n if (!playbackId) {\n throw new Error('Playback ID is required');\n }\n\n try {\n const playback = this.Playback({ id: playbackId });\n await playback.control(operation);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error controlling playback ${playbackId}:`, message);\n throw new Error(`Failed to control playback: ${message}`);\n }\n }\n\n /**\n * Stops a specific playback instance\n * @param {string} playbackId - ID of the playback to stop\n * @throws {Error} If the playback ID is invalid or the stop operation fails\n */\n async stop(playbackId: string): Promise<void> {\n if (!playbackId) {\n throw new Error('Playback ID is required');\n }\n\n try {\n const playback = this.Playback({ id: playbackId });\n await playback.stop();\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error stopping playback ${playbackId}:`, message);\n throw new Error(`Failed to stop playback: ${message}`);\n }\n }\n\n /**\n * Gets the count of active playback instances\n * @returns {number} Number of active playback instances\n */\n getInstanceCount(): number {\n return this.playbackInstances.size;\n }\n\n /**\n * Checks if a playback instance exists\n * @param {string} playbackId - ID of the playback to check\n * @returns {boolean} True if the playback instance exists\n */\n hasInstance(playbackId: string): boolean {\n return this.playbackInstances.has(playbackId);\n }\n}\n", "import type { BaseClient } from '../baseClient.js';\nimport type { Sound, SoundListRequest } from '../interfaces/sounds.types.js';\n\nexport class Sounds {\n constructor(private client: BaseClient) {}\n\n /**\n * Lists all available sounds.\n *\n * @param params - Optional parameters to filter the list of sounds.\n * @returns A promise that resolves to an array of Sound objects.\n * @throws {Error} If the API response is not an array.\n */\n async list(params?: SoundListRequest): Promise<Sound[]> {\n const query = params\n ? `?${new URLSearchParams(params as Record<string, string>).toString()}`\n : '';\n\n const sounds = await this.client.get<unknown>(`/sounds${query}`);\n\n if (!Array.isArray(sounds)) {\n throw new Error('Resposta da API /sounds n\u00E3o \u00E9 um array.');\n }\n\n return sounds as Sound[];\n }\n\n /**\n * Retrieves details of a specific sound.\n *\n * @param soundId - The unique identifier of the sound.\n * @returns A promise that resolves to a Sound object containing the details of the specified sound.\n */\n async getDetails(soundId: string): Promise<Sound> {\n return this.client.get<Sound>(`/sounds/${soundId}`);\n }\n}\n", "import { EventEmitter } from 'events';\nimport { type IBackOffOptions, backOff } from 'exponential-backoff';\nimport WebSocket from 'ws';\nimport type { AriClient } from './ariClient';\nimport type { BaseClient } from './baseClient.js';\nimport type { WebSocketEvent, WebSocketEventType } from './interfaces';\n\nconst DEFAULT_MAX_RECONNECT_ATTEMPTS = 30;\nconst DEFAULT_STARTING_DELAY = 500;\nconst DEFAULT_MAX_DELAY = 10000;\n\n/**\n * WebSocketClient handles real-time communication with the Asterisk server.\n * Extends EventEmitter to provide event-based communication patterns.\n */\nexport class WebSocketClient extends EventEmitter {\n private ws?: WebSocket;\n private isReconnecting = false;\n private isConnecting = false; // \uD83D\uDD39 Evita m\u00FAltiplas conex\u00F5es simult\u00E2neas\n private shouldReconnect = true; // \uD83D\uDD39 Nova flag para impedir reconex\u00E3o se for um fechamento intencional\n private readonly maxReconnectAttempts = DEFAULT_MAX_RECONNECT_ATTEMPTS;\n private reconnectionAttempts = 0;\n private lastWsUrl: string = '';\n private eventQueue: Map<string, NodeJS.Timeout> = new Map();\n\n /**\n * Logs the current connection status of the WebSocket client at regular intervals.\n *\n * This method sets up an interval that logs various connection-related metrics every 60 seconds.\n * The logged information includes:\n * - The number of active connections (0 or 1)\n * - The current state of the WebSocket connection\n * - The number of reconnection attempts made\n * - The size of the event queue\n *\n * This can be useful for monitoring the health and status of the WebSocket connection over time.\n *\n * @private\n * @returns {void}\n */\n private logConnectionStatus(): void {\n setInterval(() => {\n console.log({\n connections: this.ws ? 1 : 0,\n state: this.getState(),\n reconnectAttempts: this.reconnectionAttempts,\n eventQueueSize: this.eventQueue.size,\n });\n }, 60000);\n }\n\n /**\n * Sets up a heartbeat mechanism for the WebSocket connection.\n *\n * This method creates an interval that sends a ping message every 30 seconds\n * to keep the connection alive. The heartbeat is automatically cleared when\n * the WebSocket connection is closed.\n *\n * @private\n * @returns {void}\n */\n private setupHeartbeat(): void {\n const interval = setInterval(() => {\n if (this.ws?.readyState === WebSocket.OPEN) {\n this.ws.ping();\n }\n }, 30000);\n\n this.ws!.once('close', () => clearInterval(interval));\n }\n\n private readonly backOffOptions: IBackOffOptions = {\n numOfAttempts: DEFAULT_MAX_RECONNECT_ATTEMPTS,\n startingDelay: DEFAULT_STARTING_DELAY,\n maxDelay: DEFAULT_MAX_DELAY,\n timeMultiple: 2,\n jitter: 'full',\n delayFirstAttempt: false,\n retry: (error: Error, attemptNumber: number) => {\n console.warn(\n `Connection attempt #${attemptNumber} failed:`,\n error.message || 'Unknown error'\n );\n return attemptNumber < this.maxReconnectAttempts;\n },\n };\n\n /**\n * Creates a new WebSocketClient instance.\n *\n * This constructor initializes a WebSocketClient with the necessary dependencies and configuration.\n * It ensures that at least one application name is provided.\n *\n * @param baseClient - The BaseClient instance used for basic ARI operations and authentication.\n * @param apps - An array of application names to connect to via the WebSocket.\n * @param subscribedEvents - Optional. An array of WebSocketEventTypes to subscribe to. If not provided, all events will be subscribed.\n * @param ariClient - Optional. The AriClient instance, used for creating Channel and Playback instances when processing events.\n *\n * @throws {Error} Throws an error if the apps array is empty.\n */\n constructor(\n private readonly baseClient: BaseClient,\n private apps: string[],\n private subscribedEvents?: WebSocketEventType[],\n private readonly ariClient?: AriClient\n ) {\n super();\n\n if (!apps.length) {\n throw new Error('At least one application name is required');\n }\n }\n\n /**\n * Establishes a WebSocket connection to the Asterisk server.\n *\n * This method constructs the WebSocket URL using the base URL, credentials,\n * application names, and subscribed events. It then initiates the connection\n * using the constructed URL.\n *\n * @returns A Promise that resolves when the WebSocket connection is successfully established.\n * @throws Will throw an error if the connection cannot be established.\n */\n public async connect(): Promise<void> {\n if (this.isConnecting || this.isConnected()) {\n console.warn(\n 'WebSocket is already connecting or connected. Skipping new connection.'\n );\n return;\n }\n\n this.shouldReconnect = true; // \uD83D\uDD39 Permite reconex\u00E3o caso o WebSocket caia inesperadamente\n this.isConnecting = true;\n const { baseUrl, username, password, secure } = this.baseClient.getCredentials();\n\n const protocol = secure ? 'wss' : 'ws';\n const normalizedHost = baseUrl\n .replace(/^https?:\\/\\//, '')\n .replace(/\\/ari$/, '');\n\n const queryParams = new URLSearchParams();\n \n // \u2705 Usar api_key para conex\u00F5es n\u00E3o seguras (HTTP/WS)\n if (!secure) {\n queryParams.append('api_key', `${username}:${password}`);\n }\n \n queryParams.append('app', this.apps.join(','));\n this.subscribedEvents?.forEach((event) =>\n queryParams.append('event', event)\n );\n\n // \u2705 Construir URL baseada no tipo de conex\u00E3o\n if (secure) {\n // HTTPS/WSS: usar HTTP Basic Auth na URL (seu caso)\n this.lastWsUrl = `${protocol}://${encodeURIComponent(username)}:${encodeURIComponent(password)}@${normalizedHost}/ari/events?${queryParams.toString()}`;\n } else {\n // HTTP/WS: usar api_key query parameter (caso da issue)\n this.lastWsUrl = `${protocol}://${normalizedHost}/ari/events?${queryParams.toString()}`;\n }\n\n console.log(`WebSocket URL: ${this.lastWsUrl.replace(/(api_key=)[^&]*/, '$1***')}`); // Log sem mostrar credenciais\n\n try {\n await this.initializeWebSocket(this.lastWsUrl);\n } finally {\n this.isConnecting = false;\n }\n }\n\n /**\n * Reconecta o WebSocket com uma lista atualizada de aplica\u00E7\u00F5es.\n *\n * @param {string[]} newApps - Lista de aplica\u00E7\u00F5es para reconectar\n * @param {WebSocketEventType[]} [subscribedEvents] - Tipos de eventos para se inscrever (opcional)\n * @returns {Promise<void>} Promise resolvida quando reconectado com sucesso\n */\n public async reconnectWithApps(\n newApps: string[],\n subscribedEvents?: WebSocketEventType[]\n ): Promise<void> {\n if (!newApps.length) {\n throw new Error('At least one application name is required');\n }\n\n // Mesclar aplica\u00E7\u00F5es existentes com novas\n const uniqueApps = Array.from(new Set([...this.apps, ...newApps]));\n\n // Se n\u00E3o h\u00E1 mudan\u00E7as nas aplica\u00E7\u00F5es, n\u00E3o reconectar\n if (\n uniqueApps.length === this.apps.length &&\n uniqueApps.every((app) => this.apps.includes(app))\n ) {\n console.log(\n 'No changes in applications list, maintaining current connection'\n );\n return;\n }\n\n console.log(\n `Reconnecting WebSocket with updated applications: ${uniqueApps.join(', ')}`\n );\n\n // Armazenar os aplicativos atualizados\n this.apps = uniqueApps;\n\n // Atualizar eventos inscritos se fornecidos\n if (subscribedEvents) {\n this.subscribedEvents = subscribedEvents;\n }\n\n // Fechar conex\u00E3o existente\n if (this.ws) {\n await new Promise<void>((resolve) => {\n this.once('disconnected', () => resolve());\n this.close();\n });\n }\n\n // Reconectar com apps atualizados\n await this.connect();\n console.log('WebSocket reconnected successfully with updated applications');\n }\n\n /**\n * Adiciona novas aplica\u00E7\u00F5es \u00E0 conex\u00E3o WebSocket existente.\n *\n * @param {string[]} newApps - Lista de novas aplica\u00E7\u00F5es para adicionar\n * @param {WebSocketEventType[]} [subscribedEvents] - Tipos de eventos para se inscrever (opcional)\n * @returns {Promise<void>} Promise resolvida quando as aplica\u00E7\u00F5es s\u00E3o adicionadas com sucesso\n */\n public async addApps(\n newApps: string[],\n subscribedEvents?: WebSocketEventType[]\n ): Promise<void> {\n if (!newApps.length) {\n throw new Error('At least one application name is required');\n }\n\n // Verificar se h\u00E1 novas aplica\u00E7\u00F5es que ainda n\u00E3o est\u00E3o na lista\n const appsToAdd = newApps.filter((app) => !this.apps.includes(app));\n\n if (appsToAdd.length === 0) {\n console.log('All applications are already registered');\n return;\n }\n\n // Adicionar novas aplica\u00E7\u00F5es \u00E0 lista atual\n await this.reconnectWithApps(appsToAdd, subscribedEvents);\n }\n\n /**\n * Initializes a WebSocket connection with exponential backoff retry mechanism.\n *\n * This method attempts to establish a WebSocket connection to the specified URL.\n * It sets up event listeners for the WebSocket's 'open', 'message', 'close', and 'error' events.\n * If the connection is successful, it emits a 'connected' event. If it's a reconnection,\n * it also emits a 'reconnected' event with the current apps and subscribed events.\n * In case of connection failure, it uses an exponential backoff strategy to retry.\n *\n * @param wsUrl - The WebSocket URL to connect to.\n * @returns A Promise that resolves when the connection is successfully established,\n * or rejects if an error occurs during the connection process.\n * @throws Will throw an error if the WebSocket connection cannot be established\n * after the maximum number of retry attempts.\n */\n private async initializeWebSocket(wsUrl: string): Promise<void> {\n return backOff(async () => {\n return new Promise<void>((resolve, reject) => {\n try {\n this.ws = new WebSocket(wsUrl);\n\n this.ws.once('open', () => {\n this.setupHeartbeat();\n if (this.isReconnecting) {\n this.emit('reconnected', {\n apps: this.apps,\n subscribedEvents: this.subscribedEvents,\n });\n }\n this.isReconnecting = false;\n this.reconnectionAttempts = 0;\n this.emit('connected');\n resolve();\n });\n\n this.ws.on('message', (data) => this.handleMessage(data.toString()));\n\n this.ws.once('close', (code) => {\n // \uD83D\uDD39 Usa `once` para evitar handlers duplicados\n console.warn(\n `WebSocket disconnected with code ${code}. Attempting to reconnect...`\n );\n if (!this.isReconnecting) {\n this.reconnect(this.lastWsUrl);\n }\n });\n\n this.ws.once('error', (err: Error) => {\n // \uD83D\uDD39 Usa `once` para evitar ac\u00FAmulo de eventos\n console.error('WebSocket error:', err.message);\n if (!this.isReconnecting) {\n this.reconnect(this.lastWsUrl);\n }\n reject(err);\n });\n } catch (error) {\n reject(error);\n }\n });\n }, this.backOffOptions);\n }\n\n private getEventKey(event: WebSocketEvent): string {\n // Cria uma chave \u00FAnica baseada no tipo de evento e IDs relevantes\n const ids = [];\n if ('channel' in event && event.channel?.id) ids.push(event.channel.id);\n if ('playback' in event && event.playback?.id) ids.push(event.playback.id);\n if ('bridge' in event && event.bridge?.id) ids.push(event.bridge.id);\n return `${event.type}-${ids.join('-')}`;\n }\n\n private processEvent(event: WebSocketEvent): void {\n if (\n this.subscribedEvents?.length &&\n !this.subscribedEvents.includes(event.type as WebSocketEventType)\n ) {\n return;\n }\n\n if ('channel' in event && event.channel?.id && this.ariClient) {\n const instanceChannel = this.ariClient.Channel(event.channel.id);\n instanceChannel.emitEvent(event);\n event.instanceChannel = instanceChannel;\n }\n\n if ('playback' in event && event.playback?.id && this.ariClient) {\n const instancePlayback = this.ariClient.Playback(event.playback.id);\n instancePlayback.emitEvent(event);\n event.instancePlayback = instancePlayback;\n }\n\n if ('bridge' in event && event.bridge?.id && this.ariClient) {\n const instanceBridge = this.ariClient.Bridge(event.bridge.id);\n instanceBridge.emitEvent(event);\n event.instanceBridge = instanceBridge;\n }\n\n this.emit(event.type, event);\n }\n\n /**\n * Handles incoming WebSocket messages by parsing and processing events.\n *\n * This method parses the raw message into a WebSocketEvent, filters it based on\n * subscribed events (if any), processes channel and playback events, and emits\n * the event to listeners. It also handles any errors that occur during processing.\n *\n * @param rawMessage - The raw message string received from the WebSocket connection.\n * @returns void This method doesn't return a value but emits events.\n *\n * @throws Will emit an 'error' event if the message cannot be parsed or processed.\n */\n private handleMessage(rawMessage: string): void {\n try {\n const event: WebSocketEvent = JSON.parse(rawMessage);\n\n // Debounce eventos similares\n const key = this.getEventKey(event);\n const existing = this.eventQueue.get(key);\n if (existing) {\n clearTimeout(existing);\n }\n\n this.eventQueue.set(\n key,\n setTimeout(() => {\n this.processEvent(event);\n this.eventQueue.delete(key);\n }, 100)\n );\n } catch (error) {\n console.error('Error processing WebSocket message:', error);\n this.emit('error', new Error('Failed to decode WebSocket message'));\n }\n }\n\n /**\n * Attempts to reconnect to the WebSocket server using an exponential backoff strategy.\n *\n * This method is called when the WebSocket connection is closed unexpectedly.\n * It increments the reconnection attempt counter, logs the attempt, and uses\n * the backOff utility to retry the connection with exponential delays between attempts.\n *\n * @param wsUrl - The WebSocket URL to reconnect to.\n * @returns void - This method doesn't return a value.\n *\n * @emits reconnectFailed - Emitted if all reconnection attempts fail.\n */\n private async reconnect(wsUrl: string): Promise<void> {\n if (!this.shouldReconnect) {\n console.warn(\n 'Reconnection skipped because WebSocket was intentionally closed.'\n );\n return;\n }\n\n if (this.isReconnecting) {\n console.warn('J\u00E1 h\u00E1 uma tentativa de reconex\u00E3o em andamento.');\n return;\n }\n\n this.isReconnecting = true;\n this.reconnectionAttempts++;\n console.log(`Tentando reconex\u00E3o #${this.reconnectionAttempts}...`);\n\n backOff(() => this.initializeWebSocket(wsUrl), this.backOffOptions)\n .catch((error) => {\n console.error(`Falha ao reconectar: ${error.message}`);\n this.emit('reconnectFailed', error);\n })\n .finally(() => {\n this.isReconnecting = false;\n });\n }\n\n /**\n * Closes the WebSocket connection if it exists.\n *\n * This method attempts to gracefully close the WebSocket connection\n * and sets the WebSocket instance to undefined. If an error occurs\n * during the closing process, it will be caught and logged.\n *\n * @throws {Error} Logs an error message if closing the WebSocket fails.\n */\n public async close(): Promise<void> {\n if (!this.ws) {\n console.warn('No WebSocket connection to close');\n return;\n }\n\n console.log('Closing WebSocket connection.');\n this.shouldReconnect = false;\n\n // Limpar event queue\n this.eventQueue.forEach((timeout) => clearTimeout(timeout));\n this.eventQueue.clear();\n\n const closeTimeout = setTimeout(() => {\n if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {\n this.ws.terminate();\n }\n }, 5000);\n\n try {\n this.ws.removeAllListeners();\n await new Promise<void>((resolve) => {\n this.ws!.once('close', () => {\n clearTimeout(closeTimeout);\n resolve();\n });\n this.ws!.close();\n });\n } catch (error) {\n console.error('Error closing WebSocket:', error);\n } finally {\n this.ws = undefined;\n this.emit('disconnected');\n }\n }\n\n /**\n * Checks if the WebSocket connection is currently open and active.\n *\n * This method provides a way to determine the current state of the WebSocket connection.\n * It checks if the WebSocket's readyState property is equal to WebSocket.OPEN,\n * which indicates an active connection.\n *\n * @returns {boolean} True if the WebSocket connection is open and active, false otherwise.\n */\n public isConnected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Retrieves the current state of the WebSocket connection.\n *\n * This method provides a way to check the current state of the WebSocket connection.\n * It returns a number corresponding to one of the WebSocket readyState values:\n * - 0 (CONNECTING): The connection is not yet open.\n * - 1 (OPEN): The connection is open and ready to communicate.\n * - 2 (CLOSING): The connection is in the process of closing.\n * - 3 (CLOSED): The connection is closed or couldn't be opened.\n *\n * If the WebSocket instance doesn't exist, it returns WebSocket.CLOSED (3).\n *\n * @returns {number} A number representing the current state of the WebSocket connection.\n */\n public getState(): number {\n return this.ws?.readyState ?? WebSocket.CLOSED;\n }\n\n /**\n * Cleans up the WebSocketClient instance, resetting its state and clearing resources.\n *\n * This method performs the following cleanup operations:\n * - Clears the event queue and cancels any pending timeouts.\n * - Stops any ongoing reconnection attempts.\n * - Clears the stored WebSocket URL.\n * - Resets the reconnection attempt counter.\n * - Removes all event listeners attached to this instance.\n *\n * This method is typically called when the WebSocketClient is no longer needed or\n * before reinitializing the client to ensure a clean slate.\n *\n * @returns {void} This method doesn't return a value.\n */\n public cleanup(): void {\n // Limpar event queue\n this.eventQueue.forEach((timeout) => clearTimeout(timeout));\n this.eventQueue.clear();\n\n // Parar tentativas de reconex\u00E3o\n this.shouldReconnect = false;\n this.isReconnecting = false;\n\n // Limpar URL armazenada\n this.lastWsUrl = '';\n\n // Resetar contadores\n this.reconnectionAttempts = 0;\n\n // Remover todos os listeners\n this.removeAllListeners();\n }\n}\n", "import type { BaseClient } from '../baseClient';\nimport type {\n StoredRecording,\n LiveRecording,\n GetStoredParams,\n DeleteStoredParams,\n GetStoredFileParams,\n CopyStoredParams,\n GetLiveParams,\n CancelParams,\n StopParams,\n PauseParams,\n UnpauseParams,\n MuteParams,\n UnmuteParams,\n} from '../interfaces';\n\nexport class Recordings {\n constructor(private readonly baseClient: BaseClient) {}\n /**\n * List recordings that are complete.\n * @returns Promise<StoredRecording[]>\n */\n async listStored(): Promise<StoredRecording[]> {\n return this.baseClient.get<StoredRecording[]>('/recordings/stored');\n }\n\n /**\n * Get a stored recording's details.\n * @param params - The parameters for getting a stored recording\n * @returns Promise<StoredRecording>\n */\n async getStored(params: GetStoredParams): Promise<StoredRecording> {\n return this.baseClient.get<StoredRecording>(\n `/recordings/stored/${params.recordingName}`\n );\n }\n\n /**\n * Delete a stored recording.\n * @param params - The parameters for deleting a stored recording\n * @returns Promise<void>\n */\n async deleteStored(params: DeleteStoredParams): Promise<void> {\n return this.baseClient.delete<void>(\n `/recordings/stored/${params.recordingName}`\n );\n }\n\n /**\n * Get the file associated with the stored recording.\n * @param params - The parameters for getting a stored recording file\n * @returns Promise<ArrayBuffer>\n */\n async getStoredFile(params: GetStoredFileParams): Promise<ArrayBuffer> {\n return this.baseClient.get<ArrayBuffer>(\n `/recordings/stored/${params.recordingName}/file`,\n { responseType: 'arraybuffer' }\n );\n }\n\n /**\n * Copy a stored recording.\n * @param params - The parameters for copying a stored recording\n * @returns Promise<StoredRecording>\n */\n async copyStored(params: CopyStoredParams): Promise<StoredRecording> {\n return this.baseClient.post<StoredRecording>(\n `/recordings/stored/${params.recordingName}/copy`,\n undefined,\n {\n params: {\n destinationRecordingName: params.destinationRecordingName,\n },\n }\n );\n }\n\n /**\n * List live recordings.\n * @param params - The parameters for getting a live recording\n * @returns Promise<LiveRecording>\n */\n async getLive(params: GetLiveParams): Promise<LiveRecording> {\n return this.baseClient.get<LiveRecording>(\n `/recordings/live/${params.recordingName}`\n );\n }\n\n /**\n * Stop a live recording and discard it.\n * @param params - The parameters for canceling a recording\n * @returns Promise<void>\n */\n async cancel(params: CancelParams): Promise<void> {\n return this.baseClient.delete<void>(\n `/recordings/live/${params.recordingName}`\n );\n }\n\n /**\n * Stop a live recording and store it.\n * @param params - The parameters for stopping a recording\n * @returns Promise<void>\n */\n async stop(params: StopParams): Promise<void> {\n return this.baseClient.post<void>(\n `/recordings/live/${params.recordingName}/stop`\n );\n }\n\n /**\n * Pause a live recording.\n * @param params - The parameters for pausing a recording\n * @returns Promise<void>\n */\n async pause(params: PauseParams): Promise<void> {\n return this.baseClient.post<void>(\n `/recordings/live/${params.recordingName}/pause`\n );\n }\n\n /**\n * Unpause a live recording.\n * @param params - The parameters for unpausing a recording\n * @returns Promise<void>\n */\n async unpause(params: UnpauseParams): Promise<void> {\n return this.baseClient.delete<void>(\n `/recordings/live/${params.recordingName}/pause`\n );\n }\n\n /**\n * Mute a live recording.\n * @param params - The parameters for muting a recording\n * @returns Promise<void>\n */\n async mute(params: MuteParams): Promise<void> {\n return this.baseClient.post<void>(\n `/recordings/live/${params.recordingName}/mute`\n );\n }\n\n /**\n * Unmute a live recording.\n * @param params - The parameters for unmuting a recording\n * @returns Promise<void>\n */\n async unmute(params: UnmuteParams): Promise<void> {\n return this.baseClient.delete<void>(\n `/recordings/live/${params.recordingName}/mute`\n );\n }\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { BaseClient } from './baseClient.js';\nimport type {\n AriClientConfig,\n WebSocketEvent,\n WebSocketEventType,\n} from './interfaces';\nimport type {\n TypedWebSocketEventListener,\n WebSocketEventListener,\n} from './interfaces/websocket.types';\nimport { Applications } from './resources/applications.js';\nimport { Asterisk } from './resources/asterisk';\nimport { type BridgeInstance, Bridges } from './resources/bridges';\nimport { type ChannelInstance, Channels } from './resources/channels.js';\nimport { Endpoints } from './resources/endpoints';\nimport { type PlaybackInstance, Playbacks } from './resources/playbacks';\nimport { Sounds } from './resources/sounds';\nimport { WebSocketClient } from './websocketClient.js';\nimport { Recordings } from './resources/recordings';\n\n/**\n * Main client class for interacting with the Asterisk REST Interface (ARI).\n * Provides access to various ARI resources and WebSocket event handling capabilities.\n *\n * @example\n * ```typescript\n * const client = new AriClient({\n * host: 'localhost',\n * port: 8088,\n * username: 'user',\n * password: 'secret'\n * });\n * ```\n */\nexport class AriClient {\n private readonly baseClient: BaseClient;\n private webSocketClient?: WebSocketClient;\n private eventListeners = new Map<string, WebSocketEventListener[]>();\n\n public readonly channels: Channels;\n public readonly endpoints: Endpoints;\n public readonly applications: Applications;\n public readonly playbacks: Playbacks;\n public readonly sounds: Sounds;\n public readonly asterisk: Asterisk;\n public readonly bridges: Bridges;\n public readonly recordings: Recordings;\n\n /**\n * Creates a new instance of the ARI client.\n *\n * @param {AriClientConfig} config - Configuration options for the ARI client\n * @throws {Error} If required configuration parameters are missing\n */\n constructor(private readonly config: AriClientConfig) {\n if (!config.host || !config.port || !config.username || !config.password) {\n throw new Error('Missing required configuration parameters');\n }\n\n // Normalize host and create base URL\n const httpProtocol = config.secure ? 'https' : 'http';\n const normalizedHost = config.host.replace(/^https?:\\/\\//, '');\n const baseUrl = `${httpProtocol}://${normalizedHost}:${config.port}/ari`;\n\n // Initialize base client and resources\n this.baseClient = new BaseClient(baseUrl, config.username, config.password, config.secure || false);\n\n // Initialize resource handlers\n this.channels = new Channels(this.baseClient, this);\n this.playbacks = new Playbacks(this.baseClient, this);\n this.bridges = new Bridges(this.baseClient, this);\n this.endpoints = new Endpoints(this.baseClient);\n this.applications = new Applications(this.baseClient);\n this.sounds = new Sounds(this.baseClient);\n this.asterisk = new Asterisk(this.baseClient);\n this.recordings = new Recordings(this.baseClient);\n\n console.log(`ARI Client initialized with base URL: ${baseUrl}`);\n }\n\n public async cleanup(): Promise<void> {\n try {\n console.log('Starting ARI Client cleanup...');\n\n // Primeiro limpa o WebSocket para evitar novos eventos\n if (this.webSocketClient) {\n await this.closeWebSocket();\n }\n\n // Limpar todos os resources em paralelo\n await Promise.all([\n // Cleanup de channels\n (async () => {\n try {\n this.channels.cleanup();\n } catch (error) {\n console.error('Error cleaning up channels:', error);\n }\n })(),\n // Cleanup de playbacks\n (async () => {\n try {\n this.playbacks.cleanup();\n } catch (error) {\n console.error('Error cleaning up playbacks:', error);\n }\n })(),\n // Cleanup de bridges\n (async () => {\n try {\n this.bridges.cleanup();\n } catch (error) {\n console.error('Error cleaning up bridges:', error);\n }\n })(),\n ]);\n\n // Limpar listeners do cliente ARI\n this.eventListeners.forEach((listeners, event) => {\n listeners.forEach((listener) => {\n this.off(event as WebSocketEvent['type'], listener);\n });\n });\n this.eventListeners.clear();\n\n console.log('ARI Client cleanup completed successfully');\n } catch (error) {\n console.error('Error during ARI Client cleanup:', error);\n throw error;\n }\n }\n\n /**\n * Initializes a WebSocket connection for receiving events.\n *\n * @param {string[]} apps - List of application names to subscribe to\n * @param {WebSocketEventType[]} [subscribedEvents] - Optional list of specific event types to subscribe to\n * @returns {Promise<void>} Resolves when connection is established\n * @throws {Error} If connection fails\n */\n public async connectWebSocket(\n apps: string[],\n subscribedEvents?: WebSocketEventType[]\n ): Promise<void> {\n try {\n if (!apps.length) {\n throw new Error('At least one application name is required.');\n }\n\n // Se j\u00E1 existe uma conex\u00E3o, apenas adicione novas aplica\u00E7\u00F5es sem fechar\n if (this.webSocketClient && this.webSocketClient.isConnected()) {\n console.log(\n 'WebSocket already connected. Reconnecting with updated apps...'\n );\n await this.webSocketClient.reconnectWithApps(apps, subscribedEvents);\n return;\n }\n\n // Criar nova conex\u00E3o (apenas se n\u00E3o existir uma ativa)\n this.webSocketClient = new WebSocketClient(\n this.baseClient,\n apps,\n subscribedEvents,\n this\n );\n\n await this.webSocketClient.connect();\n } catch (error) {\n console.error('Failed to establish WebSocket connection:', error);\n throw error;\n }\n }\n\n /**\n * Adds applications to the existing WebSocket connection.\n *\n * @param {string[]} apps - Additional applications to subscribe to\n * @param {WebSocketEventType[]} [subscribedEvents] - Optional list of specific event types to subscribe to\n * @returns {Promise<void>} Resolves when applications are added successfully\n * @throws {Error} If no WebSocket connection exists or if the operation fails\n */\n public async addApplicationsToWebSocket(\n apps: string[],\n subscribedEvents?: WebSocketEventType[]\n ): Promise<void> {\n if (!this.webSocketClient || !this.webSocketClient.isConnected()) {\n throw new Error(\n 'No active WebSocket connection. Create one first with connectWebSocket().'\n );\n }\n\n await this.webSocketClient.addApps(apps, subscribedEvents);\n }\n\n /**\n * Destroys the ARI Client instance, cleaning up all resources and removing circular references.\n * This method should be called when the ARI Client is no longer needed to ensure proper cleanup.\n *\n * @returns {Promise<void>} A promise that resolves when the destruction process is complete.\n * @throws {Error} If an error occurs during the destruction process.\n */\n public async destroy(): Promise<void> {\n try {\n console.log('Destroying ARI Client...');\n\n // Cleanup de todos os recursos\n await this.cleanup();\n\n // Limpar refer\u00EAncias\n this.webSocketClient = undefined;\n\n // Remover todas as refer\u00EAncias circulares\n (this.channels as any) = null;\n (this.playbacks as any) = null;\n (this.bridges as any) = null;\n (this.endpoints as any) = null;\n (this.applications as any) = null;\n (this.sounds as any) = null;\n (this.asterisk as any) = null;\n (this.recordings as any) = null;\n\n console.log('ARI Client destroyed successfully');\n } catch (error) {\n console.error('Error destroying ARI Client:', error);\n throw error;\n }\n }\n\n /**\n * Registers an event listener for WebSocket events.\n *\n * @param {T} event - The event type to listen for\n * @param {Function} listener - Callback function for handling the event\n * @throws {Error} If WebSocket is not connected\n */\n /**\n * Registers an event listener for WebSocket events.\n *\n * @param {T} event - The event type to listen for\n * @param {Function} listener - Callback function for handling the event\n * @throws {Error} If WebSocket is not connected\n */\n public on<T extends WebSocketEvent['type']>(\n event: T,\n listener: TypedWebSocketEventListener<T>\n ): void {\n if (!this.webSocketClient) {\n throw new Error('WebSocket is not connected');\n }\n\n // \uD83D\uDD39 Verifica se o listener j\u00E1 est\u00E1 registrado para evitar duplica\u00E7\u00E3o\n const existingListeners = this.eventListeners.get(event) || [];\n if (existingListeners.includes(listener as WebSocketEventListener)) {\n console.warn(`Listener already registered for event ${event}, reusing.`);\n return;\n }\n\n // Conectar o listener diretamente\n this.webSocketClient.on(event, listener);\n\n // Armazenar o listener para refer\u00EAncia e limpeza futura\n existingListeners.push(listener as WebSocketEventListener);\n this.eventListeners.set(event, existingListeners);\n\n console.log(`Event listener successfully registered for ${event}`);\n }\n\n /**\n * Registers a one-time event listener for WebSocket events.\n *\n * @param {T} event - The event type to listen for\n * @param {Function} listener - Callback function for handling the event\n * @throws {Error} If WebSocket is not connected\n */\n public once<T extends WebSocketEvent['type']>(\n event: T,\n listener: TypedWebSocketEventListener<T>\n ): void {\n if (!this.webSocketClient) {\n throw new Error('WebSocket is not connected');\n }\n\n // \uD83D\uDD39 Check if an identical listener already exists to avoid duplication\n const existingListeners = this.eventListeners.get(event) || [];\n if (existingListeners.includes(listener as WebSocketEventListener)) {\n console.warn(\n `One-time listener already registered for event ${event}, reusing.`\n );\n return;\n }\n\n const wrappedListener = (data: Extract<WebSocketEvent, { type: T }>) => {\n listener(data);\n this.off(event, wrappedListener);\n };\n\n this.webSocketClient.once(event, wrappedListener);\n this.eventListeners.set(event, [\n ...existingListeners,\n wrappedListener as WebSocketEventListener,\n ]);\n\n console.log(`One-time event listener registered for ${event}`);\n }\n\n /**\n * Removes an event listener for WebSocket events.\n *\n * @param {T} event - The event type to remove listener for\n * @param {Function} listener - The listener function to remove\n */\n public off<T extends WebSocketEvent['type']>(\n event: T,\n listener: TypedWebSocketEventListener<T>\n ): void {\n if (!this.webSocketClient) {\n console.warn('No WebSocket connection to remove listener from');\n return;\n }\n\n this.webSocketClient.off(event, listener);\n const existingListeners = this.eventListeners.get(event) || [];\n this.eventListeners.set(\n event,\n existingListeners.filter(\n (l) => l !== (listener as WebSocketEventListener)\n )\n );\n\n console.log(`Event listener removed for ${event}`);\n }\n\n /**\n * Closes the WebSocket connection if one exists.\n */\n public closeWebSocket(): Promise<void> {\n return new Promise((resolve) => {\n if (!this.webSocketClient) {\n console.warn('No WebSocket connection to close');\n resolve();\n return;\n }\n\n console.log('Closing WebSocket connection and cleaning up listeners.');\n\n const closeTimeout = setTimeout(() => {\n if (this.webSocketClient) {\n this.webSocketClient.removeAllListeners();\n this.webSocketClient = undefined;\n }\n resolve();\n }, 5000);\n\n this.eventListeners.forEach((listeners, event) => {\n listeners.forEach((listener) => {\n this.webSocketClient?.off(\n event as WebSocketEvent['type'],\n listener as (...args: any[]) => void\n );\n });\n });\n this.eventListeners.clear();\n\n this.webSocketClient.once('close', () => {\n clearTimeout(closeTimeout);\n this.webSocketClient = undefined;\n console.log('WebSocket connection closed');\n resolve();\n });\n\n this.webSocketClient\n .close()\n .then(() => {\n clearTimeout(closeTimeout);\n this.webSocketClient = undefined;\n resolve();\n })\n .catch((error) => {\n console.error('Error during WebSocket close:', error);\n clearTimeout(closeTimeout);\n this.webSocketClient = undefined;\n resolve();\n });\n });\n }\n\n /**\n * Creates or retrieves a Channel instance.\n *\n * @param {string} [channelId] - Optional ID of an existing channel\n * @returns {ChannelInstance} A new or existing channel instance\n */\n public Channel(channelId?: string): ChannelInstance {\n return this.channels.Channel({ id: channelId });\n }\n\n /**\n * Creates or retrieves a Playback instance.\n *\n * @param {string} [playbackId] - Optional ID of an existing playback\n * @param {string} [_app] - Optional application name (deprecated)\n * @returns {PlaybackInstance} A new or existing playback instance\n */\n public Playback(playbackId?: string, _app?: string): PlaybackInstance {\n return this.playbacks.Playback({ id: playbackId });\n }\n\n /**\n * Creates or retrieves a Bridge instance.\n *\n * This function allows you to create a new Bridge instance or retrieve an existing one\n * based on the provided bridge ID.\n *\n * @param {string} [bridgeId] - Optional ID of an existing bridge. If provided, retrieves the\n * existing bridge with this ID. If omitted, creates a new bridge.\n * @returns {BridgeInstance} A new or existing Bridge instance that can be used to interact\n * with the Asterisk bridge.\n */\n public Bridge(bridgeId?: string): BridgeInstance {\n return this.bridges.Bridge({ id: bridgeId });\n }\n\n /**\n * Gets the current WebSocket connection status.\n *\n * @returns {boolean} True if WebSocket is connected, false otherwise\n */\n public isWebSocketConnected(): boolean {\n return !!this.webSocketClient && this.webSocketClient.isConnected();\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": [null, null, null, null, null, null, null, null, null, "/**\n * @file Main entry point for the Asterisk REST Interface (ARI) client package\n * @description This file exports all the necessary classes, types and interfaces for interacting with the ARI\n */\n\n/**\n * Main client class for interacting with Asterisk REST Interface\n * @packageDocumentation\n */\nexport { AriClient } from './ari-client/ariClient.js';\n\n/**\n * Resource Classes\n * These classes provide direct access to ARI resources\n */\nexport { Channels, ChannelInstance } from './ari-client/resources/channels.js';\n\nexport { Endpoints } from './ari-client/resources/endpoints.js';\nexport { Applications } from './ari-client/resources/applications.js';\nexport { Sounds } from './ari-client/resources/sounds.js';\nexport {\n Playbacks,\n PlaybackInstance,\n} from './ari-client/resources/playbacks.js';\nexport { Asterisk } from './ari-client/resources/asterisk.js';\nexport { Bridges, BridgeInstance } from './ari-client/resources/bridges.js';\n\n/**\n * Type Definitions\n * These types and interfaces define the shape of data structures used throughout the API\n */\n\n// Configuration Types\nexport type {\n AriClientConfig,\n AriApplication,\n} from './ari-client/interfaces/index.js';\n\n// Channel Related Types\nexport type {\n Channel,\n ChannelEvent,\n ChannelPlayback,\n ChannelVar,\n ChannelDialplan,\n OriginateRequest,\n RecordingOptions,\n SnoopOptions,\n ExternalMediaOptions,\n RTPStats,\n} from './ari-client/interfaces/index.js';\n\n// Playback Related Types\nexport type {\n Playback,\n PlaybackEvent,\n PlaybackOptions,\n PlaybackControlRequest,\n PlayMediaRequest,\n} from './ari-client/interfaces/index.js';\n\n// Bridge Related Types\nexport type {\n Bridge,\n BridgePlayback,\n CreateBridgeRequest,\n RemoveChannelRequest,\n AddChannelRequest,\n} from './ari-client/interfaces/index.js';\n\n// Endpoint Related Types\nexport type {\n Endpoint,\n EndpointDetails,\n} from './ari-client/interfaces/index.js';\n\n// Application Related Types\nexport type {\n Application,\n ApplicationDetails,\n} from './ari-client/interfaces/index.js';\n\n// Sound Related Types\nexport type { Sound, SoundListRequest } from './ari-client/interfaces/index.js';\n\n// Asterisk Related Types\nexport type {\n AsteriskInfo,\n Module,\n Logging,\n Variable,\n AsteriskPing,\n} from './ari-client/interfaces/index.js';\n\n// WebSocket Related Types\nexport type {\n AriEventMap,\n WebSocketEvent,\n WebSocketEventType,\n // Eventos individuais\n ChannelDtmfReceived,\n ChannelDialplanEvent,\n ChannelVarset,\n StasisStart,\n PlaybackStarted,\n PlaybackContinuing,\n PlaybackFinished,\n BridgeCreated,\n BridgeDestroyed,\n ChannelCreated,\n ChannelDestroyed,\n ApplicationMoveFailed,\n RecordingStarted,\n RecordingFinished,\n RecordingFailed,\n DeviceStateChanged,\n BridgeMerged,\n BridgeBlindTransfer,\n BridgeAttendedTransfer,\n BridgeVideoSourceChanged,\n ChannelEnteredBridge,\n ChannelLeftBridge,\n ChannelStateChange,\n ChannelTalkingStarted,\n ChannelTalkingFinished,\n ChannelUnhold,\n ChannelHold,\n ContactStatusChange,\n EndpointStateChange,\n Dial,\n StasisEnd,\n TextMessageReceived,\n ChannelConnectedLine,\n ChannelHangupRequest,\n PeerStatusChange,\n} from './ari-client/interfaces/index.js';\n", "import axios, {\n type AxiosInstance,\n type AxiosRequestConfig,\n isAxiosError,\n} from 'axios';\n\n/**\n * Custom error class for HTTP-related errors\n */\nclass HTTPError extends Error {\n constructor(\n message: string,\n public readonly status?: number,\n public readonly method?: string,\n public readonly url?: string\n ) {\n super(message);\n this.name = 'HTTPError';\n }\n}\n\n/**\n * BaseClient handles HTTP communications with the ARI server.\n * Provides methods for making HTTP requests and manages authentication and error handling.\n */\nexport class BaseClient {\n private readonly client: AxiosInstance;\n\n /**\n * Creates a new BaseClient instance.\n *\n * @param {string} baseUrl - The base URL for the API\n * @param {string} username - Username for authentication\n * @param {string} password - Password for authentication\n * @param {boolean} [secure=false] - Whether to use secure connections (HTTPS/WSS)\n * @param {number} [timeout=5000] - Request timeout in milliseconds\n * @throws {Error} If the base URL format is invalid\n */\n constructor(\n private readonly baseUrl: string,\n private readonly username: string,\n private readonly password: string,\n private readonly secure: boolean = false,\n timeout = 5000\n ) {\n if (!/^https?:\\/\\/.+/.test(baseUrl)) {\n throw new Error(\n 'Invalid base URL. It must start with http:// or https://'\n );\n }\n\n this.client = axios.create({\n baseURL: baseUrl,\n auth: { username, password },\n timeout,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n this.addInterceptors();\n }\n\n /**\n * Gets the base URL of the client.\n */\n public getBaseUrl(): string {\n return this.baseUrl;\n }\n\n /**\n * Gets the configured credentials including security settings.\n * Used by WebSocketClient to determine authentication method.\n */\n public getCredentials(): {\n baseUrl: string;\n username: string;\n password: string;\n secure: boolean;\n } {\n return {\n baseUrl: this.baseUrl,\n username: this.username,\n password: this.password,\n secure: this.secure,\n };\n }\n\n /**\n * Adds request and response interceptors to the Axios instance.\n */\n private addInterceptors(): void {\n this.client.interceptors.request.use(\n (config) => {\n return config;\n },\n (error: unknown) => {\n const message = this.getErrorMessage(error);\n console.error('[Request Error]', message);\n return Promise.reject(new HTTPError(message));\n }\n );\n\n this.client.interceptors.response.use(\n (response) => {\n return response;\n },\n (error: unknown) => {\n if (isAxiosError(error)) {\n const status = error.response?.status ?? 0;\n const method = error.config?.method?.toUpperCase() ?? 'UNKNOWN';\n const url = error.config?.url ?? 'unknown-url';\n const message =\n error.response?.data?.message || error.message || 'Unknown error';\n\n if (status === 404) {\n console.warn(`[404] Not Found: ${url}`);\n } else if (status >= 500) {\n console.error(`[${status}] Server Error: ${url}`);\n } else if (status > 0) {\n console.warn(`[${status}] ${method} ${url}: ${message}`);\n } else {\n console.error(`[Network] Request failed: ${message}`);\n }\n\n throw new HTTPError(message, status || undefined, method, url);\n }\n\n const message = this.getErrorMessage(error);\n console.error('[Unexpected Error]', message);\n throw new Error(message);\n }\n );\n }\n\n /**\n * Executes a GET request.\n *\n * @param path - API endpoint path\n * @param config - Optional Axios request configuration\n * @returns Promise with the response data\n */\n async get<T>(path: string, config?: AxiosRequestConfig): Promise<T> {\n try {\n const response = await this.client.get<T>(path, config);\n return response.data;\n } catch (error: unknown) {\n throw this.handleRequestError(error);\n }\n }\n\n /**\n * Executes a POST request.\n *\n * @param path - API endpoint path\n * @param data - Request payload\n * @param config - Optional Axios request configuration\n * @returns Promise with the response data\n */\n async post<T, D = unknown>(\n path: string,\n data?: D,\n config?: AxiosRequestConfig\n ): Promise<T> {\n try {\n const response = await this.client.post<T>(path, data, config);\n return response.data;\n } catch (error: unknown) {\n throw this.handleRequestError(error);\n }\n }\n\n /**\n * Executes a PUT request.\n *\n * @param path - API endpoint path\n * @param data - Request payload\n * @param config - Optional Axios request configuration\n * @returns Promise with the response data\n */\n async put<T, D = unknown>(\n path: string,\n data: D,\n config?: AxiosRequestConfig\n ): Promise<T> {\n try {\n const response = await this.client.put<T>(path, data, config);\n return response.data;\n } catch (error: unknown) {\n throw this.handleRequestError(error);\n }\n }\n\n /**\n * Executes a DELETE request.\n *\n * @param path - API endpoint path\n * @param config - Optional Axios request configuration\n * @returns Promise with the response data\n */\n async delete<T>(path: string, config?: AxiosRequestConfig): Promise<T> {\n try {\n const response = await this.client.delete<T>(path, config);\n return response.data;\n } catch (error: unknown) {\n throw this.handleRequestError(error);\n }\n }\n\n /**\n * Handles and formats error messages from various error types.\n */\n private getErrorMessage(error: unknown): string {\n if (isAxiosError(error)) {\n return error.response?.data?.message || error.message || 'HTTP Error';\n }\n if (error instanceof Error) {\n return error.message;\n }\n return 'An unknown error occurred';\n }\n\n /**\n * Handles errors from HTTP requests.\n */\n private handleRequestError(error: unknown): never {\n const message = this.getErrorMessage(error);\n if (isAxiosError(error)) {\n throw new HTTPError(\n message,\n error.response?.status,\n error.config?.method?.toUpperCase(),\n error.config?.url\n );\n }\n throw new Error(message);\n }\n\n /**\n * Sets custom headers for the client instance.\n */\n setHeaders(headers: Record<string, string>): void {\n this.client.defaults.headers.common = {\n ...this.client.defaults.headers.common,\n ...headers,\n };\n }\n\n /**\n * Gets the current request timeout setting.\n */\n getTimeout(): number {\n return this.client.defaults.timeout || 5000;\n }\n\n /**\n * Updates the request timeout setting.\n */\n setTimeout(timeout: number): void {\n this.client.defaults.timeout = timeout;\n }\n}\n", "import type { BaseClient } from '../baseClient.js';\nimport type {\n Application,\n ApplicationDetails,\n} from '../interfaces/applications.types.js';\n\nexport interface ApplicationMessage {\n event: string;\n data?: Record<string, any>;\n}\n\nexport class Applications {\n constructor(private client: BaseClient) {}\n\n /**\n * Lists all applications.\n *\n * @returns A promise that resolves to an array of Application objects.\n * @throws {Error} If the API response is not an array.\n */\n async list(): Promise<Application[]> {\n const applications = await this.client.get<unknown>('/applications');\n\n if (!Array.isArray(applications)) {\n throw new Error('Resposta da API /applications n\u00E3o \u00E9 um array.');\n }\n\n return applications as Application[];\n }\n\n /**\n * Retrieves details of a specific application.\n *\n * @param appName - The name of the application to retrieve details for.\n * @returns A promise that resolves to an ApplicationDetails object.\n * @throws {Error} If there's an error fetching the application details.\n */\n async getDetails(appName: string): Promise<ApplicationDetails> {\n try {\n return await this.client.get<ApplicationDetails>(\n `/applications/${appName}`\n );\n } catch (error) {\n console.error(`Erro ao obter detalhes do aplicativo ${appName}:`, error);\n throw error;\n }\n }\n\n /**\n * Sends a message to a specific application.\n *\n * @param appName - The name of the application to send the message to.\n * @param body - The message to be sent, containing an event and optional data.\n * @returns A promise that resolves when the message is successfully sent.\n */\n async sendMessage(appName: string, body: ApplicationMessage): Promise<void> {\n await this.client.post<void>(`/applications/${appName}/messages`, body);\n }\n}\n", "import type { BaseClient } from '../baseClient.js';\nimport type {\n AsteriskInfo,\n AsteriskPing,\n Logging,\n Module,\n Variable,\n} from '../interfaces';\n\nfunction toQueryParams<T>(options: T): string {\n return new URLSearchParams(\n Object.entries(options as Record<string, string>)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => [key, String(value)])\n ).toString();\n}\n\nexport class Asterisk {\n constructor(private client: BaseClient) {}\n\n async ping(): Promise<AsteriskPing> {\n return this.client.get<AsteriskPing>('/asterisk/ping');\n }\n\n /**\n * Retrieves information about the Asterisk server.\n */\n async get(): Promise<AsteriskInfo> {\n return this.client.get<AsteriskInfo>('/asterisk/info');\n }\n\n /**\n * Lists all loaded modules in the Asterisk server.\n */\n async list(): Promise<Module[]> {\n return this.client.get<Module[]>('/asterisk/modules');\n }\n\n /**\n * Manages a specific module in the Asterisk server.\n *\n * @param moduleName - The name of the module to manage.\n * @param action - The action to perform on the module: \"load\", \"unload\", or \"reload\".\n * @returns A promise that resolves when the action is completed successfully.\n * @throws {Error} Throws an error if the HTTP method or action is invalid.\n */\n async manage(\n moduleName: string,\n action: 'load' | 'unload' | 'reload'\n ): Promise<void> {\n const url = `/asterisk/modules/${moduleName}`;\n switch (action) {\n case 'load':\n await this.client.post<void>(`${url}?action=load`);\n break;\n case 'unload':\n await this.client.delete<void>(url);\n break;\n case 'reload':\n await this.client.put<void>(url, {});\n break;\n default:\n throw new Error(`A\u00E7\u00E3o inv\u00E1lida: ${action}`);\n }\n }\n\n /**\n * Retrieves all configured logging channels.\n */\n async listLoggingChannels(): Promise<Logging[]> {\n return this.client.get<Logging[]>('/asterisk/logging');\n }\n\n /**\n * Adds or removes a log channel in the Asterisk server.\n */\n async manageLogChannel(\n logChannelName: string,\n action: 'add' | 'remove',\n configuration?: { type?: string; configuration?: string }\n ): Promise<void> {\n const queryParams = toQueryParams(configuration || {});\n return this.client.post<void>(\n `/asterisk/logging/${logChannelName}?action=${encodeURIComponent(action)}&${queryParams}`\n );\n }\n\n /**\n * Retrieves the value of a global variable.\n */\n async getGlobalVariable(variableName: string): Promise<Variable> {\n return this.client.get<Variable>(\n `/asterisk/variables?variable=${encodeURIComponent(variableName)}`\n );\n }\n\n /**\n * Sets a global variable.\n */\n async setGlobalVariable(variableName: string, value: string): Promise<void> {\n return this.client.post<void>(\n `/asterisk/variables?variable=${encodeURIComponent(variableName)}&value=${encodeURIComponent(value)}`\n );\n }\n}\n", "import { EventEmitter } from 'events';\nimport { isAxiosError } from 'axios';\nimport type { AriClient } from '../ariClient';\nimport type { BaseClient } from '../baseClient.js';\nimport type {\n AddChannelRequest,\n AriEventMap,\n Bridge,\n BridgePlayback,\n CreateBridgeRequest,\n PlayMediaRequest,\n RemoveChannelRequest,\n WebSocketEvent,\n} from '../interfaces';\nimport { bridgeEvents } from '../interfaces/events.types';\nimport { toQueryParams } from '../utils';\n\n/**\n * Extracts an error message from various error types.\n *\n * This utility function attempts to retrieve the most relevant error message\n * from different error objects, including Axios errors and standard Error instances.\n *\n * @param error - The error object to extract the message from.\n * Can be of type AxiosError, Error, or any unknown type.\n *\n * @returns A string containing the extracted error message.\n * For Axios errors, it prioritizes the response data message,\n * then falls back to the error message, and finally a default Axios error message.\n * For standard Error instances, it returns the error message.\n * For unknown error types, it returns a generic error message.\n */\nconst getErrorMessage = (error: unknown): string => {\n if (isAxiosError(error)) {\n return (\n error.response?.data?.message ||\n error.message ||\n 'Um erro do axios ocorreu'\n );\n }\n if (error instanceof Error) {\n return error.message;\n }\n return 'Um erro desconhecido ocorreu';\n};\n\n/**\n * Represents an instance of a Bridge that provides methods to control\n * bridges, manage event listeners, and manipulate its state.\n */\nexport class BridgeInstance {\n private readonly eventEmitter = new EventEmitter();\n // biome-ignore lint/suspicious/noExplicitAny: Maps original listener \u2192 wrapped listener per event\n private readonly listenersMap = new Map<string, Map<(...args: any[]) => void, (...args: any[]) => void>>();\n private bridgeData: Bridge | null = null;\n public readonly id: string;\n\n /**\n * Creates a new BridgeInstance.\n *\n * @param client - The AriClient instance for making API calls.\n * @param baseClient - The BaseClient instance for making HTTP requests.\n * @param bridgeId - Optional. The ID of the bridge. If not provided, a new ID will be generated.\n */\n constructor(\n private readonly client: AriClient,\n private readonly baseClient: BaseClient,\n bridgeId?: string\n ) {\n this.id = bridgeId || `bridge-${Date.now()}`;\n }\n\n /**\n * Registers a listener for specific bridge events.\n *\n * @param event - The type of event to listen for.\n * @param listener - The callback function to be called when the event occurs.\n *\n * @example\n * bridge.on('BridgeCreated', (event) => {\n *\n * });\n */\n on<K extends keyof AriEventMap>(\n event: K,\n listener: (data: AriEventMap[K]) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n const eventListeners = this.listenersMap.get(event) ?? new Map();\n if (eventListeners.has(listener)) {\n console.warn(\n `Listener j\u00E1 registrado para evento ${event}, reutilizando.`\n );\n return;\n }\n\n const wrappedListener = (data: WebSocketEvent) => {\n if ('bridge' in data && data.bridge?.id === this.id) {\n listener(data as AriEventMap[K]);\n }\n };\n\n this.eventEmitter.on(event, wrappedListener);\n eventListeners.set(listener, wrappedListener as (...args: any[]) => void);\n this.listenersMap.set(event, eventListeners);\n }\n\n /**\n * Registers a one-time listener for specific bridge events.\n *\n * @param event - The type of event to listen for.\n * @param listener - The callback function to be called when the event occurs.\n */\n once<K extends keyof AriEventMap>(\n event: K,\n listener: (data: AriEventMap[K]) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n const eventListeners = this.listenersMap.get(event) ?? new Map();\n if (eventListeners.has(listener)) {\n console.warn(\n `One-time listener j\u00E1 registrado para evento ${event}, reutilizando.`\n );\n return;\n }\n\n const wrappedListener = (data: WebSocketEvent) => {\n if ('bridge' in data && data.bridge?.id === this.id) {\n listener(data as AriEventMap[K]);\n this.off(event, listener);\n }\n };\n\n this.eventEmitter.once(event, wrappedListener);\n eventListeners.set(listener, wrappedListener as (...args: any[]) => void);\n this.listenersMap.set(event, eventListeners);\n }\n\n /**\n * Removes event listener(s) from the bridge.\n *\n * @param event - The type of event to remove listeners for.\n * @param listener - Optional. The specific listener to remove. If not provided, all listeners for the event will be removed.\n */\n off<K extends keyof AriEventMap>(\n event: K,\n listener?: (data: AriEventMap[K]) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n if (listener) {\n const eventListeners = this.listenersMap.get(event);\n const wrappedListener = eventListeners?.get(listener);\n if (wrappedListener) {\n this.eventEmitter.off(event, wrappedListener);\n eventListeners!.delete(listener);\n }\n } else {\n this.eventEmitter.removeAllListeners(event);\n this.listenersMap.delete(event);\n }\n }\n\n /**\n * Cleans up the BridgeInstance, resetting its state and clearing resources.\n */\n public cleanup(): void {\n // Limpar dados do bridge\n this.bridgeData = null;\n\n // Remover todos os listeners\n this.removeAllListeners();\n\n // Limpar o map de listeners\n this.listenersMap.clear();\n\n console.log(`Bridge instance ${this.id} cleaned up`);\n }\n\n /**\n * Emits an event if it corresponds to the current bridge.\n *\n * @param event - The WebSocketEvent to emit.\n */\n emitEvent(event: WebSocketEvent): void {\n if (!event) {\n console.warn('Invalid event received');\n return;\n }\n\n if ('bridge' in event && event.bridge?.id === this.id) {\n this.eventEmitter.emit(event.type, event);\n }\n }\n\n /**\n * Removes all event listeners from this bridge instance.\n */\n removeAllListeners(): void {\n console.log(`Removing all event listeners for bridge ${this.id}`);\n this.listenersMap.forEach((listeners, event) => {\n listeners.forEach((wrappedListener) => {\n this.eventEmitter.off(event, wrappedListener);\n });\n });\n\n this.listenersMap.clear();\n this.eventEmitter.removeAllListeners();\n }\n\n /**\n * Retrieves the current details of the bridge.\n *\n * @returns A Promise that resolves to the Bridge object containing the current details.\n * @throws An error if the retrieval fails.\n */\n async get(): Promise<Bridge> {\n try {\n if (!this.id) {\n throw new Error('No bridge associated with this instance');\n }\n\n this.bridgeData = await this.baseClient.get<Bridge>(\n `/bridges/${this.id}`\n );\n return this.bridgeData;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error retrieving details for bridge ${this.id}:`, message);\n throw new Error(`Failed to get bridge details: ${message}`);\n }\n }\n\n /**\n * Adds channels to the bridge.\n *\n * @param request - The AddChannelRequest object containing the channels to add.\n * @throws An error if the operation fails.\n */\n async add(request: AddChannelRequest): Promise<void> {\n try {\n const queryParams = toQueryParams({\n channel: Array.isArray(request.channel)\n ? request.channel.join(',')\n : request.channel,\n ...(request.role && { role: request.role }),\n });\n\n await this.baseClient.post<void>(\n `/bridges/${this.id}/addChannel?${queryParams}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error adding channels to bridge ${this.id}:`, message);\n throw new Error(`Failed to add channels: ${message}`);\n }\n }\n\n /**\n * Removes channels from the bridge.\n *\n * @param request - The RemoveChannelRequest object containing the channels to remove.\n * @throws An error if the operation fails.\n */\n async remove(request: RemoveChannelRequest): Promise<void> {\n try {\n const queryParams = toQueryParams({\n channel: Array.isArray(request.channel)\n ? request.channel.join(',')\n : request.channel,\n });\n\n await this.baseClient.post<void>(\n `/bridges/${this.id}/removeChannel?${queryParams}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error removing channels from bridge ${this.id}:`, message);\n throw new Error(`Failed to remove channels: ${message}`);\n }\n }\n\n /**\n * Plays media on the bridge.\n *\n * @param request - The PlayMediaRequest object containing the media details to play.\n * @returns A Promise that resolves to a BridgePlayback object.\n * @throws An error if the operation fails.\n */\n async playMedia(request: PlayMediaRequest): Promise<BridgePlayback> {\n try {\n const queryParams = new URLSearchParams({\n ...(request.lang && { lang: request.lang }),\n ...(request.offsetms && { offsetms: request.offsetms.toString() }),\n ...(request.skipms && { skipms: request.skipms.toString() }),\n ...(request.playbackId && { playbackId: request.playbackId }),\n }).toString();\n\n const result = await this.baseClient.post<BridgePlayback>(\n `/bridges/${this.id}/play?${queryParams}`,\n { media: request.media }\n );\n\n return result;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error playing media on bridge ${this.id}:`, message);\n throw new Error(`Failed to play media: ${message}`);\n }\n }\n\n /**\n * Stops media playback on the bridge.\n *\n * @param playbackId - The ID of the playback to stop.\n * @throws An error if the operation fails.\n */\n async stopPlayback(playbackId: string): Promise<void> {\n try {\n await this.baseClient.delete<void>(\n `/bridges/${this.id}/play/${playbackId}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error stopping playback on bridge ${this.id}:`, message);\n throw new Error(`Failed to stop playback: ${message}`);\n }\n }\n\n /**\n * Sets the video source for the bridge.\n *\n * @param channelId - The ID of the channel to set as the video source.\n * @throws An error if the operation fails.\n */\n async setVideoSource(channelId: string): Promise<void> {\n try {\n await this.baseClient.post<void>(\n `/bridges/${this.id}/videoSource/${channelId}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(\n `Error setting video source for bridge ${this.id}:`,\n message\n );\n throw new Error(`Failed to set video source: ${message}`);\n }\n }\n\n /**\n * Removes the video source from the bridge.\n *\n * @throws An error if the operation fails.\n */\n async clearVideoSource(): Promise<void> {\n try {\n await this.baseClient.delete<void>(`/bridges/${this.id}/videoSource`);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(\n `Error removing video source from bridge ${this.id}:`,\n message\n );\n throw new Error(`Failed to remove video source: ${message}`);\n }\n }\n\n /**\n * Checks if the bridge has listeners for a specific event.\n *\n * @param event - The event type to check for listeners.\n * @returns A boolean indicating whether there are listeners for the event.\n */\n hasListeners(event: string): boolean {\n return this.eventEmitter.listenerCount(event) > 0;\n }\n\n /**\n * Retrieves the current bridge data without making an API call.\n *\n * @returns The current Bridge object or null if no data is available.\n */\n getCurrentData(): Bridge | null {\n return this.bridgeData;\n }\n}\nexport class Bridges {\n private readonly bridgeInstances = new Map<string, BridgeInstance>();\n private eventQueue = new Map<string, NodeJS.Timeout>();\n constructor(\n private readonly baseClient: BaseClient,\n private readonly client: AriClient\n ) {}\n /**\n * Creates or retrieves a Bridge instance.\n *\n * This method manages the creation and retrieval of BridgeInstance objects.\n * If an ID is provided and an instance with that ID already exists, it returns the existing instance.\n * If an ID is provided but no instance exists, it creates a new instance with that ID.\n * If no ID is provided, it creates a new instance with a generated ID.\n *\n * @param {Object} params - The parameters for creating or retrieving a Bridge instance.\n * @param {string} [params.id] - Optional. The ID of the Bridge instance to create or retrieve.\n *\n * @returns {BridgeInstance} A BridgeInstance object, either newly created or retrieved from existing instances.\n *\n * @throws {Error} If there's an error in creating or retrieving the Bridge instance.\n */\n Bridge({ id }: { id?: string }): BridgeInstance {\n try {\n if (!id) {\n const instance = new BridgeInstance(this.client, this.baseClient);\n this.bridgeInstances.set(instance.id, instance);\n return instance;\n }\n\n if (!this.bridgeInstances.has(id)) {\n const instance = new BridgeInstance(this.client, this.baseClient, id);\n this.bridgeInstances.set(id, instance);\n return instance;\n }\n\n return this.bridgeInstances.get(id)!;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error creating/retrieving bridge instance:`, message);\n throw new Error(`Failed to manage bridge instance: ${message}`);\n }\n }\n\n /**\n * Removes all bridge instances and cleans up their resources.\n * This method ensures proper cleanup of all bridges and their associated listeners.\n */\n public remove(): void {\n // Salvar os IDs antes de come\u00E7ar a limpeza\n const bridgeIds = Array.from(this.bridgeInstances.keys());\n\n for (const bridgeId of bridgeIds) {\n try {\n const instance = this.bridgeInstances.get(bridgeId);\n if (instance) {\n instance.cleanup(); // Usar o novo m\u00E9todo cleanup\n this.bridgeInstances.delete(bridgeId);\n console.log(`Bridge instance ${bridgeId} removed and cleaned up`);\n }\n } catch (error) {\n console.error(`Error cleaning up bridge ${bridgeId}:`, error);\n }\n }\n\n // Garantir que o map est\u00E1 vazio\n this.bridgeInstances.clear();\n console.log('All bridge instances have been removed and cleaned up');\n }\n\n /**\n * Removes a bridge instance from the collection of managed bridges.\n *\n * This function removes the specified bridge instance, cleans up its event listeners,\n * and logs the removal. If the bridge instance doesn't exist, it logs a warning.\n *\n * @param {string} bridgeId - The unique identifier of the bridge instance to be removed.\n * @throws {Error} Throws an error if the bridgeId is not provided.\n * @returns {void}\n */\n public removeBridgeInstance(bridgeId: string): void {\n if (!bridgeId) {\n throw new Error('Bridge ID is required');\n }\n\n const instance = this.bridgeInstances.get(bridgeId);\n if (instance) {\n try {\n instance.cleanup();\n this.bridgeInstances.delete(bridgeId);\n console.log(`Bridge instance ${bridgeId} removed from memory`);\n } catch (error) {\n console.error(`Error removing bridge instance ${bridgeId}:`, error);\n throw error;\n }\n } else {\n console.warn(`Attempt to remove non-existent instance: ${bridgeId}`);\n }\n }\n\n /**\n * Propagates a WebSocket event to a specific bridge instance.\n *\n * This function checks if the received event is valid and related to a bridge,\n * then emits the event to the corresponding bridge instance if it exists.\n *\n * @param {WebSocketEvent} event - The WebSocket event to be propagated.\n * This should be an object containing information about the event,\n * including the bridge ID and event type.\n *\n * @returns {void}\n *\n * @remarks\n * - If the event is invalid (null or undefined), a warning is logged and the function returns early.\n * - The function checks if the event is bridge-related and if the event contains a valid bridge ID.\n * - If a matching bridge instance is found, the event is emitted to that instance.\n * - If no matching bridge instance is found, a warning is logged.\n */\n public propagateEventToBridge(event: WebSocketEvent): void {\n if (!event || !('bridge' in event) || !event.bridge?.id) {\n console.warn('Invalid WebSocket event received');\n return;\n }\n\n const key = `${event.type}-${event.bridge.id}`;\n const existing = this.eventQueue.get(key);\n if (existing) {\n clearTimeout(existing);\n }\n\n this.eventQueue.set(\n key,\n setTimeout(() => {\n const instance = this.bridgeInstances.get(event.bridge!.id!);\n if (instance) {\n instance.emitEvent(event);\n } else {\n console.warn(\n `No instance found for bridge ${event.bridge!.id}. Event ignored.`\n );\n }\n this.eventQueue.delete(key);\n }, 100)\n );\n }\n /**\n * Performs a cleanup of the Bridges instance, clearing all event queues and removing all bridge instances.\n *\n * This method is responsible for:\n * 1. Clearing all pending timeouts in the event queue.\n * 2. Removing all bridge instances managed by this Bridges object.\n *\n * It should be called when the Bridges instance is no longer needed or before reinitializing\n * to ensure all resources are properly released.\n *\n * @returns {void}\n */\n public cleanup(): void {\n // Limpar event queue\n this.eventQueue.forEach((timeout) => clearTimeout(timeout));\n this.eventQueue.clear();\n\n // Limpar todas as inst\u00E2ncias\n this.remove();\n }\n\n /**\n * Lists all active bridges in the system.\n *\n * This asynchronous function retrieves a list of all currently active bridges\n * by making a GET request to the \"/bridges\" endpoint using the base client.\n *\n * @returns {Promise<Bridge[]>} A promise that resolves to an array of Bridge objects.\n * Each Bridge object represents an active bridge in the system.\n *\n * @throws {Error} If there's an error in fetching the bridges or if the request fails.\n *\n * @example\n * try {\n * const bridges = await bridgesInstance.list();\n *\n * } catch (error) {\n * console.error('Failed to fetch bridges:', error);\n * }\n */\n async list(): Promise<Bridge[]> {\n return this.baseClient.get<Bridge[]>('/bridges');\n }\n\n /**\n * Creates a new bridge in the system.\n *\n * This asynchronous function sends a POST request to create a new bridge\n * using the provided configuration details.\n *\n * @param request - The configuration details for creating the new bridge.\n * @param request.type - The type of bridge to create (e.g., 'mixing', 'holding').\n * @param request.name - Optional. A custom name for the bridge.\n * @param request.bridgeId - Optional. A specific ID for the bridge. If not provided, one will be generated.\n *\n * @returns A Promise that resolves to a Bridge object representing the newly created bridge.\n * The Bridge object contains details such as id, technology, bridge_type, bridge_class, channels, etc.\n *\n * @throws Will throw an error if the bridge creation fails or if there's a network issue.\n */\n async createBridge(request: CreateBridgeRequest): Promise<Bridge> {\n return this.baseClient.post<Bridge>('/bridges', request);\n }\n\n /**\n * Retrieves detailed information about a specific bridge.\n *\n * This asynchronous function fetches the complete details of a bridge\n * identified by its unique ID. It makes a GET request to the ARI endpoint\n * for the specified bridge.\n *\n * @param bridgeId - The unique identifier of the bridge to retrieve details for.\n * This should be a string that uniquely identifies the bridge in the system.\n *\n * @returns A Promise that resolves to a Bridge object containing all the details\n * of the specified bridge. This includes information such as the bridge's\n * ID, type, channels, and other relevant properties.\n *\n * @throws Will throw an error if the bridge cannot be found, if there's a network issue,\n * or if the server responds with an error.\n */\n async get(bridgeId: string): Promise<Bridge> {\n return this.baseClient.get<Bridge>(`/bridges/${bridgeId}`);\n }\n\n /**\n * Destroys (deletes) a specific bridge in the system.\n *\n * This asynchronous function sends a DELETE request to remove a bridge\n * identified by its unique ID. Once destroyed, the bridge and all its\n * associated resources are permanently removed from the system.\n *\n * @param bridgeId - The unique identifier of the bridge to be destroyed.\n * This should be a string that uniquely identifies the bridge in the system.\n *\n * @returns A Promise that resolves to void when the bridge is successfully destroyed.\n * If the operation is successful, the bridge no longer exists in the system.\n *\n * @throws Will throw an error if the bridge cannot be found, if there's a network issue,\n * or if the server responds with an error during the deletion process.\n */\n async destroy(bridgeId: string): Promise<void> {\n return this.baseClient.delete<void>(`/bridges/${bridgeId}`);\n }\n\n /**\n * Adds one or more channels to a specified bridge.\n *\n * This asynchronous function sends a POST request to add channels to an existing bridge.\n * It can handle adding a single channel or multiple channels in one operation.\n *\n * @param bridgeId - The unique identifier of the bridge to which channels will be added.\n * @param request - An object containing the details of the channel(s) to be added.\n * @param request.channel - A single channel ID or an array of channel IDs to add to the bridge.\n * @param request.role - Optional. Specifies the role of the channel(s) in the bridge.\n *\n * @returns A Promise that resolves to void when the operation is successful.\n *\n * @throws Will throw an error if the request fails, such as if the bridge doesn't exist\n * or if there's a network issue.\n */\n async addChannels(\n bridgeId: string,\n request: AddChannelRequest\n ): Promise<void> {\n const queryParams = toQueryParams({\n channel: Array.isArray(request.channel)\n ? request.channel.join(',')\n : request.channel,\n ...(request.role && { role: request.role }),\n });\n\n await this.baseClient.post<void>(\n `/bridges/${bridgeId}/addChannel?${queryParams}`\n );\n }\n\n /**\n * Removes one or more channels from a specified bridge.\n *\n * This asynchronous function sends a POST request to remove channels from an existing bridge.\n * It can handle removing a single channel or multiple channels in one operation.\n *\n * @param bridgeId - The unique identifier of the bridge from which channels will be removed.\n * @param request - An object containing the details of the channel(s) to be removed.\n * @param request.channel - A single channel ID or an array of channel IDs to remove from the bridge.\n *\n * @returns A Promise that resolves to void when the operation is successful.\n *\n * @throws Will throw an error if the request fails, such as if the bridge doesn't exist,\n * if the channels are not in the bridge, or if there's a network issue.\n */\n async removeChannels(\n bridgeId: string,\n request: RemoveChannelRequest\n ): Promise<void> {\n const queryParams = toQueryParams({\n channel: Array.isArray(request.channel)\n ? request.channel.join(',')\n : request.channel,\n });\n\n await this.baseClient.post<void>(\n `/bridges/${bridgeId}/removeChannel?${queryParams}`\n );\n }\n\n /**\n * Plays media on a specified bridge.\n *\n * This asynchronous function initiates media playback on a bridge identified by its ID.\n * It allows for customization of the playback through various options in the request.\n *\n * @param bridgeId - The unique identifier of the bridge on which to play the media.\n * @param request - An object containing the media playback request details.\n * @param request.media - The media to be played (e.g., sound file, URL).\n * @param request.lang - Optional. The language of the media content.\n * @param request.offsetms - Optional. The offset in milliseconds to start playing from.\n * @param request.skipms - Optional. The number of milliseconds to skip before playing.\n * @param request.playbackId - Optional. A custom ID for the playback session.\n *\n * @returns A Promise that resolves to a BridgePlayback object, containing details about the initiated playback.\n *\n * @throws Will throw an error if the playback request fails or if there's a network issue.\n */\n async playMedia(\n bridgeId: string,\n request: PlayMediaRequest\n ): Promise<BridgePlayback> {\n const queryParams = toQueryParams({\n ...(request.lang && { lang: request.lang }),\n ...(request.offsetms && { offsetms: request.offsetms.toString() }),\n ...(request.skipms && { skipms: request.skipms.toString() }),\n ...(request.playbackId && { playbackId: request.playbackId }),\n });\n\n return this.baseClient.post<BridgePlayback>(\n `/bridges/${bridgeId}/play?${queryParams}`,\n { media: request.media }\n );\n }\n\n /**\n * Stops media playback on a specified bridge.\n *\n * This asynchronous function sends a DELETE request to stop the playback of media\n * on a bridge identified by its ID and a specific playback session.\n *\n * @param bridgeId - The unique identifier of the bridge where the playback is to be stopped.\n * @param playbackId - The unique identifier of the playback session to be stopped.\n *\n * @returns A Promise that resolves to void when the playback is successfully stopped.\n *\n * @throws Will throw an error if the request fails, such as if the bridge or playback session\n * doesn't exist, or if there's a network issue.\n */\n async stopPlayback(bridgeId: string, playbackId: string): Promise<void> {\n await this.baseClient.delete<void>(\n `/bridges/${bridgeId}/play/${playbackId}`\n );\n }\n\n /**\n * Sets the video source for a specified bridge.\n *\n * This asynchronous function configures a channel as the video source for a given bridge.\n * It sends a POST request to the ARI endpoint to update the bridge's video source.\n *\n * @param bridgeId - The unique identifier of the bridge for which to set the video source.\n * @param channelId - The unique identifier of the channel to be set as the video source.\n *\n * @returns A Promise that resolves to void when the video source is successfully set.\n *\n * @throws Will throw an error if the request fails, such as if the bridge or channel\n * doesn't exist, or if there's a network issue.\n */\n async setVideoSource(bridgeId: string, channelId: string): Promise<void> {\n const queryParams = toQueryParams({ channelId });\n await this.baseClient.post<void>(\n `/bridges/${bridgeId}/videoSource?${queryParams}`\n );\n }\n\n /**\n * Clears the video source for a specified bridge.\n *\n * This asynchronous function removes the currently set video source from a bridge.\n * It sends a DELETE request to the ARI endpoint to clear the video source configuration.\n *\n * @param bridgeId - The unique identifier of the bridge from which to clear the video source.\n * This should be a string that uniquely identifies the bridge in the system.\n *\n * @returns A Promise that resolves to void when the video source is successfully cleared.\n * If the operation is successful, the bridge will no longer have a designated video source.\n *\n * @throws Will throw an error if the request fails, such as if the bridge doesn't exist,\n * if there's no video source set, or if there's a network issue.\n */\n async clearVideoSource(bridgeId: string): Promise<void> {\n await this.baseClient.delete<void>(`/bridges/${bridgeId}/videoSource`);\n }\n\n /**\n * Retrieves the count of active bridge instances.\n *\n * This function returns the total number of bridge instances currently\n * managed by the Bridges class. It provides a quick way to check how many\n * active bridges are present in the system.\n *\n * @returns {number} The count of active bridge instances.\n */\n getInstanceCount(): number {\n return this.bridgeInstances.size;\n }\n\n /**\n * Checks if a bridge instance exists in the collection of managed bridges.\n *\n * This function verifies whether a bridge instance with the specified ID\n * is currently being managed by the Bridges class.\n *\n * @param bridgeId - The unique identifier of the bridge instance to check.\n * This should be a string that uniquely identifies the bridge in the system.\n *\n * @returns A boolean value indicating whether the bridge instance exists.\n * Returns true if the bridge instance is found, false otherwise.\n */\n hasInstance(bridgeId: string): boolean {\n return this.bridgeInstances.has(bridgeId);\n }\n\n /**\n * Retrieves all active bridge instances currently managed by the Bridges class.\n *\n * This method provides a way to access all the BridgeInstance objects that are\n * currently active and being managed. It returns a new Map to prevent direct\n * modification of the internal bridgeInstances collection.\n *\n * @returns A new Map object containing all active bridge instances, where the keys\n * are the bridge IDs (strings) and the values are the corresponding\n * BridgeInstance objects. If no bridges are active, an empty Map is returned.\n */\n getAllInstances(): Map<string, BridgeInstance> {\n return new Map(this.bridgeInstances);\n }\n}\n", "import type { Channel, Playback, WebSocketEvent } from './interfaces';\n\nexport function toQueryParams<T>(options: T): string {\n return new URLSearchParams(\n Object.entries(options as Record<string, string>)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => [key, value as string])\n ).toString();\n}\n\nexport function isPlaybackEvent(\n event: WebSocketEvent,\n playbackId?: string\n): event is Extract<WebSocketEvent, { playback: Playback }> {\n if (!('playback' in event) || typeof event.playback?.id !== 'string') {\n return false;\n }\n return !playbackId || event.playback.id === playbackId;\n}\n\n/**\n * Verifica se um evento pertence a um canal e opcionalmente valida o ID do canal.\n * @param event O evento WebSocket a ser validado.\n * @param channelId Opcional. O ID do canal a ser validado.\n * @returns Verdadeiro se o evento \u00E9 relacionado a um canal (e ao ID, se fornecido).\n */\nexport function isChannelEvent(\n event: WebSocketEvent,\n channelId?: string\n): event is Extract<WebSocketEvent, { channel: Channel }> {\n // Verifica se o evento tem a propriedade `channel`\n const hasChannel = 'channel' in event && event.channel?.id !== undefined;\n\n return hasChannel && (!channelId || event.channel?.id === channelId);\n}\n\nexport const channelEvents = [\n 'ChannelCreated',\n 'ChannelDestroyed',\n 'ChannelEnteredBridge',\n 'ChannelLeftBridge',\n 'ChannelStateChange',\n 'ChannelDtmfReceived',\n 'ChannelDialplan',\n 'ChannelCallerId',\n 'ChannelUserevent',\n 'ChannelHangupRequest',\n 'ChannelVarset',\n 'ChannelTalkingStarted',\n 'ChannelTalkingFinished',\n 'ChannelHold',\n 'ChannelUnhold',\n];\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { EventEmitter } from 'events';\nimport { isAxiosError } from 'axios';\nimport { v4 as uuidv4 } from 'uuid';\nimport type { AriClient } from '../ariClient';\nimport type { BaseClient } from '../baseClient.js';\nimport type {\n AriEventMap,\n Channel,\n ChannelPlayback,\n ChannelVar,\n ExternalMediaOptions,\n OriginateRequest,\n PlaybackOptions,\n RTPStats,\n RecordingOptions,\n SnoopOptions,\n WebSocketEvent,\n} from '../interfaces';\nimport { toQueryParams } from '../utils';\nimport type { PlaybackInstance } from './playbacks';\n\n/**\n * Utility function to extract error message\n */\nconst getErrorMessage = (error: unknown): string => {\n if (isAxiosError(error)) {\n return (\n error.response?.data?.message ||\n error.message ||\n 'An axios error occurred'\n );\n }\n if (error instanceof Error) {\n return error.message;\n }\n return 'An unknown error occurred';\n};\n\n/**\n * Represents an instance of a communication channel managed by the AriClient.\n */\nexport class ChannelInstance {\n private readonly eventEmitter = new EventEmitter();\n private channelData: Channel | null = null;\n // biome-ignore lint/suspicious/noExplicitAny: Maps original listener \u2192 wrapped listener per event\n private readonly listenersMap = new Map<string, Map<(...args: any[]) => void, (...args: any[]) => void>>();\n public readonly id: string;\n\n constructor(\n private readonly client: AriClient,\n private readonly baseClient: BaseClient,\n channelId?: string\n ) {\n this.id = channelId || `channel-${Date.now()}`;\n }\n\n /**\n * Registers an event listener for specific channel events\n */\n on<K extends keyof AriEventMap>(\n event: K,\n listener: (data: AriEventMap[K]) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n const eventListeners = this.listenersMap.get(event) ?? new Map();\n if (eventListeners.has(listener)) {\n console.warn(\n `Listener j\u00E1 registrado para evento ${event}, reutilizando.`\n );\n return;\n }\n\n const wrappedListener = (data: WebSocketEvent) => {\n if ('channel' in data && data.channel?.id === this.id) {\n listener(data as AriEventMap[K]);\n }\n };\n\n this.eventEmitter.on(event, wrappedListener);\n eventListeners.set(listener, wrappedListener as (...args: any[]) => void);\n this.listenersMap.set(event, eventListeners);\n }\n\n /**\n * Registers a one-time event listener\n */\n once<K extends keyof AriEventMap>(\n event: K,\n listener: (data: AriEventMap[K]) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n const eventListeners = this.listenersMap.get(event) ?? new Map();\n if (eventListeners.has(listener)) {\n console.warn(\n `One-time listener j\u00E1 registrado para evento ${event}, reutilizando.`\n );\n return;\n }\n\n const wrappedListener = (data: WebSocketEvent) => {\n if ('channel' in data && data.channel?.id === this.id) {\n listener(data as AriEventMap[K]);\n this.off(event, listener);\n }\n };\n\n this.eventEmitter.once(event, wrappedListener);\n eventListeners.set(listener, wrappedListener as (...args: any[]) => void);\n this.listenersMap.set(event, eventListeners);\n }\n\n /**\n * Removes event listener(s) for a specific WebSocket event type.\n * If a specific listener is provided, only that listener is removed.\n * Otherwise, all listeners for the given event type are removed.\n *\n * @param {T} event - The type of WebSocket event to remove listener(s) for\n * @param {(data: WebSocketEvent) => void} [listener] - Optional specific listener to remove\n * @throws {Error} If no event type is provided\n */\n off<K extends keyof AriEventMap>(\n event: K,\n listener?: (data: AriEventMap[K]) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n if (listener) {\n const eventListeners = this.listenersMap.get(event);\n const wrappedListener = eventListeners?.get(listener);\n if (wrappedListener) {\n this.eventEmitter.off(event, wrappedListener);\n eventListeners!.delete(listener);\n }\n } else {\n this.eventEmitter.removeAllListeners(event);\n this.listenersMap.delete(event);\n }\n }\n\n /**\n * Cleans up the ChannelInstance, resetting its state and clearing resources.\n */\n public cleanup(): void {\n // Limpar dados do canal\n this.channelData = null;\n\n // Remover todos os listeners\n this.removeAllListeners();\n\n // Limpar o map de listeners\n this.listenersMap.clear();\n\n console.log(`Channel instance ${this.id} cleaned up`);\n }\n\n /**\n * Emits an event if it matches the current channel\n */\n emitEvent(event: WebSocketEvent): void {\n if (!event) {\n console.warn('Received invalid event');\n return;\n }\n\n if ('channel' in event && event.channel?.id === this.id) {\n this.eventEmitter.emit(event.type, event);\n }\n }\n\n /**\n * Removes all event listeners associated with the current instance.\n * This ensures that there are no lingering event handlers for the channel.\n *\n * @return {void} This method does not return a value.\n */\n removeAllListeners(): void {\n console.log(`Removing all event listeners for channel ${this.id}`);\n\n this.listenersMap.forEach((listeners, event) => {\n listeners.forEach((wrappedListener) => {\n this.eventEmitter.off(event, wrappedListener);\n });\n });\n\n this.listenersMap.clear();\n this.eventEmitter.removeAllListeners();\n }\n\n /**\n * Answers the channel\n */\n async answer(): Promise<void> {\n try {\n await this.baseClient.post<void>(`/channels/${this.id}/answer`);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error answering channel ${this.id}:`, message);\n throw new Error(`Failed to answer channel: ${message}`);\n }\n }\n\n /**\n * Originates a new channel\n *\n * @param data - Channel origination configuration\n * @returns Promise resolving to the created channel\n * @throws Error if channel already exists or origination fails\n */\n async originate(data: OriginateRequest): Promise<Channel> {\n if (this.channelData) {\n throw new Error('Channel has already been created');\n }\n\n try {\n this.channelData = await this.baseClient.post<Channel, OriginateRequest>(\n '/channels',\n data\n );\n return this.channelData;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error originating channel:`, message);\n throw new Error(`Failed to originate channel: ${message}`);\n }\n }\n\n /**\n * Continues the execution of a dialplan for the current channel.\n *\n * @param {string} [context] - The dialplan context to continue execution in, if specified.\n * @param {string} [extension] - The dialplan extension to proceed with, if provided.\n * @param {number} [priority] - The priority within the dialplan extension to resume at, if specified.\n * @param {string} [label] - The label to start from within the dialplan, if given.\n * @return {Promise<void>} Resolves when the dialplan is successfully continued.\n */\n async continueDialplan(\n context?: string,\n extension?: string,\n priority?: number,\n label?: string\n ): Promise<void> {\n try {\n if (!this.channelData) {\n this.channelData = await this.getDetails();\n }\n\n await this.baseClient.post<void>(`/channels/${this.id}/continue`, {\n context,\n extension,\n priority,\n label,\n });\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(\n `Error continuing dialplan for channel ${this.id}:`,\n message\n );\n throw new Error(`Failed to continue dialplan: ${message}`);\n }\n }\n\n /**\n * Initiates a snoop operation on this channel with the provided options.\n * Snooping allows you to listen in or interact with an existing call.\n *\n * @param {SnoopOptions} options - Configuration options for the snooping operation.\n * @return {Promise<Channel>} A promise that resolves to the snooped channel data.\n * @throws {Error} If the channel is not initialized or if snooping fails.\n */\n async snoop(options: SnoopOptions): Promise<Channel> {\n try {\n if (!this.channelData) {\n this.channelData = await this.getDetails();\n }\n\n const queryParams = toQueryParams(options);\n return await this.baseClient.post<Channel>(\n `/channels/${this.id}/snoop?${queryParams}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error snooping on channel ${this.id}:`, message);\n throw new Error(`Failed to snoop channel: ${message}`);\n }\n }\n\n /**\n * Initiates a snoop operation on this channel with a specific snoop ID.\n *\n * @param {string} snoopId - The unique identifier for the snoop operation.\n * @param {SnoopOptions} options - Configuration options for the snooping operation.\n * @return {Promise<Channel>} A promise that resolves to the snooped channel data.\n * @throws {Error} If the channel is not initialized or if snooping fails.\n */\n async snoopWithId(snoopId: string, options: SnoopOptions): Promise<Channel> {\n try {\n if (!this.channelData) {\n this.channelData = await this.getDetails();\n }\n\n const queryParams = toQueryParams(options);\n return await this.baseClient.post<Channel>(\n `/channels/${this.id}/snoop/${snoopId}?${queryParams}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error snooping with ID on channel ${this.id}:`, message);\n throw new Error(`Failed to snoop channel with ID: ${message}`);\n }\n }\n\n /**\n * Plays media on the channel\n */\n async play(\n options: { media: string; lang?: string },\n playbackId?: string\n ): Promise<PlaybackInstance> {\n if (!options.media) {\n throw new Error('Media URL is required');\n }\n\n try {\n if (!this.channelData) {\n this.channelData = await this.getDetails();\n }\n\n const playback = this.client.Playback(playbackId || uuidv4());\n await this.baseClient.post<void>(\n `/channels/${this.id}/play/${playback.id}`,\n options\n );\n\n return playback;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error playing media on channel ${this.id}:`, message);\n throw new Error(`Failed to play media: ${message}`);\n }\n }\n\n /**\n * Gets the current channel details\n */\n async getDetails(): Promise<Channel> {\n try {\n if (this.channelData) {\n return this.channelData;\n }\n\n if (!this.id) {\n throw new Error('No channel ID associated with this instance');\n }\n\n const details = await this.baseClient.get<Channel>(\n `/channels/${this.id}`\n );\n this.channelData = details;\n return details;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(\n `Error retrieving channel details for ${this.id}:`,\n message\n );\n throw new Error(`Failed to get channel details: ${message}`);\n }\n }\n\n /**\n * Checks if the channel has any listeners for a specific event\n */\n hasListeners(event: string): boolean {\n return this.eventEmitter.listenerCount(event) > 0;\n }\n\n /**\n * Gets the count of listeners for a specific event\n */\n getListenerCount(event: string): number {\n return this.eventEmitter.listenerCount(event);\n }\n\n /**\n * Fetches a specific channel variable.\n *\n * @param {string} variable - The name of the variable to retrieve. This parameter is required.\n * @return {Promise<ChannelVar>} A promise that resolves with the value of the requested channel variable.\n * @throws {Error} If the 'variable' parameter is not provided.\n */\n async getVariable(variable: string): Promise<ChannelVar> {\n if (!variable) {\n throw new Error(\"The 'variable' parameter is required.\");\n }\n return this.baseClient.get<ChannelVar>(\n `/channels/${this.id}/variable?variable=${encodeURIComponent(variable)}`\n );\n }\n\n /**\n * Terminates the active call associated with the current channel.\n * This method ensures that channel details are initialized before attempting to hang up.\n * If the channel ID is invalid or cannot be determined, an error is thrown.\n *\n * @return {Promise<void>} A promise that resolves when the call is successfully terminated.\n */\n async hangup(): Promise<void> {\n if (!this.channelData) {\n this.channelData = await this.getDetails();\n }\n\n if (!this.channelData?.id) {\n throw new Error('N\u00E3o foi poss\u00EDvel inicializar o canal. ID inv\u00E1lido.');\n }\n\n await this.baseClient.delete(`/channels/${this.channelData.id}`);\n }\n\n /**\n * Plays media on the specified channel using the provided media URL and optional playback options.\n *\n * @param {string} media - The URL or identifier of the media to be played.\n * @param {PlaybackOptions} [options] - Optional playback settings such as volume, playback speed, etc.\n * @return {Promise<ChannelPlayback>} A promise that resolves with the playback details for the channel.\n * @throws {Error} Throws an error if the channel has not been created.\n */\n async playMedia(\n media: string,\n options?: PlaybackOptions\n ): Promise<ChannelPlayback> {\n if (!this.channelData) {\n throw new Error('O canal ainda n\u00E3o foi criado.');\n }\n\n const queryParams = options\n ? `?${new URLSearchParams(options as Record<string, string>).toString()}`\n : '';\n\n return this.baseClient.post<ChannelPlayback>(\n `/channels/${this.channelData.id}/play${queryParams}`,\n { media }\n );\n }\n\n /**\n * Stops the playback for the given playback ID.\n *\n * @param {string} playbackId - The unique identifier for the playback to be stopped.\n * @return {Promise<void>} A promise that resolves when the playback is successfully stopped.\n * @throws {Error} Throws an error if the instance is not associated with a channel.\n */\n async stopPlayback(playbackId: string): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.delete<void>(\n `/channels/${this.channelData.id}/play/${playbackId}`\n );\n }\n\n /**\n * Pauses the playback of the specified media on a channel.\n *\n * @param {string} playbackId - The unique identifier of the playback to be paused.\n * @return {Promise<void>} A promise that resolves when the playback has been successfully paused.\n * @throws {Error} Throws an error if the channel is not associated with the current instance.\n */\n async pausePlayback(playbackId: string): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.post<void>(\n `/channels/${this.channelData.id}/play/${playbackId}/pause`\n );\n }\n\n /**\n * Resumes playback of the specified playback session on the associated channel.\n *\n * @param {string} playbackId - The unique identifier of the playback session to be resumed.\n * @return {Promise<void>} A promise that resolves when the playback has been successfully resumed.\n * @throws {Error} Throws an error if the channel is not associated with this instance.\n */\n async resumePlayback(playbackId: string): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.delete<void>(\n `/channels/${this.channelData.id}/play/${playbackId}/pause`\n );\n }\n\n /**\n * Rewinds the playback of a media by a specified amount of milliseconds.\n *\n * @param {string} playbackId - The unique identifier for the playback session to be rewound.\n * @param {number} skipMs - The number of milliseconds to rewind the playback.\n * @return {Promise<void>} A promise that resolves when the rewind operation is complete.\n */\n async rewindPlayback(playbackId: string, skipMs: number): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.post<void>(\n `/channels/${this.channelData.id}/play/${playbackId}/rewind`,\n { skipMs }\n );\n }\n\n /**\n * Fast forwards the playback by a specific duration in milliseconds.\n *\n * @param {string} playbackId - The unique identifier of the playback to be fast-forwarded.\n * @param {number} skipMs - The number of milliseconds to fast forward the playback.\n * @return {Promise<void>} A Promise that resolves when the fast-forward operation is complete.\n * @throws {Error} If no channel is associated with this instance.\n */\n async fastForwardPlayback(playbackId: string, skipMs: number): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.post<void>(\n `/channels/${this.channelData.id}/play/${playbackId}/forward`,\n { skipMs }\n );\n }\n\n /**\n * Mutes the specified channel for the given direction.\n *\n * @param {(\"both\" | \"in\" | \"out\")} [direction=\"both\"] - The direction to mute the channel. It can be \"both\" to mute incoming and outgoing, \"in\" to mute incoming, or \"out\" to mute outgoing.\n * @return {Promise<void>} A promise that resolves when the channel is successfully muted.\n * @throws {Error} If the channel is not associated with this instance.\n */\n async muteChannel(direction: 'both' | 'in' | 'out' = 'both'): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.post<void>(\n `/channels/${this.channelData.id}/mute?direction=${direction}`\n );\n }\n\n /**\n * Unmutes a previously muted channel in the specified direction.\n *\n * @param {\"both\" | \"in\" | \"out\"} direction - The direction in which to unmute the channel.\n * Defaults to \"both\", which unmutes both incoming and outgoing communication.\n * @return {Promise<void>} A promise that resolves once the channel has been successfully unmuted.\n * @throws {Error} If the channel is not associated with the current instance.\n */\n async unmuteChannel(\n direction: 'both' | 'in' | 'out' = 'both'\n ): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.delete<void>(\n `/channels/${this.channelData.id}/mute?direction=${direction}`\n );\n }\n\n /**\n * Places the associated channel on hold if the channel is valid and linked to this instance.\n *\n * @return {Promise<void>} A promise that resolves when the hold action is successfully executed.\n * @throws {Error} Throws an error if the channel is not associated with this instance.\n */\n async holdChannel(): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.post<void>(`/channels/${this.channelData.id}/hold`);\n }\n\n /**\n * Removes the hold status from a specific channel associated with this instance.\n * The method sends a delete request to the server to release the hold on the channel.\n * If no channel is associated with this instance, an error will be thrown.\n *\n * @return {Promise<void>} A promise that resolves when the channel hold has been successfully removed.\n * @throws {Error} If no channel is associated with this instance.\n */\n async unholdChannel(): Promise<void> {\n if (!this.channelData?.id) {\n throw new Error('Canal n\u00E3o associado a esta inst\u00E2ncia.');\n }\n\n await this.baseClient.delete<void>(`/channels/${this.channelData.id}/hold`);\n }\n}\n\n/**\n * The `Channels` class provides a comprehensive interface for managing\n * and interacting with communication channels.\n */\nexport class Channels {\n private readonly channelInstances = new Map<string, ChannelInstance>();\n private eventQueue = new Map<string, NodeJS.Timeout>();\n\n constructor(\n private readonly baseClient: BaseClient,\n private readonly client: AriClient\n ) {}\n\n /**\n * Creates or retrieves a ChannelInstance.\n *\n * @param {Object} [params] - Optional parameters for getting/creating a channel instance\n * @param {string} [params.id] - Optional ID of an existing channel\n * @returns {ChannelInstance} The requested or new channel instance\n * @throws {Error} If channel creation/retrieval fails\n *\n * @example\n * // Create new channel without ID\n * const channel1 = client.channels.Channel();\n *\n * // Create/retrieve channel with specific ID\n * const channel2 = client.channels.Channel({ id: 'some-id' });\n */\n Channel(params?: { id?: string }): ChannelInstance {\n try {\n const id = params?.id;\n\n if (!id) {\n const instance = new ChannelInstance(this.client, this.baseClient);\n this.channelInstances.set(instance.id, instance);\n return instance;\n }\n\n if (!this.channelInstances.has(id)) {\n const instance = new ChannelInstance(this.client, this.baseClient, id);\n this.channelInstances.set(id, instance);\n return instance;\n }\n\n return this.channelInstances.get(id)!;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error creating/retrieving channel instance:`, message);\n throw new Error(`Failed to manage channel instance: ${message}`);\n }\n }\n\n public cleanup(): void {\n // Limpar event queue\n this.eventQueue.forEach((timeout) => clearTimeout(timeout));\n this.eventQueue.clear();\n\n // Limpar todas as inst\u00E2ncias\n this.remove();\n }\n\n /**\n * Removes all channel instances and cleans up their resources.\n * This method ensures proper cleanup of all channels and their associated listeners.\n */\n public remove(): void {\n // Salvar os IDs antes de come\u00E7ar a limpeza\n const channelIds = Array.from(this.channelInstances.keys());\n\n for (const channelId of channelIds) {\n try {\n const instance = this.channelInstances.get(channelId);\n if (instance) {\n instance.cleanup(); // Usar o novo m\u00E9todo cleanup\n this.channelInstances.delete(channelId);\n console.log(`Channel instance ${channelId} removed and cleaned up`);\n }\n } catch (error) {\n console.error(`Error cleaning up channel ${channelId}:`, error);\n }\n }\n\n // Garantir que o map est\u00E1 vazio\n this.channelInstances.clear();\n console.log('All channel instances have been removed and cleaned up');\n }\n\n /**\n * Retrieves the details of a specific channel.\n *\n * @param {string} id - The unique identifier of the channel to retrieve.\n * @returns {Promise<Channel>} A promise that resolves to the Channel object containing the channel details.\n * @throws {Error} If no channel ID is associated with this instance or if there's an error retrieving the channel details.\n */\n async get(id: string): Promise<Channel> {\n try {\n if (!id) {\n throw new Error('No channel ID associated with this instance');\n }\n\n return await this.baseClient.get<Channel>(`/channels/${id}`);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error retrieving channel details for ${id}:`, message);\n throw new Error(`Failed to get channel details: ${message}`);\n }\n }\n\n /**\n * Removes a channel instance from the collection.\n */\n public removeChannelInstance(channelId: string): void {\n if (!channelId) {\n throw new Error('Channel ID is required');\n }\n\n const instance = this.channelInstances.get(channelId);\n if (instance) {\n try {\n instance.cleanup();\n this.channelInstances.delete(channelId);\n console.log(`Channel instance ${channelId} removed from memory`);\n } catch (error) {\n console.error(`Error removing channel instance ${channelId}:`, error);\n throw error;\n }\n } else {\n console.warn(`Attempt to remove non-existent instance: ${channelId}`);\n }\n }\n\n /**\n * Propagates a WebSocket event to a specific channel.\n */\n public propagateEventToChannel(event: WebSocketEvent): void {\n if (!event || !('channel' in event) || !event.channel?.id) {\n console.warn('Invalid WebSocket event received');\n return;\n }\n\n const key = `${event.type}-${event.channel.id}`;\n const existing = this.eventQueue.get(key);\n if (existing) {\n clearTimeout(existing);\n }\n\n this.eventQueue.set(\n key,\n setTimeout(() => {\n const instance = this.channelInstances.get(event.channel!.id!);\n if (instance) {\n instance.emitEvent(event);\n } else {\n console.warn(\n `No instance found for channel ${event.channel!.id}. Event ignored.`\n );\n }\n this.eventQueue.delete(key);\n }, 100)\n );\n }\n\n /**\n * Initiates a new channel.\n */\n async originate(data: OriginateRequest): Promise<Channel> {\n if (!data.endpoint) {\n throw new Error('Endpoint is required for channel origination');\n }\n\n try {\n return await this.baseClient.post<Channel>('/channels', data);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error originating channel:`, message);\n throw new Error(`Failed to originate channel: ${message}`);\n }\n }\n\n /**\n * Lists all active channels.\n */\n async list(): Promise<Channel[]> {\n try {\n const channels = await this.baseClient.get<unknown>('/channels');\n if (!Array.isArray(channels)) {\n throw new Error('API response for /channels is not an array');\n }\n return channels as Channel[];\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.error(`Error listing channels:`, message);\n throw new Error(`Failed to list channels: ${message}`);\n }\n }\n\n /**\n * Gets the count of active channel instances.\n */\n getInstanceCount(): number {\n return this.channelInstances.size;\n }\n\n /**\n * Checks if a channel instance exists.\n */\n hasInstance(channelId: string): boolean {\n return this.channelInstances.has(channelId);\n }\n\n /**\n * Gets all active channel instances.\n */\n getAllInstances(): Map<string, ChannelInstance> {\n return new Map(this.channelInstances);\n }\n\n /**\n * Terminates an active call on the specified channel.\n *\n * @param {string} channelId - The unique identifier of the channel to hang up.\n * @param {Object} [options] - Optional parameters for the hangup request.\n * @param {string} [options.reason_code] - A code indicating the reason for the hangup.\n * @param {string} [options.reason] - A descriptive reason for the hangup.\n * @return {Promise<void>} A promise that resolves when the call has been successfully terminated.\n */\n async hangup(\n channelId: string,\n options?: { reason_code?: string; reason?: string }\n ): Promise<void> {\n const queryParams = new URLSearchParams({\n ...(options?.reason_code && { reason_code: options.reason_code }),\n ...(options?.reason && { reason: options.reason }),\n });\n\n return this.baseClient.delete<void>(\n `/channels/${channelId}?${queryParams.toString()}`\n );\n }\n\n /**\n * Initiates snooping on a specified channel with the provided options.\n *\n * @param {string} channelId - The unique identifier of the channel to snoop on.\n * @param {SnoopOptions} options - Configuration options for the snooping operation.\n * @return {Promise<Channel>} A promise that resolves to the snooped channel data.\n */\n async snoopChannel(\n channelId: string,\n options: SnoopOptions\n ): Promise<Channel> {\n const queryParams = toQueryParams(options);\n return this.baseClient.post<Channel>(\n `/channels/${channelId}/snoop?${queryParams}`\n );\n }\n\n /**\n * Starts a silence mode for the specified channel.\n *\n * @param {string} channelId - The unique identifier of the channel where silence mode should be started.\n * @return {Promise<void>} A promise that resolves when the silence mode is successfully started.\n */\n async startSilence(channelId: string): Promise<void> {\n return this.baseClient.post<void>(`/channels/${channelId}/silence`);\n }\n\n /**\n * Stops the silence mode for a specific channel.\n *\n * @param {string} channelId - The unique identifier of the channel for which silence mode should be stopped.\n * @return {Promise<void>} A promise that resolves when the operation is complete.\n */\n async stopSilence(channelId: string): Promise<void> {\n return this.baseClient.delete<void>(`/channels/${channelId}/silence`);\n }\n\n /**\n * Retrieves the Real-Time Protocol (RTP) statistics for a specific channel.\n *\n * @param {string} channelId - The unique identifier of the channel for which RTP statistics are fetched.\n * @return {Promise<RTPStats>} A promise that resolves to the RTP statistics for the specified channel.\n */\n async getRTPStatistics(channelId: string): Promise<RTPStats> {\n return this.baseClient.get<RTPStats>(\n `/channels/${channelId}/rtp_statistics`\n );\n }\n\n /**\n * Creates an external media channel with the given options.\n *\n * @param {ExternalMediaOptions} options - The configuration options for creating the external media channel.\n * @return {Promise<Channel>} A promise that resolves with the created external media channel.\n */\n async createExternalMedia(options: ExternalMediaOptions): Promise<Channel> {\n const queryParams = toQueryParams(options);\n return this.baseClient.post<Channel>(\n `/channels/externalMedia?${queryParams}`\n );\n }\n\n /**\n * Initiates playback of a specific media item on a channel using the provided playback ID.\n *\n * @param {string} channelId - The unique identifier of the channel where playback will occur.\n * @param {string} playbackId - The unique identifier for the specific playback session.\n * @param {string} media - The media content to be played.\n * @param {PlaybackOptions} [options] - Optional playback configuration parameters.\n * @return {Promise<ChannelPlayback>} A promise that resolves with the playback details for the channel.\n */\n async playWithId(\n channelId: string,\n playbackId: string,\n media: string,\n options?: PlaybackOptions\n ): Promise<ChannelPlayback> {\n const queryParams = options ? `?${toQueryParams(options)}` : '';\n return this.baseClient.post<ChannelPlayback>(\n `/channels/${channelId}/play/${playbackId}${queryParams}`,\n { media }\n );\n }\n\n /**\n * Initiates a snoop operation on a specific channel using the provided channel ID and snoop ID.\n *\n * @param {string} channelId - The unique identifier of the channel to snoop on.\n * @param {string} snoopId - The unique identifier for the snoop operation.\n * @param {SnoopOptions} options - Additional options and parameters for the snoop operation.\n * @return {Promise<Channel>} A promise that resolves to the channel details after the snoop operation is initiated.\n */\n async snoopChannelWithId(\n channelId: string,\n snoopId: string,\n options: SnoopOptions\n ): Promise<Channel> {\n const queryParams = toQueryParams(options);\n return this.baseClient.post<Channel>(\n `/channels/${channelId}/snoop/${snoopId}?${queryParams}`\n );\n }\n\n /**\n * Starts Music on Hold for the specified channel with the provided Music on Hold class.\n *\n * @param {string} channelId - The unique identifier of the channel.\n * @param {string} mohClass - The Music on Hold class to be applied.\n * @return {Promise<void>} A promise that resolves when the operation is complete.\n */\n async startMohWithClass(channelId: string, mohClass: string): Promise<void> {\n const queryParams = `mohClass=${encodeURIComponent(mohClass)}`;\n await this.baseClient.post<void>(\n `/channels/${channelId}/moh?${queryParams}`\n );\n }\n\n /**\n * Retrieves the value of a specified variable for a given channel.\n *\n * @param {string} channelId - The unique identifier of the channel.\n * @param {string} variable - The name of the variable to retrieve.\n * @return {Promise<ChannelVar>} A promise that resolves to the value of the channel variable.\n * @throws {Error} Throws an error if the 'variable' parameter is not provided.\n */\n async getChannelVariable(\n channelId: string,\n variable: string\n ): Promise<ChannelVar> {\n if (!variable) {\n throw new Error(\"The 'variable' parameter is required.\");\n }\n return this.baseClient.get<ChannelVar>(\n `/channels/${channelId}/variable?variable=${encodeURIComponent(variable)}`\n );\n }\n\n /**\n * Sets a variable for a specific channel.\n *\n * @param {string} channelId - The unique identifier of the channel.\n * @param {string} variable - The name of the variable to be set. This parameter is required.\n * @param {string} [value] - The value of the variable to be set. This parameter is optional.\n * @return {Promise<void>} A promise that resolves when the variable is successfully set.\n * @throws {Error} Throws an error if the `variable` parameter is not provided.\n */\n async setChannelVariable(\n channelId: string,\n variable: string,\n value?: string\n ): Promise<void> {\n if (!variable) {\n throw new Error(\"The 'variable' parameter is required.\");\n }\n const queryParams = new URLSearchParams({\n variable,\n ...(value && { value }),\n });\n await this.baseClient.post<void>(\n `/channels/${channelId}/variable?${queryParams}`\n );\n }\n\n /**\n * Moves a specified channel to the given application with optional arguments.\n *\n * @param {string} channelId - The unique identifier of the channel to be moved.\n * @param {string} app - The target application to which the channel will be moved.\n * @param {string} [appArgs] - Optional arguments to be passed to the target application.\n * @return {Promise<void>} A promise that resolves when the operation is completed.\n */\n async moveToApplication(\n channelId: string,\n app: string,\n appArgs?: string\n ): Promise<void> {\n await this.baseClient.post<void>(`/channels/${channelId}/move`, {\n app,\n appArgs,\n });\n }\n\n /**\n * Continues the execution of a dialplan for a specific channel.\n *\n * @param {string} channelId - The unique identifier of the channel.\n * @param {string} [context] - The dialplan context to continue execution in, if specified.\n * @param {string} [extension] - The dialplan extension to proceed with, if provided.\n * @param {number} [priority] - The priority within the dialplan extension to resume at, if specified.\n * @param {string} [label] - The label to start from within the dialplan, if given.\n * @return {Promise<void>} Resolves when the dialplan is successfully continued.\n */\n async continueDialplan(\n channelId: string,\n context?: string,\n extension?: string,\n priority?: number,\n label?: string\n ): Promise<void> {\n await this.baseClient.post<void>(`/channels/${channelId}/continue`, {\n context,\n extension,\n priority,\n label,\n });\n }\n\n /**\n * Stops the music on hold for the specified channel.\n *\n * @param {string} channelId - The unique identifier of the channel where music on hold should be stopped.\n * @return {Promise<void>} Resolves when the music on hold is successfully stopped.\n */\n async stopMusicOnHold(channelId: string): Promise<void> {\n await this.baseClient.delete<void>(`/channels/${channelId}/moh`);\n }\n\n /**\n * Initiates the music on hold for the specified channel.\n *\n * @param {string} channelId - The unique identifier of the channel where the music on hold will be started.\n * @return {Promise<void>} A promise that resolves when the operation has been successfully invoked.\n */\n async startMusicOnHold(channelId: string): Promise<void> {\n await this.baseClient.post<void>(`/channels/${channelId}/moh`);\n }\n\n /**\n * Starts recording for a specific channel based on the provided options.\n *\n * @param {string} channelId - The unique identifier of the channel to start recording.\n * @param {RecordingOptions} options - The recording options to configure the recording process.\n * @return {Promise<Channel>} A promise that resolves to the channel object with updated recording state.\n */\n async record(channelId: string, options: RecordingOptions): Promise<Channel> {\n const queryParams = toQueryParams(options);\n return this.baseClient.post<Channel>(\n `/channels/${channelId}/record?${queryParams}`\n );\n }\n\n /**\n * Initiates a call on the specified channel with optional parameters for caller identification and timeout duration.\n *\n * @param {string} channelId - The ID of the channel where the call will be initiated.\n * @param {string} [caller] - Optional parameter specifying the name or identifier of the caller.\n * @param {number} [timeout] - Optional parameter defining the timeout duration for the call in seconds.\n * @return {Promise<void>} A promise that resolves when the call has been successfully initiated.\n */\n async dial(\n channelId: string,\n caller?: string,\n timeout?: number\n ): Promise<void> {\n const queryParams = new URLSearchParams({\n ...(caller && { caller }),\n ...(timeout && { timeout: timeout.toString() }),\n });\n await this.baseClient.post<void>(\n `/channels/${channelId}/dial?${queryParams}`\n );\n }\n\n /**\n * Redirects a channel to the specified endpoint.\n *\n * This method sends a POST request to update the redirect endpoint for the given channel.\n *\n * @param {string} channelId - The unique identifier of the channel to be redirected.\n * @param {string} endpoint - The new endpoint to redirect the channel to.\n * @return {Promise<void>} A promise that resolves when the operation is complete.\n */\n async redirectChannel(channelId: string, endpoint: string): Promise<void> {\n await this.baseClient.post<void>(\n `/channels/${channelId}/redirect?endpoint=${encodeURIComponent(endpoint)}`\n );\n }\n\n /**\n * Answers a specified channel by sending a POST request to the corresponding endpoint.\n *\n * @param {string} channelId - The unique identifier of the channel to be answered.\n * @return {Promise<void>} A promise that resolves when the channel has been successfully answered.\n */\n async answerChannel(channelId: string): Promise<void> {\n await this.baseClient.post<void>(`/channels/${channelId}/answer`);\n }\n\n /**\n * Rings the specified channel by sending a POST request to the appropriate endpoint.\n *\n * @param {string} channelId - The unique identifier of the channel to be rung.\n * @return {Promise<void>} A promise that resolves when the operation completes successfully.\n */\n async ringChannel(channelId: string): Promise<void> {\n await this.baseClient.post<void>(`/channels/${channelId}/ring`);\n }\n\n /**\n * Stops the ring channel for the specified channel ID.\n *\n * This method sends a DELETE request to the server to stop the ring action\n * associated with the provided channel ID.\n *\n * @param {string} channelId - The unique identifier of the channel for which the ring action should be stopped.\n * @return {Promise<void>} A promise that resolves when the ring channel is successfully stopped.\n */\n async stopRingChannel(channelId: string): Promise<void> {\n await this.baseClient.delete<void>(`/channels/${channelId}/ring`);\n }\n\n /**\n * Sends DTMF (Dual-Tone Multi-Frequency) signals to a specified channel.\n *\n * @param {string} channelId - The ID of the channel to which the DTMF signals should be sent.\n * @param {string} dtmf - The DTMF tones to be sent, represented as a string. Each character corresponds to a specific tone.\n * @param {Object} [options] - Optional configuration for the DTMF signal timing.\n * @param {number} [options.before] - Time in milliseconds to wait before sending the first DTMF tone.\n * @param {number} [options.between] - Time in milliseconds to wait between sending successive DTMF tones.\n * @param {number} [options.duration] - Duration in milliseconds for each DTMF tone.\n * @param {number} [options.after] - Time in milliseconds to wait after sending the last DTMF tone.\n * @return {Promise<void>} A promise that resolves when the DTMF signals are successfully sent.\n */\n async sendDTMF(\n channelId: string,\n dtmf: string,\n options?: {\n before?: number;\n between?: number;\n duration?: number;\n after?: number;\n }\n ): Promise<void> {\n const queryParams = toQueryParams({ dtmf, ...options });\n await this.baseClient.post<void>(\n `/channels/${channelId}/dtmf?${queryParams}`\n );\n }\n\n /**\n * Mutes a specified channel in the given direction.\n *\n * @param {string} channelId - The unique identifier of the channel to be muted.\n * @param {\"both\" | \"in\" | \"out\"} [direction=\"both\"] - The direction for muting, can be \"both\", \"in\", or \"out\". Default is \"both\".\n * @return {Promise<void>} A promise that resolves when the channel is successfully muted.\n */\n async muteChannel(\n channelId: string,\n direction: 'both' | 'in' | 'out' = 'both'\n ): Promise<void> {\n await this.baseClient.post<void>(\n `/channels/${channelId}/mute?direction=${direction}`\n );\n }\n\n /**\n * Unmutes a previously muted channel, allowing communication in the specified direction(s).\n *\n * @param {string} channelId - The unique identifier of the channel to be unmuted.\n * @param {\"both\" | \"in\" | \"out\"} [direction=\"both\"] - The direction of communication to unmute. Valid options are \"both\", \"in\" (incoming messages), or \"out\" (outgoing messages). Defaults to \"both\".\n * @return {Promise<void>} A promise that resolves when the channel is successfully unmuted.\n */\n async unmuteChannel(\n channelId: string,\n direction: 'both' | 'in' | 'out' = 'both'\n ): Promise<void> {\n await this.baseClient.delete<void>(\n `/channels/${channelId}/mute?direction=${direction}`\n );\n }\n\n /**\n * Places a specific channel on hold by sending a POST request to the server.\n *\n * @param {string} channelId - The unique identifier of the channel to be placed on hold.\n * @return {Promise<void>} A promise that resolves when the channel hold operation is completed.\n */\n async holdChannel(channelId: string): Promise<void> {\n await this.baseClient.post<void>(`/channels/${channelId}/hold`);\n }\n\n /**\n * Removes the hold status from a specific channel by its ID.\n *\n * @param {string} channelId - The unique identifier of the channel to unhold.\n * @return {Promise<void>} A promise that resolves when the channel hold is successfully removed.\n */\n async unholdChannel(channelId: string): Promise<void> {\n await this.baseClient.delete<void>(`/channels/${channelId}/hold`);\n }\n\n /**\n * Creates a new communication channel with the specified configuration.\n *\n * @param {OriginateRequest} data - The configuration data required to create the channel, including relevant details such as endpoint and channel variables.\n * @return {Promise<Channel>} A promise that resolves with the details of the created channel.\n */\n async createChannel(data: OriginateRequest): Promise<Channel> {\n return this.baseClient.post<Channel>('/channels/create', data);\n }\n\n /**\n * Initiates a new channel with the specified channel ID and originates a call using the provided data.\n *\n * @param {string} channelId - The unique identifier of the channel to be created.\n * @param {OriginateRequest} data - The data required to originate the call, including details such as endpoint and caller information.\n * @return {Promise<Channel>} A promise that resolves to the created Channel object.\n */\n async originateWithId(\n channelId: string,\n data: OriginateRequest\n ): Promise<Channel> {\n return this.baseClient.post<Channel>(`/channels/${channelId}`, data);\n }\n}\n", "import validate from './validate.js';\nconst byteToHex = [];\nfor (let i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n return (byteToHex[arr[offset + 0]] +\n byteToHex[arr[offset + 1]] +\n byteToHex[arr[offset + 2]] +\n byteToHex[arr[offset + 3]] +\n '-' +\n byteToHex[arr[offset + 4]] +\n byteToHex[arr[offset + 5]] +\n '-' +\n byteToHex[arr[offset + 6]] +\n byteToHex[arr[offset + 7]] +\n '-' +\n byteToHex[arr[offset + 8]] +\n byteToHex[arr[offset + 9]] +\n '-' +\n byteToHex[arr[offset + 10]] +\n byteToHex[arr[offset + 11]] +\n byteToHex[arr[offset + 12]] +\n byteToHex[arr[offset + 13]] +\n byteToHex[arr[offset + 14]] +\n byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n const uuid = unsafeStringify(arr, offset);\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;\n", "import { randomFillSync } from 'crypto';\nconst rnds8Pool = new Uint8Array(256);\nlet poolPtr = rnds8Pool.length;\nexport default function rng() {\n if (poolPtr > rnds8Pool.length - 16) {\n randomFillSync(rnds8Pool);\n poolPtr = 0;\n }\n return rnds8Pool.slice(poolPtr, (poolPtr += 16));\n}\n", "import { randomUUID } from 'crypto';\nexport default { randomUUID };\n", "import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n options = options || {};\n const rnds = options.random || (options.rng || rng)();\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n if (buf) {\n offset = offset || 0;\n for (let i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nexport default v4;\n", "import type { BaseClient } from '../baseClient.js';\nimport type { Endpoint, EndpointDetails } from '../interfaces/endpoints.types';\n\nexport class Endpoints {\n constructor(private client: BaseClient) {}\n\n /**\n * Lists all available endpoints.\n *\n * @returns A promise that resolves to an array of Endpoint objects representing all available endpoints.\n * @throws {Error} If the API response is not an array.\n */\n async list(): Promise<Endpoint[]> {\n const endpoints = await this.client.get<unknown>('/endpoints');\n\n if (!Array.isArray(endpoints)) {\n throw new Error('Resposta da API /endpoints n\u00E3o \u00E9 um array.');\n }\n\n return endpoints as Endpoint[];\n }\n\n /**\n * Retrieves details of a specific endpoint.\n *\n * @param technology - The technology of the endpoint (e.g., \"PJSIP\").\n * @param resource - The specific resource name of the endpoint (e.g., \"9001\").\n * @returns A promise that resolves to an EndpointDetails object containing the details of the specified endpoint.\n */\n async getDetails(\n technology: string,\n resource: string\n ): Promise<EndpointDetails> {\n return this.client.get<EndpointDetails>(\n `/endpoints/${technology}/${resource}`\n );\n }\n\n /**\n * Sends a message to a specific endpoint.\n *\n * @param technology - The technology of the endpoint (e.g., \"PJSIP\").\n * @param resource - The specific resource name of the endpoint (e.g., \"9001\").\n * @param message - The message payload to send to the endpoint.\n * @returns A promise that resolves when the message has been successfully sent.\n */\n async sendMessage(\n technology: string,\n resource: string,\n message: Record<string, unknown>\n ): Promise<void> {\n await this.client.post<void>(\n `/endpoints/${technology}/${resource}/sendMessage`,\n message\n );\n }\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { EventEmitter } from 'events';\nimport { isAxiosError } from 'axios';\nimport type { AriClient } from '../ariClient';\nimport type { BaseClient } from '../baseClient.js';\nimport type { AriEventMap, Playback, WebSocketEvent } from '../interfaces';\n\n/**\n * Utility function to extract error message\n * @param error - The error object to process\n * @returns A formatted error message\n */\nconst getErrorMessage = (error: unknown): string => {\n if (isAxiosError(error)) {\n return (\n error.response?.data?.message ||\n error.message ||\n 'An axios error occurred'\n );\n }\n if (error instanceof Error) {\n return error.message;\n }\n return 'An unknown error occurred';\n};\n\n/**\n * Represents a playback instance that provides methods for controlling media playback,\n * managing event listeners, and handling playback state.\n */\nexport class PlaybackInstance {\n private readonly eventEmitter = new EventEmitter();\n // biome-ignore lint/suspicious/noExplicitAny: Maps original listener \u2192 wrapped listener per event\n private readonly listenersMap = new Map<string, Map<(...args: any[]) => void, (...args: any[]) => void>>();\n private playbackData: Playback | null = null;\n public readonly id: string;\n\n /**\n * Creates a new PlaybackInstance.\n *\n * @param {AriClient} client - ARI client for communication\n * @param {BaseClient} baseClient - Base client for HTTP requests\n * @param {string} [playbackId] - Optional playback ID, generates timestamp-based ID if not provided\n */\n constructor(\n private readonly client: AriClient,\n private readonly baseClient: BaseClient,\n private readonly playbackId: string = `playback-${Date.now()}`\n ) {\n this.id = playbackId;\n }\n\n /**\n * Registers an event listener for a specific WebSocket event type.\n *\n * @param {T} event - Event type to listen for\n * @param {(data: WebSocketEvent) => void} listener - Callback function for the event\n */\n on<K extends keyof AriEventMap>(\n event: K,\n listener: (data: AriEventMap[K]) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n const eventListeners = this.listenersMap.get(event) ?? new Map();\n if (eventListeners.has(listener)) {\n console.warn(\n `Listener j\u00E1 registrado para evento ${event}, reutilizando.`\n );\n return;\n }\n\n const wrappedListener = (data: WebSocketEvent) => {\n if ('playback' in data && data.playback?.id === this.id) {\n listener(data as AriEventMap[K]);\n }\n };\n\n this.eventEmitter.on(event, wrappedListener);\n eventListeners.set(listener, wrappedListener as (...args: any[]) => void);\n this.listenersMap.set(event, eventListeners);\n }\n\n /**\n * Registers a one-time event listener for a specific WebSocket event type.\n *\n * @param {T} event - Event type to listen for\n * @param {(data: WebSocketEvent) => void} listener - Callback function for the event\n */\n once<K extends keyof AriEventMap>(\n event: K,\n listener: (data: AriEventMap[K]) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n const eventListeners = this.listenersMap.get(event) ?? new Map();\n if (eventListeners.has(listener)) {\n console.warn(\n `One-time listener j\u00E1 registrado para evento ${event}, reutilizando.`\n );\n return;\n }\n\n const wrappedListener = (data: WebSocketEvent) => {\n if ('playback' in data && data.playback?.id === this.id) {\n listener(data as AriEventMap[K]);\n this.off(event, listener);\n }\n };\n\n this.eventEmitter.once(event, wrappedListener);\n eventListeners.set(listener, wrappedListener as (...args: any[]) => void);\n this.listenersMap.set(event, eventListeners);\n }\n\n /**\n * Removes event listener(s) for a specific WebSocket event type.\n *\n * @param {T} event - Event type to remove listener(s) for\n * @param {(data: WebSocketEvent) => void} [listener] - Optional specific listener to remove\n */\n off<K extends keyof AriEventMap>(\n event: K,\n listener?: (data: AriEventMap[K]) => void\n ): void {\n if (!event) {\n throw new Error('Event type is required');\n }\n\n if (listener) {\n const eventListeners = this.listenersMap.get(event);\n const wrappedListener = eventListeners?.get(listener);\n if (wrappedListener) {\n this.eventEmitter.off(event, wrappedListener);\n eventListeners!.delete(listener);\n }\n } else {\n this.eventEmitter.removeAllListeners(event);\n this.listenersMap.delete(event);\n }\n }\n\n /**\n * Cleans up the PlaybackInstance, resetting its state and clearing resources.\n */\n public cleanup(): void {\n // Limpar dados do playback\n this.playbackData = null;\n\n // Remover todos os listeners\n this.removeAllListeners();\n\n // Limpar o map de listeners\n this.listenersMap.clear();\n\n console.log(`Playback instance ${this.id} cleaned up`);\n }\n\n /**\n * Emits a WebSocket event if it matches the current playback instance.\n *\n * @param {WebSocketEvent} event - Event to emit\n */\n emitEvent(event: WebSocketEvent): void {\n if (!event) {\n console.warn('Received invalid event');\n return;\n }\n\n if ('playback' in event && event.playback?.id === this.id) {\n this.eventEmitter.emit(event.type, event);\n }\n }\n\n /**\n * Retrieves current playback data.\n *\n * @returns {Promise<Playback>} Current playback data\n * @throws {Error} If playback is not properly initialized\n */\n async get(): Promise<Playback> {\n if (!this.id) {\n throw new Error('No playback associated with this instance');\n }\n\n try {\n this.playbackData = await this.baseClient.get<Playback>(\n `/playbacks/${this.id}`\n );\n return this.playbackData;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error retrieving playback data for ${this.id}:`, message);\n throw new Error(`Failed to get playback data: ${message}`);\n }\n }\n\n /**\n * Controls playback with specified operation.\n *\n * @param {\"pause\" | \"unpause\" | \"reverse\" | \"forward\"} operation - Control operation to perform\n * @throws {Error} If playback is not properly initialized or operation fails\n */\n async control(\n operation: 'pause' | 'unpause' | 'reverse' | 'forward'\n ): Promise<void> {\n if (!this.id) {\n throw new Error('No playback associated with this instance');\n }\n\n try {\n await this.baseClient.post<void>(\n `/playbacks/${this.id}/control?operation=${operation}`\n );\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error controlling playback ${this.id}:`, message);\n throw new Error(`Failed to control playback: ${message}`);\n }\n }\n\n /**\n * Stops the current playback.\n *\n * @throws {Error} If playback is not properly initialized or stop operation fails\n */\n async stop(): Promise<void> {\n if (!this.id) {\n throw new Error('No playback associated with this instance');\n }\n\n try {\n await this.baseClient.delete<void>(`/playbacks/${this.id}`);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error stopping playback ${this.id}:`, message);\n throw new Error(`Failed to stop playback: ${message}`);\n }\n }\n\n /**\n * Removes all event listeners associated with this playback instance.\n * This method clears both the internal listener map and the event emitter.\n *\n * @remarks\n * This method performs the following actions:\n * 1. Logs a message indicating the removal of listeners.\n * 2. Iterates through all stored listeners and removes them from the event emitter.\n * 3. Clears the internal listener map.\n * 4. Removes all listeners from the event emitter.\n *\n * @returns {void} This method doesn't return a value.\n */\n removeAllListeners(): void {\n console.log(`Removing all event listeners for playback ${this.id}`);\n this.listenersMap.forEach((listeners, event) => {\n listeners.forEach((wrappedListener) => {\n this.eventEmitter.off(event, wrappedListener);\n });\n });\n\n this.listenersMap.clear();\n this.eventEmitter.removeAllListeners();\n }\n\n /**\n * Checks if the playback instance has any listeners for a specific event.\n *\n * @param {string} event - Event type to check\n * @returns {boolean} True if there are listeners for the event\n */\n hasListeners(event: string): boolean {\n return this.eventEmitter.listenerCount(event) > 0;\n }\n\n /**\n * Gets the current playback data without making an API call.\n *\n * @returns {Playback | null} Current playback data or null if not available\n */\n getCurrentData(): Playback | null {\n return this.playbackData;\n }\n}\n\n/**\n * Manages playback instances and their related operations in the Asterisk REST Interface.\n * This class provides functionality to create, control, and manage playback instances,\n * as well as handle WebSocket events related to playbacks.\n */\nexport class Playbacks {\n private playbackInstances = new Map<string, PlaybackInstance>();\n private eventQueue = new Map<string, NodeJS.Timeout>();\n\n constructor(\n private baseClient: BaseClient,\n private client: AriClient\n ) {}\n\n /**\n * Gets or creates a playback instance\n * @param {Object} [params] - Optional parameters for getting/creating a playback instance\n * @param {string} [params.id] - Optional ID of an existing playback\n * @returns {PlaybackInstance} The requested or new playback instance\n */\n Playback(params?: { id?: string }): PlaybackInstance {\n try {\n const id = params?.id;\n\n if (!id) {\n const instance = new PlaybackInstance(this.client, this.baseClient);\n this.playbackInstances.set(instance.id, instance);\n return instance;\n }\n\n if (!this.playbackInstances.has(id)) {\n const instance = new PlaybackInstance(this.client, this.baseClient, id);\n this.playbackInstances.set(id, instance);\n return instance;\n }\n\n return this.playbackInstances.get(id)!;\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error creating/retrieving playback instance:`, message);\n throw new Error(`Failed to manage playback instance: ${message}`);\n }\n }\n\n /**\n * Cleans up resources associated with the Playbacks instance.\n * This method performs the following cleanup operations:\n * 1. Clears all pending timeouts in the event queue.\n * 2. Removes all playback instances.\n *\n * @remarks\n * This method should be called when the Playbacks instance is no longer needed\n * to ensure proper resource management and prevent memory leaks.\n *\n * @returns {void} This method doesn't return a value.\n */\n public cleanup(): void {\n // Limpar event queue\n this.eventQueue.forEach((timeout) => clearTimeout(timeout));\n this.eventQueue.clear();\n\n // Limpar todas as inst\u00E2ncias\n this.remove();\n }\n\n /**\n * Removes all playback instances and cleans up their resources.\n */\n public remove(): void {\n // Salvar os IDs antes de come\u00E7ar a limpeza\n const playbackIds = Array.from(this.playbackInstances.keys());\n\n for (const playbackId of playbackIds) {\n try {\n const instance = this.playbackInstances.get(playbackId);\n if (instance) {\n instance.cleanup(); // Usar o novo m\u00E9todo cleanup\n this.playbackInstances.delete(playbackId);\n console.log(`Playback instance ${playbackId} removed and cleaned up`);\n }\n } catch (error) {\n console.error(`Error cleaning up playback ${playbackId}:`, error);\n }\n }\n\n // Garantir que o map est\u00E1 vazio\n this.playbackInstances.clear();\n console.log('All playback instances have been removed and cleaned up');\n }\n\n /**\n * Removes a playback instance and cleans up its resources\n * @param {string} playbackId - ID of the playback instance to remove\n * @throws {Error} If the playback instance doesn't exist\n */\n public removePlaybackInstance(playbackId: string): void {\n if (!playbackId) {\n throw new Error('Playback ID is required');\n }\n\n const instance = this.playbackInstances.get(playbackId);\n if (instance) {\n try {\n instance.cleanup();\n this.playbackInstances.delete(playbackId);\n console.log(`Playback instance ${playbackId} removed from memory`);\n } catch (error) {\n console.error(`Error removing playback instance ${playbackId}:`, error);\n throw error;\n }\n } else {\n console.warn(`Attempt to remove non-existent instance: ${playbackId}`);\n }\n }\n\n /**\n * Propagates WebSocket events to the corresponding playback instance\n * @param {WebSocketEvent} event - The WebSocket event to propagate\n */\n public propagateEventToPlayback(event: WebSocketEvent): void {\n if (!event || !('playback' in event) || !event.playback?.id) {\n console.warn('Invalid WebSocket event received');\n return;\n }\n\n const key = `${event.type}-${event.playback.id}`;\n const existing = this.eventQueue.get(key);\n if (existing) {\n clearTimeout(existing);\n }\n\n this.eventQueue.set(\n key,\n setTimeout(() => {\n const instance = this.playbackInstances.get(event.playback!.id!);\n if (instance) {\n instance.emitEvent(event);\n } else {\n console.warn(\n `No instance found for playback ${event.playback!.id}. Event ignored.`\n );\n }\n this.eventQueue.delete(key);\n }, 100)\n );\n }\n\n /**\n * Retrieves details of a specific playback\n * @param {string} playbackId - ID of the playback to get details for\n * @returns {Promise<Playback>} Promise resolving to playback details\n * @throws {Error} If the playback ID is invalid or the request fails\n */\n async get(playbackId: string): Promise<Playback> {\n if (!playbackId) {\n throw new Error('Playback ID is required');\n }\n\n try {\n return await this.baseClient.get<Playback>(`/playbacks/${playbackId}`);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error getting playback details ${playbackId}:`, message);\n throw new Error(`Failed to get playback details: ${message}`);\n }\n }\n\n /**\n * Controls a specific playback instance\n * @param {string} playbackId - ID of the playback to control\n * @param {\"pause\" | \"unpause\" | \"reverse\" | \"forward\"} operation - Operation to perform\n * @throws {Error} If the playback ID is invalid or the operation fails\n */\n async control(\n playbackId: string,\n operation: 'pause' | 'unpause' | 'reverse' | 'forward'\n ): Promise<void> {\n if (!playbackId) {\n throw new Error('Playback ID is required');\n }\n\n try {\n const playback = this.Playback({ id: playbackId });\n await playback.control(operation);\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error controlling playback ${playbackId}:`, message);\n throw new Error(`Failed to control playback: ${message}`);\n }\n }\n\n /**\n * Stops a specific playback instance\n * @param {string} playbackId - ID of the playback to stop\n * @throws {Error} If the playback ID is invalid or the stop operation fails\n */\n async stop(playbackId: string): Promise<void> {\n if (!playbackId) {\n throw new Error('Playback ID is required');\n }\n\n try {\n const playback = this.Playback({ id: playbackId });\n await playback.stop();\n } catch (error: unknown) {\n const message = getErrorMessage(error);\n console.warn(`Error stopping playback ${playbackId}:`, message);\n throw new Error(`Failed to stop playback: ${message}`);\n }\n }\n\n /**\n * Gets the count of active playback instances\n * @returns {number} Number of active playback instances\n */\n getInstanceCount(): number {\n return this.playbackInstances.size;\n }\n\n /**\n * Checks if a playback instance exists\n * @param {string} playbackId - ID of the playback to check\n * @returns {boolean} True if the playback instance exists\n */\n hasInstance(playbackId: string): boolean {\n return this.playbackInstances.has(playbackId);\n }\n}\n", "import type { BaseClient } from '../baseClient.js';\nimport type { Sound, SoundListRequest } from '../interfaces/sounds.types.js';\n\nexport class Sounds {\n constructor(private client: BaseClient) {}\n\n /**\n * Lists all available sounds.\n *\n * @param params - Optional parameters to filter the list of sounds.\n * @returns A promise that resolves to an array of Sound objects.\n * @throws {Error} If the API response is not an array.\n */\n async list(params?: SoundListRequest): Promise<Sound[]> {\n const query = params\n ? `?${new URLSearchParams(params as Record<string, string>).toString()}`\n : '';\n\n const sounds = await this.client.get<unknown>(`/sounds${query}`);\n\n if (!Array.isArray(sounds)) {\n throw new Error('Resposta da API /sounds n\u00E3o \u00E9 um array.');\n }\n\n return sounds as Sound[];\n }\n\n /**\n * Retrieves details of a specific sound.\n *\n * @param soundId - The unique identifier of the sound.\n * @returns A promise that resolves to a Sound object containing the details of the specified sound.\n */\n async getDetails(soundId: string): Promise<Sound> {\n return this.client.get<Sound>(`/sounds/${soundId}`);\n }\n}\n", "import { EventEmitter } from 'events';\nimport { type IBackOffOptions, backOff } from 'exponential-backoff';\nimport WebSocket from 'ws';\nimport type { AriClient } from './ariClient';\nimport type { BaseClient } from './baseClient.js';\nimport type { WebSocketEvent, WebSocketEventType } from './interfaces';\n\nconst DEFAULT_MAX_RECONNECT_ATTEMPTS = 30;\nconst DEFAULT_STARTING_DELAY = 500;\nconst DEFAULT_MAX_DELAY = 10000;\n\n/**\n * WebSocketClient handles real-time communication with the Asterisk server.\n * Extends EventEmitter to provide event-based communication patterns.\n */\nexport class WebSocketClient extends EventEmitter {\n private ws?: WebSocket;\n private isReconnecting = false;\n private isConnecting = false; // \uD83D\uDD39 Evita m\u00FAltiplas conex\u00F5es simult\u00E2neas\n private shouldReconnect = true; // \uD83D\uDD39 Nova flag para impedir reconex\u00E3o se for um fechamento intencional\n private readonly maxReconnectAttempts = DEFAULT_MAX_RECONNECT_ATTEMPTS;\n private reconnectionAttempts = 0;\n private lastWsUrl: string = '';\n private eventQueue: Map<string, NodeJS.Timeout> = new Map();\n\n /**\n * Logs the current connection status of the WebSocket client at regular intervals.\n *\n * This method sets up an interval that logs various connection-related metrics every 60 seconds.\n * The logged information includes:\n * - The number of active connections (0 or 1)\n * - The current state of the WebSocket connection\n * - The number of reconnection attempts made\n * - The size of the event queue\n *\n * This can be useful for monitoring the health and status of the WebSocket connection over time.\n *\n * @private\n * @returns {void}\n */\n private logConnectionStatus(): void {\n setInterval(() => {\n console.log({\n connections: this.ws ? 1 : 0,\n state: this.getState(),\n reconnectAttempts: this.reconnectionAttempts,\n eventQueueSize: this.eventQueue.size,\n });\n }, 60000);\n }\n\n /**\n * Sets up a heartbeat mechanism for the WebSocket connection.\n *\n * This method creates an interval that sends a ping message every 30 seconds\n * to keep the connection alive. The heartbeat is automatically cleared when\n * the WebSocket connection is closed.\n *\n * @private\n * @returns {void}\n */\n private setupHeartbeat(): void {\n const interval = setInterval(() => {\n if (this.ws?.readyState === WebSocket.OPEN) {\n this.ws.ping();\n }\n }, 30000);\n\n this.ws!.once('close', () => clearInterval(interval));\n }\n\n private readonly backOffOptions: IBackOffOptions = {\n numOfAttempts: DEFAULT_MAX_RECONNECT_ATTEMPTS,\n startingDelay: DEFAULT_STARTING_DELAY,\n maxDelay: DEFAULT_MAX_DELAY,\n timeMultiple: 2,\n jitter: 'full',\n delayFirstAttempt: false,\n retry: (error: Error, attemptNumber: number) => {\n console.warn(\n `Connection attempt #${attemptNumber} failed:`,\n error.message || 'Unknown error'\n );\n return attemptNumber < this.maxReconnectAttempts;\n },\n };\n\n /**\n * Creates a new WebSocketClient instance.\n *\n * This constructor initializes a WebSocketClient with the necessary dependencies and configuration.\n * It ensures that at least one application name is provided.\n *\n * @param baseClient - The BaseClient instance used for basic ARI operations and authentication.\n * @param apps - An array of application names to connect to via the WebSocket.\n * @param subscribedEvents - Optional. An array of WebSocketEventTypes to subscribe to. If not provided, all events will be subscribed.\n * @param ariClient - Optional. The AriClient instance, used for creating Channel and Playback instances when processing events.\n *\n * @throws {Error} Throws an error if the apps array is empty.\n */\n constructor(\n private readonly baseClient: BaseClient,\n private apps: string[],\n private subscribedEvents?: WebSocketEventType[],\n private readonly ariClient?: AriClient\n ) {\n super();\n\n if (!apps.length) {\n throw new Error('At least one application name is required');\n }\n }\n\n /**\n * Establishes a WebSocket connection to the Asterisk server.\n *\n * This method constructs the WebSocket URL using the base URL, credentials,\n * application names, and subscribed events. It then initiates the connection\n * using the constructed URL.\n *\n * @returns A Promise that resolves when the WebSocket connection is successfully established.\n * @throws Will throw an error if the connection cannot be established.\n */\n public async connect(): Promise<void> {\n if (this.isConnecting || this.isConnected()) {\n console.warn(\n 'WebSocket is already connecting or connected. Skipping new connection.'\n );\n return;\n }\n\n this.shouldReconnect = true; // \uD83D\uDD39 Permite reconex\u00E3o caso o WebSocket caia inesperadamente\n this.isConnecting = true;\n const { baseUrl, username, password, secure } = this.baseClient.getCredentials();\n\n const protocol = secure ? 'wss' : 'ws';\n const normalizedHost = baseUrl\n .replace(/^https?:\\/\\//, '')\n .replace(/\\/ari$/, '');\n\n const queryParams = new URLSearchParams();\n \n // \u2705 Usar api_key para conex\u00F5es n\u00E3o seguras (HTTP/WS)\n if (!secure) {\n queryParams.append('api_key', `${username}:${password}`);\n }\n \n queryParams.append('app', this.apps.join(','));\n this.subscribedEvents?.forEach((event) =>\n queryParams.append('event', event)\n );\n\n // \u2705 Construir URL baseada no tipo de conex\u00E3o\n if (secure) {\n // HTTPS/WSS: usar HTTP Basic Auth na URL (seu caso)\n this.lastWsUrl = `${protocol}://${encodeURIComponent(username)}:${encodeURIComponent(password)}@${normalizedHost}/ari/events?${queryParams.toString()}`;\n } else {\n // HTTP/WS: usar api_key query parameter (caso da issue)\n this.lastWsUrl = `${protocol}://${normalizedHost}/ari/events?${queryParams.toString()}`;\n }\n\n console.log(`WebSocket URL: ${this.lastWsUrl.replace(/(api_key=)[^&]*/, '$1***')}`); // Log sem mostrar credenciais\n\n try {\n await this.initializeWebSocket(this.lastWsUrl);\n } finally {\n this.isConnecting = false;\n }\n }\n\n /**\n * Reconecta o WebSocket com uma lista atualizada de aplica\u00E7\u00F5es.\n *\n * @param {string[]} newApps - Lista de aplica\u00E7\u00F5es para reconectar\n * @param {WebSocketEventType[]} [subscribedEvents] - Tipos de eventos para se inscrever (opcional)\n * @returns {Promise<void>} Promise resolvida quando reconectado com sucesso\n */\n public async reconnectWithApps(\n newApps: string[],\n subscribedEvents?: WebSocketEventType[]\n ): Promise<void> {\n if (!newApps.length) {\n throw new Error('At least one application name is required');\n }\n\n // Mesclar aplica\u00E7\u00F5es existentes com novas\n const uniqueApps = Array.from(new Set([...this.apps, ...newApps]));\n\n // Se n\u00E3o h\u00E1 mudan\u00E7as nas aplica\u00E7\u00F5es, n\u00E3o reconectar\n if (\n uniqueApps.length === this.apps.length &&\n uniqueApps.every((app) => this.apps.includes(app))\n ) {\n console.log(\n 'No changes in applications list, maintaining current connection'\n );\n return;\n }\n\n console.log(\n `Reconnecting WebSocket with updated applications: ${uniqueApps.join(', ')}`\n );\n\n // Armazenar os aplicativos atualizados\n this.apps = uniqueApps;\n\n // Atualizar eventos inscritos se fornecidos\n if (subscribedEvents) {\n this.subscribedEvents = subscribedEvents;\n }\n\n // Fechar conex\u00E3o existente\n if (this.ws) {\n await new Promise<void>((resolve) => {\n this.once('disconnected', () => resolve());\n this.close();\n });\n }\n\n // Reconectar com apps atualizados\n await this.connect();\n console.log('WebSocket reconnected successfully with updated applications');\n }\n\n /**\n * Adiciona novas aplica\u00E7\u00F5es \u00E0 conex\u00E3o WebSocket existente.\n *\n * @param {string[]} newApps - Lista de novas aplica\u00E7\u00F5es para adicionar\n * @param {WebSocketEventType[]} [subscribedEvents] - Tipos de eventos para se inscrever (opcional)\n * @returns {Promise<void>} Promise resolvida quando as aplica\u00E7\u00F5es s\u00E3o adicionadas com sucesso\n */\n public async addApps(\n newApps: string[],\n subscribedEvents?: WebSocketEventType[]\n ): Promise<void> {\n if (!newApps.length) {\n throw new Error('At least one application name is required');\n }\n\n // Verificar se h\u00E1 novas aplica\u00E7\u00F5es que ainda n\u00E3o est\u00E3o na lista\n const appsToAdd = newApps.filter((app) => !this.apps.includes(app));\n\n if (appsToAdd.length === 0) {\n console.log('All applications are already registered');\n return;\n }\n\n // Adicionar novas aplica\u00E7\u00F5es \u00E0 lista atual\n await this.reconnectWithApps(appsToAdd, subscribedEvents);\n }\n\n /**\n * Initializes a WebSocket connection with exponential backoff retry mechanism.\n *\n * This method attempts to establish a WebSocket connection to the specified URL.\n * It sets up event listeners for the WebSocket's 'open', 'message', 'close', and 'error' events.\n * If the connection is successful, it emits a 'connected' event. If it's a reconnection,\n * it also emits a 'reconnected' event with the current apps and subscribed events.\n * In case of connection failure, it uses an exponential backoff strategy to retry.\n *\n * @param wsUrl - The WebSocket URL to connect to.\n * @returns A Promise that resolves when the connection is successfully established,\n * or rejects if an error occurs during the connection process.\n * @throws Will throw an error if the WebSocket connection cannot be established\n * after the maximum number of retry attempts.\n */\n private async initializeWebSocket(wsUrl: string): Promise<void> {\n return backOff(async () => {\n return new Promise<void>((resolve, reject) => {\n try {\n this.ws = new WebSocket(wsUrl);\n\n this.ws.once('open', () => {\n this.setupHeartbeat();\n if (this.isReconnecting) {\n this.emit('reconnected', {\n apps: this.apps,\n subscribedEvents: this.subscribedEvents,\n });\n }\n this.isReconnecting = false;\n this.reconnectionAttempts = 0;\n this.emit('connected');\n resolve();\n });\n\n this.ws.on('message', (data) => this.handleMessage(data.toString()));\n\n this.ws.once('close', (code) => {\n // \uD83D\uDD39 Usa `once` para evitar handlers duplicados\n console.warn(\n `WebSocket disconnected with code ${code}. Attempting to reconnect...`\n );\n if (!this.isReconnecting) {\n this.reconnect(this.lastWsUrl);\n }\n });\n\n this.ws.once('error', (err: Error) => {\n // \uD83D\uDD39 Usa `once` para evitar ac\u00FAmulo de eventos\n console.error('WebSocket error:', err.message);\n if (!this.isReconnecting) {\n this.reconnect(this.lastWsUrl);\n }\n reject(err);\n });\n } catch (error) {\n reject(error);\n }\n });\n }, this.backOffOptions);\n }\n\n private getEventKey(event: WebSocketEvent): string {\n // Cria uma chave \u00FAnica baseada no tipo de evento e IDs relevantes\n const ids = [];\n if ('channel' in event && event.channel?.id) ids.push(event.channel.id);\n if ('playback' in event && event.playback?.id) ids.push(event.playback.id);\n if ('bridge' in event && event.bridge?.id) ids.push(event.bridge.id);\n return `${event.type}-${ids.join('-')}`;\n }\n\n private processEvent(event: WebSocketEvent): void {\n if (\n this.subscribedEvents?.length &&\n !this.subscribedEvents.includes(event.type)\n ) {\n return;\n }\n\n if ('channel' in event && event.channel?.id && this.ariClient) {\n const instanceChannel = this.ariClient.Channel(event.channel.id);\n instanceChannel.emitEvent(event);\n event.instanceChannel = instanceChannel;\n }\n\n if ('playback' in event && event.playback?.id && this.ariClient) {\n const instancePlayback = this.ariClient.Playback(event.playback.id);\n instancePlayback.emitEvent(event);\n event.instancePlayback = instancePlayback;\n }\n\n if ('bridge' in event && event.bridge?.id && this.ariClient) {\n const instanceBridge = this.ariClient.Bridge(event.bridge.id);\n instanceBridge.emitEvent(event);\n event.instanceBridge = instanceBridge;\n }\n\n this.emit(event.type, event);\n }\n\n /**\n * Handles incoming WebSocket messages by parsing and processing events.\n *\n * This method parses the raw message into a WebSocketEvent, filters it based on\n * subscribed events (if any), processes channel and playback events, and emits\n * the event to listeners. It also handles any errors that occur during processing.\n *\n * @param rawMessage - The raw message string received from the WebSocket connection.\n * @returns void This method doesn't return a value but emits events.\n *\n * @throws Will emit an 'error' event if the message cannot be parsed or processed.\n */\n private handleMessage(rawMessage: string): void {\n try {\n const parsed: unknown = JSON.parse(rawMessage);\n if (\n !parsed ||\n typeof parsed !== 'object' ||\n !('type' in parsed) ||\n typeof (parsed as Record<string, unknown>).type !== 'string'\n ) {\n console.warn('Received malformed WebSocket message (missing type)');\n return;\n }\n const event = parsed as WebSocketEvent;\n\n // Debounce eventos similares\n const key = this.getEventKey(event);\n const existing = this.eventQueue.get(key);\n if (existing) {\n clearTimeout(existing);\n }\n\n this.eventQueue.set(\n key,\n setTimeout(() => {\n this.processEvent(event);\n this.eventQueue.delete(key);\n }, 100)\n );\n } catch (error) {\n console.error('Error processing WebSocket message:', error);\n this.emit('error', new Error('Failed to decode WebSocket message'));\n }\n }\n\n /**\n * Attempts to reconnect to the WebSocket server using an exponential backoff strategy.\n *\n * This method is called when the WebSocket connection is closed unexpectedly.\n * It increments the reconnection attempt counter, logs the attempt, and uses\n * the backOff utility to retry the connection with exponential delays between attempts.\n *\n * @param wsUrl - The WebSocket URL to reconnect to.\n * @returns void - This method doesn't return a value.\n *\n * @emits reconnectFailed - Emitted if all reconnection attempts fail.\n */\n private async reconnect(wsUrl: string): Promise<void> {\n if (!this.shouldReconnect) {\n console.warn(\n 'Reconnection skipped because WebSocket was intentionally closed.'\n );\n return;\n }\n\n if (this.isReconnecting) {\n console.warn('J\u00E1 h\u00E1 uma tentativa de reconex\u00E3o em andamento.');\n return;\n }\n\n this.isReconnecting = true;\n this.reconnectionAttempts++;\n console.log(`Tentando reconex\u00E3o #${this.reconnectionAttempts}...`);\n\n backOff(() => this.initializeWebSocket(wsUrl), this.backOffOptions)\n .catch((error) => {\n console.error(`Falha ao reconectar: ${error.message}`);\n this.emit('reconnectFailed', error);\n })\n .finally(() => {\n this.isReconnecting = false;\n });\n }\n\n /**\n * Closes the WebSocket connection if it exists.\n *\n * This method attempts to gracefully close the WebSocket connection\n * and sets the WebSocket instance to undefined. If an error occurs\n * during the closing process, it will be caught and logged.\n *\n * @throws {Error} Logs an error message if closing the WebSocket fails.\n */\n public async close(): Promise<void> {\n if (!this.ws) {\n console.warn('No WebSocket connection to close');\n return;\n }\n\n console.log('Closing WebSocket connection.');\n this.shouldReconnect = false;\n\n // Limpar event queue\n this.eventQueue.forEach((timeout) => clearTimeout(timeout));\n this.eventQueue.clear();\n\n const closeTimeout = setTimeout(() => {\n if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {\n this.ws.terminate();\n }\n }, 5000);\n\n try {\n this.ws.removeAllListeners();\n await new Promise<void>((resolve) => {\n this.ws!.once('close', () => {\n clearTimeout(closeTimeout);\n resolve();\n });\n this.ws!.close();\n });\n } catch (error) {\n console.error('Error closing WebSocket:', error);\n } finally {\n this.ws = undefined;\n this.emit('disconnected');\n }\n }\n\n /**\n * Checks if the WebSocket connection is currently open and active.\n *\n * This method provides a way to determine the current state of the WebSocket connection.\n * It checks if the WebSocket's readyState property is equal to WebSocket.OPEN,\n * which indicates an active connection.\n *\n * @returns {boolean} True if the WebSocket connection is open and active, false otherwise.\n */\n public isConnected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Retrieves the current state of the WebSocket connection.\n *\n * This method provides a way to check the current state of the WebSocket connection.\n * It returns a number corresponding to one of the WebSocket readyState values:\n * - 0 (CONNECTING): The connection is not yet open.\n * - 1 (OPEN): The connection is open and ready to communicate.\n * - 2 (CLOSING): The connection is in the process of closing.\n * - 3 (CLOSED): The connection is closed or couldn't be opened.\n *\n * If the WebSocket instance doesn't exist, it returns WebSocket.CLOSED (3).\n *\n * @returns {number} A number representing the current state of the WebSocket connection.\n */\n public getState(): number {\n return this.ws?.readyState ?? WebSocket.CLOSED;\n }\n\n /**\n * Cleans up the WebSocketClient instance, resetting its state and clearing resources.\n *\n * This method performs the following cleanup operations:\n * - Clears the event queue and cancels any pending timeouts.\n * - Stops any ongoing reconnection attempts.\n * - Clears the stored WebSocket URL.\n * - Resets the reconnection attempt counter.\n * - Removes all event listeners attached to this instance.\n *\n * This method is typically called when the WebSocketClient is no longer needed or\n * before reinitializing the client to ensure a clean slate.\n *\n * @returns {void} This method doesn't return a value.\n */\n public cleanup(): void {\n // Limpar event queue\n this.eventQueue.forEach((timeout) => clearTimeout(timeout));\n this.eventQueue.clear();\n\n // Parar tentativas de reconex\u00E3o\n this.shouldReconnect = false;\n this.isReconnecting = false;\n\n // Limpar URL armazenada\n this.lastWsUrl = '';\n\n // Resetar contadores\n this.reconnectionAttempts = 0;\n\n // Remover todos os listeners\n this.removeAllListeners();\n }\n}\n", "import type { BaseClient } from '../baseClient';\nimport type {\n StoredRecording,\n LiveRecording,\n GetStoredParams,\n DeleteStoredParams,\n GetStoredFileParams,\n CopyStoredParams,\n GetLiveParams,\n CancelParams,\n StopParams,\n PauseParams,\n UnpauseParams,\n MuteParams,\n UnmuteParams,\n} from '../interfaces';\n\nexport class Recordings {\n constructor(private readonly baseClient: BaseClient) {}\n /**\n * List recordings that are complete.\n * @returns Promise<StoredRecording[]>\n */\n async listStored(): Promise<StoredRecording[]> {\n return this.baseClient.get<StoredRecording[]>('/recordings/stored');\n }\n\n /**\n * Get a stored recording's details.\n * @param params - The parameters for getting a stored recording\n * @returns Promise<StoredRecording>\n */\n async getStored(params: GetStoredParams): Promise<StoredRecording> {\n return this.baseClient.get<StoredRecording>(\n `/recordings/stored/${params.recordingName}`\n );\n }\n\n /**\n * Delete a stored recording.\n * @param params - The parameters for deleting a stored recording\n * @returns Promise<void>\n */\n async deleteStored(params: DeleteStoredParams): Promise<void> {\n return this.baseClient.delete<void>(\n `/recordings/stored/${params.recordingName}`\n );\n }\n\n /**\n * Get the file associated with the stored recording.\n * @param params - The parameters for getting a stored recording file\n * @returns Promise<ArrayBuffer>\n */\n async getStoredFile(params: GetStoredFileParams): Promise<ArrayBuffer> {\n return this.baseClient.get<ArrayBuffer>(\n `/recordings/stored/${params.recordingName}/file`,\n { responseType: 'arraybuffer' }\n );\n }\n\n /**\n * Copy a stored recording.\n * @param params - The parameters for copying a stored recording\n * @returns Promise<StoredRecording>\n */\n async copyStored(params: CopyStoredParams): Promise<StoredRecording> {\n return this.baseClient.post<StoredRecording>(\n `/recordings/stored/${params.recordingName}/copy`,\n undefined,\n {\n params: {\n destinationRecordingName: params.destinationRecordingName,\n },\n }\n );\n }\n\n /**\n * List live recordings.\n * @param params - The parameters for getting a live recording\n * @returns Promise<LiveRecording>\n */\n async getLive(params: GetLiveParams): Promise<LiveRecording> {\n return this.baseClient.get<LiveRecording>(\n `/recordings/live/${params.recordingName}`\n );\n }\n\n /**\n * Stop a live recording and discard it.\n * @param params - The parameters for canceling a recording\n * @returns Promise<void>\n */\n async cancel(params: CancelParams): Promise<void> {\n return this.baseClient.delete<void>(\n `/recordings/live/${params.recordingName}`\n );\n }\n\n /**\n * Stop a live recording and store it.\n * @param params - The parameters for stopping a recording\n * @returns Promise<void>\n */\n async stop(params: StopParams): Promise<void> {\n return this.baseClient.post<void>(\n `/recordings/live/${params.recordingName}/stop`\n );\n }\n\n /**\n * Pause a live recording.\n * @param params - The parameters for pausing a recording\n * @returns Promise<void>\n */\n async pause(params: PauseParams): Promise<void> {\n return this.baseClient.post<void>(\n `/recordings/live/${params.recordingName}/pause`\n );\n }\n\n /**\n * Unpause a live recording.\n * @param params - The parameters for unpausing a recording\n * @returns Promise<void>\n */\n async unpause(params: UnpauseParams): Promise<void> {\n return this.baseClient.delete<void>(\n `/recordings/live/${params.recordingName}/pause`\n );\n }\n\n /**\n * Mute a live recording.\n * @param params - The parameters for muting a recording\n * @returns Promise<void>\n */\n async mute(params: MuteParams): Promise<void> {\n return this.baseClient.post<void>(\n `/recordings/live/${params.recordingName}/mute`\n );\n }\n\n /**\n * Unmute a live recording.\n * @param params - The parameters for unmuting a recording\n * @returns Promise<void>\n */\n async unmute(params: UnmuteParams): Promise<void> {\n return this.baseClient.delete<void>(\n `/recordings/live/${params.recordingName}/mute`\n );\n }\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { BaseClient } from './baseClient.js';\nimport type {\n AriClientConfig,\n AriEventMap,\n WebSocketEvent,\n WebSocketEventType,\n} from './interfaces';\nimport type {\n TypedWebSocketEventListener,\n WebSocketEventListener,\n} from './interfaces/websocket.types';\nimport { Applications } from './resources/applications.js';\nimport { Asterisk } from './resources/asterisk';\nimport { type BridgeInstance, Bridges } from './resources/bridges';\nimport { type ChannelInstance, Channels } from './resources/channels.js';\nimport { Endpoints } from './resources/endpoints';\nimport { type PlaybackInstance, Playbacks } from './resources/playbacks';\nimport { Sounds } from './resources/sounds';\nimport { WebSocketClient } from './websocketClient.js';\nimport { Recordings } from './resources/recordings';\n\n/**\n * Main client class for interacting with the Asterisk REST Interface (ARI).\n * Provides access to various ARI resources and WebSocket event handling capabilities.\n *\n * @example\n * ```typescript\n * const client = new AriClient({\n * host: 'localhost',\n * port: 8088,\n * username: 'user',\n * password: 'secret'\n * });\n * ```\n */\nexport class AriClient {\n private readonly baseClient: BaseClient;\n private webSocketClient?: WebSocketClient;\n private eventListeners = new Map<string, WebSocketEventListener[]>();\n\n public readonly channels: Channels;\n public readonly endpoints: Endpoints;\n public readonly applications: Applications;\n public readonly playbacks: Playbacks;\n public readonly sounds: Sounds;\n public readonly asterisk: Asterisk;\n public readonly bridges: Bridges;\n public readonly recordings: Recordings;\n\n /**\n * Creates a new instance of the ARI client.\n *\n * @param {AriClientConfig} config - Configuration options for the ARI client\n * @throws {Error} If required configuration parameters are missing\n */\n constructor(private readonly config: AriClientConfig) {\n if (!config.host || !config.port || !config.username || !config.password) {\n throw new Error('Missing required configuration parameters');\n }\n\n // Normalize host and create base URL\n const httpProtocol = config.secure ? 'https' : 'http';\n const normalizedHost = config.host.replace(/^https?:\\/\\//, '');\n const baseUrl = `${httpProtocol}://${normalizedHost}:${config.port}/ari`;\n\n // Initialize base client and resources\n this.baseClient = new BaseClient(baseUrl, config.username, config.password, config.secure || false);\n\n // Initialize resource handlers\n this.channels = new Channels(this.baseClient, this);\n this.playbacks = new Playbacks(this.baseClient, this);\n this.bridges = new Bridges(this.baseClient, this);\n this.endpoints = new Endpoints(this.baseClient);\n this.applications = new Applications(this.baseClient);\n this.sounds = new Sounds(this.baseClient);\n this.asterisk = new Asterisk(this.baseClient);\n this.recordings = new Recordings(this.baseClient);\n\n console.log(`ARI Client initialized with base URL: ${baseUrl}`);\n }\n\n public async cleanup(): Promise<void> {\n try {\n console.log('Starting ARI Client cleanup...');\n\n // Primeiro limpa o WebSocket para evitar novos eventos\n if (this.webSocketClient) {\n await this.closeWebSocket();\n }\n\n // Limpar todos os resources em paralelo\n await Promise.all([\n // Cleanup de channels\n (async () => {\n try {\n this.channels.cleanup();\n } catch (error) {\n console.error('Error cleaning up channels:', error);\n }\n })(),\n // Cleanup de playbacks\n (async () => {\n try {\n this.playbacks.cleanup();\n } catch (error) {\n console.error('Error cleaning up playbacks:', error);\n }\n })(),\n // Cleanup de bridges\n (async () => {\n try {\n this.bridges.cleanup();\n } catch (error) {\n console.error('Error cleaning up bridges:', error);\n }\n })(),\n ]);\n\n // Limpar listeners do cliente ARI\n this.eventListeners.forEach((listeners, event) => {\n listeners.forEach((listener) => {\n this.off(event as keyof AriEventMap, listener);\n });\n });\n this.eventListeners.clear();\n\n console.log('ARI Client cleanup completed successfully');\n } catch (error) {\n console.error('Error during ARI Client cleanup:', error);\n throw error;\n }\n }\n\n /**\n * Initializes a WebSocket connection for receiving events.\n *\n * @param {string[]} apps - List of application names to subscribe to\n * @param {WebSocketEventType[]} [subscribedEvents] - Optional list of specific event types to subscribe to\n * @returns {Promise<void>} Resolves when connection is established\n * @throws {Error} If connection fails\n */\n public async connectWebSocket(\n apps: string[],\n subscribedEvents?: WebSocketEventType[]\n ): Promise<void> {\n try {\n if (!apps.length) {\n throw new Error('At least one application name is required.');\n }\n\n // Se j\u00E1 existe uma conex\u00E3o, apenas adicione novas aplica\u00E7\u00F5es sem fechar\n if (this.webSocketClient && this.webSocketClient.isConnected()) {\n console.log(\n 'WebSocket already connected. Reconnecting with updated apps...'\n );\n await this.webSocketClient.reconnectWithApps(apps, subscribedEvents);\n return;\n }\n\n // Criar nova conex\u00E3o (apenas se n\u00E3o existir uma ativa)\n this.webSocketClient = new WebSocketClient(\n this.baseClient,\n apps,\n subscribedEvents,\n this\n );\n\n await this.webSocketClient.connect();\n } catch (error) {\n console.error('Failed to establish WebSocket connection:', error);\n throw error;\n }\n }\n\n /**\n * Adds applications to the existing WebSocket connection.\n *\n * @param {string[]} apps - Additional applications to subscribe to\n * @param {WebSocketEventType[]} [subscribedEvents] - Optional list of specific event types to subscribe to\n * @returns {Promise<void>} Resolves when applications are added successfully\n * @throws {Error} If no WebSocket connection exists or if the operation fails\n */\n public async addApplicationsToWebSocket(\n apps: string[],\n subscribedEvents?: WebSocketEventType[]\n ): Promise<void> {\n if (!this.webSocketClient || !this.webSocketClient.isConnected()) {\n throw new Error(\n 'No active WebSocket connection. Create one first with connectWebSocket().'\n );\n }\n\n await this.webSocketClient.addApps(apps, subscribedEvents);\n }\n\n /**\n * Destroys the ARI Client instance, cleaning up all resources and removing circular references.\n * This method should be called when the ARI Client is no longer needed to ensure proper cleanup.\n *\n * @returns {Promise<void>} A promise that resolves when the destruction process is complete.\n * @throws {Error} If an error occurs during the destruction process.\n */\n public async destroy(): Promise<void> {\n try {\n console.log('Destroying ARI Client...');\n\n // Cleanup de todos os recursos\n await this.cleanup();\n\n // Limpar refer\u00EAncias\n this.webSocketClient = undefined;\n\n // Remover todas as refer\u00EAncias circulares\n (this.channels as any) = null;\n (this.playbacks as any) = null;\n (this.bridges as any) = null;\n (this.endpoints as any) = null;\n (this.applications as any) = null;\n (this.sounds as any) = null;\n (this.asterisk as any) = null;\n (this.recordings as any) = null;\n\n console.log('ARI Client destroyed successfully');\n } catch (error) {\n console.error('Error destroying ARI Client:', error);\n throw error;\n }\n }\n\n /**\n * Registers an event listener for WebSocket events.\n *\n * @param {K} event - The event type to listen for\n * @param {Function} listener - Callback function for handling the event\n * @throws {Error} If WebSocket is not connected\n */\n public on<K extends keyof AriEventMap>(\n event: K,\n listener: TypedWebSocketEventListener<K>\n ): void {\n if (!this.webSocketClient) {\n throw new Error('WebSocket is not connected');\n }\n\n // \uD83D\uDD39 Verifica se o listener j\u00E1 est\u00E1 registrado para evitar duplica\u00E7\u00E3o\n const existingListeners = this.eventListeners.get(event) || [];\n if (existingListeners.includes(listener as WebSocketEventListener)) {\n console.warn(`Listener already registered for event ${event}, reusing.`);\n return;\n }\n\n // Conectar o listener diretamente\n this.webSocketClient.on(event, listener);\n\n // Armazenar o listener para refer\u00EAncia e limpeza futura\n existingListeners.push(listener as WebSocketEventListener);\n this.eventListeners.set(event, existingListeners);\n\n console.log(`Event listener successfully registered for ${event}`);\n }\n\n /**\n * Registers a one-time event listener for WebSocket events.\n *\n * @param {T} event - The event type to listen for\n * @param {Function} listener - Callback function for handling the event\n * @throws {Error} If WebSocket is not connected\n */\n public once<K extends keyof AriEventMap>(\n event: K,\n listener: TypedWebSocketEventListener<K>\n ): void {\n if (!this.webSocketClient) {\n throw new Error('WebSocket is not connected');\n }\n\n // \uD83D\uDD39 Check if an identical listener already exists to avoid duplication\n const existingListeners = this.eventListeners.get(event) || [];\n if (existingListeners.includes(listener as WebSocketEventListener)) {\n console.warn(\n `One-time listener already registered for event ${event}, reusing.`\n );\n return;\n }\n\n const wrappedListener = (data: AriEventMap[K]) => {\n listener(data);\n this.off(event, wrappedListener);\n };\n\n this.webSocketClient.once(event, wrappedListener);\n this.eventListeners.set(event, [\n ...existingListeners,\n wrappedListener as WebSocketEventListener,\n ]);\n\n console.log(`One-time event listener registered for ${event}`);\n }\n\n /**\n * Removes an event listener for WebSocket events.\n *\n * @param {T} event - The event type to remove listener for\n * @param {Function} listener - The listener function to remove\n */\n public off<K extends keyof AriEventMap>(\n event: K,\n listener: TypedWebSocketEventListener<K>\n ): void {\n if (!this.webSocketClient) {\n console.warn('No WebSocket connection to remove listener from');\n return;\n }\n\n this.webSocketClient.off(event, listener);\n const existingListeners = this.eventListeners.get(event) || [];\n this.eventListeners.set(\n event,\n existingListeners.filter(\n (l) => l !== (listener as WebSocketEventListener)\n )\n );\n\n console.log(`Event listener removed for ${event}`);\n }\n\n /**\n * Closes the WebSocket connection if one exists.\n */\n public closeWebSocket(): Promise<void> {\n return new Promise((resolve) => {\n if (!this.webSocketClient) {\n console.warn('No WebSocket connection to close');\n resolve();\n return;\n }\n\n console.log('Closing WebSocket connection and cleaning up listeners.');\n\n const closeTimeout = setTimeout(() => {\n if (this.webSocketClient) {\n this.webSocketClient.removeAllListeners();\n this.webSocketClient = undefined;\n }\n resolve();\n }, 5000);\n\n this.eventListeners.forEach((listeners, event) => {\n listeners.forEach((listener) => {\n this.webSocketClient?.off(\n event as keyof AriEventMap,\n listener as (...args: any[]) => void\n );\n });\n });\n this.eventListeners.clear();\n\n this.webSocketClient.once('close', () => {\n clearTimeout(closeTimeout);\n this.webSocketClient = undefined;\n console.log('WebSocket connection closed');\n resolve();\n });\n\n this.webSocketClient\n .close()\n .then(() => {\n clearTimeout(closeTimeout);\n this.webSocketClient = undefined;\n resolve();\n })\n .catch((error) => {\n console.error('Error during WebSocket close:', error);\n clearTimeout(closeTimeout);\n this.webSocketClient = undefined;\n resolve();\n });\n });\n }\n\n /**\n * Creates or retrieves a Channel instance.\n *\n * @param {string} [channelId] - Optional ID of an existing channel\n * @returns {ChannelInstance} A new or existing channel instance\n */\n public Channel(channelId?: string): ChannelInstance {\n return this.channels.Channel({ id: channelId });\n }\n\n /**\n * Creates or retrieves a Playback instance.\n *\n * @param {string} [playbackId] - Optional ID of an existing playback\n * @param {string} [_app] - Optional application name (deprecated)\n * @returns {PlaybackInstance} A new or existing playback instance\n */\n public Playback(playbackId?: string, _app?: string): PlaybackInstance {\n return this.playbacks.Playback({ id: playbackId });\n }\n\n /**\n * Creates or retrieves a Bridge instance.\n *\n * This function allows you to create a new Bridge instance or retrieve an existing one\n * based on the provided bridge ID.\n *\n * @param {string} [bridgeId] - Optional ID of an existing bridge. If provided, retrieves the\n * existing bridge with this ID. If omitted, creates a new bridge.\n * @returns {BridgeInstance} A new or existing Bridge instance that can be used to interact\n * with the Asterisk bridge.\n */\n public Bridge(bridgeId?: string): BridgeInstance {\n return this.bridges.Bridge({ id: bridgeId });\n }\n\n /**\n * Gets the current WebSocket connection status.\n *\n * @returns {boolean} True if WebSocket is connected, false otherwise\n */\n public isWebSocketConnected(): boolean {\n return !!this.webSocketClient && this.webSocketClient.isConnected();\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["exports", "exports", "exports", "exports", "Delay", "exports", "SkipFirstDelay", "exports", "AlwaysDelay", "exports", "exports", "backOff", "exports", "BackOff", "axios", "message", "import_axios", "toQueryParams", "toQueryParams", "import_events", "import_axios", "import_crypto", "getErrorMessage", "toQueryParams", "import_events", "import_axios", "getErrorMessage", "import_events", "WebSocket"]
7
7
  }