add hw2
This commit is contained in:
		
							
								
								
									
										387
									
								
								node_modules/@puppeteer/browsers/lib/cjs/launch.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										387
									
								
								node_modules/@puppeteer/browsers/lib/cjs/launch.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,387 @@ | ||||
| "use strict"; | ||||
| /** | ||||
|  * @license | ||||
|  * Copyright 2023 Google Inc. | ||||
|  * SPDX-License-Identifier: Apache-2.0 | ||||
|  */ | ||||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||||
|     return (mod && mod.__esModule) ? mod : { "default": mod }; | ||||
| }; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.TimeoutError = exports.Process = exports.WEBDRIVER_BIDI_WEBSOCKET_ENDPOINT_REGEX = exports.CDP_WEBSOCKET_ENDPOINT_REGEX = void 0; | ||||
| exports.computeExecutablePath = computeExecutablePath; | ||||
| exports.computeSystemExecutablePath = computeSystemExecutablePath; | ||||
| exports.launch = launch; | ||||
| exports.isErrorLike = isErrorLike; | ||||
| exports.isErrnoException = isErrnoException; | ||||
| const child_process_1 = __importDefault(require("child_process")); | ||||
| const fs_1 = require("fs"); | ||||
| const os_1 = __importDefault(require("os")); | ||||
| const readline_1 = __importDefault(require("readline")); | ||||
| const browser_data_js_1 = require("./browser-data/browser-data.js"); | ||||
| const Cache_js_1 = require("./Cache.js"); | ||||
| const debug_js_1 = require("./debug.js"); | ||||
| const detectPlatform_js_1 = require("./detectPlatform.js"); | ||||
| const debugLaunch = (0, debug_js_1.debug)('puppeteer:browsers:launcher'); | ||||
| /** | ||||
|  * @public | ||||
|  */ | ||||
| function computeExecutablePath(options) { | ||||
|     return new Cache_js_1.Cache(options.cacheDir).computeExecutablePath(options); | ||||
| } | ||||
| /** | ||||
|  * @public | ||||
|  */ | ||||
| function computeSystemExecutablePath(options) { | ||||
|     options.platform ??= (0, detectPlatform_js_1.detectBrowserPlatform)(); | ||||
|     if (!options.platform) { | ||||
|         throw new Error(`Cannot download a binary for the provided platform: ${os_1.default.platform()} (${os_1.default.arch()})`); | ||||
|     } | ||||
|     const path = (0, browser_data_js_1.resolveSystemExecutablePath)(options.browser, options.platform, options.channel); | ||||
|     try { | ||||
|         (0, fs_1.accessSync)(path); | ||||
|     } | ||||
|     catch { | ||||
|         throw new Error(`Could not find Google Chrome executable for channel '${options.channel}' at '${path}'.`); | ||||
|     } | ||||
|     return path; | ||||
| } | ||||
| /** | ||||
|  * Launches a browser process according to {@link LaunchOptions}. | ||||
|  * | ||||
|  * @public | ||||
|  */ | ||||
| function launch(opts) { | ||||
|     return new Process(opts); | ||||
| } | ||||
| /** | ||||
|  * @public | ||||
|  */ | ||||
| exports.CDP_WEBSOCKET_ENDPOINT_REGEX = /^DevTools listening on (ws:\/\/.*)$/; | ||||
| /** | ||||
|  * @public | ||||
|  */ | ||||
| exports.WEBDRIVER_BIDI_WEBSOCKET_ENDPOINT_REGEX = /^WebDriver BiDi listening on (ws:\/\/.*)$/; | ||||
| const processListeners = new Map(); | ||||
| const dispatchers = { | ||||
|     exit: (...args) => { | ||||
|         processListeners.get('exit')?.forEach(handler => { | ||||
|             return handler(...args); | ||||
|         }); | ||||
|     }, | ||||
|     SIGINT: (...args) => { | ||||
|         processListeners.get('SIGINT')?.forEach(handler => { | ||||
|             return handler(...args); | ||||
|         }); | ||||
|     }, | ||||
|     SIGHUP: (...args) => { | ||||
|         processListeners.get('SIGHUP')?.forEach(handler => { | ||||
|             return handler(...args); | ||||
|         }); | ||||
|     }, | ||||
|     SIGTERM: (...args) => { | ||||
|         processListeners.get('SIGTERM')?.forEach(handler => { | ||||
|             return handler(...args); | ||||
|         }); | ||||
|     }, | ||||
| }; | ||||
| function subscribeToProcessEvent(event, handler) { | ||||
|     const listeners = processListeners.get(event) || []; | ||||
|     if (listeners.length === 0) { | ||||
|         process.on(event, dispatchers[event]); | ||||
|     } | ||||
|     listeners.push(handler); | ||||
|     processListeners.set(event, listeners); | ||||
| } | ||||
| function unsubscribeFromProcessEvent(event, handler) { | ||||
|     const listeners = processListeners.get(event) || []; | ||||
|     const existingListenerIdx = listeners.indexOf(handler); | ||||
|     if (existingListenerIdx === -1) { | ||||
|         return; | ||||
|     } | ||||
|     listeners.splice(existingListenerIdx, 1); | ||||
|     processListeners.set(event, listeners); | ||||
|     if (listeners.length === 0) { | ||||
|         process.off(event, dispatchers[event]); | ||||
|     } | ||||
| } | ||||
| /** | ||||
|  * @public | ||||
|  */ | ||||
| class Process { | ||||
|     #executablePath; | ||||
|     #args; | ||||
|     #browserProcess; | ||||
|     #exited = false; | ||||
|     // The browser process can be closed externally or from the driver process. We | ||||
|     // need to invoke the hooks only once though but we don't know how many times | ||||
|     // we will be invoked. | ||||
|     #hooksRan = false; | ||||
|     #onExitHook = async () => { }; | ||||
|     #browserProcessExiting; | ||||
|     constructor(opts) { | ||||
|         this.#executablePath = opts.executablePath; | ||||
|         this.#args = opts.args ?? []; | ||||
|         opts.pipe ??= false; | ||||
|         opts.dumpio ??= false; | ||||
|         opts.handleSIGINT ??= true; | ||||
|         opts.handleSIGTERM ??= true; | ||||
|         opts.handleSIGHUP ??= true; | ||||
|         // On non-windows platforms, `detached: true` makes child process a | ||||
|         // leader of a new process group, making it possible to kill child | ||||
|         // process tree with `.kill(-pid)` command. @see | ||||
|         // https://nodejs.org/api/child_process.html#child_process_options_detached | ||||
|         opts.detached ??= process.platform !== 'win32'; | ||||
|         const stdio = this.#configureStdio({ | ||||
|             pipe: opts.pipe, | ||||
|             dumpio: opts.dumpio, | ||||
|         }); | ||||
|         const env = opts.env || {}; | ||||
|         debugLaunch(`Launching ${this.#executablePath} ${this.#args.join(' ')}`, { | ||||
|             detached: opts.detached, | ||||
|             env: Object.keys(env).reduce((res, key) => { | ||||
|                 if (key.toLowerCase().startsWith('puppeteer_')) { | ||||
|                     res[key] = env[key]; | ||||
|                 } | ||||
|                 return res; | ||||
|             }, {}), | ||||
|             stdio, | ||||
|         }); | ||||
|         this.#browserProcess = child_process_1.default.spawn(this.#executablePath, this.#args, { | ||||
|             detached: opts.detached, | ||||
|             env, | ||||
|             stdio, | ||||
|         }); | ||||
|         debugLaunch(`Launched ${this.#browserProcess.pid}`); | ||||
|         if (opts.dumpio) { | ||||
|             this.#browserProcess.stderr?.pipe(process.stderr); | ||||
|             this.#browserProcess.stdout?.pipe(process.stdout); | ||||
|         } | ||||
|         subscribeToProcessEvent('exit', this.#onDriverProcessExit); | ||||
|         if (opts.handleSIGINT) { | ||||
|             subscribeToProcessEvent('SIGINT', this.#onDriverProcessSignal); | ||||
|         } | ||||
|         if (opts.handleSIGTERM) { | ||||
|             subscribeToProcessEvent('SIGTERM', this.#onDriverProcessSignal); | ||||
|         } | ||||
|         if (opts.handleSIGHUP) { | ||||
|             subscribeToProcessEvent('SIGHUP', this.#onDriverProcessSignal); | ||||
|         } | ||||
|         if (opts.onExit) { | ||||
|             this.#onExitHook = opts.onExit; | ||||
|         } | ||||
|         this.#browserProcessExiting = new Promise((resolve, reject) => { | ||||
|             this.#browserProcess.once('exit', async () => { | ||||
|                 debugLaunch(`Browser process ${this.#browserProcess.pid} onExit`); | ||||
|                 this.#clearListeners(); | ||||
|                 this.#exited = true; | ||||
|                 try { | ||||
|                     await this.#runHooks(); | ||||
|                 } | ||||
|                 catch (err) { | ||||
|                     reject(err); | ||||
|                     return; | ||||
|                 } | ||||
|                 resolve(); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
|     async #runHooks() { | ||||
|         if (this.#hooksRan) { | ||||
|             return; | ||||
|         } | ||||
|         this.#hooksRan = true; | ||||
|         await this.#onExitHook(); | ||||
|     } | ||||
|     get nodeProcess() { | ||||
|         return this.#browserProcess; | ||||
|     } | ||||
|     #configureStdio(opts) { | ||||
|         if (opts.pipe) { | ||||
|             if (opts.dumpio) { | ||||
|                 return ['ignore', 'pipe', 'pipe', 'pipe', 'pipe']; | ||||
|             } | ||||
|             else { | ||||
|                 return ['ignore', 'ignore', 'ignore', 'pipe', 'pipe']; | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             if (opts.dumpio) { | ||||
|                 return ['pipe', 'pipe', 'pipe']; | ||||
|             } | ||||
|             else { | ||||
|                 return ['pipe', 'ignore', 'pipe']; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     #clearListeners() { | ||||
|         unsubscribeFromProcessEvent('exit', this.#onDriverProcessExit); | ||||
|         unsubscribeFromProcessEvent('SIGINT', this.#onDriverProcessSignal); | ||||
|         unsubscribeFromProcessEvent('SIGTERM', this.#onDriverProcessSignal); | ||||
|         unsubscribeFromProcessEvent('SIGHUP', this.#onDriverProcessSignal); | ||||
|     } | ||||
|     #onDriverProcessExit = (_code) => { | ||||
|         this.kill(); | ||||
|     }; | ||||
|     #onDriverProcessSignal = (signal) => { | ||||
|         switch (signal) { | ||||
|             case 'SIGINT': | ||||
|                 this.kill(); | ||||
|                 process.exit(130); | ||||
|             case 'SIGTERM': | ||||
|             case 'SIGHUP': | ||||
|                 void this.close(); | ||||
|                 break; | ||||
|         } | ||||
|     }; | ||||
|     async close() { | ||||
|         await this.#runHooks(); | ||||
|         if (!this.#exited) { | ||||
|             this.kill(); | ||||
|         } | ||||
|         return await this.#browserProcessExiting; | ||||
|     } | ||||
|     hasClosed() { | ||||
|         return this.#browserProcessExiting; | ||||
|     } | ||||
|     kill() { | ||||
|         debugLaunch(`Trying to kill ${this.#browserProcess.pid}`); | ||||
|         // If the process failed to launch (for example if the browser executable path | ||||
|         // is invalid), then the process does not get a pid assigned. A call to | ||||
|         // `proc.kill` would error, as the `pid` to-be-killed can not be found. | ||||
|         if (this.#browserProcess && | ||||
|             this.#browserProcess.pid && | ||||
|             pidExists(this.#browserProcess.pid)) { | ||||
|             try { | ||||
|                 debugLaunch(`Browser process ${this.#browserProcess.pid} exists`); | ||||
|                 if (process.platform === 'win32') { | ||||
|                     try { | ||||
|                         child_process_1.default.execSync(`taskkill /pid ${this.#browserProcess.pid} /T /F`); | ||||
|                     } | ||||
|                     catch (error) { | ||||
|                         debugLaunch(`Killing ${this.#browserProcess.pid} using taskkill failed`, error); | ||||
|                         // taskkill can fail to kill the process e.g. due to missing permissions. | ||||
|                         // Let's kill the process via Node API. This delays killing of all child | ||||
|                         // processes of `this.proc` until the main Node.js process dies. | ||||
|                         this.#browserProcess.kill(); | ||||
|                     } | ||||
|                 } | ||||
|                 else { | ||||
|                     // on linux the process group can be killed with the group id prefixed with | ||||
|                     // a minus sign. The process group id is the group leader's pid. | ||||
|                     const processGroupId = -this.#browserProcess.pid; | ||||
|                     try { | ||||
|                         process.kill(processGroupId, 'SIGKILL'); | ||||
|                     } | ||||
|                     catch (error) { | ||||
|                         debugLaunch(`Killing ${this.#browserProcess.pid} using process.kill failed`, error); | ||||
|                         // Killing the process group can fail due e.g. to missing permissions. | ||||
|                         // Let's kill the process via Node API. This delays killing of all child | ||||
|                         // processes of `this.proc` until the main Node.js process dies. | ||||
|                         this.#browserProcess.kill('SIGKILL'); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             catch (error) { | ||||
|                 throw new Error(`${PROCESS_ERROR_EXPLANATION}\nError cause: ${isErrorLike(error) ? error.stack : error}`); | ||||
|             } | ||||
|         } | ||||
|         this.#clearListeners(); | ||||
|     } | ||||
|     waitForLineOutput(regex, timeout = 0) { | ||||
|         if (!this.#browserProcess.stderr) { | ||||
|             throw new Error('`browserProcess` does not have stderr.'); | ||||
|         } | ||||
|         const rl = readline_1.default.createInterface(this.#browserProcess.stderr); | ||||
|         let stderr = ''; | ||||
|         return new Promise((resolve, reject) => { | ||||
|             rl.on('line', onLine); | ||||
|             rl.on('close', onClose); | ||||
|             this.#browserProcess.on('exit', onClose); | ||||
|             this.#browserProcess.on('error', onClose); | ||||
|             const timeoutId = timeout > 0 ? setTimeout(onTimeout, timeout) : undefined; | ||||
|             const cleanup = () => { | ||||
|                 if (timeoutId) { | ||||
|                     clearTimeout(timeoutId); | ||||
|                 } | ||||
|                 rl.off('line', onLine); | ||||
|                 rl.off('close', onClose); | ||||
|                 this.#browserProcess.off('exit', onClose); | ||||
|                 this.#browserProcess.off('error', onClose); | ||||
|             }; | ||||
|             function onClose(error) { | ||||
|                 cleanup(); | ||||
|                 reject(new Error([ | ||||
|                     `Failed to launch the browser process!${error ? ' ' + error.message : ''}`, | ||||
|                     stderr, | ||||
|                     '', | ||||
|                     'TROUBLESHOOTING: https://pptr.dev/troubleshooting', | ||||
|                     '', | ||||
|                 ].join('\n'))); | ||||
|             } | ||||
|             function onTimeout() { | ||||
|                 cleanup(); | ||||
|                 reject(new TimeoutError(`Timed out after ${timeout} ms while waiting for the WS endpoint URL to appear in stdout!`)); | ||||
|             } | ||||
|             function onLine(line) { | ||||
|                 stderr += line + '\n'; | ||||
|                 const match = line.match(regex); | ||||
|                 if (!match) { | ||||
|                     return; | ||||
|                 } | ||||
|                 cleanup(); | ||||
|                 // The RegExp matches, so this will obviously exist. | ||||
|                 resolve(match[1]); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| exports.Process = Process; | ||||
| const PROCESS_ERROR_EXPLANATION = `Puppeteer was unable to kill the process which ran the browser binary. | ||||
| This means that, on future Puppeteer launches, Puppeteer might not be able to launch the browser. | ||||
| Please check your open processes and ensure that the browser processes that Puppeteer launched have been killed. | ||||
| If you think this is a bug, please report it on the Puppeteer issue tracker.`; | ||||
| /** | ||||
|  * @internal | ||||
|  */ | ||||
| function pidExists(pid) { | ||||
|     try { | ||||
|         return process.kill(pid, 0); | ||||
|     } | ||||
|     catch (error) { | ||||
|         if (isErrnoException(error)) { | ||||
|             if (error.code && error.code === 'ESRCH') { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         throw error; | ||||
|     } | ||||
| } | ||||
| /** | ||||
|  * @internal | ||||
|  */ | ||||
| function isErrorLike(obj) { | ||||
|     return (typeof obj === 'object' && obj !== null && 'name' in obj && 'message' in obj); | ||||
| } | ||||
| /** | ||||
|  * @internal | ||||
|  */ | ||||
| function isErrnoException(obj) { | ||||
|     return (isErrorLike(obj) && | ||||
|         ('errno' in obj || 'code' in obj || 'path' in obj || 'syscall' in obj)); | ||||
| } | ||||
| /** | ||||
|  * @public | ||||
|  */ | ||||
| class TimeoutError extends Error { | ||||
|     /** | ||||
|      * @internal | ||||
|      */ | ||||
|     constructor(message) { | ||||
|         super(message); | ||||
|         this.name = this.constructor.name; | ||||
|         Error.captureStackTrace(this, this.constructor); | ||||
|     } | ||||
| } | ||||
| exports.TimeoutError = TimeoutError; | ||||
| //# sourceMappingURL=launch.js.map | ||||
		Reference in New Issue
	
	Block a user
	 nik
					nik