@iflyrpa/playwright 1.0.15-beta.0 → 1.0.15-beta.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/dist/index.mjs CHANGED
@@ -1,16 +1,18 @@
1
+ import { actions } from '@iflyrpa/actions';
1
2
  import fs from 'node:fs';
2
3
  import path from 'node:path';
3
- import https from 'node:https';
4
4
  import childProcess from 'node:child_process';
5
5
  import os from 'node:os';
6
6
  import { downloadArtifact } from '@electron/get';
7
7
  import extract from 'extract-zip';
8
+ import { pathExists, ensureFile, writeFile } from '@iflyrpa/share';
8
9
  import log from 'loglevel';
9
- import { PluginManager } from 'live-plugin-manager';
10
+ import { NodeClient } from '@sentry/node';
11
+ import pacote from 'pacote';
10
12
 
11
13
  const name = "@iflyrpa/playwright";
12
14
  const type = "module";
13
- const version$1 = "1.0.15-beta.0";
15
+ const version$1 = "1.0.15-beta.2";
14
16
  const main = "./dist/index.cjs";
15
17
  const module = "./dist/index.mjs";
16
18
  const types = "./dist/index.d.ts";
@@ -24,21 +26,26 @@ const license = "ISC";
24
26
  const files = [
25
27
  "dist"
26
28
  ];
27
- const dependencies = {
28
- "@electron/get": "^2.0.0",
29
- "extract-zip": "^2.0.1",
30
- "live-plugin-manager": "^1.0.0",
31
- loglevel: "^1.9.2"
32
- };
33
29
  const peerDependencies = {
34
30
  playwright: "^1.46.1"
35
31
  };
36
32
  const devDependencies = {
33
+ "@iflyrpa/share": "workspace:*",
34
+ "@types/pacote": "^11.1.8",
37
35
  esno: "^4.7.0",
38
36
  playwright: "^1.46.1",
39
37
  typescript: "^5.5.2",
40
38
  unbuild: "^2.0.0"
41
39
  };
