@wumx-labs/noxaeapi-sdk 0.3.5 → 0.4.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.
- package/README.md +46 -0
- package/dist/index.cjs +137 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +238 -2
- package/dist/index.d.ts +238 -2
- package/dist/index.js +137 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -30,6 +30,11 @@ await client.server.broadcast("Hello from the SDK!");
|
|
|
30
30
|
const coins = await client.economy.getCurrencyBalance("coins", players[0].uuid);
|
|
31
31
|
const top = await client.leaderboards.getTop("mcmmo-power", 10);
|
|
32
32
|
const network = await client.network.statusAll();
|
|
33
|
+
|
|
34
|
+
// Resolve a name to a UUID, then get their one-call profile (identity,
|
|
35
|
+
// ban/whitelist status, Vault balance, and every leaderboard entry at once):
|
|
36
|
+
const { uuid } = await client.players.resolve("NoxlyDev");
|
|
37
|
+
const profile = await client.leaderboards.getPlayerProfile(uuid);
|
|
33
38
|
```
|
|
34
39
|
|
|
35
40
|
### From environment variables
|
|
@@ -109,6 +114,47 @@ Some modules only work depending on the target server's setup:
|
|
|
109
114
|
|
|
110
115
|
Calling these against a server without the corresponding feature enabled will fail (typically 404).
|
|
111
116
|
|
|
117
|
+
## NoxAeApi-Velocity network hub
|
|
118
|
+
|
|
119
|
+
If your network runs the **NoxAeApi-Velocity** proxy plugin, use
|
|
120
|
+
`NoxAeApiNetworkHubClient` instead of (or alongside) `NoxAeApiClient` —
|
|
121
|
+
point it at the hub's own REST port, not a backend server's port.
|
|
122
|
+
Backend servers push register/heartbeat updates to the hub over
|
|
123
|
+
WebSocket, so hub calls answer from its in-memory registry rather than
|
|
124
|
+
fanning out live requests the way `client.network.*` above does — and
|
|
125
|
+
the response shapes differ accordingly (e.g. `players()` is one flat
|
|
126
|
+
proxy-wide list, not a per-backend breakdown, and there's no hub
|
|
127
|
+
equivalent of `network/health` — see each node's `health` field in
|
|
128
|
+
`statusAll()`/`statusById()` instead).
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import { NoxAeApiNetworkHubClient } from "@wumx-labs/noxaeapi-sdk";
|
|
132
|
+
|
|
133
|
+
const hub = new NoxAeApiNetworkHubClient({
|
|
134
|
+
baseUrl: "http://localhost:9090", // the hub's api-port, not a backend's port
|
|
135
|
+
apiKey: "your-hub-key",
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const status = await hub.network.statusAll();
|
|
139
|
+
const players = await hub.network.players();
|
|
140
|
+
const found = await hub.network.findPlayer(players.players[0]?.uuid ?? "");
|
|
141
|
+
await hub.network.broadcast("Hello from the hub!");
|
|
142
|
+
|
|
143
|
+
// Reach a specific backend's own REST routes through the hub:
|
|
144
|
+
await hub.network.forward("survival", "POST", "server/exec", {
|
|
145
|
+
body: { command: "say hi" },
|
|
146
|
+
form: true,
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Or from environment variables (`NOXAEAPI_HUB_BASE_URL` / `NOXAEAPI_HUB_KEY`,
|
|
151
|
+
kept separate from `NoxAeApiClient.fromEnv()`'s `NOXAEAPI_*` vars so a
|
|
152
|
+
process can hold both clients at once):
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
const hub = NoxAeApiNetworkHubClient.fromEnv();
|
|
156
|
+
```
|
|
157
|
+
|
|
112
158
|
## Configuration
|
|
113
159
|
|
|
114
160
|
```ts
|
package/dist/index.cjs
CHANGED
|
@@ -250,6 +250,18 @@ var PlayersModule = class {
|
|
|
250
250
|
get(uuid) {
|
|
251
251
|
return this.http.request("GET", `players/${encodeURIComponent(uuid)}`);
|
|
252
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* Resolve a player name to their UUID using the server's own local player
|
|
255
|
+
* cache (works on both online-mode and offline-mode servers, unlike
|
|
256
|
+
* Mojang's public API - the UUID returned matches whatever this server
|
|
257
|
+
* actually uses for that player's stats/economy/etc). Checks currently
|
|
258
|
+
* online players first, then falls back to the server's offline player
|
|
259
|
+
* cache. Throws `NoxAeApiNotFoundError` if no known player with that name
|
|
260
|
+
* has ever joined.
|
|
261
|
+
*/
|
|
262
|
+
resolve(name) {
|
|
263
|
+
return this.http.request("GET", `players/resolve/${encodeURIComponent(name)}`);
|
|
264
|
+
}
|
|
253
265
|
/** Get a player's inventory in a specific world. */
|
|
254
266
|
getInventory(playerUuid, worldUuid) {
|
|
255
267
|
return this.http.request(
|
|
@@ -777,6 +789,39 @@ var LeaderboardModule = class {
|
|
|
777
789
|
query: { limit }
|
|
778
790
|
});
|
|
779
791
|
}
|
|
792
|
+
/**
|
|
793
|
+
* One-call player profile: identity, whitelist/ban status, Vault balance,
|
|
794
|
+
* and this player's entry in every registered leaderboard source. Built so
|
|
795
|
+
* clients never have to know how many leaderboard sources exist or scan
|
|
796
|
+
* top-N lists themselves.
|
|
797
|
+
*
|
|
798
|
+
* Throws `NoxAeApiNotFoundError` if no known player with that UUID has
|
|
799
|
+
* ever joined.
|
|
800
|
+
*/
|
|
801
|
+
getPlayerProfile(uuid) {
|
|
802
|
+
return this.http.request("GET", `players/${encodeURIComponent(uuid)}/profile`);
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
805
|
+
* Bulk player profiles — same shape as `getPlayerProfile`, for many
|
|
806
|
+
* players at once. Computes each leaderboard source's full ranking
|
|
807
|
+
* exactly once for the whole batch rather than once per player, so this
|
|
808
|
+
* is far cheaper than calling `getPlayerProfile` in a loop.
|
|
809
|
+
*
|
|
810
|
+
* Pass `uuids` to fetch an exact, specific set of players — unknown UUIDs
|
|
811
|
+
* are silently skipped rather than throwing. Omit `uuids` to page through
|
|
812
|
+
* every known player instead, using `page`/`limit`, optionally narrowed
|
|
813
|
+
* to only currently-online players via `onlineOnly`.
|
|
814
|
+
*/
|
|
815
|
+
getPlayerProfiles(opts = {}) {
|
|
816
|
+
return this.http.request("GET", "players/profiles", {
|
|
817
|
+
query: {
|
|
818
|
+
uuids: opts.uuids?.length ? opts.uuids.join(",") : void 0,
|
|
819
|
+
page: opts.page,
|
|
820
|
+
limit: opts.limit,
|
|
821
|
+
onlineOnly: opts.onlineOnly
|
|
822
|
+
}
|
|
823
|
+
});
|
|
824
|
+
}
|
|
780
825
|
};
|
|
781
826
|
|
|
782
827
|
// src/modules/network.ts
|
|
@@ -830,6 +875,59 @@ var NetworkModule = class {
|
|
|
830
875
|
}
|
|
831
876
|
};
|
|
832
877
|
|
|
878
|
+
// src/modules/network-hub.ts
|
|
879
|
+
var NetworkHubModule = class {
|
|
880
|
+
constructor(http) {
|
|
881
|
+
this.http = http;
|
|
882
|
+
}
|
|
883
|
+
http;
|
|
884
|
+
/** Get last-known status (from the registry) for every backend node that has ever registered. */
|
|
885
|
+
statusAll() {
|
|
886
|
+
return this.http.request("GET", "network/status");
|
|
887
|
+
}
|
|
888
|
+
/** Get last-known status for a single node by its configured ID. */
|
|
889
|
+
statusById(id) {
|
|
890
|
+
return this.http.request("GET", `network/status/${encodeURIComponent(id)}`);
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* List every player currently connected to the proxy, read straight from
|
|
894
|
+
* Velocity's own player registry (not reported by backends), along with
|
|
895
|
+
* which backend server each is on.
|
|
896
|
+
*/
|
|
897
|
+
players() {
|
|
898
|
+
return this.http.request("GET", "network/players");
|
|
899
|
+
}
|
|
900
|
+
/** Find which backend server a player is currently on by UUID (proxy-authoritative). */
|
|
901
|
+
findPlayer(uuid) {
|
|
902
|
+
return this.http.request("GET", `network/players/${encodeURIComponent(uuid)}`);
|
|
903
|
+
}
|
|
904
|
+
/**
|
|
905
|
+
* Broadcast a message directly to every player connected to the proxy.
|
|
906
|
+
* Unlike `NetworkModule.broadcast`, this doesn't forward to each
|
|
907
|
+
* backend's `/v1/chat/broadcast` — the proxy already has every player
|
|
908
|
+
* in hand — so it still delivers even to servers with no REST API of
|
|
909
|
+
* their own reachable from the hub.
|
|
910
|
+
*/
|
|
911
|
+
broadcast(message) {
|
|
912
|
+
return this.http.request("POST", "network/broadcast", { body: { message }, form: true });
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Forward an arbitrary request to a specific backend node's own REST
|
|
916
|
+
* API, e.g. `hub.forward("survival", "POST", "server/exec", { body:
|
|
917
|
+
* { command: "say hi" }, form: true })` reaches that backend's
|
|
918
|
+
* `POST /v1/server/exec` directly. Useful for endpoints the hub doesn't
|
|
919
|
+
* have a dedicated method for (economy, worlds, etc) without
|
|
920
|
+
* instantiating a second client pointed at that backend directly.
|
|
921
|
+
*
|
|
922
|
+
* The target backend responds according to its own route's expected
|
|
923
|
+
* encoding (form vs JSON) — pass `form: true` the same way you would for
|
|
924
|
+
* a direct call to that endpoint.
|
|
925
|
+
*/
|
|
926
|
+
forward(id, method, path, opts = {}) {
|
|
927
|
+
return this.http.request(method, `network/${encodeURIComponent(id)}/${path.replace(/^\/+/, "")}`, opts);
|
|
928
|
+
}
|
|
929
|
+
};
|
|
930
|
+
|
|
833
931
|
// src/socket.ts
|
|
834
932
|
function toWsUrl(baseUrl, route, apiKey) {
|
|
835
933
|
const url = new URL(`${baseUrl.replace(/\/+$/, "")}/v1/ws/${route.replace(/^\/+/, "")}`);
|
|
@@ -939,7 +1037,17 @@ var NoxAeApiClient = class _NoxAeApiClient {
|
|
|
939
1037
|
skills;
|
|
940
1038
|
/** Generic ranked leaderboards (economy currencies, mcMMO, AuraSkills, ...). */
|
|
941
1039
|
leaderboards;
|
|
942
|
-
/**
|
|
1040
|
+
/**
|
|
1041
|
+
* Only works if `network.enabled: true` is set in the server config.
|
|
1042
|
+
*
|
|
1043
|
+
* This is NoxAeApi-main's built-in polling aggregator — it lives on the
|
|
1044
|
+
* *same* backend server you're already connected to and fans requests
|
|
1045
|
+
* out to the other backends listed in that server's own config. If the
|
|
1046
|
+
* network is running NoxAeApi-Velocity instead, use
|
|
1047
|
+
* `NoxAeApiNetworkHubClient` (pointed at the proxy's hub port) rather
|
|
1048
|
+
* than this module — the hub replaces this aggregator with a push model
|
|
1049
|
+
* and its response shapes differ.
|
|
1050
|
+
*/
|
|
943
1051
|
network;
|
|
944
1052
|
http;
|
|
945
1053
|
baseUrl;
|
|
@@ -990,11 +1098,39 @@ var NoxAeApiClient = class _NoxAeApiClient {
|
|
|
990
1098
|
});
|
|
991
1099
|
}
|
|
992
1100
|
};
|
|
1101
|
+
var NoxAeApiNetworkHubClient = class _NoxAeApiNetworkHubClient {
|
|
1102
|
+
/** The network hub's aggregated view of every registered backend node. */
|
|
1103
|
+
network;
|
|
1104
|
+
constructor(options) {
|
|
1105
|
+
const http = new HttpEngine(options);
|
|
1106
|
+
this.network = new NetworkHubModule(http);
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Build a hub client from environment variables:
|
|
1110
|
+
* `NOXAEAPI_HUB_BASE_URL` and `NOXAEAPI_HUB_KEY`.
|
|
1111
|
+
*
|
|
1112
|
+
* Same convenience as `NoxAeApiClient.fromEnv()`, under separate env var
|
|
1113
|
+
* names so a process can hold both a backend client and a hub client at
|
|
1114
|
+
* once without the two colliding.
|
|
1115
|
+
*/
|
|
1116
|
+
static fromEnv(overrides = {}) {
|
|
1117
|
+
const env = globalThis.process?.env;
|
|
1118
|
+
const baseUrl = overrides.baseUrl ?? env?.NOXAEAPI_HUB_BASE_URL;
|
|
1119
|
+
const apiKey = overrides.apiKey ?? env?.NOXAEAPI_HUB_KEY;
|
|
1120
|
+
if (!baseUrl) {
|
|
1121
|
+
throw new Error(
|
|
1122
|
+
"NoxAeApiNetworkHubClient.fromEnv(): NOXAEAPI_HUB_BASE_URL is not set and no baseUrl override was given."
|
|
1123
|
+
);
|
|
1124
|
+
}
|
|
1125
|
+
return new _NoxAeApiNetworkHubClient({ ...overrides, baseUrl, apiKey });
|
|
1126
|
+
}
|
|
1127
|
+
};
|
|
993
1128
|
|
|
994
1129
|
exports.NoxAeApiClient = NoxAeApiClient;
|
|
995
1130
|
exports.NoxAeApiError = NoxAeApiError;
|
|
996
1131
|
exports.NoxAeApiForbiddenError = NoxAeApiForbiddenError;
|
|
997
1132
|
exports.NoxAeApiNetworkError = NoxAeApiNetworkError;
|
|
1133
|
+
exports.NoxAeApiNetworkHubClient = NoxAeApiNetworkHubClient;
|
|
998
1134
|
exports.NoxAeApiNotFoundError = NoxAeApiNotFoundError;
|
|
999
1135
|
exports.NoxAeApiRateLimitError = NoxAeApiRateLimitError;
|
|
1000
1136
|
exports.NoxAeApiServerError = NoxAeApiServerError;
|