@iflyrpa/playwright 1.0.15 → 1.1.1
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/README.md +77 -1
- package/dist/index.cjs +169 -472
- package/dist/index.d.cts +38 -89
- package/dist/index.d.mts +38 -89
- package/dist/index.d.ts +38 -89
- package/dist/index.mjs +166 -468
- package/package.json +37 -30
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
|
|
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.
|
|
27
|
+
const version$1 = "1.1.1";
|
|
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
|
|
200
|
-
};
|
|
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
|
-
|
|
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;
|
|
73
|
+
devDependencies: devDependencies,
|
|
74
|
+
dependencies: dependencies
|
|
349
75
|
};
|
|
350
76
|
|
|
351
|
-
var __defProp$
|
|
352
|
-
var __defNormalProp$
|
|
353
|
-
var __publicField$
|
|
354
|
-
__defNormalProp$
|
|
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(
|
|
359
|
-
this.
|
|
360
|
-
this
|
|
361
|
-
this
|
|
362
|
-
__publicField$
|
|
363
|
-
__publicField$
|
|
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.
|
|
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) => {
|
|
@@ -447,12 +200,13 @@ const _Logger = class _Logger {
|
|
|
447
200
|
return _Logger.instance;
|
|
448
201
|
}
|
|
449
202
|
const logFile = path__default.join(cachePath, "rpa.log");
|
|
203
|
+
share.ensureFileSync(logFile);
|
|
450
204
|
this.stream = fs__default.createWriteStream(logFile, { flags: "a" });
|
|
451
205
|
log__default.setLevel("debug");
|
|
452
206
|
log__default.methodFactory = (methodName) => {
|
|
453
207
|
return (message) => {
|
|
454
208
|
this.stream.write(
|
|
455
|
-
`[${( new Date()).
|
|
209
|
+
`[${( new Date()).toLocaleString()}] ${methodName.toUpperCase()}: ${message}
|
|
456
210
|
`
|
|
457
211
|
);
|
|
458
212
|
};
|
|
@@ -478,12 +232,14 @@ const _Logger = class _Logger {
|
|
|
478
232
|
warn(...msg) {
|
|
479
233
|
log__default.warn(...msg);
|
|
480
234
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
235
|
+
// error 级别的日志上报 sentry
|
|
236
|
+
error(prefix, err) {
|
|
237
|
+
const error = err || prefix;
|
|
238
|
+
if (err instanceof Error) {
|
|
239
|
+
err.message = `${prefix}\uFF1A${err.message}`;
|
|
486
240
|
}
|
|
241
|
+
log__default.error(error);
|
|
242
|
+
sentry.captureException(error);
|
|
487
243
|
}
|
|
488
244
|
close() {
|
|
489
245
|
this.stream.end();
|
|
@@ -500,11 +256,11 @@ app.whenReady().then(() => {});
|
|
|
500
256
|
app.on("window-all-closed", (e) => e.preventDefault());
|
|
501
257
|
`;
|
|
502
258
|
const generateFile = async (dir) => {
|
|
503
|
-
const filePath = path__default.join(dir, "
|
|
504
|
-
const isPathExists = await pathExists(filePath);
|
|
259
|
+
const filePath = path__default.join(dir, "main.js");
|
|
260
|
+
const isPathExists = await share.pathExists(filePath);
|
|
505
261
|
if (!isPathExists) {
|
|
506
|
-
await ensureFile(filePath);
|
|
507
|
-
await writeFile(filePath, template);
|
|
262
|
+
await share.ensureFile(filePath);
|
|
263
|
+
await share.writeFile(filePath, template);
|
|
508
264
|
}
|
|
509
265
|
return filePath;
|
|
510
266
|
};
|
|
@@ -526,121 +282,92 @@ const launchElectronApp = async (cachePath, playwright, electronPath) => {
|
|
|
526
282
|
}
|
|
527
283
|
};
|
|
528
284
|
|
|
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
285
|
const NPM_REGISTRY = "https://registry.npmmirror.com/";
|
|
536
|
-
class PackageManager
|
|
537
|
-
constructor(
|
|
538
|
-
|
|
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
|
-
}
|
|
286
|
+
class PackageManager {
|
|
287
|
+
constructor(task) {
|
|
288
|
+
this.task = task;
|
|
569
289
|
}
|
|
570
290
|
// 获取依赖信息
|
|
571
|
-
async
|
|
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");
|
|
291
|
+
async getManifest(module) {
|
|
581
292
|
try {
|
|
582
|
-
return
|
|
293
|
+
return pacote__default.manifest(module, { registry: NPM_REGISTRY });
|
|
583
294
|
} catch (error) {
|
|
584
|
-
|
|
295
|
+
this.task.logger.error("\u83B7\u53D6\u4F9D\u8D56\u4FE1\u606F\u5931\u8D25", error);
|
|
296
|
+
throw error;
|
|
585
297
|
}
|
|
586
298
|
}
|
|
587
|
-
async getPluginAfterInit(module) {
|
|
588
|
-
await this.initPromise;
|
|
589
|
-
return this.getPlugin(module);
|
|
590
|
-
}
|
|
591
299
|
// 安装依赖
|
|
592
|
-
async
|
|
300
|
+
async extract(name, version = "latest") {
|
|
301
|
+
const packageName = `${name}@${version}`;
|
|
593
302
|
try {
|
|
594
|
-
this.logger.info(`${
|
|
595
|
-
await
|
|
596
|
-
|
|
303
|
+
this.task.logger.info(`${packageName} \u5F00\u59CB\u5B89\u88C5`);
|
|
304
|
+
await pacote__default.extract(
|
|
305
|
+
packageName,
|
|
306
|
+
path__default.join(this.task.packagesDir, packageName),
|
|
307
|
+
{ registry: NPM_REGISTRY }
|
|
308
|
+
);
|
|
309
|
+
this.task.logger.info(`${packageName} \u5B89\u88C5\u6210\u529F`);
|
|
597
310
|
} catch (error) {
|
|
598
|
-
this.logger.error(`${
|
|
311
|
+
this.task.logger.error(`${packageName} \u5B89\u88C5\u5931\u8D25`, error);
|
|
599
312
|
}
|
|
600
313
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
this.logger.info(`${name} \u662F\u5426\u5DF2\u5B89\u88C5\uFF1A${!!plugin}`);
|
|
314
|
+
// 查询本地安装的依赖
|
|
315
|
+
require(module) {
|
|
604
316
|
try {
|
|
605
|
-
|
|
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!`);
|
|
317
|
+
return require(path__default.join(this.task.packagesDir, module));
|
|
618
318
|
} catch (error) {
|
|
619
|
-
|
|
319
|
+
return null;
|
|
620
320
|
}
|
|
621
321
|
}
|
|
322
|
+
// 安装依赖
|
|
323
|
+
async install(name, version) {
|
|
324
|
+
const packageName = `${name}@${version}`;
|
|
325
|
+
const plugin = this.require(packageName);
|
|
326
|
+
this.task.logger.info(`${packageName} \u662F\u5426\u5DF2\u5B89\u88C5\uFF1A${!!plugin}`);
|
|
327
|
+
if (!plugin) {
|
|
328
|
+
await this.extract(name, version);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
// 更新依赖
|
|
332
|
+
async update(name) {
|
|
333
|
+
const manifest = await this.getManifest(`${name}@latest`);
|
|
334
|
+
const version = manifest.version;
|
|
335
|
+
const plugin = this.require(`${name}@${version}`);
|
|
336
|
+
if (!plugin) {
|
|
337
|
+
await this.extract(name, version);
|
|
338
|
+
}
|
|
339
|
+
return version;
|
|
340
|
+
}
|
|
622
341
|
}
|
|
623
342
|
|
|
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);
|
|
343
|
+
var __defProp$1 = Object.defineProperty;
|
|
344
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
345
|
+
var __publicField$1 = (obj, key, value) => {
|
|
346
|
+
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
628
347
|
return value;
|
|
629
348
|
};
|
|
630
349
|
const PLAYWRIGHT_VERSION = "1.46.1";
|
|
631
350
|
const PLAYWRIGHT_NAME = "playwright-core";
|
|
632
|
-
|
|
633
|
-
class LocalAutomateTask {
|
|
351
|
+
class Task {
|
|
634
352
|
constructor({ cachePath, debug }) {
|
|
635
|
-
__publicField(this, "logger");
|
|
636
|
-
__publicField(this, "cachePath");
|
|
637
|
-
__publicField(this, "debug");
|
|
638
|
-
__publicField(this, "
|
|
639
|
-
|
|
640
|
-
__publicField(this, "
|
|
353
|
+
__publicField$1(this, "logger");
|
|
354
|
+
__publicField$1(this, "cachePath");
|
|
355
|
+
__publicField$1(this, "debug");
|
|
356
|
+
__publicField$1(this, "packagesDir");
|
|
357
|
+
// 依赖安装目录
|
|
358
|
+
__publicField$1(this, "packageManager");
|
|
359
|
+
__publicField$1(this, "playwrightPackage");
|
|
360
|
+
__publicField$1(this, "electronPackage");
|
|
361
|
+
__publicField$1(this, "_electronApp", null);
|
|
362
|
+
/**
|
|
363
|
+
* 应用是否已关闭
|
|
364
|
+
*/
|
|
365
|
+
__publicField$1(this, "isClosed", false);
|
|
641
366
|
this.cachePath = cachePath;
|
|
367
|
+
this.packagesDir = path__default.join(cachePath, "packages");
|
|
642
368
|
this.debug = debug || false;
|
|
643
369
|
this.logger = Logger.getInstance(cachePath);
|
|
370
|
+
this.packageManager = new PackageManager(this);
|
|
644
371
|
this.playwrightPackage = this.installPlaywright();
|
|
645
372
|
this.electronPackage = this.installElectron();
|
|
646
373
|
}
|
|
@@ -648,26 +375,17 @@ class LocalAutomateTask {
|
|
|
648
375
|
* 安装 playwright
|
|
649
376
|
* @returns
|
|
650
377
|
*/
|
|
651
|
-
installPlaywright() {
|
|
652
|
-
const
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
cacheDir: this.cachePath,
|
|
656
|
-
forceUpdate: false
|
|
657
|
-
});
|
|
658
|
-
return playwrightPackageManager.getPluginAfterInit(PLAYWRIGHT_NAME);
|
|
378
|
+
async installPlaywright() {
|
|
379
|
+
const packageName = `${PLAYWRIGHT_NAME}@${PLAYWRIGHT_VERSION}`;
|
|
380
|
+
await this.packageManager.install(PLAYWRIGHT_NAME, PLAYWRIGHT_VERSION);
|
|
381
|
+
return this.packageManager.require(packageName);
|
|
659
382
|
}
|
|
660
383
|
/**
|
|
661
384
|
* 安装 electron
|
|
662
385
|
* @returns
|
|
663
386
|
*/
|
|
664
387
|
installElectron() {
|
|
665
|
-
|
|
666
|
-
path__default.join(this.cachePath, "electron"),
|
|
667
|
-
ELECTRON_VERSION,
|
|
668
|
-
this.logger
|
|
669
|
-
);
|
|
670
|
-
return electronInstall.install();
|
|
388
|
+
return new ElectronInstall(this).install();
|
|
671
389
|
}
|
|
672
390
|
/**
|
|
673
391
|
* 启动 Electron
|
|
@@ -712,31 +430,15 @@ class LocalAutomateTask {
|
|
|
712
430
|
* @returns
|
|
713
431
|
*/
|
|
714
432
|
async close() {
|
|
715
|
-
this.logger.
|
|
433
|
+
this.logger.info("\u5173\u95ED\u5E94\u7528");
|
|
716
434
|
this.clearTmpPath();
|
|
717
|
-
|
|
718
|
-
|
|
435
|
+
this.logger.close();
|
|
436
|
+
await this._electronApp?.close();
|
|
437
|
+
this.isClosed = true;
|
|
438
|
+
this._electronApp = null;
|
|
719
439
|
}
|
|
720
|
-
|
|
721
|
-
* 小红书自动化发布
|
|
722
|
-
*/
|
|
723
|
-
async xiaohongshuPublish(params) {
|
|
724
|
-
this.logger.info("\u5F00\u59CB\u5C0F\u7EA2\u4E66\u53D1\u5E03");
|
|
440
|
+
async createPage(pageParams) {
|
|
725
441
|
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
442
|
const [page] = await Promise.all([
|
|
741
443
|
electronApp.waitForEvent("window"),
|
|
742
444
|
electronApp.evaluate(
|
|
@@ -763,40 +465,35 @@ class LocalAutomateTask {
|
|
|
763
465
|
{ pageParams }
|
|
764
466
|
)
|
|
765
467
|
]);
|
|
766
|
-
|
|
468
|
+
return page;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
var __defProp = Object.defineProperty;
|
|
473
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
474
|
+
var __publicField = (obj, key, value) => {
|
|
475
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
476
|
+
return value;
|
|
477
|
+
};
|
|
478
|
+
class RpaTask extends Task {
|
|
479
|
+
constructor(params) {
|
|
480
|
+
super(params);
|
|
481
|
+
__publicField(this, "actions");
|
|
482
|
+
this.actions = new actions.Action(this);
|
|
483
|
+
params.forceUpdate && this.update();
|
|
484
|
+
}
|
|
485
|
+
async update() {
|
|
767
486
|
try {
|
|
768
|
-
const
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
debug: !!this.debug
|
|
773
|
-
});
|
|
774
|
-
this.logger.info(`\u5C0F\u7EA2\u4E66\u53D1\u5E03\u6210\u529F\uFF1A${res}`);
|
|
775
|
-
return res;
|
|
487
|
+
const name = "@iflyrpa/actions";
|
|
488
|
+
const version2 = await this.packageManager.update(name);
|
|
489
|
+
const actionPackage = this.packageManager.require(`${name}@${version2}`);
|
|
490
|
+
actionPackage?.actions && (this.actions = actionPackage.actions);
|
|
776
491
|
} catch (error) {
|
|
777
|
-
this.logger.error("\
|
|
778
|
-
throw error;
|
|
492
|
+
this.logger.error("\u66F4\u65B0\u4F9D\u8D56\u5931\u8D25", error);
|
|
779
493
|
}
|
|
780
494
|
}
|
|
781
495
|
}
|
|
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
|
-
}
|
|
795
|
-
}
|
|
796
|
-
return new LocalAutomateTask(params);
|
|
797
|
-
};
|
|
798
496
|
const version = packageJson.version;
|
|
799
497
|
|
|
800
|
-
exports.LocalAutomateTask = LocalAutomateTask;
|
|
801
498
|
exports.RpaTask = RpaTask;
|
|
802
499
|
exports.version = version;
|