@pomelolabs/leads 0.2.1 → 0.2.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/client/bundle.js +1 -1
- package/host/browser.js +61 -0
- package/host/index.js +9 -15
- package/package.json +1 -1
package/client/bundle.js
CHANGED
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
// package.json
|
|
123
123
|
var package_default = {
|
|
124
124
|
name: "@pomelolabs/leads",
|
|
125
|
-
version: "0.2.
|
|
125
|
+
version: "0.2.2",
|
|
126
126
|
description: "\u67DA\u5BA2 Pomelo\uFF1A\u5185\u5BB9\u83B7\u5BA2\u5DE5\u4F5C\u53F0\uFF08DSH \u63D2\u4EF6\uFF09",
|
|
127
127
|
license: "UNLICENSED",
|
|
128
128
|
type: "module",
|
package/host/browser.js
CHANGED
|
@@ -11,6 +11,7 @@ import fs from 'node:fs/promises';
|
|
|
11
11
|
import os from 'node:os';
|
|
12
12
|
import path from 'node:path';
|
|
13
13
|
import puppeteer from 'puppeteer-core';
|
|
14
|
+
import { Browser as BrowserType, detectBrowserPlatform, install as installBrowserBinary, resolveBuildId } from '@puppeteer/browsers';
|
|
14
15
|
|
|
15
16
|
const PLATFORM_URLS = {
|
|
16
17
|
xhs: {
|
|
@@ -106,6 +107,62 @@ async function findPlaywrightChromium() {
|
|
|
106
107
|
return '';
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
async function findCachedChromium() {
|
|
111
|
+
const roots = [
|
|
112
|
+
path.join(homeDir(), 'pomelo', 'browser-cache', 'chrome'),
|
|
113
|
+
path.join(os.homedir(), '.cache', 'puppeteer', 'chrome'),
|
|
114
|
+
];
|
|
115
|
+
for (const root of roots) {
|
|
116
|
+
let names = [];
|
|
117
|
+
try { names = await fs.readdir(root); } catch { continue; }
|
|
118
|
+
for (const name of names.sort().reverse()) {
|
|
119
|
+
const base = path.join(root, name);
|
|
120
|
+
const candidates = process.platform === 'darwin'
|
|
121
|
+
? [
|
|
122
|
+
path.join(base, 'chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing'),
|
|
123
|
+
path.join(base, 'chrome-mac-x64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing'),
|
|
124
|
+
path.join(base, 'chrome-mac/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing'),
|
|
125
|
+
]
|
|
126
|
+
: process.platform === 'win32'
|
|
127
|
+
? [path.join(base, 'chrome-win64', 'chrome.exe'), path.join(base, 'chrome-win32', 'chrome.exe')]
|
|
128
|
+
: [path.join(base, 'chrome-linux64', 'chrome'), path.join(base, 'chrome-linux', 'chrome')];
|
|
129
|
+
for (const candidate of candidates) {
|
|
130
|
+
if (await executableAt(candidate)) return candidate;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return '';
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
let browserInstallPromise = null;
|
|
138
|
+
export async function ensureBrowser(log = async () => {}) {
|
|
139
|
+
const existing = await resolveBrowserExecutable();
|
|
140
|
+
if (existing) return existing;
|
|
141
|
+
if (browserInstallPromise) return browserInstallPromise;
|
|
142
|
+
browserInstallPromise = (async () => {
|
|
143
|
+
const platform = detectBrowserPlatform();
|
|
144
|
+
if (!platform) throw new Error('无法识别当前系统平台');
|
|
145
|
+
await log('未找到采集浏览器,开始下载 Chromium(Chrome for Testing)');
|
|
146
|
+
const buildId = await resolveBuildId(BrowserType.CHROME, platform, 'stable');
|
|
147
|
+
const installed = await installBrowserBinary({
|
|
148
|
+
browser: BrowserType.CHROME,
|
|
149
|
+
buildId,
|
|
150
|
+
cacheDir: path.join(homeDir(), 'pomelo', 'browser-cache'),
|
|
151
|
+
platform,
|
|
152
|
+
});
|
|
153
|
+
const executable = installed?.executablePath || '';
|
|
154
|
+
if (!executable) throw new Error('浏览器下载完成,但没有找到可执行文件');
|
|
155
|
+
process.env.PUPPETEER_EXECUTABLE_PATH = executable;
|
|
156
|
+
await log(`Chromium 下载完成:${executable}`);
|
|
157
|
+
return { executable, source: 'downloaded' };
|
|
158
|
+
})();
|
|
159
|
+
try {
|
|
160
|
+
return await browserInstallPromise;
|
|
161
|
+
} finally {
|
|
162
|
+
browserInstallPromise = null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
109
166
|
async function resolveBrowserExecutable() {
|
|
110
167
|
const explicit = process.env.PUPPETEER_EXECUTABLE_PATH || process.env.CHROME_PATH;
|
|
111
168
|
if (explicit && await executableAt(explicit)) {
|
|
@@ -119,6 +176,10 @@ async function resolveBrowserExecutable() {
|
|
|
119
176
|
if (chromium) {
|
|
120
177
|
return { executable: chromium, source: 'playwright-chromium' };
|
|
121
178
|
}
|
|
179
|
+
const cached = await findCachedChromium();
|
|
180
|
+
if (cached) {
|
|
181
|
+
return { executable: cached, source: 'downloaded' };
|
|
182
|
+
}
|
|
122
183
|
try {
|
|
123
184
|
const bundled = typeof puppeteer.executablePath === 'function' ? await puppeteer.executablePath() : '';
|
|
124
185
|
if (bundled && await executableAt(bundled)) {
|
package/host/index.js
CHANGED
|
@@ -9,8 +9,7 @@ import { promisify } from 'node:util';
|
|
|
9
9
|
import fs from 'node:fs/promises';
|
|
10
10
|
import os from 'node:os';
|
|
11
11
|
import path from 'node:path';
|
|
12
|
-
import {
|
|
13
|
-
import { browserStatus, openLink, openLogin, searchPeerProfile, searchPublic } from './browser.js';
|
|
12
|
+
import { browserStatus, ensureBrowser, openLink, openLogin, searchPeerProfile, searchPublic } from './browser.js';
|
|
14
13
|
|
|
15
14
|
const execFileAsync = promisify(execFile);
|
|
16
15
|
|
|
@@ -565,23 +564,14 @@ ${comparisonText}
|
|
|
565
564
|
async function installBrowser() {
|
|
566
565
|
const first = await browserStatus();
|
|
567
566
|
if (first.installed) return first;
|
|
568
|
-
await store.log('开始安装 Chrome(@puppeteer/browsers,无 postinstall)');
|
|
569
567
|
try {
|
|
570
|
-
|
|
571
|
-
if (!platform) throw new Error('无法识别当前系统平台');
|
|
572
|
-
const buildId = await resolveBuildId(BrowserType.CHROME, platform, 'stable');
|
|
573
|
-
await installBrowserBinary({
|
|
574
|
-
browser: BrowserType.CHROME,
|
|
575
|
-
buildId,
|
|
576
|
-
cacheDir: path.join(os.homedir(), '.cache', 'puppeteer'),
|
|
577
|
-
platform,
|
|
578
|
-
});
|
|
568
|
+
await ensureBrowser((message) => store.log(message));
|
|
579
569
|
} catch (error) {
|
|
580
|
-
await store.log(`
|
|
581
|
-
throw rpcError('BROWSER_INSTALL_FAILED', '
|
|
570
|
+
await store.log(`Chromium 下载失败:${error?.message || error}`);
|
|
571
|
+
throw rpcError('BROWSER_INSTALL_FAILED', '采集浏览器下载失败,请检查网络后重试');
|
|
582
572
|
}
|
|
583
573
|
const next = await browserStatus();
|
|
584
|
-
await store.log(`
|
|
574
|
+
await store.log(`Chromium 就绪:${next.executable || '未找到路径'}`);
|
|
585
575
|
return next;
|
|
586
576
|
}
|
|
587
577
|
|
|
@@ -1217,12 +1207,15 @@ ${state.profile.answers[key] || '(未填写)'}
|
|
|
1217
1207
|
case 'browser.status':
|
|
1218
1208
|
return browserStatus();
|
|
1219
1209
|
case 'browser.login':
|
|
1210
|
+
await installBrowser();
|
|
1220
1211
|
return openLogin(payload?.platform || '小红书');
|
|
1221
1212
|
case 'browser.install':
|
|
1222
1213
|
return installBrowser();
|
|
1223
1214
|
case 'browser.open':
|
|
1215
|
+
await installBrowser();
|
|
1224
1216
|
return openLink(payload?.url);
|
|
1225
1217
|
case 'search.run': {
|
|
1218
|
+
await installBrowser();
|
|
1226
1219
|
const platform = payload?.platform === '抖音' ? '抖音' : '小红书';
|
|
1227
1220
|
const keyword = cleanText(payload?.keyword, 80);
|
|
1228
1221
|
if (!keyword) throw rpcError('EMPTY_KEYWORD', '请输入关键词');
|
|
@@ -1244,6 +1237,7 @@ ${state.profile.answers[key] || '(未填写)'}
|
|
|
1244
1237
|
case 'peer.history':
|
|
1245
1238
|
return store.snapshot().peerHistory || [];
|
|
1246
1239
|
case 'peer.run': {
|
|
1240
|
+
await installBrowser();
|
|
1247
1241
|
const platform = payload?.platform === '抖音' ? '抖音' : '小红书';
|
|
1248
1242
|
const account = cleanText(payload?.account, 120);
|
|
1249
1243
|
if (!account) throw rpcError('EMPTY_ACCOUNT', '先粘贴同行账号或 ID');
|