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