@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/dist/index.d.cts CHANGED
@@ -33,6 +33,16 @@ declare class HttpEngine {
33
33
  request<T>(method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH", path: string, opts?: {
34
34
  body?: unknown;
35
35
  query?: Record<string, QueryValue>;
36
+ /**
37
+ * Encode `body` as `application/x-www-form-urlencoded` (Javalin's
38
+ * `ctx.formParam(...)`) instead of JSON. Most NoxAeApi endpoints
39
+ * expect form-urlencoded bodies — only the LuckPerms and NoxAuth
40
+ * routes use `ctx.bodyAsClass(...)` and need real JSON. Defaults to
41
+ * `false` (JSON) to preserve existing behavior; each module call
42
+ * site is responsible for passing `form: true` where the server
43
+ * actually expects it.
44
+ */
45
+ form?: boolean;
36
46
  }): Promise<T>;
37
47
  }
38
48
 
@@ -205,8 +215,11 @@ declare class PlayersModule {
205
215
  getInventory(playerUuid: string, worldUuid: string): Promise<InventoryItem[]>;
206
216
  /** Kick an online player, optionally with a reason. */
207
217
  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>;
218
+ /**
219
+ * Ban a player, optionally with a reason and an ISO-8601 expiry
220
+ * (e.g. "2030-01-01T00:00:00Z"). Omit `expiry` for a permanent ban.
221
+ */
222
+ ban(uuid: string, reason?: string, expiry?: string): Promise<void>;
210
223
  /** Remove a player's ban. */
211
224
  unban(uuid: string): Promise<void>;
212
225
  /** Teleport a player to a location. */
@@ -247,23 +260,40 @@ declare class ServerModule {
247
260
  /** Get server info: version, MOTD, TPS, health, player counts, etc. */
248
261
  info(): Promise<ServerInfo>;
249
262
  /**
250
- * Run a console command on the server.
263
+ * Run a console command on the server, returning its console output.
251
264
  * This is a privileged endpoint — requires a write-enabled API key.
265
+ *
266
+ * `waitMs` is how long to wait for output before returning (server
267
+ * default 500ms if omitted). The server returns the joined output as a
268
+ * plain JSON string, not `{ lines }`.
252
269
  */
253
- exec(command: string): Promise<{
254
- lines: string[];
255
- }>;
270
+ exec(command: string, waitMs?: number): Promise<string>;
256
271
  /** List server operators. */
257
272
  getOps(): Promise<WhitelistEntry[]>;
258
- /** Grant operator status to a player. */
273
+ /**
274
+ * Grant operator status to a player.
275
+ *
276
+ * Server-side (`ServerApi.opPlayer`) reads `ctx.formParam("playerUuid")`,
277
+ * not "uuid" — the field name matters here.
278
+ */
259
279
  opPlayer(uuid: string): Promise<void>;
260
- /** Revoke operator status from a player. */
280
+ /**
281
+ * Revoke operator status from a player.
282
+ *
283
+ * Server-side (`ServerApi.deopPlayer`) reads this from the query string
284
+ * (`ctx.queryParam("playerUuid")`), not the request body.
285
+ */
261
286
  deopPlayer(uuid: string): Promise<void>;
262
287
  /** Get the current whitelist. */
263
288
  getWhitelist(): Promise<WhitelistEntry[]>;
264
289
  /** Add a player to the whitelist. */
265
290
  addToWhitelist(uuid: string, name?: string): Promise<void>;
266
- /** Remove a player from the whitelist. */
291
+ /**
292
+ * Remove a player from the whitelist.
293
+ *
294
+ * Server-side (`ServerApi.whitelistDelete`) reads `uuid`/`name` from the
295
+ * query string, not the request body.
296
+ */
267
297
  removeFromWhitelist(uuid: string): Promise<void>;
268
298
  /**
269
299
  * Restart the server.
@@ -293,11 +323,21 @@ declare class ServerModule {
293
323
  getScoreboard(): Promise<unknown>;
294
324
  /** Set a score for an entry on an objective. */
295
325
  setScore(objective: string, entry: string, value: number): Promise<void>;
296
- /** Reset (remove) a score for an entry on an objective. */
326
+ /**
327
+ * Reset (remove) a score for an entry on an objective.
328
+ *
329
+ * Server-side (`ServerApi.resetScore`) reads `entry` from the query
330
+ * string, not the request body.
331
+ */
297
332
  resetScore(objective: string, entry: string): Promise<void>;
298
333
  /** Broadcast a message to every player on the server. */
299
334
  broadcast(message: string): Promise<void>;
300
- /** Send a private message to a specific player. */
335
+ /**
336
+ * Send a private message to a specific player.
337
+ *
338
+ * Server-side (`ServerApi.tellPost`) reads `ctx.formParam("playerUuid")`,
339
+ * not "uuid".
340
+ */
301
341
  tell(uuid: string, message: string): Promise<void>;
302
342
  }
303
343
 
@@ -320,13 +360,16 @@ declare class WorldsModule {
320
360
  download(uuid: string): Promise<{
321
361
  url: string;
322
362
  }>;
323
- /** Set the in-game time for a world. */
363
+ /** Set the in-game time for a world (0-24000). */
324
364
  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>;
365
+ /**
366
+ * Set the weather for a world.
367
+ *
368
+ * Server-side (`WorldApi.setWorldWeather`) reads a single
369
+ * `ctx.formParam("weather")` enum string — "clear" | "rain" | "thunder" —
370
+ * not separate storm/thundering booleans.
371
+ */
372
+ setWeather(uuid: string, weather: "clear" | "rain" | "thunder"): Promise<void>;
330
373
  /** Get entity counts within a specific world. */
331
374
  getEntities(uuid: string): Promise<{
332
375
  world: string;
@@ -341,10 +384,14 @@ declare class PluginsModule {
341
384
  /** List all installed plugins/mods. */
342
385
  list(): Promise<Plugin[]>;
343
386
  /**
344
- * Install a plugin from a URL or identifier.
387
+ * Install a plugin by downloading it from a direct URL.
345
388
  * This is a privileged endpoint — requires a write-enabled API key.
389
+ *
390
+ * Server-side (`PluginApi.installPlugin`) reads
391
+ * `ctx.formParam("downloadUrl")`, not "source", and the request must be
392
+ * form-urlencoded.
346
393
  */
347
- install(source: string): Promise<void>;
394
+ install(downloadUrl: string): Promise<void>;
348
395
  /** Enable a plugin by name. */
349
396
  enable(name: string): Promise<void>;
350
397
  /** Disable a plugin by name. */
@@ -361,12 +408,15 @@ declare class PlaceholdersModule {
361
408
  private readonly http;
362
409
  constructor(http: HttpEngine);
363
410
  /**
364
- * Replace PlaceholderAPI-style placeholders (e.g. "%player_name%") for a
365
- * player, returning the resolved string.
411
+ * Replace PlaceholderAPI-style placeholders (e.g. "%player_name%") in
412
+ * `message` for a player, returning the resolved string.
413
+ *
414
+ * Server-side this is `PAPIApi.replacePlaceholders`, which reads
415
+ * `ctx.formParam("message")` and `ctx.formParam("uuid")` — the field is
416
+ * literally named "message", not "text", and the whole body must be
417
+ * form-urlencoded.
366
418
  */
367
- replace(uuid: string, text: string): Promise<{
368
- result: string;
369
- }>;
419
+ replace(uuid: string, message: string): Promise<string>;
370
420
  }
371
421
 
372
422
  /**
@@ -375,6 +425,10 @@ declare class PlaceholdersModule {
375
425
  * without it will fail (typically a 404). There's no separate "is this
376
426
  * available" flag from the SDK's side; check `client.plugins.list()` for
377
427
  * LuckPerms if you need to branch on it ahead of time.
428
+ *
429
+ * Unlike most other modules, these POST/DELETE bodies are sent as real
430
+ * JSON (the server reads them with `ctx.bodyAsClass(...)`, not
431
+ * `ctx.formParam(...)`) — do not add `form: true` to these calls.
378
432
  */
379
433
  declare class LuckPermsModule {
380
434
  private readonly http;
@@ -406,6 +460,10 @@ declare class LuckPermsModule {
406
460
  * Wraps the `/v1/noxauth/*` routes. These only work when `noxauth.enabled`
407
461
  * is set to true in the server's noxaeapi-config.yml and the NoxAuth plugin
408
462
  * is installed.
463
+ *
464
+ * `checkPassword`'s body is sent as real JSON (the server parses it with
465
+ * `GsonSingleton...fromJson(ctx.body(), PasswordCheckRequest.class)`, not
466
+ * `ctx.formParam(...)`) — do not add `form: true` to that call.
409
467
  */
410
468
  declare class NoxAuthModule {
411
469
  private readonly http;
package/dist/index.d.ts CHANGED
@@ -33,6 +33,16 @@ declare class HttpEngine {
33
33
  request<T>(method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH", path: string, opts?: {
34
34
  body?: unknown;
35
35
  query?: Record<string, QueryValue>;
36
+ /**
37
+ * Encode `body` as `application/x-www-form-urlencoded` (Javalin's
38
+ * `ctx.formParam(...)`) instead of JSON. Most NoxAeApi endpoints
39
+ * expect form-urlencoded bodies — only the LuckPerms and NoxAuth
40
+ * routes use `ctx.bodyAsClass(...)` and need real JSON. Defaults to
41
+ * `false` (JSON) to preserve existing behavior; each module call
42
+ * site is responsible for passing `form: true` where the server
43
+ * actually expects it.
44
+ */
45
+ form?: boolean;
36
46
  }): Promise<T>;
37
47
  }
38
48
 
@@ -205,8 +215,11 @@ declare class PlayersModule {
205
215
  getInventory(playerUuid: string, worldUuid: string): Promise<InventoryItem[]>;
206
216
  /** Kick an online player, optionally with a reason. */
207
217
  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>;
218
+ /**
219
+ * Ban a player, optionally with a reason and an ISO-8601 expiry
220
+ * (e.g. "2030-01-01T00:00:00Z"). Omit `expiry` for a permanent ban.
221
+ */
222
+ ban(uuid: string, reason?: string, expiry?: string): Promise<void>;
210
223
  /** Remove a player's ban. */
211
224
  unban(uuid: string): Promise<void>;
212
225
  /** Teleport a player to a location. */
@@ -247,23 +260,40 @@ declare class ServerModule {
247
260
  /** Get server info: version, MOTD, TPS, health, player counts, etc. */
248
261
  info(): Promise<ServerInfo>;
249
262
  /**
250
- * Run a console command on the server.
263
+ * Run a console command on the server, returning its console output.
251
264
  * This is a privileged endpoint — requires a write-enabled API key.
265
+ *
266
+ * `waitMs` is how long to wait for output before returning (server
267
+ * default 500ms if omitted). The server returns the joined output as a
268
+ * plain JSON string, not `{ lines }`.
252
269
  */
253
- exec(command: string): Promise<{
254
- lines: string[];
255
- }>;
270
+ exec(command: string, waitMs?: number): Promise<string>;
256
271
  /** List server operators. */
257
272
  getOps(): Promise<WhitelistEntry[]>;
258
- /** Grant operator status to a player. */
273
+ /**
274
+ * Grant operator status to a player.
275
+ *
276
+ * Server-side (`ServerApi.opPlayer`) reads `ctx.formParam("playerUuid")`,
277
+ * not "uuid" — the field name matters here.
278
+ */
259
279
  opPlayer(uuid: string): Promise<void>;
260
- /** Revoke operator status from a player. */
280
+ /**
281
+ * Revoke operator status from a player.
282
+ *
283
+ * Server-side (`ServerApi.deopPlayer`) reads this from the query string
284
+ * (`ctx.queryParam("playerUuid")`), not the request body.
285
+ */
261
286
  deopPlayer(uuid: string): Promise<void>;
262
287
  /** Get the current whitelist. */
263
288
  getWhitelist(): Promise<WhitelistEntry[]>;
264
289
  /** Add a player to the whitelist. */
265
290
  addToWhitelist(uuid: string, name?: string): Promise<void>;
266
- /** Remove a player from the whitelist. */
291
+ /**
292
+ * Remove a player from the whitelist.
293
+ *
294
+ * Server-side (`ServerApi.whitelistDelete`) reads `uuid`/`name` from the
295
+ * query string, not the request body.
296
+ */
267
297
  removeFromWhitelist(uuid: string): Promise<void>;
268
298
  /**
269
299
  * Restart the server.
@@ -293,11 +323,21 @@ declare class ServerModule {
293
323
  getScoreboard(): Promise<unknown>;
294
324
  /** Set a score for an entry on an objective. */
295
325
  setScore(objective: string, entry: string, value: number): Promise<void>;
296
- /** Reset (remove) a score for an entry on an objective. */
326
+ /**
327
+ * Reset (remove) a score for an entry on an objective.
328
+ *
329
+ * Server-side (`ServerApi.resetScore`) reads `entry` from the query
330
+ * string, not the request body.
331
+ */
297
332
  resetScore(objective: string, entry: string): Promise<void>;
298
333
  /** Broadcast a message to every player on the server. */
299
334
  broadcast(message: string): Promise<void>;
300
- /** Send a private message to a specific player. */
335
+ /**
336
+ * Send a private message to a specific player.
337
+ *
338
+ * Server-side (`ServerApi.tellPost`) reads `ctx.formParam("playerUuid")`,
339
+ * not "uuid".
340
+ */
301
341
  tell(uuid: string, message: string): Promise<void>;
302
342
  }
303
343
 
@@ -320,13 +360,16 @@ declare class WorldsModule {
320
360
  download(uuid: string): Promise<{
321
361
  url: string;
322
362
  }>;
323
- /** Set the in-game time for a world. */
363
+ /** Set the in-game time for a world (0-24000). */
324
364
  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>;
365
+ /**
366
+ * Set the weather for a world.
367
+ *
368
+ * Server-side (`WorldApi.setWorldWeather`) reads a single
369
+ * `ctx.formParam("weather")` enum string — "clear" | "rain" | "thunder" —
370
+ * not separate storm/thundering booleans.
371
+ */
372
+ setWeather(uuid: string, weather: "clear" | "rain" | "thunder"): Promise<void>;
330
373
  /** Get entity counts within a specific world. */
331
374
  getEntities(uuid: string): Promise<{
332
375
  world: string;
@@ -341,10 +384,14 @@ declare class PluginsModule {
341
384
  /** List all installed plugins/mods. */
342
385
  list(): Promise<Plugin[]>;
343
386
  /**
344
- * Install a plugin from a URL or identifier.
387
+ * Install a plugin by downloading it from a direct URL.
345
388
  * This is a privileged endpoint — requires a write-enabled API key.
389
+ *
390
+ * Server-side (`PluginApi.installPlugin`) reads
391
+ * `ctx.formParam("downloadUrl")`, not "source", and the request must be
392
+ * form-urlencoded.
346
393
  */
347
- install(source: string): Promise<void>;
394
+ install(downloadUrl: string): Promise<void>;
348
395
  /** Enable a plugin by name. */
349
396
  enable(name: string): Promise<void>;
350
397
  /** Disable a plugin by name. */
@@ -361,12 +408,15 @@ declare class PlaceholdersModule {
361
408
  private readonly http;
362
409
  constructor(http: HttpEngine);
363
410
  /**
364
- * Replace PlaceholderAPI-style placeholders (e.g. "%player_name%") for a
365
- * player, returning the resolved string.
411
+ * Replace PlaceholderAPI-style placeholders (e.g. "%player_name%") in
412
+ * `message` for a player, returning the resolved string.
413
+ *
414
+ * Server-side this is `PAPIApi.replacePlaceholders`, which reads
415
+ * `ctx.formParam("message")` and `ctx.formParam("uuid")` — the field is
416
+ * literally named "message", not "text", and the whole body must be
417
+ * form-urlencoded.
366
418
  */
367
- replace(uuid: string, text: string): Promise<{
368
- result: string;
369
- }>;
419
+ replace(uuid: string, message: string): Promise<string>;
370
420
  }
371
421
 
372
422
  /**
@@ -375,6 +425,10 @@ declare class PlaceholdersModule {
375
425
  * without it will fail (typically a 404). There's no separate "is this
376
426
  * available" flag from the SDK's side; check `client.plugins.list()` for
377
427
  * LuckPerms if you need to branch on it ahead of time.
428
+ *
429
+ * Unlike most other modules, these POST/DELETE bodies are sent as real
430
+ * JSON (the server reads them with `ctx.bodyAsClass(...)`, not
431
+ * `ctx.formParam(...)`) — do not add `form: true` to these calls.
378
432
  */
379
433
  declare class LuckPermsModule {
380
434
  private readonly http;
@@ -406,6 +460,10 @@ declare class LuckPermsModule {
406
460
  * Wraps the `/v1/noxauth/*` routes. These only work when `noxauth.enabled`
407
461
  * is set to true in the server's noxaeapi-config.yml and the NoxAuth plugin
408
462
  * is installed.
463
+ *
464
+ * `checkPassword`'s body is sent as real JSON (the server parses it with
465
+ * `GsonSingleton...fromJson(ctx.body(), PasswordCheckRequest.class)`, not
466
+ * `ctx.formParam(...)`) — do not add `form: true` to that call.
409
467
  */
410
468
  declare class NoxAuthModule {
411
469
  private readonly http;
package/dist/index.js CHANGED
@@ -105,7 +105,7 @@ var HttpEngine = class {
105
105
  this.fetchImpl = fetchImpl;
106
106
  }
107
107
  buildUrl(path, query) {
108
- const url = new URL(`${this.baseUrl}/${path.replace(/^\/+/, "")}`);
108
+ const url = new URL(`${this.baseUrl}/v1/${path.replace(/^\/+/, "")}`);
109
109
  if (query) {
110
110
  for (const [key, value] of Object.entries(query)) {
111
111
  if (value !== void 0 && value !== null) {
@@ -128,11 +128,20 @@ var HttpEngine = class {
128
128
  ...this.extraHeaders
129
129
  };
130
130
  if (this.apiKey) headers["key"] = this.apiKey;
131
- if (opts.body !== void 0) headers["Content-Type"] = "application/json";
131
+ let encodedBody;
132
+ if (opts.body !== void 0) {
133
+ if (opts.form) {
134
+ headers["Content-Type"] = "application/x-www-form-urlencoded";
135
+ encodedBody = encodeFormBody(opts.body);
136
+ } else {
137
+ headers["Content-Type"] = "application/json";
138
+ encodedBody = JSON.stringify(opts.body);
139
+ }
140
+ }
132
141
  const response = await this.fetchImpl(url, {
133
142
  method,
134
143
  headers,
135
- body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0,
144
+ body: encodedBody,
136
145
  signal: controller.signal
137
146
  });
138
147
  clearTimeout(timeout);
@@ -192,6 +201,19 @@ var HttpEngine = class {
192
201
  throw lastError instanceof Error ? lastError : new Error("Request failed after retries");
193
202
  }
194
203
  };
204
+ function encodeFormBody(body) {
205
+ const params = new URLSearchParams();
206
+ if (body && typeof body === "object") {
207
+ for (const [key, value] of Object.entries(body)) {
208
+ if (value === void 0 || value === null) continue;
209
+ params.set(
210
+ key,
211
+ typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value)
212
+ );
213
+ }
214
+ }
215
+ return params.toString();
216
+ }
195
217
  function safeJsonParse(text) {
196
218
  if (!text) return void 0;
197
219
  try {
@@ -236,13 +258,18 @@ var PlayersModule = class {
236
258
  /** Kick an online player, optionally with a reason. */
237
259
  kick(uuid, reason) {
238
260
  return this.http.request("POST", `players/${encodeURIComponent(uuid)}/kick`, {
239
- body: reason ? { reason } : void 0
261
+ body: reason ? { reason } : void 0,
262
+ form: true
240
263
  });
241
264
  }
242
- /** Ban a player, optionally with a reason and expiration. */
243
- ban(uuid, reason) {
265
+ /**
266
+ * Ban a player, optionally with a reason and an ISO-8601 expiry
267
+ * (e.g. "2030-01-01T00:00:00Z"). Omit `expiry` for a permanent ban.
268
+ */
269
+ ban(uuid, reason, expiry) {
244
270
  return this.http.request("POST", `players/${encodeURIComponent(uuid)}/ban`, {
245
- body: reason ? { reason } : void 0
271
+ body: reason || expiry ? { reason, expiry } : void 0,
272
+ form: true
246
273
  });
247
274
  }
248
275
  /** Remove a player's ban. */
@@ -252,13 +279,15 @@ var PlayersModule = class {
252
279
  /** Teleport a player to a location. */
253
280
  teleport(uuid, location) {
254
281
  return this.http.request("POST", `players/${encodeURIComponent(uuid)}/teleport`, {
255
- body: location
282
+ body: location,
283
+ form: true
256
284
  });
257
285
  }
258
286
  /** Change a player's gamemode. */
259
287
  setGamemode(uuid, gamemode) {
260
288
  return this.http.request("PUT", `players/${encodeURIComponent(uuid)}/gamemode`, {
261
- body: { gamemode }
289
+ body: { gamemode },
290
+ form: true
262
291
  });
263
292
  }
264
293
  /** Get kill/death/playtime/block stats for a player. */
@@ -289,11 +318,11 @@ var EconomyModule = class {
289
318
  }
290
319
  /** Pay an amount to a player (adds to their balance). */
291
320
  pay(uuid, amount) {
292
- return this.http.request("POST", "economy/pay", { body: { uuid, amount } });
321
+ return this.http.request("POST", "economy/pay", { body: { uuid, amount }, form: true });
293
322
  }
294
323
  /** Debit an amount from a player (subtracts from their balance). */
295
324
  debit(uuid, amount) {
296
- return this.http.request("POST", "economy/debit", { body: { uuid, amount } });
325
+ return this.http.request("POST", "economy/debit", { body: { uuid, amount }, form: true });
297
326
  }
298
327
  };
299
328
 
@@ -312,23 +341,40 @@ var ServerModule = class {
312
341
  return this.http.request("GET", "server");
313
342
  }
314
343
  /**
315
- * Run a console command on the server.
344
+ * Run a console command on the server, returning its console output.
316
345
  * This is a privileged endpoint — requires a write-enabled API key.
346
+ *
347
+ * `waitMs` is how long to wait for output before returning (server
348
+ * default 500ms if omitted). The server returns the joined output as a
349
+ * plain JSON string, not `{ lines }`.
317
350
  */
318
- exec(command) {
319
- return this.http.request("POST", "server/exec", { body: { command } });
351
+ exec(command, waitMs) {
352
+ return this.http.request("POST", "server/exec", {
353
+ body: { command, time: waitMs },
354
+ form: true
355
+ });
320
356
  }
321
357
  /** List server operators. */
322
358
  getOps() {
323
359
  return this.http.request("GET", "server/ops");
324
360
  }
325
- /** Grant operator status to a player. */
361
+ /**
362
+ * Grant operator status to a player.
363
+ *
364
+ * Server-side (`ServerApi.opPlayer`) reads `ctx.formParam("playerUuid")`,
365
+ * not "uuid" — the field name matters here.
366
+ */
326
367
  opPlayer(uuid) {
327
- return this.http.request("POST", "server/ops", { body: { uuid } });
368
+ return this.http.request("POST", "server/ops", { body: { playerUuid: uuid }, form: true });
328
369
  }
329
- /** Revoke operator status from a player. */
370
+ /**
371
+ * Revoke operator status from a player.
372
+ *
373
+ * Server-side (`ServerApi.deopPlayer`) reads this from the query string
374
+ * (`ctx.queryParam("playerUuid")`), not the request body.
375
+ */
330
376
  deopPlayer(uuid) {
331
- return this.http.request("DELETE", "server/ops", { body: { uuid } });
377
+ return this.http.request("DELETE", "server/ops", { query: { playerUuid: uuid } });
332
378
  }
333
379
  /** Get the current whitelist. */
334
380
  getWhitelist() {
@@ -336,11 +382,16 @@ var ServerModule = class {
336
382
  }
337
383
  /** Add a player to the whitelist. */
338
384
  addToWhitelist(uuid, name) {
339
- return this.http.request("POST", "server/whitelist", { body: { uuid, name } });
385
+ return this.http.request("POST", "server/whitelist", { body: { uuid, name }, form: true });
340
386
  }
341
- /** Remove a player from the whitelist. */
387
+ /**
388
+ * Remove a player from the whitelist.
389
+ *
390
+ * Server-side (`ServerApi.whitelistDelete`) reads `uuid`/`name` from the
391
+ * query string, not the request body.
392
+ */
342
393
  removeFromWhitelist(uuid) {
343
- return this.http.request("DELETE", "server/whitelist", { body: { uuid } });
394
+ return this.http.request("DELETE", "server/whitelist", { query: { uuid } });
344
395
  }
345
396
  /**
346
397
  * Restart the server.
@@ -363,7 +414,7 @@ var ServerModule = class {
363
414
  }
364
415
  /** Ban an IP address. */
365
416
  banIp(ip, reason) {
366
- return this.http.request("POST", "server/ban-ip", { body: { ip, reason } });
417
+ return this.http.request("POST", "server/ban-ip", { body: { ip, reason }, form: true });
367
418
  }
368
419
  /** Get a scoreboard objective's scores by objective name. */
369
420
  getObjective(name) {
@@ -376,22 +427,33 @@ var ServerModule = class {
376
427
  /** Set a score for an entry on an objective. */
377
428
  setScore(objective, entry, value) {
378
429
  return this.http.request("POST", `scoreboard/${encodeURIComponent(objective)}/score`, {
379
- body: { entry, value }
430
+ body: { entry, value },
431
+ form: true
380
432
  });
381
433
  }
382
- /** Reset (remove) a score for an entry on an objective. */
434
+ /**
435
+ * Reset (remove) a score for an entry on an objective.
436
+ *
437
+ * Server-side (`ServerApi.resetScore`) reads `entry` from the query
438
+ * string, not the request body.
439
+ */
383
440
  resetScore(objective, entry) {
384
441
  return this.http.request("DELETE", `scoreboard/${encodeURIComponent(objective)}/score`, {
385
- body: { entry }
442
+ query: { entry }
386
443
  });
387
444
  }
388
445
  /** Broadcast a message to every player on the server. */
389
446
  broadcast(message) {
390
- return this.http.request("POST", "chat/broadcast", { body: { message } });
447
+ return this.http.request("POST", "chat/broadcast", { body: { message }, form: true });
391
448
  }
392
- /** Send a private message to a specific player. */
449
+ /**
450
+ * Send a private message to a specific player.
451
+ *
452
+ * Server-side (`ServerApi.tellPost`) reads `ctx.formParam("playerUuid")`,
453
+ * not "uuid".
454
+ */
393
455
  tell(uuid, message) {
394
- return this.http.request("POST", "chat/tell", { body: { uuid, message } });
456
+ return this.http.request("POST", "chat/tell", { body: { playerUuid: uuid, message }, form: true });
395
457
  }
396
458
  };
397
459
 
@@ -425,16 +487,24 @@ var WorldsModule = class {
425
487
  download(uuid) {
426
488
  return this.http.request("GET", `worlds/${encodeURIComponent(uuid)}/download`);
427
489
  }
428
- /** Set the in-game time for a world. */
490
+ /** Set the in-game time for a world (0-24000). */
429
491
  setTime(uuid, time) {
430
492
  return this.http.request("POST", `worlds/${encodeURIComponent(uuid)}/time`, {
431
- body: { time }
493
+ body: { time },
494
+ form: true
432
495
  });
433
496
  }
434
- /** Set weather (storm/thundering) for a world. */
497
+ /**
498
+ * Set the weather for a world.
499
+ *
500
+ * Server-side (`WorldApi.setWorldWeather`) reads a single
501
+ * `ctx.formParam("weather")` enum string — "clear" | "rain" | "thunder" —
502
+ * not separate storm/thundering booleans.
503
+ */
435
504
  setWeather(uuid, weather) {
436
505
  return this.http.request("POST", `worlds/${encodeURIComponent(uuid)}/weather`, {
437
- body: weather
506
+ body: { weather },
507
+ form: true
438
508
  });
439
509
  }
440
510
  /** Get entity counts within a specific world. */
@@ -454,11 +524,15 @@ var PluginsModule = class {
454
524
  return this.http.request("GET", "plugins");
455
525
  }
456
526
  /**
457
- * Install a plugin from a URL or identifier.
527
+ * Install a plugin by downloading it from a direct URL.
458
528
  * This is a privileged endpoint — requires a write-enabled API key.
529
+ *
530
+ * Server-side (`PluginApi.installPlugin`) reads
531
+ * `ctx.formParam("downloadUrl")`, not "source", and the request must be
532
+ * form-urlencoded.
459
533
  */
460
- install(source) {
461
- return this.http.request("POST", "plugins", { body: { source } });
534
+ install(downloadUrl) {
535
+ return this.http.request("POST", "plugins", { body: { downloadUrl }, form: true });
462
536
  }
463
537
  /** Enable a plugin by name. */
464
538
  enable(name) {
@@ -487,12 +561,18 @@ var PlaceholdersModule = class {
487
561
  }
488
562
  http;
489
563
  /**
490
- * Replace PlaceholderAPI-style placeholders (e.g. "%player_name%") for a
491
- * player, returning the resolved string.
564
+ * Replace PlaceholderAPI-style placeholders (e.g. "%player_name%") in
565
+ * `message` for a player, returning the resolved string.
566
+ *
567
+ * Server-side this is `PAPIApi.replacePlaceholders`, which reads
568
+ * `ctx.formParam("message")` and `ctx.formParam("uuid")` — the field is
569
+ * literally named "message", not "text", and the whole body must be
570
+ * form-urlencoded.
492
571
  */
493
- replace(uuid, text) {
572
+ replace(uuid, message) {
494
573
  return this.http.request("POST", "placeholders/replace", {
495
- body: { uuid, text }
574
+ body: { uuid, message },
575
+ form: true
496
576
  });
497
577
  }
498
578
  };
@@ -585,7 +665,7 @@ var NoxAuthModule = class {
585
665
 
586
666
  // src/socket.ts
587
667
  function toWsUrl(baseUrl, route, apiKey) {
588
- const url = new URL(`${baseUrl.replace(/\/+$/, "")}/${route.replace(/^\/+/, "")}`);
668
+ const url = new URL(`${baseUrl.replace(/\/+$/, "")}/v1/ws/${route.replace(/^\/+/, "")}`);
589
669
  url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
590
670
  if (apiKey) url.searchParams.set("key", apiKey);
591
671
  return url.toString();