@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.
@@ -932,38 +932,41 @@ function isChannelEvent(event, channelId) {
932
932
  // src/ari-client/resources/channels.ts
933
933
  var ChannelInstance = class extends import_events2.EventEmitter {
934
934
  // ID do canal
935
- constructor(client, baseClient, channelId = `channel-${Date.now()}`) {
935
+ constructor(client, baseClient, channelId = `channel-${Date.now()}`, app) {
936
936
  super();
937
937
  this.client = client;
938
938
  this.baseClient = baseClient;
939
939
  this.channelId = channelId;
940
+ this.app = app;
940
941
  this.id = channelId || `channel-${Date.now()}`;
941
942
  const wsClients = this.client.getWebSocketClients();
942
- const wsClient = Array.from(wsClients.values()).find(
943
- (client2) => client2.isConnected()
944
- );
943
+ const wsClient = wsClients.get(this.app);
945
944
  if (!wsClient) {
946
945
  throw new Error(
947
946
  `Nenhum WebSocket conectado dispon\xEDvel para o canal: ${this.id}`
948
947
  );
949
948
  }
950
- try {
951
- wsClient.addScopedMessageListener(this.id, (event) => {
949
+ wsClient.addScopedMessageListener(
950
+ this.id,
951
+ this.app,
952
+ (event) => {
952
953
  if (isChannelEvent(event, this.id)) {
953
954
  const channelEventType = event.type;
954
955
  this.emit(channelEventType, event);
955
956
  }
956
- });
957
- } catch (error) {
958
- console.error(
959
- `Erro ao adicionar listener escopado para canal '${this.id}':`,
960
- error
961
- );
962
- throw error;
963
- }
957
+ }
958
+ );
959
+ this.on("removeListener", (eventName) => {
960
+ if (this.eventNames().length === 0 || this.listenerCount(eventName) === 0) {
961
+ wsClient.removeScopedMessageListeners(this.id, this.app);
962
+ console.log(
963
+ `Listeners escopados removidos para canal '${this.id}' no app '${this.app}'.`
964
+ );
965
+ }
966
+ });
964
967
  this.on("removeListener", (eventName) => {
965
968
  if (this.eventNames().length === 0 || this.listenerCount(eventName) === 0) {
966
- wsClient.removeScopedMessageListeners(this.id);
969
+ wsClient.removeScopedMessageListeners(this.id, this.app);
967
970
  console.log(`Listeners escopados removidos para canal '${this.id}'.`);
968
971
  }
969
972
  });
@@ -999,14 +1002,14 @@ var ChannelInstance = class extends import_events2.EventEmitter {
999
1002
  console.log(`Recebido evento '${event}' para canal '${this.id}'`);
1000
1003
  this.emit(event, webSocketEvent);
1001
1004
  callback(webSocketEvent);
1002
- wsClient.removeScopedMessageListeners(this.id);
1005
+ wsClient.removeScopedMessageListeners(this.id, this.app);
1003
1006
  console.log(
1004
1007
  `Listeners escopados para canal '${this.id}' foram removidos.`
1005
1008
  );
1006
1009
  }
1007
1010
  };
1008
1011
  try {
1009
- wsClient.addScopedMessageListener(this.id, globalListener);
1012
+ wsClient.addScopedMessageListener(this.id, this.app, globalListener);
1010
1013
  } catch (error) {
1011
1014
  console.error(
1012
1015
  `Erro ao adicionar listener escopado em 'once' para canal '${this.id}':`,
@@ -1210,8 +1213,13 @@ var Channels = class extends import_events2.EventEmitter {
1210
1213
  this.baseClient = baseClient;
1211
1214
  this.client = client;
1212
1215
  }
1213
- Channel(channelId) {
1214
- return new ChannelInstance(this.client, this.baseClient, channelId);
1216
+ Channel({ id, app }) {
1217
+ if (!app) {
1218
+ throw new Error(
1219
+ "O nome do aplicativo (app) \xE9 obrigat\xF3rio para criar um Channel."
1220
+ );
1221
+ }
1222
+ return new ChannelInstance(this.client, this.baseClient, id, app);
1215
1223
  }
1216
1224
  /**
1217
1225
  * Origina um canal físico diretamente, sem uma instância de `ChannelInstance`.
@@ -1441,11 +1449,12 @@ var Endpoints = class {
1441
1449
  var import_events3 = require("events");
1442
1450
  var PlaybackInstance = class extends import_events3.EventEmitter {
1443
1451
  // Garantimos que o ID esteja disponível
1444
- constructor(client, baseClient, playbackId = `playback-${Date.now()}`) {
1452
+ constructor(client, baseClient, playbackId = `playback-${Date.now()}`, app) {
1445
1453
  super();
1446
1454
  this.client = client;
1447
1455
  this.baseClient = baseClient;
1448
1456
  this.playbackId = playbackId;
1457
+ this.app = app;
1449
1458
  this.id = playbackId || `playback-${Date.now()}`;
1450
1459
  const wsClients = this.client.getWebSocketClients();
1451
1460
  const wsClient = Array.from(wsClients.values()).find(
@@ -1457,12 +1466,16 @@ var PlaybackInstance = class extends import_events3.EventEmitter {
1457
1466
  );
1458
1467
  }
1459
1468
  try {
1460
- wsClient.addScopedMessageListener(this.id, (event) => {
1461
- if (isPlaybackEvent(event, this.id)) {
1462
- const playbackEventType = event.type;
1463
- this.emit(playbackEventType, event);
1469
+ wsClient.addScopedMessageListener(
1470
+ this.id,
1471
+ this.app,
1472
+ (event) => {
1473
+ if (isPlaybackEvent(event, this.id)) {
1474
+ const playbackEventType = event.type;
1475
+ this.emit(playbackEventType, event);
1476
+ }
1464
1477
  }
1465
- });
1478
+ );
1466
1479
  } catch (error) {
1467
1480
  console.error(
1468
1481
  `Erro ao adicionar listener escopado para playback '${this.id}':`,
@@ -1472,7 +1485,7 @@ var PlaybackInstance = class extends import_events3.EventEmitter {
1472
1485
  }
1473
1486
  this.on("removeListener", (eventName) => {
1474
1487
  if (this.eventNames().length === 0 || this.listenerCount(eventName) === 0) {
1475
- wsClient.removeScopedMessageListeners(this.id);
1488
+ wsClient.removeScopedMessageListeners(this.id, this.app);
1476
1489
  console.log(
1477
1490
  `Listeners escopados removidos para playback '${this.id}'.`
1478
1491
  );
@@ -1513,14 +1526,14 @@ var PlaybackInstance = class extends import_events3.EventEmitter {
1513
1526
  console.log(`Recebido evento '${event}' para playback '${this.id}'`);
1514
1527
  this.emit(event, webSocketEvent);
1515
1528
  callback(webSocketEvent);
1516
- wsClient.removeScopedMessageListeners(this.id);
1529
+ wsClient.removeScopedMessageListeners(this.id, this.app);
1517
1530
  console.log(
1518
1531
  `Listeners escopados para playback '${this.id}' foram removidos.`
1519
1532
  );
1520
1533
  }
1521
1534
  };
1522
1535
  try {
1523
- wsClient.addScopedMessageListener(this.id, globalListener);
1536
+ wsClient.addScopedMessageListener(this.id, this.app, globalListener);
1524
1537
  } catch (error) {
1525
1538
  console.error(
1526
1539
  `Erro ao adicionar listener escopado em 'once' para playback '${this.id}':`,
@@ -1571,7 +1584,22 @@ var PlaybackInstance = class extends import_events3.EventEmitter {
1571
1584
  if (!this.id) {
1572
1585
  throw new Error("Nenhum playback associado para encerrar.");
1573
1586
  }
1574
- await this.baseClient.delete(`/playbacks/${this.id}`);
1587
+ try {
1588
+ await this.baseClient.delete(`/playbacks/${this.id}`);
1589
+ console.log(`Playback '${this.id}' parado com sucesso.`);
1590
+ } catch (error) {
1591
+ if (error.response?.status === 404) {
1592
+ console.warn(
1593
+ `Playback '${this.id}' n\xE3o encontrado para encerrar (404).`
1594
+ );
1595
+ return;
1596
+ }
1597
+ console.error(
1598
+ `Erro ao encerrar o playback '${this.id}':`,
1599
+ error.message || error
1600
+ );
1601
+ throw error;
1602
+ }
1575
1603
  }
1576
1604
  };
1577
1605
  var Playbacks = class extends import_events3.EventEmitter {
@@ -1583,9 +1611,14 @@ var Playbacks = class extends import_events3.EventEmitter {
1583
1611
  /**
1584
1612
  * Inicializa uma nova instância de `PlaybackInstance`.
1585
1613
  */
1586
- Playback(playbackId) {
1587
- const id = playbackId || `playback-${Date.now()}`;
1588
- return new PlaybackInstance(this.client, this.baseClient, id);
1614
+ Playback({ id, app }) {
1615
+ if (!app) {
1616
+ throw new Error(
1617
+ "O nome do aplicativo (app) \xE9 obrigat\xF3rio para criar um Channel."
1618
+ );
1619
+ }
1620
+ const playbackId = id || `playback-${Date.now()}`;
1621
+ return new PlaybackInstance(this.client, this.baseClient, playbackId, app);
1589
1622
  }
1590
1623
  /**
1591
1624
  * Obtém os clientes WebSocket disponíveis.
@@ -1627,7 +1660,22 @@ var Playbacks = class extends import_events3.EventEmitter {
1627
1660
  * @returns A promise that resolves when the playback is successfully stopped.
1628
1661
  */
1629
1662
  async stop(playbackId) {
1630
- await this.baseClient.delete(`/playbacks/${playbackId}`);
1663
+ try {
1664
+ await this.baseClient.delete(`/playbacks/${playbackId}`);
1665
+ console.log(`Playback '${playbackId}' parado com sucesso.`);
1666
+ } catch (error) {
1667
+ if (error.response?.status === 404) {
1668
+ console.warn(
1669
+ `Playback '${playbackId}' n\xE3o encontrado para encerrar (404).`
1670
+ );
1671
+ return;
1672
+ }
1673
+ console.error(
1674
+ `Erro ao encerrar o playback '${playbackId}':`,
1675
+ error.message || error
1676
+ );
1677
+ throw error;
1678
+ }
1631
1679
  }
1632
1680
  /**
1633
1681
  * Registers a listener for playback events.
@@ -1833,28 +1881,36 @@ var WebSocketClient = class extends import_events4.EventEmitter {
1833
1881
  /**
1834
1882
  * Adiciona um listener escopado ao evento "message".
1835
1883
  * @param instanceId - Identificador único da instância que está registrando o listener.
1884
+ * @param app
1836
1885
  * @param callback - Função de callback para o evento.
1837
1886
  */
1838
- addScopedMessageListener(instanceId, callback) {
1839
- if (this.scopedListeners.has(instanceId)) {
1887
+ addScopedMessageListener(instanceId, app, callback) {
1888
+ const key = `${app}:${instanceId}`;
1889
+ if (this.scopedListeners.has(key)) {
1840
1890
  console.warn(
1841
- `Listener escopado para a inst\xE2ncia '${instanceId}' j\xE1 existe. Ignorando duplica\xE7\xE3o.`
1891
+ `Listener escopado para a inst\xE2ncia '${key}' j\xE1 existe. Ignorando.`
1842
1892
  );
1843
1893
  return;
1844
1894
  }
1845
1895
  const scopedListener = (data) => {
1846
- if (data.type.startsWith("Channel") && "channel" in data && data.channel?.id === instanceId || data.type.startsWith("Playback") && "playbackId" in data && data.playbackId === instanceId) {
1847
- console.log(data);
1848
- console.log(
1849
- `Listener escopado para a inst\xE2ncia '${instanceId}' ativado.`
1896
+ try {
1897
+ 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)) {
1898
+ console.log(
1899
+ `Listener escopado ativado para inst\xE2ncia '${instanceId}' no app '${app}'.`
1900
+ );
1901
+ callback(data);
1902
+ }
1903
+ } catch (error) {
1904
+ console.error(
1905
+ `Erro no listener escopado para inst\xE2ncia '${instanceId}' no app '${app}':`,
1906
+ error
1850
1907
  );
1851
- callback(data);
1852
1908
  }
1853
1909
  };
1854
- this.scopedListeners.set(instanceId, scopedListener);
1910
+ this.scopedListeners.set(key, scopedListener);
1855
1911
  this.on("message", scopedListener);
1856
1912
  console.log(
1857
- `Listener escopado adicionado para a inst\xE2ncia '${instanceId}'. Total de listeners: ${this.listenerCount(
1913
+ `Listener escopado adicionado para a inst\xE2ncia '${instanceId}' no app '${app}'. Total de listeners: ${this.listenerCount(
1858
1914
  "message"
1859
1915
  )}`
1860
1916
  );
@@ -1862,23 +1918,25 @@ var WebSocketClient = class extends import_events4.EventEmitter {
1862
1918
  /**
1863
1919
  * Remove todos os listeners associados a uma instância específica.
1864
1920
  * @param instanceId - Identificador da instância cujos listeners serão removidos.
1921
+ * @param app
1865
1922
  */
1866
- removeScopedMessageListeners(instanceId) {
1867
- if (!this.scopedListeners.has(instanceId)) {
1868
- console.warn(
1869
- `Nenhum listener encontrado para a inst\xE2ncia '${instanceId}'.`
1870
- );
1923
+ removeScopedMessageListeners(instanceId, app) {
1924
+ const key = `${app}:${instanceId}`;
1925
+ if (!this.scopedListeners.has(key)) {
1926
+ console.warn(`Nenhum listener encontrado para a inst\xE2ncia '${key}'.`);
1871
1927
  return;
1872
1928
  }
1873
- const scopedListener = this.scopedListeners.get(instanceId);
1929
+ const scopedListener = this.scopedListeners.get(key);
1874
1930
  if (scopedListener) {
1875
1931
  this.off("message", scopedListener);
1876
- this.scopedListeners.delete(instanceId);
1932
+ this.scopedListeners.delete(key);
1877
1933
  console.log(
1878
- `Listeners removidos para a inst\xE2ncia '${instanceId}'. Total de listeners restantes: ${this.listenerCount(
1934
+ `Listeners removidos para a inst\xE2ncia '${key}'. Total de listeners restantes: ${this.listenerCount(
1879
1935
  "message"
1880
1936
  )}`
1881
1937
  );
1938
+ } else {
1939
+ console.warn(`Listener j\xE1 foi removido para a inst\xE2ncia '${key}'.`);
1882
1940
  }
1883
1941
  }
1884
1942
  /**
@@ -1888,13 +1946,14 @@ var WebSocketClient = class extends import_events4.EventEmitter {
1888
1946
  handleMessage(rawData) {
1889
1947
  try {
1890
1948
  const decodedData = JSON.parse(rawData.toString());
1891
- if (decodedData?.type) {
1892
- this.emit(decodedData.type, decodedData);
1893
- if (this.listenerCount("message") > 0) {
1894
- this.emit("message", decodedData);
1895
- }
1949
+ if (decodedData?.type && decodedData?.application) {
1950
+ this.emit(decodedData.application, decodedData);
1951
+ this.emit("message", decodedData);
1896
1952
  } else {
1897
- console.warn("Mensagem recebida sem tipo:", decodedData);
1953
+ console.warn(
1954
+ "Mensagem recebida sem tipo ou aplica\xE7\xE3o v\xE1lida:",
1955
+ decodedData
1956
+ );
1898
1957
  }
1899
1958
  } catch (err) {
1900
1959
  console.error("Erro ao decodificar mensagem do WebSocket:", err);
@@ -2004,14 +2063,18 @@ var AriClient = class {
2004
2063
  * Registra listeners globais para eventos de WebSocket.
2005
2064
  */
2006
2065
  on(eventType, callback, app) {
2066
+ if (!app) {
2067
+ throw new Error(
2068
+ "O nome do app \xE9 obrigat\xF3rio para registrar um listener de evento."
2069
+ );
2070
+ }
2007
2071
  console.log(
2008
- app ? `Registrando listener para evento '${eventType}' no app '${app}'` : `Registrando listener global para evento: '${eventType}'`
2072
+ `Registrando listener para evento '${eventType}' no app '${app}'.`
2009
2073
  );
2010
- console.log("********************************************** ", app);
2011
- const callbackKey = app ? `${eventType}-${app}` : eventType;
2074
+ const callbackKey = `${eventType}-${app}`;
2012
2075
  if (this.eventListeners.has(callbackKey)) {
2013
2076
  console.log(
2014
- `Listener para evento '${eventType}' j\xE1 est\xE1 registrado${app ? ` no app '${app}'` : " globalmente"}. Ignorando duplicata.`
2077
+ `Listener para evento '${eventType}' j\xE1 est\xE1 registrado no app '${app}'. Ignorando duplicata.`
2015
2078
  );
2016
2079
  return;
2017
2080
  }
@@ -2020,7 +2083,7 @@ var AriClient = class {
2020
2083
  const channelId = event.channel.id;
2021
2084
  if (channelId) {
2022
2085
  if (!this.channelInstances.has(channelId)) {
2023
- const channelInstance = this.createChannelInstance(channelId);
2086
+ const channelInstance = this.createChannelInstance(channelId, app);
2024
2087
  this.channelInstances.set(channelId, channelInstance);
2025
2088
  }
2026
2089
  event.instanceChannel = this.channelInstances.get(channelId);
@@ -2029,19 +2092,15 @@ var AriClient = class {
2029
2092
  }
2030
2093
  callback(event);
2031
2094
  };
2032
- if (app) {
2033
- const wsClient = this.wsClients.get(app);
2034
- if (wsClient) {
2035
- wsClient.on(eventType, wrappedCallback);
2036
- this.eventListeners.set(callbackKey, wrappedCallback);
2037
- } else {
2038
- console.warn(`WebSocket para o app '${app}' n\xE3o est\xE1 conectado.`);
2039
- }
2040
- } else {
2041
- for (const [_app, wsClient] of this.wsClients.entries()) {
2042
- wsClient.on(eventType, wrappedCallback);
2043
- }
2095
+ const wsClient = this.wsClients.get(app);
2096
+ if (wsClient) {
2097
+ wsClient.on(eventType, wrappedCallback);
2044
2098
  this.eventListeners.set(callbackKey, wrappedCallback);
2099
+ console.log(
2100
+ `Listener para evento '${eventType}' registrado com sucesso no app '${app}'.`
2101
+ );
2102
+ } else {
2103
+ console.warn(`WebSocket para o app '${app}' n\xE3o est\xE1 conectado.`);
2045
2104
  }
2046
2105
  }
2047
2106
  removeListener(eventType, app) {
@@ -2084,17 +2143,20 @@ var AriClient = class {
2084
2143
  return data?.channel?.id !== void 0;
2085
2144
  }
2086
2145
  // Método para criar uma instância de ChannelInstance
2087
- createChannelInstance(channelId) {
2088
- return this.channels.Channel(channelId);
2146
+ createChannelInstance(channelId, app) {
2147
+ return this.channels.Channel({
2148
+ id: channelId,
2149
+ app
2150
+ });
2089
2151
  }
2090
- handleWebSocketEvent(event) {
2152
+ handleWebSocketEvent(event, app) {
2091
2153
  console.log("Evento recebido no WebSocket:", event.type, event);
2092
2154
  const { type, ...data } = event;
2093
2155
  if (this.hasChannel(data)) {
2094
2156
  const channelId = data.channel.id;
2095
2157
  if (channelId) {
2096
2158
  if (!this.channelInstances.has(channelId)) {
2097
- const channelInstance2 = this.createChannelInstance(channelId);
2159
+ const channelInstance2 = this.createChannelInstance(channelId, app);
2098
2160
  this.channelInstances.set(channelId, channelInstance2);
2099
2161
  }
2100
2162
  const channelInstance = this.channelInstances.get(channelId);
@@ -2132,8 +2194,9 @@ var AriClient = class {
2132
2194
  if (!Array.isArray(apps) || apps.length === 0) {
2133
2195
  throw new Error("\xC9 necess\xE1rio fornecer pelo menos um aplicativo.");
2134
2196
  }
2197
+ const uniqueApps = [...new Set(apps)];
2135
2198
  return Promise.all(
2136
- apps.map(async (app) => {
2199
+ uniqueApps.map(async (app) => {
2137
2200
  if (this.wsClients.has(app)) {
2138
2201
  console.log(`Conex\xE3o WebSocket para '${app}' j\xE1 existe. Ignorando.`);
2139
2202
  return;
@@ -2323,19 +2386,31 @@ var AriClient = class {
2323
2386
  * Inicializa uma nova instância de `ChannelInstance` para manipular canais localmente.
2324
2387
  *
2325
2388
  * @param channelId - O ID do canal, se disponível. Caso contrário, a instância será para um canal ainda não criado.
2389
+ * @param app
2326
2390
  * @returns Uma instância de `ChannelInstance` vinculada ao cliente atual.
2327
2391
  */
2328
- Channel(channelId) {
2329
- return this.channels.Channel(channelId);
2392
+ Channel(channelId, app) {
2393
+ if (!app) {
2394
+ throw new Error(
2395
+ "O nome do aplicativo (app) \xE9 obrigat\xF3rio para criar um Channel."
2396
+ );
2397
+ }
2398
+ return this.channels.Channel({ id: channelId, app });
2330
2399
  }
2331
2400
  /**
2332
2401
  * Inicializa uma nova instância de `PlaybackInstance` para manipular playbacks.
2333
2402
  *
2334
2403
  * @param playbackId - O ID do playback, se disponível. Caso contrário, a instância será para um playback ainda não inicializado.
2404
+ * @param app
2335
2405
  * @returns Uma instância de `PlaybackInstance` vinculada ao cliente atual.
2336
2406
  */
2337
- Playback(playbackId) {
2338
- return this.playbacks.Playback(playbackId);
2407
+ Playback(playbackId, app) {
2408
+ if (!app) {
2409
+ throw new Error(
2410
+ "O nome do aplicativo (app) \xE9 obrigat\xF3rio para criar um Channel."
2411
+ );
2412
+ }
2413
+ return this.playbacks.Playback({ id: playbackId, app });
2339
2414
  }
2340
2415
  };
2341
2416
  // Annotate the CommonJS export names for ESM import in node: