@zaisma/cli 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/zaisma.mjs +24 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaisma/cli",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Upload and publish browser games on Zaisma from the command line.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://zaisma.com",
package/zaisma.mjs CHANGED
@@ -180,6 +180,12 @@ const COMMANDS = {
180
180
  arguments: [{ name: "slug" }, { name: "file", isOptional: true }],
181
181
  flags: {},
182
182
  },
183
+ "database restore": {
184
+ about: "Put a game's database back as it was at a moment in the last 30 days (an ISO time, like 2026-10-18T14:05:00Z), live; undo it with database undo-restore",
185
+ arguments: [{ name: "slug" }, { name: "restore_to_at" }],
186
+ flags: {},
187
+ },
188
+ "database undo-restore": { about: "Undo a restore of a game's database: back to just before it, live", arguments: [{ name: "slug" }, { name: "database_restore_id" }], flags: {} },
183
189
  saves: {
184
190
  about: "The players with a cloud save in a game, by player ID, 100 a page",
185
191
  arguments: [{ name: "slug" }],
@@ -203,7 +209,7 @@ const COMMANDS = {
203
209
  help: { about: "This help; with --json, every command, flag, exit code and error code", arguments: [], flags: {} },
204
210
  };
205
211
  /** Commands with a second word, like zaisma forum post. */
206
- const SUBCOMMANDS = { links: ["set", "remove"], forum: ["post", "message", "reply"], database: ["query", "batch", "export", "import"], saves: ["get", "change", "replace", "reset", "copies", "copy", "restore"], secrets: ["set", "delete"] };
212
+ const SUBCOMMANDS = { links: ["set", "remove"], forum: ["post", "message", "reply"], database: ["query", "batch", "export", "import", "restore", "undo-restore"], saves: ["get", "change", "replace", "reset", "copies", "copy", "restore"], secrets: ["set", "delete"] };
207
213
  /** Flags every command takes. */
208
214
  const GLOBAL_FLAGS = {
209
215
  json: { hasValue: false, about: "Print the API's answer as JSON, as-is (on failure its { error }), and nothing else" },
@@ -891,10 +897,22 @@ async function readInput() {
891
897
  return Buffer.concat(chunks).toString("utf8").trim();
892
898
  }
893
899
 
894
- /** A game's own database (GET and POST /games/<slug>/database…), as the MCP's get_database, query_database, batch_database, export_database and import_database. */
900
+ /** A game's own database (GET and POST /games/<slug>/database…), as the MCP's get_database, query_database, batch_database, export_database, import_database, restore_database and undo_database_restore. */
895
901
  async function database(command, values, flags) {
896
902
  if (command === "database export") return exportDatabase(values);
897
903
  if (command === "database import") return importDatabase(values);
904
+ if (command === "database restore" || command === "database undo-restore") {
905
+ const isUndo = command === "database undo-restore";
906
+ const answer = isUndo
907
+ ? await api("POST", `/games/${values.slug}/database/restores/${encodeURIComponent(values.database_restore_id)}/undo`)
908
+ : await api("POST", `/games/${values.slug}/database/restores`, { restore_to_at: values.restore_to_at });
909
+ if (isJson) return printJson(answer);
910
+ const restore = answer.database_restore;
911
+ console.log(isUndo ? `Undid restore ${values.database_restore_id}: ${values.slug}'s database is back to ${restore.restore_to_at}.` : `Restored ${values.slug}'s database to ${restore.restore_to_at}.`);
912
+ if (answer.erased_again_player_count) console.log(`Erased ${answer.erased_again_player_count} player${answer.erased_again_player_count === 1 ? "" : "s"} again who had been erased since.`);
913
+ console.log(`Undo it until ${restore.undo_expires_at}: zaisma database undo-restore ${values.slug} ${restore.id}`);
914
+ return;
915
+ }
898
916
  if (command === "database") {
899
917
  const answer = await api("GET", `/games/${values.slug}/database`);
900
918
  if (isJson) return printJson(answer);
@@ -908,6 +926,10 @@ async function database(command, values, flags) {
908
926
  `${use.written_row_count.toLocaleString("en-US")} written (${percent(use.written_row_count, use.free_written_row_count)} of ${use.free_written_row_count.toLocaleString("en-US")}), ` +
909
927
  `${(use.storage_size_bytes / 1024 / 1024).toFixed(1)} MB stored (${percent(use.storage_size_bytes, use.free_storage_size_bytes)} of ${use.free_storage_size_bytes / 1024 / 1024} MB). Resets ${use.reset_date}.`,
910
928
  );
929
+ if (answer.restores.length) {
930
+ console.log("\nRestores (newest first; undo with zaisma database undo-restore <slug> <id>):");
931
+ for (const restore of answer.restores.slice(0, 5)) console.log(`${restore.id} ${restore.restored_at} ${restore.undoes_database_restore_id ? `undid ${restore.undoes_database_restore_id}` : `back to ${restore.restore_to_at}`}`);
932
+ }
911
933
  return;
912
934
  }
913
935
  if (command === "database query") {