40
+ const dependencies = {
41
+ "@iflyrpa/actions": "workspace:*",
42
+ "@iflyrpa/share": "workspace:*",
43
+ "@electron/get": "^2.0.0",
44
+ "@sentry/node": "^5.5.0",
45
+ "extract-zip": "^2.0.1",
46
+ loglevel: "^1.9.2",
47
+ pacote: "^20.0.0"
48
+ };
42
49
  const packageJson = {
43
50
  name: name,
44
51
  type: type,
@@ -50,307 +57,29 @@ const packageJson = {
50
57
  author: author,
51
58
  license: license,
52
59
  files: files,
53
- dependencies: dependencies,
54
60
  peerDependencies: peerDependencies,
55
- devDependencies: devDependencies
56
- };
57
-
58
- async function downloadImage(url, savePath) {
59
- await ensureFile(savePath);
60
- return new Promise((resolve, reject) => {
61
- https.get(url, (response) => {
62
- if (response.statusCode === 200) {
63
- const fileStream = fs.createWriteStream(savePath);
64
- response.pipe(fileStream);
65
- fileStream.on("finish", () => {
66
- fileStream.close();
67
- console.log("\u4E0B\u8F7D\u5B8C\u6210\uFF0C\u6587\u4EF6\u5DF2\u4FDD\u5B58\u81F3:", savePath);
68
- resolve(savePath);
69
- });
70
- } else {
71
- console.log("\u56FE\u7247\u4E0B\u8F7D\u5931\u8D25:", response.statusCode);
72
- response.resume();
73
- reject();
74
- }
75
- }).on("error", (error) => {
76
- console.error("\u8BF7\u6C42\u56FE\u7247\u65F6\u53D1\u751F\u9519\u8BEF:", error.message);
77
- reject();
78
- });
79
- });
80
- }
81
- function getFilenameFromUrl(imageUrl) {
82
- const parsedUrl = new URL(imageUrl);
83
- return path.basename(parsedUrl.pathname);
84
- }
85
- function pathExists(path2) {
86
- return new Promise((resolve) => {
87
- fs.stat(path2, (err) => {
88
- resolve(!err);
89
- });
90
- });
91
- }
92
- function ensureFile(filePath) {
93
- return new Promise((resolve, reject) => {
94
- const dirPath = path.dirname(filePath);
95
- fs.stat(dirPath, (err, stats) => {
96
- if (err) {
97
- if (err.code === "ENOENT") {
98
- fs.mkdir(dirPath, { recursive: true }, (err2) => {
99
- if (err2) {
100
- return reject(err2);
101
- }
102
- createFile();
103
- });
104
- } else {
105
- return reject(err);
106
- }
107
- } else if (stats.isDirectory()) {
108
- checkFile();
109
- } else {
110
- reject(new Error(`${dirPath} is not a directory`));
111
- }
112
- });
113
- function checkFile() {
114
- fs.stat(filePath, (err, stats) => {
115
- if (err) {
116
- if (err.code === "ENOENT") {
117
- createFile();
118
- } else {
119
- reject(err);
120
- }
121
- } else if (stats.isFile()) {
122
- resolve();
123
- } else {
124
- reject(new Error(`${filePath} is not a file`));
125
- }
126
- });
127
- }
128
- function createFile() {
129
- fs.writeFile(filePath, "", (err) => {
130
- if (err) {
131
- reject(err);
132
- } else {
133
- resolve();
134
- }
135
- });
136
- }
137
- });
138
- }
139
- function ensureFileSync(filePath) {
140
- const dirPath = path.dirname(filePath);
141
- try {
142
- if (!fs.existsSync(dirPath)) {
143
- fs.mkdirSync(dirPath, { recursive: true });
144
- }
145
- } catch (err) {
146
- if (err instanceof Error) {
147
- throw new Error(`Error creating directory: ${err.message}`);
148
- }
149
- }
150
- try {
151
- if (!fs.existsSync(filePath)) {
152
- fs.writeFileSync(filePath, "");
153
- }
154
- } catch (err) {
155
- if (err instanceof Error) {
156
- throw new Error(`Error creating file: ${err.message}`);
157
- }
158
- }
159
- }
160
- function writeFile(filePath, data) {
161
- return new Promise((resolve, reject) => {
162
- fs.writeFile(filePath, data, (err) => {
163
- if (err) {
164
- console.error("Error writing file:", err);
165
- reject();
166
- } else {
167
- console.log("File written successfully");
168
- resolve();
169
- }
170
- });
171
- });
172
- }
173
- function compareVersions(v1, v2) {
174
- const parts1 = v1.split(".").map(Number);
175
- const parts2 = v2.split(".").map(Number);
176
- for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
177
- const num1 = i < parts1.length ? parts1[i] : 0;
178
- const num2 = i < parts2.length ? parts2[i] : 0;
179
- if (num1 > num2)
180
- return 1;
181
- if (num1 < num2)
182
- return -1;
183
- }
184
- return 0;
185
- }
186
- const semver = {
187
- gt: (v1, v2) => compareVersions(v1, v2) === 1
61
+ devDependencies: devDependencies,
62
+ dependencies: dependencies
188
63
  };
189
- function fetchJSON(url) {
190
- return new Promise((resolve, reject) => {
191
- https.get(url, (res) => {
192
- let data = "";
193
- res.on("data", (chunk) => {
194
- data += chunk;
195
- });
196
- res.on("end", () => {
197
- try {
198
- const parsedData = JSON.parse(data);
199
- resolve(parsedData);
200
- } catch (e) {
201
- if (e instanceof Error) {
202
- reject(new Error(`Error parsing JSON: ${e.message}`));
203
- }
204
- }
205
- });
206
- }).on("error", (err) => {
207
- reject(new Error(`Request failed: ${err.message}`));
208
- });
209
- });
210
- }
211
- function isNil(value) {
212
- return value === null || value === void 0;
213
- }
214
64
 
