@wumx-labs/noxaeapi-sdk 0.1.0 → 0.1.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 CHANGED
@@ -69,6 +69,23 @@ try {
69
69
  }
70
70
  ```
71
71
 
72
+ ## Request encoding
73
+
74
+ The server is a Javalin app, and most endpoints read their body with
75
+ `ctx.formParam(...)` — i.e. `application/x-www-form-urlencoded` — rather
76
+ than JSON. The SDK follows the same split:
77
+
78
+ - **Form-urlencoded**: everything in `economy`, `players`, `server`
79
+ (except `luckperms`/`noxauth`), `worlds`, `plugins`, and `placeholders`.
80
+ - **JSON**: `client.luckperms.*` and `client.noxauth.checkPassword` only —
81
+ these are read server-side with `ctx.bodyAsClass(...)`.
82
+
83
+ If you're adding a new SDK method, check which one the corresponding
84
+ Javalin handler uses before wiring it up, and pass `form: true` to
85
+ `http.request(...)` if it's form-urlencoded (this is also the more common
86
+ case). Getting this wrong won't throw a type error — the request just
87
+ silently sends the wrong content type and the server won't see the field.
88
+
72
89
  ## Optional modules
73
90
 
74
91
  Some modules only work depending on the target server's setup:
@@ -97,4 +114,4 @@ new NoxAeApiClient({
97
114
 
98
115
  ## License
99
116
 
100
- MIT
117
+ MIT
package/dist/index.cjs CHANGED
@@ -107,7 +107,7 @@ var HttpEngine = class {
107
107
  this.fetchImpl = fetchImpl;
108
108
  }
109
109
  buildUrl(path, query) {
110
- const url = new URL(`${this.baseUrl}/${path.replace(/^\/+/, "")}`);
110
+ const url = new URL(`${this.baseUrl}/v1/${path.replace(/^\/+/, "")}`);
111
111
  if (query) {
112
112
  for (const [key, value] of Object.entries(query)) {
113
113
  if (value !== void 0 && value !== null) {
@@ -130,11 +130,20 @@ var HttpEngine = class {
130
130
  ...this.extraHeaders
131
131
  };
132
132
  if (this.apiKey) headers["key"] = this.apiKey;
133
- if (opts.body !== void 0) headers["Content-Type"] = "application/json";
133
+ let encodedBody;
134
+ if (opts.body !== void 0) {
135
+ if (opts.form) {
136
+ headers["Content-Type"] = "application/x-www-form-urlencoded";
137
+ encodedBody = encodeFormBody(opts.body);
138
+ } else {
139
+ headers["Content-Type"] = "application/json";
140
+ encodedBody = JSON.stringify(opts.body);
141
+ }
142
+ }
134
143
  const response = await this.fetchImpl(url, {
135
144
  method,
136
145
  headers,
137
- body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0,
146
+ body: encodedBody,
138
147
  signal: controller.signal
139
148
  });
140
149
  clearTimeout(timeout);
@@ -194,6 +203,19 @@ var HttpEngine = class {
194
203
  throw lastError instanceof Error ? lastError : new Error("Request failed after retries");
195
204
  }
196
205
  };
206
+ function encodeFormBody(body) {
207
+ const params = new URLSearchParams();
208
+ if (body && typeof body === "object") {
209
+ for (const [key, value] of Object.entries(body)) {
210
+ if (value === void 0 || value === null) continue;
211
+ params.set(
212
+ key,
213
+ typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value)
214
+ );
215
+ }
216
+ }
217
+ return params.toString();
218
+ }
197
219
  function safeJsonParse(text) {
198
220
  if (!text) return void 0;
199
221
  try {
@@ -238,13 +260,18 @@ var PlayersModule = class {
238
260
  /** Kick an online player, optionally with a reason. */
239
261
  kick(uuid, reason) {
240
262
  return this.http.request("POST", `players/${encodeURIComponent(uuid)}/kick`, {
241
- body: reason ? { reason } : void 0
263
+ body: reason ? { reason } : void 0,
264
+ form: true
242
265
  });
243
266
  }
244
- /** Ban a player, optionally with a reason and expiration. */
245
- ban(uuid, reason) {
267
+ /**
268
+ * Ban a player, optionally with a reason and an ISO-8601 expiry
269
+ * (e.g. "2030-01-01T00:00:00Z"). Omit `expiry` for a permanent ban.
270
+ */
271
+ ban(uuid, reason, expiry) {
246
272
  return this.http.request("POST", `players/${encodeURIComponent(uuid)}/ban`, {
247
- body: reason ? { reason } : void 0
273
+ body: reason || expiry ? { reason, expiry } : void 0,
274
+ form: true
248
275
  });
249
276
  }
250
277
  /** Remove a player's ban. */
@@ -254,13 +281,15 @@ var PlayersModule = class {
254
281
  /** Teleport a player to a location. */
255
282
  teleport(uuid, location) {
256
283
  return this.http.request("POST", `players/${encodeURIComponent(uuid)}/teleport`, {
257
- body: location
284
+ body: location,
285
+ form: true
258
286
  });
259
287
  }
260
288
  /** Change a player's gamemode. */
261
289
  setGamemode(uuid, gamemode) {
262
290
  return this.http.request("PUT", `players/${encodeURIComponent(uuid)}/gamemode`, {
263
- body: { gamemode }
291
+ body: { gamemode },
292
+ form: true
264
293
  });
265
294
  }
266
295
  /** Get kill/death/playtime/block stats for a player. */
@@ -291,11 +320,11 @@ var EconomyModule = class {
291
320
  }
292
321
  /** Pay an amount to a player (adds to their balance). */
293
322
  pay(uuid, amount) {
294
- return this.http.request("POST", "economy/pay", { body: { uuid, amount } });
323
+ return this.http.request("POST", "economy/pay", { body: { uuid, amount }, form: true });
295
324
  }
296
325
  /** Debit an amount from a player (subtracts from their balance). */
297
326
  debit(uuid, amount) {
298
- return this.http.request("POST", "economy/debit", { body: { uuid, amount } });
327
+ return this.http.request("POST", "economy/debit", { body: { uuid, amount }, form: true });
299
328
  }
300
329
  };
301
330
 
@@ -314,23 +343,40 @@ var ServerModule = class {
314
343
  return this.http.request("GET", "server");
315
344
  }
316
345
  /**
317
- * Run a console command on the server.
346
+ * Run a console command on the server, returning its console output.
318
347
  * This is a privileged endpoint — requires a write-enabled API key.
348
+ *
349
+ * `waitMs` is how long to wait for output before returning (server
350
+ * default 500ms if omitted). The server returns the joined output as a
351
+ * plain JSON string, not `{ lines }`.
319
352
  */
320
- exec(command) {
321
- return this.http.request("POST", "server/exec", { body: { command } });
353
+ exec(command, waitMs) {
354
+ return this.http.request("POST", "server/exec", {
355
+ body: { command, time: waitMs },
356
+ form: true
357
+ });
322
358
  }
323
359
  /** List server operators. */
324
360
  getOps() {
325
361
  return this.http.request("GET", "server/ops");
326
362
  }
327
- /** Grant operator status to a player. */
363
+ /**
364
+ * Grant operator status to a player.
365
+ *
366
+ * Server-side (`ServerApi.opPlayer`) reads `ctx.formParam("playerUuid")`,
367
+ * not "uuid" — the field name matters here.
368
+ */
328
369
  opPlayer(uuid) {
329
- return this.http.request("POST", "server/ops", { body: { uuid } });
370
+ return this.http.request("POST", "server/ops", { body: { playerUuid: uuid }, form: true });
330
371
  }
331
- /** Revoke operator status from a player. */
372
+ /**
373
+ * Revoke operator status from a player.
374
+ *
375
+ * Server-side (`ServerApi.deopPlayer`) reads this from the query string
376
+ * (`ctx.queryParam("playerUuid")`), not the request body.
377
+ */
332
378
  deopPlayer(uuid) {
333
- return this.http.request("DELETE", "server/ops", { body: { uuid } });
379
+ return this.http.request("DELETE", "server/ops", { query: { playerUuid: uuid } });
334
380
  }
335
381
  /** Get the current whitelist. */
336
382
  getWhitelist() {
@@ -338,11 +384,16 @@ var ServerModule = class {
338
384
  }
339
385
  /** Add a player to the whitelist. */
340
386
  addToWhitelist(uuid, name) {
341
- return this.http.request("POST", "server/whitelist", { body: { uuid, name } });
387
+ return this.http.request("POST", "server/whitelist", { body: { uuid, name }, form: true });
342
388
  }
343
- /** Remove a player from the whitelist. */
389
+ /**
390
+ * Remove a player from the whitelist.
391
+ *
392
+ * Server-side (`ServerApi.whitelistDelete`) reads `uuid`/`name` from the
393
+ * query string, not the request body.
394
+ */
344
395
  removeFromWhitelist(uuid) {
345
- return this.http.request("DELETE", "server/whitelist", { body: { uuid } });
396
+ return this.http.request("DELETE", "server/whitelist", { query: { uuid } });
346
397
  }
347
398
  /**
348
399
  * Restart the server.
@@ -365,7 +416,7 @@ var ServerModule = class {
365
416
  }
366
417
  /** Ban an IP address. */
367
418
  banIp(ip, reason) {
368
- return this.http.request("POST", "server/ban-ip", { body: { ip, reason } });
419
+ return this.http.request("POST", "server/ban-ip", { body: { ip, reason }, form: true });
369
420
  }
370
421
  /** Get a scoreboard objective's scores by objective name. */
371
422
  getObjective(name) {
@@ -378,22 +429,33 @@ var ServerModule = class {
378
429
  /** Set a score for an entry on an objective. */
379
430
  setScore(objective, entry, value) {
380
431
  return this.http.request("POST", `scoreboard/${encodeURIComponent(objective)}/score`, {
381
- body: { entry, value }
432
+ body: { entry, value },
433
+ form: true
382
434
  });
383
435
  }
384
- /** Reset (remove) a score for an entry on an objective. */
436
+ /**
437
+ * Reset (remove) a score for an entry on an objective.
438
+ *
439
+ * Server-side (`ServerApi.resetScore`) reads `entry` from the query
440
+ * string, not the request body.
441
+ */
385
442
  resetScore(objective, entry) {
386
443
  return this.http.request("DELETE", `scoreboard/${encodeURIComponent(objective)}/score`, {
387
- body: { entry }
444
+ query: { entry }
388
445
  });
389
446
  }
390
447
  /** Broadcast a message to every player on the server. */
391
448
  broadcast(message) {
392
- return this.http.request("POST", "chat/broadcast", { body: { message } });
449
+ return this.http.request("POST", "chat/broadcast", { body: { message }, form: true });
393
450
  }
394
- /** Send a private message to a specific player. */
451
+ /**
452
+ * Send a private message to a specific player.
453
+ *
454
+ * Server-side (`ServerApi.tellPost`) reads `ctx.formParam("playerUuid")`,
455
+ * not "uuid".
456
+ */
395
457
  tell(uuid, message) {
396
- return this.http.request("POST", "chat/tell", { body: { uuid, message } });
458
+ return this.http.request("POST", "chat/tell", { body: { playerUuid: uuid, message }, form: true });
397
459
  }
398
460
  };
399
461
 
@@ -427,16 +489,24 @@ var WorldsModule = class {
427
489
  download(uuid) {
428
490
  return this.http.request("GET", `worlds/${encodeURIComponent(uuid)}/download`);
429
491
  }
430
- /** Set the in-game time for a world. */
492
+ /** Set the in-game time for a world (0-24000). */
431
493
  setTime(uuid, time) {
432
494
  return this.http.request("POST", `worlds/${encodeURIComponent(uuid)}/time`, {
433
- body: { time }
495
+ body: { time },
496
+ form: true
434
497
  });
435
498
  }
436
- /** Set weather (storm/thundering) for a world. */
499
+ /**
500
+ * Set the weather for a world.
501
+ *
502
+ * Server-side (`WorldApi.setWorldWeather`) reads a single
503
+ * `ctx.formParam("weather")` enum string — "clear" | "rain" | "thunder" —
504
+ * not separate storm/thundering booleans.
505
+ */
437
506
  setWeather(uuid, weather) {
438
507
  return this.http.request("POST", `worlds/${encodeURIComponent(uuid)}/weather`, {
439
- body: weather
508
+ body: { weather },
509
+ form: true
440
510
  });
441
511
  }
442
512
  /** Get entity counts within a specific world. */
@@ -456,11 +526,15 @@ var PluginsModule = class {
456
526
  return this.http.request("GET", "plugins");
457
527
  }
458
528
  /**
459
- * Install a plugin from a URL or identifier.
529
+ * Install a plugin by downloading it from a direct URL.
460
530
  * This is a privileged endpoint — requires a write-enabled API key.
531
+ *
532
+ * Server-side (`PluginApi.installPlugin`) reads
533
+ * `ctx.formParam("downloadUrl")`, not "source", and the request must be
534
+ * form-urlencoded.
461
535
  */
462
- install(source) {
463
- return this.http.request("POST", "plugins", { body: { source } });
536
+ install(downloadUrl) {
537
+ return this.http.request("POST", "plugins", { body: { downloadUrl }, form: true });
464
538
  }
465
539
  /** Enable a plugin by name. */
466
540
  enable(name) {
@@ -489,12 +563,18 @@ var PlaceholdersModule = class {
489
563
  }
490
564
  http;
491
565
  /**
492
- * Replace PlaceholderAPI-style placeholders (e.g. "%player_name%") for a
493
- * player, returning the resolved string.
566
+ * Replace PlaceholderAPI-style placeholders (e.g. "%player_name%") in
567
+ * `message` for a player, returning the resolved string.
568
+ *
569
+ * Server-side this is `PAPIApi.replacePlaceholders`, which reads
570
+ * `ctx.formParam("message")` and `ctx.formParam("uuid")` — the field is
571
+ * literally named "message", not "text", and the whole body must be
572
+ * form-urlencoded.
494
573
  */
495
- replace(uuid, text) {
574
+ replace(uuid, message) {
496
575
  return this.http.request("POST", "placeholders/replace", {
497
- body: { uuid, text }
576
+ body: { uuid, message },
577
+ form: true
498
578
  });
499
579
  }
500
580
  };
@@ -587,7 +667,7 @@ var NoxAuthModule = class {
587
667
 
588
668
  // src/socket.ts
589
669
  function toWsUrl(baseUrl, route, apiKey) {
590
- const url = new URL(`${baseUrl.replace(/\/+$/, "")}/${route.replace(/^\/+/, "")}`);
670
+ const url = new URL(`${baseUrl.replace(/\/+$/, "")}/v1/ws/${route.replace(/^\/+/, "")}`);
591
671
  url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
592
672
  if (apiKey) url.searchParams.set("key", apiKey);
593
673
  return url.toString();
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/http-engine.ts","../src/modules/players.ts","../src/modules/economy.ts","../src/modules/server.ts","../src/modules/worlds.ts","../src/modules/plugins.ts","../src/modules/misc.ts","../src/modules/luckperms.ts","../src/modules/noxauth.ts","../src/socket.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export interface NoxAeApiErrorInfo {\n status: number;\n method: string;\n path: string;\n body?: unknown;\n}\n\n/**\n * Base error thrown for any non-2xx response from a NoxAeApi server.\n * Prefer catching the more specific subclasses below when you need to\n * branch on the failure reason.\n */\nexport class NoxAeApiError extends Error {\n readonly status: number;\n readonly method: string;\n readonly path: string;\n readonly body?: unknown;\n\n constructor(message: string, info: NoxAeApiErrorInfo) {\n super(message);\n this.name = \"NoxAeApiError\";\n this.status = info.status;\n this.method = info.method;\n this.path = info.path;\n this.body = info.body;\n }\n}\n\n/** 401 — the API key is missing or not recognized by the server. */\nexport class NoxAeApiUnauthorizedError extends NoxAeApiError {\n constructor(info: NoxAeApiErrorInfo) {\n super(\n `Unauthorized: the API key was missing or invalid for ${info.method} ${info.path}`,\n info,\n );\n this.name = \"NoxAeApiUnauthorizedError\";\n }\n}\n\n/**\n * 403 — the API key is valid but isn't allowed to call this endpoint\n * (read-only key hitting a write route, or an endpoint restriction set\n * on the key). This is a server-side permission decision; the SDK does\n * not attempt to predict or enforce it client-side.\n */\nexport class NoxAeApiForbiddenError extends NoxAeApiError {\n constructor(info: NoxAeApiErrorInfo) {\n super(\n `Forbidden: this API key does not have permission to call ${info.method} ${info.path}`,\n info,\n );\n this.name = \"NoxAeApiForbiddenError\";\n }\n}\n\n/** 404 — the target resource (player, world, plugin, etc.) wasn't found. */\nexport class NoxAeApiNotFoundError extends NoxAeApiError {\n constructor(info: NoxAeApiErrorInfo) {\n super(`Not found: ${info.method} ${info.path}`, info);\n this.name = \"NoxAeApiNotFoundError\";\n }\n}\n\n/** 429 — rate limited. `retryAfterMs` is populated when the server sends a Retry-After header. */\nexport class NoxAeApiRateLimitError extends NoxAeApiError {\n readonly retryAfterMs?: number;\n\n constructor(info: NoxAeApiErrorInfo, retryAfterMs?: number) {\n super(\n `Rate limited on ${info.method} ${info.path}${retryAfterMs ? ` — retry after ${retryAfterMs}ms` : \"\"}`,\n info,\n );\n this.name = \"NoxAeApiRateLimitError\";\n this.retryAfterMs = retryAfterMs;\n }\n}\n\n/** 5xx — the server errored out. Usually safe to retry. */\nexport class NoxAeApiServerError extends NoxAeApiError {\n constructor(info: NoxAeApiErrorInfo) {\n super(`Server error (${info.status}) on ${info.method} ${info.path}`, info);\n this.name = \"NoxAeApiServerError\";\n }\n}\n\n/** The request could not complete at all (DNS, connection refused, timeout, abort). */\nexport class NoxAeApiNetworkError extends Error {\n readonly method: string;\n readonly path: string;\n readonly cause?: unknown;\n\n constructor(message: string, method: string, path: string, cause?: unknown) {\n super(message);\n this.name = \"NoxAeApiNetworkError\";\n this.method = method;\n this.path = path;\n this.cause = cause;\n }\n}\n","import {\n NoxAeApiError,\n NoxAeApiForbiddenError,\n NoxAeApiNetworkError,\n NoxAeApiNotFoundError,\n NoxAeApiRateLimitError,\n NoxAeApiServerError,\n NoxAeApiUnauthorizedError,\n} from \"./errors.js\";\n\nexport interface RetryOptions {\n /** Max number of attempts including the first one. Default 3. */\n attempts?: number;\n /** Base delay in ms used for exponential backoff. Default 300. */\n baseDelayMs?: number;\n /** Upper bound for any single backoff delay. Default 5000. */\n maxDelayMs?: number;\n}\n\nexport interface NoxAeApiClientOptions {\n /** Base URL of the server, e.g. \"http://localhost:8080\" or \"https://mc.example.com\". */\n baseUrl: string;\n /** The API key configured on the server (sent as the `key` header). */\n apiKey?: string;\n /** Request timeout in ms. Default 10000. */\n timeoutMs?: number;\n /** Retry behavior for network errors, 429s, and 5xx responses. */\n retry?: RetryOptions | false;\n /** Extra headers sent on every request. */\n headers?: Record<string, string>;\n /** Override fetch, mainly for testing. Defaults to the global fetch. */\n fetchImpl?: typeof fetch;\n}\n\nconst DEFAULT_RETRY: Required<RetryOptions> = {\n attempts: 3,\n baseDelayMs: 300,\n maxDelayMs: 5000,\n};\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction backoffDelay(attempt: number, opts: Required<RetryOptions>): number {\n const exp = Math.min(opts.maxDelayMs, opts.baseDelayMs * 2 ** attempt);\n // full jitter\n return Math.floor(Math.random() * exp);\n}\n\nexport type QueryValue = string | number | boolean | null | undefined;\n\nexport class HttpEngine {\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n private readonly timeoutMs: number;\n private readonly retry: Required<RetryOptions> | false;\n private readonly extraHeaders: Record<string, string>;\n private readonly fetchImpl: typeof fetch;\n\n constructor(options: NoxAeApiClientOptions) {\n if (!options.baseUrl) {\n throw new Error(\"NoxAeApiClient requires a non-empty baseUrl\");\n }\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n this.timeoutMs = options.timeoutMs ?? 10_000;\n this.retry =\n options.retry === false\n ? false\n : { ...DEFAULT_RETRY, ...(options.retry ?? {}) };\n this.extraHeaders = options.headers ?? {};\n const fetchImpl = options.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n \"No fetch implementation available. Pass `fetchImpl` in options for this runtime.\",\n );\n }\n this.fetchImpl = fetchImpl;\n }\n\n private buildUrl(path: string, query?: Record<string, QueryValue>): string {\n const url = new URL(`${this.baseUrl}/${path.replace(/^\\/+/, \"\")}`);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n return url.toString();\n }\n\n async request<T>(\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\",\n path: string,\n opts: {\n body?: unknown;\n query?: Record<string, QueryValue>;\n } = {},\n ): Promise<T> {\n const url = this.buildUrl(path, opts.query);\n const maxAttempts = this.retry ? this.retry.attempts : 1;\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...this.extraHeaders,\n };\n if (this.apiKey) headers[\"key\"] = this.apiKey;\n if (opts.body !== undefined) headers[\"Content-Type\"] = \"application/json\";\n\n const response = await this.fetchImpl(url, {\n method,\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n if (response.status === 204) return undefined as T;\n const text = await response.text();\n return (text ? JSON.parse(text) : undefined) as T;\n }\n\n const errorBody = await response.text().catch(() => undefined);\n const parsedBody = safeJsonParse(errorBody);\n const info = { status: response.status, method, path, body: parsedBody };\n\n if (response.status === 401) throw new NoxAeApiUnauthorizedError(info);\n if (response.status === 403) throw new NoxAeApiForbiddenError(info);\n if (response.status === 404) throw new NoxAeApiNotFoundError(info);\n\n if (response.status === 429) {\n const retryAfterHeader = response.headers.get(\"Retry-After\");\n const retryAfterMs = retryAfterHeader\n ? parseRetryAfter(retryAfterHeader)\n : undefined;\n const err = new NoxAeApiRateLimitError(info, retryAfterMs);\n if (this.retry && attempt < maxAttempts - 1) {\n lastError = err;\n await sleep(retryAfterMs ?? backoffDelay(attempt, this.retry));\n continue;\n }\n throw err;\n }\n\n if (response.status >= 500) {\n const err = new NoxAeApiServerError(info);\n if (this.retry && attempt < maxAttempts - 1) {\n lastError = err;\n await sleep(backoffDelay(attempt, this.retry));\n continue;\n }\n throw err;\n }\n\n throw new NoxAeApiError(\n `Unexpected status ${response.status} on ${method} ${path}`,\n info,\n );\n } catch (err) {\n clearTimeout(timeout);\n\n if (err instanceof NoxAeApiError) throw err;\n\n const isAbort = err instanceof Error && err.name === \"AbortError\";\n const networkErr = new NoxAeApiNetworkError(\n isAbort\n ? `Request timed out after ${this.timeoutMs}ms: ${method} ${path}`\n : `Network error on ${method} ${path}: ${(err as Error).message}`,\n method,\n path,\n err,\n );\n\n if (this.retry && attempt < maxAttempts - 1) {\n lastError = networkErr;\n await sleep(backoffDelay(attempt, this.retry));\n continue;\n }\n throw networkErr;\n }\n }\n\n // Unreachable in practice, but keeps TS happy and surfaces the last error if we exit the loop.\n throw lastError instanceof Error\n ? lastError\n : new Error(\"Request failed after retries\");\n }\n}\n\nfunction safeJsonParse(text: string | undefined): unknown {\n if (!text) return undefined;\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction parseRetryAfter(headerValue: string): number | undefined {\n const seconds = Number(headerValue);\n if (!Number.isNaN(seconds)) return seconds * 1000;\n const date = Date.parse(headerValue);\n if (!Number.isNaN(date)) return Math.max(0, date - Date.now());\n return undefined;\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type {\n InventoryItem,\n OfflinePlayer,\n OnlinePlayer,\n PlayerStats,\n} from \"../types/models.js\";\n\nexport class PlayersModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** List currently online players. */\n list(): Promise<OnlinePlayer[]> {\n return this.http.request(\"GET\", \"players\");\n }\n\n /** List all players the server has ever seen (online + offline). */\n listAll(): Promise<OfflinePlayer[]> {\n return this.http.request(\"GET\", \"players/all\");\n }\n\n /** Get a single player by UUID (works for online or offline players). */\n get(uuid: string): Promise<OnlinePlayer | OfflinePlayer> {\n return this.http.request(\"GET\", `players/${encodeURIComponent(uuid)}`);\n }\n\n /** Get a player's inventory in a specific world. */\n getInventory(playerUuid: string, worldUuid: string): Promise<InventoryItem[]> {\n return this.http.request(\n \"GET\",\n `players/${encodeURIComponent(playerUuid)}/${encodeURIComponent(worldUuid)}/inventory`,\n );\n }\n\n /** Kick an online player, optionally with a reason. */\n kick(uuid: string, reason?: string): Promise<void> {\n return this.http.request(\"POST\", `players/${encodeURIComponent(uuid)}/kick`, {\n body: reason ? { reason } : undefined,\n });\n }\n\n /** Ban a player, optionally with a reason and expiration. */\n ban(uuid: string, reason?: string): Promise<void> {\n return this.http.request(\"POST\", `players/${encodeURIComponent(uuid)}/ban`, {\n body: reason ? { reason } : undefined,\n });\n }\n\n /** Remove a player's ban. */\n unban(uuid: string): Promise<void> {\n return this.http.request(\"DELETE\", `players/${encodeURIComponent(uuid)}/ban`);\n }\n\n /** Teleport a player to a location. */\n teleport(\n uuid: string,\n location: { x: number; y: number; z: number; world?: string },\n ): Promise<void> {\n return this.http.request(\"POST\", `players/${encodeURIComponent(uuid)}/teleport`, {\n body: location,\n });\n }\n\n /** Change a player's gamemode. */\n setGamemode(\n uuid: string,\n gamemode: \"survival\" | \"creative\" | \"adventure\" | \"spectator\",\n ): Promise<void> {\n return this.http.request(\"PUT\", `players/${encodeURIComponent(uuid)}/gamemode`, {\n body: { gamemode },\n });\n }\n\n /** Get kill/death/playtime/block stats for a player. */\n getStats(uuid: string): Promise<PlayerStats> {\n return this.http.request(\"GET\", `players/${encodeURIComponent(uuid)}/stats`);\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { EconomyInfo, PlayerBalance, TopBalanceEntry } from \"../types/models.js\";\n\nexport class EconomyModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** Get info about the connected economy provider (Impactor on Fabric, Vault on Bukkit/Spigot/Paper). */\n info(): Promise<EconomyInfo> {\n return this.http.request(\"GET\", \"economy\");\n }\n\n /** Get a player's balance. */\n getBalance(uuid: string): Promise<PlayerBalance> {\n return this.http.request(\"GET\", `economy/balance/${encodeURIComponent(uuid)}`);\n }\n\n /** Get the top balances leaderboard. */\n getTopBalance(limit?: number): Promise<TopBalanceEntry[]> {\n return this.http.request(\"GET\", \"economy/top\", {\n query: { limit },\n });\n }\n\n /** Pay an amount to a player (adds to their balance). */\n pay(uuid: string, amount: number): Promise<void> {\n return this.http.request(\"POST\", \"economy/pay\", { body: { uuid, amount } });\n }\n\n /** Debit an amount from a player (subtracts from their balance). */\n debit(uuid: string, amount: number): Promise<void> {\n return this.http.request(\"POST\", \"economy/debit\", { body: { uuid, amount } });\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { ServerInfo, WhitelistEntry } from \"../types/models.js\";\n\nexport class ServerModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** Basic liveness check. */\n ping(): Promise<{ status: string }> {\n return this.http.request(\"GET\", \"ping\");\n }\n\n /** Get server info: version, MOTD, TPS, health, player counts, etc. */\n info(): Promise<ServerInfo> {\n return this.http.request(\"GET\", \"server\");\n }\n\n /**\n * Run a console command on the server.\n * This is a privileged endpoint — requires a write-enabled API key.\n */\n exec(command: string): Promise<{ lines: string[] }> {\n return this.http.request(\"POST\", \"server/exec\", { body: { command } });\n }\n\n /** List server operators. */\n getOps(): Promise<WhitelistEntry[]> {\n return this.http.request(\"GET\", \"server/ops\");\n }\n\n /** Grant operator status to a player. */\n opPlayer(uuid: string): Promise<void> {\n return this.http.request(\"POST\", \"server/ops\", { body: { uuid } });\n }\n\n /** Revoke operator status from a player. */\n deopPlayer(uuid: string): Promise<void> {\n return this.http.request(\"DELETE\", \"server/ops\", { body: { uuid } });\n }\n\n /** Get the current whitelist. */\n getWhitelist(): Promise<WhitelistEntry[]> {\n return this.http.request(\"GET\", \"server/whitelist\");\n }\n\n /** Add a player to the whitelist. */\n addToWhitelist(uuid: string, name?: string): Promise<void> {\n return this.http.request(\"POST\", \"server/whitelist\", { body: { uuid, name } });\n }\n\n /** Remove a player from the whitelist. */\n removeFromWhitelist(uuid: string): Promise<void> {\n return this.http.request(\"DELETE\", \"server/whitelist\", { body: { uuid } });\n }\n\n /**\n * Restart the server.\n * This is a privileged endpoint — requires a write-enabled API key.\n */\n restart(): Promise<void> {\n return this.http.request(\"POST\", \"server/restart\");\n }\n\n /** Tail the server console log. */\n getLogs(lines?: number): Promise<{ lines: string[] }> {\n return this.http.request(\"GET\", \"server/logs\", { query: { lines } });\n }\n\n /** Get entity counts on the server, optionally scoped to a world. */\n getEntities(world?: string): Promise<{ world: string; count: number; entities: Record<string, number> }> {\n return this.http.request(\"GET\", \"server/entities\", { query: { world } });\n }\n\n /** Get loaded chunk counts, optionally scoped to a world. */\n getChunks(world?: string): Promise<{ world: string; loadedChunks: number }> {\n return this.http.request(\"GET\", \"server/chunks\", { query: { world } });\n }\n\n /** Ban an IP address. */\n banIp(ip: string, reason?: string): Promise<void> {\n return this.http.request(\"POST\", \"server/ban-ip\", { body: { ip, reason } });\n }\n\n /** Get a scoreboard objective's scores by objective name. */\n getObjective(name: string) {\n return this.http.request(\"GET\", `scoreboard/${encodeURIComponent(name)}`);\n }\n\n /** List all scoreboard objectives and tracked entries. */\n getScoreboard() {\n return this.http.request(\"GET\", \"scoreboard\");\n }\n\n /** Set a score for an entry on an objective. */\n setScore(objective: string, entry: string, value: number): Promise<void> {\n return this.http.request(\"POST\", `scoreboard/${encodeURIComponent(objective)}/score`, {\n body: { entry, value },\n });\n }\n\n /** Reset (remove) a score for an entry on an objective. */\n resetScore(objective: string, entry: string): Promise<void> {\n return this.http.request(\"DELETE\", `scoreboard/${encodeURIComponent(objective)}/score`, {\n body: { entry },\n });\n }\n\n /** Broadcast a message to every player on the server. */\n broadcast(message: string): Promise<void> {\n return this.http.request(\"POST\", \"chat/broadcast\", { body: { message } });\n }\n\n /** Send a private message to a specific player. */\n tell(uuid: string, message: string): Promise<void> {\n return this.http.request(\"POST\", \"chat/tell\", { body: { uuid, message } });\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { World } from \"../types/models.js\";\n\nexport class WorldsModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** List all worlds. */\n list(): Promise<World[]> {\n return this.http.request(\"GET\", \"worlds\");\n }\n\n /** Save all worlds to disk. */\n saveAll(): Promise<void> {\n return this.http.request(\"POST\", \"worlds/save\");\n }\n\n /** Get a download link/stream reference for all worlds. */\n downloadAll(): Promise<{ url: string }> {\n return this.http.request(\"GET\", \"worlds/download\");\n }\n\n /** Get a single world by UUID. */\n get(uuid: string): Promise<World> {\n return this.http.request(\"GET\", `worlds/${encodeURIComponent(uuid)}`);\n }\n\n /** Save a specific world to disk. */\n save(uuid: string): Promise<void> {\n return this.http.request(\"POST\", `worlds/${encodeURIComponent(uuid)}/save`);\n }\n\n /** Get a download link/stream reference for a specific world. */\n download(uuid: string): Promise<{ url: string }> {\n return this.http.request(\"GET\", `worlds/${encodeURIComponent(uuid)}/download`);\n }\n\n /** Set the in-game time for a world. */\n setTime(uuid: string, time: number): Promise<void> {\n return this.http.request(\"POST\", `worlds/${encodeURIComponent(uuid)}/time`, {\n body: { time },\n });\n }\n\n /** Set weather (storm/thundering) for a world. */\n setWeather(\n uuid: string,\n weather: { storm?: boolean; thundering?: boolean },\n ): Promise<void> {\n return this.http.request(\"POST\", `worlds/${encodeURIComponent(uuid)}/weather`, {\n body: weather,\n });\n }\n\n /** Get entity counts within a specific world. */\n getEntities(uuid: string): Promise<{ world: string; count: number; entities: Record<string, number> }> {\n return this.http.request(\"GET\", `worlds/${encodeURIComponent(uuid)}/entities`);\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { Plugin } from \"../types/models.js\";\n\nexport class PluginsModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** List all installed plugins/mods. */\n list(): Promise<Plugin[]> {\n return this.http.request(\"GET\", \"plugins\");\n }\n\n /**\n * Install a plugin from a URL or identifier.\n * This is a privileged endpoint — requires a write-enabled API key.\n */\n install(source: string): Promise<void> {\n return this.http.request(\"POST\", \"plugins\", { body: { source } });\n }\n\n /** Enable a plugin by name. */\n enable(name: string): Promise<void> {\n return this.http.request(\"POST\", `plugins/${encodeURIComponent(name)}/enable`);\n }\n\n /** Disable a plugin by name. */\n disable(name: string): Promise<void> {\n return this.http.request(\"POST\", `plugins/${encodeURIComponent(name)}/disable`);\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { Advancement } from \"../types/models.js\";\n\nexport class AdvancementsModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** List all advancements known to the server. */\n list(): Promise<Advancement[]> {\n return this.http.request(\"GET\", \"advancements\");\n }\n}\n\nexport class PlaceholdersModule {\n constructor(private readonly http: HttpEngine) {}\n\n /**\n * Replace PlaceholderAPI-style placeholders (e.g. \"%player_name%\") for a\n * player, returning the resolved string.\n */\n replace(uuid: string, text: string): Promise<{ result: string }> {\n return this.http.request(\"POST\", \"placeholders/replace\", {\n body: { uuid, text },\n });\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { GroupInfo, PermissionNode } from \"../types/models.js\";\n\n/**\n * Wraps the `/v1/luckperms/*` routes. These only exist on the server when\n * the LuckPerms mod is loaded — calling any method here against a server\n * without it will fail (typically a 404). There's no separate \"is this\n * available\" flag from the SDK's side; check `client.plugins.list()` for\n * LuckPerms if you need to branch on it ahead of time.\n */\nexport class LuckPermsModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** Get the groups a player belongs to. */\n getPlayerGroups(uuid: string): Promise<string[]> {\n return this.http.request(\"GET\", `luckperms/player/${encodeURIComponent(uuid)}/groups`);\n }\n\n /** Get a player's effective permission nodes. */\n getPlayerPermissions(uuid: string): Promise<PermissionNode[]> {\n return this.http.request(\n \"GET\",\n `luckperms/player/${encodeURIComponent(uuid)}/permissions`,\n );\n }\n\n /** Add a permission node to a player. */\n addPlayerPermission(uuid: string, permission: string, value = true): Promise<void> {\n return this.http.request(\n \"POST\",\n `luckperms/player/${encodeURIComponent(uuid)}/permission`,\n { body: { permission, value } },\n );\n }\n\n /** Check whether a player has a given permission. */\n checkPlayerPermission(\n uuid: string,\n permission: string,\n ): Promise<{ permission: string; value: boolean }> {\n return this.http.request(\n \"POST\",\n `luckperms/player/${encodeURIComponent(uuid)}/check-permission`,\n { body: { permission } },\n );\n }\n\n /** Remove a permission node from a player. */\n removePlayerPermission(uuid: string, permission: string): Promise<void> {\n return this.http.request(\n \"DELETE\",\n `luckperms/player/${encodeURIComponent(uuid)}/permission`,\n { body: { permission } },\n );\n }\n\n /** Set a player's primary group. */\n setPlayerGroup(uuid: string, group: string): Promise<void> {\n return this.http.request(\n \"POST\",\n `luckperms/player/${encodeURIComponent(uuid)}/group`,\n { body: { group } },\n );\n }\n\n /** Remove a group from a player. */\n removePlayerGroup(uuid: string, groupName: string): Promise<void> {\n return this.http.request(\n \"DELETE\",\n `luckperms/player/${encodeURIComponent(uuid)}/group/${encodeURIComponent(groupName)}`,\n );\n }\n\n /** List all known groups. */\n getGroups(): Promise<string[]> {\n return this.http.request(\"GET\", \"luckperms/groups\");\n }\n\n /** Get the permissions attached to a specific group. */\n getGroupPermissions(name: string): Promise<GroupInfo> {\n return this.http.request(\"GET\", `luckperms/group/${encodeURIComponent(name)}/permissions`);\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { NoxAuthPlayerInfo, PasswordCheckResult } from \"../types/models.js\";\n\n/**\n * Wraps the `/v1/noxauth/*` routes. These only work when `noxauth.enabled`\n * is set to true in the server's noxaeapi-config.yml and the NoxAuth plugin\n * is installed.\n */\nexport class NoxAuthModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** Get NoxAuth registration/auth info for a player by name. */\n getPlayerAuth(name: string): Promise<NoxAuthPlayerInfo> {\n return this.http.request(\"GET\", `noxauth/player/${encodeURIComponent(name)}`);\n }\n\n /** Check whether a password matches a player's stored NoxAuth password. */\n checkPassword(name: string, password: string): Promise<PasswordCheckResult> {\n return this.http.request(\n \"POST\",\n `noxauth/player/${encodeURIComponent(name)}/check-password`,\n { body: { password } },\n );\n }\n}\n","export type NoxAeApiWsEvent =\n | \"open\"\n | \"close\"\n | \"error\"\n | \"console\"\n | \"event\"\n | \"message\";\n\ntype Listener = (payload: unknown) => void;\n\nexport interface NoxAeApiWsOptions {\n /** Base URL of the server, same one passed to the client (http/https). */\n baseUrl: string;\n apiKey?: string;\n /** Route suffix under the websocket base, e.g. \"console\" or \"events\". Default \"events\". */\n route?: string;\n /** Whether to auto-reconnect on unexpected close. Default true. */\n autoReconnect?: boolean;\n /** Max reconnect delay in ms. Default 30000. */\n maxReconnectDelayMs?: number;\n /** Override the WebSocket implementation, mainly for testing / non-browser runtimes. */\n webSocketImpl?: typeof WebSocket;\n}\n\nfunction toWsUrl(baseUrl: string, route: string, apiKey?: string): string {\n const url = new URL(`${baseUrl.replace(/\\/+$/, \"\")}/${route.replace(/^\\/+/, \"\")}`);\n url.protocol = url.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n if (apiKey) url.searchParams.set(\"key\", apiKey);\n return url.toString();\n}\n\n/**\n * Thin wrapper around the server's WebSocket endpoints (console tail and\n * event broadcasts). Handles reconnection with exponential backoff so\n * consumers can just attach listeners and not think about the socket\n * lifecycle.\n *\n * Usage:\n * ```ts\n * const ws = client.connect({ route: \"console\" });\n * ws.on(\"console\", (line) => console.log(line));\n * ws.on(\"close\", () => console.log(\"disconnected\"));\n * ```\n */\nexport class NoxAeApiSocket {\n private socket: WebSocket | null = null;\n private readonly listeners = new Map<NoxAeApiWsEvent, Set<Listener>>();\n private reconnectAttempt = 0;\n private closedByUser = false;\n private readonly wsImpl: typeof WebSocket;\n\n constructor(private readonly options: NoxAeApiWsOptions) {\n const impl = options.webSocketImpl ?? (globalThis as { WebSocket?: typeof WebSocket }).WebSocket;\n if (!impl) {\n throw new Error(\n \"No WebSocket implementation available in this runtime. Pass `webSocketImpl` in options.\",\n );\n }\n this.wsImpl = impl;\n this.open();\n }\n\n private open(): void {\n const url = toWsUrl(this.options.baseUrl, this.options.route ?? \"events\", this.options.apiKey);\n const socket = new this.wsImpl(url);\n\n socket.onopen = () => {\n this.reconnectAttempt = 0;\n this.emit(\"open\", undefined);\n };\n\n socket.onmessage = (event: MessageEvent) => {\n const raw = typeof event.data === \"string\" ? event.data : String(event.data);\n const parsed = safeParse(raw);\n this.emit(\"message\", parsed);\n // Best-effort routing: if the payload has a `type` field of \"console\"\n // or \"event\", also emit on that specific channel.\n if (parsed && typeof parsed === \"object\" && \"type\" in (parsed as Record<string, unknown>)) {\n const type = (parsed as Record<string, unknown>).type;\n if (type === \"console\" || type === \"event\") this.emit(type, parsed);\n }\n };\n\n socket.onerror = (event) => {\n this.emit(\"error\", event);\n };\n\n socket.onclose = () => {\n this.emit(\"close\", undefined);\n if (!this.closedByUser && this.options.autoReconnect !== false) {\n this.scheduleReconnect();\n }\n };\n\n this.socket = socket;\n }\n\n private scheduleReconnect(): void {\n const maxDelay = this.options.maxReconnectDelayMs ?? 30_000;\n const delay = Math.min(maxDelay, 500 * 2 ** this.reconnectAttempt);\n this.reconnectAttempt++;\n setTimeout(() => {\n if (!this.closedByUser) this.open();\n }, delay);\n }\n\n on(event: NoxAeApiWsEvent, listener: Listener): () => void {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set());\n this.listeners.get(event)!.add(listener);\n return () => this.listeners.get(event)?.delete(listener);\n }\n\n off(event: NoxAeApiWsEvent, listener: Listener): void {\n this.listeners.get(event)?.delete(listener);\n }\n\n private emit(event: NoxAeApiWsEvent, payload: unknown): void {\n for (const listener of this.listeners.get(event) ?? []) listener(payload);\n }\n\n /** Send a raw payload over the socket, JSON-stringified if not already a string. */\n send(payload: unknown): void {\n if (!this.socket || this.socket.readyState !== this.wsImpl.OPEN) {\n throw new Error(\"Cannot send: socket is not open\");\n }\n this.socket.send(typeof payload === \"string\" ? payload : JSON.stringify(payload));\n }\n\n /** Close the socket and stop reconnecting. */\n close(): void {\n this.closedByUser = true;\n this.socket?.close();\n }\n}\n\nfunction safeParse(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n","import { HttpEngine, type NoxAeApiClientOptions } from \"./http-engine.js\";\nimport { PlayersModule } from \"./modules/players.js\";\nimport { EconomyModule } from \"./modules/economy.js\";\nimport { ServerModule } from \"./modules/server.js\";\nimport { WorldsModule } from \"./modules/worlds.js\";\nimport { PluginsModule } from \"./modules/plugins.js\";\nimport { AdvancementsModule, PlaceholdersModule } from \"./modules/misc.js\";\nimport { LuckPermsModule } from \"./modules/luckperms.js\";\nimport { NoxAuthModule } from \"./modules/noxauth.js\";\nimport { NoxAeApiSocket, type NoxAeApiWsOptions } from \"./socket.js\";\n\nexport class NoxAeApiClient {\n readonly players: PlayersModule;\n readonly economy: EconomyModule;\n readonly server: ServerModule;\n readonly worlds: WorldsModule;\n readonly plugins: PluginsModule;\n readonly advancements: AdvancementsModule;\n readonly placeholders: PlaceholdersModule;\n /** Only works if LuckPerms is loaded on the target server. */\n readonly luckperms: LuckPermsModule;\n /** Only works if `noxauth.enabled: true` is set in the server config. */\n readonly noxauth: NoxAuthModule;\n\n private readonly http: HttpEngine;\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n\n constructor(options: NoxAeApiClientOptions) {\n this.http = new HttpEngine(options);\n this.baseUrl = options.baseUrl;\n this.apiKey = options.apiKey;\n\n this.players = new PlayersModule(this.http);\n this.economy = new EconomyModule(this.http);\n this.server = new ServerModule(this.http);\n this.worlds = new WorldsModule(this.http);\n this.plugins = new PluginsModule(this.http);\n this.advancements = new AdvancementsModule(this.http);\n this.placeholders = new PlaceholdersModule(this.http);\n this.luckperms = new LuckPermsModule(this.http);\n this.noxauth = new NoxAuthModule(this.http);\n }\n\n /**\n * Build a client from environment variables:\n * `NOXAEAPI_BASE_URL` and `NOXAEAPI_KEY`.\n *\n * This is a convenience for Node-like runtimes; the SDK itself never\n * reads `process.env` implicitly outside of this method, and does not\n * load `.env` files — use a library like `dotenv` in your own app if\n * you want that, then call `NoxAeApiClient.fromEnv()` after it's loaded.\n */\n static fromEnv(overrides: Partial<NoxAeApiClientOptions> = {}): NoxAeApiClient {\n const env = (globalThis as { process?: { env?: Record<string, string | undefined> } })\n .process?.env;\n const baseUrl = overrides.baseUrl ?? env?.NOXAEAPI_BASE_URL;\n const apiKey = overrides.apiKey ?? env?.NOXAEAPI_KEY;\n\n if (!baseUrl) {\n throw new Error(\n \"NoxAeApiClient.fromEnv(): NOXAEAPI_BASE_URL is not set and no baseUrl override was given.\",\n );\n }\n\n return new NoxAeApiClient({ ...overrides, baseUrl, apiKey });\n }\n\n /** Open a WebSocket connection to the server (console tail or event stream). */\n connect(options: Partial<NoxAeApiWsOptions> = {}): NoxAeApiSocket {\n return new NoxAeApiSocket({\n baseUrl: this.baseUrl,\n apiKey: this.apiKey,\n ...options,\n });\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/http-engine.ts","../src/modules/players.ts","../src/modules/economy.ts","../src/modules/server.ts","../src/modules/worlds.ts","../src/modules/plugins.ts","../src/modules/misc.ts","../src/modules/luckperms.ts","../src/modules/noxauth.ts","../src/socket.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export interface NoxAeApiErrorInfo {\n status: number;\n method: string;\n path: string;\n body?: unknown;\n}\n\n/**\n * Base error thrown for any non-2xx response from a NoxAeApi server.\n * Prefer catching the more specific subclasses below when you need to\n * branch on the failure reason.\n */\nexport class NoxAeApiError extends Error {\n readonly status: number;\n readonly method: string;\n readonly path: string;\n readonly body?: unknown;\n\n constructor(message: string, info: NoxAeApiErrorInfo) {\n super(message);\n this.name = \"NoxAeApiError\";\n this.status = info.status;\n this.method = info.method;\n this.path = info.path;\n this.body = info.body;\n }\n}\n\n/** 401 — the API key is missing or not recognized by the server. */\nexport class NoxAeApiUnauthorizedError extends NoxAeApiError {\n constructor(info: NoxAeApiErrorInfo) {\n super(\n `Unauthorized: the API key was missing or invalid for ${info.method} ${info.path}`,\n info,\n );\n this.name = \"NoxAeApiUnauthorizedError\";\n }\n}\n\n/**\n * 403 — the API key is valid but isn't allowed to call this endpoint\n * (read-only key hitting a write route, or an endpoint restriction set\n * on the key). This is a server-side permission decision; the SDK does\n * not attempt to predict or enforce it client-side.\n */\nexport class NoxAeApiForbiddenError extends NoxAeApiError {\n constructor(info: NoxAeApiErrorInfo) {\n super(\n `Forbidden: this API key does not have permission to call ${info.method} ${info.path}`,\n info,\n );\n this.name = \"NoxAeApiForbiddenError\";\n }\n}\n\n/** 404 — the target resource (player, world, plugin, etc.) wasn't found. */\nexport class NoxAeApiNotFoundError extends NoxAeApiError {\n constructor(info: NoxAeApiErrorInfo) {\n super(`Not found: ${info.method} ${info.path}`, info);\n this.name = \"NoxAeApiNotFoundError\";\n }\n}\n\n/** 429 — rate limited. `retryAfterMs` is populated when the server sends a Retry-After header. */\nexport class NoxAeApiRateLimitError extends NoxAeApiError {\n readonly retryAfterMs?: number;\n\n constructor(info: NoxAeApiErrorInfo, retryAfterMs?: number) {\n super(\n `Rate limited on ${info.method} ${info.path}${retryAfterMs ? ` — retry after ${retryAfterMs}ms` : \"\"}`,\n info,\n );\n this.name = \"NoxAeApiRateLimitError\";\n this.retryAfterMs = retryAfterMs;\n }\n}\n\n/** 5xx — the server errored out. Usually safe to retry. */\nexport class NoxAeApiServerError extends NoxAeApiError {\n constructor(info: NoxAeApiErrorInfo) {\n super(`Server error (${info.status}) on ${info.method} ${info.path}`, info);\n this.name = \"NoxAeApiServerError\";\n }\n}\n\n/** The request could not complete at all (DNS, connection refused, timeout, abort). */\nexport class NoxAeApiNetworkError extends Error {\n readonly method: string;\n readonly path: string;\n readonly cause?: unknown;\n\n constructor(message: string, method: string, path: string, cause?: unknown) {\n super(message);\n this.name = \"NoxAeApiNetworkError\";\n this.method = method;\n this.path = path;\n this.cause = cause;\n }\n}\n","import {\n NoxAeApiError,\n NoxAeApiForbiddenError,\n NoxAeApiNetworkError,\n NoxAeApiNotFoundError,\n NoxAeApiRateLimitError,\n NoxAeApiServerError,\n NoxAeApiUnauthorizedError,\n} from \"./errors.js\";\n\nexport interface RetryOptions {\n /** Max number of attempts including the first one. Default 3. */\n attempts?: number;\n /** Base delay in ms used for exponential backoff. Default 300. */\n baseDelayMs?: number;\n /** Upper bound for any single backoff delay. Default 5000. */\n maxDelayMs?: number;\n}\n\nexport interface NoxAeApiClientOptions {\n /** Base URL of the server, e.g. \"http://localhost:8080\" or \"https://mc.example.com\". */\n baseUrl: string;\n /** The API key configured on the server (sent as the `key` header). */\n apiKey?: string;\n /** Request timeout in ms. Default 10000. */\n timeoutMs?: number;\n /** Retry behavior for network errors, 429s, and 5xx responses. */\n retry?: RetryOptions | false;\n /** Extra headers sent on every request. */\n headers?: Record<string, string>;\n /** Override fetch, mainly for testing. Defaults to the global fetch. */\n fetchImpl?: typeof fetch;\n}\n\nconst DEFAULT_RETRY: Required<RetryOptions> = {\n attempts: 3,\n baseDelayMs: 300,\n maxDelayMs: 5000,\n};\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction backoffDelay(attempt: number, opts: Required<RetryOptions>): number {\n const exp = Math.min(opts.maxDelayMs, opts.baseDelayMs * 2 ** attempt);\n // full jitter\n return Math.floor(Math.random() * exp);\n}\n\nexport type QueryValue = string | number | boolean | null | undefined;\n\nexport class HttpEngine {\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n private readonly timeoutMs: number;\n private readonly retry: Required<RetryOptions> | false;\n private readonly extraHeaders: Record<string, string>;\n private readonly fetchImpl: typeof fetch;\n\n constructor(options: NoxAeApiClientOptions) {\n if (!options.baseUrl) {\n throw new Error(\"NoxAeApiClient requires a non-empty baseUrl\");\n }\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n this.timeoutMs = options.timeoutMs ?? 10_000;\n this.retry =\n options.retry === false\n ? false\n : { ...DEFAULT_RETRY, ...(options.retry ?? {}) };\n this.extraHeaders = options.headers ?? {};\n const fetchImpl = options.fetchImpl ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n \"No fetch implementation available. Pass `fetchImpl` in options for this runtime.\",\n );\n }\n this.fetchImpl = fetchImpl;\n }\n\n private buildUrl(path: string, query?: Record<string, QueryValue>): string {\n const url = new URL(`${this.baseUrl}/v1/${path.replace(/^\\/+/, \"\")}`);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n return url.toString();\n }\n\n async request<T>(\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\",\n path: string,\n opts: {\n body?: unknown;\n query?: Record<string, QueryValue>;\n /**\n * Encode `body` as `application/x-www-form-urlencoded` (Javalin's\n * `ctx.formParam(...)`) instead of JSON. Most NoxAeApi endpoints\n * expect form-urlencoded bodies — only the LuckPerms and NoxAuth\n * routes use `ctx.bodyAsClass(...)` and need real JSON. Defaults to\n * `false` (JSON) to preserve existing behavior; each module call\n * site is responsible for passing `form: true` where the server\n * actually expects it.\n */\n form?: boolean;\n } = {},\n ): Promise<T> {\n const url = this.buildUrl(path, opts.query);\n const maxAttempts = this.retry ? this.retry.attempts : 1;\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...this.extraHeaders,\n };\n if (this.apiKey) headers[\"key\"] = this.apiKey;\n\n let encodedBody: string | undefined;\n if (opts.body !== undefined) {\n if (opts.form) {\n headers[\"Content-Type\"] = \"application/x-www-form-urlencoded\";\n encodedBody = encodeFormBody(opts.body);\n } else {\n headers[\"Content-Type\"] = \"application/json\";\n encodedBody = JSON.stringify(opts.body);\n }\n }\n\n const response = await this.fetchImpl(url, {\n method,\n headers,\n body: encodedBody,\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n if (response.status === 204) return undefined as T;\n const text = await response.text();\n return (text ? JSON.parse(text) : undefined) as T;\n }\n\n const errorBody = await response.text().catch(() => undefined);\n const parsedBody = safeJsonParse(errorBody);\n const info = { status: response.status, method, path, body: parsedBody };\n\n if (response.status === 401) throw new NoxAeApiUnauthorizedError(info);\n if (response.status === 403) throw new NoxAeApiForbiddenError(info);\n if (response.status === 404) throw new NoxAeApiNotFoundError(info);\n\n if (response.status === 429) {\n const retryAfterHeader = response.headers.get(\"Retry-After\");\n const retryAfterMs = retryAfterHeader\n ? parseRetryAfter(retryAfterHeader)\n : undefined;\n const err = new NoxAeApiRateLimitError(info, retryAfterMs);\n if (this.retry && attempt < maxAttempts - 1) {\n lastError = err;\n await sleep(retryAfterMs ?? backoffDelay(attempt, this.retry));\n continue;\n }\n throw err;\n }\n\n if (response.status >= 500) {\n const err = new NoxAeApiServerError(info);\n if (this.retry && attempt < maxAttempts - 1) {\n lastError = err;\n await sleep(backoffDelay(attempt, this.retry));\n continue;\n }\n throw err;\n }\n\n throw new NoxAeApiError(\n `Unexpected status ${response.status} on ${method} ${path}`,\n info,\n );\n } catch (err) {\n clearTimeout(timeout);\n\n if (err instanceof NoxAeApiError) throw err;\n\n const isAbort = err instanceof Error && err.name === \"AbortError\";\n const networkErr = new NoxAeApiNetworkError(\n isAbort\n ? `Request timed out after ${this.timeoutMs}ms: ${method} ${path}`\n : `Network error on ${method} ${path}: ${(err as Error).message}`,\n method,\n path,\n err,\n );\n\n if (this.retry && attempt < maxAttempts - 1) {\n lastError = networkErr;\n await sleep(backoffDelay(attempt, this.retry));\n continue;\n }\n throw networkErr;\n }\n }\n\n // Unreachable in practice, but keeps TS happy and surfaces the last error if we exit the loop.\n throw lastError instanceof Error\n ? lastError\n : new Error(\"Request failed after retries\");\n }\n}\n\n/**\n * Encodes a plain object as `application/x-www-form-urlencoded`, matching\n * what Javalin's `ctx.formParam(name)` reads server-side. `undefined`/`null`\n * values are omitted (so optional fields can be left out entirely rather\n * than sent as the literal string \"undefined\"). Non-primitive values are\n * JSON.stringify'd as a fallback, though no current endpoint needs that.\n */\nfunction encodeFormBody(body: unknown): string {\n const params = new URLSearchParams();\n if (body && typeof body === \"object\") {\n for (const [key, value] of Object.entries(body as Record<string, unknown>)) {\n if (value === undefined || value === null) continue;\n params.set(\n key,\n typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\"\n ? String(value)\n : JSON.stringify(value),\n );\n }\n }\n return params.toString();\n}\n\nfunction safeJsonParse(text: string | undefined): unknown {\n if (!text) return undefined;\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction parseRetryAfter(headerValue: string): number | undefined {\n const seconds = Number(headerValue);\n if (!Number.isNaN(seconds)) return seconds * 1000;\n const date = Date.parse(headerValue);\n if (!Number.isNaN(date)) return Math.max(0, date - Date.now());\n return undefined;\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type {\n InventoryItem,\n OfflinePlayer,\n OnlinePlayer,\n PlayerStats,\n} from \"../types/models.js\";\n\nexport class PlayersModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** List currently online players. */\n list(): Promise<OnlinePlayer[]> {\n return this.http.request(\"GET\", \"players\");\n }\n\n /** List all players the server has ever seen (online + offline). */\n listAll(): Promise<OfflinePlayer[]> {\n return this.http.request(\"GET\", \"players/all\");\n }\n\n /** Get a single player by UUID (works for online or offline players). */\n get(uuid: string): Promise<OnlinePlayer | OfflinePlayer> {\n return this.http.request(\"GET\", `players/${encodeURIComponent(uuid)}`);\n }\n\n /** Get a player's inventory in a specific world. */\n getInventory(playerUuid: string, worldUuid: string): Promise<InventoryItem[]> {\n return this.http.request(\n \"GET\",\n `players/${encodeURIComponent(playerUuid)}/${encodeURIComponent(worldUuid)}/inventory`,\n );\n }\n\n /** Kick an online player, optionally with a reason. */\n kick(uuid: string, reason?: string): Promise<void> {\n return this.http.request(\"POST\", `players/${encodeURIComponent(uuid)}/kick`, {\n body: reason ? { reason } : undefined,\n form: true,\n });\n }\n\n /**\n * Ban a player, optionally with a reason and an ISO-8601 expiry\n * (e.g. \"2030-01-01T00:00:00Z\"). Omit `expiry` for a permanent ban.\n */\n ban(uuid: string, reason?: string, expiry?: string): Promise<void> {\n return this.http.request(\"POST\", `players/${encodeURIComponent(uuid)}/ban`, {\n body: reason || expiry ? { reason, expiry } : undefined,\n form: true,\n });\n }\n\n /** Remove a player's ban. */\n unban(uuid: string): Promise<void> {\n return this.http.request(\"DELETE\", `players/${encodeURIComponent(uuid)}/ban`);\n }\n\n /** Teleport a player to a location. */\n teleport(\n uuid: string,\n location: { x: number; y: number; z: number; world?: string },\n ): Promise<void> {\n return this.http.request(\"POST\", `players/${encodeURIComponent(uuid)}/teleport`, {\n body: location,\n form: true,\n });\n }\n\n /** Change a player's gamemode. */\n setGamemode(\n uuid: string,\n gamemode: \"survival\" | \"creative\" | \"adventure\" | \"spectator\",\n ): Promise<void> {\n return this.http.request(\"PUT\", `players/${encodeURIComponent(uuid)}/gamemode`, {\n body: { gamemode },\n form: true,\n });\n }\n\n /** Get kill/death/playtime/block stats for a player. */\n getStats(uuid: string): Promise<PlayerStats> {\n return this.http.request(\"GET\", `players/${encodeURIComponent(uuid)}/stats`);\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { EconomyInfo, PlayerBalance, TopBalanceEntry } from \"../types/models.js\";\n\nexport class EconomyModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** Get info about the connected economy provider (Impactor on Fabric, Vault on Bukkit/Spigot/Paper). */\n info(): Promise<EconomyInfo> {\n return this.http.request(\"GET\", \"economy\");\n }\n\n /** Get a player's balance. */\n getBalance(uuid: string): Promise<PlayerBalance> {\n return this.http.request(\"GET\", `economy/balance/${encodeURIComponent(uuid)}`);\n }\n\n /** Get the top balances leaderboard. */\n getTopBalance(limit?: number): Promise<TopBalanceEntry[]> {\n return this.http.request(\"GET\", \"economy/top\", {\n query: { limit },\n });\n }\n\n /** Pay an amount to a player (adds to their balance). */\n pay(uuid: string, amount: number): Promise<void> {\n return this.http.request(\"POST\", \"economy/pay\", { body: { uuid, amount }, form: true });\n }\n\n /** Debit an amount from a player (subtracts from their balance). */\n debit(uuid: string, amount: number): Promise<void> {\n return this.http.request(\"POST\", \"economy/debit\", { body: { uuid, amount }, form: true });\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { ServerInfo, WhitelistEntry } from \"../types/models.js\";\n\nexport class ServerModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** Basic liveness check. */\n ping(): Promise<{ status: string }> {\n return this.http.request(\"GET\", \"ping\");\n }\n\n /** Get server info: version, MOTD, TPS, health, player counts, etc. */\n info(): Promise<ServerInfo> {\n return this.http.request(\"GET\", \"server\");\n }\n\n /**\n * Run a console command on the server, returning its console output.\n * This is a privileged endpoint — requires a write-enabled API key.\n *\n * `waitMs` is how long to wait for output before returning (server\n * default 500ms if omitted). The server returns the joined output as a\n * plain JSON string, not `{ lines }`.\n */\n exec(command: string, waitMs?: number): Promise<string> {\n return this.http.request(\"POST\", \"server/exec\", {\n body: { command, time: waitMs },\n form: true,\n });\n }\n\n /** List server operators. */\n getOps(): Promise<WhitelistEntry[]> {\n return this.http.request(\"GET\", \"server/ops\");\n }\n\n /**\n * Grant operator status to a player.\n *\n * Server-side (`ServerApi.opPlayer`) reads `ctx.formParam(\"playerUuid\")`,\n * not \"uuid\" — the field name matters here.\n */\n opPlayer(uuid: string): Promise<void> {\n return this.http.request(\"POST\", \"server/ops\", { body: { playerUuid: uuid }, form: true });\n }\n\n /**\n * Revoke operator status from a player.\n *\n * Server-side (`ServerApi.deopPlayer`) reads this from the query string\n * (`ctx.queryParam(\"playerUuid\")`), not the request body.\n */\n deopPlayer(uuid: string): Promise<void> {\n return this.http.request(\"DELETE\", \"server/ops\", { query: { playerUuid: uuid } });\n }\n\n /** Get the current whitelist. */\n getWhitelist(): Promise<WhitelistEntry[]> {\n return this.http.request(\"GET\", \"server/whitelist\");\n }\n\n /** Add a player to the whitelist. */\n addToWhitelist(uuid: string, name?: string): Promise<void> {\n return this.http.request(\"POST\", \"server/whitelist\", { body: { uuid, name }, form: true });\n }\n\n /**\n * Remove a player from the whitelist.\n *\n * Server-side (`ServerApi.whitelistDelete`) reads `uuid`/`name` from the\n * query string, not the request body.\n */\n removeFromWhitelist(uuid: string): Promise<void> {\n return this.http.request(\"DELETE\", \"server/whitelist\", { query: { uuid } });\n }\n\n /**\n * Restart the server.\n * This is a privileged endpoint — requires a write-enabled API key.\n */\n restart(): Promise<void> {\n return this.http.request(\"POST\", \"server/restart\");\n }\n\n /** Tail the server console log. */\n getLogs(lines?: number): Promise<{ lines: string[] }> {\n return this.http.request(\"GET\", \"server/logs\", { query: { lines } });\n }\n\n /** Get entity counts on the server, optionally scoped to a world. */\n getEntities(world?: string): Promise<{ world: string; count: number; entities: Record<string, number> }> {\n return this.http.request(\"GET\", \"server/entities\", { query: { world } });\n }\n\n /** Get loaded chunk counts, optionally scoped to a world. */\n getChunks(world?: string): Promise<{ world: string; loadedChunks: number }> {\n return this.http.request(\"GET\", \"server/chunks\", { query: { world } });\n }\n\n /** Ban an IP address. */\n banIp(ip: string, reason?: string): Promise<void> {\n return this.http.request(\"POST\", \"server/ban-ip\", { body: { ip, reason }, form: true });\n }\n\n /** Get a scoreboard objective's scores by objective name. */\n getObjective(name: string) {\n return this.http.request(\"GET\", `scoreboard/${encodeURIComponent(name)}`);\n }\n\n /** List all scoreboard objectives and tracked entries. */\n getScoreboard() {\n return this.http.request(\"GET\", \"scoreboard\");\n }\n\n /** Set a score for an entry on an objective. */\n setScore(objective: string, entry: string, value: number): Promise<void> {\n return this.http.request(\"POST\", `scoreboard/${encodeURIComponent(objective)}/score`, {\n body: { entry, value },\n form: true,\n });\n }\n\n /**\n * Reset (remove) a score for an entry on an objective.\n *\n * Server-side (`ServerApi.resetScore`) reads `entry` from the query\n * string, not the request body.\n */\n resetScore(objective: string, entry: string): Promise<void> {\n return this.http.request(\"DELETE\", `scoreboard/${encodeURIComponent(objective)}/score`, {\n query: { entry },\n });\n }\n\n /** Broadcast a message to every player on the server. */\n broadcast(message: string): Promise<void> {\n return this.http.request(\"POST\", \"chat/broadcast\", { body: { message }, form: true });\n }\n\n /**\n * Send a private message to a specific player.\n *\n * Server-side (`ServerApi.tellPost`) reads `ctx.formParam(\"playerUuid\")`,\n * not \"uuid\".\n */\n tell(uuid: string, message: string): Promise<void> {\n return this.http.request(\"POST\", \"chat/tell\", { body: { playerUuid: uuid, message }, form: true });\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { World } from \"../types/models.js\";\n\nexport class WorldsModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** List all worlds. */\n list(): Promise<World[]> {\n return this.http.request(\"GET\", \"worlds\");\n }\n\n /** Save all worlds to disk. */\n saveAll(): Promise<void> {\n return this.http.request(\"POST\", \"worlds/save\");\n }\n\n /** Get a download link/stream reference for all worlds. */\n downloadAll(): Promise<{ url: string }> {\n return this.http.request(\"GET\", \"worlds/download\");\n }\n\n /** Get a single world by UUID. */\n get(uuid: string): Promise<World> {\n return this.http.request(\"GET\", `worlds/${encodeURIComponent(uuid)}`);\n }\n\n /** Save a specific world to disk. */\n save(uuid: string): Promise<void> {\n return this.http.request(\"POST\", `worlds/${encodeURIComponent(uuid)}/save`);\n }\n\n /** Get a download link/stream reference for a specific world. */\n download(uuid: string): Promise<{ url: string }> {\n return this.http.request(\"GET\", `worlds/${encodeURIComponent(uuid)}/download`);\n }\n\n /** Set the in-game time for a world (0-24000). */\n setTime(uuid: string, time: number): Promise<void> {\n return this.http.request(\"POST\", `worlds/${encodeURIComponent(uuid)}/time`, {\n body: { time },\n form: true,\n });\n }\n\n /**\n * Set the weather for a world.\n *\n * Server-side (`WorldApi.setWorldWeather`) reads a single\n * `ctx.formParam(\"weather\")` enum string — \"clear\" | \"rain\" | \"thunder\" —\n * not separate storm/thundering booleans.\n */\n setWeather(uuid: string, weather: \"clear\" | \"rain\" | \"thunder\"): Promise<void> {\n return this.http.request(\"POST\", `worlds/${encodeURIComponent(uuid)}/weather`, {\n body: { weather },\n form: true,\n });\n }\n\n /** Get entity counts within a specific world. */\n getEntities(uuid: string): Promise<{ world: string; count: number; entities: Record<string, number> }> {\n return this.http.request(\"GET\", `worlds/${encodeURIComponent(uuid)}/entities`);\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { Plugin } from \"../types/models.js\";\n\nexport class PluginsModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** List all installed plugins/mods. */\n list(): Promise<Plugin[]> {\n return this.http.request(\"GET\", \"plugins\");\n }\n\n /**\n * Install a plugin by downloading it from a direct URL.\n * This is a privileged endpoint — requires a write-enabled API key.\n *\n * Server-side (`PluginApi.installPlugin`) reads\n * `ctx.formParam(\"downloadUrl\")`, not \"source\", and the request must be\n * form-urlencoded.\n */\n install(downloadUrl: string): Promise<void> {\n return this.http.request(\"POST\", \"plugins\", { body: { downloadUrl }, form: true });\n }\n\n /** Enable a plugin by name. */\n enable(name: string): Promise<void> {\n return this.http.request(\"POST\", `plugins/${encodeURIComponent(name)}/enable`);\n }\n\n /** Disable a plugin by name. */\n disable(name: string): Promise<void> {\n return this.http.request(\"POST\", `plugins/${encodeURIComponent(name)}/disable`);\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { Advancement } from \"../types/models.js\";\n\nexport class AdvancementsModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** List all advancements known to the server. */\n list(): Promise<Advancement[]> {\n return this.http.request(\"GET\", \"advancements\");\n }\n}\n\nexport class PlaceholdersModule {\n constructor(private readonly http: HttpEngine) {}\n\n /**\n * Replace PlaceholderAPI-style placeholders (e.g. \"%player_name%\") in\n * `message` for a player, returning the resolved string.\n *\n * Server-side this is `PAPIApi.replacePlaceholders`, which reads\n * `ctx.formParam(\"message\")` and `ctx.formParam(\"uuid\")` — the field is\n * literally named \"message\", not \"text\", and the whole body must be\n * form-urlencoded.\n */\n replace(uuid: string, message: string): Promise<string> {\n return this.http.request(\"POST\", \"placeholders/replace\", {\n body: { uuid, message },\n form: true,\n });\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { GroupInfo, PermissionNode } from \"../types/models.js\";\n\n/**\n * Wraps the `/v1/luckperms/*` routes. These only exist on the server when\n * the LuckPerms mod is loaded — calling any method here against a server\n * without it will fail (typically a 404). There's no separate \"is this\n * available\" flag from the SDK's side; check `client.plugins.list()` for\n * LuckPerms if you need to branch on it ahead of time.\n *\n * Unlike most other modules, these POST/DELETE bodies are sent as real\n * JSON (the server reads them with `ctx.bodyAsClass(...)`, not\n * `ctx.formParam(...)`) — do not add `form: true` to these calls.\n */\nexport class LuckPermsModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** Get the groups a player belongs to. */\n getPlayerGroups(uuid: string): Promise<string[]> {\n return this.http.request(\"GET\", `luckperms/player/${encodeURIComponent(uuid)}/groups`);\n }\n\n /** Get a player's effective permission nodes. */\n getPlayerPermissions(uuid: string): Promise<PermissionNode[]> {\n return this.http.request(\n \"GET\",\n `luckperms/player/${encodeURIComponent(uuid)}/permissions`,\n );\n }\n\n /** Add a permission node to a player. */\n addPlayerPermission(uuid: string, permission: string, value = true): Promise<void> {\n return this.http.request(\n \"POST\",\n `luckperms/player/${encodeURIComponent(uuid)}/permission`,\n { body: { permission, value } },\n );\n }\n\n /** Check whether a player has a given permission. */\n checkPlayerPermission(\n uuid: string,\n permission: string,\n ): Promise<{ permission: string; value: boolean }> {\n return this.http.request(\n \"POST\",\n `luckperms/player/${encodeURIComponent(uuid)}/check-permission`,\n { body: { permission } },\n );\n }\n\n /** Remove a permission node from a player. */\n removePlayerPermission(uuid: string, permission: string): Promise<void> {\n return this.http.request(\n \"DELETE\",\n `luckperms/player/${encodeURIComponent(uuid)}/permission`,\n { body: { permission } },\n );\n }\n\n /** Set a player's primary group. */\n setPlayerGroup(uuid: string, group: string): Promise<void> {\n return this.http.request(\n \"POST\",\n `luckperms/player/${encodeURIComponent(uuid)}/group`,\n { body: { group } },\n );\n }\n\n /** Remove a group from a player. */\n removePlayerGroup(uuid: string, groupName: string): Promise<void> {\n return this.http.request(\n \"DELETE\",\n `luckperms/player/${encodeURIComponent(uuid)}/group/${encodeURIComponent(groupName)}`,\n );\n }\n\n /** List all known groups. */\n getGroups(): Promise<string[]> {\n return this.http.request(\"GET\", \"luckperms/groups\");\n }\n\n /** Get the permissions attached to a specific group. */\n getGroupPermissions(name: string): Promise<GroupInfo> {\n return this.http.request(\"GET\", `luckperms/group/${encodeURIComponent(name)}/permissions`);\n }\n}\n","import type { HttpEngine } from \"../http-engine.js\";\nimport type { NoxAuthPlayerInfo, PasswordCheckResult } from \"../types/models.js\";\n\n/**\n * Wraps the `/v1/noxauth/*` routes. These only work when `noxauth.enabled`\n * is set to true in the server's noxaeapi-config.yml and the NoxAuth plugin\n * is installed.\n *\n * `checkPassword`'s body is sent as real JSON (the server parses it with\n * `GsonSingleton...fromJson(ctx.body(), PasswordCheckRequest.class)`, not\n * `ctx.formParam(...)`) — do not add `form: true` to that call.\n */\nexport class NoxAuthModule {\n constructor(private readonly http: HttpEngine) {}\n\n /** Get NoxAuth registration/auth info for a player by name. */\n getPlayerAuth(name: string): Promise<NoxAuthPlayerInfo> {\n return this.http.request(\"GET\", `noxauth/player/${encodeURIComponent(name)}`);\n }\n\n /** Check whether a password matches a player's stored NoxAuth password. */\n checkPassword(name: string, password: string): Promise<PasswordCheckResult> {\n return this.http.request(\n \"POST\",\n `noxauth/player/${encodeURIComponent(name)}/check-password`,\n { body: { password } },\n );\n }\n}\n","export type NoxAeApiWsEvent =\n | \"open\"\n | \"close\"\n | \"error\"\n | \"console\"\n | \"event\"\n | \"message\";\n\ntype Listener = (payload: unknown) => void;\n\nexport interface NoxAeApiWsOptions {\n /** Base URL of the server, same one passed to the client (http/https). */\n baseUrl: string;\n apiKey?: string;\n /** Route suffix under the websocket base, e.g. \"console\" or \"events\". Default \"events\". */\n route?: string;\n /** Whether to auto-reconnect on unexpected close. Default true. */\n autoReconnect?: boolean;\n /** Max reconnect delay in ms. Default 30000. */\n maxReconnectDelayMs?: number;\n /** Override the WebSocket implementation, mainly for testing / non-browser runtimes. */\n webSocketImpl?: typeof WebSocket;\n}\n\nfunction toWsUrl(baseUrl: string, route: string, apiKey?: string): string {\n const url = new URL(`${baseUrl.replace(/\\/+$/, \"\")}/v1/ws/${route.replace(/^\\/+/, \"\")}`);\n url.protocol = url.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n if (apiKey) url.searchParams.set(\"key\", apiKey);\n return url.toString();\n}\n\n/**\n * Thin wrapper around the server's WebSocket endpoints (console tail and\n * event broadcasts). Handles reconnection with exponential backoff so\n * consumers can just attach listeners and not think about the socket\n * lifecycle.\n *\n * Usage:\n * ```ts\n * const ws = client.connect({ route: \"console\" });\n * ws.on(\"console\", (line) => console.log(line));\n * ws.on(\"close\", () => console.log(\"disconnected\"));\n * ```\n */\nexport class NoxAeApiSocket {\n private socket: WebSocket | null = null;\n private readonly listeners = new Map<NoxAeApiWsEvent, Set<Listener>>();\n private reconnectAttempt = 0;\n private closedByUser = false;\n private readonly wsImpl: typeof WebSocket;\n\n constructor(private readonly options: NoxAeApiWsOptions) {\n const impl = options.webSocketImpl ?? (globalThis as { WebSocket?: typeof WebSocket }).WebSocket;\n if (!impl) {\n throw new Error(\n \"No WebSocket implementation available in this runtime. Pass `webSocketImpl` in options.\",\n );\n }\n this.wsImpl = impl;\n this.open();\n }\n\n private open(): void {\n const url = toWsUrl(this.options.baseUrl, this.options.route ?? \"events\", this.options.apiKey);\n const socket = new this.wsImpl(url);\n\n socket.onopen = () => {\n this.reconnectAttempt = 0;\n this.emit(\"open\", undefined);\n };\n\n socket.onmessage = (event: MessageEvent) => {\n const raw = typeof event.data === \"string\" ? event.data : String(event.data);\n const parsed = safeParse(raw);\n this.emit(\"message\", parsed);\n // Best-effort routing: if the payload has a `type` field of \"console\"\n // or \"event\", also emit on that specific channel.\n if (parsed && typeof parsed === \"object\" && \"type\" in (parsed as Record<string, unknown>)) {\n const type = (parsed as Record<string, unknown>).type;\n if (type === \"console\" || type === \"event\") this.emit(type, parsed);\n }\n };\n\n socket.onerror = (event) => {\n this.emit(\"error\", event);\n };\n\n socket.onclose = () => {\n this.emit(\"close\", undefined);\n if (!this.closedByUser && this.options.autoReconnect !== false) {\n this.scheduleReconnect();\n }\n };\n\n this.socket = socket;\n }\n\n private scheduleReconnect(): void {\n const maxDelay = this.options.maxReconnectDelayMs ?? 30_000;\n const delay = Math.min(maxDelay, 500 * 2 ** this.reconnectAttempt);\n this.reconnectAttempt++;\n setTimeout(() => {\n if (!this.closedByUser) this.open();\n }, delay);\n }\n\n on(event: NoxAeApiWsEvent, listener: Listener): () => void {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set());\n this.listeners.get(event)!.add(listener);\n return () => this.listeners.get(event)?.delete(listener);\n }\n\n off(event: NoxAeApiWsEvent, listener: Listener): void {\n this.listeners.get(event)?.delete(listener);\n }\n\n private emit(event: NoxAeApiWsEvent, payload: unknown): void {\n for (const listener of this.listeners.get(event) ?? []) listener(payload);\n }\n\n /** Send a raw payload over the socket, JSON-stringified if not already a string. */\n send(payload: unknown): void {\n if (!this.socket || this.socket.readyState !== this.wsImpl.OPEN) {\n throw new Error(\"Cannot send: socket is not open\");\n }\n this.socket.send(typeof payload === \"string\" ? payload : JSON.stringify(payload));\n }\n\n /** Close the socket and stop reconnecting. */\n close(): void {\n this.closedByUser = true;\n this.socket?.close();\n }\n}\n\nfunction safeParse(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n","import { HttpEngine, type NoxAeApiClientOptions } from \"./http-engine.js\";\nimport { PlayersModule } from \"./modules/players.js\";\nimport { EconomyModule } from \"./modules/economy.js\";\nimport { ServerModule } from \"./modules/server.js\";\nimport { WorldsModule } from \"./modules/worlds.js\";\nimport { PluginsModule } from \"./modules/plugins.js\";\nimport { AdvancementsModule, PlaceholdersModule } from \"./modules/misc.js\";\nimport { LuckPermsModule } from \"./modules/luckperms.js\";\nimport { NoxAuthModule } from \"./modules/noxauth.js\";\nimport { NoxAeApiSocket, type NoxAeApiWsOptions } from \"./socket.js\";\n\nexport class NoxAeApiClient {\n readonly players: PlayersModule;\n readonly economy: EconomyModule;\n readonly server: ServerModule;\n readonly worlds: WorldsModule;\n readonly plugins: PluginsModule;\n readonly advancements: AdvancementsModule;\n readonly placeholders: PlaceholdersModule;\n /** Only works if LuckPerms is loaded on the target server. */\n readonly luckperms: LuckPermsModule;\n /** Only works if `noxauth.enabled: true` is set in the server config. */\n readonly noxauth: NoxAuthModule;\n\n private readonly http: HttpEngine;\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n\n constructor(options: NoxAeApiClientOptions) {\n this.http = new HttpEngine(options);\n this.baseUrl = options.baseUrl;\n this.apiKey = options.apiKey;\n\n this.players = new PlayersModule(this.http);\n this.economy = new EconomyModule(this.http);\n this.server = new ServerModule(this.http);\n this.worlds = new WorldsModule(this.http);\n this.plugins = new PluginsModule(this.http);\n this.advancements = new AdvancementsModule(this.http);\n this.placeholders = new PlaceholdersModule(this.http);\n this.luckperms = new LuckPermsModule(this.http);\n this.noxauth = new NoxAuthModule(this.http);\n }\n\n /**\n * Build a client from environment variables:\n * `NOXAEAPI_BASE_URL` and `NOXAEAPI_KEY`.\n *\n * This is a convenience for Node-like runtimes; the SDK itself never\n * reads `process.env` implicitly outside of this method, and does not\n * load `.env` files — use a library like `dotenv` in your own app if\n * you want that, then call `NoxAeApiClient.fromEnv()` after it's loaded.\n */\n static fromEnv(overrides: Partial<NoxAeApiClientOptions> = {}): NoxAeApiClient {\n const env = (globalThis as { process?: { env?: Record<string, string | undefined> } })\n .process?.env;\n const baseUrl = overrides.baseUrl ?? env?.NOXAEAPI_BASE_URL;\n const apiKey = overrides.apiKey ?? env?.NOXAEAPI_KEY;\n\n if (!baseUrl) {\n throw new Error(\n \"NoxAeApiClient.fromEnv(): NOXAEAPI_BASE_URL is not set and no baseUrl override was given.\",\n );\n }\n\n return new NoxAeApiClient({ ...overrides, baseUrl, apiKey });\n }\n\n /** Open a WebSocket connection to the server (console tail or event stream). */\n connect(options: Partial<NoxAeApiWsOptions> = {}): NoxAeApiSocket {\n return new NoxAeApiSocket({\n baseUrl: this.baseUrl,\n apiKey: this.apiKey,\n ...options,\n });\n }\n}\n"]}