libroadcast-cli 1.8.0 → 1.9.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
@@ -33,6 +33,15 @@ Commands:
33
33
  --withFilter Apply round number filtering based on round number.
34
34
  --slice <sliceFilter> Apply slice filtering using the provided filter string.
35
35
 
36
+ setPGNMulti <broadcastId> <sourcePGNUrl> <gamesNum> [--withFilter] [--onlyGames <sliceFilter>]
37
+ Sets the source PGN URLs for all rounds in the specified broadcast.
38
+ Use {r} in the URL as a placeholder for the round number and {g} for the game number.
39
+ Use the gamesNum parameter to specify how many games per round.
40
+ Note: For broadcasts with multiple rounds, the source PGN URLs must include the "{g}" placeholder for round numbers.
41
+ Options:
42
+ --withFilter Apply round number filtering based on round number.
43
+ --onlyGames <sliceFilter> Apply slice filtering using the provided filter string.
44
+
36
45
  setLichessGames <broadcastRoundId> <gameIds...>
37
46
  Sets the games for the specified broadcast round using Lichess game IDs.
38
47
  Note: Maximum of 64 game IDs can be provided.
@@ -43,14 +52,21 @@ Commands:
43
52
  Options:
44
53
  --rounds <roundsToFix> Specify which rounds to fix using formats like '1-4', '8+', '3,5,7', etc.
45
54
 
55
+ startsPrevious <broadcastId> <startsPrevious>
56
+ Sets the startsAfterPrevious flag for all rounds in the specified broadcast.
57
+
46
58
 
47
59
  Examples:
48
60
  # Set a 5-minute delay without changing start time
49
61
  $ delay bcast123 300 --onlyDelay
50
62
  # Set source PGN URL with round and slice filters
51
63
  $ setPGN bcast123 https://example.com/pgns/round-{}/game.pgn --withFilter --slice "1-5,7,9-12"
64
+ # Set source PGN URLs for multiple games per round
65
+ $ setPGNMulti bcast123 https://example.com/pgns/round-{r}/game-{g}.pgn 12 --withFilter --onlyGames "1-5,7,9-12"
52
66
  # Set Lichess games for a broadcast round
53
67
  $ setLichessGames round456 gameId1 gameId2 gameId3
54
68
  # Fix schedule of rounds 1 to 4 and all rounds after 8 by adding 15 minutes
55
69
  $ fixSchedule bcast123 15m --rounds 1-4,8+
