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