fca-mod 1.3.4
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.
Potentially problematic release.
This version of fca-mod might be problematic. Click here for more details.
- package/.cache/replit/__replit_disk_meta.json +1 -0
- package/.cache/replit/nix/env.json +1 -0
- package/.config/configstore/update-notifier-npm.json +4 -0
- package/.config/configstore/update-notifier-npm.json.1735545094 +4 -0
- package/.gitattributes +2 -0
- package/.replit +89 -0
- package/.upm/store.json +1 -0
- package/Extra/Database/index.js +470 -0
- package/Extra/ExtraAddons.js +80 -0
- package/Extra/ExtraFindUID.js +62 -0
- package/Extra/ExtraGetThread.js +118 -0
- package/Extra/ExtraScreenShot.js +430 -0
- package/Extra/ExtraUptimeRobot.js +38 -0
- package/Extra/Html/Classic/script.js +119 -0
- package/Extra/Html/Classic/style.css +8 -0
- package/Extra/Security/Index.js +146 -0
- package/Extra/Security/Step_1.js +6 -0
- package/Extra/Security/Step_2.js +22 -0
- package/Extra/Security/Step_3.js +22 -0
- package/Extra/Src/Change_Environment.js +24 -0
- package/Extra/Src/Check_Update.js +66 -0
- package/Extra/Src/History.js +115 -0
- package/Extra/Src/Instant_Update.js +65 -0
- package/Extra/Src/Last-Run.js +65 -0
- package/Extra/Src/Premium.js +83 -0
- package/Extra/Src/Release_Memory.js +41 -0
- package/Extra/Src/uuid.js +137 -0
- package/FastConfigFca.json +23 -0
- package/Func/AcceptAgreement.js +32 -0
- package/Func/ClearCache.js +64 -0
- package/Func/ReportV1.js +54 -0
- package/LICENSE +24 -0
- package/Language/index.json +206 -0
- package/Main.js +1098 -0
- package/README.md +136 -0
- package/SECURITY.md +14 -0
- package/broadcast.js +40 -0
- package/index.js +313 -0
- package/logger.js +66 -0
- package/package.json +102 -0
- package/replit.nix +8 -0
- package/src/Dev_Horizon_Data.js +125 -0
- package/src/Premium.js +30 -0
- package/src/Screenshot.js +85 -0
- package/src/addExternalModule.js +16 -0
- package/src/addUserToGroup.js +79 -0
- package/src/changeAdminStatus.js +79 -0
- package/src/changeArchivedStatus.js +41 -0
- package/src/changeAvt.js +85 -0
- package/src/changeBio.js +65 -0
- package/src/changeBlockedStatus.js +36 -0
- package/src/changeGroupImage.js +106 -0
- package/src/changeNickname.js +45 -0
- package/src/changeThreadColor.js +62 -0
- package/src/changeThreadEmoji.js +42 -0
- package/src/createNewGroup.js +70 -0
- package/src/createPoll.js +60 -0
- package/src/deleteMessage.js +45 -0
- package/src/deleteThread.js +43 -0
- package/src/forwardAttachment.js +48 -0
- package/src/getAccessToken.js +32 -0
- package/src/getCurrentUserID.js +7 -0
- package/src/getEmojiUrl.js +27 -0
- package/src/getFriendsList.js +73 -0
- package/src/getMessage.js +80 -0
- package/src/getThreadHistory.js +537 -0
- package/src/getThreadInfo.js +355 -0
- package/src/getThreadList.js +213 -0
- package/src/getThreadMain.js +220 -0
- package/src/getThreadPictures.js +59 -0
- package/src/getUID.js +59 -0
- package/src/getUserID.js +62 -0
- package/src/getUserInfo.js +141 -0
- package/src/getUserInfoMain.js +65 -0
- package/src/getUserInfoV2.js +36 -0
- package/src/getUserInfoV3.js +63 -0
- package/src/getUserInfoV4.js +55 -0
- package/src/getUserInfoV5.js +61 -0
- package/src/handleFriendRequest.js +46 -0
- package/src/handleMessageRequest.js +49 -0
- package/src/httpGet.js +49 -0
- package/src/httpPost.js +48 -0
- package/src/httpPostFormData.js +41 -0
- package/src/listenMqtt.js +796 -0
- package/src/logout.js +68 -0
- package/src/markAsDelivered.js +48 -0
- package/src/markAsRead.js +70 -0
- package/src/markAsReadAll.js +43 -0
- package/src/markAsSeen.js +51 -0
- package/src/muteThread.js +47 -0
- package/src/removeUserFromGroup.js +49 -0
- package/src/resolvePhotoUrl.js +37 -0
- package/src/searchForThread.js +43 -0
- package/src/sendMessage.js +334 -0
- package/src/sendTypingIndicator.js +80 -0
- package/src/setMessageReaction.js +109 -0
- package/src/setPostReaction.js +102 -0
- package/src/setTitle.js +74 -0
- package/src/threadColors.js +39 -0
- package/src/unfriend.js +43 -0
- package/src/unsendMessage.js +40 -0
- package/test/Database_Test.js +3 -0
- package/test/Db2.js +362 -0
- package/test/data/shareAttach.js +146 -0
- package/test/data/something.mov +0 -0
- package/test/data/test.png +0 -0
- package/test/data/test.txt +7 -0
- package/test/env/.env +0 -0
- package/test/example-config.json +18 -0
- package/test/example-db.db +0 -0
- package/test/kteam_Database/A_README.md +1 -0
- package/test/kteam_Database/Database.db +0 -0
- package/test/memoryleak.js +18 -0
- package/test/test-page.js +140 -0
- package/test/test.js +385 -0
- package/test/testv2.js +18 -0
- package/utils.js +1644 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const got = global.Fca.Require.Fetch;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {string | URL} url
|
|
7
|
+
* @param {{ sendMessage: (arg0: string, arg1: any) => any; }} api
|
|
8
|
+
*/
|
|
9
|
+
async function getUIDSlow(url,api) {
|
|
10
|
+
var FormData = require("form-data");
|
|
11
|
+
var Form = new FormData();
|
|
12
|
+
var Url = new URL(url);
|
|
13
|
+
Form.append('username', Url.pathname.replace(/\//g, ""));
|
|
14
|
+
try {
|
|
15
|
+
var data = await got.post('https://api.findids.net/api/get-uid-from-username',{
|
|
16
|
+
body: Form,
|
|
17
|
+
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.79 Safari/537.36'
|
|
18
|
+
})
|
|
19
|
+
} catch (e) {
|
|
20
|
+
console.log(global.Fca.Data.event.threadID,e)
|
|
21
|
+
return api.sendMessage("Lỗi: " + e.message,global.Fca.Data.event.threadID);
|
|
22
|
+
}
|
|
23
|
+
if (JSON.parse(data.body.toString()).status != 200) return api.sendMessage('Đã bị lỗi !',global.Fca.Data.event.threadID)
|
|
24
|
+
if (typeof JSON.parse(data.body.toString()).error === 'string') return "errr"
|
|
25
|
+
else return JSON.parse(data.body.toString()).data.id || "nịt";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {string | URL} url
|
|
30
|
+
* @param {{ sendMessage: (arg0: string, arg1: any, arg2: any) => any; }} api
|
|
31
|
+
*/
|
|
32
|
+
async function getUIDFast(url,api) {
|
|
33
|
+
var FormData = require("form-data");
|
|
34
|
+
var Form = new FormData();
|
|
35
|
+
var Url = new URL(url);
|
|
36
|
+
Form.append('link', Url.href);
|
|
37
|
+
try {
|
|
38
|
+
var data = await got.post('https://id.traodoisub.com/api.php',{
|
|
39
|
+
body: Form
|
|
40
|
+
})
|
|
41
|
+
} catch (e) {
|
|
42
|
+
return api.sendMessage("Lỗi: " + e.message,global.Fca.Data.event.threadID,global.Fca.Data.event.messageID);
|
|
43
|
+
}
|
|
44
|
+
if (JSON.parse(data.body.toString()).error) return api.sendMessage(JSON.parse(data.body.toString()).error,global.Fca.Data.event.threadID,global.Fca.Data.event.messageID);
|
|
45
|
+
else return JSON.parse(data.body.toString()).id || "co cai nit huhu";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {any} url
|
|
50
|
+
* @param {any} api
|
|
51
|
+
*/
|
|
52
|
+
async function getUID(url,api) {
|
|
53
|
+
var getUID = await getUIDFast(url,api);
|
|
54
|
+
if (!isNaN(getUID) == true) return getUID;
|
|
55
|
+
else {
|
|
56
|
+
let getUID = await getUIDSlow(url,api);
|
|
57
|
+
if (!isNaN(data) == true) return getUID;
|
|
58
|
+
else return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = getUID;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
"use strict";
|
|
3
|
+
var Database= require("./Database");
|
|
4
|
+
var { lastRun,capture } = require('./Src/Last-Run');
|
|
5
|
+
var logger = require("../logger");
|
|
6
|
+
var getText = global.Fca.getText;
|
|
7
|
+
var language = require("../Language/index.json");
|
|
8
|
+
language = language.find(i => i.Language == require(process.cwd() + "/FastConfigFca.json").Language).Folder.ExtraGetThread;
|
|
9
|
+
|
|
10
|
+
exports.createData = function(threadID,threadData) {
|
|
11
|
+
try {
|
|
12
|
+
Database(true).set(String(threadID),Object(threadData));
|
|
13
|
+
logger.Normal(getText(language.CreateDatabaseSuccess,String(threadID)));
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
console.log(e);
|
|
17
|
+
logger.Warning(getText(language.CreateDatabaseFailure,String(threadID)));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
exports.updateData = function(threadID,threadData) {
|
|
22
|
+
try {
|
|
23
|
+
Database(true).set(String(threadID),Object(threadData));
|
|
24
|
+
logger.Normal(getText(language.updateDataSuccess,String(threadID)));
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
console.log(e);
|
|
28
|
+
logger.Warning(getText(language.updateDataFailure,String(threadID)));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
exports.updateMessageCount = function(threadID,threadData) {
|
|
33
|
+
try {
|
|
34
|
+
Database(true).set(String(threadID),Object(threadData));
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
console.log(e);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
exports.getData = function(threadID) {
|
|
42
|
+
switch (Database(true).has(String(threadID))) {
|
|
43
|
+
case true: {
|
|
44
|
+
return Database(true).get(String(threadID))
|
|
45
|
+
}
|
|
46
|
+
case false: {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
exports.deleteAll = function(data) {
|
|
53
|
+
for (let i of data) {
|
|
54
|
+
Database(true).delete(String(i));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
exports.getAll = function() {
|
|
59
|
+
return Database(true).list();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
exports.hasData = function(threadID) {
|
|
63
|
+
return Database(true).has(String(threadID));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
exports.alreadyUpdate = function(threadID) {
|
|
67
|
+
var Time = Database(true).get(String(threadID)).TimeUpdate;
|
|
68
|
+
try {
|
|
69
|
+
if (global.Fca.startTime >= (Time + (3600 * 1000))) {
|
|
70
|
+
logger.Normal(getText(language.alreadyUpdate, String(threadID)));
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
else return false;
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
console.log(e);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
exports.readyCreate = function(Name) {
|
|
82
|
+
switch (Database(true).has(String(Name))) {
|
|
83
|
+
case true: {
|
|
84
|
+
if (Number(global.Fca.startTime) >= Number(Database(true).get(String(Name)) + (120 * 1000))) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
case false: {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
exports.setLastRun = function(Name,LastRun) {
|
|
98
|
+
Database(true).set(String(Name),String(lastRun(LastRun)));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
exports.getLastRun = function(Name) {
|
|
102
|
+
switch (Database(true).has(String(Name))) {
|
|
103
|
+
case true: {
|
|
104
|
+
return Database(true).get(String(Name));
|
|
105
|
+
}
|
|
106
|
+
case false: {
|
|
107
|
+
try {
|
|
108
|
+
capture(Name)
|
|
109
|
+
this.setLastRun(Name,Name);
|
|
110
|
+
return Database(true).get(String(Name));
|
|
111
|
+
}
|
|
112
|
+
catch(e) {
|
|
113
|
+
console.log(e);
|
|
114
|
+
return Date.now();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
/* global document */
|
|
2
|
+
'use strict';
|
|
3
|
+
const {promisify} = require('util');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const fileUrl = require('file-url');
|
|
6
|
+
const puppeteer = require('puppeteer');
|
|
7
|
+
const toughCookie = require('tough-cookie');
|
|
8
|
+
|
|
9
|
+
const writeFile = promisify(fs.writeFile);
|
|
10
|
+
|
|
11
|
+
const isUrl = string => /^(https?|file):\/\/|^data:/.test(string);
|
|
12
|
+
|
|
13
|
+
const scrollToElement = (element, options) => {
|
|
14
|
+
const isOverflown = element => {
|
|
15
|
+
return (
|
|
16
|
+
element.scrollHeight > element.clientHeight ||
|
|
17
|
+
element.scrollWidth > element.clientWidth
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const findScrollParent = element => {
|
|
22
|
+
if (element === undefined) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (isOverflown(element)) {
|
|
27
|
+
return element;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return findScrollParent(element.parentElement);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const calculateOffset = (rect, options) => {
|
|
34
|
+
if (options === undefined) {
|
|
35
|
+
return {
|
|
36
|
+
x: rect.left,
|
|
37
|
+
y: rect.top
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const offset = options.offset || 0;
|
|
42
|
+
|
|
43
|
+
switch (options.offsetFrom) {
|
|
44
|
+
case 'top':
|
|
45
|
+
return {
|
|
46
|
+
x: rect.left,
|
|
47
|
+
y: rect.top + offset
|
|
48
|
+
};
|
|
49
|
+
case 'right':
|
|
50
|
+
return {
|
|
51
|
+
x: rect.left - offset,
|
|
52
|
+
y: rect.top
|
|
53
|
+
};
|
|
54
|
+
case 'bottom':
|
|
55
|
+
return {
|
|
56
|
+
x: rect.left,
|
|
57
|
+
y: rect.top - offset
|
|
58
|
+
};
|
|
59
|
+
case 'left':
|
|
60
|
+
return {
|
|
61
|
+
x: rect.left + offset,
|
|
62
|
+
y: rect.top
|
|
63
|
+
};
|
|
64
|
+
default:
|
|
65
|
+
throw new Error('Invalid `scrollToElement.offsetFrom` value');
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const rect = element.getBoundingClientRect();
|
|
70
|
+
const offset = calculateOffset(rect, options);
|
|
71
|
+
const parent = findScrollParent(element);
|
|
72
|
+
|
|
73
|
+
if (parent !== undefined) {
|
|
74
|
+
parent.scrollIntoView(true);
|
|
75
|
+
parent.scrollTo(offset.x, offset.y);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const disableAnimations = () => {
|
|
80
|
+
const rule = `
|
|
81
|
+
*,
|
|
82
|
+
::before,
|
|
83
|
+
::after {
|
|
84
|
+
animation: initial !important;
|
|
85
|
+
transition: initial !important;
|
|
86
|
+
}
|
|
87
|
+
`;
|
|
88
|
+
|
|
89
|
+
const style = document.createElement('style');
|
|
90
|
+
document.body.append(style);
|
|
91
|
+
|
|
92
|
+
style.sheet.insertRule(rule);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const getBoundingClientRect = element => {
|
|
96
|
+
const {top, left, height, width, x, y} = element.getBoundingClientRect();
|
|
97
|
+
return {top, left, height, width, x, y};
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const parseCookie = (url, cookie) => {
|
|
101
|
+
if (typeof cookie === 'object') {
|
|
102
|
+
return cookie;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const jar = new toughCookie.CookieJar(undefined, {rejectPublicSuffixes: false});
|
|
106
|
+
jar.setCookieSync(cookie, url);
|
|
107
|
+
const returnValue = jar.serializeSync().cookies[0];
|
|
108
|
+
|
|
109
|
+
// Use this instead of the above when the following issue is fixed:
|
|
110
|
+
// https://github.com/salesforce/tough-cookie/issues/149
|
|
111
|
+
// const ret = toughCookie.parse(cookie).serializeSync();
|
|
112
|
+
|
|
113
|
+
returnValue.name = returnValue.key;
|
|
114
|
+
delete returnValue.key;
|
|
115
|
+
|
|
116
|
+
if (returnValue.expires) {
|
|
117
|
+
returnValue.expires = Math.floor(new Date(returnValue.expires) / 1000);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return returnValue;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const imagesHaveLoaded = () => [...document.images].map(element => element.complete);
|
|
124
|
+
|
|
125
|
+
const captureWebsite = async (input, options) => {
|
|
126
|
+
options = {
|
|
127
|
+
inputType: 'url',
|
|
128
|
+
width: 1920,
|
|
129
|
+
height: 1080,
|
|
130
|
+
scaleFactor: 2,
|
|
131
|
+
fullPage: false,
|
|
132
|
+
defaultBackground: true,
|
|
133
|
+
timeout: 60, // The Puppeteer default of 30 is too short
|
|
134
|
+
delay: 0,
|
|
135
|
+
debug: false,
|
|
136
|
+
darkMode: true,
|
|
137
|
+
launchOptions: { devtools:true },
|
|
138
|
+
_keepAlive: true,
|
|
139
|
+
isJavaScriptEnabled: true,
|
|
140
|
+
inset: 0,
|
|
141
|
+
args: ["--webview-disable-safebrowsing-support",
|
|
142
|
+
"--disable-web-security"],
|
|
143
|
+
ignoreHTTPSErrors: true,
|
|
144
|
+
...options
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const isHTMLContent = options.inputType === 'html';
|
|
148
|
+
|
|
149
|
+
input = isHTMLContent || isUrl(input) ? input : fileUrl(input);
|
|
150
|
+
|
|
151
|
+
const timeoutInSeconds = options.timeout * 1000;
|
|
152
|
+
|
|
153
|
+
const viewportOptions = {
|
|
154
|
+
width: options.width,
|
|
155
|
+
height: options.height,
|
|
156
|
+
deviceScaleFactor: options.scaleFactor
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const screenshotOptions = {};
|
|
160
|
+
|
|
161
|
+
if (options.type) {
|
|
162
|
+
screenshotOptions.type = options.type;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (options.quality) {
|
|
166
|
+
screenshotOptions.quality = options.quality * 100;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (options.fullPage) {
|
|
170
|
+
screenshotOptions.fullPage = options.fullPage;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (typeof options.defaultBackground === 'boolean') {
|
|
174
|
+
screenshotOptions.omitBackground = !options.defaultBackground;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const launchOptions = {...options.launchOptions};
|
|
178
|
+
|
|
179
|
+
if (options.debug) {
|
|
180
|
+
launchOptions.headless = false;
|
|
181
|
+
launchOptions.slowMo = 100;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const browser = options._browser || await puppeteer.launch(launchOptions);
|
|
185
|
+
const page = await browser.newPage();
|
|
186
|
+
|
|
187
|
+
if (options.preloadFunction) {
|
|
188
|
+
await page.evaluateOnNewDocument(options.preloadFunction);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
await page.setJavaScriptEnabled(options.isJavaScriptEnabled);
|
|
192
|
+
|
|
193
|
+
if (options.debug) {
|
|
194
|
+
page.on('console', message => {
|
|
195
|
+
let {url, lineNumber, columnNumber} = message.location();
|
|
196
|
+
lineNumber = lineNumber ? `:${lineNumber}` : '';
|
|
197
|
+
columnNumber = columnNumber ? `:${columnNumber}` : '';
|
|
198
|
+
const location = url ? ` (${url}${lineNumber}${columnNumber})` : '';
|
|
199
|
+
console.log(`\nPage log:${location}\n${message.text()}\n`);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
page.on('pageerror', error => {
|
|
203
|
+
console.log('\nPage error:', error, '\n');
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// TODO: Add more events from https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#event-requestfailed
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (options.authentication) {
|
|
210
|
+
await page.authenticate(options.authentication);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (options.cookies) {
|
|
214
|
+
const cookies = options.cookies.map(cookie => parseCookie(isHTMLContent ? 'about:blank' : input, cookie));
|
|
215
|
+
await page.setCookie(...cookies);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (options.headers) {
|
|
219
|
+
await page.setExtraHTTPHeaders(options.headers);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (options.userAgent) {
|
|
223
|
+
await page.setUserAgent(options.userAgent);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
await page.setViewport(viewportOptions);
|
|
227
|
+
|
|
228
|
+
if (options.emulateDevice) {
|
|
229
|
+
if (!(options.emulateDevice in puppeteer.devices)) {
|
|
230
|
+
throw new Error(`The device name \`${options.emulateDevice}\` is not supported`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
await page.emulate(puppeteer.devices[options.emulateDevice]);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
await page.emulateMediaFeatures([{
|
|
237
|
+
name: 'prefers-color-scheme',
|
|
238
|
+
value: options.darkMode ? 'dark' : 'light'
|
|
239
|
+
}]);
|
|
240
|
+
|
|
241
|
+
await page[isHTMLContent ? 'setContent' : 'goto'](input, {
|
|
242
|
+
timeout: timeoutInSeconds,
|
|
243
|
+
waitUntil: 'networkidle2'
|
|
244
|
+
});
|
|
245
|
+
if (options.disableAnimations) {
|
|
246
|
+
await page.evaluate(disableAnimations, options.disableAnimations);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (options.hideElements) {
|
|
250
|
+
await page.addStyleTag({
|
|
251
|
+
content: `${options.hideElements.join(', ')} { visibility: hidden !important; }`
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (options.removeElements) {
|
|
256
|
+
await page.addStyleTag({
|
|
257
|
+
content: `${options.removeElements.join(', ')} { display: none !important; }`
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (options.clickElement) {
|
|
262
|
+
await page.click(options.clickElement);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const getInjectKey = (ext, value) => isUrl(value) ? 'url' : (value.endsWith(`.${ext}`) ? 'path' : 'content');
|
|
266
|
+
|
|
267
|
+
if (!options.isJavaScriptEnabled) {
|
|
268
|
+
// Enable JavaScript again for `modules` and `scripts`.
|
|
269
|
+
await page.setJavaScriptEnabled(true);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (options.modules) {
|
|
273
|
+
await Promise.all(options.modules.map(module_ => {
|
|
274
|
+
return page.addScriptTag({
|
|
275
|
+
[getInjectKey('js', module_)]: module_,
|
|
276
|
+
type: 'module'
|
|
277
|
+
});
|
|
278
|
+
}));
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (options.scripts) {
|
|
282
|
+
await Promise.all(options.scripts.map(script => {
|
|
283
|
+
return page.addScriptTag({
|
|
284
|
+
[getInjectKey('js', script)]: script
|
|
285
|
+
});
|
|
286
|
+
}));
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (options.styles) {
|
|
290
|
+
await Promise.all(options.styles.map(style => {
|
|
291
|
+
return page.addStyleTag({
|
|
292
|
+
[getInjectKey('css', style)]: style
|
|
293
|
+
});
|
|
294
|
+
}));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (options.waitForElement) {
|
|
298
|
+
await page.waitForSelector(options.waitForElement, {
|
|
299
|
+
visible: true,
|
|
300
|
+
timeout: timeoutInSeconds
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (options.beforeScreenshot) {
|
|
305
|
+
await options.beforeScreenshot(page, browser);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (options.element) {
|
|
309
|
+
await page.waitForSelector(options.element, {
|
|
310
|
+
visible: true,
|
|
311
|
+
timeout: timeoutInSeconds
|
|
312
|
+
});
|
|
313
|
+
screenshotOptions.clip = await page.$eval(options.element, getBoundingClientRect);
|
|
314
|
+
screenshotOptions.fullPage = false;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (options.delay) {
|
|
318
|
+
await page.waitForTimeout(options.delay * 1000);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (options.scrollToElement) {
|
|
322
|
+
// eslint-disable-next-line unicorn/prefer-ternary
|
|
323
|
+
if (typeof options.scrollToElement === 'object') {
|
|
324
|
+
await page.$eval(options.scrollToElement.element, scrollToElement, options.scrollToElement);
|
|
325
|
+
} else {
|
|
326
|
+
await page.$eval(options.scrollToElement, scrollToElement);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (screenshotOptions.fullPage) {
|
|
331
|
+
// Get the height of the rendered page
|
|
332
|
+
const bodyHandle = await page.$('body');
|
|
333
|
+
const bodyBoundingHeight = await bodyHandle.boundingBox();
|
|
334
|
+
await bodyHandle.dispose();
|
|
335
|
+
|
|
336
|
+
// Scroll one viewport at a time, pausing to let content load
|
|
337
|
+
const viewportHeight = viewportOptions.height;
|
|
338
|
+
let viewportIncrement = 0;
|
|
339
|
+
while (viewportIncrement + viewportHeight < bodyBoundingHeight) {
|
|
340
|
+
const navigationPromise = page.waitForNavigation({waitUntil: 'networkidle0'});
|
|
341
|
+
/* eslint-disable no-await-in-loop */
|
|
342
|
+
await page.evaluate(_viewportHeight => {
|
|
343
|
+
/* eslint-disable no-undef */
|
|
344
|
+
window.scrollBy(0, _viewportHeight);
|
|
345
|
+
/* eslint-enable no-undef */
|
|
346
|
+
}, viewportHeight);
|
|
347
|
+
await navigationPromise;
|
|
348
|
+
/* eslint-enable no-await-in-loop */
|
|
349
|
+
viewportIncrement += viewportHeight;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Scroll back to top
|
|
353
|
+
await page.evaluate(_ => {
|
|
354
|
+
/* eslint-disable no-undef */
|
|
355
|
+
window.scrollTo(0, 0);
|
|
356
|
+
/* eslint-enable no-undef */
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// Some extra delay to let images load
|
|
360
|
+
await page.waitForFunction(imagesHaveLoaded, {timeout: timeoutInSeconds});
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (options.inset && !screenshotOptions.fullPage) {
|
|
364
|
+
const inset = {top: 0, right: 0, bottom: 0, left: 0};
|
|
365
|
+
for (const key of Object.keys(inset)) {
|
|
366
|
+
if (typeof options.inset === 'number') {
|
|
367
|
+
inset[key] = options.inset;
|
|
368
|
+
} else {
|
|
369
|
+
inset[key] = options.inset[key] || 0;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
let clipOptions = screenshotOptions.clip;
|
|
374
|
+
|
|
375
|
+
if (!clipOptions) {
|
|
376
|
+
clipOptions = await page.evaluate(() => ({
|
|
377
|
+
x: 0,
|
|
378
|
+
y: 0,
|
|
379
|
+
/* eslint-disable no-undef */
|
|
380
|
+
height: window.innerHeight,
|
|
381
|
+
width: window.innerWidth
|
|
382
|
+
/* eslint-enable no-undef */
|
|
383
|
+
}));
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const x = clipOptions.x + inset.left;
|
|
387
|
+
const y = clipOptions.y + inset.top;
|
|
388
|
+
const width = clipOptions.width - (inset.left + inset.right);
|
|
389
|
+
const height = clipOptions.height - (inset.top + inset.bottom);
|
|
390
|
+
|
|
391
|
+
if (width === 0 || height === 0) {
|
|
392
|
+
await page.close();
|
|
393
|
+
|
|
394
|
+
throw new Error('When using the `clip` option, the width or height of the screenshot cannot be equal to 0.');
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
screenshotOptions.clip = {x, y, width, height};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const buffer = await page.screenshot(screenshotOptions);
|
|
401
|
+
|
|
402
|
+
await page.close();
|
|
403
|
+
|
|
404
|
+
if (!options._keepAlive) {
|
|
405
|
+
await browser.close();
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return buffer;
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
module.exports.file = async (url, filePath, options = {}) => {
|
|
412
|
+
const screenshot = await captureWebsite(url, options);
|
|
413
|
+
|
|
414
|
+
await writeFile(filePath, screenshot, {
|
|
415
|
+
flag: options.overwrite ? 'w' : 'wx'
|
|
416
|
+
});
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
module.exports.buffer = async (url, options) => captureWebsite(url, options);
|
|
420
|
+
|
|
421
|
+
module.exports.base64 = async (url, options) => {
|
|
422
|
+
const screenshot = await captureWebsite(url, options);
|
|
423
|
+
return screenshot.toString('base64');
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
module.exports.devices = Object.values(puppeteer.devices).map(device => device.name);
|
|
427
|
+
|
|
428
|
+
if (process.env.NODE_ENV === 'test') {
|
|
429
|
+
module.exports._startBrowser = puppeteer.launch.bind(puppeteer);
|
|
430
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const logger = require("../logger");
|
|
4
|
+
module.exports = function() {
|
|
5
|
+
var Logger = global.Fca.Require.logger;
|
|
6
|
+
switch (process.platform) {
|
|
7
|
+
case 'win32': {
|
|
8
|
+
if (global.Fca.Require.FastConfig.Uptime) {
|
|
9
|
+
logger.Warning(global.Fca.Require.Language.ExtraUpTime.NotSupport);
|
|
10
|
+
}
|
|
11
|
+
break;
|
|
12
|
+
}
|
|
13
|
+
case 'darwin': {
|
|
14
|
+
if (global.Fca.Require.FastConfig.Uptime) {
|
|
15
|
+
logger.Warning(global.Fca.Require.Language.ExtraUpTime.NotSupport);
|
|
16
|
+
}
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
case 'linux':
|
|
20
|
+
if (process.env.REPL_SLUG) {
|
|
21
|
+
var Value = global.Fca.Require.FastConfig;
|
|
22
|
+
var Fetch = global.Fca.Require.Fetch;
|
|
23
|
+
if (Value.Uptime) {
|
|
24
|
+
logger.Normal(global.Fca.Require.Language.ExtraUpTime.Uptime);//
|
|
25
|
+
return setInterval(function() {
|
|
26
|
+
Fetch.get(`https://${process.env.REPL_SLUG}.${process.env.REPL_OWNER}.repl.co`);
|
|
27
|
+
},10*1000);
|
|
28
|
+
}
|
|
29
|
+
else return;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
Logger.Warning(global.Fca.Require.Language.ExtraUpTime.NotSupport);
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
Logger.Warning(global.Fca.Require.Language.ExtraUpTime.NotSupport);
|
|
37
|
+
}
|
|
38
|
+
};
|