70
+ # Set startsAfterPrevious to true for all rounds in a broadcast
71
+ $ startsPrevious bcast123 true
56
72
  ```
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.setPGNMultiCommand = void 0;
7
+ const node_process_1 = require("node:process");
8
+ const commandHandler_1 = require("../utils/commandHandler");
9
+ const getInfoBroadcast_1 = require("../utils/getInfoBroadcast");
10
+ const colors_1 = __importDefault(require("../utils/colors"));
11
+ const setPGN = async (rounds, urlsRound, gamesNum, setRoundFilter, setSliceFilter = null) => {
12
+ for (const [index, round] of rounds.entries()) {
13
+ const rN = index + 1;
14
+ const urls = urlsRound(gamesNum, rN)
15
+ .filter((_, i) => setSliceFilter ? setSliceFilter.includes(i + 1) : true)
16
+ .join("\n");
17
+ await (0, commandHandler_1.handleApiResponse)(commandHandler_1.client.POST("/broadcast/round/{broadcastRoundId}/edit", {
18
+ params: {
19
+ path: { broadcastRoundId: round.id },
20
+ query: { patch: 1 },
21
+ },
22
+ body: {
23
+ syncSource: "urls",
24
+ syncUrls: urls,
25
+ onlyRound: setRoundFilter ? rN : undefined,
26
+ },
27
+ }), `Successfully set source for round ${colors_1.default.whiteBold(round.id)} to\n${colors_1.default.whiteBold(urls)}`, `Error setting source for round ${colors_1.default.whiteBold(round.id)}`);
28
+ await (0, commandHandler_1.sleep)(200);
29
+ }
30
+ };
31
+ const translateGamesToAdd = (arg, gamesN) => {
32
+ const rounds = [];
33
+ if (arg.trim() === "")
34
+ return null;
35
+ const parts = arg.split(",");
36
+ for (const part of parts) {
37
+ if (part.endsWith("+")) {
38
+ const start = parseInt(part.slice(0, -1), 10);
39
+ if (isNaN(start))
40
+ continue;
41
+ for (let i = start; i <= gamesN; i++) {
42
+ rounds.push(i);
43
+ }
44
+ }
45
+ else if (part.includes("-")) {
46
+ const [startStr, endStr] = part.split("-");
47
+ const start = parseInt(startStr, 10);
48
+ const end = parseInt(endStr, 10);
49
+ if (isNaN(start) || isNaN(end))
50
+ continue;
51
+ for (let i = start; i <= end; i++) {
52
+ rounds.push(i);
53
+ }
54
+ }
55
+ else {
56
+ const roundNum = parseInt(part, 10);
57
+ if (isNaN(roundNum))
58
+ continue;
59
+ rounds.push(roundNum);
60
+ }
61
+ }
62
+ return [...new Set(rounds)];
63
+ };
64
+ const setPGNMultiCommand = async (args) => {
65
+ const [bId, sourcePGNs, gamesN] = args.slice(0, 3);
66
+ if (!bId || !sourcePGNs || !gamesN) {
67
+ (0, commandHandler_1.msgCommonErrorHelp)("Broadcast ID, source PGN URLs, and number of games are required.");
68
+ (0, node_process_1.exit)(1);
69
+ }
70
+ const bcast = await (0, getInfoBroadcast_1.getBroadcast)(bId);
71
+ if (!bcast?.rounds || bcast.rounds.length === 0) {
72
+ (0, commandHandler_1.msgCommonErrorHelp)("No rounds found for the specified broadcast.");
73
+ (0, node_process_1.exit)(1);
74
+ }
75
+ let gamesNum = parseInt(gamesN, 10);
76
+ if (isNaN(gamesNum) || gamesNum <= 0) {
77
+ (0, commandHandler_1.msgCommonErrorHelp)("Number of games must be a positive integer.");
78
+ (0, node_process_1.exit)(1);
79
+ }
80
+ if (bcast.rounds.length > 1 && !sourcePGNs.includes("{g}")) {
81
+ console.error(colors_1.default.red('For broadcasts with multiple rounds, the source PGN URLs must include the "{g}" placeholder for round numbers.'));
82
+ (0, node_process_1.exit)(1);
83
+ }
84
+ const urlRound = (gamesN, roundNum) => {
85
+ let rN = roundNum
86
+ ? sourcePGNs.replaceAll("{r}", roundNum.toString())
87
+ : sourcePGNs;
88
+ let urls = [];
89
+ for (let i = 1; i <= gamesN; i++) {
90
+ urls.push(rN.replaceAll("{g}", i.toString()));
91
+ }
92
+ return urls;
93
+ };
94
+ try {
95
+ const url = new URL(urlRound(gamesNum, 1)[0]);
96
+ if (!url.protocol.startsWith("http")) {
97
+ throw new Error("Invalid protocol");
98
+ }
99
+ const isLCC = url.hostname === "view.livechesscloud.com";
100
+ if (isLCC) {
101
+ console.error(colors_1.default.red("Invalid URL."));
102
+ (0, node_process_1.exit)(1);
103
+ }
104
+ }
105
+ catch (error) {
106
+ console.error(colors_1.default.red('Invalid URL. Must be http/https with "{}" as round placeholder.'));
107
+ (0, node_process_1.exit)(1);
108
+ }
109
+ const setRoundFilter = args.includes("--withFilter");
110
+ const sliceIndex = args.indexOf("--onlyGames");
111
+ const setSliceFilter = sliceIndex !== -1
112
+ ? translateGamesToAdd(args[sliceIndex + 1] || "", gamesNum)
113
+ : null;
114
+ await setPGN(bcast.rounds, urlRound, gamesNum, setRoundFilter, setSliceFilter);
115
+ };
116
+ exports.setPGNMultiCommand = setPGNMultiCommand;
@@ -9,7 +9,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
11
  const setStartsPrevious = async (rounds, startsPrevious) => {
12
- for (const round of rounds) {
12
+ const roundfilter = rounds.filter((r) => r.startsAfterPrevious !== startsPrevious && !r.startsAt);
13
+ for (const round of roundfilter) {
13
14
  await (0, commandHandler_1.handleApiResponse)(commandHandler_1.client.POST("/broadcast/round/{broadcastRoundId}/edit", {
14
15
  params: {
15
16
  path: { broadcastRoundId: round.id },
@@ -9,6 +9,7 @@ const openapi_fetch_1 = __importDefault(require("openapi-fetch"));
9
9
  const colors_1 = __importDefault(require("./colors"));
10
10
  const delay_1 = require("../cmd/delay");
11
11
  const setPGN_1 = require("../cmd/setPGN");
12
+ const setPGNMulti_1 = require("../cmd/setPGNMulti");
12
13
  const setLichessGames_1 = require("../cmd/setLichessGames");
13
14
  const fixSchedule_1 = require("../cmd/fixSchedule");
14
15
  const startsPrevious_1 = require("../cmd/startsPrevious");
@@ -19,6 +20,7 @@ var Command;
19
20
  (function (Command) {
20
21
  Command["Delay"] = "delay";
21
22
  Command["SetPGN"] = "setPGN";
23
+ Command["SetPGNMulti"] = "setPGNMulti";
22
24
  Command["SetLichessGames"] = "setLichessGames";
23
25
  Command["FixSchedule"] = "fixSchedule";
24
26
  Command["StartsPrevious"] = "startsPrevious";
@@ -26,6 +28,7 @@ var Command;
26
28
  exports.commands = new Map([
27
29
  [Command.Delay, delay_1.delayCommand],
28
30
  [Command.SetPGN, setPGN_1.setPGNCommand],
31
+ [Command.SetPGNMulti, setPGNMulti_1.setPGNMultiCommand],
29
32
  [Command.SetLichessGames, setLichessGames_1.setLichessGamesCommand],
30
33
  [Command.FixSchedule, fixSchedule_1.fixScheduleCommand],
31
34
  [Command.StartsPrevious, startsPrevious_1.startsPreviousCommand],
@@ -23,6 +23,16 @@ const helpSetPGN = [
23
23
  ` --withFilter ${colors_1.default.gray("Apply round number filtering based on round number.")}`,
24
24
  ` --slice <sliceFilter> ${colors_1.default.gray("Apply slice filtering using the provided filter string.")}`,
25
25
  ].join("\n");
26
+ const helpSetPGNMulti = [
27
+ ` ${colors_1.default.underItalic("setPGNMulti <broadcastId> <sourcePGNUrl> <gamesNum> [--withFilter] [--onlyGames <sliceFilter>]")}`,
28
+ ` ${colors_1.default.gray("Sets the source PGN URLs for all rounds in the specified broadcast.")}`,
29
+ ` ${colors_1.default.gray("Use {r} in the URL as a placeholder for the round number and {g} for the game number.")}`,
30
+ ` ${colors_1.default.gray("Use the gamesNum parameter to specify how many games per round.")}`,
31
+ ` ${colors_1.default.bold("Note:")} ${colors_1.default.gray('For broadcasts with multiple rounds, the source PGN URLs must include the "{g}" placeholder for round numbers.')}`,
32
+ ` ${colors_1.default.bold("Options:")}`,
33
+ ` --withFilter ${colors_1.default.gray("Apply round number filtering based on round number.")}`,
34
+ ` --onlyGames <sliceFilter> ${colors_1.default.gray("Apply slice filtering using the provided filter string.")}`,
35
+ ].join("\n");
26
36
  const helpSetLichessGames = [
27
37
  ` ${colors_1.default.underItalic("setLichessGames <broadcastRoundId> <gameIds...>")}`,
28
38
  ` ${colors_1.default.gray("Sets the games for the specified broadcast round using Lichess game IDs.")}`,
@@ -48,6 +58,8 @@ const msg = [
48
58
  ``,
49
59
  helpSetPGN,
50
60
  ``,
61
+ helpSetPGNMulti,
62
+ ``,
51
63
  helpSetLichessGames,
52
64
  ``,
53
65
  helpFixSchedule,
@@ -60,6 +72,8 @@ const msg = [
60
72
  ` $ ${colors_1.default.underItalic("delay")} ${colors_1.default.italic("bcast123 300 --onlyDelay")}`,
61
73
  ` ${colors_1.default.gray("# Set source PGN URL with round and slice filters")}`,
62
74
  ` $ ${colors_1.default.underItalic("setPGN")} ${colors_1.default.italic('bcast123 https://example.com/pgns/round-{}/game.pgn --withFilter --slice "1-5,7,9-12"')}`,
75
+ ` ${colors_1.default.gray("# Set source PGN URLs for multiple games per round")}`,
76
+ ` $ ${colors_1.default.underItalic("setPGNMulti")} ${colors_1.default.italic('bcast123 https://example.com/pgns/round-{r}/game-{g}.pgn 12 --withFilter --onlyGames "1-5,7,9-12"')}`,
63
77
  ` ${colors_1.default.gray("# Set Lichess games for a broadcast round")}`,
64
78
  ` $ ${colors_1.default.underItalic("setLichessGames")} ${colors_1.default.italic("round456 gameId1 gameId2 gameId3")}`,
65
79
  ` ${colors_1.default.gray("# Fix schedule of rounds 1 to 4 and all rounds after 8 by adding 15 minutes")}`,
@@ -71,6 +85,7 @@ const showHelp = (cmd) => {
71
85
  const ranges = {
72
86
  [commandHandler_1.Command.Delay]: helpDelay,
73
87
  [commandHandler_1.Command.SetPGN]: helpSetPGN,
88
+ [commandHandler_1.Command.SetPGNMulti]: helpSetPGNMulti,
74
89
  [commandHandler_1.Command.SetLichessGames]: helpSetLichessGames,
75
90
  [commandHandler_1.Command.FixSchedule]: helpFixSchedule,
76
91
  [commandHandler_1.Command.StartsPrevious]: helpStartsPrevious,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libroadcast-cli",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "CLI to help with broadcast maintenance on Lichess",
5
5
  "main": "dist/index.js",
6
6
  "keywords": [
@@ -12,7 +12,7 @@
12
12
  "license": "MIT",
13
13
  "type": "commonjs",
14
14
  "dependencies": {
15
- "@lichess-org/types": "^2.0.94",
15
+ "@lichess-org/types": "^2.0.96",
16
16
  "@types/node": "^24.10.0",
17
17
  "ms": "3.0.0-canary.202508261828",
18
18
  "openapi-fetch": "^0.15.0"