libroadcast-cli 2.9.0 → 2.11.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 +15 -0
- package/dist/cmd/bulkIDsMulti.js +58 -0
- package/dist/cmd/setLichessGamesMulti.js +38 -0
- package/dist/utils/commandHandler.js +6 -0
- package/dist/utils/help.js +23 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -48,6 +48,12 @@ Commands:
|
|
|
48
48
|
Sets the games for the specified broadcast round using Lichess game IDs.
|
|
49
49
|
Note: Maximum of 64 game IDs can be provided.
|
|
50
50
|
|
|
51
|
+
setLichessGamesMulti "<broadcastRoundIds...>" "<gameIds...>"
|
|
52
|
+
Sets the games for multiple broadcast rounds using Lichess game IDs.
|
|
53
|
+
The first argument is a space-separated list of broadcast round IDs, and the second argument is a space-separated list of game IDs.
|
|
54
|
+
The command will distribute the provided game IDs across the specified broadcast round IDs.
|
|
55
|
+
Note: Maximum of 64 game IDs can be provided. The number of game IDs should ideally be a multiple of the number of broadcast round IDs for even distribution.
|
|
56
|
+
|
|
51
57
|
fixSchedule <broadcastId> <timeDiff> [--rounds <roundsToFix>]
|
|
52
58
|
Fixes the schedule of rounds in the specified broadcast by applying a time difference.
|
|
53
59
|
Note: The time difference should be in a format like "1h", "30m", "15s", etc.
|
|
@@ -92,6 +98,11 @@ Commands:
|
|
|
92
98
|
Options:
|
|
93
99
|
--loop <intervalInSeconds> Continuously push the PGN file at the specified interval in seconds.
|
|
94
100
|
|
|
101
|
+
bulkIDsMulti <bulkID> <broadcastRoundIds...>
|
|
102
|
+
Sets Lichess Game IDs for multiple broadcast rounds using a Bulk Pairing ID.
|
|
103
|
+
The command will fetch game IDs from the specified Bulk Pairing and distribute them across the provided broadcast round IDs.
|
|
104
|
+
|
|
105
|
+
|
|
95
106
|
Examples:
|
|
96
107
|
# Login with your Lichess token (interactive)
|
|
97
108
|
$ login
|
|
@@ -107,6 +118,8 @@ Examples:
|
|
|
107
118
|
$ setPGNMulti bcast123 https://example.com/pgns/round-{r}/game-{g}.pgn 12 --withFilter --onlyGames "1-5,7,9-12"
|
|
108
119
|
# Set Lichess games for a broadcast round
|
|
109
120
|
$ setLichessGames round456 gameId1 gameId2 gameId3
|
|
121
|
+
# Set Lichess games for multiple broadcast rounds
|
|
122
|
+
$ setLichessGamesMulti "roundId1 roundId2 roundId3" "gameId1 gameId2 gameId3"
|
|
110
123
|
# Fix schedule of rounds 1 to 4 and all rounds after 8 by adding 15 minutes
|
|
111
124
|
$ fixSchedule bcast123 15m --rounds 1-4,8+
|
|
112
125
|
# Set startsAfterPrevious to true for all rounds in a broadcast
|
|
@@ -121,6 +134,8 @@ Examples:
|
|
|
121
134
|
$ pushFilterID round456 https://example.com/games.pgn 12345 67890 --loop 120
|
|
122
135
|
# Convert Lichess Usernames source to Lichess Game IDs source for a broadcast round
|
|
123
136
|
$ convertNamesToID round456
|
|
137
|
+
# Set Lichess Game IDs from Bulk Parings for multiple rounds (roundId1, roundId2, roundId3) in a broadcast
|
|
138
|
+
$ bulkIDsMulti bulk123 roundId1 roundId2 roundId3
|
|
124
139
|
```
|
|
125
140
|
|
|
126
141
|
### Test Docker Build Locally
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { exit } from "node:process";
|
|
2
|
+
import { client, msgCommonErrorHelp, handleApiResponse, checkTokenScopes, sleep, } from "../utils/commandHandler.js";
|
|
3
|
+
import { getBroadcastRound } from "../utils/getInfoBroadcast.js";
|
|
4
|
+
import cl from "../utils/colors.js";
|
|
5
|
+
const setLichessGames = (round, games) => handleApiResponse(client.POST("/broadcast/round/{broadcastRoundId}/edit", {
|
|
6
|
+
params: {
|
|
7
|
+
path: { broadcastRoundId: round.id },
|
|
8
|
+
query: { patch: 1 },
|
|
9
|
+
},
|
|
10
|
+
body: {
|
|
11
|
+
syncSource: "ids",
|
|
12
|
+
syncIds: games,
|
|
13
|
+
},
|
|
14
|
+
}), `Successfully set games for round ${cl.whiteBold(round.id)} to ${cl.whiteBold(games)}.`, `Error setting games for round ${cl.whiteBold(round.id)}`);
|
|
15
|
+
const getBulkIds = (bulkID) => client
|
|
16
|
+
.GET("/api/bulk-pairing/{id}", {
|
|
17
|
+
params: { path: { id: bulkID } },
|
|
18
|
+
})
|
|
19
|
+
.then((response) => {
|
|
20
|
+
const data = response.data;
|
|
21
|
+
let ids = data?.games
|
|
22
|
+
.map((game) => game.id)
|
|
23
|
+
.filter((id) => typeof id === "string") || [];
|
|
24
|
+
return ids;
|
|
25
|
+
})
|
|
26
|
+
.catch((error) => {
|
|
27
|
+
console.error(cl.red(`Error fetching bulk pairing data: ${error.message}`));
|
|
28
|
+
return [];
|
|
29
|
+
});
|
|
30
|
+
const splitIdsIntoGroups = (broadcastsIds, gameIds) => gameIds.reduce((groups, id, index) => {
|
|
31
|
+
groups[index % broadcastsIds.length].push(id);
|
|
32
|
+
return groups;
|
|
33
|
+
}, broadcastsIds.map(() => []));
|
|
34
|
+
export const bulkIDsMultiCommand = async (args) => {
|
|
35
|
+
await checkTokenScopes();
|
|
36
|
+
const bulkID = args.shift();
|
|
37
|
+
const broadcastsIds = args;
|
|
38
|
+
if (!bulkID || !broadcastsIds) {
|
|
39
|
+
msgCommonErrorHelp("Broadcast ID and rounds IDs are required.");
|
|
40
|
+
exit(1);
|
|
41
|
+
}
|
|
42
|
+
const gameIds = await getBulkIds(bulkID);
|
|
43
|
+
if (gameIds.length === 0) {
|
|
44
|
+
console.error(cl.red(`No game IDs found for bulk ID ${cl.whiteBold(bulkID)}.`));
|
|
45
|
+
exit(1);
|
|
46
|
+
}
|
|
47
|
+
const groupedIds = splitIdsIntoGroups(broadcastsIds, gameIds);
|
|
48
|
+
for (let [index, group] of groupedIds.entries()) {
|
|
49
|
+
const roundId = broadcastsIds[index];
|
|
50
|
+
const round = await getBroadcastRound(roundId);
|
|
51
|
+
if (!round) {
|
|
52
|
+
console.error(cl.red(`Broadcast round with ID ${cl.whiteBold(roundId)} not found or has no rounds.`));
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
await setLichessGames(round, group.join(" "));
|
|
56
|
+
await sleep(500);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { exit } from "node:process";
|
|
2
|
+
import { client, msgCommonErrorHelp, handleApiResponse, checkTokenScopes, sleep, } from "../utils/commandHandler.js";
|
|
3
|
+
import { getBroadcastRound } from "../utils/getInfoBroadcast.js";
|
|
4
|
+
import cl from "../utils/colors.js";
|
|
5
|
+
const setLichessGames = (round, games) => handleApiResponse(client.POST("/broadcast/round/{broadcastRoundId}/edit", {
|
|
6
|
+
params: {
|
|
7
|
+
path: { broadcastRoundId: round.id },
|
|
8
|
+
query: { patch: 1 },
|
|
9
|
+
},
|
|
10
|
+
body: {
|
|
11
|
+
syncSource: "ids",
|
|
12
|
+
syncIds: games,
|
|
13
|
+
},
|
|
14
|
+
}), `Successfully set games for round ${cl.whiteBold(round.id)} to ${cl.whiteBold(games)}.`, `Error setting games for round ${cl.whiteBold(round.id)}`);
|
|
15
|
+
const splitIdsIntoGroups = (broadcastsIds, gameIds) => gameIds.reduce((groups, id, index) => {
|
|
16
|
+
groups[index % broadcastsIds.length].push(id);
|
|
17
|
+
return groups;
|
|
18
|
+
}, broadcastsIds.map(() => []));
|
|
19
|
+
export const setLichessGamesMultiCommand = async (args) => {
|
|
20
|
+
await checkTokenScopes();
|
|
21
|
+
const bIds = args.shift()?.split(" ");
|
|
22
|
+
const gamesIDs = args.shift()?.split(" ");
|
|
23
|
+
if (!bIds || !gamesIDs) {
|
|
24
|
+
msgCommonErrorHelp("Broadcast ID and games IDs are required.");
|
|
25
|
+
exit(1);
|
|
26
|
+
}
|
|
27
|
+
const groups = splitIdsIntoGroups(bIds, gamesIDs);
|
|
28
|
+
for (let [index, group] of groups.entries()) {
|
|
29
|
+
const roundId = bIds[index];
|
|
30
|
+
const round = await getBroadcastRound(roundId);
|
|
31
|
+
if (!round) {
|
|
32
|
+
console.error(cl.red(`Broadcast round with ID ${cl.whiteBold(roundId)} not found or has no rounds.`));
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
await setLichessGames(round, group.join(" "));
|
|
36
|
+
await sleep(500);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
@@ -18,6 +18,8 @@ import { loginCommand } from "../cmd/login.js";
|
|
|
18
18
|
import { getStoredCredentials } from "./credentials.js";
|
|
19
19
|
import { convertNamesToIDCommand } from "../cmd/convertNamesToID.js";
|
|
20
20
|
import { pushReorderCommand } from "../cmd/pushReorder.js";
|
|
21
|
+
import { bulkIDsMultiCommand } from "../cmd/bulkIDsMulti.js";
|
|
22
|
+
import { setLichessGamesMultiCommand } from "../cmd/setLichessGamesMulti.js";
|
|
21
23
|
const getToken = () => {
|
|
22
24
|
const stored = getStoredCredentials();
|
|
23
25
|
const envToken = process.env.LICHESS_TOKEN;
|
|
@@ -41,6 +43,7 @@ export var Command;
|
|
|
41
43
|
Command["SetPGN"] = "setPGN";
|
|
42
44
|
Command["SetPGNMulti"] = "setPGNMulti";
|
|
43
45
|
Command["SetLichessGames"] = "setLichessGames";
|
|
46
|
+
Command["SetLichessGamesMulti"] = "setLichessGamesMulti";
|
|
44
47
|
Command["FixSchedule"] = "fixSchedule";
|
|
45
48
|
Command["StartsPrevious"] = "startsPrevious";
|
|
46
49
|
Command["Period"] = "period";
|
|
@@ -49,6 +52,7 @@ export var Command;
|
|
|
49
52
|
Command["PushFilterID"] = "pushFilterID";
|
|
50
53
|
Command["ConvertNamesToID"] = "convertNamesToID";
|
|
51
54
|
Command["PushReorder"] = "pushReorder";
|
|
55
|
+
Command["BulkIDsMulti"] = "bulkIDsMulti";
|
|
52
56
|
})(Command || (Command = {}));
|
|
53
57
|
export const commands = new Map([
|
|
54
58
|
[Command.Login, loginCommand],
|
|
@@ -56,6 +60,7 @@ export const commands = new Map([
|
|
|
56
60
|
[Command.SetPGN, setPGNCommand],
|
|
57
61
|
[Command.SetPGNMulti, setPGNMultiCommand],
|
|
58
62
|
[Command.SetLichessGames, setLichessGamesCommand],
|
|
63
|
+
[Command.SetLichessGamesMulti, setLichessGamesMultiCommand],
|
|
59
64
|
[Command.FixSchedule, fixScheduleCommand],
|
|
60
65
|
[Command.StartsPrevious, startsPreviousCommand],
|
|
61
66
|
[Command.Period, periodCommand],
|
|
@@ -64,6 +69,7 @@ export const commands = new Map([
|
|
|
64
69
|
[Command.PushFilterID, pushFilterIDCommand],
|
|
65
70
|
[Command.ConvertNamesToID, convertNamesToIDCommand],
|
|
66
71
|
[Command.PushReorder, pushReorderCommand],
|
|
72
|
+
[Command.BulkIDsMulti, bulkIDsMultiCommand],
|
|
67
73
|
]);
|
|
68
74
|
export const client = createClient({
|
|
69
75
|
baseUrl: LICHESS_DOMAIN,
|
package/dist/utils/help.js
CHANGED
|
@@ -42,6 +42,13 @@ const helpSetLichessGames = [
|
|
|
42
42
|
` ${cl.gray("Sets the games for the specified broadcast round using Lichess game IDs.")}`,
|
|
43
43
|
` ${cl.bold("Note:")} ${cl.gray("Maximum of 64 game IDs can be provided.")}`,
|
|
44
44
|
].join("\n");
|
|
45
|
+
const helpSetLichessGamesMulti = [
|
|
46
|
+
` ${cl.underItalic('setLichessGamesMulti "<broadcastRoundIds...>" "<gameIds...>"')}`,
|
|
47
|
+
` ${cl.gray("Sets the games for multiple broadcast rounds using Lichess game IDs.")}`,
|
|
48
|
+
` ${cl.gray("The first argument is a space-separated list of broadcast round IDs, and the second argument is a space-separated list of game IDs.")}`,
|
|
49
|
+
` ${cl.gray("The command will distribute the provided game IDs across the specified broadcast round IDs.")}`,
|
|
50
|
+
` ${cl.bold("Note:")} ${cl.gray("Maximum of 64 game IDs can be provided. The number of game IDs should ideally be a multiple of the number of broadcast round IDs for even distribution.")}`,
|
|
51
|
+
].join("\n");
|
|
45
52
|
const helpFixSchedule = [
|
|
46
53
|
` ${cl.underItalic("fixSchedule <broadcastId> <timeDiff> [--rounds <roundsToFix>]")}`,
|
|
47
54
|
` ${cl.gray("Fixes the schedule of rounds in the specified broadcast by applying a time difference.")}`,
|
|
@@ -94,6 +101,11 @@ const helpPushReorder = [
|
|
|
94
101
|
` ${cl.bold("Options:")}`,
|
|
95
102
|
` --loop <intervalInSeconds> ${cl.gray("Continuously push the PGN file at the specified interval in seconds.")}`,
|
|
96
103
|
].join("\n");
|
|
104
|
+
const helpBulkIDsMulti = [
|
|
105
|
+
` ${cl.underItalic("bulkIDsMulti <bulkID> <broadcastRoundIds...>")}`,
|
|
106
|
+
` ${cl.gray("Sets Lichess Game IDs for multiple broadcast rounds using a Bulk Pairing ID.")}`,
|
|
107
|
+
` ${cl.gray("The command will fetch game IDs from the specified Bulk Pairing and distribute them across the provided broadcast round IDs.")}`,
|
|
108
|
+
].join("\n");
|
|
97
109
|
const msg = [
|
|
98
110
|
`${cl.boldYellow("Usage:")} ${cl.underItalic("<command> [options]")}`,
|
|
99
111
|
``,
|
|
@@ -109,6 +121,8 @@ const msg = [
|
|
|
109
121
|
``,
|
|
110
122
|
helpSetLichessGames,
|
|
111
123
|
``,
|
|
124
|
+
helpSetLichessGamesMulti,
|
|
125
|
+
``,
|
|
112
126
|
helpFixSchedule,
|
|
113
127
|
``,
|
|
114
128
|
helpStartsPrevious,
|
|
@@ -125,6 +139,9 @@ const msg = [
|
|
|
125
139
|
``,
|
|
126
140
|
helpPushReorder,
|
|
127
141
|
``,
|
|
142
|
+
helpBulkIDsMulti,
|
|
143
|
+
``,
|
|
144
|
+
``,
|
|
128
145
|
`${cl.boldYellow("Examples:")}`,
|
|
129
146
|
` ${cl.gray("# Login with your Lichess token (interactive)")}`,
|
|
130
147
|
` $ ${cl.underItalic("login")}`,
|
|
@@ -140,6 +157,8 @@ const msg = [
|
|
|
140
157
|
` $ ${cl.underItalic("setPGNMulti")} ${cl.italic('bcast123 https://example.com/pgns/round-{r}/game-{g}.pgn 12 --withFilter --onlyGames "1-5,7,9-12"')}`,
|
|
141
158
|
` ${cl.gray("# Set Lichess games for a broadcast round")}`,
|
|
142
159
|
` $ ${cl.underItalic("setLichessGames")} ${cl.italic("round456 gameId1 gameId2 gameId3")}`,
|
|
160
|
+
` ${cl.gray("# Set Lichess games for multiple broadcast rounds")}`,
|
|
161
|
+
` $ ${cl.underItalic("setLichessGamesMulti")} ${cl.italic('"roundId1 roundId2 roundId3" "gameId1 gameId2 gameId3"')}`,
|
|
143
162
|
` ${cl.gray("# Fix schedule of rounds 1 to 4 and all rounds after 8 by adding 15 minutes")}`,
|
|
144
163
|
` $ ${cl.underItalic("fixSchedule")} ${cl.italic("bcast123 15m --rounds 1-4,8+")}`,
|
|
145
164
|
` ${cl.gray("# Set startsAfterPrevious to true for all rounds in a broadcast")}`,
|
|
@@ -154,6 +173,8 @@ const msg = [
|
|
|
154
173
|
` $ ${cl.underItalic("pushFilterID")} ${cl.italic("round456 https://example.com/games.pgn 12345 67890 --loop 120")}`,
|
|
155
174
|
` ${cl.gray("# Convert Lichess Usernames source to Lichess Game IDs source for a broadcast round")}`,
|
|
156
175
|
` $ ${cl.underItalic("convertNamesToID")} ${cl.italic("round456")}`,
|
|
176
|
+
` ${cl.gray("# Set Lichess Game IDs from Bulk Parings for multiple rounds (roundId1, roundId2, roundId3) in a broadcast")}`,
|
|
177
|
+
` $ ${cl.underItalic("bulkIDsMulti")} ${cl.italic("bulk123 roundId1 roundId2 roundId3")}`,
|
|
157
178
|
];
|
|
158
179
|
export const showHelp = (cmd) => {
|
|
159
180
|
const ranges = {
|
|
@@ -162,6 +183,7 @@ export const showHelp = (cmd) => {
|
|
|
162
183
|
[Command.SetPGN]: helpSetPGN,
|
|
163
184
|
[Command.SetPGNMulti]: helpSetPGNMulti,
|
|
164
185
|
[Command.SetLichessGames]: helpSetLichessGames,
|
|
186
|
+
[Command.SetLichessGamesMulti]: helpSetLichessGamesMulti,
|
|
165
187
|
[Command.FixSchedule]: helpFixSchedule,
|
|
166
188
|
[Command.StartsPrevious]: helpStartsPrevious,
|
|
167
189
|
[Command.Period]: helpSetPeriod,
|
|
@@ -170,6 +192,7 @@ export const showHelp = (cmd) => {
|
|
|
170
192
|
[Command.PushFilterID]: helpPushFilterID,
|
|
171
193
|
[Command.ConvertNamesToID]: helpConvertNamesToID,
|
|
172
194
|
[Command.PushReorder]: helpPushReorder,
|
|
195
|
+
[Command.BulkIDsMulti]: helpBulkIDsMulti,
|
|
173
196
|
};
|
|
174
197
|
const range = cmd ? ranges[cmd] : undefined;
|
|
175
198
|
console.info(range ? range : msg.join("\n"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libroadcast-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.0",
|
|
4
4
|
"description": "CLI to help with broadcast maintenance on Lichess",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"keywords": [
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"type": "module",
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@lichess-org/types": "^2.0.109",
|
|
16
|
-
"@types/node": "~24.
|
|
16
|
+
"@types/node": "~24.12.0",
|
|
17
17
|
"chessops": "^0.15.0",
|
|
18
18
|
"ms": "3.0.0-canary.202508261828",
|
|
19
19
|
"openapi-fetch": "^0.17.0"
|