blob: 0af8720d01865a3beb32897f628944162588a364 [file] [log] [blame]
Randolf Jungbcb3bc82023-06-26 16:30:141/**
Alex Rudenkoaf11b7c2024-02-06 10:44:422 * @license
3 * Copyright 2023 Google Inc.
4 * SPDX-License-Identifier: Apache-2.0
Randolf Jungbcb3bc82023-06-26 16:30:145 */
Randolf Jungbcb3bc82023-06-26 16:30:146import fs from 'fs';
Alex Rudenkof7ea7ab2023-10-24 09:40:517import os from 'os';
Randolf Jungbcb3bc82023-06-26 16:30:148import path from 'path';
Alex Rudenkof7ea7ab2023-10-24 09:40:519import { Browser, executablePathByBrowser, } from './browser-data/browser-data.js';
10import { detectBrowserPlatform } from './detectPlatform.js';
Randolf Jung3e526312023-08-08 06:20:3911/**
12 * @public
13 */
14export class InstalledBrowser {
15 browser;
16 buildId;
17 platform;
Alex Rudenkof7ea7ab2023-10-24 09:40:5118 executablePath;
Randolf Jung3e526312023-08-08 06:20:3919 #cache;
20 /**
21 * @internal
22 */
23 constructor(cache, browser, buildId, platform) {
24 this.#cache = cache;
25 this.browser = browser;
26 this.buildId = buildId;
27 this.platform = platform;
Alex Rudenkof7ea7ab2023-10-24 09:40:5128 this.executablePath = cache.computeExecutablePath({
29 browser,
30 buildId,
31 platform,
32 });
Randolf Jung3e526312023-08-08 06:20:3933 }
34 /**
35 * Path to the root of the installation folder. Use
36 * {@link computeExecutablePath} to get the path to the executable binary.
37 */
38 get path() {
39 return this.#cache.installationDir(this.browser, this.platform, this.buildId);
40 }
Randolf Jung3e526312023-08-08 06:20:3941}
Randolf Jungbcb3bc82023-06-26 16:30:1442/**
43 * The cache used by Puppeteer relies on the following structure:
44 *
45 * - rootDir
46 * -- <browser1> | browserRoot(browser1)
47 * ---- <platform>-<buildId> | installationDir()
48 * ------ the browser-platform-buildId
49 * ------ specific structure.
50 * -- <browser2> | browserRoot(browser2)
51 * ---- <platform>-<buildId> | installationDir()
52 * ------ the browser-platform-buildId
53 * ------ specific structure.
54 * @internal
55 */
56export class Cache {
Randolf Jung3e526312023-08-08 06:20:3957 #rootDir;
Randolf Jungbcb3bc82023-06-26 16:30:1458 constructor(rootDir) {
Randolf Jung3e526312023-08-08 06:20:3959 this.#rootDir = rootDir;
60 }
61 /**
62 * @internal
63 */
64 get rootDir() {
65 return this.#rootDir;
Randolf Jungbcb3bc82023-06-26 16:30:1466 }
67 browserRoot(browser) {
Randolf Jung3e526312023-08-08 06:20:3968 return path.join(this.#rootDir, browser);
Randolf Jungbcb3bc82023-06-26 16:30:1469 }
70 installationDir(browser, platform, buildId) {
71 return path.join(this.browserRoot(browser), `${platform}-${buildId}`);
72 }
73 clear() {
Randolf Jung3e526312023-08-08 06:20:3974 fs.rmSync(this.#rootDir, {
Randolf Jungbcb3bc82023-06-26 16:30:1475 force: true,
76 recursive: true,
77 maxRetries: 10,
78 retryDelay: 500,
79 });
80 }
81 uninstall(browser, platform, buildId) {
82 fs.rmSync(this.installationDir(browser, platform, buildId), {
83 force: true,
84 recursive: true,
85 maxRetries: 10,
86 retryDelay: 500,
87 });
88 }
89 getInstalledBrowsers() {
Randolf Jung3e526312023-08-08 06:20:3990 if (!fs.existsSync(this.#rootDir)) {
Randolf Jungbcb3bc82023-06-26 16:30:1491 return [];
92 }
Randolf Jung3e526312023-08-08 06:20:3993 const types = fs.readdirSync(this.#rootDir);
Randolf Jungbcb3bc82023-06-26 16:30:1494 const browsers = types.filter((t) => {
95 return Object.values(Browser).includes(t);
96 });
97 return browsers.flatMap(browser => {
98 const files = fs.readdirSync(this.browserRoot(browser));
99 return files
100 .map(file => {
101 const result = parseFolderPath(path.join(this.browserRoot(browser), file));
102 if (!result) {
103 return null;
104 }
Randolf Jung3e526312023-08-08 06:20:39105 return new InstalledBrowser(this, browser, result.buildId, result.platform);
Randolf Jungbcb3bc82023-06-26 16:30:14106 })
107 .filter((item) => {
108 return item !== null;
109 });
110 });
111 }
Alex Rudenkof7ea7ab2023-10-24 09:40:51112 computeExecutablePath(options) {
113 options.platform ??= detectBrowserPlatform();
114 if (!options.platform) {
115 throw new Error(`Cannot download a binary for the provided platform: ${os.platform()} (${os.arch()})`);
116 }
117 const installationDir = this.installationDir(options.browser, options.platform, options.buildId);
118 return path.join(installationDir, executablePathByBrowser[options.browser](options.platform, options.buildId));
119 }
Randolf Jungbcb3bc82023-06-26 16:30:14120}
Randolf Jungbcb3bc82023-06-26 16:30:14121function parseFolderPath(folderPath) {
122 const name = path.basename(folderPath);
123 const splits = name.split('-');
124 if (splits.length !== 2) {
125 return;
126 }
127 const [platform, buildId] = splits;
128 if (!buildId || !platform) {
129 return;
130 }
131 return { platform, buildId };
132}
133//# sourceMappingURL=Cache.js.map