libroadcast-cli 2.4.0 → 2.4.2
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/cmd/delay.js +19 -26
- package/dist/cmd/fixSchedule.js +22 -29
- package/dist/cmd/login.js +30 -37
- package/dist/cmd/period.js +17 -24
- package/dist/cmd/push.js +26 -33
- package/dist/cmd/pushFilterID.js +35 -39
- package/dist/cmd/score.js +19 -26
- package/dist/cmd/setLichessGames.js +13 -20
- package/dist/cmd/setPGN.js +19 -26
- package/dist/cmd/setPGNMulti.js +23 -30
- package/dist/cmd/startsPrevious.js +14 -21
- package/dist/index.js +23 -28
- package/dist/utils/colors.js +12 -14
- package/dist/utils/commandHandler.js +55 -65
- package/dist/utils/credentials.js +16 -23
- package/dist/utils/getInfoBroadcast.js +6 -14
- package/dist/utils/help.js +104 -112
- package/package.json +2 -2
|
@@ -1,42 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const score_1 = require("../cmd/score");
|
|
20
|
-
const push_1 = require("../cmd/push");
|
|
21
|
-
const pushFilterID_1 = require("../cmd/pushFilterID");
|
|
22
|
-
const login_1 = require("../cmd/login");
|
|
23
|
-
const credentials_1 = require("./credentials");
|
|
1
|
+
import { argv } from "node:process";
|
|
2
|
+
import createClient from "openapi-fetch";
|
|
3
|
+
import cl from "./colors.js";
|
|
4
|
+
const __dirname = import.meta.dirname;
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { delayCommand } from "../cmd/delay.js";
|
|
8
|
+
import { setPGNCommand } from "../cmd/setPGN.js";
|
|
9
|
+
import { setPGNMultiCommand } from "../cmd/setPGNMulti.js";
|
|
10
|
+
import { setLichessGamesCommand } from "../cmd/setLichessGames.js";
|
|
11
|
+
import { fixScheduleCommand } from "../cmd/fixSchedule.js";
|
|
12
|
+
import { startsPreviousCommand } from "../cmd/startsPrevious.js";
|
|
13
|
+
import { periodCommand } from "../cmd/period.js";
|
|
14
|
+
import { scoreCommand } from "../cmd/score.js";
|
|
15
|
+
import { pushCommand } from "../cmd/push.js";
|
|
16
|
+
import { pushFilterIDCommand } from "../cmd/pushFilterID.js";
|
|
17
|
+
import { loginCommand } from "../cmd/login.js";
|
|
18
|
+
import { getStoredCredentials } from "./credentials.js";
|
|
24
19
|
const getToken = () => {
|
|
25
|
-
const stored =
|
|
20
|
+
const stored = getStoredCredentials();
|
|
26
21
|
return stored?.lichessToken;
|
|
27
22
|
};
|
|
28
23
|
const getDomain = () => {
|
|
29
|
-
const stored =
|
|
24
|
+
const stored = getStoredCredentials();
|
|
30
25
|
if (stored?.lichessDomain) {
|
|
31
26
|
return stored.lichessDomain.replace(/\/$/, "") + "/";
|
|
32
27
|
}
|
|
33
28
|
return "https://lichess.org/";
|
|
34
29
|
};
|
|
35
|
-
|
|
30
|
+
export const LICHESS_TOKEN = getToken();
|
|
36
31
|
const LICHESS_DOMAIN = getDomain();
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
var Command;
|
|
32
|
+
export const args = argv.slice(2);
|
|
33
|
+
export const packageJson = JSON.parse(readFileSync(join(__dirname, "../../package.json"), "utf-8"));
|
|
34
|
+
export var Command;
|
|
40
35
|
(function (Command) {
|
|
41
36
|
Command["Login"] = "login";
|
|
42
37
|
Command["Delay"] = "delay";
|
|
@@ -49,51 +44,48 @@ var Command;
|
|
|
49
44
|
Command["Score"] = "score";
|
|
50
45
|
Command["Push"] = "push";
|
|
51
46
|
Command["PushFilterID"] = "pushFilterID";
|
|
52
|
-
})(Command || (
|
|
53
|
-
|
|
54
|
-
[Command.Login,
|
|
55
|
-
[Command.Delay,
|
|
56
|
-
[Command.SetPGN,
|
|
57
|
-
[Command.SetPGNMulti,
|
|
58
|
-
[Command.SetLichessGames,
|
|
59
|
-
[Command.FixSchedule,
|
|
60
|
-
[Command.StartsPrevious,
|
|
61
|
-
[Command.Period,
|
|
62
|
-
[Command.Score,
|
|
63
|
-
[Command.Push,
|
|
64
|
-
[Command.PushFilterID,
|
|
47
|
+
})(Command || (Command = {}));
|
|
48
|
+
export const commands = new Map([
|
|
49
|
+
[Command.Login, loginCommand],
|
|
50
|
+
[Command.Delay, delayCommand],
|
|
51
|
+
[Command.SetPGN, setPGNCommand],
|
|
52
|
+
[Command.SetPGNMulti, setPGNMultiCommand],
|
|
53
|
+
[Command.SetLichessGames, setLichessGamesCommand],
|
|
54
|
+
[Command.FixSchedule, fixScheduleCommand],
|
|
55
|
+
[Command.StartsPrevious, startsPreviousCommand],
|
|
56
|
+
[Command.Period, periodCommand],
|
|
57
|
+
[Command.Score, scoreCommand],
|
|
58
|
+
[Command.Push, pushCommand],
|
|
59
|
+
[Command.PushFilterID, pushFilterIDCommand],
|
|
65
60
|
]);
|
|
66
|
-
|
|
61
|
+
export const client = createClient({
|
|
67
62
|
baseUrl: LICHESS_DOMAIN,
|
|
68
63
|
headers: {
|
|
69
|
-
Authorization: `Bearer ${
|
|
64
|
+
Authorization: `Bearer ${LICHESS_TOKEN}`,
|
|
70
65
|
Accept: "application/json",
|
|
71
|
-
"User-Agent":
|
|
66
|
+
"User-Agent": packageJson.name + "/" + packageJson.version,
|
|
72
67
|
},
|
|
73
68
|
});
|
|
74
|
-
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
console.
|
|
78
|
-
console.info(colors_1.default.blue("Use --help to see usage."));
|
|
69
|
+
export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
70
|
+
export const msgCommonErrorHelp = (msg) => {
|
|
71
|
+
console.error(cl.red(msg));
|
|
72
|
+
console.info(cl.blue("Use --help to see usage."));
|
|
79
73
|
};
|
|
80
|
-
|
|
81
|
-
const handleApiResponse = async (promise, successMsg, errorContext) => {
|
|
74
|
+
export const handleApiResponse = async (promise, successMsg, errorContext) => {
|
|
82
75
|
try {
|
|
83
76
|
const response = await promise;
|
|
84
77
|
if (response.response.ok) {
|
|
85
|
-
console.log(
|
|
78
|
+
console.log(cl.green(successMsg));
|
|
86
79
|
}
|
|
87
80
|
else {
|
|
88
|
-
console.error(
|
|
81
|
+
console.error(cl.red(`${errorContext}: ${cl.whiteBold(response.response.statusText)}`));
|
|
89
82
|
}
|
|
90
83
|
}
|
|
91
84
|
catch (error) {
|
|
92
|
-
console.error(
|
|
85
|
+
console.error(cl.red(errorContext), error);
|
|
93
86
|
}
|
|
94
87
|
};
|
|
95
|
-
|
|
96
|
-
const translateRoundsToFix = (arg) => {
|
|
88
|
+
export const translateRoundsToFix = (arg) => {
|
|
97
89
|
const rounds = [];
|
|
98
90
|
const parts = arg.split(",");
|
|
99
91
|
for (const part of parts) {
|
|
@@ -124,32 +116,30 @@ const translateRoundsToFix = (arg) => {
|
|
|
124
116
|
}
|
|
125
117
|
return [...new Set(rounds)];
|
|
126
118
|
};
|
|
127
|
-
|
|
128
|
-
const checkTokenScopes = async (modRequired) => {
|
|
119
|
+
export const checkTokenScopes = async (modRequired) => {
|
|
129
120
|
const requiredScopes = ["study:read", "study:write"];
|
|
130
121
|
if (modRequired)
|
|
131
122
|
requiredScopes.push("web:mod");
|
|
132
|
-
const stored =
|
|
123
|
+
const stored = getStoredCredentials();
|
|
133
124
|
let scopes = [];
|
|
134
125
|
if (stored?.scopes) {
|
|
135
126
|
scopes = stored.scopes;
|
|
136
127
|
}
|
|
137
128
|
else {
|
|
138
|
-
const response = await
|
|
129
|
+
const response = await client.POST("/api/token/test", {
|
|
139
130
|
headers: {
|
|
140
131
|
"Content-Type": "text/plain",
|
|
141
132
|
},
|
|
142
|
-
body:
|
|
133
|
+
body: LICHESS_TOKEN,
|
|
143
134
|
bodySerializer: (body) => body,
|
|
144
135
|
});
|
|
145
136
|
const data = await response.data;
|
|
146
|
-
const scopesStr = data?.[
|
|
137
|
+
const scopesStr = data?.[LICHESS_TOKEN]?.scopes;
|
|
147
138
|
scopes = scopesStr ? scopesStr.split(",").map((s) => s.trim()) : [];
|
|
148
139
|
}
|
|
149
140
|
const missingScopes = requiredScopes.filter((scope) => !scopes.includes(scope));
|
|
150
141
|
if (missingScopes.length > 0) {
|
|
151
|
-
console.error(
|
|
142
|
+
console.error(cl.red(`Error: Missing required token scopes: ${missingScopes.join(", ")}`));
|
|
152
143
|
process.exit(1);
|
|
153
144
|
}
|
|
154
145
|
};
|
|
155
|
-
exports.checkTokenScopes = checkTokenScopes;
|
|
@@ -1,45 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const node_os_1 = require("node:os");
|
|
7
|
-
const CONFIG_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), ".libroadcast");
|
|
8
|
-
const CREDENTIALS_FILE = (0, node_path_1.join)(CONFIG_DIR, "credentials.json");
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync, } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
const CONFIG_DIR = join(homedir(), ".libroadcast");
|
|
5
|
+
const CREDENTIALS_FILE = join(CONFIG_DIR, "credentials.json");
|
|
9
6
|
const ensureConfigDir = () => {
|
|
10
|
-
if (!
|
|
11
|
-
|
|
7
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
8
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
12
9
|
}
|
|
13
10
|
};
|
|
14
|
-
const getStoredCredentials = () => {
|
|
11
|
+
export const getStoredCredentials = () => {
|
|
15
12
|
try {
|
|
16
|
-
if (!
|
|
13
|
+
if (!existsSync(CREDENTIALS_FILE)) {
|
|
17
14
|
return null;
|
|
18
15
|
}
|
|
19
|
-
const content =
|
|
16
|
+
const content = readFileSync(CREDENTIALS_FILE, "utf-8");
|
|
20
17
|
return JSON.parse(content);
|
|
21
18
|
}
|
|
22
19
|
catch (error) {
|
|
23
20
|
return null;
|
|
24
21
|
}
|
|
25
22
|
};
|
|
26
|
-
|
|
27
|
-
const saveCredentials = (credentials) => {
|
|
23
|
+
export const saveCredentials = (credentials) => {
|
|
28
24
|
ensureConfigDir();
|
|
29
|
-
|
|
25
|
+
writeFileSync(CREDENTIALS_FILE, JSON.stringify(credentials, null, 2), "utf-8");
|
|
30
26
|
};
|
|
31
|
-
|
|
32
|
-
const clearCredentials = () => {
|
|
27
|
+
export const clearCredentials = () => {
|
|
33
28
|
try {
|
|
34
|
-
if (
|
|
35
|
-
|
|
29
|
+
if (existsSync(CREDENTIALS_FILE)) {
|
|
30
|
+
unlinkSync(CREDENTIALS_FILE);
|
|
36
31
|
}
|
|
37
32
|
}
|
|
38
33
|
catch (error) {
|
|
39
34
|
}
|
|
40
35
|
};
|
|
41
|
-
|
|
42
|
-
const fetchTokenScopes = async (token, domain) => {
|
|
36
|
+
export const fetchTokenScopes = async (token, domain) => {
|
|
43
37
|
try {
|
|
44
38
|
const normalizedDomain = domain.replace(/\/$/, "") + "/";
|
|
45
39
|
const url = `${normalizedDomain}api/token/test`;
|
|
@@ -61,4 +55,3 @@ const fetchTokenScopes = async (token, domain) => {
|
|
|
61
55
|
throw new Error(`Failed to fetch token scopes: ${error instanceof Error ? error.message : String(error)}`);
|
|
62
56
|
}
|
|
63
57
|
};
|
|
64
|
-
exports.fetchTokenScopes = fetchTokenScopes;
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getBroadcastRound = exports.getBroadcast = void 0;
|
|
7
|
-
const commandHandler_1 = require("./commandHandler");
|
|
8
|
-
const colors_1 = __importDefault(require("./colors"));
|
|
9
|
-
const getBroadcast = (broadcastId) => commandHandler_1.client
|
|
1
|
+
import { client } from "./commandHandler.js";
|
|
2
|
+
import cl from "./colors.js";
|
|
3
|
+
export const getBroadcast = (broadcastId) => client
|
|
10
4
|
.GET("/api/broadcast/{broadcastTournamentId}", {
|
|
11
5
|
params: {
|
|
12
6
|
path: { broadcastTournamentId: broadcastId },
|
|
@@ -14,11 +8,10 @@ const getBroadcast = (broadcastId) => commandHandler_1.client
|
|
|
14
8
|
})
|
|
15
9
|
.then((response) => response.data)
|
|
16
10
|
.catch((error) => {
|
|
17
|
-
console.error(
|
|
11
|
+
console.error(cl.red("Error fetching broadcast:"), error);
|
|
18
12
|
return null;
|
|
19
13
|
});
|
|
20
|
-
|
|
21
|
-
const getBroadcastRound = (roundId) => commandHandler_1.client
|
|
14
|
+
export const getBroadcastRound = (roundId) => client
|
|
22
15
|
.GET("/api/broadcast/{broadcastTournamentSlug}/{broadcastRoundSlug}/{broadcastRoundId}", {
|
|
23
16
|
params: {
|
|
24
17
|
path: {
|
|
@@ -30,7 +23,6 @@ const getBroadcastRound = (roundId) => commandHandler_1.client
|
|
|
30
23
|
})
|
|
31
24
|
.then((response) => response.data?.round)
|
|
32
25
|
.catch((error) => {
|
|
33
|
-
console.error(
|
|
26
|
+
console.error(cl.red("Error fetching broadcast round:"), error);
|
|
34
27
|
return null;
|
|
35
28
|
});
|
|
36
|
-
exports.getBroadcastRound = getBroadcastRound;
|
package/dist/utils/help.js
CHANGED
|
@@ -1,98 +1,92 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.includeHelp = exports.showHelp = void 0;
|
|
7
|
-
const commandHandler_1 = require("./commandHandler");
|
|
8
|
-
const colors_1 = __importDefault(require("./colors"));
|
|
1
|
+
import { Command } from "./commandHandler.js";
|
|
2
|
+
import cl from "./colors.js";
|
|
9
3
|
const helpLogin = [
|
|
10
|
-
` ${
|
|
11
|
-
` ${
|
|
12
|
-
` ${
|
|
13
|
-
` ${
|
|
14
|
-
` --logout (-lo) ${
|
|
4
|
+
` ${cl.underItalic("login [--logout]")}`,
|
|
5
|
+
` ${cl.gray("Save your Lichess token and domain for future use.")}`,
|
|
6
|
+
` ${cl.gray("This allows you to use the CLI without setting environment variables.")}`,
|
|
7
|
+
` ${cl.bold("Options:")}`,
|
|
8
|
+
` --logout (-lo) ${cl.gray("Clear saved credentials and log out.")}`,
|
|
15
9
|
].join("\n");
|
|
16
10
|
const helpDelay = [
|
|
17
|
-
` ${
|
|
18
|
-
` ${
|
|
19
|
-
` ${
|
|
20
|
-
` ${
|
|
21
|
-
` --onlyDelay ${
|
|
22
|
-
` --noDelay ${
|
|
23
|
-
` --rounds <roundsToFix> ${
|
|
11
|
+
` ${cl.underItalic("delay <broadcastId> <delayInSeconds> [--onlyDelay] [--noDelay] [--rounds <roundsToFix>]")} `,
|
|
12
|
+
` ${cl.gray("Sets the delay for all rounds in the specified broadcast.")}`,
|
|
13
|
+
` ${cl.bold("Note:")} ${cl.gray("The delay is specified in seconds. (max 3600 seconds = 1 hour)")}`,
|
|
14
|
+
` ${cl.bold("Options:")}`,
|
|
15
|
+
` --onlyDelay ${cl.gray("Set only the delay without changing the start time.")}`,
|
|
16
|
+
` --noDelay ${cl.gray("Do not modify the delay, only adjust the start time.")}`,
|
|
17
|
+
` --rounds <roundsToFix> ${cl.gray("Specify which rounds to fix using formats like '1-4', '8+', '3,5,7', etc.")}`,
|
|
24
18
|
].join("\n");
|
|
25
19
|
const helpSetPGN = [
|
|
26
|
-
` ${
|
|
27
|
-
` ${
|
|
28
|
-
` ${
|
|
29
|
-
` ${
|
|
30
|
-
` ${
|
|
31
|
-
` --withFilter ${
|
|
32
|
-
` --slice <sliceFilter> ${
|
|
33
|
-
` --rounds <roundsToFix> ${
|
|
20
|
+
` ${cl.underItalic("setPGN <broadcastId> <sourcePGNUrl> [--withFilter] [--slice <sliceFilter>] [--rounds <roundsToFix>]")}`,
|
|
21
|
+
` ${cl.gray("Sets the source PGN URL for all rounds in the specified broadcast.")}`,
|
|
22
|
+
` ${cl.italic("(optional)")} ${cl.gray('Use "{}" in the URL as a placeholder for the round number.')}`,
|
|
23
|
+
` ${cl.bold("Note:")} ${cl.gray('For livechesscloud URLs, please ensure it ends with "/{}".')}`,
|
|
24
|
+
` ${cl.bold("Options:")}`,
|
|
25
|
+
` --withFilter ${cl.gray("Apply round number filtering based on round number.")}`,
|
|
26
|
+
` --slice <sliceFilter> ${cl.gray("Apply slice filtering using the provided filter string.")}`,
|
|
27
|
+
` --rounds <roundsToFix> ${cl.gray("Specify which rounds to fix using formats like '1-4', '8+', '3,5,7', etc.")}`,
|
|
34
28
|
].join("\n");
|
|
35
29
|
const helpSetPGNMulti = [
|
|
36
|
-
` ${
|
|
37
|
-
` ${
|
|
38
|
-
` ${
|
|
39
|
-
` ${
|
|
40
|
-
` ${
|
|
41
|
-
` ${
|
|
42
|
-
` --withFilter ${
|
|
43
|
-
` --onlyGames <sliceFilter> ${
|
|
44
|
-
` --rounds <roundsToFix> ${
|
|
30
|
+
` ${cl.underItalic("setPGNMulti <broadcastId> <sourcePGNUrl> <gamesNum> [--withFilter] [--onlyGames <sliceFilter>] [--rounds <roundsToFix>]")}`,
|
|
31
|
+
` ${cl.gray("Sets the source PGN URLs for all rounds in the specified broadcast.")}`,
|
|
32
|
+
` ${cl.gray("Use {r} in the URL as a placeholder for the round number and {g} for the game number.")}`,
|
|
33
|
+
` ${cl.gray("Use the gamesNum parameter to specify how many games per round.")}`,
|
|
34
|
+
` ${cl.bold("Note:")} ${cl.gray('For broadcasts with multiple rounds, the source PGN URLs must include the "{g}" placeholder for round numbers.')}`,
|
|
35
|
+
` ${cl.bold("Options:")}`,
|
|
36
|
+
` --withFilter ${cl.gray("Apply round number filtering based on round number.")}`,
|
|
37
|
+
` --onlyGames <sliceFilter> ${cl.gray("Apply slice filtering using the provided filter string.")}`,
|
|
38
|
+
` --rounds <roundsToFix> ${cl.gray("Specify which rounds to fix using formats like '1-4', '8+', '3,5,7', etc.")}`,
|
|
45
39
|
].join("\n");
|
|
46
40
|
const helpSetLichessGames = [
|
|
47
|
-
` ${
|
|
48
|
-
` ${
|
|
49
|
-
` ${
|
|
41
|
+
` ${cl.underItalic("setLichessGames <broadcastRoundId> <gameIds...>")}`,
|
|
42
|
+
` ${cl.gray("Sets the games for the specified broadcast round using Lichess game IDs.")}`,
|
|
43
|
+
` ${cl.bold("Note:")} ${cl.gray("Maximum of 64 game IDs can be provided.")}`,
|
|
50
44
|
].join("\n");
|
|
51
45
|
const helpFixSchedule = [
|
|
52
|
-
` ${
|
|
53
|
-
` ${
|
|
54
|
-
` ${
|
|
55
|
-
` ${
|
|
56
|
-
` --rounds <roundsToFix> ${
|
|
46
|
+
` ${cl.underItalic("fixSchedule <broadcastId> <timeDiff> [--rounds <roundsToFix>]")}`,
|
|
47
|
+
` ${cl.gray("Fixes the schedule of rounds in the specified broadcast by applying a time difference.")}`,
|
|
48
|
+
` ${cl.bold("Note:")} ${cl.gray('The time difference should be in a format like "1h", "30m", "15s", etc.')}`,
|
|
49
|
+
` ${cl.bold("Options:")}`,
|
|
50
|
+
` --rounds <roundsToFix> ${cl.gray("Specify which rounds to fix using formats like '1-4', '8+', '3,5,7', etc.")}`,
|
|
57
51
|
].join("\n");
|
|
58
52
|
const helpStartsPrevious = [
|
|
59
|
-
` ${
|
|
60
|
-
` ${
|
|
53
|
+
` ${cl.underItalic("startsPrevious <broadcastId> <startsPrevious>")}`,
|
|
54
|
+
` ${cl.gray("Sets the startsAfterPrevious flag for all rounds in the specified broadcast.")}`,
|
|
61
55
|
].join("\n");
|
|
62
56
|
const helpSetPeriod = [
|
|
63
|
-
` ${
|
|
64
|
-
` ${
|
|
65
|
-
` ${
|
|
66
|
-
` ${
|
|
67
|
-
` ${
|
|
68
|
-
` --rounds <roundsToFix> ${
|
|
57
|
+
` ${cl.underItalic("period <broadcastId> <periodInSeconds>")}`,
|
|
58
|
+
` ${cl.gray("Sets the period between polling for all rounds in the specified broadcast.")}`,
|
|
59
|
+
` ${cl.redBold("Required:")} ${cl.gray(`Your Lichess token needs the ${cl.whiteBold("web:mod")} scope to use this command. (Broadcast/Study Admin perm required)`)}`,
|
|
60
|
+
` ${cl.bold("Note:")} ${cl.gray("The period is specified in seconds.")}`,
|
|
61
|
+
` ${cl.bold("Options:")}`,
|
|
62
|
+
` --rounds <roundsToFix> ${cl.gray("Specify which rounds to fix using formats like '1-4', '8+', '3,5,7', etc.")}`,
|
|
69
63
|
].join("\n");
|
|
70
64
|
const helpScore = [
|
|
71
|
-
` ${
|
|
72
|
-
` ${
|
|
73
|
-
` ${
|
|
74
|
-
` ${
|
|
75
|
-
` --rounds <roundsToFix> ${
|
|
65
|
+
` ${cl.underItalic("score <broadcastId> <whiteWin> <whiteDraw> <blackWin> <blackDraw> [--rounds <roundsToFix>]")}`,
|
|
66
|
+
` ${cl.gray("Sets the custom scoring for all rounds in the specified broadcast.")}`,
|
|
67
|
+
` ${cl.bold("Note:")} ${cl.gray("Scores must be numbers between 0 and 10.")}`,
|
|
68
|
+
` ${cl.bold("Options:")}`,
|
|
69
|
+
` --rounds <roundsToFix> ${cl.gray("Specify which rounds to fix using formats like '1-4', '8+', '3,5,7', etc.")}`,
|
|
76
70
|
].join("\n");
|
|
77
71
|
const helpPush = [
|
|
78
|
-
` ${
|
|
79
|
-
` ${
|
|
80
|
-
` ${
|
|
81
|
-
` ${
|
|
82
|
-
` --loop <intervalInSeconds> ${
|
|
72
|
+
` ${cl.underItalic("push <roundId> <PGNFromPathOrUrl> [--loop <intervalInSeconds>]")}`,
|
|
73
|
+
` ${cl.gray("Upload a PGN file from a local path or URL to the specified broadcast round.")}`,
|
|
74
|
+
` ${cl.bold("Note:")} ${cl.gray("The PGN file must be accessible from the provided path or URL.")}`,
|
|
75
|
+
` ${cl.bold("Options:")}`,
|
|
76
|
+
` --loop <intervalInSeconds> ${cl.gray("Continuously push the PGN file at the specified interval in seconds.")}`,
|
|
83
77
|
].join("\n");
|
|
84
78
|
const helpPushFilterID = [
|
|
85
|
-
` ${
|
|
86
|
-
` ${
|
|
87
|
-
` ${
|
|
88
|
-
` ${
|
|
89
|
-
` --loop <intervalInSeconds> ${
|
|
79
|
+
` ${cl.underItalic("pushFilterID <roundId> <PGNFromPathOrUrl> <FideIds...> [--loop <intervalInSeconds>]")}`,
|
|
80
|
+
` ${cl.gray("Upload a PGN file from a local path or URL to the specified broadcast round, filtering games by FIDE ID.")}`,
|
|
81
|
+
` ${cl.bold("Note:")} ${cl.gray("The PGN file must be accessible from the provided path or URL.")}`,
|
|
82
|
+
` ${cl.bold("Options:")}`,
|
|
83
|
+
` --loop <intervalInSeconds> ${cl.gray("Continuously push the PGN file at the specified interval in seconds.")}`,
|
|
90
84
|
].join("\n");
|
|
91
85
|
const msg = [
|
|
92
|
-
`${
|
|
86
|
+
`${cl.boldYellow("Usage:")} ${cl.underItalic("<command> [options]")}`,
|
|
93
87
|
``,
|
|
94
88
|
``,
|
|
95
|
-
`${
|
|
89
|
+
`${cl.boldYellow("Commands:")}`,
|
|
96
90
|
helpLogin,
|
|
97
91
|
``,
|
|
98
92
|
helpDelay,
|
|
@@ -116,51 +110,49 @@ const msg = [
|
|
|
116
110
|
helpPushFilterID,
|
|
117
111
|
``,
|
|
118
112
|
``,
|
|
119
|
-
`${
|
|
120
|
-
` ${
|
|
121
|
-
` $ ${
|
|
122
|
-
` ${
|
|
123
|
-
` $ ${
|
|
124
|
-
` ${
|
|
125
|
-
` $ ${
|
|
126
|
-
` ${
|
|
127
|
-
` $ ${
|
|
128
|
-
` ${
|
|
129
|
-
` $ ${
|
|
130
|
-
` ${
|
|
131
|
-
` $ ${
|
|
132
|
-
` ${
|
|
133
|
-
` $ ${
|
|
134
|
-
` ${
|
|
135
|
-
` $ ${
|
|
136
|
-
` ${
|
|
137
|
-
` $ ${
|
|
138
|
-
` ${
|
|
139
|
-
` $ ${
|
|
140
|
-
` ${
|
|
141
|
-
` $ ${
|
|
142
|
-
` ${
|
|
143
|
-
` $ ${
|
|
144
|
-
` ${
|
|
145
|
-
` $ ${
|
|
113
|
+
`${cl.boldYellow("Examples:")}`,
|
|
114
|
+
` ${cl.gray("# Login with your Lichess token (interactive)")}`,
|
|
115
|
+
` $ ${cl.underItalic("login")}`,
|
|
116
|
+
` ${cl.gray("# Login with token as argument")}`,
|
|
117
|
+
` $ ${cl.underItalic("login")} ${cl.italic("lip_yourtoken https://lichess.org")}`,
|
|
118
|
+
` ${cl.gray("# Logout and clear saved credentials")}`,
|
|
119
|
+
` $ ${cl.underItalic("login")} ${cl.italic("--logout")}`,
|
|
120
|
+
` ${cl.gray("# Set a 5-minute delay without changing start time")}`,
|
|
121
|
+
` $ ${cl.underItalic("delay")} ${cl.italic("bcast123 300 --onlyDelay")}`,
|
|
122
|
+
` ${cl.gray("# Set source PGN URL with round and slice filters")}`,
|
|
123
|
+
` $ ${cl.underItalic("setPGN")} ${cl.italic('bcast123 https://example.com/pgns/round-{}/game.pgn --withFilter --slice "1-5,7,9-12"')}`,
|
|
124
|
+
` ${cl.gray("# Set source PGN URLs for multiple games per round")}`,
|
|
125
|
+
` $ ${cl.underItalic("setPGNMulti")} ${cl.italic('bcast123 https://example.com/pgns/round-{r}/game-{g}.pgn 12 --withFilter --onlyGames "1-5,7,9-12"')}`,
|
|
126
|
+
` ${cl.gray("# Set Lichess games for a broadcast round")}`,
|
|
127
|
+
` $ ${cl.underItalic("setLichessGames")} ${cl.italic("round456 gameId1 gameId2 gameId3")}`,
|
|
128
|
+
` ${cl.gray("# Fix schedule of rounds 1 to 4 and all rounds after 8 by adding 15 minutes")}`,
|
|
129
|
+
` $ ${cl.underItalic("fixSchedule")} ${cl.italic("bcast123 15m --rounds 1-4,8+")}`,
|
|
130
|
+
` ${cl.gray("# Set startsAfterPrevious to true for all rounds in a broadcast")}`,
|
|
131
|
+
` $ ${cl.underItalic("startsPrevious")} ${cl.italic("bcast123 true")}`,
|
|
132
|
+
` ${cl.gray("# Set polling period to 10 seconds for all rounds in a broadcast")}`,
|
|
133
|
+
` $ ${cl.underItalic("period")} ${cl.italic("bcast123 10")}`,
|
|
134
|
+
` ${cl.gray("# Set custom scoring for all rounds in a broadcast")}`,
|
|
135
|
+
` $ ${cl.underItalic("score")} ${cl.italic("bcast123 1.0 0.5 1.0 0.5")}`,
|
|
136
|
+
` ${cl.gray("# Push a PGN file in loop mode every 60 seconds")}`,
|
|
137
|
+
` $ ${cl.underItalic("push")} ${cl.italic("round456 /path/to/localfile.pgn --loop 60")}`,
|
|
138
|
+
` ${cl.gray("# Push a PGN file from URL filtering by FIDE IDs in loop mode every 120 seconds")}`,
|
|
139
|
+
` $ ${cl.underItalic("pushFilterID")} ${cl.italic("round456 https://example.com/games.pgn 12345 67890 --loop 120")}`,
|
|
146
140
|
];
|
|
147
|
-
const showHelp = (cmd) => {
|
|
141
|
+
export const showHelp = (cmd) => {
|
|
148
142
|
const ranges = {
|
|
149
|
-
[
|
|
150
|
-
[
|
|
151
|
-
[
|
|
152
|
-
[
|
|
153
|
-
[
|
|
154
|
-
[
|
|
155
|
-
[
|
|
156
|
-
[
|
|
157
|
-
[
|
|
158
|
-
[
|
|
159
|
-
[
|
|
143
|
+
[Command.Login]: helpLogin,
|
|
144
|
+
[Command.Delay]: helpDelay,
|
|
145
|
+
[Command.SetPGN]: helpSetPGN,
|
|
146
|
+
[Command.SetPGNMulti]: helpSetPGNMulti,
|
|
147
|
+
[Command.SetLichessGames]: helpSetLichessGames,
|
|
148
|
+
[Command.FixSchedule]: helpFixSchedule,
|
|
149
|
+
[Command.StartsPrevious]: helpStartsPrevious,
|
|
150
|
+
[Command.Period]: helpSetPeriod,
|
|
151
|
+
[Command.Score]: helpScore,
|
|
152
|
+
[Command.Push]: helpPush,
|
|
153
|
+
[Command.PushFilterID]: helpPushFilterID,
|
|
160
154
|
};
|
|
161
155
|
const range = cmd ? ranges[cmd] : undefined;
|
|
162
156
|
console.info(range ? range : msg.join("\n"));
|
|
163
157
|
};
|
|
164
|
-
|
|
165
|
-
const includeHelp = (str) => ["--help", "-h"].includes(str);
|
|
166
|
-
exports.includeHelp = includeHelp;
|
|
158
|
+
export const includeHelp = (str) => ["--help", "-h"].includes(str);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libroadcast-cli",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "CLI to help with broadcast maintenance on Lichess",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"keywords": [
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
],
|
|
11
11
|
"author": "Sérgio Glórias",
|
|
12
12
|
"license": "MIT",
|
|
13
|
-
"type": "
|
|
13
|
+
"type": "module",
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@lichess-org/types": "^2.0.109",
|
|
16
16
|
"@types/node": "~24.10.4",
|