@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 +170 -472
- package/dist/index.d.cts +39 -89
- package/dist/index.d.mts +39 -89
- package/dist/index.d.ts +39 -89
- package/dist/index.mjs +167 -468
- package/package.json +37 -30
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 {
|
|
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.
|
|
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
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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(
|
|
347
|
-
this.
|
|
348
|
-
this
|
|
349
|
-
this
|
|
350
|
-
__publicField$
|
|
351
|
-
__publicField$
|
|
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.
|
|
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()).
|
|
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
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
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, "
|
|
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
|
|
525
|
-
constructor(
|
|
526
|
-
|
|
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
|
|
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
|
|
280
|
+
return pacote.manifest(module, { registry: NPM_REGISTRY });
|
|
571
281
|
} catch (error) {
|
|
572
|
-
|
|
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
|
|
287
|
+
async extract(name, version = "latest") {
|
|
288
|
+
const packageName = `${name}@${version}`;
|
|
581
289
|
try {
|
|
582
|
-
this.logger.info(`${
|
|
583
|
-
await
|
|
584
|
-
|
|
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(`${
|
|
298
|
+
this.task.logger.error(`${packageName} \u5B89\u88C5\u5931\u8D25`, error);
|
|
587
299
|
}
|
|
588
300
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
this.logger.info(`${name} \u662F\u5426\u5DF2\u5B89\u88C5\uFF1A${!!plugin}`);
|
|
301
|
+
// 查询本地安装的依赖
|
|
302
|
+
require(module) {
|
|
592
303
|
try {
|
|
593
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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, "
|
|
627
|
-
|
|
628
|
-
__publicField(this, "
|
|
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
|
|
641
|
-
|
|
642
|
-
|
|
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
|
-
|
|
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.
|
|
420
|
+
this.logger.info("\u5173\u95ED\u5E94\u7528");
|
|
704
421
|
this.clearTmpPath();
|
|
705
|
-
|
|
706
|
-
|
|
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
|
-
|
|
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
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
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("\
|
|
766
|
-
throw error;
|
|
478
|
+
this.logger.error("\u66F4\u65B0\u4F9D\u8D56\u5931\u8D25", error);
|
|
767
479
|
}
|
|
768
480
|
}
|
|
769
|
-
|
|
770
|
-
|
|
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
|
-
|
|
785
|
-
};
|
|
484
|
+
}
|
|
786
485
|
const version = packageJson.version;
|
|
787
486
|
|
|
788
|
-
export {
|
|
487
|
+
export { RpaTask, version };
|