amule-ec-client 0.6.1 → 0.7.1

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.
Files changed (45) hide show
  1. package/README.md +10 -2
  2. package/dist/{AddLinkRequest-D2IME4eb.js → AddLinkRequest-CGv1H3PC.js} +2 -3
  3. package/dist/{ClientQueueRequest-DFfCiNcz.js → ClientQueueRequest-mklt-KLi.js} +2 -3
  4. package/dist/{ClientQueueResponse-JTrBqrr1.js → ClientQueueResponse-RfXh2JGa.js} +8 -5
  5. package/dist/{CreateCategoryRequest-CRUMcPo5.js → CreateCategoryRequest-Cyp9G7jU.js} +2 -3
  6. package/dist/{DeleteCategoryRequest-C8v9oGZ-.js → DeleteCategoryRequest-DbLJ4mvi.js} +2 -3
  7. package/dist/{DownloadCommandRequest-B3KV_bvm.js → DownloadCommandRequest-DLU7RtYs.js} +2 -3
  8. package/dist/{DownloadFileRequest-BjrroO3h.js → DownloadFileRequest-Db7oijyu.js} +2 -3
  9. package/dist/{DownloadQueueRequest-Dil5hl3D.js → DownloadQueueRequest-DdHRjl4L.js} +2 -3
  10. package/dist/{GetPreferencesRequest-DsxlghqT.js → GetPreferencesRequest-BlWGYNCP.js} +2 -3
  11. package/dist/{PreferencesDetailsResponse-DapscVQi.js → PreferencesDetailsResponse-BX6qUoga.js} +1 -2
  12. package/dist/{PreferencesResponse-8n1STWUZ.js → PreferencesResponse-migFtIG7.js} +1 -2
  13. package/dist/{ReloadSharedFilesRequest-kt0Pxs8A.js → ReloadSharedFilesRequest-WD9iYLje.js} +2 -2
  14. package/dist/{Request-C0UUuQIX.js → Request-YQ0nIM6b.js} +3 -9
  15. package/dist/{SearchProgressResponse-C1CdzKnz.js → SearchProgressResponse-CkEgZGFE.js} +1 -2
  16. package/dist/{SearchRequest-DQnKfA5Z.js → SearchRequest-DaAKS4IO.js} +2 -3
  17. package/dist/{SearchResultsRequest-2ejFGQmQ.js → SearchResultsRequest-B53jwjRH.js} +2 -2
  18. package/dist/{SearchResultsResponse-DwmvbQop.js → SearchResultsResponse-C1l-bBja.js} +1 -2
  19. package/dist/{SearchStatusRequest-B_xr4-72.js → SearchStatusRequest-DuEa5ZYu.js} +2 -2
  20. package/dist/{SearchStopRequest-8hwXobty.js → SearchStopRequest-B5TZdMiB.js} +2 -2
  21. package/dist/{ServerConnectRequest-BhNpGiEJ.js → ServerConnectRequest-BeB8RSBN.js} +2 -3
  22. package/dist/{ServerDisconnectRequest-BjCitLtU.js → ServerDisconnectRequest-CSkUHETP.js} +2 -2
  23. package/dist/{ServerListRequest-BWXLGJib.js → ServerListRequest-B82686jD.js} +2 -2
  24. package/dist/{ServerListResponse-BUJ7sz5p.js → ServerListResponse-M3C2OcfZ.js} +5 -4
  25. package/dist/{ServerUpdateFromUrlRequest-K8C_d0UQ.js → ServerUpdateFromUrlRequest-BcvhRKgH.js} +2 -3
  26. package/dist/{SetFileCategoryRequest-VwroLBTV.js → SetFileCategoryRequest-C1jWsYO5.js} +2 -3
  27. package/dist/{SetPreferencesRequest-KZ23VaBY.js → SetPreferencesRequest-CNJVmeQl.js} +2 -3
  28. package/dist/{SharedFilePriorityRequest-7BriqAcr.js → SharedFilePriorityRequest-CBqkaXaK.js} +2 -3
  29. package/dist/{SharedFilesRequest-B72XyRcA.js → SharedFilesRequest-5mKKjzgt.js} +2 -3
  30. package/dist/SharedFilesResponse-CFl0NuO-.js +45 -0
  31. package/dist/{StatsRequest-CGGumOOx.js → StatsRequest-C9gBUvSq.js} +2 -3
  32. package/dist/{StatsResponse-DxQk686g.js → StatsResponse-KOk-xT6_.js} +25 -2
  33. package/dist/{Codes-CjiW7Pdl.js → Tag-D_Ybe5RQ.js} +280 -1
  34. package/dist/{UpdateCategoryRequest-CzKJa_rC.js → UpdateCategoryRequest-BOYfb6Vn.js} +2 -3
  35. package/dist/{UpdateRequest-g2ReOQ5m.js → UpdateRequest-csLQz7JO.js} +2 -3
  36. package/dist/UpdateState-LhdtiATk.js +443 -0
  37. package/dist/index.d.ts +381 -337
  38. package/dist/index.js +116 -55
  39. package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
  40. package/dist/{utils-DBnUQnZ-.js → utils-CNoUroOI.js} +11 -1
  41. package/package.json +1 -1
  42. package/dist/DownloadQueueResponse-DUam_zNf.js +0 -259
  43. package/dist/SharedFilesResponse-CkqvYd3N.js +0 -39
  44. package/dist/Tag-CZF6BRMY.js +0 -260
  45. package/dist/UpdateResponse-CGwVjn0Y.js +0 -45
