@iflyrpa/playwright 1.0.10 → 1.0.11
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/dist/index.cjs +80 -72
- package/dist/index.d.cts +18 -15
- package/dist/index.d.mts +18 -15
- package/dist/index.d.ts +18 -15
- package/dist/index.mjs +78 -71
- package/package.json +2 -3
package/dist/index.cjs
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const path = require('node:path');
|
|
4
3
|
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
5
|
const https = require('node:https');
|
|
6
6
|
const log = require('loglevel');
|
|
7
|
-
const
|
|
7
|
+
const npminstall = require('npminstall');
|
|
8
8
|
|
|
9
9
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
10
10
|
|
|
11
|
-
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
12
11
|
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
12
|
+
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
13
13
|
const https__default = /*#__PURE__*/_interopDefaultCompat(https);
|
|
14
14
|
const log__default = /*#__PURE__*/_interopDefaultCompat(log);
|
|
15
|
+
const npminstall__default = /*#__PURE__*/_interopDefaultCompat(npminstall);
|
|
15
16
|
|
|
16
17
|
const name = "@iflyrpa/playwright";
|
|
17
18
|
const type = "module";
|
|
18
|
-
const version$1 = "1.0.
|
|
19
|
-
const description = "";
|
|
19
|
+
const version$1 = "1.0.11";
|
|
20
20
|
const main = "./dist/index.cjs";
|
|
21
21
|
const module$1 = "./dist/index.mjs";
|
|
22
22
|
const types = "./dist/index.d.ts";
|
|
@@ -25,8 +25,6 @@ const scripts = {
|
|
|
25
25
|
dev: "unbuild --stub",
|
|
26
26
|
start: "esno src/index.ts"
|
|
27
27
|
};
|
|
28
|
-
const keywords = [
|
|
29
|
-
];
|
|
30
28
|
const author = "bijinfeng";
|
|
31
29
|
const license = "ISC";
|
|
32
30
|
const files = [
|
|
@@ -34,6 +32,7 @@ const files = [
|
|
|
34
32
|
];
|
|
35
33
|
const dependencies = {
|
|
36
34
|
loglevel: "^1.9.2",
|
|
35
|
+
npminstall: "^7.12.0",
|
|
37
36
|
playwright: "^1.46.1"
|
|
38
37
|
};
|
|
39
38
|
const peerDependencies = {
|
|
@@ -48,12 +47,10 @@ const packageJson = {
|
|
|
48
47
|
name: name,
|
|
49
48
|
type: type,
|
|
50
49
|
version: version$1,
|
|
51
|
-
description: description,
|
|
52
50
|
main: main,
|
|
53
51
|
module: module$1,
|
|
54
52
|
types: types,
|
|
55
53
|
scripts: scripts,
|
|
56
|
-
keywords: keywords,
|
|
57
54
|
author: author,
|
|
58
55
|
license: license,
|
|
59
56
|
files: files,
|
|
@@ -221,7 +218,7 @@ const visibleRangeTexts = {
|
|
|
221
218
|
private: "\u79C1\u5BC6"
|
|
222
219
|
};
|
|
223
220
|
const xiaohongshuPublishAction = async (props) => {
|
|
224
|
-
const { page,
|
|
221
|
+
const { page, tmpCachePath, params } = props;
|
|
225
222
|
const selectAddress = async (selector, address) => {
|
|
226
223
|
const instance = typeof selector === "string" ? page.locator(selector) : selector;
|
|
227
224
|
await instance.click();
|
|
@@ -244,11 +241,13 @@ const xiaohongshuPublishAction = async (props) => {
|
|
|
244
241
|
await page.locator("#content-area .menu-container .publish-video a").click().catch(() => {
|
|
245
242
|
throw new Error("\u672A\u627E\u5230\u53D1\u5E03\u7B14\u8BB0\u6309\u94AE");
|
|
246
243
|
});
|
|
247
|
-
await page.locator(".creator-container .header .title").filter({ hasText: /^上传图文$/ }).click()
|
|
244
|
+
await page.locator(".creator-container .header .title").filter({ hasText: /^上传图文$/ }).click().catch(() => {
|
|
245
|
+
throw new Error("\u672A\u627E\u5230\u4E0A\u4F20\u56FE\u6587\u6309\u94AE");
|
|
246
|
+
});
|
|
248
247
|
const images = await Promise.all(
|
|
249
248
|
params.banners.map((url) => {
|
|
250
249
|
const fileName = getFilenameFromUrl(url);
|
|
251
|
-
return downloadImage(url, path__default.join(
|
|
250
|
+
return downloadImage(url, path__default.join(tmpCachePath, fileName));
|
|
252
251
|
})
|
|
253
252
|
);
|
|
254
253
|
const fileChooserPromise = page.waitForEvent("filechooser");
|
|
@@ -383,12 +382,11 @@ const _Logger = class _Logger {
|
|
|
383
382
|
log__default.warn(...msg);
|
|
384
383
|
}
|
|
385
384
|
error(prefix, error) {
|
|
386
|
-
|
|
385
|
+
log__default.error(prefix);
|
|
387
386
|
if (error instanceof Error) {
|
|
388
|
-
|
|
389
|
-
Error stack: ${error.stack}
|
|
387
|
+
log__default.error(`${error.message}
|
|
388
|
+
Error stack: ${error.stack}`);
|
|
390
389
|
}
|
|
391
|
-
log__default.error(prefix, errorMessage);
|
|
392
390
|
}
|
|
393
391
|
close() {
|
|
394
392
|
this.stream.end();
|
|
@@ -413,7 +411,7 @@ const generateFile = async (dir) => {
|
|
|
413
411
|
}
|
|
414
412
|
return filePath;
|
|
415
413
|
};
|
|
416
|
-
const createElectronApp = async (cachePath,
|
|
414
|
+
const createElectronApp = async (cachePath, playwright) => {
|
|
417
415
|
const logger = Logger.getInstance(cachePath);
|
|
418
416
|
try {
|
|
419
417
|
const executablePath = path__default.join(
|
|
@@ -422,7 +420,6 @@ const createElectronApp = async (cachePath, playwrightPackage) => {
|
|
|
422
420
|
".bin",
|
|
423
421
|
"electron"
|
|
424
422
|
);
|
|
425
|
-
const playwright = await playwrightPackage;
|
|
426
423
|
const mainPath = await generateFile(cachePath);
|
|
427
424
|
const electronApp = await playwright._electron.launch({
|
|
428
425
|
executablePath,
|
|
@@ -434,6 +431,7 @@ const createElectronApp = async (cachePath, playwrightPackage) => {
|
|
|
434
431
|
return electronApp;
|
|
435
432
|
} catch (error) {
|
|
436
433
|
logger.error("electron \u542F\u52A8\u5931\u8D25\uFF1A", error);
|
|
434
|
+
throw error;
|
|
437
435
|
}
|
|
438
436
|
};
|
|
439
437
|
|
|
@@ -443,6 +441,7 @@ var __publicField$1 = (obj, key, value) => {
|
|
|
443
441
|
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
444
442
|
return value;
|
|
445
443
|
};
|
|
444
|
+
const NPM_REGISTRY = "https://registry.npmmirror.com/";
|
|
446
445
|
class PackageManager {
|
|
447
446
|
constructor(params) {
|
|
448
447
|
__publicField$1(this, "cacheDir");
|
|
@@ -457,37 +456,6 @@ class PackageManager {
|
|
|
457
456
|
this.initCacheProject();
|
|
458
457
|
this.initPromise = this.init(params.packageName, params.packageVersion);
|
|
459
458
|
}
|
|
460
|
-
// 在子线程执行 npm 命令
|
|
461
|
-
execCommand(cmd, modules, where = this.cacheDir) {
|
|
462
|
-
return new Promise((resolve) => {
|
|
463
|
-
const args = [cmd].concat(modules).concat("--color=always").concat("--save");
|
|
464
|
-
try {
|
|
465
|
-
const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
466
|
-
const npm = node_child_process.spawn(npmCmd, args, { cwd: where });
|
|
467
|
-
let output = "";
|
|
468
|
-
npm.stdout?.on("data", (data) => {
|
|
469
|
-
output += data;
|
|
470
|
-
}).pipe(process.stdout);
|
|
471
|
-
npm.stderr?.on("data", (data) => {
|
|
472
|
-
output += data;
|
|
473
|
-
}).pipe(process.stderr);
|
|
474
|
-
npm.on("close", (code) => {
|
|
475
|
-
if (!code) {
|
|
476
|
-
resolve({ code: 0, data: output });
|
|
477
|
-
} else {
|
|
478
|
-
resolve({ code, data: output });
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
npm.on("error", (err) => {
|
|
482
|
-
console.error("NPM is not installed");
|
|
483
|
-
console.error(err);
|
|
484
|
-
});
|
|
485
|
-
} catch (error) {
|
|
486
|
-
this.logger.error(`npm ${args.join(" ")}: `, error);
|
|
487
|
-
console.error(error);
|
|
488
|
-
}
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
459
|
// 构建 package.json 文件,有了该文件后,依赖可以安装在该目录下,避免污染全局环境
|
|
492
460
|
initCacheProject() {
|
|
493
461
|
const packagePath = path__default.join(this.cacheDir, "package.json");
|
|
@@ -527,27 +495,30 @@ class PackageManager {
|
|
|
527
495
|
}
|
|
528
496
|
// 安装依赖
|
|
529
497
|
install(module, version) {
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
return this.execCommand("update", [module]);
|
|
498
|
+
return npminstall__default({
|
|
499
|
+
root: this.cacheDir,
|
|
500
|
+
pkgs: [{ name: module, version }],
|
|
501
|
+
registry: NPM_REGISTRY
|
|
502
|
+
});
|
|
536
503
|
}
|
|
537
504
|
async init(name, version) {
|
|
538
505
|
const plugin = this.getPlugin(path__default.join(name, "package.json"));
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
506
|
+
try {
|
|
507
|
+
if (!plugin) {
|
|
508
|
+
await this.install(name, version);
|
|
509
|
+
} else if (this.forceUpdate) {
|
|
510
|
+
const pkInfo = await this.getPluginInfo(name);
|
|
511
|
+
if (!pkInfo)
|
|
512
|
+
return;
|
|
513
|
+
const hasNewVersion = semver.gt(pkInfo.version, plugin.version);
|
|
514
|
+
if (hasNewVersion) {
|
|
515
|
+
await this.install(name, pkInfo.version);
|
|
516
|
+
}
|
|
548
517
|
}
|
|
518
|
+
this.logger.info(`${name} package manager init done!`);
|
|
519
|
+
} catch (error) {
|
|
520
|
+
this.logger.error(`${name} package manager init error`, error);
|
|
549
521
|
}
|
|
550
|
-
this.logger.info(`${name} package manager init done!`);
|
|
551
522
|
}
|
|
552
523
|
}
|
|
553
524
|
|
|
@@ -558,17 +529,20 @@ var __publicField = (obj, key, value) => {
|
|
|
558
529
|
return value;
|
|
559
530
|
};
|
|
560
531
|
const PLAYWRIGHT_VERSION = "1.46.1";
|
|
532
|
+
const ELECTRON_VERSION = "22.3.27";
|
|
561
533
|
class LocalAutomateTask {
|
|
562
534
|
constructor({ cachePath, debug }) {
|
|
535
|
+
__publicField(this, "logger");
|
|
563
536
|
__publicField(this, "cachePath");
|
|
564
537
|
__publicField(this, "debug");
|
|
565
538
|
__publicField(this, "playwrightPackage");
|
|
566
|
-
__publicField(this, "
|
|
539
|
+
__publicField(this, "electronPackage");
|
|
567
540
|
__publicField(this, "_electronApp", null);
|
|
568
541
|
this.cachePath = cachePath;
|
|
569
542
|
this.debug = debug || false;
|
|
570
543
|
this.logger = Logger.getInstance(cachePath);
|
|
571
544
|
this.playwrightPackage = this.installPlaywright();
|
|
545
|
+
this.electronPackage = this.installElectron();
|
|
572
546
|
}
|
|
573
547
|
/**
|
|
574
548
|
* 安装 playwright
|
|
@@ -582,25 +556,59 @@ class LocalAutomateTask {
|
|
|
582
556
|
});
|
|
583
557
|
return playwrightPackageManager.getPluginAfterInit("playwright");
|
|
584
558
|
}
|
|
559
|
+
/**
|
|
560
|
+
* 安装 electron
|
|
561
|
+
* @returns
|
|
562
|
+
*/
|
|
563
|
+
installElectron() {
|
|
564
|
+
const playwrightPackageManager = new PackageManager({
|
|
565
|
+
packageName: "electron",
|
|
566
|
+
packageVersion: ELECTRON_VERSION,
|
|
567
|
+
cacheDir: this.cachePath
|
|
568
|
+
});
|
|
569
|
+
return playwrightPackageManager.getPluginAfterInit("electron");
|
|
570
|
+
}
|
|
585
571
|
/**
|
|
586
572
|
* 启动 Electron
|
|
587
573
|
* @returns
|
|
588
574
|
*/
|
|
589
575
|
async getElectronApp() {
|
|
590
576
|
if (!this._electronApp) {
|
|
591
|
-
|
|
592
|
-
this.
|
|
593
|
-
this.
|
|
594
|
-
);
|
|
577
|
+
const [playwright] = await Promise.all([
|
|
578
|
+
this.playwrightPackage,
|
|
579
|
+
this.electronPackage
|
|
580
|
+
]);
|
|
581
|
+
this._electronApp = await createElectronApp(this.cachePath, playwright);
|
|
595
582
|
}
|
|
596
583
|
return this._electronApp;
|
|
597
584
|
}
|
|
585
|
+
/**
|
|
586
|
+
* 临时文件目录
|
|
587
|
+
* @returns
|
|
588
|
+
*/
|
|
589
|
+
getTmpPath() {
|
|
590
|
+
return path__default.join(this.cachePath, "tmp");
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* 清空临时文件
|
|
594
|
+
*/
|
|
595
|
+
clearTmpPath() {
|
|
596
|
+
const tmpPath = this.getTmpPath();
|
|
597
|
+
return fs__default.rm(tmpPath, { recursive: true, force: true }, (err) => {
|
|
598
|
+
if (err) {
|
|
599
|
+
this.logger.error("\u5220\u9664\u4E34\u65F6\u6587\u4EF6\u5931\u8D25\uFF0C", err);
|
|
600
|
+
} else {
|
|
601
|
+
this.logger.info("\u5220\u9664\u4E34\u65F6\u6587\u4EF6\u6210\u529F");
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
}
|
|
598
605
|
/**
|
|
599
606
|
* 关闭 playwright 启动的 electron 客户端
|
|
600
607
|
* @returns
|
|
601
608
|
*/
|
|
602
609
|
async close() {
|
|
603
610
|
this.logger.close();
|
|
611
|
+
this.clearTmpPath();
|
|
604
612
|
const electronApp = await this.getElectronApp();
|
|
605
613
|
return electronApp.close();
|
|
606
614
|
}
|
|
@@ -652,13 +660,13 @@ class LocalAutomateTask {
|
|
|
652
660
|
const res = await xiaohongshuPublishAction({
|
|
653
661
|
page,
|
|
654
662
|
params,
|
|
655
|
-
|
|
663
|
+
tmpCachePath: this.getTmpPath(),
|
|
656
664
|
debug: !!this.debug
|
|
657
665
|
});
|
|
658
666
|
return res;
|
|
659
667
|
} catch (error) {
|
|
660
668
|
this.logger.error("\u5C0F\u7EA2\u4E66\u53D1\u5E03\u5931\u8D25", error);
|
|
661
|
-
|
|
669
|
+
throw error;
|
|
662
670
|
}
|
|
663
671
|
}
|
|
664
672
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
import { CookiesSetDetails } from 'electron';
|
|
2
2
|
|
|
3
|
-
declare class Logger {
|
|
4
|
-
static instance: Logger | null;
|
|
5
|
-
private stream;
|
|
6
|
-
constructor(cachePath: string);
|
|
7
|
-
static getInstance(cachePath: string): Logger;
|
|
8
|
-
debug(...msg: any[]): void;
|
|
9
|
-
info(...msg: any[]): void;
|
|
10
|
-
warn(...msg: any[]): void;
|
|
11
|
-
error(prefix: string, error: unknown): void;
|
|
12
|
-
close(): void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
3
|
type CookieMap = CookiesSetDetails[];
|
|
16
4
|
|
|
17
5
|
interface FictionalRendition {
|
|
@@ -55,10 +43,11 @@ interface TaskParams {
|
|
|
55
43
|
cachePath: string;
|
|
56
44
|
}
|
|
57
45
|
declare class LocalAutomateTask implements TaskParams {
|
|
46
|
+
private logger;
|
|
58
47
|
cachePath: string;
|
|
59
48
|
debug: boolean;
|
|
60
|
-
playwrightPackage
|
|
61
|
-
|
|
49
|
+
private playwrightPackage;
|
|
50
|
+
private electronPackage;
|
|
62
51
|
private _electronApp;
|
|
63
52
|
constructor({ cachePath, debug }: TaskParams);
|
|
64
53
|
/**
|
|
@@ -66,11 +55,25 @@ declare class LocalAutomateTask implements TaskParams {
|
|
|
66
55
|
* @returns
|
|
67
56
|
*/
|
|
68
57
|
private installPlaywright;
|
|
58
|
+
/**
|
|
59
|
+
* 安装 electron
|
|
60
|
+
* @returns
|
|
61
|
+
*/
|
|
62
|
+
private installElectron;
|
|
69
63
|
/**
|
|
70
64
|
* 启动 Electron
|
|
71
65
|
* @returns
|
|
72
66
|
*/
|
|
73
67
|
private getElectronApp;
|
|
68
|
+
/**
|
|
69
|
+
* 临时文件目录
|
|
70
|
+
* @returns
|
|
71
|
+
*/
|
|
72
|
+
private getTmpPath;
|
|
73
|
+
/**
|
|
74
|
+
* 清空临时文件
|
|
75
|
+
*/
|
|
76
|
+
private clearTmpPath;
|
|
74
77
|
/**
|
|
75
78
|
* 关闭 playwright 启动的 electron 客户端
|
|
76
79
|
* @returns
|
|
@@ -79,7 +82,7 @@ declare class LocalAutomateTask implements TaskParams {
|
|
|
79
82
|
/**
|
|
80
83
|
* 小红书自动化发布
|
|
81
84
|
*/
|
|
82
|
-
xiaohongshuPublish(params: XiaohonshuPublishParams): Promise<
|
|
85
|
+
xiaohongshuPublish(params: XiaohonshuPublishParams): Promise<string>;
|
|
83
86
|
}
|
|
84
87
|
declare const RpaTask: (params: TaskParams) => LocalAutomateTask;
|
|
85
88
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
import { CookiesSetDetails } from 'electron';
|
|
2
2
|
|
|
3
|
-
declare class Logger {
|
|
4
|
-
static instance: Logger | null;
|
|
5
|
-
private stream;
|
|
6
|
-
constructor(cachePath: string);
|
|
7
|
-
static getInstance(cachePath: string): Logger;
|
|
8
|
-
debug(...msg: any[]): void;
|
|
9
|
-
info(...msg: any[]): void;
|
|
10
|
-
warn(...msg: any[]): void;
|
|
11
|
-
error(prefix: string, error: unknown): void;
|
|
12
|
-
close(): void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
3
|
type CookieMap = CookiesSetDetails[];
|
|
16
4
|
|
|
17
5
|
interface FictionalRendition {
|
|
@@ -55,10 +43,11 @@ interface TaskParams {
|
|
|
55
43
|
cachePath: string;
|
|
56
44
|
}
|
|
57
45
|
declare class LocalAutomateTask implements TaskParams {
|
|
46
|
+
private logger;
|
|
58
47
|
cachePath: string;
|
|
59
48
|
debug: boolean;
|
|
60
|
-
playwrightPackage
|
|
61
|
-
|
|
49
|
+
private playwrightPackage;
|
|
50
|
+
private electronPackage;
|
|
62
51
|
private _electronApp;
|
|
63
52
|
constructor({ cachePath, debug }: TaskParams);
|
|
64
53
|
/**
|
|
@@ -66,11 +55,25 @@ declare class LocalAutomateTask implements TaskParams {
|
|
|
66
55
|
* @returns
|
|
67
56
|
*/
|
|
68
57
|
private installPlaywright;
|
|
58
|
+
/**
|
|
59
|
+
* 安装 electron
|
|
60
|
+
* @returns
|
|
61
|
+
*/
|
|
62
|
+
private installElectron;
|
|
69
63
|
/**
|
|
70
64
|
* 启动 Electron
|
|
71
65
|
* @returns
|
|
72
66
|
*/
|
|
73
67
|
private getElectronApp;
|
|
68
|
+
/**
|
|
69
|
+
* 临时文件目录
|
|
70
|
+
* @returns
|
|
71
|
+
*/
|
|
72
|
+
private getTmpPath;
|
|
73
|
+
/**
|
|
74
|
+
* 清空临时文件
|
|
75
|
+
*/
|
|
76
|
+
private clearTmpPath;
|
|
74
77
|
/**
|
|
75
78
|
* 关闭 playwright 启动的 electron 客户端
|
|
76
79
|
* @returns
|
|
@@ -79,7 +82,7 @@ declare class LocalAutomateTask implements TaskParams {
|
|
|
79
82
|
/**
|
|
80
83
|
* 小红书自动化发布
|
|
81
84
|
*/
|
|
82
|
-
xiaohongshuPublish(params: XiaohonshuPublishParams): Promise<
|
|
85
|
+
xiaohongshuPublish(params: XiaohonshuPublishParams): Promise<string>;
|
|
83
86
|
}
|
|
84
87
|
declare const RpaTask: (params: TaskParams) => LocalAutomateTask;
|
|
85
88
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
import { CookiesSetDetails } from 'electron';
|
|
2
2
|
|
|
3
|
-
declare class Logger {
|
|
4
|
-
static instance: Logger | null;
|
|
5
|
-
private stream;
|
|
6
|
-
constructor(cachePath: string);
|
|
7
|
-
static getInstance(cachePath: string): Logger;
|
|
8
|
-
debug(...msg: any[]): void;
|
|
9
|
-
info(...msg: any[]): void;
|
|
10
|
-
warn(...msg: any[]): void;
|
|
11
|
-
error(prefix: string, error: unknown): void;
|
|
12
|
-
close(): void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
3
|
type CookieMap = CookiesSetDetails[];
|
|
16
4
|
|
|
17
5
|
interface FictionalRendition {
|
|
@@ -55,10 +43,11 @@ interface TaskParams {
|
|
|
55
43
|
cachePath: string;
|
|
56
44
|
}
|
|
57
45
|
declare class LocalAutomateTask implements TaskParams {
|
|
46
|
+
private logger;
|
|
58
47
|
cachePath: string;
|
|
59
48
|
debug: boolean;
|
|
60
|
-
playwrightPackage
|
|
61
|
-
|
|
49
|
+
private playwrightPackage;
|
|
50
|
+
private electronPackage;
|
|
62
51
|
private _electronApp;
|
|
63
52
|
constructor({ cachePath, debug }: TaskParams);
|
|
64
53
|
/**
|
|
@@ -66,11 +55,25 @@ declare class LocalAutomateTask implements TaskParams {
|
|
|
66
55
|
* @returns
|
|
67
56
|
*/
|
|
68
57
|
private installPlaywright;
|
|
58
|
+
/**
|
|
59
|
+
* 安装 electron
|
|
60
|
+
* @returns
|
|
61
|
+
*/
|
|
62
|
+
private installElectron;
|
|
69
63
|
/**
|
|
70
64
|
* 启动 Electron
|
|
71
65
|
* @returns
|
|
72
66
|
*/
|
|
73
67
|
private getElectronApp;
|
|
68
|
+
/**
|
|
69
|
+
* 临时文件目录
|
|
70
|
+
* @returns
|
|
71
|
+
*/
|
|
72
|
+
private getTmpPath;
|
|
73
|
+
/**
|
|
74
|
+
* 清空临时文件
|
|
75
|
+
*/
|
|
76
|
+
private clearTmpPath;
|
|
74
77
|
/**
|
|
75
78
|
* 关闭 playwright 启动的 electron 客户端
|
|
76
79
|
* @returns
|
|
@@ -79,7 +82,7 @@ declare class LocalAutomateTask implements TaskParams {
|
|
|
79
82
|
/**
|
|
80
83
|
* 小红书自动化发布
|
|
81
84
|
*/
|
|
82
|
-
xiaohongshuPublish(params: XiaohonshuPublishParams): Promise<
|
|
85
|
+
xiaohongshuPublish(params: XiaohonshuPublishParams): Promise<string>;
|
|
83
86
|
}
|
|
84
87
|
declare const RpaTask: (params: TaskParams) => LocalAutomateTask;
|
|
85
88
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
1
|
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
3
|
import https from 'node:https';
|
|
4
4
|
import log from 'loglevel';
|
|
5
|
-
import
|
|
5
|
+
import npminstall from 'npminstall';
|
|
6
6
|
|
|
7
7
|
const name = "@iflyrpa/playwright";
|
|
8
8
|
const type = "module";
|
|
9
|
-
const version$1 = "1.0.
|
|
10
|
-
const description = "";
|
|
9
|
+
const version$1 = "1.0.11";
|
|
11
10
|
const main = "./dist/index.cjs";
|
|
12
11
|
const module = "./dist/index.mjs";
|
|
13
12
|
const types = "./dist/index.d.ts";
|
|
@@ -16,8 +15,6 @@ const scripts = {
|
|
|
16
15
|
dev: "unbuild --stub",
|
|
17
16
|
start: "esno src/index.ts"
|
|
18
17
|
};
|
|
19
|
-
const keywords = [
|
|
20
|
-
];
|
|
21
18
|
const author = "bijinfeng";
|
|
22
19
|
const license = "ISC";
|
|
23
20
|
const files = [
|
|
@@ -25,6 +22,7 @@ const files = [
|
|
|
25
22
|
];
|
|
26
23
|
const dependencies = {
|
|
27
24
|
loglevel: "^1.9.2",
|
|
25
|
+
npminstall: "^7.12.0",
|
|
28
26
|
playwright: "^1.46.1"
|
|
29
27
|
};
|
|
30
28
|
const peerDependencies = {
|
|
@@ -39,12 +37,10 @@ const packageJson = {
|
|
|
39
37
|
name: name,
|
|
40
38
|
type: type,
|
|
41
39
|
version: version$1,
|
|
42
|
-
description: description,
|
|
43
40
|
main: main,
|
|
44
41
|
module: module,
|
|
45
42
|
types: types,
|
|
46
43
|
scripts: scripts,
|
|
47
|
-
keywords: keywords,
|
|
48
44
|
author: author,
|
|
49
45
|
license: license,
|
|
50
46
|
files: files,
|
|
@@ -212,7 +208,7 @@ const visibleRangeTexts = {
|
|
|
212
208
|
private: "\u79C1\u5BC6"
|
|
213
209
|
};
|
|
214
210
|
const xiaohongshuPublishAction = async (props) => {
|
|
215
|
-
const { page,
|
|
211
|
+
const { page, tmpCachePath, params } = props;
|
|
216
212
|
const selectAddress = async (selector, address) => {
|
|
217
213
|
const instance = typeof selector === "string" ? page.locator(selector) : selector;
|
|
218
214
|
await instance.click();
|
|
@@ -235,11 +231,13 @@ const xiaohongshuPublishAction = async (props) => {
|
|
|
235
231
|
await page.locator("#content-area .menu-container .publish-video a").click().catch(() => {
|
|
236
232
|
throw new Error("\u672A\u627E\u5230\u53D1\u5E03\u7B14\u8BB0\u6309\u94AE");
|
|
237
233
|
});
|
|
238
|
-
await page.locator(".creator-container .header .title").filter({ hasText: /^上传图文$/ }).click()
|
|
234
|
+
await page.locator(".creator-container .header .title").filter({ hasText: /^上传图文$/ }).click().catch(() => {
|
|
235
|
+
throw new Error("\u672A\u627E\u5230\u4E0A\u4F20\u56FE\u6587\u6309\u94AE");
|
|
236
|
+
});
|
|
239
237
|
const images = await Promise.all(
|
|
240
238
|
params.banners.map((url) => {
|
|
241
239
|
const fileName = getFilenameFromUrl(url);
|
|
242
|
-
return downloadImage(url, path.join(
|
|
240
|
+
return downloadImage(url, path.join(tmpCachePath, fileName));
|
|
243
241
|
})
|
|
244
242
|
);
|
|
245
243
|
const fileChooserPromise = page.waitForEvent("filechooser");
|
|
@@ -374,12 +372,11 @@ const _Logger = class _Logger {
|
|
|
374
372
|
log.warn(...msg);
|
|
375
373
|
}
|
|
376
374
|
error(prefix, error) {
|
|
377
|
-
|
|
375
|
+
log.error(prefix);
|
|
378
376
|
if (error instanceof Error) {
|
|
379
|
-
|
|
380
|
-
Error stack: ${error.stack}
|
|
377
|
+
log.error(`${error.message}
|
|
378
|
+
Error stack: ${error.stack}`);
|
|
381
379
|
}
|
|
382
|
-
log.error(prefix, errorMessage);
|
|
383
380
|
}
|
|
384
381
|
close() {
|
|
385
382
|
this.stream.end();
|
|
@@ -404,7 +401,7 @@ const generateFile = async (dir) => {
|
|
|
404
401
|
}
|
|
405
402
|
return filePath;
|
|
406
403
|
};
|
|
407
|
-
const createElectronApp = async (cachePath,
|
|
404
|
+
const createElectronApp = async (cachePath, playwright) => {
|
|
408
405
|
const logger = Logger.getInstance(cachePath);
|
|
409
406
|
try {
|
|
410
407
|
const executablePath = path.join(
|
|
@@ -413,7 +410,6 @@ const createElectronApp = async (cachePath, playwrightPackage) => {
|
|
|
413
410
|
".bin",
|
|
414
411
|
"electron"
|
|
415
412
|
);
|
|
416
|
-
const playwright = await playwrightPackage;
|
|
417
413
|
const mainPath = await generateFile(cachePath);
|
|
418
414
|
const electronApp = await playwright._electron.launch({
|
|
419
415
|
executablePath,
|
|
@@ -425,6 +421,7 @@ const createElectronApp = async (cachePath, playwrightPackage) => {
|
|
|
425
421
|
return electronApp;
|
|
426
422
|
} catch (error) {
|
|
427
423
|
logger.error("electron \u542F\u52A8\u5931\u8D25\uFF1A", error);
|
|
424
|
+
throw error;
|
|
428
425
|
}
|
|
429
426
|
};
|
|
430
427
|
|
|
@@ -434,6 +431,7 @@ var __publicField$1 = (obj, key, value) => {
|
|
|
434
431
|
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
435
432
|
return value;
|
|
436
433
|
};
|
|
434
|
+
const NPM_REGISTRY = "https://registry.npmmirror.com/";
|
|
437
435
|
class PackageManager {
|
|
438
436
|
constructor(params) {
|
|
439
437
|
__publicField$1(this, "cacheDir");
|
|
@@ -448,37 +446,6 @@ class PackageManager {
|
|
|
448
446
|
this.initCacheProject();
|
|
449
447
|
this.initPromise = this.init(params.packageName, params.packageVersion);
|
|
450
448
|
}
|
|
451
|
-
// 在子线程执行 npm 命令
|
|
452
|
-
execCommand(cmd, modules, where = this.cacheDir) {
|
|
453
|
-
return new Promise((resolve) => {
|
|
454
|
-
const args = [cmd].concat(modules).concat("--color=always").concat("--save");
|
|
455
|
-
try {
|
|
456
|
-
const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
457
|
-
const npm = spawn(npmCmd, args, { cwd: where });
|
|
458
|
-
let output = "";
|
|
459
|
-
npm.stdout?.on("data", (data) => {
|
|
460
|
-
output += data;
|
|
461
|
-
}).pipe(process.stdout);
|
|
462
|
-
npm.stderr?.on("data", (data) => {
|
|
463
|
-
output += data;
|
|
464
|
-
}).pipe(process.stderr);
|
|
465
|
-
npm.on("close", (code) => {
|
|
466
|
-
if (!code) {
|
|
467
|
-
resolve({ code: 0, data: output });
|
|
468
|
-
} else {
|
|
469
|
-
resolve({ code, data: output });
|
|
470
|
-
}
|
|
471
|
-
});
|
|
472
|
-
npm.on("error", (err) => {
|
|
473
|
-
console.error("NPM is not installed");
|
|
474
|
-
console.error(err);
|
|
475
|
-
});
|
|
476
|
-
} catch (error) {
|
|
477
|
-
this.logger.error(`npm ${args.join(" ")}: `, error);
|
|
478
|
-
console.error(error);
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
449
|
// 构建 package.json 文件,有了该文件后,依赖可以安装在该目录下,避免污染全局环境
|
|
483
450
|
initCacheProject() {
|
|
484
451
|
const packagePath = path.join(this.cacheDir, "package.json");
|
|
@@ -518,27 +485,30 @@ class PackageManager {
|
|
|
518
485
|
}
|
|
519
486
|
// 安装依赖
|
|
520
487
|
install(module, version) {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
return this.execCommand("update", [module]);
|
|
488
|
+
return npminstall({
|
|
489
|
+
root: this.cacheDir,
|
|
490
|
+
pkgs: [{ name: module, version }],
|
|
491
|
+
registry: NPM_REGISTRY
|
|
492
|
+
});
|
|
527
493
|
}
|
|
528
494
|
async init(name, version) {
|
|
529
495
|
const plugin = this.getPlugin(path.join(name, "package.json"));
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
496
|
+
try {
|
|
497
|
+
if (!plugin) {
|
|
498
|
+
await this.install(name, version);
|
|
499
|
+
} else if (this.forceUpdate) {
|
|
500
|
+
const pkInfo = await this.getPluginInfo(name);
|
|
501
|
+
if (!pkInfo)
|
|
502
|
+
return;
|
|
503
|
+
const hasNewVersion = semver.gt(pkInfo.version, plugin.version);
|
|
504
|
+
if (hasNewVersion) {
|
|
505
|
+
await this.install(name, pkInfo.version);
|
|
506
|
+
}
|
|
539
507
|
}
|
|
508
|
+
this.logger.info(`${name} package manager init done!`);
|
|
509
|
+
} catch (error) {
|
|
510
|
+
this.logger.error(`${name} package manager init error`, error);
|
|
540
511
|
}
|
|
541
|
-
this.logger.info(`${name} package manager init done!`);
|
|
542
512
|
}
|
|
543
513
|
}
|
|
544
514
|
|
|
@@ -549,17 +519,20 @@ var __publicField = (obj, key, value) => {
|
|
|
549
519
|
return value;
|
|
550
520
|
};
|
|
551
521
|
const PLAYWRIGHT_VERSION = "1.46.1";
|
|
522
|
+
const ELECTRON_VERSION = "22.3.27";
|
|
552
523
|
class LocalAutomateTask {
|
|
553
524
|
constructor({ cachePath, debug }) {
|
|
525
|
+
__publicField(this, "logger");
|
|
554
526
|
__publicField(this, "cachePath");
|
|
555
527
|
__publicField(this, "debug");
|
|
556
528
|
__publicField(this, "playwrightPackage");
|
|
557
|
-
__publicField(this, "
|
|
529
|
+
__publicField(this, "electronPackage");
|
|
558
530
|
__publicField(this, "_electronApp", null);
|
|
559
531
|
this.cachePath = cachePath;
|
|
560
532
|
this.debug = debug || false;
|
|
561
533
|
this.logger = Logger.getInstance(cachePath);
|
|
562
534
|
this.playwrightPackage = this.installPlaywright();
|
|
535
|
+
this.electronPackage = this.installElectron();
|
|
563
536
|
}
|
|
564
537
|
/**
|
|
565
538
|
* 安装 playwright
|
|
@@ -573,25 +546,59 @@ class LocalAutomateTask {
|
|
|
573
546
|
});
|
|
574
547
|
return playwrightPackageManager.getPluginAfterInit("playwright");
|
|
575
548
|
}
|
|
549
|
+
/**
|
|
550
|
+
* 安装 electron
|
|
551
|
+
* @returns
|
|
552
|
+
*/
|
|
553
|
+
installElectron() {
|
|
554
|
+
const playwrightPackageManager = new PackageManager({
|
|
555
|
+
packageName: "electron",
|
|
556
|
+
packageVersion: ELECTRON_VERSION,
|
|
557
|
+
cacheDir: this.cachePath
|
|
558
|
+
});
|
|
559
|
+
return playwrightPackageManager.getPluginAfterInit("electron");
|
|
560
|
+
}
|
|
576
561
|
/**
|
|
577
562
|
* 启动 Electron
|
|
578
563
|
* @returns
|
|
579
564
|
*/
|
|
580
565
|
async getElectronApp() {
|
|
581
566
|
if (!this._electronApp) {
|
|
582
|
-
|
|
583
|
-
this.
|
|
584
|
-
this.
|
|
585
|
-
);
|
|
567
|
+
const [playwright] = await Promise.all([
|
|
568
|
+
this.playwrightPackage,
|
|
569
|
+
this.electronPackage
|
|
570
|
+
]);
|
|
571
|
+
this._electronApp = await createElectronApp(this.cachePath, playwright);
|
|
586
572
|
}
|
|
587
573
|
return this._electronApp;
|
|
588
574
|
}
|
|
575
|
+
/**
|
|
576
|
+
* 临时文件目录
|
|
577
|
+
* @returns
|
|
578
|
+
*/
|
|
579
|
+
getTmpPath() {
|
|
580
|
+
return path.join(this.cachePath, "tmp");
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* 清空临时文件
|
|
584
|
+
*/
|
|
585
|
+
clearTmpPath() {
|
|
586
|
+
const tmpPath = this.getTmpPath();
|
|
587
|
+
return fs.rm(tmpPath, { recursive: true, force: true }, (err) => {
|
|
588
|
+
if (err) {
|
|
589
|
+
this.logger.error("\u5220\u9664\u4E34\u65F6\u6587\u4EF6\u5931\u8D25\uFF0C", err);
|
|
590
|
+
} else {
|
|
591
|
+
this.logger.info("\u5220\u9664\u4E34\u65F6\u6587\u4EF6\u6210\u529F");
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
}
|
|
589
595
|
/**
|
|
590
596
|
* 关闭 playwright 启动的 electron 客户端
|
|
591
597
|
* @returns
|
|
592
598
|
*/
|
|
593
599
|
async close() {
|
|
594
600
|
this.logger.close();
|
|
601
|
+
this.clearTmpPath();
|
|
595
602
|
const electronApp = await this.getElectronApp();
|
|
596
603
|
return electronApp.close();
|
|
597
604
|
}
|
|
@@ -643,13 +650,13 @@ class LocalAutomateTask {
|
|
|
643
650
|
const res = await xiaohongshuPublishAction({
|
|
644
651
|
page,
|
|
645
652
|
params,
|
|
646
|
-
|
|
653
|
+
tmpCachePath: this.getTmpPath(),
|
|
647
654
|
debug: !!this.debug
|
|
648
655
|
});
|
|
649
656
|
return res;
|
|
650
657
|
} catch (error) {
|
|
651
658
|
this.logger.error("\u5C0F\u7EA2\u4E66\u53D1\u5E03\u5931\u8D25", error);
|
|
652
|
-
|
|
659
|
+
throw error;
|
|
653
660
|
}
|
|
654
661
|
}
|
|
655
662
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iflyrpa/playwright",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
5
|
-
"description": "",
|
|
4
|
+
"version": "1.0.11",
|
|
6
5
|
"main": "./dist/index.cjs",
|
|
7
6
|
"module": "./dist/index.mjs",
|
|
8
7
|
"types": "./dist/index.d.ts",
|
|
@@ -11,12 +10,12 @@
|
|
|
11
10
|
"dev": "unbuild --stub",
|
|
12
11
|
"start": "esno src/index.ts"
|
|
13
12
|
},
|
|
14
|
-
"keywords": [],
|
|
15
13
|
"author": "bijinfeng",
|
|
16
14
|
"license": "ISC",
|
|
17
15
|
"files": ["dist"],
|
|
18
16
|
"dependencies": {
|
|
19
17
|
"loglevel": "^1.9.2",
|
|
18
|
+
"npminstall": "^7.12.0",
|
|
20
19
|
"playwright": "^1.46.1"
|
|
21
20
|
},
|
|
22
21
|
"peerDependencies": {
|