@wumx-labs/noxaeapi-sdk 0.1.0

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.
@@ -0,0 +1,548 @@
1
+ interface RetryOptions {
2
+ /** Max number of attempts including the first one. Default 3. */
3
+ attempts?: number;
4
+ /** Base delay in ms used for exponential backoff. Default 300. */
5
+ baseDelayMs?: number;
6
+ /** Upper bound for any single backoff delay. Default 5000. */
7
+ maxDelayMs?: number;
8
+ }
9
+ interface NoxAeApiClientOptions {
10
+ /** Base URL of the server, e.g. "http://localhost:8080" or "https://mc.example.com". */
11
+ baseUrl: string;
12
+ /** The API key configured on the server (sent as the `key` header). */
13
+ apiKey?: string;
14
+ /** Request timeout in ms. Default 10000. */
15
+ timeoutMs?: number;
16
+ /** Retry behavior for network errors, 429s, and 5xx responses. */
17
+ retry?: RetryOptions | false;
18
+ /** Extra headers sent on every request. */
19
+ headers?: Record<string, string>;
20
+ /** Override fetch, mainly for testing. Defaults to the global fetch. */
21
+ fetchImpl?: typeof fetch;
22
+ }
23
+ type QueryValue = string | number | boolean | null | undefined;
24
+ declare class HttpEngine {
25
+ private readonly baseUrl;
26
+ private readonly apiKey?;
27
+ private readonly timeoutMs;
28
+ private readonly retry;
29
+ private readonly extraHeaders;
30
+ private readonly fetchImpl;
31
+ constructor(options: NoxAeApiClientOptions);
32
+ private buildUrl;
33
+ request<T>(method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH", path: string, opts?: {
34
+ body?: unknown;
35
+ query?: Record<string, QueryValue>;
36
+ }): Promise<T>;
37
+ }
38
+
39
+ interface OnlinePlayer {
40
+ uuid: string;
41
+ displayName: string;
42
+ address: string | null;
43
+ port: number | null;
44
+ exhaustion: number;
45
+ exp: number;
46
+ expLevel: number;
47
+ whitelisted: boolean;
48
+ banned: boolean;
49
+ op: boolean;
50
+ balance: number | null;
51
+ location: [number, number, number] | null;
52
+ dimension: string | null;
53
+ health: number;
54
+ hunger: number;
55
+ saturation: number;
56
+ gamemode: string;
57
+ lastPlayed: number;
58
+ authenticated: boolean | null;
59
+ registered: boolean | null;
60
+ }
61
+ interface OfflinePlayer {
62
+ uuid: string;
63
+ displayName: string;
64
+ whitelisted: boolean;
65
+ banned: boolean;
66
+ op: boolean;
67
+ balance: number | null;
68
+ lastPlayed: number;
69
+ }
70
+ interface ServerHealth {
71
+ cpus: number;
72
+ uptime: number;
73
+ totalMemory: number;
74
+ maxMemory: number;
75
+ freeMemory: number;
76
+ }
77
+ interface ServerBan {
78
+ target: string;
79
+ source: string | null;
80
+ reason: string | null;
81
+ expiration: string | null;
82
+ }
83
+ interface WhitelistEntry {
84
+ uuid: string;
85
+ name: string;
86
+ }
87
+ interface ServerInfo {
88
+ name: string;
89
+ motd: string;
90
+ version: string;
91
+ bukkitVersion: string;
92
+ tps: string;
93
+ health: ServerHealth;
94
+ bannedIps: ServerBan[];
95
+ bannedPlayers: ServerBan[];
96
+ whitelistedPlayers: WhitelistEntry[];
97
+ maxPlayers: number;
98
+ onlinePlayers: number;
99
+ }
100
+ interface World {
101
+ name: string;
102
+ uuid: string;
103
+ time: number;
104
+ storm: boolean;
105
+ thundering: boolean;
106
+ generateStructures: boolean;
107
+ allowAnimals: boolean;
108
+ allowMonsters: boolean;
109
+ difficulty: string;
110
+ environment: string;
111
+ seed: string;
112
+ }
113
+ interface Score {
114
+ entry: string;
115
+ value: number;
116
+ }
117
+ interface Objective {
118
+ name: string;
119
+ displayName: string;
120
+ criterion: string;
121
+ scores: Score[];
122
+ displaySlot: string | null;
123
+ }
124
+ interface Scoreboard {
125
+ objectives: string[];
126
+ entries: string[];
127
+ }
128
+ interface InventoryItem {
129
+ id: string;
130
+ count: number;
131
+ slot: number;
132
+ }
133
+ interface Plugin {
134
+ name: string;
135
+ enabled: boolean;
136
+ version: string;
137
+ website: string | null;
138
+ authors: string[];
139
+ depends: string[];
140
+ softDepends: string[];
141
+ apiVersion: string | null;
142
+ description: string | null;
143
+ }
144
+ interface EconomyInfo {
145
+ available: boolean;
146
+ [key: string]: unknown;
147
+ }
148
+ interface PlayerBalance {
149
+ uuid: string;
150
+ balance: number;
151
+ }
152
+ interface TopBalanceEntry {
153
+ uuid: string;
154
+ balance: number;
155
+ }
156
+ interface GroupInfo {
157
+ name: string;
158
+ permissions: string[];
159
+ }
160
+ interface PermissionNode {
161
+ permission: string;
162
+ value: boolean;
163
+ expiry: number;
164
+ server: string | null;
165
+ world: string | null;
166
+ }
167
+ interface Advancement {
168
+ key: string;
169
+ criteria: string[];
170
+ }
171
+ interface NoxAuthPlayerInfo {
172
+ uuid: string;
173
+ name: string;
174
+ registered: boolean;
175
+ authenticated: boolean;
176
+ lastIp: string | null;
177
+ lastLoginTime: number | null;
178
+ countryCode: string | null;
179
+ countryName: string | null;
180
+ }
181
+ interface PasswordCheckResult {
182
+ name: string;
183
+ valid: boolean;
184
+ }
185
+ interface PlayerStats {
186
+ uuid: string;
187
+ name: string;
188
+ kills: number;
189
+ deaths: number;
190
+ playtime: number;
191
+ blocksPlaced: number;
192
+ blocksBroken: number;
193
+ }
194
+
195
+ declare class PlayersModule {
196
+ private readonly http;
197
+ constructor(http: HttpEngine);
198
+ /** List currently online players. */
199
+ list(): Promise<OnlinePlayer[]>;
200
+ /** List all players the server has ever seen (online + offline). */
201
+ listAll(): Promise<OfflinePlayer[]>;
202
+ /** Get a single player by UUID (works for online or offline players). */
203
+ get(uuid: string): Promise<OnlinePlayer | OfflinePlayer>;
204
+ /** Get a player's inventory in a specific world. */
205
+ getInventory(playerUuid: string, worldUuid: string): Promise<InventoryItem[]>;
206
+ /** Kick an online player, optionally with a reason. */
207
+ kick(uuid: string, reason?: string): Promise<void>;
208
+ /** Ban a player, optionally with a reason and expiration. */
209
+ ban(uuid: string, reason?: string): Promise<void>;
210
+ /** Remove a player's ban. */
211
+ unban(uuid: string): Promise<void>;
212
+ /** Teleport a player to a location. */
213
+ teleport(uuid: string, location: {
214
+ x: number;
215
+ y: number;
216
+ z: number;
217
+ world?: string;
218
+ }): Promise<void>;
219
+ /** Change a player's gamemode. */
220
+ setGamemode(uuid: string, gamemode: "survival" | "creative" | "adventure" | "spectator"): Promise<void>;
221
+ /** Get kill/death/playtime/block stats for a player. */
222
+ getStats(uuid: string): Promise<PlayerStats>;
223
+ }
224
+
225
+ declare class EconomyModule {
226
+ private readonly http;
227
+ constructor(http: HttpEngine);
228
+ /** Get info about the connected economy provider (Impactor on Fabric, Vault on Bukkit/Spigot/Paper). */
229
+ info(): Promise<EconomyInfo>;
230
+ /** Get a player's balance. */
231
+ getBalance(uuid: string): Promise<PlayerBalance>;
232
+ /** Get the top balances leaderboard. */
233
+ getTopBalance(limit?: number): Promise<TopBalanceEntry[]>;
234
+ /** Pay an amount to a player (adds to their balance). */
235
+ pay(uuid: string, amount: number): Promise<void>;
236
+ /** Debit an amount from a player (subtracts from their balance). */
237
+ debit(uuid: string, amount: number): Promise<void>;
238
+ }
239
+
240
+ declare class ServerModule {
241
+ private readonly http;
242
+ constructor(http: HttpEngine);
243
+ /** Basic liveness check. */
244
+ ping(): Promise<{
245
+ status: string;
246
+ }>;
247
+ /** Get server info: version, MOTD, TPS, health, player counts, etc. */
248
+ info(): Promise<ServerInfo>;
249
+ /**
250
+ * Run a console command on the server.
251
+ * This is a privileged endpoint — requires a write-enabled API key.
252
+ */
253
+ exec(command: string): Promise<{
254
+ lines: string[];
255
+ }>;
256
+ /** List server operators. */
257
+ getOps(): Promise<WhitelistEntry[]>;
258
+ /** Grant operator status to a player. */
259
+ opPlayer(uuid: string): Promise<void>;
260
+ /** Revoke operator status from a player. */
261
+ deopPlayer(uuid: string): Promise<void>;
262
+ /** Get the current whitelist. */
263
+ getWhitelist(): Promise<WhitelistEntry[]>;
264
+ /** Add a player to the whitelist. */
265
+ addToWhitelist(uuid: string, name?: string): Promise<void>;
266
+ /** Remove a player from the whitelist. */
267
+ removeFromWhitelist(uuid: string): Promise<void>;
268
+ /**
269
+ * Restart the server.
270
+ * This is a privileged endpoint — requires a write-enabled API key.
271
+ */
272
+ restart(): Promise<void>;
273
+ /** Tail the server console log. */
274
+ getLogs(lines?: number): Promise<{
275
+ lines: string[];
276
+ }>;
277
+ /** Get entity counts on the server, optionally scoped to a world. */
278
+ getEntities(world?: string): Promise<{
279
+ world: string;
280
+ count: number;
281
+ entities: Record<string, number>;
282
+ }>;
283
+ /** Get loaded chunk counts, optionally scoped to a world. */
284
+ getChunks(world?: string): Promise<{
285
+ world: string;
286
+ loadedChunks: number;
287
+ }>;
288
+ /** Ban an IP address. */
289
+ banIp(ip: string, reason?: string): Promise<void>;
290
+ /** Get a scoreboard objective's scores by objective name. */
291
+ getObjective(name: string): Promise<unknown>;
292
+ /** List all scoreboard objectives and tracked entries. */
293
+ getScoreboard(): Promise<unknown>;
294
+ /** Set a score for an entry on an objective. */
295
+ setScore(objective: string, entry: string, value: number): Promise<void>;
296
+ /** Reset (remove) a score for an entry on an objective. */
297
+ resetScore(objective: string, entry: string): Promise<void>;
298
+ /** Broadcast a message to every player on the server. */
299
+ broadcast(message: string): Promise<void>;
300
+ /** Send a private message to a specific player. */
301
+ tell(uuid: string, message: string): Promise<void>;
302
+ }
303
+
304
+ declare class WorldsModule {
305
+ private readonly http;
306
+ constructor(http: HttpEngine);
307
+ /** List all worlds. */
308
+ list(): Promise<World[]>;
309
+ /** Save all worlds to disk. */
310
+ saveAll(): Promise<void>;
311
+ /** Get a download link/stream reference for all worlds. */
312
+ downloadAll(): Promise<{
313
+ url: string;
314
+ }>;
315
+ /** Get a single world by UUID. */
316
+ get(uuid: string): Promise<World>;
317
+ /** Save a specific world to disk. */
318
+ save(uuid: string): Promise<void>;
319
+ /** Get a download link/stream reference for a specific world. */
320
+ download(uuid: string): Promise<{
321
+ url: string;
322
+ }>;
323
+ /** Set the in-game time for a world. */
324
+ setTime(uuid: string, time: number): Promise<void>;
325
+ /** Set weather (storm/thundering) for a world. */
326
+ setWeather(uuid: string, weather: {
327
+ storm?: boolean;
328
+ thundering?: boolean;
329
+ }): Promise<void>;
330
+ /** Get entity counts within a specific world. */
331
+ getEntities(uuid: string): Promise<{
332
+ world: string;
333
+ count: number;
334
+ entities: Record<string, number>;
335
+ }>;
336
+ }
337
+
338
+ declare class PluginsModule {
339
+ private readonly http;
340
+ constructor(http: HttpEngine);
341
+ /** List all installed plugins/mods. */
342
+ list(): Promise<Plugin[]>;
343
+ /**
344
+ * Install a plugin from a URL or identifier.
345
+ * This is a privileged endpoint — requires a write-enabled API key.
346
+ */
347
+ install(source: string): Promise<void>;
348
+ /** Enable a plugin by name. */
349
+ enable(name: string): Promise<void>;
350
+ /** Disable a plugin by name. */
351
+ disable(name: string): Promise<void>;
352
+ }
353
+
354
+ declare class AdvancementsModule {
355
+ private readonly http;
356
+ constructor(http: HttpEngine);
357
+ /** List all advancements known to the server. */
358
+ list(): Promise<Advancement[]>;
359
+ }
360
+ declare class PlaceholdersModule {
361
+ private readonly http;
362
+ constructor(http: HttpEngine);
363
+ /**
364
+ * Replace PlaceholderAPI-style placeholders (e.g. "%player_name%") for a
365
+ * player, returning the resolved string.
366
+ */
367
+ replace(uuid: string, text: string): Promise<{
368
+ result: string;
369
+ }>;
370
+ }
371
+
372
+ /**
373
+ * Wraps the `/v1/luckperms/*` routes. These only exist on the server when
374
+ * the LuckPerms mod is loaded — calling any method here against a server
375
+ * without it will fail (typically a 404). There's no separate "is this
376
+ * available" flag from the SDK's side; check `client.plugins.list()` for
377
+ * LuckPerms if you need to branch on it ahead of time.
378
+ */
379
+ declare class LuckPermsModule {
380
+ private readonly http;
381
+ constructor(http: HttpEngine);
382
+ /** Get the groups a player belongs to. */
383
+ getPlayerGroups(uuid: string): Promise<string[]>;
384
+ /** Get a player's effective permission nodes. */
385
+ getPlayerPermissions(uuid: string): Promise<PermissionNode[]>;
386
+ /** Add a permission node to a player. */
387
+ addPlayerPermission(uuid: string, permission: string, value?: boolean): Promise<void>;
388
+ /** Check whether a player has a given permission. */
389
+ checkPlayerPermission(uuid: string, permission: string): Promise<{
390
+ permission: string;
391
+ value: boolean;
392
+ }>;
393
+ /** Remove a permission node from a player. */
394
+ removePlayerPermission(uuid: string, permission: string): Promise<void>;
395
+ /** Set a player's primary group. */
396
+ setPlayerGroup(uuid: string, group: string): Promise<void>;
397
+ /** Remove a group from a player. */
398
+ removePlayerGroup(uuid: string, groupName: string): Promise<void>;
399
+ /** List all known groups. */
400
+ getGroups(): Promise<string[]>;
401
+ /** Get the permissions attached to a specific group. */
402
+ getGroupPermissions(name: string): Promise<GroupInfo>;
403
+ }
404
+
405
+ /**
406
+ * Wraps the `/v1/noxauth/*` routes. These only work when `noxauth.enabled`
407
+ * is set to true in the server's noxaeapi-config.yml and the NoxAuth plugin
408
+ * is installed.
409
+ */
410
+ declare class NoxAuthModule {
411
+ private readonly http;
412
+ constructor(http: HttpEngine);
413
+ /** Get NoxAuth registration/auth info for a player by name. */
414
+ getPlayerAuth(name: string): Promise<NoxAuthPlayerInfo>;
415
+ /** Check whether a password matches a player's stored NoxAuth password. */
416
+ checkPassword(name: string, password: string): Promise<PasswordCheckResult>;
417
+ }
418
+
419
+ type NoxAeApiWsEvent = "open" | "close" | "error" | "console" | "event" | "message";
420
+ type Listener = (payload: unknown) => void;
421
+ interface NoxAeApiWsOptions {
422
+ /** Base URL of the server, same one passed to the client (http/https). */
423
+ baseUrl: string;
424
+ apiKey?: string;
425
+ /** Route suffix under the websocket base, e.g. "console" or "events". Default "events". */
426
+ route?: string;
427
+ /** Whether to auto-reconnect on unexpected close. Default true. */
428
+ autoReconnect?: boolean;
429
+ /** Max reconnect delay in ms. Default 30000. */
430
+ maxReconnectDelayMs?: number;
431
+ /** Override the WebSocket implementation, mainly for testing / non-browser runtimes. */
432
+ webSocketImpl?: typeof WebSocket;
433
+ }
434
+ /**
435
+ * Thin wrapper around the server's WebSocket endpoints (console tail and
436
+ * event broadcasts). Handles reconnection with exponential backoff so
437
+ * consumers can just attach listeners and not think about the socket
438
+ * lifecycle.
439
+ *
440
+ * Usage:
441
+ * ```ts
442
+ * const ws = client.connect({ route: "console" });
443
+ * ws.on("console", (line) => console.log(line));
444
+ * ws.on("close", () => console.log("disconnected"));
445
+ * ```
446
+ */
447
+ declare class NoxAeApiSocket {
448
+ private readonly options;
449
+ private socket;
450
+ private readonly listeners;
451
+ private reconnectAttempt;
452
+ private closedByUser;
453
+ private readonly wsImpl;
454
+ constructor(options: NoxAeApiWsOptions);
455
+ private open;
456
+ private scheduleReconnect;
457
+ on(event: NoxAeApiWsEvent, listener: Listener): () => void;
458
+ off(event: NoxAeApiWsEvent, listener: Listener): void;
459
+ private emit;
460
+ /** Send a raw payload over the socket, JSON-stringified if not already a string. */
461
+ send(payload: unknown): void;
462
+ /** Close the socket and stop reconnecting. */
463
+ close(): void;
464
+ }
465
+
466
+ declare class NoxAeApiClient {
467
+ readonly players: PlayersModule;
468
+ readonly economy: EconomyModule;
469
+ readonly server: ServerModule;
470
+ readonly worlds: WorldsModule;
471
+ readonly plugins: PluginsModule;
472
+ readonly advancements: AdvancementsModule;
473
+ readonly placeholders: PlaceholdersModule;
474
+ /** Only works if LuckPerms is loaded on the target server. */
475
+ readonly luckperms: LuckPermsModule;
476
+ /** Only works if `noxauth.enabled: true` is set in the server config. */
477
+ readonly noxauth: NoxAuthModule;
478
+ private readonly http;
479
+ private readonly baseUrl;
480
+ private readonly apiKey?;
481
+ constructor(options: NoxAeApiClientOptions);
482
+ /**
483
+ * Build a client from environment variables:
484
+ * `NOXAEAPI_BASE_URL` and `NOXAEAPI_KEY`.
485
+ *
486
+ * This is a convenience for Node-like runtimes; the SDK itself never
487
+ * reads `process.env` implicitly outside of this method, and does not
488
+ * load `.env` files — use a library like `dotenv` in your own app if
489
+ * you want that, then call `NoxAeApiClient.fromEnv()` after it's loaded.
490
+ */
491
+ static fromEnv(overrides?: Partial<NoxAeApiClientOptions>): NoxAeApiClient;
492
+ /** Open a WebSocket connection to the server (console tail or event stream). */
493
+ connect(options?: Partial<NoxAeApiWsOptions>): NoxAeApiSocket;
494
+ }
495
+
496
+ interface NoxAeApiErrorInfo {
497
+ status: number;
498
+ method: string;
499
+ path: string;
500
+ body?: unknown;
501
+ }
502
+ /**
503
+ * Base error thrown for any non-2xx response from a NoxAeApi server.
504
+ * Prefer catching the more specific subclasses below when you need to
505
+ * branch on the failure reason.
506
+ */
507
+ declare class NoxAeApiError extends Error {
508
+ readonly status: number;
509
+ readonly method: string;
510
+ readonly path: string;
511
+ readonly body?: unknown;
512
+ constructor(message: string, info: NoxAeApiErrorInfo);
513
+ }
514
+ /** 401 — the API key is missing or not recognized by the server. */
515
+ declare class NoxAeApiUnauthorizedError extends NoxAeApiError {
516
+ constructor(info: NoxAeApiErrorInfo);
517
+ }
518
+ /**
519
+ * 403 — the API key is valid but isn't allowed to call this endpoint
520
+ * (read-only key hitting a write route, or an endpoint restriction set
521
+ * on the key). This is a server-side permission decision; the SDK does
522
+ * not attempt to predict or enforce it client-side.
523
+ */
524
+ declare class NoxAeApiForbiddenError extends NoxAeApiError {
525
+ constructor(info: NoxAeApiErrorInfo);
526
+ }
527
+ /** 404 — the target resource (player, world, plugin, etc.) wasn't found. */
528
+ declare class NoxAeApiNotFoundError extends NoxAeApiError {
529
+ constructor(info: NoxAeApiErrorInfo);
530
+ }
531
+ /** 429 — rate limited. `retryAfterMs` is populated when the server sends a Retry-After header. */
532
+ declare class NoxAeApiRateLimitError extends NoxAeApiError {
533
+ readonly retryAfterMs?: number;
534
+ constructor(info: NoxAeApiErrorInfo, retryAfterMs?: number);
535
+ }
536
+ /** 5xx — the server errored out. Usually safe to retry. */
537
+ declare class NoxAeApiServerError extends NoxAeApiError {
538
+ constructor(info: NoxAeApiErrorInfo);
539
+ }
540
+ /** The request could not complete at all (DNS, connection refused, timeout, abort). */
541
+ declare class NoxAeApiNetworkError extends Error {
542
+ readonly method: string;
543
+ readonly path: string;
544
+ readonly cause?: unknown;
545
+ constructor(message: string, method: string, path: string, cause?: unknown);
546
+ }
547
+
548
+ export { type Advancement, type EconomyInfo, type GroupInfo, type InventoryItem, NoxAeApiClient, type NoxAeApiClientOptions, NoxAeApiError, NoxAeApiForbiddenError, NoxAeApiNetworkError, NoxAeApiNotFoundError, NoxAeApiRateLimitError, NoxAeApiServerError, NoxAeApiSocket, NoxAeApiUnauthorizedError, type NoxAeApiWsEvent, type NoxAeApiWsOptions, type NoxAuthPlayerInfo, type Objective, type OfflinePlayer, type OnlinePlayer, type PasswordCheckResult, type PermissionNode, type PlayerBalance, type PlayerStats, type Plugin, type RetryOptions, type Score, type Scoreboard, type ServerBan, type ServerHealth, type ServerInfo, type TopBalanceEntry, type WhitelistEntry, type World };