package/dist/index.js CHANGED
@@ -1,6 +1,5 @@
1
- import { n as Packet, r as Flags, t as Request } from "./Request-C0UUuQIX.js";
2
- import { a as EcPrefs, i as ECTagName, n as ECOpCode, o as ProtocolVersion, r as ECSearchType, t as ECDetailLevel } from "./Codes-CjiW7Pdl.js";
3
- import { a as StringTag, c as UInt128Tag, d as UShortTag, f as findNumericTag, i as Ipv4Tag, l as UIntTag, n as DoubleTag, o as Tag, r as Hash16Tag, s as UByteTag, t as CustomTag, u as ULongTag } from "./Tag-CZF6BRMY.js";
1
+ import { n as Packet, r as Flags, t as Request } from "./Request-YQ0nIM6b.js";
2
+ import { _ as ECSearchType, a as StringTag, b as ProtocolVersion, c as UInt128Tag, d as UShortTag, f as findNumericTag, g as ECSearchFileDownloadStatus, h as ECOpCode, i as Ipv4Tag, l as UIntTag, m as ECDetailLevel, n as DoubleTag, o as Tag, p as findTag, r as Hash16Tag, s as UByteTag, t as CustomTag, u as ULongTag, v as ECTagName, y as EcPrefs } from "./Tag-D_Ybe5RQ.js";
4
3
  import { n as PARTSIZE, t as ChunkStatus } from "./download-details-OM0FJUhZ.js";
5
4
  import * as net from "net";
6
5
  import * as zlib from "zlib";
