libroadcast-cli 1.6.0 → 1.7.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.
package/README.md CHANGED
@@ -23,7 +23,7 @@ Commands:
23
23
  Note: The delay is specified in seconds. (max 3600 seconds = 1 hour)
24
24
  Options:
25
25
  --onlyDelay Set only the delay without changing the start time.
26
- --noDelay Remove the delay from the rounds.
26
+ --noDelay Do not modify the delay, only adjust the start time.
27
27
 
28
28
  setPGN <broadcastId> <sourcePGNUrl> [--withFilter] [--slice <sliceFilter>]
29
29
  Sets the source PGN URL for all rounds in the specified broadcast.
package/dist/cmd/delay.js CHANGED
@@ -10,8 +10,7 @@ const getInfoBroadcast_1 = require("../utils/getInfoBroadcast");
10
10
  const colors_1 = __importDefault(require("../utils/colors"));
11
11
  const setDelayRounds = async (rounds, delay, onlyDelay, noDelay) => {
12
12
  for (const round of rounds) {
13
- await commandHandler_1.client
14
- .POST("/broadcast/round/{broadcastRoundId}/edit", {
13
+ await (0, commandHandler_1.handleApiResponse)(commandHandler_1.client.POST("/broadcast/round/{broadcastRoundId}/edit", {
15
14
  params: {
16
15
  path: { broadcastRoundId: round.id },
17
16
  query: { patch: 1 },
@@ -22,16 +21,7 @@ const setDelayRounds = async (rounds, delay, onlyDelay, noDelay) => {
22
21
  ? round.startsAt + delay * 1000
23
22
  : undefined,
24
23
  },
25
- })
26
- .then((response) => {
27
- if (response.response.ok)
28
- console.log(colors_1.default.green(`Successfully set delay for round ${colors_1.default.whiteBold(round.id)} to ${colors_1.default.whiteBold(delay.toString())} seconds.`));
29
- else
30
- console.error(colors_1.default.red(`Failed to set delay for round ${colors_1.default.whiteBold(round.id)}: ${colors_1.default.whiteBold(response.response.statusText)}`));
31
- })
32
- .catch((error) => {
33
- console.error(colors_1.default.red(`Error setting delay for round ${colors_1.default.whiteBold(round.id)}:`), error);
34
- });
24
+ }), `Successfully set delay for round ${colors_1.default.whiteBold(round.id)} to ${colors_1.default.whiteBold(delay.toString())} seconds.`, `Error setting delay for round ${colors_1.default.whiteBold(round.id)}`);
35
25
  await (0, commandHandler_1.sleep)(200);
36
26
  }
37
27
  };
@@ -42,7 +32,7 @@ const delayCommand = async (args) => {
42
32
  (0, node_process_1.exit)(1);
43
33
  }
44
34
  const delayNum = parseInt(delay, 10);
45
- if (isNaN(delayNum) && delayNum >= 0 && delayNum <= 3600) {
35
+ if (isNaN(delayNum) || delayNum < 0 || delayNum > 3600) {
46
36
  (0, commandHandler_1.msgCommonErrorHelp)("Delay must be a number between 0 and 3600 seconds.");
47
37
  (0, node_process_1.exit)(1);
48
38
  }
@@ -57,6 +47,6 @@ const delayCommand = async (args) => {
57
47
  console.error(colors_1.default.red("No rounds found for the specified broadcast."));
58
48
  (0, node_process_1.exit)(1);
59
49
  }
60
- setDelayRounds(broadcast.rounds, parseInt(delay, 10), onlyDelay, noDelay);
50
+ await setDelayRounds(broadcast.rounds, delayNum, onlyDelay, noDelay);
61
51
  };
62
52
  exports.delayCommand = delayCommand;
@@ -10,13 +10,15 @@ const getInfoBroadcast_1 = require("../utils/getInfoBroadcast");
10
10
  const colors_1 = __importDefault(require("../utils/colors"));
11
11
  const ms_1 = require("ms");
12
12
  const fixScheduleRounds = async (rounds, timeDiff, roundsToFix) => {
13
- if (roundsToFix && roundsToFix.length > 0) {
14
- rounds = rounds.filter((_, i) => roundsToFix.includes(i + 1));
13
+ rounds = rounds
14
+ .filter((_, i) => !roundsToFix?.length || roundsToFix.includes(i + 1))
15
+ .filter((el) => el.startsAt !== undefined);
16
+ if (rounds.length === 0) {
17
+ console.error(colors_1.default.red("No rounds to fix after applying filters."));
18
+ (0, node_process_1.exit)(1);
15
19
  }
16
- rounds = rounds.filter((el) => el.startsAt !== undefined);
17
20
  for (const round of rounds) {
18
- await commandHandler_1.client
19
- .POST("/broadcast/round/{broadcastRoundId}/edit", {
21
+ await (0, commandHandler_1.handleApiResponse)(commandHandler_1.client.POST("/broadcast/round/{broadcastRoundId}/edit", {
20
22
  params: {
21
23
  path: { broadcastRoundId: round.id },
22
24
  query: { patch: 1 },
@@ -24,16 +26,7 @@ const fixScheduleRounds = async (rounds, timeDiff, roundsToFix) => {
24
26
  body: {
25
27
  startsAt: round.startsAt + timeDiff,
26
28
  },
27
- })
28
- .then((response) => {
29
- if (response.response.ok)
30
- console.log(colors_1.default.green(`Successfully fixed schedule for round ${colors_1.default.whiteBold(round.id)}.`));
31
- else
32
- console.error(colors_1.default.red(`Failed to fix schedule for round ${colors_1.default.whiteBold(round.id)}: ${colors_1.default.whiteBold(response.response.statusText)}`));
33
- })
34
- .catch((error) => {
35
- console.error(colors_1.default.red(`Error fixing schedule for round ${colors_1.default.whiteBold(round.id)}:`), error);
36
- });
29
+ }), `Successfully fixed schedule for round ${colors_1.default.whiteBold(round.id)}.`, `Error fixing schedule for round ${colors_1.default.whiteBold(round.id)}`);
37
30
  await (0, commandHandler_1.sleep)(200);
38
31
  }
39
32
  };
@@ -43,6 +36,8 @@ const translateRoundsToFix = (arg) => {
43
36
  for (const part of parts) {
44
37
  if (part.endsWith("+")) {
45
38
  const start = parseInt(part.slice(0, -1), 10);
39
+ if (isNaN(start))
40
+ continue;
46
41
  for (let i = start; i <= 64; i++) {
47
42
  rounds.push(i);
48
43
  }
@@ -51,16 +46,20 @@ const translateRoundsToFix = (arg) => {
51
46
  const [startStr, endStr] = part.split("-");
52
47
  const start = parseInt(startStr, 10);
53
48
  const end = parseInt(endStr, 10);
49
+ if (isNaN(start) || isNaN(end))
50
+ continue;
54
51
  for (let i = start; i <= end; i++) {
55
52
  rounds.push(i);
56
53
  }
57
54
  }
58
55
  else {
59
56
  const roundNum = parseInt(part, 10);
57
+ if (isNaN(roundNum))
58
+ continue;
60
59
  rounds.push(roundNum);
61
60
  }
62
61
  }
63
- return rounds;
62
+ return [...new Set(rounds)];
64
63
  };
65
64
  const fixScheduleCommand = async (args) => {
66
65
  const [broadcastId, timeDiffStr] = args.slice(0, 2);
@@ -8,8 +8,7 @@ const node_process_1 = require("node:process");
8
8
  const commandHandler_1 = require("../utils/commandHandler");
9
9
  const getInfoBroadcast_1 = require("../utils/getInfoBroadcast");
10
10
  const colors_1 = __importDefault(require("../utils/colors"));
11
- const setLichessGames = (round, games) => commandHandler_1.client
12
- .POST("/broadcast/round/{broadcastRoundId}/edit", {
11
+ const setLichessGames = (round, games) => (0, commandHandler_1.handleApiResponse)(commandHandler_1.client.POST("/broadcast/round/{broadcastRoundId}/edit", {
13
12
  params: {
14
13
  path: { broadcastRoundId: round.id },
15
14
  query: { patch: 1 },
@@ -18,16 +17,7 @@ const setLichessGames = (round, games) => commandHandler_1.client
18
17
  syncSource: "ids",
19
18
  syncIds: games,
20
19
  },
21
- })
22
- .then((response) => {
23
- if (response.response.ok)
24
- console.log(colors_1.default.green(`Successfully set games for round ${colors_1.default.whiteBold(round.id)} to ${colors_1.default.whiteBold(games)}.`));
25
- else
26
- console.error(colors_1.default.red(`Failed to set games for round ${colors_1.default.whiteBold(round.id)}: ${colors_1.default.whiteBold(response.response.statusText)}`));
27
- })
28
- .catch((error) => {
29
- console.error(colors_1.default.red(`Error setting games for round ${colors_1.default.whiteBold(round.id)}:`), error);
30
- });
20
+ }), `Successfully set games for round ${colors_1.default.whiteBold(round.id)} to ${colors_1.default.whiteBold(games)}.`, `Error setting games for round ${colors_1.default.whiteBold(round.id)}`);
31
21
  const setLichessGamesCommand = async (args) => {
32
22
  const bId = args.shift();
33
23
  const games = args.slice(0, 64).join(" ");
@@ -40,6 +30,6 @@ const setLichessGamesCommand = async (args) => {
40
30
  console.error(colors_1.default.red(`Broadcast round with ID ${colors_1.default.whiteBold(bId)} not found or has no rounds.`));
41
31
  (0, node_process_1.exit)(1);
42
32
  }
43
- setLichessGames(round, games);
33
+ await setLichessGames(round, games);
44
34
  };
45
35
  exports.setLichessGamesCommand = setLichessGamesCommand;
@@ -9,11 +9,10 @@ const commandHandler_1 = require("../utils/commandHandler");
9
9
  const getInfoBroadcast_1 = require("../utils/getInfoBroadcast");
10
10
  const colors_1 = __importDefault(require("../utils/colors"));
11
11
  const setPGN = async (rounds, urlRound, setRoundFilter, setSliceFilter = null) => {
12
- for (let rN = 1; rN <= rounds.length; rN++) {
13
- const round = rounds[rN - 1];
12
+ for (const [index, round] of rounds.entries()) {
13
+ const rN = index + 1;
14
14
  const url = urlRound(rN);
15
- await commandHandler_1.client
16
- .POST("/broadcast/round/{broadcastRoundId}/edit", {
15
+ await (0, commandHandler_1.handleApiResponse)(commandHandler_1.client.POST("/broadcast/round/{broadcastRoundId}/edit", {
17
16
  params: {
18
17
  path: { broadcastRoundId: round.id },
19
18
  query: { patch: 1 },
@@ -22,18 +21,9 @@ const setPGN = async (rounds, urlRound, setRoundFilter, setSliceFilter = null) =
22
21
  syncSource: "url",
23
22
  syncUrl: url,
24
23
  onlyRound: setRoundFilter ? rN : undefined,
25
- slices: setSliceFilter ? setSliceFilter : undefined,
24
+ slices: setSliceFilter || undefined,
26
25
  },
27
- })
28
- .then((response) => {
29
- if (response.response.ok)
30
- console.log(colors_1.default.green(`Successfully set source for round ${colors_1.default.whiteBold(round.id)} to ${colors_1.default.whiteBold(url)}.`));
31
- else
32
- console.error(colors_1.default.red(`Failed to set source for round ${colors_1.default.whiteBold(round.id)}: ${colors_1.default.whiteBold(response.response.statusText)}`));
33
- })
34
- .catch((error) => {
35
- console.error(colors_1.default.red(`Error setting source for round ${colors_1.default.whiteBold(round.id)}:`), error);
36
- });
26
+ }), `Successfully set source for round ${colors_1.default.whiteBold(round.id)} to ${colors_1.default.whiteBold(url)}.`, `Error setting source for round ${colors_1.default.whiteBold(round.id)}`);
37
27
  await (0, commandHandler_1.sleep)(200);
38
28
  }
39
29
  };
@@ -49,27 +39,24 @@ const setPGNCommand = async (args) => {
49
39
  (0, node_process_1.exit)(1);
50
40
  }
51
41
  const urlRound = (roundNum) => roundNum ? sourcePGN.replaceAll("{}", roundNum.toString()) : sourcePGN;
52
- let isLCC = false;
53
42
  try {
54
43
  const url = new URL(urlRound());
55
- if (!url.protocol.startsWith("http"))
56
- throw new Error();
57
- isLCC = url.hostname === "view.livechesscloud.com";
58
- if (isLCC && url.hash.length > 1 && !url.hash.endsWith("/{}"))
59
- throw new Error();
44
+ if (!url.protocol.startsWith("http")) {
45
+ throw new Error("Invalid protocol");
46
+ }
47
+ const isLCC = url.hostname === "view.livechesscloud.com";
48
+ if (isLCC && url.hash.length > 1 && !url.hash.endsWith("/{}")) {
49
+ console.error(colors_1.default.red('Invalid URL. For livechesscloud URLs, please ensure it ends with "/{}".'));
50
+ (0, node_process_1.exit)(1);
51
+ }
60
52
  }
61
- catch {
62
- console.error(colors_1.default.red(isLCC
63
- ? 'Invalid URL. For livechesscloud URLs, please ensure it ends with "/{}".'
64
- : 'Invalid URL. Must be http/https with "{}" as round placeholder.'));
53
+ catch (error) {
54
+ console.error(colors_1.default.red('Invalid URL. Must be http/https with "{}" as round placeholder.'));
65
55
  (0, node_process_1.exit)(1);
66
56
  }
67
57
  const setRoundFilter = args.includes("--withFilter");
68
58
  const sliceIndex = args.indexOf("--slice");
69
- let setSliceFilter = null;
70
- if (sliceIndex !== -1 && args.length > sliceIndex + 1) {
71
- setSliceFilter = args[sliceIndex + 1];
72
- }
73
- setPGN(bcast.rounds, urlRound, setRoundFilter, setSliceFilter);
59
+ const setSliceFilter = sliceIndex !== -1 ? args[sliceIndex + 1] || null : null;
60
+ await setPGN(bcast.rounds, urlRound, setRoundFilter, setSliceFilter);
74
61
  };
75
62
  exports.setPGNCommand = setPGNCommand;
package/dist/index.js CHANGED
@@ -5,13 +5,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const node_process_1 = require("node:process");
8
+ const node_fs_1 = require("node:fs");
9
+ const node_path_1 = require("node:path");
8
10
  const commandHandler_1 = require("./utils/commandHandler");
9
11
  const help_1 = require("./utils/help");
10
12
  const colors_1 = __importDefault(require("./utils/colors"));
11
13
  (async () => {
12
14
  if (commandHandler_1.args.includes("--version") || commandHandler_1.args.includes("-v")) {
13
- const { version } = require("../package.json");
14
- console.log(`${colors_1.default.whiteBold("libroadcast-cli")} ${colors_1.default.underItalic(`v${version}`)}`);
15
+ const packageJson = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(__dirname, "../package.json"), "utf-8"));
16
+ console.log(`${colors_1.default.whiteBold("libroadcast-cli")} ${colors_1.default.underItalic(`v${packageJson.version}`)}`);
15
17
  (0, node_process_1.exit)(0);
16
18
  }
17
19
  if (commandHandler_1.args.length === 0 || (0, help_1.includeHelp)(commandHandler_1.args[0])) {
@@ -28,8 +30,8 @@ const colors_1 = __importDefault(require("./utils/colors"));
28
30
  console.error(`${colors_1.default.red("Error:")} Command handler not found.`);
29
31
  (0, node_process_1.exit)(1);
30
32
  }
31
- if (!commandHandler_1.LICHESS_TOKEN) {
32
- console.error(`${colors_1.default.red("Error:")} ${colors_1.default.whiteBold("LICHESS_TOKEN")} environment variable is not set.`);
33
+ if (!commandHandler_1.LICHESS_TOKEN?.trim() || !commandHandler_1.LICHESS_TOKEN.startsWith("lip_")) {
34
+ console.error(`${colors_1.default.red("Error:")} ${colors_1.default.whiteBold("LICHESS_TOKEN")} environment variable is not set, empty, or invalid (must start with 'lip_').`);
33
35
  (0, node_process_1.exit)(1);
34
36
  }
35
37
  await handler(commandHandler_1.args);
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.msgCommonErrorHelp = exports.sleep = exports.client = exports.commands = exports.Command = exports.args = exports.LICHESS_TOKEN = void 0;
6
+ exports.handleApiResponse = exports.msgCommonErrorHelp = exports.sleep = exports.client = exports.commands = exports.Command = exports.args = exports.LICHESS_TOKEN = void 0;
7
7
  const node_process_1 = require("node:process");
8
8
  const openapi_fetch_1 = __importDefault(require("openapi-fetch"));
9
9
  const delay_1 = require("../cmd/delay");
@@ -12,7 +12,7 @@ const setLichessGames_1 = require("../cmd/setLichessGames");
12
12
  const fixSchedule_1 = require("../cmd/fixSchedule");
13
13
  const colors_1 = __importDefault(require("./colors"));
14
14
  exports.LICHESS_TOKEN = node_process_1.env.LICHESS_TOKEN;
15
- const LICHESS_DOMAIN = node_process_1.env.LICHESS_DOMAIN || "https://lichess.org/";
15
+ const LICHESS_DOMAIN = (node_process_1.env.LICHESS_DOMAIN || "https://lichess.org").replace(/\/$/, "") + "/";
16
16
  exports.args = node_process_1.argv.slice(2);
17
17
  var Command;
18
18
  (function (Command) {
@@ -41,3 +41,18 @@ const msgCommonErrorHelp = (msg) => {
41
41
  console.info(colors_1.default.blue("Use --help to see usage."));
42
42
  };
43
43
  exports.msgCommonErrorHelp = msgCommonErrorHelp;
44
+ const handleApiResponse = async (promise, successMsg, errorContext) => {
45
+ try {
46
+ const response = await promise;
47
+ if (response.response.ok) {
48
+ console.log(colors_1.default.green(successMsg));
49
+ }
50
+ else {
51
+ console.error(colors_1.default.red(`${errorContext}: ${colors_1.default.whiteBold(response.response.statusText)}`));
52
+ }
53
+ }
54
+ catch (error) {
55
+ console.error(colors_1.default.red(errorContext), error);
56
+ }
57
+ };
58
+ exports.handleApiResponse = handleApiResponse;
@@ -12,7 +12,7 @@ const helpDelay = [
12
12
  ` ${colors_1.default.bold("Note:")} ${colors_1.default.gray("The delay is specified in seconds. (max 3600 seconds = 1 hour)")}`,
13
13
  ` ${colors_1.default.bold("Options:")}`,
14
14
  ` --onlyDelay ${colors_1.default.gray("Set only the delay without changing the start time.")}`,
15
- ` --noDelay ${colors_1.default.gray("Remove the delay from the rounds.")}`,
15
+ ` --noDelay ${colors_1.default.gray("Do not modify the delay, only adjust the start time.")}`,
16
16
  ].join("\n");
17
17
  const helpSetPGN = [
18
18
  ` ${colors_1.default.underItalic("setPGN <broadcastId> <sourcePGNUrl> [--withFilter] [--slice <sliceFilter>]")}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libroadcast-cli",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "CLI to help with broadcast maintenance on Lichess",
5
5
  "main": "dist/index.js",
6
6
  "keywords": [