@easyasstudio/xhs-cli 1.4.3
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/AGENTS.md +29 -0
- package/LICENSE +641 -0
- package/README.md +108 -0
- package/dist/browser/cookie.d.ts +1 -0
- package/dist/browser/cookie.d.ts.map +1 -0
- package/dist/browser/cookie.js +2 -0
- package/dist/browser/cookie.js.map +1 -0
- package/dist/browser/index.d.ts +7 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +201 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/cli/cliRouter.d.ts +6 -0
- package/dist/cli/cliRouter.d.ts.map +1 -0
- package/dist/cli/cliRouter.js +249 -0
- package/dist/cli/cliRouter.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/parseArgs.d.ts +13 -0
- package/dist/cli/parseArgs.d.ts.map +1 -0
- package/dist/cli/parseArgs.js +64 -0
- package/dist/cli/parseArgs.js.map +1 -0
- package/dist/config.d.ts +29 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +67 -0
- package/dist/config.js.map +1 -0
- package/dist/toolset/accountRegistry.d.ts +33 -0
- package/dist/toolset/accountRegistry.d.ts.map +1 -0
- package/dist/toolset/accountRegistry.js +198 -0
- package/dist/toolset/accountRegistry.js.map +1 -0
- package/dist/toolset/cachePaths.d.ts +3 -0
- package/dist/toolset/cachePaths.d.ts.map +1 -0
- package/dist/toolset/cachePaths.js +7 -0
- package/dist/toolset/cachePaths.js.map +1 -0
- package/dist/toolset/get_metrics.d.ts +47 -0
- package/dist/toolset/get_metrics.d.ts.map +1 -0
- package/dist/toolset/get_metrics.js +201 -0
- package/dist/toolset/get_metrics.js.map +1 -0
- package/dist/toolset/get_note_detail.d.ts +3 -0
- package/dist/toolset/get_note_detail.d.ts.map +1 -0
- package/dist/toolset/get_note_detail.js +100 -0
- package/dist/toolset/get_note_detail.js.map +1 -0
- package/dist/toolset/get_profile.d.ts +16 -0
- package/dist/toolset/get_profile.d.ts.map +1 -0
- package/dist/toolset/get_profile.js +79 -0
- package/dist/toolset/get_profile.js.map +1 -0
- package/dist/toolset/get_recent_posts.d.ts +3 -0
- package/dist/toolset/get_recent_posts.d.ts.map +1 -0
- package/dist/toolset/get_recent_posts.js +113 -0
- package/dist/toolset/get_recent_posts.js.map +1 -0
- package/dist/toolset/index.d.ts +12 -0
- package/dist/toolset/index.d.ts.map +1 -0
- package/dist/toolset/index.js +48 -0
- package/dist/toolset/index.js.map +1 -0
- package/dist/toolset/login.d.ts +4 -0
- package/dist/toolset/login.d.ts.map +1 -0
- package/dist/toolset/login.js +194 -0
- package/dist/toolset/login.js.map +1 -0
- package/dist/toolset/post.d.ts +27 -0
- package/dist/toolset/post.d.ts.map +1 -0
- package/dist/toolset/post.js +148 -0
- package/dist/toolset/post.js.map +1 -0
- package/dist/toolset/postValidate.d.ts +8 -0
- package/dist/toolset/postValidate.d.ts.map +1 -0
- package/dist/toolset/postValidate.js +59 -0
- package/dist/toolset/postValidate.js.map +1 -0
- package/dist/toolset/publishButton.d.ts +7 -0
- package/dist/toolset/publishButton.d.ts.map +1 -0
- package/dist/toolset/publishButton.js +28 -0
- package/dist/toolset/publishButton.js.map +1 -0
- package/dist/toolset/publishedRecords.d.ts +15 -0
- package/dist/toolset/publishedRecords.d.ts.map +1 -0
- package/dist/toolset/publishedRecords.js +60 -0
- package/dist/toolset/publishedRecords.js.map +1 -0
- package/dist/toolset/sessionResolve.d.ts +12 -0
- package/dist/toolset/sessionResolve.d.ts.map +1 -0
- package/dist/toolset/sessionResolve.js +39 -0
- package/dist/toolset/sessionResolve.js.map +1 -0
- package/dist/toolset/sessionTypes.d.ts +13 -0
- package/dist/toolset/sessionTypes.d.ts.map +1 -0
- package/dist/toolset/sessionTypes.js +3 -0
- package/dist/toolset/sessionTypes.js.map +1 -0
- package/dist/utils/cache.d.ts +10 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +124 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/titleToFilename.d.ts +2 -0
- package/dist/utils/titleToFilename.d.ts.map +1 -0
- package/dist/utils/titleToFilename.js +19 -0
- package/dist/utils/titleToFilename.js.map +1 -0
- package/dist/utils/version_check.d.ts +2 -0
- package/dist/utils/version_check.d.ts.map +1 -0
- package/dist/utils/version_check.js +105 -0
- package/dist/utils/version_check.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionResolve.d.ts","sourceRoot":"","sources":["../../src/toolset/sessionResolve.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAwBnE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,eAAe,CAQxE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ensureAppDataLayout } from '../config.js';
|
|
2
|
+
import { hasConfiguredAccounts, loadAccountsRegistry, } from './accountRegistry.js';
|
|
3
|
+
/**
|
|
4
|
+
* 解析本次命令使用的账号 slug。
|
|
5
|
+
*
|
|
6
|
+
* 优先级:`--account` 显式指定 → registry `currentAccount`(须已通过 `xhs account use` 设置)。
|
|
7
|
+
*/
|
|
8
|
+
export function resolveAccountSlug(explicitAccount) {
|
|
9
|
+
ensureAppDataLayout();
|
|
10
|
+
const reg = loadAccountsRegistry();
|
|
11
|
+
if (!hasConfiguredAccounts(reg)) {
|
|
12
|
+
throw new Error('尚未配置任何账号。请先执行 xhs account add <name>。');
|
|
13
|
+
}
|
|
14
|
+
const explicit = explicitAccount?.trim();
|
|
15
|
+
if (explicit) {
|
|
16
|
+
if (!reg.accounts[explicit]) {
|
|
17
|
+
throw new Error(`未知账号: ${explicit}。可用 xhs account list 查看已配置账号。`);
|
|
18
|
+
}
|
|
19
|
+
return explicit;
|
|
20
|
+
}
|
|
21
|
+
const current = reg.currentAccount?.trim();
|
|
22
|
+
if (current && reg.accounts[current]) {
|
|
23
|
+
return current;
|
|
24
|
+
}
|
|
25
|
+
throw new Error('未设置当前账号。请先执行 xhs account use <slug>,或使用 --account <slug> 临时指定。');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 解析本次命令使用的 Puppeteer userDataDir 与缓存前缀。
|
|
29
|
+
*/
|
|
30
|
+
export function resolveSession(explicitAccount) {
|
|
31
|
+
const slug = resolveAccountSlug(explicitAccount);
|
|
32
|
+
const acc = loadAccountsRegistry().accounts[slug];
|
|
33
|
+
return {
|
|
34
|
+
account: slug,
|
|
35
|
+
browserUserDataDir: acc.browserDataDir,
|
|
36
|
+
cachePathPrefix: `accounts/${slug}/`,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=sessionResolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionResolve.js","sourceRoot":"","sources":["../../src/toolset/sessionResolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EACL,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAG9B;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,eAAwB;IACzD,mBAAmB,EAAE,CAAC;IACtB,MAAM,GAAG,GAAG,oBAAoB,EAAE,CAAC;IAEnC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,EAAE,IAAI,EAAE,CAAC;IACzC,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,SAAS,QAAQ,+BAA+B,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;IAC3C,IAAI,OAAO,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,eAAwB;IACrD,MAAM,IAAI,GAAG,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,oBAAoB,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,kBAAkB,EAAE,GAAG,CAAC,cAAc;QACtC,eAAe,EAAE,YAAY,IAAI,GAAG;KACrC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** 会话与缓存前缀:由 CLI 解析 `--account` 与 registry 得出 */
|
|
2
|
+
export type ResolvedSession = {
|
|
3
|
+
/** 本次使用的账号 slug */
|
|
4
|
+
account: string;
|
|
5
|
+
/** Puppeteer Chrome userDataDir */
|
|
6
|
+
browserUserDataDir: string;
|
|
7
|
+
/**
|
|
8
|
+
* 业务缓存文件相对 CACHE_DIR 的前缀;
|
|
9
|
+
* 遗留单账号会话为 `''`;多账号为 `accounts/<slug>/`
|
|
10
|
+
*/
|
|
11
|
+
cachePathPrefix: string;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=sessionTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionTypes.d.ts","sourceRoot":"","sources":["../../src/toolset/sessionTypes.ts"],"names":[],"mappings":"AAAA,iDAAiD;AAEjD,MAAM,MAAM,eAAe,GAAG;IAC5B,mBAAmB;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionTypes.js","sourceRoot":"","sources":["../../src/toolset/sessionTypes.ts"],"names":[],"mappings":"AAAA,iDAAiD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function ensureCacheDir(): void;
|
|
2
|
+
export declare function saveToCache<T>(filename: string, data: T): void;
|
|
3
|
+
export declare function loadFromCache<T>(filename: string, maxAge?: number): T | null;
|
|
4
|
+
export declare function isCacheValid(filename: string, maxAge?: number): boolean;
|
|
5
|
+
export declare function getCacheMtime(filename: string): Date | null;
|
|
6
|
+
export declare function removeCache(filename: string): boolean;
|
|
7
|
+
export declare function clearCache(): void;
|
|
8
|
+
export declare function listCacheFiles(): string[];
|
|
9
|
+
export declare function cacheExists(filename: string): boolean;
|
|
10
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAgBA,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAID,wBAAgB,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAY9D;AAID,wBAAgB,aAAa,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAwB5E;AAID,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAE,MAAa,GAAG,OAAO,CAY7E;AAGD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAW3D;AAGD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAYrD;AAGD,wBAAgB,UAAU,IAAI,IAAI,CASjC;AAGD,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAUzC;AAGD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGrD"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// src/utils/cache.js
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, statSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { CACHE_DIR, ensureAppDataLayout } from '../config.js';
|
|
5
|
+
// 确保缓存根目录存在(~/.xhs-cli/.cache)
|
|
6
|
+
export function ensureCacheDir() {
|
|
7
|
+
ensureAppDataLayout();
|
|
8
|
+
}
|
|
9
|
+
// 保存数据到缓存文件(自动添加时间戳)
|
|
10
|
+
export function saveToCache(filename, data) {
|
|
11
|
+
ensureCacheDir();
|
|
12
|
+
const filePath = join(CACHE_DIR, filename);
|
|
13
|
+
const dirPath = join(CACHE_DIR, filename.split('/').slice(0, -1).join('/'));
|
|
14
|
+
if (dirPath !== CACHE_DIR && !existsSync(dirPath)) {
|
|
15
|
+
mkdirSync(dirPath, { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
const cached = {
|
|
18
|
+
data: data,
|
|
19
|
+
cachedAt: new Date().toISOString(),
|
|
20
|
+
};
|
|
21
|
+
writeFileSync(filePath, JSON.stringify(cached, null, 2), 'utf8');
|
|
22
|
+
}
|
|
23
|
+
// 从缓存文件读取数据(支持过期检查),参数为秒
|
|
24
|
+
export function loadFromCache(filename, maxAge) {
|
|
25
|
+
const filePath = join(CACHE_DIR, filename);
|
|
26
|
+
if (!existsSync(filePath)) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const content = readFileSync(filePath, 'utf8');
|
|
31
|
+
const parsed = JSON.parse(content);
|
|
32
|
+
if (parsed && typeof parsed === 'object' && 'cachedAt' in parsed && 'data' in parsed) {
|
|
33
|
+
const cached = parsed;
|
|
34
|
+
if (maxAge !== undefined) {
|
|
35
|
+
const cachedTime = new Date(cached.cachedAt).getTime();
|
|
36
|
+
const now = Date.now();
|
|
37
|
+
if (now - cachedTime > maxAge * 1000) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return cached.data;
|
|
42
|
+
}
|
|
43
|
+
return parsed;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error(`⚠️ 读取缓存文件失败: ${filename}`, error);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// 检查缓存是否有效(基于时间)
|
|
51
|
+
export function isCacheValid(filename, maxAge = 3600) {
|
|
52
|
+
const filePath = join(CACHE_DIR, filename);
|
|
53
|
+
if (!existsSync(filePath)) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const stats = statSync(filePath);
|
|
58
|
+
const now = Date.now();
|
|
59
|
+
return now - stats.mtime.getTime() < maxAge;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// 获取缓存文件的修改时间
|
|
66
|
+
export function getCacheMtime(filename) {
|
|
67
|
+
const filePath = join(CACHE_DIR, filename);
|
|
68
|
+
if (!existsSync(filePath)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const stats = statSync(filePath);
|
|
73
|
+
return stats.mtime;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// 删除缓存文件
|
|
80
|
+
export function removeCache(filename) {
|
|
81
|
+
const filePath = join(CACHE_DIR, filename);
|
|
82
|
+
if (!existsSync(filePath)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
require('fs').unlinkSync(filePath);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
console.error(`⚠️ 删除缓存文件失败: ${filename}`, error);
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// 清空整个缓存目录
|
|
95
|
+
export function clearCache() {
|
|
96
|
+
if (existsSync(CACHE_DIR)) {
|
|
97
|
+
try {
|
|
98
|
+
require('fs').rmSync(CACHE_DIR, { recursive: true, force: true });
|
|
99
|
+
console.error('✅ 缓存已清空');
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.error('❌ 清空缓存失败:', error);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// 获取缓存文件列表
|
|
107
|
+
export function listCacheFiles() {
|
|
108
|
+
if (!existsSync(CACHE_DIR)) {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
return require('fs').readdirSync(CACHE_DIR);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
console.error('⚠️ 获取缓存文件列表失败:', error);
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// 检查缓存文件是否存在
|
|
120
|
+
export function cacheExists(filename) {
|
|
121
|
+
const filePath = join(CACHE_DIR, filename);
|
|
122
|
+
return existsSync(filePath);
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"titleToFilename.d.ts","sourceRoot":"","sources":["../../src/utils/titleToFilename.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiBrD"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function titleToFilename(title) {
|
|
2
|
+
// 移除或替换文件名中不允许的字符
|
|
3
|
+
let filename = title
|
|
4
|
+
.replace(/[<>:"/\\|?*]/g, '-') // 替换 Windows 不允许的字符
|
|
5
|
+
.replace(/\s+/g, '-') // 将空格替换为连字符
|
|
6
|
+
.replace(/[^\w\u4e00-\u9fa5-]/g, '') // 只保留字母、数字、中文和连字符
|
|
7
|
+
.replace(/-+/g, '-') // 将多个连字符合并为一个
|
|
8
|
+
.replace(/^-|-$/g, ''); // 移除开头和结尾的连字符
|
|
9
|
+
// 限制文件名长度(保留 .txt 扩展名的空间)
|
|
10
|
+
if (filename.length > 200) {
|
|
11
|
+
filename = filename.substring(0, 200);
|
|
12
|
+
}
|
|
13
|
+
// 如果文件名为空,使用默认名称
|
|
14
|
+
if (!filename) {
|
|
15
|
+
filename = 'untitled';
|
|
16
|
+
}
|
|
17
|
+
return `${filename}.txt`;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=titleToFilename.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"titleToFilename.js","sourceRoot":"","sources":["../../src/utils/titleToFilename.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe,CAAC,KAAa;IACzC,kBAAkB;IAClB,IAAI,QAAQ,GAAG,KAAK;SACf,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAE,oBAAoB;SACnD,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAW,YAAY;SAC3C,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAE,kBAAkB;SACvD,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAY,cAAc;SAC7C,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAS,cAAc;IAClD,0BAA0B;IAC1B,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACxB,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IACD,iBAAiB;IACjB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,QAAQ,GAAG,UAAU,CAAC;IAC1B,CAAC;IACD,OAAO,GAAG,QAAQ,MAAM,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version_check.d.ts","sourceRoot":"","sources":["../../src/utils/version_check.ts"],"names":[],"mappings":"AA8FA,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgBxD"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// 版本检查工具
|
|
2
|
+
import { readFileSync } from 'fs';
|
|
3
|
+
import { join, dirname } from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = dirname(__filename);
|
|
7
|
+
// 获取当前版本
|
|
8
|
+
function getCurrentVersion() {
|
|
9
|
+
try {
|
|
10
|
+
// 尝试多个可能的路径
|
|
11
|
+
// 1. 全局安装时:dist/utils/../../package.json -> node_modules/xhs-cli/package.json
|
|
12
|
+
// 2. 开发环境:src/utils/../../package.json -> 项目根目录/package.json
|
|
13
|
+
// 3. 当前工作目录(如果用户在项目目录中运行)
|
|
14
|
+
const possiblePaths = [
|
|
15
|
+
join(__dirname, '..', '..', 'package.json'), // 最可能的路径(全局安装和开发环境都适用)
|
|
16
|
+
join(process.cwd(), 'package.json'), // 当前工作目录
|
|
17
|
+
];
|
|
18
|
+
for (const packagePath of possiblePaths) {
|
|
19
|
+
try {
|
|
20
|
+
const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
|
21
|
+
if (packageJson && packageJson.version) {
|
|
22
|
+
return packageJson.version;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// 继续尝试下一个路径
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
// 忽略错误
|
|
32
|
+
}
|
|
33
|
+
// 如果所有方法都失败,返回默认值
|
|
34
|
+
return '0.0.0';
|
|
35
|
+
}
|
|
36
|
+
// 从 npm registry 获取最新版本
|
|
37
|
+
async function getLatestVersion() {
|
|
38
|
+
try {
|
|
39
|
+
// 检查 fetch 是否可用
|
|
40
|
+
if (typeof fetch === 'undefined') {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const controller = new AbortController();
|
|
44
|
+
const timeoutId = setTimeout(() => {
|
|
45
|
+
controller.abort();
|
|
46
|
+
}, 3000); // 3秒超时
|
|
47
|
+
try {
|
|
48
|
+
const response = await fetch('https://registry.npmjs.org/xhs-cli/latest', {
|
|
49
|
+
headers: {
|
|
50
|
+
'Accept': 'application/json',
|
|
51
|
+
},
|
|
52
|
+
signal: controller.signal,
|
|
53
|
+
});
|
|
54
|
+
clearTimeout(timeoutId);
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const data = await response.json();
|
|
59
|
+
return data.version || null;
|
|
60
|
+
}
|
|
61
|
+
catch (fetchError) {
|
|
62
|
+
clearTimeout(timeoutId);
|
|
63
|
+
throw fetchError;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// 比较版本号(简单比较,支持语义化版本)
|
|
71
|
+
function compareVersions(current, latest) {
|
|
72
|
+
const currentParts = current.split('.').map(Number);
|
|
73
|
+
const latestParts = latest.split('.').map(Number);
|
|
74
|
+
for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
|
|
75
|
+
const currentPart = currentParts[i] || 0;
|
|
76
|
+
const latestPart = latestParts[i] || 0;
|
|
77
|
+
if (currentPart < latestPart) {
|
|
78
|
+
return -1;
|
|
79
|
+
}
|
|
80
|
+
if (currentPart > latestPart) {
|
|
81
|
+
return 1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
// 检查版本更新(异步,不阻塞)
|
|
87
|
+
export async function checkVersionUpdate() {
|
|
88
|
+
try {
|
|
89
|
+
const currentVersion = getCurrentVersion();
|
|
90
|
+
const latestVersion = await getLatestVersion();
|
|
91
|
+
if (!latestVersion) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (compareVersions(currentVersion, latestVersion) < 0) {
|
|
95
|
+
console.error('\n📦 发现新版本!');
|
|
96
|
+
console.error(` 当前版本: ${currentVersion}`);
|
|
97
|
+
console.error(` 最新版本: ${latestVersion}`);
|
|
98
|
+
console.error(` 更新命令: PUPPETEER_SKIP_DOWNLOAD=true npm install -g xhs-cli@latest\n`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
// 静默失败,不影响主流程
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=version_check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version_check.js","sourceRoot":"","sources":["../../src/utils/version_check.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@easyasstudio/xhs-cli",
|
|
3
|
+
"version": "1.4.3",
|
|
4
|
+
"description": "小红书创作者 CLI(fork: 配置目录统一到 ~/.config/xhs-cli,与 xianyu-auto skill 约定一致)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/cli/index.js",
|
|
7
|
+
"types": "dist/cli/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"xhs": "dist/cli/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md",
|
|
14
|
+
"AGENTS.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"build:test": "tsc -p tsconfig.test.json",
|
|
20
|
+
"test": "npm run build && npm run build:test && find dist-test -name '*.test.js' -print0 | xargs -0 node --test",
|
|
21
|
+
"postpublish": "git checkout README.md",
|
|
22
|
+
"dev": "npm run build && node dist/cli/index.js help",
|
|
23
|
+
"deploy": "node scripts/deploy.mjs"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"xiaohongshu",
|
|
27
|
+
"xhs",
|
|
28
|
+
"小红书",
|
|
29
|
+
"content-creator",
|
|
30
|
+
"social-media",
|
|
31
|
+
"automation",
|
|
32
|
+
"cli",
|
|
33
|
+
"crawler",
|
|
34
|
+
"cover-generation",
|
|
35
|
+
"image-generation"
|
|
36
|
+
],
|
|
37
|
+
"author": "Joo <1546635571@qq.com> (original); fork maintained by woshihoujinxin",
|
|
38
|
+
"license": "GPL-3.0",
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "git+https://github.com/woshihoujinxin/xhs-cli.git"
|
|
45
|
+
},
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/woshihoujinxin/xhs-cli/issues"
|
|
48
|
+
},
|
|
49
|
+
"homepage": "https://github.com/woshihoujinxin/xhs-cli#readme",
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=20.0.0"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"puppeteer-core": "^24.29.1"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/jsdom": "^28.0.3",
|
|
58
|
+
"@types/node": "^24.10.0",
|
|
59
|
+
"jsdom": "^26.1.0",
|
|
60
|
+
"ssh2": "^1.17.0",
|
|
61
|
+
"typescript": "^5.3.3"
|
|
62
|
+
}
|
|
63
|
+
}
|