215
- const visibleRangeTexts = {
216
- public: "\u516C\u5F00",
217
- private: "\u79C1\u5BC6"
218
- };
219
- const xiaohongshuPublishAction = async (props) => {
220
- const { page, tmpCachePath, params } = props;
221
- const selectAddress = async (selector, address) => {
222
- const instance = typeof selector === "string" ? page.locator(selector) : selector;
223
- await instance.click();
224
- await instance.locator("input").fill(address);
225
- const poperInstance = page.locator(
226
- '.d-popover:not([style*="display: none"]) .d-options .d-grid-item'
227
- );
228
- await poperInstance.first().waitFor();
229
- await poperInstance.first().click();
230
- };
231
- const selectDate = async (selector, date) => {
232
- const instance = typeof selector === "string" ? page.locator(selector) : selector;
233
- await instance.click();
234
- await instance.fill(date);
235
- await instance.blur();
236
- };
237
- await page.waitForSelector("#CreatorPlatform", { state: "visible" }).catch(() => {
238
- throw new Error("\u767B\u5F55\u5931\u8D25");
239
- });
240
- await page.locator("#content-area .menu-container .publish-video a").click().catch(() => {
241
- throw new Error("\u672A\u627E\u5230\u53D1\u5E03\u7B14\u8BB0\u6309\u94AE");
242
- });
243
- await page.locator(".creator-container .header .title").filter({ hasText: /^上传图文$/ }).click().catch(() => {
244
- throw new Error("\u672A\u627E\u5230\u4E0A\u4F20\u56FE\u6587\u6309\u94AE");
245
- });
246
- const images = await Promise.all(
247
- params.banners.map((url) => {
248
- const fileName = getFilenameFromUrl(url);
249
- return downloadImage(url, path.join(tmpCachePath, fileName));
250
- })
251
- );
252
- const fileChooserPromise = page.waitForEvent("filechooser");
253
- await page.getByRole("textbox").click();
254
- const fileChooser = await fileChooserPromise;
255
- await fileChooser.setFiles(images);
256
- const titleInstance = page.locator(".titleInput input");
257
- await titleInstance.click();
258
- await titleInstance.fill(params.title);
259
- const descInstance = page.locator("#post-textarea");
260
- await descInstance.click();
261
- await descInstance.fill(params.content);
262
- const container = page.locator(".creator-container .content .scroll-content");
263
- await container.focus();
264
- await page.mouse.wheel(0, 500);
265
- if (params.address) {
266
- await selectAddress(
267
- page.locator(".media-extension .address-input").filter({ hasText: "\u6DFB\u52A0\u5730\u70B9" }),
268
- params.address
269
- );
270
- }
271
- if (params.selfDeclaration) {
272
- await page.locator(".declaration-wrapper").click();
273
- const selfDeclarationInstance = page.locator(
274
- ".el-popper[aria-hidden=false] ul li[role=menuitem]"
275
- );
276
- if (params.selfDeclaration.type === "fictional-rendition") {
277
- await selfDeclarationInstance.filter({ hasText: "\u865A\u6784\u6F14\u7ECE\uFF0C\u4EC5\u4F9B\u5A31\u4E50" }).click();
278
- } else if (params.selfDeclaration.type === "ai-generated") {
279
- await selfDeclarationInstance.filter({ hasText: "\u7B14\u8BB0\u542BAI\u5408\u6210\u5185\u5BB9" }).click();
280
- } else if (params.selfDeclaration.type === "source-statement") {
281
- await selfDeclarationInstance.filter({ hasText: "\u5185\u5BB9\u6765\u6E90\u58F0\u660E" }).click();
282
- const selfDeclarationSecondaryMenuInstance = page.locator(".el-popper[aria-hidden=false] .el-cascader-menu").nth(1).locator("ul li[role=menuitem]");
283
- await selfDeclarationSecondaryMenuInstance.first().waitFor();
284
- if (params.selfDeclaration.childType === "self-labeling") {
285
- await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u5DF2\u81EA\u4E3B\u6807\u6CE8" }).click();
286
- } else if (params.selfDeclaration.childType === "self-shooting") {
287
- const { shootingDate, shootingLocation } = params.selfDeclaration;
288
- await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" }).click();
289
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" });
290
- await selfShootingPopup.waitFor();
291
- const hasCustomContent = shootingDate || shootingLocation;
292
- if (shootingLocation) {
293
- await selectAddress(
294
- selfShootingPopup.locator(".address-input"),
295
- shootingLocation
296
- );
297
- }
298
- if (shootingDate) {
299
- await selectDate(
300
- selfShootingPopup.locator(".date-picker input"),
301
- shootingDate
302
- );
303
- }
304
- await selfShootingPopup.locator("footer button").filter({ hasText: hasCustomContent ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
305
- } else if (params.selfDeclaration.childType === "transshipment") {
306
- await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u6765\u6E90\u8F6C\u8F7D" }).click();
307
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u6765\u6E90\u5A92\u4F53" });
308
- await selfShootingPopup.waitFor();
309
- const sourceMedia = params.selfDeclaration.sourceMedia;
310
- if (sourceMedia) {
311
- await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
312
- }
313
- await selfShootingPopup.locator("footer button").filter({ hasText: sourceMedia ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
314
- }
315
- }
316
- }
317
- const publicLabelInstance = page.locator("label").filter({ hasText: visibleRangeTexts[params.visibleRange] });
318
- await publicLabelInstance.click();
319
- const releaseTimeInstance = page.locator("label").filter({ hasText: params.isImmediatelyPublish ? "\u7ACB\u5373\u53D1\u5E03" : "\u5B9A\u65F6\u53D1\u5E03" });
320
- await releaseTimeInstance.click();
321
- if (params.scheduledPublish) {
322
- await selectDate(".date-picker input", params.scheduledPublish);
323
- }
324
- const response = await new Promise((resolve) => {
325
- const handleResponse = async (response2) => {
326
- if (response2.url().includes("/web_api/sns/v2/note")) {
327
- const jsonResponse = await response2.json();
328
- page.off("response", handleResponse);
329
- resolve(jsonResponse?.data?.id);
330
- }
331
- };
332
- page.on("response", handleResponse);
333
- page.locator(".submit .publishBtn").click();
334
- });
335
- await page.close();
336
- return response;
337
- };
338
-
339
- var __defProp$3 = Object.defineProperty;
340
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
341
- var __publicField$3 = (obj, key, value) => {
342
- __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
65
+ var __defProp$4 = Object.defineProperty;
66
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
67
+ var __publicField$4 = (obj, key, value) => {
68
+ __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
343
69
  return value;
344
70
  };
71
+ const ELECTRON_MIRROR = "http://npmmirror.com/mirrors/electron/";
72
+ const ELECTRON_VERSION = "22.3.27";
345
73
  class ElectronInstall {
346
- constructor(rootDir, version, logger) {
347
- this.rootDir = rootDir;
348
- this.version = version;
349
- this.logger = logger;
350
- __publicField$3(this, "electronPath");
351
- __publicField$3(this, "platformPath");
74
+ constructor(task) {
75
+ this.task = task;
76
+ __publicField$4(this, "rootDir");
77
+ __publicField$4(this, "electronPath");
78
+ __publicField$4(this, "platformPath");
79
+ __publicField$4(this, "version", ELECTRON_VERSION);
352
80
  this.platformPath = this.getPlatformPath();
353
- this.electronPath = path.join(rootDir, this.platformPath);
81
+ this.rootDir = path.join(task.packagesDir, `electron@${this.version}`);
82
+ this.electronPath = path.join(this.rootDir, this.platformPath);
354
83
  }
355
84
  isInstalled() {
356
85
  try {
@@ -383,7 +112,7 @@ class ElectronInstall {
383
112
  }
384
113
  async install() {
385
114
  const installed = this.isInstalled();
386
- this.logger.info(`electron@${this.version} \u662F\u5426\u5DF2\u5B89\u88C5\uFF1A${installed}`);
115
+ this.task.logger.info(`electron@${this.version} \u662F\u5426\u5DF2\u5B89\u88C5\uFF1A${installed}`);
387
116
  if (installed)
388
117
  return this.electronPath;
389
118
  const platform = process.env.npm_config_platform || process.platform;
@@ -400,28 +129,52 @@ class ElectronInstall {
400
129
  }
401
130
  }
402
131
  try {
403
- this.logger.info(`electron@${this.version} \u5F00\u59CB\u4E0B\u8F7D\u8D44\u6E90`);
132
+ this.task.logger.info(`electron@${this.version} \u5F00\u59CB\u4E0B\u8F7D\u8D44\u6E90`);
404
133
  const zipPath = await downloadArtifact({
405
134
  version: this.version,
406
135
  artifactName: "electron",
407
136
  force: process.env.force_no_cache === "true",
408
137
  cacheRoot: process.env.electron_config_cache,
409
138
  checksums: void 0,
139
+ mirrorOptions: { mirror: ELECTRON_MIRROR },
140
+ // 使用国内镜像下载
410
141
  platform,
411
142
  arch
412
143
  });
413
- this.logger.info(`electron@${this.version} \u5F00\u59CB\u89E3\u538B\u8D44\u6E90`);
144
+ this.task.logger.info(`electron@${this.version} \u5F00\u59CB\u89E3\u538B\u8D44\u6E90`);
414
145
  process.noAsar = true;
415
146
  await extract(zipPath, { dir: this.rootDir });
416
- this.logger.info(`electron@${this.version} \u4E0B\u8F7D\u6210\u529F`);
147
+ this.task.logger.info(`electron@${this.version} \u4E0B\u8F7D\u6210\u529F`);
417
148
  return this.electronPath;
418
149
  } catch (error) {
419
- this.logger.error(`electron@${this.version} \u4E0B\u8F7D\u5931\u8D25`, error);
150
+ this.task.logger.error(`electron@${this.version} \u4E0B\u8F7D\u5931\u8D25`, error);
420
151
  throw error;
421
152
  }
422
153
  }
423
154
  }
424
155
 
156
+ var __defProp$3 = Object.defineProperty;
157
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
158
+ var __publicField$3 = (obj, key, value) => {
159
+ __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
160
+ return value;
161
+ };
162
+ class SentryInstance {
163
+ constructor(dsn) {
164
+ __publicField$3(this, "sentry");
165
+ if (!dsn)
166
+ return;
167
+ this.sentry = new NodeClient({
168
+ dsn,
169
+ defaultIntegrations: false
170
+ });
171
+ }
172
+ captureException(error) {
173
+ this.sentry?.captureException(error);
174
+ }
175
+ }
176
+ const sentry = new SentryInstance(process.env.RPA_SENTRY_DSN);
177
+
425
178
  var __defProp$2 = Object.defineProperty;
426
179
  var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
427
180
  var __publicField$2 = (obj, key, value) => {
@@ -440,7 +193,7 @@ const _Logger = class _Logger {
440
193
  log.methodFactory = (methodName) => {
441
194
  return (message) => {
442
195
  this.stream.write(
443
- `[${( new Date()).toISOString()}] ${methodName.toUpperCase()}: ${message}
196
+ `[${( new Date()).toLocaleString()}] ${methodName.toUpperCase()}: ${message}
444
197
  `
445
198
  );
446
199
  };
@@ -466,12 +219,14 @@ const _Logger = class _Logger {
466
219
  warn(...msg) {
467
220
  log.warn(...msg);
468
221
  }
469
- error(prefix, error) {
470
- log.error(prefix);
471
- if (error instanceof Error) {
472
- log.error(`${error.message}
473
- Error stack: ${error.stack}`);
222
+ // error 级别的日志上报 sentry
223
+ error(prefix, err) {
224
+ const error = err || prefix;
225
+ if (err instanceof Error) {
226
+ err.message = `${prefix}\uFF1A${err.message}`;
474
227
  }
228
+ log.error(error);
229
+ sentry.captureException(error);
475
230
  }
476
231
  close() {
477
232
  this.stream.end();
@@ -488,7 +243,7 @@ app.whenReady().then(() => {});
488
243
  app.on("window-all-closed", (e) => e.preventDefault());
489
244
  `;
490
245
  const generateFile = async (dir) => {
491
- const filePath = path.join(dir, "src", "main.js");
246
+ const filePath = path.join(dir, "main.js");
492
247
  const isPathExists = await pathExists(filePath);
493
248
  if (!isPathExists) {
494
249
  await ensureFile(filePath);
@@ -514,121 +269,92 @@ const launchElectronApp = async (cachePath, playwright, electronPath) => {
514
269
  }
515
270
  };
516
271
 
517
- var __defProp$1 = Object.defineProperty;
518
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
519
- var __publicField$1 = (obj, key, value) => {
520
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
521
- return value;
522
- };
523
272
  const NPM_REGISTRY = "https://registry.npmmirror.com/";
524
- class PackageManager extends PluginManager {
525
- constructor(params) {
526
- super({
527
- cwd: params.cacheDir,
528
- pluginsPath: path.join(params.cacheDir, "node_modules"),
529
- npmRegistryUrl: NPM_REGISTRY
530
- });
531
- __publicField$1(this, "cacheDir");
532
- // 依赖安装目录
533
- __publicField$1(this, "forceUpdate");
534
- // 是否强制更新
535
- __publicField$1(this, "initPromise");
536
- __publicField$1(this, "logger");
537
- this.logger = Logger.getInstance(params.cacheDir);
538
- this.cacheDir = params.cacheDir;
539
- this.forceUpdate = isNil(params.forceUpdate) ? true : params.forceUpdate;
540
- this.initCacheProject();
541
- this.initPromise = this.init(params.packageName, params.packageVersion);
542
- }
543
- // 构建 package.json 文件,有了该文件后,依赖可以安装在该目录下,避免污染全局环境
544
- initCacheProject() {
545
- const packagePath = path.join(this.cacheDir, "package.json");
546
- if (!fs.existsSync(packagePath)) {
547
- this.logger.info("package.json \u4E0D\u5B58\u5728\uFF0C\u6DFB\u52A0\u8BE5\u6587\u4EF6");
548
- const pkg = {
549
- name: "rpa-plugins",
550
- description: "rpa-plugins",
551
- license: "MIT",
552
- main: "./src/main.js"
553
- };
554
- ensureFileSync(packagePath);
555
- fs.writeFileSync(packagePath, JSON.stringify(pkg), "utf8");
556
- }
273
+ class PackageManager {
274
+ constructor(task) {
275
+ this.task = task;
557
276
  }
558
277
  // 获取依赖信息
559
- async getPluginInfo(module) {
560
- const res = await fetchJSON(
561
- `https://registry.npmjs.com/-/v1/search?text=${module}`
562
- );
563
- const packages = res.objects;
564
- return packages.find((it) => it.package.name === module)?.package;
565
- }
566
- // 查询本地安装的依赖
567
- getPlugin(module) {
568
- const pluginDir = path.join(this.cacheDir, "node_modules");
278
+ async getManifest(module) {
569
279
  try {
570
- return require(path.join(pluginDir, module));
280
+ return pacote.manifest(module, { registry: NPM_REGISTRY });
571
281
  } catch (error) {
572
- return null;
282
+ this.task.logger.error("\u83B7\u53D6\u4F9D\u8D56\u4FE1\u606F\u5931\u8D25", error);
283
+ throw error;
573
284
  }
574
285
  }
575
- async getPluginAfterInit(module) {
576
- await this.initPromise;
577
- return this.getPlugin(module);
578
- }
579
286
  // 安装依赖
580
- async installPackage(name, version) {
287
+ async extract(name, version = "latest") {
288
+ const packageName = `${name}@${version}`;
581
289
  try {
582
- this.logger.info(`${name} \u5F00\u59CB\u5B89\u88C5`);
583
- await this.install(name, version);
584
- this.logger.info(`${name} \u5B89\u88C5\u6210\u529F`);
290
+ this.task.logger.info(`${packageName} \u5F00\u59CB\u5B89\u88C5`);
291
+ await pacote.extract(
292
+ packageName,
293
+ path.join(this.task.packagesDir, packageName),
294
+ { registry: NPM_REGISTRY }
295
+ );
296
+ this.task.logger.info(`${packageName} \u5B89\u88C5\u6210\u529F`);
585
297
  } catch (error) {
586
- this.logger.error(`${name} \u5B89\u88C5\u5931\u8D25`, error);
298
+ this.task.logger.error(`${packageName} \u5B89\u88C5\u5931\u8D25`, error);
587
299
  }
588
300
  }
589
- async init(name, version) {
590
- const plugin = this.getPlugin(path.join(name, "package.json"));
591
- this.logger.info(`${name} \u662F\u5426\u5DF2\u5B89\u88C5\uFF1A${!!plugin}`);
301
+ // 查询本地安装的依赖
302
+ require(module) {
592
303
  try {
593
- if (!plugin) {
594
- await this.installPackage(name, version);
595
- } else if (this.forceUpdate) {
596
- const pkInfo = await this.getPluginInfo(name);
597
- if (!pkInfo)
598
- return;
599
- const hasNewVersion = semver.gt(pkInfo.version, plugin.version);
600
- if (hasNewVersion) {
601
- this.logger.info(`${name} \u68C0\u67E5\u5230\u65B0\u7248\u672C ${pkInfo.version}`);
602
- await this.installPackage(name, pkInfo.version);
603
- }
604
- }
605
- this.logger.info(`${name} package manager init done!`);
304
+ return require(path.join(this.task.packagesDir, module));
606
305
  } catch (error) {
607
- this.logger.error(`${name} package manager init error`, error);
306
+ return null;
307
+ }
308
+ }
309
+ // 安装依赖
310
+ async install(name, version) {
311
+ const packageName = `${name}@${version}`;
312
+ const plugin = this.require(packageName);
313
+ this.task.logger.info(`${packageName} \u662F\u5426\u5DF2\u5B89\u88C5\uFF1A${!!plugin}`);
314
+ if (!plugin) {
315
+ await this.extract(name, version);
316
+ }
317
+ }
318
+ // 更新依赖
319
+ async update(name) {
320
+ const manifest = await this.getManifest(`${name}@latest`);
321
+ const version = manifest.version;
322
+ const plugin = this.require(`${name}@${version}`);
323
+ if (!plugin) {
324
+ await this.extract(name, version);
608
325
  }
326
+ return version;
609
327
  }
610
328
  }
611
329
 
612
- var __defProp = Object.defineProperty;
613
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
614
- var __publicField = (obj, key, value) => {
615
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
330
+ var __defProp$1 = Object.defineProperty;
331
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
332
+ var __publicField$1 = (obj, key, value) => {
333
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
616
334
  return value;
617
335
  };
618
336
  const PLAYWRIGHT_VERSION = "1.46.1";
619
337
  const PLAYWRIGHT_NAME = "playwright-core";
620
- const ELECTRON_VERSION = "22.3.27";
621
- class LocalAutomateTask {
338
+ class Task {
622
339
  constructor({ cachePath, debug }) {
623
- __publicField(this, "logger");
624
- __publicField(this, "cachePath");
625
- __publicField(this, "debug");
626
- __publicField(this, "playwrightPackage");
627
- __publicField(this, "electronPackage");
628
- __publicField(this, "_electronApp", null);
340
+ __publicField$1(this, "logger");
341
+ __publicField$1(this, "cachePath");
342
+ __publicField$1(this, "debug");
343
+ __publicField$1(this, "packagesDir");
344
+ // 依赖安装目录
345
+ __publicField$1(this, "packageManager");
346
+ __publicField$1(this, "playwrightPackage");
347
+ __publicField$1(this, "electronPackage");
348
+ __publicField$1(this, "_electronApp", null);
349
+ /**
350
+ * 应用是否已关闭
351
+ */
352
+ __publicField$1(this, "isClosed", false);
629
353
  this.cachePath = cachePath;
354
+ this.packagesDir = path.join(cachePath, "packages");
630
355
  this.debug = debug || false;
631
356
  this.logger = Logger.getInstance(cachePath);
357
+ this.packageManager = new PackageManager(this);
632
358
  this.playwrightPackage = this.installPlaywright();
633
359
  this.electronPackage = this.installElectron();
634
360
  }
@@ -636,26 +362,17 @@ class LocalAutomateTask {
636
362
  * 安装 playwright
637
363
  * @returns
638
364
  */
639
- installPlaywright() {
640
- const playwrightPackageManager = new PackageManager({
641
- packageName: PLAYWRIGHT_NAME,
642
- packageVersion: PLAYWRIGHT_VERSION,
643
- cacheDir: this.cachePath,
644
- forceUpdate: false
645
- });
646
- return playwrightPackageManager.getPluginAfterInit(PLAYWRIGHT_NAME);
365
+ async installPlaywright() {
366
+ const packageName = `${PLAYWRIGHT_NAME}@${PLAYWRIGHT_VERSION}`;
367
+ await this.packageManager.install(PLAYWRIGHT_NAME, PLAYWRIGHT_VERSION);
368
+ return this.packageManager.require(packageName);
647
369
  }
648
370
  /**
649
371
  * 安装 electron
650
372
  * @returns
651
373
  */
652
374
  installElectron() {
653
- const electronInstall = new ElectronInstall(
654
- path.join(this.cachePath, "electron"),
655
- ELECTRON_VERSION,
656
- this.logger
657
- );
658
- return electronInstall.install();
375
+ return new ElectronInstall(this).install();
659
376
  }
660
377
  /**
661
378
  * 启动 Electron
@@ -700,31 +417,15 @@ class LocalAutomateTask {
700
417
  * @returns
701
418
  */
702
419
  async close() {
703
- this.logger.close();
420
+ this.logger.info("\u5173\u95ED\u5E94\u7528");
704
421
  this.clearTmpPath();
705
- const electronApp = await this.launchApp();
706
- return electronApp.close();
422
+ this.logger.close();
423
+ await this._electronApp?.close();
424
+ this.isClosed = true;
425
+ this._electronApp = null;
707
426
  }
708
- /**
709
- * 小红书自动化发布
710
- */
711
- async xiaohongshuPublish(params) {
712
- this.logger.info("\u5F00\u59CB\u5C0F\u7EA2\u4E66\u53D1\u5E03");
427
+ async createPage(pageParams) {
713
428
  const electronApp = await this.launchApp();
714
- this.logger.info("\u5C0F\u7EA2\u4E66\u53D1\u5E03\u4E13\u7528\u5BA2\u6237\u7AEF\u5DF2\u542F\u52A8");
715
- const commonCookies = {
716
- path: "/",
717
- sameSite: "lax",
718
- secure: false,
719
- domain: "xiaohongshu.com",
720
- url: "https://creator.xiaohongshu.com",
721
- httpOnly: true
722
- };
723
- const pageParams = {
724
- show: this.debug,
725
- url: params.url || "https://creator.xiaohongshu.com/publish/publish",
726
- cookies: params.cookies?.map((it) => Object.assign(commonCookies, it)) || []
727
- };
728
429
  const [page] = await Promise.all([
729
430
  electronApp.waitForEvent("window"),
730
431
  electronApp.evaluate(
@@ -751,38 +452,36 @@ class LocalAutomateTask {
751
452
  { pageParams }
752
453
  )
753
454
  ]);
754
- this.logger.info("\u5DF2\u6253\u5F00\u5C0F\u7EA2\u4E66\u53D1\u5E03\u9875\u9762");
455
+ return page;
456
+ }
457
+ }
458
+
459
+ var __defProp = Object.defineProperty;
460
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
461
+ var __publicField = (obj, key, value) => {
462
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
463
+ return value;
464
+ };
465
+ class RpaTask extends Task {
466
+ constructor(params) {
467
+ super(params);
468
+ __publicField(this, "actions", actions);
469
+ params.forceUpdate && this.update();
470
+ }
471
+ async update() {
755
472
  try {
756
- const res = await xiaohongshuPublishAction({
757
- page,
758
- params,
759
- tmpCachePath: this.getTmpPath(),
760
- debug: !!this.debug
761
- });
762
- this.logger.info(`\u5C0F\u7EA2\u4E66\u53D1\u5E03\u6210\u529F\uFF1A${res}`);
763
- return res;
473
+ const name = "@iflyrpa/actions";
474
+ const version2 = await this.packageManager.update(name);
475
+ const actionPackage = this.packageManager.require(`${name}@${version2}`);
476
+ actionPackage?.actions && (this.actions = actionPackage.actions);
764
477
  } catch (error) {
765
- this.logger.error("\u5C0F\u7EA2\u4E66\u53D1\u5E03\u5931\u8D25", error);
766
- throw error;
478
+ this.logger.error("\u66F4\u65B0\u4F9D\u8D56\u5931\u8D25", error);
767
479
  }
768
480
  }
769
- }
770
- const RpaTask = (params) => {
771
- const logger = Logger.getInstance(params.cachePath);
772
- if (params.forceUpdate) {
773
- logger.info("\u5C1D\u8BD5\u4F7F\u7528\u8FDC\u7A0B\u6700\u65B0\u7248\u672C");
774
- const packageManager = new PackageManager({
775
- packageName: packageJson.name,
776
- cacheDir: params.cachePath
777
- });
778
- const localPackge = packageManager.getPlugin(packageJson.name);
779
- if (localPackge?.LocalAutomateTask && localPackge?.version && semver.gt(localPackge.version, packageJson.version)) {
780
- logger.info(`\u4F7F\u7528\u8FDC\u7A0B\u7684\u65B0\u7248\u672C\uFF0C\u7248\u672C\u53F7\u4E3A\uFF1A${localPackge.version}`);
781
- return new localPackge.LocalAutomateTask(params);
782
- }
481
+ xiaohongshuPublish(params) {
482
+ return this.actions.xiaohongshuPublish(this, params);
783
483
  }
784
- return new LocalAutomateTask(params);
785
- };
484
+ }
786
485
  const version = packageJson.version;
787
486
 
788
- export { LocalAutomateTask, RpaTask, version };
487
+ export { RpaTask, version };