nekostream 2026.0.1 → 2026.1.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/README.md CHANGED
@@ -1,30 +1,30 @@
1
- # NekoStream CLI
2
-
3
- NekoStream CLI là một ứng dụng dòng lệnh xem anime tốc độ cao, siêu nhẹ, tích hợp trình phát video đa tính năng và hỗ trợ lấy dữ liệu từ nhiều nguồn (providers) phổ biến tại Việt Nam.
4
-
5
- ## Cài đặt & Sử dụng
6
-
7
- Yêu cầu: [Node.js](https://nodejs.org/) (phiên bản 18+).
8
-
9
- Mở terminal và chạy lệnh cài đặt toàn cục:
10
- ```bash
11
- npm install -g nekostream-cli
12
- ```
13
-
14
- Sau khi cài đặt xong, bạn có thể gọi ứng dụng từ bất kỳ đâu:
15
- ```bash
16
- nekostream
17
- ```
18
-
19
-
20
- ## Tính năng chính
21
- - Tốc độ cao, gọn nhẹ, điều khiển hoàn toàn bằng phím tắt.
22
- - Theo dõi lịch sử xem phim và tính năng "Tiếp tục xem".
23
- - Thay đổi tùy chọn Domain của Provider linh hoạt.
24
- - Trình phát (Player) tự động phát tập tiếp theo.
25
-
26
- ## Tuyên bố miễn trừ trách nhiệm
27
- - **Phi lợi nhuận**: Dự án không nhằm mục đích thương mại hóa, được tạo ra hoàn toàn vì cộng đồng.
28
- - **Không lưu trữ**: NekoStream CLI đóng vai trò là cầu nối (client). Chúng tôi không lưu trữ, không phát tán bất cứ thông tin hay nội dung số nào ngoài mã nguồn trên thư mục Github này.
29
- - **Tính riêng tư**: Dự án KHÔNG thu thập thông tin của bạn, không sử dụng bất kỳ máy chủ trung gian nào. Mọi request (kết nối) đều là kết nối trực tiếp từ máy tính của bạn đến máy chủ Provider.
30
- - **Mã nguồn mở**: Dự án có sử dụng AI trong quá trình phát triển. Bạn có thể thoải mái clone và tham khảo code, nhưng vui lòng để lại credit. Cảm ơn!
1
+ # NekoStream CLI
2
+
3
+ NekoStream CLI là một ứng dụng dòng lệnh xem anime tốc độ cao, siêu nhẹ, tích hợp trình phát video đa tính năng và hỗ trợ lấy dữ liệu từ nhiều nguồn (providers) phổ biến tại Việt Nam.
4
+
5
+ ## Cài đặt & Sử dụng
6
+
7
+ Yêu cầu: [Node.js](https://nodejs.org/) (phiên bản 18+).
8
+
9
+ Mở terminal và chạy lệnh cài đặt toàn cục:
10
+ ```bash
11
+ npm install -g nekostream
12
+ ```
13
+
14
+ Sau khi cài đặt xong, bạn có thể gọi ứng dụng từ bất kỳ đâu:
15
+ ```bash
16
+ nekostream
17
+ ```
18
+
19
+
20
+ ## Tính năng chính
21
+ - Tốc độ cao, gọn nhẹ, điều khiển hoàn toàn bằng phím tắt.
22
+ - Theo dõi lịch sử xem phim và tính năng "Tiếp tục xem".
23
+ - Thay đổi tùy chọn Domain của Provider linh hoạt.
24
+ - Trình phát (Player) tự động phát tập tiếp theo.
25
+
26
+ ## Tuyên bố miễn trừ trách nhiệm
27
+ - **Phi lợi nhuận**: Dự án không nhằm mục đích thương mại hóa, được tạo ra hoàn toàn vì cộng đồng.
28
+ - **Không lưu trữ**: NekoStream CLI đóng vai trò là cầu nối (client). Chúng tôi không lưu trữ, không phát tán bất cứ thông tin hay nội dung số nào ngoài mã nguồn trên thư mục Github này.
29
+ - **Tính riêng tư**: Dự án KHÔNG thu thập thông tin của bạn, không sử dụng bất kỳ máy chủ trung gian nào. Mọi request (kết nối) đều là kết nối trực tiếp từ máy tính của bạn đến máy chủ Provider.
30
+ - **Mã nguồn mở**: Dự án có sử dụng AI trong quá trình phát triển. Bạn có thể thoải mái clone và tham khảo code, nhưng vui lòng để lại credit. Cảm ơn!
package/bin/nekostream.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
2
-
3
- // NekoStream CLI Entry Point
4
- require('../dist/index.js');
1
+ #!/usr/bin/env node
2
+
3
+ // NekoStream CLI Entry Point
4
+ require('../dist/index.js');
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stripAnsi = stripAnsi;
4
+ exports.visibleLength = visibleLength;
5
+ exports.terminalWidth = terminalWidth;
6
+ exports.padRight = padRight;
7
+ exports.truncate = truncate;
8
+ exports.cleanInline = cleanInline;
9
+ exports.cleanDescription = cleanDescription;
10
+ exports.wrapText = wrapText;
11
+ const ANSI_PATTERN = /\x1B\[[0-9;]*[a-zA-Z]/g;
12
+ function stripAnsi(value) {
13
+ return value.replace(ANSI_PATTERN, '');
14
+ }
15
+ function isCombiningCodePoint(codePoint) {
16
+ return ((codePoint >= 0x0300 && codePoint <= 0x036f) ||
17
+ (codePoint >= 0x1ab0 && codePoint <= 0x1aff) ||
18
+ (codePoint >= 0x1dc0 && codePoint <= 0x1dff) ||
19
+ (codePoint >= 0x20d0 && codePoint <= 0x20ff) ||
20
+ (codePoint >= 0xfe20 && codePoint <= 0xfe2f));
21
+ }
22
+ function isFullWidthCodePoint(codePoint) {
23
+ return (codePoint >= 0x1100 &&
24
+ (codePoint <= 0x115f ||
25
+ codePoint === 0x2329 ||
26
+ codePoint === 0x232a ||
27
+ (codePoint >= 0x2e80 && codePoint <= 0xa4cf && codePoint !== 0x303f) ||
28
+ (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||
29
+ (codePoint >= 0xf900 && codePoint <= 0xfaff) ||
30
+ (codePoint >= 0xfe10 && codePoint <= 0xfe19) ||
31
+ (codePoint >= 0xfe30 && codePoint <= 0xfe6f) ||
32
+ (codePoint >= 0xff00 && codePoint <= 0xff60) ||
33
+ (codePoint >= 0xffe0 && codePoint <= 0xffe6)));
34
+ }
35
+ function charWidth(char) {
36
+ const codePoint = char.codePointAt(0) ?? 0;
37
+ if (codePoint === 0)
38
+ return 0;
39
+ if (codePoint < 32 || (codePoint >= 0x7f && codePoint < 0xa0))
40
+ return 0;
41
+ if (isCombiningCodePoint(codePoint))
42
+ return 0;
43
+ return isFullWidthCodePoint(codePoint) ? 2 : 1;
44
+ }
45
+ function visibleLength(value) {
46
+ return [...stripAnsi(value)].reduce((total, char) => total + charWidth(char), 0);
47
+ }
48
+ function terminalWidth(max = 92, min = 56) {
49
+ const width = process.stdout.columns || 80;
50
+ return Math.max(min, Math.min(max, width - 4));
51
+ }
52
+ function padRight(value, width) {
53
+ const length = visibleLength(value);
54
+ if (length >= width)
55
+ return value;
56
+ return value + ' '.repeat(width - length);
57
+ }
58
+ function truncate(value, maxLength) {
59
+ if (maxLength <= 3)
60
+ return value.slice(0, maxLength);
61
+ if (visibleLength(value) <= maxLength)
62
+ return value;
63
+ const plain = stripAnsi(value);
64
+ let output = '';
65
+ let width = 0;
66
+ for (const char of plain) {
67
+ const nextWidth = charWidth(char);
68
+ if (width + nextWidth > maxLength - 3)
69
+ break;
70
+ output += char;
71
+ width += nextWidth;
72
+ }
73
+ return output.trimEnd() + '...';
74
+ }
75
+ function cleanInline(value) {
76
+ if (value === undefined || value === null || value === '')
77
+ return '??';
78
+ return String(value).replace(/\s+/g, ' ').trim();
79
+ }
80
+ function cleanDescription(value) {
81
+ if (!value)
82
+ return '';
83
+ return value
84
+ .replace(/<[^>]*>?/gm, ' ')
85
+ .replace(/&nbsp;/g, ' ')
86
+ .replace(/&amp;/g, '&')
87
+ .replace(/&quot;/g, '"')
88
+ .replace(/&#39;/g, "'")
89
+ .replace(/\s+/g, ' ')
90
+ .trim();
91
+ }
92
+ function wrapText(value, width) {
93
+ const words = value.split(/\s+/).filter(Boolean);
94
+ const lines = [];
95
+ let current = '';
96
+ for (const word of words) {
97
+ if (visibleLength(word) > width) {
98
+ if (current) {
99
+ lines.push(current);
100
+ current = '';
101
+ }
102
+ lines.push(truncate(word, width));
103
+ continue;
104
+ }
105
+ const candidate = current ? `${current} ${word}` : word;
106
+ if (visibleLength(candidate) > width && current) {
107
+ lines.push(current);
108
+ current = word;
109
+ }
110
+ else {
111
+ current = candidate;
112
+ }
113
+ }
114
+ if (current)
115
+ lines.push(current);
116
+ return lines;
117
+ }
@@ -0,0 +1,49 @@
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.glyphs = exports.uiText = exports.palette = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ exports.palette = {
9
+ primary: '#5eead4',
10
+ accent: '#f472b6',
11
+ blue: '#60a5fa',
12
+ violet: '#a78bfa',
13
+ success: '#34d399',
14
+ warning: '#fbbf24',
15
+ danger: '#fb7185',
16
+ muted: '#94a3b8',
17
+ border: '#334155',
18
+ text: '#f8fafc'
19
+ };
20
+ exports.uiText = {
21
+ brand: chalk_1.default.hex(exports.palette.primary).bold,
22
+ title: chalk_1.default.hex(exports.palette.text).bold,
23
+ subtitle: chalk_1.default.hex(exports.palette.muted),
24
+ section: chalk_1.default.hex(exports.palette.accent).bold,
25
+ label: chalk_1.default.hex(exports.palette.blue),
26
+ value: chalk_1.default.white,
27
+ muted: chalk_1.default.hex(exports.palette.muted),
28
+ success: chalk_1.default.hex(exports.palette.success),
29
+ warning: chalk_1.default.hex(exports.palette.warning),
30
+ danger: chalk_1.default.hex(exports.palette.danger),
31
+ border: chalk_1.default.hex(exports.palette.border),
32
+ accent: chalk_1.default.hex(exports.palette.accent)
33
+ };
34
+ exports.glyphs = {
35
+ topLeft: '╭',
36
+ topRight: '╮',
37
+ bottomLeft: '╰',
38
+ bottomRight: '╯',
39
+ horizontal: '─',
40
+ vertical: '│',
41
+ teeLeft: '├',
42
+ teeRight: '┤',
43
+ dot: '•',
44
+ pointer: '›',
45
+ back: '←',
46
+ play: '▶',
47
+ next: '↓',
48
+ prev: '↑'
49
+ };