@cityssm/puppeteer-launch
Version:
Launch Puppeteer, falling back to system browsers when the cached ones aren't working or aren't available.
117 lines (97 loc) • 4.11 kB
text/typescript
import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import {
type InstalledBrowser,
Browser,
getInstalledBrowsers
} from '@puppeteer/browsers'
import Debug from 'debug'
import { DEBUG_NAMESPACE } from './debug.config.js'
import { installChromeBrowser, installFirefoxBrowser } from './installers.js'
const debug = Debug(`${DEBUG_NAMESPACE}:cache`)
export const PUPPETEER_CACHE_DIR = path.join(
os.homedir(),
'.cache',
'puppeteer'
)
let installedBrowsers: InstalledBrowser[] = []
/**
* Refreshes the cache of installed browsers by re-querying the Puppeteer cache directory.
* @returns A promise that resolves to the updated list of installed browsers.
*/
export async function refreshInstalledBrowserCache(): Promise<
InstalledBrowser[]
> {
let tempInstalledBrowsers = await getInstalledBrowsers({
cacheDir: PUPPETEER_CACHE_DIR
})
// Filter out browsers with missing executable paths
tempInstalledBrowsers = tempInstalledBrowsers.filter(
(browser) =>
fs.existsSync(browser.executablePath) &&
fs.statSync(browser.executablePath).isFile()
)
installedBrowsers = tempInstalledBrowsers
debug('Refreshed installed browser cache: %O', installedBrowsers)
return installedBrowsers
}
/**
* Retrieves the cached Chrome browser from the Puppeteer cache.
* If the browser is not found and `installIfMissing` is true, it will attempt to install the browser and refresh the cache before trying again.
* @param installIfMissing - Whether to install the browser if not found in the cache. Defaults to false.
* @returns A promise that resolves to the cached Chrome browser, or undefined if not found and not installed.
*/
export async function getCachedChromeBrowser(
installIfMissing = false
): Promise<InstalledBrowser | undefined> {
if (installedBrowsers.length === 0) {
await refreshInstalledBrowserCache()
}
const chromeBrowser = installedBrowsers.findLast(
(browser) => browser.browser === Browser.CHROME
)
if (chromeBrowser === undefined && installIfMissing) {
await installChromeBrowser()
await refreshInstalledBrowserCache()
return await getCachedChromeBrowser(false)
}
return chromeBrowser
}
/**
* Retrieves the cached Firefox browser from the Puppeteer cache.
* If the browser is not found and `installIfMissing` is true, it will attempt to install the browser and refresh the cache before trying again.
* @param installIfMissing - Whether to install the browser if not found in the cache. Defaults to false.
* @returns A promise that resolves to the cached Firefox browser, or undefined if not found and not installed.
*/
export async function getCachedFirefoxBrowser(
installIfMissing = false
): Promise<InstalledBrowser | undefined> {
if (installedBrowsers.length === 0) {
await refreshInstalledBrowserCache()
}
const firefoxBrowser = installedBrowsers.findLast(
(browser) => browser.browser === Browser.FIREFOX
)
if (firefoxBrowser === undefined && installIfMissing) {
await installFirefoxBrowser()
await refreshInstalledBrowserCache()
return await getCachedFirefoxBrowser(false)
}
return firefoxBrowser
}
/**
* Retrieves the cached browser for the specified browser type from the Puppeteer cache.
* If the browser is not found and `installIfMissing` is true, it will attempt to install the browser and refresh the cache before trying again.
* @param browser - The browser type to retrieve ('chrome' or 'firefox').
* @param installIfMissing - Whether to install the browser if not found in the cache. Defaults to false.
* @returns A promise that resolves to the cached browser, or undefined if not found and not installed.
*/
export async function getCachedBrowser(
browser: 'chrome' | 'firefox',
installIfMissing = false
): Promise<InstalledBrowser | undefined> {
return browser === 'chrome'
? await getCachedChromeBrowser(installIfMissing)
: await getCachedFirefoxBrowser(installIfMissing)
}