libroadcast-cli 1.0.1 → 1.1.1

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.
@@ -0,0 +1,58 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ version:
7
+ description: 'Version tag (e.g. v1.2.3)'
8
+ required: true
9
+ description:
10
+ description: 'Description'
11
+ required: false
12
+ default: ''
13
+
14
+ permissions:
15
+ id-token: write # Required for OIDC
16
+ contents: read
17
+
18
+ jobs:
19
+ release:
20
+ runs-on: ubuntu-latest
21
+ permissions:
22
+ contents: write
23
+ id-token: write
24
+ steps:
25
+ - run: |
26
+ [[ "${{ github.event.inputs.version }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]] || \
27
+ (echo "Version must start with 'v' and match 'v<major>.<minor>.<patch>'" && exit 1)
28
+ - uses: actions/checkout@v5
29
+ with:
30
+ fetch-depth: 0
31
+ ref: ${{ github.ref }}
32
+ - uses: pnpm/action-setup@v4
33
+ - uses: actions/setup-node@v5
34
+ with:
35
+ node-version: '24'
36
+ registry-url: https://registry.npmjs.org/
37
+ cache: pnpm
38
+ - run: pnpm install
39
+ - run: |
40
+ pnpm run build
41
+ git config user.name "github-actions"
42
+ git config user.email "github-actions@github.com"
43
+ NPM_VERSION="${GITHUB_VERSION#v}"
44
+ pnpm version "$NPM_VERSION" --allow-same-version
45
+ env:
46
+ GITHUB_VERSION: ${{ github.event.inputs.version }}
47
+
48
+ - name: Publish to npm
49
+ run: |
50
+ pnpm publish --provenance --access public
51
+ git push origin HEAD --follow-tags
52
+
53
+ - name: Publish to github
54
+ uses: softprops/action-gh-release@v2
55
+ with:
56
+ tag_name: ${{ github.event.inputs.version }}
57
+ name: Release ${{ github.event.inputs.version }}
58
+ body: ${{ github.event.inputs.description }}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.delayCommand = void 0;
4
+ const utils_1 = require("../utils");
5
+ const setDelayRounds = (rounds, delay, onlyDelay, noDelay) => rounds.forEach((round) => {
6
+ utils_1.client
7
+ .POST("/broadcast/round/{broadcastRoundId}/edit", {
8
+ params: {
9
+ path: { broadcastRoundId: round.id },
10
+ // @ts-ignore patch param is not yet documented
11
+ query: { patch: 1 },
12
+ },
13
+ // @ts-ignore name of body properties due patch param is implicit
14
+ body: {
15
+ delay: noDelay ? undefined : delay,
16
+ startsAt: round.startsAt && !onlyDelay
17
+ ? round.startsAt + delay * 1000
18
+ : undefined,
19
+ },
20
+ })
21
+ .then((response) => {
22
+ if (response.response.ok)
23
+ console.log(`Successfully set delay for round ${round.id} to ${delay} seconds.`);
24
+ else
25
+ console.error(`Failed to set delay for round ${round.id}: ${response.response.statusText}`);
26
+ })
27
+ .catch((error) => {
28
+ console.error(`Error setting delay for round ${round.id}:`, error);
29
+ });
30
+ });
31
+ const delayCommand = async (args) => {
32
+ const [broadcastId, delay] = args.slice(0, 2);
33
+ // check arg --help or -h
34
+ if (args.includes("--help") || args.includes("-h")) {
35
+ (0, utils_1.showHelp)(utils_1.Command.Delay);
36
+ process.exit(0);
37
+ }
38
+ // Validate required args
39
+ if (!broadcastId || !delay) {
40
+ (0, utils_1.showHelp)(utils_1.Command.Delay);
41
+ process.exit(1);
42
+ }
43
+ const delayNum = parseInt(delay, 10);
44
+ // Validate delay is a number between 0s and 1h
45
+ if (isNaN(delayNum) && delayNum >= 0 && delayNum <= 3600) {
46
+ console.error("Delay must be a number between 0 and 3600 seconds.");
47
+ process.exit(1);
48
+ }
49
+ // check arg --onlyDelay
50
+ const onlyDelay = args.includes("--onlyDelay");
51
+ // check arg --noDelay
52
+ const noDelay = args.includes("--noDelay");
53
+ if (onlyDelay && noDelay) {
54
+ console.error("Cannot use --onlyDelay and --noDelay together.");
55
+ process.exit(1);
56
+ }
57
+ const broadcast = await (0, utils_1.getBroadcast)(broadcastId);
58
+ if (!broadcast?.rounds || broadcast.rounds.length === 0) {
59
+ console.error("No rounds found for the specified broadcast.");
60
+ process.exit(1);
61
+ }
62
+ setDelayRounds(broadcast.rounds, parseInt(delay, 10), onlyDelay, noDelay);
63
+ };
64
+ exports.delayCommand = delayCommand;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setLCCCommand = void 0;
4
+ const utils_1 = require("../utils");
5
+ const setSourceLCC = (rounds, sourceLCC) => {
6
+ let rN = 1;
7
+ rounds.forEach((round) => {
8
+ utils_1.client
9
+ .POST("/broadcast/round/{broadcastRoundId}/edit", {
10
+ params: {
11
+ path: { broadcastRoundId: round.id },
12
+ // @ts-ignore patch param is not yet documented
13
+ query: { patch: 1 },
14
+ },
15
+ // @ts-ignore name of body properties due patch param is implicit
16
+ body: {
17
+ // @ts-ignore property is not yet documented
18
+ syncSource: "url",
19
+ syncUrl: `${sourceLCC}/${rN}`,
20
+ },
21
+ })
22
+ .then((response) => {
23
+ if (response.response.ok)
24
+ console.log(`Successfully set source LCC for round ${round.id} to ${sourceLCC}/${rN}.`);
25
+ else
26
+ console.error(`Failed to set source LCC for round ${round.id}: ${response.response.statusText}`);
27
+ })
28
+ .catch((error) => {
29
+ console.error(`Error setting source LCC for round ${round.id}:`, error);
30
+ });
31
+ rN += 1;
32
+ });
33
+ };
34
+ const setLCCCommand = async (args) => {
35
+ const [bId, sourceLCC] = args.slice(0, 2);
36
+ // check arg --help or -h
37
+ if (args.includes("--help") || args.includes("-h")) {
38
+ (0, utils_1.showHelp)(utils_1.Command.SetLCC);
39
+ process.exit(0);
40
+ }
41
+ // Validate required args
42
+ if (!bId || !sourceLCC) {
43
+ (0, utils_1.showHelp)(utils_1.Command.SetLCC);
44
+ process.exit(1);
45
+ }
46
+ const bcast = await (0, utils_1.getBroadcast)(bId);
47
+ if (!bcast?.rounds || bcast.rounds.length === 0) {
48
+ console.error("No rounds found for the specified broadcast.");
49
+ process.exit(1);
50
+ }
51
+ // check sourceLCC is a valid URL
52
+ let url;
53
+ try {
54
+ url = new URL(sourceLCC.startsWith("http")
55
+ ? sourceLCC
56
+ : `https://view.livechesscloud.com/${sourceLCC}`);
57
+ }
58
+ catch (e) {
59
+ console.error("sourceLCC must be a valid URL or LCC ID.");
60
+ process.exit(1);
61
+ }
62
+ setSourceLCC(bcast.rounds, url.toString());
63
+ };
64
+ exports.setLCCCommand = setLCCCommand;
package/dist/index.js CHANGED
@@ -1,183 +1,29 @@
1
1
  #!/usr/bin/env node
2
- import { argv, env } from "process";
3
- import createClient from "openapi-fetch";
4
- const LICHESS_TOKEN = env.LICHESS_TOKEN;
5
- const LICHESS_DOMAIN = env.LICHESS_DOMAIN || "https://lichess.org/";
6
- if (!LICHESS_TOKEN) {
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const process_1 = require("process");
5
+ const utils_1 = require("./utils");
6
+ const delay_1 = require("./cmd/delay");
7
+ const setLCC_1 = require("./cmd/setLCC");
8
+ // Ensure LICHESS_TOKEN is set
9
+ if (!utils_1.LICHESS_TOKEN) {
7
10
  console.error("Error: LICHESS_TOKEN environment variable is not set.");
8
11
  process.exit(1);
9
12
  }
10
- const args = argv.slice(2);
11
- const client = createClient({
12
- baseUrl: LICHESS_DOMAIN,
13
- headers: {
14
- Authorization: `Bearer ${LICHESS_TOKEN}`,
15
- Accept: "application/json",
16
- },
17
- });
18
- const getBroadcast = (broadcastId) => client
19
- .GET("/api/broadcast/{broadcastTournamentId}", {
20
- params: {
21
- path: { broadcastTournamentId: broadcastId },
22
- },
23
- })
24
- .then((response) => response.data)
25
- .catch((error) => {
26
- console.error("Error fetching broadcast:", error);
27
- return null;
28
- });
29
- const setDelayRounds = (rounds, delay, onlyDelay, noDelay) => rounds.forEach((round) => {
30
- client
31
- .POST("/broadcast/round/{broadcastRoundId}/edit", {
32
- params: {
33
- path: { broadcastRoundId: round.id },
34
- // @ts-ignore patch param is not yet documented
35
- query: { patch: 1 },
36
- },
37
- // @ts-ignore name of body properties due patch param is implicit
38
- body: {
39
- delay: noDelay ? undefined : delay,
40
- startsAt: round.startsAt && !onlyDelay
41
- ? round.startsAt + delay * 1000
42
- : undefined,
43
- },
44
- })
45
- .then((response) => {
46
- if (response.response.ok)
47
- console.log(`Successfully set delay for round ${round.id} to ${delay} seconds.`);
48
- else
49
- console.error(`Failed to set delay for round ${round.id}: ${response.response.statusText}`);
50
- })
51
- .catch((error) => {
52
- console.error(`Error setting delay for round ${round.id}:`, error);
53
- });
54
- });
55
- const setSourceLCC = (rounds, sourceLCC) => {
56
- let rN = 1;
57
- rounds.forEach((round) => {
58
- client
59
- .POST("/broadcast/round/{broadcastRoundId}/edit", {
60
- params: {
61
- path: { broadcastRoundId: round.id },
62
- // @ts-ignore patch param is not yet documented
63
- query: { patch: 1 },
64
- },
65
- // @ts-ignore name of body properties due patch param is implicit
66
- body: {
67
- // @ts-ignore property is not yet documented
68
- syncSource: "url",
69
- syncUrl: `${sourceLCC}/${rN}`,
70
- },
71
- })
72
- .then((response) => {
73
- if (response.response.ok)
74
- console.log(`Successfully set source LCC for round ${round.id} to ${sourceLCC}/${rN}.`);
75
- else
76
- console.error(`Failed to set source LCC for round ${round.id}: ${response.response.statusText}`);
77
- })
78
- .catch((error) => {
79
- console.error(`Error setting source LCC for round ${round.id}:`, error);
80
- });
81
- rN += 1;
82
- });
83
- };
84
- var Command;
85
- (function (Command) {
86
- Command["Delay"] = "delay";
87
- Command["SetLCC"] = "setLCC";
88
- })(Command || (Command = {}));
89
- const showHelp = (cmd) => {
90
- const msg = [
91
- "Usage: <command> [options]",
92
- "Commands:",
93
- " delay <broadcastId> <delayInSeconds> [--onlyDelay] [--noDelay]",
94
- " Sets the delay for all rounds in the specified broadcast.",
95
- " Options:",
96
- " --onlyDelay Set only the delay without changing the start time.",
97
- " --noDelay Remove the delay from the rounds.",
98
- " setLCC <broadcastId> <sourceLCCUrl>",
99
- " Sets the source LCC URL for all rounds in the specified broadcast.",
100
- ];
101
- switch (cmd) {
102
- case Command.Delay:
103
- console.info(msg.slice(2, 7).join("\n"));
104
- break;
105
- case Command.SetLCC:
106
- console.info(msg.slice(7, 9).join("\n"));
107
- break;
108
- default:
109
- console.info(msg.join("\n"));
110
- }
111
- };
13
+ const args = process_1.argv.slice(2);
112
14
  (async () => {
113
15
  // check args[0] is --help or -h
114
16
  if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
115
- showHelp();
17
+ (0, utils_1.showHelp)();
116
18
  process.exit(0);
117
19
  }
118
- switch (args[0]) {
119
- case Command.Delay:
120
- const [broadcastId, delay] = args.slice(1, 3);
121
- // check arg --help or -h
122
- if (args.includes("--help") || args.includes("-h")) {
123
- showHelp(Command.Delay);
124
- process.exit(0);
125
- }
126
- // Validate required args
127
- if (!broadcastId || !delay) {
128
- showHelp(Command.Delay);
129
- process.exit(1);
130
- }
131
- const delayNum = parseInt(delay, 10);
132
- // Validate delay is a number between 0s and 1h
133
- if (isNaN(delayNum) && delayNum >= 0 && delayNum <= 3600) {
134
- console.error("Delay must be a number between 0 and 3600 seconds.");
135
- process.exit(1);
136
- }
137
- // check arg --onlyDelay
138
- const onlyDelay = args.includes("--onlyDelay");
139
- // check arg --noDelay
140
- const noDelay = args.includes("--noDelay");
141
- if (onlyDelay && noDelay) {
142
- console.error("Cannot use --onlyDelay and --noDelay together.");
143
- process.exit(1);
144
- }
145
- const broadcast = await getBroadcast(broadcastId);
146
- if (!broadcast?.rounds || broadcast.rounds.length === 0) {
147
- console.error("No rounds found for the specified broadcast.");
148
- process.exit(1);
149
- }
150
- setDelayRounds(broadcast.rounds, parseInt(delay, 10), onlyDelay, noDelay);
20
+ const command = args.shift();
21
+ switch (command) {
22
+ case utils_1.Command.Delay:
23
+ await (0, delay_1.delayCommand)(args);
151
24
  break;
152
- case Command.SetLCC:
153
- const [bId, sourceLCC] = args.slice(1, 3);
154
- // check arg --help or -h
155
- if (args.includes("--help") || args.includes("-h")) {
156
- showHelp(Command.SetLCC);
157
- process.exit(0);
158
- }
159
- // Validate required args
160
- if (!bId || !sourceLCC) {
161
- showHelp(Command.SetLCC);
162
- process.exit(1);
163
- }
164
- const bcast = await getBroadcast(bId);
165
- if (!bcast?.rounds || bcast.rounds.length === 0) {
166
- console.error("No rounds found for the specified broadcast.");
167
- process.exit(1);
168
- }
169
- // check sourceLCC is a valid URL
170
- let url;
171
- try {
172
- url = new URL(sourceLCC.startsWith("http")
173
- ? sourceLCC
174
- : `https://view.livechesscloud.com/${sourceLCC}`);
175
- }
176
- catch (e) {
177
- console.error("sourceLCC must be a valid URL or LCC ID.");
178
- process.exit(1);
179
- }
180
- setSourceLCC(bcast.rounds, url.toString());
25
+ case utils_1.Command.SetLCC:
26
+ await (0, setLCC_1.setLCCCommand)(args);
181
27
  break;
182
28
  default:
183
29
  console.error("Unknown command. Supported commands: delay, setLCC");
package/dist/utils.js ADDED
@@ -0,0 +1,60 @@
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.getBroadcast = exports.showHelp = exports.Command = exports.client = exports.LICHESS_TOKEN = void 0;
7
+ const process_1 = require("process");
8
+ const openapi_fetch_1 = __importDefault(require("openapi-fetch"));
9
+ exports.LICHESS_TOKEN = process_1.env.LICHESS_TOKEN;
10
+ const LICHESS_DOMAIN = process_1.env.LICHESS_DOMAIN || "https://lichess.org/";
11
+ exports.client = (0, openapi_fetch_1.default)({
12
+ baseUrl: LICHESS_DOMAIN,
13
+ headers: {
14
+ Authorization: `Bearer ${exports.LICHESS_TOKEN}`,
15
+ Accept: "application/json",
16
+ },
17
+ });
18
+ // Commands names
19
+ var Command;
20
+ (function (Command) {
21
+ Command["Delay"] = "delay";
22
+ Command["SetLCC"] = "setLCC";
23
+ })(Command || (exports.Command = Command = {}));
24
+ // Function to show help messages
25
+ const showHelp = (cmd) => {
26
+ const msg = [
27
+ "Usage: <command> [options]",
28
+ "Commands:",
29
+ " delay <broadcastId> <delayInSeconds> [--onlyDelay] [--noDelay]",
30
+ " Sets the delay for all rounds in the specified broadcast.",
31
+ " Options:",
32
+ " --onlyDelay Set only the delay without changing the start time.",
33
+ " --noDelay Remove the delay from the rounds.",
34
+ " setLCC <broadcastId> <sourceLCCUrl>",
35
+ " Sets the source LCC URL for all rounds in the specified broadcast.",
36
+ ];
37
+ switch (cmd) {
38
+ case Command.Delay:
39
+ console.info(msg.slice(2, 7).join("\n"));
40
+ break;
41
+ case Command.SetLCC:
42
+ console.info(msg.slice(7, 9).join("\n"));
43
+ break;
44
+ default:
45
+ console.info(msg.join("\n"));
46
+ }
47
+ };
48
+ exports.showHelp = showHelp;
49
+ const getBroadcast = (broadcastId) => exports.client
50
+ .GET("/api/broadcast/{broadcastTournamentId}", {
51
+ params: {
52
+ path: { broadcastTournamentId: broadcastId },
53
+ },
54
+ })
55
+ .then((response) => response.data)
56
+ .catch((error) => {
57
+ console.error("Error fetching broadcast:", error);
58
+ return null;
59
+ });
60
+ exports.getBroadcast = getBroadcast;
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "libroadcast-cli",
3
- "version": "1.0.1",
4
- "description": "",
5
- "main": "dist/index.ts",
6
- "keywords": [],
7
- "author": "",
3
+ "version": "1.1.1",
4
+ "description": "CLI to help with broadcast maintenance on Lichess",
5
+ "main": "dist/index.js",
6
+ "keywords": [
7
+ "lichess",
8
+ "broadcast",
9
+ "cli"
10
+ ],
11
+ "author": "Sérgio Glórias",
8
12
  "license": "MIT",
9
- "packageManager": "pnpm@10.20.0+sha512.cf9998222162dd85864d0a8102e7892e7ba4ceadebbf5a31f9c2fce48dfce317a9c53b9f6464d1ef9042cba2e02ae02a9f7c143a2b438cd93c91840f0192b9dd",
10
- "type": "module",
13
+ "type": "commonjs",
11
14
  "dependencies": {
12
15
  "@lichess-org/types": "^2.0.94",
13
16
  "@types/node": "^24.10.0",
@@ -19,8 +22,16 @@
19
22
  "bin": {
20
23
  "libroadcast": "./dist/index.js"
21
24
  },
25
+ "repository": {
26
+ "url": "https://github.com/SergioGlorias/broadcastCLI.git",
27
+ "type": "git"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/SergioGlorias/broadcastCLI/issues"
31
+ },
32
+ "homepage": "https://github.com/SergioGlorias/broadcastCLI",
22
33
  "scripts": {
23
34
  "build": "tsc",
24
35
  "start": "pnpm build && node ./dist/index.js"
25
36
  }
26
- }
37
+ }