@ipcom/asterisk-ari 0.0.101 → 0.0.103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -910,38 +910,41 @@ function isChannelEvent(event, channelId) {
910
910
  // src/ari-client/resources/channels.ts
911
911
  var ChannelInstance = class extends EventEmitter2 {
912
912
  // ID do canal
913
- constructor(client, baseClient, channelId = `channel-${Date.now()}`) {
913
+ constructor(client, baseClient, channelId = `channel-${Date.now()}`, app) {
914
914
  super();
915
915
  this.client = client;
916
916
  this.baseClient = baseClient;
917
917
  this.channelId = channelId;
918
+ this.app = app;
918
919
  this.id = channelId || `channel-${Date.now()}`;
919
920
  const wsClients = this.client.getWebSocketClients();
920
- const wsClient = Array.from(wsClients.values()).find(
921
- (client2) => client2.isConnected()
922
- );
921
+ const wsClient = wsClients.get(this.app);
923
922
  if (!wsClient) {
924
923
  throw new Error(
925
924
  `Nenhum WebSocket conectado dispon\xEDvel para o canal: ${this.id}`
926
925
  );
927
926
  }
928
- try {
929
- wsClient.addScopedMessageListener(this.id, (event) => {
927
+ wsClient.addScopedMessageListener(
928
+ this.id,
929
+ this.app,
930
+ (event) => {
930
931
  if (isChannelEvent(event, this.id)) {
931
932
  const channelEventType = event.type;
932
933
  this.emit(channelEventType, event);
933
934
  }
934
- });
935
- } catch (error) {
936
- console.error(
937
- `Erro ao adicionar listener escopado para canal '${this.id}':`,
938
- error
939
- );
940
- throw error;
941
- }
935
+ }
936
+ );
937
+ this.on("removeListener", (eventName) => {
938
+ if (this.eventNames().length === 0 || this.listenerCount(eventName) === 0) {
939
+ wsClient.removeScopedMessageListeners(this.id, this.app);
940
+ console.log(
941
+ `Listeners escopados removidos para canal '${this.id}' no app '${this.app}'.`
942
+ );
943
+ }
944
+ });
942
945
  this.on("removeListener", (eventName) => {
943
946
  if (this.eventNames().length === 0 || this.listenerCount(eventName) === 0) {
944
- wsClient.removeScopedMessageListeners(this.id);
947
+ wsClient.removeScopedMessageListeners(this.id, this.app);
945
948
  console.log(`Listeners escopados removidos para canal '${this.id}'.`);
946
949
  }
947
950
  });
@@ -977,14 +980,14 @@ var ChannelInstance = class extends EventEmitter2 {
977
980
  console.log(`Recebido evento '${event}' para canal '${this.id}'`);
978
981
  this.emit(event, webSocketEvent);
979
982
  callback(webSocketEvent);
980
- wsClient.removeScopedMessageListeners(this.id);
983
+ wsClient.removeScopedMessageListeners(this.id, this.app);
981
984
  console.log(
982
985
  `Listeners escopados para canal '${this.id}' foram removidos.`
983
986
  );
984
987
  }
985
988
  };
986
989
  try {
987
- wsClient.addScopedMessageListener(this.id, globalListener);
990
+ wsClient.addScopedMessageListener(this.id, this.app, globalListener);
988
991
  } catch (error) {
989
992
  console.error(
990
993
  `Erro ao adicionar listener escopado em 'once' para canal '${this.id}':`,
@@ -1188,8 +1191,13 @@ var Channels = class extends EventEmitter2 {
1188
1191
  this.baseClient = baseClient;
1189
1192
  this.client = client;
1190
1193
  }
1191
- Channel(channelId) {
1192
- return new ChannelInstance(this.client, this.baseClient, channelId);
1194
+ Channel({ id, app }) {
1195
+ if (!app) {
1196
+ throw new Error(
1197
+ "O nome do aplicativo (app) \xE9 obrigat\xF3rio para criar um Channel."
1198
+ );
1199
+ }
1200
+ return new ChannelInstance(this.client, this.baseClient, id, app);
1193
1201
  }
1194
1202
  /**
1195
1203
  * Origina um canal físico diretamente, sem uma instância de `ChannelInstance`.
@@ -1419,11 +1427,12 @@ var Endpoints = class {
1419
1427
  import { EventEmitter as EventEmitter3 } from "events";
1420
1428
  var PlaybackInstance = class extends EventEmitter3 {
1421
1429
  // Garantimos que o ID esteja disponível
1422
- constructor(client, baseClient, playbackId = `playback-${Date.now()}`) {
1430
+ constructor(client, baseClient, playbackId = `playback-${Date.now()}`, app) {
1423
1431
  super();
1424
1432
  this.client = client;
1425
1433
  this.baseClient = baseClient;
1426
1434
  this.playbackId = playbackId;
1435
+ this.app = app;
1427
1436
  this.id = playbackId || `playback-${Date.now()}`;
1428
1437
  const wsClients = this.client.getWebSocketClients();
1429
1438
  const wsClient = Array.from(wsClients.values()).find(
@@ -1435,12 +1444,16 @@ var PlaybackInstance = class extends EventEmitter3 {
1435
1444
  );
1436
1445
  }
1437
1446
  try {
1438
- wsClient.addScopedMessageListener(this.id, (event) => {
1439
- if (isPlaybackEvent(event, this.id)) {
1440
- const playbackEventType = event.type;
1441
- this.emit(playbackEventType, event);
1447
+ wsClient.addScopedMessageListener(
1448
+ this.id,
1449
+ this.app,
1450
+ (event) => {
1451
+ if (isPlaybackEvent(event, this.id)) {
1452
+ const playbackEventType = event.type;
1453
+ this.emit(playbackEventType, event);
1454
+ }
1442
1455
  }
1443
- });
1456
+ );
1444
1457
  } catch (error) {
1445
1458
  console.error(
1446
1459
  `Erro ao adicionar listener escopado para playback '${this.id}':`,
@@ -1450,7 +1463,7 @@ var PlaybackInstance = class extends EventEmitter3 {
1450
1463
  }
1451
1464
  this.on("removeListener", (eventName) => {
1452
1465
  if (this.eventNames().length === 0 || this.listenerCount(eventName) === 0) {
1453
- wsClient.removeScopedMessageListeners(this.id);
1466
+ wsClient.removeScopedMessageListeners(this.id, this.app);
1454
1467
  console.log(
1455
1468
  `Listeners escopados removidos para playback '${this.id}'.`
1456
1469
  );
@@ -1491,14 +1504,14 @@ var PlaybackInstance = class extends EventEmitter3 {
1491
1504
  console.log(`Recebido evento '${event}' para playback '${this.id}'`);
1492
1505
  this.emit(event, webSocketEvent);
1493
1506
  callback(webSocketEvent);
1494
- wsClient.removeScopedMessageListeners(this.id);
1507
+ wsClient.removeScopedMessageListeners(this.id, this.app);
1495
1508
  console.log(
1496
1509
  `Listeners escopados para playback '${this.id}' foram removidos.`
1497
1510
  );
1498
1511
  }
1499
1512
  };
1500
1513
  try {
1501
- wsClient.addScopedMessageListener(this.id, globalListener);
1514
+ wsClient.addScopedMessageListener(this.id, this.app, globalListener);
1502
1515
  } catch (error) {
1503
1516
  console.error(
1504
1517
  `Erro ao adicionar listener escopado em 'once' para playback '${this.id}':`,
@@ -1549,7 +1562,22 @@ var PlaybackInstance = class extends EventEmitter3 {
1549
1562
  if (!this.id) {
1550
1563
  throw new Error("Nenhum playback associado para encerrar.");
1551
1564
  }
1552
- await this.baseClient.delete(`/playbacks/${this.id}`);
1565
+ try {
1566
+ await this.baseClient.delete(`/playbacks/${this.id}`);
1567
+ console.log(`Playback '${this.id}' parado com sucesso.`);
1568
+ } catch (error) {
1569
+ if (error.response?.status === 404) {
1570
+ console.warn(
1571
+ `Playback '${this.id}' n\xE3o encontrado para encerrar (404).`
1572
+ );
1573
+ return;
1574
+ }
1575
+ console.error(
1576
+ `Erro ao encerrar o playback '${this.id}':`,
1577
+ error.message || error
1578
+ );
1579
+ throw error;
1580
+ }
1553
1581
  }
1554
1582
  };
1555
1583
  var Playbacks = class extends EventEmitter3 {
@@ -1561,9 +1589,14 @@ var Playbacks = class extends EventEmitter3 {
1561
1589
  /**
1562
1590
  * Inicializa uma nova instância de `PlaybackInstance`.
1563
1591
  */
1564
- Playback(playbackId) {
1565
- const id = playbackId || `playback-${Date.now()}`;
1566
- return new PlaybackInstance(this.client, this.baseClient, id);
1592
+ Playback({ id, app }) {
1593
+ if (!app) {
1594
+ throw new Error(
1595
+ "O nome do aplicativo (app) \xE9 obrigat\xF3rio para criar um Channel."
1596
+ );
1597
+ }
1598
+ const playbackId = id || `playback-${Date.now()}`;
1599
+ return new PlaybackInstance(this.client, this.baseClient, playbackId, app);
1567
1600
  }
1568
1601
  /**
1569
1602
  * Obtém os clientes WebSocket disponíveis.
@@ -1605,7 +1638,22 @@ var Playbacks = class extends EventEmitter3 {
1605
1638
  * @returns A promise that resolves when the playback is successfully stopped.
1606
1639
  */
1607
1640
  async stop(playbackId) {
1608
- await this.baseClient.delete(`/playbacks/${playbackId}`);
1641
+ try {
1642
+ await this.baseClient.delete(`/playbacks/${playbackId}`);
1643
+ console.log(`Playback '${playbackId}' parado com sucesso.`);
1644
+ } catch (error) {
1645
+ if (error.response?.status === 404) {
1646
+ console.warn(
1647
+ `Playback '${playbackId}' n\xE3o encontrado para encerrar (404).`
1648
+ );
1649
+ return;
1650
+ }
1651
+ console.error(
1652
+ `Erro ao encerrar o playback '${playbackId}':`,
1653
+ error.message || error
1654
+ );
1655
+ throw error;
1656
+ }
1609
1657
  }
1610
1658
  /**
1611
1659
  * Registers a listener for playback events.
@@ -1811,28 +1859,36 @@ var WebSocketClient = class extends EventEmitter4 {
1811
1859
  /**
1812
1860
  * Adiciona um listener escopado ao evento "message".
1813
1861
  * @param instanceId - Identificador único da instância que está registrando o listener.
1862
+ * @param app
1814
1863
  * @param callback - Função de callback para o evento.
1815
1864
  */
1816
- addScopedMessageListener(instanceId, callback) {
1817
- if (this.scopedListeners.has(instanceId)) {
1865
+ addScopedMessageListener(instanceId, app, callback) {
1866
+ const key = `${app}:${instanceId}`;
1867
+ if (this.scopedListeners.has(key)) {
1818
1868
  console.warn(
1819
- `Listener escopado para a inst\xE2ncia '${instanceId}' j\xE1 existe. Ignorando duplica\xE7\xE3o.`
1869
+ `Listener escopado para a inst\xE2ncia '${key}' j\xE1 existe. Ignorando.`
1820
1870
  );
1821
1871
  return;
1822
1872
  }
1823
1873
  const scopedListener = (data) => {
1824
- if (data.type.startsWith("Channel") && "channel" in data && data.channel?.id === instanceId || data.type.startsWith("Playback") && "playbackId" in data && data.playbackId === instanceId) {
1825
- console.log(data);
1826
- console.log(
1827
- `Listener escopado para a inst\xE2ncia '${instanceId}' ativado.`
1874
+ try {
1875
+ if (data.application === app && (data.type.startsWith("Channel") && "channel" in data && data.channel?.id === instanceId || data.type.startsWith("Playback") && "playbackId" in data && data.playbackId === instanceId)) {
1876
+ console.log(
1877
+ `Listener escopado ativado para inst\xE2ncia '${instanceId}' no app '${app}'.`
1878
+ );
1879
+ callback(data);
1880
+ }
1881
+ } catch (error) {
1882
+ console.error(
1883
+ `Erro no listener escopado para inst\xE2ncia '${instanceId}' no app '${app}':`,
1884
+ error
1828
1885
  );
1829
- callback(data);
1830
1886
  }
1831
1887
  };
1832
- this.scopedListeners.set(instanceId, scopedListener);
1888
+ this.scopedListeners.set(key, scopedListener);
1833
1889
  this.on("message", scopedListener);
1834
1890
  console.log(
1835
- `Listener escopado adicionado para a inst\xE2ncia '${instanceId}'. Total de listeners: ${this.listenerCount(
1891
+ `Listener escopado adicionado para a inst\xE2ncia '${instanceId}' no app '${app}'. Total de listeners: ${this.listenerCount(
1836
1892
  "message"
1837
1893
  )}`
1838
1894
  );
@@ -1840,23 +1896,25 @@ var WebSocketClient = class extends EventEmitter4 {
1840
1896
  /**
1841
1897
  * Remove todos os listeners associados a uma instância específica.
1842
1898
  * @param instanceId - Identificador da instância cujos listeners serão removidos.
1899
+ * @param app
1843
1900
  */
1844
- removeScopedMessageListeners(instanceId) {
1845
- if (!this.scopedListeners.has(instanceId)) {
1846
- console.warn(
1847
- `Nenhum listener encontrado para a inst\xE2ncia '${instanceId}'.`
1848
- );
1901
+ removeScopedMessageListeners(instanceId, app) {
1902
+ const key = `${app}:${instanceId}`;
1903
+ if (!this.scopedListeners.has(key)) {
1904
+ console.warn(`Nenhum listener encontrado para a inst\xE2ncia '${key}'.`);
1849
1905
  return;
1850
1906
  }
1851
- const scopedListener = this.scopedListeners.get(instanceId);
1907
+ const scopedListener = this.scopedListeners.get(key);
1852
1908
  if (scopedListener) {
1853
1909
  this.off("message", scopedListener);
1854
- this.scopedListeners.delete(instanceId);
1910
+ this.scopedListeners.delete(key);
1855
1911
  console.log(
1856
- `Listeners removidos para a inst\xE2ncia '${instanceId}'. Total de listeners restantes: ${this.listenerCount(
1912
+ `Listeners removidos para a inst\xE2ncia '${key}'. Total de listeners restantes: ${this.listenerCount(
1857
1913
  "message"
1858
1914
  )}`
1859
1915
  );
1916
+ } else {
1917
+ console.warn(`Listener j\xE1 foi removido para a inst\xE2ncia '${key}'.`);
1860
1918
  }
1861
1919
  }
1862
1920
  /**
@@ -1866,13 +1924,14 @@ var WebSocketClient = class extends EventEmitter4 {
1866
1924
  handleMessage(rawData) {
1867
1925
  try {
1868
1926
  const decodedData = JSON.parse(rawData.toString());
1869
- if (decodedData?.type) {
1870
- this.emit(decodedData.type, decodedData);
1871
- if (this.listenerCount("message") > 0) {
1872
- this.emit("message", decodedData);
1873
- }
1927
+ if (decodedData?.type && decodedData?.application) {
1928
+ this.emit(decodedData.application, decodedData);
1929
+ this.emit("message", decodedData);
1874
1930
  } else {
1875
- console.warn("Mensagem recebida sem tipo:", decodedData);
1931
+ console.warn(
1932
+ "Mensagem recebida sem tipo ou aplica\xE7\xE3o v\xE1lida:",
1933
+ decodedData
1934
+ );
1876
1935
  }
1877
1936
  } catch (err) {
1878
1937
  console.error("Erro ao decodificar mensagem do WebSocket:", err);
@@ -1982,14 +2041,18 @@ var AriClient = class {
1982
2041
  * Registra listeners globais para eventos de WebSocket.
1983
2042
  */
1984
2043
  on(eventType, callback, app) {
2044
+ if (!app) {
2045
+ throw new Error(
2046
+ "O nome do app \xE9 obrigat\xF3rio para registrar um listener de evento."
2047
+ );
2048
+ }
1985
2049
  console.log(
1986
- app ? `Registrando listener para evento '${eventType}' no app '${app}'` : `Registrando listener global para evento: '${eventType}'`
2050
+ `Registrando listener para evento '${eventType}' no app '${app}'.`
1987
2051
  );
1988
- console.log("********************************************** ", app);
1989
- const callbackKey = app ? `${eventType}-${app}` : eventType;
2052
+ const callbackKey = `${eventType}-${app}`;
1990
2053
  if (this.eventListeners.has(callbackKey)) {
1991
2054
  console.log(
1992
- `Listener para evento '${eventType}' j\xE1 est\xE1 registrado${app ? ` no app '${app}'` : " globalmente"}. Ignorando duplicata.`
2055
+ `Listener para evento '${eventType}' j\xE1 est\xE1 registrado no app '${app}'. Ignorando duplicata.`
1993
2056
  );
1994
2057
  return;
1995
2058
  }
@@ -1998,7 +2061,7 @@ var AriClient = class {
1998
2061
  const channelId = event.channel.id;
1999
2062
  if (channelId) {
2000
2063
  if (!this.channelInstances.has(channelId)) {
2001
- const channelInstance = this.createChannelInstance(channelId);
2064
+ const channelInstance = this.createChannelInstance(channelId, app);
2002
2065
  this.channelInstances.set(channelId, channelInstance);
2003
2066
  }
2004
2067
  event.instanceChannel = this.channelInstances.get(channelId);
@@ -2007,19 +2070,15 @@ var AriClient = class {
2007
2070
  }
2008
2071
  callback(event);
2009
2072
  };
2010
- if (app) {
2011
- const wsClient = this.wsClients.get(app);
2012
- if (wsClient) {
2013
- wsClient.on(eventType, wrappedCallback);
2014
- this.eventListeners.set(callbackKey, wrappedCallback);
2015
- } else {
2016
- console.warn(`WebSocket para o app '${app}' n\xE3o est\xE1 conectado.`);
2017
- }
2018
- } else {
2019
- for (const [_app, wsClient] of this.wsClients.entries()) {
2020
- wsClient.on(eventType, wrappedCallback);
2021
- }
2073
+ const wsClient = this.wsClients.get(app);
2074
+ if (wsClient) {
2075
+ wsClient.on(eventType, wrappedCallback);
2022
2076
  this.eventListeners.set(callbackKey, wrappedCallback);
2077
+ console.log(
2078
+ `Listener para evento '${eventType}' registrado com sucesso no app '${app}'.`
2079
+ );
2080
+ } else {
2081
+ console.warn(`WebSocket para o app '${app}' n\xE3o est\xE1 conectado.`);
2023
2082
  }
2024
2083
  }
2025
2084
  removeListener(eventType, app) {
@@ -2062,17 +2121,20 @@ var AriClient = class {
2062
2121
  return data?.channel?.id !== void 0;
2063
2122
  }
2064
2123
  // Método para criar uma instância de ChannelInstance
2065
- createChannelInstance(channelId) {
2066
- return this.channels.Channel(channelId);
2124
+ createChannelInstance(channelId, app) {
2125
+ return this.channels.Channel({
2126
+ id: channelId,
2127
+ app
2128
+ });
2067
2129
  }
2068
- handleWebSocketEvent(event) {
2130
+ handleWebSocketEvent(event, app) {
2069
2131
  console.log("Evento recebido no WebSocket:", event.type, event);
2070
2132
  const { type, ...data } = event;
2071
2133
  if (this.hasChannel(data)) {
2072
2134
  const channelId = data.channel.id;
2073
2135
  if (channelId) {
2074
2136
  if (!this.channelInstances.has(channelId)) {
2075
- const channelInstance2 = this.createChannelInstance(channelId);
2137
+ const channelInstance2 = this.createChannelInstance(channelId, app);
2076
2138
  this.channelInstances.set(channelId, channelInstance2);
2077
2139
  }
2078
2140
  const channelInstance = this.channelInstances.get(channelId);
@@ -2110,8 +2172,9 @@ var AriClient = class {
2110
2172
  if (!Array.isArray(apps) || apps.length === 0) {
2111
2173
  throw new Error("\xC9 necess\xE1rio fornecer pelo menos um aplicativo.");
2112
2174
  }
2175
+ const uniqueApps = [...new Set(apps)];
2113
2176
  return Promise.all(
2114
- apps.map(async (app) => {
2177
+ uniqueApps.map(async (app) => {
2115
2178
  if (this.wsClients.has(app)) {
2116
2179
  console.log(`Conex\xE3o WebSocket para '${app}' j\xE1 existe. Ignorando.`);
2117
2180
  return;
@@ -2301,19 +2364,31 @@ var AriClient = class {
2301
2364
  * Inicializa uma nova instância de `ChannelInstance` para manipular canais localmente.
2302
2365
  *
2303
2366
  * @param channelId - O ID do canal, se disponível. Caso contrário, a instância será para um canal ainda não criado.
2367
+ * @param app
2304
2368
  * @returns Uma instância de `ChannelInstance` vinculada ao cliente atual.
2305
2369
  */
2306
- Channel(channelId) {
2307
- return this.channels.Channel(channelId);
2370
+ Channel(channelId, app) {
2371
+ if (!app) {
2372
+ throw new Error(
2373
+ "O nome do aplicativo (app) \xE9 obrigat\xF3rio para criar um Channel."
2374
+ );
2375
+ }
2376
+ return this.channels.Channel({ id: channelId, app });
2308
2377
  }
2309
2378
  /**
2310
2379
  * Inicializa uma nova instância de `PlaybackInstance` para manipular playbacks.
2311
2380
  *
2312
2381
  * @param playbackId - O ID do playback, se disponível. Caso contrário, a instância será para um playback ainda não inicializado.
2382
+ * @param app
2313
2383
  * @returns Uma instância de `PlaybackInstance` vinculada ao cliente atual.
2314
2384
  */
2315
- Playback(playbackId) {
2316
- return this.playbacks.Playback(playbackId);
2385
+ Playback(playbackId, app) {
2386
+ if (!app) {
2387
+ throw new Error(
2388
+ "O nome do aplicativo (app) \xE9 obrigat\xF3rio para criar um Channel."
2389
+ );
2390
+ }
2391
+ return this.playbacks.Playback({ id: playbackId, app });
2317
2392
  }
2318
2393
  };
2319
2394
  export {