@agent-infra/browser 0.0.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/LICENSE +201 -0
- package/README.md +74 -0
- package/dist/base-browser.d.ts +89 -0
- package/dist/base-browser.d.ts.map +1 -0
- package/dist/base-browser.js +146 -0
- package/dist/base-browser.js.map +1 -0
- package/dist/base-browser.mjs +114 -0
- package/dist/base-browser.mjs.map +1 -0
- package/dist/browser-finder.d.ts +59 -0
- package/dist/browser-finder.d.ts.map +1 -0
- package/dist/browser-finder.js +148 -0
- package/dist/browser-finder.js.map +1 -0
- package/dist/browser-finder.mjs +116 -0
- package/dist/browser-finder.mjs.map +1 -0
- package/dist/browser-finder.test.d.ts +2 -0
- package/dist/browser-finder.test.d.ts.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +101 -0
- package/dist/index.mjs +9 -0
- package/dist/local-browser.d.ts +23 -0
- package/dist/local-browser.d.ts.map +1 -0
- package/dist/local-browser.js +110 -0
- package/dist/local-browser.js.map +1 -0
- package/dist/local-browser.mjs +78 -0
- package/dist/local-browser.mjs.map +1 -0
- package/dist/remote-browser.d.ts +49 -0
- package/dist/remote-browser.d.ts.map +1 -0
- package/dist/remote-browser.js +85 -0
- package/dist/remote-browser.js.map +1 -0
- package/dist/remote-browser.mjs +53 -0
- package/dist/remote-browser.mjs.map +1 -0
- package/dist/types.d.ts +132 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +38 -0
- package/dist/types.mjs +7 -0
- package/package.json +39 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-browser.mjs","sources":["webpack://@agent-infra/browser/./src/base-browser.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/*\n * Copyright (c) 2025 Bytedance, Inc. and its affiliates.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport * as puppeteer from 'puppeteer-core';\nimport { Logger, defaultLogger } from '@agent-infra/logger';\nimport {\n BrowserInterface,\n EvaluateOnNewPageOptions,\n LaunchOptions,\n Page,\n} from './types';\n\n/**\n * Configuration options for the BaseBrowser class\n * @interface BaseBrowserOptions\n * @property {Logger} [logger] - Custom logger instance to use for browser logging\n */\nexport interface BaseBrowserOptions {\n logger?: Logger;\n}\n\n/**\n * Abstract base class that implements common browser automation functionality\n * Provides a foundation for specific browser implementations with shared capabilities\n * @abstract\n * @implements {BrowserInterface}\n */\nexport abstract class BaseBrowser implements BrowserInterface {\n /**\n * The underlying Puppeteer browser instance\n * @protected\n */\n protected browser: puppeteer.Browser | null = null;\n\n /**\n * Logger instance for browser-related logging\n * @protected\n */\n protected logger: Logger;\n\n /**\n * Reference to the currently active browser page\n * @protected\n */\n protected activePage: Page | null = null;\n\n /**\n * Creates an instance of BaseBrowser\n * @param {BaseBrowserOptions} [options] - Configuration options\n */\n constructor(options?: BaseBrowserOptions) {\n this.logger = options?.logger ?? defaultLogger;\n this.logger.info('Browser Options:', options);\n }\n\n /**\n * Get the underlying Puppeteer browser instance\n * @throws Error if browser is not launched\n\n * @returns {puppeteer.Browser} Puppeteer browser instance\n */\n getBrowser(): puppeteer.Browser {\n if (!this.browser) {\n throw new Error('Browser not launched');\n }\n return this.browser;\n }\n\n /**\n * Sets up listeners for browser page events\n * Tracks page creation and updates active page reference\n * @protected\n */\n protected async setupPageListener() {\n if (!this.browser) return;\n\n this.browser.on('targetcreated', async (target) => {\n const page = await target.page();\n if (page) {\n this.logger.info('New page created:', await page.url());\n this.activePage = page;\n\n page.once('close', () => {\n if (this.activePage === page) {\n this.activePage = null;\n }\n });\n\n page.once('error', () => {\n if (this.activePage === page) {\n this.activePage = null;\n }\n });\n }\n });\n }\n\n /**\n * Launches the browser with specified options\n * @abstract\n * @param {LaunchOptions} [options] - Browser launch configuration options\n * @returns {Promise<void>} Promise that resolves when browser is launched\n */\n abstract launch(options?: LaunchOptions): Promise<void>;\n\n /**\n * Closes the browser instance and cleans up resources\n * @returns {Promise<void>} Promise that resolves when browser is closed\n * @throws {Error} If browser fails to close properly\n */\n async close(): Promise<void> {\n this.logger.info('Closing browser');\n try {\n await this.browser?.close();\n this.browser = null;\n this.logger.success('Browser closed successfully');\n } catch (error) {\n this.logger.error('Failed to close browser:', error);\n throw error;\n }\n }\n\n /**\n * Creates a new page, navigates to the specified URL, executes a function in the page context, and returns the result\n * This method is inspired and modified from https://github.com/egoist/local-web-search/blob/04608ed09aa103e2fff6402c72ca12edfb692d19/src/browser.ts#L74\n * @template T - Type of parameters passed to the page function\n * @template R - Return type of the page function\n * @param {EvaluateOnNewPageOptions<T, R>} options - Configuration options for the page evaluation\n * @returns {Promise<R | null>} Promise resolving to the result of the page function or null\n * @throws {Error} If page creation or evaluation fails\n */\n async evaluateOnNewPage<T extends any[], R>(\n options: EvaluateOnNewPageOptions<T, R>,\n ): Promise<R | null> {\n const {\n url,\n pageFunction,\n pageFunctionParams,\n beforePageLoad,\n afterPageLoad,\n beforeSendResult,\n waitForOptions,\n } = options;\n const page = await this.browser!.newPage();\n try {\n await beforePageLoad?.(page);\n await page.goto(url, {\n waitUntil: 'networkidle2',\n ...waitForOptions,\n });\n await afterPageLoad?.(page);\n const _window = await page.evaluateHandle(() => window);\n const result = await page.evaluate(\n pageFunction,\n _window,\n ...pageFunctionParams,\n );\n await beforeSendResult?.(page, result);\n await _window.dispose();\n await page.close();\n return result;\n } catch (error) {\n await page.close();\n throw error;\n }\n }\n\n /**\n * Creates a new browser page\n * @returns {Promise<Page>} Promise resolving to the newly created page\n * @throws {Error} If browser is not launched or page creation fails\n */\n async createPage(): Promise<Page> {\n if (!this.browser) {\n this.logger.error('No active browser');\n throw new Error('Browser not launched');\n }\n const page = await this.browser.newPage();\n return page;\n }\n\n /**\n * Gets the currently active page or finds an active page if none is currently tracked\n * If no active pages exist, creates a new page\n * @returns {Promise<Page>} Promise resolving to the active page\n * @throws {Error} If browser is not launched or no active page can be found/created\n */\n async getActivePage(): Promise<Page> {\n if (!this.browser) {\n throw new Error('Browser not launched');\n }\n\n // If activePage exists and is still available, return directly\n if (this.activePage) {\n try {\n // Verify that the page is still available\n await this.activePage.evaluate(() => document.readyState);\n return this.activePage;\n } catch (e) {\n this.logger.warn('Active page no longer available:', e);\n this.activePage = null;\n }\n }\n\n // Get all pages and find the last active page\n const pages = await this.browser.pages();\n\n if (pages.length === 0) {\n this.activePage = await this.createPage();\n return this.activePage;\n }\n\n // Find the last responding page\n for (let i = pages.length - 1; i >= 0; i--) {\n const page = pages[i];\n try {\n await page.evaluate(() => document.readyState);\n this.activePage = page;\n return page;\n } catch (e) {\n continue;\n }\n }\n\n throw new Error('No active page found');\n }\n}\n"],"names":["BaseBrowser","Error","target","page","_this_browser","error","options","url","pageFunction","pageFunctionParams","beforePageLoad","afterPageLoad","beforeSendResult","waitForOptions","_window","window","result","document","e","pages","i","defaultLogger"],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The following code is modified based on
|
|
3
|
+
* https://github.com/egoist/local-web-search/blob/main/src/find-browser.ts
|
|
4
|
+
*
|
|
5
|
+
* MIT Licensed
|
|
6
|
+
* Copyright (c) 2025 ChatWise (https://chatwise.app) <kevin@chatwise.app>
|
|
7
|
+
* https://github.com/egoist/local-web-search/blob/main/LICENSE
|
|
8
|
+
*/
|
|
9
|
+
import { Logger } from '@agent-infra/logger';
|
|
10
|
+
/**
|
|
11
|
+
* Class responsible for finding and managing browser installations
|
|
12
|
+
* Detects installed browsers and their profiles across different platforms
|
|
13
|
+
*/
|
|
14
|
+
export declare class BrowserFinder {
|
|
15
|
+
/**
|
|
16
|
+
* Logger instance for diagnostic output
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
private logger;
|
|
20
|
+
/**
|
|
21
|
+
* Creates a new BrowserFinder instance
|
|
22
|
+
* @param {Logger} [logger] - Optional custom logger
|
|
23
|
+
*/
|
|
24
|
+
constructor(logger?: Logger);
|
|
25
|
+
/**
|
|
26
|
+
* Getter that returns the list of supported browsers with their platform-specific paths
|
|
27
|
+
* @returns {Browser[]} Array of browser configurations
|
|
28
|
+
* @private
|
|
29
|
+
*/
|
|
30
|
+
private get browsers();
|
|
31
|
+
/**
|
|
32
|
+
* Find a specific browser or the first available browser
|
|
33
|
+
* @param {string} [name] - Optional browser name to find
|
|
34
|
+
* @returns {{ executable: string; userDataDir: string }} Browser executable and user data paths
|
|
35
|
+
* @throws {Error} If no supported browser is found or the platform is unsupported
|
|
36
|
+
*/
|
|
37
|
+
findBrowser(name?: string): {
|
|
38
|
+
executable: string;
|
|
39
|
+
userDataDir: string;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Get browser profiles for a specific browser
|
|
43
|
+
* Reads the Local State file to extract profile information
|
|
44
|
+
* @param {string} [browserName] - Optional browser name to get profiles for
|
|
45
|
+
* @returns {Array<{ displayName: string; path: string }>} Array of profile objects with display names and paths
|
|
46
|
+
*/
|
|
47
|
+
getBrowserProfiles(browserName?: string): Array<{
|
|
48
|
+
displayName: string;
|
|
49
|
+
path: string;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Legacy method for backwards compatibility
|
|
53
|
+
* Finds Chrome browser executable path
|
|
54
|
+
* @deprecated Use findBrowser instead
|
|
55
|
+
* @returns {string | null} Chrome executable path or null if not found
|
|
56
|
+
*/
|
|
57
|
+
findChrome(): string | null;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=browser-finder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-finder.d.ts","sourceRoot":"","sources":["../src/browser-finder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,MAAM,EAAiB,MAAM,qBAAqB,CAAC;AAsC5D;;;GAGG;AACH,qBAAa,aAAa;IACxB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAS;IAEvB;;;OAGG;gBACS,MAAM,CAAC,EAAE,MAAM;IAI3B;;;;OAIG;IACH,OAAO,KAAK,QAAQ,GAiDnB;IAED;;;;;OAKG;IACH,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG;QAC1B,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB;IAuCD;;;;;OAKG;IACH,kBAAkB,CAChB,WAAW,CAAC,EAAE,MAAM,GACnB,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAoB/C;;;;;OAKG;IACH,UAAU,IAAI,MAAM,GAAG,IAAI;CAQ5B"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
var __webpack_require__ = {};
|
|
7
|
+
(()=>{
|
|
8
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
9
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: definition[key]
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
})();
|
|
15
|
+
(()=>{
|
|
16
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
17
|
+
})();
|
|
18
|
+
(()=>{
|
|
19
|
+
__webpack_require__.r = function(exports1) {
|
|
20
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
21
|
+
value: 'Module'
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
24
|
+
value: true
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
})();
|
|
28
|
+
var __webpack_exports__ = {};
|
|
29
|
+
__webpack_require__.r(__webpack_exports__);
|
|
30
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
31
|
+
BrowserFinder: ()=>BrowserFinder
|
|
32
|
+
});
|
|
33
|
+
const external_fs_namespaceObject = require("fs");
|
|
34
|
+
const external_path_namespaceObject = require("path");
|
|
35
|
+
const external_os_namespaceObject = require("os");
|
|
36
|
+
const logger_namespaceObject = require("@agent-infra/logger");
|
|
37
|
+
function _define_property(obj, key, value) {
|
|
38
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
39
|
+
value: value,
|
|
40
|
+
enumerable: true,
|
|
41
|
+
configurable: true,
|
|
42
|
+
writable: true
|
|
43
|
+
});
|
|
44
|
+
else obj[key] = value;
|
|
45
|
+
return obj;
|
|
46
|
+
}
|
|
47
|
+
class BrowserFinder {
|
|
48
|
+
get browsers() {
|
|
49
|
+
const HOME_DIR = external_os_namespaceObject.homedir();
|
|
50
|
+
const LOCAL_APP_DATA = process.env.LOCALAPPDATA;
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
name: 'Chromium',
|
|
54
|
+
executable: {
|
|
55
|
+
win32: 'C:\\Program Files\\Chromium\\Application\\chrome.exe',
|
|
56
|
+
darwin: '/Applications/Chromium.app/Contents/MacOS/Chromium',
|
|
57
|
+
linux: '/usr/bin/chromium'
|
|
58
|
+
},
|
|
59
|
+
userDataDir: {
|
|
60
|
+
win32: `${LOCAL_APP_DATA}\\Chromium\\User Data`,
|
|
61
|
+
darwin: `${HOME_DIR}/Library/Application Support/Chromium`,
|
|
62
|
+
linux: `${HOME_DIR}/.config/chromium`
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'Google Chrome',
|
|
67
|
+
executable: {
|
|
68
|
+
win32: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
|
|
69
|
+
darwin: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
|
70
|
+
linux: '/usr/bin/google-chrome'
|
|
71
|
+
},
|
|
72
|
+
userDataDir: {
|
|
73
|
+
win32: `${LOCAL_APP_DATA}\\Google\\Chrome\\User Data`,
|
|
74
|
+
darwin: `${HOME_DIR}/Library/Application Support/Google/Chrome`,
|
|
75
|
+
linux: `${HOME_DIR}/.config/google-chrome`
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'Google Chrome Canary',
|
|
80
|
+
executable: {
|
|
81
|
+
win32: 'C:\\Program Files\\Google\\Chrome Canary\\Application\\chrome.exe',
|
|
82
|
+
darwin: '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
|
|
83
|
+
linux: '/usr/bin/google-chrome-canary'
|
|
84
|
+
},
|
|
85
|
+
userDataDir: {
|
|
86
|
+
win32: `${LOCAL_APP_DATA}\\Google\\Chrome Canary\\User Data`,
|
|
87
|
+
darwin: `${HOME_DIR}/Library/Application Support/Google/Chrome Canary`,
|
|
88
|
+
linux: `${HOME_DIR}/.config/google-chrome-canary`
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
findBrowser(name) {
|
|
94
|
+
const platform = process.platform;
|
|
95
|
+
this.logger.info('Finding browser on platform:', platform);
|
|
96
|
+
if ('darwin' !== platform && 'win32' !== platform && 'linux' !== platform) {
|
|
97
|
+
const error = new Error(`Unsupported platform: ${platform}`);
|
|
98
|
+
this.logger.error(error.message);
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
const browser = name ? this.browsers.find((b)=>b.name === name && external_fs_namespaceObject.existsSync(b.executable[platform])) : this.browsers.find((b)=>external_fs_namespaceObject.existsSync(b.executable[platform]));
|
|
102
|
+
this.logger.log('browser', browser);
|
|
103
|
+
if (!browser) {
|
|
104
|
+
const error = name ? new Error(`Cannot find browser: ${name}`) : new Error('Cannot find a supported browser on your system. Please install Chrome, Edge, or Brave.');
|
|
105
|
+
this.logger.error(error.message);
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
const result = {
|
|
109
|
+
executable: browser.executable[platform],
|
|
110
|
+
userDataDir: browser.userDataDir[platform]
|
|
111
|
+
};
|
|
112
|
+
this.logger.success(`Found browser: ${browser.name}`);
|
|
113
|
+
this.logger.info('Browser details:', result);
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
getBrowserProfiles(browserName) {
|
|
117
|
+
const browser = this.findBrowser(browserName);
|
|
118
|
+
try {
|
|
119
|
+
const localState = JSON.parse(external_fs_namespaceObject.readFileSync(external_path_namespaceObject.join(browser.userDataDir, 'Local State'), 'utf8'));
|
|
120
|
+
const profileInfo = localState.profile.info_cache;
|
|
121
|
+
return Object.entries(profileInfo).map(([profileName, info])=>({
|
|
122
|
+
displayName: info.name,
|
|
123
|
+
path: external_path_namespaceObject.join(browser.userDataDir, profileName)
|
|
124
|
+
}));
|
|
125
|
+
} catch (error) {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
findChrome() {
|
|
130
|
+
try {
|
|
131
|
+
const { executable } = this.findBrowser('Google Chrome');
|
|
132
|
+
return executable;
|
|
133
|
+
} catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
constructor(logger){
|
|
138
|
+
_define_property(this, "logger", void 0);
|
|
139
|
+
this.logger = logger ?? logger_namespaceObject.defaultLogger;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
var __webpack_export_target__ = exports;
|
|
143
|
+
for(var __webpack_i__ in __webpack_exports__)__webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
144
|
+
if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', {
|
|
145
|
+
value: true
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
//# sourceMappingURL=browser-finder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-finder.js","sources":["webpack://@agent-infra/browser/./src/browser-finder.ts"],"sourcesContent":["/**\n * The following code is modified based on\n * https://github.com/egoist/local-web-search/blob/main/src/find-browser.ts\n *\n * MIT Licensed\n * Copyright (c) 2025 ChatWise (https://chatwise.app) <kevin@chatwise.app>\n * https://github.com/egoist/local-web-search/blob/main/LICENSE\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { Logger, defaultLogger } from '@agent-infra/logger';\n\n/**\n * Interface defining browser locations and configurations\n * Contains paths and settings for different operating systems\n * @interface Browser\n */\ninterface Browser {\n /**\n * Browser name identifier\n */\n name: string;\n\n /**\n * Executable paths by platform\n * @property {string} win32 - Windows executable path\n * @property {string} darwin - macOS executable path\n * @property {string} linux - Linux executable path\n */\n executable: {\n win32: string;\n darwin: string;\n linux: string;\n };\n\n /**\n * User data directory paths by platform\n * @property {string} win32 - Windows user data directory\n * @property {string} darwin - macOS user data directory\n * @property {string} linux - Linux user data directory\n */\n userDataDir: {\n win32: string;\n darwin: string;\n linux: string;\n };\n}\n\n/**\n * Class responsible for finding and managing browser installations\n * Detects installed browsers and their profiles across different platforms\n */\nexport class BrowserFinder {\n /**\n * Logger instance for diagnostic output\n * @private\n */\n private logger: Logger;\n\n /**\n * Creates a new BrowserFinder instance\n * @param {Logger} [logger] - Optional custom logger\n */\n constructor(logger?: Logger) {\n this.logger = logger ?? defaultLogger;\n }\n\n /**\n * Getter that returns the list of supported browsers with their platform-specific paths\n * @returns {Browser[]} Array of browser configurations\n * @private\n */\n private get browsers(): Browser[] {\n // Get HOME_DIR inside the getter to ensure it's always current\n const HOME_DIR = os.homedir();\n const LOCAL_APP_DATA = process.env.LOCALAPPDATA;\n\n return [\n {\n name: 'Chromium',\n executable: {\n win32: 'C:\\\\Program Files\\\\Chromium\\\\Application\\\\chrome.exe',\n darwin: '/Applications/Chromium.app/Contents/MacOS/Chromium',\n linux: '/usr/bin/chromium',\n },\n userDataDir: {\n win32: `${LOCAL_APP_DATA}\\\\Chromium\\\\User Data`,\n darwin: `${HOME_DIR}/Library/Application Support/Chromium`,\n linux: `${HOME_DIR}/.config/chromium`,\n },\n },\n {\n name: 'Google Chrome',\n executable: {\n win32: 'C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe',\n darwin:\n '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',\n linux: '/usr/bin/google-chrome',\n },\n userDataDir: {\n win32: `${LOCAL_APP_DATA}\\\\Google\\\\Chrome\\\\User Data`,\n darwin: `${HOME_DIR}/Library/Application Support/Google/Chrome`,\n linux: `${HOME_DIR}/.config/google-chrome`,\n },\n },\n {\n name: 'Google Chrome Canary',\n executable: {\n win32:\n 'C:\\\\Program Files\\\\Google\\\\Chrome Canary\\\\Application\\\\chrome.exe',\n darwin:\n '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',\n linux: '/usr/bin/google-chrome-canary',\n },\n userDataDir: {\n win32: `${LOCAL_APP_DATA}\\\\Google\\\\Chrome Canary\\\\User Data`,\n darwin: `${HOME_DIR}/Library/Application Support/Google/Chrome Canary`,\n linux: `${HOME_DIR}/.config/google-chrome-canary`,\n },\n },\n ];\n }\n\n /**\n * Find a specific browser or the first available browser\n * @param {string} [name] - Optional browser name to find\n * @returns {{ executable: string; userDataDir: string }} Browser executable and user data paths\n * @throws {Error} If no supported browser is found or the platform is unsupported\n */\n findBrowser(name?: string): {\n executable: string;\n userDataDir: string;\n } {\n const platform = process.platform;\n this.logger.info('Finding browser on platform:', platform);\n\n if (platform !== 'darwin' && platform !== 'win32' && platform !== 'linux') {\n const error = new Error(`Unsupported platform: ${platform}`);\n this.logger.error(error.message);\n throw error;\n }\n\n const browser = name\n ? this.browsers.find(\n (b) => b.name === name && fs.existsSync(b.executable[platform]),\n )\n : this.browsers.find((b) => fs.existsSync(b.executable[platform]));\n\n this.logger.log('browser', browser);\n\n if (!browser) {\n const error = name\n ? new Error(`Cannot find browser: ${name}`)\n : new Error(\n 'Cannot find a supported browser on your system. Please install Chrome, Edge, or Brave.',\n );\n this.logger.error(error.message);\n throw error;\n }\n\n const result = {\n executable: browser.executable[platform],\n userDataDir: browser.userDataDir[platform],\n };\n\n this.logger.success(`Found browser: ${browser.name}`);\n this.logger.info('Browser details:', result);\n\n return result;\n }\n\n /**\n * Get browser profiles for a specific browser\n * Reads the Local State file to extract profile information\n * @param {string} [browserName] - Optional browser name to get profiles for\n * @returns {Array<{ displayName: string; path: string }>} Array of profile objects with display names and paths\n */\n getBrowserProfiles(\n browserName?: string,\n ): Array<{ displayName: string; path: string }> {\n const browser = this.findBrowser(browserName);\n\n try {\n const localState = JSON.parse(\n fs.readFileSync(path.join(browser.userDataDir, 'Local State'), 'utf8'),\n );\n const profileInfo = localState.profile.info_cache;\n\n return Object.entries(profileInfo).map(\n ([profileName, info]: [string, any]) => ({\n displayName: info.name,\n path: path.join(browser.userDataDir, profileName),\n }),\n );\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Legacy method for backwards compatibility\n * Finds Chrome browser executable path\n * @deprecated Use findBrowser instead\n * @returns {string | null} Chrome executable path or null if not found\n */\n findChrome(): string | null {\n try {\n const { executable } = this.findBrowser('Google Chrome');\n return executable;\n } catch {\n return null;\n }\n }\n}\n"],"names":["BrowserFinder","HOME_DIR","os","LOCAL_APP_DATA","process","name","platform","error","Error","browser","b","fs","result","browserName","localState","JSON","path","profileInfo","Object","profileName","info","executable","logger","defaultLogger"],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import * as __WEBPACK_EXTERNAL_MODULE_fs__ from "fs";
|
|
6
|
+
import * as __WEBPACK_EXTERNAL_MODULE_path__ from "path";
|
|
7
|
+
import * as __WEBPACK_EXTERNAL_MODULE_os__ from "os";
|
|
8
|
+
import * as __WEBPACK_EXTERNAL_MODULE__agent_infra_logger_ddae3da2__ from "@agent-infra/logger";
|
|
9
|
+
function _define_property(obj, key, value) {
|
|
10
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
11
|
+
value: value,
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
writable: true
|
|
15
|
+
});
|
|
16
|
+
else obj[key] = value;
|
|
17
|
+
return obj;
|
|
18
|
+
}
|
|
19
|
+
class BrowserFinder {
|
|
20
|
+
get browsers() {
|
|
21
|
+
const HOME_DIR = __WEBPACK_EXTERNAL_MODULE_os__.homedir();
|
|
22
|
+
const LOCAL_APP_DATA = process.env.LOCALAPPDATA;
|
|
23
|
+
return [
|
|
24
|
+
{
|
|
25
|
+
name: 'Chromium',
|
|
26
|
+
executable: {
|
|
27
|
+
win32: 'C:\\Program Files\\Chromium\\Application\\chrome.exe',
|
|
28
|
+
darwin: '/Applications/Chromium.app/Contents/MacOS/Chromium',
|
|
29
|
+
linux: '/usr/bin/chromium'
|
|
30
|
+
},
|
|
31
|
+
userDataDir: {
|
|
32
|
+
win32: `${LOCAL_APP_DATA}\\Chromium\\User Data`,
|
|
33
|
+
darwin: `${HOME_DIR}/Library/Application Support/Chromium`,
|
|
34
|
+
linux: `${HOME_DIR}/.config/chromium`
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'Google Chrome',
|
|
39
|
+
executable: {
|
|
40
|
+
win32: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
|
|
41
|
+
darwin: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
|
42
|
+
linux: '/usr/bin/google-chrome'
|
|
43
|
+
},
|
|
44
|
+
userDataDir: {
|
|
45
|
+
win32: `${LOCAL_APP_DATA}\\Google\\Chrome\\User Data`,
|
|
46
|
+
darwin: `${HOME_DIR}/Library/Application Support/Google/Chrome`,
|
|
47
|
+
linux: `${HOME_DIR}/.config/google-chrome`
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'Google Chrome Canary',
|
|
52
|
+
executable: {
|
|
53
|
+
win32: 'C:\\Program Files\\Google\\Chrome Canary\\Application\\chrome.exe',
|
|
54
|
+
darwin: '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
|
|
55
|
+
linux: '/usr/bin/google-chrome-canary'
|
|
56
|
+
},
|
|
57
|
+
userDataDir: {
|
|
58
|
+
win32: `${LOCAL_APP_DATA}\\Google\\Chrome Canary\\User Data`,
|
|
59
|
+
darwin: `${HOME_DIR}/Library/Application Support/Google/Chrome Canary`,
|
|
60
|
+
linux: `${HOME_DIR}/.config/google-chrome-canary`
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
findBrowser(name) {
|
|
66
|
+
const platform = process.platform;
|
|
67
|
+
this.logger.info('Finding browser on platform:', platform);
|
|
68
|
+
if ('darwin' !== platform && 'win32' !== platform && 'linux' !== platform) {
|
|
69
|
+
const error = new Error(`Unsupported platform: ${platform}`);
|
|
70
|
+
this.logger.error(error.message);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
const browser = name ? this.browsers.find((b)=>b.name === name && __WEBPACK_EXTERNAL_MODULE_fs__.existsSync(b.executable[platform])) : this.browsers.find((b)=>__WEBPACK_EXTERNAL_MODULE_fs__.existsSync(b.executable[platform]));
|
|
74
|
+
this.logger.log('browser', browser);
|
|
75
|
+
if (!browser) {
|
|
76
|
+
const error = name ? new Error(`Cannot find browser: ${name}`) : new Error('Cannot find a supported browser on your system. Please install Chrome, Edge, or Brave.');
|
|
77
|
+
this.logger.error(error.message);
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
const result = {
|
|
81
|
+
executable: browser.executable[platform],
|
|
82
|
+
userDataDir: browser.userDataDir[platform]
|
|
83
|
+
};
|
|
84
|
+
this.logger.success(`Found browser: ${browser.name}`);
|
|
85
|
+
this.logger.info('Browser details:', result);
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
getBrowserProfiles(browserName) {
|
|
89
|
+
const browser = this.findBrowser(browserName);
|
|
90
|
+
try {
|
|
91
|
+
const localState = JSON.parse(__WEBPACK_EXTERNAL_MODULE_fs__.readFileSync(__WEBPACK_EXTERNAL_MODULE_path__.join(browser.userDataDir, 'Local State'), 'utf8'));
|
|
92
|
+
const profileInfo = localState.profile.info_cache;
|
|
93
|
+
return Object.entries(profileInfo).map(([profileName, info])=>({
|
|
94
|
+
displayName: info.name,
|
|
95
|
+
path: __WEBPACK_EXTERNAL_MODULE_path__.join(browser.userDataDir, profileName)
|
|
96
|
+
}));
|
|
97
|
+
} catch (error) {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
findChrome() {
|
|
102
|
+
try {
|
|
103
|
+
const { executable } = this.findBrowser('Google Chrome');
|
|
104
|
+
return executable;
|
|
105
|
+
} catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
constructor(logger){
|
|
110
|
+
_define_property(this, "logger", void 0);
|
|
111
|
+
this.logger = logger ?? __WEBPACK_EXTERNAL_MODULE__agent_infra_logger_ddae3da2__.defaultLogger;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export { BrowserFinder };
|
|
115
|
+
|
|
116
|
+
//# sourceMappingURL=browser-finder.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-finder.mjs","sources":["webpack://@agent-infra/browser/./src/browser-finder.ts"],"sourcesContent":["/**\n * The following code is modified based on\n * https://github.com/egoist/local-web-search/blob/main/src/find-browser.ts\n *\n * MIT Licensed\n * Copyright (c) 2025 ChatWise (https://chatwise.app) <kevin@chatwise.app>\n * https://github.com/egoist/local-web-search/blob/main/LICENSE\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { Logger, defaultLogger } from '@agent-infra/logger';\n\n/**\n * Interface defining browser locations and configurations\n * Contains paths and settings for different operating systems\n * @interface Browser\n */\ninterface Browser {\n /**\n * Browser name identifier\n */\n name: string;\n\n /**\n * Executable paths by platform\n * @property {string} win32 - Windows executable path\n * @property {string} darwin - macOS executable path\n * @property {string} linux - Linux executable path\n */\n executable: {\n win32: string;\n darwin: string;\n linux: string;\n };\n\n /**\n * User data directory paths by platform\n * @property {string} win32 - Windows user data directory\n * @property {string} darwin - macOS user data directory\n * @property {string} linux - Linux user data directory\n */\n userDataDir: {\n win32: string;\n darwin: string;\n linux: string;\n };\n}\n\n/**\n * Class responsible for finding and managing browser installations\n * Detects installed browsers and their profiles across different platforms\n */\nexport class BrowserFinder {\n /**\n * Logger instance for diagnostic output\n * @private\n */\n private logger: Logger;\n\n /**\n * Creates a new BrowserFinder instance\n * @param {Logger} [logger] - Optional custom logger\n */\n constructor(logger?: Logger) {\n this.logger = logger ?? defaultLogger;\n }\n\n /**\n * Getter that returns the list of supported browsers with their platform-specific paths\n * @returns {Browser[]} Array of browser configurations\n * @private\n */\n private get browsers(): Browser[] {\n // Get HOME_DIR inside the getter to ensure it's always current\n const HOME_DIR = os.homedir();\n const LOCAL_APP_DATA = process.env.LOCALAPPDATA;\n\n return [\n {\n name: 'Chromium',\n executable: {\n win32: 'C:\\\\Program Files\\\\Chromium\\\\Application\\\\chrome.exe',\n darwin: '/Applications/Chromium.app/Contents/MacOS/Chromium',\n linux: '/usr/bin/chromium',\n },\n userDataDir: {\n win32: `${LOCAL_APP_DATA}\\\\Chromium\\\\User Data`,\n darwin: `${HOME_DIR}/Library/Application Support/Chromium`,\n linux: `${HOME_DIR}/.config/chromium`,\n },\n },\n {\n name: 'Google Chrome',\n executable: {\n win32: 'C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe',\n darwin:\n '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',\n linux: '/usr/bin/google-chrome',\n },\n userDataDir: {\n win32: `${LOCAL_APP_DATA}\\\\Google\\\\Chrome\\\\User Data`,\n darwin: `${HOME_DIR}/Library/Application Support/Google/Chrome`,\n linux: `${HOME_DIR}/.config/google-chrome`,\n },\n },\n {\n name: 'Google Chrome Canary',\n executable: {\n win32:\n 'C:\\\\Program Files\\\\Google\\\\Chrome Canary\\\\Application\\\\chrome.exe',\n darwin:\n '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',\n linux: '/usr/bin/google-chrome-canary',\n },\n userDataDir: {\n win32: `${LOCAL_APP_DATA}\\\\Google\\\\Chrome Canary\\\\User Data`,\n darwin: `${HOME_DIR}/Library/Application Support/Google/Chrome Canary`,\n linux: `${HOME_DIR}/.config/google-chrome-canary`,\n },\n },\n ];\n }\n\n /**\n * Find a specific browser or the first available browser\n * @param {string} [name] - Optional browser name to find\n * @returns {{ executable: string; userDataDir: string }} Browser executable and user data paths\n * @throws {Error} If no supported browser is found or the platform is unsupported\n */\n findBrowser(name?: string): {\n executable: string;\n userDataDir: string;\n } {\n const platform = process.platform;\n this.logger.info('Finding browser on platform:', platform);\n\n if (platform !== 'darwin' && platform !== 'win32' && platform !== 'linux') {\n const error = new Error(`Unsupported platform: ${platform}`);\n this.logger.error(error.message);\n throw error;\n }\n\n const browser = name\n ? this.browsers.find(\n (b) => b.name === name && fs.existsSync(b.executable[platform]),\n )\n : this.browsers.find((b) => fs.existsSync(b.executable[platform]));\n\n this.logger.log('browser', browser);\n\n if (!browser) {\n const error = name\n ? new Error(`Cannot find browser: ${name}`)\n : new Error(\n 'Cannot find a supported browser on your system. Please install Chrome, Edge, or Brave.',\n );\n this.logger.error(error.message);\n throw error;\n }\n\n const result = {\n executable: browser.executable[platform],\n userDataDir: browser.userDataDir[platform],\n };\n\n this.logger.success(`Found browser: ${browser.name}`);\n this.logger.info('Browser details:', result);\n\n return result;\n }\n\n /**\n * Get browser profiles for a specific browser\n * Reads the Local State file to extract profile information\n * @param {string} [browserName] - Optional browser name to get profiles for\n * @returns {Array<{ displayName: string; path: string }>} Array of profile objects with display names and paths\n */\n getBrowserProfiles(\n browserName?: string,\n ): Array<{ displayName: string; path: string }> {\n const browser = this.findBrowser(browserName);\n\n try {\n const localState = JSON.parse(\n fs.readFileSync(path.join(browser.userDataDir, 'Local State'), 'utf8'),\n );\n const profileInfo = localState.profile.info_cache;\n\n return Object.entries(profileInfo).map(\n ([profileName, info]: [string, any]) => ({\n displayName: info.name,\n path: path.join(browser.userDataDir, profileName),\n }),\n );\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Legacy method for backwards compatibility\n * Finds Chrome browser executable path\n * @deprecated Use findBrowser instead\n * @returns {string | null} Chrome executable path or null if not found\n */\n findChrome(): string | null {\n try {\n const { executable } = this.findBrowser('Google Chrome');\n return executable;\n } catch {\n return null;\n }\n }\n}\n"],"names":["BrowserFinder","HOME_DIR","os","LOCAL_APP_DATA","process","name","platform","error","Error","browser","b","fs","result","browserName","localState","JSON","path","profileInfo","Object","profileName","info","executable","logger","defaultLogger"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-finder.test.d.ts","sourceRoot":"","sources":["../src/browser-finder.test.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @agent-infra/browser
|
|
3
|
+
* A browser automation library based on puppeteer-core
|
|
4
|
+
*
|
|
5
|
+
* Main exports:
|
|
6
|
+
* - types: Type definitions for browser interfaces
|
|
7
|
+
* - BrowserFinder: Utility to detect and locate installed browsers
|
|
8
|
+
* - LocalBrowser: Control locally installed browsers
|
|
9
|
+
* - RemoteBrowser: Connect to remote browser instances
|
|
10
|
+
* - BaseBrowser: Abstract base class for browser implementations
|
|
11
|
+
*/
|
|
12
|
+
export * from './types';
|
|
13
|
+
export * from './browser-finder';
|
|
14
|
+
export * from './local-browser';
|
|
15
|
+
export * from './remote-browser';
|
|
16
|
+
export * from './base-browser';
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;GAUG;AACH,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
var __webpack_modules__ = {
|
|
7
|
+
"./base-browser": function(module) {
|
|
8
|
+
module.exports = require("./base-browser.js");
|
|
9
|
+
},
|
|
10
|
+
"./browser-finder": function(module) {
|
|
11
|
+
module.exports = require("./browser-finder.js");
|
|
12
|
+
},
|
|
13
|
+
"./local-browser": function(module) {
|
|
14
|
+
module.exports = require("./local-browser.js");
|
|
15
|
+
},
|
|
16
|
+
"./remote-browser": function(module) {
|
|
17
|
+
module.exports = require("./remote-browser.js");
|
|
18
|
+
},
|
|
19
|
+
"./types": function(module) {
|
|
20
|
+
module.exports = require("./types.js");
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
var __webpack_module_cache__ = {};
|
|
24
|
+
function __webpack_require__(moduleId) {
|
|
25
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
|
26
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
27
|
+
var module = __webpack_module_cache__[moduleId] = {
|
|
28
|
+
exports: {}
|
|
29
|
+
};
|
|
30
|
+
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
31
|
+
return module.exports;
|
|
32
|
+
}
|
|
33
|
+
(()=>{
|
|
34
|
+
__webpack_require__.n = (module)=>{
|
|
35
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
36
|
+
__webpack_require__.d(getter, {
|
|
37
|
+
a: getter
|
|
38
|
+
});
|
|
39
|
+
return getter;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
(()=>{
|
|
43
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
44
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
45
|
+
enumerable: true,
|
|
46
|
+
get: definition[key]
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
50
|
+
(()=>{
|
|
51
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
52
|
+
})();
|
|
53
|
+
(()=>{
|
|
54
|
+
__webpack_require__.r = function(exports1) {
|
|
55
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
56
|
+
value: 'Module'
|
|
57
|
+
});
|
|
58
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
59
|
+
value: true
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
})();
|
|
63
|
+
var __webpack_exports__ = {};
|
|
64
|
+
(()=>{
|
|
65
|
+
__webpack_require__.r(__webpack_exports__);
|
|
66
|
+
var _types__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./types");
|
|
67
|
+
var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
68
|
+
for(var __WEBPACK_IMPORT_KEY__ in _types__WEBPACK_IMPORTED_MODULE_0__)if ("default" !== __WEBPACK_IMPORT_KEY__) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = (function(key) {
|
|
69
|
+
return _types__WEBPACK_IMPORTED_MODULE_0__[key];
|
|
70
|
+
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
71
|
+
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
72
|
+
var _browser_finder__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./browser-finder");
|
|
73
|
+
var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
74
|
+
for(var __WEBPACK_IMPORT_KEY__ in _browser_finder__WEBPACK_IMPORTED_MODULE_1__)if ("default" !== __WEBPACK_IMPORT_KEY__) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = (function(key) {
|
|
75
|
+
return _browser_finder__WEBPACK_IMPORTED_MODULE_1__[key];
|
|
76
|
+
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
77
|
+
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
78
|
+
var _local_browser__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./local-browser");
|
|
79
|
+
var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
80
|
+
for(var __WEBPACK_IMPORT_KEY__ in _local_browser__WEBPACK_IMPORTED_MODULE_2__)if ("default" !== __WEBPACK_IMPORT_KEY__) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = (function(key) {
|
|
81
|
+
return _local_browser__WEBPACK_IMPORTED_MODULE_2__[key];
|
|
82
|
+
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
83
|
+
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
84
|
+
var _remote_browser__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./remote-browser");
|
|
85
|
+
var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
86
|
+
for(var __WEBPACK_IMPORT_KEY__ in _remote_browser__WEBPACK_IMPORTED_MODULE_3__)if ("default" !== __WEBPACK_IMPORT_KEY__) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = (function(key) {
|
|
87
|
+
return _remote_browser__WEBPACK_IMPORTED_MODULE_3__[key];
|
|
88
|
+
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
89
|
+
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
90
|
+
var _base_browser__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./base-browser");
|
|
91
|
+
var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
92
|
+
for(var __WEBPACK_IMPORT_KEY__ in _base_browser__WEBPACK_IMPORTED_MODULE_4__)if ("default" !== __WEBPACK_IMPORT_KEY__) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = (function(key) {
|
|
93
|
+
return _base_browser__WEBPACK_IMPORTED_MODULE_4__[key];
|
|
94
|
+
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
95
|
+
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
96
|
+
})();
|
|
97
|
+
var __webpack_export_target__ = exports;
|
|
98
|
+
for(var __webpack_i__ in __webpack_exports__)__webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
99
|
+
if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', {
|
|
100
|
+
value: true
|
|
101
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
export * from "./types.mjs";
|
|
6
|
+
export * from "./browser-finder.mjs";
|
|
7
|
+
export * from "./local-browser.mjs";
|
|
8
|
+
export * from "./remote-browser.mjs";
|
|
9
|
+
export * from "./base-browser.mjs";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { LaunchOptions } from './types';
|
|
2
|
+
import { BaseBrowser } from './base-browser';
|
|
3
|
+
/**
|
|
4
|
+
* LocalBrowser class for controlling locally installed browsers
|
|
5
|
+
* Extends the BaseBrowser with functionality specific to managing local browser instances
|
|
6
|
+
* @extends BaseBrowser
|
|
7
|
+
*/
|
|
8
|
+
export declare class LocalBrowser extends BaseBrowser {
|
|
9
|
+
/**
|
|
10
|
+
* Browser finder instance to detect and locate installed browsers
|
|
11
|
+
* @private
|
|
12
|
+
*/
|
|
13
|
+
private browserFinder;
|
|
14
|
+
/**
|
|
15
|
+
* Launches a local browser instance with specified options
|
|
16
|
+
* Automatically detects installed browsers if no executable path is provided
|
|
17
|
+
* @param {LaunchOptions} options - Configuration options for launching the browser
|
|
18
|
+
* @returns {Promise<void>} Promise that resolves when the browser is successfully launched
|
|
19
|
+
* @throws {Error} If the browser cannot be launched
|
|
20
|
+
*/
|
|
21
|
+
launch(options?: LaunchOptions): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=local-browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-browser.d.ts","sourceRoot":"","sources":["../src/local-browser.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,WAAW;IAC3C;;;OAGG;IACH,OAAO,CAAC,aAAa,CAAuB;IAE5C;;;;;;OAMG;IACG,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;CA2DzD"}
|