install.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. "use strict";
  2. /**
  3. * @license
  4. * Copyright 2017 Google Inc.
  5. * SPDX-License-Identifier: Apache-2.0
  6. */
  7. var __importDefault = (this && this.__importDefault) || function (mod) {
  8. return (mod && mod.__esModule) ? mod : { "default": mod };
  9. };
  10. Object.defineProperty(exports, "__esModule", { value: true });
  11. exports.canDownload = exports.getInstalledBrowsers = exports.uninstall = exports.install = void 0;
  12. const assert_1 = __importDefault(require("assert"));
  13. const fs_1 = require("fs");
  14. const promises_1 = require("fs/promises");
  15. const os_1 = __importDefault(require("os"));
  16. const path_1 = __importDefault(require("path"));
  17. const browser_data_js_1 = require("./browser-data/browser-data.js");
  18. const Cache_js_1 = require("./Cache.js");
  19. const debug_js_1 = require("./debug.js");
  20. const detectPlatform_js_1 = require("./detectPlatform.js");
  21. const fileUtil_js_1 = require("./fileUtil.js");
  22. const httpUtil_js_1 = require("./httpUtil.js");
  23. const debugInstall = (0, debug_js_1.debug)('puppeteer:browsers:install');
  24. const times = new Map();
  25. function debugTime(label) {
  26. times.set(label, process.hrtime());
  27. }
  28. function debugTimeEnd(label) {
  29. const end = process.hrtime();
  30. const start = times.get(label);
  31. if (!start) {
  32. return;
  33. }
  34. const duration = end[0] * 1000 + end[1] / 1e6 - (start[0] * 1000 + start[1] / 1e6); // calculate duration in milliseconds
  35. debugInstall(`Duration for ${label}: ${duration}ms`);
  36. }
  37. async function install(options) {
  38. options.platform ??= (0, detectPlatform_js_1.detectBrowserPlatform)();
  39. options.unpack ??= true;
  40. if (!options.platform) {
  41. throw new Error(`Cannot download a binary for the provided platform: ${os_1.default.platform()} (${os_1.default.arch()})`);
  42. }
  43. const url = getDownloadUrl(options.browser, options.platform, options.buildId, options.baseUrl);
  44. try {
  45. return await installUrl(url, options);
  46. }
  47. catch (err) {
  48. // If custom baseUrl is provided, do not fall back to CfT dashboard.
  49. if (options.baseUrl && !options.forceFallbackForTesting) {
  50. throw err;
  51. }
  52. debugInstall(`Error downloading from ${url}.`);
  53. switch (options.browser) {
  54. case browser_data_js_1.Browser.CHROME:
  55. case browser_data_js_1.Browser.CHROMEDRIVER:
  56. case browser_data_js_1.Browser.CHROMEHEADLESSSHELL: {
  57. debugInstall(`Trying to find download URL via https://googlechromelabs.github.io/chrome-for-testing.`);
  58. const version = (await (0, httpUtil_js_1.getJSON)(new URL(`https://googlechromelabs.github.io/chrome-for-testing/${options.buildId}.json`)));
  59. let platform = '';
  60. switch (options.platform) {
  61. case browser_data_js_1.BrowserPlatform.LINUX:
  62. platform = 'linux64';
  63. break;
  64. case browser_data_js_1.BrowserPlatform.MAC_ARM:
  65. platform = 'mac-arm64';
  66. break;
  67. case browser_data_js_1.BrowserPlatform.MAC:
  68. platform = 'mac-x64';
  69. break;
  70. case browser_data_js_1.BrowserPlatform.WIN32:
  71. platform = 'win32';
  72. break;
  73. case browser_data_js_1.BrowserPlatform.WIN64:
  74. platform = 'win64';
  75. break;
  76. }
  77. const url = version.downloads[options.browser]?.find(link => {
  78. return link['platform'] === platform;
  79. })?.url;
  80. if (url) {
  81. debugInstall(`Falling back to downloading from ${url}.`);
  82. return await installUrl(new URL(url), options);
  83. }
  84. throw err;
  85. }
  86. default:
  87. throw err;
  88. }
  89. }
  90. }
  91. exports.install = install;
  92. async function installUrl(url, options) {
  93. options.platform ??= (0, detectPlatform_js_1.detectBrowserPlatform)();
  94. if (!options.platform) {
  95. throw new Error(`Cannot download a binary for the provided platform: ${os_1.default.platform()} (${os_1.default.arch()})`);
  96. }
  97. const fileName = url.toString().split('/').pop();
  98. (0, assert_1.default)(fileName, `A malformed download URL was found: ${url}.`);
  99. const cache = new Cache_js_1.Cache(options.cacheDir);
  100. const browserRoot = cache.browserRoot(options.browser);
  101. const archivePath = path_1.default.join(browserRoot, `${options.buildId}-${fileName}`);
  102. if (!(0, fs_1.existsSync)(browserRoot)) {
  103. await (0, promises_1.mkdir)(browserRoot, { recursive: true });
  104. }
  105. if (!options.unpack) {
  106. if ((0, fs_1.existsSync)(archivePath)) {
  107. return archivePath;
  108. }
  109. debugInstall(`Downloading binary from ${url}`);
  110. debugTime('download');
  111. await (0, httpUtil_js_1.downloadFile)(url, archivePath, options.downloadProgressCallback);
  112. debugTimeEnd('download');
  113. return archivePath;
  114. }
  115. const outputPath = cache.installationDir(options.browser, options.platform, options.buildId);
  116. try {
  117. if ((0, fs_1.existsSync)(outputPath)) {
  118. const installedBrowser = new Cache_js_1.InstalledBrowser(cache, options.browser, options.buildId, options.platform);
  119. if (!(0, fs_1.existsSync)(installedBrowser.executablePath)) {
  120. throw new Error(`The browser folder (${outputPath}) exists but the executable (${installedBrowser.executablePath}) is missing`);
  121. }
  122. return installedBrowser;
  123. }
  124. debugInstall(`Downloading binary from ${url}`);
  125. try {
  126. debugTime('download');
  127. await (0, httpUtil_js_1.downloadFile)(url, archivePath, options.downloadProgressCallback);
  128. }
  129. finally {
  130. debugTimeEnd('download');
  131. }
  132. debugInstall(`Installing ${archivePath} to ${outputPath}`);
  133. try {
  134. debugTime('extract');
  135. await (0, fileUtil_js_1.unpackArchive)(archivePath, outputPath);
  136. }
  137. finally {
  138. debugTimeEnd('extract');
  139. }
  140. const installedBrowser = new Cache_js_1.InstalledBrowser(cache, options.browser, options.buildId, options.platform);
  141. if (options.buildIdAlias) {
  142. const metadata = installedBrowser.readMetadata();
  143. metadata.aliases[options.buildIdAlias] = options.buildId;
  144. installedBrowser.writeMetadata(metadata);
  145. }
  146. return installedBrowser;
  147. }
  148. finally {
  149. if ((0, fs_1.existsSync)(archivePath)) {
  150. await (0, promises_1.unlink)(archivePath);
  151. }
  152. }
  153. }
  154. /**
  155. *
  156. * @public
  157. */
  158. async function uninstall(options) {
  159. options.platform ??= (0, detectPlatform_js_1.detectBrowserPlatform)();
  160. if (!options.platform) {
  161. throw new Error(`Cannot detect the browser platform for: ${os_1.default.platform()} (${os_1.default.arch()})`);
  162. }
  163. new Cache_js_1.Cache(options.cacheDir).uninstall(options.browser, options.platform, options.buildId);
  164. }
  165. exports.uninstall = uninstall;
  166. /**
  167. * Returns metadata about browsers installed in the cache directory.
  168. *
  169. * @public
  170. */
  171. async function getInstalledBrowsers(options) {
  172. return new Cache_js_1.Cache(options.cacheDir).getInstalledBrowsers();
  173. }
  174. exports.getInstalledBrowsers = getInstalledBrowsers;
  175. /**
  176. * @public
  177. */
  178. async function canDownload(options) {
  179. options.platform ??= (0, detectPlatform_js_1.detectBrowserPlatform)();
  180. if (!options.platform) {
  181. throw new Error(`Cannot download a binary for the provided platform: ${os_1.default.platform()} (${os_1.default.arch()})`);
  182. }
  183. return await (0, httpUtil_js_1.headHttpRequest)(getDownloadUrl(options.browser, options.platform, options.buildId, options.baseUrl));
  184. }
  185. exports.canDownload = canDownload;
  186. function getDownloadUrl(browser, platform, buildId, baseUrl) {
  187. return new URL(browser_data_js_1.downloadUrls[browser](platform, buildId, baseUrl));
  188. }
  189. //# sourceMappingURL=install.js.map