anichi 1.0.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.
package/README.md ADDED
File without changes
package/bin/anich ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require('../dist/index.js');
package/dist/api.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ declare class ApiClient {
2
+ private client;
3
+ private cache;
4
+ constructor();
5
+ private request;
6
+ getHome(): Promise<unknown>;
7
+ getAnime(slug: string): Promise<unknown>;
8
+ getGenre(): Promise<unknown>;
9
+ getEpisode(slug: string): Promise<unknown>;
10
+ getServer(id: string): Promise<unknown>;
11
+ clearCache(): void;
12
+ }
13
+ declare const _default: ApiClient;
14
+ export default _default;
15
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AASA,cAAM,SAAS;IACb,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAY;;YAUX,OAAO;IAoCf,OAAO;IAGP,QAAQ,CAAC,IAAI,EAAE,MAAM;IAGrB,QAAQ;IAGR,UAAU,CAAC,IAAI,EAAE,MAAM;IAGvB,SAAS,CAAC,EAAE,EAAE,MAAM;IAI1B,UAAU;CAIX;;AAED,wBAA+B"}
package/dist/api.js ADDED
@@ -0,0 +1,75 @@
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
+ const axios_1 = __importDefault(require("axios"));
7
+ const node_cache_1 = __importDefault(require("node-cache"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const ui_1 = require("./ui");
10
+ const BASE_URL = "https://www.sankavollerei.com/anime";
11
+ const CACHE_TTL = 3600;
12
+ const MAX_RETRIES = 3;
13
+ class ApiClient {
14
+ constructor() {
15
+ this.client = axios_1.default.create({
16
+ baseURL: BASE_URL,
17
+ timeout: 10000,
18
+ });
19
+ this.cache = new node_cache_1.default({ stdTTL: CACHE_TTL, checkperiod: 600 });
20
+ }
21
+ async request(url) {
22
+ const cached = this.cache.get(url);
23
+ if (cached)
24
+ return cached;
25
+ const spinner = (0, ora_1.default)({
26
+ text: `Fetching ${url}...`,
27
+ color: "cyan",
28
+ }).start();
29
+ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
30
+ try {
31
+ const { data, status } = await this.client.get(url);
32
+ if (data.statusCode === 404) {
33
+ spinner.warn("Not found");
34
+ return data;
35
+ }
36
+ if (status !== 200)
37
+ throw new Error(`HTTP ${status}`);
38
+ this.cache.set(url, data);
39
+ spinner.succeed();
40
+ return data;
41
+ }
42
+ catch (err) {
43
+ if (attempt === MAX_RETRIES - 1) {
44
+ spinner.fail();
45
+ throw err;
46
+ }
47
+ const delay = Math.pow(2, attempt + 1) * 1000;
48
+ spinner.text = `Retry ${attempt + 1}/${MAX_RETRIES}...`;
49
+ await new Promise((r) => setTimeout(r, delay));
50
+ }
51
+ }
52
+ throw new Error("Request failed");
53
+ }
54
+ async getHome() {
55
+ return this.request("/home");
56
+ }
57
+ async getAnime(slug) {
58
+ return this.request(`/anime/${slug}`);
59
+ }
60
+ async getGenre() {
61
+ return this.request("/genre");
62
+ }
63
+ async getEpisode(slug) {
64
+ return this.request(`/episode/${slug}`);
65
+ }
66
+ async getServer(id) {
67
+ return this.request(`/server/${id}`);
68
+ }
69
+ clearCache() {
70
+ this.cache.flushAll();
71
+ ui_1.logger.success("Cache cleared");
72
+ }
73
+ }
74
+ exports.default = new ApiClient();
75
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { AppConfig } from "./types";
2
+ export declare const ensureConfigDir: () => void;
3
+ export declare const loadConfig: () => AppConfig;
4
+ export declare const saveConfig: (config: AppConfig) => void;
5
+ export declare const getConfigPath: () => string;
6
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,SAAS,EAAC,MAAM,SAAS,CAAC;AAIlC,eAAO,MAAM,eAAe,QAAO,IAIlC,CAAC;AAEF,eAAO,MAAM,UAAU,QAAO,SAW7B,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,QAAQ,SAAS,KAAG,IAG9C,CAAC;AAEF,eAAO,MAAM,aAAa,QAAO,MAAqB,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,39 @@
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.getConfigPath = exports.saveConfig = exports.loadConfig = exports.ensureConfigDir = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const os_1 = __importDefault(require("os"));
10
+ const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), ".config", "anich");
11
+ const CONFIG_FILE = path_1.default.join(CONFIG_DIR, "config.json");
12
+ const ensureConfigDir = () => {
13
+ if (!fs_1.default.existsSync(CONFIG_DIR)) {
14
+ fs_1.default.mkdirSync(CONFIG_DIR, { recursive: true });
15
+ }
16
+ };
17
+ exports.ensureConfigDir = ensureConfigDir;
18
+ const loadConfig = () => {
19
+ (0, exports.ensureConfigDir)();
20
+ if (!fs_1.default.existsSync(CONFIG_FILE)) {
21
+ return {};
22
+ }
23
+ try {
24
+ const content = fs_1.default.readFileSync(CONFIG_FILE, "utf-8");
25
+ return JSON.parse(content);
26
+ }
27
+ catch (err) {
28
+ return {};
29
+ }
30
+ };
31
+ exports.loadConfig = loadConfig;
32
+ const saveConfig = (config) => {
33
+ (0, exports.ensureConfigDir)();
34
+ fs_1.default.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
35
+ };
36
+ exports.saveConfig = saveConfig;
37
+ const getConfigPath = () => CONFIG_FILE;
38
+ exports.getConfigPath = getConfigPath;
39
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AAEpB,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC/D,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAElD,MAAM,eAAe,GAAG,GAAS,EAAE;IACxC,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,YAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC,CAAC;AAJW,QAAA,eAAe,mBAI1B;AAEK,MAAM,UAAU,GAAG,GAAc,EAAE;IACxC,IAAA,uBAAe,GAAE,CAAC;IAClB,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AAXW,QAAA,UAAU,cAWrB;AAEK,MAAM,UAAU,GAAG,CAAC,MAAiB,EAAQ,EAAE;IACpD,IAAA,uBAAe,GAAE,CAAC;IAClB,YAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,CAAC;AAHW,QAAA,UAAU,cAGrB;AAEK,MAAM,aAAa,GAAG,GAAW,EAAE,CAAC,WAAW,CAAC;AAA1C,QAAA,aAAa,iBAA6B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,364 @@
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
+ const update_notifier_1 = __importDefault(require("update-notifier"));
7
+ const package_json_1 = __importDefault(require("../package.json"));
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const ora_1 = __importDefault(require("ora"));
10
+ const commander_1 = require("commander");
11
+ const readline_1 = __importDefault(require("readline"));
12
+ const open_1 = __importDefault(require("open"));
13
+ const api_1 = __importDefault(require("./api"));
14
+ const player_1 = require("./player");
15
+ const config_1 = require("./config");
16
+ const ui_1 = require("./ui");
17
+ (0, update_notifier_1.default)({
18
+ pkg: package_json_1.default,
19
+ updateCheckInterval: 1000 * 60 * 60 * 12,
20
+ }).notify();
21
+ const program = new commander_1.Command();
22
+ program.name("anich").description("Modern CLI tool for anime streaming").version("1.0.0");
23
+ const ask = (query) => {
24
+ const rl = readline_1.default.createInterface({
25
+ input: process.stdin,
26
+ output: process.stdout,
27
+ });
28
+ return new Promise((resolve) => rl.question(chalk_1.default.hex("#00d9ff")(` ${query} `), (ans) => {
29
+ rl.close();
30
+ resolve(ans.trim());
31
+ }));
32
+ };
33
+ // Cari episode berdasarkan nomor atau 'latest'
34
+ const resolveEpisode = (eps, list) => {
35
+ if (eps === "latest")
36
+ return list[0];
37
+ return list.find((e) => e.eps === eps);
38
+ };
39
+ // Coba ambil URL dari server dengan timeout pendek untuk menghindari macet
40
+ const tryGetServer = async (serverId) => {
41
+ try {
42
+ const controller = new AbortController();
43
+ const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout
44
+ const res = await fetch(`https://www.sankavollerei.com/anime/server/${serverId}`, {
45
+ signal: controller.signal,
46
+ }).then((r) => r.json());
47
+ clearTimeout(timeoutId);
48
+ if (res.status === "success" && res.data?.url) {
49
+ return res.data.url;
50
+ }
51
+ return null;
52
+ }
53
+ catch {
54
+ return null;
55
+ }
56
+ };
57
+ // Pilih Kualitas
58
+ const selectQuality = async (qualities) => {
59
+ (0, ui_1.clearScreen)();
60
+ (0, ui_1.createHeader)("Select Quality", "#ff6b9d");
61
+ (0, ui_1.printQualityOptions)(qualities);
62
+ ui_1.logger.br();
63
+ ui_1.logger.muted(" Select quality (1-" + qualities.length + ") or 'back'\n");
64
+ const answer = await ask("Quality:");
65
+ const choice = answer.toLowerCase();
66
+ if (choice === "back" || choice === "0")
67
+ return null;
68
+ const index = parseInt(choice) - 1;
69
+ if (!isNaN(index) && index >= 0 && index < qualities.length) {
70
+ return qualities[index];
71
+ }
72
+ ui_1.logger.warn("Invalid selection");
73
+ await new Promise((r) => setTimeout(r, 1000));
74
+ return await selectQuality(qualities);
75
+ };
76
+ // Handle Download
77
+ const handleDownload = async (episodeData) => {
78
+ const downloads = episodeData.downloadUrl?.qualities || [];
79
+ if (downloads.length === 0) {
80
+ ui_1.logger.error("No download links available");
81
+ return;
82
+ }
83
+ (0, ui_1.clearScreen)();
84
+ (0, ui_1.createHeader)("Download Episode", "#00ff9f");
85
+ (0, ui_1.printDownloadOptions)(downloads);
86
+ ui_1.logger.br();
87
+ ui_1.logger.muted(" Select quality (1-" + downloads.length + ") or 'back'\n");
88
+ const answer = await ask("Quality:");
89
+ const choice = answer.toLowerCase();
90
+ if (choice === "back" || choice === "0")
91
+ return;
92
+ const qIndex = parseInt(choice) - 1;
93
+ if (isNaN(qIndex) || qIndex < 0 || qIndex >= downloads.length) {
94
+ ui_1.logger.warn("Invalid selection");
95
+ await new Promise((r) => setTimeout(r, 1000));
96
+ return await handleDownload(episodeData);
97
+ }
98
+ const selected = downloads[qIndex];
99
+ (0, ui_1.clearScreen)();
100
+ (0, ui_1.createHeader)(`Download ${selected.title} (${selected.size})`, "#00ff9f");
101
+ selected.urls.forEach((provider, idx) => {
102
+ const num = chalk_1.default.hex("#00ff9f").bold(` [${idx + 1}]`);
103
+ console.log(`${num} ${chalk_1.default.white(provider.title)}`);
104
+ });
105
+ ui_1.logger.br();
106
+ ui_1.logger.muted(" Select provider (1-" + selected.urls.length + ") or 'back'\n");
107
+ const provAnswer = await ask("Provider:");
108
+ const provChoice = provAnswer.toLowerCase();
109
+ if (provChoice === "back" || provChoice === "0")
110
+ return await handleDownload(episodeData);
111
+ const pIndex = parseInt(provChoice) - 1;
112
+ if (isNaN(pIndex) || pIndex < 0 || pIndex >= selected.urls.length) {
113
+ ui_1.logger.warn("Invalid selection");
114
+ await new Promise((r) => setTimeout(r, 1000));
115
+ return await handleDownload(episodeData);
116
+ }
117
+ const provider = selected.urls[pIndex];
118
+ ui_1.logger.info(`Opening ${provider.title}...`);
119
+ await (0, open_1.default)(provider.url);
120
+ await new Promise((r) => setTimeout(r, 2000));
121
+ };
122
+ // PERBAIKAN UTAMA: handlePlay sekarang menerima animeData untuk menghindari fetch ulang
123
+ const handlePlay = async (slug, episodeStr, animeData) => {
124
+ const config = (0, config_1.loadConfig)();
125
+ try {
126
+ // Jika animeData tidak dikirim, fetch baru (hanya saat perlu)
127
+ let data = animeData;
128
+ if (!data) {
129
+ const spinner = (0, ora_1.default)("Fetching details...").start();
130
+ const res = await api_1.default.getAnime(slug);
131
+ data = res.data;
132
+ spinner.stop();
133
+ }
134
+ const epsNum = episodeStr === "latest" ? "latest" : parseInt(episodeStr);
135
+ const episode = resolveEpisode(epsNum, data.episodeList);
136
+ if (!episode) {
137
+ ui_1.logger.error(`Episode ${episodeStr} not found`);
138
+ return false;
139
+ }
140
+ // Ambil detail episode untuk mendapatkan daftar server
141
+ const epRes = await api_1.default.getEpisode(episode.episodeId);
142
+ if (!epRes.ok || !epRes.data) {
143
+ ui_1.logger.error("Failed to fetch episode data");
144
+ return false;
145
+ }
146
+ const qualities = epRes.data.server?.qualities || [];
147
+ if (qualities.length === 0) {
148
+ ui_1.logger.warn("No streaming qualities available");
149
+ const url = epRes.data.defaultStreamingUrl || episode.otakudesuUrl;
150
+ if (url) {
151
+ ui_1.logger.info("Opening default stream...");
152
+ await (0, open_1.default)(url);
153
+ return true;
154
+ }
155
+ return false;
156
+ }
157
+ const selectedQuality = await selectQuality(qualities);
158
+ if (!selectedQuality)
159
+ return false;
160
+ (0, ui_1.clearScreen)();
161
+ ui_1.logger.info(`Playing: ${episode.title}`);
162
+ ui_1.logger.info(`Quality: ${selectedQuality.title}`);
163
+ let url = null;
164
+ // Coba server satu per satu
165
+ for (const server of selectedQuality.serverList) {
166
+ ui_1.logger.info(`Trying ${server.title}...`);
167
+ url = await tryGetServer(server.serverId);
168
+ if (url) {
169
+ // Skip server embed yang tidak support player (filedon/vidhide biasanya butuh browser)
170
+ if (url.includes("filedon.co") || url.includes("vidhide")) {
171
+ ui_1.logger.warn(`${server.title} unsupported (Embed detected), skipping...`);
172
+ continue;
173
+ }
174
+ break;
175
+ }
176
+ }
177
+ if (!url) {
178
+ ui_1.logger.warn("No working server found, using default...");
179
+ url = epRes.data.defaultStreamingUrl;
180
+ }
181
+ if (!url) {
182
+ ui_1.logger.error("No stream URL available");
183
+ return false;
184
+ }
185
+ // Jika URL adalah link embed, buka browser
186
+ if (url.includes("/embed/") || url.includes("player")) {
187
+ ui_1.logger.info("Opening browser player...");
188
+ await (0, open_1.default)(url);
189
+ await new Promise((r) => setTimeout(r, 1000));
190
+ return true;
191
+ }
192
+ // Play with MPV/VLC
193
+ const playerPath = config.player || config.playerPath;
194
+ const args = config.playerArgs ? config.playerArgs.split(" ") : [];
195
+ const success = await (0, player_1.playUrl)(url, playerPath, args, false);
196
+ if (!success) {
197
+ ui_1.logger.warn("Opening in browser...");
198
+ await (0, open_1.default)(url);
199
+ }
200
+ return success;
201
+ }
202
+ catch (err) {
203
+ ui_1.logger.error(`Playback failed: ${err.message}`);
204
+ return false;
205
+ }
206
+ };
207
+ // Menu Episode
208
+ const showEpisodeMenu = async (slug, data) => {
209
+ (0, ui_1.clearScreen)();
210
+ (0, ui_1.showAnimeDetails)(data); // Tampilkan detail setiap masuk menu
211
+ (0, ui_1.createHeader)("Episodes", "#ff6b9d");
212
+ (0, ui_1.printEpisodeList)(data.episodeList);
213
+ ui_1.logger.br();
214
+ ui_1.logger.muted(" Commands:");
215
+ ui_1.logger.muted(" • [number] or 'latest' - Watch episode");
216
+ ui_1.logger.muted(" • 'd' or 'download' - Download episode");
217
+ ui_1.logger.muted(" • 'back' - Return to anime list\n");
218
+ const answer = await ask("Command:");
219
+ const choice = answer.toLowerCase();
220
+ if (choice === "back" || choice === "0")
221
+ return;
222
+ if (choice === "d" || choice === "download") {
223
+ (0, ui_1.clearScreen)();
224
+ (0, ui_1.createHeader)("Select Episode to Download", "#00ff9f");
225
+ (0, ui_1.printEpisodeList)(data.episodeList);
226
+ ui_1.logger.br();
227
+ ui_1.logger.muted(" Type episode number or 'back'\n");
228
+ const epAnswer = await ask("Episode:");
229
+ const epChoice = epAnswer.toLowerCase();
230
+ if (epChoice !== "back" && epChoice !== "0") {
231
+ const epNum = parseInt(epChoice);
232
+ if (!isNaN(epNum) || epChoice === "latest") {
233
+ const episode = resolveEpisode(epChoice === "latest" ? "latest" : epNum, data.episodeList);
234
+ if (episode) {
235
+ const epRes = await api_1.default.getEpisode(episode.episodeId);
236
+ if (epRes.ok && epRes.data) {
237
+ await handleDownload(epRes.data);
238
+ }
239
+ }
240
+ }
241
+ }
242
+ return await showEpisodeMenu(slug, data); // Kembali ke menu episode
243
+ }
244
+ const epNum = parseInt(choice);
245
+ if (!isNaN(epNum) || choice === "latest") {
246
+ // KITA LEWATKAN clearScreen DI SINI agar info anime tidak hilang saat berpindah
247
+ // Hapus detail duplikat atau berlebihan dengan membiarkan handlePlay yang menghandle clear screen internalnya jika perlu
248
+ await handlePlay(slug, isNaN(epNum) ? "latest" : String(epNum), data);
249
+ // Beri waktu user membaca log setelah selesai/gagal
250
+ await new Promise((r) => setTimeout(r, 2000));
251
+ // Refresh menu tanpa flicker berlebihan
252
+ return await showEpisodeMenu(slug, data);
253
+ }
254
+ ui_1.logger.warn("Invalid input");
255
+ await new Promise((r) => setTimeout(r, 1000));
256
+ return await showEpisodeMenu(slug, data);
257
+ };
258
+ // Menu Detail Anime (Hanya entry point)
259
+ const showAnimeDetail = async (slug) => {
260
+ try {
261
+ const res = await api_1.default.getAnime(slug);
262
+ await showEpisodeMenu(slug, res.data);
263
+ }
264
+ catch {
265
+ ui_1.logger.error("Failed to load anime");
266
+ }
267
+ };
268
+ // Menu List Anime
269
+ const showAnimeList = async (list, title) => {
270
+ (0, ui_1.clearScreen)();
271
+ (0, ui_1.createHeader)(title, "#00d9ff");
272
+ (0, ui_1.printAnimeList)(list);
273
+ ui_1.logger.br();
274
+ ui_1.logger.muted(` Select anime (1-${list.length}) or 'home' to return\n`);
275
+ const answer = await ask("Select:");
276
+ const choice = answer.toLowerCase();
277
+ if (choice === "home" || choice === "0")
278
+ return "home";
279
+ const index = parseInt(choice) - 1;
280
+ if (!isNaN(index) && index >= 0 && index < list.length) {
281
+ await showAnimeDetail(list[index].animeId);
282
+ return await showAnimeList(list, title);
283
+ }
284
+ ui_1.logger.warn("Invalid selection");
285
+ await new Promise((r) => setTimeout(r, 1000));
286
+ return await showAnimeList(list, title);
287
+ };
288
+ // Home Runner
289
+ const runHome = async () => {
290
+ (0, ui_1.clearScreen)();
291
+ (0, ui_1.showBanner)();
292
+ (0, ui_1.createHeader)("Main Menu", "#ff6b9d");
293
+ (0, ui_1.showMenu)(["Ongoing Anime", "Completed Anime"]);
294
+ const answer = await ask("Choose:");
295
+ const res = await api_1.default.getHome();
296
+ if (answer === "1") {
297
+ const list = res.data?.ongoing?.animeList || [];
298
+ if (list.length === 0) {
299
+ ui_1.logger.warn("No ongoing anime");
300
+ return;
301
+ }
302
+ const action = await showAnimeList(list, "Ongoing Anime");
303
+ if (action === "home")
304
+ await runHome();
305
+ }
306
+ else if (answer === "2") {
307
+ const list = res.data?.completed?.animeList || [];
308
+ if (list.length === 0) {
309
+ ui_1.logger.warn("No completed anime");
310
+ return;
311
+ }
312
+ const action = await showAnimeList(list, "Completed Anime");
313
+ if (action === "home")
314
+ await runHome();
315
+ }
316
+ else {
317
+ ui_1.logger.warn("Invalid choice");
318
+ await new Promise((r) => setTimeout(r, 1000));
319
+ await runHome();
320
+ }
321
+ };
322
+ // Commands
323
+ program.command("home").description("Launch interactive menu").action(runHome);
324
+ program
325
+ .command("play <slug> <episode>")
326
+ .description("Play episode directly")
327
+ .option("-p, --player <path>", "Player path")
328
+ .option("-a, --args <args>", "Player arguments")
329
+ .action(async (slug, ep) => {
330
+ (0, ui_1.clearScreen)();
331
+ (0, ui_1.showBanner)();
332
+ await handlePlay(slug, ep);
333
+ });
334
+ program
335
+ .command("config [action] [key] [value]")
336
+ .description("Manage configuration")
337
+ .action((action = "show", key, value) => {
338
+ const config = (0, config_1.loadConfig)();
339
+ if (action === "set" && key && value) {
340
+ if (key === "player" || key === "playerArgs") {
341
+ config[key] = value;
342
+ (0, config_1.saveConfig)(config);
343
+ ui_1.logger.success(`${key} = ${value}`);
344
+ }
345
+ else {
346
+ ui_1.logger.error("Invalid key");
347
+ }
348
+ }
349
+ else {
350
+ console.log(JSON.stringify(config, null, 2));
351
+ ui_1.logger.info(`Config: ${(0, config_1.getConfigPath)()}`);
352
+ }
353
+ });
354
+ program
355
+ .command("cache <cmd>")
356
+ .description("Cache management")
357
+ .action((cmd) => {
358
+ if (cmd === "clear")
359
+ api_1.default.clearCache();
360
+ else
361
+ ui_1.logger.info("Usage: anich cache clear");
362
+ });
363
+ program.parse();
364
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,sEAA6C;AAC7C,mEAAkC;AAClC,kDAA0B;AAC1B,8CAAsB;AACtB,yCAAkC;AAClC,wDAAgC;AAChC,gDAAwB;AACxB,gDAAwB;AACxB,qCAAiC;AACjC,qCAA+D;AAC/D,6BAWc;AAEd,IAAA,yBAAc,EAAC;IACb,GAAG,EAAH,sBAAG;IACH,mBAAmB,EAAE,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;CACzC,CAAC,CAAC,MAAM,EAAE,CAAC;AAEZ,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,qCAAqC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAE1F,MAAM,GAAG,GAAG,CAAC,KAAa,EAAmB,EAAE;IAC7C,MAAM,EAAE,GAAG,kBAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC7B,EAAE,CAAC,QAAQ,CAAC,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;QACvD,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACtB,CAAC,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,+CAA+C;AAC/C,MAAM,cAAc,GAAG,CAAC,GAAsB,EAAE,IAAW,EAAE,EAAE;IAC7D,IAAI,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;IACrC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;AACzC,CAAC,CAAC;AAEF,2EAA2E;AAC3E,MAAM,YAAY,GAAG,KAAK,EAAE,QAAgB,EAA0B,EAAE;IACtE,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,aAAa;QAE3E,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,8CAA8C,QAAQ,EAAE,EAAE;YAChF,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,YAAY,CAAC,SAAS,CAAC,CAAC;QAExB,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;YAC9C,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;QACtB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,iBAAiB;AACjB,MAAM,aAAa,GAAG,KAAK,EAAE,SAAgB,EAAuB,EAAE;IACpE,IAAA,gBAAW,GAAE,CAAC;IACd,IAAA,iBAAY,EAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;IAC1C,IAAA,wBAAmB,EAAC,SAAS,CAAC,CAAC;IAC/B,WAAM,CAAC,EAAE,EAAE,CAAC;IACZ,WAAM,CAAC,KAAK,CAAC,sBAAsB,GAAG,SAAS,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC;IAE1E,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAEpC,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAErD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;QAC5D,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,WAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACjC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9C,OAAO,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,kBAAkB;AAClB,MAAM,cAAc,GAAG,KAAK,EAAE,WAAgB,EAAE,EAAE;IAChD,MAAM,SAAS,GAAG,WAAW,CAAC,WAAW,EAAE,SAAS,IAAI,EAAE,CAAC;IAE3D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,WAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,IAAA,gBAAW,GAAE,CAAC;IACd,IAAA,iBAAY,EAAC,kBAAkB,EAAE,SAAS,CAAC,CAAC;IAC5C,IAAA,yBAAoB,EAAC,SAAS,CAAC,CAAC;IAChC,WAAM,CAAC,EAAE,EAAE,CAAC;IACZ,WAAM,CAAC,KAAK,CAAC,sBAAsB,GAAG,SAAS,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC;IAE1E,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAEpC,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO;IAEhD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;QAC9D,WAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACjC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9C,OAAO,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAEnC,IAAA,gBAAW,GAAE,CAAC;IACd,IAAA,iBAAY,EAAC,YAAY,QAAQ,CAAC,KAAK,KAAK,QAAQ,CAAC,IAAI,GAAG,EAAE,SAAS,CAAC,CAAC;IAEzE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAa,EAAE,GAAW,EAAE,EAAE;QACnD,MAAM,GAAG,GAAG,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,eAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,WAAM,CAAC,EAAE,EAAE,CAAC;IACZ,WAAM,CAAC,KAAK,CAAC,uBAAuB,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC;IAE/E,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IAE5C,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,GAAG;QAAE,OAAO,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;IAE1F,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAClE,WAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACjC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9C,OAAO,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,WAAM,CAAC,IAAI,CAAC,WAAW,QAAQ,CAAC,KAAK,KAAK,CAAC,CAAC;IAC5C,MAAM,IAAA,cAAI,EAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC;AAEF,wFAAwF;AACxF,MAAM,UAAU,GAAG,KAAK,EAAE,IAAY,EAAE,UAAkB,EAAE,SAAe,EAAE,EAAE;IAC7E,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAE5B,IAAI,CAAC;QACH,8DAA8D;QAC9D,IAAI,IAAI,GAAG,SAAS,CAAC;QACrB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,qBAAqB,CAAC,CAAC,KAAK,EAAE,CAAC;YACnD,MAAM,GAAG,GAAQ,MAAM,aAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YAChB,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,CAAC;QAED,MAAM,MAAM,GAAG,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACzE,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAEzD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,WAAM,CAAC,KAAK,CAAC,WAAW,UAAU,YAAY,CAAC,CAAC;YAChD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,uDAAuD;QACvD,MAAM,KAAK,GAAQ,MAAM,aAAG,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAE3D,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAC7B,WAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAC7C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,CAAC;QAErD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,WAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;YAChD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,mBAAmB,IAAI,OAAO,CAAC,YAAY,CAAC;YACnE,IAAI,GAAG,EAAE,CAAC;gBACR,WAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;gBACzC,MAAM,IAAA,cAAI,EAAC,GAAG,CAAC,CAAC;gBAChB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,eAAe,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC,eAAe;YAAE,OAAO,KAAK,CAAC;QAEnC,IAAA,gBAAW,GAAE,CAAC;QACd,WAAM,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACzC,WAAM,CAAC,IAAI,CAAC,YAAY,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC;QAEjD,IAAI,GAAG,GAAkB,IAAI,CAAC;QAE9B,4BAA4B;QAC5B,KAAK,MAAM,MAAM,IAAI,eAAe,CAAC,UAAU,EAAE,CAAC;YAChD,WAAM,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,KAAK,KAAK,CAAC,CAAC;YACzC,GAAG,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAE1C,IAAI,GAAG,EAAE,CAAC;gBACR,uFAAuF;gBACvF,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC1D,WAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,4CAA4C,CAAC,CAAC;oBACzE,SAAS;gBACX,CAAC;gBACD,MAAM;YACR,CAAC;QACH,CAAC;QAED,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,WAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;YACzD,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC;QACvC,CAAC;QAED,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,WAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,2CAA2C;QAC3C,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtD,WAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YACzC,MAAM,IAAA,cAAI,EAAC,GAAG,CAAC,CAAC;YAChB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,oBAAoB;QACpB,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,CAAC;QACtD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAEnE,MAAM,OAAO,GAAG,MAAM,IAAA,gBAAO,EAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAE5D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,WAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YACrC,MAAM,IAAA,cAAI,EAAC,GAAG,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,WAAM,CAAC,KAAK,CAAC,oBAAoB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAEF,eAAe;AACf,MAAM,eAAe,GAAG,KAAK,EAAE,IAAY,EAAE,IAAS,EAAE,EAAE;IACxD,IAAA,gBAAW,GAAE,CAAC;IACd,IAAA,qBAAgB,EAAC,IAAI,CAAC,CAAC,CAAC,qCAAqC;IAC7D,IAAA,iBAAY,EAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACpC,IAAA,qBAAgB,EAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACnC,WAAM,CAAC,EAAE,EAAE,CAAC;IAEZ,WAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAC5B,WAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IACzD,WAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IACzD,WAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAEpD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAEpC,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO;IAEhD,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC5C,IAAA,gBAAW,GAAE,CAAC;QACd,IAAA,iBAAY,EAAC,4BAA4B,EAAE,SAAS,CAAC,CAAC;QACtD,IAAA,qBAAgB,EAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACnC,WAAM,CAAC,EAAE,EAAE,CAAC;QACZ,WAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAElD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QAExC,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC3C,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC3F,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,KAAK,GAAQ,MAAM,aAAG,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;oBAC3D,IAAI,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;wBAC3B,MAAM,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACnC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,0BAA0B;IACtE,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACzC,gFAAgF;QAChF,yHAAyH;QACzH,MAAM,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;QAEtE,oDAAoD;QACpD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAE9C,wCAAwC;QACxC,OAAO,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,WAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC7B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9C,OAAO,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,wCAAwC;AACxC,MAAM,eAAe,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,GAAQ,MAAM,aAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,WAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACvC,CAAC;AACH,CAAC,CAAC;AAEF,kBAAkB;AAClB,MAAM,aAAa,GAAG,KAAK,EAAE,IAAW,EAAE,KAAa,EAAmB,EAAE;IAC1E,IAAA,gBAAW,GAAE,CAAC;IACd,IAAA,iBAAY,EAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC/B,IAAA,mBAAc,EAAC,IAAI,CAAC,CAAC;IACrB,WAAM,CAAC,EAAE,EAAE,CAAC;IACZ,WAAM,CAAC,KAAK,CAAC,qBAAqB,IAAI,CAAC,MAAM,yBAAyB,CAAC,CAAC;IAExE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAEpC,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,MAAM,CAAC;IAEvD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACvD,MAAM,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3C,OAAO,MAAM,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,WAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACjC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9C,OAAO,MAAM,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC1C,CAAC,CAAC;AAEF,cAAc;AACd,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;IACzB,IAAA,gBAAW,GAAE,CAAC;IACd,IAAA,eAAU,GAAE,CAAC;IACb,IAAA,iBAAY,EAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACrC,IAAA,aAAQ,EAAC,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAE/C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,CAAC;IACpC,MAAM,GAAG,GAAQ,MAAM,aAAG,CAAC,OAAO,EAAE,CAAC;IAErC,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC;QAChD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,WAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAC1D,IAAI,MAAM,KAAK,MAAM;YAAE,MAAM,OAAO,EAAE,CAAC;IACzC,CAAC;SAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,IAAI,EAAE,CAAC;QAClD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,WAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YAClC,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAC5D,IAAI,MAAM,KAAK,MAAM;YAAE,MAAM,OAAO,EAAE,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,WAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC9B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9C,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC;AACH,CAAC,CAAC;AAEF,WAAW;AACX,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,yBAAyB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAE/E,OAAO;KACJ,OAAO,CAAC,uBAAuB,CAAC;KAChC,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,qBAAqB,EAAE,aAAa,CAAC;KAC5C,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,CAAC;KAC/C,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE;IACzB,IAAA,gBAAW,GAAE,CAAC;IACd,IAAA,eAAU,GAAE,CAAC;IACb,MAAM,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,+BAA+B,CAAC;KACxC,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;IACtC,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAE5B,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;QACrC,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;YAC5C,MAAc,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAC7B,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC;YACnB,WAAM,CAAC,OAAO,CAAC,GAAG,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,WAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,WAAM,CAAC,IAAI,CAAC,WAAW,IAAA,sBAAa,GAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,kBAAkB,CAAC;KAC/B,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;IACd,IAAI,GAAG,KAAK,OAAO;QAAE,aAAG,CAAC,UAAU,EAAE,CAAC;;QACjC,WAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const playUrl: (url: string, customPlayer?: string, customArgs?: string[], noBrowser?: boolean) => Promise<boolean>;
2
+ //# sourceMappingURL=player.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"AAuFA,eAAO,MAAM,OAAO,GAClB,KAAK,MAAM,EACX,eAAe,MAAM,EACrB,aAAY,MAAM,EAAO,EACzB,mBAAiB,KAChB,OAAO,CAAC,OAAO,CAuDjB,CAAC"}
package/dist/player.js ADDED
@@ -0,0 +1,142 @@
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.playUrl = void 0;
7
+ const child_process_1 = require("child_process");
8
+ const open_1 = __importDefault(require("open"));
9
+ const ui_1 = require("./ui");
10
+ const fs_1 = __importDefault(require("fs"));
11
+ const path_1 = __importDefault(require("path"));
12
+ const os_1 = __importDefault(require("os"));
13
+ const DEFAULT_PLAYERS = {
14
+ win32: "mpv.exe",
15
+ darwin: "mpv",
16
+ linux: "mpv",
17
+ };
18
+ const FALLBACK_PLAYERS = {
19
+ win32: "vlc.exe",
20
+ darwin: "VLC",
21
+ linux: "vlc",
22
+ };
23
+ const findMpvOnWindows = () => {
24
+ const paths = [
25
+ "C:\\ProgramData\\chocolatey\\lib\\mpvio.install\\tools\\mpv.exe",
26
+ "C:\\ProgramData\\chocolatey\\bin\\mpv.exe",
27
+ "C:\\mpv\\mpv.exe",
28
+ "C:\\Program Files\\mpv\\mpv.exe",
29
+ "C:\\Program Files (x86)\\mpv\\mpv.exe",
30
+ path_1.default.join(os_1.default.homedir(), "AppData", "Local", "Programs", "mpv", "mpv.exe"),
31
+ path_1.default.join(os_1.default.homedir(), "scoop", "apps", "mpv", "current", "mpv.exe"),
32
+ ];
33
+ for (const p of paths) {
34
+ if (fs_1.default.existsSync(p))
35
+ return p;
36
+ }
37
+ return null;
38
+ };
39
+ const commandExists = (cmd) => {
40
+ try {
41
+ const check = process.platform === "win32" ? `where "${cmd}" 2>nul` : `which ${cmd}`;
42
+ (0, child_process_1.execSync)(check, { stdio: "pipe" });
43
+ return true;
44
+ }
45
+ catch {
46
+ return false;
47
+ }
48
+ };
49
+ const spawnPlayer = (player, args) => {
50
+ return new Promise((resolve, reject) => {
51
+ const child = (0, child_process_1.spawn)(player, args, {
52
+ stdio: "ignore",
53
+ detached: true,
54
+ shell: process.platform === "win32",
55
+ windowsHide: process.platform === "win32",
56
+ });
57
+ let resolved = false;
58
+ child.on("error", (err) => {
59
+ if (!resolved) {
60
+ resolved = true;
61
+ reject(err);
62
+ }
63
+ });
64
+ child.on("spawn", () => {
65
+ if (!resolved) {
66
+ child.unref();
67
+ resolved = true;
68
+ resolve(true);
69
+ }
70
+ });
71
+ setTimeout(() => {
72
+ if (!resolved) {
73
+ if (child.pid && !child.killed) {
74
+ child.unref();
75
+ resolved = true;
76
+ resolve(true);
77
+ }
78
+ else {
79
+ resolved = true;
80
+ reject(new Error("Player timeout"));
81
+ }
82
+ }
83
+ }, 2000);
84
+ });
85
+ };
86
+ const playUrl = async (url, customPlayer, customArgs = [], noBrowser = false) => {
87
+ let playerPath = customPlayer;
88
+ const args = customArgs.map((a) => (a.startsWith("--") || a.startsWith("-") ? a : `--${a}`));
89
+ if (!playerPath) {
90
+ if (process.platform === "win32") {
91
+ const found = findMpvOnWindows();
92
+ if (found)
93
+ playerPath = found;
94
+ else {
95
+ const vlc = "C:\\Program Files\\VideoLAN\\VLC\\vlc.exe";
96
+ if (fs_1.default.existsSync(vlc))
97
+ playerPath = vlc;
98
+ }
99
+ }
100
+ else {
101
+ const platform = process.platform;
102
+ const def = DEFAULT_PLAYERS[platform];
103
+ playerPath = commandExists(def)
104
+ ? def
105
+ : commandExists(FALLBACK_PLAYERS[platform])
106
+ ? FALLBACK_PLAYERS[platform]
107
+ : undefined;
108
+ }
109
+ }
110
+ if (!playerPath) {
111
+ ui_1.logger.error("No video player found");
112
+ if (!noBrowser) {
113
+ ui_1.logger.info("Opening in browser...");
114
+ await (0, open_1.default)(url);
115
+ return true;
116
+ }
117
+ return false;
118
+ }
119
+ if (process.platform === "win32" && !fs_1.default.existsSync(playerPath)) {
120
+ ui_1.logger.error(`Player not found: ${playerPath}`);
121
+ if (!noBrowser) {
122
+ await (0, open_1.default)(url);
123
+ return true;
124
+ }
125
+ return false;
126
+ }
127
+ try {
128
+ await spawnPlayer(playerPath, [...args, url]);
129
+ ui_1.logger.success(`Playing in ${path_1.default.basename(playerPath)}`);
130
+ return true;
131
+ }
132
+ catch (err) {
133
+ ui_1.logger.error(`Failed: ${err.message}`);
134
+ if (!noBrowser) {
135
+ await (0, open_1.default)(url);
136
+ return true;
137
+ }
138
+ return false;
139
+ }
140
+ };
141
+ exports.playUrl = playUrl;
142
+ //# sourceMappingURL=player.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.js","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":";;;;;;AAAA,iDAA8C;AAC9C,gDAAwB;AACxB,6BAA4B;AAC5B,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AAEpB,MAAM,eAAe,GAAG;IACtB,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,KAAK;IACb,KAAK,EAAE,KAAK;CACb,CAAC;AAEF,MAAM,gBAAgB,GAAG;IACvB,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,KAAK;IACb,KAAK,EAAE,KAAK;CACb,CAAC;AAEF,MAAM,gBAAgB,GAAG,GAAkB,EAAE;IAC3C,MAAM,KAAK,GAAG;QACZ,iEAAiE;QACjE,2CAA2C;QAC3C,kBAAkB;QAClB,iCAAiC;QACjC,uCAAuC;QACvC,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC;QACzE,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC;KACtE,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,YAAE,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,GAAW,EAAW,EAAE;IAC7C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC;QACrF,IAAA,wBAAQ,EAAC,KAAK,EAAE,EAAC,KAAK,EAAE,MAAM,EAAC,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,MAAc,EAAE,IAAc,EAAoB,EAAE;IACvE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,IAAA,qBAAK,EAAC,MAAM,EAAE,IAAI,EAAE;YAChC,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;YACnC,WAAW,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;SAC1C,CAAC,CAAC;QAEH,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACrB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,OAAO,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;oBAC/B,KAAK,CAAC,KAAK,EAAE,CAAC;oBACd,QAAQ,GAAG,IAAI,CAAC;oBAChB,OAAO,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC;qBAAM,CAAC;oBACN,QAAQ,GAAG,IAAI,CAAC;oBAChB,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEK,MAAM,OAAO,GAAG,KAAK,EAC1B,GAAW,EACX,YAAqB,EACrB,aAAuB,EAAE,EACzB,SAAS,GAAG,KAAK,EACC,EAAE;IACpB,IAAI,UAAU,GAAG,YAAY,CAAC;IAE9B,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAE7F,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;YACjC,IAAI,KAAK;gBAAE,UAAU,GAAG,KAAK,CAAC;iBACzB,CAAC;gBACJ,MAAM,GAAG,GAAG,2CAA2C,CAAC;gBACxD,IAAI,YAAE,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,UAAU,GAAG,GAAG,CAAC;YAC3C,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAwC,CAAC;YAClE,MAAM,GAAG,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;YACtC,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC;gBAC7B,CAAC,CAAC,GAAG;gBACL,CAAC,CAAC,aAAa,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;oBAC3C,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC;oBAC5B,CAAC,CAAC,SAAS,CAAC;QAChB,CAAC;IACH,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,WAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACtC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,WAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YACrC,MAAM,IAAA,cAAI,EAAC,GAAG,CAAC,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/D,WAAM,CAAC,KAAK,CAAC,qBAAqB,UAAU,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAA,cAAI,EAAC,GAAG,CAAC,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,CAAC,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9C,WAAM,CAAC,OAAO,CAAC,cAAc,cAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,WAAM,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAA,cAAI,EAAC,GAAG,CAAC,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AA5DW,QAAA,OAAO,WA4DlB"}
@@ -0,0 +1,119 @@
1
+ export interface ApiResponse<T> {
2
+ status: string;
3
+ creator: string;
4
+ statusCode: number;
5
+ statusMessage?: string;
6
+ message?: string;
7
+ ok: boolean;
8
+ data: T;
9
+ pagination: any;
10
+ }
11
+ export interface AnimeSummary {
12
+ title: string;
13
+ poster: string;
14
+ episodes: number;
15
+ releaseDay?: string;
16
+ latestReleaseDate?: string;
17
+ score?: string;
18
+ lastReleaseDate?: string;
19
+ animeId: string;
20
+ href: string;
21
+ otakudesuUrl: string;
22
+ }
23
+ export interface HomeData {
24
+ ongoing: {
25
+ href: string;
26
+ otakudesuUrl: string;
27
+ animeList: AnimeSummary[];
28
+ };
29
+ completed: {
30
+ href: string;
31
+ otakudesuUrl: string;
32
+ animeList: AnimeSummary[];
33
+ };
34
+ }
35
+ export type HomeResponse = ApiResponse<HomeData>;
36
+ export interface GenreItem {
37
+ title: string;
38
+ genreId: string;
39
+ href: string;
40
+ otakudesuUrl: string;
41
+ }
42
+ export interface GenreData {
43
+ genreList: GenreItem[];
44
+ }
45
+ export type GenreResponse = ApiResponse<GenreData>;
46
+ export interface EpisodeItem {
47
+ title: string;
48
+ eps: number;
49
+ date: string;
50
+ episodeId: string;
51
+ href: string;
52
+ otakudesuUrl: string;
53
+ }
54
+ export interface AnimeDetailData {
55
+ title: string;
56
+ poster: string;
57
+ japanese: string;
58
+ score: string;
59
+ producers: string;
60
+ type: string;
61
+ status: string;
62
+ episodes: number;
63
+ duration: string;
64
+ aired: string;
65
+ studios: string;
66
+ batch: {
67
+ title: string;
68
+ batchId: string;
69
+ href: string;
70
+ otakudesuUrl: string;
71
+ };
72
+ synopsis: {
73
+ paragraphs: string[];
74
+ connections: {
75
+ title: string;
76
+ animeId: string;
77
+ href: string;
78
+ otakudesuUrl: string;
79
+ }[];
80
+ };
81
+ genreList: GenreItem[];
82
+ episodeList: EpisodeItem[];
83
+ recommendedAnimeList: AnimeSummary[];
84
+ }
85
+ export type AnimeDetailResponse = ApiResponse<AnimeDetailData>;
86
+ export interface ServerItem {
87
+ title: string;
88
+ serverId: string;
89
+ href: string;
90
+ }
91
+ export interface QualityItem {
92
+ title: string;
93
+ serverList: ServerItem[];
94
+ }
95
+ export interface EpisodeData {
96
+ title: string;
97
+ animeId: string;
98
+ releaseTime: string;
99
+ defaultStreamingUrl: string;
100
+ server: {
101
+ qualities: QualityItem[];
102
+ };
103
+ downloadUrl: any;
104
+ info: any;
105
+ episodeList: any;
106
+ }
107
+ export type EpisodeResponse = ApiResponse<EpisodeData>;
108
+ export interface ServerData {
109
+ url: string;
110
+ }
111
+ export type ServerResponse = ApiResponse<ServerData>;
112
+ export interface AppConfig {
113
+ [key: string]: any;
114
+ playerPath?: string;
115
+ playerArgs?: string;
116
+ subtitle?: boolean;
117
+ resume?: boolean;
118
+ }
119
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/dist/ui.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ export declare const clearScreen: () => void;
2
+ export declare const showBanner: () => void;
3
+ export declare const createBox: (content: string, title?: string, color?: string) => string;
4
+ export declare const createHeader: (text: string, color?: string) => void;
5
+ export declare const logger: {
6
+ info: (msg: string) => void;
7
+ success: (msg: string) => void;
8
+ warn: (msg: string) => void;
9
+ error: (msg: string) => void;
10
+ plain: (msg: string) => void;
11
+ muted: (msg: string) => void;
12
+ br: () => void;
13
+ };
14
+ export declare const printAnimeList: (list: any[]) => void;
15
+ export declare const printEpisodeList: (list: any[]) => void;
16
+ export declare const showMenu: (options: string[]) => void;
17
+ export declare const showAnimeDetails: (data: any) => void;
18
+ export declare const printQualityOptions: (qualities: any[]) => void;
19
+ export declare const printDownloadOptions: (downloads: any[]) => void;
20
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,WAAW,YAGvB,CAAC;AAEF,eAAO,MAAM,UAAU,YAOtB,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,EAAE,QAAQ,MAAM,EAAE,QAAO,MAAsB,WASvF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,QAAO,MAAsB,SAQvE,CAAC;AAEF,eAAO,MAAM,MAAM;gBACL,MAAM;mBACH,MAAM;gBACT,MAAM;iBACL,MAAM;iBACN,MAAM;iBACN,MAAM;;CAEpB,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,GAAG,EAAE,SAQzC,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,MAAM,GAAG,EAAE,SAgB3C,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,SAAS,MAAM,EAAE,SAMzC,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,MAAM,GAAG,SAwBzC,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,WAAW,GAAG,EAAE,SAOnD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,WAAW,GAAG,EAAE,SAQpD,CAAC"}
package/dist/ui.js ADDED
@@ -0,0 +1,136 @@
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.printDownloadOptions = exports.printQualityOptions = exports.showAnimeDetails = exports.showMenu = exports.printEpisodeList = exports.printAnimeList = exports.logger = exports.createHeader = exports.createBox = exports.showBanner = exports.clearScreen = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const boxen_1 = __importDefault(require("boxen"));
9
+ const gradient_string_1 = __importDefault(require("gradient-string"));
10
+ const figlet_1 = __importDefault(require("figlet"));
11
+ const theme = {
12
+ primary: "#00d9ff",
13
+ secondary: "#ff6b9d",
14
+ success: "#00ff9f",
15
+ warning: "#ffaa00",
16
+ error: "#ff4757",
17
+ info: "#70a1ff",
18
+ muted: "#747d8c",
19
+ };
20
+ const clearScreen = () => {
21
+ console.clear();
22
+ console.log("\n");
23
+ };
24
+ exports.clearScreen = clearScreen;
25
+ const showBanner = () => {
26
+ const banner = figlet_1.default.textSync("ANICH", {
27
+ font: "ANSI Shadow",
28
+ horizontalLayout: "fitted",
29
+ });
30
+ console.log(gradient_string_1.default.pastel.multiline(banner));
31
+ console.log(chalk_1.default.hex(theme.muted)(" Your Ultimate Anime CLI Experience\n"));
32
+ };
33
+ exports.showBanner = showBanner;
34
+ const createBox = (content, title, color = theme.primary) => {
35
+ return (0, boxen_1.default)(content, {
36
+ padding: 1,
37
+ margin: 1,
38
+ borderStyle: "round",
39
+ borderColor: color,
40
+ title: title,
41
+ titleAlignment: "center",
42
+ });
43
+ };
44
+ exports.createBox = createBox;
45
+ const createHeader = (text, color = theme.primary) => {
46
+ const box = (0, boxen_1.default)(chalk_1.default.bold.white(text), {
47
+ padding: { top: 0, bottom: 0, left: 2, right: 2 },
48
+ borderStyle: "round",
49
+ borderColor: color,
50
+ dimBorder: false,
51
+ });
52
+ console.log(box);
53
+ };
54
+ exports.createHeader = createHeader;
55
+ exports.logger = {
56
+ info: (msg) => console.log(chalk_1.default.hex(theme.info)(" ℹ"), chalk_1.default.white(msg)),
57
+ success: (msg) => console.log(chalk_1.default.hex(theme.success)(" ✓"), chalk_1.default.white(msg)),
58
+ warn: (msg) => console.log(chalk_1.default.hex(theme.warning)(" ⚠"), chalk_1.default.white(msg)),
59
+ error: (msg) => console.log(chalk_1.default.hex(theme.error)(" ✗"), chalk_1.default.white(msg)),
60
+ plain: (msg) => console.log(chalk_1.default.white(msg)),
61
+ muted: (msg) => console.log(chalk_1.default.hex(theme.muted)(msg)),
62
+ br: () => console.log(""),
63
+ };
64
+ const printAnimeList = (list) => {
65
+ list.forEach((anime, idx) => {
66
+ const num = chalk_1.default.hex(theme.primary).bold(` ${(idx + 1).toString().padStart(2, "0")}`);
67
+ const title = chalk_1.default.white(anime.title);
68
+ const eps = chalk_1.default.hex(theme.muted)(`[${anime.episodes} eps]`);
69
+ const day = anime.releaseDay ? chalk_1.default.hex(theme.secondary)(`• ${anime.releaseDay}`) : "";
70
+ console.log(`${num} ${title} ${eps} ${day}`);
71
+ });
72
+ };
73
+ exports.printAnimeList = printAnimeList;
74
+ const printEpisodeList = (list) => {
75
+ const columns = 4;
76
+ const rows = Math.ceil(list.length / columns);
77
+ for (let i = 0; i < rows; i++) {
78
+ let row = " ";
79
+ for (let j = 0; j < columns; j++) {
80
+ const idx = i + j * rows;
81
+ if (idx < list.length) {
82
+ const ep = list[idx];
83
+ const num = chalk_1.default.hex(theme.primary).bold(`${ep.eps}`).padStart(3);
84
+ row += `${num} `;
85
+ }
86
+ }
87
+ console.log(row);
88
+ }
89
+ };
90
+ exports.printEpisodeList = printEpisodeList;
91
+ const showMenu = (options) => {
92
+ options.forEach((opt, idx) => {
93
+ const num = chalk_1.default.hex(theme.primary).bold(` [${idx + 1}]`);
94
+ console.log(`${num} ${chalk_1.default.white(opt)}`);
95
+ });
96
+ exports.logger.br();
97
+ };
98
+ exports.showMenu = showMenu;
99
+ const showAnimeDetails = (data) => {
100
+ const info = [
101
+ `${chalk_1.default.hex(theme.secondary)("🇯🇵 Japanese:")} ${chalk_1.default.white(data.japanese)}`,
102
+ `${chalk_1.default.hex(theme.secondary)("⭐ Score:")} ${chalk_1.default.hex(theme.warning)(data.score)}`,
103
+ `${chalk_1.default.hex(theme.secondary)("📺 Status:")} ${chalk_1.default.hex(theme.success)(data.status)}`,
104
+ `${chalk_1.default.hex(theme.secondary)("🏢 Studio:")} ${chalk_1.default.white(data.studios)} ${chalk_1.default.hex(theme.muted)("•")} ${data.type}`,
105
+ `${chalk_1.default.hex(theme.secondary)("⏱️ Duration:")} ${chalk_1.default.white(data.duration)} ${chalk_1.default.hex(theme.muted)("•")} ${data.episodes} episodes`,
106
+ `${chalk_1.default.hex(theme.secondary)("📅 Aired:")} ${chalk_1.default.white(data.aired)}`,
107
+ `${chalk_1.default.hex(theme.secondary)("🏷️ Genres:")} ${chalk_1.default.white(data.genreList.map((g) => g.title).join(", "))}`,
108
+ ].join("\n");
109
+ console.log((0, exports.createBox)(info, data.title, theme.primary));
110
+ exports.logger.muted(" Synopsis:");
111
+ const synopsis = data.synopsis.paragraphs.join(" ");
112
+ const wrapped = synopsis.match(/.{1,80}(\s|$)/g) || [synopsis];
113
+ wrapped.forEach((line) => console.log(chalk_1.default.white(` ${line.trim()}`)));
114
+ exports.logger.br();
115
+ };
116
+ exports.showAnimeDetails = showAnimeDetails;
117
+ const printQualityOptions = (qualities) => {
118
+ qualities.forEach((q, idx) => {
119
+ const num = chalk_1.default.hex(theme.primary).bold(` [${idx + 1}]`);
120
+ const quality = chalk_1.default.white(q.title);
121
+ const servers = chalk_1.default.hex(theme.muted)(`(${q.serverList.length} servers)`);
122
+ console.log(`${num} ${quality} ${servers}`);
123
+ });
124
+ };
125
+ exports.printQualityOptions = printQualityOptions;
126
+ const printDownloadOptions = (downloads) => {
127
+ downloads.forEach((dl, idx) => {
128
+ const num = chalk_1.default.hex(theme.primary).bold(` [${idx + 1}]`);
129
+ const quality = chalk_1.default.white(dl.title);
130
+ const size = chalk_1.default.hex(theme.warning)(dl.size);
131
+ const providers = chalk_1.default.hex(theme.muted)(`(${dl.urls.length} providers)`);
132
+ console.log(`${num} ${quality} ${size} ${providers}`);
133
+ });
134
+ };
135
+ exports.printDownloadOptions = printDownloadOptions;
136
+ //# sourceMappingURL=ui.js.map
package/dist/ui.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "anichi",
3
+ "version": "1.0.1",
4
+ "description": "A modern, interactive CLI for discovering, streaming, and managing anime directly from the terminal.",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "anich": "./bin/anich"
8
+ },
9
+ "type": "commonjs",
10
+ "files": [
11
+ "dist",
12
+ "bin"
13
+ ],
14
+ "scripts": {
15
+ "prebuild": "rimraf dist",
16
+ "build": "tsc",
17
+ "start": "node dist/index.js",
18
+ "dev": "ts-node-dev --respawn src/index.ts",
19
+ "test": "jest",
20
+ "lint": "eslint src --ext .ts",
21
+ "prepare": "npm run build"
22
+ },
23
+ "keywords": [
24
+ "anime",
25
+ "anime-cli",
26
+ "cli",
27
+ "terminal",
28
+ "streaming",
29
+ "mpv",
30
+ "node-cli"
31
+ ],
32
+ "author": {
33
+ "name": "Aditya K.",
34
+ "email": "adityarabbyoka3@gmail.com"
35
+ },
36
+ "license": "MIT",
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ },
40
+ "dependencies": {
41
+ "axios": "^1.6.0",
42
+ "boxen": "^8.0.1",
43
+ "chalk": "^4.1.2",
44
+ "cli-table3": "^0.6.3",
45
+ "commander": "^11.0.0",
46
+ "figlet": "^1.9.4",
47
+ "gradient-string": "^3.0.0",
48
+ "node-cache": "^5.1.2",
49
+ "open": "^8.4.2",
50
+ "ora": "^5.4.1",
51
+ "update-notifier": "^7.3.1"
52
+ },
53
+ "devDependencies": {
54
+ "@types/figlet": "^1.7.0",
55
+ "@types/gradient-string": "^1.1.6",
56
+ "@types/jest": "^29.5.0",
57
+ "@types/node": "^20.0.0",
58
+ "@types/update-notifier": "^6.0.8",
59
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
60
+ "@typescript-eslint/parser": "^6.0.0",
61
+ "eslint": "^8.0.0",
62
+ "jest": "^29.5.0",
63
+ "rimraf": "^5.0.0",
64
+ "ts-jest": "^29.1.0",
65
+ "ts-node-dev": "^2.0.0",
66
+ "typescript": "^5.0.0"
67
+ }
68
+ }