bdy 1.8.50-dev → 1.9.1-dev
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/distTs/package.json +6 -5
- package/distTs/src/texts.js +7 -5
- package/distTs/src/types/schemas.js +52 -0
- package/distTs/src/visualTest/requests.js +2 -2
- package/distTs/src/visualTest/resources.js +25 -22
- package/distTs/src/visualTest/server.js +59 -3
- package/distTs/src/visualTest/snapshots.js +9 -13
- package/package.json +6 -5
package/distTs/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bdy",
|
|
3
3
|
"preferGlobal": false,
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.9.1-dev",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"scripts": {
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
"jsonwebtoken": "9.0.2",
|
|
32
32
|
"mime-db": "1.52.0",
|
|
33
33
|
"mime-types": "2.1.35",
|
|
34
|
-
"punycode.js": "2.3.1",
|
|
35
34
|
"netmask": "2.0.2",
|
|
36
35
|
"node-fetch": "3.3.2",
|
|
37
36
|
"node-forge": "1.3.1",
|
|
38
37
|
"path-is-inside": "1.0.2",
|
|
39
38
|
"pino": "8.20.0",
|
|
39
|
+
"punycode.js": "2.3.1",
|
|
40
40
|
"puppeteer-core": "23.6.0",
|
|
41
41
|
"range-parser": "1.2.1",
|
|
42
42
|
"socket.io-client": "4.7.5",
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
"undici": "6.19.2",
|
|
46
46
|
"uuid": "10.0.0",
|
|
47
47
|
"which": "4.0.0",
|
|
48
|
-
"ws": "8.18.0"
|
|
48
|
+
"ws": "8.18.0",
|
|
49
|
+
"zod": "3.24.2"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@eslint/js": "9.13.0",
|
|
@@ -64,9 +65,9 @@
|
|
|
64
65
|
"eslint-config-prettier": "9.1.0",
|
|
65
66
|
"globals": "15.11.0",
|
|
66
67
|
"prettier": "3.3.3",
|
|
68
|
+
"rollup": "4.24.2",
|
|
67
69
|
"rollup-plugin-natives": "0.7.8",
|
|
68
70
|
"typescript": "5.6.3",
|
|
69
|
-
"typescript-eslint": "8.11.0"
|
|
70
|
-
"rollup": "4.24.2"
|
|
71
|
+
"typescript-eslint": "8.11.0"
|
|
71
72
|
}
|
|
72
73
|
}
|
package/distTs/src/texts.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ERR_FETCH_VERSION = exports.ERR_SWW = exports.ERR_NOT_FOUND = exports.ERR_FAILED_TO_CONNECT_TO_AGENT = exports.ERR_TUNNEL_REMOVED = exports.ERR_TUNNELS_DISABLED = exports.ERR_AGENT_LIMIT_REACHED = exports.ERR_TUNNEL_LIMIT_REACHED = exports.ERR_DOMAIN_RESTRICTED = exports.ERR_SUBDOMAIN_INVALID = exports.ERR_SUBDOMAIN_TAKEN = exports.ERR_AGENT_REMOVED = exports.ERR_FAILED_TO_CONNECT = exports.ERR_TUNNEL_ALREADY_EXISTS = exports.ERR_AGENT_NOT_SUPPORTED = exports.ERR_AGENT_ADMIN_RIGHTS = exports.ERR_AGENT_ENABLE = exports.ERR_SWW_AGENT_UPDATING = exports.ERR_SWW_AGENT_DISABLING = exports.ERR_SWW_AGENT_ENABLING = exports.ERR_AGENT_NOT_FOUND = exports.ERR_AGENT_NOT_RUNNING = exports.ERR_AGENT_NOT_ENABLED = exports.ERR_TUNNEL_NOT_FOUND = exports.ERR_WHITELIST_IS_NOT_VALID = exports.ERR_USER_AGENT_IS_NOT_VALID = exports.ERR_BA_IS_NOT_VALID = exports.ERR_BA_LOGIN_NOT_PROVIDED = exports.ERR_BA_PASSWORD_NOT_PROVIDED = exports.ERR_CB_THRESHOLD_IS_NOT_VALID = exports.ERR_DOMAIN_IS_NOT_VALID = exports.ERR_CERT_PATH_IS_NOT_VALID = exports.ERR_KEY_PATH_IS_NOT_VALID = exports.ERR_CA_PATH_IS_NOT_VALID = exports.ERR_WRONG_CA = exports.ERR_WRONG_KEY_CERT = exports.ERR_NAME_WITHOUT_ASTERISK = exports.ERR_PORT_IS_NOT_VALID = exports.ERR_REGION_IS_NOT_VALID = exports.ERR_PATH_IS_NOT_DIRECTORY = exports.ERR_DIRECTORY_DOES_NOT_EXISTS = exports.ERR_SUBDOMAIN_IS_TOO_LONG = exports.ERR_SUBDOMAIN_IS_TOO_SHORT = exports.ERR_SUBDOMAIN_IS_NOT_VALID = exports.ERR_TERMINATE_IS_NOT_VALID = exports.ERR_TIMEOUT_IS_NOT_VALID = exports.ERR_TYPE_IS_NOT_VALID = exports.ERR_TARGET_IS_NOT_VALID = exports.ERR_SAVING_AGENT_CONFIG = exports.ERR_AGENT_NOT_REGISTERED = void 0;
|
|
4
|
-
exports.
|
|
5
|
-
exports.
|
|
6
|
-
exports.
|
|
7
|
-
exports.
|
|
8
|
-
exports.DEBUG_WAIT_FOR_IDLE_TIMEOUT = exports.DEBUG_WAIT_FOR_IDLE = exports.DEBUG_RESOURCE_DISCOVERY_TIMEOUT = exports.DEBUG_AUTO_WIDTH = exports.DEBUG_AUTO_SCROLL = exports.DEBUG_RESOURCE_SCRAPPING_URL = exports.DEBUG_SNAPSHOT_PROCESSING = exports.DEBUG_SNAPSHOTS_PROCESSING = exports.DEBUG_EXEC_COMMAND = exports.DEBUG_EXEC_TEST_COMMAND = exports.LOG_INSTALLED_BROWSER = exports.LOG_SENDING_REQUEST = exports.LOG_PROCESSING_SNAPSHOTS = exports.LOG_RUNNING_EXEC_COMMAND = exports.LOG_TUNNEL_SSH_STREAM = exports.LOG_TUNNEL_TLS_AGENT_STREAM = exports.LOG_TUNNEL_TLS_REGION_STREAM = exports.LOG_TUNNEL_TLS_TARGET_STREAM = exports.LOG_TUNNEL_HTTP2_STREAM = exports.LOG_TUNNEL_HTTP1_STREAM = exports.LOG_TUNNEL_TCP_STREAM = exports.LOG_TUNNEL_HTTP_WRONG_USER_AGENTS = exports.LOG_TUNNEL_HTTP_CIRCUIT_BREAKER_OPEN = exports.LOG_TUNNEL_HTTP_RATE_LIMIT = exports.LOG_TUNNEL_HTTP_WRON_AUTH = exports.LOG_TUNNEL_IDENTIFIED = exports.LOG_TUNNEL_DISCONNECTED = exports.LOG_TUNNEL_FAILED = exports.LOG_TUNNEL_CONNECTED = exports.LOG_AGENT_STARTED = exports.LOG_AGENT_SERVER_STARTED = exports.LOG_ERROR_STARTING_AGENT_SERVER = void 0;
|
|
4
|
+
exports.TXT_AGENT_ALREADY_ENABLED = exports.TXT_AGENT_UPDATED = exports.TXT_AGENT_ENABLED = exports.TXT_AGENT_TARGET_DISABLED = exports.TXT_AGENT_TARGET_ENABLED = exports.TXT_AGENT_IS_DISABLED = exports.TXT_AGENT_IS_ENABLED_AND_HAVE_TROUBLES = exports.TXT_AGENT_IS_ENABLED_AND_INITIALIZING = exports.TXT_AGENT_IS_ENABLED_AND_STOPPED = exports.TXT_AGENT_IS_ENABLED_AND_STARTED = exports.TXT_AGENT_RESTARTED = exports.TXT_AGENT_STARTED = exports.TXT_AGENT_STOPPED = exports.WARN_BROWSER_VERSION = exports.ERR_INVALID_SNAPSHOT = exports.ERR_GETTING_COMMIT_DETAILS = exports.ERR_GETTING_BASE_COMMIT = exports.ERR_HEAD_BRANCH_NOT_DEFINED = exports.ERR_BASE_BRANCH_NOT_DEFINED = exports.ERR_INVALID_COMMIT_HASH = exports.ERR_GETTING_COMMIT_HASH = exports.ERR_INVALID_BRANCH_NAME = exports.ERR_GETTING_BRANCH_NAME = exports.ERR_MISSING_HEAD_COMMIT_IN_FILE = exports.ERR_READING_FILE_WITH_HEAD_COMMIT = exports.ERR_MISSING_FILE_WITH_HEAD_COMMIT = exports.ERR_GITHUB_EVENT_PATH_NOT_FOUND = exports.ERR_TEST_EXECUTION = exports.ERR_INVALID_JSON = exports.ERR_INVALID_STORYBOOK_RESPONSE = exports.ERR_INVALID_DEFAULT_SETTINGS_RESPONSE = exports.ERR_INVALID_CLOSE_SESSION_RESPONSE = exports.ERR_INVALID_SNAPSHOTS_RESPONSE = exports.ERR_INVALID_SNAPSHOT_RESPONSE = exports.ERR_RESOURCE_NOT_FOUND = exports.ERR_MISSING_EXEC_COMMAND = exports.ERR_PARSING_STORIES = exports.ERR_UNSUPPORTED_STORYBOOK = exports.ERR_MISSING_STORYBOOK_INDEX_FILE = exports.ERR_WRONG_STORYBOOK_DIRECTORY = exports.ERR_MISSING_BUILD_ID = exports.ERR_MISSING_TOKEN = exports.ERR_CONFIG_CORRUPTED = exports.ERR_WRONG_TOKEN = exports.ERR_TOKEN_NOT_PROVIDED = exports.ERR_CANT_CREATE_DIR_IN_HOME = exports.ERR_CONNECTION_ERROR = exports.ERR_CONNECTION_TIMEOUT = exports.ERR_WRONG_STREAM = exports.ERR_WRONG_HANDSHAKE = void 0;
|
|
5
|
+
exports.DESC_COMMAND_AGENT_VERSION = exports.DESC_COMMAND_AGENT_UPDATE = exports.DESC_COMMAND_AGENT_TARGET = exports.DESC_COMMAND_AGENT_TUNNEL = exports.DESC_COMMAND_AGENT_STOP = exports.DESC_COMMAND_AGENT_TARGET_DISABLE = exports.DESC_COMMAND_AGENT_TARGET_ENABLE = exports.DESC_COMMAND_AGENT_TARGET_STATUS = exports.DESC_COMMAND_AGENT_STATUS = exports.DESC_COMMAND_AGENT_RESTART = exports.DESC_COMMAND_AGENT_START = exports.DESC_COMMAND_AGENT_INSTALL = exports.DESC_COMMAND_AGENT_UNINSTALL = exports.DESC_COMMAND_AGENT_TUNNEL_TLS = exports.DESC_COMMAND_AGENT_TUNNEL_TCP = exports.DESC_COMMAND_AGENT_TUNNEL_REMOVE = exports.DESC_COMMAND_AGENT_TUNNEL_STATUS = exports.DESC_COMMAND_AGENT_TUNNEL_START = exports.DESC_COMMAND_AGENT_TUNNEL_LIST = exports.DESC_COMMAND_AGENT_TUNNEL_HTTP = exports.DESC_COMMAND_CONFIG_SET = exports.DESC_COMMAND_CONFIG_REMOVE = exports.DESC_COMMAND_CONFIG_GET = exports.DESC_COMMAND_CONFIG_ADD = exports.DESC_COMMAND_CONFIG_SET_WHITELIST = exports.DESC_COMMAND_CONFIG_SET_TOKEN = exports.DESC_COMMAND_CONFIG_SET_TIMEOUT = exports.DESC_COMMAND_CONFIG_SET_REGION = exports.DESC_COMMAND_CONFIG_REMOVE_TUNNEL = exports.DESC_COMMAND_CONFIG_GET_WHITELIST = exports.DESC_COMMAND_CONFIG_GET_TUNNELS = exports.DESC_COMMAND_CONFIG_GET_TUNNEL = exports.DESC_COMMAND_CONFIG_GET_TOKEN = exports.DESC_COMMAND_CONFIG_GET_TIMEOUT = exports.DESC_COMMAND_CONFIG_GET_REGION = exports.DESC_COMMAND_CONFIG_ADD_TLS = exports.DESC_COMMAND_CONFIG_ADD_TCP = exports.DESC_COMMAND_CONFIG_ADD_HTTP = exports.AGENT_FETCH_RETRY = exports.NO_TUNNELS_STARTED = exports.TXT_TUNNEL_ADDED = exports.TXT_TUNNEL_REMOVED = exports.TXT_REGION_SAVED = exports.TXT_TIMEOUT_SAVED = exports.TXT_TOKEN_REMOVED = exports.TXT_TOKEN_SAVED = exports.TXT_WHITELIST_SAVED = exports.TXT_TUNNEL_STOPPED = exports.TXT_TUNNEL_STARTED = exports.TXT_AGENT_DISABLED = void 0;
|
|
6
|
+
exports.OPTION_AGENT_START = exports.OPTION_AGENT_ID = exports.OPTION_ID = exports.OPTION_NAME = exports.OPTION_TARGET = exports.OPTION_TLS_TERMINATE = exports.OPTION_TLS_CA = exports.OPTION_TLS_CERT = exports.OPTION_TLS_KEY = exports.OPTION_HTTP_CIRCUIT_BREAKER = exports.OPTION_HTTP_COMPRESSION = exports.OPTION_HTTP_2 = exports.OPTION_HTTP_VERIFY = exports.OPTION_HTTP_LOG = exports.OPTION_HTTP_AUTH = exports.OPTION_HTTP_HOST = exports.OPTION_FORCE = exports.OPTION_TOKEN = exports.OPTION_TIMEOUT = exports.OPTION_DOMAIN = exports.OPTION_FOLLOW = exports.OPTION_SUBDOMAIN = exports.OPTION_SERVE = exports.OPTION_HEADER_USER_AGENT = exports.OPTION_RESPONSE_HEADER = exports.OPTION_HEADER = exports.OPTION_WHITELIST = exports.OPTION_DEFAULT_REGION = exports.OPTION_REGION = exports.TXT_CI_INFO = exports.TXT_STORIES_AMOUNT = exports.TXT_OPENING_TUNNEL = exports.TXT_UPDATING_AGENT = exports.TXT_ENABLING_AGENT = exports.TXT_DISABLING_AGENT = exports.TXT_NEW_AGENT_VERSION = exports.TXT_NEW_CLI_VERSION = exports.TXT_NEW_CLI_DOCKER_VERSION = exports.DESC_COMMAND_VT_INSTALL_BROWSER = exports.DESC_COMMAND_VT_EXEC = exports.DESC_COMMAND_VT_STORYBOOK = exports.DESC_COMMAND_VT_CLOSE = exports.DESC_COMMAND_VT = exports.DESC_PROGRAM = exports.DESC_COMMAND_TLS = exports.DESC_COMMAND_TCP = exports.DESC_COMMAND_START = exports.DESC_COMMAND_AGENT = exports.DESC_COMMAND_HTTP = exports.DESC_COMMAND_CONFIG = void 0;
|
|
7
|
+
exports.LOG_SSH_CONNECTION = exports.LOG_WRONG_STREAM = exports.LOG_DETECTED_STREAM = exports.LOG_HTTP2_REQUEST = exports.LOG_HTTP2_CONNECTION = exports.LOG_HTTP1_REQUEST = exports.LOG_HTTP1_CONNECTION = exports.LOG_ERROR = exports.LOG_STOPPING_TUNNEL = exports.LOG_STARTING_TUNNEL = exports.LOG_ENABLING_AGENT_TARGET = exports.LOG_DISABLING_AGENT_TARGET = exports.LOG_REMOVING_TUNNEL = exports.LOG_TUNNEL_REGISTERED = exports.LOG_ERROR_WHILE_REFRESHING_AGENT = exports.LOG_REGISTERING_TUNNEL = exports.LOG_GETTING_AGENT = exports.LOG_UNREGISTERING_AGENT = exports.LOG_REGION_DETECTED = exports.LOG_AGENT_REGISTERED = exports.LOG_SOCKET_DISCONNECTED = exports.LOG_SOCKET_CONNECTED = exports.LOG_AGENT_NSSM_CLEARING = exports.LOG_AGENT_NSSM_EXTRACTING = exports.LOG_AGENT_NSSM_DOWNLOADING = exports.LOG_AGENT_ENABLED = exports.LOG_AGENT_STARTING_SYSTEM = exports.LOG_AGENT_STOPPING_SYSTEM = exports.LOG_AGENT_ENABLING_SYSTEM = exports.LOG_AGENT_SYSTEM_SERVICE_CONFIG = exports.LOG_AGENT_EXTRACTING_ARCHIVE = exports.LOG_AGENT_DOWNLOADING_ARCHIVE = exports.LOG_AGENT_SYSTEM_DIR = exports.LOG_ERROR_SAVING_AGENT_LOCAL_CONFIG = exports.LOG_ERROR_SAVING_AGENT_SYSTEM_CONFIG = exports.LOG_ERROR_SAVING_AGENT_CONFIG = exports.LOG_SAVING_AGENT_LOCAL_CONFIG = exports.LOG_SAVING_AGENT_SYSTEM_CONFIG = exports.LOG_SAVING_AGENT_CONFIG = exports.LOG_REGISTERING_AGENT = exports.OPTION_EXEC_PARALLEL = exports.OPTION_EXEC_ONE_BY_ONE = exports.OPTION_EXEC_SKIP_DISCOVERY = exports.OPTION_EXEC_COMMAND = exports.OPTION_AGENT_DEBUG = exports.OPTION_AGENT_PORT = exports.OPTION_AGENT_TARGET = exports.OPTION_PASS = exports.OPTION_USER = exports.OPTION_AGENT_TOKEN = void 0;
|
|
8
|
+
exports.DEBUG_WAIT_FOR_IDLE_TIMEOUT = exports.DEBUG_WAIT_FOR_IDLE = exports.DEBUG_RESOURCE_DISCOVERY_TIMEOUT = exports.DEBUG_AUTO_WIDTH = exports.DEBUG_AUTO_SCROLL = exports.DEBUG_RESOURCE_SCRAPPING_URL = exports.DEBUG_SNAPSHOT_PROCESSING = exports.DEBUG_SNAPSHOTS_PROCESSING = exports.DEBUG_EXEC_COMMAND = exports.DEBUG_EXEC_TEST_COMMAND = exports.LOG_INSTALLED_BROWSER = exports.LOG_SENDING_REQUEST = exports.LOG_PROCESSING_SNAPSHOTS = exports.LOG_RUNNING_EXEC_COMMAND = exports.LOG_TUNNEL_SSH_STREAM = exports.LOG_TUNNEL_TLS_AGENT_STREAM = exports.LOG_TUNNEL_TLS_REGION_STREAM = exports.LOG_TUNNEL_TLS_TARGET_STREAM = exports.LOG_TUNNEL_HTTP2_STREAM = exports.LOG_TUNNEL_HTTP1_STREAM = exports.LOG_TUNNEL_TCP_STREAM = exports.LOG_TUNNEL_HTTP_WRONG_USER_AGENTS = exports.LOG_TUNNEL_HTTP_CIRCUIT_BREAKER_OPEN = exports.LOG_TUNNEL_HTTP_RATE_LIMIT = exports.LOG_TUNNEL_HTTP_WRON_AUTH = exports.LOG_TUNNEL_IDENTIFIED = exports.LOG_TUNNEL_DISCONNECTED = exports.LOG_TUNNEL_FAILED = exports.LOG_TUNNEL_CONNECTED = exports.LOG_AGENT_STARTED = exports.LOG_AGENT_SERVER_STARTED = exports.LOG_ERROR_STARTING_AGENT_SERVER = exports.LOG_REQUEST = void 0;
|
|
9
9
|
const utils_1 = require("./utils");
|
|
10
10
|
exports.ERR_AGENT_NOT_REGISTERED = 'Agent not registered. Exiting.';
|
|
11
11
|
exports.ERR_SAVING_AGENT_CONFIG = 'Failed saving agent config. Exiting.';
|
|
@@ -124,6 +124,8 @@ const ERR_GETTING_BASE_COMMIT = (baseBranch, headBranch, error) => `Error while
|
|
|
124
124
|
exports.ERR_GETTING_BASE_COMMIT = ERR_GETTING_BASE_COMMIT;
|
|
125
125
|
const ERR_GETTING_COMMIT_DETAILS = (error) => `Error while getting commit details: ${error}`;
|
|
126
126
|
exports.ERR_GETTING_COMMIT_DETAILS = ERR_GETTING_COMMIT_DETAILS;
|
|
127
|
+
const ERR_INVALID_SNAPSHOT = (name, errors) => `Invalid snapshot "${name}" was skipped: ${errors}`;
|
|
128
|
+
exports.ERR_INVALID_SNAPSHOT = ERR_INVALID_SNAPSHOT;
|
|
127
129
|
const WARN_BROWSER_VERSION = (version) => `Detected browser version: ${version}. We recommend using HeadlessChrome/${utils_1.SUGGESTED_BROWSER_VERSION} to avoid issues(Can be installed with command 'bdy vt install-browser').`;
|
|
128
130
|
exports.WARN_BROWSER_VERSION = WARN_BROWSER_VERSION;
|
|
129
131
|
exports.TXT_AGENT_STOPPED = 'Agent stopped';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.snapshotSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const resourceSchema = zod_1.z.object({
|
|
6
|
+
url: zod_1.z.string().min(1),
|
|
7
|
+
status: zod_1.z.number().positive().optional(),
|
|
8
|
+
headers: zod_1.z.record(zod_1.z.string(), zod_1.z.string()),
|
|
9
|
+
body: zod_1.z.union([zod_1.z.string(), zod_1.z.instanceof(Blob)]).optional(),
|
|
10
|
+
duplicate: zod_1.z.boolean().optional(),
|
|
11
|
+
});
|
|
12
|
+
const viewportSchema = zod_1.z.object({
|
|
13
|
+
width: zod_1.z.number().positive(),
|
|
14
|
+
height: zod_1.z.number().positive(),
|
|
15
|
+
});
|
|
16
|
+
const deviceSchema = zod_1.z
|
|
17
|
+
.object({
|
|
18
|
+
viewport: viewportSchema,
|
|
19
|
+
screen: viewportSchema.optional(),
|
|
20
|
+
devicePixelRatio: zod_1.z.number().positive().default(1),
|
|
21
|
+
isMobile: zod_1.z.boolean().default(false),
|
|
22
|
+
})
|
|
23
|
+
.transform((data) => {
|
|
24
|
+
return {
|
|
25
|
+
...data,
|
|
26
|
+
screen: data.screen ?? data.viewport,
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
const colorSchemeEnum = zod_1.z.enum(['LIGHT', 'DARK', 'LIGHT_AND_DARK']);
|
|
30
|
+
exports.snapshotSchema = zod_1.z.object({
|
|
31
|
+
version: zod_1.z.literal(1),
|
|
32
|
+
name: zod_1.z.string().min(1),
|
|
33
|
+
url: zod_1.z.string().min(1),
|
|
34
|
+
title: zod_1.z.string().min(1),
|
|
35
|
+
html: zod_1.z.string().min(1),
|
|
36
|
+
devices: zod_1.z.array(deviceSchema).optional().default([]),
|
|
37
|
+
enableJavaScript: zod_1.z.boolean().optional().default(false),
|
|
38
|
+
injectStyles: zod_1.z.string().optional(),
|
|
39
|
+
resources: zod_1.z.array(resourceSchema).optional().default([]),
|
|
40
|
+
resourceDiscoveryTimeout: zod_1.z.number().nonnegative().optional().default(0),
|
|
41
|
+
cookies: zod_1.z
|
|
42
|
+
.array(zod_1.z.object({
|
|
43
|
+
name: zod_1.z.string(),
|
|
44
|
+
value: zod_1.z.string(),
|
|
45
|
+
domain: zod_1.z.string().optional(),
|
|
46
|
+
path: zod_1.z.string().optional(),
|
|
47
|
+
}))
|
|
48
|
+
.optional()
|
|
49
|
+
.default([]),
|
|
50
|
+
colorScheme: colorSchemeEnum.optional(),
|
|
51
|
+
fullPage: zod_1.z.boolean().optional(),
|
|
52
|
+
});
|
|
@@ -15,7 +15,7 @@ const node_fs_1 = require("node:fs");
|
|
|
15
15
|
const output_1 = __importDefault(require("../output"));
|
|
16
16
|
const texts_1 = require("../texts");
|
|
17
17
|
const serviceUrl = process.env.SNAPSHOTS_SERVICE_URL || 'http://localhost:3000';
|
|
18
|
-
function
|
|
18
|
+
function prepareSnapshotInternal(snapshot) {
|
|
19
19
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
20
20
|
const { resourceDiscoveryTimeout, cookies, ...filteredSnapshot } = snapshot;
|
|
21
21
|
return filteredSnapshot;
|
|
@@ -31,7 +31,7 @@ function convertTextToBlob(text, headers) {
|
|
|
31
31
|
}
|
|
32
32
|
function prepareSnapshot(snapshot, files) {
|
|
33
33
|
return {
|
|
34
|
-
...
|
|
34
|
+
...prepareSnapshotInternal(snapshot),
|
|
35
35
|
resources: snapshot.resources.map((resource) => {
|
|
36
36
|
const { body, headers, ...rest } = resource;
|
|
37
37
|
if (body) {
|
|
@@ -45,28 +45,29 @@ const utils_1 = require("../utils");
|
|
|
45
45
|
const scrapedUrls = new Map();
|
|
46
46
|
const scrapedResources = new Map();
|
|
47
47
|
let showedBrowserVersionWarning = false;
|
|
48
|
-
async function collectResources({ url,
|
|
48
|
+
async function collectResources({ url, devices, resourceDiscoveryTimeout = 0, cookies = [], }) {
|
|
49
49
|
const scrapedUrl = scrapedUrls.get(url);
|
|
50
|
-
const
|
|
51
|
-
?
|
|
50
|
+
const missingDevices = scrapedUrl
|
|
51
|
+
? devices.filter(({ viewport }) => !scrapedUrl.widths.includes(viewport.width))
|
|
52
52
|
: [];
|
|
53
|
-
if (scrapedUrl &&
|
|
53
|
+
if (scrapedUrl && missingDevices.length === 0) {
|
|
54
54
|
return getResourceUrlsData({
|
|
55
55
|
duplicatedResourcesUrls: scrapedUrl.resources,
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
|
-
else if (scrapedUrl &&
|
|
58
|
+
else if (scrapedUrl && missingDevices.length > 0) {
|
|
59
59
|
const { scrapedResourcesUrls, duplicatedResourcesUrls } = await output_1.default.debugAction((0, texts_1.DEBUG_RESOURCE_SCRAPPING_URL)(url), scrapeResources({
|
|
60
60
|
url,
|
|
61
|
-
|
|
62
|
-
height,
|
|
61
|
+
devices: missingDevices,
|
|
63
62
|
resourceDiscoveryTimeout,
|
|
64
63
|
cookies,
|
|
65
|
-
scaleRatio,
|
|
66
64
|
}));
|
|
67
65
|
const duplicatedScrapedResourceUrls = [...scrapedUrl.resources];
|
|
68
66
|
scrapedUrls.set(url, {
|
|
69
|
-
widths: [
|
|
67
|
+
widths: [
|
|
68
|
+
...scrapedUrl.widths,
|
|
69
|
+
...missingDevices.map(({ viewport }) => viewport.width),
|
|
70
|
+
],
|
|
70
71
|
resources: [
|
|
71
72
|
...new Set([
|
|
72
73
|
...scrapedUrl.resources,
|
|
@@ -88,14 +89,12 @@ async function collectResources({ url, widths = [1280], resourceDiscoveryTimeout
|
|
|
88
89
|
else {
|
|
89
90
|
const { scrapedResourcesUrls, duplicatedResourcesUrls } = await output_1.default.debugAction((0, texts_1.DEBUG_RESOURCE_SCRAPPING_URL)(url), scrapeResources({
|
|
90
91
|
url,
|
|
91
|
-
|
|
92
|
-
height,
|
|
92
|
+
devices,
|
|
93
93
|
resourceDiscoveryTimeout,
|
|
94
94
|
cookies,
|
|
95
|
-
scaleRatio,
|
|
96
95
|
}));
|
|
97
96
|
scrapedUrls.set(url, {
|
|
98
|
-
widths,
|
|
97
|
+
widths: devices.map(({ viewport }) => viewport.width),
|
|
99
98
|
resources: [...scrapedResourcesUrls, ...duplicatedResourcesUrls],
|
|
100
99
|
});
|
|
101
100
|
return getResourceUrlsData({
|
|
@@ -136,7 +135,7 @@ function getResourceUrlsData({ resourcesUrls = [], duplicatedResourcesUrls = [],
|
|
|
136
135
|
}
|
|
137
136
|
return resources;
|
|
138
137
|
}
|
|
139
|
-
async function scrapeResources({ url,
|
|
138
|
+
async function scrapeResources({ url, devices, resourceDiscoveryTimeout, cookies = [], }) {
|
|
140
139
|
const scrapedResourcesUrls = [];
|
|
141
140
|
const duplicatedResourcesUrls = [];
|
|
142
141
|
const launchOptions = {
|
|
@@ -156,11 +155,11 @@ async function scrapeResources({ url, widths, height, resourceDiscoveryTimeout,
|
|
|
156
155
|
}
|
|
157
156
|
const page = await browser.newPage();
|
|
158
157
|
page.setDefaultTimeout(context_js_1.defaultTimeout);
|
|
159
|
-
const initWidth =
|
|
158
|
+
const initWidth = devices[0].viewport.width;
|
|
160
159
|
await page.setViewport({
|
|
161
160
|
width: initWidth,
|
|
162
|
-
height,
|
|
163
|
-
deviceScaleFactor:
|
|
161
|
+
height: devices[0].viewport.height,
|
|
162
|
+
deviceScaleFactor: devices[0].devicePixelRatio,
|
|
164
163
|
});
|
|
165
164
|
await page.setCookie(...cookies);
|
|
166
165
|
page.on('response', async (response) => {
|
|
@@ -198,7 +197,7 @@ async function scrapeResources({ url, widths, height, resourceDiscoveryTimeout,
|
|
|
198
197
|
});
|
|
199
198
|
await page.goto(url);
|
|
200
199
|
await output_1.default.debugAction(texts_1.DEBUG_AUTO_SCROLL, autoScroll(page));
|
|
201
|
-
await output_1.default.debugAction(texts_1.DEBUG_AUTO_WIDTH, autoWidths(page,
|
|
200
|
+
await output_1.default.debugAction(texts_1.DEBUG_AUTO_WIDTH, autoWidths(page, devices));
|
|
202
201
|
if (resourceDiscoveryTimeout > 0) {
|
|
203
202
|
await new Promise((resolve) => setTimeout(resolve, resourceDiscoveryTimeout));
|
|
204
203
|
if (context_js_1.debug) {
|
|
@@ -238,10 +237,14 @@ async function autoScroll(page) {
|
|
|
238
237
|
});
|
|
239
238
|
});
|
|
240
239
|
}
|
|
241
|
-
async function autoWidths(page,
|
|
242
|
-
for (const
|
|
243
|
-
if (width !==
|
|
244
|
-
await page.setViewport({
|
|
240
|
+
async function autoWidths(page, devices) {
|
|
241
|
+
for (const device of devices) {
|
|
242
|
+
if (device.viewport.width !== devices[0].viewport.width) {
|
|
243
|
+
await page.setViewport({
|
|
244
|
+
width: device.viewport.width,
|
|
245
|
+
height: device.viewport.height,
|
|
246
|
+
deviceScaleFactor: device.devicePixelRatio,
|
|
247
|
+
});
|
|
245
248
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
246
249
|
}
|
|
247
250
|
}
|
|
@@ -11,6 +11,10 @@ const promises_1 = __importDefault(require("node:fs/promises"));
|
|
|
11
11
|
const node_path_1 = __importDefault(require("node:path"));
|
|
12
12
|
const node_sea_1 = require("node:sea");
|
|
13
13
|
const utils_js_1 = require("../utils.js");
|
|
14
|
+
const output_js_1 = __importDefault(require("../output.js"));
|
|
15
|
+
const schemas_js_1 = require("../types/schemas.js");
|
|
16
|
+
const zod_1 = require("zod");
|
|
17
|
+
const texts_js_1 = require("../texts.js");
|
|
14
18
|
const port = 1337;
|
|
15
19
|
let cachedParseDom = '';
|
|
16
20
|
function prepareParseDom(parseDom) {
|
|
@@ -30,6 +34,52 @@ async function getParseDom() {
|
|
|
30
34
|
}
|
|
31
35
|
return cachedParseDom;
|
|
32
36
|
}
|
|
37
|
+
function prepareSnapshotPlugin(data) {
|
|
38
|
+
try {
|
|
39
|
+
const validatedData = schemas_js_1.snapshotSchema.parse(data);
|
|
40
|
+
const { version, ...snapshot } = validatedData;
|
|
41
|
+
const cookies = snapshot.cookies.map((cookie) => {
|
|
42
|
+
if (cookie.domain) {
|
|
43
|
+
return cookie;
|
|
44
|
+
}
|
|
45
|
+
else if (cookie.path) {
|
|
46
|
+
return cookie;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const domain = new URL(snapshot.url).hostname;
|
|
50
|
+
return {
|
|
51
|
+
...cookie,
|
|
52
|
+
domain,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
...snapshot,
|
|
58
|
+
resources: snapshot.resources ?? [],
|
|
59
|
+
devices: snapshot.devices ?? [],
|
|
60
|
+
enableJavaScript: snapshot.enableJavaScript ?? false,
|
|
61
|
+
resourceDiscoveryTimeout: snapshot.resourceDiscoveryTimeout ?? 0,
|
|
62
|
+
cookies,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
const name = data &&
|
|
67
|
+
typeof data === 'object' &&
|
|
68
|
+
'name' in data &&
|
|
69
|
+
typeof data.name === 'string'
|
|
70
|
+
? data.name
|
|
71
|
+
: 'Unknown name';
|
|
72
|
+
if (error instanceof zod_1.ZodError) {
|
|
73
|
+
output_js_1.default.error((0, texts_js_1.ERR_INVALID_SNAPSHOT)(name, error.errors
|
|
74
|
+
.map((e) => `${e.path.join('.')} - ${e.message}`)
|
|
75
|
+
.join(', ')));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
33
83
|
async function createServer() {
|
|
34
84
|
const app = (0, fastify_1.default)({
|
|
35
85
|
// logger: true,
|
|
@@ -40,10 +90,16 @@ async function createServer() {
|
|
|
40
90
|
const parseDomFile = await getParseDom();
|
|
41
91
|
reply.type('text/javascript').send(parseDomFile);
|
|
42
92
|
});
|
|
43
|
-
app.post('/snapshot',
|
|
93
|
+
app.post('/snapshot', (request, reply) => {
|
|
44
94
|
const data = request.body;
|
|
45
|
-
|
|
46
|
-
|
|
95
|
+
const preparedSnapshot = prepareSnapshotPlugin(data);
|
|
96
|
+
if (preparedSnapshot) {
|
|
97
|
+
(0, snapshots_js_1.addSnapshot)(preparedSnapshot);
|
|
98
|
+
reply.send('Snapshot received');
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
reply.send('Invalid snapshot format');
|
|
102
|
+
}
|
|
47
103
|
});
|
|
48
104
|
app.get('*', (request, reply) => {
|
|
49
105
|
reply.send('Wrong path');
|
|
@@ -13,24 +13,21 @@ const queue_js_1 = require("./queue.js");
|
|
|
13
13
|
const output_1 = __importDefault(require("../output"));
|
|
14
14
|
const texts_1 = require("../texts");
|
|
15
15
|
const snapshots = [];
|
|
16
|
-
let
|
|
17
|
-
let defaultScaleRatio = 1;
|
|
16
|
+
let defaultDevices = [];
|
|
18
17
|
let firstSnapshot = true;
|
|
19
|
-
function setDefaultSettings(
|
|
20
|
-
|
|
21
|
-
defaultScaleRatio = scaleRatio;
|
|
18
|
+
function setDefaultSettings(defaultSettings) {
|
|
19
|
+
defaultDevices = defaultSettings.defaultDevices;
|
|
22
20
|
}
|
|
23
21
|
function addSnapshot(snapshot) {
|
|
24
|
-
const
|
|
22
|
+
const preparedSnapshot = {
|
|
25
23
|
...snapshot,
|
|
26
|
-
|
|
27
|
-
scaleRatio: defaultScaleRatio,
|
|
24
|
+
devices: snapshot.devices.length > 0 ? snapshot.devices : defaultDevices,
|
|
28
25
|
};
|
|
29
26
|
if (context_js_1.oneByOne) {
|
|
30
|
-
(0, queue_js_1.addToQueue)(() => processSnapshot(
|
|
27
|
+
(0, queue_js_1.addToQueue)(() => processSnapshot(preparedSnapshot, firstSnapshot));
|
|
31
28
|
}
|
|
32
29
|
else {
|
|
33
|
-
snapshots.push(
|
|
30
|
+
snapshots.push(preparedSnapshot);
|
|
34
31
|
}
|
|
35
32
|
if (firstSnapshot) {
|
|
36
33
|
firstSnapshot = false;
|
|
@@ -86,13 +83,12 @@ async function processSnapshots() {
|
|
|
86
83
|
}
|
|
87
84
|
}
|
|
88
85
|
async function getSnapshotWithResources(snapshot) {
|
|
89
|
-
const { url,
|
|
86
|
+
const { url, devices, resourceDiscoveryTimeout, cookies } = snapshot;
|
|
90
87
|
const resources = await (0, resources_js_1.collectResources)({
|
|
91
88
|
url,
|
|
92
|
-
|
|
89
|
+
devices,
|
|
93
90
|
resourceDiscoveryTimeout,
|
|
94
91
|
cookies,
|
|
95
|
-
scaleRatio,
|
|
96
92
|
});
|
|
97
93
|
if (context_js_1.debug) {
|
|
98
94
|
output_1.default.normal(`Collected resources for snapshot: ${snapshot.name}`);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bdy",
|
|
3
3
|
"preferGlobal": false,
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.9.1-dev",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"scripts": {
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
"jsonwebtoken": "9.0.2",
|
|
32
32
|
"mime-db": "1.52.0",
|
|
33
33
|
"mime-types": "2.1.35",
|
|
34
|
-
"punycode.js": "2.3.1",
|
|
35
34
|
"netmask": "2.0.2",
|
|
36
35
|
"node-fetch": "3.3.2",
|
|
37
36
|
"node-forge": "1.3.1",
|
|
38
37
|
"path-is-inside": "1.0.2",
|
|
39
38
|
"pino": "8.20.0",
|
|
39
|
+
"punycode.js": "2.3.1",
|
|
40
40
|
"puppeteer-core": "23.6.0",
|
|
41
41
|
"range-parser": "1.2.1",
|
|
42
42
|
"socket.io-client": "4.7.5",
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
"undici": "6.19.2",
|
|
46
46
|
"uuid": "10.0.0",
|
|
47
47
|
"which": "4.0.0",
|
|
48
|
-
"ws": "8.18.0"
|
|
48
|
+
"ws": "8.18.0",
|
|
49
|
+
"zod": "3.24.2"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@eslint/js": "9.13.0",
|
|
@@ -64,9 +65,9 @@
|
|
|
64
65
|
"eslint-config-prettier": "9.1.0",
|
|
65
66
|
"globals": "15.11.0",
|
|
66
67
|
"prettier": "3.3.3",
|
|
68
|
+
"rollup": "4.24.2",
|
|
67
69
|
"rollup-plugin-natives": "0.7.8",
|
|
68
70
|
"typescript": "5.6.3",
|
|
69
|
-
"typescript-eslint": "8.11.0"
|
|
70
|
-
"rollup": "4.24.2"
|
|
71
|
+
"typescript-eslint": "8.11.0"
|
|
71
72
|
}
|
|
72
73
|
}
|