UNPKG

electron-forge

Version:

A complete tool for building modern Electron applications

240 lines (203 loc) 11.1 kB
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <base data-ice="baseUrl" href="../../"> <title data-ice="title">api/install.js | API Document</title> <link type="text/css" rel="stylesheet" href="css/style.css"> <link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css"> <script src="script/prettify/prettify.js"></script> <script src="script/manual.js"></script> </head> <body class="layout-container" data-ice="rootContainer"> <header> <a href="./">Home</a> <a href="identifiers.html">Reference</a> <a href="source.html">Source</a> <a data-ice="repoURL" href="https://github.com/electron-userland/electron-forge" class="repo-url-github">Repository</a> <div class="search-box"> <span> <img src="./image/search.png"> <span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span> </span> <ul class="search-result"></ul> </div> </header> <nav class="navigation" data-ice="nav"><div> <ul> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-import">import</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-init">init</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-install">install</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-lint">lint</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-make">make</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-package">package</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-publish">publish</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-start">start</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-typedef">T</span><span data-ice="name"><span><a href="typedef/index.html#static-typedef-ImportOptions">ImportOptions</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-typedef">T</span><span data-ice="name"><span><a href="typedef/index.html#static-typedef-InitOptions">InitOptions</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-typedef">T</span><span data-ice="name"><span><a href="typedef/index.html#static-typedef-InstallOptions">InstallOptions</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-typedef">T</span><span data-ice="name"><span><a href="typedef/index.html#static-typedef-LintOptions">LintOptions</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-typedef">T</span><span data-ice="name"><span><a href="typedef/index.html#static-typedef-MakeOptions">MakeOptions</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-typedef">T</span><span data-ice="name"><span><a href="typedef/index.html#static-typedef-PackageOptions">PackageOptions</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-typedef">T</span><span data-ice="name"><span><a href="typedef/index.html#static-typedef-PublishOptions">PublishOptions</a></span></span></li> <li data-ice="doc"><span data-ice="kind" class="kind-typedef">T</span><span data-ice="name"><span><a href="typedef/index.html#static-typedef-StartOptions">StartOptions</a></span></span></li> </ul> </div> </nav> <div class="content" data-ice="content"><h1 data-ice="title">api/install.js</h1> <pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">import &apos;colors&apos;; import debug from &apos;debug&apos;; import fetch from &apos;node-fetch&apos;; import fs from &apos;fs-promise&apos;; import inquirer from &apos;inquirer&apos;; import nugget from &apos;nugget&apos;; import opn from &apos;opn&apos;; import os from &apos;os&apos;; import path from &apos;path&apos;; import pify from &apos;pify&apos;; import semver from &apos;semver&apos;; import asyncOra from &apos;../util/ora-handler&apos;; import darwinDMGInstaller from &apos;../installers/darwin/dmg&apos;; import darwinZipInstaller from &apos;../installers/darwin/zip&apos;; import linuxDebInstaller from &apos;../installers/linux/deb&apos;; import linuxRPMInstaller from &apos;../installers/linux/rpm&apos;; const d = debug(&apos;electron-forge:install&apos;); const GITHUB_API = &apos;https://api.github.com&apos;; /** * @typedef {Object} InstallOptions * @property {boolean} [interactive=false] Whether to use sensible defaults or prompt the user visually * @property {boolean} [prerelease=false] Whether to install prerelease versions * @property {string} repo The GitHub repository to install from, in the format owner/name * @property {function} chooseAsset A function that must return the asset to use/install from a provided array of compatible GitHub assets */ /** * Install an Electron application from GitHub. If you leave interactive as `false`, you MUST provide a `chooseAsset` function. * * @param {InstallOptions} providedOptions - Options for the install method * @return {Promise} Will resolve when the install process is complete */ export default async (providedOptions = {}) =&gt; { // eslint-disable-next-line prefer-const, no-unused-vars let { interactive, prerelease, repo, chooseAsset } = Object.assign({ interactive: false, prerelease: false, }, providedOptions); asyncOra.interactive = interactive; let latestRelease; let possibleAssets = []; await asyncOra(&apos;Searching for Application&apos;, async (searchSpinner) =&gt; { if (!repo || repo.indexOf(&apos;/&apos;) === -1) { // eslint-disable-next-line no-throw-literal throw &apos;Invalid repository name, must be in the format owner/name&apos;; } d(&apos;searching for repo:&apos;, repo); let releases; try { releases = await (await fetch(`${GITHUB_API}/repos/${repo}/releases`)).json(); } catch (err) { // Ignore error } if (!releases || releases.message === &apos;Not Found&apos; || !Array.isArray(releases)) { // eslint-disable-next-line no-throw-literal throw `Failed to find releases for repository &quot;${repo}&quot;. Please check the name and try again.`; } releases = releases.filter(release =&gt; !release.prerelease || prerelease); const sortedReleases = releases.sort((releaseA, releaseB) =&gt; { let tagA = releaseA.tag_name; if (tagA.substr(0, 1) === &apos;v&apos;) tagA = tagA.substr(1); let tagB = releaseB.tag_name; if (tagB.substr(0, 1) === &apos;v&apos;) tagB = tagB.substr(1); return (semver.gt(tagB, tagA) ? 1 : -1); }); latestRelease = sortedReleases[0]; searchSpinner.text = &apos;Searching for Releases&apos;; // eslint-disable-line const assets = latestRelease.assets; if (!assets || !Array.isArray(assets)) { // eslint-disable-next-line no-throw-literal throw &apos;Could not find any assets for the latest release&apos;; } const installTargets = { win32: [/\.exe$/], darwin: [/OSX.*\.zip$/, /darwin.*\.zip$/, /macOS.*\.zip$/, /mac.*\.zip$/, /\.dmg$/], linux: [/\.rpm$/, /\.deb$/], }; possibleAssets = assets.filter((asset) =&gt; { const targetSuffixes = installTargets[process.platform]; for (const suffix of targetSuffixes) { if (suffix.test(asset.name)) return true; } return false; }); if (possibleAssets.length === 0) { // eslint-disable-next-line no-throw-literal throw `Failed to find any installable assets for target platform: ${`${process.platform}`.cyan}`; } }); console.info(`Found latest release${prerelease ? &apos; (including prereleases)&apos; : &apos;&apos;}: ${latestRelease.tag_name.cyan}`); let targetAsset = possibleAssets[0]; if (possibleAssets.length &gt; 1) { if (chooseAsset) { targetAsset = await Promise.resolve(chooseAsset(possibleAssets)); } else if (!interactive) { const choices = []; possibleAssets.forEach((asset) =&gt; { choices.push({ name: asset.name, value: asset.id }); }); const { assetID } = await inquirer.createPromptModule()({ type: &apos;list&apos;, name: &apos;assetID&apos;, message: &apos;Multiple potential assets found, please choose one from the list below:&apos;.cyan, choices, }); targetAsset = possibleAssets.find(asset =&gt; asset.id === assetID); } else { // eslint-disable-next-line no-throw-literal throw &apos;expected a chooseAsset function to be provided but it was not&apos;; } } const tmpdir = path.resolve(os.tmpdir(), &apos;forge-install&apos;); const pathSafeRepo = repo.replace(/[/\\]/g, &apos;-&apos;); const filename = `${pathSafeRepo}-${latestRelease.tag_name}-${targetAsset.name}`; const fullFilePath = path.resolve(tmpdir, filename); if (!await fs.exists(fullFilePath) || (await fs.stat(fullFilePath)).size !== targetAsset.size) { await fs.mkdirs(tmpdir); const nuggetOpts = { target: filename, dir: tmpdir, resume: true, strictSSL: true, }; await pify(nugget)(targetAsset.browser_download_url, nuggetOpts); } await asyncOra(&apos;Installing Application&apos;, async (installSpinner) =&gt; { const installActions = { win32: { &apos;.exe&apos;: async filePath =&gt; await opn(filePath, { wait: false }), }, darwin: { &apos;.zip&apos;: darwinZipInstaller, &apos;.dmg&apos;: darwinDMGInstaller, }, linux: { &apos;.deb&apos;: linuxDebInstaller, &apos;.rpm&apos;: linuxRPMInstaller, }, }; const suffixFnIdent = Object.keys(installActions[process.platform]).find(suffix =&gt; targetAsset.name.endsWith(suffix)); await installActions[process.platform][suffixFnIdent](fullFilePath, installSpinner); }); }; </code></pre> </div> <footer class="footer"> Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(0.5.2)</span><img src="./image/esdoc-logo-mini-black.png"></a> </footer> <script src="script/search_index.js"></script> <script src="script/search.js"></script> <script src="script/pretty-print.js"></script> <script src="script/inherited-summary.js"></script> <script src="script/test-summary.js"></script> <script src="script/inner-link.js"></script> <script src="script/patch-for-local.js"></script> </body> </html>