@ipcom/asterisk-ari 0.0.4 → 0.0.6

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.
@@ -97,29 +97,85 @@ var Channels = class {
97
97
  // src/ari-client/websocketClient.ts
98
98
  var import_ws = __toESM(require("ws"), 1);
99
99
  var WebSocketClient = class {
100
+ // Para evitar reconexões automáticas quando fechado manualmente
100
101
  constructor(url) {
101
102
  this.url = url;
102
103
  }
103
104
  ws = null;
104
- async connect() {
105
+ isClosedManually = false;
106
+ async connect(retryInterval = 1e3) {
105
107
  return new Promise((resolve, reject) => {
106
108
  this.ws = new import_ws.default(this.url);
107
- this.ws.on("open", resolve);
108
- this.ws.on("error", reject);
109
+ this.ws.on("open", () => {
110
+ console.log("WebSocket conectado.");
111
+ this.isClosedManually = false;
112
+ resolve();
113
+ });
114
+ this.ws.on("error", (err) => {
115
+ console.error("Erro na conex\xE3o WebSocket:", err);
116
+ if (!this.isClosedManually) {
117
+ setTimeout(() => this.reconnect(retryInterval), retryInterval);
118
+ }
119
+ reject(err);
120
+ });
121
+ this.ws.on("close", (code, reason) => {
122
+ console.warn(`WebSocket desconectado: ${code} - ${reason}`);
123
+ if (!this.isClosedManually) {
124
+ setTimeout(() => this.reconnect(retryInterval), retryInterval);
125
+ }
126
+ });
109
127
  });
110
128
  }
129
+ reconnect(retryInterval) {
130
+ console.log("Tentando reconectar ao WebSocket...");
131
+ this.connect(retryInterval).catch((err) => {
132
+ console.error("Erro ao tentar reconectar:", err);
133
+ });
134
+ }
135
+ isConnected() {
136
+ return this.ws?.readyState === import_ws.default.OPEN;
137
+ }
111
138
  on(event, callback) {
112
- if (!this.ws) throw new Error("WebSocket not initialized.");
139
+ if (!this.ws || this.ws.readyState !== import_ws.default.OPEN) {
140
+ throw new Error("WebSocket n\xE3o est\xE1 conectado.");
141
+ }
113
142
  this.ws.on(event, callback);
114
143
  }
144
+ send(data) {
145
+ if (!this.ws || this.ws.readyState !== import_ws.default.OPEN) {
146
+ throw new Error("WebSocket n\xE3o est\xE1 conectado.");
147
+ }
148
+ this.ws.send(data, (err) => {
149
+ if (err) {
150
+ console.error("Erro ao enviar dados pelo WebSocket:", err);
151
+ }
152
+ });
153
+ }
115
154
  close() {
116
- if (this.ws) this.ws.close();
155
+ if (this.ws) {
156
+ this.isClosedManually = true;
157
+ this.ws.close();
158
+ console.log("WebSocket fechado manualmente.");
159
+ }
117
160
  }
118
161
  };
119
162
 
120
163
  // src/ari-client/ariClient.ts
121
164
  var AriClient = class {
122
165
  // Adicionado
166
+ /**
167
+ * Initializes a new instance of the AriClient class.
168
+ *
169
+ * This constructor sets up the necessary configurations for connecting to an Asterisk ARI server,
170
+ * including WebSocket and HTTP connections. It also initializes the channels resource.
171
+ *
172
+ * @param config - The configuration object for the ARI client.
173
+ * @param config.host - The hostname or IP address of the Asterisk server.
174
+ * @param config.port - The port number on which the Asterisk ARI is listening.
175
+ * @param config.username - The username for authentication with the Asterisk ARI.
176
+ * @param config.password - The password for authentication with the Asterisk ARI.
177
+ * @param config.secure - Optional. If true, uses secure protocols (WSS/HTTPS). Defaults to false.
178
+ */
123
179
  constructor(config) {
124
180
  this.config = config;
125
181
  const protocol = config.secure ? "wss" : "ws";
@@ -127,8 +183,9 @@ var AriClient = class {
127
183
  const encodedUsername = encodeURIComponent(config.username);
128
184
  const encodedPassword = encodeURIComponent(config.password);
129
185
  const normalizedHost = config.host.replace(/^https?:\/\//, "");
130
- const wsUrl = `${protocol}://${encodedUsername}:${encodedPassword}@${normalizedHost}:${config.port}/ari/events`;
186
+ const wsUrl = `${protocol}://${encodedUsername}:${encodedPassword}@${normalizedHost}:${config.port}/ari/events?app=${config.app}`;
131
187
  const baseUrl = `${httpProtocol}://${normalizedHost}:${config.port}/ari`;
188
+ console.log({ wsUrl, baseUrl });
132
189
  this.wsClient = new WebSocketClient(wsUrl);
133
190
  this.baseClient = new BaseClient(baseUrl, config.username, config.password);
134
191
  this.channels = new Channels(this.baseClient);
@@ -136,18 +193,80 @@ var AriClient = class {
136
193
  wsClient;
137
194
  baseClient;
138
195
  channels;
196
+ /**
197
+ * Conecta ao WebSocket do ARI.
198
+ * @returns {Promise<void>} Retorna uma promise resolvida ao conectar com sucesso.
199
+ */
139
200
  async connectWebSocket() {
140
- await this.wsClient.connect();
201
+ try {
202
+ await this.wsClient.connect();
203
+ console.log("WebSocket conectado com sucesso!");
204
+ } catch (err) {
205
+ console.error("Erro ao conectar ao WebSocket:", err);
206
+ throw err;
207
+ }
208
+ }
209
+ /**
210
+ * Checks if the WebSocket connection is currently active.
211
+ *
212
+ * This method provides a way to determine the current state of the WebSocket connection
213
+ * to the Asterisk ARI server.
214
+ *
215
+ * @returns {boolean} Returns true if the WebSocket is connected, false otherwise.
216
+ */
217
+ isWebSocketConnected() {
218
+ return this.wsClient.isConnected();
141
219
  }
220
+ /**
221
+ * Registers a callback function for a specific WebSocket event.
222
+ *
223
+ * This method allows you to attach event listeners to WebSocket events
224
+ * from the Asterisk ARI server. When the specified event occurs, the
225
+ * provided callback function will be executed.
226
+ *
227
+ * @param event - The name of the WebSocket event to listen for.
228
+ * @param callback - The function to be called when the event occurs.
229
+ * It receives the event data as its parameter.
230
+ * @returns void
231
+ */
142
232
  onWebSocketEvent(event, callback) {
143
233
  this.wsClient.on(event, callback);
144
234
  }
235
+ /**
236
+ * Closes the WebSocket connection to the Asterisk ARI server.
237
+ *
238
+ * This method terminates the existing WebSocket connection, if one is active.
239
+ * It's useful for cleaning up resources when the connection is no longer needed.
240
+ */
145
241
  closeWebSocket() {
146
242
  this.wsClient.close();
147
243
  }
244
+ /**
245
+ * Retrieves a list of all active channels from the Asterisk ARI server.
246
+ *
247
+ * This method makes an asynchronous GET request to the '/channels' endpoint
248
+ * of the Asterisk ARI.
249
+ *
250
+ * @returns {Promise<any>} A promise that resolves with the list of active channels.
251
+ * The exact structure of the returned data depends on the
252
+ * Asterisk ARI specification.
253
+ */
148
254
  async listChannels() {
149
255
  return this.baseClient.get("/channels");
150
256
  }
257
+ /**
258
+ * Initiates a new channel on the Asterisk server.
259
+ *
260
+ * This method makes an asynchronous POST request to the '/channels' endpoint
261
+ * of the Asterisk ARI to create a new channel with the specified parameters.
262
+ *
263
+ * @param {any} data - An object containing the parameters for the new channel.
264
+ * The structure of this object should conform to the
265
+ * Asterisk ARI specification for channel origination.
266
+ * @returns {Promise<any>} A promise that resolves with the response from the
267
+ * Asterisk server, typically containing details of
268
+ * the newly created channel.
269
+ */
151
270
  async originateChannel(data) {
152
271
  return this.baseClient.post("/channels", data);
153
272
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts", "../../src/ari-client/baseClient.ts", "../../src/ari-client/resources/channels.ts", "../../src/ari-client/websocketClient.ts", "../../src/ari-client/ariClient.ts"],
4
- "sourcesContent": ["// Exporta a classe principal AriClient\nexport { AriClient } from \"./ari-client/ariClient\";\n\n// Exporta as classes dos recursos, caso o usu\u00E1rio precise us\u00E1-las diretamente\nexport { Channels } from \"./ari-client/resources/channels\";\n\n// Exporta interfaces importantes para tipagem\nexport type { AriClientConfig } from \"./ari-client/ariClient\";\nexport type { Channel } from \"./ari-client/interfaces/channels.types\";\n", "import axios, { type AxiosInstance } from \"axios\";\n\nexport class BaseClient {\n private client: AxiosInstance;\n\n constructor(baseUrl: string, username: string, password: string) {\n this.client = axios.create({\n baseURL: baseUrl,\n auth: { username, password },\n });\n }\n\n async get<T>(path: string): Promise<T> {\n const response = await this.client.get<T>(path);\n return response.data;\n }\n\n async post<T>(path: string, data?: unknown): Promise<T> {\n const response = await this.client.post<T>(path, data);\n return response.data;\n }\n}\n", "import type { BaseClient } from \"../baseClient\";\nimport type { Channel, OriginateRequest } from \"../interfaces/channels.types\";\n\nexport class Channels {\n constructor(private client: BaseClient) {}\n\n // Lista todos os canais ativos\n async list(): Promise<Channel[]> {\n return this.client.get<Channel[]>(\"/channels\");\n }\n\n // Cria um novo canal\n async originate(data: OriginateRequest): Promise<Channel> {\n return this.client.post<Channel>(\"/channels\", data);\n }\n\n // Obt\u00E9m detalhes de um canal espec\u00EDfico\n async getDetails(channelId: string): Promise<Channel> {\n return this.client.get<Channel>(`/channels/${channelId}`);\n }\n\n // Desliga (hangup) um canal\n async hangup(channelId: string): Promise<void> {\n return this.client.post<void>(`/channels/${channelId}/hangup`);\n }\n\n // Continua no dialplan\n async continueDialplan(\n channelId: string,\n context?: string,\n extension?: string,\n priority?: number,\n label?: string,\n ): Promise<void> {\n return this.client.post<void>(`/channels/${channelId}/continue`, {\n context,\n extension,\n priority,\n label,\n });\n }\n\n // Move o canal para outra aplica\u00E7\u00E3o Stasis\n async moveToApplication(\n channelId: string,\n app: string,\n appArgs?: string,\n ): Promise<void> {\n return this.client.post<void>(`/channels/${channelId}/move`, {\n app,\n appArgs,\n });\n }\n}\n", "import WebSocket from \"ws\";\n\nexport class WebSocketClient {\n private ws: WebSocket | null = null;\n\n constructor(private url: string) {}\n\n async connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.ws = new WebSocket(this.url);\n this.ws.on(\"open\", resolve);\n this.ws.on(\"error\", reject);\n });\n }\n\n on(event: string, callback: (data: any) => void): void {\n if (!this.ws) throw new Error(\"WebSocket not initialized.\");\n this.ws.on(event, callback);\n }\n\n close(): void {\n if (this.ws) this.ws.close();\n }\n}\n", "import { BaseClient } from \"./baseClient.js\";\nimport { Channels } from \"./resources/channels\";\nimport { WebSocketClient } from \"./websocketClient.js\";\n\nexport interface AriClientConfig {\n host: string;\n port: number;\n username: string;\n password: string;\n secure?: boolean;\n}\n\nexport class AriClient {\n private wsClient: WebSocketClient;\n private readonly baseClient: BaseClient;\n\n public channels: Channels; // Adicionado\n\n constructor(private config: AriClientConfig) {\n // Determina o protocolo com base na seguran\u00E7a\n const protocol = config.secure ? \"wss\" : \"ws\";\n const httpProtocol = config.secure ? \"https\" : \"http\";\n\n // Codifica credenciais para uso seguro no URL\n const encodedUsername = encodeURIComponent(config.username);\n const encodedPassword = encodeURIComponent(config.password);\n\n // Remove o protocolo do host, caso esteja presente\n const normalizedHost = config.host.replace(/^https?:\\/\\//, \"\");\n\n // Constr\u00F3i os URLs\n const wsUrl = `${protocol}://${encodedUsername}:${encodedPassword}@${normalizedHost}:${config.port}/ari/events`;\n const baseUrl = `${httpProtocol}://${normalizedHost}:${config.port}/ari`;\n\n // Inicializa os clientes WebSocket e HTTP\n this.wsClient = new WebSocketClient(wsUrl);\n this.baseClient = new BaseClient(baseUrl, config.username, config.password);\n\n // Inicializa os recursos do cliente\n this.channels = new Channels(this.baseClient);\n }\n\n async connectWebSocket(): Promise<void> {\n await this.wsClient.connect();\n }\n\n onWebSocketEvent(event: string, callback: (data: any) => void): void {\n this.wsClient.on(event, callback);\n }\n\n closeWebSocket(): void {\n this.wsClient.close();\n }\n\n async listChannels() {\n return this.baseClient.get(\"/channels\");\n }\n\n async originateChannel(data: any) {\n return this.baseClient.post(\"/channels\", data);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Exporta a classe principal AriClient\nexport { AriClient } from \"./ari-client/ariClient.js\";\n\n// Exporta as classes dos recursos, caso o usu\u00E1rio precise us\u00E1-las diretamente\nexport { Channels } from \"./ari-client/resources/channels.js\";\n\n// Exporta interfaces importantes para tipagem\nexport type { AriClientConfig } from \"./ari-client/interfaces/requests.js\";\nexport type { Channel } from \"./ari-client/interfaces/channels.types.js\";\n", "import axios, { type AxiosInstance } from \"axios\";\n\nexport class BaseClient {\n private client: AxiosInstance;\n\n constructor(baseUrl: string, username: string, password: string) {\n this.client = axios.create({\n baseURL: baseUrl,\n auth: { username, password },\n });\n }\n\n async get<T>(path: string): Promise<T> {\n const response = await this.client.get<T>(path);\n return response.data;\n }\n\n async post<T>(path: string, data?: unknown): Promise<T> {\n const response = await this.client.post<T>(path, data);\n return response.data;\n }\n}\n", "import type { BaseClient } from \"../baseClient.js\";\nimport type {\n Channel,\n OriginateRequest,\n} from \"../interfaces/channels.types.js\";\n\nexport class Channels {\n constructor(private client: BaseClient) {}\n\n // Lista todos os canais ativos\n async list(): Promise<Channel[]> {\n return this.client.get<Channel[]>(\"/channels\");\n }\n\n // Cria um novo canal\n async originate(data: OriginateRequest): Promise<Channel> {\n return this.client.post<Channel>(\"/channels\", data);\n }\n\n // Obt\u00E9m detalhes de um canal espec\u00EDfico\n async getDetails(channelId: string): Promise<Channel> {\n return this.client.get<Channel>(`/channels/${channelId}`);\n }\n\n // Desliga (hangup) um canal\n async hangup(channelId: string): Promise<void> {\n return this.client.post<void>(`/channels/${channelId}/hangup`);\n }\n\n // Continua no dialplan\n async continueDialplan(\n channelId: string,\n context?: string,\n extension?: string,\n priority?: number,\n label?: string,\n ): Promise<void> {\n return this.client.post<void>(`/channels/${channelId}/continue`, {\n context,\n extension,\n priority,\n label,\n });\n }\n\n // Move o canal para outra aplica\u00E7\u00E3o Stasis\n async moveToApplication(\n channelId: string,\n app: string,\n appArgs?: string,\n ): Promise<void> {\n return this.client.post<void>(`/channels/${channelId}/move`, {\n app,\n appArgs,\n });\n }\n}\n", "import WebSocket from \"ws\";\n\nexport class WebSocketClient {\n private ws: WebSocket | null = null;\n private isClosedManually = false; // Para evitar reconex\u00F5es autom\u00E1ticas quando fechado manualmente\n\n constructor(private url: string) {}\n\n async connect(retryInterval = 1000): Promise<void> {\n return new Promise((resolve, reject) => {\n this.ws = new WebSocket(this.url);\n\n this.ws.on(\"open\", () => {\n console.log(\"WebSocket conectado.\");\n this.isClosedManually = false;\n resolve();\n });\n\n this.ws.on(\"error\", (err) => {\n console.error(\"Erro na conex\u00E3o WebSocket:\", err);\n if (!this.isClosedManually) {\n setTimeout(() => this.reconnect(retryInterval), retryInterval);\n }\n reject(err);\n });\n\n this.ws.on(\"close\", (code, reason) => {\n console.warn(`WebSocket desconectado: ${code} - ${reason}`);\n if (!this.isClosedManually) {\n setTimeout(() => this.reconnect(retryInterval), retryInterval);\n }\n });\n });\n }\n\n private reconnect(retryInterval: number): void {\n console.log(\"Tentando reconectar ao WebSocket...\");\n this.connect(retryInterval).catch((err) => {\n console.error(\"Erro ao tentar reconectar:\", err);\n });\n }\n\n isConnected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n on(event: string, callback: (data: any) => void): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n throw new Error(\"WebSocket n\u00E3o est\u00E1 conectado.\");\n }\n\n this.ws.on(event, callback);\n }\n\n send(data: any): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n throw new Error(\"WebSocket n\u00E3o est\u00E1 conectado.\");\n }\n\n this.ws.send(data, (err) => {\n if (err) {\n console.error(\"Erro ao enviar dados pelo WebSocket:\", err);\n }\n });\n }\n\n close(): void {\n if (this.ws) {\n this.isClosedManually = true;\n this.ws.close();\n console.log(\"WebSocket fechado manualmente.\");\n }\n }\n}\n", "import { BaseClient } from \"./baseClient.js\";\nimport type { AriClientConfig } from \"./interfaces/requests.js\";\nimport { Channels } from \"./resources/channels.js\";\nimport { WebSocketClient } from \"./websocketClient.js\";\n\nexport class AriClient {\n private wsClient: WebSocketClient;\n private readonly baseClient: BaseClient;\n\n public channels: Channels; // Adicionado\n\n /**\n * Initializes a new instance of the AriClient class.\n *\n * This constructor sets up the necessary configurations for connecting to an Asterisk ARI server,\n * including WebSocket and HTTP connections. It also initializes the channels resource.\n *\n * @param config - The configuration object for the ARI client.\n * @param config.host - The hostname or IP address of the Asterisk server.\n * @param config.port - The port number on which the Asterisk ARI is listening.\n * @param config.username - The username for authentication with the Asterisk ARI.\n * @param config.password - The password for authentication with the Asterisk ARI.\n * @param config.secure - Optional. If true, uses secure protocols (WSS/HTTPS). Defaults to false.\n */\n constructor(private config: AriClientConfig) {\n // Determina o protocolo com base na seguran\u00E7a\n const protocol = config.secure ? \"wss\" : \"ws\";\n const httpProtocol = config.secure ? \"https\" : \"http\";\n\n // Codifica credenciais para uso seguro no URL\n const encodedUsername = encodeURIComponent(config.username);\n const encodedPassword = encodeURIComponent(config.password);\n\n // Remove o protocolo do host, caso esteja presente\n const normalizedHost = config.host.replace(/^https?:\\/\\//, \"\");\n\n // Constr\u00F3i os URLs\n const wsUrl = `${protocol}://${encodedUsername}:${encodedPassword}@${normalizedHost}:${config.port}/ari/events?app=${config.app}`;\n\n const baseUrl = `${httpProtocol}://${normalizedHost}:${config.port}/ari`;\n\n console.log({ wsUrl, baseUrl });\n\n // Inicializa os clientes WebSocket e HTTP\n this.wsClient = new WebSocketClient(wsUrl);\n this.baseClient = new BaseClient(baseUrl, config.username, config.password);\n\n // Inicializa os recursos do cliente\n this.channels = new Channels(this.baseClient);\n }\n\n /**\n * Conecta ao WebSocket do ARI.\n * @returns {Promise<void>} Retorna uma promise resolvida ao conectar com sucesso.\n */\n async connectWebSocket(): Promise<void> {\n try {\n await this.wsClient.connect();\n console.log(\"WebSocket conectado com sucesso!\");\n } catch (err) {\n console.error(\"Erro ao conectar ao WebSocket:\", err);\n throw err;\n }\n }\n\n /**\n * Checks if the WebSocket connection is currently active.\n *\n * This method provides a way to determine the current state of the WebSocket connection\n * to the Asterisk ARI server.\n *\n * @returns {boolean} Returns true if the WebSocket is connected, false otherwise.\n */\n isWebSocketConnected(): boolean {\n return this.wsClient.isConnected();\n }\n\n /**\n * Registers a callback function for a specific WebSocket event.\n *\n * This method allows you to attach event listeners to WebSocket events\n * from the Asterisk ARI server. When the specified event occurs, the\n * provided callback function will be executed.\n *\n * @param event - The name of the WebSocket event to listen for.\n * @param callback - The function to be called when the event occurs.\n * It receives the event data as its parameter.\n * @returns void\n */\n onWebSocketEvent(event: string, callback: (data: any) => void): void {\n this.wsClient.on(event, callback);\n }\n\n /**\n * Closes the WebSocket connection to the Asterisk ARI server.\n *\n * This method terminates the existing WebSocket connection, if one is active.\n * It's useful for cleaning up resources when the connection is no longer needed.\n */\n closeWebSocket(): void {\n this.wsClient.close();\n }\n\n /**\n * Retrieves a list of all active channels from the Asterisk ARI server.\n *\n * This method makes an asynchronous GET request to the '/channels' endpoint\n * of the Asterisk ARI.\n *\n * @returns {Promise<any>} A promise that resolves with the list of active channels.\n * The exact structure of the returned data depends on the\n * Asterisk ARI specification.\n */\n async listChannels() {\n return this.baseClient.get(\"/channels\");\n }\n\n /**\n * Initiates a new channel on the Asterisk server.\n *\n * This method makes an asynchronous POST request to the '/channels' endpoint\n * of the Asterisk ARI to create a new channel with the specified parameters.\n *\n * @param {any} data - An object containing the parameters for the new channel.\n * The structure of this object should conform to the\n * Asterisk ARI specification for channel origination.\n * @returns {Promise<any>} A promise that resolves with the response from the\n * Asterisk server, typically containing details of\n * the newly created channel.\n */\n async originateChannel(data: any) {\n return this.baseClient.post(\"/channels\", data);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["axios", "WebSocket"]
7
7
  }
package/dist/esm/index.js CHANGED
@@ -60,29 +60,85 @@ var Channels = class {
60
60
  // src/ari-client/websocketClient.ts
61
61
  import WebSocket from "ws";
62
62
  var WebSocketClient = class {
63
+ // Para evitar reconexões automáticas quando fechado manualmente
63
64
  constructor(url) {
64
65
  this.url = url;
65
66
  }
66
67
  ws = null;
67
- async connect() {
68
+ isClosedManually = false;
69
+ async connect(retryInterval = 1e3) {
68
70
  return new Promise((resolve, reject) => {
69
71
  this.ws = new WebSocket(this.url);
70
- this.ws.on("open", resolve);
71
- this.ws.on("error", reject);
72
+ this.ws.on("open", () => {
73
+ console.log("WebSocket conectado.");
74
+ this.isClosedManually = false;
75
+ resolve();
76
+ });
77
+ this.ws.on("error", (err) => {
78
+ console.error("Erro na conex\xE3o WebSocket:", err);
79
+ if (!this.isClosedManually) {
80
+ setTimeout(() => this.reconnect(retryInterval), retryInterval);
81
+ }
82
+ reject(err);
83
+ });
84
+ this.ws.on("close", (code, reason) => {
85
+ console.warn(`WebSocket desconectado: ${code} - ${reason}`);
86
+ if (!this.isClosedManually) {
87
+ setTimeout(() => this.reconnect(retryInterval), retryInterval);
88
+ }
89
+ });
72
90
  });
73
91
  }
92
+ reconnect(retryInterval) {
93
+ console.log("Tentando reconectar ao WebSocket...");
94
+ this.connect(retryInterval).catch((err) => {
95
+ console.error("Erro ao tentar reconectar:", err);
96
+ });
97
+ }
98
+ isConnected() {
99
+ return this.ws?.readyState === WebSocket.OPEN;
100
+ }
74
101
  on(event, callback) {
75
- if (!this.ws) throw new Error("WebSocket not initialized.");
102
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
103
+ throw new Error("WebSocket n\xE3o est\xE1 conectado.");
104
+ }
76
105
  this.ws.on(event, callback);
77
106
  }
107
+ send(data) {
108
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
109
+ throw new Error("WebSocket n\xE3o est\xE1 conectado.");
110
+ }
111
+ this.ws.send(data, (err) => {
112
+ if (err) {
113
+ console.error("Erro ao enviar dados pelo WebSocket:", err);
114
+ }
115
+ });
116
+ }
78
117
  close() {
79
- if (this.ws) this.ws.close();
118
+ if (this.ws) {
119
+ this.isClosedManually = true;
120
+ this.ws.close();
121
+ console.log("WebSocket fechado manualmente.");
122
+ }
80
123
  }
81
124
  };
82
125
 
83
126
  // src/ari-client/ariClient.ts
84
127
  var AriClient = class {
85
128
  // Adicionado
129
+ /**
130
+ * Initializes a new instance of the AriClient class.
131
+ *
132
+ * This constructor sets up the necessary configurations for connecting to an Asterisk ARI server,
133
+ * including WebSocket and HTTP connections. It also initializes the channels resource.
134
+ *
135
+ * @param config - The configuration object for the ARI client.
136
+ * @param config.host - The hostname or IP address of the Asterisk server.
137
+ * @param config.port - The port number on which the Asterisk ARI is listening.
138
+ * @param config.username - The username for authentication with the Asterisk ARI.
139
+ * @param config.password - The password for authentication with the Asterisk ARI.
140
+ * @param config.secure - Optional. If true, uses secure protocols (WSS/HTTPS). Defaults to false.
141
+ */
86
142
  constructor(config) {
87
143
  this.config = config;
88
144
  const protocol = config.secure ? "wss" : "ws";
@@ -90,8 +146,9 @@ var AriClient = class {
90
146
  const encodedUsername = encodeURIComponent(config.username);
91
147
  const encodedPassword = encodeURIComponent(config.password);
92
148
  const normalizedHost = config.host.replace(/^https?:\/\//, "");
93
- const wsUrl = `${protocol}://${encodedUsername}:${encodedPassword}@${normalizedHost}:${config.port}/ari/events`;
149
+ const wsUrl = `${protocol}://${encodedUsername}:${encodedPassword}@${normalizedHost}:${config.port}/ari/events?app=${config.app}`;
94
150
  const baseUrl = `${httpProtocol}://${normalizedHost}:${config.port}/ari`;
151
+ console.log({ wsUrl, baseUrl });
95
152
  this.wsClient = new WebSocketClient(wsUrl);
96
153
  this.baseClient = new BaseClient(baseUrl, config.username, config.password);
97
154
  this.channels = new Channels(this.baseClient);
@@ -99,18 +156,80 @@ var AriClient = class {
99
156
  wsClient;
100
157
  baseClient;
101
158
  channels;
159
+ /**
160
+ * Conecta ao WebSocket do ARI.
161
+ * @returns {Promise<void>} Retorna uma promise resolvida ao conectar com sucesso.
162
+ */
102
163
  async connectWebSocket() {
103
- await this.wsClient.connect();
104
- }
164
+ try {
165
+ await this.wsClient.connect();
166
+ console.log("WebSocket conectado com sucesso!");
167
+ } catch (err) {
168
+ console.error("Erro ao conectar ao WebSocket:", err);
169
+ throw err;
170
+ }
171
+ }
172
+ /**
173
+ * Checks if the WebSocket connection is currently active.
174
+ *
175
+ * This method provides a way to determine the current state of the WebSocket connection
176
+ * to the Asterisk ARI server.
177
+ *
178
+ * @returns {boolean} Returns true if the WebSocket is connected, false otherwise.
179
+ */
180
+ isWebSocketConnected() {
181
+ return this.wsClient.isConnected();
182
+ }
183
+ /**
184
+ * Registers a callback function for a specific WebSocket event.
185
+ *
186
+ * This method allows you to attach event listeners to WebSocket events
187
+ * from the Asterisk ARI server. When the specified event occurs, the
188
+ * provided callback function will be executed.
189
+ *
190
+ * @param event - The name of the WebSocket event to listen for.
191
+ * @param callback - The function to be called when the event occurs.
192
+ * It receives the event data as its parameter.
193
+ * @returns void
194
+ */
105
195
  onWebSocketEvent(event, callback) {
106
196
  this.wsClient.on(event, callback);
107
197
  }
198
+ /**
199
+ * Closes the WebSocket connection to the Asterisk ARI server.
200
+ *
201
+ * This method terminates the existing WebSocket connection, if one is active.
202
+ * It's useful for cleaning up resources when the connection is no longer needed.
203
+ */
108
204
  closeWebSocket() {
109
205
  this.wsClient.close();
110
206
  }
207
+ /**
208
+ * Retrieves a list of all active channels from the Asterisk ARI server.
209
+ *
210
+ * This method makes an asynchronous GET request to the '/channels' endpoint
211
+ * of the Asterisk ARI.
212
+ *
213
+ * @returns {Promise<any>} A promise that resolves with the list of active channels.
214
+ * The exact structure of the returned data depends on the
215
+ * Asterisk ARI specification.
216
+ */
111
217
  async listChannels() {
112
218
  return this.baseClient.get("/channels");
113
219
  }
220
+ /**
221
+ * Initiates a new channel on the Asterisk server.
222
+ *
223
+ * This method makes an asynchronous POST request to the '/channels' endpoint
224
+ * of the Asterisk ARI to create a new channel with the specified parameters.
225
+ *
226
+ * @param {any} data - An object containing the parameters for the new channel.
227
+ * The structure of this object should conform to the
228
+ * Asterisk ARI specification for channel origination.
229
+ * @returns {Promise<any>} A promise that resolves with the response from the
230
+ * Asterisk server, typically containing details of
231
+ * the newly created channel.
232
+ */
114
233
  async originateChannel(data) {
115
234
  return this.baseClient.post("/channels", data);
116
235
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/ari-client/baseClient.ts", "../../src/ari-client/resources/channels.ts", "../../src/ari-client/websocketClient.ts", "../../src/ari-client/ariClient.ts"],
4
- "sourcesContent": ["import axios, { type AxiosInstance } from \"axios\";\n\nexport class BaseClient {\n private client: AxiosInstance;\n\n constructor(baseUrl: string, username: string, password: string) {\n this.client = axios.create({\n baseURL: baseUrl,\n auth: { username, password },\n });\n }\n\n async get<T>(path: string): Promise<T> {\n const response = await this.client.get<T>(path);\n return response.data;\n }\n\n async post<T>(path: string, data?: unknown): Promise<T> {\n const response = await this.client.post<T>(path, data);\n return response.data;\n }\n}\n", "import type { BaseClient } from \"../baseClient\";\nimport type { Channel, OriginateRequest } from \"../interfaces/channels.types\";\n\nexport class Channels {\n constructor(private client: BaseClient) {}\n\n // Lista todos os canais ativos\n async list(): Promise<Channel[]> {\n return this.client.get<Channel[]>(\"/channels\");\n }\n\n // Cria um novo canal\n async originate(data: OriginateRequest): Promise<Channel> {\n return this.client.post<Channel>(\"/channels\", data);\n }\n\n // Obt\u00E9m detalhes de um canal espec\u00EDfico\n async getDetails(channelId: string): Promise<Channel> {\n return this.client.get<Channel>(`/channels/${channelId}`);\n }\n\n // Desliga (hangup) um canal\n async hangup(channelId: string): Promise<void> {\n return this.client.post<void>(`/channels/${channelId}/hangup`);\n }\n\n // Continua no dialplan\n async continueDialplan(\n channelId: string,\n context?: string,\n extension?: string,\n priority?: number,\n label?: string,\n ): Promise<void> {\n return this.client.post<void>(`/channels/${channelId}/continue`, {\n context,\n extension,\n priority,\n label,\n });\n }\n\n // Move o canal para outra aplica\u00E7\u00E3o Stasis\n async moveToApplication(\n channelId: string,\n app: string,\n appArgs?: string,\n ): Promise<void> {\n return this.client.post<void>(`/channels/${channelId}/move`, {\n app,\n appArgs,\n });\n }\n}\n", "import WebSocket from \"ws\";\n\nexport class WebSocketClient {\n private ws: WebSocket | null = null;\n\n constructor(private url: string) {}\n\n async connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.ws = new WebSocket(this.url);\n this.ws.on(\"open\", resolve);\n this.ws.on(\"error\", reject);\n });\n }\n\n on(event: string, callback: (data: any) => void): void {\n if (!this.ws) throw new Error(\"WebSocket not initialized.\");\n this.ws.on(event, callback);\n }\n\n close(): void {\n if (this.ws) this.ws.close();\n }\n}\n", "import { BaseClient } from \"./baseClient.js\";\nimport { Channels } from \"./resources/channels\";\nimport { WebSocketClient } from \"./websocketClient.js\";\n\nexport interface AriClientConfig {\n host: string;\n port: number;\n username: string;\n password: string;\n secure?: boolean;\n}\n\nexport class AriClient {\n private wsClient: WebSocketClient;\n private readonly baseClient: BaseClient;\n\n public channels: Channels; // Adicionado\n\n constructor(private config: AriClientConfig) {\n // Determina o protocolo com base na seguran\u00E7a\n const protocol = config.secure ? \"wss\" : \"ws\";\n const httpProtocol = config.secure ? \"https\" : \"http\";\n\n // Codifica credenciais para uso seguro no URL\n const encodedUsername = encodeURIComponent(config.username);\n const encodedPassword = encodeURIComponent(config.password);\n\n // Remove o protocolo do host, caso esteja presente\n const normalizedHost = config.host.replace(/^https?:\\/\\//, \"\");\n\n // Constr\u00F3i os URLs\n const wsUrl = `${protocol}://${encodedUsername}:${encodedPassword}@${normalizedHost}:${config.port}/ari/events`;\n const baseUrl = `${httpProtocol}://${normalizedHost}:${config.port}/ari`;\n\n // Inicializa os clientes WebSocket e HTTP\n this.wsClient = new WebSocketClient(wsUrl);\n this.baseClient = new BaseClient(baseUrl, config.username, config.password);\n\n // Inicializa os recursos do cliente\n this.channels = new Channels(this.baseClient);\n }\n\n async connectWebSocket(): Promise<void> {\n await this.wsClient.connect();\n }\n\n onWebSocketEvent(event: string, callback: (data: any) => void): void {\n this.wsClient.on(event, callback);\n }\n\n closeWebSocket(): void {\n this.wsClient.close();\n }\n\n async listChannels() {\n return this.baseClient.get(\"/channels\");\n }\n\n async originateChannel(data: any) {\n return this.baseClient.post(\"/channels\", data);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import axios, { type AxiosInstance } from \"axios\";\n\nexport class BaseClient {\n private client: AxiosInstance;\n\n constructor(baseUrl: string, username: string, password: string) {\n this.client = axios.create({\n baseURL: baseUrl,\n auth: { username, password },\n });\n }\n\n async get<T>(path: string): Promise<T> {\n const response = await this.client.get<T>(path);\n return response.data;\n }\n\n async post<T>(path: string, data?: unknown): Promise<T> {\n const response = await this.client.post<T>(path, data);\n return response.data;\n }\n}\n", "import type { BaseClient } from \"../baseClient.js\";\nimport type {\n Channel,\n OriginateRequest,\n} from \"../interfaces/channels.types.js\";\n\nexport class Channels {\n constructor(private client: BaseClient) {}\n\n // Lista todos os canais ativos\n async list(): Promise<Channel[]> {\n return this.client.get<Channel[]>(\"/channels\");\n }\n\n // Cria um novo canal\n async originate(data: OriginateRequest): Promise<Channel> {\n return this.client.post<Channel>(\"/channels\", data);\n }\n\n // Obt\u00E9m detalhes de um canal espec\u00EDfico\n async getDetails(channelId: string): Promise<Channel> {\n return this.client.get<Channel>(`/channels/${channelId}`);\n }\n\n // Desliga (hangup) um canal\n async hangup(channelId: string): Promise<void> {\n return this.client.post<void>(`/channels/${channelId}/hangup`);\n }\n\n // Continua no dialplan\n async continueDialplan(\n channelId: string,\n context?: string,\n extension?: string,\n priority?: number,\n label?: string,\n ): Promise<void> {\n return this.client.post<void>(`/channels/${channelId}/continue`, {\n context,\n extension,\n priority,\n label,\n });\n }\n\n // Move o canal para outra aplica\u00E7\u00E3o Stasis\n async moveToApplication(\n channelId: string,\n app: string,\n appArgs?: string,\n ): Promise<void> {\n return this.client.post<void>(`/channels/${channelId}/move`, {\n app,\n appArgs,\n });\n }\n}\n", "import WebSocket from \"ws\";\n\nexport class WebSocketClient {\n private ws: WebSocket | null = null;\n private isClosedManually = false; // Para evitar reconex\u00F5es autom\u00E1ticas quando fechado manualmente\n\n constructor(private url: string) {}\n\n async connect(retryInterval = 1000): Promise<void> {\n return new Promise((resolve, reject) => {\n this.ws = new WebSocket(this.url);\n\n this.ws.on(\"open\", () => {\n console.log(\"WebSocket conectado.\");\n this.isClosedManually = false;\n resolve();\n });\n\n this.ws.on(\"error\", (err) => {\n console.error(\"Erro na conex\u00E3o WebSocket:\", err);\n if (!this.isClosedManually) {\n setTimeout(() => this.reconnect(retryInterval), retryInterval);\n }\n reject(err);\n });\n\n this.ws.on(\"close\", (code, reason) => {\n console.warn(`WebSocket desconectado: ${code} - ${reason}`);\n if (!this.isClosedManually) {\n setTimeout(() => this.reconnect(retryInterval), retryInterval);\n }\n });\n });\n }\n\n private reconnect(retryInterval: number): void {\n console.log(\"Tentando reconectar ao WebSocket...\");\n this.connect(retryInterval).catch((err) => {\n console.error(\"Erro ao tentar reconectar:\", err);\n });\n }\n\n isConnected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n on(event: string, callback: (data: any) => void): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n throw new Error(\"WebSocket n\u00E3o est\u00E1 conectado.\");\n }\n\n this.ws.on(event, callback);\n }\n\n send(data: any): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n throw new Error(\"WebSocket n\u00E3o est\u00E1 conectado.\");\n }\n\n this.ws.send(data, (err) => {\n if (err) {\n console.error(\"Erro ao enviar dados pelo WebSocket:\", err);\n }\n });\n }\n\n close(): void {\n if (this.ws) {\n this.isClosedManually = true;\n this.ws.close();\n console.log(\"WebSocket fechado manualmente.\");\n }\n }\n}\n", "import { BaseClient } from \"./baseClient.js\";\nimport type { AriClientConfig } from \"./interfaces/requests.js\";\nimport { Channels } from \"./resources/channels.js\";\nimport { WebSocketClient } from \"./websocketClient.js\";\n\nexport class AriClient {\n private wsClient: WebSocketClient;\n private readonly baseClient: BaseClient;\n\n public channels: Channels; // Adicionado\n\n /**\n * Initializes a new instance of the AriClient class.\n *\n * This constructor sets up the necessary configurations for connecting to an Asterisk ARI server,\n * including WebSocket and HTTP connections. It also initializes the channels resource.\n *\n * @param config - The configuration object for the ARI client.\n * @param config.host - The hostname or IP address of the Asterisk server.\n * @param config.port - The port number on which the Asterisk ARI is listening.\n * @param config.username - The username for authentication with the Asterisk ARI.\n * @param config.password - The password for authentication with the Asterisk ARI.\n * @param config.secure - Optional. If true, uses secure protocols (WSS/HTTPS). Defaults to false.\n */\n constructor(private config: AriClientConfig) {\n // Determina o protocolo com base na seguran\u00E7a\n const protocol = config.secure ? \"wss\" : \"ws\";\n const httpProtocol = config.secure ? \"https\" : \"http\";\n\n // Codifica credenciais para uso seguro no URL\n const encodedUsername = encodeURIComponent(config.username);\n const encodedPassword = encodeURIComponent(config.password);\n\n // Remove o protocolo do host, caso esteja presente\n const normalizedHost = config.host.replace(/^https?:\\/\\//, \"\");\n\n // Constr\u00F3i os URLs\n const wsUrl = `${protocol}://${encodedUsername}:${encodedPassword}@${normalizedHost}:${config.port}/ari/events?app=${config.app}`;\n\n const baseUrl = `${httpProtocol}://${normalizedHost}:${config.port}/ari`;\n\n console.log({ wsUrl, baseUrl });\n\n // Inicializa os clientes WebSocket e HTTP\n this.wsClient = new WebSocketClient(wsUrl);\n this.baseClient = new BaseClient(baseUrl, config.username, config.password);\n\n // Inicializa os recursos do cliente\n this.channels = new Channels(this.baseClient);\n }\n\n /**\n * Conecta ao WebSocket do ARI.\n * @returns {Promise<void>} Retorna uma promise resolvida ao conectar com sucesso.\n */\n async connectWebSocket(): Promise<void> {\n try {\n await this.wsClient.connect();\n console.log(\"WebSocket conectado com sucesso!\");\n } catch (err) {\n console.error(\"Erro ao conectar ao WebSocket:\", err);\n throw err;\n }\n }\n\n /**\n * Checks if the WebSocket connection is currently active.\n *\n * This method provides a way to determine the current state of the WebSocket connection\n * to the Asterisk ARI server.\n *\n * @returns {boolean} Returns true if the WebSocket is connected, false otherwise.\n */\n isWebSocketConnected(): boolean {\n return this.wsClient.isConnected();\n }\n\n /**\n * Registers a callback function for a specific WebSocket event.\n *\n * This method allows you to attach event listeners to WebSocket events\n * from the Asterisk ARI server. When the specified event occurs, the\n * provided callback function will be executed.\n *\n * @param event - The name of the WebSocket event to listen for.\n * @param callback - The function to be called when the event occurs.\n * It receives the event data as its parameter.\n * @returns void\n */\n onWebSocketEvent(event: string, callback: (data: any) => void): void {\n this.wsClient.on(event, callback);\n }\n\n /**\n * Closes the WebSocket connection to the Asterisk ARI server.\n *\n * This method terminates the existing WebSocket connection, if one is active.\n * It's useful for cleaning up resources when the connection is no longer needed.\n */\n closeWebSocket(): void {\n this.wsClient.close();\n }\n\n /**\n * Retrieves a list of all active channels from the Asterisk ARI server.\n *\n * This method makes an asynchronous GET request to the '/channels' endpoint\n * of the Asterisk ARI.\n *\n * @returns {Promise<any>} A promise that resolves with the list of active channels.\n * The exact structure of the returned data depends on the\n * Asterisk ARI specification.\n */\n async listChannels() {\n return this.baseClient.get(\"/channels\");\n }\n\n /**\n * Initiates a new channel on the Asterisk server.\n *\n * This method makes an asynchronous POST request to the '/channels' endpoint\n * of the Asterisk ARI to create a new channel with the specified parameters.\n *\n * @param {any} data - An object containing the parameters for the new channel.\n * The structure of this object should conform to the\n * Asterisk ARI specification for channel origination.\n * @returns {Promise<any>} A promise that resolves with the response from the\n * Asterisk server, typically containing details of\n * the newly created channel.\n */\n async originateChannel(data: any) {\n return this.baseClient.post(\"/channels\", data);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,21 +1,82 @@
1
- import { Channels } from "./resources/channels";
2
- export interface AriClientConfig {
3
- host: string;
4
- port: number;
5
- username: string;
6
- password: string;
7
- secure?: boolean;
8
- }
1
+ import type { AriClientConfig } from "./interfaces/requests.js";
2
+ import { Channels } from "./resources/channels.js";
9
3
  export declare class AriClient {
10
4
  private config;
11
5
  private wsClient;
12
6
  private readonly baseClient;
13
7
  channels: Channels;
8
+ /**
9
+ * Initializes a new instance of the AriClient class.
10
+ *
11
+ * This constructor sets up the necessary configurations for connecting to an Asterisk ARI server,
12
+ * including WebSocket and HTTP connections. It also initializes the channels resource.
13
+ *
14
+ * @param config - The configuration object for the ARI client.
15
+ * @param config.host - The hostname or IP address of the Asterisk server.
16
+ * @param config.port - The port number on which the Asterisk ARI is listening.
17
+ * @param config.username - The username for authentication with the Asterisk ARI.
18
+ * @param config.password - The password for authentication with the Asterisk ARI.
19
+ * @param config.secure - Optional. If true, uses secure protocols (WSS/HTTPS). Defaults to false.
20
+ */
14
21
  constructor(config: AriClientConfig);
22
+ /**
23
+ * Conecta ao WebSocket do ARI.
24
+ * @returns {Promise<void>} Retorna uma promise resolvida ao conectar com sucesso.
25
+ */
15
26
  connectWebSocket(): Promise<void>;
27
+ /**
28
+ * Checks if the WebSocket connection is currently active.
29
+ *
30
+ * This method provides a way to determine the current state of the WebSocket connection
31
+ * to the Asterisk ARI server.
32
+ *
33
+ * @returns {boolean} Returns true if the WebSocket is connected, false otherwise.
34
+ */
35
+ isWebSocketConnected(): boolean;
36
+ /**
37
+ * Registers a callback function for a specific WebSocket event.
38
+ *
39
+ * This method allows you to attach event listeners to WebSocket events
40
+ * from the Asterisk ARI server. When the specified event occurs, the
41
+ * provided callback function will be executed.
42
+ *
43
+ * @param event - The name of the WebSocket event to listen for.
44
+ * @param callback - The function to be called when the event occurs.
45
+ * It receives the event data as its parameter.
46
+ * @returns void
47
+ */
16
48
  onWebSocketEvent(event: string, callback: (data: any) => void): void;
49
+ /**
50
+ * Closes the WebSocket connection to the Asterisk ARI server.
51
+ *
52
+ * This method terminates the existing WebSocket connection, if one is active.
53
+ * It's useful for cleaning up resources when the connection is no longer needed.
54
+ */
17
55
  closeWebSocket(): void;
56
+ /**
57
+ * Retrieves a list of all active channels from the Asterisk ARI server.
58
+ *
59
+ * This method makes an asynchronous GET request to the '/channels' endpoint
60
+ * of the Asterisk ARI.
61
+ *
62
+ * @returns {Promise<any>} A promise that resolves with the list of active channels.
63
+ * The exact structure of the returned data depends on the
64
+ * Asterisk ARI specification.
65
+ */
18
66
  listChannels(): Promise<unknown>;
67
+ /**
68
+ * Initiates a new channel on the Asterisk server.
69
+ *
70
+ * This method makes an asynchronous POST request to the '/channels' endpoint
71
+ * of the Asterisk ARI to create a new channel with the specified parameters.
72
+ *
73
+ * @param {any} data - An object containing the parameters for the new channel.
74
+ * The structure of this object should conform to the
75
+ * Asterisk ARI specification for channel origination.
76
+ * @returns {Promise<any>} A promise that resolves with the response from the
77
+ * Asterisk server, typically containing details of
78
+ * the newly created channel.
79
+ */
19
80
  originateChannel(data: any): Promise<unknown>;
20
81
  }
21
82
  //# sourceMappingURL=ariClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ariClient.d.ts","sourceRoot":"","sources":["../../../src/ari-client/ariClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGhD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,SAAS;IAMR,OAAO,CAAC,MAAM;IAL1B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IAEjC,QAAQ,EAAE,QAAQ,CAAC;gBAEN,MAAM,EAAE,eAAe;IAwBrC,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvC,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAIpE,cAAc,IAAI,IAAI;IAIhB,YAAY;IAIZ,gBAAgB,CAAC,IAAI,EAAE,GAAG;CAGjC"}
1
+ {"version":3,"file":"ariClient.d.ts","sourceRoot":"","sources":["../../../src/ari-client/ariClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGnD,qBAAa,SAAS;IAmBR,OAAO,CAAC,MAAM;IAlB1B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IAEjC,QAAQ,EAAE,QAAQ,CAAC;IAE1B;;;;;;;;;;;;OAYG;gBACiB,MAAM,EAAE,eAAe;IA2B3C;;;OAGG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAUvC;;;;;;;OAOG;IACH,oBAAoB,IAAI,OAAO;IAI/B;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAIpE;;;;;OAKG;IACH,cAAc,IAAI,IAAI;IAItB;;;;;;;;;OASG;IACG,YAAY;IAIlB;;;;;;;;;;;;OAYG;IACG,gBAAgB,CAAC,IAAI,EAAE,GAAG;CAGjC"}
@@ -4,5 +4,6 @@ export interface AriClientConfig {
4
4
  username: string;
5
5
  password: string;
6
6
  secure?: boolean;
7
+ app: string;
7
8
  }
8
9
  //# sourceMappingURL=requests.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../../../src/ari-client/interfaces/requests.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB"}
1
+ {"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../../../src/ari-client/interfaces/requests.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb"}
@@ -1,5 +1,5 @@
1
- import type { BaseClient } from "../baseClient";
2
- import type { Channel, OriginateRequest } from "../interfaces/channels.types";
1
+ import type { BaseClient } from "../baseClient.js";
2
+ import type { Channel, OriginateRequest } from "../interfaces/channels.types.js";
3
3
  export declare class Channels {
4
4
  private client;
5
5
  constructor(client: BaseClient);
@@ -1 +1 @@
1
- {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../../../src/ari-client/resources/channels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAE9E,qBAAa,QAAQ;IACP,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,UAAU;IAGhC,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAK1B,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAKnD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/C,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IAUV,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;CAMjB"}
1
+ {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../../../src/ari-client/resources/channels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EACV,OAAO,EACP,gBAAgB,EACjB,MAAM,iCAAiC,CAAC;AAEzC,qBAAa,QAAQ;IACP,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,UAAU;IAGhC,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAK1B,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAKnD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/C,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IAUV,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;CAMjB"}
@@ -1,9 +1,13 @@
1
1
  export declare class WebSocketClient {
2
2
  private url;
3
3
  private ws;
4
+ private isClosedManually;
4
5
  constructor(url: string);
5
- connect(): Promise<void>;
6
+ connect(retryInterval?: number): Promise<void>;
7
+ private reconnect;
8
+ isConnected(): boolean;
6
9
  on(event: string, callback: (data: any) => void): void;
10
+ send(data: any): void;
7
11
  close(): void;
8
12
  }
9
13
  //# sourceMappingURL=websocketClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"websocketClient.d.ts","sourceRoot":"","sources":["../../../src/ari-client/websocketClient.ts"],"names":[],"mappings":"AAEA,qBAAa,eAAe;IAGd,OAAO,CAAC,GAAG;IAFvB,OAAO,CAAC,EAAE,CAA0B;gBAEhB,GAAG,EAAE,MAAM;IAEzB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAKtD,KAAK,IAAI,IAAI;CAGd"}
1
+ {"version":3,"file":"websocketClient.d.ts","sourceRoot":"","sources":["../../../src/ari-client/websocketClient.ts"],"names":[],"mappings":"AAEA,qBAAa,eAAe;IAId,OAAO,CAAC,GAAG;IAHvB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,gBAAgB,CAAS;gBAEb,GAAG,EAAE,MAAM;IAEzB,OAAO,CAAC,aAAa,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BlD,OAAO,CAAC,SAAS;IAOjB,WAAW,IAAI,OAAO;IAItB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAQtD,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAYrB,KAAK,IAAI,IAAI;CAOd"}
@@ -1,5 +1,5 @@
1
- export { AriClient } from "./ari-client/ariClient";
2
- export { Channels } from "./ari-client/resources/channels";
3
- export type { AriClientConfig } from "./ari-client/ariClient";
4
- export type { Channel } from "./ari-client/interfaces/channels.types";
1
+ export { AriClient } from "./ari-client/ariClient.js";
2
+ export { Channels } from "./ari-client/resources/channels.js";
3
+ export type { AriClientConfig } from "./ari-client/interfaces/requests.js";
4
+ export type { Channel } from "./ari-client/interfaces/channels.types.js";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGnD,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAG3D,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,YAAY,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAGtD,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAG9D,YAAY,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC3E,YAAY,EAAE,OAAO,EAAE,MAAM,2CAA2C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ipcom/asterisk-ari",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "type": "module",
5
5
  "description": "JavaScript client for Asterisk REST Interface.",
6
6
  "homepage": "https://github.com/fabiotheo/ipcom-asterisk-ari",