@@ -183,7 +182,11 @@ var TagParser = class {
183
182
  case 5: return new ULongTag(name, value.length >= 8 ? value.readBigUInt64BE(0) : 0n);
184
183
  case 10: return new UInt128Tag(name, value.length >= 16 ? this.parseUInt128(value) : 0n);
185
184
  case 6: return new StringTag(name, value[value.length - 1] === 0 ? value.toString("utf-8", 0, value.length - 1) : value.toString("utf-8"));
186
- case 7: return new DoubleTag(name, value.length >= 8 ? value.readDoubleBE(0) : 0);
185
+ case 7: {
186
+ const tag = new DoubleTag(name);
187
+ tag.parseValue(value);
188
+ return tag;
189
+ }
187
190
  case 8: {
188
191
  if (value.length !== 6) throw new InvalidECException(`Ipv4Tag value must be 6 bytes long, got ${value.length}`);
189
192
  const address = `${value[0]}.${value[1]}.${value[2]}.${value[3]}`;
@@ -335,7 +338,7 @@ var TagEncoder = class {
335
338
  case 4: return 4;
336
339
  case 5: return 8;
337
340
  case 10: return 16;
338
- case 7: return 8;
341
+ case 7: return encoded.length;
339
342
  case 8: return 6;
340
343
  case 9: return 16;
341
344
  default: return 0;
@@ -518,8 +521,8 @@ var PasswordHasher = class {
518
521
  /**
519
522
  * Hash a password with salt using MD5
520
523
  *
521
- * This matches aMule's password hashing algorithm (from jamule):
522
- * 1. saltHash = MD5(salt.toHexString().uppercase())
524
+ * This matches aMule's password hashing algorithm (ExternalConn.cpp):
525
+ * 1. saltHash = MD5(salt formatted as "%lX")
523
526
  * 2. passwordHash = MD5(password)
524
527
  * 3. return MD5(passwordHash.toHex().lowercase() + saltHash.toHex().lowercase())
525
528
  *
@@ -528,7 +531,7 @@ var PasswordHasher = class {
528
531
  * @returns The hashed password as a Buffer
529
532
  */
530
533
  static hash(password, salt) {
531
- const saltHexUpper = salt.toString(16).toUpperCase().padStart(16, "0");
534
+ const saltHexUpper = salt.toString(16).toUpperCase();
532
535
  const saltHash = crypto.createHash("md5").update(saltHexUpper, "utf-8").digest();
533
536
  const passwordHashHex = crypto.createHash("md5").update(password, "utf-8").digest().toString("hex").toLowerCase();
534
537
  const saltHashHex = saltHash.toString("hex").toLowerCase();
@@ -549,7 +552,7 @@ var PasswordHasher = class {
549
552
  /**
550
553
  * AmuleConnection - Manages the low-level connection to aMule EC
551
554
  */
552
- var AmuleConnection = class {
555
+ var AmuleConnection = class AmuleConnection {
553
556
  host;
554
557
  port;
555
558
  password;
@@ -560,6 +563,7 @@ var AmuleConnection = class {
560
563
  pendingResponses = [];
561
564
  connectionPromise;
562
565
  requestTimeout = 0;
566
+ sessionGeneration = 0;
563
567
  debug = false;
564
568
  /**
565
569
  * Enable or disable debug logging
@@ -595,6 +599,13 @@ var AmuleConnection = class {
595
599
  return this.requestTimeout;
596
600
  }
597
601
  /**
602
+ * Monotonic counter incremented on every (re)connection attempt.
603
+ * Lets consumers detect that the daemon-side per-connection state was reset.
604
+ */
605
+ getSessionGeneration() {
606
+ return this.sessionGeneration;
607
+ }
608
+ /**
598
609
  * Reject and clear all pending responses.
599
610
  */
600
611
  rejectAllPending(error) {
@@ -611,7 +622,9 @@ var AmuleConnection = class {
611
622
  if (this.connectionPromise) return this.connectionPromise;
612
623
  this.connectionPromise = (async () => {
613
624
  this.connected = false;
625
+ this.sessionGeneration++;
614
626
  if (this.socket) this.socket.destroy();
627
+ this.buffer = Buffer.allocUnsafe(0);
615
628
  this.socket = new net.Socket();
616
629
  if (this.timeout > 0) this.socket.setTimeout(this.timeout);
617
630
  this.socket.on("data", (data) => this.handleData(Buffer.isBuffer(data) ? data : Buffer.from(data)));
@@ -621,6 +634,7 @@ var AmuleConnection = class {
621
634
  try {
622
635
  await this.connectSocket();
623
636
  await this.authenticate();
637
+ this.socket?.setTimeout(0);
624
638
  this.connected = true;
625
639
  } finally {
626
640
  this.connectionPromise = void 0;
@@ -633,11 +647,14 @@ var AmuleConnection = class {
633
647
  */
634
648
  connectSocket() {
635
649
  return new Promise((resolve, reject) => {
636
- if (!this.socket) return reject(new CommunicationException("Socket not initialized"));
637
- this.socket.connect(this.port, this.host, () => {
650
+ const socket = this.socket;
651
+ if (!socket) return reject(new CommunicationException("Socket not initialized"));
652
+ const onError = (error) => reject(error);
653
+ socket.once("error", onError);
654
+ socket.connect(this.port, this.host, () => {
655
+ socket.removeListener("error", onError);
638
656
  resolve();
639
657
  });
640
- this.socket.once("error", reject);
641
658
  });
642
659
  }
643
660
  /**
@@ -649,7 +666,7 @@ var AmuleConnection = class {
649
666
  this.log("Sending client info...");
650
667
  const saltPacket = await this.sendRequestNoAuth(clientInfoRequest);
651
668
  this.log("Received salt response");
652
- if (saltPacket.opCode === 3) throw new ServerException("Authentication failed: server rejected client");
669
+ if (saltPacket.opCode === 3) throw new ServerException(`Authentication failed: ${AmuleConnection.authFailReason(saltPacket) ?? "connection refused with no reason; the daemon usually does this when its EC password is empty (external connections disabled)"}`);
653
670
  if (saltPacket.opCode !== 79) throw new ServerException(`Unexpected response to client info: ${saltPacket.opCode}`);
654
671
  const saltResponse = AuthSaltResponse.fromPacket(saltPacket);
655
672
  this.log("Salt:", saltResponse.salt);
@@ -659,11 +676,18 @@ var AmuleConnection = class {
659
676
  this.log("Sending hashed password...");
660
677
  const authPacket = await this.sendRequestNoAuth(authRequest);
661
678
  this.log("Received auth response");
662
- if (authPacket.opCode === 3) throw new ServerException("Authentication failed: invalid password");
679
+ if (authPacket.opCode === 3) throw new ServerException(`Authentication failed: ${AmuleConnection.authFailReason(authPacket) ?? "unknown reason"}`);
663
680
  if (authPacket.opCode !== 4) throw new ServerException(`Unexpected auth response: ${authPacket.opCode}`);
664
681
  this.log("Authentication successful!");
665
682
  }
666
683
  /**
684
+ * Extract the human-readable reason the daemon attaches to EC_OP_AUTH_FAIL packets.
685
+ */
686
+ static authFailReason(packet) {
687
+ const reason = findTag(packet.tags, 0)?.getValue();
688
+ return typeof reason === "string" && reason.length > 0 ? reason : void 0;
689
+ }
690
+ /**
667
691
  * Handle incoming data
668
692
  */
669
693
  handleData(data) {
@@ -790,6 +814,7 @@ let SearchType = /* @__PURE__ */ function(SearchType) {
790
814
  */
791
815
  var AmuleClient = class {
792
816
  connection;
817
+ updateState;
793
818
  constructor(options) {
794
819
  this.connection = new AmuleConnection(options.host, options.port, options.password, options.timeout || 0, options.requestTimeout || 0);
795
820
  }
@@ -810,33 +835,63 @@ var AmuleClient = class {
810
835
  * Reconnect to the server
811
836
  */
812
837
  async reconnect() {
838
+ this.updateState = void 0;
813
839
  await this.connection.reconnect();
814
840
  }
815
841
  /**
816
842
  * Get server statistics
817
843
  */
818
844
  async getStats() {
819
- const { StatsRequest } = await import("./StatsRequest-CGGumOOx.js");
820
- const { StatsResponseParser } = await import("./StatsResponse-DxQk686g.js");
845
+ const { StatsRequest } = await import("./StatsRequest-C9gBUvSq.js");
846
+ const { StatsResponseParser } = await import("./StatsResponse-KOk-xT6_.js");
821
847
  const request = new StatsRequest();
822
848
  const packet = await this.connection.sendRequest(request);
823
849
  return StatsResponseParser.fromPacket(packet);
824
850
  }
825
851
  /**
826
- * Get incremental updates for files, clients, servers, and friends
852
+ * Per-connection file-detail state (diff baselines, source names, merged snapshots).
853
+ * The daemon diffs per connection and shares the diff state between the update,
854
+ * download-queue and shared-files requests, so this state must be fed by all of
855
+ * them (see UpdateState). Call only after sendRequest: connecting may have started
856
+ * a new session, which invalidates the previous state.
857
+ */
858
+ async getFileState() {
859
+ const { UpdateState } = await import("./UpdateState-LhdtiATk.js");
860
+ const generation = this.connection.getSessionGeneration();
861
+ if (!this.updateState || this.updateState.sessionGeneration !== generation) this.updateState = new UpdateState(generation);
862
+ return this.updateState;
863
+ }
864
+ /**
865
+ * Get updates for files, clients, servers, and friends.
866
+ *
867
+ * The underlying EC_OP_GET_UPDATE request is incremental per connection: the daemon
868
+ * only sends the fields that changed since the previous call. This method keeps a
869
+ * client-side cache and merges those diffs, so it always returns full snapshots.
870
+ * Downloads carry their connected peers in `sources` (linked via client requestFileId
871
+ * and file ecid). The cache is reset whenever the connection is re-established.
827
872
  */
828
873
  async getUpdate(detailLevel = 4) {
829
- const { UpdateRequest } = await import("./UpdateRequest-g2ReOQ5m.js");
830
- const { UpdateResponseParser } = await import("./UpdateResponse-CGwVjn0Y.js");
874
+ const { UpdateRequest } = await import("./UpdateRequest-csLQz7JO.js");
831
875
  const request = new UpdateRequest(detailLevel);
832
876
  const packet = await this.connection.sendRequest(request);
833
- return UpdateResponseParser.fromPacket(packet);
877
+ return (await this.getFileState()).apply(packet);
878
+ }
879
+ /**
880
+ * Get the download queue including per-peer source details.
881
+ *
882
+ * Unlike getDownloadQueue() (EC_OP_GET_DLOAD_QUEUE, which never includes peers),
883
+ * this uses the incremental update mechanism (see getUpdate), the only way the
884
+ * daemon exposes the clients each download is fed from. Each returned file has
885
+ * `sources` filled with the currently connected peers for that download.
886
+ */
887
+ async getDownloadQueueWithSources() {
888
+ return (await this.getUpdate()).downloadQueue;
834
889
  }
835
890
  /**
836
891
  * Start an asynchronous search
837
892
  */
838
893
  async searchAsync(query, searchType, filters) {
839
- const { SearchRequest } = await import("./SearchRequest-DQnKfA5Z.js");
894
+ const { SearchRequest } = await import("./SearchRequest-DaAKS4IO.js");
840
895
  const request = new SearchRequest(query, searchType, filters);
841
896
  await this.connection.sendRequest(request);
842
897
  return query;
@@ -845,8 +900,8 @@ var AmuleClient = class {
845
900
  * Get search status (0-1)
846
901
  */
847
902
  async searchStatus() {
848
- const { SearchStatusRequest } = await import("./SearchStatusRequest-B_xr4-72.js");
849
- const { SearchProgressResponse } = await import("./SearchProgressResponse-C1CdzKnz.js");
903
+ const { SearchStatusRequest } = await import("./SearchStatusRequest-DuEa5ZYu.js");
904
+ const { SearchProgressResponse } = await import("./SearchProgressResponse-CkEgZGFE.js");
850
905
  const request = new SearchStatusRequest();
851
906
  const packet = await this.connection.sendRequest(request);
852
907
  return SearchProgressResponse.fromPacket(packet).progress;
@@ -855,8 +910,8 @@ var AmuleClient = class {
855
910
  * Get search results
856
911
  */
857
912
  async searchResults() {
858
- const { SearchResultsRequest } = await import("./SearchResultsRequest-2ejFGQmQ.js");
859
- const { SearchResultsResponseParser } = await import("./SearchResultsResponse-DwmvbQop.js");
913
+ const { SearchResultsRequest } = await import("./SearchResultsRequest-B53jwjRH.js");
914
+ const { SearchResultsResponseParser } = await import("./SearchResultsResponse-C1l-bBja.js");
860
915
  const request = new SearchResultsRequest();
861
916
  const packet = await this.connection.sendRequest(request);
862
917
  return SearchResultsResponseParser.fromPacket(packet);
@@ -877,7 +932,7 @@ var AmuleClient = class {
877
932
  * Stop current search
878
933
  */
879
934
  async searchStop() {
880
- const { SearchStopRequest } = await import("./SearchStopRequest-8hwXobty.js");
935
+ const { SearchStopRequest } = await import("./SearchStopRequest-B5TZdMiB.js");
881
936
  const request = new SearchStopRequest();
882
937
  await this.connection.sendRequest(request);
883
938
  }
@@ -885,7 +940,7 @@ var AmuleClient = class {
885
940
  * Download a file from search results
886
941
  */
887
942
  async downloadSearchResult(hash) {
888
- const { DownloadFileRequest } = await import("./DownloadFileRequest-BjrroO3h.js");
943
+ const { DownloadFileRequest } = await import("./DownloadFileRequest-Db7oijyu.js");
889
944
  const request = new DownloadFileRequest(hash);
890
945
  await this.connection.sendRequest(request);
891
946
  }
@@ -893,44 +948,50 @@ var AmuleClient = class {
893
948
  * Download from an ed2k link
894
949
  */
895
950
  async downloadEd2kLink(link) {
896
- const { AddLinkRequest } = await import("./AddLinkRequest-D2IME4eb.js");
951
+ const { AddLinkRequest } = await import("./AddLinkRequest-CGv1H3PC.js");
897
952
  const request = new AddLinkRequest(link);
898
953
  await this.connection.sendRequest(request);
899
954
  }
900
955
  /**
901
- * Get download queue
956
+ * Get download queue (EC_OP_GET_DLOAD_QUEUE, full detail).
957
+ *
958
+ * The response rebases the per-connection diff state the daemon shares with
959
+ * getUpdate()/getDownloadQueueWithSources(), so it is fed into the same
960
+ * client-side state: both methods stay consistent however they are interleaved,
961
+ * and chunkInfo/sourceNames are correct across repeated calls.
902
962
  */
903
963
  async getDownloadQueue() {
904
- const { DownloadQueueRequest } = await import("./DownloadQueueRequest-Dil5hl3D.js");
905
- const { DownloadQueueResponseParser } = await import("./DownloadQueueResponse-DUam_zNf.js");
964
+ const { DownloadQueueRequest } = await import("./DownloadQueueRequest-DdHRjl4L.js");
906
965
  const request = new DownloadQueueRequest();
907
966
  const packet = await this.connection.sendRequest(request);
908
- return DownloadQueueResponseParser.fromPacket(packet).files;
967
+ return (await this.getFileState()).applyDownloadQueue(packet);
909
968
  }
910
969
  /**
911
970
  * Get shared files
912
971
  */
913
972
  async getSharedFiles() {
914
- const { SharedFilesRequest } = await import("./SharedFilesRequest-B72XyRcA.js");
915
- const { SharedFilesResponseParser } = await import("./SharedFilesResponse-CkqvYd3N.js");
973
+ const { SharedFilesRequest } = await import("./SharedFilesRequest-5mKKjzgt.js");
974
+ const { SharedFilesResponseParser } = await import("./SharedFilesResponse-CFl0NuO-.js").then((n) => n.n);
916
975
  const request = new SharedFilesRequest();
917
976
  const packet = await this.connection.sendRequest(request);
977
+ (await this.getFileState()).applySharedFiles(packet);
918
978
  return SharedFilesResponseParser.fromPacket(packet).files;
919
979
  }
920
980
  /**
921
981
  * Reload shared files list
922
982
  */
923
983
  async reloadSharedFiles() {
924
- const { ReloadSharedFilesRequest } = await import("./ReloadSharedFilesRequest-kt0Pxs8A.js");
984
+ const { ReloadSharedFilesRequest } = await import("./ReloadSharedFilesRequest-WD9iYLje.js");
925
985
  const request = new ReloadSharedFilesRequest();
926
986
  await this.connection.sendRequest(request);
927
987
  }
928
988
  /**
929
- * Get client upload/download queue (clients we are uploading to/downloading from)
989
+ * Get the upload queue: clients we are uploading to or that wait in our queue
990
+ * (EC_OP_GET_ULOAD_QUEUE). For download sources use getDownloadQueueWithSources().
930
991
  */
931
992
  async getClientQueue() {
932
- const { ClientQueueRequest } = await import("./ClientQueueRequest-DFfCiNcz.js");
933
- const { ClientQueueResponseParser } = await import("./ClientQueueResponse-JTrBqrr1.js");
993
+ const { ClientQueueRequest } = await import("./ClientQueueRequest-mklt-KLi.js");
994
+ const { ClientQueueResponseParser } = await import("./ClientQueueResponse-RfXh2JGa.js").then((n) => n.n);
934
995
  const request = new ClientQueueRequest();
935
996
  const packet = await this.connection.sendRequest(request);
936
997
  return ClientQueueResponseParser.fromPacket(packet).clients;
@@ -939,8 +1000,8 @@ var AmuleClient = class {
939
1000
  * Get the list of servers
940
1001
  */
941
1002
  async getServerList() {
942
- const { ServerListRequest } = await import("./ServerListRequest-BWXLGJib.js");
943
- const { ServerListResponseParser } = await import("./ServerListResponse-BUJ7sz5p.js");
1003
+ const { ServerListRequest } = await import("./ServerListRequest-B82686jD.js");
1004
+ const { ServerListResponseParser } = await import("./ServerListResponse-M3C2OcfZ.js").then((n) => n.n);
944
1005
  const request = new ServerListRequest();
945
1006
  const packet = await this.connection.sendRequest(request);
946
1007
  return ServerListResponseParser.fromPacket(packet).servers;
@@ -949,7 +1010,7 @@ var AmuleClient = class {
949
1010
  * Connect to a specific server
950
1011
  */
951
1012
  async connectToServer(ip, port) {
952
- const { ServerConnectRequest } = await import("./ServerConnectRequest-BhNpGiEJ.js");
1013
+ const { ServerConnectRequest } = await import("./ServerConnectRequest-BeB8RSBN.js");
953
1014
  const request = new ServerConnectRequest(ip, port);
954
1015
  await this.connection.sendRequest(request);
955
1016
  }
@@ -957,7 +1018,7 @@ var AmuleClient = class {
957
1018
  * Disconnect from the current server
958
1019
  */
959
1020
  async disconnectFromServer() {
960
- const { ServerDisconnectRequest } = await import("./ServerDisconnectRequest-BjCitLtU.js");
1021
+ const { ServerDisconnectRequest } = await import("./ServerDisconnectRequest-CSkUHETP.js");
961
1022
  const request = new ServerDisconnectRequest();
962
1023
  await this.connection.sendRequest(request);
963
1024
  }
@@ -965,7 +1026,7 @@ var AmuleClient = class {
965
1026
  * Create a category
966
1027
  */
967
1028
  async createCategory(category) {
968
- const { CreateCategoryRequest } = await import("./CreateCategoryRequest-CRUMcPo5.js");
1029
+ const { CreateCategoryRequest } = await import("./CreateCategoryRequest-Cyp9G7jU.js");
969
1030
  const request = new CreateCategoryRequest(category);
970
1031
  await this.connection.sendRequest(request);
971
1032
  }
@@ -973,7 +1034,7 @@ var AmuleClient = class {
973
1034
  * Update a category
974
1035
  */
975
1036
  async updateCategory(id, category) {
976
- const { UpdateCategoryRequest } = await import("./UpdateCategoryRequest-CzKJa_rC.js");
1037
+ const { UpdateCategoryRequest } = await import("./UpdateCategoryRequest-BOYfb6Vn.js");
977
1038
  const request = new UpdateCategoryRequest(id, category);
978
1039
  await this.connection.sendRequest(request);
979
1040
  }
@@ -981,7 +1042,7 @@ var AmuleClient = class {
981
1042
  * Delete a category
982
1043
  */
983
1044
  async deleteCategory(id) {
984
- const { DeleteCategoryRequest } = await import("./DeleteCategoryRequest-C8v9oGZ-.js");
1045
+ const { DeleteCategoryRequest } = await import("./DeleteCategoryRequest-DbLJ4mvi.js");
985
1046
  const request = new DeleteCategoryRequest(id);
986
1047
  await this.connection.sendRequest(request);
987
1048
  }
@@ -989,8 +1050,8 @@ var AmuleClient = class {
989
1050
  * Get all categories
990
1051
  */
991
1052
  async getCategories() {
992
- const { GetPreferencesRequest } = await import("./GetPreferencesRequest-DsxlghqT.js");
993
- const { PreferencesResponseParser } = await import("./PreferencesResponse-8n1STWUZ.js");
1053
+ const { GetPreferencesRequest } = await import("./GetPreferencesRequest-BlWGYNCP.js");
1054
+ const { PreferencesResponseParser } = await import("./PreferencesResponse-migFtIG7.js");
994
1055
  const request = new GetPreferencesRequest(1);
995
1056
  const packet = await this.connection.sendRequest(request);
996
1057
  return PreferencesResponseParser.fromPacket(packet).categories;
@@ -999,7 +1060,7 @@ var AmuleClient = class {
999
1060
  * Set file category
1000
1061
  */
1001
1062
  async setFileCategory(hash, categoryId) {
1002
- const { SetFileCategoryRequest } = await import("./SetFileCategoryRequest-VwroLBTV.js");
1063
+ const { SetFileCategoryRequest } = await import("./SetFileCategoryRequest-C1jWsYO5.js");
1003
1064
  const request = new SetFileCategoryRequest(hash, categoryId);
1004
1065
  await this.connection.sendRequest(request);
1005
1066
  }
@@ -1007,7 +1068,7 @@ var AmuleClient = class {
1007
1068
  * Send a download command (PAUSE, RESUME, STOP, DELETE, etc.)
1008
1069
  */
1009
1070
  async sendDownloadCommand(hash, command) {
1010
- const { DownloadCommandRequest } = await import("./DownloadCommandRequest-B3KV_bvm.js");
1071
+ const { DownloadCommandRequest } = await import("./DownloadCommandRequest-DLU7RtYs.js");
1011
1072
  const request = new DownloadCommandRequest(hash, command);
1012
1073
  await this.connection.sendRequest(request);
1013
1074
  }
@@ -1039,7 +1100,7 @@ var AmuleClient = class {
1039
1100
  * Trigger a server list update from an URL.
1040
1101
  */
1041
1102
  async updateServerListFromUrl(url) {
1042
- const { ServerUpdateFromUrlRequest } = await import("./ServerUpdateFromUrlRequest-K8C_d0UQ.js");
1103
+ const { ServerUpdateFromUrlRequest } = await import("./ServerUpdateFromUrlRequest-BcvhRKgH.js");
1043
1104
  const request = new ServerUpdateFromUrlRequest(url);
1044
1105
  await this.connection.sendRequest(request);
1045
1106
  }
@@ -1047,7 +1108,7 @@ var AmuleClient = class {
1047
1108
  * Set upload priority for a shared file.
1048
1109
  */
1049
1110
  async setSharedFilePriority(hash, priority) {
1050
- const { SharedFilePriorityRequest } = await import("./SharedFilePriorityRequest-7BriqAcr.js");
1111
+ const { SharedFilePriorityRequest } = await import("./SharedFilePriorityRequest-CBqkaXaK.js");
1051
1112
  const request = new SharedFilePriorityRequest(hash, priority);
1052
1113
  await this.connection.sendRequest(request);
1053
1114
  }
@@ -1055,8 +1116,8 @@ var AmuleClient = class {
1055
1116
  * Get daemon preferences for general/connection/servers/security sections.
1056
1117
  */
1057
1118
  async getPreferences() {
1058
- const { GetPreferencesRequest } = await import("./GetPreferencesRequest-DsxlghqT.js");
1059
- const { PreferencesDetailsResponseParser } = await import("./PreferencesDetailsResponse-DapscVQi.js");
1119
+ const { GetPreferencesRequest } = await import("./GetPreferencesRequest-BlWGYNCP.js");
1120
+ const { PreferencesDetailsResponseParser } = await import("./PreferencesDetailsResponse-BX6qUoga.js");
1060
1121
  const request = new GetPreferencesRequest(2118);
1061
1122
  const packet = await this.connection.sendRequest(request);
1062
1123
  return PreferencesDetailsResponseParser.fromPacket(packet).preferences;
@@ -1066,10 +1127,10 @@ var AmuleClient = class {
1066
1127
  */
1067
1128
  async setPreferences(preferences) {
1068
1129
  if (!preferences.general && !preferences.connection && !preferences.servers && !preferences.security) return;
1069
- const { SetPreferencesRequest } = await import("./SetPreferencesRequest-KZ23VaBY.js");
1130
+ const { SetPreferencesRequest } = await import("./SetPreferencesRequest-CNJVmeQl.js");
1070
1131
  const request = new SetPreferencesRequest(preferences);
1071
1132
  await this.connection.sendRequest(request);
1072
1133
  }
1073
1134
  };
1074
1135
  //#endregion
1075
- export { AmuleClient, AmuleException, ChunkStatus, CommunicationException, CustomTag, DoubleTag, DownloadCommand, ECDetailLevel, ECOpCode, ECSearchType, ECTagName, EcPrefs, FileStatus, Flags, Hash16Tag, InvalidECException, Ipv4Tag, PARTSIZE, Packet, PacketParser, PacketWriter, ProtocolVersion, SearchType, ServerException, StringTag, Tag, UByteTag, UInt128Tag, UIntTag, ULongTag, UShortTag };
1136
+ export { AmuleClient, AmuleException, ChunkStatus, CommunicationException, CustomTag, DoubleTag, DownloadCommand, ECDetailLevel, ECOpCode, ECSearchFileDownloadStatus, ECSearchType, ECTagName, EcPrefs, FileStatus, Flags, Hash16Tag, InvalidECException, Ipv4Tag, PARTSIZE, Packet, PacketParser, PacketWriter, ProtocolVersion, SearchType, ServerException, StringTag, Tag, UByteTag, UInt128Tag, UIntTag, ULongTag, UShortTag };
@@ -0,0 +1,13 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ //#endregion
13
+ export { __exportAll as t };
@@ -20,5 +20,15 @@ function toOptionalIp(value) {
20
20
  if (value === void 0) return void 0;
21
21
  return formatIp(value);
22
22
  }
23
+ /**
24
+ * Read the own numeric value of a tag (e.g. the ECID carried by EC_TAG_PARTFILE / EC_TAG_CLIENT container tags).
25
+ * Returns undefined when the tag value is not numeric (string, buffer, ...).
26
+ */
27
+ function tagOwnNumericValue(tag) {
28
+ if (!tag) return void 0;
29
+ const value = tag.getValue();
30
+ if (typeof value === "number") return value;
31
+ if (typeof value === "bigint") return Number(value);
32
+ }
23
33
  //#endregion
24
- export { toOptionalNumber as i, toOptionalBool as n, toOptionalIp as r, formatIp as t };
34
+ export { toOptionalNumber as a, toOptionalIp as i, tagOwnNumericValue as n, toOptionalBool as r, formatIp as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amule-ec-client",
3
- "version": "0.6.1",
3
+ "version": "0.7.1",
4
4
  "description": "A TypeScript client for Amule EC API.",
5
5
  "author": "José Carlos HR <joecarlhr@gmail.com>",
6
6
  "license": "MIT",